Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- Add "Math" to uses (implementation section) - ArcTan2, EnsureRange, Tan and SinCos are used from there:
- ...
- uses
- Windows, WinSpool, Math,
- ...
- ****************************
- procedure TPdfCanvas.Arc(aArcDirection:integer; aRect: TPdfRect;
- aStartPointX, aStartPointY, aEndPointX, aEndPointY: single);
- // see https://www.spaceroots.org/documents/ellipse/node22.html
- var StartAngle, EndAngle, TotalAngle, SpanAngle: single;
- CenterX, CenterY, RadiusX, RadiusY: single;
- NumOfFragments, Fragment:integer;
- StartSi, StartCo, EndSi, EndCo: single;
- StartX, StartY, EndX, EndY: single;
- C1X, C1Y, C2X, C2Y: single;
- Tmp:single;
- begin
- CenterX:=(aRect.Left+aRect.Right)/2;
- CenterY:=(aRect.Top+aRect.Bottom)/2;
- RadiusX:=abs(aRect.Right-CenterX);
- RadiusY:=abs(aRect.Bottom-CenterY);
- StartAngle:=ArcTan2(aStartPointY-CenterY, aStartPointX-CenterX);
- EndAngle:=ArcTan2(aEndPointY-CenterY, aEndPointX-CenterX);
- if EndAngle=StartAngle then EndAngle:=StartAngle+c2PI; // MSDN: If the starting point and ending point are the same, a complete ellipse is drawn.
- // check arc direction
- if aArcDirection=AD_CLOCKWISE then begin
- Tmp:=StartAngle;
- StartAngle:=EndAngle;
- EndAngle:=Tmp;
- end;
- //
- if StartAngle<EndAngle
- then TotalAngle:=EndAngle-StartAngle
- else TotalAngle:=EndAngle-StartAngle+C2Pi;
- NumOfFragments:=EnsureRange(trunc(TotalAngle/cPIdiv2)+1, 1, 4);
- SpanAngle:=TotalAngle/NumOfFragments;
- Tmp:=Sin(SpanAngle)*(Sqrt(4+3*Sqr(Tan(SpanAngle/2)))-1)/3;
- //
- SinCos(StartAngle, StartSi, StartCo);
- StartX:=CenterX+RadiusX*StartCo;
- StartY:=CenterY+RadiusY*StartSi;
- MoveTo(StartX, StartY);
- for Fragment:=1 to NumOfFragments do begin
- EndAngle:=StartAngle+TotalAngle*Fragment/NumOfFragments; // not using SpanAngle - avoid rounding errors
- SinCos(EndAngle, EndSi, EndCo);
- EndX:=CenterX+RadiusX*EndCo;
- EndY:=CenterY+RadiusY*EndSi;
- C1X:=StartX+Tmp*(-RadiusX*StartSi);
- C1Y:=StartY+Tmp*( RadiusY*StartCo);
- C2X:=EndX-Tmp*(-RadiusX*EndSi);
- C2Y:=EndY-Tmp*( RadiusY*EndCo);
- CurveToC(C1X, C1Y, C2X, C2Y, EndX, EndY);
- //
- StartSi:=EndSi;
- StartCo:=EndCo;
- StartX:=EndX;
- StartY:=EndY;
- end;
- end;
- ****************************
- Add to
- function EnumEMFFunc(DC: HDC; var Table: THandleTable; R: PEnhMetaRecord;
- NumObjects: DWord; E: TPdfEnum): LongBool; stdcall;
- ...
- EMR_ARC: begin
- E.NeedPen;
- E.Canvas.Arc(ArcDirection, E.Canvas.RectI(PEMRArc(R)^.rclBox, false),
- E.Canvas.I2X(PEMRArc(R)^.ptlStart.X), E.Canvas.I2Y(PEMRArc(R)^.ptlStart.Y),
- E.Canvas.I2X(PEMRArc(R)^.ptlEnd.X), E.Canvas.I2Y(PEMRArc(R)^.ptlEnd.Y) );
- E.Canvas.Stroke;
- E.FlushPenBrush;
- end;
- ...
- ****************************
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement