예제 #1
0
파일: _pdf-device.c 프로젝트: rk700/PyMuPDF
static void
pdf_dev_path(fz_context *ctx, pdf_device *pdev, const fz_path *path)
{
	gstate *gs = CURRENT_GSTATE(pdev);

	fz_walk_path(ctx, path, &pdf_dev_path_proc, (void *)gs->buf);
}
예제 #2
0
static void
pdf_dev_alpha(fz_context *ctx, pdf_device *pdev, float alpha, int stroke)
{
	int i;
	pdf_document *doc = pdev->doc;
	gstate *gs = CURRENT_GSTATE(pdev);

	/* If the alpha is unchanged, nothing to do */
	if (gs->alpha[stroke] == alpha)
		return;

	/* Have we sent such an alpha before? */
	for (i = 0; i < pdev->num_alphas; i++)
		if (pdev->alphas[i].alpha == alpha && pdev->alphas[i].stroke == stroke)
			break;

	if (i == pdev->num_alphas)
	{
		pdf_obj *o;
		pdf_obj *ref = NULL;

		fz_var(ref);

		/* No. Need to make a new one */
		if (pdev->num_alphas == pdev->max_alphas)
		{
			int newmax = pdev->max_alphas * 2;
			if (newmax == 0)
				newmax = 4;
			pdev->alphas = fz_resize_array(ctx, pdev->alphas, newmax, sizeof(*pdev->alphas));
			pdev->max_alphas = newmax;
		}
		pdev->alphas[i].alpha = alpha;
		pdev->alphas[i].stroke = stroke;

		o = pdf_new_dict(ctx, doc, 1);
		fz_try(ctx)
		{
			char text[32];
			pdf_dict_put_drop(ctx, o, (stroke ? PDF_NAME_CA : PDF_NAME_ca), pdf_new_real(ctx, doc, alpha));
			ref = pdf_add_object(ctx, doc, o);
			fz_snprintf(text, sizeof(text), "ExtGState/Alp%d", i);
			pdf_dict_putp(ctx, pdev->resources, text, ref);
		}
		fz_always(ctx)
		{
			pdf_drop_obj(ctx, o);
			pdf_drop_obj(ctx, ref);
		}
		fz_catch(ctx)
		{
			fz_rethrow(ctx);
		}
		pdev->num_alphas++;
	}
예제 #3
0
파일: _pdf-device.c 프로젝트: rk700/PyMuPDF
static void
pdf_dev_ctm(fz_context *ctx, pdf_device *pdev, fz_matrix ctm)
{
	fz_matrix inverse;
	gstate *gs = CURRENT_GSTATE(pdev);

	if (memcmp(&gs->ctm, &ctm, sizeof(ctm)) == 0)
		return;
	inverse = fz_invert_matrix(gs->ctm);
	inverse = fz_concat(ctm, inverse);
	gs->ctm = ctm;
	fz_append_printf(ctx, gs->buf, "%M cm\n", &inverse);
}
예제 #4
0
static void
pdf_dev_ctm(fz_context *ctx, pdf_device *pdev, const fz_matrix *ctm)
{
	fz_matrix inverse;
	gstate *gs = CURRENT_GSTATE(pdev);

	if (memcmp(&gs->ctm, ctm, sizeof(*ctm)) == 0)
		return;
	fz_invert_matrix(&inverse, &gs->ctm);
	fz_concat(&inverse, ctm, &inverse);
	gs->ctm = *ctm;
	fz_buffer_printf(ctx, gs->buf, "%M cm\n", &inverse);
}
예제 #5
0
파일: _pdf-device.c 프로젝트: rk700/PyMuPDF
/* Helper functions */
static void
pdf_dev_stroke_state(fz_context *ctx, pdf_device *pdev, const fz_stroke_state *stroke_state)
{
	gstate *gs = CURRENT_GSTATE(pdev);

	if (stroke_state == gs->stroke_state)
		return;
	if (gs->stroke_state && !memcmp(stroke_state, gs->stroke_state, sizeof(*stroke_state)))
		return;
	if (!gs->stroke_state || gs->stroke_state->linewidth != stroke_state->linewidth)
	{
		fz_append_printf(ctx, gs->buf, "%g w\n", stroke_state->linewidth);
	}
	if (!gs->stroke_state || gs->stroke_state->start_cap != stroke_state->start_cap)
	{
		int cap = stroke_state->start_cap;
		/* FIXME: Triangle caps aren't supported in pdf */
		if (cap == FZ_LINECAP_TRIANGLE)
			cap = FZ_LINECAP_BUTT;
		fz_append_printf(ctx, gs->buf, "%d J\n", cap);
	}
	if (!gs->stroke_state || gs->stroke_state->linejoin != stroke_state->linejoin)
	{
		int join = stroke_state->linejoin;
		if (join == FZ_LINEJOIN_MITER_XPS)
			join = FZ_LINEJOIN_MITER;
		fz_append_printf(ctx, gs->buf, "%d j\n", join);
	}
	if (!gs->stroke_state || gs->stroke_state->miterlimit != stroke_state->miterlimit)
	{
		fz_append_printf(ctx, gs->buf, "%g M\n", stroke_state->miterlimit);
	}
	if (gs->stroke_state == NULL && stroke_state->dash_len == 0)
	{}
	else if (!gs->stroke_state || gs->stroke_state->dash_phase != stroke_state->dash_phase || gs->stroke_state->dash_len != stroke_state->dash_len ||
		memcmp(gs->stroke_state->dash_list, stroke_state->dash_list, sizeof(float)*stroke_state->dash_len))
	{
		int i;
		if (stroke_state->dash_len == 0)
			fz_append_byte(ctx, gs->buf, '[');
		for (i = 0; i < stroke_state->dash_len; i++)
		{
			if (i > 0)
				fz_append_byte(ctx, gs->buf, ' ');
			fz_append_printf(ctx, gs->buf, "%g", stroke_state->dash_list[i]);
		}
		fz_append_printf(ctx, gs->buf, "]%g d\n", stroke_state->dash_phase);
	}
	fz_drop_stroke_state(ctx, gs->stroke_state);
	gs->stroke_state = fz_keep_stroke_state(ctx, stroke_state);
}
예제 #6
0
파일: _pdf-device.c 프로젝트: rk700/PyMuPDF
static void
pdf_dev_color(fz_context *ctx, pdf_device *pdev, fz_colorspace *colorspace, const float *color, int stroke, const fz_color_params *color_params)
{
	int diff = 0;
	int i;
	int cspace = 0;
	float rgb[FZ_MAX_COLORS];
	gstate *gs = CURRENT_GSTATE(pdev);

	if (colorspace == fz_device_gray(ctx))
		cspace = 1;
	else if (colorspace == fz_device_rgb(ctx))
		cspace = 3;
	else if (colorspace == fz_device_cmyk(ctx))
		cspace = 4;

	if (cspace == 0)
	{
		/* If it's an unknown colorspace, fallback to rgb */
		fz_convert_color(ctx, color_params, NULL, fz_device_rgb(ctx), rgb, colorspace, color);
		color = rgb;
		colorspace = fz_device_rgb(ctx);
		cspace = 3;
	}

	if (gs->colorspace[stroke] != colorspace)
	{
		gs->colorspace[stroke] = colorspace;
		diff = 1;
	}

	for (i=0; i < cspace; i++)
		if (gs->color[stroke][i] != color[i])
		{
			gs->color[stroke][i] = color[i];
			diff = 1;
		}

	if (diff == 0)
		return;

	switch (cspace + stroke*8)
	{
		case 1:
			fz_append_printf(ctx, gs->buf, "%g g\n", color[0]);
			break;
		case 3:
			fz_append_printf(ctx, gs->buf, "%g %g %g rg\n", color[0], color[1], color[2]);
			break;
		case 4:
			fz_append_printf(ctx, gs->buf, "%g %g %g %g k\n", color[0], color[1], color[2], color[3]);
			break;
		case 1+8:
			fz_append_printf(ctx, gs->buf, "%g G\n", color[0]);
			break;
		case 3+8:
			fz_append_printf(ctx, gs->buf, "%g %g %g RG\n", color[0], color[1], color[2]);
			break;
		case 4+8:
			fz_append_printf(ctx, gs->buf, "%g %g %g %g K\n", color[0], color[1], color[2], color[3]);
			break;
	}
}
예제 #7
0
static void
pdf_dev_color(fz_context *ctx, pdf_device *pdev, fz_colorspace *colorspace, const float *color, int stroke)
{
	int diff = 0;
	int i;
	int cspace = 0;
	float rgb[FZ_MAX_COLORS];
	gstate *gs = CURRENT_GSTATE(pdev);

	if (colorspace == fz_device_gray(ctx))
		cspace = 1;
	else if (colorspace == fz_device_rgb(ctx))
		cspace = 3;
	else if (colorspace == fz_device_cmyk(ctx))
		cspace = 4;

	if (cspace == 0)
	{
		/* If it's an unknown colorspace, fallback to rgb */
		colorspace->to_rgb(ctx, colorspace, color, rgb);
		color = rgb;
		colorspace = fz_device_rgb(ctx);
	}

	if (gs->colorspace[stroke] != colorspace)
	{
		gs->colorspace[stroke] = colorspace;
		diff = 1;
	}

	for (i=0; i < colorspace->n; i++)
		if (gs->color[stroke][i] != color[i])
		{
			gs->color[stroke][i] = color[i];
			diff = 1;
		}

	if (diff == 0)
		return;

	switch (cspace + stroke*8)
	{
		case 1:
			fz_buffer_printf(ctx, gs->buf, "%f g\n", color[0]);
			break;
		case 3:
			fz_buffer_printf(ctx, gs->buf, "%f %f %f rg\n", color[0], color[1], color[2]);
			break;
		case 4:
			fz_buffer_printf(ctx, gs->buf, "%f %f %f %f k\n", color[0], color[1], color[2], color[3]);
			break;
		case 1+8:
			fz_buffer_printf(ctx, gs->buf, "%f G\n", color[0]);
			break;
		case 3+8:
			fz_buffer_printf(ctx, gs->buf, "%f %f %f RG\n", color[0], color[1], color[2]);
			break;
		case 4+8:
			fz_buffer_printf(ctx, gs->buf, "%f %f %f %f K\n", color[0], color[1], color[2], color[3]);
			break;
	}
}