diff -r 59758314f811 -r d4524d6a4472 Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/fonts_8c_source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/fonts_8c_source.html Fri Jun 11 15:24:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1034 +0,0 @@ - - -
- -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 */ -