Commit fc3c29fa authored by Dom Lachowicz's avatar Dom Lachowicz

support font style, stretch, variant, weight, family and inherit them...

support font style, stretch, variant, weight, family and inherit them properly, if necessary. also added CSS methods for parsing time, frequency, degrees/radians/grades
parent f70ddd71
2003-01-02 Dom Lachowicz <cinamod@hotmail.com>
* rsvg.c (*): Support font-style, font-variant, font-weight,
font-stretch, font-family, including the "inherit" option
* rsvg-css.c (*): ditto, CSS functions for parsing time, frequency,
degrees/radians/grades
* NEWS: added above news items
=== librsvg 2.1.2 ===
2002-11-25 Alexander Larsson <alexl@redhat.com>
......
Version 2.1.3
- Better font handling (stretch, style, variant, weight supported, inherited)
Version 2.1.2
- Fixed crash with non-utf8 characters.
......@@ -20,7 +24,7 @@ Version 2.1.1
Version 2.1.0
- New comaintainer Dom Lachowicz
- New co-maintainer Dom Lachowicz
- Added new svg based gtk+ engine
......
......@@ -31,6 +31,10 @@
#include <errno.h>
#include <stdio.h>
#ifndef M_PI
#define M_PI 3.14159265358979323846
#endif /* M_PI */
#define POINTS_PER_INCH (72.0)
#define CM_PER_INCH (2.54)
#define MM_PER_INCH (25.4)
......@@ -65,9 +69,7 @@ rsvg_css_parse_length (const char *str, gdouble pixels_per_inch,
/* todo: error condition - figure out how to best represent it */
if ((length == -HUGE_VAL || length == HUGE_VAL) && (ERANGE == errno))
{
return 0.0;
}
return 0.0;
/* test for either pixels or no unit, which is assumed to be pixels */
if (p && (strcmp(p, "px") != 0))
......@@ -157,7 +159,7 @@ rsvg_css_clip_rgb_percent (gint in_percent)
else if (in_percent <= 0)
return 0;
return (gint)floor(255. * (double)in_percent / 100.);
return (gint)floor(255. * (double)in_percent / 100. + 0.5);
}
static gint
......@@ -438,5 +440,200 @@ rsvg_css_parse_opacity (const char *str)
if (end_ptr && end_ptr[0] == '%')
opacity *= 0.01;
return (guint)floor (opacity * 255 + 0.5);
return (guint)floor (opacity * 255. + 0.5);
}
/*
<angle>: An angle value is a <number> optionally followed immediately with
an angle unit identifier. Angle unit identifiers are:
* deg: degrees
* grad: grads
* rad: radians
For properties defined in [CSS2], an angle unit identifier must be provided.
For SVG-specific attributes and properties, the angle unit identifier is
optional. If not provided, the angle value is assumed to be in degrees.
*/
double
rsvg_css_parse_angle (const char * str)
{
double degrees;
char *end_ptr;
degrees = g_ascii_strtod (str, &end_ptr);
/* todo: error condition - figure out how to best represent it */
if ((degrees == -HUGE_VAL || degrees == HUGE_VAL) && (ERANGE == errno))
return 0.0;
if (end_ptr)
{
if (!strcmp(end_ptr, "rad"))
return degrees * 180. / M_PI;
else if (!strcmp(end_ptr, "grad"))
return degrees * 360. / 400.;
}
return degrees;
}
/*
<frequency>: Frequency values are used with aural properties. The normative
definition of frequency values can be found in [CSS2-AURAL]. A frequency
value is a <number> immediately followed by a frequency unit identifier.
Frequency unit identifiers are:
* Hz: Hertz
* kHz: kilo Hertz
Frequency values may not be negative.
*/
double
rsvg_css_parse_frequency (const char * str)
{
double hz;
char *end_ptr;
hz = g_ascii_strtod (str, &end_ptr);
/* todo: error condition - figure out how to best represent it */
if ((hz == -HUGE_VAL || hz == HUGE_VAL) && (ERANGE == errno))
return 0.0;
if (end_ptr && !strcmp(end_ptr, "kHz"))
return hz * 1000.;
return hz;
}
/*
<time>: A time value is a <number> immediately followed by a time unit
identifier. Time unit identifiers are:
* ms: milliseconds
* s: seconds
Time values are used in CSS properties and may not be negative.
*/
double
rsvg_css_parse_time (const char * str)
{
double ms;
char *end_ptr;
ms = g_ascii_strtod (str, &end_ptr);
/* todo: error condition - figure out how to best represent it */
if ((ms == -HUGE_VAL || ms == HUGE_VAL) && (ERANGE == errno))
return 0.0;
if (end_ptr && !strcmp(end_ptr, "s"))
return ms * 1000.;
return ms;
}
PangoStyle
rsvg_css_parse_font_style (const char * str, PangoStyle inherit)
{
if (str)
{
if (!strcmp(str, "oblique"))
return PANGO_STYLE_OBLIQUE;
if (!strcmp(str, "italic"))
return PANGO_STYLE_ITALIC;
else if (!strcmp(str, "inherit"))
return inherit;
}
return PANGO_STYLE_NORMAL;
}
PangoVariant
rsvg_css_parse_font_variant (const char * str, PangoVariant inherit)
{
if (str)
{
if (!strcmp(str, "small-caps"))
return PANGO_VARIANT_SMALL_CAPS;
else if (!strcmp(str, "inherit"))
return inherit;
}
return PANGO_VARIANT_NORMAL;
}
PangoWeight
rsvg_css_parse_font_weight (const char * str, PangoWeight inherit)
{
if (str)
{
if (!strcmp (str, "lighter"))
return PANGO_WEIGHT_LIGHT;
else if (!strcmp (str, "bold"))
return PANGO_WEIGHT_BOLD;
else if (!strcmp (str, "bolder"))
return PANGO_WEIGHT_ULTRABOLD;
else if (!strcmp (str, "100"))
return (PangoWeight)100;
else if (!strcmp (str, "200"))
return (PangoWeight)200;
else if (!strcmp (str, "300"))
return (PangoWeight)300;
else if (!strcmp (str, "400"))
return (PangoWeight)400;
else if (!strcmp (str, "500"))
return (PangoWeight)500;
else if (!strcmp (str, "600"))
return (PangoWeight)600;
else if (!strcmp (str, "700"))
return (PangoWeight)700;
else if (!strcmp (str, "800"))
return (PangoWeight)800;
else if (!strcmp (str, "900"))
return (PangoWeight)900;
else if (!strcmp(str, "inherit"))
return inherit;
}
return PANGO_WEIGHT_NORMAL;
}
PangoStretch
rsvg_css_parse_font_stretch (const char * str, PangoStretch inherit)
{
if (str)
{
/* TODO: wider | narrower */
if (!strcmp (str, "ultra-condensed"))
return PANGO_STRETCH_ULTRA_CONDENSED;
else if (!strcmp (str, "extra-condensed"))
return PANGO_STRETCH_EXTRA_CONDENSED;
else if (!strcmp (str, "condensed"))
return PANGO_STRETCH_CONDENSED;
else if (!strcmp (str, "semi-condensed"))
return PANGO_STRETCH_SEMI_CONDENSED;
else if (!strcmp (str, "semi-expanded"))
return PANGO_STRETCH_SEMI_EXPANDED;
else if (!strcmp (str, "expanded"))
return PANGO_STRETCH_EXPANDED;
else if (!strcmp (str, "extra-expanded"))
return PANGO_STRETCH_EXTRA_EXPANDED;
else if (!strcmp (str, "ultra-expanded"))
return PANGO_STRETCH_ULTRA_EXPANDED;
else if (!strcmp(str, "inherit"))
return inherit;
}
return PANGO_STRETCH_NORMAL;
}
const char *
rsvg_css_parse_font_family (const char * str, const char * inherit)
{
if (!str)
return NULL;
if (!strcmp (str, "inherit"))
return inherit;
else
return str;
}
#include <glib/gtypes.h>
#include <pango/pangoft2.h>
double
rsvg_css_parse_length (const char *str, gdouble pixels_per_inch,
......@@ -20,3 +21,27 @@ rsvg_css_parse_color (const char *str);
guint
rsvg_css_parse_opacity (const char *str);
double
rsvg_css_parse_angle (const char * str);
double
rsvg_css_parse_frequency (const char * str);
double
rsvg_css_parse_time (const char * str);
PangoStyle
rsvg_css_parse_font_style (const char * str, PangoStyle inherit);
PangoVariant
rsvg_css_parse_font_variant (const char * str, PangoVariant inherit);
PangoWeight
rsvg_css_parse_font_weight (const char * str, PangoWeight inherit);
PangoStretch
rsvg_css_parse_font_stretch (const char * str, PangoStretch inherit);
const char *
rsvg_css_parse_font_family (const char * str, const char * inherit);
......@@ -60,6 +60,9 @@
/* 4/3 * (1-cos 45ƒ)/sin 45ƒ = 4/3 * sqrt(2) - 1 */
#define RSVG_ARC_MAGIC ((double) 0.5522847498)
/* Our default font */
#define DEFAULT_FONT "Times Roman"
/*
* This is configurable at runtime
*/
......@@ -82,8 +85,13 @@ typedef struct {
ArtPathStrokeCapType cap;
ArtPathStrokeJoinType join;
double font_size;
char *font_family;
double font_size;
char *font_family;
PangoStyle font_style;
PangoVariant font_variant;
PangoWeight font_weight;
PangoStretch font_stretch;
guint text_offset;
guint32 stop_color; /* rgb */
......@@ -156,6 +164,13 @@ rsvg_state_init (RsvgState *state)
state->cap = ART_PATH_STROKE_CAP_BUTT;
state->join = ART_PATH_STROKE_JOIN_MITER;
state->stop_opacity = 0xff;
state->font_family = g_strdup (DEFAULT_FONT);
state->font_size = 12.0;
state->font_style = PANGO_STYLE_NORMAL;
state->font_variant = PANGO_VARIANT_NORMAL;
state->font_weight = PANGO_WEIGHT_NORMAL;
state->font_stretch = PANGO_STRETCH_NORMAL;
}
static void
......@@ -413,8 +428,25 @@ rsvg_parse_style_arg (RsvgHandle *ctx, RsvgState *state, const char *str)
}
else if (rsvg_css_param_match (str, "font-family"))
{
char * save = g_strdup (rsvg_css_parse_font_family (str + arg_off, state->font_family));
g_free (state->font_family);
state->font_family = g_strdup (str + arg_off);
state->font_family = save;
}
else if (rsvg_css_param_match (str, "font-style"))
{
state->font_style = rsvg_css_parse_font_style (str + arg_off, state->font_style);
}
else if (rsvg_css_param_match (str, "font-variant"))
{
state->font_variant = rsvg_css_parse_font_variant (str + arg_off, state->font_variant);
}
else if (rsvg_css_param_match (str, "font-weight"))
{
state->font_weight = rsvg_css_parse_font_weight (str + arg_off, state->font_weight);
}
else if (rsvg_css_param_match (str, "font-stretch"))
{
state->font_stretch = rsvg_css_parse_font_stretch (str + arg_off, state->font_stretch);
}
else if (rsvg_css_param_match (str, "stop-color"))
{
......@@ -495,6 +527,10 @@ rsvg_is_style_arg(const char *str)
g_hash_table_insert (styles, "fill-opacity", GINT_TO_POINTER (TRUE));
g_hash_table_insert (styles, "font-family", GINT_TO_POINTER (TRUE));
g_hash_table_insert (styles, "font-size", GINT_TO_POINTER (TRUE));
g_hash_table_insert (styles, "font-stretch", GINT_TO_POINTER (TRUE));
g_hash_table_insert (styles, "font-style", GINT_TO_POINTER (TRUE));
g_hash_table_insert (styles, "font-variant", GINT_TO_POINTER (TRUE));
g_hash_table_insert (styles, "font-weight", GINT_TO_POINTER (TRUE));
g_hash_table_insert (styles, "opacity", GINT_TO_POINTER (TRUE));
g_hash_table_insert (styles, "stop-color", GINT_TO_POINTER (TRUE));
g_hash_table_insert (styles, "stop-opacity", GINT_TO_POINTER (TRUE));
......@@ -1356,12 +1392,19 @@ rsvg_text_handler_characters (RsvgSaxHandler *self, const xmlChar *ch, int len)
layout = pango_layout_new (ctx->pango_context);
pango_layout_set_text (layout, string, end - beg);
font = pango_font_description_copy (pango_context_get_font_description (ctx->pango_context));
if (state->font_family)
pango_font_description_set_family_static (font, state->font_family);
/* we need to resize the font by our X or Y scale (ideally could stretch in both directions...)
which, though? Y for now */
pango_font_description_set_size (font, state->font_size * PANGO_SCALE * state->affine[3]);
if (state->font_family)
pango_font_description_set_family_static (font, state->font_family);
pango_font_description_set_style (font, state->font_style);
pango_font_description_set_variant (font, state->font_variant);
pango_font_description_set_weight (font, state->font_weight);
pango_font_description_set_stretch (font, state->font_stretch);
pango_layout_set_font_description (layout, font);
pango_font_description_free (font);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment