summaryrefslogtreecommitdiffstats
path: root/src/style.cpp
diff options
context:
space:
mode:
authorTavmjong Bah <tavmjong@free.fr>2014-02-18 20:36:32 +0000
committertavmjong-free <tavmjong@free.fr>2014-02-18 20:36:32 +0000
commitd1e1659004e194e8fdae47bf03f08cea96ab7bd9 (patch)
tree14f7f32c00d2cd6da3a7d3827008ae168cbedf20 /src/style.cpp
parentextensions. Render Gear. improve precision of output (Bug 1240455) (diff)
downloadinkscape-d1e1659004e194e8fdae47bf03f08cea96ab7bd9.tar.gz
inkscape-d1e1659004e194e8fdae47bf03f08cea96ab7bd9.zip
Read new SVG2 property 'paint-order'.
(bzr r13037)
Diffstat (limited to 'src/style.cpp')
-rw-r--r--src/style.cpp199
1 files changed, 199 insertions, 0 deletions
diff --git a/src/style.cpp b/src/style.cpp
index bb5603f1c..7ad9749f0 100644
--- a/src/style.cpp
+++ b/src/style.cpp
@@ -90,6 +90,8 @@ static void sp_style_read_istring(SPIString *val, gchar const *str);
static void sp_style_read_ilength(SPILength *val, gchar const *str);
static void sp_style_read_ilengthornormal(SPILengthOrNormal *val, gchar const *str);
+static void sp_style_read_ipaintorder(SPIPaintOrder *val, gchar const *str);
+
static void sp_style_read_itextdecoration(SPITextDecorationLine *line, SPITextDecorationStyle *style, SPIPaint *color, gchar const *str);
static void sp_style_read_itextdecorationLine(SPITextDecorationLine *line, gchar const *str);
static void sp_style_read_itextdecorationStyle(SPITextDecorationStyle *style, gchar const *str);
@@ -112,6 +114,8 @@ static gint sp_style_write_ienum(gchar *p, gint len, gchar const *key, SPStyleEn
static gint sp_style_write_istring(gchar *p, gint len, gchar const *key, SPIString const *val, SPIString const *base, guint flags);
static gint sp_style_write_ilength(gchar *p, gint len, gchar const *key, SPILength const *val, SPILength const *base, guint flags);
static gint sp_style_write_ipaint(gchar *b, gint len, gchar const *key, SPIPaint const *paint, SPIPaint const *base, guint flags);
+static gint sp_style_write_ipaintorder(gchar *p, gint len, gchar const *key, SPIPaintOrder const *paint_order, SPIPaintOrder const *base, guint flags);
+
static gint sp_style_write_ifontsize(gchar *p, gint len, gchar const *key, SPIFontSize const *val, SPIFontSize const *base, guint flags);
static gint sp_style_write_ibaselineshift(gchar *p, gint len, gchar const *key, SPIBaselineShift const *val, SPIBaselineShift const *base, guint flags);
static gint sp_style_write_ilengthornormal(gchar *p, gint const len, gchar const *const key, SPILengthOrNormal const *const val, SPILengthOrNormal const *const base, guint const flags);
@@ -666,6 +670,8 @@ sp_style_read(SPStyle *style, SPObject *object, Inkscape::XML::Node *repr)
}
/* 2. Presentation attributes */
+ /* Attributes are only read in if not already set in a style sheet or style attribute above. */
+
/* CSS2 */
SPS_READ_PENUM_IF_UNSET(&style->visibility, repr, "visibility", enum_visibility, true);
SPS_READ_PENUM_IF_UNSET(&style->display, repr, "display", enum_display, true);
@@ -819,6 +825,16 @@ sp_style_read(SPStyle *style, SPObject *object, Inkscape::XML::Node *repr)
}
}
+ /* paint-order */
+ if (!style->paint_order.set) {
+ val = repr->attribute("paint-order");
+ if (val) {
+ sp_style_read_ipaintorder(&style->paint_order, val);
+ } else {
+ style->paint_order.layer[0] = SP_CSS_PAINT_ORDER_NORMAL;
+ }
+ }
+
/* -inkscape-font-specification */
if (!style->text_private || !style->text->font_specification.set) {
val = repr->attribute("-inkscape-font-specification");
@@ -1435,6 +1451,11 @@ sp_style_merge_property(SPStyle *style, gint id, gchar const *val)
sp_style_read_iscale24(&style->stroke_opacity, val);
}
break;
+ case SP_PROP_PAINT_ORDER:
+ if (!style->paint_order.set) {
+ sp_style_read_ipaintorder(&style->paint_order, val);
+ }
+ break;
default:
g_warning("Invalid style property id: %d value: %s", id, val);
@@ -1889,6 +1910,15 @@ sp_style_merge_from_parent(SPStyle *const style, SPStyle const *const parent)
style->stroke_opacity.value = parent->stroke_opacity.value;
}
+ if (!style->paint_order.set || style->paint_order.inherit) {
+ g_free(style->paint_order.value);
+ style->paint_order.value = g_strdup(parent->paint_order.value);
+ for (unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i) {
+ style->paint_order.layer[i] = parent->paint_order.layer[i];
+ style->paint_order.layer_set[i] = parent->paint_order.layer_set[i];
+ }
+ }
+
if (style->text && parent->text) {
if (!style->text->font_family.set || style->text->font_family.inherit) {
g_free(style->text->font_family.value);
@@ -2802,6 +2832,12 @@ sp_style_write_string(SPStyle const *const style, guint const flags)
}
}
+ if (style->paint_order.set) {
+ p += sp_style_write_ipaintorder(p, c + BMAX - p, "paint-order", &style->paint_order, NULL, flags);
+ } else if (flags == SP_STYLE_FLAG_ALWAYS) {
+ p += g_snprintf(p, c + BMAX - p, "paint-order:normal;");
+ }
+
bool marker_none = false;
gchar *master = style->marker[SP_MARKER_LOC].value;
if (style->marker[SP_MARKER_LOC].set) {
@@ -2974,6 +3010,11 @@ sp_style_write_difference(SPStyle const *const from, SPStyle const *const to)
p += sp_style_write_iscale24(p, c + BMAX - p, "stroke-opacity", &from->stroke_opacity, &to->stroke_opacity, SP_STYLE_FLAG_IFDIFF);
}
+ /* paint-order */
+ if( from->paint_order.set) {
+ p += sp_style_write_ipaintorder(p, c + BMAX - p, "paint-order", &from->paint_order, &to->paint_order, SP_STYLE_FLAG_IFDIFF);
+ }
+
/* markers */
gchar *master = from->marker[SP_MARKER_LOC].value;
if (master != NULL) {
@@ -3277,6 +3318,15 @@ sp_style_clear(SPStyle *style)
style->marker[i].value = NULL;
}
+ /* SVG 2 */
+ style->paint_order.set = FALSE;
+ style->paint_order.inherit = FALSE; // For now
+ for (unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i) {
+ style->paint_order.layer[i] = SP_CSS_PAINT_ORDER_NORMAL;
+ style->paint_order.layer_set[i] = false;
+ }
+ style->paint_order.value = NULL;
+
style->filter.set = FALSE;
style->filter.inherit = FALSE;
style->filter.href = NULL;
@@ -3645,6 +3695,77 @@ sp_style_read_ilengthornormal(SPILengthOrNormal *val, gchar const *str)
}
/**
+ * Set SPIPaintOrder object from string.
+ */
+static void
+sp_style_read_ipaintorder(SPIPaintOrder *val, gchar const *str)
+{
+ g_free(val->value);
+
+ if (!strcmp(str, "inherit")) {
+ // NEED TO CHECK FINAL SPEC
+ val->set = TRUE;
+ val->inherit = TRUE;
+ val->value = NULL;
+ } else {
+ val->set = TRUE;
+ val->inherit = FALSE;
+ val->value = g_strdup(str);
+
+ if (!strcmp(str, "normal")) {
+ val->layer[0] = SP_CSS_PAINT_ORDER_NORMAL;
+ val->layer_set[0] = true;
+ } else {
+ // This certainly can be done more efficiently
+ gchar** c = g_strsplit(str, " ", PAINT_ORDER_LAYERS + 1);
+ bool used[3] = {false, false, false};
+ unsigned int i = 0;
+ for( ; i < PAINT_ORDER_LAYERS; ++i ) {
+ if( c[i] ) {
+ val->layer_set[i] = false;
+ if( !strcmp( c[i], "fill")) {
+ val->layer[i] = SP_CSS_PAINT_ORDER_FILL;
+ val->layer_set[i] = true;
+ used[0] = true;
+ } else if( !strcmp( c[i], "stroke")) {
+ val->layer[i] = SP_CSS_PAINT_ORDER_STROKE;
+ val->layer_set[i] = true;
+ used[1] = true;
+ } else if( !strcmp( c[i], "marker")) {
+ val->layer[i] = SP_CSS_PAINT_ORDER_MARKER;
+ val->layer_set[i] = true;
+ used[2] = true;
+ } else {
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ g_strfreev(c);
+
+ // Fill out rest of the layers using the default order
+ if( !used[0] && i < PAINT_ORDER_LAYERS ) {
+ val->layer[i] = SP_CSS_PAINT_ORDER_FILL;
+ val->layer_set[i] = false;
+ ++i;
+ }
+ if( !used[1] && i < PAINT_ORDER_LAYERS ) {
+ val->layer[i] = SP_CSS_PAINT_ORDER_STROKE;
+ val->layer_set[i] = false;
+ ++i;
+ }
+ if( !used[2] && i < PAINT_ORDER_LAYERS ) {
+ val->layer[i] = SP_CSS_PAINT_ORDER_MARKER;
+ val->layer_set[i] = false;
+ }
+ }
+ }
+}
+
+
+
+/**
* Set SPITextDecoration object from string.
*/
static void
@@ -4557,6 +4678,81 @@ sp_style_write_ipaint(gchar *b, gint const len, gchar const *const key,
*
*/
static bool
+sp_paint_order_differ(SPIPaintOrder const *const a, SPIPaintOrder const *const b)
+{
+ if( (a->set != b->set) ||
+ (a->inherit!= b->inherit) ) {
+ return true;
+ }
+
+ // Check this works when paint-order value is 'normal'
+ for (unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i ) {
+ if( (a->layer[i] != b->layer[i]) ||
+ (a->layer_set[i] != b->layer_set[i]) ) {
+ return true;
+ }
+ }
+ return false;
+}
+
+
+
+/**
+ * Write SPIPaintOrder object into string.
+ */
+static gint
+sp_style_write_ipaintorder(gchar *p, gint len, gchar const *key, SPIPaintOrder const *paint_order, SPIPaintOrder const *base, guint flags)
+{
+ int retval = 0;
+
+ if ((flags & SP_STYLE_FLAG_ALWAYS)
+ || ((flags & SP_STYLE_FLAG_IFSET) && paint_order->set)
+ || ((flags & SP_STYLE_FLAG_IFDIFF) && paint_order->set
+ && (!base->set || sp_paint_order_differ(paint_order, base))))
+ {
+ CSSOStringStream css;
+
+ if (paint_order->inherit) {
+ css << "inherit";
+ } else {
+ for( unsigned i = 0; i < PAINT_ORDER_LAYERS; ++i ) {
+ if( paint_order->layer_set[i] == true ) {
+ switch (paint_order->layer[i]) {
+ case SP_CSS_PAINT_ORDER_NORMAL:
+ css << "normal";
+ assert( i == 0 );
+ break;
+ case SP_CSS_PAINT_ORDER_FILL:
+ if (i!=0) css << " ";
+ css << "fill";
+ break;
+ case SP_CSS_PAINT_ORDER_STROKE:
+ if (i!=0) css << " ";
+ css << "stroke";
+ break;
+ case SP_CSS_PAINT_ORDER_MARKER:
+ if (i!=0) css << " ";
+ css << "marker";
+ break;
+ }
+ } else {
+ break;
+ }
+ }
+ }
+
+ if ( !css.str().empty() ) {
+ retval = g_snprintf( p, len, "%s:%s;", key, css.str().c_str() );
+ }
+ }
+
+ return retval;
+}
+
+/**
+ *
+ */
+static bool
sp_fontsize_differ(SPIFontSize const *const a, SPIFontSize const *const b)
{
if (a->type != b->type)
@@ -4842,6 +5038,9 @@ sp_style_unset_property_attrs(SPObject *o)
if (style->stroke_dashoffset_set) {
repr->setAttribute("stroke-dashoffset", NULL);
}
+ if (style->paint_order.set) {
+ repr->setAttribute("paint-order", NULL);
+ }
if (style->text_private && style->text->font_specification.set) {
repr->setAttribute("-inkscape-font-specification", NULL);
}