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