コード例 #1
0
ファイル: enesim_matrix.c プロジェクト: bluezery/enesim
/**
 * Creates a projective matrix that maps a quadrangle to a quadrangle
 */
EAPI Eina_Bool enesim_matrix_quad_quad_map(Enesim_Matrix *m,
		const Enesim_Quad *src, const Enesim_Quad *dst)
{
	Enesim_Matrix tmp;

	/* TODO check that both are actually quadrangles */
	if (!enesim_matrix_quad_square_map(m, src))
		return EINA_FALSE;
	if (!enesim_matrix_square_quad_map(&tmp, dst))
		return EINA_FALSE;
	enesim_matrix_compose(&tmp, m, m);

	return EINA_TRUE;
}
コード例 #2
0
ファイル: egueb_svg_renderable.c プロジェクト: turran/egueb
/*----------------------------------------------------------------------------*
 *                             Element interface                              *
 *----------------------------------------------------------------------------*/
static Eina_Bool _egueb_svg_renderable_process(Egueb_Svg_Element *e)
{
	Egueb_Svg_Renderable *thiz;
	Egueb_Svg_Renderable_Class *klass;
	Egueb_Svg_Clip_Path clip_path = EGUEB_SVG_CLIP_PATH_INIT;
	Egueb_Svg_Matrix m;
	Egueb_Svg_Painter *painter;
	Egueb_Dom_Node *relative;
	Egueb_Dom_Node *doc;
	Egueb_Dom_Node *topmost;
	Enesim_Renderer *ren = NULL;

	thiz = EGUEB_SVG_RENDERABLE(e);
	klass = EGUEB_SVG_RENDERABLE_CLASS_GET(e);

	/* set the new transformation */
	relative = egueb_svg_element_geometry_relative_get(EGUEB_DOM_NODE(e));
	if (relative)
	{
		Egueb_Svg_Element *e_parent;

		e_parent = EGUEB_SVG_ELEMENT(relative);
		egueb_dom_attr_final_get(thiz->transform, &m);
		enesim_matrix_compose(&e_parent->transform, &m, &e->transform);
		egueb_dom_node_unref(relative);
	}
	/* TODO in case there is no relative, set our own transform */

	DBG_ELEMENT(EGUEB_DOM_NODE(e), "New transformation %" ENESIM_MATRIX_FORMAT, ENESIM_MATRIX_ARGS(&e->transform));

	/* first process the renderable itself */
	if (klass->process)
	{
		if (!klass->process(thiz))
		{
			WARN_ELEMENT(EGUEB_DOM_NODE(e), "Process failed");
			return EINA_FALSE;
		}
	}

	/* propagate the presentation attributes */
	/* resolve the painter based on the presentation attributes */
	painter = egueb_svg_painter_ref(thiz->painter);
	if (!painter)
	{
		doc = egueb_dom_node_owner_document_get(EGUEB_DOM_NODE(e));
		if (!doc)
		{
			WARN_ELEMENT(EGUEB_DOM_NODE(e), "No document available");
			return EINA_FALSE;
		}
		topmost = egueb_dom_document_document_element_get(doc);
		egueb_dom_node_unref(doc);

		/* The only special case is the topmost svg element */
		if (topmost == EGUEB_DOM_NODE(e))
		{
			painter = egueb_svg_renderable_class_painter_get(EGUEB_DOM_NODE(e));
			if (!painter)
			{
				WARN_ELEMENT(EGUEB_DOM_NODE(e), "Topmost element does not have a painter");
				egueb_dom_node_unref(topmost);
			}
			egueb_dom_node_unref(topmost);
		}
		else
		{
			egueb_dom_node_unref(topmost);
			WARN_ELEMENT(EGUEB_DOM_NODE(e), "No painter available");
		}
	}

	if (painter)
	{
		if (!egueb_svg_painter_resolve(painter, e))
		{
			WARN_ELEMENT(EGUEB_DOM_NODE(e), "Painter resolving failed");
			egueb_svg_painter_unref(painter);
			return EINA_FALSE;
		}
		/* finally call the renderer propagate implementation */
		if (klass->painter_apply)
			klass->painter_apply(thiz, painter);
		egueb_svg_painter_unref(painter);
	}

	/* now resolve the clip path */
	egueb_svg_element_clip_path_final_get(EGUEB_DOM_NODE(e), &clip_path);
	egueb_svg_element_clip_path_resolve(EGUEB_DOM_NODE(e), &clip_path,
			&thiz->clip_path_last, &thiz->clip_path);
	egueb_svg_clip_path_reset(&clip_path);

	if (thiz->clip_path)
		egueb_svg_reference_clip_path_renderer_get(thiz->clip_path, &ren);

	/* set the correct renderer on the proxy */
	if (ren)
	{
		DBG_ELEMENT(EGUEB_DOM_NODE(e), "Clip path: %s", enesim_renderer_name_get(ren));
	}
	else
	{
		if (klass->renderer_get)
			ren = klass->renderer_get(thiz);
		if (!ren)
		{
			WARN_ELEMENT(EGUEB_DOM_NODE(e), "No renderer found");
			return EINA_FALSE;
		}
		else
		{
			DBG_ELEMENT(EGUEB_DOM_NODE(e), "Renderer: %s", enesim_renderer_name_get(ren));
		}
	}
	enesim_renderer_proxy_proxied_set(thiz->proxy, ren);
	_egueb_svg_renderable_check_new_bounds(thiz);
	return EINA_TRUE;
}
コード例 #3
0
/*----------------------------------------------------------------------------*
 *                              Gradient interface                            *
 *----------------------------------------------------------------------------*/
static Eina_Bool _egueb_svg_reference_gradient_linear_process(
		Egueb_Svg_Reference_Gradient *g)
{
	Egueb_Svg_Reference_Gradient_Linear *thiz;
	Egueb_Svg_Reference *r;
	Egueb_Svg_Length x1, y1, x2, y2;
	Egueb_Svg_Referenceable_Units units;
	Egueb_Dom_Node *doc = NULL;
	Enesim_Matrix m, transform;
	double gx1, gy1, gx2, gy2;

	DBG("Processing a linear gradient reference");
	/* get the final attributes */
	r = EGUEB_SVG_REFERENCE(g);
	egueb_svg_element_linear_gradient_deep_x1_get(r->referenceable, &x1);
	egueb_svg_element_linear_gradient_deep_y1_get(r->referenceable, &y1);
	egueb_svg_element_linear_gradient_deep_x2_get(r->referenceable, &x2);
	egueb_svg_element_linear_gradient_deep_y2_get(r->referenceable, &y2);
	egueb_svg_gradient_deep_units_get(r->referenceable, &units);
	egueb_svg_gradient_deep_transform_get(r->referenceable, &transform);

	if (units == EGUEB_SVG_REFERENCEABLE_UNITS_OBJECT_BOUNDING_BOX)
	{
		Enesim_Rectangle bounds;
		Egueb_Svg_Element *e_referencer;

		e_referencer = EGUEB_SVG_ELEMENT(r->referencer);
		/* check that the coordinates shold be set with (0,0) -> (1, 1) */
		gx1 = egueb_svg_coord_final_get(&x1, 1, 1);
		gy1 = egueb_svg_coord_final_get(&y1, 1, 1);
		gx2 = egueb_svg_coord_final_get(&x2, 1, 1);
		gy2 = egueb_svg_coord_final_get(&y2, 1, 1);

		egueb_svg_renderable_bounds_get(r->referencer, &bounds);
		enesim_matrix_values_set(&m, bounds.w, 0, bounds.x, 0, bounds.h, bounds.y, 0, 0, 1);
		DBG("Using the object bounding box %" ENESIM_RECTANGLE_FORMAT, ENESIM_RECTANGLE_ARGS(&bounds));
		/* transform the bounds using the context matrix */
		enesim_matrix_compose(&e_referencer->transform, &m, &m);
	}
	else
	{
		Egueb_Dom_Node *g_relative;
		Egueb_Svg_Element *ge_relative;
		double font_size;

		DBG("Using the user space on use");
		doc = egueb_dom_node_owner_document_get(r->referencer);
		if (!doc)
		{
			WARN("No document set");
			return EINA_FALSE;
		}
		font_size = egueb_svg_document_font_size_get(doc);
		egueb_dom_node_unref(doc);

		g_relative = egueb_svg_element_geometry_relative_get(r->referencer);
		if (!g_relative)
		{
			WARN("No relative geometry");
			return EINA_FALSE;
		}
		ge_relative = EGUEB_SVG_ELEMENT(g_relative);

		/* use the user space coordiantes */
		gx1 = egueb_svg_coord_final_get(&x1, ge_relative->viewbox.w, font_size);
		gy1 = egueb_svg_coord_final_get(&y1, ge_relative->viewbox.h, font_size);
		gx2 = egueb_svg_coord_final_get(&x2, ge_relative->viewbox.w, font_size);
		gy2 = egueb_svg_coord_final_get(&y2, ge_relative->viewbox.h, font_size);

		m = ge_relative->transform;
		egueb_dom_node_unref(g_relative);
	}
	/* Apply the gradient transform */
	if (enesim_matrix_type_get(&transform) != ENESIM_MATRIX_TYPE_IDENTITY)
		enesim_matrix_compose(&m, &transform, &m);

	/* set the renderer properties */
	thiz = EGUEB_SVG_REFERENCE_GRADIENT_LINEAR(r);
	enesim_renderer_transformation_set(thiz->r, &m);
	enesim_renderer_gradient_linear_x0_set(thiz->r, gx1);
	enesim_renderer_gradient_linear_y0_set(thiz->r, gy1);
	enesim_renderer_gradient_linear_x1_set(thiz->r, gx2);
	enesim_renderer_gradient_linear_y1_set(thiz->r, gy2);

	DBG("Coordinates x1 = %g, y1 = %g, x2 = %g, y2 = %g", gx1, gy1, gx2, gy2);
	DBG("Transformation %" ENESIM_MATRIX_FORMAT, ENESIM_MATRIX_ARGS(&m));

	return EINA_TRUE;
}