diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/prop8_8c_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/prop8_8c_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,1512 @@ + + +
+ +00001 /* +00002 * prop8.c +00003 * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL +00004 * +00005 * Description: +00006 * Read the property information from a MS Word 8, 9,10 or 11 file +00007 * +00008 * Word 8 is better known as Word 97 or as Word 98 for Mac +00009 * Word 9 is better known as Word 2000 or as Word 2001 for Mac +00010 * Word 10 is better known as Word 2002 or as Word XP +00011 * Word 11 is better known as Word 2003 +00012 */ +00013 +00014 #include <stdlib.h> +00015 #include <string.h> +00016 #include "antiword.h" +00017 +00018 #define DEFAULT_LISTCHAR 0x002e /* A full stop */ +00019 +00020 +00021 /* +00022 * iGet8InfoLength - the length of the information for Word 8/9/10/11 files +00023 */ +00024 static int +00025 iGet8InfoLength(int iByteNbr, const UCHAR *aucGrpprl) +00026 { +00027 int iTmp, iDel, iAdd; +00028 USHORT usOpCode; +00029 +00030 usOpCode = usGetWord(iByteNbr, aucGrpprl); +00031 +00032 switch (usOpCode & 0xe000) { +00033 case 0x0000: case 0x2000: +00034 return 3; +00035 case 0x4000: case 0x8000: case 0xa000: +00036 return 4; +00037 case 0xe000: +00038 return 5; +00039 case 0x6000: +00040 return 6; +00041 case 0xc000: +00042 iTmp = (int)ucGetByte(iByteNbr + 2, aucGrpprl); +00043 if (usOpCode == 0xc615 && iTmp == 255) { +00044 iDel = (int)ucGetByte(iByteNbr + 3, aucGrpprl); +00045 iAdd = (int)ucGetByte( +00046 iByteNbr + 4 + iDel * 4, aucGrpprl); +00047 iTmp = 2 + iDel * 4 + iAdd * 3; +00048 } +00049 return 3 + iTmp; +00050 default: +00051 DBG_HEX(usOpCode); +00052 DBG_FIXME(); +00053 return 1; +00054 } +00055 } /* end of iGet8InfoLength */ +00056 +00057 /* +00058 * aucFillInfoBuffer - fill the information buffer +00059 * +00060 * Returns the information buffer when successful, otherwise NULL +00061 */ +00062 static UCHAR * +00063 aucFillInfoBuffer(FILE *pFile, const pps_type *pTable, +00064 const ULONG *aulBBD, size_t tBBDLen, +00065 const ULONG *aulSBD, size_t tSBDLen, +00066 ULONG ulBeginInfo, size_t tInfoLen) +00067 { +00068 const ULONG *aulBlockDepot; +00069 UCHAR *aucBuffer; +00070 size_t tBlockDepotLen, tBlockSize; +00071 +00072 fail(pFile == NULL || pTable == NULL); +00073 fail(aulBBD == NULL || aulSBD == NULL); +00074 fail(tInfoLen == 0); +00075 +00076 NO_DBG_DEC(pTable->ulSB); +00077 NO_DBG_HEX(pTable->ulSize); +00078 if (pTable->ulSize == 0) { +00079 DBG_MSG("No information"); +00080 return NULL; +00081 } +00082 +00083 if (pTable->ulSize < MIN_SIZE_FOR_BBD_USE) { +00084 /* Use the Small Block Depot */ +00085 aulBlockDepot = aulSBD; +00086 tBlockDepotLen = tSBDLen; +00087 tBlockSize = SMALL_BLOCK_SIZE; +00088 } else { +00089 /* Use the Big Block Depot */ +00090 aulBlockDepot = aulBBD; +00091 tBlockDepotLen = tBBDLen; +00092 tBlockSize = BIG_BLOCK_SIZE; +00093 } +00094 aucBuffer = xmalloc(tInfoLen); +00095 if (!bReadBuffer(pFile, pTable->ulSB, +00096 aulBlockDepot, tBlockDepotLen, tBlockSize, +00097 aucBuffer, ulBeginInfo, tInfoLen)) { +00098 aucBuffer = xfree(aucBuffer); +00099 return NULL; +00100 } +00101 return aucBuffer; +00102 } /* end of aucFillInfoBuffer */ +00103 +00104 /* +00105 * Build the lists with Document Property Information for Word 8/9/10/11 files +00106 */ +00107 void +00108 vGet8DopInfo(FILE *pFile, const pps_type *pTable, +00109 const ULONG *aulBBD, size_t tBBDLen, +00110 const ULONG *aulSBD, size_t tSBDLen, +00111 const UCHAR *aucHeader) +00112 { +00113 document_block_type tDocument; +00114 UCHAR *aucBuffer; +00115 ULONG ulBeginDocpInfo, ulTmp; +00116 size_t tDocpInfoLen; +00117 USHORT usTmp; +00118 +00119 fail(pFile == NULL || pTable == NULL || aucHeader == NULL); +00120 fail(aulBBD == NULL || aulSBD == NULL); +00121 +00122 ulBeginDocpInfo = ulGetLong(0x192, aucHeader); /* fcDop */ +00123 NO_DBG_HEX(ulBeginSectInfo); +00124 tDocpInfoLen = (size_t)ulGetLong(0x196, aucHeader); /* lcbDop */ +00125 NO_DBG_DEC(tSectInfoLen); +00126 if (tDocpInfoLen < 28) { +00127 DBG_MSG("No Document information"); +00128 return; +00129 } +00130 +00131 aucBuffer = aucFillInfoBuffer(pFile, pTable, +00132 aulBBD, tBBDLen, aulSBD, tSBDLen, +00133 ulBeginDocpInfo, tDocpInfoLen); +00134 if (aucBuffer == NULL) { +00135 return; +00136 } +00137 +00138 usTmp = usGetWord(0x00, aucBuffer); +00139 tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */ +00140 tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */ +00141 ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */ +00142 tDocument.tCreateDate = tConvertDTTM(ulTmp); +00143 ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */ +00144 tDocument.tRevisedDate = tConvertDTTM(ulTmp); +00145 vCreateDocumentInfoList(&tDocument); +00146 +00147 aucBuffer = xfree(aucBuffer); +00148 } /* end of vGet8DopInfo */ +00149 +00150 /* +00151 * Fill the section information block with information +00152 * from a Word 8/9/10/11 file. +00153 */ +00154 static void +00155 vGet8SectionInfo(const UCHAR *aucGrpprl, size_t tBytes, +00156 section_block_type *pSection) +00157 { +00158 UINT uiIndex; +00159 int iFodoOff, iInfoLen, iSize, iTmp; +00160 USHORT usCcol; +00161 UCHAR ucTmp; +00162 +00163 fail(aucGrpprl == NULL || pSection == NULL); +00164 +00165 iFodoOff = 0; +00166 while (tBytes >= (size_t)iFodoOff + 2) { +00167 iInfoLen = 0; +00168 switch (usGetWord(iFodoOff, aucGrpprl)) { +00169 case 0x3009: /* bkc */ +00170 ucTmp = ucGetByte(iFodoOff + 2, aucGrpprl); +00171 DBG_DEC(ucTmp); +00172 pSection->bNewPage = ucTmp != 0 && ucTmp != 1; +00173 break; +00174 case 0x3014: /* grpfIhdt */ +00175 pSection->ucHdrFtrSpecification = +00176 ucGetByte(iFodoOff + 2, aucGrpprl); +00177 break; +00178 case 0x500b: /* ccolM1 */ +00179 usCcol = 1 + usGetWord(iFodoOff + 2, aucGrpprl); +00180 DBG_DEC(usCcol); +00181 break; +00182 case 0xd202: /* olstAnm */ +00183 iSize = (int)ucGetByte(iFodoOff + 2, aucGrpprl); +00184 DBG_DEC_C(iSize != 212, iSize); +00185 for (uiIndex = 0, iTmp = iFodoOff + 3; +00186 uiIndex < 9 && iTmp < iFodoOff + 3 + iSize - 15; +00187 uiIndex++, iTmp += 16) { +00188 pSection->aucNFC[uiIndex] = +00189 ucGetByte(iTmp, aucGrpprl); +00190 DBG_DEC(pSection->aucNFC[uiIndex]); +00191 ucTmp = ucGetByte(iTmp + 3, aucGrpprl); +00192 DBG_HEX(ucTmp); +00193 if ((ucTmp & BIT(2)) != 0) { +00194 pSection->usNeedPrevLvl |= +00195 (USHORT)BIT(uiIndex); +00196 } +00197 if ((ucTmp & BIT(3)) != 0) { +00198 pSection->usHangingIndent |= +00199 (USHORT)BIT(uiIndex); +00200 } +00201 } +00202 DBG_HEX(pSection->usNeedPrevLvl); +00203 DBG_HEX(pSection->usHangingIndent); +00204 break; +00205 default: +00206 break; +00207 } +00208 if (iInfoLen <= 0) { +00209 iInfoLen = iGet8InfoLength(iFodoOff, aucGrpprl); +00210 fail(iInfoLen <= 0); +00211 } +00212 iFodoOff += iInfoLen; +00213 } +00214 } /* end of vGet8SectionInfo */ +00215 +00216 /* +00217 * Build the lists with Section Property Information for Word 8/9/10/11 files +00218 */ +00219 void +00220 vGet8SepInfo(FILE *pFile, const pps_info_type *pPPS, +00221 const ULONG *aulBBD, size_t tBBDLen, +00222 const ULONG *aulSBD, size_t tSBDLen, +00223 const UCHAR *aucHeader) +00224 { +00225 section_block_type tSection; +00226 ULONG *aulSectPage, *aulCharPos; +00227 UCHAR *aucBuffer, *aucFpage; +00228 ULONG ulBeginOfText, ulTextOffset, ulBeginSectInfo; +00229 size_t tSectInfoLen, tIndex, tOffset, tLen, tBytes; +00230 UCHAR aucTmp[2]; +00231 +00232 fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); +00233 fail(aulBBD == NULL || aulSBD == NULL); +00234 +00235 ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ +00236 NO_DBG_HEX(ulBeginOfText); +00237 ulBeginSectInfo = ulGetLong(0xca, aucHeader); /* fcPlcfsed */ +00238 NO_DBG_HEX(ulBeginSectInfo); +00239 tSectInfoLen = (size_t)ulGetLong(0xce, aucHeader); /* lcbPlcfsed */ +00240 NO_DBG_DEC(tSectInfoLen); +00241 if (tSectInfoLen < 4) { +00242 DBG_DEC(tSectInfoLen); +00243 return; +00244 } +00245 +00246 aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable, +00247 aulBBD, tBBDLen, aulSBD, tSBDLen, +00248 ulBeginSectInfo, tSectInfoLen); +00249 if (aucBuffer == NULL) { +00250 return; +00251 } +00252 NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen); +00253 +00254 /* Read the Section Descriptors */ +00255 tLen = (tSectInfoLen - 4) / 16; +00256 /* Save the section offsets */ +00257 aulCharPos = xcalloc(tLen, sizeof(ULONG)); +00258 for (tIndex = 0, tOffset = 0; +00259 tIndex < tLen; +00260 tIndex++, tOffset += 4) { +00261 ulTextOffset = ulGetLong(tOffset, aucBuffer); +00262 NO_DBG_HEX(ulTextOffset); +00263 aulCharPos[tIndex] = ulBeginOfText + ulTextOffset; +00264 NO_DBG_HEX(aulCharPos[tIndex]); +00265 } +00266 /* Save the Sepx offsets */ +00267 aulSectPage = xcalloc(tLen, sizeof(ULONG)); +00268 for (tIndex = 0, tOffset = (tLen + 1) * 4; +00269 tIndex < tLen; +00270 tIndex++, tOffset += 12) { +00271 aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer); +00272 NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */ +00273 } +00274 aucBuffer = xfree(aucBuffer); +00275 +00276 /* Read the Section Properties */ +00277 for (tIndex = 0; tIndex < tLen; tIndex++) { +00278 if (aulSectPage[tIndex] == FC_INVALID) { +00279 vDefault2SectionInfoList(aulCharPos[tIndex]); +00280 continue; +00281 } +00282 /* Get the number of bytes to read */ +00283 if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, +00284 aulBBD, tBBDLen, BIG_BLOCK_SIZE, +00285 aucTmp, aulSectPage[tIndex], 2)) { +00286 continue; +00287 } +00288 tBytes = 2 + (size_t)usGetWord(0, aucTmp); +00289 NO_DBG_DEC(tBytes); +00290 /* Read the bytes */ +00291 aucFpage = xmalloc(tBytes); +00292 if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, +00293 aulBBD, tBBDLen, BIG_BLOCK_SIZE, +00294 aucFpage, aulSectPage[tIndex], tBytes)) { +00295 aucFpage = xfree(aucFpage); +00296 continue; +00297 } +00298 NO_DBG_PRINT_BLOCK(aucFpage, tBytes); +00299 /* Process the bytes */ +00300 vGetDefaultSection(&tSection); +00301 vGet8SectionInfo(aucFpage + 2, tBytes - 2, &tSection); +00302 vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]); +00303 aucFpage = xfree(aucFpage); +00304 } +00305 aulCharPos = xfree(aulCharPos); +00306 aulSectPage = xfree(aulSectPage); +00307 } /* end of vGet8SepInfo */ +00308 +00309 /* +00310 * Build the list with Header/Footer Information for Word 8/9/10/11 files +00311 */ +00312 void +00313 vGet8HdrFtrInfo(FILE *pFile, const pps_type *pTable, +00314 const ULONG *aulBBD, size_t tBBDLen, +00315 const ULONG *aulSBD, size_t tSBDLen, +00316 const UCHAR *aucHeader) +00317 { +00318 ULONG *aulCharPos; +00319 UCHAR *aucBuffer; +00320 ULONG ulHdrFtrOffset, ulBeginHdrFtrInfo; +00321 size_t tHdrFtrInfoLen, tIndex, tOffset, tLen; +00322 +00323 fail(pFile == NULL || pTable == NULL || aucHeader == NULL); +00324 fail(aulBBD == NULL || aulSBD == NULL); +00325 +00326 ulBeginHdrFtrInfo = ulGetLong(0xf2, aucHeader); /* fcPlcfhdd */ +00327 NO_DBG_HEX(ulBeginHdrFtrInfo); +00328 tHdrFtrInfoLen = (size_t)ulGetLong(0xf6, aucHeader); /* lcbPlcfhdd */ +00329 NO_DBG_DEC(tHdrFtrInfoLen); +00330 if (tHdrFtrInfoLen < 8) { +00331 DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen); +00332 return; +00333 } +00334 +00335 aucBuffer = aucFillInfoBuffer(pFile, pTable, +00336 aulBBD, tBBDLen, aulSBD, tSBDLen, +00337 ulBeginHdrFtrInfo, tHdrFtrInfoLen); +00338 if (aucBuffer == NULL) { +00339 return; +00340 } +00341 NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen); +00342 +00343 tLen = tHdrFtrInfoLen / 4 - 1; +00344 DBG_DEC_C(tLen % 12 != 1 && tLen % 12 != 7, tLen); +00345 /* Save the header/footer offsets */ +00346 aulCharPos = xcalloc(tLen, sizeof(ULONG)); +00347 for (tIndex = 0, tOffset = 0; +00348 tIndex < tLen; +00349 tIndex++, tOffset += 4) { +00350 ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer); +00351 NO_DBG_HEX(ulHdrFtrOffset); +00352 aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset); +00353 NO_DBG_HEX(aulCharPos[tIndex]); +00354 } +00355 vCreat8HdrFtrInfoList(aulCharPos, tLen); +00356 /* Clean up and leave */ +00357 aulCharPos = xfree(aulCharPos); +00358 aucBuffer = xfree(aucBuffer); +00359 } /* end of vGet8HdrFtrInfo */ +00360 +00361 /* +00362 * Translate the rowinfo to a member of the row_info enumeration +00363 */ +00364 row_info_enum +00365 eGet8RowInfo(int iFodo, +00366 const UCHAR *aucGrpprl, int iBytes, row_block_type *pRow) +00367 { +00368 int iFodoOff, iInfoLen; +00369 int iIndex, iSize, iCol; +00370 int iPosCurr, iPosPrev; +00371 USHORT usTmp; +00372 BOOL bFound2416_0, bFound2416_1, bFound2417_0, bFound2417_1; +00373 BOOL bFound244b_0, bFound244b_1, bFound244c_0, bFound244c_1; +00374 BOOL bFoundd608; +00375 +00376 fail(iFodo < 0 || aucGrpprl == NULL || pRow == NULL); +00377 +00378 iFodoOff = 0; +00379 bFound2416_0 = FALSE; +00380 bFound2416_1 = FALSE; +00381 bFound2417_0 = FALSE; +00382 bFound2417_1 = FALSE; +00383 bFound244b_0 = FALSE; +00384 bFound244b_1 = FALSE; +00385 bFound244c_0 = FALSE; +00386 bFound244c_1 = FALSE; +00387 bFoundd608 = FALSE; +00388 while (iBytes >= iFodoOff + 2) { +00389 iInfoLen = 0; +00390 switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) { +00391 case 0x2416: /* fInTable */ +00392 if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) { +00393 bFound2416_1 = TRUE; +00394 } else { +00395 bFound2416_0 = TRUE; +00396 } +00397 break; +00398 case 0x2417: /* fTtp */ +00399 if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) { +00400 bFound2417_1 = TRUE; +00401 } else { +00402 bFound2417_0 = TRUE; +00403 } +00404 break; +00405 case 0x244b: /* sub-table fInTable */ +00406 if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) { +00407 bFound244b_1 = TRUE; +00408 } else { +00409 bFound244b_0 = TRUE; +00410 } +00411 break; +00412 case 0x244c: /* sub-table fTtp */ +00413 if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) { +00414 bFound244c_1 = TRUE; +00415 } else { +00416 bFound244c_0 = TRUE; +00417 } +00418 break; +00419 case 0x6424: /* brcTop */ +00420 usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +00421 usTmp &= 0xff00; +00422 NO_DBG_DEC(usTmp >> 8); +00423 if (usTmp == 0) { +00424 pRow->ucBorderInfo &= ~TABLE_BORDER_TOP; +00425 } else { +00426 pRow->ucBorderInfo |= TABLE_BORDER_TOP; +00427 } +00428 break; +00429 case 0x6425: /* brcLeft */ +00430 usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +00431 usTmp &= 0xff00; +00432 NO_DBG_DEC(usTmp >> 8); +00433 if (usTmp == 0) { +00434 pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT; +00435 } else { +00436 pRow->ucBorderInfo |= TABLE_BORDER_LEFT; +00437 } +00438 break; +00439 case 0x6426: /* brcBottom */ +00440 usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +00441 usTmp &= 0xff00; +00442 NO_DBG_DEC(usTmp >> 8); +00443 if (usTmp == 0) { +00444 pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM; +00445 } else { +00446 pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM; +00447 } +00448 break; +00449 case 0x6427: /* brcRight */ +00450 usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +00451 usTmp &= 0xff00; +00452 NO_DBG_DEC(usTmp >> 8); +00453 if (usTmp == 0) { +00454 pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT; +00455 } else { +00456 pRow->ucBorderInfo |= TABLE_BORDER_RIGHT; +00457 } +00458 break; +00459 case 0xd606: /* cDefTable10 */ +00460 DBG_MSG("0xd606: sprmTDefTable10"); +00461 iSize = (int)usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +00462 DBG_DEC(iSize); +00463 break; +00464 case 0xd608: /* cDefTable */ +00465 iSize = (int)usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +00466 if (iSize < 6 || iBytes < iFodoOff + 8) { +00467 DBG_DEC(iSize); +00468 DBG_DEC(iFodoOff); +00469 iInfoLen = 2; +00470 break; +00471 } +00472 iCol = (int)ucGetByte(iFodo + iFodoOff + 4, aucGrpprl); +00473 if (iCol < 1 || +00474 iBytes < iFodoOff + 4 + (iCol + 1) * 2) { +00475 DBG_DEC(iCol); +00476 DBG_DEC(iFodoOff); +00477 iInfoLen = 2; +00478 break; +00479 } +00480 if (iCol >= (int)elementsof(pRow->asColumnWidth)) { +00481 DBG_DEC(iCol); +00482 werr(1, "The number of columns is corrupt"); +00483 } +00484 pRow->ucNumberOfColumns = (UCHAR)iCol; +00485 iPosPrev = (int)(short)usGetWord( +00486 iFodo + iFodoOff + 5, +00487 aucGrpprl); +00488 for (iIndex = 0; iIndex < iCol; iIndex++) { +00489 iPosCurr = (int)(short)usGetWord( +00490 iFodo + iFodoOff + 7 + iIndex * 2, +00491 aucGrpprl); +00492 pRow->asColumnWidth[iIndex] = +00493 (short)(iPosCurr - iPosPrev); +00494 iPosPrev = iPosCurr; +00495 } +00496 bFoundd608 = TRUE; +00497 break; +00498 default: +00499 break; +00500 } +00501 if (iInfoLen <= 0) { +00502 iInfoLen = +00503 iGet8InfoLength(iFodo + iFodoOff, aucGrpprl); +00504 fail(iInfoLen <= 0); +00505 } +00506 iFodoOff += iInfoLen; +00507 } +00508 +00509 if (bFound2417_1 && bFoundd608) { +00510 return found_end_of_row; +00511 } +00512 if (bFound2417_0 && !bFoundd608) { +00513 return found_not_end_of_row; +00514 } +00515 if (bFound2416_1 || bFound244b_1) { +00516 return found_a_cell; +00517 } +00518 if (bFound2416_0 || bFound244b_0) { +00519 return found_not_a_cell; +00520 } +00521 return found_nothing; +00522 } /* end of eGet8RowInfo */ +00523 +00524 /* +00525 * Fill the style information block with information +00526 * from a Word 8/9/10/11 file. +00527 */ +00528 void +00529 vGet8StyleInfo(int iFodo, +00530 const UCHAR *aucGrpprl, int iBytes, style_block_type *pStyle) +00531 { +00532 list_block_type tList6; +00533 const list_block_type *pList; +00534 int iFodoOff, iInfoLen; +00535 int iTmp, iDel, iAdd, iBefore; +00536 USHORT usOpCode, usTmp; +00537 short sTmp; +00538 +00539 fail(iFodo < 0 || aucGrpprl == NULL || pStyle == NULL); +00540 +00541 NO_DBG_DEC_C(pStyle->usListIndex != 0, pStyle->usIstd); +00542 NO_DBG_DEC_C(pStyle->usListIndex != 0, pStyle->usListIndex); +00543 +00544 (void)memset(&tList6, 0, sizeof(tList6)); +00545 +00546 iFodoOff = 0; +00547 while (iBytes >= iFodoOff + 2) { +00548 iInfoLen = 0; +00549 usOpCode = usGetWord(iFodo + iFodoOff, aucGrpprl); +00550 switch (usOpCode) { +00551 case 0x2403: /* jc */ +00552 pStyle->ucAlignment = ucGetByte( +00553 iFodo + iFodoOff + 2, aucGrpprl); +00554 break; +00555 case 0x260a: /* ilvl */ +00556 pStyle->ucListLevel = +00557 ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +00558 NO_DBG_DEC(pStyle->ucListLevel); +00559 pStyle->ucNumLevel = pStyle->ucListLevel; +00560 break; +00561 case 0x4600: /* istd */ +00562 usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +00563 NO_DBG_DEC(usTmp); +00564 break; +00565 case 0x460b: /* ilfo */ +00566 pStyle->usListIndex = +00567 usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +00568 NO_DBG_DEC(pStyle->usListIndex); +00569 break; +00570 case 0x4610: /* Nest dxaLeft */ +00571 sTmp = (short)usGetWord( +00572 iFodo + iFodoOff + 2, aucGrpprl); +00573 pStyle->sLeftIndent += sTmp; +00574 if (pStyle->sLeftIndent < 0) { +00575 pStyle->sLeftIndent = 0; +00576 } +00577 DBG_DEC(sTmp); +00578 DBG_DEC(pStyle->sLeftIndent); +00579 break; +00580 case 0xc60d: /* ChgTabsPapx */ +00581 case 0xc615: /* ChgTabs */ +00582 iTmp = (int)ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +00583 if (iTmp < 2) { +00584 iInfoLen = 1; +00585 break; +00586 } +00587 NO_DBG_DEC(iTmp); +00588 iDel = (int)ucGetByte(iFodo + iFodoOff + 3, aucGrpprl); +00589 if (iTmp < 2 + 2 * iDel) { +00590 iInfoLen = 1; +00591 break; +00592 } +00593 NO_DBG_DEC(iDel); +00594 iAdd = (int)ucGetByte( +00595 iFodo + iFodoOff + 4 + 2 * iDel, aucGrpprl); +00596 if (iTmp < 2 + 2 * iDel + 2 * iAdd) { +00597 iInfoLen = 1; +00598 break; +00599 } +00600 NO_DBG_DEC(iAdd); +00601 break; +00602 case 0x840e: /* dxaRight */ +00603 pStyle->sRightIndent = (short)usGetWord( +00604 iFodo + iFodoOff + 2, aucGrpprl); +00605 NO_DBG_DEC(pStyle->sRightIndent); +00606 break; +00607 case 0x840f: /* dxaLeft */ +00608 pStyle->sLeftIndent = (short)usGetWord( +00609 iFodo + iFodoOff + 2, aucGrpprl); +00610 NO_DBG_DEC(pStyle->sLeftIndent); +00611 break; +00612 case 0x8411: /* dxaLeft1 */ +00613 pStyle->sLeftIndent1 = (short)usGetWord( +00614 iFodo + iFodoOff + 2, aucGrpprl); +00615 NO_DBG_DEC(pStyle->sLeftIndent1); +00616 break; +00617 case 0xa413: /* dyaBefore */ +00618 pStyle->usBeforeIndent = usGetWord( +00619 iFodo + iFodoOff + 2, aucGrpprl); +00620 NO_DBG_DEC(pStyle->usBeforeIndent); +00621 break; +00622 case 0xa414: /* dyaAfter */ +00623 pStyle->usAfterIndent = usGetWord( +00624 iFodo + iFodoOff + 2, aucGrpprl); +00625 NO_DBG_DEC(pStyle->usAfterIndent); +00626 break; +00627 case 0xc63e: /* anld */ +00628 iTmp = (int)ucGetByte( +00629 iFodo + iFodoOff + 2, aucGrpprl); +00630 DBG_DEC_C(iTmp < 84, iTmp); +00631 if (iTmp >= 1) { +00632 tList6.ucNFC = ucGetByte( +00633 iFodo + iFodoOff + 3, aucGrpprl); +00634 } +00635 if (tList6.ucNFC != LIST_BULLETS && iTmp >= 2) { +00636 iBefore = (int)ucGetByte( +00637 iFodo + iFodoOff + 4, aucGrpprl); +00638 } else { +00639 iBefore = 0; +00640 } +00641 if (iTmp >= 12) { +00642 tList6.ulStartAt = (ULONG)usGetWord( +00643 iFodo + iFodoOff + 13, aucGrpprl); +00644 } +00645 if (iTmp >= iBefore + 22) { +00646 tList6.usListChar = usGetWord( +00647 iFodo + iFodoOff + iBefore + 23, +00648 aucGrpprl); +00649 DBG_HEX(tList6.usListChar); +00650 } +00651 break; +00652 default: +00653 NO_DBG_HEX(usOpCode); +00654 break; +00655 } +00656 if (iInfoLen <= 0) { +00657 iInfoLen = +00658 iGet8InfoLength(iFodo + iFodoOff, aucGrpprl); +00659 fail(iInfoLen <= 0); +00660 } +00661 iFodoOff += iInfoLen; +00662 } +00663 +00664 if (pStyle->usListIndex == 2047) { +00665 /* Old style list */ +00666 pStyle->usStartAt = (USHORT)tList6.ulStartAt; +00667 pStyle->usListChar = tList6.usListChar; +00668 pStyle->ucNFC = tList6.ucNFC; +00669 } else { +00670 /* New style list */ +00671 pList = pGetListInfo(pStyle->usListIndex, pStyle->ucListLevel); +00672 if (pList != NULL) { +00673 pStyle->bNoRestart = pList->bNoRestart; +00674 fail(pList->ulStartAt > (ULONG)USHRT_MAX); +00675 pStyle->usStartAt = (USHORT)pList->ulStartAt; +00676 pStyle->usListChar = pList->usListChar; +00677 pStyle->ucNFC = pList->ucNFC; +00678 if (pStyle->sLeftIndent <= 0) { +00679 pStyle->sLeftIndent = pList->sLeftIndent; +00680 } +00681 } +00682 } +00683 } /* end of vGet8StyleInfo */ +00684 +00685 /* +00686 * Get the left indentation value from the style information block +00687 * +00688 * Returns the value when found, otherwise 0 +00689 */ +00690 static short +00691 sGetLeftIndent(const UCHAR *aucGrpprl, size_t tBytes) +00692 { +00693 int iOffset, iInfoLen; +00694 USHORT usOpCode, usTmp; +00695 +00696 fail(aucGrpprl == NULL); +00697 +00698 iOffset = 0; +00699 while (tBytes >= (size_t)iOffset + 4) { +00700 usOpCode = usGetWord(iOffset, aucGrpprl); +00701 if (usOpCode == 0x840f) { /* dxaLeft */ +00702 usTmp = usGetWord(iOffset + 2, aucGrpprl); +00703 if (usTmp <= 0x7fff) { +00704 NO_DBG_DEC(usTmp); +00705 return (short)usTmp; +00706 } +00707 } +00708 iInfoLen = iGet8InfoLength(iOffset, aucGrpprl); +00709 fail(iInfoLen <= 0); +00710 iOffset += iInfoLen; +00711 } +00712 return 0; +00713 } /* end of sGetLeftIndent */ +00714 +00715 /* +00716 * Build the list with List Information for Word 8/9/10/11 files +00717 */ +00718 void +00719 vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS, +00720 const ULONG *aulBBD, size_t tBBDLen, +00721 const ULONG *aulSBD, size_t tSBDLen, +00722 const UCHAR *aucHeader) +00723 { +00724 list_block_type tList; +00725 const ULONG *aulBlockDepot; +00726 UCHAR *aucLfoInfo, *aucLstfInfo, *aucPapx, *aucXString; +00727 ULONG ulBeginLfoInfo, ulBeginLstfInfo, ulBeginLvlfInfo; +00728 ULONG ulListID, ulStart; +00729 size_t tBlockDepotLen, tBlockSize; +00730 size_t tLfoInfoLen, tLstfInfoLen, tPapxLen, tXstLen, tOff; +00731 size_t tLstfRecords, tStart, tIndex; +00732 int iNums; +00733 USHORT usIstd; +00734 UCHAR ucTmp, ucListLevel, ucMaxLevel, ucChpxLen; +00735 UCHAR aucLvlfInfo[28], aucXst[2]; +00736 +00737 fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); +00738 fail(aulBBD == NULL || aulSBD == NULL); +00739 +00740 NO_DBG_DEC(pPPS->tTable.ulSB); +00741 NO_DBG_HEX(pPPS->tTable.ulSize); +00742 if (pPPS->tTable.ulSize == 0) { +00743 DBG_MSG("No list information"); +00744 return; +00745 } +00746 +00747 if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) { +00748 /* Use the Small Block Depot */ +00749 aulBlockDepot = aulSBD; +00750 tBlockDepotLen = tSBDLen; +00751 tBlockSize = SMALL_BLOCK_SIZE; +00752 } else { +00753 /* Use the Big Block Depot */ +00754 aulBlockDepot = aulBBD; +00755 tBlockDepotLen = tBBDLen; +00756 tBlockSize = BIG_BLOCK_SIZE; +00757 } +00758 +00759 /* LFO (List Format Override) */ +00760 ulBeginLfoInfo = ulGetLong(0x2ea, aucHeader); /* fcPlfLfo */ +00761 DBG_HEX(ulBeginLfoInfo); +00762 tLfoInfoLen = (size_t)ulGetLong(0x2ee, aucHeader); /* lcbPlfLfo */ +00763 DBG_DEC(tLfoInfoLen); +00764 if (tLfoInfoLen == 0) { +00765 DBG_MSG("No lists in this document"); +00766 return; +00767 } +00768 +00769 aucLfoInfo = xmalloc(tLfoInfoLen); +00770 if (!bReadBuffer(pFile, pPPS->tTable.ulSB, +00771 aulBlockDepot, tBlockDepotLen, tBlockSize, +00772 aucLfoInfo, ulBeginLfoInfo, tLfoInfoLen)) { +00773 aucLfoInfo = xfree(aucLfoInfo); +00774 return; +00775 } +00776 NO_DBG_PRINT_BLOCK(aucLfoInfo, tLfoInfoLen); +00777 vBuildLfoList(aucLfoInfo, tLfoInfoLen); +00778 aucLfoInfo = xfree(aucLfoInfo); +00779 +00780 /* LSTF (LiST data on File) */ +00781 ulBeginLstfInfo = ulGetLong(0x2e2, aucHeader); /* fcPlcfLst */ +00782 DBG_HEX(ulBeginLstfInfo); +00783 tLstfInfoLen = (size_t)ulGetLong(0x2e6, aucHeader); /* lcbPlcfLst */ +00784 DBG_DEC(tLstfInfoLen); +00785 if (tLstfInfoLen == 0) { +00786 DBG_MSG("No list data on file"); +00787 return; +00788 } +00789 +00790 aucLstfInfo = xmalloc(tLstfInfoLen); +00791 if (!bReadBuffer(pFile, pPPS->tTable.ulSB, +00792 aulBlockDepot, tBlockDepotLen, tBlockSize, +00793 aucLstfInfo, ulBeginLstfInfo, tLstfInfoLen)) { +00794 aucLstfInfo = xfree(aucLstfInfo); +00795 return; +00796 } +00797 NO_DBG_PRINT_BLOCK(aucLstfInfo, tLstfInfoLen); +00798 +00799 tLstfRecords = (size_t)usGetWord(0, aucLstfInfo); +00800 if (2 + tLstfRecords * 28 < tLstfInfoLen) { +00801 DBG_DEC(2 + tLstfRecords * 28); +00802 DBG_DEC(tLstfInfoLen); +00803 aucLstfInfo = xfree(aucLstfInfo); +00804 return; +00805 } +00806 +00807 /* LVLF (List leVeL on File) */ +00808 ulBeginLvlfInfo = ulBeginLstfInfo + tLstfInfoLen; +00809 DBG_HEX(ulBeginLvlfInfo); +00810 +00811 aucXString = NULL; +00812 ulStart = ulBeginLvlfInfo; +00813 +00814 for (tIndex = 0, tStart = 2; +00815 tIndex < tLstfRecords; +00816 tIndex++, tStart += 28) { +00817 ulListID = ulGetLong(tStart, aucLstfInfo); +00818 NO_DBG_HEX(ulListID); +00819 ucTmp = ucGetByte(tStart + 26, aucLstfInfo); +00820 ucMaxLevel = odd(ucTmp) ? 1 : 9; +00821 for (ucListLevel = 0; ucListLevel < ucMaxLevel; ucListLevel++) { +00822 fail(aucXString != NULL); +00823 usIstd = usGetWord( +00824 tStart + 8 + 2 * (size_t)ucListLevel, +00825 aucLstfInfo); +00826 DBG_DEC_C(usIstd != STI_NIL, usIstd); +00827 NO_DBG_HEX(ulStart); +00828 (void)memset(&tList, 0, sizeof(tList)); +00829 /* Read the lvlf (List leVeL on File) */ +00830 if (!bReadBuffer(pFile, pPPS->tTable.ulSB, +00831 aulBlockDepot, tBlockDepotLen, +00832 tBlockSize, aucLvlfInfo, +00833 ulStart, sizeof(aucLvlfInfo))) { +00834 aucLstfInfo = xfree(aucLstfInfo); +00835 return; +00836 } +00837 NO_DBG_PRINT_BLOCK(aucLvlfInfo, sizeof(aucLvlfInfo)); +00838 if (bAllZero(aucLvlfInfo, sizeof(aucLvlfInfo))) { +00839 tList.ulStartAt = 1; +00840 tList.ucNFC = 0x00; +00841 tList.bNoRestart = FALSE; +00842 } else { +00843 tList.ulStartAt = ulGetLong(0, aucLvlfInfo); +00844 tList.ucNFC = ucGetByte(4, aucLvlfInfo); +00845 ucTmp = ucGetByte(5, aucLvlfInfo); +00846 tList.bNoRestart = (ucTmp & BIT(3)) != 0; +00847 DBG_MSG_C((ucTmp & BIT(4)) != 0 && +00848 (ucTmp & BIT(6)) != 0, "Found one"); +00849 } +00850 ulStart += sizeof(aucLvlfInfo); +00851 tPapxLen = (size_t)ucGetByte(25, aucLvlfInfo); +00852 if (tPapxLen != 0) { +00853 aucPapx = xmalloc(tPapxLen); +00854 /* Read the Papx */ +00855 if (!bReadBuffer(pFile, pPPS->tTable.ulSB, +00856 aulBlockDepot, tBlockDepotLen, +00857 tBlockSize, aucPapx, +00858 ulStart, tPapxLen)) { +00859 aucPapx = xfree(aucPapx); +00860 aucLstfInfo = xfree(aucLstfInfo); +00861 return; +00862 } +00863 NO_DBG_PRINT_BLOCK(aucPapx, tPapxLen); +00864 tList.sLeftIndent = +00865 sGetLeftIndent(aucPapx, tPapxLen); +00866 aucPapx = xfree(aucPapx); +00867 } +00868 ulStart += tPapxLen; +00869 ucChpxLen = ucGetByte(24, aucLvlfInfo); +00870 ulStart += (ULONG)ucChpxLen; +00871 /* Read the length of the XString */ +00872 if (!bReadBuffer(pFile, pPPS->tTable.ulSB, +00873 aulBlockDepot, tBlockDepotLen, +00874 tBlockSize, aucXst, +00875 ulStart, sizeof(aucXst))) { +00876 aucLstfInfo = xfree(aucLstfInfo); +00877 return; +00878 } +00879 NO_DBG_PRINT_BLOCK(aucXst, sizeof(aucXst)); +00880 tXstLen = (size_t)usGetWord(0, aucXst); +00881 ulStart += sizeof(aucXst); +00882 if (tXstLen == 0) { +00883 tList.usListChar = DEFAULT_LISTCHAR; +00884 vAdd2ListInfoList(ulListID, +00885 usIstd, +00886 ucListLevel, +00887 &tList); +00888 continue; +00889 } +00890 tXstLen *= 2; /* Length in chars to length in bytes */ +00891 aucXString = xmalloc(tXstLen); +00892 /* Read the XString */ +00893 if (!bReadBuffer(pFile, pPPS->tTable.ulSB, +00894 aulBlockDepot, tBlockDepotLen, +00895 tBlockSize, aucXString, +00896 ulStart, tXstLen)) { +00897 aucXString = xfree(aucXString); +00898 aucLstfInfo = xfree(aucLstfInfo); +00899 return; +00900 } +00901 NO_DBG_PRINT_BLOCK(aucXString, tXstLen); +00902 tOff = 0; +00903 for (iNums = 6; iNums < 15; iNums++) { +00904 ucTmp = ucGetByte(iNums, aucLvlfInfo); +00905 if (ucTmp == 0) { +00906 break; +00907 } +00908 tOff = (size_t)ucTmp; +00909 } +00910 tOff *= 2; /* Offset in chars to offset in bytes */ +00911 NO_DBG_DEC(tOff); +00912 if (tList.ucNFC == LIST_SPECIAL || +00913 tList.ucNFC == LIST_SPECIAL2 || +00914 tList.ucNFC == LIST_BULLETS) { +00915 tList.usListChar = usGetWord(0, aucXString); +00916 } else if (tOff != 0 && tOff < tXstLen) { +00917 tList.usListChar = usGetWord(tOff, aucXString); +00918 } else { +00919 tList.usListChar = DEFAULT_LISTCHAR; +00920 } +00921 vAdd2ListInfoList(ulListID, +00922 usIstd, +00923 ucListLevel, +00924 &tList); +00925 ulStart += tXstLen; +00926 aucXString = xfree(aucXString); +00927 } +00928 } +00929 aucLstfInfo = xfree(aucLstfInfo); +00930 } /* end of vGet8LstInfo */ +00931 +00932 /* +00933 * Build the lists with Paragraph Information for Word 8/9/10/11 files +00934 */ +00935 void +00936 vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS, +00937 const ULONG *aulBBD, size_t tBBDLen, +00938 const ULONG *aulSBD, size_t tSBDLen, +00939 const UCHAR *aucHeader) +00940 { +00941 row_block_type tRow; +00942 style_block_type tStyle; +00943 ULONG *aulParfPage; +00944 UCHAR *aucBuffer; +00945 ULONG ulCharPos, ulCharPosFirst, ulCharPosLast; +00946 ULONG ulBeginParfInfo; +00947 size_t tParfInfoLen, tOffset, tLen; +00948 int iIndex, iIndex2, iRun, iFodo, iLen; +00949 row_info_enum eRowInfo; +00950 USHORT usIstd; +00951 UCHAR aucFpage[BIG_BLOCK_SIZE]; +00952 +00953 fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); +00954 fail(aulBBD == NULL || aulSBD == NULL); +00955 +00956 ulBeginParfInfo = ulGetLong(0x102, aucHeader); /* fcPlcfbtePapx */ +00957 NO_DBG_HEX(ulBeginParfInfo); +00958 tParfInfoLen = (size_t)ulGetLong(0x106, aucHeader); /* lcbPlcfbtePapx */ +00959 NO_DBG_DEC(tParfInfoLen); +00960 if (tParfInfoLen < 4) { +00961 DBG_DEC(tParfInfoLen); +00962 return; +00963 } +00964 +00965 aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable, +00966 aulBBD, tBBDLen, aulSBD, tSBDLen, +00967 ulBeginParfInfo, tParfInfoLen); +00968 if (aucBuffer == NULL) { +00969 return; +00970 } +00971 NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen); +00972 +00973 tLen = (tParfInfoLen / 4 - 1) / 2; +00974 aulParfPage = xcalloc(tLen, sizeof(ULONG)); +00975 for (iIndex = 0, tOffset = (tLen + 1) * 4; +00976 iIndex < (int)tLen; +00977 iIndex++, tOffset += 4) { +00978 aulParfPage[iIndex] = ulGetLong(tOffset, aucBuffer); +00979 NO_DBG_DEC(aulParfPage[iIndex]); +00980 } +00981 DBG_HEX(ulGetLong(0, aucBuffer)); +00982 aucBuffer = xfree(aucBuffer); +00983 NO_DBG_PRINT_BLOCK(aucHeader, HEADER_SIZE); +00984 +00985 (void)memset(&tRow, 0, sizeof(tRow)); +00986 ulCharPosFirst = CP_INVALID; +00987 for (iIndex = 0; iIndex < (int)tLen; iIndex++) { +00988 fail(aulParfPage[iIndex] > ULONG_MAX / BIG_BLOCK_SIZE); +00989 if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, +00990 aulBBD, tBBDLen, BIG_BLOCK_SIZE, +00991 aucFpage, +00992 aulParfPage[iIndex] * BIG_BLOCK_SIZE, +00993 BIG_BLOCK_SIZE)) { +00994 break; +00995 } +00996 NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); +00997 iRun = (int)ucGetByte(0x1ff, aucFpage); +00998 NO_DBG_DEC(iRun); +00999 for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { +01000 NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage)); +01001 iFodo = 2 * (int)ucGetByte( +01002 (iRun + 1) * 4 + iIndex2 * 13, aucFpage); +01003 if (iFodo <= 0) { +01004 continue; +01005 } +01006 +01007 iLen = 2 * (int)ucGetByte(iFodo, aucFpage); +01008 if (iLen == 0) { +01009 iFodo++; +01010 iLen = 2 * (int)ucGetByte(iFodo, aucFpage); +01011 } +01012 +01013 usIstd = usGetWord(iFodo + 1, aucFpage); +01014 vFillStyleFromStylesheet(usIstd, &tStyle); +01015 vGet8StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle); +01016 ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); +01017 NO_DBG_HEX(ulCharPos); +01018 tStyle.ulFileOffset = ulCharPos2FileOffsetX( +01019 ulCharPos, &tStyle.eListID); +01020 vAdd2StyleInfoList(&tStyle); +01021 +01022 eRowInfo = eGet8RowInfo(iFodo, +01023 aucFpage + 3, iLen - 3, &tRow); +01024 switch (eRowInfo) { +01025 case found_a_cell: +01026 if (ulCharPosFirst != CP_INVALID) { +01027 break; +01028 } +01029 ulCharPosFirst = ulGetLong( +01030 iIndex2 * 4, aucFpage); +01031 NO_DBG_HEX(ulCharPosFirst); +01032 tRow.ulCharPosStart = ulCharPosFirst; +01033 tRow.ulFileOffsetStart = +01034 ulCharPos2FileOffset(ulCharPosFirst); +01035 NO_DBG_HEX_C( +01036 tRow.ulFileOffsetStart == FC_INVALID, +01037 ulCharPosFirst); +01038 break; +01039 case found_end_of_row: +01040 ulCharPosLast = ulGetLong( +01041 iIndex2 * 4, aucFpage); +01042 NO_DBG_HEX(ulCharPosLast); +01043 tRow.ulCharPosEnd = ulCharPosLast; +01044 tRow.ulFileOffsetEnd = +01045 ulCharPos2FileOffset(ulCharPosLast); +01046 NO_DBG_HEX_C(tRow.ulFileOffsetEnd == FC_INVALID, +01047 ulCharPosLast); +01048 vAdd2RowInfoList(&tRow); +01049 (void)memset(&tRow, 0, sizeof(tRow)); +01050 ulCharPosFirst = CP_INVALID; +01051 break; +01052 case found_nothing: +01053 break; +01054 default: +01055 DBG_DEC(eRowInfo); +01056 break; +01057 } +01058 } +01059 } +01060 aulParfPage = xfree(aulParfPage); +01061 } /* end of vGet8PapInfo */ +01062 +01063 /* +01064 * Fill the font information block with information +01065 * from a Word 8/9/10/11 file. +01066 */ +01067 void +01068 vGet8FontInfo(int iFodo, USHORT usIstd, +01069 const UCHAR *aucGrpprl, int iBytes, font_block_type *pFont) +01070 { +01071 long lTmp; +01072 int iFodoOff, iInfoLen; +01073 USHORT usFtc0, usFtc1, usFtc2, usTmp; +01074 UCHAR ucTmp; +01075 +01076 fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL); +01077 +01078 usFtc0 = USHRT_MAX; +01079 usFtc1 = USHRT_MAX; +01080 usFtc2 = USHRT_MAX; +01081 +01082 iFodoOff = 0; +01083 while (iBytes >= iFodoOff + 2) { +01084 switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) { +01085 case 0x0800: /* fRMarkDel */ +01086 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01087 if (ucTmp == 0) { +01088 pFont->usFontStyle &= ~FONT_MARKDEL; +01089 } else { +01090 pFont->usFontStyle |= FONT_MARKDEL; +01091 } +01092 break; +01093 case 0x0835: /* fBold */ +01094 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01095 switch (ucTmp) { +01096 case 0: /* Unset */ +01097 pFont->usFontStyle &= ~FONT_BOLD; +01098 break; +01099 case 1: /* Set */ +01100 pFont->usFontStyle |= FONT_BOLD; +01101 break; +01102 case 128: /* Unchanged */ +01103 break; +01104 case 129: /* Negation */ +01105 pFont->usFontStyle ^= FONT_BOLD; +01106 break; +01107 default: +01108 DBG_DEC(ucTmp); +01109 DBG_FIXME(); +01110 break; +01111 } +01112 break; +01113 case 0x0836: /* fItalic */ +01114 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01115 switch (ucTmp) { +01116 case 0: /* Unset */ +01117 pFont->usFontStyle &= ~FONT_ITALIC; +01118 break; +01119 case 1: /* Set */ +01120 pFont->usFontStyle |= FONT_ITALIC; +01121 break; +01122 case 128: /* Unchanged */ +01123 break; +01124 case 129: /* Negation */ +01125 pFont->usFontStyle ^= FONT_ITALIC; +01126 break; +01127 default: +01128 DBG_DEC(ucTmp); +01129 DBG_FIXME(); +01130 break; +01131 } +01132 break; +01133 case 0x0837: /* fStrike */ +01134 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01135 switch (ucTmp) { +01136 case 0: /* Unset */ +01137 pFont->usFontStyle &= ~FONT_STRIKE; +01138 break; +01139 case 1: /* Set */ +01140 pFont->usFontStyle |= FONT_STRIKE; +01141 break; +01142 case 128: /* Unchanged */ +01143 break; +01144 case 129: /* Negation */ +01145 pFont->usFontStyle ^= FONT_STRIKE; +01146 break; +01147 default: +01148 DBG_DEC(ucTmp); +01149 DBG_FIXME(); +01150 break; +01151 } +01152 break; +01153 case 0x083a: /* fSmallCaps */ +01154 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01155 switch (ucTmp) { +01156 case 0: /* Unset */ +01157 pFont->usFontStyle &= ~FONT_SMALL_CAPITALS; +01158 break; +01159 case 1: /* Set */ +01160 pFont->usFontStyle |= FONT_SMALL_CAPITALS; +01161 break; +01162 case 128: /* Unchanged */ +01163 break; +01164 case 129: /* Negation */ +01165 pFont->usFontStyle ^= FONT_SMALL_CAPITALS; +01166 break; +01167 default: +01168 DBG_DEC(ucTmp); +01169 DBG_FIXME(); +01170 break; +01171 } +01172 break; +01173 case 0x083b: /* fCaps */ +01174 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01175 switch (ucTmp) { +01176 case 0: /* Unset */ +01177 pFont->usFontStyle &= ~FONT_CAPITALS; +01178 break; +01179 case 1: /* Set */ +01180 pFont->usFontStyle |= FONT_CAPITALS; +01181 break; +01182 case 128: /* Unchanged */ +01183 break; +01184 case 129: /* Negation */ +01185 pFont->usFontStyle ^= FONT_CAPITALS; +01186 break; +01187 default: +01188 DBG_DEC(ucTmp); +01189 DBG_FIXME(); +01190 break; +01191 } +01192 break; +01193 case 0x083c: /* fVanish */ +01194 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01195 switch (ucTmp) { +01196 case 0: /* Unset */ +01197 pFont->usFontStyle &= ~FONT_HIDDEN; +01198 break; +01199 case 1: /* Set */ +01200 pFont->usFontStyle |= FONT_HIDDEN; +01201 break; +01202 case 128: /* Unchanged */ +01203 break; +01204 case 129: /* Negation */ +01205 pFont->usFontStyle ^= FONT_HIDDEN; +01206 break; +01207 default: +01208 DBG_DEC(ucTmp); +01209 DBG_FIXME(); +01210 break; +01211 } +01212 break; +01213 case 0x2a32: /* cDefault */ +01214 pFont->usFontStyle &= FONT_HIDDEN; +01215 pFont->ucFontColor = FONT_COLOR_DEFAULT; +01216 break; +01217 case 0x2a33: /* cPlain */ +01218 DBG_MSG("2a33: cPlain"); +01219 vFillFontFromStylesheet(usIstd, pFont); +01220 break; +01221 case 0x2a3e: /* cKul */ +01222 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01223 if (ucTmp == 0 || ucTmp == 5) { +01224 pFont->usFontStyle &= ~FONT_UNDERLINE; +01225 } else { +01226 NO_DBG_MSG("Underline text"); +01227 pFont->usFontStyle |= FONT_UNDERLINE; +01228 if (ucTmp == 6) { +01229 DBG_MSG("Bold text"); +01230 pFont->usFontStyle |= FONT_BOLD; +01231 } +01232 } +01233 break; +01234 case 0x2a42: /* cIco */ +01235 pFont->ucFontColor = +01236 ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01237 NO_DBG_DEC(pFont->ucFontColor); +01238 break; +01239 case 0x2a44: /* cHpsInc */ +01240 DBG_MSG("0x2a44: sprmCHpsInc"); +01241 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01242 DBG_DEC(ucTmp); +01243 break; +01244 case 0x2a48: /* cIss */ +01245 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01246 ucTmp &= 0x07; +01247 if (ucTmp == 1) { +01248 pFont->usFontStyle |= FONT_SUPERSCRIPT; +01249 NO_DBG_MSG("Superscript"); +01250 } else if (ucTmp == 2) { +01251 pFont->usFontStyle |= FONT_SUBSCRIPT; +01252 NO_DBG_MSG("Subscript"); +01253 } +01254 break; +01255 case 0x4a30: /* cIstd */ +01256 usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +01257 NO_DBG_DEC(usTmp); +01258 break; +01259 case 0x4a43: /* cHps */ +01260 pFont->usFontSize = +01261 usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +01262 NO_DBG_DEC(pFont->usFontSize); +01263 break; +01264 case 0x4a4d: /* cHpsMul */ +01265 DBG_MSG("0x4a4d: sprmCHpsMul"); +01266 usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +01267 DBG_DEC(usTmp); +01268 break; +01269 case 0x4a4f: /* cFtc0 */ +01270 usFtc0 = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +01271 break; +01272 case 0x4a50: /* cFtc1 */ +01273 usFtc1 = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +01274 break; +01275 case 0x4a51: /* cFtc2 */ +01276 usFtc2 = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +01277 break; +01278 case 0xca47: /* cMajority */ +01279 DBG_MSG("0xca47: sprmCMajority"); +01280 break; +01281 case 0xca4a: /* cHpsInc1 */ +01282 usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl); +01283 lTmp = (long)pFont->usFontSize + (long)usTmp; +01284 if (lTmp < 8) { +01285 pFont->usFontSize = 8; +01286 } else if (lTmp > 32766) { +01287 pFont->usFontSize = 32766; +01288 } else { +01289 pFont->usFontSize = (USHORT)lTmp; +01290 } +01291 break; +01292 case 0xca4c: /* cMajority50 */ +01293 DBG_MSG("0xca4c: sprmCMajority50"); +01294 break; +01295 case 0xea3f: /* cHps, cHpsPos */ +01296 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01297 DBG_DEC(ucTmp); +01298 if (ucTmp != 0) { +01299 pFont->usFontSize = (USHORT)ucTmp; +01300 } +01301 ucTmp = ucGetByte(iFodo + iFodoOff + 3, aucGrpprl); +01302 DBG_DEC(ucTmp); +01303 break; +01304 default: +01305 break; +01306 } +01307 iInfoLen = iGet8InfoLength(iFodo + iFodoOff, aucGrpprl); +01308 fail(iInfoLen <= 0); +01309 iFodoOff += iInfoLen; +01310 } +01311 +01312 /* Combine the Ftc's to a FontNumber */ +01313 NO_DBG_DEC_C(usFtc0 != USHRT_MAX, usFtc0); +01314 NO_DBG_DEC_C(usFtc2 != USHRT_MAX, usFtc2); +01315 NO_DBG_DEC_C(usFtc1 != USHRT_MAX, usFtc1); +01316 if (usFtc0 <= 0x7fff) { +01317 if (usFtc0 <= (USHORT)UCHAR_MAX) { +01318 pFont->ucFontNumber = (UCHAR)usFtc0; +01319 } else { +01320 DBG_DEC(usFtc0); +01321 DBG_FIXME(); +01322 pFont->ucFontNumber = 0; +01323 } +01324 } else if (usFtc2 <= 0x7fff) { +01325 if (usFtc2 <= (USHORT)UCHAR_MAX) { +01326 pFont->ucFontNumber = (UCHAR)usFtc2; +01327 } else { +01328 DBG_DEC(usFtc2); +01329 DBG_FIXME(); +01330 pFont->ucFontNumber = 0; +01331 } +01332 } else if (usFtc1 <= 0x7fff) { +01333 if (usFtc1 <= (USHORT)UCHAR_MAX) { +01334 pFont->ucFontNumber = (UCHAR)usFtc1; +01335 } else { +01336 DBG_DEC(usFtc1); +01337 DBG_FIXME(); +01338 pFont->ucFontNumber = 0; +01339 } +01340 } +01341 } /* end of vGet8FontInfo */ +01342 +01343 /* +01344 * Fill the picture information block with information +01345 * from a Word 8/9/10/11 file. +01346 * Returns TRUE when successful, otherwise FALSE +01347 */ +01348 static BOOL +01349 bGet8PicInfo(int iFodo, +01350 const UCHAR *aucGrpprl, int iBytes, picture_block_type *pPicture) +01351 { +01352 ULONG ulTmp; +01353 int iFodoOff, iInfoLen; +01354 BOOL bFound; +01355 UCHAR ucTmp; +01356 +01357 fail(iFodo <= 0 || aucGrpprl == NULL || pPicture == NULL); +01358 +01359 iFodoOff = 0; +01360 bFound = FALSE; +01361 while (iBytes >= iFodoOff + 2) { +01362 switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) { +01363 #if 0 +01364 case 0x0806: /* fData */ +01365 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01366 if (ucTmp == 0x01) { +01367 /* Not a picture, but a form field */ +01368 return FALSE; +01369 } +01370 DBG_DEC_C(ucTmp != 0, ucTmp); +01371 break; +01372 #endif +01373 case 0x080a: /* fOle2 */ +01374 ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +01375 if (ucTmp == 0x01) { +01376 /* Not a picture, but an OLE object */ +01377 return FALSE; +01378 } +01379 DBG_DEC_C(ucTmp != 0, ucTmp); +01380 break; +01381 case 0x680e: /* fcObj */ +01382 ulTmp = ulGetLong(iFodo + iFodoOff + 2, aucGrpprl); +01383 DBG_HEX(ulTmp); +01384 break; +01385 case 0x6a03: /* fcPic */ +01386 pPicture->ulPictureOffset = ulGetLong( +01387 iFodo + iFodoOff + 2, aucGrpprl); +01388 bFound = TRUE; +01389 break; +01390 default: +01391 break; +01392 } +01393 iInfoLen = iGet8InfoLength(iFodo + iFodoOff, aucGrpprl); +01394 fail(iInfoLen <= 0); +01395 iFodoOff += iInfoLen; +01396 } +01397 return bFound; +01398 } /* end of bGet8PicInfo */ +01399 +01400 /* +01401 * Build the lists with Character Information for Word 8/9/10/11 files +01402 */ +01403 void +01404 vGet8ChrInfo(FILE *pFile, const pps_info_type *pPPS, +01405 const ULONG *aulBBD, size_t tBBDLen, +01406 const ULONG *aulSBD, size_t tSBDLen, +01407 const UCHAR *aucHeader) +01408 { +01409 font_block_type tFont; +01410 picture_block_type tPicture; +01411 ULONG *aulCharPage; +01412 UCHAR *aucBuffer; +01413 ULONG ulFileOffset, ulCharPos, ulBeginCharInfo; +01414 size_t tCharInfoLen, tOffset, tLen; +01415 int iIndex, iIndex2, iRun, iFodo, iLen; +01416 USHORT usIstd; +01417 UCHAR aucFpage[BIG_BLOCK_SIZE]; +01418 +01419 fail(pFile == NULL || pPPS == NULL || aucHeader == NULL); +01420 fail(aulBBD == NULL || aulSBD == NULL); +01421 +01422 ulBeginCharInfo = ulGetLong(0xfa, aucHeader); /* fcPlcfbteChpx */ +01423 NO_DBG_HEX(ulBeginCharInfo); +01424 tCharInfoLen = (size_t)ulGetLong(0xfe, aucHeader); /* lcbPlcfbteChpx */ +01425 NO_DBG_DEC(tCharInfoLen); +01426 if (tCharInfoLen < 4) { +01427 DBG_DEC(tCharInfoLen); +01428 return; +01429 } +01430 +01431 aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable, +01432 aulBBD, tBBDLen, aulSBD, tSBDLen, +01433 ulBeginCharInfo, tCharInfoLen); +01434 if (aucBuffer == NULL) { +01435 return; +01436 } +01437 NO_DBG_PRINT_BLOCK(aucBuffer, tCharInfoLen); +01438 +01439 tLen = (tCharInfoLen / 4 - 1) / 2; +01440 aulCharPage = xcalloc(tLen, sizeof(ULONG)); +01441 for (iIndex = 0, tOffset = (tLen + 1) * 4; +01442 iIndex < (int)tLen; +01443 iIndex++, tOffset += 4) { +01444 aulCharPage[iIndex] = ulGetLong(tOffset, aucBuffer); +01445 NO_DBG_DEC(aulCharPage[iIndex]); +01446 } +01447 DBG_HEX(ulGetLong(0, aucBuffer)); +01448 aucBuffer = xfree(aucBuffer); +01449 NO_DBG_PRINT_BLOCK(aucHeader, HEADER_SIZE); +01450 +01451 for (iIndex = 0; iIndex < (int)tLen; iIndex++) { +01452 fail(aulCharPage[iIndex] > ULONG_MAX / BIG_BLOCK_SIZE); +01453 if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB, +01454 aulBBD, tBBDLen, BIG_BLOCK_SIZE, +01455 aucFpage, +01456 aulCharPage[iIndex] * BIG_BLOCK_SIZE, +01457 BIG_BLOCK_SIZE)) { +01458 break; +01459 } +01460 NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); +01461 iRun = (int)ucGetByte(0x1ff, aucFpage); +01462 NO_DBG_DEC(iRun); +01463 for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { +01464 ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); +01465 ulFileOffset = ulCharPos2FileOffset(ulCharPos); +01466 iFodo = 2 * (int)ucGetByte( +01467 (iRun + 1) * 4 + iIndex2, aucFpage); +01468 +01469 iLen = (int)ucGetByte(iFodo, aucFpage); +01470 +01471 usIstd = usGetIstd(ulFileOffset); +01472 vFillFontFromStylesheet(usIstd, &tFont); +01473 if (iFodo != 0) { +01474 vGet8FontInfo(iFodo, usIstd, +01475 aucFpage + 1, iLen - 1, &tFont); +01476 } +01477 tFont.ulFileOffset = ulFileOffset; +01478 vAdd2FontInfoList(&tFont); +01479 +01480 if (iFodo <= 0) { +01481 continue; +01482 } +01483 +01484 (void)memset(&tPicture, 0, sizeof(tPicture)); +01485 if (bGet8PicInfo(iFodo, aucFpage + 1, +01486 iLen - 1, &tPicture)) { +01487 tPicture.ulFileOffset = ulFileOffset; +01488 tPicture.ulFileOffsetPicture = +01489 ulDataPos2FileOffset( +01490 tPicture.ulPictureOffset); +01491 vAdd2PictInfoList(&tPicture); +01492 } +01493 } +01494 } +01495 aulCharPage = xfree(aulCharPage); +01496 } /* end of vGet8ChrInfo */ +