summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor.andersson@artifex.com>2016-02-10 18:08:23 +0100
committerTor Andersson <tor.andersson@artifex.com>2016-02-10 18:08:23 +0100
commita94ecea1aa6d3ce994782a7dd1d531728463186e (patch)
tree5e79e0ec68729fe7849cedb13ad277d97cc4b524
parent0e91218ff89aee9a24d7cd577de37b0f1bb8331a (diff)
downloadmupdf-a94ecea1aa6d3ce994782a7dd1d531728463186e.tar.xz
Add bold/italic/monospaced/serif flags to fz_font.
Use the flags when selecting a fallback font.
-rw-r--r--include/mupdf/fitz/font.h12
-rw-r--r--source/fitz/font.c39
-rw-r--r--source/html/html-font.c1
-rw-r--r--source/pdf/pdf-font.c22
-rw-r--r--source/xps/xps-glyphs.c8
5 files changed, 49 insertions, 33 deletions
diff --git a/include/mupdf/fitz/font.h b/include/mupdf/fitz/font.h
index 0de3e00e..ebd792e9 100644
--- a/include/mupdf/fitz/font.h
+++ b/include/mupdf/fitz/font.h
@@ -29,12 +29,18 @@ struct fz_font_s
int refs;
char name[32];
+ char is_mono;
+ char is_serif;
+ char is_bold;
+ char is_italic;
+
void *ft_face; /* has an FT_Face if used */
int ft_substitute; /* ... substitute metrics */
int ft_stretch; /* ... and stretch to match PDF metrics */
- int ft_bold; /* ... synthesize bold */
- int ft_italic; /* ... synthesize italic */
- int ft_hint; /* ... force hinting for DynaLab fonts */
+
+ int fake_bold; /* ... synthesize bold */
+ int fake_italic; /* ... synthesize italic */
+ int force_hinting; /* ... force hinting for DynaLab fonts */
/* origin of font data */
fz_buffer *ft_buffer;
diff --git a/source/fitz/font.c b/source/fitz/font.c
index e7dbc827..bfe91cf4 100644
--- a/source/fitz/font.c
+++ b/source/fitz/font.c
@@ -7,6 +7,7 @@
#include FT_FREETYPE_H
#include FT_ADVANCES_H
#include FT_STROKER_H
+#include FT_TRUETYPE_TABLES_H
#define MAX_BBOX_TABLE_SIZE 4096
#define MAX_ADVANCE_CACHE 4096
@@ -32,9 +33,9 @@ fz_new_font(fz_context *ctx, const char *name, int use_glyph_bbox, int glyph_cou
font->ft_face = NULL;
font->ft_substitute = 0;
- font->ft_bold = 0;
- font->ft_italic = 0;
- font->ft_hint = 0;
+ font->fake_bold = 0;
+ font->fake_italic = 0;
+ font->force_hinting = 0;
font->ft_buffer = NULL;
font->ft_filepath = NULL;
@@ -454,6 +455,7 @@ fz_font *
fz_new_font_from_memory(fz_context *ctx, const char *name, unsigned char *data, int len, int index, int use_glyph_bbox)
{
FT_Face face;
+ TT_OS2 *os2;
fz_font *font;
int fterr;
@@ -479,6 +481,15 @@ fz_new_font_from_memory(fz_context *ctx, const char *name, unsigned char *data,
(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);
+
+ os2 = FT_Get_Sfnt_Table(face, FT_SFNT_OS2);
+ if (os2)
+ font->is_serif = !(os2->sFamilyClass & 2048); /* Class 8 is sans-serif */
+
return font;
}
@@ -550,7 +561,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->ft_italic)
+ if (font->fake_italic)
fz_pre_shear(&local_trm, SHEAR, 0);
/*
@@ -595,7 +606,7 @@ do_ft_render_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *trm
goto retry_unhinted;
}
}
- else if (font->ft_hint)
+ else if (font->force_hinting)
{
/*
Enable hinting, but keep the huge char size so that
@@ -621,7 +632,7 @@ retry_unhinted:
}
}
- if (font->ft_bold)
+ if (font->fake_bold)
{
FT_Outline_Embolden(&face->glyph->outline, strength * 64);
FT_Outline_Translate(&face->glyph->outline, -strength * 32, -strength * 32);
@@ -710,7 +721,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->ft_italic)
+ if (font->fake_italic)
fz_pre_shear(&local_trm, SHEAR, 0);
m.xx = local_trm.a * 64; /* should be 65536 */
@@ -870,7 +881,7 @@ fz_bound_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_rect *bounds)
fz_adjust_ft_glyph_width(ctx, font, gid, &local_trm);
- if (font->ft_italic)
+ if (font->fake_italic)
fz_pre_shear(&local_trm, SHEAR, 0);
m.xx = local_trm.a * 65536;
@@ -880,7 +891,7 @@ fz_bound_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_rect *bounds)
v.x = local_trm.e * 65536;
v.y = local_trm.f * 65536;
- if (font->ft_hint)
+ if (font->force_hinting)
{
ft_flags = FT_LOAD_NO_BITMAP;
}
@@ -908,7 +919,7 @@ fz_bound_ft_glyph(fz_context *ctx, fz_font *font, int gid, fz_rect *bounds)
return bounds;
}
- if (font->ft_bold)
+ if (font->fake_bold)
{
FT_Outline_Embolden(&face->glyph->outline, strength * scale);
FT_Outline_Translate(&face->glyph->outline, -strength * 0.5 * scale, -strength * 0.5 * scale);
@@ -1010,12 +1021,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->ft_italic)
+ if (font->fake_italic)
fz_pre_shear(&local_trm, SHEAR, 0);
fz_lock(ctx, FZ_LOCK_FREETYPE);
- if (font->ft_hint)
+ if (font->force_hinting)
{
ft_flags = FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM;
fterr = FT_Set_Char_Size(face, scale, scale, 72, 72);
@@ -1035,7 +1046,7 @@ fz_outline_ft_glyph(fz_context *ctx, fz_font *font, int gid, const fz_matrix *tr
return NULL;
}
- if (font->ft_bold)
+ if (font->fake_bold)
{
FT_Outline_Embolden(&face->glyph->outline, strength * scale);
FT_Outline_Translate(&face->glyph->outline, -strength * 0.5 * scale, -strength * 0.5 * scale);
@@ -1459,7 +1470,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, 0, 0, 0);
+ font = fz_load_fallback_font(ctx, script, user_font->is_serif, user_font->is_bold, user_font->is_italic);
if (font)
{
gid = fz_encode_character(ctx, font, unicode);
diff --git a/source/html/html-font.c b/source/html/html-font.c
index bb356d6c..0612490c 100644
--- a/source/html/html-font.c
+++ b/source/html/html-font.c
@@ -23,6 +23,7 @@ fz_load_html_builtin_font(fz_context *ctx, fz_html_font_set *set, const char *fa
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]->is_serif = !is_sans;
}
return set->fonts[idx];
}
diff --git a/source/pdf/pdf-font.c b/source/pdf/pdf-font.c
index 41a4c279..2d8cf0bb 100644
--- a/source/pdf/pdf-font.c
+++ b/source/pdf/pdf-font.c
@@ -129,16 +129,6 @@ static int ft_kind(FT_Face face)
return UNKNOWN;
}
-static int ft_is_bold(FT_Face face)
-{
- return face->style_flags & FT_STYLE_FLAG_BOLD;
-}
-
-static int ft_is_italic(FT_Face face)
-{
- return face->style_flags & FT_STYLE_FLAG_ITALIC;
-}
-
static int ft_char_index(FT_Face face, int cid)
{
int gid = FT_Get_Char_Index(face, cid);
@@ -219,6 +209,7 @@ pdf_load_builtin_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontname,
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find builtin font: '%s'", fontname);
fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 1);
+ fontdesc->font->is_serif = !!strstr(clean_name, "Times");
}
if (!strcmp(clean_name, "Symbol") || !strcmp(clean_name, "ZapfDingbats"))
@@ -243,8 +234,13 @@ pdf_load_substitute_font(fz_context *ctx, pdf_font_desc *fontdesc, char *fontnam
fz_throw(ctx, FZ_ERROR_GENERIC, "cannot find substitute font");
fontdesc->font = fz_new_font_from_memory(ctx, fontname, data, len, 0, 1);
- fontdesc->font->ft_bold = bold && !ft_is_bold(fontdesc->font->ft_face);
- fontdesc->font->ft_italic = italic && !ft_is_italic(fontdesc->font->ft_face);
+ fontdesc->font->fake_bold = bold && !fontdesc->font->is_bold;
+ fontdesc->font->fake_italic = italic && !fontdesc->font->is_italic;
+
+ fontdesc->font->is_mono = mono;
+ fontdesc->font->is_serif = serif;
+ fontdesc->font->is_bold = bold;
+ fontdesc->font->is_italic = italic;
}
fontdesc->font->ft_substitute = 1;
@@ -1189,7 +1185,7 @@ pdf_load_font_descriptor(fz_context *ctx, pdf_document *doc, pdf_font_desc *font
if (ft_kind(face) == TRUETYPE)
{
if (FT_IS_TRICKY(face) || is_dynalab(fontdesc->font->name))
- fontdesc->font->ft_hint = 1;
+ fontdesc->font->force_hinting = 1;
if (fontdesc->ascent == 0.0f)
fontdesc->ascent = 1000.0f * face->ascender / face->units_per_EM;
diff --git a/source/xps/xps-glyphs.c b/source/xps/xps-glyphs.c
index 8cfbbafc..a87c2862 100644
--- a/source/xps/xps-glyphs.c
+++ b/source/xps/xps-glyphs.c
@@ -242,8 +242,10 @@ xps_lookup_font(fz_context *ctx, xps_document *doc, char *base_uri, char *font_u
if (style_att)
{
- font->ft_bold = !!strstr(style_att, "Bold");
- font->ft_italic = !!strstr(style_att, "Italic");
+ font->fake_bold = !!strstr(style_att, "Bold");
+ font->is_bold = font->fake_bold;
+ font->fake_italic = !!strstr(style_att, "Italic");
+ font->is_italic = font->fake_italic;
}
xps_select_best_font_encoding(ctx, doc, font);
@@ -421,7 +423,7 @@ xps_parse_glyphs_imp(fz_context *ctx, xps_document *doc, const fz_matrix *ctm,
else
advance = mtx.hadv * 100;
- if (font->ft_bold)
+ if (font->fake_bold)
advance *= 1.02f;
if (is && *is)