fpvectorial: Fix rendering of elliptical arc path segments.

git-svn-id: trunk@52895 -
This commit is contained in:
wp 2016-08-30 21:33:39 +00:00
parent ba13893b95
commit 0ed4960cd0
4 changed files with 30 additions and 12 deletions

View File

@ -316,6 +316,8 @@ type
{ TPathSegment }
TPathSegment = class
protected
FPath: TPath;
public
SegmentType: TSegmentType;
// Fields for linking the list
@ -332,6 +334,8 @@ type
function GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer): Pointer; virtual;
// rendering
procedure AddToPoints(ADestX, ADestY: Integer; AMulX, AMulY: Double; var Points: TPointsArray); virtual;
// helper methods
function UseTopLeftCoordinates: Boolean;
end;
{@@
@ -2907,6 +2911,7 @@ var
xstart, ystart: Double;
n: Integer;
done: Boolean;
clockwise: Boolean;
begin
n := 0;
SetLength(Points, BUFSIZE);
@ -2918,21 +2923,25 @@ begin
tstart := CalcEllipsePointAngle(xstart, ystart, RX, RY, CX, CY, XRotation);
tend := CalcEllipsePointAngle(X, Y, RX, RY, CX, CY, XRotation);
// wp: Something's wrong here: I think "clockwise" is the other way round...
// Flip clockwise flag in case of top/left coordinates
clockwise := ClockwiseArcFlag xor UseTopLeftCoordinates;
if ClockwiseArcFlag then
begin // tend must be larger than tstart
if tend < tstart then tend := TWO_PI + tend;
end else begin // tend must be smaller than tstart
if tstart < tend then tstart := TWO_PI + tstart;
if clockwise then
begin
// clockwise --> angle decreases --> tstart must be > tend
dt := -dt;
if tstart < tend then tstart := TWO_PI + tstart;
end else
begin
// counter-clockwise --> angle increases --> tstart must be < tend
if tend < tstart then tend := TWO_PI + tend;
end;
done := false;
t := tstart;
while not done do begin
if (ClockwiseArcFlag and (t > tend)) or
(not ClockwiseArcFlag and (t < tend)) then
if (clockwise and (t < tend)) or // angle decreases
(not clockwise and (t > tend)) then // angle increases
begin
t := tend;
done := true;
@ -2941,7 +2950,7 @@ begin
SetLength(Points, Length(Points) + BUFSIZE);
CalcEllipsePoint(t, RX, RY, CX, CY, XRotation, Points[n].x, Points[n].y);
inc(n);
t := t + dt; // Note: dt is <0 in counter-clockwise case
t := t + dt; // Note: dt is < 0 in clockwise case
end;
SetLength(Points, n);
end;
@ -3345,6 +3354,11 @@ begin
// Override by descendants
end;
function TPathSegment.UseTopLeftCoordinates: Boolean;
begin
Result := (FPath <> nil) and FPath.FPage.UseTopLeftCoordinates;
end;
{ T2DSegment }
@ -4796,6 +4810,8 @@ procedure TPath.AppendSegment(ASegment: TPathSegment);
var
L: Integer;
begin
ASegment.FPath := self;
// Check if we are the first segment in the tmp path
if PointsEnd = nil then
begin

View File

@ -553,7 +553,7 @@ begin
// Rotate ellipse back to align its major axis with the x axis
P := Rotate3dPointInXY(Make3dPoint(x-cx, y-cy, 0), Make3dPoint(0, 0, 0), phi);
// Correctly speaking, above line should use -phi, instead of phi. But
// Make3DPointInXY seems to define the angle in the opposite way.
// Rotate3DPointInXY seems to define the angle in the opposite way.
Result := arctan2(P.Y/ry, P.X/rx);
if Result < 0 then Result := TWO_PI + Result;
end;

View File

@ -418,7 +418,7 @@ begin
TRenderParams.Create(@Render_SelfIntersectingPoly_GradientFill_NonZeroWinding, 'selfintersecting_poly_gradient_nzw.png'));
node0 := Tree.Items.AddChild(nil, 'Arcs');
node := Tree.Items.AddChild(node0, 'clockwise "1" --> "2"');
node := Tree.Items.AddChild(node0, 'clockwise from point 1 to point 2');
Tree.Items.AddChildObject(node, 'Quarter circle in quadrant I',
TRenderParams.Create(@Render_Arc_CW_Q1, 'arc_cw_q1.png'));
Tree.Items.AddChildObject(node, 'Quarter circle in quadrant I+II',
@ -435,7 +435,7 @@ begin
TRenderParams.Create(@Render_Arc_CW_Q4, 'arc_cw_q4.png'));
Tree.Items.AddChildObject(node, 'Quarter circle in quadrant IV+I',
TRenderParams.Create(@Render_Arc_CW_Q41, 'arc_cw_q41.png'));
node := Tree.Items.AddChild(node0, 'counterclockwise "1" --> "2"');
node := Tree.Items.AddChild(node0, 'counterclockwise from point 1 to point 2');
Tree.Items.AddChildObject(node, 'Quarter circle in quadrant I',
TRenderParams.Create(@Render_Arc_CCW_Q1, 'arc_ccw_q1.png'));
Tree.Items.AddChildObject(node, 'Quarter circle in quadrant I+II',

View File

@ -154,12 +154,14 @@ begin
txt.Value.Add('1');
txt.X := X1;
txt.Y := Y1;
txt.Font.Color := colRed;
APage.AddEntity(txt);
txt := TvText.Create(APage);
txt.Value.Add('2');
txt.X := X2;
txt.Y := Y2;
txt.Font.Color := colRed;
APage.AddEntity(txt);
end;