3 * Copyright (C) 1999-2004 A.J. van Os; Released under GNU GPL
6 * Functions to deal with fonts (Unix version)
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;
22 * pOpenFontTableFile - open the Font translation file
24 * Returns the file pointer or NULL
27 pOpenFontTableFile(void)
30 const char *szHome, *szAntiword, *szGlobalFile;
31 char szEnvironmentFile[PATH_MAX+1];
32 char szLocalFile[PATH_MAX+1];
34 szEnvironmentFile[0] = '\0';
35 szLocalFile[0] = '\0';
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)) {
44 "The name of your ANTIWORDHOME directory is too long");
47 sprintf(szEnvironmentFile, "%s%s",
49 FILE_SEPARATOR FONTNAMES_FILE);
50 DBG_MSG(szEnvironmentFile);
52 pFile = fopen(szEnvironmentFile, "r");
58 /* Try the local version of the fontnames file */
59 szHome = szGetHomeDirectory();
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");
67 sprintf(szLocalFile, "%s%s",
69 FILE_SEPARATOR ANTIWORD_DIR FILE_SEPARATOR FONTNAMES_FILE);
72 pFile = fopen(szLocalFile, "r");
77 /* Try the global version of the fontnames file */
78 szGlobalFile = GLOBAL_ANTIWORD_DIR FILE_SEPARATOR FONTNAMES_FILE;
79 DBG_MSG(szGlobalFile);
81 pFile = fopen(szGlobalFile, "r");
86 if (szEnvironmentFile[0] != '\0') {
87 werr(0, "I can not open your fontnames file.\n"
90 "'%s' can be opened for reading.",
91 szEnvironmentFile, szLocalFile, szGlobalFile);
93 werr(0, "I can not open your fontnames file.\n"
95 "'%s' can be opened for reading.",
96 szLocalFile, szGlobalFile);
99 } /* end of pOpenFontTableFile */
102 * vCloseFont - close the current font, if any
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 */
114 * tOpenFont - make the specified font the current font
116 * Returns the font reference number
119 tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
121 options_type tOptions;
122 const char *szOurFontname;
126 NO_DBG_MSG("tOpenFont");
127 NO_DBG_DEC(ucWordFontNumber);
128 NO_DBG_HEX(usFontStyle);
129 NO_DBG_DEC(usWordFontSize);
131 /* Keep the relevant bits */
132 usFontStyle &= FONT_BOLD|FONT_ITALIC;
133 NO_DBG_HEX(usFontStyle);
135 vGetOptions(&tOptions);
136 eEncoding = tOptions.eEncoding;
137 bUsePlainText = tOptions.eConversionType != conversion_draw &&
138 tOptions.eConversionType != conversion_ps &&
139 tOptions.eConversionType != conversion_pdf;
142 /* Plain text, no fonts */
143 return (drawfile_fontref)0;
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;
152 NO_DBG_MSG(szOurFontname);
154 for (tIndex = 0; tIndex < elementsof(szFontnames); tIndex++) {
155 if (STREQ(szFontnames[tIndex], szOurFontname)) {
157 return (drawfile_fontref)tIndex;
160 return (drawfile_fontref)0;
161 } /* end of tOpenFont */
164 * tOpenTableFont - make the table font the current font
166 * Returns the font reference number
169 tOpenTableFont(USHORT usWordFontSize)
171 options_type tOptions;
174 NO_DBG_MSG("tOpenTableFont");
176 vGetOptions(&tOptions);
177 eEncoding = tOptions.eEncoding;
178 bUsePlainText = tOptions.eConversionType != conversion_draw &&
179 tOptions.eConversionType != conversion_ps &&
180 tOptions.eConversionType != conversion_pdf;
183 /* Plain text, no fonts */
184 return (drawfile_fontref)0;
187 iWordFontnumber = iFontname2Fontnumber(TABLE_FONT, FONT_REGULAR);
188 if (iWordFontnumber < 0 || iWordFontnumber > (int)UCHAR_MAX) {
189 DBG_DEC(iWordFontnumber);
190 return (drawfile_fontref)0;
193 return tOpenFont((UCHAR)iWordFontnumber, FONT_REGULAR, usWordFontSize);
194 } /* end of tOpenTableFont */
197 * szGetFontname - get the fontname
200 szGetFontname(drawfile_fontref tFontRef)
202 fail((size_t)(UCHAR)tFontRef >= elementsof(szFontnames));
203 return szFontnames[(int)(UCHAR)tFontRef];
204 } /* end of szGetFontname */
207 * lComputeStringWidth - compute the string width
209 * Note: the fontsize is specified in half-points!
210 * the stringlength is specified in bytes, not characters!
212 * Returns the string width in millipoints
215 lComputeStringWidth(const char *szString, size_t tStringLength,
216 drawfile_fontref tFontRef, USHORT usFontSize)
218 USHORT *ausCharWidths;
224 fail(szString == NULL);
225 fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
227 if (szString[0] == '\0' || tStringLength == 0) {
232 if (eEncoding == encoding_utf_8) {
233 fail(!bUsePlainText);
234 return lChar2MilliPoints(
235 utf8_strwidth(szString, tStringLength));
239 /* No current font, use "systemfont" */
240 return lChar2MilliPoints(tStringLength);
243 if (eEncoding == encoding_cyrillic) {
244 /* FIXME: until the character tables are available */
245 return (tStringLength * 600L * (long)usFontSize + 1) / 2;
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);
253 /* Compute the relative string width */
254 iFontRef = (int)(UCHAR)tFontRef;
255 if (eEncoding == encoding_latin_2) {
256 ausCharWidths = ausCharacterWidths2[iFontRef];
258 ausCharWidths = ausCharacterWidths1[iFontRef];
261 for (tIndex = 0, pucChar = (UCHAR *)szString;
262 tIndex < tStringLength;
263 tIndex++, pucChar++) {
264 lRelWidth += (long)ausCharWidths[(int)*pucChar];
267 /* Compute the absolute string width */
268 return (lRelWidth * (long)usFontSize + 1) / 2;
269 } /* end of lComputeStringWidth */
272 * tCountColumns - count the number of columns in a string
274 * Note: the length is specified in bytes!
275 * A UTF-8 a character can be 0, 1 or 2 columns wide.
277 * Returns the number of columns
280 tCountColumns(const char *szString, size_t tLength)
282 fail(szString == NULL);
284 if (eEncoding != encoding_utf_8) {
285 /* One byte, one character, one column */
288 return (size_t)utf8_strwidth(szString, tLength);
289 } /* end of tCountColumns */
292 * tGetCharacterLength - the length of the specified character in bytes
294 * Returns the length in bytes
297 tGetCharacterLength(const char *szString)
299 fail(szString == NULL);
301 if (eEncoding != encoding_utf_8) {
304 return (size_t)utf8_chrlength(szString);
305 } /* end of tGetCharacterLength */