diff -r 59758314f811 -r d4524d6a4472 Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/prop8_8c_source.html --- a/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/prop8_8c_source.html Fri Jun 11 15:24:34 2010 +0100 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,1512 +0,0 @@ - - -
- -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 */ -