diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/fonts_8c_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/fonts_8c_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,1034 @@ + + +
+ +00001 /* +00002 * fonts.c +00003 * Copyright (C) 1998-2004 A.J. van Os; Released under GNU GPL +00004 * +00005 * Description: +00006 * Functions to deal with fonts (generic) +00007 */ +00008 +00009 #include <ctype.h> +00010 #include <string.h> +00011 #include "antiword.h" +00012 +00013 /* Maximum line length in the font file */ +00014 #define FONT_LINE_LENGTH 81 +00015 +00016 /* Pitch */ +00017 #define PITCH_UNKNOWN 0 +00018 #define PITCH_FIXED 1 +00019 #define PITCH_VARIABLE 2 +00020 +00021 /* Font Family */ +00022 #define FAMILY_UNKNOWN 0 +00023 #define FAMILY_ROMAN 1 +00024 #define FAMILY_SWISS 2 +00025 #define FAMILY_MODERN 3 +00026 #define FAMILY_SCRIPT 4 +00027 #define FAMILY_DECORATIVE 5 +00028 +00029 /* Font Translation Table */ +00030 static size_t tFontTableRecords = 0; +00031 static font_table_type *pFontTable = NULL; +00032 +00033 /* +00034 * Find the given font in the font table +00035 * +00036 * returns the index into the FontTable, -1 if not found +00037 */ +00038 int +00039 iGetFontByNumber(UCHAR ucWordFontNumber, USHORT usFontStyle) +00040 { +00041 int iIndex; +00042 +00043 for (iIndex = 0; iIndex < (int)tFontTableRecords; iIndex++) { +00044 if (ucWordFontNumber == pFontTable[iIndex].ucWordFontNumber && +00045 usFontStyle == pFontTable[iIndex].usFontStyle && +00046 pFontTable[iIndex].szOurFontname[0] != '\0') { +00047 return iIndex; +00048 } +00049 } +00050 DBG_DEC(ucWordFontNumber); +00051 DBG_HEX(usFontStyle); +00052 return -1; +00053 } /* end of iGetFontByNumber */ +00054 +00055 /* +00056 * szGetOurFontname - Get our font name +00057 * +00058 * return our font name from the given index, NULL if not found +00059 */ +00060 const char * +00061 szGetOurFontname(int iIndex) +00062 { +00063 if (iIndex < 0 || iIndex >= (int)tFontTableRecords) { +00064 return NULL; +00065 } +00066 return pFontTable[iIndex].szOurFontname; +00067 } /* end of szGetOurFontname */ +00068 +00069 /* +00070 * Find the given font in the font table +00071 * +00072 * returns the Word font number, -1 if not found +00073 */ +00074 int +00075 iFontname2Fontnumber(const char *szOurFontname, USHORT usFontStyle) +00076 { +00077 int iIndex; +00078 +00079 for (iIndex = 0; iIndex < (int)tFontTableRecords; iIndex++) { +00080 if (pFontTable[iIndex].usFontStyle == usFontStyle && +00081 STREQ(pFontTable[iIndex].szOurFontname, szOurFontname)) { +00082 return (int)pFontTable[iIndex].ucWordFontNumber; +00083 } +00084 } +00085 return -1; +00086 } /* end of iFontname2Fontnumber */ +00087 +00088 /* +00089 * szGetDefaultFont - get the default font that matches the parameters +00090 */ +00091 static const char * +00092 szGetDefaultFont(UCHAR ucFFN, int iEmphasis) +00093 { +00094 UCHAR ucPrq, ucFf; +00095 +00096 fail(iEmphasis < 0 || iEmphasis > 3); +00097 +00098 ucPrq = ucFFN & 0x03; +00099 ucFf = (ucFFN & 0x70) >> 4; +00100 NO_DBG_DEC(ucPrq); +00101 NO_DBG_DEC(ucFf); +00102 if (ucPrq == PITCH_FIXED) { +00103 /* Set to the default monospaced font */ +00104 switch (iEmphasis) { +00105 case 1: return FONT_MONOSPACED_BOLD; +00106 case 2: return FONT_MONOSPACED_ITALIC; +00107 case 3: return FONT_MONOSPACED_BOLDITALIC; +00108 default: return FONT_MONOSPACED_PLAIN; +00109 } +00110 } else if (ucFf == FAMILY_ROMAN) { +00111 /* Set to the default serif font */ +00112 switch (iEmphasis) { +00113 case 1: return FONT_SERIF_BOLD; +00114 case 2: return FONT_SERIF_ITALIC; +00115 case 3: return FONT_SERIF_BOLDITALIC; +00116 default: return FONT_SERIF_PLAIN; +00117 } +00118 } else if (ucFf == FAMILY_SWISS) { +00119 /* Set to the default sans serif font */ +00120 switch (iEmphasis) { +00121 case 1: return FONT_SANS_SERIF_BOLD; +00122 case 2: return FONT_SANS_SERIF_ITALIC; +00123 case 3: return FONT_SANS_SERIF_BOLDITALIC; +00124 default: return FONT_SANS_SERIF_PLAIN; +00125 } +00126 } else { +00127 /* Set to the default default font */ +00128 switch (iEmphasis) { +00129 case 1: return FONT_SERIF_BOLD; +00130 case 2: return FONT_SERIF_ITALIC; +00131 case 3: return FONT_SERIF_BOLDITALIC; +00132 default: return FONT_SERIF_PLAIN; +00133 } +00134 } +00135 } /* end of szGetDefaultFont */ +00136 +00137 /* +00138 * See if the fontname from the Word file matches the fontname from the +00139 * font translation file. +00140 * If iBytesPerChar is one than aucWord is in ISO-8859-x (Word 2/6/7), +00141 * if iBytesPerChar is two than aucWord is in Unicode (Word 8/9/10). +00142 */ +00143 static BOOL +00144 bFontEqual(const UCHAR *aucWord, const char *szTable, int iBytesPerChar) +00145 { +00146 const UCHAR *pucTmp; +00147 const char *pcTmp; +00148 +00149 fail(aucWord == NULL || szTable == NULL); +00150 fail(iBytesPerChar != 1 && iBytesPerChar != 2); +00151 +00152 for (pucTmp = aucWord, pcTmp = szTable; +00153 *pucTmp != 0; +00154 pucTmp += iBytesPerChar, pcTmp++) { +00155 if (ulToUpper((ULONG)*pucTmp) != +00156 ulToUpper((ULONG)(UCHAR)*pcTmp)) { +00157 return FALSE; +00158 } +00159 } +00160 return *pcTmp == '\0'; +00161 } /* end of bFontEqual */ +00162 +00163 /* +00164 * vFontname2Table - add fontnames to the font table +00165 */ +00166 static void +00167 vFontname2Table(const UCHAR *aucFont, const UCHAR *aucAltFont, +00168 int iBytesPerChar, int iEmphasis, UCHAR ucFFN, +00169 const char *szWordFont, const char *szOurFont, +00170 font_table_type *pFontTableRecord) +00171 { +00172 BOOL bMatchFound; +00173 +00174 fail(aucFont == NULL || aucFont[0] == 0); +00175 fail(aucAltFont != NULL && aucAltFont[0] == 0); +00176 fail(iBytesPerChar != 1 && iBytesPerChar != 2); +00177 fail(iEmphasis < 0 || iEmphasis > 3); +00178 fail(szWordFont == NULL || szWordFont[0] == '\0'); +00179 fail(szOurFont == NULL || szOurFont[0] == '\0'); +00180 fail(pFontTableRecord == NULL); +00181 +00182 bMatchFound = bFontEqual(aucFont, szWordFont, iBytesPerChar); +00183 +00184 if (!bMatchFound && aucAltFont != NULL) { +00185 bMatchFound = bFontEqual(aucAltFont, szWordFont, iBytesPerChar); +00186 } +00187 +00188 if (!bMatchFound && +00189 pFontTableRecord->szWordFontname[0] == '\0' && +00190 szWordFont[0] == '*' && +00191 szWordFont[1] == '\0') { +00192 /* +00193 * szWordFont contains a "*", so szOurFont will contain the +00194 * "default default" font. See if we can do better than that. +00195 */ +00196 szOurFont = szGetDefaultFont(ucFFN, iEmphasis); +00197 bMatchFound = TRUE; +00198 } +00199 +00200 if (bMatchFound) { +00201 switch (iBytesPerChar) { +00202 case 1: +00203 (void)strncpy(pFontTableRecord->szWordFontname, +00204 (const char *)aucFont, +00205 sizeof(pFontTableRecord->szWordFontname) - 1); +00206 break; +00207 case 2: +00208 (void)unincpy(pFontTableRecord->szWordFontname, +00209 aucFont, +00210 sizeof(pFontTableRecord->szWordFontname) - 1); +00211 break; +00212 default: +00213 DBG_FIXME(); +00214 pFontTableRecord->szWordFontname[0] = '\0'; +00215 break; +00216 } +00217 pFontTableRecord->szWordFontname[ +00218 sizeof(pFontTableRecord->szWordFontname) - 1] = '\0'; +00219 (void)strncpy(pFontTableRecord->szOurFontname, szOurFont, +00220 sizeof(pFontTableRecord->szOurFontname) - 1); +00221 pFontTableRecord->szOurFontname[ +00222 sizeof(pFontTableRecord->szOurFontname) - 1] = '\0'; +00223 NO_DBG_MSG(pFontTableRecord->szWordFontname); +00224 NO_DBG_MSG(pFontTableRecord->szOurFontname); +00225 pFontTableRecord->ucFFN = ucFFN; +00226 pFontTableRecord->ucEmphasis = (UCHAR)iEmphasis; +00227 } +00228 } /* end of vFontname2Table */ +00229 +00230 /* +00231 * vCreateFontTable - Create and initialize the internal font table +00232 */ +00233 static void +00234 vCreateFontTable(void) +00235 { +00236 font_table_type *pTmp; +00237 int iNbr; +00238 +00239 if (tFontTableRecords == 0) { +00240 pFontTable = xfree(pFontTable); +00241 return; +00242 } +00243 +00244 /* Create the font table */ +00245 pFontTable = xcalloc(tFontTableRecords, sizeof(*pFontTable)); +00246 +00247 /* Initialize the font table */ +00248 for (iNbr = 0, pTmp = pFontTable; +00249 pTmp < pFontTable + tFontTableRecords; +00250 iNbr++, pTmp++) { +00251 pTmp->ucWordFontNumber = (UCHAR)(iNbr / 4); +00252 switch (iNbr % 4) { +00253 case 0: +00254 pTmp->usFontStyle = FONT_REGULAR; +00255 break; +00256 case 1: +00257 pTmp->usFontStyle = FONT_BOLD; +00258 break; +00259 case 2: +00260 pTmp->usFontStyle = FONT_ITALIC; +00261 break; +00262 case 3: +00263 pTmp->usFontStyle = FONT_BOLD|FONT_ITALIC; +00264 break; +00265 default: +00266 DBG_DEC(iNbr); +00267 break; +00268 } +00269 } +00270 } /* end of vCreateFontTable */ +00271 +00272 /* +00273 * vMinimizeFontTable - make the font table as small as possible +00274 */ +00275 static void +00276 vMinimizeFontTable(void) +00277 { +00278 font_block_type tFontNext; +00279 const style_block_type *pStyle; +00280 const font_block_type *pFont; +00281 font_table_type *pTmp; +00282 int iUnUsed; +00283 BOOL bMustAddTableFont; +00284 +00285 NO_DBG_MSG("vMinimizeFontTable"); +00286 +00287 if (tFontTableRecords == 0) { +00288 pFontTable = xfree(pFontTable); +00289 return; +00290 } +00291 +00292 /* See if we must add a font for our tables */ +00293 bMustAddTableFont = TRUE; +00294 +00295 #if 0 +00296 DBG_MSG("Before"); +00297 DBG_DEC(tFontTableRecords); +00298 for (pTmp = pFontTable; +00299 pTmp < pFontTable + tFontTableRecords; +00300 pTmp++) { +00301 DBG_DEC(pTmp->ucWordFontNumber); +00302 DBG_HEX(pTmp->usFontStyle); +00303 DBG_MSG(pTmp->szWordFontname); +00304 DBG_MSG(pTmp->szOurFontname); +00305 } +00306 #endif /* DEBUG */ +00307 +00308 /* See which fonts/styles we really need */ +00309 +00310 /* Default font/style is by definition in use */ +00311 pFontTable[0].ucInUse = 1; +00312 +00313 /* Make InUse 1 for all the fonts/styles that WILL be used */ +00314 pFont = NULL; +00315 while((pFont = pGetNextFontInfoListItem(pFont)) != NULL) { +00316 pTmp = pFontTable + 4 * (int)pFont->ucFontNumber; +00317 if (bIsBold(pFont->usFontStyle)) { +00318 pTmp++; +00319 } +00320 if (bIsItalic(pFont->usFontStyle)) { +00321 pTmp += 2; +00322 } +00323 if (pTmp >= pFontTable + tFontTableRecords) { +00324 continue; +00325 } +00326 if (STREQ(pTmp->szOurFontname, TABLE_FONT)) { +00327 /* The table font is already present */ +00328 bMustAddTableFont = FALSE; +00329 } +00330 pTmp->ucInUse = 1; +00331 } +00332 +00333 /* Make InUse 1 for all the fonts/styles that MIGHT be used */ +00334 pStyle = NULL; +00335 while((pStyle = pGetNextStyleInfoListItem(pStyle)) != NULL) { +00336 vFillFontFromStylesheet(pStyle->usIstdNext, &tFontNext); +00337 vCorrectFontValues(&tFontNext); +00338 pTmp = pFontTable + 4 * (int)tFontNext.ucFontNumber; +00339 if (bIsBold(tFontNext.usFontStyle)) { +00340 pTmp++; +00341 } +00342 if (bIsItalic(tFontNext.usFontStyle)) { +00343 pTmp += 2; +00344 } +00345 if (pTmp >= pFontTable + tFontTableRecords) { +00346 continue; +00347 } +00348 if (STREQ(pTmp->szOurFontname, TABLE_FONT)) { +00349 /* The table font is already present */ +00350 bMustAddTableFont = FALSE; +00351 } +00352 pTmp->ucInUse = 1; +00353 } +00354 +00355 /* Remove the unused font entries from the font table */ +00356 iUnUsed = 0; +00357 for (pTmp = pFontTable; +00358 pTmp < pFontTable + tFontTableRecords; +00359 pTmp++) { +00360 if (pTmp->ucInUse == 0) { +00361 iUnUsed++; +00362 continue; +00363 } +00364 if (iUnUsed > 0) { +00365 fail(pTmp - iUnUsed <= pFontTable); +00366 *(pTmp - iUnUsed) = *pTmp; +00367 } +00368 } +00369 fail(iUnUsed < 0); +00370 fail(tFontTableRecords <= (size_t)iUnUsed); +00371 tFontTableRecords -= (size_t)iUnUsed; +00372 +00373 if (bMustAddTableFont) { +00374 pTmp = pFontTable + tFontTableRecords; +00375 fail(pTmp <= pFontTable); +00376 pTmp->ucWordFontNumber = (pTmp - 1)->ucWordFontNumber + 1; +00377 pTmp->usFontStyle = FONT_REGULAR; +00378 pTmp->ucInUse = 1; +00379 strcpy(pTmp->szWordFontname, "Extra Table Font"); +00380 strcpy(pTmp->szOurFontname, TABLE_FONT); +00381 tFontTableRecords++; +00382 iUnUsed--; +00383 } +00384 if (iUnUsed > 0) { +00385 /* Resize the font table */ +00386 pFontTable = xrealloc(pFontTable, +00387 tFontTableRecords * sizeof(*pFontTable)); +00388 } +00389 #if defined(DEBUG) +00390 DBG_MSG("After"); +00391 DBG_DEC(tFontTableRecords); +00392 for (pTmp = pFontTable; +00393 pTmp < pFontTable + tFontTableRecords; +00394 pTmp++) { +00395 DBG_DEC(pTmp->ucWordFontNumber); +00396 DBG_HEX(pTmp->usFontStyle); +00397 DBG_MSG(pTmp->szWordFontname); +00398 DBG_MSG(pTmp->szOurFontname); +00399 } +00400 #endif /* DEBUG */ +00401 } /* end of vMinimizeFontTable */ +00402 +00403 /* +00404 * bReadFontFile - read and check a line from the font translation file +00405 * +00406 * returns TRUE when a correct line has been read, otherwise FALSE +00407 */ +00408 static BOOL +00409 bReadFontFile(FILE *pFontTableFile, char *szWordFont, +00410 int *piItalic, int *piBold, char *szOurFont, int *piSpecial) +00411 { +00412 char *pcTmp; +00413 int iFields; +00414 char szLine[FONT_LINE_LENGTH]; +00415 +00416 fail(szWordFont == NULL || szOurFont == NULL); +00417 fail(piItalic == NULL || piBold == NULL || piSpecial == NULL); +00418 +00419 while (fgets(szLine, (int)sizeof(szLine), pFontTableFile) != NULL) { +00420 if (szLine[0] == '#' || +00421 szLine[0] == '\n' || +00422 szLine[0] == '\r') { +00423 continue; +00424 } +00425 iFields = sscanf(szLine, "%[^,],%d,%d,%1s%[^,],%d", +00426 szWordFont, piItalic, piBold, +00427 &szOurFont[0], &szOurFont[1], piSpecial); +00428 if (iFields != 6) { +00429 pcTmp = strchr(szLine, '\r'); +00430 if (pcTmp != NULL) { +00431 *pcTmp = '\0'; +00432 } +00433 pcTmp = strchr(szLine, '\n'); +00434 if (pcTmp != NULL) { +00435 *pcTmp = '\0'; +00436 } +00437 DBG_DEC(iFields); +00438 werr(0, "Syntax error in: '%s'", szLine); +00439 continue; +00440 } +00441 if (strlen(szWordFont) >= +00442 sizeof(pFontTable[0].szWordFontname)) { +00443 werr(0, "Word fontname too long: '%s'", szWordFont); +00444 continue; +00445 } +00446 if (strlen(szOurFont) >= +00447 sizeof(pFontTable[0].szOurFontname)) { +00448 werr(0, "Local fontname too long: '%s'", szOurFont); +00449 continue; +00450 } +00451 /* The current line passed all the tests */ +00452 return TRUE; +00453 } +00454 return FALSE; +00455 } /* end of bReadFontFile */ +00456 +00457 /* +00458 * vCreate0FontTable - create a font table from Word for DOS +00459 */ +00460 void +00461 vCreate0FontTable(void) +00462 { +00463 FILE *pFontTableFile; +00464 font_table_type *pTmp; +00465 UCHAR *aucFont; +00466 int iBold, iItalic, iSpecial, iEmphasis, iFtc; +00467 UCHAR ucPrq, ucFf, ucFFN; +00468 char szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH]; +00469 +00470 tFontTableRecords = 0; +00471 pFontTable = xfree(pFontTable); +00472 +00473 pFontTableFile = pOpenFontTableFile(); +00474 if (pFontTableFile == NULL) { +00475 /* No translation table file, no translation table */ +00476 return; +00477 } +00478 +00479 /* Get the maximum number of entries in the font table */ +00480 tFontTableRecords = 64; +00481 tFontTableRecords *= 4; /* Plain, Bold, Italic and Bold/italic */ +00482 tFontTableRecords++; /* One extra for the table-font */ +00483 vCreateFontTable(); +00484 +00485 /* Read the font translation file */ +00486 iItalic = 0; +00487 iBold = 0; +00488 iSpecial = 0; +00489 while (bReadFontFile(pFontTableFile, szWordFont, +00490 &iItalic, &iBold, szOurFont, &iSpecial)) { +00491 iEmphasis = 0; +00492 if (iBold != 0) { +00493 iEmphasis++; +00494 } +00495 if (iItalic != 0) { +00496 iEmphasis += 2; +00497 } +00498 for (iFtc = 0, pTmp = pFontTable + iEmphasis; +00499 pTmp < pFontTable + tFontTableRecords; +00500 iFtc++, pTmp += 4) { +00501 if (iFtc >= 16 && iFtc <= 55) { +00502 ucPrq = PITCH_VARIABLE; +00503 ucFf = FAMILY_ROMAN; +00504 aucFont = (UCHAR *)"Times"; +00505 } else { +00506 ucPrq = PITCH_FIXED; +00507 ucFf = FAMILY_MODERN; +00508 aucFont = (UCHAR *)"Courier"; +00509 } +00510 ucFFN = (ucFf << 4) | ucPrq; +00511 vFontname2Table(aucFont, NULL, 1, iEmphasis, +00512 ucFFN, szWordFont, szOurFont, pTmp); +00513 } +00514 } +00515 (void)fclose(pFontTableFile); +00516 vMinimizeFontTable(); +00517 } /* end of vCreate0FontTable */ +00518 +00519 /* +00520 * vCreate2FontTable - create a font table from WinWord 1/2 +00521 */ +00522 void +00523 vCreate2FontTable(FILE *pFile, int iWordVersion, const UCHAR *aucHeader) +00524 { +00525 FILE *pFontTableFile; +00526 font_table_type *pTmp; +00527 UCHAR *aucFont; +00528 UCHAR *aucBuffer; +00529 ULONG ulBeginFontInfo; +00530 size_t tFontInfoLen; +00531 int iPos, iOff, iRecLen; +00532 int iBold, iItalic, iSpecial, iEmphasis; +00533 UCHAR ucFFN; +00534 char szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH]; +00535 +00536 fail(pFile == NULL || aucHeader == NULL); +00537 fail(iWordVersion != 1 && iWordVersion != 2); +00538 +00539 tFontTableRecords = 0; +00540 pFontTable = xfree(pFontTable); +00541 +00542 pFontTableFile = pOpenFontTableFile(); +00543 if (pFontTableFile == NULL) { +00544 /* No translation table file, no translation table */ +00545 return; +00546 } +00547 +00548 ulBeginFontInfo = ulGetLong(0xb2, aucHeader); /* fcSttbfffn */ +00549 DBG_HEX(ulBeginFontInfo); +00550 tFontInfoLen = (size_t)usGetWord(0xb6, aucHeader); /* cbSttbfffn */ +00551 DBG_DEC(tFontInfoLen); +00552 +00553 if (ulBeginFontInfo > (ULONG)LONG_MAX || tFontInfoLen == 0) { +00554 /* Don't ask me why this is needed */ +00555 DBG_HEX_C(tFontInfoLen != 0, ulBeginFontInfo); +00556 (void)fclose(pFontTableFile); +00557 return; +00558 } +00559 +00560 aucBuffer = xmalloc(tFontInfoLen); +00561 if (!bReadBytes(aucBuffer, tFontInfoLen, ulBeginFontInfo, pFile)) { +00562 aucBuffer = xfree(aucBuffer); +00563 (void)fclose(pFontTableFile); +00564 return; +00565 } +00566 NO_DBG_PRINT_BLOCK(aucBuffer, tFontInfoLen); +00567 DBG_DEC(usGetWord(0, aucBuffer)); +00568 +00569 /* Compute the maximum number of entries in the font table */ +00570 if (iWordVersion == 1) { +00571 fail(tFontInfoLen < 2); +00572 /* WinWord 1 has three implicit fonts */ +00573 tFontTableRecords = 3; +00574 iOff = 2; +00575 } else { +00576 fail(tFontInfoLen < 6); +00577 /* WinWord 2 and up have no implicit fonts */ +00578 tFontTableRecords = 0; +00579 iOff = 3; +00580 } +00581 iPos = 2; +00582 while (iPos + iOff < (int)tFontInfoLen) { +00583 iRecLen = (int)ucGetByte(iPos, aucBuffer); +00584 NO_DBG_DEC(iRecLen); +00585 NO_DBG_MSG(aucBuffer + iPos + iOff); +00586 iPos += iRecLen + 1; +00587 tFontTableRecords++; +00588 } +00589 tFontTableRecords *= 4; /* Plain, Bold, Italic and Bold/Italic */ +00590 tFontTableRecords++; /* One extra for the table-font */ +00591 vCreateFontTable(); +00592 +00593 /* Add the tree implicit fonts (in four variations) */ +00594 if (iWordVersion == 1) { +00595 fail(tFontTableRecords < 13); +00596 vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 0, +00597 (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), +00598 "*", "Times-Roman", pFontTable + 0); +00599 vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 1, +00600 (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), +00601 "*", "Times-Bold", pFontTable + 1); +00602 vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 2, +00603 (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), +00604 "*", "Times-Italic", pFontTable + 2); +00605 vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 3, +00606 (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), +00607 "*", "Times-BoldItalic", pFontTable + 3); +00608 vFontname2Table((UCHAR *)"Symbol", NULL, 1, 0, +00609 (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), +00610 "*", "Times-Roman", pFontTable + 4); +00611 vFontname2Table((UCHAR *)"Symbol", NULL, 1, 1, +00612 (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), +00613 "*", "Times-Bold", pFontTable + 5); +00614 vFontname2Table((UCHAR *)"Symbol", NULL, 1, 2, +00615 (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), +00616 "*", "Times-Italic", pFontTable + 6); +00617 vFontname2Table((UCHAR *)"Symbol", NULL, 1, 3, +00618 (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), +00619 "*", "Times-BoldItalic", pFontTable + 7); +00620 vFontname2Table((UCHAR *)"Helv", NULL, 1, 0, +00621 (UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE), +00622 "*", "Helvetica", pFontTable + 8); +00623 vFontname2Table((UCHAR *)"Helv", NULL, 1, 1, +00624 (UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE), +00625 "*", "Helvetica-Bold", pFontTable + 9); +00626 vFontname2Table((UCHAR *)"Helv", NULL, 1, 2, +00627 (UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE), +00628 "*", "Helvetica-Oblique", pFontTable + 10); +00629 vFontname2Table((UCHAR *)"Helv", NULL, 1, 3, +00630 (UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE), +00631 "*", "Helvetica-BoldOblique", pFontTable + 11); +00632 } +00633 +00634 /* Read the font translation file */ +00635 iItalic = 0; +00636 iBold = 0; +00637 iSpecial = 0; +00638 while (bReadFontFile(pFontTableFile, szWordFont, +00639 &iItalic, &iBold, szOurFont, &iSpecial)) { +00640 iEmphasis = 0; +00641 if (iBold != 0) { +00642 iEmphasis++; +00643 } +00644 if (iItalic != 0) { +00645 iEmphasis += 2; +00646 } +00647 pTmp = pFontTable + iEmphasis; +00648 iPos = 2; +00649 while (iPos + iOff < (int)tFontInfoLen) { +00650 iRecLen = (int)ucGetByte(iPos, aucBuffer); +00651 ucFFN = ucGetByte(iPos + 1, aucBuffer); +00652 aucFont = aucBuffer + iPos + iOff; +00653 vFontname2Table(aucFont, NULL, 1, iEmphasis, +00654 ucFFN, szWordFont, szOurFont, pTmp); +00655 pTmp += 4; +00656 iPos += iRecLen + 1; +00657 } +00658 } +00659 (void)fclose(pFontTableFile); +00660 aucBuffer = xfree(aucBuffer); +00661 vMinimizeFontTable(); +00662 } /* end of vCreate2FontTable */ +00663 +00664 /* +00665 * vCreate6FontTable - create a font table from Word 6/7 +00666 */ +00667 void +00668 vCreate6FontTable(FILE *pFile, ULONG ulStartBlock, +00669 const ULONG *aulBBD, size_t tBBDLen, +00670 const UCHAR *aucHeader) +00671 { +00672 FILE *pFontTableFile; +00673 font_table_type *pTmp; +00674 UCHAR *aucFont, *aucAltFont; +00675 UCHAR *aucBuffer; +00676 ULONG ulBeginFontInfo; +00677 size_t tFontInfoLen; +00678 int iPos, iRecLen, iOffsetAltName; +00679 int iBold, iItalic, iSpecial, iEmphasis; +00680 UCHAR ucFFN; +00681 char szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH]; +00682 +00683 fail(pFile == NULL || aucHeader == NULL); +00684 fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); +00685 fail(aulBBD == NULL); +00686 +00687 tFontTableRecords = 0; +00688 pFontTable = xfree(pFontTable); +00689 +00690 pFontTableFile = pOpenFontTableFile(); +00691 if (pFontTableFile == NULL) { +00692 /* No translation table file, no translation table */ +00693 return; +00694 } +00695 +00696 ulBeginFontInfo = ulGetLong(0xd0, aucHeader); /* fcSttbfffn */ +00697 DBG_HEX(ulBeginFontInfo); +00698 tFontInfoLen = (size_t)ulGetLong(0xd4, aucHeader); /* lcbSttbfffn */ +00699 DBG_DEC(tFontInfoLen); +00700 fail(tFontInfoLen < 9); +00701 +00702 aucBuffer = xmalloc(tFontInfoLen); +00703 if (!bReadBuffer(pFile, ulStartBlock, +00704 aulBBD, tBBDLen, BIG_BLOCK_SIZE, +00705 aucBuffer, ulBeginFontInfo, tFontInfoLen)) { +00706 aucBuffer = xfree(aucBuffer); +00707 (void)fclose(pFontTableFile); +00708 return; +00709 } +00710 DBG_DEC(usGetWord(0, aucBuffer)); +00711 +00712 /* Compute the maximum number of entries in the font table */ +00713 tFontTableRecords = 0; +00714 iPos = 2; +00715 while (iPos + 6 < (int)tFontInfoLen) { +00716 iRecLen = (int)ucGetByte(iPos, aucBuffer); +00717 NO_DBG_DEC(iRecLen); +00718 iOffsetAltName = (int)ucGetByte(iPos + 5, aucBuffer); +00719 NO_DBG_MSG(aucBuffer + iPos + 6); +00720 NO_DBG_MSG_C(iOffsetAltName > 0, +00721 aucBuffer + iPos + 6 + iOffsetAltName); +00722 iPos += iRecLen + 1; +00723 tFontTableRecords++; +00724 } +00725 tFontTableRecords *= 4; /* Plain, Bold, Italic and Bold/italic */ +00726 tFontTableRecords++; /* One extra for the table-font */ +00727 vCreateFontTable(); +00728 +00729 /* Read the font translation file */ +00730 iItalic = 0; +00731 iBold = 0; +00732 iSpecial = 0; +00733 while (bReadFontFile(pFontTableFile, szWordFont, +00734 &iItalic, &iBold, szOurFont, &iSpecial)) { +00735 iEmphasis = 0; +00736 if (iBold != 0) { +00737 iEmphasis++; +00738 } +00739 if (iItalic != 0) { +00740 iEmphasis += 2; +00741 } +00742 pTmp = pFontTable + iEmphasis; +00743 iPos = 2; +00744 while (iPos + 6 < (int)tFontInfoLen) { +00745 iRecLen = (int)ucGetByte(iPos, aucBuffer); +00746 ucFFN = ucGetByte(iPos + 1, aucBuffer); +00747 aucFont = aucBuffer + iPos + 6; +00748 iOffsetAltName = (int)ucGetByte(iPos + 5, aucBuffer); +00749 if (iOffsetAltName <= 0) { +00750 aucAltFont = NULL; +00751 } else { +00752 aucAltFont = aucFont + iOffsetAltName; +00753 NO_DBG_MSG(aucFont); +00754 NO_DBG_MSG(aucAltFont); +00755 } +00756 vFontname2Table(aucFont, aucAltFont, 1, iEmphasis, +00757 ucFFN, szWordFont, szOurFont, pTmp); +00758 pTmp += 4; +00759 iPos += iRecLen + 1; +00760 } +00761 } +00762 (void)fclose(pFontTableFile); +00763 aucBuffer = xfree(aucBuffer); +00764 vMinimizeFontTable(); +00765 } /* end of vCreate6FontTable */ +00766 +00767 /* +00768 * vCreate8FontTable - create a font table from Word 8/9/10 +00769 */ +00770 void +00771 vCreate8FontTable(FILE *pFile, const pps_info_type *pPPS, +00772 const ULONG *aulBBD, size_t tBBDLen, +00773 const ULONG *aulSBD, size_t tSBDLen, +00774 const UCHAR *aucHeader) +00775 { +00776 FILE *pFontTableFile; +00777 font_table_type *pTmp; +00778 const ULONG *aulBlockDepot; +00779 UCHAR *aucFont, *aucAltFont; +00780 UCHAR *aucBuffer; +00781 ULONG ulBeginFontInfo; +00782 size_t tFontInfoLen, tBlockDepotLen, tBlockSize; +00783 int iPos, iRecLen, iOffsetAltName; +00784 int iBold, iItalic, iSpecial, iEmphasis; +00785 UCHAR ucFFN; +00786 char szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH]; +00787 +00788 fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); +00789 fail(aulBBD == NULL || aulSBD == NULL); +00790 +00791 tFontTableRecords = 0; +00792 pFontTable = xfree(pFontTable); +00793 +00794 pFontTableFile = pOpenFontTableFile(); +00795 if (pFontTableFile == NULL) { +00796 /* No translation table file, no translation table */ +00797 return; +00798 } +00799 +00800 ulBeginFontInfo = ulGetLong(0x112, aucHeader); /* fcSttbfffn */ +00801 DBG_HEX(ulBeginFontInfo); +00802 tFontInfoLen = (size_t)ulGetLong(0x116, aucHeader); /* lcbSttbfffn */ +00803 DBG_DEC(tFontInfoLen); +00804 fail(tFontInfoLen < 46); +00805 +00806 DBG_DEC(pPPS->tTable.ulSB); +00807 DBG_HEX(pPPS->tTable.ulSize); +00808 if (pPPS->tTable.ulSize == 0) { +00809 DBG_MSG("No fontname table"); +00810 (void)fclose(pFontTableFile); +00811 return; +00812 } +00813 +00814 if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { +00815 /* Use the Small Block Depot */ +00816 aulBlockDepot = aulSBD; +00817 tBlockDepotLen = tSBDLen; +00818 tBlockSize = SMALL_BLOCK_SIZE; +00819 } else { +00820 /* Use the Big Block Depot */ +00821 aulBlockDepot = aulBBD; +00822 tBlockDepotLen = tBBDLen; +00823 tBlockSize = BIG_BLOCK_SIZE; +00824 } +00825 aucBuffer = xmalloc(tFontInfoLen); +00826 if (!bReadBuffer(pFile, pPPS->tTable.ulSB, +00827 aulBlockDepot, tBlockDepotLen, tBlockSize, +00828 aucBuffer, ulBeginFontInfo, tFontInfoLen)) { +00829 aucBuffer = xfree(aucBuffer); +00830 (void)fclose(pFontTableFile); +00831 return; +00832 } +00833 NO_DBG_PRINT_BLOCK(aucBuffer, tFontInfoLen); +00834 +00835 /* Get the maximum number of entries in the font table */ +00836 tFontTableRecords = (size_t)usGetWord(0, aucBuffer); +00837 tFontTableRecords *= 4; /* Plain, Bold, Italic and Bold/italic */ +00838 tFontTableRecords++; /* One extra for the table-font */ +00839 vCreateFontTable(); +00840 +00841 /* Read the font translation file */ +00842 iItalic = 0; +00843 iBold = 0; +00844 iSpecial = 0; +00845 while (bReadFontFile(pFontTableFile, szWordFont, +00846 &iItalic, &iBold, szOurFont, &iSpecial)) { +00847 iEmphasis = 0; +00848 if (iBold != 0) { +00849 iEmphasis++; +00850 } +00851 if (iItalic != 0) { +00852 iEmphasis += 2; +00853 } +00854 pTmp = pFontTable + iEmphasis; +00855 iPos = 4; +00856 while (iPos + 40 < (int)tFontInfoLen) { +00857 iRecLen = (int)ucGetByte(iPos, aucBuffer); +00858 ucFFN = ucGetByte(iPos + 1, aucBuffer); +00859 aucFont = aucBuffer + iPos + 40; +00860 iOffsetAltName = (int)unilen(aucFont); +00861 if (iPos + 40 + iOffsetAltName + 4 >= iRecLen) { +00862 aucAltFont = NULL; +00863 } else { +00864 aucAltFont = aucFont + iOffsetAltName + 2; +00865 NO_DBG_UNICODE(aucFont); +00866 NO_DBG_UNICODE(aucAltFont); +00867 } +00868 vFontname2Table(aucFont, aucAltFont, 2, iEmphasis, +00869 ucFFN, szWordFont, szOurFont, pTmp); +00870 pTmp += 4; +00871 iPos += iRecLen + 1; +00872 } +00873 } +00874 (void)fclose(pFontTableFile); +00875 aucBuffer = xfree(aucBuffer); +00876 vMinimizeFontTable(); +00877 } /* end of vCreate8FontTable */ +00878 +00879 /* +00880 * Destroy the internal font table by freeing its memory +00881 */ +00882 void +00883 vDestroyFontTable(void) +00884 { +00885 DBG_MSG("vDestroyFontTable"); +00886 +00887 tFontTableRecords = 0; +00888 pFontTable = xfree(pFontTable); +00889 } /* end of vDestroyFontTable */ +00890 +00891 /* +00892 * pGetNextFontTableRecord +00893 * +00894 * returns the next record in the table or NULL if there is no next record +00895 */ +00896 const font_table_type * +00897 pGetNextFontTableRecord(const font_table_type *pRecordCurr) +00898 { +00899 size_t tIndexCurr; +00900 +00901 if (pRecordCurr == NULL) { +00902 /* No current record, so start with the first one */ +00903 return &pFontTable[0]; +00904 } +00905 +00906 if (pRecordCurr < pFontTable || +00907 pRecordCurr >= pFontTable + tFontTableRecords) { +00908 /* Not a pointer in the array */ +00909 DBG_HEX(pRecordCurr); +00910 DBG_HEX(pFontTable); +00911 return NULL; +00912 } +00913 +00914 tIndexCurr = (size_t)(pRecordCurr - pFontTable); +00915 if (tIndexCurr + 1 < tFontTableRecords) { +00916 /* There is a next record, so return it */ +00917 return &pFontTable[tIndexCurr + 1]; +00918 } +00919 /* There is no next record */ +00920 return NULL; +00921 } /* end of pGetNextFontTableRecord */ +00922 +00923 /* +00924 * tGetFontTableLength +00925 * +00926 * returns the number of records in the internal font table +00927 */ +00928 size_t +00929 tGetFontTableLength(void) +00930 { +00931 return tFontTableRecords; +00932 } /* end of tGetFontTableLength */ +00933 +00934 #if !defined(__riscos) +00935 /* +00936 * vCorrect4PDF - only include PDF default fonts +00937 */ +00938 static void +00939 vCorrect4PDF(void) +00940 { +00941 font_table_type *pTmp; +00942 const char *szOurFont; +00943 +00944 for (pTmp = pFontTable; pTmp < pFontTable + tFontTableRecords; pTmp++) { +00945 if (STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_PLAIN) || +00946 STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_BOLD) || +00947 STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_ITALIC) || +00948 STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_BOLDITALIC) || +00949 STRCEQ(pTmp->szOurFontname, FONT_SERIF_PLAIN) || +00950 STRCEQ(pTmp->szOurFontname, FONT_SERIF_BOLD) || +00951 STRCEQ(pTmp->szOurFontname, FONT_SERIF_ITALIC) || +00952 STRCEQ(pTmp->szOurFontname, FONT_SERIF_BOLDITALIC) || +00953 STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_PLAIN) || +00954 STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_BOLD) || +00955 STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_ITALIC) || +00956 STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_BOLDITALIC)) { +00957 /* Already a default font */ +00958 continue; +00959 } +00960 szOurFont = +00961 szGetDefaultFont(pTmp->ucFFN, (int)pTmp->ucEmphasis); +00962 (void)strncpy(pTmp->szOurFontname, szOurFont, +00963 sizeof(pTmp->szOurFontname) - 1); +00964 pTmp->szOurFontname[sizeof(pTmp->szOurFontname) - 1] = '\0'; +00965 } +00966 } /* end of vCorrect4PDF */ +00967 +00968 /* +00969 * vCorrect4CyrPS - only include monospaced fonts +00970 */ +00971 static void +00972 vCorrect4CyrPS(void) +00973 { +00974 font_table_type *pTmp; +00975 const char *szOurFont; +00976 UCHAR ucFFN; +00977 +00978 ucFFN = (FAMILY_UNKNOWN << 4) | PITCH_FIXED; +00979 for (pTmp = pFontTable; pTmp < pFontTable + tFontTableRecords; pTmp++) { +00980 szOurFont = szGetDefaultFont(ucFFN, (int)pTmp->ucEmphasis); +00981 (void)strncpy(pTmp->szOurFontname, szOurFont, +00982 sizeof(pTmp->szOurFontname) - 1); +00983 pTmp->szOurFontname[sizeof(pTmp->szOurFontname) - 1] = '\0'; +00984 } +00985 } /* end of vCorrect4CyrPS */ +00986 #endif /* __riscos */ +00987 +00988 /* +00989 * vCorrectFontTable - correct the font table in special cases +00990 */ +00991 void +00992 vCorrectFontTable(conversion_type eConversionType, encoding_type eEncoding) +00993 { +00994 #if !defined(__riscos) +00995 if (eConversionType == conversion_pdf) { +00996 vCorrect4PDF(); +00997 } +00998 if (eConversionType == conversion_ps && +00999 eEncoding == encoding_cyrillic) { +01000 vCorrect4CyrPS(); +01001 } +01002 #endif /* __riscos */ +01003 } /* end of vCorrectFontTable */ +01004 +01005 /* +01006 * lComputeSpaceWidth - compute the width of a space character +01007 * +01008 * Returns the space width in millipoints +01009 */ +01010 long +01011 lComputeSpaceWidth(drawfile_fontref tFontRef, USHORT usFontSize) +01012 { +01013 char szSpace[] = " "; +01014 +01015 fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); +01016 +01017 return lComputeStringWidth(szSpace, 1, tFontRef, usFontSize); +01018 } /* end of lComputeSpaceWidth */ +