[gnumeric] Conditional formats: handle diagonal borders for xls
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Conditional formats: handle diagonal borders for xls
- Date: Mon, 17 Mar 2014 17:05:30 +0000 (UTC)
commit c5d6389e769d7c65e389949f5cef2e4066d04228
Author: Morten Welinder <terra gnome org>
Date: Mon Mar 17 13:04:45 2014 -0400
Conditional formats: handle diagonal borders for xls
Excel seems to ignore these even though MS has defined them in the format.
plugins/excel/ms-excel-read.c | 40 ++++++++++++++++-----------
plugins/excel/ms-excel-write.c | 52 ++++++++++++++++++++++-------------
samples/cond-format-tests.gnumeric | Bin 4947 -> 5034 bytes
3 files changed, 57 insertions(+), 35 deletions(-)
---
diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c
index f78fee7..8a99cc7 100644
--- a/plugins/excel/ms-excel-read.c
+++ b/plugins/excel/ms-excel-read.c
@@ -5132,7 +5132,8 @@ excel_read_CF_border (GnmStyle *style, ExcelReadSheet *esheet,
GnmStyleBorderLocation type,
unsigned xl_pat_index, unsigned xl_color_index)
{
- gnm_style_set_border (style, GNM_STYLE_BORDER_LOCATION_TO_STYLE_ELEMENT (type),
+ GnmStyleElement elem = GNM_STYLE_BORDER_LOCATION_TO_STYLE_ELEMENT (type);
+ gnm_style_set_border (style, elem,
gnm_style_border_fetch (biff_xf_map_border (xl_pat_index),
excel_palette_get (esheet->container.importer,
xl_color_index),
@@ -5248,10 +5249,10 @@ excel_read_CF (BiffQuery *q, ExcelReadSheet *esheet, GnmStyleConditions *sc,
offset = 6 /* CF record header */ + 6; /* format header */
if (flags & 0x02000000) { /* number format */
- XL_CHECK_CONDITION (q->length >= offset + 2);
-
gboolean ignore = (flags & 0x00080000) != 0;
+ XL_CHECK_CONDITION (q->length >= offset + 2);
+
if (flags2 & 1) {
/* Format as string */
guint bytes = GSF_LE_GET_GUINT16 (q->data + offset);
@@ -5382,31 +5383,38 @@ excel_read_CF (BiffQuery *q, ExcelReadSheet *esheet, GnmStyleConditions *sc,
}
if (flags & 0x10000000) { /* borders */
- guint16 patterns;
- guint32 colours;
+ guint32 d0, d1;
XL_CHECK_CONDITION (q->length >= offset + 8);
- patterns = GSF_LE_GET_GUINT16 (q->data + offset);
- colours = GSF_LE_GET_GUINT32 (q->data + offset + 2);
+ d0 = GSF_LE_GET_GUINT32 (q->data + offset);
+ d1 = GSF_LE_GET_GUINT32 (q->data + offset + 4);
if (0 == (flags & 0x0400))
excel_read_CF_border (overlay, esheet, GNM_STYLE_BORDER_LEFT,
- (patterns >> 0) & 0xf,
- (colours >> 0) & 0x7f);
+ (d0 >> 0) & 0xf,
+ (d0 >> 16) & 0x7f);
if (0 == (flags & 0x0800))
excel_read_CF_border (overlay, esheet, GNM_STYLE_BORDER_RIGHT,
- (patterns >> 4) & 0xf,
- (colours >> 7) & 0x7f);
+ (d0 >> 4) & 0xf,
+ (d0 >> 23) & 0x7f);
if (0 == (flags & 0x1000))
excel_read_CF_border (overlay, esheet, GNM_STYLE_BORDER_TOP,
- (patterns >> 8) & 0xf,
- (colours >> 16) & 0x7f);
+ (d0 >> 8) & 0xf,
+ (d1 >> 0) & 0x7f);
if (0 == (flags & 0x2000))
excel_read_CF_border (overlay, esheet, GNM_STYLE_BORDER_BOTTOM,
- (patterns >> 12) & 0xf,
- (colours >> 23) & 0x7f);
+ (d0 >> 12) & 0xf,
+ (d1 >> 7) & 0x7f);
+ if (0 == (flags & 0x4000) && (d0 & 0x80000000)) {
+ excel_read_CF_border (overlay, esheet, GNM_STYLE_BORDER_DIAG,
+ (d1 >> 21) & 0xf,
+ (d1 >> 14) & 0x7f);
+ }
+ if (0 == (flags & 0x8000) && (d0 & 0x40000000))
+ excel_read_CF_border (overlay, esheet, GNM_STYLE_BORDER_REV_DIAG,
+ (d1 >> 21) & 0xf,
+ (d1 >> 14) & 0x7f);
- /* I wonder what the last two bytes are. future growth ? */
offset += 8;
}
diff --git a/plugins/excel/ms-excel-write.c b/plugins/excel/ms-excel-write.c
index 01aa158..65c76a2 100644
--- a/plugins/excel/ms-excel-write.c
+++ b/plugins/excel/ms-excel-write.c
@@ -930,22 +930,23 @@ typedef struct {
static gboolean
write_border (ExcelWriteSheet const *esheet,
GnmStyle const *s, GnmStyleElement elem,
- guint16 *patterns, guint32 *colours,
+ guint32 d[2],
unsigned pat_offset, unsigned colour_offset)
{
- unsigned c;
+ unsigned c;
GnmBorder *b;
if (!gnm_style_is_element_set (s, elem) ||
NULL == (b = gnm_style_get_border(s, elem)))
return TRUE;
- *patterns |= (map_border_to_xl (b->line_type, esheet->ewb->bp->version)
- << pat_offset);
+ d[pat_offset / 32] |=
+ (map_border_to_xl (b->line_type, esheet->ewb->bp->version)
+ << (pat_offset & 31));
c = map_color_to_palette (&esheet->ewb->base,
- b->color, PALETTE_AUTO_PATTERN);
- *colours |= (c << colour_offset);
+ b->color, PALETTE_AUTO_PATTERN);
+ d[colour_offset / 32] |= (c << (colour_offset & 31));
return FALSE;
}
@@ -1107,7 +1108,7 @@ cb_write_condition (GnmStyleConditions const *sc, CondDetails *cd,
GnmStyleCond const *cond = g_ptr_array_index (details, i);
GnmStyle const *s = cond->overlay;
GnmExprTop const *alt_texpr;
- guint32 flags = 0x0030C380; /* these are always true */
+ guint32 flags = 0x00300380; /* these are always true */
guint16 flags2 = 0x02; /* these are always true */
ms_biff_put_var_next (bp, BIFF_CF);
@@ -1291,25 +1292,38 @@ cb_write_condition (GnmStyleConditions const *sc, CondDetails *cd,
if (gnm_style_is_element_set (s, MSTYLE_BORDER_LEFT) ||
gnm_style_is_element_set (s, MSTYLE_BORDER_RIGHT) ||
gnm_style_is_element_set (s, MSTYLE_BORDER_TOP) ||
- gnm_style_is_element_set (s, MSTYLE_BORDER_BOTTOM)) {
- guint16 p = 0;
- guint32 c = 0;
- if (write_border (esheet, s, MSTYLE_BORDER_LEFT, &p, &c, 0, 0))
+ gnm_style_is_element_set (s, MSTYLE_BORDER_BOTTOM) ||
+ gnm_style_is_element_set (s, MSTYLE_BORDER_DIAGONAL) ||
+ gnm_style_is_element_set (s, MSTYLE_BORDER_REV_DIAGONAL)) {
+ guint32 d[2] = { 0, 0 };
+ if (write_border (esheet, s, MSTYLE_BORDER_LEFT, d, 0, 16))
flags |= 0x0400;
- if (write_border (esheet, s, MSTYLE_BORDER_RIGHT, &p, &c, 4, 7))
+ if (write_border (esheet, s, MSTYLE_BORDER_RIGHT, d, 4, 23))
flags |= 0x0800;
- if (write_border (esheet, s, MSTYLE_BORDER_TOP, &p, &c, 8, 16))
+ if (write_border (esheet, s, MSTYLE_BORDER_TOP, d, 8, 32))
flags |= 0x1000;
- if (write_border (esheet, s, MSTYLE_BORDER_BOTTOM, &p, &c, 12, 23))
+ if (write_border (esheet, s, MSTYLE_BORDER_BOTTOM, d, 12, 39))
flags |= 0x2000;
- GSF_LE_SET_GUINT16 (buf+0, p);
- GSF_LE_SET_GUINT32 (buf+2, c);
- GSF_LE_SET_GUINT16 (buf+6, 0);
+ /*
+ * MS-XLS defines fields for diagonals, but Excel does not seem to
+ * read them, not does the GUI allows creating them.
+ */
+ if (write_border (esheet, s, MSTYLE_BORDER_DIAGONAL, d, 53, 46))
+ flags |= 0x4000;
+ else
+ d[0] |= 0x80000000;
+ if (write_border (esheet, s, MSTYLE_BORDER_REV_DIAGONAL, d, 53, 46))
+ flags |= 0x8000;
+ else
+ d[0] |= 0x40000000;
+
+ GSF_LE_SET_GUINT32 (buf+0, d[0]);
+ GSF_LE_SET_GUINT32 (buf+4, d[1]);
ms_biff_put_var_write (bp, buf, 8);
flags |= 0x10000000;
} else
- flags |= 0x3C00;
+ flags |= 0xFC00;
if (gnm_style_is_element_set (s, MSTYLE_PATTERN) ||
gnm_style_is_element_set (s, MSTYLE_COLOR_BACK) ||
@@ -2098,7 +2112,7 @@ put_colors (ExcelStyleVariant const *esv, gpointer dummy, XLExportBase *ewb)
/* Borders */
for (i = STYLE_TOP; i < STYLE_ORIENT_MAX; i++) {
- b = gnm_style_get_border (st, MSTYLE_BORDER_TOP + i);
+ GnmBorder const *b = gnm_style_get_border (st, MSTYLE_BORDER_TOP + i);
if (b && b->color)
put_color_gnm (ewb, b->color);
}
diff --git a/samples/cond-format-tests.gnumeric b/samples/cond-format-tests.gnumeric
index 6510b1b..cd9a0db 100644
Binary files a/samples/cond-format-tests.gnumeric and b/samples/cond-format-tests.gnumeric differ
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]