Bug 241607 - Separate postscript generation from print job handling.

r=tor, sr=roc
This commit is contained in:
kjh-5727%comcast.net 2004-05-28 23:06:44 +00:00
Родитель 381caa59c9
Коммит e8eb4572ff
11 изменённых файлов: 1081 добавлений и 430 удалений

Просмотреть файл

@ -71,6 +71,8 @@ CPPSRCS = \
nsAFMObject.cpp \
nsGfxFactoryPS.cpp \
nsTempfilePS.cpp \
nsPrintJobPS.cpp \
nsPrintJobFactoryPS.cpp \
$(NULL)
EXPORTS = \

Просмотреть файл

@ -1,4 +1,5 @@
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
@ -21,6 +22,7 @@
*
* Contributor(s):
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
* Ken Herron <kherron@fastmail.us>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -59,6 +61,9 @@
#include "nsPostScriptObj.h"
#include "nspr.h"
#include "nsILanguageAtomService.h"
#include "nsType8.h"
#include "nsPrintJobPS.h"
#include "nsPrintJobFactoryPS.h"
#ifdef PR_LOGGING
static PRLogModuleInfo *nsDeviceContextPSLM = PR_NewLogModule("nsDeviceContextPS");
@ -89,6 +94,7 @@ nsDeviceContextPS :: nsDeviceContextPS()
: DeviceContextImpl(),
mSpec(nsnull),
mParentDeviceContext(nsnull),
mPrintJob(nsnull),
mPSObj(nsnull),
mPSFontGeneratorList(nsnull)
{
@ -108,13 +114,8 @@ nsDeviceContextPS::~nsDeviceContextPS()
{
PR_LOG(nsDeviceContextPSLM, PR_LOG_DEBUG, ("nsDeviceContextPS::~nsDeviceContextPS()\n"));
if (mPSObj) {
delete mPSObj;
mPSObj = nsnull;
}
/* nsCOMPtr<> will dispose the objects... */
mSpec = nsnull;
delete mPSObj;
delete mPrintJob;
mParentDeviceContext = nsnull;
#ifdef WE_DO_NOT_SUPPORT_MULTIPLE_PRINT_DEVICECONTEXTS
@ -134,8 +135,8 @@ NS_IMETHODIMP
nsDeviceContextPS::SetSpec(nsIDeviceContextSpec* aSpec)
{
PR_LOG(nsDeviceContextPSLM, PR_LOG_DEBUG, ("nsDeviceContextPS::SetSpec()\n"));
nsresult rv = NS_ERROR_FAILURE;
NS_PRECONDITION(!mPSObj, "Already have a postscript object");
NS_PRECONDITION(!mPrintJob, "Already have a printjob object");
#ifdef WE_DO_NOT_SUPPORT_MULTIPLE_PRINT_DEVICECONTEXTS
NS_ASSERTION(instance_counter < 2, "Cannot have more than one print device context.");
@ -145,24 +146,23 @@ nsDeviceContextPS::SetSpec(nsIDeviceContextSpec* aSpec)
#endif /* WE_DO_NOT_SUPPORT_MULTIPLE_PRINT_DEVICECONTEXTS */
mSpec = aSpec;
nsCOMPtr<nsIDeviceContextSpecPS> psSpec;
mPSObj = new nsPostScriptObj();
if (!mPSObj)
return NS_ERROR_OUT_OF_MEMORY;
psSpec = do_QueryInterface(mSpec, &rv);
nsresult rv;
nsCOMPtr<nsIDeviceContextSpecPS> psSpec = do_QueryInterface(mSpec, &rv);
if (NS_SUCCEEDED(rv)) {
rv = mPSObj->Init(psSpec);
if (NS_FAILED(rv)) {
delete mPSObj;
mPSObj = nsnull;
}
if (NS_SUCCEEDED(rv))
rv = nsPrintJobFactoryPS::CreatePrintJob(psSpec, mPrintJob);
}
return rv;
if (NS_FAILED(rv) && mPSObj) {
delete mPSObj;
mPSObj = nsnull;
}
return rv;
}
NS_IMPL_ISUPPORTS_INHERITED1(nsDeviceContextPS,
@ -415,12 +415,10 @@ static PRBool PR_CALLBACK
GeneratePSFontCallback(nsHashKey *aKey, void *aData, void* aClosure)
{
nsPSFontGenerator* psFontGenerator = (nsPSFontGenerator*)aData;
nsPostScriptObj *psObj = (nsPostScriptObj*)aClosure;
NS_ENSURE_TRUE(psFontGenerator && psObj, PR_FALSE);
NS_ENSURE_TRUE(psFontGenerator && aClosure, PR_FALSE);
FILE *f = psObj->GetPrintFile();
if (f)
psFontGenerator->GeneratePSFont(f);
if (aClosure)
psFontGenerator->GeneratePSFont((FILE *)aClosure);
return PR_TRUE;
}
@ -433,26 +431,48 @@ NS_IMETHODIMP nsDeviceContextPS::EndDocument(void)
PR_LOG(nsDeviceContextPSLM, PR_LOG_DEBUG, ("nsDeviceContextPS::EndDocument()\n"));
NS_ENSURE_TRUE(mPSObj != nsnull, NS_ERROR_NULL_POINTER);
// Finish the document and print it...
nsresult rv = mPSObj->end_document();
if (NS_SUCCEEDED(rv)) {
FILE *submitFP;
rv = mPrintJob->StartSubmission(&submitFP);
if (NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED == rv) {
// This was probably a print-preview operation
rv = NS_OK;
}
else if (NS_SUCCEEDED(rv)) {
NS_ASSERTION(submitFP, "No print job submission handle");
// Start writing the print job to the job handler
mPSObj->write_prolog(submitFP);
#ifdef MOZ_ENABLE_FREETYPE2
// Before output Type8 font, check whether printer support CID font
if (mFTPEnable && mPSFontGeneratorList)
if (mPSFontGeneratorList->Count() > 0)
mPSObj->add_cid_check();
// Before output Type8 font, check whether printer support CID font
if (mFTPEnable && mPSFontGeneratorList)
if (mPSFontGeneratorList->Count() > 0)
AddCIDCheckCode(submitFP);
#endif
/* Core of TrueType printing:
* enumerate items("nsPSFontGenerator") in hashtable
* to generate Type8 font and output to Postscript file
*/
if (mPSFontGeneratorList)
mPSFontGeneratorList->Enumerate(GeneratePSFontCallback, (void *) mPSObj);
/* Core of TrueType printing:
* enumerate items("nsPSFontGenerator") in hashtable
* to generate Type8 font and output to Postscript file
*/
if (mPSFontGeneratorList)
mPSFontGeneratorList->Enumerate(GeneratePSFontCallback,
(void *) submitFP);
/* Finish the document and print it... */
nsresult rv = mPSObj->end_document();
rv = mPSObj->write_script(submitFP);
if (NS_SUCCEEDED(rv))
rv = mPrintJob->FinishSubmission();
}
}
delete mPSObj;
mPSObj = nsnull;
delete mPrintJob;
mPrintJob = nsnull;
PR_LOG(nsDeviceContextPSLM, PR_LOG_DEBUG,
("nsDeviceContextPS::EndDocument() return value %d\n", rv));
return rv;
}
@ -467,9 +487,8 @@ NS_IMETHODIMP nsDeviceContextPS::AbortDocument(void)
NS_ENSURE_TRUE(mPSObj != nsnull, NS_ERROR_NULL_POINTER);
delete mPSObj;
mPSObj = nsnull;
delete mPrintJob;
mPrintJob = nsnull;
return NS_OK;
}

Просмотреть файл

@ -21,6 +21,7 @@
*
* Contributor(s):
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
* Ken Herron <kherron@fastmail.us>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -47,6 +48,7 @@
#include "nsVoidArray.h"
#include "nsIDeviceContextPS.h"
#include "nsFontMetricsPS.h"
#include "nsIPrintJobPS.h"
class nsPostScriptObj;
class nsDeviceContextWin; // need to be a friend of the class using us.
@ -106,6 +108,7 @@ protected:
PRUint32 mDepth;
nsCOMPtr<nsIDeviceContextSpec> mSpec;
nsCOMPtr<nsIDeviceContext> mParentDeviceContext;
nsIPrintJobPS *mPrintJob;
nsPostScriptObj *mPSObj;
nsHashtable *mPSFontGeneratorList;
};

109
gfx/src/ps/nsIPrintJobPS.h Normal file
Просмотреть файл

@ -0,0 +1,109 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public 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.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Ken Herron <kherron@fastmail.us>
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsIPrintJobPS_h__
#define nsIPrintJobPS_h__
#include <stdio.h>
class nsIDeviceContextSpecPS;
/*
* This is an interface for a class that accepts and submits print jobs.
*
* Instances should be obtained through nsPrintJobFactoryPS::CreatePrintJob().
* After obtaining a print job object, the caller can retrieve the PostScript
* object associated with the print job and use that to generate the content.
* Once that is done, the caller may call Submit() to finalize and print
* the job, or Cancel() to abort the job.
*/
class nsIPrintJobPS
{
public:
/**
* Obligatory virtual destructor for polymorphic objects.
*/
virtual ~nsIPrintJobPS();
/* Allow the print job factory to create instances */
friend class nsPrintJobFactoryPS;
/**
* Begin submitting a print job.
* @param aHandle If the return value is NS_OK, this will be filled
* in with a file handle which the caller should use
* to write the text of the print job. The file
* handle may not support seeking. The caller must
* not close the file handle.
* @return NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED if the print
* job object doesn't actually support printing (e.g.
* for print preview)
* NS_OK for success
* Another value for initialization/startup failures.
*/
virtual nsresult StartSubmission(FILE **aHandle) = 0;
/**
* Finish submitting a print job. The caller must call this after
* calling StartSubmission() and writing the text of the print job
* to the file handle. The return value indicates the overall success
* or failure of the print operation.
*
* @return NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED if the print
* job object doesn't actually support printing (e.g.
* for print preview)
* NS_OK for success
* Another value for initialization/startup failures.
*/
virtual nsresult FinishSubmission() = 0;
protected:
/**
* Initialize an object from a device context spec. This must be
* called before any of the public methods.
* @param aContext The device context spec describing the
* desired print job.
* @return NS_OK or a suitable error value.
*/
virtual nsresult Init(nsIDeviceContextSpecPS *aContext) = 0;
};
#endif /* nsIPrintJobPS_h__ */

Просмотреть файл

@ -1,6 +1,6 @@
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
*
* ***** BEGIN LICENSE BLOCK *****
/* -*- Mode: C; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
/* ex: set tabstop=8 softtabstop=2 shiftwidth=2 expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
@ -22,6 +22,7 @@
*
* Contributor(s):
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
* Ken Herron <kherron@fastmail.us>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -84,10 +85,6 @@
#include <errno.h>
#include <sys/wait.h>
#ifdef MOZ_ENABLE_FREETYPE2
#include "nsType8.h"
#endif
#ifdef PR_LOGGING
static PRLogModuleInfo *nsPostScriptObjLM = PR_NewLogModule("nsPostScriptObj");
#endif /* PR_LOGGING */
@ -198,7 +195,8 @@ PrintAsDSCTextline(FILE *f, const char *text, int maxlen)
nsPostScriptObj::nsPostScriptObj() :
mPrintSetup(nsnull),
mPrintContext(nsnull),
mTitle(nsnull)
mTitle(nsnull),
mScriptFP(nsnull)
{
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("nsPostScriptObj::nsPostScriptObj()\n"));
@ -215,24 +213,11 @@ nsPostScriptObj::~nsPostScriptObj()
{
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("nsPostScriptObj::~nsPostScriptObj()\n"));
// The mPrintContext can be null
// if opening the PostScript document
// fails. Giving an invalid path, relative path
// or a directory which the user does not have
// write permissions for will fail to open a document
// see bug 85535
if (mPrintContext) {
if (mPrintSetup->out) {
fclose(mPrintSetup->out);
mPrintSetup->out = nsnull;
}
if (mPrintSetup->tmpBody) {
fclose(mPrintSetup->tmpBody);
mPrintSetup->tmpBody = nsnull;
}
finalize_translation();
}
if (mScriptFP)
fclose(mScriptFP);
if (mDocScript)
mDocScript->Remove(PR_FALSE);
finalize_translation();
// Cleanup things allocated along the way
if (nsnull != mTitle){
@ -263,11 +248,6 @@ nsPostScriptObj::~nsPostScriptObj()
gLangGroups = nsnull;
}
if (mDocProlog)
mDocProlog->Remove(PR_FALSE);
if (mDocScript)
mDocScript->Remove(PR_FALSE);
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("nsPostScriptObj::~nsPostScriptObj(): printing done."));
}
@ -287,11 +267,8 @@ nsresult
nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec )
{
PRBool isGray,
isAPrinter,
isFirstPageFirst;
int landscape;
const char *printername;
nsresult rv;
PrintInfo* pi = new PrintInfo();
mPrintSetup = new PrintSetup();
@ -313,107 +290,14 @@ nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec )
aSpec->GetFirstPageFirst( isFirstPageFirst );
if ( isFirstPageFirst == PR_FALSE )
mPrintSetup->reverse = 1;
// Clean up tempfile remnants of any previous print job
if (mDocProlog)
mDocProlog->Remove(PR_FALSE);
if (mDocScript)
mDocScript->Remove(PR_FALSE);
aSpec->GetToPrinter( isAPrinter );
if (isAPrinter) {
/* Define the destination printer (queue).
* We assume that the print command is set to
* "lpr ${MOZ_PRINTER_NAME:+'-P'}${MOZ_PRINTER_NAME}"
* - which means that if the ${MOZ_PRINTER_NAME} env var is not empty
* the "-P" option of lpr will be set to the printer name.
*/
/* get printer name */
aSpec->GetPrinterName(&printername);
/* do not set the ${MOZ_PRINTER_NAME} env var if we want the default
* printer */
if (printername)
{
/* strip the leading NS_POSTSCRIPT_DRIVER_NAME string */
printername = printername + NS_POSTSCRIPT_DRIVER_NAME_LEN;
if (!strcmp(printername, "default"))
printername = "";
}
else
printername = "";
/* Construct an environment string MOZ_PRINTER_NAME=<printername>
* and add it to the environment.
* On a POSIX system the original buffer becomes part of the
* environment, so it must remain valid until replaced. To preserve
* the ability to unload shared libraries, we have to either remove
* the string from the environment at unload time or else store the
* string in the heap, where it'll be left behind after unloading
* the library.
*/
static char *moz_printer_string;
char *old_printer_string = moz_printer_string;
moz_printer_string = PR_smprintf("MOZ_PRINTER_NAME=%s", printername);
#ifdef DEBUG
printf("setting '%s'\n", moz_printer_string);
#endif
if (!moz_printer_string) {
/* We're probably out of memory */
moz_printer_string = old_printer_string;
return (PR_OUT_OF_MEMORY_ERROR == PR_GetError()) ?
NS_ERROR_OUT_OF_MEMORY : NS_ERROR_UNEXPECTED;
}
else {
PR_SetEnv(moz_printer_string);
if (old_printer_string)
PR_smprintf_free(old_printer_string);
}
aSpec->GetCommand(&mPrintSetup->print_cmd);
// Create a temporary file for the document prolog
rv = mTempfileFactory.CreateTempFile(getter_AddRefs(mDocProlog),
&mPrintSetup->out, "w+");
NS_ENSURE_SUCCESS(rv, NS_ERROR_GFX_PRINTER_FILE_IO_ERROR);
NS_POSTCONDITION(nsnull != mPrintSetup->out,
"CreateTempFile succeeded but no file handle");
} else {
const char *path;
aSpec->GetPath(&path);
rv = NS_NewNativeLocalFile(nsDependentCString(path),
PR_FALSE, getter_AddRefs(mDocProlog));
rv = mDocProlog->OpenANSIFileDesc("w", &mPrintSetup->out);
if (NS_FAILED(rv))
return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
NS_POSTCONDITION(nsnull != mPrintSetup->out,
"OpenANSIFileDesc succeeded but no file handle");
mPrintSetup->print_cmd = NULL; // Indicate print-to-file
}
// Open the temporary file for the document script (printable content)
rv = mTempfileFactory.CreateTempFile(getter_AddRefs(mDocScript),
&mPrintSetup->tmpBody, "w+");
if (NS_FAILED(rv)) {
fclose(mPrintSetup->out);
mPrintSetup->out = nsnull;
mDocProlog->Remove(PR_FALSE);
mDocProlog = nsnull;
return NS_ERROR_GFX_PRINTER_FILE_IO_ERROR;
}
NS_POSTCONDITION(nsnull != mPrintSetup->tmpBody,
"CreateTempFile succeeded but no file handle");
} else
return NS_ERROR_FAILURE;
/* make sure the open worked */
/* Open a temporary file for the document body */
nsresult rv = mTempfileFactory.CreateTempFile(
getter_AddRefs(mDocScript), &mScriptFP, "a+");
NS_ENSURE_SUCCESS(rv, NS_ERROR_GFX_PRINTER_FILE_IO_ERROR);
if (!mPrintSetup->out)
return NS_ERROR_GFX_PRINTER_CMD_FAILURE;
mPrintContext = new PSContext();
memset(mPrintContext, 0, sizeof(struct PSContext_));
memset(pi, 0, sizeof(struct PrintInfo_));
@ -478,8 +362,12 @@ nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec )
// begin the document
initialize_translation(mPrintSetup);
begin_document();
mPageNumber = 1; // we are on the first page
// read the printer properties file
NS_LoadPersistentPropertiesFromURISpec(getter_AddRefs(mPrinterProps),
NS_LITERAL_CSTRING("resource:/res/unixpsfonts.properties"));
return NS_OK;
} else {
return NS_ERROR_FAILURE;
@ -512,14 +400,14 @@ nsPostScriptObj::initialize_translation(PrintSetup* pi)
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
* Write the document prolog.
* @param aHandle File handle which receives the prolog
*/
void
nsPostScriptObj::begin_document()
nsPostScriptObj::write_prolog(FILE *aHandle)
{
int i;
FILE *f;
int i;
FILE *f = aHandle;
nscoord paper_width = mPrintContext->prSetup->width;
nscoord paper_height = mPrintContext->prSetup->height;
@ -537,7 +425,6 @@ FILE *f;
else
orientation = "Portrait";
f = mPrintContext->prSetup->out;
fprintf(f, "%%!PS-Adobe-3.0\n");
fprintf(f, "%%%%BoundingBox: 0 0 %s %s\n",
fpCString(NSTwipsToFloatPoints(paper_width)).get(),
@ -548,18 +435,10 @@ FILE *f;
fprintf(f, "%%%%DocumentData: Clean8Bit\n");
fprintf(f, "%%%%DocumentPaperSizes: %s\n", mPrintSetup->paper_name);
fprintf(f, "%%%%Orientation: %s\n", orientation);
fprintf(f, "%%%%Pages: %d\n", (int) mPageNumber - 1);
// hmm, n_pages is always zero so don't use it
#if 0
fprintf(f, "%%%%Pages: %d\n", (int) mPrintContext->prInfo->n_pages);
#else
fprintf(f, "%%%%Pages: (atend)\n");
#endif
if (mPrintContext->prSetup->reverse)
fprintf(f, "%%%%PageOrder: Descend\n");
else
fprintf(f, "%%%%PageOrder: Ascend\n");
fprintf(f, "%%%%PageOrder: %s\n",
mPrintContext->prSetup->reverse ? "Descend" : "Ascend");
if (nsnull != mPrintContext->prInfo->doc_title) {
// DSC spec: max line length is 255 characters
@ -568,16 +447,10 @@ FILE *f;
fprintf(f, "\n");
}
#ifdef NOTYET
fprintf(f, "%%%%For: %n", user_name_stuff);
#endif
fprintf(f, "%%%%EndComments\n");
// general comments: Mozilla-specific
#ifdef NOTYET
fprintf(f, "\n%% MozillaURL: %s\n", mPrintContext->prSetup->url->address);
#endif
fprintf(f, "%% MozillaCharsetName: iso-8859-1\n\n");
fputs("% MozillaCharsetName: iso-8859-1\n\n", f);
// now begin prolog
fprintf(f, "%%%%BeginProlog\n");
@ -633,7 +506,6 @@ FILE *f;
"/F%d /%s Mfr\n"
"/f%d { dup /csize exch def /F%d Msf } bind def\n",
i, gSubstituteFonts[i].mPSName, i, i);
}
fprintf(f, "%s",
@ -1697,7 +1569,9 @@ FILE *f;
"16#FB4B /afii57700 def\n"
"end\n"
"def\n"
);
fprintf(f, "%s",
"10 dict dup begin\n"
" /FontType 3 def\n"
" /FontMatrix [.001 0 0 .001 0 0 ] def\n"
@ -1756,7 +1630,9 @@ FILE *f;
" } for\n"
" show pop pop\n"
"} def\n"
);
fprintf(f, "%s",
"/draw_undefined_char\n"
"{\n"
" csize /NoglyphFont Msf (a) show\n"
@ -1895,11 +1771,13 @@ FILE *f;
" /unicodeshow1 { real_glyph_unicodeshow } bind def\n"
" /unicodeshow2 { real_unicodeshow_native } bind def\n"
"} bind def\n"
);
// Procedure to stroke a rectangle. Coordinates are rounded
// to device pixel boundaries. See Adobe Technical notes 5111 and
// 5126 and the "Scan Conversion" section of the PS Language
// Reference for background.
fprintf(f, "%s",
"/Mrect { % x y w h Mrect -\n"
" 2 index add\n" // x y w h+y
" 4 1 roll\n" // h+y x y w
@ -1927,28 +1805,36 @@ FILE *f;
"\n"
);
// read the printer properties file
NS_LoadPersistentPropertiesFromURISpec(getter_AddRefs(mPrinterProps),
NS_LITERAL_CSTRING("resource:/res/unixpsfonts.properties"));
// setup prolog for each langgroup
initlanggroup();
initlanggroup(f);
fprintf(f, "%%%%EndProlog\n");
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 20/01/03 louie
* Copy the body of the print job to a stream.
* @param aDestHandle Stream which will receive the print job.
* @return NS_OK on success.
* NS_ERROR_GFX_PRINTER_FILE_IO_ERROR on any I/O error.
*/
void
nsPostScriptObj::add_cid_check()
nsresult
nsPostScriptObj::write_script(FILE *aDestHandle)
{
#ifdef MOZ_ENABLE_FREETYPE2
AddCIDCheckCode(mPrintContext->prSetup->out);
#endif
NS_PRECONDITION(aDestHandle, "Handle must not be NULL");
char buf[BUFSIZ];
size_t readAmt;
rewind(mScriptFP);
while ((readAmt = fread(buf, 1, sizeof buf, mScriptFP))) {
size_t writeAmt = fwrite(buf, 1, readAmt, aDestHandle);
if (readAmt != writeAmt)
break;
}
return ferror(mScriptFP) || ferror(aDestHandle) ?
NS_ERROR_GFX_PRINTER_FILE_IO_ERROR : NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
@ -1956,26 +1842,24 @@ nsPostScriptObj::add_cid_check()
void
nsPostScriptObj::begin_page()
{
FILE *f;
f = mPrintContext->prSetup->tmpBody;
fprintf(f, "%%%%Page: %d %d\n", mPageNumber, mPageNumber);
fprintf(f, "%%%%BeginPageSetup\n");
fprintf(mScriptFP, "%%%%Page: %d %d\n", mPageNumber, mPageNumber);
fprintf(mScriptFP, "%%%%BeginPageSetup\n");
if(mPrintSetup->num_copies != 1) {
fprintf(f, "1 dict dup /NumCopies %d put setpagedevice\n",
fprintf(mScriptFP, "1 dict dup /NumCopies %d put setpagedevice\n",
mPrintSetup->num_copies);
}
fprintf(f,"/pagelevel save def\n");
fprintf(mScriptFP,"/pagelevel save def\n");
// Rescale the coordinate system from points to twips.
scale(1.0 / TWIPS_PER_POINT_FLOAT, 1.0 / TWIPS_PER_POINT_FLOAT);
// Rotate and shift the coordinate system for landscape
if (mPrintContext->prSetup->landscape){
fprintf(f, "90 rotate 0 -%d translate\n", mPrintContext->prSetup->height);
fprintf(mScriptFP, "90 rotate 0 -%d translate\n",
mPrintContext->prSetup->height);
}
// Try to turn on automatic stroke adjust
fputs("true Msetstrokeadjust\n", f);
fprintf(f, "%%%%EndPageSetup\n");
fputs("true Msetstrokeadjust\n", mScriptFP);
fprintf(mScriptFP, "%%%%EndPageSetup\n");
// need to reset all U2Ntable
gLangGroups->Enumerate(ResetU2Ntable, nsnull);
@ -1988,8 +1872,7 @@ FILE *f;
void
nsPostScriptObj::end_page()
{
fprintf(mPrintContext->prSetup->tmpBody, "pagelevel restore\n");
fprintf(mPrintContext->prSetup->tmpBody, "showpage\n");
fputs("pagelevel restore showpage\n", mScriptFP);
mPageNumber++;
}
@ -2000,109 +1883,16 @@ nsPostScriptObj::end_page()
nsresult
nsPostScriptObj::end_document()
{
nsresult rv;
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("nsPostScriptObj::end_document()\n"));
NS_PRECONDITION(mScriptFP, "No script file handle");
// insurance against breakage
if (!mPrintContext || !mPrintContext->prSetup|| !mPrintContext->prSetup->out || !mPrintSetup)
return NS_ERROR_GFX_PRINTER_CMD_FAILURE;
FILE *f = mPrintContext->prSetup->out;
// output "tmpBody"
char buffer[256];
size_t length;
if (!mPrintContext->prSetup->tmpBody)
return NS_ERROR_GFX_PRINTER_CMD_FAILURE;
/* Reset file pointer to the beginning of the temp tmpBody file... */
fseek(mPrintContext->prSetup->tmpBody, 0, SEEK_SET);
/* Copy the document script (body) to the end of the prolog (header) */
while ((length = fread(buffer, 1, sizeof(buffer),
mPrintContext->prSetup->tmpBody)) > 0) {
fwrite(buffer, 1, length, f);
}
/* Close the script file handle and dispose of the temporary file */
if (mPrintSetup->tmpBody) {
fclose(mPrintSetup->tmpBody);
mPrintSetup->tmpBody = nsnull;
}
mDocScript->Remove(PR_FALSE);
mDocScript = nsnull;
// Finish up the document.
// n_pages is zero so use mPageNumber
fprintf(f, "%%%%Trailer\n");
fprintf(f, "%%%%Pages: %d\n", (int) mPageNumber - 1);
fprintf(f, "%%%%EOF\n");
fprintf(mScriptFP, "%%%%Trailer\n");
fprintf(mScriptFP, "%%%%EOF\n");
if (!mPrintSetup->print_cmd) {
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("print to file completed.\n"));
fclose(mPrintSetup->out);
rv = NS_OK;
}
else {
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("piping job to '%s'\n", mPrintSetup->print_cmd));
#ifdef VMS
// VMS can't print to a pipe, so issue a print command for the
// mDocProlog file.
fclose(mPrintSetup->out);
nsCAutoString prologFile;
rv = mDocProlog->GetNativePath(prologFile);
if (NS_SUCCEEDED(rv)) {
char *VMSPrintCommand =
PR_smprintf("%s %s.", mPrintSetup->print_cmd, prologFile.get());
if (!VMSPrintCommand)
rv = NS_ERROR_OUT_OF_MEMORY;
else {
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("VMS print command '%s'\n",
VMSPrintCommand));
int VMSstatus = system(VMSPrintCommand);
PR_smprintf_free(VMSPrintCommand);
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("VMS print status = %d\n",
VMSstatus));
rv = WIFEXITED(VMSstatus) ? NS_OK : NS_ERROR_GFX_PRINTER_CMD_FAILURE;
}
}
#else
// On *nix, popen() the print command and pipe the contents of
// mDocProlog into it.
FILE *pipe;
pipe = popen(mPrintSetup->print_cmd, "w");
if (!pipe)
rv = NS_ERROR_GFX_PRINTER_CMD_FAILURE;
else {
unsigned long job_size = 0;
/* Reset file pointer to the beginning of the temp file... */
fseek(mPrintSetup->out, 0, SEEK_SET);
while ((length = fread(buffer, 1, sizeof(buffer), mPrintSetup->out)) > 0)
{
fwrite(buffer, 1, length, pipe);
job_size += length;
}
fclose(mPrintSetup->out);
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG,
("piping done, copied %ld bytes.\n", job_size));
int exitStatus = pclose(pipe);
rv = WIFEXITED(exitStatus) ? NS_OK : NS_ERROR_GFX_PRINTER_CMD_FAILURE;
}
#endif
mDocProlog->Remove(PR_FALSE);
}
mPrintSetup->out = nsnull;
mDocProlog = nsnull;
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("postscript generation completed.\n"));
return rv;
return ferror(mScriptFP) ? NS_ERROR_GFX_PRINTER_FILE_IO_ERROR : NS_OK;
}
/** ---------------------------------------------------
@ -2112,25 +1902,22 @@ nsPostScriptObj::end_document()
void
nsPostScriptObj::show(const char* txt, int len, const char *align)
{
FILE *f;
f = mPrintContext->prSetup->tmpBody;
fprintf(f, "(");
fputc('(', mScriptFP);
while (len-- > 0) {
switch (*txt) {
case '(':
case ')':
case '\\':
fprintf(f, "\\%c", *txt);
break;
fputc('\\', mScriptFP);
// Fall through
default:
fprintf(f, "%c", *txt);
break;
fputc(*txt, mScriptFP);
break;
}
txt++;
}
fprintf(f, ") %sshow\n", align);
fprintf(mScriptFP, ") %sshow\n", align);
}
/** ---------------------------------------------------
@ -2140,7 +1927,6 @@ FILE *f;
void
nsPostScriptObj::preshow(const PRUnichar* txt, int len)
{
FILE *f = mPrintContext->prSetup->tmpBody;
unsigned char highbyte;
PRUnichar uch;
@ -2178,7 +1964,7 @@ nsPostScriptObj::preshow(const PRUnichar* txt, int len)
ncode = new PRInt32;
*ncode = code;
gU2Ntable->Put(&key, ncode);
fprintf(f, "%d <%x> u2nadd\n", uch, code);
fprintf(mScriptFP, "%d <%x> u2nadd\n", uch, code);
}
}
}
@ -2196,35 +1982,34 @@ void
nsPostScriptObj::show(const PRUnichar* txt, int len,
const char *align, int aType)
{
FILE *f = mPrintContext->prSetup->tmpBody;
unsigned char highbyte, lowbyte;
PRUnichar uch;
if (aType == 1) {
int i;
fprintf(f, "<");
fputc('<', mScriptFP);
for (i=0; i < len; i++) {
if (i == 0)
fprintf(f, "%04x", txt[i]);
fprintf(mScriptFP, "%04x", txt[i]);
else
fprintf(f, " %04x", txt[i]);
fprintf(mScriptFP, " %04x", txt[i]);
}
fprintf(f, "> show\n");
fputs("> show\n", mScriptFP);
return;
}
fprintf(f, "(");
fputc('(', mScriptFP);
while (len-- > 0) {
switch (*txt) {
case 0x0028: // '('
fprintf(f, "\\050\\000");
fputs("\\050\\000", mScriptFP);
break;
case 0x0029: // ')'
fprintf(f, "\\051\\000");
fputs("\\051\\000", mScriptFP);
break;
case 0x005c: // '\\'
fprintf(f, "\\134\\000");
fputs("\\134\\000", mScriptFP);
break;
default:
uch = *txt;
@ -2234,24 +2019,24 @@ nsPostScriptObj::show(const PRUnichar* txt, int len,
// we output all unicode chars in the 2x3 digits oct format for easier post-processing
// Our 'show' command will always treat the second 3 digit oct as high 8-bits of unicode, independent of Endians
if ( lowbyte < 8 )
fprintf(f, "\\00%o", lowbyte & 0xff);
fprintf(mScriptFP, "\\00%o", lowbyte & 0xff);
else if ( lowbyte < 64 && lowbyte >= 8)
fprintf(f, "\\0%o", lowbyte & 0xff);
fprintf(mScriptFP, "\\0%o", lowbyte & 0xff);
else
fprintf(f, "\\%o", lowbyte & 0xff);
fprintf(mScriptFP, "\\%o", lowbyte & 0xff);
if ( highbyte < 8 )
fprintf(f, "\\00%o", highbyte & 0xff);
fprintf(mScriptFP, "\\00%o", highbyte & 0xff);
else if ( highbyte < 64 && highbyte >= 8)
fprintf(f, "\\0%o", highbyte & 0xff);
fprintf(mScriptFP, "\\0%o", highbyte & 0xff);
else
fprintf(f, "\\%o", highbyte & 0xff);
fprintf(mScriptFP, "\\%o", highbyte & 0xff);
break;
break;
}
txt++;
}
fprintf(f, ") %sunicodeshow\n", align);
fprintf(mScriptFP, ") %sunicodeshow\n", align);
}
@ -2264,7 +2049,7 @@ nsPostScriptObj::show(const PRUnichar* txt, int len,
void
nsPostScriptObj::moveto(nscoord x, nscoord y)
{
fprintf(mPrintContext->prSetup->tmpBody, "%d %d moveto\n", x, y);
fprintf(mScriptFP, "%d %d moveto\n", x, y);
}
/** ---------------------------------------------------
@ -2274,7 +2059,7 @@ nsPostScriptObj::moveto(nscoord x, nscoord y)
void
nsPostScriptObj::lineto(nscoord aX, nscoord aY)
{
fprintf(mPrintContext->prSetup->tmpBody, "%d %d lineto\n", aX, aY);
fprintf(mScriptFP, "%d %d lineto\n", aX, aY);
}
/** ---------------------------------------------------
@ -2289,7 +2074,7 @@ nsPostScriptObj::arc(nscoord aWidth, nscoord aHeight,
float aStartAngle,float aEndAngle)
{
// Arc definition
fprintf(mPrintContext->prSetup->tmpBody,
fprintf(mScriptFP,
"%s %s matrix currentmatrix currentpoint translate\n"
" 3 1 roll scale newpath 0 0 1 %s %s arc setmatrix\n",
fpCString(aWidth * 0.5).get(), fpCString(aHeight * 0.5).get(),
@ -2303,8 +2088,7 @@ nsPostScriptObj::arc(nscoord aWidth, nscoord aHeight,
void
nsPostScriptObj::box(nscoord aX, nscoord aY, nscoord aW, nscoord aH)
{
fprintf(mPrintContext->prSetup->tmpBody,
"%d %d %d %d Mrect ", aX, aY, aW, aH);
fprintf(mScriptFP, "%d %d %d %d Mrect ", aX, aY, aW, aH);
}
/** ---------------------------------------------------
@ -2314,7 +2098,7 @@ nsPostScriptObj::box(nscoord aX, nscoord aY, nscoord aW, nscoord aH)
void
nsPostScriptObj::box_subtract(nscoord aX, nscoord aY, nscoord aW, nscoord aH)
{
fprintf(mPrintContext->prSetup->tmpBody,
fprintf(mScriptFP,
"%d %d moveto 0 %d rlineto %d 0 rlineto 0 %d rlineto closepath ",
aX, aY, aH, aW, -aH);
}
@ -2326,7 +2110,7 @@ nsPostScriptObj::box_subtract(nscoord aX, nscoord aY, nscoord aW, nscoord aH)
void
nsPostScriptObj::clip()
{
fprintf(mPrintContext->prSetup->tmpBody, " clip \n");
fputs(" clip\n", mScriptFP);
}
/** ---------------------------------------------------
@ -2336,7 +2120,7 @@ nsPostScriptObj::clip()
void
nsPostScriptObj::eoclip()
{
fprintf(mPrintContext->prSetup->tmpBody, " eoclip \n");
fputs(" eoclip\n", mScriptFP);
}
/** ---------------------------------------------------
@ -2346,7 +2130,7 @@ nsPostScriptObj::eoclip()
void
nsPostScriptObj::clippath()
{
fprintf(mPrintContext->prSetup->tmpBody, " clippath \n");
fputs(" clippath\n", mScriptFP);
}
/** ---------------------------------------------------
@ -2356,7 +2140,7 @@ nsPostScriptObj::clippath()
void
nsPostScriptObj::newpath()
{
fprintf(mPrintContext->prSetup->tmpBody, " newpath \n");
fputs(" newpath\n", mScriptFP);
}
/** ---------------------------------------------------
@ -2366,7 +2150,7 @@ nsPostScriptObj::newpath()
void
nsPostScriptObj::closepath()
{
fprintf(mPrintContext->prSetup->tmpBody, " closepath \n");
fputs(" closepath\n", mScriptFP);
}
/** ---------------------------------------------------
@ -2376,7 +2160,7 @@ nsPostScriptObj::closepath()
void
nsPostScriptObj::initclip()
{
fprintf(mPrintContext->prSetup->tmpBody, " initclip \n");
fputs(" initclip\n", mScriptFP);
}
/** ---------------------------------------------------
@ -2387,11 +2171,10 @@ void
nsPostScriptObj::line(nscoord aX1, nscoord aY1,
nscoord aX2, nscoord aY2, nscoord aThick)
{
fprintf(mPrintContext->prSetup->tmpBody, "gsave %d setlinewidth\n ", aThick);
fprintf(mPrintContext->prSetup->tmpBody, " %d %d moveto %d %d lineto\n",
aX1, aY1, aX2, aY2);
fprintf(mScriptFP, "gsave %d setlinewidth\n ", aThick);
fprintf(mScriptFP, " %d %d moveto %d %d lineto\n", aX1, aY1, aX2, aY2);
stroke();
fprintf(mPrintContext->prSetup->tmpBody, "grestore\n");
fprintf(mScriptFP, "grestore\n");
}
/** ---------------------------------------------------
@ -2401,7 +2184,7 @@ nsPostScriptObj::line(nscoord aX1, nscoord aY1,
void
nsPostScriptObj::stroke()
{
fprintf(mPrintContext->prSetup->tmpBody, " stroke \n");
fputs(" stroke\n", mScriptFP);
}
/** ---------------------------------------------------
@ -2411,7 +2194,7 @@ nsPostScriptObj::stroke()
void
nsPostScriptObj::fill()
{
fprintf(mPrintContext->prSetup->tmpBody, " fill \n");
fputs(" fill\n", mScriptFP);
}
/** ---------------------------------------------------
@ -2421,7 +2204,7 @@ nsPostScriptObj::fill()
void
nsPostScriptObj::graphics_save()
{
fprintf(mPrintContext->prSetup->tmpBody, " gsave \n");
fputs(" gsave\n", mScriptFP);
}
/** ---------------------------------------------------
@ -2431,7 +2214,7 @@ nsPostScriptObj::graphics_save()
void
nsPostScriptObj::graphics_restore()
{
fprintf(mPrintContext->prSetup->tmpBody, " grestore \n");
fputs(" grestore\n", mScriptFP);
}
@ -2443,7 +2226,7 @@ nsPostScriptObj::graphics_restore()
void
nsPostScriptObj::scale(float aX, float aY)
{
fprintf(mPrintContext->prSetup->tmpBody, "%s %s scale\n",
fprintf(mScriptFP, "%s %s scale\n",
fpCString(aX).get(), fpCString(aX).get());
}
@ -2454,7 +2237,7 @@ nsPostScriptObj::scale(float aX, float aY)
void
nsPostScriptObj::translate(nscoord x, nscoord y)
{
fprintf(mPrintContext->prSetup->tmpBody, "%d %d translate\n", x, y);
fprintf(mScriptFP, "%d %d translate\n", x, y);
}
@ -2492,8 +2275,6 @@ void
nsPostScriptObj::draw_image(nsIImage *anImage,
const nsRect& sRect, const nsRect& iRect, const nsRect& dRect)
{
FILE *f = mPrintContext->prSetup->tmpBody;
// If a final image dimension is 0 pixels, just return (see bug 191684)
if ((0 == dRect.width) || (0 == dRect.height)) {
return;
@ -2511,7 +2292,7 @@ nsPostScriptObj::draw_image(nsIImage *anImage,
// Save the current graphic state and define a PS variable that
// can hold one line of pixel data.
fprintf(f, "gsave\n/rowdata %d string def\n",
fprintf(mScriptFP, "gsave\n/rowdata %d string def\n",
mPrintSetup->color ? iRect.width * 3 : iRect.width);
// Translate the coordinate origin to the corner of the rectangle where
@ -2520,11 +2301,11 @@ nsPostScriptObj::draw_image(nsIImage *anImage,
translate(dRect.x, dRect.y);
box(0, 0, dRect.width, dRect.height);
clip();
fprintf(f, "%d %d scale\n", dRect.width, dRect.height);
fprintf(mScriptFP, "%d %d scale\n", dRect.width, dRect.height);
// Describe how the pixel data is to be interpreted: pixels per row,
// rows, and bits per pixel (per component in color).
fprintf(f, "%d %d 8 ", iRect.width, iRect.height);
fprintf(mScriptFP, "%d %d 8 ", iRect.width, iRect.height);
// Output the transformation matrix for the image. This is a bit tricky
// to understand. PS image-drawing operations involve two transformation
@ -2566,14 +2347,14 @@ nsPostScriptObj::draw_image(nsIImage *anImage,
tmTY += tmSY;
tmSY = -tmSY;
}
fprintf(f, "[ %d 0 0 %d %d %d ]\n", tmSX, tmSY, tmTX, tmTY);
fprintf(mScriptFP, "[ %d 0 0 %d %d %d ]\n", tmSX, tmSY, tmTX, tmTY);
// Output the data-reading procedure and the appropriate image command.
fputs(" { currentfile rowdata readhexstring pop }", f);
fputs(" { currentfile rowdata readhexstring pop }", mScriptFP);
if (mPrintSetup->color)
fputs(" false 3 colorimage\n", f);
fputs(" false 3 colorimage\n", mScriptFP);
else
fputs(" image\n", f);
fputs(" image\n", mScriptFP);
// Output the image data. The entire image is written, even
// if it's partially clipped in the document.
@ -2589,12 +2370,13 @@ nsPostScriptObj::draw_image(nsIImage *anImage,
PRUint8 *pixel = row + (x * 3);
if (mPrintSetup->color)
outputCount +=
fprintf(f, "%02x%02x%02x", pixel[0], pixel[1], pixel[2]);
fprintf(mScriptFP, "%02x%02x%02x", pixel[0], pixel[1], pixel[2]);
else
outputCount +=
fprintf(f, "%02x", NS_RGB_TO_GRAY(pixel[0], pixel[1], pixel[2]));
fprintf(mScriptFP, "%02x",
NS_RGB_TO_GRAY(pixel[0], pixel[1], pixel[2]));
if (outputCount >= 72) {
fputc('\n', f);
fputc('\n', mScriptFP);
outputCount = 0;
}
}
@ -2602,8 +2384,8 @@ nsPostScriptObj::draw_image(nsIImage *anImage,
anImage->UnlockImagePixels(PR_FALSE);
// Free the PS data buffer and restore the previous graphics state.
fputs("\n/rowdata where { /rowdata undef } if\n", f);
fputs("grestore\n", f);
fputs("\n/rowdata where { /rowdata undef } if\n", mScriptFP);
fputs("grestore\n", mScriptFP);
}
@ -2625,10 +2407,9 @@ float greyBrightness;
greyBrightness=NS_PS_GRAY(NS_RGB_TO_GRAY(NS_GET_R(aColor),
NS_GET_G(aColor),
NS_GET_B(aColor)));
fprintf(mPrintContext->prSetup->tmpBody, "%s setgray\n",
fpCString(greyBrightness).get());
fprintf(mScriptFP, "%s setgray\n", fpCString(greyBrightness).get());
} else {
fprintf(mPrintContext->prSetup->tmpBody, "%s %s %s setrgbcolor\n",
fprintf(mScriptFP, "%s %s %s setrgbcolor\n",
fpCString(NS_PS_RED(aColor)).get(),
fpCString(NS_PS_GREEN(aColor)).get(),
fpCString(NS_PS_BLUE(aColor)).get());
@ -2639,8 +2420,7 @@ float greyBrightness;
void nsPostScriptObj::setfont(const nsCString aFontName, PRUint32 aHeight)
{
fprintf(mPrintContext->prSetup->tmpBody,
"%d /%s Msf\n", aHeight, aFontName.get());
fprintf(mScriptFP, "%d /%s Msf\n", aHeight, aFontName.get());
}
/** ---------------------------------------------------
@ -2653,11 +2433,7 @@ nsPostScriptObj::setscriptfont(PRInt16 aFontIndex,const nsString &aFamily,nscoor
{
int postscriptFont = 0;
// fprintf(mPrintContext->prSetup->out, "%% aFontIndex = %d, Family = %s, aStyle = %d,
// aWeight=%d, postscriptfont = %d\n", aFontIndex, &aFamily, aStyle, aWeight, postscriptFont);
fprintf(mPrintContext->prSetup->tmpBody,"%d", aHeight);
fprintf(mScriptFP, "%d", aHeight);
if( aFontIndex >= 0) {
postscriptFont = aFontIndex;
@ -2693,7 +2469,7 @@ int postscriptFont = 0;
}
//#endif
}
fprintf(mPrintContext->prSetup->tmpBody, " f%d\n", postscriptFont);
fprintf(mScriptFP, " f%d\n", postscriptFont);
#if 0
@ -2723,7 +2499,7 @@ int postscriptFont = 0;
void
nsPostScriptObj::comment(const char *aTheComment)
{
fprintf(mPrintContext->prSetup->tmpBody,"%%%s\n", aTheComment);
fprintf(mScriptFP, "%%%s\n", aTheComment);
}
/** ---------------------------------------------------
@ -2733,13 +2509,11 @@ nsPostScriptObj::comment(const char *aTheComment)
void
nsPostScriptObj::setlanggroup(nsIAtom * aLangGroup)
{
FILE *f = mPrintContext->prSetup->tmpBody;
gEncoder = nsnull;
gU2Ntable = nsnull;
if (aLangGroup == nsnull) {
fprintf(f, "default_ls\n");
fputs("default_ls\n", mScriptFP);
return;
}
nsAutoString langstr;
@ -2751,12 +2525,12 @@ nsPostScriptObj::setlanggroup(nsIAtom * aLangGroup)
if (linfo) {
nsCAutoString str; str.AssignWithConversion(langstr);
fprintf(f, "%s_ls\n", str.get());
fprintf(mScriptFP, "%s_ls\n", str.get());
gEncoder = linfo->mEncoder;
gU2Ntable = linfo->mU2Ntable;
return;
} else {
fprintf(f, "default_ls\n");
fputs("default_ls\n", mScriptFP);
}
}
@ -2803,20 +2577,20 @@ GetUnixPrinterFallbackSetting(const nsCAutoString& aKey, char** aVal)
return PR_FALSE;
}
FILE * nsPostScriptObj::GetPrintFile()
{
return(mPrintContext->prSetup->out);
}
const char* kNativeFontPrefix = "print.postscript.nativefont.";
const char* kUnicodeFontPrefix = "print.postscript.unicodefont.";
struct PrefEnumClosure {
FILE *handle; // Output file handle
nsPostScriptObj *psObj; // Renderer
};
/* make <langgroup>_ls define for each LangGroup here */
static void PrefEnumCallback(const char *aName, void *aClosure)
{
nsPostScriptObj *psObj = (nsPostScriptObj*)aClosure;
FILE *f = psObj->GetPrintFile();
nsPostScriptObj *psObj = ((PrefEnumClosure *)aClosure)->psObj;
FILE *f = ((PrefEnumClosure *)aClosure)->handle;
nsAutoString lang; lang.AssignWithConversion(aName);
@ -2964,14 +2738,17 @@ static void PrefEnumCallback(const char *aName, void *aClosure)
* @update 5/30/00 katakai
*/
void
nsPostScriptObj::initlanggroup()
nsPostScriptObj::initlanggroup(FILE *aHandle)
{
PrefEnumClosure closure;
closure.handle = aHandle;
closure.psObj = this;
/* check langgroup of preference */
gPrefs->EnumerateChildren(kNativeFontPrefix,
PrefEnumCallback, (void *) this);
PrefEnumCallback, (void *) &closure);
gPrefs->EnumerateChildren(kUnicodeFontPrefix,
PrefEnumCallback, (void *) this);
PrefEnumCallback, (void *) &closure);
}

Просмотреть файл

@ -21,7 +21,7 @@
*
* Contributor(s):
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
* Ken Herron <kherron@newsguy.com>
* Ken Herron <kherron@fastmail.us>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -58,6 +58,7 @@
#include "nsTempfilePS.h"
class nsIImage;
class nsIAtom;
#endif
#include <stdio.h>
@ -137,12 +138,9 @@ struct PrintSetup_ {
const char* bullet; /* What char to use for bullets */
struct URL_Struct_ *url; /* url of doc being translated */
FILE *out; /* Where to send the output */
FILE *tmpBody; /* temp file for True-Type printing */
XL_CompletionRoutine completion; /* Called when translation finished */
void* carg; /* Data saved for completion routine */
int status; /* Status of URL on completion */
const char *print_cmd; /* print command */
int num_copies; /* Number of copies of job to print */
};
@ -183,22 +181,26 @@ public:
* @update 2/1/99 dwc
*/
void end_page();
/** ---------------------------------------------------
* start the current document
* @update 2/1/99 dwc
*/
void begin_document();
/** ---------------------------------------------------
* end the current document
* @update 2/1/99 dwc
*/
nsresult end_document();
/** ---------------------------------------------------
* add CID check code
* @update 01/20/03 louie
* Write the document prolog to the given file handle
* @param File handle which should receive the prolog.
*/
void add_cid_check();
void write_prolog(FILE *aHandle);
/** ---------------------------------------------------
* Write the document script (body) to the given file handle.
* @param File handle which should receive the prolog.
* @return NS_OK or a suitable error code for I/O errors.
*/
nsresult write_script(FILE *aHandle);
/** ---------------------------------------------------
* move the current point to this location
* @update 9/30/2003 kherron
@ -394,7 +396,13 @@ public:
void settitle(PRUnichar * aTitle);
FILE * GetPrintFile();
/** ---------------------------------------------------
* Retrieve the handle for the temp file holding the
* document script.
* @return the script file handle.
*/
FILE * GetScriptHandle() { return mScriptFP; }
PRBool GetUnixPrinterSetting(const nsCAutoString&, char**);
PrintSetup *mPrintSetup;
private:
@ -403,9 +411,8 @@ private:
nsCOMPtr<nsIPersistentProperties> mPrinterProps;
char *mTitle;
nsTempfilePS mTempfileFactory;
nsCOMPtr<nsILocalFile> mDocProlog;
nsCOMPtr<nsILocalFile> mDocScript;
FILE *mScriptFP;
/** ---------------------------------------------------
@ -415,9 +422,10 @@ private:
void initialize_translation(PrintSetup* aPi);
/** ---------------------------------------------------
* initialize language group
* @update 5/30/00 katakai
* @update 5/17/2004 kherron
* @param aHandle File handle to write langgroup directives
*/
void initlanggroup();
void initlanggroup(FILE *aHandle);
};

Просмотреть файл

@ -0,0 +1,83 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public 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.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Kenneth Herron <kherron@fastmail.us>
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nsDebug.h"
#include "nsPrintJobFactoryPS.h"
#include "nsIDeviceContextSpecPS.h"
#include "nsPrintJobPS.h"
/**
* Construct a print job object for the given device context spec.
*
* @param aSpec An nsIDeviceContextSpecPS object for the print
* job in question.
* @param aPrintJob A pointer to a print job object which will
* handle the print job.
* @return NS_OK if all is well, or a suitable error value.
*/
nsresult
nsPrintJobFactoryPS::CreatePrintJob(nsIDeviceContextSpecPS *aSpec,
nsIPrintJobPS* &aPrintJob)
{
NS_PRECONDITION(nsnull != aSpec, "aSpec is NULL");
nsIPrintJobPS *newPJ;
PRBool destIsPrinter;
aSpec->GetToPrinter(destIsPrinter);
if (destIsPrinter)
#ifdef VMS
newPJ = new nsPrintJobVMSCmdPS();
#else
newPJ = new nsPrintJobPipePS();
#endif
else
newPJ = new nsPrintJobFilePS();
if (!newPJ)
return NS_ERROR_OUT_OF_MEMORY;
nsresult rv = newPJ->Init(aSpec);
if (NS_FAILED(rv))
delete newPJ;
else
aPrintJob = newPJ;
return rv;
}

Просмотреть файл

@ -0,0 +1,71 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public 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.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Kenneth Herron <kherron@fastmail.us>
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsPrintJobFactoryPS_h__
#define nsPrintJobFactoryPS_h__
#include "nscore.h"
#include "nsIPrintJobPS.h"
/* Factory class for the print job subsystem. This class determines
* which print job class should handle a print job, and constructs
* an object of the appropriate class.
*/
class nsPrintJobFactoryPS
{
public:
/**
* Construct a print job object for the given device context spec.
* On success, the print job object is owned by the caller and should
* be destroyed when no longer needed.
*
* @param aSpec An nsIDeviceContextSpecPS object for the print
* job in question.
* @param aPrintJob If NS_OK is returned, this will be filled in with
* a pointer to a print job object.
* @return NS_OK or a suitable error value.
*/
static nsresult CreatePrintJob(nsIDeviceContextSpecPS *aSpec,
nsIPrintJobPS* &aPrintJob);
};
#endif /* nsPrintJobFactoryPS_h__ */

418
gfx/src/ps/nsPrintJobPS.cpp Normal file
Просмотреть файл

@ -0,0 +1,418 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public 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.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Ken Herron <kherron@fastmail.us>
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#include "nscore.h"
#include "nsIDeviceContext.h" // NS_ERROR_GFX_*
#include "nsIDeviceContextPS.h" // NS_POSTSCRIPT_DRIVER_NAME_LEN
#include "nsIDeviceContextSpecPS.h"
#include "nsPrintJobPS.h"
#include "nsReadableUtils.h"
#include "prenv.h"
#include "prinit.h"
#include "prlock.h"
#include "prprf.h"
#include <stdlib.h>
#include <sys/wait.h>
/* Routines to set environment variables. These are defined toward
* the end of this file.
*/
static PRStatus EnvLock();
static PRStatus EnvSetPrinter(nsCString&);
static void EnvClear();
/* ~nsIPrintJobPS() is virtual, so must implement a destructor. */
nsIPrintJobPS::~nsIPrintJobPS() {}
/**** nsPrintJobPreviewPS - Stub class for print preview ****/
nsresult
nsPrintJobPreviewPS::Init(nsIDeviceContextSpecPS *aSpec)
{
return NS_OK;
}
/**** nsPrintJobFilePS - Print-to-file support ****/
/* Print-to-file constructor */
nsPrintJobFilePS::nsPrintJobFilePS() : mDestHandle(nsnull) { };
/* Print-to-file destructor */
nsPrintJobFilePS::~nsPrintJobFilePS()
{
if (mDestHandle)
fclose(mDestHandle);
}
/**
* Initialize the print-to-file object from the printing spec.
* See nsPrintJobPS.h for details.
*/
nsresult
nsPrintJobFilePS::Init(nsIDeviceContextSpecPS *aSpec)
{
NS_PRECONDITION(aSpec, "aSpec must not be NULL");
#ifdef DEBUG
PRBool toPrinter;
aSpec->GetToPrinter(toPrinter);
NS_PRECONDITION(!toPrinter, "This print job is to a printer");
#endif
const char *path;
aSpec->GetPath(&path);
mDestination = path;
return NS_OK;
}
/**
* Create the final output file and copy the temporary files there.
* See nsIPrintJobPS.h and nsPrintJobPS.h for details.
*/
nsresult
nsPrintJobFilePS::StartSubmission(FILE **aHandle)
{
NS_PRECONDITION(aHandle, "aHandle is NULL");
NS_PRECONDITION(!mDestination.IsEmpty(), "No destination");
NS_PRECONDITION(!mDestHandle, "Already have a destination handle");
nsCOMPtr<nsILocalFile> destFile;
nsresult rv = NS_NewNativeLocalFile(GetDestination(),
PR_FALSE, getter_AddRefs(destFile));
if (NS_SUCCEEDED(rv))
rv = destFile->OpenANSIFileDesc("w", &mDestHandle);
NS_ENSURE_SUCCESS(rv, NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE);
NS_POSTCONDITION(mDestHandle,
"OpenANSIFileDesc succeeded but no file handle");
*aHandle = mDestHandle;
return rv;
}
/**
* Finish a print job. See nsIPrintJobPS.h and nsPrintJobPS.h for details.
*/
nsresult
nsPrintJobFilePS::FinishSubmission()
{
NS_PRECONDITION(mDestHandle, "No destination file handle");
fclose(mDestHandle);
mDestHandle = nsnull;
return NS_OK;
}
#ifdef VMS
/**** Print-to-command on VMS. ****/
/* This implementation writes the print job to a temporary file, then runs
* the print command with the name of that file appended.
*/
/**
* Initialize a VMS print-to-command object from the printing spec.
* See nsIPrintJobPS.h and nsPrintJobPS.h.
*/
nsresult
nsPrintJobVMSCmdPS::Init(nsIDeviceContextSpecPS *aSpec)
{
NS_PRECONDITION(aSpec, "argument must not be NULL");
#ifdef DEBUG
PRBool toPrinter;
aSpec->GetToPrinter(toPrinter);
NS_PRECONDITION(toPrinter, "This print job is not to a printer");
#endif
/* Print command. This is stored as the destination string. */
const char *command;
aSpec->GetCommand(&command);
SetDestination(command);
/* Printer name */
const char *printerName;
aSpec->GetPrinterName(&printerName);
if (printerName) {
printerName += NS_POSTSCRIPT_DRIVER_NAME_LEN;
if (0 != strcmp(printerName, "default"))
mPrinterName = printerName;
}
return NS_OK;
}
/**
* Create the temporary file for the print job and return a file handle
* to the caller.
* See nsIPrintJobPS.h and nsPrintJobPS.h for details.
*/
nsresult
nsPrintJobVMSCmdPS::StartSubmission(FILE **aHandle)
{
NS_PRECONDITION(aHandle, "aHandle is NULL");
NS_PRECONDITION(!GetDestination().IsEmpty(), "No destination");
NS_PRECONDITION(!GetDestHandle(), "Already have a destination handle");
/* Create the final output file */
FILE *printHandle = nsnull;
nsresult rv = mTempFactory.CreateTempFile(
getter_AddRefs(mTempFile), &printHandle, "w+");
if (NS_SUCCEEDED(rv)) {
SetDestHandle(printHandle);
*aHandle = printHandle;
}
return rv;
}
nsresult
nsPrintJobVMSCmdPS::FinishSubmission()
{
NS_PRECONDITION(GetDestHandle(), "No destination file handle");
NS_PRECONDITION(!GetDestination().IsEmpty(), "No destination");
/* Close the temporary file handle */
fclose(GetDestHandle());
SetDestHandle(nsnull);
/* construct the print command */
nsCAutoString printFileName;
nsresult rv = mTempFile->GetNativePath(printFileName);
if (NS_SUCCEEDED(rv)) {
nsCAutoString cmd(GetDestination());
cmd += " "; cmd += printFileName; cmd += ".";
/* Set up the environment. */
if (PR_SUCCESS != EnvLock())
return NS_ERROR_OUT_OF_MEMORY;
if (!mPrinterName.IsEmpty())
EnvSetPrinter(mPrinterName);
/* Run the print command */
int presult = system(cmd.get());
/* Clean up */
EnvClear();
mTempFile->Remove(PR_FALSE);
rv = (!WIFEXITED(presult) || (EXIT_SUCCESS != WEXITSTATUS(presult)))
? NS_ERROR_GFX_PRINTER_CMD_FAILURE : NS_OK;
}
return rv;
}
#else /* NOT VMS */
/**** Print-to-Pipe for unix and unix-like systems ****/
/* This launches a command using popen(); the print job is then written
* to the pipe.
*/
/* Destructor. We must override the print-to-file destructor in order
* to pclose() any open file handle.
*/
nsPrintJobPipePS::~nsPrintJobPipePS()
{
if (GetDestHandle()) {
pclose(GetDestHandle());
SetDestHandle(nsnull);
}
}
/**
* Initialize a print-to-pipe object.
* See nsIPrintJobPS.h and nsPrintJobPS.h for details.
*/
nsresult
nsPrintJobPipePS::Init(nsIDeviceContextSpecPS *aSpec)
{
NS_PRECONDITION(aSpec, "argument must not be NULL");
#ifdef DEBUG
PRBool toPrinter;
aSpec->GetToPrinter(toPrinter);
NS_PRECONDITION(toPrinter, "Wrong class for this print job");
#endif
/* Print command. This is stored as the destination string. */
const char *command;
aSpec->GetCommand(&command);
SetDestination(command);
/* Printer name */
const char *printerName;
aSpec->GetPrinterName(&printerName);
if (printerName) {
printerName += NS_POSTSCRIPT_DRIVER_NAME_LEN;
if (0 != strcmp(printerName, "default"))
mPrinterName = printerName;
}
return NS_OK;
}
/**
* Launch the print command using popen(), then copy the print job data
* to the pipe. See nsIPrintJobPS.h and nsPrintJobPS.h for details.
*/
nsresult
nsPrintJobPipePS::StartSubmission(FILE **aHandle)
{
NS_PRECONDITION(aHandle, "aHandle is NULL");
NS_PRECONDITION(!GetDestination().IsEmpty(), "No destination");
NS_PRECONDITION(!GetDestHandle(), "Already have a destination handle");
if (PR_SUCCESS != EnvLock())
return NS_ERROR_OUT_OF_MEMORY; // Couldn't allocate the object?
if (!mPrinterName.IsEmpty())
EnvSetPrinter(mPrinterName);
FILE *destPipe = popen(GetDestination().get(), "w");
EnvClear();
if (!destPipe)
return NS_ERROR_GFX_PRINTER_CMD_FAILURE;
SetDestHandle(destPipe);
*aHandle = destPipe;
return NS_OK;
}
nsresult
nsPrintJobPipePS::FinishSubmission()
{
NS_PRECONDITION(GetDestHandle(), "No destination file handle");
NS_PRECONDITION(!GetDestination().IsEmpty(), "No destination");
int presult = pclose(GetDestHandle());
SetDestHandle(nsnull);
if (!WIFEXITED(presult) || (EXIT_SUCCESS != WEXITSTATUS(presult)))
return NS_ERROR_GFX_PRINTER_CMD_FAILURE;
return NS_OK;
}
#endif /* VMS */
/* Routines to set the MOZ_PRINTER_NAME environment variable and to
* single-thread print jobs while the variable is set.
*/
static PRLock *EnvLockObj;
static PRCallOnceType EnvLockOnce;
/* EnvLock callback function */
static PRStatus
EnvLockInit()
{
EnvLockObj = PR_NewLock();
return EnvLockObj ? PR_SUCCESS : PR_FAILURE;
}
/**
* Get the lock for setting printing-related environment variables and
* running print commands.
* @return PR_SUCCESS on success
* PR_FAILURE if the lock object could not be initialized.
*
*/
static PRStatus
EnvLock()
{
if (PR_FAILURE == PR_CallOnce(&EnvLockOnce, EnvLockInit))
return PR_FAILURE;
PR_Lock(EnvLockObj);
return PR_SUCCESS;
}
static char *EnvPrinterString;
static const char EnvPrinterName[] = { "MOZ_PRINTER_NAME" };
/**
* Set MOZ_PRINTER_NAME to the specified string.
* @param aPrinter The value for MOZ_PRINTER_NAME. May be an empty string.
* @return PR_SUCCESS on success.
* PR_FAILURE if memory could not be allocated.
*/
static PRStatus
EnvSetPrinter(nsCString& aPrinter)
{
/* Construct the new environment string */
char *newVar = PR_smprintf("%s=%s", EnvPrinterName, aPrinter.get());
if (!newVar)
return PR_FAILURE;
/* Add it to the environment and dispose of any old string */
PR_SetEnv(newVar);
if (EnvPrinterString)
PR_smprintf_free(EnvPrinterString);
EnvPrinterString = newVar;
return PR_SUCCESS;
}
/**
* Clear the printer environment variable and release the environment lock.
*/
static void
EnvClear()
{
if (EnvPrinterString) {
/* On some systems, setenv("FOO") will remove FOO
* from the environment.
*/
PR_SetEnv(EnvPrinterName);
if (!PR_GetEnv(EnvPrinterName)) {
/* It must have worked */
PR_smprintf_free(EnvPrinterString);
EnvPrinterString = nsnull;
}
}
PR_Unlock(EnvLockObj);
}

160
gfx/src/ps/nsPrintJobPS.h Normal file
Просмотреть файл

@ -0,0 +1,160 @@
/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
/* ex: set tabstop=8 softtabstop=4 shiftwidth=4 expandtab: */
/* ***** BEGIN LICENSE BLOCK *****
* Version: NPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Netscape Public 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.mozilla.org/NPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is mozilla.org code.
*
* The Initial Developer of the Original Code is
* Ken Herron <kherron@fastmail.us>
* Portions created by the Initial Developer are Copyright (C) 2004
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
*
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the NPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the NPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
#ifndef nsPrintJobPS_h__
#define nsPrintJobPS_h__
#include "nsDebug.h"
#include "nsIDeviceContext.h" // for NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED
#include "nsILocalFile.h"
#include "nsIPrintJobPS.h"
#include "nsString.h"
#include "nsTempfilePS.h"
/* Print job class for print preview operations. */
class nsPrintJobPreviewPS : public nsIPrintJobPS {
public:
/* see nsIPrintJobPS.h. Print preview doesn't actually
* implement printing.
*/
nsresult StartSubmission(FILE **aHandle)
{ return NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED; }
nsresult FinishSubmission()
{ return NS_ERROR_GFX_PRINTING_NOT_IMPLEMENTED; }
protected:
/* See nsIPrintJobPS.h. */
nsresult Init(nsIDeviceContextSpecPS *);
};
/* Print job class for print-to-file. */
class nsPrintJobFilePS : public nsIPrintJobPS {
public:
nsPrintJobFilePS();
~nsPrintJobFilePS();
/* see nsIPrintJobPS.h */
nsresult StartSubmission(FILE **aHandle);
nsresult FinishSubmission();
protected:
/* see nsIPrintJobPS.h */
nsresult Init(nsIDeviceContextSpecPS *);
/**
* Set the destination file handle.
* @param aHandle New value for the handle.
*/
void SetDestHandle(FILE *aHandle) { mDestHandle = aHandle; }
/**
* Get the current value for the destination file handle.
* @return the current value for the destination file handle.
*/
FILE *GetDestHandle() { return mDestHandle; }
/**
* Set a string representing the destination. For print-to-file
* this is the name of the destination file. Subclasses could
* store something else here.
* @param aDest Destination filename.
*/
void SetDestination(const char *aDest) { mDestination = aDest; }
/**
* Get the string representing the destination.
* @return The current value of the destination string.
*/
nsCString& GetDestination() { return mDestination; }
private:
FILE *mDestHandle; // Destination file handle
nsCString mDestination;
};
#ifdef VMS
/* This is the class for printing by launching a command on VMS. The
* string for GetDestination() and SetDestination() is a command to be
* executed, rather than a filename.
*/
class nsPrintJobVMSCmdPS : public nsPrintJobFilePS {
public:
/* see nsIPrintJobPS.h */
nsresult StartSubmission(FILE **aHandle);
nsresult FinishSubmission();
protected:
nsresult Init(nsIDeviceContextSpecPS *);
private:
nsCString mPrinterName;
nsTempfilePS mTempFactory;
nsCOMPtr<nsILocalFile> mTempFile;
};
#else /* Not VMS */
/* This is the class for printing to a pipe. The destination for
* GetDestination() and SetDestination() is a command to be executed,
* rather than a filename.
*/
class nsPrintJobPipePS : public nsPrintJobFilePS {
public:
/* see nsIPrintJobPS.h */
~nsPrintJobPipePS();
nsresult StartSubmission(FILE **aHandle);
nsresult FinishSubmission();
protected:
nsresult Init(nsIDeviceContextSpecPS *);
private:
nsCString mPrinterName;
};
#endif /* VMS */
#endif /* nsPrintJobPS_h__ */

Просмотреть файл

@ -22,6 +22,7 @@
* Contributor(s):
* Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
* Leon Sha <leon.sha@sun.com>
* Ken Herron <kherron@fastmail.us>
*
* Alternatively, the contents of this file may be used under the terms of
* either of the GNU General Public License Version 2 or later (the "GPL"),
@ -1316,7 +1317,7 @@ NS_IMETHODIMP nsRenderingContextPS::RenderPostScriptDataFragment(const unsigned
// Reset the coordinate system to point-sized. The origin and Y axis
// orientation are already correct.
mPSObj->scale(TWIPS_PER_POINT_FLOAT, TWIPS_PER_POINT_FLOAT);
fwrite(aData, aDatalen, 1, mPSObj->mPrintSetup->tmpBody);
fwrite(aData, aDatalen, 1, mPSObj->GetScriptHandle());
return NS_OK;
}