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

Annotation of /archive/guilib/ufont.c

Parent Directory Parent Directory | Revision Log Revision Log


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

1 james 16 /* 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