[gnumeric] Conditional formats: handle font names for xls.



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]