diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 07714ec775..b7ead4cbc7 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -257,38 +257,6 @@ void CAIRO_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEnd } -void CAIRO_GAL::DrawPolyline( std::deque& aPointList ) -{ - // Iterate over the point list and draw the segments - std::deque::const_iterator it = aPointList.begin(); - - cairo_move_to( currentContext, it->x, it->y ); - - for( ++it; it != aPointList.end(); ++it ) - { - cairo_line_to( currentContext, it->x, it->y ); - } - - isElementAdded = true; -} - - -void CAIRO_GAL::DrawPolygon( const std::deque& aPointList ) -{ - // Iterate over the point list and draw the polygon - std::deque::const_iterator it = aPointList.begin(); - - cairo_move_to( currentContext, it->x, it->y ); - - for( ++it; it != aPointList.end(); ++it ) - { - cairo_line_to( currentContext, it->x, it->y ); - } - - isElementAdded = true; -} - - void CAIRO_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControlPointA, const VECTOR2D& aControlPointB, const VECTOR2D& aEndPoint ) { @@ -1059,6 +1027,39 @@ void CAIRO_GAL::setCompositor() } +void CAIRO_GAL::drawPoly( const std::deque& aPointList ) +{ + // Iterate over the point list and draw the segments + std::deque::const_iterator it = aPointList.begin(); + + cairo_move_to( currentContext, it->x, it->y ); + + for( ++it; it != aPointList.end(); ++it ) + { + cairo_line_to( currentContext, it->x, it->y ); + } + + isElementAdded = true; +} + + +void CAIRO_GAL::drawPoly( const VECTOR2D aPointList[], int aListSize ) +{ + // Iterate over the point list and draw the segments + const VECTOR2D* ptr = aPointList; + + cairo_move_to( currentContext, ptr->x, ptr->y ); + + for( int i = 0; i < aListSize; ++i ) + { + ++ptr; + cairo_line_to( currentContext, ptr->x, ptr->y ); + } + + isElementAdded = true; +} + + unsigned int CAIRO_GAL::getNewGroupNumber() { wxASSERT_MSG( groups.size() < std::numeric_limits::max(), diff --git a/common/gal/opengl/opengl_gal.cpp b/common/gal/opengl/opengl_gal.cpp index 73c71fb207..1f2eab7e36 100644 --- a/common/gal/opengl/opengl_gal.cpp +++ b/common/gal/opengl/opengl_gal.cpp @@ -3,7 +3,7 @@ * * Copyright (C) 2012 Torsten Hueter, torstenhtr gmx.de * Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors. - * Copyright (C) 2013-2015 CERN + * Copyright (C) 2013-2016 CERN * @author Maciej Suminski * * Graphics Abstraction Layer (GAL) for OpenGL @@ -448,7 +448,7 @@ void OPENGL_GAL::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEn } -void OPENGL_GAL::DrawPolyline( std::deque& aPointList ) +void OPENGL_GAL::DrawPolyline( const std::deque& aPointList ) { if( aPointList.empty() ) return; @@ -476,19 +476,43 @@ void OPENGL_GAL::DrawPolyline( std::deque& aPointList ) } +void OPENGL_GAL::DrawPolyline( const VECTOR2D aPointList[], int aListSize ) +{ + currentManager->Color( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a ); + + // Start from the second point + for( int i = 1; i < aListSize; ++i ) + { + const VECTOR2D startEndVector = ( aPointList[i] - aPointList[i - 1] ); + double lineAngle = startEndVector.Angle(); + + drawLineQuad( aPointList[i - 1], aPointList[i] ); + + // There is no need to draw line caps on both ends of polyline's segments + drawFilledSemiCircle( aPointList[i - 1], lineWidth / 2, lineAngle + M_PI / 2 ); + } + + // ..and now - draw the ending cap + const VECTOR2D startEndVector = ( aPointList[aListSize - 1] - aPointList[aListSize - 2] ); + double lineAngle = startEndVector.Angle(); + drawFilledSemiCircle( aPointList[aListSize - 1], lineWidth / 2, lineAngle - M_PI / 2 ); +} + + void OPENGL_GAL::DrawPolygon( const std::deque& aPointList ) { - // Any non convex polygon needs to be tesselated - // for this purpose the GLU standard functions are used currentManager->Shader( SHADER_NONE ); currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a ); + // Any non convex polygon needs to be tesselated + // for this purpose the GLU standard functions are used TessParams params = { currentManager, tessIntersects }; gluTessBeginPolygon( tesselator, ¶ms ); gluTessBeginContour( tesselator ); boost::shared_array points( new GLdouble[3 * aPointList.size()] ); int v = 0; + for( std::deque::const_iterator it = aPointList.begin(); it != aPointList.end(); ++it ) { points[v] = it->x; @@ -508,6 +532,41 @@ void OPENGL_GAL::DrawPolygon( const std::deque& aPointList ) } +void OPENGL_GAL::DrawPolygon( const VECTOR2D aPointList[], int aListSize ) +{ + currentManager->Shader( SHADER_NONE ); + currentManager->Color( fillColor.r, fillColor.g, fillColor.b, fillColor.a ); + + // Any non convex polygon needs to be tesselated + // for this purpose the GLU standard functions are used + TessParams params = { currentManager, tessIntersects }; + gluTessBeginPolygon( tesselator, ¶ms ); + gluTessBeginContour( tesselator ); + + boost::shared_array points( new GLdouble[3 * aListSize] ); + int v = 0; + const VECTOR2D* ptr = aPointList; + + for( int i = 0; i < aListSize; ++i ) + { + points[v] = ptr->x; + points[v + 1] = ptr->y; + points[v + 2] = layerDepth; + gluTessVertex( tesselator, &points[v], &points[v] ); + ++ptr; + v += 3; + } + + gluTessEndContour( tesselator ); + gluTessEndPolygon( tesselator ); + + // Free allocated intersecting points + tessIntersects.clear(); + + // vertexList destroyed here +} + + void OPENGL_GAL::DrawCurve( const VECTOR2D& aStartPoint, const VECTOR2D& aControlPointA, const VECTOR2D& aControlPointB, const VECTOR2D& aEndPoint ) { diff --git a/include/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h index dca18acc05..1f395f7201 100644 --- a/include/gal/cairo/cairo_gal.h +++ b/include/gal/cairo/cairo_gal.h @@ -112,10 +112,12 @@ public: virtual void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ); /// @copydoc GAL::DrawPolyline() - virtual void DrawPolyline( std::deque& aPointList ); + virtual void DrawPolyline( const std::deque& aPointList ) { drawPoly( aPointList ); } + virtual void DrawPolyline( const VECTOR2D aPointList[], int aListSize ) { drawPoly( aPointList, aListSize ); } /// @copydoc GAL::DrawPolygon() - virtual void DrawPolygon( const std::deque& aPointList ); + virtual void DrawPolygon( const std::deque& aPointList ) { drawPoly( aPointList ); } + virtual void DrawPolygon( const VECTOR2D aPointList[], int aListSize ) { drawPoly( aPointList, aListSize ); } /// @copydoc GAL::DrawCurve() virtual void DrawCurve( const VECTOR2D& startPoint, const VECTOR2D& controlPointA, @@ -381,6 +383,10 @@ private: /// Prepare the compositor void setCompositor(); + /// Drawing polygons & polylines is the same in cairo, so here is the common code + void drawPoly( const std::deque& aPointList ); + void drawPoly( const VECTOR2D aPointList[], int aListSize ); + /** * @brief Returns a valid key that can be used as a new group number. * diff --git a/include/gal/graphics_abstraction_layer.h b/include/gal/graphics_abstraction_layer.h index 1867f94175..40cebbf9f7 100644 --- a/include/gal/graphics_abstraction_layer.h +++ b/include/gal/graphics_abstraction_layer.h @@ -105,7 +105,8 @@ public: * * @param aPointList is a list of 2D-Vectors containing the polyline points. */ - virtual void DrawPolyline( std::deque& aPointList ) {}; + virtual void DrawPolyline( const std::deque& aPointList ) {}; + virtual void DrawPolyline( const VECTOR2D aPointList[], int aListSize ) {}; /** * @brief Draw a circle using world coordinates. @@ -140,6 +141,7 @@ public: * @param aPointList is the list of the polygon points. */ virtual void DrawPolygon( const std::deque& aPointList ) {}; + virtual void DrawPolygon( const VECTOR2D aPointList[], int aListSize ) {}; /** * @brief Draw a cubic bezier spline. diff --git a/include/gal/opengl/opengl_gal.h b/include/gal/opengl/opengl_gal.h index b587e7023f..83598baf68 100644 --- a/include/gal/opengl/opengl_gal.h +++ b/include/gal/opengl/opengl_gal.h @@ -3,7 +3,7 @@ * * Copyright (C) 2012 Torsten Hueter, torstenhtr gmx.de * Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors. - * Copyright (C) 2013-2015 CERN + * Copyright (C) 2013-2016 CERN * @author Maciej Suminski * * Graphics Abstraction Layer (GAL) for OpenGL @@ -113,10 +113,12 @@ public: virtual void DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ); /// @copydoc GAL::DrawPolyline() - virtual void DrawPolyline( std::deque& aPointList ); + virtual void DrawPolyline( const std::deque& aPointList ); + virtual void DrawPolyline( const VECTOR2D aPointList[], int aListSize ); /// @copydoc GAL::DrawPolygon() virtual void DrawPolygon( const std::deque& aPointList ); + virtual void DrawPolygon( const VECTOR2D aPointList[], int aListSize ); /// @copydoc GAL::DrawCurve() virtual void DrawCurve( const VECTOR2D& startPoint, const VECTOR2D& controlPointA,