/*
* Copyright © 2025 Red Hat , Inc
*
* SPDX - License - Identifier : LGPL - 2 . 1 - or - later
*
* This library is free software ; you can redistribute it and / or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation ; either
* version 2 . 1 of the License , or ( at your option ) any later version .
*
* This library 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
* Lesser General Public License for more details .
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library . If not , see < http : //www.gnu.org/licenses/>.
*
* Authors : Matthias Clasen < mclasen @ redhat . com >
*/
#include "config.h"
#include "gtksvgorientprivate.h"
#include "gtksvgvalueprivate.h"
#include "gtksvgutilsprivate.h"
#include "gtksvgstringutilsprivate.h"
#include "gtksvgnumberprivate.h"
#include "gtksvgelementinternal.h"
typedef struct
{
SvgValue base;
OrientKind kind;
gboolean start_reverse;
double angle;
SvgUnit unit;
} SvgOrient;
static gboolean
svg_orient_equal (const SvgValue *value0,
const SvgValue *value1)
{
const SvgOrient *v0 = (const SvgOrient *) value0;
const SvgOrient *v1 = (const SvgOrient *) value1;
if (v0->kind != v1->kind)
return FALSE ;
if (v0->kind == ORIENT_AUTO)
return v0->start_reverse == v1->start_reverse;
else
return v0->angle == v1->angle &&
v0->unit == v1->unit;
}
static SvgValue *
svg_orient_interpolate (const SvgValue *value0,
const SvgValue *value1,
SvgComputeContext *context,
double t)
{
const SvgOrient *v0 = (const SvgOrient *) value0;
const SvgOrient *v1 = (const SvgOrient *) value1;
if (v0->kind == v1->kind &&
v0->kind == ORIENT_ANGLE &&
v0->unit == v1->unit)
return svg_orient_new_angle (lerp (v0->angle, v1->angle, t), v0->unit);
if (t < 0 .5 )
return svg_value_ref ((SvgValue *) value0);
else
return svg_value_ref ((SvgValue *) value1);
}
static SvgValue *
svg_orient_accumulate (const SvgValue *value0,
const SvgValue *value1,
SvgComputeContext *context,
int n)
{
return NULL;
}
static void
svg_orient_print (const SvgValue *value,
GString *string)
{
const SvgOrient *v = (const SvgOrient *) value;
if (v->kind == ORIENT_ANGLE)
{
string_append_double (string, "" , v->angle);
g_string_append (string, svg_unit_name (v->unit));
}
else if (v->start_reverse)
{
g_string_append (string, "auto-start-reverse" );
}
else
{
g_string_append (string, "auto" );
}
}
static SvgValue * svg_orient_resolve (const SvgValue *value,
SvgProperty attr,
unsigned int idx,
SvgElement *shape,
SvgComputeContext *context);
static const SvgValueClass SVG_ORIENT_CLASS = {
"SvgOrient" ,
svg_value_default_free,
svg_orient_equal,
svg_orient_interpolate,
svg_orient_accumulate,
svg_orient_print,
svg_value_default_distance,
svg_orient_resolve,
};
SvgValue *
svg_orient_new_angle (double angle,
SvgUnit unit)
{
static SvgOrient def = { { &SVG_ORIENT_CLASS, 0 }, .kind = ORIENT_ANGLE, .angle = 0 , .unit = SVG_UNIT_NUMBER };
SvgOrient *v;
if (angle == 0 && unit == SVG_UNIT_NUMBER)
return (SvgValue *) &def;
v = (SvgOrient *) svg_value_alloc (&SVG_ORIENT_CLASS, sizeof (SvgOrient));
v->kind = ORIENT_ANGLE;
v->angle = angle;
v->unit = unit;
return (SvgValue *) v;
}
SvgValue *
svg_orient_new_auto (gboolean start_reverse)
{
SvgOrient *v;
v = (SvgOrient *) svg_value_alloc (&SVG_ORIENT_CLASS, sizeof (SvgOrient));
v->kind = ORIENT_AUTO;
v->start_reverse = start_reverse;
return (SvgValue *) v;
}
SvgValue *
svg_orient_parse (GtkCssParser *parser)
{
if (gtk_css_parser_try_ident (parser, "auto" ))
return svg_orient_new_auto (FALSE );
else if (gtk_css_parser_try_ident (parser, "auto-start-reverse" ))
return svg_orient_new_auto (TRUE );
else
{
double f;
SvgUnit unit;
if (!svg_number_parse2 (parser, -DBL_MAX, DBL_MAX, SVG_PARSE_NUMBER|SVG_PARSE_ANGLE, &f, &unit))
return NULL;
return svg_orient_new_angle (f, unit);
}
}
static SvgValue *
svg_orient_resolve (const SvgValue *value,
SvgProperty attr,
unsigned int idx,
SvgElement *shape,
SvgComputeContext *context)
{
const SvgOrient *v = (const SvgOrient *) value;
if (v->kind == ORIENT_ANGLE)
{
switch ((unsigned int ) v->unit)
{
case SVG_UNIT_NUMBER:
return svg_value_ref ((SvgValue *) value);
case SVG_UNIT_RAD:
return svg_orient_new_angle (v->angle * 180 .0 / M_PI, SVG_UNIT_NUMBER);
case SVG_UNIT_DEG:
return svg_orient_new_angle (v->angle, SVG_UNIT_NUMBER);
case SVG_UNIT_GRAD:
return svg_orient_new_angle (v->angle * 360 .0 / 400 .0 , SVG_UNIT_NUMBER);
case SVG_UNIT_TURN:
return svg_orient_new_angle (v->angle * 360 .0 , SVG_UNIT_NUMBER);
default :
g_assert_not_reached ();
}
}
else
return svg_value_ref ((SvgValue *) value);
}
OrientKind
svg_orient_get_kind (const SvgValue *value)
{
const SvgOrient *v = (const SvgOrient *) value;
g_assert (value->class == &SVG_ORIENT_CLASS);
return v->kind;
}
gboolean
svg_orient_get_start_reverse (const SvgValue *value)
{
const SvgOrient *v = (const SvgOrient *) value;
g_assert (value->class == &SVG_ORIENT_CLASS);
g_assert (v->kind == ORIENT_AUTO);
return v->start_reverse;
}
double
svg_orient_get_angle (const SvgValue *value)
{
const SvgOrient *v = (const SvgOrient *) value;
g_assert (value->class == &SVG_ORIENT_CLASS);
g_assert (v->kind == ORIENT_ANGLE);
return v->angle;
}
Messung V0.5 in Prozent C=99 H=92 G=95
¤ Dauer der Verarbeitung: 0.12 Sekunden
(vorverarbeitet am 2026-07-03)
¤
*© Formatika GbR, Deutschland