summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-10-14 07:39:49 +0200
committerTor Andersson <tor@ghostscript.com>2004-10-14 07:39:49 +0200
commitbbf53bb5172130d375ac4e6214c685d24120204b (patch)
tree354253a281a2cf91207da0038a4e1620e96c9b4c
parent21c12718cabdd7acad2a2ceccc938e0df659b4f9 (diff)
downloadmupdf-bbf53bb5172130d375ac4e6214c685d24120204b.tar.xz
stretch substituted fonts to match metrics
-rw-r--r--include/mupdf.h1
-rw-r--r--mupdf/font.c37
-rw-r--r--mupdf/fontfile.c29
-rw-r--r--render/glyphcache.c14
-rw-r--r--test/pdfrip.c7
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 = "";