Esempio n. 1
0
static fz_matrix pdfViewctm(PDFContext* ctx) {
	fz_matrix ctm;
	ctm = fz_identity();
	ctm = fz_concat(ctm, fz_translate(0, -ctx->page->mediabox.y1));
	ctm = fz_concat(ctm, fz_scale(ctx->zoom, -ctx->zoom));
	ctm = fz_concat(ctm, fz_rotate(ctx->rotate + ctx->page->rotate));
	return ctm;
}
Esempio n. 2
0
fz_matrix pdfapp_viewctm(pdfapp_t *app)
{
	fz_matrix ctm;
	ctm = fz_identity();
	ctm = fz_concat(ctm, fz_translate(0, -app->page->mediabox.y1));
	ctm = fz_concat(ctm, fz_scale(app->zoom, -app->zoom));
	ctm = fz_concat(ctm, fz_rotate(app->rotate + app->page->rotate));
	return ctm;
}
Esempio n. 3
0
static int fitsinside(fz_node *node, fz_rect clip)
{
    fz_rect bbox;
    bbox = fz_boundnode(node, fz_identity());
    if (fz_isinfiniterect(bbox)) return 0;
    if (fz_isemptyrect(bbox)) return 1;
    if (bbox.x0 < clip.x0) return 0;
    if (bbox.x1 > clip.x1) return 0;
    if (bbox.y0 < clip.y0) return 0;
    if (bbox.y1 > clip.y1) return 0;
    return 1;
}
Esempio n. 4
0
static fz_matrix getmatrix(fz_node *node)
{
	if (node->parent)
	{
		fz_matrix ptm = getmatrix(node->parent);
		if (fz_istransformnode(node))
			return fz_concat(((fz_transformnode*)node)->m, ptm);
		return ptm;
	}
	if (fz_istransformnode(node))
		return ((fz_transformnode*)node)->m;
	return fz_identity();
}
Esempio n. 5
0
fz_matrix pdfmoz_pagectm(pdfmoz_t *moz, int pagenum)
{
    page_t *page = moz->pages + pagenum;
    fz_matrix ctm;
    float zoom;
    RECT rc;

    GetClientRect(moz->hwnd, &rc);

    zoom = (rc.right - rc.left) / (float) page->w;

    ctm = fz_identity();
    ctm = fz_concat(ctm, fz_translate(0, -page->page->mediabox.y1));
    ctm = fz_concat(ctm, fz_scale(zoom, -zoom));
    ctm = fz_concat(ctm, fz_rotate(page->page->rotate));

    return ctm;
}
Esempio n. 6
0
fz_error
fz_newtextnode(fz_textnode **textp, fz_font *font)
{
	fz_textnode *text;

	text = fz_malloc(sizeof(fz_textnode));
	if (!text)
		return fz_rethrow(-1, "out of memory");

	fz_initnode((fz_node*)text, FZ_NTEXT);

	text->font = fz_keepfont(font);
	text->trm = fz_identity();
	text->len = 0;
	text->cap = 0;
	text->els = nil;

	*textp = text;
	return fz_okay;
}
Esempio n. 7
0
static fz_font *
fz_newfont(void)
{
	fz_font *font;

	font = fz_malloc(sizeof(fz_font));
	font->refs = 1;
	strcpy(font->name, "<unknown>");

	font->ftface = nil;
	font->ftsubstitute = 0;
	font->fthint = 0;

	font->t3matrix = fz_identity();
	font->t3procs = nil;
	font->t3widths = nil;

	font->bbox.x0 = 0;
	font->bbox.y0 = 0;
	font->bbox.x1 = 1000;
	font->bbox.y1 = 1000;

	return font;
}
Esempio n. 8
0
File: pdfdraw.c Progetto: Limsik/e17
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");
}
Esempio n. 9
0
fz_error *
pdf_loadshade(fz_shade **shadep, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
{
	fz_error *error;
	fz_matrix mat;
	fz_obj *obj;
	fz_obj *shd;

	if ((*shadep = pdf_finditem(xref->store, PDF_KSHADE, ref)))
		return nil;

	/*
	 * Type 2 pattern dictionary
	 */
	if (fz_dictgets(dict, "PatternType"))
	{
		pdf_logshade("load shade pattern %d %d {\n", fz_tonum(ref), fz_togen(ref));

		obj = fz_dictgets(dict, "Matrix");
		if (obj)
		{
			mat = pdf_tomatrix(obj);
			pdf_logshade("matrix [%g %g %g %g %g %g]\n",
				mat.a, mat.b, mat.c, mat.d, mat.e, mat.f);
		}
		else
		{
			mat = fz_identity();
		}

		obj = fz_dictgets(dict, "ExtGState");
		if (obj)
		{
			pdf_logshade("extgstate ...\n");
		}

		obj = fz_dictgets(dict, "Shading");
		if (!obj)
			return fz_throw("syntaxerror: missing shading dictionary");

		shd = obj;
		error = pdf_resolve(&shd, xref);
		if (error)
			return error;
		error = loadshadedict(shadep, xref, shd, obj, mat);
		fz_dropobj(shd);
		if (error)
			return error;

		pdf_logshade("}\n");
	}

	/*
	 * Naked shading dictionary
	 */
	else
	{
		error = loadshadedict(shadep, xref, dict, ref, fz_identity());
		if (error)
			return error;
	}

	error = pdf_storeitem(xref->store, PDF_KSHADE, ref, *shadep);
	if (error)
	{
		fz_dropshade(*shadep);
		return error;
	}

	return nil;
}
Esempio n. 10
0
fz_error*
processPage(
    soPdfFile* inFile,
    int pageNo,
    fz_rect *bbRect,
    int rectCount
    )
{
    fz_error    *error;
    fz_obj      *pageRef;
    pdf_page    *pdfPage;
    fz_rect     contentBox;
    fz_rect     mediaBox;


    // Initialize 
    for (int ctr = 0; ctr < rectCount; ctr++)
        bbRect[ctr] = fz_emptyrect;

    // Get the page reference and load the page contents
    pageRef = pdf_getpageobject(inFile->pageTree, pageNo);
    error = pdf_loadpage(&pdfPage, inFile->xref, pageRef);
    if (error != NULL)
    {
        // Ideally pdf_loadpage should render all the pages
        // and this should never happen
        return processErrorPage(inFile, pageRef, pageNo, bbRect, error);
    }

    // Get the bounding box for the page
    mediaBox = pdfPage->mediabox;
    float mbHeight = mediaBox.y1 - mediaBox.y0;
    
    // calculate the bounding box for all the elements in the page
    contentBox = fz_boundnode(pdfPage->tree->root, fz_identity());
    float cbHeight = contentBox.y1 - contentBox.y0;

    // If there is nothing on the page we return nothing.
    // should we return an empty page instead ???
    if (fz_isemptyrect(contentBox))
        goto Cleanup;

    // if contentBox is bigger than mediaBox then there are some
    // elements that should not be display and hence we reset the
    // content box to media box
    if ((cbHeight > mbHeight) || ((contentBox.x1 - contentBox.x0) > (mediaBox.x1 - mediaBox.x0)))
    {
        // Calculate the new content box based on the content that is 
        // inside the the media box and recalculate cbHeight
        contentBox = getContainingRect(pdfPage->tree->root, mediaBox);
        cbHeight = contentBox.y1 - contentBox.y0;
    }


#ifdef _blahblah
    printf("-->Page %d\n", pageNo);
    bbdump(pdfPage->tree->root, 1);
#endif

    // The rotation takes place when we insert the page into destination
    // If only the mupdf renderer could give accurate values of the 
    // bounding box of all the elements in a page, the splitting would
    // be so much more easier without overlapping, cutting text, etc
    switch(p_mode)
    {
    case FitHeight:
    case FitWidth:
        bbRect[0] = contentBox;
        goto Cleanup;

    case Fit2xHeight:
    case Fit2xWidth:
        // Let the processing happen.
        break;

    case SmartFitHeight:
    case SmartFitWidth:
    default:
        return fz_throw("Mode(%d) not yet implemented.", p_mode);
        break;
    }

    // If the contentBox is 60% of mediaBox then do not split 
    if (((cbHeight / mbHeight) * 100) <= 55)
    {
        bbRect[0] = contentBox;
        goto Cleanup;
    }

    // Get the first split contents from top. The box we specify is 
    // top 55% (bottom + 45) of the contents
    bbRect[0] = contentBox;
    bbRect[0].y0 = bbRect[0].y0 + (float)(0.45 * cbHeight);
    bbRect[0] = getContainingRect(pdfPage->tree->root, bbRect[0]);

    // Check if the contents we got in first split is more than 40%
    // of the total contents
    float bbRect0Height = bbRect[0].y1 - bbRect[0].y0;
    if (((bbRect0Height / cbHeight) * 100) >= 40)
    {
        // The content is more than 40%. Put the rest of the 
        // content in the second split and exit
        bbRect[1] = contentBox;
        bbRect[1].y1 = bbRect[1].y1 - bbRect0Height;

        // Adjust the split box height by X points to make sure
        // we get everything and dont have annoying tail cuts
        bbRect[0].y0 -= 2;
        goto Cleanup;
    }

    // Since the contents we got in first split is less than 40%
    // of the total contents, split the content in half with overlap
    float overlap = (cbHeight * (float)(p_overlap / 100)) / 2;
    bbRect[0] = contentBox;
    bbRect[0].y0 = bbRect[0].y0 + (float)(0.5 * cbHeight) - overlap;
    bbRect[1] = contentBox;
    bbRect[1].y1 = bbRect[1].y1 - (float)(0.5 * cbHeight) + overlap;


Cleanup:

    // This function can overflow the stack when the pdf page
    // to be rendered is very complex. I had to increase the 
    // stack size reserved for exe using compiler option
    pdf_droppage(pdfPage);

    return error;
}
Esempio n. 11
0
fz_error *
pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict, fz_obj *ref)
{
	fz_error *error;
	pdf_xobject *form;
	fz_obj *obj;

	if ((*formp = pdf_finditem(xref->store, PDF_KXOBJECT, ref)))
	{
		pdf_keepxobject(*formp);
		return fz_okay;
	}

	form = fz_malloc(sizeof(pdf_xobject));
	if (!form)
		return fz_throw("outofmem: xobject struct");

	form->refs = 1;
	form->resources = nil;
	form->contents = nil;

	/* Store item immediately, to avoid infinite recursion if contained
	   objects refer again to this xobject */
	error = pdf_storeitem(xref->store, PDF_KXOBJECT, ref, form);
	if (error)
	{
		pdf_dropxobject(form);
		return fz_rethrow(error, "cannot store xobject resource");
	}

	pdf_logrsrc("load xobject %d %d (%p) {\n", fz_tonum(ref), fz_togen(ref), form);

	obj = fz_dictgets(dict, "BBox");
	form->bbox = pdf_torect(obj);

	pdf_logrsrc("bbox [%g %g %g %g]\n",
			form->bbox.x0, form->bbox.y0,
			form->bbox.x1, form->bbox.y1);

	obj = fz_dictgets(dict, "Matrix");
	if (obj)
		form->matrix = pdf_tomatrix(obj);
	else
		form->matrix = fz_identity();

	pdf_logrsrc("matrix [%g %g %g %g %g %g]\n",
			form->matrix.a, form->matrix.b,
			form->matrix.c, form->matrix.d,
			form->matrix.e, form->matrix.f);

	obj = fz_dictgets(dict, "I");
	form->isolated = fz_tobool(obj);
	obj = fz_dictgets(dict, "K");
	form->knockout = fz_tobool(obj);

	pdf_logrsrc("isolated %d\n", form->isolated);
	pdf_logrsrc("knockout %d\n", form->knockout);

	obj = fz_dictgets(dict, "Resources");
	if (obj)
	{
		error = pdf_resolve(&obj, xref);
		if (error)
		{
			fz_dropobj(obj);
			error = fz_rethrow(error, "cannot resolve xobject resources");
			goto cleanup;
		}
		error = pdf_loadresources(&form->resources, xref, obj);
		fz_dropobj(obj);
		if (error)
		{
			error = fz_rethrow(error, "cannot load xobject resources");
			goto cleanup;
		}
	}

	error = pdf_loadstream(&form->contents, xref, fz_tonum(ref), fz_togen(ref));
	if (error)
	{
		error = fz_rethrow(error, "cannot load xobject content stream");
		goto cleanup;
	}

	pdf_logrsrc("stream %d bytes\n", form->contents->wp - form->contents->rp);

	pdf_logrsrc("}\n");

	*formp = form;
	return fz_okay;
cleanup:
	pdf_removeitem(xref->store, PDF_KXOBJECT, ref);
	pdf_dropxobject(form);
	return error;
}
Esempio n. 12
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();
}
Esempio n. 13
0
fz_error
pdf_loadxobject(pdf_xobject **formp, pdf_xref *xref, fz_obj *dict)
{
	fz_error error;
	pdf_xobject *form;
	fz_obj *obj;

	if ((*formp = pdf_finditem(xref->store, PDF_KXOBJECT, dict)))
	{
		pdf_keepxobject(*formp);
		return fz_okay;
	}

	form = fz_malloc(sizeof(pdf_xobject));
	form->refs = 1;
	form->resources = nil;
	form->contents = nil;

	/* Store item immediately, to avoid possible recursion if objects refer back to this one */
	pdf_storeitem(xref->store, PDF_KXOBJECT, dict, form);

	pdf_logrsrc("load xobject (%d %d R) ptr=%p {\n", fz_tonum(dict), fz_togen(dict), form);

	obj = fz_dictgets(dict, "BBox");
	form->bbox = pdf_torect(obj);

	pdf_logrsrc("bbox [%g %g %g %g]\n",
		form->bbox.x0, form->bbox.y0,
		form->bbox.x1, form->bbox.y1);

	obj = fz_dictgets(dict, "Matrix");
	if (obj)
		form->matrix = pdf_tomatrix(obj);
	else
		form->matrix = fz_identity();

	pdf_logrsrc("matrix [%g %g %g %g %g %g]\n",
		form->matrix.a, form->matrix.b,
		form->matrix.c, form->matrix.d,
		form->matrix.e, form->matrix.f);

	form->isolated = 0;
	form->knockout = 0;
	form->transparency = 0;

	obj = fz_dictgets(dict, "Group");
	if (obj)
	{
		fz_obj *attrs = obj;

		form->isolated = fz_tobool(fz_dictgets(attrs, "I"));
		form->knockout = fz_tobool(fz_dictgets(attrs, "K"));

		obj = fz_dictgets(attrs, "S");
		if (fz_isname(obj) && !strcmp(fz_toname(obj), "Transparency"))
			form->transparency = 1;
	}

	pdf_logrsrc("isolated %d\n", form->isolated);
	pdf_logrsrc("knockout %d\n", form->knockout);
	pdf_logrsrc("transparency %d\n", form->transparency);

	form->resources = fz_dictgets(dict, "Resources");
	if (form->resources)
		fz_keepobj(form->resources);

	error = pdf_loadstream(&form->contents, xref, fz_tonum(dict), fz_togen(dict));
	if (error)
	{
		pdf_removeitem(xref->store, PDF_KXOBJECT, dict);
		pdf_dropxobject(form);
		return fz_rethrow(error, "cannot load xobject content stream (%d %d R)", fz_tonum(dict), fz_togen(dict));
	}

	pdf_logrsrc("stream %d bytes\n", form->contents->wp - form->contents->rp);
	pdf_logrsrc("}\n");

	*formp = form;
	return fz_okay;
}
Esempio n. 14
0
static void pdfapp_showpage(pdfapp_t *app, int loadpage, int drawpage)
{
    char buf[256];
    fz_error error;
    fz_device *idev, *tdev, *mdev;
    fz_displaylist *list;
    fz_matrix ctm;
    fz_bbox bbox;
    fz_obj *obj;

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

        if (app->page)
            pdf_droppage(app->page);
        app->page = nil;
        //code change by kakai
        kno_clearselect(app);
        //code change by kakai
        pdf_flushxref(app->xref, 0);

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

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

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

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

        list = fz_newdisplaylist();

        mdev = fz_newlistdevice(list);
        error = pdf_runcontentstream(mdev, fz_identity(), app->xref, app->page->resources, app->page->contents);
        if (error)
            pdfapp_error(app, error);
        fz_freedevice(mdev);

        if (app->image)
            fz_droppixmap(app->image);
        app->image = fz_newpixmapwithrect(pdf_devicergb, bbox);
        fz_clearpixmap(app->image, 0xFF);
        idev = fz_newdrawdevice(app->cache, app->image);
        fz_executedisplaylist(list, idev, ctm);
        fz_freedevice(idev);

        if (app->text)
            fz_freetextspan(app->text);
        app->text = fz_newtextspan();
        tdev = fz_newtextdevice(app->text);
        fz_executedisplaylist(list, tdev, ctm);
        fz_freedevice(tdev);

        fz_freedisplaylist(list);

        //code change by kakai
        kno_allocselection(app);
        kno_applyselect(app);
        //code change by kakai

        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);
}