Removed different styles of line caps and line joins, leaving only round caps & joins.

Fixed drawing stroked semicircles using OpenGL backend.
This commit is contained in:
unknown 2013-07-01 14:39:27 +02:00 committed by Maciej Suminski
parent 8a44751b61
commit 4360860bee
8 changed files with 152 additions and 444 deletions

View File

@ -72,15 +72,6 @@ CAIRO_GAL::CAIRO_GAL( wxWindow* aParent, wxEvtHandler* aMouseListener,
Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) ); Connect( wxEVT_ENTER_WINDOW, wxMouseEventHandler( CAIRO_GAL::skipMouseEvent ) );
#endif #endif
// Initialize line attributes map
lineCapMap[LINE_CAP_BUTT] = CAIRO_LINE_CAP_BUTT;
lineCapMap[LINE_CAP_ROUND] = CAIRO_LINE_CAP_ROUND;
lineCapMap[LINE_CAP_SQUARED] = CAIRO_LINE_CAP_SQUARE;
lineJoinMap[LINE_JOIN_BEVEL] = CAIRO_LINE_JOIN_BEVEL;
lineJoinMap[LINE_JOIN_ROUND] = CAIRO_LINE_JOIN_ROUND;
lineJoinMap[LINE_JOIN_MITER] = CAIRO_LINE_JOIN_MITER;
// Initialize the cursor shape // Initialize the cursor shape
SetCursorColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) ); SetCursorColor( COLOR4D( 1.0, 1.0, 1.0, 1.0 ) );
initCursor( 21 ); initCursor( 21 );
@ -179,8 +170,8 @@ void CAIRO_GAL::initSurface()
cairo_new_path( cairoImage ); cairo_new_path( cairoImage );
isElementAdded = true; isElementAdded = true;
cairo_set_line_join( cairoImage, lineJoinMap[lineJoin] ); cairo_set_line_join( cairoImage, CAIRO_LINE_JOIN_ROUND );
cairo_set_line_cap( cairoImage, lineCapMap[lineCap] ); cairo_set_line_cap( cairoImage, CAIRO_LINE_CAP_ROUND );
lineWidth = 0; lineWidth = 0;
@ -298,9 +289,6 @@ void CAIRO_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint
void CAIRO_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint, double aWidth ) 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 ) if( isFillEnabled )
{ {
SetLineWidth( aWidth ); SetLineWidth( aWidth );
@ -520,42 +508,6 @@ void CAIRO_GAL::SetLineWidth( double aLineWidth )
} }
void CAIRO_GAL::SetLineCap( LineCap aLineCap )
{
storePath();
lineCap = aLineCap;
cairo_set_line_cap( cairoImage, lineCapMap[aLineCap] );
if( isGrouping )
{
GroupElement groupElement;
groupElement.command = CMD_SET_LINE_CAP;
groupElement.intArgument = (int) aLineCap;
currentGroup->push_back( groupElement );
}
}
void CAIRO_GAL::SetLineJoin( LineJoin aLineJoin )
{
storePath();
lineJoin = aLineJoin;
cairo_set_line_join( cairoImage, lineJoinMap[aLineJoin] );
if( isGrouping )
{
GroupElement groupElement;
groupElement.command = CMD_SET_LINE_JOIN;
groupElement.intArgument = (int) aLineJoin;
currentGroup->push_back( groupElement );
}
}
void CAIRO_GAL::ClearScreen() void CAIRO_GAL::ClearScreen()
{ {
// Clear screen // Clear screen
@ -767,14 +719,6 @@ void CAIRO_GAL::DrawGroup( int aGroupNumber )
cairo_set_line_width( cairoImage, it->arguments[0] ); cairo_set_line_width( cairoImage, it->arguments[0] );
break; break;
case CMD_SET_LINE_JOIN:
cairo_set_line_join( cairoImage, lineJoinMap[(LineJoin) ( it->intArgument )] );
break;
case CMD_SET_LINE_CAP:
cairo_set_line_cap( cairoImage, lineCapMap[(LineCap) ( it->intArgument )] );
break;
case CMD_STROKE_PATH: case CMD_STROKE_PATH:
cairo_set_source_rgb( cairoImage, strokeColor.r, strokeColor.g, strokeColor.b ); cairo_set_source_rgb( cairoImage, strokeColor.r, strokeColor.g, strokeColor.b );
cairo_append_path( cairoImage, it->cairoPath ); cairo_append_path( cairoImage, it->cairoPath );

View File

@ -38,8 +38,6 @@ GAL::GAL()
// Set the default values for the internal variables // Set the default values for the internal variables
SetIsFill( false ); SetIsFill( false );
SetIsStroke( true ); SetIsStroke( true );
SetLineJoin( LINE_JOIN_ROUND );
SetLineCap( LINE_CAP_ROUND );
SetIsCursorEnabled( false ); SetIsCursorEnabled( false );
SetZoomFactor( 1.0 ); SetZoomFactor( 1.0 );
SetFillColor( COLOR4D( 0.0, 0.0, 0.0, 0.0 ) ); SetFillColor( COLOR4D( 0.0, 0.0, 0.0, 0.0 ) );

View File

@ -658,9 +658,11 @@ void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP
color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a ); color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
SetLineWidth( aWidth ); SetLineWidth( aWidth );
drawSemiCircle( aStartPoint, aWidth / 2, lineAngle + M_PI / 2 );
drawSemiCircle( aEndPoint, aWidth / 2, lineAngle - M_PI / 2 );
drawLineQuad( aStartPoint, aEndPoint ); drawLineQuad( aStartPoint, aEndPoint );
// Draw line caps
drawFilledSemiCircle( aStartPoint, aWidth / 2, lineAngle + M_PI / 2 );
drawFilledSemiCircle( aEndPoint, aWidth / 2, lineAngle - M_PI / 2 );
} }
else else
{ {
@ -680,41 +682,15 @@ void OPENGL_GAL::DrawSegment( const VECTOR2D& aStartPoint, const VECTOR2D& aEndP
drawLineQuad( VECTOR2D( 0.0, -aWidth / 2.0 ), drawLineQuad( VECTOR2D( 0.0, -aWidth / 2.0 ),
VECTOR2D( lineLength, -aWidth / 2.0 ) ); VECTOR2D( lineLength, -aWidth / 2.0 ) );
drawSemiCircle( VECTOR2D( 0.0, 0.0 ), aWidth / 2, M_PI / 2 ); // Draw line caps
drawSemiCircle( VECTOR2D( lineLength, 0.0 ), aWidth / 2, -M_PI / 2 ); drawStrokedSemiCircle( VECTOR2D( 0.0, 0.0 ), ( aWidth + lineWidth ) / 2, M_PI / 2 );
drawStrokedSemiCircle( VECTOR2D( lineLength, 0.0 ), ( aWidth + lineWidth ) / 2, -M_PI / 2 );
Restore(); Restore();
} }
} }
inline void OPENGL_GAL::drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
{
VECTOR2D startEndVector = aEndPoint - aStartPoint;
// double lineLength = startEndVector.EuclideanNorm();
double lineAngle = startEndVector.Angle();
switch( lineCap )
{
case LINE_CAP_BUTT:
// TODO
break;
case LINE_CAP_ROUND:
// Add a semicircle at the line end
drawSemiCircle( aStartPoint, lineWidth / 2, lineAngle + M_PI / 2 );
break;
case LINE_CAP_SQUARED:
// FIXME? VECTOR2D offset;
// offset = startEndVector * ( lineWidth / lineLength / 2.0 );
// aStartPoint = aStartPoint - offset;
// aEndPoint = aEndPoint + offset;
break;
}
}
unsigned int OPENGL_GAL::getGroupNumber() unsigned int OPENGL_GAL::getGroupNumber()
{ {
wxASSERT_MSG( groups.size() < std::numeric_limits<unsigned int>::max(), wxASSERT_MSG( groups.size() < std::numeric_limits<unsigned int>::max(),
@ -731,256 +707,26 @@ unsigned int OPENGL_GAL::getGroupNumber()
void OPENGL_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ) void OPENGL_GAL::DrawLine( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint )
{ {
if( isFillEnabled ) const VECTOR2D startEndVector = aEndPoint - aStartPoint;
{ double lineAngle = startEndVector.Angle();
color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
drawLineCap( aStartPoint, aEndPoint ); drawLineQuad( aStartPoint, aEndPoint );
drawLineCap( aEndPoint, aStartPoint );
drawLineQuad( aStartPoint, aEndPoint );
}
if( isStrokeEnabled ) // Line caps
{ drawFilledSemiCircle( aStartPoint, lineWidth / 2, lineAngle + M_PI / 2 );
// TODO outline mode drawFilledSemiCircle( aEndPoint, lineWidth / 2, lineAngle + M_PI / 2 );
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
drawLineCap( aStartPoint, aEndPoint );
drawLineCap( aEndPoint, aStartPoint );
drawLineQuad( aStartPoint, aEndPoint );
}
} }
void OPENGL_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList ) void OPENGL_GAL::DrawPolyline( std::deque<VECTOR2D>& aPointList )
{ {
if( isUseShader ) std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
// Start from the second point
for( it++; it != aPointList.end(); it++ )
{ {
// This method reduces amount of triangles used for drawing DrawLine( *( it - 1 ), *it );
std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
// Start from the second point
for( it++; it != aPointList.end(); it++ )
{
DrawLine( *( it - 1 ), *it );
}
return;
} }
bool isFirstPoint = true;
LineCap savedLineCap = lineCap;
bool isFirstLine = true;
VECTOR2D startEndVector;
VECTOR2D lastStartEndVector;
VECTOR2D lastPoint;
unsigned int i = 0;
// Draw for each segment a line
for( std::deque<VECTOR2D>::const_iterator it = aPointList.begin();
it != aPointList.end(); it++ )
{
// First point
if( it == aPointList.begin() )
{
isFirstPoint = false;
lastPoint = *it;
}
else
{
VECTOR2D actualPoint = *it;
startEndVector = actualPoint - lastPoint;
if( isFirstLine )
{
drawLineCap( lastPoint, actualPoint );
isFirstLine = false;
}
else
{
// Compute some variables for the joints
double lineLengthA = lastStartEndVector.EuclideanNorm();
double scale = 0.5 * lineWidth / lineLengthA;
VECTOR2D perpendicularVector1( -lastStartEndVector.y * scale,
lastStartEndVector.x * scale );
double lineLengthB = startEndVector.EuclideanNorm();
scale = 0.5 * lineWidth / lineLengthB;
VECTOR2D perpendicularVector2( -startEndVector.y * scale,
startEndVector.x * scale );
switch( lineJoin )
{
case LINE_JOIN_ROUND:
{
// Insert a triangle fan at the line joint
// Compute the start and end angle for the triangle fan
double angle1 = startEndVector.Angle();
double angle2 = lastStartEndVector.Angle();
double angleDiff = angle1 - angle2;
// Determines the side of the triangle fan
double adjust = angleDiff < 0 ? -0.5 * lineWidth : 0.5 * lineWidth;
// Angle correction for some special cases
if( angleDiff < -M_PI )
{
if( angle1 < 0 )
{
angle1 += 2 * M_PI;
}
if( angle2 < 0 )
{
angle2 += 2 * M_PI;
}
adjust = -adjust;
}
else if( angleDiff > M_PI )
{
if( angle1 > 0 )
{
angle1 -= 2 * M_PI;
}
if( angle2 > 0 )
{
angle2 -= 2 * M_PI;
}
adjust = -adjust;
}
// Now draw the fan
SWAP( angle1, >, angle2 );
begin( GL_TRIANGLES );
for( double a = angle1; a < angle2; )
{
// Compute vertices
vertex3( lastPoint.x, lastPoint.y, layerDepth );
vertex3( lastPoint.x + adjust * sin( a ),
lastPoint.y - adjust * cos( a ), layerDepth );
a += M_PI / 32;
if(a > angle2)
a = angle2;
vertex3( lastPoint.x + adjust * sin( a ),
lastPoint.y - adjust * cos( a ), layerDepth );
}
end();
break;
}
case LINE_JOIN_BEVEL:
{
// We compute the edge points of the line segments at the joint
VECTOR2D edgePoint1;
VECTOR2D edgePoint2;
// Determine the correct side
if( lastStartEndVector.x * startEndVector.y
- lastStartEndVector.y * startEndVector.x
< 0 )
{
edgePoint1 = lastPoint + perpendicularVector1;
edgePoint2 = lastPoint + perpendicularVector2;
}
else
{
edgePoint1 = lastPoint - perpendicularVector1;
edgePoint2 = lastPoint - perpendicularVector2;
}
// Insert a triangle at the joint to close the gap
begin( GL_TRIANGLES );
vertex3( edgePoint1.x, edgePoint1.y, layerDepth );
vertex3( edgePoint2.x, edgePoint2.y, layerDepth );
vertex3( lastPoint.x, lastPoint.y, layerDepth );
end();
break;
}
case LINE_JOIN_MITER:
{
// Compute points of the outer edges
VECTOR2D point1 = lastPoint - perpendicularVector1;
VECTOR2D point3 = lastPoint - perpendicularVector2;
if( lastStartEndVector.x * startEndVector.y
- lastStartEndVector.y * startEndVector.x < 0 )
{
point1 = lastPoint + perpendicularVector1;
point3 = lastPoint + perpendicularVector2;
}
VECTOR2D point2 = point1 - lastStartEndVector;
VECTOR2D point4 = point3 + startEndVector;
// Now compute the intersection point of the edges
double c1 = point1.Cross( point2 );
double c2 = point3.Cross( point4 );
double quot = startEndVector.Cross( lastStartEndVector );
VECTOR2D miterPoint( -c1 * startEndVector.x - c2 * lastStartEndVector.x,
-c1 * startEndVector.y - c2 * lastStartEndVector.y );
miterPoint = ( 1 / quot ) * miterPoint;
// Check if the point is outside the limit
if( ( lastPoint - miterPoint ).EuclideanNorm() > 2 * lineWidth )
{
// if it's outside cut the edge and insert three triangles
double limit = MITER_LIMIT * lineWidth;
VECTOR2D mp1 = point1 + ( limit / lineLengthA ) * lastStartEndVector;
VECTOR2D mp2 = point3 - ( limit / lineLengthB ) * startEndVector;
begin( GL_TRIANGLES );
vertex3( lastPoint.x, lastPoint.y, layerDepth );
vertex3( point1.x, point1.y, layerDepth );
vertex3( mp1.x, mp1.y, layerDepth );
vertex3( lastPoint.x, lastPoint.y, layerDepth );
vertex3( mp1.x, mp1.y, layerDepth );
vertex3( mp2.x, mp2.y, layerDepth );
vertex3( lastPoint.x, lastPoint.y, layerDepth );
vertex3( mp2.x, mp2.y, layerDepth );
vertex3( point3.x, point3.y, layerDepth );
end();
}
else
{
// Insert two triangles for the mitered edge
begin( GL_TRIANGLES );
vertex3( lastPoint.x, lastPoint.y, layerDepth );
vertex3( point1.x, point1.y, layerDepth );
vertex3( miterPoint.x, miterPoint.y, layerDepth );
vertex3( lastPoint.x, lastPoint.y, layerDepth );
vertex3( miterPoint.x, miterPoint.y, layerDepth );
vertex3( point3.x, point3.y, layerDepth );
end();
}
break;
}
}
}
if( it == aPointList.end() - 1 )
{
drawLineCap( actualPoint, lastPoint );
}
drawLineQuad( lastPoint, *it );
lastPoint = *it;
lastStartEndVector = startEndVector;
}
i++;
}
lineCap = savedLineCap;
} }
@ -1058,7 +804,8 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
/* Draw a triangle that contains the circle, then shade it leaving only the circle. /* Draw a triangle that contains the circle, then shade it leaving only the circle.
Parameters given to setShader are relative coordinates of the triangle's vertices Parameters given to setShader are relative coordinates of the triangle's vertices
and the line width. Shader uses this coordinates to determine if fragments are inside and the line width. Shader uses this coordinates to determine if fragments are inside
the circle or not. Width parameter has to be passed as a relative value. the circle or not. Width parameter has to be passed as a ratio of inner radius
to outer radius.
v2 v2
/\ /\
//\\ //\\
@ -1084,15 +831,14 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
return; return;
} }
// Draw the middle of the circle (not anti-aliased)
// Compute the factors for the unit circle
double outerScale = lineWidth / aRadius / 2;
double innerScale = -outerScale;
outerScale += 1.0;
innerScale += 1.0;
if( isStrokeEnabled ) if( isStrokeEnabled )
{ {
// Compute the factors for the unit circle
double outerScale = lineWidth / aRadius / 2;
double innerScale = -outerScale;
outerScale += 1.0;
innerScale += 1.0;
if( innerScale < outerScale ) if( innerScale < outerScale )
{ {
// Draw the outline // Draw the outline
@ -1167,6 +913,22 @@ void OPENGL_GAL::DrawCircle( const VECTOR2D& aCenterPoint, double aRadius )
void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle ) void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle )
{
if( isFillEnabled )
{
color4( fillColor.r, fillColor.g, fillColor.b, fillColor.a );
drawFilledSemiCircle( aCenterPoint, aRadius, aAngle );
}
if( isStrokeEnabled )
{
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
drawStrokedSemiCircle( aCenterPoint, aRadius, aAngle );
}
}
void OPENGL_GAL::drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle )
{ {
if( isUseShader && isGrouping ) if( isUseShader && isGrouping )
{ {
@ -1174,23 +936,21 @@ void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, d
Translate( aCenterPoint ); Translate( aCenterPoint );
Rotate( aAngle ); Rotate( aAngle );
color4( strokeColor.r, strokeColor.g, strokeColor.b, strokeColor.a );
/* Draw a triangle that contains the semicircle, then shade it to leave only the semicircle. /* Draw a triangle that contains the semicircle, then shade it to leave only the semicircle.
Parameters given to setShader are relative coordinates of the triangle's vertices. Parameters given to setShader are relative coordinates of the triangle's vertices.
Shader uses this coordinates to determine if fragments are inside the semicircle or not. Shader uses this coordinates to determine if fragments are inside the semicircle or not.
v2 v2
/\ /\
/__\ /__\
v0 //__\\ v1 v0 //__\\ v1
*/ */
setShader( SHADER_FILLED_CIRCLE, -3.0f / sqrt( 3.0f ), 0.0f, lineWidth ); setShader( SHADER_FILLED_CIRCLE, -3.0f / sqrt( 3.0f ), 0.0f );
vertex3( -aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v0 vertex3( -aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v0
setShader( SHADER_FILLED_CIRCLE, 3.0f / sqrt( 3.0f ), 0.0f, lineWidth ); setShader( SHADER_FILLED_CIRCLE, 3.0f / sqrt( 3.0f ), 0.0f );
vertex3( aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v1 vertex3( aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v1
setShader( SHADER_FILLED_CIRCLE, 0.0f, 2.0f, lineWidth ); setShader( SHADER_FILLED_CIRCLE, 0.0f, 2.0f );
vertex3( 0.0f, aRadius * 2.0f, layerDepth ); // v2 vertex3( 0.0f, aRadius * 2.0f, layerDepth ); // v2
Restore(); Restore();
@ -1217,6 +977,96 @@ void OPENGL_GAL::drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, d
} }
void OPENGL_GAL::drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle )
{
if( isUseShader && isGrouping )
{
Save();
Translate( aCenterPoint );
Rotate( aAngle );
/* Draw a triangle that contains the semicircle, then shade it to leave only the semicircle.
Parameters given to setShader are relative coordinates of the triangle's vertices
and the line width. Shader uses this coordinates to determine if fragments are inside
the semicircle or not. Width parameter has to be passed as a ratio of inner radius
to outer radius.
v2
/\
/__\
v0 //__\\ v1
*/
float outerRadius = aRadius;
float innerRadius = aRadius - lineWidth;
float relWidth = innerRadius / outerRadius;
setShader( SHADER_STROKED_CIRCLE, -3.0f / sqrt( 3.0f ), 0.0f, relWidth );
vertex3( -aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v0
setShader( SHADER_STROKED_CIRCLE, 3.0f / sqrt( 3.0f ), 0.0f, relWidth );
vertex3( aRadius * 3.0f / sqrt( 3.0f ), 0.0f, layerDepth ); // v1
setShader( SHADER_STROKED_CIRCLE, 0.0f, 2.0f, relWidth );
vertex3( 0.0f, aRadius * 2.0f, layerDepth ); // v2
Restore();
}
else
{
// Compute the factors for the unit circle
double outerScale = lineWidth / aRadius / 2;
double innerScale = -outerScale;
outerScale += 1.0;
innerScale += 1.0;
if( innerScale < outerScale )
{
Save();
Translate( aCenterPoint );
Rotate( aAngle );
// Draw the outline
VBO_VERTEX* circle = verticesCircle->GetVertices();
int next;
begin( GL_TRIANGLES );
for( int i = 0; i < ( 3 * CIRCLE_POINTS ) / 2; ++i )
{
// verticesCircle contains precomputed circle points interleaved with vertex
// (0,0,0), so filled circles can be drawn as consecutive triangles, ie:
// { 0,a,b, 0,c,d, 0,e,f, 0,g,h, ... }
// where letters stand for consecutive circle points and 0 for (0,0,0) vertex.
// We have to skip all (0,0,0) vertices (every third vertex)
if( i % 3 == 0 )
{
i++;
// Depending on the vertex, next circle point may be stored in the next vertex..
next = i + 1;
}
else
{
// ..or 2 vertices away (in case it is preceded by (0,0,0) vertex)
next = i + 2;
}
vertex3( circle[i].x * innerScale, circle[i].y * innerScale, layerDepth );
vertex3( circle[i].x * outerScale, circle[i].y * outerScale, layerDepth );
vertex3( circle[next].x * innerScale, circle[next].y * innerScale, layerDepth );
vertex3( circle[i].x * outerScale, circle[i].y * outerScale, layerDepth );
vertex3( circle[next].x * outerScale, circle[next].y * outerScale, layerDepth );
vertex3( circle[next].x * innerScale, circle[next].y * innerScale, layerDepth );
}
end();
Restore();
}
}
}
// FIXME Optimize // FIXME Optimize
void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle, void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double aStartAngle,
double aEndAngle ) double aEndAngle )
@ -1300,11 +1150,9 @@ void OPENGL_GAL::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double a
end(); end();
if( lineCap == LINE_CAP_ROUND ) // Draw line caps
{ drawFilledSemiCircle( startPoint, lineWidth / aRadius / 2.0, aStartAngle + M_PI );
drawSemiCircle( startPoint, lineWidth / aRadius / 2.0, aStartAngle + M_PI ); drawFilledSemiCircle( endPoint, lineWidth / aRadius / 2.0, aEndAngle );
drawSemiCircle( endPoint, lineWidth / aRadius / 2.0, aEndAngle );
}
} }
} }

View File

@ -233,8 +233,6 @@ void STROKE_FONT::Draw( std::string aText, const VECTOR2D& aPosition, double aRo
m_gal->SetIsStroke( true ); m_gal->SetIsStroke( true );
m_gal->SetIsFill( false ); m_gal->SetIsFill( false );
m_gal->SetLineCap( LINE_CAP_ROUND );
m_gal->SetLineJoin( LINE_JOIN_ROUND );
if( m_bold ) if( m_bold )
{ {

View File

@ -159,12 +159,6 @@ public:
/// @copydoc GAL::SetBackgroundColor() /// @copydoc GAL::SetBackgroundColor()
virtual void SetBackgroundColor( const COLOR4D& aColor ); virtual void SetBackgroundColor( const COLOR4D& aColor );
/// @copydoc GAL::SetLineCap()
virtual void SetLineCap( LineCap aLineCap );
/// @copydoc GAL::SetLineJoin()
virtual void SetLineJoin( LineJoin aLineJoin );
/// @copydoc GAL::SetLineWidth() /// @copydoc GAL::SetLineWidth()
virtual void SetLineWidth( double aLineWidth ); virtual void SetLineWidth( double aLineWidth );
@ -334,8 +328,6 @@ private:
CMD_SET_FILLCOLOR, ///< Set the fill color CMD_SET_FILLCOLOR, ///< Set the fill color
CMD_SET_STROKECOLOR, ///< Set the stroke color CMD_SET_STROKECOLOR, ///< Set the stroke color
CMD_SET_LINE_WIDTH, ///< Set the line width CMD_SET_LINE_WIDTH, ///< Set the line width
CMD_SET_LINE_CAP, ///< Set the line cap style
CMD_SET_LINE_JOIN, ///< Set the line join style
CMD_STROKE_PATH, ///< Set the stroke path CMD_STROKE_PATH, ///< Set the stroke path
CMD_FILL_PATH, ///< Set the fill path CMD_FILL_PATH, ///< Set the fill path
CMD_TRANSFORM, ///< Transform the actual context CMD_TRANSFORM, ///< Transform the actual context
@ -371,10 +363,6 @@ private:
int stride; ///< Stride value for Cairo int stride; ///< Stride value for Cairo
bool isInitialized; ///< Are Cairo image & surface ready to use bool isInitialized; ///< Are Cairo image & surface ready to use
// Mapping between Cairo and GAL line attributes
std::map<LineCap, cairo_line_cap_t> lineCapMap; ///< Line cap style mapping
std::map<LineJoin, cairo_line_join_t> lineJoinMap; ///< Line join style mapping
// Methods // Methods
void storePath(); ///< Store the actual path void storePath(); ///< Store the actual path

View File

@ -38,27 +38,6 @@
namespace KiGfx namespace KiGfx
{ {
/**
* LineCap: Type definition of the line end point style
*/
enum LineCap
{
LINE_CAP_BUTT, ///< Stop line at the end point
LINE_CAP_ROUND, ///< Draw a circle at the end point
LINE_CAP_SQUARED ///< Draw a square at the end point
};
/**
* LineJoin: Type definition of the line joint style
*/
enum LineJoin
{
LINE_JOIN_MITER, ///< Use sharp corners
LINE_JOIN_ROUND, ///< Insert a circle at the joints
LINE_JOIN_BEVEL ///< Diagonal corner
};
/** /**
* GridStyle: Type definition of the grid style * GridStyle: Type definition of the grid style
*/ */
@ -251,26 +230,6 @@ public:
*/ */
virtual void SetBackgroundColor( const COLOR4D& aColor ) = 0; virtual void SetBackgroundColor( const COLOR4D& aColor ) = 0;
/**
* @brief Set the style of the line caps.
*
* @param aLineCap is the line cap style.
*/
inline virtual void SetLineCap( LineCap aLineCap )
{
lineCap = aLineCap;
}
/**
* @brief Set the line join style.
*
* @param aLineJoin is the line join style.
*/
inline virtual void SetLineJoin( LineJoin aLineJoin )
{
lineJoin = aLineJoin;
}
/** /**
* @brief Set the line width. * @brief Set the line width.
* *
@ -710,8 +669,6 @@ protected:
double worldScale; ///< The scale factor world->screen double worldScale; ///< The scale factor world->screen
double lineWidth; ///< The line width double lineWidth; ///< The line width
LineCap lineCap; ///< Line end style
LineJoin lineJoin; ///< Style of the line joints
bool isFillEnabled; ///< Is filling of graphic objects enabled ? bool isFillEnabled; ///< Is filling of graphic objects enabled ?
bool isStrokeEnabled; ///< Are the outlines stroked ? bool isStrokeEnabled; ///< Are the outlines stroked ?

View File

@ -176,18 +176,6 @@ public:
/// @copydoc GAL::SetBackgroundColor() /// @copydoc GAL::SetBackgroundColor()
virtual void SetBackgroundColor( const COLOR4D& aColor ); virtual void SetBackgroundColor( const COLOR4D& aColor );
/// @copydoc GAL::SetLineCap()
virtual void SetLineCap( LineCap aLineCap )
{
lineCap = aLineCap;
}
/// @copydoc GAL::SetLineJoin()
virtual void SetLineJoin( LineJoin aLineJoin )
{
lineJoin = aLineJoin;
}
/// @copydoc GAL::SetLineWidth() /// @copydoc GAL::SetLineWidth()
virtual void SetLineWidth( double aLineWidth ); virtual void SetLineWidth( double aLineWidth );
@ -421,6 +409,9 @@ private:
*/ */
void drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle ); void drawSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
void drawFilledSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
void drawStrokedSemiCircle( const VECTOR2D& aCenterPoint, double aRadius, double aAngle );
/// Compute the points of a unit circle. /// Compute the points of a unit circle.
void computeUnitCircle(); void computeUnitCircle();
@ -514,15 +505,6 @@ private:
*/ */
inline void drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint ); inline void drawLineQuad( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
/**
* @brief Draw the line cap
*
* @param aStartPoint is the start point of the line.
* @param aEndPoint is the end point of the line.
* @param aDepthOffset is the relative depth of the line cap.
*/
inline void drawLineCap( const VECTOR2D& aStartPoint, const VECTOR2D& aEndPoint );
/** /**
* @brief Returns a valid key that can be used as a group number. * @brief Returns a valid key that can be used as a group number.
* *

View File

@ -314,8 +314,6 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
// Outline mode // Outline mode
m_gal->SetIsFill( false ); m_gal->SetIsFill( false );
m_gal->SetIsStroke( true ); m_gal->SetIsStroke( true );
m_gal->SetLineCap( LINE_CAP_ROUND );
m_gal->SetLineJoin( LINE_JOIN_MITER );
m_gal->SetLineWidth( m_pcbSettings->m_outlineWidth ); m_gal->SetLineWidth( m_pcbSettings->m_outlineWidth );
m_gal->SetStrokeColor( color ); m_gal->SetStrokeColor( color );
} }
@ -420,8 +418,6 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment )
m_gal->SetIsStroke( true ); m_gal->SetIsStroke( true );
m_gal->SetStrokeColor( strokeColor ); m_gal->SetStrokeColor( strokeColor );
m_gal->SetLineWidth( aSegment->GetWidth() ); m_gal->SetLineWidth( aSegment->GetWidth() );
m_gal->SetLineCap( LINE_CAP_ROUND );
m_gal->SetLineJoin( LINE_JOIN_ROUND );
switch( aSegment->GetShape() ) switch( aSegment->GetShape() )
{ {
@ -430,9 +426,8 @@ void PCB_PAINTER::draw( const DRAWSEGMENT* aSegment )
break; break;
case S_RECT: case S_RECT:
m_gal->SetLineCap( LINE_CAP_SQUARED ); wxASSERT_MSG( false, wxT( "Not tested yet" ) );
m_gal->SetLineJoin( LINE_JOIN_BEVEL ); m_gal->DrawRectangle( VECTOR2D( aSegment->GetStart() ), VECTOR2D( aSegment->GetEnd() ) );
m_gal->DrawLine( VECTOR2D( aSegment->GetStart() ), VECTOR2D( aSegment->GetEnd() ) );
break; break;
case S_ARC: case S_ARC:
@ -506,8 +501,6 @@ void PCB_PAINTER::draw( const ZONE_CONTAINER* aContainer )
m_gal->SetIsFill( !fillMode ); m_gal->SetIsFill( !fillMode );
m_gal->SetIsStroke( true ); m_gal->SetIsStroke( true );
m_gal->SetLineWidth( aContainer->GetThermalReliefCopperBridge() / 2.0 ); m_gal->SetLineWidth( aContainer->GetThermalReliefCopperBridge() / 2.0 );
m_gal->SetLineCap( LINE_CAP_ROUND );
m_gal->SetLineJoin( LINE_JOIN_ROUND );
// FIXME implement hatch mode // FIXME implement hatch mode