<commit_before>/*
 * Copyright © 2009 <NAME>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 *
 * Author:
 * 	<NAME> <<EMAIL>>
 */

#include <lsmsvgsvgelement.h>
#include <lsmsvgstyle.h>
#include <lsmsvgview.h>
#include <lsmdebug.h>
#include <lsmdomdocument.h>
#include <math.h>
#include <stdio.h>

static GObjectClass *parent_class;

/* GdomNode implementation */

static const char *
lsm_svg_svg_element_get_node_name (LsmDomNode *node)
{
	return "svg";
}

/* LsmSvgElement implementation */

void
lsm_svg_svg_element_measure (LsmSvgSvgElement *self, double *width, double *height)
{
	LsmDomDocument *document;
	LsmSvgViewbox *svg_viewbox;
	LsmBox viewport;
	double resolution_ppi;
	double svg_x;
	double svg_y;
	double svg_width;
	double svg_height;
	double font_size;

	g_return_if_fail (LSM_IS_SVG_SVG_ELEMENT (self));

	document = LSM_DOM_DOCUMENT (LSM_DOM_NODE (self)->parent_node);
	g_return_if_fail (LSM_IS_DOM_DOCUMENT (document));

	resolution_ppi = lsm_dom_document_get_resolution (document);
	viewport = lsm_dom_document_get_viewport_px (document);

	svg_viewbox = lsm_svg_viewbox_new (resolution_ppi, &viewport);
	font_size = 10 * resolution_ppi / 72.0;

	if (lsm_attribute_is_defined (&self->x.base))
		svg_x = lsm_svg_length_normalize (&self->x.length, svg_viewbox,
						  font_size, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
	else
		svg_x = viewport.x;

	if (lsm_attribute_is_defined (&self->y.base))
		svg_y = lsm_svg_length_normalize (&self->y.length, svg_viewbox,
						  font_size, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
	else
		svg_y = viewport.y;

	if (lsm_attribute_is_defined (&self->width.base))
		svg_width = lsm_svg_length_normalize (&self->width.length, svg_viewbox,
						       font_size, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
	else
		svg_width = viewport.width;

	if (lsm_attribute_is_defined (&self->height.base))
		svg_height = lsm_svg_length_normalize (&self->height.length, svg_viewbox,
						       font_size, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
	else
		svg_height = viewport.height;

	if (width != NULL)
		*width = svg_width * 72.0 / resolution_ppi;
	if (height != NULL)
		*height = svg_height * 72.0 / resolution_ppi;

	self->svg_box.x = svg_x;
	self->svg_box.y = svg_y;
	self->svg_box.width = svg_width;
	self->svg_box.height = svg_height;

	lsm_debug ("[LsmSvgSvgElement::measure] Size = %g, %g, %g, %g",
		   svg_x, svg_y, svg_width, svg_height);

	lsm_svg_viewbox_free (svg_viewbox);
}

/* LsmSvgGraphic implementation */

static void
_svg_element_render (LsmSvgElement *self, LsmSvgView *view)
{
	LsmSvgSvgElement *svg = LSM_SVG_SVG_ELEMENT (self);
	gboolean is_viewbox_defined;
	LsmBox viewport;

	viewport.x      = lsm_svg_view_normalize_length (view, &svg->x.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
	viewport.y      = lsm_svg_view_normalize_length (view, &svg->y.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
	viewport.width  = lsm_svg_view_normalize_length (view, &svg->width.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
	viewport.height = lsm_svg_view_normalize_length (view, &svg->height.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);

	is_viewbox_defined = lsm_attribute_is_defined ((LsmAttribute *) &svg->viewbox);

	if (is_viewbox_defined && (svg->viewbox.value.width <= 0.0 ||
				   svg->viewbox.value.height <= 0.0))
		return;

	lsm_debug ("[LsmSvgSvgElement::render] viewport %g, %g, %g, %g",
		   viewport.x, viewport.y, viewport.width, viewport.height);

	lsm_svg_view_push_viewport (view, &viewport, is_viewbox_defined ? &svg->viewbox.value : NULL,
				    &svg->preserve_aspect_ratio.value);

	LSM_SVG_ELEMENT_CLASS (parent_class)->render (self, view);

	lsm_svg_view_pop_viewport (view);
}

/* LsmSvgSvgElement implementation */

void
lsm_svg_svg_element_render (LsmSvgSvgElement *svg, LsmSvgView *view)
{
	lsm_svg_view_push_viewbox (view, &svg->svg_box);
	lsm_svg_element_render (LSM_SVG_ELEMENT (svg), view);
	lsm_svg_view_pop_viewbox (view);
}

LsmDomNode *
lsm_svg_svg_element_new (void)
{
	return g_object_new (LSM_TYPE_SVG_SVG_ELEMENT, NULL);
}

static const LsmSvgLength x_y_default = 	 { .value_unit =   0.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
static const LsmSvgLength width_height_default = { .value_unit = 100.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
static const LsmBox viewbox_default =		 {0.0, 0.0, 0.0, 0.0};
static const LsmSvgPreserveAspectRatio preserve_aspect_ratio_default = {
	.defer = FALSE,
	.align = LSM_SVG_ALIGN_X_MID_Y_MID,
	.meet_or_slice = LSM_SVG_MEET_OR_SLICE_MEET
};

static void
lsm_svg_svg_element_init (LsmSvgSvgElement *self)
{<commit_msg><svg:svg> Use view_push_viewport instead of view_push_viewbox.<commit_after>/*
 * Copyright © 2009 <NAME>
 *
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
 *
 * Author:
 * 	<NAME> <<EMAIL>>
 */

#include <lsmsvgsvgelement.h>
#include <lsmsvgstyle.h>
#include <lsmsvgview.h>
#include <lsmdebug.h>
#include <lsmdomdocument.h>
#include <math.h>
#include <stdio.h>

static GObjectClass *parent_class;

/* GdomNode implementation */

static const char *
lsm_svg_svg_element_get_node_name (LsmDomNode *node)
{
	return "svg";
}

/* LsmSvgElement implementation */

void
lsm_svg_svg_element_measure (LsmSvgSvgElement *self, double *width, double *height)
{
	LsmDomDocument *document;
	LsmSvgViewbox *svg_viewbox;
	LsmBox viewport;
	double resolution_ppi;
	double svg_x;
	double svg_y;
	double svg_width;
	double svg_height;
	double font_size;

	g_return_if_fail (LSM_IS_SVG_SVG_ELEMENT (self));

	document = LSM_DOM_DOCUMENT (LSM_DOM_NODE (self)->parent_node);
	g_return_if_fail (LSM_IS_DOM_DOCUMENT (document));

	resolution_ppi = lsm_dom_document_get_resolution (document);
	viewport = lsm_dom_document_get_viewport_px (document);

	svg_viewbox = lsm_svg_viewbox_new (resolution_ppi, &viewport);
	font_size = 10 * resolution_ppi / 72.0;

	if (lsm_attribute_is_defined (&self->x.base))
		svg_x = lsm_svg_length_normalize (&self->x.length, svg_viewbox,
						  font_size, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
	else
		svg_x = viewport.x;

	if (lsm_attribute_is_defined (&self->y.base))
		svg_y = lsm_svg_length_normalize (&self->y.length, svg_viewbox,
						  font_size, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
	else
		svg_y = viewport.y;

	if (lsm_attribute_is_defined (&self->width.base))
		svg_width = lsm_svg_length_normalize (&self->width.length, svg_viewbox,
						       font_size, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
	else
		svg_width = viewport.width;

	if (lsm_attribute_is_defined (&self->height.base))
		svg_height = lsm_svg_length_normalize (&self->height.length, svg_viewbox,
						       font_size, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
	else
		svg_height = viewport.height;

	if (width != NULL)
		*width = svg_width * 72.0 / resolution_ppi;
	if (height != NULL)
		*height = svg_height * 72.0 / resolution_ppi;

	self->svg_box.x = svg_x;
	self->svg_box.y = svg_y;
	self->svg_box.width = svg_width;
	self->svg_box.height = svg_height;

	lsm_debug ("[LsmSvgSvgElement::measure] Size = %g, %g, %g, %g",
		   svg_x, svg_y, svg_width, svg_height);

	lsm_svg_viewbox_free (svg_viewbox);
}

/* LsmSvgGraphic implementation */

static void
_svg_element_render (LsmSvgElement *self, LsmSvgView *view)
{
	LsmSvgSvgElement *svg = LSM_SVG_SVG_ELEMENT (self);
	gboolean is_viewbox_defined;
	LsmBox viewport;

	viewport.x      = lsm_svg_view_normalize_length (view, &svg->x.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
	viewport.y      = lsm_svg_view_normalize_length (view, &svg->y.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);
	viewport.width  = lsm_svg_view_normalize_length (view, &svg->width.length, LSM_SVG_LENGTH_DIRECTION_HORIZONTAL);
	viewport.height = lsm_svg_view_normalize_length (view, &svg->height.length, LSM_SVG_LENGTH_DIRECTION_VERTICAL);

	is_viewbox_defined = lsm_attribute_is_defined ((LsmAttribute *) &svg->viewbox);

	if (is_viewbox_defined && (svg->viewbox.value.width <= 0.0 ||
				   svg->viewbox.value.height <= 0.0))
		return;

	lsm_debug ("[LsmSvgSvgElement::render] viewport %g, %g, %g, %g",
		   viewport.x, viewport.y, viewport.width, viewport.height);

	lsm_svg_view_push_viewport (view, &viewport, is_viewbox_defined ? &svg->viewbox.value : NULL,
				    &svg->preserve_aspect_ratio.value);

	LSM_SVG_ELEMENT_CLASS (parent_class)->render (self, view);

	lsm_svg_view_pop_viewport (view);
}

/* LsmSvgSvgElement implementation */

void
lsm_svg_svg_element_render (LsmSvgSvgElement *svg, LsmSvgView *view)
{
	lsm_svg_view_push_viewport (view, &svg->svg_box, NULL, NULL);
	lsm_svg_element_render (LSM_SVG_ELEMENT (svg), view);
	lsm_svg_view_pop_viewport (view);
}

LsmDomNode *
lsm_svg_svg_element_new (void)
{
	return g_object_new (LSM_TYPE_SVG_SVG_ELEMENT, NULL);
}

static const LsmSvgLength x_y_default = 	 { .value_unit =   0.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
static const LsmSvgLength width_height_default = { .value_unit = 100.0, .type = LSM_SVG_LENGTH_TYPE_PERCENTAGE};
static const LsmBox viewbox_default =		 {0.0, 0.0, 0.0, 0.0};
static const LsmSvgPreserveAspectRatio preserve_aspect_ratio_default = {
	.defer = FALSE,
	.align = LSM_SVG_ALIGN_X_MID_Y_MID,
	.meet_or_slice = LSM_SVG_MEET_OR_SLICE_MEET
};

static void
lsm_svg_svg_element_init (LsmSvgSvgElement *self)
{
{'fraction_non_alphanumeric': 0.10368817306775946, 'fraction_numerical': 0.008577146669208044, 'mean_word_length': 5.302702702702702, 'pattern_counts': {'":': 0, '<': 30, '<?xml version=': 0, '>': 74, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '2935681', 'n_tokens_mistral': 4249, 'n_tokens_neox': 4026, 'n_words': 843}