diff options
Diffstat (limited to 'libraries/evas/src/lib/canvas/evas_font_dir.c')
-rw-r--r-- | libraries/evas/src/lib/canvas/evas_font_dir.c | 1349 |
1 files changed, 0 insertions, 1349 deletions
diff --git a/libraries/evas/src/lib/canvas/evas_font_dir.c b/libraries/evas/src/lib/canvas/evas_font_dir.c deleted file mode 100644 index e97f7f7..0000000 --- a/libraries/evas/src/lib/canvas/evas_font_dir.c +++ /dev/null | |||
@@ -1,1349 +0,0 @@ | |||
1 | #ifdef HAVE_CONFIG_H | ||
2 | # include <config.h> | ||
3 | #endif | ||
4 | |||
5 | #ifdef HAVE_EVIL | ||
6 | # include <Evil.h> | ||
7 | #endif | ||
8 | |||
9 | #ifdef BUILD_FONT_LOADER_EET | ||
10 | #include <Eet.h> | ||
11 | #endif | ||
12 | |||
13 | #ifdef HAVE_FONTCONFIG | ||
14 | #include <fontconfig/fontconfig.h> | ||
15 | #endif | ||
16 | |||
17 | #include "evas_common.h" | ||
18 | #include "evas_private.h" | ||
19 | |||
20 | /* font dir cache */ | ||
21 | static Eina_Hash *font_dirs = NULL; | ||
22 | static Eina_List *fonts_cache = NULL; | ||
23 | static Eina_List *fonts_zero = NULL; | ||
24 | |||
25 | typedef struct _Fndat Fndat; | ||
26 | |||
27 | struct _Fndat | ||
28 | { | ||
29 | Evas_Font_Description *fdesc; | ||
30 | const char *source; | ||
31 | Evas_Font_Size size; | ||
32 | Evas_Font_Set *font; | ||
33 | int ref; | ||
34 | Font_Rend_Flags wanted_rend; | ||
35 | |||
36 | #ifdef HAVE_FONTCONFIG | ||
37 | FcFontSet *set; | ||
38 | FcPattern *p_nm; | ||
39 | #endif | ||
40 | }; | ||
41 | |||
42 | /* private methods for font dir cache */ | ||
43 | static Eina_Bool font_cache_dir_free(const Eina_Hash *hash, const void *key, void *data, void *fdata); | ||
44 | static Evas_Font_Dir *object_text_font_cache_dir_update(char *dir, Evas_Font_Dir *fd); | ||
45 | static Evas_Font *object_text_font_cache_font_find_x(Evas_Font_Dir *fd, char *font); | ||
46 | static Evas_Font *object_text_font_cache_font_find_file(Evas_Font_Dir *fd, char *font); | ||
47 | static Evas_Font *object_text_font_cache_font_find_alias(Evas_Font_Dir *fd, char *font); | ||
48 | static Evas_Font *object_text_font_cache_font_find(Evas_Font_Dir *fd, char *font); | ||
49 | static Evas_Font_Dir *object_text_font_cache_dir_add(char *dir); | ||
50 | static void object_text_font_cache_dir_del(char *dir, Evas_Font_Dir *fd); | ||
51 | static int evas_object_text_font_string_parse(char *buffer, char dest[14][256]); | ||
52 | |||
53 | #ifdef HAVE_FONTCONFIG | ||
54 | static int fc_init = 0; | ||
55 | #endif | ||
56 | |||
57 | void | ||
58 | evas_font_dir_cache_free(void) | ||
59 | { | ||
60 | if (!font_dirs) return; | ||
61 | |||
62 | eina_hash_foreach(font_dirs, font_cache_dir_free, NULL); | ||
63 | eina_hash_free(font_dirs); | ||
64 | font_dirs = NULL; | ||
65 | |||
66 | #ifdef HAVE_FONTCONFIG | ||
67 | /* this is bad i got a: | ||
68 | * fccache.c:512: FcCacheFini: Assertion fcCacheChains[i] == ((void *)0)' failed. | ||
69 | * | ||
70 | * all i can do for now is shut this puppy down. butthat breaks, so disable | ||
71 | * it as in reality - there is little reason to care about the memory not | ||
72 | * being freed etc. | ||
73 | * | ||
74 | * fc_init--; | ||
75 | * if (fc_init == 0) FcFini(); | ||
76 | */ | ||
77 | #endif | ||
78 | } | ||
79 | |||
80 | const char * | ||
81 | evas_font_dir_cache_find(char *dir, char *font) | ||
82 | { | ||
83 | Evas_Font_Dir *fd = NULL; | ||
84 | |||
85 | if (!font_dirs) font_dirs = eina_hash_string_superfast_new(NULL); | ||
86 | else fd = eina_hash_find(font_dirs, dir); | ||
87 | fd = object_text_font_cache_dir_update(dir, fd); | ||
88 | if (fd) | ||
89 | { | ||
90 | Evas_Font *fn; | ||
91 | |||
92 | fn = object_text_font_cache_font_find(fd, font); | ||
93 | if (fn) | ||
94 | { | ||
95 | return fn->path; | ||
96 | } | ||
97 | } | ||
98 | return NULL; | ||
99 | } | ||
100 | |||
101 | static Eina_List * | ||
102 | evas_font_set_get(const char *name) | ||
103 | { | ||
104 | Eina_List *fonts = NULL; | ||
105 | char *p; | ||
106 | |||
107 | p = strchr(name, ','); | ||
108 | if (!p) | ||
109 | { | ||
110 | fonts = eina_list_append(fonts, eina_stringshare_add(name)); | ||
111 | } | ||
112 | else | ||
113 | { | ||
114 | const char *pp; | ||
115 | char *nm; | ||
116 | |||
117 | pp = name; | ||
118 | while (p) | ||
119 | { | ||
120 | nm = alloca(p - pp + 1); | ||
121 | strncpy(nm, pp, p - pp); | ||
122 | nm[p - pp] = 0; | ||
123 | fonts = eina_list_append(fonts, eina_stringshare_add(nm)); | ||
124 | pp = p + 1; | ||
125 | p = strchr(pp, ','); | ||
126 | if (!p) fonts = eina_list_append(fonts, eina_stringshare_add(pp)); | ||
127 | } | ||
128 | } | ||
129 | return fonts; | ||
130 | } | ||
131 | |||
132 | void | ||
133 | evas_fonts_zero_free(Evas *evas) | ||
134 | { | ||
135 | Fndat *fd; | ||
136 | |||
137 | EINA_LIST_FREE(fonts_zero, fd) | ||
138 | { | ||
139 | if (fd->fdesc) evas_font_desc_unref(fd->fdesc); | ||
140 | if (fd->source) eina_stringshare_del(fd->source); | ||
141 | evas->engine.func->font_free(evas->engine.data.output, fd->font); | ||
142 | #ifdef HAVE_FONTCONFIG | ||
143 | if (fd->set) FcFontSetDestroy(fd->set); | ||
144 | if (fd->p_nm) FcPatternDestroy(fd->p_nm); | ||
145 | #endif | ||
146 | free(fd); | ||
147 | } | ||
148 | } | ||
149 | |||
150 | void | ||
151 | evas_fonts_zero_presure(Evas *evas) | ||
152 | { | ||
153 | Fndat *fd; | ||
154 | |||
155 | while (fonts_zero | ||
156 | && eina_list_count(fonts_zero) > 4) /* 4 is arbitrary */ | ||
157 | { | ||
158 | fd = eina_list_data_get(fonts_zero); | ||
159 | |||
160 | if (fd->ref != 0) break; | ||
161 | fonts_zero = eina_list_remove_list(fonts_zero, fonts_zero); | ||
162 | |||
163 | if (fd->fdesc) evas_font_desc_unref(fd->fdesc); | ||
164 | if (fd->source) eina_stringshare_del(fd->source); | ||
165 | evas->engine.func->font_free(evas->engine.data.output, fd->font); | ||
166 | #ifdef HAVE_FONTCONFIG | ||
167 | if (fd->set) FcFontSetDestroy(fd->set); | ||
168 | if (fd->p_nm) FcPatternDestroy(fd->p_nm); | ||
169 | #endif | ||
170 | free(fd); | ||
171 | |||
172 | if (eina_list_count(fonts_zero) < 5) break; | ||
173 | } | ||
174 | } | ||
175 | |||
176 | void | ||
177 | evas_font_free(Evas *evas, void *font) | ||
178 | { | ||
179 | Eina_List *l; | ||
180 | Fndat *fd; | ||
181 | |||
182 | EINA_LIST_FOREACH(fonts_cache, l, fd) | ||
183 | { | ||
184 | if (fd->font == font) | ||
185 | { | ||
186 | fd->ref--; | ||
187 | if (fd->ref == 0) | ||
188 | { | ||
189 | fonts_cache = eina_list_remove_list(fonts_cache, l); | ||
190 | fonts_zero = eina_list_append(fonts_zero, fd); | ||
191 | } | ||
192 | break; | ||
193 | } | ||
194 | } | ||
195 | while (fonts_zero | ||
196 | && eina_list_count(fonts_zero) > 42) /* 42 is arbitrary */ | ||
197 | { | ||
198 | fd = eina_list_data_get(fonts_zero); | ||
199 | |||
200 | if (fd->ref != 0) break; | ||
201 | fonts_zero = eina_list_remove_list(fonts_zero, fonts_zero); | ||
202 | |||
203 | if (fd->fdesc) evas_font_desc_unref(fd->fdesc); | ||
204 | if (fd->source) eina_stringshare_del(fd->source); | ||
205 | evas->engine.func->font_free(evas->engine.data.output, fd->font); | ||
206 | #ifdef HAVE_FONTCONFIG | ||
207 | if (fd->set) FcFontSetDestroy(fd->set); | ||
208 | if (fd->p_nm) FcPatternDestroy(fd->p_nm); | ||
209 | #endif | ||
210 | free(fd); | ||
211 | |||
212 | if (eina_list_count(fonts_zero) < 43) break; | ||
213 | } | ||
214 | } | ||
215 | |||
216 | static void | ||
217 | evas_font_init(void) | ||
218 | { | ||
219 | static int done = 0; | ||
220 | if (done) return; | ||
221 | done = 1; | ||
222 | #ifdef HAVE_FONTCONFIG | ||
223 | fc_init++; | ||
224 | if (fc_init == 1) | ||
225 | { | ||
226 | FcInit(); | ||
227 | FcConfigEnableHome(1); | ||
228 | } | ||
229 | #endif | ||
230 | } | ||
231 | |||
232 | #ifdef HAVE_FONTCONFIG | ||
233 | static Evas_Font_Set * | ||
234 | evas_load_fontconfig(Evas *evas, FcFontSet *set, int size, | ||
235 | Font_Rend_Flags wanted_rend) | ||
236 | { | ||
237 | Evas_Font_Set *font = NULL; | ||
238 | int i; | ||
239 | |||
240 | /* Do loading for all in family */ | ||
241 | for (i = 0; i < set->nfont; i++) | ||
242 | { | ||
243 | FcValue filename; | ||
244 | |||
245 | FcPatternGet(set->fonts[i], FC_FILE, 0, &filename); | ||
246 | |||
247 | if (font) | ||
248 | evas->engine.func->font_add(evas->engine.data.output, font, (char *)filename.u.s, size, wanted_rend); | ||
249 | else | ||
250 | font = evas->engine.func->font_load(evas->engine.data.output, (char *)filename.u.s, size, wanted_rend); | ||
251 | } | ||
252 | |||
253 | return font; | ||
254 | } | ||
255 | #endif | ||
256 | |||
257 | #ifdef HAVE_FONTCONFIG | ||
258 | /* In sync with Evas_Font_Style, Evas_Font_Weight and Evas_Font_Width */ | ||
259 | static int _fc_slant_map[] = | ||
260 | { | ||
261 | FC_SLANT_ROMAN, | ||
262 | FC_SLANT_OBLIQUE, | ||
263 | FC_SLANT_ITALIC | ||
264 | }; | ||
265 | |||
266 | static int _fc_weight_map[] = | ||
267 | { | ||
268 | FC_WEIGHT_NORMAL, | ||
269 | FC_WEIGHT_THIN, | ||
270 | FC_WEIGHT_ULTRALIGHT, | ||
271 | FC_WEIGHT_LIGHT, | ||
272 | FC_WEIGHT_BOOK, | ||
273 | FC_WEIGHT_MEDIUM, | ||
274 | FC_WEIGHT_SEMIBOLD, | ||
275 | FC_WEIGHT_BOLD, | ||
276 | FC_WEIGHT_ULTRABOLD, | ||
277 | FC_WEIGHT_BLACK, | ||
278 | FC_WEIGHT_EXTRABLACK | ||
279 | }; | ||
280 | |||
281 | # ifdef FC_WIDTH | ||
282 | static int _fc_width_map[] = | ||
283 | { | ||
284 | FC_WIDTH_NORMAL, | ||
285 | FC_WIDTH_ULTRACONDENSED, | ||
286 | FC_WIDTH_EXTRACONDENSED, | ||
287 | FC_WIDTH_CONDENSED, | ||
288 | FC_WIDTH_SEMICONDENSED, | ||
289 | FC_WIDTH_SEMIEXPANDED, | ||
290 | FC_WIDTH_EXPANDED, | ||
291 | FC_WIDTH_EXTRAEXPANDED, | ||
292 | FC_WIDTH_ULTRAEXPANDED | ||
293 | }; | ||
294 | # endif | ||
295 | |||
296 | #endif | ||
297 | |||
298 | struct _Style_Map | ||
299 | { | ||
300 | const char *name; | ||
301 | int type; | ||
302 | }; | ||
303 | typedef struct _Style_Map Style_Map; | ||
304 | |||
305 | static Style_Map _style_width_map[] = | ||
306 | { | ||
307 | {"normal", EVAS_FONT_WIDTH_NORMAL}, | ||
308 | {"ultracondensed", EVAS_FONT_WIDTH_ULTRACONDENSED}, | ||
309 | {"extracondensed", EVAS_FONT_WIDTH_EXTRACONDENSED}, | ||
310 | {"condensed", EVAS_FONT_WIDTH_CONDENSED}, | ||
311 | {"semicondensed", EVAS_FONT_WIDTH_SEMICONDENSED}, | ||
312 | {"semiexpanded", EVAS_FONT_WIDTH_SEMIEXPANDED}, | ||
313 | {"expanded", EVAS_FONT_WIDTH_EXPANDED}, | ||
314 | {"extraexpanded", EVAS_FONT_WIDTH_EXTRAEXPANDED}, | ||
315 | {"ultraexpanded", EVAS_FONT_WIDTH_ULTRAEXPANDED}, | ||
316 | }; | ||
317 | |||
318 | static Style_Map _style_weight_map[] = | ||
319 | { | ||
320 | {"normal", EVAS_FONT_WEIGHT_NORMAL}, | ||
321 | {"thin", EVAS_FONT_WEIGHT_THIN}, | ||
322 | {"ultralight", EVAS_FONT_WEIGHT_ULTRALIGHT}, | ||
323 | {"light", EVAS_FONT_WEIGHT_LIGHT}, | ||
324 | {"book", EVAS_FONT_WEIGHT_BOOK}, | ||
325 | {"medium", EVAS_FONT_WEIGHT_MEDIUM}, | ||
326 | {"semibold", EVAS_FONT_WEIGHT_SEMIBOLD}, | ||
327 | {"bold", EVAS_FONT_WEIGHT_BOLD}, | ||
328 | {"ultrabold", EVAS_FONT_WEIGHT_ULTRABOLD}, | ||
329 | {"black", EVAS_FONT_WEIGHT_BLACK}, | ||
330 | {"extrablack", EVAS_FONT_WEIGHT_EXTRABLACK} | ||
331 | }; | ||
332 | |||
333 | static Style_Map _style_slant_map[] = | ||
334 | { | ||
335 | {"normal", EVAS_FONT_SLANT_NORMAL}, | ||
336 | {"oblique", EVAS_FONT_SLANT_OBLIQUE}, | ||
337 | {"italic", EVAS_FONT_SLANT_ITALIC} | ||
338 | }; | ||
339 | |||
340 | #define _STYLE_MAP_LEN(x) (sizeof(x) / sizeof(*(x))) | ||
341 | /** | ||
342 | * @internal | ||
343 | * Find a certain attribute from the map in the style. | ||
344 | * @return the index of the found one. | ||
345 | */ | ||
346 | static int | ||
347 | _evas_font_style_find_internal(const char *style, const char *style_end, | ||
348 | Style_Map _map[], size_t map_len) | ||
349 | { | ||
350 | size_t i; | ||
351 | while (style < style_end) | ||
352 | { | ||
353 | for (i = 0 ; i < map_len ; i++) | ||
354 | { | ||
355 | size_t len; | ||
356 | const char *cur = _map[i].name; | ||
357 | len = strlen(cur); | ||
358 | if (!strncasecmp(style, cur, len) && | ||
359 | (!cur[len] || (cur[len] == ' '))) | ||
360 | { | ||
361 | return _map[i].type; | ||
362 | } | ||
363 | } | ||
364 | style = strchr(style, ' '); | ||
365 | if (!style) | ||
366 | break; | ||
367 | |||
368 | while (*style && (*style == ' ')) | ||
369 | style++; | ||
370 | } | ||
371 | return 0; | ||
372 | } | ||
373 | |||
374 | int | ||
375 | evas_font_style_find(const char *start, const char *end, | ||
376 | Evas_Font_Style style) | ||
377 | { | ||
378 | #define _RET_STYLE(x) \ | ||
379 | return _evas_font_style_find_internal(start, end, \ | ||
380 | _style_##x##_map, _STYLE_MAP_LEN(_style_##x##_map)); | ||
381 | switch (style) | ||
382 | { | ||
383 | case EVAS_FONT_STYLE_SLANT: | ||
384 | _RET_STYLE(slant); | ||
385 | case EVAS_FONT_STYLE_WEIGHT: | ||
386 | _RET_STYLE(weight); | ||
387 | case EVAS_FONT_STYLE_WIDTH: | ||
388 | _RET_STYLE(width); | ||
389 | default: | ||
390 | return 0; | ||
391 | } | ||
392 | #undef _RET_STYLE | ||
393 | } | ||
394 | |||
395 | void | ||
396 | evas_font_desc_unref(Evas_Font_Description *fdesc) | ||
397 | { | ||
398 | if (--(fdesc->ref) == 0) | ||
399 | { | ||
400 | eina_stringshare_del(fdesc->name); | ||
401 | eina_stringshare_del(fdesc->fallbacks); | ||
402 | eina_stringshare_del(fdesc->lang); | ||
403 | free(fdesc); | ||
404 | } | ||
405 | } | ||
406 | |||
407 | Evas_Font_Description * | ||
408 | evas_font_desc_ref(Evas_Font_Description *fdesc) | ||
409 | { | ||
410 | fdesc->ref++; | ||
411 | return fdesc; | ||
412 | } | ||
413 | |||
414 | Evas_Font_Description * | ||
415 | evas_font_desc_new(void) | ||
416 | { | ||
417 | Evas_Font_Description *fdesc; | ||
418 | fdesc = calloc(1, sizeof(*fdesc)); | ||
419 | fdesc->ref = 1; | ||
420 | fdesc->is_new = EINA_TRUE; | ||
421 | |||
422 | return fdesc; | ||
423 | } | ||
424 | |||
425 | Evas_Font_Description * | ||
426 | evas_font_desc_dup(const Evas_Font_Description *fdesc) | ||
427 | { | ||
428 | Evas_Font_Description *new; | ||
429 | new = evas_font_desc_new(); | ||
430 | memcpy(new, fdesc, sizeof(*new)); | ||
431 | new->ref = 1; | ||
432 | new->is_new = EINA_TRUE; | ||
433 | new->name = eina_stringshare_ref(new->name); | ||
434 | |||
435 | return new; | ||
436 | } | ||
437 | |||
438 | int | ||
439 | evas_font_desc_cmp(const Evas_Font_Description *a, | ||
440 | const Evas_Font_Description *b) | ||
441 | { | ||
442 | /* FIXME: Do actual comparison, i.e less than and bigger than. */ | ||
443 | return !((a->name == b->name) && (a->weight == b->weight) && | ||
444 | (a->slant == b->slant) && (a->width == b->width) && | ||
445 | (a->lang == b->lang)); | ||
446 | } | ||
447 | |||
448 | void | ||
449 | evas_font_name_parse(Evas_Font_Description *fdesc, const char *name) | ||
450 | { | ||
451 | const char *end; | ||
452 | |||
453 | end = strchr(name, ':'); | ||
454 | if (!end) | ||
455 | eina_stringshare_replace(&(fdesc->name), name); | ||
456 | else | ||
457 | eina_stringshare_replace_length(&(fdesc->name), name, end - name); | ||
458 | |||
459 | while (end) | ||
460 | { | ||
461 | const char *tend; | ||
462 | name = end; | ||
463 | end = strchr(end + 1, ':'); | ||
464 | if (!end) | ||
465 | tend = name + strlen(name); | ||
466 | else | ||
467 | tend = end; | ||
468 | |||
469 | if (!strncmp(name, ":style=", 7)) | ||
470 | { | ||
471 | #define _SET_STYLE(x) \ | ||
472 | fdesc->x = _evas_font_style_find_internal(name + 7, tend, \ | ||
473 | _style_##x##_map, _STYLE_MAP_LEN(_style_##x##_map)); | ||
474 | _SET_STYLE(slant); | ||
475 | _SET_STYLE(weight); | ||
476 | _SET_STYLE(width); | ||
477 | #undef _SET_STYLE | ||
478 | } | ||
479 | else if (!strncmp(name, ":lang=", 6)) | ||
480 | { | ||
481 | const char *tmp = name + 6; | ||
482 | eina_stringshare_replace_length(&(fdesc->lang), tmp, tend - tmp); | ||
483 | } | ||
484 | } | ||
485 | } | ||
486 | |||
487 | void * | ||
488 | evas_font_load(Evas *evas, Evas_Font_Description *fdesc, const char *source, Evas_Font_Size size) | ||
489 | { | ||
490 | #ifdef HAVE_FONTCONFIG | ||
491 | FcPattern *p_nm = NULL; | ||
492 | FcFontSet *set = NULL; | ||
493 | #endif | ||
494 | |||
495 | Evas_Font_Set *font = NULL; | ||
496 | Eina_List *fonts, *l; | ||
497 | Fndat *fd; | ||
498 | char *nm; | ||
499 | Font_Rend_Flags wanted_rend = 0; | ||
500 | |||
501 | if (!fdesc) return NULL; | ||
502 | fdesc->is_new = EINA_FALSE; | ||
503 | |||
504 | if (fdesc->slant != EVAS_FONT_SLANT_NORMAL) | ||
505 | wanted_rend |= FONT_REND_SLANT; | ||
506 | if (fdesc->weight == EVAS_FONT_WEIGHT_BOLD) | ||
507 | wanted_rend |= FONT_REND_WEIGHT; | ||
508 | |||
509 | evas_font_init(); | ||
510 | |||
511 | EINA_LIST_FOREACH(fonts_cache, l, fd) | ||
512 | { | ||
513 | if (!evas_font_desc_cmp(fdesc, fd->fdesc)) | ||
514 | { | ||
515 | if (((!source) && (!fd->source)) || | ||
516 | ((source) && (fd->source) && (!strcmp(source, fd->source)))) | ||
517 | { | ||
518 | if ((size == fd->size) && | ||
519 | (wanted_rend == fd->wanted_rend)) | ||
520 | { | ||
521 | fonts_cache = eina_list_promote_list(fonts_cache, l); | ||
522 | fd->ref++; | ||
523 | return fd->font; | ||
524 | } | ||
525 | #ifdef HAVE_FONTCONFIG | ||
526 | else if (fd->set && fd->p_nm) | ||
527 | { | ||
528 | font = evas_load_fontconfig(evas, fd->set, size, | ||
529 | wanted_rend); | ||
530 | goto on_find; | ||
531 | } | ||
532 | #endif | ||
533 | } | ||
534 | } | ||
535 | } | ||
536 | |||
537 | EINA_LIST_FOREACH(fonts_zero, l, fd) | ||
538 | { | ||
539 | if (!evas_font_desc_cmp(fdesc, fd->fdesc)) | ||
540 | { | ||
541 | if (((!source) && (!fd->source)) || | ||
542 | ((source) && (fd->source) && (!strcmp(source, fd->source)))) | ||
543 | { | ||
544 | if ((size == fd->size) && | ||
545 | (wanted_rend == fd->wanted_rend)) | ||
546 | { | ||
547 | fonts_zero = eina_list_remove_list(fonts_zero, l); | ||
548 | fonts_cache = eina_list_prepend(fonts_cache, fd); | ||
549 | fd->ref++; | ||
550 | return fd->font; | ||
551 | } | ||
552 | #ifdef HAVE_FONTCONFIG | ||
553 | else if (fd->set && fd->p_nm) | ||
554 | { | ||
555 | font = evas_load_fontconfig(evas, fd->set, size, | ||
556 | wanted_rend); | ||
557 | goto on_find; | ||
558 | } | ||
559 | #endif | ||
560 | } | ||
561 | } | ||
562 | } | ||
563 | |||
564 | fonts = evas_font_set_get(fdesc->name); | ||
565 | EINA_LIST_FOREACH(fonts, l, nm) /* Load each font in append */ | ||
566 | { | ||
567 | if (l == fonts || !font) /* First iteration OR no font */ | ||
568 | { | ||
569 | #ifdef BUILD_FONT_LOADER_EET | ||
570 | if (source) /* Load Font from "eet" source */ | ||
571 | { | ||
572 | Eet_File *ef; | ||
573 | char *fake_name; | ||
574 | |||
575 | fake_name = evas_file_path_join(source, nm); | ||
576 | if (fake_name) | ||
577 | { | ||
578 | font = evas->engine.func->font_load(evas->engine.data.output, fake_name, size, wanted_rend); | ||
579 | if (!font) /* Load from fake name failed, probably not cached */ | ||
580 | { | ||
581 | /* read original!!! */ | ||
582 | ef = eet_open(source, EET_FILE_MODE_READ); | ||
583 | if (ef) | ||
584 | { | ||
585 | void *fdata; | ||
586 | int fsize = 0; | ||
587 | |||
588 | fdata = eet_read(ef, nm, &fsize); | ||
589 | if ((fdata) && (fsize > 0)) | ||
590 | { | ||
591 | font = evas->engine.func->font_memory_load(evas->engine.data.output, fake_name, size, fdata, fsize, wanted_rend); | ||
592 | free(fdata); | ||
593 | } | ||
594 | eet_close(ef); | ||
595 | } | ||
596 | } | ||
597 | free(fake_name); | ||
598 | } | ||
599 | } | ||
600 | if (!font) /* Source load failed */ | ||
601 | { | ||
602 | #endif | ||
603 | if (evas_file_path_is_full_path((char *)nm)) /* Try filename */ | ||
604 | font = evas->engine.func->font_load(evas->engine.data.output, (char *)nm, size, wanted_rend); | ||
605 | else /* search font path */ | ||
606 | { | ||
607 | Eina_List *ll; | ||
608 | char *dir; | ||
609 | |||
610 | EINA_LIST_FOREACH(evas->font_path, ll, dir) | ||
611 | { | ||
612 | const char *f_file; | ||
613 | |||
614 | f_file = evas_font_dir_cache_find(dir, (char *)nm); | ||
615 | if (f_file) | ||
616 | { | ||
617 | font = evas->engine.func->font_load(evas->engine.data.output, f_file, size, wanted_rend); | ||
618 | if (font) break; | ||
619 | } | ||
620 | } | ||
621 | } | ||
622 | #ifdef BUILD_FONT_LOADER_EET | ||
623 | } | ||
624 | #endif | ||
625 | } | ||
626 | else /* Base font loaded, append others */ | ||
627 | { | ||
628 | #ifdef BUILD_FONT_LOADER_EET | ||
629 | void *ok = NULL; | ||
630 | |||
631 | if (source) | ||
632 | { | ||
633 | Eet_File *ef; | ||
634 | char *fake_name; | ||
635 | |||
636 | fake_name = evas_file_path_join(source, nm); | ||
637 | if (fake_name) | ||
638 | { | ||
639 | /* FIXME: make an engine func */ | ||
640 | if (!evas->engine.func->font_add(evas->engine.data.output, font, fake_name, size, wanted_rend)) | ||
641 | { | ||
642 | /* read original!!! */ | ||
643 | ef = eet_open(source, EET_FILE_MODE_READ); | ||
644 | if (ef) | ||
645 | { | ||
646 | void *fdata; | ||
647 | int fsize = 0; | ||
648 | |||
649 | fdata = eet_read(ef, nm, &fsize); | ||
650 | if ((fdata) && (fsize > 0)) | ||
651 | { | ||
652 | ok = evas->engine.func->font_memory_add(evas->engine.data.output, font, fake_name, size, fdata, fsize, wanted_rend); | ||
653 | free(fdata); | ||
654 | } | ||
655 | eet_close(ef); | ||
656 | } | ||
657 | } | ||
658 | else | ||
659 | ok = (void *)1; | ||
660 | free(fake_name); | ||
661 | } | ||
662 | } | ||
663 | if (!ok) | ||
664 | { | ||
665 | #endif | ||
666 | if (evas_file_path_is_full_path((char *)nm)) | ||
667 | evas->engine.func->font_add(evas->engine.data.output, font, (char *)nm, size, wanted_rend); | ||
668 | else | ||
669 | { | ||
670 | Eina_List *ll; | ||
671 | char *dir; | ||
672 | |||
673 | EINA_LIST_FOREACH(evas->font_path, ll, dir) | ||
674 | { | ||
675 | const char *f_file; | ||
676 | |||
677 | f_file = evas_font_dir_cache_find(dir, (char *)nm); | ||
678 | if (f_file) | ||
679 | { | ||
680 | if (evas->engine.func->font_add(evas->engine.data.output, font, f_file, size, wanted_rend)) | ||
681 | break; | ||
682 | } | ||
683 | } | ||
684 | } | ||
685 | #ifdef BUILD_FONT_LOADER_EET | ||
686 | } | ||
687 | #endif | ||
688 | } | ||
689 | eina_stringshare_del(nm); | ||
690 | } | ||
691 | fonts = eina_list_free(fonts); | ||
692 | |||
693 | #ifdef HAVE_FONTCONFIG | ||
694 | if (!font) /* Search using fontconfig */ | ||
695 | { | ||
696 | FcResult res; | ||
697 | |||
698 | p_nm = FcPatternBuild (NULL, | ||
699 | FC_WEIGHT, FcTypeInteger, _fc_weight_map[fdesc->weight], | ||
700 | FC_SLANT, FcTypeInteger, _fc_slant_map[fdesc->slant], | ||
701 | #ifdef FC_WIDTH | ||
702 | FC_WIDTH, FcTypeInteger, _fc_width_map[fdesc->width], | ||
703 | #endif | ||
704 | NULL); | ||
705 | FcPatternAddString (p_nm, FC_FAMILY, (FcChar8*) fdesc->name); | ||
706 | |||
707 | /* Handle font fallbacks */ | ||
708 | if (fdesc->fallbacks) | ||
709 | { | ||
710 | while (1) | ||
711 | { | ||
712 | const char *start, *end; | ||
713 | start = fdesc->fallbacks; | ||
714 | end = strchr(start, ','); | ||
715 | if (end) | ||
716 | { | ||
717 | char *tmp = alloca((end - start) + 1); | ||
718 | strncpy(tmp, start, end - start); | ||
719 | tmp[end - start] = 0; | ||
720 | FcPatternAddString (p_nm, FC_FAMILY, (FcChar8*) tmp); | ||
721 | } | ||
722 | else | ||
723 | { | ||
724 | FcPatternAddString (p_nm, FC_FAMILY, (FcChar8*) start); | ||
725 | break; | ||
726 | } | ||
727 | } | ||
728 | } | ||
729 | |||
730 | if (fdesc->lang) | ||
731 | FcPatternAddString (p_nm, FC_LANG, (FcChar8 *) fdesc->lang); | ||
732 | |||
733 | FcConfigSubstitute(NULL, p_nm, FcMatchPattern); | ||
734 | FcDefaultSubstitute(p_nm); | ||
735 | |||
736 | /* do matching */ | ||
737 | set = FcFontSort(NULL, p_nm, FcTrue, NULL, &res); | ||
738 | if (!set) | ||
739 | { | ||
740 | ERR("No fontconfig font matches '%s'. It was the last resource, no font found!", fdesc->name); | ||
741 | FcPatternDestroy(p_nm); | ||
742 | p_nm = NULL; | ||
743 | } | ||
744 | else | ||
745 | { | ||
746 | font = evas_load_fontconfig(evas, set, size, wanted_rend); | ||
747 | } | ||
748 | } | ||
749 | #endif | ||
750 | |||
751 | #ifdef HAVE_FONTCONFIG | ||
752 | on_find: | ||
753 | #endif | ||
754 | fd = calloc(1, sizeof(Fndat)); | ||
755 | if (fd) | ||
756 | { | ||
757 | fd->fdesc = evas_font_desc_ref(fdesc); | ||
758 | if (source) fd->source = eina_stringshare_add(source); | ||
759 | fd->font = font; | ||
760 | fd->wanted_rend = wanted_rend; | ||
761 | fd->size = size; | ||
762 | fd->ref = 1; | ||
763 | fonts_cache = eina_list_prepend(fonts_cache, fd); | ||
764 | #ifdef HAVE_FONTCONFIG | ||
765 | fd->set = set; | ||
766 | fd->p_nm = p_nm; | ||
767 | #endif | ||
768 | } | ||
769 | |||
770 | if (font) | ||
771 | evas->engine.func->font_hinting_set(evas->engine.data.output, font, | ||
772 | evas->hinting); | ||
773 | return font; | ||
774 | } | ||
775 | |||
776 | void | ||
777 | evas_font_load_hinting_set(Evas *evas, void *font, int hinting) | ||
778 | { | ||
779 | evas->engine.func->font_hinting_set(evas->engine.data.output, font, | ||
780 | hinting); | ||
781 | } | ||
782 | |||
783 | Eina_List * | ||
784 | evas_font_dir_available_list(const Evas *evas) | ||
785 | { | ||
786 | Eina_List *l; | ||
787 | Eina_List *ll; | ||
788 | Eina_List *available = NULL; | ||
789 | char *dir; | ||
790 | |||
791 | #ifdef HAVE_FONTCONFIG | ||
792 | /* Add font config fonts */ | ||
793 | FcPattern *p; | ||
794 | FcFontSet *set = NULL; | ||
795 | FcObjectSet *os; | ||
796 | int i; | ||
797 | |||
798 | evas_font_init(); | ||
799 | |||
800 | p = FcPatternCreate(); | ||
801 | os = FcObjectSetBuild(FC_FAMILY, FC_STYLE, NULL); | ||
802 | |||
803 | if (p && os) set = FcFontList(NULL, p, os); | ||
804 | |||
805 | if (p) FcPatternDestroy(p); | ||
806 | if (os) FcObjectSetDestroy(os); | ||
807 | |||
808 | if (set) | ||
809 | { | ||
810 | for (i = 0; i < set->nfont; i++) | ||
811 | { | ||
812 | char *font; | ||
813 | |||
814 | font = (char *)FcNameUnparse(set->fonts[i]); | ||
815 | available = eina_list_append(available, eina_stringshare_add(font)); | ||
816 | free(font); | ||
817 | } | ||
818 | |||
819 | FcFontSetDestroy(set); | ||
820 | } | ||
821 | #endif | ||
822 | |||
823 | /* Add fonts in evas font_path*/ | ||
824 | if (!evas->font_path) | ||
825 | return available; | ||
826 | |||
827 | if (!font_dirs) font_dirs = eina_hash_string_superfast_new(NULL); | ||
828 | |||
829 | EINA_LIST_FOREACH(evas->font_path, l, dir) | ||
830 | { | ||
831 | Evas_Font_Dir *fd; | ||
832 | |||
833 | fd = eina_hash_find(font_dirs, dir); | ||
834 | fd = object_text_font_cache_dir_update(dir, fd); | ||
835 | if (fd && fd->aliases) | ||
836 | { | ||
837 | Evas_Font_Alias *fa; | ||
838 | |||
839 | EINA_LIST_FOREACH(fd->aliases, ll, fa) | ||
840 | available = eina_list_append(available, eina_stringshare_add((char *)fa->alias)); | ||
841 | } | ||
842 | } | ||
843 | |||
844 | return available; | ||
845 | } | ||
846 | |||
847 | void | ||
848 | evas_font_dir_available_list_free(Eina_List *available) | ||
849 | { | ||
850 | while (available) | ||
851 | { | ||
852 | eina_stringshare_del(available->data); | ||
853 | available = eina_list_remove(available, available->data); | ||
854 | } | ||
855 | } | ||
856 | |||
857 | /* private stuff */ | ||
858 | static Eina_Bool | ||
859 | font_cache_dir_free(const Eina_Hash *hash __UNUSED__, const void *key, void *data, void *fdata __UNUSED__) | ||
860 | { | ||
861 | object_text_font_cache_dir_del((char *) key, data); | ||
862 | return 1; | ||
863 | } | ||
864 | |||
865 | static Evas_Font_Dir * | ||
866 | object_text_font_cache_dir_update(char *dir, Evas_Font_Dir *fd) | ||
867 | { | ||
868 | DATA64 mt; | ||
869 | char *tmp; | ||
870 | |||
871 | if (fd) | ||
872 | { | ||
873 | mt = evas_file_modified_time(dir); | ||
874 | if (mt != fd->dir_mod_time) | ||
875 | { | ||
876 | object_text_font_cache_dir_del(dir, fd); | ||
877 | eina_hash_del(font_dirs, dir, fd); | ||
878 | } | ||
879 | else | ||
880 | { | ||
881 | tmp = evas_file_path_join(dir, "fonts.dir"); | ||
882 | if (tmp) | ||
883 | { | ||
884 | mt = evas_file_modified_time(tmp); | ||
885 | free(tmp); | ||
886 | if (mt != fd->fonts_dir_mod_time) | ||
887 | { | ||
888 | object_text_font_cache_dir_del(dir, fd); | ||
889 | eina_hash_del(font_dirs, dir, fd); | ||
890 | } | ||
891 | else | ||
892 | { | ||
893 | tmp = evas_file_path_join(dir, "fonts.alias"); | ||
894 | if (tmp) | ||
895 | { | ||
896 | mt = evas_file_modified_time(tmp); | ||
897 | free(tmp); | ||
898 | } | ||
899 | if (mt != fd->fonts_alias_mod_time) | ||
900 | { | ||
901 | object_text_font_cache_dir_del(dir, fd); | ||
902 | eina_hash_del(font_dirs, dir, fd); | ||
903 | } | ||
904 | else | ||
905 | return fd; | ||
906 | } | ||
907 | } | ||
908 | } | ||
909 | } | ||
910 | return object_text_font_cache_dir_add(dir); | ||
911 | } | ||
912 | |||
913 | static Evas_Font * | ||
914 | object_text_font_cache_font_find_x(Evas_Font_Dir *fd, char *font) | ||
915 | { | ||
916 | Eina_List *l; | ||
917 | char font_prop[14][256]; | ||
918 | int num; | ||
919 | Evas_Font *fn; | ||
920 | |||
921 | num = evas_object_text_font_string_parse(font, font_prop); | ||
922 | if (num != 14) return NULL; | ||
923 | EINA_LIST_FOREACH(fd->fonts, l, fn) | ||
924 | { | ||
925 | if (fn->type == 1) | ||
926 | { | ||
927 | int i; | ||
928 | int match = 0; | ||
929 | |||
930 | for (i = 0; i < 14; i++) | ||
931 | { | ||
932 | if ((font_prop[i][0] == '*') && (font_prop[i][1] == 0)) | ||
933 | match++; | ||
934 | else | ||
935 | { | ||
936 | if (!strcasecmp(font_prop[i], fn->x.prop[i])) match++; | ||
937 | else break; | ||
938 | } | ||
939 | } | ||
940 | if (match == 14) return fn; | ||
941 | } | ||
942 | } | ||
943 | return NULL; | ||
944 | } | ||
945 | |||
946 | static Evas_Font * | ||
947 | object_text_font_cache_font_find_file(Evas_Font_Dir *fd, char *font) | ||
948 | { | ||
949 | Eina_List *l; | ||
950 | Evas_Font *fn; | ||
951 | |||
952 | EINA_LIST_FOREACH(fd->fonts, l, fn) | ||
953 | { | ||
954 | if (fn->type == 0) | ||
955 | { | ||
956 | if (!strcasecmp(font, fn->simple.name)) return fn; | ||
957 | } | ||
958 | } | ||
959 | return NULL; | ||
960 | } | ||
961 | |||
962 | static Evas_Font * | ||
963 | object_text_font_cache_font_find_alias(Evas_Font_Dir *fd, char *font) | ||
964 | { | ||
965 | Eina_List *l; | ||
966 | Evas_Font_Alias *fa; | ||
967 | |||
968 | EINA_LIST_FOREACH(fd->aliases, l, fa) | ||
969 | if (!strcasecmp(fa->alias, font)) return fa->fn; | ||
970 | return NULL; | ||
971 | } | ||
972 | |||
973 | static Evas_Font * | ||
974 | object_text_font_cache_font_find(Evas_Font_Dir *fd, char *font) | ||
975 | { | ||
976 | Evas_Font *fn; | ||
977 | |||
978 | fn = eina_hash_find(fd->lookup, font); | ||
979 | if (fn) return fn; | ||
980 | fn = object_text_font_cache_font_find_alias(fd, font); | ||
981 | if (!fn) fn = object_text_font_cache_font_find_x(fd, font); | ||
982 | if (!fn) fn = object_text_font_cache_font_find_file(fd, font); | ||
983 | if (!fn) return NULL; | ||
984 | eina_hash_add(fd->lookup, font, fn); | ||
985 | return fn; | ||
986 | } | ||
987 | |||
988 | static Evas_Font_Dir * | ||
989 | object_text_font_cache_dir_add(char *dir) | ||
990 | { | ||
991 | Evas_Font_Dir *fd; | ||
992 | char *tmp, *tmp2; | ||
993 | Eina_List *fdir; | ||
994 | Evas_Font *fn; | ||
995 | |||
996 | fd = calloc(1, sizeof(Evas_Font_Dir)); | ||
997 | if (!fd) return NULL; | ||
998 | fd->lookup = eina_hash_string_superfast_new(NULL); | ||
999 | |||
1000 | eina_hash_add(font_dirs, dir, fd); | ||
1001 | |||
1002 | /* READ fonts.alias, fonts.dir and directory listing */ | ||
1003 | |||
1004 | /* fonts.dir */ | ||
1005 | tmp = evas_file_path_join(dir, "fonts.dir"); | ||
1006 | if (tmp) | ||
1007 | { | ||
1008 | FILE *f; | ||
1009 | |||
1010 | f = fopen(tmp, "rb"); | ||
1011 | if (f) | ||
1012 | { | ||
1013 | int num; | ||
1014 | char fname[4096], fdef[4096]; | ||
1015 | |||
1016 | if (fscanf(f, "%i\n", &num) != 1) goto cant_read; | ||
1017 | /* read font lines */ | ||
1018 | while (fscanf(f, "%4090s %[^\n]\n", fname, fdef) == 2) | ||
1019 | { | ||
1020 | char font_prop[14][256]; | ||
1021 | int i; | ||
1022 | |||
1023 | /* skip comments */ | ||
1024 | if ((fdef[0] == '!') || (fdef[0] == '#')) continue; | ||
1025 | /* parse font def */ | ||
1026 | num = evas_object_text_font_string_parse((char *)fdef, font_prop); | ||
1027 | if (num == 14) | ||
1028 | { | ||
1029 | fn = calloc(1, sizeof(Evas_Font)); | ||
1030 | if (fn) | ||
1031 | { | ||
1032 | fn->type = 1; | ||
1033 | for (i = 0; i < 14; i++) | ||
1034 | fn->x.prop[i] = eina_stringshare_add(font_prop[i]); | ||
1035 | tmp2 = evas_file_path_join(dir, fname); | ||
1036 | if (tmp2) | ||
1037 | { | ||
1038 | fn->path = eina_stringshare_add(tmp2); | ||
1039 | free(tmp2); | ||
1040 | } | ||
1041 | fd->fonts = eina_list_append(fd->fonts, fn); | ||
1042 | } | ||
1043 | } | ||
1044 | } | ||
1045 | cant_read: ; | ||
1046 | fclose(f); | ||
1047 | } | ||
1048 | free(tmp); | ||
1049 | } | ||
1050 | |||
1051 | /* directoy listing */ | ||
1052 | fdir = evas_file_path_list(dir, "*.ttf", 0); | ||
1053 | while (fdir) | ||
1054 | { | ||
1055 | tmp = evas_file_path_join(dir, fdir->data); | ||
1056 | if (tmp) | ||
1057 | { | ||
1058 | fn = calloc(1, sizeof(Evas_Font)); | ||
1059 | if (fn) | ||
1060 | { | ||
1061 | char *p; | ||
1062 | |||
1063 | fn->type = 0; | ||
1064 | tmp2 = alloca(strlen(fdir->data) + 1); | ||
1065 | strcpy(tmp2, fdir->data); | ||
1066 | p = strrchr(tmp2, '.'); | ||
1067 | if (p) *p = 0; | ||
1068 | fn->simple.name = eina_stringshare_add(tmp2); | ||
1069 | tmp2 = evas_file_path_join(dir, fdir->data); | ||
1070 | if (tmp2) | ||
1071 | { | ||
1072 | fn->path = eina_stringshare_add(tmp2); | ||
1073 | free(tmp2); | ||
1074 | } | ||
1075 | fd->fonts = eina_list_append(fd->fonts, fn); | ||
1076 | } | ||
1077 | free(tmp); | ||
1078 | } | ||
1079 | free(fdir->data); | ||
1080 | fdir = eina_list_remove(fdir, fdir->data); | ||
1081 | } | ||
1082 | |||
1083 | /* fonts.alias */ | ||
1084 | tmp = evas_file_path_join(dir, "fonts.alias"); | ||
1085 | if (tmp) | ||
1086 | { | ||
1087 | FILE *f; | ||
1088 | |||
1089 | f = fopen(tmp, "rb"); | ||
1090 | if (f) | ||
1091 | { | ||
1092 | char fname[4096], fdef[4096]; | ||
1093 | |||
1094 | /* read font alias lines */ | ||
1095 | while (fscanf(f, "%4090s %[^\n]\n", fname, fdef) == 2) | ||
1096 | { | ||
1097 | Evas_Font_Alias *fa; | ||
1098 | |||
1099 | /* skip comments */ | ||
1100 | if ((fname[0] == '!') || (fname[0] == '#')) continue; | ||
1101 | fa = calloc(1, sizeof(Evas_Font_Alias)); | ||
1102 | if (fa) | ||
1103 | { | ||
1104 | fa->alias = eina_stringshare_add(fname); | ||
1105 | fa->fn = object_text_font_cache_font_find_x(fd, fdef); | ||
1106 | if ((!fa->alias) || (!fa->fn)) | ||
1107 | { | ||
1108 | if (fa->alias) eina_stringshare_del(fa->alias); | ||
1109 | free(fa); | ||
1110 | } | ||
1111 | else | ||
1112 | fd->aliases = eina_list_append(fd->aliases, fa); | ||
1113 | } | ||
1114 | } | ||
1115 | fclose(f); | ||
1116 | } | ||
1117 | free(tmp); | ||
1118 | } | ||
1119 | |||
1120 | fd->dir_mod_time = evas_file_modified_time(dir); | ||
1121 | tmp = evas_file_path_join(dir, "fonts.dir"); | ||
1122 | if (tmp) | ||
1123 | { | ||
1124 | fd->fonts_dir_mod_time = evas_file_modified_time(tmp); | ||
1125 | free(tmp); | ||
1126 | } | ||
1127 | tmp = evas_file_path_join(dir, "fonts.alias"); | ||
1128 | if (tmp) | ||
1129 | { | ||
1130 | fd->fonts_alias_mod_time = evas_file_modified_time(tmp); | ||
1131 | free(tmp); | ||
1132 | } | ||
1133 | |||
1134 | return fd; | ||
1135 | } | ||
1136 | |||
1137 | static void | ||
1138 | object_text_font_cache_dir_del(char *dir __UNUSED__, Evas_Font_Dir *fd) | ||
1139 | { | ||
1140 | if (fd->lookup) eina_hash_free(fd->lookup); | ||
1141 | while (fd->fonts) | ||
1142 | { | ||
1143 | Evas_Font *fn; | ||
1144 | int i; | ||
1145 | |||
1146 | fn = fd->fonts->data; | ||
1147 | fd->fonts = eina_list_remove(fd->fonts, fn); | ||
1148 | for (i = 0; i < 14; i++) | ||
1149 | { | ||
1150 | if (fn->x.prop[i]) eina_stringshare_del(fn->x.prop[i]); | ||
1151 | } | ||
1152 | if (fn->simple.name) eina_stringshare_del(fn->simple.name); | ||
1153 | if (fn->path) eina_stringshare_del(fn->path); | ||
1154 | free(fn); | ||
1155 | } | ||
1156 | while (fd->aliases) | ||
1157 | { | ||
1158 | Evas_Font_Alias *fa; | ||
1159 | |||
1160 | fa = fd->aliases->data; | ||
1161 | fd->aliases = eina_list_remove(fd->aliases, fa); | ||
1162 | if (fa->alias) eina_stringshare_del(fa->alias); | ||
1163 | free(fa); | ||
1164 | } | ||
1165 | free(fd); | ||
1166 | } | ||
1167 | |||
1168 | static int | ||
1169 | evas_object_text_font_string_parse(char *buffer, char dest[14][256]) | ||
1170 | { | ||
1171 | char *p; | ||
1172 | int n, m, i; | ||
1173 | |||
1174 | n = 0; | ||
1175 | m = 0; | ||
1176 | p = buffer; | ||
1177 | if (p[0] != '-') return 0; | ||
1178 | i = 1; | ||
1179 | while (p[i]) | ||
1180 | { | ||
1181 | dest[n][m] = p[i]; | ||
1182 | if ((p[i] == '-') || (m == 255)) | ||
1183 | { | ||
1184 | dest[n][m] = 0; | ||
1185 | n++; | ||
1186 | m = -1; | ||
1187 | } | ||
1188 | i++; | ||
1189 | m++; | ||
1190 | if (n == 14) return n; | ||
1191 | } | ||
1192 | dest[n][m] = 0; | ||
1193 | n++; | ||
1194 | return n; | ||
1195 | } | ||
1196 | |||
1197 | EAPI void | ||
1198 | evas_font_path_clear(Evas *e) | ||
1199 | { | ||
1200 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1201 | return; | ||
1202 | MAGIC_CHECK_END(); | ||
1203 | while (e->font_path) | ||
1204 | { | ||
1205 | eina_stringshare_del(e->font_path->data); | ||
1206 | e->font_path = eina_list_remove(e->font_path, e->font_path->data); | ||
1207 | } | ||
1208 | } | ||
1209 | |||
1210 | EAPI void | ||
1211 | evas_font_path_append(Evas *e, const char *path) | ||
1212 | { | ||
1213 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1214 | return; | ||
1215 | MAGIC_CHECK_END(); | ||
1216 | |||
1217 | if (!path) return; | ||
1218 | e->font_path = eina_list_append(e->font_path, eina_stringshare_add(path)); | ||
1219 | } | ||
1220 | |||
1221 | EAPI void | ||
1222 | evas_font_path_prepend(Evas *e, const char *path) | ||
1223 | { | ||
1224 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1225 | return; | ||
1226 | MAGIC_CHECK_END(); | ||
1227 | |||
1228 | if (!path) return; | ||
1229 | e->font_path = eina_list_prepend(e->font_path, eina_stringshare_add(path)); | ||
1230 | } | ||
1231 | |||
1232 | EAPI const Eina_List * | ||
1233 | evas_font_path_list(const Evas *e) | ||
1234 | { | ||
1235 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1236 | return NULL; | ||
1237 | MAGIC_CHECK_END(); | ||
1238 | return e->font_path; | ||
1239 | } | ||
1240 | |||
1241 | static void | ||
1242 | evas_font_object_rehint(Evas_Object *obj) | ||
1243 | { | ||
1244 | if (obj->smart.smart) | ||
1245 | { | ||
1246 | EINA_INLIST_FOREACH(evas_object_smart_members_get_direct(obj), obj) | ||
1247 | evas_font_object_rehint(obj); | ||
1248 | } | ||
1249 | else | ||
1250 | { | ||
1251 | if (!strcmp(obj->type, "text")) | ||
1252 | _evas_object_text_rehint(obj); | ||
1253 | if (!strcmp(obj->type, "textblock")) | ||
1254 | _evas_object_textblock_rehint(obj); | ||
1255 | } | ||
1256 | } | ||
1257 | |||
1258 | EAPI void | ||
1259 | evas_font_hinting_set(Evas *e, Evas_Font_Hinting_Flags hinting) | ||
1260 | { | ||
1261 | Evas_Layer *lay; | ||
1262 | |||
1263 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1264 | return; | ||
1265 | MAGIC_CHECK_END(); | ||
1266 | if (e->hinting == hinting) return; | ||
1267 | e->hinting = hinting; | ||
1268 | |||
1269 | EINA_INLIST_FOREACH(e->layers, lay) | ||
1270 | { | ||
1271 | Evas_Object *obj; | ||
1272 | |||
1273 | EINA_INLIST_FOREACH(lay->objects, obj) | ||
1274 | evas_font_object_rehint(obj); | ||
1275 | } | ||
1276 | } | ||
1277 | |||
1278 | EAPI Evas_Font_Hinting_Flags | ||
1279 | evas_font_hinting_get(const Evas *e) | ||
1280 | { | ||
1281 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1282 | return EVAS_FONT_HINTING_BYTECODE; | ||
1283 | MAGIC_CHECK_END(); | ||
1284 | return e->hinting; | ||
1285 | } | ||
1286 | |||
1287 | EAPI Eina_Bool | ||
1288 | evas_font_hinting_can_hint(const Evas *e, Evas_Font_Hinting_Flags hinting) | ||
1289 | { | ||
1290 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1291 | return 0; | ||
1292 | MAGIC_CHECK_END(); | ||
1293 | if (e->engine.func->font_hinting_can_hint) | ||
1294 | return e->engine.func->font_hinting_can_hint(e->engine.data.output, | ||
1295 | hinting); | ||
1296 | return EINA_FALSE; | ||
1297 | } | ||
1298 | |||
1299 | EAPI void | ||
1300 | evas_font_cache_flush(Evas *e) | ||
1301 | { | ||
1302 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1303 | return; | ||
1304 | MAGIC_CHECK_END(); | ||
1305 | |||
1306 | e->engine.func->font_cache_flush(e->engine.data.output); | ||
1307 | } | ||
1308 | |||
1309 | EAPI void | ||
1310 | evas_font_cache_set(Evas *e, int size) | ||
1311 | { | ||
1312 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1313 | return; | ||
1314 | MAGIC_CHECK_END(); | ||
1315 | |||
1316 | if (size < 0) size = 0; | ||
1317 | e->engine.func->font_cache_set(e->engine.data.output, size); | ||
1318 | } | ||
1319 | |||
1320 | EAPI int | ||
1321 | evas_font_cache_get(const Evas *e) | ||
1322 | { | ||
1323 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1324 | return 0; | ||
1325 | MAGIC_CHECK_END(); | ||
1326 | |||
1327 | return e->engine.func->font_cache_get(e->engine.data.output); | ||
1328 | } | ||
1329 | |||
1330 | EAPI Eina_List * | ||
1331 | evas_font_available_list(const Evas *e) | ||
1332 | { | ||
1333 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1334 | return NULL; | ||
1335 | MAGIC_CHECK_END(); | ||
1336 | |||
1337 | return evas_font_dir_available_list(e); | ||
1338 | } | ||
1339 | |||
1340 | EAPI void | ||
1341 | evas_font_available_list_free(Evas *e, Eina_List *available) | ||
1342 | { | ||
1343 | MAGIC_CHECK(e, Evas, MAGIC_EVAS); | ||
1344 | return; | ||
1345 | MAGIC_CHECK_END(); | ||
1346 | |||
1347 | evas_font_dir_available_list_free(available); | ||
1348 | } | ||
1349 | |||