diff options
author | Bartosz Kosiorek <gang65@poczta.onet.pl> | 2024-09-29 11:16:18 +0200 |
---|---|---|
committer | Bartosz Kosiorek <gang65@poczta.onet.pl> | 2024-10-01 20:14:47 +0200 |
commit | 2849204df192331ea94c37414c9452acc9dda287 (patch) | |
tree | a8230269095a7ceaadbc7bb9113d989935dedcf9 | |
parent | 0c69b34e5f1ca995d0b6acf14594319a4c1cf5f3 (diff) |
tdf136564 VSDX Add support for TextBackground from SheetStyle
Previously the TextBackgroundColor was not supported when
it was defined inside StyleSheet.
This commit fixes that and allow for proper import of VSDX into
LibreOffice.
More information about TextBkgnd Cell:
https://learn.microsoft.com/en-us/office/client-developer/visio/textbkgnd-cell-text-block-format-section
Change-Id: Id8d1676d802916dc0776138041ea9f7928914f06
Reviewed-on: https://gerrit.libreoffice.org/c/libvisio/+/174173
Tested-by: Miklos Vajna <vmiklos@collabora.com>
Reviewed-by: Bartosz Kosiorek <gang65@poczta.onet.pl>
-rw-r--r-- | src/lib/VSDXMLParserBase.cpp | 25 | ||||
-rw-r--r-- | src/lib/VSDXMLParserBase.h | 1 | ||||
-rw-r--r-- | src/lib/VSDXParser.cpp | 54 | ||||
-rw-r--r-- | src/test/Makefile.am | 5 | ||||
-rw-r--r-- | src/test/data/tdf136564-WhiteTextBackground.vsdx | bin | 0 -> 19149 bytes | |||
-rw-r--r-- | src/test/importtest.cpp | 20 |
6 files changed, 83 insertions, 22 deletions
diff --git a/src/lib/VSDXMLParserBase.cpp b/src/lib/VSDXMLParserBase.cpp index bf1ab6a..8dadd5f 100644 --- a/src/lib/VSDXMLParserBase.cpp +++ b/src/lib/VSDXMLParserBase.cpp @@ -2221,6 +2221,31 @@ int libvisio::VSDXMLParserBase::readExtendedColourData(boost::optional<Colour> & return ret; } +/* Currently this method is used only for VSDX import, to avoid regression. + * TODO align usage with other file type importers (VSD), and cover it with test cases + */ +bool libvisio::VSDXMLParserBase::readColourOrColourIndex(Colour &value, long &idx, xmlTextReaderPtr reader) +{ + const shared_ptr<xmlChar> stringValue(readStringData(reader), xmlFree); + if (stringValue) + { + VSD_DEBUG_MSG(("VSDXMLParserBase::readExtendedColourData stringValue %s\n", (const char *)stringValue.get())); + if (!xmlStrEqual(stringValue.get(), BAD_CAST("Themed"))) + { + try + { + value = xmlStringToColour(stringValue); + return true; + } + catch (const XmlParserException &) + { + idx = xmlStringToLong(stringValue); + } + } + } + return false; +} + int libvisio::VSDXMLParserBase::readExtendedColourData(Colour &value, xmlTextReaderPtr reader) { long idx = -1; diff --git a/src/lib/VSDXMLParserBase.h b/src/lib/VSDXMLParserBase.h index ab8521d..62ebb4b 100644 --- a/src/lib/VSDXMLParserBase.h +++ b/src/lib/VSDXMLParserBase.h @@ -79,6 +79,7 @@ protected: int readExtendedColourData(Colour &value, long &idx, xmlTextReaderPtr reader); int readExtendedColourData(Colour &value, xmlTextReaderPtr reader); int readExtendedColourData(boost::optional<Colour> &value, xmlTextReaderPtr reader); + bool readColourOrColourIndex(Colour &value, long &idx, xmlTextReaderPtr reader); int readNURBSData(boost::optional<NURBSData> &data, xmlTextReaderPtr reader); int readPolylineData(boost::optional<PolylineData> &data, xmlTextReaderPtr reader); int readStringData(VSDName &text, xmlTextReaderPtr reader); diff --git a/src/lib/VSDXParser.cpp b/src/lib/VSDXParser.cpp index 1167ccb..8ede9c7 100644 --- a/src/lib/VSDXParser.cpp +++ b/src/lib/VSDXParser.cpp @@ -737,8 +737,8 @@ void libvisio::VSDXParser::readStyleProperties(xmlTextReaderPtr reader) boost::optional<double> topMargin; boost::optional<double> bottomMargin; boost::optional<unsigned char> verticalAlign; - boost::optional<bool> bgClrId; - boost::optional<Colour> bgColour; + boost::optional<bool> isTextBkgndFilled; + boost::optional<Colour> textBkgndColour; boost::optional<double> defaultTabStop; boost::optional<unsigned char> textDirection; @@ -846,10 +846,35 @@ void libvisio::VSDXParser::readStyleProperties(xmlTextReaderPtr reader) ret = readByteData(verticalAlign, reader); break; case XML_TEXTBKGND: -#if 0 if (XML_READER_TYPE_ELEMENT == tokenType) - ret = readExtendedColourData(bgColour, bgClrId, reader); -#endif + { + long bgClrId = -1; + Colour tmpColour; + if (readColourOrColourIndex(tmpColour, bgClrId, reader)) + { + isTextBkgndFilled = true; + textBkgndColour = tmpColour; + break; + } + /* + The TextBkgnd cell can have any value from 0 through 24, or 255. + The values 0 and 255 (visTxtBlklOpaque) both indicate a transparent text background. + For custom color, is is using the RGB or HSL function plus one. + */ + if ((bgClrId < 1) || (bgClrId >= 255)) + { + isTextBkgndFilled = false; + break; + } + std::map<unsigned, Colour>::const_iterator iter = m_colours.find(bgClrId - 1); + if (iter != m_colours.end()) + { + textBkgndColour = iter->second; + isTextBkgndFilled = true; + break; + } + isTextBkgndFilled = false; + } break; case XML_DEFAULTTABSTOP: if (XML_READER_TYPE_ELEMENT == tokenType) @@ -893,19 +918,6 @@ void libvisio::VSDXParser::readStyleProperties(xmlTextReaderPtr reader) } while ((XML_STYLESHEET != tokenId || XML_READER_TYPE_END_ELEMENT != tokenType) && 1 == ret && (!m_watcher || !m_watcher->isError())); -#if 0 - if (bgClrId < 0) - bgClrId = 0; - if (bgClrId) - { - std::map<unsigned, Colour>::const_iterator iter = m_colours.find(bgClrId-1); - if (iter != m_colours.end()) - bgColour = iter->second; - else - bgColour = Colour(); - } -#endif - if (m_isInStyles) { m_collector->collectLineStyle(level, strokeWidth, strokeColour, linePattern, startMarker, endMarker, lineCap, @@ -914,7 +926,7 @@ void libvisio::VSDXParser::readStyleProperties(xmlTextReaderPtr reader) fillBGTransparency, shadowPattern, shadowColourFG, shadowOffsetX, shadowOffsetY, qsFillColour, qsShadowColour, qsFillMatrix); m_collector->collectTextBlockStyle(level, leftMargin, rightMargin, topMargin, bottomMargin, - verticalAlign, bgClrId, bgColour, defaultTabStop, textDirection); + verticalAlign, isTextBkgndFilled, textBkgndColour, defaultTabStop, textDirection); } else { @@ -923,8 +935,8 @@ void libvisio::VSDXParser::readStyleProperties(xmlTextReaderPtr reader) m_shape.m_fillStyle.override(VSDOptionalFillStyle(fillColourFG, fillColourBG, fillPattern, fillFGTransparency, fillBGTransparency, shadowColourFG, shadowPattern, shadowOffsetX, shadowOffsetY, qsFillColour, qsShadowColour, qsFillMatrix)); - m_shape.m_textBlockStyle.override(VSDOptionalTextBlockStyle(leftMargin, rightMargin, topMargin, bottomMargin, verticalAlign, !!bgClrId, bgColour, - defaultTabStop, textDirection)); + m_shape.m_textBlockStyle.override(VSDOptionalTextBlockStyle(leftMargin, rightMargin, topMargin, bottomMargin, verticalAlign, + isTextBkgndFilled, textBkgndColour, defaultTabStop, textDirection)); } } diff --git a/src/test/Makefile.am b/src/test/Makefile.am index a546396..224d14b 100644 --- a/src/test/Makefile.am +++ b/src/test/Makefile.am @@ -55,6 +55,7 @@ EXTRA_DIST = \ data/bgcolor.vsdx \ data/bitmaps.vsd \ data/bitmaps2.vsd \ + data/blue-box.vsdx \ data/color-boxes.vsdx \ data/dwg.vsd \ data/dwg.vsdx \ @@ -62,8 +63,10 @@ EXTRA_DIST = \ data/fdo86729-ms1252.vsd \ data/fdo86729-utf8.vsd \ data/no-bgcolor.vsd \ + data/qs-box.vsdx \ data/tdf76829-datetime-format.vsd \ - data/tdf76829-numeric-format.vsd + data/tdf76829-numeric-format.vsd \ + data/tdf136564-WhiteTextBackground.vsdx # ImportTest::testVsdMetadataTitleUtf8 checks formatted date string AM_TESTS_ENVIRONMENT = TZ=UTC; export TZ; diff --git a/src/test/data/tdf136564-WhiteTextBackground.vsdx b/src/test/data/tdf136564-WhiteTextBackground.vsdx Binary files differnew file mode 100644 index 0000000..59f4bca --- /dev/null +++ b/src/test/data/tdf136564-WhiteTextBackground.vsdx diff --git a/src/test/importtest.cpp b/src/test/importtest.cpp index 12e909a..c4fcf5c 100644 --- a/src/test/importtest.cpp +++ b/src/test/importtest.cpp @@ -210,6 +210,7 @@ class ImportTest : public CPPUNIT_NS::TestFixture CPPUNIT_TEST(testVsdxCharBgColor); #endif CPPUNIT_TEST(testVsdTextBlockWithoutBgColor); + CPPUNIT_TEST(testVsdxTextBkgndColorFromStylesheet); CPPUNIT_TEST(testVsdNumericFormat); CPPUNIT_TEST(testVsdDateTimeFormatting); CPPUNIT_TEST(testVsd11FormatLine); @@ -229,6 +230,7 @@ class ImportTest : public CPPUNIT_NS::TestFixture void testVsdxImportBgColorFromTheme(); void testVsdxCharBgColor(); void testVsdTextBlockWithoutBgColor(); + void testVsdxTextBkgndColorFromStylesheet(); void testVsdNumericFormat(); void testVsd11FormatLine(); void testVsdDateTimeFormatting(); @@ -358,6 +360,24 @@ void ImportTest::testVsdTextBlockWithoutBgColor() assertXPathNoAttribute(m_doc, "/document/page/layer[5]/textObject/paragraph[1]/span", "background-color"); } +void ImportTest::testVsdxTextBkgndColorFromStylesheet() +{ + m_doc = parse("tdf136564-WhiteTextBackground.vsdx", m_buffer); + assertXPathNoAttribute(m_doc, "/document/page/layer[2]/textObject/paragraph/span", "background-color"); + assertXPathContent(m_doc, "/document/page/layer[2]/textObject/paragraph/span/insertText", "First triangle without background"); + + assertXPathNoAttribute(m_doc, "/document/page/layer[3]/textObject/paragraph/span", "background-color"); + assertXPathContent(m_doc, "/document/page/layer[3]/textObject/paragraph/span/insertText", "Second triangle without background"); + + // Without the accompanying fix in place, this test would have failed with: + // equality assertion failed + // - Expected: #ffffff + // - Actual : + assertXPath(m_doc, "/document/page/layer[4]/textObject/paragraph/span", "background-color", "#ffffff"); + assertXPath(m_doc, "/document/page/layer[4]/textObject/paragraph/span", "color", "#000000"); + assertXPathContent(m_doc, "/document/page/layer[4]/textObject/paragraph/span/insertText", "By default Text is with white Background"); +} + void ImportTest::testVsdNumericFormat() { m_doc = parse("tdf76829-numeric-format.vsd", m_buffer); |