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 */