1f5736e95SDavid du Colombier /*
2f5736e95SDavid du Colombier * out2window.c
3*25b329d5SDavid du Colombier * Copyright (C) 1998-2005 A.J. van Os; Released under GPL
4f5736e95SDavid du Colombier *
5f5736e95SDavid du Colombier * Description:
6f5736e95SDavid du Colombier * Output to a text window
7f5736e95SDavid du Colombier */
8f5736e95SDavid du Colombier
9f5736e95SDavid du Colombier #include <string.h>
10f5736e95SDavid du Colombier #include <stdlib.h>
11f5736e95SDavid du Colombier #include <ctype.h>
12f5736e95SDavid du Colombier #include "antiword.h"
13f5736e95SDavid du Colombier
14f5736e95SDavid du Colombier /* Used for numbering the chapters */
15f5736e95SDavid du Colombier static unsigned int auiHdrCounter[9];
16f5736e95SDavid du Colombier
17f5736e95SDavid du Colombier
18f5736e95SDavid du Colombier /*
19f5736e95SDavid du Colombier * vString2Diagram - put a string into a diagram
20f5736e95SDavid du Colombier */
21f5736e95SDavid du Colombier static void
vString2Diagram(diagram_type * pDiag,output_type * pAnchor)22f5736e95SDavid du Colombier vString2Diagram(diagram_type *pDiag, output_type *pAnchor)
23f5736e95SDavid du Colombier {
24f5736e95SDavid du Colombier output_type *pOutput;
25f5736e95SDavid du Colombier long lWidth;
26f5736e95SDavid du Colombier USHORT usMaxFontSize;
27f5736e95SDavid du Colombier
28*25b329d5SDavid du Colombier TRACE_MSG("vString2Diagram");
29*25b329d5SDavid du Colombier
30f5736e95SDavid du Colombier fail(pDiag == NULL);
31f5736e95SDavid du Colombier fail(pAnchor == NULL);
32f5736e95SDavid du Colombier
33f5736e95SDavid du Colombier /* Compute the maximum fontsize in this string */
34f5736e95SDavid du Colombier usMaxFontSize = MIN_FONT_SIZE;
35f5736e95SDavid du Colombier for (pOutput = pAnchor; pOutput != NULL; pOutput = pOutput->pNext) {
36f5736e95SDavid du Colombier if (pOutput->usFontSize > usMaxFontSize) {
37f5736e95SDavid du Colombier usMaxFontSize = pOutput->usFontSize;
38f5736e95SDavid du Colombier }
39f5736e95SDavid du Colombier }
40f5736e95SDavid du Colombier
41f5736e95SDavid du Colombier /* Goto the next line */
42f5736e95SDavid du Colombier vMove2NextLine(pDiag, pAnchor->tFontRef, usMaxFontSize);
43f5736e95SDavid du Colombier
44f5736e95SDavid du Colombier /* Output all substrings */
45f5736e95SDavid du Colombier for (pOutput = pAnchor; pOutput != NULL; pOutput = pOutput->pNext) {
46f5736e95SDavid du Colombier lWidth = lMilliPoints2DrawUnits(pOutput->lStringWidth);
47f5736e95SDavid du Colombier vSubstring2Diagram(pDiag, pOutput->szStorage,
48f5736e95SDavid du Colombier pOutput->tNextFree, lWidth, pOutput->ucFontColor,
49f5736e95SDavid du Colombier pOutput->usFontStyle, pOutput->tFontRef,
50f5736e95SDavid du Colombier pOutput->usFontSize, usMaxFontSize);
51f5736e95SDavid du Colombier }
52f5736e95SDavid du Colombier
53f5736e95SDavid du Colombier /* Goto the start of the line */
54f5736e95SDavid du Colombier pDiag->lXleft = 0;
55*25b329d5SDavid du Colombier TRACE_MSG("leaving vString2Diagram");
56f5736e95SDavid du Colombier } /* end of vString2Diagram */
57f5736e95SDavid du Colombier
58f5736e95SDavid du Colombier /*
59f5736e95SDavid du Colombier * vSetLeftIndentation - set the left indentation of the specified diagram
60f5736e95SDavid du Colombier */
61f5736e95SDavid du Colombier void
vSetLeftIndentation(diagram_type * pDiag,long lLeftIndentation)62f5736e95SDavid du Colombier vSetLeftIndentation(diagram_type *pDiag, long lLeftIndentation)
63f5736e95SDavid du Colombier {
64f5736e95SDavid du Colombier long lX;
65f5736e95SDavid du Colombier
66*25b329d5SDavid du Colombier TRACE_MSG("vSetLeftIndentation");
67*25b329d5SDavid du Colombier
68f5736e95SDavid du Colombier fail(pDiag == NULL);
69f5736e95SDavid du Colombier fail(lLeftIndentation < 0);
70f5736e95SDavid du Colombier
71f5736e95SDavid du Colombier lX = lMilliPoints2DrawUnits(lLeftIndentation);
72f5736e95SDavid du Colombier if (lX > 0) {
73f5736e95SDavid du Colombier pDiag->lXleft = lX;
74f5736e95SDavid du Colombier } else {
75f5736e95SDavid du Colombier pDiag->lXleft = 0;
76f5736e95SDavid du Colombier }
77f5736e95SDavid du Colombier } /* end of vSetLeftIndentation */
78f5736e95SDavid du Colombier
79f5736e95SDavid du Colombier /*
80f5736e95SDavid du Colombier * lComputeNetWidth - compute the net string width
81f5736e95SDavid du Colombier */
82f5736e95SDavid du Colombier static long
lComputeNetWidth(output_type * pAnchor)83f5736e95SDavid du Colombier lComputeNetWidth(output_type *pAnchor)
84f5736e95SDavid du Colombier {
85f5736e95SDavid du Colombier output_type *pTmp;
86f5736e95SDavid du Colombier long lNetWidth;
87f5736e95SDavid du Colombier
88*25b329d5SDavid du Colombier TRACE_MSG("lComputeNetWidth");
89*25b329d5SDavid du Colombier
90f5736e95SDavid du Colombier fail(pAnchor == NULL);
91f5736e95SDavid du Colombier
92f5736e95SDavid du Colombier /* Step 1: Count all but the last sub-string */
93f5736e95SDavid du Colombier lNetWidth = 0;
94f5736e95SDavid du Colombier for (pTmp = pAnchor; pTmp->pNext != NULL; pTmp = pTmp->pNext) {
95f5736e95SDavid du Colombier fail(pTmp->lStringWidth < 0);
96f5736e95SDavid du Colombier lNetWidth += pTmp->lStringWidth;
97f5736e95SDavid du Colombier }
98f5736e95SDavid du Colombier fail(pTmp == NULL);
99f5736e95SDavid du Colombier fail(pTmp->pNext != NULL);
100f5736e95SDavid du Colombier
101f5736e95SDavid du Colombier /* Step 2: remove the white-space from the end of the string */
102f5736e95SDavid du Colombier while (pTmp->tNextFree != 0 &&
103f5736e95SDavid du Colombier isspace((int)(UCHAR)pTmp->szStorage[pTmp->tNextFree - 1])) {
104f5736e95SDavid du Colombier pTmp->szStorage[pTmp->tNextFree - 1] = '\0';
105f5736e95SDavid du Colombier pTmp->tNextFree--;
106f5736e95SDavid du Colombier NO_DBG_DEC(pTmp->lStringWidth);
107f5736e95SDavid du Colombier pTmp->lStringWidth = lComputeStringWidth(
108f5736e95SDavid du Colombier pTmp->szStorage,
109f5736e95SDavid du Colombier pTmp->tNextFree,
110f5736e95SDavid du Colombier pTmp->tFontRef,
111f5736e95SDavid du Colombier pTmp->usFontSize);
112f5736e95SDavid du Colombier NO_DBG_DEC(pTmp->lStringWidth);
113f5736e95SDavid du Colombier }
114f5736e95SDavid du Colombier
115f5736e95SDavid du Colombier /* Step 3: Count the last sub-string */
116f5736e95SDavid du Colombier lNetWidth += pTmp->lStringWidth;
117f5736e95SDavid du Colombier return lNetWidth;
118f5736e95SDavid du Colombier } /* end of lComputeNetWidth */
119f5736e95SDavid du Colombier
120f5736e95SDavid du Colombier /*
121f5736e95SDavid du Colombier * iComputeHoles - compute number of holes
122f5736e95SDavid du Colombier * (A hole is a number of whitespace characters followed by a
123f5736e95SDavid du Colombier * non-whitespace character)
124f5736e95SDavid du Colombier */
125f5736e95SDavid du Colombier static int
iComputeHoles(output_type * pAnchor)126f5736e95SDavid du Colombier iComputeHoles(output_type *pAnchor)
127f5736e95SDavid du Colombier {
128f5736e95SDavid du Colombier output_type *pTmp;
129f5736e95SDavid du Colombier size_t tIndex;
130f5736e95SDavid du Colombier int iCounter;
131f5736e95SDavid du Colombier BOOL bWasSpace, bIsSpace;
132f5736e95SDavid du Colombier
133*25b329d5SDavid du Colombier TRACE_MSG("iComputeHoles");
134*25b329d5SDavid du Colombier
135f5736e95SDavid du Colombier fail(pAnchor == NULL);
136f5736e95SDavid du Colombier
137f5736e95SDavid du Colombier iCounter = 0;
138f5736e95SDavid du Colombier bIsSpace = FALSE;
139f5736e95SDavid du Colombier /* Count the holes */
140f5736e95SDavid du Colombier for (pTmp = pAnchor; pTmp != NULL; pTmp = pTmp->pNext) {
141f5736e95SDavid du Colombier fail(pTmp->tNextFree != strlen(pTmp->szStorage));
142f5736e95SDavid du Colombier for (tIndex = 0; tIndex <= pTmp->tNextFree; tIndex++) {
143f5736e95SDavid du Colombier bWasSpace = bIsSpace;
144f5736e95SDavid du Colombier bIsSpace = isspace((int)(UCHAR)pTmp->szStorage[tIndex]);
145f5736e95SDavid du Colombier if (bWasSpace && !bIsSpace) {
146f5736e95SDavid du Colombier iCounter++;
147f5736e95SDavid du Colombier }
148f5736e95SDavid du Colombier }
149f5736e95SDavid du Colombier }
150f5736e95SDavid du Colombier return iCounter;
151f5736e95SDavid du Colombier } /* end of iComputeHoles */
152f5736e95SDavid du Colombier
153f5736e95SDavid du Colombier /*
154*25b329d5SDavid du Colombier * vAlign2Window - Align a string and insert it into the text
155f5736e95SDavid du Colombier */
156f5736e95SDavid du Colombier void
vAlign2Window(diagram_type * pDiag,output_type * pAnchor,long lScreenWidth,UCHAR ucAlignment)157f5736e95SDavid du Colombier vAlign2Window(diagram_type *pDiag, output_type *pAnchor,
158f5736e95SDavid du Colombier long lScreenWidth, UCHAR ucAlignment)
159f5736e95SDavid du Colombier {
160f5736e95SDavid du Colombier long lNetWidth, lLeftIndentation;
161f5736e95SDavid du Colombier
162*25b329d5SDavid du Colombier TRACE_MSG("vAlign2Window");
163*25b329d5SDavid du Colombier
164f5736e95SDavid du Colombier fail(pDiag == NULL || pAnchor == NULL);
165f5736e95SDavid du Colombier fail(lScreenWidth < lChar2MilliPoints(MIN_SCREEN_WIDTH));
166f5736e95SDavid du Colombier
167f5736e95SDavid du Colombier lNetWidth = lComputeNetWidth(pAnchor);
168f5736e95SDavid du Colombier
169f5736e95SDavid du Colombier if (lScreenWidth > lChar2MilliPoints(MAX_SCREEN_WIDTH) ||
170f5736e95SDavid du Colombier lNetWidth <= 0) {
171f5736e95SDavid du Colombier /*
172f5736e95SDavid du Colombier * Screenwidth is "infinite", so no alignment is possible
173f5736e95SDavid du Colombier * Don't bother to align an empty line
174f5736e95SDavid du Colombier */
175f5736e95SDavid du Colombier vString2Diagram(pDiag, pAnchor);
176*25b329d5SDavid du Colombier TRACE_MSG("leaving vAlign2Window #1");
177f5736e95SDavid du Colombier return;
178f5736e95SDavid du Colombier }
179f5736e95SDavid du Colombier
180f5736e95SDavid du Colombier switch (ucAlignment) {
181f5736e95SDavid du Colombier case ALIGNMENT_CENTER:
182f5736e95SDavid du Colombier lLeftIndentation = (lScreenWidth - lNetWidth) / 2;
183f5736e95SDavid du Colombier DBG_DEC_C(lLeftIndentation < 0, lLeftIndentation);
184f5736e95SDavid du Colombier if (lLeftIndentation > 0) {
185f5736e95SDavid du Colombier vSetLeftIndentation(pDiag, lLeftIndentation);
186f5736e95SDavid du Colombier }
187f5736e95SDavid du Colombier break;
188f5736e95SDavid du Colombier case ALIGNMENT_RIGHT:
189f5736e95SDavid du Colombier lLeftIndentation = lScreenWidth - lNetWidth;
190f5736e95SDavid du Colombier DBG_DEC_C(lLeftIndentation < 0, lLeftIndentation);
191f5736e95SDavid du Colombier if (lLeftIndentation > 0) {
192f5736e95SDavid du Colombier vSetLeftIndentation(pDiag, lLeftIndentation);
193f5736e95SDavid du Colombier }
194f5736e95SDavid du Colombier break;
195f5736e95SDavid du Colombier case ALIGNMENT_JUSTIFY:
196f5736e95SDavid du Colombier case ALIGNMENT_LEFT:
197f5736e95SDavid du Colombier default:
198f5736e95SDavid du Colombier break;
199f5736e95SDavid du Colombier }
200f5736e95SDavid du Colombier vString2Diagram(pDiag, pAnchor);
201*25b329d5SDavid du Colombier TRACE_MSG("leaving vAlign2Window #2");
202f5736e95SDavid du Colombier } /* end of vAlign2Window */
203f5736e95SDavid du Colombier
204f5736e95SDavid du Colombier /*
205*25b329d5SDavid du Colombier * vJustify2Window - Justify a string and insert it into the text
206f5736e95SDavid du Colombier */
207f5736e95SDavid du Colombier void
vJustify2Window(diagram_type * pDiag,output_type * pAnchor,long lScreenWidth,long lRightIndentation,UCHAR ucAlignment)208f5736e95SDavid du Colombier vJustify2Window(diagram_type *pDiag, output_type *pAnchor,
209f5736e95SDavid du Colombier long lScreenWidth, long lRightIndentation, UCHAR ucAlignment)
210f5736e95SDavid du Colombier {
211f5736e95SDavid du Colombier output_type *pTmp;
212f5736e95SDavid du Colombier char *pcNew, *pcOld, *szStorage;
213f5736e95SDavid du Colombier long lNetWidth, lSpaceWidth, lToAdd;
214f5736e95SDavid du Colombier int iFillerLen, iHoles;
215f5736e95SDavid du Colombier
216*25b329d5SDavid du Colombier TRACE_MSG("vJustify2Window");
217*25b329d5SDavid du Colombier
218f5736e95SDavid du Colombier fail(pDiag == NULL || pAnchor == NULL);
219f5736e95SDavid du Colombier fail(lScreenWidth < MIN_SCREEN_WIDTH);
220f5736e95SDavid du Colombier fail(lRightIndentation > 0);
221f5736e95SDavid du Colombier
222f5736e95SDavid du Colombier if (ucAlignment != ALIGNMENT_JUSTIFY) {
223f5736e95SDavid du Colombier vAlign2Window(pDiag, pAnchor, lScreenWidth, ucAlignment);
224f5736e95SDavid du Colombier return;
225f5736e95SDavid du Colombier }
226f5736e95SDavid du Colombier
227f5736e95SDavid du Colombier lNetWidth = lComputeNetWidth(pAnchor);
228f5736e95SDavid du Colombier
229f5736e95SDavid du Colombier if (lScreenWidth > lChar2MilliPoints(MAX_SCREEN_WIDTH) ||
230f5736e95SDavid du Colombier lNetWidth <= 0) {
231f5736e95SDavid du Colombier /*
232f5736e95SDavid du Colombier * Screenwidth is "infinite", so justify is not possible
233*25b329d5SDavid du Colombier * Don't bother to justify an empty line
234f5736e95SDavid du Colombier */
235f5736e95SDavid du Colombier vString2Diagram(pDiag, pAnchor);
236*25b329d5SDavid du Colombier TRACE_MSG("leaving vJustify2Window #1");
237f5736e95SDavid du Colombier return;
238f5736e95SDavid du Colombier }
239f5736e95SDavid du Colombier
240f5736e95SDavid du Colombier /* Justify */
241f5736e95SDavid du Colombier fail(ucAlignment != ALIGNMENT_JUSTIFY);
242f5736e95SDavid du Colombier lSpaceWidth = lComputeStringWidth(" ", 1,
243f5736e95SDavid du Colombier pAnchor->tFontRef, pAnchor->usFontSize);
244f5736e95SDavid du Colombier lToAdd = lScreenWidth -
245f5736e95SDavid du Colombier lNetWidth -
246f5736e95SDavid du Colombier lDrawUnits2MilliPoints(pDiag->lXleft) +
247f5736e95SDavid du Colombier lRightIndentation;
248f5736e95SDavid du Colombier #if defined(DEBUG)
249f5736e95SDavid du Colombier if (lToAdd / lSpaceWidth < -1) {
250f5736e95SDavid du Colombier DBG_DEC(lSpaceWidth);
251f5736e95SDavid du Colombier DBG_DEC(lToAdd);
252f5736e95SDavid du Colombier DBG_DEC(lScreenWidth);
253f5736e95SDavid du Colombier DBG_DEC(lNetWidth);
254f5736e95SDavid du Colombier DBG_DEC(lDrawUnits2MilliPoints(pDiag->lXleft));
255f5736e95SDavid du Colombier DBG_DEC(pDiag->lXleft);
256f5736e95SDavid du Colombier DBG_DEC(lRightIndentation);
257f5736e95SDavid du Colombier }
258f5736e95SDavid du Colombier #endif /* DEBUG */
259f5736e95SDavid du Colombier lToAdd /= lSpaceWidth;
260f5736e95SDavid du Colombier DBG_DEC_C(lToAdd < 0, lToAdd);
261f5736e95SDavid du Colombier if (lToAdd <= 0) {
262f5736e95SDavid du Colombier vString2Diagram(pDiag, pAnchor);
263*25b329d5SDavid du Colombier TRACE_MSG("leaving vJustify2Window #2");
264f5736e95SDavid du Colombier return;
265f5736e95SDavid du Colombier }
266f5736e95SDavid du Colombier
267f5736e95SDavid du Colombier /* Justify by adding spaces */
268*25b329d5SDavid du Colombier iHoles = iComputeHoles(pAnchor);
269f5736e95SDavid du Colombier for (pTmp = pAnchor; pTmp != NULL; pTmp = pTmp->pNext) {
270f5736e95SDavid du Colombier fail(pTmp->tNextFree != strlen(pTmp->szStorage));
271f5736e95SDavid du Colombier fail(lToAdd < 0);
272f5736e95SDavid du Colombier szStorage = xmalloc(pTmp->tNextFree + (size_t)lToAdd + 1);
273f5736e95SDavid du Colombier pcNew = szStorage;
274f5736e95SDavid du Colombier for (pcOld = pTmp->szStorage; *pcOld != '\0'; pcOld++) {
275f5736e95SDavid du Colombier *pcNew++ = *pcOld;
276f5736e95SDavid du Colombier if (*pcOld == ' ' &&
277f5736e95SDavid du Colombier *(pcOld + 1) != ' ' &&
278f5736e95SDavid du Colombier iHoles > 0) {
279f5736e95SDavid du Colombier iFillerLen = (int)(lToAdd / iHoles);
280f5736e95SDavid du Colombier lToAdd -= iFillerLen;
281f5736e95SDavid du Colombier iHoles--;
282f5736e95SDavid du Colombier for (; iFillerLen > 0; iFillerLen--) {
283f5736e95SDavid du Colombier *pcNew++ = ' ';
284f5736e95SDavid du Colombier }
285f5736e95SDavid du Colombier }
286f5736e95SDavid du Colombier }
287f5736e95SDavid du Colombier *pcNew = '\0';
288f5736e95SDavid du Colombier pTmp->szStorage = xfree(pTmp->szStorage);
289f5736e95SDavid du Colombier pTmp->szStorage = szStorage;
290f5736e95SDavid du Colombier pTmp->tStorageSize = pTmp->tNextFree + (size_t)lToAdd + 1;
291f5736e95SDavid du Colombier pTmp->lStringWidth +=
292f5736e95SDavid du Colombier (pcNew - szStorage - (long)pTmp->tNextFree) *
293f5736e95SDavid du Colombier lSpaceWidth;
294f5736e95SDavid du Colombier fail(pcNew < szStorage);
295f5736e95SDavid du Colombier pTmp->tNextFree = (size_t)(pcNew - szStorage);
296f5736e95SDavid du Colombier fail(pTmp->tNextFree != strlen(pTmp->szStorage));
297f5736e95SDavid du Colombier }
298f5736e95SDavid du Colombier DBG_DEC_C(lToAdd != 0, lToAdd);
299f5736e95SDavid du Colombier vString2Diagram(pDiag, pAnchor);
300*25b329d5SDavid du Colombier TRACE_MSG("leaving vJustify2Window #3");
301f5736e95SDavid du Colombier } /* end of vJustify2Window */
302f5736e95SDavid du Colombier
303f5736e95SDavid du Colombier /*
304f5736e95SDavid du Colombier * vResetStyles - reset the style information variables
305f5736e95SDavid du Colombier */
306f5736e95SDavid du Colombier void
vResetStyles(void)307f5736e95SDavid du Colombier vResetStyles(void)
308f5736e95SDavid du Colombier {
309*25b329d5SDavid du Colombier TRACE_MSG("vResetStyles");
310*25b329d5SDavid du Colombier
311f5736e95SDavid du Colombier (void)memset(auiHdrCounter, 0, sizeof(auiHdrCounter));
312f5736e95SDavid du Colombier } /* end of vResetStyles */
313f5736e95SDavid du Colombier
314f5736e95SDavid du Colombier /*
315*25b329d5SDavid du Colombier * tStyle2Window - Add the style characters to the line
316f5736e95SDavid du Colombier *
317f5736e95SDavid du Colombier * Returns the length of the resulting string
318f5736e95SDavid du Colombier */
319f5736e95SDavid du Colombier size_t
tStyle2Window(char * szLine,size_t tLineSize,const style_block_type * pStyle,const section_block_type * pSection)320*25b329d5SDavid du Colombier tStyle2Window(char *szLine, size_t tLineSize, const style_block_type *pStyle,
321f5736e95SDavid du Colombier const section_block_type *pSection)
322f5736e95SDavid du Colombier {
323f5736e95SDavid du Colombier char *pcTxt;
324*25b329d5SDavid du Colombier size_t tIndex, tStyleIndex;
325f5736e95SDavid du Colombier BOOL bNeedPrevLvl;
326f5736e95SDavid du Colombier level_type_enum eNumType;
327f5736e95SDavid du Colombier UCHAR ucNFC;
328f5736e95SDavid du Colombier
329*25b329d5SDavid du Colombier TRACE_MSG("tStyle2Window");
330*25b329d5SDavid du Colombier
331f5736e95SDavid du Colombier fail(szLine == NULL || pStyle == NULL || pSection == NULL);
332f5736e95SDavid du Colombier
333f5736e95SDavid du Colombier if (pStyle->usIstd == 0 || pStyle->usIstd > 9) {
334f5736e95SDavid du Colombier szLine[0] = '\0';
335f5736e95SDavid du Colombier return 0;
336f5736e95SDavid du Colombier }
337f5736e95SDavid du Colombier
338f5736e95SDavid du Colombier /* Set the numbers */
339*25b329d5SDavid du Colombier tStyleIndex = (size_t)pStyle->usIstd - 1;
340*25b329d5SDavid du Colombier for (tIndex = 0; tIndex < 9; tIndex++) {
341*25b329d5SDavid du Colombier if (tIndex == tStyleIndex) {
342*25b329d5SDavid du Colombier auiHdrCounter[tIndex]++;
343*25b329d5SDavid du Colombier } else if (tIndex > tStyleIndex) {
344*25b329d5SDavid du Colombier auiHdrCounter[tIndex] = 0;
345*25b329d5SDavid du Colombier } else if (auiHdrCounter[tIndex] == 0) {
346*25b329d5SDavid du Colombier auiHdrCounter[tIndex] = 1;
347f5736e95SDavid du Colombier }
348f5736e95SDavid du Colombier }
349f5736e95SDavid du Colombier
350f5736e95SDavid du Colombier eNumType = eGetNumType(pStyle->ucNumLevel);
351f5736e95SDavid du Colombier if (eNumType != level_type_outline) {
352f5736e95SDavid du Colombier szLine[0] = '\0';
353f5736e95SDavid du Colombier return 0;
354f5736e95SDavid du Colombier }
355f5736e95SDavid du Colombier
356f5736e95SDavid du Colombier /* Print the numbers */
357*25b329d5SDavid du Colombier pcTxt = szLine;
358*25b329d5SDavid du Colombier bNeedPrevLvl = (pSection->usNeedPrevLvl & BIT(tStyleIndex)) != 0;
359*25b329d5SDavid du Colombier for (tIndex = 0; tIndex <= tStyleIndex; tIndex++) {
360*25b329d5SDavid du Colombier if (tIndex == tStyleIndex ||
361*25b329d5SDavid du Colombier (bNeedPrevLvl && tIndex < tStyleIndex)) {
362*25b329d5SDavid du Colombier if (pcTxt - szLine >= tLineSize - 25) {
363*25b329d5SDavid du Colombier /* Prevent a possible buffer overflow */
364*25b329d5SDavid du Colombier DBG_DEC(pcTxt - szLine);
365*25b329d5SDavid du Colombier DBG_DEC(tLineSize - 25);
366*25b329d5SDavid du Colombier DBG_FIXME();
367*25b329d5SDavid du Colombier szLine[0] = '\0';
368*25b329d5SDavid du Colombier return 0;
369*25b329d5SDavid du Colombier }
370*25b329d5SDavid du Colombier ucNFC = pSection->aucNFC[tIndex];
371f5736e95SDavid du Colombier switch(ucNFC) {
372f5736e95SDavid du Colombier case LIST_ARABIC_NUM:
373*25b329d5SDavid du Colombier case LIST_NUMBER_TXT:
374*25b329d5SDavid du Colombier case LIST_ORDINAL_TXT:
375f5736e95SDavid du Colombier pcTxt += sprintf(pcTxt, "%u",
376*25b329d5SDavid du Colombier auiHdrCounter[tIndex]);
377f5736e95SDavid du Colombier break;
378f5736e95SDavid du Colombier case LIST_UPPER_ROMAN:
379f5736e95SDavid du Colombier case LIST_LOWER_ROMAN:
380f5736e95SDavid du Colombier pcTxt += tNumber2Roman(
381*25b329d5SDavid du Colombier auiHdrCounter[tIndex],
382f5736e95SDavid du Colombier ucNFC == LIST_UPPER_ROMAN,
383f5736e95SDavid du Colombier pcTxt);
384f5736e95SDavid du Colombier break;
385f5736e95SDavid du Colombier case LIST_UPPER_ALPHA:
386f5736e95SDavid du Colombier case LIST_LOWER_ALPHA:
387f5736e95SDavid du Colombier pcTxt += tNumber2Alpha(
388*25b329d5SDavid du Colombier auiHdrCounter[tIndex],
389f5736e95SDavid du Colombier ucNFC == LIST_UPPER_ALPHA,
390f5736e95SDavid du Colombier pcTxt);
391f5736e95SDavid du Colombier break;
392*25b329d5SDavid du Colombier case LIST_OUTLINE_NUM:
393*25b329d5SDavid du Colombier pcTxt += sprintf(pcTxt, "%02u",
394*25b329d5SDavid du Colombier auiHdrCounter[tIndex]);
395*25b329d5SDavid du Colombier break;
396f5736e95SDavid du Colombier default:
397f5736e95SDavid du Colombier DBG_DEC(ucNFC);
398f5736e95SDavid du Colombier DBG_FIXME();
399f5736e95SDavid du Colombier pcTxt += sprintf(pcTxt, "%u",
400*25b329d5SDavid du Colombier auiHdrCounter[tIndex]);
401f5736e95SDavid du Colombier break;
402f5736e95SDavid du Colombier }
403*25b329d5SDavid du Colombier if (tIndex < tStyleIndex) {
404f5736e95SDavid du Colombier *pcTxt++ = '.';
405*25b329d5SDavid du Colombier } else if (tIndex == tStyleIndex) {
406f5736e95SDavid du Colombier *pcTxt++ = ' ';
407f5736e95SDavid du Colombier }
408f5736e95SDavid du Colombier }
409f5736e95SDavid du Colombier }
410f5736e95SDavid du Colombier *pcTxt = '\0';
411f5736e95SDavid du Colombier NO_DBG_MSG_C((int)pStyle->usIstd >= 1 &&
412f5736e95SDavid du Colombier (int)pStyle->usIstd <= 9 &&
413f5736e95SDavid du Colombier eNumType != level_type_none &&
414f5736e95SDavid du Colombier eNumType != level_type_outline, szLine);
415f5736e95SDavid du Colombier NO_DBG_MSG_C(szLine[0] != '\0', szLine);
416f5736e95SDavid du Colombier fail(pcTxt < szLine);
417f5736e95SDavid du Colombier return (size_t)(pcTxt - szLine);
418f5736e95SDavid du Colombier } /* end of tStyle2Window */
419f5736e95SDavid du Colombier
420f5736e95SDavid du Colombier /*
421f5736e95SDavid du Colombier * vRemoveRowEnd - remove the end of table row indicator
422f5736e95SDavid du Colombier *
423f5736e95SDavid du Colombier * Remove the double TABLE_SEPARATOR characters from the end of the string.
424f5736e95SDavid du Colombier * Special: remove the TABLE_SEPARATOR, 0x0a sequence
425f5736e95SDavid du Colombier */
426f5736e95SDavid du Colombier static void
vRemoveRowEnd(char * szRowTxt)427f5736e95SDavid du Colombier vRemoveRowEnd(char *szRowTxt)
428f5736e95SDavid du Colombier {
429f5736e95SDavid du Colombier int iLastIndex;
430f5736e95SDavid du Colombier
431*25b329d5SDavid du Colombier TRACE_MSG("vRemoveRowEnd");
432*25b329d5SDavid du Colombier
433f5736e95SDavid du Colombier fail(szRowTxt == NULL || szRowTxt[0] == '\0');
434f5736e95SDavid du Colombier
435f5736e95SDavid du Colombier iLastIndex = (int)strlen(szRowTxt) - 1;
436f5736e95SDavid du Colombier
437f5736e95SDavid du Colombier if (szRowTxt[iLastIndex] == TABLE_SEPARATOR ||
438*25b329d5SDavid du Colombier szRowTxt[iLastIndex] == (char)0x0a) {
439f5736e95SDavid du Colombier szRowTxt[iLastIndex] = '\0';
440f5736e95SDavid du Colombier iLastIndex--;
441f5736e95SDavid du Colombier } else {
442f5736e95SDavid du Colombier DBG_HEX(szRowTxt[iLastIndex]);
443f5736e95SDavid du Colombier }
444f5736e95SDavid du Colombier
445*25b329d5SDavid du Colombier if (iLastIndex >= 0 && szRowTxt[iLastIndex] == (char)0x0a) {
446f5736e95SDavid du Colombier szRowTxt[iLastIndex] = '\0';
447f5736e95SDavid du Colombier iLastIndex--;
448f5736e95SDavid du Colombier }
449f5736e95SDavid du Colombier
450f5736e95SDavid du Colombier if (iLastIndex >= 0 && szRowTxt[iLastIndex] == TABLE_SEPARATOR) {
451f5736e95SDavid du Colombier szRowTxt[iLastIndex] = '\0';
452f5736e95SDavid du Colombier return;
453f5736e95SDavid du Colombier }
454f5736e95SDavid du Colombier
455f5736e95SDavid du Colombier DBG_DEC(iLastIndex);
456f5736e95SDavid du Colombier DBG_HEX(szRowTxt[iLastIndex]);
457f5736e95SDavid du Colombier DBG_MSG(szRowTxt);
458f5736e95SDavid du Colombier } /* end of vRemoveRowEnd */
459f5736e95SDavid du Colombier
460f5736e95SDavid du Colombier /*
461f5736e95SDavid du Colombier * tComputeStringLengthMax - max string length in relation to max column width
462f5736e95SDavid du Colombier *
463f5736e95SDavid du Colombier * Return the maximum string length
464f5736e95SDavid du Colombier */
465f5736e95SDavid du Colombier static size_t
tComputeStringLengthMax(const char * szString,size_t tColumnWidthMax)466f5736e95SDavid du Colombier tComputeStringLengthMax(const char *szString, size_t tColumnWidthMax)
467f5736e95SDavid du Colombier {
468f5736e95SDavid du Colombier const char *pcTmp;
469f5736e95SDavid du Colombier size_t tLengthMax, tLenPrev, tLen, tWidth;
470f5736e95SDavid du Colombier
471*25b329d5SDavid du Colombier TRACE_MSG("tComputeStringLengthMax");
472*25b329d5SDavid du Colombier
473f5736e95SDavid du Colombier fail(szString == NULL);
474f5736e95SDavid du Colombier fail(tColumnWidthMax == 0);
475f5736e95SDavid du Colombier
476f5736e95SDavid du Colombier pcTmp = strchr(szString, '\n');
477f5736e95SDavid du Colombier if (pcTmp != NULL) {
478f5736e95SDavid du Colombier tLengthMax = (size_t)(pcTmp - szString + 1);
479f5736e95SDavid du Colombier } else {
480f5736e95SDavid du Colombier tLengthMax = strlen(szString);
481f5736e95SDavid du Colombier }
482f5736e95SDavid du Colombier if (tLengthMax == 0) {
483f5736e95SDavid du Colombier return 0;
484f5736e95SDavid du Colombier }
485f5736e95SDavid du Colombier
486f5736e95SDavid du Colombier tLen = 0;
487f5736e95SDavid du Colombier tWidth = 0;
488f5736e95SDavid du Colombier for (;;) {
489f5736e95SDavid du Colombier tLenPrev = tLen;
490f5736e95SDavid du Colombier tLen += tGetCharacterLength(szString + tLen);
491f5736e95SDavid du Colombier DBG_DEC_C(tLen > tLengthMax, tLen);
492f5736e95SDavid du Colombier DBG_DEC_C(tLen > tLengthMax, tLengthMax);
493f5736e95SDavid du Colombier fail(tLen > tLengthMax);
494f5736e95SDavid du Colombier tWidth = tCountColumns(szString, tLen);
495f5736e95SDavid du Colombier if (tWidth > tColumnWidthMax) {
496f5736e95SDavid du Colombier return tLenPrev;
497f5736e95SDavid du Colombier }
498f5736e95SDavid du Colombier if (tLen >= tLengthMax) {
499f5736e95SDavid du Colombier return tLengthMax;
500f5736e95SDavid du Colombier }
501f5736e95SDavid du Colombier }
502f5736e95SDavid du Colombier } /* end of tComputeStringLengthMax */
503f5736e95SDavid du Colombier
504f5736e95SDavid du Colombier /*
505f5736e95SDavid du Colombier * tGetBreakingPoint - get the number of bytes that fit the column
506f5736e95SDavid du Colombier *
507f5736e95SDavid du Colombier * Returns the number of bytes that fit the column
508f5736e95SDavid du Colombier */
509f5736e95SDavid du Colombier static size_t
tGetBreakingPoint(const char * szString,size_t tLen,size_t tWidth,size_t tColumnWidthMax)510f5736e95SDavid du Colombier tGetBreakingPoint(const char *szString,
511f5736e95SDavid du Colombier size_t tLen, size_t tWidth, size_t tColumnWidthMax)
512f5736e95SDavid du Colombier {
513f5736e95SDavid du Colombier int iIndex;
514f5736e95SDavid du Colombier
515*25b329d5SDavid du Colombier TRACE_MSG("tGetBreakingPoint");
516*25b329d5SDavid du Colombier
517f5736e95SDavid du Colombier fail(szString == NULL);
518f5736e95SDavid du Colombier fail(tLen > strlen(szString));
519f5736e95SDavid du Colombier fail(tWidth > tColumnWidthMax);
520f5736e95SDavid du Colombier
521f5736e95SDavid du Colombier if (tWidth < tColumnWidthMax ||
522f5736e95SDavid du Colombier (tWidth == tColumnWidthMax &&
523f5736e95SDavid du Colombier (szString[tLen] == ' ' ||
524f5736e95SDavid du Colombier szString[tLen] == '\n' ||
525f5736e95SDavid du Colombier szString[tLen] == '\0'))) {
526f5736e95SDavid du Colombier /* The string already fits, do nothing */
527f5736e95SDavid du Colombier return tLen;
528f5736e95SDavid du Colombier }
529f5736e95SDavid du Colombier /* Search for a breaking point */
530f5736e95SDavid du Colombier for (iIndex = (int)tLen - 1; iIndex >= 0; iIndex--) {
531f5736e95SDavid du Colombier if (szString[iIndex] == ' ') {
532f5736e95SDavid du Colombier return (size_t)iIndex;
533f5736e95SDavid du Colombier }
534f5736e95SDavid du Colombier }
535f5736e95SDavid du Colombier /* No breaking point found, just fill the column */
536f5736e95SDavid du Colombier return tLen;
537f5736e95SDavid du Colombier } /* end of tGetBreakingPoint */
538f5736e95SDavid du Colombier
539f5736e95SDavid du Colombier /*
540*25b329d5SDavid du Colombier * tComputeColumnWidthMax - compute the maximum column width
541*25b329d5SDavid du Colombier */
542*25b329d5SDavid du Colombier static size_t
tComputeColumnWidthMax(short sWidth,long lCharWidth,double dFactor)543*25b329d5SDavid du Colombier tComputeColumnWidthMax(short sWidth, long lCharWidth, double dFactor)
544*25b329d5SDavid du Colombier {
545*25b329d5SDavid du Colombier size_t tColumnWidthMax;
546*25b329d5SDavid du Colombier
547*25b329d5SDavid du Colombier TRACE_MSG("tComputeColumnWidthMax");
548*25b329d5SDavid du Colombier
549*25b329d5SDavid du Colombier fail(sWidth < 0);
550*25b329d5SDavid du Colombier fail(lCharWidth <= 0);
551*25b329d5SDavid du Colombier fail(dFactor <= 0.0);
552*25b329d5SDavid du Colombier
553*25b329d5SDavid du Colombier tColumnWidthMax = (size_t)(
554*25b329d5SDavid du Colombier (lTwips2MilliPoints(sWidth) * dFactor + lCharWidth / 2.0) /
555*25b329d5SDavid du Colombier lCharWidth);
556*25b329d5SDavid du Colombier if (tColumnWidthMax == 0) {
557*25b329d5SDavid du Colombier /* Minimum column width */
558*25b329d5SDavid du Colombier return 1;
559*25b329d5SDavid du Colombier }
560*25b329d5SDavid du Colombier if (tColumnWidthMax > 1) {
561*25b329d5SDavid du Colombier /* Make room for the TABLE_SEPARATOR_CHAR */
562*25b329d5SDavid du Colombier tColumnWidthMax--;
563*25b329d5SDavid du Colombier }
564*25b329d5SDavid du Colombier NO_DBG_DEC(tColumnWidthMax);
565*25b329d5SDavid du Colombier return tColumnWidthMax;
566*25b329d5SDavid du Colombier } /* end of tComputeColumnWidthMax */
567*25b329d5SDavid du Colombier
568*25b329d5SDavid du Colombier /*
569f5736e95SDavid du Colombier * vTableRow2Window - put a table row into a diagram
570f5736e95SDavid du Colombier */
571f5736e95SDavid du Colombier void
vTableRow2Window(diagram_type * pDiag,output_type * pOutput,const row_block_type * pRowInfo,conversion_type eConversionType,int iParagraphBreak)572f5736e95SDavid du Colombier vTableRow2Window(diagram_type *pDiag, output_type *pOutput,
573*25b329d5SDavid du Colombier const row_block_type *pRowInfo,
574*25b329d5SDavid du Colombier conversion_type eConversionType, int iParagraphBreak)
575f5736e95SDavid du Colombier {
576f5736e95SDavid du Colombier output_type tRow;
577f5736e95SDavid du Colombier char *aszColTxt[TABLE_COLUMN_MAX];
578f5736e95SDavid du Colombier char *szLine, *pcTxt;
579*25b329d5SDavid du Colombier double dMagnify;
580f5736e95SDavid du Colombier long lCharWidthLarge, lCharWidthSmall;
581*25b329d5SDavid du Colombier size_t tColumnWidthTotal, atColumnWidthMax[TABLE_COLUMN_MAX];
582f5736e95SDavid du Colombier size_t tSize, tColumnWidthMax, tWidth, tLen;
583f5736e95SDavid du Colombier int iIndex, iNbrOfColumns, iTmp;
584f5736e95SDavid du Colombier BOOL bNotReady;
585f5736e95SDavid du Colombier
586*25b329d5SDavid du Colombier TRACE_MSG("vTableRow2Window");
587*25b329d5SDavid du Colombier
588f5736e95SDavid du Colombier fail(pDiag == NULL || pOutput == NULL || pRowInfo == NULL);
589f5736e95SDavid du Colombier fail(pOutput->szStorage == NULL);
590f5736e95SDavid du Colombier fail(pOutput->pNext != NULL);
591*25b329d5SDavid du Colombier fail(iParagraphBreak < 0);
592f5736e95SDavid du Colombier
593f5736e95SDavid du Colombier /* Character sizes */
594f5736e95SDavid du Colombier lCharWidthLarge = lComputeStringWidth("W", 1,
595f5736e95SDavid du Colombier pOutput->tFontRef, pOutput->usFontSize);
596f5736e95SDavid du Colombier NO_DBG_DEC(lCharWidthLarge);
597f5736e95SDavid du Colombier lCharWidthSmall = lComputeStringWidth("i", 1,
598f5736e95SDavid du Colombier pOutput->tFontRef, pOutput->usFontSize);
599f5736e95SDavid du Colombier NO_DBG_DEC(lCharWidthSmall);
600f5736e95SDavid du Colombier /* For the time being: use a fixed width font */
601f5736e95SDavid du Colombier fail(lCharWidthLarge != lCharWidthSmall);
602f5736e95SDavid du Colombier
603f5736e95SDavid du Colombier vRemoveRowEnd(pOutput->szStorage);
604f5736e95SDavid du Colombier
605f5736e95SDavid du Colombier /* Split the row text into a set of column texts */
606f5736e95SDavid du Colombier aszColTxt[0] = pOutput->szStorage;
607f5736e95SDavid du Colombier for (iNbrOfColumns = 1;
608f5736e95SDavid du Colombier iNbrOfColumns < TABLE_COLUMN_MAX;
609f5736e95SDavid du Colombier iNbrOfColumns++) {
610f5736e95SDavid du Colombier aszColTxt[iNbrOfColumns] =
611f5736e95SDavid du Colombier strchr(aszColTxt[iNbrOfColumns - 1],
612f5736e95SDavid du Colombier TABLE_SEPARATOR);
613f5736e95SDavid du Colombier if (aszColTxt[iNbrOfColumns] == NULL) {
614f5736e95SDavid du Colombier break;
615f5736e95SDavid du Colombier }
616f5736e95SDavid du Colombier *aszColTxt[iNbrOfColumns] = '\0';
617f5736e95SDavid du Colombier aszColTxt[iNbrOfColumns]++;
618f5736e95SDavid du Colombier NO_DBG_DEC(iNbrOfColumns);
619f5736e95SDavid du Colombier NO_DBG_MSG(aszColTxt[iNbrOfColumns]);
620f5736e95SDavid du Colombier }
621f5736e95SDavid du Colombier
622*25b329d5SDavid du Colombier /* Work around a bug in Word */
623*25b329d5SDavid du Colombier while (iNbrOfColumns > (int)pRowInfo->ucNumberOfColumns &&
624*25b329d5SDavid du Colombier pRowInfo->asColumnWidth[iNbrOfColumns] == 0) {
625*25b329d5SDavid du Colombier iNbrOfColumns--;
626*25b329d5SDavid du Colombier }
627*25b329d5SDavid du Colombier
628f5736e95SDavid du Colombier DBG_DEC_C(iNbrOfColumns != (int)pRowInfo->ucNumberOfColumns,
629f5736e95SDavid du Colombier iNbrOfColumns);
630f5736e95SDavid du Colombier DBG_DEC_C(iNbrOfColumns != (int)pRowInfo->ucNumberOfColumns,
631f5736e95SDavid du Colombier pRowInfo->ucNumberOfColumns);
632f5736e95SDavid du Colombier if (iNbrOfColumns != (int)pRowInfo->ucNumberOfColumns) {
633f5736e95SDavid du Colombier werr(0, "Skipping an unmatched table row");
634f5736e95SDavid du Colombier return;
635f5736e95SDavid du Colombier }
636f5736e95SDavid du Colombier
637*25b329d5SDavid du Colombier #if defined(__FULL_TEXT_SEARCH)
638*25b329d5SDavid du Colombier /* No table formatting: use for full-text search (untested) */
639*25b329d5SDavid du Colombier for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) {
640*25b329d5SDavid du Colombier fprintf(pDiag->pOutFile, "%s\n" , aszColTxt[iIndex]);
641*25b329d5SDavid du Colombier }
642*25b329d5SDavid du Colombier #else
643f5736e95SDavid du Colombier if (bAddTableRow(pDiag, aszColTxt, iNbrOfColumns,
644f5736e95SDavid du Colombier pRowInfo->asColumnWidth, pRowInfo->ucBorderInfo)) {
645f5736e95SDavid du Colombier /* All work has been done */
646f5736e95SDavid du Colombier return;
647f5736e95SDavid du Colombier }
648f5736e95SDavid du Colombier
649*25b329d5SDavid du Colombier /* Fill the table with maximum column widths */
650*25b329d5SDavid du Colombier if (eConversionType == conversion_text ||
651*25b329d5SDavid du Colombier eConversionType == conversion_fmt_text) {
652*25b329d5SDavid du Colombier if (iParagraphBreak == 0 ||
653*25b329d5SDavid du Colombier iParagraphBreak >= MAX_SCREEN_WIDTH) {
654*25b329d5SDavid du Colombier dMagnify = (double)MAX_SCREEN_WIDTH;
655*25b329d5SDavid du Colombier } else if (iParagraphBreak <= MIN_SCREEN_WIDTH) {
656*25b329d5SDavid du Colombier dMagnify = (double)MIN_SCREEN_WIDTH;
657*25b329d5SDavid du Colombier } else {
658*25b329d5SDavid du Colombier dMagnify = (double)iParagraphBreak;
659*25b329d5SDavid du Colombier }
660*25b329d5SDavid du Colombier dMagnify /= (double)DEFAULT_SCREEN_WIDTH;
661*25b329d5SDavid du Colombier DBG_FLT_C(dMagnify < 0.99 || dMagnify > 1.01, dMagnify);
662*25b329d5SDavid du Colombier } else {
663*25b329d5SDavid du Colombier dMagnify = 1.0;
664*25b329d5SDavid du Colombier }
665*25b329d5SDavid du Colombier tColumnWidthTotal = 0;
666*25b329d5SDavid du Colombier for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) {
667*25b329d5SDavid du Colombier atColumnWidthMax[iIndex] = tComputeColumnWidthMax(
668*25b329d5SDavid du Colombier pRowInfo->asColumnWidth[iIndex],
669*25b329d5SDavid du Colombier lCharWidthLarge,
670*25b329d5SDavid du Colombier dMagnify);
671*25b329d5SDavid du Colombier tColumnWidthTotal += atColumnWidthMax[iIndex];
672*25b329d5SDavid du Colombier }
673*25b329d5SDavid du Colombier
674f5736e95SDavid du Colombier /*
675f5736e95SDavid du Colombier * Get enough space for the row.
676f5736e95SDavid du Colombier * Worst case: three bytes per UTF-8 character
677f5736e95SDavid du Colombier */
678*25b329d5SDavid du Colombier tSize = 3 * (1 + tColumnWidthTotal + (size_t)iNbrOfColumns + 3);
679f5736e95SDavid du Colombier szLine = xmalloc(tSize);
680f5736e95SDavid du Colombier
681f5736e95SDavid du Colombier do {
682f5736e95SDavid du Colombier /* Print one line of a table row */
683f5736e95SDavid du Colombier bNotReady = FALSE;
684f5736e95SDavid du Colombier pcTxt = szLine;
685f5736e95SDavid du Colombier *pcTxt++ = TABLE_SEPARATOR_CHAR;
686f5736e95SDavid du Colombier for (iIndex = 0; iIndex < iNbrOfColumns; iIndex++) {
687*25b329d5SDavid du Colombier tColumnWidthMax = atColumnWidthMax[iIndex];
688f5736e95SDavid du Colombier if (aszColTxt[iIndex] == NULL) {
689f5736e95SDavid du Colombier /* Add an empty column */
690f5736e95SDavid du Colombier for (iTmp = 0;
691f5736e95SDavid du Colombier iTmp < (int)tColumnWidthMax;
692f5736e95SDavid du Colombier iTmp++) {
693f5736e95SDavid du Colombier *pcTxt++ = (char)FILLER_CHAR;
694f5736e95SDavid du Colombier }
695f5736e95SDavid du Colombier *pcTxt++ = TABLE_SEPARATOR_CHAR;
696f5736e95SDavid du Colombier *pcTxt = '\0';
697f5736e95SDavid du Colombier continue;
698f5736e95SDavid du Colombier }
699f5736e95SDavid du Colombier /* Compute the length and width of the column text */
700f5736e95SDavid du Colombier tLen = tComputeStringLengthMax(
701f5736e95SDavid du Colombier aszColTxt[iIndex], tColumnWidthMax);
702f5736e95SDavid du Colombier NO_DBG_DEC(tLen);
703f5736e95SDavid du Colombier while (tLen != 0 &&
704f5736e95SDavid du Colombier (aszColTxt[iIndex][tLen - 1] == '\n' ||
705f5736e95SDavid du Colombier aszColTxt[iIndex][tLen - 1] == ' ')) {
706f5736e95SDavid du Colombier aszColTxt[iIndex][tLen - 1] = ' ';
707f5736e95SDavid du Colombier tLen--;
708f5736e95SDavid du Colombier }
709f5736e95SDavid du Colombier tWidth = tCountColumns(aszColTxt[iIndex], tLen);
710f5736e95SDavid du Colombier fail(tWidth > tColumnWidthMax);
711f5736e95SDavid du Colombier tLen = tGetBreakingPoint(aszColTxt[iIndex],
712f5736e95SDavid du Colombier tLen, tWidth, tColumnWidthMax);
713f5736e95SDavid du Colombier tWidth = tCountColumns(aszColTxt[iIndex], tLen);
714f5736e95SDavid du Colombier if (tLen == 0 && *aszColTxt[iIndex] == '\0') {
715f5736e95SDavid du Colombier /* No text at all */
716f5736e95SDavid du Colombier aszColTxt[iIndex] = NULL;
717f5736e95SDavid du Colombier } else {
718f5736e95SDavid du Colombier /* Add the text */
719f5736e95SDavid du Colombier pcTxt += sprintf(pcTxt,
720f5736e95SDavid du Colombier "%.*s", (int)tLen, aszColTxt[iIndex]);
721f5736e95SDavid du Colombier if (tLen == 0 && *aszColTxt[iIndex] != ' ') {
722f5736e95SDavid du Colombier tLen = tGetCharacterLength(
723f5736e95SDavid du Colombier aszColTxt[iIndex]);
724f5736e95SDavid du Colombier DBG_CHR(*aszColTxt[iIndex]);
725f5736e95SDavid du Colombier DBG_FIXME();
726f5736e95SDavid du Colombier fail(tLen == 0);
727f5736e95SDavid du Colombier }
728f5736e95SDavid du Colombier aszColTxt[iIndex] += tLen;
729f5736e95SDavid du Colombier while (*aszColTxt[iIndex] == ' ') {
730f5736e95SDavid du Colombier aszColTxt[iIndex]++;
731f5736e95SDavid du Colombier }
732f5736e95SDavid du Colombier if (*aszColTxt[iIndex] == '\0') {
733f5736e95SDavid du Colombier /* This row is now complete */
734f5736e95SDavid du Colombier aszColTxt[iIndex] = NULL;
735f5736e95SDavid du Colombier } else {
736f5736e95SDavid du Colombier /* This row needs more lines */
737f5736e95SDavid du Colombier bNotReady = TRUE;
738f5736e95SDavid du Colombier }
739f5736e95SDavid du Colombier }
740f5736e95SDavid du Colombier /* Fill up the rest */
741f5736e95SDavid du Colombier for (iTmp = 0;
742f5736e95SDavid du Colombier iTmp < (int)tColumnWidthMax - (int)tWidth;
743f5736e95SDavid du Colombier iTmp++) {
744f5736e95SDavid du Colombier *pcTxt++ = (char)FILLER_CHAR;
745f5736e95SDavid du Colombier }
746f5736e95SDavid du Colombier /* End of column */
747f5736e95SDavid du Colombier *pcTxt++ = TABLE_SEPARATOR_CHAR;
748f5736e95SDavid du Colombier *pcTxt = '\0';
749f5736e95SDavid du Colombier }
750f5736e95SDavid du Colombier /* Output the table row line */
751f5736e95SDavid du Colombier *pcTxt = '\0';
752f5736e95SDavid du Colombier tRow = *pOutput;
753f5736e95SDavid du Colombier tRow.szStorage = szLine;
754f5736e95SDavid du Colombier fail(pcTxt < szLine);
755f5736e95SDavid du Colombier tRow.tNextFree = (size_t)(pcTxt - szLine);
756f5736e95SDavid du Colombier tRow.lStringWidth = lComputeStringWidth(
757f5736e95SDavid du Colombier tRow.szStorage,
758f5736e95SDavid du Colombier tRow.tNextFree,
759f5736e95SDavid du Colombier tRow.tFontRef,
760f5736e95SDavid du Colombier tRow.usFontSize);
761f5736e95SDavid du Colombier vString2Diagram(pDiag, &tRow);
762*25b329d5SDavid du Colombier TRACE_MSG("after vString2Diagram in vTableRow2Window");
763f5736e95SDavid du Colombier } while (bNotReady);
764f5736e95SDavid du Colombier /* Clean up before you leave */
765f5736e95SDavid du Colombier szLine = xfree(szLine);
766*25b329d5SDavid du Colombier TRACE_MSG("leaving vTableRow2Window");
767*25b329d5SDavid du Colombier #endif /* __FULL_TEXT_SEARCH */
768f5736e95SDavid du Colombier } /* end of vTableRow2Window */
769