summaryrefslogtreecommitdiff
path: root/source
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2016-01-21 12:34:56 +0100
committerTor Andersson <tor.andersson@artifex.com>2016-01-21 12:34:56 +0100
commit000b8df004b175781af5b071590cf3867ae16f3a (patch)
tree1d57886b3cd2fb62a146cf1e367b20c30dd0e951 /source
parent1ceb3b2acf3b8b8c1d009a01e94957698e6ec142 (diff)
downloadmupdf-000b8df004b175781af5b071590cf3867ae16f3a.tar.xz
epub: Put font fallback chain in fz_font.
fz_encode_character_with_fallback finds the first font in the fallback chain that has the glyph encoded, and if none do then try to encode a bullet character.
Diffstat (limited to 'source')
-rw-r--r--source/fitz/font.c36
-rw-r--r--source/html/css-apply.c1
-rw-r--r--source/html/html-font.c35
-rw-r--r--source/html/html-layout.c97
4 files changed, 67 insertions, 102 deletions
diff --git a/source/fitz/font.c b/source/fitz/font.c
index 0350674f..bdfee584 100644
--- a/source/fitz/font.c
+++ b/source/fitz/font.c
@@ -120,14 +120,14 @@ fz_drop_font(fz_context *ctx, fz_font *font)
if (!fz_drop_imp(ctx, font, &font->refs))
return;
- free_resources(ctx, font);
+ fz_drop_font(ctx, font->fallback);
+
if (font->t3lists)
{
+ free_resources(ctx, font);
for (i = 0; i < 256; i++)
- {
if (font->t3lists[i])
fz_drop_display_list(ctx, font->t3lists[i]);
- }
fz_free(ctx, font->t3procs);
fz_free(ctx, font->t3lists);
fz_free(ctx, font->t3widths);
@@ -1366,3 +1366,33 @@ fz_encode_character(fz_context *ctx, fz_font *font, int ucs)
}
return ucs;
}
+
+int
+fz_encode_character_with_fallback(fz_context *ctx, fz_font *first_font, int ucs, fz_font **out_font)
+{
+ fz_font *font;
+
+ for (font = first_font; font; font = font->fallback)
+ {
+ int gid = fz_encode_character(ctx, font, ucs);
+ if (gid > 0)
+ {
+ *out_font = font;
+ return gid;
+ }
+ }
+
+ ucs = 0x25CF; /* bullet */
+ for (font = first_font; font; font = font->fallback)
+ {
+ int gid = fz_encode_character(ctx, font, ucs);
+ if (gid > 0)
+ {
+ *out_font = font;
+ return gid;
+ }
+ }
+
+ *out_font = first_font;
+ return 0;
+}
diff --git a/source/html/css-apply.c b/source/html/css-apply.c
index f7884504..45fa7713 100644
--- a/source/html/css-apply.c
+++ b/source/html/css-apply.c
@@ -1161,7 +1161,6 @@ fz_apply_css_style(fz_context *ctx, fz_html_font_set *set, fz_css_style *style,
const char *font_style = string_from_property(match, "font-style", "normal");
const char *font_weight = string_from_property(match, "font-weight", "normal");
style->font = fz_load_html_font(ctx, set, font_family, font_variant, font_style, font_weight);
- style->fallback = fz_load_html_fallback_font(ctx, set);
}
}
diff --git a/source/html/html-font.c b/source/html/html-font.c
index e9c17719..4b138162 100644
--- a/source/html/html-font.c
+++ b/source/html/html-font.c
@@ -12,6 +12,23 @@ static const char *font_names[16] =
};
fz_font *
+fz_load_html_fallback_font(fz_context *ctx, fz_html_font_set *set)
+{
+ if (!set->fallback)
+ {
+ unsigned char *data;
+ unsigned int size;
+ int index;
+
+ data = pdf_lookup_substitute_cjk_font(ctx, FZ_ADOBE_GB_1, 0, 0, &size, &index);
+ if (!data)
+ fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load fallback font");
+ set->fallback = fz_new_font_from_memory(ctx, "fallback", data, size, index, 0);
+ }
+ return set->fallback;
+}
+
+fz_font *
fz_load_html_font(fz_context *ctx, fz_html_font_set *set,
const char *family, const char *variant, const char *style, const char *weight)
{
@@ -30,28 +47,12 @@ fz_load_html_font(fz_context *ctx, fz_html_font_set *set,
if (!data)
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load html font: %s", font_names[idx]);
set->fonts[idx] = fz_new_font_from_memory(ctx, font_names[idx], data, size, 0, 1);
+ set->fonts[idx]->fallback = fz_load_html_fallback_font(ctx, set);
}
return set->fonts[idx];
}
-fz_font *
-fz_load_html_fallback_font(fz_context *ctx, fz_html_font_set *set)
-{
- if (!set->fallback)
- {
- unsigned char *data;
- unsigned int size;
- int index;
-
- data = pdf_lookup_substitute_cjk_font(ctx, FZ_ADOBE_GB_1, 0, 0, &size, &index);
- if (!data)
- fz_throw(ctx, FZ_ERROR_GENERIC, "cannot load fallback font");
- set->fallback = fz_new_font_from_memory(ctx, "fallback", data, size, index, 0);
- }
- return set->fallback;
-}
-
fz_html_font_set *fz_new_html_font_set(fz_context *ctx)
{
return fz_malloc_struct(ctx, fz_html_font_set);
diff --git a/source/html/html-layout.c b/source/html/html-layout.c
index 6366f5cc..36995c34 100644
--- a/source/html/html-layout.c
+++ b/source/html/html-layout.c
@@ -538,6 +538,7 @@ static void measure_image(fz_context *ctx, fz_html_flow *node, float max_w, floa
static void measure_word(fz_context *ctx, fz_html_flow *node, float em)
{
+ fz_font *font;
const char *s;
int c, g;
float w;
@@ -552,16 +553,8 @@ static void measure_word(fz_context *ctx, fz_html_flow *node, float em)
while (*s)
{
s += fz_chartorune(&c, s);
- g = fz_encode_character(ctx, node->style->font, c);
- if (g)
- {
- w += fz_advance_glyph(ctx, node->style->font, g) * em;
- }
- else
- {
- g = fz_encode_character(ctx, node->style->fallback, c);
- w += fz_advance_glyph(ctx, node->style->fallback, g) * em;
- }
+ g = fz_encode_character_with_fallback(ctx, node->style->font, c, &font);
+ w += fz_advance_glyph(ctx, font, g) * em;
}
node->w = w;
node->em = em;
@@ -906,6 +899,7 @@ static float layout_block(fz_context *ctx, fz_html *box, fz_html *top, float em,
static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float page_bot, fz_device *dev, const fz_matrix *ctm)
{
+ fz_font *font;
fz_html_flow *node;
fz_text *text;
fz_matrix trm;
@@ -949,27 +943,9 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p
{
t += fz_chartorune(&c, t);
if (node->mirror)
- {
c = ucdn_mirror(c);
- }
- g = fz_encode_character(ctx, node->style->font, c);
- if (g)
- {
- w += fz_advance_glyph(ctx, node->style->font, g) * node->em;
- }
- else
- {
- g = fz_encode_character(ctx, node->style->fallback, c);
- if (g)
- {
- w += fz_advance_glyph(ctx, node->style->fallback, g) * node->em;
- }
- else
- {
- g = fz_encode_character(ctx, node->style->font, 0x25CF); /* bullet */
- w += fz_advance_glyph(ctx, node->style->font, g) * node->em;
- }
- }
+ g = fz_encode_character_with_fallback(ctx, node->style->font, c, &font);
+ w += fz_advance_glyph(ctx, font, g) * node->em;
}
trm.e += w;
@@ -977,33 +953,11 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p
{
s += fz_chartorune(&c, s);
if (node->mirror)
- {
c = ucdn_mirror(c);
- }
- g = fz_encode_character(ctx, node->style->font, c);
- if (g)
- {
- trm.e -= fz_advance_glyph(ctx, node->style->font, g) * node->em;
- if (node->style->visibility == V_VISIBLE)
- fz_add_text(ctx, text, node->style->font, 0, &trm, g, c);
- }
- else
- {
- g = fz_encode_character(ctx, node->style->fallback, c);
- if (g)
- {
- trm.e -= fz_advance_glyph(ctx, node->style->fallback, g) * node->em;
- if (node->style->visibility == V_VISIBLE)
- fz_add_text(ctx, text, node->style->fallback, 0, &trm, g, c);
- }
- else
- {
- trm.e -= fz_advance_glyph(ctx, node->style->font, g) * node->em;
- g = fz_encode_character(ctx, node->style->font, 0x25CF); /* bullet */
- if (node->style->visibility == V_VISIBLE)
- fz_add_text(ctx, text, node->style->font, 0, &trm, g, c);
- }
- }
+ g = fz_encode_character_with_fallback(ctx, node->style->font, c, &font);
+ trm.e -= fz_advance_glyph(ctx, font, g) * node->em;
+ if (node->style->visibility == V_VISIBLE)
+ fz_add_text(ctx, text, font, 0, &trm, g, c);
}
trm.e += w;
}
@@ -1012,30 +966,10 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p
while (*s)
{
s += fz_chartorune(&c, s);
- g = fz_encode_character(ctx, node->style->font, c);
- if (g)
- {
- if (node->style->visibility == V_VISIBLE)
- fz_add_text(ctx, text, node->style->font, 0, &trm, g, c);
- trm.e += fz_advance_glyph(ctx, node->style->font, g) * node->em;
- }
- else
- {
- g = fz_encode_character(ctx, node->style->fallback, c);
- if (g)
- {
- if (node->style->visibility == V_VISIBLE)
- fz_add_text(ctx, text, node->style->fallback, 0, &trm, g, c);
- trm.e += fz_advance_glyph(ctx, node->style->fallback, g) * node->em;
- }
- else
- {
- g = fz_encode_character(ctx, node->style->font, 0x25CF); /* bullet */
- if (node->style->visibility == V_VISIBLE)
- fz_add_text(ctx, text, node->style->font, 0, &trm, g, c);
- trm.e += fz_advance_glyph(ctx, node->style->font, g) * node->em;
- }
- }
+ g = fz_encode_character_with_fallback(ctx, node->style->font, c, &font);
+ if (node->style->visibility == V_VISIBLE)
+ fz_add_text(ctx, text, font, 0, &trm, g, c);
+ trm.e += fz_advance_glyph(ctx, font, g) * node->em;
}
}
@@ -1181,6 +1115,7 @@ static fz_html_flow *find_list_mark_anchor(fz_context *ctx, fz_html *box)
static void draw_list_mark(fz_context *ctx, fz_html *box, float page_top, float page_bot, fz_device *dev, const fz_matrix *ctm, int n)
{
+ fz_font *font;
fz_text *text;
fz_matrix trm;
fz_html_flow *line;
@@ -1219,7 +1154,7 @@ static void draw_list_mark(fz_context *ctx, fz_html *box, float page_top, float
while (*s)
{
s += fz_chartorune(&c, s);
- g = fz_encode_character(ctx, box->style.font, c);
+ g = fz_encode_character_with_fallback(ctx, box->style.font, c, &font);
w += fz_advance_glyph(ctx, box->style.font, g) * box->em;
}