/[james]/archive/guilib/ufont.c
ViewVC logotype

Contents of /archive/guilib/ufont.c

Parent Directory Parent Directory | Revision Log Revision Log


Revision 16 - (show annotations) (download) (as text)
Mon Feb 10 22:56:40 2003 UTC (21 years, 9 months ago) by james
File MIME type: text/x-csrc
File size: 11406 byte(s)
Initial import.

1 /* ufont.c */
2
3 #include "ufont.h"
4
5 #include "oslib/osfile.h"
6
7
8 #define MALLOC_CHUNK 256
9
10
11 struct ufont_font
12 {
13 font_f handle[65536];
14 char character[65536];
15 unsigned int handles_used;
16 font_f handles[256];
17 };
18
19
20 os_error error_exists = { error_FONT_NOT_FOUND, "Fonts file not found" };
21 os_error error_memory = { error_FONT_NO_ROOM, "Insufficient memory for font" };
22 os_error error_size = { error_FONT_BAD_FONT_FILE, "Wrong size of font file" };
23
24
25 /*
26 * UFont_FindFont
27 *
28 * => as Font_FindFont, but
29 * font_name does not support '\' qualifiers
30 *
31 * <= as Font_FindFont, but
32 * handle is 32-bit
33 */
34
35 os_error *
36 xufont_find_font(char const *font_name,
37 int xsize,
38 int ysize,
39 int xres,
40 int yres,
41 struct ufont_font **font,
42 int *xres_out,
43 int *yres_out)
44 {
45 char *old_font;
46 char *fonts_file;
47 char file_name[256];
48 fileswitch_object_type obj_type;
49 int code;
50 int handle;
51 unsigned int size;
52 os_error *error;
53
54 /* find size of Fonts file */
55 strcpy(file_name, font_name);
56 strcat(file_name, ".Fonts");
57 error = xosfile_read_stamped_path(file_name, "UFont:", &obj_type, NULL, NULL, &size, NULL, NULL);
58 if (error != NULL) return error;
59 if (obj_type != fileswitch_IS_FILE) return &error_exists;
60
61 /* allocate memory */
62 fonts_file = malloc(size);
63 if (fonts_file == NULL) return &error_memory;
64
65 *font = malloc(sizeof(struct ufont_font));
66 if (*font == NULL) return &error_memory;
67
68 /* load Fonts */
69 error = xosfile_load_stamped_path(file_name, fonts_file, "UFont:", NULL, NULL, NULL, NULL, NULL);
70 if (error != NULL) return error;
71
72 /* open all fonts listed in Fonts */
73 for (old_font = fonts_file, handle = 0; old_font - fonts_file < size;
74 old_font += strlen(old_font) + 1, handle++)
75 {
76 /* #ifdef DEBUG */
77 /* printf("%i %s: ", handle, old_font); */
78 /* #endif */
79
80 error = xfont_find_font(old_font, xsize, ysize, xres, yres,
81 &(*font)->handles[handle], xres_out, yres_out);
82 if (error != NULL) return error;
83
84 /* #ifdef DEBUG */
85 /* printf("%i\n", (*font)->handles[handle]); */
86 /* #endif */
87 }
88 (*font)->handles_used = handle;
89
90 /* free Fonts */
91 free(fonts_file);
92
93 /* load Data */
94 strcpy(file_name, font_name);
95 strcat(file_name, ".Data");
96 error = xosfile_load_stamped_path(file_name, (byte *) (*font), "UFont:",
97 NULL, NULL, NULL, &size, NULL);
98 if (error != NULL) return error;
99 if (size != 2*65536) return &error_size;
100
101 /* change font indexes to font handles */
102 for (code = 0; code < 65536; code++)
103 (*font)->handle[code] = (*font)->handles[(*font)->handle[code]];
104
105 return NULL;
106 }
107
108
109 /*
110 * UFont_LoseFont
111 *
112 * => font handle as returned by UFont_FindFont
113 */
114
115 os_error *
116 xufont_lose_font(struct ufont_font *font)
117 {
118 unsigned int handle;
119 os_error *error;
120
121 /* close all fonts used */
122 for (handle = 0; handle < font->handles_used; handle++)
123 {
124 error = xfont_lose_font(font->handles[handle]);
125 if (error != NULL) return error;
126 }
127
128 /* free font structure */
129 free(font);
130
131 return NULL;
132 }
133
134
135 /*
136 * UFont_Paint
137 *
138 * => font handle as returned by UFont_FindFont
139 * string is unicode (2 byte characters), see UFont_Convert
140 * other parameters as Font_Paint
141 */
142
143 os_error *
144 xufont_paint(struct ufont_font *font,
145 wchar_t const *string,
146 font_string_flags flags,
147 int xpos,
148 int ypos,
149 font_paint_block const *block,
150 os_trfm const *trfm,
151 unsigned int length)
152 {
153 char *result;
154 os_error *error;
155
156 if ((flags & font_GIVEN_LENGTH) == 0) length = 0x7fffffff;
157
158 error = xufont_convert(font, string, length, &result, NULL);
159 if (error != NULL) return error;
160
161 error = xfont_paint(result[1], result,
162 (flags & (~font_GIVEN_LENGTH)) | font_GIVEN_FONT,
163 xpos, ypos, block, trfm, 0);
164 if (error != NULL) { free(result); return error; }
165
166 free(result);
167
168 return NULL;
169 }
170
171
172 /*
173 * UFont_Convert
174 *
175 * => initial font
176 * unicode string to convert
177 * length to convert (characters)
178 *
179 * control sequences in string (all 2 byte):
180 *
181 * 9, dx_low, dx_middle, dx_high (each 2 byte, but maximum 255)
182 * 11, dy_low, dy_middle, dy_high "
183 * 19, r, g, b, R, G, B, max "
184 * 25, underline_position, underline_thickness "
185 * 26, font_handle (4 bytes, ie. 2 wide characters)
186 * 27, m1, m2, m3, m4 (each matrix entry 4 bytes,
187 * 28, m1, m2, m3, m4, m5, m6 ie. 2 wide characters)
188 *
189 * <= string converted to Font_Paint format
190 * table of offsets in unicode string
191 */
192
193 os_error *
194 xufont_convert(struct ufont_font *font,
195 wchar_t const *string,
196 unsigned int length,
197 char **presult,
198 unsigned int **ptable)
199 {
200 char *result;
201 unsigned int string_index = 0;
202 unsigned int result_index = 0;
203 unsigned int i;
204 unsigned int current_size = MALLOC_CHUNK;
205 unsigned int *table;
206 font_f current_font = 0;
207
208 result = malloc(MALLOC_CHUNK);
209 if (result == NULL) return &error_memory;
210
211 if (ptable != NULL)
212 {
213 table = malloc(MALLOC_CHUNK * sizeof(unsigned int));
214 if (table == NULL) return &error_memory;
215 }
216
217 while ((string[string_index] != 0) && (string_index < length))
218 {
219 /* #ifdef DEBUG */
220 /* printf("0x%x ", string[string_index]); */
221 /* #endif */
222
223 if (result_index + 32 > current_size)
224 {
225 current_size += MALLOC_CHUNK;
226
227 result = realloc(result, current_size);
228 if (result == NULL) return &error_memory;
229
230 if (ptable != NULL)
231 {
232 table = realloc(result, current_size * sizeof(unsigned int));
233 if (table == NULL) return &error_memory;
234 }
235 }
236
237 if (ptable != NULL) table[result_index] = string_index;
238
239 switch (string[string_index])
240 {
241 case 9:
242 case 11:
243 {
244 if (ptable != NULL)
245 table[result_index + 1] = table[result_index + 2] = table[result_index + 3] = string_index;
246
247 result[result_index++] = string[string_index++];
248 result[result_index++] = string[string_index++];
249 result[result_index++] = string[string_index++];
250 result[result_index++] = string[string_index++];
251 break;
252 }
253 case 19:
254 {
255 if (ptable != NULL)
256 table[result_index + 1] = table[result_index + 2] = table[result_index + 3] =
257 table[result_index + 4] = table[result_index + 5] = table[result_index + 6] =
258 table[result_index + 7] = string_index;
259
260 result[result_index++] = string[string_index++];
261 result[result_index++] = string[string_index++];
262 result[result_index++] = string[string_index++];
263 result[result_index++] = string[string_index++];
264 result[result_index++] = string[string_index++];
265 result[result_index++] = string[string_index++];
266 result[result_index++] = string[string_index++];
267 result[result_index++] = string[string_index++];
268 break;
269 }
270 case 25:
271 {
272 if (ptable != NULL)
273 table[result_index + 1] = table[result_index + 2] = string_index;
274
275 result[result_index++] = string[string_index++];
276 result[result_index++] = string[string_index++];
277 result[result_index++] = string[string_index++];
278 break;
279 }
280 case 26:
281 {
282 string_index++;
283 font = (struct ufont_font *) ((string[string_index + 1] << 16) | string[string_index]);
284 break;
285 }
286 case 27:
287 {
288 if (ptable != NULL)
289 for (i = result_index + 1; i < ((result_index + 1 + 16 + 3) & (unsigned int) (~3)); i++)
290 table[i] = string_index;
291
292 result[result_index++] = string[string_index++];
293 result_index = (result_index + 3) & (unsigned int) (~3);
294 for (i = 0; i < 8; i++)
295 {
296 result[result_index++] = string[string_index] & 0xff;
297 result[result_index++] = string[string_index++] >> 8;
298 }
299 break;
300 }
301 case 28:
302 {
303 if (ptable != NULL)
304 for (i = result_index + 1; i < ((result_index + 1 + 24 + 3) & (unsigned int) (~3)); i++)
305 table[i] = string_index;
306
307 result[result_index++] = string[string_index++];
308 result_index = (result_index + 3) & (unsigned int) (~3);
309 for (i = 0; i < 12; i++)
310 {
311 result[result_index++] = string[string_index] & 0xff;
312 result[result_index++] = string[string_index++] >> 8;
313 }
314 break;
315 }
316 default:
317 {
318 if (font->handle[(unsigned int) string[string_index]] != current_font)
319 {
320 if (ptable != NULL)
321 table[result_index + 1] = table[result_index + 2] = string_index;
322
323 result[result_index++] = 26;
324 result[result_index++] = current_font = font->handle[(unsigned int) string[string_index]];
325
326 /* #ifdef DEBUG */
327 /* printf("{%i} ", current_font); */
328 /* #endif */
329 }
330 result[result_index++] = font->character[(unsigned int) string[string_index++]];
331
332 /* #ifdef DEBUG */
333 /* printf("[0x%x] ", result[result_index - 1]); */
334 /* #endif */
335
336 break;
337 }
338 }
339 }
340 result[result_index] = 0;
341
342 *presult = result;
343 if (ptable != NULL)
344 {
345 table[result_index] = string_index;
346 *ptable = table;
347 }
348
349 /* #ifdef DEBUG */
350 /* printf("\n"); */
351
352 /* for (result_index = 0; result[result_index] != 0; result_index++) */
353 /* printf("0x%x ", result[result_index]); */
354 /* printf("\n"); */
355 /* #endif */
356
357 return NULL;
358 }
359
360
361 /*
362 * UFont_ScanString
363 *
364 * => font handle as returned by UFont_FindFont
365 * string is unicode (2 byte characters), see UFont_Convert
366 * split length is index in string, not pointer
367 * other parameters as Font_ScanString
368 *
369 * <= as Font_ScanString
370 */
371
372 extern os_error *
373 xufont_scan_string(ufont_f font,
374 wchar_t const *string,
375 font_string_flags flags,
376 int x,
377 int y,
378 font_scan_block const *block,
379 os_trfm const *trfm,
380 unsigned int length,
381 int *split_length,
382 int *x_out,
383 int *y_out,
384 int *length_out)
385 {
386 char *result;
387 char *split_point;
388 unsigned int *table;
389 os_error *error;
390
391 if ((flags & font_GIVEN_LENGTH) == 0) length = 0x7fffffff;
392
393 error = xufont_convert(font, string, length, &result, &table);
394 if (error != NULL) return error;
395
396 /* #ifdef DEBUG */
397 /* { */
398 /* unsigned int i; */
399 /* for (i = 0; i < 200; i++) */
400 /* printf("%i ", table[i]); */
401 /* printf("\n"); */
402 /* } */
403 /* #endif */
404
405 error = xfont_scan_string((font_f) result[1], result,
406 (flags & (~font_GIVEN_LENGTH)) | font_GIVEN_FONT,
407 x, y, block, trfm, 0,
408 &split_point, x_out, y_out, length_out);
409 if (error != NULL) { free(result); return error; }
410
411 if (split_length != NULL)
412 *split_length = table[split_point - result];
413
414 free(result);
415 free(table);
416
417 return NULL;
418 }

  ViewVC Help
Powered by ViewVC 1.1.26