summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2016-02-11 13:47:44 +0100
committerTor Andersson <tor.andersson@artifex.com>2016-02-11 13:47:44 +0100
commit29f5166856a1c57c69d8a9658a2f8929ee84197f (patch)
tree74e48abb7f3ec75777555c875f13ebbc06f89e04
parenta94ecea1aa6d3ce994782a7dd1d531728463186e (diff)
downloadmupdf-29f5166856a1c57c69d8a9658a2f8929ee84197f.tar.xz
gl: Use fz_font instead of freetype directly.
-rw-r--r--platform/gl/gl-font.c145
1 files 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 <ft2build.h>
-#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)