3 * Copyright (C) 1998,1999 A.J. van Os
6 * MS Word to text functions
20 #define INITIAL_SIZE 40
21 #define EXTENTION_SIZE 20
24 /* Macros to make sure all such statements will be identical */
25 #define OUTPUT_LINE() \
27 vAlign2Window(pDiag, pAnchor, iWidthMax, ucAlignment);\
28 pAnchor = pStartNewOutput(pAnchor, NULL);\
32 #define RESET_LINE() \
34 pAnchor = pStartNewOutput(pAnchor, NULL);\
38 /* Length of the document in characters */
39 static unsigned int uiDocumentLength
;
40 /* Number of characters processed so far */
41 static unsigned int uiCharCounter
;
42 static int iCurrPct
, iPrevPct
;
43 /* Special treatment for files from the Apple Macintosh */
44 static BOOL bMacFile
= FALSE
;
45 /* Needed for reading a complete table row */
46 static row_block_type tRowInfo
;
47 static BOOL bRowInfo
= FALSE
;
48 static BOOL bStartRow
= FALSE
;
49 static BOOL bEndRow
= FALSE
;
50 static BOOL bIsTableRow
= FALSE
;
51 /* Needed for finding the start of a style */
52 static const style_block_type
*pStyleInfo
= NULL
;
53 static BOOL bStartStyle
= FALSE
;
54 /* Needed for finding the start of a font */
55 static const font_block_type
*pFontInfo
= NULL
;
56 static BOOL bStartFont
= FALSE
;
60 * vUpdateCounters - Update the counters for the hourglass
67 iCurrPct
= (int)((uiCharCounter
* 100) / uiDocumentLength
);
68 if (iCurrPct
!= iPrevPct
) {
69 visdelay_percent(iCurrPct
);
73 } /* end of vUpdateCounters */
76 * bOutputContainsText - see if the output contains more than white-space
79 bOutputContainsText(output_type
*pAnchor
)
84 fail(pAnchor
== NULL
);
86 for (pTmp
= pAnchor
; pTmp
!= NULL
; pTmp
= pTmp
->pNext
) {
87 fail(pTmp
->iStringWidth
< 0);
88 for (iIndex
= 0; iIndex
< pTmp
->iNextFree
; iIndex
++) {
89 if (isspace(pTmp
->szStorage
[iIndex
])) {
93 if ((unsigned char)pTmp
->szStorage
[iIndex
] ==
102 } /* end of bOutputContainsText */
105 * iTotalStringWidth - compute the total width of the output string
108 iTotalStringWidth(output_type
*pAnchor
)
114 for (pTmp
= pAnchor
; pTmp
!= NULL
; pTmp
= pTmp
->pNext
) {
115 fail(pTmp
->iStringWidth
< 0);
116 iTotal
+= pTmp
->iStringWidth
;
119 } /* end of iTotalStringWidth */
122 * vStoreCharacter - store one character
125 vStoreCharacter(int iChar
, output_type
*pOutput
)
127 fail(pOutput
== NULL
);
130 pOutput
->szStorage
[pOutput
->iNextFree
] = '\0';
133 while (pOutput
->iNextFree
+ 2 > pOutput
->iStorageSize
) {
134 pOutput
->iStorageSize
+= EXTENTION_SIZE
;
135 pOutput
->szStorage
= xrealloc(pOutput
->szStorage
,
136 pOutput
->iStorageSize
);
138 pOutput
->szStorage
[pOutput
->iNextFree
] = (char)iChar
;
139 pOutput
->szStorage
[pOutput
->iNextFree
+1] = '\0';
140 pOutput
->iStringWidth
+= iComputeStringWidth(
141 pOutput
->szStorage
+ pOutput
->iNextFree
,
144 pOutput
->ucFontsize
);
145 pOutput
->iNextFree
++;
146 } /* end of vStoreCharacter */
149 * vStoreString - store a string
152 vStoreString(const char *szString
, int iStringLength
, output_type
*pOutput
)
156 fail(szString
== NULL
|| iStringLength
< 0 || pOutput
== NULL
);
158 for (iIndex
= 0; iIndex
< iStringLength
; iIndex
++) {
159 vStoreCharacter(szString
[iIndex
], pOutput
);
161 } /* end of vStoreString */
164 * vStoreIntegerAsDecimal - store an integer as a decimal number
167 vStoreIntegerAsDecimal(int iNumber
, output_type
*pOutput
)
172 fail(pOutput
== NULL
);
174 iLen
= sprintf(szString
, "%d", iNumber
);
175 vStoreString(szString
, iLen
, pOutput
);
176 } /* end of vStoreIntegerAsDecimal */
179 * vStoreIntegerAsRoman - store an integer as a roman numerical
182 vStoreIntegerAsRoman(int iNumber
, output_type
*pOutput
)
188 fail(pOutput
== NULL
);
190 iLen
= iInteger2Roman(iNumber
, FALSE
, szString
);
191 vStoreString(szString
, iLen
, pOutput
);
192 } /* end of vStoreIntegerAsRoman */
195 * vStoreStyle - store a style
198 vStoreStyle(const style_block_type
*pStyleInfo
, output_type
*pOutput
)
203 fail(pOutput
== NULL
);
204 iLen
= iStyle2Window(szString
, pStyleInfo
);
205 vStoreString(szString
, iLen
, pOutput
);
206 } /* end of vStoreStyle */
209 * vPutIndentation - output the given amount of indentation
212 vPutIndentation(diagram_type
*pDiag
, output_type
*pOutput
, BOOL bUnmarked
,
213 int iListNumber
, unsigned char ucListType
, char cListCharacter
,
216 int iLeftIndentation
, iWidth
, iNextFree
;
219 fail(pDiag
== NULL
|| pOutput
== NULL
);
220 fail(iListNumber
< 0);
221 fail(iLeftIndent
< 0);
223 if (iLeftIndent
<= 0) {
226 iLeftIndentation
= iTwips2MilliPoints(iLeftIndent
);
228 vSetLeftIndentation(pDiag
, iLeftIndentation
);
231 fail(iListNumber
<= 0 || iscntrl(cListCharacter
));
233 switch (ucListType
) {
237 case LIST_ROMAN_NUM_UPPER
:
238 case LIST_ROMAN_NUM_LOWER
:
239 iNextFree
= iInteger2Roman(iListNumber
,
240 ucListType
== LIST_ROMAN_NUM_UPPER
, szLine
);
242 case LIST_UPPER_ALPHA
:
243 case LIST_LOWER_ALPHA
:
244 iNextFree
= iInteger2Alpha(iListNumber
,
245 ucListType
== LIST_UPPER_ALPHA
, szLine
);
247 case LIST_ARABIC_NUM
:
249 iNextFree
= sprintf(szLine
, "%d", iListNumber
);
251 szLine
[iNextFree
++] = cListCharacter
;
252 szLine
[iNextFree
++] = ' ';
253 szLine
[iNextFree
] = '\0';
254 iWidth
= iComputeStringWidth(szLine
, iNextFree
,
255 pOutput
->tFontRef
, pOutput
->ucFontsize
);
256 iLeftIndentation
-= iWidth
;
257 if (iLeftIndentation
> 0) {
258 vSetLeftIndentation(pDiag
, iLeftIndentation
);
260 vStoreString(szLine
, iNextFree
, pOutput
);
261 } /* end of vPutIndentation */
264 * vPutNoteSeparator - output a note separator
266 * A note separator is a horizontal line two inches long.
267 * Two inches equals 144000 milliponts.
270 vPutNoteSeparator(output_type
*pOutput
)
272 int iCounter
, iChars
, iCharWidth
;
275 fail(pOutput
== NULL
);
277 szOne
[0] = OUR_EM_DASH
;
279 iCharWidth
= iComputeStringWidth(szOne
, 1,
280 pOutput
->tFontRef
, pOutput
->ucFontsize
);
282 iChars
= (144000 + iCharWidth
/ 2) / iCharWidth
;
284 for (iCounter
= 0; iCounter
< iChars
; iCounter
++) {
285 vStoreCharacter(OUR_EM_DASH
, pOutput
);
287 } /* end of vPutNoteSeparator */
293 pStartNextOutput(output_type
*pCurrent
)
297 if (pCurrent
->iNextFree
== 0) {
298 /* The current record is empty, re-use */
299 fail(pCurrent
->szStorage
[0] != '\0');
300 fail(pCurrent
->iStringWidth
!= 0);
303 /* The current record is in use, make a new one */
304 pNew
= xmalloc(sizeof(*pNew
));
305 pCurrent
->pNext
= pNew
;
306 pNew
->iStorageSize
= INITIAL_SIZE
;
307 pNew
->szStorage
= xmalloc(pNew
->iStorageSize
);
308 pNew
->szStorage
[0] = '\0';
310 pNew
->iStringWidth
= 0;
312 pNew
->ucFontstyle
= FONT_REGULAR
;
314 pNew
->ucFontsize
= DEFAULT_FONT_SIZE
;
315 pNew
->pPrev
= pCurrent
;
318 } /* end of pStartNextOutput */
324 pStartNewOutput(output_type
*pAnchor
, output_type
*pLeftOver
)
326 output_type
*pCurr
, *pNext
;
328 draw_fontref tFontRef
;
329 unsigned char ucFontstyle
, ucFontsize
;
331 iColour
= FONT_COLOUR_DEFAULT
;
332 ucFontstyle
= FONT_REGULAR
;
334 ucFontsize
= DEFAULT_FONT_SIZE
;
335 /* Free the old output space */
337 while (pCurr
!= NULL
) {
338 pNext
= pCurr
->pNext
;
339 pCurr
->szStorage
= xfree(pCurr
->szStorage
);
340 if (pCurr
->pNext
== NULL
) {
341 iColour
= pCurr
->iColour
;
342 ucFontstyle
= pCurr
->ucFontstyle
;
343 tFontRef
= pCurr
->tFontRef
;
344 ucFontsize
= pCurr
->ucFontsize
;
346 pCurr
= xfree(pCurr
);
349 if (pLeftOver
== NULL
) {
350 /* Create new output space */
351 pLeftOver
= xmalloc(sizeof(*pLeftOver
));
352 pLeftOver
->iStorageSize
= INITIAL_SIZE
;
353 pLeftOver
->szStorage
= xmalloc(pLeftOver
->iStorageSize
);
354 pLeftOver
->szStorage
[0] = '\0';
355 pLeftOver
->iNextFree
= 0;
356 pLeftOver
->iStringWidth
= 0;
357 pLeftOver
->iColour
= iColour
;
358 pLeftOver
->ucFontstyle
= ucFontstyle
;
359 pLeftOver
->tFontRef
= tFontRef
;
360 pLeftOver
->ucFontsize
= ucFontsize
;
361 pLeftOver
->pPrev
= NULL
;
362 pLeftOver
->pNext
= NULL
;
364 fail(!bCheckDoubleLinkedList(pLeftOver
));
366 } /* end of pStartNewOutput */
369 * iGetChar - get the next character from the given list
372 iGetChar(FILE *pFile
, list_id_enum eListID
)
374 const font_block_type
*pCurr
;
375 int iChar
, iFileOffset
;
383 iChar
= iNextChar(pFile
, eListID
, &iFileOffset
);
391 bStartRow
= bRowInfo
&&
392 iFileOffset
== tRowInfo
.iOffsetStart
;
393 NO_DBG_HEX_C(bStartRow
, tRowInfo
.iOffsetStart
);
396 bEndRow
= bRowInfo
&&
397 iFileOffset
== tRowInfo
.iOffsetEnd
;
398 NO_DBG_HEX_C(bStartRow
, tRowInfo
.iOffsetEnd
);
401 bStartStyle
= pStyleInfo
!= NULL
&&
402 iFileOffset
== pStyleInfo
->iOffset
;
403 NO_DBG_HEX_C(bStartStyle
, iFileOffset
);
405 if (pCurr
!= NULL
&& iFileOffset
== pCurr
->iOffset
) {
407 NO_DBG_HEX(iFileOffset
);
409 pCurr
= pGetNextFontInfoListItem(pCurr
);
412 /* Skip embedded characters */
413 if (iChar
== START_EMBEDDED
) {
417 if (iChar
== END_IGNORE
|| iChar
== END_EMBEDDED
) {
424 iChar
= iTranslateCharacters(iChar
, iFileOffset
, bMacFile
);
430 } /* end of iGetChar */
436 vWord2Text(diagram_type
*pDiag
, const char *szFilename
)
438 options_type tOptions
;
440 output_type
*pAnchor
, *pOutput
, *pLeftOver
;
441 list_id_enum eListID
;
442 int iFontsize
, iDefaultTabWidth
;
443 int iFootnoteNumber
, iEndnoteNumber
, iLeftIndent
;
444 int iChar
, iListNumber
, iWidthCurr
, iWidthMax
, iTmp
;
445 BOOL bWasTableRow
, bTableFontClosed
, bUnmarked
;
446 BOOL bAllCapitals
, bHiddenText
;
447 unsigned char ucFontnumber
, ucFontcolour
, ucTmp
;
448 unsigned char ucFontstyle
, ucFontstyleMinimal
;
449 unsigned char ucListType
, ucAlignment
;
452 fail(pDiag
== NULL
|| szFilename
== NULL
|| szFilename
[0] == '\0');
454 DBG_MSG("vWord2Text");
456 pFile
= pOpenDocument(szFilename
);
460 vAddFonts2Diagram(pDiag
);
466 uiDocumentLength
= uiGetDocumentLength();
467 bMacFile
= bFileFromTheMac();
468 iDefaultTabWidth
= iGetDefaultTabWidth();
469 DBG_DEC_C(iDefaultTabWidth
!= 36000, iDefaultTabWidth
);
470 bRowInfo
= bGetNextRowInfoListItem(&tRowInfo
);
471 DBG_HEX_C(bRowInfo
, tRowInfo
.iOffsetStart
);
472 DBG_HEX_C(bRowInfo
, tRowInfo
.iOffsetEnd
);
476 bWasTableRow
= FALSE
;
478 pStyleInfo
= pGetNextStyleInfoListItem();
481 pFontInfo
= pGetNextFontInfoListItem(NULL
);
482 DBG_HEX_C(pFontInfo
!= NULL
, pFontInfo
->iOffset
);
483 DBG_MSG_C(pFontInfo
== NULL
, "No fonts at all");
486 ucFontstyleMinimal
= FONT_REGULAR
;
487 ucFontstyle
= FONT_REGULAR
;
488 iFontsize
= DEFAULT_FONT_SIZE
;
490 pAnchor
= pStartNewOutput(pAnchor
, NULL
);
492 pOutput
->iColour
= ucFontcolour
;
493 pOutput
->ucFontstyle
= ucFontstyle
;
495 tOpenFont(pDiag
, ucFontnumber
, ucFontstyle
, iFontsize
);
496 pOutput
->ucFontsize
= iFontsize
;
497 bTableFontClosed
= TRUE
;
500 ucListType
= LIST_BULLETS
;
501 cListChar
= OUR_BULLET
;
503 ucAlignment
= ALIGNMENT_LEFT
;
504 bAllCapitals
= FALSE
;
506 vGetOptions(&tOptions
);
507 fail(tOptions
.iParagraphBreak
< 0);
508 if (tOptions
.iParagraphBreak
== 0) {
510 } else if (tOptions
.iParagraphBreak
< MIN_SCREEN_WIDTH
) {
511 iWidthMax
= iChar2MilliPoints(MIN_SCREEN_WIDTH
);
512 } else if (tOptions
.iParagraphBreak
> MAX_SCREEN_WIDTH
) {
513 iWidthMax
= iChar2MilliPoints(MAX_SCREEN_WIDTH
);
515 iWidthMax
= iChar2MilliPoints(tOptions
.iParagraphBreak
);
517 NO_DBG_DEC(iWidthMax
);
525 iChar
= iGetChar(pFile
, eListID
);
527 if (bOutputContainsText(pAnchor
)) {
534 eListID
= footnote_list
;
535 if (iFootnoteNumber
> 0) {
536 vPutNoteSeparator(pAnchor
);
542 eListID
= endnote_list
;
543 if (iEndnoteNumber
> 0) {
544 vPutNoteSeparator(pAnchor
);
551 eListID
= end_of_lists
;
554 if (eListID
== end_of_lists
) {
560 if (iChar
== UNKNOWN_NOTE_CHAR
) {
563 iChar
= FOOTNOTE_CHAR
;
566 iChar
= ENDNOTE_CHAR
;
574 /* Begin of a tablerow found */
575 if (bOutputContainsText(pAnchor
)) {
580 fail(pAnchor
!= pOutput
);
581 if (bTableFontClosed
) {
582 /* Start special table font */
585 * Compensate for the fact that Word uses
586 * proportional fonts for its tables and we
587 * only one fixed-width font
589 pOutput
->ucFontsize
=
590 iFontsize
<= DEFAULT_FONT_SIZE
?
591 (DEFAULT_FONT_SIZE
* 5 + 3) / 6 :
592 (iFontsize
* 5 + 3) / 6;
594 tOpenTableFont(pDiag
,
595 pOutput
->ucFontsize
);
596 pOutput
->ucFontstyle
= FONT_REGULAR
;
597 pOutput
->iColour
= FONT_COLOUR_BLACK
;
598 bTableFontClosed
= FALSE
;
607 iChar
!= HARD_RETURN
&&
608 iChar
!= FORM_FEED
&&
609 iChar
!= COLUMN_FEED
) {
611 * The end of a table should be followed by an
612 * empty line, like the end of a paragraph
615 vEndOfParagraph2Diagram(pDiag
,
617 pOutput
->ucFontsize
);
624 vStoreCharacter('\n', pOutput
);
627 if (bOutputContainsText(pAnchor
)) {
632 if (iChar
== FORM_FEED
) {
633 vEndOfPage2Diagram(pDiag
,
635 pOutput
->ucFontsize
);
637 vEndOfParagraph2Diagram(pDiag
,
639 pOutput
->ucFontsize
);
647 /* Begin of a font found */
648 fail(pFontInfo
== NULL
);
649 bAllCapitals
= bIsCapitals(pFontInfo
->ucFontstyle
);
650 bHiddenText
= bIsHidden(pFontInfo
->ucFontstyle
);
651 ucTmp
= pFontInfo
->ucFontstyle
&
652 (FONT_BOLD
|FONT_ITALIC
|FONT_UNDERLINE
|FONT_STRIKE
);
654 (iFontsize
!= pFontInfo
->ucFontsize
||
655 ucFontnumber
!= pFontInfo
->ucFontnumber
||
656 ucFontstyleMinimal
!= ucTmp
||
657 ucFontcolour
!= pFontInfo
->ucFontcolour
)) {
658 pOutput
= pStartNextOutput(pOutput
);
660 pOutput
->iColour
= pFontInfo
->ucFontcolour
;
661 pOutput
->ucFontstyle
= pFontInfo
->ucFontstyle
;
662 pOutput
->ucFontsize
= pFontInfo
->ucFontsize
;
663 pOutput
->tFontRef
= tOpenFont(
665 pFontInfo
->ucFontnumber
,
666 pFontInfo
->ucFontstyle
,
667 pFontInfo
->ucFontsize
);
668 fail(!bCheckDoubleLinkedList(pAnchor
));
670 ucFontnumber
= pFontInfo
->ucFontnumber
;
671 iFontsize
= pFontInfo
->ucFontsize
;
672 ucFontcolour
= pFontInfo
->ucFontcolour
;
673 ucFontstyle
= pFontInfo
->ucFontstyle
;
674 ucFontstyleMinimal
= ucTmp
;
675 pFontInfo
= pGetNextFontInfoListItem(pFontInfo
);
676 NO_DBG_HEX_C(pFontInfo
!= NULL
, pFontInfo
->iOffset
);
677 DBG_MSG_C(pFontInfo
== NULL
, "No more fonts");
682 /* Begin of a style found */
683 fail(pStyleInfo
== NULL
);
685 vStoreStyle(pStyleInfo
, pOutput
);
687 iLeftIndent
= pStyleInfo
->sLeftIndent
;
688 bUnmarked
= !pStyleInfo
->bInList
||
689 pStyleInfo
->bUnmarked
;
690 ucListType
= pStyleInfo
->ucListType
;
691 cListChar
= pStyleInfo
->ucListCharacter
;
692 ucAlignment
= pStyleInfo
->ucAlignment
;
693 if (pStyleInfo
->bInList
) {
694 if (!pStyleInfo
->bUnmarked
) {
700 pStyleInfo
= pGetNextStyleInfoListItem();
701 NO_DBG_HEX_C(pStyleInfo
!= NULL
,pStyleInfo
->iOffset
);
706 iTotalStringWidth(pAnchor
) == 0) {
707 vPutIndentation(pDiag
, pAnchor
, bUnmarked
,
708 iListNumber
, ucListType
, cListChar
,
710 /* One mark per paragraph will do */
716 vStoreString("[pic]", 5, pOutput
);
720 vStoreCharacter('[', pOutput
);
721 vStoreIntegerAsDecimal(iFootnoteNumber
, pOutput
);
722 vStoreCharacter(']', pOutput
);
726 vStoreCharacter('[', pOutput
);
727 vStoreIntegerAsRoman(iEndnoteNumber
, pOutput
);
728 vStoreCharacter(']', pOutput
);
730 case UNKNOWN_NOTE_CHAR
:
731 vStoreString("[?]", 3, pOutput
);
735 vStoreCharacter('\n', pOutput
);
738 if (bOutputContainsText(pAnchor
)) {
743 vEndOfParagraph2Diagram(pDiag
,
745 pOutput
->ucFontsize
);
747 * End of paragraph seen, reset indentation,
748 * marking and alignment
752 ucAlignment
= ALIGNMENT_LEFT
;
756 vStoreCharacter('\n', pOutput
);
759 if (bOutputContainsText(pAnchor
)) {
762 vEmptyLine2Diagram(pDiag
,
764 pOutput
->ucFontsize
);
768 /* Already dealt with */
770 case TABLE_SEPARATOR
:
772 vStoreCharacter(iChar
, pOutput
);
775 vStoreCharacter(' ', pOutput
);
776 vStoreCharacter(TABLE_SEPARATOR_CHAR
, pOutput
);
780 vStoreCharacter(' ', pOutput
);
783 if (tOptions
.iParagraphBreak
== 0 &&
784 !tOptions
.bUseOutlineFonts
) {
785 /* No logical lines, so no tab expansion */
786 vStoreCharacter(TAB
, pOutput
);
789 iTmp
= iTotalStringWidth(pAnchor
);
790 iTmp
+= iDrawUnits2MilliPoints(pDiag
->iXleft
);
791 iTmp
/= iDefaultTabWidth
;
793 vStoreCharacter(FILLER_CHAR
, pOutput
);
794 iWidthCurr
= iTotalStringWidth(pAnchor
);
796 iDrawUnits2MilliPoints(pDiag
->iXleft
);
797 } while (iTmp
== iWidthCurr
/ iDefaultTabWidth
&&
798 iWidthCurr
< iWidthMax
);
801 if (bHiddenText
&& tOptions
.bHideHiddenText
) {
804 if (bAllCapitals
&& iChar
< UCHAR_MAX
) {
805 iChar
= iToUpper(iChar
);
807 vStoreCharacter(iChar
, pOutput
);
811 if (bWasTableRow
&& !bIsTableRow
) {
812 /* End of a table, resume normal font */
813 NO_DBG_MSG("End of table font");
815 bTableFontClosed
= TRUE
;
816 pOutput
->iColour
= ucFontcolour
;
817 pOutput
->ucFontstyle
= ucFontstyle
;
818 pOutput
->ucFontsize
= iFontsize
;
819 pOutput
->tFontRef
= tOpenFont(pDiag
, ucFontnumber
,
820 ucFontstyle
, iFontsize
);
822 bWasTableRow
= bIsTableRow
;
825 fail(pAnchor
!= pOutput
);
829 /* End of a table row */
831 vTableRow2Window(pDiag
, pAnchor
, &tRowInfo
);
833 pAnchor
= pStartNewOutput(pAnchor
, NULL
);
835 bRowInfo
= bGetNextRowInfoListItem(&tRowInfo
);
838 NO_DBG_HEX_C(bRowInfo
, tRowInfo
.iOffsetStart
);
839 NO_DBG_HEX_C(bRowInfo
, tRowInfo
.iOffsetEnd
);
842 iWidthCurr
= iTotalStringWidth(pAnchor
);
843 iWidthCurr
+= iDrawUnits2MilliPoints(pDiag
->iXleft
);
844 if (iWidthCurr
< iWidthMax
) {
847 pLeftOver
= pSplitList(pAnchor
);
848 vJustify2Window(pDiag
, pAnchor
, iWidthMax
, ucAlignment
);
849 pAnchor
= pStartNewOutput(pAnchor
, pLeftOver
);
850 for (pOutput
= pAnchor
;
851 pOutput
->pNext
!= NULL
;
852 pOutput
= pOutput
->pNext
)
854 fail(pOutput
== NULL
);
855 if (iTotalStringWidth(pAnchor
) > 0) {
856 vSetLeftIndentation(pDiag
,
857 iTwips2MilliPoints(iLeftIndent
));
861 pAnchor
= pStartNewOutput(pAnchor
, NULL
);
862 pAnchor
->szStorage
= xfree(pAnchor
->szStorage
);
863 pAnchor
= xfree(pAnchor
);
865 vCloseDocument(pFile
);
867 } /* end of vWord2Text */