move around - flatter.
[profile/ivi/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
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)
19      {
20         initialised--;
21         return;
22      }
23 }
24
25 EAPI void
26 evas_common_font_shutdown(void)
27 {
28    int error;
29
30    initialised--;
31    if (initialised != 0) return;
32
33    evas_common_font_cache_set(0);
34    evas_common_font_flush();
35
36    error = FT_Done_FreeType(evas_ft_lib);
37    evas_ft_lib = 0;
38 }
39
40 EAPI int
41 evas_common_font_ascent_get(RGBA_Font *fn)
42 {
43    int val, dv;
44    int ret;
45    RGBA_Font_Int *fi;
46
47    evas_common_font_size_use(fn);
48    fi = fn->fonts->data;
49    val = (int)fi->src->ft.face->size->metrics.ascender;
50    if (fi->src->ft.face->units_per_EM == 0)
51      return val;  
52    dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
53    ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
54    return ret;
55 }
56
57 EAPI int
58 evas_common_font_descent_get(RGBA_Font *fn)
59 {
60    int val, dv;
61    int ret;
62    RGBA_Font_Int *fi;
63
64    evas_common_font_size_use(fn);
65    fi = fn->fonts->data;
66    val = -(int)fi->src->ft.face->size->metrics.descender;
67    if (fi->src->ft.face->units_per_EM == 0)
68      return val;  
69    dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
70    ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
71    return ret;
72 }
73
74 EAPI int
75 evas_common_font_max_ascent_get(RGBA_Font *fn)
76 {
77    int val, dv;
78    int ret;
79    RGBA_Font_Int *fi;
80
81    evas_common_font_size_use(fn);
82    fi = fn->fonts->data;
83    val = (int)fi->src->ft.face->bbox.yMax;
84    if (fi->src->ft.face->units_per_EM == 0)
85      return val;  
86    dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
87    ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
88    return ret;
89 }
90
91 EAPI int
92 evas_common_font_max_descent_get(RGBA_Font *fn)
93 {
94    int val, dv;
95    int ret;
96    RGBA_Font_Int *fi;
97
98    evas_common_font_size_use(fn);
99    fi = fn->fonts->data;
100    val = -(int)fi->src->ft.face->bbox.yMin;
101    if (fi->src->ft.face->units_per_EM == 0)
102      return val;  
103    dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
104    ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
105    return ret;
106 }
107
108 EAPI int
109 evas_common_font_get_line_advance(RGBA_Font *fn)
110 {
111    int val, dv;
112    int ret;
113    RGBA_Font_Int *fi;
114
115    evas_common_font_size_use(fn);
116    fi = fn->fonts->data;
117    val = (int)fi->src->ft.face->size->metrics.height;
118    if (fi->src->ft.face->units_per_EM == 0)
119      return val;  
120    dv = (fi->src->ft.orig_upem * 2048) / fi->src->ft.face->units_per_EM;
121    ret = (val * fi->src->ft.face->size->metrics.y_scale) / (dv * dv);
122    return ret;
123 }
124
125 EAPI int
126 evas_common_font_utf8_get_next(unsigned char *buf, int *iindex)
127 {
128    /* Reads UTF8 bytes from @buf, starting at *@index and returns
129     * the decoded code point at iindex offset, and advances iindex
130     * to the next code point after this.
131     *
132     * Returns 0 to indicate there is no next char
133     */
134    int index = *iindex, len, r;
135    unsigned char d, d2, d3, d4;
136
137    d = buf[index++];
138    if (!d)
139      return 0;
140    
141    while (buf[index] && ((buf[index] & 0xc0) == 0x80))
142      index++;
143    len = index - *iindex;
144    
145    if (len == 1)
146       r = d;
147    else if (len == 2)
148      {
149         /* 2 bytes */
150         d2 = buf[*iindex + 1];
151         r = d & 0x1f; /* copy lower 5 */
152         r <<= 6;
153         r |= (d2 & 0x3f); /* copy lower 6 */
154      }
155    else if (len == 3)
156      {
157         /* 3 bytes */
158         d2 = buf[*iindex + 1];
159         d3 = buf[*iindex + 2];
160         r = d & 0x0f; /* copy lower 4 */
161         r <<= 6;
162         r |= (d2 & 0x3f);
163         r <<= 6;
164         r |= (d3 & 0x3f);
165      }
166    else
167      {
168         /* 4 bytes */
169         d2 = buf[*iindex + 1];
170         d3 = buf[*iindex + 2];
171         d4 = buf[*iindex + 3];
172         r = d & 0x0f; /* copy lower 4 */
173         r <<= 6;
174         r |= (d2 & 0x3f);
175         r <<= 6;
176         r |= (d3 & 0x3f);
177         r <<= 6;
178         r |= (d4 & 0x3f);
179      }
180    
181    *iindex = index;
182    return r;
183 }
184
185 EAPI int
186 evas_common_font_utf8_get_prev(unsigned char *buf, int *iindex)
187 {
188    /* Reads UTF8 bytes from @buf, starting at *@index and returns
189     * the decoded code point at iindex offset, and advances iindex
190     * to the prev code point after this.
191     *
192     * Returns 0 to indicate there is no prev char
193     */
194    int index = *iindex, len, r;
195    unsigned char d, d2, d3, d4;
196
197    if (index <= 0)
198      return 0;
199    d = buf[index--];
200    
201    while ((index > 0) && ((buf[index] & 0xc0) == 0x80))
202      index--;
203    len = *iindex - index;
204    
205    if (len == 1)
206       r = d;
207    else if (len == 2)
208      {
209         /* 2 bytes */
210         d2 = buf[index + 1];
211         r = d & 0x1f; /* copy lower 5 */
212         r <<= 6;
213         r |= (d2 & 0x3f); /* copy lower 6 */
214      }
215    else if (len == 3)
216      {
217         /* 3 bytes */
218         d2 = buf[index + 1];
219         d3 = buf[index + 2];
220         r = d & 0x0f; /* copy lower 4 */
221         r <<= 6;
222         r |= (d2 & 0x3f);
223         r <<= 6;
224         r |= (d3 & 0x3f);
225      }
226    else
227      {
228         /* 4 bytes */
229         d2 = buf[index + 1];
230         d3 = buf[index + 2];
231         d4 = buf[index + 3];
232         r = d & 0x0f; /* copy lower 4 */
233         r <<= 6;
234         r |= (d2 & 0x3f);
235         r <<= 6;
236         r |= (d3 & 0x3f);
237         r <<= 6;
238         r |= (d4 & 0x3f);
239      }
240    
241    *iindex = index;
242    return r;
243 }
244
245 EAPI int
246 evas_common_font_utf8_get_last(unsigned char *buf, int buflen)
247 {
248    /* jumps to the nul byte at the buffer end and decodes backwards and
249     * returns the offset index byte in the buffer where the last character
250     * in the buffer begins.
251     *
252     * Returns -1 to indicate an error
253     */
254    int index;
255    unsigned char d;
256
257    if (buflen < 1) return 0;
258    index = buflen - 1;
259    d = buf[index];
260    if (!(d & 0x80))
261      return index;
262    else
263      {
264         while (index > 0)
265           {
266              index--;
267              d = buf[index];
268              if ((d & 0xc0) != 0x80)
269                return index;
270           }
271      }
272    return 0;
273 }