From d40bbed59190e951082f7a84b167fc686e8e88fe Mon Sep 17 00:00:00 2001 From: Alex Shvartzkop Date: Mon, 10 Jun 2024 21:21:13 +0300 Subject: [PATCH] Cairo GAL: improve alignment between arcs and segments and of odd-width lines. (cherry picked from commit f60b76696a8bb40aa0df6e35c552e8533eec491e) --- common/gal/cairo/cairo_gal.cpp | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 0b3309504b..1e5581568d 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -191,7 +191,7 @@ static double roundp( double x ) const VECTOR2D CAIRO_GAL_BASE::roundp( const VECTOR2D& v ) { - if( m_lineWidthIsOdd && m_isStrokeEnabled ) + if( m_lineWidthIsOdd ) return VECTOR2D( ::roundp( v.x ), ::roundp( v.y ) ); else return VECTOR2D( floor( v.x + 0.5 ), floor( v.y + 0.5 ) ); @@ -353,13 +353,18 @@ void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, double r = xform( aRadius ); - // N.B. This is backwards. We set this because we want to adjust the center - // point that changes both endpoints. In the worst case, this is twice as far. - // We cannot adjust radius or center based on the other because this causes the - // whole arc to change position/size - m_lineWidthIsOdd = !( static_cast( aRadius ) % 2 ); + // Adjust center and radius slightly to better match the rounding of endpoints. + VECTOR2D mid = roundp( xform( aCenterPoint ) ); - auto mid = roundp( xform( aCenterPoint ) ); + VECTOR2D startPointS = VECTOR2D( r, 0.0 ); + VECTOR2D endPointS = VECTOR2D( r, 0.0 ); + RotatePoint( startPointS, -EDA_ANGLE( startAngle, RADIANS_T ) ); + RotatePoint( endPointS, -EDA_ANGLE( endAngle, RADIANS_T ) ); + + VECTOR2D refStart = roundp( xform( aCenterPoint ) + startPointS ); + VECTOR2D refEnd = roundp( xform( aCenterPoint ) + endPointS ); + + r = ( ( refStart - mid ).EuclideanNorm() + ( refEnd - mid ).EuclideanNorm() ) / 2.0; cairo_set_line_width( m_currentContext, m_lineWidthInPixels ); cairo_new_sub_path( m_currentContext ); @@ -404,13 +409,7 @@ void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadiu double r = xform( aRadius ); - // N.B. This is backwards. We set this because we want to adjust the center - // point that changes both endpoints. In the worst case, this is twice as far. - // We cannot adjust radius or center based on the other because this causes the - // whole arc to change position/size - m_lineWidthIsOdd = !( static_cast( aRadius ) % 2 ); - - VECTOR2D mid = roundp( xform( aCenterPoint ) ); + VECTOR2D mid = xform( aCenterPoint ); double width = xform( aWidth / 2.0 ); VECTOR2D startPointS = VECTOR2D( r, 0.0 ); VECTOR2D endPointS = VECTOR2D( r, 0.0 );