1 {
2 /***************************************************************************
3 Printers.pas
4 ------------
5 Basic Printer object
6
7 ****************************************************************************/
8
9 *****************************************************************************
10 This file is part of the Lazarus Component Library (LCL)
11
12 See the file COPYING.modifiedLGPL.txt, included in this distribution,
13 for details about the license.
14 *****************************************************************************
15
16 Author: Olivier Guilbaud
17 }
18 unit Printers;
19
20 {$mode objfpc}{$H+}
21
22 interface
23
24 uses
25 Classes, SysUtils, LCLProc, Graphics;
26 type
27 TPrinter = Class;
28 EPrinter = class(Exception);
29
30 TPrinterOrientation = (poPortrait,poLandscape,poReverseLandscape,poReversePortrait);
31 TPrinterCapability = (pcCopies, pcOrientation, pcCollation);
32 TPrinterCapabilities= Set of TPrinterCapability;
33 TPrinterState = (psNoDefine,psReady,psPrinting,psStopped);
34 TPrinterType = (ptLocal,ptNetWork);
35
36 {
37 This object it's a base class for TCanvas for TPrinter Object.
38 Few properties it's replicate for can create an TPrinterCavas not
39 associated with TPrinter or override few values.
40
41 BeginDoc,NewPage and EndDoc it's called in Printer.BeginDoc ...
42
43 PaperWidth: physical width of paper
44 PaperHeight: Physical height of paper
45 PageWidth: Printable width on page
46 PageHeight: Printable height of paper
47 }
48
49 { TPrinterCanvas }
50
51 TPrinterCanvas = class(TCanvas)
52 private
53 fPrinter : TPrinter;
54 fTitle : String;
55 fPageNum : Integer;
56 fTopMargin : Integer;
57 fLeftMargin : Integer;
58 fBottomMargin : Integer;
59 fRightMargin : Integer;
60 fPaperWidth : Integer;
61 fPaperHeight : Integer;
62 fOrientation : TPrinterOrientation;
63 fXDPI,fYDPI : Integer;
64
GetOrientationnull65 function GetOrientation: TPrinterOrientation;
GetPageHeightnull66 function GetPageHeight: Integer;
GetPageWidthnull67 function GetPageWidth: Integer;
GetPaperHeightnull68 function GetPaperHeight: Integer;
GetPaperWidthnull69 function GetPaperWidth: Integer;
GetTitlenull70 function GetTitle: string;
GetXDPInull71 function GetXDPI: Integer;
GetYDPInull72 function GetYDPI: Integer;
73 procedure SetOrientation(const AValue: TPrinterOrientation);
74 procedure SetPaperHeight(const AValue: Integer);
75 procedure SetPaperWidth(const AValue: Integer);
76 procedure SetTitle(const AValue: string);
HasDefaultMarginsnull77 function HasDefaultMargins: boolean;
78 procedure SetXDPI(const AValue: Integer);
79 procedure SetYDPI(const AValue: Integer);
80 protected
GetLeftMarginnull81 function GetLeftMargin: Integer;
GetTopMarginnull82 function GetTopMargin: Integer;
GetBottomMarginnull83 function GetBottomMargin: Integer;
GetRightMarginnull84 function GetRightMargin: Integer;
85 public
86 constructor Create(APrinter: TPrinter); virtual;
87 procedure BeginDoc; virtual;
88 procedure NewPage; virtual;
89 procedure BeginPage; virtual;
90 procedure EndPage; virtual;
91 procedure EndDoc; virtual;
92 procedure Changing; override;
93
94 property Printer : TPrinter read fPrinter;
95
96 property Title : string read GetTitle write SetTitle;
97 property PageHeight : Integer read GetPageHeight;
98 property PageWidth : Integer read GetPageWidth;
99 property PaperWidth : Integer read GetPaperWidth write SetPaperWidth;
100 property PaperHeight: Integer read GetPaperHeight write SetPaperHeight;
101 property PageNumber : Integer read fPageNum;
102 property TopMargin : Integer read GetTopMargin write FTopMargin;
103 property LeftMargin: Integer read GetLeftMargin write FLeftMargin;
104 property BottomMargin: Integer read GetBottomMargin write FBottomMargin;
105 property RightMargin: Integer read GetRightMargin write FRightMargin;
106 property Orientation: TPrinterOrientation read GetOrientation Write SetOrientation;
107 property XDPI: Integer read GetXDPI write SetXDPI;
108 property YDPI: Integer read GetYDPI write SetYDPI;
109
110 end;
111
112 TPrinterCanvasRef = Class of TPrinterCanvas;
113
114 { TFilePrinterCanvas }
115
116 TFilePrinterCanvas = class(TPrinterCanvas)
117 protected
118 FOutputFileName: string;
119 public
120 property OutputFileName : string read FOutputFileName write FOutputFileName;
121 end;
122
123 TFilePrinterCanvasClass = class of TFilePrinterCanvas;
124
125 TPaperRect = Record
126 PhysicalRect : TRect;
127 WorkRect : TRect;
128 end;
129
130 TPaperItem = record
131 PaperName: string[40];
132 PaperRect: TPaperRect;
133 end;
134
135 { TPaperSize }
136
137 TPaperSize = Class(TObject)
138 private
139 //The width and length are in points;
140 //there are 72 points per inch.
141
142 fOwnedPrinter : TPrinter;
143 fSupportedPapers : TStringList; //List of Paper supported by the current printer
144 fLastPrinterIndex : Integer; //Last index of printer used
145
GetDefaultPaperNamenull146 function GetDefaultPaperName: string;
GetPhysPaperHeightnull147 function GetPhysPaperHeight: Integer;
GetPaperNamenull148 function GetPaperName: string;
GetPaperRectnull149 function GetPaperRect: TPaperRect;
GetPhysPaperWidthnull150 function GetPhysPaperWidth: Integer;
GetSupportedPapersnull151 function GetSupportedPapers: TStrings;
152 procedure SetPaperName(const AName: string);
PaperRectOfNamenull153 function PaperRectOfName(const AName: string) : TPaperRect;
154 procedure CheckSupportedPapers;
155 private
156 fInternalPapers : array of TPaperItem;
157 fDefaultPapers : boolean;
158 fDefaultPaperIndex : Integer;
159 procedure CreateInternalPapers;
160 procedure FillDefaultPapers;
GetDefaultPaperRectnull161 function GetDefaultPaperRect(const AName: string; var APaperRect:TPaperRect): Integer;
IndexOfDefaultPapernull162 function IndexOfDefaultPaper(const AName: string): Integer;
163 public
164 constructor Create(aOwner : TPrinter); overload;
165 destructor Destroy; override;
166
167 property DefaultPapers : boolean read fDefaultPapers;
168 property Width : Integer read GetPhysPaperWidth;
169 property Height : Integer read GetPhysPaperHeight;
170 property PaperName : string read GetPaperName write SetPaperName;
171 property DefaultPaperName: string read GetDefaultPaperName;
172
173 property PaperRect : TPaperRect read GetPaperRect;
174 property SupportedPapers : TStrings read GetSupportedPapers;
175
176 property PaperRectOf[aName : string] : TPaperRect read PaperRectOfName;
177 end;
178
179 TPrinterFlags = set of
180 (
181 pfPrinting, //Printing
182 pfAborted, //Abort process
183 pfDestroying, //Printer object is being destroyed
184 pfPrintersValid, //fPrinters list is valid
185 pfRawMode //Printer is in raw mode
186 );
187
188 { TPrinter }
189
190 TPrinter = class(TObject)
191 private
192 fCanvas : TCanvas; //Active canvas object
193 FFileName : string; //Filename for output file
194 fFonts : TStrings; //Accepted font by printer
195 fPageNumber : Integer; //Current page number
196 fPrinters : TStrings; //Printers names list
197 fPrinterIndex: Integer; //selected printer index
198 fTitle : string; //Title of current document
199 //fCapabilities: TPrinterCapabilities;
200 fPaperSize : TPaperSize;
201 fCanvasClass : TPrinterCanvasRef;
202 fBins : TStrings;
203 fFlags : TPrinterFlags;
204
GetAbortednull205 function GetAborted: Boolean;
GetCanvasnull206 function GetCanvas: TCanvas;
207 procedure CheckPrinting(Value: Boolean);
GetCanvasClassnull208 function GetCanvasClass: TPrinterCanvasRef;
GetCopiesnull209 function GetCopies: Integer;
GetFontsnull210 function GetFonts: TStrings;
GetOrientationnull211 function GetOrientation: TPrinterOrientation;
GetPageHeightnull212 function GetPageHeight: Integer;
GetPageWidthnull213 function GetPageWidth: Integer;
GetPaperSizenull214 function GetPaperSize: TPaperSize;
GetBinNamenull215 Function GetBinName: string;
GetDefaultBinNamenull216 function GetDefaultBinName: string;
GetPrinterIndexnull217 function GetPrinterIndex: integer;
GetPrinterNamenull218 function GetPrinterName: string;
GetPrintersnull219 function GetPrinters: TStrings;
GetPrintingnull220 function GetPrinting: Boolean;
GetRawModenull221 function GetRawMode: boolean;
222 procedure SetCanvasClass(const AValue: TPrinterCanvasRef);
223 procedure SetCopies(AValue: Integer);
224 procedure SetOrientation(const AValue: TPrinterOrientation);
225 procedure SetPrinterIndex(AValue: integer);
226 procedure SetRawMode(const AValue: boolean);
227 procedure SetBinName(const aName: string);
228 protected
229 procedure SelectCurrentPrinterOrDefault;
230
231 procedure DoBeginDoc; virtual;
232 procedure DoNewPage; virtual;
233 procedure DoBeginPage; virtual;
234 procedure DoEndPage; virtual;
235 procedure DoEndDoc(aAborded : Boolean); virtual;
236 procedure DoAbort; virtual;
237 procedure DoResetPrintersList; virtual;
238 procedure DoResetFontsList; virtual;
239
240 procedure DoEnumPrinters(Lst : TStrings); virtual;
241 procedure DoEnumFonts(Lst : TStrings); virtual;
242 procedure DoEnumPapers(Lst : TStrings); virtual;
243 procedure DoEnumBins(Lst : TStrings); virtual;
244 procedure DoInitialization; virtual;
DoSetPrinternull245 function DoSetPrinter(aName : string): Integer; virtual;
DoGetCopiesnull246 function DoGetCopies : Integer; virtual;
247 procedure DoSetCopies(aValue : Integer); virtual;
DoGetOrientationnull248 function DoGetOrientation: TPrinterOrientation; virtual;
249 procedure DoSetOrientation(aValue : TPrinterOrientation); virtual;
DoGetDefaultPaperNamenull250 function DoGetDefaultPaperName: string; virtual;
DoGetPaperNamenull251 function DoGetPaperName: string; virtual;
252 procedure DoSetPaperName(aName : string); virtual;
DoGetDefaultBinNamenull253 function DoGetDefaultBinName: string; virtual;
DoGetBinNamenull254 function DoGetBinName: string; virtual;
255 procedure DoSetBinName(aName: string); virtual;
DoGetPaperRectnull256 function DoGetPaperRect(aName : string; Var aPaperRc : TPaperRect) : Integer; virtual;
DoGetPrinterStatenull257 function DoGetPrinterState: TPrinterState; virtual;
258 procedure DoDestroy; virtual;
259
GetPrinterTypenull260 function GetPrinterType : TPrinterType; virtual;
GetCanPrintnull261 function GetCanPrint : Boolean; virtual;
GetCanRenderCopiesnull262 function GetCanRenderCopies : Boolean; virtual;
GetXDPInull263 function GetXDPI: Integer; virtual;
GetYDPInull264 function GetYDPI: Integer; virtual;
GetBinsnull265 function GetBins: TStrings; virtual;
266 procedure CheckRawMode(const Value: boolean; Msg:string='');
267 procedure RawModeChanging; virtual;
268 procedure PrinterSelected; virtual;
DoGetDefaultCanvasClassnull269 function DoGetDefaultCanvasClass: TPrinterCanvasRef; virtual;
270
271 property PrinterFlags: TPrinterFlags read fFlags write fFlags;
272 public
273 constructor Create; virtual;
274 destructor Destroy; override;
275
276 procedure Abort;
277 procedure BeginDoc;
278 procedure EndDoc;
279 procedure NewPage;
280 procedure BeginPage;
281 procedure EndPage;
282 procedure Refresh;
283 procedure SetPrinter(aName : String);
284 Procedure RestoreDefaultBin; virtual;
Writenull285 function Write(const Buffer; Count:Integer; out Written: Integer): Boolean; virtual;
Writenull286 function Write(const s: ansistring): boolean; overload;
287
288 property PrinterIndex : integer read GetPrinterIndex write SetPrinterIndex;
289 property PrinterName: string read GetPrinterName;
290 property PaperSize : TPaperSize read GetPaperSize;
291 property Orientation: TPrinterOrientation read GetOrientation write SetOrientation;
292 property PrinterState : TPrinterState read DoGetPrinterState;
293 property Copies : Integer read GetCopies write SetCopies;
294 property Printers: TStrings read GetPrinters;
295 property FileName: string read FFileName write FFileName;
296 property Fonts: TStrings read GetFonts;
297 property Canvas: TCanvas read GetCanvas;
298 property CanvasClass: TPrinterCanvasRef read GetCanvasClass write SetCanvasClass;
299 property PageHeight: Integer read GetPageHeight;
300 property PageWidth: Integer read GetPageWidth;
301 property PageNumber : Integer read fPageNumber;
302 property Aborted: Boolean read GetAborted;
303 property Printing: Boolean read GetPrinting;
304 property Title: string read fTitle write fTitle;
305 property PrinterType : TPrinterType read GetPrinterType;
306 property CanPrint : Boolean read GetCanPrint;
307 property CanRenderCopies : Boolean read GetCanRenderCopies;
308 property XDPI : Integer read GetXDPI;
309 property YDPI : Integer read GetYDPI;
310 property RawMode: boolean read GetRawMode write SetRawMode;
311 property DefaultBinName: string read GetDefaultBinName;
312 property BinName: string read GetBinName write SetBinName;
313 property SupportedBins: TStrings read GetBins;
314 end;
315
316 // TPrinter it's an basic object. If you override this object,
317 // you must create an instance.
318 var
319 Printer: TPrinter = nil;
320
321 implementation
322
323 { TPrinter }
324
325 constructor TPrinter.Create;
326 begin
327 if ClassType=TPrinter then
328 raise Exception.Create('TPrinter is an abstract base class.'
329 +' Please use a printer implementation like the package printers4lazarus.');
330 Inherited Create;
331 fPrinterIndex:=-1; //By default, use the default printer
332 fCanvas:=nil;
333 fPaperSize:=nil;
334 fBins:=nil;
335 fTitle:='';
336 end;
337
338 destructor TPrinter.Destroy;
339 begin
340 Include(fFlags, pfDestroying);
341 DoDestroy;
342 inherited Destroy;
343 end;
344
345 //Abort the current document
346 procedure TPrinter.Abort;
347 begin
348 //Check if Printer print otherwise, exception
349 CheckPrinting(True);
350
351 DoAbort;
352
353 Include(fFlags, pfAborted);
354 EndDoc;
355 end;
356
357 //Begin a new document
358 procedure TPrinter.BeginDoc;
359 begin
360 //Check if Printer not printing otherwise, exception
361 CheckPrinting(False);
362
363 //If not selected printer, set default printer
364 SelectCurrentPrinterOrDefault;
365
366 Include(fFlags, pfPrinting);
367 Exclude(fFlags, pfAborted);
368 fPageNumber := 1;
369
370 if not RawMode then begin
371 Canvas.Refresh;
372 TPrinterCanvas(Canvas).BeginDoc;
373 end;
374 //Call the specifique Begindoc
375 DoBeginDoc;
376
377 BeginPage;
378
379 // Set font resolution
380 if not RawMode then
381 Canvas.Font.PixelsPerInch := YDPI;
382 end;
383
384 //End the current document
385 procedure TPrinter.EndDoc;
386 begin
387
388 EndPage;
389
390 //Check if Printer print otherwise, exception
391 CheckPrinting(True);
392
393 if not RawMode then
394 TPrinterCanvas(Canvas).EndDoc;
395
396 DoEndDoc(pfAborted in fFlags);
397
398 Exclude(fFlags, pfPrinting);
399 Exclude(fFlags, pfAborted);
400 fPageNumber := 0;
401 end;
402
403 //Create an new page
404 procedure TPrinter.NewPage;
405 begin
406 if TMethod(@Self.DoNewPage).Code = Pointer(@TPrinter.DoNewPage) then
407 begin
408 // DoNewPage has not been overriden, use the new method
409 EndPage;
410 BeginPage;
411 end else
412 begin
413 // Use the old method as DoNewPage has been overriden in descendat TPrinter
414 CheckPrinting(True);
415 Inc(fPageNumber);
416 if not RawMode then
417 TPrinterCanvas(Canvas).NewPage;
418 DoNewPage;
419 end;
420 end;
421
422 procedure TPrinter.BeginPage;
423 begin
424 CheckPrinting(True);
425 inc(fPageNumber);
426 if not RawMode then
427 TPrinterCanvas(Canvas).BeginPage;
428 DoBeginPage;
429 end;
430
431 procedure TPrinter.EndPage;
432 begin
433 if not RawMode then
434 TPrinterCanvas(Canvas).EndPage;
435 DoEndPage;
436 end;
437
438 //Clear Printers & Fonts list
439 procedure TPrinter.Refresh;
440 var
441 OldPrinter: string;
442 begin
443 //Check if Printer not printing otherwise, exception
444 CheckPrinting(False);
445
446 if FPrinterIndex>=0 then
447 OldPrinter := fPrinters[FPrinterIndex]
448 else
449 OldPrinter := '';
450
451 if Assigned(fPrinters) then
452 begin
453 DoResetPrintersList;
454 FreeAndNil(fPrinters);
455 end;
456
457 if Assigned(fFonts) then
458 begin
459 DoResetFontsList;
460 FreeAndNil(fFonts);
461 end;
462
463 // need to refill printers here otherwise
464 // it wont be filled on getting printers
465 // due to only one initialization
466 GetPrinters;
467
468 fPrinterIndex:=-1;
469
470 // try to locate old selected printer
471 if OldPrinter<>'' then
472 SetPrinter(OldPrinter);
473 end;
474
475 //Set the current printer
476 procedure TPrinter.SetPrinter(aName: String);
477 var
478 i,oldIndex : Integer;
479 begin
480 if aName='*' then begin
481 // select default printer
482 OldIndex := FPrinterIndex;
483 fPrinterIndex := -1; // avoid to remember last printer
484 Refresh;
485 if Printers.count>0 then begin
486 i:= doSetprinter(FPrinters[0]); // now first printer is default
487 if i<>0 then begin
488 // something went wrong, try to restore old printer
489 if OldIndex>=0 then
490 FPrinterIndex := doSetPrinter(FPrinters[OldIndex]);
491 raise EPrinter.Create('Unable to set default printer!');
492 end else
493 FPrinterIndex := i;
494 end;
495 end else
496 if (Printers.Count>0) then
497 begin
498 if (aName<>'') then
499 begin
500 //Printer changed ?
501 if fPrinters.IndexOf(aName)<>fPrinterIndex then
502 begin
503 i:=DoSetPrinter(aName);
504 if i<0 then
505 raise EPrinter.Create(Format('Printer "%s" doesn''t exist.',[aName]));
506 fPrinterIndex:=i;
507 end;
508 end;
509 end;
510 PrinterSelected;
511 end;
512
513 procedure TPrinter.RestoreDefaultBin;
514 begin
515 DoSetBinName(DoGetDefaultBinName);
516 end;
517
Writenull518 function TPrinter.Write(const Buffer; Count: Integer; out Written: Integer): Boolean;
519 begin
520 result := False;
521 Written := 0;
522 end;
523
Writenull524 function TPrinter.Write(const s: ansistring): boolean;
525 var
526 Written: integer;
527 begin
528 Result := Write(S[1], Length(S), Written);
529 end;
530
531 //Return an Canvas object
GetCanvasnull532 function TPrinter.GetCanvas: TCanvas;
533 begin
534 Result := nil;
535
536 CheckRawMode(False, 'Canvas not allowed in Raw Mode');
537
538 if not Assigned(fCanvas) then
539 begin
540 if not Assigned(CanvasClass) then
541 raise Exception.Create('Canvas Class not defined.');
542
543 fCanvas:=CanvasClass.Create(Self);
544 end;
545
546 Result:=fCanvas;
547 end;
548
GetAbortednull549 function TPrinter.GetAborted: Boolean;
550 begin
551 Result := (pfAborted in fFlags);
552 end;
553
554 //Raise error if Printer.Printing is not Value
555 procedure TPrinter.CheckPrinting(Value: Boolean);
556 begin
557 if Printing<>Value then
558 begin
559 if Value then
560 raise EPrinter.Create('Printer is not printing')
561 else
562 raise Eprinter.Create('Printer is printing');
563 end;
564 end;
565
GetCanvasClassnull566 function TPrinter.GetCanvasClass: TPrinterCanvasRef;
567 begin
568 if RawMode then
569 result := nil
570 else
571 if FCanvasClass=nil then
572 Result := DoGetDefaultCanvasClass
573 else
574 Result := FCanvasClass;
575 end;
576
577 procedure TPrinter.CheckRawMode(const Value: boolean; Msg: string);
578 begin
579 if RawMode<>Value then
580 begin
581 if msg='' then
582 if Value then
583 Msg:='Printer is in Raw Mode'
584 else
585 Msg:='Printer is not in Raw Mode';
586 raise EPrinter.Create(msg);
587 end;
588 end;
589
590 procedure TPrinter.RawModeChanging;
591 begin
592 //
593 end;
594
595 procedure TPrinter.PrinterSelected;
596 begin
597 end;
598
DoGetDefaultCanvasClassnull599 function TPrinter.DoGetDefaultCanvasClass: TPrinterCanvasRef;
600 begin
601 result := TPrinterCanvas;
602 end;
603
604 //Get current copies number
GetCopiesnull605 function TPrinter.GetCopies: Integer;
606 Var i : Integer;
607 begin
608 Result:=1;
609 i:=DoGetCopies;
610 if i>0 then
611 Result:=i;
612 end;
613
614 //Return & initialize the Fonts list
GetFontsnull615 function TPrinter.GetFonts: TStrings;
616 begin
617 if not Assigned(fFonts) then
618 fFonts:=TStringList.Create;
619 Result:=fFonts;
620
621 //Only 1 initialization
622 if fFonts.Count=0 then
623 DoEnumFonts(fFonts);
624 end;
625
GetOrientationnull626 function TPrinter.GetOrientation: TPrinterOrientation;
627 begin
628 Result:=DoGetOrientation;
629 end;
630
631 // Returns the height in points (pixels) of printable area
GetPageHeightnull632 function TPrinter.GetPageHeight: Integer;
633 begin
634 Result:=0;
635 if (Printers.Count>0) then
636 with PaperSize.PaperRect.WorkRect do
637 Result:=Bottom-Top;
638 end;
639
640 // Returns the width in points (pixels) of the printable area
GetPageWidthnull641 function TPrinter.GetPageWidth: Integer;
642 begin
643 Result:=0;
644 if (Printers.Count>0) then
645 with PaperSize.PaperRect.WorkRect do
646 // PageWidth is the size in "pixels" of the printable area
647 Result:=Right-Left;
648 end;
649
GetPaperSizenull650 function TPrinter.GetPaperSize: TPaperSize;
651 begin
652 if not Assigned(fPaperSize) then
653 fPaperSize:=TPaperSize.Create(self);
654 Result:=fPaperSize;
655 end;
656
GetBinNamenull657 function TPrinter.GetBinName: string;
658 begin
659 result := doGetBinName;
660 end;
661
GetDefaultBinNamenull662 function TPrinter.GetDefaultBinName: string;
663 begin
664 result := doGetDefaultBinName;
665 end;
666
667 //Return the current selected printer
GetPrinterIndexnull668 function TPrinter.GetPrinterIndex: integer;
669 begin
670 Result:=fPrinterIndex;
671 if (Result<0) and (Printers.Count>0) then
672 Result:=0; //printer by default
673 end;
674
GetPrinterNamenull675 function TPrinter.GetPrinterName: string;
676 begin
677 if PrinterIndex<0 then
678 result := ''
679 else
680 result := Printers[PrinterIndex];
681 end;
682
683 //Return & initialize the printers list
GetPrintersnull684 function TPrinter.GetPrinters: TStrings;
685 begin
686 if not Assigned(fPrinters) then
687 fPrinters:=TStringList.Create;
688 Result:=fPrinters;
689
690 //Only 1 initialization
691 if [pfPrintersValid, pfDestroying]*fFlags = [] then begin
692 Include(fFlags, pfPrintersValid);
693 DoEnumPrinters(fPrinters);
694 if FPrinters.Count>0 then
695 SelectCurrentPrinterOrDefault;
696 DoInitialization;
697 end;
698 end;
699
GetPrintingnull700 function TPrinter.GetPrinting: Boolean;
701 begin
702 result := (pfPrinting in fFlags);
703 end;
704
GetRawModenull705 function TPrinter.GetRawMode: boolean;
706 begin
707 result := (pfRawMode in fFlags);
708 end;
709
710 procedure TPrinter.SetCanvasClass(const AValue: TPrinterCanvasRef);
711 begin
712 FCanvasClass := AValue;
713 end;
714
715 //Return XDPI
GetXDPInull716 function TPrinter.GetXDPI: Integer;
717 begin
718 Result:=1;
719 end;
720
721 //Return YDPI
GetYDPInull722 function TPrinter.GetYDPI: Integer;
723 begin
724 Result:=1;
725 end;
726
GetBinsnull727 function TPrinter.GetBins: TStrings;
728 begin
729 if fBins=nil then
730 fBins := TStringList.Create;
731
732 doEnumBins(fBins);
733
734 result := fBins;
735 end;
736
737 //Set copies number
738 procedure TPrinter.SetCopies(AValue: Integer);
739 begin
740 CheckPrinting(False);
741 if aValue<1 then aValue:=1;
742 if Printers.Count>0 then
743 DoSetCopies(aValue)
744 else
745 raise EPrinter.Create('No printers found.');
746 end;
747
748 procedure TPrinter.SetOrientation(const AValue: TPrinterOrientation);
749 begin
750 DoSetOrientation(aValue);
751 end;
752
753 //Set selected printer
754 procedure TPrinter.SetPrinterIndex(AValue: integer);
755 Var aName : String;
756 begin
757 if fPrinterIndex=AValue then exit;
758 CheckPrinting(False);
759 if Printers.Count>0 then
760 begin
761 if AValue=-1 then
762 aName:='*'
763 else
764 if (AValue>=0) and (AValue<Printers.Count) then
765 aName:=Printers.Strings[AValue]
766 else
767 raise EPrinter.Create('Printer index out of range!');
768 SetPrinter(aName);
769 DoResetFontsList;
770 end
771 else
772 raise EPrinter.Create('No printers defined!');
773 end;
774
775 procedure TPrinter.SetRawMode(const AValue: boolean);
776 begin
777 if AValue<>RawMode then begin
778 CheckPrinting(False);
779 RawModeChanging;
780 if AValue then
781 Include(fFlags, pfRawMode)
782 else
783 Exclude(fFlags, pfRawMode);
784 end;
785 end;
786
787 procedure TPrinter.SetBinName(const aName: string);
788 begin
789 CheckPrinting(False);
790 DoSetBinName(aName);
791 end;
792
793 //If not Printer selected, Select the default printer
794 procedure TPrinter.SelectCurrentPrinterOrDefault;
795 begin
796 if (fPrinterIndex<0) and (Printers.Count>0) then
797 PrinterIndex:=0;
798 end;
799
800 procedure TPrinter.DoBeginDoc;
801 begin
802 //Override this method
803 end;
804
805 procedure TPrinter.DoNewPage;
806 begin
807 //Override this method
808 end;
809
810 procedure TPrinter.DoBeginPage;
811 begin
812 //Override this method
813 end;
814
815 procedure TPrinter.DoEndPage;
816 begin
817 //Override this method
818 end;
819
820 procedure TPrinter.DoEndDoc(aAborded : Boolean);
821 begin
822 //Override this method
823 end;
824
825 procedure TPrinter.DoAbort;
826 begin
827 //Override this method
828 end;
829
830 procedure TPrinter.DoResetPrintersList;
831 begin
832 //Override this method
833 Exclude(fFlags, pfPrintersValid);
834 end;
835
836 procedure TPrinter.DoResetFontsList;
837 begin
838 if fFonts<>nil then
839 fFonts.Clear;
840 end;
841
842 //Initialize the Lst with all definied printers
843 procedure TPrinter.DoEnumPrinters(Lst: TStrings);
844 begin
845 //Override this method
846 //Warning: The default printer must be the first printer
847 // (fPrinters[0])
848 end;
849
850 //Initialize the Lst with all supported fonts
851 procedure TPrinter.DoEnumFonts(Lst: TStrings);
852 begin
853 //Override this method
854 end;
855
856 //Initialize the Lst with all supported papers names
857 procedure TPrinter.DoEnumPapers(Lst: TStrings);
858 begin
859 //DebugLn(['TPrinter.DoEnumPapers ',dbgsName(Self)]);
860
861 //Override this method
862 end;
863
864 procedure TPrinter.DoEnumBins(Lst : TStrings);
865 begin
866 // Override this method
867 end;
868
869 // This method is called once after the printer list
870 // is obtained for the first time.
871 procedure TPrinter.DoInitialization;
872 begin
873 //Override this method
874 end;
875
876
877 //Set the current printer
DoSetPrinternull878 function TPrinter.DoSetPrinter(aName : string): Integer;
879 begin
880 //Override this method. The result must be
881 //the index of aName printer in Printers list
882 //if the aName doesn't exist, return -1
883 Result:=-1;
884 end;
885
886 //Get the current copies nulbers
TPrinter.DoGetCopiesnull887 function TPrinter.DoGetCopies: Integer;
888 begin
889 //Override this method
890 Result:=1;
891 end;
892
893 //Set copies number
894 procedure TPrinter.DoSetCopies(aValue: Integer);
895 begin
896 //Override this method
897 end;
898
899 //Return current paper orientation
TPrinter.DoGetOrientationnull900 function TPrinter.DoGetOrientation: TPrinterOrientation;
901 begin
902 Result:=poPortrait;
903 //Override this method
904 end;
905
906 //Set paper Orientation
907 procedure TPrinter.DoSetOrientation(aValue: TPrinterOrientation);
908 begin
909 //Override this method
910 end;
911
912 //Return the default paper name for the selected printer
TPrinter.DoGetDefaultPaperNamenull913 function TPrinter.DoGetDefaultPaperName: string;
914 begin
915 Result:='';
916 //Override this methode
917 end;
918
919 //Return selected paper name for the current printer
TPrinter.DoGetPaperNamenull920 function TPrinter.DoGetPaperName: string;
921 begin
922 Result:='';
923 //Override this method
924 end;
925
926 procedure TPrinter.DoSetPaperName(aName: string);
927 begin
928 //Override this method
929 end;
930
TPrinter.DoGetDefaultBinNamenull931 function TPrinter.DoGetDefaultBinName: string;
932 begin
933 Result:='';
934 end;
935
TPrinter.DoGetBinNamenull936 function TPrinter.DoGetBinName: string;
937 begin
938 result := '';
939 end;
940
941 procedure TPrinter.DoSetBinName(aName: string);
942 begin
943 if SupportedBins.Count>0 then
944 DebugLn('Warning: bin %s is not allowed',[aName]);
945 end;
946
947 //Initialise aPaperRc with the aName paper rect
948 //Result : -1 no result
949 // 0 aPaperRc.WorkRect is a margins
950 // 1 aPaperRc.WorkRect is really the work rect
DoGetPaperRectnull951 function TPrinter.DoGetPaperRect(aName : string; var aPaperRc: TPaperRect): Integer;
952 begin
953 Result:=-1;
954 //Override this method
955 end;
956
957 //Get a state of current printer
TPrinter.DoGetPrinterStatenull958 function TPrinter.DoGetPrinterState: TPrinterState;
959 begin
960 //Override this method
961 Result:=psNoDefine;
962 end;
963
964 procedure TPrinter.DoDestroy;
965 begin
966 if Printing then
967 Abort;
968
969 fBins.free;
970
971 if Assigned(fCanvas) then
972 fCanvas.Free;
973
974 if Assigned(fPaperSize) then
975 fPaperSize.Free;
976
977
978 if Assigned(fPrinters) then
979 begin
980 DoResetPrintersList;
981 FreeAndNil(fPrinters);
982 end;
983
984 if Assigned(fFonts) then
985 begin
986 DoResetFontsList;
987 FreeAndNil(fFonts);
988 end;
989 end;
990
991 //Return the type of selected printer
GetPrinterTypenull992 function TPrinter.GetPrinterType: TPrinterType;
993 begin
994 Result:=ptLocal;
995 end;
996
997 //Return True if selected printer is able to print
GetCanPrintnull998 function TPrinter.GetCanPrint: Boolean;
999 begin
1000 Result:=True;
1001 end;
1002
GetCanRenderCopiesnull1003 function TPrinter.GetCanRenderCopies: Boolean;
1004 begin
1005 Result:=True;
1006 end;
1007
1008 { TPaperSize }
1009
1010 procedure TPaperSize.CreateInternalPapers;
1011 procedure add(AnIndex:Integer; aname:string; aPhysRect,aWrkRect:TRect);
1012 begin
1013 with fInternalPapers[AnIndex] do begin
1014 PaperName := aName;
1015 PaperRect.PhysicalRect := aPhysRect;
1016 PaperRect.WorkRect := aWrkRect;
1017 end;
1018 end;
PRRectnull1019 function PRRect(const ALeft,ATop,ARight,ABottom: Integer): TRect;
1020 begin
1021 Result.Left := ALeft;
1022 Result.Top := ATop;
1023 Result.Right := round(ARight * FOwnedPrinter.XDPI / 72);
1024 Result.Bottom := round(ABottom * FOwnedPrinter.XDPI / 72);
1025 end;
1026 begin
1027 if Length(fInternalPapers)=0 then
1028 begin
1029 SetLength(fInternalPapers, 3);
1030 add(0, 'Letter', PRRect(0, 0, 612, 792 ), PRRect(0, 0, 612, 792 ));
1031 add(1, 'A4', PRRect(0, 0, 595, 892 ), PRRect(0, 0, 595, 892 ));
1032 add(2, 'Legal', PRRect(0, 0, 612, 1008), PRRect(0, 0, 612, 1008));
1033 end;
1034 end;
1035
1036 procedure TPaperSize.FillDefaultPapers;
1037 var
1038 i: Integer;
1039 begin
1040 FSupportedPapers.Clear;
1041 CreateInternalPapers;
1042 for i:=0 to Length(FInternalPapers)-1 do
1043 FSupportedPapers.Add(FInternalPapers[i].PaperName);
1044 FDefaultPaperIndex := 0;
1045 FDefaultPapers := true;
1046 end;
1047
TPaperSize.GetDefaultPaperNamenull1048 function TPaperSize.GetDefaultPaperName: string;
1049 begin
1050 CheckSupportedPapers;
1051
1052 if fDefaultPapers then
1053 Result := FSupportedPapers[0]
1054 else
1055 Result := fOwnedPrinter.DoGetDefaultPaperName;
1056 end;
1057
TPaperSize.GetDefaultPaperRectnull1058 function TPaperSize.GetDefaultPaperRect(const AName: string;
1059 var APaperRect:TPaperRect): Integer;
1060 var
1061 PR: TPaperRect;
1062 begin
1063 Result := IndexOfDefaultPaper(AName);
1064 if Result>=0 then
1065 PR:=FInternalPapers[Result].PaperRect;
1066 if FOwnedPrinter.Orientation in [poPortrait, poReversePortrait] then
1067 begin
1068 APaperRect.PhysicalRect := PR.PhysicalRect;
1069 APaperRect.WorkRect := PR.WorkRect;
1070 end else
1071 begin
1072 APaperRect.PhysicalRect.Left := 0;
1073 APaperRect.PhysicalRect.Top := 0;
1074 APaperRect.PhysicalRect.Right := PR.PhysicalRect.Bottom;
1075 APaperRect.Physicalrect.Bottom := PR.PhysicalRect.Right;
1076
1077 APaperRect.WorkRect.Left := PR.WorkRect.Top;
1078 APaperRect.WorkRect.Top := PR.PhysicalRect.Right-PR.WorkRect.Right;
1079 APaperRect.WorkRect.Right := PR.WorkRect.Bottom;
1080 APaperRect.WorkRect.Bottom := PR.PhysicalRect.Right-PR.Workrect.Left;
1081 end;
1082 end;
1083
GetPhysPaperHeightnull1084 function TPaperSize.GetPhysPaperHeight: Integer;
1085 begin
1086 result := PaperRect.PhysicalRect.Bottom - PaperRect.PhysicalRect.Top;
1087 end;
1088
TPaperSize.GetPaperNamenull1089 function TPaperSize.GetPaperName: string;
1090 begin
1091 CheckSupportedPapers;
1092
1093 if fDefaultPapers then
1094 Result := SupportedPapers[FDefaultPaperIndex]
1095 else
1096 Result := fOwnedPrinter.DoGetPaperName;
1097
1098 if Result='' then
1099 Result:=DefaultPaperName;
1100 end;
1101
GetPaperRectnull1102 function TPaperSize.GetPaperRect: TPaperRect;
1103 begin
1104 Result:=PaperRectOfName(PaperName);
1105 end;
1106
GetPhysPaperWidthnull1107 function TPaperSize.GetPhysPaperWidth: Integer;
1108 begin
1109 result := PaperRect.PhysicalRect.Right - PaperRect.PhysicalRect.Left;
1110 end;
1111
TPaperSize.GetSupportedPapersnull1112 function TPaperSize.GetSupportedPapers: TStrings;
1113 begin
1114 CheckSupportedPapers;
1115
1116 Result:=fSupportedPapers;
1117 end;
1118
TPaperSize.IndexOfDefaultPapernull1119 function TPaperSize.IndexOfDefaultPaper(const AName: string): Integer;
1120 var
1121 i: Integer;
1122 begin
1123 Result := -1;
1124 for i:=0 to Length(fInternalPapers)-1 do
1125 if CompareText(fInternalPapers[i].PaperName, AName)=0 then
1126 begin
1127 Result := i;
1128 break;
1129 end;
1130 end;
1131
1132 procedure TPaperSize.SetPaperName(const AName: string);
1133 begin
1134 if SupportedPapers.IndexOf(aName)<>-1 then
1135 begin
1136 if aName<>PaperName then
1137 begin
1138 if fDefaultPapers then
1139 FDefaultPaperIndex := IndexOfDefaultPaper(AName)
1140 else
1141 FOwnedPrinter.DoSetPaperName(aName)
1142 end;
1143 end
1144 else
1145 raise EPrinter.Create(Format('Paper "%s" not supported!',[aName]));
1146 end;
1147
1148 //Return an TPaperRect corresponding at an paper name
TPaperSize.PaperRectOfNamenull1149 function TPaperSize.PaperRectOfName(const AName: string): TPaperRect;
1150 var TmpPaperRect : TPaperRect;
1151 Margins : Integer;
1152 begin
1153 FillChar(Result,SizeOf(Result),0);
1154
1155 if SupportedPapers.IndexOf(AName)<>-1 then
1156 begin
1157
1158 if fDefaultPapers then
1159 Margins := GetDefaultPaperRect(AName, TmpPaperRect)
1160 else
1161 Margins := fOwnedPrinter.DoGetPaperRect(aName,TmpPaperRect);
1162
1163 if Margins>=0 then
1164 Result := TmpPaperRect
1165 else
1166 raise EPrinter.Create(Format('The paper "%s" has no defined rectangle!',[aName]));
1167
1168 end
1169 else raise EPrinter.Create(Format('Paper "%s" not supported!',[aName]));
1170 end;
1171
1172 procedure TPaperSize.CheckSupportedPapers;
1173 begin
1174 if (fSupportedPapers.Count=0) or
1175 (fLastPrinterIndex<>fOwnedPrinter.PrinterIndex) then
1176 begin
1177 fOwnedPrinter.SelectCurrentPrinterOrDefault;
1178
1179 fSupportedPapers.Clear;
1180 fDefaultPapers := false;
1181 //DebugLn(['TPaperSize.GetSupportedPapers ',dbgsName(fOwnedPrinter),' ',dbgsName(Printer),' ',fOwnedPrinter=Printer]);
1182 fOwnedPrinter.DoEnumPapers(fSupportedPapers);
1183
1184 if fSupportedPapers.Count=0 then
1185 FillDefaultPapers;
1186
1187 fLastPrinterIndex:=fOwnedPrinter.PrinterIndex;
1188 end;
1189 end;
1190
1191 constructor TPaperSize.Create(aOwner: TPrinter);
1192 begin
1193 if not assigned(aOwner) then
1194 raise Exception.Create('TMediaSize.Create, aOwner must be defined!');
1195 Inherited Create;
1196
1197 fLastPrinterIndex:=-2;
1198 fOwnedPrinter:=aOwner;
1199 fSupportedPapers:=TStringList.Create;
1200 end;
1201
1202 destructor TPaperSize.Destroy;
1203 begin
1204 fSupportedPapers.Free;
1205
1206 inherited Destroy;
1207 end;
1208
1209 { TPrinterCanvas }
1210
TPrinterCanvas.GetTitlenull1211 function TPrinterCanvas.GetTitle: string;
1212 begin
1213 if Assigned(fPrinter) then
1214 Result:=fPrinter.Title
1215 else
1216 Result:=fTitle;
1217 end;
1218
GetXDPInull1219 function TPrinterCanvas.GetXDPI: Integer;
1220 begin
1221 if Printer<>nil then
1222 result := Printer.XDPI
1223 else
1224 if fXDPI <= 0 then
1225 result := 300
1226 else
1227 result := fXDPI;
1228 end;
1229
TPrinterCanvas.GetYDPInull1230 function TPrinterCanvas.GetYDPI: Integer;
1231 begin
1232 if Printer<>nil then
1233 result := Printer.YDPI
1234 else
1235 if fYDPI <= 0 then
1236 result := 300
1237 else
1238 result := fYDPI;
1239 end;
1240
1241 procedure TPrinterCanvas.SetOrientation(const AValue: TPrinterOrientation);
1242 begin
1243 if Assigned(fPrinter) then
1244 fPrinter.Orientation := AValue
1245 else
1246 fOrientation := AValue;
1247 end;
1248
TPrinterCanvas.GetOrientationnull1249 function TPrinterCanvas.GetOrientation: TPrinterOrientation;
1250 begin
1251 if fPrinter<>nil then
1252 result := fPrinter.Orientation
1253 else
1254 result := fOrientation;
1255 end;
1256
TPrinterCanvas.GetPageHeightnull1257 function TPrinterCanvas.GetPageHeight: Integer;
1258 begin
1259 if Assigned(fPrinter) and HasDefaultMargins then
1260 Result:=fPrinter.PageHeight
1261 else
1262 Result:= PaperHeight - TopMargin - BottomMargin;
1263 end;
1264
GetPageWidthnull1265 function TPrinterCanvas.GetPageWidth: Integer;
1266 begin
1267 if Assigned(fPrinter) and HasDefaultMargins then
1268 Result:=fPrinter.PageWidth
1269 else
1270 Result:= PaperWidth - LeftMargin - RightMargin;
1271 end;
1272
GetPaperHeightnull1273 function TPrinterCanvas.GetPaperHeight: Integer;
1274 begin
1275 if Assigned(fPrinter) then
1276 result := fPrinter.PaperSize.Height
1277 else
1278 if fPaperHeight<=0 then
1279 result := round(YDPI * 842 / 72) // default to A4 paper
1280 else
1281 result := fPaperHeight;
1282 end;
1283
TPrinterCanvas.GetPaperWidthnull1284 function TPrinterCanvas.GetPaperWidth: Integer;
1285 begin
1286 if Assigned(fPrinter) then
1287 result := fPrinter.PaperSize.Width
1288 else
1289 if fPaperWidth<=0 then
1290 result := round(XDPI * 595 / 72) // default to A4 paper
1291 else
1292 result := fPaperWidth;
1293 end;
1294
1295 procedure TPrinterCanvas.SetPaperHeight(const AValue: Integer);
1296 begin
1297 fPaperHeight := AValue;
1298 end;
1299
1300 procedure TPrinterCanvas.SetPaperWidth(const AValue: Integer);
1301 begin
1302 fPaperWidth := AValue;
1303 end;
1304
1305 procedure TPrinterCanvas.SetTitle(const AValue: string);
1306 begin
1307 if Assigned(fPrinter) then
1308 fPrinter.Title:=aValue
1309 else
1310 fTitle:=aValue;
1311 end;
1312
HasDefaultMarginsnull1313 function TPrinterCanvas.HasDefaultMargins: boolean;
1314 begin
1315 result := (FLeftMargin=0) and (FRightMargin=0) and
1316 (FTopMargin=0) and (FBottomMargin=0);
1317 end;
1318
1319 procedure TPrinterCanvas.SetXDPI(const AValue: Integer);
1320 begin
1321 fXDPI := AValue;
1322 end;
1323
1324 procedure TPrinterCanvas.SetYDPI(const AValue: Integer);
1325 begin
1326 fYDPI := AValue;
1327 end;
1328
1329 constructor TPrinterCanvas.Create(APrinter: TPrinter);
1330 begin
1331 inherited Create;
1332 fPrinter:=aPrinter;
1333 end;
1334
1335 procedure TPrinterCanvas.Changing;
1336 begin
1337 if Assigned(fPrinter) then
1338 fPrinter.CheckPrinting(True);
1339 inherited Changing;
1340 end;
1341
1342 procedure TPrinterCanvas.BeginDoc;
1343 begin
1344 fPageNum:=1;
1345 end;
1346
1347 procedure TPrinterCanvas.NewPage;
1348 begin
1349 BeginPage;
1350 end;
1351
1352 procedure TPrinterCanvas.BeginPage;
1353 begin
1354 Inc(fPageNum);
1355 end;
1356
1357 procedure TPrinterCanvas.EndPage;
1358 begin
1359
1360 end;
1361
1362 procedure TPrinterCanvas.EndDoc;
1363 begin
1364 //No special action
1365 end;
1366
GetLeftMarginnull1367 function TPrinterCanvas.GetLeftMargin: Integer;
1368 begin
1369 if (fLeftMargin=0) and (fPrinter<>nil) then
1370 Result:=fPrinter.PaperSize.PaperRect.WorkRect.Left
1371 else
1372 Result:=fLeftMargin;
1373 end;
1374
TPrinterCanvas.GetTopMarginnull1375 function TPrinterCanvas.GetTopMargin: Integer;
1376 begin
1377 if (fTopMargin=0) and (fPrinter<>nil) then
1378 Result:=fPrinter.PaperSize.PaperRect.WorkRect.Top
1379 else
1380 Result:=fTopMargin;
1381 end;
1382
TPrinterCanvas.GetBottomMarginnull1383 function TPrinterCanvas.GetBottomMargin: Integer;
1384 begin
1385 if (fBottomMargin=0) and (fPrinter<>nil) then
1386 begin
1387 with fPrinter.Papersize.PaperRect do
1388 Result := PhysicalRect.Bottom-WorkRect.Bottom;
1389 end else
1390 Result := fBottomMargin;
1391 end;
1392
TPrinterCanvas.GetRightMarginnull1393 function TPrinterCanvas.GetRightMargin: Integer;
1394 var
1395 PR: TPaperRect;
1396 begin
1397 if (fRightMargin=0) and (fPrinter<>nil) then
1398 begin
1399 PR:=fPrinter.Papersize.PaperRect;
1400 Result := PR.PhysicalRect.Right-PR.WorkRect.Right;
1401 end else
1402 Result := fRightMargin;
1403 end;
1404
1405
1406 procedure doFreePrinter;
1407 begin
1408 if Assigned(Printer) then
1409 Printer.Free;
1410 Printer := nil;
1411 end;
1412
1413 initialization
1414 RegisterInterfaceFinalizationHandler(@doFreePrinter);
1415
1416 end.
1417