summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--apps/common/pdfapp.c3
-rw-r--r--apps/pdftool.c2
-rw-r--r--include/fitz-world.h1
-rw-r--r--include/fitz/wld_font.h60
-rw-r--r--include/fitz/wld_text.h5
-rw-r--r--include/mupdf/content.h2
-rw-r--r--include/mupdf/rsrc.h77
-rw-r--r--mupdf/Jamfile1
-rw-r--r--mupdf/pdf_build.c41
-rw-r--r--mupdf/pdf_font.c480
-rw-r--r--mupdf/pdf_fontfile.c89
-rw-r--r--mupdf/pdf_fontfilefc.c8
-rw-r--r--mupdf/pdf_fontfilems.c8
-rw-r--r--mupdf/pdf_fontmtx.c179
-rw-r--r--mupdf/pdf_resources.c4
-rw-r--r--mupdf/pdf_store.c4
-rw-r--r--mupdf/pdf_type3.c108
-rw-r--r--mupdf/pdf_unicode.c16
-rw-r--r--raster/glyphcache.c17
-rw-r--r--raster/render.c6
-rw-r--r--world/node_text.c5
-rw-r--r--world/node_toxml.c10
-rw-r--r--world/res_font.c442
23 files changed, 874 insertions, 694 deletions
diff --git a/apps/common/pdfapp.c b/apps/common/pdfapp.c
index 6d82ef39..b01bd485 100644
--- a/apps/common/pdfapp.c
+++ b/apps/common/pdfapp.c
@@ -635,6 +635,8 @@ void pdfapp_onmouse(pdfapp_t *app, int x, int y, int btn, int modifiers, int sta
void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen)
{
+ ucsbuf[0] = 0;
+#if 0 /* pdf_loadtextfromtree needs rewriting, so removing this temporarily */
fz_error *error;
pdf_textline *line, *ln;
int y, c;
@@ -687,5 +689,6 @@ void pdfapp_oncopy(pdfapp_t *app, unsigned short *ucsbuf, int ucslen)
ucsbuf[p] = 0;
pdf_droptextline(line);
+#endif
}
diff --git a/apps/pdftool.c b/apps/pdftool.c
index 36bc35bc..91ecc22b 100644
--- a/apps/pdftool.c
+++ b/apps/pdftool.c
@@ -719,6 +719,7 @@ drawpnm(int pagenum, struct benchmark *loadtimes, struct benchmark *drawtimes)
void
drawtxt(int pagenum)
{
+#if 0 /* removed temporarily pending rewrite of pdf_loadtextfromtree */
fz_error *error;
pdf_textline *line;
fz_matrix ctm;
@@ -737,6 +738,7 @@ drawtxt(int pagenum)
pdf_droptextline(line);
drawfreepage();
+#endif
}
void
diff --git a/include/fitz-world.h b/include/fitz-world.h
index f810e07b..ddf9a445 100644
--- a/include/fitz-world.h
+++ b/include/fitz-world.h
@@ -15,6 +15,7 @@
#include "fitz/wld_color.h"
#include "fitz/wld_image.h"
#include "fitz/wld_shade.h"
+
#include "fitz/wld_tree.h"
#include "fitz/wld_path.h"
#include "fitz/wld_text.h"
diff --git a/include/fitz/wld_font.h b/include/fitz/wld_font.h
index 27217c6c..8bcffb60 100644
--- a/include/fitz/wld_font.h
+++ b/include/fitz/wld_font.h
@@ -1,43 +1,22 @@
typedef struct fz_font_s fz_font;
-typedef struct fz_hmtx_s fz_hmtx;
-typedef struct fz_vmtx_s fz_vmtx;
typedef struct fz_glyph_s fz_glyph;
typedef struct fz_glyphcache_s fz_glyphcache;
-struct fz_hmtx_s
-{
- unsigned short lo;
- unsigned short hi;
- int w; /* type3 fonts can be big! */
-};
-
-struct fz_vmtx_s
-{
- unsigned short lo;
- unsigned short hi;
- short x;
- short y;
- short w;
-};
+char *ft_errorstring(int err);
struct fz_font_s
{
int refs;
char name[32];
- fz_error* (*render)(fz_glyph*, fz_font*, int, fz_matrix);
- void (*drop)(fz_font *);
+ void *ftface; /* has an FT_Face if used */
+ int ftsubstitute; /* ... substitute metrics */
- int wmode;
- fz_irect bbox;
+ struct fz_tree_s **t3procs; /* has 256 entries if used */
+ fz_matrix t3matrix;
- int nhmtx, hmtxcap;
- fz_hmtx dhmtx;
- fz_hmtx *hmtx;
+ fz_irect bbox;
- int nvmtx, vmtxcap;
- fz_vmtx dvmtx;
- fz_vmtx *vmtx;
};
struct fz_glyph_s
@@ -46,23 +25,24 @@ struct fz_glyph_s
unsigned char *samples;
};
-void fz_initfont(fz_font *font, char *name);
-fz_font *fz_keepfont(fz_font *font);
+fz_error * fz_newfreetypefont(fz_font **fontp, char *name, int substitute);
+fz_error * fz_loadfreetypefontfile(fz_font *font, char *path, int index);
+fz_error * fz_loadfreetypefontbuffer(fz_font *font, unsigned char *data, int len, int index);
+fz_error * fz_newtype3font(fz_font **fontp, char *name, fz_matrix matrix, void **procs);
+
+fz_error * fz_newfontfrombuffer(fz_font **fontp, unsigned char *data, int len, int index);
+fz_error * fz_newfontfromfile(fz_font **fontp, char *path, int index);
+
+fz_font * fz_keepfont(fz_font *font);
void fz_dropfont(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_setdefaulthmtx(fz_font *font, int w);
-void fz_setdefaultvmtx(fz_font *font, 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 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);
+fz_error * fz_renderftglyph(fz_glyph *glyph, fz_font *font, int cid, fz_matrix trm);
+fz_error * fz_rendert3glyph(fz_glyph *glyph, fz_font *font, int cid, fz_matrix trm);
+fz_error * fz_newglyphcache(fz_glyphcache **arenap, int slots, int size);
+fz_error * fz_renderglyph(fz_glyphcache*, fz_glyph*, fz_font*, int, fz_matrix);
void fz_debugglyphcache(fz_glyphcache *);
void fz_dropglyphcache(fz_glyphcache *);
diff --git a/include/fitz/wld_text.h b/include/fitz/wld_text.h
index 619aae83..d9e5c980 100644
--- a/include/fitz/wld_text.h
+++ b/include/fitz/wld_text.h
@@ -25,7 +25,8 @@ typedef struct fz_textel_s fz_textel;
struct fz_textel_s
{
float x, y;
- int cid;
+ int gid;
+ int ucs;
};
struct fz_textnode_s
@@ -39,6 +40,6 @@ struct fz_textnode_s
fz_error *fz_newtextnode(fz_textnode **textp, fz_font *face);
fz_error *fz_clonetextnode(fz_textnode **textp, fz_textnode *oldtext);
-fz_error *fz_addtext(fz_textnode *text, int g, float x, float y);
+fz_error *fz_addtext(fz_textnode *text, int gid, int ucs, float x, float y);
fz_error *fz_endtext(fz_textnode *text);
diff --git a/include/mupdf/content.h b/include/mupdf/content.h
index c28a33f3..a77a7296 100644
--- a/include/mupdf/content.h
+++ b/include/mupdf/content.h
@@ -54,7 +54,7 @@ struct pdf_gstate_s
float wordspace;
float scale;
float leading;
- pdf_font *font;
+ pdf_fontdesc *font;
float size;
int render;
float rise;
diff --git a/include/mupdf/rsrc.h b/include/mupdf/rsrc.h
index aa1935b5..65f9e536 100644
--- a/include/mupdf/rsrc.h
+++ b/include/mupdf/rsrc.h
@@ -189,11 +189,31 @@ extern const char * const pdf_expert[256];
extern const char * const pdf_symbol[256];
extern const char * const pdf_zapfdingbats[256];
-typedef struct pdf_font_s pdf_font;
+typedef struct pdf_hmtx_s pdf_hmtx;
+typedef struct pdf_vmtx_s pdf_vmtx;
+typedef struct pdf_fontdesc_s pdf_fontdesc;
-struct pdf_font_s
+struct pdf_hmtx_s
{
- fz_font super;
+ unsigned short lo;
+ unsigned short hi;
+ int w; /* type3 fonts can be big! */
+};
+
+struct pdf_vmtx_s
+{
+ unsigned short lo;
+ unsigned short hi;
+ short x;
+ short y;
+ short w;
+};
+
+struct pdf_fontdesc_s
+{
+ int refs;
+
+ fz_font *font;
/* FontDescriptor */
int flags;
@@ -215,32 +235,47 @@ struct pdf_font_s
int ncidtoucs;
unsigned short *cidtoucs;
- /* Freetype */
- int substitute;
- void *ftface;
- char *filename;
- fz_buffer *fontdata;
+ /* Metrics (given in the PDF file) */
+ int wmode;
- /* Type3 data */
- fz_matrix matrix;
- fz_tree *charprocs[256];
+ int nhmtx, hmtxcap;
+ pdf_hmtx dhmtx;
+ pdf_hmtx *hmtx;
+
+ int nvmtx, vmtxcap;
+ pdf_vmtx dvmtx;
+ pdf_vmtx *vmtx;
};
+/* fontmtx.c */
+void pdf_setfontwmode(pdf_fontdesc *font, int wmode);
+void pdf_setdefaulthmtx(pdf_fontdesc *font, int w);
+void pdf_setdefaultvmtx(pdf_fontdesc *font, int y, int w);
+fz_error *pdf_addhmtx(pdf_fontdesc *font, int lo, int hi, int w);
+fz_error *pdf_addvmtx(pdf_fontdesc *font, int lo, int hi, int x, int y, int w);
+fz_error *pdf_endhmtx(pdf_fontdesc *font);
+fz_error *pdf_endvmtx(pdf_fontdesc *font);
+pdf_hmtx pdf_gethmtx(pdf_fontdesc *font, int cid);
+pdf_vmtx pdf_getvmtx(pdf_fontdesc *font, int cid);
+
/* unicode.c */
-fz_error *pdf_loadtounicode(pdf_font *font, pdf_xref *xref, char **strings, char *collection, fz_obj *cmapstm);
+fz_error *pdf_loadtounicode(pdf_fontdesc *font, pdf_xref *xref, char **strings, char *collection, fz_obj *cmapstm);
/* fontfile.c */
-fz_error *pdf_loadbuiltinfont(pdf_font *font, char *basefont);
-fz_error *pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref);
-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_loadbuiltinfont(pdf_fontdesc *font, char *basefont);
+fz_error *pdf_loadembeddedfont(pdf_fontdesc *font, pdf_xref *xref, fz_obj *stmref);
+fz_error *pdf_loadsystemfont(pdf_fontdesc *font, char *basefont, char *collection);
+fz_error *pdf_loadsubstitutefont(pdf_fontdesc *font, int fdflags, char *collection);
/* type3.c */
-fz_error *pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *obj, fz_obj *ref);
+fz_error *pdf_loadtype3font(pdf_fontdesc **fontp, pdf_xref *xref, fz_obj *obj, fz_obj *ref);
/* font.c */
-char *ft_errstr(int err);
-fz_error *pdf_loadfontdescriptor(pdf_font *font, pdf_xref *xref, fz_obj *desc, char *collection);
-fz_error *pdf_loadfont(pdf_font **fontp, pdf_xref *xref, fz_obj *obj, fz_obj *ref);
-void pdf_dropfont(pdf_font *font);
+int pdf_fontcidtogid(pdf_fontdesc *fontdesc, int cid);
+fz_error *pdf_loadfontdescriptor(pdf_fontdesc *font, pdf_xref *xref, fz_obj *desc, char *collection);
+fz_error *pdf_loadfont(pdf_fontdesc **fontp, pdf_xref *xref, fz_obj *obj, fz_obj *ref);
+pdf_fontdesc * pdf_newfontdesc(void);
+pdf_fontdesc * pdf_keepfont(pdf_fontdesc *fontdesc);
+void pdf_dropfont(pdf_fontdesc *font);
+void pdf_debugfont(pdf_fontdesc *fontdesc);
diff --git a/mupdf/Jamfile b/mupdf/Jamfile
index dba33a63..a96f4d30 100644
--- a/mupdf/Jamfile
+++ b/mupdf/Jamfile
@@ -26,6 +26,7 @@ Library libmupdf :
pdf_unicode.c
pdf_font.c
pdf_type3.c
+ pdf_fontmtx.c
pdf_fontfile.c # use builtin fonts
# pdf_fontfilefc.c # use fontconfig
# pdf_fontfilems.c # scan $WINDIR/Fonts
diff --git a/mupdf/pdf_build.c b/mupdf/pdf_build.c
index 741d5b72..f303a2c9 100644
--- a/mupdf/pdf_build.c
+++ b/mupdf/pdf_build.c
@@ -851,12 +851,14 @@ fz_error *
showglyph(pdf_csi *csi, int cid)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- pdf_font *font = gstate->font;
+ pdf_fontdesc *fontdesc = gstate->font;
fz_error *error;
fz_matrix tsm, trm;
float w0, w1, tx, ty;
- fz_hmtx h;
- fz_vmtx v;
+ pdf_hmtx h;
+ pdf_vmtx v;
+ int gid;
+ int ucs;
tsm.a = gstate->size * gstate->scale;
tsm.b = 0;
@@ -865,9 +867,18 @@ showglyph(pdf_csi *csi, int cid)
tsm.e = 0;
tsm.f = gstate->rise;
- if (font->super.wmode == 1)
+ if (fontdesc->tounicode)
+ ucs = pdf_lookupcmap(fontdesc->tounicode, cid);
+ else if (cid < fontdesc->ncidtoucs)
+ ucs = fontdesc->cidtoucs[cid];
+ else
+ ucs = '?';
+
+ gid = pdf_fontcidtogid(fontdesc, cid);
+
+ if (fontdesc->wmode == 1)
{
- v = fz_getvmtx((fz_font*)font, cid);
+ v = pdf_getvmtx(fontdesc, cid);
tsm.e -= v.x * gstate->size / 1000.0;
tsm.f -= v.y * gstate->size / 1000.0;
}
@@ -876,7 +887,7 @@ showglyph(pdf_csi *csi, int cid)
/* flush buffered text if face or matrix or rendermode has changed */
if (!csi->text ||
- ((fz_font*)font) != csi->text->font ||
+ (fontdesc->font) != csi->text->font ||
fabs(trm.a - csi->text->trm.a) > FLT_EPSILON ||
fabs(trm.b - csi->text->trm.b) > FLT_EPSILON ||
fabs(trm.c - csi->text->trm.c) > FLT_EPSILON ||
@@ -887,7 +898,7 @@ showglyph(pdf_csi *csi, int cid)
if (error)
return fz_rethrow(error, "cannot finish text node (face/matrix change)");
- error = fz_newtextnode(&csi->text, (fz_font*)font);
+ error = fz_newtextnode(&csi->text, fontdesc->font);
if (error)
return fz_rethrow(error, "cannot create text node");
@@ -898,13 +909,13 @@ showglyph(pdf_csi *csi, int cid)
}
/* add glyph to textobject */
- error = fz_addtext(csi->text, cid, trm.e, trm.f);
+ error = fz_addtext(csi->text, gid, ucs, trm.e, trm.f);
if (error)
return fz_rethrow(error, "cannot add glyph to text node");
- if (font->super.wmode == 0)
+ if (fontdesc->wmode == 0)
{
- h = fz_gethmtx((fz_font*)font, cid);
+ h = pdf_gethmtx(fontdesc, cid);
w0 = h.w / 1000.0;
tx = (w0 * gstate->size + gstate->charspace) * gstate->scale;
csi->tm = fz_concat(fz_translate(tx, 0), csi->tm);
@@ -923,8 +934,8 @@ void
showspace(pdf_csi *csi, float tadj)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- pdf_font *font = gstate->font;
- if (font->super.wmode == 0)
+ pdf_fontdesc *fontdesc = gstate->font;
+ if (fontdesc->wmode == 0)
csi->tm = fz_concat(fz_translate(tadj * gstate->scale, 0), csi->tm);
else
csi->tm = fz_concat(fz_translate(0, tadj), csi->tm);
@@ -934,7 +945,7 @@ fz_error *
pdf_showtext(pdf_csi *csi, fz_obj *text)
{
pdf_gstate *gstate = csi->gstate + csi->gtop;
- pdf_font *font = gstate->font;
+ pdf_fontdesc *fontdesc = gstate->font;
fz_error *error;
unsigned char *buf;
unsigned char *end;
@@ -966,8 +977,8 @@ pdf_showtext(pdf_csi *csi, fz_obj *text)
while (buf < end)
{
- buf = pdf_decodecmap(font->encoding, buf, &cpt);
- cid = pdf_lookupcmap(font->encoding, cpt);
+ buf = pdf_decodecmap(fontdesc->encoding, buf, &cpt);
+ cid = pdf_lookupcmap(fontdesc->encoding, cpt);
if (cid == -1)
cid = 0;
diff --git a/mupdf/pdf_font.c b/mupdf/pdf_font.c
index 7ed7ef1c..4a1a29db 100644
--- a/mupdf/pdf_font.c
+++ b/mupdf/pdf_font.c
@@ -43,33 +43,6 @@ static char *basefontnames[14][7] =
enum { UNKNOWN, TYPE1, TRUETYPE, CID };
-#undef __FTERRORS_H__
-#define FT_ERRORDEF(e, v, s) { (e), (s) },
-#define FT_ERROR_START_LIST
-#define FT_ERROR_END_LIST { 0, NULL }
-
-struct ft_error
-{
- int err;
- char *str;
-};
-
-const struct ft_error ft_errors[] =
-{
-#include FT_ERRORS_H
-};
-
-char *ft_errstr(int err)
-{
- const struct ft_error *e;
-
- for (e = ft_errors; e->str != NULL; e++)
- if (e->err == err)
- return e->str;
-
- return "Unknown error";
-}
-
static int ftkind(FT_Face face)
{
const char *kind = FT_Get_X11_Font_Format(face);
@@ -93,138 +66,38 @@ static int ftcharindex(FT_Face face, int cid)
return gid;
}
-static inline int ftcidtogid(pdf_font *font, int cid)
+static inline int ftcidtogid(pdf_fontdesc *fontdesc, int cid)
{
- if (font->tottfcmap)
+ if (fontdesc->tottfcmap)
{
- cid = pdf_lookupcmap(font->tottfcmap, cid);
- return ftcharindex(font->ftface, cid);
+ cid = pdf_lookupcmap(fontdesc->tottfcmap, cid);
+ return ftcharindex(fontdesc->font->ftface, cid);
}
- if (font->cidtogid)
- return font->cidtogid[cid];
+ if (fontdesc->cidtogid)
+ return fontdesc->cidtogid[cid];
return cid;
}
-static int ftwidth(pdf_font *font, int cid)
+int pdf_fontcidtogid(pdf_fontdesc *fontdesc, int cid)
{
- int e;
-
- cid = ftcidtogid(font, 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 ((FT_Face)font->ftface)->glyph->advance.x;
+ if (fontdesc->font->ftface)
+ return ftcidtogid(fontdesc, cid);
+ return cid;
}
-static fz_error *
-ftrender(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
+static int ftwidth(pdf_fontdesc *fontdesc, int cid)
{
- pdf_font *font = (pdf_font*)fzfont;
- FT_Face face = font->ftface;
- FT_Matrix m;
- FT_Vector v;
- FT_Error fterr;
- float scale;
- int gid;
- int x, y;
-
- gid = ftcidtogid(font, cid);
-
- if (font->substitute && fzfont->wmode == 0)
- {
- fz_hmtx subw;
- int realw;
-
- 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: %s", ft_errstr(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);
- }
-
- glyph->w = 0;
- glyph->h = 0;
- glyph->x = 0;
- glyph->y = 0;
- glyph->samples = nil;
-
- /* freetype mutilates complex glyphs if they are loaded
- * with FT_Set_Char_Size 1.0. it rounds the coordinates
- * before applying transformation. to get more precision in
- * freetype, we shift part of the scale in the matrix
- * into FT_Set_Char_Size instead
- */
+ int gid, e;
-#ifdef HINT
- scale = fz_matrixexpansion(trm);
- m.xx = trm.a * 65536 / scale;
- m.yx = trm.b * 65536 / scale;
- m.xy = trm.c * 65536 / scale;
- m.yy = trm.d * 65536 / scale;
- v.x = 0;
- v.y = 0;
+ gid = ftcidtogid(fontdesc, cid);
- FT_Set_Char_Size(face, 64 * scale, 64 * scale, 72, 72);
- FT_Set_Transform(face, &m, &v);
-
- fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP);
- if (fterr)
- fz_warn("freetype load glyph: %s", ft_errstr(fterr));
-
-#else
-
- m.xx = trm.a * 64; /* should be 65536 */
- m.yx = trm.b * 64;
- m.xy = trm.c * 64;
- m.yy = trm.d * 64;
- v.x = trm.e * 64;
- v.y = trm.f * 64;
-
- FT_Set_Char_Size(face, 65536, 65536, 72, 72); /* should be 64, 64 */
- FT_Set_Transform(face, &m, &v);
-
- fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
- if (fterr)
- fz_warn("freetype load glyph: %s", ft_errstr(fterr));
-
-#endif
-
- fterr = FT_Render_Glyph(face->glyph, ft_render_mode_normal);
- if (fterr)
- fz_warn("freetype render glyph: %s", ft_errstr(fterr));
-
- glyph->w = face->glyph->bitmap.width;
- glyph->h = face->glyph->bitmap.rows;
- glyph->x = face->glyph->bitmap_left;
- glyph->y = face->glyph->bitmap_top - glyph->h;
- glyph->samples = face->glyph->bitmap.buffer;
-
- for (y = 0; y < glyph->h / 2; y++)
- {
- for (x = 0; x < glyph->w; x++)
- {
- unsigned char a = glyph->samples[y * glyph->w + x ];
- unsigned char b = glyph->samples[(glyph->h - y - 1) * glyph->w + x];
- glyph->samples[y * glyph->w + x ] = b;
- glyph->samples[(glyph->h - y - 1) * glyph->w + x] = a;
- }
- }
-
- return fz_okay;
+ e = FT_Load_Glyph(fontdesc->font->ftface, gid,
+ FT_LOAD_NO_HINTING | FT_LOAD_NO_BITMAP | FT_LOAD_IGNORE_TRANSFORM);
+ if (e)
+ return 0;
+ return ((FT_Face)fontdesc->font->ftface)->glyph->advance.x;
}
/*
@@ -254,64 +127,84 @@ static int mrecode(char *name)
* Create and destroy
*/
-static void ftdropfont(fz_font *font)
+pdf_fontdesc *
+pdf_keepfont(pdf_fontdesc *fontdesc)
{
- pdf_font *pfont = (pdf_font*)font;
- if (pfont->encoding)
- pdf_dropcmap(pfont->encoding);
- if (pfont->tottfcmap)
- pdf_dropcmap(pfont->tottfcmap);
- if (pfont->tounicode)
- pdf_dropcmap(pfont->tounicode);
- fz_free(pfont->cidtogid);
- fz_free(pfont->cidtoucs);
- if (pfont->ftface)
- FT_Done_Face((FT_Face)pfont->ftface);
- if (pfont->fontdata)
- fz_dropbuffer(pfont->fontdata);
+ fontdesc->refs ++;
+ return fontdesc;
}
-pdf_font *
-pdf_newfont(char *name)
+void
+pdf_dropfont(pdf_fontdesc *fontdesc)
{
- pdf_font *font;
- int i;
+ if (fontdesc && --fontdesc->refs == 0)
+ {
+ if (fontdesc->font)
+ fz_dropfont(fontdesc->font);
+ if (fontdesc->encoding)
+ pdf_dropcmap(fontdesc->encoding);
+ if (fontdesc->tottfcmap)
+ pdf_dropcmap(fontdesc->tottfcmap);
+ if (fontdesc->tounicode)
+ pdf_dropcmap(fontdesc->tounicode);
+ fz_free(fontdesc->cidtogid);
+ fz_free(fontdesc->cidtoucs);
+ fz_free(fontdesc->hmtx);
+ fz_free(fontdesc->vmtx);
+ fz_free(fontdesc);
+ }
+}
+
+pdf_fontdesc *
+pdf_newfontdesc(void)
+{
+ pdf_fontdesc *fontdesc;
- font = fz_malloc(sizeof (pdf_font));
- if (!font)
+ fontdesc = fz_malloc(sizeof (pdf_fontdesc));
+ if (!fontdesc)
return nil;
- fz_initfont((fz_font*)font, name);
- font->super.render = ftrender;
- font->super.drop = (void(*)(fz_font*)) ftdropfont;
+ fontdesc->refs = 1;
- font->ftface = nil;
- font->substitute = 0;
+ fontdesc->font = nil;
- font->flags = 0;
- font->italicangle = 0;
- font->ascent = 0;
- font->descent = 0;
- font->capheight = 0;
- font->xheight = 0;
- font->missingwidth = 0;
+ fontdesc->flags = 0;
+ fontdesc->italicangle = 0;
+ fontdesc->ascent = 0;
+ fontdesc->descent = 0;
+ fontdesc->capheight = 0;
+ fontdesc->xheight = 0;
+ fontdesc->missingwidth = 0;
- font->encoding = nil;
- font->tottfcmap = 0;
- font->ncidtogid = 0;
- font->cidtogid = nil;
+ fontdesc->encoding = nil;
+ fontdesc->tottfcmap = 0;
+ fontdesc->ncidtogid = 0;
+ fontdesc->cidtogid = nil;
- font->tounicode = nil;
- font->ncidtoucs = 0;
- font->cidtoucs = nil;
+ fontdesc->tounicode = nil;
+ fontdesc->ncidtoucs = 0;
+ fontdesc->cidtoucs = nil;
- font->filename = nil;
- font->fontdata = nil;
+ fontdesc->wmode = 0;
- for (i = 0; i < 256; i++)
- font->charprocs[i] = nil;
+ fontdesc->hmtxcap = 0;
+ fontdesc->vmtxcap = 0;
+ fontdesc->nhmtx = 0;
+ fontdesc->nvmtx = 0;
+ fontdesc->hmtx = nil;
+ fontdesc->vmtx = nil;
+
+ fontdesc->dhmtx.lo = 0x0000;
+ fontdesc->dhmtx.hi = 0xFFFF;
+ fontdesc->dhmtx.w = 0;
+
+ fontdesc->dvmtx.lo = 0x0000;
+ fontdesc->dvmtx.hi = 0xFFFF;
+ fontdesc->dvmtx.x = 0;
+ fontdesc->dvmtx.y = 880;
+ fontdesc->dvmtx.w = -1000;
- return font;
+ return fontdesc;
}
/*
@@ -319,14 +212,14 @@ pdf_newfont(char *name)
*/
static fz_error *
-loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
+loadsimplefont(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
{
fz_error *error;
fz_obj *descriptor = nil;
fz_obj *encoding = nil;
fz_obj *widths = nil;
unsigned short *etable = nil;
- pdf_font *font;
+ pdf_fontdesc *fontdesc;
fz_irect bbox;
FT_Face face;
FT_CharMap cmap;
@@ -347,23 +240,23 @@ loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
* Load font file
*/
- font = pdf_newfont(fontname);
- if (!font)
+ fontdesc = pdf_newfontdesc();
+ if (!fontdesc)
return fz_outofmem;
- pdf_logfont("load simple font (%d %d R) ptr=%p {\n", fz_tonum(ref), fz_togen(ref), font);
+ pdf_logfont("load simple font (%d %d R) ptr=%p {\n", fz_tonum(ref), fz_togen(ref), fontdesc);
pdf_logfont("basefont0 %s\n", basefont);
pdf_logfont("basefont1 %s\n", fontname);
descriptor = fz_dictgets(dict, "FontDescriptor");
if (descriptor && basefont == fontname)
- error = pdf_loadfontdescriptor(font, xref, descriptor, nil);
+ error = pdf_loadfontdescriptor(fontdesc, xref, descriptor, nil);
else
- error = pdf_loadbuiltinfont(font, fontname);
+ error = pdf_loadbuiltinfont(fontdesc, fontname);
if (error)
goto cleanup;
- face = font->ftface;
+ face = fontdesc->font->ftface;
kind = ftkind(face);
pdf_logfont("ft name '%s' '%s'\n", face->family_name, face->style_name);
@@ -376,15 +269,15 @@ loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
pdf_logfont("ft bbox [%d %d %d %d]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1);
if (bbox.x0 == bbox.x1)
- fz_setfontbbox((fz_font*)font, -1000, -1000, 2000, 2000);
+ fz_setfontbbox(fontdesc->font, -1000, -1000, 2000, 2000);
else
- fz_setfontbbox((fz_font*)font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
+ fz_setfontbbox(fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
/*
* Encoding
*/
- symbolic = font->flags & 4;
+ symbolic = fontdesc->flags & 4;
if (face->num_charmaps > 0)
cmap = face->charmaps[0];
@@ -415,7 +308,7 @@ loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
fterr = FT_Set_Charmap(face, cmap);
if (fterr)
{
- error = fz_throw("freetype could not set cmap: %s", ft_errstr(fterr));
+ error = fz_throw("freetype could not set cmap: %s", ft_errorstring(fterr));
goto cleanup;
}
}
@@ -545,15 +438,14 @@ loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
}
}
- error = pdf_newidentitycmap(&font->encoding, 0, 1);
+ error = pdf_newidentitycmap(&fontdesc->encoding, 0, 1);
if (error)
goto cleanup;
- font->ncidtogid = 256;
- font->cidtogid = etable;
+ fontdesc->ncidtogid = 256;
+ fontdesc->cidtogid = etable;
- error = pdf_loadtounicode(font, xref,
- estrings, nil, fz_dictgets(dict, "ToUnicode"));
+ error = pdf_loadtounicode(fontdesc, xref, estrings, nil, fz_dictgets(dict, "ToUnicode"));
if (error)
goto cleanup;
@@ -561,7 +453,7 @@ loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
* Widths
*/
- fz_setdefaulthmtx((fz_font*)font, font->missingwidth);
+ pdf_setdefaulthmtx(fontdesc, fontdesc->missingwidth);
widths = fz_dictgets(dict, "Widths");
if (widths)
@@ -581,7 +473,7 @@ loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
for (i = 0; i < last - first + 1; i++)
{
int wid = fz_toint(fz_arrayget(widths, i));
- error = fz_addhmtx((fz_font*)font, i + first, i + first, wid);
+ error = pdf_addhmtx(fontdesc, i + first, i + first, wid);
if (error)
goto cleanup;
}
@@ -593,26 +485,27 @@ loadsimplefont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
FT_Set_Char_Size(face, 1000, 1000, 72, 72);
for (i = 0; i < 256; i++)
{
- error = fz_addhmtx((fz_font*)font, i, i, ftwidth(font, i));
+ error = pdf_addhmtx(fontdesc, i, i, ftwidth(fontdesc, i));
if (error)
goto cleanup;
}
}
- error = fz_endhmtx((fz_font*)font);
+ error = pdf_endhmtx(fontdesc);
if (error)
goto cleanup;
pdf_logfont("}\n");
- *fontp = font;
+ *fontdescp = fontdesc;
return fz_okay;
cleanup:
fz_free(etable);
if (widths)
fz_dropobj(widths);
- fz_dropfont((fz_font*)font);
+ fz_dropfont(fontdesc->font);
+ fz_free(fontdesc);
return fz_rethrow(error, "cannot load simple font");
}
@@ -621,12 +514,12 @@ cleanup:
*/
static fz_error *
-loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj *encoding, fz_obj *tounicode)
+loadcidfont(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj *encoding, fz_obj *tounicode)
{
fz_error *error;
fz_obj *widths = nil;
fz_obj *descriptor;
- pdf_font *font;
+ pdf_fontdesc *fontdesc;
FT_Face face;
fz_irect bbox;
int kind;
@@ -673,23 +566,23 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
* Load font file
*/
- font = pdf_newfont(basefont);
- if (!font)
+ fontdesc = pdf_newfontdesc();
+ if (!fontdesc)
return fz_outofmem;
- pdf_logfont("load cid font (%d %d R) ptr=%p {\n", fz_tonum(ref), fz_togen(ref), font);
+ pdf_logfont("load cid font (%d %d R) ptr=%p {\n", fz_tonum(ref), fz_togen(ref), fontdesc);
pdf_logfont("basefont %s\n", basefont);
pdf_logfont("collection %s\n", collection);
descriptor = fz_dictgets(dict, "FontDescriptor");
if (descriptor)
- error = pdf_loadfontdescriptor(font, xref, descriptor, collection);
+ error = pdf_loadfontdescriptor(fontdesc, xref, descriptor, collection);
else
error = fz_throw("syntaxerror: missing font descriptor");
if (error)
goto cleanup;
- face = font->ftface;
+ face = fontdesc->font->ftface;
kind = ftkind(face);
bbox.x0 = (face->bbox.xMin * 1000) / face->units_per_EM;
@@ -700,9 +593,9 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
pdf_logfont("ft bbox [%d %d %d %d]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1);
if (bbox.x0 == bbox.x1)
- fz_setfontbbox((fz_font*)font, -1000, -1000, 2000, 2000);
+ fz_setfontbbox(fontdesc->font, -1000, -1000, 2000, 2000);
else
- fz_setfontbbox((fz_font*)font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
+ fz_setfontbbox(fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
/*
* Encoding
@@ -712,16 +605,16 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
{
pdf_logfont("encoding /%s\n", fz_toname(encoding));
if (!strcmp(fz_toname(encoding), "Identity-H"))
- error = pdf_newidentitycmap(&font->encoding, 0, 2);
+ error = pdf_newidentitycmap(&fontdesc->encoding, 0, 2);
else if (!strcmp(fz_toname(encoding), "Identity-V"))
- error = pdf_newidentitycmap(&font->encoding, 1, 2);
+ error = pdf_newidentitycmap(&fontdesc->encoding, 1, 2);
else
- error = pdf_loadsystemcmap(&font->encoding, fz_toname(encoding));
+ error = pdf_loadsystemcmap(&fontdesc->encoding, fz_toname(encoding));
}
else if (fz_isindirect(encoding))
{
pdf_logfont("encoding %d %d R\n", fz_tonum(encoding), fz_togen(encoding));
- error = pdf_loadembeddedcmap(&font->encoding, xref, encoding);
+ error = pdf_loadembeddedcmap(&fontdesc->encoding, xref, encoding);
}
else
{
@@ -730,8 +623,8 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
if (error)
goto cleanup;
- fz_setfontwmode((fz_font*)font, pdf_getwmode(font->encoding));
- pdf_logfont("wmode %d\n", pdf_getwmode(font->encoding));
+ pdf_setfontwmode(fontdesc, pdf_getwmode(fontdesc->encoding));
+ pdf_logfont("wmode %d\n", pdf_getwmode(fontdesc->encoding));
if (kind == TRUETYPE)
{
@@ -762,8 +655,8 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
for (i = 0; i < len; i++)
map[i] = (buf->rp[i * 2] << 8) + buf->rp[i * 2 + 1];
- font->ncidtogid = len;
- font->cidtogid = map;
+ fontdesc->ncidtogid = len;
+ fontdesc->cidtogid = map;
fz_dropbuffer(buf);
}
@@ -771,7 +664,7 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
/* if truetype font is external, cidtogidmap should not be identity */
/* so we map from cid to unicode and then map that through the (3 1) */
/* unicode cmap to get a glyph id */
- else if (font->substitute)
+ else if (fontdesc->font->ftsubstitute)
{
int e;
@@ -782,15 +675,15 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
return fz_throw("fonterror: no unicode cmap when emulating CID font");
if (!strcmp(collection, "Adobe-CNS1"))
- error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-CNS1-UCS2");
+ error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-CNS1-UCS2");
else if (!strcmp(collection, "Adobe-GB1"))
- error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-GB1-UCS2");
+ error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-GB1-UCS2");
else if (!strcmp(collection, "Adobe-Japan1"))
- error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-Japan1-UCS2");
+ error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-Japan1-UCS2");
else if (!strcmp(collection, "Adobe-Japan2"))
- error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-Japan2-UCS2");
+ error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-Japan2-UCS2");
else if (!strcmp(collection, "Adobe-Korea1"))
- error = pdf_loadsystemcmap(&font->tottfcmap, "Adobe-Korea1-UCS2");
+ error = pdf_loadsystemcmap(&fontdesc->tottfcmap, "Adobe-Korea1-UCS2");
else
error = fz_okay;
@@ -799,7 +692,7 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
}
}
- error = pdf_loadtounicode(font, xref, nil, collection, tounicode);
+ error = pdf_loadtounicode(fontdesc, xref, nil, collection, tounicode);
if (error)
goto cleanup;
@@ -807,7 +700,7 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
* Horizontal
*/
- fz_setdefaulthmtx((fz_font*)font, fz_toint(fz_dictgets(dict, "DW")));
+ pdf_setdefaulthmtx(fontdesc, fz_toint(fz_dictgets(dict, "DW")));
widths = fz_dictgets(dict, "W");
if (widths)
@@ -828,7 +721,7 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
for (k = 0; k < fz_arraylen(obj); k++)
{
w = fz_toint(fz_arrayget(obj, k));
- error = fz_addhmtx((fz_font*)font, c0 + k, c0 + k, w);
+ error = pdf_addhmtx(fontdesc, c0 + k, c0 + k, w);
if (error)
goto cleanup;
}
@@ -838,7 +731,7 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
{
c1 = fz_toint(obj);
w = fz_toint(fz_arrayget(widths, i + 2));
- error = fz_addhmtx((fz_font*)font, c0, c1, w);
+ error = pdf_addhmtx(fontdesc, c0, c1, w);
if (error)
goto cleanup;
i += 3;
@@ -848,7 +741,7 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
fz_dropobj(widths);
}
- error = fz_endhmtx((fz_font*)font);
+ error = pdf_endhmtx(fontdesc);
if (error)
goto cleanup;
@@ -856,7 +749,7 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
* Vertical
*/
- if (pdf_getwmode(font->encoding) == 1)
+ if (pdf_getwmode(fontdesc->encoding) == 1)
{
fz_obj *obj;
int dw2y = 880;
@@ -869,7 +762,7 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
dw2w = fz_toint(fz_arrayget(obj, 1));
}
- fz_setdefaultvmtx((fz_font*)font, dw2y, dw2w);
+ pdf_setdefaultvmtx(fontdesc, dw2y, dw2w);
widths = fz_dictgets(dict, "W2");
if (widths)
@@ -891,7 +784,7 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
w = fz_toint(fz_arrayget(obj, k + 0));
x = fz_toint(fz_arrayget(obj, k + 1));
y = fz_toint(fz_arrayget(obj, k + 2));
- error = fz_addvmtx((fz_font*)font, c0 + k, c0 + k, x, y, w);
+ error = pdf_addvmtx(fontdesc, c0 + k, c0 + k, x, y, w);
if (error)
goto cleanup;
}
@@ -903,7 +796,7 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
w = fz_toint(fz_arrayget(widths, i + 2));
x = fz_toint(fz_arrayget(widths, i + 3));
y = fz_toint(fz_arrayget(widths, i + 4));
- error = fz_addvmtx((fz_font*)font, c0, c1, x, y, w);
+ error = pdf_addvmtx(fontdesc, c0, c1, x, y, w);
if (error)
goto cleanup;
i += 5;
@@ -913,25 +806,26 @@ loadcidfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref, fz_obj
fz_dropobj(widths);
}
- error = fz_endvmtx((fz_font*)font);
+ error = pdf_endvmtx(fontdesc);
if (error)
goto cleanup;
}
pdf_logfont("}\n");
- *fontp = font;
+ *fontdescp = fontdesc;
return fz_okay;
cleanup:
if (widths)
fz_dropobj(widths);
- fz_dropfont((fz_font*)font);
+ fz_dropfont(fontdesc->font);
+ fz_free(fontdesc);
return fz_rethrow(error, "cannot load cid font");
}
static fz_error *
-loadtype0(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
+loadtype0(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
{
fz_error *error;
fz_obj *dfonts;
@@ -958,9 +852,9 @@ loadtype0(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
tounicode = fz_dictgets(dict, "ToUnicode");
if (!strcmp(fz_toname(subtype), "CIDFontType0"))
- error = loadcidfont(fontp, xref, dfont, ref, encoding, tounicode);
+ error = loadcidfont(fontdescp, xref, dfont, ref, encoding, tounicode);
else if (!strcmp(fz_toname(subtype), "CIDFontType2"))
- error = loadcidfont(fontp, xref, dfont, ref, encoding, tounicode);
+ error = loadcidfont(fontdescp, xref, dfont, ref, encoding, tounicode);
else
error = fz_throw("syntaxerror: unknown cid font type");
@@ -978,41 +872,41 @@ loadtype0(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
*/
fz_error *
-pdf_loadfontdescriptor(pdf_font *font, pdf_xref *xref, fz_obj *desc, char *collection)
+pdf_loadfontdescriptor(pdf_fontdesc *fontdesc, pdf_xref *xref, fz_obj *dict, char *collection)
{
fz_error *error;
fz_obj *obj1, *obj2, *obj3, *obj;
fz_rect bbox;
char *fontname;
- error = pdf_resolve(&desc, xref);
+ error = pdf_resolve(&dict, xref);
if (error)
return fz_rethrow(error, "cannot find font descriptor");
pdf_logfont("load fontdescriptor {\n");
- fontname = fz_toname(fz_dictgets(desc, "FontName"));
+ fontname = fz_toname(fz_dictgets(dict, "FontName"));
pdf_logfont("fontname %s\n", 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"));
+ fontdesc->flags = fz_toint(fz_dictgets(dict, "Flags"));
+ fontdesc->italicangle = fz_toreal(fz_dictgets(dict, "ItalicAngle"));
+ fontdesc->ascent = fz_toreal(fz_dictgets(dict, "Ascent"));
+ fontdesc->descent = fz_toreal(fz_dictgets(dict, "Descent"));
+ fontdesc->capheight = fz_toreal(fz_dictgets(dict, "CapHeight"));
+ fontdesc->xheight = fz_toreal(fz_dictgets(dict, "XHeight"));
+ fontdesc->missingwidth = fz_toreal(fz_dictgets(dict, "MissingWidth"));
- bbox = pdf_torect(fz_dictgets(desc, "FontBBox"));
+ bbox = pdf_torect(fz_dictgets(dict, "FontBBox"));
pdf_logfont("bbox [%g %g %g %g]\n",
bbox.x0, bbox.y0,
bbox.x1, bbox.y1);
- pdf_logfont("flags %d\n", font->flags);
+ pdf_logfont("flags %d\n", fontdesc->flags);
- obj1 = fz_dictgets(desc, "FontFile");
- obj2 = fz_dictgets(desc, "FontFile2");
- obj3 = fz_dictgets(desc, "FontFile3");
+ obj1 = fz_dictgets(dict, "FontFile");
+ obj2 = fz_dictgets(dict, "FontFile2");
+ obj3 = fz_dictgets(dict, "FontFile3");
obj = obj1 ? obj1 : obj2 ? obj2 : obj3;
if (getenv("NOFONT"))
@@ -1020,59 +914,91 @@ pdf_loadfontdescriptor(pdf_font *font, pdf_xref *xref, fz_obj *desc, char *colle
if (fz_isindirect(obj))
{
- error = pdf_loadembeddedfont(font, xref, obj);
+ error = pdf_loadembeddedfont(fontdesc, xref, obj);
if (error)
goto cleanup;
}
else
{
- error = pdf_loadsystemfont(font, fontname, collection);
+ error = pdf_loadsystemfont(fontdesc, fontname, collection);
if (error)
goto cleanup;
}
- fz_dropobj(desc);
+ fz_dropobj(dict);
pdf_logfont("}\n");
return fz_okay;
cleanup:
- fz_dropobj(desc);
+ fz_dropobj(dict);
return fz_rethrow(error, "cannot load font descriptor");
}
fz_error *
-pdf_loadfont(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
+pdf_loadfont(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
{
fz_error *error;
char *subtype;
- if ((*fontp = pdf_finditem(xref->store, PDF_KFONT, ref)))
+ if ((*fontdescp = pdf_finditem(xref->store, PDF_KFONT, ref)))
{
- fz_keepfont((fz_font*)*fontp);
+ // XXX pdf_keepfontdesc(*fontdescp);
return fz_okay;
}
subtype = fz_toname(fz_dictgets(dict, "Subtype"));
if (!strcmp(subtype, "Type0"))
- error = loadtype0(fontp, xref, dict, ref);
+ error = loadtype0(fontdescp, xref, dict, ref);
else if (!strcmp(subtype, "Type1") || !strcmp(subtype, "MMType1"))
- error = loadsimplefont(fontp, xref, dict, ref);
+ error = loadsimplefont(fontdescp, xref, dict, ref);
else if (!strcmp(subtype, "TrueType"))
- error = loadsimplefont(fontp, xref, dict, ref);
+ error = loadsimplefont(fontdescp, xref, dict, ref);
else if (!strcmp(subtype, "Type3"))
- error = pdf_loadtype3font(fontp, xref, dict, ref);
+ error = pdf_loadtype3font(fontdescp, xref, dict, ref);
else
return fz_throw("cannot recognize font format %s", subtype);
if (error)
return fz_rethrow(error, "cannot load font");
- error = pdf_storeitem(xref->store, PDF_KFONT, ref, *fontp);
+ error = pdf_storeitem(xref->store, PDF_KFONT, ref, *fontdescp);
if (error)
return fz_rethrow(error, "cannot store font resource");
return fz_okay;
}
+void
+pdf_debugfont(pdf_fontdesc *fontdesc)
+{
+ int i;
+
+ printf("fontdesc {\n");
+
+ if (fontdesc->font->ftface)
+ printf(" freetype font\n");
+ if (fontdesc->font->t3procs)
+ printf(" type3 font\n");
+
+ printf(" wmode %d\n", fontdesc->wmode);
+ printf(" DW %d\n", fontdesc->dhmtx.w);
+
+ printf(" W {\n");
+ for (i = 0; i < fontdesc->nhmtx; i++)
+ printf(" <%04x> <%04x> %d\n",
+ fontdesc->hmtx[i].lo, fontdesc->hmtx[i].hi, fontdesc->hmtx[i].w);
+ printf(" }\n");
+
+ if (fontdesc->wmode)
+ {
+ printf(" DW2 [%d %d]\n", fontdesc->dvmtx.y, fontdesc->dvmtx.w);
+ printf(" W2 {\n");
+ for (i = 0; i < fontdesc->nvmtx; i++)
+ printf(" <%04x> <%04x> %d %d %d\n", fontdesc->vmtx[i].lo, fontdesc->vmtx[i].hi,
+ fontdesc->vmtx[i].x, fontdesc->vmtx[i].y, fontdesc->vmtx[i].w);
+ printf(" }\n");
+ }
+}
+
diff --git a/mupdf/pdf_fontfile.c b/mupdf/pdf_fontfile.c
index d9808328..4ba4dfba 100644
--- a/mupdf/pdf_fontfile.c
+++ b/mupdf/pdf_fontfile.c
@@ -3,11 +3,6 @@
#include "mupdf/base14.h"
-#include <ft2build.h>
-#include FT_FREETYPE_H
-
-static FT_Library ftlib = nil;
-
enum
{
FD_FIXED = 1 << 0,
@@ -26,7 +21,7 @@ static const struct
const char *name;
const unsigned char *cff;
const unsigned int *len;
-} basefonts[15] = {
+} basefonts[] = {
{ "Courier",
fonts_NimbusMonL_Regu_cff,
&fonts_NimbusMonL_Regu_cff_len },
@@ -71,7 +66,8 @@ static const struct
&fonts_Dingbats_cff_len },
{ "Chancery",
fonts_URWChanceryL_MediItal_cff,
- &fonts_URWChanceryL_MediItal_cff_len }
+ &fonts_URWChanceryL_MediItal_cff_len },
+ { 0, 0, 0 }
};
enum { CNS, GB, Japan, Korea };
@@ -110,39 +106,15 @@ static const struct subent fontsubs[] =
{ Korea, GOTHIC, "dotum.ttc" },
};
-static fz_error *initfontlibs(void)
-{
- int fterr;
- int maj, min, pat;
-
- if (ftlib)
- return fz_okay;
-
- fterr = FT_Init_FreeType(&ftlib);
- if (fterr)
- return fz_throw("freetype failed initialisation: %s", ft_errstr(fterr));
-
- FT_Library_Version(ftlib, &maj, &min, &pat);
- if (maj == 2 && min == 1 && pat < 7)
- return fz_throw("freetype version too old: %d.%d.%d", maj, min, pat);
-
- return fz_okay;
-}
-
fz_error *
-pdf_loadbuiltinfont(pdf_font *font, char *fontname)
+pdf_loadbuiltinfont(pdf_fontdesc *font, char *fontname)
{
fz_error *error;
unsigned char *data;
unsigned int len;
- int fterr;
int i;
- error = initfontlibs();
- if (error)
- return fz_rethrow(error, "cannot init font libraries");
-
- for (i = 0; i < 15; i++)
+ for (i = 0; basefonts[i].name; i++)
if (!strcmp(fontname, basefonts[i].name))
goto found;
@@ -154,9 +126,9 @@ found:
data = (unsigned char *) basefonts[i].cff;
len = *basefonts[i].len;
- fterr = FT_New_Memory_Face(ftlib, data, len, 0, (FT_Face*)&font->ftface);
- if (fterr)
- return fz_throw("freetype: cannot load font: %s", ft_errstr(fterr));
+ error = fz_newfontfrombuffer(&font->font, data, len, 0);
+ if (error)
+ return fz_rethrow(error, "cannot load freetype font from buffer");
return fz_okay;
}
@@ -229,10 +201,10 @@ findcidfont(char *filename, char *path, int pathlen)
}
static fz_error *
-loadcidfont(pdf_font *font, int csi, int kind)
+loadcidfont(pdf_fontdesc *font, int csi, int kind)
{
char path[1024];
- int fterr;
+ fz_error *error;
int i;
for (i = 0; i < nelem(fontsubs); i++)
@@ -242,9 +214,11 @@ loadcidfont(pdf_font *font, int csi, int kind)
if (findcidfont(fontsubs[i].name, path, sizeof path))
{
pdf_logfont("load system font '%s'\n", fontsubs[i].name);
- fterr = FT_New_Face(ftlib, path, 0, (FT_Face*)&font->ftface);
- if (fterr)
- return fz_throw("freetype: cannot load font: %s", ft_errstr(fterr));
+
+ error = fz_newfontfromfile(&font->font, path, 0);
+ if (error)
+ return fz_rethrow(error, "cannot load freetype font from file: %s", path);
+
return fz_okay;
}
}
@@ -254,7 +228,7 @@ loadcidfont(pdf_font *font, int csi, int kind)
}
fz_error *
-pdf_loadsystemfont(pdf_font *font, char *fontname, char *collection)
+pdf_loadsystemfont(pdf_fontdesc *font, char *fontname, char *collection)
{
fz_error *error;
char *name;
@@ -265,11 +239,9 @@ pdf_loadsystemfont(pdf_font *font, char *fontname, char *collection)
int isscript = 0;
int isfixed = 0;
- error = initfontlibs();
- if (error)
- return fz_rethrow(error, "cannot init font libraries");
-
- font->substitute = 1;
+//XXX error = initfontlibs();
+// if (error)
+// return fz_rethrow(error, "cannot init font libraries");
if (strstr(fontname, "Bold"))
isbold = 1;
@@ -358,20 +330,21 @@ pdf_loadsystemfont(pdf_font *font, char *fontname, char *collection)
if (error)
return fz_throw("cannot load builtin substitute font: %s", name);
+ /* it's a substitute font: override the metrics */
+ font->font->ftsubstitute = 1;
+
return fz_okay;
}
fz_error *
-pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref)
+pdf_loadembeddedfont(pdf_fontdesc *font, pdf_xref *xref, fz_obj *stmref)
{
fz_error *error;
- int fterr;
- FT_Face face;
fz_buffer *buf;
- error = initfontlibs();
- if (error)
- return fz_rethrow(error, "cannot init font libraries");
+//XXX error = initfontlibs();
+// if (error)
+// return fz_rethrow(error, "cannot init font libraries");
pdf_logfont("load embedded font\n");
@@ -379,15 +352,15 @@ pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref)
if (error)
return fz_rethrow(error, "cannot load font stream");
- fterr = FT_New_Memory_Face(ftlib, buf->rp, buf->wp - buf->rp, 0, &face);
- if (fterr)
+ error = fz_newfontfrombuffer(&font->font, buf->rp, buf->wp - buf->rp, 0);
+ if (error)
{
fz_dropbuffer(buf);
- return fz_throw("freetype: cannot load embedded font: %s", ft_errstr(fterr));
+ return fz_rethrow(error, "cannot load embedded font (%d %d R)", fz_tonum(stmref), fz_togen(stmref));
}
- font->ftface = face;
- font->fontdata = buf;
+//XXX font->ftbuffer = buf->rp; /* save the buffer so we can free it later */
+// fz_free(buf); /* only free the fz_buffer struct, not the contained data */
return fz_okay;
}
diff --git a/mupdf/pdf_fontfilefc.c b/mupdf/pdf_fontfilefc.c
index 904fbb9a..5573f128 100644
--- a/mupdf/pdf_fontfilefc.c
+++ b/mupdf/pdf_fontfilefc.c
@@ -71,7 +71,7 @@ static fz_error *initfontlibs(void)
fterr = FT_Init_FreeType(&ftlib);
if (fterr)
- return fz_throw("freetype failed initialisation: %s", ft_errstr(fterr));
+ return fz_throw("freetype failed initialisation: %s", ft_errorstring(fterr));
FT_Library_Version(ftlib, &maj, &min, &pat);
if (maj == 2 && min == 1 && pat < 7)
@@ -130,7 +130,7 @@ pdf_loadbuiltinfont(pdf_font *font, char *basefont)
fterr = FT_New_Face(ftlib, file, index, &face);
if (fterr)
- return fz_throw("freetype could not load font file '%s': %s", file, ft_errstr(fterr));
+ return fz_throw("freetype could not load font file '%s': %s", file, ft_errorstring(fterr));
FcPatternDestroy(matchpat);
FcPatternDestroy(searchpat);
@@ -247,7 +247,7 @@ pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection)
if (fterr) {
FcPatternDestroy(matchpat);
FcPatternDestroy(searchpat);
- return fz_throw("freetype could not load font file '%s': %s", file, ft_errstr(fterr));
+ return fz_throw("freetype could not load font file '%s': %s", file, ft_errorstring(fterr));
}
FcPatternDestroy(matchpat);
@@ -284,7 +284,7 @@ pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref)
if (fterr) {
fz_free(buf);
- return fz_throw("freetype could not load embedded font: %s", ft_errstr(fterr));
+ return fz_throw("freetype could not load embedded font: %s", ft_errorstring(fterr));
}
font->ftface = face;
diff --git a/mupdf/pdf_fontfilems.c b/mupdf/pdf_fontfilems.c
index 24fa846d..e5d9d551 100644
--- a/mupdf/pdf_fontfilems.c
+++ b/mupdf/pdf_fontfilems.c
@@ -679,7 +679,7 @@ static fz_error *initfontlibs(void)
fterr = FT_Init_FreeType(&ftlib);
if (fterr)
- return fz_throw("freetype failed initialisation: %s", ft_errstr(fterr));
+ return fz_throw("freetype failed initialisation: %s", ft_errorstring(fterr));
FT_Library_Version(ftlib, &maj, &min, &pat);
if (maj == 2 && min == 1 && pat < 7)
@@ -712,7 +712,7 @@ pdf_loadbuiltinfont(pdf_font *font, char *basefont)
fterr = FT_New_Face(ftlib, file, index, &face);
if (fterr)
- return fz_throw("freetype could not load font file '%s': %s", file, ft_errstr(fterr));
+ return fz_throw("freetype could not load font file '%s': %s", file, ft_errorstring(fterr));
font->ftface = face;
@@ -738,7 +738,7 @@ pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection)
fterr = FT_New_Face(ftlib, file, index, &face);
if (fterr) {
- return fz_throw("freetype could not load font file '%s': %s", file, ft_errstr(fterr));
+ return fz_throw("freetype could not load font file '%s': %s", file, ft_errorstring(fterr));
}
font->ftface = face;
@@ -769,7 +769,7 @@ pdf_loadembeddedfont(pdf_font *font, pdf_xref *xref, fz_obj *stmref)
if (fterr) {
fz_free(buf);
- return fz_throw("freetype could not load embedded font: %s", ft_errstr(fterr));
+ return fz_throw("freetype could not load embedded font: %s", ft_errorstring(fterr));
}
font->ftface = face;
diff --git a/mupdf/pdf_fontmtx.c b/mupdf/pdf_fontmtx.c
new file mode 100644
index 00000000..cf1560f8
--- /dev/null
+++ b/mupdf/pdf_fontmtx.c
@@ -0,0 +1,179 @@
+#include "fitz.h"
+#include "mupdf.h"
+
+void
+pdf_setfontwmode(pdf_fontdesc *font, int wmode)
+{
+ font->wmode = wmode;
+}
+
+void
+pdf_setdefaulthmtx(pdf_fontdesc *font, int w)
+{
+ font->dhmtx.w = w;
+}
+
+void
+pdf_setdefaultvmtx(pdf_fontdesc *font, int y, int w)
+{
+ font->dvmtx.y = y;
+ font->dvmtx.w = w;
+}
+
+fz_error *
+pdf_addhmtx(pdf_fontdesc *font, int lo, int hi, int w)
+{
+ int newcap;
+ pdf_hmtx *newmtx;
+
+ if (font->nhmtx + 1 >= font->hmtxcap)
+ {
+ newcap = font->hmtxcap + 16;
+ newmtx = fz_realloc(font->hmtx, sizeof(pdf_hmtx) * newcap);
+ if (!newmtx)
+ return fz_outofmem;
+ font->hmtxcap = newcap;
+ font->hmtx = newmtx;
+ }
+
+ font->hmtx[font->nhmtx].lo = lo;
+ font->hmtx[font->nhmtx].hi = hi;
+ font->hmtx[font->nhmtx].w = w;
+ font->nhmtx++;
+
+ return fz_okay;
+}
+
+fz_error *
+pdf_addvmtx(pdf_fontdesc *font, int lo, int hi, int x, int y, int w)
+{
+ int newcap;
+ pdf_vmtx *newmtx;
+
+ if (font->nvmtx + 1 >= font->vmtxcap)
+ {
+ newcap = font->vmtxcap + 16;
+ newmtx = fz_realloc(font->vmtx, sizeof(pdf_vmtx) * newcap);
+ if (!newmtx)
+ return fz_outofmem;
+ font->vmtxcap = newcap;
+ font->vmtx = newmtx;
+ }
+
+ 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;
+ font->nvmtx++;
+
+ return fz_okay;
+}
+
+static int cmph(const void *a0, const void *b0)
+{
+ pdf_hmtx *a = (pdf_hmtx*)a0;
+ pdf_hmtx *b = (pdf_hmtx*)b0;
+ return a->lo - b->lo;
+}
+
+static int cmpv(const void *a0, const void *b0)
+{
+ pdf_vmtx *a = (pdf_vmtx*)a0;
+ pdf_vmtx *b = (pdf_vmtx*)b0;
+ return a->lo - b->lo;
+}
+
+fz_error *
+pdf_endhmtx(pdf_fontdesc *font)
+{
+ pdf_hmtx *newmtx;
+
+ if (!font->hmtx)
+ return fz_okay;
+
+ qsort(font->hmtx, font->nhmtx, sizeof(pdf_hmtx), cmph);
+
+ newmtx = fz_realloc(font->hmtx, sizeof(pdf_hmtx) * font->nhmtx);
+ if (!newmtx)
+ return fz_outofmem;
+ font->hmtxcap = font->nhmtx;
+ font->hmtx = newmtx;
+
+ return fz_okay;
+}
+
+fz_error *
+pdf_endvmtx(pdf_fontdesc *font)
+{
+ pdf_vmtx *newmtx;
+
+ if (!font->vmtx)
+ return fz_okay;
+
+ qsort(font->vmtx, font->nvmtx, sizeof(pdf_vmtx), cmpv);
+
+ newmtx = fz_realloc(font->vmtx, sizeof(pdf_vmtx) * font->nvmtx);
+ if (!newmtx)
+ return fz_outofmem;
+ font->vmtxcap = font->nvmtx;
+ font->vmtx = newmtx;
+
+ return fz_okay;
+}
+
+pdf_hmtx
+pdf_gethmtx(pdf_fontdesc *font, int cid)
+{
+ int l = 0;
+ int r = font->nhmtx - 1;
+ int m;
+
+ if (!font->hmtx)
+ goto notfound;
+
+ while (l <= r)
+ {
+ m = (l + r) >> 1;
+ if (cid < font->hmtx[m].lo)
+ r = m - 1;
+ else if (cid > font->hmtx[m].hi)
+ l = m + 1;
+ else
+ return font->hmtx[m];
+ }
+
+notfound:
+ return font->dhmtx;
+}
+
+pdf_vmtx
+pdf_getvmtx(pdf_fontdesc *font, int cid)
+{
+ pdf_hmtx h;
+ pdf_vmtx v;
+ int l = 0;
+ int r = font->nvmtx - 1;
+ int m;
+
+ if (!font->vmtx)
+ goto notfound;
+
+ while (l <= r)
+ {
+ m = (l + r) >> 1;
+ if (cid < font->vmtx[m].lo)
+ r = m - 1;
+ else if (cid > font->vmtx[m].hi)
+ l = m + 1;
+ else
+ return font->vmtx[m];
+ }
+
+notfound:
+ h = pdf_gethmtx(font, cid);
+ v = font->dvmtx;
+ v.x = h.w / 2;
+ return v;
+}
+
diff --git a/mupdf/pdf_resources.c b/mupdf/pdf_resources.c
index 7a2c750c..52bd624e 100644
--- a/mupdf/pdf_resources.c
+++ b/mupdf/pdf_resources.c
@@ -180,13 +180,13 @@ static fz_error *
preloadfont(pdf_xref *xref, fz_obj *ref)
{
fz_error *error;
- pdf_font *font;
+ pdf_fontdesc *font;
fz_obj *obj = ref;
error = pdf_resolve(&obj, xref);
if (error)
return fz_rethrow(error, "cannot resolve font resource (%d %d R)", fz_tonum(ref), fz_togen(ref));
error = pdf_loadfont(&font, xref, obj, ref);
- fz_dropfont((fz_font*)font); /* we did this just to fill the store, no need to hold on to it */
+ pdf_dropfont(font); /* we did this just to fill the store, no need to hold on to it */
if (error)
return fz_rethrow(error, "cannot load font resource (%d %d R)", fz_tonum(ref), fz_togen(ref));
return fz_okay;
diff --git a/mupdf/pdf_store.c b/mupdf/pdf_store.c
index 917a1ebc..ab8004a0 100644
--- a/mupdf/pdf_store.c
+++ b/mupdf/pdf_store.c
@@ -58,7 +58,7 @@ static void dropitem(pdf_itemkind kind, void *val)
case PDF_KPATTERN: pdf_droppattern(val); break;
case PDF_KSHADE: fz_dropshade(val); break;
case PDF_KCMAP: pdf_dropcmap(val); break;
- case PDF_KFONT: fz_dropfont(val); break;
+ case PDF_KFONT: pdf_dropfont(val); break;
}
}
@@ -234,7 +234,7 @@ pdf_removeitem(pdf_store *store, pdf_itemkind kind, fz_obj *key)
case PDF_KPATTERN: pdf_droppattern(val); break;
case PDF_KSHADE: fz_dropshade(val); break;
case PDF_KCMAP: pdf_dropcmap(val); break;
- case PDF_KFONT: fz_dropfont(val); break;
+ case PDF_KFONT: pdf_dropfont(val); break;
}
}
diff --git a/mupdf/pdf_type3.c b/mupdf/pdf_type3.c
index 7948a9a5..35f0591b 100644
--- a/mupdf/pdf_type3.c
+++ b/mupdf/pdf_type3.c
@@ -1,68 +1,6 @@
#include "fitz.h"
#include "mupdf.h"
-/* TODO: we leak the pixmap buffer. not good. we should render into the glyph cache directly or keep it in the font struct.. */
-
-#define GCMEM (4 * 1024)
-
-extern pdf_font *pdf_newfont(char *name);
-
-static void
-t3dropfont(fz_font *font)
-{
- int i;
- pdf_font *pfont = (pdf_font*)font;
- if (pfont->encoding)
- pdf_dropcmap(pfont->encoding);
- for (i = 0; i < 256; i++)
- if (pfont->charprocs[i])
- fz_droptree(pfont->charprocs[i]);
-}
-
-static fz_error *
-t3render(fz_glyph *glyph, fz_font *fzfont, int cid, fz_matrix trm)
-{
- pdf_font *font = (pdf_font*)fzfont;
- fz_error *error;
- fz_renderer *gc;
- fz_tree *tree;
- fz_pixmap *pixmap;
- fz_matrix ctm;
- fz_irect bbox;
-
- if (cid < 0 || cid > 255)
- return fz_throw("assert: glyph out of range");
-
- tree = font->charprocs[cid];
- if (!tree)
- {
- glyph->w = 0;
- glyph->h = 0;
- return fz_okay;
- }
-
- ctm = fz_concat(font->matrix, trm);
- bbox = fz_roundrect(fz_boundtree(tree, ctm));
-
- error = fz_newrenderer(&gc, pdf_devicegray, 1, GCMEM);
- if (error)
- return fz_rethrow(error, "cannot create renderer");
- error = fz_rendertree(&pixmap, gc, tree, ctm, bbox, 0);
- fz_droprenderer(gc);
- if (error)
- return fz_rethrow(error, "cannot render glyph");
-
- assert(pixmap->n == 1);
-
- glyph->x = pixmap->x;
- glyph->y = pixmap->y;
- glyph->w = pixmap->w;
- glyph->h = pixmap->h;
- glyph->samples = pixmap->samples;
-
- return fz_okay;
-}
-
static fz_error *
loadcharproc(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref)
{
@@ -98,12 +36,12 @@ loadcharproc(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref)
}
fz_error *
-pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
+pdf_loadtype3font(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
{
fz_error *error;
char buf[256];
char *estrings[256];
- pdf_font *font;
+ pdf_fontdesc *fontdesc;
fz_obj *encoding;
fz_obj *widths;
fz_obj *resources;
@@ -119,23 +57,20 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
else
sprintf(buf, "Unnamed-T3");
- font = pdf_newfont(buf);
- if (!font)
+ fontdesc = pdf_newfontdesc();
+ if (!fontdesc)
return fz_throw("outofmem: font struct");
- pdf_logfont("load type3 font (%d %d R) ptr=%p {\n", fz_tonum(ref), fz_togen(ref), font);
+ pdf_logfont("load type3 font (%d %d R) ptr=%p {\n", fz_tonum(ref), fz_togen(ref), fontdesc);
pdf_logfont("name %s\n", buf);
- font->super.render = t3render;
- font->super.drop = (void(*)(fz_font*)) t3dropfont;
-
obj = fz_dictgets(dict, "FontMatrix");
- font->matrix = pdf_tomatrix(obj);
+ fontdesc->font->t3matrix = pdf_tomatrix(obj);
pdf_logfont("matrix [%g %g %g %g %g %g]\n",
- font->matrix.a, font->matrix.b,
- font->matrix.c, font->matrix.d,
- font->matrix.e, font->matrix.f);
+ fontdesc->font->t3matrix.a, fontdesc->font->t3matrix.b,
+ fontdesc->font->t3matrix.c, fontdesc->font->t3matrix.d,
+ fontdesc->font->t3matrix.e, fontdesc->font->t3matrix.f);
obj = fz_dictgets(dict, "FontBBox");
bbox = pdf_torect(obj);
@@ -144,12 +79,12 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
bbox.x0, bbox.y0,
bbox.x1, bbox.y1);
- bbox = fz_transformaabb(font->matrix, bbox);
+ bbox = fz_transformaabb(fontdesc->font->t3matrix, bbox);
bbox.x0 = fz_floor(bbox.x0 * 1000);
bbox.y0 = fz_floor(bbox.y0 * 1000);
bbox.x1 = fz_ceil(bbox.x1 * 1000);
bbox.y1 = fz_ceil(bbox.y1 * 1000);
- fz_setfontbbox((fz_font*)font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
+ fz_setfontbbox(fontdesc->font, bbox.x0, bbox.y0, bbox.x1, bbox.y1);
/*
* Encoding
@@ -199,11 +134,11 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
fz_dropobj(encoding);
- error = pdf_newidentitycmap(&font->encoding, 0, 1);
+ error = pdf_newidentitycmap(&fontdesc->encoding, 0, 1);
if (error)
goto cleanup;
- error = pdf_loadtounicode(font, xref,
+ error = pdf_loadtounicode(fontdesc, xref,
estrings, nil, fz_dictgets(dict, "ToUnicode"));
if (error)
goto cleanup;
@@ -212,7 +147,7 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
* Widths
*/
- fz_setdefaulthmtx((fz_font*)font, 0);
+ pdf_setdefaulthmtx(fontdesc, 0);
first = fz_toint(fz_dictgets(dict, "FirstChar"));
last = fz_toint(fz_dictgets(dict, "LastChar"));
@@ -230,8 +165,8 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
for (i = first; i <= last; i++)
{
float w = fz_toreal(fz_arrayget(widths, i - first));
- w = font->matrix.a * w * 1000.0;
- error = fz_addhmtx((fz_font*)font, i, i, w);
+ w = fontdesc->font->t3matrix.a * w * 1000.0;
+ error = pdf_addhmtx(fontdesc, i, i, w);
if (error) {
fz_dropobj(widths);
goto cleanup;
@@ -240,7 +175,7 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
fz_dropobj(widths);
- error = fz_endhmtx((fz_font*)font);
+ error = pdf_endhmtx(fontdesc);
if (error)
goto cleanup;
@@ -290,11 +225,11 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
if (obj)
{
pdf_logfont("load charproc %s {\n", estrings[i]);
- error = loadcharproc(&font->charprocs[i], xref, resources, obj);
+ error = loadcharproc(&fontdesc->font->t3procs[i], xref, resources, obj);
if (error)
goto cleanup2;
- error = fz_optimizetree(font->charprocs[i]);
+ error = fz_optimizetree(fontdesc->font->t3procs[i]);
if (error)
goto cleanup2;
@@ -309,14 +244,15 @@ pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
pdf_logfont("}\n");
- *fontp = font;
+ *fontdescp = fontdesc;
return fz_okay;
cleanup2:
if (resources)
fz_dropobj(resources);
cleanup:
- fz_dropfont((fz_font*)font);
+ fz_dropfont(fontdesc->font);
+ fz_free(fontdesc);
return fz_rethrow(error, "cannot load type3 font");
}
diff --git a/mupdf/pdf_unicode.c b/mupdf/pdf_unicode.c
index 8c3a90a2..4001b5b0 100644
--- a/mupdf/pdf_unicode.c
+++ b/mupdf/pdf_unicode.c
@@ -6,7 +6,7 @@
*/
fz_error *
-pdf_loadtounicode(pdf_font *font, pdf_xref *xref,
+pdf_loadtounicode(pdf_fontdesc *font, pdf_xref *xref,
char **strings, char *collection, fz_obj *cmapstm)
{
fz_error *error = fz_okay;
@@ -115,9 +115,15 @@ pdf_loadtounicode(pdf_font *font, pdf_xref *xref,
}
/*
- * Extract lines of text from display tree
+ * Extract lines of text from display tree.
+ *
+ * This extraction needs to be rewritten for the new tree
+ * architecture where glyph index and unicode characters are both stored
+ * in the text objects.
*/
+#if 0
+
fz_error *
pdf_newtextline(pdf_textline **linep)
{
@@ -175,7 +181,7 @@ extracttext(pdf_textline **line, fz_node *node, fz_matrix ctm)
if (fz_istextnode(node))
{
fz_textnode *text = (fz_textnode*)node;
- pdf_font *font = (pdf_font*)text->font;
+ pdf_fontdesc *font = (pdf_fontdesc*)text->font;
fz_matrix inv = fz_invertmatrix(text->trm);
fz_matrix tm = text->trm;
fz_matrix trm;
@@ -183,7 +189,7 @@ extracttext(pdf_textline **line, fz_node *node, fz_matrix ctm)
fz_point p;
fz_point vx;
fz_point vy;
- fz_vmtx v;
+ _vmtx v;
fz_hmtx h;
int i, g;
int x, y;
@@ -329,3 +335,5 @@ pdf_debugtextline(pdf_textline *line)
pdf_debugtextline(line->next);
}
+#endif
+
diff --git a/raster/glyphcache.c b/raster/glyphcache.c
index e2d93bc9..fe03524e 100644
--- a/raster/glyphcache.c
+++ b/raster/glyphcache.c
@@ -352,9 +352,22 @@ fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz
ctm.e = fz_floor(ctm.e) + key.e / 256.0;
ctm.f = fz_floor(ctm.f) + key.f / 256.0;
- error = font->render(glyph, font, cid, ctm);
- if (error)
+ if (font->ftface)
+ {
+ error = fz_renderftglyph(glyph, font, cid, ctm);
+ if (error)
+ return error;
+ }
+ else if (font->t3procs)
+ {
+ error = fz_rendert3glyph(glyph, font, cid, ctm);
+ if (error)
return error;
+ }
+ else
+ {
+ return fz_throw("uninitialized font structure");
+ }
size = glyph->w * glyph->h;
diff --git a/raster/render.c b/raster/render.c
index bbdf019f..90ead6a7 100644
--- a/raster/render.c
+++ b/raster/render.c
@@ -315,7 +315,7 @@ rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm)
fz_irect clip;
fz_matrix tm, trm;
fz_glyph glyph;
- int i, x, y, cid;
+ int i, x, y, gid;
tbox = fz_roundrect(fz_boundnode((fz_node*)text, ctm));
clip = fz_intersectirects(gc->clip, tbox);
@@ -339,7 +339,7 @@ text->trm.a, text->trm.b, text->trm.c, text->trm.d);
for (i = 0; i < text->len; i++)
{
- cid = text->els[i].cid;
+ gid = text->els[i].gid;
tm.e = text->els[i].x;
tm.f = text->els[i].y;
trm = fz_concat(tm, ctm);
@@ -348,7 +348,7 @@ text->trm.a, text->trm.b, text->trm.c, text->trm.d);
trm.e = QUANT(trm.e - fz_floor(trm.e), HSUBPIX);
trm.f = QUANT(trm.f - fz_floor(trm.f), VSUBPIX);
- error = fz_renderglyph(gc->cache, &glyph, text->font, cid, trm);
+ error = fz_renderglyph(gc->cache, &glyph, text->font, gid, trm);
if (error)
return error;
diff --git a/world/node_text.c b/world/node_text.c
index b816196e..86a523df 100644
--- a/world/node_text.c
+++ b/world/node_text.c
@@ -129,11 +129,12 @@ growtext(fz_textnode *text, int n)
}
fz_error *
-fz_addtext(fz_textnode *text, int cid, float x, float y)
+fz_addtext(fz_textnode *text, int gid, int ucs, float x, float y)
{
if (growtext(text, 1) != nil)
return fz_outofmem;
- text->els[text->len].cid = cid;
+ text->els[text->len].ucs = ucs;
+ text->els[text->len].gid = gid;
text->els[text->len].x = x;
text->els[text->len].y = y;
text->len++;
diff --git a/world/node_toxml.c b/world/node_toxml.c
index 4dff8dbf..cc87c997 100644
--- a/world/node_toxml.c
+++ b/world/node_toxml.c
@@ -119,12 +119,12 @@ static void xmltext(fz_textnode *node, int level)
for (i = 0; i < node->len; i++)
{
indent(level + 1);
- if (node->els[i].cid >= 32 && node->els[i].cid < 128)
- printf("<g c=\"%c\" x=\"%g\" y=\"%g\" />\n",
- node->els[i].cid, node->els[i].x, node->els[i].y);
+ if (node->els[i].ucs >= 32 && node->els[i].ucs < 128)
+ printf("<g ucs=\"%c\" gid=%d x=\"%g\" y=\"%g\" />\n",
+ node->els[i].ucs, node->els[i].gid, node->els[i].x, node->els[i].y);
else
- printf("<g c=\"<%04x>\" x=\"%g\" y=\"%g\" />\n",
- node->els[i].cid, node->els[i].x, node->els[i].y);
+ printf("<g ucs=\"U+%04X\" gid=%d x=\"%g\" y=\"%g\" />\n",
+ node->els[i].ucs, node->els[i].gid, node->els[i].x, node->els[i].y);
}
indent(level);
diff --git a/world/res_font.c b/world/res_font.c
index 9d5f29bf..299f0d50 100644
--- a/world/res_font.c
+++ b/world/res_font.c
@@ -1,35 +1,34 @@
#include "fitz-base.h"
#include "fitz-world.h"
+#include "fitz-draw.h" /* for type3 font rendering */
-void
-fz_initfont(fz_font *font, char *name)
+#include <ft2build.h>
+#include FT_FREETYPE_H
+
+static fz_font *
+fz_newfont(void)
{
+ fz_font *font;
+
+ font = fz_malloc(sizeof(fz_font));
+ if (!font)
+ return nil;
+
font->refs = 1;
- strlcpy(font->name, name, sizeof font->name);
+ strcpy(font->name, "<unknown>");
+
+ font->ftsubstitute = 0;
+ font->ftface = nil;
- font->wmode = 0;
+ font->t3matrix = fz_identity();
+ font->t3procs = nil;
font->bbox.x0 = 0;
font->bbox.y0 = 0;
font->bbox.x1 = 1000;
font->bbox.y1 = 1000;
- font->hmtxcap = 0;
- font->vmtxcap = 0;
- font->nhmtx = 0;
- font->nvmtx = 0;
- font->hmtx = nil;
- font->vmtx = nil;
-
- font->dhmtx.lo = 0x0000;
- font->dhmtx.hi = 0xFFFF;
- font->dhmtx.w = 0;
-
- font->dvmtx.lo = 0x0000;
- font->dvmtx.hi = 0xFFFF;
- font->dvmtx.x = 0;
- font->dvmtx.y = 880;
- font->dvmtx.w = -1000;
+ return font;
}
fz_font *
@@ -42,23 +41,28 @@ fz_keepfont(fz_font *font)
void
fz_dropfont(fz_font *font)
{
+ int i;
+
if (font && --font->refs == 0)
{
- if (font->drop)
- font->drop(font);
- fz_free(font->hmtx);
- fz_free(font->vmtx);
+ if (font->t3procs)
+ {
+ for (i = 0; i < 256; i++)
+ if (font->t3procs[i])
+ fz_droptree(font->t3procs[i]);
+ fz_free(font->t3procs);
+ }
+
+ if (font->ftface)
+ {
+ FT_Done_Face((FT_Face)font->ftface);
+ }
+
fz_free(font);
}
}
void
-fz_setfontwmode(fz_font *font, int wmode)
-{
- font->wmode = wmode;
-}
-
-void
fz_setfontbbox(fz_font *font, int xmin, int ymin, int xmax, int ymax)
{
font->bbox.x0 = xmin;
@@ -67,204 +71,310 @@ fz_setfontbbox(fz_font *font, int xmin, int ymin, int xmax, int ymax)
font->bbox.y1 = ymax;
}
-void
-fz_setdefaulthmtx(fz_font *font, int w)
+/*
+ * Freetype hooks
+ */
+
+static FT_Library fz_ftlib = nil;
+
+#undef __FTERRORS_H__
+#define FT_ERRORDEF(e, v, s) { (e), (s) },
+#define FT_ERROR_START_LIST
+#define FT_ERROR_END_LIST { 0, NULL }
+
+struct ft_error
{
- font->dhmtx.w = w;
-}
+ int err;
+ char *str;
+};
-void
-fz_setdefaultvmtx(fz_font *font, int y, int w)
+const struct ft_error ft_errors[] =
{
- font->dvmtx.y = y;
- font->dvmtx.w = w;
+#include FT_ERRORS_H
+};
+
+char *ft_errorstring(int err)
+{
+ const struct ft_error *e;
+
+ for (e = ft_errors; e->str != NULL; e++)
+ if (e->err == err)
+ return e->str;
+
+ return "Unknown error";
}
-fz_error *
-fz_addhmtx(fz_font *font, int lo, int hi, int w)
+static fz_error *
+fz_initfreetype(void)
{
- int newcap;
- fz_hmtx *newmtx;
+ int code;
+ int maj, min, pat;
- if (font->nhmtx + 1 >= font->hmtxcap)
- {
- newcap = font->hmtxcap + 16;
- newmtx = fz_realloc(font->hmtx, sizeof(fz_hmtx) * newcap);
- if (!newmtx)
- return fz_outofmem;
- font->hmtxcap = newcap;
- font->hmtx = newmtx;
- }
+ if (fz_ftlib)
+ return fz_okay;
+
+ code = FT_Init_FreeType(&fz_ftlib);
+ if (code)
+ return fz_throw("cannot init freetype: %s", ft_errorstring(code));
- font->hmtx[font->nhmtx].lo = lo;
- font->hmtx[font->nhmtx].hi = hi;
- font->hmtx[font->nhmtx].w = w;
- font->nhmtx++;
+ FT_Library_Version(fz_ftlib, &maj, &min, &pat);
+ if (maj == 2 && min == 1 && pat < 7)
+ return fz_throw("freetype version too old: %d.%d.%d", maj, min, pat);
return fz_okay;
}
fz_error *
-fz_addvmtx(fz_font *font, int lo, int hi, int x, int y, int w)
+fz_newfontfromfile(fz_font **fontp, char *path, int index)
{
- int newcap;
- fz_vmtx *newmtx;
+ fz_error *error;
+ fz_font *font;
+ int code;
- if (font->nvmtx + 1 >= font->vmtxcap)
+ error = fz_initfreetype();
+ if (error)
+ return fz_rethrow(error, "cannot init freetype library");
+
+ font = fz_newfont();
+ if (!font)
+ return fz_throw("outofmem: font struct");
+
+ code = FT_New_Face(fz_ftlib, path, index, (FT_Face*)&font->ftface);
+ if (code)
{
- newcap = font->vmtxcap + 16;
- newmtx = fz_realloc(font->vmtx, sizeof(fz_vmtx) * newcap);
- if (!newmtx)
- return fz_outofmem;
- font->vmtxcap = newcap;
- font->vmtx = newmtx;
+ fz_free(font);
+ return fz_throw("freetype: cannot load font: %s", ft_errorstring(code));
}
- 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;
- font->nvmtx++;
-
+ *fontp = font;
return fz_okay;
}
-static int cmph(const void *a0, const void *b0)
-{
- fz_hmtx *a = (fz_hmtx*)a0;
- fz_hmtx *b = (fz_hmtx*)b0;
- 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->lo - b->lo;
-}
-
fz_error *
-fz_endhmtx(fz_font *font)
+fz_newfontfrombuffer(fz_font **fontp, unsigned char *data, int len, int index)
{
- fz_hmtx *newmtx;
+ fz_error *error;
+ fz_font *font;
+ int code;
- if (!font->hmtx)
- return fz_okay;
+ error = fz_initfreetype();
+ if (error)
+ return fz_rethrow(error, "cannot init freetype library");
- qsort(font->hmtx, font->nhmtx, sizeof(fz_hmtx), cmph);
+ font = fz_newfont();
+ if (!font)
+ return fz_throw("outofmem: font struct");
- newmtx = fz_realloc(font->hmtx, sizeof(fz_hmtx) * font->nhmtx);
- if (!newmtx)
- return fz_outofmem;
- font->hmtxcap = font->nhmtx;
- font->hmtx = newmtx;
+ code = FT_New_Memory_Face(fz_ftlib, data, len, index, (FT_Face*)&font->ftface);
+ if (code)
+ {
+ fz_free(font);
+ return fz_throw("freetype: cannot load font: %s", ft_errorstring(code));
+ }
+ *fontp = font;
return fz_okay;
}
fz_error *
-fz_endvmtx(fz_font *font)
+fz_renderftglyph(fz_glyph *glyph, fz_font *font, int gid, fz_matrix trm)
{
- fz_vmtx *newmtx;
+ FT_Face face = font->ftface;
+ FT_Matrix m;
+ FT_Vector v;
+ FT_Error fterr;
+ int x, y;
+
+#if 0
+ /* We lost this feature in refactoring.
+ * We can't access pdf_fontdesc metrics from fz_font.
+ * The pdf_fontdesc metrics are character based (cid),
+ * where the glyph being rendered is given by glyph (gid).
+ */
+ if (font->ftsubstitute && font->wmode == 0)
+ {
+ fz_hmtx subw;
+ int realw;
+ float scale;
- if (!font->vmtx)
- return fz_okay;
+ FT_Set_Char_Size(face, 1000, 1000, 72, 72);
- qsort(font->vmtx, font->nvmtx, sizeof(fz_vmtx), cmpv);
+ 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: %s", ft_errorstring(fterr));
+
+ realw = ((FT_Face)font->ftface)->glyph->advance.x;
+ subw = fz_gethmtx(font, cid); // <-- this is the offender
+ if (realw)
+ scale = (float) subw.w / realw;
+ else
+ scale = 1.0;
- newmtx = fz_realloc(font->vmtx, sizeof(fz_vmtx) * font->nvmtx);
- if (!newmtx)
- return fz_outofmem;
- font->vmtxcap = font->nvmtx;
- font->vmtx = newmtx;
+ trm = fz_concat(fz_scale(scale, 1.0), trm);
+ }
+#endif
+
+ glyph->w = 0;
+ glyph->h = 0;
+ glyph->x = 0;
+ glyph->y = 0;
+ glyph->samples = nil;
+
+ /* freetype mutilates complex glyphs if they are loaded
+ * with FT_Set_Char_Size 1.0. it rounds the coordinates
+ * before applying transformation. to get more precision in
+ * freetype, we shift part of the scale in the matrix
+ * into FT_Set_Char_Size instead
+ */
+
+ m.xx = trm.a * 64; /* should be 65536 */
+ m.yx = trm.b * 64;
+ m.xy = trm.c * 64;
+ m.yy = trm.d * 64;
+ v.x = trm.e * 64;
+ v.y = trm.f * 64;
+
+ FT_Set_Char_Size(face, 65536, 65536, 72, 72); /* should be 64, 64 */
+ FT_Set_Transform(face, &m, &v);
+
+ fterr = FT_Load_Glyph(face, gid, FT_LOAD_NO_BITMAP | FT_LOAD_NO_HINTING);
+ if (fterr)
+ fz_warn("freetype load glyph: %s", ft_errorstring(fterr));
+ fterr = FT_Render_Glyph(face->glyph, ft_render_mode_normal);
+
+ if (fterr)
+ fz_warn("freetype render glyph: %s", ft_errorstring(fterr));
+
+ glyph->w = face->glyph->bitmap.width;
+ glyph->h = face->glyph->bitmap.rows;
+ glyph->x = face->glyph->bitmap_left;
+ glyph->y = face->glyph->bitmap_top - glyph->h;
+ glyph->samples = face->glyph->bitmap.buffer;
+
+ for (y = 0; y < glyph->h / 2; y++)
+ {
+ for (x = 0; x < glyph->w; x++)
+ {
+ unsigned char a = glyph->samples[y * glyph->w + x ];
+ unsigned char b = glyph->samples[(glyph->h - y - 1) * glyph->w + x];
+ glyph->samples[y * glyph->w + x ] = b;
+ glyph->samples[(glyph->h - y - 1) * glyph->w + x] = a;
+ }
+ }
return fz_okay;
}
-fz_hmtx
-fz_gethmtx(fz_font *font, int cid)
+
+/*
+ * Type 3 fonts...
+ */
+
+fz_error *
+fz_newtype3font(fz_font **fontp, char *name, fz_matrix matrix, void **procs0)
{
- int l = 0;
- int r = font->nhmtx - 1;
- int m;
+ fz_font *font;
+ fz_tree **procs = (fz_tree**)procs0;
+ int i;
- if (!font->hmtx)
- goto notfound;
+ font = fz_newfont();
+ if (!font)
+ return fz_throw("outofmem: font struct");
- while (l <= r)
+ font->t3procs = fz_malloc(sizeof(fz_tree*) * 256);
+ if (!font->t3procs)
{
- m = (l + r) >> 1;
- if (cid < font->hmtx[m].lo)
- r = m - 1;
- else if (cid > font->hmtx[m].hi)
- l = m + 1;
- else
- return font->hmtx[m];
+ fz_free(font);
+ return fz_throw("outofmem: type3 font charproc array");
}
-notfound:
- return font->dhmtx;
+ font->t3matrix = matrix;
+ for (i = 0; i < 256; i++)
+ font->t3procs[i] = procs[i];
+
+ strlcpy(font->name, name, sizeof(font->name));
+
+ *fontp = font;
+ return fz_okay;
}
-fz_vmtx
-fz_getvmtx(fz_font *font, int cid)
+fz_error *
+fz_rendert3glyph(fz_glyph *glyph, fz_font *font, int gid, fz_matrix trm)
{
- fz_hmtx h;
- fz_vmtx v;
- int l = 0;
- int r = font->nvmtx - 1;
- int m;
+ fz_error *error;
+ fz_renderer *gc;
+ fz_tree *tree;
+ fz_matrix ctm;
+ fz_irect bbox;
+
+ /* TODO: make it reentrant */
+ static fz_pixmap *pixmap = nil;
+ if (pixmap)
+ {
+ fz_droppixmap(pixmap);
+ pixmap = nil;
+ }
+
+ if (gid < 0 || gid > 255)
+ return fz_throw("assert: glyph out of range");
+
+ tree = font->t3procs[gid];
+ if (!tree)
+ {
+ glyph->w = 0;
+ glyph->h = 0;
+ return fz_okay;
+ }
- if (!font->vmtx)
- goto notfound;
+ /* XXX UGLY HACK XXX */
+ extern fz_colorspace *pdf_devicegray;
- while (l <= r)
- {
- m = (l + r) >> 1;
- if (cid < font->vmtx[m].lo)
- r = m - 1;
- else if (cid > font->vmtx[m].hi)
- l = m + 1;
- else
- return font->vmtx[m];
- }
+ ctm = fz_concat(font->t3matrix, trm);
+ bbox = fz_roundrect(fz_boundtree(tree, ctm));
+
+ error = fz_newrenderer(&gc, pdf_devicegray, 1, 4096);
+ if (error)
+ return fz_rethrow(error, "cannot create renderer");
+ error = fz_rendertree(&pixmap, gc, tree, ctm, bbox, 0);
+ fz_droprenderer(gc);
+ if (error)
+ return fz_rethrow(error, "cannot render glyph");
-notfound:
- h = fz_gethmtx(font, cid);
- v = font->dvmtx;
- v.x = h.w / 2;
- return v;
+ assert(pixmap->n == 1);
+
+ glyph->x = pixmap->x;
+ glyph->y = pixmap->y;
+ glyph->w = pixmap->w;
+ glyph->h = pixmap->h;
+ glyph->samples = pixmap->samples;
+
+ return fz_okay;
}
void
fz_debugfont(fz_font *font)
{
- int i;
-
printf("font '%s' {\n", font->name);
- printf(" wmode %d\n", font->wmode);
- printf(" bbox [%d %d %d %d]\n",
- font->bbox.x0, font->bbox.y0,
- font->bbox.x1, font->bbox.y1);
- printf(" DW %d\n", font->dhmtx.w);
- printf(" W {\n");
- for (i = 0; i < font->nhmtx; i++)
- printf(" <%04x> <%04x> %d\n",
- font->hmtx[i].lo, font->hmtx[i].hi, font->hmtx[i].w);
- printf(" }\n");
+ if (font->ftface)
+ {
+ printf(" freetype face %p\n", font->ftface);
+ if (font->ftsubstitute)
+ printf(" substitute metrics\n");
+ }
- if (font->wmode)
+ if (font->t3procs)
{
- printf(" DW2 [%d %d]\n", font->dvmtx.y, font->dvmtx.w);
- printf(" W2 {\n");
- for (i = 0; i < font->nvmtx; i++)
- 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");
+ printf(" type3 matrix [%g %g %g %g]\n",
+ font->t3matrix.a, font->t3matrix.b,
+ font->t3matrix.c, font->t3matrix.d);
}
+ printf(" bbox [%d %d %d %d]\n",
+ font->bbox.x0, font->bbox.y0,
+ font->bbox.x1, font->bbox.y1);
+
printf("}\n");
}