source: trunk/Packages/Common/UMetaCanvas.pas

Last change on this file was 1, checked in by chronos, 3 years ago
  • Added: "Clovece nezlob se" game with adjustable board for different player count.
File size: 14.5 KB
Line 
1unit UMetaCanvas;
2
3{$mode delphi}
4
5interface
6
7uses
8 Classes, SysUtils, Graphics, Contnrs, 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 SetLength(APoints, NumPts);
511 for I := 0 to High(APoints) do
512 APoints[I] := Points[I];
513 DoPolygon(APoints);
514end;
515
516procedure TMetaCanvas.DoPolygon(const Points: array of TPoint);
517var
518 NewObj: TCanvasPolygon;
519 I: Integer;
520begin
521 NewObj := TCanvasPolygon.Create;
522 NewObj.Brush.Assign(Brush);
523 NewObj.Pen.Assign(Pen);
524 SetLength(NewObj.Points, Length(Points));
525 for I := 0 to High(Points) do
526 NewObj.Points[I] := Points[I];
527 Objects.Add(NewObj);
528end;
529
530procedure TMetaCanvas.CreateHandle;
531begin
532end;
533
534procedure TMetaCanvas.Ellipse(x1, y1, x2, y2: Integer);
535begin
536 DoEllipse(Rect(X1, Y1, X2, Y2));
537end;
538
539procedure TMetaCanvas.DoEllipse(const Bounds: TRect);
540var
541 NewObj: TCanvasEllipse;
542begin
543 NewObj := TCanvasEllipse.Create;
544 NewObj.Brush.Assign(Brush);
545 NewObj.Pen.Assign(Pen);
546 NewObj.BoundingRect := Bounds;
547 Objects.Add(NewObj);
548end;
549
550procedure TMetaCanvas.StretchDraw(const DestRect: TRect; SrcGraphic: TGraphic);
551var
552 NewObj: TCanvasStretchDraw;
553begin
554 NewObj := TCanvasStretchDraw.Create;
555 NewObj.SrcGraphic := SrcGraphic;
556 NewObj.DestRect := DestRect;
557 Objects.Add(NewObj);
558end;
559
560function TMetaCanvas.TextExtent(const Text: string): TSize;
561var
562 Canvas: TCanvas;
563begin
564 Canvas := TCanvas.Create;
565 Canvas.Handle := CreateCompatibleDC(0);
566 Canvas.Font.Assign(Font);
567 Result := Canvas.TextExtent(Text);
568 DeleteDC(Canvas.Handle);
569 Canvas.Free;
570end;
571
572procedure TMetaCanvas.DoMoveTo(X, Y: Integer);
573begin
574 FPenPos := Point(X, Y);
575end;
576
577procedure TMetaCanvas.DoLineTo(X, Y: Integer);
578begin
579 DoLine(FPenPos.X, FPenPos.Y, X, Y);
580 DoMoveTo(X, Y);
581end;
582
583procedure TMetaCanvas.FillRect(const ARect: TRect);
584begin
585 DoRectangleFill(ARect);
586end;
587
588procedure TMetaCanvas.FillRect(X1, Y1, X2, Y2: Integer);
589begin
590 FillRect(Rect(X1, Y1, X2, Y2));
591end;
592
593procedure TMetaCanvas.RoundRect(X1, Y1, X2, Y2: Integer; RX, RY: Integer);
594begin
595 RoundRect(Rect(X1, Y1, X2, Y2), RX, RY);
596end;
597
598procedure TMetaCanvas.RoundRect(const Rect: TRect; RX, RY: Integer);
599var
600 NewObj: TCanvasRectangle;
601begin
602 NewObj := TCanvasRectangle.Create;
603 NewObj.Brush.Assign(Brush);
604 NewObj.Pen.Assign(Pen);
605 NewObj.BoundingRect := Rect;
606 NewObj.Rounded := Point(RX, RY);
607 Objects.Add(NewObj);
608end;
609
610procedure TMetaCanvas.Pie(EllipseX1, EllipseY1, EllipseX2, EllipseY2, StartX,
611 StartY, EndX, EndY: Integer);
612var
613 NewObj: TCanvasPie;
614begin
615 NewObj := TCanvasPie.Create;
616 NewObj.Brush.Assign(Brush);
617 NewObj.Pen.Assign(Pen);
618 NewObj.BoundingRect := Rect(EllipseX1, EllipseY1, EllipseX2, EllipseY2);
619 NewObj.StartPoint := Point(StartX, StartY);
620 NewObj.EndPoint := Point(EndX, EndY);
621 Objects.Add(NewObj);
622end;
623
624procedure TMetaCanvas.Reset;
625begin
626 Objects.Count := 0;
627end;
628
629procedure TMetaCanvas.DrawTo(Canvas: TCanvas);
630var
631 I: Integer;
632begin
633 for I := 0 to Objects.Count - 1 do
634 Objects[I].Paint(Canvas);
635end;
636
637procedure TMetaCanvas.Zoom(Factor: Double);
638var
639 I: Integer;
640begin
641 for I := 0 to Objects.Count - 1 do
642 Objects[I].Zoom(Factor);
643end;
644
645procedure TMetaCanvas.Move(Delta: TPoint);
646var
647 I: Integer;
648begin
649 for I := 0 to Objects.Count - 1 do
650 Objects[I].Move(Delta);
651end;
652
653constructor TMetaCanvas.Create;
654begin
655 inherited;
656 FPenPos := Point(0, 0);
657 Objects := TCanvasObjects.Create;
658end;
659
660destructor TMetaCanvas.Destroy;
661begin
662 Objects.Free;
663 inherited;
664end;
665
666end.
667
Note: See TracBrowser for help on using the repository browser.