コード例 #1
0
static void cleanmasks(fz_node *node)
{
    fz_node *prev;
    fz_node *current;
    fz_node *shape;
    fz_node *color;
    fz_rect bbox;

    for (current = node->first; current; current = current->next)
        cleanmasks(current);

    prev = nil;
    for (current = node->first; current; current = current->next)
    {
retry:
        if (!current)
            break;

        if (fz_ismasknode(current))
        {
            shape = current->first;
            color = shape->next;

            if (color == nil)
            {
                fz_removenode(current);
                prev = nil;
                current = node->first;
                goto retry;
            }

            if (fz_ispathnode(shape))
            {
                if (getrect((fz_pathnode*)shape, &bbox))
                {
                    if (fitsinside(color, bbox))
                    {
                        fz_removenode(current);
                        if (prev)
                            fz_insertnodeafter(prev, color);
                        else
                            fz_insertnodefirst(node, color);
                        /* cf. http://bugs.ghostscript.com/show_bug.cgi?id=690679 */
                        current->first->next = nil;
                        fz_dropnode(current);
                        current = color;
                        goto retry;
                    }
                }
            }
        }

        prev = current;
    }
}
コード例 #2
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;
}