From 5af8d2d0a8e84c1bd75d32dc9bfb94b1c3ebc0da Mon Sep 17 00:00:00 2001 From: Seth Hillbrand Date: Mon, 18 Feb 2019 09:39:10 -0800 Subject: [PATCH] cairo: Fix rotated oval pads Fixes: lp:1816428 * https://bugs.launchpad.net/kicad/+bug/1816428 --- common/gal/cairo/cairo_gal.cpp | 30 ++++++++++++++++++++---------- include/gal/cairo/cairo_gal.h | 1 + include/gal/definitions.h | 11 +++++++++-- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/common/gal/cairo/cairo_gal.cpp b/common/gal/cairo/cairo_gal.cpp index 56683df328..8acdf53321 100644 --- a/common/gal/cairo/cairo_gal.cpp +++ b/common/gal/cairo/cairo_gal.cpp @@ -110,6 +110,14 @@ const VECTOR2D CAIRO_GAL_BASE::xform( const VECTOR2D& aP ) } +const double CAIRO_GAL_BASE::angle_xform( const double aAngle ) +{ + double world_angle = -std::atan2( currentWorld2Screen.xy, currentWorld2Screen.xx ); + + return std::fmod( aAngle + world_angle, 2.0 * M_PI ); +} + + const double CAIRO_GAL_BASE::xform( double x ) { double dx = currentWorld2Screen.xx * x; @@ -256,7 +264,9 @@ void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, doub 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 { @@ -265,7 +275,7 @@ void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, doub cairo_set_line_width( currentContext, 1.0 ); cairo_new_sub_path( currentContext ); - cairo_arc( currentContext, c.x, c.y, r, aStartAngle, aEndAngle ); + 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 ); @@ -277,7 +287,7 @@ void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, doub cairo_set_line_width( currentContext, lineWidthInPixels ); cairo_new_sub_path( currentContext ); - cairo_arc( currentContext, c.x, c.y, r, aStartAngle, aEndAngle ); + cairo_arc( currentContext, c.x, c.y, r, startAngleS, endAngleS ); flushPath(); isElementAdded = true; @@ -290,13 +300,15 @@ void CAIRO_GAL_BASE::DrawRectangle( const VECTOR2D& aStartPoint, const VECTOR2D& syncLineWidth(); const auto p0 = roundp( xform( aStartPoint ) ); - const auto p1 = roundp( xform( aEndPoint ) ); + const auto p1 = roundp( xform( VECTOR2D( aEndPoint.x, aStartPoint.y ) ) ); + const auto p2 = roundp( xform( aEndPoint ) ); + const auto p3 = roundp( xform( VECTOR2D( aStartPoint.x, aEndPoint.y ) ) ); // The path is composed from 4 segments cairo_move_to( currentContext, p0.x, p0.y ); - cairo_line_to( currentContext, p1.x, p0.y ); cairo_line_to( currentContext, p1.x, p1.y ); - cairo_line_to( currentContext, p0.x, p1.y ); + cairo_line_to( currentContext, p2.x, p2.y ); + cairo_line_to( currentContext, p3.x, p3.y ); cairo_close_path( currentContext ); flushPath(); @@ -1452,11 +1464,9 @@ void CAIRO_GAL_BASE::DrawGrid() int gridEndY = KiROUND( ( worldEndPoint.y - gridOrigin.y ) / gridSize.y ); // Ensure start coordinate > end coordinate - if( gridStartX > gridEndX ) - std::swap( gridStartX, gridEndX ); - if( gridStartY > gridEndY ) - std::swap( gridStartY, gridEndY ); + SWAP( gridStartX, >, gridStartX ); + SWAP( gridStartY, >, gridEndY ); // Ensure the grid fills the screen --gridStartX; ++gridEndX; diff --git a/include/gal/cairo/cairo_gal.h b/include/gal/cairo/cairo_gal.h index e39aebe4aa..dd43dda286 100644 --- a/include/gal/cairo/cairo_gal.h +++ b/include/gal/cairo/cairo_gal.h @@ -218,6 +218,7 @@ protected: const double xform( double x ); const VECTOR2D xform( double x, double y ); const VECTOR2D xform( const VECTOR2D& aP ); + const double angle_xform( const double aAngle ); /// @copydoc GAL::BeginDrawing() virtual void beginDrawing() override; diff --git a/include/gal/definitions.h b/include/gal/definitions.h index 4ee1d6f077..456d5f6c29 100644 --- a/include/gal/definitions.h +++ b/include/gal/definitions.h @@ -28,8 +28,15 @@ #define DEFINITIONS_H_ /// Swap the variables if a condition is met. -#define SWAP( varA, condition, varB ) if( varA condition varB ) { double tmp = varA; varA = varB; \ - varB = tmp; } +#define SWAP( varA, condition, varB ) \ + assert( typeid( varA ).hash_code() == typeid( varB ).hash_code() ); \ + \ + if( varA condition varB ) \ + { \ + decltype( varA ) tmp = varA; \ + varA = varB; \ + varB = tmp; \ + } namespace KIGFX {