big patch from Samsung SAIT (Advanced research group) for async multi-frame
[framework/uifw/evas.git] / src / lib / engines / common / evas_font_main.c
1 /*
2  * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
3  */
4
5 #include "evas_common.h"
6 #include "evas_private.h"
7 FT_Library      evas_ft_lib = 0;
8 static int      initialised = 0;
9
10 EAPI void
11 evas_common_font_init(void)
12 {
13    int error;
14
15    initialised++;
16    if (initialised != 1) return;
17    error = FT_Init_FreeType(&evas_ft_lib);
18    if (error) return;
19    evas_common_font_load_init();
20 #ifdef EVAS_FRAME_QUEUING
21    evas_common_font_draw_init();
22 #endif
23 }
24
25 EAPI void
26 evas_common_font_shutdown(void)
27 {
28    int error;
29
30    if (initialised < 1) return;
31    initialised--;
32    if (initialised != 0) return;
33
34    evas_common_font_load_shutdown();
35    evas_common_font_cache_set(0);
36    evas_common_font_flush();
37
38    error = FT_Done_FreeType(evas_ft_lib);
39 #ifdef EVAS_FRAME_QUEUING
40    evas_common_font_draw_finish();
41 #endif
42    evas_ft_lib = 0;
43 }
44
45 EAPI void
46 evas_common_font_font_all_unload(void)
47 {
48    evas_common_font_all_clear();
49 }
50
51 EAPI int
52 evas_common_font_ascent_get(RGBA_Font *fn)
53 {
54    int val, dv;
55    int ret;
56    RGBA_Font_Int *fi;
57
58 //   evas_common_font_size_use(fn);
59 #if 0
60      {
61         Eina_List *l;
62         
63         EINA_LIST_FOREACH(fn->fonts, l, fi)
64           {
65              if (!fi->src->ft.face) continue;
66              if (fi->src->current_size != fi->size)
67                {
68                   FT_Activate_Size(fi->ft.size);
69                   fi->src->current_size = fi->size;
70                }
71              val = (int)fi->src->ft.face->size->metrics.ascender;
72              if (fi->src->ft.face->units_per_EM == 0)
73                return val;
74              dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
75              ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
76              printf(" ==== %p: %i\n", fi, ret);
77           }
78      }
79 #endif
80    fi = fn->fonts->data;
81    if (fi->src->current_size != fi->size)
82      {
83         FT_Activate_Size(fi->ft.size);
84         fi->src->current_size = fi->size;
85      }
86    if (!FT_IS_SCALABLE(fi->src->ft.face))
87      {
88         printf("NOT SCALABLE!\n");
89      }
90    val = (int)fi->src->ft.face->size->metrics.ascender;
91    return val >> 6;
92 //   printf("%i | %i\n", val, val >> 6);
93 //   if (fi->src->ft.face->units_per_EM == 0)
94 //     return val;
95 //   dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
96 //   ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
97 //   return ret;
98 }
99
100 EAPI int
101 evas_common_font_descent_get(RGBA_Font *fn)
102 {
103    int val, dv;
104    int ret;
105    RGBA_Font_Int *fi;
106
107 //   evas_common_font_size_use(fn);
108    fi = fn->fonts->data;
109    if (fi->src->current_size != fi->size)
110      {
111         FT_Activate_Size(fi->ft.size);
112         fi->src->current_size = fi->size;
113      }
114    val = -(int)fi->src->ft.face->size->metrics.descender;
115    return val >> 6;
116 //   if (fi->src->ft.face->units_per_EM == 0)
117 //     return val;
118 //   dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
119 //   ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
120 //   return ret;
121 }
122
123 EAPI int
124 evas_common_font_max_ascent_get(RGBA_Font *fn)
125 {
126    int val, dv;
127    int ret;
128    RGBA_Font_Int *fi;
129
130 //   evas_common_font_size_use(fn);
131    fi = fn->fonts->data;
132    if (fi->src->current_size != fi->size)
133      {
134         FT_Activate_Size(fi->ft.size);
135         fi->src->current_size = fi->size;
136      }
137    val = (int)fi->src->ft.face->bbox.yMax;
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
145 EAPI int
146 evas_common_font_max_descent_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    if (fi->src->current_size != fi->size)
155      {
156         FT_Activate_Size(fi->ft.size);
157         fi->src->current_size = fi->size;
158      }
159    val = -(int)fi->src->ft.face->bbox.yMin;
160    if (fi->src->ft.face->units_per_EM == 0)
161      return val;
162    dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
163    ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
164    return ret;
165 }
166
167 EAPI int
168 evas_common_font_get_line_advance(RGBA_Font *fn)
169 {
170    int val, dv;
171    int ret;
172    RGBA_Font_Int *fi;
173
174 //   evas_common_font_size_use(fn);
175    fi = fn->fonts->data;
176    if (fi->src->current_size != fi->size)
177      {
178         FT_Activate_Size(fi->ft.size);
179         fi->src->current_size = fi->size;
180      }
181    val = (int)fi->src->ft.face->size->metrics.height;
182    if (fi->src->ft.face->units_per_EM == 0)
183      return val;
184    return val >> 6;
185 //   dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
186 //   ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
187 //   return ret;
188 }
189
190 EAPI int
191 evas_common_font_utf8_get_next(const unsigned char *buf, int *iindex)
192 {
193    /* Reads UTF8 bytes from @buf, starting at *@index and returns
194     * the decoded code point at iindex offset, and advances iindex
195     * to the next code point after this.
196     *
197     * Returns 0 to indicate there is no next char
198     */
199    int index = *iindex, len, r;
200    unsigned char d, d2, d3, d4;
201
202    /* if this char is the null terminator, exit */
203    if (!buf[index])
204      return 0;
205      
206    d = buf[index++];
207
208    while (buf[index] && ((buf[index] & 0xc0) == 0x80))
209      index++;
210    len = index - *iindex;
211
212    if (len == 1)
213       r = d;
214    else if (len == 2)
215      {
216         /* 2 bytes */
217         d2 = buf[*iindex + 1];
218         r = d & 0x1f; /* copy lower 5 */
219         r <<= 6;
220         r |= (d2 & 0x3f); /* copy lower 6 */
221      }
222    else if (len == 3)
223      {
224         /* 3 bytes */
225         d2 = buf[*iindex + 1];
226         d3 = buf[*iindex + 2];
227         r = d & 0x0f; /* copy lower 4 */
228         r <<= 6;
229         r |= (d2 & 0x3f);
230         r <<= 6;
231         r |= (d3 & 0x3f);
232      }
233    else
234      {
235         /* 4 bytes */
236         d2 = buf[*iindex + 1];
237         d3 = buf[*iindex + 2];
238         d4 = buf[*iindex + 3];
239         r = d & 0x0f; /* copy lower 4 */
240         r <<= 6;
241         r |= (d2 & 0x3f);
242         r <<= 6;
243         r |= (d3 & 0x3f);
244         r <<= 6;
245         r |= (d4 & 0x3f);
246      }
247
248    *iindex = index;
249    return r;
250 }
251
252 EAPI int
253 evas_common_font_utf8_get_prev(const unsigned char *buf, int *iindex)
254 {
255    /* Reads UTF8 bytes from @buf, starting at *@index and returns
256     * the decoded code point at iindex offset, and advances iindex
257     * to the prev code point after this.
258     *
259     * Returns 0 to indicate there is no prev char
260     */
261
262    int r;
263    int index = *iindex;
264    /* although when index == 0 there's no previous char, we still want to get
265     * the current char */
266    if (index < 0) 
267      return 0;
268
269    /* First obtain the codepoint at iindex */
270    r = evas_common_font_utf8_get_next(buf, &index);
271
272    /* Next advance iindex to previous codepoint */
273    index = *iindex;
274    index--;
275    while ((index > 0) && ((buf[index] & 0xc0) == 0x80))
276      index--;
277
278    *iindex = index;
279    return r;
280 }
281
282 EAPI int
283 evas_common_font_utf8_get_last(const unsigned char *buf, int buflen)
284 {
285    /* jumps to the nul byte at the buffer end and decodes backwards and
286     * returns the offset index byte in the buffer where the last character
287     * in the buffer begins.
288     *
289     * Returns -1 to indicate an error
290     */
291    int index;
292    unsigned char d;
293
294    if (buflen < 1) return 0;
295    index = buflen - 1;
296    d = buf[index];
297    if (!(d & 0x80))
298      return index;
299    else
300      {
301         while (index > 0)
302           {
303              index--;
304              d = buf[index];
305              if ((d & 0xc0) != 0x80)
306                return index;
307           }
308      }
309    return 0;
310 }
311
312 EAPI int
313 evas_common_font_utf8_get_len(const unsigned char *buf)
314 {
315    /* returns the number of utf8 characters (not bytes) in the string */
316    int index = 0, len = 0;
317
318    while (buf[index])
319      {
320         if ((buf[index] & 0xc0) != 0x80)
321           len++;
322         index++;
323      }
324    return len;
325 }