diff options
-rw-r--r-- | include/mupdf.h | 1 | ||||
-rw-r--r-- | mupdf/font.c | 37 | ||||
-rw-r--r-- | mupdf/fontfile.c | 29 | ||||
-rw-r--r-- | render/glyphcache.c | 14 | ||||
-rw-r--r-- | test/pdfrip.c | 7 |
5 files changed, 66 insertions, 22 deletions
diff --git a/include/mupdf.h b/include/mupdf.h index 3c766740..2c423408 100644 --- a/include/mupdf.h +++ b/include/mupdf.h @@ -158,6 +158,7 @@ struct pdf_font_s fz_font super; void *ftface; + int substitute; /* FontDescriptor */ int flags; diff --git a/mupdf/font.c b/mupdf/font.c index b3f97f32..5ee65f4f 100644 --- a/mupdf/font.c +++ b/mupdf/font.c @@ -38,12 +38,44 @@ static int ftwidth(pdf_font *font, int cid) } static fz_error * -ftrender(fz_glyph *glyph, fz_font *font, int gid, fz_matrix trm) +ftrender(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm) { - FT_Face face = ((pdf_font*)font)->ftface; + pdf_font *font = (pdf_font*)fzfont; + FT_Face face = font->ftface; FT_Matrix m; FT_Vector v; FT_Error fterr; + int gid; + + if (fzfont->cidtogid) + gid = fzfont->cidtogid[cid]; + else + gid = cid; + + if (font->substitute && fzfont->wmode == 0) + { + fz_hmtx subw; + int realw; + float scale; + + FT_Set_Char_Size(face, 1000, 1000, 72, 72); + + fterr = FT_Load_Glyph(font->ftface, gid, + FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM); + if (fterr) + return fz_throw("freetype failed to load glyph: 0x%x", fterr); + + realw = ((FT_Face)font->ftface)->glyph->advance.x; + subw = fz_gethmtx(fzfont, cid); + if (realw) + scale = (float) subw.w / realw; + else + scale = 1.0; + + trm = fz_concat(fz_scale(scale, 1.0), trm); + + FT_Set_Char_Size(face, 64, 64, 72, 72); + } glyph->w = 0; glyph->h = 0; @@ -161,6 +193,7 @@ newfont(char *name) font->super.free = (void(*)(fz_font*)) ftfreefont; font->ftface = nil; + font->substitute = 0; font->flags = 0; font->italicangle = 0; diff --git a/mupdf/fontfile.c b/mupdf/fontfile.c index c0eeda9b..eef29c2f 100644 --- a/mupdf/fontfile.c +++ b/mupdf/fontfile.c @@ -8,6 +8,18 @@ static FT_Library ftlib = nil; static FcConfig *fclib = nil; +enum +{ + FD_FIXED = 1 << 0, + FD_SERIF = 1 << 1, + FD_SYMBOLIC = 1 << 2, + FD_SCRIPT = 1 << 3, + FD_NONSYMBOLIC = 1 << 5, + FD_ITALIC = 1 << 6, + FD_ALLCAP = 1 << 16, + FD_SMALLCAP = 1 << 17, +}; + static char *basenames[14] = { "Courier", @@ -159,6 +171,7 @@ pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection) error = fz_outofmem; + /* pattern from name */ if (!FcPatternAddString(searchpat, FC_FAMILY, fontname)) goto cleanup; if (collection) @@ -170,6 +183,10 @@ pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection) if (!FcPatternAddBool(searchpat, FC_OUTLINE, 1)) goto cleanup; + /* additional pattern from fd flags */ + FcPatternAddString(searchpat, FC_FAMILY, font->flags & FD_SERIF ? "serif" : "sans-serif"); + FcPatternAddString(searchpat, FC_STYLE, font->flags & FD_ITALIC ? "Italic" : "Regular"); + file = FcNameUnparse(searchpat); printf(" system font pattern %s\n", file); free(file); @@ -182,9 +199,15 @@ free(file); if (fcerr != FcResultMatch) return fz_throw("fontconfig could not find font %s", basefont); -file = FcNameUnparse(matchpat); -printf(" system found %s\n", file); -free(file); + fcerr = FcPatternGetString(matchpat, FC_FAMILY, 0, (FcChar8**)&file); + if (file && strcmp(fontname, file)) + font->substitute = 1; + + fcerr = FcPatternGetString(matchpat, FC_STYLE, 0, (FcChar8**)&file); + if (file && style && strcmp(style, file)) + font->substitute = 1; + +printf(" is a substituted font\n"); fcerr = FcPatternGetString(matchpat, FC_FILE, 0, (FcChar8**)&file); if (fcerr != FcResultMatch) diff --git a/render/glyphcache.c b/render/glyphcache.c index 23fb5dd1..beb77ccc 100644 --- a/render/glyphcache.c +++ b/render/glyphcache.c @@ -23,7 +23,7 @@ struct fz_key_s void *fid; int a, b; int c, d; - unsigned short gid; + unsigned short cid; unsigned char e, f; }; @@ -233,7 +233,7 @@ fz_debugglyphcache(fz_glyphcache *arena) fz_val *b = arena->hash[i].val; printf("glyph % 4d: %p %d [%g %g %g %g + %d %d] " "-> [%dx%d %d,%d]\n", i, - k->fid, k->gid, + k->fid, k->cid, k->a / 65536.0, k->b / 65536.0, k->c / 65536.0, @@ -303,15 +303,9 @@ fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz fz_key key; fz_val *val; int size; - int gid; - - if (font->cidtogid) - gid = font->cidtogid[cid]; - else - gid = cid; key.fid = font; - key.gid = gid; + key.cid = cid; key.a = ctm.a * 65536; key.b = ctm.b * 65536; key.c = ctm.c * 65536; @@ -337,7 +331,7 @@ fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz ctm.e = floor(ctm.e) + key.e / HSUBPIX; ctm.f = floor(ctm.f) + key.f / HSUBPIX; - error = font->render(glyph, font, gid, ctm); + error = font->render(glyph, font, cid, ctm); if (error) return error; diff --git a/test/pdfrip.c b/test/pdfrip.c index 68276fb2..f0785055 100644 --- a/test/pdfrip.c +++ b/test/pdfrip.c @@ -53,12 +53,6 @@ void showpage(pdf_xref *xref, fz_obj *page) else fz_abort(fz_throw("syntaxerror: missing resource dictionary")); -printf("resources:\n"); -printf(" font:\n"); -fz_debugobj(rdb->font); -printf("\n extgstate:\n"); -fz_debugobj(rdb->extgstate); - error = pdf_newcsi(&csi); if (error) fz_abort(error); @@ -125,7 +119,6 @@ int main(int argc, char **argv) char *filename; pdf_xref *xref; pdf_pagetree *pages; - int d; int c; char *password = ""; |