예제 #1
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;
}
예제 #2
0
static void
fz_draw_stroke_text(fz_context *ctx, void *user, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm,
	fz_colorspace *colorspace, float *color, float alpha)
{
	fz_draw_device *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	unsigned char colorbv[FZ_MAX_COLORS + 1];
	float colorfv[FZ_MAX_COLORS];
	fz_matrix tm, trm;
	fz_pixmap *glyph;
	int i, x, y, gid;

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

	fz_convert_color(ctx, colorspace, color, model, colorfv);
	for (i = 0; i < model->n; i++)
		colorbv[i] = colorfv[i] * 255;
	colorbv[i] = alpha * 255;

	tm = text->trm;

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

		tm.e = text->items[i].x;
		tm.f = text->items[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_render_stroked_glyph(ctx, dev->cache, text->font, gid, trm, ctm, stroke);
		if (glyph)
		{
			draw_glyph(colorbv, dev->dest, glyph, x, y, dev->scissor);
			if (dev->shape)
				draw_glyph(colorbv, dev->shape, glyph, x, y, dev->scissor);
			fz_drop_pixmap(ctx, glyph);
		}
	}

	if (dev->blendmode & FZ_BLEND_KNOCKOUT)
		fz_knockout_end(ctx, dev);
}
예제 #3
0
/*  ofun -- piecewise-linear output-table mappings; inverse of xfun, yfun, zfun
 */
static fut_otbldat_t
	ofun (fut_gtbldat_t q, fut_calcData_p dataP)
{
double	p, delta, neutralgrid;

	neutralgrid = ((fData_p) dataP)->neutralgrid;

	p = DEQUANT (q, FUT_GRD_MAXVAL);

	switch (((fData_p) dataP)->std.chan)
	{
	   case 0:   /* L* */
			break;

	   case 1:   /* a */
	   case 2:   /* b */
			delta = p - neutralgrid;
			if (delta < 0.0)
			   p = ((fData_p) dataP)->neutralInput * (p / neutralgrid);
			else
			   p = 1.0 - (1.0 - ((fData_p) dataP)->neutralInput) * ((1.0 - p) / (1.0 - neutralgrid));
			break;
	}

	return QUANT (p, FUT_MAX_PEL12);
}
예제 #4
0
static void
fz_drawstroketext(void *user, fz_text *text, fz_strokestate *stroke, fz_matrix ctm,
	fz_colorspace *colorspace, float *color, float alpha)
{
	fz_drawdevice *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	unsigned char colorbv[FZ_MAXCOLORS + 1];
	float colorfv[FZ_MAXCOLORS];
	fz_matrix tm, trm;
	fz_pixmap *glyph;
	int i, x, y, gid;

	fz_convertcolor(colorspace, color, model, colorfv);
	for (i = 0; i < model->n; i++)
		colorbv[i] = colorfv[i] * 255;
	colorbv[i] = alpha * 255;

	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(colorbv, dev->dest, glyph, x, y, dev->scissor);
			fz_droppixmap(glyph);
		}
	}
}
예제 #5
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);
			}
		}
	}
}
예제 #6
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);
			}
		}
	}
}
예제 #7
0
static void
fz_draw_clip_stroke_text(fz_context *ctx, void *user, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm)
{
	fz_draw_device *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	fz_bbox bbox;
	fz_pixmap *mask, *dest, *shape;
	fz_matrix tm, trm;
	fz_pixmap *glyph;
	int i, x, y, gid;

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

	/* make the mask the exact size needed */
	bbox = fz_round_rect(fz_bound_text(text, ctm));
	bbox = fz_intersect_bbox(bbox, dev->scissor);

	mask = fz_new_pixmap_with_rect(ctx, NULL, bbox);
	fz_clear_pixmap(mask);
	dest = fz_new_pixmap_with_rect(ctx, model, bbox);
	/* FIXME: See note #1 */
	fz_clear_pixmap(dest);
	if (dev->shape)
	{
		shape = fz_new_pixmap_with_rect(ctx, NULL, bbox);
		fz_clear_pixmap(shape);
	}
	else
		shape = dev->shape;

	dev->stack[dev->top].scissor = dev->scissor;
	dev->stack[dev->top].mask = mask;
	dev->stack[dev->top].dest = dev->dest;
	dev->stack[dev->top].shape = dev->shape;
	/* FIXME: See note #1 */
	dev->stack[dev->top].blendmode = dev->blendmode | FZ_BLEND_ISOLATED;
	dev->scissor = bbox;
	dev->dest = dest;
	dev->shape = shape;
#ifdef DUMP_GROUP_BLENDS
	dump_spaces(dev->top, "Clip (stroke text) begin\n");
#endif
	dev->top++;

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

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

			tm.e = text->items[i].x;
			tm.f = text->items[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_render_stroked_glyph(ctx, dev->cache, text->font, gid, trm, ctm, stroke);
			if (glyph)
			{
				draw_glyph(NULL, mask, glyph, x, y, bbox);
				if (dev->shape)
					draw_glyph(NULL, dev->shape, glyph, x, y, bbox);
				fz_drop_pixmap(ctx, glyph);
			}
		}
	}
}
예제 #8
0
static void
fz_draw_clip_text(fz_context *ctx, void *user, fz_text *text, fz_matrix ctm, int accumulate)
{
	fz_draw_device *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	fz_bbox bbox;
	fz_pixmap *mask, *dest, *shape;
	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 == dev->stack_max)
		fz_grow_stack(dev);

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

	if (accumulate == 0 || accumulate == 1)
	{
		mask = fz_new_pixmap_with_rect(ctx, NULL, bbox);
		fz_clear_pixmap(mask);
		dest = fz_new_pixmap_with_rect(ctx, model, bbox);
		/* FIXME: See note #1 */
		fz_clear_pixmap(dest);
		if (dev->shape)
		{
			shape = fz_new_pixmap_with_rect(ctx, NULL, bbox);
			fz_clear_pixmap(shape);
		}
		else
			shape = NULL;

		dev->stack[dev->top].scissor = dev->scissor;
		dev->stack[dev->top].mask = mask;
		dev->stack[dev->top].dest = dev->dest;
		dev->stack[dev->top].shape = dev->shape;
		/* FIXME: See note #1 */
		dev->stack[dev->top].blendmode = dev->blendmode | FZ_BLEND_ISOLATED;
		dev->scissor = bbox;
		dev->dest = dest;
		dev->shape = shape;
#ifdef DUMP_GROUP_BLENDS
		dump_spaces(dev->top, "Clip (text) begin\n");
#endif
		dev->top++;
	}
	else
	{
		mask = dev->stack[dev->top-1].mask;
	}

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

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

			tm.e = text->items[i].x;
			tm.f = text->items[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_render_glyph(ctx, dev->cache, text->font, gid, trm, model);
			if (glyph)
			{
				draw_glyph(NULL, mask, glyph, x, y, bbox);
				if (dev->shape)
					draw_glyph(NULL, dev->shape, glyph, x, y, bbox);
				fz_drop_pixmap(ctx, glyph);
			}
		}
	}
}
예제 #9
0
static void
fz_draw_fill_text(fz_context *ctx, void *user, fz_text *text, fz_matrix ctm,
	fz_colorspace *colorspace, float *color, float alpha)
{
	fz_draw_device *dev = user;
	fz_colorspace *model = dev->dest->colorspace;
	unsigned char colorbv[FZ_MAX_COLORS + 1];
	unsigned char shapebv;
	float colorfv[FZ_MAX_COLORS];
	fz_matrix tm, trm;
	fz_pixmap *glyph;
	int i, x, y, gid;

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

	fz_convert_color(ctx, colorspace, color, model, colorfv);
	for (i = 0; i < model->n; i++)
		colorbv[i] = colorfv[i] * 255;
	colorbv[i] = alpha * 255;
	shapebv = 255;

	tm = text->trm;

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

		tm.e = text->items[i].x;
		tm.f = text->items[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_render_glyph(ctx, dev->cache, text->font, gid, trm, model);
		if (glyph)
		{
			/* cf. http://code.google.com/p/sumatrapdf/issues/detail?id=1746 */
			if (glyph->n > 1 && text->font->t3procs)
			{
				float light;
				fz_convert_color(ctx, colorspace, color, fz_device_gray, &light);
				if (light != 0)
				{
					fz_pixmap *gray = fz_new_pixmap_with_rect(ctx, fz_device_gray, fz_bound_pixmap(glyph));
					fz_convert_pixmap(ctx, glyph, gray);
					fz_drop_pixmap(ctx, glyph);
					glyph = fz_alpha_from_gray(ctx, gray, 0);
					fz_drop_pixmap(ctx, gray);
				}
			}
			if (glyph->n == 1)
			{
				draw_glyph(colorbv, dev->dest, glyph, x, y, dev->scissor);
				if (dev->shape)
					draw_glyph(&shapebv, dev->shape, glyph, x, y, dev->scissor);
			}
			else
			{
				fz_matrix ctm = {glyph->w, 0.0, 0.0, -glyph->h, x + glyph->x, y + glyph->y + glyph->h};
				fz_paint_image(dev->dest, dev->scissor, dev->shape, glyph, ctm, alpha * 255);
			}
			fz_drop_pixmap(ctx, glyph);
		}
	}

	if (dev->blendmode & FZ_BLEND_KNOCKOUT)
		fz_knockout_end(ctx, dev);
}
예제 #10
0
static void
fz_draw_clip_text(fz_device *devp, fz_text *text, fz_matrix ctm, int accumulate)
{
	fz_draw_device *dev = devp->user;
	fz_context *ctx = dev->ctx;
	fz_bbox bbox;
	fz_pixmap *mask, *dest, *shape;
	fz_matrix tm, trm, trunc_trm;
	fz_pixmap *glyph;
	int i, x, y, gid;
	fz_draw_state *state;
	fz_colorspace *model;

	/* 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 */

	state = push_stack(dev);
	model = state->dest->colorspace;

	if (accumulate == 0)
	{
		/* make the mask the exact size needed */
		bbox = fz_bbox_covering_rect(fz_bound_text(dev->ctx, text, ctm));
		bbox = fz_intersect_bbox(bbox, state->scissor);
	}
	else
	{
		/* be conservative about the size of the mask needed */
		bbox = state->scissor;
	}

	if (accumulate == 0 || accumulate == 1)
	{
		mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
		fz_clear_pixmap(dev->ctx, mask);
		dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox);
		fz_clear_pixmap(dev->ctx, dest);
		if (state->shape)
		{
			shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
			fz_clear_pixmap(dev->ctx, shape);
		}
		else
			shape = NULL;

		state[1].blendmode |= FZ_BLEND_ISOLATED;
		state[1].scissor = bbox;
		state[1].dest = dest;
		state[1].mask = mask;
		state[1].shape = shape;
#ifdef DUMP_GROUP_BLENDS
		dump_spaces(dev->top-1, "Clip (text) begin\n");
#endif
	}
	else
	{
		mask = state->mask;
		dev->top--;
	}

	if (!fz_is_empty_rect(bbox) && mask)
	{
		tm = text->trm;

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

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

			trunc_trm = trm;
			trunc_trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX);
			trunc_trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX);

			glyph = fz_render_glyph(dev->ctx, text->font, gid, trunc_trm, model, bbox);
			if (glyph)
			{
				draw_glyph(NULL, mask, glyph, x, y, bbox);
				if (state[1].shape)
					draw_glyph(NULL, state[1].shape, glyph, x, y, bbox);
				fz_drop_pixmap(dev->ctx, glyph);
			}
			else
			{
				fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, trm);
				if (path)
				{
					fz_pixmap *old_dest;
					float white = 1;

					state = &dev->stack[dev->top];
					old_dest = state[0].dest;
					state[0].dest = state[0].mask;
					state[0].mask = NULL;
					fz_try(ctx)
					{
						fz_draw_fill_path(devp, path, 0, fz_identity, fz_device_gray, &white, 1);
					}
					fz_always(ctx)
					{
						state[0].mask = state[0].dest;
						state[0].dest = old_dest;
						fz_free_path(dev->ctx, path);
					}
					fz_catch(ctx)
					{
						fz_rethrow(ctx);
					}
				}
				else
				{
					fz_warn(dev->ctx, "cannot render glyph for clipping");
				}
			}
		}
예제 #11
0
static void
fz_draw_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm,
	fz_colorspace *colorspace, float *color, float alpha)
{
	fz_draw_device *dev = devp->user;
	unsigned char colorbv[FZ_MAX_COLORS + 1];
	float colorfv[FZ_MAX_COLORS];
	fz_matrix tm, trm, trunc_trm;
	fz_pixmap *glyph;
	int i, x, y, gid;
	fz_draw_state *state = &dev->stack[dev->top];
	fz_colorspace *model = state->dest->colorspace;
	fz_bbox scissor = state->scissor;

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

	fz_convert_color(dev->ctx, model, colorfv, colorspace, color);
	for (i = 0; i < model->n; i++)
		colorbv[i] = colorfv[i] * 255;
	colorbv[i] = alpha * 255;

	tm = text->trm;

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

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

		trunc_trm = trm;
		trunc_trm.e = QUANT(trm.e - floorf(trm.e), HSUBPIX);
		trunc_trm.f = QUANT(trm.f - floorf(trm.f), VSUBPIX);

		scissor.x0 -= x; scissor.x1 -= x;
		scissor.y0 -= y; scissor.y1 -= y;

		glyph = fz_render_stroked_glyph(dev->ctx, text->font, gid, trunc_trm, ctm, stroke, scissor);
		if (glyph)
		{
			draw_glyph(colorbv, state->dest, glyph, x, y, state->scissor);
			if (state->shape)
				draw_glyph(colorbv, state->shape, glyph, x, y, state->scissor);
			fz_drop_pixmap(dev->ctx, glyph);
		}
		else
		{
			fz_path *path = fz_outline_glyph(dev->ctx, text->font, gid, trm);
			if (path)
			{
				fz_draw_stroke_path(devp, path, stroke, fz_identity, colorspace, color, alpha);
				fz_free_path(dev->ctx, path);
			}
			else
			{
				fz_warn(dev->ctx, "cannot render glyph");
			}
		}
	}

	if (state->blendmode & FZ_BLEND_KNOCKOUT)
		fz_knockout_end(dev);
}
예제 #12
0
static void
fz_draw_clip_stroke_text(fz_device *devp, fz_text *text, fz_stroke_state *stroke, fz_matrix ctm)
{
	fz_draw_device *dev = devp->user;
	fz_bbox bbox;
	fz_pixmap *mask, *dest, *shape;
	fz_matrix tm, trm;
	fz_pixmap *glyph;
	int i, x, y, gid;
	fz_draw_state *state = push_stack(dev);
	fz_colorspace *model = state->dest->colorspace;

	/* make the mask the exact size needed */
	bbox = fz_bbox_covering_rect(fz_bound_text(dev->ctx, text, ctm));
	bbox = fz_intersect_bbox(bbox, state->scissor);

	mask = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
	fz_clear_pixmap(dev->ctx, mask);
	dest = fz_new_pixmap_with_bbox(dev->ctx, model, bbox);
	fz_clear_pixmap(dev->ctx, dest);
	if (state->shape)
	{
		shape = fz_new_pixmap_with_bbox(dev->ctx, NULL, bbox);
		fz_clear_pixmap(dev->ctx, shape);
	}
	else
		shape = state->shape;

	state[1].blendmode |= FZ_BLEND_ISOLATED;
	state[1].scissor = bbox;
	state[1].dest = dest;
	state[1].shape = shape;
	state[1].mask = mask;
#ifdef DUMP_GROUP_BLENDS
	dump_spaces(dev->top-1, "Clip (stroke text) begin\n");
#endif

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

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

			tm.e = text->items[i].x;
			tm.f = text->items[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_render_stroked_glyph(dev->ctx, text->font, gid, trm, ctm, stroke, bbox);
			if (glyph)
			{
				draw_glyph(NULL, mask, glyph, x, y, bbox);
				if (shape)
					draw_glyph(NULL, shape, glyph, x, y, bbox);
				fz_drop_pixmap(dev->ctx, glyph);
			}
			else
			{
				fz_warn(dev->ctx, "cannot draw glyph for clipping (unimplemented case)");
				// TODO: outline/non-cached case
			}
		}
	}
}
예제 #13
0
Int quantizeMacroblock(CWMImageStrCodec* pSC)
{
    CWMITile * pTile = pSC->pTile + pSC->cTileColumn;
    CWMIMBInfo * pMBInfo = &pSC->MBInfo;
    const COLORFORMAT cf = pSC->m_param.cfColorFormat;
    int iChannel, i, j;

    if(/*pSC->m_param.bScaledArith && */pSC->m_param.bTranscode == FALSE)
        for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
            const Bool bUV = (iChannel > 0 && (cf == YUV_444 || cf == YUV_422 || cf == YUV_420));
            const int iNumBlock = (bUV ? (cf == YUV_422 ? 8 : (cf == YUV_420 ? 4 : 16)) : 16);
            const int * pOffset = (iNumBlock == 4 ? blkOffsetUV : (iNumBlock == 8 ? blkOffsetUV_422 : blkOffset));
            CWMIQuantizer * pQPDC = pTile->pQuantizerDC[iChannel];
            CWMIQuantizer * pQPLP = pTile->pQuantizerLP[iChannel] + pMBInfo->iQIndexLP;
            CWMIQuantizer * pQPHP = pTile->pQuantizerHP[iChannel] + pMBInfo->iQIndexHP;

            for(j = 0; j < iNumBlock; j ++){
                PixelI * pData = pSC->pPlane[iChannel] + pOffset[j];

                if(j == 0) // DC
                    pData[0] = (pQPDC->iMan == 0 ? QUANT_Mulless(pData[0], pQPDC->iOffset, pQPDC->iExp) : QUANT(pData[0], pQPDC->iOffset, pQPDC->iMan, pQPDC->iExp));
                else if(pSC->WMISCP.sbSubband != SB_DC_ONLY) // LP
                    pData[0] = (pQPLP->iMan == 0 ? QUANT_Mulless(pData[0], pQPLP->iOffset, pQPLP->iExp) : QUANT(pData[0], pQPLP->iOffset, pQPLP->iMan, pQPLP->iExp));

                // quantize HP
                if(pSC->WMISCP.sbSubband != SB_DC_ONLY && pSC->WMISCP.sbSubband != SB_NO_HIGHPASS)
                    for(i = 1; i < 16; i ++)
                        pData[i] = (pQPHP->iMan == 0 ? QUANT_Mulless(pData[i], pQPHP->iOffset, pQPHP->iExp) : QUANT(pData[i], pQPHP->iOffset, pQPHP->iMan, pQPHP->iExp));
            }
        }
    
    for(iChannel = 0; iChannel < (int)pSC->m_param.cNumChannels; iChannel ++){
        I32 * pDC = pSC->MBInfo.iBlockDC[iChannel];
        PixelI * pData = pSC->pPlane[iChannel];

        if(iChannel > 0 && cf == YUV_422){
            for(i = 0; i < 8; i ++){
                pDC[i] = pData[blkOffsetUV_422[i]];
            }
        }
        else if(iChannel > 0 && cf == YUV_420){
            for(i = 0; i < 4; i ++){
                pDC[i] = pData[blkOffsetUV[i]];
            }
        }
        else{
            for(i = 0; i < 16; i ++){
                pDC[i] = pData[dctIndex[2][i]];
            }
        }
    }

    return 0;
}