From 63eb552e0a675b6e843a6406a12efd3fefb0fd67 Mon Sep 17 00:00:00 2001 From: jean-pierre charras Date: Sun, 9 Jun 2019 11:06:00 +0200 Subject: [PATCH] Fix issue in cairo_gal when drawing a 360 deg arc (in fact a circle). It was due to a angle normalization between -360 and 360 degrees. So, in arcs, if the start angle and end angle diff is n*360 deg, this normalization gives start angle = end angle. The fix forces end angle = start angle+360deg in this case. Fixes: lp:1832096 https://bugs.launchpad.net/kicad/+bug/1832096 --- common/gal/cairo/cairo_gal.cpp | 12 +++++++++++- gerbview/gerbview_painter.cpp | 20 ++++++++++---------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 7bdc60698c..05b01e22ad 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -146,8 +146,18 @@ void CAIRO_GAL_BASE::arc_angles_xform_and_normalize( double& aStartAngle, double SWAP( startAngle, >, endAngle ); // now rotate arc according to the rotation transform matrix + // Remark: + // We call angle_xform() to calculate angles according to the flip/rotation + // transform and normatize between -2M_PI and +2M_PI. + // Therefore, if aStartAngle = aEndAngle + 2*n*M_PI, the transform gives + // aEndAngle = aStartAngle + // So, if this is the case, force the aEndAngle value to draw a circle. aStartAngle = angle_xform( startAngle ); - aEndAngle = angle_xform( endAngle ); + + if( std::abs( aEndAngle - aStartAngle ) >= 2*M_PI ) // arc is a full circle + aEndAngle = aStartAngle + 2*M_PI; + else + aEndAngle = angle_xform( endAngle ); } diff --git a/gerbview/gerbview_painter.cpp b/gerbview/gerbview_painter.cpp index 752b6d0e41..7920d30b25 100644 --- a/gerbview/gerbview_painter.cpp +++ b/gerbview/gerbview_painter.cpp @@ -2,7 +2,7 @@ * This program source code file is part of KiCad, a free EDA CAD application. * * Copyright (C) 2017 Jon Evans - * Copyright (C) 2017 KiCad Developers, see AUTHORS.txt for contributors. + * Copyright (C) 2019 KiCad Developers, see AUTHORS.txt for contributors. * * This program is free software: you can redistribute it and/or modify it * under the terms of the GNU General Public License as published by the @@ -315,21 +315,21 @@ void GERBVIEW_PAINTER::draw( /*const*/ GERBER_DRAW_ITEM* aItem, int aLayer ) if( startAngle > endAngle ) endAngle += (2 * M_PI); - // 360-degree arcs are stored in the file with start equal to end + // In Gerber, 360-degree arcs are stored in the file with start equal to end if( arcStart == arcEnd ) { - startAngle = 0; - endAngle = 2 * M_PI; + endAngle = startAngle + 2*M_PI; } m_gal->DrawArcSegment( center, radius, startAngle, endAngle, width ); - // Arc Debugging - // m_gal->SetLineWidth( 5 ); - // m_gal->SetStrokeColor( COLOR4D( 0.0, 1.0, 0.0, 1.0 ) ); - // m_gal->DrawLine( center, aItem->GetABPosition( arcStart ) ); - // m_gal->SetStrokeColor( COLOR4D( 1.0, 0.0, 0.0, 1.0 ) ); - // m_gal->DrawLine( center, aItem->GetABPosition( arcEnd ) ); +#if 0 // Arc Debugging only + m_gal->SetLineWidth( 5 ); + m_gal->SetStrokeColor( COLOR4D( 0.0, 1.0, 0.0, 1.0 ) ); + m_gal->DrawLine( center, aItem->GetABPosition( arcStart ) ); + m_gal->SetStrokeColor( COLOR4D( 1.0, 0.0, 0.0, 1.0 ) ); + m_gal->DrawLine( center, aItem->GetABPosition( arcEnd ) ); +#endif break; }