mirror of
https://github.com/reactos/reactos.git
synced 2024-09-17 00:00:42 +00:00
435a566751
* sumatrapdf - vendor import * everything compiles (libjpeg, poppler, fitz, sumatrapdf) * does NOT link (remove the comment tags in the parent directory.rbuild file (rosapps dir) to build it) svn path=/trunk/; revision=29295
312 lines
5.8 KiB
C
312 lines
5.8 KiB
C
#include <fitz.h>
|
|
#include <mupdf.h>
|
|
|
|
#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("rangecheck: glyph out of range");
|
|
|
|
tree = font->charprocs[cid];
|
|
if (!tree)
|
|
{
|
|
glyph->w = 0;
|
|
glyph->h = 0;
|
|
return nil;
|
|
}
|
|
|
|
ctm = fz_concat(font->matrix, trm);
|
|
bbox = fz_roundrect(fz_boundtree(tree, ctm));
|
|
|
|
error = fz_newrenderer(&gc, pdf_devicegray, 1, GCMEM);
|
|
if (error)
|
|
return error;
|
|
error = fz_rendertree(&pixmap, gc, tree, ctm, bbox, 0);
|
|
fz_droprenderer(gc);
|
|
if (error)
|
|
return error;
|
|
|
|
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 nil;
|
|
}
|
|
|
|
static fz_error *
|
|
loadcharproc(fz_tree **treep, pdf_xref *xref, fz_obj *rdb, fz_obj *stmref)
|
|
{
|
|
fz_error *error;
|
|
pdf_csi *csi;
|
|
fz_stream *stm;
|
|
|
|
error = pdf_newcsi(&csi, 1);
|
|
|
|
error = pdf_openstream(&stm, xref, fz_tonum(stmref), fz_togen(stmref));
|
|
if (error)
|
|
return error;
|
|
|
|
error = pdf_runcsi(csi, xref, rdb, stm);
|
|
|
|
fz_dropstream(stm);
|
|
|
|
*treep = csi->tree;
|
|
csi->tree = nil;
|
|
|
|
pdf_dropcsi(csi);
|
|
|
|
return error;
|
|
}
|
|
|
|
fz_error *
|
|
pdf_loadtype3font(pdf_font **fontp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
|
|
{
|
|
fz_error *error;
|
|
char buf[256];
|
|
char *estrings[256];
|
|
pdf_font *font;
|
|
fz_obj *encoding;
|
|
fz_obj *widths;
|
|
fz_obj *resources;
|
|
fz_obj *charprocs;
|
|
fz_obj *obj;
|
|
int first, last;
|
|
int i, k, n;
|
|
fz_rect bbox;
|
|
|
|
obj = fz_dictgets(dict, "Name");
|
|
if (obj)
|
|
strlcpy(buf, fz_toname(obj), sizeof buf);
|
|
else
|
|
sprintf(buf, "Unnamed-T3");
|
|
|
|
font = pdf_newfont(buf);
|
|
if (!font)
|
|
return fz_outofmem;
|
|
|
|
pdf_logfont("load type3 font %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), font);
|
|
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);
|
|
|
|
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);
|
|
|
|
obj = fz_dictgets(dict, "FontBBox");
|
|
bbox = pdf_torect(obj);
|
|
|
|
pdf_logfont("bbox [%g %g %g %g]\n",
|
|
bbox.x0, bbox.y0,
|
|
bbox.x1, bbox.y1);
|
|
|
|
bbox = fz_transformaabb(font->matrix, 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);
|
|
|
|
/*
|
|
* Encoding
|
|
*/
|
|
|
|
for (i = 0; i < 256; i++)
|
|
estrings[i] = nil;
|
|
|
|
encoding = fz_dictgets(dict, "Encoding");
|
|
if (!encoding) {
|
|
error = fz_throw("syntaxerror: Type3 font missing Encoding");
|
|
goto cleanup;
|
|
}
|
|
|
|
error = pdf_resolve(&encoding, xref);
|
|
if (error)
|
|
goto cleanup;
|
|
|
|
if (fz_isname(obj))
|
|
pdf_loadencoding(estrings, fz_toname(encoding));
|
|
|
|
if (fz_isdict(encoding))
|
|
{
|
|
fz_obj *base, *diff, *item;
|
|
|
|
base = fz_dictgets(encoding, "BaseEncoding");
|
|
if (fz_isname(base))
|
|
pdf_loadencoding(estrings, fz_toname(base));
|
|
|
|
diff = fz_dictgets(encoding, "Differences");
|
|
if (fz_isarray(diff))
|
|
{
|
|
n = fz_arraylen(diff);
|
|
k = 0;
|
|
for (i = 0; i < n; i++)
|
|
{
|
|
item = fz_arrayget(diff, i);
|
|
if (fz_isint(item))
|
|
k = fz_toint(item);
|
|
if (fz_isname(item))
|
|
estrings[k++] = fz_toname(item);
|
|
if (k < 0) k = 0;
|
|
if (k > 255) k = 255;
|
|
}
|
|
}
|
|
}
|
|
|
|
fz_dropobj(encoding);
|
|
|
|
error = pdf_newidentitycmap(&font->encoding, 0, 1);
|
|
if (error)
|
|
goto cleanup;
|
|
|
|
error = pdf_loadtounicode(font, xref,
|
|
estrings, nil, fz_dictgets(dict, "ToUnicode"));
|
|
if (error)
|
|
goto cleanup;
|
|
|
|
/*
|
|
* Widths
|
|
*/
|
|
|
|
fz_setdefaulthmtx((fz_font*)font, 0);
|
|
|
|
first = fz_toint(fz_dictgets(dict, "FirstChar"));
|
|
last = fz_toint(fz_dictgets(dict, "LastChar"));
|
|
|
|
widths = fz_dictgets(dict, "Widths");
|
|
if (!widths) {
|
|
error = fz_throw("syntaxerror: Type3 font missing Widths");
|
|
goto cleanup;
|
|
}
|
|
|
|
error = pdf_resolve(&widths, xref);
|
|
if (error)
|
|
goto cleanup;
|
|
|
|
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);
|
|
if (error) {
|
|
fz_dropobj(widths);
|
|
goto cleanup;
|
|
}
|
|
}
|
|
|
|
fz_dropobj(widths);
|
|
|
|
error = fz_endhmtx((fz_font*)font);
|
|
if (error)
|
|
goto cleanup;
|
|
|
|
/*
|
|
* Resources
|
|
*/
|
|
|
|
resources = nil;
|
|
|
|
obj = fz_dictgets(dict, "Resources");
|
|
if (obj)
|
|
{
|
|
error = pdf_resolve(&obj, xref);
|
|
if (error)
|
|
goto cleanup;
|
|
|
|
error = pdf_loadresources(&resources, xref, obj);
|
|
|
|
fz_dropobj(obj);
|
|
|
|
if (error)
|
|
goto cleanup;
|
|
}
|
|
else
|
|
pdf_logfont("no resource dict!\n");
|
|
|
|
/*
|
|
* CharProcs
|
|
*/
|
|
|
|
charprocs = fz_dictgets(dict, "CharProcs");
|
|
if (!charprocs)
|
|
{
|
|
error = fz_throw("syntaxerror: Type3 font missing CharProcs");
|
|
goto cleanup2;
|
|
}
|
|
|
|
error = pdf_resolve(&charprocs, xref);
|
|
if (error)
|
|
goto cleanup2;
|
|
|
|
for (i = 0; i < 256; i++)
|
|
{
|
|
if (estrings[i])
|
|
{
|
|
obj = fz_dictgets(charprocs, estrings[i]);
|
|
if (obj)
|
|
{
|
|
pdf_logfont("load charproc %s {\n", estrings[i]);
|
|
error = loadcharproc(&font->charprocs[i], xref, resources, obj);
|
|
if (error)
|
|
goto cleanup2;
|
|
|
|
error = fz_optimizetree(font->charprocs[i]);
|
|
if (error)
|
|
goto cleanup2;
|
|
|
|
pdf_logfont("}\n");
|
|
}
|
|
}
|
|
}
|
|
|
|
fz_dropobj(charprocs);
|
|
if (resources)
|
|
fz_dropobj(resources);
|
|
|
|
pdf_logfont("}\n");
|
|
|
|
*fontp = font;
|
|
return nil;
|
|
|
|
cleanup2:
|
|
if (resources)
|
|
fz_dropobj(resources);
|
|
cleanup:
|
|
fz_dropfont((fz_font*)font);
|
|
return error;
|
|
}
|
|
|