xref: /plan9-contrib/sys/src/cmd/aux/antiword/fonts_r.c (revision 25b329d522281a8cdd35da0dcc08c3fc621059a9)
1f5736e95SDavid du Colombier /*
2f5736e95SDavid du Colombier  * fonts_r.c
3f5736e95SDavid du Colombier  * Copyright (C) 1999-2002 A.J. van Os; Released under GPL
4f5736e95SDavid du Colombier  *
5f5736e95SDavid du Colombier  * Description:
6f5736e95SDavid du Colombier  * Functions to deal with fonts (RiscOs version)
7f5736e95SDavid du Colombier  */
8f5736e95SDavid du Colombier 
9f5736e95SDavid du Colombier #include <stdlib.h>
10f5736e95SDavid du Colombier #include <string.h>
11*25b329d5SDavid du Colombier #include "DeskLib:Font.h"
12*25b329d5SDavid du Colombier #include "drawfile.h"
13f5736e95SDavid du Colombier #include "antiword.h"
14f5736e95SDavid du Colombier 
15*25b329d5SDavid du Colombier static font_handle	tFontCurr = (font_handle)-1;
16f5736e95SDavid du Colombier 
17f5736e95SDavid du Colombier /*
18f5736e95SDavid du Colombier  * pOpenFontTableFile - open the Font translation file
19f5736e95SDavid du Colombier  * Copy the file to the proper place if necessary.
20f5736e95SDavid du Colombier  *
21f5736e95SDavid du Colombier  * Returns the file pointer or NULL
22f5736e95SDavid du Colombier  */
23f5736e95SDavid du Colombier FILE *
pOpenFontTableFile(void)24f5736e95SDavid du Colombier pOpenFontTableFile(void)
25f5736e95SDavid du Colombier {
26f5736e95SDavid du Colombier 	FILE	*pFileR, *pFileW;
27f5736e95SDavid du Colombier 	char	*szFontNamesFile;
28f5736e95SDavid du Colombier 	size_t	tSize;
29f5736e95SDavid du Colombier 	BOOL	bFailed;
30f5736e95SDavid du Colombier 	char	acBuffer[256];
31f5736e95SDavid du Colombier 
32f5736e95SDavid du Colombier 	pFileR = fopen("<AntiWord$FontNamesFile>", "r");
33f5736e95SDavid du Colombier 	if (pFileR != NULL) {
34f5736e95SDavid du Colombier 		/* The font table is already in the right directory */
35f5736e95SDavid du Colombier 		return pFileR;
36f5736e95SDavid du Colombier 	}
37f5736e95SDavid du Colombier 
38f5736e95SDavid du Colombier 	szFontNamesFile = getenv("AntiWord$FontNamesSave");
39f5736e95SDavid du Colombier 	if (szFontNamesFile == NULL) {
40f5736e95SDavid du Colombier 		werr(0, "Warning: Name of the FontNames file not found");
41f5736e95SDavid du Colombier 		return NULL;
42f5736e95SDavid du Colombier 	}
43f5736e95SDavid du Colombier 	DBG_MSG(szFontNamesFile);
44f5736e95SDavid du Colombier 
45f5736e95SDavid du Colombier 	pFileR = fopen("<AntiWord$Dir>.Resources.Default", "r");
46f5736e95SDavid du Colombier 	if (pFileR == NULL) {
47f5736e95SDavid du Colombier 		werr(0, "I can't find 'Resources.Default'");
48f5736e95SDavid du Colombier 		return NULL;
49f5736e95SDavid du Colombier 	}
50f5736e95SDavid du Colombier 	/* Here the default font translation table is known to exist */
51f5736e95SDavid du Colombier 
52f5736e95SDavid du Colombier 	if (!bMakeDirectory(szFontNamesFile)) {
53f5736e95SDavid du Colombier 		werr(0,
54f5736e95SDavid du Colombier 		"I can't make a directory for the FontNames file");
55f5736e95SDavid du Colombier 		return NULL;
56f5736e95SDavid du Colombier 	}
57f5736e95SDavid du Colombier 	/* Here the proper directory is known to exist */
58f5736e95SDavid du Colombier 
59f5736e95SDavid du Colombier 	pFileW = fopen(szFontNamesFile, "w");
60f5736e95SDavid du Colombier 	if (pFileW == NULL) {
61f5736e95SDavid du Colombier 		(void)fclose(pFileR);
62f5736e95SDavid du Colombier 		werr(0, "I can't create a default FontNames file");
63f5736e95SDavid du Colombier 		return NULL;
64f5736e95SDavid du Colombier 	}
65f5736e95SDavid du Colombier 	/* Here the proper directory is known to be writeable */
66f5736e95SDavid du Colombier 
67f5736e95SDavid du Colombier 	/* Copy the default FontNames file */
68f5736e95SDavid du Colombier 	bFailed = FALSE;
69f5736e95SDavid du Colombier 	while (!feof(pFileR)) {
70f5736e95SDavid du Colombier 		tSize = fread(acBuffer, 1, sizeof(acBuffer), pFileR);
71f5736e95SDavid du Colombier 		if (ferror(pFileR)) {
72f5736e95SDavid du Colombier 			DBG_MSG("Read error");
73f5736e95SDavid du Colombier 			bFailed = TRUE;
74f5736e95SDavid du Colombier 			break;
75f5736e95SDavid du Colombier 		}
76f5736e95SDavid du Colombier 		if (fwrite(acBuffer, 1, tSize, pFileW) != tSize) {
77f5736e95SDavid du Colombier 			DBG_MSG("Write error");
78f5736e95SDavid du Colombier 			bFailed = TRUE;
79f5736e95SDavid du Colombier 			break;
80f5736e95SDavid du Colombier 		}
81f5736e95SDavid du Colombier 	}
82f5736e95SDavid du Colombier 	(void)fclose(pFileW);
83f5736e95SDavid du Colombier 	(void)fclose(pFileR);
84f5736e95SDavid du Colombier 	if (bFailed) {
85f5736e95SDavid du Colombier 		DBG_MSG("Copying the FontNames file failed");
86f5736e95SDavid du Colombier 		(void)remove(szFontNamesFile);
87f5736e95SDavid du Colombier 		return NULL;
88f5736e95SDavid du Colombier 	}
89f5736e95SDavid du Colombier 	return fopen(szFontNamesFile, "r");
90f5736e95SDavid du Colombier } /* end of pOpenFontTableFile */
91f5736e95SDavid du Colombier 
92f5736e95SDavid du Colombier /*
93f5736e95SDavid du Colombier  * vCloseFont - close the current font, if any
94f5736e95SDavid du Colombier  */
95f5736e95SDavid du Colombier void
vCloseFont(void)96f5736e95SDavid du Colombier vCloseFont(void)
97f5736e95SDavid du Colombier {
98f5736e95SDavid du Colombier 	os_error	*e;
99f5736e95SDavid du Colombier 
100f5736e95SDavid du Colombier 	NO_DBG_MSG("vCloseFont");
101f5736e95SDavid du Colombier 
102*25b329d5SDavid du Colombier 	if (tFontCurr == (font_handle)-1) {
103f5736e95SDavid du Colombier 		return;
104f5736e95SDavid du Colombier 	}
105*25b329d5SDavid du Colombier 	e = Font_LoseFont(tFontCurr);
106f5736e95SDavid du Colombier 	if (e != NULL) {
107f5736e95SDavid du Colombier 		werr(0, "Close font error %d: %s", e->errnum, e->errmess);
108f5736e95SDavid du Colombier 	}
109*25b329d5SDavid du Colombier 	tFontCurr = (font_handle)-1;
110f5736e95SDavid du Colombier } /* end of vCloseFont */
111f5736e95SDavid du Colombier 
112f5736e95SDavid du Colombier /*
113f5736e95SDavid du Colombier  * tOpenFont - make the specified font the current font
114f5736e95SDavid du Colombier  *
115f5736e95SDavid du Colombier  * Returns the font reference number for use in a draw file
116f5736e95SDavid du Colombier  */
117*25b329d5SDavid du Colombier drawfile_fontref
tOpenFont(UCHAR ucWordFontNumber,USHORT usFontStyle,USHORT usWordFontSize)118f5736e95SDavid du Colombier tOpenFont(UCHAR ucWordFontNumber, USHORT usFontStyle, USHORT usWordFontSize)
119f5736e95SDavid du Colombier {
120f5736e95SDavid du Colombier 	os_error	*e;
121f5736e95SDavid du Colombier 	const char	*szOurFontname;
122*25b329d5SDavid du Colombier 	font_handle	tFont;
123f5736e95SDavid du Colombier 	int	iFontnumber;
124f5736e95SDavid du Colombier 
125f5736e95SDavid du Colombier 	NO_DBG_MSG("tOpenFont");
126f5736e95SDavid du Colombier 	NO_DBG_DEC(ucWordFontNumber);
127f5736e95SDavid du Colombier 	NO_DBG_HEX(usFontStyle);
128f5736e95SDavid du Colombier 	NO_DBG_DEC(usWordFontSize);
129f5736e95SDavid du Colombier 
130f5736e95SDavid du Colombier 	/* Keep the relevant bits */
131f5736e95SDavid du Colombier 	usFontStyle &= FONT_BOLD|FONT_ITALIC;
132f5736e95SDavid du Colombier 	NO_DBG_HEX(usFontStyle);
133f5736e95SDavid du Colombier 
134f5736e95SDavid du Colombier 	iFontnumber = iGetFontByNumber(ucWordFontNumber, usFontStyle);
135f5736e95SDavid du Colombier 	szOurFontname = szGetOurFontname(iFontnumber);
136f5736e95SDavid du Colombier 	if (szOurFontname == NULL || szOurFontname[0] == '\0') {
137*25b329d5SDavid du Colombier 		tFontCurr = (font_handle)-1;
138*25b329d5SDavid du Colombier 		return (byte)0;
139f5736e95SDavid du Colombier 	}
140f5736e95SDavid du Colombier 	NO_DBG_MSG(szOurFontname);
141*25b329d5SDavid du Colombier 	e = Font_FindFont(&tFont, (char *)szOurFontname,
142f5736e95SDavid du Colombier 			(int)usWordFontSize * 8, (int)usWordFontSize * 8,
143*25b329d5SDavid du Colombier 			0, 0);
144f5736e95SDavid du Colombier 	if (e != NULL) {
145f5736e95SDavid du Colombier 		switch (e->errnum) {
146f5736e95SDavid du Colombier 		case 523:
147f5736e95SDavid du Colombier 			werr(0, "%s", e->errmess);
148f5736e95SDavid du Colombier 			break;
149f5736e95SDavid du Colombier 		default:
150f5736e95SDavid du Colombier 			werr(0, "Open font error %d: %s",
151f5736e95SDavid du Colombier 				e->errnum, e->errmess);
152f5736e95SDavid du Colombier 			break;
153f5736e95SDavid du Colombier 		}
154*25b329d5SDavid du Colombier 		tFontCurr = (font_handle)-1;
155*25b329d5SDavid du Colombier 		return (drawfile_fontref)0;
156f5736e95SDavid du Colombier 	}
157f5736e95SDavid du Colombier 	tFontCurr = tFont;
158f5736e95SDavid du Colombier 	NO_DBG_DEC(tFontCurr);
159*25b329d5SDavid du Colombier 	return (drawfile_fontref)(iFontnumber + 1);
160f5736e95SDavid du Colombier } /* end of tOpenFont */
161f5736e95SDavid du Colombier 
162f5736e95SDavid du Colombier /*
163f5736e95SDavid du Colombier  * tOpenTableFont - make the table font the current font
164f5736e95SDavid du Colombier  *
165f5736e95SDavid du Colombier  * Returns the font reference number for use in a draw file
166f5736e95SDavid du Colombier  */
167*25b329d5SDavid du Colombier drawfile_fontref
tOpenTableFont(USHORT usWordFontSize)168f5736e95SDavid du Colombier tOpenTableFont(USHORT usWordFontSize)
169f5736e95SDavid du Colombier {
170f5736e95SDavid du Colombier 	int	iWordFontnumber;
171f5736e95SDavid du Colombier 
172f5736e95SDavid du Colombier 	NO_DBG_MSG("tOpenTableFont");
173f5736e95SDavid du Colombier 
174f5736e95SDavid du Colombier 	iWordFontnumber = iFontname2Fontnumber(TABLE_FONT, FONT_REGULAR);
175f5736e95SDavid du Colombier 	if (iWordFontnumber < 0 || iWordFontnumber > (int)UCHAR_MAX) {
176f5736e95SDavid du Colombier 		DBG_DEC(iWordFontnumber);
177*25b329d5SDavid du Colombier 		tFontCurr = (font_handle)-1;
178*25b329d5SDavid du Colombier 		return (drawfile_fontref)0;
179f5736e95SDavid du Colombier 	}
180f5736e95SDavid du Colombier 
181f5736e95SDavid du Colombier 	return tOpenFont((UCHAR)iWordFontnumber, FONT_REGULAR, usWordFontSize);
182f5736e95SDavid du Colombier } /* end of tOpenTableFont */
183f5736e95SDavid du Colombier 
184f5736e95SDavid du Colombier /*
185f5736e95SDavid du Colombier  * lComputeStringWidth - compute the string width
186f5736e95SDavid du Colombier  *
187f5736e95SDavid du Colombier  * Returns the string width in millipoints
188f5736e95SDavid du Colombier  */
189f5736e95SDavid du Colombier long
lComputeStringWidth(const char * szString,size_t tStringLength,drawfile_fontref tFontRef,USHORT usFontSize)190f5736e95SDavid du Colombier lComputeStringWidth(const char *szString, size_t tStringLength,
191*25b329d5SDavid du Colombier 	drawfile_fontref tFontRef, USHORT usFontSize)
192f5736e95SDavid du Colombier {
193f5736e95SDavid du Colombier 	font_string	tStr;
194f5736e95SDavid du Colombier 	os_error	*e;
195f5736e95SDavid du Colombier 
196f5736e95SDavid du Colombier 	fail(szString == NULL);
197f5736e95SDavid du Colombier 	fail(usFontSize < MIN_FONT_SIZE || usFontSize > MAX_FONT_SIZE);
198f5736e95SDavid du Colombier 
199f5736e95SDavid du Colombier 	if (szString[0] == '\0' || tStringLength == 0) {
200f5736e95SDavid du Colombier 		/* Empty string */
201f5736e95SDavid du Colombier 		return 0;
202f5736e95SDavid du Colombier 	}
203f5736e95SDavid du Colombier 	if (tStringLength == 1 && szString[0] == TABLE_SEPARATOR) {
204f5736e95SDavid du Colombier 		/* Font_strwidth doesn't like control characters */
205f5736e95SDavid du Colombier 		return 0;
206f5736e95SDavid du Colombier 	}
207*25b329d5SDavid du Colombier 	if (tFontCurr == (font_handle)-1) {
208f5736e95SDavid du Colombier 		/* No current font, use systemfont */
209f5736e95SDavid du Colombier 		return lChar2MilliPoints(tStringLength);
210f5736e95SDavid du Colombier 	}
211f5736e95SDavid du Colombier 	tStr.s = (char *)szString;
212f5736e95SDavid du Colombier 	tStr.x = INT_MAX;
213f5736e95SDavid du Colombier 	tStr.y = INT_MAX;
214f5736e95SDavid du Colombier 	tStr.split = -1;
215f5736e95SDavid du Colombier 	tStr.term = tStringLength;
216*25b329d5SDavid du Colombier 	e = Font_StringWidth(&tStr);
217f5736e95SDavid du Colombier 	if (e == NULL) {
218f5736e95SDavid du Colombier 		return (long)tStr.x;
219f5736e95SDavid du Colombier 	}
220f5736e95SDavid du Colombier 	DBG_DEC(e->errnum);
221f5736e95SDavid du Colombier 	DBG_MSG(e->errmess);
222f5736e95SDavid du Colombier 	DBG_DEC(tStringLength);
223f5736e95SDavid du Colombier 	DBG_MSG(szString);
224f5736e95SDavid du Colombier 	werr(0, "String width error %d: %s", e->errnum, e->errmess);
225f5736e95SDavid du Colombier 	return lChar2MilliPoints(tStringLength);
226f5736e95SDavid du Colombier } /* end of lComputeStringWidth */
227f5736e95SDavid du Colombier 
228f5736e95SDavid du Colombier /*
229f5736e95SDavid du Colombier  * tCountColumns - count the number of columns in a string
230f5736e95SDavid du Colombier  *
231f5736e95SDavid du Colombier  * Returns the number of columns
232f5736e95SDavid du Colombier  */
233f5736e95SDavid du Colombier size_t
tCountColumns(const char * szString,size_t tLength)234f5736e95SDavid du Colombier tCountColumns(const char *szString, size_t tLength)
235f5736e95SDavid du Colombier {
236f5736e95SDavid du Colombier 	fail(szString == NULL);
237f5736e95SDavid du Colombier 
238f5736e95SDavid du Colombier 	/* One byte, one character, one column */
239f5736e95SDavid du Colombier 	return tLength;
240f5736e95SDavid du Colombier } /* end of tCountColumns */
241f5736e95SDavid du Colombier 
242f5736e95SDavid du Colombier /*
243f5736e95SDavid du Colombier  * tGetCharacterLength - the length of the specified character in bytes
244f5736e95SDavid du Colombier  *
245f5736e95SDavid du Colombier  * Returns the length in bytes
246f5736e95SDavid du Colombier  */
247f5736e95SDavid du Colombier size_t
tGetCharacterLength(const char * szString)248f5736e95SDavid du Colombier tGetCharacterLength(const char *szString)
249f5736e95SDavid du Colombier {
250f5736e95SDavid du Colombier 	return 1;
251f5736e95SDavid du Colombier } /* end of tGetCharacterLength */
252