Printers4Lazarus: initial implementation of native Carbon printing, use -dNativePrint to try it

git-svn-id: trunk@13104 -
This commit is contained in:
tombo 2007-12-01 15:12:29 +00:00
parent 7a6627d167
commit 032af9a4ec
9 changed files with 651 additions and 93 deletions

2
.gitattributes vendored
View File

@ -648,6 +648,8 @@ components/printers/Makefile svneol=native#text/plain
components/printers/Makefile.fpc svneol=native#text/plain
components/printers/carbon/carbonprinters.inc svneol=native#text/pascal
components/printers/carbon/carbonprinters_h.inc svneol=native#text/pascal
components/printers/carbon/carbonprinting.pas svneol=native#text/pascal
components/printers/carbon/carbonprndialogs.inc svneol=native#text/pascal
components/printers/design/Makefile svneol=native#text/plain
components/printers/design/Makefile.fpc svneol=native#text/plain
components/printers/design/ideprinting.pas svneol=native#text/plain

View File

@ -2,178 +2,526 @@
{**************************************************************
Implementation for carbonprinter
***************************************************************}
Uses InterfaceBase, LCLIntf;
Uses InterfaceBase, LCLIntf, CarbonProc, LCLProc;
{ TCarbonPrinterContext }
function TCarbonPrinterContext.GetSize: TPoint;
var
R: PMRect;
begin
Result.X := 0;
Result.Y := 0;
if Printer = nil then Exit;
if OSError(PMGetAdjustedPaperRect((Printer as TCarbonPrinter).PageFormat, R),
Self, 'GetSize', 'PMGetUnadjustedPaperRect') then Exit;
Result.X := Round(R.right - R.left);
Result.Y := Round(R.bottom - R.top);
end;
procedure TCarbonPrinterContext.Release;
begin
// redirect drawing to dummy context when not able printing page
CGContext := DefaultContext.CGContext;
end;
procedure TCarbonPrinterContext.Reset;
begin
inherited Reset;
if CGContext <> nil then
begin
// flip and offset CTM from lower to upper left corner
CGContextTranslateCTM(CGContext, 0, GetSize.Y);
CGContextScaleCTM(CGContext, 1, -1);
end;
end;
{ TCarbonPrinter }
procedure TCarbonPrinter.CreatePrintSession;
begin
if OSError(PMCreateSession(FPrintSession), Self, 'GetPrintSession', 'PMCreateSession') then
raise EPrinter.Create('Error initializing printing for Carbon: Unable to create print session!');
end;
procedure TCarbonPrinter.CreatePrintSettings;
const
SName = 'CreatePrintSettings';
begin
if OSError(PMCreatePrintSettings(FPrintSettings), Self, SName, 'PMCreatePrintSettings') then
raise EPrinter.Create('Error initializing printing for Carbon: Unable to create print settings!');
OSError(PMSessionDefaultPrintSettings(PrintSession, FPrintSettings), Self, SName, 'PMSessionDefaultPrintSettings');
end;
function TCarbonPrinter.CreatePageFormat(APaper: String): PMPageFormat;
var
I: Integer;
S: TStringList;
const
SName = 'CreatePageFormat';
begin
if APaper = '' then
begin
I := -1;
S := nil;
end
else
begin
S := TStringList.Create;
BeginEnumPapers(S);
I := S.IndexOf(APaper);
end;
try
if I < 0 then
begin
if OSError(PMCreatePageFormat(Result), Self, SName, 'PMCreatePageFormat') then
raise EPrinter.Create('Error initializing printing for Carbon: Unable to create page format!');
OSError(PMSessionDefaultPageFormat(PrintSession, Result), Self, SName, 'PMSessionDefaultPageFormat');
end
else
begin
OSError(PMCreatePageFormatWithPMPaper(Result,
PMPaper(CFArrayGetValueAtIndex(FPaperArray, I))),
Self, SName, 'PMCreatePageFormatWithPMPaper');
ValidatePageFormat;
end;
finally
if S <> nil then
begin
EndEnumPapers;
S.Free;
end;
end;
end;
function TCarbonPrinter.ValidatePageFormat: Boolean;
begin
Result := False;
OSError(PMSessionValidatePageFormat(PrintSession, PageFormat, @Result),
Self, 'ValidatePageFormat', 'PMSessionValidatePageFormat');
end;
function TCarbonPrinter.ValidatePrintSettings: Boolean;
begin
Result := False;
OSError(PMSessionValidatePrintSettings(PrintSession, PrintSettings, @Result),
Self, 'ValidatePrintSettings', 'PMSessionValidatePrintSettings');
end;
function TCarbonPrinter.GetCurrentPrinter: PMPrinter;
begin
OSError(PMSessionGetCurrentPrinter(PrintSession, Result), Self, 'GetCurrentPrinter', 'PMSessionGetCurrentPrinter');
end;
procedure TCarbonPrinter.BeginPage;
begin
if FBeginDocumentStatus = noErr then
begin
FNewPageStatus := PMSessionBeginPage(PrintSession, nil, nil);
OSError(FNewPageStatus, Self, 'BeginPage', 'PMSessionBeginPage', '', kPMCancel);
// update printer context
if OSError(PMSessionGetCGGraphicsContext(PrintSession, FPrinterContext.CGContext),
Self, 'BeginPage', 'PMSessionGetCGGraphicsContext') then
FPrinterContext.Release
else
FPrinterContext.Reset;
if Assigned(Canvas) then Canvas.Handle := HDC(FPrinterContext);
end;
end;
procedure TCarbonPrinter.EndPage;
begin
FPrinterContext.Release;
if Assigned(Canvas) then Canvas.Handle := 0;
if FBeginDocumentStatus = noErr then
begin
if FNewPageStatus = noErr then
OSError(PMSessionEndPage(PrintSession), Self, 'EndPage', 'PMSessionEndPage', '', kPMCancel);
end;
end;
procedure TCarbonPrinter.BeginEnumPrinters(Lst: TStrings);
var
P: PMPrinter;
I, C: CFIndex;
PrinterName: String;
begin
if OSError(PMServerCreatePrinterList(kPMServerLocal, FPrinterArray),
Self, 'DoEnumPrinters', 'PMServerCreatePrinterList') then Exit;
C := CFArrayGetCount(FPrinterArray);
for I := 0 to C - 1 do
begin
P := CFArrayGetValueAtIndex(FPrinterArray, I);
PrinterName := CFStringToStr(PMPrinterGetName(P));
if PMPrinterIsDefault(P) then
Lst.Insert(0, PrinterName)
else
Lst.Add(PrinterName);
end;
end;
procedure TCarbonPrinter.EndEnumPrinters;
begin
CFRelease(FPrinterArray);
end;
procedure TCarbonPrinter.BeginEnumPapers(Lst: TStrings);
var
P: PMPaper;
I, C: CFIndex;
CFString: CFStringRef;
PaperName: String;
const
SName = 'DoEnumPapers';
begin
if OSError(PMPrinterGetPaperList(GetCurrentPrinter, FPaperArray),
Self, SName, 'PMPrinterGetPaperList') then Exit;
FPaperArray := CFRetain(FPaperArray);
C := CFArrayGetCount(FPaperArray);
for I := 0 to C - 1 do
begin
P := CFArrayGetValueAtIndex(FPaperArray, I);
if OSError(PMPaperGetName(P, CFString), Self, SName, 'PMPaperGetName') then Continue;
PaperName := CFStringToStr(CFString);
Lst.Add(PaperName);
end;
end;
procedure TCarbonPrinter.EndEnumPapers;
begin
CFRelease(FPaperArray);
end;
constructor TCarbonPrinter.Create;
begin
inherited Create;
//IMPLEMENT ME
CreatePrintSession;
CreatePrintSettings;
FPageFormat := CreatePageFormat('');
FPrinterContext := TCarbonPrinterContext.Create;
end;
destructor TCarbonPrinter.Destroy;
begin
FPrinterContext.Free;
if FPrintSettings <> nil then PMRelease(PMObject(FPrintSettings));
if FPageFormat <> nil then PMRelease(PMObject(FPageFormat));
if FPrintSession <> nil then PMRelease(PMObject(FPrintSession));
inherited Destroy;
//IMPLEMENT ME
end;
function TCarbonPrinter.Write(const Buffer; Count: Integer;
var Written: Integer): Boolean;
begin
Result := False;
CheckRawMode(True);
//IMPLEMENT ME
end;
function TCarbonPrinter.GetHandlePrinter : HDC;
begin
//IMPLEMENT ME
result := 0;
end;
procedure TCarbonPrinter.SetHandlePrinter(aValue : HDC);
begin
CheckRawMode(False);
//IMPLEMENT ME
DebugLn('TCarbonPrinter.Write Error: Raw mode is not supported for Carbon!');
end;
procedure TCarbonPrinter.RawModeChanging;
begin
//IMPLEMENT ME
//
end;
procedure TCarbonPrinter.Validate;
var
P: String;
begin
ValidatePrintSettings;
ValidatePageFormat;
// if target paper is not supported, use the default
P := DoGetPaperName;
if PaperSize.SupportedPapers.IndexOf(P) = -1 then
DoSetPaperName(DoGetDefaultPaperName);
end;
function TCarbonPrinter.GetXDPI: Integer;
begin
//IMPLEMENT ME
Result := 72;
end;
function TCarbonPrinter.GetYDPI: Integer;
begin
//IMPLEMENT ME
Result := 72;
end;
procedure TCarbonPrinter.DoBeginDoc;
begin
inherited DoBeginDoc;
//IMPLEMENT ME
//DebugLn('TCarbonPrinter.DoBeginDoc ' + DbgS(Printing));
FBeginDocumentStatus := PMSessionBeginCGDocument(PrintSession, PrintSettings, PageFormat);
OSError(FBeginDocumentStatus, Self, 'DoBeginDoc', 'PMSessionBeginCGDocument', '', kPMCancel);
FNewPageStatus := kPMCancel;
BeginPage;
end;
procedure TCarbonPrinter.DoNewPage;
begin
inherited DoNewPage;
//IMPLEMENT ME
EndPage;
BeginPage;
end;
procedure TCarbonPrinter.DoEndDoc(aAborded: Boolean);
begin
inherited DoEndDoc(aAborded);
//IMPLEMENT ME
EndPage;
if FBeginDocumentStatus = noErr then
OSError(PMSessionEndDocument(PrintSession), Self, 'DoEndDoc', 'PMSessionEndDocument', '', kPMCancel);
end;
procedure TCarbonPrinter.DoAbort;
begin
inherited DoAbort;
//IMPLEMENT ME
OSError(PMSessionSetError(PrintSession, kPMCancel), Self, 'DoAbort', 'PMSessionSetError');
end;
//Enum all defined printers. First printer it's default
procedure TCarbonPrinter.DoEnumPrinters(Lst: TStrings);
begin
//IMPLEMENT ME
BeginEnumPrinters(Lst);
EndEnumPrinters;
end;
procedure TCarbonPrinter.DoResetPrintersList;
begin
//IMPLEMENT ME
inherited DoResetPrintersList;
end;
procedure TCarbonPrinter.DoEnumPapers(Lst: TStrings);
begin
inherited DoEnumPapers(Lst);
//IMPLEMENT ME
BeginEnumPapers(Lst);
EndEnumPapers;
end;
function TCarbonPrinter.DoGetPaperName: string;
var
P: PMPaper;
CFString: CFStringRef;
const
SName = 'DoGetPaperName';
begin
Result:=inherited DoGetPaperName;
//IMPLEMENT ME
Result := '';
if OSError(PMGetPageFormatPaper(PageFormat, P), Self, SName, 'PMGetPageFormatPaper') then Exit;
if OSError(PMPaperGetName(P, CFString), Self, SName, 'PMPaperGetName') then Exit;
Result := CFStringToStr(CFString);
end;
function TCarbonPrinter.DoGetDefaultPaperName: string;
var
T: PMPageFormat;
begin
Result:=inherited DoGetDefaultPaperName;
//IMPLEMENT ME
Result := '';
T := FPageFormat;
FPageFormat := CreatePageFormat('');
Result := DoGetPaperName;
if T <> nil then
begin
PMRelease(PMObject(FPageFormat));
FPageFormat := T;
end;
end;
procedure TCarbonPrinter.DoSetPaperName(aName: string);
procedure TCarbonPrinter.DoSetPaperName(AName: string);
var
O: TPrinterOrientation;
begin
inherited DoSetPaperName(aName);
//IMPLEMENT ME
O := DoGetOrientation;
if FPageFormat <> nil then PMRelease(PMObject(FPageFormat));
FPageFormat := CreatePageFormat(AName);
DoSetOrientation(O);
end;
function TCarbonPrinter.DoGetPaperRect(aName: string;
var aPaperRc: TPaperRect): Integer;
function TCarbonPrinter.DoGetPaperRect(AName: string; var APaperRc: TPaperRect): Integer;
var
T: PMPageFormat;
PaperRect, PageRect: PMRect;
S: Double;
O: PMOrientation;
const
SName = 'DoGetPaperRect';
begin
Result:=Inherited DoGetPaperRect(aName,aPaperRc);
//IMPLEMENT ME
Result := -1;
T := CreatePageFormat(AName);
try
// copy scale
OSError(PMGetScale(PageFormat, S), Self, SName, 'PMGetScale');
OSError(PMSetScale(T, S), Self, SName, 'PMSetScale');
// copy orientation
OSError(PMGetOrientation(PageFormat, O), Self, SName, 'PMGetOrientation');
OSError(PMSetOrientation(T, O, False), Self, SName, 'PMSetOrientation');
// update
OSError(PMSessionValidatePageFormat(PrintSession, T, nil),
Self, SName, 'PMSessionValidatePageFormat');
OSError(PMGetAdjustedPaperRect(T, PaperRect), Self, SName, 'PMGetAdjustedPaperRect');
OSError(PMGetAdjustedPageRect(T, PageRect), Self, SName, 'PMGetAdjustedPageRect');
finally
PMRelease(PMObject(T));
end;
ValidatePageFormat;
APaperRc.PhysicalRect.Left := 0;
APaperRc.PhysicalRect.Top := 0;
APaperRc.PhysicalRect.Right := Round(PaperRect.right - PaperRect.left);
APaperRc.PhysicalRect.Bottom := Round(PaperRect.bottom - PaperRect.top);
APaperRc.WorkRect.Left := Round(-PaperRect.left);
APaperRc.WorkRect.Top := Round(-PaperRect.top);
APaperRc.WorkRect.Right := Round(PageRect.right - PageRect.left - PaperRect.left);
APaperRc.WorkRect.Bottom := Round(PageRect.bottom - PageRect.top - PaperRect.top);
Result := 1;
end;
function TCarbonPrinter.DoSetPrinter(aName: string): Integer;
var
S: TStringList;
P: PMPrinter;
begin
Result:=inherited DoSetPrinter(aName);
//IMPLEMENT ME
S := TStringList.Create;
BeginEnumPrinters(S);
try
Result := S.IndexOf(AName);
if Result >= 0 then
begin
//DebugLn('TCarbonPrinter.DoSetPrinter ' + AName + ' ' + DbgS(PrintSession) + ' ' + DbgS(Printers.Objects[Result]));
P := PMPrinter(CFArrayGetValueAtIndex(FPrinterArray, Result));
PMRetain(PMObject(P));
if OSError(PMSessionSetCurrentPMPrinter(PrintSession, P),
Self, 'DoSetPrinter', 'PMSessionSetCurrentPMPrinter') then
raise EPrinter.CreateFmt('The system is unable to select printer "%s"!', [AName]);
ValidatePageFormat;
ValidatePrintSettings;
end;
finally
EndEnumPrinters;
S.Free;
end;
end;
function TCarbonPrinter.DoGetCopies: Integer;
var
C: UInt32;
begin
Result:=inherited DoGetCopies;
//IMPLEMENT ME
Result := inherited DoGetCopies;
if OSError(PMGetCopies(PrintSettings, C), Self, 'DoGetCopies', 'PMGetCopies') then Exit;
Result := C;
end;
procedure TCarbonPrinter.DoSetCopies(aValue: Integer);
procedure TCarbonPrinter.DoSetCopies(AValue: Integer);
begin
inherited DoSetCopies(aValue);
//IMPLEMENT ME
inherited DoSetCopies(AValue);
OSError(PMSetCopies(PrintSettings, AValue, False), Self, 'DoSetCopies', 'PMSetCopies');
ValidatePrintSettings;
end;
function TCarbonPrinter.DoGetOrientation: TPrinterOrientation;
var
O: PMOrientation;
begin
Result:=inherited DoGetOrientation;
//IMPLEMENT ME
Result := inherited DoGetOrientation;
if OSError(PMGetOrientation(PageFormat, O), Self, 'DoGetOrientation', 'PMGetOrientation') then Exit;
case O of
kPMPortrait: Result := poPortrait;
kPMLandscape: Result := poLandscape;
kPMReversePortrait: Result := poReversePortrait;
kPMReverseLandscape: Result := poReverseLandscape;
end;
end;
procedure TCarbonPrinter.DoSetOrientation(aValue: TPrinterOrientation);
procedure TCarbonPrinter.DoSetOrientation(AValue: TPrinterOrientation);
var
O: PMOrientation;
begin
inherited DoSetOrientation(aValue);
//IMPLEMENT ME
case AValue of
poPortrait: O := kPMPortrait;
poLandscape: O := kPMLandscape;
poReversePortrait: O := kPMReversePortrait;
poReverseLandscape: O := kPMReverseLandscape;
end;
OSError(PMSetOrientation(PageFormat, O, kPMUnlocked), Self, 'DoSetOrientation', 'PMSetOrientation');
ValidatePageFormat;
end;
function TCarbonPrinter.GetPrinterType: TPrinterType;
begin
Result:=ptLocal;
//IMPLEMENT ME
Result := ptLocal;
if PMPrinterIsRemote(GetCurrentPrinter) then Result := ptNetwork
end;
function TCarbonPrinter.DoGetPrinterState: TPrinterState;
var
State: PMPrinterState;
begin
Result:=psNoDefine;
//IMPLEMENT ME
Result := psNoDefine;
if OSError(PMPrinterGetState(GetCurrentPrinter, State), Self, 'DoGetPrinterState', 'PMPrinterGetState') then Exit;
case State of
kPMPrinterIdle: Result := psReady;
kPMPrinterProcessing: Result := psPrinting;
kPMPrinterStopped: Result := psStopped;
end;
end;
function TCarbonPrinter.GetCanPrint: Boolean;
begin
//IMPLEMENT ME
Result := (DoGetPrinterState <> psStopped);
Result := (DoGetPrinterState <> psStopped);
end;
function TCarbonPrinter.GetCanRenderCopies: Boolean;
begin
Result := inherited GetCanRenderCopies;
//IMPLEMENT ME
Result := True;
end;
initialization
Printer:=TCarbonPrinter.Create;
Printer := TCarbonPrinter.Create;
finalization
FreeAndNil(Printer);

View File

@ -1,12 +1,47 @@
{%MainUnit ../osprinters.pas}
uses
Classes,SysUtils,Printers,LCLType;
FPCMacOSAll, Classes, SysUtils, Printers, LCLType, CarbonCanvas, CarbonPrinting;
type
{ TCarbonPrinterContext }
TCarbonPrinterContext = class(TCarbonDeviceContext)
protected
function GetSize: TPoint; override;
public
procedure Release;
procedure Reset; override;
end;
{ TCarbonPrinter }
TCarbonPrinter = class(TPrinter)
private
FPrintSession: PMPrintSession;
FPrintSettings: PMPrintSettings;
FPageFormat: PMPageFormat;
FBeginDocumentStatus: OSStatus;
FNewPageStatus: OSStatus;
FPrinterContext: TCarbonPrinterContext;
FPrinterArray: CFArrayRef;
FPaperArray: CFArrayRef;
procedure CreatePrintSession;
procedure CreatePrintSettings;
function GetCurrentPrinter: PMPrinter;
function CreatePageFormat(APaper: String): PMPageFormat;
function ValidatePageFormat: Boolean;
function ValidatePrintSettings: Boolean;
procedure BeginPage;
procedure EndPage;
procedure BeginEnumPrinters(Lst: TStrings);
procedure EndEnumPrinters;
procedure BeginEnumPapers(Lst: TStrings);
procedure EndEnumPapers;
protected
procedure DoBeginDoc; override;
procedure DoNewPage; override;
@ -35,16 +70,18 @@ type
function DoGetPrinterState: TPrinterState;override;
function GetCanPrint: Boolean;override;
function GetCanRenderCopies : Boolean;override;
function GetHandlePrinter : HDC;
procedure SetHandlePrinter(aValue : HDC);
procedure RawModeChanging; override;
public
procedure Validate;
public
constructor Create; override;
destructor Destroy; override;
function Write(const Buffer; Count:Integer; var Written: Integer): Boolean; override;
//Warning not portable functions here
//Warning it is a not potable property
property Handle : HDC read GetHandlePrinter write SetHandlePrinter;
// Warning not portable functions here
property PrintSession: PMPrintSession read FPrintSession;
property PrintSettings: PMPrintSettings read FPrintSettings;
property PageFormat: PMPageFormat read FPageFormat;
// Warning it is a not portable property
property Handle: TCarbonPrinterContext read FPrinterContext;
end;

View File

@ -0,0 +1,43 @@
unit CarbonPrinting;
{$mode macpas}
{$packenum 1}
{$macro on}
{$inline on}
{$CALLING MWPASCAL}
{$ALIGN MAC68K}
interface
uses
Classes, SysUtils, FPCMacOSAll;
// functions missing in FPCMacOSAll
type
PMPaper = ^SInt32; { an opaque 32-bit type }
PMPaperPtr = ^PMPaper; { when a var xx:PMPaper parameter can be nil, it is changed to xx: PMPaperPtr }
PMServer = ^SInt32; { an opaque 32-bit type }
function PMPaperGetName(paper: PMPaper; var paperName: CFStringRef): OSStatus; external name '_PMPaperGetName';
function PMServerCreatePrinterList(server: PMServer; var printerList: CFArrayRef): OSStatus; external name '_PMServerCreatePrinterList';
function PMPrinterGetName(printer: PMPrinter): CFStringRef; external name '_PMPrinterGetName';
function PMPrinterGetState(printer: PMPrinter; var state: PMPrinterState): OSStatus; external name '_PMPrinterGetState';
function PMPrinterIsDefault(printer: PMPrinter): Boolean; external name '_PMPrinterIsDefault';
function PMPrinterIsRemote(printer: PMPrinter): Boolean; external name '_PMPrinterIsRemote';
function PMPrinterGetPaperList(printer: PMPrinter; var paperList: CFArrayRef): OSStatus; external name '_PMPrinterGetPaperList';
function PMCreatePageFormatWithPMPaper(var pageFormat: PMPageFormat; paper: PMPaper): OSStatus; external name '_PMCreatePageFormatWithPMPaper';
function PMGetPageFormatPaper(pageFormat: PMPageFormat; var paper: PMPaper): OSStatus; external name '_PMGetPageFormatPaper';
function PMSessionBeginCGDocument(printSession: PMPrintSession; printSettings: PMPrintSettings;
pageFormat: PMPageFormat): OSStatus; external name '_PMSessionBeginCGDocument';
function PMSessionSetCurrentPMPrinter(session: PMPrintSession; printer: PMPrinter): OSStatus; external name '_PMSessionSetCurrentPMPrinter';
function PMSessionGetCGGraphicsContext(session: PMPrintSession; var context: CGContextRef): OSStatus; external name '_PMSessionGetCGGraphicsContext';
implementation
end.

View File

@ -0,0 +1,97 @@
{%MainUnit ../printersdlgs.pp}
const
SExecute = 'Execute';
{ TPageSetupDialog }
function TPageSetupDialog.Execute: Boolean;
var
CarbonPrinter: TCarbonPrinter;
begin
Result := False;
// TODO: set and get paper margins, title
if not Assigned(Printer) then Exit;
if Printer.Printers.Count <= 0 then Exit;
CarbonPrinter := Printer as TCarbonPrinter;
if OSError(PMSessionPageSetupDialog(CarbonPrinter.PrintSession,
CarbonPrinter.PageFormat, Result),
Self, SExecute, 'PMSessionPageSetupDialog') then Exit;
CarbonPrinter.Validate;
end;
{ TPrinterSetupDialog }
function TPrinterSetupDialog.Execute: Boolean;
begin
Result := False;
if not Assigned(Printer) then Exit;
if Printer.Printers.Count <= 0 then Exit;
raise Printers.EPrinter.Create('TPrinterSetupDialog is not supported in Carbon!');
end;
{ TPrintDialog }
function TPrintDialog.Execute: Boolean;
var
CarbonPrinter: TCarbonPrinter;
DialogSettings: PMPrintSettings;
V: UInt32;
begin
Result := False;
// TODO: Options, Title
if not Assigned(Printer) then Exit;
if Printer.Printers.Count <= 0 then Exit;
CarbonPrinter := Printer as TCarbonPrinter;
if OSError(PMCreatePrintSettings(DialogSettings),
Self, SExecute, 'PMCreatePrintSettings') then Exit;
try
if OSError(PMCopyPrintSettings(CarbonPrinter.PrintSettings, DialogSettings),
Self, SExecute, 'PMCopyPrintSettings') then Exit;
OSError(PMSetCollate(DialogSettings, Collate), Self, SExecute, 'PMSetCollate');
OSError(PMSetCopies(DialogSettings, Copies, False), Self, SExecute, 'PMSetCopies');
OSError(PMSetPageRange(DialogSettings, MinPage, MaxPage),
Self, SExecute, 'PMSetPageRange');
OSError(PMSetFirstPage(DialogSettings, FromPage, False), Self, SExecute, 'PMSetFirstPage');
OSError(PMSetLastPage(DialogSettings, ToPage, False), Self, SExecute, 'PMSetLastPage');
if OSError(PMSessionPrintDialog(CarbonPrinter.PrintSession, CarbonPrinter.PrintSettings, CarbonPrinter.PageFormat, Result),
Self, SExecute, 'PMSessionPrintDialog') then Exit;
if Result then
begin
PrintRange := prSelection;
OSError(PMGetCollate(DialogSettings, Collate), Self, SExecute, 'PMGetCollate');
V := Copies;
OSError(PMGetCopies(DialogSettings, V), Self, SExecute, 'PMGetCopies');
Copies := V;
V := FromPage;
OSError(PMGetFirstPage(DialogSettings, V), Self, SExecute, 'PMGetFirstPage');
FromPage := V;
V := ToPage;
OSError(PMGetLastPage(DialogSettings, V), Self, SExecute, 'PMGetLastPage');
ToPage := V;
if OSError(PMCopyPrintSettings(DialogSettings, CarbonPrinter.PrintSettings),
Self, SExecute, 'PMCopyPrintSettings') then Exit;
end;
finally
PMRelease(PMObject(DialogSettings));
end;
end;

View File

@ -37,8 +37,11 @@ interface
{$IFDEF UNIX}
{$IFDEF LCLCarbon}
{.$I carbonprinters_h.inc}
{$I cupsprinters_h.inc}
{$IFNDEF NativePrint}
{$I cupsprinters_h.inc}
{$ELSE}
{$I carbonprinters_h.inc}
{$ENDIF}
{$ELSE}
{$I cupsprinters_h.inc}
{$ENDIF}
@ -52,8 +55,11 @@ implementation
{$IFDEF UNIX}
{$IFDEF LCLCarbon}
{.$I carbonprinters.inc}
{$I cupsprinters.inc}
{$IFNDEF NativePrint}
{$I cupsprinters.inc}
{$ELSE}
{$I carbonprinters.inc}
{$ENDIF}
{$ELSE}
{$I cupsprinters.inc}
{$ENDIF}

View File

@ -1,6 +1,6 @@
<?xml version="1.0"?>
<CONFIG>
<Package Version="2">
<Package Version="3">
<Name Value="Printer4Lazarus"/>
<Author Value="Olivier Guilbaud"/>
<CompilerOptions>
@ -9,12 +9,14 @@
<IncludeFiles Value="unix/;win32/;carbon/"/>
<OtherUnitFiles Value="unix/;win32/;carbon/"/>
<UnitOutputDirectory Value="lib/$(TargetCPU)-$(TargetOS)"/>
<LCLWidgetType Value="carbon"/>
</SearchPaths>
<CodeGeneration>
<Generate Value="Faster"/>
</CodeGeneration>
<Other>
<CustomOptions Value="-dUseCache
"/>
<CompilerPath Value="$(CompPath)"/>
<CreateMakefileOnBuild Value="True"/>
@ -25,7 +27,7 @@
<License Value="LGPL
"/>
<Version Minor="5"/>
<Files Count="27">
<Files Count="28">
<Item1>
<Filename Value="printersdlgs.lrs"/>
<Type Value="LRS"/>
@ -128,27 +130,31 @@
<Type Value="Include"/>
</Item24>
<Item25>
<Filename Value="unix/minicupslibc.pas"/>
<AddToUsesPkgSection Value="False"/>
<UnitName Value="MiniCUPSLibc"/>
<Filename Value="carbon/carbonprinters.inc"/>
<Type Value="Include"/>
</Item25>
<Item26>
<Filename Value="carbon/carbonprinters.inc"/>
<Filename Value="carbon/carbonprinters_h.inc"/>
<Type Value="Include"/>
</Item26>
<Item27>
<Filename Value="carbon/carbonprinters_h.inc"/>
<Filename Value="carbon/carbonprndialogs.inc"/>
<Type Value="Include"/>
</Item27>
<Item28>
<Filename Value="carbon/carbonprinting.pas"/>
<AddToUsesPkgSection Value="False"/>
<UnitName Value="CarbonPrinting"/>
</Item28>
</Files>
<Type Value="RunAndDesignTime"/>
<RequiredPkgs Count="2">
<Item1>
<PackageName Value="LCL"/>
</Item1>
<Item2>
<PackageName Value="FCL"/>
<MinVersion Major="1" Valid="True"/>
</Item1>
<Item2>
<PackageName Value="LCL"/>
</Item2>
</RequiredPkgs>
<UsageOptions>

View File

@ -74,19 +74,32 @@ procedure Register;
implementation
{$IFDEF UNIX}
{$IFDEF LCLCarbon}
{$IFDEF LCLCarbon}
{$IFNDEF NativePrint}
// add units as needed for carbon, for the moment use cups ones.
uses Controls, udlgSelectPrinter, udlgPropertiesPrinter, FileUtil;
{$I cupsprndialogs.inc}
{$ELSE}
{$ELSE}
uses Controls, CarbonProc, FPCMacOSAll;
{$I carbonprndialogs.inc}
{$ENDIF}
{$ELSE}
uses Controls, udlgSelectPrinter, udlgPropertiesPrinter, FileUtil;
{$I cupsprndialogs.inc}
{$ENDIF}
{$ENDIF}
{$ENDIF}
{$IFDEF MSWindows}
uses Windows, WinUtilPrn, InterfaceBase, LCLIntf, LCLType, WinVer;
{$I winprndialogs.inc}
{$ENDIF}
constructor TPageSetupDialog.Create(TheOwner: TComponent);

View File

@ -1,15 +1,15 @@
Printer4Lazarus package
=======================
This package add some components.
TPrinterSetupDialog : for update properties of selected printer
TPrintDialog : for select and/or update an printer before printing
TPageSetupDialog : to select margins (currently only under Windows)
This package adds some components.
TPrinterSetupDialog - for update properties of selected printer
TPrintDialog - for select and/or update an printer before printing
TPageSetupDialog - to select margins (currently only under Windows)
Win32 :
Native implementation
Win32:
Native implementation
Notes:
Notes:
1. TPrinter.CanRenderCopies return information if printer driver is able to print more then one copy at once.
Not all printers drivers support that feature (n that case programmer should print document requested times)
@ -23,10 +23,16 @@ Notes:
Linux :
Linux and Mac OS X (gtk):
Yous must install CUPS and libcups v1.1.19 or more.
FAQ :
Q:If I use Printers unit, the call of printer object generate an exception "Access Violation"
R:Add in uses clause of your project, osPrinters
Mac OS X (Carbon):
Uses CUPS by default. You can use native implementation by adding compiler switch -dNativePrint.
Notes: TPrinterSetupDialog is not supported.
FAQ:
Q: If I use Printers unit, the call of printer object generate an exception "Access Violation".
A: Add in uses clause of your project, osPrinters.