Cairo GAL: fix incorrect arc position in mirror mode. the previous fix
(c56e540e5d
) did not really work.
Fix from master branch.
This commit is contained in:
parent
89f9bf545d
commit
cebba6c0b9
|
@ -117,9 +117,37 @@ const VECTOR2D CAIRO_GAL_BASE::xform( const VECTOR2D& aP )
|
||||||
|
|
||||||
const double CAIRO_GAL_BASE::angle_xform( const double aAngle )
|
const double CAIRO_GAL_BASE::angle_xform( const double aAngle )
|
||||||
{
|
{
|
||||||
double world_angle = -std::atan2( currentWorld2Screen.xy, currentWorld2Screen.xx );
|
// calculate rotation angle due to the rotation transform
|
||||||
|
// and if flipped on X axis.
|
||||||
|
double world_rotation = -std::atan2( currentWorld2Screen.xy, currentWorld2Screen.xx );
|
||||||
|
|
||||||
return std::fmod( aAngle + world_angle, 2.0 * M_PI );
|
// When flipped on X axis, the rotation angle is M_PI - initial angle:
|
||||||
|
if( IsFlippedX() )
|
||||||
|
world_rotation = M_PI - world_rotation;
|
||||||
|
|
||||||
|
return std::fmod( aAngle + world_rotation, 2.0 * M_PI );
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
void CAIRO_GAL_BASE::arc_angles_xform_and_normalize( double& aStartAngle, double& aEndAngle )
|
||||||
|
{
|
||||||
|
double startAngle = aStartAngle;
|
||||||
|
double endAngle = aEndAngle;
|
||||||
|
|
||||||
|
// When the view is flipped, the coordinates are flipped by the matrix transform
|
||||||
|
// However, arc angles need to be "flipped": the flipped angle is M_PI - initial angle.
|
||||||
|
if( IsFlippedX() )
|
||||||
|
{
|
||||||
|
startAngle = M_PI - startAngle;
|
||||||
|
endAngle = M_PI - endAngle;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Normalize arc angles
|
||||||
|
SWAP( startAngle, >, endAngle );
|
||||||
|
|
||||||
|
// now rotate arc according to the rotation transform matrix
|
||||||
|
aStartAngle = angle_xform( startAngle );
|
||||||
|
aEndAngle = angle_xform( endAngle );
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -259,21 +287,11 @@ void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, doub
|
||||||
{
|
{
|
||||||
syncLineWidth();
|
syncLineWidth();
|
||||||
|
|
||||||
// When the view is flipped, the coordinates are flipped by the matrix transform
|
// calculate start and end arc angles according to the rotation transform matrix
|
||||||
// However, arc angles need a small change: swapping start and end, *without changing*
|
// and normalize:
|
||||||
// the arc orientation.
|
arc_angles_xform_and_normalize( aStartAngle, aEndAngle );
|
||||||
// TODO: see the changes if the flip is for the Y axis
|
|
||||||
if( IsFlippedX() )
|
|
||||||
{
|
|
||||||
double delta = aEndAngle - aStartAngle;
|
|
||||||
aEndAngle = aStartAngle;
|
|
||||||
aStartAngle -= delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
SWAP( aStartAngle, >, aEndAngle );
|
double r = xform( aRadius );
|
||||||
auto startAngleS = angle_xform( aStartAngle );
|
|
||||||
auto endAngleS = angle_xform( aEndAngle );
|
|
||||||
auto r = xform( aRadius );
|
|
||||||
|
|
||||||
// N.B. This is backwards. We set this because we want to adjust the center
|
// 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.
|
// point that changes both endpoints. In the worst case, this is twice as far.
|
||||||
|
@ -289,7 +307,7 @@ void CAIRO_GAL_BASE::DrawArc( const VECTOR2D& aCenterPoint, double aRadius, doub
|
||||||
if( isFillEnabled )
|
if( isFillEnabled )
|
||||||
cairo_move_to( currentContext, mid.x, mid.y );
|
cairo_move_to( currentContext, mid.x, mid.y );
|
||||||
|
|
||||||
cairo_arc( currentContext, mid.x, mid.y, r, startAngleS, endAngleS );
|
cairo_arc( currentContext, mid.x, mid.y, r, aStartAngle, aEndAngle );
|
||||||
|
|
||||||
if( isFillEnabled )
|
if( isFillEnabled )
|
||||||
cairo_close_path( currentContext );
|
cairo_close_path( currentContext );
|
||||||
|
@ -316,21 +334,13 @@ void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadiu
|
||||||
|
|
||||||
syncLineWidth();
|
syncLineWidth();
|
||||||
|
|
||||||
// When the view is flipped, the coordinates are flipped by the matrix transform
|
// calculate start and end arc angles according to the rotation transform matrix
|
||||||
// However, arc angles need a small change: swapping start and end, *without changing*
|
// and normalize:
|
||||||
// the arc orientation.
|
double startAngleS = aStartAngle;
|
||||||
// TODO: see the changes if the flip is for the Y axis
|
double endAngleS = aEndAngle;
|
||||||
if( IsFlippedX() )
|
arc_angles_xform_and_normalize( startAngleS, endAngleS );
|
||||||
{
|
|
||||||
double delta = aEndAngle - aStartAngle;
|
|
||||||
aEndAngle = aStartAngle;
|
|
||||||
aStartAngle -= delta;
|
|
||||||
}
|
|
||||||
|
|
||||||
SWAP( aStartAngle, >, aEndAngle );
|
double r = xform( aRadius );
|
||||||
auto startAngleS = angle_xform( aStartAngle );
|
|
||||||
auto endAngleS = angle_xform( aEndAngle );
|
|
||||||
auto r = xform( aRadius );
|
|
||||||
|
|
||||||
// N.B. This is backwards. We set this because we want to adjust the center
|
// 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.
|
// point that changes both endpoints. In the worst case, this is twice as far.
|
||||||
|
@ -339,7 +349,7 @@ void CAIRO_GAL_BASE::DrawArcSegment( const VECTOR2D& aCenterPoint, double aRadiu
|
||||||
lineWidthIsOdd = !( static_cast<int>( aRadius ) % 1 );
|
lineWidthIsOdd = !( static_cast<int>( aRadius ) % 1 );
|
||||||
|
|
||||||
auto mid = roundp( xform( aCenterPoint ) );
|
auto mid = roundp( xform( aCenterPoint ) );
|
||||||
auto width = xform( aWidth / 2.0 );
|
double width = xform( aWidth / 2.0 );
|
||||||
auto startPointS = VECTOR2D( r, 0.0 ).Rotate( startAngleS );
|
auto startPointS = VECTOR2D( r, 0.0 ).Rotate( startAngleS );
|
||||||
auto endPointS = VECTOR2D( r, 0.0 ).Rotate( endAngleS );
|
auto endPointS = VECTOR2D( r, 0.0 ).Rotate( endAngleS );
|
||||||
|
|
||||||
|
|
|
@ -219,11 +219,24 @@ public:
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
const double xform( double x );
|
// Geometric transforms according to the currentWorld2Screen transform matrix:
|
||||||
const VECTOR2D xform( double x, double y );
|
const double xform( double x ); // scale
|
||||||
const VECTOR2D xform( const VECTOR2D& aP );
|
const VECTOR2D xform( double x, double y ); // rotation, scale and offset
|
||||||
|
const VECTOR2D xform( const VECTOR2D& aP ); // rotation, scale and offset
|
||||||
|
|
||||||
|
/** Transform according to the rotation from currentWorld2Screen transform matrix:
|
||||||
|
* @param aAngle is the angle in radians to transform
|
||||||
|
* @return the modified angle
|
||||||
|
*/
|
||||||
const double angle_xform( const double aAngle );
|
const double angle_xform( const double aAngle );
|
||||||
|
|
||||||
|
/** Transform according to the rotation from currentWorld2Screen transform matrix
|
||||||
|
* for the start angle and the end angle of an arc
|
||||||
|
* @param aStartAngle is the arc starting point in radians to transform
|
||||||
|
* @param aEndAngle is the arc ending point in radians to transform
|
||||||
|
*/
|
||||||
|
void arc_angles_xform_and_normalize( double& aStartAngle, double& aEndAngle );
|
||||||
|
|
||||||
/// @copydoc GAL::BeginDrawing()
|
/// @copydoc GAL::BeginDrawing()
|
||||||
virtual void beginDrawing() override;
|
virtual void beginDrawing() override;
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue