1f5736e95SDavid du Colombier /*
2f5736e95SDavid du Colombier * stylelist.c
3*25b329d5SDavid du Colombier * Copyright (C) 1998-2005 A.J. van Os; Released under GNU GPL
4f5736e95SDavid du Colombier *
5f5736e95SDavid du Colombier * Description:
6f5736e95SDavid du Colombier * Build, read and destroy a list of Word style information
7f5736e95SDavid du Colombier */
8f5736e95SDavid du Colombier
9f5736e95SDavid du Colombier #include <stdlib.h>
10f5736e95SDavid du Colombier #include <stddef.h>
11f5736e95SDavid du Colombier #include <ctype.h>
12f5736e95SDavid du Colombier #include "antiword.h"
13f5736e95SDavid du Colombier
14f5736e95SDavid du Colombier
15f5736e95SDavid du Colombier /*
16f5736e95SDavid du Colombier * Private structure to hide the way the information
17f5736e95SDavid du Colombier * is stored from the rest of the program
18f5736e95SDavid du Colombier */
19f5736e95SDavid du Colombier typedef struct style_mem_tag {
20f5736e95SDavid du Colombier style_block_type tInfo;
21f5736e95SDavid du Colombier ULONG ulSequenceNumber;
22f5736e95SDavid du Colombier struct style_mem_tag *pNext;
23f5736e95SDavid du Colombier } style_mem_type;
24f5736e95SDavid du Colombier
25f5736e95SDavid du Colombier /* Variables needed to write the Style Information List */
26f5736e95SDavid du Colombier static style_mem_type *pAnchor = NULL;
27f5736e95SDavid du Colombier static style_mem_type *pStyleLast = NULL;
28f5736e95SDavid du Colombier /* The type of conversion */
29f5736e95SDavid du Colombier static conversion_type eConversionType = conversion_unknown;
30f5736e95SDavid du Colombier /* The character set encoding */
31f5736e95SDavid du Colombier static encoding_type eEncoding = encoding_neutral;
32f5736e95SDavid du Colombier /* Values for efficiency reasons */
33f5736e95SDavid du Colombier static const style_mem_type *pMidPtr = NULL;
34f5736e95SDavid du Colombier static BOOL bMoveMidPtr = FALSE;
35f5736e95SDavid du Colombier static BOOL bInSequence = TRUE;
36f5736e95SDavid du Colombier
37f5736e95SDavid du Colombier
38f5736e95SDavid du Colombier /*
39f5736e95SDavid du Colombier * vDestroyStyleInfoList - destroy the Style Information List
40f5736e95SDavid du Colombier */
41f5736e95SDavid du Colombier void
vDestroyStyleInfoList(void)42f5736e95SDavid du Colombier vDestroyStyleInfoList(void)
43f5736e95SDavid du Colombier {
44f5736e95SDavid du Colombier style_mem_type *pCurr, *pNext;
45f5736e95SDavid du Colombier
46f5736e95SDavid du Colombier DBG_MSG("vDestroyStyleInfoList");
47f5736e95SDavid du Colombier
48f5736e95SDavid du Colombier /* Free the Style Information List */
49f5736e95SDavid du Colombier pCurr = pAnchor;
50f5736e95SDavid du Colombier while (pCurr != NULL) {
51f5736e95SDavid du Colombier pNext = pCurr->pNext;
52f5736e95SDavid du Colombier pCurr = xfree(pCurr);
53f5736e95SDavid du Colombier pCurr = pNext;
54f5736e95SDavid du Colombier }
55f5736e95SDavid du Colombier pAnchor = NULL;
56f5736e95SDavid du Colombier /* Reset all control variables */
57f5736e95SDavid du Colombier pStyleLast = NULL;
58f5736e95SDavid du Colombier pMidPtr = NULL;
59f5736e95SDavid du Colombier bMoveMidPtr = FALSE;
60f5736e95SDavid du Colombier bInSequence = TRUE;
61f5736e95SDavid du Colombier } /* end of vDestroyStyleInfoList */
62f5736e95SDavid du Colombier
63f5736e95SDavid du Colombier /*
64f5736e95SDavid du Colombier * vConvertListCharacter - convert the list character
65f5736e95SDavid du Colombier */
66f5736e95SDavid du Colombier static void
vConvertListCharacter(UCHAR ucNFC,USHORT usListChar,char * szListChar)67f5736e95SDavid du Colombier vConvertListCharacter(UCHAR ucNFC, USHORT usListChar, char *szListChar)
68f5736e95SDavid du Colombier {
69f5736e95SDavid du Colombier options_type tOptions;
70f5736e95SDavid du Colombier size_t tLen;
71f5736e95SDavid du Colombier
72f5736e95SDavid du Colombier fail(szListChar == NULL);
73f5736e95SDavid du Colombier fail(szListChar[0] != '\0');
74f5736e95SDavid du Colombier
75f5736e95SDavid du Colombier if (usListChar < 0x80 && isprint((int)usListChar)) {
76f5736e95SDavid du Colombier DBG_CHR_C(isalnum((int)usListChar), usListChar);
77f5736e95SDavid du Colombier szListChar[0] = (char)usListChar;
78f5736e95SDavid du Colombier szListChar[1] = '\0';
79f5736e95SDavid du Colombier return;
80f5736e95SDavid du Colombier }
81f5736e95SDavid du Colombier
82*25b329d5SDavid du Colombier if (ucNFC != LIST_SPECIAL &&
83*25b329d5SDavid du Colombier ucNFC != LIST_SPECIAL2 &&
84*25b329d5SDavid du Colombier ucNFC != LIST_BULLETS) {
85f5736e95SDavid du Colombier szListChar[0] = '.';
86f5736e95SDavid du Colombier szListChar[1] = '\0';
87f5736e95SDavid du Colombier return;
88f5736e95SDavid du Colombier }
89f5736e95SDavid du Colombier
90f5736e95SDavid du Colombier if (eConversionType == conversion_unknown ||
91f5736e95SDavid du Colombier eEncoding == encoding_neutral) {
92f5736e95SDavid du Colombier vGetOptions(&tOptions);
93f5736e95SDavid du Colombier eConversionType = tOptions.eConversionType;
94f5736e95SDavid du Colombier eEncoding = tOptions.eEncoding;
95f5736e95SDavid du Colombier }
96f5736e95SDavid du Colombier
97f5736e95SDavid du Colombier switch (usListChar) {
98f5736e95SDavid du Colombier case 0x0000: case 0x00b7: case 0x00fe: case 0xf021: case 0xf043:
99*25b329d5SDavid du Colombier case 0xf06c: case 0xf093: case 0xf0b7:
100f5736e95SDavid du Colombier usListChar = 0x2022; /* BULLET */
101f5736e95SDavid du Colombier break;
102f5736e95SDavid du Colombier case 0x0096: case 0xf02d:
103f5736e95SDavid du Colombier usListChar = 0x2013; /* EN DASH */
104f5736e95SDavid du Colombier break;
105f5736e95SDavid du Colombier case 0x00a8:
106f5736e95SDavid du Colombier usListChar = 0x2666; /* BLACK DIAMOND SUIT */
107f5736e95SDavid du Colombier break;
108f5736e95SDavid du Colombier case 0x00de:
109f5736e95SDavid du Colombier usListChar = 0x21d2; /* RIGHTWARDS DOUBLE ARROW */
110f5736e95SDavid du Colombier break;
111f5736e95SDavid du Colombier case 0x00e0: case 0xf074:
112f5736e95SDavid du Colombier usListChar = 0x25ca; /* LOZENGE */
113f5736e95SDavid du Colombier break;
114f5736e95SDavid du Colombier case 0x00e1:
115f5736e95SDavid du Colombier usListChar = 0x2329; /* LEFT ANGLE BRACKET */
116f5736e95SDavid du Colombier break;
117f5736e95SDavid du Colombier case 0xf020:
118f5736e95SDavid du Colombier usListChar = 0x0020; /* SPACE */
119f5736e95SDavid du Colombier break;
120f5736e95SDavid du Colombier case 0xf041:
121f5736e95SDavid du Colombier usListChar = 0x270c; /* VICTORY HAND */
122f5736e95SDavid du Colombier break;
123f5736e95SDavid du Colombier case 0xf066:
124f5736e95SDavid du Colombier usListChar = 0x03d5; /* GREEK PHI SYMBOL */
125f5736e95SDavid du Colombier break;
126f5736e95SDavid du Colombier case 0xf06e:
127f5736e95SDavid du Colombier usListChar = 0x25a0; /* BLACK SQUARE */
128f5736e95SDavid du Colombier break;
129f5736e95SDavid du Colombier case 0xf06f: case 0xf070: case 0xf0a8:
130f5736e95SDavid du Colombier usListChar = 0x25a1; /* WHITE SQUARE */
131f5736e95SDavid du Colombier break;
132f5736e95SDavid du Colombier case 0xf071:
133f5736e95SDavid du Colombier usListChar = 0x2751; /* LOWER RIGHT SHADOWED WHITE SQUARE */
134f5736e95SDavid du Colombier break;
135*25b329d5SDavid du Colombier case 0xf075: case 0xf077:
136f5736e95SDavid du Colombier usListChar = 0x25c6; /* BLACK DIAMOND */
137f5736e95SDavid du Colombier break;
138f5736e95SDavid du Colombier case 0xf076:
139f5736e95SDavid du Colombier usListChar = 0x2756; /* BLACK DIAMOND MINUS WHITE X */
140f5736e95SDavid du Colombier break;
141f5736e95SDavid du Colombier case 0xf0a7:
142f5736e95SDavid du Colombier usListChar = 0x25aa; /* BLACK SMALL SQUARE */
143f5736e95SDavid du Colombier break;
144f5736e95SDavid du Colombier case 0xf0d8:
145f5736e95SDavid du Colombier usListChar = 0x27a2; /* RIGHTWARDS ARROWHEAD */
146f5736e95SDavid du Colombier break;
147f5736e95SDavid du Colombier case 0xf0e5:
148f5736e95SDavid du Colombier usListChar = 0x2199; /* SOUTH WEST ARROW */
149f5736e95SDavid du Colombier break;
150f5736e95SDavid du Colombier case 0xf0f0:
151f5736e95SDavid du Colombier usListChar = 0x21e8; /* RIGHTWARDS WHITE ARROW */
152f5736e95SDavid du Colombier break;
153f5736e95SDavid du Colombier case 0xf0fc:
154f5736e95SDavid du Colombier usListChar = 0x2713; /* CHECK MARK */
155f5736e95SDavid du Colombier break;
156f5736e95SDavid du Colombier default:
157f5736e95SDavid du Colombier if ((usListChar >= 0xe000 && usListChar < 0xf900) ||
158f5736e95SDavid du Colombier (usListChar < 0x80 && !isprint((int)usListChar))) {
159f5736e95SDavid du Colombier /*
160f5736e95SDavid du Colombier * All remaining private area characters and all
161*25b329d5SDavid du Colombier * remaining non-printable ASCII characters to their
162*25b329d5SDavid du Colombier * default bullet character
163f5736e95SDavid du Colombier */
164f5736e95SDavid du Colombier DBG_HEX(usListChar);
165f5736e95SDavid du Colombier DBG_FIXME();
166*25b329d5SDavid du Colombier if (ucNFC == LIST_SPECIAL || ucNFC == LIST_SPECIAL2) {
167*25b329d5SDavid du Colombier usListChar = 0x2190; /* LEFTWARDS ARROW */
168*25b329d5SDavid du Colombier } else {
169f5736e95SDavid du Colombier usListChar = 0x2022; /* BULLET */
170f5736e95SDavid du Colombier }
171*25b329d5SDavid du Colombier }
172f5736e95SDavid du Colombier break;
173f5736e95SDavid du Colombier }
174f5736e95SDavid du Colombier
175*25b329d5SDavid du Colombier if (eEncoding == encoding_utf_8) {
176f5736e95SDavid du Colombier tLen = tUcs2Utf8(usListChar, szListChar, 4);
177f5736e95SDavid du Colombier szListChar[tLen] = '\0';
178f5736e95SDavid du Colombier } else {
179f5736e95SDavid du Colombier switch (usListChar) {
180f5736e95SDavid du Colombier case 0x03d5: case 0x25a1: case 0x25c6: case 0x25ca:
181f5736e95SDavid du Colombier case 0x2751:
182f5736e95SDavid du Colombier szListChar[0] = 'o';
183f5736e95SDavid du Colombier break;
184f5736e95SDavid du Colombier case 0x2013: case 0x2500:
185f5736e95SDavid du Colombier szListChar[0] = '-';
186f5736e95SDavid du Colombier break;
187*25b329d5SDavid du Colombier case 0x2190: case 0x2199: case 0x2329:
188f5736e95SDavid du Colombier szListChar[0] = '<';
189f5736e95SDavid du Colombier break;
190f5736e95SDavid du Colombier case 0x21d2:
191f5736e95SDavid du Colombier szListChar[0] = '=';
192f5736e95SDavid du Colombier break;
193f5736e95SDavid du Colombier case 0x21e8: case 0x27a2:
194f5736e95SDavid du Colombier szListChar[0] = '>';
195f5736e95SDavid du Colombier break;
196f5736e95SDavid du Colombier case 0x25a0: case 0x25aa:
197f5736e95SDavid du Colombier szListChar[0] = '.';
198f5736e95SDavid du Colombier break;
199f5736e95SDavid du Colombier case 0x2666:
200f5736e95SDavid du Colombier szListChar[0] = OUR_DIAMOND;
201f5736e95SDavid du Colombier break;
202f5736e95SDavid du Colombier case 0x270c:
203f5736e95SDavid du Colombier szListChar[0] = 'x';
204f5736e95SDavid du Colombier break;
205f5736e95SDavid du Colombier case 0x2713:
206f5736e95SDavid du Colombier szListChar[0] = 'V';
207f5736e95SDavid du Colombier break;
208f5736e95SDavid du Colombier case 0x2756:
209f5736e95SDavid du Colombier szListChar[0] = '*';
210f5736e95SDavid du Colombier break;
211f5736e95SDavid du Colombier case 0x2022:
212f5736e95SDavid du Colombier default:
213f5736e95SDavid du Colombier vGetBulletValue(eConversionType, eEncoding,
214f5736e95SDavid du Colombier szListChar, 2);
215f5736e95SDavid du Colombier break;
216f5736e95SDavid du Colombier }
217f5736e95SDavid du Colombier tLen = 1;
218f5736e95SDavid du Colombier }
219f5736e95SDavid du Colombier szListChar[tLen] = '\0';
220f5736e95SDavid du Colombier } /* end of vConvertListCharacter */
221f5736e95SDavid du Colombier
222f5736e95SDavid du Colombier /*
223f5736e95SDavid du Colombier * eGetNumType - get the level type from the given level number
224f5736e95SDavid du Colombier *
225f5736e95SDavid du Colombier * Returns the level type
226f5736e95SDavid du Colombier */
227f5736e95SDavid du Colombier level_type_enum
eGetNumType(UCHAR ucNumLevel)228f5736e95SDavid du Colombier eGetNumType(UCHAR ucNumLevel)
229f5736e95SDavid du Colombier {
230f5736e95SDavid du Colombier switch (ucNumLevel) {
231f5736e95SDavid du Colombier case 1: case 2: case 3: case 4: case 5:
232f5736e95SDavid du Colombier case 6: case 7: case 8: case 9:
233f5736e95SDavid du Colombier return level_type_outline;
234f5736e95SDavid du Colombier case 10:
235f5736e95SDavid du Colombier return level_type_numbering;
236f5736e95SDavid du Colombier case 11:
237f5736e95SDavid du Colombier return level_type_sequence;
238f5736e95SDavid du Colombier case 12:
239f5736e95SDavid du Colombier return level_type_pause;
240f5736e95SDavid du Colombier default:
241f5736e95SDavid du Colombier return level_type_none;
242f5736e95SDavid du Colombier }
243f5736e95SDavid du Colombier } /* end of eGetNumType */
244f5736e95SDavid du Colombier
245f5736e95SDavid du Colombier /*
246f5736e95SDavid du Colombier * vCorrectStyleValues - correct style values that Antiword can't use
247f5736e95SDavid du Colombier */
248f5736e95SDavid du Colombier void
vCorrectStyleValues(style_block_type * pStyleBlock)249f5736e95SDavid du Colombier vCorrectStyleValues(style_block_type *pStyleBlock)
250f5736e95SDavid du Colombier {
251f5736e95SDavid du Colombier if (pStyleBlock->usBeforeIndent > 0x7fff) {
252f5736e95SDavid du Colombier pStyleBlock->usBeforeIndent = 0;
253f5736e95SDavid du Colombier } else if (pStyleBlock->usBeforeIndent > 2160) {
254f5736e95SDavid du Colombier /* 2160 twips = 1.5 inches or 38.1 mm */
255f5736e95SDavid du Colombier DBG_DEC(pStyleBlock->usBeforeIndent);
256f5736e95SDavid du Colombier pStyleBlock->usBeforeIndent = 2160;
257f5736e95SDavid du Colombier }
258f5736e95SDavid du Colombier if (pStyleBlock->usIstd >= 1 &&
259f5736e95SDavid du Colombier pStyleBlock->usIstd <= 9 &&
260f5736e95SDavid du Colombier pStyleBlock->usBeforeIndent < HEADING_GAP) {
261f5736e95SDavid du Colombier NO_DBG_DEC(pStyleBlock->usBeforeIndent);
262f5736e95SDavid du Colombier pStyleBlock->usBeforeIndent = HEADING_GAP;
263f5736e95SDavid du Colombier }
264f5736e95SDavid du Colombier
265f5736e95SDavid du Colombier if (pStyleBlock->usAfterIndent > 0x7fff) {
266f5736e95SDavid du Colombier pStyleBlock->usAfterIndent = 0;
267f5736e95SDavid du Colombier } else if (pStyleBlock->usAfterIndent > 2160) {
268f5736e95SDavid du Colombier /* 2160 twips = 1.5 inches or 38.1 mm */
269f5736e95SDavid du Colombier DBG_DEC(pStyleBlock->usAfterIndent);
270f5736e95SDavid du Colombier pStyleBlock->usAfterIndent = 2160;
271f5736e95SDavid du Colombier }
272f5736e95SDavid du Colombier if (pStyleBlock->usIstd >= 1 &&
273f5736e95SDavid du Colombier pStyleBlock->usIstd <= 9 &&
274f5736e95SDavid du Colombier pStyleBlock->usAfterIndent < HEADING_GAP) {
275f5736e95SDavid du Colombier NO_DBG_DEC(pStyleBlock->usAfterIndent);
276f5736e95SDavid du Colombier pStyleBlock->usAfterIndent = HEADING_GAP;
277f5736e95SDavid du Colombier }
278f5736e95SDavid du Colombier
279f5736e95SDavid du Colombier if (pStyleBlock->sLeftIndent < 0) {
280f5736e95SDavid du Colombier pStyleBlock->sLeftIndent = 0;
281f5736e95SDavid du Colombier }
282f5736e95SDavid du Colombier if (pStyleBlock->sRightIndent > 0) {
283f5736e95SDavid du Colombier pStyleBlock->sRightIndent = 0;
284f5736e95SDavid du Colombier }
285f5736e95SDavid du Colombier vConvertListCharacter(pStyleBlock->ucNFC,
286f5736e95SDavid du Colombier pStyleBlock->usListChar,
287f5736e95SDavid du Colombier pStyleBlock->szListChar);
288f5736e95SDavid du Colombier } /* end of vCorrectStyleValues */
289f5736e95SDavid du Colombier
290f5736e95SDavid du Colombier /*
291f5736e95SDavid du Colombier * vAdd2StyleInfoList - Add an element to the Style Information List
292f5736e95SDavid du Colombier */
293f5736e95SDavid du Colombier void
vAdd2StyleInfoList(const style_block_type * pStyleBlock)294f5736e95SDavid du Colombier vAdd2StyleInfoList(const style_block_type *pStyleBlock)
295f5736e95SDavid du Colombier {
296f5736e95SDavid du Colombier style_mem_type *pListMember;
297f5736e95SDavid du Colombier
298f5736e95SDavid du Colombier fail(pStyleBlock == NULL);
299f5736e95SDavid du Colombier
300f5736e95SDavid du Colombier NO_DBG_MSG("bAdd2StyleInfoList");
301f5736e95SDavid du Colombier
302f5736e95SDavid du Colombier if (pStyleBlock->ulFileOffset == FC_INVALID) {
303f5736e95SDavid du Colombier NO_DBG_DEC(pStyleBlock->usIstd);
304f5736e95SDavid du Colombier return;
305f5736e95SDavid du Colombier }
306f5736e95SDavid du Colombier
307f5736e95SDavid du Colombier NO_DBG_HEX(pStyleBlock->ulFileOffset);
308f5736e95SDavid du Colombier NO_DBG_DEC_C(pStyleBlock->sLeftIndent != 0,
309f5736e95SDavid du Colombier pStyleBlock->sLeftIndent);
310f5736e95SDavid du Colombier NO_DBG_DEC_C(pStyleBlock->sRightIndent != 0,
311f5736e95SDavid du Colombier pStyleBlock->sRightIndent);
312f5736e95SDavid du Colombier NO_DBG_DEC_C(pStyleBlock->bNumPause, pStyleBlock->bNumPause);
313f5736e95SDavid du Colombier NO_DBG_DEC_C(pStyleBlock->usIstd != 0, pStyleBlock->usIstd);
314f5736e95SDavid du Colombier NO_DBG_DEC_C(pStyleBlock->usStartAt != 1, pStyleBlock->usStartAt);
315f5736e95SDavid du Colombier NO_DBG_DEC_C(pStyleBlock->usAfterIndent != 0,
316f5736e95SDavid du Colombier pStyleBlock->usAfterIndent);
317f5736e95SDavid du Colombier NO_DBG_DEC_C(pStyleBlock->ucAlignment != 0, pStyleBlock->ucAlignment);
318f5736e95SDavid du Colombier NO_DBG_DEC(pStyleBlock->ucNFC);
319f5736e95SDavid du Colombier NO_DBG_HEX(pStyleBlock->usListChar);
320f5736e95SDavid du Colombier
321f5736e95SDavid du Colombier if (pStyleLast != NULL &&
322f5736e95SDavid du Colombier pStyleLast->tInfo.ulFileOffset == pStyleBlock->ulFileOffset) {
323f5736e95SDavid du Colombier /*
324f5736e95SDavid du Colombier * If two consecutive styles share the same
325f5736e95SDavid du Colombier * offset, remember only the last style
326f5736e95SDavid du Colombier */
327f5736e95SDavid du Colombier fail(pStyleLast->pNext != NULL);
328f5736e95SDavid du Colombier pStyleLast->tInfo = *pStyleBlock;
329f5736e95SDavid du Colombier /* Correct the values where needed */
330f5736e95SDavid du Colombier vCorrectStyleValues(&pStyleLast->tInfo);
331f5736e95SDavid du Colombier return;
332f5736e95SDavid du Colombier }
333f5736e95SDavid du Colombier
334f5736e95SDavid du Colombier /* Create list member */
335f5736e95SDavid du Colombier pListMember = xmalloc(sizeof(style_mem_type));
336f5736e95SDavid du Colombier /* Fill the list member */
337f5736e95SDavid du Colombier pListMember->tInfo = *pStyleBlock;
338f5736e95SDavid du Colombier pListMember->pNext = NULL;
339f5736e95SDavid du Colombier /* Add the sequence number */
340f5736e95SDavid du Colombier pListMember->ulSequenceNumber =
341f5736e95SDavid du Colombier ulGetSeqNumber(pListMember->tInfo.ulFileOffset);
342f5736e95SDavid du Colombier /* Correct the values where needed */
343f5736e95SDavid du Colombier vCorrectStyleValues(&pListMember->tInfo);
344f5736e95SDavid du Colombier /* Add the new member to the list */
345f5736e95SDavid du Colombier if (pAnchor == NULL) {
346f5736e95SDavid du Colombier pAnchor = pListMember;
347f5736e95SDavid du Colombier /* For efficiency */
348f5736e95SDavid du Colombier pMidPtr = pAnchor;
349f5736e95SDavid du Colombier bMoveMidPtr = FALSE;
350f5736e95SDavid du Colombier bInSequence = TRUE;
351f5736e95SDavid du Colombier } else {
352f5736e95SDavid du Colombier fail(pStyleLast == NULL);
353f5736e95SDavid du Colombier pStyleLast->pNext = pListMember;
354f5736e95SDavid du Colombier /* For efficiency */
355f5736e95SDavid du Colombier if (bMoveMidPtr) {
356f5736e95SDavid du Colombier pMidPtr = pMidPtr->pNext;
357f5736e95SDavid du Colombier bMoveMidPtr = FALSE;
358f5736e95SDavid du Colombier } else {
359f5736e95SDavid du Colombier bMoveMidPtr = TRUE;
360f5736e95SDavid du Colombier }
361f5736e95SDavid du Colombier if (bInSequence) {
362f5736e95SDavid du Colombier bInSequence = pListMember->ulSequenceNumber >
363f5736e95SDavid du Colombier pStyleLast->ulSequenceNumber;
364f5736e95SDavid du Colombier }
365f5736e95SDavid du Colombier }
366f5736e95SDavid du Colombier pStyleLast = pListMember;
367f5736e95SDavid du Colombier } /* end of vAdd2StyleInfoList */
368f5736e95SDavid du Colombier
369f5736e95SDavid du Colombier /*
370f5736e95SDavid du Colombier * Get the record that follows the given recored in the Style Information List
371f5736e95SDavid du Colombier */
372f5736e95SDavid du Colombier const style_block_type *
pGetNextStyleInfoListItem(const style_block_type * pCurr)373f5736e95SDavid du Colombier pGetNextStyleInfoListItem(const style_block_type *pCurr)
374f5736e95SDavid du Colombier {
375f5736e95SDavid du Colombier const style_mem_type *pRecord;
376f5736e95SDavid du Colombier size_t tOffset;
377f5736e95SDavid du Colombier
378f5736e95SDavid du Colombier if (pCurr == NULL) {
379f5736e95SDavid du Colombier if (pAnchor == NULL) {
380f5736e95SDavid du Colombier /* There are no records */
381f5736e95SDavid du Colombier return NULL;
382f5736e95SDavid du Colombier }
383f5736e95SDavid du Colombier /* The first record is the only one without a predecessor */
384f5736e95SDavid du Colombier return &pAnchor->tInfo;
385f5736e95SDavid du Colombier }
386f5736e95SDavid du Colombier tOffset = offsetof(style_mem_type, tInfo);
387f5736e95SDavid du Colombier /* Many casts to prevent alignment warnings */
388f5736e95SDavid du Colombier pRecord = (style_mem_type *)(void *)((char *)pCurr - tOffset);
389f5736e95SDavid du Colombier fail(pCurr != &pRecord->tInfo);
390f5736e95SDavid du Colombier if (pRecord->pNext == NULL) {
391f5736e95SDavid du Colombier /* The last record has no successor */
392f5736e95SDavid du Colombier return NULL;
393f5736e95SDavid du Colombier }
394f5736e95SDavid du Colombier return &pRecord->pNext->tInfo;
395f5736e95SDavid du Colombier } /* end of pGetNextStyleInfoListItem */
396f5736e95SDavid du Colombier
397f5736e95SDavid du Colombier /*
398*25b329d5SDavid du Colombier * Get the next text style
399*25b329d5SDavid du Colombier */
400*25b329d5SDavid du Colombier const style_block_type *
pGetNextTextStyle(const style_block_type * pCurr)401*25b329d5SDavid du Colombier pGetNextTextStyle(const style_block_type *pCurr)
402*25b329d5SDavid du Colombier {
403*25b329d5SDavid du Colombier const style_block_type *pRecord;
404*25b329d5SDavid du Colombier
405*25b329d5SDavid du Colombier pRecord = pCurr;
406*25b329d5SDavid du Colombier do {
407*25b329d5SDavid du Colombier pRecord = pGetNextStyleInfoListItem(pRecord);
408*25b329d5SDavid du Colombier } while (pRecord != NULL &&
409*25b329d5SDavid du Colombier (pRecord->eListID == hdrftr_list ||
410*25b329d5SDavid du Colombier pRecord->eListID == macro_list ||
411*25b329d5SDavid du Colombier pRecord->eListID == annotation_list));
412*25b329d5SDavid du Colombier return pRecord;
413*25b329d5SDavid du Colombier } /* end of pGetNextTextStyle */
414*25b329d5SDavid du Colombier
415*25b329d5SDavid du Colombier /*
416f5736e95SDavid du Colombier * usGetIstd - get the istd that belongs to the given file offset
417f5736e95SDavid du Colombier */
418f5736e95SDavid du Colombier USHORT
usGetIstd(ULONG ulFileOffset)419f5736e95SDavid du Colombier usGetIstd(ULONG ulFileOffset)
420f5736e95SDavid du Colombier {
421f5736e95SDavid du Colombier const style_mem_type *pCurr, *pBest, *pStart;
422f5736e95SDavid du Colombier ULONG ulSeq, ulBest;
423f5736e95SDavid du Colombier
424f5736e95SDavid du Colombier ulSeq = ulGetSeqNumber(ulFileOffset);
425f5736e95SDavid du Colombier if (ulSeq == FC_INVALID) {
426f5736e95SDavid du Colombier return ISTD_NORMAL;
427f5736e95SDavid du Colombier }
428f5736e95SDavid du Colombier NO_DBG_HEX(ulFileOffset);
429f5736e95SDavid du Colombier NO_DBG_DEC(ulSeq);
430f5736e95SDavid du Colombier
431f5736e95SDavid du Colombier if (bInSequence &&
432f5736e95SDavid du Colombier pMidPtr != NULL &&
433f5736e95SDavid du Colombier ulSeq > pMidPtr->ulSequenceNumber) {
434f5736e95SDavid du Colombier /* The istd is in the second half of the chained list */
435f5736e95SDavid du Colombier pStart = pMidPtr;
436f5736e95SDavid du Colombier } else {
437f5736e95SDavid du Colombier pStart = pAnchor;
438f5736e95SDavid du Colombier }
439f5736e95SDavid du Colombier
440f5736e95SDavid du Colombier pBest = NULL;
441f5736e95SDavid du Colombier ulBest = 0;
442f5736e95SDavid du Colombier for (pCurr = pStart; pCurr != NULL; pCurr = pCurr->pNext) {
443f5736e95SDavid du Colombier if (pCurr->ulSequenceNumber != FC_INVALID &&
444f5736e95SDavid du Colombier (pBest == NULL || pCurr->ulSequenceNumber > ulBest) &&
445f5736e95SDavid du Colombier pCurr->ulSequenceNumber <= ulSeq) {
446f5736e95SDavid du Colombier pBest = pCurr;
447f5736e95SDavid du Colombier ulBest = pCurr->ulSequenceNumber;
448f5736e95SDavid du Colombier }
449f5736e95SDavid du Colombier if (bInSequence && pCurr->ulSequenceNumber > ulSeq) {
450f5736e95SDavid du Colombier break;
451f5736e95SDavid du Colombier }
452f5736e95SDavid du Colombier }
453f5736e95SDavid du Colombier NO_DBG_DEC(ulBest);
454f5736e95SDavid du Colombier
455f5736e95SDavid du Colombier if (pBest == NULL) {
456f5736e95SDavid du Colombier return ISTD_NORMAL;
457f5736e95SDavid du Colombier }
458f5736e95SDavid du Colombier
459f5736e95SDavid du Colombier NO_DBG_DEC(pBest->tInfo.usIstd);
460f5736e95SDavid du Colombier return pBest->tInfo.usIstd;
461f5736e95SDavid du Colombier } /* end of usGetIstd */
462f5736e95SDavid du Colombier
463f5736e95SDavid du Colombier /*
464f5736e95SDavid du Colombier * bStyleImpliesList - does style info implies being part of a list
465f5736e95SDavid du Colombier *
466f5736e95SDavid du Colombier * Decide whether the style information implies that the given paragraph is
467f5736e95SDavid du Colombier * part of a list
468f5736e95SDavid du Colombier *
469f5736e95SDavid du Colombier * Returns TRUE when the paragraph is part of a list, otherwise FALSE
470f5736e95SDavid du Colombier */
471f5736e95SDavid du Colombier BOOL
bStyleImpliesList(const style_block_type * pStyle,int iWordVersion)472f5736e95SDavid du Colombier bStyleImpliesList(const style_block_type *pStyle, int iWordVersion)
473f5736e95SDavid du Colombier {
474f5736e95SDavid du Colombier fail(pStyle == NULL);
475f5736e95SDavid du Colombier fail(iWordVersion < 0);
476f5736e95SDavid du Colombier
477f5736e95SDavid du Colombier if (pStyle->usIstd >= 1 && pStyle->usIstd <= 9) {
478f5736e95SDavid du Colombier /* These are heading levels */
479f5736e95SDavid du Colombier return FALSE;
480f5736e95SDavid du Colombier }
481f5736e95SDavid du Colombier if (iWordVersion < 8) {
482f5736e95SDavid du Colombier /* Check for old style lists */
483f5736e95SDavid du Colombier return pStyle->ucNumLevel != 0;
484f5736e95SDavid du Colombier }
485f5736e95SDavid du Colombier /* Check for new style lists */
486f5736e95SDavid du Colombier return pStyle->usListIndex != 0;
487f5736e95SDavid du Colombier } /* end of bStyleImpliesList */
488