summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorTor Andersson <tor@ghostscript.com>2004-12-06 18:08:20 +0100
committerTor Andersson <tor@ghostscript.com>2004-12-06 18:08:20 +0100
commitf04ff9cf7f22f9a34f6e9ed1d8159fe67eb2c79d (patch)
treedd43cdef26db51a5ee7edc232b7406721cce2edf
parent6162dc43d376fce8906160d51e3ab076d83632aa (diff)
downloadmupdf-f04ff9cf7f22f9a34f6e9ed1d8159fe67eb2c79d.tar.xz
xref parse workaround. font config messing. shade cleanup.
-rw-r--r--Jamfile4
-rw-r--r--TODO16
-rw-r--r--filter/filec.c6
-rw-r--r--filter/jbig2d.c2
-rw-r--r--include/fitz/base.h3
-rw-r--r--mupdf/colorspace1.c34
-rw-r--r--mupdf/debug.c14
-rw-r--r--mupdf/font.c3
-rw-r--r--mupdf/fontfile.c172
-rw-r--r--mupdf/fontfilefc.c23
-rw-r--r--mupdf/open.c11
-rw-r--r--mupdf/shade.c6
-rw-r--r--mupdf/shade2.c2
-rw-r--r--mupdf/shade3.c23
-rw-r--r--mupdf/store.c6
-rw-r--r--render/glyphcache.c11
-rw-r--r--render/optunpack.c4
-rw-r--r--render/render.c21
-rw-r--r--test/gtkpdf.c72
-rw-r--r--test/x11pdf.c8
-rw-r--r--tree/path.c3
21 files changed, 322 insertions, 122 deletions
diff --git a/Jamfile b/Jamfile
index 81992755..c6b8061c 100644
--- a/Jamfile
+++ b/Jamfile
@@ -208,8 +208,8 @@ Main pdffunction : test/pdffunction.c ;
Main x11pdf : test/x11pdf.c test/ximage.c ;
-CCFLAGS += `gtk-config --cflags` ;
-LINKLIBS on gtkpdf = $(LINKLIBS) `gtk-config --libs` -lgthread ;
+CCFLAGS += `pkg-config --cflags gtk+ gthread` ;
+LINKLIBS on gtkpdf = $(LINKLIBS) `pkg-config --libs gtk+ gmodule gthread` ;
Main gtkpdf : test/gtkpdf.c ;
diff --git a/TODO b/TODO
index 63dd9669..6d41f0d9 100644
--- a/TODO
+++ b/TODO
@@ -1,15 +1,25 @@
immediate plan:
+
- altivec optimize
- - page labels + dests + outline + annots
- design gui for editor
- go through spec and check all features!
- talk to keithp about fontconfig cid-font + cmap support
+ * page labels + dests + outline + annots
+
+ * libfontfocus
+
+ * font and cmap config (where to load cmap and which cid fonts)
+ - global fontfile/cmap cache
- unify handling of mallocing fonts and images
- - font and cmap config (where to load cmap and which cid fonts)
- - global font/cmap cache
- split type3 and ftfont malloc (dont waste t3 charprocs on ft fonts)
- make ftfontfile separate struct w/ refcounting
+ - refactor font loading more. simple/cid/type3 have too much in common.
+ fix default .fonts.conf for base14 fonts
+ fix default .fonts.conf for asian fonts
+ maybe add CMap directory entry to fontconfig?
+
+ * clean up and 'freeze' public api
---
diff --git a/filter/filec.c b/filter/filec.c
index 5ea3c75a..4388b48a 100644
--- a/filter/filec.c
+++ b/filter/filec.c
@@ -276,6 +276,12 @@ fz_seek(fz_file *f, int ofs, int whence)
return ofs;
}
+ if (whence == 1)
+ {
+ ofs = fz_tell(f) + ofs;
+ whence = 0;
+ }
+
t = lseek(f->fd, ofs, whence);
if (t == -1)
{
diff --git a/filter/jbig2d.c b/filter/jbig2d.c
index f0022bda..ed54eed3 100644
--- a/filter/jbig2d.c
+++ b/filter/jbig2d.c
@@ -12,7 +12,7 @@
+create the per-page ctx
*/
-#ifdef WIN32 /* Microsoft Visual C+*/
+#ifdef WIN32 /* Microsoft Visual C++ */
typedef signed char int8_t;
typedef short int int16_t;
diff --git a/include/fitz/base.h b/include/fitz/base.h
index 562bb1df..d6b35592 100644
--- a/include/fitz/base.h
+++ b/include/fitz/base.h
@@ -4,6 +4,9 @@
#undef offsetof
#define offsetof(s, m) (unsigned long)(&(((s*)0)->m))
+#undef nelem
+#define nelem(x) (sizeof(x)/sizeof((x)[0]))
+
#undef ABS
#define ABS(x) ( (x) < 0 ? -(x) : (x) )
diff --git a/mupdf/colorspace1.c b/mupdf/colorspace1.c
index 3be2c6be..e9c384b9 100644
--- a/mupdf/colorspace1.c
+++ b/mupdf/colorspace1.c
@@ -227,9 +227,14 @@ fz_colorspace *pdf_devicepattern = &kdevicepattern;
static fz_error *
loadcalgray(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
{
+ fz_error *error;
struct calgray *cs;
fz_obj *tmp;
+ error = pdf_resolve(&dict, xref);
+ if (error)
+ return error;
+
cs = fz_malloc(sizeof(struct calgray));
if (!cs)
return fz_outofmem;
@@ -268,6 +273,8 @@ loadcalgray(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
if (fz_isreal(tmp))
cs->gamma = fz_toreal(tmp);
+ fz_dropobj(dict);
+
*csp = (fz_colorspace*) cs;
return nil;
}
@@ -275,10 +282,15 @@ loadcalgray(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
static fz_error *
loadcalrgb(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
{
+ fz_error *error;
struct calrgb *cs;
fz_obj *tmp;
int i;
+ error = pdf_resolve(&dict, xref);
+ if (error)
+ return error;
+
cs = fz_malloc(sizeof(struct calrgb));
if (!cs)
return fz_outofmem;
@@ -336,6 +348,8 @@ loadcalrgb(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
fz_invert3x3(cs->invmat, cs->matrix);
+ fz_dropobj(dict);
+
*csp = (fz_colorspace*) cs;
return nil;
}
@@ -343,9 +357,14 @@ loadcalrgb(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
static fz_error *
loadlab(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
{
+ fz_error *error;
struct cielab *cs;
fz_obj *tmp;
+ error = pdf_resolve(&dict, xref);
+ if (error)
+ return error;
+
cs = fz_malloc(sizeof(struct cielab));
if (!cs)
return fz_outofmem;
@@ -392,6 +411,8 @@ loadlab(fz_colorspace **csp, pdf_xref *xref, fz_obj *dict)
cs->range[3] = fz_toreal(fz_arrayget(tmp, 3));
}
+ fz_dropobj(dict);
+
*csp = (fz_colorspace*) cs;
return nil;
}
@@ -705,12 +726,21 @@ pdf_loadcolorspace(fz_colorspace **csp, pdf_xref *xref, fz_obj *obj)
/* load base colorspace instead */
else if (!strcmp(fz_toname(name), "Pattern"))
{
- if (!fz_arrayget(obj, 1))
+ fz_error *error;
+
+ obj = fz_arrayget(obj, 1);
+ if (!obj)
{
*csp = pdf_devicepattern;
return nil;
}
- return pdf_loadcolorspace(csp, xref, fz_arrayget(obj, 1));
+
+ error = pdf_resolve(&obj, xref);
+ if (error)
+ return error;
+ error = pdf_loadcolorspace(csp, xref, obj);
+ fz_dropobj(obj);
+ return error;
}
else
diff --git a/mupdf/debug.c b/mupdf/debug.c
index 3a300e6a..d51fa476 100644
--- a/mupdf/debug.c
+++ b/mupdf/debug.c
@@ -19,7 +19,7 @@ enum
PDF_LPAGE = 32,
};
-static inline void log(int tag, char *name, char *fmt, va_list ap)
+static inline void pdflog(int tag, char *name, char *fmt, va_list ap)
{
static int flags = 128;
static int level = 0;
@@ -71,20 +71,20 @@ static inline void log(int tag, char *name, char *fmt, va_list ap)
}
void pdf_logxref(char *fmt, ...)
-{va_list ap;va_start(ap,fmt);log(PDF_LXREF,"xref",fmt,ap);va_end(ap);}
+{va_list ap;va_start(ap,fmt);pdflog(PDF_LXREF,"xref",fmt,ap);va_end(ap);}
void pdf_logrsrc(char *fmt, ...)
-{va_list ap;va_start(ap,fmt);log(PDF_LRSRC,"rsrc",fmt,ap);va_end(ap);}
+{va_list ap;va_start(ap,fmt);pdflog(PDF_LRSRC,"rsrc",fmt,ap);va_end(ap);}
void pdf_logfont(char *fmt, ...)
-{va_list ap;va_start(ap,fmt);log(PDF_LFONT,"font",fmt,ap);va_end(ap);}
+{va_list ap;va_start(ap,fmt);pdflog(PDF_LFONT,"font",fmt,ap);va_end(ap);}
void pdf_logimage(char *fmt, ...)
-{va_list ap;va_start(ap,fmt);log(PDF_LIMAGE,"imag",fmt,ap);va_end(ap);}
+{va_list ap;va_start(ap,fmt);pdflog(PDF_LIMAGE,"imag",fmt,ap);va_end(ap);}
void pdf_logshade(char *fmt, ...)
-{va_list ap;va_start(ap,fmt);log(PDF_LSHADE,"shad",fmt,ap);va_end(ap);}
+{va_list ap;va_start(ap,fmt);pdflog(PDF_LSHADE,"shad",fmt,ap);va_end(ap);}
void pdf_logpage(char *fmt, ...)
-{va_list ap;va_start(ap,fmt);log(PDF_LPAGE,"page",fmt,ap);va_end(ap);}
+{va_list ap;va_start(ap,fmt);pdflog(PDF_LPAGE,"page",fmt,ap);va_end(ap);}
diff --git a/mupdf/font.c b/mupdf/font.c
index 50d2b187..eeb48ac6 100644
--- a/mupdf/font.c
+++ b/mupdf/font.c
@@ -963,6 +963,9 @@ pdf_loadfontdescriptor(pdf_font *font, pdf_xref *xref, fz_obj *desc, char *colle
obj3 = fz_dictgets(desc, "FontFile3");
obj = obj1 ? obj1 : obj2 ? obj2 : obj3;
+ if (getenv("NOFONT"))
+ obj = nil;
+
if (fz_isindirect(obj))
{
error = pdf_loadembeddedfont(font, xref, obj);
diff --git a/mupdf/fontfile.c b/mupdf/fontfile.c
index 72e0c1b5..e5e4e3a8 100644
--- a/mupdf/fontfile.c
+++ b/mupdf/fontfile.c
@@ -40,15 +40,6 @@ static char *basenames[15] =
"Chancery"
};
-static struct { char *collection; char *serif; char *gothic; } cidfonts[5] =
-{
- { "Adobe-CNS1", "bkai00mp.ttf", "bsmi00lp.ttf" },
- { "Adobe-GB1", "gkai00mp.ttf", "gbsn00lp.ttf" },
- { "Adobe-Japan1", "kochi-mincho.ttf", "kochi-gothic.ttf" },
- { "Adobe-Japan2", "kochi-mincho.ttf", "kochi-gothic.ttf" },
- { "Adobe-Korea1", "batang.ttf", "dotum.ttf" },
-};
-
static void loadfontdata(int i, unsigned char **d, unsigned int *l)
{
switch (i)
@@ -71,6 +62,42 @@ static void loadfontdata(int i, unsigned char **d, unsigned int *l)
}
}
+enum { CNS, GB, Japan, Korea };
+enum { MINCHO, GOTHIC };
+
+struct subent { int csi; int kind; char *name; };
+
+static struct subent fontsubs[] =
+{
+ { CNS, MINCHO, "bkai00mp.ttf" },
+ { CNS, GOTHIC, "bsmi00lp.ttf" },
+ { CNS, MINCHO, "\345\204\267\345\256\213 Pro.ttf" }, /* LiSong Pro */
+ { CNS, GOTHIC, "\345\204\267\351\273\221 Pro.ttf" }, /* LiHei Pro */
+ { CNS, MINCHO, "simsun.ttc" },
+ { CNS, GOTHIC, "simhei.ttf" },
+
+ { GB, MINCHO, "gkai00mp.ttf" },
+ { GB, GOTHIC, "gbsn00lp.ttf" },
+ { GB, MINCHO, "\345\215\216\346\226\207\345\256\213\344\275\223.ttf" }, /* STSong */
+ { GB, GOTHIC, "\345\215\216\346\226\207\346\245\267\344\275\223.ttf" }, /* STHeiti */
+ { GB, MINCHO, "mingliu.ttc" },
+ { GB, GOTHIC, "mingliu.ttc" },
+
+ { Japan, MINCHO, "\343\203\222\343\203\251\343\202\255\343\202\231\343\203\216\346\230\216\346\234\235 Pro W3.otf" },
+ { Japan, GOTHIC, "\343\203\222\343\203\251\343\202\255\343\202\231\343\203\216\350\247\222\343\202\263\343\202\231 Pro W3.otf" },
+ { Japan, MINCHO, "kochi-mincho.ttf" },
+ { Japan, GOTHIC, "kochi-gothic.ttf" },
+ { Japan, MINCHO, "msmincho.ttc" },
+ { Japan, GOTHIC, "msgothic.ttc" },
+
+ { Korea, MINCHO, "batang.ttf" },
+ { Korea, GOTHIC, "dotum.ttf" },
+ { Korea, MINCHO, "AppleMyungjo.dfont" },
+ { Korea, GOTHIC, "AppleGothic.dfont" },
+ { Korea, MINCHO, "batang.ttc" },
+ { Korea, GOTHIC, "dotum.ttc" },
+};
+
static fz_error *initfontlibs(void)
{
int fterr;
@@ -121,34 +148,87 @@ found:
return nil;
}
-static fz_error *
-loadcidfont(pdf_font *font, char *filename)
+static int
+findcidfont(char *filename, char *path, int pathlen)
{
- char path[1024];
- char *fontdir;
- int e;
+ static char *dirs[] =
+ {
+ "$/.fonts",
+ "$/Library/Fonts",
+ "/usr/X11R6/lib/X11/fonts/TTF",
+ "/usr/X11R6/lib/X11/fonts/TrueType",
+ "/usr/share/fonts/arphic",
+ "/usr/share/fonts/baekmuk",
+ "/usr/share/fonts/kochi",
+ "/System/Library/Fonts",
+ "/Library/Fonts",
+ "c:/windows/fonts",
+ nil
+ };
+
+ char **dirp;
+ char *home;
+ char *dir;
+
+ dir = getenv("FONTDIR");
+ if (dir)
+ {
+ strlcpy(path, dir, pathlen);
+ strlcat(path, "/", pathlen);
+ strlcat(path, filename, pathlen);
+ if (access(path, R_OK) == 0)
+ return 1;
+ }
- pdf_logfont("load system font '%s'\n", filename);
+ home = getenv("HOME");
+ if (!home)
+ home = "/";
- fontdir = getenv("FONTDIR");
- if (!fontdir)
+ for (dirp = dirs; *dirp; dirp++)
{
- fontdir = "/usr/local/share/font";
- fz_warn("FONTDIR environment not set");
+ dir = *dirp;
+ if (dir[0] == '$')
+ {
+ strlcpy(path, home, pathlen);
+ strlcat(path, "/", pathlen);
+ strlcat(path, dir + 1, pathlen);
+ }
+ else
+ {
+ strlcpy(path, dir, pathlen);
+ }
+ strlcat(path, "/", pathlen);
+ strlcat(path, filename, pathlen);
+ if (access(path, R_OK) == 0)
+ return 1;
}
- strlcpy(path, fontdir, sizeof path);
- strlcat(path, "/", sizeof path);
- strlcat(path, filename, sizeof path);
+ return 0;
+}
- if (access(path, R_OK))
- return fz_throw("ioerror: could not access file '%s'", path);
+static fz_error *
+loadcidfont(pdf_font *font, int csi, int kind)
+{
+ char path[1024];
+ int e;
+ int i;
- e = FT_New_Face(ftlib, path, 0, (FT_Face*)&font->ftface);
- if (e)
- return fz_throw("freetype: could not load font: 0x%x", e);
+ for (i = 0; i < nelem(fontsubs); i++)
+ {
+ if (fontsubs[i].csi == csi && fontsubs[i].kind == kind)
+ {
+ if (findcidfont(fontsubs[i].name, path, sizeof path))
+ {
+ pdf_logfont("load system font '%s'\n", fontsubs[i].name);
+ e = FT_New_Face(ftlib, path, 0, (FT_Face*)&font->ftface);
+ if (e)
+ return fz_throw("freetype: could not load font: 0x%x", e);
+ return nil;
+ }
+ }
+ }
- return nil;
+ return fz_throw("could not find cid font file");
}
fz_error *
@@ -156,7 +236,6 @@ pdf_loadsystemfont(pdf_font *font, char *fontname, char *collection)
{
fz_error *error;
char *name;
- int i;
int isbold = 0;
int isitalic = 0;
@@ -193,24 +272,23 @@ pdf_loadsystemfont(pdf_font *font, char *fontname, char *collection)
if (collection)
{
- char buf[256];
- char *env;
-
- snprintf(buf, sizeof buf, "%s_%s", strstr(collection, "-") + 1, isserif ? "S" : "G");
- env = getenv(buf);
- if (env)
- return loadcidfont(font, env);
-
- for (i = 0; i < 5; i++)
- {
- if (!strcmp(collection, cidfonts[i].collection))
- {
- if (isserif)
- return loadcidfont(font, cidfonts[i].serif);
- else
- return loadcidfont(font, cidfonts[i].gothic);
- }
- }
+ int kind;
+
+ if (isserif)
+ kind = MINCHO;
+ else
+ kind = GOTHIC;
+
+ if (!strcmp(collection, "Adobe-CNS1"))
+ return loadcidfont(font, CNS, kind);
+ else if (!strcmp(collection, "Adobe-GB1"))
+ return loadcidfont(font, GB, kind);
+ else if (!strcmp(collection, "Adobe-Japan1"))
+ return loadcidfont(font, Japan, kind);
+ else if (!strcmp(collection, "Adobe-Japan2"))
+ return loadcidfont(font, Japan, kind);
+ else if (!strcmp(collection, "Adobe-Korea1"))
+ return loadcidfont(font, Korea, kind);
fz_warn("unknown cid collection: %s", collection);
}
diff --git a/mupdf/fontfilefc.c b/mupdf/fontfilefc.c
index e7dd0cd1..b4a92929 100644
--- a/mupdf/fontfilefc.c
+++ b/mupdf/fontfilefc.c
@@ -159,17 +159,12 @@ pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection)
if (error)
return error;
- /* parse windows-style font name descriptors Font,Style or Font-Style */
+ /* parse windows-style font name descriptors Font,Style */
+ /* TODO: reliable way to split style from Font-Style type names */
strlcpy(fontname, basefont, sizeof fontname);
style = strchr(fontname, ',');
- if (style) {
+ if (style)
*style++ = 0;
- }
- else {
- style = strchr(fontname, '-');
- if (style)
- *style++ = 0;
- }
searchpat = FcPatternCreate();
if (!searchpat)
@@ -183,10 +178,10 @@ pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection)
if (collection)
{
if (!strcmp(collection, "Adobe-GB1"))
- if (!FcPatternAddString(searchpat, FC_LANG, "zh"))
+ if (!FcPatternAddString(searchpat, FC_LANG, "zh-TW"))
goto cleanup;
if (!strcmp(collection, "Adobe-CNS1"))
- if (!FcPatternAddString(searchpat, FC_LANG, "zh"))
+ if (!FcPatternAddString(searchpat, FC_LANG, "zh-CN"))
goto cleanup;
if (!strcmp(collection, "Adobe-Japan1"))
if (!FcPatternAddString(searchpat, FC_LANG, "ja"))
@@ -216,13 +211,17 @@ pdf_loadsystemfont(pdf_font *font, char *basefont, char *collection)
goto cleanup;
file = FcNameUnparse(searchpat);
- pdf_logfont("fontconfig %s\n", file);
+ pdf_logfont("fontconfig0 %s\n", file);
free(file);
fcerr = FcResultMatch;
- FcDefaultSubstitute(searchpat);
+/* FcDefaultSubstitute(searchpat); */
FcConfigSubstitute(fclib, searchpat, FcMatchPattern);
+ file = FcNameUnparse(searchpat);
+ pdf_logfont("fontconfig1 %s\n", file);
+ free(file);
+
matchpat = FcFontMatch(fclib, searchpat, &fcerr);
if (fcerr != FcResultMatch)
return fz_throw("fontconfig could not find font %s", basefont);
diff --git a/mupdf/open.c b/mupdf/open.c
index 0dcd1d62..1be868c9 100644
--- a/mupdf/open.c
+++ b/mupdf/open.c
@@ -98,6 +98,10 @@ readoldtrailer(pdf_xref *xref, char *buf, int cap)
ofs = atoi(strsep(&s, " "));
len = atoi(strsep(&s, " "));
+ /* broken pdfs where the section is not on a separate line */
+ if (s && *s != '\0')
+ fz_seek(xref->file, -(n + buf - s + 2), 1);
+
t = fz_tell(xref->file);
if (t < 0) return fz_ferror(xref->file);
@@ -175,6 +179,13 @@ readoldxref(fz_obj **trailerp, pdf_xref *xref, char *buf, int cap)
ofs = atoi(strsep(&s, " "));
len = atoi(strsep(&s, " "));
+ /* broken pdfs where the section is not on a separate line */
+ if (s && *s != '\0')
+ {
+ fz_warn("syntaxerror: broken xref section");
+ fz_seek(xref->file, -(n + buf - s + 2), 1);
+ }
+
for (i = 0; i < len; i++)
{
n = fz_read(xref->file, buf, 20);
diff --git a/mupdf/shade.c b/mupdf/shade.c
index b80453d5..524c70f9 100644
--- a/mupdf/shade.c
+++ b/mupdf/shade.c
@@ -39,7 +39,7 @@ pdf_loadshadedict(fz_shade **shadep, pdf_xref *xref, fz_obj *shading, fz_obj *re
shade->matrix = mat;
- pdf_logshade("load shade dict {\n");
+ pdf_logshade("load shade dict %d %d {\n", fz_tonum(ref), fz_togen(ref));
sobj = fz_dictgets(shading, "ShadingType");
type = fz_toint(sobj);
@@ -124,7 +124,7 @@ pdf_loadshade(fz_shade **shadep, pdf_xref *xref, fz_obj *obj, fz_obj *ref)
if ((*shadep = pdf_finditem(xref->store, PDF_KSHADE, ref)))
return nil;
- pdf_logshade("loading shade %d %d {\n", fz_tonum(ref), fz_togen(ref));
+ pdf_logshade("load shade %d %d {\n", fz_tonum(ref), fz_togen(ref));
shading = fz_dictgets(obj, "Shading");
@@ -165,7 +165,7 @@ cleanup:
void
pdf_setmeshvalue(float *mesh, int i, float x, float y, float t)
{
- pdf_logshade("mesh %d: %g %g %g\n", i, x, y, t);
+// pdf_logshade("mesh %d: %g %g %g\n", i, x, y, t);
mesh[i*3+0] = x;
mesh[i*3+1] = y;
mesh[i*3+2] = t;
diff --git a/mupdf/shade2.c b/mupdf/shade2.c
index b9f86d5f..94d6ad64 100644
--- a/mupdf/shade2.c
+++ b/mupdf/shade2.c
@@ -11,7 +11,7 @@ pdf_buildt2shademesh(fz_shade *shade, pdf_xref *xref, fz_obj *shading,
fz_obj *obj;
pdf_function *func;
- pdf_logshade("loading type2 shade {\n");
+ pdf_logshade("load type2 shade {\n");
obj = fz_dictgets(shading, "Coords");
x0 = fz_toreal(fz_arrayget(obj, 0));
diff --git a/mupdf/shade3.c b/mupdf/shade3.c
index c77fbec6..50aa4fe9 100644
--- a/mupdf/shade3.c
+++ b/mupdf/shade3.c
@@ -43,8 +43,8 @@ fz_buildannulusmesh(float* mesh,
}
fz_error *
-pdf_buildt3shademesh(fz_shade *shade, pdf_xref *xref, fz_obj *shading,
- fz_obj *ref, fz_matrix mat)
+pdf_loadtype3shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading,
+ fz_obj *ref, fz_matrix mat)
{
fz_error *error;
float x0, y0, r0, x1, y1, r1;
@@ -52,6 +52,8 @@ pdf_buildt3shademesh(fz_shade *shade, pdf_xref *xref, fz_obj *shading,
fz_obj *obj;
pdf_function *func;
+ pdf_logshade("load type3 shade {\n");
+
obj = fz_dictgets(shading, "Coords");
x0 = fz_toreal(fz_arrayget(obj, 0));
y0 = fz_toreal(fz_arrayget(obj, 1));
@@ -60,6 +62,8 @@ pdf_buildt3shademesh(fz_shade *shade, pdf_xref *xref, fz_obj *shading,
y1 = fz_toreal(fz_arrayget(obj, 4));
r1 = fz_toreal(fz_arrayget(obj, 5));
+ pdf_logshade("coords %g %g %g %g %g %g\n", x0, y0, r0, x1, y1, r1);
+
obj = fz_dictgets(shading, "Domain");
if (obj) {
t0 = fz_toreal(fz_arrayget(obj, 0));
@@ -69,6 +73,8 @@ pdf_buildt3shademesh(fz_shade *shade, pdf_xref *xref, fz_obj *shading,
t1 = 1.;
}
+ pdf_logshade("domain %g %g\n", t0, t1);
+
pdf_loadshadefunction(shade, xref, shading, t0, t1);
shade->meshlen = 36 * 10 * 2;
@@ -96,20 +102,11 @@ pdf_buildt3shademesh(fz_shade *shade, pdf_xref *xref, fz_obj *shading,
fz_buildannulusmesh(&(shade->mesh[i*36*2*9]), tx0, ty0, tr0, tx1, ty1, tr1, c0, c1, 36);
}
+ pdf_logshade("}\n");
+
return nil;
cleanup:
return error;
}
-fz_error *
-pdf_loadtype3shade(fz_shade *shade, pdf_xref *xref, fz_obj *shading,
- fz_obj *ref, fz_matrix mat)
-{
- fz_error *error;
- fz_obj *obj;
-
- error = pdf_buildt3shademesh(shade, xref, shading, ref, mat);
-
- return error;
-}
diff --git a/mupdf/store.c b/mupdf/store.c
index a5e19b18..1c7f09d3 100644
--- a/mupdf/store.c
+++ b/mupdf/store.c
@@ -5,9 +5,9 @@ typedef struct pdf_item_s pdf_item;
struct pdf_item_s
{
- pdf_itemkind kind;
- fz_obj *key;
- void *val;
+ pdf_itemkind kind;
+ fz_obj *key;
+ void *val;
pdf_item *next;
};
diff --git a/render/glyphcache.c b/render/glyphcache.c
index 93b25b4c..9fd4a5a7 100644
--- a/render/glyphcache.c
+++ b/render/glyphcache.c
@@ -1,8 +1,5 @@
#include <fitz.h>
-#define HSUBPIX 5.0
-#define VSUBPIX 5.0
-
typedef struct fz_hash_s fz_hash;
typedef struct fz_key_s fz_key;
typedef struct fz_val_s fz_val;
@@ -321,8 +318,8 @@ fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz
key.b = ctm.b * 65536;
key.c = ctm.c * 65536;
key.d = ctm.d * 65536;
- key.e = (ctm.e - fz_floor(ctm.e)) * HSUBPIX;
- key.f = (ctm.f - fz_floor(ctm.f)) * VSUBPIX;
+ key.e = (ctm.e - fz_floor(ctm.e)) * 256;
+ key.f = (ctm.f - fz_floor(ctm.f)) * 256;
val = hashfind(arena, &key);
if (val)
@@ -339,8 +336,8 @@ fz_renderglyph(fz_glyphcache *arena, fz_glyph *glyph, fz_font *font, int cid, fz
return nil;
}
- ctm.e = fz_floor(ctm.e) + key.e / HSUBPIX;
- ctm.f = fz_floor(ctm.f) + key.f / VSUBPIX;
+ 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)
diff --git a/render/optunpack.c b/render/optunpack.c
index 1c77a787..0885c293 100644
--- a/render/optunpack.c
+++ b/render/optunpack.c
@@ -8,8 +8,8 @@ typedef unsigned char byte;
static void decodetile(fz_pixmap *pix, int skip, float *decode)
{
- int min[FZ_MAXCOLORS];
- int max[FZ_MAXCOLORS];
+ int min[FZ_MAXCOLORS];
+ int max[FZ_MAXCOLORS];
int sub[FZ_MAXCOLORS];
int useless = 1;
byte *p = pix->samples;
diff --git a/render/render.c b/render/render.c
index 41c0d3c1..0b08e158 100644
--- a/render/render.c
+++ b/render/render.c
@@ -5,6 +5,10 @@
#define DEBUG(args...)
#endif
+#define QUANT(x,a) (((int)((x) * (a))) / (a))
+#define HSUBPIX 5.0
+#define VSUBPIX 5.0
+
#define FNONE 0
#define FOVER 1
#define FRGB 4
@@ -227,12 +231,12 @@ static void drawglyph(fz_renderer *gc, fz_pixmap *dst, fz_glyph *src, int xorig,
int sx1 = src->w;
int sy1 = src->h;
- if (x1 < dx0 || x0 >= dx1) return;
- if (y1 < dy0 || y0 >= dy1) return;
+ if (x1 <= dx0 || x0 >= dx1) return;
+ if (y1 <= dy0 || y0 >= dy1) return;
if (x0 < dx0) { sx0 += dx0 - x0; x0 = dx0; }
if (y0 < dy0) { sy0 += dy0 - y0; y0 = dy0; }
- if (x1 >= dx1) { sx1 += dx1 - x1; x1 = dx1; }
- if (y1 >= dy1) { sy1 += dy1 - y1; y1 = dy1; }
+ if (x1 > dx1) { sx1 += dx1 - x1; x1 = dx1; }
+ if (y1 > dy1) { sy1 += dy1 - y1; y1 = dy1; }
sp = src->samples + (sy0 * src->w + sx0);
dp = dst->samples + ((y0 - dst->y) * dst->w + (x0 - dst->x)) * dst->n;
@@ -282,11 +286,6 @@ text->trm.a, text->trm.b, text->trm.c, text->trm.d);
if (fz_isemptyrect(clip))
return nil;
- clip.min.x ++;
- clip.min.y ++;
- clip.max.x ++;
- clip.max.y ++;
-
if (!(gc->flag & FOVER))
{
error = fz_newpixmapwithrect(&gc->dest, clip, 1);
@@ -305,8 +304,8 @@ text->trm.a, text->trm.b, text->trm.c, text->trm.d);
trm = fz_concat(tm, ctm);
x = fz_floor(trm.e);
y = fz_floor(trm.f);
- trm.e = (trm.e - fz_floor(trm.e));
- trm.f = (trm.f - fz_floor(trm.f));
+ 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);
if (error)
diff --git a/test/gtkpdf.c b/test/gtkpdf.c
index 97508310..c50190d3 100644
--- a/test/gtkpdf.c
+++ b/test/gtkpdf.c
@@ -21,12 +21,15 @@ TODO:
typedef struct PDFApp PDFApp;
+enum { ZOOM, FITWIDTH, FITPAGE };
+
struct PDFApp
{
GtkWidget *canvas;
GtkWidget *status;
GtkWidget *scroll;
int statusid;
+ int viewmode;
char *filename;
int pageno;
@@ -85,8 +88,9 @@ static void* drawpage(void*args)
{
char msg[256];
fz_error *error;
+ float scalex, scaley, scale;
fz_matrix ctm;
- fz_rect bbox;
+ fz_irect bbox;
fz_obj *obj;
if (!gapp->xref)
@@ -119,6 +123,39 @@ Lskipload:
gdk_threads_enter();
showstatus(" drawing ... ");
+
+ ctm = fz_identity();
+ ctm = fz_concat(ctm, fz_translate(0, -gapp->page->mediabox.max.y));
+ ctm = fz_concat(ctm, fz_rotate(gapp->rotate + gapp->page->rotate));
+ bbox = fz_roundrect(fz_transformaabb(ctm, gapp->page->mediabox));
+
+ scale = gapp->zoom;
+ scalex = scaley = 1.0;
+
+ if (gapp->viewmode == FITWIDTH || gapp->viewmode == FITPAGE)
+ {
+ GtkAdjustment *hadj;
+ int w;
+ hadj = gtk_scrolled_window_get_hadjustment(GTK_SCROLLED_WINDOW(gapp->scroll));
+ w = bbox.max.x - bbox.min.x;
+ if (w != 0)
+ scalex = hadj->page_size / (float)w;
+ scale = scalex;
+ }
+
+ if (gapp->viewmode == FITPAGE)
+ {
+ GtkAdjustment *vadj;
+ int h;
+ vadj = gtk_scrolled_window_get_vadjustment(GTK_SCROLLED_WINDOW(gapp->scroll));
+ h = bbox.max.y - bbox.min.y;
+ if (h != 0)
+ scaley = vadj->page_size / (float)h;
+ scale = MIN(scale, scaley);
+ }
+
+ gapp->zoom = scale;
+
gdk_threads_leave();
if (gapp->image)
@@ -129,11 +166,9 @@ Lskipload:
ctm = fz_concat(ctm, fz_translate(0, -gapp->page->mediabox.max.y));
ctm = fz_concat(ctm, fz_scale(gapp->zoom, -gapp->zoom));
ctm = fz_concat(ctm, fz_rotate(gapp->rotate + gapp->page->rotate));
+ bbox = fz_roundrect(fz_transformaabb(ctm, gapp->page->mediabox));
- bbox = fz_transformaabb(ctm, gapp->page->mediabox);
-
- error = fz_rendertree(&gapp->image, gapp->gc, gapp->page->tree,
- ctm, fz_roundrect(bbox), 1);
+ error = fz_rendertree(&gapp->image, gapp->gc, gapp->page->tree, ctm, bbox, 1);
if (error)
panic(error);
@@ -291,19 +326,40 @@ static void onlast(GtkWidget *widget, void *data)
forkwork(drawpage);
}
-static void onzoomin(GtkWidget *widget, void *data) { gapp->zoom *= 1.25; forkwork(drawpage); }
-static void onzoomout(GtkWidget *widget, void *data) { gapp->zoom *= 0.8; forkwork(drawpage); }
-static void onzoom100(GtkWidget *widget, void *data) { gapp->zoom = 1.0; forkwork(drawpage); }
+static void onzoomin(GtkWidget * widget, void *data)
+{
+ gapp->viewmode = ZOOM;
+ gapp->zoom *= 1.25;
+ forkwork(drawpage);
+}
+
+static void onzoomout(GtkWidget * widget, void *data)
+{
+ gapp->viewmode = ZOOM;
+ gapp->zoom *= 0.8;
+ forkwork(drawpage);
+}
+
+static void onzoom100(GtkWidget * widget, void *data)
+{
+ gapp->viewmode = ZOOM;
+ gapp->zoom = 1.0;
+ forkwork(drawpage);
+}
static void onrotl(GtkWidget *widget, void *data) { gapp->rotate -= 90; forkwork(drawpage); }
static void onrotr(GtkWidget *widget, void *data) { gapp->rotate += 90; forkwork(drawpage); }
static void onfitwidth(GtkWidget *widget, void *data)
{
+ gapp->viewmode = FITWIDTH;
+ forkwork(drawpage);
}
static void onfitpage(GtkWidget *widget, void *data)
{
+ gapp->viewmode = FITPAGE;
+ forkwork(drawpage);
}
static int startxpos;
diff --git a/test/x11pdf.c b/test/x11pdf.c
index c2f546ab..02aeb8c0 100644
--- a/test/x11pdf.c
+++ b/test/x11pdf.c
@@ -374,6 +374,13 @@ int main(int argc, char **argv)
pdfopen(filename, password);
showpage();
+#ifdef RUNFAST
+ while (pageno < count)
+ {
+ pageno ++;
+ showpage();
+ }
+#else
while (1)
{
int len;
@@ -395,6 +402,7 @@ int main(int argc, char **argv)
break;
}
}
+#endif
pdf_closepdf(xref);
diff --git a/tree/path.c b/tree/path.c
index b623d25c..24b4dfc8 100644
--- a/tree/path.c
+++ b/tree/path.c
@@ -163,6 +163,9 @@ fz_endpath(fz_pathnode *path, fz_pathkind paint, fz_stroke *stroke, fz_dash *das
path->miterlimit = stroke->miterlimit;
}
+ if (path->linewidth < 0.01)
+ path->linewidth = 0.01;
+
return nil;
}