1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_vcl.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <stdio.h> 32*cdf0e10cSrcweir #include <sys/types.h> 33*cdf0e10cSrcweir #include <sys/stat.h> 34*cdf0e10cSrcweir #include <fcntl.h> 35*cdf0e10cSrcweir #include <unistd.h> 36*cdf0e10cSrcweir #include <pwd.h> 37*cdf0e10cSrcweir 38*cdf0e10cSrcweir #include "psputil.hxx" 39*cdf0e10cSrcweir #include "glyphset.hxx" 40*cdf0e10cSrcweir 41*cdf0e10cSrcweir #include "printerjob.hxx" 42*cdf0e10cSrcweir #include "printergfx.hxx" 43*cdf0e10cSrcweir #include "vcl/ppdparser.hxx" 44*cdf0e10cSrcweir #include "vcl/strhelper.hxx" 45*cdf0e10cSrcweir #include "vcl/printerinfomanager.hxx" 46*cdf0e10cSrcweir 47*cdf0e10cSrcweir #include "rtl/ustring.hxx" 48*cdf0e10cSrcweir #include "rtl/strbuf.hxx" 49*cdf0e10cSrcweir #include "rtl/ustrbuf.hxx" 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir #include "osl/thread.h" 52*cdf0e10cSrcweir #include "sal/alloca.h" 53*cdf0e10cSrcweir 54*cdf0e10cSrcweir #include <algorithm> 55*cdf0e10cSrcweir #include <vector> 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir using namespace psp; 58*cdf0e10cSrcweir using namespace rtl; 59*cdf0e10cSrcweir 60*cdf0e10cSrcweir // forward declaration 61*cdf0e10cSrcweir 62*cdf0e10cSrcweir #define nBLOCKSIZE 0x2000 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir namespace psp 65*cdf0e10cSrcweir { 66*cdf0e10cSrcweir 67*cdf0e10cSrcweir sal_Bool 68*cdf0e10cSrcweir AppendPS (FILE* pDst, osl::File* pSrc, sal_uChar* pBuffer, 69*cdf0e10cSrcweir sal_uInt32 nBlockSize = nBLOCKSIZE) 70*cdf0e10cSrcweir { 71*cdf0e10cSrcweir if ((pDst == NULL) || (pSrc == NULL)) 72*cdf0e10cSrcweir return sal_False; 73*cdf0e10cSrcweir 74*cdf0e10cSrcweir if (nBlockSize == 0) 75*cdf0e10cSrcweir nBlockSize = nBLOCKSIZE; 76*cdf0e10cSrcweir if (pBuffer == NULL) 77*cdf0e10cSrcweir pBuffer = (sal_uChar*)alloca (nBlockSize); 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir pSrc->setPos (osl_Pos_Absolut, 0); 80*cdf0e10cSrcweir 81*cdf0e10cSrcweir sal_uInt64 nIn = 0; 82*cdf0e10cSrcweir sal_uInt64 nOut = 0; 83*cdf0e10cSrcweir do 84*cdf0e10cSrcweir { 85*cdf0e10cSrcweir pSrc->read (pBuffer, nBlockSize, nIn); 86*cdf0e10cSrcweir if (nIn > 0) 87*cdf0e10cSrcweir nOut = fwrite (pBuffer, 1, sal::static_int_cast<sal_uInt32>(nIn), pDst); 88*cdf0e10cSrcweir } 89*cdf0e10cSrcweir while ((nIn > 0) && (nIn == nOut)); 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir return sal_True; 92*cdf0e10cSrcweir } 93*cdf0e10cSrcweir 94*cdf0e10cSrcweir } // namespace psp 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir /* 97*cdf0e10cSrcweir * private convenience routines for file handling 98*cdf0e10cSrcweir */ 99*cdf0e10cSrcweir 100*cdf0e10cSrcweir osl::File* 101*cdf0e10cSrcweir PrinterJob::CreateSpoolFile (const rtl::OUString& rName, const rtl::OUString& rExtension) 102*cdf0e10cSrcweir { 103*cdf0e10cSrcweir osl::File::RC nError = osl::File::E_None; 104*cdf0e10cSrcweir osl::File* pFile = NULL; 105*cdf0e10cSrcweir 106*cdf0e10cSrcweir rtl::OUString aFile = rName + rExtension; 107*cdf0e10cSrcweir rtl::OUString aFileURL; 108*cdf0e10cSrcweir nError = osl::File::getFileURLFromSystemPath( aFile, aFileURL ); 109*cdf0e10cSrcweir if (nError != osl::File::E_None) 110*cdf0e10cSrcweir return NULL; 111*cdf0e10cSrcweir aFileURL = maSpoolDirName + rtl::OUString::createFromAscii ("/") + aFileURL; 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir pFile = new osl::File (aFileURL); 114*cdf0e10cSrcweir nError = pFile->open (OpenFlag_Read | OpenFlag_Write | OpenFlag_Create); 115*cdf0e10cSrcweir if (nError != osl::File::E_None) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir delete pFile; 118*cdf0e10cSrcweir return NULL; 119*cdf0e10cSrcweir } 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir pFile->setAttributes (aFileURL, 122*cdf0e10cSrcweir osl_File_Attribute_OwnWrite | osl_File_Attribute_OwnRead); 123*cdf0e10cSrcweir return pFile; 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir 126*cdf0e10cSrcweir /* 127*cdf0e10cSrcweir * public methods of PrinterJob: for use in PrinterGfx 128*cdf0e10cSrcweir */ 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir void 131*cdf0e10cSrcweir PrinterJob::GetScale (double &rXScale, double &rYScale) const 132*cdf0e10cSrcweir { 133*cdf0e10cSrcweir rXScale = mfXScale; 134*cdf0e10cSrcweir rYScale = mfYScale; 135*cdf0e10cSrcweir } 136*cdf0e10cSrcweir 137*cdf0e10cSrcweir sal_uInt16 138*cdf0e10cSrcweir PrinterJob::GetDepth () const 139*cdf0e10cSrcweir { 140*cdf0e10cSrcweir sal_Int32 nLevel = GetPostscriptLevel(); 141*cdf0e10cSrcweir sal_Bool bColor = IsColorPrinter (); 142*cdf0e10cSrcweir 143*cdf0e10cSrcweir return nLevel > 1 && bColor ? 24 : 8; 144*cdf0e10cSrcweir } 145*cdf0e10cSrcweir 146*cdf0e10cSrcweir sal_uInt16 147*cdf0e10cSrcweir PrinterJob::GetPostscriptLevel (const JobData *pJobData) const 148*cdf0e10cSrcweir { 149*cdf0e10cSrcweir sal_uInt16 nPSLevel = 2; 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir if( pJobData == NULL ) 152*cdf0e10cSrcweir pJobData = &m_aLastJobData; 153*cdf0e10cSrcweir 154*cdf0e10cSrcweir if( pJobData->m_nPSLevel ) 155*cdf0e10cSrcweir nPSLevel = pJobData->m_nPSLevel; 156*cdf0e10cSrcweir else 157*cdf0e10cSrcweir if( pJobData->m_pParser ) 158*cdf0e10cSrcweir nPSLevel = pJobData->m_pParser->getLanguageLevel(); 159*cdf0e10cSrcweir 160*cdf0e10cSrcweir return nPSLevel; 161*cdf0e10cSrcweir } 162*cdf0e10cSrcweir 163*cdf0e10cSrcweir sal_Bool 164*cdf0e10cSrcweir PrinterJob::IsColorPrinter () const 165*cdf0e10cSrcweir { 166*cdf0e10cSrcweir sal_Bool bColor = sal_False; 167*cdf0e10cSrcweir 168*cdf0e10cSrcweir if( m_aLastJobData.m_nColorDevice ) 169*cdf0e10cSrcweir bColor = m_aLastJobData.m_nColorDevice == -1 ? sal_False : sal_True; 170*cdf0e10cSrcweir else if( m_aLastJobData.m_pParser ) 171*cdf0e10cSrcweir bColor = m_aLastJobData.m_pParser->isColorDevice() ? sal_True : sal_False; 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir return bColor; 174*cdf0e10cSrcweir } 175*cdf0e10cSrcweir 176*cdf0e10cSrcweir osl::File* 177*cdf0e10cSrcweir PrinterJob::GetDocumentHeader () 178*cdf0e10cSrcweir { 179*cdf0e10cSrcweir return mpJobHeader; 180*cdf0e10cSrcweir } 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir osl::File* 183*cdf0e10cSrcweir PrinterJob::GetDocumentTrailer () 184*cdf0e10cSrcweir { 185*cdf0e10cSrcweir return mpJobTrailer; 186*cdf0e10cSrcweir } 187*cdf0e10cSrcweir 188*cdf0e10cSrcweir osl::File* 189*cdf0e10cSrcweir PrinterJob::GetCurrentPageHeader () 190*cdf0e10cSrcweir { 191*cdf0e10cSrcweir return maHeaderList.back(); 192*cdf0e10cSrcweir } 193*cdf0e10cSrcweir 194*cdf0e10cSrcweir osl::File* 195*cdf0e10cSrcweir PrinterJob::GetCurrentPageBody () 196*cdf0e10cSrcweir { 197*cdf0e10cSrcweir return maPageList.back(); 198*cdf0e10cSrcweir } 199*cdf0e10cSrcweir 200*cdf0e10cSrcweir /* 201*cdf0e10cSrcweir * public methods of PrinterJob: the actual job / spool handling 202*cdf0e10cSrcweir */ 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir PrinterJob::PrinterJob () : 205*cdf0e10cSrcweir mpJobHeader( NULL ), 206*cdf0e10cSrcweir mpJobTrailer( NULL ), 207*cdf0e10cSrcweir m_bQuickJob( false ) 208*cdf0e10cSrcweir { 209*cdf0e10cSrcweir } 210*cdf0e10cSrcweir 211*cdf0e10cSrcweir namespace psp 212*cdf0e10cSrcweir { 213*cdf0e10cSrcweir 214*cdf0e10cSrcweir /* check whether the given name points to a directory which is 215*cdf0e10cSrcweir usable for the user */ 216*cdf0e10cSrcweir sal_Bool 217*cdf0e10cSrcweir existsTmpDir (const char* pName) 218*cdf0e10cSrcweir { 219*cdf0e10cSrcweir struct stat aFileStatus; 220*cdf0e10cSrcweir 221*cdf0e10cSrcweir if (pName == NULL) 222*cdf0e10cSrcweir return sal_False; 223*cdf0e10cSrcweir if (stat(pName, &aFileStatus) != 0) 224*cdf0e10cSrcweir return sal_False; 225*cdf0e10cSrcweir if (! S_ISDIR(aFileStatus.st_mode)) 226*cdf0e10cSrcweir return sal_False; 227*cdf0e10cSrcweir 228*cdf0e10cSrcweir return access(pName, W_OK | R_OK) == 0 ? sal_True : sal_False; 229*cdf0e10cSrcweir } 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir /* return the username in the given buffer */ 232*cdf0e10cSrcweir sal_Bool 233*cdf0e10cSrcweir getUserName (char* pName, int nSize) 234*cdf0e10cSrcweir { 235*cdf0e10cSrcweir struct passwd *pPWEntry; 236*cdf0e10cSrcweir struct passwd aPWEntry; 237*cdf0e10cSrcweir sal_Char pPWBuffer[256]; 238*cdf0e10cSrcweir 239*cdf0e10cSrcweir sal_Bool bSuccess = sal_False; 240*cdf0e10cSrcweir 241*cdf0e10cSrcweir #ifdef FREEBSD 242*cdf0e10cSrcweir pPWEntry = getpwuid( getuid()); 243*cdf0e10cSrcweir #else 244*cdf0e10cSrcweir if (getpwuid_r(getuid(), &aPWEntry, pPWBuffer, sizeof(pPWBuffer), &pPWEntry) != 0) 245*cdf0e10cSrcweir pPWEntry = NULL; 246*cdf0e10cSrcweir #endif 247*cdf0e10cSrcweir 248*cdf0e10cSrcweir if (pPWEntry != NULL && pPWEntry->pw_name != NULL) 249*cdf0e10cSrcweir { 250*cdf0e10cSrcweir sal_Int32 nLen = strlen(pPWEntry->pw_name); 251*cdf0e10cSrcweir if (nLen > 0 && nLen < nSize) 252*cdf0e10cSrcweir { 253*cdf0e10cSrcweir memcpy (pName, pPWEntry->pw_name, nLen); 254*cdf0e10cSrcweir pName[nLen] = '\0'; 255*cdf0e10cSrcweir 256*cdf0e10cSrcweir bSuccess = sal_True; 257*cdf0e10cSrcweir } 258*cdf0e10cSrcweir } 259*cdf0e10cSrcweir 260*cdf0e10cSrcweir // wipe the passwd off the stack 261*cdf0e10cSrcweir memset (pPWBuffer, 0, sizeof(pPWBuffer)); 262*cdf0e10cSrcweir 263*cdf0e10cSrcweir return bSuccess; 264*cdf0e10cSrcweir } 265*cdf0e10cSrcweir 266*cdf0e10cSrcweir /* remove all our temporary files, uses external program "rm", since 267*cdf0e10cSrcweir osl functionality is inadequate */ 268*cdf0e10cSrcweir void 269*cdf0e10cSrcweir removeSpoolDir (const rtl::OUString& rSpoolDir) 270*cdf0e10cSrcweir { 271*cdf0e10cSrcweir rtl::OUString aSysPath; 272*cdf0e10cSrcweir if( osl::File::E_None != osl::File::getSystemPathFromFileURL( rSpoolDir, aSysPath ) ) 273*cdf0e10cSrcweir { 274*cdf0e10cSrcweir // Conversion did not work, as this is quite a dangerous action, 275*cdf0e10cSrcweir // we should abort here .... 276*cdf0e10cSrcweir OSL_ENSURE( 0, "psprint: couldn't remove spool directory" ); 277*cdf0e10cSrcweir return; 278*cdf0e10cSrcweir } 279*cdf0e10cSrcweir rtl::OString aSysPathByte = 280*cdf0e10cSrcweir rtl::OUStringToOString (aSysPath, osl_getThreadTextEncoding()); 281*cdf0e10cSrcweir sal_Char pSystem [128]; 282*cdf0e10cSrcweir sal_Int32 nChar = 0; 283*cdf0e10cSrcweir 284*cdf0e10cSrcweir nChar = psp::appendStr ("rm -rf ", pSystem); 285*cdf0e10cSrcweir nChar += psp::appendStr (aSysPathByte.getStr(), pSystem + nChar); 286*cdf0e10cSrcweir 287*cdf0e10cSrcweir if (system (pSystem) == -1) 288*cdf0e10cSrcweir OSL_ENSURE( 0, "psprint: couldn't remove spool directory" ); 289*cdf0e10cSrcweir } 290*cdf0e10cSrcweir 291*cdf0e10cSrcweir /* creates a spool directory with a "pidgin random" value based on 292*cdf0e10cSrcweir current system time */ 293*cdf0e10cSrcweir rtl::OUString 294*cdf0e10cSrcweir createSpoolDir () 295*cdf0e10cSrcweir { 296*cdf0e10cSrcweir TimeValue aCur; 297*cdf0e10cSrcweir osl_getSystemTime( &aCur ); 298*cdf0e10cSrcweir sal_Int32 nRand = aCur.Seconds ^ (aCur.Nanosec/1000); 299*cdf0e10cSrcweir 300*cdf0e10cSrcweir rtl::OUString aTmpDir; 301*cdf0e10cSrcweir osl_getTempDirURL( &aTmpDir.pData ); 302*cdf0e10cSrcweir 303*cdf0e10cSrcweir do 304*cdf0e10cSrcweir { 305*cdf0e10cSrcweir rtl::OUStringBuffer aDir( aTmpDir.getLength() + 16 ); 306*cdf0e10cSrcweir aDir.append( aTmpDir ); 307*cdf0e10cSrcweir aDir.appendAscii( "/psp" ); 308*cdf0e10cSrcweir aDir.append(nRand); 309*cdf0e10cSrcweir rtl::OUString aResult = aDir.makeStringAndClear(); 310*cdf0e10cSrcweir if( osl::Directory::create( aResult ) == osl::FileBase::E_None ) 311*cdf0e10cSrcweir { 312*cdf0e10cSrcweir osl::File::setAttributes( aResult, 313*cdf0e10cSrcweir osl_File_Attribute_OwnWrite 314*cdf0e10cSrcweir | osl_File_Attribute_OwnRead 315*cdf0e10cSrcweir | osl_File_Attribute_OwnExe ); 316*cdf0e10cSrcweir return aResult; 317*cdf0e10cSrcweir } 318*cdf0e10cSrcweir nRand++; 319*cdf0e10cSrcweir } while( nRand ); 320*cdf0e10cSrcweir return rtl::OUString(); 321*cdf0e10cSrcweir } 322*cdf0e10cSrcweir 323*cdf0e10cSrcweir } // namespace psp 324*cdf0e10cSrcweir 325*cdf0e10cSrcweir PrinterJob::~PrinterJob () 326*cdf0e10cSrcweir { 327*cdf0e10cSrcweir std::list< osl::File* >::iterator pPage; 328*cdf0e10cSrcweir for (pPage = maPageList.begin(); pPage != maPageList.end(); pPage++) 329*cdf0e10cSrcweir { 330*cdf0e10cSrcweir //(*pPage)->remove(); 331*cdf0e10cSrcweir delete *pPage; 332*cdf0e10cSrcweir } 333*cdf0e10cSrcweir for (pPage = maHeaderList.begin(); pPage != maHeaderList.end(); pPage++) 334*cdf0e10cSrcweir { 335*cdf0e10cSrcweir //(*pPage)->remove(); 336*cdf0e10cSrcweir delete *pPage; 337*cdf0e10cSrcweir } 338*cdf0e10cSrcweir // mpJobHeader->remove(); 339*cdf0e10cSrcweir delete mpJobHeader; 340*cdf0e10cSrcweir // mpJobTrailer->remove(); 341*cdf0e10cSrcweir delete mpJobTrailer; 342*cdf0e10cSrcweir 343*cdf0e10cSrcweir // XXX should really call osl::remove routines 344*cdf0e10cSrcweir if( maSpoolDirName.getLength() ) 345*cdf0e10cSrcweir removeSpoolDir (maSpoolDirName); 346*cdf0e10cSrcweir 347*cdf0e10cSrcweir // osl::Directory::remove (maSpoolDirName); 348*cdf0e10cSrcweir } 349*cdf0e10cSrcweir 350*cdf0e10cSrcweir namespace psp 351*cdf0e10cSrcweir { 352*cdf0e10cSrcweir 353*cdf0e10cSrcweir // get locale invariant, 7bit clean current local time string 354*cdf0e10cSrcweir sal_Char* 355*cdf0e10cSrcweir getLocalTime(sal_Char* pBuffer) 356*cdf0e10cSrcweir { 357*cdf0e10cSrcweir time_t nTime = time (NULL); 358*cdf0e10cSrcweir struct tm aTime; 359*cdf0e10cSrcweir struct tm *pLocalTime = localtime_r (&nTime, &aTime); 360*cdf0e10cSrcweir 361*cdf0e10cSrcweir return asctime_r(pLocalTime, pBuffer); 362*cdf0e10cSrcweir } 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir } 365*cdf0e10cSrcweir 366*cdf0e10cSrcweir static bool isAscii( const rtl::OUString& rStr ) 367*cdf0e10cSrcweir { 368*cdf0e10cSrcweir const sal_Unicode* pStr = rStr; 369*cdf0e10cSrcweir sal_Int32 nLen = rStr.getLength(); 370*cdf0e10cSrcweir for( sal_Int32 i = 0; i < nLen; i++ ) 371*cdf0e10cSrcweir if( pStr[i] > 127 ) 372*cdf0e10cSrcweir return false; 373*cdf0e10cSrcweir return true; 374*cdf0e10cSrcweir } 375*cdf0e10cSrcweir 376*cdf0e10cSrcweir sal_Bool 377*cdf0e10cSrcweir PrinterJob::StartJob ( 378*cdf0e10cSrcweir const rtl::OUString& rFileName, 379*cdf0e10cSrcweir int nMode, 380*cdf0e10cSrcweir const rtl::OUString& rJobName, 381*cdf0e10cSrcweir const rtl::OUString& rAppName, 382*cdf0e10cSrcweir const JobData& rSetupData, 383*cdf0e10cSrcweir PrinterGfx* pGraphics, 384*cdf0e10cSrcweir bool bIsQuickJob 385*cdf0e10cSrcweir ) 386*cdf0e10cSrcweir { 387*cdf0e10cSrcweir m_bQuickJob = bIsQuickJob; 388*cdf0e10cSrcweir mnMaxWidthPt = mnMaxHeightPt = 0; 389*cdf0e10cSrcweir mnLandscapes = mnPortraits = 0; 390*cdf0e10cSrcweir m_pGraphics = pGraphics; 391*cdf0e10cSrcweir InitPaperSize (rSetupData); 392*cdf0e10cSrcweir 393*cdf0e10cSrcweir // create file container for document header and trailer 394*cdf0e10cSrcweir maFileName = rFileName; 395*cdf0e10cSrcweir mnFileMode = nMode; 396*cdf0e10cSrcweir maSpoolDirName = createSpoolDir (); 397*cdf0e10cSrcweir maJobTitle = rJobName; 398*cdf0e10cSrcweir 399*cdf0e10cSrcweir rtl::OUString aExt = rtl::OUString::createFromAscii (".ps"); 400*cdf0e10cSrcweir mpJobHeader = CreateSpoolFile (rtl::OUString::createFromAscii("psp_head"), aExt); 401*cdf0e10cSrcweir mpJobTrailer = CreateSpoolFile (rtl::OUString::createFromAscii("psp_tail"), aExt); 402*cdf0e10cSrcweir if( ! (mpJobHeader && mpJobTrailer) ) // existing files are removed in destructor 403*cdf0e10cSrcweir return sal_False; 404*cdf0e10cSrcweir 405*cdf0e10cSrcweir // write document header according to Document Structuring Conventions (DSC) 406*cdf0e10cSrcweir WritePS (mpJobHeader, 407*cdf0e10cSrcweir "%!PS-Adobe-3.0\n" 408*cdf0e10cSrcweir "%%BoundingBox: (atend)\n" ); 409*cdf0e10cSrcweir 410*cdf0e10cSrcweir rtl::OUString aFilterWS; 411*cdf0e10cSrcweir 412*cdf0e10cSrcweir // Creator (this application) 413*cdf0e10cSrcweir aFilterWS = WhitespaceToSpace( rAppName, sal_False ); 414*cdf0e10cSrcweir WritePS (mpJobHeader, "%%Creator: ("); 415*cdf0e10cSrcweir WritePS (mpJobHeader, aFilterWS); 416*cdf0e10cSrcweir WritePS (mpJobHeader, ")\n"); 417*cdf0e10cSrcweir 418*cdf0e10cSrcweir // For (user name) 419*cdf0e10cSrcweir sal_Char pUserName[64]; 420*cdf0e10cSrcweir if (getUserName(pUserName, sizeof(pUserName))) 421*cdf0e10cSrcweir { 422*cdf0e10cSrcweir WritePS (mpJobHeader, "%%For: ("); 423*cdf0e10cSrcweir WritePS (mpJobHeader, pUserName); 424*cdf0e10cSrcweir WritePS (mpJobHeader, ")\n"); 425*cdf0e10cSrcweir } 426*cdf0e10cSrcweir 427*cdf0e10cSrcweir // Creation Date (locale independent local time) 428*cdf0e10cSrcweir sal_Char pCreationDate [256]; 429*cdf0e10cSrcweir WritePS (mpJobHeader, "%%CreationDate: ("); 430*cdf0e10cSrcweir getLocalTime(pCreationDate); 431*cdf0e10cSrcweir for( unsigned int i = 0; i < sizeof(pCreationDate)/sizeof(pCreationDate[0]); i++ ) 432*cdf0e10cSrcweir { 433*cdf0e10cSrcweir if( pCreationDate[i] == '\n' ) 434*cdf0e10cSrcweir { 435*cdf0e10cSrcweir pCreationDate[i] = 0; 436*cdf0e10cSrcweir break; 437*cdf0e10cSrcweir } 438*cdf0e10cSrcweir } 439*cdf0e10cSrcweir WritePS (mpJobHeader, pCreationDate ); 440*cdf0e10cSrcweir WritePS (mpJobHeader, ")\n"); 441*cdf0e10cSrcweir 442*cdf0e10cSrcweir // Document Title 443*cdf0e10cSrcweir /* #i74335# 444*cdf0e10cSrcweir * The title should be clean ascii; rJobName however may 445*cdf0e10cSrcweir * contain any Unicode character. So implement the following 446*cdf0e10cSrcweir * algorithm: 447*cdf0e10cSrcweir * use rJobName, if it contains only ascii 448*cdf0e10cSrcweir * use the filename, if it contains only ascii 449*cdf0e10cSrcweir * else omit %%Title 450*cdf0e10cSrcweir */ 451*cdf0e10cSrcweir aFilterWS = WhitespaceToSpace( rJobName, sal_False ); 452*cdf0e10cSrcweir rtl::OUString aTitle( aFilterWS ); 453*cdf0e10cSrcweir if( ! isAscii( aTitle ) ) 454*cdf0e10cSrcweir { 455*cdf0e10cSrcweir sal_Int32 nIndex = 0; 456*cdf0e10cSrcweir while( nIndex != -1 ) 457*cdf0e10cSrcweir aTitle = rFileName.getToken( 0, '/', nIndex ); 458*cdf0e10cSrcweir aTitle = WhitespaceToSpace( aTitle, sal_False ); 459*cdf0e10cSrcweir if( ! isAscii( aTitle ) ) 460*cdf0e10cSrcweir aTitle = rtl::OUString(); 461*cdf0e10cSrcweir } 462*cdf0e10cSrcweir 463*cdf0e10cSrcweir maJobTitle = aFilterWS; 464*cdf0e10cSrcweir if( aTitle.getLength() ) 465*cdf0e10cSrcweir { 466*cdf0e10cSrcweir WritePS (mpJobHeader, "%%Title: ("); 467*cdf0e10cSrcweir WritePS (mpJobHeader, aTitle); 468*cdf0e10cSrcweir WritePS (mpJobHeader, ")\n"); 469*cdf0e10cSrcweir } 470*cdf0e10cSrcweir 471*cdf0e10cSrcweir // Language Level 472*cdf0e10cSrcweir sal_Char pLevel[16]; 473*cdf0e10cSrcweir sal_Int32 nSz = getValueOf(GetPostscriptLevel(&rSetupData), pLevel); 474*cdf0e10cSrcweir pLevel[nSz++] = '\n'; 475*cdf0e10cSrcweir pLevel[nSz ] = '\0'; 476*cdf0e10cSrcweir WritePS (mpJobHeader, "%%LanguageLevel: "); 477*cdf0e10cSrcweir WritePS (mpJobHeader, pLevel); 478*cdf0e10cSrcweir 479*cdf0e10cSrcweir // Other 480*cdf0e10cSrcweir WritePS (mpJobHeader, "%%DocumentData: Clean7Bit\n"); 481*cdf0e10cSrcweir WritePS (mpJobHeader, "%%Pages: (atend)\n"); 482*cdf0e10cSrcweir WritePS (mpJobHeader, "%%Orientation: (atend)\n"); 483*cdf0e10cSrcweir WritePS (mpJobHeader, "%%PageOrder: Ascend\n"); 484*cdf0e10cSrcweir WritePS (mpJobHeader, "%%EndComments\n"); 485*cdf0e10cSrcweir 486*cdf0e10cSrcweir // write Prolog 487*cdf0e10cSrcweir writeProlog (mpJobHeader, rSetupData); 488*cdf0e10cSrcweir 489*cdf0e10cSrcweir // mark last job setup as not set 490*cdf0e10cSrcweir m_aLastJobData.m_pParser = NULL; 491*cdf0e10cSrcweir m_aLastJobData.m_aContext.setParser( NULL ); 492*cdf0e10cSrcweir 493*cdf0e10cSrcweir return sal_True; 494*cdf0e10cSrcweir } 495*cdf0e10cSrcweir 496*cdf0e10cSrcweir sal_Bool 497*cdf0e10cSrcweir PrinterJob::EndJob () 498*cdf0e10cSrcweir { 499*cdf0e10cSrcweir // no pages ? that really means no print job 500*cdf0e10cSrcweir if( maPageList.empty() ) 501*cdf0e10cSrcweir return sal_False; 502*cdf0e10cSrcweir 503*cdf0e10cSrcweir // write document setup (done here because it 504*cdf0e10cSrcweir // includes the accumulated fonts 505*cdf0e10cSrcweir if( mpJobHeader ) 506*cdf0e10cSrcweir writeSetup( mpJobHeader, m_aDocumentJobData ); 507*cdf0e10cSrcweir m_pGraphics->OnEndJob(); 508*cdf0e10cSrcweir if( ! (mpJobHeader && mpJobTrailer) ) 509*cdf0e10cSrcweir return sal_False; 510*cdf0e10cSrcweir 511*cdf0e10cSrcweir // write document trailer according to Document Structuring Conventions (DSC) 512*cdf0e10cSrcweir rtl::OStringBuffer aTrailer(512); 513*cdf0e10cSrcweir aTrailer.append( "%%Trailer\n" ); 514*cdf0e10cSrcweir aTrailer.append( "%%BoundingBox: 0 0 " ); 515*cdf0e10cSrcweir aTrailer.append( (sal_Int32)mnMaxWidthPt ); 516*cdf0e10cSrcweir aTrailer.append( " " ); 517*cdf0e10cSrcweir aTrailer.append( (sal_Int32)mnMaxHeightPt ); 518*cdf0e10cSrcweir if( mnLandscapes > mnPortraits ) 519*cdf0e10cSrcweir aTrailer.append("\n%%Orientation: Landscape"); 520*cdf0e10cSrcweir else 521*cdf0e10cSrcweir aTrailer.append("\n%%Orientation: Portrait"); 522*cdf0e10cSrcweir aTrailer.append( "\n%%Pages: " ); 523*cdf0e10cSrcweir aTrailer.append( (sal_Int32)maPageList.size() ); 524*cdf0e10cSrcweir aTrailer.append( "\n%%EOF\n" ); 525*cdf0e10cSrcweir WritePS (mpJobTrailer, aTrailer.getStr()); 526*cdf0e10cSrcweir 527*cdf0e10cSrcweir /* 528*cdf0e10cSrcweir * spool the set of files to their final destination, this is U**X dependent 529*cdf0e10cSrcweir */ 530*cdf0e10cSrcweir 531*cdf0e10cSrcweir FILE* pDestFILE = NULL; 532*cdf0e10cSrcweir 533*cdf0e10cSrcweir /* create a destination either as file or as a pipe */ 534*cdf0e10cSrcweir sal_Bool bSpoolToFile = maFileName.getLength() > 0 ? sal_True : sal_False; 535*cdf0e10cSrcweir if (bSpoolToFile) 536*cdf0e10cSrcweir { 537*cdf0e10cSrcweir const rtl::OString aFileName = rtl::OUStringToOString (maFileName, 538*cdf0e10cSrcweir osl_getThreadTextEncoding()); 539*cdf0e10cSrcweir if( mnFileMode ) 540*cdf0e10cSrcweir { 541*cdf0e10cSrcweir int nFile = open( aFileName.getStr(), O_CREAT | O_EXCL | O_RDWR, mnFileMode ); 542*cdf0e10cSrcweir if( nFile != -1 ) 543*cdf0e10cSrcweir { 544*cdf0e10cSrcweir pDestFILE = fdopen( nFile, "w" ); 545*cdf0e10cSrcweir if( pDestFILE == NULL ) 546*cdf0e10cSrcweir { 547*cdf0e10cSrcweir close( nFile ); 548*cdf0e10cSrcweir unlink( aFileName.getStr() ); 549*cdf0e10cSrcweir return sal_False; 550*cdf0e10cSrcweir } 551*cdf0e10cSrcweir } 552*cdf0e10cSrcweir else 553*cdf0e10cSrcweir chmod( aFileName.getStr(), mnFileMode ); 554*cdf0e10cSrcweir } 555*cdf0e10cSrcweir if (pDestFILE == NULL) 556*cdf0e10cSrcweir pDestFILE = fopen (aFileName.getStr(), "w"); 557*cdf0e10cSrcweir 558*cdf0e10cSrcweir if (pDestFILE == NULL) 559*cdf0e10cSrcweir return sal_False; 560*cdf0e10cSrcweir } 561*cdf0e10cSrcweir else 562*cdf0e10cSrcweir { 563*cdf0e10cSrcweir PrinterInfoManager& rPrinterInfoManager = PrinterInfoManager::get (); 564*cdf0e10cSrcweir pDestFILE = rPrinterInfoManager.startSpool( m_aLastJobData.m_aPrinterName, m_bQuickJob ); 565*cdf0e10cSrcweir if (pDestFILE == NULL) 566*cdf0e10cSrcweir return sal_False; 567*cdf0e10cSrcweir } 568*cdf0e10cSrcweir 569*cdf0e10cSrcweir /* spool the document parts to the destination */ 570*cdf0e10cSrcweir 571*cdf0e10cSrcweir sal_uChar pBuffer[ nBLOCKSIZE ]; 572*cdf0e10cSrcweir 573*cdf0e10cSrcweir AppendPS (pDestFILE, mpJobHeader, pBuffer); 574*cdf0e10cSrcweir mpJobHeader->close(); 575*cdf0e10cSrcweir 576*cdf0e10cSrcweir sal_Bool bSuccess = sal_True; 577*cdf0e10cSrcweir std::list< osl::File* >::iterator pPageBody; 578*cdf0e10cSrcweir std::list< osl::File* >::iterator pPageHead; 579*cdf0e10cSrcweir for (pPageBody = maPageList.begin(), pPageHead = maHeaderList.begin(); 580*cdf0e10cSrcweir pPageBody != maPageList.end() && pPageHead != maHeaderList.end(); 581*cdf0e10cSrcweir pPageBody++, pPageHead++) 582*cdf0e10cSrcweir { 583*cdf0e10cSrcweir if( *pPageHead ) 584*cdf0e10cSrcweir { 585*cdf0e10cSrcweir osl::File::RC nError = (*pPageHead)->open(OpenFlag_Read); 586*cdf0e10cSrcweir if (nError == osl::File::E_None) 587*cdf0e10cSrcweir { 588*cdf0e10cSrcweir AppendPS (pDestFILE, *pPageHead, pBuffer); 589*cdf0e10cSrcweir (*pPageHead)->close(); 590*cdf0e10cSrcweir } 591*cdf0e10cSrcweir } 592*cdf0e10cSrcweir else 593*cdf0e10cSrcweir bSuccess = sal_False; 594*cdf0e10cSrcweir if( *pPageBody ) 595*cdf0e10cSrcweir { 596*cdf0e10cSrcweir osl::File::RC nError = (*pPageBody)->open(OpenFlag_Read); 597*cdf0e10cSrcweir if (nError == osl::File::E_None) 598*cdf0e10cSrcweir { 599*cdf0e10cSrcweir AppendPS (pDestFILE, *pPageBody, pBuffer); 600*cdf0e10cSrcweir (*pPageBody)->close(); 601*cdf0e10cSrcweir } 602*cdf0e10cSrcweir } 603*cdf0e10cSrcweir else 604*cdf0e10cSrcweir bSuccess = sal_False; 605*cdf0e10cSrcweir } 606*cdf0e10cSrcweir 607*cdf0e10cSrcweir AppendPS (pDestFILE, mpJobTrailer, pBuffer); 608*cdf0e10cSrcweir mpJobTrailer->close(); 609*cdf0e10cSrcweir 610*cdf0e10cSrcweir /* well done */ 611*cdf0e10cSrcweir 612*cdf0e10cSrcweir if (bSpoolToFile) 613*cdf0e10cSrcweir fclose (pDestFILE); 614*cdf0e10cSrcweir else 615*cdf0e10cSrcweir { 616*cdf0e10cSrcweir PrinterInfoManager& rPrinterInfoManager = PrinterInfoManager::get(); 617*cdf0e10cSrcweir if (0 == rPrinterInfoManager.endSpool( m_aLastJobData.m_aPrinterName, 618*cdf0e10cSrcweir maJobTitle, pDestFILE, m_aDocumentJobData, true )) 619*cdf0e10cSrcweir { 620*cdf0e10cSrcweir bSuccess = sal_False; 621*cdf0e10cSrcweir } 622*cdf0e10cSrcweir } 623*cdf0e10cSrcweir 624*cdf0e10cSrcweir return bSuccess; 625*cdf0e10cSrcweir } 626*cdf0e10cSrcweir 627*cdf0e10cSrcweir sal_Bool 628*cdf0e10cSrcweir PrinterJob::AbortJob () 629*cdf0e10cSrcweir { 630*cdf0e10cSrcweir m_pGraphics->OnEndJob(); 631*cdf0e10cSrcweir return sal_False; 632*cdf0e10cSrcweir } 633*cdf0e10cSrcweir 634*cdf0e10cSrcweir void 635*cdf0e10cSrcweir PrinterJob::InitPaperSize (const JobData& rJobSetup) 636*cdf0e10cSrcweir { 637*cdf0e10cSrcweir int nRes = rJobSetup.m_aContext.getRenderResolution (); 638*cdf0e10cSrcweir 639*cdf0e10cSrcweir String aPaper; 640*cdf0e10cSrcweir int nWidth, nHeight; 641*cdf0e10cSrcweir rJobSetup.m_aContext.getPageSize (aPaper, nWidth, nHeight); 642*cdf0e10cSrcweir 643*cdf0e10cSrcweir int nLeft = 0, nRight = 0, nUpper = 0, nLower = 0; 644*cdf0e10cSrcweir const PPDParser* pParser = rJobSetup.m_aContext.getParser(); 645*cdf0e10cSrcweir if (pParser != NULL) 646*cdf0e10cSrcweir pParser->getMargins (aPaper, nLeft, nRight, nUpper, nLower); 647*cdf0e10cSrcweir 648*cdf0e10cSrcweir mnResolution = nRes; 649*cdf0e10cSrcweir 650*cdf0e10cSrcweir mnWidthPt = nWidth; 651*cdf0e10cSrcweir mnHeightPt = nHeight; 652*cdf0e10cSrcweir 653*cdf0e10cSrcweir if( mnWidthPt > mnMaxWidthPt ) 654*cdf0e10cSrcweir mnMaxWidthPt = mnWidthPt; 655*cdf0e10cSrcweir if( mnHeightPt > mnMaxHeightPt ) 656*cdf0e10cSrcweir mnMaxHeightPt = mnHeightPt; 657*cdf0e10cSrcweir 658*cdf0e10cSrcweir mnLMarginPt = nLeft; 659*cdf0e10cSrcweir mnRMarginPt = nRight; 660*cdf0e10cSrcweir mnTMarginPt = nUpper; 661*cdf0e10cSrcweir mnBMarginPt = nLower; 662*cdf0e10cSrcweir 663*cdf0e10cSrcweir mfXScale = (double)72.0 / (double)mnResolution; 664*cdf0e10cSrcweir mfYScale = -1.0 * (double)72.0 / (double)mnResolution; 665*cdf0e10cSrcweir } 666*cdf0e10cSrcweir 667*cdf0e10cSrcweir 668*cdf0e10cSrcweir sal_Bool 669*cdf0e10cSrcweir PrinterJob::StartPage (const JobData& rJobSetup) 670*cdf0e10cSrcweir { 671*cdf0e10cSrcweir InitPaperSize (rJobSetup); 672*cdf0e10cSrcweir 673*cdf0e10cSrcweir rtl::OUString aPageNo = rtl::OUString::valueOf ((sal_Int32)maPageList.size()+1); // sequential page number must start with 1 674*cdf0e10cSrcweir rtl::OUString aExt = aPageNo + rtl::OUString::createFromAscii (".ps"); 675*cdf0e10cSrcweir 676*cdf0e10cSrcweir osl::File* pPageHeader = CreateSpoolFile ( 677*cdf0e10cSrcweir rtl::OUString::createFromAscii("psp_pghead"), aExt); 678*cdf0e10cSrcweir osl::File* pPageBody = CreateSpoolFile ( 679*cdf0e10cSrcweir rtl::OUString::createFromAscii("psp_pgbody"), aExt); 680*cdf0e10cSrcweir 681*cdf0e10cSrcweir maHeaderList.push_back (pPageHeader); 682*cdf0e10cSrcweir maPageList.push_back (pPageBody); 683*cdf0e10cSrcweir 684*cdf0e10cSrcweir if( ! (pPageHeader && pPageBody) ) 685*cdf0e10cSrcweir return sal_False; 686*cdf0e10cSrcweir 687*cdf0e10cSrcweir // write page header according to Document Structuring Conventions (DSC) 688*cdf0e10cSrcweir WritePS (pPageHeader, "%%Page: "); 689*cdf0e10cSrcweir WritePS (pPageHeader, aPageNo); 690*cdf0e10cSrcweir WritePS (pPageHeader, " "); 691*cdf0e10cSrcweir WritePS (pPageHeader, aPageNo); 692*cdf0e10cSrcweir WritePS (pPageHeader, "\n"); 693*cdf0e10cSrcweir 694*cdf0e10cSrcweir if( rJobSetup.m_eOrientation == orientation::Landscape ) 695*cdf0e10cSrcweir { 696*cdf0e10cSrcweir WritePS (pPageHeader, "%%PageOrientation: Landscape\n"); 697*cdf0e10cSrcweir mnLandscapes++; 698*cdf0e10cSrcweir } 699*cdf0e10cSrcweir else 700*cdf0e10cSrcweir { 701*cdf0e10cSrcweir WritePS (pPageHeader, "%%PageOrientation: Portrait\n"); 702*cdf0e10cSrcweir mnPortraits++; 703*cdf0e10cSrcweir } 704*cdf0e10cSrcweir 705*cdf0e10cSrcweir sal_Char pBBox [256]; 706*cdf0e10cSrcweir sal_Int32 nChar = 0; 707*cdf0e10cSrcweir 708*cdf0e10cSrcweir nChar = psp::appendStr ("%%PageBoundingBox: ", pBBox); 709*cdf0e10cSrcweir nChar += psp::getValueOf (mnLMarginPt, pBBox + nChar); 710*cdf0e10cSrcweir nChar += psp::appendStr (" ", pBBox + nChar); 711*cdf0e10cSrcweir nChar += psp::getValueOf (mnBMarginPt, pBBox + nChar); 712*cdf0e10cSrcweir nChar += psp::appendStr (" ", pBBox + nChar); 713*cdf0e10cSrcweir nChar += psp::getValueOf (mnWidthPt - mnRMarginPt, pBBox + nChar); 714*cdf0e10cSrcweir nChar += psp::appendStr (" ", pBBox + nChar); 715*cdf0e10cSrcweir nChar += psp::getValueOf (mnHeightPt - mnTMarginPt, pBBox + nChar); 716*cdf0e10cSrcweir nChar += psp::appendStr ("\n", pBBox + nChar); 717*cdf0e10cSrcweir 718*cdf0e10cSrcweir WritePS (pPageHeader, pBBox); 719*cdf0e10cSrcweir 720*cdf0e10cSrcweir /* #i7262# #i65491# write setup only before first page 721*cdf0e10cSrcweir * (to %%Begin(End)Setup, instead of %%Begin(End)PageSetup) 722*cdf0e10cSrcweir * don't do this in StartJob since the jobsetup there may be 723*cdf0e10cSrcweir * different. 724*cdf0e10cSrcweir */ 725*cdf0e10cSrcweir bool bWriteFeatures = true; 726*cdf0e10cSrcweir if( 1 == maPageList.size() ) 727*cdf0e10cSrcweir { 728*cdf0e10cSrcweir m_aDocumentJobData = rJobSetup; 729*cdf0e10cSrcweir bWriteFeatures = false; 730*cdf0e10cSrcweir } 731*cdf0e10cSrcweir 732*cdf0e10cSrcweir if ( writePageSetup( pPageHeader, rJobSetup, bWriteFeatures ) ) 733*cdf0e10cSrcweir { 734*cdf0e10cSrcweir m_aLastJobData = rJobSetup; 735*cdf0e10cSrcweir return true; 736*cdf0e10cSrcweir } 737*cdf0e10cSrcweir 738*cdf0e10cSrcweir return false; 739*cdf0e10cSrcweir } 740*cdf0e10cSrcweir 741*cdf0e10cSrcweir sal_Bool 742*cdf0e10cSrcweir PrinterJob::EndPage () 743*cdf0e10cSrcweir { 744*cdf0e10cSrcweir m_pGraphics->OnEndPage(); 745*cdf0e10cSrcweir 746*cdf0e10cSrcweir osl::File* pPageHeader = maHeaderList.back(); 747*cdf0e10cSrcweir osl::File* pPageBody = maPageList.back(); 748*cdf0e10cSrcweir 749*cdf0e10cSrcweir if( ! (pPageBody && pPageHeader) ) 750*cdf0e10cSrcweir return sal_False; 751*cdf0e10cSrcweir 752*cdf0e10cSrcweir // copy page to paper and write page trailer according to DSC 753*cdf0e10cSrcweir 754*cdf0e10cSrcweir sal_Char pTrailer[256]; 755*cdf0e10cSrcweir sal_Int32 nChar = 0; 756*cdf0e10cSrcweir nChar = psp::appendStr ("grestore grestore\n", pTrailer); 757*cdf0e10cSrcweir nChar += psp::appendStr ("showpage\n", pTrailer + nChar); 758*cdf0e10cSrcweir nChar += psp::appendStr ("%%PageTrailer\n\n", pTrailer + nChar); 759*cdf0e10cSrcweir WritePS (pPageBody, pTrailer); 760*cdf0e10cSrcweir 761*cdf0e10cSrcweir // this page is done for now, close it to avoid having too many open fd's 762*cdf0e10cSrcweir 763*cdf0e10cSrcweir pPageHeader->close(); 764*cdf0e10cSrcweir pPageBody->close(); 765*cdf0e10cSrcweir 766*cdf0e10cSrcweir return sal_True; 767*cdf0e10cSrcweir } 768*cdf0e10cSrcweir 769*cdf0e10cSrcweir sal_uInt32 770*cdf0e10cSrcweir PrinterJob::GetErrorCode () 771*cdf0e10cSrcweir { 772*cdf0e10cSrcweir /* TODO */ 773*cdf0e10cSrcweir return 0; 774*cdf0e10cSrcweir } 775*cdf0e10cSrcweir 776*cdf0e10cSrcweir struct less_ppd_key : public ::std::binary_function<double, double, bool> 777*cdf0e10cSrcweir { 778*cdf0e10cSrcweir bool operator()(const PPDKey* left, const PPDKey* right) 779*cdf0e10cSrcweir { return left->getOrderDependency() < right->getOrderDependency(); } 780*cdf0e10cSrcweir }; 781*cdf0e10cSrcweir 782*cdf0e10cSrcweir static bool writeFeature( osl::File* pFile, const PPDKey* pKey, const PPDValue* pValue, bool bUseIncluseFeature ) 783*cdf0e10cSrcweir { 784*cdf0e10cSrcweir if( ! pKey || ! pValue ) 785*cdf0e10cSrcweir return true; 786*cdf0e10cSrcweir 787*cdf0e10cSrcweir OStringBuffer aFeature(256); 788*cdf0e10cSrcweir aFeature.append( "[{\n" ); 789*cdf0e10cSrcweir if( bUseIncluseFeature ) 790*cdf0e10cSrcweir aFeature.append( "%%IncludeFeature:" ); 791*cdf0e10cSrcweir else 792*cdf0e10cSrcweir aFeature.append( "%%BeginFeature:" ); 793*cdf0e10cSrcweir aFeature.append( " *" ); 794*cdf0e10cSrcweir aFeature.append( OUStringToOString( pKey->getKey(), RTL_TEXTENCODING_ASCII_US ) ); 795*cdf0e10cSrcweir aFeature.append( ' ' ); 796*cdf0e10cSrcweir aFeature.append( OUStringToOString( pValue->m_aOption, RTL_TEXTENCODING_ASCII_US ) ); 797*cdf0e10cSrcweir if( !bUseIncluseFeature ) 798*cdf0e10cSrcweir { 799*cdf0e10cSrcweir aFeature.append( '\n' ); 800*cdf0e10cSrcweir aFeature.append( OUStringToOString( pValue->m_aValue, RTL_TEXTENCODING_ASCII_US ) ); 801*cdf0e10cSrcweir aFeature.append( "\n%%EndFeature" ); 802*cdf0e10cSrcweir } 803*cdf0e10cSrcweir aFeature.append( "\n} stopped cleartomark\n" ); 804*cdf0e10cSrcweir sal_uInt64 nWritten = 0; 805*cdf0e10cSrcweir return pFile->write( aFeature.getStr(), aFeature.getLength(), nWritten ) 806*cdf0e10cSrcweir || nWritten != (sal_uInt64)aFeature.getLength() ? false : true; 807*cdf0e10cSrcweir } 808*cdf0e10cSrcweir 809*cdf0e10cSrcweir bool PrinterJob::writeFeatureList( osl::File* pFile, const JobData& rJob, bool bDocumentSetup ) 810*cdf0e10cSrcweir { 811*cdf0e10cSrcweir bool bSuccess = true; 812*cdf0e10cSrcweir int i; 813*cdf0e10cSrcweir 814*cdf0e10cSrcweir // emit features ordered to OrderDependency 815*cdf0e10cSrcweir // ignore features that are set to default 816*cdf0e10cSrcweir 817*cdf0e10cSrcweir // sanity check 818*cdf0e10cSrcweir if( rJob.m_pParser == rJob.m_aContext.getParser() && 819*cdf0e10cSrcweir rJob.m_pParser && 820*cdf0e10cSrcweir ( m_aLastJobData.m_pParser == rJob.m_pParser || m_aLastJobData.m_pParser == NULL ) 821*cdf0e10cSrcweir ) 822*cdf0e10cSrcweir { 823*cdf0e10cSrcweir int nKeys = rJob.m_aContext.countValuesModified(); 824*cdf0e10cSrcweir ::std::vector< const PPDKey* > aKeys( nKeys ); 825*cdf0e10cSrcweir for( i = 0; i < nKeys; i++ ) 826*cdf0e10cSrcweir aKeys[i] = rJob.m_aContext.getModifiedKey( i ); 827*cdf0e10cSrcweir ::std::sort( aKeys.begin(), aKeys.end(), less_ppd_key() ); 828*cdf0e10cSrcweir 829*cdf0e10cSrcweir for( i = 0; i < nKeys && bSuccess; i++ ) 830*cdf0e10cSrcweir { 831*cdf0e10cSrcweir const PPDKey* pKey = aKeys[i]; 832*cdf0e10cSrcweir bool bEmit = false; 833*cdf0e10cSrcweir if( bDocumentSetup ) 834*cdf0e10cSrcweir { 835*cdf0e10cSrcweir if( pKey->getSetupType() == PPDKey::DocumentSetup ) 836*cdf0e10cSrcweir bEmit = true; 837*cdf0e10cSrcweir } 838*cdf0e10cSrcweir if( pKey->getSetupType() == PPDKey::PageSetup || 839*cdf0e10cSrcweir pKey->getSetupType() == PPDKey::AnySetup ) 840*cdf0e10cSrcweir bEmit = true; 841*cdf0e10cSrcweir if( bEmit ) 842*cdf0e10cSrcweir { 843*cdf0e10cSrcweir const PPDValue* pValue = rJob.m_aContext.getValue( pKey ); 844*cdf0e10cSrcweir if( pValue 845*cdf0e10cSrcweir && pValue->m_eType == eInvocation 846*cdf0e10cSrcweir && ( m_aLastJobData.m_pParser == NULL 847*cdf0e10cSrcweir || m_aLastJobData.m_aContext.getValue( pKey ) != pValue 848*cdf0e10cSrcweir || bDocumentSetup 849*cdf0e10cSrcweir ) 850*cdf0e10cSrcweir ) 851*cdf0e10cSrcweir { 852*cdf0e10cSrcweir // try to avoid PS level 2 feature commands if level is set to 1 853*cdf0e10cSrcweir if( GetPostscriptLevel( &rJob ) == 1 ) 854*cdf0e10cSrcweir { 855*cdf0e10cSrcweir bool bHavePS2 = 856*cdf0e10cSrcweir ( pValue->m_aValue.SearchAscii( "<<" ) != STRING_NOTFOUND ) 857*cdf0e10cSrcweir || 858*cdf0e10cSrcweir ( pValue->m_aValue.SearchAscii( ">>" ) != STRING_NOTFOUND ); 859*cdf0e10cSrcweir if( bHavePS2 ) 860*cdf0e10cSrcweir continue; 861*cdf0e10cSrcweir } 862*cdf0e10cSrcweir bSuccess = writeFeature( pFile, pKey, pValue, PrinterInfoManager::get().getUseIncludeFeature() ); 863*cdf0e10cSrcweir } 864*cdf0e10cSrcweir } 865*cdf0e10cSrcweir } 866*cdf0e10cSrcweir } 867*cdf0e10cSrcweir else 868*cdf0e10cSrcweir bSuccess = false; 869*cdf0e10cSrcweir 870*cdf0e10cSrcweir return bSuccess; 871*cdf0e10cSrcweir } 872*cdf0e10cSrcweir 873*cdf0e10cSrcweir bool PrinterJob::writePageSetup( osl::File* pFile, const JobData& rJob, bool bWriteFeatures ) 874*cdf0e10cSrcweir { 875*cdf0e10cSrcweir bool bSuccess = true; 876*cdf0e10cSrcweir 877*cdf0e10cSrcweir WritePS (pFile, "%%BeginPageSetup\n%\n"); 878*cdf0e10cSrcweir if ( bWriteFeatures ) 879*cdf0e10cSrcweir bSuccess = writeFeatureList( pFile, rJob, false ); 880*cdf0e10cSrcweir WritePS (pFile, "%%EndPageSetup\n"); 881*cdf0e10cSrcweir 882*cdf0e10cSrcweir sal_Char pTranslate [128]; 883*cdf0e10cSrcweir sal_Int32 nChar = 0; 884*cdf0e10cSrcweir 885*cdf0e10cSrcweir if( rJob.m_eOrientation == orientation::Portrait ) 886*cdf0e10cSrcweir { 887*cdf0e10cSrcweir nChar = psp::appendStr ("gsave\n[", pTranslate); 888*cdf0e10cSrcweir nChar += psp::getValueOfDouble ( pTranslate + nChar, mfXScale, 5); 889*cdf0e10cSrcweir nChar += psp::appendStr (" 0 0 ", pTranslate + nChar); 890*cdf0e10cSrcweir nChar += psp::getValueOfDouble ( pTranslate + nChar, mfYScale, 5); 891*cdf0e10cSrcweir nChar += psp::appendStr (" ", pTranslate + nChar); 892*cdf0e10cSrcweir nChar += psp::getValueOf (mnRMarginPt, pTranslate + nChar); 893*cdf0e10cSrcweir nChar += psp::appendStr (" ", pTranslate + nChar); 894*cdf0e10cSrcweir nChar += psp::getValueOf (mnHeightPt-mnTMarginPt, 895*cdf0e10cSrcweir pTranslate + nChar); 896*cdf0e10cSrcweir nChar += psp::appendStr ("] concat\ngsave\n", 897*cdf0e10cSrcweir pTranslate + nChar); 898*cdf0e10cSrcweir } 899*cdf0e10cSrcweir else 900*cdf0e10cSrcweir { 901*cdf0e10cSrcweir nChar = psp::appendStr ("gsave\n", pTranslate); 902*cdf0e10cSrcweir nChar += psp::appendStr ("[ 0 ", pTranslate + nChar); 903*cdf0e10cSrcweir nChar += psp::getValueOfDouble ( pTranslate + nChar, -mfYScale, 5); 904*cdf0e10cSrcweir nChar += psp::appendStr (" ", pTranslate + nChar); 905*cdf0e10cSrcweir nChar += psp::getValueOfDouble ( pTranslate + nChar, mfXScale, 5); 906*cdf0e10cSrcweir nChar += psp::appendStr (" 0 ", pTranslate + nChar ); 907*cdf0e10cSrcweir nChar += psp::getValueOfDouble ( pTranslate + nChar, mnLMarginPt, 5 ); 908*cdf0e10cSrcweir nChar += psp::appendStr (" ", pTranslate + nChar); 909*cdf0e10cSrcweir nChar += psp::getValueOf (mnBMarginPt, pTranslate + nChar ); 910*cdf0e10cSrcweir nChar += psp::appendStr ("] concat\ngsave\n", 911*cdf0e10cSrcweir pTranslate + nChar); 912*cdf0e10cSrcweir } 913*cdf0e10cSrcweir 914*cdf0e10cSrcweir WritePS (pFile, pTranslate); 915*cdf0e10cSrcweir 916*cdf0e10cSrcweir return bSuccess; 917*cdf0e10cSrcweir } 918*cdf0e10cSrcweir 919*cdf0e10cSrcweir void PrinterJob::writeJobPatch( osl::File* pFile, const JobData& rJobData ) 920*cdf0e10cSrcweir { 921*cdf0e10cSrcweir if( ! PrinterInfoManager::get().getUseJobPatch() ) 922*cdf0e10cSrcweir return; 923*cdf0e10cSrcweir 924*cdf0e10cSrcweir const PPDKey* pKey = NULL; 925*cdf0e10cSrcweir 926*cdf0e10cSrcweir if( rJobData.m_pParser ) 927*cdf0e10cSrcweir pKey = rJobData.m_pParser->getKey( OUString( RTL_CONSTASCII_USTRINGPARAM( "JobPatchFile" ) ) ); 928*cdf0e10cSrcweir if( ! pKey ) 929*cdf0e10cSrcweir return; 930*cdf0e10cSrcweir 931*cdf0e10cSrcweir // order the patch files 932*cdf0e10cSrcweir // according to PPD spec the JobPatchFile options must be int 933*cdf0e10cSrcweir // and should be emitted in order 934*cdf0e10cSrcweir std::list< sal_Int32 > patch_order; 935*cdf0e10cSrcweir int nValueCount = pKey->countValues(); 936*cdf0e10cSrcweir for( int i = 0; i < nValueCount; i++ ) 937*cdf0e10cSrcweir { 938*cdf0e10cSrcweir const PPDValue* pVal = pKey->getValue( i ); 939*cdf0e10cSrcweir patch_order.push_back( pVal->m_aOption.ToInt32() ); 940*cdf0e10cSrcweir if( patch_order.back() == 0 && ! pVal->m_aOption.EqualsAscii( "0" ) ) 941*cdf0e10cSrcweir { 942*cdf0e10cSrcweir WritePS( pFile, "% Warning: left out JobPatchFile option \"" ); 943*cdf0e10cSrcweir OString aOption = OUStringToOString( pVal->m_aOption, RTL_TEXTENCODING_ASCII_US ); 944*cdf0e10cSrcweir WritePS( pFile, aOption.getStr() ); 945*cdf0e10cSrcweir WritePS( pFile, 946*cdf0e10cSrcweir "\"\n% as it violates the PPD spec;\n" 947*cdf0e10cSrcweir "% JobPatchFile options need to be numbered for ordering.\n" ); 948*cdf0e10cSrcweir } 949*cdf0e10cSrcweir } 950*cdf0e10cSrcweir 951*cdf0e10cSrcweir patch_order.sort(); 952*cdf0e10cSrcweir patch_order.unique(); 953*cdf0e10cSrcweir 954*cdf0e10cSrcweir while( patch_order.begin() != patch_order.end() ) 955*cdf0e10cSrcweir { 956*cdf0e10cSrcweir // note: this discards patch files not adhering to the "int" scheme 957*cdf0e10cSrcweir // as there won't be a value for them 958*cdf0e10cSrcweir writeFeature( pFile, pKey, pKey->getValue( OUString::valueOf( patch_order.front() ) ), false ); 959*cdf0e10cSrcweir patch_order.pop_front(); 960*cdf0e10cSrcweir } 961*cdf0e10cSrcweir } 962*cdf0e10cSrcweir 963*cdf0e10cSrcweir bool PrinterJob::writeProlog (osl::File* pFile, const JobData& rJobData ) 964*cdf0e10cSrcweir { 965*cdf0e10cSrcweir WritePS( pFile, "%%BeginProlog\n" ); 966*cdf0e10cSrcweir 967*cdf0e10cSrcweir // JobPatchFile feature needs to be emitted at begin of prolog 968*cdf0e10cSrcweir writeJobPatch( pFile, rJobData ); 969*cdf0e10cSrcweir 970*cdf0e10cSrcweir static const sal_Char pProlog[] = { 971*cdf0e10cSrcweir "%%BeginResource: procset PSPrint-Prolog 1.0 0\n" 972*cdf0e10cSrcweir "/ISO1252Encoding [\n" 973*cdf0e10cSrcweir "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 974*cdf0e10cSrcweir "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 975*cdf0e10cSrcweir "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 976*cdf0e10cSrcweir "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 977*cdf0e10cSrcweir "/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n" 978*cdf0e10cSrcweir "/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n" 979*cdf0e10cSrcweir "/zero /one /two /three /four /five /six /seven\n" 980*cdf0e10cSrcweir "/eight /nine /colon /semicolon /less /equal /greater /question\n" 981*cdf0e10cSrcweir "/at /A /B /C /D /E /F /G\n" 982*cdf0e10cSrcweir "/H /I /J /K /L /M /N /O\n" 983*cdf0e10cSrcweir "/P /Q /R /S /T /U /V /W\n" 984*cdf0e10cSrcweir "/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n" 985*cdf0e10cSrcweir "/grave /a /b /c /d /e /f /g\n" 986*cdf0e10cSrcweir "/h /i /j /k /l /m /n /o\n" 987*cdf0e10cSrcweir "/p /q /r /s /t /u /v /w\n" 988*cdf0e10cSrcweir "/x /y /z /braceleft /bar /braceright /asciitilde /unused\n" 989*cdf0e10cSrcweir "/Euro /unused /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl\n" 990*cdf0e10cSrcweir "/circumflex /perthousand /Scaron /guilsinglleft /OE /unused /Zcaron /unused\n" 991*cdf0e10cSrcweir "/unused /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash\n" 992*cdf0e10cSrcweir "/tilde /trademark /scaron /guilsinglright /oe /unused /zcaron /Ydieresis\n" 993*cdf0e10cSrcweir "/space /exclamdown /cent /sterling /currency /yen /brokenbar /section\n" 994*cdf0e10cSrcweir "/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron\n" 995*cdf0e10cSrcweir "/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered\n" 996*cdf0e10cSrcweir "/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown\n" 997*cdf0e10cSrcweir "/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n" 998*cdf0e10cSrcweir "/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis\n" 999*cdf0e10cSrcweir "/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply\n" 1000*cdf0e10cSrcweir "/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls\n" 1001*cdf0e10cSrcweir "/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n" 1002*cdf0e10cSrcweir "/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis\n" 1003*cdf0e10cSrcweir "/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide\n" 1004*cdf0e10cSrcweir "/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] def\n" 1005*cdf0e10cSrcweir "\n" 1006*cdf0e10cSrcweir "/psp_definefont { exch dup findfont dup length dict begin { 1 index /FID ne\n" 1007*cdf0e10cSrcweir "{ def } { pop pop } ifelse } forall /Encoding 3 -1 roll def\n" 1008*cdf0e10cSrcweir "currentdict end exch pop definefont pop } def\n" 1009*cdf0e10cSrcweir "\n" 1010*cdf0e10cSrcweir "/pathdict dup 8 dict def load begin\n" 1011*cdf0e10cSrcweir "/rcmd { { currentfile 1 string readstring pop 0 get dup 32 gt { exit }\n" 1012*cdf0e10cSrcweir "{ pop } ifelse } loop dup 126 eq { pop exit } if 65 sub dup 16#3 and 1\n" 1013*cdf0e10cSrcweir "add exch dup 16#C and -2 bitshift 16#3 and 1 add exch 16#10 and 16#10\n" 1014*cdf0e10cSrcweir "eq 3 1 roll exch } def\n" 1015*cdf0e10cSrcweir "/rhex { dup 1 sub exch currentfile exch string readhexstring pop dup 0\n" 1016*cdf0e10cSrcweir "get dup 16#80 and 16#80 eq dup 3 1 roll { 16#7f and } if 2 index 0 3\n" 1017*cdf0e10cSrcweir "-1 roll put 3 1 roll 0 0 1 5 -1 roll { 2 index exch get add 256 mul }\n" 1018*cdf0e10cSrcweir "for 256 div exch pop exch { neg } if } def\n" 1019*cdf0e10cSrcweir "/xcmd { rcmd exch rhex exch rhex exch 5 -1 roll add exch 4 -1 roll add\n" 1020*cdf0e10cSrcweir "1 index 1 index 5 -1 roll { moveto } { lineto } ifelse } def end\n" 1021*cdf0e10cSrcweir "/readpath { 0 0 pathdict begin { xcmd } loop end pop pop } def\n" 1022*cdf0e10cSrcweir "\n" 1023*cdf0e10cSrcweir "systemdict /languagelevel known not {\n" 1024*cdf0e10cSrcweir "/xshow { exch dup length 0 1 3 -1 roll 1 sub { dup 3 index exch get\n" 1025*cdf0e10cSrcweir "exch 2 index exch get 1 string dup 0 4 -1 roll put currentpoint 3 -1\n" 1026*cdf0e10cSrcweir "roll show moveto 0 rmoveto } for pop pop } def\n" 1027*cdf0e10cSrcweir "/rectangle { 4 -2 roll moveto 1 index 0 rlineto 0 exch rlineto neg 0\n" 1028*cdf0e10cSrcweir "rlineto closepath } def\n" 1029*cdf0e10cSrcweir "/rectfill { rectangle fill } def\n" 1030*cdf0e10cSrcweir "/rectstroke { rectangle stroke } def } if\n" 1031*cdf0e10cSrcweir "/bshow { currentlinewidth 3 1 roll currentpoint 3 index show moveto\n" 1032*cdf0e10cSrcweir "setlinewidth false charpath stroke setlinewidth } def\n" 1033*cdf0e10cSrcweir "/bxshow { currentlinewidth 4 1 roll setlinewidth exch dup length 1 sub\n" 1034*cdf0e10cSrcweir "0 1 3 -1 roll { 1 string 2 index 2 index get 1 index exch 0 exch put dup\n" 1035*cdf0e10cSrcweir "currentpoint 3 -1 roll show moveto currentpoint 3 -1 roll false charpath\n" 1036*cdf0e10cSrcweir "stroke moveto 2 index exch get 0 rmoveto } for pop pop setlinewidth } def\n" 1037*cdf0e10cSrcweir "\n" 1038*cdf0e10cSrcweir "/psp_lzwfilter { currentfile /ASCII85Decode filter /LZWDecode filter } def\n" 1039*cdf0e10cSrcweir "/psp_ascii85filter { currentfile /ASCII85Decode filter } def\n" 1040*cdf0e10cSrcweir "/psp_lzwstring { psp_lzwfilter 1024 string readstring } def\n" 1041*cdf0e10cSrcweir "/psp_ascii85string { psp_ascii85filter 1024 string readstring } def\n" 1042*cdf0e10cSrcweir "/psp_imagedict {\n" 1043*cdf0e10cSrcweir "/psp_bitspercomponent { 3 eq { 1 }{ 8 } ifelse } def\n" 1044*cdf0e10cSrcweir "/psp_decodearray { [ [0 1 0 1 0 1] [0 255] [0 1] [0 255] ] exch get }\n" 1045*cdf0e10cSrcweir "def 7 dict dup\n" 1046*cdf0e10cSrcweir "/ImageType 1 put dup\n" 1047*cdf0e10cSrcweir "/Width 7 -1 roll put dup\n" 1048*cdf0e10cSrcweir "/Height 5 index put dup\n" 1049*cdf0e10cSrcweir "/BitsPerComponent 4 index psp_bitspercomponent put dup\n" 1050*cdf0e10cSrcweir "/Decode 5 -1 roll psp_decodearray put dup\n" 1051*cdf0e10cSrcweir "/ImageMatrix [1 0 0 1 0 0] dup 5 8 -1 roll put put dup\n" 1052*cdf0e10cSrcweir "/DataSource 4 -1 roll 1 eq { psp_lzwfilter } { psp_ascii85filter } ifelse put\n" 1053*cdf0e10cSrcweir "} def\n" 1054*cdf0e10cSrcweir "%%EndResource\n" 1055*cdf0e10cSrcweir "%%EndProlog\n" 1056*cdf0e10cSrcweir }; 1057*cdf0e10cSrcweir static const sal_Char pSO52CompatProlog[] = { 1058*cdf0e10cSrcweir "%%BeginResource: procset PSPrint-Prolog 1.0 0\n" 1059*cdf0e10cSrcweir "/ISO1252Encoding [\n" 1060*cdf0e10cSrcweir "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 1061*cdf0e10cSrcweir "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 1062*cdf0e10cSrcweir "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 1063*cdf0e10cSrcweir "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n" 1064*cdf0e10cSrcweir "/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quoteright\n" 1065*cdf0e10cSrcweir "/parenleft /parenright /asterisk /plus /comma /minus /period /slash\n" 1066*cdf0e10cSrcweir "/zero /one /two /three /four /five /six /seven\n" 1067*cdf0e10cSrcweir "/eight /nine /colon /semicolon /less /equal /greater /question\n" 1068*cdf0e10cSrcweir "/at /A /B /C /D /E /F /G\n" 1069*cdf0e10cSrcweir "/H /I /J /K /L /M /N /O\n" 1070*cdf0e10cSrcweir "/P /Q /R /S /T /U /V /W\n" 1071*cdf0e10cSrcweir "/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n" 1072*cdf0e10cSrcweir "/grave /a /b /c /d /e /f /g\n" 1073*cdf0e10cSrcweir "/h /i /j /k /l /m /n /o\n" 1074*cdf0e10cSrcweir "/p /q /r /s /t /u /v /w\n" 1075*cdf0e10cSrcweir "/x /y /z /braceleft /bar /braceright /asciitilde /unused\n" 1076*cdf0e10cSrcweir "/Euro /unused /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl\n" 1077*cdf0e10cSrcweir "/circumflex /perthousand /Scaron /guilsinglleft /OE /unused /Zcaron /unused\n" 1078*cdf0e10cSrcweir "/unused /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash\n" 1079*cdf0e10cSrcweir "/tilde /trademark /scaron /guilsinglright /oe /unused /zcaron /Ydieresis\n" 1080*cdf0e10cSrcweir "/space /exclamdown /cent /sterling /currency /yen /brokenbar /section\n" 1081*cdf0e10cSrcweir "/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron\n" 1082*cdf0e10cSrcweir "/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered\n" 1083*cdf0e10cSrcweir "/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown\n" 1084*cdf0e10cSrcweir "/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n" 1085*cdf0e10cSrcweir "/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis\n" 1086*cdf0e10cSrcweir "/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply\n" 1087*cdf0e10cSrcweir "/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls\n" 1088*cdf0e10cSrcweir "/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n" 1089*cdf0e10cSrcweir "/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis\n" 1090*cdf0e10cSrcweir "/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide\n" 1091*cdf0e10cSrcweir "/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] def\n" 1092*cdf0e10cSrcweir "\n" 1093*cdf0e10cSrcweir "/psp_definefont { exch dup findfont dup length dict begin { 1 index /FID ne\n" 1094*cdf0e10cSrcweir "{ def } { pop pop } ifelse } forall /Encoding 3 -1 roll def\n" 1095*cdf0e10cSrcweir "currentdict end exch pop definefont pop } def\n" 1096*cdf0e10cSrcweir "\n" 1097*cdf0e10cSrcweir "/pathdict dup 8 dict def load begin\n" 1098*cdf0e10cSrcweir "/rcmd { { currentfile 1 string readstring pop 0 get dup 32 gt { exit }\n" 1099*cdf0e10cSrcweir "{ pop } ifelse } loop dup 126 eq { pop exit } if 65 sub dup 16#3 and 1\n" 1100*cdf0e10cSrcweir "add exch dup 16#C and -2 bitshift 16#3 and 1 add exch 16#10 and 16#10\n" 1101*cdf0e10cSrcweir "eq 3 1 roll exch } def\n" 1102*cdf0e10cSrcweir "/rhex { dup 1 sub exch currentfile exch string readhexstring pop dup 0\n" 1103*cdf0e10cSrcweir "get dup 16#80 and 16#80 eq dup 3 1 roll { 16#7f and } if 2 index 0 3\n" 1104*cdf0e10cSrcweir "-1 roll put 3 1 roll 0 0 1 5 -1 roll { 2 index exch get add 256 mul }\n" 1105*cdf0e10cSrcweir "for 256 div exch pop exch { neg } if } def\n" 1106*cdf0e10cSrcweir "/xcmd { rcmd exch rhex exch rhex exch 5 -1 roll add exch 4 -1 roll add\n" 1107*cdf0e10cSrcweir "1 index 1 index 5 -1 roll { moveto } { lineto } ifelse } def end\n" 1108*cdf0e10cSrcweir "/readpath { 0 0 pathdict begin { xcmd } loop end pop pop } def\n" 1109*cdf0e10cSrcweir "\n" 1110*cdf0e10cSrcweir "systemdict /languagelevel known not {\n" 1111*cdf0e10cSrcweir "/xshow { exch dup length 0 1 3 -1 roll 1 sub { dup 3 index exch get\n" 1112*cdf0e10cSrcweir "exch 2 index exch get 1 string dup 0 4 -1 roll put currentpoint 3 -1\n" 1113*cdf0e10cSrcweir "roll show moveto 0 rmoveto } for pop pop } def\n" 1114*cdf0e10cSrcweir "/rectangle { 4 -2 roll moveto 1 index 0 rlineto 0 exch rlineto neg 0\n" 1115*cdf0e10cSrcweir "rlineto closepath } def\n" 1116*cdf0e10cSrcweir "/rectfill { rectangle fill } def\n" 1117*cdf0e10cSrcweir "/rectstroke { rectangle stroke } def } if\n" 1118*cdf0e10cSrcweir "/bshow { currentlinewidth 3 1 roll currentpoint 3 index show moveto\n" 1119*cdf0e10cSrcweir "setlinewidth false charpath stroke setlinewidth } def\n" 1120*cdf0e10cSrcweir "/bxshow { currentlinewidth 4 1 roll setlinewidth exch dup length 1 sub\n" 1121*cdf0e10cSrcweir "0 1 3 -1 roll { 1 string 2 index 2 index get 1 index exch 0 exch put dup\n" 1122*cdf0e10cSrcweir "currentpoint 3 -1 roll show moveto currentpoint 3 -1 roll false charpath\n" 1123*cdf0e10cSrcweir "stroke moveto 2 index exch get 0 rmoveto } for pop pop setlinewidth } def\n" 1124*cdf0e10cSrcweir "\n" 1125*cdf0e10cSrcweir "/psp_lzwfilter { currentfile /ASCII85Decode filter /LZWDecode filter } def\n" 1126*cdf0e10cSrcweir "/psp_ascii85filter { currentfile /ASCII85Decode filter } def\n" 1127*cdf0e10cSrcweir "/psp_lzwstring { psp_lzwfilter 1024 string readstring } def\n" 1128*cdf0e10cSrcweir "/psp_ascii85string { psp_ascii85filter 1024 string readstring } def\n" 1129*cdf0e10cSrcweir "/psp_imagedict {\n" 1130*cdf0e10cSrcweir "/psp_bitspercomponent { 3 eq { 1 }{ 8 } ifelse } def\n" 1131*cdf0e10cSrcweir "/psp_decodearray { [ [0 1 0 1 0 1] [0 255] [0 1] [0 255] ] exch get }\n" 1132*cdf0e10cSrcweir "def 7 dict dup\n" 1133*cdf0e10cSrcweir "/ImageType 1 put dup\n" 1134*cdf0e10cSrcweir "/Width 7 -1 roll put dup\n" 1135*cdf0e10cSrcweir "/Height 5 index put dup\n" 1136*cdf0e10cSrcweir "/BitsPerComponent 4 index psp_bitspercomponent put dup\n" 1137*cdf0e10cSrcweir "/Decode 5 -1 roll psp_decodearray put dup\n" 1138*cdf0e10cSrcweir "/ImageMatrix [1 0 0 1 0 0] dup 5 8 -1 roll put put dup\n" 1139*cdf0e10cSrcweir "/DataSource 4 -1 roll 1 eq { psp_lzwfilter } { psp_ascii85filter } ifelse put\n" 1140*cdf0e10cSrcweir "} def\n" 1141*cdf0e10cSrcweir "%%EndResource\n" 1142*cdf0e10cSrcweir "%%EndProlog\n" 1143*cdf0e10cSrcweir }; 1144*cdf0e10cSrcweir WritePS (pFile, m_pGraphics && m_pGraphics->getStrictSO52Compatibility() ? pSO52CompatProlog : pProlog); 1145*cdf0e10cSrcweir 1146*cdf0e10cSrcweir return true; 1147*cdf0e10cSrcweir } 1148*cdf0e10cSrcweir 1149*cdf0e10cSrcweir bool PrinterJob::writeSetup( osl::File* pFile, const JobData& rJob ) 1150*cdf0e10cSrcweir { 1151*cdf0e10cSrcweir WritePS (pFile, "%%BeginSetup\n%\n"); 1152*cdf0e10cSrcweir 1153*cdf0e10cSrcweir // download fonts 1154*cdf0e10cSrcweir std::list< rtl::OString > aFonts[2]; 1155*cdf0e10cSrcweir m_pGraphics->writeResources( pFile, aFonts[0], aFonts[1] ); 1156*cdf0e10cSrcweir 1157*cdf0e10cSrcweir for( int i = 0; i < 2; i++ ) 1158*cdf0e10cSrcweir { 1159*cdf0e10cSrcweir if( !aFonts[i].empty() ) 1160*cdf0e10cSrcweir { 1161*cdf0e10cSrcweir std::list< rtl::OString >::const_iterator it = aFonts[i].begin(); 1162*cdf0e10cSrcweir rtl::OStringBuffer aLine( 256 ); 1163*cdf0e10cSrcweir if( i == 0 ) 1164*cdf0e10cSrcweir aLine.append( "%%DocumentSuppliedResources: font " ); 1165*cdf0e10cSrcweir else 1166*cdf0e10cSrcweir aLine.append( "%%DocumentNeededResources: font " ); 1167*cdf0e10cSrcweir aLine.append( *it ); 1168*cdf0e10cSrcweir aLine.append( "\n" ); 1169*cdf0e10cSrcweir WritePS ( pFile, aLine.getStr() ); 1170*cdf0e10cSrcweir while( (++it) != aFonts[i].end() ) 1171*cdf0e10cSrcweir { 1172*cdf0e10cSrcweir aLine.setLength(0); 1173*cdf0e10cSrcweir aLine.append( "%%+ font " ); 1174*cdf0e10cSrcweir aLine.append( *it ); 1175*cdf0e10cSrcweir aLine.append( "\n" ); 1176*cdf0e10cSrcweir WritePS ( pFile, aLine.getStr() ); 1177*cdf0e10cSrcweir } 1178*cdf0e10cSrcweir } 1179*cdf0e10cSrcweir } 1180*cdf0e10cSrcweir 1181*cdf0e10cSrcweir bool bSuccess = true; 1182*cdf0e10cSrcweir // in case of external print dialog the number of copies is prepended 1183*cdf0e10cSrcweir // to the job, let us not complicate things by emitting our own copy count 1184*cdf0e10cSrcweir bool bExternalDialog = PrinterInfoManager::get().checkFeatureToken( GetPrinterName(), "external_dialog" ); 1185*cdf0e10cSrcweir if( ! bExternalDialog && rJob.m_nCopies > 1 ) 1186*cdf0e10cSrcweir { 1187*cdf0e10cSrcweir // setup code 1188*cdf0e10cSrcweir ByteString aLine( "/#copies " ); 1189*cdf0e10cSrcweir aLine += ByteString::CreateFromInt32( rJob.m_nCopies ); 1190*cdf0e10cSrcweir aLine += " def\n"; 1191*cdf0e10cSrcweir sal_uInt64 nWritten = 0; 1192*cdf0e10cSrcweir bSuccess = pFile->write( aLine.GetBuffer(), aLine.Len(), nWritten ) 1193*cdf0e10cSrcweir || nWritten != aLine.Len() ? false : true; 1194*cdf0e10cSrcweir 1195*cdf0e10cSrcweir if( bSuccess && GetPostscriptLevel( &rJob ) >= 2 ) 1196*cdf0e10cSrcweir WritePS (pFile, "<< /NumCopies null /Policies << /NumCopies 1 >> >> setpagedevice\n" ); 1197*cdf0e10cSrcweir } 1198*cdf0e10cSrcweir 1199*cdf0e10cSrcweir bool bFeatureSuccess = writeFeatureList( pFile, rJob, true ); 1200*cdf0e10cSrcweir 1201*cdf0e10cSrcweir WritePS (pFile, "%%EndSetup\n"); 1202*cdf0e10cSrcweir 1203*cdf0e10cSrcweir return bSuccess && bFeatureSuccess; 1204*cdf0e10cSrcweir } 1205