3 * Copyright (C) 1998-2005 A.J. van Os; Released under GPL
6 * Output to a text window
14 /* Used for numbering the chapters */
15 static unsigned int auiHdrCounter
[9];
19 * vString2Diagram - put a string into a diagram
22 vString2Diagram(diagram_type
*pDiag
, output_type
*pAnchor
)
28 TRACE_MSG("vString2Diagram");
31 fail(pAnchor
== NULL
);
33 /* Compute the maximum fontsize in this string */
34 usMaxFontSize
= MIN_FONT_SIZE
;
35 for (pOutput
= pAnchor
; pOutput
!= NULL
; pOutput
= pOutput
->pNext
) {
36 if (pOutput
->usFontSize
> usMaxFontSize
) {
37 usMaxFontSize
= pOutput
->usFontSize
;
41 /* Goto the next line */
42 vMove2NextLine(pDiag
, pAnchor
->tFontRef
, usMaxFontSize
);
44 /* Output all substrings */
45 for (pOutput
= pAnchor
; pOutput
!= NULL
; pOutput
= pOutput
->pNext
) {
46 lWidth
= lMilliPoints2DrawUnits(pOutput
->lStringWidth
);
47 vSubstring2Diagram(pDiag
, pOutput
->szStorage
,
48 pOutput
->tNextFree
, lWidth
, pOutput
->ucFontColor
,
49 pOutput
->usFontStyle
, pOutput
->tFontRef
,
50 pOutput
->usFontSize
, usMaxFontSize
);
53 /* Goto the start of the line */
55 TRACE_MSG("leaving vString2Diagram");
56 } /* end of vString2Diagram */
59 * vSetLeftIndentation - set the left indentation of the specified diagram
62 vSetLeftIndentation(diagram_type
*pDiag
, long lLeftIndentation
)
66 TRACE_MSG("vSetLeftIndentation");
69 fail(lLeftIndentation
< 0);
71 lX
= lMilliPoints2DrawUnits(lLeftIndentation
);
77 } /* end of vSetLeftIndentation */
80 * lComputeNetWidth - compute the net string width
83 lComputeNetWidth(output_type
*pAnchor
)
88 TRACE_MSG("lComputeNetWidth");
90 fail(pAnchor
== NULL
);
92 /* Step 1: Count all but the last sub-string */
94 for (pTmp
= pAnchor
; pTmp
->pNext
!= NULL
; pTmp
= pTmp
->pNext
) {
95 fail(pTmp
->lStringWidth
< 0);
96 lNetWidth
+= pTmp
->lStringWidth
;
99 fail(pTmp
->pNext
!= NULL
);
101 /* Step 2: remove the white-space from the end of the string */
102 while (pTmp
->tNextFree
!= 0 &&
103 isspace((int)(UCHAR
)pTmp
->szStorage
[pTmp
->tNextFree
- 1])) {
104 pTmp
->szStorage
[pTmp
->tNextFree
- 1] = '\0';
106 NO_DBG_DEC(pTmp
->lStringWidth
);
107 pTmp
->lStringWidth
= lComputeStringWidth(
112 NO_DBG_DEC(pTmp
->lStringWidth
);
115 /* Step 3: Count the last sub-string */
116 lNetWidth
+= pTmp
->lStringWidth
;
118 } /* end of lComputeNetWidth */
121 * iComputeHoles - compute number of holes
122 * (A hole is a number of whitespace characters followed by a
123 * non-whitespace character)
126 iComputeHoles(output_type
*pAnchor
)
131 BOOL bWasSpace
, bIsSpace
;
133 TRACE_MSG("iComputeHoles");
135 fail(pAnchor
== NULL
);
139 /* Count the holes */
140 for (pTmp
= pAnchor
; pTmp
!= NULL
; pTmp
= pTmp
->pNext
) {
141 fail(pTmp
->tNextFree
!= strlen(pTmp
->szStorage
));
142 for (tIndex
= 0; tIndex
<= pTmp
->tNextFree
; tIndex
++) {
143 bWasSpace
= bIsSpace
;
144 bIsSpace
= isspace((int)(UCHAR
)pTmp
->szStorage
[tIndex
]);
145 if (bWasSpace
&& !bIsSpace
) {
151 } /* end of iComputeHoles */
154 * vAlign2Window - Align a string and insert it into the text
157 vAlign2Window(diagram_type
*pDiag
, output_type
*pAnchor
,
158 long lScreenWidth
, UCHAR ucAlignment
)
160 long lNetWidth
, lLeftIndentation
;
162 TRACE_MSG("vAlign2Window");
164 fail(pDiag
== NULL
|| pAnchor
== NULL
);
165 fail(lScreenWidth
< lChar2MilliPoints(MIN_SCREEN_WIDTH
));
167 lNetWidth
= lComputeNetWidth(pAnchor
);
169 if (lScreenWidth
> lChar2MilliPoints(MAX_SCREEN_WIDTH
) ||
172 * Screenwidth is "infinite", so no alignment is possible
173 * Don't bother to align an empty line
175 vString2Diagram(pDiag
, pAnchor
);
176 TRACE_MSG("leaving vAlign2Window #1");
180 switch (ucAlignment
) {
181 case ALIGNMENT_CENTER
:
182 lLeftIndentation
= (lScreenWidth
- lNetWidth
) / 2;
183 DBG_DEC_C(lLeftIndentation
< 0, lLeftIndentation
);
184 if (lLeftIndentation
> 0) {
185 vSetLeftIndentation(pDiag
, lLeftIndentation
);
188 case ALIGNMENT_RIGHT
:
189 lLeftIndentation
= lScreenWidth
- lNetWidth
;
190 DBG_DEC_C(lLeftIndentation
< 0, lLeftIndentation
);
191 if (lLeftIndentation
> 0) {
192 vSetLeftIndentation(pDiag
, lLeftIndentation
);
195 case ALIGNMENT_JUSTIFY
:
200 vString2Diagram(pDiag
, pAnchor
);
201 TRACE_MSG("leaving vAlign2Window #2");
202 } /* end of vAlign2Window */
205 * vJustify2Window - Justify a string and insert it into the text
208 vJustify2Window(diagram_type
*pDiag
, output_type
*pAnchor
,
209 long lScreenWidth
, long lRightIndentation
, UCHAR ucAlignment
)
212 char *pcNew
, *pcOld
, *szStorage
;
213 long lNetWidth
, lSpaceWidth
, lToAdd
;
214 int iFillerLen
, iHoles
;
216 TRACE_MSG("vJustify2Window");
218 fail(pDiag
== NULL
|| pAnchor
== NULL
);
219 fail(lScreenWidth
< MIN_SCREEN_WIDTH
);
220 fail(lRightIndentation
> 0);
222 if (ucAlignment
!= ALIGNMENT_JUSTIFY
) {
223 vAlign2Window(pDiag
, pAnchor
, lScreenWidth
, ucAlignment
);
227 lNetWidth
= lComputeNetWidth(pAnchor
);
229 if (lScreenWidth
> lChar2MilliPoints(MAX_SCREEN_WIDTH
) ||
232 * Screenwidth is "infinite", so justify is not possible
233 * Don't bother to justify an empty line
235 vString2Diagram(pDiag
, pAnchor
);
236 TRACE_MSG("leaving vJustify2Window #1");
241 fail(ucAlignment
!= ALIGNMENT_JUSTIFY
);
242 lSpaceWidth
= lComputeStringWidth(" ", 1,
243 pAnchor
->tFontRef
, pAnchor
->usFontSize
);
244 lToAdd
= lScreenWidth
-
246 lDrawUnits2MilliPoints(pDiag
->lXleft
) +
249 if (lToAdd
/ lSpaceWidth
< -1) {
250 DBG_DEC(lSpaceWidth
);
252 DBG_DEC(lScreenWidth
);
254 DBG_DEC(lDrawUnits2MilliPoints(pDiag
->lXleft
));
255 DBG_DEC(pDiag
->lXleft
);
256 DBG_DEC(lRightIndentation
);
259 lToAdd
/= lSpaceWidth
;
260 DBG_DEC_C(lToAdd
< 0, lToAdd
);
262 vString2Diagram(pDiag
, pAnchor
);
263 TRACE_MSG("leaving vJustify2Window #2");
267 /* Justify by adding spaces */
268 iHoles
= iComputeHoles(pAnchor
);
269 for (pTmp
= pAnchor
; pTmp
!= NULL
; pTmp
= pTmp
->pNext
) {
270 fail(pTmp
->tNextFree
!= strlen(pTmp
->szStorage
));
272 szStorage
= xmalloc(pTmp
->tNextFree
+ (size_t)lToAdd
+ 1);
274 for (pcOld
= pTmp
->szStorage
; *pcOld
!= '\0'; pcOld
++) {
277 *(pcOld
+ 1) != ' ' &&
279 iFillerLen
= (int)(lToAdd
/ iHoles
);
280 lToAdd
-= iFillerLen
;
282 for (; iFillerLen
> 0; iFillerLen
--) {
288 pTmp
->szStorage
= xfree(pTmp
->szStorage
);
289 pTmp
->szStorage
= szStorage
;
290 pTmp
->tStorageSize
= pTmp
->tNextFree
+ (size_t)lToAdd
+ 1;
291 pTmp
->lStringWidth
+=
292 (pcNew
- szStorage
- (long)pTmp
->tNextFree
) *
294 fail(pcNew
< szStorage
);
295 pTmp
->tNextFree
= (size_t)(pcNew
- szStorage
);
296 fail(pTmp
->tNextFree
!= strlen(pTmp
->szStorage
));
298 DBG_DEC_C(lToAdd
!= 0, lToAdd
);
299 vString2Diagram(pDiag
, pAnchor
);
300 TRACE_MSG("leaving vJustify2Window #3");
301 } /* end of vJustify2Window */
304 * vResetStyles - reset the style information variables
309 TRACE_MSG("vResetStyles");
311 (void)memset(auiHdrCounter
, 0, sizeof(auiHdrCounter
));
312 } /* end of vResetStyles */
315 * tStyle2Window - Add the style characters to the line
317 * Returns the length of the resulting string
320 tStyle2Window(char *szLine
, size_t tLineSize
, const style_block_type
*pStyle
,
321 const section_block_type
*pSection
)
324 size_t tIndex
, tStyleIndex
;
326 level_type_enum eNumType
;
329 TRACE_MSG("tStyle2Window");
331 fail(szLine
== NULL
|| pStyle
== NULL
|| pSection
== NULL
);
333 if (pStyle
->usIstd
== 0 || pStyle
->usIstd
> 9) {
338 /* Set the numbers */
339 tStyleIndex
= (size_t)pStyle
->usIstd
- 1;
340 for (tIndex
= 0; tIndex
< 9; tIndex
++) {
341 if (tIndex
== tStyleIndex
) {
342 auiHdrCounter
[tIndex
]++;
343 } else if (tIndex
> tStyleIndex
) {
344 auiHdrCounter
[tIndex
] = 0;
345 } else if (auiHdrCounter
[tIndex
] == 0) {
346 auiHdrCounter
[tIndex
] = 1;
350 eNumType
= eGetNumType(pStyle
->ucNumLevel
);
351 if (eNumType
!= level_type_outline
) {
356 /* Print the numbers */
358 bNeedPrevLvl
= (pSection
->usNeedPrevLvl
& BIT(tStyleIndex
)) != 0;
359 for (tIndex
= 0; tIndex
<= tStyleIndex
; tIndex
++) {
360 if (tIndex
== tStyleIndex
||
361 (bNeedPrevLvl
&& tIndex
< tStyleIndex
)) {
362 if (pcTxt
- szLine
>= tLineSize
- 25) {
363 /* Prevent a possible buffer overflow */
364 DBG_DEC(pcTxt
- szLine
);
365 DBG_DEC(tLineSize
- 25);
370 ucNFC
= pSection
->aucNFC
[tIndex
];
372 case LIST_ARABIC_NUM
:
373 case LIST_NUMBER_TXT
:
374 case LIST_ORDINAL_TXT
:
375 pcTxt
+= sprintf(pcTxt
, "%u",
376 auiHdrCounter
[tIndex
]);
378 case LIST_UPPER_ROMAN
:
379 case LIST_LOWER_ROMAN
:
380 pcTxt
+= tNumber2Roman(
381 auiHdrCounter
[tIndex
],
382 ucNFC
== LIST_UPPER_ROMAN
,
385 case LIST_UPPER_ALPHA
:
386 case LIST_LOWER_ALPHA
:
387 pcTxt
+= tNumber2Alpha(
388 auiHdrCounter
[tIndex
],
389 ucNFC
== LIST_UPPER_ALPHA
,
392 case LIST_OUTLINE_NUM
:
393 pcTxt
+= sprintf(pcTxt
, "%02u",
394 auiHdrCounter
[tIndex
]);
399 pcTxt
+= sprintf(pcTxt
, "%u",
400 auiHdrCounter
[tIndex
]);
403 if (tIndex
< tStyleIndex
) {
405 } else if (tIndex
== tStyleIndex
) {
411 NO_DBG_MSG_C((int)pStyle
->usIstd
>= 1 &&
412 (int)pStyle
->usIstd
<= 9 &&
413 eNumType
!= level_type_none
&&
414 eNumType
!= level_type_outline
, szLine
);
415 NO_DBG_MSG_C(szLine
[0] != '\0', szLine
);
416 fail(pcTxt
< szLine
);
417 return (size_t)(pcTxt
- szLine
);
418 } /* end of tStyle2Window */
421 * vRemoveRowEnd - remove the end of table row indicator
423 * Remove the double TABLE_SEPARATOR characters from the end of the string.
424 * Special: remove the TABLE_SEPARATOR, 0x0a sequence
427 vRemoveRowEnd(char *szRowTxt
)
431 TRACE_MSG("vRemoveRowEnd");
433 fail(szRowTxt
== NULL
|| szRowTxt
[0] == '\0');
435 iLastIndex
= (int)strlen(szRowTxt
) - 1;
437 if (szRowTxt
[iLastIndex
] == TABLE_SEPARATOR
||
438 szRowTxt
[iLastIndex
] == (char)0x0a) {
439 szRowTxt
[iLastIndex
] = '\0';
442 DBG_HEX(szRowTxt
[iLastIndex
]);
445 if (iLastIndex
>= 0 && szRowTxt
[iLastIndex
] == (char)0x0a) {
446 szRowTxt
[iLastIndex
] = '\0';
450 if (iLastIndex
>= 0 && szRowTxt
[iLastIndex
] == TABLE_SEPARATOR
) {
451 szRowTxt
[iLastIndex
] = '\0';
456 DBG_HEX(szRowTxt
[iLastIndex
]);
458 } /* end of vRemoveRowEnd */
461 * tComputeStringLengthMax - max string length in relation to max column width
463 * Return the maximum string length
466 tComputeStringLengthMax(const char *szString
, size_t tColumnWidthMax
)
469 size_t tLengthMax
, tLenPrev
, tLen
, tWidth
;
471 TRACE_MSG("tComputeStringLengthMax");
473 fail(szString
== NULL
);
474 fail(tColumnWidthMax
== 0);
476 pcTmp
= strchr(szString
, '\n');
478 tLengthMax
= (size_t)(pcTmp
- szString
+ 1);
480 tLengthMax
= strlen(szString
);
482 if (tLengthMax
== 0) {
490 tLen
+= tGetCharacterLength(szString
+ tLen
);
491 DBG_DEC_C(tLen
> tLengthMax
, tLen
);
492 DBG_DEC_C(tLen
> tLengthMax
, tLengthMax
);
493 fail(tLen
> tLengthMax
);
494 tWidth
= tCountColumns(szString
, tLen
);
495 if (tWidth
> tColumnWidthMax
) {
498 if (tLen
>= tLengthMax
) {
502 } /* end of tComputeStringLengthMax */
505 * tGetBreakingPoint - get the number of bytes that fit the column
507 * Returns the number of bytes that fit the column
510 tGetBreakingPoint(const char *szString
,
511 size_t tLen
, size_t tWidth
, size_t tColumnWidthMax
)
515 TRACE_MSG("tGetBreakingPoint");
517 fail(szString
== NULL
);
518 fail(tLen
> strlen(szString
));
519 fail(tWidth
> tColumnWidthMax
);
521 if (tWidth
< tColumnWidthMax
||
522 (tWidth
== tColumnWidthMax
&&
523 (szString
[tLen
] == ' ' ||
524 szString
[tLen
] == '\n' ||
525 szString
[tLen
] == '\0'))) {
526 /* The string already fits, do nothing */
529 /* Search for a breaking point */
530 for (iIndex
= (int)tLen
- 1; iIndex
>= 0; iIndex
--) {
531 if (szString
[iIndex
] == ' ') {
532 return (size_t)iIndex
;
535 /* No breaking point found, just fill the column */
537 } /* end of tGetBreakingPoint */
540 * tComputeColumnWidthMax - compute the maximum column width
543 tComputeColumnWidthMax(short sWidth
, long lCharWidth
, double dFactor
)
545 size_t tColumnWidthMax
;
547 TRACE_MSG("tComputeColumnWidthMax");
550 fail(lCharWidth
<= 0);
551 fail(dFactor
<= 0.0);
553 tColumnWidthMax
= (size_t)(
554 (lTwips2MilliPoints(sWidth
) * dFactor
+ lCharWidth
/ 2.0) /
556 if (tColumnWidthMax
== 0) {
557 /* Minimum column width */
560 if (tColumnWidthMax
> 1) {
561 /* Make room for the TABLE_SEPARATOR_CHAR */
564 NO_DBG_DEC(tColumnWidthMax
);
565 return tColumnWidthMax
;
566 } /* end of tComputeColumnWidthMax */
569 * vTableRow2Window - put a table row into a diagram
572 vTableRow2Window(diagram_type
*pDiag
, output_type
*pOutput
,
573 const row_block_type
*pRowInfo
,
574 conversion_type eConversionType
, int iParagraphBreak
)
577 char *aszColTxt
[TABLE_COLUMN_MAX
];
578 char *szLine
, *pcTxt
;
580 long lCharWidthLarge
, lCharWidthSmall
;
581 size_t tColumnWidthTotal
, atColumnWidthMax
[TABLE_COLUMN_MAX
];
582 size_t tSize
, tColumnWidthMax
, tWidth
, tLen
;
583 int iIndex
, iNbrOfColumns
, iTmp
;
586 TRACE_MSG("vTableRow2Window");
588 fail(pDiag
== NULL
|| pOutput
== NULL
|| pRowInfo
== NULL
);
589 fail(pOutput
->szStorage
== NULL
);
590 fail(pOutput
->pNext
!= NULL
);
591 fail(iParagraphBreak
< 0);
593 /* Character sizes */
594 lCharWidthLarge
= lComputeStringWidth("W", 1,
595 pOutput
->tFontRef
, pOutput
->usFontSize
);
596 NO_DBG_DEC(lCharWidthLarge
);
597 lCharWidthSmall
= lComputeStringWidth("i", 1,
598 pOutput
->tFontRef
, pOutput
->usFontSize
);
599 NO_DBG_DEC(lCharWidthSmall
);
600 /* For the time being: use a fixed width font */
601 fail(lCharWidthLarge
!= lCharWidthSmall
);
603 vRemoveRowEnd(pOutput
->szStorage
);
605 /* Split the row text into a set of column texts */
606 aszColTxt
[0] = pOutput
->szStorage
;
607 for (iNbrOfColumns
= 1;
608 iNbrOfColumns
< TABLE_COLUMN_MAX
;
610 aszColTxt
[iNbrOfColumns
] =
611 strchr(aszColTxt
[iNbrOfColumns
- 1],
613 if (aszColTxt
[iNbrOfColumns
] == NULL
) {
616 *aszColTxt
[iNbrOfColumns
] = '\0';
617 aszColTxt
[iNbrOfColumns
]++;
618 NO_DBG_DEC(iNbrOfColumns
);
619 NO_DBG_MSG(aszColTxt
[iNbrOfColumns
]);
622 /* Work around a bug in Word */
623 while (iNbrOfColumns
> (int)pRowInfo
->ucNumberOfColumns
&&
624 pRowInfo
->asColumnWidth
[iNbrOfColumns
] == 0) {
628 DBG_DEC_C(iNbrOfColumns
!= (int)pRowInfo
->ucNumberOfColumns
,
630 DBG_DEC_C(iNbrOfColumns
!= (int)pRowInfo
->ucNumberOfColumns
,
631 pRowInfo
->ucNumberOfColumns
);
632 if (iNbrOfColumns
!= (int)pRowInfo
->ucNumberOfColumns
) {
633 werr(0, "Skipping an unmatched table row");
637 #if defined(__FULL_TEXT_SEARCH)
638 /* No table formatting: use for full-text search (untested) */
639 for (iIndex
= 0; iIndex
< iNbrOfColumns
; iIndex
++) {
640 fprintf(pDiag
->pOutFile
, "%s\n" , aszColTxt
[iIndex
]);
643 if (bAddTableRow(pDiag
, aszColTxt
, iNbrOfColumns
,
644 pRowInfo
->asColumnWidth
, pRowInfo
->ucBorderInfo
)) {
645 /* All work has been done */
649 /* Fill the table with maximum column widths */
650 if (eConversionType
== conversion_text
||
651 eConversionType
== conversion_fmt_text
) {
652 if (iParagraphBreak
== 0 ||
653 iParagraphBreak
>= MAX_SCREEN_WIDTH
) {
654 dMagnify
= (double)MAX_SCREEN_WIDTH
;
655 } else if (iParagraphBreak
<= MIN_SCREEN_WIDTH
) {
656 dMagnify
= (double)MIN_SCREEN_WIDTH
;
658 dMagnify
= (double)iParagraphBreak
;
660 dMagnify
/= (double)DEFAULT_SCREEN_WIDTH
;
661 DBG_FLT_C(dMagnify
< 0.99 || dMagnify
> 1.01, dMagnify
);
665 tColumnWidthTotal
= 0;
666 for (iIndex
= 0; iIndex
< iNbrOfColumns
; iIndex
++) {
667 atColumnWidthMax
[iIndex
] = tComputeColumnWidthMax(
668 pRowInfo
->asColumnWidth
[iIndex
],
671 tColumnWidthTotal
+= atColumnWidthMax
[iIndex
];
675 * Get enough space for the row.
676 * Worst case: three bytes per UTF-8 character
678 tSize
= 3 * (1 + tColumnWidthTotal
+ (size_t)iNbrOfColumns
+ 3);
679 szLine
= xmalloc(tSize
);
682 /* Print one line of a table row */
685 *pcTxt
++ = TABLE_SEPARATOR_CHAR
;
686 for (iIndex
= 0; iIndex
< iNbrOfColumns
; iIndex
++) {
687 tColumnWidthMax
= atColumnWidthMax
[iIndex
];
688 if (aszColTxt
[iIndex
] == NULL
) {
689 /* Add an empty column */
691 iTmp
< (int)tColumnWidthMax
;
693 *pcTxt
++ = (char)FILLER_CHAR
;
695 *pcTxt
++ = TABLE_SEPARATOR_CHAR
;
699 /* Compute the length and width of the column text */
700 tLen
= tComputeStringLengthMax(
701 aszColTxt
[iIndex
], tColumnWidthMax
);
704 (aszColTxt
[iIndex
][tLen
- 1] == '\n' ||
705 aszColTxt
[iIndex
][tLen
- 1] == ' ')) {
706 aszColTxt
[iIndex
][tLen
- 1] = ' ';
709 tWidth
= tCountColumns(aszColTxt
[iIndex
], tLen
);
710 fail(tWidth
> tColumnWidthMax
);
711 tLen
= tGetBreakingPoint(aszColTxt
[iIndex
],
712 tLen
, tWidth
, tColumnWidthMax
);
713 tWidth
= tCountColumns(aszColTxt
[iIndex
], tLen
);
714 if (tLen
== 0 && *aszColTxt
[iIndex
] == '\0') {
716 aszColTxt
[iIndex
] = NULL
;
719 pcTxt
+= sprintf(pcTxt
,
720 "%.*s", (int)tLen
, aszColTxt
[iIndex
]);
721 if (tLen
== 0 && *aszColTxt
[iIndex
] != ' ') {
722 tLen
= tGetCharacterLength(
724 DBG_CHR(*aszColTxt
[iIndex
]);
728 aszColTxt
[iIndex
] += tLen
;
729 while (*aszColTxt
[iIndex
] == ' ') {
732 if (*aszColTxt
[iIndex
] == '\0') {
733 /* This row is now complete */
734 aszColTxt
[iIndex
] = NULL
;
736 /* This row needs more lines */
740 /* Fill up the rest */
742 iTmp
< (int)tColumnWidthMax
- (int)tWidth
;
744 *pcTxt
++ = (char)FILLER_CHAR
;
747 *pcTxt
++ = TABLE_SEPARATOR_CHAR
;
750 /* Output the table row line */
753 tRow
.szStorage
= szLine
;
754 fail(pcTxt
< szLine
);
755 tRow
.tNextFree
= (size_t)(pcTxt
- szLine
);
756 tRow
.lStringWidth
= lComputeStringWidth(
761 vString2Diagram(pDiag
, &tRow
);
762 TRACE_MSG("after vString2Diagram in vTableRow2Window");
764 /* Clean up before you leave */
765 szLine
= xfree(szLine
);
766 TRACE_MSG("leaving vTableRow2Window");
767 #endif /* __FULL_TEXT_SEARCH */
768 } /* end of vTableRow2Window */