1 {
2 *****************************************************************************
3 This file is part of the Printer4Lazarus package
4
5 See the file COPYING.modifiedLGPL.txt, included in this distribution,
6 for details about the license.
7 *****************************************************************************
8
9 custom-page in cocoa example:
10 https://developer.apple.com/library/mac/documentation/Cocoa/Conceptual/Printing/osxp_pagination/osxp_pagination.html
11 }
12 unit cocoaprintcanvas;
13
14 {$mode objfpc}{$H+}
15 {$modeswitch objectivec1}
16
17 interface
18
19 uses
20 // fpc
21 MacOSAll, CocoaAll, Classes, SysUtils, fpcanvas, Contnrs, Types,
22 // lcl-widgetset
23 CocoaUtils, CocoaGDIObjects,
24 // lcl
25 Printers, LCLType, Graphics;
26
27 type
28
29 { TCanvasOperation }
30
31 TCanvasOperation = class(TObject)
32 public
33 procedure DrawTo(const ADest: TCocoaContext); virtual; abstract;
34 end;
35
36 { TCanvasOperation_Pen }
37
38 TCanvasOperation_Pen = class(TCanvasOperation)
39 public
40 Pen_Color: TColor; // default clBlack;
41 Pen_Cosmetic: Boolean; // default True;
42 Pen_Style: TFPPenStyle;
43 Pen_Width: Integer;
44 Pen_Mode: TFPPenMode;
45 Pen_EndCap: TFPPenEndCap;
46 Pen_JoinStyle: TFPPenJoinStyle;
47 //
48 DisablePen: Boolean; // for descendents to disable pen setting in DrawTo
49 procedure DrawTo(const ADest: TCocoaContext); override;
50 end;
51
52 { TCanvasOperation_Pen_Brush }
53
54 TCanvasOperation_Pen_Brush = class(TCanvasOperation_Pen)
55 public
56 Brush_Color: TColor; // default clBlack;
57 Brush_Style: TFPBrushStyle;
58 Brush_Pattern: TBrushPattern;
59 procedure DrawTo(const ADest: TCocoaContext); override;
60 end;
61
62 TCanvasOperation_Font = class(TCanvasOperation_Pen_Brush)
63 public
64 Font_Name: string;
65 Font_Size: integer;
66 Font_Bold: boolean;
67 Font_Italic: boolean;
68 Font_Underline: boolean;
69 Font_StrikeThrough: boolean;
70 Font_Orientation: Integer;
71 //
72 Font_Pitch: TFontPitch;
73 Font_Quality: TFontQuality;
74 procedure DrawTo(const ADest: TCocoaContext); override;
75 end;
76
77 { TCanvasOperation_Ellipse }
78
79 TCanvasOperation_Ellipse = class(TCanvasOperation_Pen_Brush)
80 public
81 X1, Y1, X2, Y2: Integer;
82 constructor Create(AX1, AY1, AX2, AY2: Integer);
83 procedure DrawTo(const ADest: TCocoaContext); override;
84 end;
85
86 TCanvasOperation_Rectangle = class(TCanvasOperation_Pen_Brush)
87 public
88 X1, Y1, X2, Y2: Integer;
89 constructor Create(AX1, AY1, AX2, AY2: Integer);
90 procedure DrawTo(const ADest: TCocoaContext); override;
91 end;
92
93 TCanvasOperation_TextOut = class(TCanvasOperation_Font)
94 public
95 X, Y: Integer;
96 Text: string;
97 constructor Create(AX, AY: Integer; AText: string);
98 procedure DrawTo(const ADest: TCocoaContext); override;
99 end;
100
101 { TCocoaPrinterCanvas }
102
103 TCocoaPrinterCanvas = class(TFilePrinterCanvas)
104 private
105 FLazClipRect: TRect;
106 FRecordingPages: TFPObjectList; // list of 1 (FCurRecording: TFPObjectList) per page
107 FCurRecording: TFPObjectList; // this is the current recording
SetCurPagenull108 function SetCurPage(APageNum: Integer): Boolean;
GetOperationCountnull109 function GetOperationCount: Integer;
GetOperationnull110 function GetOperation(ANum: Integer): TCanvasOperation;
111 procedure SetPenProperties(ADest: TCanvasOperation_Pen);
112 procedure SetBrushProperties(ADest: TCanvasOperation_Pen_Brush);
113 procedure SetFontProperties(ADest: TCanvasOperation_Font);
114 procedure SetPenAndBrush(ADest: TCanvasOperation_Pen_Brush);
115 procedure SetFontAndBrush(ADest: TCanvasOperation_Font);
116 protected
117 ScaleX, ScaleY, FontScale: Double;
118 procedure SetLazClipRect(r: TRect);
119 procedure DoLineTo(X1,Y1: Integer); override;
120 procedure DoMoveTo({%H-}x, {%H-}y: integer); override;
121 procedure SetHandle(NewHandle: HDC); override;
GetClipRectnull122 function GetClipRect: TRect; override;
123 procedure SetClipRect(const ARect: TRect); override;
GetClippingnull124 function GetClipping: Boolean; override;
125 procedure SetClipping(const AValue: boolean); override;
126 //
127 procedure CreateBrush; override;
128 procedure CreateFont; override;
129 procedure CreateHandle; override;
130 procedure CreatePen; override;
131 procedure CreateRegion; override;
132 procedure RealizeAntialiasing; override;
133 procedure DestroyHandle;
134 public
135 SurfaceXDPI, SurfaceYDPI: Integer;
136 constructor Create(APrinter : TPrinter); override;
137 constructor Create; overload;
138 destructor Destroy; override;
139 procedure BeginDoc; override;
140 procedure EndDoc; override;
141 procedure NewPage; override;
142 procedure FillRect(const ARect: TRect); override;
143 procedure Rectangle(X1,Y1,X2,Y2: Integer); override;
144 procedure Polyline(Points: PPoint; NumPts: Integer); override;
145 procedure Polygon(Points: PPoint; NumPts: Integer; {%H-}Winding: boolean = False); override;
146 procedure FrameRect(const ARect: TRect); override;
147 procedure Frame(const ARect: TRect); override;
148 procedure RoundRect(X1, Y1, X2, Y2: Integer; RX, RY: Integer); override;
149 procedure Ellipse(X1, Y1, X2, Y2: Integer); override;
150 procedure Arc(ALeft, ATop, ARight, ABottom, Angle16Deg, Angle16DegLength: Integer); override;
151 procedure Arc(ALeft, ATop, ARight, ABottom, StX, StY, EX, EY: Integer); override;
152 procedure Chord(X1, Y1, X2, Y2, Angle1, Angle2: Integer); override;
153 procedure Chord(X1, Y1, X2, Y2, StX, StY, EX, EY: Integer); override;
154 procedure Pie(EllipseX1, EllipseY1, EllipseX2, EllipseY2, StartX, StartY, EndX, EndY: Integer); override;
155 procedure RadialPie(Left, Top, Right, Bottom, Angle1, Angle2: Integer); override;
156 procedure PolyBezier(Points: PPoint; NumPts: Integer; Filled: boolean = False; Continuous: boolean = False); override;
157 procedure TextOut(X,Y: Integer; const Text: String); override;
158 procedure TextRect(ARect: TRect; X1, Y1: integer; const Text: string; const Style: TTextStyle); override;
TextExtentnull159 function TextExtent(const Text: string): TSize; override;
GetTextMetricsnull160 function GetTextMetrics(out M: TLCLTextMetric): boolean; override;
161 procedure StretchDraw(const DestRect: TRect; SrcGraphic: TGraphic); override;
162 procedure SetPixel(X,Y: Integer; Value: TColor); override;
163 public
164 procedure DrawRecording(const ADest: NSView; dirtyRect: NSRect; APageNum: Integer);
165 end;
166
167 implementation
168
169 { TCanvasOperation_Pen }
170
171 procedure TCanvasOperation_Pen.DrawTo(const ADest: TCocoaContext);
172 var
173 lCocoaPen: TCocoaPen;
174 begin
175 if DisablePen then Exit;
176
177 lCocoaPen := TCocoaPen.Create(Pen_Color, Pen_Style, Pen_Cosmetic,
178 Pen_Width, Pen_Mode, Pen_EndCap, Pen_JoinStyle);
179 lCocoaPen.Apply(ADest);
180 lCocoaPen.Free;
181 end;
182
183 { TCanvasOperation_Pen_Brush }
184
185 procedure TCanvasOperation_Pen_Brush.DrawTo(const ADest: TCocoaContext);
186 var
187 lCocoaBrush: TCocoaBrush;
188 begin
189 inherited DrawTo(ADest);
190 lCocoaBrush := TCocoaBrush.Create(Brush_Color, Brush_Style, Brush_Pattern);
191 lCocoaBrush.Apply(ADest);
192 lCocoaBrush.Free;
193 end;
194
195 { TCanvasOperation_Font }
196
197 procedure TCanvasOperation_Font.DrawTo(const ADest: TCocoaContext);
198 const
199 LF_BOOL: array[Boolean] of Byte = (0, 255);
200 LF_WEIGHT: array[Boolean] of Integer = (FW_NORMAL, FW_BOLD);
201 LF_QUALITY: array[TFontQuality] of Integer = (DEFAULT_QUALITY,
202 DRAFT_QUALITY, PROOF_QUALITY, NONANTIALIASED_QUALITY, ANTIALIASED_QUALITY,
203 CLEARTYPE_QUALITY, CLEARTYPE_NATURAL_QUALITY);
204 var
205 lLogFont: TLogFont;
206 lCocoaFont: TCocoaFont;
207 begin
208 lLogFont.lfHeight := Font_Size;
209 lLogFont.lfWidth := 0;
210 lLogFont.lfEscapement := Font_Orientation;
211 lLogFont.lfOrientation := Font_Orientation;
212 lLogFont.lfWeight := LF_WEIGHT[Font_Bold];
213 lLogFont.lfItalic := LF_BOOL[Font_Italic];
214 lLogFont.lfUnderline := LF_BOOL[Font_Underline];
215 lLogFont.lfStrikeOut := LF_BOOL[Font_StrikeThrough];
216 lLogFont.lfCharSet := DEFAULT_CHARSET;
217 lLogFont.lfOutPrecision := OUT_DEFAULT_PRECIS;
218 lLogFont.lfClipPrecision := CLIP_DEFAULT_PRECIS;
219 lLogFont.lfQuality := LF_QUALITY[Font_Quality];
220 case Font_Pitch of
221 fpVariable: lLogFont.lfPitchAndFamily := VARIABLE_PITCH;
222 fpFixed: lLogFont.lfPitchAndFamily := FIXED_PITCH;
223 else
224 lLogFont.lfPitchAndFamily := DEFAULT_PITCH;
225 end;
226
227 lLogFont.lfFaceName := Font_Name;
228
229 {lCocoaFont := TCocoaFont.Create(lLogFont, Font_Name);
230 ADest.Font.Free;
231 ADest.Font := lCocoaFont;}
232
233 inherited DrawTo(ADest);
234 end;
235
236 { TCanvasOperation_Ellipse }
237
238 constructor TCanvasOperation_Ellipse.Create(AX1, AY1, AX2, AY2: Integer);
239 begin
240 inherited Create;
241 X1 := AX1;
242 Y1 := AY1;
243 X2 := AX2;
244 Y2 := AY2;
245 end;
246
247 procedure TCanvasOperation_Ellipse.DrawTo(const ADest: TCocoaContext);
248 begin
249 inherited DrawTo(ADest); // apply pen and brush
250 ADest.Ellipse(X1, Y1, X2, Y2);
251 end;
252
253 { TCanvasOperation_Rectangle }
254
255 constructor TCanvasOperation_Rectangle.Create(AX1, AY1, AX2, AY2: Integer);
256 begin
257 inherited Create;
258 X1 := AX1;
259 Y1 := AY1;
260 X2 := AX2;
261 Y2 := AY2;
262 end;
263
264 procedure TCanvasOperation_Rectangle.DrawTo(const ADest: TCocoaContext);
265 begin
266 inherited DrawTo(ADest); // apply pen and brush
267 ADest.Rectangle(X1, Y1, X2, Y2, True, nil);
268 end;
269
270 { TCanvasOperation_TextOut }
271
272 constructor TCanvasOperation_TextOut.Create(AX, AY: Integer; AText: string);
273 begin
274 inherited Create;
275 DisablePen := True;
276 X := AX;
277 Y := AY;
278 Text := AText;
279 end;
280
281 procedure TCanvasOperation_TextOut.DrawTo(const ADest: TCocoaContext);
282 begin
283 inherited DrawTo(ADest); // apply pen and brush
284 ADest.TextOut(X, Y, 0, nil, PChar(Text), Length(Text), nil);
285 end;
286
287 { TCocoaPrinterCanvas }
288
SetCurPagenull289 function TCocoaPrinterCanvas.SetCurPage(APageNum: Integer): Boolean;
290 begin
291 Result := False;
292 if (APageNum < 0) or (APageNum >= FRecordingPages.Count) then Exit;
293 FCurRecording := TFPObjectList(FRecordingPages.Items[APageNum]);
294 Result := True;
295 end;
296
TCocoaPrinterCanvas.GetOperationCountnull297 function TCocoaPrinterCanvas.GetOperationCount: Integer;
298 begin
299 Result := FCurRecording.Count;
300 end;
301
GetOperationnull302 function TCocoaPrinterCanvas.GetOperation(ANum: Integer): TCanvasOperation;
303 begin
304 Result := TCanvasOperation(FCurRecording.Items[ANum]);
305 end;
306
307 procedure TCocoaPrinterCanvas.SetPenProperties(ADest: TCanvasOperation_Pen);
308 begin
309 ADest.Pen_Color := Pen.Color;
310 ADest.Pen_Cosmetic := Pen.Cosmetic;
311 ADest.Pen_Style := Pen.Style;
312 ADest.Pen_Width := Pen.Width;
313 ADest.Pen_Mode := Pen.Mode;
314 ADest.Pen_EndCap := Pen.EndCap;
315 ADest.Pen_JoinStyle := Pen.JoinStyle;
316 end;
317
318 procedure TCocoaPrinterCanvas.SetBrushProperties(ADest: TCanvasOperation_Pen_Brush);
319 begin
320 ADest.Brush_Color := Brush.Color;
321 ADest.Brush_Style := Brush.Style;
322 ADest.Brush_Pattern := Brush.Pattern;
323 end;
324
325 procedure TCocoaPrinterCanvas.SetFontProperties(ADest: TCanvasOperation_Font);
326 begin
327 end;
328
329 procedure TCocoaPrinterCanvas.SetPenAndBrush(ADest: TCanvasOperation_Pen_Brush);
330 begin
331 SetPenProperties(ADest);
332 SetBrushProperties(ADest);
333 end;
334
335 procedure TCocoaPrinterCanvas.SetFontAndBrush(ADest: TCanvasOperation_Font);
336 begin
337 SetBrushProperties(ADest);
338 SetFontProperties(ADest);
339 end;
340
341 procedure TCocoaPrinterCanvas.DoLineTo(X1, Y1: Integer);
342 begin
343 {Changing;
344 RequiredState([csHandleValid, csPenValid]);
345 SetPenProperties;
346 cairo_move_to(cr, SX(PenPos.X), SY(PenPos.Y));
347 cairo_line_to(cr, SX(X1), SY(Y1));
348 SetInternalPenPos(Point(X1,Y1));
349 StrokeOnly;
350 Changed;}
351 end;
352
353 procedure TCocoaPrinterCanvas.DoMoveTo(x, y: integer);
354 begin
355 // should not call inherited DoMoveTo which would end calling
356 // interface MoveToEx which breaks things for Qt
357 end;
358
359 procedure TCocoaPrinterCanvas.SetHandle(NewHandle: HDC);
360 begin
361 inherited SetHandle(NewHandle);
362 end;
363
364 procedure TCocoaPrinterCanvas.BeginDoc;
365 begin
366 inherited BeginDoc;
367 if assigned(printer) then
368 FLazClipRect:=printer.PaperSize.PaperRect.WorkRect;
369 end;
370
371 procedure TCocoaPrinterCanvas.EndDoc;
372 begin
373 inherited EndDoc;
374 {cairo_show_page(cr);
375 FLazClipRect := Rect(0, 0, 0, 0);
376 //if caller is printer, then at the end destroy cairo handles (flush output)
377 //and establishes CreateCairoHandle call on the next print}
378 Handle := 0;
379 end;
380
381 procedure TCocoaPrinterCanvas.NewPage;
382 begin
383 inherited NewPage;
384 //cairo_show_page(cr);
385 end;
386
387 procedure TCocoaPrinterCanvas.CreateBrush;
388 begin
389 end;
390
391 procedure TCocoaPrinterCanvas.CreateFont;
392 begin
393 end;
394
395 procedure TCocoaPrinterCanvas.CreateHandle;
396 begin
397 ScaleX := SurfaceXDPI/XDPI;
398 ScaleY := SurfaceYDPI/YDPI;
399
400 if FRecordingPages = nil then
401 begin
402 FCurRecording := TFPObjectList.Create;
403 FRecordingPages := TFPObjectList.Create;
404 FRecordingPages.Add(FCurRecording);
405 end;
406 Handle := HWND(FRecordingPages);
407 end;
408
409 procedure TCocoaPrinterCanvas.CreatePen;
410 begin
411 end;
412
413 procedure TCocoaPrinterCanvas.CreateRegion;
414 begin
415 end;
416
417 procedure TCocoaPrinterCanvas.RealizeAntialiasing;
418 begin
419 end;
420
421 procedure TCocoaPrinterCanvas.DestroyHandle;
422 var
423 i: Integer;
424 begin
425 for i := 0 to FRecordingPages.Count-1 do
426 FRecordingPages.Items[i].Free;
427 FCurRecording := nil;
428 end;
429
TCocoaPrinterCanvas.GetClipRectnull430 function TCocoaPrinterCanvas.GetClipRect: TRect;
431 var
432 x1,y1,x2,y2: double;
433 begin
434 RequiredState([csHandleValid]);
435
436 {// it doesn't matter what the clip is in use, default or user
437 // this returns always the current clip
438
439 result.Left:=round(x1/ScaleX);
440 result.Top:=round(y1/ScaleY);
441 result.Right:=round(x2/ScaleX);
442 result.Bottom:=round(y2/ScaleY);}
443 end;
444
445 procedure TCocoaPrinterCanvas.SetClipRect(const ARect: TRect);
446 begin
447 {RequiredState([csHandleValid]);
448 if FUserClipRect=nil then
449 New(FUserClipRect);
450
451 fUserClipRect^.x := SX(ARect.Left);
452 fUserClipRect^.y := SY(ARect.Top);
453 fUserClipRect^.width := SX2(ARect.Right-ARect.Left);
454 fUserClipRect^.height:= SY2(ARect.Bottom-ARect.Top);
455 }
456 end;
457
TCocoaPrinterCanvas.GetClippingnull458 function TCocoaPrinterCanvas.GetClipping: Boolean;
459 begin
460 //result := (fUserClipRect<>nil);
461 end;
462
463 procedure TCocoaPrinterCanvas.SetClipping(const AValue: boolean);
464 begin
465 RequiredState([csHandleValid]);
466 {cairo_reset_clip(cr);
467
468 if not AValue then begin
469 // free user cliprect if exists
470 if fUserClipRect<>nil then
471 Dispose(fUserClipRect);
472 fUserClipRect := nil;
473 end
474 else begin
475 if fUserClipRect<>nil then
476 begin
477 with fUserClipRect^ do
478 begin
479 cairo_rectangle(cr, x, y, width, height);
480 cairo_clip(cr);
481 end;
482 end else
483 ; // cairo_reset_clip always clip
484 end;}
485 end;
486
487 procedure TCocoaPrinterCanvas.SetLazClipRect(r: TRect);
488 begin
489 FLazClipRect := r;
490 end;
491
492 constructor TCocoaPrinterCanvas.Create(APrinter: TPrinter);
493 begin
494 inherited Create(APrinter);
495 ScaleX := 1;
496 ScaleY := 1;
497 FontScale := 1;
498 SurfaceXDPI := 72;
499 SurfaceYDPI := 72;
500 XDPI := SurfaceXDPI;
501 YDPI := SurfaceXDPI;
502
503 CreateHandle;
504 end;
505
506 constructor TCocoaPrinterCanvas.Create;
507 begin
508 Create(nil);
509 end;
510
511 destructor TCocoaPrinterCanvas.Destroy;
512 begin
513 DestroyHandle;
514
515 inherited Destroy;
516 end;
517
518 procedure TCocoaPrinterCanvas.Rectangle(X1, Y1, X2, Y2: Integer);
519 var
520 lRect: TCanvasOperation_Rectangle;
521 begin
522 Changing;
523 RequiredState([csHandleValid, csPenValid, csBrushValid]);
524 lRect := TCanvasOperation_Rectangle.Create(X1, Y1, X2, Y2);
525 SetPenAndBrush(lRect);
526 FCurRecording.Add(lRect);
527 Changed;
528 end;
529
530 //1 point rectangle in _Brush_ color
531 procedure TCocoaPrinterCanvas.FrameRect(const ARect: TRect);
532 begin
533 {Changing;
534 RequiredState([csHandleValid, csBrushValid]);
535 cairo_rectangle(cr, SX(ARect.Left), SY(ARect.Top), SX2(ARect.Right-ARect.Left), SY2(ARect.Bottom-ARect.Top));
536 SetSourceColor(Brush.Color);
537 cairo_set_line_width(cr, 1);
538 cairo_stroke(cr); //Don't touch
539 Changed;}
540 end;
541
542 procedure TCocoaPrinterCanvas.Frame(const ARect: TRect);
543 begin
544 {Changing;
545 RequiredState([csHandleValid, csPenValid]);
546 cairo_rectangle(cr, SX(ARect.Left), SY(ARect.Top), SX2(ARect.Right-ARect.Left), SY2(ARect.Bottom-ARect.Top));
547 cairo_set_line_width(cr, 1);
548 SetSourceColor(Pen.Color);
549 cairo_stroke(cr); //Don't touch
550 Changed;}
551 end;
552
553 procedure TCocoaPrinterCanvas.RoundRect(X1, Y1, X2, Y2: Integer; RX, RY: Integer);
554 begin
555 {Changing;
556 RequiredState([csHandleValid, csPenValid, csBrushValid]);
557 cairo_move_to(cr, SX(X1+RX), SY(Y1));
558 cairo_line_to(cr, SX(X2-RX), SY(Y1));
559 EllipseArcPath(X2-RX, Y1+RY, RX, RY, -PI/2, 0, True, True);
560 cairo_line_to(cr, SX(X2), SY(Y2-RY));
561 EllipseArcPath(X2-RX, Y2-RY, RX, RY, 0, PI/2, True, True);
562 cairo_line_to(cr, SX(X1+RX), SY(Y2));
563 EllipseArcPath(X1+RX, Y2-RY, RX, RY, PI/2, PI, True, True);
564 cairo_line_to(cr, SX(X1), SY(Y1+RX));
565 EllipseArcPath(X1+RX, Y1+RY, RX, RY, PI, PI*1.5, True, True);
566 FillAndStroke;
567 Changed;}
568 end;
569
570 procedure TCocoaPrinterCanvas.Ellipse(X1, Y1, X2, Y2: Integer);
571 var
572 lEllipse: TCanvasOperation_Ellipse;
573 begin
574 Changing;
575 RequiredState([csHandleValid, csPenValid, csBrushValid]);
576 lEllipse := TCanvasOperation_Ellipse.Create(X1, Y1, X2, Y2);
577 SetPenAndBrush(lEllipse);
578 FCurRecording.Add(lEllipse);
579 Changed;
580 end;
581
582 procedure TCocoaPrinterCanvas.Arc(ALeft, ATop, ARight, ABottom, Angle16Deg, Angle16DegLength: Integer);
583 begin
584 {Changing;
585 RequiredState([csHandleValid, csPenValid]);
586 ArcPath(ALeft, ATop, ARight, ABottom, Angle16Deg, Angle16DegLength);
587 StrokeOnly;
588 Changed;}
589 end;
590
591 procedure TCocoaPrinterCanvas.Chord(X1, Y1, X2, Y2, Angle1, Angle2: Integer);
592 begin
593 {Changing;
594 RequiredState([csHandleValid, csPenValid, csBrushValid]);
595 ArcPath(X1, Y1, X2, Y2, Angle1, Angle2);
596 cairo_close_path(cr);
597 FillAndStroke;
598 Changed;}
599 end;
600
601 procedure TCocoaPrinterCanvas.RadialPie(Left, Top, Right, Bottom, Angle1, Angle2: Integer);
602 {var
603 cx, cy: double;}
604 begin
605 {Changing;
606 RequiredState([csHandleValid, csPenValid, csBrushValid]);
607 ArcPath(Left, Top, Right, Bottom, Angle1, Angle2);
608 cx := (Right+Left)/2;
609 cy := (Bottom+Top)/2;
610 cairo_line_to(cr, SX(cx), SY(cy));
611 cairo_close_path(cr);
612 FillAndStroke;
613 Changed;}
614 end;
615
616 procedure TCocoaPrinterCanvas.Arc(ALeft, ATop, ARight, ABottom, StX, StY, EX, EY: Integer);
617 begin
618 {Changing;
619 RequiredState([csHandleValid, csPenValid]);
620 ArcPath(ALeft, ATop, ARight, ABottom, StX, StY, EX, EY);
621 StrokeOnly;
622 Changed;}
623 end;
624
625 procedure TCocoaPrinterCanvas.Chord(X1, Y1, X2, Y2, StX, StY, EX, EY: Integer);
626 begin
627 {Changing;
628 RequiredState([csHandleValid, csPenValid, csBrushValid]);
629 ArcPath(X1, Y1, X2, Y2, StX, StY, EX, EY);
630 cairo_close_path(cr);
631 FillAndStroke;
632 Changed;}
633 end;
634
635 procedure TCocoaPrinterCanvas.Pie(EllipseX1, EllipseY1, EllipseX2, EllipseY2,
636 StartX, StartY, EndX, EndY: Integer);
637 var
638 cx, cy: double;
639 begin
640 {Changing;
641 RequiredState([csHandleValid, csPenValid, csBrushValid]);
642 ArcPath(EllipseX1, EllipseY1, EllipseX2, EllipseY2, StartX, StartY, EndX, EndY);
643 cx := (EllipseX2+EllipseX1)/2;
644 cy := (EllipseY2+EllipseY1)/2;
645 cairo_line_to(cr, SX(cx), SY(cy));
646 cairo_close_path(cr);
647 FillAndStroke;
648 Changed;}
649 end;
650
651 procedure TCocoaPrinterCanvas.PolyBezier(Points: PPoint; NumPts: Integer; Filled: boolean; Continuous: boolean);
652 begin
653 end;
654
655 procedure TCocoaPrinterCanvas.TextOut(X, Y: Integer; const Text: String);
656 var
657 lText: TCanvasOperation_TextOut;
658 begin
659 Changing;
660 RequiredState([csHandleValid, csPenValid, csBrushValid]);
661 lText := TCanvasOperation_TextOut.Create(X, Y, Text);
662 SetFontAndBrush(lText);
663 FCurRecording.Add(lText);
664 Changed;
665 end;
666
667 procedure TCocoaPrinterCanvas.TextRect(ARect: TRect; X1, Y1: integer; const Text: string; const Style: TTextStyle);
668 var
669 s: string;
670 begin
671 Changing;
672 RequiredState([csHandleValid, csFontValid, csBrushValid]);
673 Changed;
674 end;
675
TCocoaPrinterCanvas.TextExtentnull676 function TCocoaPrinterCanvas.TextExtent(const Text: string): TSize;
677 begin
678 RequiredState([csHandleValid, csFontValid]);
679 //SelectFont;
680 end;
681
GetTextMetricsnull682 function TCocoaPrinterCanvas.GetTextMetrics(out M: TLCLTextMetric): boolean;
683 begin
684 {RequiredState([csHandleValid, csFontValid]);
685 SelectFont;
686 cairo_font_extents(cr, @e); //transformation matrix is here ignored
687 FillChar(M{%H-}, SizeOf(M), 0);
688 M.Ascender := Round(e.ascent/ScaleY);
689 M.Descender := Round(e.descent/ScaleY);
690 M.Height := Round(e.height/ScaleY);
691 Result := True;}
692 end;
693
694 procedure TCocoaPrinterCanvas.StretchDraw(const DestRect: TRect; SrcGraphic: TGraphic);
695 begin
696 end;
697
698 procedure TCocoaPrinterCanvas.SetPixel(X, Y: Integer; Value: TColor);
699 begin
700 {Changing;
701 RequiredState([csHandleValid, csPenValid]);
702 SetSourceColor(Value);
703 cairo_rectangle(cr, SX(X), SY(Y), 1, 1);
704 cairo_fill(cr);
705 Changed;}
706 end;
707
708 procedure TCocoaPrinterCanvas.Polyline(Points: PPoint; NumPts: Integer);
709 begin
710 {if NumPts <= 0 then
711 Exit;
712 Changing;
713 RequiredState([csHandleValid, csPenValid]);
714 PolylinePath(Points, NumPts);
715 StrokeOnly;
716 Changed;}
717 end;
718
719 procedure TCocoaPrinterCanvas.Polygon(Points: PPoint; NumPts: Integer; Winding: boolean);
720 begin
721 {if NumPts <= 0 then
722 Exit;
723 Changing;
724 RequiredState([csHandleValid, csBrushValid, csPenValid]);
725 PolylinePath(Points, NumPts);
726 cairo_close_path(cr);
727 FillAndStroke;
728 Changed;}
729 end;
730
731 procedure TCocoaPrinterCanvas.FillRect(const ARect: TRect);
732 begin
733 {Changing;
734 RequiredState([csHandleValid, csBrushValid]);
735 cairo_rectangle(cr, SX(ARect.Left), SY(ARect.Top), SX2(ARect.Right-ARect.Left), SY2(ARect.Bottom-ARect.Top));
736 FillOnly;
737 Changed;}
738 end;
739
740 procedure TCocoaPrinterCanvas.DrawRecording(const ADest: NSView; dirtyRect: NSRect; APageNum: Integer);
741 var
742 i: Integer;
743 lCurOperation: TCanvasOperation;
744 lCocoaContext: TCocoaContext;
745 begin
746 if not SetCurPage(APageNum) then Exit;
747 lCocoaContext := TCocoaContext.Create(NSGraphicsContext.currentContext);
748 for i := 0 to GetOperationCount()-1 do
749 begin
750 lCurOperation := GetOperation(i);
751 lCurOperation.DrawTo(lCocoaContext);
752 end;
753 lCocoaContext.Free;
754 end;
755
756 end.
757
758