📄 fonts.c
字号:
vFontname2Table(aucFont, NULL, 1, iEmphasis, ucFFN, szWordFont, szOurFont, pTmp); } } (void)fclose(pFontTableFile); vMinimizeFontTable();} /* end of vCreate0FontTable *//* * vCreate2FontTable - create a font table from WinWord 1/2 */voidvCreate2FontTable(FILE *pFile, int iWordVersion, const UCHAR *aucHeader){ FILE *pFontTableFile; font_table_type *pTmp; UCHAR *aucFont; UCHAR *aucBuffer; ULONG ulBeginFontInfo; size_t tFontInfoLen; int iPos, iOff, iRecLen; int iBold, iItalic, iSpecial, iEmphasis; UCHAR ucFFN; char szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH]; fail(pFile == NULL || aucHeader == NULL); fail(iWordVersion != 1 && iWordVersion != 2); tFontTableRecords = 0; pFontTable = xfree(pFontTable); pFontTableFile = pOpenFontTableFile(); if (pFontTableFile == NULL) { /* No translation table file, no translation table */ return; } ulBeginFontInfo = ulGetLong(0xb2, aucHeader); /* fcSttbfffn */ DBG_HEX(ulBeginFontInfo); tFontInfoLen = (size_t)usGetWord(0xb6, aucHeader); /* cbSttbfffn */ DBG_DEC(tFontInfoLen); if (ulBeginFontInfo > (ULONG)LONG_MAX || tFontInfoLen == 0) { /* Don't ask me why this is needed */ DBG_HEX_C(tFontInfoLen != 0, ulBeginFontInfo); (void)fclose(pFontTableFile); return; } aucBuffer = xmalloc(tFontInfoLen); if (!bReadBytes(aucBuffer, tFontInfoLen, ulBeginFontInfo, pFile)) { aucBuffer = xfree(aucBuffer); (void)fclose(pFontTableFile); return; } NO_DBG_PRINT_BLOCK(aucBuffer, tFontInfoLen); DBG_DEC(usGetWord(0, aucBuffer)); /* Compute the maximum number of entries in the font table */ if (iWordVersion == 1) { fail(tFontInfoLen < 2); /* WinWord 1 has three implicit fonts */ tFontTableRecords = 3; iOff = 2; } else { fail(tFontInfoLen < 6); /* WinWord 2 and up have no implicit fonts */ tFontTableRecords = 0; iOff = 3; } iPos = 2; while (iPos + iOff < (int)tFontInfoLen) { iRecLen = (int)ucGetByte(iPos, aucBuffer); NO_DBG_DEC(iRecLen); NO_DBG_MSG(aucBuffer + iPos + iOff); iPos += iRecLen + 1; tFontTableRecords++; } tFontTableRecords *= 4; /* Plain, Bold, Italic and Bold/Italic */ tFontTableRecords++; /* One extra for the table-font */ vCreateFontTable(); /* Add the tree implicit fonts (in four variations) */ if (iWordVersion == 1) { fail(tFontTableRecords < 13); vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 0, (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), "*", "Times-Roman", pFontTable + 0); vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 1, (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), "*", "Times-Bold", pFontTable + 1); vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 2, (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), "*", "Times-Italic", pFontTable + 2); vFontname2Table((UCHAR *)"Tms Rmn", NULL, 1, 3, (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), "*", "Times-BoldItalic", pFontTable + 3); vFontname2Table((UCHAR *)"Symbol", NULL, 1, 0, (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), "*", "Times-Roman", pFontTable + 4); vFontname2Table((UCHAR *)"Symbol", NULL, 1, 1, (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), "*", "Times-Bold", pFontTable + 5); vFontname2Table((UCHAR *)"Symbol", NULL, 1, 2, (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), "*", "Times-Italic", pFontTable + 6); vFontname2Table((UCHAR *)"Symbol", NULL, 1, 3, (UCHAR)((FAMILY_ROMAN << 4) | PITCH_VARIABLE), "*", "Times-BoldItalic", pFontTable + 7); vFontname2Table((UCHAR *)"Helv", NULL, 1, 0, (UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE), "*", "Helvetica", pFontTable + 8); vFontname2Table((UCHAR *)"Helv", NULL, 1, 1, (UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE), "*", "Helvetica-Bold", pFontTable + 9); vFontname2Table((UCHAR *)"Helv", NULL, 1, 2, (UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE), "*", "Helvetica-Oblique", pFontTable + 10); vFontname2Table((UCHAR *)"Helv", NULL, 1, 3, (UCHAR)((FAMILY_SWISS << 4) | PITCH_VARIABLE), "*", "Helvetica-BoldOblique", pFontTable + 11); } /* Read the font translation file */ iItalic = 0; iBold = 0; iSpecial = 0; while (bReadFontFile(pFontTableFile, szWordFont, &iItalic, &iBold, szOurFont, &iSpecial)) { iEmphasis = 0; if (iBold != 0) { iEmphasis++; } if (iItalic != 0) { iEmphasis += 2; } pTmp = pFontTable + iEmphasis; iPos = 2; while (iPos + iOff < (int)tFontInfoLen) { iRecLen = (int)ucGetByte(iPos, aucBuffer); ucFFN = ucGetByte(iPos + 1, aucBuffer); aucFont = aucBuffer + iPos + iOff; vFontname2Table(aucFont, NULL, 1, iEmphasis, ucFFN, szWordFont, szOurFont, pTmp); pTmp += 4; iPos += iRecLen + 1; } } (void)fclose(pFontTableFile); aucBuffer = xfree(aucBuffer); vMinimizeFontTable();} /* end of vCreate2FontTable *//* * vCreate6FontTable - create a font table from Word 6/7 */voidvCreate6FontTable(FILE *pFile, ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader){ FILE *pFontTableFile; font_table_type *pTmp; UCHAR *aucFont, *aucAltFont; UCHAR *aucBuffer; ULONG ulBeginFontInfo; size_t tFontInfoLen; int iPos, iRecLen, iOffsetAltName; int iBold, iItalic, iSpecial, iEmphasis; UCHAR ucFFN; char szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH]; fail(pFile == NULL || aucHeader == NULL); fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN); fail(aulBBD == NULL); tFontTableRecords = 0; pFontTable = xfree(pFontTable); pFontTableFile = pOpenFontTableFile(); if (pFontTableFile == NULL) { /* No translation table file, no translation table */ return; } ulBeginFontInfo = ulGetLong(0xd0, aucHeader); /* fcSttbfffn */ DBG_HEX(ulBeginFontInfo); tFontInfoLen = (size_t)ulGetLong(0xd4, aucHeader); /* lcbSttbfffn */ DBG_DEC(tFontInfoLen); fail(tFontInfoLen < 9); aucBuffer = xmalloc(tFontInfoLen); if (!bReadBuffer(pFile, ulStartBlock, aulBBD, tBBDLen, BIG_BLOCK_SIZE, aucBuffer, ulBeginFontInfo, tFontInfoLen)) { aucBuffer = xfree(aucBuffer); (void)fclose(pFontTableFile); return; } DBG_DEC(usGetWord(0, aucBuffer)); /* Compute the maximum number of entries in the font table */ tFontTableRecords = 0; iPos = 2; while (iPos + 6 < (int)tFontInfoLen) { iRecLen = (int)ucGetByte(iPos, aucBuffer); NO_DBG_DEC(iRecLen); iOffsetAltName = (int)ucGetByte(iPos + 5, aucBuffer); NO_DBG_MSG(aucBuffer + iPos + 6); NO_DBG_MSG_C(iOffsetAltName > 0, aucBuffer + iPos + 6 + iOffsetAltName); iPos += iRecLen + 1; tFontTableRecords++; } tFontTableRecords *= 4; /* Plain, Bold, Italic and Bold/italic */ tFontTableRecords++; /* One extra for the table-font */ vCreateFontTable(); /* Read the font translation file */ iItalic = 0; iBold = 0; iSpecial = 0; while (bReadFontFile(pFontTableFile, szWordFont, &iItalic, &iBold, szOurFont, &iSpecial)) { iEmphasis = 0; if (iBold != 0) { iEmphasis++; } if (iItalic != 0) { iEmphasis += 2; } pTmp = pFontTable + iEmphasis; iPos = 2; while (iPos + 6 < (int)tFontInfoLen) { iRecLen = (int)ucGetByte(iPos, aucBuffer); ucFFN = ucGetByte(iPos + 1, aucBuffer); aucFont = aucBuffer + iPos + 6; iOffsetAltName = (int)ucGetByte(iPos + 5, aucBuffer); if (iOffsetAltName <= 0) { aucAltFont = NULL; } else { aucAltFont = aucFont + iOffsetAltName; NO_DBG_MSG(aucFont); NO_DBG_MSG(aucAltFont); } vFontname2Table(aucFont, aucAltFont, 1, iEmphasis, ucFFN, szWordFont, szOurFont, pTmp); pTmp += 4; iPos += iRecLen + 1; } } (void)fclose(pFontTableFile); aucBuffer = xfree(aucBuffer); vMinimizeFontTable();} /* end of vCreate6FontTable *//* * vCreate8FontTable - create a font table from Word 8/9/10 */voidvCreate8FontTable(FILE *pFile, const pps_info_type *pPPS, const ULONG *aulBBD, size_t tBBDLen, const ULONG *aulSBD, size_t tSBDLen, const UCHAR *aucHeader){ FILE *pFontTableFile; font_table_type *pTmp; const ULONG *aulBlockDepot; UCHAR *aucFont, *aucAltFont; UCHAR *aucBuffer; ULONG ulBeginFontInfo; size_t tFontInfoLen, tBlockDepotLen, tBlockSize; int iPos, iRecLen, iOffsetAltName; int iBold, iItalic, iSpecial, iEmphasis; UCHAR ucFFN; char szWordFont[FONT_LINE_LENGTH], szOurFont[FONT_LINE_LENGTH]; fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); fail(aulBBD == NULL || aulSBD == NULL); tFontTableRecords = 0; pFontTable = xfree(pFontTable); pFontTableFile = pOpenFontTableFile(); if (pFontTableFile == NULL) { /* No translation table file, no translation table */ return; } ulBeginFontInfo = ulGetLong(0x112, aucHeader); /* fcSttbfffn */ DBG_HEX(ulBeginFontInfo); tFontInfoLen = (size_t)ulGetLong(0x116, aucHeader); /* lcbSttbfffn */ DBG_DEC(tFontInfoLen); fail(tFontInfoLen < 46); DBG_DEC(pPPS->tTable.ulSB); DBG_HEX(pPPS->tTable.ulSize); if (pPPS->tTable.ulSize == 0) { DBG_MSG("No fontname table"); (void)fclose(pFontTableFile); return; } if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { /* Use the Small Block Depot */ aulBlockDepot = aulSBD; tBlockDepotLen = tSBDLen; tBlockSize = SMALL_BLOCK_SIZE; } else { /* Use the Big Block Depot */ aulBlockDepot = aulBBD; tBlockDepotLen = tBBDLen; tBlockSize = BIG_BLOCK_SIZE; } aucBuffer = xmalloc(tFontInfoLen); if (!bReadBuffer(pFile, pPPS->tTable.ulSB, aulBlockDepot, tBlockDepotLen, tBlockSize, aucBuffer, ulBeginFontInfo, tFontInfoLen)) { aucBuffer = xfree(aucBuffer); (void)fclose(pFontTableFile); return; } NO_DBG_PRINT_BLOCK(aucBuffer, tFontInfoLen); /* Get the maximum number of entries in the font table */ tFontTableRecords = (size_t)usGetWord(0, aucBuffer); tFontTableRecords *= 4; /* Plain, Bold, Italic and Bold/italic */ tFontTableRecords++; /* One extra for the table-font */ vCreateFontTable(); /* Read the font translation file */ iItalic = 0; iBold = 0; iSpecial = 0; while (bReadFontFile(pFontTableFile, szWordFont, &iItalic, &iBold, szOurFont, &iSpecial)) { iEmphasis = 0; if (iBold != 0) { iEmphasis++; } if (iItalic != 0) { iEmphasis += 2; } pTmp = pFontTable + iEmphasis; iPos = 4; while (iPos + 40 < (int)tFontInfoLen) { iRecLen = (int)ucGetByte(iPos, aucBuffer); ucFFN = ucGetByte(iPos + 1, aucBuffer); aucFont = aucBuffer + iPos + 40; iOffsetAltName = (int)unilen(aucFont); if (iPos + 40 + iOffsetAltName + 4 >= iRecLen) { aucAltFont = NULL; } else { aucAltFont = aucFont + iOffsetAltName + 2; NO_DBG_UNICODE(aucFont); NO_DBG_UNICODE(aucAltFont); } vFontname2Table(aucFont, aucAltFont, 2, iEmphasis, ucFFN, szWordFont, szOurFont, pTmp); pTmp += 4; iPos += iRecLen + 1; } } (void)fclose(pFontTableFile); aucBuffer = xfree(aucBuffer); vMinimizeFontTable();} /* end of vCreate8FontTable *//* * Destroy the internal font table by freeing its memory */voidvDestroyFontTable(void){ DBG_MSG("vDestroyFontTable"); tFontTableRecords = 0; pFontTable = xfree(pFontTable);} /* end of vDestroyFontTable *//* * pGetNextFontTableRecord * * returns the next record in the table or NULL if there is no next record */const font_table_type *pGetNextFontTableRecord(const font_table_type *pRecordCurr){ size_t tIndexCurr; if (pRecordCurr == NULL) { /* No current record, so start with the first one */ return &pFontTable[0]; } if (pRecordCurr < pFontTable || pRecordCurr >= pFontTable + tFontTableRecords) { /* Not a pointer in the array */ DBG_HEX(pRecordCurr); DBG_HEX(pFontTable); return NULL; } tIndexCurr = (size_t)(pRecordCurr - pFontTable); if (tIndexCurr + 1 < tFontTableRecords) { /* There is a next record, so return it */ return &pFontTable[tIndexCurr + 1]; } /* There is no next record */ return NULL;} /* end of pGetNextFontTableRecord *//* * tGetFontTableLength * * returns the number of records in the internal font table */size_ttGetFontTableLength(void){ return tFontTableRecords;} /* end of tGetFontTableLength */#if !defined(__riscos)/* * vCorrect4PDF - only include PDF default fonts */static voidvCorrect4PDF(void){ font_table_type *pTmp; const char *szOurFont; for (pTmp = pFontTable; pTmp < pFontTable + tFontTableRecords; pTmp++) { if (STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_PLAIN) || STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_BOLD) || STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_ITALIC) || STRCEQ(pTmp->szOurFontname, FONT_MONOSPACED_BOLDITALIC) || STRCEQ(pTmp->szOurFontname, FONT_SERIF_PLAIN) || STRCEQ(pTmp->szOurFontname, FONT_SERIF_BOLD) || STRCEQ(pTmp->szOurFontname, FONT_SERIF_ITALIC) || STRCEQ(pTmp->szOurFontname, FONT_SERIF_BOLDITALIC) || STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_PLAIN) || STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_BOLD) || STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_ITALIC) || STRCEQ(pTmp->szOurFontname, FONT_SANS_SERIF_BOLDITALIC)) { /* Already a default font */ continue; } szOurFont = szGetDefaultFont(pTmp->ucFFN, (int)pTmp->ucEmphasis); (void)strncpy(pTmp->szOurFontname, szOurFont, sizeof(pTmp->szOurFontname) - 1); pTmp->szOurFontname[sizeof(pTmp->szOurFontname) - 1] = '\0'; }} /* end of vCorrect4PDF *//* * vCorrect4CyrPS - only include monospaced fonts */static voidvCorrect4CyrPS(void){ font_table_type *pTmp; const char *szOurFont; UCHAR ucFFN; ucFFN = (FAMILY_UNKNOWN << 4) | PITCH_FIXED; for (pTmp = pFontTable; pTmp < pFontTable + tFontTableRecords; pTmp++) { szOurFont = szGetDefaultFont(ucFFN, (int)pTmp->ucEmphasis); (void)strncpy(pTmp->szOurFontname, szOurFont, sizeof(pTmp->szOurFontname) - 1); pTmp->szOurFontname[sizeof(pTmp->szOurFontname) - 1] = '\0'; }} /* end of vCorrect4CyrPS */#endif /* __riscos *//* * vCorrectFontTable - correct the font table in special cases */voidvCorrectFontTable(conversion_type eConversionType, encoding_type eEncoding){#if !defined(__riscos) if (eConversionType == conversion_pdf) { vCorrect4PDF(); } if (eConversionType == conversion_ps && eEncoding == encoding_cyrillic) { vCorrect4CyrPS(); }#endif /* __riscos */} /* end of vCorrectFontTable *//* * lComputeSpaceWidth - compute the width of a space character * * Returns the space width in millipoints */longlComputeSpaceWidth(drawfile_fontref tFontRef, USHORT usFontSize){ char szSpace[] = " "; fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE); return lComputeStringWidth(szSpace, 1, tFontRef, usFontSize);} /* end of lComputeSpaceWidth */
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -