summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/fitz/font.h18
-rw-r--r--include/fitz/text.h2
-rw-r--r--include/mupdf.h26
-rw-r--r--mupdf/build.c28
-rw-r--r--mupdf/cmap.c4
-rw-r--r--mupdf/font.c147
-rw-r--r--mupdf/fontfile.c84
-rw-r--r--render/glyphcache.c8
-rw-r--r--render/render.c22
-rw-r--r--tree/debug.c5
-rw-r--r--tree/font.c51
-rw-r--r--tree/text.c4
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++;