Example #1
0
fz_rect
fz_boundtext(fz_text *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_transformrect(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.001f;
	fbox.y0 = text->font->bbox.y0 * 0.001f;
	fbox.x1 = text->font->bbox.x1 * 0.001f;
	fbox.y1 = text->font->bbox.y1 * 0.001f;

	fbox = fz_transformrect(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;
}
Example #2
0
static void
pdf_begingroup(pdf_csi *csi, fz_rect bbox)
{
	pdf_gstate *gstate = csi->gstate + csi->gtop;
	fz_error error;

	if (gstate->softmask)
	{
		pdf_xobject *softmask = gstate->softmask;
		fz_rect bbox = fz_transformrect(gstate->ctm, softmask->bbox);

		gstate->softmask = nil;

		csi->dev->beginmask(csi->dev->user, bbox, gstate->luminosity,
			softmask->colorspace, gstate->softmaskbc);
		error = pdf_runxobject(csi, nil, softmask, fz_identity);
		if (error)
			fz_catch(error, "cannot run softmask");
		csi->dev->endmask(csi->dev->user);

		gstate->softmask = softmask;
	}

	if (gstate->blendmode != FZ_BNORMAL)
		csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode, 1);
}
void
pdf_showimage(pdf_csi *csi, fz_pixmap *image)
{
	pdf_gstate *gstate = csi->gstate + csi->gtop;
	fz_rect bbox;

	bbox = fz_transformrect(gstate->ctm, fz_unitrect);

	if (gstate->blendmode != FZ_BNORMAL)
		csi->dev->begingroup(csi->dev->user, bbox, 0, 0, gstate->blendmode, 1);

	if (image->mask)
		csi->dev->clipimagemask(csi->dev->user, image->mask, gstate->ctm);

	if (!image->colorspace)
	{

		switch (gstate->fill.kind)
		{
		case PDF_MNONE:
			break;
		case PDF_MCOLOR:
			csi->dev->fillimagemask(csi->dev->user, image, gstate->ctm,
				gstate->fill.cs, gstate->fill.v, gstate->fill.alpha);
			break;
		case PDF_MPATTERN:
			if (gstate->fill.pattern)
			{
				csi->dev->clipimagemask(csi->dev->user, image, gstate->ctm);
				pdf_showpattern(csi, gstate->fill.pattern, bbox, PDF_MFILL);
				csi->dev->popclip(csi->dev->user);
			}
			break;
		case PDF_MSHADE:
			if (gstate->fill.shade)
			{
				csi->dev->clipimagemask(csi->dev->user, image, gstate->ctm);
				csi->dev->fillshade(csi->dev->user, gstate->fill.shade, gstate->ctm, gstate->fill.alpha);
				csi->dev->popclip(csi->dev->user);
			}
			break;
		}
	}
	else
	{
		csi->dev->fillimage(csi->dev->user, image, gstate->ctm, gstate->fill.alpha);
	}

	if (image->mask)
		csi->dev->popclip(csi->dev->user);

	if (gstate->blendmode != FZ_BNORMAL)
		csi->dev->endgroup(csi->dev->user);
}
Example #4
0
JNIEXPORT void JNICALL Java_com_artifex_mupdf_MuPDFCore_gotoPageInternal(
                                            JNIEnv  *env,
                                            jobject  thiz,
                                            int      page)
{
    float      zoom;
    fz_matrix  ctm;
    fz_obj    *pageobj;
    fz_bbox    bbox;
    fz_error   error;
    fz_device *dev;
    pdf_page  *currentPage;

    /* In the event of an error, ensure we give a non-empty page */
    pageWidth  = 100;
    pageHeight = 100;

    LOGE("Goto page %d...", page);
    if (currentPageList != NULL)
    {
	fz_freedisplaylist(currentPageList);
	currentPageList = NULL;
    }
    pagenum = page;
    pageobj = pdf_getpageobject(xref, pagenum);
    if (pageobj == NULL)
        return;
    error = pdf_loadpage(&currentPage, xref, pageobj);
    if (error)
        return;
    zoom = resolution / 72;
    currentMediabox = currentPage->mediabox;
    currentRotate   = currentPage->rotate;
    ctm = fz_translate(0, -currentMediabox.y1);
    ctm = fz_concat(ctm, fz_scale(zoom, -zoom));
    ctm = fz_concat(ctm, fz_rotate(currentRotate));
    bbox = fz_roundrect(fz_transformrect(ctm, currentMediabox));
    pageWidth  = bbox.x1-bbox.x0;
    pageHeight = bbox.y1-bbox.y0;
    /* Render to list */
    currentPageList = fz_newdisplaylist();
    dev = fz_newlistdevice(currentPageList);
    error = pdf_runpage(xref, currentPage, dev, fz_identity);
    pdf_freepage(currentPage);
    if (error)
        LOGE("cannot make displaylist from page %d", pagenum);
    fz_freedevice(dev);
}
Example #5
0
static void
fz_drawclipimagemask(void *user, fz_pixmap *image, fz_matrix ctm)
{
	fz_drawdevice *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	fz_bbox bbox;
	fz_pixmap *mask, *dest;
	fz_pixmap *scaled = nil;
	int dx, dy;

	if (dev->top == STACKSIZE)
	{
		fz_warn("assert: too many buffers on stack");
		return;
	}

	if (image->w == 0 || image->h == 0)
	{
		dev->stack[dev->top].scissor = dev->scissor;
		dev->stack[dev->top].mask = nil;
		dev->stack[dev->top].dest = nil;
		dev->scissor = fz_emptybbox;
		dev->top++;
		return;
	}

	bbox = fz_roundrect(fz_transformrect(ctm, fz_unitrect));
	bbox = fz_intersectbbox(bbox, dev->scissor);

	mask = fz_newpixmapwithrect(nil, bbox);
	dest = fz_newpixmapwithrect(model, bbox);

	fz_clearpixmap(mask, 0);
	fz_clearpixmap(dest, 0);

#ifdef SMOOTHSCALE
	dx = sqrtf(ctm.a * ctm.a + ctm.b * ctm.b);
	dy = sqrtf(ctm.c * ctm.c + ctm.d * ctm.d);
	if (dx < image->w && dy < image->h)
	{
		scaled = fz_smoothtransformpixmap(image, &ctm, dev->dest->x, dev->dest->y, dx, dy);
		if (scaled == NULL)
		{
			if (dx < 1)
				dx = 1;
			if (dy < 1)
				dy = 1;
			scaled = fz_smoothscalepixmap(image, image->x, image->y, dx, dy);
		}
		if (scaled != NULL)
			image = scaled;
	}
#else
	if (fz_calcimagescale(image, ctm, &dx, &dy))
	{
		scaled = fz_scalepixmap(image, dx, dy);
		image = scaled;
	}
#endif

	fz_paintimage(mask, bbox, image, ctm, 255);

	if (scaled)
		fz_droppixmap(scaled);

	dev->stack[dev->top].scissor = dev->scissor;
	dev->stack[dev->top].mask = mask;
	dev->stack[dev->top].dest = dev->dest;
	dev->scissor = bbox;
	dev->dest = dest;
	dev->top++;
}
Example #6
0
static void
fz_drawfillshade(void *user, fz_shade *shade, fz_matrix ctm, float alpha)
{
	fz_drawdevice *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	fz_pixmap *dest = dev->dest;
	fz_rect bounds;
	fz_bbox bbox;
	float colorfv[FZ_MAXCOLORS];
	unsigned char colorbv[FZ_MAXCOLORS + 1];

	bounds = fz_boundshade(shade, ctm);
	bbox = fz_intersectbbox(fz_roundrect(bounds), dev->scissor);

	// TODO: proper clip by shade->bbox
	if (!fz_isemptyrect(shade->bbox))
	{
		bounds = fz_transformrect(fz_concat(shade->matrix, ctm), shade->bbox);
		bbox = fz_intersectbbox(fz_roundrect(bounds), bbox);
	}

	if (fz_isemptyrect(bbox))
		return;

	if (!model)
	{
		fz_warn("cannot render shading directly to an alpha mask");
		return;
	}

	if (alpha < 1)
	{
		dest = fz_newpixmapwithrect(dev->dest->colorspace, bbox);
		fz_clearpixmap(dest, 0);
	}

	if (shade->usebackground)
	{
		unsigned char *s;
		int x, y, n, i;
		fz_convertcolor(shade->cs, shade->background, model, colorfv);
		for (i = 0; i < model->n; i++)
			colorbv[i] = colorfv[i] * 255;
		colorbv[i] = 255;

		n = dest->n;
		for (y = bbox.y0; y < bbox.y1; y++)
		{
			s = dest->samples + ((bbox.x0 - dest->x) + (y - dest->y) * dest->w) * dest->n;
			for (x = bbox.x0; x < bbox.x1; x++)
			{
				for (i = 0; i < n; i++)
					*s++ = colorbv[i];
			}
		}
	}

	fz_rendershade(shade, ctm, dest, bbox);

	if (alpha < 1)
	{
		fz_paintpixmap(dev->dest, dest, alpha * 255);
		fz_droppixmap(dest);
	}
}
Example #7
0
fz_rect
fz_boundshade(fz_shade *shade, fz_matrix ctm)
{
	ctm = fz_concat(shade->matrix, ctm);
	return fz_transformrect(ctm, shade->bbox);
}
Example #8
0
static void
pdf_showpattern(pdf_csi *csi, pdf_pattern *pat, fz_rect bbox, int what)
{
	pdf_gstate *gstate;
	fz_matrix ptm, invptm;
	fz_matrix oldtopctm;
	fz_error error;
	int x, y, x0, y0, x1, y1;
	int oldtop;

	pdf_gsave(csi);
	gstate = csi->gstate + csi->gtop;

	if (pat->ismask)
	{
		pdf_unsetpattern(csi, PDF_MFILL);
		pdf_unsetpattern(csi, PDF_MSTROKE);
		if (what == PDF_MFILL)
		{
			pdf_dropmaterial(&gstate->stroke);
			pdf_keepmaterial(&gstate->fill);
			gstate->stroke = gstate->fill;
		}
		if (what == PDF_MSTROKE)
		{
			pdf_dropmaterial(&gstate->fill);
			pdf_keepmaterial(&gstate->stroke);
			gstate->fill = gstate->stroke;
		}
	}
	else
	{
		// TODO: unset only the current fill/stroke or both?
		pdf_unsetpattern(csi, what);
	}

	/* don't apply softmasks to objects in the pattern as well */
	if (gstate->softmask)
	{
		pdf_dropxobject(gstate->softmask);
		gstate->softmask = nil;
	}

	ptm = fz_concat(pat->matrix, csi->topctm);
	invptm = fz_invertmatrix(ptm);

	/* patterns are painted using the ctm in effect at the beginning of the content stream */
	/* get bbox of shape in pattern space for stamping */
	bbox = fz_transformrect(invptm, bbox);
	x0 = floorf(bbox.x0 / pat->xstep);
	y0 = floorf(bbox.y0 / pat->ystep);
	x1 = ceilf(bbox.x1 / pat->xstep);
	y1 = ceilf(bbox.y1 / pat->ystep);

	oldtopctm = csi->topctm;
	oldtop = csi->gtop;

	for (y = y0; y < y1; y++)
	{
		for (x = x0; x < x1; x++)
		{
			gstate->ctm = fz_concat(fz_translate(x * pat->xstep, y * pat->ystep), ptm);
			csi->topctm = gstate->ctm;
			error = pdf_runcsibuffer(csi, pat->resources, pat->contents);
			while (oldtop < csi->gtop)
				pdf_grestore(csi);
			if (error)
			{
				fz_catch(error, "cannot render pattern tile");
				goto cleanup;
			}
		}
	}

cleanup:
	csi->topctm = oldtopctm;

	pdf_grestore(csi);
}
Example #9
0
JNIEXPORT jboolean JNICALL Java_com_artifex_mupdf_MuPDFCore_drawPage(
                                            JNIEnv  *env,
                                            jobject  thiz,
                                            jobject  bitmap,
                                            int      pageW,
                                            int      pageH,
                                            int      patchX,
                                            int      patchY,
                                            int      patchW,
                                            int      patchH)
{
    AndroidBitmapInfo  info;
    void              *pixels;
    int                ret;
    fz_error           error;
    fz_device         *dev;
    float              zoom;
    fz_matrix          ctm;
    fz_bbox            bbox;
    fz_pixmap         *pix;
    float              xscale, yscale;

    LOGI("In native method\n");
    if ((ret = AndroidBitmap_getInfo(env, bitmap, &info)) < 0) {
        LOGE("AndroidBitmap_getInfo() failed ! error=%d", ret);
        return 0;
    }

    LOGI("Checking format\n");
    if (info.format != ANDROID_BITMAP_FORMAT_RGBA_8888) {
        LOGE("Bitmap format is not RGBA_8888 !");
        return 0;
    }

    LOGI("locking pixels\n");
    if ((ret = AndroidBitmap_lockPixels(env, bitmap, &pixels)) < 0) {
        LOGE("AndroidBitmap_lockPixels() failed ! error=%d", ret);
        return 0;
    }

    /* Call mupdf to render display list to screen */
    LOGE("Rendering page=%dx%d patch=[%d,%d,%d,%d]",
         pageW, pageH, patchX, patchY, patchW, patchH);

    pix = fz_newpixmapwithdata(colorspace,
                               patchX,
                               patchY,
                               patchW,
                               patchH,
                               pixels);
    if (currentPageList == NULL)
    {
        fz_clearpixmapwithcolor(pix, 0xd0);
        return 0;
    }
    fz_clearpixmapwithcolor(pix, 0xff);

    zoom = resolution / 72;
    ctm = fz_translate(0, -currentMediabox.y1);
    ctm = fz_concat(ctm, fz_scale(zoom, -zoom));
    ctm = fz_concat(ctm, fz_rotate(currentRotate));
    bbox = fz_roundrect(fz_transformrect(ctm,currentMediabox));
    /* Now, adjust ctm so that it would give the correct page width
     * heights. */
    xscale = (float)pageW/(float)(bbox.x1-bbox.x0);
    yscale = (float)pageH/(float)(bbox.y1-bbox.y0);
    ctm = fz_concat(ctm, fz_scale(xscale, yscale));
    dev = fz_newdrawdevice(glyphcache, pix);
    fz_executedisplaylist(currentPageList, dev, ctm);
    fz_freedevice(dev);
    fz_droppixmap(pix);
    LOGE("Rendered");

    AndroidBitmap_unlockPixels(env, bitmap);

    return 1;
}
Example #10
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);
}