예제 #1
0
static void
fz_drawbeginmask(void *user, fz_rect rect, int luminosity, fz_colorspace *colorspace, float *colorfv)
{
	fz_drawdevice *dev = user;
	fz_pixmap *dest;
	fz_bbox bbox;

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

	bbox = fz_roundrect(rect);
	bbox = fz_intersectbbox(bbox, dev->scissor);
	dest = fz_newpixmapwithrect(fz_devicegray, bbox);

	if (luminosity)
	{
		/* SumatraPDF: pass a Luminosity softmask's background color */
		float gray = 1.0;
		fz_convertcolor(colorspace, colorfv, fz_devicegray, &gray);
		fz_clearpixmap(dest, gray * 255);
	}
	else
		fz_clearpixmap(dest, 0);

	dev->stack[dev->top].scissor = dev->scissor;
	dev->stack[dev->top].dest = dev->dest;
	dev->stack[dev->top].luminosity = luminosity;
	dev->top++;

	dev->scissor = bbox;
	dev->dest = dest;
}
예제 #2
0
static void
fz_drawbegingroup(void *user, fz_rect rect, int isolated, int knockout, fz_blendmode blendmode, float alpha)
{
	fz_drawdevice *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	fz_bbox bbox;
	fz_pixmap *dest;

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

	bbox = fz_roundrect(rect);
	bbox = fz_intersectbbox(bbox, dev->scissor);
	dest = fz_newpixmapwithrect(model, bbox);

	fz_clearpixmap(dest, 0);

	dev->stack[dev->top].alpha = alpha;
	dev->stack[dev->top].blendmode = blendmode;
	dev->stack[dev->top].scissor = dev->scissor;
	dev->stack[dev->top].dest = dev->dest;
	dev->top++;

	dev->scissor = bbox;
	dev->dest = dest;
}
예제 #3
0
파일: processPdf.cpp 프로젝트: iroot/sopdf
fz_error*
setPageMediaBox(
    pdf_xref*   pdfXRef,
    fz_obj*     pageObj,
    fz_rect     mediaBox
    )
{
    fz_error    *error;
    fz_obj      *objMedia;
    fz_irect    mRect;
    fz_obj      *objInt;

    // Delete the CropBox. This is done because we are reducing
    // the size of the media box and CropBox is of no use to us
    fz_dictdels(pageObj, "CropBox");
    //objMedia = fz_dictgets(pageObj, "CropBox");
    //if (objMedia == NULL) return fz_throw("no CropBox entry");
    //error = pdf_resolve(&objMedia, pdfXRef);
    //if (error) return fz_rethrow(error, "cannot resolve page bounds");
    //if (! fz_isarray(objMedia)) return fz_throw("cannot find page bounds");
    //fz_rect cRect = pdf_torect(objMedia);

    // Get the media box
    objMedia = fz_dictgets(pageObj, "MediaBox");
    if (objMedia == NULL) return fz_throw("no MediaBox entry");

    error = pdf_resolve(&objMedia, pdfXRef);
    if (error) return fz_rethrow(error, "cannot resolve page bounds");

    if (! fz_isarray(objMedia)) return fz_throw("cannot find page bounds");


    // We have the MediaBox array here
    mRect = fz_roundrect(mediaBox);

    error = fz_newint(&objInt, mRect.x0);
    if (error) return fz_rethrow(error, "cannot allocate int"); 
    fz_arrayput(objMedia, 0, objInt);
    fz_dropobj(objInt);

    error = fz_newint(&objInt, mRect.y0);
    if (error) return fz_rethrow(error, "cannot allocate int"); 
    fz_arrayput(objMedia, 1, objInt);
    fz_dropobj(objInt);

    error = fz_newint(&objInt, mRect.x1);
    if (error) return fz_rethrow(error, "cannot allocate int"); 
    fz_arrayput(objMedia, 2, objInt);
    fz_dropobj(objInt);

    error = fz_newint(&objInt, mRect.y1);
    if (error) return fz_rethrow(error, "cannot allocate int"); 
    fz_arrayput(objMedia, 3, objInt);
    fz_dropobj(objInt);

    return NULL;
}
예제 #4
0
파일: render.c 프로젝트: lgchmomo/mupdf
static fz_error *
rendertext(fz_renderer *gc, fz_textnode *text, fz_matrix ctm)
{
	fz_error *error;
	fz_irect tbox;
	fz_irect clip;
	fz_matrix tm, trm;
	fz_glyph glyph;
	int i, x, y, cid;

	tbox = fz_roundrect(fz_boundnode((fz_node*)text, ctm));
	clip = fz_intersectirects(gc->clip, tbox);

DEBUG("text %s n=%d [%g %g %g %g];\n",
text->font->name, text->len,
text->trm.a, text->trm.b, text->trm.c, text->trm.d);

	if (fz_isemptyrect(clip))
		return fz_okay;

	if (!(gc->flag & FOVER))
	{
		error = fz_newpixmapwithrect(&gc->dest, clip, 1);
		if (error)
			return error;
		fz_clearpixmap(gc->dest);
	}

	tm = text->trm;

	for (i = 0; i < text->len; i++)
	{
		cid = text->els[i].cid;
		tm.e = text->els[i].x;
		tm.f = text->els[i].y;
		trm = fz_concat(tm, ctm);
		x = fz_floor(trm.e);
		y = 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)
			return error;

		if (!(gc->flag & FOVER))
			drawglyph(gc, gc->dest, &glyph, x, y);
		else
			drawglyph(gc, gc->over, &glyph, x, y);
	}

	return fz_okay;
}
예제 #5
0
fz_error
fz_rendert3glyph(fz_glyph *glyph, fz_font *font, int gid, fz_matrix trm)
{
	fz_error error;
	fz_renderer *gc;
	fz_tree *tree;
	fz_matrix ctm;
	fz_irect bbox;

	/* TODO: make it reentrant */
	static fz_pixmap *pixmap = nil;
	if (pixmap)
	{
		fz_droppixmap(pixmap);
		pixmap = nil;
	}

	if (gid < 0 || gid > 255)
		return fz_throw("assert: glyph out of range");

	tree = font->t3procs[gid];
	if (!tree)
	{
		glyph->w = 0;
		glyph->h = 0;
		return fz_okay;
	}

	ctm = fz_concat(font->t3matrix, trm);
	bbox = fz_roundrect(fz_boundtree(tree, ctm));

	error = fz_newrenderer(&gc, pdf_devicegray, 1, 4096);
	if (error)
		return fz_rethrow(error, "cannot create renderer");
	error = fz_rendertree(&pixmap, gc, tree, ctm, bbox, 0);
	fz_droprenderer(gc);
	if (error)
		return fz_rethrow(error, "cannot render glyph");

	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 fz_okay;
}
예제 #6
0
파일: mupdf.c 프로젝트: paradigm/paraPDF
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);
}
예제 #7
0
파일: moz_main.c 프로젝트: Limsik/e17
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);
}
예제 #8
0
파일: pdf_type3.c 프로젝트: plcode7/sopdf
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("assert: glyph out of range");

    tree = font->charprocs[cid];
    if (!tree)
    {
        glyph->w = 0;
        glyph->h = 0;
        return fz_okay;
    }

    ctm = fz_concat(font->matrix, trm);
    bbox = fz_roundrect(fz_boundtree(tree, ctm));

    error = fz_newrenderer(&gc, pdf_devicegray, 1, GCMEM);
    if (error)
        return fz_rethrow(error, "cannot create renderer");
    error = fz_rendertree(&pixmap, gc, tree, ctm, bbox, 0);
    fz_droprenderer(gc);
    if (error)
        return fz_rethrow(error, "cannot render glyph");

    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 fz_okay;
}
예제 #9
0
파일: render.c 프로젝트: lgchmomo/mupdf
static fz_error *
rendershade(fz_renderer *gc, fz_shadenode *node, fz_matrix ctm)
{
	fz_error *error;
	fz_irect bbox;

	assert(!gc->maskonly);

	DEBUG("shade;\n");

	bbox = fz_roundrect(fz_boundnode((fz_node*)node, ctm));
	bbox = fz_intersectirects(gc->clip, bbox);

	error = fz_newpixmapwithrect(&gc->dest, bbox, gc->model->n + 1);
	if (error)
		return error;

	return fz_rendershade(node->shade, ctm, gc->model, gc->dest);
}
예제 #10
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;
}
예제 #11
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++;
}
예제 #12
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);
	}
}
예제 #13
0
static void
fz_drawclipstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm)
{
	fz_drawdevice *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	fz_bbox bbox;
	fz_pixmap *mask, *dest;
	fz_matrix tm, trm;
	fz_pixmap *glyph;
	int i, x, y, gid;

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

	/* make the mask the exact size needed */
	bbox = fz_roundrect(fz_boundtext(text, ctm));
	bbox = fz_intersectbbox(bbox, dev->scissor);

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

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

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

	if (!fz_isemptyrect(bbox))
	{
		tm = text->trm;

		for (i = 0; i < text->len; i++)
		{
			gid = text->els[i].gid;
			if (gid < 0)
				continue;

			tm.e = text->els[i].x;
			tm.f = text->els[i].y;
			trm = fz_concat(tm, ctm);
			x = floorf(trm.e);
			y = floorf(trm.f);
			trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX);
			trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX);

			glyph = fz_renderstrokedglyph(dev->cache, text->font, gid, trm, ctm, stroke);
			if (glyph)
			{
				drawglyph(nil, mask, glyph, x, y, bbox);
				fz_droppixmap(glyph);
			}
		}
	}
}
예제 #14
0
static void
fz_drawcliptext(void *user, fz_text *text, fz_matrix ctm, int accumulate)
{
	fz_drawdevice *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	fz_bbox bbox;
	fz_pixmap *mask, *dest;
	fz_matrix tm, trm;
	fz_pixmap *glyph;
	int i, x, y, gid;

	/* If accumulate == 0 then this text object is guaranteed complete */
	/* If accumulate == 1 then this text object is the first (or only) in a sequence */
	/* If accumulate == 2 then this text object is a continuation */

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

	if (accumulate == 0)
	{
		/* make the mask the exact size needed */
		bbox = fz_roundrect(fz_boundtext(text, ctm));
		bbox = fz_intersectbbox(bbox, dev->scissor);
	}
	else
	{
		/* be conservative about the size of the mask needed */
		bbox = dev->scissor;
	}

	if (accumulate == 0 || accumulate == 1)
	{
		mask = fz_newpixmapwithrect(nil, bbox);
		dest = fz_newpixmapwithrect(model, bbox);

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

		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++;
	}
	else
	{
		mask = dev->stack[dev->top-1].mask;
	}

	if (!fz_isemptyrect(bbox))
	{
		tm = text->trm;

		for (i = 0; i < text->len; i++)
		{
			gid = text->els[i].gid;
			if (gid < 0)
				continue;

			tm.e = text->els[i].x;
			tm.f = text->els[i].y;
			trm = fz_concat(tm, ctm);
			x = floorf(trm.e);
			y = floorf(trm.f);
			trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX);
			trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX);

			glyph = fz_renderglyph(dev->cache, text->font, gid, trm);
			if (glyph)
			{
				drawglyph(nil, mask, glyph, x, y, bbox);
				fz_droppixmap(glyph);
			}
		}
	}
}
예제 #15
0
파일: pdfdraw.c 프로젝트: 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");
}
예제 #16
0
파일: mupdf.c 프로젝트: paradigm/paraPDF
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;
}
예제 #17
0
파일: pdf_page.c 프로젝트: paradigm/paraPDF
fz_error
pdf_loadpage(pdf_page **pagep, pdf_xref *xref, fz_obj *dict)
{
	fz_error error;
	pdf_page *page;
	fz_obj *obj;
	fz_bbox bbox;

	pdf_logpage("load page {\n");

	// TODO: move this to a more appropriate place
	/* Ensure that we have a store for resource objects */
	if (!xref->store)
		xref->store = pdf_newstore();

	page = fz_malloc(sizeof(pdf_page));
	page->resources = nil;
	page->contents = nil;
	page->transparency = 0;
	page->list = nil;
	page->text = nil;
	page->links = nil;
	page->annots = nil;

	obj = fz_dictgets(dict, "MediaBox");
	bbox = fz_roundrect(pdf_torect(obj));
	if (fz_isemptyrect(pdf_torect(obj)))
	{
		fz_warn("cannot find page bounds, guessing page bounds.");
		bbox.x0 = 0;
		bbox.y0 = 0;
		bbox.x1 = 612;
		bbox.y1 = 792;
	}

	obj = fz_dictgets(dict, "CropBox");
	if (fz_isarray(obj))
	{
		fz_bbox cropbox = fz_roundrect(pdf_torect(obj));
		bbox = fz_intersectbbox(bbox, cropbox);
	}

	page->mediabox.x0 = MIN(bbox.x0, bbox.x1);
	page->mediabox.y0 = MIN(bbox.y0, bbox.y1);
	page->mediabox.x1 = MAX(bbox.x0, bbox.x1);
	page->mediabox.y1 = MAX(bbox.y0, bbox.y1);

	if (page->mediabox.x1 - page->mediabox.x0 < 1 || page->mediabox.y1 - page->mediabox.y0 < 1)
		return fz_throw("invalid page size");

	page->rotate = fz_toint(fz_dictgets(dict, "Rotate"));

	pdf_logpage("bbox [%d %d %d %d]\n", bbox.x0, bbox.y0, bbox.x1, bbox.y1);
	pdf_logpage("rotate %d\n", page->rotate);

	obj = fz_dictgets(dict, "Annots");
	if (obj)
	{
		pdf_loadlinks(&page->links, xref, obj);
		pdf_loadannots(&page->annots, xref, obj);
	}

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

	obj = fz_dictgets(dict, "Contents");
	error = pdf_loadpagecontents(&page->contents, xref, obj);
	if (error)
	{
		pdf_freepage(page);
		return fz_rethrow(error, "cannot load page contents (%d %d R)", fz_tonum(obj), fz_togen(obj));
	}

	if (page->resources && pdf_resourcesuseblending(page->resources))
		page->transparency = 1;

	pdf_logpage("} %p\n", page);

	*pagep = page;
	return fz_okay;
}
예제 #18
0
파일: moz_main.c 프로젝트: Limsik/e17
void pdfmoz_open(pdfmoz_t *moz, char *filename)
{
    SCROLLINFO si;
    fz_error error;
    fz_obj *obj;
    fz_irect bbox;
    int rot;
    int i;

    strcpy(moz->error, "");

    error = fz_newrenderer(&moz->rast, pdf_devicergb, 0, 1024 * 512);
    if (error)
	pdfmoz_error(moz, error);

    /*
     * Open PDF and load xref table
     */

    moz->filename = filename;

    moz->xref = pdf_newxref();
    error = pdf_loadxref(moz->xref, filename);
    if (error)
    {
	error = pdf_repairxref(moz->xref, filename);
	if (error)
	    pdfmoz_error(moz, error);
    }

    /*
     * Handle encrypted PDF files
     */

    error = pdf_decryptxref(moz->xref);
    if (error)
	pdfmoz_error(moz, error);

    if (pdf_needspassword(moz->xref))
    {
	pdfmoz_warn(moz, "PDF file is encrypted and needs a password.");
    }

    moz->pagecount = pdf_getpagecount(moz->xref);
    moz->pages = fz_malloc(sizeof(page_t) * moz->pagecount);

    for (i = 0; i < moz->pagecount; i++)
    {
	fz_obj *pageobj;
	pageobj = pdf_getpageobject(moz->xref, i);
	moz->pages[i].obj = fz_keepobj(pageobj);
	moz->pages[i].page = nil;
	moz->pages[i].image = nil;

	obj = fz_dictgets(moz->pages[i].obj, "CropBox");
	if (!obj)
	    obj = fz_dictgets(moz->pages[i].obj, "MediaBox");
	bbox = fz_roundrect(pdf_torect(obj));
	moz->pages[i].w = bbox.x1 - bbox.x0;
	moz->pages[i].h = bbox.y1 - bbox.y0;

	rot = fz_toint(fz_dictgets(moz->pages[i].obj, "Rotate"));
	if ((rot / 90) % 2)
	{
	    int t = moz->pages[i].w;
	    moz->pages[i].w = moz->pages[i].h;
	    moz->pages[i].h = t;
	}

	moz->pages[i].px = 1 + PAD;
    }

    /*
     * Load meta information
     * TODO: move this into mupdf library
     */

    obj = fz_dictgets(moz->xref->trailer, "Root");
    moz->xref->root = fz_resolveindirect(obj);
    if (!moz->xref->root)
	pdfmoz_error(moz, fz_throw("syntaxerror: missing Root object"));
    if (moz->xref->root)
	fz_keepobj(moz->xref->root);

    obj = fz_dictgets(moz->xref->trailer, "Info");
    moz->xref->info = fz_resolveindirect(obj);
    if (moz->xref->info)
	fz_keepobj(moz->xref->info);

    moz->doctitle = filename;
    if (strrchr(moz->doctitle, '\\'))
	moz->doctitle = strrchr(moz->doctitle, '\\') + 1;
    if (strrchr(moz->doctitle, '/'))
	moz->doctitle = strrchr(moz->doctitle, '/') + 1;
    if (moz->xref->info)
    {
	obj = fz_dictgets(moz->xref->info, "Title");
	if (obj)
	    moz->doctitle = pdf_toutf8(obj);
    }

    /*
     * Start at first page
     */

    si.cbSize = sizeof(si);
    si.fMask = SIF_POS | SIF_RANGE; // XXX | SIF_PAGE;
    si.nPos = 0;
    si.nMin = 0;
    si.nMax = 1;
    si.nPage = 1;
    SetScrollInfo(moz->hwnd, SB_VERT, &si, TRUE);

    moz->scrollpage = 0;
    moz->scrollyofs = 0;

    InvalidateRect(moz->hwnd, NULL, FALSE);
}
예제 #19
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();
}
예제 #20
0
파일: pdfapp.c 프로젝트: fkhan/mupdf_fareed
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);
}
예제 #21
0
파일: render.c 프로젝트: lgchmomo/mupdf
static fz_error *
renderimage(fz_renderer *gc, fz_imagenode *node, fz_matrix ctm)
{
	fz_error *error;
	fz_image *image = node->image;
	fz_irect bbox;
	fz_irect clip;
	int dx, dy;
	fz_pixmap *tile;
	fz_pixmap *temp;
	fz_matrix imgmat;
	fz_matrix invmat;
	int fa, fb, fc, fd;
	int u0, v0;
	int x0, y0;
	int w, h;
	int tileheight;

DEBUG("image %dx%d %d+%d %s\n{\n", image->w, image->h, image->n, image->a, image->cs?image->cs->name:"(nil)");

	bbox = fz_roundrect(fz_boundnode((fz_node*)node, ctm));
	clip = fz_intersectirects(gc->clip, bbox);

	if (fz_isemptyrect(clip))
		return fz_okay;
        if (image->w == 0 || image->h == 0)
                return fz_okay;

	if (image->n + image->a == 0)
		return fz_okay;

	calcimagescale(ctm, image->w, image->h, &dx, &dy);

	/* try to fit tile into a typical L2 cachce */
	tileheight = 512 * 1024 / (image->w * (image->n + image->a));
	/* tileheight must be an even multiple of dy, except for last band */
	tileheight = (tileheight + dy - 1) / dy * dy;

	if ((dx != 1 || dy != 1) && image->h > tileheight) {
		int y = 0;

		DEBUG("  load image tile size = %dx%d\n", image->w, tileheight);
		error = fz_newpixmap(&tile, 0, 0, image->w,
				     tileheight, image->n + 1);
		if (error)
			return error;

		error = fz_newscaledpixmap(&temp, image->w, image->h, image->n + 1, dx, dy);
		if (error)
			goto cleanup;

		do {
			if (y + tileheight > image->h)
				tileheight = image->h - y;
			tile->y = y;
			tile->h = tileheight;
			DEBUG("  tile xywh=%d %d %d %d sxsy=1/%d 1/%d\n",
			      0, y, image->w, tileheight, dx, dy);
			error = image->loadtile(image, tile);
			if (error)
				goto cleanup1;

			error = fz_scalepixmaptile(temp, 0, y, tile, dx, dy);
			if (error)
				goto cleanup1;

			y += tileheight;
		} while (y < image->h);

		fz_droppixmap(tile);
		tile = temp;
	}
	else {


DEBUG("  load image\n");
		error = fz_newpixmap(&tile, 0, 0, image->w, image->h, image->n + 1);
		if (error)
			return error;

		error = image->loadtile(image, tile);
		if (error)
			goto cleanup;

		if (dx != 1 || dy != 1)
		{
DEBUG("  scale image 1/%d 1/%d\n", dx, dy);
			error = fz_scalepixmap(&temp, tile, dx, dy);
			if (error)
				goto cleanup;
			fz_droppixmap(tile);
			tile = temp;
		}
	}

	if (image->cs && image->cs != gc->model)
	{
DEBUG("  convert from %s to %s\n", image->cs->name, gc->model->name);
		error = fz_newpixmap(&temp, tile->x, tile->y, tile->w, tile->h, gc->model->n + 1);
		if (error)
			goto cleanup;
		fz_convertpixmap(image->cs, tile, gc->model, temp);
		fz_droppixmap(tile);
		tile = temp;
	}

	imgmat.a = 1.0 / tile->w;
	imgmat.b = 0.0;
	imgmat.c = 0.0;
	imgmat.d = -1.0 / tile->h;
	imgmat.e = 0.0;
	imgmat.f = 1.0;
	invmat = fz_invertmatrix(fz_concat(imgmat, ctm));

	w = clip.x1 - clip.x0;
	h = clip.y1 - clip.y0;
	x0 = clip.x0;
	y0 = clip.y0;
	u0 = (invmat.a * (x0+0.5) + invmat.c * (y0+0.5) + invmat.e) * 65536;
	v0 = (invmat.b * (x0+0.5) + invmat.d * (y0+0.5) + invmat.f) * 65536;
	fa = invmat.a * 65536;
	fb = invmat.b * 65536;
	fc = invmat.c * 65536;
	fd = invmat.d * 65536;

#define PSRC tile->samples, tile->w, tile->h
#define PDST(p) p->samples + ((y0-p->y) * p->w + (x0-p->x)) * p->n, p->w * p->n
#define PCTM u0, v0, fa, fb, fc, fd, w, h

	switch (gc->flag)
	{
	case FNONE:
		{
DEBUG("  fnone %d x %d\n", w, h);
			if (image->cs)
				error = fz_newpixmapwithrect(&gc->dest, clip, gc->model->n + 1);
			else
				error = fz_newpixmapwithrect(&gc->dest, clip, 1);
			if (error)
				goto cleanup;

			if (image->cs)
				fz_img_4c4(PSRC, PDST(gc->dest), PCTM);
			else
				fz_img_1c1(PSRC, PDST(gc->dest), PCTM);
		}
		break;

	case FOVER:
		{
DEBUG("  fover %d x %d\n", w, h);
			if (image->cs)
				fz_img_4o4(PSRC, PDST(gc->over), PCTM);
			else
				fz_img_1o1(PSRC, PDST(gc->over), PCTM);
		}
		break;

	case FOVER | FRGB:
DEBUG("  fover+rgb %d x %d\n", w, h);
		fz_img_w4i1o4(gc->argb, PSRC, PDST(gc->over), PCTM);
		break;

	default:
		assert(!"impossible flag in image span function");
	}

DEBUG("}\n");

	fz_droppixmap(tile);
	return fz_okay;

cleanup1:
	fz_droppixmap(temp);
cleanup:
	fz_droppixmap(tile);
	return error;
}
예제 #22
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);
}
예제 #23
0
파일: render.c 프로젝트: lgchmomo/mupdf
static fz_error *
rendermask(fz_renderer *gc, fz_masknode *mask, fz_matrix ctm)
{
	fz_error *error;
	int oldmaskonly;
	fz_pixmap *oldover;
	fz_irect oldclip;
	fz_irect bbox;
	fz_irect clip;
	fz_pixmap *shapepix = nil;
	fz_pixmap *colorpix = nil;
	fz_node *shape;
	fz_node *color;
	float rgb[3];

	shape = mask->super.first;
	color = shape->next;

	/* special case black voodo */
	if (gc->flag & FOVER)
	{
		if (fz_issolidnode(color))
		{
			fz_solidnode *solid = (fz_solidnode*)color;

			fz_convertcolor(solid->cs, solid->samples, gc->model, rgb);
			gc->argb[0] = solid->a * 255;
			gc->argb[1] = rgb[0] * solid->a * 255;
			gc->argb[2] = rgb[1] * solid->a * 255;
			gc->argb[3] = rgb[2] * solid->a * 255;
			gc->argb[4] = rgb[0] * 255;
			gc->argb[5] = rgb[1] * 255;
			gc->argb[6] = rgb[2] * 255;
			gc->flag |= FRGB;

			/* we know these can handle the FRGB shortcut */
			if (fz_ispathnode(shape))
				return renderpath(gc, (fz_pathnode*)shape, ctm);
			if (fz_istextnode(shape))
				return rendertext(gc, (fz_textnode*)shape, ctm);
			if (fz_isimagenode(shape))
				return renderimage(gc, (fz_imagenode*)shape, ctm);
		}
	}

	oldclip = gc->clip;
	oldover = gc->over;

	bbox = fz_roundrect(fz_boundnode(shape, ctm));
	clip = fz_intersectirects(bbox, gc->clip);
	bbox = fz_roundrect(fz_boundnode(color, ctm));
	clip = fz_intersectirects(bbox, clip);

	if (fz_isemptyrect(clip))
		return fz_okay;

DEBUG("mask [%d %d %d %d]\n{\n", clip.x0, clip.y0, clip.x1, clip.y1);

{
fz_irect sbox = fz_roundrect(fz_boundnode(shape, ctm));
fz_irect cbox = fz_roundrect(fz_boundnode(color, ctm));
if (cbox.x0 >= sbox.x0 && cbox.x1 <= sbox.x1)
if (cbox.y0 >= sbox.y0 && cbox.y1 <= sbox.y1)
DEBUG("potentially useless mask\n");
}

	gc->clip = clip;
	gc->over = nil;

	oldmaskonly = gc->maskonly;
	gc->maskonly = 1;

	error = rendernode(gc, shape, ctm);
	if (error)
		goto cleanup;
	shapepix = gc->dest;
	gc->dest = nil;

	gc->maskonly = oldmaskonly;

	error = rendernode(gc, color, ctm);
	if (error)
		goto cleanup;
	colorpix = gc->dest;
	gc->dest = nil;

	gc->clip = oldclip;
	gc->over = oldover;

	if (shapepix && colorpix)
	{
		if (gc->over)
		{
			blendmask(gc, colorpix, shapepix, gc->over, 1);
		}
		else
		{
			clip.x0 = MAX(colorpix->x, shapepix->x);
			clip.y0 = MAX(colorpix->y, shapepix->y);
			clip.x1 = MIN(colorpix->x+colorpix->w, shapepix->x+shapepix->w);
			clip.y1 = MIN(colorpix->y+colorpix->h, shapepix->y+shapepix->h);
			error = fz_newpixmapwithrect(&gc->dest, clip, colorpix->n);
			if (error)
				goto cleanup;
			blendmask(gc, colorpix, shapepix, gc->dest, 0);
		}
	}

DEBUG("}\n");

	if (shapepix) fz_droppixmap(shapepix);
	if (colorpix) fz_droppixmap(colorpix);
	return fz_okay;

cleanup:
	if (shapepix) fz_droppixmap(shapepix);
	if (colorpix) fz_droppixmap(colorpix);
	return error;
}
예제 #24
0
static fz_error *
renderimage(fz_renderer *gc, fz_imagenode *node, fz_matrix ctm)
{
	fz_error *error;
	fz_image *image = node->image;
	fz_irect bbox;
	fz_irect clip;
	int dx, dy;
	fz_pixmap *tile;
	fz_pixmap *temp;
	fz_matrix imgmat;
	fz_matrix invmat;
	int fa, fb, fc, fd;
	int u0, v0;
	int x0, y0;
	int w, h;

DEBUG("image %dx%d %d+%d %s\n{\n", image->w, image->h, image->n, image->a, image->cs?image->cs->name:"(nil)");

	bbox = fz_roundrect(fz_boundnode((fz_node*)node, ctm));
	clip = fz_intersectirects(gc->clip, bbox);

	if (fz_isemptyrect(clip))
		return nil;

	calcimagescale(ctm, image->w, image->h, &dx, &dy);

DEBUG("  load image\n");
	error = fz_newpixmap(&tile, 0, 0, image->w, image->h, image->n + 1);
	if (error)
		return error;

	error = image->loadtile(image, tile);
	if (error)
		goto cleanup;

	if (dx != 1 || dy != 1)
	{
DEBUG("  scale image 1/%d 1/%d\n", dx, dy);
		error = fz_scalepixmap(&temp, tile, dx, dy);
		if (error)
			goto cleanup;
		fz_droppixmap(tile);
		tile = temp;
	}

	if (image->cs && image->cs != gc->model)
	{
DEBUG("  convert from %s to %s\n", image->cs->name, gc->model->name);
		error = fz_newpixmap(&temp, tile->x, tile->y, tile->w, tile->h, gc->model->n + 1);
		if (error)
			goto cleanup;
		fz_convertpixmap(image->cs, tile, gc->model, temp);
		fz_droppixmap(tile);
		tile = temp;
	}

	imgmat.a = 1.0 / tile->w;
	imgmat.b = 0.0;
	imgmat.c = 0.0;
	imgmat.d = -1.0 / tile->h;
	imgmat.e = 0.0;
	imgmat.f = 1.0;
	invmat = fz_invertmatrix(fz_concat(imgmat, ctm));

	w = clip.x1 - clip.x0;
	h = clip.y1 - clip.y0;
	x0 = clip.x0;
	y0 = clip.y0;
	u0 = (invmat.a * (x0+0.5) + invmat.c * (y0+0.5) + invmat.e) * 65536;
	v0 = (invmat.b * (x0+0.5) + invmat.d * (y0+0.5) + invmat.f) * 65536;
	fa = invmat.a * 65536;
	fb = invmat.b * 65536;
	fc = invmat.c * 65536;
	fd = invmat.d * 65536;

#define PSRC tile->samples, tile->w, tile->h
#define PDST(p) p->samples + ((y0-p->y) * p->w + (x0-p->x)) * p->n, p->w * p->n
#define PCTM u0, v0, fa, fb, fc, fd, w, h

	switch (gc->flag)
	{
	case FNONE:
		{
DEBUG("  fnone %d x %d\n", w, h);
			if (image->cs)
				error = fz_newpixmapwithrect(&gc->dest, clip, gc->model->n + 1);
			else
				error = fz_newpixmapwithrect(&gc->dest, clip, 1);
			if (error)
				goto cleanup;

			if (image->cs)
				fz_img_4c4(PSRC, PDST(gc->dest), PCTM);
			else
				fz_img_1c1(PSRC, PDST(gc->dest), PCTM);
		}
		break;

	case FOVER:
		{
DEBUG("  fover %d x %d\n", w, h);
			if (image->cs)
				fz_img_4o4(PSRC, PDST(gc->over), PCTM);
			else
				fz_img_1o1(PSRC, PDST(gc->over), PCTM);
		}
		break;

	case FOVER | FRGB:
DEBUG("  fover+rgb %d x %d\n", w, h);
		fz_img_w3i1o4(gc->rgb, PSRC, PDST(gc->over), PCTM);
		break;

	default:
		assert(!"impossible flag in image span function");
	}

DEBUG("}\n");

	fz_droppixmap(tile);
	return nil;

cleanup:
	fz_droppixmap(tile);
	return error;
}