source: trunk/Packages/Common/UMetaCanvas.pas

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