examples/PIPS/antiword/src/postscript.c

00001 /*
00002  * postscript.c
00003  * Copyright (C) 1999-2005 A.J. van Os; Released under GNU GPL
00004  *
00005  * Description:
00006  * Functions to deal with the PostScript format
00007  *
00008  *================================================================
00009  * The function vImagePrologue is based on:
00010  * jpeg2ps - convert JPEG compressed images to PostScript Level 2
00011  * Copyright (C) 1994-99 Thomas Merz ([email protected])
00012  *================================================================
00013  * The credit should go to him, but all the bugs are mine.
00014  */
00015 
00016 #include <stdlib.h>
00017 #include <errno.h>
00018 #include <time.h>
00019 #include <string.h>
00020 #include "version.h"
00021 #include "antiword.h"
00022 
00023 /* The character set */
00024 static encoding_type    eEncoding = encoding_neutral;
00025 /* The image level */
00026 static image_level_enum eImageLevel = level_default;
00027 /* The output must use landscape orientation */
00028 static BOOL             bUseLandscape = FALSE;
00029 /* The height and width of a PostScript page (in DrawUnits) */
00030 static long             lPageHeight = LONG_MAX;
00031 static long             lPageWidth = LONG_MAX;
00032 /* The height of the footer on the current page (in DrawUnits) */
00033 static long             lFooterHeight = 0;
00034 /* Inside a footer (to prevent an infinite loop when the footer is too big) */
00035 static BOOL             bInFtrSpace = FALSE;
00036 /* Current time for a PS header */
00037 static const char       *szCreationDate = NULL;
00038 /* Current creator for a PS header */
00039 static const char       *szCreator = NULL;
00040 /* Current font information */
00041 static drawfile_fontref tFontRefCurr = (drawfile_fontref)-1;
00042 static USHORT           usFontSizeCurr = 0;
00043 static int              iFontColorCurr = -1;
00044 /* Current vertical position information */
00045 static long             lYtopCurr = -1;
00046 /* PostScript page counter */
00047 static int              iPageCount = 0;
00048 /* Image counter */
00049 static int              iImageCount = 0;
00050 /* Section index */
00051 static int              iSectionIndex = 0;
00052 /* Are we on the first page of the section? */
00053 static BOOL             bFirstInSection = TRUE;
00054 
00055 static void             vMoveTo(diagram_type *, long);
00056 
00057 static const char *iso_8859_1_data[] = {
00058 "/newcodes      % ISO-8859-1 character encodings",
00059 "[",
00060 "140/ellipsis 141/trademark 142/perthousand 143/bullet",
00061 "144/quoteleft 145/quoteright 146/guilsinglleft 147/guilsinglright",
00062 "148/quotedblleft 149/quotedblright 150/quotedblbase 151/endash 152/emdash",
00063 "153/minus 154/OE 155/oe 156/dagger 157/daggerdbl 158/fi 159/fl",
00064 "160/space 161/exclamdown 162/cent 163/sterling 164/currency",
00065 "165/yen 166/brokenbar 167/section 168/dieresis 169/copyright",
00066 "170/ordfeminine 171/guillemotleft 172/logicalnot 173/hyphen 174/registered",
00067 "175/macron 176/degree 177/plusminus 178/twosuperior 179/threesuperior",
00068 "180/acute 181/mu 182/paragraph 183/periodcentered 184/cedilla",
00069 "185/onesuperior 186/ordmasculine 187/guillemotright 188/onequarter",
00070 "189/onehalf 190/threequarters 191/questiondown 192/Agrave 193/Aacute",
00071 "194/Acircumflex 195/Atilde 196/Adieresis 197/Aring 198/AE 199/Ccedilla",
00072 "200/Egrave 201/Eacute 202/Ecircumflex 203/Edieresis 204/Igrave 205/Iacute",
00073 "206/Icircumflex 207/Idieresis 208/Eth 209/Ntilde 210/Ograve 211/Oacute",
00074 "212/Ocircumflex 213/Otilde 214/Odieresis 215/multiply 216/Oslash",
00075 "217/Ugrave 218/Uacute 219/Ucircumflex 220/Udieresis 221/Yacute 222/Thorn",
00076 "223/germandbls 224/agrave 225/aacute 226/acircumflex 227/atilde",
00077 "228/adieresis 229/aring 230/ae 231/ccedilla 232/egrave 233/eacute",
00078 "234/ecircumflex 235/edieresis 236/igrave 237/iacute 238/icircumflex",
00079 "239/idieresis 240/eth 241/ntilde 242/ograve 243/oacute 244/ocircumflex",
00080 "245/otilde 246/odieresis 247/divide 248/oslash 249/ugrave 250/uacute",
00081 "251/ucircumflex 252/udieresis 253/yacute 254/thorn 255/ydieresis",
00082 "] bind def",
00083 "",
00084 "/reencdict 12 dict def",
00085 "",
00086 };
00087 
00088 static const char *iso_8859_2_data[] = {
00089 "/newcodes      % ISO-8859-2 character encodings",
00090 "[",
00091 "160/space 161/Aogonek 162/breve 163/Lslash 164/currency 165/Lcaron",
00092 "166/Sacute 167/section 168/dieresis 169/Scaron 170/Scommaaccent",
00093 "171/Tcaron 172/Zacute 173/hyphen 174/Zcaron 175/Zdotaccent 176/degree",
00094 "177/aogonek 178/ogonek 179/lslash 180/acute 181/lcaron 182/sacute",
00095 "183/caron 184/cedilla 185/scaron 186/scommaaccent 187/tcaron",
00096 "188/zacute 189/hungarumlaut 190/zcaron 191/zdotaccent 192/Racute",
00097 "193/Aacute 194/Acircumflex 195/Abreve 196/Adieresis 197/Lacute",
00098 "198/Cacute 199/Ccedilla 200/Ccaron 201/Eacute 202/Eogonek",
00099 "203/Edieresis 204/Ecaron 205/Iacute 206/Icircumflex 207/Dcaron",
00100 "208/Dcroat 209/Nacute 210/Ncaron 211/Oacute 212/Ocircumflex",
00101 "213/Ohungarumlaut 214/Odieresis 215/multiply 216/Rcaron 217/Uring",
00102 "218/Uacute 219/Uhungarumlaut 220/Udieresis 221/Yacute 222/Tcommaaccent",
00103 "223/germandbls 224/racute 225/aacute 226/acircumflex 227/abreve",
00104 "228/adieresis 229/lacute 230/cacute 231/ccedilla 232/ccaron 233/eacute",
00105 "234/eogonek 235/edieresis 236/ecaron 237/iacute 238/icircumflex",
00106 "239/dcaron 240/dcroat 241/nacute 242/ncaron 243/oacute 244/ocircumflex",
00107 "245/ohungarumlaut 246/odieresis 247/divide 248/rcaron 249/uring",
00108 "250/uacute 251/uhungarumlaut 252/udieresis 253/yacute 254/tcommaaccent",
00109 "255/dotaccent",
00110 "] bind def",
00111 "",
00112 "/reencdict 12 dict def",
00113 "",
00114 };
00115 
00116 static const char *iso_8859_5_data[] = {
00117 "/newcodes      % ISO-8859-5 character encodings",
00118 "[",
00119 "160/space     161/afii10023 162/afii10051 163/afii10052 164/afii10053",
00120 "165/afii10054 166/afii10055 167/afii10056 168/afii10057 169/afii10058",
00121 "170/afii10059 171/afii10060 172/afii10061 173/hyphen    174/afii10062",
00122 "175/afii10145 176/afii10017 177/afii10018 178/afii10019 179/afii10020",
00123 "180/afii10021 181/afii10022 182/afii10024 183/afii10025 184/afii10026",
00124 "185/afii10027 186/afii10028 187/afii10029 188/afii10030 189/afii10031",
00125 "190/afii10032 191/afii10033 192/afii10034 193/afii10035 194/afii10036",
00126 "195/afii10037 196/afii10038 197/afii10039 198/afii10040 199/afii10041",
00127 "200/afii10042 201/afii10043 202/afii10044 203/afii10045 204/afii10046",
00128 "205/afii10047 206/afii10048 207/afii10049 208/afii10065 209/afii10066",
00129 "210/afii10067 211/afii10068 212/afii10069 213/afii10070 214/afii10072",
00130 "215/afii10073 216/afii10074 217/afii10075 218/afii10076 219/afii10077",
00131 "220/afii10078 221/afii10079 222/afii10080 223/afii10081 224/afii10082",
00132 "225/afii10083 226/afii10084 227/afii10085 228/afii10086 229/afii10087",
00133 "230/afii10088 231/afii10089 232/afii10090 233/afii10091 234/afii10092",
00134 "235/afii10093 236/afii10094 237/afii10095 238/afii10096 239/afii10097",
00135 "240/afii61352 241/afii10071 242/afii10099 243/afii10100 244/afii10101",
00136 "245/afii10102 246/afii10103 247/afii10104 248/afii10105 249/afii10106",
00137 "250/afii10107 251/afii10108 252/afii10109 253/section   254/afii10110",
00138 "255/afii10193",
00139 "] bind def",
00140 "",
00141 "/reencdict 12 dict def",
00142 "",
00143 };
00144 
00145 static const char *iso_8859_x_func[] = {
00146 "% change fonts using ISO-8859-x characters",
00147 "/ChgFnt                % size psname natname => font",
00148 "{",
00149 "       dup FontDirectory exch known            % is re-encoded name known?",
00150 "       { exch pop }                            % yes, get rid of long name",
00151 "       { dup 3 1 roll ReEncode } ifelse        % no, re-encode it",
00152 "       findfont exch scalefont setfont",
00153 "} bind def",
00154 "",
00155 "/ReEncode",
00156 "{",
00157 "reencdict begin",
00158 "       /newname exch def",
00159 "       /basename exch def",
00160 "       /basedict basename findfont def",
00161 "       /newfont basedict maxlength dict def",
00162 "       basedict",
00163 "       { exch dup /FID ne",
00164 "               { dup /Encoding eq",
00165 "                       { exch dup length array copy newfont 3 1 roll put }",
00166 "                       { exch newfont 3 1 roll put } ifelse",
00167 "               }",
00168 "               { pop pop } ifelse",
00169 "       } forall",
00170 "       newfont /FontName newname put",
00171 "       newcodes aload pop newcodes length 2 idiv",
00172 "       { newfont /Encoding get 3 1 roll put } repeat",
00173 "       newname newfont definefont pop",
00174 "end",
00175 "} bind def",
00176 "",
00177 };
00178 
00179 static const char *misc_func[] = {
00180 "% draw a line and show the string",
00181 "/LineShow      % string linewidth movement",
00182 "{",
00183 "       gsave",
00184 "               0 exch rmoveto",
00185 "               setlinewidth",
00186 "               dup",
00187 "               stringwidth pop",
00188 "               0 rlineto stroke",
00189 "       grestore",
00190 "       show",
00191 "} bind def",
00192 "",
00193 "% begin an EPS file (level 2 and up)",
00194 "/BeginEPSF",
00195 "{",
00196 "       /b4_Inc_state save def",
00197 "       /dict_count countdictstack def",
00198 "       /op_count count 1 sub def",
00199 "       userdict begin",
00200 "               /showpage { } def",
00201 "               0 setgray 0 setlinecap",
00202 "               1 setlinewidth 0 setlinejoin",
00203 "               10 setmiterlimit [ ] 0 setdash newpath",
00204 "               false setstrokeadjust false setoverprint",
00205 "} bind def",
00206 "",
00207 "% end an EPS file",
00208 "/EndEPSF {",
00209 "       count op_count sub { pop } repeat",
00210 "       countdictstack dict_count sub { end } repeat",
00211 "       b4_Inc_state restore",
00212 "} bind def",
00213 "",
00214 };
00215 
00216 
00217 /*
00218  * vAddPageSetup - add the page setup
00219  */
00220 static void
00221 vAddPageSetup(FILE *pOutFile)
00222 {
00223         if (bUseLandscape) {
00224                 fprintf(pOutFile, "%%%%BeginPageSetup\n");
00225                 fprintf(pOutFile, "90 rotate\n");
00226                 fprintf(pOutFile, "0.00 %.2f translate\n",
00227                                         -dDrawUnits2Points(lPageHeight));
00228                 fprintf(pOutFile, "%%%%EndPageSetup\n");
00229         }
00230 } /* end of vAddPageSetup */
00231 
00232 /*
00233  * vAddHdrFtr - add a header or footer
00234  */
00235 static void
00236 vAddHdrFtr(diagram_type *pDiag, const hdrftr_block_type *pHdrFtrInfo)
00237 {
00238         output_type     *pStart, *pPrev, *pNext;
00239 
00240         fail(pDiag == NULL);
00241         fail(pHdrFtrInfo == NULL);
00242 
00243         vStartOfParagraphPS(pDiag, 0);
00244         pStart = pHdrFtrInfo->pText;
00245         while (pStart != NULL) {
00246                 pNext = pStart;
00247                 while (pNext != NULL &&
00248                        (pNext->tNextFree != 1 ||
00249                         (pNext->szStorage[0] != PAR_END &&
00250                          pNext->szStorage[0] != HARD_RETURN))) {
00251                         pNext = pNext->pNext;
00252                 }
00253                 if (pNext == NULL) {
00254                         if (bOutputContainsText(pStart)) {
00255                                 vAlign2Window(pDiag, pStart,
00256                                         lChar2MilliPoints(DEFAULT_SCREEN_WIDTH),
00257                                         ALIGNMENT_LEFT);
00258                         } else {
00259                                 vMove2NextLinePS(pDiag, pStart->usFontSize);
00260                         }
00261                         break;
00262                 }
00263                 fail(pNext->tNextFree != 1);
00264                 fail(pNext->szStorage[0] != PAR_END &&
00265                         pNext->szStorage[0] != HARD_RETURN);
00266 
00267                 if (pStart != pNext) {
00268                         /* There is something to print */
00269                         pPrev = pNext->pPrev;
00270                         fail(pPrev->pNext != pNext);
00271                         /* Cut the chain */
00272                         pPrev->pNext = NULL;
00273                         if (bOutputContainsText(pStart)) {
00274                                 /* Print it */
00275                                 vAlign2Window(pDiag, pStart,
00276                                         lChar2MilliPoints(DEFAULT_SCREEN_WIDTH),
00277                                         ALIGNMENT_LEFT);
00278                         } else {
00279                                 /* Just an empty line */
00280                                 vMove2NextLinePS(pDiag, pStart->usFontSize);
00281                         }
00282                         /* Repair the chain */
00283                         pPrev->pNext = pNext;
00284                 }
00285                 if (pNext->szStorage[0] == PAR_END) {
00286                         vEndOfParagraphPS(pDiag, pNext->usFontSize,
00287                                         (long)pNext->usFontSize * 200);
00288                 }
00289                 pStart = pNext->pNext;
00290         }
00291 } /* end of vAddHdrFtr */
00292 
00293 /*
00294  * vAddHeader - add a page header
00295  */
00296 static void
00297 vAddHeader(diagram_type *pDiag)
00298 {
00299         const hdrftr_block_type *pHdrInfo;
00300         const hdrftr_block_type *pFtrInfo;
00301 
00302         fail(pDiag == NULL);
00303 
00304         NO_DBG_MSG("vAddHeader");
00305 
00306         pHdrInfo = pGetHdrFtrInfo(iSectionIndex, TRUE,
00307                                         odd(iPageCount), bFirstInSection);
00308         pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE,
00309                                         odd(iPageCount), bFirstInSection);
00310         /* Set the height of the footer of this page */
00311         lFooterHeight = pFtrInfo == NULL ? 0 : pFtrInfo->lHeight;
00312         fail(lFooterHeight < 0);
00313 
00314         if (pHdrInfo == NULL ||
00315             pHdrInfo->pText == NULL ||
00316             pHdrInfo->lHeight <= 0) {
00317                 fail(pHdrInfo != NULL && pHdrInfo->lHeight < 0);
00318                 fail(pHdrInfo != NULL &&
00319                         pHdrInfo->pText != NULL &&
00320                         pHdrInfo->lHeight == 0);
00321                 return;
00322         }
00323 
00324         vAddHdrFtr(pDiag, pHdrInfo);
00325 
00326         DBG_DEC_C(pHdrInfo->lHeight !=
00327                 lPageHeight - PS_TOP_MARGIN - pDiag->lYtop,
00328                 pHdrInfo->lHeight);
00329         DBG_DEC_C(pHdrInfo->lHeight !=
00330                 lPageHeight - PS_TOP_MARGIN - pDiag->lYtop,
00331                 lPageHeight - PS_TOP_MARGIN - pDiag->lYtop);
00332 
00333 #if 0 /* defined(DEBUG) */
00334         fprintf(pDiag->pOutFile,
00335         "(HEADER: FileOffset 0x%04lx-0x%04lx; Height %ld-%ld) show\n",
00336                 ulCharPos2FileOffset(pHdrInfo->ulCharPosStart),
00337                 ulCharPos2FileOffset(pHdrInfo->ulCharPosNext),
00338                 pHdrInfo->lHeight,
00339                 lPageHeight - PS_TOP_MARGIN - pDiag->lYtop);
00340 #endif
00341 } /* end of vAddHeader */
00342 
00343 /*
00344  * vAddFooter - add a page footer
00345  */
00346 static void
00347 vAddFooter(diagram_type *pDiag)
00348 {
00349         const hdrftr_block_type *pFtrInfo;
00350 
00351         fail(pDiag == NULL);
00352 
00353         NO_DBG_MSG("vAddFooter");
00354         pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE,
00355                                         odd(iPageCount), bFirstInSection);
00356         bFirstInSection = FALSE;
00357         if (pFtrInfo == NULL ||
00358             pFtrInfo->pText == NULL ||
00359             pFtrInfo->lHeight <= 0) {
00360                 fail(pFtrInfo != NULL && pFtrInfo->lHeight < 0);
00361                 fail(pFtrInfo != NULL &&
00362                         pFtrInfo->pText != NULL &&
00363                         pFtrInfo->lHeight == 0);
00364                 return;
00365         }
00366 
00367         bInFtrSpace = TRUE;
00368 
00369         DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, pFtrInfo->lHeight);
00370         DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, lFooterHeight);
00371         DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN,
00372                         pDiag->lYtop);
00373         DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN,
00374                         lFooterHeight + PS_BOTTOM_MARGIN);
00375 
00376         if (pDiag->lYtop > lFooterHeight + PS_BOTTOM_MARGIN) {
00377                 /* Move down to the start of the footer */
00378                 pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN;
00379                 vMoveTo(pDiag, 0);
00380         } else if (pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN / 2) {
00381                 DBG_FIXME();
00382                 /*
00383                  * Move up to the start of the footer, to prevent moving
00384                  * of the bottom edge of the paper
00385                  */
00386                 pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN;
00387                 vMoveTo(pDiag, 0);
00388         }
00389 
00390         DBG_FLT_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN,
00391         dDrawUnits2Points(lFooterHeight + PS_BOTTOM_MARGIN - pDiag->lYtop));
00392 
00393 #if 0 /* defined(DEBUG) */
00394         fprintf(pDiag->pOutFile,
00395         "(FOOTER: FileOffset 0x%04lx-0x%04lx; Bottom %ld-%ld) show\n",
00396                 ulCharPos2FileOffset(pFtrInfo->ulCharPosStart),
00397                 ulCharPos2FileOffset(pFtrInfo->ulCharPosNext),
00398                 pDiag->lYtop,
00399                 pFtrInfo->lHeight + PS_BOTTOM_MARGIN);
00400 #endif
00401         vAddHdrFtr(pDiag, pFtrInfo);
00402         bInFtrSpace = FALSE;
00403 } /* end of vAddFooter */
00404 
00405 /*
00406  * vMove2NextPage - move to the start of the next page
00407  */
00408 static void
00409 vMove2NextPage(diagram_type *pDiag, BOOL bNewSection)
00410 {
00411         fail(pDiag == NULL);
00412 
00413         vAddFooter(pDiag);
00414         fprintf(pDiag->pOutFile, "showpage\n");
00415         iPageCount++;
00416         fprintf(pDiag->pOutFile, "%%%%Page: %d %d\n", iPageCount, iPageCount);
00417         if (bNewSection) {
00418                 iSectionIndex++;
00419                 bFirstInSection = TRUE;
00420         }
00421         vAddPageSetup(pDiag->pOutFile);
00422         pDiag->lYtop = lPageHeight - PS_TOP_MARGIN;
00423         lYtopCurr = -1;
00424         vAddHeader(pDiag);
00425 } /* end of vMove2NextPage */
00426 
00427 /*
00428  * vMoveTo - move to the specified X,Y coordinates
00429  *
00430  * Move the current position of the specified diagram to its X,Y coordinates,
00431  * start on a new page if needed
00432  */
00433 static void
00434 vMoveTo(diagram_type *pDiag, long lLastVerticalMovement)
00435 {
00436         fail(pDiag == NULL);
00437         fail(pDiag->pOutFile == NULL);
00438 
00439         if (pDiag->lYtop <= lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace) {
00440                 vMove2NextPage(pDiag, FALSE);
00441                 /* Repeat the last vertical movement on the new page */
00442                 pDiag->lYtop -= lLastVerticalMovement;
00443         }
00444 
00445         fail(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace);
00446         DBG_DEC_C(pDiag->lYtop < PS_BOTTOM_MARGIN, pDiag->lYtop);
00447         fail(pDiag->lYtop < PS_BOTTOM_MARGIN / 3);
00448 
00449         if (pDiag->lYtop != lYtopCurr) {
00450                 fprintf(pDiag->pOutFile, "%.2f %.2f moveto\n",
00451                         dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN),
00452                         dDrawUnits2Points(pDiag->lYtop));
00453                 lYtopCurr = pDiag->lYtop;
00454         }
00455 } /* end of vMoveTo */
00456 
00457 /*
00458  * vProloguePS - set options and perform the PostScript initialization
00459  */
00460 void
00461 vProloguePS(diagram_type *pDiag,
00462         const char *szTask, const char *szFilename,
00463         const options_type *pOptions)
00464 {
00465         FILE    *pOutFile;
00466         const char      *szTmp;
00467         time_t  tTime;
00468 
00469         fail(pDiag == NULL);
00470         fail(pDiag->pOutFile == NULL);
00471         fail(szTask == NULL || szTask[0] == '\0');
00472         fail(pOptions == NULL);
00473 
00474         pOutFile = pDiag->pOutFile;
00475 
00476         bUseLandscape = pOptions->bUseLandscape;
00477         eEncoding = pOptions->eEncoding;
00478         eImageLevel = pOptions->eImageLevel;
00479 
00480         if (pOptions->iPageHeight == INT_MAX) {
00481                 lPageHeight = LONG_MAX;
00482         } else {
00483                 lPageHeight = lPoints2DrawUnits(pOptions->iPageHeight);
00484         }
00485         DBG_DEC(lPageHeight);
00486         if (pOptions->iPageWidth == INT_MAX) {
00487                 lPageWidth = LONG_MAX;
00488         } else {
00489                 lPageWidth = lPoints2DrawUnits(pOptions->iPageWidth);
00490         }
00491         DBG_DEC(lPageWidth);
00492         lFooterHeight = 0;
00493         bInFtrSpace = FALSE;
00494 
00495         tFontRefCurr = (drawfile_fontref)-1;
00496         usFontSizeCurr = 0;
00497         iFontColorCurr = -1;
00498         lYtopCurr = -1;
00499         iPageCount = 0;
00500         iImageCount = 0;
00501         iSectionIndex = 0;
00502         bFirstInSection = TRUE;
00503         pDiag->lXleft = 0;
00504         pDiag->lYtop = lPageHeight - PS_TOP_MARGIN;
00505 
00506         szCreator = szTask;
00507 
00508         fprintf(pOutFile, "%%!PS-Adobe-2.0\n");
00509         fprintf(pOutFile, "%%%%Title: %s\n", szBasename(szFilename));
00510         fprintf(pOutFile, "%%%%Creator: %s %s\n", szCreator, VERSIONSTRING);
00511         szTmp = getenv("LOGNAME");
00512         if (szTmp == NULL || szTmp[0] == '\0') {
00513                 szTmp = getenv("USER");
00514                 if (szTmp == NULL || szTmp[0] == '\0') {
00515                         szTmp = "unknown";
00516                 }
00517         }
00518         fprintf(pOutFile, "%%%%For: %.50s\n", szTmp);
00519         errno = 0;
00520         tTime = time(NULL);
00521         if (tTime == (time_t)-1 && errno != 0) {
00522                 szCreationDate = NULL;
00523         } else {
00524                 szCreationDate = ctime(&tTime);
00525         }
00526         if (szCreationDate == NULL || szCreationDate[0] == '\0') {
00527                 szCreationDate = "unknown\n";
00528         }
00529         fprintf(pOutFile, "%%%%CreationDate: %s", szCreationDate);
00530         if (bUseLandscape) {
00531                 fprintf(pOutFile, "%%%%Orientation: Landscape\n");
00532                 fprintf(pOutFile, "%%%%BoundingBox: 0 0 %.0f %.0f\n",
00533                                 dDrawUnits2Points(lPageHeight),
00534                                 dDrawUnits2Points(lPageWidth));
00535         } else {
00536                 fprintf(pOutFile, "%%%%Orientation: Portrait\n");
00537                 fprintf(pOutFile, "%%%%BoundingBox: 0 0 %.0f %.0f\n",
00538                                 dDrawUnits2Points(lPageWidth),
00539                                 dDrawUnits2Points(lPageHeight));
00540         }
00541 } /* end of vProloguePS */
00542 
00543 /*
00544  * vEpiloguePS - clean up after everything is done
00545  */
00546 void
00547 vEpiloguePS(diagram_type *pDiag)
00548 {
00549         fail(pDiag == NULL);
00550         fail(pDiag->pOutFile == NULL);
00551 
00552         if (pDiag->lYtop < lPageHeight - PS_TOP_MARGIN) {
00553                 vAddFooter(pDiag);
00554                 fprintf(pDiag->pOutFile, "showpage\n");
00555         }
00556         fprintf(pDiag->pOutFile, "%%%%Trailer\n");
00557         fprintf(pDiag->pOutFile, "%%%%Pages: %d\n", iPageCount);
00558         fprintf(pDiag->pOutFile, "%%%%EOF\n");
00559         szCreationDate = NULL;
00560         szCreator = NULL;
00561 } /* end of vEpiloguePS */
00562 
00563 /*
00564  * vPrintPalette - print a postscript palette
00565  */
00566 static void
00567 vPrintPalette(FILE *pOutFile, const imagedata_type *pImg)
00568 {
00569         int     iIndex;
00570 
00571         fail(pOutFile == NULL);
00572         fail(pImg == NULL);
00573         fail(pImg->iColorsUsed < 2);
00574         fail(pImg->iColorsUsed > 256);
00575 
00576         fprintf(pOutFile, "[ /Indexed\n");
00577         fprintf(pOutFile, "\t/Device%s %d\n",
00578                 pImg->bColorImage ? "RGB" : "Gray", pImg->iColorsUsed - 1);
00579         fprintf(pOutFile, "<");
00580         for (iIndex = 0; iIndex < pImg->iColorsUsed; iIndex++) {
00581                 fprintf(pOutFile, "%02x",
00582                                 (unsigned int)pImg->aucPalette[iIndex][0]);
00583                 if (pImg->bColorImage) {
00584                         fprintf(pOutFile, "%02x%02x",
00585                                 (unsigned int)pImg->aucPalette[iIndex][1],
00586                                 (unsigned int)pImg->aucPalette[iIndex][2]);
00587                 }
00588                 if (iIndex % 8 == 7) {
00589                         fprintf(pOutFile, "\n");
00590                 } else {
00591                         fprintf(pOutFile, " ");
00592                 }
00593         }
00594         fprintf(pOutFile, ">\n");
00595         fprintf(pOutFile, "] setcolorspace\n");
00596 } /* end of vPrintPalette */
00597 
00598 /*
00599  * vImageProloguePS - perform the Encapsulated PostScript initialization
00600  */
00601 void
00602 vImageProloguePS(diagram_type *pDiag, const imagedata_type *pImg)
00603 {
00604         FILE    *pOutFile;
00605 
00606         fail(pDiag == NULL);
00607         fail(pDiag->pOutFile == NULL);
00608         fail(pImg == NULL);
00609 
00610         if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) {
00611                 return;
00612         }
00613 
00614         fail(szCreationDate == NULL);
00615         fail(szCreator == NULL);
00616         fail(eImageLevel == level_no_images);
00617 
00618         iImageCount++;
00619 
00620         DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);
00621 
00622         pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled);
00623         vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled));
00624 
00625         pOutFile = pDiag->pOutFile;
00626 
00627         fprintf(pOutFile, "BeginEPSF\n");
00628         fprintf(pOutFile, "%%%%BeginDocument: image%03d.eps\n", iImageCount);
00629         fprintf(pOutFile, "%%!PS-Adobe-2.0 EPSF-2.0\n");
00630         fprintf(pOutFile, "%%%%Creator: %s %s\n", szCreator, VERSIONSTRING);
00631         fprintf(pOutFile, "%%%%Title: Image %03d\n", iImageCount);
00632         fprintf(pOutFile, "%%%%CreationDate: %s", szCreationDate);
00633         fprintf(pOutFile, "%%%%BoundingBox: 0 0 %d %d\n",
00634                                 pImg->iHorSizeScaled, pImg->iVerSizeScaled);
00635         fprintf(pOutFile, "%%%%DocumentData: Clean7Bit\n");
00636         fprintf(pOutFile, "%%%%LanguageLevel: 2\n");
00637         fprintf(pOutFile, "%%%%EndComments\n");
00638         fprintf(pOutFile, "%%%%BeginProlog\n");
00639         fprintf(pOutFile, "%%%%EndProlog\n");
00640         fprintf(pOutFile, "%%%%Page: 1 1\n");
00641 
00642         fprintf(pOutFile, "save\n");
00643 
00644         switch (pImg->eImageType) {
00645         case imagetype_is_jpeg:
00646                 fprintf(pOutFile, "/Data1 currentfile ");
00647                 fprintf(pOutFile, "/ASCII85Decode filter def\n");
00648                 fprintf(pOutFile, "/Data Data1 << ");
00649                 fprintf(pOutFile, ">> /DCTDecode filter def\n");
00650                 switch (pImg->iComponents) {
00651                 case 1:
00652                         fprintf(pOutFile, "/DeviceGray setcolorspace\n");
00653                         break;
00654                 case 3:
00655                         fprintf(pOutFile, "/DeviceRGB setcolorspace\n");
00656                         break;
00657                 case 4:
00658                         fprintf(pOutFile, "/DeviceCMYK setcolorspace\n");
00659                         break;
00660                 default:
00661                         DBG_DEC(pImg->iComponents);
00662                         break;
00663                 }
00664                 break;
00665         case imagetype_is_png:
00666                 if (eImageLevel == level_gs_special) {
00667                         fprintf(pOutFile,
00668                         "/Data2 currentfile /ASCII85Decode filter def\n");
00669                         fprintf(pOutFile,
00670                         "/Data1 Data2 << >> /FlateDecode filter def\n");
00671                         fprintf(pOutFile, "/Data Data1 <<\n");
00672                         fprintf(pOutFile, "\t/Colors %d\n", pImg->iComponents);
00673                         fprintf(pOutFile, "\t/BitsPerComponent %u\n",
00674                                                 pImg->uiBitsPerComponent);
00675                         fprintf(pOutFile, "\t/Columns %d\n", pImg->iWidth);
00676                         fprintf(pOutFile,
00677                                 ">> /PNGPredictorDecode filter def\n");
00678                 } else {
00679                         fprintf(pOutFile,
00680                         "/Data1 currentfile /ASCII85Decode filter def\n");
00681                         fprintf(pOutFile,
00682                         "/Data Data1 << >> /FlateDecode filter def\n");
00683                 }
00684                 if (pImg->iComponents == 3 || pImg->iComponents == 4) {
00685                         fprintf(pOutFile, "/DeviceRGB setcolorspace\n");
00686                 } else if (pImg->iColorsUsed > 0) {
00687                         vPrintPalette(pOutFile, pImg);
00688                 } else {
00689                         fprintf(pOutFile, "/DeviceGray setcolorspace\n");
00690                 }
00691                 break;
00692         case imagetype_is_dib:
00693                 fprintf(pOutFile, "/Data currentfile ");
00694                 fprintf(pOutFile, "/ASCII85Decode filter def\n");
00695                 if (pImg->uiBitsPerComponent <= 8) {
00696                         vPrintPalette(pOutFile, pImg);
00697                 } else {
00698                         fprintf(pOutFile, "/DeviceRGB setcolorspace\n");
00699                 }
00700                 break;
00701         default:
00702                 fprintf(pOutFile, "/Data currentfile ");
00703                 fprintf(pOutFile, "/ASCIIHexDecode filter def\n");
00704                 fprintf(pOutFile, "/Device%s setcolorspace\n",
00705                         pImg->bColorImage ? "RGB" : "Gray");
00706                 break;
00707         }
00708 
00709         /* Translate to lower left corner of image */
00710         fprintf(pOutFile, "%.2f %.2f translate\n",
00711                         dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN),
00712                         dDrawUnits2Points(pDiag->lYtop));
00713 
00714         fprintf(pOutFile, "%d %d scale\n",
00715                                 pImg->iHorSizeScaled, pImg->iVerSizeScaled);
00716 
00717         fprintf(pOutFile, "{ <<\n");
00718         fprintf(pOutFile, "\t/ImageType 1\n");
00719         fprintf(pOutFile, "\t/Width %d\n", pImg->iWidth);
00720         fprintf(pOutFile, "\t/Height %d\n", pImg->iHeight);
00721         if (pImg->eImageType == imagetype_is_dib) {
00722                 /* Scanning from left to right and bottom to top */
00723                 fprintf(pOutFile, "\t/ImageMatrix [ %d 0 0 %d 0 0 ]\n",
00724                         pImg->iWidth, pImg->iHeight);
00725         } else {
00726                 /* Scanning from left to right and top to bottom */
00727                 fprintf(pOutFile, "\t/ImageMatrix [ %d 0 0 %d 0 %d ]\n",
00728                         pImg->iWidth, -pImg->iHeight, pImg->iHeight);
00729         }
00730         fprintf(pOutFile, "\t/DataSource Data\n");
00731 
00732         switch (pImg->eImageType) {
00733         case imagetype_is_jpeg:
00734                 fprintf(pOutFile, "\t/BitsPerComponent 8\n");
00735                 switch (pImg->iComponents) {
00736                 case 1:
00737                         fprintf(pOutFile, "\t/Decode [0 1]\n");
00738                         break;
00739                 case 3:
00740                         fprintf(pOutFile, "\t/Decode [0 1 0 1 0 1]\n");
00741                         break;
00742                 case 4:
00743                         if (pImg->bAdobe) {
00744                                 /*
00745                                  * Adobe-conforming CMYK file
00746                                  * applying workaround for color inversion
00747                                  */
00748                                 fprintf(pOutFile,
00749                                         "\t/Decode [1 0 1 0 1 0 1 0]\n");
00750                         } else {
00751                                 fprintf(pOutFile,
00752                                         "\t/Decode [0 1 0 1 0 1 0 1]\n");
00753                         }
00754                         break;
00755                 default:
00756                         DBG_DEC(pImg->iComponents);
00757                         break;
00758                 }
00759                 break;
00760         case imagetype_is_png:
00761                 if (pImg->iComponents == 3) {
00762                         fprintf(pOutFile, "\t/BitsPerComponent 8\n");
00763                         fprintf(pOutFile, "\t/Decode [0 1 0 1 0 1]\n");
00764                 } else if (pImg->iColorsUsed > 0) {
00765                         fail(pImg->uiBitsPerComponent > 8);
00766                         fprintf(pOutFile, "\t/BitsPerComponent %u\n",
00767                                         pImg->uiBitsPerComponent);
00768                         fprintf(pOutFile, "\t/Decode [0 %d]\n",
00769                                         (1 << pImg->uiBitsPerComponent) - 1);
00770                 } else {
00771                         fprintf(pOutFile, "\t/BitsPerComponent 8\n");
00772                         fprintf(pOutFile, "\t/Decode [0 1]\n");
00773                 }
00774                 break;
00775         case imagetype_is_dib:
00776                 fprintf(pOutFile, "\t/BitsPerComponent 8\n");
00777                 if (pImg->uiBitsPerComponent <= 8) {
00778                         fprintf(pOutFile, "\t/Decode [0 255]\n");
00779                 } else {
00780                         fprintf(pOutFile, "\t/Decode [0 1 0 1 0 1]\n");
00781                 }
00782                 break;
00783         default:
00784                 fprintf(pOutFile, "\t/BitsPerComponent 8\n");
00785                 if (pImg->bColorImage) {
00786                         fprintf(pOutFile, "\t/Decode [0 1 0 1 0 1]\n");
00787                 } else {
00788                         fprintf(pOutFile, "\t/Decode [0 1]\n");
00789                 }
00790                 break;
00791         }
00792 
00793         fprintf(pOutFile, "  >> image\n");
00794         fprintf(pOutFile, "  Data closefile\n");
00795         fprintf(pOutFile, "  showpage\n");
00796         fprintf(pOutFile, "  restore\n");
00797         fprintf(pOutFile, "} exec\n");
00798 } /* end of vImageProloguePS */
00799 
00800 /*
00801  * vImageEpiloguePS - clean up after Encapsulated PostScript
00802  */
00803 void
00804 vImageEpiloguePS(diagram_type *pDiag)
00805 {
00806         FILE    *pOutFile;
00807 
00808         fail(pDiag == NULL);
00809         fail(pDiag->pOutFile == NULL);
00810 
00811         pOutFile = pDiag->pOutFile;
00812 
00813         fprintf(pOutFile, "%%%%EOF\n");
00814         fprintf(pOutFile, "%%%%EndDocument\n");
00815         fprintf(pOutFile, "EndEPSF\n");
00816 
00817         pDiag->lXleft = 0;
00818 } /* end of vImageEpiloguePS */
00819 
00820 /*
00821  * bAddDummyImagePS - add a dummy image
00822  *
00823  * return TRUE when successful, otherwise FALSE
00824  */
00825 BOOL
00826 bAddDummyImagePS(diagram_type *pDiag, const imagedata_type *pImg)
00827 {
00828         FILE    *pOutFile;
00829 
00830         fail(pDiag == NULL);
00831         fail(pDiag->pOutFile == NULL);
00832         fail(pImg == NULL);
00833 
00834         if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) {
00835                 return FALSE;
00836         }
00837 
00838         iImageCount++;
00839 
00840         DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft);
00841 
00842         pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled);
00843         vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled));
00844 
00845         pOutFile = pDiag->pOutFile;
00846 
00847         fprintf(pOutFile, "gsave %% Image %03d\n", iImageCount);
00848         fprintf(pOutFile, "\tnewpath\n");
00849         fprintf(pOutFile, "\t%.2f %.2f moveto\n",
00850                         dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN),
00851                         dDrawUnits2Points(pDiag->lYtop));
00852         fprintf(pOutFile, "\t1.0 setlinewidth\n");
00853         fprintf(pOutFile, "\t0.3 setgray\n");
00854         fprintf(pOutFile, "\t0 %d rlineto\n", pImg->iVerSizeScaled);
00855         fprintf(pOutFile, "\t%d 0 rlineto\n", pImg->iHorSizeScaled);
00856         fprintf(pOutFile, "\t0 %d rlineto\n", -pImg->iVerSizeScaled);
00857         fprintf(pOutFile, "\tclosepath\n");
00858         fprintf(pOutFile, "\tstroke\n");
00859         fprintf(pOutFile, "grestore\n");
00860 
00861         pDiag->lXleft = 0;
00862 
00863         return TRUE;
00864 } /* end of bAddDummyImagePS */
00865 
00866 /*
00867  * vAddFontsPS - add the list of fonts and complete the prologue
00868  */
00869 void
00870 vAddFontsPS(diagram_type *pDiag)
00871 {
00872         FILE    *pOutFile;
00873         const font_table_type *pTmp, *pTmp2;
00874         size_t  tIndex;
00875         int     iLineLen, iOurFontnameLen;
00876         BOOL    bFound;
00877 
00878         fail(pDiag == NULL);
00879         fail(pDiag->pOutFile == NULL);
00880 
00881         pOutFile = pDiag->pOutFile;
00882         iLineLen = fprintf(pOutFile, "%%%%DocumentFonts:");
00883 
00884         if (tGetFontTableLength() == 0) {
00885                 iLineLen += fprintf(pOutFile, " Courier");
00886         } else {
00887                 pTmp = NULL;
00888                 while ((pTmp = pGetNextFontTableRecord(pTmp)) != NULL) {
00889                         /* Print the document fonts */
00890                         bFound = FALSE;
00891                         pTmp2 = NULL;
00892                         while ((pTmp2 = pGetNextFontTableRecord(pTmp2))
00893                                         != NULL && pTmp2 < pTmp) {
00894                                 bFound = STREQ(pTmp2->szOurFontname,
00895                                                 pTmp->szOurFontname);
00896                                 if (bFound) {
00897                                         break;
00898                                 }
00899                         }
00900                         iOurFontnameLen = (int)strlen(pTmp->szOurFontname);
00901                         if (bFound || iOurFontnameLen <= 0) {
00902                                 continue;
00903                         }
00904                         if (iLineLen + iOurFontnameLen > 76) {
00905                                 fprintf(pOutFile, "\n%%%%+");
00906                                 iLineLen = 3;
00907                         }
00908                         iLineLen += fprintf(pOutFile,
00909                                         " %s", pTmp->szOurFontname);
00910                 }
00911         }
00912         fprintf(pOutFile, "\n");
00913         fprintf(pOutFile, "%%%%Pages: (atend)\n");
00914         fprintf(pOutFile, "%%%%EndComments\n");
00915         fprintf(pOutFile, "%%%%BeginProlog\n");
00916 
00917         switch (eEncoding) {
00918         case encoding_latin_1:
00919                 for (tIndex = 0;
00920                      tIndex < elementsof(iso_8859_1_data);
00921                      tIndex++) {
00922                         fprintf(pOutFile, "%s\n", iso_8859_1_data[tIndex]);
00923                 }
00924                 fprintf(pOutFile, "\n");
00925                 for (tIndex = 0;
00926                      tIndex < elementsof(iso_8859_x_func);
00927                      tIndex++) {
00928                         fprintf(pOutFile, "%s\n", iso_8859_x_func[tIndex]);
00929                 }
00930                 break;
00931         case encoding_latin_2:
00932                 for (tIndex = 0;
00933                      tIndex < elementsof(iso_8859_2_data);
00934                      tIndex++) {
00935                         fprintf(pOutFile, "%s\n", iso_8859_2_data[tIndex]);
00936                 }
00937                 fprintf(pOutFile, "\n");
00938                 for (tIndex = 0;
00939                      tIndex < elementsof(iso_8859_x_func);
00940                      tIndex++) {
00941                         fprintf(pOutFile, "%s\n", iso_8859_x_func[tIndex]);
00942                 }
00943                 break;
00944         case encoding_cyrillic:
00945                 for (tIndex = 0;
00946                      tIndex < elementsof(iso_8859_5_data);
00947                      tIndex++) {
00948                         fprintf(pOutFile, "%s\n", iso_8859_5_data[tIndex]);
00949                 }
00950                 fprintf(pOutFile, "\n");
00951                 for (tIndex = 0;
00952                      tIndex < elementsof(iso_8859_x_func);
00953                      tIndex++) {
00954                         fprintf(pOutFile, "%s\n", iso_8859_x_func[tIndex]);
00955                 }
00956                 break;
00957         case encoding_utf_8:
00958                 werr(1,
00959                 "The combination PostScript and UTF-8 is not supported");
00960                 break;
00961         default:
00962                 DBG_DEC(eEncoding);
00963                 break;
00964         }
00965 
00966         /* The rest of the functions */
00967         for (tIndex = 0; tIndex < elementsof(misc_func); tIndex++) {
00968                 fprintf(pOutFile, "%s\n", misc_func[tIndex]);
00969         }
00970         fprintf(pOutFile, "%%%%EndProlog\n");
00971         iPageCount = 1;
00972         fprintf(pDiag->pOutFile, "%%%%Page: %d %d\n", iPageCount, iPageCount);
00973         vAddPageSetup(pDiag->pOutFile);
00974         vAddHeader(pDiag);
00975 } /* end of vAddFontsPS */
00976 
00977 /*
00978  * vPrintPS - print a PostScript string
00979  */
00980 static void
00981 vPrintPS(FILE *pFile, const char *szString, size_t tStringLength,
00982                 USHORT usFontstyle)
00983 {
00984         double          dSuperscriptMove, dSubscriptMove;
00985         const UCHAR     *ucBytes;
00986         size_t          tCount;
00987 
00988         fail(szString == NULL);
00989 
00990         if (szString == NULL || szString[0] == '\0' || tStringLength == 0) {
00991                 return;
00992         }
00993         DBG_DEC_C(usFontSizeCurr < MIN_FONT_SIZE, usFontSizeCurr);
00994 
00995         dSuperscriptMove = 0.0;
00996         dSubscriptMove = 0.0;
00997 
00998         /* Up for superscript */
00999         if (bIsSuperscript(usFontstyle) && usFontSizeCurr != 0) {
01000                 dSuperscriptMove = (double)((usFontSizeCurr + 1) / 2) * 0.375;
01001                 fprintf(pFile, "0 %.2f rmoveto\n", dSuperscriptMove);
01002         }
01003 
01004         /* Down for subscript */
01005         if (bIsSubscript(usFontstyle) && usFontSizeCurr != 0) {
01006                 dSubscriptMove = (double)usFontSizeCurr * 0.125;
01007                 fprintf(pFile, "0 %.2f rmoveto\n", -dSubscriptMove);
01008         }
01009 
01010         /* Generate and print the PostScript output */
01011         ucBytes = (UCHAR *)szString;
01012         (void)putc('(', pFile);
01013         for (tCount = 0; tCount < tStringLength ; tCount++) {
01014                 switch (ucBytes[tCount]) {
01015                 case '(':
01016                 case ')':
01017                 case '\\':
01018                         (void)putc('\\', pFile);
01019                         (void)putc(szString[tCount], pFile);
01020                         break;
01021                 default:
01022                         if (ucBytes[tCount] < 0x20 ||
01023                             (ucBytes[tCount] >= 0x7f &&
01024                              ucBytes[tCount] < 0x8c)) {
01025                                 DBG_HEX(ucBytes[tCount]);
01026                                 (void)putc(' ', pFile);
01027                         } else if (ucBytes[tCount] >= 0x80) {
01028                                 fprintf(pFile, "\\%03o", (UINT)ucBytes[tCount]);
01029                         } else {
01030                                 (void)putc(szString[tCount], pFile);
01031                         }
01032                         break;
01033                 }
01034         }
01035         fprintf(pFile, ") ");
01036         if ((bIsStrike(usFontstyle) || bIsMarkDel(usFontstyle)) &&
01037                         usFontSizeCurr != 0) {
01038                 fprintf(pFile, "%.2f %.2f LineShow\n",
01039                         (double)usFontSizeCurr * 0.02,
01040                         (double)usFontSizeCurr * 0.12);
01041         } else if (bIsUnderline(usFontstyle) && usFontSizeCurr != 0) {
01042                 fprintf(pFile, "%.2f %.2f LineShow\n",
01043                         (double)usFontSizeCurr * 0.02,
01044                         (double)usFontSizeCurr * -0.06);
01045         } else {
01046                 fprintf(pFile, "show\n");
01047         }
01048 
01049         /* Undo the superscript move */
01050         if (bIsSuperscript(usFontstyle) && usFontSizeCurr != 0) {
01051                 fprintf(pFile, "0 %.2f rmoveto\n", -dSuperscriptMove);
01052         }
01053 
01054         /* Undo the subscript move */
01055         if (bIsSubscript(usFontstyle) && usFontSizeCurr != 0) {
01056                 fprintf(pFile, "0 %.2f rmoveto\n", dSubscriptMove);
01057         }
01058 } /* end of vPrintPS */
01059 
01060 /*
01061  * vSetColor - move to the specified color
01062  */
01063 static void
01064 vSetColor(FILE *pFile, UCHAR ucFontColor)
01065 {
01066         ULONG   ulTmp, ulRed, ulGreen, ulBlue;
01067 
01068         ulTmp = ulColor2Color(ucFontColor);
01069         ulRed   = (ulTmp & 0x0000ff00) >> 8;
01070         ulGreen = (ulTmp & 0x00ff0000) >> 16;
01071         ulBlue  = (ulTmp & 0xff000000) >> 24;
01072         fprintf(pFile, "%.3f %.3f %.3f setrgbcolor\n",
01073                                 ulRed / 255.0, ulGreen / 255.0, ulBlue / 255.0);
01074 } /* end of vSetColor */
01075 
01076 /*
01077  * vMove2NextLinePS - move to the next line
01078  */
01079 void
01080 vMove2NextLinePS(diagram_type *pDiag, USHORT usFontSize)
01081 {
01082         fail(pDiag == NULL);
01083         fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
01084 
01085         pDiag->lYtop -= lComputeLeading(usFontSize);
01086 } /* end of vMove2NextLinePS */
01087 
01088 /*
01089  * vSubstringPS - print a sub string
01090  */
01091 void
01092 vSubstringPS(diagram_type *pDiag,
01093         char *szString, size_t tStringLength, long lStringWidth,
01094         UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef,
01095         USHORT usFontSize, USHORT usMaxFontSize)
01096 {
01097         const char      *szOurFontname;
01098 
01099         fail(pDiag == NULL || szString == NULL);
01100         fail(pDiag->pOutFile == NULL);
01101         fail(pDiag->lXleft < 0);
01102         fail(tStringLength != strlen(szString));
01103         fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
01104         fail(usMaxFontSize < MIN_FONT_SIZE || usMaxFontSize > MAX_FONT_SIZE);
01105         fail(usFontSize > usMaxFontSize);
01106 
01107         if (szString[0] == '\0' || tStringLength == 0) {
01108                 return;
01109         }
01110 
01111         if (tFontRef != tFontRefCurr || usFontSize != usFontSizeCurr) {
01112                 szOurFontname = szGetFontname(tFontRef);
01113                 fail(szOurFontname == NULL);
01114                 fprintf(pDiag->pOutFile,
01115                         "%.1f /%s /%s-ISO-8859-x ChgFnt\n",
01116                         (double)usFontSize / 2.0,
01117                         szOurFontname, szOurFontname);
01118                 tFontRefCurr = tFontRef;
01119                 usFontSizeCurr = usFontSize;
01120         }
01121         if ((int)ucFontColor != iFontColorCurr) {
01122                 vSetColor(pDiag->pOutFile, ucFontColor);
01123                 iFontColorCurr = (int)ucFontColor;
01124         }
01125         vMoveTo(pDiag, lComputeLeading(usMaxFontSize));
01126         vPrintPS(pDiag->pOutFile, szString, tStringLength, usFontstyle);
01127         pDiag->lXleft += lStringWidth;
01128 } /* end of vSubstringPS */
01129 
01130 /*
01131  * Create an start of paragraph by moving the y-top mark
01132  */
01133 void
01134 vStartOfParagraphPS(diagram_type *pDiag, long lBeforeIndentation)
01135 {
01136         fail(pDiag == NULL);
01137         fail(lBeforeIndentation < 0);
01138 
01139         pDiag->lXleft = 0;
01140         pDiag->lYtop -= lMilliPoints2DrawUnits(lBeforeIndentation);
01141 } /* end of vStartOfParagraphPS */
01142 
01143 /*
01144  * Create an end of paragraph by moving the y-top mark
01145  */
01146 void
01147 vEndOfParagraphPS(diagram_type *pDiag,
01148         USHORT usFontSize, long lAfterIndentation)
01149 {
01150         fail(pDiag == NULL);
01151         fail(pDiag->pOutFile == NULL);
01152         fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
01153         fail(lAfterIndentation < 0);
01154 
01155         if (pDiag->lXleft > 0) {
01156                 /* To the start of the line */
01157                 vMove2NextLinePS(pDiag, usFontSize);
01158         }
01159 
01160         pDiag->lXleft = 0;
01161         pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation);
01162 } /* end of vEndOfParagraphPS */
01163 
01164 /*
01165  * Create an end of page
01166  */
01167 void
01168 vEndOfPagePS(diagram_type *pDiag, BOOL bNewSection)
01169 {
01170         vMove2NextPage(pDiag, bNewSection);
01171 } /* end of vEndOfPagePS */

Generated by  doxygen 1.6.2