tdf#158445: support viewBox in symbol elements
Change-Id: Ie45b1e1dd4a4dcfc3cf3ce3d30f8dd9e040e37fb Reviewed-on: https://gerrit.libreoffice.org/c/core/+/162605 Tested-by: Jenkins Reviewed-by: Xisco Fauli <xiscofauli@libreoffice.org>
This commit is contained in:
@@ -29,6 +29,12 @@ namespace svgio::svgreader
|
||||
/// use styles
|
||||
SvgStyleAttributes maSvgStyleAttributes;
|
||||
|
||||
SvgNumber maX;
|
||||
SvgNumber maY;
|
||||
SvgNumber maWidth;
|
||||
SvgNumber maHeight;
|
||||
|
||||
std::unique_ptr<basegfx::B2DRange> mpViewBox;
|
||||
SvgAspectRatio maSvgAspectRatio;
|
||||
|
||||
public:
|
||||
@@ -39,6 +45,15 @@ namespace svgio::svgreader
|
||||
|
||||
virtual const SvgStyleAttributes* getSvgStyleAttributes() const override;
|
||||
virtual void parseAttribute(SVGToken aSVGToken, const OUString& aContent) override;
|
||||
virtual void decomposeSvgNode(drawinglayer::primitive2d::Primitive2DContainer& rTarget, bool bReferenced) const override;
|
||||
|
||||
/// viewBox content
|
||||
const basegfx::B2DRange* getViewBox() const { return mpViewBox.get(); }
|
||||
void setViewBox(const basegfx::B2DRange* pViewBox) { mpViewBox.reset(); if(pViewBox) mpViewBox.reset( new basegfx::B2DRange(*pViewBox) ); }
|
||||
|
||||
/// SvgAspectRatio content
|
||||
const SvgAspectRatio& getSvgAspectRatio() const { return maSvgAspectRatio; }
|
||||
|
||||
};
|
||||
|
||||
} // end of namespace svgio::svgreader
|
||||
|
||||
@@ -1591,6 +1591,21 @@ CPPUNIT_TEST_FIXTURE(Test, testTdf155733)
|
||||
assertXPath(pDocument, "/primitive2D/transform/transform/unifiedtransparence"_ostr, "transparence"_ostr, "50");
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testTdf158445)
|
||||
{
|
||||
Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/tdf158445.svg");
|
||||
CPPUNIT_ASSERT_EQUAL(1, static_cast<int>(aSequence.getLength()));
|
||||
|
||||
drawinglayer::Primitive2dXmlDump dumper;
|
||||
xmlDocUniquePtr pDocument = dumper.dumpAndParse(Primitive2DContainer(aSequence));
|
||||
|
||||
CPPUNIT_ASSERT (pDocument);
|
||||
|
||||
assertXPath(pDocument, "/primitive2D/transform/transform/transform/transform/polypolygoncolor"_ostr, "color"_ostr, "#000000");
|
||||
assertXPath(pDocument, "/primitive2D/transform/transform/transform/transform/polypolygoncolor/polypolygon"_ostr, "height"_ostr, "8.052");
|
||||
assertXPath(pDocument, "/primitive2D/transform/transform/transform/transform/polypolygoncolor/polypolygon"_ostr, "width"_ostr, "5.328");
|
||||
}
|
||||
|
||||
CPPUNIT_TEST_FIXTURE(Test, testTdf97663)
|
||||
{
|
||||
Primitive2DSequence aSequence = parseSvg(u"/svgio/qa/cppunit/data/em_units.svg");
|
||||
|
||||
@@ -0,0 +1,5 @@
|
||||
<svg width="160.353" height="30.488" xmlns="http://www.w3.org/2000/svg" viewBox="-0.376 -26.625 160.353 30.488">
|
||||
<symbol id="STIXTwoMathRegular_4275" width="5.868" height="51.216" viewBox="0 -31.524 5.868 51.216">
|
||||
<path d="M 5.868 -2.088 L 5.868 -2.088 L 5.46 0 L 0.54 0 L 0.54 -0.588 L 2.244 -2.316 Q 2.916 -2.988 3.354 -3.504 Q 3.792 -4.02 4.008 -4.542 Q 4.224 -5.064 4.224 -5.736 Q 4.224 -6.372 3.834 -6.786 Q 3.444 -7.2 2.736 -7.2 Q 2.088 -7.2 1.65 -6.942 Q 1.212 -6.684 0.876 -6.096 L 0.552 -6.252 Q 0.852 -7.092 1.482 -7.572 Q 2.112 -8.052 3.036 -8.052 Q 3.756 -8.052 4.308 -7.794 Q 4.86 -7.536 5.172 -7.056 Q 5.484 -6.576 5.484 -5.892 Q 5.484 -5.304 5.22 -4.788 Q 4.956 -4.272 4.47 -3.732 Q 3.984 -3.192 3.312 -2.532 L 1.812 -1.08 L 1.812 -0.996 L 2.748 -1.044 L 4.308 -1.044 Q 4.656 -1.044 4.842 -1.14 Q 5.028 -1.236 5.16 -1.47 Q 5.292 -1.704 5.448 -2.088 Z " viewBox="0 -31.524 5.868 51.216"/>
|
||||
</symbol>
|
||||
<use href="#STIXTwoMathRegular_4275" transform="translate(151.174 -52.774) scale(1.4)" fill="black" /></svg>
|
||||
|
After Width: | Height: | Size: 1022 B |
@@ -18,6 +18,8 @@
|
||||
*/
|
||||
|
||||
#include <svgsymbolnode.hxx>
|
||||
#include <basegfx/matrix/b2dhommatrix.hxx>
|
||||
#include <drawinglayer/primitive2d/transformprimitive2d.hxx>
|
||||
|
||||
namespace svgio::svgreader
|
||||
{
|
||||
@@ -54,9 +56,60 @@ namespace svgio::svgreader
|
||||
readLocalCssStyle(aContent);
|
||||
break;
|
||||
}
|
||||
case SVGToken::X:
|
||||
{
|
||||
SvgNumber aNum;
|
||||
|
||||
if(readSingleNumber(aContent, aNum))
|
||||
{
|
||||
maX = aNum;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SVGToken::Y:
|
||||
{
|
||||
SvgNumber aNum;
|
||||
|
||||
if(readSingleNumber(aContent, aNum))
|
||||
{
|
||||
maY = aNum;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SVGToken::Width:
|
||||
{
|
||||
SvgNumber aNum;
|
||||
|
||||
if(readSingleNumber(aContent, aNum))
|
||||
{
|
||||
if(aNum.isPositive())
|
||||
{
|
||||
maWidth = aNum;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SVGToken::Height:
|
||||
{
|
||||
SvgNumber aNum;
|
||||
|
||||
if(readSingleNumber(aContent, aNum))
|
||||
{
|
||||
if(aNum.isPositive())
|
||||
{
|
||||
maHeight = aNum;
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SVGToken::ViewBox:
|
||||
{
|
||||
readViewBox(aContent, *this);
|
||||
const basegfx::B2DRange aRange(readViewBox(aContent, *this));
|
||||
|
||||
if(!aRange.isEmpty())
|
||||
{
|
||||
setViewBox(&aRange);
|
||||
}
|
||||
break;
|
||||
}
|
||||
case SVGToken::PreserveAspectRatio:
|
||||
@@ -71,6 +124,45 @@ namespace svgio::svgreader
|
||||
}
|
||||
}
|
||||
|
||||
void SvgSymbolNode::decomposeSvgNode(drawinglayer::primitive2d::Primitive2DContainer& rTarget, bool bReferenced) const
|
||||
{
|
||||
drawinglayer::primitive2d::Primitive2DContainer aNewTarget;
|
||||
|
||||
// decompose children
|
||||
SvgNode::decomposeSvgNode(aNewTarget, bReferenced);
|
||||
|
||||
if(aNewTarget.empty())
|
||||
return;
|
||||
|
||||
if(getViewBox())
|
||||
{
|
||||
// create mapping
|
||||
// #i122610 SVG 1.1 defines in section 5.1.2 that if the attribute preserveAspectRatio is not specified,
|
||||
// then the effect is as if a value of 'xMidYMid meet' were specified.
|
||||
SvgAspectRatio aRatioDefault(SvgAlign::xMidYMid, true);
|
||||
const SvgAspectRatio& rRatio = getSvgAspectRatio().isSet()? getSvgAspectRatio() : aRatioDefault;
|
||||
|
||||
const double fX(maX.solve(*this, NumberType::xcoordinate));
|
||||
const double fY(maY.solve(*this, NumberType::ycoordinate));
|
||||
const double fWidth(maWidth.solve(*this, NumberType::xcoordinate));
|
||||
const double fHeight(maHeight.solve(*this, NumberType::ycoordinate));
|
||||
const basegfx::B2DRange aRange(fX, fY, fX + fWidth, fY + fHeight);
|
||||
|
||||
// let mapping be created from SvgAspectRatio
|
||||
const basegfx::B2DHomMatrix aEmbeddingTransform(
|
||||
rRatio.createMapping(aRange, *getViewBox()));
|
||||
|
||||
// prepare embedding in transformation
|
||||
// create embedding group element with transformation
|
||||
const drawinglayer::primitive2d::Primitive2DReference xRef(
|
||||
new drawinglayer::primitive2d::TransformPrimitive2D(
|
||||
aEmbeddingTransform,
|
||||
std::move(aNewTarget)));
|
||||
|
||||
rTarget.push_back(xRef);
|
||||
}
|
||||
}
|
||||
|
||||
} // end of namespace svgio::svgreader
|
||||
|
||||
/* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|
||||
|
||||
Reference in New Issue
Block a user