From 29f5166856a1c57c69d8a9658a2f8929ee84197f Mon Sep 17 00:00:00 2001 From: Tor Andersson Date: Thu, 11 Feb 2016 13:47:44 +0100 Subject: gl: Use fz_font instead of freetype directly. --- platform/gl/gl-font.c | 145 ++++++++++++++++---------------------------------- 1 file changed, 46 insertions(+), 99 deletions(-) diff --git a/platform/gl/gl-font.c b/platform/gl/gl-font.c index 80d0d27e..94076eae 100644 --- a/platform/gl/gl-font.c +++ b/platform/gl/gl-font.c @@ -14,10 +14,6 @@ #include "gl-app.h" -#include -#include FT_FREETYPE_H -#include FT_ADVANCES_H - #define PADDING 1 /* set to 0 to save some space but disallow arbitrary transforms */ #define MAXGLYPHS 4093 /* prime number for hash table goodness */ @@ -27,17 +23,16 @@ struct key { - FT_Face face; + fz_font *font; short gid; - short subx; - short suby; + unsigned char subx; + unsigned char suby; }; struct glyph { char lsb, top, w, h; short s, t; - float advance; }; struct table @@ -46,7 +41,6 @@ struct table struct glyph glyph; }; -static FT_Library g_freetype_lib = NULL; static struct table g_table[MAXGLYPHS]; static int g_table_load = 0; static unsigned int g_cache_tex = 0; @@ -56,8 +50,8 @@ static int g_cache_row_y = 0; static int g_cache_row_x = 0; static int g_cache_row_h = 0; -static FT_Face g_font = NULL; -static FT_Face g_fallback_font = NULL; +static fz_font *g_font = NULL; +static float g_font_size = 16; static void clear_font_cache(void) { @@ -79,15 +73,8 @@ static void clear_font_cache(void) void ui_init_fonts(fz_context *ctx, float pixelsize) { - int fontsize = pixelsize * 64; unsigned char *data; unsigned int size; - int code; - int index; - - code = FT_Init_FreeType(&g_freetype_lib); - if (code) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot initialize freetype"); glGenTextures(1, &g_cache_tex); glBindTexture(GL_TEXTURE_2D, g_cache_tex); @@ -100,27 +87,14 @@ void ui_init_fonts(fz_context *ctx, float pixelsize) clear_font_cache(); data = fz_lookup_base14_font(ctx, "Times-Roman", &size); - code = FT_New_Memory_Face(g_freetype_lib, data, size, 0, &g_font); - if (code) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load ui font"); - - data = fz_lookup_cjk_font(ctx, 0, 0, 0, &size, &index); - code = FT_New_Memory_Face(g_freetype_lib, data, size, 0, &g_fallback_font); - if (code) - fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load ui fallback font"); - - FT_Select_Charmap(g_font, ft_encoding_unicode); - FT_Select_Charmap(g_fallback_font, ft_encoding_unicode); - - FT_Set_Char_Size(g_font, fontsize, fontsize, 72, 72); - FT_Set_Char_Size(g_fallback_font, fontsize, fontsize, 72, 72); + g_font = fz_new_font_from_memory(ctx, "Times-Roman", data, size, 0, 0); + g_font_size = pixelsize; } void ui_finish_fonts(fz_context *ctx) { clear_font_cache(); - FT_Done_Face(g_font); - FT_Done_Face(g_fallback_font); + fz_drop_font(ctx, g_font); } static unsigned int hashfunc(struct key *key) @@ -138,7 +112,7 @@ static unsigned int lookup_table(struct key *key) unsigned int pos = hashfunc(key) % MAXGLYPHS; while (1) { - if (!g_table[pos].key.face) /* empty slot */ + if (!g_table[pos].key.font) /* empty slot */ return pos; if (!memcmp(key, &g_table[pos].key, sizeof(struct key))) /* matching slot */ return pos; @@ -146,26 +120,35 @@ static unsigned int lookup_table(struct key *key) } } -static struct glyph *lookup_glyph(FT_Face face, int gid, int subx, int suby) +static struct glyph *lookup_glyph(fz_font *font, int gid, float *xp, float *yp) { - FT_Vector subv; + fz_matrix trm, subpix_trm; + unsigned char subx, suby; + fz_pixmap *pixmap; struct key key; unsigned int pos; - int code; int w, h; + /* match fitz's glyph cache quantization */ + fz_scale(&trm, g_font_size, -g_font_size); + trm.e = *xp; + trm.f = *yp; + fz_subpixel_adjust(ctx, &trm, &subpix_trm, &subx, &suby); + *xp = trm.e; + *yp = trm.f; + /* * Look it up in the table */ memset(&key, 0, sizeof key); - key.face = face; + key.font = font; key.gid = gid; key.subx = subx; key.suby = suby; pos = lookup_table(&key); - if (g_table[pos].key.face) + if (g_table[pos].key.font) return &g_table[pos].glyph; /* @@ -174,21 +157,9 @@ static struct glyph *lookup_glyph(FT_Face face, int gid, int subx, int suby) glEnd(); - subv.x = subx; - subv.y = suby; - - FT_Set_Transform(face, NULL, &subv); - - code = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING); - if (code < 0) - return NULL; - - code = FT_Render_Glyph(face->glyph, FT_RENDER_MODE_NORMAL); - if (code < 0) - return NULL; - - w = face->glyph->bitmap.width; - h = face->glyph->bitmap.rows; + pixmap = fz_render_glyph_pixmap(ctx, font, gid, &subpix_trm, NULL, NULL); + w = pixmap->w; + h = pixmap->h; /* * Find an empty slot in the texture @@ -222,21 +193,22 @@ static struct glyph *lookup_glyph(FT_Face face, int gid, int subx, int suby) */ memcpy(&g_table[pos].key, &key, sizeof(struct key)); - g_table[pos].glyph.w = face->glyph->bitmap.width; - g_table[pos].glyph.h = face->glyph->bitmap.rows; - g_table[pos].glyph.lsb = face->glyph->bitmap_left; - g_table[pos].glyph.top = face->glyph->bitmap_top; + g_table[pos].glyph.w = pixmap->w; + g_table[pos].glyph.h = pixmap->h; + g_table[pos].glyph.lsb = pixmap->x; + g_table[pos].glyph.top = -pixmap->y; g_table[pos].glyph.s = g_cache_row_x; g_table[pos].glyph.t = g_cache_row_y; - g_table[pos].glyph.advance = face->glyph->advance.x / 64.0; g_table_load ++; glPixelStorei(GL_UNPACK_ALIGNMENT, 1); - glPixelStorei(GL_UNPACK_ROW_LENGTH, face->glyph->bitmap.pitch); + glPixelStorei(GL_UNPACK_ROW_LENGTH, pixmap->w); glTexSubImage2D(GL_TEXTURE_2D, 0, g_cache_row_x, g_cache_row_y, w, h, - GL_ALPHA, GL_UNSIGNED_BYTE, face->glyph->bitmap.buffer); + GL_ALPHA, GL_UNSIGNED_BYTE, pixmap->samples); glPixelStorei(GL_UNPACK_ROW_LENGTH, 0); + fz_drop_pixmap(ctx, pixmap); + glBegin(GL_QUADS); g_cache_row_x += w + PADDING; @@ -246,67 +218,42 @@ static struct glyph *lookup_glyph(FT_Face face, int gid, int subx, int suby) return &g_table[pos].glyph; } -static float ui_draw_glyph(FT_Face face, int gid, float x, float y) +static float ui_draw_glyph(fz_font *font, int gid, float x, float y) { struct glyph *glyph; float s0, t0, s1, t1, xc, yc; - int subx = (x - floor(x)) * XPRECISION; - int suby = (y - floor(y)) * YPRECISION; - subx = (subx * 64) / XPRECISION; - suby = (suby * 64) / YPRECISION; - - glyph = lookup_glyph(face, gid, subx, suby); + glyph = lookup_glyph(font, gid, &x, &y); if (!glyph) - return 0.0; + return 0; s0 = (float) glyph->s / g_cache_w; t0 = (float) glyph->t / g_cache_h; s1 = (float) (glyph->s + glyph->w) / g_cache_w; t1 = (float) (glyph->t + glyph->h) / g_cache_h; - xc = floor(x) + glyph->lsb; - yc = floor(y) - glyph->top + glyph->h; + xc = floorf(x) + glyph->lsb; + yc = floorf(y) - glyph->top + glyph->h; glTexCoord2f(s0, t0); glVertex2f(xc, yc - glyph->h); glTexCoord2f(s1, t0); glVertex2f(xc + glyph->w, yc - glyph->h); glTexCoord2f(s1, t1); glVertex2f(xc + glyph->w, yc); glTexCoord2f(s0, t1); glVertex2f(xc, yc); - return glyph->advance; + return fz_advance_glyph(ctx, font, gid) * g_font_size; } float ui_measure_character(fz_context *ctx, int ucs) { - FT_Fixed advance; - FT_Face face; - int gid; - - face = g_font; - gid = FT_Get_Char_Index(face, ucs); - if (gid <= 0) - { - face = g_fallback_font; - gid = FT_Get_Char_Index(face, ucs); - } - - FT_Get_Advance(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING, &advance); - return advance / 65536.0f; + fz_font *font; + int gid = fz_encode_character_with_fallback(ctx, g_font, ucs, 0, &font); + return fz_advance_glyph(ctx, font, gid) * g_font_size; } float ui_draw_character(fz_context *ctx, int ucs, float x, float y) { - FT_Face face; - int gid; - - face = g_font; - gid = FT_Get_Char_Index(face, ucs); - if (gid <= 0) - { - face = g_fallback_font; - gid = FT_Get_Char_Index(face, ucs); - } - - return ui_draw_glyph(face, gid, x, y); + fz_font *font; + int gid = fz_encode_character_with_fallback(ctx, g_font, ucs, 0, &font); + return ui_draw_glyph(font, gid, x, y); } void ui_begin_text(fz_context *ctx) -- cgit v1.2.3