diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/pdf_8c_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/pdf_8c_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,1164 @@ + + +
+ +00001 /* +00002 * pdf.c +00003 * Copyright (C) 2003-2005 A.J. van Os; Released under GNU GPL +00004 * +00005 * Description: +00006 * Functions to deal with the Adobe Portable Document Format (pdf) +00007 * +00008 */ +00009 +00010 #include <stdarg.h> +00011 #include <string.h> +00012 #include "version.h" +00013 #include "antiword.h" +00014 +00015 +00016 /* Constants for the file positions */ +00017 #define INITIAL_LOCATION_SIZE 20 +00018 #define INITIAL_PAGEOBJECT_SIZE 5 +00019 #if defined(DEBUG) +00020 #define EXTENSION_ARRAY_SIZE 10 +00021 #else +00022 #define EXTENSION_ARRAY_SIZE 30 +00023 #endif /* DEBUG */ +00024 +00025 /* The character set */ +00026 static encoding_type eEncoding = encoding_neutral; +00027 /* Current creator for a PDF header */ +00028 static const char *szProducer = NULL; +00029 /* The height and width of a PDF 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 font information */ +00037 static drawfile_fontref tFontRefCurr = (drawfile_fontref)-1; +00038 static USHORT usFontSizeCurr = 0; +00039 static int iFontColorCurr = -1; +00040 /* Current vertical position information */ +00041 static long lYtopCurr = -1; +00042 /* Image counter */ +00043 static int iImageCount = 0; +00044 /* Section index */ +00045 static int iSectionIndex = 0; +00046 /* Are we on the first page of the section? */ +00047 static BOOL bFirstInSection = TRUE; +00048 /* File positions */ +00049 static long lFilePosition = 0; +00050 static long *alLocation = NULL; +00051 static size_t tLocations = 0; +00052 static int iMaxLocationNumber = 0; +00053 /* File position at the start of a page */ +00054 static long lStreamStart = -1; +00055 /* Page objects */ +00056 static int *aiPageObject = NULL; +00057 static int iPageCount = 0; +00058 static size_t tMaxPageObjects = 0; +00059 /* Current object number */ +00060 /* 1 = root; 2 = info; 3 = pages; 4 = encoding; 5-16 = fonts; 17 = resources */ +00061 static int iObjectNumberCurr = 17; +00062 +00063 static void vMoveTo(diagram_type *, long); +00064 +00065 static const struct { +00066 const char *szPDFname; +00067 const char *szPSname; +00068 } atFontname[] = { +00069 { "Courier", FONT_MONOSPACED_PLAIN }, +00070 { "Courier-Bold", FONT_MONOSPACED_BOLD }, +00071 { "Courier-Oblique", FONT_MONOSPACED_ITALIC }, +00072 { "Courier-BoldOblique", FONT_MONOSPACED_BOLDITALIC }, +00073 { "Helvetica", FONT_SANS_SERIF_PLAIN }, +00074 { "Helvetica-Bold", FONT_SANS_SERIF_BOLD }, +00075 { "Helvetica-Oblique", FONT_SANS_SERIF_ITALIC }, +00076 { "Helvetica-BoldOblique", FONT_SANS_SERIF_BOLDITALIC }, +00077 { "Times-Roman", FONT_SERIF_PLAIN }, +00078 { "Times-Bold", FONT_SERIF_BOLD }, +00079 { "Times-Italic", FONT_SERIF_ITALIC }, +00080 { "Times-BoldItalic", FONT_SERIF_BOLDITALIC }, +00081 }; +00082 +00083 static const char *iso_8859_1[] = { +00084 "128 /Euro", +00085 "140 /ellipsis /trademark /perthousand /bullet", +00086 " /quoteleft /quoteright /guilsinglleft /guilsinglright", +00087 " /quotedblleft /quotedblright /quotedblbase /endash /emdash", +00088 " /minus /OE /oe /dagger /daggerdbl /fi /fl", +00089 "160 /space /exclamdown /cent /sterling /currency", +00090 " /yen /brokenbar /section /dieresis /copyright", +00091 " /ordfeminine /guillemotleft /logicalnot /hyphen /registered", +00092 " /macron /degree /plusminus /twosuperior /threesuperior", +00093 " /acute /mu /paragraph /periodcentered /cedilla", +00094 " /onesuperior /ordmasculine /guillemotright /onequarter", +00095 " /onehalf /threequarters /questiondown /Agrave /Aacute", +00096 " /Acircumflex /Atilde /Adieresis /Aring /AE /Ccedilla", +00097 " /Egrave /Eacute /Ecircumflex /Edieresis /Igrave /Iacute", +00098 " /Icircumflex /Idieresis /Eth /Ntilde /Ograve /Oacute", +00099 " /Ocircumflex /Otilde /Odieresis /multiply /Oslash", +00100 " /Ugrave /Uacute /Ucircumflex /Udieresis /Yacute /Thorn", +00101 " /germandbls /agrave /aacute /acircumflex /atilde", +00102 " /adieresis /aring /ae /ccedilla /egrave /eacute", +00103 " /ecircumflex /edieresis /igrave /iacute /icircumflex", +00104 " /idieresis /eth /ntilde /ograve /oacute /ocircumflex", +00105 " /otilde /odieresis /divide /oslash /ugrave /uacute", +00106 " /ucircumflex /udieresis /yacute /thorn /ydieresis", +00107 }; +00108 +00109 static const char *iso_8859_2[] = { +00110 "160 /space /Aogonek /breve /Lslash /currency /Lcaron", +00111 " /Sacute /section /dieresis /Scaron /Scommaaccent", +00112 " /Tcaron /Zacute /hyphen /Zcaron /Zdotaccent /degree", +00113 " /aogonek /ogonek /lslash /acute /lcaron /sacute", +00114 " /caron /cedilla /scaron /scommaaccent /tcaron", +00115 " /zacute /hungarumlaut /zcaron /zdotaccent /Racute", +00116 " /Aacute /Acircumflex /Abreve /Adieresis /Lacute", +00117 " /Cacute /Ccedilla /Ccaron /Eacute /Eogonek", +00118 " /Edieresis /Ecaron /Iacute /Icircumflex /Dcaron", +00119 " /.notdef /Nacute /Ncaron /Oacute /Ocircumflex", +00120 " /Ohungarumlaut /Odieresis /multiply /Rcaron /Uring", +00121 " /Uacute /Uhungarumlaut /Udieresis /Yacute /Tcommaaccent", +00122 " /germandbls /racute /aacute /acircumflex /abreve", +00123 " /adieresis /lacute /cacute /ccedilla /ccaron /eacute", +00124 " /eogonek /edieresis /ecaron /iacute /icircumflex", +00125 " /dcaron /.notdef /nacute /ncaron /oacute /ocircumflex", +00126 " /ohungarumlaut /odieresis /divide /rcaron /uring", +00127 " /uacute /uhungarumlaut /udieresis /yacute /tcommaaccent", +00128 " /dotaccent", +00129 }; +00130 +00131 +00132 /* +00133 * tGetFontIndex - get the font index +00134 */ +00135 static size_t +00136 tGetFontIndex(drawfile_fontref tFontRef) +00137 { +00138 const char *szFontname; +00139 size_t tIndex; +00140 +00141 /* Get the font name */ +00142 szFontname = szGetFontname(tFontRef); +00143 fail(szFontname == NULL); +00144 if (szFontname == NULL) { +00145 return 0; +00146 } +00147 +00148 /* Find the name in the table */ +00149 for (tIndex = 0; tIndex < elementsof(atFontname); tIndex++) { +00150 if (STRCEQ(atFontname[tIndex].szPSname, szFontname)) { +00151 return tIndex; +00152 } +00153 } +00154 /* Not found */ +00155 DBG_DEC(tFontRef); +00156 DBG_MSG(szFontname); +00157 return 0; +00158 } /* end of tGetFontIndex */ +00159 +00160 /* +00161 * vSetLocation - store the location of objects +00162 */ +00163 static void +00164 vSetLocation(int iLocationNumber) +00165 { +00166 fail(iLocationNumber <= 0); +00167 +00168 if ((size_t)iLocationNumber >= tLocations) { +00169 /* Extend and set to zero */ +00170 tLocations += EXTENSION_ARRAY_SIZE; +00171 alLocation = xrealloc(alLocation, tLocations * sizeof(long)); +00172 memset(alLocation + tLocations - EXTENSION_ARRAY_SIZE, +00173 0, +00174 EXTENSION_ARRAY_SIZE * sizeof(long)); +00175 DBG_DEC(tLocations); +00176 } +00177 if (iLocationNumber > iMaxLocationNumber) { +00178 iMaxLocationNumber = iLocationNumber; +00179 } +00180 +00181 DBG_DEC_C((size_t)iLocationNumber >= tLocations, iLocationNumber); +00182 DBG_DEC_C((size_t)iLocationNumber >= tLocations, tLocations); +00183 fail((size_t)iLocationNumber >= tLocations); +00184 +00185 alLocation[iLocationNumber] = lFilePosition; +00186 } /* end of vSetLocation */ +00187 +00188 /* +00189 * vFillNextPageObject - fil the next page object with the current object number +00190 */ +00191 static void +00192 vFillNextPageObject(void) +00193 { +00194 iPageCount++; +00195 if ((size_t)iPageCount >= tMaxPageObjects) { +00196 /* Extend the array */ +00197 tMaxPageObjects += EXTENSION_ARRAY_SIZE; +00198 aiPageObject = xrealloc(aiPageObject, +00199 tMaxPageObjects * sizeof(int)); +00200 DBG_DEC(tMaxPageObjects); +00201 } +00202 aiPageObject[iPageCount] = iObjectNumberCurr; +00203 } /* end of vFillNextPageObject */ +00204 +00205 /* +00206 * vFPprintf - printf and update the fileposition +00207 * +00208 * called with arguments like fprintf(3) +00209 */ +00210 static void +00211 vFPprintf(FILE *pOutFile, const char *szFormat, ...) +00212 { +00213 va_list tArg; +00214 +00215 va_start(tArg, szFormat); +00216 lFilePosition += vfprintf(pOutFile, szFormat, tArg); +00217 va_end(tArg); +00218 } /* end of vFPprintf */ +00219 +00220 /* +00221 * vCreateInfoDictionary - create the document information dictionary +00222 */ +00223 void +00224 vCreateInfoDictionary(diagram_type *pDiag, int iWordVersion) +00225 { +00226 FILE *pOutFile; +00227 const char *szTitle, *szAuthor, *szSubject, *szCreator; +00228 const char *szCreationDate, *szModDate; +00229 +00230 fail(pDiag == NULL); +00231 fail(pDiag->pOutFile == NULL); +00232 fail(iWordVersion < 0); +00233 fail(szProducer == NULL || szProducer[0] == '\0'); +00234 +00235 szTitle = szGetTitle(); +00236 szAuthor = szGetAuthor(); +00237 szSubject = szGetSubject(); +00238 szCreationDate = szGetCreationDate(); +00239 szModDate = szGetModDate(); +00240 +00241 switch (iWordVersion) { +00242 case 0: szCreator = "Word for DOS"; break; +00243 case 1: szCreator = "WinWord 1.x"; break; +00244 case 2: szCreator = "WinWord 2.0"; break; +00245 case 4: szCreator = "MacWord 4"; break; +00246 case 5: szCreator = "MacWord 5"; break; +00247 case 6: szCreator = "Word 6"; break; +00248 case 7: szCreator = "Word 7/95"; break; +00249 case 8: szCreator = "Word 97 or later"; break; +00250 default: szCreator = NULL; break; +00251 } +00252 +00253 pOutFile = pDiag->pOutFile; +00254 +00255 vSetLocation(2); +00256 vFPprintf(pOutFile, "2 0 obj\n"); +00257 vFPprintf(pOutFile, "<<\n"); +00258 if (szTitle != NULL && szTitle[0] != '\0') { +00259 vFPprintf(pOutFile, "/Title (%s)\n", szTitle); +00260 } +00261 if (szAuthor != NULL && szAuthor[0] != '\0') { +00262 vFPprintf(pOutFile, "/Author (%s)\n", szAuthor); +00263 } +00264 if (szSubject != NULL && szSubject[0] != '\0') { +00265 vFPprintf(pOutFile, "/Subject (%s)\n", szSubject); +00266 } +00267 if (szCreator != NULL && szCreator[0] != '\0') { +00268 vFPprintf(pOutFile, "/Creator (%s)\n", szCreator); +00269 } +00270 vFPprintf(pOutFile, "/Producer (%s %s)\n", szProducer, VERSIONSTRING); +00271 if (szCreationDate != NULL && szCreationDate[0] != '\0') { +00272 vFPprintf(pOutFile, "/CreationDate (%s)\n", szCreationDate); +00273 } +00274 if (szModDate != NULL && szModDate[0] != '\0') { +00275 vFPprintf(pOutFile, "/ModDate (%s)\n", szModDate); +00276 } +00277 vFPprintf(pOutFile, ">>\n"); +00278 vFPprintf(pOutFile, "endobj\n"); +00279 } /* end of vCreateInfoDictionary */ +00280 +00281 /* +00282 * vAddHdrFtr - add a header or footer +00283 */ +00284 static void +00285 vAddHdrFtr(diagram_type *pDiag, const hdrftr_block_type *pHdrFtrInfo) +00286 { +00287 output_type *pStart, *pPrev, *pNext; +00288 +00289 fail(pDiag == NULL); +00290 fail(pHdrFtrInfo == NULL); +00291 +00292 vStartOfParagraphPDF(pDiag, 0); +00293 pStart = pHdrFtrInfo->pText; +00294 while (pStart != NULL) { +00295 pNext = pStart; +00296 while (pNext != NULL && +00297 (pNext->tNextFree != 1 || +00298 (pNext->szStorage[0] != PAR_END && +00299 pNext->szStorage[0] != HARD_RETURN))) { +00300 pNext = pNext->pNext; +00301 } +00302 if (pNext == NULL) { +00303 if (bOutputContainsText(pStart)) { +00304 vAlign2Window(pDiag, pStart, +00305 lChar2MilliPoints(DEFAULT_SCREEN_WIDTH), +00306 ALIGNMENT_LEFT); +00307 } else { +00308 vMove2NextLinePDF(pDiag, pStart->usFontSize); +00309 } +00310 break; +00311 } +00312 fail(pNext->tNextFree != 1); +00313 fail(pNext->szStorage[0] != PAR_END && +00314 pNext->szStorage[0] != HARD_RETURN); +00315 +00316 if (pStart != pNext) { +00317 /* There is something to print */ +00318 pPrev = pNext->pPrev; +00319 fail(pPrev->pNext != pNext); +00320 /* Cut the chain */ +00321 pPrev->pNext = NULL; +00322 if (bOutputContainsText(pStart)) { +00323 /* Print it */ +00324 vAlign2Window(pDiag, pStart, +00325 lChar2MilliPoints(DEFAULT_SCREEN_WIDTH), +00326 ALIGNMENT_LEFT); +00327 } else { +00328 /* Just an empty line */ +00329 vMove2NextLinePDF(pDiag, pStart->usFontSize); +00330 } +00331 /* Repair the chain */ +00332 pPrev->pNext = pNext; +00333 } +00334 if (pNext->szStorage[0] == PAR_END) { +00335 vEndOfParagraphPDF(pDiag, pNext->usFontSize, +00336 (long)pNext->usFontSize * 200); +00337 } +00338 pStart = pNext->pNext; +00339 } +00340 } /* end of vAddHdrFtr */ +00341 +00342 /* +00343 * vAddHeader - add a page header +00344 */ +00345 static void +00346 vAddHeader(diagram_type *pDiag) +00347 { +00348 const hdrftr_block_type *pHdrInfo; +00349 const hdrftr_block_type *pFtrInfo; +00350 +00351 fail(pDiag == NULL); +00352 +00353 NO_DBG_MSG("vAddHeader"); +00354 +00355 pHdrInfo = pGetHdrFtrInfo(iSectionIndex, TRUE, +00356 odd(iPageCount), bFirstInSection); +00357 pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE, +00358 odd(iPageCount), bFirstInSection); +00359 /* Set the height of the footer of this page */ +00360 lFooterHeight = pFtrInfo == NULL ? 0 : pFtrInfo->lHeight; +00361 fail(lFooterHeight < 0); +00362 +00363 if (pHdrInfo == NULL || +00364 pHdrInfo->pText == NULL || +00365 pHdrInfo->lHeight <= 0) { +00366 fail(pHdrInfo != NULL && pHdrInfo->lHeight < 0); +00367 fail(pHdrInfo != NULL && +00368 pHdrInfo->pText != NULL && +00369 pHdrInfo->lHeight == 0); +00370 return; +00371 } +00372 +00373 vAddHdrFtr(pDiag, pHdrInfo); +00374 +00375 DBG_DEC_C(pHdrInfo->lHeight != +00376 lPageHeight - PS_TOP_MARGIN - pDiag->lYtop, +00377 pHdrInfo->lHeight); +00378 DBG_DEC_C(pHdrInfo->lHeight != +00379 lPageHeight - PS_TOP_MARGIN - pDiag->lYtop, +00380 lPageHeight - PS_TOP_MARGIN - pDiag->lYtop); +00381 } /* end of vAddHeader */ +00382 +00383 /* +00384 * vAddFooter - add a page footer +00385 */ +00386 static void +00387 vAddFooter(diagram_type *pDiag) +00388 { +00389 const hdrftr_block_type *pFtrInfo; +00390 +00391 fail(pDiag == NULL); +00392 +00393 NO_DBG_MSG("vAddFooter"); +00394 +00395 pFtrInfo = pGetHdrFtrInfo(iSectionIndex, FALSE, +00396 odd(iPageCount), bFirstInSection); +00397 bFirstInSection = FALSE; +00398 if (pFtrInfo == NULL || +00399 pFtrInfo->pText == NULL || +00400 pFtrInfo->lHeight <= 0) { +00401 fail(pFtrInfo != NULL && pFtrInfo->lHeight < 0); +00402 fail(pFtrInfo != NULL && +00403 pFtrInfo->pText != NULL && +00404 pFtrInfo->lHeight == 0); +00405 return; +00406 } +00407 +00408 bInFtrSpace = TRUE; +00409 +00410 DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, pFtrInfo->lHeight); +00411 DBG_DEC_C(pFtrInfo->lHeight != lFooterHeight, lFooterHeight); +00412 DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN, +00413 pDiag->lYtop); +00414 DBG_DEC_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN, +00415 lFooterHeight + PS_BOTTOM_MARGIN); +00416 +00417 if (pDiag->lYtop > lFooterHeight + PS_BOTTOM_MARGIN) { +00418 /* Move down to the start of the footer */ +00419 pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN; +00420 vMoveTo(pDiag, 0); +00421 } else if (pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN / 2) { +00422 DBG_FIXME(); +00423 /* +00424 * Move up to the start of the footer, to prevent moving +00425 * of the bottom edge of the paper +00426 */ +00427 pDiag->lYtop = lFooterHeight + PS_BOTTOM_MARGIN; +00428 vMoveTo(pDiag, 0); +00429 } +00430 +00431 DBG_FLT_C(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN, +00432 dDrawUnits2Points(lFooterHeight + PS_BOTTOM_MARGIN - pDiag->lYtop)); +00433 +00434 vAddHdrFtr(pDiag, pFtrInfo); +00435 bInFtrSpace = FALSE; +00436 } /* end of vAddFooter */ +00437 +00438 /* +00439 * vEndPageObject - end the current page object +00440 */ +00441 static void +00442 vEndPageObject(FILE *pOutFile) +00443 { +00444 long lStreamEnd; +00445 +00446 if (lStreamStart < 0) { +00447 /* There is no current page object */ +00448 return; +00449 } +00450 +00451 vFPprintf(pOutFile, "ET\n"); +00452 lStreamEnd = lFilePosition; +00453 vFPprintf(pOutFile, "endstream\n"); +00454 vFPprintf(pOutFile, "endobj\n"); +00455 +00456 iObjectNumberCurr++; +00457 vSetLocation(iObjectNumberCurr); +00458 vFPprintf(pOutFile, "%d 0 obj\n", iObjectNumberCurr); +00459 vFPprintf(pOutFile, "%lu\n", lStreamEnd - lStreamStart); +00460 vFPprintf(pOutFile, "endobj\n"); +00461 } /* end of vEndPageObject */ +00462 +00463 /* +00464 * vMove2NextPage - move to the start of the next page +00465 */ +00466 static void +00467 vMove2NextPage(diagram_type *pDiag, BOOL bNewSection) +00468 { +00469 FILE *pOutFile; +00470 +00471 fail(pDiag == NULL); +00472 fail(pDiag->pOutFile == NULL); +00473 +00474 pOutFile = pDiag->pOutFile; +00475 +00476 vAddFooter(pDiag); +00477 /* End the old page object */ +00478 vEndPageObject(pOutFile); +00479 if (bNewSection) { +00480 iSectionIndex++; +00481 bFirstInSection = TRUE; +00482 } +00483 +00484 /* Start the new page object */ +00485 iObjectNumberCurr++; +00486 vSetLocation(iObjectNumberCurr); +00487 vFillNextPageObject(); +00488 vFPprintf(pOutFile, "%d 0 obj\n", iObjectNumberCurr); +00489 vFPprintf(pOutFile, "<<\n"); +00490 vFPprintf(pOutFile, "/Type /Page\n"); +00491 vFPprintf(pOutFile, "/Parent 3 0 R\n"); +00492 vFPprintf(pOutFile, "/Resources 17 0 R\n"); +00493 vFPprintf(pOutFile, "/Contents %d 0 R\n", iObjectNumberCurr + 1); +00494 vFPprintf(pOutFile, ">>\n"); +00495 vFPprintf(pOutFile, "endobj\n"); +00496 +00497 /* Start the new text object */ +00498 iObjectNumberCurr++; +00499 vSetLocation(iObjectNumberCurr); +00500 vFPprintf(pOutFile, "%d 0 obj\n", iObjectNumberCurr); +00501 vFPprintf(pOutFile, "<<\n"); +00502 vFPprintf(pOutFile, "/Length %d 0 R\n", iObjectNumberCurr + 1); +00503 vFPprintf(pOutFile, ">>\n"); +00504 vFPprintf(pOutFile, "stream\n"); +00505 lStreamStart = lFilePosition; +00506 vFPprintf(pOutFile, "BT\n"); +00507 +00508 /* Set variables to their start of page values */ +00509 pDiag->lYtop = lPageHeight - PS_TOP_MARGIN; +00510 tFontRefCurr = (drawfile_fontref)-1; +00511 usFontSizeCurr = 0; +00512 iFontColorCurr = -1; +00513 lYtopCurr = -1; +00514 vAddHeader(pDiag); +00515 } /* end of vMove2NextPage */ +00516 +00517 /* +00518 * vMoveTo - move to the specified X,Y coordinates +00519 * +00520 * Move the current position of the specified diagram to its X,Y coordinates, +00521 * start on a new page if needed +00522 */ +00523 static void +00524 vMoveTo(diagram_type *pDiag, long lLastVerticalMovement) +00525 { +00526 fail(pDiag == NULL); +00527 fail(pDiag->pOutFile == NULL); +00528 +00529 if (pDiag->lYtop <= lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace) { +00530 vMove2NextPage(pDiag, FALSE); +00531 /* Repeat the last vertical movement on the new page */ +00532 pDiag->lYtop -= lLastVerticalMovement; +00533 } +00534 +00535 fail(pDiag->lYtop < lFooterHeight + PS_BOTTOM_MARGIN && !bInFtrSpace); +00536 DBG_DEC_C(pDiag->lYtop < PS_BOTTOM_MARGIN, pDiag->lYtop); +00537 fail(pDiag->lYtop < PS_BOTTOM_MARGIN / 3); +00538 +00539 if (pDiag->lYtop != lYtopCurr) { +00540 vFPprintf(pDiag->pOutFile, "1 0 0 1 %.2f %.2f Tm\n", +00541 dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), +00542 dDrawUnits2Points(pDiag->lYtop)); +00543 lYtopCurr = pDiag->lYtop; +00544 } +00545 } /* end of vMoveTo */ +00546 +00547 /* +00548 * vProloguePDF - set options and perform the PDF initialization +00549 */ +00550 void +00551 vProloguePDF(diagram_type *pDiag, +00552 const char *szTask, const options_type *pOptions) +00553 { +00554 FILE *pOutFile; +00555 +00556 fail(pDiag == NULL); +00557 fail(pDiag->pOutFile == NULL); +00558 fail(pOptions == NULL); +00559 +00560 pOutFile = pDiag->pOutFile; +00561 +00562 eEncoding = pOptions->eEncoding; +00563 +00564 /* Create an empty location array */ +00565 tLocations = INITIAL_LOCATION_SIZE; +00566 alLocation = xcalloc(tLocations, sizeof(long)); +00567 +00568 /* Create an empty pageobject array */ +00569 tMaxPageObjects = INITIAL_PAGEOBJECT_SIZE; +00570 aiPageObject = xcalloc(tMaxPageObjects, sizeof(int)); +00571 +00572 if (pOptions->iPageHeight == INT_MAX) { +00573 lPageHeight = LONG_MAX; +00574 } else { +00575 lPageHeight = lPoints2DrawUnits(pOptions->iPageHeight); +00576 } +00577 DBG_DEC(lPageHeight); +00578 if (pOptions->iPageWidth == INT_MAX) { +00579 lPageWidth = LONG_MAX; +00580 } else { +00581 lPageWidth = lPoints2DrawUnits(pOptions->iPageWidth); +00582 } +00583 DBG_DEC(lPageWidth); +00584 lFooterHeight = 0; +00585 bInFtrSpace = FALSE; +00586 +00587 tFontRefCurr = (drawfile_fontref)-1; +00588 usFontSizeCurr = 0; +00589 iFontColorCurr = -1; +00590 lYtopCurr = -1; +00591 iPageCount = 0; +00592 iImageCount = 0; +00593 iSectionIndex = 0; +00594 bFirstInSection = TRUE; +00595 lFilePosition = 0; +00596 iMaxLocationNumber = 0; +00597 lStreamStart = -1; +00598 iObjectNumberCurr = 17; +00599 pDiag->lXleft = 0; +00600 pDiag->lYtop = 0; +00601 +00602 szProducer = szTask; +00603 +00604 vFPprintf(pOutFile, "%%PDF-1.3\n"); +00605 vFPprintf(pOutFile, "%%%c%c%c%c\n", 0xe2, 0xe3, 0xcf, 0xd3); +00606 +00607 /* Root catalog */ +00608 vSetLocation(1); +00609 vFPprintf(pOutFile, "1 0 obj\n"); +00610 vFPprintf(pOutFile, "<<\n"); +00611 vFPprintf(pOutFile, "/Type /Catalog\n"); +00612 vFPprintf(pOutFile, "/Pages 3 0 R\n"); +00613 vFPprintf(pOutFile, ">>\n"); +00614 vFPprintf(pOutFile, "endobj\n"); +00615 } /* end of vProloguePDF */ +00616 +00617 /* +00618 * vEpiloguePDF - clean up after everything is done +00619 */ +00620 void +00621 vEpiloguePDF(diagram_type *pDiag) +00622 { +00623 FILE *pOutFile; +00624 long lXref; +00625 int iIndex; +00626 +00627 fail(pDiag == NULL); +00628 fail(pDiag->pOutFile == NULL); +00629 +00630 pOutFile = pDiag->pOutFile; +00631 +00632 vAddFooter(pDiag); +00633 /* End the old page object */ +00634 vEndPageObject(pOutFile); +00635 +00636 vSetLocation(3); +00637 vFPprintf(pOutFile, "3 0 obj\n"); +00638 vFPprintf(pOutFile, "<<\n"); +00639 vFPprintf(pOutFile, "/Type /Pages\n"); +00640 vFPprintf(pOutFile, "/Count %d\n", iPageCount); +00641 vFPprintf(pOutFile, "/MediaBox [ 0 0 %.0f %.0f ]\n", +00642 dDrawUnits2Points(lPageWidth), +00643 dDrawUnits2Points(lPageHeight)); +00644 vFPprintf(pOutFile, "/Kids [ "); +00645 for (iIndex = 1; iIndex <= iPageCount; iIndex++) { +00646 vFPprintf(pOutFile, "\t%d 0 R\n", aiPageObject[iIndex]); +00647 } +00648 vFPprintf(pOutFile, "]\n"); +00649 vFPprintf(pOutFile, ">>\n"); +00650 vFPprintf(pOutFile, "endobj\n"); +00651 +00652 lXref = lFilePosition; +00653 +00654 vFPprintf(pOutFile, "xref\n"); +00655 vFPprintf(pOutFile, "0 %d\n", iMaxLocationNumber + 1); +00656 vFPprintf(pOutFile, "0000000000 65535 f \n"); +00657 for (iIndex = 1; iIndex <= iMaxLocationNumber; iIndex++) { +00658 vFPprintf(pOutFile, "%.10ld 00000 n \n", alLocation[iIndex]); +00659 } +00660 +00661 vFPprintf(pOutFile, "trailer\n"); +00662 vFPprintf(pOutFile, "<<\n"); +00663 vFPprintf(pOutFile, "/Size %d\n", iMaxLocationNumber + 1); +00664 vFPprintf(pOutFile, "/Root 1 0 R\n"); +00665 vFPprintf(pOutFile, "/Info 2 0 R\n"); +00666 vFPprintf(pOutFile, ">>\n"); +00667 +00668 vFPprintf(pOutFile, "startxref\n"); +00669 vFPprintf(pOutFile, "%ld\n", lXref); +00670 vFPprintf(pOutFile, "%%%%EOF\n"); +00671 +00672 szProducer = NULL; +00673 aiPageObject = xfree(aiPageObject); +00674 alLocation = xfree(alLocation); +00675 } /* end of vEpiloguePDF */ +00676 +00677 /* +00678 * vPrintPalette - print a pdf color space (palette) +00679 */ +00680 static void +00681 vPrintPalette(FILE *pOutFile, const imagedata_type *pImg) +00682 { +00683 int iIndex; +00684 +00685 fail(pOutFile == NULL); +00686 fail(pImg == NULL); +00687 fail(pImg->iColorsUsed < 2); +00688 fail(pImg->iColorsUsed > 256); +00689 +00690 vFPprintf(pOutFile, "\t/ColorSpace [ /Indexed\n"); +00691 vFPprintf(pOutFile, "\t/Device%s %d\n", +00692 pImg->bColorImage ? "RGB" : "Gray", pImg->iColorsUsed - 1); +00693 vFPprintf(pOutFile, "<"); +00694 for (iIndex = 0; iIndex < pImg->iColorsUsed; iIndex++) { +00695 vFPprintf(pOutFile, "%02x", +00696 (unsigned int)pImg->aucPalette[iIndex][0]); +00697 if (pImg->bColorImage) { +00698 vFPprintf(pOutFile, "%02x%02x", +00699 (unsigned int)pImg->aucPalette[iIndex][1], +00700 (unsigned int)pImg->aucPalette[iIndex][2]); +00701 } +00702 if (iIndex % 8 == 7) { +00703 vFPprintf(pOutFile, "\n"); +00704 } else { +00705 vFPprintf(pOutFile, " "); +00706 } +00707 } +00708 vFPprintf(pOutFile, "> ]\n"); +00709 } /* end of vPrintPalette */ +00710 +00711 /* +00712 * vImageProloguePDF - perform the image initialization +00713 */ +00714 void +00715 vImageProloguePDF(diagram_type *pDiag, const imagedata_type *pImg) +00716 { +00717 FILE *pOutFile; +00718 +00719 fail(pDiag == NULL); +00720 fail(pDiag->pOutFile == NULL); +00721 fail(pImg == NULL); +00722 +00723 if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) { +00724 return; +00725 } +00726 +00727 iImageCount++; +00728 +00729 DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft); +00730 +00731 pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled); +00732 vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled)); +00733 +00734 pOutFile = pDiag->pOutFile; +00735 +00736 vFPprintf(pOutFile, "ET\n"); +00737 vFPprintf(pOutFile, "q %% Image %03d\n", iImageCount); +00738 if (pImg->eImageType == imagetype_is_dib) { +00739 /* Scanning from left to right and bottom to top */ +00740 vFPprintf(pOutFile, "%d 0 0 %d %.2f %.2f cm\n", +00741 pImg->iHorSizeScaled, -pImg->iVerSizeScaled, +00742 dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), +00743 dDrawUnits2Points(pDiag->lYtop) + pImg->iVerSizeScaled); +00744 } else { +00745 /* Scanning from left to right and top to bottom */ +00746 vFPprintf(pOutFile, "%d 0 0 %d %.2f %.2f cm\n", +00747 pImg->iHorSizeScaled, pImg->iVerSizeScaled, +00748 dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), +00749 dDrawUnits2Points(pDiag->lYtop)); +00750 } +00751 vFPprintf(pOutFile, "BI\n"); +00752 vFPprintf(pOutFile, "\t/Width %d\n", pImg->iWidth); +00753 vFPprintf(pOutFile, "\t/Height %d\n", pImg->iHeight); +00754 switch (pImg->eImageType) { +00755 case imagetype_is_jpeg: +00756 switch (pImg->iComponents) { +00757 case 1: +00758 vFPprintf(pOutFile, "\t/ColorSpace /DeviceGray\n"); +00759 break; +00760 case 3: +00761 vFPprintf(pOutFile, "\t/ColorSpace /DeviceRGB\n"); +00762 break; +00763 case 4: +00764 vFPprintf(pOutFile, "\t/ColorSpace /DeviceCMYK\n"); +00765 if (pImg->bAdobe) { +00766 /* +00767 * Adobe-conforming CMYK file +00768 * applying workaround for color inversion +00769 */ +00770 vFPprintf(pOutFile, +00771 "\t/Decode [1 0 1 0 1 0 1 0]\n"); +00772 } +00773 break; +00774 default: +00775 DBG_DEC(pImg->iComponents); +00776 break; +00777 } +00778 vFPprintf(pOutFile, "\t/BitsPerComponent 8\n"); +00779 vFPprintf(pOutFile, +00780 "\t/Filter [ /ASCII85Decode /DCTDecode ]\n"); +00781 break; +00782 case imagetype_is_png: +00783 if (pImg->iComponents == 3 || pImg->iComponents == 4) { +00784 vFPprintf(pOutFile, "\t/ColorSpace /DeviceRGB\n"); +00785 vFPprintf(pOutFile, "\t/BitsPerComponent 8\n"); +00786 } else if (pImg->iColorsUsed > 0) { +00787 vPrintPalette(pOutFile, pImg); +00788 fail(pImg->uiBitsPerComponent > 8); +00789 vFPprintf(pOutFile, "\t/BitsPerComponent %u\n", +00790 pImg->uiBitsPerComponent); +00791 } else { +00792 vFPprintf(pOutFile, "\t/ColorSpace /DeviceGray\n"); +00793 vFPprintf(pOutFile, "\t/BitsPerComponent 8\n"); +00794 } +00795 vFPprintf(pOutFile, +00796 "\t/Filter [ /ASCII85Decode /FlateDecode ]\n"); +00797 vFPprintf(pOutFile, "\t/DecodeParms [ null <<\n"); +00798 vFPprintf(pOutFile, "\t\t/Predictor 10\n"); +00799 vFPprintf(pOutFile, "\t\t/Colors %d\n", pImg->iComponents); +00800 vFPprintf(pOutFile, "\t\t/BitsPerComponent %u\n", +00801 pImg->uiBitsPerComponent); +00802 vFPprintf(pOutFile, "\t\t/Columns %d\n", pImg->iWidth); +00803 vFPprintf(pOutFile, "\t\t>> ]\n"); +00804 break; +00805 case imagetype_is_dib: +00806 if (pImg->uiBitsPerComponent <= 8) { +00807 vPrintPalette(pOutFile, pImg); +00808 } else { +00809 vFPprintf(pOutFile, "\t/ColorSpace /DeviceRGB\n"); +00810 } +00811 vFPprintf(pOutFile, "\t/BitsPerComponent 8\n"); +00812 vFPprintf(pOutFile, "\t/Filter /ASCII85Decode\n"); +00813 break; +00814 default: +00815 vFPprintf(pOutFile, "\t/ColorSpace /Device%s\n", +00816 pImg->bColorImage ? "RGB" : "Gray"); +00817 vFPprintf(pOutFile, "\t/BitsPerComponent 8\n"); +00818 vFPprintf(pOutFile, "\t/Filter /ASCIIHexDecode\n"); +00819 break; +00820 } +00821 vFPprintf(pOutFile, "ID\n"); +00822 } /* end of vImageProloguePDF */ +00823 +00824 /* +00825 * vImageEpiloguePDF - clean up after the image +00826 */ +00827 void +00828 vImageEpiloguePDF(diagram_type *pDiag) +00829 { +00830 FILE *pOutFile; +00831 +00832 fail(pDiag == NULL); +00833 fail(pDiag->pOutFile == NULL); +00834 +00835 pOutFile = pDiag->pOutFile; +00836 +00837 /* Correction for the image bytes */ +00838 lFilePosition = ftell(pOutFile); +00839 +00840 vFPprintf(pOutFile, "EI\n"); +00841 vFPprintf(pOutFile, "Q\n"); +00842 vFPprintf(pOutFile, "BT\n"); +00843 +00844 pDiag->lXleft = 0; +00845 } /* end of vImageEpiloguePDF */ +00846 +00847 /* +00848 * bAddDummyImagePDF - add a dummy image +00849 * +00850 * return TRUE when successful, otherwise FALSE +00851 */ +00852 BOOL +00853 bAddDummyImagePDF(diagram_type *pDiag, const imagedata_type *pImg) +00854 { +00855 FILE *pOutFile; +00856 +00857 fail(pDiag == NULL); +00858 fail(pDiag->pOutFile == NULL); +00859 fail(pImg == NULL); +00860 +00861 if (pImg->iVerSizeScaled <= 0 || pImg->iHorSizeScaled <= 0) { +00862 return FALSE; +00863 } +00864 +00865 iImageCount++; +00866 +00867 DBG_DEC_C(pDiag->lXleft != 0, pDiag->lXleft); +00868 +00869 pDiag->lYtop -= lPoints2DrawUnits(pImg->iVerSizeScaled); +00870 vMoveTo(pDiag, lPoints2DrawUnits(pImg->iVerSizeScaled)); +00871 +00872 pOutFile = pDiag->pOutFile; +00873 +00874 vFPprintf(pOutFile, "ET\n"); +00875 vFPprintf(pOutFile, "q %% Image %03d\n", iImageCount); +00876 vFPprintf(pOutFile, "\t1.0 w\n"); +00877 vFPprintf(pOutFile, "\t0.3 G\n"); +00878 vFPprintf(pOutFile, "\t%.2f %.2f %d %d re\n", +00879 dDrawUnits2Points(pDiag->lXleft + PS_LEFT_MARGIN), +00880 dDrawUnits2Points(pDiag->lYtop), +00881 pImg->iHorSizeScaled, +00882 pImg->iVerSizeScaled); +00883 vFPprintf(pOutFile, "\tS\n"); +00884 vFPprintf(pOutFile, "Q\n"); +00885 vFPprintf(pOutFile, "BT\n"); +00886 +00887 pDiag->lXleft = 0; +00888 +00889 return TRUE; +00890 } /* end of bAddDummyImagePDF */ +00891 +00892 /* +00893 * vAddFontsPDF - add the font information +00894 */ +00895 void +00896 vAddFontsPDF(diagram_type *pDiag) +00897 { +00898 FILE *pOutFile; +00899 size_t tIndex; +00900 +00901 fail(pDiag == NULL); +00902 fail(pDiag->pOutFile == NULL); +00903 +00904 pOutFile = pDiag->pOutFile; +00905 +00906 /* The font encoding */ +00907 vSetLocation(4); +00908 vFPprintf(pOutFile, "4 0 obj\n"); +00909 vFPprintf(pOutFile, "<<\n"); +00910 vFPprintf(pOutFile, "/Type /Encoding\n"); +00911 vFPprintf(pOutFile, "/BaseEncoding /StandardEncoding\n"); +00912 vFPprintf(pOutFile, "/Differences [\n"); +00913 switch (eEncoding) { +00914 case encoding_latin_1: +00915 for (tIndex = 0; +00916 tIndex < elementsof(iso_8859_1); +00917 tIndex++) { +00918 vFPprintf(pOutFile, "%s\n", iso_8859_1[tIndex]); +00919 } +00920 break; +00921 case encoding_latin_2: +00922 for (tIndex = 0; +00923 tIndex < elementsof(iso_8859_2); +00924 tIndex++) { +00925 vFPprintf(pOutFile, "%s\n", iso_8859_2[tIndex]); +00926 } +00927 break; +00928 case encoding_cyrillic: +00929 werr(1, +00930 "The combination PDF and Cyrillic is not supported"); +00931 break; +00932 case encoding_utf_8: +00933 werr(1, +00934 "The combination PDF and UTF-8 is not supported"); +00935 break; +00936 default: +00937 DBG_DEC(eEncoding); +00938 break; +00939 } +00940 vFPprintf(pOutFile, "]\n"); +00941 vFPprintf(pOutFile, ">>\n"); +00942 vFPprintf(pOutFile, "endobj\n"); +00943 +00944 /* Twelve of the standard type 1 fonts */ +00945 for (tIndex = 0; tIndex < 12; tIndex++) { +00946 vSetLocation(5 + tIndex); +00947 vFPprintf(pOutFile, "%u 0 obj\n", 5 + tIndex); +00948 vFPprintf(pOutFile, "<<\n"); +00949 vFPprintf(pOutFile, "/Type /Font\n"); +00950 vFPprintf(pOutFile, "/Subtype /Type1\n"); +00951 vFPprintf(pOutFile, "/Name /F%u\n", 1 + tIndex); +00952 vFPprintf(pOutFile, "/BaseFont /%s\n", +00953 atFontname[tIndex].szPDFname); +00954 vFPprintf(pOutFile, "/Encoding 4 0 R\n"); +00955 vFPprintf(pOutFile, ">>\n"); +00956 vFPprintf(pOutFile, "endobj\n"); +00957 } +00958 +00959 /* The Resources */ +00960 vSetLocation(17); +00961 vFPprintf(pOutFile, "17 0 obj\n"); +00962 vFPprintf(pOutFile, "<<\n"); +00963 vFPprintf(pOutFile, "/ProcSet [ /PDF /Text ]\n"); +00964 vFPprintf(pOutFile, "/Font <<\n"); +00965 for (tIndex = 0; tIndex < 12; tIndex++) { +00966 vFPprintf(pOutFile, "\t/F%u %u 0 R\n", 1 + tIndex, 5 + tIndex); +00967 } +00968 vFPprintf(pOutFile, "\t>>\n"); +00969 vFPprintf(pOutFile, ">>\n"); +00970 vFPprintf(pOutFile, "endobj\n"); +00971 vAddHeader(pDiag); +00972 } /* end of vAddFontsPDF */ +00973 +00974 /* +00975 * vPrintPDF - print a PDF string +00976 */ +00977 static void +00978 vPrintPDF(FILE *pFile, const char *szString, size_t tStringLength, +00979 USHORT usFontstyle) +00980 { +00981 const UCHAR *aucBytes; +00982 double dMove; +00983 size_t tCount; +00984 +00985 fail(szString == NULL); +00986 +00987 if (szString == NULL || szString[0] == '\0' || tStringLength == 0) { +00988 return; +00989 } +00990 DBG_DEC_C(usFontSizeCurr < MIN_FONT_SIZE, usFontSizeCurr); +00991 +00992 dMove = 0.0; +00993 +00994 /* Up for superscript */ +00995 if (bIsSuperscript(usFontstyle) && usFontSizeCurr != 0) { +00996 dMove = (double)((usFontSizeCurr + 1) / 2) * 0.375; +00997 vFPprintf(pFile, "%.2f Ts\n", dMove); +00998 } +00999 +01000 /* Down for subscript */ +01001 if (bIsSubscript(usFontstyle) && usFontSizeCurr != 0) { +01002 dMove = (double)usFontSizeCurr * 0.125; +01003 vFPprintf(pFile, "%.2f Ts\n", -dMove); +01004 } +01005 +01006 /* Generate and print the PDF output */ +01007 aucBytes = (UCHAR *)szString; +01008 vFPprintf(pFile, "("); +01009 for (tCount = 0; tCount < tStringLength ; tCount++) { +01010 switch (aucBytes[tCount]) { +01011 case '(': +01012 case ')': +01013 case '\\': +01014 vFPprintf(pFile, "\\%c", szString[tCount]); +01015 break; +01016 default: +01017 if (aucBytes[tCount] < 0x20 || +01018 aucBytes[tCount] == 0x7f || +01019 (aucBytes[tCount] >= 0x81 && +01020 aucBytes[tCount] < 0x8c)) { +01021 DBG_HEX(aucBytes[tCount]); +01022 vFPprintf(pFile, " "); +01023 } else if (aucBytes[tCount] >= 0x80) { +01024 vFPprintf(pFile, "\\%03o", +01025 (UINT)aucBytes[tCount]); +01026 } else { +01027 vFPprintf(pFile, "%c", szString[tCount]); +01028 } +01029 break; +01030 } +01031 } +01032 vFPprintf(pFile, ") Tj\n"); +01033 +01034 /* Undo the superscript/subscript move */ +01035 if (dMove != 0.0) { +01036 vFPprintf(pFile, "0 Ts\n"); +01037 } +01038 } /* end of vPrintPDF */ +01039 +01040 /* +01041 * vSetColor - move to the specified color +01042 */ +01043 static void +01044 vSetColor(FILE *pFile, UCHAR ucFontColor) +01045 { +01046 ULONG ulTmp, ulRed, ulGreen, ulBlue; +01047 +01048 ulTmp = ulColor2Color(ucFontColor); +01049 ulRed = (ulTmp & 0x0000ff00) >> 8; +01050 ulGreen = (ulTmp & 0x00ff0000) >> 16; +01051 ulBlue = (ulTmp & 0xff000000) >> 24; +01052 vFPprintf(pFile, "%.3f %.3f %.3f rg\n", +01053 ulRed / 255.0, ulGreen / 255.0, ulBlue / 255.0); +01054 } /* end of vSetColor */ +01055 +01056 /* +01057 * vMove2NextLinePDF - move to the next line +01058 */ +01059 void +01060 vMove2NextLinePDF(diagram_type *pDiag, USHORT usFontSize) +01061 { +01062 fail(pDiag == NULL); +01063 fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); +01064 +01065 pDiag->lYtop -= lComputeLeading(usFontSize); +01066 } /* end of vMove2NextLinePDF */ +01067 +01068 /* +01069 * vSubstringPDF - print a sub string +01070 */ +01071 void +01072 vSubstringPDF(diagram_type *pDiag, +01073 char *szString, size_t tStringLength, long lStringWidth, +01074 UCHAR ucFontColor, USHORT usFontstyle, drawfile_fontref tFontRef, +01075 USHORT usFontSize, USHORT usMaxFontSize) +01076 { +01077 size_t tFontIndex; +01078 +01079 fail(pDiag == NULL || szString == NULL); +01080 fail(pDiag->pOutFile == NULL); +01081 fail(pDiag->lXleft < 0); +01082 fail(tStringLength != strlen(szString)); +01083 fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); +01084 fail(usMaxFontSize < MIN_FONT_SIZE || usMaxFontSize > MAX_FONT_SIZE); +01085 fail(usFontSize > usMaxFontSize); +01086 +01087 if (szString[0] == '\0' || tStringLength == 0) { +01088 return; +01089 } +01090 +01091 vMoveTo(pDiag, lComputeLeading(usMaxFontSize)); +01092 if (tFontRef != tFontRefCurr || usFontSize != usFontSizeCurr) { +01093 tFontIndex = tGetFontIndex(tFontRef); +01094 vFPprintf(pDiag->pOutFile, "/F%u %.1f Tf\n", +01095 1 + tFontIndex, (double)usFontSize / 2.0); +01096 tFontRefCurr = tFontRef; +01097 usFontSizeCurr = usFontSize; +01098 } +01099 if ((int)ucFontColor != iFontColorCurr) { +01100 vSetColor(pDiag->pOutFile, ucFontColor); +01101 iFontColorCurr = (int)ucFontColor; +01102 } +01103 vPrintPDF(pDiag->pOutFile, szString, tStringLength, usFontstyle); +01104 pDiag->lXleft += lStringWidth; +01105 } /* end of vSubstringPDF */ +01106 +01107 /* +01108 * Create an start of paragraph by moving the y-top mark +01109 */ +01110 void +01111 vStartOfParagraphPDF(diagram_type *pDiag, long lBeforeIndentation) +01112 { +01113 fail(pDiag == NULL); +01114 fail(lBeforeIndentation < 0); +01115 +01116 pDiag->lXleft = 0; +01117 pDiag->lYtop -= lMilliPoints2DrawUnits(lBeforeIndentation); +01118 } /* end of vStartOfParagraphPDF */ +01119 +01120 /* +01121 * Create an end of paragraph by moving the y-top mark +01122 */ +01123 void +01124 vEndOfParagraphPDF(diagram_type *pDiag, +01125 USHORT usFontSize, long lAfterIndentation) +01126 { +01127 fail(pDiag == NULL); +01128 fail(pDiag->pOutFile == NULL); +01129 fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); +01130 fail(lAfterIndentation < 0); +01131 +01132 if (pDiag->lXleft > 0) { +01133 /* To the start of the line */ +01134 vMove2NextLinePDF(pDiag, usFontSize); +01135 } +01136 +01137 pDiag->lXleft = 0; +01138 pDiag->lYtop -= lMilliPoints2DrawUnits(lAfterIndentation); +01139 } /* end of vEndOfParagraphPDF */ +01140 +01141 /* +01142 * Create an end of page +01143 */ +01144 void +01145 vEndOfPagePDF(diagram_type *pDiag, BOOL bNewSection) +01146 { +01147 vMove2NextPage(pDiag, bNewSection); +01148 } /* end of vEndOfPagePDF */ +