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