source: trunk/Packages/Common/UMetaCanvas.pas

Last change on this file was 10, checked in by chronos, 2 years ago
  • Modified: General UTest unit moved into Common package.
File size: 14.5 KB
Line 
1unit UMetaCanvas;
2
3interface
4
5uses
6 Classes, SysUtils, Graphics, Types, Generics.Collections;
7
8type
9 TArrayOfPoint = array of TPoint;
10
11 { TCanvasObject }
12
13 TCanvasObject = class
14 procedure Paint(Canvas: TCanvas); virtual;
15 procedure Zoom(Factor: Double); virtual;
16 procedure Move(Delta: TPoint); virtual;
17 end;
18
19 TCanvasObjects = class(TObjectList<TCanvasObject>)
20 end;
21
22 { TCanvasText }
23
24 TCanvasText = class(TCanvasObject)
25 Brush: TBrush;
26 Font: TFont;
27 Position: TPoint;
28 Text: string;
29 procedure Paint(Canvas: TCanvas); override;
30 procedure Zoom(Factor: Double); override;
31 procedure Move(Delta: TPoint); override;
32 constructor Create;
33 destructor Destroy; override;
34 end;
35
36 { TCanvasRectangle }
37
38 TCanvasRectangle = class(TCanvasObject)
39 Pen: TPen;
40 Brush: TBrush;
41 BoundingRect: TRect;
42 Rounded: TPoint;
43 procedure Paint(Canvas: TCanvas); override;
44 procedure Zoom(Factor: Double); override;
45 procedure Move(Delta: TPoint); override;
46 constructor Create;
47 destructor Destroy; override;
48 end;
49
50 { TCanvasLine }
51
52 TCanvasLine = class(TCanvasObject)
53 Pen: TPen;
54 P1, P2: TPoint;
55 procedure Paint(Canvas: TCanvas); override;
56 procedure Zoom(Factor: Double); override;
57 procedure Move(Delta: TPoint); override;
58 constructor Create;
59 destructor Destroy; override;
60 end;
61
62 { TCanvasPolygon }
63
64 TCanvasPolygon = class(TCanvasObject)
65 Pen: TPen;
66 Brush: TBrush;
67 Points: array of TPoint;
68 procedure Paint(Canvas: TCanvas); override;
69 procedure Zoom(Factor: Double); override;
70 procedure Move(Delta: TPoint); override;
71 constructor Create;
72 destructor Destroy; override;
73 end;
74
75 { TCanvasEllipse }
76
77 TCanvasEllipse = class(TCanvasObject)
78 Pen: TPen;
79 Brush: TBrush;
80 BoundingRect: TRect;
81 procedure Paint(Canvas: TCanvas); override;
82 procedure Zoom(Factor: Double); override;
83 procedure Move(Delta: TPoint); override;
84 constructor Create;
85 destructor Destroy; override;
86 end;
87
88 { TCanvasPie }
89
90 TCanvasPie = class(TCanvasObject)
91 Pen: TPen;
92 Brush: TBrush;
93 BoundingRect: TRect;
94 StartPoint: TPoint;
95 EndPoint: TPoint;
96 procedure Paint(Canvas: TCanvas); override;
97 procedure Zoom(Factor: Double); override;
98 procedure Move(Delta: TPoint); override;
99 constructor Create;
100 destructor Destroy; override;
101 end;
102
103 { TCanvasStretchDraw }
104
105 TCanvasStretchDraw = class(TCanvasObject)
106 SrcGraphic: TGraphic;
107 DestRect: TRect;
108 procedure Paint(Canvas: TCanvas); override;
109 procedure Zoom(Factor: Double); override;
110 procedure Move(Delta: TPoint); override;
111 constructor Create;
112 destructor Destroy; override;
113 end;
114
115 { TMetaCanvas }
116
117 TMetaCanvas = class(TCanvas)
118 private
119 FSize: TPoint;
120 FPenPos: TPoint;
121 protected
122 procedure SetHeight(AValue: Integer); override;
123 function GetHeight: Integer; override;
124 procedure SetWidth(AValue: Integer); override;
125 function GetWidth: Integer; override;
126 procedure DoLine (x1,y1,x2,y2:integer); override;
127 procedure DoTextOut(X, Y: Integer; Text: string); override;
128 procedure DoRectangle(const Bounds: TRect); override;
129 procedure DoRectangleFill(const Bounds: TRect); override;
130 procedure DoPolygon(const Points: array of TPoint); override;
131 procedure CreateHandle; override;
132 procedure DoEllipse(const Bounds: TRect); override;
133 procedure DoMoveTo(X, Y: Integer); override;
134 procedure DoLineTo(X, Y: Integer); override;
135 public
136 Objects: TCanvasObjects;
137 procedure FillRect(const ARect: TRect); overload; override;
138 procedure FillRect(X1,Y1,X2,Y2: Integer); overload;
139 procedure RoundRect(X1, Y1, X2, Y2: Integer; RX,RY: Integer); overload; override;
140 procedure RoundRect(const Rect: TRect; RX,RY: Integer); overload;
141 procedure TextOut(X,Y: Integer; const Text: String); override;
142 procedure Polygon(Points: PPoint; NumPts: Integer; Winding: Boolean = False); override;
143 procedure Ellipse(x1, y1, x2, y2: Integer); override;
144 procedure StretchDraw(const DestRect: TRect; SrcGraphic: TGraphic); override;
145 function TextExtent(const Text: string): TSize; override;
146 procedure Pie(EllipseX1, EllipseY1, EllipseX2, EllipseY2,
147 StartX, StartY, EndX, EndY: Integer); override;
148 procedure Reset;
149 procedure DrawTo(Canvas: TCanvas);
150 procedure Zoom(Factor: Double);
151 procedure Move(Delta: TPoint);
152 constructor Create;
153 destructor Destroy; override;
154 property Size: TPoint read FSize write FSize;
155 end;
156
157
158implementation
159
160uses
161 UGeometric, LCLIntf;
162
163{ TCanvasPie }
164
165procedure TCanvasPie.Paint(Canvas: TCanvas);
166begin
167 Canvas.Brush.Assign(Brush);
168 Canvas.Pen.Assign(Pen);
169 Canvas.Pie(BoundingRect.Left, BoundingRect.Top,
170 BoundingRect.Right, BoundingRect.Bottom, StartPoint.X, StartPoint.Y,
171 EndPoint.X, EndPoint.Y);
172end;
173
174procedure TCanvasPie.Zoom(Factor: Double);
175begin
176 BoundingRect := Rect(Trunc(BoundingRect.Left * Factor),
177 Trunc(BoundingRect.Top * Factor),
178 Trunc(BoundingRect.Right * Factor),
179 Trunc(BoundingRect.Bottom * Factor));
180 Pen.Width := Trunc(Pen.Width * Factor);
181 StartPoint := Point(Trunc(StartPoint.X * Factor), Trunc(StartPoint.Y * Factor));
182 EndPoint := Point(Trunc(EndPoint.X * Factor), Trunc(EndPoint.Y * Factor));
183end;
184
185procedure TCanvasPie.Move(Delta: TPoint);
186begin
187 BoundingRect := ShiftRect(BoundingRect, Delta);
188 StartPoint := AddPoint(StartPoint, Delta);
189 EndPoint := AddPoint(EndPoint, Delta);
190end;
191
192constructor TCanvasPie.Create;
193begin
194 Pen := TPen.Create;
195 Brush := TBrush.Create;
196end;
197
198destructor TCanvasPie.Destroy;
199begin
200 Pen.Free;
201 Brush.Free;
202 inherited;
203end;
204
205{ TCanvasStretchDraw }
206
207procedure TCanvasStretchDraw.Paint(Canvas: TCanvas);
208begin
209 Canvas.StretchDraw(DestRect, SrcGraphic);
210end;
211
212procedure TCanvasStretchDraw.Zoom(Factor: Double);
213begin
214 DestRect := Rect(Trunc(DestRect.Left * Factor),
215 Trunc(DestRect.Top * Factor),
216 Trunc(DestRect.Right * Factor),
217 Trunc(DestRect.Bottom * Factor));
218end;
219
220procedure TCanvasStretchDraw.Move(Delta: TPoint);
221begin
222 DestRect := ShiftRect(DestRect, Delta);
223end;
224
225constructor TCanvasStretchDraw.Create;
226begin
227 SrcGraphic := nil;
228end;
229
230destructor TCanvasStretchDraw.Destroy;
231begin
232 inherited;
233end;
234
235{ TCanvasEllipse }
236
237procedure TCanvasEllipse.Paint(Canvas: TCanvas);
238begin
239 Canvas.Pen.Assign(Pen);
240 Canvas.Brush.Assign(Brush);
241 Canvas.Ellipse(BoundingRect);
242end;
243
244procedure TCanvasEllipse.Zoom(Factor: Double);
245begin
246 BoundingRect := Rect(Trunc(BoundingRect.Left * Factor),
247 Trunc(BoundingRect.Top * Factor),
248 Trunc(BoundingRect.Right * Factor),
249 Trunc(BoundingRect.Bottom * Factor));
250 Pen.Width := Trunc(Pen.Width * Factor);
251end;
252
253procedure TCanvasEllipse.Move(Delta: TPoint);
254begin
255 BoundingRect := ShiftRect(BoundingRect, Delta);
256end;
257
258constructor TCanvasEllipse.Create;
259begin
260 Pen := TPen.Create;
261 Brush := TBrush.Create;
262end;
263
264destructor TCanvasEllipse.Destroy;
265begin
266 Pen.Free;
267 Brush.Free;
268 inherited;
269end;
270
271{ TCanvasPolygon }
272
273procedure TCanvasPolygon.Paint(Canvas: TCanvas);
274begin
275 Canvas.Pen.Assign(Pen);
276 Canvas.Brush.Assign(Brush);
277 Canvas.Polygon(Points);
278end;
279
280procedure TCanvasPolygon.Zoom(Factor: Double);
281var
282 I: Integer;
283begin
284 for I := 0 to High(Points) do
285 Points[I] := Point(Trunc(Points[I].X * Factor),
286 Trunc(Points[I].Y * Factor));
287 Pen.Width := Trunc(Pen.Width * Factor);
288end;
289
290procedure TCanvasPolygon.Move(Delta: TPoint);
291var
292 I: Integer;
293begin
294 for I := 0 to High(Points) do
295 Points[I] := AddPoint(Points[I], Delta);
296end;
297
298constructor TCanvasPolygon.Create;
299begin
300 Pen := TPen.Create;
301 Brush := TBrush.Create;
302end;
303
304destructor TCanvasPolygon.Destroy;
305begin
306 Brush.Free;
307 Pen.Free;
308 inherited;
309end;
310
311{ TCanvasLine }
312
313procedure TCanvasLine.Paint(Canvas: TCanvas);
314begin
315 Canvas.Pen.Assign(Pen);
316 Canvas.Line(P1, P2);
317end;
318
319procedure TCanvasLine.Zoom(Factor: Double);
320begin
321 P1 := Point(Trunc(P1.X * Factor), Trunc(P1.Y * Factor));
322 P2 := Point(Trunc(P2.X * Factor), Trunc(P2.Y * Factor));
323 Pen.Width := Trunc(Pen.Width * Factor);
324end;
325
326procedure TCanvasLine.Move(Delta: TPoint);
327begin
328 P1 := AddPoint(P1, Delta);
329 P2 := AddPoint(P2, Delta);
330end;
331
332constructor TCanvasLine.Create;
333begin
334 Pen := TPen.Create;
335end;
336
337destructor TCanvasLine.Destroy;
338begin
339 Pen.Free;
340 inherited;
341end;
342
343{ TCanvasRectangle }
344
345procedure TCanvasRectangle.Paint(Canvas: TCanvas);
346begin
347 Canvas.Pen.Assign(Pen);
348 Canvas.Brush.Assign(Brush);
349
350 if Rounded <> Point(0, 0) then Canvas.RoundRect(BoundingRect, Rounded.X, Rounded.Y)
351 else Canvas.Rectangle(BoundingRect);
352end;
353
354procedure TCanvasRectangle.Zoom(Factor: Double);
355begin
356 BoundingRect := Rect(Trunc(BoundingRect.Left * Factor),
357 Trunc(BoundingRect.Top * Factor),
358 Trunc(BoundingRect.Right * Factor),
359 Trunc(BoundingRect.Bottom * Factor));
360 Pen.Width := Trunc(Pen.Width * Factor);
361end;
362
363procedure TCanvasRectangle.Move(Delta: TPoint);
364begin
365 BoundingRect := ShiftRect(BoundingRect, Delta);
366end;
367
368constructor TCanvasRectangle.Create;
369begin
370 Pen := TPen.Create;
371 Brush := TBrush.Create;
372 Rounded := Point(0, 0);
373end;
374
375destructor TCanvasRectangle.Destroy;
376begin
377 Pen.Free;
378 Brush.Free;
379 inherited;
380end;
381
382{ TCanvasText }
383
384procedure TCanvasText.Paint(Canvas: TCanvas);
385begin
386 Canvas.Brush.Assign(Brush);
387 Canvas.Font.Assign(Font);
388 Canvas.TextOut(Position.X, Position.Y, Text);
389end;
390
391procedure TCanvasText.Zoom(Factor: Double);
392begin
393 Position := Point(Trunc(Position.X * Factor), Trunc(Position.Y * Factor));
394 Font.Size := Trunc(Font.Size * Factor);
395end;
396
397procedure TCanvasText.Move(Delta: TPoint);
398begin
399 Position := AddPoint(Position, Delta);
400end;
401
402constructor TCanvasText.Create;
403begin
404 Font := TFont.Create;
405 Brush := TBrush.Create;
406end;
407
408destructor TCanvasText.Destroy;
409begin
410 Brush.Free;
411 Font.Free;
412 inherited;
413end;
414
415{ TCanvasObject }
416
417procedure TCanvasObject.Paint(Canvas: TCanvas);
418begin
419
420end;
421
422procedure TCanvasObject.Zoom(Factor: Double);
423begin
424
425end;
426
427procedure TCanvasObject.Move(Delta: TPoint);
428begin
429end;
430
431{ TMetaCanvas }
432
433procedure TMetaCanvas.SetHeight(AValue: Integer);
434begin
435 FSize.Y := AValue;
436end;
437
438function TMetaCanvas.GetHeight: Integer;
439begin
440 Result := FSize.Y;
441end;
442
443procedure TMetaCanvas.SetWidth(AValue: Integer);
444begin
445 FSize.X := AValue;
446end;
447
448function TMetaCanvas.GetWidth: Integer;
449begin
450 Result := FSize.X;
451end;
452
453procedure TMetaCanvas.DoLine(x1, y1, x2, y2: integer);
454var
455 NewObj: TCanvasLine;
456begin
457 NewObj := TCanvasLine.Create;
458 NewObj.Pen.Assign(Pen);
459 NewObj.P1 := Point(X1, Y1);
460 NewObj.P2 := Point(X2, Y2);
461 Objects.Add(NewObj);
462end;
463
464procedure TMetaCanvas.DoTextOut(X, Y: Integer; Text: string);
465var
466 NewObj: TCanvasText;
467begin
468 NewObj := TCanvasText.Create;
469 NewObj.Font.Assign(Font);
470 NewObj.Brush.Assign(Brush);
471 NewObj.Position := Point(X, Y);
472 NewObj.Text := Text;
473 Objects.Add(NewObj);
474end;
475
476procedure TMetaCanvas.TextOut(X, Y: Integer; const Text: String);
477begin
478 DoTextOut(X, Y, Text);
479end;
480
481procedure TMetaCanvas.DoRectangle(const Bounds: TRect);
482var
483 NewObj: TCanvasRectangle;
484begin
485 NewObj := TCanvasRectangle.Create;
486 NewObj.Pen.Assign(Pen);
487 NewObj.BoundingRect := Bounds;
488 Objects.Add(NewObj);
489end;
490
491procedure TMetaCanvas.DoRectangleFill(const Bounds: TRect);
492var
493 NewObj: TCanvasRectangle;
494begin
495 NewObj := TCanvasRectangle.Create;
496 NewObj.Brush.Assign(Brush);
497 NewObj.Pen.Assign(Pen);
498 NewObj.BoundingRect := Bounds;
499 Objects.Add(NewObj);
500end;
501
502procedure TMetaCanvas.Polygon(Points: PPoint; NumPts: Integer; Winding: Boolean
503 );
504var
505 APoints: array of TPoint;
506 I: Integer;
507begin
508 APoints := nil;
509 SetLength(APoints, NumPts);
510 for I := 0 to High(APoints) do
511 APoints[I] := Points[I];
512 DoPolygon(APoints);
513end;
514
515procedure TMetaCanvas.DoPolygon(const Points: array of TPoint);
516var
517 NewObj: TCanvasPolygon;
518 I: Integer;
519begin
520 NewObj := TCanvasPolygon.Create;
521 NewObj.Brush.Assign(Brush);
522 NewObj.Pen.Assign(Pen);
523 SetLength(NewObj.Points, Length(Points));
524 for I := 0 to High(Points) do
525 NewObj.Points[I] := Points[I];
526 Objects.Add(NewObj);
527end;
528
529procedure TMetaCanvas.CreateHandle;
530begin
531end;
532
533procedure TMetaCanvas.Ellipse(x1, y1, x2, y2: Integer);
534begin
535 DoEllipse(Rect(X1, Y1, X2, Y2));
536end;
537
538procedure TMetaCanvas.DoEllipse(const Bounds: TRect);
539var
540 NewObj: TCanvasEllipse;
541begin
542 NewObj := TCanvasEllipse.Create;
543 NewObj.Brush.Assign(Brush);
544 NewObj.Pen.Assign(Pen);
545 NewObj.BoundingRect := Bounds;
546 Objects.Add(NewObj);
547end;
548
549procedure TMetaCanvas.StretchDraw(const DestRect: TRect; SrcGraphic: TGraphic);
550var
551 NewObj: TCanvasStretchDraw;
552begin
553 NewObj := TCanvasStretchDraw.Create;
554 NewObj.SrcGraphic := SrcGraphic;
555 NewObj.DestRect := DestRect;
556 Objects.Add(NewObj);
557end;
558
559function TMetaCanvas.TextExtent(const Text: string): TSize;
560var
561 Canvas: TCanvas;
562begin
563 Canvas := TCanvas.Create;
564 Canvas.Handle := CreateCompatibleDC(0);
565 Canvas.Font.Assign(Font);
566 Result := Canvas.TextExtent(Text);
567 DeleteDC(Canvas.Handle);
568 Canvas.Free;
569end;
570
571procedure TMetaCanvas.DoMoveTo(X, Y: Integer);
572begin
573 FPenPos := Point(X, Y);
574end;
575
576procedure TMetaCanvas.DoLineTo(X, Y: Integer);
577begin
578 DoLine(FPenPos.X, FPenPos.Y, X, Y);
579 DoMoveTo(X, Y);
580end;
581
582procedure TMetaCanvas.FillRect(const ARect: TRect);
583begin
584 DoRectangleFill(ARect);
585end;
586
587procedure TMetaCanvas.FillRect(X1, Y1, X2, Y2: Integer);
588begin
589 FillRect(Rect(X1, Y1, X2, Y2));
590end;
591
592procedure TMetaCanvas.RoundRect(X1, Y1, X2, Y2: Integer; RX, RY: Integer);
593begin
594 RoundRect(Rect(X1, Y1, X2, Y2), RX, RY);
595end;
596
597procedure TMetaCanvas.RoundRect(const Rect: TRect; RX, RY: Integer);
598var
599 NewObj: TCanvasRectangle;
600begin
601 NewObj := TCanvasRectangle.Create;
602 NewObj.Brush.Assign(Brush);
603 NewObj.Pen.Assign(Pen);
604 NewObj.BoundingRect := Rect;
605 NewObj.Rounded := Point(RX, RY);
606 Objects.Add(NewObj);
607end;
608
609procedure TMetaCanvas.Pie(EllipseX1, EllipseY1, EllipseX2, EllipseY2, StartX,
610 StartY, EndX, EndY: Integer);
611var
612 NewObj: TCanvasPie;
613begin
614 NewObj := TCanvasPie.Create;
615 NewObj.Brush.Assign(Brush);
616 NewObj.Pen.Assign(Pen);
617 NewObj.BoundingRect := Rect(EllipseX1, EllipseY1, EllipseX2, EllipseY2);
618 NewObj.StartPoint := Point(StartX, StartY);
619 NewObj.EndPoint := Point(EndX, EndY);
620 Objects.Add(NewObj);
621end;
622
623procedure TMetaCanvas.Reset;
624begin
625 Objects.Count := 0;
626end;
627
628procedure TMetaCanvas.DrawTo(Canvas: TCanvas);
629var
630 I: Integer;
631begin
632 for I := 0 to Objects.Count - 1 do
633 Objects[I].Paint(Canvas);
634end;
635
636procedure TMetaCanvas.Zoom(Factor: Double);
637var
638 I: Integer;
639begin
640 for I := 0 to Objects.Count - 1 do
641 Objects[I].Zoom(Factor);
642end;
643
644procedure TMetaCanvas.Move(Delta: TPoint);
645var
646 I: Integer;
647begin
648 for I := 0 to Objects.Count - 1 do
649 Objects[I].Move(Delta);
650end;
651
652constructor TMetaCanvas.Create;
653begin
654 inherited;
655 FPenPos := Point(0, 0);
656 Objects := TCanvasObjects.Create;
657end;
658
659destructor TMetaCanvas.Destroy;
660begin
661 Objects.Free;
662 inherited;
663end;
664
665end.
666
Note: See TracBrowser for help on using the repository browser.