blob: 0be3e2bec7dda0f5f903dd684850da06f2caa80d [file] [log] [blame]
/**************************************************************
*
* Licensed to the Apache Software Foundation (ASF) under one
* or more contributor license agreements. See the NOTICE file
* distributed with this work for additional information
* regarding copyright ownership. The ASF licenses this file
* to you under the Apache License, Version 2.0 (the
* "License"); you may not use this file except in compliance
* with the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing,
* software distributed under the License is distributed on an
* "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
* KIND, either express or implied. See the License for the
* specific language governing permissions and limitations
* under the License.
*
*************************************************************/
// MARKER(update_precomp.py): autogen include statement, do not remove
#include "precompiled_vcl.hxx"
#include <boost/bind.hpp>
#include "vcl/print.hxx"
#include "vcl/unohelp.hxx"
#include "aqua/salinst.h"
#include "aqua/salprn.h"
#include "aqua/aquaprintview.h"
#include "aqua/salgdi.h"
#include "aqua/saldata.hxx"
#include "jobset.h"
#include "salptype.hxx"
#include "com/sun/star/lang/XMultiServiceFactory.hpp"
#include "com/sun/star/container/XNameAccess.hpp"
#include "com/sun/star/beans/PropertyValue.hpp"
#include "com/sun/star/awt/Size.hpp"
#include <algorithm>
using namespace rtl;
using namespace vcl;
using namespace com::sun::star;
using namespace com::sun::star::uno;
using namespace com::sun::star::lang;
using namespace com::sun::star::beans;
using namespace com::sun::star::container;
// =======================================================================
AquaSalInfoPrinter::AquaSalInfoPrinter( const SalPrinterQueueInfo& i_rQueue ) :
mpGraphics( 0 ),
mbGraphics( false ),
mbJob( false ),
mpPrinter( nil ),
mpPrintInfo( nil ),
mePageOrientation( ORIENTATION_PORTRAIT ),
mnStartPageOffsetX( 0 ),
mnStartPageOffsetY( 0 ),
mnCurPageRangeStart( 0 ),
mnCurPageRangeCount( 0 )
{
NSString* pStr = CreateNSString( i_rQueue.maPrinterName );
mpPrinter = [NSPrinter printerWithName: pStr];
[pStr release];
NSPrintInfo* pShared = [NSPrintInfo sharedPrintInfo];
if( pShared )
{
mpPrintInfo = [pShared copy];
[mpPrintInfo setPrinter: mpPrinter];
mePageOrientation = ([mpPrintInfo orientation] == NSLandscapeOrientation) ? ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT;
[mpPrintInfo setOrientation: NSPortraitOrientation];
}
mpGraphics = new AquaSalGraphics();
const int nWidth = 100, nHeight = 100;
maContextMemory.reset( reinterpret_cast<sal_uInt8*>( rtl_allocateMemory( nWidth * 4 * nHeight ) ),
boost::bind( rtl_freeMemory, _1 ) );
if( maContextMemory )
{
mrContext = CGBitmapContextCreate( maContextMemory.get(), nWidth, nHeight, 8, nWidth * 4, GetSalData()->mxRGBSpace, kCGImageAlphaNoneSkipFirst );
if( mrContext )
SetupPrinterGraphics( mrContext );
}
}
// -----------------------------------------------------------------------
AquaSalInfoPrinter::~AquaSalInfoPrinter()
{
delete mpGraphics;
if( mpPrintInfo )
[mpPrintInfo release];
#if 0
// FIXME: verify that NSPrintInfo releases the printer
// else we have a leak here
if( mpPrinter )
[mpPrinter release];
#endif
if( mrContext )
CFRelease( mrContext );
}
// -----------------------------------------------------------------------
void AquaSalInfoPrinter::SetupPrinterGraphics( CGContextRef i_rContext ) const
{
if( mpGraphics )
{
if( mpPrintInfo )
{
// FIXME: get printer resolution
long nDPIX = 720, nDPIY = 720;
NSSize aPaperSize = [mpPrintInfo paperSize];
NSRect aImageRect = [mpPrintInfo imageablePageBounds];
if( mePageOrientation == ORIENTATION_PORTRAIT )
{
// move mirrored CTM back into paper
double dX = 0, dY = aPaperSize.height;
// move CTM to reflect imageable area
dX += aImageRect.origin.x;
dY -= aPaperSize.height - aImageRect.size.height - aImageRect.origin.y;
CGContextTranslateCTM( i_rContext, dX + mnStartPageOffsetX, dY - mnStartPageOffsetY );
// scale to be top/down and reflect our "virtual" DPI
CGContextScaleCTM( i_rContext, 72.0/double(nDPIX), -(72.0/double(nDPIY)) );
}
else
{
// move CTM to reflect imageable area
double dX = aImageRect.origin.x, dY = aPaperSize.height - aImageRect.size.height - aImageRect.origin.y;
CGContextTranslateCTM( i_rContext, -dX, -dY );
// turn by 90 degree
CGContextRotateCTM( i_rContext, M_PI/2 );
// move turned CTM back into paper
dX = aPaperSize.height;
dY = -aPaperSize.width;
CGContextTranslateCTM( i_rContext, dX + mnStartPageOffsetY, dY - mnStartPageOffsetX );
// scale to be top/down and reflect our "virtual" DPI
CGContextScaleCTM( i_rContext, -(72.0/double(nDPIY)), (72.0/double(nDPIX)) );
}
mpGraphics->SetPrinterGraphics( i_rContext, nDPIX, nDPIY, 1.0 );
}
else
DBG_ERROR( "no print info in SetupPrinterGraphics" );
}
}
// -----------------------------------------------------------------------
SalGraphics* AquaSalInfoPrinter::GetGraphics()
{
SalGraphics* pGraphics = mbGraphics ? NULL : mpGraphics;
mbGraphics = true;
return pGraphics;
}
// -----------------------------------------------------------------------
void AquaSalInfoPrinter::ReleaseGraphics( SalGraphics* )
{
mbGraphics = false;
}
// -----------------------------------------------------------------------
sal_Bool AquaSalInfoPrinter::Setup( SalFrame*, ImplJobSetup* )
{
return sal_False;
}
// -----------------------------------------------------------------------
sal_Bool AquaSalInfoPrinter::SetPrinterData( ImplJobSetup* io_pSetupData )
{
// FIXME: implement driver data
if( io_pSetupData && io_pSetupData->mpDriverData )
return SetData( ~0, io_pSetupData );
sal_Bool bSuccess = sal_True;
// set system type
io_pSetupData->mnSystem = JOBSETUP_SYSTEM_MAC;
// get paper format
if( mpPrintInfo )
{
NSSize aPaperSize = [mpPrintInfo paperSize];
double width = aPaperSize.width, height = aPaperSize.height;
// set paper
PaperInfo aInfo( PtTo10Mu( width ), PtTo10Mu( height ) );
aInfo.doSloppyFit();
io_pSetupData->mePaperFormat = aInfo.getPaper();
if( io_pSetupData->mePaperFormat == PAPER_USER )
{
io_pSetupData->mnPaperWidth = PtTo10Mu( width );
io_pSetupData->mnPaperHeight = PtTo10Mu( height );
}
else
{
io_pSetupData->mnPaperWidth = 0;
io_pSetupData->mnPaperHeight = 0;
}
// set orientation
io_pSetupData->meOrientation = mePageOrientation;
io_pSetupData->mnPaperBin = 0;
io_pSetupData->mpDriverData = reinterpret_cast<sal_uInt8*>(rtl_allocateMemory( 4 ));
io_pSetupData->mnDriverDataLen = 4;
}
else
bSuccess = sal_False;
return bSuccess;
}
// -----------------------------------------------------------------------
void AquaSalInfoPrinter::setPaperSize( long i_nWidth, long i_nHeight, Orientation i_eSetOrientation )
{
Orientation ePaperOrientation = ORIENTATION_PORTRAIT;
const PaperInfo* pPaper = matchPaper( i_nWidth, i_nHeight, ePaperOrientation );
if( pPaper )
{
NSString* pPaperName = [CreateNSString( rtl::OStringToOUString(PaperInfo::toPSName(pPaper->getPaper()), RTL_TEXTENCODING_ASCII_US) ) autorelease];
[mpPrintInfo setPaperName: pPaperName];
}
else if( i_nWidth > 0 && i_nHeight > 0 )
{
NSSize aPaperSize = NSMakeSize( TenMuToPt(i_nWidth), TenMuToPt(i_nHeight));
[mpPrintInfo setPaperSize: aPaperSize];
}
// this seems counterintuitive
mePageOrientation = i_eSetOrientation;
}
// -----------------------------------------------------------------------
sal_Bool AquaSalInfoPrinter::SetData( sal_uLong i_nFlags, ImplJobSetup* io_pSetupData )
{
if( ! io_pSetupData || io_pSetupData->mnSystem != JOBSETUP_SYSTEM_MAC )
return sal_False;
if( mpPrintInfo )
{
if( (i_nFlags & SAL_JOBSET_ORIENTATION) != 0 )
mePageOrientation = io_pSetupData->meOrientation;
if( (i_nFlags & SAL_JOBSET_PAPERSIZE) != 0)
{
// set paper format
long width = 21000, height = 29700;
if( io_pSetupData->mePaperFormat == PAPER_USER )
{
// #i101108# sanity check
if( io_pSetupData->mnPaperWidth && io_pSetupData->mnPaperHeight )
{
width = io_pSetupData->mnPaperWidth;
height = io_pSetupData->mnPaperHeight;
}
}
else
{
PaperInfo aInfo( io_pSetupData->mePaperFormat );
width = aInfo.getWidth();
height = aInfo.getHeight();
}
setPaperSize( width, height, mePageOrientation );
}
}
return mpPrintInfo != nil;
}
// -----------------------------------------------------------------------
sal_uLong AquaSalInfoPrinter::GetPaperBinCount( const ImplJobSetup* )
{
return 0;
}
// -----------------------------------------------------------------------
XubString AquaSalInfoPrinter::GetPaperBinName( const ImplJobSetup*, sal_uLong )
{
return XubString();
}
// -----------------------------------------------------------------------
static bool getUseNativeDialog()
{
bool bNative = true;
try
{
// get service provider
uno::Reference< XMultiServiceFactory > xSMgr( unohelper::GetMultiServiceFactory() );
// create configuration hierachical access name
if( xSMgr.is() )
{
try
{
uno::Reference< XMultiServiceFactory > xConfigProvider(
uno::Reference< XMultiServiceFactory >(
xSMgr->createInstance( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.configuration.ConfigurationProvider" ))),
UNO_QUERY )
);
if( xConfigProvider.is() )
{
Sequence< Any > aArgs(1);
PropertyValue aVal;
aVal.Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "nodepath" ) );
aVal.Value <<= OUString( RTL_CONSTASCII_USTRINGPARAM( "/org.openoffice.Office.Common/Misc" ) );
aArgs.getArray()[0] <<= aVal;
uno::Reference< XNameAccess > xConfigAccess(
uno::Reference< XNameAccess >(
xConfigProvider->createInstanceWithArguments( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM(
"com.sun.star.configuration.ConfigurationAccess" )),
aArgs ),
UNO_QUERY )
);
if( xConfigAccess.is() )
{
try
{
sal_Bool bValue = sal_False;
Any aAny = xConfigAccess->getByName( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "UseSystemPrintDialog" ) ) );
if( aAny >>= bValue )
bNative = bValue;
}
catch( NoSuchElementException& )
{
}
catch( WrappedTargetException& )
{
}
}
}
}
catch( Exception& )
{
}
}
}
catch( WrappedTargetException& )
{
}
return bNative;
}
sal_uLong AquaSalInfoPrinter::GetCapabilities( const ImplJobSetup*, sal_uInt16 i_nType )
{
switch( i_nType )
{
case PRINTER_CAPABILITIES_SUPPORTDIALOG:
return 0;
case PRINTER_CAPABILITIES_COPIES:
return 0xffff;
case PRINTER_CAPABILITIES_COLLATECOPIES:
return 0xffff;
case PRINTER_CAPABILITIES_SETORIENTATION:
return 1;
case PRINTER_CAPABILITIES_SETDUPLEX:
return 0;
case PRINTER_CAPABILITIES_SETPAPERBIN:
return 0;
case PRINTER_CAPABILITIES_SETPAPERSIZE:
return 1;
case PRINTER_CAPABILITIES_SETPAPER:
return 1;
case PRINTER_CAPABILITIES_EXTERNALDIALOG:
return getUseNativeDialog() ? 1 : 0;
case PRINTER_CAPABILITIES_PDF:
return 1;
case PRINTER_CAPABILITIES_USEPULLMODEL:
return 1;
default: break;
};
return 0;
}
// -----------------------------------------------------------------------
void AquaSalInfoPrinter::GetPageInfo( const ImplJobSetup*,
long& o_rOutWidth, long& o_rOutHeight,
long& o_rPageOffX, long& o_rPageOffY,
long& o_rPageWidth, long& o_rPageHeight )
{
if( mpPrintInfo )
{
sal_Int32 nDPIX = 72, nDPIY = 72;
mpGraphics->GetResolution( nDPIX, nDPIY );
const double fXScaling = static_cast<double>(nDPIX)/72.0,
fYScaling = static_cast<double>(nDPIY)/72.0;
NSSize aPaperSize = [mpPrintInfo paperSize];
o_rPageWidth = static_cast<long>( double(aPaperSize.width) * fXScaling );
o_rPageHeight = static_cast<long>( double(aPaperSize.height) * fYScaling );
NSRect aImageRect = [mpPrintInfo imageablePageBounds];
o_rPageOffX = static_cast<long>( aImageRect.origin.x * fXScaling );
o_rPageOffY = static_cast<long>( (aPaperSize.height - aImageRect.size.height - aImageRect.origin.y) * fYScaling );
o_rOutWidth = static_cast<long>( aImageRect.size.width * fXScaling );
o_rOutHeight = static_cast<long>( aImageRect.size.height * fYScaling );
if( mePageOrientation == ORIENTATION_LANDSCAPE )
{
std::swap( o_rOutWidth, o_rOutHeight );
std::swap( o_rPageWidth, o_rPageHeight );
std::swap( o_rPageOffX, o_rPageOffY );
}
}
}
static Size getPageSize( vcl::PrinterController& i_rController, sal_Int32 i_nPage )
{
Size aPageSize;
Sequence< PropertyValue > aPageParms( i_rController.getPageParameters( i_nPage ) );
for( sal_Int32 nProperty = 0, nPropertyCount = aPageParms.getLength(); nProperty < nPropertyCount; ++nProperty )
{
if( aPageParms[ nProperty ].Name.equalsAscii( "PageSize" ) )
{
awt::Size aSize;
aPageParms[ nProperty].Value >>= aSize;
aPageSize.Width() = aSize.Width;
aPageSize.Height() = aSize.Height;
break;
}
}
return aPageSize;
}
sal_Bool AquaSalInfoPrinter::StartJob( const String* i_pFileName,
const String& i_rJobName,
const String& /*i_rAppName*/,
ImplJobSetup* i_pSetupData,
vcl::PrinterController& i_rController
)
{
if( mbJob )
return sal_False;
sal_Bool bSuccess = sal_False;
bool bWasAborted = false;
AquaSalInstance* pInst = GetSalData()->mpFirstInstance;
PrintAccessoryViewState aAccViewState;
sal_Int32 nAllPages = 0;
// reset IsLastPage
i_rController.setLastPage( sal_False );
// update job data
if( i_pSetupData )
SetData( ~0, i_pSetupData );
// do we want a progress panel ?
sal_Bool bShowProgressPanel = sal_True;
beans::PropertyValue* pMonitor = i_rController.getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "MonitorVisible" ) ) );
if( pMonitor )
pMonitor->Value >>= bShowProgressPanel;
if( ! i_rController.isShowDialogs() )
bShowProgressPanel = sal_False;
// possibly create one job for collated output
sal_Bool bSinglePrintJobs = sal_False;
beans::PropertyValue* pSingleValue = i_rController.getValue( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "PrintCollateAsSingleJobs" ) ) );
if( pSingleValue )
{
pSingleValue->Value >>= bSinglePrintJobs;
}
// FIXME: jobStarted() should be done after the print dialog has ended (if there is one)
// how do I know when that might be ?
i_rController.jobStarted();
int nCopies = i_rController.getPrinter()->GetCopyCount();
int nJobs = 1;
if( bSinglePrintJobs )
{
nJobs = nCopies;
nCopies = 1;
}
for( int nCurJob = 0; nCurJob < nJobs; nCurJob++ )
{
aAccViewState.bNeedRestart = true;
do
{
if( aAccViewState.bNeedRestart )
{
mnCurPageRangeStart = 0;
mnCurPageRangeCount = 0;
nAllPages = i_rController.getFilteredPageCount();
}
aAccViewState.bNeedRestart = false;
Size aCurSize( 21000, 29700 );
if( nAllPages > 0 )
{
mnCurPageRangeCount = 1;
aCurSize = getPageSize( i_rController, mnCurPageRangeStart );
Size aNextSize( aCurSize );
// print pages up to a different size
while( mnCurPageRangeCount + mnCurPageRangeStart < nAllPages )
{
aNextSize = getPageSize( i_rController, mnCurPageRangeStart + mnCurPageRangeCount );
if( aCurSize == aNextSize // same page size
||
(aCurSize.Width() == aNextSize.Height() && aCurSize.Height() == aNextSize.Width()) // same size, but different orientation
)
{
mnCurPageRangeCount++;
}
else
break;
}
}
else
mnCurPageRangeCount = 0;
// now for the current run
mnStartPageOffsetX = mnStartPageOffsetY = 0;
// setup the paper size and orientation
// do this on our associated Printer object, since that is
// out interface to the applications which occasionally rely on the paper
// information (e.g. brochure printing scales to the found paper size)
// also SetPaperSizeUser has the advantage that we can share a
// platform independent paper matching algorithm
boost::shared_ptr<Printer> pPrinter( i_rController.getPrinter() );
pPrinter->SetMapMode( MapMode( MAP_100TH_MM ) );
pPrinter->SetPaperSizeUser( aCurSize, true );
// create view
NSView* pPrintView = [[AquaPrintView alloc] initWithController: &i_rController withInfoPrinter: this];
NSMutableDictionary* pPrintDict = [mpPrintInfo dictionary];
// set filename
if( i_pFileName )
{
[mpPrintInfo setJobDisposition: NSPrintSaveJob];
NSString* pPath = CreateNSString( *i_pFileName );
[pPrintDict setObject: pPath forKey: NSPrintSavePath];
[pPath release];
}
[pPrintDict setObject: [[NSNumber numberWithInt: nCopies] autorelease] forKey: NSPrintCopies];
if( nCopies > 1 )
[pPrintDict setObject: [[NSNumber numberWithBool: pPrinter->IsCollateCopy()] autorelease] forKey: NSPrintMustCollate];
[pPrintDict setObject: [[NSNumber numberWithBool: YES] autorelease] forKey: NSPrintDetailedErrorReporting];
[pPrintDict setObject: [[NSNumber numberWithInt: 1] autorelease] forKey: NSPrintFirstPage];
// #i103253# weird: for some reason, autoreleasing the value below like the others above
// leads do a double free malloc error. Why this value should behave differently from all the others
// is a mystery.
[pPrintDict setObject: [NSNumber numberWithInt: mnCurPageRangeCount] forKey: NSPrintLastPage];
// create print operation
NSPrintOperation* pPrintOperation = [NSPrintOperation printOperationWithView: pPrintView printInfo: mpPrintInfo];
if( pPrintOperation )
{
NSObject* pReleaseAfterUse = nil;
bool bShowPanel = (! i_rController.isDirectPrint() && getUseNativeDialog() && i_rController.isShowDialogs() );
[pPrintOperation setShowsPrintPanel: bShowPanel ? YES : NO ];
[pPrintOperation setShowsProgressPanel: bShowProgressPanel ? YES : NO];
// set job title (since MacOSX 10.5)
if( [pPrintOperation respondsToSelector: @selector(setJobTitle:)] )
[pPrintOperation performSelector: @selector(setJobTitle:) withObject: [CreateNSString( i_rJobName ) autorelease]];
if( bShowPanel && mnCurPageRangeStart == 0 && nCurJob == 0) // only the first range of pages (in the first job) gets the accesory view
pReleaseAfterUse = [AquaPrintAccessoryView setupPrinterPanel: pPrintOperation withController: &i_rController withState: &aAccViewState];
bSuccess = sal_True;
mbJob = true;
pInst->startedPrintJob();
[pPrintOperation runOperation];
pInst->endedPrintJob();
bWasAborted = [[[pPrintOperation printInfo] jobDisposition] compare: NSPrintCancelJob] == NSOrderedSame;
mbJob = false;
if( pReleaseAfterUse )
[pReleaseAfterUse release];
}
mnCurPageRangeStart += mnCurPageRangeCount;
mnCurPageRangeCount = 1;
} while( aAccViewState.bNeedRestart || mnCurPageRangeStart + mnCurPageRangeCount < nAllPages );
}
// inform application that it can release its data
// this is awkward, but the XRenderable interface has no method for this,
// so we need to call XRenderadble::render one last time with IsLastPage = sal_True
i_rController.setLastPage( sal_True );
GDIMetaFile aPageFile;
if( mrContext )
SetupPrinterGraphics( mrContext );
i_rController.getFilteredPageFile( 0, aPageFile );
i_rController.setJobState( bWasAborted
? view::PrintableState_JOB_ABORTED
: view::PrintableState_JOB_SPOOLED );
mnCurPageRangeStart = mnCurPageRangeCount = 0;
return bSuccess;
}
// -----------------------------------------------------------------------
sal_Bool AquaSalInfoPrinter::EndJob()
{
mnStartPageOffsetX = mnStartPageOffsetY = 0;
mbJob = false;
return sal_True;
}
// -----------------------------------------------------------------------
sal_Bool AquaSalInfoPrinter::AbortJob()
{
mbJob = false;
// FIXME: implementation
return sal_False;
}
// -----------------------------------------------------------------------
SalGraphics* AquaSalInfoPrinter::StartPage( ImplJobSetup* i_pSetupData, sal_Bool i_bNewJobData )
{
if( i_bNewJobData && i_pSetupData )
SetPrinterData( i_pSetupData );
CGContextRef rContext = reinterpret_cast<CGContextRef>([[NSGraphicsContext currentContext] graphicsPort]);
SetupPrinterGraphics( rContext );
return mpGraphics;
}
// -----------------------------------------------------------------------
sal_Bool AquaSalInfoPrinter::EndPage()
{
mpGraphics->InvalidateContext();
return sal_True;
}
// -----------------------------------------------------------------------
sal_uLong AquaSalInfoPrinter::GetErrorCode() const
{
return 0;
}
// =======================================================================
AquaSalPrinter::AquaSalPrinter( AquaSalInfoPrinter* i_pInfoPrinter ) :
mpInfoPrinter( i_pInfoPrinter )
{
}
// -----------------------------------------------------------------------
AquaSalPrinter::~AquaSalPrinter()
{
}
// -----------------------------------------------------------------------
sal_Bool AquaSalPrinter::StartJob( const String* i_pFileName,
const String& i_rJobName,
const String& i_rAppName,
ImplJobSetup* i_pSetupData,
vcl::PrinterController& i_rController )
{
return mpInfoPrinter->StartJob( i_pFileName, i_rJobName, i_rAppName, i_pSetupData, i_rController );
}
// -----------------------------------------------------------------------
sal_Bool AquaSalPrinter::StartJob( const XubString* /*i_pFileName*/,
const XubString& /*i_rJobName*/,
const XubString& /*i_rAppName*/,
sal_uLong /*i_nCopies*/,
bool /*i_bCollate*/,
bool /*i_bDirect*/,
ImplJobSetup* )
{
DBG_ERROR( "should never be called" );
return sal_False;
}
// -----------------------------------------------------------------------
sal_Bool AquaSalPrinter::EndJob()
{
return mpInfoPrinter->EndJob();
}
// -----------------------------------------------------------------------
sal_Bool AquaSalPrinter::AbortJob()
{
return mpInfoPrinter->AbortJob();
}
// -----------------------------------------------------------------------
SalGraphics* AquaSalPrinter::StartPage( ImplJobSetup* i_pSetupData, sal_Bool i_bNewJobData )
{
return mpInfoPrinter->StartPage( i_pSetupData, i_bNewJobData );
}
// -----------------------------------------------------------------------
sal_Bool AquaSalPrinter::EndPage()
{
return mpInfoPrinter->EndPage();
}
// -----------------------------------------------------------------------
sal_uLong AquaSalPrinter::GetErrorCode()
{
return mpInfoPrinter->GetErrorCode();
}
void AquaSalInfoPrinter::InitPaperFormats( const ImplJobSetup* )
{
m_aPaperFormats.clear();
m_bPapersInit = true;
if( mpPrinter )
{
if( [mpPrinter statusForTable: @"PPD"] == NSPrinterTableOK )
{
NSArray* pPaperNames = [mpPrinter stringListForKey: @"PageSize" inTable: @"PPD"];
if( pPaperNames )
{
unsigned int nPapers = [pPaperNames count];
for( unsigned int i = 0; i < nPapers; i++ )
{
NSString* pPaper = [pPaperNames objectAtIndex: i];
// first try to match the name
rtl::OString aPaperName( [pPaper UTF8String] );
Paper ePaper = PaperInfo::fromPSName( aPaperName );
if( ePaper != PAPER_USER )
{
m_aPaperFormats.push_back( PaperInfo( ePaper ) );
}
else
{
NSSize aPaperSize = [mpPrinter pageSizeForPaper: pPaper];
if( aPaperSize.width > 0 && aPaperSize.height > 0 )
{
PaperInfo aInfo( PtTo10Mu( aPaperSize.width ),
PtTo10Mu( aPaperSize.height ) );
if( aInfo.getPaper() == PAPER_USER )
aInfo.doSloppyFit();
m_aPaperFormats.push_back( aInfo );
}
}
}
}
}
}
}
const PaperInfo* AquaSalInfoPrinter::matchPaper( long i_nWidth, long i_nHeight, Orientation& o_rOrientation ) const
{
if( ! m_bPapersInit )
const_cast<AquaSalInfoPrinter*>(this)->InitPaperFormats( NULL );
const PaperInfo* pMatch = NULL;
o_rOrientation = ORIENTATION_PORTRAIT;
for( int n = 0; n < 2 ; n++ )
{
for( size_t i = 0; i < m_aPaperFormats.size(); i++ )
{
if( abs( m_aPaperFormats[i].getWidth() - i_nWidth ) < 50 &&
abs( m_aPaperFormats[i].getHeight() - i_nHeight ) < 50 )
{
pMatch = &m_aPaperFormats[i];
return pMatch;
}
}
o_rOrientation = ORIENTATION_LANDSCAPE;
std::swap( i_nWidth, i_nHeight );
}
return pMatch;
}
int AquaSalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* )
{
return 900;
}