3 * Copyright (C) 2004,2005 A.J. van Os; Released under GNU GPL
6 * Build, read and destroy list(s) of Word Header/footer information
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
21 * Private structures to hide the way the information
22 * is stored from the rest of the program
24 typedef struct hdrftr_local_tag
{
25 hdrftr_block_type tInfo
;
31 typedef struct hdrftr_mem_tag
{
32 hdrftr_local_type atElement
[6];
35 /* Variables needed to write the Header/footer Information List */
36 static hdrftr_mem_type
*pHdrFtrList
= NULL
;
37 static size_t tHdrFtrLen
= 0;
41 * vDestroyHdrFtrInfoList - destroy the Header/footer Information List
44 vDestroyHdrFtrInfoList(void)
46 hdrftr_mem_type
*pRecord
;
47 output_type
*pCurr
, *pNext
;
48 size_t tHdrFtr
, tIndex
;
50 DBG_MSG("vDestroyHdrFtrInfoList");
52 /* Free the Header/footer Information List */
53 for (tHdrFtr
= 0; tHdrFtr
< tHdrFtrLen
; tHdrFtr
++) {
54 pRecord
= pHdrFtrList
+ tHdrFtr
;
56 tIndex
< elementsof(pRecord
->atElement
);
58 if (!pRecord
->atElement
[tIndex
].bTextOriginal
) {
61 pCurr
= pRecord
->atElement
[tIndex
].tInfo
.pText
;
62 while (pCurr
!= NULL
) {
63 pCurr
->szStorage
= xfree(pCurr
->szStorage
);
70 pHdrFtrList
= xfree(pHdrFtrList
);
71 /* Reset all control variables */
73 } /* end of vDestroyHdrFtrInfoList */
76 * vCreat8HdrFtrInfoList - Create the Header/footer Information List
79 vCreat8HdrFtrInfoList(const ULONG
*aulCharPos
, size_t tLength
)
81 hdrftr_mem_type
*pListMember
;
82 size_t tHdrFtr
, tIndex
, tMainIndex
;
84 fail(aulCharPos
== NULL
);
90 tHdrFtrLen
= tLength
/ 12;
91 if (tLength
% 12 != 0 && tLength
% 12 != 1) {
96 pHdrFtrList
= xcalloc(tHdrFtrLen
, sizeof(hdrftr_mem_type
));
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];
110 pListMember
->atElement
[tIndex
].ulCharPosNext
=
111 aulCharPos
[tMainIndex
];
115 } /* end of vCreat8HdrFtrInfoList */
118 * vCreat6HdrFtrInfoList - Create the Header/footer Information List
121 vCreat6HdrFtrInfoList(const ULONG
*aulCharPos
, size_t tLength
)
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
,
127 hdrftr_mem_type
*pListMember
;
128 size_t tHdrFtr
, tTmp
, tIndex
, tMainIndex
, tBit
;
129 UCHAR ucDopSpecification
, ucSepSpecification
;
131 fail(aulCharPos
== NULL
);
137 tHdrFtrLen
= tGetNumberOfSections();
138 if (tHdrFtrLen
== 0) {
143 pHdrFtrList
= xcalloc(tHdrFtrLen
, sizeof(hdrftr_mem_type
));
145 /* Get the start index in aulCharPos */
146 ucDopSpecification
= ucGetDopHdrFtrSpecification();
147 DBG_HEX(ucDopSpecification
& 0xe0);
149 for (tBit
= 7; tBit
>= 5; tBit
--) {
150 if ((ucDopSpecification
& BIT(tBit
)) != 0) {
156 for (tHdrFtr
= 0; tHdrFtr
< tHdrFtrLen
; tHdrFtr
++) {
157 ucSepSpecification
= ucGetSepHdrFtrSpecification(tHdrFtr
);
158 DBG_HEX(ucSepSpecification
& 0xfc);
159 pListMember
= pHdrFtrList
+ tHdrFtr
;
161 tTmp
< elementsof(pListMember
->atElement
);
163 pListMember
->atElement
[tTmp
].tInfo
.pText
= NULL
;
165 for (tBit
= 7; tBit
>= 2; tBit
--) {
166 if (tMainIndex
>= tLength
) {
169 if ((ucSepSpecification
& BIT(tBit
)) == 0) {
172 tIndex
= atIndex
[tBit
];
174 pListMember
->atElement
[tIndex
].ulCharPosStart
=
175 aulCharPos
[tMainIndex
];
176 if (tMainIndex
+ 1 < tLength
) {
177 pListMember
->atElement
[tIndex
].ulCharPosNext
=
178 aulCharPos
[tMainIndex
+ 1];
180 pListMember
->atElement
[tIndex
].ulCharPosNext
=
181 aulCharPos
[tMainIndex
];
186 } /* end of vCreat6HdrFtrInfoList */
189 * vCreat2HdrFtrInfoList - Create the Header/footer Information List
192 vCreat2HdrFtrInfoList(const ULONG
*aulCharPos
, size_t tLength
)
194 vCreat6HdrFtrInfoList(aulCharPos
, tLength
);
195 } /* end of vCreat2HdrFtrInfoList */
198 * pGetHdrFtrInfo - get the Header/footer information
200 const hdrftr_block_type
*
201 pGetHdrFtrInfo(int iSectionIndex
,
202 BOOL bWantHeader
, BOOL bOddPage
, BOOL bFirstInSection
)
204 hdrftr_mem_type
*pCurr
;
206 fail(iSectionIndex
< 0);
207 fail(pHdrFtrList
== NULL
&& tHdrFtrLen
!= 0);
209 if (pHdrFtrList
== NULL
|| tHdrFtrLen
== 0) {
214 if (iSectionIndex
< 0) {
216 } else if (iSectionIndex
>= (int)tHdrFtrLen
) {
217 iSectionIndex
= (int)(tHdrFtrLen
- 1);
220 pCurr
= pHdrFtrList
+ iSectionIndex
;
222 if (bFirstInSection
) {
224 return &pCurr
->atElement
[HDR_FIRST_PAGE
].tInfo
;
226 return &pCurr
->atElement
[FTR_FIRST_PAGE
].tInfo
;
231 return &pCurr
->atElement
[HDR_ODD_PAGES
].tInfo
;
233 return &pCurr
->atElement
[HDR_EVEN_PAGES
].tInfo
;
237 return &pCurr
->atElement
[FTR_ODD_PAGES
].tInfo
;
239 return &pCurr
->atElement
[FTR_EVEN_PAGES
].tInfo
;
243 } /* end of pGetHdrFtrInfo */
246 * lComputeHdrFtrHeight - compute the height of a header or footer
248 * Returns the height in DrawUnits
251 lComputeHdrFtrHeight(const output_type
*pAnchor
)
253 const output_type
*pCurr
;
255 USHORT usFontSizeMax
;
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);
269 if (pCurr
->szStorage
[0] == HARD_RETURN
) {
271 lTotal
+= lComputeLeading(usFontSizeMax
);
276 if (pCurr
->usFontSize
> usFontSizeMax
) {
277 usFontSizeMax
= pCurr
->usFontSize
;
280 if (usFontSizeMax
!= 0) {
281 /* Height of the last paragraph */
282 lTotal
+= lComputeLeading(usFontSizeMax
);
285 } /* end of lComputeHdrFtrHeight */
288 * vPrepareHdrFtrText - prepare the header/footer text
291 vPrepareHdrFtrText(FILE *pFile
)
293 hdrftr_mem_type
*pCurr
, *pPrev
;
294 hdrftr_local_type
*pTmp
;
296 size_t tHdrFtr
, tIndex
;
299 fail(pHdrFtrList
== NULL
&& tHdrFtrLen
!= 0);
301 if (pHdrFtrList
== NULL
|| tHdrFtrLen
== 0) {
306 /* Fill text, text height and useful-ness */
307 for (tHdrFtr
= 0; tHdrFtr
< tHdrFtrLen
; tHdrFtr
++) {
308 pCurr
= pHdrFtrList
+ tHdrFtr
;
310 tIndex
< elementsof(pHdrFtrList
->atElement
);
312 pTmp
= &pCurr
->atElement
[tIndex
];
314 pTmp
->ulCharPosStart
!= pTmp
->ulCharPosNext
;
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
;
324 pTmp
->tInfo
.pText
= NULL
;
325 pTmp
->tInfo
.lHeight
= 0;
326 pTmp
->bTextOriginal
= FALSE
;
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
;
338 pTmp
= &pHdrFtrList
->atElement
[HDR_EVEN_PAGES
];
339 if (!pTmp
->bUseful
) {
340 *pTmp
= pHdrFtrList
->atElement
[HDR_FIRST_PAGE
];
341 pTmp
->bTextOriginal
= FALSE
;
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
;
350 pTmp
= &pHdrFtrList
->atElement
[FTR_EVEN_PAGES
];
351 if (!pTmp
->bUseful
) {
352 *pTmp
= pHdrFtrList
->atElement
[FTR_FIRST_PAGE
];
353 pTmp
->bTextOriginal
= FALSE
;
356 for (tHdrFtr
= 1, pCurr
= &pHdrFtrList
[1];
357 tHdrFtr
< tHdrFtrLen
;
358 tHdrFtr
++, pCurr
++) {
361 tIndex
< elementsof(pHdrFtrList
->atElement
);
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
;
371 } /* end of vPrepareHdrFtrText */