1c82f2877SAndrew Rist /**************************************************************
2cdf0e10cSrcweir *
3c82f2877SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one
4c82f2877SAndrew Rist * or more contributor license agreements. See the NOTICE file
5c82f2877SAndrew Rist * distributed with this work for additional information
6c82f2877SAndrew Rist * regarding copyright ownership. The ASF licenses this file
7c82f2877SAndrew Rist * to you under the Apache License, Version 2.0 (the
8c82f2877SAndrew Rist * "License"); you may not use this file except in compliance
9c82f2877SAndrew Rist * with the License. You may obtain a copy of the License at
10c82f2877SAndrew Rist *
11c82f2877SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0
12c82f2877SAndrew Rist *
13c82f2877SAndrew Rist * Unless required by applicable law or agreed to in writing,
14c82f2877SAndrew Rist * software distributed under the License is distributed on an
15c82f2877SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16c82f2877SAndrew Rist * KIND, either express or implied. See the License for the
17c82f2877SAndrew Rist * specific language governing permissions and limitations
18c82f2877SAndrew Rist * under the License.
19c82f2877SAndrew Rist *
20c82f2877SAndrew Rist *************************************************************/
21c82f2877SAndrew Rist
22c82f2877SAndrew 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
AppendPS(FILE * pDst,osl::File * pSrc,sal_uChar * pBuffer,sal_uInt32 nBlockSize=nBLOCKSIZE)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*
CreateSpoolFile(const rtl::OUString & rName,const rtl::OUString & rExtension)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
GetScale(double & rXScale,double & rYScale) const127cdf0e10cSrcweir PrinterJob::GetScale (double &rXScale, double &rYScale) const
128cdf0e10cSrcweir {
129cdf0e10cSrcweir rXScale = mfXScale;
130cdf0e10cSrcweir rYScale = mfYScale;
131cdf0e10cSrcweir }
132cdf0e10cSrcweir
133cdf0e10cSrcweir sal_uInt16
GetDepth() const134cdf0e10cSrcweir 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
GetPostscriptLevel(const JobData * pJobData) const143cdf0e10cSrcweir 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
IsColorPrinter() const160cdf0e10cSrcweir 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*
GetDocumentHeader()173cdf0e10cSrcweir PrinterJob::GetDocumentHeader ()
174cdf0e10cSrcweir {
175cdf0e10cSrcweir return mpJobHeader;
176cdf0e10cSrcweir }
177cdf0e10cSrcweir
178cdf0e10cSrcweir osl::File*
GetDocumentTrailer()179cdf0e10cSrcweir PrinterJob::GetDocumentTrailer ()
180cdf0e10cSrcweir {
181cdf0e10cSrcweir return mpJobTrailer;
182cdf0e10cSrcweir }
183cdf0e10cSrcweir
184cdf0e10cSrcweir osl::File*
GetCurrentPageHeader()185cdf0e10cSrcweir PrinterJob::GetCurrentPageHeader ()
186cdf0e10cSrcweir {
187cdf0e10cSrcweir return maHeaderList.back();
188cdf0e10cSrcweir }
189cdf0e10cSrcweir
190cdf0e10cSrcweir osl::File*
GetCurrentPageBody()191cdf0e10cSrcweir PrinterJob::GetCurrentPageBody ()
192cdf0e10cSrcweir {
193cdf0e10cSrcweir return maPageList.back();
194cdf0e10cSrcweir }
195cdf0e10cSrcweir
196cdf0e10cSrcweir /*
197cdf0e10cSrcweir * public methods of PrinterJob: the actual job / spool handling
198cdf0e10cSrcweir */
199cdf0e10cSrcweir
PrinterJob()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
existsTmpDir(const char * pName)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
getUserName(char * pName,int nSize)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
removeSpoolDir(const rtl::OUString & rSpoolDir)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
createSpoolDir()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
~PrinterJob()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*
getLocalTime(sal_Char * pBuffer)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
isAscii(const rtl::OUString & rStr)362cdf0e10cSrcweir static bool isAscii( const rtl::OUString& rStr )
363cdf0e10cSrcweir {
364*24c56ab9SHerbert Dürr const sal_Unicode* pStr = rStr.getStr();
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
StartJob(const rtl::OUString & rFileName,int nMode,const rtl::OUString & rJobName,const rtl::OUString & rAppName,const JobData & rSetupData,PrinterGfx * pGraphics,bool bIsQuickJob)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
EndJob()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
AbortJob()624cdf0e10cSrcweir PrinterJob::AbortJob ()
625cdf0e10cSrcweir {
626cdf0e10cSrcweir m_pGraphics->OnEndJob();
627cdf0e10cSrcweir return sal_False;
628cdf0e10cSrcweir }
629cdf0e10cSrcweir
630cdf0e10cSrcweir void
InitPaperSize(const JobData & rJobSetup)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
StartPage(const JobData & rJobSetup)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
EndPage()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
GetErrorCode()766cdf0e10cSrcweir PrinterJob::GetErrorCode ()
767cdf0e10cSrcweir {
768cdf0e10cSrcweir /* TODO */
769cdf0e10cSrcweir return 0;
770cdf0e10cSrcweir }
771cdf0e10cSrcweir
772cdf0e10cSrcweir struct less_ppd_key : public ::std::binary_function<double, double, bool>
773cdf0e10cSrcweir {
operator ()less_ppd_key774cdf0e10cSrcweir bool operator()(const PPDKey* left, const PPDKey* right)
775cdf0e10cSrcweir { return left->getOrderDependency() < right->getOrderDependency(); }
776cdf0e10cSrcweir };
777cdf0e10cSrcweir
writeFeature(osl::File * pFile,const PPDKey * pKey,const PPDValue * pValue,bool bUseIncluseFeature)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
writeFeatureList(osl::File * pFile,const JobData & rJob,bool bDocumentSetup)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
writePageSetup(osl::File * pFile,const JobData & rJob,bool bWriteFeatures)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
writeJobPatch(osl::File * pFile,const JobData & rJobData)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
writeProlog(osl::File * pFile,const JobData & rJobData)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
writeSetup(osl::File * pFile,const JobData & rJob)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