From 895d265603255199046cffed8d799f05742f605e Mon Sep 17 00:00:00 2001 From: Maciej Suminski Date: Wed, 17 Apr 2013 12:38:00 +0200 Subject: [PATCH] Added GAL::DrawSegment for drawing rounded segments (used for drawing tracks). --- common/gal/cairo/cairo_gal.cpp | 40 ++++++++++++++++++++++++ common/gal/opengl/opengl_gal.cpp | 39 +++++++++++++++++++++++ include/gal/cairo/cairo_gal.h | 3 ++ include/gal/graphics_abstraction_layer.h | 11 +++++++ include/gal/opengl/opengl_gal.h | 3 ++ pcbnew/pcb_painter.cpp | 32 +++++-------------- 6 files changed, 104 insertions(+), 24 deletions(-) diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 9070098c81..741fad0761 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -301,6 +301,46 @@ void CAIRO_GAL::DrawLine( VECTOR2D aStartPoint, VECTOR2D aEndPoint ) } +void CAIRO_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, double aWidth ) +{ + cairo_set_line_cap( cairoImage, CAIRO_LINE_CAP_ROUND ); + cairo_set_line_join( cairoImage, CAIRO_LINE_JOIN_ROUND ); + + if( isFillEnabled ) + { + cairo_set_line_width( cairoImage, aWidth ); + + cairo_move_to( cairoImage, (double) aStartPoint.x, (double) aStartPoint.y ); + cairo_line_to( cairoImage, (double) aEndPoint.x, (double) aEndPoint.y ); + } + else + { + VECTOR2D startEndVector = aEndPoint - aStartPoint; + double lineAngle = atan2( startEndVector.y, startEndVector.x ); + double lineLength = startEndVector.EuclideanNorm(); + + cairo_save( cairoImage ); + + cairo_translate( cairoImage, aStartPoint.x, aStartPoint.y ); + cairo_rotate( cairoImage, lineAngle ); + + cairo_arc( cairoImage, 0.0, 0.0, aWidth / 2.0, M_PI / 2.0, 3.0 * M_PI / 2.0 ); + cairo_arc( cairoImage, lineLength, 0.0, aWidth / 2.0, -M_PI / 2.0, M_PI / 2.0 ); + + cairo_move_to( cairoImage, 0.0, aWidth / 2.0 ); + cairo_line_to( cairoImage, lineLength, aWidth / 2.0 ); + + cairo_move_to( cairoImage, 0.0, -aWidth / 2.0 ); + cairo_line_to( cairoImage, lineLength, -aWidth / 2.0 ); + + cairo_restore( cairoImage ); + + } + + isElementAdded = true; +} + + void CAIRO_GAL::DrawCircle( VECTOR2D aCenterPoint, double aRadius ) { // A circle is drawn using an arc diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index c839cb62f0..e3747bca24 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -525,6 +525,45 @@ inline void OPENGL_GAL::drawLineQuad( VECTOR2D aStartPoint, VECTOR2D aEndPoint ) } +void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, double aWidth ) +{ + VECTOR2D startEndVector = aEndPoint - aStartPoint; + double lineAngle = atan2( startEndVector.y, startEndVector.x ); + + if( isFillEnabled ) + { + glColor4d( fillColor.r, fillColor.g, fillColor.b, fillColor.a ); + + SetLineWidth( aWidth ); + drawSemiCircle( aStartPoint, aWidth / 2, lineAngle + M_PI / 2, layerDepth ); + drawSemiCircle( aEndPoint, aWidth / 2, lineAngle - M_PI / 2, layerDepth ); + drawLineQuad( aStartPoint, aEndPoint ); + } + else + { + double lineLength = startEndVector.EuclideanNorm(); + + glColor4d( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a ); + + glPushMatrix(); + + glTranslated( aStartPoint.x, aStartPoint.y, 0.0 ); + glRotated( lineAngle * ( 360 / ( 2 * M_PI ) ), 0, 0, 1 ); + + drawLineQuad( VECTOR2D( 0.0, aWidth / 2.0 ), + VECTOR2D( lineLength, aWidth / 2.0 ) ); + + drawLineQuad( VECTOR2D( 0.0, -aWidth / 2.0 ), + VECTOR2D( lineLength, -aWidth / 2.0 ) ); + + DrawArc( VECTOR2D( 0.0, 0.0 ), aWidth / 2.0, M_PI / 2.0, 3.0 * M_PI / 2.0 ); + DrawArc( VECTOR2D( lineLength, 0.0 ), aWidth / 2.0, M_PI / 2.0, -M_PI / 2.0 ); + + glPopMatrix(); + } +} + + inline void OPENGL_GAL::drawLineCap( VECTOR2D aStartPoint, VECTOR2D aEndPoint, double aDepthOffset ) { VECTOR2D startEndVector = aEndPoint - aStartPoint; diff --git a/include/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h index 87100c6016..7e69bd7c16 100644 --- a/include/gal/cairo/cairo_gal.h +++ b/include/gal/cairo/cairo_gal.h @@ -98,6 +98,9 @@ public: /// @copydoc GAL::DrawLine() virtual void DrawLine( VECTOR2D aStartPoint, VECTOR2D aEndPoint ); + /// @copydoc GAL::DrawSegment() + virtual void DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, double aWidth ); + /// @copydoc GAL::DrawPolyline() virtual void DrawPolyline( std::deque& aPointList ); diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index e5ea3c344f..b06cfef9f7 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -107,6 +107,17 @@ public: */ virtual void DrawLine( VECTOR2D aStartPoint, VECTOR2D aEndPoint ) = 0; + /** + * @brief Draw a rounded segment. + * + * Start and end points are defined as 2D-Vectors. + * + * @param aStartPoint is the start point of the segment. + * @param aEndPoint is the end point of the segment. + * @param aWidth is a width of the segment + */ + virtual void DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, double aWidth ) = 0; + /** * @brief Draw a polyline * diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index d3539cc19d..2a8194144b 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -105,6 +105,9 @@ public: /// @copydoc GAL::DrawLine() virtual void DrawLine( VECTOR2D aStartPoint, VECTOR2D aEndPoint ); + /// @copydoc GAL::DrawSegment() + virtual void DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, double aWidth ); + /// @copydoc GAL::DrawPolyline() virtual void DrawPolyline( std::deque& aPointList ); diff --git a/pcbnew/pcb_painter.cpp b/pcbnew/pcb_painter.cpp index 17664e814f..a46fd45531 100644 --- a/pcbnew/pcb_painter.cpp +++ b/pcbnew/pcb_painter.cpp @@ -224,42 +224,26 @@ void PCB_PAINTER::draw( const TRACK* aTrack ) { VECTOR2D start( aTrack->GetStart() ); VECTOR2D end( aTrack->GetEnd() ); - COLOR4D strokeColor = getLayerColor( aTrack->GetLayer(), aTrack->GetNet() ); + int width = aTrack->GetWidth(); + COLOR4D color = getLayerColor( aTrack->GetLayer(), aTrack->GetNet() ); + + m_gal->SetStrokeColor( color ); + m_gal->SetIsStroke( true ); - m_gal->SetLineCap( LINE_CAP_ROUND ); - m_gal->SetLineJoin( LINE_JOIN_ROUND ); - m_gal->SetStrokeColor( strokeColor ); if( m_pcbSettings->m_sketchModeSelect[TRACKS_VISIBLE] ) { // Outline mode - VECTOR2D line = end - start; - double length = line.EuclideanNorm(); - int width = aTrack->GetWidth(); - m_gal->SetLineWidth( m_pcbSettings->m_outlineWidth ); m_gal->SetIsFill( false ); - m_gal->SetIsStroke( true ); - m_gal->Save(); - - m_gal->Translate( start ); - m_gal->Rotate( line.Angle() ); - m_gal->DrawLine( VECTOR2D( 0, width / 2 ), - VECTOR2D( length, width / 2 ) ); - m_gal->DrawLine( VECTOR2D( 0, -width / 2 ), - VECTOR2D( length, -width / 2 ) ); - m_gal->DrawArc( VECTOR2D( 0, 0 ), width / 2, M_PI / 2, 3 * M_PI / 2 ); - m_gal->DrawArc( VECTOR2D( length, 0 ), width / 2, M_PI / 2, -M_PI / 2 ); - - m_gal->Restore(); } else { // Filled mode + m_gal->SetFillColor( color ); m_gal->SetIsFill( true ); - m_gal->SetIsStroke( false ); - m_gal->SetLineWidth( aTrack->GetWidth() ); - m_gal->DrawLine( start, end ); } + + m_gal->DrawSegment( start, end, width ); }