summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorArmin Le Grand <Armin.Le.Grand@cib.de>2016-01-27 00:15:53 +0100
committerArmin Le Grand <Armin.Le.Grand@cib.de>2016-02-05 09:24:44 +0000
commit080e5f2f24513e871f2563c88a69fa8a9ecfe0eb (patch)
tree2eff85ac57ed00fba3fd94b17962497b3ec8ed1b
parent10ed6326346ea44202f75e87cce99d2aab8c7939 (diff)
SVGIO: tdf#97383: Keep ratio in embedded images...
... when height and width are different SVG specifies embedded graphics to keep their aspect ratio (thanks to Regina for pointing out). To implement this for Office SVG import, I had to correctly set the graphic data unit dimensions to make the existing SvgAspectRatio mapping work. All together this now simplifies this method and packs all in clean linear transformations in the created stack of drwainglayer primitives. Change-Id: Id80c2f74ffb148085085b2c9627bc31bc15bdee5 Reviewed-on: https://gerrit.libreoffice.org/21830 Reviewed-by: Armin Le Grand <Armin.Le.Grand@cib.de> Tested-by: Armin Le Grand <Armin.Le.Grand@cib.de>
-rw-r--r--svgio/source/svgreader/svgimagenode.cxx100
-rw-r--r--svgio/source/svgreader/svgtools.cxx4
2 files changed, 59 insertions, 45 deletions
diff --git a/svgio/source/svgreader/svgimagenode.cxx b/svgio/source/svgreader/svgimagenode.cxx
index a53798a45d24..d58dd716b8cd 100644
--- a/svgio/source/svgreader/svgimagenode.cxx
+++ b/svgio/source/svgreader/svgimagenode.cxx
@@ -271,16 +271,45 @@ namespace svgio
}
}
- if(!aBitmapEx.IsEmpty())
+ if(!aBitmapEx.IsEmpty() && 0 != aBitmapEx.GetSizePixel().Width() && 0 != aBitmapEx.GetSizePixel().Height())
{
- // create content from created bitmap
+ // calculate centered unit size
+ const double fAspectRatio = (double)aBitmapEx.GetSizePixel().Width() / (double)aBitmapEx.GetSizePixel().Height();
+
+ if(basegfx::fTools::equal(fAspectRatio, 0.0))
+ {
+ // use unit range
+ aViewBox = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0);
+ }
+ else if(basegfx::fTools::more(fAspectRatio, 0.0))
+ {
+ // width bigger height
+ const double fHalfHeight((1.0 / fAspectRatio) * 0.5);
+ aViewBox = basegfx::B2DRange(
+ 0.0,
+ 0.5 - fHalfHeight,
+ 1.0,
+ 0.5 + fHalfHeight);
+ }
+ else
+ {
+ // height bigger width
+ const double fHalfWidth(fAspectRatio * 0.5);
+ aViewBox = basegfx::B2DRange(
+ 0.5 - fHalfWidth,
+ 0.0,
+ 0.5 + fHalfWidth,
+ 1.0);
+ }
+
+ // create content from created bitmap, use calculated unit range size
+ // as transformation to map the picture data correctly
aNewTarget.resize(1);
aNewTarget[0] = new drawinglayer::primitive2d::BitmapPrimitive2D(
aBitmapEx,
- basegfx::B2DHomMatrix());
-
- // fill aViewBox. No size set yet, use unit size
- aViewBox = basegfx::B2DRange(0.0, 0.0, 1.0, 1.0);
+ basegfx::tools::createScaleTranslateB2DHomMatrix(
+ aViewBox.getRange(),
+ aViewBox.getMinimum()));
}
if(!aNewTarget.empty())
@@ -295,47 +324,30 @@ namespace svgio
// create mapping
const SvgAspectRatio& rRatio = getSvgAspectRatio();
- if(rRatio.isSet())
+ // even when ratio is not set, use the defaults
+ // let mapping be created from SvgAspectRatio
+ const basegfx::B2DHomMatrix aEmbeddingTransform(rRatio.createMapping(aTarget, aViewBox));
+
+ if(!aEmbeddingTransform.isIdentity())
{
- // let mapping be created from SvgAspectRatio
- const basegfx::B2DHomMatrix aEmbeddingTransform(rRatio.createMapping(aTarget, aViewBox));
-
- if(!aEmbeddingTransform.isIdentity())
- {
- const drawinglayer::primitive2d::Primitive2DReference xRef(
- new drawinglayer::primitive2d::TransformPrimitive2D(
- aEmbeddingTransform,
- aNewTarget));
-
- aNewTarget = drawinglayer::primitive2d::Primitive2DContainer { xRef };
- }
-
- if(!rRatio.isMeetOrSlice())
- {
- // need to embed in MaskPrimitive2D to ensure clipping
- const drawinglayer::primitive2d::Primitive2DReference xMask(
- new drawinglayer::primitive2d::MaskPrimitive2D(
- basegfx::B2DPolyPolygon(
- basegfx::tools::createPolygonFromRect(aTarget)),
- aNewTarget));
-
- aNewTarget = drawinglayer::primitive2d::Primitive2DContainer { xMask };
- }
+ const drawinglayer::primitive2d::Primitive2DReference xRef(
+ new drawinglayer::primitive2d::TransformPrimitive2D(
+ aEmbeddingTransform,
+ aNewTarget));
+
+ aNewTarget = drawinglayer::primitive2d::Primitive2DContainer { xRef };
}
- else
+
+ if(!rRatio.isMeetOrSlice())
{
- // choose default mapping
- const basegfx::B2DHomMatrix aEmbeddingTransform(SvgAspectRatio::createLinearMapping(aTarget, aViewBox));
-
- if(!aEmbeddingTransform.isIdentity())
- {
- const drawinglayer::primitive2d::Primitive2DReference xRef(
- new drawinglayer::primitive2d::TransformPrimitive2D(
- aEmbeddingTransform,
- aNewTarget));
-
- aNewTarget = drawinglayer::primitive2d::Primitive2DContainer { xRef };
- }
+ // need to embed in MaskPrimitive2D to ensure clipping
+ const drawinglayer::primitive2d::Primitive2DReference xMask(
+ new drawinglayer::primitive2d::MaskPrimitive2D(
+ basegfx::B2DPolyPolygon(
+ basegfx::tools::createPolygonFromRect(aTarget)),
+ aNewTarget));
+
+ aNewTarget = drawinglayer::primitive2d::Primitive2DContainer { xMask };
}
// embed and add to rTarget, take local extra-transform into account
diff --git a/svgio/source/svgreader/svgtools.cxx b/svgio/source/svgreader/svgtools.cxx
index 349fd292f595..ff74d63061aa 100644
--- a/svgio/source/svgreader/svgtools.cxx
+++ b/svgio/source/svgreader/svgtools.cxx
@@ -67,7 +67,9 @@ namespace svgio
basegfx::B2DHomMatrix SvgAspectRatio::createMapping(const basegfx::B2DRange& rTarget, const basegfx::B2DRange& rSource) const
{
- if(!isSet() || Align_none == getSvgAlign())
+ // removed !isSet() from below. Due to correct defaults in the constructor an instance
+ // of this class is perfectly useful without being set by any importer
+ if(Align_none == getSvgAlign())
{
// create linear mapping (default)
return createLinearMapping(rTarget, rSource);