xref: /plan9/sys/src/cmd/aux/antiword/fmt_text.c (revision 25b329d522281a8cdd35da0dcc08c3fc621059a9)
1 /*
2  * fmt_text.c
3  * Copyright (C) 2004 A.J. van Os; Released under GNU GPL
4  *
5  * Description:
6  * Functions to deal with the Formatted Text format
7  *
8  * Based on patches send by: Ofir Reichenberg <ofir@qlusters.com>
9  *
10  * The credit should go to him, but all the bugs are mine.
11  */
12 
13 #include <string.h>
14 #include "antiword.h"
15 
16 /* The character set */
17 static encoding_type	eEncoding = encoding_neutral;
18 /* Current vertical position information */
19 static long		lYtopCurr = 0;
20 /* Local representation of the non-breaking space */
21 static UCHAR		ucNbsp = 0;
22 
23 
24 /*
25  * vPrologueFMT - set options and perform the Formatted Text initialization
26  */
27 void
vPrologueFMT(diagram_type * pDiag,const options_type * pOptions)28 vPrologueFMT(diagram_type *pDiag, const options_type *pOptions)
29 {
30 	fail(pDiag == NULL);
31 	fail(pOptions == NULL);
32 
33 	eEncoding = pOptions->eEncoding;
34 	pDiag->lXleft = 0;
35 	pDiag->lYtop = 0;
36 	lYtopCurr = 0;
37 } /* end of vPrologueFMT */
38 
39 /*
40  * vPrintFMT - print a Formatted Text string
41  */
42 static void
vPrintFMT(FILE * pFile,const char * szString,size_t tStringLength,USHORT usFontstyle)43 vPrintFMT(FILE *pFile,
44 	const char *szString, size_t tStringLength, USHORT usFontstyle)
45 {
46 	const UCHAR	*pucByte, *pucStart, *pucLast, *pucNonSpace;
47 
48 	fail(szString == NULL);
49 
50 	if (szString == NULL || szString[0] == '\0' || tStringLength == 0) {
51 		return;
52 	}
53 
54 	if (eEncoding == encoding_utf_8) {
55 		fprintf(pFile, "%.*s", (int)tStringLength, szString);
56 		return;
57 	}
58 
59 	if (ucNbsp == 0) {
60 		ucNbsp = ucGetNbspCharacter();
61 		DBG_HEX_C(ucNbsp != 0xa0, ucNbsp);
62 	}
63 
64 	pucStart = (UCHAR *)szString;
65 	pucLast = pucStart + tStringLength - 1;
66 	pucNonSpace = pucLast;
67 	while ((*pucNonSpace == (UCHAR)' ' || *pucNonSpace == ucNbsp) &&
68 	       pucNonSpace > pucStart) {
69 		pucNonSpace--;
70 	}
71 
72 	/* 1: The spaces at the start */
73 	pucByte = pucStart;
74 	while ((*pucByte == (UCHAR)' ' || *pucByte == ucNbsp) &&
75 	       pucByte <= pucLast) {
76 		(void)putc(' ', pFile);
77 		pucByte++;
78 	}
79 
80 	if (pucByte > pucLast) {
81 		/* There is no text, just spaces */
82 		return;
83 	}
84 
85 	/* 2: Start the *bold*, /italic/ and _underline_ */
86 	if (bIsBold(usFontstyle)) {
87 		(void)putc('*', pFile);
88 	}
89 	if (bIsItalic(usFontstyle)) {
90 		(void)putc('/', pFile);
91 	}
92 	if (bIsUnderline(usFontstyle)) {
93 		(void)putc('_', pFile);
94 	}
95 
96 	/* 3: The text itself */
97 	while (pucByte <= pucNonSpace) {
98 		if (*pucByte == ucNbsp) {
99 			(void)putc(' ', pFile);
100 		} else {
101 			(void)putc((char)*pucByte, pFile);
102 		}
103 		pucByte++;
104 	}
105 
106 	/* 4: End the *bold*, /italic/ and _underline_ */
107 	if (bIsUnderline(usFontstyle)) {
108 		(void)putc('_', pFile);
109 	}
110 	if (bIsItalic(usFontstyle)) {
111 		(void)putc('/', pFile);
112 	}
113 	if (bIsBold(usFontstyle)) {
114 		(void)putc('*', pFile);
115 	}
116 
117 	/* 5: The spaces at the end */
118 	while (pucByte <= pucLast) {
119 		(void)putc(' ', pFile);
120 		pucByte++;
121 	}
122 } /* end of vPrintFMT */
123 
124 /*
125  * vMoveTo - move to the given X,Y coordinates
126  *
127  * Move the current position of the given diagram to its X,Y coordinates,
128  * start on a new page if needed
129  */
130 static void
vMoveTo(diagram_type * pDiag)131 vMoveTo(diagram_type *pDiag)
132 {
133 	int	iCount, iNbr;
134 
135 	fail(pDiag == NULL);
136 	fail(pDiag->pOutFile == NULL);
137 
138 	if (pDiag->lYtop != lYtopCurr) {
139 		iNbr = iDrawUnits2Char(pDiag->lXleft);
140 		for (iCount = 0; iCount < iNbr; iCount++) {
141 			(void)putc(FILLER_CHAR, pDiag->pOutFile);
142 		}
143 		lYtopCurr = pDiag->lYtop;
144 	}
145 } /* end of vMoveTo */
146 
147 /*
148  * vSubstringFMT - print a sub string
149  */
150 void
vSubstringFMT(diagram_type * pDiag,const char * szString,size_t tStringLength,long lStringWidth,USHORT usFontstyle)151 vSubstringFMT(diagram_type *pDiag,
152 	const char *szString, size_t tStringLength, long lStringWidth,
153 	USHORT usFontstyle)
154 {
155 	fail(pDiag == NULL || szString == NULL);
156 	fail(pDiag->pOutFile == NULL);
157 	fail(pDiag->lXleft < 0);
158 	fail(tStringLength != strlen(szString));
159 
160 	if (szString[0] == '\0' || tStringLength == 0) {
161 		return;
162 	}
163 
164 	vMoveTo(pDiag);
165 	vPrintFMT(pDiag->pOutFile, szString, tStringLength, usFontstyle);
166 	pDiag->lXleft += lStringWidth;
167 } /* end of vSubstringFMT */
168