Warning: Attempt to read property "date" on null in /usr/local/www/websvn.planix.org/blame.php on line 247

Warning: Attempt to read property "msg" on null in /usr/local/www/websvn.planix.org/blame.php on line 247
WebSVN – planix.SVN – Blame – /os/branches/feature-vt/sys/src/cmd/aux/antiword/hdrftrlist.c – Rev 2

Subversion Repositories planix.SVN

Rev

Go to most recent revision | Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * hdrftrlist.c
3
 * Copyright (C) 2004,2005 A.J. van Os; Released under GNU GPL
4
 *
5
 * Description:
6
 * Build, read and destroy list(s) of Word Header/footer information
7
 */
8
 
9
#include <string.h>
10
#include "antiword.h"
11
 
12
 
13
#define HDR_EVEN_PAGES	0
14
#define HDR_ODD_PAGES	1
15
#define FTR_EVEN_PAGES	2
16
#define FTR_ODD_PAGES	3
17
#define HDR_FIRST_PAGE	4
18
#define FTR_FIRST_PAGE	5
19
 
20
/*
21
 * Private structures to hide the way the information
22
 * is stored from the rest of the program
23
 */
24
typedef struct hdrftr_local_tag {
25
	hdrftr_block_type	tInfo;
26
	ULONG			ulCharPosStart;
27
	ULONG			ulCharPosNext;
28
	BOOL			bUseful;
29
	BOOL			bTextOriginal;
30
} hdrftr_local_type;
31
typedef struct hdrftr_mem_tag {
32
	hdrftr_local_type	atElement[6];
33
} hdrftr_mem_type;
34
 
35
/* Variables needed to write the Header/footer Information List */
36
static hdrftr_mem_type	*pHdrFtrList = NULL;
37
static size_t		tHdrFtrLen = 0;
38
 
39
 
40
/*
41
 * vDestroyHdrFtrInfoList - destroy the Header/footer Information List
42
 */
43
void
44
vDestroyHdrFtrInfoList(void)
45
{
46
	hdrftr_mem_type *pRecord;
47
	output_type	*pCurr, *pNext;
48
	size_t		tHdrFtr, tIndex;
49
 
50
	DBG_MSG("vDestroyHdrFtrInfoList");
51
 
52
	/* Free the Header/footer Information List */
53
	for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
54
		pRecord = pHdrFtrList + tHdrFtr;
55
		for (tIndex = 0;
56
		     tIndex < elementsof(pRecord->atElement);
57
		     tIndex++) {
58
			if (!pRecord->atElement[tIndex].bTextOriginal) {
59
				continue;
60
			}
61
			pCurr = pRecord->atElement[tIndex].tInfo.pText;
62
			while (pCurr != NULL) {
63
				pCurr->szStorage = xfree(pCurr->szStorage);
64
				pNext = pCurr->pNext;
65
				pCurr = xfree(pCurr);
66
				pCurr = pNext;
67
			}
68
		}
69
	}
70
	pHdrFtrList = xfree(pHdrFtrList);
71
	/* Reset all control variables */
72
	tHdrFtrLen = 0;
73
} /* end of vDestroyHdrFtrInfoList */
74
 
75
/*
76
 * vCreat8HdrFtrInfoList - Create the Header/footer Information List
77
 */
78
void
79
vCreat8HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength)
80
{
81
	hdrftr_mem_type	*pListMember;
82
	size_t	tHdrFtr, tIndex, tMainIndex;
83
 
84
	fail(aulCharPos == NULL);
85
 
86
	DBG_DEC(tLength);
87
	if (tLength <= 1) {
88
		return;
89
	}
90
	tHdrFtrLen = tLength / 12;
91
	if (tLength % 12 != 0 && tLength % 12 != 1) {
92
		tHdrFtrLen++;
93
	}
94
	DBG_DEC(tHdrFtrLen);
95
 
96
	pHdrFtrList = xcalloc(tHdrFtrLen, sizeof(hdrftr_mem_type));
97
 
98
	for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
99
		pListMember = pHdrFtrList + tHdrFtr;
100
		for (tIndex = 0, tMainIndex = tHdrFtr * 12;
101
		     tIndex < 6 && tMainIndex < tLength;
102
		     tIndex++, tMainIndex++) {
103
			pListMember->atElement[tIndex].tInfo.pText = NULL;
104
			pListMember->atElement[tIndex].ulCharPosStart =
105
						aulCharPos[tMainIndex];
106
			if (tMainIndex + 1 < tLength) {
107
				pListMember->atElement[tIndex].ulCharPosNext =
108
					aulCharPos[tMainIndex + 1];
109
			} else {
110
				pListMember->atElement[tIndex].ulCharPosNext =
111
					aulCharPos[tMainIndex];
112
			}
113
		}
114
	}
115
} /* end of vCreat8HdrFtrInfoList */
116
 
117
/*
118
 * vCreat6HdrFtrInfoList - Create the Header/footer Information List
119
 */
120
void
121
vCreat6HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength)
122
{
123
	static const size_t	atIndex[] =
124
		{ SIZE_T_MAX, SIZE_T_MAX, FTR_FIRST_PAGE, HDR_FIRST_PAGE,
125
		  FTR_ODD_PAGES, FTR_EVEN_PAGES, HDR_ODD_PAGES, HDR_EVEN_PAGES,
126
		};
127
	hdrftr_mem_type	*pListMember;
128
	size_t	tHdrFtr, tTmp, tIndex, tMainIndex, tBit;
129
	UCHAR	ucDopSpecification, ucSepSpecification;
130
 
131
	fail(aulCharPos == NULL);
132
 
133
	DBG_DEC(tLength);
134
	if (tLength <= 1) {
135
		return;
136
	}
137
	tHdrFtrLen = tGetNumberOfSections();
138
	if (tHdrFtrLen == 0) {
139
		tHdrFtrLen = 1;
140
	}
141
	DBG_DEC(tHdrFtrLen);
142
 
143
	pHdrFtrList = xcalloc(tHdrFtrLen, sizeof(hdrftr_mem_type));
144
 
145
	/* Get the start index in aulCharPos */
146
	ucDopSpecification = ucGetDopHdrFtrSpecification();
147
	DBG_HEX(ucDopSpecification & 0xe0);
148
	tMainIndex = 0;
149
	for (tBit = 7; tBit >= 5; tBit--) {
150
		if ((ucDopSpecification & BIT(tBit)) != 0) {
151
			tMainIndex++;
152
		}
153
	}
154
	DBG_DEC(tMainIndex);
155
 
156
	for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
157
		ucSepSpecification = ucGetSepHdrFtrSpecification(tHdrFtr);
158
		DBG_HEX(ucSepSpecification & 0xfc);
159
		pListMember = pHdrFtrList + tHdrFtr;
160
		for (tTmp = 0;
161
		     tTmp < elementsof(pListMember->atElement);
162
		     tTmp++) {
163
			pListMember->atElement[tTmp].tInfo.pText = NULL;
164
		}
165
		for (tBit = 7; tBit >= 2; tBit--) {
166
			if (tMainIndex >= tLength) {
167
				break;
168
			}
169
			if ((ucSepSpecification & BIT(tBit)) == 0) {
170
				continue;
171
			}
172
			tIndex = atIndex[tBit];
173
			fail(tIndex >= 6);
174
			pListMember->atElement[tIndex].ulCharPosStart =
175
				aulCharPos[tMainIndex];
176
			if (tMainIndex + 1 < tLength) {
177
				pListMember->atElement[tIndex].ulCharPosNext =
178
					aulCharPos[tMainIndex + 1];
179
			} else {
180
				pListMember->atElement[tIndex].ulCharPosNext =
181
					aulCharPos[tMainIndex];
182
			}
183
			tMainIndex++;
184
		}
185
	}
186
} /* end of vCreat6HdrFtrInfoList */
187
 
188
/*
189
 * vCreat2HdrFtrInfoList - Create the Header/footer Information List
190
 */
191
void
192
vCreat2HdrFtrInfoList(const ULONG *aulCharPos, size_t tLength)
193
{
194
	vCreat6HdrFtrInfoList(aulCharPos, tLength);
195
} /* end of vCreat2HdrFtrInfoList */
196
 
197
/*
198
 * pGetHdrFtrInfo - get the Header/footer information
199
 */
200
const hdrftr_block_type *
201
pGetHdrFtrInfo(int iSectionIndex,
202
	BOOL bWantHeader, BOOL bOddPage, BOOL bFirstInSection)
203
{
204
	hdrftr_mem_type	*pCurr;
205
 
206
	fail(iSectionIndex < 0);
207
	fail(pHdrFtrList == NULL && tHdrFtrLen != 0);
208
 
209
	if (pHdrFtrList == NULL || tHdrFtrLen == 0) {
210
		/* No information */
211
		return NULL;
212
	}
213
 
214
	if (iSectionIndex < 0) {
215
		iSectionIndex = 0;
216
	} else if (iSectionIndex >= (int)tHdrFtrLen) {
217
		iSectionIndex = (int)(tHdrFtrLen - 1);
218
	}
219
 
220
	pCurr = pHdrFtrList + iSectionIndex;
221
 
222
	if (bFirstInSection) {
223
		if (bWantHeader) {
224
			return &pCurr->atElement[HDR_FIRST_PAGE].tInfo;
225
		} else {
226
			return &pCurr->atElement[FTR_FIRST_PAGE].tInfo;
227
		}
228
	} else {
229
		if (bWantHeader) {
230
			if (bOddPage) {
231
				return &pCurr->atElement[HDR_ODD_PAGES].tInfo;
232
			} else {
233
				return &pCurr->atElement[HDR_EVEN_PAGES].tInfo;
234
			}
235
		} else {
236
			if (bOddPage) {
237
				return &pCurr->atElement[FTR_ODD_PAGES].tInfo;
238
			} else {
239
				return &pCurr->atElement[FTR_EVEN_PAGES].tInfo;
240
			}
241
		}
242
	}
243
} /* end of pGetHdrFtrInfo */
244
 
245
/*
246
 * lComputeHdrFtrHeight - compute the height of a header or footer
247
 *
248
 * Returns the height in DrawUnits
249
 */
250
static long
251
lComputeHdrFtrHeight(const output_type *pAnchor)
252
{
253
	const output_type *pCurr;
254
	long	lTotal;
255
	USHORT	usFontSizeMax;
256
 
257
	lTotal = 0;
258
	usFontSizeMax = 0;
259
	for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
260
		if (pCurr->tNextFree == 1) {
261
			if (pCurr->szStorage[0] == PAR_END) {
262
				/* End of a paragraph */
263
				lTotal += lComputeLeading(usFontSizeMax);
264
				lTotal += lMilliPoints2DrawUnits(
265
						(long)pCurr->usFontSize * 200);
266
				usFontSizeMax = 0;
267
				continue;
268
			}
269
			if (pCurr->szStorage[0] == HARD_RETURN) {
270
				/* End of a line */
271
				lTotal += lComputeLeading(usFontSizeMax);
272
				usFontSizeMax = 0;
273
				continue;
274
			}
275
		}
276
		if (pCurr->usFontSize > usFontSizeMax) {
277
			usFontSizeMax = pCurr->usFontSize;
278
		}
279
	}
280
	if (usFontSizeMax != 0) {
281
		/* Height of the last paragraph */
282
		lTotal += lComputeLeading(usFontSizeMax);
283
	}
284
	return lTotal;
285
} /* end of lComputeHdrFtrHeight */
286
 
287
/*
288
 * vPrepareHdrFtrText - prepare the header/footer text
289
 */
290
void
291
vPrepareHdrFtrText(FILE *pFile)
292
{
293
	hdrftr_mem_type		*pCurr, *pPrev;
294
	hdrftr_local_type	*pTmp;
295
	output_type		*pText;
296
	size_t		tHdrFtr, tIndex;
297
 
298
	fail(pFile == NULL);
299
	fail(pHdrFtrList == NULL && tHdrFtrLen != 0);
300
 
301
	if (pHdrFtrList == NULL || tHdrFtrLen == 0) {
302
		/* No information */
303
		return;
304
	}
305
 
306
	/* Fill text, text height and useful-ness */
307
	for (tHdrFtr = 0; tHdrFtr < tHdrFtrLen; tHdrFtr++) {
308
		pCurr = pHdrFtrList + tHdrFtr;
309
		for (tIndex = 0;
310
		     tIndex < elementsof(pHdrFtrList->atElement);
311
		     tIndex++) {
312
			pTmp = &pCurr->atElement[tIndex];
313
			pTmp->bUseful =
314
				pTmp->ulCharPosStart != pTmp->ulCharPosNext;
315
			if (pTmp->bUseful) {
316
				pText = pHdrFtrDecryptor(pFile,
317
						pTmp->ulCharPosStart,
318
						pTmp->ulCharPosNext);
319
				pTmp->tInfo.pText = pText;
320
				pTmp->tInfo.lHeight =
321
						lComputeHdrFtrHeight(pText);
322
				pTmp->bTextOriginal = pText != NULL;
323
			} else {
324
				pTmp->tInfo.pText = NULL;
325
				pTmp->tInfo.lHeight = 0;
326
				pTmp->bTextOriginal = FALSE;
327
			}
328
		}
329
	}
330
 
331
	/* Replace not-useful records by using inheritance */
332
	if (pHdrFtrList->atElement[HDR_FIRST_PAGE].bUseful) {
333
		pTmp = &pHdrFtrList->atElement[HDR_ODD_PAGES];
334
		if (!pTmp->bUseful) {
335
			*pTmp = pHdrFtrList->atElement[HDR_FIRST_PAGE];
336
			pTmp->bTextOriginal = FALSE;
337
		}
338
		pTmp = &pHdrFtrList->atElement[HDR_EVEN_PAGES];
339
		if (!pTmp->bUseful) {
340
			*pTmp = pHdrFtrList->atElement[HDR_FIRST_PAGE];
341
			pTmp->bTextOriginal = FALSE;
342
		}
343
	}
344
	if (pHdrFtrList->atElement[FTR_FIRST_PAGE].bUseful) {
345
		pTmp = &pHdrFtrList->atElement[FTR_ODD_PAGES];
346
		if (!pTmp->bUseful) {
347
			*pTmp = pHdrFtrList->atElement[FTR_FIRST_PAGE];
348
			pTmp->bTextOriginal = FALSE;
349
		}
350
		pTmp = &pHdrFtrList->atElement[FTR_EVEN_PAGES];
351
		if (!pTmp->bUseful) {
352
			*pTmp = pHdrFtrList->atElement[FTR_FIRST_PAGE];
353
			pTmp->bTextOriginal = FALSE;
354
		}
355
	}
356
	for (tHdrFtr = 1, pCurr = &pHdrFtrList[1];
357
	     tHdrFtr < tHdrFtrLen;
358
	     tHdrFtr++, pCurr++) {
359
		pPrev = pCurr - 1;
360
		for (tIndex = 0;
361
		     tIndex < elementsof(pHdrFtrList->atElement);
362
		     tIndex++) {
363
			if (!pCurr->atElement[tIndex].bUseful &&
364
			    pPrev->atElement[tIndex].bUseful) {
365
				pCurr->atElement[tIndex] =
366
						pPrev->atElement[tIndex];
367
				pCurr->atElement[tIndex].bTextOriginal = FALSE;
368
			}
369
		}
370
	}
371
} /* end of vPrepareHdrFtrText */