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