1 /*
2 * text.c
3 * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL
4 *
5 * Description:
6 * Functions to deal with the Text format
7 *
8 */
9
10 #include <string.h>
11 #include "antiword.h"
12
13 /* The character set */
14 static encoding_type eEncoding = encoding_neutral;
15 /* Current vertical position information */
16 static long lYtopCurr = 0;
17 /* Local representation of the non-breaking space */
18 static UCHAR ucNbsp = 0;
19
20
21 /*
22 * vPrologueTXT - set options and perform the Text initialization
23 */
24 void
vPrologueTXT(diagram_type * pDiag,const options_type * pOptions)25 vPrologueTXT(diagram_type *pDiag, const options_type *pOptions)
26 {
27 fail(pDiag == NULL);
28 fail(pOptions == NULL);
29
30 eEncoding = pOptions->eEncoding;
31 pDiag->lXleft = 0;
32 pDiag->lYtop = 0;
33 lYtopCurr = 0;
34 } /* end of vPrologueTXT */
35
36 /*
37 * vEpilogueTXT - clean up after everything is done
38 */
39 void
vEpilogueTXT(FILE * pOutFile)40 vEpilogueTXT(FILE *pOutFile)
41 {
42 fail(pOutFile == NULL);
43
44 fprintf(pOutFile, "\n");
45 } /* end of vEpilogueTXT */
46
47 /*
48 * vPrintTXT - print a Text string
49 */
50 static void
vPrintTXT(FILE * pFile,const char * szString,size_t tStringLength)51 vPrintTXT(FILE *pFile, const char *szString, size_t tStringLength)
52 {
53 const UCHAR *ucBytes;
54 size_t tCount;
55
56 fail(szString == NULL);
57
58 if (szString == NULL || szString[0] == '\0' || tStringLength == 0) {
59 return;
60 }
61
62 if (eEncoding == encoding_utf_8) {
63 fprintf(pFile, "%.*s", (int)tStringLength, szString);
64 return;
65 }
66
67 if (ucNbsp == 0) {
68 ucNbsp = ucGetNbspCharacter();
69 DBG_HEX_C(ucNbsp != 0xa0, ucNbsp);
70 }
71
72 ucBytes = (UCHAR *)szString;
73 for (tCount = 0; tCount < tStringLength ; tCount++) {
74 if (ucBytes[tCount] == ucNbsp) {
75 (void)putc(' ', pFile);
76 } else {
77 (void)putc(szString[tCount], pFile);
78 }
79 }
80 } /* end of vPrintTXT */
81
82 /*
83 * vMoveTo - move to the given X,Y coordinates
84 *
85 * Move the current position of the given diagram to its X,Y coordinates,
86 * start on a new page if needed
87 */
88 static void
vMoveTo(diagram_type * pDiag)89 vMoveTo(diagram_type *pDiag)
90 {
91 int iCount, iNbr;
92
93 fail(pDiag == NULL);
94 fail(pDiag->pOutFile == NULL);
95
96 if (pDiag->lYtop != lYtopCurr) {
97 iNbr = iDrawUnits2Char(pDiag->lXleft);
98 for (iCount = 0; iCount < iNbr; iCount++) {
99 (void)putc(FILLER_CHAR, pDiag->pOutFile);
100 }
101 lYtopCurr = pDiag->lYtop;
102 }
103 } /* end of vMoveTo */
104
105 /*
106 * vMove2NextLineTXT - move to the next line
107 */
108 void
vMove2NextLineTXT(diagram_type * pDiag)109 vMove2NextLineTXT(diagram_type *pDiag)
110 {
111 fail(pDiag == NULL);
112 fail(pDiag->pOutFile == NULL);
113
114 pDiag->lYtop++;
115 (void)fprintf(pDiag->pOutFile, "\n");
116 } /* end of vMove2NextLineTXT */
117
118 /*
119 * vSubstringTXT - print a sub string
120 */
121 void
vSubstringTXT(diagram_type * pDiag,const char * szString,size_t tStringLength,long lStringWidth)122 vSubstringTXT(diagram_type *pDiag,
123 const char *szString, size_t tStringLength, long lStringWidth)
124 {
125 fail(pDiag == NULL || szString == NULL);
126 fail(pDiag->pOutFile == NULL);
127 fail(pDiag->lXleft < 0);
128 fail(tStringLength != strlen(szString));
129
130 if (szString[0] == '\0' || tStringLength == 0) {
131 return;
132 }
133
134 vMoveTo(pDiag);
135 vPrintTXT(pDiag->pOutFile, szString, tStringLength);
136 pDiag->lXleft += lStringWidth;
137 } /* end of vSubstringTXT */
138
139 /*
140 * Create an start of paragraph by moving the y-top mark
141 */
142 void
vStartOfParagraphTXT(diagram_type * pDiag,long lBeforeIndentation)143 vStartOfParagraphTXT(diagram_type *pDiag, long lBeforeIndentation)
144 {
145 fail(pDiag == NULL);
146 fail(lBeforeIndentation < 0);
147
148 if (lBeforeIndentation >= lTwips2MilliPoints(HEADING_GAP)) {
149 /* A large gap is replaced by an empty line */
150 vMove2NextLineTXT(pDiag);
151 }
152 } /* end of vStartOfParagraphTXT */
153
154 /*
155 * Create an end of paragraph by moving the y-top mark
156 */
157 void
vEndOfParagraphTXT(diagram_type * pDiag,long lAfterIndentation)158 vEndOfParagraphTXT(diagram_type *pDiag, long lAfterIndentation)
159 {
160 fail(pDiag == NULL);
161 fail(pDiag->pOutFile == NULL);
162 fail(lAfterIndentation < 0);
163
164 if (pDiag->lXleft > 0) {
165 /* To the start of the line */
166 vMove2NextLineTXT(pDiag);
167 }
168
169 if (lAfterIndentation >= lTwips2MilliPoints(HEADING_GAP)) {
170 /* A large gap is replaced by an empty line */
171 vMove2NextLineTXT(pDiag);
172 }
173 } /* end of vEndOfParagraphTXT */
174
175 /*
176 * Create an end of page
177 */
178 void
vEndOfPageTXT(diagram_type * pDiag,long lAfterIndentation)179 vEndOfPageTXT(diagram_type *pDiag, long lAfterIndentation)
180 {
181 vEndOfParagraphTXT(pDiag, lAfterIndentation);
182 } /* end of vEndOfPageTXT */
183