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