Advertisement
Guest User

Untitled

a guest
May 17th, 2017
91
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 2.69 KB | None | 0 0
  1. Add "Math" to uses (implementation section) - ArcTan2, EnsureRange, Tan and SinCos are used from there:
  2.  
  3. ...
  4. uses
  5. Windows, WinSpool, Math,
  6. ...
  7.  
  8. ****************************
  9.  
  10. procedure TPdfCanvas.Arc(aArcDirection:integer; aRect: TPdfRect;
  11. aStartPointX, aStartPointY, aEndPointX, aEndPointY: single);
  12. // see https://www.spaceroots.org/documents/ellipse/node22.html
  13. var StartAngle, EndAngle, TotalAngle, SpanAngle: single;
  14. CenterX, CenterY, RadiusX, RadiusY: single;
  15. NumOfFragments, Fragment:integer;
  16. StartSi, StartCo, EndSi, EndCo: single;
  17. StartX, StartY, EndX, EndY: single;
  18. C1X, C1Y, C2X, C2Y: single;
  19. Tmp:single;
  20. begin
  21. CenterX:=(aRect.Left+aRect.Right)/2;
  22. CenterY:=(aRect.Top+aRect.Bottom)/2;
  23. RadiusX:=abs(aRect.Right-CenterX);
  24. RadiusY:=abs(aRect.Bottom-CenterY);
  25. StartAngle:=ArcTan2(aStartPointY-CenterY, aStartPointX-CenterX);
  26. EndAngle:=ArcTan2(aEndPointY-CenterY, aEndPointX-CenterX);
  27. if EndAngle=StartAngle then EndAngle:=StartAngle+c2PI; // MSDN: If the starting point and ending point are the same, a complete ellipse is drawn.
  28. // check arc direction
  29. if aArcDirection=AD_CLOCKWISE then begin
  30. Tmp:=StartAngle;
  31. StartAngle:=EndAngle;
  32. EndAngle:=Tmp;
  33. end;
  34. //
  35. if StartAngle<EndAngle
  36. then TotalAngle:=EndAngle-StartAngle
  37. else TotalAngle:=EndAngle-StartAngle+C2Pi;
  38. NumOfFragments:=EnsureRange(trunc(TotalAngle/cPIdiv2)+1, 1, 4);
  39. SpanAngle:=TotalAngle/NumOfFragments;
  40. Tmp:=Sin(SpanAngle)*(Sqrt(4+3*Sqr(Tan(SpanAngle/2)))-1)/3;
  41. //
  42. SinCos(StartAngle, StartSi, StartCo);
  43. StartX:=CenterX+RadiusX*StartCo;
  44. StartY:=CenterY+RadiusY*StartSi;
  45. MoveTo(StartX, StartY);
  46. for Fragment:=1 to NumOfFragments do begin
  47. EndAngle:=StartAngle+TotalAngle*Fragment/NumOfFragments; // not using SpanAngle - avoid rounding errors
  48. SinCos(EndAngle, EndSi, EndCo);
  49. EndX:=CenterX+RadiusX*EndCo;
  50. EndY:=CenterY+RadiusY*EndSi;
  51. C1X:=StartX+Tmp*(-RadiusX*StartSi);
  52. C1Y:=StartY+Tmp*( RadiusY*StartCo);
  53. C2X:=EndX-Tmp*(-RadiusX*EndSi);
  54. C2Y:=EndY-Tmp*( RadiusY*EndCo);
  55. CurveToC(C1X, C1Y, C2X, C2Y, EndX, EndY);
  56. //
  57. StartSi:=EndSi;
  58. StartCo:=EndCo;
  59. StartX:=EndX;
  60. StartY:=EndY;
  61. end;
  62. end;
  63.  
  64.  
  65. ****************************
  66.  
  67. Add to
  68. function EnumEMFFunc(DC: HDC; var Table: THandleTable; R: PEnhMetaRecord;
  69. NumObjects: DWord; E: TPdfEnum): LongBool; stdcall;
  70.  
  71. ...
  72. EMR_ARC: begin
  73. E.NeedPen;
  74. E.Canvas.Arc(ArcDirection, E.Canvas.RectI(PEMRArc(R)^.rclBox, false),
  75. E.Canvas.I2X(PEMRArc(R)^.ptlStart.X), E.Canvas.I2Y(PEMRArc(R)^.ptlStart.Y),
  76. E.Canvas.I2X(PEMRArc(R)^.ptlEnd.X), E.Canvas.I2Y(PEMRArc(R)^.ptlEnd.Y) );
  77. E.Canvas.Stroke;
  78. E.FlushPenBrush;
  79. end;
  80. ...
  81.  
  82.  
  83. ****************************
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement