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) ;
35 if (right_bound == left_bound)
39 else if (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL)
43 items = props->text_offset + props->text_len - base_cluster;
47 items = props->info->ot[left_bound].source_cluster - base_cluster;
52 if (right_bound > (int) (props->text_offset + props->text_len))
54 items = props->text_offset + props->text_len - base_cluster;
58 items = props->info->ot[right_bound].source_cluster - base_cluster;
61 return (items > 0) ? items : 1;
65 evas_common_font_ot_load_face(void *_font)
67 RGBA_Font_Source *font = (RGBA_Font_Source *) _font;
68 /* Unload the face if by any chance it's already loaded */
69 evas_common_font_ot_unload_face(font);
70 font->hb.face = hb_ft_face_create(font->ft.face, NULL);
74 evas_common_font_ot_unload_face(void *_font)
76 RGBA_Font_Source *font = (RGBA_Font_Source *) _font;
77 if (!font->hb.face) return;
78 hb_face_destroy(font->hb.face);
82 /* Harfbuzz font functions */
83 static hb_font_funcs_t *_ft_font_funcs = NULL;
86 _evas_common_font_ot_hb_get_glyph(hb_font_t *font, hb_face_t *face,
87 const void *user_data, hb_codepoint_t unicode,
88 hb_codepoint_t variation_selector)
90 RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
91 return hb_font_funcs_get_glyph_func(_ft_font_funcs)(font, face,
92 fi->src->ft.face, unicode, variation_selector);
96 _evas_common_font_ot_hb_get_glyph_advance(hb_font_t *font, hb_face_t *face,
97 const void *user_data, hb_codepoint_t glyph,
98 hb_position_t *x_advance, hb_position_t *y_advance)
101 RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
105 fg = evas_common_font_int_cache_glyph_get(fi, glyph);
108 *x_advance = fg->glyph->advance.x >> 10;
109 *y_advance = fg->glyph->advance.y >> 10;
114 _evas_common_font_ot_hb_get_glyph_extents(hb_font_t *font, hb_face_t *face,
115 const void *user_data, hb_codepoint_t glyph, hb_glyph_extents_t *extents)
117 RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
118 hb_font_funcs_get_glyph_extents_func(_ft_font_funcs)(font, face,
119 fi->src->ft.face, glyph, extents);
123 _evas_common_font_ot_hb_get_contour_point(hb_font_t *font, hb_face_t *face,
124 const void *user_data, unsigned int point_index, hb_codepoint_t glyph,
125 hb_position_t *x, hb_position_t *y)
127 RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
128 return hb_font_funcs_get_contour_point_func(_ft_font_funcs)(font, face,
129 fi->src->ft.face, point_index, glyph, x, y);
133 _evas_common_font_ot_hb_get_kerning(hb_font_t *font, hb_face_t *face,
134 const void *user_data, hb_codepoint_t first_glyph,
135 hb_codepoint_t second_glyph)
137 RGBA_Font_Int *fi = (RGBA_Font_Int *) user_data;
141 if (evas_common_font_query_kerning(fi, first_glyph, second_glyph, &kern))
147 /* End of harfbuzz font funcs */
149 static hb_font_funcs_t *
150 _evas_common_font_ot_font_funcs_get(void)
152 static hb_font_funcs_t *font_funcs = NULL;
155 _ft_font_funcs = hb_ft_get_font_funcs();
156 font_funcs = hb_font_funcs_create();
157 hb_font_funcs_set_glyph_func(font_funcs,
158 _evas_common_font_ot_hb_get_glyph);
159 hb_font_funcs_set_glyph_advance_func(font_funcs,
160 _evas_common_font_ot_hb_get_glyph_advance);
161 hb_font_funcs_set_glyph_extents_func(font_funcs,
162 _evas_common_font_ot_hb_get_glyph_extents);
163 hb_font_funcs_set_contour_point_func(font_funcs,
164 _evas_common_font_ot_hb_get_contour_point);
165 hb_font_funcs_set_kerning_func(font_funcs,
166 _evas_common_font_ot_hb_get_kerning);
173 _evas_common_font_ot_shape(hb_buffer_t *buffer, RGBA_Font_Int *fi)
177 hb_font = hb_ft_font_create(fi->src->ft.face, NULL);
178 hb_font_set_funcs(hb_font, _evas_common_font_ot_font_funcs_get(), NULL, fi);
180 hb_shape(hb_font, fi->src->hb.face, buffer, NULL, 0);
181 hb_font_destroy(hb_font);
185 evas_common_font_ot_populate_text_props(void *_fn, const Eina_Unicode *text,
186 Evas_Text_Props *props, int len)
188 RGBA_Font *fn = (RGBA_Font *) _fn;
191 hb_glyph_position_t *positions;
192 hb_glyph_info_t *infos;
196 fi = fn->fonts->data;
197 /* Load the font needed for this script */
199 /* Skip common chars */
200 const Eina_Unicode *tmp;
203 evas_common_language_char_script_get(*tmp) == EVAS_SCRIPT_COMMON ;
206 if (!*tmp && (tmp > text)) tmp--;
207 evas_common_font_glyph_search(fn, &fi, *tmp);
209 evas_common_font_int_reload(fi);
210 if (fi->src->current_size != fi->size)
213 FT_Activate_Size(fi->ft.size);
215 fi->src->current_size = fi->size;
220 slen = eina_unicode_strlen(text);
227 buffer = hb_buffer_create(slen);
228 hb_buffer_set_unicode_funcs(buffer, evas_common_language_unicode_funcs_get());
229 hb_buffer_set_language(buffer, hb_language_from_string(
230 evas_common_language_from_locale_get()));
231 hb_buffer_set_script(buffer, props->script);
232 hb_buffer_set_direction(buffer,
233 (props->bidi.dir == EVAS_BIDI_DIRECTION_RTL) ?
234 HB_DIRECTION_RTL : HB_DIRECTION_LTR);
235 /* FIXME: add run-time conversions if needed, which is very unlikely */
236 hb_buffer_add_utf32(buffer, (const uint32_t *) text, slen, 0, slen);
238 _evas_common_font_ot_shape(buffer, fi);
240 props->len = hb_buffer_get_length(buffer);
241 props->info->ot = calloc(props->len,
242 sizeof(Evas_Font_OT_Info));
243 props->info->glyph = calloc(props->len,
244 sizeof(Evas_Font_Glyph_Info));
245 positions = hb_buffer_get_glyph_positions(buffer);
246 infos = hb_buffer_get_glyph_infos(buffer);
247 for (i = 0 ; i < props->len ; i++)
249 props->info->ot[i].source_cluster = infos[i].cluster;
250 props->info->ot[i].x_offset = positions[i].x_offset;
251 props->info->ot[i].y_offset = positions[i].y_offset;
252 props->info->glyph[i].index = infos[i].codepoint;
253 props->info->glyph[i].advance = positions[i].x_advance;
256 hb_buffer_destroy(buffer);
257 evas_common_font_int_use_trim();