aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/libraries/evas/src/lib/engines/common/evas_font_main.c
diff options
context:
space:
mode:
Diffstat (limited to 'libraries/evas/src/lib/engines/common/evas_font_main.c')
-rw-r--r--libraries/evas/src/lib/engines/common/evas_font_main.c545
1 files changed, 0 insertions, 545 deletions
diff --git a/libraries/evas/src/lib/engines/common/evas_font_main.c b/libraries/evas/src/lib/engines/common/evas_font_main.c
deleted file mode 100644
index 7b3dabe..0000000
--- a/libraries/evas/src/lib/engines/common/evas_font_main.c
+++ /dev/null
@@ -1,545 +0,0 @@
1#include "evas_common.h"
2#include "evas_private.h"
3
4#include "evas_font_private.h"
5
6#include FT_OUTLINE_H
7
8FT_Library evas_ft_lib = 0;
9static int initialised = 0;
10
11LK(lock_font_draw); // for freetype2 API calls
12LK(lock_bidi); // for evas bidi internal usage.
13LK(lock_ot); // for evas bidi internal usage.
14
15EAPI void
16evas_common_font_init(void)
17{
18 int error;
19 const char *s;
20
21 initialised++;
22 if (initialised != 1) return;
23 error = FT_Init_FreeType(&evas_ft_lib);
24 if (error) return;
25 evas_common_font_load_init();
26 evas_common_font_draw_init();
27 s = getenv("EVAS_FONT_DPI");
28 if (s)
29 {
30 int dpi = atoi(s);
31
32 if (dpi > 0) evas_common_font_dpi_set(dpi);
33 }
34 LKI(lock_font_draw);
35 LKI(lock_bidi);
36 LKI(lock_ot);
37}
38
39EAPI void
40evas_common_font_shutdown(void)
41{
42 if (initialised < 1) return;
43 initialised--;
44 if (initialised != 0) return;
45
46 LKD(lock_font_draw);
47 LKD(lock_bidi);
48 LKD(lock_ot);
49
50 evas_common_font_load_shutdown();
51 evas_common_font_cache_set(0);
52 evas_common_font_flush();
53
54 FT_Done_FreeType(evas_ft_lib);
55#ifdef EVAS_FRAME_QUEUING
56 evas_common_font_draw_finish();
57#endif
58 evas_ft_lib = 0;
59}
60
61EAPI void
62evas_common_font_font_all_unload(void)
63{
64 evas_common_font_all_clear();
65}
66
67EAPI int
68evas_common_font_ascent_get(RGBA_Font *fn)
69{
70 int val;
71 RGBA_Font_Int *fi;
72
73// evas_common_font_size_use(fn);
74#if 0
75 {
76 Eina_List *l;
77
78 EINA_LIST_FOREACH(fn->fonts, l, fi)
79 {
80 if (!fi->src->ft.face) continue;
81 if (fi->src->current_size != fi->size)
82 {
83 FTLOCK();
84 FT_Activate_Size(fi->ft.size);
85 FTUNLOCK();
86 fi->src->current_size = fi->size;
87 }
88 val = (int)fi->src->ft.face->size->metrics.ascender;
89 if (fi->src->ft.face->units_per_EM == 0)
90 return val;
91 dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
92 ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
93 printf(" ==== %p: %i\n", fi, ret);
94 }
95 }
96#endif
97 fi = fn->fonts->data;
98 evas_common_font_int_reload(fi);
99 if (fi->src->current_size != fi->size)
100 {
101 FTLOCK();
102 FT_Activate_Size(fi->ft.size);
103 FTUNLOCK();
104 fi->src->current_size = fi->size;
105 }
106 if (!FT_IS_SCALABLE(fi->src->ft.face))
107 {
108 WRN("NOT SCALABLE!");
109 }
110 val = (int)fi->src->ft.face->size->metrics.ascender;
111 return val >> 6;
112// printf("%i | %i\n", val, val >> 6);
113// if (fi->src->ft.face->units_per_EM == 0)
114// return val;
115// dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
116// ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
117// return ret;
118}
119
120EAPI int
121evas_common_font_descent_get(RGBA_Font *fn)
122{
123 int val;
124 RGBA_Font_Int *fi;
125
126// evas_common_font_size_use(fn);
127 fi = fn->fonts->data;
128 evas_common_font_int_reload(fi);
129 if (fi->src->current_size != fi->size)
130 {
131 FTLOCK();
132 FT_Activate_Size(fi->ft.size);
133 FTUNLOCK();
134 fi->src->current_size = fi->size;
135 }
136 val = -(int)fi->src->ft.face->size->metrics.descender;
137 return val >> 6;
138// if (fi->src->ft.face->units_per_EM == 0)
139// return val;
140// dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
141// ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
142// return ret;
143}
144
145EAPI int
146evas_common_font_max_ascent_get(RGBA_Font *fn)
147{
148 int val, dv;
149 int ret;
150 RGBA_Font_Int *fi;
151
152// evas_common_font_size_use(fn);
153 fi = fn->fonts->data;
154 evas_common_font_int_reload(fi);
155 if (fi->src->current_size != fi->size)
156 {
157 FTLOCK();
158 FT_Activate_Size(fi->ft.size);
159 FTUNLOCK();
160 fi->src->current_size = fi->size;
161 }
162 val = (int)fi->src->ft.face->bbox.yMax;
163 if (fi->src->ft.face->units_per_EM == 0)
164 return val;
165 dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
166 ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
167 return ret;
168}
169
170EAPI int
171evas_common_font_max_descent_get(RGBA_Font *fn)
172{
173 int val, dv;
174 int ret;
175 RGBA_Font_Int *fi;
176
177// evas_common_font_size_use(fn);
178 fi = fn->fonts->data;
179 evas_common_font_int_reload(fi);
180 if (fi->src->current_size != fi->size)
181 {
182 FTLOCK();
183 FT_Activate_Size(fi->ft.size);
184 FTUNLOCK();
185 fi->src->current_size = fi->size;
186 }
187 val = -(int)fi->src->ft.face->bbox.yMin;
188 if (fi->src->ft.face->units_per_EM == 0)
189 return val;
190 dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
191 ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
192 return ret;
193}
194
195EAPI int
196evas_common_font_get_line_advance(RGBA_Font *fn)
197{
198 int val;
199 RGBA_Font_Int *fi;
200
201// evas_common_font_size_use(fn);
202 fi = fn->fonts->data;
203 evas_common_font_int_reload(fi);
204 if (fi->src->current_size != fi->size)
205 {
206 FTLOCK();
207 FT_Activate_Size(fi->ft.size);
208 FTUNLOCK();
209 fi->src->current_size = fi->size;
210 }
211 val = (int)fi->src->ft.face->size->metrics.height;
212 if (fi->src->ft.face->units_per_EM == 0)
213 return val;
214 return val >> 6;
215// dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
216// ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
217// return ret;
218}
219
220/* Set of common functions that are used in a couple of places. */
221
222static void
223_fash_int2_free(Fash_Int_Map2 *fash)
224{
225 int i;
226
227 for (i = 0; i < 256; i++) if (fash->bucket[i]) free(fash->bucket[i]);
228 free(fash);
229}
230
231static void
232_fash_int_free(Fash_Int *fash)
233{
234 int i;
235
236 for (i = 0; i < 256; i++) if (fash->bucket[i]) _fash_int2_free(fash->bucket[i]);
237 free(fash);
238}
239
240static Fash_Int *
241_fash_int_new(void)
242{
243 Fash_Int *fash = calloc(1, sizeof(Fash_Int));
244 fash->freeme = _fash_int_free;
245 return fash;
246}
247
248static Fash_Item_Index_Map *
249_fash_int_find(Fash_Int *fash, int item)
250{
251 int grp, maj, min;
252
253 // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
254 grp = (item >> 16) & 0xff;
255 maj = (item >> 8) & 0xff;
256 min = item & 0xff;
257 if (!fash->bucket[grp]) return NULL;
258 if (!fash->bucket[grp]->bucket[maj]) return NULL;
259 return &(fash->bucket[grp]->bucket[maj]->item[min]);
260}
261
262static void
263_fash_int_add(Fash_Int *fash, int item, RGBA_Font_Int *fint, int idx)
264{
265 int grp, maj, min;
266
267 // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
268 grp = (item >> 16) & 0xff;
269 maj = (item >> 8) & 0xff;
270 min = item & 0xff;
271 if (!fash->bucket[grp])
272 fash->bucket[grp] = calloc(1, sizeof(Fash_Int_Map2));
273 EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]);
274 if (!fash->bucket[grp]->bucket[maj])
275 fash->bucket[grp]->bucket[maj] = calloc(1, sizeof(Fash_Int_Map));
276 EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]->bucket[maj]);
277 fash->bucket[grp]->bucket[maj]->item[min].fint = fint;
278 fash->bucket[grp]->bucket[maj]->item[min].index = idx;
279}
280
281static void
282_fash_gl2_free(Fash_Glyph_Map2 *fash)
283{
284 int i;
285
286 for (i = 0; i < 256; i++) if (fash->bucket[i]) free(fash->bucket[i]);
287 free(fash);
288}
289
290static void
291_fash_gl_free(Fash_Glyph *fash)
292{
293 int i;
294
295 for (i = 0; i < 256; i++) if (fash->bucket[i]) _fash_gl2_free(fash->bucket[i]);
296 free(fash);
297}
298
299static Fash_Glyph *
300_fash_gl_new(void)
301{
302 Fash_Glyph *fash = calloc(1, sizeof(Fash_Glyph));
303 fash->freeme = _fash_gl_free;
304 return fash;
305}
306
307static RGBA_Font_Glyph *
308_fash_gl_find(Fash_Glyph *fash, int item)
309{
310 int grp, maj, min;
311
312 // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
313 grp = (item >> 16) & 0xff;
314 maj = (item >> 8) & 0xff;
315 min = item & 0xff;
316 if (!fash->bucket[grp]) return NULL;
317 if (!fash->bucket[grp]->bucket[maj]) return NULL;
318 return fash->bucket[grp]->bucket[maj]->item[min];
319}
320
321static void
322_fash_gl_add(Fash_Glyph *fash, int item, RGBA_Font_Glyph *glyph)
323{
324 int grp, maj, min;
325
326 // 24bits for unicode - v6 up to E01EF (chrs) & 10FFFD for private use (plane 16)
327 grp = (item >> 16) & 0xff;
328 maj = (item >> 8) & 0xff;
329 min = item & 0xff;
330 if (!fash->bucket[grp])
331 fash->bucket[grp] = calloc(1, sizeof(Fash_Glyph_Map2));
332 EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]);
333 if (!fash->bucket[grp]->bucket[maj])
334 fash->bucket[grp]->bucket[maj] = calloc(1, sizeof(Fash_Glyph_Map));
335 EINA_SAFETY_ON_NULL_RETURN(fash->bucket[grp]->bucket[maj]);
336 fash->bucket[grp]->bucket[maj]->item[min] = glyph;
337}
338
339EAPI RGBA_Font_Glyph *
340evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt idx)
341{
342 RGBA_Font_Glyph *fg;
343 FT_UInt hindex;
344 FT_Error error;
345 int size;
346 const FT_Int32 hintflags[3] =
347 { FT_LOAD_NO_HINTING, FT_LOAD_FORCE_AUTOHINT, FT_LOAD_NO_AUTOHINT };
348 static FT_Matrix transform = {0x10000, 0x05000, 0x0000, 0x10000}; // about 12 degree.
349
350 evas_common_font_int_promote(fi);
351 if (fi->fash)
352 {
353 fg = _fash_gl_find(fi->fash, idx);
354 if (fg == (void *)(-1)) return NULL;
355 else if (fg) return fg;
356 }
357
358 hindex = idx + (fi->hinting * 500000000);
359
360// fg = eina_hash_find(fi->glyphs, &hindex);
361// if (fg) return fg;
362
363 evas_common_font_int_reload(fi);
364 FTLOCK();
365 error = FT_Load_Glyph(fi->src->ft.face, idx,
366 FT_LOAD_DEFAULT | FT_LOAD_NO_BITMAP |
367 hintflags[fi->hinting]);
368 FTUNLOCK();
369 if (error)
370 {
371 if (!fi->fash) fi->fash = _fash_gl_new();
372 if (fi->fash) _fash_gl_add(fi->fash, idx, (void *)(-1));
373 return NULL;
374 }
375
376 /* Transform the outline of Glyph according to runtime_rend. */
377 if (fi->runtime_rend & FONT_REND_SLANT)
378 FT_Outline_Transform(&fi->src->ft.face->glyph->outline, &transform);
379 /* Embolden the outline of Glyph according to rundtime_rend. */
380 if (fi->runtime_rend & FONT_REND_WEIGHT)
381 FT_Outline_Embolden(&fi->src->ft.face->glyph->outline,
382 (fi->src->ft.face->size->metrics.x_ppem * 5 * 64) / 100);
383
384 fg = malloc(sizeof(struct _RGBA_Font_Glyph));
385 if (!fg) return NULL;
386 memset(fg, 0, (sizeof(struct _RGBA_Font_Glyph)));
387
388 FTLOCK();
389 error = FT_Get_Glyph(fi->src->ft.face->glyph, &(fg->glyph));
390 FTUNLOCK();
391 if (error)
392 {
393 free(fg);
394 if (!fi->fash) fi->fash = _fash_gl_new();
395 if (fi->fash) _fash_gl_add(fi->fash, idx, (void *)(-1));
396 return NULL;
397 }
398
399 FTLOCK();
400 error = FT_Glyph_To_Bitmap(&(fg->glyph), FT_RENDER_MODE_NORMAL, 0, 1);
401 if (error)
402 {
403 FT_Done_Glyph(fg->glyph);
404 FTUNLOCK();
405 free(fg);
406 if (!fi->fash) fi->fash = _fash_gl_new();
407 if (fi->fash) _fash_gl_add(fi->fash, idx, (void *)(-1));
408 return NULL;
409 }
410 FTUNLOCK();
411
412 fg->glyph_out = (FT_BitmapGlyph)fg->glyph;
413 fg->index = hindex;
414 fg->fi = fi;
415
416 if (!fi->fash) fi->fash = _fash_gl_new();
417 if (fi->fash) _fash_gl_add(fi->fash, idx, fg);
418 /* This '+ 200' is just an estimation of how much memory freetype will use
419 * on it's size. This value is not really used anywhere in code - it's
420 * only for statistics. */
421 size = sizeof(RGBA_Font_Glyph) + sizeof(Eina_List) +
422 (fg->glyph_out->bitmap.width * fg->glyph_out->bitmap.rows) + 200;
423 fi->usage += size;
424 if (fi->inuse) evas_common_font_int_use_increase(size);
425
426// eina_hash_direct_add(fi->glyphs, &fg->index, fg);
427 return fg;
428}
429
430typedef struct _Font_Char_Index Font_Char_Index;
431struct _Font_Char_Index
432{
433 FT_UInt index;
434 Eina_Unicode gl;
435};
436
437EAPI FT_UInt
438evas_common_get_char_index(RGBA_Font_Int* fi, Eina_Unicode gl)
439{
440 Font_Char_Index result;
441 //FT_UInt ret;
442
443#ifdef HAVE_PTHREAD
444/// pthread_mutex_lock(&fi->ft_mutex);
445#endif
446
447// result = eina_hash_find(fi->indexes, &gl);
448// if (result) goto on_correct;
449//
450// result = malloc(sizeof (Font_Char_Index));
451// if (!result)
452// {
453//#ifdef HAVE_PTHREAD
454// pthread_mutex_unlock(&fi->ft_mutex);
455//#endif
456// return FT_Get_Char_Index(fi->src->ft.face, gl);
457// }
458
459 evas_common_font_int_reload(fi);
460 FTLOCK();
461 result.index = FT_Get_Char_Index(fi->src->ft.face, gl);
462 FTUNLOCK();
463 result.gl = gl;
464
465// eina_hash_direct_add(fi->indexes, &result->gl, result);
466//
467// on_correct:
468#ifdef HAVE_PTHREAD
469// pthread_mutex_unlock(&fi->ft_mutex);
470#endif
471 return result.index;
472}
473
474EAPI int
475evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, Eina_Unicode gl)
476{
477 Eina_List *l;
478
479 if (fn->fash)
480 {
481 Fash_Item_Index_Map *fm = _fash_int_find(fn->fash, gl);
482 if (fm)
483 {
484 if (fm->fint)
485 {
486 *fi_ret = fm->fint;
487 return fm->index;
488 }
489 else if (fm->index == -1) return 0;
490 }
491 }
492
493 for (l = fn->fonts; l; l = l->next)
494 {
495 RGBA_Font_Int *fi;
496 int idx;
497
498 fi = l->data;
499
500#if 0 /* FIXME: charmap user is disabled and use a deprecated data type. */
501/*
502 if (fi->src->charmap) // Charmap loaded, FI/FS blank
503 {
504 idx = evas_array_hash_search(fi->src->charmap, gl);
505 if (idx != 0)
506 {
507 evas_common_font_source_load_complete(fi->src);
508 evas_common_font_int_load_complete(fi);
509
510 evas_array_hash_free(fi->src->charmap);
511 fi->src->charmap = NULL;
512
513 *fi_ret = fi;
514 return idx;
515 }
516 }
517 else
518*/
519#endif
520 if (!fi->src->ft.face) /* Charmap not loaded, FI/FS blank */
521 {
522 evas_common_font_int_reload(fi);
523 }
524 if (fi->src->ft.face)
525 {
526 idx = evas_common_get_char_index(fi, gl);
527 if (idx != 0)
528 {
529 if (!fi->ft.size)
530 evas_common_font_int_load_complete(fi);
531 if (!fn->fash) fn->fash = _fash_int_new();
532 if (fn->fash) _fash_int_add(fn->fash, gl, fi, idx);
533 *fi_ret = fi;
534 return idx;
535 }
536 else
537 {
538 if (!fn->fash) fn->fash = _fash_int_new();
539 if (fn->fash) _fash_int_add(fn->fash, gl, NULL, -1);
540 }
541 }
542 }
543 *fi_ret = NULL;
544 return 0;
545}