examples/PIPS/antiword/src/stylesheet.c

00001 /*
00002  * stylesheet.c
00003  * Copyright (C) 2001-2004 A.J. van Os; Released under GNU GPL
00004  *
00005  * Description:
00006  * Build, read and destroy a list of stylesheet information
00007  *
00008  */
00009 
00010 #include <string.h>
00011 #include "antiword.h"
00012 
00013 
00014 #define SGC_PAP         1
00015 #define SGC_CHP         2
00016 
00017 /* Variables needed to describe the stylesheet list */
00018 static style_block_type *atStyleInfo = NULL;
00019 static font_block_type  *atFontInfo = NULL;
00020 static BOOL             *abFilled = NULL;
00021 static size_t           tStdCount = 0;
00022 
00023 
00024 /*
00025  * vDestroyStylesheetList - destroy the stylesheet list
00026  */
00027 void
00028 vDestroyStylesheetList(void)
00029 {
00030         DBG_MSG("vDestroyStylesheetList");
00031 
00032         tStdCount = 0;
00033         atStyleInfo = xfree(atStyleInfo);
00034         atFontInfo = xfree(atFontInfo);
00035         abFilled = xfree(abFilled);
00036 } /* end of vDestroyStylesheetList */
00037 
00038 /*
00039  * vGetDefaultStyle - fill the style struct with default values
00040  */
00041 static void
00042 vGetDefaultStyle(style_block_type *pStyle)
00043 {
00044         (void)memset(pStyle, 0, sizeof(*pStyle));
00045         pStyle->usIstd = ISTD_INVALID;
00046         pStyle->usIstdNext = ISTD_INVALID;
00047         pStyle->usStartAt = 1;
00048         pStyle->ucListLevel = 9;
00049 } /* end of vGetDefaultStyle */
00050 
00051 /*
00052  * vGetDefaultFont - fill the font struct with default values
00053  */
00054 static void
00055 vGetDefaultFont(font_block_type *pFont, USHORT usDefaultFontNumber)
00056 {
00057         (void)memset(pFont, 0, sizeof(*pFont));
00058         pFont->usFontSize = DEFAULT_FONT_SIZE;
00059         if (usDefaultFontNumber <= (USHORT)UCHAR_MAX) {
00060                 pFont->ucFontNumber = (UCHAR)usDefaultFontNumber;
00061         } else {
00062                 DBG_DEC(usDefaultFontNumber);
00063                 DBG_FIXME();
00064                 pFont->ucFontNumber = 0;
00065         }
00066 } /* end of vGetDefaultFont */
00067 
00068 /*
00069  * iGetStyleIndex - get the index of the record with the specified istd
00070  *
00071  * returns the index when found, otherwise -1
00072  */
00073 static int
00074 iGetStyleIndex(USHORT usIstd)
00075 {
00076         int     iIndex;
00077 
00078         fail(abFilled == NULL);
00079 
00080         if (usIstd == ISTD_INVALID || abFilled == NULL) {
00081                 return -1;
00082         }
00083 
00084         for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) {
00085                 if (abFilled[iIndex] && atStyleInfo[iIndex].usIstd == usIstd) {
00086                         /* The record is filled and the istd matches */
00087                         return iIndex;
00088                 }
00089         }
00090         return -1;
00091 } /* end of iGetStyleIndex */
00092 
00093 /*
00094  * Get a build-in style for Winword 1/2
00095  */
00096 static void
00097 vGetBuildinStyle(UCHAR ucStc, style_block_type *pStyle)
00098 {
00099         fail(pStyle == NULL);
00100 
00101         /* Start with de defaults */
00102         vGetDefaultStyle(pStyle);
00103 
00104         /* Add the build-in style info */
00105         switch (ucStc) {
00106         case 246:
00107         case 247:
00108         case 248:
00109         case 249:
00110         case 250:
00111         case 255:
00112                 pStyle->sLeftIndent = 720;
00113                 break;
00114         case 251:
00115         case 252:
00116                 pStyle->sLeftIndent = 360;
00117                 break;
00118         case 253:
00119                 pStyle->usBeforeIndent = 120;
00120                 break;
00121         case 254:
00122                 pStyle->usBeforeIndent = 240;
00123                 break;
00124         default:
00125                 if (ucStc >= 233 && ucStc <= 239) {
00126                         pStyle->sLeftIndent = (239 - (short)ucStc) * 360;
00127                 }
00128                 if (ucStc >= 225 && ucStc <= 232) {
00129                         pStyle->sLeftIndent = (232 - (short)ucStc) * 720;
00130                         pStyle->sRightIndent = 720;
00131                 }
00132                 break;
00133         }
00134 } /* end of vGetBuildinStyle */
00135 
00136 /*
00137  * Get a build-in fontstyle for Winword 1/2
00138  */
00139 static void
00140 vGetBuildinFont(UCHAR ucStc, font_block_type *pFont)
00141 {
00142         fail(pFont == NULL);
00143 
00144         /* Start with de defaults */
00145         vGetDefaultFont(pFont, 0);
00146 
00147         /* Add the build-in fontstyle info */
00148         switch (ucStc) {
00149         case 223:
00150         case 244:
00151                 pFont->usFontSize = 16;
00152                 break;
00153         case 246:
00154         case 247:
00155         case 248:
00156                 pFont->usFontStyle |= FONT_ITALIC;
00157                 break;
00158         case 249:
00159                 pFont->usFontStyle |= FONT_UNDERLINE;
00160                 break;
00161         case 250:
00162                 pFont->usFontStyle |= FONT_BOLD;
00163                 break;
00164         case 251:
00165                 pFont->usFontStyle |= FONT_UNDERLINE;
00166                 pFont->usFontSize = 24;
00167                 break;
00168         case 252:
00169                 pFont->usFontStyle |= FONT_BOLD;
00170                 pFont->usFontSize = 24;
00171                 break;
00172         case 253:
00173                 pFont->ucFontNumber = 2;
00174                 pFont->usFontStyle |= FONT_BOLD;
00175                 pFont->usFontSize = 24;
00176                 break;
00177         case 254:
00178                 pFont->ucFontNumber = 2;
00179                 pFont->usFontStyle |= (FONT_BOLD|FONT_UNDERLINE);
00180                 pFont->usFontSize = 24;
00181                 break;
00182         default:
00183                 break;
00184         }
00185 } /* end of vGetBuildinFont */
00186 
00187 /*
00188  * Convert a stylecode (stc) as used by WinWord 1/2 into a styleindex (istd)
00189  * as used by Word 6 and up
00190  */
00191 USHORT
00192 usStc2istd(UCHAR ucStc)
00193 {
00194         /* Old nil style to new nil style */
00195         if (ucStc == 222) {
00196                 return STI_NIL;
00197         }
00198 
00199         /* Heading 1 through 9 must become istd 1 through 9 */
00200         /* so 254 through 246 must become 1 through 9 and vice versa */
00201         if ((ucStc >= 1 && ucStc <= 9) ||
00202             (ucStc >= 246 && ucStc <= 254)) {
00203                 return 255 - (USHORT)ucStc;
00204         }
00205         return (USHORT)ucStc;
00206 } /* end of usStd2istd */
00207 
00208 /*
00209  * Build the lists with Stylesheet Information for WinWord 1/2 files
00210  */
00211 void
00212 vGet2Stylesheet(FILE *pFile, int iWordVersion, const UCHAR *aucHeader)
00213 {
00214         style_block_type        *pStyle;
00215         font_block_type         *pFont;
00216         UCHAR   *aucBuffer;
00217         ULONG   ulBeginStshInfo;
00218         size_t  tStshInfoLen, tName, tChpx, tPapx, tMaxIndex;
00219         int     iStIndex, iChpxIndex, iPapxIndex, iSt, iChpx, iPapx;
00220         int     iStd, iIndex, iBaseStyleIndex, iCounter;
00221         USHORT  usBaseStyle;
00222         UCHAR   ucStc, ucStcNext, ucStcBase;
00223 
00224         fail(pFile == NULL || aucHeader == NULL);
00225         fail(iWordVersion != 1 && iWordVersion != 2);
00226 
00227         ulBeginStshInfo = ulGetLong(0x5e, aucHeader); /* fcStshf */
00228         NO_DBG_HEX(ulBeginStshInfo);
00229         tStshInfoLen = (size_t)usGetWord(0x62, aucHeader); /* cbStshf */
00230         NO_DBG_DEC(tStshInfoLen);
00231 
00232         aucBuffer = xmalloc(tStshInfoLen);
00233         if (!bReadBytes(aucBuffer, tStshInfoLen, ulBeginStshInfo, pFile)) {
00234                 aucBuffer = xfree(aucBuffer);
00235                 return;
00236         }
00237         NO_DBG_PRINT_BLOCK(aucBuffer, tStshInfoLen);
00238 
00239         fail(2 > tStshInfoLen);
00240         iStd = (int)usGetWord(0, aucBuffer);
00241 
00242         fail(2 + 2 > tStshInfoLen);
00243         tName = (size_t)usGetWord(2, aucBuffer);
00244 
00245         fail(2 + tName + 2 > tStshInfoLen);
00246         tChpx = (size_t)usGetWord(2 + tName, aucBuffer);
00247 
00248         fail(2 + tName + tChpx + 2 > tStshInfoLen);
00249         tPapx = (size_t)usGetWord(2 + tName + tChpx, aucBuffer);
00250 
00251         fail(2 + tName + tChpx + tPapx + 2 > tStshInfoLen);
00252         tStdCount = (size_t)usGetWord(2 + tName + tChpx + tPapx, aucBuffer);
00253 
00254         NO_DBG_HEX(tStdCount);
00255 
00256         atStyleInfo = xcalloc(tStdCount, sizeof(style_block_type));
00257         atFontInfo = xcalloc(tStdCount, sizeof(font_block_type));
00258         abFilled = xcalloc(tStdCount, sizeof(BOOL));
00259 
00260         do {
00261                 iCounter = 0;
00262                 iStIndex = 2 + 2;
00263                 iChpxIndex = 2 + (int)tName + 2;
00264                 iPapxIndex = 2 + (int)tName + (int)tChpx + 2;
00265                 tMaxIndex = 2 + tName + tChpx + tPapx + 2;
00266                 /* Read the styles one-by-one */
00267                 for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) {
00268                         pStyle = &atStyleInfo[iIndex];
00269                         pFont = &atFontInfo[iIndex];
00270                         iSt = (int)ucGetByte(iStIndex, aucBuffer);
00271                         iChpx = (int)ucGetByte(iChpxIndex, aucBuffer);
00272                         iPapx = (int)ucGetByte(iPapxIndex, aucBuffer);
00273                         NO_DBG_HEX(iSt);
00274                         NO_DBG_HEX(iChpx);
00275                         NO_DBG_HEX(iPapx);
00276                         if (iSt == 0xff || tMaxIndex + 1 >= tStshInfoLen) {
00277                                 /* Undefined style or no information */
00278                                 iStIndex++;
00279                                 iChpxIndex++;
00280                                 iPapxIndex++;
00281                                 tMaxIndex += 2;
00282                                 if (!abFilled[iIndex]) {
00283                                         DBG_HEX_C(iChpx != 0xff, iChpx);
00284                                         DBG_HEX_C(iPapx != 0xff, iPapx);
00285                                         vGetDefaultStyle(pStyle);
00286                                         vGetDefaultFont(pFont, 0);
00287                                         abFilled[iIndex] = TRUE;
00288                                 }
00289                                 continue;
00290                         }
00291 
00292                         NO_DBG_STRN(aucBuffer + iStIndex + 1, iSt);
00293                         iStIndex += iSt + 1;
00294 
00295                         ucStcNext = ucGetByte(tMaxIndex, aucBuffer);
00296                         ucStcBase = ucGetByte(tMaxIndex + 1, aucBuffer);
00297                         ucStc = (UCHAR)((iIndex - iStd) & 0xff);
00298                         NO_DBG_DEC(ucStc);
00299 
00300                         if (iChpx == 0xff || iPapx == 0xff) {
00301                                 /* Use a build-in style */
00302                                 iChpxIndex++;
00303                                 iPapxIndex++;
00304                                 tMaxIndex += 2;
00305                                 if (!abFilled[iIndex]) {
00306                                         DBG_HEX_C(iChpx != 0xff, iChpx);
00307                                         DBG_HEX_C(iPapx != 0xff, iPapx);
00308                                         vGetBuildinStyle(ucStc, pStyle);
00309                                         pStyle->usIstd = usStc2istd(ucStc);
00310                                         pStyle->usIstdNext =
00311                                                         usStc2istd(ucStcNext);
00312                                         vGetBuildinFont(ucStc, pFont);
00313                                         abFilled[iIndex] = TRUE;
00314                                 }
00315                                 continue;
00316                         }
00317 
00318                         if (abFilled[iIndex]) {
00319                                 /* This record has already been filled */
00320                                 iChpxIndex += iChpx + 1;
00321                                 iPapxIndex += iPapx + 1;
00322                                 tMaxIndex += 2;
00323                                 continue;
00324                         }
00325 
00326                         usBaseStyle = usStc2istd(ucStcBase);
00327 
00328                         if (usBaseStyle == STI_NIL) {
00329                                 /* Based on the Nil style */
00330                                 vGetDefaultStyle(pStyle);
00331                                 vGetDefaultFont(pFont, 0);
00332                         } else {
00333                                 iBaseStyleIndex = iGetStyleIndex(usBaseStyle);
00334                                 NO_DBG_DEC(iBaseStyleIndex);
00335                                 if (iBaseStyleIndex < 0) {
00336                                         /* This style is not known yet */
00337                                         iChpxIndex += iChpx + 1;
00338                                         iPapxIndex += iPapx + 1;
00339                                         tMaxIndex += 2;
00340                                         continue;
00341                                 }
00342                                 fail(iBaseStyleIndex >= (int)tStdCount);
00343                                 fail(!abFilled[iBaseStyleIndex]);
00344                                 /* Based on the specified base style */
00345                                 *pStyle = atStyleInfo[iBaseStyleIndex];
00346                                 *pFont = atFontInfo[iBaseStyleIndex];
00347                         }
00348                         pStyle->usIstd = usStc2istd(ucStc);
00349                         pStyle->usIstdNext = usStc2istd(ucStcNext);
00350 
00351                         abFilled[iIndex] = TRUE;
00352                         iCounter++;
00353 
00354                         /* Add the changes if any */
00355                         switch (iChpx) {
00356                         case 0x00:
00357                         case 0xff:
00358                                 iChpxIndex++;
00359                                 break;
00360                         default:
00361                                 NO_DBG_PRINT_BLOCK(aucBuffer + iChpxIndex + 1,
00362                                                 iChpx);
00363                                 if (iWordVersion == 1) {
00364                                         vGet1FontInfo(0,
00365                                                 aucBuffer + iChpxIndex + 1,
00366                                                 (size_t)iChpx, pFont);
00367                                 } else {
00368                                         vGet2FontInfo(0,
00369                                                 aucBuffer + iChpxIndex + 1,
00370                                                 (size_t)iChpx, pFont);
00371                                 }
00372                                 iChpxIndex += iChpx + 1;
00373                                 break;
00374                         }
00375 
00376                         switch (iPapx) {
00377                         case 0x00:
00378                         case 0xff:
00379                                 iPapxIndex++;
00380                                 break;
00381                         default:
00382                                 NO_DBG_PRINT_BLOCK(aucBuffer + iPapxIndex + 8,
00383                                                 iPapx - 7);
00384                                 vGet2StyleInfo(0, aucBuffer + iPapxIndex + 8,
00385                                                 iPapx - 7, pStyle);
00386                                 iPapxIndex += iPapx + 1;
00387                                 break;
00388                         }
00389                         tMaxIndex += 2;
00390 
00391                 }
00392                 NO_DBG_DEC(iCounter);
00393         } while (iCounter > 0);
00394 
00395         /* Fill records that are still empty */
00396         for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) {
00397                 if (!abFilled[iIndex]) {
00398                         NO_DBG_DEC(iIndex);
00399                         vGetDefaultStyle(&atStyleInfo[iIndex]);
00400                         vGetDefaultFont(&atFontInfo[iIndex], 0);
00401                 }
00402         }
00403 
00404         /* Clean up before you leave */
00405         abFilled = xfree(abFilled);
00406         aucBuffer = xfree(aucBuffer);
00407 } /* end of vGet2Stylesheet */
00408 
00409 /*
00410  * Build the lists with Stylesheet Information for Word 6/7 files
00411  */
00412 void
00413 vGet6Stylesheet(FILE *pFile, ULONG ulStartBlock,
00414         const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader)
00415 {
00416         style_block_type        *pStyle;
00417         font_block_type         *pFont;
00418         UCHAR   *aucBuffer;
00419         ULONG   ulBeginStshInfo;
00420         size_t  tStshInfoLen, tOffset, tStdLen, tStdBaseInFile;
00421         size_t  tPos, tNameLen, tUpxLen;
00422         int     iIndex, iBaseStyleIndex, iCounter;
00423         USHORT  usTmp, usUpxCount, usStyleType, usBaseStyle;
00424         USHORT  usFtcStandardChpStsh;
00425 
00426         fail(pFile == NULL || aucHeader == NULL);
00427         fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
00428         fail(aulBBD == NULL);
00429 
00430         ulBeginStshInfo = ulGetLong(0x60, aucHeader); /* fcStshf */
00431         NO_DBG_HEX(ulBeginStshInfo);
00432         tStshInfoLen = (size_t)ulGetLong(0x64, aucHeader); /* lcbStshf */
00433         NO_DBG_DEC(tStshInfoLen);
00434 
00435         aucBuffer = xmalloc(tStshInfoLen);
00436         if (!bReadBuffer(pFile, ulStartBlock,
00437                         aulBBD, tBBDLen, BIG_BLOCK_SIZE,
00438                         aucBuffer, ulBeginStshInfo, tStshInfoLen)) {
00439                 aucBuffer = xfree(aucBuffer);
00440                 return;
00441         }
00442         NO_DBG_PRINT_BLOCK(aucBuffer, tStshInfoLen);
00443 
00444         tStdCount = (size_t)usGetWord(2, aucBuffer);
00445         NO_DBG_DEC(tStdCount);
00446         tStdBaseInFile = (size_t)usGetWord(4, aucBuffer);
00447         usFtcStandardChpStsh = usGetWord(14, aucBuffer);
00448         NO_DBG_DEC(usFtcStandardChpStsh);
00449 
00450         atStyleInfo = xcalloc(tStdCount, sizeof(style_block_type));
00451         atFontInfo = xcalloc(tStdCount, sizeof(font_block_type));
00452         abFilled = xcalloc(tStdCount, sizeof(BOOL));
00453 
00454         do {
00455                 iCounter = 0;
00456                 /* Read the styles one-by-one */
00457                 for (iIndex = 0, tOffset = 2 + (size_t)usGetWord(0, aucBuffer);
00458                      iIndex < (int)tStdCount;
00459                      iIndex++, tOffset += 2 + tStdLen) {
00460                         NO_DBG_DEC(tOffset);
00461                         tStdLen = (size_t)usGetWord(tOffset, aucBuffer);
00462                         NO_DBG_DEC(tStdLen);
00463                         if (abFilled[iIndex]) {
00464                                 /* This record has already been filled */
00465                                 continue;
00466                         }
00467                         pStyle = &atStyleInfo[iIndex];
00468                         pFont = &atFontInfo[iIndex];
00469                         if (tStdLen == 0) {
00470                                 /* Empty record */
00471                                 vGetDefaultStyle(pStyle);
00472                                 vGetDefaultFont(pFont, usFtcStandardChpStsh);
00473                                 abFilled[iIndex] = TRUE;
00474                                 continue;
00475                         }
00476                         usTmp = usGetWord(tOffset + 4, aucBuffer);
00477                         usStyleType = usTmp % 16;
00478                         usBaseStyle = usTmp / 16;
00479                         NO_DBG_DEC(usStyleType);
00480                         NO_DBG_DEC(usBaseStyle);
00481                         if (usBaseStyle == STI_NIL || usBaseStyle == STI_USER) {
00482                                 /* Based on the Nil style */
00483                                 vGetDefaultStyle(pStyle);
00484                                 vGetDefaultFont(pFont, usFtcStandardChpStsh);
00485                         } else {
00486                                 iBaseStyleIndex = iGetStyleIndex(usBaseStyle);
00487                                 NO_DBG_DEC(iBaseStyleIndex);
00488                                 if (iBaseStyleIndex < 0) {
00489                                         /* This base style is not known yet */
00490                                         continue;
00491                                 }
00492                                 fail(iBaseStyleIndex >= (int)tStdCount);
00493                                 fail(!abFilled[iBaseStyleIndex]);
00494                                 /* Based on the specified base style */
00495                                 *pStyle = atStyleInfo[iBaseStyleIndex];
00496                                 pStyle->usIstd = ISTD_INVALID;
00497                                 *pFont = atFontInfo[iBaseStyleIndex];
00498                         }
00499                         abFilled[iIndex] = TRUE;
00500                         iCounter++;
00501                         /* STD */
00502                         usTmp = usGetWord(tOffset + 6, aucBuffer);
00503                         usUpxCount = usTmp % 16;
00504                         pStyle->usIstdNext = usTmp / 16;;
00505                         NO_DBG_DEC(usUpxCount);
00506                         tPos = 2 + tStdBaseInFile;
00507                         NO_DBG_DEC(tPos);
00508                         tNameLen = (size_t)ucGetByte(tOffset + tPos, aucBuffer);
00509                         NO_DBG_DEC(tNameLen);
00510                         NO_DBG_STRN(aucBuffer + tOffset + tPos + 1, tNameLen);
00511                         tNameLen++;     /* Include the ASCII NULL character */
00512                         tPos += 1 + tNameLen;
00513                         if (odd(tPos)) {
00514                                 tPos++;
00515                         }
00516                         NO_DBG_DEC(tPos);
00517                         if (tPos >= tStdLen) {
00518                                 continue;
00519                         }
00520                         tUpxLen = (size_t)usGetWord(tOffset + tPos, aucBuffer);
00521                         NO_DBG_DEC(tUpxLen);
00522                         if (tPos + tUpxLen > tStdLen) {
00523                                 /* UPX length too large to be a record */
00524                                 DBG_DEC_C(tPos + tUpxLen > tStdLen,
00525                                                 tPos + tUpxLen);
00526                                 continue;
00527                         }
00528                         if (usStyleType == SGC_PAP && usUpxCount >= 1) {
00529                                 if (tUpxLen >= 2) {
00530                                         NO_DBG_PRINT_BLOCK(
00531                                                 aucBuffer + tOffset + tPos + 2,
00532                                                 tUpxLen);
00533                                         pStyle->usIstd = usGetWord(
00534                                                 tOffset + tPos + 2, aucBuffer);
00535                                         NO_DBG_DEC(pStyle->usIstd);
00536                                         NO_DBG_DEC(pStyle->usIstdNext);
00537                                         vGet6StyleInfo(0,
00538                                                 aucBuffer + tOffset + tPos + 4,
00539                                                 tUpxLen - 2, pStyle);
00540                                         NO_DBG_DEC(pStyle->sLeftIndent);
00541                                         NO_DBG_DEC(pStyle->sRightIndent);
00542                                         NO_DBG_HEX(pStyle->ucAlignment);
00543                                 }
00544                                 tPos += 2 + tUpxLen;
00545                                 if (odd(tPos)) {
00546                                         tPos++;
00547                                 }
00548                                 NO_DBG_DEC(tPos);
00549                                 tUpxLen = (size_t)usGetWord(
00550                                                 tOffset + tPos, aucBuffer);
00551                                 NO_DBG_DEC(tUpxLen);
00552                         }
00553                         if (tUpxLen == 0 || tPos + tUpxLen > tStdLen) {
00554                                 /* Too small or too large to be a record */
00555                                 DBG_DEC_C(tPos + tUpxLen > tStdLen,
00556                                                         tPos + tUpxLen);
00557                                 continue;
00558                         }
00559                         if ((usStyleType == SGC_PAP && usUpxCount >= 2) ||
00560                             (usStyleType == SGC_CHP && usUpxCount >= 1)) {
00561                                 NO_DBG_PRINT_BLOCK(
00562                                                 aucBuffer + tOffset + tPos + 2,
00563                                                 tUpxLen);
00564                                 vGet6FontInfo(0, ISTD_INVALID,
00565                                                 aucBuffer + tOffset + tPos + 2,
00566                                                 (int)tUpxLen, pFont);
00567                                 NO_DBG_DEC(pFont->usFontSize);
00568                                 NO_DBG_DEC(pFont->ucFontcolor);
00569                                 NO_DBG_HEX(pFont->usFontStyle);
00570                         }
00571                 }
00572                 NO_DBG_DEC(iCounter);
00573         } while (iCounter > 0);
00574 
00575         /* Fill records that are still empty */
00576         for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) {
00577                 if (!abFilled[iIndex]) {
00578                         NO_DBG_DEC(iIndex);
00579                         vGetDefaultStyle(&atStyleInfo[iIndex]);
00580                         vGetDefaultFont(&atFontInfo[iIndex],
00581                                         usFtcStandardChpStsh);
00582                 }
00583         }
00584 
00585         /* Clean up before you leave */
00586         abFilled = xfree(abFilled);
00587         aucBuffer = xfree(aucBuffer);
00588 } /* end of vGet6Stylesheet */
00589 
00590 /*
00591  * Build the lists with Stylesheet Information for Word 8/9/10 files
00592  */
00593 void
00594 vGet8Stylesheet(FILE *pFile, const pps_info_type *pPPS,
00595         const ULONG *aulBBD, size_t tBBDLen,
00596         const ULONG *aulSBD, size_t tSBDLen,
00597         const UCHAR *aucHeader)
00598 {
00599         style_block_type        *pStyle;
00600         font_block_type         *pFont;
00601         const ULONG     *aulBlockDepot;
00602         UCHAR   *aucBuffer;
00603         ULONG   ulBeginStshInfo;
00604         size_t  tStshInfoLen, tBlockDepotLen, tOffset, tStdLen, tStdBaseInFile;
00605         size_t  tBlockSize, tPos, tNameLen, tUpxLen;
00606         int     iIndex, iBaseStyleIndex, iCounter;
00607         USHORT  usTmp, usUpxCount, usStyleType, usBaseStyle;
00608         USHORT  usFtcStandardChpStsh;
00609 
00610         fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
00611         fail(aulBBD == NULL || aulSBD == NULL);
00612 
00613         ulBeginStshInfo = ulGetLong(0xa2, aucHeader); /* fcStshf */
00614         NO_DBG_HEX(ulBeginStshInfo);
00615         tStshInfoLen = (size_t)ulGetLong(0xa6, aucHeader); /* lcbStshf */
00616         NO_DBG_DEC(tStshInfoLen);
00617 
00618         NO_DBG_DEC(pPPS->tTable.ulSB);
00619         NO_DBG_HEX(pPPS->tTable.ulSize);
00620         if (pPPS->tTable.ulSize == 0) {
00621                 DBG_MSG("No stylesheet information");
00622                 return;
00623         }
00624 
00625         if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
00626                 /* Use the Small Block Depot */
00627                 aulBlockDepot = aulSBD;
00628                 tBlockDepotLen = tSBDLen;
00629                 tBlockSize = SMALL_BLOCK_SIZE;
00630         } else {
00631                 /* Use the Big Block Depot */
00632                 aulBlockDepot = aulBBD;
00633                 tBlockDepotLen = tBBDLen;
00634                 tBlockSize = BIG_BLOCK_SIZE;
00635         }
00636         aucBuffer = xmalloc(tStshInfoLen);
00637         if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
00638                         aulBlockDepot, tBlockDepotLen, tBlockSize,
00639                         aucBuffer, ulBeginStshInfo, tStshInfoLen)) {
00640                 aucBuffer = xfree(aucBuffer);
00641                 return;
00642         }
00643         NO_DBG_PRINT_BLOCK(aucBuffer, tStshInfoLen);
00644 
00645         tStdCount = (size_t)usGetWord(2, aucBuffer);
00646         NO_DBG_DEC(tStdCount);
00647         tStdBaseInFile = (size_t)usGetWord(4, aucBuffer);
00648         usFtcStandardChpStsh = usGetWord(14, aucBuffer);
00649         NO_DBG_DEC(usFtcStandardChpStsh);
00650 
00651         atStyleInfo = xcalloc(tStdCount, sizeof(style_block_type));
00652         atFontInfo = xcalloc(tStdCount, sizeof(font_block_type));
00653         abFilled = xcalloc(tStdCount, sizeof(BOOL));
00654 
00655         do {
00656                 iCounter = 0;
00657                 /* Read the styles one-by-one */
00658                 for (iIndex = 0, tOffset = 2 + (size_t)usGetWord(0, aucBuffer);
00659                      iIndex < (int)tStdCount;
00660                      iIndex++, tOffset += 2 + tStdLen) {
00661                         NO_DBG_DEC(tOffset);
00662                         tStdLen = (size_t)usGetWord(tOffset, aucBuffer);
00663                         NO_DBG_DEC(tStdLen);
00664                         if (abFilled[iIndex]) {
00665                                 /* This record has already been filled */
00666                                 continue;
00667                         }
00668                         pStyle = &atStyleInfo[iIndex];
00669                         pFont = &atFontInfo[iIndex];
00670                         if (tStdLen == 0) {
00671                                 /* Empty record */
00672                                 vGetDefaultStyle(pStyle);
00673                                 vGetDefaultFont(pFont, usFtcStandardChpStsh);
00674                                 abFilled[iIndex] = TRUE;
00675                                 continue;
00676                         }
00677                         usTmp = usGetWord(tOffset + 4, aucBuffer);
00678                         usStyleType = usTmp % 16;
00679                         usBaseStyle = usTmp / 16;
00680                         NO_DBG_DEC(usStyleType);
00681                         NO_DBG_DEC(usBaseStyle);
00682                         if (usBaseStyle == STI_NIL || usBaseStyle == STI_USER) {
00683                                 /* Based on the Nil style */
00684                                 vGetDefaultStyle(pStyle);
00685                                 vGetDefaultFont(pFont, usFtcStandardChpStsh);
00686                         } else {
00687                                 iBaseStyleIndex = iGetStyleIndex(usBaseStyle);
00688                                 NO_DBG_DEC(iBaseStyleIndex);
00689                                 if (iBaseStyleIndex < 0) {
00690                                         /* This base style is not known yet */
00691                                         continue;
00692                                 }
00693                                 fail(iBaseStyleIndex >= (int)tStdCount);
00694                                 fail(!abFilled[iBaseStyleIndex]);
00695                                 /* Based on the specified base style */
00696                                 *pStyle = atStyleInfo[iBaseStyleIndex];
00697                                 pStyle->usIstd = ISTD_INVALID;
00698                                 *pFont = atFontInfo[iBaseStyleIndex];
00699                         }
00700                         abFilled[iIndex] = TRUE;
00701                         iCounter++;
00702                         /* STD */
00703                         usTmp = usGetWord(tOffset + 6, aucBuffer);
00704                         usUpxCount = usTmp % 16;
00705                         pStyle->usIstdNext = usTmp / 16;
00706                         NO_DBG_DEC(usUpxCount);
00707                         tPos = 2 + tStdBaseInFile;
00708                         NO_DBG_DEC(tPos);
00709                         tNameLen = (size_t)usGetWord(tOffset + tPos, aucBuffer);
00710                         NO_DBG_DEC(tNameLen);
00711                         tNameLen *= 2;  /* From Unicode characters to bytes */
00712                         NO_DBG_UNICODE_N(aucBuffer + tOffset + tPos + 2,
00713                                         tNameLen);
00714                         tNameLen += 2;  /* Include the Unicode NULL character */
00715                         tPos += 2 + tNameLen;
00716                         if (odd(tPos)) {
00717                                 tPos++;
00718                         }
00719                         NO_DBG_DEC(tPos);
00720                         if (tPos >= tStdLen) {
00721                                 continue;
00722                         }
00723                         tUpxLen = (size_t)usGetWord(tOffset + tPos, aucBuffer);
00724                         NO_DBG_DEC(tUpxLen);
00725                         if (tPos + tUpxLen > tStdLen) {
00726                                 /* UPX length too large to be a record */
00727                                 DBG_DEC_C(tPos + tUpxLen > tStdLen,
00728                                                 tPos + tUpxLen);
00729                                 continue;
00730                         }
00731                         if (usStyleType == SGC_PAP && usUpxCount >= 1) {
00732                                 if (tUpxLen >= 2) {
00733                                         NO_DBG_PRINT_BLOCK(
00734                                                 aucBuffer + tOffset + tPos + 2,
00735                                                 tUpxLen);
00736                                         pStyle->usIstd = usGetWord(
00737                                                 tOffset + tPos + 2, aucBuffer);
00738                                         NO_DBG_DEC(pStyle->usIstd);
00739                                         NO_DBG_DEC(pStyle->usIstdNext);
00740                                         vGet8StyleInfo(0,
00741                                                 aucBuffer + tOffset + tPos + 4,
00742                                                 tUpxLen - 2, pStyle);
00743                                         NO_DBG_DEC(pStyle->sLeftIndent);
00744                                         NO_DBG_DEC(pStyle->sRightIndent);
00745                                         NO_DBG_HEX(pStyle->ucAlignment);
00746                                 }
00747                                 tPos += 2 + tUpxLen;
00748                                 if (odd(tPos)) {
00749                                         tPos++;
00750                                 }
00751                                 NO_DBG_DEC(tPos);
00752                                 tUpxLen = (size_t)usGetWord(
00753                                                 tOffset + tPos, aucBuffer);
00754                                 NO_DBG_DEC(tUpxLen);
00755                         }
00756                         if (tUpxLen == 0 || tPos + tUpxLen > tStdLen) {
00757                                 /* Too small or too large to be a record */
00758                                 DBG_DEC_C(tPos + tUpxLen > tStdLen,
00759                                                         tPos + tUpxLen);
00760                                 continue;
00761                         }
00762                         if ((usStyleType == SGC_PAP && usUpxCount >= 2) ||
00763                             (usStyleType == SGC_CHP && usUpxCount >= 1)) {
00764                                 NO_DBG_PRINT_BLOCK(
00765                                                 aucBuffer + tOffset + tPos + 2,
00766                                                 tUpxLen);
00767                                 vGet8FontInfo(0, ISTD_INVALID,
00768                                                 aucBuffer + tOffset + tPos + 2,
00769                                                 (int)tUpxLen, pFont);
00770                                 NO_DBG_DEC(pFont->usFontSize);
00771                                 NO_DBG_DEC(pFont->ucFontcolor);
00772                                 NO_DBG_HEX(pFont->usFontStyle);
00773                         }
00774                 }
00775                 NO_DBG_DEC(iCounter);
00776         } while (iCounter > 0);
00777 
00778         /* Fill records that are still empty */
00779         for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) {
00780                 if (!abFilled[iIndex]) {
00781                         NO_DBG_DEC(iIndex);
00782                         vGetDefaultStyle(&atStyleInfo[iIndex]);
00783                         vGetDefaultFont(&atFontInfo[iIndex],
00784                                         usFtcStandardChpStsh);
00785                 }
00786         }
00787 
00788         /* Clean up before you leave */
00789         abFilled = xfree(abFilled);
00790         aucBuffer = xfree(aucBuffer);
00791 } /* end of vGet8Stylesheet */
00792 
00793 /*
00794  * vFillStyleFromStylesheet - fill a style struct with stylesheet info
00795  */
00796 void
00797 vFillStyleFromStylesheet(USHORT usIstd, style_block_type *pStyle)
00798 {
00799         int     iIndex;
00800 
00801         fail(pStyle == NULL);
00802 
00803         if (usIstd != ISTD_INVALID && usIstd != STI_NIL && usIstd != STI_USER) {
00804                 for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) {
00805                         if (atStyleInfo[iIndex].usIstd == usIstd) {
00806                                 /* Right index found; return style */
00807                                 *pStyle = atStyleInfo[iIndex];
00808                                 return;
00809                         }
00810                 }
00811         }
00812 
00813         vGetDefaultStyle(pStyle);
00814         pStyle->usIstd = usIstd;
00815 } /* end of vFillStyleFromStylesheet */
00816 
00817 /*
00818  * vFillFontFromStylesheet - fill a font struct with stylesheet info
00819  */
00820 void
00821 vFillFontFromStylesheet(USHORT usIstd, font_block_type *pFont)
00822 {
00823         int     iIndex;
00824 
00825         fail(pFont == NULL);
00826 
00827         if (usIstd != ISTD_INVALID && usIstd != STI_NIL && usIstd != STI_USER) {
00828                 for (iIndex = 0; iIndex < (int)tStdCount; iIndex++) {
00829                         if (atStyleInfo[iIndex].usIstd == usIstd) {
00830                                 /* Right index found; return font */
00831                                 *pFont = atFontInfo[iIndex];
00832                                 return;
00833                         }
00834                 }
00835         }
00836 
00837         vGetDefaultFont(pFont, 0);
00838 } /* end of vFillFontFromStylesheet */

Generated by  doxygen 1.6.2