📄 stylesheet.c
字号:
/* * stylesheet.c * Copyright (C) 2001-2004 A.J. van Os; Released under GNU GPL * * Description: * Build, read and destroy a list of stylesheet information * */#include <string.h>#include "antiword.h"#define SGC_PAP 1#define SGC_CHP 2/* Variables needed to describe the stylesheet list */static style_block_type *atStyleInfo = NULL;static font_block_type *atFontInfo = NULL;static BOOL *abFilled = NULL;static size_t tStdCount = 0;/* * vDestroyStylesheetList - destroy the stylesheet list */voidvDestroyStylesheetList(void){ DBG_MSG("vDestroyStylesheetList"); tStdCount = 0; atStyleInfo = xfree(atStyleInfo); atFontInfo = xfree(atFontInfo); abFilled = xfree(abFilled);} /* end of vDestroyStylesheetList *//* * vGetDefaultStyle - fill the style struct with default values */static voidvGetDefaultStyle(style_block_type *pStyle){ (void)memset(pStyle, 0, sizeof(*pStyle)); pStyle->usIstd = ISTD_INVALID; pStyle->usIstdNext = ISTD_INVALID; pStyle->usStartAt = 1; pStyle->ucListLevel = 9;} /* end of vGetDefaultStyle *//* * vGetDefaultFont - fill the font struct with default values */static voidvGetDefaultFont(font_block_type *pFont, USHORT usDefaultFontNumber){ (void)memset(pFont, 0, sizeof(*pFont)); pFont->usFontSize = DEFAULT_FONT_SIZE; if (usDefaultFontNumber <= (USHORT)UCHAR_MAX) { pFont->ucFontNumber = (UCHAR)usDefaultFontNumber; } else { DBG_DEC(usDefaultFontNumber); DBG_FIXME(); pFont->ucFontNumber = 0; }} /* end of vGetDefaultFont *//* * iGetStyleIndex - get the index of the record with the specified istd * * returns the index when found, otherwise -1 */static intiGetStyleIndex(USHORT usIstd){ int iIndex; fail(abFilled == NULL); if (usIstd == ISTD_INVALID || abFilled == NULL) { return -1; } for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) { if (abFilled[iIndex] && atStyleInfo[iIndex].usIstd == usIstd) { /* The record is filled and the istd matches */ return iIndex; } } return -1;} /* end of iGetStyleIndex *//* * Get a build-in style for Winword 1/2 */static voidvGetBuildinStyle(UCHAR ucStc, style_block_type *pStyle){ fail(pStyle == NULL); /* Start with de defaults */ vGetDefaultStyle(pStyle); /* Add the build-in style info */ switch (ucStc) { case 246: case 247: case 248: case 249: case 250: case 255: pStyle->sLeftIndent = 720; break; case 251: case 252: pStyle->sLeftIndent = 360; break; case 253: pStyle->usBeforeIndent = 120; break; case 254: pStyle->usBeforeIndent = 240; break; default: if (ucStc >= 233 && ucStc <= 239) { pStyle->sLeftIndent = (239 - (short)ucStc) * 360; } if (ucStc >= 225 && ucStc <= 232) { pStyle->sLeftIndent = (232 - (short)ucStc) * 720; pStyle->sRightIndent = 720; } break; }} /* end of vGetBuildinStyle *//* * Get a build-in fontstyle for Winword 1/2 */static voidvGetBuildinFont(UCHAR ucStc, font_block_type *pFont){ fail(pFont == NULL); /* Start with de defaults */ vGetDefaultFont(pFont, 0); /* Add the build-in fontstyle info */ switch (ucStc) { case 223: case 244: pFont->usFontSize = 16; break; case 246: case 247: case 248: pFont->usFontStyle |= FONT_ITALIC; break; case 249: pFont->usFontStyle |= FONT_UNDERLINE; break; case 250: pFont->usFontStyle |= FONT_BOLD; break; case 251: pFont->usFontStyle |= FONT_UNDERLINE; pFont->usFontSize = 24; break; case 252: pFont->usFontStyle |= FONT_BOLD; pFont->usFontSize = 24; break; case 253: pFont->ucFontNumber = 2; pFont->usFontStyle |= FONT_BOLD; pFont->usFontSize = 24; break; case 254: pFont->ucFontNumber = 2; pFont->usFontStyle |= (FONT_BOLD|FONT_UNDERLINE); pFont->usFontSize = 24; break; default: break; }} /* end of vGetBuildinFont *//* * Convert a stylecode (stc) as used by WinWord 1/2 into a styleindex (istd) * as used by Word 6 and up */USHORTusStc2istd(UCHAR ucStc){ /* Old nil style to new nil style */ if (ucStc == 222) { return STI_NIL; } /* Heading 1 through 9 must become istd 1 through 9 */ /* so 254 through 246 must become 1 through 9 and vice versa */ if ((ucStc >= 1 && ucStc <= 9) || (ucStc >= 246 && ucStc <= 254)) { return 255 - (USHORT)ucStc; } return (USHORT)ucStc;} /* end of usStd2istd *//* * Build the lists with Stylesheet Information for WinWord 1/2 files */voidvGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader){ style_block_type *pStyle; font_block_type *pFont; UCHAR *aucBuffer; ULONG ulBeginStshInfo; size_t tStshInfoLen, tName, tChpx, tPapx, tMaxIndex; int iStIndex, iChpxIndex, iPapxIndex, iSt, iChpx, iPapx; int iStd, iIndex, iBaseStyleIndex, iCounter; USHORT usBaseStyle; UCHAR ucStc, ucStcNext, ucStcBase; fail(pFile == NULL || aucHeader == NULL); fail(iWordVersion != 1 && iWordVersion != 2); ulBeginStshInfo = ulGetLong(0x5e, aucHeader); /* fcStshf */ NO_DBG_HEX(ulBeginStshInfo); tStshInfoLen = (size_t)usGetWord(0x62, aucHeader); /* cbStshf */ NO_DBG_DEC(tStshInfoLen); aucBuffer = xmalloc(tStshInfoLen); if (!bReadBytes(aucBuffer, tStshInfoLen, ulBeginStshInfo, pFile)) { aucBuffer = xfree(aucBuffer); return; } NO_DBG_PRINT_BLOCK(aucBuffer, tStshInfoLen); fail(2 > tStshInfoLen); iStd = (int)usGetWord(0, aucBuffer); fail(2 + 2 > tStshInfoLen); tName = (size_t)usGetWord(2, aucBuffer); fail(2 + tName + 2 > tStshInfoLen); tChpx = (size_t)usGetWord(2 + tName, aucBuffer); fail(2 + tName + tChpx + 2 > tStshInfoLen); tPapx = (size_t)usGetWord(2 + tName + tChpx, aucBuffer); fail(2 + tName + tChpx + tPapx + 2 > tStshInfoLen); tStdCount = (size_t)usGetWord(2 + tName + tChpx + tPapx, aucBuffer); NO_DBG_HEX(tStdCount); atStyleInfo = xcalloc(tStdCount, sizeof(style_block_type)); atFontInfo = xcalloc(tStdCount, sizeof(font_block_type)); abFilled = xcalloc(tStdCount, sizeof(BOOL)); do { iCounter = 0; iStIndex = 2 + 2; iChpxIndex = 2 + (int)tName + 2; iPapxIndex = 2 + (int)tName + (int)tChpx + 2; tMaxIndex = 2 + tName + tChpx + tPapx + 2; /* Read the styles one-by-one */ for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) { pStyle = &atStyleInfo[iIndex]; pFont = &atFontInfo[iIndex]; iSt = (int)ucGetByte(iStIndex, aucBuffer); iChpx = (int)ucGetByte(iChpxIndex, aucBuffer); iPapx = (int)ucGetByte(iPapxIndex, aucBuffer); NO_DBG_HEX(iSt); NO_DBG_HEX(iChpx); NO_DBG_HEX(iPapx); if (iSt == 0xff || tMaxIndex + 1 >= tStshInfoLen) { /* Undefined style or no information */ iStIndex++; iChpxIndex++; iPapxIndex++; tMaxIndex += 2; if (!abFilled[iIndex]) { DBG_HEX_C(iChpx != 0xff, iChpx); DBG_HEX_C(iPapx != 0xff, iPapx); vGetDefaultStyle(pStyle); vGetDefaultFont(pFont, 0); abFilled[iIndex] = TRUE; } continue; } NO_DBG_STRN(aucBuffer + iStIndex + 1, iSt); iStIndex += iSt + 1; ucStcNext = ucGetByte(tMaxIndex, aucBuffer); ucStcBase = ucGetByte(tMaxIndex + 1, aucBuffer); ucStc = (UCHAR)((iIndex - iStd) & 0xff); NO_DBG_DEC(ucStc); if (iChpx == 0xff || iPapx == 0xff) { /* Use a build-in style */ iChpxIndex++; iPapxIndex++; tMaxIndex += 2; if (!abFilled[iIndex]) { DBG_HEX_C(iChpx != 0xff, iChpx); DBG_HEX_C(iPapx != 0xff, iPapx); vGetBuildinStyle(ucStc, pStyle); pStyle->usIstd = usStc2istd(ucStc); pStyle->usIstdNext = usStc2istd(ucStcNext); vGetBuildinFont(ucStc, pFont); abFilled[iIndex] = TRUE; } continue; } if (abFilled[iIndex]) { /* This record has already been filled */ iChpxIndex += iChpx + 1; iPapxIndex += iPapx + 1; tMaxIndex += 2; continue; } usBaseStyle = usStc2istd(ucStcBase); if (usBaseStyle == STI_NIL) { /* Based on the Nil style */ vGetDefaultStyle(pStyle); vGetDefaultFont(pFont, 0); } else { iBaseStyleIndex = iGetStyleIndex(usBaseStyle); NO_DBG_DEC(iBaseStyleIndex); if (iBaseStyleIndex < 0) { /* This style is not known yet */ iChpxIndex += iChpx + 1; iPapxIndex += iPapx + 1; tMaxIndex += 2; continue; } fail(iBaseStyleIndex >= (int)tStdCount); fail(!abFilled[iBaseStyleIndex]); /* Based on the specified base style */ *pStyle = atStyleInfo[iBaseStyleIndex]; *pFont = atFontInfo[iBaseStyleIndex]; } pStyle->usIstd = usStc2istd(ucStc); pStyle->usIstdNext = usStc2istd(ucStcNext); abFilled[iIndex] = TRUE; iCounter++; /* Add the changes if any */ switch (iChpx) { case 0x00: case 0xff: iChpxIndex++; break; default: NO_DBG_PRINT_BLOCK(aucBuffer + iChpxIndex + 1, iChpx); if (iWordVersion == 1) { vGet1FontInfo(0, aucBuffer + iChpxIndex + 1, (size_t)iChpx, pFont); } else { vGet2FontInfo(0, aucBuffer + iChpxIndex + 1, (size_t)iChpx, pFont); } iChpxIndex += iChpx + 1; break; } switch (iPapx) { case 0x00: case 0xff: iPapxIndex++; break; default: NO_DBG_PRINT_BLOCK(aucBuffer + iPapxIndex + 8, iPapx - 7); vGet2StyleInfo(0, aucBuffer + iPapxIndex + 8, iPapx - 7, pStyle); iPapxIndex += iPapx + 1; break; } tMaxIndex += 2; } NO_DBG_DEC(iCounter); } while (iCounter > 0); /* Fill records that are still empty */ for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) { if (!abFilled[iIndex]) { NO_DBG_DEC(iIndex); vGetDefaultStyle(&atStyleInfo[iIndex]); vGetDefaultFont(&atFontInfo[iIndex], 0); } } /* Clean up before you leave */ abFilled = xfree(abFilled); aucBuffer = xfree(aucBuffer);} /* end of vGet2Stylesheet *//* * Build the lists with Stylesheet Information for Word 6/7 files */voidvGet6Stylesheet(FILE *pFile, ULONG ulStartBlock, const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader){ style_block_type *pStyle; font_block_type *pFont; UCHAR *aucBuffer; ULONG ulBeginStshInfo; size_t tStshInfoLen, tOffset, tStdLen, tStdBaseInFile;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -