summaryrefslogtreecommitdiff
path: root/source/fitz
diff options
context:
space:
mode:
Diffstat (limited to 'source/fitz')
-rw-r--r--source/fitz/draw-glyph.c20
-rw-r--r--source/fitz/font-impl.h50
-rw-r--r--source/fitz/font.c92
-rw-r--r--source/fitz/stext-device.c18
-rw-r--r--source/fitz/stext-output.c23
-rw-r--r--source/fitz/svg-device.c2
-rw-r--r--source/fitz/trace-device.c2
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++)
{