diff options
-rw-r--r-- | include/fitz/font.h | 18 | ||||
-rw-r--r-- | include/fitz/text.h | 2 | ||||
-rw-r--r-- | include/mupdf.h | 26 | ||||
-rw-r--r-- | mupdf/build.c | 28 | ||||
-rw-r--r-- | mupdf/cmap.c | 4 | ||||
-rw-r--r-- | mupdf/font.c | 147 | ||||
-rw-r--r-- | mupdf/fontfile.c | 84 | ||||
-rw-r--r-- | render/glyphcache.c | 8 | ||||
-rw-r--r-- | render/render.c | 22 | ||||
-rw-r--r-- | tree/debug.c | 5 | ||||
-rw-r--r-- | tree/font.c | 51 | ||||
-rw-r--r-- | tree/text.c | 4 |
12 files changed, 222 insertions, 177 deletions
diff --git a/include/fitz/font.h b/include/fitz/font.h index 743d87fa..b915755b 100644 --- a/include/fitz/font.h +++ b/include/fitz/font.h @@ -6,13 +6,15 @@ typedef struct fz_glyphcache_s fz_glyphcache; struct fz_hmtx_s { - unsigned short c; + unsigned short lo; + unsigned short hi; short w; }; struct fz_vmtx_s { - unsigned short c; + unsigned short lo; + unsigned short hi; short x; short y; short w; @@ -35,6 +37,9 @@ struct fz_font_s int nvmtx, vmtxcap; fz_vmtx dvmtx; fz_vmtx *vmtx; + + int ncidtogid; + unsigned short *cidtogid; }; struct fz_glyph_s @@ -48,14 +53,15 @@ void fz_freefont(fz_font *font); void fz_debugfont(fz_font *font); void fz_setfontwmode(fz_font *font, int wmode); void fz_setfontbbox(fz_font *font, int xmin, int ymin, int xmax, int ymax); +void fz_setcidtogid(fz_font *font, int n, unsigned short *map); void fz_setdefaulthmtx(fz_font *font, int w); void fz_setdefaultvmtx(fz_font *font, int y, int w); -fz_error *fz_addhmtx(fz_font *font, int gid, int w); -fz_error *fz_addvmtx(fz_font *font, int gid, int x, int y, int w); +fz_error *fz_addhmtx(fz_font *font, int lo, int hi, int w); +fz_error *fz_addvmtx(fz_font *font, int lo, int hi, int x, int y, int w); fz_error *fz_endhmtx(fz_font *font); fz_error *fz_endvmtx(fz_font *font); -fz_hmtx fz_gethmtx(fz_font *font, int gid); -fz_vmtx fz_getvmtx(fz_font *font, int gid); +fz_hmtx fz_gethmtx(fz_font *font, int cid); +fz_vmtx fz_getvmtx(fz_font *font, int cid); fz_error *fz_newglyphcache(fz_glyphcache **arenap, int slots, int size); fz_error *fz_renderglyph(fz_glyphcache*, fz_glyph*, fz_font*, int, fz_matrix); diff --git a/include/fitz/text.h b/include/fitz/text.h index c28d96c7..1a321f8f 100644 --- a/include/fitz/text.h +++ b/include/fitz/text.h @@ -3,7 +3,7 @@ typedef struct fz_textel_s fz_textel; struct fz_textel_s { float x, y; - int g; + int cid; }; struct fz_textnode_s diff --git a/include/mupdf.h b/include/mupdf.h index 29f0754b..3c766740 100644 --- a/include/mupdf.h +++ b/include/mupdf.h @@ -159,13 +159,21 @@ struct pdf_font_s void *ftface; + /* FontDescriptor */ + int flags; + float italicangle; + float ascent; + float descent; + float capheight; + float xheight; + float missingwidth; + + /* Encoding (CMap) */ fz_cmap *encoding; - int cidtogidlen; - int *cidtogidmap; + /* Raw data for freetype */ char *filename; - char *fontdata; - int fontlen; + fz_buffer *fontdata; }; struct pdf_type3_s @@ -250,13 +258,13 @@ void pdf_freepagetree(pdf_pagetree *pages); fz_error *pdf_parsecmap(fz_cmap **cmapp, fz_file *file); fz_error *pdf_loadembeddedcmap(fz_cmap **cmapp, pdf_xref *xref, fz_obj *stmref); fz_error *pdf_loadsystemcmap(fz_cmap **cmapp, char *name); -fz_error *pdf_makeidentitycmap(fz_cmap **cmapp, int wmode); +fz_error *pdf_makeidentitycmap(fz_cmap **cmapp, int wmode, int bytes); /* fontfile.c */ -fz_error *pdf_loadbuiltinfont(void **fontp, char *pattern); -fz_error *pdf_loadsystemfont(void **fontp, char *basefont, char *collection); -fz_error *pdf_loadembeddedfont(void **fontp, pdf_xref *xref, fz_obj *stmref); -fz_error *pdf_loadfontdescriptor(void **fontp, pdf_xref *xref, fz_obj *desc, char *collection); +fz_error *pdf_loadbuiltinfont(pdf_font *font, char *basefont); +fz_error *pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection); +fz_error *pdf_loadsubstitutefont(pdf_font *font, int fdflags, char *collection); +fz_error *pdf_loadfontdescriptor(pdf_font *font, pdf_xref *xref, fz_obj *desc, char *collection); /* font.c */ fz_error *pdf_loadfont(pdf_font **fontp, pdf_xref *xref, fz_obj *font); diff --git a/mupdf/build.c b/mupdf/build.c index dfca7446..0e65f6a4 100644 --- a/mupdf/build.c +++ b/mupdf/build.c @@ -219,7 +219,7 @@ pdf_flushtext(pdf_csi *csi) } fz_error * -showglyph(pdf_csi *csi, int g) +showglyph(pdf_csi *csi, int cid) { pdf_gstate *gstate = csi->gstate + csi->gtop; pdf_font *font = gstate->font; @@ -240,7 +240,7 @@ showglyph(pdf_csi *csi, int g) if (font->super.wmode == 1) { - v = fz_getvmtx((fz_font*)font, g); + v = fz_getvmtx((fz_font*)font, cid); tm.e -= v.x * gstate->size / 1000.0; tm.f += v.y * gstate->size / 1000.0; } @@ -267,13 +267,13 @@ showglyph(pdf_csi *csi, int g) } /* add glyph to textobject */ - error = fz_addtext(csi->text, g, trm.e, trm.f); + error = fz_addtext(csi->text, cid, trm.e, trm.f); if (error) return error; if (font->super.wmode == 0) { - h = fz_gethmtx((fz_font*)font, g); + h = fz_gethmtx((fz_font*)font, cid); w0 = h.w / 1000.0; tx = (w0 * gstate->size + gstate->charspace) * gstate->scale; csi->tm = fz_concat(fz_translate(tx, 0), csi->tm); @@ -308,7 +308,7 @@ pdf_showtext(pdf_csi *csi, fz_obj *text) unsigned char *buf; unsigned char *end; int i, len; - int cpt, cid, gid; + int cpt, cid; if (fz_isarray(text)) { @@ -338,24 +338,12 @@ pdf_showtext(pdf_csi *csi, fz_obj *text) cid = fz_lookupcid(font->encoding, cpt); - if (font->cidtogidmap) - { - if (cid >= 0 && cid < font->cidtogidlen) - gid = font->cidtogidmap[cid]; - else - gid = 0; - } - else - { - gid = cid; - } - -//printf("gl %s %g [%g %g %g %g %g %g] cpt<%02x> cid %d gid %d h %d\n", +//printf("gl %s %g [%g %g %g %g %g %g] cpt<%02x> cid %d h %d\n", // font->super.name, size, // csi->tm.a, csi->tm.b, csi->tm.c, csi->tm.d, csi->tm.e, csi->tm.f, -// cpt, cid, gid, font->super.hadv[gid]); +// cpt, cid, font->super.hadv[gid]); - error = showglyph(csi, gid); + error = showglyph(csi, cid); if (error) return error; diff --git a/mupdf/cmap.c b/mupdf/cmap.c index 54ee5b0f..ceedcf59 100644 --- a/mupdf/cmap.c +++ b/mupdf/cmap.c @@ -488,7 +488,7 @@ cleanup: } fz_error * -pdf_makeidentitycmap(fz_cmap **cmapp, int wmode) +pdf_makeidentitycmap(fz_cmap **cmapp, int wmode, int bytes) { fz_error *error = nil; @@ -496,7 +496,7 @@ pdf_makeidentitycmap(fz_cmap **cmapp, int wmode) if (error) return error; - error = fz_addcodespacerange(*cmapp, 0x0000, 0xffff, 2); + error = fz_addcodespacerange(*cmapp, 0x0000, 0xffff, bytes); if (error) { fz_freecmap(*cmapp); return error; diff --git a/mupdf/font.c b/mupdf/font.c index 258dbe2a..b3f97f32 100644 --- a/mupdf/font.c +++ b/mupdf/font.c @@ -25,14 +25,16 @@ printf(" type %s\n", kind); return UNKNOWN; } -static int ftwidth(FT_Face face, int gid) +static int ftwidth(pdf_font *font, int cid) { int e; - e = FT_Load_Glyph(face, gid, + if (font->super.cidtogid) + cid = font->super.cidtogid[cid]; + e = FT_Load_Glyph(font->ftface, cid, FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM); if (e) return 0; - return face->glyph->advance.x; + return ((FT_Face)font->ftface)->glyph->advance.x; } static fz_error * @@ -138,17 +140,6 @@ static int mrecode(char *name) return -1; } -static int cidtogid(pdf_font *font, int cid) -{ - if (font->cidtogidmap) - { - if (cid >= 0 && cid < font->cidtogidlen) - return font->cidtogidmap[cid]; - return 0; - } - return cid; -} - static void ftfreefont(fz_font *font) { pdf_font *pfont = (pdf_font*)font; @@ -170,9 +161,19 @@ newfont(char *name) font->super.free = (void(*)(fz_font*)) ftfreefont; font->ftface = nil; + + font->flags = 0; + font->italicangle = 0; + font->ascent = 0; + font->descent = 0; + font->capheight = 0; + font->xheight = 0; + font->missingwidth = 0; + font->encoding = nil; - font->cidtogidlen = 0; - font->cidtogidmap = nil; + + font->filename = nil; + font->fontdata = nil; return font; } @@ -184,14 +185,15 @@ loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict) fz_obj *descriptor = nil; fz_obj *encoding = nil; fz_obj *widths = nil; + unsigned short *etable = nil; pdf_font *font; FT_Face face; FT_CharMap cmap; int kind; + int symbolic; char *basefont; char *estrings[256]; - int etable[256]; int i, k, n, e; basefont = fz_toname(fz_dictgets(dict, "BaseFont")); @@ -209,15 +211,17 @@ printf("loading simple font %s\n", basefont); descriptor = fz_dictgets(dict, "FontDescriptor"); if (descriptor) - error = pdf_loadfontdescriptor(&font->ftface, xref, descriptor, nil); + error = pdf_loadfontdescriptor(font, xref, descriptor, nil); else - error = pdf_loadsystemfont(&font->ftface, basefont, nil); + error = pdf_loadbuiltinfont(font, basefont); if (error) goto cleanup; face = font->ftface; kind = ftkind(face); + symbolic = font->flags & 4; + fz_setfontbbox((fz_font*)font, face->bbox.xMin, face->bbox.yMin, face->bbox.xMax, face->bbox.yMax); @@ -263,6 +267,10 @@ printf("loading simple font %s\n", basefont); goto cleanup; } + etable = fz_malloc(sizeof(unsigned short) * 256); + if (!etable) + goto cleanup; + for (i = 0; i < 256; i++) { estrings[i] = _notdef; @@ -270,13 +278,12 @@ printf("loading simple font %s\n", basefont); } encoding = fz_dictgets(dict, "Encoding"); - if (encoding) + if (encoding && !(kind == TRUETYPE && symbolic)) { error = pdf_resolve(&encoding, xref); if (error) goto cleanup; - if (fz_isname(encoding)) loadencoding(estrings, fz_toname(encoding)); @@ -321,6 +328,7 @@ printf("loading simple font %s\n", basefont); /* Unicode cmap */ if (face->charmap->platform_id == 3) { +printf(" winansi cmap\n"); for (i = 0; i < 256; i++) if (estrings[i]) { @@ -337,6 +345,7 @@ printf("loading simple font %s\n", basefont); /* MacRoman cmap */ else if (face->charmap->platform_id == 1) { +printf(" macroman cmap\n"); for (i = 0; i < 256; i++) if (estrings[i]) { @@ -353,6 +362,7 @@ printf("loading simple font %s\n", basefont); /* Symbolic cmap */ else { +printf(" symbolic cmap\n"); for (i = 0; i < 256; i++) etable[i] = FT_Get_Char_Index(face, i); } @@ -363,27 +373,22 @@ printf("loading simple font %s\n", basefont); else { +printf(" builtin encoding\n"); for (i = 0; i < 256; i++) etable[i] = FT_Get_Char_Index(face, i); } - error = fz_newcmap(&font->encoding); - if (error) - goto cleanup; - - error = fz_addcodespacerange(font->encoding, 0x00, 0xff, 1); + error = pdf_makeidentitycmap(&font->encoding, 0, 1); if (error) goto cleanup; - error = fz_setcidlookup(font->encoding, etable); - if (error) - goto cleanup; + fz_setcidtogid((fz_font*)font, 256, etable); /* * Widths */ - /* FIXME should set defaulthmtx to MissingWidth in FontDescriptor */ + fz_setdefaulthmtx((fz_font*)font, font->missingwidth); widths = fz_dictgets(dict, "Widths"); if (widths) @@ -404,14 +409,10 @@ printf(" widths vector %d to %d\n", first, last); for (i = 0; i < last - first + 1; i++) { - int gid = etable[i + first]; int wid = fz_toint(fz_arrayget(widths, i)); - if (gid >= 0) - { - error = fz_addhmtx((fz_font*)font, gid, wid); - if (error) - goto cleanup; - } + error = fz_addhmtx((fz_font*)font, i + first, i + first, wid); + if (error) + goto cleanup; } widths = fz_dropobj(widths); @@ -422,13 +423,9 @@ printf(" builtin widths\n"); FT_Set_Char_Size(face, 1000, 1000, 72, 72); for (i = 0; i < 256; i++) { - int gid = etable[i]; - if (gid >= 0) - { - error = fz_addhmtx((fz_font*)font, gid, ftwidth(face, gid)); - if (error) - goto cleanup; - } + error = fz_addhmtx((fz_font*)font, i, i, ftwidth(font, i)); + if (error) + goto cleanup; } } @@ -440,11 +437,10 @@ printf(" builtin widths\n"); printf("\n"); -fz_debugfont((fz_font*)font); - return nil; cleanup: + fz_free(etable); if (widths) fz_dropobj(widths); fz_freefont((fz_font*)font); @@ -514,7 +510,7 @@ printf(" collection %s\n", collection); descriptor = fz_dictgets(dict, "FontDescriptor"); if (descriptor) - error = pdf_loadfontdescriptor(&font->ftface, xref, descriptor, collection); + error = pdf_loadfontdescriptor(font, xref, descriptor, collection); else error = fz_throw("syntaxerror: missing font descriptor"); if (error) @@ -535,9 +531,9 @@ printf(" collection %s\n", collection); { printf(" external CMap %s\n", fz_toname(encoding)); if (!strcmp(fz_toname(encoding), "Identity-H")) - error = pdf_makeidentitycmap(&font->encoding, 0); + error = pdf_makeidentitycmap(&font->encoding, 0, 2); else if (!strcmp(fz_toname(encoding), "Identity-V")) - error = pdf_makeidentitycmap(&font->encoding, 1); + error = pdf_makeidentitycmap(&font->encoding, 1, 2); else error = pdf_loadsystemcmap(&font->encoding, fz_toname(encoding)); } @@ -562,6 +558,7 @@ printf(" embedded CMap\n"); cidtogidmap = fz_dictgets(dict, "CIDToGIDMap"); if (fz_isindirect(cidtogidmap)) { + unsigned short *map; fz_buffer *buf; int len; @@ -569,11 +566,10 @@ printf(" embedded CMap\n"); if (error) goto cleanup; - len = buf->wp - buf->rp; + len = (buf->wp - buf->rp) / 2; - font->cidtogidlen = len / 2; - font->cidtogidmap = fz_malloc((len / 2) * sizeof(int)); - if (!font->cidtogidmap) { + map = fz_malloc(len * sizeof(unsigned short)); + if (!map) { fz_freebuffer(buf); error = fz_outofmem; goto cleanup; @@ -581,15 +577,16 @@ printf(" embedded CMap\n"); printf(" cidtogidmap %d\n", len / 2); - for (i = 0; i < len / 2; i++) - font->cidtogidmap[i] = (buf->rp[i * 2] << 8) + buf->rp[i * 2 + 1]; + for (i = 0; i < len; i++) + map[i] = (buf->rp[i * 2] << 8) + buf->rp[i * 2 + 1]; + + fz_setcidtogid((fz_font*)font, len, map); fz_freebuffer(buf); } /* TODO: if truetype font is external, cidtogidmap should not be identity */ /* we should map the cid to another encoding represented by a 'cmap' table */ - /* and then through that to a gid */ /* cids: Adobe-CNS1 Adobe-GB1 Adobe-Japan1 Adobe-Japan2 Adobe-Korea1 */ /* cmap: Big5 Johab PRC ShiftJIS Unicode Wansung */ /* win: 3,4 3,6 3,3 3,2 3,1 3,5 */ @@ -604,7 +601,7 @@ printf(" cidtogidmap %d\n", len / 2); widths = fz_dictgets(dict, "W"); if (widths) { - int c0, c1, w, gid; + int c0, c1, w; fz_obj *obj; error = pdf_resolve(&widths, xref); @@ -620,8 +617,7 @@ printf(" cidtogidmap %d\n", len / 2); for (k = 0; k < fz_arraylen(obj); k++) { w = fz_toint(fz_arrayget(obj, k)); - gid = cidtogid(font, c0 + k); - error = fz_addhmtx((fz_font*)font, gid, w); + error = fz_addhmtx((fz_font*)font, c0 + k, c0 + k, w); if (error) goto cleanup; } @@ -631,13 +627,9 @@ printf(" cidtogidmap %d\n", len / 2); { c1 = fz_toint(obj); w = fz_toint(fz_arrayget(widths, i + 2)); - for (k = c0; k <= c1; k++) - { - gid = cidtogid(font, k); - error = fz_addhmtx((fz_font*)font, gid, w); - if (error) - goto cleanup; - } + error = fz_addhmtx((fz_font*)font, c0, c1, w); + if (error) + goto cleanup; i += 3; } } @@ -671,15 +663,15 @@ printf(" cidtogidmap %d\n", len / 2); widths = fz_dictgets(dict, "W2"); if (widths) { - int c0, c1, w, x, y, k, gid; + int c0, c1, w, x, y, k; error = pdf_resolve(&widths, xref); if (error) goto cleanup; -printf(" W2 "); -fz_debugobj(widths); -printf("\n"); +//printf(" W2 "); +//fz_debugobj(widths); +//printf("\n"); for (i = 0; i < fz_arraylen(widths); ) { @@ -692,8 +684,7 @@ printf("\n"); w = fz_toint(fz_arrayget(obj, k + 0)); x = fz_toint(fz_arrayget(obj, k + 1)); y = fz_toint(fz_arrayget(obj, k + 2)); - gid = cidtogid(font, c0 + k); - error = fz_addvmtx((fz_font*)font, gid, x, y, w); + error = fz_addvmtx((fz_font*)font, c0 + k, c0 + k, x, y, w); if (error) goto cleanup; } @@ -705,13 +696,9 @@ printf("\n"); w = fz_toint(fz_arrayget(widths, i + 2)); x = fz_toint(fz_arrayget(widths, i + 3)); y = fz_toint(fz_arrayget(widths, i + 4)); - for (k = c0; k <= c1; k++) - { - gid = cidtogid(font, c0); - error = fz_addvmtx((fz_font*)font, gid, x, y, w); - if (error) - goto cleanup; - } + error = fz_addvmtx((fz_font*)font, c0, c1, x, y, w); + if (error) + goto cleanup; i += 5; } } @@ -728,7 +715,7 @@ printf("\n"); printf("\n"); -fz_debugfont((fz_font*)font); +//fz_debugfont((fz_font*)font); return nil; diff --git a/mupdf/fontfile.c b/mupdf/fontfile.c index 99414b90..c0eeda9b 100644 --- a/mupdf/fontfile.c +++ b/mupdf/fontfile.c @@ -28,18 +28,18 @@ static char *basenames[14] = static char *basepatterns[14] = { - "Courier,Nimbus Mono L,Courier New:style=Regular,Roman", - "Courier,Nimbus Mono L,Courier New:style=Bold", - "Courier,Nimbus Mono L,Courier New:style=Oblique,Italic", - "Courier,Nimbus Mono L,Courier New:style=BoldOblique,BoldItalic", - "Helvetica,Nimbus Sans L,Arial:style=Regular,Roman", - "Helvetica,Nimbus Sans L,Arial:style=Bold", - "Helvetica,Nimbus Sans L,Arial:style=Oblique,Italic", - "Helvetica,Nimbus Sans L,Arial:style=BoldOblique,BoldItalic", - "Times,Nimbus Roman No9 L,Times New Roman:style=Regular,Roman", - "Times,Nimbus Roman No9 L,Times New Roman:style=Bold,Medium", - "Times,Nimbus Roman No9 L,Times New Roman:style=Italic,Regular Italic", - "Times,Nimbus Roman No9 L,Times New Roman:style=BoldItalic,Medium Italic", + "Nimbus Mono L,Courier,Courier New:style=Regular,Roman", + "Nimbus Mono L,Courier,Courier New:style=Bold", + "Nimbus Mono L,Courier,Courier New:style=Oblique,Italic", + "Nimbus Mono L,Courier,Courier New:style=BoldOblique,BoldItalic", + "Nimbus Sans L,Helvetica,Arial:style=Regular,Roman", + "Nimbus Sans L,Helvetica,Arial:style=Bold", + "Nimbus Sans L,Helvetica,Arial:style=Oblique,Italic", + "Nimbus Sans L,Helvetica,Arial:style=BoldOblique,BoldItalic", + "Nimbus Roman No9 L,Times,Times New Roman:style=Regular,Roman", + "Nimbus Roman No9 L,Times,Times New Roman:style=Bold,Medium", + "Nimbus Roman No9 L,Times,Times New Roman:style=Italic,Regular Italic", + "Nimbus Roman No9 L,Times,Times New Roman:style=BoldItalic,Medium Italic", "Standard Symbols L,Symbol", "Zapf Dingbats,Dingbats" }; @@ -68,7 +68,7 @@ static fz_error *initfontlibs(void) } fz_error * -pdf_loadbuiltinfont(void **fontp, char *pattern) +pdf_loadbuiltinfont(pdf_font *font, char *basefont) { fz_error *error; FcResult fcerr; @@ -77,12 +77,20 @@ pdf_loadbuiltinfont(void **fontp, char *pattern) FcPattern *searchpat; FcPattern *matchpat; FT_Face face; + char *pattern; char *file; + int index; + int i; error = initfontlibs(); if (error) return error; + pattern = basefont; + for (i = 0; i < 14; i++) + if (!strcmp(basefont, basenames[i])) + pattern = basepatterns[i]; + fcerr = FcResultMatch; searchpat = FcNameParse(pattern); FcDefaultSubstitute(searchpat); @@ -92,24 +100,29 @@ pdf_loadbuiltinfont(void **fontp, char *pattern) if (fcerr != FcResultMatch) return fz_throw("fontconfig could not find font %s", pattern); - fcerr = FcPatternGetString(matchpat, "file", 0, (FcChar8**)&file); + fcerr = FcPatternGetString(matchpat, FC_FILE, 0, (FcChar8**)&file); if (fcerr != FcResultMatch) return fz_throw("fontconfig could not find font %s", pattern); - fterr = FT_New_Face(ftlib, file, 0, &face); + index = 0; + fcerr = FcPatternGetInteger(matchpat, FC_INDEX, 0, &index); + +printf(" builtin font %s idx %d\n", file, index); + + fterr = FT_New_Face(ftlib, file, index, &face); if (fterr) return fz_throw("freetype could not load font file '%s': 0x%x", file, fterr); FcPatternDestroy(matchpat); FcPatternDestroy(searchpat); - *fontp = face; + font->ftface = face; return nil; } fz_error * -pdf_loadsystemfont(void **fontp, char *basefont, char *collection) +pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection) { fz_error *error; FcResult fcerr; @@ -121,6 +134,7 @@ pdf_loadsystemfont(void **fontp, char *basefont, char *collection) FT_Face face; char *style; char *file; + int index; error = initfontlibs(); if (error) @@ -168,13 +182,20 @@ free(file); if (fcerr != FcResultMatch) return fz_throw("fontconfig could not find font %s", basefont); - fcerr = FcPatternGetString(matchpat, "file", 0, (FcChar8**)&file); +file = FcNameUnparse(matchpat); +printf(" system found %s\n", file); +free(file); + + fcerr = FcPatternGetString(matchpat, FC_FILE, 0, (FcChar8**)&file); if (fcerr != FcResultMatch) return fz_throw("fontconfig could not find font %s", basefont); -printf(" system font file %s\n", file); + index = 0; + fcerr = FcPatternGetInteger(matchpat, FC_INDEX, 0, &index); + +printf(" system font file %s idx %d\n", file, index); - fterr = FT_New_Face(ftlib, file, 0, &face); + fterr = FT_New_Face(ftlib, file, index, &face); if (fterr) { FcPatternDestroy(matchpat); FcPatternDestroy(searchpat); @@ -184,7 +205,7 @@ printf(" system font file %s\n", file); FcPatternDestroy(matchpat); FcPatternDestroy(searchpat); - *fontp = face; + font->ftface = face; return nil; @@ -194,7 +215,7 @@ cleanup: } fz_error * -pdf_loadembeddedfont(void **fontp, pdf_xref *xref, fz_obj *stmref) +pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref) { fz_error *error; int fterr; @@ -216,15 +237,14 @@ pdf_loadembeddedfont(void **fontp, pdf_xref *xref, fz_obj *stmref) return fz_throw("freetype could not load embedded font: 0x%x", fterr); } - *fontp = face; - - /* TODO: figure out how to free 'buf' when the FT_Face is freed */ + font->ftface = face; + font->fontdata = buf; return nil; } fz_error * -pdf_loadfontdescriptor(void **facep, pdf_xref *xref, fz_obj *desc, char *collection) +pdf_loadfontdescriptor(pdf_font *font, pdf_xref *xref, fz_obj *desc, char *collection) { fz_error *error; fz_obj *obj1, *obj2, *obj3, *obj; @@ -236,6 +256,14 @@ pdf_loadfontdescriptor(void **facep, pdf_xref *xref, fz_obj *desc, char *collect fontname = fz_toname(fz_dictgets(desc, "FontName")); + font->flags = fz_toint(fz_dictgets(desc, "Flags")); + font->italicangle = fz_toreal(fz_dictgets(desc, "ItalicAngle")); + font->ascent = fz_toreal(fz_dictgets(desc, "Ascent")); + font->descent = fz_toreal(fz_dictgets(desc, "Descent")); + font->capheight = fz_toreal(fz_dictgets(desc, "CapHeight")); + font->xheight = fz_toreal(fz_dictgets(desc, "XHeight")); + font->missingwidth = fz_toreal(fz_dictgets(desc, "MissingWidth")); + obj1 = fz_dictgets(desc, "FontFile"); obj2 = fz_dictgets(desc, "FontFile2"); obj3 = fz_dictgets(desc, "FontFile3"); @@ -243,13 +271,13 @@ pdf_loadfontdescriptor(void **facep, pdf_xref *xref, fz_obj *desc, char *collect if (fz_isindirect(obj)) { - error = pdf_loadembeddedfont(facep, xref, obj); + error = pdf_loadembeddedfont(font, xref, obj); if (error) goto cleanup; } else { - error = pdf_loadsystemfont(facep, fontname, collection); + error = pdf_loadsystemfont(font, fontname, collection); if (error) goto cleanup; } diff --git a/render/glyphcache.c b/render/glyphcache.c index 81b1f5d5..23fb5dd1 100644 --- a/render/glyphcache.c +++ b/render/glyphcache.c @@ -297,12 +297,18 @@ evictlast(fz_glyphcache *arena) } fz_error * -fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int gid, fz_matrix ctm) +fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz_matrix ctm) { fz_error *error; 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; diff --git a/render/render.c b/render/render.c index 1e152410..183672bf 100644 --- a/render/render.c +++ b/render/render.c @@ -145,7 +145,7 @@ puts("render text"); for (i = 0; i < text->len; i++) { - g = text->els[i].g; + g = text->els[i].cid; x = text->els[i].x; y = text->els[i].y; @@ -188,7 +188,7 @@ puts("render (mask color text)"); for (i = 0; i < text->len; i++) { - g = text->els[i].g; + g = text->els[i].cid; x = text->els[i].x; y = text->els[i].y; @@ -239,17 +239,19 @@ fz_renderpath(fz_renderer *gc, fz_pathnode *path, fz_matrix ctm) puts("render path"); - fz_resetgel(gc->gel, 17, 15); + float flatness = 0.3 / ctm.a; + + fz_resetgel(gc->gel, 16, 16); if (path->paint == FZ_STROKE) { if (path->dash) - fz_dashpath(gc->gel, path, ctm, 0.2); + fz_dashpath(gc->gel, path, ctm, flatness); else - fz_strokepath(gc->gel, path, ctm, 0.2); + fz_strokepath(gc->gel, path, ctm, flatness); } else - fz_fillpath(gc->gel, path, ctm, 0.2); + fz_fillpath(gc->gel, path, ctm, flatness); fz_sortgel(gc->gel); @@ -301,17 +303,19 @@ rcolorpath(fz_renderer *gc, fz_pathnode *path, fz_colornode *color, fz_matrix ct { puts("render (mask color path)"); + float flatness = 0.3 / ctm.a; + fz_resetgel(gc->gel, 17, 15); if (path->paint == FZ_STROKE) { if (path->dash) - fz_dashpath(gc->gel, path, ctm, 0.2); + fz_dashpath(gc->gel, path, ctm, flatness); else - fz_strokepath(gc->gel, path, ctm, 0.2); + fz_strokepath(gc->gel, path, ctm, flatness); } else - fz_fillpath(gc->gel, path, ctm, 0.2); + fz_fillpath(gc->gel, path, ctm, flatness); fz_sortgel(gc->gel); diff --git a/tree/debug.c b/tree/debug.c index b10eacad..c56464ba 100644 --- a/tree/debug.c +++ b/tree/debug.c @@ -124,7 +124,10 @@ static void lisptext(fz_textnode *node, int level) for (i = 0; i < node->len; i++) { indent(level + 1); - printf("(g %d %g %g)\n", node->els[i].g, node->els[i].x, node->els[i].y); + if (node->els[i].cid >= 32 && node->els[i].cid < 128) + printf("(cid '%c' %g %g)\n", node->els[i].cid, node->els[i].x, node->els[i].y); + else + printf("(cid <%04x> %g %g)\n", node->els[i].cid, node->els[i].x, node->els[i].y); } indent(level); diff --git a/tree/font.c b/tree/font.c index 9ddbad04..207896c5 100644 --- a/tree/font.c +++ b/tree/font.c @@ -19,13 +19,18 @@ fz_initfont(fz_font *font, char *name) font->hmtx = nil; font->vmtx = nil; - font->dhmtx.c = 0x0000; + font->dhmtx.lo = 0x0000; + font->dhmtx.hi = 0xFFFF; font->dhmtx.w = 0; - font->dvmtx.c = 0x0000; + font->dvmtx.lo = 0x0000; + font->dvmtx.hi = 0xFFFF; font->dvmtx.x = 0; font->dvmtx.y = 880; font->dvmtx.w = -1000; + + font->ncidtogid = 0; + font->cidtogid = nil; } void @@ -44,6 +49,13 @@ fz_setfontbbox(fz_font *font, int xmin, int ymin, int xmax, int ymax) } void +fz_setcidtogid(fz_font *font, int n, unsigned short *map) +{ + font->ncidtogid = n; + font->cidtogid = map; +} + +void fz_setdefaulthmtx(fz_font *font, int w) { font->dhmtx.w = w; @@ -57,7 +69,7 @@ fz_setdefaultvmtx(fz_font *font, int y, int w) } fz_error * -fz_addhmtx(fz_font *font, int c, int w) +fz_addhmtx(fz_font *font, int lo, int hi, int w) { int newcap; fz_hmtx *newmtx; @@ -72,7 +84,8 @@ fz_addhmtx(fz_font *font, int c, int w) font->hmtx = newmtx; } - font->hmtx[font->nhmtx].c = c; + font->hmtx[font->nhmtx].lo = lo; + font->hmtx[font->nhmtx].hi = hi; font->hmtx[font->nhmtx].w = w; font->nhmtx++; @@ -80,7 +93,7 @@ fz_addhmtx(fz_font *font, int c, int w) } fz_error * -fz_addvmtx(fz_font *font, int c, int x, int y, int w) +fz_addvmtx(fz_font *font, int lo, int hi, int x, int y, int w) { int newcap; fz_vmtx *newmtx; @@ -95,7 +108,8 @@ fz_addvmtx(fz_font *font, int c, int x, int y, int w) font->vmtx = newmtx; } - font->vmtx[font->nvmtx].c = c; + font->vmtx[font->nvmtx].lo = lo; + font->vmtx[font->nvmtx].hi = hi; font->vmtx[font->nvmtx].x = x; font->vmtx[font->nvmtx].y = y; font->vmtx[font->nvmtx].w = w; @@ -108,14 +122,14 @@ static int cmph(const void *a0, const void *b0) { fz_hmtx *a = (fz_hmtx*)a0; fz_hmtx *b = (fz_hmtx*)b0; - return a->c - b->c; + return a->lo - b->lo; } static int cmpv(const void *a0, const void *b0) { fz_vmtx *a = (fz_vmtx*)a0; fz_vmtx *b = (fz_vmtx*)b0; - return a->c - b->c; + return a->lo - b->lo; } static int uniq(void *ptr, int count, int size) @@ -178,7 +192,7 @@ fz_endvmtx(fz_font *font) } fz_hmtx -fz_gethmtx(fz_font *font, int gid) +fz_gethmtx(fz_font *font, int cid) { int l = 0; int r = font->nhmtx; @@ -190,9 +204,9 @@ fz_gethmtx(fz_font *font, int gid) while (l <= r) { m = (l + r) >> 1; - if (gid < font->hmtx[m].c) + if (cid < font->hmtx[m].lo) r = m - 1; - else if (gid > font->hmtx[m].c) + else if (cid > font->hmtx[m].hi) l = m + 1; else return font->hmtx[m]; @@ -203,7 +217,7 @@ notfound: } fz_vmtx -fz_getvmtx(fz_font *font, int gid) +fz_getvmtx(fz_font *font, int cid) { fz_hmtx h; fz_vmtx v; @@ -217,16 +231,16 @@ fz_getvmtx(fz_font *font, int gid) while (l <= r) { m = (l + r) >> 1; - if (gid < font->vmtx[m].c) + if (cid < font->vmtx[m].lo) r = m - 1; - else if (gid > font->vmtx[m].c) + else if (cid > font->vmtx[m].hi) l = m + 1; else return font->vmtx[m]; } notfound: - h = fz_gethmtx(font, gid); + h = fz_gethmtx(font, cid); v = font->dvmtx; v.x = h.w / 2; return v; @@ -237,6 +251,7 @@ fz_freefont(fz_font *font) { if (font->free) font->free(font); + fz_free(font->cidtogid); fz_free(font->hmtx); fz_free(font->vmtx); fz_free(font); @@ -256,8 +271,8 @@ fz_debugfont(fz_font *font) printf(" W {\n"); for (i = 0; i < font->nhmtx; i++) - printf(" <%04x> %d\n", - font->hmtx[i].c, font->hmtx[i].w); + printf(" <%04x> <%04x> %d\n", + font->hmtx[i].lo, font->hmtx[i].hi, font->hmtx[i].w); printf(" }\n"); if (font->wmode) @@ -265,7 +280,7 @@ fz_debugfont(fz_font *font) printf(" DW2 [%d %d]\n", font->dvmtx.y, font->dvmtx.w); printf(" W2 {\n"); for (i = 0; i < font->nvmtx; i++) - printf(" <%04x> %d %d %d\n", font->vmtx[i].c, + printf(" <%04x> <%04x> %d %d %d\n", font->vmtx[i].lo, font->vmtx[i].hi, font->vmtx[i].x, font->vmtx[i].y, font->vmtx[i].w); printf(" }\n"); } diff --git a/tree/text.c b/tree/text.c index b36fe59d..d822ec34 100644 --- a/tree/text.c +++ b/tree/text.c @@ -54,11 +54,11 @@ growtext(fz_textnode *text, int n) } fz_error * -fz_addtext(fz_textnode *text, int g, float x, float y) +fz_addtext(fz_textnode *text, int cid, float x, float y) { if (growtext(text, 1) != nil) return fz_outofmem; - text->els[text->len].g = g; + text->els[text->len].cid = cid; text->els[text->len].x = x; text->els[text->len].y = y; text->len++; |