[gnumeric] Conditional formats: handle font names for xls.
- From: Morten Welinder <mortenw src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnumeric] Conditional formats: handle font names for xls.
- Date: Mon, 17 Mar 2014 14:10:49 +0000 (UTC)
commit 219acc5657a53c6b460c7d20ae143478aa45dd99
Author: Morten Welinder <terra gnome org>
Date: Mon Mar 17 10:09:51 2014 -0400
Conditional formats: handle font names for xls.
plugins/excel/ms-excel-read.c | 31 ++++++++++++++++++++
plugins/excel/ms-excel-write.c | 54 ++++++++++++++++++++++++++++++++---
samples/cond-format-tests.gnumeric | Bin 4848 -> 4946 bytes
test/t6515-cond-format.pl | 3 +-
4 files changed, 82 insertions(+), 6 deletions(-)
---
diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c
index d0452fe..f37585c 100644
--- a/plugins/excel/ms-excel-read.c
+++ b/plugins/excel/ms-excel-read.c
@@ -5247,6 +5247,30 @@ excel_read_CF (BiffQuery *q, ExcelReadSheet *esheet, GnmStyleConditions *sc,
offset = 6 /* CF record header */ + 6; /* format header */
+ if (FALSE && (flags & 0x02000000)) { /* number format */
+ XL_CHECK_CONDITION (q->length >= offset + 2);
+
+ /*
+ * This is documented in MS-XLS, but Excel does not read it.
+ * (Setting both a number format and Bold does not result in
+ * bold, so Excel does not account for the size of this field.)
+ */
+
+ if (flags2 & 1) {
+ /* Format as string */
+ guint bytes = GSF_LE_GET_GUINT16 (q->data + offset);
+ char *xlfmt = excel_biff_text_2 (importer, q, offset + 2);
+ GOFormat *fmt = go_format_new_from_XL (xlfmt);
+ gnm_style_set_format (overlay, fmt);
+ go_format_unref (fmt);
+ g_free (xlfmt);
+ offset += bytes;
+ } else {
+ /* Format as index */
+ offset += 2;
+ }
+ }
+
if (flags & 0x04000000) { /* font */
guint32 size, colour;
guint8 tmp8, font_flags;
@@ -5254,6 +5278,13 @@ excel_read_CF (BiffQuery *q, ExcelReadSheet *esheet, GnmStyleConditions *sc,
XL_CHECK_CONDITION (q->length >= offset + 64 + 54);
+ if (data[0]) {
+ char *font = excel_biff_text_1
+ (importer, q, offset);
+ gnm_style_set_font_name (overlay, font);
+ g_free (font);
+ }
+
data += 64;
if (0xFFFFFFFF != (size = GSF_LE_GET_GUINT32 (data)))
diff --git a/plugins/excel/ms-excel-write.c b/plugins/excel/ms-excel-write.c
index dcf64c6..947cbf1 100644
--- a/plugins/excel/ms-excel-write.c
+++ b/plugins/excel/ms-excel-write.c
@@ -1083,7 +1083,6 @@ cb_write_condition (GnmStyleConditions const *sc, CondDetails *cd,
BiffPut *bp = esheet->ewb->bp;
guint16 range_count;
guint8 buf[14], type, op;
- guint32 flags = 0x0038C380; /* these are always true */
unsigned i, expr0_len, expr1_len, header_pos;
GPtrArray const *details = gnm_style_conditions_details (sc);
unsigned det_len = details ? details->len : 0;
@@ -1108,13 +1107,41 @@ 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 = 0x0038C380; /* these are always true */
+ guint16 flags2 = 0x02; /* these are always true */
ms_biff_put_var_next (bp, BIFF_CF);
header_pos = bp->curpos;
ms_biff_put_var_seekto (bp, header_pos+12);
- if (gnm_style_is_element_set (s, MSTYLE_FONT_COLOR ) ||
- gnm_style_is_element_set (s, MSTYLE_FONT_NAME ) ||
+ /*
+ * This is documented in MS-XLS, but Excel does not read it.
+ * (Setting both a number format and Bold does not result in
+ * bold, so Excel does not account for the size of this field.)
+ */
+ if (FALSE && gnm_style_is_element_set (s, MSTYLE_FORMAT)) {
+ GOFormat const *fmt = gnm_style_get_format (s);
+ const char *xlfmt = go_format_as_XL (fmt);
+ guint16 bytes;
+ unsigned afterpos, lenpos = bp->curpos;
+
+ /* Write as DXFNumUsr structure. */
+ ms_biff_put_var_seekto (bp, lenpos + 2);
+ bytes = excel_write_string
+ (bp, STR_TWO_BYTE_LENGTH, xlfmt);
+
+ afterpos = bp->curpos;
+ ms_biff_put_var_seekto (bp, lenpos);
+ GSF_LE_SET_GUINT16 (buf, bytes + 2);
+ ms_biff_put_var_write (bp, buf, 2);
+ ms_biff_put_var_seekto (bp, afterpos);
+
+ flags |= 0x02000000;
+ flags2 |= 0x1;
+ }
+
+ if (gnm_style_is_element_set (s, MSTYLE_FONT_COLOR) ||
+ gnm_style_is_element_set (s, MSTYLE_FONT_NAME) ||
gnm_style_is_element_set (s, MSTYLE_FONT_BOLD) ||
gnm_style_is_element_set (s, MSTYLE_FONT_ITALIC) ||
gnm_style_is_element_set (s, MSTYLE_FONT_UNDERLINE ) ||
@@ -1123,9 +1150,24 @@ cb_write_condition (GnmStyleConditions const *sc, CondDetails *cd,
gnm_style_is_element_set (s, MSTYLE_FONT_SIZE)) {
guint8 fbuf[118];
guint32 tmp, font_flags = 0x18;
+ guint32 written = 0;
memset (fbuf, 0, sizeof (fbuf));
+ if (gnm_style_is_element_set (s, MSTYLE_FONT_NAME)) {
+ char *font = g_strdup (gnm_style_get_font_name (s));
+ size_t bytes;
+ guint charlen = excel_strlen (font, &bytes);
+ guint maxlen = (bytes == charlen) ? 62 : 30;
+
+ if (charlen > maxlen)
+ g_utf8_offset_to_pointer (font, maxlen)[0] = 0;
+
+ written = excel_write_string
+ (bp, STR_ONE_BYTE_LENGTH, font);
+ g_free (font);
+ }
+
if (gnm_style_is_element_set (s, MSTYLE_FONT_SIZE))
tmp = (int) (gnm_style_get_font_size (s) * 20. + .5);
else
@@ -1180,7 +1222,9 @@ cb_write_condition (GnmStyleConditions const *sc, CondDetails *cd,
GSF_LE_SET_GUINT8 (fbuf + 88, font_flags);
- ms_biff_put_var_write (bp, fbuf, sizeof (fbuf));
+ ms_biff_put_var_write (bp,
+ fbuf + written,
+ sizeof (fbuf) - written);
flags |= 0x04000000;
}
@@ -1364,7 +1408,7 @@ cb_write_condition (GnmStyleConditions const *sc, CondDetails *cd,
GSF_LE_SET_GUINT16 (buf+2, expr0_len);
GSF_LE_SET_GUINT16 (buf+4, expr1_len);
GSF_LE_SET_GUINT32 (buf+6, flags);
- GSF_LE_SET_GUINT16 (buf+10, 2); /* We have seen 2 and 0x802 */
+ GSF_LE_SET_GUINT16 (buf+10, flags2);
ms_biff_put_var_write (bp, buf, 12);
ms_biff_put_commit (bp);
diff --git a/samples/cond-format-tests.gnumeric b/samples/cond-format-tests.gnumeric
index 2225146..4381fd5 100644
Binary files a/samples/cond-format-tests.gnumeric and b/samples/cond-format-tests.gnumeric differ
diff --git a/test/t6515-cond-format.pl b/test/t6515-cond-format.pl
index 0efd35d..2344f33 100755
--- a/test/t6515-cond-format.pl
+++ b/test/t6515-cond-format.pl
@@ -22,7 +22,8 @@ my $file = "$samples/cond-format-tests.gnumeric";
my $xls_codepage_filter = "$PERL -p -e '\$_ = \"\" if m{<meta:user-defined meta:name=.msole:codepage.}'";
# xls/biff cannot handle format in conditional formats.
-my $xls_cond_format_filter = "$PERL -p -e 's{\\s+Format=\"[^\"\"]*\"}{} if m{<gnm:Style .*/>};'";
+my $xls_cond_format_filter = "$PERL -p -e 'if (m{<gnm:Condition\\b} ... m{</gnm:Condition\\b}) {
s{\\s+Format=\"[^\"\"]*\"}{}; }'";
+print STDERR "$xls_cond_format_filter\n";
&message ("Check conditional format xls/BIFF7 roundtrip.");
&test_roundtrip ($file,
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]