[gnumeric] xlsx: apply colour modifiers when reading theme.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] xlsx: apply colour modifiers when reading theme.
- Date: Wed, 1 Apr 2015 01:50:58 +0000 (UTC)
commit 280a4f768c8e953d12da392f49bc609d3377a883
Author: Morten Welinder <terra gnome org>
Date: Tue Mar 31 21:50:39 2015 -0400
xlsx: apply colour modifiers when reading theme.
NEWS | 1 +
plugins/excel/ChangeLog | 10 +-
plugins/excel/Makefile.am | 1 +
plugins/excel/xlsx-read-color.c | 327 +++++++++++++++++++++++++++++++++++++
plugins/excel/xlsx-read-drawing.c | 209 -----------------------
plugins/excel/xlsx-read.c | 145 ++++-------------
6 files changed, 370 insertions(+), 323 deletions(-)
---
diff --git a/NEWS b/NEWS
index a89be5e..d5ffba2 100644
--- a/NEWS
+++ b/NEWS
@@ -22,6 +22,7 @@ Morten:
* Fix RANDLOG.
* Fix RANDGEOM to use same distribution as R.DGEOM.
* Improve xlsx roundtrip of GOStyle.
+ * Improve reading of xlsx theme colours.
--------------------------------------------------------------------------
Gnumeric 1.12.21
diff --git a/plugins/excel/ChangeLog b/plugins/excel/ChangeLog
index d419312..18db0b4 100644
--- a/plugins/excel/ChangeLog
+++ b/plugins/excel/ChangeLog
@@ -1,3 +1,11 @@
+2015-03-31 Morten Welinder <terra gnome org>
+
+ * xlsx-read-color.c: New file extracted from xlsx-read-drawing.c
+ and xlsx-read.c
+ (xlsx_draw_color_hsl_channel): Implement.
+
+ * xlsx-read.c (theme): Apply colour modifications.
+
2015-03-30 Morten Welinder <terra gnome org>
* xlsx-read-drawing.c (xlsx_draw_color_rgba_channel): Rename from
@@ -187,7 +195,7 @@
* xlsx-read-drawing.c (xlsx_chart_line_headtail): Improve arrow
import with xls_arrow_from_xl.
- * ms-excel-util.c (xls_arrow_from_xl): New function extrated...
+ * ms-excel-util.c (xls_arrow_from_xl): New function extracted...
* ms-excel-read.c (handle_arrow_head): ...from here.
* xlsx-write-drawing.c (xlsx_write_go_style_full): Improve arrow
diff --git a/plugins/excel/Makefile.am b/plugins/excel/Makefile.am
index aa41bc0..53229e3 100644
--- a/plugins/excel/Makefile.am
+++ b/plugins/excel/Makefile.am
@@ -83,6 +83,7 @@ EXTRA_DIST = $(xml_in_files) \
xlsx-write-docprops.c \
xlsx-read-pivot.c \
xlsx-write-pivot.c \
+ xlsx-read-color.c \
xlsx-read-drawing.c \
xlsx-write-drawing.c
diff --git a/plugins/excel/xlsx-read-color.c b/plugins/excel/xlsx-read-color.c
new file mode 100644
index 0000000..7ac7a37
--- /dev/null
+++ b/plugins/excel/xlsx-read-color.c
@@ -0,0 +1,327 @@
+
+/* RGBMAX, HSLMAX must each fit in a byte. */
+/* HSLMAX BEST IF DIVISIBLE BY 6 */
+#define HSLMAX 240 /* H,L, and S vary over 0-HSLMAX */
+#define RGBMAX 255 /* R,G, and B vary over 0-RGBMAX */
+
+/* Hue is undefined if Saturation is 0 (grey-scale) */
+/* This value determines where the Hue scrollbar is */
+/* initially set for achromatic colors */
+//#define UNDEFINED (HSLMAX*2/3)
+
+/* utility routine for HSLtoRGB */
+static int
+hue_to_color (int m1, int m2, int h)
+{
+ if (h < 0)
+ h += HSLMAX;
+ if (h > HSLMAX)
+ h -= HSLMAX;
+
+ /* return r,g, or b value from this tridrant */
+ if (h < HSLMAX / 6)
+ return m1 + (((m2 - m1) * h + HSLMAX / 12) / (HSLMAX / 6));
+ if (h < HSLMAX / 2)
+ return m2;
+ if (h < HSLMAX * 2 /3)
+ return m1 + ((m2 - m1) * ((HSLMAX * 2 / 3 - h) + HSLMAX / 12) / (HSLMAX / 6));
+
+ return m1;
+}
+
+static GOColor
+gnm_go_color_from_hsla (int h, int s, int l, int a)
+{
+ int m2 = (l <= HSLMAX / 2)
+ ? (l * (HSLMAX + s) + HSLMAX / 2) / HSLMAX
+ : l + s - (l * s + HSLMAX / 2) / HSLMAX;
+ int m1 = 2 * l - m2;
+ guint8 r = (hue_to_color (m1, m2, h + HSLMAX / 3) * RGBMAX + HSLMAX / 2) / HSLMAX;
+ guint8 g = (hue_to_color (m1, m2, h ) * RGBMAX + HSLMAX / 2) / HSLMAX;
+ guint8 b = (hue_to_color (m1, m2, h - HSLMAX / 3) * RGBMAX + HSLMAX / 2) / HSLMAX;
+
+ return GO_COLOR_FROM_RGBA (r,g,b,a);
+}
+
+static void
+gnm_go_color_to_hsla (GOColor orig, int *ph, int *ps, int *pl, int *pa)
+{
+ int r = GO_COLOR_UINT_R (orig);
+ int g = GO_COLOR_UINT_G (orig);
+ int b = GO_COLOR_UINT_B (orig);
+ int a = GO_COLOR_UINT_A (orig);
+ int maxC = b, minC = b, delta, sum, h = 0, l, s;
+
+ maxC = MAX (MAX (r,g),b);
+ minC = MIN (MIN (r,g),b);
+ l = (((maxC + minC)*HSLMAX) + RGBMAX)/(2*RGBMAX);
+
+ delta = maxC - minC;
+ sum = maxC + minC;
+ if (delta != 0) {
+ if (l <= (HSLMAX/2))
+ s = ( (delta*HSLMAX) + (sum/2) ) / sum;
+ else
+ s = ( (delta*HSLMAX) + ((2*RGBMAX - sum)/2) ) / (2*RGBMAX - sum);
+
+ if (r == maxC)
+ h = ((g - b) * HSLMAX) / (6 * delta);
+ else if (g == maxC)
+ h = ( HSLMAX/3) + ((b - r) * HSLMAX) / (6 * delta);
+ else if (b == maxC)
+ h = (2*HSLMAX/3) + ((r - g) * HSLMAX) / (6 * delta);
+
+ if (h < 0)
+ h += HSLMAX;
+ else if (h >= HSLMAX)
+ h -= HSLMAX;
+ } else {
+ h = 0;
+ s = 0;
+ }
+
+ *ph = h;
+ *ps = s;
+ *pl = l;
+ *pa = a;
+}
+
+/*
+ * Apply tinting or shading.
+ * 0 <= tint <= 1: tinting -- l is increased
+ * -1 <= tint <= 0: shading -- l is decreased
+ */
+
+static GOColor
+gnm_go_color_apply_tint (GOColor orig, double tint)
+{
+ int h, s, l, a;
+
+ if (fabs (tint) < .005)
+ return orig;
+
+ gnm_go_color_to_hsla (orig, &h, &s, &l, &a);
+
+ tint = CLAMP (tint, -1.0, +1.0);
+
+ if (tint < 0.)
+ l = l * (1. + tint);
+ else
+ l = l * (1. - tint) + (HSLMAX - HSLMAX * (1.0 - tint));
+
+ if (s == 0) { /* achromatic case */
+ int g = (l * RGBMAX) / HSLMAX;
+ return GO_COLOR_FROM_RGBA (g, g, g, a);
+ }
+
+ return gnm_go_color_from_hsla (h, s, l, a);
+}
+
+typedef enum {
+ XLSX_CS_NONE = 0,
+ XLSX_CS_FONT = 1,
+ XLSX_CS_LINE = 2,
+ XLSX_CS_FILL_BACK = 3,
+ XLSX_CS_FILL_FORE = 4,
+ XLSX_CS_MARKER = 5,
+ XLSX_CS_MARKER_OUTLINE = 6,
+ XLSX_CS_ANY = 7 /* for pop */
+} XLSXColorState;
+
+static void
+color_set_helper (XLSXReadState *state)
+{
+#ifdef DEBUG_COLOR
+ g_printerr ("color: #%08x in state %d\n",
+ state->color, state->chart_color_state & 7);
+#endif
+
+ switch (state->chart_color_state & 7) {
+ default:
+ case XLSX_CS_NONE:
+ break;
+ case XLSX_CS_FONT:
+ state->cur_style->font.color = state->color;
+ state->cur_style->font.auto_color = FALSE;
+ break;
+ case XLSX_CS_LINE:
+ state->cur_style->line.color = state->color;
+ state->cur_style->line.auto_color = FALSE;
+ break;
+ case XLSX_CS_FILL_BACK:
+ state->cur_style->fill.pattern.back = state->color;
+ state->cur_style->fill.auto_back = FALSE;
+ break;
+ case XLSX_CS_FILL_FORE:
+ state->cur_style->fill.pattern.fore = state->color;
+ state->cur_style->fill.auto_fore = FALSE;
+ break;
+ case XLSX_CS_MARKER:
+ go_marker_set_fill_color (state->marker, state->color);
+ state->cur_style->marker.auto_fill_color = FALSE;
+ break;
+ case XLSX_CS_MARKER_OUTLINE:
+ go_marker_set_outline_color (state->marker, state->color);
+ state->cur_style->marker.auto_outline_color = FALSE;
+ break;
+ }
+}
+
+static void
+xlsx_draw_color_rgba_channel (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ XLSXReadState *state = (XLSXReadState *)xin->user_state;
+ guint action = xin->node->user_data.v_int & 3;
+ guint channel = xin->node->user_data.v_int >> 2; /* a=3, r=2, g=1, b=0 */
+ int val;
+ if (simple_int (xin, attrs, &val)) {
+ const double f = val / 100000.0;
+ int v;
+ double vf;
+
+ switch (channel) {
+ case 3: v = GO_COLOR_UINT_A (state->color); break;
+ case 2: v = GO_COLOR_UINT_R (state->color); break;
+ case 1: v = GO_COLOR_UINT_G (state->color); break;
+ case 0: v = GO_COLOR_UINT_B (state->color); break;
+ default: g_assert_not_reached ();
+ }
+ switch (action) {
+ case 0: vf = 256 * f; break;
+ case 1: vf = v + 256 * f; break;
+ case 2: vf = v * f; break;
+ default: g_assert_not_reached ();
+ }
+ v = CLAMP (vf, 0, 255);
+ switch (channel) {
+ case 3: state->color = GO_COLOR_CHANGE_A (state->color, v); break;
+ case 2: state->color = GO_COLOR_CHANGE_R (state->color, v); break;
+ case 1: state->color = GO_COLOR_CHANGE_G (state->color, v); break;
+ case 0: state->color = GO_COLOR_CHANGE_B (state->color, v); break;
+ default: g_assert_not_reached ();
+ }
+ color_set_helper (state);
+ }
+}
+
+static void
+xlsx_draw_color_gray (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ XLSXReadState *state = (XLSXReadState *)xin->user_state;
+ int g = (22 * GO_COLOR_UINT_R (state->color) +
+ 72 * GO_COLOR_UINT_G (state->color) +
+ 06 * GO_COLOR_UINT_B (state->color)) / 100;
+ state->color = GO_COLOR_GREY (g);
+ color_set_helper (state);
+}
+
+static void
+xlsx_draw_color_comp (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ XLSXReadState *state = (XLSXReadState *)xin->user_state;
+ g_warning ("Unhandled hsl complement of #%08x\n", state->color);
+}
+
+static void
+xlsx_draw_color_invert (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ XLSXReadState *state = (XLSXReadState *)xin->user_state;
+ state->color = GO_COLOR_FROM_RGBA (0xff, 0xff, 0xff, 0) ^ state->color;
+ color_set_helper (state);
+}
+
+static void
+xlsx_draw_color_hsl_channel (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ XLSXReadState *state = (XLSXReadState *)xin->user_state;
+ guint action = xin->node->user_data.v_int & 3;
+ guint channel = xin->node->user_data.v_int >> 2; /* hue=2, sat=1, lum=0 */
+ int val;
+ if (simple_int (xin, attrs, &val)) {
+ const double f = val / 100000.0;
+ int hsl[3], a, v;
+ double vf;
+
+ gnm_go_color_to_hsla (state->color, &hsl[2], &hsl[1], &hsl[0], &a);
+ v = hsl[channel];
+
+ switch (action) {
+ case 0: vf = (HSLMAX + 1) * f; break;
+ case 1: vf = v + (HSLMAX + 1) * f; break;
+ case 2: vf = v * f; break;
+ default: g_assert_not_reached ();
+ }
+
+ hsl[channel] = CLAMP (vf, 0, HSLMAX);
+ state->color = gnm_go_color_from_hsla (hsl[2], hsl[1], hsl[0], a);
+ }
+}
+
+static void
+xlsx_draw_color_gamma (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ XLSXReadState *state = (XLSXReadState *)xin->user_state;
+ gboolean inv = xin->node->user_data.v_int;
+ g_warning ("Unhandled colour %d gamma transformation of #%08x\n", inv, state->color);
+}
+
+
+static void
+xlsx_draw_color_shade (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ XLSXReadState *state = (XLSXReadState *)xin->user_state;
+ unsigned val;
+ if (simple_uint (xin, attrs, &val)) {
+ const double scale = 100000;
+ double f = val / scale;
+ state->color = gnm_go_color_apply_tint (state->color, -f);
+ color_set_helper (state);
+ }
+}
+
+static void
+xlsx_draw_color_tint (GsfXMLIn *xin, xmlChar const **attrs)
+{
+ XLSXReadState *state = (XLSXReadState *)xin->user_state;
+ unsigned val;
+ if (simple_uint (xin, attrs, &val)) {
+ const double scale = 100000;
+ double f = val / scale;
+ state->color = gnm_go_color_apply_tint (state->color, f);
+ color_set_helper (state);
+ }
+}
+
+
+#define COLOR_MODIFIER_NODE(parent,node,name,first,handler,user) \
+ GSF_XML_IN_NODE_FULL (parent, node, XL_NS_DRAW, name, (first ? GSF_XML_NO_CONTENT : GSF_XML_2ND),
FALSE, FALSE, handler, NULL, user)
+
+#define COLOR_MODIFIER_NODES(parent,first) \
+ COLOR_MODIFIER_NODE(parent, COLOR_SHADE, "shade", first, &xlsx_draw_color_shade, 0), \
+ COLOR_MODIFIER_NODE(parent, COLOR_TINT, "tint", first, &xlsx_draw_color_tint, 0), \
+ COLOR_MODIFIER_NODE(parent, COLOR_COMP, "comp", first, &xlsx_draw_color_comp, 0), \
+ COLOR_MODIFIER_NODE(parent, COLOR_INV, "inv", first, &xlsx_draw_color_invert, 0), \
+ COLOR_MODIFIER_NODE(parent, COLOR_GRAY, "gray", first, &xlsx_draw_color_gray, 0), \
+ COLOR_MODIFIER_NODE(parent, COLOR_ALPHA, "alpha", first, &xlsx_draw_color_rgba_channel, 12), \
+ COLOR_MODIFIER_NODE(parent, COLOR_ALPHA_OFF, "alphaOff", first, &xlsx_draw_color_rgba_channel, 13), \
+ COLOR_MODIFIER_NODE(parent, COLOR_ALPHA_MOD, "alphaMod", first, &xlsx_draw_color_rgba_channel, 14), \
+ COLOR_MODIFIER_NODE(parent, COLOR_HUE, "hue", first, xlsx_draw_color_hsl_channel, 8), \
+ COLOR_MODIFIER_NODE(parent, COLOR_HUE_OFF, "hueOff", first, xlsx_draw_color_hsl_channel, 9), \
+ COLOR_MODIFIER_NODE(parent, COLOR_HUE_MOD, "hueMod", first, xlsx_draw_color_hsl_channel, 10), \
+ COLOR_MODIFIER_NODE(parent, COLOR_SAT, "sat", first, xlsx_draw_color_hsl_channel, 4), \
+ COLOR_MODIFIER_NODE(parent, COLOR_SAT_OFF, "satOff", first, xlsx_draw_color_hsl_channel, 5), \
+ COLOR_MODIFIER_NODE(parent, COLOR_SAT_MOD, "satMod", first, xlsx_draw_color_hsl_channel, 6), \
+ COLOR_MODIFIER_NODE(parent, COLOR_LUM, "lum", first, xlsx_draw_color_hsl_channel, 0), \
+ COLOR_MODIFIER_NODE(parent, COLOR_LUM_OFF, "lumOff", first, xlsx_draw_color_hsl_channel, 1), \
+ COLOR_MODIFIER_NODE(parent, COLOR_LUM_MOD, "lumMod", first, xlsx_draw_color_hsl_channel, 2), \
+ COLOR_MODIFIER_NODE(parent, COLOR_RED, "red", first, &xlsx_draw_color_rgba_channel, 8), \
+ COLOR_MODIFIER_NODE(parent, COLOR_RED_OFF, "redOff", first, &xlsx_draw_color_rgba_channel, 9), \
+ COLOR_MODIFIER_NODE(parent, COLOR_RED_MOD, "redMod", first, &xlsx_draw_color_rgba_channel, 10), \
+ COLOR_MODIFIER_NODE(parent, COLOR_GREEN, "green", first, &xlsx_draw_color_rgba_channel, 4), \
+ COLOR_MODIFIER_NODE(parent, COLOR_GREEN_OFF, "greenOff", first, &xlsx_draw_color_rgba_channel, 5), \
+ COLOR_MODIFIER_NODE(parent, COLOR_GREEN_MOD, "greenMod", first, &xlsx_draw_color_rgba_channel, 6), \
+ COLOR_MODIFIER_NODE(parent, COLOR_BLUE, "blue", first, &xlsx_draw_color_rgba_channel, 0), \
+ COLOR_MODIFIER_NODE(parent, COLOR_BLUE_OFF, "blueOff", first, &xlsx_draw_color_rgba_channel, 1), \
+ COLOR_MODIFIER_NODE(parent, COLOR_BLUE_MOD, "blueMod", first, &xlsx_draw_color_rgba_channel, 2), \
+ COLOR_MODIFIER_NODE(parent, COLOR_GAMMA, "gamma", first, &xlsx_draw_color_gamma, 0), \
+ COLOR_MODIFIER_NODE(parent, COLOR_INV_GAMMA, "invGamma", first, &xlsx_draw_color_gamma, 1)
diff --git a/plugins/excel/xlsx-read-drawing.c b/plugins/excel/xlsx-read-drawing.c
index e17ca7d..3565271 100644
--- a/plugins/excel/xlsx-read-drawing.c
+++ b/plugins/excel/xlsx-read-drawing.c
@@ -93,18 +93,6 @@ xlsx_push_text_object (XLSXReadState *state, const char *name)
xlsx_chart_push_obj (state, label);
}
-
-typedef enum {
- XLSX_CS_NONE = 0,
- XLSX_CS_FONT = 1,
- XLSX_CS_LINE = 2,
- XLSX_CS_FILL_BACK = 3,
- XLSX_CS_FILL_FORE = 4,
- XLSX_CS_MARKER = 5,
- XLSX_CS_MARKER_OUTLINE = 6,
- XLSX_CS_ANY = 7 /* for pop */
-} XLSXColorState;
-
static void
xlsx_chart_push_color_state (XLSXReadState *state, XLSXColorState s)
{
@@ -446,45 +434,6 @@ xlsx_sppr_xfrm (GsfXMLIn *xin, xmlChar const **attrs)
}
static void
-color_set_helper (XLSXReadState *state)
-{
-#ifdef DEBUG_COLOR
- g_printerr ("color: #%08x in state %d\n",
- state->color, state->chart_color_state & 7);
-#endif
-
- switch (state->chart_color_state & 7) {
- default:
- case XLSX_CS_NONE:
- break;
- case XLSX_CS_FONT:
- state->cur_style->font.color = state->color;
- state->cur_style->font.auto_color = FALSE;
- break;
- case XLSX_CS_LINE:
- state->cur_style->line.color = state->color;
- state->cur_style->line.auto_color = FALSE;
- break;
- case XLSX_CS_FILL_BACK:
- state->cur_style->fill.pattern.back = state->color;
- state->cur_style->fill.auto_back = FALSE;
- break;
- case XLSX_CS_FILL_FORE:
- state->cur_style->fill.pattern.fore = state->color;
- state->cur_style->fill.auto_fore = FALSE;
- break;
- case XLSX_CS_MARKER:
- go_marker_set_fill_color (state->marker, state->color);
- state->cur_style->marker.auto_fill_color = FALSE;
- break;
- case XLSX_CS_MARKER_OUTLINE:
- go_marker_set_outline_color (state->marker, state->color);
- state->cur_style->marker.auto_outline_color = FALSE;
- break;
- }
-}
-
-static void
xlsx_draw_color_themed (GsfXMLIn *xin, xmlChar const **attrs)
{
#if 0
@@ -555,164 +504,6 @@ xlsx_draw_color_scrgb (GsfXMLIn *xin, xmlChar const **attrs)
color_set_helper (state);
}
-static void
-xlsx_draw_color_rgba_channel (GsfXMLIn *xin, xmlChar const **attrs)
-{
- XLSXReadState *state = (XLSXReadState *)xin->user_state;
- guint action = xin->node->user_data.v_int & 3;
- guint channel = xin->node->user_data.v_int >> 2; /* a=3, r=2, g=1, b=0 */
- int val;
- if (simple_int (xin, attrs, &val)) {
- const double f = val / 100000.0;
- int v;
- double vf;
-
- switch (channel) {
- case 3: v = GO_COLOR_UINT_A (state->color); break;
- case 2: v = GO_COLOR_UINT_R (state->color); break;
- case 1: v = GO_COLOR_UINT_G (state->color); break;
- case 0: v = GO_COLOR_UINT_B (state->color); break;
- default: g_assert_not_reached ();
- }
- switch (action) {
- case 0: vf = 256 * f; break;
- case 1: vf = v + 256 * f; break;
- case 2: vf = v * f; break;
- default: g_assert_not_reached ();
- }
- v = CLAMP (vf, 0, 255);
- switch (channel) {
- case 3: state->color = GO_COLOR_CHANGE_A (state->color, v); break;
- case 2: state->color = GO_COLOR_CHANGE_R (state->color, v); break;
- case 1: state->color = GO_COLOR_CHANGE_G (state->color, v); break;
- case 0: state->color = GO_COLOR_CHANGE_B (state->color, v); break;
- default: g_assert_not_reached ();
- }
- color_set_helper (state);
- }
-}
-
-static void
-xlsx_draw_color_gray (GsfXMLIn *xin, xmlChar const **attrs)
-{
- XLSXReadState *state = (XLSXReadState *)xin->user_state;
- int g = (22 * GO_COLOR_UINT_R (state->color) +
- 72 * GO_COLOR_UINT_G (state->color) +
- 06 * GO_COLOR_UINT_B (state->color)) / 100;
- state->color = GO_COLOR_GREY (g);
- color_set_helper (state);
-}
-
-static void
-xlsx_draw_color_comp (GsfXMLIn *xin, xmlChar const **attrs)
-{
- XLSXReadState *state = (XLSXReadState *)xin->user_state;
- g_warning ("Unhandled hsl complement of #%08x\n", state->color);
-}
-
-static void
-xlsx_draw_color_invert (GsfXMLIn *xin, xmlChar const **attrs)
-{
- XLSXReadState *state = (XLSXReadState *)xin->user_state;
- state->color = GO_COLOR_FROM_RGBA (0xff, 0xff, 0xff, 0) ^ state->color;
- color_set_helper (state);
-}
-
-static void
-xlsx_draw_color_hsl_channel (GsfXMLIn *xin, xmlChar const **attrs)
-{
- XLSXReadState *state = (XLSXReadState *)xin->user_state;
- guint action = xin->node->user_data.v_int & 3;
- guint channel = xin->node->user_data.v_int >> 2; /* hue=2, sat=1, lum=0 */
- int val;
- if (simple_int (xin, attrs, &val)) {
- g_warning ("Unhandling hsl colour modification %d %d for #%08x",
- action, channel, state->color);
- }
-}
-
-static void
-xlsx_draw_color_gamma (GsfXMLIn *xin, xmlChar const **attrs)
-{
- XLSXReadState *state = (XLSXReadState *)xin->user_state;
- gboolean inv = xin->node->user_data.v_int;
- g_warning ("Unhandled colour %d gamma transformation of #%08x\n", inv, state->color);
-}
-
-
-static void
-xlsx_draw_color_shade (GsfXMLIn *xin, xmlChar const **attrs)
-{
- XLSXReadState *state = (XLSXReadState *)xin->user_state;
- unsigned val;
- if (simple_uint (xin, attrs, &val)) {
- const unsigned scale = 100000u;
- double f = CLAMP (val, 0u, scale) / (double)scale;
- /*
- * FIXME: Wrong RGB colour space, see
- *
https://social.msdn.microsoft.com/forums/office/en-US/f6d26f2c-114f-4a0d-8bca-a27442aec4d0/tint-and-shade-elements
- */
- state->color = GO_COLOR_CHANGE_R(state->color, (guint8)(f*GO_COLOR_UINT_R(state->color)));
- state->color = GO_COLOR_CHANGE_G(state->color, (guint8)(f*GO_COLOR_UINT_G(state->color)));
- state->color = GO_COLOR_CHANGE_B(state->color, (guint8)(f*GO_COLOR_UINT_B(state->color)));
- color_set_helper (state);
- }
-}
-
-static void
-xlsx_draw_color_tint (GsfXMLIn *xin, xmlChar const **attrs)
-{
- XLSXReadState *state = (XLSXReadState *)xin->user_state;
- unsigned val;
- if (simple_uint (xin, attrs, &val)) {
- const unsigned scale = 100000u;
- double f = CLAMP (val, 0u, scale) / (double)scale;
- /*
- * FIXME: Wrong RGB colour space, see
- *
https://social.msdn.microsoft.com/forums/office/en-US/f6d26f2c-114f-4a0d-8bca-a27442aec4d0/tint-and-shade-elements
- */
- state->color = GO_COLOR_CHANGE_R(state->color, (guint8)(f * 255 + (1 - f) *
GO_COLOR_UINT_R(state->color)));
- state->color = GO_COLOR_CHANGE_G(state->color, (guint8)(f * 255 + (1 - f) *
GO_COLOR_UINT_G(state->color)));
- state->color = GO_COLOR_CHANGE_B(state->color, (guint8)(f * 255 + (1 - f) *
GO_COLOR_UINT_B(state->color)));
- color_set_helper (state);
- }
-}
-
-
-#define COLOR_MODIFIER_NODE(parent,node,name,first,handler,user) \
- GSF_XML_IN_NODE_FULL (parent, node, XL_NS_DRAW, name, (first ? GSF_XML_NO_CONTENT : GSF_XML_2ND),
FALSE, FALSE, handler, NULL, user)
-
-#define COLOR_MODIFIER_NODES(parent,first) \
- COLOR_MODIFIER_NODE(parent, COLOR_SHADE, "shade", first, &xlsx_draw_color_shade, 0), \
- COLOR_MODIFIER_NODE(parent, COLOR_TINT, "tint", first, &xlsx_draw_color_tint, 0), \
- COLOR_MODIFIER_NODE(parent, COLOR_COMP, "comp", first, &xlsx_draw_color_comp, 0), \
- COLOR_MODIFIER_NODE(parent, COLOR_INV, "inv", first, &xlsx_draw_color_invert, 0), \
- COLOR_MODIFIER_NODE(parent, COLOR_GRAY, "gray", first, &xlsx_draw_color_gray, 0), \
- COLOR_MODIFIER_NODE(parent, COLOR_ALPHA, "alpha", first, &xlsx_draw_color_rgba_channel, 12), \
- COLOR_MODIFIER_NODE(parent, COLOR_ALPHA_OFF, "alphaOff", first, &xlsx_draw_color_rgba_channel, 13), \
- COLOR_MODIFIER_NODE(parent, COLOR_ALPHA_MOD, "alphaMod", first, &xlsx_draw_color_rgba_channel, 14), \
- COLOR_MODIFIER_NODE(parent, COLOR_HUE, "hue", first, xlsx_draw_color_hsl_channel, 8), \
- COLOR_MODIFIER_NODE(parent, COLOR_HUE_OFF, "hueOff", first, xlsx_draw_color_hsl_channel, 9), \
- COLOR_MODIFIER_NODE(parent, COLOR_HUE_MOD, "hueMod", first, xlsx_draw_color_hsl_channel, 10), \
- COLOR_MODIFIER_NODE(parent, COLOR_SAT, "sat", first, xlsx_draw_color_hsl_channel, 4), \
- COLOR_MODIFIER_NODE(parent, COLOR_SAT_OFF, "satOff", first, xlsx_draw_color_hsl_channel, 5), \
- COLOR_MODIFIER_NODE(parent, COLOR_SAT_MOD, "satMod", first, xlsx_draw_color_hsl_channel, 6), \
- COLOR_MODIFIER_NODE(parent, COLOR_LUM, "lum", first, xlsx_draw_color_hsl_channel, 0), \
- COLOR_MODIFIER_NODE(parent, COLOR_LUM_OFF, "lumOff", first, xlsx_draw_color_hsl_channel, 1), \
- COLOR_MODIFIER_NODE(parent, COLOR_LUM_MOD, "lumMod", first, xlsx_draw_color_hsl_channel, 2), \
- COLOR_MODIFIER_NODE(parent, COLOR_RED, "red", first, &xlsx_draw_color_rgba_channel, 8), \
- COLOR_MODIFIER_NODE(parent, COLOR_RED_OFF, "redOff", first, &xlsx_draw_color_rgba_channel, 9), \
- COLOR_MODIFIER_NODE(parent, COLOR_RED_MOD, "redMod", first, &xlsx_draw_color_rgba_channel, 10), \
- COLOR_MODIFIER_NODE(parent, COLOR_GREEN, "green", first, &xlsx_draw_color_rgba_channel, 4), \
- COLOR_MODIFIER_NODE(parent, COLOR_GREEN_OFF, "greenOff", first, &xlsx_draw_color_rgba_channel, 5), \
- COLOR_MODIFIER_NODE(parent, COLOR_GREEN_MOD, "greenMod", first, &xlsx_draw_color_rgba_channel, 6), \
- COLOR_MODIFIER_NODE(parent, COLOR_BLUE, "blue", first, &xlsx_draw_color_rgba_channel, 0), \
- COLOR_MODIFIER_NODE(parent, COLOR_BLUE_OFF, "blueOff", first, &xlsx_draw_color_rgba_channel, 1), \
- COLOR_MODIFIER_NODE(parent, COLOR_BLUE_MOD, "blueMod", first, &xlsx_draw_color_rgba_channel, 2), \
- COLOR_MODIFIER_NODE(parent, COLOR_GAMMA, "gamma", first, &xlsx_draw_color_gamma, 0), \
- COLOR_MODIFIER_NODE(parent, COLOR_INV_GAMMA, "invGamma", first, &xlsx_draw_color_gamma, 1)
-
-
static GsfXMLInNode const xlsx_chart_drawing_dtd[] =
{
GSF_XML_IN_NODE_FULL (START, START, -1, NULL, GSF_XML_NO_CONTENT, FALSE, TRUE, NULL, NULL, 0),
diff --git a/plugins/excel/xlsx-read.c b/plugins/excel/xlsx-read.c
index 7ccb369..d0005f6 100644
--- a/plugins/excel/xlsx-read.c
+++ b/plugins/excel/xlsx-read.c
@@ -1201,103 +1201,11 @@ xlsx_parse_sqref (GsfXMLIn *xin, xmlChar const *refs)
static void xlsx_ext_begin (GsfXMLIn *xin, xmlChar const **attrs);
static void xlsx_ext_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob);
+#include "xlsx-read-color.c"
#include "xlsx-read-drawing.c"
/***********************************************************************/
-/* RGBMAX, HLSMAX must each fit in a byte. */
-/* HLSMAX BEST IF DIVISIBLE BY 6 */
-#define HLSMAX 240 /* H,L, and S vary over 0-HLSMAX */
-#define RGBMAX 255 /* R,G, and B vary over 0-RGBMAX */
-
-/* Hue is undefined if Saturation is 0 (grey-scale) */
-/* This value determines where the Hue scrollbar is */
-/* initially set for achromatic colors */
-#define UNDEFINED (HLSMAX*2/3)
-
-/* utility routine for HLStoRGB */
-static int
-hue_to_color (int m1, int m2, int h)
-{
- if (h < 0)
- h += HLSMAX;
- if (h > HLSMAX)
- h -= HLSMAX;
-
- /* return r,g, or b value from this tridrant */
- if (h < (HLSMAX/6))
- return m1 + (((m2 - m1)*h + (HLSMAX/12))/(HLSMAX/6));
- if (h < (HLSMAX/2))
- return m2;
- if (h < ((HLSMAX*2)/3))
- return m1 + (((m2 - m1)*(((HLSMAX*2)/3)-h)+(HLSMAX/12))/(HLSMAX/6));
-
- return m1;
-}
-
-static GOColor
-apply_tint (GOColor orig, double tint)
-{
- int r = GO_COLOR_UINT_R (orig);
- int g = GO_COLOR_UINT_G (orig);
- int b = GO_COLOR_UINT_B (orig);
- int a = GO_COLOR_UINT_A (orig);
- int maxC = b, minC = b, delta, sum, h = 0, l, s, m1, m2;
-
- if (fabs (tint) < .005)
- return orig;
-
- maxC = MAX (MAX (r,g),b);
- minC = MIN (MIN (r,g),b);
- l = (((maxC + minC)*HLSMAX) + RGBMAX)/(2*RGBMAX);
-
- delta = maxC - minC;
- sum = maxC + minC;
- if (delta != 0) {
- if (l <= (HLSMAX/2))
- s = ( (delta*HLSMAX) + (sum/2) ) / sum;
- else
- s = ( (delta*HLSMAX) + ((2*RGBMAX - sum)/2) ) / (2*RGBMAX - sum);
-
- if (r == maxC)
- h = ((g - b) * HLSMAX) / (6 * delta);
- else if (g == maxC)
- h = ( HLSMAX/3) + ((b - r) * HLSMAX) / (6 * delta);
- else if (b == maxC)
- h = (2*HLSMAX/3) + ((r - g) * HLSMAX) / (6 * delta);
-
- if (h < 0)
- h += HLSMAX;
- else if (h >= HLSMAX)
- h -= HLSMAX;
- } else {
- h = 0;
- s = 0;
- }
-
- if (tint < 0.)
- l = l * (1. + tint);
- else
- l = l * (1. - tint) + (HLSMAX - HLSMAX * (1.0 - tint));
-
- if (s == 0) { /* achromatic case */
- r = (l * RGBMAX) / HLSMAX;
- return GO_COLOR_FROM_RGBA (r, r, r, a);
- }
-
- if (l <= (HLSMAX/2))
- m2 = (l*(HLSMAX + s) + (HLSMAX/2))/HLSMAX;
- else
- m2 = l + s - ((l*s) + (HLSMAX/2))/HLSMAX;
- m1 = 2*l - m2;
-
- r = (hue_to_color (m1, m2, h + (HLSMAX/3))*RGBMAX + (HLSMAX/2)) / HLSMAX;
- g = (hue_to_color (m1, m2, h )*RGBMAX + (HLSMAX/2)) / HLSMAX;
- b = (hue_to_color (m1, m2, h - (HLSMAX/3))*RGBMAX + (HLSMAX/2)) / HLSMAX;
-
- return GO_COLOR_FROM_RGBA (r,g,b,a);
-}
-
static GnmColor *
elem_color (GsfXMLIn *xin, xmlChar const **attrs, gboolean allow_alpha)
{
@@ -1325,14 +1233,14 @@ elem_color (GsfXMLIn *xin, xmlChar const **attrs, gboolean allow_alpha)
has_color = TRUE;
c = themed_color (xin, indx);
} else if (attr_float (xin, attrs, "tint", &tint))
- tint = CLAMP (tint, -1., 1.);
+ ; /* Nothing */
}
if (!has_color)
return NULL;
- c = apply_tint (c, tint);
+ c = gnm_go_color_apply_tint (c, tint);
if (!allow_alpha)
- c |= 0xFF;
+ c = GO_COLOR_CHANGE_A (c, 0xFF);
return gnm_color_new_go (c);
}
@@ -4874,25 +4782,38 @@ static void
xlsx_theme_color_sys (GsfXMLIn *xin, xmlChar const **attrs)
{
XLSXReadState *state = (XLSXReadState *)xin->user_state;
- GOColor c;
- for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+ GOColor c = GO_COLOR_BLACK;
+
+ for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2) {
if (attr_gocolor (xin, attrs, "lastClr", &c)) {
- g_hash_table_replace (state->theme_colors_by_name,
- g_strdup (((GsfXMLInNode *)xin->node_stack->data)->name),
- GUINT_TO_POINTER (c));
}
+ }
+
+ state->color = c;
}
static void
xlsx_theme_color_rgb (GsfXMLIn *xin, xmlChar const **attrs)
{
XLSXReadState *state = (XLSXReadState *)xin->user_state;
- GOColor c;
- for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2)
+ GOColor c = GO_COLOR_BLACK;
+
+ for (; attrs != NULL && attrs[0] && attrs[1] ; attrs += 2) {
if (attr_gocolor (xin, attrs, "val", &c)) {
- g_hash_table_replace (state->theme_colors_by_name,
- g_strdup (((GsfXMLInNode *)xin->node_stack->data)->name),
- GUINT_TO_POINTER (c));
}
+ }
+
+ state->color = c;
+}
+
+static void
+xlsx_theme_color_end (GsfXMLIn *xin, G_GNUC_UNUSED GsfXMLBlob *blob)
+{
+ XLSXReadState *state = (XLSXReadState *)xin->user_state;
+ const char *name = ((GsfXMLInNode *)xin->node_stack->data)->name;
+
+ g_hash_table_replace (state->theme_colors_by_name,
+ g_strdup (name),
+ GUINT_TO_POINTER (state->color));
}
static GsfXMLInNode const xlsx_theme_dtd[] = {
@@ -4901,9 +4822,10 @@ GSF_XML_IN_NODE_FULL (START, THEME, XL_NS_DRAW, "theme", GSF_XML_NO_CONTENT, FAL
GSF_XML_IN_NODE (THEME, ELEMENTS, XL_NS_DRAW, "themeElements", GSF_XML_NO_CONTENT, NULL, NULL),
GSF_XML_IN_NODE (ELEMENTS, COLOR_SCHEME, XL_NS_DRAW, "clrScheme", GSF_XML_NO_CONTENT, NULL, NULL),
GSF_XML_IN_NODE (COLOR_SCHEME, dk1, XL_NS_DRAW, "dk1", GSF_XML_NO_CONTENT, NULL, NULL),
- GSF_XML_IN_NODE (dk1, SYS_COLOR, XL_NS_DRAW, "sysClr", GSF_XML_NO_CONTENT, &xlsx_theme_color_sys,
NULL),
- GSF_XML_IN_NODE (dk1, RGB_COLOR, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, &xlsx_theme_color_rgb,
NULL),
- GSF_XML_IN_NODE (RGB_COLOR, COLOR_ALPHA, XL_NS_DRAW, "alpha", GSF_XML_NO_CONTENT, NULL, NULL),
+ GSF_XML_IN_NODE (dk1, SYS_COLOR, XL_NS_DRAW, "sysClr", GSF_XML_NO_CONTENT, &xlsx_theme_color_sys,
&xlsx_theme_color_end),
+ COLOR_MODIFIER_NODES(SYS_COLOR,TRUE),
+ GSF_XML_IN_NODE (dk1, RGB_COLOR, XL_NS_DRAW, "srgbClr", GSF_XML_NO_CONTENT, &xlsx_theme_color_rgb,
&xlsx_theme_color_end),
+ COLOR_MODIFIER_NODES(RGB_COLOR,FALSE),
GSF_XML_IN_NODE (COLOR_SCHEME, lt1, XL_NS_DRAW, "lt1", GSF_XML_NO_CONTENT, NULL, NULL),
GSF_XML_IN_NODE (lt1, SYS_COLOR, XL_NS_DRAW, "sysClr", GSF_XML_2ND, NULL, NULL),
GSF_XML_IN_NODE (lt1, RGB_COLOR, XL_NS_DRAW, "srgbClr", GSF_XML_2ND, NULL, NULL),
@@ -4954,10 +4876,7 @@ GSF_XML_IN_NODE_FULL (START, THEME, XL_NS_DRAW, "theme", GSF_XML_NO_CONTENT, FAL
GSF_XML_IN_NODE (FORMAT_SCHEME, FILL_STYLE_LIST, XL_NS_DRAW, "fillStyleLst", GSF_XML_NO_CONTENT, NULL,
NULL),
GSF_XML_IN_NODE (FILL_STYLE_LIST, SOLID_FILL, XL_NS_DRAW, "solidFill", GSF_XML_NO_CONTENT, NULL,
NULL),
GSF_XML_IN_NODE (SOLID_FILL, SCHEME_COLOR, XL_NS_DRAW, "schemeClr", GSF_XML_NO_CONTENT, NULL,
NULL),
- GSF_XML_IN_NODE (SCHEME_COLOR, COLOR_TINT, XL_NS_DRAW, "tint", GSF_XML_NO_CONTENT, NULL, NULL),
- GSF_XML_IN_NODE (SCHEME_COLOR, COLOR_LUM, XL_NS_DRAW, "lumMod", GSF_XML_NO_CONTENT, NULL, NULL),
- GSF_XML_IN_NODE (SCHEME_COLOR, COLOR_SAT, XL_NS_DRAW, "satMod", GSF_XML_NO_CONTENT, NULL, NULL),
- GSF_XML_IN_NODE (SCHEME_COLOR, COLOR_SHADE, XL_NS_DRAW, "shade", GSF_XML_NO_CONTENT, NULL, NULL),
+ COLOR_MODIFIER_NODES(SCHEME_COLOR,FALSE),
GSF_XML_IN_NODE (FILL_STYLE_LIST, GRAD_FILL, XL_NS_DRAW, "gradFill", GSF_XML_NO_CONTENT, NULL,
NULL),
GSF_XML_IN_NODE (GRAD_FILL, GRAD_PATH, XL_NS_DRAW, "path", GSF_XML_NO_CONTENT, NULL, NULL),
GSF_XML_IN_NODE (GRAD_PATH, GRAD_PATH_RECT, XL_NS_DRAW, "fillToRect", GSF_XML_NO_CONTENT, NULL,
NULL),
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]