00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
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
00024 static encoding_type eEncoding = encoding_neutral;
00025
00026 static image_level_enum eImageLevel = level_default;
00027
00028 static BOOL bUseLandscape = FALSE;
00029
00030 static long lPageHeight = LONG_MAX;
00031 static long lPageWidth = LONG_MAX;
00032
00033 static long lFooterHeight = 0;
00034
00035 static BOOL bInFtrSpace = FALSE;
00036
00037 static const char *szCreationDate = NULL;
00038
00039 static const char *szCreator = NULL;
00040
00041 static drawfile_fontref tFontRefCurr = (drawfile_fontref)-1;
00042 static USHORT usFontSizeCurr = 0;
00043 static int iFontColorCurr = -1;
00044
00045 static long lYtopCurr = -1;
00046
00047 static int iPageCount = 0;
00048
00049 static int iImageCount = 0;
00050
00051 static int iSectionIndex = 0;
00052
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
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 }
00231
00232
00233
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
00269 pPrev = pNext->pPrev;
00270 fail(pPrev->pNext != pNext);
00271
00272 pPrev->pNext = NULL;
00273 if (bOutputContainsText(pStart)) {
00274
00275 vAlign2Window(pDiag, pStart,
00276 lChar2MilliPoints(DEFAULT_SCREEN_WIDTH),
00277 ALIGNMENT_LEFT);
00278 } else {
00279
00280 vMove2NextLinePS(pDiag, pStart->usFontSize);
00281 }
00282
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 }
00292
00293
00294
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
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
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 }
00342
00343
00344
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
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
00384
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
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 }
00404
00405
00406
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 }
00426
00427
00428
00429
00430
00431
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
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 }
00456
00457
00458
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 }
00542
00543
00544
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 }
00562
00563
00564
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 }
00597
00598
00599
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
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
00723 fprintf(pOutFile, "\t/ImageMatrix [ %d 0 0 %d 0 0 ]\n",
00724 pImg->iWidth, pImg->iHeight);
00725 } else {
00726
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
00746
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 }
00799
00800
00801
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 }
00819
00820
00821
00822
00823
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 }
00865
00866
00867
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
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
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 }
00976
00977
00978
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
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
01005 if (bIsSubscript(usFontstyle) && usFontSizeCurr != 0) {
01006 dSubscriptMove = (double)usFontSizeCurr * 0.125;
01007 fprintf(pFile, "0 %.2f rmoveto\n", -dSubscriptMove);
01008 }
01009
01010
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
01050 if (bIsSuperscript(usFontstyle) && usFontSizeCurr != 0) {
01051 fprintf(pFile, "0 %.2f rmoveto\n", -dSuperscriptMove);
01052 }
01053
01054
01055 if (bIsSubscript(usFontstyle) && usFontSizeCurr != 0) {
01056 fprintf(pFile, "0 %.2f rmoveto\n", dSubscriptMove);
01057 }
01058 }
01059
01060
01061
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 }
01075
01076
01077
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 }
01087
01088
01089
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 }
01129
01130
01131
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 }
01142
01143
01144
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
01157 vMove2NextLinePS(pDiag, usFontSize);
01158 }
01159
01160 pDiag->lXleft = 0;
01161 pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation);
01162 }
01163
01164
01165
01166
01167 void
01168 vEndOfPagePS(diagram_type *pDiag, BOOL bNewSection)
01169 {
01170 vMove2NextPage(pDiag, bNewSection);
01171 }