diff options
author | Robin Watts <Robin.Watts@artifex.com> | 2016-09-28 16:46:10 +0100 |
---|---|---|
committer | Robin Watts <robin.watts@artifex.com> | 2016-10-05 19:37:11 +0100 |
commit | 9e88b088ea2ddcb6f85584750eb3c989af101905 (patch) | |
tree | 19db41ec596cc347fd1b77389821135f8e934e84 /source/fitz | |
parent | 14109acf198d9371a4e2cb09ea4a125af67d441d (diff) | |
download | mupdf-9e88b088ea2ddcb6f85584750eb3c989af101905.tar.xz |
Move fz_font definition to be private.
Move the definition of fz_font to be in a private header file
rather than in the public API. Add accessors for specific
parts of the structure and use them as appropriate.
The font flags, and the harfbuzz records remain public.
This means that only 3 files now need access to the font
implementation (font.c, pdf-font.c and pdf-type3.c). This
may be able to be improved further in future.
Diffstat (limited to 'source/fitz')
-rw-r--r-- | source/fitz/draw-glyph.c | 20 | ||||
-rw-r--r-- | source/fitz/font-impl.h | 50 | ||||
-rw-r--r-- | source/fitz/font.c | 92 | ||||
-rw-r--r-- | source/fitz/stext-device.c | 18 | ||||
-rw-r--r-- | source/fitz/stext-output.c | 23 | ||||
-rw-r--r-- | source/fitz/svg-device.c | 2 | ||||
-rw-r--r-- | source/fitz/trace-device.c | 2 |
7 files changed, 150 insertions, 57 deletions
diff --git a/source/fitz/draw-glyph.c b/source/fitz/draw-glyph.c index dbaace9e..93bd62b3 100644 --- a/source/fitz/draw-glyph.c +++ b/source/fitz/draw-glyph.c @@ -175,7 +175,7 @@ fz_subpixel_adjust(fz_context *ctx, fz_matrix *ctm, fz_matrix *subpix_ctm, unsig fz_glyph * fz_render_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *stroke, const fz_irect *scissor) { - if (font->ft_face) + if (fz_font_ft_face(font)) { fz_matrix subpix_trm; unsigned char qe, qf; @@ -191,7 +191,7 @@ fz_render_stroked_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *trm, fz_pixmap * fz_render_stroked_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix *trm, const fz_matrix *ctm, const fz_stroke_state *stroke, const fz_irect *scissor) { - if (font->ft_face) + if (fz_font_ft_face(font)) { fz_matrix subpix_trm; unsigned char qe, qf; @@ -252,6 +252,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, fz_colo int do_cache, locked, caching; fz_glyph_cache_entry *entry; unsigned hash; + int is_ft_font = !!fz_font_ft_face(font); fz_var(locked); fz_var(caching); @@ -266,7 +267,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, fz_colo } else { - if (font->ft_face) + if (is_ft_font) return NULL; subpix_scissor.x0 = scissor->x0 - floorf(ctm->e); subpix_scissor.y0 = scissor->y0 - floorf(ctm->f); @@ -307,11 +308,11 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, fz_colo fz_try(ctx) { - if (font->ft_face) + if (is_ft_font) { val = fz_render_ft_glyph(ctx, font, gid, &subpix_ctm, key.aa); } - else if (font->t3procs) + else if (fz_font_t3_procs(font)) { /* We drop the glyphcache here, and execute the t3 * glyph code. The danger here is that some other @@ -339,7 +340,7 @@ fz_render_glyph(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, fz_colo /* If we throw an exception whilst caching, * just ignore the exception and carry on. */ caching = 1; - if (!font->ft_face) + if (!is_ft_font) { /* We had to unlock. Someone else might * have rendered in the meantime */ @@ -413,6 +414,7 @@ fz_render_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, unsigned char qe, qf; fz_matrix subpix_ctm; float size = fz_subpixel_adjust(ctx, ctm, &subpix_ctm, &qe, &qf); + int is_ft_font = !!fz_font_ft_face(font); if (size <= MAX_GLYPH_SIZE) { @@ -420,17 +422,17 @@ fz_render_glyph_pixmap(fz_context *ctx, fz_font *font, int gid, fz_matrix *ctm, } else { - if (font->ft_face) + if (is_ft_font) return NULL; } fz_try(ctx) { - if (font->ft_face) + if (is_ft_font) { val = fz_render_ft_glyph_pixmap(ctx, font, gid, &subpix_ctm, fz_text_aa_level(ctx)); } - else if (font->t3procs) + else if (fz_font_t3_procs(font)) { val = fz_render_t3_glyph_pixmap(ctx, font, gid, &subpix_ctm, NULL, scissor); } diff --git a/source/fitz/font-impl.h b/source/fitz/font-impl.h new file mode 100644 index 00000000..b6015172 --- /dev/null +++ b/source/fitz/font-impl.h @@ -0,0 +1,50 @@ +#ifndef MUPDF_FITZ_FONT_IMPL_H +#define MUPDF_FITZ_FONT_IMPL_H + +#include "mupdf/fitz/font.h" + +/* forward declaration for circular dependency */ +struct fz_device_s; +struct fz_display_list_s; + +struct fz_font_s +{ + int refs; + char name[32]; + fz_buffer *buffer; + + fz_font_flags_t flags; + + void *ft_face; /* has an FT_Face if used */ + fz_hb_t hb; + + fz_matrix t3matrix; + void *t3resources; + fz_buffer **t3procs; /* has 256 entries if used */ + struct fz_display_list_s **t3lists; /* has 256 entries if used */ + float *t3widths; /* has 256 entries if used */ + unsigned short *t3flags; /* has 256 entries if used */ + void *t3doc; /* a pdf_document for the callback */ + void (*t3run)(fz_context *ctx, void *doc, void *resources, fz_buffer *contents, struct fz_device_s *dev, const fz_matrix *ctm, void *gstate, int nestedDepth); + void (*t3freeres)(fz_context *ctx, void *doc, void *resources); + + fz_rect bbox; /* font bbox is used only for t3 fonts */ + + int glyph_count; + + /* per glyph bounding box cache */ + fz_rect *bbox_table; + + /* substitute metrics */ + int width_count; + short width_default; /* in 1000 units */ + short *width_table; /* in 1000 units */ + + /* cached glyph metrics */ + float *advance_cache; + + /* cached encoding lookup */ + uint16_t *encoding_cache[256]; +}; + +#endif diff --git a/source/fitz/font.c b/source/fitz/font.c index beab4c87..be0f38d7 100644 --- a/source/fitz/font.c +++ b/source/fitz/font.c @@ -1,5 +1,7 @@ #include "mupdf/fitz.h" +#include "font-impl.h" + #include <ft2build.h> #include "hb.h" #include "hb-ft.h" @@ -37,11 +39,11 @@ fz_new_font(fz_context *ctx, const char *name, int use_glyph_bbox, int glyph_cou fz_strlcpy(font->name, "(null)", sizeof font->name); font->ft_face = NULL; - font->ft_substitute = 0; - font->fake_bold = 0; - font->fake_italic = 0; - font->force_hinting = 0; - font->has_opentype = 0; + font->flags.ft_substitute = 0; + font->flags.fake_bold = 0; + font->flags.fake_italic = 0; + font->flags.force_hinting = 0; + font->flags.has_opentype = 0; font->t3matrix = fz_identity; font->t3resources = NULL; @@ -59,7 +61,7 @@ fz_new_font(fz_context *ctx, const char *name, int use_glyph_bbox, int glyph_cou font->glyph_count = glyph_count; - font->use_glyph_bbox = !!use_glyph_bbox; + font->flags.use_glyph_bbox = !!use_glyph_bbox; if (use_glyph_bbox && glyph_count <= MAX_BBOX_TABLE_SIZE) { font->bbox_table = fz_malloc_array(ctx, glyph_count, sizeof(fz_rect)); @@ -156,10 +158,10 @@ fz_drop_font(fz_context *ctx, fz_font *font) fz_free(ctx, font->bbox_table); fz_free(ctx, font->width_table); fz_free(ctx, font->advance_cache); - if (font->hb_destroy && font->hb_font) + if (font->hb.destroy && font->hb.font) { hb_lock(ctx); - font->hb_destroy(font->hb_font); + font->hb.destroy(font->hb.font); hb_unlock(ctx); } fz_free(ctx, font); @@ -176,7 +178,7 @@ fz_set_font_bbox(fz_context *ctx, fz_font *font, float xmin, float ymin, float x font->bbox.y0 = -1; font->bbox.x1 = 2; font->bbox.y1 = 2; - font->invalid_bbox = 1; + font->flags.invalid_bbox = 1; } else { @@ -475,23 +477,23 @@ fz_new_font_from_buffer(fz_context *ctx, const char *name, fz_buffer *buffer, in (float) face->bbox.xMax / face->units_per_EM, (float) face->bbox.yMax / face->units_per_EM); - font->is_mono = !!(face->face_flags & FT_FACE_FLAG_FIXED_WIDTH); - font->is_serif = 1; - font->is_bold = !!(face->style_flags & FT_STYLE_FLAG_BOLD); - font->is_italic = !!(face->style_flags & FT_STYLE_FLAG_ITALIC); + font->flags.is_mono = !!(face->face_flags & FT_FACE_FLAG_FIXED_WIDTH); + font->flags.is_serif = 1; + font->flags.is_bold = !!(face->style_flags & FT_STYLE_FLAG_BOLD); + font->flags.is_italic = !!(face->style_flags & FT_STYLE_FLAG_ITALIC); if (FT_IS_SFNT(face)) { os2 = FT_Get_Sfnt_Table(face, FT_SFNT_OS2); if (os2) - font->is_serif = !(os2->sFamilyClass & 2048); /* Class 8 is sans-serif */ + font->flags.is_serif = !(os2->sFamilyClass & 2048); /* Class 8 is sans-serif */ FT_Sfnt_Table_Info(face, 0, NULL, &n); for (i = 0; i < n; ++i) { FT_Sfnt_Table_Info(face, i, &tag, &size); if (tag == TTAG_GDEF || tag == TTAG_GPOS || tag == TTAG_GSUB) - font->has_opentype = 1; + font->flags.has_opentype = 1; } } @@ -532,7 +534,7 @@ static fz_matrix * fz_adjust_ft_glyph_width(fz_context *ctx, fz_font *font, int gid, fz_matrix *trm) { /* Fudge the font matrix to stretch the glyph if we've substituted the font. */ - if (font->ft_stretch && font->width_table /* && font->wmode == 0 */) + if (font->flags.ft_stretch && font->width_table /* && font->wmode == 0 */) { FT_Fixed adv; float subw; @@ -588,7 +590,7 @@ do_ft_render_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm fz_adjust_ft_glyph_width(ctx, font, gid, &local_trm); - if (font->fake_italic) + if (font->flags.fake_italic) fz_pre_shear(&local_trm, SHEAR, 0); /* @@ -633,7 +635,7 @@ do_ft_render_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm goto retry_unhinted; } } - else if (font->force_hinting) + else if (font->flags.force_hinting) { /* Enable hinting, but keep the huge char size so that @@ -659,7 +661,7 @@ retry_unhinted: } } - if (font->fake_bold) + if (font->flags.fake_bold) { FT_Outline_Embolden(&face->glyph->outline, strength * 64); FT_Outline_Translate(&face->glyph->outline, -strength * 32, -strength * 32); @@ -749,7 +751,7 @@ do_render_ft_stroked_glyph(fz_context *ctx, fz_font *font, int gid, const fz_mat fz_adjust_ft_glyph_width(ctx, font, gid, &local_trm); - if (font->fake_italic) + if (font->flags.fake_italic) fz_pre_shear(&local_trm, SHEAR, 0); m.xx = local_trm.a * 64; /* should be 65536 */ @@ -907,7 +909,7 @@ fz_bound_ft_glyph(fz_context *ctx, fz_font *font, int gid) fz_adjust_ft_glyph_width(ctx, font, gid, &local_trm); - if (font->fake_italic) + if (font->flags.fake_italic) fz_pre_shear(&local_trm, SHEAR, 0); m.xx = local_trm.a * 65536; @@ -917,7 +919,7 @@ fz_bound_ft_glyph(fz_context *ctx, fz_font *font, int gid) v.x = local_trm.e * 65536; v.y = local_trm.f * 65536; - if (font->force_hinting) + if (font->flags.force_hinting) { ft_flags = FT_LOAD_NO_BITMAP; } @@ -945,7 +947,7 @@ fz_bound_ft_glyph(fz_context *ctx, fz_font *font, int gid) return bounds; } - if (font->fake_bold) + if (font->flags.fake_bold) { FT_Outline_Embolden(&face->glyph->outline, strength * scale); FT_Outline_Translate(&face->glyph->outline, -strength * 0.5 * scale, -strength * 0.5 * scale); @@ -1047,12 +1049,12 @@ fz_outline_ft_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *tr fz_adjust_ft_glyph_width(ctx, font, gid, &local_trm); - if (font->fake_italic) + if (font->flags.fake_italic) fz_pre_shear(&local_trm, SHEAR, 0); fz_lock(ctx, FZ_LOCK_FREETYPE); - if (font->force_hinting) + if (font->flags.force_hinting) { ft_flags = FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM; fterr = FT_Set_Char_Size(face, scale, scale, 72, 72); @@ -1072,7 +1074,7 @@ fz_outline_ft_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *tr return NULL; } - if (font->fake_bold) + if (font->flags.fake_bold) { FT_Outline_Embolden(&face->glyph->outline, strength * scale); FT_Outline_Translate(&face->glyph->outline, -strength * 0.5 * scale, -strength * 0.5 * scale); @@ -1205,7 +1207,7 @@ fz_prepare_t3_glyph(fz_context *ctx, fz_font *font, int gid, int nested_depth) font->bbox_table[gid] = d1_rect; fz_transform_rect(&font->bbox_table[gid], &font->t3matrix); - if (font->invalid_bbox || !fz_contains_rect(&font->bbox, &d1_rect)) + if (font->flags.invalid_bbox || !fz_contains_rect(&font->bbox, &d1_rect)) { /* Either the font bbox is invalid, or the d1_rect returned is * incompatible with it. Either way, don't trust the d1 rect @@ -1352,7 +1354,7 @@ fz_print_font(fz_context *ctx, fz_output *out, fz_font *font) if (font->ft_face) { fz_printf(ctx, out, "\tfreetype face %p\n", font->ft_face); - if (font->ft_substitute) + if (font->flags.ft_substitute) fz_printf(ctx, out, "\tsubstitute font\n"); } @@ -1524,7 +1526,7 @@ fz_encode_character_with_fallback(fz_context *ctx, fz_font *user_font, int unico if (script == 0) script = ucdn_get_script(unicode); - font = fz_load_fallback_font(ctx, script, language, user_font->is_serif, user_font->is_bold, user_font->is_italic); + font = fz_load_fallback_font(ctx, script, language, user_font->flags.is_serif, user_font->flags.is_bold, user_font->flags.is_italic); if (font) { gid = fz_encode_character(ctx, font, unicode); @@ -1550,3 +1552,35 @@ fz_encode_character_with_fallback(fz_context *ctx, fz_font *user_font, int unico return *out_font = user_font, 0; } + +const char *fz_font_name(fz_font *font) +{ + if (font == NULL || font->name == NULL) + return ""; + return font->name; +} + +fz_buffer **fz_font_t3_procs(fz_font *font) +{ + return font ? font->t3procs : NULL; +} + +fz_rect *fz_font_bbox(fz_font *font) +{ + return font ? &font->bbox : NULL; +} + +void *fz_font_ft_face(fz_font *font) +{ + return font ? font->ft_face : NULL; +} + +fz_font_flags_t *fz_font_flags(fz_font *font) +{ + return font ? &font->flags : NULL; +} + +fz_hb_t *fz_font_hb(fz_font *font) +{ + return font ? &font->hb : NULL; +} diff --git a/source/fitz/stext-device.c b/source/fitz/stext-device.c index 909d0a46..88a9f669 100644 --- a/source/fitz/stext-device.c +++ b/source/fitz/stext-device.c @@ -784,7 +784,9 @@ static void fz_stext_extract(fz_context *ctx, fz_stext_device *dev, fz_text_span *span, const fz_matrix *ctm, fz_stext_style *style) { fz_font *font = span->font; - FT_Face face = font->ft_face; + FT_Face face = fz_font_ft_face(font); + fz_buffer **t3procs = fz_font_t3_procs(font); + fz_rect *bbox = fz_font_bbox(font); fz_matrix tm = span->trm; fz_matrix trm; float adv; @@ -800,26 +802,26 @@ fz_stext_extract(fz_context *ctx, fz_stext_device *dev, fz_text_span *span, cons if (style->wmode == 0) { - if (font->ft_face) + if (face) { fz_lock(ctx, FZ_LOCK_FREETYPE); - err = FT_Set_Char_Size(font->ft_face, 64, 64, 72, 72); + err = FT_Set_Char_Size(face, 64, 64, 72, 72); if (err) fz_warn(ctx, "freetype set character size: %s", ft_error_string(err)); ascender = (float)face->ascender / face->units_per_EM; descender = (float)face->descender / face->units_per_EM; fz_unlock(ctx, FZ_LOCK_FREETYPE); } - else if (font->t3procs && !fz_is_empty_rect(&font->bbox)) + else if (t3procs && !fz_is_empty_rect(bbox)) { - ascender = font->bbox.y1; - descender = font->bbox.y0; + ascender = bbox->y1; + descender = bbox->y0; } } else { - ascender = font->bbox.x1; - descender = font->bbox.x0; + ascender = bbox->x1; + descender = bbox->x0; } style->ascender = ascender; style->descender = descender; diff --git a/source/fitz/stext-output.c b/source/fitz/stext-output.c index f7ea0c24..39d97dc3 100644 --- a/source/fitz/stext-output.c +++ b/source/fitz/stext-output.c @@ -10,20 +10,22 @@ static int font_is_bold(fz_font *font) { - FT_Face face = font->ft_face; + FT_Face face = fz_font_ft_face(font); if (face && (face->style_flags & FT_STYLE_FLAG_BOLD)) return 1; - if (strstr(font->name, "Bold")) + if (strstr(fz_font_name(font), "Bold")) return 1; return 0; } static int font_is_italic(fz_font *font) { - FT_Face face = font->ft_face; + FT_Face face = fz_font_ft_face(font); + const char *name; if (face && (face->style_flags & FT_STYLE_FLAG_ITALIC)) return 1; - if (strstr(font->name, "Italic") || strstr(font->name, "Oblique")) + name = fz_font_name(font); + if (strstr(name, "Italic") || strstr(name, "Oblique")) return 1; return 0; } @@ -53,8 +55,9 @@ fz_print_style_end(fz_context *ctx, fz_output *out, fz_stext_style *style) static void fz_print_style(fz_context *ctx, fz_output *out, fz_stext_style *style) { - char *s = strchr(style->font->name, '+'); - s = s ? s + 1 : style->font->name; + const char *name = fz_font_name(style->font); + const char *s = strchr(name, '+'); + s = s ? s + 1 : name; fz_printf(ctx, out, "span.s%d{font-family:\"%s\";font-size:%gpt;", style->id, s, style->size); if (font_is_italic(style->font)) @@ -292,7 +295,7 @@ fz_print_stext_page_xml(fz_context *ctx, fz_output *out, fz_stext_page *page) { fz_stext_block *block = page->blocks[block_n].u.text; fz_stext_line *line; - char *s; + const char *s; fz_printf(ctx, out, "<block bbox=\"%g %g %g %g\">\n", block->bbox.x0, block->bbox.y0, block->bbox.x1, block->bbox.y1); @@ -304,6 +307,7 @@ fz_print_stext_page_xml(fz_context *ctx, fz_output *out, fz_stext_page *page) for (span = line->first_span; span; span = span->next) { fz_stext_style *style = NULL; + const char *name = NULL; int char_num; for (char_num = 0; char_num < span->len; char_num++) { @@ -315,8 +319,9 @@ fz_print_stext_page_xml(fz_context *ctx, fz_output *out, fz_stext_page *page) fz_printf(ctx, out, "</span>\n"); } style = ch->style; - s = strchr(style->font->name, '+'); - s = s ? s + 1 : style->font->name; + name = fz_font_name(style->font); + s = strchr(name, '+'); + s = s ? s + 1 : name; fz_printf(ctx, out, "<span bbox=\"%g %g %g %g\" font=\"%s\" size=\"%g\">\n", span->bbox.x0, span->bbox.y0, span->bbox.x1, span->bbox.y1, s, style->size); diff --git a/source/fitz/svg-device.c b/source/fitz/svg-device.c index b997653d..1484dddd 100644 --- a/source/fitz/svg-device.c +++ b/source/fitz/svg-device.c @@ -274,7 +274,7 @@ svg_dev_text_span(fz_context *ctx, svg_device *sdev, const fz_matrix *ctm, const fz_printf(ctx, out, " transform=\"matrix(%g,%g,%g,%g,%g,%g)\"", local_trm.a, local_trm.b, local_trm.c, local_trm.d, local_trm.e, local_trm.f); fz_printf(ctx, out, " font-size=\"%g\"", size); - fz_printf(ctx, out, " font-family=\"%s\"", span->font->name); + fz_printf(ctx, out, " font-family=\"%s\"", fz_font_name(span->font)); /* Leading (and repeated) whitespace presents a problem for SVG * text, so elide it here. */ diff --git a/source/fitz/trace-device.c b/source/fitz/trace-device.c index 0b77c075..86e059b5 100644 --- a/source/fitz/trace-device.c +++ b/source/fitz/trace-device.c @@ -38,7 +38,7 @@ static void fz_trace_text_span(fz_context *ctx, fz_output *out, fz_text_span *span) { int i; - fz_printf(ctx, out, "<span font=\"%s\" wmode=\"%d\"", span->font->name, span->wmode); + fz_printf(ctx, out, "<span font=\"%s\" wmode=\"%d\"", fz_font_name(span->font), span->wmode); fz_printf(ctx, out, " trm=\"%g %g %g %g\">\n", span->trm.a, span->trm.b, span->trm.c, span->trm.d); for (i = 0; i < span->len; i++) { |