home *** CD-ROM | disk | FTP | other *** search
/ OS/2 Shareware BBS: 5 Edit / 05-Edit.zip / anwor032.zip / antiword.0.32 / prop6.c < prev    next >
C/C++ Source or Header  |  2001-09-28  |  20KB  |  771 lines

  1. /*
  2.  * prop6.c
  3.  * Copyright (C) 1998-2001 A.J. van Os; Released under GPL
  4.  *
  5.  * Description:
  6.  * Read the property information from a MS Word 6 or 7 file
  7.  */
  8.  
  9. #include <stdlib.h>
  10. #include <string.h>
  11. #include "antiword.h"
  12.  
  13.  
  14. /*
  15.  * iGet6InfoLength - the length of the information for Word 6/7 files
  16.  */
  17. static int
  18. iGet6InfoLength(int iByteNbr, const unsigned char *aucFpage)
  19. {
  20.     int    iTmp, iDel, iAdd;
  21.  
  22.     switch (ucGetByte(iByteNbr, aucFpage)) {
  23.     case 0x02: case 0x10: case 0x11: case 0x13:
  24.     case 0x15: case 0x16: case 0x1b: case 0x1c:
  25.     case 0x26: case 0x27: case 0x28: case 0x29:
  26.     case 0x2a: case 0x2b: case 0x2d: case 0x2e:
  27.     case 0x2f: case 0x30: case 0x31: case 0x50:
  28.     case 0x5d: case 0x60: case 0x61: case 0x63:
  29.     case 0x65: case 0x69: case 0x6a: case 0x6b:
  30.     case 0x90: case 0xa4: case 0xa5: case 0xb6:
  31.     case 0xb8: case 0xbd: case 0xc3: case 0xc5:
  32.     case 0xc6:
  33.         return 3;
  34.     case 0x03: case 0x0c: case 0x0f: case 0x51:
  35.     case 0x67: case 0x6c: case 0xbc: case 0xbe:
  36.     case 0xbf:
  37.         return 2 + (int)ucGetByte(iByteNbr + 1, aucFpage);
  38.     case 0x14: case 0x49: case 0x4a: case 0xc0:
  39.     case 0xc2: case 0xc4: case 0xc8:
  40.         return 5;
  41.     case 0x17:
  42.         iTmp = (int)ucGetByte(iByteNbr + 1, aucFpage);
  43.         if (iTmp == 255) {
  44.             iDel = (int)ucGetByte(iByteNbr + 2, aucFpage);
  45.             iAdd = (int)ucGetByte(
  46.                     iByteNbr + 3 + iDel * 4, aucFpage);
  47.             iTmp = 2 + iDel * 4 + iAdd * 3;
  48.         }
  49.         return 2 + iTmp;
  50.     case 0x44: case 0xc1: case 0xc7:
  51.         return 6;
  52.     case 0x5f: case 0x88: case 0x89:
  53.         return 4;
  54.     case 0x78:
  55.         return 14;
  56.     case 0xbb:
  57.         return 13;
  58.     default:
  59.         return 2;
  60.     }
  61. } /* end of iGet6InfoLength */
  62.  
  63. /*
  64.  * Translate the rowinfo to a member of the row_info enumeration
  65.  */
  66. row_info_enum
  67. eGet6RowInfo(int iFodo,
  68.     const unsigned char *aucGrpprl, int iBytes, row_block_type *pRow)
  69. {
  70.     int    iFodoOff, iInfoLen;
  71.     int    iIndex, iSize, iCol;
  72.     int    iPosCurr, iPosPrev;
  73.     BOOL    bFound24_0, bFound24_1, bFound25_0, bFound25_1, bFound190;
  74.  
  75.     fail(iFodo < 0 || aucGrpprl == NULL || pRow == NULL);
  76.  
  77.     iFodoOff = 0;
  78.     bFound24_0 = FALSE;
  79.     bFound24_1 = FALSE;
  80.     bFound25_0 = FALSE;
  81.     bFound25_1 = FALSE;
  82.     bFound190 = FALSE;
  83.     while (iBytes >= iFodoOff + 1) {
  84.         iInfoLen = 0;
  85.         switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) {
  86.         case  24:    /* fIntable */
  87.             if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) {
  88.                 bFound24_1 = TRUE;
  89.             } else {
  90.                 bFound24_0 = TRUE;
  91.             }
  92.             break;
  93.         case  25:    /* fTtp */
  94.             if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) {
  95.                 bFound25_1 = TRUE;
  96.             } else {
  97.                 bFound25_0 = TRUE;
  98.             }
  99.             break;
  100.         case 190:    /* cDefTable */
  101.             iSize = (int)ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  102.             if (iSize < 6 || iBytes < iFodoOff + 7) {
  103.                 DBG_DEC(iSize);
  104.                 DBG_DEC(iFodoOff);
  105.                 iInfoLen = 1;
  106.                 break;
  107.             }
  108.             iCol = (int)ucGetByte(iFodo + iFodoOff + 3, aucGrpprl);
  109.             if (iCol < 1 ||
  110.                 iBytes < iFodoOff + 3 + (iCol + 1) * 2) {
  111.                 DBG_DEC(iCol);
  112.                 DBG_DEC(iFodoOff);
  113.                 iInfoLen = 1;
  114.                 break;
  115.             }
  116.             if (iCol >= (int)elementsof(pRow->asColumnWidth)) {
  117.                 werr(1, "The number of columns is corrupt");
  118.             }
  119.             pRow->ucNumberOfColumns = (unsigned char)iCol;
  120.             pRow->iColumnWidthSum = 0;
  121.             iPosPrev = (int)(short)usGetWord(
  122.                     iFodo + iFodoOff + 4,
  123.                     aucGrpprl);
  124.             for (iIndex = 0; iIndex < iCol; iIndex++) {
  125.                 iPosCurr = (int)(short)usGetWord(
  126.                     iFodo + iFodoOff + 6 + iIndex * 2,
  127.                     aucGrpprl);
  128.                 pRow->asColumnWidth[iIndex] =
  129.                         (short)(iPosCurr - iPosPrev);
  130.                 pRow->iColumnWidthSum +=
  131.                     pRow->asColumnWidth[iIndex];
  132.                 iPosPrev = iPosCurr;
  133.             }
  134.             bFound190 = TRUE;
  135.             break;
  136.         default:
  137.             break;
  138.         }
  139.         if (iInfoLen <= 0) {
  140.             iInfoLen =
  141.                 iGet6InfoLength(iFodo + iFodoOff, aucGrpprl);
  142.             fail(iInfoLen <= 0);
  143.         }
  144.         iFodoOff += iInfoLen;
  145.     }
  146.     if (bFound24_1 && bFound25_1 && bFound190) {
  147.         return found_end_of_row;
  148.     }
  149.     if (bFound24_0 && bFound25_0 && !bFound190) {
  150.         return found_not_end_of_row;
  151.     }
  152.     if (bFound24_1) {
  153.         return found_a_cell;
  154.     }
  155.     if (bFound24_0) {
  156.         return found_not_a_cell;
  157.     }
  158.     return found_nothing;
  159. } /* end of eGet6RowInfo */
  160.  
  161. /*
  162.  * Fill the style information block with information
  163.  * from a Word 6/7 file.
  164.  * Returns TRUE when successful, otherwise FALSE
  165.  */
  166. static BOOL
  167. bGet6StyleInfo(int iFodo, const unsigned char *aucFpage,
  168.         style_block_type *pStyle)
  169. {
  170.     int    iBytes, iFodoOff, iInfoLen;
  171.     int    iTmp, iDel, iAdd;
  172.     short    sTmp;
  173.  
  174.     fail(iFodo <= 0 || aucFpage == NULL || pStyle == NULL);
  175.  
  176.     iBytes = 2 * (int)ucGetByte(iFodo, aucFpage);
  177.     iFodoOff = 3;
  178.     if (iBytes < 1) {
  179.         return FALSE;
  180.     }
  181.     (void)memset(pStyle, 0, sizeof(*pStyle));
  182.     pStyle->ucStyle = ucGetByte(iFodo + 1, aucFpage);
  183.     while (iBytes >= iFodoOff + 1) {
  184.         iInfoLen = 0;
  185.         switch (ucGetByte(iFodo + iFodoOff, aucFpage)) {
  186.         case   2:    /* istd */
  187.             sTmp = (short)ucGetByte(
  188.                     iFodo + iFodoOff + 1, aucFpage);
  189.             NO_DBG_DEC(sTmp);
  190.             NO_DBG_DEC(pStyle->ucStyle);
  191.             break;
  192.         case   5:    /* jc */
  193.             pStyle->ucAlignment = ucGetByte(
  194.                     iFodo + iFodoOff + 1, aucFpage);
  195.             break;
  196.         case  12:    /* anld */
  197.             iTmp = (int)ucGetByte(
  198.                     iFodo + iFodoOff + 1, aucFpage);
  199.             if (iTmp < 52) {
  200.                 DBG_DEC(iTmp);
  201.                 break;
  202.             }
  203.             pStyle->ucListType = ucGetByte(
  204.                     iFodo + iFodoOff + 2, aucFpage);
  205.             pStyle->bInList = TRUE;
  206.             pStyle->ucListCharacter = ucGetByte(
  207.                     iFodo + iFodoOff + 22, aucFpage);
  208.             break;
  209.         case  13:    /* nLvlAnm */
  210.             iTmp = (int)ucGetByte(
  211.                     iFodo + iFodoOff + 1, aucFpage);
  212.             pStyle->bInList = TRUE;
  213.             if (iTmp == 0x0c) {
  214.                 pStyle->bUnmarked = TRUE;
  215.             }
  216.             break;
  217.         case  15:    /* ChgTabsPapx */
  218.             iTmp = (int)ucGetByte(iFodo + iFodoOff + 1, aucFpage);
  219.             if (iTmp < 2) {
  220.                 iInfoLen = 1;
  221.                 break;
  222.             }
  223.             NO_DBG_DEC(iTmp);
  224.             iDel = (int)ucGetByte(iFodo + iFodoOff + 2, aucFpage);
  225.             if (iTmp < 2 + 2 * iDel) {
  226.                 iInfoLen = 1;
  227.                 break;
  228.             }
  229.             NO_DBG_DEC(iDel);
  230.             iAdd = (int)ucGetByte(
  231.                 iFodo + iFodoOff + 3 + 2 * iDel, aucFpage);
  232.             if (iTmp < 2 + 2 * iDel + 2 * iAdd) {
  233.                 iInfoLen = 1;
  234.                 break;
  235.             }
  236.             NO_DBG_DEC(iAdd);
  237.             break;
  238.         case  16:    /* dxaRight */
  239.             pStyle->sRightIndent = (short)usGetWord(
  240.                     iFodo + iFodoOff + 1, aucFpage);
  241.             NO_DBG_DEC(pStyle->sRightIndent);
  242.             break;
  243.         case  17:    /* dxaLeft */
  244.             pStyle->sLeftIndent = (short)usGetWord(
  245.                     iFodo + iFodoOff + 1, aucFpage);
  246.             NO_DBG_DEC(pStyle->sLeftIndent);
  247.             break;
  248.         case  18:    /* Nest dxaLeft */
  249.             sTmp = (short)usGetWord(iFodo + iFodoOff + 1, aucFpage);
  250.             pStyle->sLeftIndent += sTmp;
  251.             if (pStyle->sLeftIndent < 0) {
  252.                 pStyle->sLeftIndent = 0;
  253.             }
  254.             NO_DBG_DEC(sTmp);
  255.             NO_DBG_DEC(pStyle->sLeftIndent);
  256.             break;
  257.         default:
  258.             break;
  259.         }
  260.         if (iInfoLen <= 0) {
  261.             iInfoLen =
  262.                 iGet6InfoLength(iFodo + iFodoOff, aucFpage);
  263.             fail(iInfoLen <= 0);
  264.         }
  265.         iFodoOff += iInfoLen;
  266.     }
  267.     return TRUE;
  268. } /* end of bGet6StyleInfo */
  269.  
  270. /*
  271.  * Build the lists with Paragraph Information for Word 6/7 files
  272.  */
  273. void
  274. vGet6PapInfo(FILE *pFile, long lStartBlock,
  275.     const long *alBBD, size_t tBBDLen,
  276.     const unsigned char *aucHeader)
  277. {
  278.     row_block_type        tRow;
  279.     style_block_type    tStyle;
  280.     unsigned short    *ausParfPage;
  281.     unsigned char    *aucBuffer;
  282.     long    lParmOffset, lParmOffsetFirst, lParmOffsetLast, lBeginParfInfo;
  283.     size_t    tParfInfoLen, tParfPageNum, tOffset, tSize, tLenOld, tLen;
  284.     int    iIndex, iIndex2, iRun, iFodo, iLen;
  285.     row_info_enum    eRowInfo;
  286.     unsigned short    usParfFirstPage, usCount;
  287.     unsigned char    aucFpage[BIG_BLOCK_SIZE];
  288.  
  289.     fail(pFile == NULL || aucHeader == NULL);
  290.     fail(lStartBlock < 0);
  291.     fail(alBBD == NULL);
  292.  
  293.     lBeginParfInfo = (long)ulGetLong(0xc0, aucHeader); /* fcPlcfbtePapx */
  294.     NO_DBG_HEX(lBeginParfInfo);
  295.     tParfInfoLen = (size_t)ulGetLong(0xc4, aucHeader); /* lcbPlcfbtePapx */
  296.     NO_DBG_DEC(tParfInfoLen);
  297.     if (tParfInfoLen < 4) {
  298.         DBG_DEC(tParfInfoLen);
  299.         return;
  300.     }
  301.  
  302.     aucBuffer = xmalloc(tParfInfoLen);
  303.     if (!bReadBuffer(pFile, lStartBlock,
  304.             alBBD, tBBDLen, BIG_BLOCK_SIZE,
  305.             aucBuffer, lBeginParfInfo, tParfInfoLen)) {
  306.         aucBuffer = xfree(aucBuffer);
  307.         return;
  308.     }
  309.     NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen);
  310.  
  311.     tLen = (tParfInfoLen - 4) / 6;
  312.     tSize = tLen * sizeof(unsigned short);
  313.     ausParfPage = xmalloc(tSize);
  314.     for (iIndex = 0, tOffset = (tLen + 1) * 4;
  315.          iIndex < (int)tLen;
  316.          iIndex++, tOffset += 2) {
  317.          ausParfPage[iIndex] = usGetWord(tOffset, aucBuffer);
  318.          NO_DBG_DEC(ausParfPage[iIndex]);
  319.     }
  320.     DBG_HEX(ulGetLong(0, aucBuffer));
  321.     aucBuffer = xfree(aucBuffer);
  322.     aucBuffer = NULL;
  323.     tParfPageNum = (size_t)usGetWord(0x190, aucHeader);
  324.     DBG_DEC(tParfPageNum);
  325.     if (tLen < tParfPageNum) {
  326.         /* Replace ParfPage by a longer version */
  327.         tLenOld = tLen;
  328.         usParfFirstPage = usGetWord(0x18c, aucHeader);
  329.         DBG_DEC(usParfFirstPage);
  330.         tLen += tParfPageNum - 1;
  331.         tSize = tLen * sizeof(unsigned short);
  332.         ausParfPage = xrealloc(ausParfPage, tSize);
  333.         /* Add new values */
  334.         usCount = usParfFirstPage + 1;
  335.         for (iIndex = (int)tLenOld; iIndex < (int)tLen; iIndex++) {
  336.             ausParfPage[iIndex] = usCount;
  337.             NO_DBG_DEC(ausParfPage[iIndex]);
  338.             usCount++;
  339.         }
  340.     }
  341.  
  342.     (void)memset(&tStyle, 0, sizeof(tStyle));
  343.     (void)memset(&tRow, 0, sizeof(tRow));
  344.     lParmOffsetFirst = -1;
  345.     for (iIndex = 0; iIndex < (int)tLen; iIndex++) {
  346.         if (!bReadBuffer(pFile, lStartBlock,
  347.                 alBBD, tBBDLen, BIG_BLOCK_SIZE,
  348.                 aucFpage,
  349.                 (long)ausParfPage[iIndex] * BIG_BLOCK_SIZE,
  350.                 BIG_BLOCK_SIZE)) {
  351.             break;
  352.         }
  353.         iRun = (int)ucGetByte(0x1ff, aucFpage);
  354.         NO_DBG_DEC(iRun);
  355.         for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) {
  356.             NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage));
  357.             iFodo = 2 * (int)ucGetByte(
  358.                 (iRun + 1) * 4 + iIndex2 * 7, aucFpage);
  359.             if (iFodo <= 0) {
  360.                 continue;
  361.             }
  362.             if (bGet6StyleInfo(iFodo, aucFpage, &tStyle)) {
  363.                 lParmOffset = (long)ulGetLong(
  364.                         iIndex2 * 4, aucFpage);
  365.                 NO_DBG_HEX(lParmOffset);
  366.                 tStyle.lFileOffset = lTextOffset2FileOffset(
  367.                             lParmOffset);
  368.                 vAdd2StyleInfoList(&tStyle);
  369.                 (void)memset(&tStyle, 0, sizeof(tStyle));
  370.             }
  371.  
  372.             iLen = 2 * (int)ucGetByte(iFodo, aucFpage);
  373.             eRowInfo = eGet6RowInfo(iFodo,
  374.                     aucFpage + 3, iLen - 3, &tRow);
  375.             switch(eRowInfo) {
  376.             case found_a_cell:
  377.                 if (lParmOffsetFirst >= 0) {
  378.                     break;
  379.                 }
  380.                 lParmOffsetFirst = (long)ulGetLong(
  381.                         iIndex2 * 4, aucFpage);
  382.                 NO_DBG_HEX(lParmOffsetFirst);
  383.                 tRow.lTextOffsetStart = lParmOffsetFirst;
  384.                 tRow.lFileOffsetStart = lTextOffset2FileOffset(
  385.                             lParmOffsetFirst);
  386.                 DBG_HEX_C(tRow.lFileOffsetStart < 0,
  387.                             lParmOffsetFirst);
  388.                 break;
  389.             case found_end_of_row:
  390.                 lParmOffsetLast = (long)ulGetLong(
  391.                         iIndex2 * 4, aucFpage);
  392.                 NO_DBG_HEX(lParmOffsetLast);
  393.                 tRow.lTextOffsetEnd = lParmOffsetLast;
  394.                 tRow.lFileOffsetEnd = lTextOffset2FileOffset(
  395.                             lParmOffsetLast);
  396.                 DBG_HEX_C(tRow.lFileOffsetEnd < 0,
  397.                             lParmOffsetLast);
  398.                 vAdd2RowInfoList(&tRow);
  399.                 (void)memset(&tRow, 0, sizeof(tRow));
  400.                 lParmOffsetFirst = -1;
  401.                 break;
  402.             case found_nothing:
  403.                 break;
  404.             default:
  405.                 DBG_DEC(eRowInfo);
  406.                 break;
  407.             }
  408.         }
  409.     }
  410.     ausParfPage = xfree(ausParfPage);
  411. } /* end of vGet6PapInfo */
  412.  
  413. /*
  414.  * Fill the font information block with information
  415.  * from a Word 6/7 file.
  416.  * Returns TRUE when successful, otherwise FALSE
  417.  */
  418. static BOOL
  419. bGet6FontInfo(int iFodo, const unsigned char *aucFpage,
  420.         font_block_type *pFont)
  421. {
  422.     int    iBytes, iFodoOff, iInfoLen;
  423.     unsigned short    usTmp;
  424.     short        sTmp;
  425.     unsigned char    ucTmp;
  426.  
  427.     fail(iFodo <= 0 || aucFpage == NULL || pFont == NULL);
  428.  
  429.     iBytes = (int)ucGetByte(iFodo, aucFpage);
  430.     iFodoOff = 1;
  431.     if (iBytes < 1) {
  432.         return FALSE;
  433.     }
  434.     (void)memset(pFont, 0, sizeof(*pFont));
  435.     pFont->sFontsize = DEFAULT_FONT_SIZE;
  436.     while (iBytes >= iFodoOff + 1) {
  437.         switch (ucGetByte(iFodo + iFodoOff, aucFpage)) {
  438.         case  80:    /* cIstd */
  439.             sTmp = (short)usGetWord(iFodo + iFodoOff + 1, aucFpage);
  440.             DBG_DEC(sTmp);
  441.                         break;
  442.         case  82:    /* cDefault */
  443.             pFont->ucFontstyle &= FONT_HIDDEN;
  444.             pFont->ucFontcolor = FONT_COLOR_DEFAULT;
  445.             break;
  446.         case  85:    /* fBold */
  447.             ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucFpage);
  448.             switch (ucTmp) {
  449.             case   0:    /* Unset */
  450.                 pFont->ucFontstyle &= ~FONT_BOLD;
  451.                 break;
  452.             case   1:    /* Set */
  453.                 pFont->ucFontstyle |= FONT_BOLD;
  454.                 break;
  455.             case 128:    /* Unchanged */
  456.                 break;
  457.             case 129:    /* Negation */
  458.                 pFont->ucFontstyle ^= FONT_BOLD;
  459.                 break;
  460.             default:
  461.                 DBG_DEC(ucTmp);
  462.                 DBG_FIXME();
  463.                 break;
  464.             }
  465.             break;
  466.         case  86:    /* fItalic */
  467.             ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucFpage);
  468.             switch (ucTmp) {
  469.             case   0:    /* Unset */
  470.                 pFont->ucFontstyle &= ~FONT_ITALIC;
  471.                 break;
  472.             case   1:    /* Set */
  473.                 pFont->ucFontstyle |= FONT_ITALIC;
  474.                 break;
  475.             case 128:    /* Unchanged */
  476.                 break;
  477.             case 129:    /* Negation */
  478.                 pFont->ucFontstyle ^= FONT_ITALIC;
  479.                 break;
  480.             default:
  481.                 DBG_DEC(ucTmp);
  482.                 DBG_FIXME();
  483.                 break;
  484.             }
  485.             break;
  486.         case  87:    /* fStrike */
  487.             ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucFpage);
  488.             switch (ucTmp) {
  489.             case   0:    /* Unset */
  490.                 pFont->ucFontstyle &= ~FONT_STRIKE;
  491.                 break;
  492.             case   1:    /* Set */
  493.                 pFont->ucFontstyle |= FONT_STRIKE;
  494.                 break;
  495.             case 128:    /* Unchanged */
  496.                 break;
  497.             case 129:    /* Negation */
  498.                 pFont->ucFontstyle ^= FONT_STRIKE;
  499.                 break;
  500.             default:
  501.                 DBG_DEC(ucTmp);
  502.                 DBG_FIXME();
  503.                 break;
  504.             }
  505.             break;
  506.         case  90:    /* fSmallCaps */
  507.             ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucFpage);
  508.             switch (ucTmp) {
  509.             case   0:    /* Unset */
  510.                 pFont->ucFontstyle &= ~FONT_SMALL_CAPITALS;
  511.                 break;
  512.             case   1:    /* Set */
  513.                 pFont->ucFontstyle |= FONT_SMALL_CAPITALS;
  514.                 break;
  515.             case 128:    /* Unchanged */
  516.                 break;
  517.             case 129:    /* Negation */
  518.                 pFont->ucFontstyle ^= FONT_SMALL_CAPITALS;
  519.                 break;
  520.             default:
  521.                 DBG_DEC(ucTmp);
  522.                 DBG_FIXME();
  523.                 break;
  524.             }
  525.             break;
  526.         case  91:    /* fCaps */
  527.             ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucFpage);
  528.             switch (ucTmp) {
  529.             case   0:    /* Unset */
  530.                 pFont->ucFontstyle &= ~FONT_CAPITALS;
  531.                 break;
  532.             case   1:    /* Set */
  533.                 pFont->ucFontstyle |= FONT_CAPITALS;
  534.                 break;
  535.             case 128:    /* Unchanged */
  536.                 break;
  537.             case 129:    /* Negation */
  538.                 pFont->ucFontstyle ^= FONT_CAPITALS;
  539.                 break;
  540.             default:
  541.                 DBG_DEC(ucTmp);
  542.                 DBG_FIXME();
  543.                 break;
  544.             }
  545.             break;
  546.         case  92:    /* fVanish */
  547.             ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucFpage);
  548.             switch (ucTmp) {
  549.             case   0:    /* Unset */
  550.                 pFont->ucFontstyle &= ~FONT_HIDDEN;
  551.                 break;
  552.             case   1:    /* Set */
  553.                 pFont->ucFontstyle |= FONT_HIDDEN;
  554.                 break;
  555.             case 128:    /* Unchanged */
  556.                 break;
  557.             case 129:    /* Negation */
  558.                 pFont->ucFontstyle ^= FONT_HIDDEN;
  559.                 break;
  560.             default:
  561.                 DBG_DEC(ucTmp);
  562.                 DBG_FIXME();
  563.                 break;
  564.             }
  565.             break;
  566.         case  93:    /* cFtc */
  567.             usTmp = usGetWord(iFodo + iFodoOff + 1, aucFpage);
  568.             if (usTmp <= (unsigned short)UCHAR_MAX) {
  569.                 pFont->ucFontnumber = (unsigned char)usTmp;
  570.             }
  571.             break;
  572.         case  94:    /* cKul */
  573.             ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucFpage);
  574.             if (ucTmp != 0 && ucTmp != 5) {
  575.                 NO_DBG_MSG("Underline text");
  576.                 pFont->ucFontstyle |= FONT_UNDERLINE;
  577.                 if (ucTmp == 6) {
  578.                     DBG_MSG("Bold text");
  579.                     pFont->ucFontstyle |= FONT_BOLD;
  580.                 }
  581.             }
  582.             break;
  583.         case  98:    /* cIco */
  584.             pFont->ucFontcolor =
  585.                 ucGetByte(iFodo + iFodoOff + 1, aucFpage);
  586.             break;
  587.         case  99:    /* cHps */
  588.             usTmp = usGetWord(iFodo + iFodoOff + 1, aucFpage);
  589.             if (usTmp > (unsigned short)SHRT_MAX) {
  590.                 pFont->sFontsize = SHRT_MAX;
  591.             } else {
  592.                 pFont->sFontsize = (short)usTmp;
  593.             }
  594.             break;
  595.         default:
  596.             break;
  597.         }
  598.         iInfoLen = iGet6InfoLength(iFodo + iFodoOff, aucFpage);
  599.         fail(iInfoLen <= 0);
  600.         iFodoOff += iInfoLen;
  601.     }
  602.     return TRUE;
  603. } /* end of bGet6FontInfo */
  604.  
  605. /*
  606.  * Fill the picture information block with information
  607.  * from a Word 6/7 file.
  608.  * Returns TRUE when successful, otherwise FALSE
  609.  */
  610. static BOOL
  611. bGet6PicInfo(int iFodo, const unsigned char *aucFpage,
  612.         picture_block_type *pPicture)
  613. {
  614.     int    iBytes, iFodoOff, iInfoLen;
  615.     BOOL    bFound;
  616.     unsigned char    ucTmp;
  617.  
  618.     fail(iFodo <= 0 || aucFpage == NULL || pPicture == NULL);
  619.  
  620.     iBytes = (int)ucGetByte(iFodo, aucFpage);
  621.     iFodoOff = 1;
  622.     if (iBytes < 1) {
  623.         return FALSE;
  624.     }
  625.     bFound = FALSE;
  626.     (void)memset(pPicture, 0, sizeof(*pPicture));
  627.     while (iBytes >= iFodoOff + 1) {
  628.         switch (ucGetByte(iFodo + iFodoOff, aucFpage)) {
  629.         case 0x44:
  630.             pPicture->lPictureOffset = (long)ulGetLong(
  631.                     iFodo + iFodoOff + 2, aucFpage);
  632.             bFound = TRUE;
  633.             break;
  634.         case 0x47:
  635.             ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucFpage);
  636.             if (ucTmp == 0x01) {
  637.                 /* Not a picture, but a form field */
  638.                 return FALSE;
  639.             }
  640.             DBG_DEC_C(ucTmp != 0, ucTmp);
  641.             break;
  642.         case 0x4b:
  643.             ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucFpage);
  644.             if (ucTmp == 0x01) {
  645.                 /* Not a picture, but an OLE object */
  646.                 return FALSE;
  647.             }
  648.             DBG_DEC_C(ucTmp != 0, ucTmp);
  649.             break;
  650.         default:
  651.             break;
  652.         }
  653.         iInfoLen = iGet6InfoLength(iFodo + iFodoOff, aucFpage);
  654.         fail(iInfoLen <= 0);
  655.         iFodoOff += iInfoLen;
  656.     }
  657.     return bFound;
  658. } /* end of bGet6PicInfo */
  659.  
  660. /*
  661.  * Build the lists with Character Information for Word 6/7 files
  662.  */
  663. void
  664. vGet6ChrInfo(FILE *pFile, const pps_info_type *pPPS,
  665.     const long *alBBD, size_t tBBDLen,
  666.     const unsigned char *aucHeader)
  667. {
  668.     font_block_type        tFont;
  669.     picture_block_type    tPicture;
  670.     unsigned short    *ausCharPage;
  671.     unsigned char    *aucBuffer;
  672.     long    lFileOffset, lParmOffset, lBeginCharInfo;
  673.     size_t    tCharInfoLen, tOffset, tSize, tLenOld, tLen, tCharPageNum;
  674.     int    iIndex, iIndex2, iRun, iFodo;
  675.     unsigned short    usCharFirstPage, usCount;
  676.     unsigned char    aucFpage[BIG_BLOCK_SIZE];
  677.  
  678.     fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
  679.     fail(alBBD == NULL);
  680.  
  681.     lBeginCharInfo = (long)ulGetLong(0xb8, aucHeader); /* fcPlcfbteChpx */
  682.     NO_DBG_HEX(lBeginCharInfo);
  683.     tCharInfoLen = (size_t)ulGetLong(0xbc, aucHeader); /* lcbPlcfbteChpx */
  684.     NO_DBG_DEC(tCharInfoLen);
  685.     if (tCharInfoLen < 4) {
  686.         DBG_DEC(tCharInfoLen);
  687.         return;
  688.     }
  689.  
  690.     aucBuffer = xmalloc(tCharInfoLen);
  691.     if (!bReadBuffer(pFile, pPPS->tWordDocument.lSb,
  692.             alBBD, tBBDLen, BIG_BLOCK_SIZE,
  693.             aucBuffer, lBeginCharInfo, tCharInfoLen)) {
  694.         aucBuffer = xfree(aucBuffer);
  695.         return;
  696.     }
  697.  
  698.     tLen = (tCharInfoLen - 4) / 6;
  699.     tSize = tLen * sizeof(unsigned short);
  700.     ausCharPage = xmalloc(tSize);
  701.     for (iIndex = 0, tOffset = (tLen + 1) * 4;
  702.          iIndex < (int)tLen;
  703.          iIndex++, tOffset += 2) {
  704.          ausCharPage[iIndex] = usGetWord(tOffset, aucBuffer);
  705.          NO_DBG_DEC(ausCharPage[iIndex]);
  706.     }
  707.     DBG_HEX(ulGetLong(0, aucBuffer));
  708.     aucBuffer = xfree(aucBuffer);
  709.     aucBuffer = NULL;
  710.     tCharPageNum = (size_t)usGetWord(0x18e, aucHeader);
  711.     DBG_DEC(tCharPageNum);
  712.     if (tLen < tCharPageNum) {
  713.         /* Replace CharPage by a longer version */
  714.         tLenOld = tLen;
  715.         usCharFirstPage = usGetWord(0x18a, aucHeader);
  716.         DBG_DEC(usCharFirstPage);
  717.         tLen += tCharPageNum - 1;
  718.         tSize = tLen * sizeof(unsigned short);
  719.         ausCharPage = xrealloc(ausCharPage, tSize);
  720.         /* Add new values */
  721.         usCount = usCharFirstPage + 1;
  722.         for (iIndex = (int)tLenOld; iIndex < (int)tLen; iIndex++) {
  723.             ausCharPage[iIndex] = usCount;
  724.             NO_DBG_DEC(ausCharPage[iIndex]);
  725.             usCount++;
  726.         }
  727.     }
  728.  
  729.     (void)memset(&tFont, 0, sizeof(tFont));
  730.     (void)memset(&tPicture, 0, sizeof(tPicture));
  731.     for (iIndex = 0; iIndex < (int)tLen; iIndex++) {
  732.         if (!bReadBuffer(pFile, pPPS->tWordDocument.lSb,
  733.                 alBBD, tBBDLen, BIG_BLOCK_SIZE,
  734.                 aucFpage,
  735.                 (long)ausCharPage[iIndex] * BIG_BLOCK_SIZE,
  736.                 BIG_BLOCK_SIZE)) {
  737.             break;
  738.         }
  739.         iRun = (int)ucGetByte(0x1ff, aucFpage);
  740.         NO_DBG_DEC(iRun);
  741.         for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) {
  742.               lParmOffset = (long)ulGetLong(
  743.                         iIndex2 * 4, aucFpage);
  744.             lFileOffset = lTextOffset2FileOffset(lParmOffset);
  745.             iFodo = 2 * (int)ucGetByte(
  746.                 (iRun + 1) * 4 + iIndex2, aucFpage);
  747.             if (iFodo == 0) {
  748.                 NO_DBG_HEX(lParmOffset);
  749.                 vReset2FontInfoList(lFileOffset);
  750.             } else {
  751.                 if (bGet6FontInfo(iFodo, aucFpage, &tFont)) {
  752.                     tFont.lFileOffset = lFileOffset;
  753.                     vAdd2FontInfoList(&tFont);
  754.                 }
  755.             }
  756.             (void)memset(&tFont, 0, sizeof(tFont));
  757.             if (iFodo <= 0) {
  758.                 continue;
  759.             }
  760.             if (bGet6PicInfo(iFodo, aucFpage, &tPicture)) {
  761.                 tPicture.lFileOffset = lFileOffset;
  762.                 tPicture.lFileOffsetPicture =
  763.                     lDataOffset2FileOffset(tPicture.lPictureOffset);
  764.                 vAdd2PicInfoList(&tPicture);
  765.             }
  766.             (void)memset(&tPicture, 0, sizeof(tPicture));
  767.         }
  768.     }
  769.     ausCharPage = xfree(ausCharPage);
  770. } /* end of vGet6ChrInfo */
  771.