cairo: Draw ovals with filled half-arcs

The circle at the end only ever looked right with 100% opacity.

Also fixes double-drawn arc fills in Cairo
This commit is contained in:
Seth Hillbrand 2019-02-18 11:54:29 -08:00
parent 525b9bd550
commit 4597979d18
2 changed files with 20 additions and 40 deletions

View File

@ -2,7 +2,7 @@
* This program source code file is part of KICAD, a free EDA CAD application.
*
* Copyright (C) 2012 Torsten Hueter, torstenhtr <at> gmx.de
* Copyright (C) 2012 Kicad Developers, see change_log.txt for contributors.
* Copyright (C) 2012-2019 Kicad Developers, see change_log.txt for contributors.
* Copyright (C) 2017-2018 CERN
* @author Maciej Suminski <maciej.suminski@cern.ch>
*
@ -52,6 +52,11 @@ CAIRO_GAL_BASE::CAIRO_GAL_BASE( GAL_DISPLAY_OPTIONS& aDisplayOptions ) :
groupCounter = 0;
currentGroup = nullptr;
lineWidth = 1.0;
linePixelWidth = 1.0;
lineWidthInPixels = 1.0;
lineWidthIsOdd = true;
// Initialise Cairo state
cairo_matrix_init_identity( &cairoWorldScreenMatrix );
currentContext = nullptr;
@ -255,39 +260,21 @@ void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, doub
auto c = roundp( xform( aCenterPoint ) );
auto r = ::roundp( xform( aRadius ) );
VECTOR2D startPoint( cos( aStartAngle ) * aRadius + aCenterPoint.x,
sin( aStartAngle ) * aRadius + aCenterPoint.y );
VECTOR2D endPoint( cos( aEndAngle ) * aRadius + aCenterPoint.x,
sin( aEndAngle ) * aRadius + aCenterPoint.y );
auto startPointS = roundp( xform ( startPoint ) );
auto endPointS = roundp( xform ( endPoint ) );
SWAP( aStartAngle, >, aEndAngle );
auto startAngleS = angle_xform( aStartAngle );
auto endAngleS = angle_xform( aEndAngle );
SWAP( startAngleS, >, endAngleS );
if( isFillEnabled ) // Draw the filled area of the shape, before drawing the outline itself
{
auto fgcolor = GetStrokeColor();
SetStrokeColor( GetFillColor() );
cairo_set_line_width( currentContext, 1.0 );
cairo_new_sub_path( currentContext );
cairo_arc( currentContext, c.x, c.y, r, startAngleS, endAngleS );
cairo_move_to( currentContext, c.x, c.y );
cairo_line_to( currentContext, startPointS.x, startPointS.y );
cairo_line_to( currentContext, endPointS.x, endPointS.y );
cairo_close_path( currentContext );
flushPath();
SetStrokeColor( fgcolor );
}
cairo_set_line_width( currentContext, lineWidthInPixels );
cairo_new_sub_path( currentContext );
if( isFillEnabled )
cairo_move_to( currentContext, c.x, c.y );
cairo_arc( currentContext, c.x, c.y, r, startAngleS, endAngleS );
if( isFillEnabled )
cairo_close_path( currentContext );
flushPath();
isElementAdded = true;

View File

@ -779,19 +779,16 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
m = ( size.y - size.x );
n = size.x;
m_gal->DrawArc( VECTOR2D( 0, -m ), n, -M_PI, 0 );
m_gal->DrawArc( VECTOR2D( 0, m ), n, M_PI, 0 );
if( m_pcbSettings.m_sketchMode[LAYER_PADS_TH] )
{
// Outline mode
m_gal->DrawArc( VECTOR2D( 0, -m ), n, -M_PI, 0 );
m_gal->DrawArc( VECTOR2D( 0, m ), n, M_PI, 0 );
m_gal->DrawLine( VECTOR2D( -n, -m ), VECTOR2D( -n, m ) );
m_gal->DrawLine( VECTOR2D( n, -m ), VECTOR2D( n, m ) );
}
else
{
// Filled mode
m_gal->DrawCircle( VECTOR2D( 0, -m ), n );
m_gal->DrawCircle( VECTOR2D( 0, m ), n );
m_gal->DrawRectangle( VECTOR2D( -n, -m ), VECTOR2D( n, m ) );
}
}
@ -799,20 +796,16 @@ void PCB_PAINTER::draw( const D_PAD* aPad, int aLayer )
{
m = ( size.x - size.y );
n = size.y;
m_gal->DrawArc( VECTOR2D( -m, 0 ), n, M_PI / 2, 3 * M_PI / 2 );
m_gal->DrawArc( VECTOR2D( m, 0 ), n, M_PI / 2, -M_PI / 2 );
if( m_pcbSettings.m_sketchMode[LAYER_PADS_TH] )
{
// Outline mode
m_gal->DrawArc( VECTOR2D( -m, 0 ), n, M_PI / 2, 3 * M_PI / 2 );
m_gal->DrawArc( VECTOR2D( m, 0 ), n, M_PI / 2, -M_PI / 2 );
m_gal->DrawLine( VECTOR2D( -m, -n ), VECTOR2D( m, -n ) );
m_gal->DrawLine( VECTOR2D( -m, n ), VECTOR2D( m, n ) );
}
else
{
// Filled mode
m_gal->DrawCircle( VECTOR2D( -m, 0 ), n );
m_gal->DrawCircle( VECTOR2D( m, 0 ), n );
m_gal->DrawRectangle( VECTOR2D( -m, -n ), VECTOR2D( m, n ) );
}
}