fune/gfx/src/ps/nsPostScriptObj.cpp

2981 lines
88 KiB
C++

/* -*- 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
* 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/MPL/
*
* 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
* Netscape Communications Corporation.
* Portions created by the Initial Developer are Copyright (C) 1998
* the Initial Developer. All Rights Reserved.
*
* 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"),
* 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 MPL, 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 MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK *****
*
* This Original Code has been modified by IBM Corporation. Modifications made by IBM
* described herein are Copyright (c) International Business Machines Corporation, 2000.
* Modifications to Mozilla code or documentation identified per MPL Section 3.3
*
* Date Modified by Description of modification
* 04/20/2000 IBM Corp. OS/2 VisualAge build.
* 10/09/2000 IPLabs Linux Team True Unicode glyps support added.
*/
#include "gfx-config.h"
#define FORCE_PR_LOG /* Allow logging in the release build */
#define PR_LOGGING 1
#include "prlog.h"
#include "nscore.h"
#include "nsIAtom.h"
#include "nsPostScriptObj.h"
#include "isotab.c"
#include "nsFont.h"
#include "nsIImage.h"
#include "nsAFMObject.h"
#include "nsIServiceManager.h"
#include "nsICharsetConverterManager.h"
#include "nsIUnicodeEncoder.h"
#include "nsIUnicodeDecoder.h"
#include "nsReadableUtils.h"
#include "nsICharsetAlias.h"
#include "nsNetUtil.h"
#include "nsIPersistentProperties2.h"
#include "nsCRT.h"
#include "nsFontMetricsPS.h"
#include "nsPrintfCString.h"
#include "prenv.h"
#include "prprf.h"
#include "prerror.h"
#include <errno.h>
#include <sys/wait.h>
#ifdef PR_LOGGING
static PRLogModuleInfo *nsPostScriptObjLM = PR_NewLogModule("nsPostScriptObj");
#endif /* PR_LOGGING */
/* A private class to format floating-point values into strings. This
* is used to write floating-point values into the postscript document.
* printf()-based functions can't be used because they may generate
* locale-ized output, e.g. using a comma for the decimal point, which
* isn't a valid postscript number.
*/
class fpCString : public nsCAutoString {
public:
inline fpCString(float aValue) { AppendFloat(aValue); }
};
#define NS_PS_RED(x) (((float)(NS_GET_R(x))) / 255.0)
#define NS_PS_GREEN(x) (((float)(NS_GET_G(x))) / 255.0)
#define NS_PS_BLUE(x) (((float)(NS_GET_B(x))) / 255.0)
#define NS_PS_GRAY(x) (((float)(x)) / 255.0)
#define NS_RGB_TO_GRAY(r,g,b) ((int(r) * 77 + int(g) * 150 + int(b) * 29) / 256)
#define NS_IS_BOLD(x) (((x) >= 401) ? 1 : 0)
/*
* global
*/
static nsIUnicodeEncoder *gEncoder = nsnull;
static nsHashtable *gU2Ntable = nsnull;
static nsIPref *gPrefs = nsnull;
static nsHashtable *gLangGroups = nsnull;
static PRBool
FreeU2Ntable(nsHashKey * aKey, void *aData, void *aClosure)
{
delete(int *) aData;
return PR_TRUE;
}
static PRBool
ResetU2Ntable(nsHashKey * aKey, void *aData, void *aClosure)
{
PS_LangGroupInfo *linfo = (PS_LangGroupInfo *)aData;
if (linfo && linfo->mU2Ntable) {
linfo->mU2Ntable->Reset(FreeU2Ntable, nsnull);
}
return PR_TRUE;
}
static PRBool
FreeLangGroups(nsHashKey * aKey, void *aData, void *aClosure)
{
PS_LangGroupInfo *linfo = (PS_LangGroupInfo *) aData;
NS_IF_RELEASE(linfo->mEncoder);
if (linfo->mU2Ntable) {
linfo->mU2Ntable->Reset(FreeU2Ntable, nsnull);
delete linfo->mU2Ntable;
linfo->mU2Ntable = nsnull;
}
delete linfo;
linfo = nsnull;
return PR_TRUE;
}
static void
PrintAsDSCTextline(FILE *f, const char *text, int maxlen)
{
NS_ASSERTION(maxlen > 1, "bad max length");
if (*text != '(') {
// Format as DSC textline type
fprintf(f, "%.*s", maxlen, text);
return;
}
// Fallback: Format as DSC text type
fprintf(f, "(");
int len = maxlen - 2;
while (*text && len > 0) {
if (!isprint(*text)) {
if (len < 4) break;
fprintf(f, "\\%03o", *text);
len -= 4;
}
else if (*text == '(' || *text == ')' || *text == '\\') {
if (len < 2) break;
fprintf(f, "\\%c", *text);
len -= 2;
}
else {
fprintf(f, "%c", *text);
len--;
}
text++;
}
fprintf(f, ")");
}
/** ---------------------------------------------------
* Default Constructor
* @update 2/1/99 dwc
*/
nsPostScriptObj::nsPostScriptObj() :
mPrintSetup(nsnull),
mPrintContext(nsnull),
mTitle(nsnull),
mScriptFP(nsnull)
{
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("nsPostScriptObj::nsPostScriptObj()\n"));
CallGetService(NS_PREF_CONTRACTID, &gPrefs);
gLangGroups = new nsHashtable();
}
/** ---------------------------------------------------
* Destructor
* @update 2/1/99 dwc
*/
nsPostScriptObj::~nsPostScriptObj()
{
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("nsPostScriptObj::~nsPostScriptObj()\n"));
if (mScriptFP)
fclose(mScriptFP);
if (mDocScript)
mDocScript->Remove(PR_FALSE);
finalize_translation();
// Cleanup things allocated along the way
if (nsnull != mTitle){
nsMemory::Free(mTitle);
}
if (nsnull != mPrintContext){
delete mPrintContext->prInfo;
delete mPrintContext->prSetup;
delete mPrintContext;
mPrintContext = nsnull;
}
delete mPrintSetup;
mPrintSetup = nsnull;
NS_IF_RELEASE(gPrefs);
if (gLangGroups) {
gLangGroups->Reset(FreeLangGroups, nsnull);
delete gLangGroups;
gLangGroups = nsnull;
}
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("nsPostScriptObj::~nsPostScriptObj(): printing done."));
}
void
nsPostScriptObj::settitle(PRUnichar * aTitle)
{
if (aTitle) {
mTitle = ToNewCString(nsDependentString(aTitle));
}
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/20/2004 kherron
*/
nsresult
nsPostScriptObj::Init( nsIDeviceContextSpecPS *aSpec )
{
PRBool isGray,
isFirstPageFirst;
PrintInfo* pi = new PrintInfo();
mPrintSetup = new PrintSetup();
if( (nsnull!=pi) && (nsnull!=mPrintSetup) ){
memset(mPrintSetup, 0, sizeof(struct PrintSetup_));
mPrintSetup->color = PR_TRUE; // Image output
mPrintSetup->deep_color = PR_TRUE; // 24 bit color output
mPrintSetup->reverse = 0; // Output order, 0 is acsending
mPrintSetup->num_copies = 1;
if ( aSpec != nsnull ) {
aSpec->GetGrayscale( isGray );
if ( isGray == PR_TRUE ) {
mPrintSetup->color = PR_FALSE;
mPrintSetup->deep_color = PR_FALSE;
}
aSpec->GetFirstPageFirst( isFirstPageFirst );
if ( isFirstPageFirst == PR_FALSE )
mPrintSetup->reverse = 1;
} else
return NS_ERROR_FAILURE;
/* 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);
mPrintContext = new PSContext();
memset(mPrintContext, 0, sizeof(struct PSContext_));
memset(pi, 0, sizeof(struct PrintInfo_));
/* Get the paper name to write into the ps output */
aSpec->GetPaperName(&(mPrintSetup->paper_name));
/* Get the paper size */
rv = aSpec->GetPageSizeInTwips(&mPrintSetup->width, &mPrintSetup->height);
if ( NS_FAILED(rv) || mPrintSetup->width <= 0 || mPrintSetup->height <= 0 ) {
return NS_ERROR_GFX_PRINTER_PAPER_SIZE_NOT_SUPPORTED;
}
#ifdef DEBUG
printf("\nPaper Width = %d twips (%gmm) Height = %d twips (%gmm)\n",
mPrintSetup->width, NS_TWIPS_TO_MILLIMETERS(mPrintSetup->width),
mPrintSetup->height, NS_TWIPS_TO_MILLIMETERS(mPrintSetup->height));
#endif
mPrintSetup->header = "header";
mPrintSetup->footer = "footer";
mPrintSetup->sizes = nsnull;
aSpec->GetLandscape(mPrintSetup->landscape);
mPrintSetup->underline = PR_TRUE; // underline links
mPrintSetup->scale_images = PR_TRUE; // Scale unsized images which are too big
mPrintSetup->scale_pre = PR_FALSE; // do the pre-scaling thing
mPrintSetup->rules = 1.0f; // Scale factor for rulers
mPrintSetup->n_up = 0; // cool page combining
mPrintSetup->bigger = 1; // Used to init sizes if sizesin NULL
mPrintSetup->prefix = ""; // For text xlate, prepended to each line
mPrintSetup->eol = ""; // For text translation, line terminator
mPrintSetup->bullet = "+"; // What char to use for bullets
#ifdef NOTYET
URL_Struct_* url = new URL_Struct_;
memset(url, 0, sizeof(URL_Struct_));
mPrintSetup->url = url; // url of doc being translated
#else
mPrintSetup->url = nsnull;
#endif
mPrintSetup->completion = nsnull; // Called when translation finished
mPrintSetup->carg = nsnull; // Data saved for completion routine
mPrintSetup->status = 0; // Status of URL on completion
mTitle = nsnull;
pi->doc_title = mTitle;
mPrintContext->prInfo = pi;
// begin the document
initialize_translation(mPrintSetup);
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;
}
}
void
nsPostScriptObj::SetNumCopies(int aNumCopies)
{
NS_PRECONDITION(mPrintSetup, "mPrintSetup must not be NULL");
mPrintSetup->num_copies = aNumCopies;
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::finalize_translation()
{
if (mPrintContext) {
free(mPrintContext->prSetup);
mPrintContext->prSetup = nsnull;
}
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::initialize_translation(PrintSetup* pi)
{
PrintSetup *dup = (PrintSetup *)malloc(sizeof(PrintSetup));
*dup = *pi;
mPrintContext->prSetup = dup;
}
/** ---------------------------------------------------
* Write the document prolog.
* @param aHandle File handle which receives the prolog
*/
void
nsPostScriptObj::write_prolog(FILE *aHandle, PRBool aFTPEnable)
{
FILE *f = aHandle;
float fWidth = NSTwipsToFloatPoints(mPrintContext->prSetup->width);
float fHeight = NSTwipsToFloatPoints(mPrintContext->prSetup->height);
// PostScript comments marked with %% are document structuring conventions
// (DSC) comments. See Adobe specification 5001 at
// <http://partners.adobe.com/public/developer/ps/index_specs.html>.
fprintf(f, "%%!PS-Adobe-3.0\n");
fprintf(f, "%%%%BoundingBox: 0 0 %s %s\n",
fpCString(NSToCoordRound(fWidth)).get(),
fpCString(NSToCoordRound(fHeight)).get());
fprintf(f, "%%%%HiResBoundingBox: 0 0 %s %s\n",
fpCString(fWidth).get(),
fpCString(fHeight).get());
fprintf(f, "%%%%Creator: Mozilla PostScript module (%s)\n",
"rv:" MOZILLA_VERSION);
fprintf(f, "%%%%DocumentData: Clean8Bit\n");
fprintf(f, "%%%%DocumentPaperSizes: %s\n", mPrintSetup->paper_name);
fprintf(f, "%%%%Orientation: %s\n",
mPrintContext->prSetup->landscape ? "Landscape" : "Portrait");
fprintf(f, "%%%%Pages: %d\n", (int) mPageNumber - 1);
fprintf(f, "%%%%PageOrder: %s\n",
mPrintContext->prSetup->reverse ? "Descend" : "Ascend");
if (nsnull != mPrintContext->prInfo->doc_title) {
// DSC spec: max line length is 255 characters
fprintf(f, "%%%%Title: ");
PrintAsDSCTextline(f, mPrintContext->prInfo->doc_title, 230);
fprintf(f, "\n");
}
fprintf(f, "%%%%EndComments\n");
// general comments: Mozilla-specific
fputs("% MozillaCharsetName: iso-8859-1\n\n", f);
fputs("%%BeginProlog\n", f);
// The first number following "Gecko_procset" is a version number. If you change
// any of the PS between the following BeginResource and EndResource lines, you
// must increment the version.
fputs("%%BeginResource: procset Gecko_procset 1.0 0\n", f);
// Procedure to select and scale a font, using selectfont if available. See
// Adobe Technical note 5048. Note msf args are backwards from selectfont.
fprintf(f, "%s",
"/Msf /selectfont where\n"
" { pop { exch selectfont } }\n"
" { { findfont exch scalefont setfont } }\n"
" ifelse\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
" 2 index add\n" // h+y x y w+x
" 4 1 roll\n" // w+x h+y x y
" transform round .1 add exch round .1 add exch itransform\n"
" 4 -2 roll\n" // x' y' w+x h+x
" transform round .1 sub exch round .1 sub exch itransform\n"
" 2 index sub\n" // x' y' w'+x h'
" 4 1 roll\n" // h' x' y' w'+x
" 2 index sub\n" // h' x' y' w'
" 4 1 roll\n" // w' h' x' y'
" moveto\n" // w' h'
" dup 0 exch rlineto\n" // w' h'
" exch 0 rlineto\n" // h'
" neg 0 exch rlineto\n" // -
" closepath\n"
"} bind def\n"
// Setstrokeadjust, or null if not supported
"/Msetstrokeadjust /setstrokeadjust where\n"
" { pop /setstrokeadjust } { /pop } ifelse\n"
" load def\n"
);
fputs("%%EndResource\n", f); // Gecko_procset
if (aFTPEnable) {
return;
}
// Write the AFM font support.
// The first number following "Gecko_afm_procset" is a version number. If you change
// any of the PS between the following BeginResource and EndResource lines, you
// must increment the version.
fputs("%%BeginResource: procset Gecko_afm_procset 1.0 0\n", f);
fprintf(f, "[");
for (int i = 0; i < 256; i++) {
if (*isotab[i] == '\0') {
fputs(" /.notdef", f);
}
else {
fprintf(f, " /%s", isotab[i]);
}
if (( i % 6) == 5){
fprintf(f, "\n");
}
}
fprintf(f, "] /isolatin1encoding exch def\n");
// Procedure to reencode a font
fprintf(f, "%s",
"/Mfr {\n"
" findfont dup length dict\n"
" begin\n"
" {1 index /FID ne {def} {pop pop} ifelse} forall\n"
" /Encoding isolatin1encoding def\n"
" currentdict\n"
" end\n"
" definefont pop\n"
"} bind def\n");
fprintf(f, "%s",
// Unicode glyph dictionary
"/UniDict\n"
"1051 dict dup begin\n"
"16#0020 /space def\n"
"16#0021 /exclam def\n"
"16#0022 /quotedbl def\n"
"16#0023 /numbersign def\n"
"16#0024 /dollar def\n"
"16#0025 /percent def\n"
"16#0026 /ampersand def\n"
"16#0027 /quotesingle def\n"
"16#0028 /parenleft def\n"
"16#0029 /parenright def\n"
"16#002A /asterisk def\n"
"16#002B /plus def\n"
"16#002C /comma def\n"
"16#002D /hyphen def\n"
"16#002E /period def\n"
"16#002F /slash def\n"
"16#0030 /zero def\n"
"16#0031 /one def\n"
"16#0032 /two def\n"
"16#0033 /three def\n"
"16#0034 /four def\n"
"16#0035 /five def\n"
"16#0036 /six def\n"
"16#0037 /seven def\n"
"16#0038 /eight def\n"
"16#0039 /nine def\n"
"16#003A /colon def\n"
"16#003B /semicolon def\n"
"16#003C /less def\n"
"16#003D /equal def\n"
"16#003E /greater def\n"
"16#003F /question def\n"
"16#0040 /at def\n"
"16#0041 /A def\n"
"16#0042 /B def\n"
"16#0043 /C def\n"
"16#0044 /D def\n"
"16#0045 /E def\n"
"16#0046 /F def\n"
"16#0047 /G def\n"
"16#0048 /H def\n"
"16#0049 /I def\n"
"16#004A /J def\n"
"16#004B /K def\n"
"16#004C /L def\n"
"16#004D /M def\n"
"16#004E /N def\n"
"16#004F /O def\n"
"16#0050 /P def\n"
"16#0051 /Q def\n"
"16#0052 /R def\n"
"16#0053 /S def\n"
"16#0054 /T def\n"
"16#0055 /U def\n"
"16#0056 /V def\n"
"16#0057 /W def\n"
"16#0058 /X def\n"
"16#0059 /Y def\n"
"16#005A /Z def\n"
"16#005B /bracketleft def\n"
"16#005C /backslash def\n"
"16#005D /bracketright def\n"
"16#005E /asciicircum def\n"
"16#005F /underscore def\n"
"16#0060 /grave def\n"
"16#0061 /a def\n"
"16#0062 /b def\n"
"16#0063 /c def\n"
"16#0064 /d def\n"
"16#0065 /e def\n"
"16#0066 /f def\n"
"16#0067 /g def\n"
"16#0068 /h def\n"
"16#0069 /i def\n"
"16#006A /j def\n"
"16#006B /k def\n"
"16#006C /l def\n"
"16#006D /m def\n"
"16#006E /n def\n"
"16#006F /o def\n"
"16#0070 /p def\n"
"16#0071 /q def\n"
"16#0072 /r def\n"
"16#0073 /s def\n"
"16#0074 /t def\n"
"16#0075 /u def\n"
"16#0076 /v def\n"
"16#0077 /w def\n"
"16#0078 /x def\n"
"16#0079 /y def\n"
"16#007A /z def\n"
"16#007B /braceleft def\n"
"16#007C /bar def\n"
"16#007D /braceright def\n"
"16#007E /asciitilde def\n"
"16#00A0 /space def\n"
"16#00A1 /exclamdown def\n"
"16#00A2 /cent def\n"
"16#00A3 /sterling def\n"
"16#00A4 /currency def\n"
"16#00A5 /yen def\n"
"16#00A6 /brokenbar def\n"
"16#00A7 /section def\n"
"16#00A8 /dieresis def\n"
"16#00A9 /copyright def\n"
"16#00AA /ordfeminine def\n"
"16#00AB /guillemotleft def\n"
"16#00AC /logicalnot def\n"
"16#00AD /hyphen def\n"
"16#00AE /registered def\n"
"16#00AF /macron def\n"
"16#00B0 /degree def\n"
"16#00B1 /plusminus def\n"
"16#00B2 /twosuperior def\n"
"16#00B3 /threesuperior def\n"
"16#00B4 /acute def\n"
"16#00B5 /mu def\n"
"16#00B6 /paragraph def\n"
"16#00B7 /periodcentered def\n"
"16#00B8 /cedilla def\n"
"16#00B9 /onesuperior def\n"
"16#00BA /ordmasculine def\n"
"16#00BB /guillemotright def\n"
"16#00BC /onequarter def\n"
"16#00BD /onehalf def\n"
"16#00BE /threequarters def\n"
"16#00BF /questiondown def\n"
"16#00C0 /Agrave def\n"
"16#00C1 /Aacute def\n"
"16#00C2 /Acircumflex def\n"
"16#00C3 /Atilde def\n"
"16#00C4 /Adieresis def\n"
"16#00C5 /Aring def\n"
"16#00C6 /AE def\n"
"16#00C7 /Ccedilla def\n"
"16#00C8 /Egrave def\n"
"16#00C9 /Eacute def\n"
"16#00CA /Ecircumflex def\n"
"16#00CB /Edieresis def\n"
"16#00CC /Igrave def\n"
"16#00CD /Iacute def\n"
"16#00CE /Icircumflex def\n"
"16#00CF /Idieresis def\n"
"16#00D0 /Eth def\n"
"16#00D1 /Ntilde def\n"
"16#00D2 /Ograve def\n"
"16#00D3 /Oacute def\n"
"16#00D4 /Ocircumflex def\n"
"16#00D5 /Otilde def\n"
"16#00D6 /Odieresis def\n"
"16#00D7 /multiply def\n"
"16#00D8 /Oslash def\n"
"16#00D9 /Ugrave def\n"
"16#00DA /Uacute def\n"
"16#00DB /Ucircumflex def\n"
"16#00DC /Udieresis def\n"
"16#00DD /Yacute def\n"
"16#00DE /Thorn def\n"
"16#00DF /germandbls def\n"
"16#00E0 /agrave def\n"
"16#00E1 /aacute def\n"
"16#00E2 /acircumflex def\n"
"16#00E3 /atilde def\n"
"16#00E4 /adieresis def\n"
"16#00E5 /aring def\n"
"16#00E6 /ae def\n"
"16#00E7 /ccedilla def\n"
"16#00E8 /egrave def\n"
"16#00E9 /eacute def\n"
"16#00EA /ecircumflex def\n"
"16#00EB /edieresis def\n"
"16#00EC /igrave def\n"
"16#00ED /iacute def\n"
"16#00EE /icircumflex def\n"
"16#00EF /idieresis def\n"
"16#00F0 /eth def\n"
"16#00F1 /ntilde def\n"
"16#00F2 /ograve def\n"
"16#00F3 /oacute def\n"
"16#00F4 /ocircumflex def\n"
"16#00F5 /otilde def\n"
"16#00F6 /odieresis def\n"
"16#00F7 /divide def\n"
"16#00F8 /oslash def\n"
"16#00F9 /ugrave def\n"
"16#00FA /uacute def\n"
"16#00FB /ucircumflex def\n"
"16#00FC /udieresis def\n"
"16#00FD /yacute def\n"
"16#00FE /thorn def\n"
"16#00FF /ydieresis def\n"
"16#0100 /Amacron def\n"
"16#0101 /amacron def\n"
"16#0102 /Abreve def\n"
"16#0103 /abreve def\n"
"16#0104 /Aogonek def\n"
"16#0105 /aogonek def\n"
"16#0106 /Cacute def\n"
"16#0107 /cacute def\n"
"16#0108 /Ccircumflex def\n"
"16#0109 /ccircumflex def\n"
"16#010A /Cdotaccent def\n"
"16#010B /cdotaccent def\n"
"16#010C /Ccaron def\n"
"16#010D /ccaron def\n"
"16#010E /Dcaron def\n"
"16#010F /dcaron def\n"
"16#0110 /Dcroat def\n"
"16#0111 /dcroat def\n"
"16#0112 /Emacron def\n"
"16#0113 /emacron def\n"
"16#0114 /Ebreve def\n"
"16#0115 /ebreve def\n"
"16#0116 /Edotaccent def\n"
"16#0117 /edotaccent def\n"
"16#0118 /Eogonek def\n"
"16#0119 /eogonek def\n"
"16#011A /Ecaron def\n"
"16#011B /ecaron def\n"
"16#011C /Gcircumflex def\n"
"16#011D /gcircumflex def\n"
"16#011E /Gbreve def\n"
"16#011F /gbreve def\n"
"16#0120 /Gdotaccent def\n"
"16#0121 /gdotaccent def\n"
"16#0122 /Gcommaaccent def\n"
"16#0123 /gcommaaccent def\n"
"16#0124 /Hcircumflex def\n"
"16#0125 /hcircumflex def\n"
"16#0126 /Hbar def\n"
"16#0127 /hbar def\n"
"16#0128 /Itilde def\n"
"16#0129 /itilde def\n"
"16#012A /Imacron def\n"
"16#012B /imacron def\n"
"16#012C /Ibreve def\n"
"16#012D /ibreve def\n"
"16#012E /Iogonek def\n"
"16#012F /iogonek def\n"
"16#0130 /Idotaccent def\n"
"16#0131 /dotlessi def\n"
"16#0132 /IJ def\n"
"16#0133 /ij def\n"
"16#0134 /Jcircumflex def\n"
"16#0135 /jcircumflex def\n"
"16#0136 /Kcommaaccent def\n"
"16#0137 /kcommaaccent def\n"
"16#0138 /kgreenlandic def\n"
"16#0139 /Lacute def\n"
"16#013A /lacute def\n"
"16#013B /Lcommaaccent def\n"
"16#013C /lcommaaccent def\n"
"16#013D /Lcaron def\n"
"16#013E /lcaron def\n"
"16#013F /Ldot def\n"
"16#0140 /ldot def\n"
"16#0141 /Lslash def\n"
"16#0142 /lslash def\n"
"16#0143 /Nacute def\n"
"16#0144 /nacute def\n"
"16#0145 /Ncommaaccent def\n"
"16#0146 /ncommaaccent def\n"
"16#0147 /Ncaron def\n"
"16#0148 /ncaron def\n"
"16#0149 /napostrophe def\n"
"16#014A /Eng def\n"
"16#014B /eng def\n"
"16#014C /Omacron def\n"
"16#014D /omacron def\n"
"16#014E /Obreve def\n"
"16#014F /obreve def\n"
"16#0150 /Ohungarumlaut def\n"
"16#0151 /ohungarumlaut def\n"
"16#0152 /OE def\n"
"16#0153 /oe def\n"
"16#0154 /Racute def\n"
"16#0155 /racute def\n"
"16#0156 /Rcommaaccent def\n"
"16#0157 /rcommaaccent def\n"
"16#0158 /Rcaron def\n"
"16#0159 /rcaron def\n"
"16#015A /Sacute def\n"
"16#015B /sacute def\n"
"16#015C /Scircumflex def\n"
"16#015D /scircumflex def\n"
"16#015E /Scedilla def\n"
"16#015F /scedilla def\n"
"16#0160 /Scaron def\n"
"16#0161 /scaron def\n"
"16#0162 /Tcommaaccent def\n"
"16#0163 /tcommaaccent def\n"
"16#0164 /Tcaron def\n"
"16#0165 /tcaron def\n"
"16#0166 /Tbar def\n"
"16#0167 /tbar def\n"
"16#0168 /Utilde def\n"
"16#0169 /utilde def\n"
"16#016A /Umacron def\n"
"16#016B /umacron def\n"
"16#016C /Ubreve def\n"
"16#016D /ubreve def\n"
"16#016E /Uring def\n"
"16#016F /uring def\n"
"16#0170 /Uhungarumlaut def\n"
"16#0171 /uhungarumlaut def\n"
"16#0172 /Uogonek def\n"
"16#0173 /uogonek def\n"
"16#0174 /Wcircumflex def\n"
"16#0175 /wcircumflex def\n"
"16#0176 /Ycircumflex def\n"
"16#0177 /ycircumflex def\n"
"16#0178 /Ydieresis def\n"
"16#0179 /Zacute def\n"
"16#017A /zacute def\n"
"16#017B /Zdotaccent def\n"
"16#017C /zdotaccent def\n"
"16#017D /Zcaron def\n"
"16#017E /zcaron def\n"
"16#017F /longs def\n"
"16#0192 /florin def\n"
"16#01A0 /Ohorn def\n"
"16#01A1 /ohorn def\n"
"16#01AF /Uhorn def\n"
"16#01B0 /uhorn def\n"
"16#01E6 /Gcaron def\n"
"16#01E7 /gcaron def\n"
"16#01FA /Aringacute def\n"
"16#01FB /aringacute def\n"
"16#01FC /AEacute def\n"
"16#01FD /aeacute def\n"
"16#01FE /Oslashacute def\n"
"16#01FF /oslashacute def\n"
"16#0218 /Scommaaccent def\n"
"16#0219 /scommaaccent def\n"
"16#021A /Tcommaaccent def\n"
"16#021B /tcommaaccent def\n"
"16#02BC /afii57929 def\n"
"16#02BD /afii64937 def\n"
"16#02C6 /circumflex def\n"
"16#02C7 /caron def\n"
"16#02C9 /macron def\n"
"16#02D8 /breve def\n"
"16#02D9 /dotaccent def\n"
"16#02DA /ring def\n"
"16#02DB /ogonek def\n"
"16#02DC /tilde def\n"
"16#02DD /hungarumlaut def\n"
"16#0300 /gravecomb def\n"
"16#0301 /acutecomb def\n"
"16#0303 /tildecomb def\n"
"16#0309 /hookabovecomb def\n"
"16#0323 /dotbelowcomb def\n"
"16#0384 /tonos def\n"
"16#0385 /dieresistonos def\n"
"16#0386 /Alphatonos def\n"
"16#0387 /anoteleia def\n"
"16#0388 /Epsilontonos def\n"
"16#0389 /Etatonos def\n"
"16#038A /Iotatonos def\n"
"16#038C /Omicrontonos def\n"
"16#038E /Upsilontonos def\n"
"16#038F /Omegatonos def\n"
"16#0390 /iotadieresistonos def\n"
"16#0391 /Alpha def\n"
"16#0392 /Beta def\n"
"16#0393 /Gamma def\n"
"16#0394 /Delta def\n"
"16#0395 /Epsilon def\n"
"16#0396 /Zeta def\n"
"16#0397 /Eta def\n"
"16#0398 /Theta def\n"
"16#0399 /Iota def\n"
"16#039A /Kappa def\n"
"16#039B /Lambda def\n"
"16#039C /Mu def\n"
"16#039D /Nu def\n"
"16#039E /Xi def\n"
"16#039F /Omicron def\n"
"16#03A0 /Pi def\n"
"16#03A1 /Rho def\n"
"16#03A3 /Sigma def\n"
"16#03A4 /Tau def\n"
"16#03A5 /Upsilon def\n"
"16#03A6 /Phi def\n"
"16#03A7 /Chi def\n"
"16#03A8 /Psi def\n"
"16#03A9 /Omega def\n"
"16#03AA /Iotadieresis def\n"
"16#03AB /Upsilondieresis def\n"
"16#03AC /alphatonos def\n"
"16#03AD /epsilontonos def\n"
"16#03AE /etatonos def\n"
"16#03AF /iotatonos def\n"
"16#03B0 /upsilondieresistonos def\n"
"16#03B1 /alpha def\n"
"16#03B2 /beta def\n"
"16#03B3 /gamma def\n"
"16#03B4 /delta def\n"
"16#03B5 /epsilon def\n"
"16#03B6 /zeta def\n"
"16#03B7 /eta def\n"
"16#03B8 /theta def\n"
"16#03B9 /iota def\n"
"16#03BA /kappa def\n"
"16#03BB /lambda def\n"
"16#03BC /mu def\n"
"16#03BD /nu def\n"
"16#03BE /xi def\n"
"16#03BF /omicron def\n"
"16#03C0 /pi def\n"
"16#03C1 /rho def\n"
"16#03C2 /sigma1 def\n"
"16#03C3 /sigma def\n"
"16#03C4 /tau def\n"
"16#03C5 /upsilon def\n"
"16#03C6 /phi def\n"
"16#03C7 /chi def\n"
"16#03C8 /psi def\n"
"16#03C9 /omega def\n"
"16#03CA /iotadieresis def\n"
"16#03CB /upsilondieresis def\n"
"16#03CC /omicrontonos def\n"
);
fprintf(f, "%s",
"16#03CD /upsilontonos def\n"
"16#03CE /omegatonos def\n"
"16#03D1 /theta1 def\n"
"16#03D2 /Upsilon1 def\n"
"16#03D5 /phi1 def\n"
"16#03D6 /omega1 def\n"
"16#0401 /afii10023 def\n"
"16#0402 /afii10051 def\n"
"16#0403 /afii10052 def\n"
"16#0404 /afii10053 def\n"
"16#0405 /afii10054 def\n"
"16#0406 /afii10055 def\n"
"16#0407 /afii10056 def\n"
"16#0408 /afii10057 def\n"
"16#0409 /afii10058 def\n"
"16#040A /afii10059 def\n"
"16#040B /afii10060 def\n"
"16#040C /afii10061 def\n"
"16#040E /afii10062 def\n"
"16#040F /afii10145 def\n"
"16#0410 /afii10017 def\n"
"16#0411 /afii10018 def\n"
"16#0412 /afii10019 def\n"
"16#0413 /afii10020 def\n"
"16#0414 /afii10021 def\n"
"16#0415 /afii10022 def\n"
"16#0416 /afii10024 def\n"
"16#0417 /afii10025 def\n"
"16#0418 /afii10026 def\n"
"16#0419 /afii10027 def\n"
"16#041A /afii10028 def\n"
"16#041B /afii10029 def\n"
"16#041C /afii10030 def\n"
"16#041D /afii10031 def\n"
"16#041E /afii10032 def\n"
"16#041F /afii10033 def\n"
"16#0420 /afii10034 def\n"
"16#0421 /afii10035 def\n"
"16#0422 /afii10036 def\n"
"16#0423 /afii10037 def\n"
"16#0424 /afii10038 def\n"
"16#0425 /afii10039 def\n"
"16#0426 /afii10040 def\n"
"16#0427 /afii10041 def\n"
"16#0428 /afii10042 def\n"
"16#0429 /afii10043 def\n"
"16#042A /afii10044 def\n"
"16#042B /afii10045 def\n"
"16#042C /afii10046 def\n"
"16#042D /afii10047 def\n"
"16#042E /afii10048 def\n"
"16#042F /afii10049 def\n"
"16#0430 /afii10065 def\n"
"16#0431 /afii10066 def\n"
"16#0432 /afii10067 def\n"
"16#0433 /afii10068 def\n"
"16#0434 /afii10069 def\n"
"16#0435 /afii10070 def\n"
"16#0436 /afii10072 def\n"
"16#0437 /afii10073 def\n"
"16#0438 /afii10074 def\n"
"16#0439 /afii10075 def\n"
"16#043A /afii10076 def\n"
"16#043B /afii10077 def\n"
"16#043C /afii10078 def\n"
"16#043D /afii10079 def\n"
"16#043E /afii10080 def\n"
"16#043F /afii10081 def\n"
"16#0440 /afii10082 def\n"
"16#0441 /afii10083 def\n"
"16#0442 /afii10084 def\n"
"16#0443 /afii10085 def\n"
"16#0444 /afii10086 def\n"
"16#0445 /afii10087 def\n"
"16#0446 /afii10088 def\n"
"16#0447 /afii10089 def\n"
"16#0448 /afii10090 def\n"
"16#0449 /afii10091 def\n"
"16#044A /afii10092 def\n"
"16#044B /afii10093 def\n"
"16#044C /afii10094 def\n"
"16#044D /afii10095 def\n"
"16#044E /afii10096 def\n"
"16#044F /afii10097 def\n"
"16#0451 /afii10071 def\n"
"16#0452 /afii10099 def\n"
"16#0453 /afii10100 def\n"
"16#0454 /afii10101 def\n"
"16#0455 /afii10102 def\n"
"16#0456 /afii10103 def\n"
"16#0457 /afii10104 def\n"
"16#0458 /afii10105 def\n"
"16#0459 /afii10106 def\n"
"16#045A /afii10107 def\n"
"16#045B /afii10108 def\n"
"16#045C /afii10109 def\n"
"16#045E /afii10110 def\n"
"16#045F /afii10193 def\n"
"16#0462 /afii10146 def\n"
"16#0463 /afii10194 def\n"
"16#0472 /afii10147 def\n"
"16#0473 /afii10195 def\n"
"16#0474 /afii10148 def\n"
"16#0475 /afii10196 def\n"
"16#0490 /afii10050 def\n"
"16#0491 /afii10098 def\n"
"16#04D9 /afii10846 def\n"
"16#05B0 /afii57799 def\n"
"16#05B1 /afii57801 def\n"
"16#05B2 /afii57800 def\n"
"16#05B3 /afii57802 def\n"
"16#05B4 /afii57793 def\n"
"16#05B5 /afii57794 def\n"
"16#05B6 /afii57795 def\n"
"16#05B7 /afii57798 def\n"
"16#05B8 /afii57797 def\n"
"16#05B9 /afii57806 def\n"
"16#05BB /afii57796 def\n"
"16#05BC /afii57807 def\n"
"16#05BD /afii57839 def\n"
"16#05BE /afii57645 def\n"
"16#05BF /afii57841 def\n"
"16#05C0 /afii57842 def\n"
"16#05C1 /afii57804 def\n"
"16#05C2 /afii57803 def\n"
"16#05C3 /afii57658 def\n"
"16#05D0 /afii57664 def\n"
"16#05D1 /afii57665 def\n"
"16#05D2 /afii57666 def\n"
"16#05D3 /afii57667 def\n"
"16#05D4 /afii57668 def\n"
"16#05D5 /afii57669 def\n"
"16#05D6 /afii57670 def\n"
"16#05D7 /afii57671 def\n"
"16#05D8 /afii57672 def\n"
"16#05D9 /afii57673 def\n"
"16#05DA /afii57674 def\n"
"16#05DB /afii57675 def\n"
"16#05DC /afii57676 def\n"
"16#05DD /afii57677 def\n"
"16#05DE /afii57678 def\n"
"16#05DF /afii57679 def\n"
"16#05E0 /afii57680 def\n"
"16#05E1 /afii57681 def\n"
"16#05E2 /afii57682 def\n"
"16#05E3 /afii57683 def\n"
"16#05E4 /afii57684 def\n"
"16#05E5 /afii57685 def\n"
"16#05E6 /afii57686 def\n"
"16#05E7 /afii57687 def\n"
"16#05E8 /afii57688 def\n"
"16#05E9 /afii57689 def\n"
"16#05EA /afii57690 def\n"
"16#05F0 /afii57716 def\n"
"16#05F1 /afii57717 def\n"
"16#05F2 /afii57718 def\n"
"16#060C /afii57388 def\n"
"16#061B /afii57403 def\n"
"16#061F /afii57407 def\n"
"16#0621 /afii57409 def\n"
"16#0622 /afii57410 def\n"
"16#0623 /afii57411 def\n"
"16#0624 /afii57412 def\n"
"16#0625 /afii57413 def\n"
"16#0626 /afii57414 def\n"
"16#0627 /afii57415 def\n"
"16#0628 /afii57416 def\n"
"16#0629 /afii57417 def\n"
"16#062A /afii57418 def\n"
"16#062B /afii57419 def\n"
"16#062C /afii57420 def\n"
"16#062D /afii57421 def\n"
"16#062E /afii57422 def\n"
"16#062F /afii57423 def\n"
"16#0630 /afii57424 def\n"
"16#0631 /afii57425 def\n"
"16#0632 /afii57426 def\n"
"16#0633 /afii57427 def\n"
"16#0634 /afii57428 def\n"
"16#0635 /afii57429 def\n"
"16#0636 /afii57430 def\n"
"16#0637 /afii57431 def\n"
"16#0638 /afii57432 def\n"
"16#0639 /afii57433 def\n"
"16#063A /afii57434 def\n"
"16#0640 /afii57440 def\n"
"16#0641 /afii57441 def\n"
"16#0642 /afii57442 def\n"
"16#0643 /afii57443 def\n"
"16#0644 /afii57444 def\n"
"16#0645 /afii57445 def\n"
"16#0646 /afii57446 def\n"
"16#0647 /afii57470 def\n"
"16#0648 /afii57448 def\n"
"16#0649 /afii57449 def\n"
"16#064A /afii57450 def\n"
"16#064B /afii57451 def\n"
"16#064C /afii57452 def\n"
"16#064D /afii57453 def\n"
"16#064E /afii57454 def\n"
"16#064F /afii57455 def\n"
"16#0650 /afii57456 def\n"
"16#0651 /afii57457 def\n"
"16#0652 /afii57458 def\n"
"16#0660 /afii57392 def\n"
"16#0661 /afii57393 def\n"
"16#0662 /afii57394 def\n"
"16#0663 /afii57395 def\n"
"16#0664 /afii57396 def\n"
"16#0665 /afii57397 def\n"
"16#0666 /afii57398 def\n"
"16#0667 /afii57399 def\n"
"16#0668 /afii57400 def\n"
"16#0669 /afii57401 def\n"
"16#066A /afii57381 def\n"
"16#066D /afii63167 def\n"
"16#0679 /afii57511 def\n"
"16#067E /afii57506 def\n"
"16#0686 /afii57507 def\n"
"16#0688 /afii57512 def\n"
"16#0691 /afii57513 def\n"
"16#0698 /afii57508 def\n"
"16#06A4 /afii57505 def\n"
"16#06AF /afii57509 def\n"
"16#06BA /afii57514 def\n"
"16#06D2 /afii57519 def\n"
"16#06D5 /afii57534 def\n"
"16#1E80 /Wgrave def\n"
"16#1E81 /wgrave def\n"
"16#1E82 /Wacute def\n"
"16#1E83 /wacute def\n"
"16#1E84 /Wdieresis def\n"
"16#1E85 /wdieresis def\n"
"16#1EF2 /Ygrave def\n"
"16#1EF3 /ygrave def\n"
"16#200C /afii61664 def\n"
"16#200D /afii301 def\n"
"16#200E /afii299 def\n"
"16#200F /afii300 def\n"
"16#2012 /figuredash def\n"
"16#2013 /endash def\n"
"16#2014 /emdash def\n"
"16#2015 /afii00208 def\n"
"16#2017 /underscoredbl def\n"
"16#2018 /quoteleft def\n"
"16#2019 /quoteright def\n"
"16#201A /quotesinglbase def\n"
"16#201B /quotereversed def\n"
"16#201C /quotedblleft def\n"
"16#201D /quotedblright def\n"
"16#201E /quotedblbase def\n"
"16#2020 /dagger def\n"
"16#2021 /daggerdbl def\n"
"16#2022 /bullet def\n"
"16#2024 /onedotenleader def\n"
"16#2025 /twodotenleader def\n"
"16#2026 /ellipsis def\n"
"16#202C /afii61573 def\n"
"16#202D /afii61574 def\n"
"16#202E /afii61575 def\n"
"16#2030 /perthousand def\n"
"16#2032 /minute def\n"
"16#2033 /second def\n"
"16#2039 /guilsinglleft def\n"
"16#203A /guilsinglright def\n"
"16#203C /exclamdbl def\n"
"16#2044 /fraction def\n"
"16#2070 /zerosuperior def\n"
"16#2074 /foursuperior def\n"
"16#2075 /fivesuperior def\n"
"16#2076 /sixsuperior def\n"
"16#2077 /sevensuperior def\n"
"16#2078 /eightsuperior def\n"
"16#2079 /ninesuperior def\n"
"16#207D /parenleftsuperior def\n"
"16#207E /parenrightsuperior def\n"
"16#207F /nsuperior def\n"
"16#2080 /zeroinferior def\n"
"16#2081 /oneinferior def\n"
"16#2082 /twoinferior def\n"
"16#2083 /threeinferior def\n"
"16#2084 /fourinferior def\n"
"16#2085 /fiveinferior def\n"
"16#2086 /sixinferior def\n"
"16#2087 /seveninferior def\n"
"16#2088 /eightinferior def\n"
"16#2089 /nineinferior def\n"
"16#208D /parenleftinferior def\n"
"16#208E /parenrightinferior def\n"
"16#20A1 /colonmonetary def\n"
"16#20A3 /franc def\n"
"16#20A4 /lira def\n"
"16#20A7 /peseta def\n"
"16#20AA /afii57636 def\n"
"16#20AB /dong def\n"
"16#20AC /Euro def\n"
"16#2105 /afii61248 def\n"
"16#2111 /Ifraktur def\n"
"16#2113 /afii61289 def\n"
"16#2116 /afii61352 def\n"
"16#2118 /weierstrass def\n"
"16#211C /Rfraktur def\n"
"16#211E /prescription def\n"
"16#2122 /trademark def\n"
"16#2126 /Omega def\n"
"16#212E /estimated def\n"
"16#2135 /aleph def\n"
"16#2153 /onethird def\n"
"16#2154 /twothirds def\n"
"16#215B /oneeighth def\n"
"16#215C /threeeighths def\n"
"16#215D /fiveeighths def\n"
"16#215E /seveneighths def\n"
"16#2190 /arrowleft def\n"
"16#2191 /arrowup def\n"
"16#2192 /arrowright def\n"
"16#2193 /arrowdown def\n"
"16#2194 /arrowboth def\n"
"16#2195 /arrowupdn def\n"
"16#21A8 /arrowupdnbse def\n"
"16#21B5 /carriagereturn def\n"
"16#21D0 /arrowdblleft def\n"
"16#21D1 /arrowdblup def\n"
"16#21D2 /arrowdblright def\n"
"16#21D3 /arrowdbldown def\n"
"16#21D4 /arrowdblboth def\n"
"16#2200 /universal def\n"
"16#2202 /partialdiff def\n"
"16#2203 /existential def\n"
"16#2205 /emptyset def\n"
"16#2206 /Delta def\n"
"16#2207 /gradient def\n"
"16#2208 /element def\n"
"16#2209 /notelement def\n"
"16#220B /suchthat def\n"
"16#220F /product def\n"
"16#2211 /summation def\n"
"16#2212 /minus def\n"
"16#2215 /fraction def\n"
"16#2217 /asteriskmath def\n"
"16#2219 /periodcentered def\n"
"16#221A /radical def\n"
"16#221D /proportional def\n"
"16#221E /infinity def\n"
"16#221F /orthogonal def\n"
"16#2220 /angle def\n"
"16#2227 /logicaland def\n"
"16#2228 /logicalor def\n"
"16#2229 /intersection def\n"
"16#222A /union def\n"
"16#222B /integral def\n"
"16#2234 /therefore def\n"
"16#223C /similar def\n"
"16#2245 /congruent def\n"
"16#2248 /approxequal def\n"
"16#2260 /notequal def\n"
"16#2261 /equivalence def\n"
"16#2264 /lessequal def\n"
"16#2265 /greaterequal def\n"
"16#2282 /propersubset def\n"
"16#2283 /propersuperset def\n"
"16#2284 /notsubset def\n"
"16#2286 /reflexsubset def\n"
"16#2287 /reflexsuperset def\n"
"16#2295 /circleplus def\n"
"16#2297 /circlemultiply def\n"
"16#22A5 /perpendicular def\n"
"16#22C5 /dotmath def\n"
"16#2302 /house def\n"
"16#2310 /revlogicalnot def\n"
"16#2320 /integraltp def\n"
"16#2321 /integralbt def\n"
"16#2329 /angleleft def\n"
"16#232A /angleright def\n"
"16#2500 /SF100000 def\n"
"16#2502 /SF110000 def\n"
"16#250C /SF010000 def\n"
"16#2510 /SF030000 def\n"
"16#2514 /SF020000 def\n"
"16#2518 /SF040000 def\n"
"16#251C /SF080000 def\n"
"16#2524 /SF090000 def\n"
"16#252C /SF060000 def\n"
"16#2534 /SF070000 def\n"
"16#253C /SF050000 def\n"
"16#2550 /SF430000 def\n"
"16#2551 /SF240000 def\n"
"16#2552 /SF510000 def\n"
"16#2553 /SF520000 def\n"
"16#2554 /SF390000 def\n"
"16#2555 /SF220000 def\n"
"16#2556 /SF210000 def\n"
"16#2557 /SF250000 def\n"
"16#2558 /SF500000 def\n"
"16#2559 /SF490000 def\n"
"16#255A /SF380000 def\n"
"16#255B /SF280000 def\n"
"16#255C /SF270000 def\n"
"16#255D /SF260000 def\n"
"16#255E /SF360000 def\n"
"16#255F /SF370000 def\n"
"16#2560 /SF420000 def\n"
"16#2561 /SF190000 def\n"
"16#2562 /SF200000 def\n"
"16#2563 /SF230000 def\n"
"16#2564 /SF470000 def\n"
"16#2565 /SF480000 def\n"
"16#2566 /SF410000 def\n"
"16#2567 /SF450000 def\n"
"16#2568 /SF460000 def\n"
"16#2569 /SF400000 def\n"
"16#256A /SF540000 def\n"
"16#256B /SF530000 def\n"
"16#256C /SF440000 def\n"
"16#2580 /upblock def\n"
"16#2584 /dnblock def\n"
"16#2588 /block def\n"
"16#258C /lfblock def\n"
"16#2590 /rtblock def\n"
"16#2591 /ltshade def\n"
"16#2592 /shade def\n"
"16#2593 /dkshade def\n"
"16#25A0 /filledbox def\n"
);
fprintf(f, "%s",
"16#25A1 /H22073 def\n"
"16#25AA /H18543 def\n"
"16#25AB /H18551 def\n"
"16#25AC /filledrect def\n"
"16#25B2 /triagup def\n"
"16#25BA /triagrt def\n"
"16#25BC /triagdn def\n"
"16#25C4 /triaglf def\n"
"16#25CA /lozenge def\n"
"16#25CB /circle def\n"
"16#25CF /H18533 def\n"
"16#25D8 /invbullet def\n"
"16#25D9 /invcircle def\n"
"16#25E6 /openbullet def\n"
"16#263A /smileface def\n"
"16#263B /invsmileface def\n"
"16#263C /sun def\n"
"16#2640 /female def\n"
"16#2642 /male def\n"
"16#2660 /spade def\n"
"16#2663 /club def\n"
"16#2665 /heart def\n"
"16#2666 /diamond def\n"
"16#266A /musicalnote def\n"
"16#266B /musicalnotedbl def\n"
"16#F6BE /dotlessj def\n"
"16#F6BF /LL def\n"
"16#F6C0 /ll def\n"
"16#F6C1 /Scedilla def\n"
"16#F6C2 /scedilla def\n"
"16#F6C3 /commaaccent def\n"
"16#F6C4 /afii10063 def\n"
"16#F6C5 /afii10064 def\n"
"16#F6C6 /afii10192 def\n"
"16#F6C7 /afii10831 def\n"
"16#F6C8 /afii10832 def\n"
"16#F6C9 /Acute def\n"
"16#F6CA /Caron def\n"
"16#F6CB /Dieresis def\n"
"16#F6CC /DieresisAcute def\n"
"16#F6CD /DieresisGrave def\n"
"16#F6CE /Grave def\n"
"16#F6CF /Hungarumlaut def\n"
"16#F6D0 /Macron def\n"
"16#F6D1 /cyrBreve def\n"
"16#F6D2 /cyrFlex def\n"
"16#F6D3 /dblGrave def\n"
"16#F6D4 /cyrbreve def\n"
"16#F6D5 /cyrflex def\n"
"16#F6D6 /dblgrave def\n"
"16#F6D7 /dieresisacute def\n"
"16#F6D8 /dieresisgrave def\n"
"16#F6D9 /copyrightserif def\n"
"16#F6DA /registerserif def\n"
"16#F6DB /trademarkserif def\n"
"16#F6DC /onefitted def\n"
"16#F6DD /rupiah def\n"
"16#F6DE /threequartersemdash def\n"
"16#F6DF /centinferior def\n"
"16#F6E0 /centsuperior def\n"
"16#F6E1 /commainferior def\n"
"16#F6E2 /commasuperior def\n"
"16#F6E3 /dollarinferior def\n"
"16#F6E4 /dollarsuperior def\n"
"16#F6E5 /hypheninferior def\n"
"16#F6E6 /hyphensuperior def\n"
"16#F6E7 /periodinferior def\n"
"16#F6E8 /periodsuperior def\n"
"16#F6E9 /asuperior def\n"
"16#F6EA /bsuperior def\n"
"16#F6EB /dsuperior def\n"
"16#F6EC /esuperior def\n"
"16#F6ED /isuperior def\n"
"16#F6EE /lsuperior def\n"
"16#F6EF /msuperior def\n"
"16#F6F0 /osuperior def\n"
"16#F6F1 /rsuperior def\n"
"16#F6F2 /ssuperior def\n"
"16#F6F3 /tsuperior def\n"
"16#F6F4 /Brevesmall def\n"
"16#F6F5 /Caronsmall def\n"
"16#F6F6 /Circumflexsmall def\n"
"16#F6F7 /Dotaccentsmall def\n"
"16#F6F8 /Hungarumlautsmall def\n"
"16#F6F9 /Lslashsmall def\n"
"16#F6FA /OEsmall def\n"
"16#F6FB /Ogoneksmall def\n"
"16#F6FC /Ringsmall def\n"
"16#F6FD /Scaronsmall def\n"
"16#F6FE /Tildesmall def\n"
"16#F6FF /Zcaronsmall def\n"
"16#F721 /exclamsmall def\n"
"16#F724 /dollaroldstyle def\n"
"16#F726 /ampersandsmall def\n"
"16#F730 /zerooldstyle def\n"
"16#F731 /oneoldstyle def\n"
"16#F732 /twooldstyle def\n"
"16#F733 /threeoldstyle def\n"
"16#F734 /fouroldstyle def\n"
"16#F735 /fiveoldstyle def\n"
"16#F736 /sixoldstyle def\n"
"16#F737 /sevenoldstyle def\n"
"16#F738 /eightoldstyle def\n"
"16#F739 /nineoldstyle def\n"
"16#F73F /questionsmall def\n"
"16#F760 /Gravesmall def\n"
"16#F761 /Asmall def\n"
"16#F762 /Bsmall def\n"
"16#F763 /Csmall def\n"
"16#F764 /Dsmall def\n"
"16#F765 /Esmall def\n"
"16#F766 /Fsmall def\n"
"16#F767 /Gsmall def\n"
"16#F768 /Hsmall def\n"
"16#F769 /Ismall def\n"
"16#F76A /Jsmall def\n"
"16#F76B /Ksmall def\n"
"16#F76C /Lsmall def\n"
"16#F76D /Msmall def\n"
"16#F76E /Nsmall def\n"
"16#F76F /Osmall def\n"
"16#F770 /Psmall def\n"
"16#F771 /Qsmall def\n"
"16#F772 /Rsmall def\n"
"16#F773 /Ssmall def\n"
"16#F774 /Tsmall def\n"
"16#F775 /Usmall def\n"
"16#F776 /Vsmall def\n"
"16#F777 /Wsmall def\n"
"16#F778 /Xsmall def\n"
"16#F779 /Ysmall def\n"
"16#F77A /Zsmall def\n"
"16#F7A1 /exclamdownsmall def\n"
"16#F7A2 /centoldstyle def\n"
"16#F7A8 /Dieresissmall def\n"
"16#F7AF /Macronsmall def\n"
"16#F7B4 /Acutesmall def\n"
"16#F7B8 /Cedillasmall def\n"
"16#F7BF /questiondownsmall def\n"
"16#F7E0 /Agravesmall def\n"
"16#F7E1 /Aacutesmall def\n"
"16#F7E2 /Acircumflexsmall def\n"
"16#F7E3 /Atildesmall def\n"
"16#F7E4 /Adieresissmall def\n"
"16#F7E5 /Aringsmall def\n"
"16#F7E6 /AEsmall def\n"
"16#F7E7 /Ccedillasmall def\n"
"16#F7E8 /Egravesmall def\n"
"16#F7E9 /Eacutesmall def\n"
"16#F7EA /Ecircumflexsmall def\n"
"16#F7EB /Edieresissmall def\n"
"16#F7EC /Igravesmall def\n"
"16#F7ED /Iacutesmall def\n"
"16#F7EE /Icircumflexsmall def\n"
"16#F7EF /Idieresissmall def\n"
"16#F7F0 /Ethsmall def\n"
"16#F7F1 /Ntildesmall def\n"
"16#F7F2 /Ogravesmall def\n"
"16#F7F3 /Oacutesmall def\n"
"16#F7F4 /Ocircumflexsmall def\n"
"16#F7F5 /Otildesmall def\n"
"16#F7F6 /Odieresissmall def\n"
"16#F7F8 /Oslashsmall def\n"
"16#F7F9 /Ugravesmall def\n"
"16#F7FA /Uacutesmall def\n"
"16#F7FB /Ucircumflexsmall def\n"
"16#F7FC /Udieresissmall def\n"
"16#F7FD /Yacutesmall def\n"
"16#F7FE /Thornsmall def\n"
"16#F7FF /Ydieresissmall def\n"
"16#F8E5 /radicalex def\n"
"16#F8E6 /arrowvertex def\n"
"16#F8E7 /arrowhorizex def\n"
"16#F8E8 /registersans def\n"
"16#F8E9 /copyrightsans def\n"
"16#F8EA /trademarksans def\n"
"16#F8EB /parenlefttp def\n"
"16#F8EC /parenleftex def\n"
"16#F8ED /parenleftbt def\n"
"16#F8EE /bracketlefttp def\n"
"16#F8EF /bracketleftex def\n"
"16#F8F0 /bracketleftbt def\n"
"16#F8F1 /bracelefttp def\n"
"16#F8F2 /braceleftmid def\n"
"16#F8F3 /braceleftbt def\n"
"16#F8F4 /braceex def\n"
"16#F8F5 /integralex def\n"
"16#F8F6 /parenrighttp def\n"
"16#F8F7 /parenrightex def\n"
"16#F8F8 /parenrightbt def\n"
"16#F8F9 /bracketrighttp def\n"
"16#F8FA /bracketrightex def\n"
"16#F8FB /bracketrightbt def\n"
"16#F8FC /bracerighttp def\n"
"16#F8FD /bracerightmid def\n"
"16#F8FE /bracerightbt def\n"
"16#FB00 /ff def\n"
"16#FB01 /fi def\n"
"16#FB02 /fl def\n"
"16#FB03 /ffi def\n"
"16#FB04 /ffl def\n"
"16#FB1F /afii57705 def\n"
"16#FB2A /afii57694 def\n"
"16#FB2B /afii57695 def\n"
"16#FB35 /afii57723 def\n"
"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"
" /FontBBox [0 0 100 100] def\n"
" /Encoding 256 array def\n"
" 0 1 255 {Encoding exch /.notdef put} for\n"
" Encoding 97 /openbox put\n"
" /CharProcs 2 dict def\n"
" CharProcs begin\n"
" /.notdef { } def\n"
" /openbox\n"
" { newpath\n"
" 90 30 moveto 90 670 lineto\n"
" 730 670 lineto 730 30 lineto\n"
" closepath\n"
" 60 setlinewidth\n"
" stroke } def\n"
" end\n"
" /BuildChar\n"
" { 1000 0 0\n"
" 0 750 750\n"
" setcachedevice\n"
" exch begin\n"
" Encoding exch get\n"
" CharProcs exch get\n"
" end\n"
" exec\n"
" } def\n"
"end\n"
"/NoglyphFont exch definefont pop\n"
"\n"
"/mbshow { % num\n"
" 8 array % num array\n"
" -1 % num array counter\n"
" {\n"
" dup 7 ge { exit } if\n"
" 1 add % num array counter\n"
" 2 index 16#100 mod % num array counter mod\n"
" 3 copy put pop % num array counter\n"
" 2 index 16#100 idiv % num array counter num\n"
" dup 0 le\n"
" {\n"
" pop exit\n"
" } if\n"
" 4 -1 roll pop\n"
" 3 1 roll\n"
" } loop % num array counter\n"
" 3 -1 roll pop % array counter\n"
" dup 1 add string % array counter string\n"
" 0 1 3 index\n"
" { % array counter string index\n"
" 2 index 1 index sub % array counter string index sid\n"
" 4 index 3 2 roll get % array counter string sid byte\n"
" 2 index 3 1 roll put % array counter string\n"
" } for\n"
" show pop pop\n"
"} def\n"
);
fprintf(f, "%s",
"/draw_undefined_char\n"
"{\n"
" csize /NoglyphFont Msf (a) show\n"
"} bind def\n"
"\n"
"/real_unicodeshow\n"
"{\n"
" /ccode exch def\n"
" /Unicodedict where {\n"
" pop\n"
" Unicodedict ccode known {\n"
" /cwidth {currentfont /ScaleMatrix get 0 get} def \n"
" /cheight cwidth def \n"
" gsave\n"
" currentpoint translate\n"
" cwidth 1056 div cheight 1056 div scale\n"
" 2 -2 translate\n"
" ccode Unicodedict exch get\n"
" cvx exec\n"
" grestore\n"
" currentpoint exch cwidth add exch moveto\n"
" true\n"
" } {\n"
" false\n"
" } ifelse\n"
" } {\n"
" false\n"
" } ifelse\n"
"} bind def\n"
"\n"
"/real_unicodeshow_native\n"
"{\n"
" /ccode exch def\n"
" /NativeFont where {\n"
" pop\n"
" NativeFont findfont /FontName get /Courier eq {\n"
" false\n"
" } {\n"
" csize NativeFont Msf\n"
" /Unicode2NativeDict where {\n"
" pop\n"
" Unicode2NativeDict ccode known {\n"
" Unicode2NativeDict ccode get show\n"
" true\n"
" } {\n"
" false\n"
" } ifelse\n"
" } {\n"
" false\n"
" } ifelse\n"
" } ifelse\n"
" } {\n"
" false\n"
" } ifelse\n"
"} bind def\n"
"\n"
"/real_glyph_unicodeshow\n"
"{\n"
" /ccode exch def\n"
" /UniDict where {\n"
" pop\n"
" UniDict ccode known {\n"
" UniDict ccode get glyphshow\n"
" true\n"
" } {\n"
" false\n"
" } ifelse\n"
" } {\n"
" false\n"
" } ifelse\n"
"} bind def\n"
"/real_unicodeshow_cid\n"
"{\n"
" /ccode exch def\n"
" /UCS2Font where {\n"
" pop\n"
" UCS2Font findfont /FontName get /Courier eq {\n"
" false\n"
" } {\n"
" csize UCS2Font Msf\n"
" ccode mbshow\n"
" true\n"
" } ifelse\n"
" } {\n"
" false\n"
" } ifelse\n"
"} bind def\n"
"\n"
"/unicodeshow \n"
"{\n"
" /cfont currentfont def\n"
" /str exch def\n"
" /i 0 def\n"
" str length /ls exch def\n"
" {\n"
" i 1 add ls ge {exit} if\n"
" str i get /c1 exch def\n"
" str i 1 add get /c2 exch def\n"
" /c c2 256 mul c1 add def\n"
" c2 1 ge \n"
" {\n"
" c unicodeshow1\n"
" {\n"
" % do nothing\n"
" } {\n"
" c real_unicodeshow_cid % try CID \n"
" {\n"
" % do nothing\n"
" } {\n"
" c unicodeshow2\n"
" {\n"
" % do nothing\n"
" } {\n"
" draw_undefined_char\n"
" } ifelse\n"
" } ifelse\n"
" } ifelse\n"
" } {\n"
" % ascii\n"
" cfont setfont\n"
" str i 1 getinterval show\n"
" } ifelse\n"
" /i i 2 add def\n"
" } loop\n"
"} bind def\n"
"\n"
"/u2nadd {Unicode2NativeDict 3 1 roll put} bind def\n"
"\n"
"/Unicode2NativeDictdef 0 dict def\n"
"/default_ls {\n"
" /Unicode2NativeDict Unicode2NativeDictdef def\n"
" /UCS2Font /Courier def\n"
" /NativeFont /Courier def\n"
" /unicodeshow1 { real_glyph_unicodeshow } bind def\n"
" /unicodeshow2 { real_unicodeshow_native } bind def\n"
"} bind def\n"
);
// setup prolog for each langgroup
initlanggroup(f);
fputs("%%EndResource\n", f); // Gecko_afm_procset
for(int i = 0;i < NUM_AFM_FONTS; i++) {
fprintf(f,
"%%%%BeginResource: font Gecko_%s\n"
"/F%d /%s Mfr\n"
"/f%d { dup /csize exch def /F%d Msf } bind def\n"
"%%%%EndResource\n",
gSubstituteFonts[i].mPSName, i, gSubstituteFonts[i].mPSName, i, i);
}
}
/** ---------------------------------------------------
* 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.
*/
nsresult
nsPostScriptObj::write_script(FILE *aDestHandle)
{
NS_PRECONDITION(aDestHandle, "Handle must not be NULL");
// Close out the prolog
fprintf(aDestHandle, "%%%%EndProlog\n");
// Begin the script section. Set the correct paper size.
fputs("%%BeginSetup\n", aDestHandle);
fprintf(aDestHandle,
"%%%%BeginFeature: *PageSize %s\n"
"/setpagedevice where\n" // Test for the feature
"{ pop 1 dict\n"
" dup /PageSize [ %s %s ] put\n" // Paper dimensions
" setpagedevice\n" // Install settings
"} if\n"
"%%%%EndFeature\n",
mPrintSetup->paper_name,
fpCString(NSTwipsToFloatPoints(mPrintContext->prSetup->width)).get(),
fpCString(NSTwipsToFloatPoints(mPrintContext->prSetup->height)).get());
fputs("%%EndSetup\n", aDestHandle);
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
*/
void
nsPostScriptObj::begin_page()
{
fprintf(mScriptFP, "%%%%Page: %d %d\n", mPageNumber, mPageNumber);
fprintf(mScriptFP, "%%%%BeginPageSetup\n");
if(mPrintSetup->num_copies > 1) {
fprintf(mScriptFP,
"/setpagedevice where\n"
"{ pop 1 dict dup /NumCopies %d put setpagedevice }\n"
"{ userdict /#copies %d put } ifelse\n",
mPrintSetup->num_copies, mPrintSetup->num_copies);
}
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(mScriptFP, "90 rotate 0 -%d translate\n",
mPrintContext->prSetup->height);
}
// Try to turn on automatic stroke adjust
fputs("true Msetstrokeadjust\n", mScriptFP);
fprintf(mScriptFP, "%%%%EndPageSetup\n");
// need to reset all U2Ntable
gLangGroups->Enumerate(ResetU2Ntable, nsnull);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::end_page()
{
fputs("pagelevel restore showpage\n", mScriptFP);
mPageNumber++;
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
nsresult
nsPostScriptObj::end_document()
{
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("nsPostScriptObj::end_document()\n"));
NS_PRECONDITION(mScriptFP, "No script file handle");
// Finish up the document.
fprintf(mScriptFP, "%%%%Trailer\n");
fprintf(mScriptFP, "%%%%EOF\n");
PR_LOG(nsPostScriptObjLM, PR_LOG_DEBUG, ("postscript generation completed.\n"));
return ferror(mScriptFP) ? NS_ERROR_GFX_PRINTER_FILE_IO_ERROR : NS_OK;
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc. Updated 3/22/2000 to deal with only non-Unicode chars. yueheng.xu@intel.com
*/
void
nsPostScriptObj::show(const char* txt, int len, const char *align)
{
fputc('(', mScriptFP);
while (len-- > 0) {
switch (*txt) {
case '(':
case ')':
case '\\':
fputc('\\', mScriptFP);
// Fall through
default:
fputc(*txt, mScriptFP);
break;
}
txt++;
}
fprintf(mScriptFP, ") %sshow\n", align);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 6/1/2000 katakai
*/
void
nsPostScriptObj::preshow(const PRUnichar* txt, int len)
{
unsigned char highbyte;
PRUnichar uch;
char outbuffer[6];
PRUnichar inbuffer[2];
nsresult res = NS_OK;
if (gEncoder && gU2Ntable) {
while (len-- > 0) {
uch = *txt;
highbyte = (uch >> 8 ) & 0xff;
if (highbyte > 0) {
inbuffer[0] = uch;
inbuffer[1] = 0;
PRInt32 *ncode = nsnull;
nsStringKey key(inbuffer, 1);
ncode = (PRInt32 *) gU2Ntable->Get(&key);
if (ncode && *ncode) {
} else {
PRInt32 insize, outsize;
outsize = 6;
insize = 1;
// example, 13327 (USC2 0x340f) -> 14913679 (gb18030 0xe3908f)
res = gEncoder->Convert(inbuffer, &insize, outbuffer, &outsize);
if (NS_SUCCEEDED(res) && outsize > 1) {
int i;
PRInt32 code = 0;
for(i=1;i<=outsize;i++) {
code += (outbuffer[i - 1] & 0xff) << (8 * (outsize - i));
}
if (code) {
ncode = new PRInt32;
*ncode = code;
gU2Ntable->Put(&key, ncode);
fprintf(mScriptFP, "%d <%x> u2nadd\n", uch, code);
}
}
}
}
txt++;
}
}
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 3/22/2000 to deal with only unicode chars. yueheng.xu@intel.com
*/
void
nsPostScriptObj::show(const PRUnichar* txt, int len,
const char *align, int aType)
{
unsigned char highbyte, lowbyte;
PRUnichar uch;
if (aType == 1) {
int i;
fputc('<', mScriptFP);
for (i=0; i < len; i++) {
if (i == 0)
fprintf(mScriptFP, "%04x", txt[i]);
else
fprintf(mScriptFP, " %04x", txt[i]);
}
fputs("> show\n", mScriptFP);
return;
}
fputc('(', mScriptFP);
while (len-- > 0) {
switch (*txt) {
case 0x0028: // '('
fputs("\\050\\000", mScriptFP);
break;
case 0x0029: // ')'
fputs("\\051\\000", mScriptFP);
break;
case 0x005c: // '\\'
fputs("\\134\\000", mScriptFP);
break;
default:
uch = *txt;
highbyte = (uch >> 8 ) & 0xff;
lowbyte = ( uch & 0xff );
// 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(mScriptFP, "\\00%o", lowbyte & 0xff);
else if ( lowbyte < 64 && lowbyte >= 8)
fprintf(mScriptFP, "\\0%o", lowbyte & 0xff);
else
fprintf(mScriptFP, "\\%o", lowbyte & 0xff);
if ( highbyte < 8 )
fprintf(mScriptFP, "\\00%o", highbyte & 0xff);
else if ( highbyte < 64 && highbyte >= 8)
fprintf(mScriptFP, "\\0%o", highbyte & 0xff);
else
fprintf(mScriptFP, "\\%o", highbyte & 0xff);
break;
}
txt++;
}
fprintf(mScriptFP, ") %sunicodeshow\n", align);
}
#if defined(MOZ_ENABLE_FREETYPE2) || defined(MOZ_ENABLE_XFT)
void
nsPostScriptObj::show(const PRUnichar* aTxt, int aLen,
const nsAFlatString& aCharList, PRUint16 aSubFontIdx)
{
int i;
fputc('<', mScriptFP);
const PRUint16 subFontSize = nsPSFontGenerator::kSubFontSize;
// the character repertoire of a subfont (255 characters max)
const nsAString& repertoire =
Substring(aCharList, aSubFontIdx * subFontSize,
PR_MIN(subFontSize,
aCharList.Length() - aSubFontIdx * subFontSize));
for (i = 0; i < aLen; i++) {
// XXX This is a little inefficient, but printing is not perf. critical.
NS_ASSERTION(repertoire.FindChar(aTxt[i]) != kNotFound,
"character is not covered by this subfont");
// Type 1 encoding vector has 256 slots, but the 0-th slot is
// reserved for /.notdef so that we use the 1st through 255th slots
// for actual characters (hence '+ 1')
fprintf(mScriptFP, "%02x", repertoire.FindChar(aTxt[i]) + 1);
}
fputs("> show\n", mScriptFP);
}
#endif
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::moveto(nscoord x, nscoord y)
{
fprintf(mScriptFP, "%d %d moveto\n", x, y);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::lineto(nscoord aX, nscoord aY)
{
fprintf(mScriptFP, "%d %d lineto\n", aX, aY);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @param aWidth Width of the ellipse implied by the arc
* aHeight Height of the ellipse
* aStartAngle Angle for the start of the arc
* aEndAngle Angle for the end of the arc
*/
void
nsPostScriptObj::arc(nscoord aWidth, nscoord aHeight,
float aStartAngle,float aEndAngle)
{
// Arc definition
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(),
fpCString(aStartAngle).get(), fpCString(aEndAngle).get());
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::box(nscoord aX, nscoord aY, nscoord aW, nscoord aH)
{
fprintf(mScriptFP, "%d %d %d %d Mrect ", aX, aY, aW, aH);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::box_subtract(nscoord aX, nscoord aY, nscoord aW, nscoord aH)
{
fprintf(mScriptFP,
"%d %d moveto 0 %d rlineto %d 0 rlineto 0 %d rlineto closepath ",
aX, aY, aH, aW, -aH);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::clip()
{
fputs(" clip\n", mScriptFP);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::eoclip()
{
fputs(" eoclip\n", mScriptFP);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::clippath()
{
fputs(" clippath\n", mScriptFP);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::newpath()
{
fputs(" newpath\n", mScriptFP);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::closepath()
{
fputs(" closepath\n", mScriptFP);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::initclip()
{
fputs(" initclip\n", mScriptFP);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::line(nscoord aX1, nscoord aY1,
nscoord aX2, nscoord aY2, nscoord aThick)
{
fprintf(mScriptFP, "gsave %d setlinewidth\n ", aThick);
fprintf(mScriptFP, " %d %d moveto %d %d lineto\n", aX1, aY1, aX2, aY2);
stroke();
fprintf(mScriptFP, "grestore\n");
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::stroke()
{
fputs(" stroke\n", mScriptFP);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::fill()
{
fputs(" fill\n", mScriptFP);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::graphics_save()
{
fputs(" gsave\n", mScriptFP);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::graphics_restore()
{
fputs(" grestore\n", mScriptFP);
}
/** ---------------------------------------------------
* Output postscript to scale the current coordinate system
* @param aX X scale factor
* aY Y scale factor
*/
void
nsPostScriptObj::scale(float aX, float aY)
{
fprintf(mScriptFP, "%s %s scale\n",
fpCString(aX).get(), fpCString(aY).get());
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::translate(nscoord x, nscoord y)
{
fprintf(mScriptFP, "%d %d translate\n", x, y);
}
/** ---------------------------------------------------
* Draw an image. This involves two coordinate systems, one for the
* page and one for the image. dRect is in the page coordinate system;
* it describes the rectangle which the image should occupy on the page.
* sRect describes the same rectangle, only in image space; it's the
* portion of the image which should appear on the page. iRect describes
* the position and dimensions of the actual pixel data within image
* space.
*
* In the simple case, sRect and iRect will be the same, and their (x,y)
* values will be (0,0). But images may have a virtual size larger than
* the pixel rectangle, so iRect's position may not be (0,0) and its
* dimensions may be smaller than sRect's. Similarly, it's possible that
* only part of the image is being printed, in which case sRect's
* position may not be (0,0) and its dimensions may not span the entire
* iRect rectangle. So in the general case, iRect and sRect may be
* completely arbitrary relative to each other and to the image-space
* origin.
*
* @update 3/14/2004 kherron
* @param anImage Image to draw
* @param dRect Rectangle describing where on the page the image
* should appear. Units are twips.
* @param sRect Rectangle describing the portion of the image that
* appears on the page, i.e. the part of the image's
* coordinate space that maps to dRect.
* @param iRect Rectangle describing the portion of the image's
* coordinate space covered by the image pixel data.
*/
void
nsPostScriptObj::draw_image(nsIImage *anImage,
const nsRect& sRect, const nsRect& iRect, const nsRect& dRect)
{
// If a final image dimension is 0 pixels, just return (see bug 191684)
if ((0 == dRect.width) || (0 == dRect.height)) {
return;
}
PRBool hasAlpha = anImage->GetHasAlphaMask();
PRInt32 bytesPerRow = anImage->GetLineStride();
PRUint8 *rowCopy = nsnull;
if (hasAlpha) {
rowCopy = new PRUint8[bytesPerRow];
if (!rowCopy) {
return;
}
}
anImage->LockImagePixels(PR_FALSE);
PRUint8 *theBits = anImage->GetBits();
// Image data is unavailable, or it has no height or width.
// There's nothing to print, so just return.
if (!theBits || (0 == iRect.width) || (0 == iRect.height)) {
anImage->UnlockImagePixels(PR_FALSE);
delete[] rowCopy;
return;
}
// Save the current graphic state and define a PS variable that
// can hold pixel data.
// If !hasAlpha, we read the image one line at a time
PRInt32 pixCountBytes = mPrintSetup->color ? iRect.width * 3 : iRect.width;
PRInt32 alphaCountBytes = hasAlpha ? (iRect.width + 7)/8 : 0;
fprintf(mScriptFP, "gsave\n"
"/rowdata %d string def\n", pixCountBytes + alphaCountBytes);
if (hasAlpha) {
// Determine whether we can support explicit mask
fputs("/useExplicitMask false def\n"
"/languagelevel where\n"
"{pop languagelevel\n"
" 3 eq\n"
" {/useExplicitMask true def} if\n"
"} if\n"
"/makedict {"
" counttomark 2 idiv\n"
" dup dict\n"
" begin\n"
" {def} repeat\n"
" pop\n"
" currentdict\n"
" end } def\n", mScriptFP);
}
// Translate the coordinate origin to the corner of the rectangle where
// the image should appear, set up a clipping region, and scale the
// coordinate system to the image's final size.
translate(dRect.x, dRect.y);
box(0, 0, dRect.width, dRect.height);
clip();
fprintf(mScriptFP, "%d %d scale\n", dRect.width, dRect.height);
// Output the transformation matrix for the image. This is a bit tricky
// to understand. PS image-drawing operations involve two transformation
// matrices: (1) A Transformation matrix associated with the image
// describes how to map the pixel data (width x height) onto a unit square,
// and (2) the document's TM maps the unit square to the desired size and
// position. The image TM is technically an inverse TM, i.e. it describes
// how to map the unit square onto the pixel array.
//
// sRect and dRect define the same rectangle, only in different coordinate
// systems. Following the translate & scale operations above, the origin
// is at [sRect.x, sRect.y]. The "real" origin of image space is thus at
// [-sRect.x, -sRect.y] and the pixel data should start at
// [-sRect.x + iRect.x, -sRect.y + iRect.y]. These are negated because the
// TM is supposed to be an inverse TM.
nscoord tmTX = sRect.x - iRect.x;
nscoord tmTY = sRect.y - iRect.y;
// In document space, the target rectangle is [dRect.width,
// dRect.height]; in image space it's [sRect.width, sRect.height]. So
// the proper scale factor is [1/sRect.width, 1/sRect.height], but
// again, the output should be an inverse TM so these are inverted.
nscoord tmSX = sRect.width;
nscoord tmSY = sRect.height;
// If the image is being stretched and clipped, it's possible that only
// a fraction of a pixel is supposed to be visible, resulting in a
// dimension of zero after rounding. 0 isn't a valid scaling factor.
// But something should appear on the page, unlike the case where dRect
// or iRect is zero-sized, so force the dimension to 1. See bug 236801.
if (0 == tmSX)
tmSX = 1;
if (0 == tmSY)
tmSY = 1;
// If the image data is in the wrong order, invert the TM, causing
// the image to be drawn inverted.
if (!anImage->GetIsRowOrderTopToBottom()) {
tmTY += tmSY;
tmSY = -tmSY;
}
if (hasAlpha) {
const char* decodeMatrix;
fprintf(mScriptFP, " useExplicitMask {\n");
if (mPrintSetup->color) {
fprintf(mScriptFP, " /DeviceRGB setcolorspace\n");
decodeMatrix = "0 1 0 1 0 1";
} else {
fprintf(mScriptFP, " /DeviceGray setcolorspace\n");
decodeMatrix = "0 1";
}
fprintf(mScriptFP, "mark /ImageType 3\n"
" /DataDict mark\n"
" /ImageType 1 /Width %d /Height %d\n"
" /ImageMatrix [ %d 0 0 %d %d %d ]\n"
" /DataSource { currentfile rowdata readhexstring pop }\n"
" /BitsPerComponent 8\n"
" /Decode [%s]\n"
" makedict\n"
" /MaskDict mark\n"
" /ImageType 1 /Width %d /Height %d\n"
" /ImageMatrix [ %d 0 0 %d %d %d ]\n"
" /BitsPerComponent 1\n"
" /Decode [1 0]\n"
" makedict\n"
" /InterleaveType 2\n" // interleave by row
" makedict image}\n"
"{", iRect.width, iRect.height, tmSX, tmSY, tmTX, tmTY,
decodeMatrix,
iRect.width, iRect.height, tmSX, tmSY, tmTX, tmTY);
}
// output the runtime fallback "no mask" code
fprintf(mScriptFP, " %d %d 8 [ %d 0 0 %d %d %d ]\n",
iRect.width, iRect.height, tmSX, tmSY, tmTX, tmTY);
if (hasAlpha) {
fprintf(mScriptFP, " { currentfile rowdata readhexstring pop %d %d getinterval }\n",
/*index*/ alphaCountBytes, /*index*/ pixCountBytes);
} else {
fprintf(mScriptFP, " { currentfile rowdata readhexstring pop }\n");
}
if (mPrintSetup->color) {
fputs(" false 3 colorimage\n", mScriptFP);
} else {
fputs(" image\n", mScriptFP);
}
if (hasAlpha) {
fputs("} ifelse\n", mScriptFP);
}
PRUint8* alphaBits;
PRInt32 alphaBytesPerRow;
PRInt32 alphaDepth;
if (hasAlpha) {
anImage->LockImagePixels(PR_TRUE);
alphaBits = anImage->GetAlphaBits();
alphaBytesPerRow = anImage->GetAlphaLineStride();
alphaDepth = anImage->GetAlphaDepth();
}
// Output the image data. The entire image is written, even
// if it's partially clipped in the document.
int outputCount = 0;
nscoord y;
for (y = 0; y < iRect.height; y++) {
PRUint8 *row = theBits + y * bytesPerRow;
// output alpha first, if any
if (hasAlpha) {
// Copy the row so that we can set any transparent pixels to white
memcpy(rowCopy, row, bytesPerRow);
row = rowCopy;
PRUint8 *alphaRow = alphaBits + y * alphaBytesPerRow;
PRUint8 v = 0;
for (nscoord x = 0; x < iRect.width; x++) {
PRUint8 alpha;
if (alphaDepth == 8) {
alpha = alphaRow[x];
} else {
PRUint8 mask = 0x80 >> (x & 7);
// Test the x'th bit of the alphaRow
alpha = (alphaRow[x >> 3] & mask) ? 255 : 0;
}
if (alpha >= 128) {
PRUint8 mask = 0x80 >> (x & 7);
// set the correct bit for the Postscript mask
v |= mask;
} else {
// Many tools set fully transparent pixels to black (perhaps
// because that compresses better). So for PS printers that
// don't support transparency, we'll get the image on an ugly
// black background which is especially bad on printers.
// So if the pixel is fully transparent and fully black, then
// we set it to white --- still wrong, but less bad.
PRUint8 *pixel = row + (x * 3);
if (alpha == 0 && pixel[0] == 0 && pixel[1] == 0 &&
pixel[2] == 0) {
pixel[0] = pixel[1] = pixel[2] = 0xFF;
}
}
if ((x & 7) == 7 || x == iRect.width - 1) {
outputCount += fprintf(mScriptFP, "%02x", v);
if (outputCount >= 72) {
fputc('\n', mScriptFP);
outputCount = 0;
}
v = 0;
}
}
fputc('\n', mScriptFP);
outputCount = 0;
}
for (nscoord x = 0; x < iRect.width; x++) {
PRUint8 *pixel = row + (x * 3);
if (mPrintSetup->color)
outputCount +=
fprintf(mScriptFP, "%02x%02x%02x", pixel[0], pixel[1], pixel[2]);
else
outputCount +=
fprintf(mScriptFP, "%02x",
NS_RGB_TO_GRAY(pixel[0], pixel[1], pixel[2]));
if (outputCount >= 72) {
fputc('\n', mScriptFP);
outputCount = 0;
}
}
fputc('\n', mScriptFP);
outputCount = 0;
}
if (hasAlpha) {
anImage->UnlockImagePixels(PR_TRUE);
}
anImage->UnlockImagePixels(PR_FALSE);
// Free the PS data buffer and restore the previous graphics state.
fputs("/undef where { pop /rowdata where { /rowdata undef } if } if\n"
"grestore\n", mScriptFP);
delete[] rowCopy;
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/99 dwc
*/
void
nsPostScriptObj::setcolor(nscolor aColor)
{
float greyBrightness;
/* For greyscale postscript, find the average brightness of red, green, and
* blue. Using this average value as the brightness for red, green, and
* blue is a simple way to make the postscript greyscale instead of color.
*/
if(mPrintSetup->color == PR_FALSE ) {
greyBrightness=NS_PS_GRAY(NS_RGB_TO_GRAY(NS_GET_R(aColor),
NS_GET_G(aColor),
NS_GET_B(aColor)));
fprintf(mScriptFP, "%s setgray\n", fpCString(greyBrightness).get());
} else {
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());
}
}
void nsPostScriptObj::setfont(const nsCString& aFontName, PRUint32 aHeight,
PRInt32 aSubFont)
{
fprintf(mScriptFP, "%d /%s.Set%d Msf\n", aHeight, aFontName.get(),
aSubFont);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/98 dwc
*/
void
nsPostScriptObj::setscriptfont(PRInt16 aFontIndex,const nsString &aFamily,nscoord aHeight, PRUint8 aStyle,
PRUint8 aVariant, PRUint16 aWeight, PRUint8 decorations)
{
int postscriptFont = 0;
fprintf(mScriptFP, "%d", aHeight);
if( aFontIndex >= 0) {
postscriptFont = aFontIndex;
} else {
//#ifdef NOTNOW
//XXX:PS Add bold, italic and other settings here
switch(aStyle){
case NS_FONT_STYLE_NORMAL :
if (NS_IS_BOLD(aWeight)) {
postscriptFont = 1; // TIMES NORMAL BOLD
}else{
postscriptFont = 0; // Times ROMAN Normal
}
break;
case NS_FONT_STYLE_ITALIC:
if (NS_IS_BOLD(aWeight)) {
postscriptFont = 2; // TIMES BOLD ITALIC
}else{
postscriptFont = 3; // TIMES ITALIC
}
break;
case NS_FONT_STYLE_OBLIQUE:
if (NS_IS_BOLD(aWeight)) {
postscriptFont = 6; // HELVETICA OBLIQUE
}else{
postscriptFont = 7; // HELVETICA OBLIQUE
}
break;
}
//#endif
}
fprintf(mScriptFP, " f%d\n", postscriptFont);
#if 0
// The style of font (normal, italic, oblique)
PRUint8 style;
// The variant of the font (normal, small-caps)
PRUint8 variant;
// The weight of the font (0-999)
PRUint16 weight;
// The decorations on the font (underline, overline,
// line-through). The decorations can be binary or'd together.
PRUint8 decorations;
// The size of the font, in nscoord units
nscoord size;
#endif
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 2/1/98 dwc
*/
void
nsPostScriptObj::comment(const char *aTheComment)
{
fprintf(mScriptFP, "%%%s\n", aTheComment);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 5/30/00 katakai
*/
void
nsPostScriptObj::setlanggroup(nsIAtom * aLangGroup)
{
gEncoder = nsnull;
gU2Ntable = nsnull;
if (aLangGroup == nsnull) {
fputs("default_ls\n", mScriptFP);
return;
}
nsAutoString langstr;
aLangGroup->ToString(langstr);
/* already exist */
nsStringKey key(langstr);
PS_LangGroupInfo *linfo = (PS_LangGroupInfo *) gLangGroups->Get(&key);
if (linfo) {
nsCAutoString str; str.AssignWithConversion(langstr);
fprintf(mScriptFP, "%s_ls\n", str.get());
gEncoder = linfo->mEncoder;
gU2Ntable = linfo->mU2Ntable;
return;
} else {
fputs("default_ls\n", mScriptFP);
}
}
PRBool
nsPostScriptObj::GetUnixPrinterSetting(const nsCAutoString& aKey, char** aVal)
{
if (!mPrinterProps) {
return nsnull;
}
nsAutoString oValue;
nsresult res = mPrinterProps->GetStringProperty(aKey, oValue);
if (NS_FAILED(res)) {
return PR_FALSE;
}
*aVal = ToNewCString(oValue);
return PR_TRUE;
}
typedef struct _unixPrinterFallbacks_t {
const char *key;
const char *val;
} unixPrinterFallbacks_t;
static const unixPrinterFallbacks_t unixPrinterFallbacks[] = {
{"print.postscript.nativefont.ja", "Ryumin-Light-EUC-H"},
{"print.postscript.nativecode.ja", "euc-jp"},
{nsnull, nsnull}
};
PRBool
GetUnixPrinterFallbackSetting(const nsCAutoString& aKey, char** aVal)
{
const unixPrinterFallbacks_t *p;
const char* key = aKey.get();
for (p=unixPrinterFallbacks; p->key; p++) {
if (strcmp(key, p->key) == 0) {
*aVal = nsCRT::strdup(p->val);
return PR_TRUE;
}
}
return PR_FALSE;
}
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 = ((PrefEnumClosure *)aClosure)->psObj;
FILE *f = ((PrefEnumClosure *)aClosure)->handle;
nsAutoString lang; lang.AssignWithConversion(aName);
if (strstr(aName, kNativeFontPrefix)) {
NS_ASSERTION(strlen(kNativeFontPrefix) == 28, "Wrong hard-coded size.");
lang.Cut(0, 28);
} else if (strstr(aName, kUnicodeFontPrefix)) {
NS_ASSERTION(strlen(kNativeFontPrefix) == 29, "Wrong hard-coded size.");
lang.Cut(0, 29);
}
nsStringKey key(lang);
PS_LangGroupInfo *linfo = (PS_LangGroupInfo *) gLangGroups->Get(&key);
if (linfo) {
/* already exist */
return;
}
/* define new language group */
nsXPIDLCString psnativefont;
nsXPIDLCString psnativecode;
nsXPIDLCString psunicodefont;
int psfontorder = 0;
PRBool use_prefsfile = PR_FALSE;
PRBool use_vendorfile = PR_FALSE;
//
// Try to get the info from the user's prefs file
//
nsCAutoString namepsnativefont(kNativeFontPrefix);
namepsnativefont.AppendWithConversion(lang);
gPrefs->CopyCharPref(namepsnativefont.get(), getter_Copies(psnativefont));
nsCAutoString namepsnativecode("print.postscript.nativecode.");
namepsnativecode.AppendWithConversion(lang);
gPrefs->CopyCharPref(namepsnativecode.get(), getter_Copies(psnativecode));
if (((psnativefont)&&(*psnativefont)) && ((psnativecode)&&(*psnativecode))) {
use_prefsfile = PR_TRUE;
} else {
psnativefont.Adopt(0);
psnativecode.Adopt(0);
}
//
// if not found look for info from the printer vendor
//
if (use_prefsfile != PR_TRUE) {
psObj->GetUnixPrinterSetting(namepsnativefont, getter_Copies(psnativefont));
psObj->GetUnixPrinterSetting(namepsnativecode, getter_Copies(psnativecode));
if ((psnativefont) && (psnativecode)) {
use_vendorfile = PR_TRUE;
} else {
psnativefont.Adopt(0);
psnativecode.Adopt(0);
}
}
if (!use_prefsfile && !use_vendorfile) {
GetUnixPrinterFallbackSetting(namepsnativefont, getter_Copies(psnativefont));
GetUnixPrinterFallbackSetting(namepsnativecode, getter_Copies(psnativecode));
}
/* psnativefont and psnativecode both should be set */
if (!psnativefont || !psnativecode) {
psnativefont.Adopt(0);
psnativecode.Adopt(0);
} else {
nsCAutoString namepsfontorder("print.postscript.fontorder.");
namepsfontorder.AppendWithConversion(lang);
if (use_prefsfile) {
gPrefs->GetIntPref(namepsfontorder.get(), &psfontorder);
}
else if (use_vendorfile) {
nsXPIDLCString psfontorder_str;
psObj->GetUnixPrinterSetting(namepsfontorder, getter_Copies(psfontorder_str));
if (psfontorder_str) {
psfontorder = atoi(psfontorder_str);
}
}
}
/* check UCS fonts */
nsCAutoString namepsunicodefont(kUnicodeFontPrefix);
namepsunicodefont.AppendWithConversion(lang);
if (use_prefsfile) {
gPrefs->CopyCharPref(namepsunicodefont.get(), getter_Copies(psunicodefont));
} else if (use_vendorfile) {
psObj->GetUnixPrinterSetting(namepsunicodefont, getter_Copies(psunicodefont));
}
nsresult res = NS_OK;
if (psnativefont || psunicodefont) {
linfo = new PS_LangGroupInfo;
linfo->mEncoder = nsnull;
linfo->mU2Ntable = nsnull;
if (psnativecode) {
nsAutoString str;
nsCOMPtr<nsICharsetConverterManager> ccMain =
do_GetService(NS_CHARSETCONVERTERMANAGER_CONTRACTID, &res);
if (NS_SUCCEEDED(res)) {
res = ccMain->GetUnicodeEncoder(psnativecode.get(), &linfo->mEncoder);
}
}
gLangGroups->Put(&key, (void *) linfo);
nsCAutoString langstrC; langstrC.AssignWithConversion(lang);
if (psnativefont && linfo->mEncoder) {
fprintf(f, "/Unicode2NativeDict%s 0 dict def\n", langstrC.get());
}
fprintf(f, "/%s_ls {\n", langstrC.get());
fprintf(f, " /NativeFont /%s def\n",
(psnativefont && linfo->mEncoder) ? psnativefont.get() : "Courier");
fprintf(f, " /UCS2Font /%s def\n",
psunicodefont ? psunicodefont.get() : "Courier");
if (psnativefont && linfo->mEncoder) {
fprintf(f, " /Unicode2NativeDict Unicode2NativeDict%s def\n",
langstrC.get());
}
if (psfontorder) {
fprintf(f, " /unicodeshow1 { real_unicodeshow_native } bind def\n");
fprintf(f, " /unicodeshow2 { real_unicodeshow } bind def\n");
} else {
fprintf(f, " /unicodeshow1 { real_unicodeshow } bind def\n");
fprintf(f, " /unicodeshow2 { real_unicodeshow_native } bind def\n");
}
fprintf(f, "} bind def\n");
if (linfo->mEncoder) {
linfo->mEncoder->SetOutputErrorBehavior(
linfo->mEncoder->kOnError_Replace, nsnull, '?');
linfo->mU2Ntable = new nsHashtable();
}
}
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 5/30/00 katakai
*/
void
nsPostScriptObj::initlanggroup(FILE *aHandle)
{
PrefEnumClosure closure;
closure.handle = aHandle;
closure.psObj = this;
/* check langgroup of preference */
gPrefs->EnumerateChildren(kNativeFontPrefix,
PrefEnumCallback, (void *) &closure);
gPrefs->EnumerateChildren(kUnicodeFontPrefix,
PrefEnumCallback, (void *) &closure);
}
/** ---------------------------------------------------
* See documentation in nsPostScriptObj.h
* @update 3/6/2004 kherron
* @update 3/25/2004 dantifer
*/
nsresult
nsPostScriptObj::render_eps(const nsRect& aRect, nsEPSObjectPS &anEPS)
{
FILE *bfile = mScriptFP;
nsresult rv;
NS_PRECONDITION(nsnull != bfile, "No document body file handle");
/* Set up EPSF state. See Adobe spec #5002 section 3.2 */
fputs(
"/b4_Inc_state save def\n"
"/dict_count countdictstack def\n"
"/op_count count 1 sub def\n"
"userdict begin\n"
"/showpage { } def\n"
"0 setgray 0 setlinecap 1 setlinewidth 0 setlinejoin\n"
"10 setmiterlimit [ ] 0 setdash newpath\n"
"/languagelevel where\n"
"{pop languagelevel\n"
" 1 ne\n"
" {false setstrokeadjust false setoverprint\n"
" } if\n"
"} if\n",
bfile);
/* Set up a clipping region around the EPS rectangle */
box(aRect.x, aRect.y, aRect.width, aRect.height);
clip();
/* translate to the lower left corner of the rectangle */
translate(aRect.x, aRect.y + aRect.height);
/* Rescale */
scale(
aRect.width / (anEPS.GetBoundingBoxURX() - anEPS.GetBoundingBoxLLX()),
-(aRect.height / (anEPS.GetBoundingBoxURY() - anEPS.GetBoundingBoxLLY()))
);
/* Translate to the EPSF origin. Can't use translate() here because
* it takes integers.
*/
fprintf(bfile, "%s %s translate\n",
fpCString(-anEPS.GetBoundingBoxLLX()).get(),
fpCString(-anEPS.GetBoundingBoxLLY()).get()
);
/* embeding EPS file content */
comment("%BeginDocument: Mozilla-Internal");
rv = anEPS.WriteTo(bfile);
comment("%EndDocument");
/* Restore previous state */
fputs(
"count op_count sub { pop } repeat\n"
"countdictstack dict_count sub { end } repeat\n"
"b4_Inc_state restore\n",
bfile);
return rv;
}