diff options
author | Robin Watts <robin.watts@artifex.com> | 2013-08-29 15:53:45 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2013-09-02 11:40:14 +0100 |
commit | e53325d2366e313dafcfee8432d12d20f6d0a88f (patch) | |
tree | 3b3c39c9c8d83d219c4005be6f46bbe0550a3952 /source/fitz/font.c | |
parent | da277059b37380d57028ff79a636f4d725c96e8f (diff) | |
download | mupdf-e53325d2366e313dafcfee8432d12d20f6d0a88f.tar.xz |
Add glyph rendering routines that return fz_pixmaps rather than fz_glyphs.
These do no caching, and are intended to be useful for the opengl device.
Diffstat (limited to 'source/fitz/font.c')
-rw-r--r-- | source/fitz/font.c | 135 |
1 files changed, 114 insertions, 21 deletions
diff --git a/source/fitz/font.c b/source/fitz/font.c index 1aeab3a6..165b6880 100644 --- a/source/fitz/font.c +++ b/source/fitz/font.c @@ -402,7 +402,7 @@ fz_adjust_ft_glyph_width(fz_context *ctx, fz_font *font, int gid, fz_matrix *trm } static fz_glyph * -fz_copy_ft_bitmap(fz_context *ctx, int left, int top, FT_Bitmap *bitmap) +glyph_from_ft_bitmap(fz_context *ctx, int left, int top, FT_Bitmap *bitmap) { if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO) return fz_new_glyph_from_1bpp_data(ctx, left, top - bitmap->rows, bitmap->width, bitmap->rows, bitmap->buffer + (bitmap->rows-1)*bitmap->pitch, -bitmap->pitch); @@ -410,15 +410,23 @@ fz_copy_ft_bitmap(fz_context *ctx, int left, int top, FT_Bitmap *bitmap) return fz_new_glyph_from_8bpp_data(ctx, left, top - bitmap->rows, bitmap->width, bitmap->rows, bitmap->buffer + (bitmap->rows-1)*bitmap->pitch, -bitmap->pitch); } -/* The glyph cache lock is always taken when this is called. */ -fz_glyph * -fz_render_ft_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, int aa) +static fz_pixmap * +pixmap_from_ft_bitmap(fz_context *ctx, int left, int top, FT_Bitmap *bitmap) +{ + if (bitmap->pixel_mode == FT_PIXEL_MODE_MONO) + return fz_new_pixmap_from_1bpp_data(ctx, left, top - bitmap->rows, bitmap->width, bitmap->rows, bitmap->buffer + (bitmap->rows-1)*bitmap->pitch, -bitmap->pitch); + else + return fz_new_pixmap_from_8bpp_data(ctx, left, top - bitmap->rows, bitmap->width, bitmap->rows, bitmap->buffer + (bitmap->rows-1)*bitmap->pitch, -bitmap->pitch); +} + +/* Takes the freetype lock, and returns with it held */ +static FT_GlyphSlot +do_ft_render_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, int aa) { FT_Face face = font->ft_face; FT_Matrix m; FT_Vector v; FT_Error fterr; - fz_glyph *result; fz_matrix local_trm = *trm; float strength = fz_matrix_expansion(trm) * 0.02f; @@ -492,7 +500,6 @@ retry_unhinted: if (fterr) { fz_warn(ctx, "freetype load glyph (gid %d): %s", gid, ft_error_string(fterr)); - fz_unlock(ctx, FZ_LOCK_FREETYPE); return NULL; } } @@ -507,13 +514,26 @@ retry_unhinted: if (fterr) { fz_warn(ctx, "freetype render glyph (gid %d): %s", gid, ft_error_string(fterr)); + return NULL; + } + return face->glyph; +} + +fz_pixmap * +fz_render_ft_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, int aa) +{ + FT_GlyphSlot slot = do_ft_render_glyph(ctx, font, gid, trm, aa); + fz_pixmap *pixmap; + + if (slot == NULL) + { fz_unlock(ctx, FZ_LOCK_FREETYPE); return NULL; } fz_try(ctx) { - result = fz_copy_ft_bitmap(ctx, face->glyph->bitmap_left, face->glyph->bitmap_top, &face->glyph->bitmap); + pixmap = pixmap_from_ft_bitmap(ctx, slot->bitmap_left, slot->bitmap_top, &slot->bitmap); } fz_always(ctx) { @@ -524,11 +544,41 @@ retry_unhinted: fz_rethrow(ctx); } - return result; + return pixmap; } +/* The glyph cache lock is always taken when this is called. */ fz_glyph * -fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, fz_stroke_state *state) +fz_render_ft_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, int aa) +{ + FT_GlyphSlot slot = do_ft_render_glyph(ctx, font, gid, trm, aa); + fz_glyph *glyph; + + if (slot == NULL) + { + fz_unlock(ctx, FZ_LOCK_FREETYPE); + return NULL; + } + + fz_try(ctx) + { + glyph = glyph_from_ft_bitmap(ctx, slot->bitmap_left, slot->bitmap_top, &slot->bitmap); + } + fz_always(ctx) + { + fz_unlock(ctx, FZ_LOCK_FREETYPE); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } + + return glyph; +} + +/* Takes the freetype lock, and returns with it held */ +static FT_Glyph +do_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, fz_stroke_state *state) { FT_Face face = font->ft_face; float expansion = fz_matrix_expansion(ctm); @@ -538,8 +588,6 @@ fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_mat FT_Error fterr; FT_Stroker stroker; FT_Glyph glyph; - FT_BitmapGlyph bitmap; - fz_glyph *result; FT_Stroker_LineJoin line_join; fz_matrix local_trm = *trm; @@ -560,7 +608,6 @@ fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_mat if (fterr) { fz_warn(ctx, "FT_Set_Char_Size: %s", ft_error_string(fterr)); - fz_unlock(ctx, FZ_LOCK_FREETYPE); return NULL; } @@ -570,7 +617,6 @@ fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_mat if (fterr) { fz_warn(ctx, "FT_Load_Glyph(gid %d): %s", gid, ft_error_string(fterr)); - fz_unlock(ctx, FZ_LOCK_FREETYPE); return NULL; } @@ -578,7 +624,6 @@ fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_mat if (fterr) { fz_warn(ctx, "FT_Stroker_New: %s", ft_error_string(fterr)); - fz_unlock(ctx, FZ_LOCK_FREETYPE); return NULL; } @@ -604,7 +649,6 @@ fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_mat { fz_warn(ctx, "FT_Get_Glyph: %s", ft_error_string(fterr)); FT_Stroker_Done(stroker); - fz_unlock(ctx, FZ_LOCK_FREETYPE); return NULL; } @@ -614,7 +658,6 @@ fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_mat fz_warn(ctx, "FT_Glyph_Stroke: %s", ft_error_string(fterr)); FT_Done_Glyph(glyph); FT_Stroker_Done(stroker); - fz_unlock(ctx, FZ_LOCK_FREETYPE); return NULL; } @@ -625,14 +668,57 @@ fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_mat { fz_warn(ctx, "FT_Glyph_To_Bitmap: %s", ft_error_string(fterr)); FT_Done_Glyph(glyph); + return NULL; + } + return glyph; +} + +fz_pixmap * +fz_render_ft_stroked_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, fz_stroke_state *state) +{ + FT_Glyph glyph = do_render_ft_stroked_glyph(ctx, font, gid, trm, ctm, state); + FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph; + fz_pixmap *pixmap; + + if (bitmap == NULL) + { fz_unlock(ctx, FZ_LOCK_FREETYPE); return NULL; } - bitmap = (FT_BitmapGlyph)glyph; fz_try(ctx) { - result = fz_copy_ft_bitmap(ctx, bitmap->left, bitmap->top, &bitmap->bitmap); + pixmap = pixmap_from_ft_bitmap(ctx, bitmap->left, bitmap->top, &bitmap->bitmap); + } + fz_always(ctx) + { + FT_Done_Glyph(glyph); + fz_unlock(ctx, FZ_LOCK_FREETYPE); + } + fz_catch(ctx) + { + fz_rethrow(ctx); + } + + return pixmap; +} + +fz_glyph * +fz_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, const fz_matrix *ctm, fz_stroke_state *state) +{ + FT_Glyph glyph = do_render_ft_stroked_glyph(ctx, font, gid, trm, ctm, state); + FT_BitmapGlyph bitmap = (FT_BitmapGlyph)glyph; + fz_glyph *result; + + if (bitmap == NULL) + { + fz_unlock(ctx, FZ_LOCK_FREETYPE); + return NULL; + } + + fz_try(ctx) + { + result = glyph_from_ft_bitmap(ctx, bitmap->left, bitmap->top, &bitmap->bitmap); } fz_always(ctx) { @@ -933,8 +1019,8 @@ fz_bound_t3_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, return bounds; } -fz_glyph * -fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, fz_colorspace *model, const fz_irect *scissor) +fz_pixmap * +fz_render_t3_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, fz_colorspace *model, const fz_irect *scissor) { fz_display_list *list; fz_matrix ctm; @@ -998,7 +1084,14 @@ fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm else result = glyph; - return fz_new_glyph_from_pixmap(ctx, result); + return result; +} + +fz_glyph * +fz_render_t3_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm, fz_colorspace *model, const fz_irect *scissor) +{ + fz_pixmap *pixmap = fz_render_t3_glyph_pixmap(ctx, font, gid, trm, model, scissor); + return fz_new_glyph_from_pixmap(ctx, pixmap); } void |