00001
00002
00003
00004
00005
00006
00007
00008
00009 #include <ctype.h>
00010 #include <string.h>
00011 #include "antiword.h"
00012
00013
00014 #define FONT_LINE_LENGTH 81
00015
00016
00017 #define PITCH_UNKNOWN 0
00018 #define PITCH_FIXED 1
00019 #define PITCH_VARIABLE 2
00020
00021
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
00030 static size_t tFontTableRecords = 0;
00031 static font_table_type *pFontTable = NULL;
00032
00033
00034
00035
00036
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 }
00054
00055
00056
00057
00058
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 }
00068
00069
00070
00071
00072
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 }
00087
00088
00089
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
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
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
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
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 }
00136
00137
00138
00139
00140
00141
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 }
00162
00163
00164
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
00194
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 }
00229
00230
00231
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
00245 pFontTable = xcalloc(tFontTableRecords, sizeof(*pFontTable));
00246
00247
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 }
00271
00272
00273
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
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
00307
00308
00309
00310
00311 pFontTable[0].ucInUse = 1;
00312
00313
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
00328 bMustAddTableFont = FALSE;
00329 }
00330 pTmp->ucInUse = 1;
00331 }
00332
00333
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
00350 bMustAddTableFont = FALSE;
00351 }
00352 pTmp->ucInUse = 1;
00353 }
00354
00355
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
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
00401 }
00402
00403
00404
00405
00406
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
00452 return TRUE;
00453 }
00454 return FALSE;
00455 }
00456
00457
00458
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
00476 return;
00477 }
00478
00479
00480 tFontTableRecords = 64;
00481 tFontTableRecords *= 4;
00482 tFontTableRecords++;
00483 vCreateFontTable();
00484
00485
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 }
00518
00519
00520
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
00545 return;
00546 }
00547
00548 ulBeginFontInfo = ulGetLong(0xb2, aucHeader);
00549 DBG_HEX(ulBeginFontInfo);
00550 tFontInfoLen = (size_t)usGetWord(0xb6, aucHeader);
00551 DBG_DEC(tFontInfoLen);
00552
00553 if (ulBeginFontInfo > (ULONG)LONG_MAX || tFontInfoLen == 0) {
00554
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
00570 if (iWordVersion == 1) {
00571 fail(tFontInfoLen < 2);
00572
00573 tFontTableRecords = 3;
00574 iOff = 2;
00575 } else {
00576 fail(tFontInfoLen < 6);
00577
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;
00590 tFontTableRecords++;
00591 vCreateFontTable();
00592
00593
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
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 }
00663
00664
00665
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
00693 return;
00694 }
00695
00696 ulBeginFontInfo = ulGetLong(0xd0, aucHeader);
00697 DBG_HEX(ulBeginFontInfo);
00698 tFontInfoLen = (size_t)ulGetLong(0xd4, aucHeader);
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
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;
00726 tFontTableRecords++;
00727 vCreateFontTable();
00728
00729
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 }
00766
00767
00768
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
00797 return;
00798 }
00799
00800 ulBeginFontInfo = ulGetLong(0x112, aucHeader);
00801 DBG_HEX(ulBeginFontInfo);
00802 tFontInfoLen = (size_t)ulGetLong(0x116, aucHeader);
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
00816 aulBlockDepot = aulSBD;
00817 tBlockDepotLen = tSBDLen;
00818 tBlockSize = SMALL_BLOCK_SIZE;
00819 } else {
00820
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
00836 tFontTableRecords = (size_t)usGetWord(0, aucBuffer);
00837 tFontTableRecords *= 4;
00838 tFontTableRecords++;
00839 vCreateFontTable();
00840
00841
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 }
00878
00879
00880
00881
00882 void
00883 vDestroyFontTable(void)
00884 {
00885 DBG_MSG("vDestroyFontTable");
00886
00887 tFontTableRecords = 0;
00888 pFontTable = xfree(pFontTable);
00889 }
00890
00891
00892
00893
00894
00895
00896 const font_table_type *
00897 pGetNextFontTableRecord(const font_table_type *pRecordCurr)
00898 {
00899 size_t tIndexCurr;
00900
00901 if (pRecordCurr == NULL) {
00902
00903 return &pFontTable[0];
00904 }
00905
00906 if (pRecordCurr < pFontTable ||
00907 pRecordCurr >= pFontTable + tFontTableRecords) {
00908
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
00917 return &pFontTable[tIndexCurr + 1];
00918 }
00919
00920 return NULL;
00921 }
00922
00923
00924
00925
00926
00927
00928 size_t
00929 tGetFontTableLength(void)
00930 {
00931 return tFontTableRecords;
00932 }
00933
00934 #if !defined(__riscos)
00935
00936
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
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 }
00967
00968
00969
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 }
00986 #endif
00987
00988
00989
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
01003 }
01004
01005
01006
01007
01008
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 }