From 887cc007eadf597fd1eb2d21a026296678cc5900 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Wed, 8 Jun 2016 00:10:26 +0530 Subject: [PATCH 1/7] Add enums and entries for various underline attributes --- include/orcus/spreadsheet/types.hpp | 43 ++++++++++++++++++++++++++++- 1 file changed, 42 insertions(+), 1 deletion(-) diff --git a/include/orcus/spreadsheet/types.hpp b/include/orcus/spreadsheet/types.hpp index 9b4987f11..394e4b262 100644 --- a/include/orcus/spreadsheet/types.hpp +++ b/include/orcus/spreadsheet/types.hpp @@ -81,7 +81,48 @@ enum class underline_t single_line, single_accounting, // unique to xlsx double_line, - double_accounting // unique to xlsx + double_accounting, // unique to xlsx + solid, + dotted, + dash, + long_dash, + dot_dash, + dot_dot_dot_dash, + wave +}; + +enum class underline_width_t +{ + none = 0, + normal, + bold, + thin, + medium, + thick, + positive_integer, + percent, + positive_length +}; + +enum class underline_mode_t +{ + continuos = 0, + skip_white_space +}; + +enum class underline_type_t +{ + none = 0, + single, + double_type //necessary to not call it "double", since it is a reserved word +}; + +struct underline_attrs_t +{ + underline_t underline_style; + underline_width_t underline_width; + underline_mode_t underline_mode; + underline_type_t underline_type; }; enum class hor_alignment_t -- GitLab From 3b2f710d7f67f63d76c853a45ede3783c7277f01 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Wed, 8 Jun 2016 00:12:05 +0530 Subject: [PATCH 2/7] Add a few functions for underline attributes to import interface --- .../orcus/spreadsheet/import_interface.hpp | 4 +++ include/orcus/spreadsheet/styles.hpp | 10 ++++++- src/spreadsheet/styles.cpp | 27 +++++++++++++++++-- 3 files changed, 38 insertions(+), 3 deletions(-) diff --git a/include/orcus/spreadsheet/import_interface.hpp b/include/orcus/spreadsheet/import_interface.hpp index cc83e5a51..ede5b64a0 100644 --- a/include/orcus/spreadsheet/import_interface.hpp +++ b/include/orcus/spreadsheet/import_interface.hpp @@ -90,6 +90,10 @@ public: virtual void set_font_name(const char* s, size_t n) = 0; virtual void set_font_size(double point) = 0; virtual void set_font_underline(orcus::spreadsheet::underline_t e) = 0; + virtual void set_font_underline_width(underline_width_t e) = 0; + virtual void set_font_underline_mode(underline_mode_t e) = 0; + virtual void set_font_underline_type(underline_type_t e) = 0; + virtual void set_font_underline_color(color_elem_t alpha, color_elem_t red, color_elem_t green, color_elem_t blue) = 0; virtual void set_font_color(color_elem_t alpha, color_elem_t red, color_elem_t green, color_elem_t blue) = 0; virtual size_t commit_font() = 0; diff --git a/include/orcus/spreadsheet/styles.hpp b/include/orcus/spreadsheet/styles.hpp index 3cf019e73..c17e5a43f 100644 --- a/include/orcus/spreadsheet/styles.hpp +++ b/include/orcus/spreadsheet/styles.hpp @@ -39,7 +39,11 @@ struct ORCUS_SPM_DLLPUBLIC font_t double size; bool bold:1; bool italic:1; - underline_t underline; + underline_t underline_style; + underline_width_t underline_width; + underline_mode_t underline_mode; + underline_type_t underline_type; + color_t underline_color; color_t color; font_t(); @@ -146,6 +150,10 @@ public: virtual void set_font_name(const char* s, size_t n); virtual void set_font_size(double point); virtual void set_font_underline(underline_t e); + virtual void set_font_underline_width(underline_width_t e); + virtual void set_font_underline_mode(underline_mode_t e); + virtual void set_font_underline_type(underline_type_t e); + virtual void set_font_underline_color(color_elem_t alpha, color_elem_t red, color_elem_t green, color_elem_t blue); virtual void set_font_color(color_elem_t alpha, color_elem_t red, color_elem_t green, color_elem_t blue); virtual size_t commit_font(); diff --git a/src/spreadsheet/styles.cpp b/src/spreadsheet/styles.cpp index 9e62c0c6c..e1795d80a 100644 --- a/src/spreadsheet/styles.cpp +++ b/src/spreadsheet/styles.cpp @@ -15,7 +15,10 @@ namespace orcus { namespace spreadsheet { font_t::font_t() : size(0.0), bold(false), - italic(false), underline(underline_t::none), + italic(false), underline_style(underline_t::none), + underline_width(underline_width_t::none), + underline_mode(underline_mode_t::continuos), + underline_type(underline_type_t::none), color() { } @@ -154,7 +157,27 @@ void import_styles::set_font_size(double point) void import_styles::set_font_underline(underline_t e) { - m_cur_font.underline = e; + m_cur_font.underline_style = e; +} + +void import_styles::set_font_underline_width(underline_width_t e) +{ + m_cur_font.underline_width = e; +} + +void import_styles::set_font_underline_mode(underline_mode_t e) +{ + m_cur_font.underline_mode = e; +} + +void import_styles::set_font_underline_type(underline_type_t e) +{ + m_cur_font.underline_type = e; +} + +void import_styles::set_font_underline_color(color_elem_t alpha, color_elem_t red, color_elem_t green, color_elem_t blue) +{ + m_cur_font.underline_color = color_t(alpha, red, green, blue); } void import_styles::set_font_color(color_elem_t alpha, color_elem_t red, color_elem_t green, color_elem_t blue) -- GitLab From febd5ac7178630aff070c07a4d9aca30adab2399 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Wed, 8 Jun 2016 14:14:06 +0530 Subject: [PATCH 3/7] Add helper function for odf underline width --- src/liborcus/odf_helper.cpp | 25 +++++++++++++++++++++++++ src/liborcus/odf_helper.hpp | 1 + 2 files changed, 26 insertions(+) diff --git a/src/liborcus/odf_helper.cpp b/src/liborcus/odf_helper.cpp index 3e4cd6d10..d2668712b 100644 --- a/src/liborcus/odf_helper.cpp +++ b/src/liborcus/odf_helper.cpp @@ -40,6 +40,21 @@ odf_border_style_map::entry odf_border_style_entries[] = { MDDS_ASCII("thin"), spreadsheet::border_style_t::thin} }; +typedef mdds::sorted_string_map odf_underline_width_map; + +odf_underline_width_map::entry odf_underline_width_entries[] = +{ + { MDDS_ASCII("bold"), spreadsheet::underline_width_t::bold}, + { MDDS_ASCII("medium"), spreadsheet::underline_width_t::medium}, + { MDDS_ASCII("none"), spreadsheet::underline_width_t::none}, + { MDDS_ASCII("normal"), spreadsheet::underline_width_t::normal}, + { MDDS_ASCII("percent"), spreadsheet::underline_width_t::percent}, + { MDDS_ASCII("positiveInteger"), spreadsheet::underline_width_t::positive_integer}, + { MDDS_ASCII("positiveLength"), spreadsheet::underline_width_t::positive_length}, + { MDDS_ASCII("thick"), spreadsheet::underline_width_t::thick}, + { MDDS_ASCII("thin"), spreadsheet::underline_width_t::thin}, +}; + bool is_valid_hex_digit(const char& character, orcus::spreadsheet::color_elem_t& val) { @@ -118,6 +133,16 @@ orcus::odf_helper::odf_border_details odf_helper::extract_border_details(const o } return border_details; } + +orcus::spreadsheet::underline_width_t odf_helper::extract_underline_width(const orcus::pstring& value) +{ + orcus::spreadsheet::underline_width_t underline_width; + + odf_underline_width_map underline_width_map(odf_underline_width_entries, ORCUS_N_ELEMENTS(odf_underline_width_entries), spreadsheet::underline_width_t::none); + underline_width = underline_width_map.find(value.get(), value.size()); + + return underline_width; +} } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_helper.hpp b/src/liborcus/odf_helper.hpp index f8a22b730..4c6c310d6 100644 --- a/src/liborcus/odf_helper.hpp +++ b/src/liborcus/odf_helper.hpp @@ -37,6 +37,7 @@ public: **/ static orcus::odf_helper::odf_border_details extract_border_details(const orcus::pstring& value); + static orcus::spreadsheet::underline_width_t extract_underline_width(const orcus::pstring& value); }; } -- GitLab From 16f696fd1d60db418f075cdecfceb0e8454457ea Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Wed, 8 Jun 2016 15:28:53 +0530 Subject: [PATCH 4/7] Add helper function for odf underline style --- src/liborcus/odf_helper.cpp | 24 ++++++++++++++++++++++++ src/liborcus/odf_helper.hpp | 2 ++ 2 files changed, 26 insertions(+) diff --git a/src/liborcus/odf_helper.cpp b/src/liborcus/odf_helper.cpp index d2668712b..7ebbe6c50 100644 --- a/src/liborcus/odf_helper.cpp +++ b/src/liborcus/odf_helper.cpp @@ -55,6 +55,19 @@ odf_underline_width_map::entry odf_underline_width_entries[] = { MDDS_ASCII("thin"), spreadsheet::underline_width_t::thin}, }; +typedef mdds::sorted_string_map odf_underline_style_map; + +odf_underline_style_map::entry odf_underline_style_entries[] = +{ + { MDDS_ASCII("dash"), spreadsheet::underline_t::dash}, + { MDDS_ASCII("dot-dash"), spreadsheet::underline_t::dot_dash}, + { MDDS_ASCII("dot-dot-dot-dash"), spreadsheet::underline_t::dot_dot_dot_dash}, + { MDDS_ASCII("dotted"), spreadsheet::underline_t::dotted}, + { MDDS_ASCII("long-dash"), spreadsheet::underline_t::long_dash}, + { MDDS_ASCII("none"), spreadsheet::underline_t::none}, + { MDDS_ASCII("solid"), spreadsheet::underline_t::solid}, + { MDDS_ASCII("wave"), spreadsheet::underline_t::wave} +}; bool is_valid_hex_digit(const char& character, orcus::spreadsheet::color_elem_t& val) { @@ -143,6 +156,17 @@ orcus::spreadsheet::underline_width_t odf_helper::extract_underline_width(const return underline_width; } + +orcus::spreadsheet::underline_t odf_helper::extract_underline_style(const orcus::pstring& value) +{ + spreadsheet::underline_t underline_style; + + odf_underline_style_map underline_style_map(odf_underline_style_entries, ORCUS_N_ELEMENTS(odf_underline_style_entries), spreadsheet::underline_t::none); + underline_style = underline_style_map.find(value.get(), value.size()); + + return underline_style; +} + } /* vim:set shiftwidth=4 softtabstop=4 expandtab: */ diff --git a/src/liborcus/odf_helper.hpp b/src/liborcus/odf_helper.hpp index 4c6c310d6..e022412e0 100644 --- a/src/liborcus/odf_helper.hpp +++ b/src/liborcus/odf_helper.hpp @@ -38,6 +38,8 @@ public: static orcus::odf_helper::odf_border_details extract_border_details(const orcus::pstring& value); static orcus::spreadsheet::underline_width_t extract_underline_width(const orcus::pstring& value); + + static orcus::spreadsheet::underline_t extract_underline_style(const orcus::pstring& value); }; } -- GitLab From e4cf516cd7041e686dd5f42e880708fb2f4e0bb7 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Wed, 8 Jun 2016 18:20:33 +0530 Subject: [PATCH 5/7] Add code to read odf underline attributes --- src/liborcus/odf_styles_context.cpp | 69 ++++++++++++++++++++++++++++- 1 file changed, 68 insertions(+), 1 deletion(-) diff --git a/src/liborcus/odf_styles_context.cpp b/src/liborcus/odf_styles_context.cpp index b62edfc15..824942f72 100644 --- a/src/liborcus/odf_styles_context.cpp +++ b/src/liborcus/odf_styles_context.cpp @@ -107,8 +107,25 @@ class text_prop_attr_parser : std::unary_function spreadsheet::color_elem_t m_green; spreadsheet::color_elem_t m_blue; + bool m_underline_is_text_color; + bool m_underline; + + spreadsheet::color_elem_t m_underline_red; + spreadsheet::color_elem_t m_underline_green; + spreadsheet::color_elem_t m_underline_blue; + + spreadsheet::underline_mode_t m_underline_mode; + spreadsheet::underline_width_t m_underline_width; + spreadsheet::underline_t m_underline_style; + spreadsheet::underline_type_t m_underline_type; + public: - text_prop_attr_parser() : m_bold(false), m_italic(false), m_color(false) {} + text_prop_attr_parser() : m_bold(false), m_italic(false), m_color(false), + m_underline_is_text_color(false), m_underline(false), + m_underline_mode(spreadsheet::underline_mode_t::continuos), + m_underline_width(spreadsheet::underline_width_t::none), + m_underline_style(spreadsheet::underline_t::none), + m_underline_type(spreadsheet::underline_type_t::none) {} void operator() (const xml_token_attr_t& attr) { @@ -119,6 +136,43 @@ public: case XML_font_name: m_font_name = attr.value; break; + case XML_text_underline_color: + if (!odf_helper::convert_fo_color(attr.value, m_underline_red, m_underline_green, m_underline_blue)) + { + m_underline = true; + m_underline_is_text_color = true; + } + break; + case XML_text_underline_mode: + m_underline = true; + if (attr.value == "skip-white-space") + m_underline_mode = spreadsheet::underline_mode_t::skip_white_space; + else + m_underline_mode = spreadsheet::underline_mode_t::continuos; + break; + case XML_text_underline_width: + { + m_underline = true; + m_underline_width = odf_helper::extract_underline_width(attr.value); + } + break; + case XML_text_underline_style: + { + m_underline = true; + m_underline_style = odf_helper::extract_underline_style(attr.value); + } + break; + case XML_text_underline_type: + { + m_underline = true; + if (attr.value == "none") + m_underline_type = spreadsheet::underline_type_t::none; + if (attr.value == "single") + m_underline_type = spreadsheet::underline_type_t::single; + if (attr.value == "double") + m_underline_type = spreadsheet::underline_type_t::double_type; + } + break; default: ; } @@ -158,6 +212,19 @@ public: green = m_green; blue = m_blue; } + bool has_underline() const { return m_underline; } + bool underline_is_text_color() const { return m_underline_is_text_color; } + const spreadsheet::underline_width_t get_underline_width() const { return m_underline_width; } + const spreadsheet::underline_mode_t get_underline_mode() const { return m_underline_mode; } + const spreadsheet::underline_type_t get_underline_type() const { return m_underline_type; } + const spreadsheet::underline_t get_underline_style() const { return m_underline_style; } + void get_underline_color(spreadsheet::color_elem_t& red, spreadsheet::color_elem_t& green, + spreadsheet::color_elem_t& blue) + { + red = m_underline_red; + green = m_underline_green; + blue = m_underline_blue; + } }; class cell_prop_attr_parser : std::unary_function -- GitLab From 806f4357539a93a5279321ef56c0c139f1b02179 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Thu, 9 Jun 2016 09:17:13 +0530 Subject: [PATCH 6/7] Add code to commit font underline --- src/liborcus/odf_styles_context.cpp | 27 +++++++++++++++++++++++++++ 1 file changed, 27 insertions(+) diff --git a/src/liborcus/odf_styles_context.cpp b/src/liborcus/odf_styles_context.cpp index 824942f72..72c343213 100644 --- a/src/liborcus/odf_styles_context.cpp +++ b/src/liborcus/odf_styles_context.cpp @@ -481,6 +481,33 @@ void styles_context::start_element(xmlns_id_t ns, xml_token_t name, const std::v mp_styles->set_font_color(0, red, green, blue); } + if (func.has_underline()) + { + if (func.underline_is_text_color() && func.has_color()) + { + spreadsheet::color_elem_t red, green, blue; + func.get_color(red, green, blue); + mp_styles->set_font_underline_color(0, red, green, blue); + } + else + { + spreadsheet::color_elem_t red, green, blue; + func.get_underline_color(red, green, blue); + mp_styles->set_font_underline_color(0, red, green, blue); + } + spreadsheet::underline_width_t width = func.get_underline_width(); + mp_styles->set_font_underline_width(width); + + spreadsheet::underline_t style = func.get_underline_style(); + mp_styles->set_font_underline(style); + + spreadsheet::underline_type_t type = func.get_underline_type(); + mp_styles->set_font_underline_type(type); + + spreadsheet::underline_mode_t mode = func.get_underline_mode(); + mp_styles->set_font_underline_mode(mode); + } + size_t font_id = mp_styles->commit_font(); switch (m_current_style->family) -- GitLab From cc6a848202afa505c275bf3ae7661aa9b631b078 Mon Sep 17 00:00:00 2001 From: Jaskaran Singh Date: Thu, 9 Jun 2016 09:23:21 +0530 Subject: [PATCH 7/7] Add test for odf font import --- src/liborcus/odf_styles_context_test.cpp | 41 ++++++++++++++++++++++++ test/ods/styles/cell-styles.xml | 6 ++++ 2 files changed, 47 insertions(+) diff --git a/src/liborcus/odf_styles_context_test.cpp b/src/liborcus/odf_styles_context_test.cpp index 838bf2d55..d037b18eb 100644 --- a/src/liborcus/odf_styles_context_test.cpp +++ b/src/liborcus/odf_styles_context_test.cpp @@ -112,5 +112,46 @@ int main() assert(cell_border->diagonal_tl_br.border_color.green == 0x00); assert(cell_border->diagonal_tl_br.border_width.value == 0.74); +/* Test for Font and underline + ================================================== +*/ + style = find_cell_style_by_name("Name8", &styles); + xf = style->xf; + cell_format = styles.get_cell_style_format(xf); + size_t font = cell_format->font; + assert(cell_format); + + const orcus::spreadsheet::font_t* cell_font = styles.get_font(font); + assert(cell_font->name == "Liberation Sans"); + assert(cell_font->size == 24); + assert(cell_font->bold == true); + assert(cell_font->italic == true); + assert(cell_font->underline_style == orcus::spreadsheet::underline_t::solid); + assert(cell_font->underline_width == orcus::spreadsheet::underline_width_t::thick); + assert(cell_font->underline_mode == orcus::spreadsheet::underline_mode_t::continuos); + assert(cell_font->underline_type == orcus::spreadsheet::underline_type_t::none); + assert(cell_font->underline_color.red == (int)0x80); + assert(cell_font->underline_color.green == (int)0x80); + assert(cell_font->underline_color.blue == (int)0x80); + + style = find_cell_style_by_name("Name9", &styles); + xf = style->xf; + cell_format = styles.get_cell_style_format(xf); + font = cell_format->font; + assert(cell_format); + + cell_font = styles.get_font(font); + assert(cell_font->name == "Tahoma"); + assert(cell_font->size == 00); + assert(cell_font->bold == true); + assert(cell_font->italic == false); + assert(cell_font->underline_style == orcus::spreadsheet::underline_t::dash); + assert(cell_font->underline_width == orcus::spreadsheet::underline_width_t::bold); + assert(cell_font->underline_mode == orcus::spreadsheet::underline_mode_t::continuos); + assert(cell_font->underline_type == orcus::spreadsheet::underline_type_t::none); + assert(cell_font->underline_color.red == (int)0x18); + assert(cell_font->underline_color.green == (int)0x56); + assert(cell_font->underline_color.blue == (int)0xff); + return 0; } diff --git a/test/ods/styles/cell-styles.xml b/test/ods/styles/cell-styles.xml index e9b944d1a..81b2a45ca 100644 --- a/test/ods/styles/cell-styles.xml +++ b/test/ods/styles/cell-styles.xml @@ -12,4 +12,10 @@ + + + + + + -- GitLab