mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-10-17 22:01:44 +02:00
fpvectorial: Fix rendering of elliptical arc path segments.
git-svn-id: trunk@52895 -
This commit is contained in:
parent
ba13893b95
commit
0ed4960cd0
@ -316,6 +316,8 @@ type
|
|||||||
{ TPathSegment }
|
{ TPathSegment }
|
||||||
|
|
||||||
TPathSegment = class
|
TPathSegment = class
|
||||||
|
protected
|
||||||
|
FPath: TPath;
|
||||||
public
|
public
|
||||||
SegmentType: TSegmentType;
|
SegmentType: TSegmentType;
|
||||||
// Fields for linking the list
|
// Fields for linking the list
|
||||||
@ -332,6 +334,8 @@ type
|
|||||||
function GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer): Pointer; virtual;
|
function GenerateDebugTree(ADestRoutine: TvDebugAddItemProc; APageItem: Pointer): Pointer; virtual;
|
||||||
// rendering
|
// rendering
|
||||||
procedure AddToPoints(ADestX, ADestY: Integer; AMulX, AMulY: Double; var Points: TPointsArray); virtual;
|
procedure AddToPoints(ADestX, ADestY: Integer; AMulX, AMulY: Double; var Points: TPointsArray); virtual;
|
||||||
|
// helper methods
|
||||||
|
function UseTopLeftCoordinates: Boolean;
|
||||||
end;
|
end;
|
||||||
|
|
||||||
{@@
|
{@@
|
||||||
@ -2907,6 +2911,7 @@ var
|
|||||||
xstart, ystart: Double;
|
xstart, ystart: Double;
|
||||||
n: Integer;
|
n: Integer;
|
||||||
done: Boolean;
|
done: Boolean;
|
||||||
|
clockwise: Boolean;
|
||||||
begin
|
begin
|
||||||
n := 0;
|
n := 0;
|
||||||
SetLength(Points, BUFSIZE);
|
SetLength(Points, BUFSIZE);
|
||||||
@ -2918,21 +2923,25 @@ begin
|
|||||||
tstart := CalcEllipsePointAngle(xstart, ystart, RX, RY, CX, CY, XRotation);
|
tstart := CalcEllipsePointAngle(xstart, ystart, RX, RY, CX, CY, XRotation);
|
||||||
tend := CalcEllipsePointAngle(X, Y, 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
|
if clockwise then
|
||||||
begin // tend must be larger than tstart
|
begin
|
||||||
if tend < tstart then tend := TWO_PI + tend;
|
// clockwise --> angle decreases --> tstart must be > tend
|
||||||
end else begin // tend must be smaller than tstart
|
|
||||||
if tstart < tend then tstart := TWO_PI + tstart;
|
|
||||||
dt := -dt;
|
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;
|
end;
|
||||||
|
|
||||||
done := false;
|
done := false;
|
||||||
t := tstart;
|
t := tstart;
|
||||||
while not done do begin
|
while not done do begin
|
||||||
if (ClockwiseArcFlag and (t > tend)) or
|
if (clockwise and (t < tend)) or // angle decreases
|
||||||
(not ClockwiseArcFlag and (t < tend)) then
|
(not clockwise and (t > tend)) then // angle increases
|
||||||
begin
|
begin
|
||||||
t := tend;
|
t := tend;
|
||||||
done := true;
|
done := true;
|
||||||
@ -2941,7 +2950,7 @@ begin
|
|||||||
SetLength(Points, Length(Points) + BUFSIZE);
|
SetLength(Points, Length(Points) + BUFSIZE);
|
||||||
CalcEllipsePoint(t, RX, RY, CX, CY, XRotation, Points[n].x, Points[n].y);
|
CalcEllipsePoint(t, RX, RY, CX, CY, XRotation, Points[n].x, Points[n].y);
|
||||||
inc(n);
|
inc(n);
|
||||||
t := t + dt; // Note: dt is <0 in counter-clockwise case
|
t := t + dt; // Note: dt is < 0 in clockwise case
|
||||||
end;
|
end;
|
||||||
SetLength(Points, n);
|
SetLength(Points, n);
|
||||||
end;
|
end;
|
||||||
@ -3345,6 +3354,11 @@ begin
|
|||||||
// Override by descendants
|
// Override by descendants
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
function TPathSegment.UseTopLeftCoordinates: Boolean;
|
||||||
|
begin
|
||||||
|
Result := (FPath <> nil) and FPath.FPage.UseTopLeftCoordinates;
|
||||||
|
end;
|
||||||
|
|
||||||
|
|
||||||
{ T2DSegment }
|
{ T2DSegment }
|
||||||
|
|
||||||
@ -4796,6 +4810,8 @@ procedure TPath.AppendSegment(ASegment: TPathSegment);
|
|||||||
var
|
var
|
||||||
L: Integer;
|
L: Integer;
|
||||||
begin
|
begin
|
||||||
|
ASegment.FPath := self;
|
||||||
|
|
||||||
// Check if we are the first segment in the tmp path
|
// Check if we are the first segment in the tmp path
|
||||||
if PointsEnd = nil then
|
if PointsEnd = nil then
|
||||||
begin
|
begin
|
||||||
|
@ -553,7 +553,7 @@ begin
|
|||||||
// Rotate ellipse back to align its major axis with the x axis
|
// 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);
|
P := Rotate3dPointInXY(Make3dPoint(x-cx, y-cy, 0), Make3dPoint(0, 0, 0), phi);
|
||||||
// Correctly speaking, above line should use -phi, instead of phi. But
|
// 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);
|
Result := arctan2(P.Y/ry, P.X/rx);
|
||||||
if Result < 0 then Result := TWO_PI + Result;
|
if Result < 0 then Result := TWO_PI + Result;
|
||||||
end;
|
end;
|
||||||
|
@ -418,7 +418,7 @@ begin
|
|||||||
TRenderParams.Create(@Render_SelfIntersectingPoly_GradientFill_NonZeroWinding, 'selfintersecting_poly_gradient_nzw.png'));
|
TRenderParams.Create(@Render_SelfIntersectingPoly_GradientFill_NonZeroWinding, 'selfintersecting_poly_gradient_nzw.png'));
|
||||||
|
|
||||||
node0 := Tree.Items.AddChild(nil, 'Arcs');
|
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',
|
Tree.Items.AddChildObject(node, 'Quarter circle in quadrant I',
|
||||||
TRenderParams.Create(@Render_Arc_CW_Q1, 'arc_cw_q1.png'));
|
TRenderParams.Create(@Render_Arc_CW_Q1, 'arc_cw_q1.png'));
|
||||||
Tree.Items.AddChildObject(node, 'Quarter circle in quadrant I+II',
|
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'));
|
TRenderParams.Create(@Render_Arc_CW_Q4, 'arc_cw_q4.png'));
|
||||||
Tree.Items.AddChildObject(node, 'Quarter circle in quadrant IV+I',
|
Tree.Items.AddChildObject(node, 'Quarter circle in quadrant IV+I',
|
||||||
TRenderParams.Create(@Render_Arc_CW_Q41, 'arc_cw_q41.png'));
|
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',
|
Tree.Items.AddChildObject(node, 'Quarter circle in quadrant I',
|
||||||
TRenderParams.Create(@Render_Arc_CCW_Q1, 'arc_ccw_q1.png'));
|
TRenderParams.Create(@Render_Arc_CCW_Q1, 'arc_ccw_q1.png'));
|
||||||
Tree.Items.AddChildObject(node, 'Quarter circle in quadrant I+II',
|
Tree.Items.AddChildObject(node, 'Quarter circle in quadrant I+II',
|
||||||
|
@ -154,12 +154,14 @@ begin
|
|||||||
txt.Value.Add('1');
|
txt.Value.Add('1');
|
||||||
txt.X := X1;
|
txt.X := X1;
|
||||||
txt.Y := Y1;
|
txt.Y := Y1;
|
||||||
|
txt.Font.Color := colRed;
|
||||||
APage.AddEntity(txt);
|
APage.AddEntity(txt);
|
||||||
|
|
||||||
txt := TvText.Create(APage);
|
txt := TvText.Create(APage);
|
||||||
txt.Value.Add('2');
|
txt.Value.Add('2');
|
||||||
txt.X := X2;
|
txt.X := X2;
|
||||||
txt.Y := Y2;
|
txt.Y := Y2;
|
||||||
|
txt.Font.Color := colRed;
|
||||||
APage.AddEntity(txt);
|
APage.AddEntity(txt);
|
||||||
end;
|
end;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user