1 #include "evas_font_ot.h"
8 #include "evas_common.h"
11 #include "evas_font_private.h"
14 /* FIXME: doc. returns #items */
16 evas_common_font_ot_cluster_size_get(const Evas_Text_Props *props, size_t char_index)
20 int left_bound, right_bound;
21 size_t base_cluster = EVAS_FONT_OT_POS_GET(props->info->ot[char_index]);
22 for (i = (int) char_index ;
23 (i >= (int) props->start) &&
24 (EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ;
28 for (i = (int) char_index + 1;
29 (i < (int) (props->start + props->len)) &&
30 (EVAS_FONT_OT_POS_GET(props->info->ot[i]) == base_cluster) ;
36 if (right_bound >= (int) (props->start + props->len))
37 right_bound = props->start + props->len - 1;
39 if (right_bound == left_bound)
43 else if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
47 items = props->start + props->len -
48 props->info->ot[left_bound + 1].source_cluster;
52 items = props->info->ot[left_bound].source_cluster -
53 props->info->ot[left_bound + 1].source_cluster;
58 if (right_bound == (int) (props->start + props->len))
60 items = props->start + props->len -
61 props->info->ot[right_bound - 1].source_cluster;
65 items = props->info->ot[right_bound].source_cluster -
66 props->info->ot[right_bound - 1].source_cluster;
69 return (items > 0) ? items : 1;
73 evas_common_font_ot_load_face(void *_font)
75 RGBA_Font_Source *font = (RGBA_Font_Source *) _font;
76 /* Unload the face if by any chance it's already loaded */
77 evas_common_font_ot_unload_face(font);
78 font->hb.face = hb_ft_face_create(font->ft.face, NULL);
82 evas_common_font_ot_unload_face(void *_font)
84 RGBA_Font_Source *font = (RGBA_Font_Source *) _font;
85 if (!font->hb.face) return;
86 hb_face_destroy(font->hb.face);
90 /* Harfbuzz font functions */
91 static hb_font_funcs_t *_ft_font_funcs = NULL;
94 _evas_common_font_ot_hb_get_glyph(hb_font_t *font, hb_face_t *face,
95 const void *user_data, hb_codepoint_t unicode,
96 hb_codepoint_t variation_selector)
98 RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
99 return hb_font_funcs_get_glyph_func(_ft_font_funcs)(font, face,
100 fi->src->ft.face, unicode, variation_selector);
104 _evas_common_font_ot_hb_get_glyph_advance(hb_font_t *font, hb_face_t *face,
105 const void *user_data, hb_codepoint_t glyph,
106 hb_position_t *x_advance, hb_position_t *y_advance)
109 RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
113 fg = evas_common_font_int_cache_glyph_get(fi, glyph);
116 *x_advance = fg->glyph->advance.x >> 10;
117 *y_advance = fg->glyph->advance.y >> 10;
122 _evas_common_font_ot_hb_get_glyph_extents(hb_font_t *font, hb_face_t *face,
123 const void *user_data, hb_codepoint_t glyph, hb_glyph_extents_t *extents)
125 RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
126 hb_font_funcs_get_glyph_extents_func(_ft_font_funcs)(font, face,
127 fi->src->ft.face, glyph, extents);
131 _evas_common_font_ot_hb_get_contour_point(hb_font_t *font, hb_face_t *face,
132 const void *user_data, unsigned int point_index, hb_codepoint_t glyph,
133 hb_position_t *x, hb_position_t *y)
135 RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
136 return hb_font_funcs_get_contour_point_func(_ft_font_funcs)(font, face,
137 fi->src->ft.face, point_index, glyph, x, y);
141 _evas_common_font_ot_hb_get_kerning(hb_font_t *font, hb_face_t *face,
142 const void *user_data, hb_codepoint_t first_glyph,
143 hb_codepoint_t second_glyph)
145 RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
149 if (evas_common_font_query_kerning(fi, first_glyph, second_glyph, &kern))
155 /* End of harfbuzz font funcs */
157 static hb_font_funcs_t *
158 _evas_common_font_ot_font_funcs_get(void)
160 static hb_font_funcs_t *font_funcs = NULL;
163 _ft_font_funcs = hb_ft_get_font_funcs();
164 font_funcs = hb_font_funcs_create();
165 hb_font_funcs_set_glyph_func(font_funcs,
166 _evas_common_font_ot_hb_get_glyph);
167 hb_font_funcs_set_glyph_advance_func(font_funcs,
168 _evas_common_font_ot_hb_get_glyph_advance);
169 hb_font_funcs_set_glyph_extents_func(font_funcs,
170 _evas_common_font_ot_hb_get_glyph_extents);
171 hb_font_funcs_set_contour_point_func(font_funcs,
172 _evas_common_font_ot_hb_get_contour_point);
173 hb_font_funcs_set_kerning_func(font_funcs,
174 _evas_common_font_ot_hb_get_kerning);
181 _evas_common_font_ot_shape(hb_buffer_t *buffer, RGBA_Font_Int *fi)
185 hb_font = hb_ft_font_create(fi->src->ft.face, NULL);
186 hb_font_set_funcs(hb_font, _evas_common_font_ot_font_funcs_get(), NULL, fi);
188 hb_shape(hb_font, fi->src->hb.face, buffer, NULL, 0);
189 hb_font_destroy(hb_font);
193 evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
194 Evas_Text_Props *props, int len)
196 RGBA_Font *fn = (RGBA_Font *) _fn;
199 hb_glyph_position_t *positions;
200 hb_glyph_info_t *infos;
204 fi = fn->fonts->data;
205 /* Load the font needed for this script */
207 /* Skip common chars */
208 const Eina_Unicode *tmp;
211 evas_common_language_char_script_get(*tmp) == EVAS_SCRIPT_COMMON ;
214 if (!*tmp && (tmp > text)) tmp--;
215 evas_common_font_glyph_search(fn, &fi, *tmp);
217 evas_common_font_int_reload(fi);
218 if (fi->src->current_size != fi->size)
221 FT_Activate_Size(fi->ft.size);
223 fi->src->current_size = fi->size;
228 slen = eina_unicode_strlen(text);
235 buffer = hb_buffer_create(slen);
236 hb_buffer_set_unicode_funcs(buffer, evas_common_language_unicode_funcs_get());
237 hb_buffer_set_language(buffer, hb_language_from_string(
238 evas_common_language_from_locale_get()));
239 hb_buffer_set_script(buffer, props->script);
240 hb_buffer_set_direction(buffer,
241 (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ?
242 HB_DIRECTION_RTL : HB_DIRECTION_LTR);
243 /* FIXME: add run-time conversions if needed, which is very unlikely */
244 hb_buffer_add_utf32(buffer, (const uint32_t *) text, slen, 0, slen);
246 _evas_common_font_ot_shape(buffer, fi);
248 props->len = hb_buffer_get_length(buffer);
249 props->info->ot = calloc(props->len,
250 sizeof(Evas_Font_OT_Info));
251 props->info->glyph = calloc(props->len,
252 sizeof(Evas_Font_Glyph_Info));
253 positions = hb_buffer_get_glyph_positions(buffer);
254 infos = hb_buffer_get_glyph_infos(buffer);
255 for (i = 0 ; i < props->len ; i++)
257 props->info->ot[i].source_cluster = infos[i].cluster;
258 props->info->ot[i].x_offset = positions[i].x_offset;
259 props->info->ot[i].y_offset = positions[i].y_offset;
260 props->info->glyph[i].index = infos[i].codepoint;
261 props->info->glyph[i].advance = positions[i].x_advance;
264 hb_buffer_destroy(buffer);
265 evas_common_font_int_use_trim();