Exemple #1
0
static void fz_knockout_end(fz_context *ctx, void *user)
{
	fz_draw_device *dev = user;
	fz_pixmap *group = dev->dest;
	fz_pixmap *shape = dev->shape;
	int blendmode;
	int isolated;

	if ((dev->blendmode & FZ_BLEND_KNOCKOUT) == 0)
		return;

	if (dev->top == dev->stack_max)
		fz_grow_stack(dev);

	if (dev->top > 0)
	{
		dev->top--;
		blendmode = dev->blendmode & FZ_BLEND_MODEMASK;
		isolated = dev->blendmode & FZ_BLEND_ISOLATED;
		dev->blendmode = dev->stack[dev->top].blendmode;
		dev->shape = dev->stack[dev->top].shape;
		dev->dest = dev->stack[dev->top].dest;
		dev->scissor = dev->stack[dev->top].scissor;

#ifdef DUMP_GROUP_BLENDS
		dump_spaces(dev->top, "");
		fz_dump_blend(group, "Blending ");
		if (shape)
			fz_dump_blend(shape, "/");
		fz_dump_blend(dev->dest, " onto ");
		if (dev->shape)
			fz_dump_blend(dev->shape, "/");
		if (blendmode != 0)
			printf(" (blend %d)", blendmode);
		if (isolated != 0)
			printf(" (isolated)");
		printf(" (knockout)");
#endif
		if ((blendmode == 0) && (shape == NULL))
			fz_paint_pixmap(dev->dest, group, 255);
		else
			fz_blend_pixmap(dev->dest, group, 255, blendmode, isolated, shape);

		fz_drop_pixmap(ctx, group);
		if (shape != dev->shape)
		{
			if (dev->shape)
			{
				fz_paint_pixmap(dev->shape, shape, 255);
			}
			fz_drop_pixmap(ctx, shape);
		}
#ifdef DUMP_GROUP_BLENDS
		fz_dump_blend(dev->dest, " to get ");
		if (dev->shape)
			fz_dump_blend(dev->shape, "/");
		printf("\n");
#endif
	}
}
Exemple #2
0
static void
fz_draw_end_group(fz_device *devp)
{
	fz_draw_device *dev = devp->user;
	int blendmode;
	int isolated;
	float alpha;
	fz_context *ctx = dev->ctx;
	fz_draw_state *state;

	if (dev->top == 0)
	{
		fz_warn(ctx, "Unexpected end_group");
		return;
	}

	state = &dev->stack[--dev->top];
	alpha = state[1].alpha;
	blendmode = state[1].blendmode & FZ_BLEND_MODEMASK;
	isolated = state[1].blendmode & FZ_BLEND_ISOLATED;
#ifdef DUMP_GROUP_BLENDS
	dump_spaces(dev->top, "");
	fz_dump_blend(dev->ctx, state[1].dest, "Group end: blending ");
	if (state[1].shape)
		fz_dump_blend(dev->ctx, state[1].shape, "/");
	fz_dump_blend(dev->ctx, state[0].dest, " onto ");
	if (state[0].shape)
		fz_dump_blend(dev->ctx, state[0].shape, "/");
	if (alpha != 1.0f)
		printf(" (alpha %g)", alpha);
	if (blendmode != 0)
		printf(" (blend %d)", blendmode);
	if (isolated != 0)
		printf(" (isolated)");
	if (state[1].blendmode & FZ_BLEND_KNOCKOUT)
		printf(" (knockout)");
#endif
	if ((blendmode == 0) && (state[0].shape == state[1].shape))
		fz_paint_pixmap(state[0].dest, state[1].dest, alpha * 255);
	else
		fz_blend_pixmap(state[0].dest, state[1].dest, alpha * 255, blendmode, isolated, state[1].shape);

	fz_drop_pixmap(dev->ctx, state[1].dest);
	if (state[0].shape != state[1].shape)
	{
		if (state[0].shape)
			fz_paint_pixmap(state[0].shape, state[1].shape, alpha * 255);
		fz_drop_pixmap(dev->ctx, state[1].shape);
	}
#ifdef DUMP_GROUP_BLENDS
	fz_dump_blend(dev->ctx, state[0].dest, " to get ");
	if (state[0].shape)
		fz_dump_blend(dev->ctx, state[0].shape, "/");
	printf("\n");
#endif

	if (state[0].blendmode & FZ_BLEND_KNOCKOUT)
		fz_knockout_end(dev);
}
Exemple #3
0
static void fz_knockout_end(fz_draw_device *dev)
{
	fz_draw_state *state;
	int blendmode;
	int isolated;
	fz_context *ctx = dev->ctx;

	if (dev->top == 0)
	{
		fz_warn(ctx, "unexpected knockout end");
		return;
	}
	state = &dev->stack[--dev->top];
	if ((state[0].blendmode & FZ_BLEND_KNOCKOUT) == 0)
		return;

	blendmode = state->blendmode & FZ_BLEND_MODEMASK;
	isolated = state->blendmode & FZ_BLEND_ISOLATED;

#ifdef DUMP_GROUP_BLENDS
	dump_spaces(dev->top, "");
	fz_dump_blend(dev->ctx, state[1].dest, "Knockout end: blending ");
	if (state[1].shape)
		fz_dump_blend(dev->ctx, state[1].shape, "/");
	fz_dump_blend(dev->ctx, state[0].dest, " onto ");
	if (state[0].shape)
		fz_dump_blend(dev->ctx, state[0].shape, "/");
	if (blendmode != 0)
		printf(" (blend %d)", blendmode);
	if (isolated != 0)
		printf(" (isolated)");
	printf(" (knockout)");
#endif
	if ((blendmode == 0) && (state[0].shape == state[1].shape))
		fz_paint_pixmap(state[0].dest, state[1].dest, 255);
	else
		fz_blend_pixmap(state[0].dest, state[1].dest, 255, blendmode, isolated, state[1].shape);

	fz_drop_pixmap(dev->ctx, state[1].dest);
	if (state[0].shape != state[1].shape)
	{
		if (state[0].shape)
			fz_paint_pixmap(state[0].shape, state[1].shape, 255);
		fz_drop_pixmap(dev->ctx, state[1].shape);
	}
#ifdef DUMP_GROUP_BLENDS
	fz_dump_blend(dev->ctx, state[0].dest, " to get ");
	if (state[0].shape)
		fz_dump_blend(dev->ctx, state[0].shape, "/");
	printf("\n");
#endif
}
Exemple #4
0
void
fz_paint_shade(fz_shade *shade, fz_matrix ctm, fz_pixmap *dest, fz_bbox bbox)
{
	unsigned char clut[256][FZ_MAX_COLORS];
	fz_pixmap *temp, *conv;
	float color[FZ_MAX_COLORS];
	int i, k;

		ctm = fz_concat(shade->matrix, ctm);

		if (shade->use_function)
		{
			for (i = 0; i < 256; i++)
			{
			fz_convert_color(shade->colorspace, shade->function[i], dest->colorspace, color);
				for (k = 0; k < dest->colorspace->n; k++)
					clut[i][k] = color[k] * 255;
				clut[i][k] = shade->function[i][shade->colorspace->n] * 255;
			}
		conv = fz_new_pixmap_with_rect(dest->colorspace, bbox);
		temp = fz_new_pixmap_with_rect(fz_device_gray, bbox);
		fz_clear_pixmap(temp);
		}
		else
		{
			temp = dest;
		}

		switch (shade->type)
		{
		case FZ_LINEAR: fz_paint_linear(shade, ctm, temp, bbox); break;
		case FZ_RADIAL: fz_paint_radial(shade, ctm, temp, bbox); break;
	case FZ_MESH: fz_paint_mesh(shade, ctm, temp, bbox); break;
		}

		if (shade->use_function)
		{
			unsigned char *s = temp->samples;
			unsigned char *d = conv->samples;
			int len = temp->w * temp->h;
			while (len--)
			{
				int v = *s++;
				int a = fz_mul255(*s++, clut[v][conv->n - 1]);
				for (k = 0; k < conv->n - 1; k++)
					*d++ = fz_mul255(clut[v][k], a);
				*d++ = a;
			}
			fz_paint_pixmap(dest, conv, 255);
		fz_drop_pixmap(conv);
		fz_drop_pixmap(temp);
	}
}
Exemple #5
0
static void
fz_draw_end_group(void *user)
{
	fz_draw_device *dev = user;
	fz_pixmap *group = dev->dest;
	int blendmode;
	float alpha;

	if (dev->top > 0)
	{
		dev->top--;
		alpha = dev->stack[dev->top].alpha;
		blendmode = dev->stack[dev->top].blendmode;
		dev->dest = dev->stack[dev->top].dest;
		dev->scissor = dev->stack[dev->top].scissor;

		if (blendmode == 0)
			fz_paint_pixmap(dev->dest, group, alpha * 255);
		else
			fz_blend_pixmap(dev->dest, group, alpha * 255, blendmode);

		fz_drop_pixmap(group);
	}
}
Exemple #6
0
static void
fz_draw_fill_shade(fz_context *ctx, void *user, fz_shade *shade, fz_matrix ctm, float alpha)
{
	fz_draw_device *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	fz_pixmap *dest = dev->dest;
	fz_rect bounds;
	fz_bbox bbox, scissor;
	float colorfv[FZ_MAX_COLORS];
	unsigned char colorbv[FZ_MAX_COLORS + 1];

	bounds = fz_bound_shade(shade, ctm);
	bbox = fz_intersect_bbox(fz_round_rect(bounds), dev->scissor);
	scissor = dev->scissor;

	// TODO: proper clip by shade->bbox

	if (fz_is_empty_rect(bbox))
		return;

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

	if (alpha < 1)
	{
		dest = fz_new_pixmap_with_rect(ctx, dev->dest->colorspace, bbox);
		fz_clear_pixmap(dest);
	}

	if (dev->blendmode & FZ_BLEND_KNOCKOUT)
		fz_knockout_begin(ctx, dev);

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

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

	fz_paint_shade(ctx, shade, ctm, dest, bbox);
	if (dev->shape)
		fz_clear_pixmap_rect_with_color(dev->shape, 255, bbox);

	if (alpha < 1)
	{
		fz_paint_pixmap(dev->dest, dest, alpha * 255);
		fz_drop_pixmap(ctx, dest);
	}

	if (dev->blendmode & FZ_BLEND_KNOCKOUT)
		fz_knockout_end(ctx, dev);
}
Exemple #7
0
void
fz_paint_shade(fz_context *ctx, fz_shade *shade, const fz_matrix *ctm, fz_pixmap *dest, const fz_irect *bbox)
{
	unsigned char clut[256][FZ_MAX_COLORS];
	fz_pixmap *temp = NULL;
	fz_pixmap *conv = NULL;
	float color[FZ_MAX_COLORS];
	struct paint_tri_data ptd;
	int i, k;
	fz_matrix local_ctm;

	fz_var(temp);
	fz_var(conv);

	fz_try(ctx)
	{
		fz_concat(&local_ctm, &shade->matrix, ctm);

		if (shade->use_function)
		{
			fz_color_converter cc;
			fz_find_color_converter(&cc, ctx, dest->colorspace, shade->colorspace);
			for (i = 0; i < 256; i++)
			{
				cc.convert(&cc, color, shade->function[i]);
				for (k = 0; k < dest->colorspace->n; k++)
					clut[i][k] = color[k] * 255;
				clut[i][k] = shade->function[i][shade->colorspace->n] * 255;
			}
			conv = fz_new_pixmap_with_bbox(ctx, dest->colorspace, bbox);
			temp = fz_new_pixmap_with_bbox(ctx, fz_device_gray, bbox);
			fz_clear_pixmap(ctx, temp);
		}
		else
		{
			temp = dest;
		}

		ptd.ctx = ctx;
		ptd.dest = temp;
		ptd.shade = shade;
		ptd.bbox = bbox;

		fz_process_mesh(ctx, shade, &local_ctm, &do_paint_tri, &ptd);

		if (shade->use_function)
		{
			unsigned char *s = temp->samples;
			unsigned char *d = conv->samples;
			int len = temp->w * temp->h;
			while (len--)
			{
				int v = *s++;
				int a = fz_mul255(*s++, clut[v][conv->n - 1]);
				for (k = 0; k < conv->n - 1; k++)
					*d++ = fz_mul255(clut[v][k], a);
				*d++ = a;
			}
			fz_paint_pixmap(dest, conv, 255);
			fz_drop_pixmap(ctx, conv);
			fz_drop_pixmap(ctx, temp);
		}
	}
	fz_catch(ctx)
	{
		fz_drop_pixmap(ctx, conv);
		fz_drop_pixmap(ctx, temp);
		fz_rethrow(ctx);
	}
}
Exemple #8
0
static void
fz_draw_fill_shade(fz_device *devp, fz_shade *shade, fz_matrix ctm, float alpha)
{
	fz_draw_device *dev = devp->user;
	fz_rect bounds;
	fz_bbox bbox, scissor;
	fz_pixmap *dest, *shape;
	float colorfv[FZ_MAX_COLORS];
	unsigned char colorbv[FZ_MAX_COLORS + 1];
	fz_draw_state *state = &dev->stack[dev->top];
	fz_colorspace *model = state->dest->colorspace;

	bounds = fz_bound_shade(dev->ctx, shade, ctm);
	scissor = state->scissor;
	bbox = fz_intersect_bbox(fz_bbox_covering_rect(bounds), scissor);

	if (fz_is_empty_rect(bbox))
		return;

	if (!model)
	{
		fz_warn(dev->ctx, "cannot render shading directly to an alpha mask");
		return;
	}

	if (state->blendmode & FZ_BLEND_KNOCKOUT)
		state = fz_knockout_begin(dev);

	dest = state->dest;
	shape = state->shape;

	if (alpha < 1)
	{
		dest = fz_new_pixmap_with_bbox(dev->ctx, state->dest->colorspace, bbox);
		fz_clear_pixmap(dev->ctx, dest);
		if (shape)
		{
			shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
			fz_clear_pixmap(dev->ctx, shape);
		}
	}

	if (shade->use_background)
	{
		unsigned char *s;
		int x, y, n, i;
		fz_convert_color(dev->ctx, model, colorfv, shade->colorspace, shade->background);
		for (i = 0; i < model->n; i++)
			colorbv[i] = colorfv[i] * 255;
		colorbv[i] = 255;

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

	fz_paint_shade(dev->ctx, shade, ctm, dest, bbox);
	if (shape)
		fz_clear_pixmap_rect_with_value(dev->ctx, shape, 255, bbox);

	if (alpha < 1)
	{
		fz_paint_pixmap(state->dest, dest, alpha * 255);
		fz_drop_pixmap(dev->ctx, dest);
		if (shape)
		{
			fz_paint_pixmap(state->shape, shape, alpha * 255);
			fz_drop_pixmap(dev->ctx, shape);
		}
	}

	if (state->blendmode & FZ_BLEND_KNOCKOUT)
		fz_knockout_end(dev);
}