summaryrefslogtreecommitdiff
path: root/svgio
diff options
context:
space:
mode:
authorXisco Fauli <xiscofauli@libreoffice.org>2023-07-05 13:31:27 +0200
committerXisco Fauli <xiscofauli@libreoffice.org>2023-07-06 17:17:54 +0200
commit0b0e2e1660cb43608f6c8d2d7264dda9857a6e82 (patch)
treeffa89bd3b702941485e3bfdee66efc3ab3a820a1 /svgio
parentcf874ef8bb0df0528163c347aa4fc079572a59de (diff)
tdf#156167: create separate map for case insensitive strings
Add static_assert to make sure both maps have the same size Regression from: svgio: use "frozen" for mapping between token strings and enums Change-Id: I2061606146cfcb34169dccf69b6f720727839d04 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/153174 Tested-by: Jenkins Reviewed-by: Tomaž Vajngerl <quikee@gmail.com> Change-Id: Ic54dfe45eaff5ef75bcd4ebab715f278540da913 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154055 Tested-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org> Signed-off-by: Xisco Fauli <xiscofauli@libreoffice.org> Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154132 Tested-by: Jenkins
Diffstat (limited to 'svgio')
-rw-r--r--svgio/qa/cppunit/SvgImportTest.cxx19
-rw-r--r--svgio/qa/cppunit/data/tdf156167.svg18
-rw-r--r--svgio/source/svgreader/svgtoken.cxx156
3 files changed, 175 insertions, 18 deletions
diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx
index 8e301469394b..56e896c56eac 100644
--- a/svgio/qa/cppunit/SvgImportTest.cxx
+++ b/svgio/qa/cppunit/SvgImportTest.cxx
@@ -501,6 +501,25 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf156018)
assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[2]", "color", "#0000ff");
}
+CPPUNIT_TEST_FIXTURE(Test, testTdf156167)
+{
+ Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/tdf156167.svg");
+ CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
+
+ drawinglayer::Primitive2dXmlDump dumper;
+ xmlDocUniquePtr pDocument = dumper.dumpAndParse(aSequence);
+
+ CPPUNIT_ASSERT (pDocument);
+
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[1]", "color", "#ffa500");
+
+ // Without the fix in place, this test would have failed with
+ // - Expected: #ffa500
+ // - Actual : #ff0000
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[2]", "color", "#ffa500");
+ assertXPath(pDocument, "/primitive2D/transform/polypolygoncolor[3]", "color", "#ffa500");
+}
+
CPPUNIT_TEST_FIXTURE(Test, testTdf155932)
{
Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/tdf155932.svg");
diff --git a/svgio/qa/cppunit/data/tdf156167.svg b/svgio/qa/cppunit/data/tdf156167.svg
new file mode 100644
index 000000000000..5ab1254013c4
--- /dev/null
+++ b/svgio/qa/cppunit/data/tdf156167.svg
@@ -0,0 +1,18 @@
+<svg id="svg-root" width="100%" height="100%"
+ viewBox="0 0 480 360" xmlns="http://www.w3.org/2000/svg"
+ xmlns:xlink="http://www.w3.org/1999/xlink">
+ <g id="test-body-content" font-family="SVGFreeSansASCII,sans-serif" font-size="18">
+
+ <g fill="orange">
+ <circle id="a" FiLl="red" cx="140" cy="100" r="50"/>
+ </g>
+ <circle id="b" fill="red" style="FiLl: oRaNgE" cx="340" cy="100" r="50"/>
+ <circle id="c" fill="blue" cx="140" cy="220" r="50"/>
+
+ <style type="text/css">
+ #c {fill: red }
+ #c {FiLl: oRaNgE }
+ </style>
+
+ </g>
+</svg>
diff --git a/svgio/source/svgreader/svgtoken.cxx b/svgio/source/svgreader/svgtoken.cxx
index 1e2d3d7486da..0d77ca901ee8 100644
--- a/svgio/source/svgreader/svgtoken.cxx
+++ b/svgio/source/svgreader/svgtoken.cxx
@@ -180,25 +180,95 @@ constexpr frozen::unordered_map<std::u16string_view, SVGToken, 145> aSVGTokenMap
{ u"flowRoot", SVGToken::FlowRoot }
};
-constexpr frozen::unordered_map<std::u16string_view, SVGToken, 32> aLowerCaseList
+// The same elements as the map above but lowercase. CSS is case insensitive
+// TODO: create separate maps for css and xml elements
+constexpr frozen::unordered_map<std::u16string_view, SVGToken, 145> aSVGLowerCaseTokenMapperList
{
+ { u"width", SVGToken::Width },
+ { u"height", SVGToken::Height },
{ u"viewbox", SVGToken::ViewBox },
+ { u"transform", SVGToken::Transform },
+ { u"style", SVGToken::Style },
+ { u"display", SVGToken::Display }, // #i121656#
+ { u"d", SVGToken::D },
+ { u"x", SVGToken::X },
+ { u"y", SVGToken::Y },
+ { u"xmlns", SVGToken::Xmlns },
+ { u"version", SVGToken::Version },
+ { u"id", SVGToken::Id },
+ { u"in", SVGToken::In },
+ { u"rx", SVGToken::Rx },
+ { u"ry", SVGToken::Ry },
+ { u"points", SVGToken::Points },
+ { u"dx", SVGToken::Dx },
+ { u"dy", SVGToken::Dy },
+ { u"rotate", SVGToken::Rotate },
{ u"textlength", SVGToken::TextLength },
{ u"lengthadjust", SVGToken::LengthAdjust },
+ { u"font", SVGToken::Font },
+ { u"font-family", SVGToken::FontFamily },
+ { u"font-size", SVGToken::FontSize },
+ { u"font-size-adjust", SVGToken::FontSizeAdjust },
+ { u"font-stretch", SVGToken::FontStretch },
+ { u"font-style", SVGToken::FontStyle },
+ { u"font-variant", SVGToken::FontVariant },
+ { u"font-weight", SVGToken::FontWeight },
+ { u"direction", SVGToken::Direction },
+ { u"letter-spacing", SVGToken::LetterSpacing },
+ { u"text-decoration", SVGToken::TextDecoration },
+ { u"unicode-bidi", SVGToken::UnicodeBidi },
+ { u"word-spacing", SVGToken::WordSpacing },
+ { u"tspan", SVGToken::Tspan },
+ { u"tref", SVGToken::Tref },
{ u"textpath", SVGToken::TextPath },
{ u"startoffset", SVGToken::StartOffset },
+ { u"method", SVGToken::Method },
+ { u"spacing", SVGToken::Spacing },
+ { u"stddeviation", SVGToken::StdDeviation },
+ { u"text-align", SVGToken::TextAlign },
{ u"pathlength", SVGToken::PathLength },
+ { u"type", SVGToken::Type },
+ { u"class", SVGToken::Class },
+ { u"text-anchor", SVGToken::TextAnchor },
+ { u"xml:space", SVGToken::XmlSpace },
+ { u"color", SVGToken::Color },
{ u"clippath", SVGToken::ClipPathNode },
+ { u"clip-path", SVGToken::ClipPathProperty },
+ { u"fecolormatrix", SVGToken::FeColorMatrix },
+ { u"fedropshadow", SVGToken::FeDropShadow },
+ { u"feflood", SVGToken::FeFlood },
+ { u"feimage", SVGToken::FeImage },
+ { u"fegaussianblur", SVGToken::FeGaussianBlur },
+ { u"feoffset", SVGToken::FeOffset },
+ { u"filter", SVGToken::Filter },
+ { u"flood-color", SVGToken::FloodColor },
+ { u"flood-opacity", SVGToken::FloodOpacity },
+ { u"mask", SVGToken::Mask },
{ u"clippathunits", SVGToken::ClipPathUnits },
{ u"maskunits", SVGToken::MaskUnits },
{ u"maskcontentunits", SVGToken::MaskContentUnits },
+ { u"clip-rule", SVGToken::ClipRule },
+ { u"marker", SVGToken::Marker },
+ { u"marker-start", SVGToken::MarkerStart },
+ { u"marker-mid", SVGToken::MarkerMid },
+ { u"marker-end", SVGToken::MarkerEnd },
+ { u"refx", SVGToken::RefX },
+ { u"refy", SVGToken::RefY },
{ u"markerunits", SVGToken::MarkerUnits },
{ u"markerwidth", SVGToken::MarkerWidth },
{ u"markerheight", SVGToken::MarkerHeight },
+ { u"orient", SVGToken::Orient },
+ { u"pattern", SVGToken::Pattern },
{ u"patternunits", SVGToken::PatternUnits },
{ u"patterncontentunits", SVGToken::PatternContentUnits },
{ u"patterntransform", SVGToken::PatternTransform },
+ { u"opacity", SVGToken::Opacity },
+ { u"visibility", SVGToken::Visibility },
+ { u"title", SVGToken::Title },
+ { u"desc", SVGToken::Desc },
{ u"preserveaspectratio", SVGToken::PreserveAspectRatio },
+ { u"defer", SVGToken::Defer },
+ { u"none", SVGToken::None },
{ u"xminymin", SVGToken::XMinYMin },
{ u"xmidymin", SVGToken::XMidYMin },
{ u"xmaxymin", SVGToken::XMaxYMin },
@@ -208,42 +278,92 @@ constexpr frozen::unordered_map<std::u16string_view, SVGToken, 32> aLowerCaseLis
{ u"xminymax", SVGToken::XMinYMax },
{ u"xmidymax", SVGToken::XMidYMax },
{ u"xmaxymax", SVGToken::XMaxYMax },
+ { u"meet", SVGToken::Meet },
+ { u"slice", SVGToken::Slice },
+ { u"values", SVGToken::Values },
+
+ { u"defs", SVGToken::Defs },
+ { u"g", SVGToken::G },
+ { u"svg", SVGToken::Svg },
+ { u"symbol", SVGToken::Symbol },
+ { u"use", SVGToken::Use },
+ { u"a", SVGToken::A },
+
+ { u"circle", SVGToken::Circle },
+ { u"ellipse", SVGToken::Ellipse },
+ { u"line", SVGToken::Line },
+ { u"path", SVGToken::Path },
+ { u"polygon", SVGToken::Polygon },
+ { u"polyline", SVGToken::Polyline },
+ { u"rect", SVGToken::Rect },
+ { u"image", SVGToken::Image },
+
{ u"lineargradient", SVGToken::LinearGradient },
{ u"radialgradient", SVGToken::RadialGradient },
+ { u"stop", SVGToken::Stop },
+ { u"offset", SVGToken::Offset },
+ { u"x1", SVGToken::X1 },
+ { u"y1", SVGToken::Y1 },
+ { u"x2", SVGToken::X2 },
+ { u"y2", SVGToken::Y2 },
+ { u"cx", SVGToken::Cx },
+ { u"cy", SVGToken::Cy },
+ { u"fx", SVGToken::Fx },
+ { u"fy", SVGToken::Fy },
+ { u"r", SVGToken::R },
{ u"gradientunits", SVGToken::GradientUnits },
{ u"gradienttransform", SVGToken::GradientTransform },
{ u"spreadmethod", SVGToken::SpreadMethod },
+ { u"href", SVGToken::Href },
+ { u"xlink:href", SVGToken::XlinkHref },
+ { u"stop-color", SVGToken::StopColor },
+ { u"stop-opacity", SVGToken::StopOpacity },
+
+ { u"fill", SVGToken::Fill },
+ { u"fill-opacity", SVGToken::FillOpacity },
+ { u"fill-rule", SVGToken::FillRule },
+
+ { u"stroke", SVGToken::Stroke },
+ { u"stroke-dasharray", SVGToken::StrokeDasharray },
+ { u"stroke-dashoffset", SVGToken::StrokeDashoffset },
+ { u"stroke-linecap", SVGToken::StrokeLinecap },
+ { u"stroke-linejoin", SVGToken::StrokeLinejoin },
+ { u"stroke-miterlimit", SVGToken::StrokeMiterlimit },
+ { u"stroke-opacity", SVGToken::StrokeOpacity },
+ { u"stroke-width", SVGToken::StrokeWidth },
+
+ { u"text", SVGToken::Text },
+ { u"baseline-shift", SVGToken::BaselineShift },
{ u"flowroot", SVGToken::FlowRoot }
};
+static_assert(sizeof(aSVGTokenMapperList) == sizeof(aSVGLowerCaseTokenMapperList),
+ "Number of elements in both maps must be the same");
+
SVGToken StrToSVGToken(const OUString& rStr, bool bCaseIndependent)
{
OUString aSearchString = rStr.startsWith("svg:") ? rStr.copy(4) : rStr;
- auto const aResult = aSVGTokenMapperList.find(aSearchString);
-
- if (aResult == aSVGTokenMapperList.end())
+ if (bCaseIndependent)
{
- if (bCaseIndependent)
- {
- auto const aResultLowerCase(aLowerCaseList.find(rStr.toAsciiLowerCase()));
+ auto const aResult(aSVGLowerCaseTokenMapperList.find(aSearchString.toAsciiLowerCase()));
- if (aResultLowerCase == aLowerCaseList.end())
- {
- return SVGToken::Unknown;
- }
- else
- {
- return aResultLowerCase->second;
- }
+ if (aResult != aSVGLowerCaseTokenMapperList.end())
+ {
+ return aResult->second;
}
-
- return SVGToken::Unknown;
}
else
{
- return aResult->second;
+ auto const aResult(aSVGTokenMapperList.find(aSearchString));
+
+ if (aResult != aSVGTokenMapperList.end())
+ {
+ return aResult->second;
+ }
}
+
+ return SVGToken::Unknown;
}
OUString SVGTokenToStr(const SVGToken& rToken)