1f5736e95SDavid du Colombier /*
2f5736e95SDavid du Colombier * prop8.c
3*25b329d5SDavid du Colombier * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
4f5736e95SDavid du Colombier *
5f5736e95SDavid du Colombier * Description:
6*25b329d5SDavid du Colombier * Read the property information from a MS Word 8, 9,10 or 11 file
7f5736e95SDavid du Colombier *
8f5736e95SDavid du Colombier * Word 8 is better known as Word 97 or as Word 98 for Mac
9f5736e95SDavid du Colombier * Word 9 is better known as Word 2000 or as Word 2001 for Mac
10f5736e95SDavid du Colombier * Word 10 is better known as Word 2002 or as Word XP
11*25b329d5SDavid du Colombier * Word 11 is better known as Word 2003
12f5736e95SDavid du Colombier */
13f5736e95SDavid du Colombier
14f5736e95SDavid du Colombier #include <stdlib.h>
15f5736e95SDavid du Colombier #include <string.h>
16f5736e95SDavid du Colombier #include "antiword.h"
17f5736e95SDavid du Colombier
18f5736e95SDavid du Colombier #define DEFAULT_LISTCHAR 0x002e /* A full stop */
19f5736e95SDavid du Colombier
20f5736e95SDavid du Colombier
21f5736e95SDavid du Colombier /*
22*25b329d5SDavid du Colombier * iGet8InfoLength - the length of the information for Word 8/9/10/11 files
23f5736e95SDavid du Colombier */
24f5736e95SDavid du Colombier static int
iGet8InfoLength(int iByteNbr,const UCHAR * aucGrpprl)25f5736e95SDavid du Colombier iGet8InfoLength(int iByteNbr, const UCHAR *aucGrpprl)
26f5736e95SDavid du Colombier {
27f5736e95SDavid du Colombier int iTmp, iDel, iAdd;
28f5736e95SDavid du Colombier USHORT usOpCode;
29f5736e95SDavid du Colombier
30f5736e95SDavid du Colombier usOpCode = usGetWord(iByteNbr, aucGrpprl);
31f5736e95SDavid du Colombier
32f5736e95SDavid du Colombier switch (usOpCode & 0xe000) {
33f5736e95SDavid du Colombier case 0x0000: case 0x2000:
34f5736e95SDavid du Colombier return 3;
35f5736e95SDavid du Colombier case 0x4000: case 0x8000: case 0xa000:
36f5736e95SDavid du Colombier return 4;
37f5736e95SDavid du Colombier case 0xe000:
38f5736e95SDavid du Colombier return 5;
39f5736e95SDavid du Colombier case 0x6000:
40f5736e95SDavid du Colombier return 6;
41f5736e95SDavid du Colombier case 0xc000:
42f5736e95SDavid du Colombier iTmp = (int)ucGetByte(iByteNbr + 2, aucGrpprl);
43f5736e95SDavid du Colombier if (usOpCode == 0xc615 && iTmp == 255) {
44f5736e95SDavid du Colombier iDel = (int)ucGetByte(iByteNbr + 3, aucGrpprl);
45f5736e95SDavid du Colombier iAdd = (int)ucGetByte(
46f5736e95SDavid du Colombier iByteNbr + 4 + iDel * 4, aucGrpprl);
47f5736e95SDavid du Colombier iTmp = 2 + iDel * 4 + iAdd * 3;
48f5736e95SDavid du Colombier }
49f5736e95SDavid du Colombier return 3 + iTmp;
50f5736e95SDavid du Colombier default:
51f5736e95SDavid du Colombier DBG_HEX(usOpCode);
52f5736e95SDavid du Colombier DBG_FIXME();
53f5736e95SDavid du Colombier return 1;
54f5736e95SDavid du Colombier }
55f5736e95SDavid du Colombier } /* end of iGet8InfoLength */
56f5736e95SDavid du Colombier
57f5736e95SDavid du Colombier /*
58*25b329d5SDavid du Colombier * aucFillInfoBuffer - fill the information buffer
59*25b329d5SDavid du Colombier *
60*25b329d5SDavid du Colombier * Returns the information buffer when successful, otherwise NULL
61*25b329d5SDavid du Colombier */
62*25b329d5SDavid du Colombier static UCHAR *
aucFillInfoBuffer(FILE * pFile,const pps_type * pTable,const ULONG * aulBBD,size_t tBBDLen,const ULONG * aulSBD,size_t tSBDLen,ULONG ulBeginInfo,size_t tInfoLen)63*25b329d5SDavid du Colombier aucFillInfoBuffer(FILE *pFile, const pps_type *pTable,
64*25b329d5SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
65*25b329d5SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
66*25b329d5SDavid du Colombier ULONG ulBeginInfo, size_t tInfoLen)
67*25b329d5SDavid du Colombier {
68*25b329d5SDavid du Colombier const ULONG *aulBlockDepot;
69*25b329d5SDavid du Colombier UCHAR *aucBuffer;
70*25b329d5SDavid du Colombier size_t tBlockDepotLen, tBlockSize;
71*25b329d5SDavid du Colombier
72*25b329d5SDavid du Colombier fail(pFile == NULL || pTable == NULL);
73*25b329d5SDavid du Colombier fail(aulBBD == NULL || aulSBD == NULL);
74*25b329d5SDavid du Colombier fail(tInfoLen == 0);
75*25b329d5SDavid du Colombier
76*25b329d5SDavid du Colombier NO_DBG_DEC(pTable->ulSB);
77*25b329d5SDavid du Colombier NO_DBG_HEX(pTable->ulSize);
78*25b329d5SDavid du Colombier if (pTable->ulSize == 0) {
79*25b329d5SDavid du Colombier DBG_MSG("No information");
80*25b329d5SDavid du Colombier return NULL;
81*25b329d5SDavid du Colombier }
82*25b329d5SDavid du Colombier
83*25b329d5SDavid du Colombier if (pTable->ulSize < MIN_SIZE_FOR_BBD_USE) {
84*25b329d5SDavid du Colombier /* Use the Small Block Depot */
85*25b329d5SDavid du Colombier aulBlockDepot = aulSBD;
86*25b329d5SDavid du Colombier tBlockDepotLen = tSBDLen;
87*25b329d5SDavid du Colombier tBlockSize = SMALL_BLOCK_SIZE;
88*25b329d5SDavid du Colombier } else {
89*25b329d5SDavid du Colombier /* Use the Big Block Depot */
90*25b329d5SDavid du Colombier aulBlockDepot = aulBBD;
91*25b329d5SDavid du Colombier tBlockDepotLen = tBBDLen;
92*25b329d5SDavid du Colombier tBlockSize = BIG_BLOCK_SIZE;
93*25b329d5SDavid du Colombier }
94*25b329d5SDavid du Colombier aucBuffer = xmalloc(tInfoLen);
95*25b329d5SDavid du Colombier if (!bReadBuffer(pFile, pTable->ulSB,
96*25b329d5SDavid du Colombier aulBlockDepot, tBlockDepotLen, tBlockSize,
97*25b329d5SDavid du Colombier aucBuffer, ulBeginInfo, tInfoLen)) {
98*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
99*25b329d5SDavid du Colombier return NULL;
100*25b329d5SDavid du Colombier }
101*25b329d5SDavid du Colombier return aucBuffer;
102*25b329d5SDavid du Colombier } /* end of aucFillInfoBuffer */
103*25b329d5SDavid du Colombier
104*25b329d5SDavid du Colombier /*
105*25b329d5SDavid du Colombier * Build the lists with Document Property Information for Word 8/9/10/11 files
106*25b329d5SDavid du Colombier */
107*25b329d5SDavid du Colombier void
vGet8DopInfo(FILE * pFile,const pps_type * pTable,const ULONG * aulBBD,size_t tBBDLen,const ULONG * aulSBD,size_t tSBDLen,const UCHAR * aucHeader)108*25b329d5SDavid du Colombier vGet8DopInfo(FILE *pFile, const pps_type *pTable,
109*25b329d5SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
110*25b329d5SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
111*25b329d5SDavid du Colombier const UCHAR *aucHeader)
112*25b329d5SDavid du Colombier {
113*25b329d5SDavid du Colombier document_block_type tDocument;
114*25b329d5SDavid du Colombier UCHAR *aucBuffer;
115*25b329d5SDavid du Colombier ULONG ulBeginDocpInfo, ulTmp;
116*25b329d5SDavid du Colombier size_t tDocpInfoLen;
117*25b329d5SDavid du Colombier USHORT usTmp;
118*25b329d5SDavid du Colombier
119*25b329d5SDavid du Colombier fail(pFile == NULL || pTable == NULL || aucHeader == NULL);
120*25b329d5SDavid du Colombier fail(aulBBD == NULL || aulSBD == NULL);
121*25b329d5SDavid du Colombier
122*25b329d5SDavid du Colombier ulBeginDocpInfo = ulGetLong(0x192, aucHeader); /* fcDop */
123*25b329d5SDavid du Colombier NO_DBG_HEX(ulBeginSectInfo);
124*25b329d5SDavid du Colombier tDocpInfoLen = (size_t)ulGetLong(0x196, aucHeader); /* lcbDop */
125*25b329d5SDavid du Colombier NO_DBG_DEC(tSectInfoLen);
126*25b329d5SDavid du Colombier if (tDocpInfoLen < 28) {
127*25b329d5SDavid du Colombier DBG_MSG("No Document information");
128*25b329d5SDavid du Colombier return;
129*25b329d5SDavid du Colombier }
130*25b329d5SDavid du Colombier
131*25b329d5SDavid du Colombier aucBuffer = aucFillInfoBuffer(pFile, pTable,
132*25b329d5SDavid du Colombier aulBBD, tBBDLen, aulSBD, tSBDLen,
133*25b329d5SDavid du Colombier ulBeginDocpInfo, tDocpInfoLen);
134*25b329d5SDavid du Colombier if (aucBuffer == NULL) {
135*25b329d5SDavid du Colombier return;
136*25b329d5SDavid du Colombier }
137*25b329d5SDavid du Colombier
138*25b329d5SDavid du Colombier usTmp = usGetWord(0x00, aucBuffer);
139*25b329d5SDavid du Colombier tDocument.ucHdrFtrSpecification = (UCHAR)(usTmp >> 8); /* grpfIhdt */
140*25b329d5SDavid du Colombier tDocument.usDefaultTabWidth = usGetWord(0x0a, aucBuffer); /* dxaTab */
141*25b329d5SDavid du Colombier ulTmp = ulGetLong(0x14, aucBuffer); /* dttmCreated */
142*25b329d5SDavid du Colombier tDocument.tCreateDate = tConvertDTTM(ulTmp);
143*25b329d5SDavid du Colombier ulTmp = ulGetLong(0x18, aucBuffer); /* dttmRevised */
144*25b329d5SDavid du Colombier tDocument.tRevisedDate = tConvertDTTM(ulTmp);
145*25b329d5SDavid du Colombier vCreateDocumentInfoList(&tDocument);
146*25b329d5SDavid du Colombier
147*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
148*25b329d5SDavid du Colombier } /* end of vGet8DopInfo */
149*25b329d5SDavid du Colombier
150*25b329d5SDavid du Colombier /*
151f5736e95SDavid du Colombier * Fill the section information block with information
152*25b329d5SDavid du Colombier * from a Word 8/9/10/11 file.
153f5736e95SDavid du Colombier */
154f5736e95SDavid du Colombier static void
vGet8SectionInfo(const UCHAR * aucGrpprl,size_t tBytes,section_block_type * pSection)155f5736e95SDavid du Colombier vGet8SectionInfo(const UCHAR *aucGrpprl, size_t tBytes,
156f5736e95SDavid du Colombier section_block_type *pSection)
157f5736e95SDavid du Colombier {
158f5736e95SDavid du Colombier UINT uiIndex;
159f5736e95SDavid du Colombier int iFodoOff, iInfoLen, iSize, iTmp;
160f5736e95SDavid du Colombier USHORT usCcol;
161f5736e95SDavid du Colombier UCHAR ucTmp;
162f5736e95SDavid du Colombier
163f5736e95SDavid du Colombier fail(aucGrpprl == NULL || pSection == NULL);
164f5736e95SDavid du Colombier
165f5736e95SDavid du Colombier iFodoOff = 0;
166f5736e95SDavid du Colombier while (tBytes >= (size_t)iFodoOff + 2) {
167f5736e95SDavid du Colombier iInfoLen = 0;
168f5736e95SDavid du Colombier switch (usGetWord(iFodoOff, aucGrpprl)) {
169f5736e95SDavid du Colombier case 0x3009: /* bkc */
170f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodoOff + 2, aucGrpprl);
171f5736e95SDavid du Colombier DBG_DEC(ucTmp);
172f5736e95SDavid du Colombier pSection->bNewPage = ucTmp != 0 && ucTmp != 1;
173f5736e95SDavid du Colombier break;
174*25b329d5SDavid du Colombier case 0x3014: /* grpfIhdt */
175*25b329d5SDavid du Colombier pSection->ucHdrFtrSpecification =
176*25b329d5SDavid du Colombier ucGetByte(iFodoOff + 2, aucGrpprl);
177*25b329d5SDavid du Colombier break;
178f5736e95SDavid du Colombier case 0x500b: /* ccolM1 */
179f5736e95SDavid du Colombier usCcol = 1 + usGetWord(iFodoOff + 2, aucGrpprl);
180f5736e95SDavid du Colombier DBG_DEC(usCcol);
181f5736e95SDavid du Colombier break;
182f5736e95SDavid du Colombier case 0xd202: /* olstAnm */
183f5736e95SDavid du Colombier iSize = (int)ucGetByte(iFodoOff + 2, aucGrpprl);
184f5736e95SDavid du Colombier DBG_DEC_C(iSize != 212, iSize);
185f5736e95SDavid du Colombier for (uiIndex = 0, iTmp = iFodoOff + 3;
186f5736e95SDavid du Colombier uiIndex < 9 && iTmp < iFodoOff + 3 + iSize - 15;
187f5736e95SDavid du Colombier uiIndex++, iTmp += 16) {
188f5736e95SDavid du Colombier pSection->aucNFC[uiIndex] =
189f5736e95SDavid du Colombier ucGetByte(iTmp, aucGrpprl);
190f5736e95SDavid du Colombier DBG_DEC(pSection->aucNFC[uiIndex]);
191f5736e95SDavid du Colombier ucTmp = ucGetByte(iTmp + 3, aucGrpprl);
192f5736e95SDavid du Colombier DBG_HEX(ucTmp);
193f5736e95SDavid du Colombier if ((ucTmp & BIT(2)) != 0) {
194f5736e95SDavid du Colombier pSection->usNeedPrevLvl |=
195f5736e95SDavid du Colombier (USHORT)BIT(uiIndex);
196f5736e95SDavid du Colombier }
197f5736e95SDavid du Colombier if ((ucTmp & BIT(3)) != 0) {
198f5736e95SDavid du Colombier pSection->usHangingIndent |=
199f5736e95SDavid du Colombier (USHORT)BIT(uiIndex);
200f5736e95SDavid du Colombier }
201f5736e95SDavid du Colombier }
202f5736e95SDavid du Colombier DBG_HEX(pSection->usNeedPrevLvl);
203f5736e95SDavid du Colombier DBG_HEX(pSection->usHangingIndent);
204f5736e95SDavid du Colombier break;
205f5736e95SDavid du Colombier default:
206f5736e95SDavid du Colombier break;
207f5736e95SDavid du Colombier }
208f5736e95SDavid du Colombier if (iInfoLen <= 0) {
209f5736e95SDavid du Colombier iInfoLen = iGet8InfoLength(iFodoOff, aucGrpprl);
210f5736e95SDavid du Colombier fail(iInfoLen <= 0);
211f5736e95SDavid du Colombier }
212f5736e95SDavid du Colombier iFodoOff += iInfoLen;
213f5736e95SDavid du Colombier }
214f5736e95SDavid du Colombier } /* end of vGet8SectionInfo */
215f5736e95SDavid du Colombier
216f5736e95SDavid du Colombier /*
217*25b329d5SDavid du Colombier * Build the lists with Section Property Information for Word 8/9/10/11 files
218f5736e95SDavid du Colombier */
219f5736e95SDavid du Colombier void
vGet8SepInfo(FILE * pFile,const pps_info_type * pPPS,const ULONG * aulBBD,size_t tBBDLen,const ULONG * aulSBD,size_t tSBDLen,const UCHAR * aucHeader)220f5736e95SDavid du Colombier vGet8SepInfo(FILE *pFile, const pps_info_type *pPPS,
221f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
222f5736e95SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
223f5736e95SDavid du Colombier const UCHAR *aucHeader)
224f5736e95SDavid du Colombier {
225f5736e95SDavid du Colombier section_block_type tSection;
226*25b329d5SDavid du Colombier ULONG *aulSectPage, *aulCharPos;
227f5736e95SDavid du Colombier UCHAR *aucBuffer, *aucFpage;
228*25b329d5SDavid du Colombier ULONG ulBeginOfText, ulTextOffset, ulBeginSectInfo;
229*25b329d5SDavid du Colombier size_t tSectInfoLen, tIndex, tOffset, tLen, tBytes;
230f5736e95SDavid du Colombier UCHAR aucTmp[2];
231f5736e95SDavid du Colombier
232f5736e95SDavid du Colombier fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
233f5736e95SDavid du Colombier fail(aulBBD == NULL || aulSBD == NULL);
234f5736e95SDavid du Colombier
235*25b329d5SDavid du Colombier ulBeginOfText = ulGetLong(0x18, aucHeader); /* fcMin */
236*25b329d5SDavid du Colombier NO_DBG_HEX(ulBeginOfText);
237f5736e95SDavid du Colombier ulBeginSectInfo = ulGetLong(0xca, aucHeader); /* fcPlcfsed */
238f5736e95SDavid du Colombier NO_DBG_HEX(ulBeginSectInfo);
239f5736e95SDavid du Colombier tSectInfoLen = (size_t)ulGetLong(0xce, aucHeader); /* lcbPlcfsed */
240f5736e95SDavid du Colombier NO_DBG_DEC(tSectInfoLen);
241f5736e95SDavid du Colombier if (tSectInfoLen < 4) {
242f5736e95SDavid du Colombier DBG_DEC(tSectInfoLen);
243f5736e95SDavid du Colombier return;
244f5736e95SDavid du Colombier }
245f5736e95SDavid du Colombier
246*25b329d5SDavid du Colombier aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable,
247*25b329d5SDavid du Colombier aulBBD, tBBDLen, aulSBD, tSBDLen,
248*25b329d5SDavid du Colombier ulBeginSectInfo, tSectInfoLen);
249*25b329d5SDavid du Colombier if (aucBuffer == NULL) {
250f5736e95SDavid du Colombier return;
251f5736e95SDavid du Colombier }
252f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucBuffer, tSectInfoLen);
253f5736e95SDavid du Colombier
254f5736e95SDavid du Colombier /* Read the Section Descriptors */
255f5736e95SDavid du Colombier tLen = (tSectInfoLen - 4) / 16;
256f5736e95SDavid du Colombier /* Save the section offsets */
257*25b329d5SDavid du Colombier aulCharPos = xcalloc(tLen, sizeof(ULONG));
258*25b329d5SDavid du Colombier for (tIndex = 0, tOffset = 0;
259*25b329d5SDavid du Colombier tIndex < tLen;
260*25b329d5SDavid du Colombier tIndex++, tOffset += 4) {
261*25b329d5SDavid du Colombier ulTextOffset = ulGetLong(tOffset, aucBuffer);
262*25b329d5SDavid du Colombier NO_DBG_HEX(ulTextOffset);
263*25b329d5SDavid du Colombier aulCharPos[tIndex] = ulBeginOfText + ulTextOffset;
264*25b329d5SDavid du Colombier NO_DBG_HEX(aulCharPos[tIndex]);
265f5736e95SDavid du Colombier }
266f5736e95SDavid du Colombier /* Save the Sepx offsets */
267f5736e95SDavid du Colombier aulSectPage = xcalloc(tLen, sizeof(ULONG));
268*25b329d5SDavid du Colombier for (tIndex = 0, tOffset = (tLen + 1) * 4;
269*25b329d5SDavid du Colombier tIndex < tLen;
270*25b329d5SDavid du Colombier tIndex++, tOffset += 12) {
271*25b329d5SDavid du Colombier aulSectPage[tIndex] = ulGetLong(tOffset + 2, aucBuffer);
272*25b329d5SDavid du Colombier NO_DBG_HEX(aulSectPage[tIndex]); /* fcSepx */
273f5736e95SDavid du Colombier }
274f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
275f5736e95SDavid du Colombier
276f5736e95SDavid du Colombier /* Read the Section Properties */
277*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < tLen; tIndex++) {
278*25b329d5SDavid du Colombier if (aulSectPage[tIndex] == FC_INVALID) {
279*25b329d5SDavid du Colombier vDefault2SectionInfoList(aulCharPos[tIndex]);
280f5736e95SDavid du Colombier continue;
281f5736e95SDavid du Colombier }
282f5736e95SDavid du Colombier /* Get the number of bytes to read */
283f5736e95SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB,
284f5736e95SDavid du Colombier aulBBD, tBBDLen, BIG_BLOCK_SIZE,
285*25b329d5SDavid du Colombier aucTmp, aulSectPage[tIndex], 2)) {
286f5736e95SDavid du Colombier continue;
287f5736e95SDavid du Colombier }
288f5736e95SDavid du Colombier tBytes = 2 + (size_t)usGetWord(0, aucTmp);
289f5736e95SDavid du Colombier NO_DBG_DEC(tBytes);
290f5736e95SDavid du Colombier /* Read the bytes */
291f5736e95SDavid du Colombier aucFpage = xmalloc(tBytes);
292f5736e95SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB,
293f5736e95SDavid du Colombier aulBBD, tBBDLen, BIG_BLOCK_SIZE,
294*25b329d5SDavid du Colombier aucFpage, aulSectPage[tIndex], tBytes)) {
295f5736e95SDavid du Colombier aucFpage = xfree(aucFpage);
296f5736e95SDavid du Colombier continue;
297f5736e95SDavid du Colombier }
298f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucFpage, tBytes);
299f5736e95SDavid du Colombier /* Process the bytes */
300f5736e95SDavid du Colombier vGetDefaultSection(&tSection);
301f5736e95SDavid du Colombier vGet8SectionInfo(aucFpage + 2, tBytes - 2, &tSection);
302*25b329d5SDavid du Colombier vAdd2SectionInfoList(&tSection, aulCharPos[tIndex]);
303f5736e95SDavid du Colombier aucFpage = xfree(aucFpage);
304f5736e95SDavid du Colombier }
305*25b329d5SDavid du Colombier aulCharPos = xfree(aulCharPos);
306f5736e95SDavid du Colombier aulSectPage = xfree(aulSectPage);
307f5736e95SDavid du Colombier } /* end of vGet8SepInfo */
308f5736e95SDavid du Colombier
309f5736e95SDavid du Colombier /*
310*25b329d5SDavid du Colombier * Build the list with Header/Footer Information for Word 8/9/10/11 files
311*25b329d5SDavid du Colombier */
312*25b329d5SDavid du Colombier void
vGet8HdrFtrInfo(FILE * pFile,const pps_type * pTable,const ULONG * aulBBD,size_t tBBDLen,const ULONG * aulSBD,size_t tSBDLen,const UCHAR * aucHeader)313*25b329d5SDavid du Colombier vGet8HdrFtrInfo(FILE *pFile, const pps_type *pTable,
314*25b329d5SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
315*25b329d5SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
316*25b329d5SDavid du Colombier const UCHAR *aucHeader)
317*25b329d5SDavid du Colombier {
318*25b329d5SDavid du Colombier ULONG *aulCharPos;
319*25b329d5SDavid du Colombier UCHAR *aucBuffer;
320*25b329d5SDavid du Colombier ULONG ulHdrFtrOffset, ulBeginHdrFtrInfo;
321*25b329d5SDavid du Colombier size_t tHdrFtrInfoLen, tIndex, tOffset, tLen;
322*25b329d5SDavid du Colombier
323*25b329d5SDavid du Colombier fail(pFile == NULL || pTable == NULL || aucHeader == NULL);
324*25b329d5SDavid du Colombier fail(aulBBD == NULL || aulSBD == NULL);
325*25b329d5SDavid du Colombier
326*25b329d5SDavid du Colombier ulBeginHdrFtrInfo = ulGetLong(0xf2, aucHeader); /* fcPlcfhdd */
327*25b329d5SDavid du Colombier NO_DBG_HEX(ulBeginHdrFtrInfo);
328*25b329d5SDavid du Colombier tHdrFtrInfoLen = (size_t)ulGetLong(0xf6, aucHeader); /* lcbPlcfhdd */
329*25b329d5SDavid du Colombier NO_DBG_DEC(tHdrFtrInfoLen);
330*25b329d5SDavid du Colombier if (tHdrFtrInfoLen < 8) {
331*25b329d5SDavid du Colombier DBG_DEC_C(tHdrFtrInfoLen != 0, tHdrFtrInfoLen);
332*25b329d5SDavid du Colombier return;
333*25b329d5SDavid du Colombier }
334*25b329d5SDavid du Colombier
335*25b329d5SDavid du Colombier aucBuffer = aucFillInfoBuffer(pFile, pTable,
336*25b329d5SDavid du Colombier aulBBD, tBBDLen, aulSBD, tSBDLen,
337*25b329d5SDavid du Colombier ulBeginHdrFtrInfo, tHdrFtrInfoLen);
338*25b329d5SDavid du Colombier if (aucBuffer == NULL) {
339*25b329d5SDavid du Colombier return;
340*25b329d5SDavid du Colombier }
341*25b329d5SDavid du Colombier NO_DBG_PRINT_BLOCK(aucBuffer, tHdrFtrInfoLen);
342*25b329d5SDavid du Colombier
343*25b329d5SDavid du Colombier tLen = tHdrFtrInfoLen / 4 - 1;
344*25b329d5SDavid du Colombier DBG_DEC_C(tLen % 12 != 1 && tLen % 12 != 7, tLen);
345*25b329d5SDavid du Colombier /* Save the header/footer offsets */
346*25b329d5SDavid du Colombier aulCharPos = xcalloc(tLen, sizeof(ULONG));
347*25b329d5SDavid du Colombier for (tIndex = 0, tOffset = 0;
348*25b329d5SDavid du Colombier tIndex < tLen;
349*25b329d5SDavid du Colombier tIndex++, tOffset += 4) {
350*25b329d5SDavid du Colombier ulHdrFtrOffset = ulGetLong(tOffset, aucBuffer);
351*25b329d5SDavid du Colombier NO_DBG_HEX(ulHdrFtrOffset);
352*25b329d5SDavid du Colombier aulCharPos[tIndex] = ulHdrFtrOffset2CharPos(ulHdrFtrOffset);
353*25b329d5SDavid du Colombier NO_DBG_HEX(aulCharPos[tIndex]);
354*25b329d5SDavid du Colombier }
355*25b329d5SDavid du Colombier vCreat8HdrFtrInfoList(aulCharPos, tLen);
356*25b329d5SDavid du Colombier /* Clean up and leave */
357*25b329d5SDavid du Colombier aulCharPos = xfree(aulCharPos);
358*25b329d5SDavid du Colombier aucBuffer = xfree(aucBuffer);
359*25b329d5SDavid du Colombier } /* end of vGet8HdrFtrInfo */
360*25b329d5SDavid du Colombier
361*25b329d5SDavid du Colombier /*
362f5736e95SDavid du Colombier * Translate the rowinfo to a member of the row_info enumeration
363f5736e95SDavid du Colombier */
364f5736e95SDavid du Colombier row_info_enum
eGet8RowInfo(int iFodo,const UCHAR * aucGrpprl,int iBytes,row_block_type * pRow)365f5736e95SDavid du Colombier eGet8RowInfo(int iFodo,
366f5736e95SDavid du Colombier const UCHAR *aucGrpprl, int iBytes, row_block_type *pRow)
367f5736e95SDavid du Colombier {
368f5736e95SDavid du Colombier int iFodoOff, iInfoLen;
369f5736e95SDavid du Colombier int iIndex, iSize, iCol;
370f5736e95SDavid du Colombier int iPosCurr, iPosPrev;
371f5736e95SDavid du Colombier USHORT usTmp;
372f5736e95SDavid du Colombier BOOL bFound2416_0, bFound2416_1, bFound2417_0, bFound2417_1;
373*25b329d5SDavid du Colombier BOOL bFound244b_0, bFound244b_1, bFound244c_0, bFound244c_1;
374f5736e95SDavid du Colombier BOOL bFoundd608;
375f5736e95SDavid du Colombier
376f5736e95SDavid du Colombier fail(iFodo < 0 || aucGrpprl == NULL || pRow == NULL);
377f5736e95SDavid du Colombier
378f5736e95SDavid du Colombier iFodoOff = 0;
379f5736e95SDavid du Colombier bFound2416_0 = FALSE;
380f5736e95SDavid du Colombier bFound2416_1 = FALSE;
381f5736e95SDavid du Colombier bFound2417_0 = FALSE;
382f5736e95SDavid du Colombier bFound2417_1 = FALSE;
383*25b329d5SDavid du Colombier bFound244b_0 = FALSE;
384*25b329d5SDavid du Colombier bFound244b_1 = FALSE;
385*25b329d5SDavid du Colombier bFound244c_0 = FALSE;
386*25b329d5SDavid du Colombier bFound244c_1 = FALSE;
387f5736e95SDavid du Colombier bFoundd608 = FALSE;
388f5736e95SDavid du Colombier while (iBytes >= iFodoOff + 2) {
389f5736e95SDavid du Colombier iInfoLen = 0;
390f5736e95SDavid du Colombier switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) {
391*25b329d5SDavid du Colombier case 0x2416: /* fInTable */
392f5736e95SDavid du Colombier if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) {
393f5736e95SDavid du Colombier bFound2416_1 = TRUE;
394f5736e95SDavid du Colombier } else {
395f5736e95SDavid du Colombier bFound2416_0 = TRUE;
396f5736e95SDavid du Colombier }
397f5736e95SDavid du Colombier break;
398f5736e95SDavid du Colombier case 0x2417: /* fTtp */
399f5736e95SDavid du Colombier if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) {
400f5736e95SDavid du Colombier bFound2417_1 = TRUE;
401f5736e95SDavid du Colombier } else {
402f5736e95SDavid du Colombier bFound2417_0 = TRUE;
403f5736e95SDavid du Colombier }
404f5736e95SDavid du Colombier break;
405*25b329d5SDavid du Colombier case 0x244b: /* sub-table fInTable */
406*25b329d5SDavid du Colombier if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) {
407*25b329d5SDavid du Colombier bFound244b_1 = TRUE;
408*25b329d5SDavid du Colombier } else {
409*25b329d5SDavid du Colombier bFound244b_0 = TRUE;
410*25b329d5SDavid du Colombier }
411*25b329d5SDavid du Colombier break;
412*25b329d5SDavid du Colombier case 0x244c: /* sub-table fTtp */
413*25b329d5SDavid du Colombier if (odd(ucGetByte(iFodo + iFodoOff + 2, aucGrpprl))) {
414*25b329d5SDavid du Colombier bFound244c_1 = TRUE;
415*25b329d5SDavid du Colombier } else {
416*25b329d5SDavid du Colombier bFound244c_0 = TRUE;
417*25b329d5SDavid du Colombier }
418*25b329d5SDavid du Colombier break;
419f5736e95SDavid du Colombier case 0x6424: /* brcTop */
420f5736e95SDavid du Colombier usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
421f5736e95SDavid du Colombier usTmp &= 0xff00;
422f5736e95SDavid du Colombier NO_DBG_DEC(usTmp >> 8);
423f5736e95SDavid du Colombier if (usTmp == 0) {
424f5736e95SDavid du Colombier pRow->ucBorderInfo &= ~TABLE_BORDER_TOP;
425f5736e95SDavid du Colombier } else {
426f5736e95SDavid du Colombier pRow->ucBorderInfo |= TABLE_BORDER_TOP;
427f5736e95SDavid du Colombier }
428f5736e95SDavid du Colombier break;
429f5736e95SDavid du Colombier case 0x6425: /* brcLeft */
430f5736e95SDavid du Colombier usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
431f5736e95SDavid du Colombier usTmp &= 0xff00;
432f5736e95SDavid du Colombier NO_DBG_DEC(usTmp >> 8);
433f5736e95SDavid du Colombier if (usTmp == 0) {
434f5736e95SDavid du Colombier pRow->ucBorderInfo &= ~TABLE_BORDER_LEFT;
435f5736e95SDavid du Colombier } else {
436f5736e95SDavid du Colombier pRow->ucBorderInfo |= TABLE_BORDER_LEFT;
437f5736e95SDavid du Colombier }
438f5736e95SDavid du Colombier break;
439f5736e95SDavid du Colombier case 0x6426: /* brcBottom */
440f5736e95SDavid du Colombier usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
441f5736e95SDavid du Colombier usTmp &= 0xff00;
442f5736e95SDavid du Colombier NO_DBG_DEC(usTmp >> 8);
443f5736e95SDavid du Colombier if (usTmp == 0) {
444f5736e95SDavid du Colombier pRow->ucBorderInfo &= ~TABLE_BORDER_BOTTOM;
445f5736e95SDavid du Colombier } else {
446f5736e95SDavid du Colombier pRow->ucBorderInfo |= TABLE_BORDER_BOTTOM;
447f5736e95SDavid du Colombier }
448f5736e95SDavid du Colombier break;
449f5736e95SDavid du Colombier case 0x6427: /* brcRight */
450f5736e95SDavid du Colombier usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
451f5736e95SDavid du Colombier usTmp &= 0xff00;
452f5736e95SDavid du Colombier NO_DBG_DEC(usTmp >> 8);
453f5736e95SDavid du Colombier if (usTmp == 0) {
454f5736e95SDavid du Colombier pRow->ucBorderInfo &= ~TABLE_BORDER_RIGHT;
455f5736e95SDavid du Colombier } else {
456f5736e95SDavid du Colombier pRow->ucBorderInfo |= TABLE_BORDER_RIGHT;
457f5736e95SDavid du Colombier }
458f5736e95SDavid du Colombier break;
459*25b329d5SDavid du Colombier case 0xd606: /* cDefTable10 */
460*25b329d5SDavid du Colombier DBG_MSG("0xd606: sprmTDefTable10");
461*25b329d5SDavid du Colombier iSize = (int)usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
462*25b329d5SDavid du Colombier DBG_DEC(iSize);
463*25b329d5SDavid du Colombier break;
464f5736e95SDavid du Colombier case 0xd608: /* cDefTable */
465f5736e95SDavid du Colombier iSize = (int)usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
466f5736e95SDavid du Colombier if (iSize < 6 || iBytes < iFodoOff + 8) {
467f5736e95SDavid du Colombier DBG_DEC(iSize);
468f5736e95SDavid du Colombier DBG_DEC(iFodoOff);
469f5736e95SDavid du Colombier iInfoLen = 2;
470f5736e95SDavid du Colombier break;
471f5736e95SDavid du Colombier }
472f5736e95SDavid du Colombier iCol = (int)ucGetByte(iFodo + iFodoOff + 4, aucGrpprl);
473f5736e95SDavid du Colombier if (iCol < 1 ||
474f5736e95SDavid du Colombier iBytes < iFodoOff + 4 + (iCol + 1) * 2) {
475f5736e95SDavid du Colombier DBG_DEC(iCol);
476f5736e95SDavid du Colombier DBG_DEC(iFodoOff);
477f5736e95SDavid du Colombier iInfoLen = 2;
478f5736e95SDavid du Colombier break;
479f5736e95SDavid du Colombier }
480f5736e95SDavid du Colombier if (iCol >= (int)elementsof(pRow->asColumnWidth)) {
481f5736e95SDavid du Colombier DBG_DEC(iCol);
482f5736e95SDavid du Colombier werr(1, "The number of columns is corrupt");
483f5736e95SDavid du Colombier }
484f5736e95SDavid du Colombier pRow->ucNumberOfColumns = (UCHAR)iCol;
485f5736e95SDavid du Colombier iPosPrev = (int)(short)usGetWord(
486f5736e95SDavid du Colombier iFodo + iFodoOff + 5,
487f5736e95SDavid du Colombier aucGrpprl);
488f5736e95SDavid du Colombier for (iIndex = 0; iIndex < iCol; iIndex++) {
489f5736e95SDavid du Colombier iPosCurr = (int)(short)usGetWord(
490f5736e95SDavid du Colombier iFodo + iFodoOff + 7 + iIndex * 2,
491f5736e95SDavid du Colombier aucGrpprl);
492f5736e95SDavid du Colombier pRow->asColumnWidth[iIndex] =
493f5736e95SDavid du Colombier (short)(iPosCurr - iPosPrev);
494f5736e95SDavid du Colombier iPosPrev = iPosCurr;
495f5736e95SDavid du Colombier }
496f5736e95SDavid du Colombier bFoundd608 = TRUE;
497f5736e95SDavid du Colombier break;
498f5736e95SDavid du Colombier default:
499f5736e95SDavid du Colombier break;
500f5736e95SDavid du Colombier }
501f5736e95SDavid du Colombier if (iInfoLen <= 0) {
502f5736e95SDavid du Colombier iInfoLen =
503f5736e95SDavid du Colombier iGet8InfoLength(iFodo + iFodoOff, aucGrpprl);
504f5736e95SDavid du Colombier fail(iInfoLen <= 0);
505f5736e95SDavid du Colombier }
506f5736e95SDavid du Colombier iFodoOff += iInfoLen;
507f5736e95SDavid du Colombier }
508*25b329d5SDavid du Colombier
509*25b329d5SDavid du Colombier if (bFound2417_1 && bFoundd608) {
510f5736e95SDavid du Colombier return found_end_of_row;
511f5736e95SDavid du Colombier }
512*25b329d5SDavid du Colombier if (bFound2417_0 && !bFoundd608) {
513f5736e95SDavid du Colombier return found_not_end_of_row;
514f5736e95SDavid du Colombier }
515*25b329d5SDavid du Colombier if (bFound2416_1 || bFound244b_1) {
516f5736e95SDavid du Colombier return found_a_cell;
517f5736e95SDavid du Colombier }
518*25b329d5SDavid du Colombier if (bFound2416_0 || bFound244b_0) {
519f5736e95SDavid du Colombier return found_not_a_cell;
520f5736e95SDavid du Colombier }
521f5736e95SDavid du Colombier return found_nothing;
522f5736e95SDavid du Colombier } /* end of eGet8RowInfo */
523f5736e95SDavid du Colombier
524f5736e95SDavid du Colombier /*
525f5736e95SDavid du Colombier * Fill the style information block with information
526*25b329d5SDavid du Colombier * from a Word 8/9/10/11 file.
527f5736e95SDavid du Colombier */
528f5736e95SDavid du Colombier void
vGet8StyleInfo(int iFodo,const UCHAR * aucGrpprl,int iBytes,style_block_type * pStyle)529f5736e95SDavid du Colombier vGet8StyleInfo(int iFodo,
530f5736e95SDavid du Colombier const UCHAR *aucGrpprl, int iBytes, style_block_type *pStyle)
531f5736e95SDavid du Colombier {
532f5736e95SDavid du Colombier list_block_type tList6;
533f5736e95SDavid du Colombier const list_block_type *pList;
534f5736e95SDavid du Colombier int iFodoOff, iInfoLen;
535f5736e95SDavid du Colombier int iTmp, iDel, iAdd, iBefore;
536f5736e95SDavid du Colombier USHORT usOpCode, usTmp;
537f5736e95SDavid du Colombier short sTmp;
538f5736e95SDavid du Colombier
539f5736e95SDavid du Colombier fail(iFodo < 0 || aucGrpprl == NULL || pStyle == NULL);
540f5736e95SDavid du Colombier
541f5736e95SDavid du Colombier NO_DBG_DEC_C(pStyle->usListIndex != 0, pStyle->usIstd);
542f5736e95SDavid du Colombier NO_DBG_DEC_C(pStyle->usListIndex != 0, pStyle->usListIndex);
543f5736e95SDavid du Colombier
544f5736e95SDavid du Colombier (void)memset(&tList6, 0, sizeof(tList6));
545f5736e95SDavid du Colombier
546f5736e95SDavid du Colombier iFodoOff = 0;
547f5736e95SDavid du Colombier while (iBytes >= iFodoOff + 2) {
548f5736e95SDavid du Colombier iInfoLen = 0;
549f5736e95SDavid du Colombier usOpCode = usGetWord(iFodo + iFodoOff, aucGrpprl);
550f5736e95SDavid du Colombier switch (usOpCode) {
551f5736e95SDavid du Colombier case 0x2403: /* jc */
552f5736e95SDavid du Colombier pStyle->ucAlignment = ucGetByte(
553f5736e95SDavid du Colombier iFodo + iFodoOff + 2, aucGrpprl);
554f5736e95SDavid du Colombier break;
555f5736e95SDavid du Colombier case 0x260a: /* ilvl */
556f5736e95SDavid du Colombier pStyle->ucListLevel =
557f5736e95SDavid du Colombier ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
558f5736e95SDavid du Colombier NO_DBG_DEC(pStyle->ucListLevel);
559f5736e95SDavid du Colombier pStyle->ucNumLevel = pStyle->ucListLevel;
560f5736e95SDavid du Colombier break;
561f5736e95SDavid du Colombier case 0x4600: /* istd */
562f5736e95SDavid du Colombier usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
563f5736e95SDavid du Colombier NO_DBG_DEC(usTmp);
564f5736e95SDavid du Colombier break;
565f5736e95SDavid du Colombier case 0x460b: /* ilfo */
566f5736e95SDavid du Colombier pStyle->usListIndex =
567f5736e95SDavid du Colombier usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
568f5736e95SDavid du Colombier NO_DBG_DEC(pStyle->usListIndex);
569f5736e95SDavid du Colombier break;
570f5736e95SDavid du Colombier case 0x4610: /* Nest dxaLeft */
571f5736e95SDavid du Colombier sTmp = (short)usGetWord(
572f5736e95SDavid du Colombier iFodo + iFodoOff + 2, aucGrpprl);
573f5736e95SDavid du Colombier pStyle->sLeftIndent += sTmp;
574f5736e95SDavid du Colombier if (pStyle->sLeftIndent < 0) {
575f5736e95SDavid du Colombier pStyle->sLeftIndent = 0;
576f5736e95SDavid du Colombier }
577f5736e95SDavid du Colombier DBG_DEC(sTmp);
578f5736e95SDavid du Colombier DBG_DEC(pStyle->sLeftIndent);
579f5736e95SDavid du Colombier break;
580*25b329d5SDavid du Colombier case 0xc60d: /* ChgTabsPapx */
581*25b329d5SDavid du Colombier case 0xc615: /* ChgTabs */
582f5736e95SDavid du Colombier iTmp = (int)ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
583f5736e95SDavid du Colombier if (iTmp < 2) {
584f5736e95SDavid du Colombier iInfoLen = 1;
585f5736e95SDavid du Colombier break;
586f5736e95SDavid du Colombier }
587*25b329d5SDavid du Colombier NO_DBG_DEC(iTmp);
588f5736e95SDavid du Colombier iDel = (int)ucGetByte(iFodo + iFodoOff + 3, aucGrpprl);
589f5736e95SDavid du Colombier if (iTmp < 2 + 2 * iDel) {
590f5736e95SDavid du Colombier iInfoLen = 1;
591f5736e95SDavid du Colombier break;
592f5736e95SDavid du Colombier }
593*25b329d5SDavid du Colombier NO_DBG_DEC(iDel);
594f5736e95SDavid du Colombier iAdd = (int)ucGetByte(
595f5736e95SDavid du Colombier iFodo + iFodoOff + 4 + 2 * iDel, aucGrpprl);
596f5736e95SDavid du Colombier if (iTmp < 2 + 2 * iDel + 2 * iAdd) {
597f5736e95SDavid du Colombier iInfoLen = 1;
598f5736e95SDavid du Colombier break;
599f5736e95SDavid du Colombier }
600*25b329d5SDavid du Colombier NO_DBG_DEC(iAdd);
601f5736e95SDavid du Colombier break;
602f5736e95SDavid du Colombier case 0x840e: /* dxaRight */
603f5736e95SDavid du Colombier pStyle->sRightIndent = (short)usGetWord(
604f5736e95SDavid du Colombier iFodo + iFodoOff + 2, aucGrpprl);
605f5736e95SDavid du Colombier NO_DBG_DEC(pStyle->sRightIndent);
606f5736e95SDavid du Colombier break;
607f5736e95SDavid du Colombier case 0x840f: /* dxaLeft */
608f5736e95SDavid du Colombier pStyle->sLeftIndent = (short)usGetWord(
609f5736e95SDavid du Colombier iFodo + iFodoOff + 2, aucGrpprl);
610f5736e95SDavid du Colombier NO_DBG_DEC(pStyle->sLeftIndent);
611f5736e95SDavid du Colombier break;
612f5736e95SDavid du Colombier case 0x8411: /* dxaLeft1 */
613f5736e95SDavid du Colombier pStyle->sLeftIndent1 = (short)usGetWord(
614f5736e95SDavid du Colombier iFodo + iFodoOff + 2, aucGrpprl);
615f5736e95SDavid du Colombier NO_DBG_DEC(pStyle->sLeftIndent1);
616f5736e95SDavid du Colombier break;
617f5736e95SDavid du Colombier case 0xa413: /* dyaBefore */
618f5736e95SDavid du Colombier pStyle->usBeforeIndent = usGetWord(
619f5736e95SDavid du Colombier iFodo + iFodoOff + 2, aucGrpprl);
620f5736e95SDavid du Colombier NO_DBG_DEC(pStyle->usBeforeIndent);
621f5736e95SDavid du Colombier break;
622f5736e95SDavid du Colombier case 0xa414: /* dyaAfter */
623f5736e95SDavid du Colombier pStyle->usAfterIndent = usGetWord(
624f5736e95SDavid du Colombier iFodo + iFodoOff + 2, aucGrpprl);
625f5736e95SDavid du Colombier NO_DBG_DEC(pStyle->usAfterIndent);
626f5736e95SDavid du Colombier break;
627f5736e95SDavid du Colombier case 0xc63e: /* anld */
628f5736e95SDavid du Colombier iTmp = (int)ucGetByte(
629f5736e95SDavid du Colombier iFodo + iFodoOff + 2, aucGrpprl);
630f5736e95SDavid du Colombier DBG_DEC_C(iTmp < 84, iTmp);
631f5736e95SDavid du Colombier if (iTmp >= 1) {
632f5736e95SDavid du Colombier tList6.ucNFC = ucGetByte(
633f5736e95SDavid du Colombier iFodo + iFodoOff + 3, aucGrpprl);
634f5736e95SDavid du Colombier }
635f5736e95SDavid du Colombier if (tList6.ucNFC != LIST_BULLETS && iTmp >= 2) {
636f5736e95SDavid du Colombier iBefore = (int)ucGetByte(
637f5736e95SDavid du Colombier iFodo + iFodoOff + 4, aucGrpprl);
638f5736e95SDavid du Colombier } else {
639f5736e95SDavid du Colombier iBefore = 0;
640f5736e95SDavid du Colombier }
641f5736e95SDavid du Colombier if (iTmp >= 12) {
642f5736e95SDavid du Colombier tList6.ulStartAt = (ULONG)usGetWord(
643f5736e95SDavid du Colombier iFodo + iFodoOff + 13, aucGrpprl);
644f5736e95SDavid du Colombier }
645f5736e95SDavid du Colombier if (iTmp >= iBefore + 22) {
646f5736e95SDavid du Colombier tList6.usListChar = usGetWord(
647f5736e95SDavid du Colombier iFodo + iFodoOff + iBefore + 23,
648f5736e95SDavid du Colombier aucGrpprl);
649f5736e95SDavid du Colombier DBG_HEX(tList6.usListChar);
650f5736e95SDavid du Colombier }
651f5736e95SDavid du Colombier break;
652f5736e95SDavid du Colombier default:
653f5736e95SDavid du Colombier NO_DBG_HEX(usOpCode);
654f5736e95SDavid du Colombier break;
655f5736e95SDavid du Colombier }
656f5736e95SDavid du Colombier if (iInfoLen <= 0) {
657f5736e95SDavid du Colombier iInfoLen =
658f5736e95SDavid du Colombier iGet8InfoLength(iFodo + iFodoOff, aucGrpprl);
659f5736e95SDavid du Colombier fail(iInfoLen <= 0);
660f5736e95SDavid du Colombier }
661f5736e95SDavid du Colombier iFodoOff += iInfoLen;
662f5736e95SDavid du Colombier }
663f5736e95SDavid du Colombier
664f5736e95SDavid du Colombier if (pStyle->usListIndex == 2047) {
665f5736e95SDavid du Colombier /* Old style list */
666f5736e95SDavid du Colombier pStyle->usStartAt = (USHORT)tList6.ulStartAt;
667f5736e95SDavid du Colombier pStyle->usListChar = tList6.usListChar;
668f5736e95SDavid du Colombier pStyle->ucNFC = tList6.ucNFC;
669f5736e95SDavid du Colombier } else {
670f5736e95SDavid du Colombier /* New style list */
671f5736e95SDavid du Colombier pList = pGetListInfo(pStyle->usListIndex, pStyle->ucListLevel);
672f5736e95SDavid du Colombier if (pList != NULL) {
673f5736e95SDavid du Colombier pStyle->bNoRestart = pList->bNoRestart;
674f5736e95SDavid du Colombier fail(pList->ulStartAt > (ULONG)USHRT_MAX);
675f5736e95SDavid du Colombier pStyle->usStartAt = (USHORT)pList->ulStartAt;
676f5736e95SDavid du Colombier pStyle->usListChar = pList->usListChar;
677f5736e95SDavid du Colombier pStyle->ucNFC = pList->ucNFC;
678f5736e95SDavid du Colombier if (pStyle->sLeftIndent <= 0) {
679f5736e95SDavid du Colombier pStyle->sLeftIndent = pList->sLeftIndent;
680f5736e95SDavid du Colombier }
681f5736e95SDavid du Colombier }
682f5736e95SDavid du Colombier }
683f5736e95SDavid du Colombier } /* end of vGet8StyleInfo */
684f5736e95SDavid du Colombier
685f5736e95SDavid du Colombier /*
686f5736e95SDavid du Colombier * Get the left indentation value from the style information block
687f5736e95SDavid du Colombier *
688f5736e95SDavid du Colombier * Returns the value when found, otherwise 0
689f5736e95SDavid du Colombier */
690f5736e95SDavid du Colombier static short
sGetLeftIndent(const UCHAR * aucGrpprl,size_t tBytes)691f5736e95SDavid du Colombier sGetLeftIndent(const UCHAR *aucGrpprl, size_t tBytes)
692f5736e95SDavid du Colombier {
693f5736e95SDavid du Colombier int iOffset, iInfoLen;
694f5736e95SDavid du Colombier USHORT usOpCode, usTmp;
695f5736e95SDavid du Colombier
696f5736e95SDavid du Colombier fail(aucGrpprl == NULL);
697f5736e95SDavid du Colombier
698f5736e95SDavid du Colombier iOffset = 0;
699f5736e95SDavid du Colombier while (tBytes >= (size_t)iOffset + 4) {
700f5736e95SDavid du Colombier usOpCode = usGetWord(iOffset, aucGrpprl);
701f5736e95SDavid du Colombier if (usOpCode == 0x840f) { /* dxaLeft */
702f5736e95SDavid du Colombier usTmp = usGetWord(iOffset + 2, aucGrpprl);
703f5736e95SDavid du Colombier if (usTmp <= 0x7fff) {
704f5736e95SDavid du Colombier NO_DBG_DEC(usTmp);
705f5736e95SDavid du Colombier return (short)usTmp;
706f5736e95SDavid du Colombier }
707f5736e95SDavid du Colombier }
708f5736e95SDavid du Colombier iInfoLen = iGet8InfoLength(iOffset, aucGrpprl);
709f5736e95SDavid du Colombier fail(iInfoLen <= 0);
710f5736e95SDavid du Colombier iOffset += iInfoLen;
711f5736e95SDavid du Colombier }
712f5736e95SDavid du Colombier return 0;
713f5736e95SDavid du Colombier } /* end of sGetLeftIndent */
714f5736e95SDavid du Colombier
715f5736e95SDavid du Colombier /*
716*25b329d5SDavid du Colombier * Build the list with List Information for Word 8/9/10/11 files
717f5736e95SDavid du Colombier */
718f5736e95SDavid du Colombier void
vGet8LstInfo(FILE * pFile,const pps_info_type * pPPS,const ULONG * aulBBD,size_t tBBDLen,const ULONG * aulSBD,size_t tSBDLen,const UCHAR * aucHeader)719f5736e95SDavid du Colombier vGet8LstInfo(FILE *pFile, const pps_info_type *pPPS,
720f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
721f5736e95SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
722f5736e95SDavid du Colombier const UCHAR *aucHeader)
723f5736e95SDavid du Colombier {
724f5736e95SDavid du Colombier list_block_type tList;
725f5736e95SDavid du Colombier const ULONG *aulBlockDepot;
726f5736e95SDavid du Colombier UCHAR *aucLfoInfo, *aucLstfInfo, *aucPapx, *aucXString;
727f5736e95SDavid du Colombier ULONG ulBeginLfoInfo, ulBeginLstfInfo, ulBeginLvlfInfo;
728f5736e95SDavid du Colombier ULONG ulListID, ulStart;
729f5736e95SDavid du Colombier size_t tBlockDepotLen, tBlockSize;
730f5736e95SDavid du Colombier size_t tLfoInfoLen, tLstfInfoLen, tPapxLen, tXstLen, tOff;
731f5736e95SDavid du Colombier size_t tLstfRecords, tStart, tIndex;
732f5736e95SDavid du Colombier int iNums;
733*25b329d5SDavid du Colombier USHORT usIstd;
734f5736e95SDavid du Colombier UCHAR ucTmp, ucListLevel, ucMaxLevel, ucChpxLen;
735f5736e95SDavid du Colombier UCHAR aucLvlfInfo[28], aucXst[2];
736f5736e95SDavid du Colombier
737f5736e95SDavid du Colombier fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
738f5736e95SDavid du Colombier fail(aulBBD == NULL || aulSBD == NULL);
739f5736e95SDavid du Colombier
740*25b329d5SDavid du Colombier NO_DBG_DEC(pPPS->tTable.ulSB);
741*25b329d5SDavid du Colombier NO_DBG_HEX(pPPS->tTable.ulSize);
742*25b329d5SDavid du Colombier if (pPPS->tTable.ulSize == 0) {
743f5736e95SDavid du Colombier DBG_MSG("No list information");
744f5736e95SDavid du Colombier return;
745f5736e95SDavid du Colombier }
746*25b329d5SDavid du Colombier
747*25b329d5SDavid du Colombier if (pPPS->tTable.ulSize < MIN_SIZE_FOR_BBD_USE) {
748f5736e95SDavid du Colombier /* Use the Small Block Depot */
749f5736e95SDavid du Colombier aulBlockDepot = aulSBD;
750f5736e95SDavid du Colombier tBlockDepotLen = tSBDLen;
751f5736e95SDavid du Colombier tBlockSize = SMALL_BLOCK_SIZE;
752f5736e95SDavid du Colombier } else {
753f5736e95SDavid du Colombier /* Use the Big Block Depot */
754f5736e95SDavid du Colombier aulBlockDepot = aulBBD;
755f5736e95SDavid du Colombier tBlockDepotLen = tBBDLen;
756f5736e95SDavid du Colombier tBlockSize = BIG_BLOCK_SIZE;
757f5736e95SDavid du Colombier }
758f5736e95SDavid du Colombier
759f5736e95SDavid du Colombier /* LFO (List Format Override) */
760f5736e95SDavid du Colombier ulBeginLfoInfo = ulGetLong(0x2ea, aucHeader); /* fcPlfLfo */
761f5736e95SDavid du Colombier DBG_HEX(ulBeginLfoInfo);
762f5736e95SDavid du Colombier tLfoInfoLen = (size_t)ulGetLong(0x2ee, aucHeader); /* lcbPlfLfo */
763f5736e95SDavid du Colombier DBG_DEC(tLfoInfoLen);
764f5736e95SDavid du Colombier if (tLfoInfoLen == 0) {
765f5736e95SDavid du Colombier DBG_MSG("No lists in this document");
766f5736e95SDavid du Colombier return;
767f5736e95SDavid du Colombier }
768f5736e95SDavid du Colombier
769f5736e95SDavid du Colombier aucLfoInfo = xmalloc(tLfoInfoLen);
770*25b329d5SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
771f5736e95SDavid du Colombier aulBlockDepot, tBlockDepotLen, tBlockSize,
772f5736e95SDavid du Colombier aucLfoInfo, ulBeginLfoInfo, tLfoInfoLen)) {
773f5736e95SDavid du Colombier aucLfoInfo = xfree(aucLfoInfo);
774f5736e95SDavid du Colombier return;
775f5736e95SDavid du Colombier }
776f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucLfoInfo, tLfoInfoLen);
777f5736e95SDavid du Colombier vBuildLfoList(aucLfoInfo, tLfoInfoLen);
778f5736e95SDavid du Colombier aucLfoInfo = xfree(aucLfoInfo);
779f5736e95SDavid du Colombier
780f5736e95SDavid du Colombier /* LSTF (LiST data on File) */
781f5736e95SDavid du Colombier ulBeginLstfInfo = ulGetLong(0x2e2, aucHeader); /* fcPlcfLst */
782f5736e95SDavid du Colombier DBG_HEX(ulBeginLstfInfo);
783f5736e95SDavid du Colombier tLstfInfoLen = (size_t)ulGetLong(0x2e6, aucHeader); /* lcbPlcfLst */
784f5736e95SDavid du Colombier DBG_DEC(tLstfInfoLen);
785f5736e95SDavid du Colombier if (tLstfInfoLen == 0) {
786f5736e95SDavid du Colombier DBG_MSG("No list data on file");
787f5736e95SDavid du Colombier return;
788f5736e95SDavid du Colombier }
789f5736e95SDavid du Colombier
790f5736e95SDavid du Colombier aucLstfInfo = xmalloc(tLstfInfoLen);
791*25b329d5SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
792f5736e95SDavid du Colombier aulBlockDepot, tBlockDepotLen, tBlockSize,
793f5736e95SDavid du Colombier aucLstfInfo, ulBeginLstfInfo, tLstfInfoLen)) {
794f5736e95SDavid du Colombier aucLstfInfo = xfree(aucLstfInfo);
795f5736e95SDavid du Colombier return;
796f5736e95SDavid du Colombier }
797f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucLstfInfo, tLstfInfoLen);
798f5736e95SDavid du Colombier
799f5736e95SDavid du Colombier tLstfRecords = (size_t)usGetWord(0, aucLstfInfo);
800f5736e95SDavid du Colombier if (2 + tLstfRecords * 28 < tLstfInfoLen) {
801f5736e95SDavid du Colombier DBG_DEC(2 + tLstfRecords * 28);
802f5736e95SDavid du Colombier DBG_DEC(tLstfInfoLen);
803f5736e95SDavid du Colombier aucLstfInfo = xfree(aucLstfInfo);
804f5736e95SDavid du Colombier return;
805f5736e95SDavid du Colombier }
806f5736e95SDavid du Colombier
807f5736e95SDavid du Colombier /* LVLF (List leVeL on File) */
808f5736e95SDavid du Colombier ulBeginLvlfInfo = ulBeginLstfInfo + tLstfInfoLen;
809f5736e95SDavid du Colombier DBG_HEX(ulBeginLvlfInfo);
810f5736e95SDavid du Colombier
811f5736e95SDavid du Colombier aucXString = NULL;
812f5736e95SDavid du Colombier ulStart = ulBeginLvlfInfo;
813f5736e95SDavid du Colombier
814f5736e95SDavid du Colombier for (tIndex = 0, tStart = 2;
815f5736e95SDavid du Colombier tIndex < tLstfRecords;
816f5736e95SDavid du Colombier tIndex++, tStart += 28) {
817f5736e95SDavid du Colombier ulListID = ulGetLong(tStart, aucLstfInfo);
818f5736e95SDavid du Colombier NO_DBG_HEX(ulListID);
819f5736e95SDavid du Colombier ucTmp = ucGetByte(tStart + 26, aucLstfInfo);
820f5736e95SDavid du Colombier ucMaxLevel = odd(ucTmp) ? 1 : 9;
821f5736e95SDavid du Colombier for (ucListLevel = 0; ucListLevel < ucMaxLevel; ucListLevel++) {
822f5736e95SDavid du Colombier fail(aucXString != NULL);
823f5736e95SDavid du Colombier usIstd = usGetWord(
824f5736e95SDavid du Colombier tStart + 8 + 2 * (size_t)ucListLevel,
825f5736e95SDavid du Colombier aucLstfInfo);
826f5736e95SDavid du Colombier DBG_DEC_C(usIstd != STI_NIL, usIstd);
827f5736e95SDavid du Colombier NO_DBG_HEX(ulStart);
828f5736e95SDavid du Colombier (void)memset(&tList, 0, sizeof(tList));
829f5736e95SDavid du Colombier /* Read the lvlf (List leVeL on File) */
830*25b329d5SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
831f5736e95SDavid du Colombier aulBlockDepot, tBlockDepotLen,
832f5736e95SDavid du Colombier tBlockSize, aucLvlfInfo,
833f5736e95SDavid du Colombier ulStart, sizeof(aucLvlfInfo))) {
834f5736e95SDavid du Colombier aucLstfInfo = xfree(aucLstfInfo);
835f5736e95SDavid du Colombier return;
836f5736e95SDavid du Colombier }
837f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucLvlfInfo, sizeof(aucLvlfInfo));
838f5736e95SDavid du Colombier if (bAllZero(aucLvlfInfo, sizeof(aucLvlfInfo))) {
839f5736e95SDavid du Colombier tList.ulStartAt = 1;
840f5736e95SDavid du Colombier tList.ucNFC = 0x00;
841f5736e95SDavid du Colombier tList.bNoRestart = FALSE;
842f5736e95SDavid du Colombier } else {
843f5736e95SDavid du Colombier tList.ulStartAt = ulGetLong(0, aucLvlfInfo);
844f5736e95SDavid du Colombier tList.ucNFC = ucGetByte(4, aucLvlfInfo);
845f5736e95SDavid du Colombier ucTmp = ucGetByte(5, aucLvlfInfo);
846f5736e95SDavid du Colombier tList.bNoRestart = (ucTmp & BIT(3)) != 0;
847*25b329d5SDavid du Colombier DBG_MSG_C((ucTmp & BIT(4)) != 0 &&
848*25b329d5SDavid du Colombier (ucTmp & BIT(6)) != 0, "Found one");
849f5736e95SDavid du Colombier }
850f5736e95SDavid du Colombier ulStart += sizeof(aucLvlfInfo);
851f5736e95SDavid du Colombier tPapxLen = (size_t)ucGetByte(25, aucLvlfInfo);
852f5736e95SDavid du Colombier if (tPapxLen != 0) {
853f5736e95SDavid du Colombier aucPapx = xmalloc(tPapxLen);
854f5736e95SDavid du Colombier /* Read the Papx */
855*25b329d5SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
856f5736e95SDavid du Colombier aulBlockDepot, tBlockDepotLen,
857f5736e95SDavid du Colombier tBlockSize, aucPapx,
858f5736e95SDavid du Colombier ulStart, tPapxLen)) {
859f5736e95SDavid du Colombier aucPapx = xfree(aucPapx);
860f5736e95SDavid du Colombier aucLstfInfo = xfree(aucLstfInfo);
861f5736e95SDavid du Colombier return;
862f5736e95SDavid du Colombier }
863f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucPapx, tPapxLen);
864f5736e95SDavid du Colombier tList.sLeftIndent =
865f5736e95SDavid du Colombier sGetLeftIndent(aucPapx, tPapxLen);
866f5736e95SDavid du Colombier aucPapx = xfree(aucPapx);
867f5736e95SDavid du Colombier }
868f5736e95SDavid du Colombier ulStart += tPapxLen;
869f5736e95SDavid du Colombier ucChpxLen = ucGetByte(24, aucLvlfInfo);
870f5736e95SDavid du Colombier ulStart += (ULONG)ucChpxLen;
871f5736e95SDavid du Colombier /* Read the length of the XString */
872*25b329d5SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
873f5736e95SDavid du Colombier aulBlockDepot, tBlockDepotLen,
874f5736e95SDavid du Colombier tBlockSize, aucXst,
875f5736e95SDavid du Colombier ulStart, sizeof(aucXst))) {
876f5736e95SDavid du Colombier aucLstfInfo = xfree(aucLstfInfo);
877f5736e95SDavid du Colombier return;
878f5736e95SDavid du Colombier }
879f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucXst, sizeof(aucXst));
880f5736e95SDavid du Colombier tXstLen = (size_t)usGetWord(0, aucXst);
881f5736e95SDavid du Colombier ulStart += sizeof(aucXst);
882f5736e95SDavid du Colombier if (tXstLen == 0) {
883f5736e95SDavid du Colombier tList.usListChar = DEFAULT_LISTCHAR;
884f5736e95SDavid du Colombier vAdd2ListInfoList(ulListID,
885f5736e95SDavid du Colombier usIstd,
886f5736e95SDavid du Colombier ucListLevel,
887f5736e95SDavid du Colombier &tList);
888f5736e95SDavid du Colombier continue;
889f5736e95SDavid du Colombier }
890f5736e95SDavid du Colombier tXstLen *= 2; /* Length in chars to length in bytes */
891f5736e95SDavid du Colombier aucXString = xmalloc(tXstLen);
892f5736e95SDavid du Colombier /* Read the XString */
893*25b329d5SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tTable.ulSB,
894f5736e95SDavid du Colombier aulBlockDepot, tBlockDepotLen,
895f5736e95SDavid du Colombier tBlockSize, aucXString,
896f5736e95SDavid du Colombier ulStart, tXstLen)) {
897f5736e95SDavid du Colombier aucXString = xfree(aucXString);
898f5736e95SDavid du Colombier aucLstfInfo = xfree(aucLstfInfo);
899f5736e95SDavid du Colombier return;
900f5736e95SDavid du Colombier }
901f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucXString, tXstLen);
902f5736e95SDavid du Colombier tOff = 0;
903f5736e95SDavid du Colombier for (iNums = 6; iNums < 15; iNums++) {
904f5736e95SDavid du Colombier ucTmp = ucGetByte(iNums, aucLvlfInfo);
905f5736e95SDavid du Colombier if (ucTmp == 0) {
906f5736e95SDavid du Colombier break;
907f5736e95SDavid du Colombier }
908f5736e95SDavid du Colombier tOff = (size_t)ucTmp;
909f5736e95SDavid du Colombier }
910f5736e95SDavid du Colombier tOff *= 2; /* Offset in chars to offset in bytes */
911f5736e95SDavid du Colombier NO_DBG_DEC(tOff);
912f5736e95SDavid du Colombier if (tList.ucNFC == LIST_SPECIAL ||
913*25b329d5SDavid du Colombier tList.ucNFC == LIST_SPECIAL2 ||
914f5736e95SDavid du Colombier tList.ucNFC == LIST_BULLETS) {
915f5736e95SDavid du Colombier tList.usListChar = usGetWord(0, aucXString);
916f5736e95SDavid du Colombier } else if (tOff != 0 && tOff < tXstLen) {
917f5736e95SDavid du Colombier tList.usListChar = usGetWord(tOff, aucXString);
918f5736e95SDavid du Colombier } else {
919f5736e95SDavid du Colombier tList.usListChar = DEFAULT_LISTCHAR;
920f5736e95SDavid du Colombier }
921f5736e95SDavid du Colombier vAdd2ListInfoList(ulListID,
922f5736e95SDavid du Colombier usIstd,
923f5736e95SDavid du Colombier ucListLevel,
924f5736e95SDavid du Colombier &tList);
925f5736e95SDavid du Colombier ulStart += tXstLen;
926f5736e95SDavid du Colombier aucXString = xfree(aucXString);
927f5736e95SDavid du Colombier }
928f5736e95SDavid du Colombier }
929f5736e95SDavid du Colombier aucLstfInfo = xfree(aucLstfInfo);
930f5736e95SDavid du Colombier } /* end of vGet8LstInfo */
931f5736e95SDavid du Colombier
932f5736e95SDavid du Colombier /*
933*25b329d5SDavid du Colombier * Build the lists with Paragraph Information for Word 8/9/10/11 files
934f5736e95SDavid du Colombier */
935f5736e95SDavid du Colombier void
vGet8PapInfo(FILE * pFile,const pps_info_type * pPPS,const ULONG * aulBBD,size_t tBBDLen,const ULONG * aulSBD,size_t tSBDLen,const UCHAR * aucHeader)936f5736e95SDavid du Colombier vGet8PapInfo(FILE *pFile, const pps_info_type *pPPS,
937f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
938f5736e95SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
939f5736e95SDavid du Colombier const UCHAR *aucHeader)
940f5736e95SDavid du Colombier {
941f5736e95SDavid du Colombier row_block_type tRow;
942f5736e95SDavid du Colombier style_block_type tStyle;
943f5736e95SDavid du Colombier ULONG *aulParfPage;
944f5736e95SDavid du Colombier UCHAR *aucBuffer;
945f5736e95SDavid du Colombier ULONG ulCharPos, ulCharPosFirst, ulCharPosLast;
946f5736e95SDavid du Colombier ULONG ulBeginParfInfo;
947*25b329d5SDavid du Colombier size_t tParfInfoLen, tOffset, tLen;
948f5736e95SDavid du Colombier int iIndex, iIndex2, iRun, iFodo, iLen;
949f5736e95SDavid du Colombier row_info_enum eRowInfo;
950*25b329d5SDavid du Colombier USHORT usIstd;
951f5736e95SDavid du Colombier UCHAR aucFpage[BIG_BLOCK_SIZE];
952f5736e95SDavid du Colombier
953f5736e95SDavid du Colombier fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
954f5736e95SDavid du Colombier fail(aulBBD == NULL || aulSBD == NULL);
955f5736e95SDavid du Colombier
956f5736e95SDavid du Colombier ulBeginParfInfo = ulGetLong(0x102, aucHeader); /* fcPlcfbtePapx */
957f5736e95SDavid du Colombier NO_DBG_HEX(ulBeginParfInfo);
958f5736e95SDavid du Colombier tParfInfoLen = (size_t)ulGetLong(0x106, aucHeader); /* lcbPlcfbtePapx */
959f5736e95SDavid du Colombier NO_DBG_DEC(tParfInfoLen);
960f5736e95SDavid du Colombier if (tParfInfoLen < 4) {
961f5736e95SDavid du Colombier DBG_DEC(tParfInfoLen);
962f5736e95SDavid du Colombier return;
963f5736e95SDavid du Colombier }
964f5736e95SDavid du Colombier
965*25b329d5SDavid du Colombier aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable,
966*25b329d5SDavid du Colombier aulBBD, tBBDLen, aulSBD, tSBDLen,
967*25b329d5SDavid du Colombier ulBeginParfInfo, tParfInfoLen);
968*25b329d5SDavid du Colombier if (aucBuffer == NULL) {
969f5736e95SDavid du Colombier return;
970f5736e95SDavid du Colombier }
971f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucBuffer, tParfInfoLen);
972f5736e95SDavid du Colombier
973f5736e95SDavid du Colombier tLen = (tParfInfoLen / 4 - 1) / 2;
974f5736e95SDavid du Colombier aulParfPage = xcalloc(tLen, sizeof(ULONG));
975f5736e95SDavid du Colombier for (iIndex = 0, tOffset = (tLen + 1) * 4;
976f5736e95SDavid du Colombier iIndex < (int)tLen;
977f5736e95SDavid du Colombier iIndex++, tOffset += 4) {
978f5736e95SDavid du Colombier aulParfPage[iIndex] = ulGetLong(tOffset, aucBuffer);
979f5736e95SDavid du Colombier NO_DBG_DEC(aulParfPage[iIndex]);
980f5736e95SDavid du Colombier }
981f5736e95SDavid du Colombier DBG_HEX(ulGetLong(0, aucBuffer));
982f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
983f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucHeader, HEADER_SIZE);
984f5736e95SDavid du Colombier
985f5736e95SDavid du Colombier (void)memset(&tRow, 0, sizeof(tRow));
986f5736e95SDavid du Colombier ulCharPosFirst = CP_INVALID;
987f5736e95SDavid du Colombier for (iIndex = 0; iIndex < (int)tLen; iIndex++) {
988f5736e95SDavid du Colombier fail(aulParfPage[iIndex] > ULONG_MAX / BIG_BLOCK_SIZE);
989f5736e95SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB,
990f5736e95SDavid du Colombier aulBBD, tBBDLen, BIG_BLOCK_SIZE,
991f5736e95SDavid du Colombier aucFpage,
992f5736e95SDavid du Colombier aulParfPage[iIndex] * BIG_BLOCK_SIZE,
993f5736e95SDavid du Colombier BIG_BLOCK_SIZE)) {
994f5736e95SDavid du Colombier break;
995f5736e95SDavid du Colombier }
996f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE);
997f5736e95SDavid du Colombier iRun = (int)ucGetByte(0x1ff, aucFpage);
998f5736e95SDavid du Colombier NO_DBG_DEC(iRun);
999f5736e95SDavid du Colombier for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) {
1000f5736e95SDavid du Colombier NO_DBG_HEX(ulGetLong(iIndex2 * 4, aucFpage));
1001f5736e95SDavid du Colombier iFodo = 2 * (int)ucGetByte(
1002f5736e95SDavid du Colombier (iRun + 1) * 4 + iIndex2 * 13, aucFpage);
1003f5736e95SDavid du Colombier if (iFodo <= 0) {
1004f5736e95SDavid du Colombier continue;
1005f5736e95SDavid du Colombier }
1006f5736e95SDavid du Colombier
1007f5736e95SDavid du Colombier iLen = 2 * (int)ucGetByte(iFodo, aucFpage);
1008f5736e95SDavid du Colombier if (iLen == 0) {
1009f5736e95SDavid du Colombier iFodo++;
1010f5736e95SDavid du Colombier iLen = 2 * (int)ucGetByte(iFodo, aucFpage);
1011f5736e95SDavid du Colombier }
1012f5736e95SDavid du Colombier
1013f5736e95SDavid du Colombier usIstd = usGetWord(iFodo + 1, aucFpage);
1014f5736e95SDavid du Colombier vFillStyleFromStylesheet(usIstd, &tStyle);
1015f5736e95SDavid du Colombier vGet8StyleInfo(iFodo, aucFpage + 3, iLen - 3, &tStyle);
1016f5736e95SDavid du Colombier ulCharPos = ulGetLong(iIndex2 * 4, aucFpage);
1017f5736e95SDavid du Colombier NO_DBG_HEX(ulCharPos);
1018*25b329d5SDavid du Colombier tStyle.ulFileOffset = ulCharPos2FileOffsetX(
1019*25b329d5SDavid du Colombier ulCharPos, &tStyle.eListID);
1020f5736e95SDavid du Colombier vAdd2StyleInfoList(&tStyle);
1021f5736e95SDavid du Colombier
1022f5736e95SDavid du Colombier eRowInfo = eGet8RowInfo(iFodo,
1023f5736e95SDavid du Colombier aucFpage + 3, iLen - 3, &tRow);
1024f5736e95SDavid du Colombier switch (eRowInfo) {
1025f5736e95SDavid du Colombier case found_a_cell:
1026f5736e95SDavid du Colombier if (ulCharPosFirst != CP_INVALID) {
1027f5736e95SDavid du Colombier break;
1028f5736e95SDavid du Colombier }
1029f5736e95SDavid du Colombier ulCharPosFirst = ulGetLong(
1030f5736e95SDavid du Colombier iIndex2 * 4, aucFpage);
1031f5736e95SDavid du Colombier NO_DBG_HEX(ulCharPosFirst);
1032f5736e95SDavid du Colombier tRow.ulCharPosStart = ulCharPosFirst;
1033f5736e95SDavid du Colombier tRow.ulFileOffsetStart =
1034f5736e95SDavid du Colombier ulCharPos2FileOffset(ulCharPosFirst);
1035f5736e95SDavid du Colombier NO_DBG_HEX_C(
1036f5736e95SDavid du Colombier tRow.ulFileOffsetStart == FC_INVALID,
1037f5736e95SDavid du Colombier ulCharPosFirst);
1038f5736e95SDavid du Colombier break;
1039f5736e95SDavid du Colombier case found_end_of_row:
1040f5736e95SDavid du Colombier ulCharPosLast = ulGetLong(
1041f5736e95SDavid du Colombier iIndex2 * 4, aucFpage);
1042f5736e95SDavid du Colombier NO_DBG_HEX(ulCharPosLast);
1043f5736e95SDavid du Colombier tRow.ulCharPosEnd = ulCharPosLast;
1044f5736e95SDavid du Colombier tRow.ulFileOffsetEnd =
1045f5736e95SDavid du Colombier ulCharPos2FileOffset(ulCharPosLast);
1046f5736e95SDavid du Colombier NO_DBG_HEX_C(tRow.ulFileOffsetEnd == FC_INVALID,
1047f5736e95SDavid du Colombier ulCharPosLast);
1048f5736e95SDavid du Colombier vAdd2RowInfoList(&tRow);
1049f5736e95SDavid du Colombier (void)memset(&tRow, 0, sizeof(tRow));
1050f5736e95SDavid du Colombier ulCharPosFirst = CP_INVALID;
1051f5736e95SDavid du Colombier break;
1052f5736e95SDavid du Colombier case found_nothing:
1053f5736e95SDavid du Colombier break;
1054f5736e95SDavid du Colombier default:
1055f5736e95SDavid du Colombier DBG_DEC(eRowInfo);
1056f5736e95SDavid du Colombier break;
1057f5736e95SDavid du Colombier }
1058f5736e95SDavid du Colombier }
1059f5736e95SDavid du Colombier }
1060f5736e95SDavid du Colombier aulParfPage = xfree(aulParfPage);
1061f5736e95SDavid du Colombier } /* end of vGet8PapInfo */
1062f5736e95SDavid du Colombier
1063f5736e95SDavid du Colombier /*
1064f5736e95SDavid du Colombier * Fill the font information block with information
1065*25b329d5SDavid du Colombier * from a Word 8/9/10/11 file.
1066f5736e95SDavid du Colombier */
1067f5736e95SDavid du Colombier void
vGet8FontInfo(int iFodo,USHORT usIstd,const UCHAR * aucGrpprl,int iBytes,font_block_type * pFont)1068f5736e95SDavid du Colombier vGet8FontInfo(int iFodo, USHORT usIstd,
1069f5736e95SDavid du Colombier const UCHAR *aucGrpprl, int iBytes, font_block_type *pFont)
1070f5736e95SDavid du Colombier {
1071f5736e95SDavid du Colombier long lTmp;
1072f5736e95SDavid du Colombier int iFodoOff, iInfoLen;
1073*25b329d5SDavid du Colombier USHORT usFtc0, usFtc1, usFtc2, usTmp;
1074f5736e95SDavid du Colombier UCHAR ucTmp;
1075f5736e95SDavid du Colombier
1076f5736e95SDavid du Colombier fail(iFodo < 0 || aucGrpprl == NULL || pFont == NULL);
1077f5736e95SDavid du Colombier
1078*25b329d5SDavid du Colombier usFtc0 = USHRT_MAX;
1079*25b329d5SDavid du Colombier usFtc1 = USHRT_MAX;
1080*25b329d5SDavid du Colombier usFtc2 = USHRT_MAX;
1081*25b329d5SDavid du Colombier
1082f5736e95SDavid du Colombier iFodoOff = 0;
1083f5736e95SDavid du Colombier while (iBytes >= iFodoOff + 2) {
1084f5736e95SDavid du Colombier switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) {
1085f5736e95SDavid du Colombier case 0x0800: /* fRMarkDel */
1086f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1087f5736e95SDavid du Colombier if (ucTmp == 0) {
1088f5736e95SDavid du Colombier pFont->usFontStyle &= ~FONT_MARKDEL;
1089f5736e95SDavid du Colombier } else {
1090f5736e95SDavid du Colombier pFont->usFontStyle |= FONT_MARKDEL;
1091f5736e95SDavid du Colombier }
1092f5736e95SDavid du Colombier break;
1093f5736e95SDavid du Colombier case 0x0835: /* fBold */
1094f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1095f5736e95SDavid du Colombier switch (ucTmp) {
1096f5736e95SDavid du Colombier case 0: /* Unset */
1097f5736e95SDavid du Colombier pFont->usFontStyle &= ~FONT_BOLD;
1098f5736e95SDavid du Colombier break;
1099f5736e95SDavid du Colombier case 1: /* Set */
1100f5736e95SDavid du Colombier pFont->usFontStyle |= FONT_BOLD;
1101f5736e95SDavid du Colombier break;
1102f5736e95SDavid du Colombier case 128: /* Unchanged */
1103f5736e95SDavid du Colombier break;
1104f5736e95SDavid du Colombier case 129: /* Negation */
1105f5736e95SDavid du Colombier pFont->usFontStyle ^= FONT_BOLD;
1106f5736e95SDavid du Colombier break;
1107f5736e95SDavid du Colombier default:
1108f5736e95SDavid du Colombier DBG_DEC(ucTmp);
1109f5736e95SDavid du Colombier DBG_FIXME();
1110f5736e95SDavid du Colombier break;
1111f5736e95SDavid du Colombier }
1112f5736e95SDavid du Colombier break;
1113f5736e95SDavid du Colombier case 0x0836: /* fItalic */
1114f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1115f5736e95SDavid du Colombier switch (ucTmp) {
1116f5736e95SDavid du Colombier case 0: /* Unset */
1117f5736e95SDavid du Colombier pFont->usFontStyle &= ~FONT_ITALIC;
1118f5736e95SDavid du Colombier break;
1119f5736e95SDavid du Colombier case 1: /* Set */
1120f5736e95SDavid du Colombier pFont->usFontStyle |= FONT_ITALIC;
1121f5736e95SDavid du Colombier break;
1122f5736e95SDavid du Colombier case 128: /* Unchanged */
1123f5736e95SDavid du Colombier break;
1124f5736e95SDavid du Colombier case 129: /* Negation */
1125f5736e95SDavid du Colombier pFont->usFontStyle ^= FONT_ITALIC;
1126f5736e95SDavid du Colombier break;
1127f5736e95SDavid du Colombier default:
1128f5736e95SDavid du Colombier DBG_DEC(ucTmp);
1129f5736e95SDavid du Colombier DBG_FIXME();
1130f5736e95SDavid du Colombier break;
1131f5736e95SDavid du Colombier }
1132f5736e95SDavid du Colombier break;
1133f5736e95SDavid du Colombier case 0x0837: /* fStrike */
1134f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1135f5736e95SDavid du Colombier switch (ucTmp) {
1136f5736e95SDavid du Colombier case 0: /* Unset */
1137f5736e95SDavid du Colombier pFont->usFontStyle &= ~FONT_STRIKE;
1138f5736e95SDavid du Colombier break;
1139f5736e95SDavid du Colombier case 1: /* Set */
1140f5736e95SDavid du Colombier pFont->usFontStyle |= FONT_STRIKE;
1141f5736e95SDavid du Colombier break;
1142f5736e95SDavid du Colombier case 128: /* Unchanged */
1143f5736e95SDavid du Colombier break;
1144f5736e95SDavid du Colombier case 129: /* Negation */
1145f5736e95SDavid du Colombier pFont->usFontStyle ^= FONT_STRIKE;
1146f5736e95SDavid du Colombier break;
1147f5736e95SDavid du Colombier default:
1148f5736e95SDavid du Colombier DBG_DEC(ucTmp);
1149f5736e95SDavid du Colombier DBG_FIXME();
1150f5736e95SDavid du Colombier break;
1151f5736e95SDavid du Colombier }
1152f5736e95SDavid du Colombier break;
1153f5736e95SDavid du Colombier case 0x083a: /* fSmallCaps */
1154f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1155f5736e95SDavid du Colombier switch (ucTmp) {
1156f5736e95SDavid du Colombier case 0: /* Unset */
1157f5736e95SDavid du Colombier pFont->usFontStyle &= ~FONT_SMALL_CAPITALS;
1158f5736e95SDavid du Colombier break;
1159f5736e95SDavid du Colombier case 1: /* Set */
1160f5736e95SDavid du Colombier pFont->usFontStyle |= FONT_SMALL_CAPITALS;
1161f5736e95SDavid du Colombier break;
1162f5736e95SDavid du Colombier case 128: /* Unchanged */
1163f5736e95SDavid du Colombier break;
1164f5736e95SDavid du Colombier case 129: /* Negation */
1165f5736e95SDavid du Colombier pFont->usFontStyle ^= FONT_SMALL_CAPITALS;
1166f5736e95SDavid du Colombier break;
1167f5736e95SDavid du Colombier default:
1168f5736e95SDavid du Colombier DBG_DEC(ucTmp);
1169f5736e95SDavid du Colombier DBG_FIXME();
1170f5736e95SDavid du Colombier break;
1171f5736e95SDavid du Colombier }
1172f5736e95SDavid du Colombier break;
1173f5736e95SDavid du Colombier case 0x083b: /* fCaps */
1174f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1175f5736e95SDavid du Colombier switch (ucTmp) {
1176f5736e95SDavid du Colombier case 0: /* Unset */
1177f5736e95SDavid du Colombier pFont->usFontStyle &= ~FONT_CAPITALS;
1178f5736e95SDavid du Colombier break;
1179f5736e95SDavid du Colombier case 1: /* Set */
1180f5736e95SDavid du Colombier pFont->usFontStyle |= FONT_CAPITALS;
1181f5736e95SDavid du Colombier break;
1182f5736e95SDavid du Colombier case 128: /* Unchanged */
1183f5736e95SDavid du Colombier break;
1184f5736e95SDavid du Colombier case 129: /* Negation */
1185f5736e95SDavid du Colombier pFont->usFontStyle ^= FONT_CAPITALS;
1186f5736e95SDavid du Colombier break;
1187f5736e95SDavid du Colombier default:
1188f5736e95SDavid du Colombier DBG_DEC(ucTmp);
1189f5736e95SDavid du Colombier DBG_FIXME();
1190f5736e95SDavid du Colombier break;
1191f5736e95SDavid du Colombier }
1192f5736e95SDavid du Colombier break;
1193f5736e95SDavid du Colombier case 0x083c: /* fVanish */
1194f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1195f5736e95SDavid du Colombier switch (ucTmp) {
1196f5736e95SDavid du Colombier case 0: /* Unset */
1197f5736e95SDavid du Colombier pFont->usFontStyle &= ~FONT_HIDDEN;
1198f5736e95SDavid du Colombier break;
1199f5736e95SDavid du Colombier case 1: /* Set */
1200f5736e95SDavid du Colombier pFont->usFontStyle |= FONT_HIDDEN;
1201f5736e95SDavid du Colombier break;
1202f5736e95SDavid du Colombier case 128: /* Unchanged */
1203f5736e95SDavid du Colombier break;
1204f5736e95SDavid du Colombier case 129: /* Negation */
1205f5736e95SDavid du Colombier pFont->usFontStyle ^= FONT_HIDDEN;
1206f5736e95SDavid du Colombier break;
1207f5736e95SDavid du Colombier default:
1208f5736e95SDavid du Colombier DBG_DEC(ucTmp);
1209f5736e95SDavid du Colombier DBG_FIXME();
1210f5736e95SDavid du Colombier break;
1211f5736e95SDavid du Colombier }
1212f5736e95SDavid du Colombier break;
1213f5736e95SDavid du Colombier case 0x2a32: /* cDefault */
1214f5736e95SDavid du Colombier pFont->usFontStyle &= FONT_HIDDEN;
1215f5736e95SDavid du Colombier pFont->ucFontColor = FONT_COLOR_DEFAULT;
1216f5736e95SDavid du Colombier break;
1217f5736e95SDavid du Colombier case 0x2a33: /* cPlain */
1218f5736e95SDavid du Colombier DBG_MSG("2a33: cPlain");
1219f5736e95SDavid du Colombier vFillFontFromStylesheet(usIstd, pFont);
1220f5736e95SDavid du Colombier break;
1221f5736e95SDavid du Colombier case 0x2a3e: /* cKul */
1222f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1223f5736e95SDavid du Colombier if (ucTmp == 0 || ucTmp == 5) {
1224f5736e95SDavid du Colombier pFont->usFontStyle &= ~FONT_UNDERLINE;
1225f5736e95SDavid du Colombier } else {
1226f5736e95SDavid du Colombier NO_DBG_MSG("Underline text");
1227f5736e95SDavid du Colombier pFont->usFontStyle |= FONT_UNDERLINE;
1228f5736e95SDavid du Colombier if (ucTmp == 6) {
1229f5736e95SDavid du Colombier DBG_MSG("Bold text");
1230f5736e95SDavid du Colombier pFont->usFontStyle |= FONT_BOLD;
1231f5736e95SDavid du Colombier }
1232f5736e95SDavid du Colombier }
1233f5736e95SDavid du Colombier break;
1234f5736e95SDavid du Colombier case 0x2a42: /* cIco */
1235f5736e95SDavid du Colombier pFont->ucFontColor =
1236f5736e95SDavid du Colombier ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1237f5736e95SDavid du Colombier NO_DBG_DEC(pFont->ucFontColor);
1238f5736e95SDavid du Colombier break;
1239*25b329d5SDavid du Colombier case 0x2a44: /* cHpsInc */
1240*25b329d5SDavid du Colombier DBG_MSG("0x2a44: sprmCHpsInc");
1241*25b329d5SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1242*25b329d5SDavid du Colombier DBG_DEC(ucTmp);
1243*25b329d5SDavid du Colombier break;
1244f5736e95SDavid du Colombier case 0x2a48: /* cIss */
1245f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1246f5736e95SDavid du Colombier ucTmp &= 0x07;
1247f5736e95SDavid du Colombier if (ucTmp == 1) {
1248f5736e95SDavid du Colombier pFont->usFontStyle |= FONT_SUPERSCRIPT;
1249f5736e95SDavid du Colombier NO_DBG_MSG("Superscript");
1250f5736e95SDavid du Colombier } else if (ucTmp == 2) {
1251f5736e95SDavid du Colombier pFont->usFontStyle |= FONT_SUBSCRIPT;
1252f5736e95SDavid du Colombier NO_DBG_MSG("Subscript");
1253f5736e95SDavid du Colombier }
1254f5736e95SDavid du Colombier break;
1255f5736e95SDavid du Colombier case 0x4a30: /* cIstd */
1256f5736e95SDavid du Colombier usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
1257f5736e95SDavid du Colombier NO_DBG_DEC(usTmp);
1258f5736e95SDavid du Colombier break;
1259f5736e95SDavid du Colombier case 0x4a43: /* cHps */
1260f5736e95SDavid du Colombier pFont->usFontSize =
1261f5736e95SDavid du Colombier usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
1262f5736e95SDavid du Colombier NO_DBG_DEC(pFont->usFontSize);
1263f5736e95SDavid du Colombier break;
1264*25b329d5SDavid du Colombier case 0x4a4d: /* cHpsMul */
1265*25b329d5SDavid du Colombier DBG_MSG("0x4a4d: sprmCHpsMul");
1266f5736e95SDavid du Colombier usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
1267*25b329d5SDavid du Colombier DBG_DEC(usTmp);
1268f5736e95SDavid du Colombier break;
1269*25b329d5SDavid du Colombier case 0x4a4f: /* cFtc0 */
1270*25b329d5SDavid du Colombier usFtc0 = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
1271*25b329d5SDavid du Colombier break;
1272*25b329d5SDavid du Colombier case 0x4a50: /* cFtc1 */
1273*25b329d5SDavid du Colombier usFtc1 = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
1274*25b329d5SDavid du Colombier break;
1275*25b329d5SDavid du Colombier case 0x4a51: /* cFtc2 */
1276*25b329d5SDavid du Colombier usFtc2 = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
1277*25b329d5SDavid du Colombier break;
1278*25b329d5SDavid du Colombier case 0xca47: /* cMajority */
1279*25b329d5SDavid du Colombier DBG_MSG("0xca47: sprmCMajority");
1280*25b329d5SDavid du Colombier break;
1281*25b329d5SDavid du Colombier case 0xca4a: /* cHpsInc1 */
1282f5736e95SDavid du Colombier usTmp = usGetWord(iFodo + iFodoOff + 2, aucGrpprl);
1283f5736e95SDavid du Colombier lTmp = (long)pFont->usFontSize + (long)usTmp;
1284f5736e95SDavid du Colombier if (lTmp < 8) {
1285f5736e95SDavid du Colombier pFont->usFontSize = 8;
1286f5736e95SDavid du Colombier } else if (lTmp > 32766) {
1287f5736e95SDavid du Colombier pFont->usFontSize = 32766;
1288f5736e95SDavid du Colombier } else {
1289f5736e95SDavid du Colombier pFont->usFontSize = (USHORT)lTmp;
1290f5736e95SDavid du Colombier }
1291f5736e95SDavid du Colombier break;
1292*25b329d5SDavid du Colombier case 0xca4c: /* cMajority50 */
1293*25b329d5SDavid du Colombier DBG_MSG("0xca4c: sprmCMajority50");
1294*25b329d5SDavid du Colombier break;
1295f5736e95SDavid du Colombier case 0xea3f: /* cHps, cHpsPos */
1296f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1297*25b329d5SDavid du Colombier DBG_DEC(ucTmp);
1298f5736e95SDavid du Colombier if (ucTmp != 0) {
1299f5736e95SDavid du Colombier pFont->usFontSize = (USHORT)ucTmp;
1300f5736e95SDavid du Colombier }
1301*25b329d5SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 3, aucGrpprl);
1302f5736e95SDavid du Colombier DBG_DEC(ucTmp);
1303f5736e95SDavid du Colombier break;
1304f5736e95SDavid du Colombier default:
1305f5736e95SDavid du Colombier break;
1306f5736e95SDavid du Colombier }
1307f5736e95SDavid du Colombier iInfoLen = iGet8InfoLength(iFodo + iFodoOff, aucGrpprl);
1308f5736e95SDavid du Colombier fail(iInfoLen <= 0);
1309f5736e95SDavid du Colombier iFodoOff += iInfoLen;
1310f5736e95SDavid du Colombier }
1311*25b329d5SDavid du Colombier
1312*25b329d5SDavid du Colombier /* Combine the Ftc's to a FontNumber */
1313*25b329d5SDavid du Colombier NO_DBG_DEC_C(usFtc0 != USHRT_MAX, usFtc0);
1314*25b329d5SDavid du Colombier NO_DBG_DEC_C(usFtc2 != USHRT_MAX, usFtc2);
1315*25b329d5SDavid du Colombier NO_DBG_DEC_C(usFtc1 != USHRT_MAX, usFtc1);
1316*25b329d5SDavid du Colombier if (usFtc0 <= 0x7fff) {
1317*25b329d5SDavid du Colombier if (usFtc0 <= (USHORT)UCHAR_MAX) {
1318*25b329d5SDavid du Colombier pFont->ucFontNumber = (UCHAR)usFtc0;
1319*25b329d5SDavid du Colombier } else {
1320*25b329d5SDavid du Colombier DBG_DEC(usFtc0);
1321*25b329d5SDavid du Colombier DBG_FIXME();
1322*25b329d5SDavid du Colombier pFont->ucFontNumber = 0;
1323*25b329d5SDavid du Colombier }
1324*25b329d5SDavid du Colombier } else if (usFtc2 <= 0x7fff) {
1325*25b329d5SDavid du Colombier if (usFtc2 <= (USHORT)UCHAR_MAX) {
1326*25b329d5SDavid du Colombier pFont->ucFontNumber = (UCHAR)usFtc2;
1327*25b329d5SDavid du Colombier } else {
1328*25b329d5SDavid du Colombier DBG_DEC(usFtc2);
1329*25b329d5SDavid du Colombier DBG_FIXME();
1330*25b329d5SDavid du Colombier pFont->ucFontNumber = 0;
1331*25b329d5SDavid du Colombier }
1332*25b329d5SDavid du Colombier } else if (usFtc1 <= 0x7fff) {
1333*25b329d5SDavid du Colombier if (usFtc1 <= (USHORT)UCHAR_MAX) {
1334*25b329d5SDavid du Colombier pFont->ucFontNumber = (UCHAR)usFtc1;
1335*25b329d5SDavid du Colombier } else {
1336*25b329d5SDavid du Colombier DBG_DEC(usFtc1);
1337*25b329d5SDavid du Colombier DBG_FIXME();
1338*25b329d5SDavid du Colombier pFont->ucFontNumber = 0;
1339*25b329d5SDavid du Colombier }
1340*25b329d5SDavid du Colombier }
1341f5736e95SDavid du Colombier } /* end of vGet8FontInfo */
1342f5736e95SDavid du Colombier
1343f5736e95SDavid du Colombier /*
1344f5736e95SDavid du Colombier * Fill the picture information block with information
1345*25b329d5SDavid du Colombier * from a Word 8/9/10/11 file.
1346f5736e95SDavid du Colombier * Returns TRUE when successful, otherwise FALSE
1347f5736e95SDavid du Colombier */
1348f5736e95SDavid du Colombier static BOOL
bGet8PicInfo(int iFodo,const UCHAR * aucGrpprl,int iBytes,picture_block_type * pPicture)1349f5736e95SDavid du Colombier bGet8PicInfo(int iFodo,
1350f5736e95SDavid du Colombier const UCHAR *aucGrpprl, int iBytes, picture_block_type *pPicture)
1351f5736e95SDavid du Colombier {
1352*25b329d5SDavid du Colombier ULONG ulTmp;
1353f5736e95SDavid du Colombier int iFodoOff, iInfoLen;
1354f5736e95SDavid du Colombier BOOL bFound;
1355f5736e95SDavid du Colombier UCHAR ucTmp;
1356f5736e95SDavid du Colombier
1357f5736e95SDavid du Colombier fail(iFodo <= 0 || aucGrpprl == NULL || pPicture == NULL);
1358f5736e95SDavid du Colombier
1359f5736e95SDavid du Colombier iFodoOff = 0;
1360f5736e95SDavid du Colombier bFound = FALSE;
1361f5736e95SDavid du Colombier while (iBytes >= iFodoOff + 2) {
1362f5736e95SDavid du Colombier switch (usGetWord(iFodo + iFodoOff, aucGrpprl)) {
1363*25b329d5SDavid du Colombier #if 0
1364f5736e95SDavid du Colombier case 0x0806: /* fData */
1365f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1366f5736e95SDavid du Colombier if (ucTmp == 0x01) {
1367f5736e95SDavid du Colombier /* Not a picture, but a form field */
1368f5736e95SDavid du Colombier return FALSE;
1369f5736e95SDavid du Colombier }
1370f5736e95SDavid du Colombier DBG_DEC_C(ucTmp != 0, ucTmp);
1371f5736e95SDavid du Colombier break;
1372*25b329d5SDavid du Colombier #endif
1373f5736e95SDavid du Colombier case 0x080a: /* fOle2 */
1374f5736e95SDavid du Colombier ucTmp = ucGetByte(iFodo + iFodoOff + 2, aucGrpprl);
1375f5736e95SDavid du Colombier if (ucTmp == 0x01) {
1376f5736e95SDavid du Colombier /* Not a picture, but an OLE object */
1377f5736e95SDavid du Colombier return FALSE;
1378f5736e95SDavid du Colombier }
1379f5736e95SDavid du Colombier DBG_DEC_C(ucTmp != 0, ucTmp);
1380f5736e95SDavid du Colombier break;
1381*25b329d5SDavid du Colombier case 0x680e: /* fcObj */
1382*25b329d5SDavid du Colombier ulTmp = ulGetLong(iFodo + iFodoOff + 2, aucGrpprl);
1383*25b329d5SDavid du Colombier DBG_HEX(ulTmp);
1384*25b329d5SDavid du Colombier break;
1385f5736e95SDavid du Colombier case 0x6a03: /* fcPic */
1386f5736e95SDavid du Colombier pPicture->ulPictureOffset = ulGetLong(
1387f5736e95SDavid du Colombier iFodo + iFodoOff + 2, aucGrpprl);
1388f5736e95SDavid du Colombier bFound = TRUE;
1389f5736e95SDavid du Colombier break;
1390f5736e95SDavid du Colombier default:
1391f5736e95SDavid du Colombier break;
1392f5736e95SDavid du Colombier }
1393f5736e95SDavid du Colombier iInfoLen = iGet8InfoLength(iFodo + iFodoOff, aucGrpprl);
1394f5736e95SDavid du Colombier fail(iInfoLen <= 0);
1395f5736e95SDavid du Colombier iFodoOff += iInfoLen;
1396f5736e95SDavid du Colombier }
1397f5736e95SDavid du Colombier return bFound;
1398f5736e95SDavid du Colombier } /* end of bGet8PicInfo */
1399f5736e95SDavid du Colombier
1400f5736e95SDavid du Colombier /*
1401*25b329d5SDavid du Colombier * Build the lists with Character Information for Word 8/9/10/11 files
1402f5736e95SDavid du Colombier */
1403f5736e95SDavid du Colombier void
vGet8ChrInfo(FILE * pFile,const pps_info_type * pPPS,const ULONG * aulBBD,size_t tBBDLen,const ULONG * aulSBD,size_t tSBDLen,const UCHAR * aucHeader)1404f5736e95SDavid du Colombier vGet8ChrInfo(FILE *pFile, const pps_info_type *pPPS,
1405f5736e95SDavid du Colombier const ULONG *aulBBD, size_t tBBDLen,
1406f5736e95SDavid du Colombier const ULONG *aulSBD, size_t tSBDLen,
1407f5736e95SDavid du Colombier const UCHAR *aucHeader)
1408f5736e95SDavid du Colombier {
1409f5736e95SDavid du Colombier font_block_type tFont;
1410f5736e95SDavid du Colombier picture_block_type tPicture;
1411f5736e95SDavid du Colombier ULONG *aulCharPage;
1412f5736e95SDavid du Colombier UCHAR *aucBuffer;
1413f5736e95SDavid du Colombier ULONG ulFileOffset, ulCharPos, ulBeginCharInfo;
1414*25b329d5SDavid du Colombier size_t tCharInfoLen, tOffset, tLen;
1415f5736e95SDavid du Colombier int iIndex, iIndex2, iRun, iFodo, iLen;
1416*25b329d5SDavid du Colombier USHORT usIstd;
1417f5736e95SDavid du Colombier UCHAR aucFpage[BIG_BLOCK_SIZE];
1418f5736e95SDavid du Colombier
1419f5736e95SDavid du Colombier fail(pFile == NULL || pPPS == NULL || aucHeader == NULL);
1420f5736e95SDavid du Colombier fail(aulBBD == NULL || aulSBD == NULL);
1421f5736e95SDavid du Colombier
1422f5736e95SDavid du Colombier ulBeginCharInfo = ulGetLong(0xfa, aucHeader); /* fcPlcfbteChpx */
1423f5736e95SDavid du Colombier NO_DBG_HEX(ulBeginCharInfo);
1424f5736e95SDavid du Colombier tCharInfoLen = (size_t)ulGetLong(0xfe, aucHeader); /* lcbPlcfbteChpx */
1425f5736e95SDavid du Colombier NO_DBG_DEC(tCharInfoLen);
1426f5736e95SDavid du Colombier if (tCharInfoLen < 4) {
1427f5736e95SDavid du Colombier DBG_DEC(tCharInfoLen);
1428f5736e95SDavid du Colombier return;
1429f5736e95SDavid du Colombier }
1430f5736e95SDavid du Colombier
1431*25b329d5SDavid du Colombier aucBuffer = aucFillInfoBuffer(pFile, &pPPS->tTable,
1432*25b329d5SDavid du Colombier aulBBD, tBBDLen, aulSBD, tSBDLen,
1433*25b329d5SDavid du Colombier ulBeginCharInfo, tCharInfoLen);
1434*25b329d5SDavid du Colombier if (aucBuffer == NULL) {
1435f5736e95SDavid du Colombier return;
1436f5736e95SDavid du Colombier }
1437f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucBuffer, tCharInfoLen);
1438f5736e95SDavid du Colombier
1439f5736e95SDavid du Colombier tLen = (tCharInfoLen / 4 - 1) / 2;
1440f5736e95SDavid du Colombier aulCharPage = xcalloc(tLen, sizeof(ULONG));
1441f5736e95SDavid du Colombier for (iIndex = 0, tOffset = (tLen + 1) * 4;
1442f5736e95SDavid du Colombier iIndex < (int)tLen;
1443f5736e95SDavid du Colombier iIndex++, tOffset += 4) {
1444f5736e95SDavid du Colombier aulCharPage[iIndex] = ulGetLong(tOffset, aucBuffer);
1445f5736e95SDavid du Colombier NO_DBG_DEC(aulCharPage[iIndex]);
1446f5736e95SDavid du Colombier }
1447f5736e95SDavid du Colombier DBG_HEX(ulGetLong(0, aucBuffer));
1448f5736e95SDavid du Colombier aucBuffer = xfree(aucBuffer);
1449f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucHeader, HEADER_SIZE);
1450f5736e95SDavid du Colombier
1451f5736e95SDavid du Colombier for (iIndex = 0; iIndex < (int)tLen; iIndex++) {
1452f5736e95SDavid du Colombier fail(aulCharPage[iIndex] > ULONG_MAX / BIG_BLOCK_SIZE);
1453f5736e95SDavid du Colombier if (!bReadBuffer(pFile, pPPS->tWordDocument.ulSB,
1454f5736e95SDavid du Colombier aulBBD, tBBDLen, BIG_BLOCK_SIZE,
1455f5736e95SDavid du Colombier aucFpage,
1456f5736e95SDavid du Colombier aulCharPage[iIndex] * BIG_BLOCK_SIZE,
1457f5736e95SDavid du Colombier BIG_BLOCK_SIZE)) {
1458f5736e95SDavid du Colombier break;
1459f5736e95SDavid du Colombier }
1460f5736e95SDavid du Colombier NO_DBG_PRINT_BLOCK(aucFpage, BIG_BLOCK_SIZE);
1461f5736e95SDavid du Colombier iRun = (int)ucGetByte(0x1ff, aucFpage);
1462f5736e95SDavid du Colombier NO_DBG_DEC(iRun);
1463f5736e95SDavid du Colombier for (iIndex2 = 0; iIndex2 < iRun; iIndex2++) {
1464f5736e95SDavid du Colombier ulCharPos = ulGetLong(iIndex2 * 4, aucFpage);
1465f5736e95SDavid du Colombier ulFileOffset = ulCharPos2FileOffset(ulCharPos);
1466f5736e95SDavid du Colombier iFodo = 2 * (int)ucGetByte(
1467f5736e95SDavid du Colombier (iRun + 1) * 4 + iIndex2, aucFpage);
1468f5736e95SDavid du Colombier
1469f5736e95SDavid du Colombier iLen = (int)ucGetByte(iFodo, aucFpage);
1470f5736e95SDavid du Colombier
1471f5736e95SDavid du Colombier usIstd = usGetIstd(ulFileOffset);
1472f5736e95SDavid du Colombier vFillFontFromStylesheet(usIstd, &tFont);
1473f5736e95SDavid du Colombier if (iFodo != 0) {
1474f5736e95SDavid du Colombier vGet8FontInfo(iFodo, usIstd,
1475f5736e95SDavid du Colombier aucFpage + 1, iLen - 1, &tFont);
1476f5736e95SDavid du Colombier }
1477f5736e95SDavid du Colombier tFont.ulFileOffset = ulFileOffset;
1478f5736e95SDavid du Colombier vAdd2FontInfoList(&tFont);
1479f5736e95SDavid du Colombier
1480f5736e95SDavid du Colombier if (iFodo <= 0) {
1481f5736e95SDavid du Colombier continue;
1482f5736e95SDavid du Colombier }
1483f5736e95SDavid du Colombier
1484f5736e95SDavid du Colombier (void)memset(&tPicture, 0, sizeof(tPicture));
1485f5736e95SDavid du Colombier if (bGet8PicInfo(iFodo, aucFpage + 1,
1486f5736e95SDavid du Colombier iLen - 1, &tPicture)) {
1487f5736e95SDavid du Colombier tPicture.ulFileOffset = ulFileOffset;
1488f5736e95SDavid du Colombier tPicture.ulFileOffsetPicture =
1489f5736e95SDavid du Colombier ulDataPos2FileOffset(
1490f5736e95SDavid du Colombier tPicture.ulPictureOffset);
1491f5736e95SDavid du Colombier vAdd2PictInfoList(&tPicture);
1492f5736e95SDavid du Colombier }
1493f5736e95SDavid du Colombier }
1494f5736e95SDavid du Colombier }
1495f5736e95SDavid du Colombier aulCharPage = xfree(aulCharPage);
1496f5736e95SDavid du Colombier } /* end of vGet8ChrInfo */
1497