diff options
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++) { |