xref: /plan9/sys/src/cmd/aux/antiword/prop8.c (revision 25b329d522281a8cdd35da0dcc08c3fc621059a9)
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