prop6.c 30 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141
  1. /*
  2. * prop6.c
  3. * Copyright (C) 1998-2005 A.J. van Os; Released under GPL
  4. *
  5. * Description:
  6. * Read the property information from a MS Word 6 or 7 file
  7. */
  8. #include <stdlib.h>
  9. #include <string.h>
  10. #include "antiword.h"
  11. /*
  12. * iGet6InfoLength - the length of the information for Word 6/7 files
  13. */
  14. static int
  15. iGet6InfoLength(int iByteNbr, const UCHAR *aucGrpprl)
  16. {
  17. int iTmp, iDel, iAdd;
  18. switch (ucGetByte(iByteNbr, aucGrpprl)) {
  19. case 2: case 16: case 17: case 18: case 19: case 21: case 22:
  20. case 26: case 27: case 28: case 30: case 31: case 32: case 33:
  21. case 34: case 35: case 36: case 38: case 39: case 40: case 41:
  22. case 42: case 43: case 45: case 46: case 47: case 48: case 49:
  23. case 69: case 72: case 80: case 93: case 96: case 97: case 99:
  24. case 101: case 105: case 106: case 107: case 109: case 110: case 121:
  25. case 122: case 123: case 124: case 140: case 141: case 144: case 145:
  26. case 148: case 149: case 154: case 155: case 156: case 157: case 160:
  27. case 161: case 164: case 165: case 166: case 167: case 168: case 169:
  28. case 170: case 171: case 182: case 183: case 184: case 189: case 195:
  29. case 197: case 198:
  30. return 1 + 2;
  31. case 3: case 12: case 15: case 81: case 103: case 108: case 188:
  32. case 190: case 191:
  33. return 2 + (int)ucGetByte(iByteNbr + 1, aucGrpprl);
  34. case 20: case 70: case 74: case 192: case 194: case 196: case 200:
  35. return 1 + 4;
  36. case 23:
  37. iTmp = (int)ucGetByte(iByteNbr + 1, aucGrpprl);
  38. if (iTmp == 255) {
  39. iDel = (int)ucGetByte(iByteNbr + 2, aucGrpprl);
  40. iAdd = (int)ucGetByte(
  41. iByteNbr + 3 + iDel * 4, aucGrpprl);
  42. iTmp = 2 + iDel * 4 + iAdd * 3;
  43. }
  44. return 2 + iTmp;
  45. case 68: case 193: case 199:
  46. return 1 + 5;
  47. case 73: case 95: case 136: case 137:
  48. return 1 + 3;
  49. case 120: case 187:
  50. return 1 + 12;
  51. default:
  52. return 1 + 1;
  53. }
  54. } /* end of iGet6InfoLength */
  55. /*
  56. * Build the lists with Document Property Information for Word 6/7 files
  57. */
  58. void
  59. vGet6DopInfo(FILE *pFile, ULONG ulStartBlock,
  60. const ULONG *aulBBD, size_t tBBDLen,
  61. const UCHAR *aucHeader)
  62. {
  63. document_block_type tDocument;
  64. UCHAR *aucBuffer;
  65. ULONG ulBeginDocpInfo, ulTmp;
  66. size_t tDocpInfoLen;
  67. USHORT usTmp;
  68. ulBeginDocpInfo = ulGetLong(0x150, aucHeader); /* fcDop */
  69. DBG_HEX(ulBeginDocpInfo);
  70. tDocpInfoLen = (size_t)ulGetLong(0x154, aucHeader); /* lcbDop */
  71. DBG_DEC(tDocpInfoLen);
  72. if (tDocpInfoLen < 28) {
  73. DBG_MSG("No Document information");
  74. return;
  75. }
  76. aucBuffer = xmalloc(tDocpInfoLen);
  77. if (!bReadBuffer(pFile, ulStartBlock,
  78. aulBBD, tBBDLen, BIG_BLOCK_SIZE,
  79. aucBuffer, ulBeginDocpInfo, tDocpInfoLen)) {
  80. aucBuffer = xfree(aucBuffer);
  81. return;
  82. }
  83. usTmp = usGetWord(0x00, aucBuffer);
  84. tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */
  85. tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */
  86. ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */
  87. tDocument.tCreateDate = tConvertDTTM(ulTmp);
  88. ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */
  89. tDocument.tRevisedDate = tConvertDTTM(ulTmp);
  90. vCreateDocumentInfoList(&tDocument);
  91. aucBuffer = xfree(aucBuffer);
  92. } /* end of vGet6DopInfo */
  93. /*
  94. * Fill the section information block with information
  95. * from a Word 6/7 file.
  96. */
  97. static void
  98. vGet6SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,
  99. section_block_type *pSection)
  100. {
  101. UINT uiIndex;
  102. int iFodoOff, iInfoLen, iSize, iTmp;
  103. USHORT usCcol;
  104. UCHAR ucTmp;
  105. fail(aucGrpprl == NULL || pSection == NULL);
  106. iFodoOff = 0;
  107. while (tBytes >= (size_t)iFodoOff + 1) {
  108. iInfoLen = 0;
  109. switch (ucGetByte(iFodoOff, aucGrpprl)) {
  110. case 133: /* olstAnm */
  111. iSize = (int)ucGetByte(iFodoOff + 1, aucGrpprl);
  112. DBG_DEC_C(iSize != 212, iSize);
  113. for (uiIndex = 0, iTmp = iFodoOff + 2;
  114. uiIndex < 9 && iTmp < iFodoOff + 2 + iSize - 15;
  115. uiIndex++, iTmp += 16) {
  116. pSection->aucNFC[uiIndex] =
  117. ucGetByte(iTmp, aucGrpprl);
  118. NO_DBG_DEC(pSection->aucNFC[uiIndex]);
  119. ucTmp = ucGetByte(iTmp + 3, aucGrpprl);
  120. NO_DBG_HEX(ucTmp);
  121. if ((ucTmp & BIT(2)) != 0) {
  122. pSection->usNeedPrevLvl |=
  123. (USHORT)BIT(uiIndex);
  124. }
  125. if ((ucTmp & BIT(3)) != 0) {
  126. pSection->usHangingIndent |=
  127. (USHORT)BIT(uiIndex);
  128. }
  129. }
  130. DBG_HEX(pSection->usNeedPrevLvl);
  131. DBG_HEX(pSection->usHangingIndent);
  132. break;
  133. case 142: /* bkc */
  134. ucTmp = ucGetByte(iFodoOff + 1, aucGrpprl);
  135. DBG_DEC(ucTmp);
  136. pSection->bNewPage = ucTmp != 0 && ucTmp != 1;
  137. break;
  138. case 144: /* ccolM1 */
  139. usCcol = 1 + usGetWord(iFodoOff + 1, aucGrpprl);
  140. DBG_DEC(usCcol);
  141. break;
  142. case 153: /* grpfIhdt */
  143. pSection->ucHdrFtrSpecification =
  144. ucGetByte(iFodoOff + 1, aucGrpprl);
  145. break;
  146. default:
  147. break;
  148. }
  149. if (iInfoLen <= 0) {
  150. iInfoLen = iGet6InfoLength(iFodoOff, aucGrpprl);
  151. fail(iInfoLen <= 0);
  152. }
  153. iFodoOff += iInfoLen;
  154. }
  155. } /* end of vGet6SectionInfo */
  156. /*
  157. * Build the lists with Section Property Information for Word 6/7 files
  158. */
  159. void
  160. vGet6SepInfo(FILE *pFile, ULONG ulStartBlock,
  161. const ULONG *aulBBD, size_t tBBDLen,
  162. const UCHAR *aucHeader)
  163. {
  164. section_block_type tSection;
  165. ULONG *aulSectPage, *aulCharPos;
  166. UCHAR *aucBuffer, *aucFpage;
  167. ULONG ulBeginOfText, ulTextOffset, ulBeginSectInfo;
  168. size_t tSectInfoLen, tIndex, tOffset, tLen, tBytes;
  169. UCHAR aucTmp[2];
  170. fail(pFile == NULL || aucHeader == NULL);
  171. fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
  172. fail(aulBBD == NULL);
  173. ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
  174. NO_DBG_HEX(ulBeginOfText);
  175. ulBeginSectInfo = ulGetLong(0x88, aucHeader); /* fcPlcfsed */
  176. DBG_HEX(ulBeginSectInfo);
  177. tSectInfoLen = (size_t)ulGetLong(0x8c, aucHeader); /* lcbPlcfsed */
  178. DBG_DEC(tSectInfoLen);
  179. if (tSectInfoLen < 4) {
  180. DBG_DEC(tSectInfoLen);
  181. return;
  182. }
  183. aucBuffer = xmalloc(tSectInfoLen);
  184. if (!bReadBuffer(pFile, ulStartBlock,
  185. aulBBD, tBBDLen, BIG_BLOCK_SIZE,
  186. aucBuffer, ulBeginSectInfo, tSectInfoLen)) {
  187. aucBuffer = xfree(aucBuffer);
  188. return;
  189. }
  190. NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen);
  191. /* Read the Section Descriptors */
  192. tLen = (tSectInfoLen - 4) / 16;
  193. /* Save the section offsets */
  194. aulCharPos = xcalloc(tLen, sizeof(ULONG));
  195. for (tIndex = 0, tOffset = 0; tIndex < tLen; tIndex++, tOffset += 4) {
  196. ulTextOffset = ulGetLong(tOffset, aucBuffer);
  197. NO_DBG_HEX(ulTextOffset);
  198. aulCharPos[tIndex] = ulBeginOfText + ulTextOffset;
  199. NO_DBG_HEX(aulCharPos[tIndex]);
  200. }
  201. /* Save the Sepx offsets */
  202. aulSectPage = xcalloc(tLen, sizeof(ULONG));
  203. for (tIndex = 0, tOffset = (tLen + 1) * 4;
  204. tIndex < tLen;
  205. tIndex++, tOffset += 12) {
  206. aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer);
  207. NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */
  208. }
  209. aucBuffer = xfree(aucBuffer);
  210. /* Read the Section Properties */
  211. for (tIndex = 0; tIndex < tLen; tIndex++) {
  212. if (aulSectPage[tIndex] == FC_INVALID) {
  213. vDefault2SectionInfoList(aulCharPos[tIndex]);
  214. continue;
  215. }
  216. /* Get the number of bytes to read */
  217. if (!bReadBuffer(pFile, ulStartBlock,
  218. aulBBD, tBBDLen, BIG_BLOCK_SIZE,
  219. aucTmp, aulSectPage[tIndex], 2)) {
  220. continue;
  221. }
  222. tBytes = 2 + (size_t)usGetWord(0, aucTmp);
  223. NO_DBG_DEC(tBytes);
  224. /* Read the bytes */
  225. aucFpage = xmalloc(tBytes);
  226. if (!bReadBuffer(pFile, ulStartBlock,
  227. aulBBD, tBBDLen, BIG_BLOCK_SIZE,
  228. aucFpage, aulSectPage[tIndex], tBytes)) {
  229. aucFpage = xfree(aucFpage);
  230. continue;
  231. }
  232. NO_DBG_PRINT_BLOCK(aucFpage, tBytes);
  233. /* Process the bytes */
  234. vGetDefaultSection(&tSection);
  235. vGet6SectionInfo(aucFpage + 2, tBytes - 2, &tSection);
  236. vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]);
  237. aucFpage = xfree(aucFpage);
  238. }
  239. aulCharPos = xfree(aulCharPos);
  240. aulSectPage = xfree(aulSectPage);
  241. } /* end of vGet6SepInfo */
  242. /*
  243. * Build the list with Header/Footer Information for Word 6/7 files
  244. */
  245. void
  246. vGet6HdrFtrInfo(FILE *pFile, ULONG ulStartBlock,
  247. const ULONG *aulBBD, size_t tBBDLen,
  248. const UCHAR *aucHeader)
  249. {
  250. ULONG *aulCharPos;
  251. UCHAR *aucBuffer;
  252. ULONG ulHdrFtrOffset, ulBeginHdrFtrInfo;
  253. size_t tHdrFtrInfoLen, tIndex, tOffset, tLen;
  254. fail(pFile == NULL || aucHeader == NULL);
  255. fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
  256. fail(aulBBD == NULL);
  257. ulBeginHdrFtrInfo = ulGetLong(0xb0, aucHeader); /* fcPlcfhdd */
  258. NO_DBG_HEX(ulBeginHdrFtrInfo);
  259. tHdrFtrInfoLen = (size_t)ulGetLong(0xb4, aucHeader); /* lcbPlcfhdd */
  260. NO_DBG_DEC(tHdrFtrInfoLen);
  261. if (tHdrFtrInfoLen < 8) {
  262. DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen);
  263. return;
  264. }
  265. aucBuffer = xmalloc(tHdrFtrInfoLen);
  266. if (!bReadBuffer(pFile, ulStartBlock,
  267. aulBBD, tBBDLen, BIG_BLOCK_SIZE,
  268. aucBuffer, ulBeginHdrFtrInfo, tHdrFtrInfoLen)) {
  269. aucBuffer = xfree(aucBuffer);
  270. return;
  271. }
  272. NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen);
  273. tLen = tHdrFtrInfoLen / 4 - 1;
  274. /* Save the header/footer offsets */
  275. aulCharPos = xcalloc(tLen, sizeof(ULONG));
  276. for (tIndex = 0, tOffset = 0;
  277. tIndex < tLen;
  278. tIndex++, tOffset += 4) {
  279. ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer);
  280. NO_DBG_HEX(ulHdrFtrOffset);
  281. aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset);
  282. NO_DBG_HEX(aulCharPos[tIndex]);
  283. }
  284. vCreat6HdrFtrInfoList(aulCharPos, tLen);
  285. aulCharPos = xfree(aulCharPos);
  286. aucBuffer = xfree(aucBuffer);
  287. } /* end of vGet6HdrFtrInfo */
  288. /*
  289. * Translate the rowinfo to a member of the row_info enumeration
  290. */
  291. row_info_enum
  292. eGet6RowInfo(int iFodo,
  293. const UCHAR *aucGrpprl, int iBytes, row_block_type *pRow)
  294. {
  295. int iFodoOff, iInfoLen;
  296. int iIndex, iSize, iCol;
  297. int iPosCurr, iPosPrev;
  298. USHORT usTmp;
  299. BOOL bFound24_0, bFound24_1, bFound25_0, bFound25_1, bFound190;
  300. fail(iFodo < 0 || aucGrpprl == NULL || pRow == NULL);
  301. iFodoOff = 0;
  302. bFound24_0 = FALSE;
  303. bFound24_1 = FALSE;
  304. bFound25_0 = FALSE;
  305. bFound25_1 = FALSE;
  306. bFound190 = FALSE;
  307. while (iBytes >= iFodoOff + 1) {
  308. iInfoLen = 0;
  309. switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) {
  310. case 24: /* fInTable */
  311. if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) {
  312. bFound24_1 = TRUE;
  313. } else {
  314. bFound24_0 = TRUE;
  315. }
  316. break;
  317. case 25: /* fTtp */
  318. if (odd(ucGetByte(iFodo + iFodoOff + 1, aucGrpprl))) {
  319. bFound25_1 = TRUE;
  320. } else {
  321. bFound25_0 = TRUE;
  322. }
  323. break;
  324. case 38: /* brcTop */
  325. usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
  326. usTmp &= 0x0018;
  327. NO_DBG_DEC(usTmp >> 3);
  328. if (usTmp == 0) {
  329. pRow->ucBorderInfo &= ~TABLE_BORDER_TOP;
  330. } else {
  331. pRow->ucBorderInfo |= TABLE_BORDER_TOP;
  332. }
  333. break;
  334. case 39: /* brcLeft */
  335. usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
  336. usTmp &= 0x0018;
  337. NO_DBG_DEC(usTmp >> 3);
  338. if (usTmp == 0) {
  339. pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT;
  340. } else {
  341. pRow->ucBorderInfo |= TABLE_BORDER_LEFT;
  342. }
  343. break;
  344. case 40: /* brcBottom */
  345. usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
  346. usTmp &= 0x0018;
  347. NO_DBG_DEC(usTmp >> 3);
  348. if (usTmp == 0) {
  349. pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM;
  350. } else {
  351. pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM;
  352. }
  353. break;
  354. case 41: /* brcRight */
  355. usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
  356. usTmp &= 0x0018;
  357. NO_DBG_DEC(usTmp >> 3);
  358. if (usTmp == 0) {
  359. pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT;
  360. } else {
  361. pRow->ucBorderInfo |= TABLE_BORDER_RIGHT;
  362. }
  363. break;
  364. case 188: /* cDefTable10 */
  365. DBG_MSG("188: sprmTDefTable10");
  366. iSize = (int)usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
  367. DBG_DEC(iSize);
  368. break;
  369. case 190: /* cDefTable */
  370. iSize = (int)usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
  371. if (iSize < 6 || iBytes < iFodoOff + 7) {
  372. DBG_DEC(iSize);
  373. DBG_DEC(iFodoOff);
  374. iInfoLen = 1;
  375. break;
  376. }
  377. iCol = (int)ucGetByte(iFodo + iFodoOff + 3, aucGrpprl);
  378. if (iCol < 1 ||
  379. iBytes < iFodoOff + 3 + (iCol + 1) * 2) {
  380. DBG_DEC(iCol);
  381. DBG_DEC(iFodoOff);
  382. iInfoLen = 1;
  383. break;
  384. }
  385. if (iCol >= (int)elementsof(pRow->asColumnWidth)) {
  386. DBG_DEC(iCol);
  387. werr(1, "The number of columns is corrupt");
  388. }
  389. pRow->ucNumberOfColumns = (UCHAR)iCol;
  390. iPosPrev = (int)(short)usGetWord(
  391. iFodo + iFodoOff + 4,
  392. aucGrpprl);
  393. for (iIndex = 0; iIndex < iCol; iIndex++) {
  394. iPosCurr = (int)(short)usGetWord(
  395. iFodo + iFodoOff + 6 + iIndex * 2,
  396. aucGrpprl);
  397. pRow->asColumnWidth[iIndex] =
  398. (short)(iPosCurr - iPosPrev);
  399. iPosPrev = iPosCurr;
  400. }
  401. bFound190 = TRUE;
  402. break;
  403. default:
  404. break;
  405. }
  406. if (iInfoLen <= 0) {
  407. iInfoLen =
  408. iGet6InfoLength(iFodo + iFodoOff, aucGrpprl);
  409. fail(iInfoLen <= 0);
  410. }
  411. iFodoOff += iInfoLen;
  412. }
  413. if (bFound25_1 && bFound190) {
  414. return found_end_of_row;
  415. }
  416. if (bFound25_0 && !bFound190) {
  417. return found_not_end_of_row;
  418. }
  419. if (bFound24_1) {
  420. return found_a_cell;
  421. }
  422. if (bFound24_0) {
  423. return found_not_a_cell;
  424. }
  425. return found_nothing;
  426. } /* end of eGet6RowInfo */
  427. /*
  428. * Fill the style information block with information
  429. * from a Word 6/7 file.
  430. */
  431. void
  432. vGet6StyleInfo(int iFodo,
  433. const UCHAR *aucGrpprl, int iBytes, style_block_type *pStyle)
  434. {
  435. int iFodoOff, iInfoLen;
  436. int iTmp, iDel, iAdd, iBefore;
  437. short sTmp;
  438. UCHAR ucTmp;
  439. fail(iFodo < 0 || aucGrpprl == NULL || pStyle == NULL);
  440. NO_DBG_DEC(pStyle->usIstd);
  441. iFodoOff = 0;
  442. while (iBytes >= iFodoOff + 1) {
  443. iInfoLen = 0;
  444. switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) {
  445. case 2: /* istd */
  446. sTmp = (short)ucGetByte(
  447. iFodo + iFodoOff + 1, aucGrpprl);
  448. NO_DBG_DEC(sTmp);
  449. break;
  450. case 5: /* jc */
  451. pStyle->ucAlignment = ucGetByte(
  452. iFodo + iFodoOff + 1, aucGrpprl);
  453. break;
  454. case 12: /* anld */
  455. iTmp = (int)ucGetByte(
  456. iFodo + iFodoOff + 1, aucGrpprl);
  457. DBG_DEC_C(iTmp < 52, iTmp);
  458. if (iTmp >= 1) {
  459. pStyle->ucNFC = ucGetByte(
  460. iFodo + iFodoOff + 2, aucGrpprl);
  461. }
  462. if (pStyle->ucNFC != LIST_BULLETS && iTmp >= 2) {
  463. iBefore = (int)ucGetByte(
  464. iFodo + iFodoOff + 3, aucGrpprl);
  465. } else {
  466. iBefore = 0;
  467. }
  468. if (iTmp >= 12) {
  469. pStyle->usStartAt = usGetWord(
  470. iFodo + iFodoOff + 12, aucGrpprl);
  471. }
  472. if (iTmp >= iBefore + 21) {
  473. pStyle->usListChar = (USHORT)ucGetByte(
  474. iFodo + iFodoOff + iBefore + 22,
  475. aucGrpprl);
  476. NO_DBG_HEX(pStyle->usListChar);
  477. }
  478. break;
  479. case 13: /* nLvlAnm */
  480. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  481. pStyle->ucNumLevel = ucTmp;
  482. pStyle->bNumPause =
  483. eGetNumType(ucTmp) == level_type_pause;
  484. break;
  485. case 15: /* ChgTabsPapx */
  486. case 23: /* ChgTabs */
  487. iTmp = (int)ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  488. if (iTmp < 2) {
  489. iInfoLen = 1;
  490. break;
  491. }
  492. NO_DBG_DEC(iTmp);
  493. iDel = (int)ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
  494. if (iTmp < 2 + 2 * iDel) {
  495. iInfoLen = 1;
  496. break;
  497. }
  498. NO_DBG_DEC(iDel);
  499. iAdd = (int)ucGetByte(
  500. iFodo + iFodoOff + 3 + 2 * iDel, aucGrpprl);
  501. if (iTmp < 2 + 2 * iDel + 2 * iAdd) {
  502. iInfoLen = 1;
  503. break;
  504. }
  505. NO_DBG_DEC(iAdd);
  506. break;
  507. case 16: /* dxaRight */
  508. pStyle->sRightIndent = (short)usGetWord(
  509. iFodo + iFodoOff + 1, aucGrpprl);
  510. NO_DBG_DEC(pStyle->sRightIndent);
  511. break;
  512. case 17: /* dxaLeft */
  513. pStyle->sLeftIndent = (short)usGetWord(
  514. iFodo + iFodoOff + 1, aucGrpprl);
  515. NO_DBG_DEC(pStyle->sLeftIndent);
  516. break;
  517. case 18: /* Nest dxaLeft */
  518. sTmp = (short)usGetWord(
  519. iFodo + iFodoOff + 1, aucGrpprl);
  520. pStyle->sLeftIndent += sTmp;
  521. if (pStyle->sLeftIndent < 0) {
  522. pStyle->sLeftIndent = 0;
  523. }
  524. NO_DBG_DEC(sTmp);
  525. NO_DBG_DEC(pStyle->sLeftIndent);
  526. break;
  527. case 19: /* dxaLeft1 */
  528. pStyle->sLeftIndent1 = (short)usGetWord(
  529. iFodo + iFodoOff + 1, aucGrpprl);
  530. NO_DBG_DEC(pStyle->sLeftIndent1);
  531. break;
  532. case 21: /* dyaBefore */
  533. pStyle->usBeforeIndent = usGetWord(
  534. iFodo + iFodoOff + 1, aucGrpprl);
  535. NO_DBG_DEC(pStyle->usBeforeIndent);
  536. break;
  537. case 22: /* dyaAfter */
  538. pStyle->usAfterIndent = usGetWord(
  539. iFodo + iFodoOff + 1, aucGrpprl);
  540. NO_DBG_DEC(pStyle->usAfterIndent);
  541. break;
  542. default:
  543. break;
  544. }
  545. if (iInfoLen <= 0) {
  546. iInfoLen =
  547. iGet6InfoLength(iFodo + iFodoOff, aucGrpprl);
  548. fail(iInfoLen <= 0);
  549. }
  550. iFodoOff += iInfoLen;
  551. }
  552. } /* end of vGet6StyleInfo */
  553. /*
  554. * Build the lists with Paragraph Information for Word 6/7 files
  555. */
  556. void
  557. vGet6PapInfo(FILE *pFile, ULONG ulStartBlock,
  558. const ULONG *aulBBD, size_t tBBDLen,
  559. const UCHAR *aucHeader)
  560. {
  561. row_block_type tRow;
  562. style_block_type tStyle;
  563. USHORT *ausParfPage;
  564. UCHAR *aucBuffer;
  565. ULONG ulCharPos, ulCharPosFirst, ulCharPosLast;
  566. ULONG ulBeginParfInfo;
  567. size_t tParfInfoLen, tParfPageNum, tOffset, tSize, tLenOld, tLen;
  568. size_t tIndex, tIndex2, tRun;
  569. int iFodo, iLen;
  570. row_info_enum eRowInfo;
  571. USHORT usParfFirstPage, usCount, usIstd;
  572. UCHAR aucFpage[BIG_BLOCK_SIZE];
  573. fail(pFile == NULL || aucHeader == NULL);
  574. fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
  575. fail(aulBBD == NULL);
  576. ulBeginParfInfo = ulGetLong(0xc0, aucHeader); /* fcPlcfbtePapx */
  577. NO_DBG_HEX(ulBeginParfInfo);
  578. tParfInfoLen = (size_t)ulGetLong(0xc4, aucHeader); /* lcbPlcfbtePapx */
  579. NO_DBG_DEC(tParfInfoLen);
  580. if (tParfInfoLen < 4) {
  581. DBG_DEC(tParfInfoLen);
  582. return;
  583. }
  584. aucBuffer = xmalloc(tParfInfoLen);
  585. if (!bReadBuffer(pFile, ulStartBlock,
  586. aulBBD, tBBDLen, BIG_BLOCK_SIZE,
  587. aucBuffer, ulBeginParfInfo, tParfInfoLen)) {
  588. aucBuffer = xfree(aucBuffer);
  589. return;
  590. }
  591. NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen);
  592. tLen = (tParfInfoLen - 4) / 6;
  593. ausParfPage = xcalloc(tLen, sizeof(USHORT));
  594. for (tIndex = 0, tOffset = (tLen + 1) * 4;
  595. tIndex < tLen;
  596. tIndex++, tOffset += 2) {
  597. ausParfPage[tIndex] = usGetWord(tOffset, aucBuffer);
  598. NO_DBG_DEC(ausParfPage[tIndex]);
  599. }
  600. DBG_HEX(ulGetLong(0, aucBuffer));
  601. aucBuffer = xfree(aucBuffer);
  602. tParfPageNum = (size_t)usGetWord(0x190, aucHeader); /* cpnBtePap */
  603. DBG_DEC(tParfPageNum);
  604. if (tLen < tParfPageNum) {
  605. /* Replace ParfPage by a longer version */
  606. tLenOld = tLen;
  607. usParfFirstPage = usGetWord(0x18c, aucHeader); /* pnPapFirst */
  608. DBG_DEC(usParfFirstPage);
  609. tLen += tParfPageNum - 1;
  610. tSize = tLen * sizeof(USHORT);
  611. ausParfPage = xrealloc(ausParfPage, tSize);
  612. /* Add new values */
  613. usCount = usParfFirstPage + 1;
  614. for (tIndex = tLenOld; tIndex < tLen; tIndex++) {
  615. ausParfPage[tIndex] = usCount;
  616. NO_DBG_DEC(ausParfPage[tIndex]);
  617. usCount++;
  618. }
  619. }
  620. (void)memset(&tRow, 0, sizeof(tRow));
  621. ulCharPosFirst = CP_INVALID;
  622. for (tIndex = 0; tIndex < tLen; tIndex++) {
  623. if (!bReadBuffer(pFile, ulStartBlock,
  624. aulBBD, tBBDLen, BIG_BLOCK_SIZE,
  625. aucFpage,
  626. (ULONG)ausParfPage[tIndex] * BIG_BLOCK_SIZE,
  627. BIG_BLOCK_SIZE)) {
  628. break;
  629. }
  630. tRun = (size_t)ucGetByte(0x1ff, aucFpage);
  631. NO_DBG_DEC(tRun);
  632. for (tIndex2 = 0; tIndex2 < tRun; tIndex2++) {
  633. NO_DBG_HEX(ulGetLong(tIndex2 * 4, aucFpage));
  634. iFodo = 2 * (int)ucGetByte(
  635. (tRun + 1) * 4 + tIndex2 * 7, aucFpage);
  636. if (iFodo <= 0) {
  637. continue;
  638. }
  639. iLen = 2 * (int)ucGetByte(iFodo, aucFpage);
  640. usIstd = (USHORT)ucGetByte(iFodo + 1, aucFpage);
  641. vFillStyleFromStylesheet(usIstd, &tStyle);
  642. vGet6StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle);
  643. ulCharPos = ulGetLong(tIndex2 * 4, aucFpage);
  644. NO_DBG_HEX(ulCharPos);
  645. tStyle.ulFileOffset = ulCharPos2FileOffsetX(
  646. ulCharPos, &tStyle.eListID);
  647. vAdd2StyleInfoList(&tStyle);
  648. eRowInfo = eGet6RowInfo(iFodo,
  649. aucFpage + 3, iLen - 3, &tRow);
  650. switch(eRowInfo) {
  651. case found_a_cell:
  652. if (ulCharPosFirst != CP_INVALID) {
  653. break;
  654. }
  655. ulCharPosFirst = ulGetLong(
  656. tIndex2 * 4, aucFpage);
  657. NO_DBG_HEX(ulCharPosFirst);
  658. tRow.ulCharPosStart = ulCharPosFirst;
  659. tRow.ulFileOffsetStart =
  660. ulCharPos2FileOffset(ulCharPosFirst);
  661. DBG_HEX_C(tRow.ulFileOffsetStart == FC_INVALID,
  662. ulCharPosFirst);
  663. break;
  664. case found_end_of_row:
  665. ulCharPosLast = ulGetLong(
  666. tIndex2 * 4, aucFpage);
  667. NO_DBG_HEX(ulCharPosLast);
  668. tRow.ulCharPosEnd = ulCharPosLast;
  669. tRow.ulFileOffsetEnd =
  670. ulCharPos2FileOffset(ulCharPosLast);
  671. DBG_HEX_C(tRow.ulFileOffsetEnd == FC_INVALID,
  672. ulCharPosLast);
  673. vAdd2RowInfoList(&tRow);
  674. (void)memset(&tRow, 0, sizeof(tRow));
  675. ulCharPosFirst = CP_INVALID;
  676. break;
  677. case found_nothing:
  678. break;
  679. default:
  680. DBG_DEC(eRowInfo);
  681. break;
  682. }
  683. }
  684. }
  685. ausParfPage = xfree(ausParfPage);
  686. } /* end of vGet6PapInfo */
  687. /*
  688. * Fill the font information block with information
  689. * from a Word 6/7 file.
  690. * Returns TRUE when successful, otherwise FALSE
  691. */
  692. void
  693. vGet6FontInfo(int iFodo, USHORT usIstd,
  694. const UCHAR *aucGrpprl, int iBytes, font_block_type *pFont)
  695. {
  696. long lTmp;
  697. int iFodoOff, iInfoLen;
  698. USHORT usTmp;
  699. UCHAR ucTmp;
  700. TRACE_MSG("vGet6FontInfo");
  701. fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL);
  702. iFodoOff = 0;
  703. while (iBytes >= iFodoOff + 1) {
  704. switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) {
  705. case 65: /* fRMarkDel */
  706. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  707. if (ucTmp == 0) {
  708. pFont->usFontStyle &= ~FONT_MARKDEL;
  709. } else {
  710. pFont->usFontStyle |= FONT_MARKDEL;
  711. }
  712. break;
  713. case 80: /* cIstd */
  714. usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
  715. NO_DBG_DEC(usTmp);
  716. break;
  717. case 82: /* cDefault */
  718. pFont->usFontStyle &= FONT_HIDDEN;
  719. pFont->ucFontColor = FONT_COLOR_DEFAULT;
  720. break;
  721. case 83: /* cPlain */
  722. DBG_MSG("83: cPlain");
  723. vFillFontFromStylesheet(usIstd, pFont);
  724. break;
  725. case 85: /* fBold */
  726. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  727. switch (ucTmp) {
  728. case 0: /* Unset */
  729. pFont->usFontStyle &= ~FONT_BOLD;
  730. break;
  731. case 1: /* Set */
  732. pFont->usFontStyle |= FONT_BOLD;
  733. break;
  734. case 128: /* Unchanged */
  735. break;
  736. case 129: /* Negation */
  737. pFont->usFontStyle ^= FONT_BOLD;
  738. break;
  739. default:
  740. DBG_DEC(ucTmp);
  741. DBG_FIXME();
  742. break;
  743. }
  744. break;
  745. case 86: /* fItalic */
  746. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  747. switch (ucTmp) {
  748. case 0: /* Unset */
  749. pFont->usFontStyle &= ~FONT_ITALIC;
  750. break;
  751. case 1: /* Set */
  752. pFont->usFontStyle |= FONT_ITALIC;
  753. break;
  754. case 128: /* Unchanged */
  755. break;
  756. case 129: /* Negation */
  757. pFont->usFontStyle ^= FONT_ITALIC;
  758. break;
  759. default:
  760. DBG_DEC(ucTmp);
  761. DBG_FIXME();
  762. break;
  763. }
  764. break;
  765. case 87: /* fStrike */
  766. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  767. switch (ucTmp) {
  768. case 0: /* Unset */
  769. pFont->usFontStyle &= ~FONT_STRIKE;
  770. break;
  771. case 1: /* Set */
  772. pFont->usFontStyle |= FONT_STRIKE;
  773. break;
  774. case 128: /* Unchanged */
  775. break;
  776. case 129: /* Negation */
  777. pFont->usFontStyle ^= FONT_STRIKE;
  778. break;
  779. default:
  780. DBG_DEC(ucTmp);
  781. DBG_FIXME();
  782. break;
  783. }
  784. break;
  785. case 90: /* fSmallCaps */
  786. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  787. switch (ucTmp) {
  788. case 0: /* Unset */
  789. pFont->usFontStyle &= ~FONT_SMALL_CAPITALS;
  790. break;
  791. case 1: /* Set */
  792. pFont->usFontStyle |= FONT_SMALL_CAPITALS;
  793. break;
  794. case 128: /* Unchanged */
  795. break;
  796. case 129: /* Negation */
  797. pFont->usFontStyle ^= FONT_SMALL_CAPITALS;
  798. break;
  799. default:
  800. DBG_DEC(ucTmp);
  801. DBG_FIXME();
  802. break;
  803. }
  804. break;
  805. case 91: /* fCaps */
  806. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  807. switch (ucTmp) {
  808. case 0: /* Unset */
  809. pFont->usFontStyle &= ~FONT_CAPITALS;
  810. break;
  811. case 1: /* Set */
  812. pFont->usFontStyle |= FONT_CAPITALS;
  813. break;
  814. case 128: /* Unchanged */
  815. break;
  816. case 129: /* Negation */
  817. pFont->usFontStyle ^= FONT_CAPITALS;
  818. break;
  819. default:
  820. DBG_DEC(ucTmp);
  821. DBG_FIXME();
  822. break;
  823. }
  824. break;
  825. case 92: /* fVanish */
  826. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  827. switch (ucTmp) {
  828. case 0: /* Unset */
  829. pFont->usFontStyle &= ~FONT_HIDDEN;
  830. break;
  831. case 1: /* Set */
  832. pFont->usFontStyle |= FONT_HIDDEN;
  833. break;
  834. case 128: /* Unchanged */
  835. break;
  836. case 129: /* Negation */
  837. pFont->usFontStyle ^= FONT_HIDDEN;
  838. break;
  839. default:
  840. DBG_DEC(ucTmp);
  841. DBG_FIXME();
  842. break;
  843. }
  844. break;
  845. case 93: /* cFtc */
  846. usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
  847. if (usTmp <= (USHORT)UCHAR_MAX) {
  848. pFont->ucFontNumber = (UCHAR)usTmp;
  849. } else {
  850. DBG_DEC(usTmp);
  851. DBG_FIXME();
  852. pFont->ucFontNumber = 0;
  853. }
  854. break;
  855. case 94: /* cKul */
  856. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  857. if (ucTmp == 0 || ucTmp == 5) {
  858. pFont->usFontStyle &= ~FONT_UNDERLINE;
  859. } else {
  860. NO_DBG_MSG("Underline text");
  861. pFont->usFontStyle |= FONT_UNDERLINE;
  862. if (ucTmp == 6) {
  863. DBG_MSG("Bold text");
  864. pFont->usFontStyle |= FONT_BOLD;
  865. }
  866. }
  867. break;
  868. case 95: /* cHps, cHpsPos */
  869. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  870. DBG_DEC(ucTmp);
  871. if (ucTmp != 0) {
  872. pFont->usFontSize = (USHORT)ucTmp;
  873. }
  874. ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
  875. DBG_DEC(ucTmp);
  876. break;
  877. case 98: /* cIco */
  878. pFont->ucFontColor =
  879. ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  880. break;
  881. case 99: /* cHps */
  882. pFont->usFontSize =
  883. usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
  884. break;
  885. case 100: /* cHpsInc */
  886. DBG_MSG("100: sprmCHpsInc");
  887. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  888. DBG_DEC(ucTmp);
  889. break;
  890. case 103: /* cMajority */
  891. DBG_MSG("103: sprmCMajority");
  892. break;
  893. case 104: /* cIss */
  894. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  895. ucTmp &= 0x07;
  896. if (ucTmp == 1) {
  897. pFont->usFontStyle |= FONT_SUPERSCRIPT;
  898. NO_DBG_MSG("Superscript");
  899. } else if (ucTmp == 2) {
  900. pFont->usFontStyle |= FONT_SUBSCRIPT;
  901. NO_DBG_MSG("Subscript");
  902. }
  903. break;
  904. case 106: /* cHpsInc1 */
  905. usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
  906. lTmp = (long)pFont->usFontSize + (long)usTmp;
  907. if (lTmp < 8) {
  908. pFont->usFontSize = 8;
  909. } else if (lTmp > 32766) {
  910. pFont->usFontSize = 32766;
  911. } else {
  912. pFont->usFontSize = (USHORT)lTmp;
  913. }
  914. break;
  915. case 108: /* cMajority50 */
  916. DBG_MSG("108: sprmCMajority50");
  917. break;
  918. case 109: /* cHpsMul */
  919. DBG_MSG("109: sprmCHpsMul");
  920. usTmp = usGetWord(iFodo + iFodoOff + 1, aucGrpprl);
  921. DBG_DEC(usTmp);
  922. break;
  923. default:
  924. break;
  925. }
  926. iInfoLen = iGet6InfoLength(iFodo + iFodoOff, aucGrpprl);
  927. fail(iInfoLen <= 0);
  928. iFodoOff += iInfoLen;
  929. }
  930. } /* end of vGet6FontInfo */
  931. /*
  932. * Fill the picture information block with information
  933. * from a Word 6/7 file.
  934. * Returns TRUE when successful, otherwise FALSE
  935. */
  936. static BOOL
  937. bGet6PicInfo(int iFodo,
  938. const UCHAR *aucGrpprl, int iBytes, picture_block_type *pPicture)
  939. {
  940. int iFodoOff, iInfoLen;
  941. BOOL bFound;
  942. UCHAR ucTmp;
  943. TRACE_MSG("vGet6PicInfo");
  944. fail(iFodo < 0 || aucGrpprl == NULL || pPicture == NULL);
  945. iFodoOff = 0;
  946. bFound = FALSE;
  947. while (iBytes >= iFodoOff + 1) {
  948. switch (ucGetByte(iFodo + iFodoOff, aucGrpprl)) {
  949. case 68: /* fcPic */
  950. pPicture->ulPictureOffset = ulGetLong(
  951. iFodo + iFodoOff + 2, aucGrpprl);
  952. bFound = TRUE;
  953. break;
  954. #if 0
  955. case 71: /* fData */
  956. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  957. if (ucTmp == 0x01) {
  958. /* Not a picture, but a form field */
  959. return FALSE;
  960. }
  961. DBG_DEC_C(ucTmp != 0, ucTmp);
  962. break;
  963. #endif
  964. case 75: /* fOle2 */
  965. ucTmp = ucGetByte(iFodo + iFodoOff + 1, aucGrpprl);
  966. if (ucTmp == 0x01) {
  967. /* Not a picture, but an OLE object */
  968. return FALSE;
  969. }
  970. DBG_DEC_C(ucTmp != 0, ucTmp);
  971. break;
  972. default:
  973. break;
  974. }
  975. iInfoLen = iGet6InfoLength(iFodo + iFodoOff, aucGrpprl);
  976. fail(iInfoLen <= 0);
  977. iFodoOff += iInfoLen;
  978. }
  979. return bFound;
  980. } /* end of bGet6PicInfo */
  981. /*
  982. * Build the lists with Character Information for Word 6/7 files
  983. */
  984. void
  985. vGet6ChrInfo(FILE *pFile, ULONG ulStartBlock,
  986. const ULONG *aulBBD, size_t tBBDLen, const UCHAR *aucHeader)
  987. {
  988. font_block_type tFont;
  989. picture_block_type tPicture;
  990. USHORT *ausCharPage;
  991. UCHAR *aucBuffer;
  992. ULONG ulFileOffset, ulCharPos, ulBeginCharInfo;
  993. size_t tCharInfoLen, tOffset, tSize, tLenOld, tLen, tCharPageNum;
  994. size_t tIndex, tIndex2, tRun;
  995. int iFodo, iLen;
  996. USHORT usCharFirstPage, usCount, usIstd;
  997. UCHAR aucFpage[BIG_BLOCK_SIZE];
  998. fail(pFile == NULL || aucHeader == NULL);
  999. fail(ulStartBlock > MAX_BLOCKNUMBER && ulStartBlock != END_OF_CHAIN);
  1000. fail(aulBBD == NULL);
  1001. ulBeginCharInfo = ulGetLong(0xb8, aucHeader); /* fcPlcfbteChpx */
  1002. NO_DBG_HEX(lBeginCharInfo);
  1003. tCharInfoLen = (size_t)ulGetLong(0xbc, aucHeader); /* lcbPlcfbteChpx */
  1004. NO_DBG_DEC(tCharInfoLen);
  1005. if (tCharInfoLen < 4) {
  1006. DBG_DEC(tCharInfoLen);
  1007. return;
  1008. }
  1009. aucBuffer = xmalloc(tCharInfoLen);
  1010. if (!bReadBuffer(pFile, ulStartBlock,
  1011. aulBBD, tBBDLen, BIG_BLOCK_SIZE,
  1012. aucBuffer, ulBeginCharInfo, tCharInfoLen)) {
  1013. aucBuffer = xfree(aucBuffer);
  1014. return;
  1015. }
  1016. tLen = (tCharInfoLen - 4) / 6;
  1017. ausCharPage = xcalloc(tLen, sizeof(USHORT));
  1018. for (tIndex = 0, tOffset = (tLen + 1) * 4;
  1019. tIndex < tLen;
  1020. tIndex++, tOffset += 2) {
  1021. ausCharPage[tIndex] = usGetWord(tOffset, aucBuffer);
  1022. NO_DBG_DEC(ausCharPage[tIndex]);
  1023. }
  1024. DBG_HEX(ulGetLong(0, aucBuffer));
  1025. aucBuffer = xfree(aucBuffer);
  1026. tCharPageNum = (size_t)usGetWord(0x18e, aucHeader); /* cpnBteChp */
  1027. DBG_DEC(tCharPageNum);
  1028. if (tLen < tCharPageNum) {
  1029. /* Replace CharPage by a longer version */
  1030. tLenOld = tLen;
  1031. usCharFirstPage = usGetWord(0x18a, aucHeader); /* pnChrFirst */
  1032. DBG_DEC(usCharFirstPage);
  1033. tLen += tCharPageNum - 1;
  1034. tSize = tLen * sizeof(USHORT);
  1035. ausCharPage = xrealloc(ausCharPage, tSize);
  1036. /* Add new values */
  1037. usCount = usCharFirstPage + 1;
  1038. for (tIndex = tLenOld; tIndex < tLen; tIndex++) {
  1039. ausCharPage[tIndex] = usCount;
  1040. NO_DBG_DEC(ausCharPage[tIndex]);
  1041. usCount++;
  1042. }
  1043. }
  1044. for (tIndex = 0; tIndex < tLen; tIndex++) {
  1045. if (!bReadBuffer(pFile, ulStartBlock,
  1046. aulBBD, tBBDLen, BIG_BLOCK_SIZE,
  1047. aucFpage,
  1048. (ULONG)ausCharPage[tIndex] * BIG_BLOCK_SIZE,
  1049. BIG_BLOCK_SIZE)) {
  1050. break;
  1051. }
  1052. tRun = (size_t)ucGetByte(0x1ff, aucFpage);
  1053. NO_DBG_DEC(tRun);
  1054. for (tIndex2 = 0; tIndex2 < tRun; tIndex2++) {
  1055. ulCharPos = ulGetLong(tIndex2 * 4, aucFpage);
  1056. ulFileOffset = ulCharPos2FileOffset(ulCharPos);
  1057. iFodo = 2 * (int)ucGetByte(
  1058. (tRun + 1) * 4 + tIndex2, aucFpage);
  1059. iLen = (int)ucGetByte(iFodo, aucFpage);
  1060. usIstd = usGetIstd(ulFileOffset);
  1061. vFillFontFromStylesheet(usIstd, &tFont);
  1062. if (iFodo != 0) {
  1063. vGet6FontInfo(iFodo, usIstd,
  1064. aucFpage + 1, iLen - 1, &tFont);
  1065. }
  1066. tFont.ulFileOffset = ulFileOffset;
  1067. vAdd2FontInfoList(&tFont);
  1068. if (iFodo <= 0) {
  1069. continue;
  1070. }
  1071. (void)memset(&tPicture, 0, sizeof(tPicture));
  1072. if (bGet6PicInfo(iFodo, aucFpage + 1,
  1073. iLen - 1, &tPicture)) {
  1074. tPicture.ulFileOffset = ulFileOffset;
  1075. tPicture.ulFileOffsetPicture =
  1076. ulDataPos2FileOffset(
  1077. tPicture.ulPictureOffset);
  1078. vAdd2PictInfoList(&tPicture);
  1079. }
  1080. }
  1081. }
  1082. ausCharPage = xfree(ausCharPage);
  1083. } /* end of vGet6ChrInfo */