From 04c78e1a46a423071d7ea68724525ec7ef92e0e8 Mon Sep 17 00:00:00 2001 From: Xisco Fauli Date: Wed, 5 Jul 2023 13:31:27 +0200 Subject: tdf#156167: create separate map for case insensitive strings MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 Change-Id: Ic54dfe45eaff5ef75bcd4ebab715f278540da913 Reviewed-on: https://gerrit.libreoffice.org/c/core/+/154055 Tested-by: Xisco Fauli Reviewed-by: Xisco Fauli --- svgio/qa/cppunit/SvgImportTest.cxx | 19 +++++ svgio/qa/cppunit/data/tdf156167.svg | 18 +++++ svgio/source/svgreader/svgtoken.cxx | 156 +++++++++++++++++++++++++++++++----- 3 files changed, 175 insertions(+), 18 deletions(-) create mode 100644 svgio/qa/cppunit/data/tdf156167.svg (limited to 'svgio') diff --git a/svgio/qa/cppunit/SvgImportTest.cxx b/svgio/qa/cppunit/SvgImportTest.cxx index 788eab52fdf5..24f146592249 100644 --- a/svgio/qa/cppunit/SvgImportTest.cxx +++ b/svgio/qa/cppunit/SvgImportTest.cxx @@ -505,6 +505,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(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 @@ + + + + + + + + + + + + + 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 aSVGTokenMap { u"flowRoot", SVGToken::FlowRoot } }; -constexpr frozen::unordered_map 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 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 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) -- cgit