diff -r f345bda72bc4 -r 43e37759235e Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/prop2_8c_source.html --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Symbian3/Examples/guid-6013a680-57f9-415b-8851-c4fa63356636/prop2_8c_source.html Tue Mar 30 16:16:55 2010 +0100 @@ -0,0 +1,1083 @@ + + +
+ +00001 /* +00002 * prop2.c +00003 * Copyright (C) 2002-2005 A.J. van Os; Released under GPL +00004 * +00005 * Description: +00006 * Read the property information from a WinWord 1 or 2 file +00007 */ +00008 +00009 #include <string.h> +00010 #include "antiword.h" +00011 +00012 +00013 #define MAX_FILESIZE 0x2000000UL /* 32 Mb */ +00014 +00015 /* +00016 * iGet2InfoLength - the length of the information for WinWord 1/2 files +00017 */ +00018 static int +00019 iGet2InfoLength(int iByteNbr, const UCHAR *aucGrpprl) +00020 { +00021 int iTmp, iDel, iAdd; +00022 +00023 switch (ucGetByte(iByteNbr, aucGrpprl)) { +00024 case 3: case 15: case 78: case 152: case 154: case 155: +00025 return 2 + (int)ucGetByte(iByteNbr + 1, aucGrpprl); +00026 case 16: case 17: case 18: case 19: case 21: case 22: case 26: +00027 case 27: case 28: case 30: case 31: case 32: case 33: case 34: +00028 case 35: case 36: case 38: case 39: case 40: case 41: case 42: +00029 case 43: case 45: case 46: case 47: case 48: case 49: case 68: +00030 case 71: case 72: case 82: case 83: case 96: case 97: case 98: +00031 case 99: case 115: case 116: case 119: case 120: case 123: case 124: +00032 case 129: case 130: case 131: case 132: case 135: case 136: case 139: +00033 case 140: case 141: case 142: case 143: case 144: case 145: case 146: +00034 case 147: case 148: case 153: case 159: case 161: case 162: +00035 return 1 + 2; +00036 case 23: +00037 iTmp = (int)ucGetByte(iByteNbr + 1, aucGrpprl); +00038 if (iTmp == 255) { +00039 iDel = (int)ucGetByte(iByteNbr + 2, aucGrpprl); +00040 iAdd = (int)ucGetByte( +00041 iByteNbr + 3 + iDel * 4, aucGrpprl); +00042 iTmp = 2 + iDel * 4 + iAdd * 3; +00043 } +00044 return 2 + iTmp; +00045 case 70: +00046 return 1 + 3; +00047 case 95: +00048 return 1 + 13; +00049 case 157: case 163: +00050 return 1 + 5; +00051 case 158: case 160: case 164: +00052 return 1 + 4; +00053 default: +00054 return 1 + 1; +00055 } +00056 } /* end of iGet2InfoLength */ +00057 +00058 /* +00059 * Build the lists with Document Property Information for WinWord 1/2 files +00060 */ +00061 void +00062 vGet2DopInfo(FILE *pFile, const UCHAR *aucHeader) +00063 { +00064 document_block_type tDocument; +00065 UCHAR *aucBuffer; +00066 ULONG ulBeginDocpInfo, ulTmp; +00067 size_t tDocpInfoLen; +00068 USHORT usTmp; +00069 +00070 ulBeginDocpInfo = ulGetLong(0x112, aucHeader); /* fcDop */ +00071 DBG_HEX(ulBeginDocpInfo); +00072 tDocpInfoLen = (size_t)usGetWord(0x116, aucHeader); /* cbDop */ +00073 DBG_DEC(tDocpInfoLen); +00074 if (tDocpInfoLen < 28) { +00075 DBG_MSG("No Document information"); +00076 return; +00077 } +00078 +00079 aucBuffer = xmalloc(tDocpInfoLen); +00080 if (!bReadBytes(aucBuffer, tDocpInfoLen, ulBeginDocpInfo, pFile)) { +00081 aucBuffer = xfree(aucBuffer); +00082 return; +00083 } +00084 +00085 usTmp = usGetWord(0x00, aucBuffer); +00086 tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */ +00087 tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */ +00088 ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */ +00089 tDocument.tCreateDate = tConvertDTTM(ulTmp); +00090 ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */ +00091 tDocument.tRevisedDate = tConvertDTTM(ulTmp); +00092 vCreateDocumentInfoList(&tDocument); +00093 +00094 aucBuffer = xfree(aucBuffer); +00095 } /* end of vGet2DopInfo */ +00096 +00097 /* +00098 * Fill the section information block with information +00099 * from a WinWord 1/2 file. +00100 */ +00101 static void +00102 vGet2SectionInfo(const UCHAR *aucGrpprl, size_t tBytes, +00103 section_block_type *pSection) +00104 { +00105 int iFodoOff, iInfoLen; +00106 USHORT usCcol; +00107 UCHAR ucTmp; +00108 +00109 fail(aucGrpprl == NULL || pSection == NULL); +00110 +00111 iFodoOff = 0; +00112 while (tBytes >= (size_t)iFodoOff + 1) { +00113 switch (ucGetByte(iFodoOff, aucGrpprl)) { +00114 case 117: /* bkc */ +00115 ucTmp = ucGetByte(iFodoOff + 1, aucGrpprl); +00116 DBG_DEC(ucTmp); +00117 pSection->bNewPage = ucTmp != 0 && ucTmp != 1; +00118 break; +00119 case 119: /* ccolM1 */ +00120 usCcol = 1 + usGetWord(iFodoOff + 1, aucGrpprl); +00121 DBG_DEC(usCcol); +00122 break; +00123 case 128: /* grpfIhdt */ +00124 pSection->ucHdrFtrSpecification = +00125 ucGetByte(iFodoOff + 1, aucGrpprl); +00126 break; +00127 default: +00128 break; +00129 } +00130 iInfoLen = iGet2InfoLength(iFodoOff, aucGrpprl); +00131 fail(iInfoLen <= 0); +00132 iFodoOff += iInfoLen; +00133 } +00134 } /* end of vGet2SectionInfo */ +00135 +00136 /* +00137 * Build the lists with Section Property Information for WinWord 1/2 files +00138 */ +00139 void +00140 vGet2SepInfo(FILE *pFile, const UCHAR *aucHeader) +00141 { +00142 section_block_type tSection; +00143 ULONG *aulSectPage, *aulCharPos; +00144 UCHAR *aucBuffer, *aucFpage; +00145 ULONG ulBeginOfText, ulTextOffset, ulBeginSectInfo; +00146 size_t tSectInfoLen, tIndex, tOffset, tLen, tBytes; +00147 UCHAR aucTmp[1]; +00148 +00149 fail(pFile == NULL || aucHeader == NULL); +00150 +00151 ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */ +00152 NO_DBG_HEX(ulBeginOfText); +00153 ulBeginSectInfo = ulGetLong(0x7c, aucHeader); /* fcPlcfsed */ +00154 DBG_HEX(ulBeginSectInfo); +00155 tSectInfoLen = (size_t)usGetWord(0x80, aucHeader); /* cbPlcfsed */ +00156 DBG_DEC(tSectInfoLen); +00157 if (tSectInfoLen < 4) { +00158 DBG_DEC(tSectInfoLen); +00159 return; +00160 } +00161 +00162 aucBuffer = xmalloc(tSectInfoLen); +00163 if (!bReadBytes(aucBuffer, tSectInfoLen, ulBeginSectInfo, pFile)) { +00164 aucBuffer = xfree(aucBuffer); +00165 return; +00166 } +00167 NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen); +00168 +00169 /* Read the Section Descriptors */ +00170 tLen = (tSectInfoLen - 4) / 10; +00171 /* Save the section offsets */ +00172 aulCharPos = xcalloc(tLen, sizeof(ULONG)); +00173 for (tIndex = 0, tOffset = 0; +00174 tIndex < tLen; +00175 tIndex++, tOffset += 4) { +00176 ulTextOffset = ulGetLong(tOffset, aucBuffer); +00177 NO_DBG_HEX(ulTextOffset); +00178 aulCharPos[tIndex] = ulBeginOfText + ulTextOffset; +00179 NO_DBG_HEX(aulCharPos[tIndex]); +00180 } +00181 /* Save the Sepx offsets */ +00182 aulSectPage = xcalloc(tLen, sizeof(ULONG)); +00183 for (tIndex = 0, tOffset = (tLen + 1) * 4; +00184 tIndex < tLen; +00185 tIndex++, tOffset += 6) { +00186 aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer); +00187 NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */ +00188 } +00189 aucBuffer = xfree(aucBuffer); +00190 +00191 /* Read the Section Properties */ +00192 for (tIndex = 0; tIndex < tLen; tIndex++) { +00193 if (aulSectPage[tIndex] == FC_INVALID) { +00194 vDefault2SectionInfoList(aulCharPos[tIndex]); +00195 continue; +00196 } +00197 /* Get the number of bytes to read */ +00198 if (!bReadBytes(aucTmp, 1, aulSectPage[tIndex], pFile)) { +00199 continue; +00200 } +00201 tBytes = 1 + (size_t)ucGetByte(0, aucTmp); +00202 NO_DBG_DEC(tBytes); +00203 /* Read the bytes */ +00204 aucFpage = xmalloc(tBytes); +00205 if (!bReadBytes(aucFpage, tBytes, aulSectPage[tIndex], pFile)) { +00206 aucFpage = xfree(aucFpage); +00207 continue; +00208 } +00209 NO_DBG_PRINT_BLOCK(aucFpage, tBytes); +00210 /* Process the bytes */ +00211 vGetDefaultSection(&tSection); +00212 vGet2SectionInfo(aucFpage + 1, tBytes - 1, &tSection); +00213 vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]); +00214 aucFpage = xfree(aucFpage); +00215 } +00216 aulCharPos = xfree(aulCharPos); +00217 aulSectPage = xfree(aulSectPage); +00218 } /* end of vGet2SepInfo */ +00219 +00220 /* +00221 * Build the list with Header/Footer Information for WinWord 1/2 files +00222 */ +00223 void +00224 vGet2HdrFtrInfo(FILE *pFile, const UCHAR *aucHeader) +00225 { +00226 ULONG *aulCharPos; +00227 UCHAR *aucBuffer; +00228 ULONG ulHdrFtrOffset, ulBeginHdrFtrInfo; +00229 size_t tHdrFtrInfoLen, tIndex, tOffset, tLen; +00230 +00231 fail(pFile == NULL || aucHeader == NULL); +00232 +00233 ulBeginHdrFtrInfo = ulGetLong(0x9a, aucHeader); /* fcPlcfhdd */ +00234 NO_DBG_HEX(ulBeginHdrFtrInfo); +00235 tHdrFtrInfoLen = (size_t)usGetWord(0x9e, aucHeader); /* cbPlcfhdd */ +00236 NO_DBG_DEC(tHdrFtrInfoLen); +00237 if (tHdrFtrInfoLen < 8) { +00238 DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen); +00239 return; +00240 } +00241 +00242 aucBuffer = xmalloc(tHdrFtrInfoLen); +00243 if (!bReadBytes(aucBuffer, tHdrFtrInfoLen, ulBeginHdrFtrInfo, pFile)) { +00244 aucBuffer = xfree(aucBuffer); +00245 return; +00246 } +00247 NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen); +00248 +00249 tLen = tHdrFtrInfoLen / 4 - 1; +00250 /* Save the header/footer offsets */ +00251 aulCharPos = xcalloc(tLen, sizeof(ULONG)); +00252 for (tIndex = 0, tOffset = 0; +00253 tIndex < tLen; +00254 tIndex++, tOffset += 4) { +00255 ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer); +00256 NO_DBG_HEX(ulHdrFtrOffset); +00257 aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset); +00258 NO_DBG_HEX(aulCharPos[tIndex]); +00259 } +00260 vCreat2HdrFtrInfoList(aulCharPos, tLen); +00261 aulCharPos = xfree(aulCharPos); +00262 aucBuffer = xfree(aucBuffer); +00263 } /* end of vGet2HdrFtrInfo */ +00264 +00265 /* +00266 * Translate the rowinfo to a member of the row_info enumeration +00267 */ +00268 row_info_enum +00269 eGet2RowInfo(int iFodo, +00270 const UCHAR *aucGrpprl, int iBytes, row_block_type *pRow) +00271 { +00272 int iFodoOff, iInfoLen; +00273 int iIndex, iSize, iCol; +00274 int iPosCurr, iPosPrev; +00275 USHORT usTmp; +00276 BOOL bFound24_0, bFound24_1, bFound25_0, bFound25_1, bFound154; +00277 +00278 fail(iFodo < 0 || aucGrpprl == NULL || pRow == NULL); +00279 +00280 iFodoOff = 0; +00281 bFound24_0 = FALSE; +00282 bFound24_1 = FALSE; +00283 bFound25_0 = FALSE; +00284 bFound25_1 = FALSE; +00285 bFound154 = FALSE; +00286 while (iBytes >= iFodoOff + 1) { +00287 iInfoLen = 0; +00288 switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) { +00289 case 24: /* fIntable */ +00290 if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) { +00291 bFound24_1 = TRUE; +00292 } else { +00293 bFound24_0 = TRUE; +00294 } +00295 break; +00296 case 25: /* fTtp */ +00297 if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) { +00298 bFound25_1 = TRUE; +00299 } else { +00300 bFound25_0 = TRUE; +00301 } +00302 break; +00303 case 30: /* brcTop10 */ +00304 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); +00305 usTmp &= 0x01ff; +00306 NO_DBG_DEC(usTmp >> 6); +00307 if (usTmp == 0) { +00308 pRow->ucBorderInfo &= ~TABLE_BORDER_TOP; +00309 } else { +00310 pRow->ucBorderInfo |= TABLE_BORDER_TOP; +00311 } +00312 break; +00313 case 31: /* brcLeft10 */ +00314 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); +00315 usTmp &= 0x01ff; +00316 NO_DBG_DEC(usTmp >> 6); +00317 if (usTmp == 0) { +00318 pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT; +00319 } else { +00320 pRow->ucBorderInfo |= TABLE_BORDER_LEFT; +00321 } +00322 break; +00323 case 32: /* brcBottom10 */ +00324 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); +00325 usTmp &= 0x01ff; +00326 NO_DBG_DEC(usTmp >> 6); +00327 if (usTmp == 0) { +00328 pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM; +00329 } else { +00330 pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM; +00331 } +00332 break; +00333 case 33: /* brcRight10 */ +00334 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); +00335 usTmp &= 0x01ff; +00336 NO_DBG_DEC(usTmp >> 6); +00337 if (usTmp == 0) { +00338 pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT; +00339 } else { +00340 pRow->ucBorderInfo |= TABLE_BORDER_RIGHT; +00341 } +00342 break; +00343 case 38: /* brcTop */ +00344 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); +00345 usTmp &= 0x0018; +00346 NO_DBG_DEC(usTmp >> 3); +00347 if (usTmp == 0) { +00348 pRow->ucBorderInfo &= ~TABLE_BORDER_TOP; +00349 } else { +00350 pRow->ucBorderInfo |= TABLE_BORDER_TOP; +00351 } +00352 break; +00353 case 39: /* brcLeft */ +00354 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); +00355 usTmp &= 0x0018; +00356 NO_DBG_DEC(usTmp >> 3); +00357 if (usTmp == 0) { +00358 pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT; +00359 } else { +00360 pRow->ucBorderInfo |= TABLE_BORDER_LEFT; +00361 } +00362 break; +00363 case 40: /* brcBottom */ +00364 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); +00365 usTmp &= 0x0018; +00366 NO_DBG_DEC(usTmp >> 3); +00367 if (usTmp == 0) { +00368 pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM; +00369 } else { +00370 pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM; +00371 } +00372 break; +00373 case 41: /* brcRight */ +00374 usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl); +00375 usTmp &= 0x0018; +00376 NO_DBG_DEC(usTmp >> 3); +00377 if (usTmp == 0) { +00378 pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT; +00379 } else { +00380 pRow->ucBorderInfo |= TABLE_BORDER_RIGHT; +00381 } +00382 break; +00383 case 152: /* cDefTable10 */ +00384 case 154: /* cDefTable */ +00385 iSize = (int)usGetWord(iFodo + iFodoOff + 1, aucGrpprl); +00386 if (iSize < 6 || iBytes < iFodoOff + 7) { +00387 DBG_DEC(iSize); +00388 DBG_DEC(iBytes); +00389 DBG_DEC(iFodoOff); +00390 iInfoLen = 1; +00391 break; +00392 } +00393 iCol = (int)ucGetByte(iFodo + iFodoOff + 3, aucGrpprl); +00394 if (iCol < 1 || +00395 iBytes < iFodoOff + 3 + (iCol + 1) * 2) { +00396 DBG_DEC(iCol); +00397 DBG_DEC(iBytes); +00398 DBG_DEC(iFodoOff); +00399 DBG_DEC(ucGetByte(iFodo + iFodoOff, aucGrpprl)); +00400 iInfoLen = 1; +00401 break; +00402 } +00403 if (iCol >= (int)elementsof(pRow->asColumnWidth)) { +00404 DBG_DEC(iCol); +00405 werr(1, "The number of columns is corrupt"); +00406 } +00407 pRow->ucNumberOfColumns = (UCHAR)iCol; +00408 iPosPrev = (int)(short)usGetWord( +00409 iFodo + iFodoOff + 4, +00410 aucGrpprl); +00411 for (iIndex = 0; iIndex < iCol; iIndex++) { +00412 iPosCurr = (int)(short)usGetWord( +00413 iFodo + iFodoOff + 6 + iIndex * 2, +00414 aucGrpprl); +00415 pRow->asColumnWidth[iIndex] = +00416 (short)(iPosCurr - iPosPrev); +00417 iPosPrev = iPosCurr; +00418 } +00419 bFound154 = TRUE; +00420 break; +00421 default: +00422 break; +00423 } +00424 if (iInfoLen <= 0) { +00425 iInfoLen = +00426 iGet2InfoLength(iFodo + iFodoOff, aucGrpprl); +00427 fail(iInfoLen <= 0); +00428 } +00429 iFodoOff += iInfoLen; +00430 } +00431 if (bFound24_1 && bFound25_1 && bFound154) { +00432 return found_end_of_row; +00433 } +00434 if (bFound24_0 && bFound25_0 && !bFound154) { +00435 return found_not_end_of_row; +00436 } +00437 if (bFound24_1) { +00438 return found_a_cell; +00439 } +00440 if (bFound24_0) { +00441 return found_not_a_cell; +00442 } +00443 return found_nothing; +00444 } /* end of eGet2RowInfo */ +00445 +00446 /* +00447 * Fill the style information block with information +00448 * from a WinWord 1/2 file. +00449 */ +00450 void +00451 vGet2StyleInfo(int iFodo, +00452 const UCHAR *aucGrpprl, int iBytes, style_block_type *pStyle) +00453 { +00454 int iFodoOff, iInfoLen; +00455 int iTmp, iDel, iAdd; +00456 short sTmp; +00457 UCHAR ucTmp; +00458 +00459 fail(iFodo < 0 || aucGrpprl == NULL || pStyle == NULL); +00460 +00461 NO_DBG_DEC(pStyle->usIstd); +00462 +00463 iFodoOff = 0; +00464 while (iBytes >= iFodoOff + 1) { +00465 iInfoLen = 0; +00466 switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) { +00467 case 2: /* istd */ +00468 sTmp = (short)ucGetByte( +00469 iFodo + iFodoOff + 1, aucGrpprl); +00470 NO_DBG_DEC(sTmp); +00471 break; +00472 case 5: /* jc */ +00473 pStyle->ucAlignment = ucGetByte( +00474 iFodo + iFodoOff + 1, aucGrpprl); +00475 break; +00476 case 12: /* nfcSeqNumb */ +00477 pStyle->ucNFC = ucGetByte( +00478 iFodo + iFodoOff + 1, aucGrpprl); +00479 break; +00480 case 13: /* nLvlAnm */ +00481 ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); +00482 pStyle->ucNumLevel = ucTmp; +00483 pStyle->bNumPause = +00484 eGetNumType(ucTmp) == level_type_pause; +00485 break; +00486 case 15: /* ChgTabsPapx */ +00487 case 23: /* ChgTabs */ +00488 iTmp = (int)ucGetByte(iFodo + iFodoOff + 1, aucGrpprl); +00489 if (iTmp < 2) { +00490 iInfoLen = 1; +00491 break; +00492 } +00493 NO_DBG_DEC(iTmp); +00494 iDel = (int)ucGetByte(iFodo + iFodoOff + 2, aucGrpprl); +00495 if (iTmp < 2 + 2 * iDel) { +00496 iInfoLen = 1; +00497 break; +00498 } +00499 NO_DBG_DEC(iDel); +00500 iAdd = (int)ucGetByte( +00501 iFodo + iFodoOff + 3 + 2 * iDel, aucGrpprl); +00502 if (iTmp < 2 + 2 * iDel + 2 * iAdd) { +00503 iInfoLen = 1; +00504 break; +00505 } +00506 NO_DBG_DEC(iAdd); +00507 break; +00508 case 16: /* dxaRight */ +00509 pStyle->sRightIndent = (short)usGetWord( +00510 iFodo + iFodoOff + 1, aucGrpprl); +00511 NO_DBG_DEC(pStyle->sRightIndent); +00512 break; +00513 case 17: /* dxaLeft */ +00514 pStyle->sLeftIndent = (short)usGetWord( +00515 iFodo + iFodoOff + 1, aucGrpprl); +00516 NO_DBG_DEC(pStyle->sLeftIndent); +00517 break; +00518 case 18: /* Nest dxaLeft */ +00519 sTmp = (short)usGetWord( +00520 iFodo + iFodoOff + 1, aucGrpprl); +00521 pStyle->sLeftIndent += sTmp; +00522 if (pStyle->sLeftIndent < 0) { +00523 pStyle->sLeftIndent = 0; +00524 } +00525 NO_DBG_DEC(sTmp); +00526 NO_DBG_DEC(pStyle->sLeftIndent); +00527 break; +00528 case 19: /* dxaLeft1 */ +00529 pStyle->sLeftIndent1 = (short)usGetWord( +00530 iFodo + iFodoOff + 1, aucGrpprl); +00531 NO_DBG_DEC(pStyle->sLeftIndent1); +00532 break; +00533 case 21: /* dyaBefore */ +00534 pStyle->usBeforeIndent = usGetWord( +00535 iFodo + iFodoOff + 1, aucGrpprl); +00536 NO_DBG_DEC(pStyle->usBeforeIndent); +00537 break; +00538 case 22: /* dyaAfter */ +00539 pStyle->usAfterIndent = usGetWord( +00540 iFodo + iFodoOff + 1, aucGrpprl); +00541 NO_DBG_DEC(pStyle->usAfterIndent); +00542 break; +00543 default: +00544 break; +00545 } +00546 if (iInfoLen <= 0) { +00547 iInfoLen = +00548 iGet2InfoLength(iFodo + iFodoOff, aucGrpprl); +00549 fail(iInfoLen <= 0); +00550 } +00551 iFodoOff += iInfoLen; +00552 } +00553 } /* end of vGet2StyleInfo */ +00554 +00555 /* +00556 * Build the lists with Paragraph Information for WinWord 1/2 files +00557 */ +00558 void +00559 vGet2PapInfo(FILE *pFile, const UCHAR *aucHeader) +00560 { +00561 row_block_type tRow; +00562 style_block_type tStyle; +00563 USHORT *ausParfPage; +00564 UCHAR *aucBuffer; +00565 ULONG ulCharPos, ulCharPosFirst, ulCharPosLast; +00566 ULONG ulBeginParfInfo; +00567 size_t tParfInfoLen, tParfPageNum, tOffset, tSize, tLenOld, tLen; +00568 int iIndex, iIndex2, iRun, iFodo, iLen; +00569 row_info_enum eRowInfo; +00570 USHORT usParfFirstPage, usCount, usIstd; +00571 UCHAR ucStc; +00572 UCHAR aucFpage[BIG_BLOCK_SIZE]; +00573 +00574 fail(pFile == NULL || aucHeader == NULL); +00575 +00576 ulBeginParfInfo = ulGetLong(0xa6, aucHeader); /* fcPlcfbtePapx */ +00577 NO_DBG_HEX(ulBeginParfInfo); +00578 tParfInfoLen = (size_t)usGetWord(0xaa, aucHeader); /* cbPlcfbtePapx */ +00579 NO_DBG_DEC(tParfInfoLen); +00580 if (tParfInfoLen < 4) { +00581 DBG_DEC(tParfInfoLen); +00582 return; +00583 } +00584 +00585 aucBuffer = xmalloc(tParfInfoLen); +00586 if (!bReadBytes(aucBuffer, tParfInfoLen, ulBeginParfInfo, pFile)) { +00587 aucBuffer = xfree(aucBuffer); +00588 return; +00589 } +00590 NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen); +00591 +00592 tLen = (tParfInfoLen - 4) / 6; +00593 ausParfPage = xcalloc(tLen, sizeof(USHORT)); +00594 for (iIndex = 0, tOffset = (tLen + 1) * 4; +00595 iIndex < (int)tLen; +00596 iIndex++, tOffset += 2) { +00597 ausParfPage[iIndex] = usGetWord(tOffset, aucBuffer); +00598 NO_DBG_DEC(ausParfPage[iIndex]); +00599 } +00600 DBG_HEX(ulGetLong(0, aucBuffer)); +00601 aucBuffer = xfree(aucBuffer); +00602 tParfPageNum = (size_t)usGetWord(0x144, aucHeader); /* cpnBtePap */ +00603 DBG_DEC(tParfPageNum); +00604 if (tLen < tParfPageNum) { +00605 /* Replace ParfPage by a longer version */ +00606 tLenOld = tLen; +00607 usParfFirstPage = usGetWord(0x140, aucHeader); /* pnPapFirst */ +00608 DBG_DEC(usParfFirstPage); +00609 tLen += tParfPageNum - 1; +00610 tSize = tLen * sizeof(USHORT); +00611 ausParfPage = xrealloc(ausParfPage, tSize); +00612 /* Add new values */ +00613 usCount = usParfFirstPage + 1; +00614 for (iIndex = (int)tLenOld; iIndex < (int)tLen; iIndex++) { +00615 ausParfPage[iIndex] = usCount; +00616 NO_DBG_DEC(ausParfPage[iIndex]); +00617 usCount++; +00618 } +00619 } +00620 +00621 (void)memset(&tRow, 0, sizeof(tRow)); +00622 ulCharPosFirst = CP_INVALID; +00623 for (iIndex = 0; iIndex < (int)tLen; iIndex++) { +00624 if (!bReadBytes(aucFpage, BIG_BLOCK_SIZE, +00625 (ULONG)ausParfPage[iIndex] * BIG_BLOCK_SIZE, +00626 pFile)) { +00627 break; +00628 } +00629 NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); +00630 iRun = (int)ucGetByte(0x1ff, aucFpage); +00631 NO_DBG_DEC(iRun); +00632 for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { +00633 if ((iRun + 1) * 4 + iIndex2 * 1 >= BIG_BLOCK_SIZE) { +00634 break; +00635 } +00636 NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage)); +00637 iFodo = 2 * (int)ucGetByte( +00638 (iRun + 1) * 4 + iIndex2 * 1, aucFpage); +00639 if (iFodo <= 0) { +00640 continue; +00641 } +00642 +00643 iLen = 2 * (int)ucGetByte(iFodo, aucFpage); +00644 +00645 ucStc = ucGetByte(iFodo + 1, aucFpage); +00646 usIstd = usStc2istd(ucStc); +00647 +00648 vFillStyleFromStylesheet(usIstd, &tStyle); +00649 vGet2StyleInfo(iFodo, aucFpage + 8, iLen - 8, &tStyle); +00650 ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); +00651 NO_DBG_HEX(ulCharPos); +00652 tStyle.ulFileOffset = ulCharPos; +00653 vAdd2StyleInfoList(&tStyle); +00654 +00655 eRowInfo = eGet2RowInfo(iFodo, +00656 aucFpage + 8, iLen - 8, &tRow); +00657 +00658 switch(eRowInfo) { +00659 case found_a_cell: +00660 if (ulCharPosFirst != CP_INVALID) { +00661 break; +00662 } +00663 ulCharPosFirst = ulGetLong( +00664 iIndex2 * 4, aucFpage); +00665 NO_DBG_HEX(ulCharPosFirst); +00666 tRow.ulCharPosStart = ulCharPosFirst; +00667 tRow.ulFileOffsetStart = ulCharPosFirst; +00668 break; +00669 case found_end_of_row: +00670 ulCharPosLast = ulGetLong( +00671 iIndex2 * 4, aucFpage); +00672 NO_DBG_HEX(ulCharPosLast); +00673 tRow.ulCharPosEnd = ulCharPosLast; +00674 /* Add 1 for compatiblity with Word 6 and up */ +00675 tRow.ulFileOffsetEnd = ulCharPosLast + 1; +00676 vAdd2RowInfoList(&tRow); +00677 (void)memset(&tRow, 0, sizeof(tRow)); +00678 ulCharPosFirst = CP_INVALID; +00679 break; +00680 case found_nothing: +00681 break; +00682 default: +00683 DBG_DEC(eRowInfo); +00684 break; +00685 } +00686 } +00687 } +00688 ausParfPage = xfree(ausParfPage); +00689 } /* end of vGet2PapInfo */ +00690 +00691 /* +00692 * Fill the font information block with information +00693 * from a WinWord 1 file. +00694 */ +00695 void +00696 vGet1FontInfo(int iFodo, +00697 const UCHAR *aucGrpprl, size_t tBytes, font_block_type *pFont) +00698 { +00699 BOOL bIcoChange, bFtcChange, bHpsChange, bKulChange; +00700 USHORT usTmp; +00701 UCHAR ucTmp; +00702 UCHAR aucChpx[12]; +00703 +00704 fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL); +00705 +00706 if (tBytes > sizeof(aucChpx)) { +00707 NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes); +00708 return; +00709 } +00710 +00711 /* Build the CHPX structure */ +00712 (void)memset(aucChpx, 0, sizeof(aucChpx)); +00713 (void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx))); +00714 +00715 usTmp = usGetWord(0, aucChpx); +00716 if ((usTmp & BIT(0)) != 0) { +00717 pFont->usFontStyle ^= FONT_BOLD; +00718 } +00719 if ((usTmp & BIT(1)) != 0) { +00720 pFont->usFontStyle ^= FONT_ITALIC; +00721 } +00722 if ((usTmp & BIT(2)) != 0) { +00723 pFont->usFontStyle ^= FONT_STRIKE; +00724 } +00725 if ((usTmp & BIT(5)) != 0) { +00726 pFont->usFontStyle ^= FONT_SMALL_CAPITALS; +00727 } +00728 if ((usTmp & BIT(6)) != 0) { +00729 pFont->usFontStyle ^= FONT_CAPITALS; +00730 } +00731 if ((usTmp & BIT(7)) != 0) { +00732 pFont->usFontStyle ^= FONT_HIDDEN; +00733 } +00734 +00735 ucTmp = ucGetByte(5, aucChpx); +00736 if (ucTmp != 0) { +00737 if (ucTmp < 128) { +00738 pFont->usFontStyle |= FONT_SUPERSCRIPT; +00739 DBG_MSG("Superscript"); +00740 } else { +00741 pFont->usFontStyle |= FONT_SUBSCRIPT; +00742 DBG_MSG("Subscript"); +00743 } +00744 } +00745 +00746 bIcoChange = (usTmp & BIT(10)) != 0; +00747 bFtcChange = (usTmp & BIT(11)) != 0; +00748 bHpsChange = (usTmp & BIT(12)) != 0; +00749 bKulChange = (usTmp & BIT(13)) != 0; +00750 +00751 if (bFtcChange) { +00752 usTmp = usGetWord(2, aucChpx); +00753 if (usTmp <= (USHORT)UCHAR_MAX) { +00754 pFont->ucFontNumber = (UCHAR)usTmp; +00755 } else { +00756 pFont->ucFontNumber = 0; +00757 } +00758 } +00759 +00760 if (bHpsChange) { +00761 pFont->usFontSize = (USHORT)ucGetByte(4, aucChpx); +00762 } +00763 +00764 if (bIcoChange || bKulChange) { +00765 usTmp = usGetWord(6, aucChpx); +00766 if (bIcoChange) { +00767 pFont->ucFontColor = (UCHAR)((usTmp & 0x0f00) >> 8); +00768 if (pFont->ucFontColor <= 7) { +00769 /* Add 1 for compatibility with Word 2 and up */ +00770 pFont->ucFontColor++; +00771 } else { +00772 DBG_DEC(pFont->ucFontColor); +00773 pFont->ucFontColor = 0; +00774 } +00775 } +00776 if (bKulChange) { +00777 usTmp = (usTmp & 0x7000) >> 12; +00778 DBG_DEC_C(usTmp > 4, usTmp); +00779 if (usTmp == 0) { +00780 pFont->usFontStyle &= ~FONT_UNDERLINE; +00781 } else { +00782 pFont->usFontStyle |= FONT_UNDERLINE; +00783 } +00784 } +00785 } +00786 } /* end of vGet1FontInfo */ +00787 +00788 /* +00789 * Fill the font information block with information +00790 * from a WinWord 1/2 file. +00791 */ +00792 void +00793 vGet2FontInfo(int iFodo, +00794 const UCHAR *aucGrpprl, size_t tBytes, font_block_type *pFont) +00795 { +00796 BOOL bIcoChange, bFtcChange, bHpsChange, bKulChange; +00797 USHORT usTmp; +00798 UCHAR ucTmp; +00799 UCHAR aucChpx[18]; +00800 +00801 fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL); +00802 +00803 if (tBytes > sizeof(aucChpx)) { +00804 NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes); +00805 return; +00806 } +00807 +00808 /* Build the CHPX structure */ +00809 (void)memset(aucChpx, 0, sizeof(aucChpx)); +00810 (void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx))); +00811 +00812 usTmp = usGetWord(0, aucChpx); +00813 if ((usTmp & BIT(0)) != 0) { +00814 pFont->usFontStyle ^= FONT_BOLD; +00815 } +00816 if ((usTmp & BIT(1)) != 0) { +00817 pFont->usFontStyle ^= FONT_ITALIC; +00818 } +00819 if (usTmp & BIT(3)) { +00820 pFont->usFontStyle ^= FONT_MARKDEL; +00821 } +00822 if ((usTmp & BIT(5)) != 0) { +00823 pFont->usFontStyle ^= FONT_SMALL_CAPITALS; +00824 } +00825 if ((usTmp & BIT(6)) != 0) { +00826 pFont->usFontStyle ^= FONT_CAPITALS; +00827 } +00828 if ((usTmp & BIT(7)) != 0) { +00829 pFont->usFontStyle ^= FONT_HIDDEN; +00830 } +00831 if (usTmp & BIT(10)) { +00832 pFont->usFontStyle ^= FONT_STRIKE; +00833 } +00834 +00835 ucTmp = ucGetByte(10, aucChpx); +00836 DBG_MSG_C(ucTmp != 0 && ucTmp < 128, "Superscript"); +00837 DBG_MSG_C(ucTmp >= 128, "Subscript"); +00838 +00839 usTmp = usGetWord(2, aucChpx); +00840 if (usTmp == 0) { +00841 /* No changes, nothing to do */ +00842 return; +00843 } +00844 +00845 bIcoChange = (usTmp & BIT(0)) != 0; +00846 bFtcChange = (usTmp & BIT(1)) != 0; +00847 bHpsChange = (usTmp & BIT(2)) != 0; +00848 bKulChange = (usTmp & BIT(3)) != 0; +00849 +00850 if (bFtcChange) { +00851 usTmp = usGetWord(4, aucChpx); +00852 if (usTmp <= (USHORT)UCHAR_MAX) { +00853 pFont->ucFontNumber = (UCHAR)usTmp; +00854 } else { +00855 pFont->ucFontNumber = 0; +00856 } +00857 } +00858 +00859 if (bHpsChange) { +00860 pFont->usFontSize = usGetWord(6, aucChpx); +00861 } +00862 +00863 if (bIcoChange || bKulChange) { +00864 ucTmp = ucGetByte(9, aucChpx); +00865 if (bIcoChange) { +00866 pFont->ucFontColor = ucTmp & 0x1f; +00867 if (pFont->ucFontColor > 16) { +00868 DBG_DEC(pFont->ucFontColor); +00869 pFont->ucFontColor = 0; +00870 } +00871 } +00872 if (bKulChange) { +00873 ucTmp = (ucTmp & 0xe0) >> 5; +00874 DBG_DEC_C(ucTmp > 4, ucTmp); +00875 if (ucTmp == 0) { +00876 pFont->usFontStyle &= ~FONT_UNDERLINE; +00877 } else { +00878 pFont->usFontStyle |= FONT_UNDERLINE; +00879 } +00880 } +00881 } +00882 } /* end of vGet2FontInfo */ +00883 +00884 /* +00885 * Fill the picture information block with information from a WinWord 1 file. +00886 * Returns TRUE when successful, otherwise FALSE +00887 */ +00888 static BOOL +00889 bGet1PicInfo(int iFodo, +00890 const UCHAR *aucGrpprl, size_t tBytes, picture_block_type *pPicture) +00891 { +00892 ULONG ulTmp; +00893 UCHAR aucChpx[12]; +00894 +00895 fail(iFodo < 0 || aucGrpprl == NULL || pPicture == NULL); +00896 +00897 if (tBytes > sizeof(aucChpx)) { +00898 NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes); +00899 tBytes = sizeof(aucChpx); +00900 } +00901 +00902 /* Build the CHPX structure */ +00903 (void)memset(aucChpx, 0, sizeof(aucChpx)); +00904 (void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx))); +00905 +00906 ulTmp = ulGetLong(8, aucChpx); +00907 if (ulTmp != 0 && ulTmp < MAX_FILESIZE) { +00908 pPicture->ulPictureOffset = ulTmp; +00909 DBG_HEX(pPicture->ulPictureOffset); +00910 return TRUE; +00911 } +00912 return FALSE; +00913 } /* end of bGet1PicInfo */ +00914 +00915 /* +00916 * Fill the picture information block with information from a WinWord 2 file. +00917 * Returns TRUE when successful, otherwise FALSE +00918 */ +00919 static BOOL +00920 bGet2PicInfo(int iFodo, +00921 const UCHAR *aucGrpprl, size_t tBytes, picture_block_type *pPicture) +00922 { +00923 ULONG ulTmp; +00924 UCHAR aucChpx[18]; +00925 +00926 fail(iFodo < 0 || aucGrpprl == NULL || pPicture == NULL); +00927 +00928 if (tBytes > sizeof(aucChpx)) { +00929 NO_DBG_PRINT_BLOCK(aucGrpprl + iFodo, tBytes); +00930 tBytes = sizeof(aucChpx); +00931 } +00932 +00933 /* Build the CHPX structure */ +00934 (void)memset(aucChpx, 0, sizeof(aucChpx)); +00935 (void)memcpy(aucChpx, aucGrpprl + iFodo, min(tBytes, sizeof(aucChpx))); +00936 +00937 ulTmp = ulGetLong(14, aucChpx); +00938 if (ulTmp != 0 && ulTmp < MAX_FILESIZE) { +00939 pPicture->ulPictureOffset = ulTmp; +00940 DBG_HEX(pPicture->ulPictureOffset); +00941 DBG_DEC(tBytes); +00942 return TRUE; +00943 } +00944 return FALSE; +00945 } /* end of bGet2PicInfo */ +00946 +00947 /* +00948 * Build the lists with Character Information for WinWord 1/2 files +00949 */ +00950 void +00951 vGet2ChrInfo(FILE *pFile, int iWordVersion, const UCHAR *aucHeader) +00952 { +00953 font_block_type tFont; +00954 picture_block_type tPicture; +00955 USHORT *ausCharPage; +00956 UCHAR *aucBuffer; +00957 ULONG ulFileOffset, ulCharPos, ulBeginCharInfo; +00958 size_t tCharInfoLen, tOffset, tSize, tChrLen, tCharPageNum; +00959 size_t tLenOld, tLen; +00960 int iIndex, iIndex2, iRun, iFodo; +00961 BOOL bSuccess1, bSuccess2; +00962 USHORT usCharFirstPage, usCount, usIstd; +00963 UCHAR aucFpage[BIG_BLOCK_SIZE]; +00964 +00965 fail(pFile == NULL || aucHeader == NULL); +00966 fail(iWordVersion != 1 && iWordVersion != 2); +00967 +00968 ulBeginCharInfo = ulGetLong(0xa0, aucHeader); /* fcPlcfbteChpx */ +00969 DBG_HEX(ulBeginCharInfo); +00970 tCharInfoLen = (size_t)usGetWord(0xa4, aucHeader); /* cbPlcfbteChpx */ +00971 DBG_DEC(tCharInfoLen); +00972 if (tCharInfoLen < 4) { +00973 DBG_DEC(tCharInfoLen); +00974 return; +00975 } +00976 +00977 aucBuffer = xmalloc(tCharInfoLen); +00978 if (!bReadBytes(aucBuffer, tCharInfoLen, ulBeginCharInfo, pFile)) { +00979 aucBuffer = xfree(aucBuffer); +00980 return; +00981 } +00982 NO_DBG_PRINT_BLOCK(aucBuffer, tCharInfoLen); +00983 +00984 tLen = (tCharInfoLen - 4) / 6; +00985 ausCharPage = xcalloc(tLen, sizeof(USHORT)); +00986 for (iIndex = 0, tOffset = (tLen + 1) * 4; +00987 iIndex < (int)tLen; +00988 iIndex++, tOffset += 2) { +00989 ausCharPage[iIndex] = usGetWord(tOffset, aucBuffer); +00990 NO_DBG_DEC(ausCharPage[iIndex]); +00991 } +00992 DBG_HEX(ulGetLong(0, aucBuffer)); +00993 aucBuffer = xfree(aucBuffer); +00994 tCharPageNum = (size_t)usGetWord(0x142, aucHeader); /* cpnBteChp */ +00995 DBG_DEC(tCharPageNum); +00996 if (tLen < tCharPageNum) { +00997 /* Replace CharPage by a longer version */ +00998 tLenOld = tLen; +00999 usCharFirstPage = usGetWord(0x13e, aucHeader); /* pnChrFirst */ +01000 NO_DBG_DEC(usCharFirstPage); +01001 tLen += tCharPageNum - 1; +01002 tSize = tLen * sizeof(USHORT); +01003 ausCharPage = xrealloc(ausCharPage, tSize); +01004 /* Add new values */ +01005 usCount = usCharFirstPage + 1; +01006 for (iIndex = (int)tLenOld; iIndex < (int)tLen; iIndex++) { +01007 ausCharPage[iIndex] = usCount; +01008 NO_DBG_DEC(ausCharPage[iIndex]); +01009 usCount++; +01010 } +01011 } +01012 +01013 for (iIndex = 0; iIndex < (int)tLen; iIndex++) { +01014 if (!bReadBytes(aucFpage, BIG_BLOCK_SIZE, +01015 (ULONG)ausCharPage[iIndex] * BIG_BLOCK_SIZE, +01016 pFile)) { +01017 break; +01018 } +01019 NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE); +01020 iRun = (int)ucGetByte(0x1ff, aucFpage); +01021 NO_DBG_DEC(iRun); +01022 for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) { +01023 if ((iRun + 1) * 4 + iIndex2 >= BIG_BLOCK_SIZE) { +01024 break; +01025 } +01026 ulCharPos = ulGetLong(iIndex2 * 4, aucFpage); +01027 ulFileOffset = ulCharPos; +01028 iFodo = 2 * (int)ucGetByte( +01029 (iRun + 1) * 4 + iIndex2, aucFpage); +01030 +01031 tChrLen = (size_t)ucGetByte(iFodo, aucFpage); +01032 +01033 usIstd = usGetIstd(ulFileOffset); +01034 vFillFontFromStylesheet(usIstd, &tFont); +01035 if (iFodo != 0) { +01036 if (iWordVersion == 1) { +01037 vGet1FontInfo(iFodo, +01038 aucFpage + 1, tChrLen, &tFont); +01039 } else if (iWordVersion == 2) { +01040 vGet2FontInfo(iFodo, +01041 aucFpage + 1, tChrLen, &tFont); +01042 } +01043 } +01044 tFont.ulFileOffset = ulFileOffset; +01045 vAdd2FontInfoList(&tFont); +01046 +01047 if (iFodo <= 0) { +01048 continue; +01049 } +01050 +01051 (void)memset(&tPicture, 0, sizeof(tPicture)); +01052 bSuccess1 = iWordVersion == 1 && +01053 bGet1PicInfo(iFodo, aucFpage + 1, +01054 tChrLen, &tPicture); +01055 bSuccess2 = iWordVersion == 2 && +01056 bGet2PicInfo(iFodo, aucFpage + 1, +01057 tChrLen, &tPicture); +01058 if (bSuccess1 || bSuccess2) { +01059 tPicture.ulFileOffset = ulFileOffset; +01060 tPicture.ulFileOffsetPicture = +01061 tPicture.ulPictureOffset; +01062 vAdd2PictInfoList(&tPicture); +01063 } +01064 } +01065 } +01066 ausCharPage = xfree(ausCharPage); +01067 } /* end of vGet2ChrInfo */ +