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