1f5736e95SDavid du Colombier /*
2f5736e95SDavid du Colombier * word2text.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 * MS Word to "text" functions
7f5736e95SDavid du Colombier */
8f5736e95SDavid du Colombier
9f5736e95SDavid du Colombier #include <stdio.h>
10f5736e95SDavid du Colombier #include <stdlib.h>
11f5736e95SDavid du Colombier #include <string.h>
12f5736e95SDavid du Colombier #include <ctype.h>
13f5736e95SDavid du Colombier #if defined(__riscos)
14*25b329d5SDavid du Colombier #include "DeskLib:Hourglass.h"
15*25b329d5SDavid du Colombier #include "drawfile.h"
16f5736e95SDavid du Colombier #endif /* __riscos */
17f5736e95SDavid du Colombier #include "antiword.h"
18f5736e95SDavid du Colombier
19f5736e95SDavid du Colombier
20f5736e95SDavid du Colombier #define INITIAL_SIZE 40
21f5736e95SDavid du Colombier #define EXTENTION_SIZE 20
22f5736e95SDavid du Colombier
23f5736e95SDavid du Colombier
24f5736e95SDavid du Colombier /* Macros to make sure all such statements will be identical */
25f5736e95SDavid du Colombier #define OUTPUT_LINE() \
26f5736e95SDavid du Colombier do {\
27f5736e95SDavid du Colombier vAlign2Window(pDiag, pAnchor, lWidthMax, ucAlignment);\
28*25b329d5SDavid du Colombier TRACE_MSG("after vAlign2Window");\
29f5736e95SDavid du Colombier pAnchor = pStartNewOutput(pAnchor, NULL);\
30f5736e95SDavid du Colombier pOutput = pAnchor;\
31f5736e95SDavid du Colombier } while(0)
32f5736e95SDavid du Colombier
33f5736e95SDavid du Colombier #define RESET_LINE() \
34f5736e95SDavid du Colombier do {\
35f5736e95SDavid du Colombier pAnchor = pStartNewOutput(pAnchor, NULL);\
36f5736e95SDavid du Colombier pOutput = pAnchor;\
37f5736e95SDavid du Colombier } while(0)
38f5736e95SDavid du Colombier
39f5736e95SDavid du Colombier #if defined(__riscos)
40f5736e95SDavid du Colombier /* Length of the document in characters */
41f5736e95SDavid du Colombier static ULONG ulDocumentLength;
42f5736e95SDavid du Colombier /* Number of characters processed so far */
43f5736e95SDavid du Colombier static ULONG ulCharCounter;
44f5736e95SDavid du Colombier static int iCurrPct, iPrevPct;
45f5736e95SDavid du Colombier #endif /* __riscos */
46f5736e95SDavid du Colombier /* The document is in the format belonging to this version of Word */
47f5736e95SDavid du Colombier static int iWordVersion = -1;
48*25b329d5SDavid du Colombier /* Special treatment for files from Word 4/5/6 on an Apple Macintosh */
49f5736e95SDavid du Colombier static BOOL bOldMacFile = FALSE;
50f5736e95SDavid du Colombier /* Section Information */
51f5736e95SDavid du Colombier static const section_block_type *pSection = NULL;
52f5736e95SDavid du Colombier static const section_block_type *pSectionNext = NULL;
53f5736e95SDavid du Colombier /* All the (command line) options */
54f5736e95SDavid du Colombier static options_type tOptions;
55f5736e95SDavid du Colombier /* Needed for reading a complete table row */
56f5736e95SDavid du Colombier static const row_block_type *pRowInfo = NULL;
57f5736e95SDavid du Colombier static BOOL bStartRow = FALSE;
58f5736e95SDavid du Colombier static BOOL bEndRowNorm = FALSE;
59f5736e95SDavid du Colombier static BOOL bEndRowFast = FALSE;
60f5736e95SDavid du Colombier static BOOL bIsTableRow = FALSE;
61f5736e95SDavid du Colombier /* Index of the next style and font information */
62f5736e95SDavid du Colombier static USHORT usIstdNext = ISTD_NORMAL;
63f5736e95SDavid du Colombier /* Needed for finding the start of a style */
64f5736e95SDavid du Colombier static const style_block_type *pStyleInfo = NULL;
65f5736e95SDavid du Colombier static style_block_type tStyleNext;
66f5736e95SDavid du Colombier static BOOL bStartStyle = FALSE;
67f5736e95SDavid du Colombier static BOOL bStartStyleNext = FALSE;
68f5736e95SDavid du Colombier /* Needed for finding the start of a font */
69f5736e95SDavid du Colombier static const font_block_type *pFontInfo = NULL;
70f5736e95SDavid du Colombier static font_block_type tFontNext;
71f5736e95SDavid du Colombier static BOOL bStartFont = FALSE;
72f5736e95SDavid du Colombier static BOOL bStartFontNext = FALSE;
73f5736e95SDavid du Colombier /* Needed for finding an image */
74f5736e95SDavid du Colombier static ULONG ulFileOffsetImage = FC_INVALID;
75f5736e95SDavid du Colombier
76f5736e95SDavid du Colombier
77f5736e95SDavid du Colombier /*
78f5736e95SDavid du Colombier * vUpdateCounters - Update the counters for the hourglass
79f5736e95SDavid du Colombier */
80f5736e95SDavid du Colombier static void
vUpdateCounters(void)81f5736e95SDavid du Colombier vUpdateCounters(void)
82f5736e95SDavid du Colombier {
83f5736e95SDavid du Colombier #if defined(__riscos)
84f5736e95SDavid du Colombier ulCharCounter++;
85f5736e95SDavid du Colombier iCurrPct = (int)((ulCharCounter * 100) / ulDocumentLength);
86f5736e95SDavid du Colombier if (iCurrPct != iPrevPct) {
87*25b329d5SDavid du Colombier Hourglass_Percentage(iCurrPct);
88f5736e95SDavid du Colombier iPrevPct = iCurrPct;
89f5736e95SDavid du Colombier }
90f5736e95SDavid du Colombier #endif /* __riscos */
91f5736e95SDavid du Colombier } /* end of vUpdateCounters */
92f5736e95SDavid du Colombier
93f5736e95SDavid du Colombier /*
94f5736e95SDavid du Colombier * bOutputContainsText - see if the output contains more than white space
95f5736e95SDavid du Colombier */
96*25b329d5SDavid du Colombier BOOL
bOutputContainsText(const output_type * pAnchor)97*25b329d5SDavid du Colombier bOutputContainsText(const output_type *pAnchor)
98f5736e95SDavid du Colombier {
99*25b329d5SDavid du Colombier const output_type *pCurr;
100f5736e95SDavid du Colombier size_t tIndex;
101f5736e95SDavid du Colombier
102f5736e95SDavid du Colombier fail(pAnchor == NULL);
103f5736e95SDavid du Colombier
104f5736e95SDavid du Colombier for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
105f5736e95SDavid du Colombier fail(pCurr->lStringWidth < 0);
106f5736e95SDavid du Colombier for (tIndex = 0; tIndex < pCurr->tNextFree; tIndex++) {
107f5736e95SDavid du Colombier if (isspace((int)(UCHAR)pCurr->szStorage[tIndex])) {
108f5736e95SDavid du Colombier continue;
109f5736e95SDavid du Colombier }
110f5736e95SDavid du Colombier #if defined(DEBUG)
111f5736e95SDavid du Colombier if (pCurr->szStorage[tIndex] == FILLER_CHAR) {
112f5736e95SDavid du Colombier continue;
113f5736e95SDavid du Colombier }
114f5736e95SDavid du Colombier #endif /* DEBUG */
115f5736e95SDavid du Colombier return TRUE;
116f5736e95SDavid du Colombier }
117f5736e95SDavid du Colombier }
118f5736e95SDavid du Colombier return FALSE;
119f5736e95SDavid du Colombier } /* end of bOutputContainsText */
120f5736e95SDavid du Colombier
121f5736e95SDavid du Colombier /*
122f5736e95SDavid du Colombier * lTotalStringWidth - compute the total width of the output string
123f5736e95SDavid du Colombier */
124f5736e95SDavid du Colombier static long
lTotalStringWidth(const output_type * pAnchor)125*25b329d5SDavid du Colombier lTotalStringWidth(const output_type *pAnchor)
126f5736e95SDavid du Colombier {
127*25b329d5SDavid du Colombier const output_type *pCurr;
128f5736e95SDavid du Colombier long lTotal;
129f5736e95SDavid du Colombier
130f5736e95SDavid du Colombier lTotal = 0;
131f5736e95SDavid du Colombier for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
132f5736e95SDavid du Colombier DBG_DEC_C(pCurr->lStringWidth < 0, pCurr->lStringWidth);
133f5736e95SDavid du Colombier fail(pCurr->lStringWidth < 0);
134f5736e95SDavid du Colombier lTotal += pCurr->lStringWidth;
135f5736e95SDavid du Colombier }
136f5736e95SDavid du Colombier return lTotal;
137f5736e95SDavid du Colombier } /* end of lTotalStringWidth */
138f5736e95SDavid du Colombier
139f5736e95SDavid du Colombier /*
140f5736e95SDavid du Colombier * vStoreByte - store one byte
141f5736e95SDavid du Colombier */
142f5736e95SDavid du Colombier static void
vStoreByte(UCHAR ucChar,output_type * pOutput)143f5736e95SDavid du Colombier vStoreByte(UCHAR ucChar, output_type *pOutput)
144f5736e95SDavid du Colombier {
145f5736e95SDavid du Colombier fail(pOutput == NULL);
146f5736e95SDavid du Colombier
147f5736e95SDavid du Colombier if (ucChar == 0) {
148f5736e95SDavid du Colombier pOutput->szStorage[pOutput->tNextFree] = '\0';
149f5736e95SDavid du Colombier return;
150f5736e95SDavid du Colombier }
151f5736e95SDavid du Colombier
152f5736e95SDavid du Colombier while (pOutput->tNextFree + 2 > pOutput->tStorageSize) {
153f5736e95SDavid du Colombier pOutput->tStorageSize += EXTENTION_SIZE;
154f5736e95SDavid du Colombier pOutput->szStorage = xrealloc(pOutput->szStorage,
155f5736e95SDavid du Colombier pOutput->tStorageSize);
156f5736e95SDavid du Colombier }
157f5736e95SDavid du Colombier pOutput->szStorage[pOutput->tNextFree] = (char)ucChar;
158f5736e95SDavid du Colombier pOutput->szStorage[pOutput->tNextFree + 1] = '\0';
159f5736e95SDavid du Colombier pOutput->tNextFree++;
160f5736e95SDavid du Colombier } /* end of vStoreByte */
161f5736e95SDavid du Colombier
162f5736e95SDavid du Colombier /*
163f5736e95SDavid du Colombier * vStoreChar - store a character as one or more bytes
164f5736e95SDavid du Colombier */
165f5736e95SDavid du Colombier static void
vStoreChar(ULONG ulChar,BOOL bChangeAllowed,output_type * pOutput)166f5736e95SDavid du Colombier vStoreChar(ULONG ulChar, BOOL bChangeAllowed, output_type *pOutput)
167f5736e95SDavid du Colombier {
168f5736e95SDavid du Colombier char szResult[4];
169f5736e95SDavid du Colombier size_t tIndex, tLen;
170f5736e95SDavid du Colombier
171f5736e95SDavid du Colombier fail(pOutput == NULL);
172f5736e95SDavid du Colombier
173*25b329d5SDavid du Colombier if (tOptions.eEncoding == encoding_utf_8 && bChangeAllowed) {
174f5736e95SDavid du Colombier DBG_HEX_C(ulChar > 0xffff, ulChar);
175f5736e95SDavid du Colombier fail(ulChar > 0xffff);
176f5736e95SDavid du Colombier tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult));
177f5736e95SDavid du Colombier for (tIndex = 0; tIndex < tLen; tIndex++) {
178f5736e95SDavid du Colombier vStoreByte((UCHAR)szResult[tIndex], pOutput);
179f5736e95SDavid du Colombier }
180f5736e95SDavid du Colombier } else {
181f5736e95SDavid du Colombier DBG_HEX_C(ulChar > 0xff, ulChar);
182f5736e95SDavid du Colombier fail(ulChar > 0xff);
183f5736e95SDavid du Colombier vStoreByte((UCHAR)ulChar, pOutput);
184f5736e95SDavid du Colombier tLen = 1;
185f5736e95SDavid du Colombier }
186f5736e95SDavid du Colombier pOutput->lStringWidth += lComputeStringWidth(
187f5736e95SDavid du Colombier pOutput->szStorage + pOutput->tNextFree - tLen,
188f5736e95SDavid du Colombier tLen,
189f5736e95SDavid du Colombier pOutput->tFontRef,
190f5736e95SDavid du Colombier pOutput->usFontSize);
191f5736e95SDavid du Colombier } /* end of vStoreChar */
192f5736e95SDavid du Colombier
193f5736e95SDavid du Colombier /*
194f5736e95SDavid du Colombier * vStoreCharacter - store one character
195f5736e95SDavid du Colombier */
196f5736e95SDavid du Colombier static void
vStoreCharacter(ULONG ulChar,output_type * pOutput)197f5736e95SDavid du Colombier vStoreCharacter(ULONG ulChar, output_type *pOutput)
198f5736e95SDavid du Colombier {
199f5736e95SDavid du Colombier vStoreChar(ulChar, TRUE, pOutput);
200f5736e95SDavid du Colombier } /* end of vStoreCharacter */
201f5736e95SDavid du Colombier
202f5736e95SDavid du Colombier /*
203f5736e95SDavid du Colombier * vStoreString - store a string
204f5736e95SDavid du Colombier */
205f5736e95SDavid du Colombier static void
vStoreString(const char * szString,size_t tStringLength,output_type * pOutput)206f5736e95SDavid du Colombier vStoreString(const char *szString, size_t tStringLength, output_type *pOutput)
207f5736e95SDavid du Colombier {
208f5736e95SDavid du Colombier size_t tIndex;
209f5736e95SDavid du Colombier
210f5736e95SDavid du Colombier fail(szString == NULL || pOutput == NULL);
211f5736e95SDavid du Colombier
212f5736e95SDavid du Colombier for (tIndex = 0; tIndex < tStringLength; tIndex++) {
213*25b329d5SDavid du Colombier vStoreCharacter((ULONG)(UCHAR)szString[tIndex], pOutput);
214f5736e95SDavid du Colombier }
215f5736e95SDavid du Colombier } /* end of vStoreString */
216f5736e95SDavid du Colombier
217f5736e95SDavid du Colombier /*
218f5736e95SDavid du Colombier * vStoreNumberAsDecimal - store a number as a decimal number
219f5736e95SDavid du Colombier */
220f5736e95SDavid du Colombier static void
vStoreNumberAsDecimal(UINT uiNumber,output_type * pOutput)221f5736e95SDavid du Colombier vStoreNumberAsDecimal(UINT uiNumber, output_type *pOutput)
222f5736e95SDavid du Colombier {
223f5736e95SDavid du Colombier size_t tLen;
224f5736e95SDavid du Colombier char szString[3 * sizeof(UINT) + 1];
225f5736e95SDavid du Colombier
226f5736e95SDavid du Colombier fail(uiNumber == 0);
227f5736e95SDavid du Colombier fail(pOutput == NULL);
228f5736e95SDavid du Colombier
229f5736e95SDavid du Colombier tLen = (size_t)sprintf(szString, "%u", uiNumber);
230f5736e95SDavid du Colombier vStoreString(szString, tLen, pOutput);
231f5736e95SDavid du Colombier } /* end of vStoreNumberAsDecimal */
232f5736e95SDavid du Colombier
233f5736e95SDavid du Colombier /*
234f5736e95SDavid du Colombier * vStoreNumberAsRoman - store a number as a roman numerical
235f5736e95SDavid du Colombier */
236f5736e95SDavid du Colombier static void
vStoreNumberAsRoman(UINT uiNumber,output_type * pOutput)237f5736e95SDavid du Colombier vStoreNumberAsRoman(UINT uiNumber, output_type *pOutput)
238f5736e95SDavid du Colombier {
239f5736e95SDavid du Colombier size_t tLen;
240f5736e95SDavid du Colombier char szString[15];
241f5736e95SDavid du Colombier
242f5736e95SDavid du Colombier fail(uiNumber == 0);
243f5736e95SDavid du Colombier fail(pOutput == NULL);
244f5736e95SDavid du Colombier
245f5736e95SDavid du Colombier tLen = tNumber2Roman(uiNumber, FALSE, szString);
246f5736e95SDavid du Colombier vStoreString(szString, tLen, pOutput);
247f5736e95SDavid du Colombier } /* end of vStoreNumberAsRoman */
248f5736e95SDavid du Colombier
249f5736e95SDavid du Colombier /*
250f5736e95SDavid du Colombier * vStoreStyle - store a style
251f5736e95SDavid du Colombier */
252f5736e95SDavid du Colombier static void
vStoreStyle(diagram_type * pDiag,output_type * pOutput,const style_block_type * pStyle)253f5736e95SDavid du Colombier vStoreStyle(diagram_type *pDiag, output_type *pOutput,
254f5736e95SDavid du Colombier const style_block_type *pStyle)
255f5736e95SDavid du Colombier {
256f5736e95SDavid du Colombier size_t tLen;
257f5736e95SDavid du Colombier char szString[120];
258f5736e95SDavid du Colombier
259f5736e95SDavid du Colombier fail(pDiag == NULL);
260f5736e95SDavid du Colombier fail(pOutput == NULL);
261f5736e95SDavid du Colombier fail(pStyle == NULL);
262f5736e95SDavid du Colombier
263f5736e95SDavid du Colombier if (tOptions.eConversionType == conversion_xml) {
264f5736e95SDavid du Colombier vSetHeaders(pDiag, pStyle->usIstd);
265f5736e95SDavid du Colombier } else {
266*25b329d5SDavid du Colombier tLen = tStyle2Window(szString, sizeof(szString),
267*25b329d5SDavid du Colombier pStyle, pSection);
268f5736e95SDavid du Colombier vStoreString(szString, tLen, pOutput);
269f5736e95SDavid du Colombier }
270f5736e95SDavid du Colombier } /* end of vStoreStyle */
271f5736e95SDavid du Colombier
272f5736e95SDavid du Colombier /*
273f5736e95SDavid du Colombier * vPutIndentation - output the specified amount of indentation
274f5736e95SDavid du Colombier */
275f5736e95SDavid du Colombier static void
vPutIndentation(diagram_type * pDiag,output_type * pOutput,BOOL bNoMarks,BOOL bFirstLine,UINT uiListNumber,UCHAR ucNFC,const char * szListChar,long lLeftIndentation,long lLeftIndentation1)276f5736e95SDavid du Colombier vPutIndentation(diagram_type *pDiag, output_type *pOutput,
277f5736e95SDavid du Colombier BOOL bNoMarks, BOOL bFirstLine,
278f5736e95SDavid du Colombier UINT uiListNumber, UCHAR ucNFC, const char *szListChar,
279f5736e95SDavid du Colombier long lLeftIndentation, long lLeftIndentation1)
280f5736e95SDavid du Colombier {
281f5736e95SDavid du Colombier long lWidth;
282f5736e95SDavid du Colombier size_t tIndex, tNextFree;
283f5736e95SDavid du Colombier char szLine[30];
284f5736e95SDavid du Colombier
285f5736e95SDavid du Colombier fail(pDiag == NULL);
286f5736e95SDavid du Colombier fail(pOutput == NULL);
287f5736e95SDavid du Colombier fail(szListChar == NULL);
288f5736e95SDavid du Colombier fail(lLeftIndentation < 0);
289f5736e95SDavid du Colombier
290f5736e95SDavid du Colombier if (tOptions.eConversionType == conversion_xml) {
291f5736e95SDavid du Colombier /* XML does its own indentation at rendering time */
292f5736e95SDavid du Colombier return;
293f5736e95SDavid du Colombier }
294f5736e95SDavid du Colombier
295f5736e95SDavid du Colombier if (bNoMarks) {
296f5736e95SDavid du Colombier if (bFirstLine) {
297f5736e95SDavid du Colombier lLeftIndentation += lLeftIndentation1;
298f5736e95SDavid du Colombier }
299f5736e95SDavid du Colombier if (lLeftIndentation < 0) {
300f5736e95SDavid du Colombier lLeftIndentation = 0;
301f5736e95SDavid du Colombier }
302f5736e95SDavid du Colombier vSetLeftIndentation(pDiag, lLeftIndentation);
303f5736e95SDavid du Colombier return;
304f5736e95SDavid du Colombier }
305f5736e95SDavid du Colombier if (lLeftIndentation <= 0) {
306f5736e95SDavid du Colombier DBG_HEX_C(ucNFC != 0x00, ucNFC);
307f5736e95SDavid du Colombier vSetLeftIndentation(pDiag, 0);
308f5736e95SDavid du Colombier return;
309f5736e95SDavid du Colombier }
310f5736e95SDavid du Colombier
311f5736e95SDavid du Colombier #if defined(DEBUG)
312*25b329d5SDavid du Colombier if (tOptions.eEncoding == encoding_utf_8) {
313f5736e95SDavid du Colombier fail(strlen(szListChar) > 3);
314f5736e95SDavid du Colombier } else {
315f5736e95SDavid du Colombier DBG_HEX_C(iscntrl((int)szListChar[0]), szListChar[0]);
316f5736e95SDavid du Colombier fail(iscntrl((int)szListChar[0]));
317f5736e95SDavid du Colombier fail(szListChar[1] != '\0');
318f5736e95SDavid du Colombier }
319f5736e95SDavid du Colombier #endif /* DEBUG */
320f5736e95SDavid du Colombier
321f5736e95SDavid du Colombier switch (ucNFC) {
322f5736e95SDavid du Colombier case LIST_ARABIC_NUM:
323*25b329d5SDavid du Colombier case LIST_NUMBER_TXT:
324f5736e95SDavid du Colombier tNextFree = (size_t)sprintf(szLine, "%u", uiListNumber);
325f5736e95SDavid du Colombier break;
326f5736e95SDavid du Colombier case LIST_UPPER_ROMAN:
327f5736e95SDavid du Colombier case LIST_LOWER_ROMAN:
328f5736e95SDavid du Colombier tNextFree = tNumber2Roman(uiListNumber,
329f5736e95SDavid du Colombier ucNFC == LIST_UPPER_ROMAN, szLine);
330f5736e95SDavid du Colombier break;
331f5736e95SDavid du Colombier case LIST_UPPER_ALPHA:
332f5736e95SDavid du Colombier case LIST_LOWER_ALPHA:
333f5736e95SDavid du Colombier tNextFree = tNumber2Alpha(uiListNumber,
334f5736e95SDavid du Colombier ucNFC == LIST_UPPER_ALPHA, szLine);
335f5736e95SDavid du Colombier break;
336f5736e95SDavid du Colombier case LIST_ORDINAL_NUM:
337*25b329d5SDavid du Colombier case LIST_ORDINAL_TXT:
338f5736e95SDavid du Colombier if (uiListNumber % 10 == 1 && uiListNumber != 11) {
339f5736e95SDavid du Colombier tNextFree =
340f5736e95SDavid du Colombier (size_t)sprintf(szLine, "%ust", uiListNumber);
341f5736e95SDavid du Colombier } else if (uiListNumber % 10 == 2 && uiListNumber != 12) {
342f5736e95SDavid du Colombier tNextFree =
343f5736e95SDavid du Colombier (size_t)sprintf(szLine, "%und", uiListNumber);
344f5736e95SDavid du Colombier } else if (uiListNumber % 10 == 3 && uiListNumber != 13) {
345f5736e95SDavid du Colombier tNextFree =
346f5736e95SDavid du Colombier (size_t)sprintf(szLine, "%urd", uiListNumber);
347f5736e95SDavid du Colombier } else {
348f5736e95SDavid du Colombier tNextFree =
349f5736e95SDavid du Colombier (size_t)sprintf(szLine, "%uth", uiListNumber);
350f5736e95SDavid du Colombier }
351f5736e95SDavid du Colombier break;
352*25b329d5SDavid du Colombier case LIST_OUTLINE_NUM:
353*25b329d5SDavid du Colombier tNextFree = (size_t)sprintf(szLine, "%02u", uiListNumber);
354*25b329d5SDavid du Colombier break;
355f5736e95SDavid du Colombier case LIST_SPECIAL:
356*25b329d5SDavid du Colombier case LIST_SPECIAL2:
357f5736e95SDavid du Colombier case LIST_BULLETS:
358f5736e95SDavid du Colombier tNextFree = 0;
359f5736e95SDavid du Colombier break;
360f5736e95SDavid du Colombier default:
361*25b329d5SDavid du Colombier DBG_HEX(ucNFC);
362f5736e95SDavid du Colombier DBG_FIXME();
363f5736e95SDavid du Colombier tNextFree = (size_t)sprintf(szLine, "%u", uiListNumber);
364f5736e95SDavid du Colombier break;
365f5736e95SDavid du Colombier }
366f5736e95SDavid du Colombier tNextFree += (size_t)sprintf(szLine + tNextFree, "%.3s", szListChar);
367f5736e95SDavid du Colombier szLine[tNextFree++] = ' ';
368f5736e95SDavid du Colombier szLine[tNextFree] = '\0';
369f5736e95SDavid du Colombier lWidth = lComputeStringWidth(szLine, tNextFree,
370f5736e95SDavid du Colombier pOutput->tFontRef, pOutput->usFontSize);
371f5736e95SDavid du Colombier lLeftIndentation -= lWidth;
372f5736e95SDavid du Colombier if (lLeftIndentation < 0) {
373f5736e95SDavid du Colombier lLeftIndentation = 0;
374f5736e95SDavid du Colombier }
375f5736e95SDavid du Colombier vSetLeftIndentation(pDiag, lLeftIndentation);
376f5736e95SDavid du Colombier for (tIndex = 0; tIndex < tNextFree; tIndex++) {
377*25b329d5SDavid du Colombier vStoreChar((ULONG)(UCHAR)szLine[tIndex], FALSE, pOutput);
378f5736e95SDavid du Colombier }
379f5736e95SDavid du Colombier } /* end of vPutIndentation */
380f5736e95SDavid du Colombier
381f5736e95SDavid du Colombier /*
382f5736e95SDavid du Colombier * vPutSeparatorLine - output a separator line
383f5736e95SDavid du Colombier *
384f5736e95SDavid du Colombier * A separator line is a horizontal line two inches long.
385f5736e95SDavid du Colombier * Two inches equals 144000 millipoints.
386f5736e95SDavid du Colombier */
387f5736e95SDavid du Colombier static void
vPutSeparatorLine(output_type * pOutput)388f5736e95SDavid du Colombier vPutSeparatorLine(output_type *pOutput)
389f5736e95SDavid du Colombier {
390f5736e95SDavid du Colombier long lCharWidth;
391f5736e95SDavid du Colombier int iCounter, iChars;
392f5736e95SDavid du Colombier char szOne[2];
393f5736e95SDavid du Colombier
394f5736e95SDavid du Colombier fail(pOutput == NULL);
395f5736e95SDavid du Colombier
396f5736e95SDavid du Colombier szOne[0] = OUR_EM_DASH;
397f5736e95SDavid du Colombier szOne[1] = '\0';
398f5736e95SDavid du Colombier lCharWidth = lComputeStringWidth(szOne, 1,
399f5736e95SDavid du Colombier pOutput->tFontRef, pOutput->usFontSize);
400f5736e95SDavid du Colombier NO_DBG_DEC(lCharWidth);
401f5736e95SDavid du Colombier iChars = (int)((144000 + lCharWidth / 2) / lCharWidth);
402f5736e95SDavid du Colombier NO_DBG_DEC(iChars);
403f5736e95SDavid du Colombier for (iCounter = 0; iCounter < iChars; iCounter++) {
404f5736e95SDavid du Colombier vStoreCharacter((ULONG)(UCHAR)OUR_EM_DASH, pOutput);
405f5736e95SDavid du Colombier }
406f5736e95SDavid du Colombier } /* end of vPutSeparatorLine */
407f5736e95SDavid du Colombier
408f5736e95SDavid du Colombier /*
409f5736e95SDavid du Colombier * pStartNextOutput - start the next output record
410f5736e95SDavid du Colombier *
411f5736e95SDavid du Colombier * returns a pointer to the next record
412f5736e95SDavid du Colombier */
413f5736e95SDavid du Colombier static output_type *
pStartNextOutput(output_type * pCurrent)414f5736e95SDavid du Colombier pStartNextOutput(output_type *pCurrent)
415f5736e95SDavid du Colombier {
416f5736e95SDavid du Colombier output_type *pNew;
417f5736e95SDavid du Colombier
418*25b329d5SDavid du Colombier TRACE_MSG("pStartNextOutput");
419*25b329d5SDavid du Colombier
420f5736e95SDavid du Colombier if (pCurrent->tNextFree == 0) {
421f5736e95SDavid du Colombier /* The current record is empty, re-use */
422f5736e95SDavid du Colombier fail(pCurrent->szStorage[0] != '\0');
423f5736e95SDavid du Colombier fail(pCurrent->lStringWidth != 0);
424f5736e95SDavid du Colombier return pCurrent;
425f5736e95SDavid du Colombier }
426f5736e95SDavid du Colombier /* The current record is in use, make a new one */
427f5736e95SDavid du Colombier pNew = xmalloc(sizeof(*pNew));
428f5736e95SDavid du Colombier pCurrent->pNext = pNew;
429f5736e95SDavid du Colombier pNew->tStorageSize = INITIAL_SIZE;
430f5736e95SDavid du Colombier pNew->szStorage = xmalloc(pNew->tStorageSize);
431f5736e95SDavid du Colombier pNew->szStorage[0] = '\0';
432f5736e95SDavid du Colombier pNew->tNextFree = 0;
433f5736e95SDavid du Colombier pNew->lStringWidth = 0;
434f5736e95SDavid du Colombier pNew->ucFontColor = FONT_COLOR_DEFAULT;
435f5736e95SDavid du Colombier pNew->usFontStyle = FONT_REGULAR;
436*25b329d5SDavid du Colombier pNew->tFontRef = (drawfile_fontref)0;
437f5736e95SDavid du Colombier pNew->usFontSize = DEFAULT_FONT_SIZE;
438f5736e95SDavid du Colombier pNew->pPrev = pCurrent;
439f5736e95SDavid du Colombier pNew->pNext = NULL;
440f5736e95SDavid du Colombier return pNew;
441f5736e95SDavid du Colombier } /* end of pStartNextOutput */
442f5736e95SDavid du Colombier
443f5736e95SDavid du Colombier /*
444f5736e95SDavid du Colombier * pStartNewOutput
445f5736e95SDavid du Colombier */
446f5736e95SDavid du Colombier static output_type *
pStartNewOutput(output_type * pAnchor,output_type * pLeftOver)447f5736e95SDavid du Colombier pStartNewOutput(output_type *pAnchor, output_type *pLeftOver)
448f5736e95SDavid du Colombier {
449f5736e95SDavid du Colombier output_type *pCurr, *pNext;
450f5736e95SDavid du Colombier USHORT usFontStyle, usFontSize;
451*25b329d5SDavid du Colombier drawfile_fontref tFontRef;
452f5736e95SDavid du Colombier UCHAR ucFontColor;
453f5736e95SDavid du Colombier
454*25b329d5SDavid du Colombier TRACE_MSG("pStartNewOutput");
455*25b329d5SDavid du Colombier
456f5736e95SDavid du Colombier ucFontColor = FONT_COLOR_DEFAULT;
457f5736e95SDavid du Colombier usFontStyle = FONT_REGULAR;
458*25b329d5SDavid du Colombier tFontRef = (drawfile_fontref)0;
459f5736e95SDavid du Colombier usFontSize = DEFAULT_FONT_SIZE;
460f5736e95SDavid du Colombier /* Free the old output space */
461f5736e95SDavid du Colombier pCurr = pAnchor;
462f5736e95SDavid du Colombier while (pCurr != NULL) {
463*25b329d5SDavid du Colombier TRACE_MSG("Free the old output space");
464f5736e95SDavid du Colombier pNext = pCurr->pNext;
465f5736e95SDavid du Colombier pCurr->szStorage = xfree(pCurr->szStorage);
466f5736e95SDavid du Colombier if (pCurr->pNext == NULL) {
467f5736e95SDavid du Colombier ucFontColor = pCurr->ucFontColor;
468f5736e95SDavid du Colombier usFontStyle = pCurr->usFontStyle;
469f5736e95SDavid du Colombier tFontRef = pCurr->tFontRef;
470f5736e95SDavid du Colombier usFontSize = pCurr->usFontSize;
471f5736e95SDavid du Colombier }
472f5736e95SDavid du Colombier pCurr = xfree(pCurr);
473f5736e95SDavid du Colombier pCurr = pNext;
474f5736e95SDavid du Colombier }
475f5736e95SDavid du Colombier if (pLeftOver == NULL) {
476f5736e95SDavid du Colombier /* Create new output space */
477*25b329d5SDavid du Colombier TRACE_MSG("Create new output space");
478f5736e95SDavid du Colombier pLeftOver = xmalloc(sizeof(*pLeftOver));
479f5736e95SDavid du Colombier pLeftOver->tStorageSize = INITIAL_SIZE;
480*25b329d5SDavid du Colombier NO_DBG_DEC(pLeftOver->tStorageSize);
481*25b329d5SDavid du Colombier TRACE_MSG("before 2nd xmalloc");
482f5736e95SDavid du Colombier pLeftOver->szStorage = xmalloc(pLeftOver->tStorageSize);
483*25b329d5SDavid du Colombier TRACE_MSG("after 2nd xmalloc");
484f5736e95SDavid du Colombier pLeftOver->szStorage[0] = '\0';
485f5736e95SDavid du Colombier pLeftOver->tNextFree = 0;
486f5736e95SDavid du Colombier pLeftOver->lStringWidth = 0;
487f5736e95SDavid du Colombier pLeftOver->ucFontColor = ucFontColor;
488f5736e95SDavid du Colombier pLeftOver->usFontStyle = usFontStyle;
489f5736e95SDavid du Colombier pLeftOver->tFontRef = tFontRef;
490f5736e95SDavid du Colombier pLeftOver->usFontSize = usFontSize;
491f5736e95SDavid du Colombier pLeftOver->pPrev = NULL;
492f5736e95SDavid du Colombier pLeftOver->pNext = NULL;
493f5736e95SDavid du Colombier }
494f5736e95SDavid du Colombier fail(!bCheckDoubleLinkedList(pLeftOver));
495f5736e95SDavid du Colombier return pLeftOver;
496f5736e95SDavid du Colombier } /* end of pStartNewOutput */
497f5736e95SDavid du Colombier
498f5736e95SDavid du Colombier /*
499f5736e95SDavid du Colombier * ulGetChar - get the next character from the specified list
500f5736e95SDavid du Colombier *
501f5736e95SDavid du Colombier * returns the next character of EOF
502f5736e95SDavid du Colombier */
503f5736e95SDavid du Colombier static ULONG
ulGetChar(FILE * pFile,list_id_enum eListID)504f5736e95SDavid du Colombier ulGetChar(FILE *pFile, list_id_enum eListID)
505f5736e95SDavid du Colombier {
506f5736e95SDavid du Colombier const font_block_type *pCurr;
507*25b329d5SDavid du Colombier ULONG ulChar, ulFileOffset, ulCharPos;
508f5736e95SDavid du Colombier row_info_enum eRowInfo;
509f5736e95SDavid du Colombier USHORT usChar, usPropMod;
510f5736e95SDavid du Colombier BOOL bSkip;
511f5736e95SDavid du Colombier
512f5736e95SDavid du Colombier fail(pFile == NULL);
513f5736e95SDavid du Colombier
514f5736e95SDavid du Colombier pCurr = pFontInfo;
515f5736e95SDavid du Colombier bSkip = FALSE;
516f5736e95SDavid du Colombier for (;;) {
517f5736e95SDavid du Colombier usChar = usNextChar(pFile, eListID,
518*25b329d5SDavid du Colombier &ulFileOffset, &ulCharPos, &usPropMod);
519f5736e95SDavid du Colombier if (usChar == (USHORT)EOF) {
520f5736e95SDavid du Colombier return (ULONG)EOF;
521f5736e95SDavid du Colombier }
522f5736e95SDavid du Colombier
523f5736e95SDavid du Colombier vUpdateCounters();
524f5736e95SDavid du Colombier
525f5736e95SDavid du Colombier eRowInfo = ePropMod2RowInfo(usPropMod, iWordVersion);
526f5736e95SDavid du Colombier if (!bStartRow) {
527f5736e95SDavid du Colombier #if 0
528f5736e95SDavid du Colombier bStartRow = eRowInfo == found_a_cell ||
529f5736e95SDavid du Colombier (pRowInfo != NULL &&
530f5736e95SDavid du Colombier ulFileOffset == pRowInfo->ulFileOffsetStart &&
531f5736e95SDavid du Colombier eRowInfo != found_not_a_cell);
532f5736e95SDavid du Colombier #else
533f5736e95SDavid du Colombier bStartRow = pRowInfo != NULL &&
534f5736e95SDavid du Colombier ulFileOffset == pRowInfo->ulFileOffsetStart;
535f5736e95SDavid du Colombier #endif
536f5736e95SDavid du Colombier NO_DBG_HEX_C(bStartRow, pRowInfo->ulFileOffsetStart);
537f5736e95SDavid du Colombier }
538f5736e95SDavid du Colombier if (!bEndRowNorm) {
539f5736e95SDavid du Colombier #if 0
540f5736e95SDavid du Colombier bEndRow = eRowInfo == found_end_of_row ||
541f5736e95SDavid du Colombier (pRowInfo != NULL &&
542f5736e95SDavid du Colombier ulFileOffset == pRowInfo->ulFileOffsetEnd &&
543f5736e95SDavid du Colombier eRowInfo != found_not_end_of_row);
544f5736e95SDavid du Colombier #else
545f5736e95SDavid du Colombier bEndRowNorm = pRowInfo != NULL &&
546f5736e95SDavid du Colombier ulFileOffset == pRowInfo->ulFileOffsetEnd;
547f5736e95SDavid du Colombier #endif
548f5736e95SDavid du Colombier NO_DBG_HEX_C(bEndRowNorm, pRowInfo->ulFileOffsetEnd);
549f5736e95SDavid du Colombier }
550f5736e95SDavid du Colombier if (!bEndRowFast) {
551f5736e95SDavid du Colombier bEndRowFast = eRowInfo == found_end_of_row;
552f5736e95SDavid du Colombier NO_DBG_HEX_C(bEndRowFast, pRowInfo->ulFileOffsetEnd);
553f5736e95SDavid du Colombier }
554f5736e95SDavid du Colombier
555f5736e95SDavid du Colombier if (!bStartStyle) {
556f5736e95SDavid du Colombier bStartStyle = pStyleInfo != NULL &&
557f5736e95SDavid du Colombier ulFileOffset == pStyleInfo->ulFileOffset;
558f5736e95SDavid du Colombier NO_DBG_HEX_C(bStartStyle, ulFileOffset);
559f5736e95SDavid du Colombier }
560f5736e95SDavid du Colombier if (pCurr != NULL && ulFileOffset == pCurr->ulFileOffset) {
561f5736e95SDavid du Colombier bStartFont = TRUE;
562f5736e95SDavid du Colombier NO_DBG_HEX(ulFileOffset);
563f5736e95SDavid du Colombier pFontInfo = pCurr;
564f5736e95SDavid du Colombier pCurr = pGetNextFontInfoListItem(pCurr);
565f5736e95SDavid du Colombier }
566f5736e95SDavid du Colombier
567f5736e95SDavid du Colombier /* Skip embedded characters */
568f5736e95SDavid du Colombier if (usChar == START_EMBEDDED) {
569f5736e95SDavid du Colombier bSkip = TRUE;
570f5736e95SDavid du Colombier continue;
571f5736e95SDavid du Colombier }
572f5736e95SDavid du Colombier if (usChar == END_IGNORE || usChar == END_EMBEDDED) {
573f5736e95SDavid du Colombier bSkip = FALSE;
574f5736e95SDavid du Colombier continue;
575f5736e95SDavid du Colombier }
576f5736e95SDavid du Colombier if (bSkip) {
577f5736e95SDavid du Colombier continue;
578f5736e95SDavid du Colombier }
579f5736e95SDavid du Colombier ulChar = ulTranslateCharacters(usChar,
580f5736e95SDavid du Colombier ulFileOffset,
581f5736e95SDavid du Colombier iWordVersion,
582f5736e95SDavid du Colombier tOptions.eConversionType,
583f5736e95SDavid du Colombier tOptions.eEncoding,
584f5736e95SDavid du Colombier bOldMacFile);
585f5736e95SDavid du Colombier if (ulChar == IGNORE_CHARACTER) {
586f5736e95SDavid du Colombier continue;
587f5736e95SDavid du Colombier }
588f5736e95SDavid du Colombier if (ulChar == PICTURE) {
589f5736e95SDavid du Colombier ulFileOffsetImage = ulGetPictInfoListItem(ulFileOffset);
590f5736e95SDavid du Colombier } else {
591f5736e95SDavid du Colombier ulFileOffsetImage = FC_INVALID;
592f5736e95SDavid du Colombier }
593f5736e95SDavid du Colombier if (ulChar == PAR_END) {
594f5736e95SDavid du Colombier /* End of paragraph seen, prepare for the next */
595f5736e95SDavid du Colombier vFillStyleFromStylesheet(usIstdNext, &tStyleNext);
596f5736e95SDavid du Colombier vCorrectStyleValues(&tStyleNext);
597f5736e95SDavid du Colombier bStartStyleNext = TRUE;
598f5736e95SDavid du Colombier vFillFontFromStylesheet(usIstdNext, &tFontNext);
599f5736e95SDavid du Colombier vCorrectFontValues(&tFontNext);
600f5736e95SDavid du Colombier bStartFontNext = TRUE;
601f5736e95SDavid du Colombier }
602f5736e95SDavid du Colombier if (ulChar == PAGE_BREAK) {
603f5736e95SDavid du Colombier /* Might be the start of a new section */
604*25b329d5SDavid du Colombier pSectionNext = pGetSectionInfo(pSection, ulCharPos);
605f5736e95SDavid du Colombier }
606f5736e95SDavid du Colombier return ulChar;
607f5736e95SDavid du Colombier }
608f5736e95SDavid du Colombier } /* end of ulGetChar */
609f5736e95SDavid du Colombier
610f5736e95SDavid du Colombier /*
611*25b329d5SDavid du Colombier * lGetWidthMax - get the maximum line width from the paragraph break value
612*25b329d5SDavid du Colombier *
613*25b329d5SDavid du Colombier * Returns the maximum line width in millipoints
614*25b329d5SDavid du Colombier */
615*25b329d5SDavid du Colombier static long
lGetWidthMax(int iParagraphBreak)616*25b329d5SDavid du Colombier lGetWidthMax(int iParagraphBreak)
617*25b329d5SDavid du Colombier {
618*25b329d5SDavid du Colombier fail(iParagraphBreak < 0);
619*25b329d5SDavid du Colombier
620*25b329d5SDavid du Colombier if (iParagraphBreak == 0) {
621*25b329d5SDavid du Colombier return LONG_MAX;
622*25b329d5SDavid du Colombier }
623*25b329d5SDavid du Colombier if (iParagraphBreak < MIN_SCREEN_WIDTH) {
624*25b329d5SDavid du Colombier return lChar2MilliPoints(MIN_SCREEN_WIDTH);
625*25b329d5SDavid du Colombier }
626*25b329d5SDavid du Colombier if (iParagraphBreak > MAX_SCREEN_WIDTH) {
627*25b329d5SDavid du Colombier return lChar2MilliPoints(MAX_SCREEN_WIDTH);
628*25b329d5SDavid du Colombier }
629*25b329d5SDavid du Colombier return lChar2MilliPoints(iParagraphBreak);
630*25b329d5SDavid du Colombier } /* end of lGetWidthMax */
631*25b329d5SDavid du Colombier
632*25b329d5SDavid du Colombier /*
633*25b329d5SDavid du Colombier * bWordDecryptor - turn Word to something more useful
634f5736e95SDavid du Colombier *
635f5736e95SDavid du Colombier * returns TRUE when succesful, otherwise FALSE
636f5736e95SDavid du Colombier */
637f5736e95SDavid du Colombier BOOL
bWordDecryptor(FILE * pFile,long lFilesize,diagram_type * pDiag)638f5736e95SDavid du Colombier bWordDecryptor(FILE *pFile, long lFilesize, diagram_type *pDiag)
639f5736e95SDavid du Colombier {
640f5736e95SDavid du Colombier imagedata_type tImage;
641f5736e95SDavid du Colombier const style_block_type *pStyleTmp;
642f5736e95SDavid du Colombier const font_block_type *pFontTmp;
643f5736e95SDavid du Colombier const char *szListChar;
644f5736e95SDavid du Colombier output_type *pAnchor, *pOutput, *pLeftOver;
645f5736e95SDavid du Colombier ULONG ulChar;
646f5736e95SDavid du Colombier long lBeforeIndentation, lAfterIndentation;
647f5736e95SDavid du Colombier long lLeftIndentation, lLeftIndentation1, lRightIndentation;
648*25b329d5SDavid du Colombier long lWidthCurr, lWidthMax, lDefaultTabWidth, lHalfSpaceWidth, lTmp;
649f5736e95SDavid du Colombier list_id_enum eListID;
650f5736e95SDavid du Colombier image_info_enum eRes;
651f5736e95SDavid du Colombier UINT uiFootnoteNumber, uiEndnoteNumber, uiTmp;
652f5736e95SDavid du Colombier int iListSeqNumber;
653f5736e95SDavid du Colombier BOOL bWasTableRow, bTableFontClosed, bWasEndOfParagraph;
654f5736e95SDavid du Colombier BOOL bInList, bWasInList, bNoMarks, bFirstLine;
655f5736e95SDavid du Colombier BOOL bAllCapitals, bHiddenText, bMarkDelText, bSuccess;
656f5736e95SDavid du Colombier USHORT usListNumber;
657f5736e95SDavid du Colombier USHORT usFontStyle, usFontStyleMinimal, usFontSize, usTmp;
658f5736e95SDavid du Colombier UCHAR ucFontNumber, ucFontColor;
659f5736e95SDavid du Colombier UCHAR ucNFC, ucAlignment;
660f5736e95SDavid du Colombier
661f5736e95SDavid du Colombier fail(pFile == NULL || lFilesize <= 0 || pDiag == NULL);
662f5736e95SDavid du Colombier
663*25b329d5SDavid du Colombier TRACE_MSG("bWordDecryptor");
664f5736e95SDavid du Colombier
665f5736e95SDavid du Colombier iWordVersion = iInitDocument(pFile, lFilesize);
666f5736e95SDavid du Colombier if (iWordVersion < 0) {
667f5736e95SDavid du Colombier DBG_DEC(iWordVersion);
668f5736e95SDavid du Colombier return FALSE;
669f5736e95SDavid du Colombier }
670*25b329d5SDavid du Colombier
671*25b329d5SDavid du Colombier vGetOptions(&tOptions);
672*25b329d5SDavid du Colombier bOldMacFile = bIsOldMacFile();
673*25b329d5SDavid du Colombier vPrepareHdrFtrText(pFile);
674*25b329d5SDavid du Colombier vPrepareFootnoteText(pFile);
675*25b329d5SDavid du Colombier
676f5736e95SDavid du Colombier vPrologue2(pDiag, iWordVersion);
677f5736e95SDavid du Colombier
678f5736e95SDavid du Colombier /* Initialisation */
679f5736e95SDavid du Colombier #if defined(__riscos)
680f5736e95SDavid du Colombier ulCharCounter = 0;
681f5736e95SDavid du Colombier iCurrPct = 0;
682f5736e95SDavid du Colombier iPrevPct = -1;
683f5736e95SDavid du Colombier ulDocumentLength = ulGetDocumentLength();
684f5736e95SDavid du Colombier #endif /* __riscos */
685f5736e95SDavid du Colombier pSection = pGetSectionInfo(NULL, 0);
686f5736e95SDavid du Colombier pSectionNext = pSection;
687f5736e95SDavid du Colombier lDefaultTabWidth = lGetDefaultTabWidth();
688f5736e95SDavid du Colombier DBG_DEC_C(lDefaultTabWidth != 36000, lDefaultTabWidth);
689f5736e95SDavid du Colombier pRowInfo = pGetNextRowInfoListItem();
690f5736e95SDavid du Colombier DBG_HEX_C(pRowInfo != NULL, pRowInfo->ulFileOffsetStart);
691f5736e95SDavid du Colombier DBG_HEX_C(pRowInfo != NULL, pRowInfo->ulFileOffsetEnd);
692f5736e95SDavid du Colombier DBG_MSG_C(pRowInfo == NULL, "No rows at all");
693f5736e95SDavid du Colombier bStartRow = FALSE;
694f5736e95SDavid du Colombier bEndRowNorm = FALSE;
695f5736e95SDavid du Colombier bEndRowFast = FALSE;
696f5736e95SDavid du Colombier bIsTableRow = FALSE;
697f5736e95SDavid du Colombier bWasTableRow = FALSE;
698f5736e95SDavid du Colombier vResetStyles();
699*25b329d5SDavid du Colombier pStyleInfo = pGetNextTextStyle(NULL);
700f5736e95SDavid du Colombier bStartStyle = FALSE;
701f5736e95SDavid du Colombier bInList = FALSE;
702f5736e95SDavid du Colombier bWasInList = FALSE;
703f5736e95SDavid du Colombier iListSeqNumber = 0;
704f5736e95SDavid du Colombier usIstdNext = ISTD_NORMAL;
705f5736e95SDavid du Colombier pAnchor = NULL;
706f5736e95SDavid du Colombier pFontInfo = pGetNextFontInfoListItem(NULL);
707f5736e95SDavid du Colombier DBG_HEX_C(pFontInfo != NULL, pFontInfo->ulFileOffset);
708f5736e95SDavid du Colombier DBG_MSG_C(pFontInfo == NULL, "No fonts at all");
709f5736e95SDavid du Colombier bStartFont = FALSE;
710f5736e95SDavid du Colombier ucFontNumber = 0;
711f5736e95SDavid du Colombier usFontStyleMinimal = FONT_REGULAR;
712f5736e95SDavid du Colombier usFontStyle = FONT_REGULAR;
713f5736e95SDavid du Colombier usFontSize = DEFAULT_FONT_SIZE;
714f5736e95SDavid du Colombier ucFontColor = FONT_COLOR_DEFAULT;
715f5736e95SDavid du Colombier pAnchor = pStartNewOutput(pAnchor, NULL);
716f5736e95SDavid du Colombier pOutput = pAnchor;
717f5736e95SDavid du Colombier pOutput->ucFontColor = ucFontColor;
718f5736e95SDavid du Colombier pOutput->usFontStyle = usFontStyle;
719f5736e95SDavid du Colombier pOutput->tFontRef = tOpenFont(ucFontNumber, usFontStyle, usFontSize);
720f5736e95SDavid du Colombier pOutput->usFontSize = usFontSize;
721f5736e95SDavid du Colombier bTableFontClosed = TRUE;
722f5736e95SDavid du Colombier lBeforeIndentation = 0;
723f5736e95SDavid du Colombier lAfterIndentation = 0;
724f5736e95SDavid du Colombier lLeftIndentation = 0;
725f5736e95SDavid du Colombier lLeftIndentation1 = 0;
726f5736e95SDavid du Colombier lRightIndentation = 0;
727f5736e95SDavid du Colombier bWasEndOfParagraph = TRUE;
728f5736e95SDavid du Colombier bNoMarks = TRUE;
729f5736e95SDavid du Colombier bFirstLine = TRUE;
730f5736e95SDavid du Colombier ucNFC = LIST_BULLETS;
731f5736e95SDavid du Colombier if (pStyleInfo != NULL) {
732f5736e95SDavid du Colombier szListChar = pStyleInfo->szListChar;
733f5736e95SDavid du Colombier pStyleTmp = pStyleInfo;
734f5736e95SDavid du Colombier } else {
735f5736e95SDavid du Colombier if (tStyleNext.szListChar[0] == '\0') {
736f5736e95SDavid du Colombier vGetBulletValue(tOptions.eConversionType,
737f5736e95SDavid du Colombier tOptions.eEncoding, tStyleNext.szListChar, 4);
738f5736e95SDavid du Colombier }
739f5736e95SDavid du Colombier szListChar = tStyleNext.szListChar;
740f5736e95SDavid du Colombier pStyleTmp = &tStyleNext;
741f5736e95SDavid du Colombier }
742f5736e95SDavid du Colombier usListNumber = 0;
743f5736e95SDavid du Colombier ucAlignment = ALIGNMENT_LEFT;
744f5736e95SDavid du Colombier bAllCapitals = FALSE;
745f5736e95SDavid du Colombier bHiddenText = FALSE;
746f5736e95SDavid du Colombier bMarkDelText = FALSE;
747*25b329d5SDavid du Colombier lWidthMax = lGetWidthMax(tOptions.iParagraphBreak);
748f5736e95SDavid du Colombier NO_DBG_DEC(lWidthMax);
749f5736e95SDavid du Colombier
750*25b329d5SDavid du Colombier Hourglass_On();
751f5736e95SDavid du Colombier
752f5736e95SDavid du Colombier uiFootnoteNumber = 0;
753f5736e95SDavid du Colombier uiEndnoteNumber = 0;
754f5736e95SDavid du Colombier eListID = text_list;
755f5736e95SDavid du Colombier for(;;) {
756f5736e95SDavid du Colombier ulChar = ulGetChar(pFile, eListID);
757f5736e95SDavid du Colombier if (ulChar == (ULONG)EOF) {
758f5736e95SDavid du Colombier if (bOutputContainsText(pAnchor)) {
759f5736e95SDavid du Colombier OUTPUT_LINE();
760f5736e95SDavid du Colombier } else {
761f5736e95SDavid du Colombier RESET_LINE();
762f5736e95SDavid du Colombier }
763f5736e95SDavid du Colombier switch (eListID) {
764f5736e95SDavid du Colombier case text_list:
765*25b329d5SDavid du Colombier if (tOptions.eConversionType !=
766*25b329d5SDavid du Colombier conversion_xml) {
767f5736e95SDavid du Colombier eListID = footnote_list;
768f5736e95SDavid du Colombier if (uiFootnoteNumber != 0) {
769f5736e95SDavid du Colombier vPutSeparatorLine(pAnchor);
770f5736e95SDavid du Colombier OUTPUT_LINE();
771f5736e95SDavid du Colombier uiFootnoteNumber = 0;
772f5736e95SDavid du Colombier }
773f5736e95SDavid du Colombier break;
774*25b329d5SDavid du Colombier }
775*25b329d5SDavid du Colombier /* No break or return */
776f5736e95SDavid du Colombier case footnote_list:
777f5736e95SDavid du Colombier eListID = endnote_list;
778f5736e95SDavid du Colombier if (uiEndnoteNumber != 0) {
779f5736e95SDavid du Colombier vPutSeparatorLine(pAnchor);
780f5736e95SDavid du Colombier OUTPUT_LINE();
781f5736e95SDavid du Colombier uiEndnoteNumber = 0;
782f5736e95SDavid du Colombier }
783f5736e95SDavid du Colombier break;
784f5736e95SDavid du Colombier case endnote_list:
785f5736e95SDavid du Colombier eListID = textbox_list;
786f5736e95SDavid du Colombier if (bExistsTextBox()) {
787f5736e95SDavid du Colombier vPutSeparatorLine(pAnchor);
788f5736e95SDavid du Colombier OUTPUT_LINE();
789f5736e95SDavid du Colombier }
790f5736e95SDavid du Colombier break;
791f5736e95SDavid du Colombier case textbox_list:
792f5736e95SDavid du Colombier eListID = hdrtextbox_list;
793f5736e95SDavid du Colombier if (bExistsHdrTextBox()) {
794f5736e95SDavid du Colombier vPutSeparatorLine(pAnchor);
795f5736e95SDavid du Colombier OUTPUT_LINE();
796f5736e95SDavid du Colombier }
797f5736e95SDavid du Colombier break;
798f5736e95SDavid du Colombier case hdrtextbox_list:
799f5736e95SDavid du Colombier default:
800f5736e95SDavid du Colombier eListID = end_of_lists;
801f5736e95SDavid du Colombier break;
802f5736e95SDavid du Colombier }
803f5736e95SDavid du Colombier if (eListID == end_of_lists) {
804f5736e95SDavid du Colombier break;
805f5736e95SDavid du Colombier }
806f5736e95SDavid du Colombier continue;
807f5736e95SDavid du Colombier }
808f5736e95SDavid du Colombier
809f5736e95SDavid du Colombier if (ulChar == UNKNOWN_NOTE_CHAR) {
810f5736e95SDavid du Colombier switch (eListID) {
811f5736e95SDavid du Colombier case footnote_list:
812f5736e95SDavid du Colombier ulChar = FOOTNOTE_CHAR;
813f5736e95SDavid du Colombier break;
814f5736e95SDavid du Colombier case endnote_list:
815f5736e95SDavid du Colombier ulChar = ENDNOTE_CHAR;
816f5736e95SDavid du Colombier break;
817f5736e95SDavid du Colombier default:
818f5736e95SDavid du Colombier break;
819f5736e95SDavid du Colombier }
820f5736e95SDavid du Colombier }
821f5736e95SDavid du Colombier
822f5736e95SDavid du Colombier if (bStartRow) {
823f5736e95SDavid du Colombier /* Begin of a tablerow found */
824f5736e95SDavid du Colombier if (bOutputContainsText(pAnchor)) {
825f5736e95SDavid du Colombier OUTPUT_LINE();
826f5736e95SDavid du Colombier } else {
827f5736e95SDavid du Colombier RESET_LINE();
828f5736e95SDavid du Colombier }
829f5736e95SDavid du Colombier fail(pAnchor != pOutput);
830f5736e95SDavid du Colombier if (bTableFontClosed) {
831f5736e95SDavid du Colombier /* Start special table font */
832f5736e95SDavid du Colombier vCloseFont();
833f5736e95SDavid du Colombier /*
834f5736e95SDavid du Colombier * Compensate for the fact that Word uses
835f5736e95SDavid du Colombier * proportional fonts for its tables and we
836f5736e95SDavid du Colombier * only one fixed-width font
837f5736e95SDavid du Colombier */
838f5736e95SDavid du Colombier uiTmp = ((UINT)usFontSize * 5 + 3) / 6;
839f5736e95SDavid du Colombier if (uiTmp < MIN_TABLEFONT_SIZE) {
840f5736e95SDavid du Colombier uiTmp = MIN_TABLEFONT_SIZE;
841f5736e95SDavid du Colombier } else if (uiTmp > MAX_TABLEFONT_SIZE) {
842f5736e95SDavid du Colombier uiTmp = MAX_TABLEFONT_SIZE;
843f5736e95SDavid du Colombier }
844f5736e95SDavid du Colombier pOutput->usFontSize = (USHORT)uiTmp;
845f5736e95SDavid du Colombier pOutput->tFontRef =
846f5736e95SDavid du Colombier tOpenTableFont(pOutput->usFontSize);
847f5736e95SDavid du Colombier pOutput->usFontStyle = FONT_REGULAR;
848f5736e95SDavid du Colombier pOutput->ucFontColor = FONT_COLOR_BLACK;
849f5736e95SDavid du Colombier bTableFontClosed = FALSE;
850f5736e95SDavid du Colombier }
851f5736e95SDavid du Colombier bIsTableRow = TRUE;
852f5736e95SDavid du Colombier bStartRow = FALSE;
853f5736e95SDavid du Colombier }
854f5736e95SDavid du Colombier
855f5736e95SDavid du Colombier if (bWasTableRow &&
856f5736e95SDavid du Colombier !bIsTableRow &&
857f5736e95SDavid du Colombier ulChar != PAR_END &&
858f5736e95SDavid du Colombier ulChar != HARD_RETURN &&
859f5736e95SDavid du Colombier ulChar != PAGE_BREAK &&
860f5736e95SDavid du Colombier ulChar != COLUMN_FEED) {
861f5736e95SDavid du Colombier /*
862f5736e95SDavid du Colombier * The end of a table should be followed by an
863f5736e95SDavid du Colombier * empty line, like the end of a paragraph
864f5736e95SDavid du Colombier */
865f5736e95SDavid du Colombier OUTPUT_LINE();
866f5736e95SDavid du Colombier vEndOfParagraph(pDiag,
867f5736e95SDavid du Colombier pOutput->tFontRef,
868f5736e95SDavid du Colombier pOutput->usFontSize,
869f5736e95SDavid du Colombier (long)pOutput->usFontSize * 600);
870f5736e95SDavid du Colombier }
871f5736e95SDavid du Colombier
872f5736e95SDavid du Colombier switch (ulChar) {
873f5736e95SDavid du Colombier case PAGE_BREAK:
874f5736e95SDavid du Colombier case COLUMN_FEED:
875f5736e95SDavid du Colombier if (bIsTableRow) {
876*25b329d5SDavid du Colombier /* Ignore when in a table */
877f5736e95SDavid du Colombier break;
878f5736e95SDavid du Colombier }
879f5736e95SDavid du Colombier if (bOutputContainsText(pAnchor)) {
880f5736e95SDavid du Colombier OUTPUT_LINE();
881f5736e95SDavid du Colombier } else {
882f5736e95SDavid du Colombier RESET_LINE();
883f5736e95SDavid du Colombier }
884f5736e95SDavid du Colombier if (ulChar == PAGE_BREAK) {
885*25b329d5SDavid du Colombier vEndOfPage(pDiag, lAfterIndentation,
886*25b329d5SDavid du Colombier pSection != pSectionNext);
887f5736e95SDavid du Colombier } else {
888f5736e95SDavid du Colombier vEndOfParagraph(pDiag,
889f5736e95SDavid du Colombier pOutput->tFontRef,
890f5736e95SDavid du Colombier pOutput->usFontSize,
891f5736e95SDavid du Colombier lAfterIndentation);
892f5736e95SDavid du Colombier }
893f5736e95SDavid du Colombier break;
894f5736e95SDavid du Colombier default:
895f5736e95SDavid du Colombier break;
896f5736e95SDavid du Colombier }
897f5736e95SDavid du Colombier
898f5736e95SDavid du Colombier if (bStartFont || (bStartFontNext && ulChar != PAR_END)) {
899f5736e95SDavid du Colombier /* Begin of a font found */
900f5736e95SDavid du Colombier if (bStartFont) {
901f5736e95SDavid du Colombier /* bStartFont takes priority */
902f5736e95SDavid du Colombier fail(pFontInfo == NULL);
903f5736e95SDavid du Colombier pFontTmp = pFontInfo;
904f5736e95SDavid du Colombier } else {
905f5736e95SDavid du Colombier pFontTmp = &tFontNext;
906f5736e95SDavid du Colombier }
907f5736e95SDavid du Colombier bAllCapitals = bIsCapitals(pFontTmp->usFontStyle);
908f5736e95SDavid du Colombier bHiddenText = bIsHidden(pFontTmp->usFontStyle);
909f5736e95SDavid du Colombier bMarkDelText = bIsMarkDel(pFontTmp->usFontStyle);
910f5736e95SDavid du Colombier usTmp = pFontTmp->usFontStyle &
911f5736e95SDavid du Colombier (FONT_BOLD|FONT_ITALIC|FONT_UNDERLINE|
912f5736e95SDavid du Colombier FONT_STRIKE|FONT_MARKDEL|
913f5736e95SDavid du Colombier FONT_SUPERSCRIPT|FONT_SUBSCRIPT);
914f5736e95SDavid du Colombier if (!bIsTableRow &&
915f5736e95SDavid du Colombier (usFontSize != pFontTmp->usFontSize ||
916f5736e95SDavid du Colombier ucFontNumber != pFontTmp->ucFontNumber ||
917f5736e95SDavid du Colombier usFontStyleMinimal != usTmp ||
918f5736e95SDavid du Colombier ucFontColor != pFontTmp->ucFontColor)) {
919f5736e95SDavid du Colombier pOutput = pStartNextOutput(pOutput);
920f5736e95SDavid du Colombier vCloseFont();
921f5736e95SDavid du Colombier pOutput->ucFontColor = pFontTmp->ucFontColor;
922f5736e95SDavid du Colombier pOutput->usFontStyle = pFontTmp->usFontStyle;
923f5736e95SDavid du Colombier pOutput->usFontSize = pFontTmp->usFontSize;
924f5736e95SDavid du Colombier pOutput->tFontRef = tOpenFont(
925f5736e95SDavid du Colombier pFontTmp->ucFontNumber,
926f5736e95SDavid du Colombier pFontTmp->usFontStyle,
927f5736e95SDavid du Colombier pFontTmp->usFontSize);
928f5736e95SDavid du Colombier fail(!bCheckDoubleLinkedList(pAnchor));
929f5736e95SDavid du Colombier }
930f5736e95SDavid du Colombier ucFontNumber = pFontTmp->ucFontNumber;
931f5736e95SDavid du Colombier usFontSize = pFontTmp->usFontSize;
932f5736e95SDavid du Colombier ucFontColor = pFontTmp->ucFontColor;
933f5736e95SDavid du Colombier usFontStyle = pFontTmp->usFontStyle;
934f5736e95SDavid du Colombier usFontStyleMinimal = usTmp;
935f5736e95SDavid du Colombier if (bStartFont) {
936f5736e95SDavid du Colombier /* Get the next font info */
937f5736e95SDavid du Colombier pFontInfo = pGetNextFontInfoListItem(pFontInfo);
938f5736e95SDavid du Colombier NO_DBG_HEX_C(pFontInfo != NULL,
939f5736e95SDavid du Colombier pFontInfo->ulFileOffset);
940f5736e95SDavid du Colombier DBG_MSG_C(pFontInfo == NULL, "No more fonts");
941f5736e95SDavid du Colombier }
942f5736e95SDavid du Colombier bStartFont = FALSE;
943f5736e95SDavid du Colombier bStartFontNext = FALSE;
944f5736e95SDavid du Colombier }
945f5736e95SDavid du Colombier
946f5736e95SDavid du Colombier if (bStartStyle || (bStartStyleNext && ulChar != PAR_END)) {
947f5736e95SDavid du Colombier bFirstLine = TRUE;
948f5736e95SDavid du Colombier /* Begin of a style found */
949f5736e95SDavid du Colombier if (bStartStyle) {
950f5736e95SDavid du Colombier /* bStartStyle takes priority */
951f5736e95SDavid du Colombier fail(pStyleInfo == NULL);
952f5736e95SDavid du Colombier pStyleTmp = pStyleInfo;
953f5736e95SDavid du Colombier } else {
954f5736e95SDavid du Colombier pStyleTmp = &tStyleNext;
955f5736e95SDavid du Colombier }
956f5736e95SDavid du Colombier if (!bIsTableRow) {
957f5736e95SDavid du Colombier vStoreStyle(pDiag, pOutput, pStyleTmp);
958f5736e95SDavid du Colombier }
959f5736e95SDavid du Colombier usIstdNext = pStyleTmp->usIstdNext;
960f5736e95SDavid du Colombier lBeforeIndentation =
961f5736e95SDavid du Colombier lTwips2MilliPoints(pStyleTmp->usBeforeIndent);
962f5736e95SDavid du Colombier lAfterIndentation =
963f5736e95SDavid du Colombier lTwips2MilliPoints(pStyleTmp->usAfterIndent);
964f5736e95SDavid du Colombier lLeftIndentation =
965f5736e95SDavid du Colombier lTwips2MilliPoints(pStyleTmp->sLeftIndent);
966f5736e95SDavid du Colombier lLeftIndentation1 =
967f5736e95SDavid du Colombier lTwips2MilliPoints(pStyleTmp->sLeftIndent1);
968f5736e95SDavid du Colombier lRightIndentation =
969f5736e95SDavid du Colombier lTwips2MilliPoints(pStyleTmp->sRightIndent);
970f5736e95SDavid du Colombier bInList = bStyleImpliesList(pStyleTmp, iWordVersion);
971f5736e95SDavid du Colombier bNoMarks = !bInList || pStyleTmp->bNumPause;
972f5736e95SDavid du Colombier ucNFC = pStyleTmp->ucNFC;
973f5736e95SDavid du Colombier szListChar = pStyleTmp->szListChar;
974f5736e95SDavid du Colombier ucAlignment = pStyleTmp->ucAlignment;
975f5736e95SDavid du Colombier if (bInList && !bWasInList) {
976f5736e95SDavid du Colombier /* Start of a list */
977f5736e95SDavid du Colombier iListSeqNumber++;
978f5736e95SDavid du Colombier vStartOfList(pDiag, ucNFC,
979f5736e95SDavid du Colombier bWasTableRow && !bIsTableRow);
980f5736e95SDavid du Colombier }
981f5736e95SDavid du Colombier if (!bInList && bWasInList) {
982f5736e95SDavid du Colombier /* End of a list */
983f5736e95SDavid du Colombier vEndOfList(pDiag);
984f5736e95SDavid du Colombier }
985f5736e95SDavid du Colombier bWasInList = bInList;
986f5736e95SDavid du Colombier if (bStartStyle) {
987*25b329d5SDavid du Colombier pStyleInfo = pGetNextTextStyle(pStyleInfo);
988f5736e95SDavid du Colombier NO_DBG_HEX_C(pStyleInfo != NULL,
989f5736e95SDavid du Colombier pStyleInfo->ulFileOffset);
990f5736e95SDavid du Colombier DBG_MSG_C(pStyleInfo == NULL,
991f5736e95SDavid du Colombier "No more styles");
992f5736e95SDavid du Colombier }
993f5736e95SDavid du Colombier bStartStyle = FALSE;
994f5736e95SDavid du Colombier bStartStyleNext = FALSE;
995f5736e95SDavid du Colombier }
996f5736e95SDavid du Colombier
997f5736e95SDavid du Colombier if (bWasEndOfParagraph) {
998f5736e95SDavid du Colombier vStartOfParagraph1(pDiag, lBeforeIndentation);
999f5736e95SDavid du Colombier }
1000f5736e95SDavid du Colombier
1001f5736e95SDavid du Colombier if (!bIsTableRow &&
1002f5736e95SDavid du Colombier lTotalStringWidth(pAnchor) == 0) {
1003f5736e95SDavid du Colombier if (!bNoMarks) {
1004f5736e95SDavid du Colombier usListNumber = usGetListValue(iListSeqNumber,
1005f5736e95SDavid du Colombier iWordVersion,
1006f5736e95SDavid du Colombier pStyleTmp);
1007f5736e95SDavid du Colombier }
1008f5736e95SDavid du Colombier if (bInList && bFirstLine) {
1009f5736e95SDavid du Colombier vStartOfListItem(pDiag, bNoMarks);
1010f5736e95SDavid du Colombier }
1011f5736e95SDavid du Colombier vPutIndentation(pDiag, pAnchor, bNoMarks, bFirstLine,
1012f5736e95SDavid du Colombier usListNumber, ucNFC, szListChar,
1013f5736e95SDavid du Colombier lLeftIndentation, lLeftIndentation1);
1014f5736e95SDavid du Colombier bFirstLine = FALSE;
1015f5736e95SDavid du Colombier /* One number or mark per paragraph will do */
1016f5736e95SDavid du Colombier bNoMarks = TRUE;
1017f5736e95SDavid du Colombier }
1018f5736e95SDavid du Colombier
1019f5736e95SDavid du Colombier if (bWasEndOfParagraph) {
1020f5736e95SDavid du Colombier vStartOfParagraph2(pDiag);
1021f5736e95SDavid du Colombier bWasEndOfParagraph = FALSE;
1022f5736e95SDavid du Colombier }
1023f5736e95SDavid du Colombier
1024f5736e95SDavid du Colombier switch (ulChar) {
1025f5736e95SDavid du Colombier case PICTURE:
1026f5736e95SDavid du Colombier (void)memset(&tImage, 0, sizeof(tImage));
1027f5736e95SDavid du Colombier eRes = eExamineImage(pFile, ulFileOffsetImage, &tImage);
1028f5736e95SDavid du Colombier switch (eRes) {
1029f5736e95SDavid du Colombier case image_no_information:
1030f5736e95SDavid du Colombier bSuccess = FALSE;
1031f5736e95SDavid du Colombier break;
1032f5736e95SDavid du Colombier case image_minimal_information:
1033f5736e95SDavid du Colombier case image_full_information:
1034f5736e95SDavid du Colombier #if 0
1035f5736e95SDavid du Colombier if (bOutputContainsText(pAnchor)) {
1036f5736e95SDavid du Colombier OUTPUT_LINE();
1037f5736e95SDavid du Colombier } else {
1038f5736e95SDavid du Colombier RESET_LINE();
1039f5736e95SDavid du Colombier }
1040f5736e95SDavid du Colombier #endif
1041f5736e95SDavid du Colombier bSuccess = bTranslateImage(pDiag, pFile,
1042f5736e95SDavid du Colombier eRes == image_minimal_information,
1043f5736e95SDavid du Colombier ulFileOffsetImage, &tImage);
1044f5736e95SDavid du Colombier break;
1045f5736e95SDavid du Colombier default:
1046f5736e95SDavid du Colombier DBG_DEC(eRes);
1047f5736e95SDavid du Colombier bSuccess = FALSE;
1048f5736e95SDavid du Colombier break;
1049f5736e95SDavid du Colombier }
1050f5736e95SDavid du Colombier if (!bSuccess) {
1051f5736e95SDavid du Colombier vStoreString("[pic]", 5, pOutput);
1052f5736e95SDavid du Colombier }
1053f5736e95SDavid du Colombier break;
1054f5736e95SDavid du Colombier case FOOTNOTE_CHAR:
1055f5736e95SDavid du Colombier uiFootnoteNumber++;
1056*25b329d5SDavid du Colombier if (tOptions.eConversionType == conversion_xml) {
1057*25b329d5SDavid du Colombier vStoreCharacter((ULONG)FOOTNOTE_OR_ENDNOTE,
1058*25b329d5SDavid du Colombier pOutput);
1059*25b329d5SDavid du Colombier break;
1060*25b329d5SDavid du Colombier }
1061f5736e95SDavid du Colombier vStoreCharacter((ULONG)'[', pOutput);
1062f5736e95SDavid du Colombier vStoreNumberAsDecimal(uiFootnoteNumber, pOutput);
1063f5736e95SDavid du Colombier vStoreCharacter((ULONG)']', pOutput);
1064f5736e95SDavid du Colombier break;
1065f5736e95SDavid du Colombier case ENDNOTE_CHAR:
1066f5736e95SDavid du Colombier uiEndnoteNumber++;
1067f5736e95SDavid du Colombier vStoreCharacter((ULONG)'[', pOutput);
1068f5736e95SDavid du Colombier vStoreNumberAsRoman(uiEndnoteNumber, pOutput);
1069f5736e95SDavid du Colombier vStoreCharacter((ULONG)']', pOutput);
1070f5736e95SDavid du Colombier break;
1071f5736e95SDavid du Colombier case UNKNOWN_NOTE_CHAR:
1072f5736e95SDavid du Colombier vStoreString("[?]", 3, pOutput);
1073f5736e95SDavid du Colombier break;
1074f5736e95SDavid du Colombier case PAR_END:
1075f5736e95SDavid du Colombier if (bIsTableRow) {
1076f5736e95SDavid du Colombier vStoreCharacter((ULONG)'\n', pOutput);
1077f5736e95SDavid du Colombier break;
1078f5736e95SDavid du Colombier }
1079*25b329d5SDavid du Colombier if (bOutputContainsText(pAnchor)) {
1080f5736e95SDavid du Colombier OUTPUT_LINE();
1081*25b329d5SDavid du Colombier } else {
1082*25b329d5SDavid du Colombier vMove2NextLine(pDiag,
1083*25b329d5SDavid du Colombier pOutput->tFontRef, pOutput->usFontSize);
1084*25b329d5SDavid du Colombier RESET_LINE();
1085*25b329d5SDavid du Colombier }
1086f5736e95SDavid du Colombier vEndOfParagraph(pDiag,
1087f5736e95SDavid du Colombier pOutput->tFontRef,
1088f5736e95SDavid du Colombier pOutput->usFontSize,
1089f5736e95SDavid du Colombier lAfterIndentation);
1090f5736e95SDavid du Colombier bWasEndOfParagraph = TRUE;
1091f5736e95SDavid du Colombier break;
1092f5736e95SDavid du Colombier case HARD_RETURN:
1093f5736e95SDavid du Colombier if (bIsTableRow) {
1094f5736e95SDavid du Colombier vStoreCharacter((ULONG)'\n', pOutput);
1095f5736e95SDavid du Colombier break;
1096f5736e95SDavid du Colombier }
1097f5736e95SDavid du Colombier if (bOutputContainsText(pAnchor)) {
1098f5736e95SDavid du Colombier OUTPUT_LINE();
1099*25b329d5SDavid du Colombier } else {
1100f5736e95SDavid du Colombier vMove2NextLine(pDiag,
1101f5736e95SDavid du Colombier pOutput->tFontRef, pOutput->usFontSize);
1102*25b329d5SDavid du Colombier RESET_LINE();
1103*25b329d5SDavid du Colombier }
1104f5736e95SDavid du Colombier break;
1105f5736e95SDavid du Colombier case PAGE_BREAK:
1106f5736e95SDavid du Colombier case COLUMN_FEED:
1107f5736e95SDavid du Colombier pSection = pSectionNext;
1108f5736e95SDavid du Colombier break;
1109f5736e95SDavid du Colombier case TABLE_SEPARATOR:
1110f5736e95SDavid du Colombier if (bIsTableRow) {
1111f5736e95SDavid du Colombier vStoreCharacter(ulChar, pOutput);
1112f5736e95SDavid du Colombier break;
1113f5736e95SDavid du Colombier }
1114f5736e95SDavid du Colombier vStoreCharacter((ULONG)' ', pOutput);
1115f5736e95SDavid du Colombier vStoreCharacter((ULONG)TABLE_SEPARATOR_CHAR, pOutput);
1116f5736e95SDavid du Colombier break;
1117f5736e95SDavid du Colombier case TAB:
1118f5736e95SDavid du Colombier if (bIsTableRow ||
1119f5736e95SDavid du Colombier tOptions.eConversionType == conversion_xml) {
1120f5736e95SDavid du Colombier vStoreCharacter((ULONG)' ', pOutput);
1121f5736e95SDavid du Colombier break;
1122f5736e95SDavid du Colombier }
1123f5736e95SDavid du Colombier if (tOptions.iParagraphBreak == 0 &&
1124*25b329d5SDavid du Colombier (tOptions.eConversionType == conversion_text ||
1125*25b329d5SDavid du Colombier tOptions.eConversionType == conversion_fmt_text)) {
1126f5736e95SDavid du Colombier /* No logical lines, so no tab expansion */
1127f5736e95SDavid du Colombier vStoreCharacter(TAB, pOutput);
1128f5736e95SDavid du Colombier break;
1129f5736e95SDavid du Colombier }
1130*25b329d5SDavid du Colombier lHalfSpaceWidth = (lComputeSpaceWidth(
1131*25b329d5SDavid du Colombier pOutput->tFontRef,
1132*25b329d5SDavid du Colombier pOutput->usFontSize) + 1) / 2;
1133f5736e95SDavid du Colombier lTmp = lTotalStringWidth(pAnchor);
1134f5736e95SDavid du Colombier lTmp += lDrawUnits2MilliPoints(pDiag->lXleft);
1135f5736e95SDavid du Colombier lTmp /= lDefaultTabWidth;
1136f5736e95SDavid du Colombier do {
1137f5736e95SDavid du Colombier vStoreCharacter((ULONG)FILLER_CHAR, pOutput);
1138f5736e95SDavid du Colombier lWidthCurr = lTotalStringWidth(pAnchor);
1139f5736e95SDavid du Colombier lWidthCurr +=
1140f5736e95SDavid du Colombier lDrawUnits2MilliPoints(pDiag->lXleft);
1141f5736e95SDavid du Colombier } while (lTmp == lWidthCurr / lDefaultTabWidth &&
1142f5736e95SDavid du Colombier lWidthCurr < lWidthMax + lRightIndentation);
1143f5736e95SDavid du Colombier break;
1144f5736e95SDavid du Colombier default:
1145f5736e95SDavid du Colombier if (bHiddenText && tOptions.bHideHiddenText) {
1146f5736e95SDavid du Colombier continue;
1147f5736e95SDavid du Colombier }
1148*25b329d5SDavid du Colombier if (bMarkDelText && tOptions.bRemoveRemovedText) {
1149f5736e95SDavid du Colombier continue;
1150f5736e95SDavid du Colombier }
1151*25b329d5SDavid du Colombier if (ulChar == UNICODE_ELLIPSIS &&
1152*25b329d5SDavid du Colombier tOptions.eEncoding != encoding_utf_8) {
1153*25b329d5SDavid du Colombier vStoreString("...", 3, pOutput);
1154*25b329d5SDavid du Colombier } else {
1155f5736e95SDavid du Colombier if (bAllCapitals) {
1156f5736e95SDavid du Colombier ulChar = ulToUpper(ulChar);
1157f5736e95SDavid du Colombier }
1158f5736e95SDavid du Colombier vStoreCharacter(ulChar, pOutput);
1159*25b329d5SDavid du Colombier }
1160f5736e95SDavid du Colombier break;
1161f5736e95SDavid du Colombier }
1162f5736e95SDavid du Colombier
1163f5736e95SDavid du Colombier if (bWasTableRow && !bIsTableRow) {
1164f5736e95SDavid du Colombier /* End of a table */
1165f5736e95SDavid du Colombier vEndOfTable(pDiag);
1166f5736e95SDavid du Colombier /* Resume normal font */
1167f5736e95SDavid du Colombier NO_DBG_MSG("End of table font");
1168f5736e95SDavid du Colombier vCloseFont();
1169f5736e95SDavid du Colombier bTableFontClosed = TRUE;
1170f5736e95SDavid du Colombier pOutput->ucFontColor = ucFontColor;
1171f5736e95SDavid du Colombier pOutput->usFontStyle = usFontStyle;
1172f5736e95SDavid du Colombier pOutput->usFontSize = usFontSize;
1173f5736e95SDavid du Colombier pOutput->tFontRef = tOpenFont(
1174f5736e95SDavid du Colombier ucFontNumber, usFontStyle, usFontSize);
1175f5736e95SDavid du Colombier }
1176f5736e95SDavid du Colombier bWasTableRow = bIsTableRow;
1177f5736e95SDavid du Colombier
1178f5736e95SDavid du Colombier if (bIsTableRow) {
1179f5736e95SDavid du Colombier fail(pAnchor != pOutput);
1180f5736e95SDavid du Colombier if (!bEndRowNorm && !bEndRowFast) {
1181f5736e95SDavid du Colombier continue;
1182f5736e95SDavid du Colombier }
1183f5736e95SDavid du Colombier /* End of a table row */
1184f5736e95SDavid du Colombier if (bEndRowNorm) {
1185f5736e95SDavid du Colombier fail(pRowInfo == NULL);
1186*25b329d5SDavid du Colombier vTableRow2Window(pDiag, pAnchor, pRowInfo,
1187*25b329d5SDavid du Colombier tOptions.eConversionType,
1188*25b329d5SDavid du Colombier tOptions.iParagraphBreak);
1189f5736e95SDavid du Colombier } else {
1190f5736e95SDavid du Colombier fail(!bEndRowFast);
1191f5736e95SDavid du Colombier }
1192f5736e95SDavid du Colombier /* Reset */
1193f5736e95SDavid du Colombier pAnchor = pStartNewOutput(pAnchor, NULL);
1194f5736e95SDavid du Colombier pOutput = pAnchor;
1195f5736e95SDavid du Colombier if (bEndRowNorm) {
1196f5736e95SDavid du Colombier pRowInfo = pGetNextRowInfoListItem();
1197f5736e95SDavid du Colombier }
1198f5736e95SDavid du Colombier bIsTableRow = FALSE;
1199f5736e95SDavid du Colombier bEndRowNorm = FALSE;
1200f5736e95SDavid du Colombier bEndRowFast = FALSE;
1201f5736e95SDavid du Colombier NO_DBG_HEX_C(pRowInfo != NULL,
1202f5736e95SDavid du Colombier pRowInfo->ulFileOffsetStart);
1203f5736e95SDavid du Colombier NO_DBG_HEX_C(pRowInfo != NULL,
1204f5736e95SDavid du Colombier pRowInfo->ulFileOffsetEnd);
1205f5736e95SDavid du Colombier continue;
1206f5736e95SDavid du Colombier }
1207f5736e95SDavid du Colombier lWidthCurr = lTotalStringWidth(pAnchor);
1208f5736e95SDavid du Colombier lWidthCurr += lDrawUnits2MilliPoints(pDiag->lXleft);
1209f5736e95SDavid du Colombier if (lWidthCurr < lWidthMax + lRightIndentation) {
1210f5736e95SDavid du Colombier continue;
1211f5736e95SDavid du Colombier }
1212f5736e95SDavid du Colombier pLeftOver = pSplitList(pAnchor);
1213f5736e95SDavid du Colombier vJustify2Window(pDiag, pAnchor,
1214f5736e95SDavid du Colombier lWidthMax, lRightIndentation, ucAlignment);
1215f5736e95SDavid du Colombier pAnchor = pStartNewOutput(pAnchor, pLeftOver);
1216f5736e95SDavid du Colombier for (pOutput = pAnchor;
1217f5736e95SDavid du Colombier pOutput->pNext != NULL;
1218f5736e95SDavid du Colombier pOutput = pOutput->pNext)
1219f5736e95SDavid du Colombier ; /* EMPTY */
1220f5736e95SDavid du Colombier fail(pOutput == NULL);
1221f5736e95SDavid du Colombier if (lTotalStringWidth(pAnchor) > 0) {
1222f5736e95SDavid du Colombier vSetLeftIndentation(pDiag, lLeftIndentation);
1223f5736e95SDavid du Colombier }
1224f5736e95SDavid du Colombier }
1225f5736e95SDavid du Colombier
1226f5736e95SDavid du Colombier pAnchor = pStartNewOutput(pAnchor, NULL);
1227f5736e95SDavid du Colombier pAnchor->szStorage = xfree(pAnchor->szStorage);
1228f5736e95SDavid du Colombier pAnchor = xfree(pAnchor);
1229f5736e95SDavid du Colombier vCloseFont();
1230f5736e95SDavid du Colombier vFreeDocument();
1231*25b329d5SDavid du Colombier Hourglass_Off();
1232f5736e95SDavid du Colombier return TRUE;
1233f5736e95SDavid du Colombier } /* end of bWordDecryptor */
1234*25b329d5SDavid du Colombier
1235*25b329d5SDavid du Colombier /*
1236*25b329d5SDavid du Colombier * lLastStringWidth - compute the width of the last part of the output string
1237*25b329d5SDavid du Colombier */
1238*25b329d5SDavid du Colombier static long
lLastStringWidth(const output_type * pAnchor)1239*25b329d5SDavid du Colombier lLastStringWidth(const output_type *pAnchor)
1240*25b329d5SDavid du Colombier {
1241*25b329d5SDavid du Colombier const output_type *pCurr, *pStart;
1242*25b329d5SDavid du Colombier
1243*25b329d5SDavid du Colombier pStart = NULL;
1244*25b329d5SDavid du Colombier for (pCurr = pAnchor; pCurr != NULL; pCurr = pCurr->pNext) {
1245*25b329d5SDavid du Colombier if (pCurr->tNextFree == 1 &&
1246*25b329d5SDavid du Colombier (pCurr->szStorage[0] == PAR_END ||
1247*25b329d5SDavid du Colombier pCurr->szStorage[0] == HARD_RETURN)) {
1248*25b329d5SDavid du Colombier /* Found a separator. Start after the separator */
1249*25b329d5SDavid du Colombier pStart = pCurr->pNext;
1250*25b329d5SDavid du Colombier }
1251*25b329d5SDavid du Colombier }
1252*25b329d5SDavid du Colombier if (pStart == NULL) {
1253*25b329d5SDavid du Colombier /* No separators. Use the whole output string */
1254*25b329d5SDavid du Colombier pStart = pAnchor;
1255*25b329d5SDavid du Colombier }
1256*25b329d5SDavid du Colombier return lTotalStringWidth(pStart);
1257*25b329d5SDavid du Colombier } /* end of lLastStringWidth */
1258*25b329d5SDavid du Colombier
1259*25b329d5SDavid du Colombier /*
1260*25b329d5SDavid du Colombier * pHdrFtrDecryptor - turn a header/footer list element to something useful
1261*25b329d5SDavid du Colombier */
1262*25b329d5SDavid du Colombier output_type *
pHdrFtrDecryptor(FILE * pFile,ULONG ulCharPosStart,ULONG ulCharPosNext)1263*25b329d5SDavid du Colombier pHdrFtrDecryptor(FILE *pFile, ULONG ulCharPosStart, ULONG ulCharPosNext)
1264*25b329d5SDavid du Colombier {
1265*25b329d5SDavid du Colombier output_type *pAnchor, *pOutput, *pLeftOver;
1266*25b329d5SDavid du Colombier ULONG ulChar, ulFileOffset, ulCharPos;
1267*25b329d5SDavid du Colombier long lWidthCurr, lWidthMax;
1268*25b329d5SDavid du Colombier long lRightIndentation;
1269*25b329d5SDavid du Colombier USHORT usChar;
1270*25b329d5SDavid du Colombier UCHAR ucAlignment;
1271*25b329d5SDavid du Colombier BOOL bSkip;
1272*25b329d5SDavid du Colombier
1273*25b329d5SDavid du Colombier fail(iWordVersion < 0);
1274*25b329d5SDavid du Colombier fail(tOptions.eConversionType == conversion_unknown);
1275*25b329d5SDavid du Colombier fail(tOptions.eEncoding == 0);
1276*25b329d5SDavid du Colombier
1277*25b329d5SDavid du Colombier if (ulCharPosStart == ulCharPosNext) {
1278*25b329d5SDavid du Colombier /* There are no bytes to decrypt */
1279*25b329d5SDavid du Colombier return NULL;
1280*25b329d5SDavid du Colombier }
1281*25b329d5SDavid du Colombier
1282*25b329d5SDavid du Colombier lRightIndentation = 0;
1283*25b329d5SDavid du Colombier ucAlignment = ALIGNMENT_LEFT;
1284*25b329d5SDavid du Colombier bSkip = FALSE;
1285*25b329d5SDavid du Colombier lWidthMax = lGetWidthMax(tOptions.iParagraphBreak);
1286*25b329d5SDavid du Colombier pAnchor = pStartNewOutput(NULL, NULL);
1287*25b329d5SDavid du Colombier pOutput = pAnchor;
1288*25b329d5SDavid du Colombier pOutput->tFontRef = tOpenFont(0, FONT_REGULAR, DEFAULT_FONT_SIZE);
1289*25b329d5SDavid du Colombier usChar = usToHdrFtrPosition(pFile, ulCharPosStart);
1290*25b329d5SDavid du Colombier ulCharPos = ulCharPosStart;
1291*25b329d5SDavid du Colombier ulFileOffset = ulCharPos2FileOffset(ulCharPos);
1292*25b329d5SDavid du Colombier while (usChar != (USHORT)EOF && ulCharPos != ulCharPosNext) {
1293*25b329d5SDavid du Colombier /* Skip embedded characters */
1294*25b329d5SDavid du Colombier if (usChar == START_EMBEDDED) {
1295*25b329d5SDavid du Colombier bSkip = TRUE;
1296*25b329d5SDavid du Colombier } else if (usChar == END_IGNORE || usChar == END_EMBEDDED) {
1297*25b329d5SDavid du Colombier bSkip = FALSE;
1298*25b329d5SDavid du Colombier }
1299*25b329d5SDavid du Colombier /* Translate character */
1300*25b329d5SDavid du Colombier if (bSkip || usChar == END_IGNORE || usChar == END_EMBEDDED) {
1301*25b329d5SDavid du Colombier ulChar = IGNORE_CHARACTER;
1302*25b329d5SDavid du Colombier } else {
1303*25b329d5SDavid du Colombier ulChar = ulTranslateCharacters(usChar,
1304*25b329d5SDavid du Colombier ulFileOffset,
1305*25b329d5SDavid du Colombier iWordVersion,
1306*25b329d5SDavid du Colombier tOptions.eConversionType,
1307*25b329d5SDavid du Colombier tOptions.eEncoding,
1308*25b329d5SDavid du Colombier bOldMacFile);
1309*25b329d5SDavid du Colombier }
1310*25b329d5SDavid du Colombier /* Process character */
1311*25b329d5SDavid du Colombier if (ulChar != IGNORE_CHARACTER) {
1312*25b329d5SDavid du Colombier switch (ulChar) {
1313*25b329d5SDavid du Colombier case PICTURE:
1314*25b329d5SDavid du Colombier vStoreString("[pic]", 5, pOutput);
1315*25b329d5SDavid du Colombier break;
1316*25b329d5SDavid du Colombier case PAR_END:
1317*25b329d5SDavid du Colombier case HARD_RETURN:
1318*25b329d5SDavid du Colombier case PAGE_BREAK:
1319*25b329d5SDavid du Colombier case COLUMN_FEED:
1320*25b329d5SDavid du Colombier /* To the next substring */
1321*25b329d5SDavid du Colombier pOutput = pStartNextOutput(pOutput);
1322*25b329d5SDavid du Colombier vCloseFont();
1323*25b329d5SDavid du Colombier pOutput->tFontRef = tOpenFont(0,
1324*25b329d5SDavid du Colombier FONT_REGULAR, DEFAULT_FONT_SIZE);
1325*25b329d5SDavid du Colombier /* A substring with just one character */
1326*25b329d5SDavid du Colombier if (ulChar == HARD_RETURN) {
1327*25b329d5SDavid du Colombier vStoreCharacter(HARD_RETURN, pOutput);
1328*25b329d5SDavid du Colombier } else {
1329*25b329d5SDavid du Colombier vStoreCharacter(PAR_END, pOutput);
1330*25b329d5SDavid du Colombier }
1331*25b329d5SDavid du Colombier /* To the next substring */
1332*25b329d5SDavid du Colombier pOutput = pStartNextOutput(pOutput);
1333*25b329d5SDavid du Colombier vCloseFont();
1334*25b329d5SDavid du Colombier pOutput->tFontRef = tOpenFont(0,
1335*25b329d5SDavid du Colombier FONT_REGULAR, DEFAULT_FONT_SIZE);
1336*25b329d5SDavid du Colombier fail(!bCheckDoubleLinkedList(pAnchor));
1337*25b329d5SDavid du Colombier break;
1338*25b329d5SDavid du Colombier case TABLE_SEPARATOR:
1339*25b329d5SDavid du Colombier vStoreCharacter((ULONG)' ', pOutput);
1340*25b329d5SDavid du Colombier vStoreCharacter((ULONG)TABLE_SEPARATOR_CHAR,
1341*25b329d5SDavid du Colombier pOutput);
1342*25b329d5SDavid du Colombier break;
1343*25b329d5SDavid du Colombier case TAB:
1344*25b329d5SDavid du Colombier vStoreCharacter((ULONG)FILLER_CHAR, pOutput);
1345*25b329d5SDavid du Colombier break;
1346*25b329d5SDavid du Colombier default:
1347*25b329d5SDavid du Colombier vStoreCharacter(ulChar, pOutput);
1348*25b329d5SDavid du Colombier break;
1349*25b329d5SDavid du Colombier }
1350*25b329d5SDavid du Colombier }
1351*25b329d5SDavid du Colombier lWidthCurr = lLastStringWidth(pAnchor);
1352*25b329d5SDavid du Colombier if (lWidthCurr >= lWidthMax + lRightIndentation) {
1353*25b329d5SDavid du Colombier pLeftOver = pSplitList(pAnchor);
1354*25b329d5SDavid du Colombier for (pOutput = pAnchor;
1355*25b329d5SDavid du Colombier pOutput->pNext != NULL;
1356*25b329d5SDavid du Colombier pOutput = pOutput->pNext)
1357*25b329d5SDavid du Colombier ; /* EMPTY */
1358*25b329d5SDavid du Colombier fail(pOutput == NULL);
1359*25b329d5SDavid du Colombier /* To the next substring */
1360*25b329d5SDavid du Colombier pOutput = pStartNextOutput(pOutput);
1361*25b329d5SDavid du Colombier /* A substring with just one HARD_RETURN */
1362*25b329d5SDavid du Colombier vStoreCharacter(HARD_RETURN, pOutput);
1363*25b329d5SDavid du Colombier /* Put the leftover piece(s) at the end */
1364*25b329d5SDavid du Colombier pOutput->pNext = pLeftOver;
1365*25b329d5SDavid du Colombier if (pLeftOver != NULL) {
1366*25b329d5SDavid du Colombier pLeftOver->pPrev = pOutput;
1367*25b329d5SDavid du Colombier }
1368*25b329d5SDavid du Colombier fail(!bCheckDoubleLinkedList(pAnchor));
1369*25b329d5SDavid du Colombier for (pOutput = pAnchor;
1370*25b329d5SDavid du Colombier pOutput->pNext != NULL;
1371*25b329d5SDavid du Colombier pOutput = pOutput->pNext)
1372*25b329d5SDavid du Colombier ; /* EMPTY */
1373*25b329d5SDavid du Colombier fail(pOutput == NULL);
1374*25b329d5SDavid du Colombier }
1375*25b329d5SDavid du Colombier usChar = usNextChar(pFile, hdrftr_list,
1376*25b329d5SDavid du Colombier &ulFileOffset, &ulCharPos, NULL);
1377*25b329d5SDavid du Colombier }
1378*25b329d5SDavid du Colombier vCloseFont();
1379*25b329d5SDavid du Colombier if (bOutputContainsText(pAnchor)) {
1380*25b329d5SDavid du Colombier return pAnchor;
1381*25b329d5SDavid du Colombier }
1382*25b329d5SDavid du Colombier pAnchor = pStartNewOutput(pAnchor, NULL);
1383*25b329d5SDavid du Colombier pAnchor->szStorage = xfree(pAnchor->szStorage);
1384*25b329d5SDavid du Colombier pAnchor = xfree(pAnchor);
1385*25b329d5SDavid du Colombier return NULL;
1386*25b329d5SDavid du Colombier } /* end of pHdrFtrDecryptor */
1387*25b329d5SDavid du Colombier
1388*25b329d5SDavid du Colombier /*
1389*25b329d5SDavid du Colombier * pFootnoteDecryptor - turn a footnote text list element into text
1390*25b329d5SDavid du Colombier */
1391*25b329d5SDavid du Colombier char *
szFootnoteDecryptor(FILE * pFile,ULONG ulCharPosStart,ULONG ulCharPosNext)1392*25b329d5SDavid du Colombier szFootnoteDecryptor(FILE *pFile, ULONG ulCharPosStart, ULONG ulCharPosNext)
1393*25b329d5SDavid du Colombier {
1394*25b329d5SDavid du Colombier char *szText;
1395*25b329d5SDavid du Colombier ULONG ulChar, ulFileOffset, ulCharPos;
1396*25b329d5SDavid du Colombier USHORT usChar;
1397*25b329d5SDavid du Colombier size_t tLen, tIndex, tNextFree, tStorageSize;
1398*25b329d5SDavid du Colombier char szResult[6];
1399*25b329d5SDavid du Colombier BOOL bSkip;
1400*25b329d5SDavid du Colombier
1401*25b329d5SDavid du Colombier fail(iWordVersion < 0);
1402*25b329d5SDavid du Colombier fail(tOptions.eConversionType == conversion_unknown);
1403*25b329d5SDavid du Colombier fail(tOptions.eEncoding == 0);
1404*25b329d5SDavid du Colombier
1405*25b329d5SDavid du Colombier if (ulCharPosStart == ulCharPosNext) {
1406*25b329d5SDavid du Colombier /* There are no bytes to decrypt */
1407*25b329d5SDavid du Colombier return NULL;
1408*25b329d5SDavid du Colombier }
1409*25b329d5SDavid du Colombier
1410*25b329d5SDavid du Colombier if (tOptions.eConversionType != conversion_xml) {
1411*25b329d5SDavid du Colombier /* Only implemented for XML output */
1412*25b329d5SDavid du Colombier return NULL;
1413*25b329d5SDavid du Colombier }
1414*25b329d5SDavid du Colombier
1415*25b329d5SDavid du Colombier bSkip = FALSE;
1416*25b329d5SDavid du Colombier
1417*25b329d5SDavid du Colombier /* Initialise the text buffer */
1418*25b329d5SDavid du Colombier tStorageSize = INITIAL_SIZE;
1419*25b329d5SDavid du Colombier szText = xmalloc(tStorageSize);
1420*25b329d5SDavid du Colombier tNextFree = 0;
1421*25b329d5SDavid du Colombier szText[tNextFree] = '\0';
1422*25b329d5SDavid du Colombier
1423*25b329d5SDavid du Colombier /* Goto the start */
1424*25b329d5SDavid du Colombier usChar = usToFootnotePosition(pFile, ulCharPosStart);
1425*25b329d5SDavid du Colombier ulCharPos = ulCharPosStart;
1426*25b329d5SDavid du Colombier ulFileOffset = ulCharPos2FileOffset(ulCharPos);
1427*25b329d5SDavid du Colombier /* Skip the unwanted starting characters */
1428*25b329d5SDavid du Colombier while (usChar != (USHORT)EOF && ulCharPos != ulCharPosNext &&
1429*25b329d5SDavid du Colombier (usChar == FOOTNOTE_OR_ENDNOTE ||
1430*25b329d5SDavid du Colombier usChar == PAR_END ||
1431*25b329d5SDavid du Colombier usChar == TAB ||
1432*25b329d5SDavid du Colombier usChar == (USHORT)' ')) {
1433*25b329d5SDavid du Colombier usChar = usNextChar(pFile, footnote_list,
1434*25b329d5SDavid du Colombier &ulFileOffset, &ulCharPos, NULL);
1435*25b329d5SDavid du Colombier }
1436*25b329d5SDavid du Colombier /* Process the footnote text */
1437*25b329d5SDavid du Colombier while (usChar != (USHORT)EOF && ulCharPos != ulCharPosNext) {
1438*25b329d5SDavid du Colombier /* Skip embedded characters */
1439*25b329d5SDavid du Colombier if (usChar == START_EMBEDDED) {
1440*25b329d5SDavid du Colombier bSkip = TRUE;
1441*25b329d5SDavid du Colombier } else if (usChar == END_IGNORE || usChar == END_EMBEDDED) {
1442*25b329d5SDavid du Colombier bSkip = FALSE;
1443*25b329d5SDavid du Colombier }
1444*25b329d5SDavid du Colombier /* Translate character */
1445*25b329d5SDavid du Colombier if (bSkip ||
1446*25b329d5SDavid du Colombier usChar == END_IGNORE ||
1447*25b329d5SDavid du Colombier usChar == END_EMBEDDED ||
1448*25b329d5SDavid du Colombier usChar == FOOTNOTE_OR_ENDNOTE) {
1449*25b329d5SDavid du Colombier ulChar = IGNORE_CHARACTER;
1450*25b329d5SDavid du Colombier } else {
1451*25b329d5SDavid du Colombier ulChar = ulTranslateCharacters(usChar,
1452*25b329d5SDavid du Colombier ulFileOffset,
1453*25b329d5SDavid du Colombier iWordVersion,
1454*25b329d5SDavid du Colombier tOptions.eConversionType,
1455*25b329d5SDavid du Colombier tOptions.eEncoding,
1456*25b329d5SDavid du Colombier bOldMacFile);
1457*25b329d5SDavid du Colombier }
1458*25b329d5SDavid du Colombier /* Process character */
1459*25b329d5SDavid du Colombier if (ulChar == PICTURE) {
1460*25b329d5SDavid du Colombier tLen = 5;
1461*25b329d5SDavid du Colombier strcpy(szResult, "[pic]");
1462*25b329d5SDavid du Colombier } else if (ulChar == IGNORE_CHARACTER) {
1463*25b329d5SDavid du Colombier tLen = 0;
1464*25b329d5SDavid du Colombier szResult[0] = '\0';
1465*25b329d5SDavid du Colombier } else {
1466*25b329d5SDavid du Colombier switch (ulChar) {
1467*25b329d5SDavid du Colombier case PAR_END:
1468*25b329d5SDavid du Colombier case HARD_RETURN:
1469*25b329d5SDavid du Colombier case PAGE_BREAK:
1470*25b329d5SDavid du Colombier case COLUMN_FEED:
1471*25b329d5SDavid du Colombier ulChar = (ULONG)PAR_END;
1472*25b329d5SDavid du Colombier break;
1473*25b329d5SDavid du Colombier case TAB:
1474*25b329d5SDavid du Colombier ulChar = (ULONG)' ';
1475*25b329d5SDavid du Colombier break;
1476*25b329d5SDavid du Colombier default:
1477*25b329d5SDavid du Colombier break;
1478*25b329d5SDavid du Colombier }
1479*25b329d5SDavid du Colombier tLen = tUcs2Utf8(ulChar, szResult, sizeof(szResult));
1480*25b329d5SDavid du Colombier }
1481*25b329d5SDavid du Colombier /* Add the results to the text */
1482*25b329d5SDavid du Colombier if (tNextFree + tLen + 1 > tStorageSize) {
1483*25b329d5SDavid du Colombier tStorageSize += EXTENTION_SIZE;
1484*25b329d5SDavid du Colombier szText = xrealloc(szText, tStorageSize);
1485*25b329d5SDavid du Colombier }
1486*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < tLen; tIndex++) {
1487*25b329d5SDavid du Colombier szText[tNextFree++] = szResult[tIndex];
1488*25b329d5SDavid du Colombier }
1489*25b329d5SDavid du Colombier szText[tNextFree] = '\0';
1490*25b329d5SDavid du Colombier /* Next character */
1491*25b329d5SDavid du Colombier usChar = usNextChar(pFile, footnote_list,
1492*25b329d5SDavid du Colombier &ulFileOffset, &ulCharPos, NULL);
1493*25b329d5SDavid du Colombier }
1494*25b329d5SDavid du Colombier /* Remove redundant spaces */
1495*25b329d5SDavid du Colombier while (tNextFree != 0 && szText[tNextFree - 1] == ' ') {
1496*25b329d5SDavid du Colombier szText[tNextFree - 1] = '\0';
1497*25b329d5SDavid du Colombier tNextFree--;
1498*25b329d5SDavid du Colombier }
1499*25b329d5SDavid du Colombier if (tNextFree == 0) {
1500*25b329d5SDavid du Colombier /* No text */
1501*25b329d5SDavid du Colombier szText = xfree(szText);
1502*25b329d5SDavid du Colombier return NULL;
1503*25b329d5SDavid du Colombier }
1504*25b329d5SDavid du Colombier return szText;
1505*25b329d5SDavid du Colombier } /* end of szFootnoteDecryptor */
1506