From c97ba05ef627bfdea79bf925e5728ae27270d25e Mon Sep 17 00:00:00 2001
From: Tor Andersson <tor.andersson@artifex.com>
Date: Tue, 15 Sep 2015 12:38:37 +0200
Subject: epub: Use a fallback font.

---
 source/html/css-apply.c   |  1 +
 source/html/html-font.c   | 19 ++++++++++++++++
 source/html/html-layout.c | 56 +++++++++++++++++++++++++++++++++++++----------
 3 files changed, 65 insertions(+), 11 deletions(-)

(limited to 'source/html')

diff --git a/source/html/css-apply.c b/source/html/css-apply.c
index 2333ef5d..551dc2d8 100644
--- a/source/html/css-apply.c
+++ b/source/html/css-apply.c
@@ -1069,6 +1069,7 @@ 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 08da04f5..e9c17719 100644
--- a/source/html/html-font.c
+++ b/source/html/html-font.c
@@ -1,6 +1,7 @@
 #include "mupdf/html.h"
 
 unsigned char *pdf_lookup_builtin_font(fz_context *ctx, const char *name, unsigned int *len);
+unsigned char *pdf_lookup_substitute_cjk_font(fz_context *ctx, int ros, int serif, int wmode, unsigned int *len, int *index);
 
 static const char *font_names[16] =
 {
@@ -34,6 +35,23 @@ fz_load_html_font(fz_context *ctx, fz_html_font_set *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);
@@ -44,5 +62,6 @@ void fz_drop_html_font_set(fz_context *ctx, fz_html_font_set *set)
 	int i;
 	for (i = 0; i < nelem(set->fonts); ++i)
 		fz_drop_font(ctx, set->fonts[i]);
+	fz_drop_font(ctx, set->fallback);
 	fz_free(ctx, set);
 }
diff --git a/source/html/html-layout.c b/source/html/html-layout.c
index d729c058..717bb1ea 100644
--- a/source/html/html-layout.c
+++ b/source/html/html-layout.c
@@ -451,7 +451,15 @@ static void measure_word(fz_context *ctx, fz_html_flow *node, float em)
 	{
 		s += fz_chartorune(&c, s);
 		g = fz_encode_character(ctx, node->style->font, c);
-		w += fz_advance_glyph(ctx, node->style->font, g) * em;
+		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;
+		}
 	}
 	node->w = w;
 	node->em = em;
@@ -759,6 +767,7 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p
 {
 	fz_html_flow *node;
 	fz_text *text;
+	fz_text *falltext;
 	fz_matrix trm;
 	const char *s;
 	float color[3];
@@ -781,7 +790,13 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p
 		if (node->type == FLOW_WORD)
 		{
 			fz_scale(&trm, node->em, -node->em);
-			text = fz_new_text(ctx, node->style->font, &trm, 0);
+
+			color[0] = node->style->color.r / 255.0f;
+			color[1] = node->style->color.g / 255.0f;
+			color[2] = node->style->color.b / 255.0f;
+
+			text = NULL;
+			falltext = NULL;
 
 			x = node->x;
 			y = node->y;
@@ -790,17 +805,36 @@ static void draw_flow_box(fz_context *ctx, fz_html *box, float page_top, float p
 			{
 				s += fz_chartorune(&c, s);
 				g = fz_encode_character(ctx, node->style->font, c);
-				fz_add_text(ctx, text, g, c, x, y);
-				x += fz_advance_glyph(ctx, node->style->font, g) * node->em;
+				if (g)
+				{
+					if (!text)
+						text = fz_new_text(ctx, node->style->font, &trm, 0);
+					fz_add_text(ctx, text, g, c, x, y);
+					x += fz_advance_glyph(ctx, node->style->font, g) * node->em;
+				}
+				else
+				{
+					g = fz_encode_character(ctx, node->style->fallback, c);
+					if (g)
+					{
+						if (!falltext)
+							falltext = fz_new_text(ctx, node->style->fallback, &trm, 0);
+						fz_add_text(ctx, falltext, g, c, x, y);
+					}
+					x += fz_advance_glyph(ctx, node->style->fallback, g) * node->em;
+				}
 			}
 
-			color[0] = node->style->color.r / 255.0f;
-			color[1] = node->style->color.g / 255.0f;
-			color[2] = node->style->color.b / 255.0f;
-
-			fz_fill_text(ctx, dev, text, ctm, fz_device_rgb(ctx), color, 1);
-
-			fz_drop_text(ctx, text);
+			if (text)
+			{
+				fz_fill_text(ctx, dev, text, ctm, fz_device_rgb(ctx), color, 1);
+				fz_drop_text(ctx, text);
+			}
+			if (falltext)
+			{
+				fz_fill_text(ctx, dev, falltext, ctm, fz_device_rgb(ctx), color, 1);
+				fz_drop_text(ctx, falltext);
+			}
 		}
 		else if (node->type == FLOW_IMAGE)
 		{
-- 
cgit v1.2.3