Subversion Repositories planix.SVN

Rev

Rev 2 | Details | Compare with Previous | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
/*
2
 * fonts_u.c
3
 * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL
4
 *
5
 * Description:
6
 * Functions to deal with fonts (Unix version)
7
 */
8
 
9
#include <stdio.h>
10
#include <stdlib.h>
11
#include <string.h>
12
#include "antiword.h"
13
#include "fontinfo.h"
14
 
15
/* Don't use fonts, just plain text */
16
static BOOL		bUsePlainText = TRUE;
17
/* Which character set should be used */
18
static encoding_type	eEncoding = encoding_neutral;
19
 
20
 
21
/*
22
 * pOpenFontTableFile - open the Font translation file
23
 *
24
 * Returns the file pointer or NULL
25
 */
26
FILE *
27
pOpenFontTableFile(void)
28
{
29
	FILE		*pFile;
30
	const char	*szHome, *szAntiword, *szGlobalFile;
31
	char		szEnvironmentFile[PATH_MAX+1];
32
	char		szLocalFile[PATH_MAX+1];
33
 
34
	szEnvironmentFile[0] = '\0';
35
	szLocalFile[0] = '\0';
36
 
37
	/* Try the environment version of the fontnames file */
38
	szAntiword = szGetAntiwordDirectory();
39
	if (szAntiword != NULL && szAntiword[0] != '\0') {
40
		if (strlen(szAntiword) +
41
		    sizeof(FILE_SEPARATOR FONTNAMES_FILE) >=
42
		    sizeof(szEnvironmentFile)) {
43
			werr(0,
44
			"The name of your ANTIWORDHOME directory is too long");
45
			return NULL;
46
		}
47
		sprintf(szEnvironmentFile, "%s%s",
48
			szAntiword,
49
			FILE_SEPARATOR FONTNAMES_FILE);
50
		DBG_MSG(szEnvironmentFile);
51
 
52
		pFile = fopen(szEnvironmentFile, "r");
53
		if (pFile != NULL) {
54
			return pFile;
55
		}
56
	}
57
 
58
	/* Try the local version of the fontnames file */
59
	szHome = szGetHomeDirectory();
60
	if (strlen(szHome) +
61
	    sizeof(FILE_SEPARATOR ANTIWORD_DIR FILE_SEPARATOR FONTNAMES_FILE) >=
62
	    sizeof(szLocalFile)) {
63
		werr(0, "The name of your HOME directory is too long");
64
		return NULL;
65
	}
66
 
67
	sprintf(szLocalFile, "%s%s",
68
		szHome,
69
		FILE_SEPARATOR ANTIWORD_DIR FILE_SEPARATOR FONTNAMES_FILE);
70
	DBG_MSG(szLocalFile);
71
 
72
	pFile = fopen(szLocalFile, "r");
73
	if (pFile != NULL) {
74
		return pFile;
75
	}
76
 
77
	/* Try the global version of the fontnames file */
78
	szGlobalFile = GLOBAL_ANTIWORD_DIR FILE_SEPARATOR FONTNAMES_FILE;
79
	DBG_MSG(szGlobalFile);
80
 
81
	pFile = fopen(szGlobalFile, "r");
82
	if (pFile != NULL) {
83
		return pFile;
84
	}
85
 
86
	if (szEnvironmentFile[0] != '\0') {
87
		werr(0, "I can not open your fontnames file.\n"
88
			"Neither '%s' nor\n"
89
			"'%s' nor\n"
90
			"'%s' can be opened for reading.",
91
			szEnvironmentFile, szLocalFile, szGlobalFile);
92
	} else {
93
		werr(0, "I can not open your fontnames file.\n"
94
			"Neither '%s' nor\n"
95
			"'%s' can be opened for reading.",
96
			szLocalFile, szGlobalFile);
97
	}
98
	return NULL;
99
} /* end of pOpenFontTableFile */
100
 
101
/*
102
 * vCloseFont - close the current font, if any
103
 */
104
void
105
vCloseFont(void)
106
{
107
	NO_DBG_MSG("vCloseFont");
108
	/* For safety: to be overwritten at the next call of tOpenfont() */
109
	eEncoding = encoding_neutral;
110
	bUsePlainText = TRUE;
111
} /* end of vCloseFont */
112
 
113
/*
114
 * tOpenFont - make the specified font the current font
115
 *
116
 * Returns the font reference number
117
 */
118
drawfile_fontref
119
tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
120
{
121
	options_type	tOptions;
122
	const char	*szOurFontname;
123
	size_t	tIndex;
124
	int	iFontnumber;
125
 
126
	NO_DBG_MSG("tOpenFont");
127
	NO_DBG_DEC(ucWordFontNumber);
128
	NO_DBG_HEX(usFontStyle);
129
	NO_DBG_DEC(usWordFontSize);
130
 
131
	/* Keep the relevant bits */
132
	usFontStyle &= FONT_BOLD|FONT_ITALIC;
133
	NO_DBG_HEX(usFontStyle);
134
 
135
	vGetOptions(&tOptions);
136
	eEncoding = tOptions.eEncoding;
137
	bUsePlainText = tOptions.eConversionType != conversion_draw &&
138
			tOptions.eConversionType != conversion_ps &&
139
			tOptions.eConversionType != conversion_pdf;
140
 
141
	if (bUsePlainText) {
142
		/* Plain text, no fonts */
143
		return (drawfile_fontref)0;
144
	}
145
 
146
	iFontnumber = iGetFontByNumber(ucWordFontNumber, usFontStyle);
147
	szOurFontname = szGetOurFontname(iFontnumber);
148
	if (szOurFontname == NULL || szOurFontname[0] == '\0') {
149
		DBG_DEC(iFontnumber);
150
		return (drawfile_fontref)0;
151
	}
152
	NO_DBG_MSG(szOurFontname);
153
 
154
	for (tIndex = 0; tIndex < elementsof(szFontnames); tIndex++) {
155
		if (STREQ(szFontnames[tIndex], szOurFontname)) {
156
			NO_DBG_DEC(tIndex);
157
			return (drawfile_fontref)tIndex;
158
		}
159
	}
160
	return (drawfile_fontref)0;
161
} /* end of tOpenFont */
162
 
163
/*
164
 * tOpenTableFont - make the table font the current font
165
 *
166
 * Returns the font reference number
167
 */
168
drawfile_fontref
169
tOpenTableFont(USHORT usWordFontSize)
170
{
171
	options_type	tOptions;
172
	int	iWordFontnumber;
173
 
174
	NO_DBG_MSG("tOpenTableFont");
175
 
176
	vGetOptions(&tOptions);
177
	eEncoding = tOptions.eEncoding;
178
	bUsePlainText = tOptions.eConversionType != conversion_draw &&
179
			tOptions.eConversionType != conversion_ps &&
180
			tOptions.eConversionType != conversion_pdf;
181
 
182
	if (bUsePlainText) {
183
		/* Plain text, no fonts */
184
		return (drawfile_fontref)0;
185
	}
186
 
187
	iWordFontnumber = iFontname2Fontnumber(TABLE_FONT, FONT_REGULAR);
188
	if (iWordFontnumber < 0 || iWordFontnumber > (int)UCHAR_MAX) {
189
		DBG_DEC(iWordFontnumber);
190
		return (drawfile_fontref)0;
191
	}
192
 
193
	return tOpenFont((UCHAR)iWordFontnumber, FONT_REGULAR, usWordFontSize);
194
} /* end of tOpenTableFont */
195
 
196
/*
197
 * szGetFontname - get the fontname
198
 */
199
const char *
200
szGetFontname(drawfile_fontref tFontRef)
201
{
202
	fail((size_t)(UCHAR)tFontRef >= elementsof(szFontnames));
203
	return szFontnames[(int)(UCHAR)tFontRef];
204
} /* end of szGetFontname */
205
 
206
/*
207
 * lComputeStringWidth - compute the string width
208
 *
209
 * Note: the fontsize is specified in half-points!
210
 *       the stringlength is specified in bytes, not characters!
211
 *
212
 * Returns the string width in millipoints
213
 */
214
long
215
lComputeStringWidth(const char *szString, size_t tStringLength,
216
	drawfile_fontref tFontRef, USHORT usFontSize)
217
{
218
	USHORT	*ausCharWidths;
219
	UCHAR	*pucChar;
220
	long	lRelWidth;
221
	size_t	tIndex;
222
	int	iFontRef;
223
 
224
	fail(szString == NULL);
225
	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
226
 
227
	if (szString[0] == '\0' || tStringLength == 0) {
228
		/* Empty string */
229
		return 0;
230
	}
231
 
232
	if (eEncoding == encoding_utf_8) {
233
		fail(!bUsePlainText);
234
		return lChar2MilliPoints(
235
			utf8_strwidth(szString, tStringLength));
236
	}
237
 
238
	if (bUsePlainText) {
239
		/* No current font, use "systemfont" */
240
		return lChar2MilliPoints(tStringLength);
241
	}
242
 
243
	if (eEncoding == encoding_cyrillic) {
244
		/* FIXME: until the character tables are available */
245
		return (tStringLength * 600L * (long)usFontSize + 1) / 2;
246
	}
247
 
248
	DBG_DEC_C(eEncoding != encoding_latin_1 &&
249
		eEncoding != encoding_latin_2, eEncoding);
250
	fail(eEncoding != encoding_latin_1 &&
251
		eEncoding != encoding_latin_2);
252
 
253
	/* Compute the relative string width */
254
	iFontRef = (int)(UCHAR)tFontRef;
255
	if (eEncoding == encoding_latin_2) {
256
		ausCharWidths = ausCharacterWidths2[iFontRef];
257
	} else {
258
		ausCharWidths = ausCharacterWidths1[iFontRef];
259
	}
260
	lRelWidth = 0;
261
	for (tIndex = 0, pucChar = (UCHAR *)szString;
262
	     tIndex < tStringLength;
263
	     tIndex++, pucChar++) {
264
		lRelWidth += (long)ausCharWidths[(int)*pucChar];
265
	}
266
 
267
	/* Compute the absolute string width */
268
	return (lRelWidth * (long)usFontSize + 1) / 2;
269
} /* end of lComputeStringWidth */
270
 
271
/*
272
 * tCountColumns - count the number of columns in a string
273
 *
274
 * Note: the length is specified in bytes!
275
 *       A UTF-8 a character can be 0, 1 or 2 columns wide.
276
 *
277
 * Returns the number of columns
278
 */
279
size_t
280
tCountColumns(const char *szString, size_t tLength)
281
{
282
	fail(szString == NULL);
283
 
284
	if (eEncoding != encoding_utf_8) {
285
		/* One byte, one character, one column */
286
		return tLength;
287
	}
288
	return (size_t)utf8_strwidth(szString, tLength);
289
} /* end of tCountColumns */
290
 
291
/*
292
 * tGetCharacterLength - the length of the specified character in bytes
293
 *
294
 * Returns the length in bytes
295
 */
296
size_t
297
tGetCharacterLength(const char *szString)
298
{
299
	fail(szString == NULL);
300
 
301
	if (eEncoding != encoding_utf_8) {
302
		return 1;
303
	}
304
	return (size_t)utf8_chrlength(szString);
305
} /* end of tGetCharacterLength */