lazarus/components/printers/cocoa/cocoaprinters.inc

977 lines
25 KiB
PHP

{%MainUnit ../osprinters.pas}
{**************************************************************
Implementation for carbonprinter
***************************************************************}
uses InterfaceBase, LCLIntf, LCLProc, CocoaPrnDelegate;
const
CleanPMRect: PMRect = (top: 0; left: 0; bottom: 0; right: 0);
//CleanPMOrientation: PMOrientation = 0;
{ TCocoaPrinterCanvas }
procedure ReleaseMemoryStream(info: UnivPtr; data: UnivPtr; size: size_t); mwpascal;
begin
TMemoryStream(info).free;
end;
function TCocoaPrinterCanvas.GetCGContext: CGContextRef;
begin
result := TCocoaContext(Handle).CGContext;
end;
procedure TCocoaPrinterCanvas.DoEllipse(const Bounds: TRect);
var
R: CGRect;
begin
R := CGRectMake(bounds.left, bounds.top, bounds.Width, bounds.Height);
CGContextFillEllipseInRect(CGContext, R);
end;
procedure TCocoaPrinterCanvas.DoEllipseFill(const Bounds: TRect);
var
R: CGRect;
begin
R := CGRectMake(bounds.left, bounds.top, bounds.Width, bounds.Height);
CGContextStrokeEllipseInRect(CGContext, R);
end;
procedure TCocoaPrinterCanvas.DoEllipseAndFill(const Bounds: TRect);
var
R: CGRect;
begin
R := CGRectMake(bounds.left, bounds.top, bounds.Width, bounds.Height);
CGContextFillEllipseInRect(CGContext, R);
CGContextStrokeEllipseInRect(CGContext, R);
end;
{ TPrinterEnumerator }
constructor TPrinterEnumerator.Create(objType: TObjType; aPrinterRef: PMPrinter);
begin
inherited create;
fArray := nil;
fObjType := objType;
fIndex := -1;
fPrinterRef := aPrinterRef;
end;
destructor TPrinterEnumerator.Destroy;
begin
if (fObjType=otPrinters) and (fArray<>nil) then
CFRelease(fArray);
inherited destroy;
end;
function TPrinterEnumerator.MoveNext: boolean;
var
res: OSStatus;
begin
if fIndex<0 then
begin
case fObjType of
otPrinters:
res := PMServerCreatePrinterList(kPMServerLocal, fArray);
otPapers:
res := PMPrinterGetPaperList(fPrinterRef, fArray);
end;
result := (res=noErr) and (fArray<>nil);
if not result then
exit;
end;
inc(fIndex);
result := fIndex<CFArrayGetCount(fArray);
if result then
fCurrent := CFArrayGetValueAtIndex(fArray, fIndex);
end;
function TPrinterEnumerator.GetEnumerator: TPrinterEnumerator;
begin
result := self;
end;
{ TCocoaPrinterView }
procedure TCocoaPrinterView.drawRect(dirtyRect: NSRect);
var
Context: NSGraphicsContext;
begin
Context := NSGraphicsContext.currentContext;
CGContextDrawPDFDocument(context.lclCGContext, CGRect(dirtyRect), doc, pageNum);
end;
// Return the number of pages available for printing
function TCocoaPrinterView.knowsPageRange(range: NSRangePointer): LCLObjCBoolean;
begin
range^.location := 1;
range^.length := CGPDFDocumentGetNumberOfPages(doc);
Result := True;
end;
function TCocoaPrinterView.rectForPage(page: NSInteger): NSRect;
var
aPage: CGPDFPageRef;
begin
pageNum := page;
aPage := CGPDFDocumentGetPage(Doc, pageNum);
result := NSRect(CGPDFPageGetBoxRect(aPage, kCGPDFMediaBox));
self.setBounds(result);
end;
function TCocoaPrinterView.isFlipped: LCLObjCBoolean;
begin
Result := true;
end;
{ TCocoaPrinter }
procedure TCocoaPrinter.ResetPapersList(aPrinter: PMPrinter);
var
aPaper: PMPaper;
aName: CFStringRef;
res: OSStatus;
pageFormat: PMPageFormat;
paperR, pageR: PMRect;
i: Integer;
aInfo: NSPrintInfo;
validationResult: Boolean;
pmOr: PMOrientation;
kx, ky: Double;
begin
kx := XDPI/72;
ky := YDPI/72;
aInfo := NSPrintInfo.sharedPrintInfo;
if aInfo.orientation=NSPortraitOrientation then
pmOr := kPMPortrait
else
pmOr := kPMLandscape;
SetLength(fPapersList, 0);
for aPaper in self.GetPMPrinterEnumerator(otPapers, aPrinter) do
begin
aName := nil;
pageFormat := nil;
res := PMPaperCreateLocalizedName(aPaper, aPrinter, aName);
if res<>noErr then continue;
if res<>noErr then continue;
res := PMCreatePageFormatWithPMPaper(pageFormat, aPaper);
if res<>noErr then continue;
res := PMSetOrientation(pageFormat, pmOr, false);
if res<>noErr then continue;
res := PMSessionValidatePageFormat(aInfo.PMPrintSession, pageFormat, @validationResult);
if res<>noErr then continue;
paperR:=CleanPMRect;
res := PMGetAdjustedPaperRect(pageFormat, paperR);
if res<>noErr then begin PMRelease(pageFormat); continue; end;
pageR:=CleanPMRect;
res := PMGetAdjustedPageRect(pageFormat, pageR);
PMRelease(pageFormat);
if res<>noErr then continue;
i:= Length(fPapersList);
SetLength(fPapersList, i+1);
with fPapersList[i] do
begin
PaperName := CFStringToString(aName);
CFRelease(aName);
PaperRect.PhysicalRect.Left := 0;
PaperRect.PhysicalRect.Top := 0;
PaperRect.PhysicalRect.Right := Round((paperR.right - paperR.left)*kx);
PaperRect.PhysicalRect.Bottom := Round((paperR.bottom - paperR.top)*ky);
PaperRect.WorkRect.Left := Round(-paperR.left*kx);
PaperRect.WorkRect.Top := Round(-paperR.top*ky);
PaperRect.WorkRect.Right := Round((pageR.right - pageR.left - paperR.left)*kx);
PaperRect.WorkRect.Bottom := Round((pageR.bottom - pageR.top - paperR.top)*ky);
end;
end;
end;
function TCocoaPrinter.GetDefaultPaperFromPPDFile: string;
var
pInfo: NSPrintInfo;
aStatus: NSPrinterTableStatus;
aValue: NSString;
begin
result := '';
pInfo := NSPrintInfo.sharedPrintInfo;
aStatus := pInfo.printer.statusForTable(NSSTR('PPD'));
if aStatus=NSPrinterTableOK then
begin
// it is a shame that the NSPrinter functions available for querying
// PPD key and values are deprecated (except by StatusForTable)
// if using deprecated functions hurt too much we can always parse the
// ppd file directly as done in the the carbon printer.
aValue := pInfo.printer.stringForKey_inTable(NSSTR('DefaultPageSize'), NSSTR('PPD'));
if aValue<>nil then
result := aValue.UTF8String;
end;
end;
function TCocoaPrinter.GetCurrentPrinterName: string;
var
aInfo: NSPrintInfo;
begin
aInfo := NSPrintInfo.sharedPrintInfo;
result := aInfo.printer.name.UTF8String;
end;
function TCocoaPrinter.GetCurrentPrinter: PMPrinter;
var
pInfo: NSPrintInfo;
begin
Result := nil;
pInfo := NSPrintInfo.sharedPrintInfo;
if PMSessionGetCurrentPrinter(pInfo.PMPrintSession, Result) <> noErr then Exit;
end;
function TCocoaPrinter.GetPMPrinterEnumerator(objType: TObjType;
printerRef: PMPrinter): TPrinterEnumerator;
begin
result := TPrinterEnumerator.create(objType, printerRef);
end;
procedure TCocoaPrinter.FindDefaultPrinter;
var
aPrinter: PMPrinter;
begin
FDefaultPrinter := '';
for aPrinter in GetPMPrinterEnumerator(otPrinters) do
begin
if PMPrinterIsDefault(aPrinter) then
begin
FDefaultPrinter := CFStringToStr(PMPrinterGetName(aPrinter));
break;
end;
end;
end;
constructor TCocoaPrinter.Create;
begin
inherited Create;
CanvasClass := TCocoaPrinterCanvas;
FindDefaultPrinter;
UpdatePrinter;
Validate;
end;
procedure TCocoaPrinter.DoDestroy;
begin
inherited DoDestroy;
end;
function TCocoaPrinter.Write(const Buffer; Count: Integer; out Written: Integer): Boolean;
begin
Result := False;
CheckRawMode(True);
Written := FStream.Write(buffer, count);
result := (Written=Count);
end;
procedure TCocoaPrinter.CheckPrinterList;
var
orgList,curList: TStringList;
begin
orgList := TStringList.create;
curList := TStringList.create;
try
orgList.Assign(Printers);
DoEnumPrinters(curList);
orgList.Sort;
curList.Sort;
if not curList.Equals(orgList) then
Refresh;
finally
curList.Free;
orgList.Free;
end;
end;
procedure TCocoaPrinter.RawModeChanging;
begin
//
end;
procedure TCocoaPrinter.Validate;
var
P: String;
aPrinter: PMPrinter;
aPaper: PMPaper;
aPaperName: CFStringRef;
papersList: TStrings;
found: Boolean;
begin
aPrinter := GetCurrentPrinter;
ResetPapersList(aPrinter);
PaperSize.SupportedPapers.Clear; // refill on next query, ie. next line
papersList := PaperSize.SupportedPapers;
// if target paper is not supported, use the default
P := DoGetPaperName();
if papersList.IndexOf(P) = -1 then
begin
P := DoGetDefaultPaperName();
if papersList.IndexOf(P) < 0 then
begin
// neither the current paper or the default one exists in the supported
// list of papers, instead of randomly choose one, let's try a bit harder
// as some printer ppd files have a hint about the default paper.
found := false;
P := GetDefaultPaperFromPPDFile;
if p<>'' then
begin
for aPaper in GetPMPrinterEnumerator(otPapers, aPrinter) do
begin
aPaperName := nil;
PMPaperGetPPDPaperName(aPaper, aPaperName);
if (aPapername<>nil) and (CFStringToString(aPaperName)=P) then
begin
aPaperName := nil;
PMPaperCreateLocalizedName(aPaper, aPrinter, aPapername);
if aPaperName<>nil then
begin
P := CFStringToString(aPaperName);
CFRelease(aPapername);
found := (papersList.IndexOf(P)>=0);
break;
end;
end;
end;
end;
if not found then
p := papersList[0];
end;
DoSetPaperName(P);
end;
end;
procedure TCocoaPrinter.UpdatePrinter;
var
s: string;
pInfo: NSPrintInfo;
begin
pInfo := NSPrintInfo.sharedPrintInfo;
s := pInfo.printer.name.UTF8String;
if trim(s) = '' then // Observed if Default printer set to "Use last printer", and no printing done
s := '*'; // so select lcl default
SetPrinter(s);
end;
function TCocoaPrinter.GetOutputResolution: PMResolution;
var
pInfo: NSPrintInfo;
prn : PMPrinter;
cnt : UInt32;
i : UInt32;
rs : PMResolution;
begin
// JRA: This method should return the user desired output resolution, and not the higher
// resolution that the printer can handle. In fact, it seems that the old method of
// setting up some output resolution is now deprecated in cocoa. Drawing at
// "high resolution" should be now made through setting up some transformation
// matrix. That is a TODO. At the moment, some printing, even if it is a lower
// lower resolution, is better than no printing at all.
{
Result.vRes := 0;
Result.hRes := 0;
cnt := 0;
pInfo := NSPrintInfo.sharedPrintInfo;
prn := GetCurrentPrinter();
// todo: the code has been changed to mirror Carbon implementation
// for some drivers PMPrinterGetOutputResolution() returns failure at all times
// (even if printer dialog has been called).
// Enumeration of resolution doesn't return all possible values either.
// (i.e. Brother MFC 7860DW only gives 300x300 resolution
// while it actually supports 300, 600 and HQ1200 (2400x600) dpis)
// CUPS properties do indicate the actual resoltuion, BUT there's no standard
// way of reading the resolution.
// (i.e. the same Brother printer reports via "lpoptions -l":
// BRResolution/Resolution: 300dpi *600dpi 2400x600dpi)
//
if (PMPrinterGetOutputResolution(prn, pInfo.PMPrintSettings, rs{%H-}) = noErr) then
Result := rs
else if PMPrinterGetPrinterResolutionCount(prn, cnt) = noErr then
begin
for i:=1 to cnt do
begin
if (PMPrinterGetIndexedPrinterResolution(prn, i, rs) = noErr)
and ((rs.vRes > Result.vRes) or (rs.hRes > Result.hRes)) then
Result := rs;
end;
end;
if (Result.vRes = 0) or (Result.hRes = 0) then
begin
}
Result.vRes := 72;
Result.hRes := 72;
//end;
end;
function TCocoaPrinter.GetXDPI: Integer;
var
dpi: PMResolution;
begin
dpi := GetOutputResolution;
result := round(dpi.hRes);
end;
function TCocoaPrinter.GetYDPI: Integer;
var
dpi: PMResolution;
begin
dpi := GetOutputResolution;
result := round(dpi.hRes);
end;
{$define ToPrinter}
procedure TCocoaPrinter.DoBeginDoc;
var
//pInfo: NSPrintInfo;
consumer: CGDataConsumerRef;
gr: NSGraphicsContext;
//path: CStringPtr;
//url: CFUrlRef;
R: TRect;
begin
fDocStarted := true;
if RawMode then
begin
fStream := TMemoryStream.create;
end else
begin
// TODO: margins ???
//
// Initially NSPrintInfo do not carry the printer real margins
// (from the imageable area) set up in the printer ppd file but some
// standard defined (undocumented but I guess they corresponds
// to the "Any Printer" printer). It is even documented somewhere
// that in order to use the real printer margins one have to
// run the PageLayout dialog and choose the real printer instead
// of the "Any Printer" and this way the margins will match the
// real printer ones. Check later this stuff...
//
// * We don't use margins in the calc of the mediabox because
// Apple doesn't implement a custom margins dialog and ...
// * In order to implement custom margins we have to probably
// add some accessory panel, but as we currently don't do that
// it makes no sense to use them.
//
//pInfo := NSPrintInfo.sharedPrintInfo;
//pInfo.setLeftMargin(0);
//pInfo.setTopMargin(0);
//pInfo.setRightMargin(0);
//pInfo.setBottomMargin(0);
R := PaperSize.PaperRect.WorkRect;
pdfMediaBox := CGRectMake(0, 0, r.Width, r.Height);
{$ifdef ToPrinter}
if pdfData<>nil then
CFRelease(pdfData);
pdfData := CFDataCreateMutable(nil, 0);
consumer := CGDataConsumerCreateWithCFData(pdfData);
{$else}
path := 'salida.pdf';
url := CFURLCreateFromFileSystemRepresentation(nil, path, length(path), false);
consumer := CGDataConsumerCreateWithURL(url);
CFRelease(url);
{$endif}
pdfContext := CGPDFContextCreate(consumer, pdfMediabox, nil);
CGDataConsumerRelease(consumer);
gr := NSGraphicsContext.graphicsContextWithGraphicsPort_flipped(pdfContext, false);
FPrinterContext := TCocoaContext.Create(gr);
end;
end;
procedure TCocoaPrinter.DoBeginPage;
var
mediaBox: CGRect;
R: TRect;
rgn: TCocoaRegion;
begin
if RawMode then
exit;
R := PaperSize.PaperRect.WorkRect;
mediaBox := CGRectMake(0, 0, r.Width, r.Height);
//CGPDFContextBeginPage(pdfContext, nil);
CGContextBeginPage(pdfContext, mediabox);
CGContextSaveGState(pdfContext);
if Assigned(Canvas) then
Canvas.Handle := HDC(FPrinterContext);
rgn := TCocoaRegion.Create(0, 0, r.Width, r.height);
FPrinterContext.SetClipRegion(Rgn, cc_Copy);
rgn.Free;
end;
procedure TCocoaPrinter.DoEndPage;
procedure ResetCanvasHandle;
begin
if Assigned(Canvas) then
Canvas.Handle := HDC(0);
end;
begin
if RawMode then
exit;
if not fDocStarted then
begin
ResetcanvasHandle;
exit;
end;
if Aborted then
begin
ResetcanvasHandle;
exit;
end;
CGContextRestoreGState(pdfContext);
CGContextEndPage(pdfContext);
ResetCanvasHandle;
end;
// starts a raw mode print job
procedure TCocoaPrinter.StartRawModePrintJob(Sender: TObject);
var
pInfo: NSPrintInfo;
printDestination: PMDestinationType;
aPrinter: PMPrinter;
mimeType: CFStringRef;
mimeTypes: CFArrayRef;
arrayCount: CFIndex;
provider: CGDataProviderRef;
status: OSStatus;
procedure Error(s:string);
begin
//DebugLn(s);
try
fStream.free;
except
// DebugLn
end;
fStream := nil;
raise Exception.Create(s);
end;
begin
pInfo := NSPrintInfo.sharedPrintInfo;
printDestination := kPMDestinationInvalid;
if PMSessionGetDestinationType(pInfo.PMPrintSession, pInfo.PMPrintSettings, printDestination)=noErr then
begin
if printDestination=kPMDestinationPrinter then
begin
aPrinter := GetCurrentPrinter;
if aPrinter<>nil then
begin
status := PMPrinterGetMimeTypes(aPrinter, pInfo.PMPrintSettings, mimeTypes);
if (status=noErr) and (mimeTypes<>nil) then
begin
mimeType := CFSTR('application/vnd.cups-raw');
arrayCount := CFArrayGetCount(mimeTypes);
if CFArrayContainsValue(mimeTypes, CFRangeMake(0, arrayCount), mimeType) then
begin
provider := CGDataProviderCreateWithData(fStream, fStream.Memory, fStream.Size, @ReleaseMemoryStream);
status := PMPrinterPrintWithProvider(aPrinter, pInfo.PMPrintSettings, pInfo.PMPageFormat, mimeType, provider);
CGDataProviderRelease(provider);
if status<>noErr then
Error('Error '+IntToStr(status)+'while raw printing')
else
fStream := nil;
end else
Error('Printer do not support raw printing');
end else
Error('Error while getting supported mime types');
end else
Error('Error, couldn''t get the current printer');
end else
Error('Error, destination is not printer');
end else
Error('Error on getting DestinationType');
end;
procedure TCocoaPrinter.DoEndDoc(aAborted: Boolean);
var
preview: TCocoaPrinterView;
op: NSPrintOperation;
provider: CGDataProviderRef;
pInfo: NSPrintInfo;
begin
if not fDocStarted then
exit;
if aAborted then
begin
// TODO: check leaks ...
end;
try
pInfo := NSPrintInfo.SharedPrintInfo;
if not RawMode then
begin
FPrinterContext.Free;
FPrinterContext := nil;
CGPDFContextClose(pdfContext);
//path := 'salida2.pdf';
//url := CFURLCreateFromFileSystemRepresentation(nil, path, length(path), false);
//if not CFURLWriteDataAndPropertiesToResource(url, pdfData, nil, err) then
// WriteLn('Error al guardar pdfdata: ', err)
//else
// WriteLn('pdf data guardado exitosamente');
preview := TCocoaPrinterView.alloc.initWithFrame(NSRect(pdfMediabox));
provider := CGDataProviderCreateWithCFData(pdfData);
preview.Doc := CGPDFDocumentCreateWithProvider(provider);
CGDataProviderRelease(provider);
end;
// here for
// rawmode: we have a fStream with data ready to print
// not rawmode: we have a view that can render pdf content
//
// check if we want to print directly or through a print dialog.
if printDelegate<>nil then
begin
printDelegate.sender := self;
printDelegate.OnStartJob := nil;
printDelegate.renderView := nil;
if RawMode then
printDelegate.OnStartJob := @StartRawModePrintJob
else
printDelegate.renderView := preview;
try
printDelegate.RunPrintJob;
finally
printDelegate := nil;
end;
end else
begin
if RawMode then
StartRawModePrintJob(self)
else
begin
// run print operation without print dialog
op := NSPrintOperation.printOperationWithView_printInfo(preview, pInfo);
op.setShowsPrintPanel(false);
op.runOperation;
end;
end;
finally
fDocStarted := false;
end;
end;
procedure TCocoaPrinter.DoAbort;
begin
inherited DoAbort;
//OSError(PMSessionSetError(PrintSession, kPMCancel), Self, 'DoAbort', 'PMSessionSetError');
end;
//Enum all defined printers. First printer it's default
procedure TCocoaPrinter.DoEnumPrinters(Lst: TStrings);
var
aName: String;
aPrinter: PMPrinter;
begin
Lst.Clear;
for aprinter in GetPMPrinterEnumerator(otPrinters) do
begin
aName := CFStringToStr(PMPrinterGetName(aPrinter));
if aName=FDefaultPrinter then begin
Lst.Insert(0, aName);
end
else
Lst.Add(aName);
end;
end;
procedure TCocoaPrinter.DoResetPrintersList;
begin
inherited DoResetPrintersList;
end;
// We need to use Core Printing here, see:
// http://lists.apple.com/archives/cocoa-dev/2005/Nov/msg01227.html
// See Also "Using Cocoa and Core Printing Together"
// https://developer.apple.com/library/mac/technotes/tn2248/_index.html
procedure TCocoaPrinter.DoEnumPapers(Lst: TStrings);
var
aPaper: PMPaper;
CFString: CFStringRef;
aPrinter: PMPrinter;
locName: string;
begin
aPrinter := GetCurrentPrinter;
for aPaper in GetPMPrinterEnumerator(otPapers, aPrinter) do
begin
CFString := nil;
PMPaperCreateLocalizedName(aPaper, aPrinter, CFString);
if CFString<>nil then
begin
locName := CFStringToStr(CFString);
CFRelease(CFString);
CFString := nil;
Lst.Add(locName);
end;
end;
end;
function TCocoaPrinter.DoGetPaperName(): string;
var
pInfo: NSPrintInfo;
begin
pInfo := NSPrintInfo.sharedPrintInfo;
result := NSStringToString(pInfo.localizedPaperName);
end;
function TCocoaPrinter.DoGetDefaultPaperName: string;
var
pageFormat: PMPageFormat = nil;
pInfo: NSPrintInfo;
aPaper: PMPaper = nil;
aPapername: CFStringRef = nil;
begin
Result := '';
pInfo := NSPrintInfo.sharedPrintInfo;
if PMCreatePageFormat(pageFormat) <> noErr then exit;
try
if PMSessionDefaultPageFormat(pInfo.PMPrintSession, pageFormat) <> noErr then exit;
if PMGetPageFormatPaper(pageFormat, aPaper) <> noErr then exit;
if PMPaperCreateLocalizedName(aPaper, GetCurrentPrinter, aPapername) <> noErr then exit;
result := CFStringToString(aPapername);
finally
PMRelease(pageFormat);
end;
end;
procedure TCocoaPrinter.DoSetPaperName(aName: string);
var
anOrientation: TPrinterOrientation;
aPrinter: PMPrinter;
aPaper: PMPaper;
orgFormat: PMPageFormat;
pageFormat: PMPageFormat = nil;
aPapername: CFStringRef;
pInfo: NSPrintInfo;
curName: String;
begin
pInfo := NSPrintInfo.sharedPrintInfo;
anOrientation := DoGetOrientation();
aPrinter := GetCurrentPrinter;
for aPaper in Self.GetPMPrinterEnumerator(otPapers, aPrinter) do
begin
aPapername := nil;
PMPaperCreateLocalizedName(aPaper, aPrinter, aPaperName);
if aPapername<>nil then
begin
curName := CFStringToString(aPapername);
CFRelease(aPapername);
if curName=aName then
begin
PMCreatePageFormatWithPMPaper(pageFormat, aPaper);
orgFormat := pInfo.PMPageFormat;
PMCopyPageFormat(pageFormat, orgFormat);
pInfo.updateFromPMPageFormat;
PMRelease(pageFormat);
DoSetOrientation(anOrientation);
break;
end;
end;
end;
end;
function TCocoaPrinter.DoGetPaperRect(aName: string; var aPaperRc: TPaperRect
): Integer;
var
i: Integer;
begin
Result := -1;
for i:=0 to Length(fPapersList)-1 do
begin
if aName=fPapersList[i].PaperName then
begin
aPaperRc := fPapersList[i].PaperRect;
result := i;
break;
end;
end;
end;
function TCocoaPrinter.DoSetPrinter(aName: string): Integer;
var
aPrinter: PMPrinter;
curName: String;
pInfo: NSPrintInfo;
begin
result := -1;
for aPrinter in Self.GetPMPrinterEnumerator(otPrinters) do
begin
curName := CFStringToStr(PMPrinterGetName(aPrinter));
if curName=aName then
begin
result := Printers.IndexOf(aName);
//
pInfo := NSPrintInfo.sharedPrintInfo;
PMSessionSetCurrentPMPrinter( pInfo.PMPrintSession, aPrinter);
ResetPapersList(aPrinter);
break;
end;
end;
end;
function TCocoaPrinter.DoGetCopies: Integer;
var
NumCopies: UInt32;
pInfo: NSPrintInfo;
begin
Result := 1;
NumCopies := 0;
pInfo := NSPrintInfo.sharedPrintInfo;
if PMGetCopies(pInfo.PMPrintSettings, NumCopies) <> noErr then Exit;
Result := NumCopies;
end;
procedure TCocoaPrinter.DoSetCopies(aValue: Integer);
var
pInfo: NSPrintInfo;
begin
pInfo := NSPrintInfo.sharedPrintInfo;
if PMSetCopies(pInfo.PMPrintSettings, AValue, False) <> noErr then
Exit;
pInfo.updateFromPMPrintSettings();
end;
function TCocoaPrinter.DoGetOrientation: TPrinterOrientation;
var
info: NSPrintInfo;
begin
info := NSPrintInfo.sharedPrintInfo;
if info.orientation=NSPortraitOrientation then
result := poPortrait
else
result := poLandscape;
end;
procedure TCocoaPrinter.DoSetOrientation(aValue: TPrinterOrientation);
var
info: NSPrintInfo;
oldValue: NSPrintingOrientation;
begin
info := NSPrintInfo.sharedPrintInfo;
oldValue := info.orientation;
case aValue of
poPortrait, poReversePortrait:
info.setOrientation(NSPortraitOrientation);
else
info.setOrientation(NSLandscapeOrientation);
end;
if oldValue<>info.orientation then
ResetPapersList(GetCurrentPrinter);
end;
function TCocoaPrinter.GetPrinterType: TPrinterType;
var
IsRemote: Boolean;
begin
Result := ptLocal;
IsRemote := false;
if PMPrinterIsRemote(GetCurrentPrinter(), IsRemote) <> noErr then Exit;
if IsRemote then Result := ptNetwork;
end;
function TCocoaPrinter.DoGetPrinterState: TPrinterState;
var
State: PMPrinterState;
begin
Result := psNoDefine;
State:=0;
if PMPrinterGetState(GetCurrentPrinter(), State) <> noErr then Exit;
case State of
kPMPrinterIdle: Result := psReady;
kPMPrinterProcessing: Result := psPrinting;
kPMPrinterStopped: Result := psStopped;
end;
end;
function TCocoaPrinter.GetCanPrint: Boolean;
begin
Result := (DoGetPrinterState() <> psStopped);
end;
function TCocoaPrinter.GetCanRenderCopies: Boolean;
begin
Result := True;
end;
initialization
Printer := TCocoaPrinter.Create;
finalization
FreeAndNil(Printer);