1 unit vtprimitives;
2
3 {$mode objfpc}{$H+}
4
5 interface
6
7 uses
8 Classes, SysUtils, fpcanvas, fpimage, fpvectorial;
9
CreateCirclenull10 function CreateCircle(APage: TvVectorialPage; CtrX, CtrY, R: Double): TvCircle;
CreateEllipsenull11 function CreateEllipse(APage: TvVectorialPage; X1, Y1, X2, Y2: Double): TvEllipse;
CreateRectanglenull12 function CreateRectangle(APage: TvVectorialPage; X1, Y1, X2, Y2: Double): TvRectangle;
CreateRoundedRectnull13 function CreateRoundedRect(APage: TvVectorialPage; X1, Y1, X2, Y2, RX, RY: Double): TvRectangle;
CreatePolygonnull14 function CreatePolygon(APage: TvVectorialPage; const APoints: array of T3DPoint): TvPolygon;
CreateArcnull15 function CreateArc(APage: TvVectorialPage; X1,Y1, X2,Y2, CX,CY, RX, RY, Angle: Double;
16 Clockwise: Boolean): TPath;
CreateBeziernull17 function CreateBezier(APage: TvVectorialPage; X1,Y1, X2,Y2, X3,Y3, X4,Y4: Double): TPath;
18
CreateSimpleBrushnull19 function CreateSimpleBrush(AStyle: TFPBrushStyle; AColor: TFPColor): TvBrush; overload;
CreateSimpleBrushnull20 function CreateSimpleBrush(AStyle: TFPBrushStyle): TvBrush; overload;
CreateLinearGradientBrushnull21 function CreateLinearGradientBrush(AStartPt, AEndPt: T2DPoint; AFlags: TvGradientFlags;
22 AStartColor, AEndColor: TFPColor): TvBrush;
CreateRadialGradientBrushnull23 function CreateRadialGradientBrush(CX, CY, R, FX, FY: Double;
24 AStartColor, AEndColor: TFPColor): TvBrush;
CreatePennull25 function CreatePen(AStyle: TFPPenStyle; AWidth: Integer; AColor: TFPColor): TvPen;
26
CreateStdCirclenull27 function CreateStdCircle(APage: TvVectorialPage): TvCircle;
CreateStdEllipsenull28 function CreateStdEllipse(APage: TvVectorialPage): TvEllipse;
CreateStdRectnull29 function CreateStdRect(APage: TvVectorialPage): TvRectangle;
CreateStdRoundedRectnull30 function CreateStdRoundedRect(APage: TvVectorialPage): TvRectangle;
CreateStdPolygonnull31 function CreateStdPolygon(APage: TvVectorialPage): TvPolygon;
CreateStdSelfIntersectingPolygonnull32 function CreateStdSelfIntersectingPolygon(APage: TvVectorialPage): TvPolygon;
CreatePathWithHolenull33 function CreatePathWithHole(APage: TvVectorialPage): TPath;
34
StdSolidBrushnull35 function StdSolidBrush: TvBrush;
StdHorizGradientBrushnull36 function StdHorizGradientBrush: TvBrush;
StdVertGradientBrushnull37 function StdVertGradientBrush: TvBrush;
StdLinearGradientBrushnull38 function StdLinearGradientBrush: TvBrush;
StdRadialGradientBrushnull39 function StdRadialGradientBrush: TvBrush;
StdPennull40 function StdPen: TvPen;
41
42 const
43 PAGE_SIZE = 100;
44
45
46 implementation
47
48 uses
49 Math, fpvutils;
50
51 { Shapes }
52
53 { circle with specified center and radius.
54 Valid for any coordinate system }
CreateCirclenull55 function CreateCircle(APage: TvVectorialPage; CtrX, CtrY, R: Double): TvCircle;
56 begin
57 Result := TvCircle.Create(APage);
58 Result.X := CtrX;
59 Result.Y := CtrY;
60 Result.Radius := R;
61 Result.Brush := CreateSimpleBrush(bsClear);
62 Result.Pen := CreatePen(psSolid, 1, colBlack);
63 end;
64
65 { Ellipse with specified center and halfaxes.
66 Coordinate system uses an upward y axis for input data, but is flipped if needed }
CreateEllipsenull67 function CreateEllipse(APage: TvVectorialPage; X1, Y1, X2, Y2: Double): TvEllipse;
68 begin
69 Result := TvEllipse.Create(APage);
70 Result.X := (X1 + X2) / 2; // Center
71 Result.Y := (Y1 + Y2) / 2;
72 if APage.UseTopLeftCoordinates then
73 Result.Y := PAGE_SIZE - Result.Y;
74 Result.HorzHalfAxis := abs(X2 - X1) / 2;
75 Result.VertHalfAxis := abs(Y2 - Y1) / 2;
76 Result.Brush := CreateSimpleBrush(bsClear);
77 Result.Pen := CreatePen(psSolid, 1, colBlack);
78 end;
79
80 { Rectangle with specified top/left corner and width and height.
81 Coordinate system uses an upward y axis for input data, but is flipped if needed. }
CreateRectanglenull82 function CreateRectangle(APage: TvVectorialPage; X1, Y1, X2, Y2: Double): TvRectangle;
83 begin
84 Result := TvRectangle.Create(APage);
85 Result.X := Min(X1, X2);
86 if APage.UseTopLeftCoordinates then
87 Result.Y := Min(PAGE_SIZE-Y1, PAGE_SIZE-Y2) else
88 Result.Y := Max(Y1, Y2);
89 Result.CX := abs(X2 - X1); // width
90 Result.CY := abs(Y2 - Y1); // height
91 Result.Brush := CreateSimpleBrush(bsClear);
92 Result.Pen := CreatePen(psSolid, 1, colBlack);
93 end;
94
95 { Rectangle with rounded corner
96 Coordinate system uses an upward y axis for input data, but is flipped if needed. }
CreateRoundedRectnull97 function CreateRoundedRect(APage: TvVectorialPage;
98 X1, Y1, X2, Y2, RX, RY: Double): TvRectangle;
99 begin
100 Result := TvRectangle.Create(APage);
101 Result.X := Min(X1, X2);
102 if APage.UseTopLeftCoordinates then
103 Result.Y := Min(PAGE_SIZE-Y1, PAGE_SIZE-Y2) else
104 Result.Y := Max(Y1, Y2);
105 Result.CX := abs(X2 - X1);
106 Result.CY := abs(Y2 - Y1);
107 Result.RX := RX;
108 Result.RY := RY;
109 Result.Brush := CreateSimpleBrush(bsClear);
110 Result.Pen := CreatePen(psSolid, 1, colBlack);
111 end;
112
113 { Polygon with vertices specified in the array.
114 Valid for any coordinate system. }
CreatePolygonnull115 function CreatePolygon(APage: TvVectorialPage;
116 const APoints: Array of T3DPoint): TvPolygon;
117 var
118 i: Integer;
119 begin
120 Result := TvPolygon.Create(APage);
121 SetLength(Result.Points, Length(APoints));
122 for i:=0 to High(APoints) do
123 Result.Points[i] := APoints[i];
124 Result.X := Result.Points[0].X;
125 Result.Y := Result.Points[0].Y;
126 Result.Brush := CreateSimpleBrush(bsClear);
127 Result.Pen := CreatePen(psSolid, 1, colBlack);
128 end;
129
CreateArcnull130 function CreateArc(APage: TvVectorialPage; X1,Y1, X2,Y2, CX,CY, RX, RY, Angle: Double;
131 Clockwise: Boolean): TPath;
132 var
133 txt: TvText;
134 begin
135 if APage.UseTopLeftCoordinates then begin
136 Y1 := PAGE_SIZE - Y1;
137 Y2 := PAGE_SIZE - Y2;
138 CY := PAGE_SIZE - CY;
139 Angle := -Angle;
140 end;
141 // Don't invert "Clockwise" here. It does not matter where the y axis points to.
142
143 APage.StartPath(X1, Y1);
144 APage.AddEllipticalArcWithCenterToPath(RX, RY, Angle, X2, Y2, CX, CY, Clockwise);
145 Result := APage.EndPath;
146 Result.Pen := StdPen;
147
148 txt := TvText.Create(APage);
149 txt.Value.Add('1');
150 txt.X := X1;
151 txt.Y := Y1;
152 txt.Font.Color := colRed;
153 APage.AddEntity(txt);
154
155 txt := TvText.Create(APage);
156 txt.Value.Add('2');
157 txt.X := X2;
158 txt.Y := Y2;
159 txt.Font.Color := colRed;
160 APage.AddEntity(txt);
161 end;
162
163 function CreateBezier(APage: TvVectorialPage;
164 X1,Y1, X2,Y2, X3,Y3, X4,Y4: Double): TPath;
165 var
166 txt: TvText;
167 begin
168 if APage.UseTopLeftCoordinates then begin
169 Y1 := PAGE_SIZE - Y1;
170 Y2 := PAGE_SIZE - Y2;
171 Y3 := PAGE_SIZE - Y3;
172 Y4 := PAGE_SIZE - Y4;
173 end;
174 APage.StartPath(X1, Y1);
175 APage.AddBezierToPath(X2,Y2, X3,Y3, X4,Y4);
176 Result := APage.EndPath;
177 Result.Pen := StdPen;
178
179 APage.StartPath(X1, Y1);
180 APage.AddLineToPath(X2, Y2);
181 APage.Endpath.Pen.Color := colRed;
182
183 APage.StartPath(X4,Y4);
184 APage.AddLineToPath(X3, Y3);
185 APage.EndPath.Pen.Color := colRed;
186
187 txt := TvText.Create(APage);
188 txt.Value.Add('1');
189 txt.X := X1;
190 txt.Y := Y1;
191 txt.Font.Color := colRed;
192 APage.AddEntity(txt);
193
194 txt := TvText.Create(APage);
195 txt.Value.Add('2');
196 txt.X := X2;
197 txt.Y := Y2;
198 txt.Font.Color := colRed;
199 APage.AddEntity(txt);
200
201 txt := TvText.Create(APage);
202 txt.Value.Add('3');
203 txt.X := X3;
204 txt.Y := Y3;
205 txt.Font.Color := colRed;
206 APage.AddEntity(txt);
207
208 txt := TvText.Create(APage);
209 txt.Value.Add('4');
210 txt.X := X4;
211 txt.Y := Y4;
212 txt.Font.Color := colRed;
213 APage.AddEntity(txt);
214 end;
215
216
217 { Brushes }
218
219 function CreateSimpleBrush(AStyle: TFPBrushStyle): TvBrush;
220 begin
221 Result := CreateSimpleBrush(AStyle, colBlack);
222 end;
223
224 function CreateSimpleBrush(AStyle: TFPBrushStyle; AColor: TFPColor): TvBrush;
225 begin
226 Result.Kind := bkSimpleBrush;
227 Result.Color := TFPColor(AColor);
228 Result.Style := AStyle;
229 end;
230
231 function CreateLinearGradientBrush(AStartPt, AEndPt: T2DPoint;
232 AFlags: TvGradientFlags; AStartColor, AEndColor: TFPColor): TvBrush;
233 var
234 p1, p2: T2dPoint;
235 x1str, x2str, y1str, y2str: String;
236 begin
237 if AStartPt.Y = AEndPt.Y then
238 Result.Kind := bkHorizontalGradient
239 else if AStartPt.X = AEndPt.X then
240 Result.Kind := bkVerticalGradient
241 else
242 Result.Kind := bkOtherLinearGradient;
243 Result.Gradient_start := AStartPt;
244 Result.Gradient_end := AEndPt;
245 Result.Gradient_flags := AFlags;
246 SetLength(Result.Gradient_colors, 2);
247 Result.Gradient_colors[0].Color := AStartColor;
248 Result.Gradient_colors[0].Position := 0;
249 Result.Gradient_colors[1].Color := AEndColor;
250 Result.Gradient_colors[1].Position := 1;
251 end;
252
253 function CreateRadialGradientBrush(CX, CY, R, FX, FY: Double;
254 AStartColor, AEndColor: TFPColor): TvBrush;
255 begin
256 Result.Kind := bkRadialGradient;
257 Result.Gradient_cx := CX;
258 Result.Gradient_cy := CY;
259 Result.Gradient_r := R;
260 Result.Gradient_fx := FX;
261 Result.Gradient_fy := FY;
262 SetLength(Result.Gradient_colors, 2);
263 Result.Gradient_colors[0].Color := AStartColor;
264 Result.Gradient_colors[0].Position := 0;
265 Result.Gradient_colors[1].Color := AEndColor;
266 Result.Gradient_colors[1].Position := 1;
267 end;
268
269
270 { Pen }
271
272 function CreatePen(AStyle: TFPPenStyle; AWidth: Integer; AColor: TFPColor): TvPen;
273 begin
274 Result.Style := AStyle;
275 Result.Width := AWidth;
276 Result.Color := AColor;
277 end;
278
279
280 { Standardized objects }
281
282 { A circle shifted up }
283 function CreateStdCircle(APage: TvVectorialPage): TvCircle;
284 const
285 CENTER_X = 50;
286 CENTER_Y = 55; // y points up for this number
287 RADIUS = 40;
288 begin
289 if APage.UseTopLeftCoordinates then
290 Result := CreateCircle(APage, CENTER_X, PAGE_SIZE - CENTER_Y, RADIUS) else
291 Result := CreateCircle(APage, CENTER_X, CENTER_Y, RADIUS);
292 Result.Pen := StdPen;
293 end;
294
295 { An ellipse shifted up }
296 function CreateStdEllipse(APage: TvVectorialPage): TvEllipse;
297 begin
298 Result := CreateEllipse(APage, 10, 30, 90, 80);
299 // CreateEllipse will invert the axis if needed
300 Result.Pen := StdPen;
301 end;
302
303 { A rectangle shifted up }
304 function CreateStdRect(APage: TvVectorialPage): TvRectangle;
305 const
306 LEFT = 10;
307 RIGHT = 90;
308 TOP = 95; // for bottom-up y axis
309 BOTTOM = 15; // dto.
310 begin
311 Result := CreateRectangle(APage, LEFT, TOP, RIGHT, BOTTOM);
312 // CreateRect will invert the y axis if needed
313 Result.Pen := StdPen;
314 end;
315
316 { A rounded rectangle shifted up }
317 function CreateStdRoundedRect(APage: TvVectorialPage): TvRectangle;
318 const
319 LEFT = 10;
320 RIGHT = 90;
321 TOP = 95; // for bottom-up y axis
322 BOTTOM = 15; // dto.
323 RX = 10;
324 RY = 10;
325 begin
326 Result := CreateRoundedRect(APage,LEFT, TOP, RIGHT, BOTTOM, RX, RY);
327 // CreateRect will invert the y axis if needed
328 Result.Pen := StdPen;
329 end;
330
331 { A triangle as polygon, base line at bottom }
332 function CreateStdPolygon(APage: TvVectorialPage):TvPolygon;
333 var
334 pts: array[0..3] of T3DPoint;
335 i: Integer;
336 begin
337 pts[0] := Make3DPoint(10, 10);
338 pts[1] := Make3dPoint(90, 10);
339 pts[2] := Make3DPoint(50, 90);
340 pts[3] := pts[0];
341 if APage.UseTopLeftCoordinates then
342 for i:=0 to High(pts) do
343 pts[i].Y := PAGE_SIZE - pts[i].Y;
344 Result := CreatePolygon(APage, pts);
345 Result.Pen := StdPen;
346 end;
347
348 { A star-like self-intersecting polygon, tip at bottom }
349 function CreateStdSelfIntersectingPolygon(APage: TvVectorialPage): TvPolygon;
350 var
351 pts: array[0..5] of T3DPoint;
352 i: Integer;
353 begin
354 pts[0] := Make3DPoint(50, 5);
355 pts[1] := Make3DPoint(20, 90);
356 pts[2] := Make3DPoint(95, 30);
357 pts[3] := Make3DPoint(5, 30);
358 pts[4] := Make3DPoint(80, 90);
359 pts[5] := Make3DPoint(50, 5);
360 if APage.UseTopLeftCoordinates then
361 for i:=0 to High(pts) do
362 pts[i].Y := PAGE_SIZE - pts[i].Y;
363 Result := CreatePolygon(APage, pts);
364 Result.Pen := StdPen;
365 end;
366
367 function CreatePathWithHole(APage: TvVectorialPage): TPath;
368 const
369 OUTER_POINTS: array[0..4] of T2DPoint = (
370 (X:10; Y:5), (X:90; Y:5), (X:90; Y:90), (X:10; Y:90), (X:10; Y:5)
371 );
372 INNER_POINTS: array[0..4] of T2DPoint = (
373 (X:50; Y:45), (X:40; Y:55), (X:50; Y:65), (X:60; Y:55), (X:50; Y:45)
374 );
375 var
376 i: Integer;
377 begin
378 if APage.UseTopLeftCoordinates then begin
379 APage.StartPath(OUTER_POINTS[0].X, PAGE_SIZE - OUTER_POINTS[0].Y);
380 for i:=1 to High(OUTER_POINTS) do
381 APage.AddLineToPath(OUTER_POINTS[i].X, PAGE_SIZE - OUTER_POINTS[i].Y);
382 APage.AddMoveToPath(INNER_POINTS[0].X, PAGE_SIZE - INNER_POINTS[0].Y);
383 for i:=1 to High(INNER_POINTS) do
384 APage.AddLineToPath(INNER_POINTS[i].X, PAGE_SIZE - INNER_POINTS[i].Y);
385 end else begin
386 APage.StartPath(OUTER_POINTS[0].X, OUTER_POINTS[0].Y);
387 for i:=1 to High(OUTER_POINTS) do
388 APage.AddLineToPath(OUTER_POINTS[i].X, OUTER_POINTS[i].Y);
389 APage.AddMoveToPath(INNER_POINTS[0].X, INNER_POINTS[0].Y);
390 for i:=1 to High(INNER_POINTS) do
391 APage.AddLineToPath(INNER_POINTS[i].X, INNER_POINTS[i].Y);
392 end;
393 Result := APage.EndPath;
394 Result.Pen := StdPen;
395 end;
396 (*
397 { Quarter circle in quadrant I }
398 function CreateStdCircArcQ1(APage: TvVectorialPage;
399 Clockwise, Reverse: Boolean): TPath;
400 const
401 CX = 50.0;
402 CY = 55.0;
403 RX = 30.0;
404 RY = 30.0;
405 X1 = CX + RX;
406 Y1 = CY;
407 X2 = CX;
408 Y2 = CY + RY;
409 begin
410 if Reverse then
411 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, 0, Clockwise)
412 else
413 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, 0, Clockwise);
414 end;
415
416 { Quarter circle reaching from quadrant I into quadrant II}
417 function CreateStdCircArcQ12(APage: TvVectorialPage;
418 Clockwise, Reverse: Boolean): TPath;
419 const
420 SQRT2 = 1.4142135623731;
421 CX = 50.0;
422 CY = 55.0;
423 RX = 30.0;
424 RY = 30.0;
425 X1 = CX + RX/SQRT2;
426 Y1 = CY + RY/SQRT2;
427 X2 = CX - RX/SQRT2;
428 Y2 = CY + RY/SQRT2;
429 begin
430 if Reverse then
431 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, 0, Clockwise)
432 else
433 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, 0, Clockwise);
434 end;
435
436 { Quarter circle in quadrant II }
437 function CreateStdCircArcQ2(APage: TvVectorialPage; Clockwise: Boolean): TPath;
438 const
439 CX = 50.0;
440 CY = 55.0;
441 RX = 30.0;
442 RY = 30.0;
443 X1 = CX;
444 Y1 = CY + RY;
445 X2 = CX - RX;
446 Y2 = CY;
447 begin
448 if Reverse then
449 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, 0, Clockwise)
450 else
451 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, 0, Clockwise);
452 end;
453
454 { Quarter circle reaching from quadrant II into quadrant III}
455 function CreateStdCircArcQ23(APage: TvVectorialPage; Clockwise: Boolean): TPath;
456 const
457 SQRT2 = 1.4142135623731;
458 CX = 50.0;
459 CY = 55.0;
460 RX = 30.0;
461 RY = 30.0;
462 X1 = CX - RX/SQRT2;
463 Y1 = CY + RY/SQRT2;
464 X2 = CX - RX/SQRT2;
465 Y2 = CY - RY/SQRT2;
466 begin
467 if Reverse then
468 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, 0, Clockwise)
469 else
470 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, 0, Clockwise);
471 end;
472
473 { Quarter circle in quadrant III }
474 function CreateStdCircArcQ3(APage: TvVectorialPage; Clockwise: Boolean): TPath;
475 const
476 CX = 50.0;
477 CY = 55.0;
478 RX = 30.0;
479 RY = 30.0;
480 X1 = CX - RX;
481 Y1 = CY;
482 X2 = CX;
483 Y2 = CY - RY;
484 begin
485 if Reverse then
486 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, 0, Clockwise)
487 else
488 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, 0, Clockwise);
489 end;
490
491 { Quarter circle reaching from quadrant III into quadrant IV}
492 function CreateStdCircArcQ34(APage: TvVectorialPage; Clockwise: Boolean): TPath;
493 const
494 SQRT2 = 1.4142135623731;
495 CX = 50.0;
496 CY = 55.0;
497 RX = 30.0;
498 RY = 30.0;
499 X1 = CX - RX/SQRT2;
500 Y1 = CY - RY/SQRT2;
501 X2 = CX + RX/SQRT2;
502 Y2 = CY - RY/SQRT2;
503 begin
504 if Reverse then
505 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, 0, Clockwise)
506 else
507 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, 0, Clockwise);
508 end;
509
510 { Quarter circle in quadrant IV }
511 function CreateStdCircArcQ4(APage: TvVectorialPage; Clockwise: Boolean): TPath;
512 const
513 CX = 50.0;
514 CY = 55.0;
515 RX = 30.0;
516 RY = 30.0;
517 X1 = CX;
518 Y1 = CY - RY;
519 X2 = CX + RX;
520 Y2 = CY;
521 begin
522 if Reverse then
523 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, 0, Clockwise)
524 else
525 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, 0, Clockwise);
526 end;
527
528 { Quarter circle reaching from quadrant IV into quadrant I}
529 function CreateStdCircArcQ41(APage: TvVectorialPage; Clockwise: Boolean): TPath;
530 const
531 SQRT2 = 1.4142135623731;
532 CX = 50.0;
533 CY = 55.0;
534 RX = 30.0;
535 RY = 30.0;
536 X1 = CX + RX/SQRT2;
537 Y1 = CY - RY/SQRT2;
538 X2 = CX + RX/SQRT2;
539 Y2 = CY + RY/SQRT2;
540 begin
541 if Reverse then
542 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, 0, Clockwise)
543 else
544 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, 0, Clockwise);
545 end;
546
547 function CreateStdEllArcQ1(APage: TvVectorialPage;
548 Clockwise, Reverse: Boolean; Angle: Double): TPath;
549 const
550 SQRT2 = 1.4142135623731;
551 CX = 50.0;
552 CY = 55.0;
553 RX = 30.0;
554 RY = 20.0;
555 X1 = CX + RX;
556 Y1 = CY;
557 X2 = CX;
558 Y2 = CY + RY;
559 begin
560 if Reverse then
561 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, Angle, Clockwise)
562 else
563 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, Angle, Clockwise);
564 end;
565
566 function CreateStdEllArcQ12(APage: TvVectorialPage;
567 Clockwise, Reverse: Boolean; Angle: Double): TPath;
568 const
569 SQRT2 = 1.4142135623731;
570 CX = 50.0;
571 CY = 55.0;
572 RX = 30.0;
573 RY = 20.0;
574 X1 = CX + RX/SQRT2;
575 Y1 = CY + RY/SQRT2;
576 X2 = CX - RX/SQRT2;
577 Y2 = CY + RY/SQRT2;
578 begin
579 if Reverse then
580 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, Angle, Clockwise)
581 else
582 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, Angle, Clockwise);
583 end;
584
585 function CreateStdEllArcQ2(APage: TvVectorialPage;
586 Clockwise, Reverse: Boolean; Angle: Double): TPath;
587 const
588 SQRT2 = 1.4142135623731;
589 CX = 50.0;
590 CY = 55.0;
591 RX = 30.0;
592 RY = 20.0;
593 X1 = CX;
594 Y1 = CY + RY;
595 X2 = CX - RX;
596 Y2 = CY;
597 begin
598 if Reverse then
599 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, Angle, Clockwise)
600 else
601 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, Angle, Clockwise);
602 end;
603
604 function CreateStdEllArcQ23(APage: TvVectorialPage;
605 Clockwise, Reverse: Boolean; Angle: Double): TPath;
606 const
607 SQRT2 = 1.4142135623731;
608 CX = 50.0;
609 CY = 55.0;
610 RX = 30.0;
611 RY = 20.0;
612 X1 = CX - RX/SQRT2;
613 Y1 = CY + RY/SQRT2;
614 X2 = CX - RX/SQRT2;
615 Y2 = CY - RY/SQRT2;
616 begin
617 if Reverse then
618 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, Angle, Clockwise)
619 else
620 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, Angle, Clockwise);
621 end;
622
623 function CreateStdEllArcQ3(APage: TvVectorialPage;
624 Clockwise, Reverse: Boolean; Angle: Double): TPath;
625 const
626 SQRT2 = 1.4142135623731;
627 CX = 50.0;
628 CY = 55.0;
629 RX = 30.0;
630 RY = 20.0;
631 X1 = CX - RX;
632 Y1 = CY;
633 X2 = CX;
634 Y2 = CY - RY;
635 begin
636 if Reverse then
637 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, Angle, Clockwise)
638 else
639 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, Angle, Clockwise);
640 end;
641
642 function CreateStdEllArcQ34(APage: TvVectorialPage;
643 Clockwise, Reverse: Boolean; Angle: Double): TPath;
644 const
645 SQRT2 = 1.4142135623731;
646 CX = 50.0;
647 CY = 55.0;
648 RX = 30.0;
649 RY = 20.0;
650 X1 = CX - RX/SQRT2;
651 Y1 = CY - RY/SQRT2;
652 X2 = CX + RX/SQRT2;
653 Y2 = CY - RY/SQRT2;
654 begin
655 if Reverse then
656 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, Angle, Clockwise)
657 else
658 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, Angle, Clockwise);
659 end;
660
661 function CreateStdEllArcQ4(APage: TvVectorialPage;
662 Clockwise, Reverse: Boolean; Angle: Double): TPath;
663 const
664 SQRT2 = 1.4142135623731;
665 CX = 50.0;
666 CY = 55.0;
667 RX = 30.0;
668 RY = 20.0;
669 X1 = CX;
670 Y1 = CY - RY;
671 X2 = CX + RX;
672 Y2 = CY;
673 begin
674 if Reverse then
675 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, Angle, Clockwise)
676 else
677 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, Angle, Clockwise);
678 end;
679
680 function CreateStdEllArcQ41(APage: TvVectorialPage;
681 Clockwise, Reverse: Boolean; Angle: Double): TPath;
682 const
683 SQRT2 = 1.4142135623731;
684 CX = 50.0;
685 CY = 55.0;
686 RX = 30.0;
687 RY = 20.0;
688 X1 = CX + RX/SQRT2;
689 Y1 = CY - RY/SQRT2;
690 X2 = CX + RX/SQRT2;
691 Y2 = CY + RY/SQRT2;
692 begin
693 if Reverse then
694 Result := CreateArc(APage, X2, Y2, X1, Y1, CX, CY, RX, RY, Angle, Clockwise)
695 else
696 Result := CreateArc(APage, X1, Y1, X2, Y2, CX, CY, RX, RY, Angle, Clockwise);
697 end;
698 *)
699
700 { ---- }
701
702 function StdSolidBrush: TvBrush;
703 begin
704 Result := CreateSimpleBrush(bsSolid, colRed);
705 end;
706
707 function StdHorizGradientBrush: TvBrush;
708 begin
709 Result := CreateLinearGradientBrush(Point2D(0, 0), Point2D(1, 0),
710 [gfRelStartX, gfRelEndX, gfRelStartY, gfRelEndY],
711 colBlue, colWhite);
712 end;
713
714 { A vertical gradient, yellow at top, red at bottom }
715 function StdVertGradientBrush: TvBrush;
716 var
717 P1, P2: T2DPoint;
718 begin
719 {if APage.UseTopLeftCoordinates then begin
720 P1 := Point2D(0, 1);
721 P2 := Point2D(0, 0);
722 end else
723 }
724 begin
725 P1 := Point2D(0, 0);
726 P2 := Point2D(0, 1);
727 end;
728 Result := CreateLinearGradientBrush(P1, P2,
729 [gfRelStartX, gfRelEndX, gfRelStartY, gfRelEndY],
730 colYellow, colRed);
731 end;
732
733 { A diagonal gradient running from bottom/left (yellow) to top/right (red) }
734 function StdLinearGradientBrush: TvBrush;
735 var
736 P1, P2: T2DPoint;
737 begin
738 {
739 if APage.UseTopLeftCoordinates then begin
740 P1 := Point2D(0, 1);
741 P2 := Point2D(1, 0);
742 end else
743 }
744 begin
745 P1 := Point2D(0, 0);
746 P2 := Point2D(1, 1);
747 end;
748 Result := CreateLinearGradientBrush(Point2D(0, 0), Point2D(1, 1),
749 [gfRelStartX, gfRelEndX, gfRelStartY, gfRelEndY],
750 colYellow, colRed);
751 end;
752
753 function StdRadialGradientBrush: TvBrush;
754 begin
755 Result := CreateRadialGradientBrush(0.5, 0.5, 0.5, 0.5, 0.5,
756 colRed, colYellow);
757 end;
758
759 function StdPen: TvPen;
760 begin
761 Result := CreatePen(psSolid, 4, colBlack);
762 end;
763
764 end.
765
766