summaryrefslogtreecommitdiff
path: root/psprint/source/printergfx/printerjob.cxx
diff options
context:
space:
mode:
authorPhilipp Lohmann <pl@openoffice.org>2001-05-08 10:46:10 +0000
committerPhilipp Lohmann <pl@openoffice.org>2001-05-08 10:46:10 +0000
commit571f15004533c1e7a5472e033139d5765862fb73 (patch)
treeb8f12e3cf34cc94fbf54c7ada9bd8c1cea38fc0f /psprint/source/printergfx/printerjob.cxx
parenta6f388c4614f0c87378affa1bbfead2d2939722b (diff)
Unix PS-Print Environment
Diffstat (limited to 'psprint/source/printergfx/printerjob.cxx')
-rw-r--r--psprint/source/printergfx/printerjob.cxx858
1 files changed, 858 insertions, 0 deletions
diff --git a/psprint/source/printergfx/printerjob.cxx b/psprint/source/printergfx/printerjob.cxx
new file mode 100644
index 000000000000..2093cc68cdef
--- /dev/null
+++ b/psprint/source/printergfx/printerjob.cxx
@@ -0,0 +1,858 @@
+/*************************************************************************
+ *
+ * $RCSfile: printerjob.cxx,v $
+ *
+ * $Revision: 1.1.1.1 $
+ *
+ * last change: $Author: pl $ $Date: 2001-05-08 11:46:04 $
+ *
+ * The Contents of this file are made available subject to the terms of
+ * either of the following licenses
+ *
+ * - GNU Lesser General Public License Version 2.1
+ * - Sun Industry Standards Source License Version 1.1
+ *
+ * Sun Microsystems Inc., October, 2000
+ *
+ * GNU Lesser General Public License Version 2.1
+ * =============================================
+ * Copyright 2000 by Sun Microsystems, Inc.
+ * 901 San Antonio Road, Palo Alto, CA 94303, USA
+ *
+ * This library is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU Lesser General Public
+ * License version 2.1, as published by the Free Software Foundation.
+ *
+ * This library is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 59 Temple Place, Suite 330, Boston,
+ * MA 02111-1307 USA
+ *
+ *
+ * Sun Industry Standards Source License Version 1.1
+ * =================================================
+ * The contents of this file are subject to the Sun Industry Standards
+ * Source License Version 1.1 (the "License"); You may not use this file
+ * except in compliance with the License. You may obtain a copy of the
+ * License at http://www.openoffice.org/license.html.
+ *
+ * Software provided under this License is provided on an "AS IS" basis,
+ * WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
+ * WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
+ * MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
+ * See the License for the specific provisions governing your rights and
+ * obligations concerning the Software.
+ *
+ * The Initial Developer of the Original Code is: Sun Microsystems, Inc.
+ *
+ * Copyright: 2000 by Sun Microsystems, Inc.
+ *
+ * All Rights Reserved.
+ *
+ * Contributor(s): _______________________________________
+ *
+ *
+ ************************************************************************/
+
+#ifndef __SGI_STL_VECTOR
+#include <vector>
+#endif
+#ifndef _PSPRINT_PRINTERJOB_HXX_
+#include <psprint/printerjob.hxx>
+#endif
+#ifndef _PSPRINT_PPDPARSER_HXX_
+#include <psprint/ppdparser.hxx>
+#endif
+#ifndef _PSPRINT_STRHELPER_HXX_
+#include <psprint/strhelper.hxx>
+#endif
+#ifndef _PSPRINT_PRINTERINFOMANAGER_HXX_
+#include <psprint/printerinfomanager.hxx>
+#endif
+#ifndef _PSPRINT_PRINTERUTIL_HXX_
+#include <psputil.hxx>
+#endif
+#ifndef _RTL_USTRING_HXX_
+#include <rtl/ustring.hxx>
+#endif
+#ifndef _OSL_THREAD_H_
+#include <osl/thread.h>
+#endif
+
+#include <stdio.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <pwd.h>
+
+
+using namespace psp ;
+
+// forward declaration
+
+#define nBLOCKSIZE 0x2000
+
+sal_Bool
+AppendPS(FILE* pDst, osl::File* pSrc,
+ sal_uChar* pBuffer = NULL, sal_uInt64 nBlockSize = nBLOCKSIZE);
+
+/*
+ * private convenience routines for file handling
+ */
+
+osl::File*
+PrinterJob::CreateSpoolFile (const rtl::OUString& rName, const rtl::OUString& rExtension)
+{
+
+ rtl::OUString aFileName = maSpoolDirName + rtl::OUString::createFromAscii ("/")
+ + rName + rExtension;
+ rtl::OUString aUNCFileName;
+ osl::File::normalizePath (aFileName, aUNCFileName);
+
+ osl::File* pFile = new osl::File (aUNCFileName);
+ pFile->open (OpenFlag_Read | OpenFlag_Write | OpenFlag_Create);
+ pFile->setAttributes (aUNCFileName,
+ osl_File_Attribute_OwnWrite | osl_File_Attribute_OwnRead );
+
+ return pFile;
+}
+
+sal_Bool
+AppendPS (FILE* pDst, osl::File* pSrc, sal_uChar* pBuffer, sal_uInt64 nBlockSize)
+{
+ if ((pDst == NULL) || (pSrc == NULL))
+ return sal_False;
+
+ if (nBlockSize == 0)
+ nBlockSize = nBLOCKSIZE;
+ if (pBuffer == NULL)
+ pBuffer = (sal_uChar*)alloca (nBlockSize);
+
+ pSrc->setPos (osl_Pos_Absolut, 0);
+
+ sal_uInt64 nIn;
+ sal_uInt64 nOut;
+ do
+ {
+ pSrc->read (pBuffer, nBlockSize, nIn);
+ if (nIn > 0)
+ nOut = fwrite (pBuffer, 1, nIn, pDst);
+ }
+ while ((nIn > 0) && (nIn == nOut));
+
+ return sal_True;
+}
+
+/*
+ * public methods of PrinterJob: for use in PrinterGfx
+ */
+
+void
+PrinterJob::GetResolution (sal_uInt32 &rDpiX, sal_uInt32 &rDpiY) const
+{
+ rDpiX = mnResX;
+ rDpiY = mnResY;
+}
+
+void
+PrinterJob::GetScale (double &rXScale, double &rYScale) const
+{
+ rXScale = mfXScale;
+ rYScale = mfYScale;
+}
+
+sal_uInt16
+PrinterJob::GetDepth () const
+{
+ sal_Int32 nLevel = GetPostscriptLevel();
+ sal_Bool bColor = IsColorPrinter ();
+
+ return nLevel > 1 && bColor ? 24 : 8;
+}
+
+sal_uInt16
+PrinterJob::GetPostscriptLevel (const JobData *pJobData) const
+{
+ sal_uInt16 nPSLevel = 2;
+
+ if( pJobData == NULL )
+ pJobData = &m_aLastJobData;
+
+ if( pJobData->m_nPSLevel )
+ nPSLevel = pJobData->m_nPSLevel;
+ else
+ if( pJobData->m_pParser )
+ nPSLevel = pJobData->m_pParser->getLanguageLevel();
+
+ return nPSLevel;
+}
+
+sal_Bool
+PrinterJob::IsColorPrinter () const
+{
+ sal_Bool bColor = sal_False;
+
+ if( m_aLastJobData.m_nColorDevice )
+ bColor = m_aLastJobData.m_nColorDevice == -1 ? sal_False : sal_True;
+ else if( m_aLastJobData.m_pParser )
+ bColor = m_aLastJobData.m_pParser->isColorDevice() ? sal_True : sal_False;
+
+ return bColor;
+}
+
+osl::File*
+PrinterJob::GetDocumentHeader ()
+{
+ return mpJobHeader;
+}
+
+osl::File*
+PrinterJob::GetDocumentTrailer ()
+{
+ return mpJobTrailer;
+}
+
+osl::File*
+PrinterJob::GetCurrentPageHeader ()
+{
+ return maHeaderList.back();
+}
+
+osl::File*
+PrinterJob::GetCurrentPageBody ()
+{
+ return maPageList.back();
+}
+
+/*
+ * public methods of PrinterJob: the actual job / spool handling
+ */
+
+PrinterJob::PrinterJob () :
+ mpJobTrailer (NULL),
+ mpJobHeader (NULL)
+{
+}
+
+/* check whether the given name points to a directory which is
+ usable for the user */
+sal_Bool
+existsTmpDir (const char* pName)
+{
+ struct stat aFileStatus;
+
+ if (pName == NULL)
+ return sal_False;
+ if (stat(pName, &aFileStatus) != 0)
+ return sal_False;
+ if (! S_ISDIR(aFileStatus.st_mode))
+ return sal_False;
+
+ return access(pName, W_OK | R_OK) == 0 ? sal_True : sal_False;
+}
+
+/* return the username in the given buffer */
+sal_Bool
+getUserName (char* pName, int nSize)
+{
+ struct passwd *pPWEntry;
+ struct passwd aPWEntry;
+ sal_Char pPWBuffer[256];
+
+ sal_Bool bSuccess = sal_False;
+
+ if (getpwuid_r(getuid(), &aPWEntry, pPWBuffer, sizeof(pPWBuffer), &pPWEntry) != 0)
+ pPWEntry = NULL;
+
+ if (pPWEntry != NULL && pPWEntry->pw_name != NULL)
+ {
+ sal_Int32 nLen = strlen(pPWEntry->pw_name);
+ if (nLen > 0 && nLen < nSize)
+ {
+ memcpy (pName, pPWEntry->pw_name, nLen);
+ pName[nLen] = '\0';
+
+ bSuccess = sal_True;
+ }
+ }
+
+ // wipe the passwd off the stack
+ memset (pPWBuffer, 0, sizeof(pPWBuffer));
+
+ return bSuccess;
+}
+
+/* remove all our temporary files, uses external program "rm", since
+ osl functionality is inadequate */
+void
+removeSpoolDir (const rtl::OUString& rSpoolDir)
+{
+ rtl::OUString aSysPath;
+ osl::File::getSystemPathFromNormalizedPath (rSpoolDir, aSysPath);
+ rtl::OString aSysPathByte =
+ rtl::OUStringToOString (aSysPath, osl_getThreadTextEncoding());
+ sal_Char pSystem [128];
+ sal_Int32 nChar = 0;
+
+ nChar = psp::appendStr ("rm -rf ", pSystem);
+ nChar += psp::appendStr (aSysPathByte.getStr(), pSystem + nChar);
+
+ system (pSystem);
+}
+
+/* creates a spool directory using the environment TMPDIR, or the
+ standard P_tmpdir definition (/tmp for Linux and /var/tmp for Solaris)
+ leads to a directory like "/tmp/pspXXXXXX" */
+rtl::OUString
+createSpoolDir ()
+{
+ /* get a tmp directory */
+ static char* pTmpDir = NULL;
+ if (pTmpDir == NULL)
+ {
+ if (! existsTmpDir(pTmpDir = getenv("TMPDIR")))
+ if (! existsTmpDir(pTmpDir = P_tmpdir))
+ pTmpDir = "/tmp";
+ }
+
+ /* create a subdirectory in the tmp directory */
+ char* pName = tempnam (pTmpDir, "psp");
+ rtl::OUString aSubDir = rtl::OUString::createFromAscii (pName);
+ rtl::OUString aUNCSubDir;
+ osl::File::normalizePath (aSubDir, aUNCSubDir);
+ free (pName);
+
+ /* create directory with attributes */
+ osl::Directory::create (aUNCSubDir);
+ osl::File::setAttributes (aUNCSubDir, osl_File_Attribute_OwnWrite
+ | osl_File_Attribute_OwnRead
+ | osl_File_Attribute_OwnExe );
+
+ return aUNCSubDir;
+}
+
+PrinterJob::~PrinterJob ()
+{
+ std::list< osl::File* >::iterator pPage;
+ for (pPage = maPageList.begin(); pPage != maPageList.end(); pPage++)
+ {
+ //(*pPage)->remove();
+ delete *pPage;
+ }
+ for (pPage = maHeaderList.begin(); pPage != maHeaderList.end(); pPage++)
+ {
+ //(*pPage)->remove();
+ delete *pPage;
+ }
+ // mpJobHeader->remove();
+ delete mpJobHeader;
+ // mpJobTrailer->remove();
+ delete mpJobTrailer;
+
+ // XXX should really call osl::remove routines
+ removeSpoolDir (maSpoolDirName);
+
+ // osl::Directory::remove (maSpoolDirName);
+}
+
+
+// get locale invariant, 7bit clean current local time string
+sal_Char*
+getLocalTime(sal_Char* pBuffer, sal_uInt32 nBufSize)
+{
+ time_t nTime = time (NULL);
+ struct tm aTime;
+ struct tm *pLocalTime = localtime_r (&nTime, &aTime);
+
+ return asctime_r(pLocalTime, pBuffer);
+}
+
+sal_Bool
+PrinterJob::StartJob (
+ const rtl::OUString& rFileName,
+ const rtl::OUString& rJobName,
+ const rtl::OUString& rAppName,
+ const JobData& rSetupData)
+{
+ InitPaperSize (rSetupData);
+
+ // create file container for document header and trailer
+ maFileName = rFileName;
+ maSpoolDirName = createSpoolDir ();
+
+ rtl::OUString aExt = rtl::OUString::createFromAscii (".ps");
+ mpJobHeader = CreateSpoolFile (rtl::OUString::createFromAscii("psp_head"), aExt);
+ mpJobTrailer = CreateSpoolFile (rtl::OUString::createFromAscii("psp_tail"), aExt);
+
+ // write document header according to Document Structuring Conventions (DSC)
+ WritePS (mpJobHeader, "%!PS-Adobe-3.0\n");
+
+ // BoundingBox
+ sal_Char pBBox [256];
+ sal_Int32 nChar = 0;
+
+ nChar = psp::appendStr ("%%BoundingBox: ", pBBox);
+ nChar += psp::getValueOf (0, pBBox + nChar);
+ nChar += psp::appendStr (" ", pBBox + nChar);
+ nChar += psp::getValueOf (0, pBBox + nChar);
+ nChar += psp::appendStr (" ", pBBox + nChar);
+ nChar += psp::getValueOf (mnWidthPt, pBBox + nChar);
+ nChar += psp::appendStr (" ", pBBox + nChar);
+ nChar += psp::getValueOf (mnHeightPt, pBBox + nChar);
+ nChar += psp::appendStr ("\n", pBBox + nChar);
+
+ WritePS (mpJobHeader, pBBox);
+
+ // Creator (this application)
+ WritePS (mpJobHeader, "%%Creator: ");
+ WritePS (mpJobHeader, rAppName);
+ WritePS (mpJobHeader, "\n");
+
+ // For (user name)
+ sal_Char pUserName[64];
+ if (getUserName(pUserName, sizeof(pUserName)))
+ {
+ WritePS (mpJobHeader, "%%For: ");
+ WritePS (mpJobHeader, pUserName);
+ WritePS (mpJobHeader, "\n");
+ }
+
+ // Creation Date (locale independent local time)
+ sal_Char pCreationDate [256];
+ WritePS (mpJobHeader, "%%CreationDate: ");
+ WritePS (mpJobHeader, getLocalTime(pCreationDate, sizeof(pCreationDate)));
+
+ // Document Title
+ WritePS (mpJobHeader, "%%Title: ");
+ WritePS (mpJobHeader, rJobName);
+ WritePS (mpJobHeader, "\n");
+
+ // Language Level
+ sal_Char pLevel[16];
+ sal_Int32 nSz = getValueOf(GetPostscriptLevel(&rSetupData), pLevel);
+ pLevel[nSz++] = '\n';
+ pLevel[nSz ] = '\0';
+ WritePS (mpJobHeader, "%%LanguageLevel: ");
+ WritePS (mpJobHeader, pLevel);
+
+ // Other
+ WritePS (mpJobHeader, "%%DocumentData: Clean7Bit\n");
+ WritePS (mpJobHeader, "%%Pages: (atend)\n");
+ WritePS (mpJobHeader, "%%PageOrder: Ascend\n");
+ WritePS (mpJobHeader, "%%EndComments\n");
+
+ writeProlog (mpJobHeader);
+
+ // mark last job setup as not set
+ m_aLastJobData.m_pParser = NULL;
+ m_aLastJobData.m_aContext.setParser( NULL );
+
+ writeSetup( mpJobHeader, rSetupData );
+
+ return sal_True;
+}
+
+sal_Bool
+PrinterJob::EndJob ()
+{
+ // write document trailer according to Document Structuring Conventions (DSC)
+ sal_Char pPageNr [16];
+ sal_Int32 nSz = getValueOf((sal_Int32)maPageList.size(), pPageNr);
+ pPageNr [nSz] = '\0';
+
+ WritePS (mpJobTrailer, "%%Trailer\n");
+ WritePS (mpJobTrailer, "%%Pages: ");
+ WritePS (mpJobTrailer, pPageNr);
+ WritePS (mpJobTrailer, "\n");
+ WritePS (mpJobTrailer, "%%EOF\n");
+
+ /*
+ * spool the set of files to their final destination, this is U**X dependent
+ */
+
+ FILE* pDestFILE = NULL;
+
+ /* create a destination either as file or as a pipe */
+
+ sal_Bool bSpoolToFile = maFileName.getLength() > 0 ? sal_True : sal_False;
+ if (bSpoolToFile)
+ {
+ const rtl::OString aFileName = rtl::OUStringToOString (maFileName,
+ osl_getThreadTextEncoding());
+
+ pDestFILE = fopen (aFileName.getStr(), "w");
+ if (pDestFILE == NULL)
+ return sal_False;
+ }
+ else
+ {
+ const PrinterInfoManager& rPrinterInfoManager = PrinterInfoManager::get ();
+ const rtl::OUString& rPrinter = m_aLastJobData.m_aPrinterName;
+ const PrinterInfo& rPrinterInfo = rPrinterInfoManager.getPrinterInfo (rPrinter);
+ const rtl::OUString& rCommand = rPrinterInfo.m_aCommand;
+
+ const rtl::OString aShellCommand = rtl::OUStringToOString (rCommand,
+ RTL_TEXTENCODING_ISO_8859_1);
+
+ pDestFILE = popen (aShellCommand.getStr(), "w");
+ if (pDestFILE == NULL)
+ return sal_False;
+ }
+
+ /* spool the document parts to the destination */
+
+ sal_uChar pBuffer[ nBLOCKSIZE ];
+
+ AppendPS (pDestFILE, mpJobHeader, pBuffer);
+ mpJobHeader->close();
+
+ std::list< osl::File* >::iterator pPageBody;
+ std::list< osl::File* >::iterator pPageHead;
+ for (pPageBody = maPageList.begin(), pPageHead = maHeaderList.begin();
+ pPageBody != maPageList.end() && pPageHead != maHeaderList.end();
+ pPageBody++, pPageHead++)
+ {
+ (*pPageHead)->open(OpenFlag_Read);
+ AppendPS (pDestFILE, *pPageHead, pBuffer);
+ (*pPageHead)->close();
+
+ (*pPageBody)->open(OpenFlag_Read);
+ AppendPS (pDestFILE, *pPageBody, pBuffer);
+ (*pPageBody)->close();
+ }
+
+ AppendPS (pDestFILE, mpJobTrailer, pBuffer);
+ mpJobTrailer->close();
+
+ /* well done */
+
+ if (bSpoolToFile)
+ fclose (pDestFILE);
+ else
+ pclose (pDestFILE);
+
+ return sal_True;
+}
+
+sal_Bool
+PrinterJob::AbortJob ()
+{
+ return sal_False;
+}
+
+void
+PrinterJob::InitPaperSize (const JobData& rJobSetup)
+{
+ int nResX, nResY;
+ rJobSetup.m_aContext.getResolution (nResX, nResY);
+
+ String aPaper;
+ int nWidth, nHeight;
+ rJobSetup.m_aContext.getPageSize (aPaper, nWidth, nHeight);
+
+ int nLeft = 0, nRight = 0, nUpper = 0, nLower = 0;
+ const PPDParser* pParser = rJobSetup.m_aContext.getParser();
+ if (pParser != NULL)
+ pParser->getMargins (aPaper, nLeft, nRight, nUpper, nLower);
+
+ mnResX = nResX;
+ mnResY = nResY;
+
+ mnWidthPt = nWidth;
+ mnHeightPt = nHeight;
+
+ mnLMarginPt = nLeft;
+ mnRMarginPt = nRight;
+ mnTMarginPt = nUpper;
+ mnBMarginPt = nLower;
+
+ mfXScale = (double)72.0 / (double)mnResX;
+ mfYScale = -1.0 * (double)72.0 / (double)mnResY;
+}
+
+
+SalGraphics*
+PrinterJob::StartPage (const JobData& rJobSetup, sal_Bool bNewJobData)
+{
+ InitPaperSize (rJobSetup);
+
+ rtl::OUString aPageNo = rtl::OUString::valueOf ((sal_Int32)maPageList.size());
+ rtl::OUString aExt = aPageNo + rtl::OUString::createFromAscii (".ps");
+
+ osl::File* pPageHeader = CreateSpoolFile (
+ rtl::OUString::createFromAscii("psp_pghead"), aExt);
+ osl::File* pPageBody = CreateSpoolFile (
+ rtl::OUString::createFromAscii("psp_pgbody"), aExt);
+
+ maHeaderList.push_back (pPageHeader);
+ maPageList.push_back (pPageBody);
+
+ // write page header according to Document Structuring Conventions (DSC)
+
+ WritePS (pPageHeader, "%%Page: ");
+ WritePS (pPageHeader, aPageNo);
+ WritePS (pPageHeader, " ");
+ WritePS (pPageHeader, aPageNo);
+ WritePS (pPageHeader, "\n");
+
+ sal_Char pBBox [256];
+ sal_Int32 nChar = 0;
+
+ nChar = psp::appendStr ("%%PageBoundingBox: ", pBBox);
+ nChar += psp::getValueOf (mnLMarginPt, pBBox + nChar);
+ nChar += psp::appendStr (" ", pBBox + nChar);
+ nChar += psp::getValueOf (mnBMarginPt, pBBox + nChar);
+ nChar += psp::appendStr (" ", pBBox + nChar);
+ nChar += psp::getValueOf (mnWidthPt - mnRMarginPt, pBBox + nChar);
+ nChar += psp::appendStr (" ", pBBox + nChar);
+ nChar += psp::getValueOf (mnHeightPt - mnTMarginPt, pBBox + nChar);
+ nChar += psp::appendStr ("\n", pBBox + nChar);
+
+ WritePS (pPageHeader, pBBox);
+
+ writeSetup ( pPageHeader, rJobSetup );
+ writePageSetup ( pPageHeader, rJobSetup );
+
+ return NULL;
+}
+
+sal_Bool
+PrinterJob::EndPage ()
+{
+ osl::File* pPageHeader = maHeaderList.back();
+ osl::File* pPageBody = maPageList.back();
+
+ // copy page to paper and write page trailer according to DSC
+
+ sal_Char pTrailer[256];
+ sal_Int32 nChar = 0;
+ nChar = psp::appendStr ("showpage\n", pTrailer);
+ nChar += psp::appendStr ("grestore grestore\n", pTrailer + nChar);
+ nChar += psp::appendStr ("%%PageTrailer\n\n", pTrailer + nChar);
+ WritePS (pPageBody, pTrailer);
+
+ // this page is done for now, close it to avoid having too many open fd's
+
+ pPageHeader->close();
+ pPageBody->close();
+
+ return sal_True;
+}
+
+sal_uInt32
+PrinterJob::GetErrorCode ()
+{
+ /* TODO */
+ return 0;
+}
+
+struct less_ppd_key : public ::std::binary_function<double, double, bool>
+{
+ bool operator()(const PPDKey* left, const PPDKey* right)
+ { return left->getOrderDependency() < right->getOrderDependency(); }
+};
+
+static bool writeFeature( osl::File* pFile, const PPDKey* pKey, const PPDValue* pValue )
+{
+ if( ! pKey || ! pValue )
+ return true;
+
+ String aFeature( RTL_CONSTASCII_USTRINGPARAM( "%%BeginFeature: *" ) );
+ aFeature += pKey->getKey();
+ aFeature += ' ';
+ aFeature += pValue->m_aOption;
+ aFeature += '\n';
+ aFeature += pValue->m_aValue;
+ aFeature.AppendAscii( "\n%%EndFeature\n" );
+ ByteString aPSFeature( aFeature, RTL_TEXTENCODING_ASCII_US );
+ sal_uInt64 nWritten = 0;
+ return pFile->write( aPSFeature.GetBuffer(), aPSFeature.Len(), nWritten )
+ || nWritten != aPSFeature.Len() ? false : true;
+}
+
+bool PrinterJob::writePageSetup( osl::File* pFile, const JobData& rJob )
+{
+ bool bSuccess = true;
+
+ WritePS (pFile, "%%BeginPageSetup\n%\n");
+ ByteString aLine( "/#copies " );
+ aLine += ByteString::CreateFromInt32( rJob.m_nCopies );
+ aLine += " def\n";
+ sal_uInt64 nWritten = 0;
+ bSuccess = pFile->write( aLine.GetBuffer(), aLine.Len(), nWritten )
+ || nWritten != aLine.Len() ? false : true;
+
+ sal_Char pTranslate [128];
+ sal_Int32 nChar = 0;
+
+ if( rJob.m_eOrientation == orientation::Portrait )
+ {
+ nChar = psp::appendStr ("gsave\n[", pTranslate);
+ nChar += psp::getValueOfDouble ( pTranslate + nChar, mfXScale, 5);
+ nChar += psp::appendStr (" 0 0 ", pTranslate + nChar);
+ nChar += psp::getValueOfDouble ( pTranslate + nChar, mfYScale, 5);
+ nChar += psp::appendStr (" ", pTranslate + nChar);
+ nChar += psp::getValueOf (mnRMarginPt, pTranslate + nChar);
+ nChar += psp::appendStr (" ", pTranslate + nChar);
+ nChar += psp::getValueOf (mnHeightPt-mnTMarginPt,
+ pTranslate + nChar);
+ nChar += psp::appendStr ("] concat\ngsave\n",
+ pTranslate + nChar);
+ }
+ else
+ {
+ nChar = psp::appendStr ("gsave\n", pTranslate);
+ nChar += psp::appendStr ("[ 0 ", pTranslate + nChar);
+ nChar += psp::getValueOfDouble ( pTranslate + nChar, -mfYScale, 5);
+ nChar += psp::appendStr (" ", pTranslate + nChar);
+ nChar += psp::getValueOfDouble ( pTranslate + nChar, mfXScale, 5);
+ nChar += psp::appendStr (" 0 ", pTranslate + nChar );
+ nChar += psp::getValueOfDouble ( pTranslate + nChar, mnLMarginPt, 5 );
+ nChar += psp::appendStr (" ", pTranslate + nChar);
+ nChar += psp::getValueOf (mnBMarginPt, pTranslate + nChar );
+ nChar += psp::appendStr ("] concat\ngsave\n",
+ pTranslate + nChar);
+ }
+
+ WritePS (pFile, pTranslate);
+
+ WritePS (pFile, "%%EndPageSetup\n");
+
+ return bSuccess;
+}
+
+bool PrinterJob::writeProlog (osl::File* pFile)
+{
+ const sal_Char pProlog[] = {
+ "%%BeginProlog\n"
+ "/ISO1252Encoding [\n"
+ "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
+ "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
+ "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
+ "/.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef /.notdef\n"
+ "/space /exclam /quotedbl /numbersign /dollar /percent /ampersand /quotesingle\n"
+ "/parenleft /parenright /asterisk /plus /comma /hyphen /period /slash\n"
+ "/zero /one /two /three /four /five /six /seven\n"
+ "/eight /nine /colon /semicolon /less /equal /greater /question\n"
+ "/at /A /B /C /D /E /F /G\n"
+ "/H /I /J /K /L /M /N /O\n"
+ "/P /Q /R /S /T /U /V /W\n"
+ "/X /Y /Z /bracketleft /backslash /bracketright /asciicircum /underscore\n"
+ "/grave /a /b /c /d /e /f /g\n"
+ "/h /i /j /k /l /m /n /o\n"
+ "/p /q /r /s /t /u /v /w\n"
+ "/x /y /z /braceleft /bar /braceright /asciitilde /unused\n"
+ "/euro /unused /quotesinglbase /florin /quotedblbase /ellipsis /dagger /daggerdbl\n"
+ "/circumflex /perthousand /Scaron /guilsinglleft /OE /unused /zcaron /unused\n"
+ "/unused /quoteleft /quoteright /quotedblleft /quotedblright /bullet /endash /emdash\n"
+ "/tilde /trademark /scaron /guilsinglright /oe /unused /zcaron /Ydieresis\n"
+ "/space /exclamdown /cent /sterling /currency /yen /brokenbar /section\n"
+ "/dieresis /copyright /ordfeminine /guillemotleft /logicalnot /hyphen /registered /macron\n"
+ "/degree /plusminus /twosuperior /threesuperior /acute /mu /paragraph /periodcentered\n"
+ "/cedilla /onesuperior /ordmasculine /guillemotright /onequarter /onehalf /threequarters /questiondown\n"
+ "/Agrave /Aacute /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla\n"
+ "/Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute /Icircumflex /Idieresis\n"
+ "/Eth /Ntilde /Ograve /Oacute /Ocircumflex /Otilde /Odieresis /multiply\n"
+ "/Oslash /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn /germandbls\n"
+ "/agrave /aacute /acircumflex /atilde /adieresis /aring /ae /ccedilla\n"
+ "/egrave /eacute /ecircumflex /edieresis /igrave /iacute /icircumflex /idieresis\n"
+ "/eth /ntilde /ograve /oacute /ocircumflex /otilde /odieresis /divide\n"
+ "/oslash /ugrave /uacute /ucircumflex /udieresis /yacute /thorn /ydieresis] def\n"
+ "/findfont1252 {\n"
+ "findfont\n"
+ "dup length dict begin\n"
+ "{ 1 index /FID ne\n"
+ " { def }\n"
+ " { pop pop }\n"
+ " ifelse\n"
+ "} forall\n"
+ "/Encoding ISO1252Encoding def\n"
+ "currentdict end\n"
+ "/reenc1252font exch definefont } def\n"
+ "\n"
+ "/pathdict dup 8 dict def load begin\n"
+ "/rcmd { { currentfile 1 string readstring pop 0 get dup 32 gt { exit }\n"
+ "{ pop } ifelse } loop dup 126 eq { pop exit } if 65 sub dup 16#3 and 1\n"
+ "add exch dup 16#C and -2 bitshift 16#3 and 1 add exch 16#10 and 16#10\n"
+ "eq 3 1 roll exch } def\n"
+ "/rhex { dup 1 sub exch currentfile exch string readhexstring pop dup 0\n"
+ "get dup 16#80 and 16#80 eq dup 3 1 roll { 16#7f and } if 2 index 0 3\n"
+ "-1 roll put 3 1 roll 0 0 1 5 -1 roll { 2 index exch get add 256 mul }\n"
+ "for 256 div exch pop exch { neg } if } def\n"
+ "/xcmd { rcmd exch rhex exch rhex exch 5 -1 roll add exch 4 -1 roll add\n"
+ "1 index 1 index 5 -1 roll { moveto } { lineto } ifelse } def end\n"
+ "/readpath { 0 0 pathdict begin { xcmd } loop end pop pop } def\n"
+ "\n"
+ "systemdict /languagelevel known not {\n"
+ "/xshow { exch dup length 0 1 3 -1 roll 1 sub { dup 3 index exch get\n"
+ "exch 2 index exch get 1 string dup 0 4 -1 roll put currentpoint 3 -1\n"
+ "roll show moveto 0 rmoveto } for pop pop } def\n"
+ "/rectangle { 4 -2 roll moveto 1 index 0 rlineto 0 exch rlineto neg 0\n"
+ "rlineto closepath } def\n"
+ "/rectfill { rectangle fill } def\n"
+ "/rectstroke { rectangle stroke } def } if\n"
+ "\n"
+ "%%EndProlog\n"
+ };
+ WritePS (pFile, pProlog);
+
+ return true;
+}
+
+bool PrinterJob::writeSetup( osl::File* pFile, const JobData& rJob )
+{
+ bool bSuccess = true;
+ int i;
+
+ WritePS (pFile, "%%BeginSetup\n%\n");
+
+ // emit features ordered to OrderDependency
+ // ignore features that are set to default
+ const PPDContext& rContext = rJob.m_aContext;
+ // sanity check
+ if( rJob.m_pParser == rJob.m_aContext.getParser() &&
+ rJob.m_pParser &&
+ ( m_aLastJobData.m_pParser == rJob.m_pParser || m_aLastJobData.m_pParser == NULL )
+ )
+ {
+ int nKeys = rJob.m_aContext.countValuesModified();
+ ::std::vector< const PPDKey* > aKeys( nKeys );
+ for( i = 0; i < nKeys; i++ )
+ aKeys[i] = rJob.m_aContext.getModifiedKey( i );
+ ::std::sort( aKeys.begin(), aKeys.end(), less_ppd_key() );
+
+ for( i = 0; i < nKeys && bSuccess; i++ )
+ {
+ const PPDKey* pKey = aKeys[i];
+ if( pKey->getSetupType() == PPDKey::DocumentSetup ||
+ pKey->getSetupType() == PPDKey::PageSetup ||
+ pKey->getSetupType() == PPDKey::AnySetup )
+ {
+ const PPDValue* pValue = rJob.m_aContext.getValue( pKey );
+ if(pValue
+ && pValue->m_eType == eInvocation
+ && pValue->m_aValue.Len()
+ && ( m_aLastJobData.m_pParser == NULL
+ || m_aLastJobData.m_aContext.getValue( pKey ) != pValue )
+ )
+ {
+ bSuccess = writeFeature( pFile, pKey, pValue );
+ }
+ }
+ }
+ }
+ else
+ bSuccess = false;
+
+ WritePS (pFile, "%%EndSetup\n");
+
+ if( bSuccess )
+ m_aLastJobData = rJob;
+
+ return bSuccess;
+}