summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBartosz Kosiorek <gang65@poczta.onet.pl>2024-09-29 11:16:18 +0200
committerBartosz Kosiorek <gang65@poczta.onet.pl>2024-10-01 20:14:47 +0200
commit2849204df192331ea94c37414c9452acc9dda287 (patch)
treea8230269095a7ceaadbc7bb9113d989935dedcf9
parent0c69b34e5f1ca995d0b6acf14594319a4c1cf5f3 (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.cpp25
-rw-r--r--src/lib/VSDXMLParserBase.h1
-rw-r--r--src/lib/VSDXParser.cpp54
-rw-r--r--src/test/Makefile.am5
-rw-r--r--src/test/data/tdf136564-WhiteTextBackground.vsdxbin0 -> 19149 bytes
-rw-r--r--src/test/importtest.cpp20
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
new file mode 100644
index 0000000..59f4bca
--- /dev/null
+++ b/src/test/data/tdf136564-WhiteTextBackground.vsdx
Binary files differ
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);