Beispiel #1
0
fz_rect
fz_boundtextnode(fz_textnode *text, fz_matrix ctm)
{
	fz_matrix trm;
	fz_rect bbox;
	fz_rect fbox;
	int i;

	if (text->len == 0)
		return fz_emptyrect;

	/* find bbox of glyph origins in ctm space */

	bbox.x0 = bbox.x1 = text->els[0].x;
	bbox.y0 = bbox.y1 = text->els[0].y;

	for (i = 1; i < text->len; i++)
	{
		bbox.x0 = MIN(bbox.x0, text->els[i].x);
		bbox.y0 = MIN(bbox.y0, text->els[i].y);
		bbox.x1 = MAX(bbox.x1, text->els[i].x);
		bbox.y1 = MAX(bbox.y1, text->els[i].y);
	}

	bbox = fz_transformaabb(ctm, bbox);

	/* find bbox of font in trm * ctm space */

	trm = fz_concat(text->trm, ctm);
	trm.e = 0;
	trm.f = 0;

	fbox.x0 = text->font->bbox.x0 * 0.001;
	fbox.y0 = text->font->bbox.y0 * 0.001;
	fbox.x1 = text->font->bbox.x1 * 0.001;
	fbox.y1 = text->font->bbox.y1 * 0.001;

	fbox = fz_transformaabb(trm, fbox);

	/* expand glyph origin bbox by font bbox */

	bbox.x0 += fbox.x0;
	bbox.y0 += fbox.y0;
	bbox.x1 += fbox.x1;
	bbox.y1 += fbox.y1;

	return bbox;
}
Beispiel #2
0
fz_rect
fz_boundimagenode(fz_imagenode *node, fz_matrix ctm)
{
	fz_rect bbox;
	bbox.x0 = 0;
	bbox.y0 = 0;
	bbox.x1 = 1;
	bbox.y1 = 1;
	return fz_transformaabb(ctm, bbox);
}
Beispiel #3
0
void pdfmoz_drawpage(pdfmoz_t *moz, int pagenum)
{
    page_t *page = moz->pages + pagenum;
    fz_error error;
    fz_matrix ctm;
    fz_rect bbox;

    if (page->image)
	return;

    ctm = pdfmoz_pagectm(moz, pagenum);
    bbox = fz_transformaabb(ctm, page->page->mediabox);

    error = fz_rendertree(&page->image, moz->rast, page->page->tree,
	    ctm, fz_roundrect(bbox), 1);
    if (error)
	pdfmoz_error(moz, error);
}
Beispiel #4
0
static void recalcScreenMediaBox(PDFContext* ctx) {
	fz_matrix ctm;
	fz_rect bbox;
	float h = ctx->page->mediabox.y1 - ctx->page->mediabox.y0;
	float w = ctx->page->mediabox.x1 - ctx->page->mediabox.x0;
	float x = ctx->page->mediabox.x0;
	float y = ctx->page->mediabox.x0;
	bbox.x0 = x;
	bbox.y0 = y;
	bbox.x1 = x;
	bbox.y1 = y;
	ctm = pdfViewctm(ctx);
	bbox.x1 += w;
	bbox.y1 += h;
	bbox = fz_transformaabb(ctm, bbox);
	screenMediaBox = bbox;
	//printf("sCMB (%g, %g) - (%g, %g)\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1);
}
Beispiel #5
0
static fz_pixmap* pdfRenderTile(PDFContext* ctx, int x, int y, int w, int h, bool transform = false) {
	fz_error *error;
	fz_matrix ctm;
	fz_rect bbox;

	bbox.x0 = x;
	bbox.y0 = y;
	bbox.x1 = x;
	bbox.y1 = y;
	ctm = pdfViewctm(ctx);
	if (transform) {
		bbox.x1 += w;
		bbox.y1 += h;
		bbox = fz_transformaabb(ctm, bbox);
	} else {
		bbox.x0 = x;
		bbox.y0 = y;
		bbox.x1 = bbox.x0 + w;
		bbox.y1 = bbox.y0 + h;
	}
	fz_irect ir = fz_roundrect(bbox);
	/*if (!transform) {
		ir.x1 = ir.x0 + w;
		ir.y1 = ir.y0 + h;
	}*/
	fz_pixmap* pix = NULL;
	error = fz_rendertree(&pix, ctx->rast, ctx->page->tree, ctm, ir, 1);
	if (error) {
		return 0;
	}
	if (BKUser::options.pdfInvertColors) {
		unsigned int* s = (unsigned int*)pix->samples;
		unsigned int n = pix->w * pix->h;
		for (unsigned int i = 0; i < n; ++i) {
			*s = ~(*s);
			++s;
		}
	}
	return pix;
}
Beispiel #6
0
static void drawpnm(int pagenum, struct benchmark *loadtimes, struct benchmark *drawtimes)
{
	fz_error error;
	fz_matrix ctm;
	fz_irect bbox;
	fz_pixmap *pix;
	char name[256];
	char pnmhdr[256];
	int i, x, y, w, h, b, bh;
	int fd = -1;
	long start;
	long end;
	long elapsed;
	fz_md5 digest;

	if (!drawpattern)
		fz_md5init(&digest);

	drawloadpage(pagenum, loadtimes);

	if (benchmark)
		gettime(&start);

	ctm = fz_identity();
	ctm = fz_concat(ctm, fz_translate(0, -drawpage->mediabox.y1));
	ctm = fz_concat(ctm, fz_scale(drawzoom, -drawzoom));
	ctm = fz_concat(ctm, fz_rotate(drawrotate + drawpage->rotate));

	bbox = fz_roundrect(fz_transformaabb(ctm, drawpage->mediabox));
	w = bbox.x1 - bbox.x0;
	h = bbox.y1 - bbox.y0;
	bh = h / drawbands;

	if (drawpattern)
	{
		sprintf(name, drawpattern, drawcount++);
		fd = open(name, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0666);
		if (fd < 0)
			die(fz_throw("ioerror: could not open file '%s'", name));

		sprintf(pnmhdr, "P6\n%d %d\n255\n", w, h);
		write(fd, pnmhdr, strlen(pnmhdr));
	}

	error = fz_newpixmap(&pix, bbox.x0, bbox.y0, w, bh, 4);
	if (error)
		die(error);

	memset(pix->samples, 0xff, pix->h * pix->w * pix->n);

	for (b = 0; b < drawbands; b++)
	{
		if (drawbands > 1)
			fprintf(stderr, "drawing band %d / %d\n", b + 1, drawbands);

		error = fz_rendertreeover(drawgc, pix, drawpage->tree, ctm);
		if (error)
			die(error);

		if (drawpattern)
		{
			for (y = 0; y < pix->h; y++)
			{
				unsigned char *src = pix->samples + y * pix->w * 4;
				unsigned char *dst = src;

				for (x = 0; x < pix->w; x++)
				{
					dst[x * 3 + 0] = src[x * 4 + 1];
					dst[x * 3 + 1] = src[x * 4 + 2];
					dst[x * 3 + 2] = src[x * 4 + 3];
				}

				write(fd, dst, pix->w * 3);

				memset(src, 0xff, pix->w * 4);
			}
		}

		if (!drawpattern)
			fz_md5update(&digest, pix->samples, pix->h * pix->w * 4);

		pix->y += bh;
		if (pix->y + pix->h > bbox.y1)
			pix->h = bbox.y1 - pix->y;
	}

	fz_droppixmap(pix);

	if (!drawpattern) {
		unsigned char buf[16];
		fz_md5final(&digest, buf);
		for (i = 0; i < 16; i++)
			fprintf(stderr, "%02x", buf[i]);
	}

	if (drawpattern)
		close(fd);

	drawfreepage();

	if (benchmark)
	{
		gettime(&end);
		elapsed = end - start;

		if (elapsed < drawtimes->min)
		{
			drawtimes->min = elapsed;
			drawtimes->minpage = pagenum;
		}
		if (elapsed > drawtimes->max)
		{
			drawtimes->max = elapsed;
			drawtimes->maxpage = pagenum;
		}
		drawtimes->avg += elapsed;
		drawtimes->pages++;

		fprintf(stderr, " time %.3fs",
			elapsed / 1000000.0);
	}

	fprintf(stderr, "\n");
}
Beispiel #7
0
fz_error
pdf_loadtype3font(pdf_fontdesc **fontdescp, pdf_xref *xref, fz_obj *rdb, fz_obj *dict)
{
	fz_error error;
	char buf[256];
	char *estrings[256];
	pdf_fontdesc *fontdesc;
	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;
	fz_matrix matrix;

	obj = fz_dictgets(dict, "Name");
	if (fz_isname(obj))
		strlcpy(buf, fz_toname(obj), sizeof buf);
	else
		sprintf(buf, "Unnamed-T3");

	fontdesc = pdf_newfontdesc();

	pdf_logfont("load type3 font (%d %d R) ptr=%p {\n", fz_tonum(dict), fz_togen(dict), fontdesc);
	pdf_logfont("name %s\n", buf);

	obj = fz_dictgets(dict, "FontMatrix");
	matrix = pdf_tomatrix(obj);

	pdf_logfont("matrix [%g %g %g %g %g %g]\n",
		matrix.a, matrix.b,
		matrix.c, matrix.d,
		matrix.e, 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(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);

	fontdesc->font = fz_newtype3font(buf, matrix);

	fz_setfontbbox(fontdesc->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;
	}

	if (fz_isname(encoding))
		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;
			}
		}
	}

	fontdesc->encoding = pdf_newidentitycmap(0, 1);

	error = pdf_loadtounicode(fontdesc, xref, estrings, nil, fz_dictgets(dict, "ToUnicode"));
	if (error)
		goto cleanup;

	/*
	 * Widths
	 */

	pdf_setdefaulthmtx(fontdesc, 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;
	}

	for (i = first; i <= last; i++)
	{
		float w = fz_toreal(fz_arrayget(widths, i - first));
		w = fontdesc->font->t3matrix.a * w * 1000.0;
		fontdesc->font->t3widths[i] = w * 0.001;
		pdf_addhmtx(fontdesc, i, i, w);
	}

	pdf_endhmtx(fontdesc);

	/*
	 * Resources
	 */

	resources = fz_dictgets(dict, "Resources");

	/* Inherit page's resource dict if type3 font does not have one */
	if (!resources && rdb)
		resources = rdb;
	else if (!resources && !rdb)
		fz_warn("no resource dictionary for type 3 font!");

	/*
	 * CharProcs
	 */

	charprocs = fz_dictgets(dict, "CharProcs");
	if (!charprocs)
	{
		error = fz_throw("syntaxerror: Type3 font missing CharProcs");
		goto cleanup;
	}

	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(&fontdesc->font->t3procs[i], xref, resources, obj);
				if (error)
					goto cleanup;

				pdf_logfont("}\n");
			}
		}
	}

	pdf_logfont("}\n");

	*fontdescp = fontdesc;
	return fz_okay;

cleanup:
	fz_dropfont(fontdesc->font);
	fz_free(fontdesc);
	return fz_rethrow(error, "cannot load type3 font");
}
Beispiel #8
0
void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage)
{
	char buf[256];
	fz_error *error;
	fz_matrix ctm;
	fz_rect bbox;
	fz_obj *obj;

	if (loadpage)
	{
		wincursor(app, WAIT);

		if (app->page)
			pdf_droppage(app->page);
		app->page = nil;

		obj = pdf_getpageobject(app->pages, app->pageno - 1);

		error = pdf_loadpage(&app->page, app->xref, obj);
		if (error)
			pdfapp_error(app, error);

		sprintf(buf, "%s - %d/%d", app->doctitle,
				app->pageno, pdf_getpagecount(app->pages));
		wintitle(app, buf);
	}

	if (drawpage)
	{
		wincursor(app, WAIT);

		if (app->image)
			fz_droppixmap(app->image);
		app->image = nil;

		ctm = pdfapp_viewctm(app);
		bbox = fz_transformaabb(ctm, app->page->mediabox);

		error = fz_rendertree(&app->image, app->rast, app->page->tree,
				ctm, fz_roundrect(bbox), 1);
		if (error)
			pdfapp_error(app, error);

		winconvert(app, app->image);
	}

	pdfapp_panview(app, app->panx, app->pany);

	if (app->shrinkwrap)
	{
		int w = app->image->w;
		int h = app->image->h;
		if (app->winw == w)
			app->panx = 0;
		if (app->winh == h)
			app->pany = 0;
		if (w > app->scrw * 90 / 100)
			w = app->scrw * 90 / 100;
		if (h > app->scrh * 90 / 100)
			h = app->scrh * 90 / 100;
		if (w != app->winw || h != app->winh)
			winresize(app, w, h);
	}

	winrepaint(app);

	wincursor(app, ARROW);
}
Beispiel #9
0
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_throw("outofmem: font struct");

    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 fz_okay;

cleanup2:
    if (resources)
        fz_dropobj(resources);
cleanup:
    fz_dropfont((fz_font*)font);
    return fz_rethrow(error, "cannot load type3 font");
}
Beispiel #10
0
void
drawpnm(int pagenum)
{
    fz_error *error;
    fz_matrix ctm;
    fz_irect bbox;
    fz_pixmap *pix;
    char namebuf[256];
    char buf[256];
    int x, y, w, h, b, bh;
    int fd;

    drawloadpage(pagenum);

    ctm = fz_identity();
    ctm = fz_concat(ctm, fz_translate(0, -drawpage->mediabox.y1));
    ctm = fz_concat(ctm, fz_scale(drawzoom, -drawzoom));
    ctm = fz_concat(ctm, fz_rotate(drawrotate + drawpage->rotate));

    bbox = fz_roundrect(fz_transformaabb(ctm, drawpage->mediabox));
    w = bbox.x1 - bbox.x0;
    h = bbox.y1 - bbox.y0;
    bh = h / drawbands;

    if (drawpattern)
    {
        sprintf(namebuf, drawpattern, drawcount++);
        fd = open(namebuf, O_BINARY|O_WRONLY|O_CREAT|O_TRUNC, 0666);
        if (fd < 0)
            die(fz_throw("ioerror: could not open file '%s'", namebuf));
    }
    else
        fd = 1;

    sprintf(buf, "P6\n%d %d\n255\n", w, h);
    write(fd, buf, strlen(buf));

    error = fz_newpixmap(&pix, bbox.x0, bbox.y0, w, bh, 4);
    if (error)
        die(error);

    memset(pix->samples, 0xff, pix->h * pix->w * pix->n);

    for (b = 0; b < drawbands; b++)
    {
        if (drawbands > 1)
            fprintf(stderr, "drawing band %d / %d\n", b + 1, drawbands);

        error = fz_rendertreeover(drawgc, pix, drawpage->tree, ctm);
        if (error)
            die(error);

        for (y = 0; y < pix->h; y++)
        {
            unsigned char *src = pix->samples + y * pix->w * 4;
            unsigned char *dst = src;

            for (x = 0; x < pix->w; x++)
            {
                dst[x * 3 + 0] = src[x * 4 + 1];
                dst[x * 3 + 1] = src[x * 4 + 2];
                dst[x * 3 + 2] = src[x * 4 + 3];
            }

            write(fd, dst, pix->w * 3);

            memset(src, 0xff, pix->w * 4);
        }

        pix->y += bh;
        if (pix->y + pix->h > bbox.y1)
            pix->h = bbox.y1 - pix->y;
    }

    fz_droppixmap(pix);

    if (drawpattern)
        close(fd);

    drawfreepage();
}