mirror of
https://gitlab.com/freepascal.org/lazarus/lazarus.git
synced 2025-04-18 07:29:30 +02:00
Printers4Lazarus: initial implementation of native Carbon printing, use -dNativePrint to try it
git-svn-id: trunk@13104 -
This commit is contained in:
parent
7a6627d167
commit
032af9a4ec
2
.gitattributes
vendored
2
.gitattributes
vendored
@ -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
|
||||
|
@ -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);
|
||||
|
@ -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;
|
||||
|
||||
|
||||
|
43
components/printers/carbon/carbonprinting.pas
Normal file
43
components/printers/carbon/carbonprinting.pas
Normal 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.
|
||||
|
97
components/printers/carbon/carbonprndialogs.inc
Normal file
97
components/printers/carbon/carbonprndialogs.inc
Normal 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;
|
||||
|
@ -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}
|
||||
|
@ -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>
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user