[gnumeric] xlsx: take xl's scaling of arrow head size with line width into account.



commit 10adbb6ee752af2e6c5a145eb3898bce84dc73f1
Author: Morten Welinder <terra gnome org>
Date:   Fri Feb 13 07:54:40 2015 -0500

    xlsx: take xl's scaling of arrow head size with line width into account.

 plugins/excel/ms-excel-read.c      |   12 +++++--
 plugins/excel/ms-excel-util.c      |   55 +++++++++++++++++++----------------
 plugins/excel/ms-excel-util.h      |    6 ++-
 plugins/excel/ms-excel-write.c     |   18 ++++++-----
 plugins/excel/xlsx-read-drawing.c  |    4 ++-
 plugins/excel/xlsx-write-drawing.c |    5 ++-
 6 files changed, 59 insertions(+), 41 deletions(-)
---
diff --git a/plugins/excel/ms-excel-read.c b/plugins/excel/ms-excel-read.c
index 709e6f5..57a52e9 100644
--- a/plugins/excel/ms-excel-read.c
+++ b/plugins/excel/ms-excel-read.c
@@ -449,6 +449,7 @@ ms_sheet_obj_anchor_to_pos (Sheet const * sheet,
 
 static void
 handle_arrow_head (SheetObject *so, const char *prop_name,
+                  double width,
                   MSObjAttrBag *attrs, MSObjAttrID typid,
                   MSObjAttrID wid, MSObjAttrID lid)
 {
@@ -456,7 +457,7 @@ handle_arrow_head (SheetObject *so, const char *prop_name,
        int w = ms_obj_attr_get_int (attrs, wid, 1);
        int l = ms_obj_attr_get_int (attrs, lid, 1);
        int typ = ms_obj_attr_get_int (attrs, typid, 0);
-       xls_arrow_from_xl (&arrow, typ, l, w);
+       xls_arrow_from_xl (&arrow, width, typ, l, w);
        g_object_set (so, prop_name, &arrow, NULL);
 }
 
@@ -552,7 +553,8 @@ ms_sheet_realize_obj (MSContainer *container, MSObj *obj)
                break;
 
        case MSOT_LINE:
-       case MSOT_ARC:
+       case MSOT_ARC: {
+               double width;
                style = go_style_new ();
                style->line.color = ms_sheet_map_color
                        (esheet, obj, MS_OBJ_ATTR_OUTLINE_COLOR,
@@ -565,20 +567,22 @@ ms_sheet_realize_obj (MSContainer *container, MSObj *obj)
                        ? GO_LINE_NONE
                        : ms_escher_xl_to_line_type (ms_obj_attr_get_int (obj->attrs, 
MS_OBJ_ATTR_OUTLINE_STYLE, 0));
 
+               width = style->line.auto_width ? 0 : style->line.width;
                g_object_set (G_OBJECT (so), "style", style, NULL);
                g_object_unref (style);
 
-               handle_arrow_head (so, "start-arrow",
+               handle_arrow_head (so, "start-arrow", width,
                                   obj->attrs,
                                   MS_OBJ_ATTR_ARROW_START,
                                   MS_OBJ_ATTR_ARROW_START_WIDTH,
                                   MS_OBJ_ATTR_ARROW_START_LENGTH);
-               handle_arrow_head (so, "end-arrow",
+               handle_arrow_head (so, "end-arrow", width,
                                   obj->attrs,
                                   MS_OBJ_ATTR_ARROW_END,
                                   MS_OBJ_ATTR_ARROW_END_WIDTH,
                                   MS_OBJ_ATTR_ARROW_END_LENGTH);
                break;
+       }
 
        case MSOT_POLYGON:
                g_object_set (G_OBJECT (so), "points",
diff --git a/plugins/excel/ms-excel-util.c b/plugins/excel/ms-excel-util.c
index 62fbd5c..661d950 100644
--- a/plugins/excel/ms-excel-util.c
+++ b/plugins/excel/ms-excel-util.c
@@ -825,8 +825,11 @@ xls_header_footer_import (PrintHF *hf, const char *txt)
 /*****************************************************************************/
 
 void
-xls_arrow_to_xl (GOArrow const *arrow, XLArrowType *ptyp, int *pl, int *pw)
+xls_arrow_to_xl (GOArrow const *arrow, double width,
+                XLArrowType *ptyp, int *pl, int *pw)
 {
+       double s = CLAMP (width, 1.0, 5); /* Excel arrows scale with line width */
+
        switch (arrow->typ) {
        case GO_ARROW_NONE:
                *ptyp = XL_ARROW_NONE;
@@ -836,26 +839,26 @@ xls_arrow_to_xl (GOArrow const *arrow, XLArrowType *ptyp, int *pl, int *pw)
        case GO_ARROW_KITE:
                if (fabs (arrow->a - arrow->b) < 0.01) {
                        *ptyp = XL_ARROW_REGULAR;
-                       *pl = (int)CLAMP ((arrow->a / 3.5) - 1, 0.0, 2.0);
-                       *pw = (int)CLAMP ((arrow->c / 2.5) - 1, 0.0, 2.0);
+                       *pl = (int)CLAMP ((arrow->a / (s * 3.5)) - 1, 0.0, 2.0);
+                       *pw = (int)CLAMP ((arrow->c / (s * 2.5)) - 1, 0.0, 2.0);
                } else if (arrow->a > arrow->b) {
                        *ptyp = XL_ARROW_DIAMOND;
-                       *pl = (int)CLAMP ((arrow->a / 5.0) - 1, 0.0, 2.0);
-                       *pw = (int)CLAMP ((arrow->c / 2.5) - 1, 0.0, 2.0);
+                       *pl = (int)CLAMP ((arrow->a / (s * 5.0)) - 1, 0.0, 2.0);
+                       *pw = (int)CLAMP ((arrow->c / (s * 2.5)) - 1, 0.0, 2.0);
                } else if (arrow->a < 0.5 * arrow->b) {
                        *ptyp = XL_ARROW_OPEN;
-                       *pl = (int)CLAMP ((arrow->a / 1.0) - 1, 0.0, 2.0);
-                       *pw = (int)CLAMP ((arrow->c / 1.5) - 1, 0.0, 2.0);
+                       *pl = (int)CLAMP ((arrow->a / (s * 1.0)) - 1, 0.0, 2.0);
+                       *pw = (int)CLAMP ((arrow->c / (s * 1.5)) - 1, 0.0, 2.0);
                } else {
                        *ptyp = XL_ARROW_STEALTH;
-                       *pl = (int)CLAMP ((arrow->b / 4.0) - 1, 0.0, 2.0);
-                       *pw = (int)CLAMP ((arrow->c / 2.0) - 1, 0.0, 2.0);
+                       *pl = (int)CLAMP ((arrow->b / (s * 4.0)) - 1, 0.0, 2.0);
+                       *pw = (int)CLAMP ((arrow->c / (s * 2.0)) - 1, 0.0, 2.0);
                }
                break;
        case GO_ARROW_OVAL:
                *ptyp = XL_ARROW_OVAL;
-               *pl = (int)CLAMP ((arrow->a / 2.5) - 1, 0.0, 2.0);
-               *pw = (int)CLAMP ((arrow->b / 2.5) - 1, 0.0, 2.0);
+               *pl = (int)CLAMP ((arrow->a / (s * 2.5)) - 1, 0.0, 2.0);
+               *pw = (int)CLAMP ((arrow->b / (s * 2.5)) - 1, 0.0, 2.0);
                break;
        default:
                g_assert_not_reached ();
@@ -863,8 +866,10 @@ xls_arrow_to_xl (GOArrow const *arrow, XLArrowType *ptyp, int *pl, int *pw)
 }
 
 void
-xls_arrow_from_xl (GOArrow *arrow, XLArrowType typ, int l, int w)
+xls_arrow_from_xl (GOArrow *arrow, double width, XLArrowType typ, int l, int w)
 {
+       double s = CLAMP (width, 1.0, 5); /* Excel arrows scale with line width */
+
        switch (typ) {
        case XL_ARROW_NONE:
                go_arrow_clear (arrow);
@@ -872,30 +877,30 @@ xls_arrow_from_xl (GOArrow *arrow, XLArrowType typ, int l, int w)
        default:
        case XL_ARROW_REGULAR:
                go_arrow_init_kite (arrow,
-                                   3.5 * (l + 1),
-                                   3.5 * (l + 1),
-                                   2.5 * (w + 1));
+                                   s * 3.5 * (l + 1),
+                                   s * 3.5 * (l + 1),
+                                   s * 2.5 * (w + 1));
                break;
        case XL_ARROW_STEALTH:
                go_arrow_init_kite (arrow,
-                                   2.5 * (l + 1),
-                                   4.0 * (l + 1),
-                                   2.0 * (w + 1));
+                                   s * 2.5 * (l + 1),
+                                   s * 4.0 * (l + 1),
+                                   s * 2.0 * (w + 1));
                break;
        case XL_ARROW_DIAMOND:
                go_arrow_init_kite (arrow,
-                                   5 * (l + 1),
-                                   2.5 * (l + 1),
-                                   2.5 * (w + 1));
+                                   s * 5 * (l + 1),
+                                   s * 2.5 * (l + 1),
+                                   s * 2.5 * (w + 1));
                break;
        case XL_ARROW_OVAL:
-               go_arrow_init_oval (arrow, (l + 1) * 2.5, (w + 1) * 2.5);
+               go_arrow_init_oval (arrow, s * 2.5 * (l + 1), s * 2.5 * (w + 1));
                break;
        case XL_ARROW_OPEN: /* Approximation! */
                go_arrow_init_kite (arrow,
-                                   1.0 * (l + 1),
-                                   2.5 * (l + 1),
-                                   1.5 * (w + 1));
+                                   s * 1.0 * (l + 1),
+                                   s * 2.5 * (l + 1),
+                                   s * 1.5 * (w + 1));
                break;
        }
 }
diff --git a/plugins/excel/ms-excel-util.h b/plugins/excel/ms-excel-util.h
index aad77d8..fc7bc1f 100644
--- a/plugins/excel/ms-excel-util.h
+++ b/plugins/excel/ms-excel-util.h
@@ -116,8 +116,10 @@ typedef enum {
        XL_ARROW_OPEN = 5
 } XLArrowType;
 
-void xls_arrow_to_xl (GOArrow const *arrow, XLArrowType *ptyp, int *pl, int *pw);
-void xls_arrow_from_xl (GOArrow *arrow, XLArrowType typ, int l, int w);
+void xls_arrow_to_xl (GOArrow const *arrow, double width,
+                     XLArrowType *ptyp, int *pl, int *pw);
+void xls_arrow_from_xl (GOArrow *arrow, double width,
+                       XLArrowType typ, int l, int w);
 
 /*****************************************************************************/
 
diff --git a/plugins/excel/ms-excel-write.c b/plugins/excel/ms-excel-write.c
index a84e06d..18ecd3d 100644
--- a/plugins/excel/ms-excel-write.c
+++ b/plugins/excel/ms-excel-write.c
@@ -4881,13 +4881,13 @@ excel_write_other_v8 (ExcelWriteSheet *esheet,
 }
 
 static void
-write_arrow (GOArrow const *arrow, GString *escher, gsize optmark,
+write_arrow (GOArrow const *arrow, double width, GString *escher, gsize optmark,
             guint id)
 {
        XLArrowType typ;
        int l, w;
 
-       xls_arrow_to_xl (arrow, &typ, &l, &w);
+       xls_arrow_to_xl (arrow, width, &typ, &l, &w);
 
        switch (id) {
        case MSEP_LINESTARTARROWHEAD:
@@ -4929,6 +4929,7 @@ excel_write_line_v8 (ExcelWriteSheet *esheet, SheetObject *so)
        GOArrow *start_arrow, *end_arrow;
        SheetObjectAnchor const *anchor = sheet_object_get_anchor (so);
        guint32 spflags;
+       double width;
 
        g_object_get (so,
                      "start-arrow", &start_arrow,
@@ -4969,12 +4970,13 @@ excel_write_line_v8 (ExcelWriteSheet *esheet, SheetObject *so)
        }
 
        /* The two arrows' attributes are interleaved.  */
-       write_arrow (start_arrow, escher, optmark, MSEP_LINESTARTARROWHEAD);
-       write_arrow (end_arrow, escher, optmark, MSEP_LINEENDARROWHEAD);
-       write_arrow (start_arrow, escher, optmark, MSEP_LINESTARTARROWWIDTH);
-       write_arrow (start_arrow, escher, optmark, MSEP_LINESTARTARROWLENGTH);
-       write_arrow (end_arrow, escher, optmark, MSEP_LINEENDARROWWIDTH);
-       write_arrow (end_arrow, escher, optmark, MSEP_LINEENDARROWLENGTH);
+       width = style->line.auto_width ? 0 : style->line.width;
+       write_arrow (start_arrow, width, escher, optmark, MSEP_LINESTARTARROWHEAD);
+       write_arrow (end_arrow, width, escher, optmark, MSEP_LINEENDARROWHEAD);
+       write_arrow (start_arrow, width, escher, optmark, MSEP_LINESTARTARROWWIDTH);
+       write_arrow (start_arrow, width, escher, optmark, MSEP_LINESTARTARROWLENGTH);
+       write_arrow (end_arrow, width, escher, optmark, MSEP_LINEENDARROWWIDTH);
+       write_arrow (end_arrow, width, escher, optmark, MSEP_LINEENDARROWLENGTH);
        ms_escher_opt_add_bool (escher, optmark, MSEP_ARROWHEADSOK, TRUE);
 
        if (name)
diff --git a/plugins/excel/xlsx-read-drawing.c b/plugins/excel/xlsx-read-drawing.c
index 5f5e9dd..d9e52a4 100644
--- a/plugins/excel/xlsx-read-drawing.c
+++ b/plugins/excel/xlsx-read-drawing.c
@@ -1850,7 +1850,9 @@ xlsx_chart_line_headtail (GsfXMLIn *xin, xmlChar const **attrs)
 
        if (IS_GNM_SO_LINE (state->so)) {
                GOArrow arrow;
-               xls_arrow_from_xl (&arrow, typ, l, w);
+               GOStyle const *style = state->cur_style;
+               double width = style->line.auto_width ? 0 : style->line.width;
+               xls_arrow_from_xl (&arrow, width, typ, l, w);
                g_object_set (state->so,
                              (is_tail ? "end-arrow" : "start-arrow"), &arrow,
                              NULL);
diff --git a/plugins/excel/xlsx-write-drawing.c b/plugins/excel/xlsx-write-drawing.c
index a750def..65c0673 100644
--- a/plugins/excel/xlsx-write-drawing.c
+++ b/plugins/excel/xlsx-write-drawing.c
@@ -367,10 +367,13 @@ xlsx_write_go_style_full (GsfXMLOut *xml, GOStyle *style, const XLSXStyleContext
                                "diamond", "oval", "arrow"
                        };
                        static const char *sizes[] = { "sm", "med", "lg" };
+                       double width;
 
                        if (!arr) continue;
 
-                       xls_arrow_to_xl (arr, &typ, &l, &w);
+                       width = style->line.auto_width ? 0 : style->line.width;
+
+                       xls_arrow_to_xl (arr, width, &typ, &l, &w);
                        gsf_xml_out_start_element (xml, i ? "a:tailEnd" : "a:headEnd");
                        gsf_xml_out_add_cstr_unchecked (xml, "type", types[typ]);
                        if (typ) {


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]