3 * Copyright (C) 1998-2002 A.J. van Os; Released under GPL
6 * Build, read and destroy a list of Word style information
16 * Private structure to hide the way the information
17 * is stored from the rest of the program
19 typedef struct style_mem_tag
{
20 style_block_type tInfo
;
21 ULONG ulSequenceNumber
;
22 struct style_mem_tag
*pNext
;
25 /* Variables needed to write the Style Information List */
26 static style_mem_type
*pAnchor
= NULL
;
27 static style_mem_type
*pStyleLast
= NULL
;
28 /* Values for efficiency reasons */
29 static const style_mem_type
*pMidPtr
= NULL
;
30 static BOOL bMoveMidPtr
= FALSE
;
31 static BOOL bInSequence
= TRUE
;
35 * vDestroyStyleInfoList - destroy the Style Information List
38 vDestroyStyleInfoList(void)
40 style_mem_type
*pCurr
, *pNext
;
42 DBG_MSG("vDestroyStyleInfoList");
44 /* Free the Style Information List */
46 while (pCurr
!= NULL
) {
52 /* Reset all control variables */
57 } /* end of vDestroyStyleInfoList */
60 * ucChooseListCharacter - choose our list character
63 ucChooseListCharacter(UCHAR ucNFC
, UCHAR ucListCharacter
)
65 if (isprint(ucListCharacter
)) {
66 return ucListCharacter
;
68 if (ucNFC
== LIST_BULLETS
) {
69 switch (ucListCharacter
) {
72 return (UCHAR
)OUR_BULLET
;
74 return (UCHAR
)OUR_DIAMOND
;
84 DBG_HEX(ucListCharacter
);
85 return (UCHAR
)OUR_BULLET
;
89 } /* end of ucChooseListCharacter */
92 * eGetNumType - get level type from level number
95 eGetNumType(UCHAR ucLevelNumber
)
97 switch (ucLevelNumber
) {
99 return level_type_numbering
;
101 return level_type_sequence
;
103 return level_type_pause
;
105 if ((int)ucLevelNumber
>= 1 && (int)ucLevelNumber
<= 9) {
106 return level_type_outline
;
108 return level_type_none
;
110 } /* end of eGetNumType */
113 * vCorrectStyleValues - correct style values that Antiword can't use
116 vCorrectStyleValues(style_block_type
*pStyleBlock
)
118 if (pStyleBlock
->usBeforeIndent
> 0x7fff) {
119 pStyleBlock
->usBeforeIndent
= 0;
120 } else if (pStyleBlock
->usBeforeIndent
> 2160) {
121 /* 2160 twips = 1.5 inches or 38.1 mm */
122 DBG_DEC(pStyleBlock
->usBeforeIndent
);
123 pStyleBlock
->usBeforeIndent
= 2160;
125 if (pStyleBlock
->usIstd
>= 1 &&
126 pStyleBlock
->usIstd
<= 9 &&
127 pStyleBlock
->usBeforeIndent
< HEADING_GAP
) {
128 NO_DBG_DEC(pStyleBlock
->usBeforeIndent
);
129 pStyleBlock
->usBeforeIndent
= HEADING_GAP
;
131 if (pStyleBlock
->usAfterIndent
> 0x7fff) {
132 pStyleBlock
->usAfterIndent
= 0;
133 } else if (pStyleBlock
->usAfterIndent
> 2160) {
134 /* 2160 twips = 1.5 inches or 38.1 mm */
135 DBG_DEC(pStyleBlock
->usAfterIndent
);
136 pStyleBlock
->usAfterIndent
= 2160;
138 if (pStyleBlock
->usIstd
>= 1 &&
139 pStyleBlock
->usIstd
<= 9 &&
140 pStyleBlock
->usAfterIndent
< HEADING_GAP
) {
141 NO_DBG_DEC(pStyleBlock
->usAfterIndent
);
142 pStyleBlock
->usAfterIndent
= HEADING_GAP
;
144 if (pStyleBlock
->sLeftIndent
< 0) {
145 pStyleBlock
->sLeftIndent
= 0;
147 if (pStyleBlock
->sRightIndent
> 0) {
148 pStyleBlock
->sRightIndent
= 0;
150 pStyleBlock
->ucListCharacter
=
151 ucChooseListCharacter(
153 pStyleBlock
->ucListCharacter
);
154 } /* end of vCorrectStyleValues */
157 * vAdd2StyleInfoList - Add an element to the Style Information List
160 vAdd2StyleInfoList(const style_block_type
*pStyleBlock
)
162 style_mem_type
*pListMember
;
164 fail(pStyleBlock
== NULL
);
166 NO_DBG_MSG("bAdd2StyleInfoList");
168 if (pStyleBlock
->ulFileOffset
== FC_INVALID
) {
169 NO_DBG_DEC(pStyleBlock
->usIstd
);
173 NO_DBG_HEX(pStyleBlock
->ulFileOffset
);
174 NO_DBG_DEC_C(pStyleBlock
->sLeftIndent
!= 0,
175 pStyleBlock
->sLeftIndent
);
176 NO_DBG_DEC_C(pStyleBlock
->sRightIndent
!= 0,
177 pStyleBlock
->sRightIndent
);
178 NO_DBG_DEC_C(pStyleBlock
->bInList
, pStyleBlock
->bInList
);
179 NO_DBG_DEC_C(pStyleBlock
->bNumPause
, pStyleBlock
->bNumPause
);
180 NO_DBG_DEC_C(pStyleBlock
->usIstd
!= 0, pStyleBlock
->usIstd
);
181 NO_DBG_DEC_C(pStyleBlock
->usStartAt
!= 0, pStyleBlock
->usStartAt
);
182 NO_DBG_DEC_C(pStyleBlock
->usAfterIndent
!= 0,
183 pStyleBlock
->usAfterIndent
);
184 NO_DBG_DEC_C(pStyleBlock
->ucAlignment
!= 0, pStyleBlock
->ucAlignment
);
185 NO_DBG_DEC_C(pStyleBlock
->bInList
, pStyleBlock
->ucNFC
);
186 NO_DBG_HEX_C(pStyleBlock
->bInList
, pStyleBlock
->ucListCharacter
);
187 NO_DBG_DEC_C(pStyleBlock
->ucNFC
!= LIST_BULLETS
,
188 pStyleBlock
->usStartAt
);
190 if (pStyleLast
!= NULL
&&
191 pStyleLast
->tInfo
.ulFileOffset
== pStyleBlock
->ulFileOffset
) {
193 * If two consecutive styles share the same
194 * offset, remember only the last style
196 fail(pStyleLast
->pNext
!= NULL
);
197 pStyleLast
->tInfo
= *pStyleBlock
;
201 /* Create list member */
202 pListMember
= xmalloc(sizeof(style_mem_type
));
203 /* Fill the list member */
204 pListMember
->tInfo
= *pStyleBlock
;
205 pListMember
->pNext
= NULL
;
206 /* Add the sequence number */
207 pListMember
->ulSequenceNumber
=
208 ulGetSeqNumber(pListMember
->tInfo
.ulFileOffset
);
209 /* Correct the values where needed */
210 vCorrectStyleValues(&pListMember
->tInfo
);
211 /* Add the new member to the list */
212 if (pAnchor
== NULL
) {
213 pAnchor
= pListMember
;
219 fail(pStyleLast
== NULL
);
220 pStyleLast
->pNext
= pListMember
;
223 pMidPtr
= pMidPtr
->pNext
;
229 bInSequence
= pListMember
->ulSequenceNumber
>
230 pStyleLast
->ulSequenceNumber
;
233 pStyleLast
= pListMember
;
234 } /* end of vAdd2StyleInfoList */
237 * Get the record that follows the given recored in the Style Information List
239 const style_block_type
*
240 pGetNextStyleInfoListItem(const style_block_type
*pCurr
)
242 const style_mem_type
*pRecord
;
246 if (pAnchor
== NULL
) {
247 /* There are no records */
250 /* The first record is the only one without a predecessor */
251 return &pAnchor
->tInfo
;
253 tOffset
= offsetof(style_mem_type
, tInfo
);
254 /* Many casts to prevent alignment warnings */
255 pRecord
= (style_mem_type
*)(void *)((char *)pCurr
- tOffset
);
256 fail(pCurr
!= &pRecord
->tInfo
);
257 if (pRecord
->pNext
== NULL
) {
258 /* The last record has no successor */
261 return &pRecord
->pNext
->tInfo
;
262 } /* end of pGetNextStyleInfoListItem */
265 * usGetIstd - get the istd that belongs to the given file offset
268 usGetIstd(ULONG ulFileOffset
)
270 const style_mem_type
*pCurr
, *pBest
, *pStart
;
273 ulSeq
= ulGetSeqNumber(ulFileOffset
);
274 if (ulSeq
== FC_INVALID
) {
277 NO_DBG_HEX(ulFileOffset
);
282 ulSeq
> pMidPtr
->ulSequenceNumber
) {
283 /* The istd is in the second half of the chained list */
291 for (pCurr
= pStart
; pCurr
!= NULL
; pCurr
= pCurr
->pNext
) {
292 if (pCurr
->ulSequenceNumber
!= FC_INVALID
&&
293 (pBest
== NULL
|| pCurr
->ulSequenceNumber
> ulBest
) &&
294 pCurr
->ulSequenceNumber
<= ulSeq
) {
296 ulBest
= pCurr
->ulSequenceNumber
;
298 if (bInSequence
&& pCurr
->ulSequenceNumber
> ulSeq
) {
308 NO_DBG_DEC(pBest
->tInfo
.usIstd
);
309 return pBest
->tInfo
.usIstd
;
310 } /* end of usGetIstd */