2 * vim:ts=8:sw=3:sts=8:noexpandtab:cino=>5n-3f0^-2{2
5 #include "evas_common.h"
6 #include "evas_blend_private.h"
9 evas_common_font_int_cache_glyph_get(RGBA_Font_Int *fi, FT_UInt index)
15 const FT_Int32 hintflags[3] =
16 { FT_LOAD_NO_HINTING, FT_LOAD_FORCE_AUTOHINT, FT_LOAD_NO_AUTOHINT };
18 hindex = index + (fi->hinting * 500000000);
20 key[0] = ((hindex ) & 0x7f) + 1;
21 key[1] = ((hindex >> 7 ) & 0x7f) + 1;
22 key[2] = ((hindex >> 14 ) & 0x7f) + 1;
23 key[3] = ((hindex >> 21 ) & 0x7f) + 1;
24 key[4] = ((hindex >> 28 ) & 0x0f) + 1;
27 fg = evas_hash_find(fi->glyphs, key);
30 // error = FT_Load_Glyph(fi->src->ft.face, index, FT_LOAD_NO_BITMAP);
31 error = FT_Load_Glyph(fi->src->ft.face, index,
32 FT_LOAD_RENDER | hintflags[fi->hinting]);
33 if (error) return NULL;
35 fg = malloc(sizeof(struct _RGBA_Font_Glyph));
37 memset(fg, 0, (sizeof(struct _RGBA_Font_Glyph)));
39 error = FT_Get_Glyph(fi->src->ft.face->glyph, &(fg->glyph));
45 if (fg->glyph->format != FT_GLYPH_FORMAT_BITMAP)
47 error = FT_Glyph_To_Bitmap(&(fg->glyph), FT_RENDER_MODE_NORMAL, 0, 1);
50 FT_Done_Glyph(fg->glyph);
55 fg->glyph_out = (FT_BitmapGlyph)fg->glyph;
57 fi->glyphs = evas_hash_add(fi->glyphs, key, fg);
62 evas_common_font_glyph_search(RGBA_Font *fn, RGBA_Font_Int **fi_ret, int gl)
66 for (l = fn->fonts; l; l = l->next)
73 if (fi->src->charmap) /* Charmap loaded, FI/FS blank */
75 index = evas_array_hash_search(fi->src->charmap, gl);
78 evas_common_font_source_load_complete(fi->src);
79 evas_common_font_int_load_complete(fi);
81 evas_array_hash_free(fi->src->charmap);
82 fi->src->charmap = NULL;
88 else if (!fi->src->ft.face) /* Charmap not loaded, FI/FS blank */
90 if (evas_common_font_source_load_complete(fi->src))
92 #if 0 /* FIXME: disable this. this can eat a LOT of memory and in my tests with expedite at any rate shows no visible improvements */
93 index = FT_Get_Char_Index(fi->src->ft.face, gl);
100 fi->src->charmap = evas_array_hash_new();
101 charcode = FT_Get_First_Char(fi->src->ft.face, &gindex);
104 evas_array_hash_add(fi->src->charmap, charcode, gindex);
105 charcode = FT_Get_Next_Char(fi->src->ft.face, charcode, &gindex);
109 FT_Done_Face(fi->src->ft.face);
110 fi->src->ft.face = NULL;
114 evas_common_font_int_load_complete(fi);
121 else /* Charmap not loaded, FS loaded */
123 index = FT_Get_Char_Index(fi->src->ft.face, gl);
127 evas_common_font_int_load_complete(fi);
138 evas_common_font_draw(RGBA_Image *dst, RGBA_Draw_Context *dc, RGBA_Font *fn, int x, int y, const char *text)
145 int ext_x, ext_y, ext_w, ext_h;
150 FT_Face pface = NULL;
152 fi = fn->fonts->data;
154 im = dst->image.data;
155 im_w = dst->cache_entry.w;
156 im_h = dst->cache_entry.h;
158 ext_x = 0; ext_y = 0; ext_w = im_w; ext_h = im_h;
175 if ((ext_x + ext_w) > im_w)
176 ext_w = im_w - ext_x;
177 if ((ext_y + ext_h) > im_h)
178 ext_h = im_h - ext_y;
180 if (ext_w <= 0) return;
181 if (ext_h <= 0) return;
186 evas_common_font_size_use(fn);
187 use_kerning = FT_HAS_KERNING(fi->src->ft.face);
189 func = evas_common_gfx_func_composite_mask_color_span_get(dc->col.col, dst, 1, dc->render_op);
190 for (c = 0, chr = 0; text[chr];)
197 gl = evas_common_font_utf8_get_next((unsigned char *)text, &chr);
199 index = evas_common_font_glyph_search(fn, &fi, gl);
200 /* hmmm kerning means i can't sanely do my own cached metric tables! */
201 /* grrr - this means font face sharing is kinda... not an option if */
202 /* you want performance */
203 if ((use_kerning) && (prev_index) && (index) &&
204 (pface == fi->src->ft.face))
208 if (FT_Get_Kerning(fi->src->ft.face, prev_index, index,
209 ft_kerning_default, &delta) == 0)
210 pen_x += delta.x >> 6;
212 pface = fi->src->ft.face;
213 fg = evas_common_font_int_cache_glyph_get(fi, index);
216 if (dc->font_ext.func.gl_new)
218 /* extension calls */
219 fg->ext_dat = dc->font_ext.func.gl_new(dc->font_ext.data, fg);
220 fg->ext_dat_free = dc->font_ext.func.gl_free;
223 chr_x = (pen_x + (fg->glyph_out->left));
224 chr_y = (pen_y + (fg->glyph_out->top));
226 if (chr_x < (ext_x + ext_w))
231 data = fg->glyph_out->bitmap.buffer;
232 j = fg->glyph_out->bitmap.pitch;
233 w = fg->glyph_out->bitmap.width;
235 h = fg->glyph_out->bitmap.rows;
237 if ((fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays)
238 && (fg->glyph_out->bitmap.num_grays == 256)
242 if ((j > 0) && (chr_x + w > ext_x))
244 if ((fg->ext_dat) && (dc->font_ext.func.gl_draw))
247 dc->font_ext.func.gl_draw(dc->font_ext.data,
256 if ((fg->glyph_out->bitmap.num_grays == 256) &&
257 (fg->glyph_out->bitmap.pixel_mode == ft_pixel_mode_grays))
259 for (i = 0; i < h; i++)
267 dy = y - (chr_y - i - y);
269 if (((dy) % dc->sli.h) == dc->sli.y)
272 if ((dx < (ext_x + ext_w)) &&
274 (dy < (ext_y + ext_h)))
276 if (dx + w > (ext_x + ext_w))
277 in_w += (dx + w) - (ext_x + ext_w);
286 func(NULL, data + (i * j) + in_x, dc->col.col,
287 im + (dy * im_w) + dx, w - in_w);
295 DATA8 *tmpbuf = NULL, *dp, *tp, bits;
297 const DATA8 bitrepl[2] = {0x0, 0xff};
300 for (i = 0; i < h; i++)
308 dy = y - (chr_y - i - y);
310 if (((dy) % dc->sli.h) == dc->sli.y)
314 dp = data + (i * fg->glyph_out->bitmap.pitch);
315 for (bi = 0; bi < w; bi += 8)
318 if ((w - bi) < 8) end = w - bi;
320 for (bj = 0; bj < end; bj++)
322 *tp = bitrepl[(bits >> (7 - bj)) & 0x1];
327 if ((dx < (ext_x + ext_w)) &&
329 (dy < (ext_y + ext_h)))
331 if (dx + w > (ext_x + ext_w))
332 in_w += (dx + w) - (ext_x + ext_w);
341 func(NULL, tmpbuf + in_x, dc->col.col,
342 im + (dy * im_w) + dx, w - in_w);
355 pen_x += fg->glyph->advance.x >> 16;