[Libreoffice-commits] core.git: Branch 'aoo/trunk' - drawinglayer/source svx/inc svx/source

Armin Le Grand alg at apache.org
Wed Jan 22 20:07:31 PST 2014


 drawinglayer/source/primitive2d/cropprimitive2d.cxx |  172 ++++++++------------
 svx/inc/svx/sdr/contact/viewcontactofgraphic.hxx    |    3 
 svx/source/sdr/contact/viewcontactofgraphic.cxx     |    8 
 3 files changed, 74 insertions(+), 109 deletions(-)

New commits:
commit 08d42c4da0a3f6dc105080102c1b1de4bce987a1
Author: Armin Le Grand <alg at apache.org>
Date:   Thu Jan 23 02:12:41 2014 +0000

    i123950 unified and redefined CropPrimitive2D::get2DDecomposition

diff --git a/drawinglayer/source/primitive2d/cropprimitive2d.cxx b/drawinglayer/source/primitive2d/cropprimitive2d.cxx
index 76dd206..371d871 100644
--- a/drawinglayer/source/primitive2d/cropprimitive2d.cxx
+++ b/drawinglayer/source/primitive2d/cropprimitive2d.cxx
@@ -79,112 +79,78 @@ namespace drawinglayer
 
             if(getChildren().hasElements())
             {
-                // decompose to have current translate and scale
-                basegfx::B2DVector aScale, aTranslate;
-                double fRotate, fShearX;
-
-                getTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
-
-                // detect 180 degree rotation, this is the same as mirrored in X and Y,
-                // thus change to mirroring. Prefer mirroring here. Use the equal call
-                // with getSmallValue here, the original which uses rtl::math::approxEqual
-                // is too correct here. Maybe this changes with enhanced precision in aw080
-                // to the better so that this can be reduced to the more precise call again
-                if(basegfx::fTools::equal(fabs(fRotate), F_PI, 0.000000001))
-                {
-                    aScale.setX(aScale.getX() * -1.0);
-                    aScale.setY(aScale.getY() * -1.0);
-                    fRotate = 0.0;
-                }
-
-                // create target translate and scale
-                const bool bMirroredX(aScale.getX() < 0.0);
-                const bool bMirroredY(aScale.getY() < 0.0);
-                basegfx::B2DVector aTargetScale(aScale);
-                basegfx::B2DVector aTargetTranslate(aTranslate);
-
-                if(bMirroredX)
-                {
-                    aTargetTranslate.setX(aTargetTranslate.getX() + getCropRight());
-                    aTargetScale.setX(aTargetScale.getX() - getCropLeft() - getCropRight());
-                }
-                else
-                {
-                    aTargetTranslate.setX(aTargetTranslate.getX() - getCropLeft());
-                    aTargetScale.setX(aTargetScale.getX() + getCropRight() + getCropLeft());
-                }
-
-                if(bMirroredY)
-                {
-                    aTargetTranslate.setY(aTargetTranslate.getY() + getCropBottom());
-                    aTargetScale.setY(aTargetScale.getY() - getCropTop() - getCropBottom());
-                }
-                else
-                {
-                    aTargetTranslate.setY(aTargetTranslate.getY() - getCropTop());
-                    aTargetScale.setY(aTargetScale.getY() + getCropBottom() + getCropTop());
-                }
-
-                // create ranges to make comparisons
-                const basegfx::B2DRange aCurrent(
-                    aTranslate.getX(), aTranslate.getY(),
-                    aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
-                const basegfx::B2DRange aCropped(
-                    aTargetTranslate.getX(), aTargetTranslate.getY(),
-                    aTargetTranslate.getX() + aTargetScale.getX(), aTargetTranslate.getY() + aTargetScale.getY());
+                // get original object scale in unit coordinates (no mirroring)
+                const basegfx::B2DVector aObjectScale(basegfx::absolute(getTransformation() * basegfx::B2DVector(1.0, 1.0)));
 
-                if(aCropped.isEmpty())
+                // we handle cropping, so when no width or no height, content will be empty,
+                // so only do something when we have a width and a height
+                if(!aObjectScale.equalZero())
                 {
-                    // nothing to return since cropped content is completely empty
-                }
-                else if(aCurrent.equal(aCropped))
-                {
-                    // no crop, just use content
-                    xRetval = getChildren();
-                }
-                else
-                {
-                    // build new combined content transformation
-                    basegfx::B2DHomMatrix aNewObjectTransform(getTransformation());
-
-                    // remove content transform by inverting
-                    aNewObjectTransform.invert();
-
-                    // add target values and original shear/rotate
-                    aNewObjectTransform = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
-                        aTargetScale.getX(),
-                        aTargetScale.getY(),
-                        fShearX,
-                        fRotate,
-                        aTargetTranslate.getX(),
-                        aTargetTranslate.getY())
-                            * aNewObjectTransform;
-
-                    // prepare TransformPrimitive2D with xPrimitive
-                    const Primitive2DReference xTransformPrimitive(
-                        new TransformPrimitive2D(
-                            aNewObjectTransform,
-                            getChildren()));
-
-                    if(aCurrent.isInside(aCropped))
-                    {
-                        // crop just shrunk so that its inside content,
-                        // no need to use a mask since not really cropped.
-                        xRetval = Primitive2DSequence(&xTransformPrimitive, 1);
-                    }
-                    else
+                    // calculate crop distances in unit coordinates. They are already combined with CropScaleFactor, thus
+                    // are relative only to object scale
+                    const double fBackScaleX(basegfx::fTools::equalZero(aObjectScale.getX()) ? 1.0 : 1.0 / fabs(aObjectScale.getX()));
+                    const double fBackScaleY(basegfx::fTools::equalZero(aObjectScale.getY()) ? 1.0 : 1.0 / fabs(aObjectScale.getY()));
+                    const double fLeft(getCropLeft() * fBackScaleX);
+                    const double fTop(getCropTop() * fBackScaleY);
+                    const double fRight(getCropRight() * fBackScaleX);
+                    const double fBottom(getCropBottom() * fBackScaleY);
+
+                    // calc new unit range for comparisons; the original range is the unit range
+                    const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0);
+                    const basegfx::B2DRange aNewRange(
+                        -fLeft,
+                        -fTop,
+                        1.0 + fRight,
+                        1.0 + fBottom);
+
+                    // if we have no overlap the crop has removed everything, so we do only
+                    // have to create content if this is not the case
+                    if(aNewRange.overlaps(aUnitRange))
                     {
-                        // mask with original object's bounds
-                        basegfx::B2DPolyPolygon aMaskPolyPolygon(basegfx::tools::createUnitPolygon());
-                        aMaskPolyPolygon.transform(getTransformation());
-
-                        // create maskPrimitive with aMaskPolyPolygon and aMaskContentVector
-                        const Primitive2DReference xMask(
-                            new MaskPrimitive2D(
-                                aMaskPolyPolygon,
-                                Primitive2DSequence(&xTransformPrimitive, 1)));
-
-                        xRetval = Primitive2DSequence(&xMask, 1);
+                        // create new transform; first take out old transform to get
+                        // to unit coordinates by inverting. Inverting should be flawless
+                        // since we already cheched that object size is not zero in X or Y
+                        basegfx::B2DHomMatrix aNewTransform(getTransformation());
+
+                        aNewTransform.invert();
+
+                        // apply crop enlargement in unit coordinates
+                        aNewTransform = basegfx::tools::createScaleTranslateB2DHomMatrix(
+                            aNewRange.getRange(),
+                            aNewRange.getMinimum()) * aNewTransform;
+
+                        // apply original transformation. Since we have manipulated the crop
+                        // in unit coordinates we do not need to care about mirroring or
+                        // a corrected point for eventual shear or rotation, this all comes for
+                        // free
+                        aNewTransform = getTransformation() * aNewTransform;
+
+                        // prepare TransformPrimitive2D with xPrimitive
+                        const Primitive2DReference xTransformPrimitive(
+                            new TransformPrimitive2D(
+                                aNewTransform,
+                                getChildren()));
+
+                        if(aUnitRange.isInside(aNewRange))
+                        {
+                            // the new range is completely inside the old range (unit range),
+                            // so no masking is needed
+                            xRetval = Primitive2DSequence(&xTransformPrimitive, 1);
+                        }
+                        else
+                        {
+                            // mask with original object's bounds
+                            basegfx::B2DPolyPolygon aMaskPolyPolygon(basegfx::tools::createUnitPolygon());
+                            aMaskPolyPolygon.transform(getTransformation());
+
+                            // create maskPrimitive with aMaskPolyPolygon and aMaskContentVector
+                            const Primitive2DReference xMask(
+                                new MaskPrimitive2D(
+                                    aMaskPolyPolygon,
+                                    Primitive2DSequence(&xTransformPrimitive, 1)));
+
+                            xRetval = Primitive2DSequence(&xMask, 1);
+                        }
                     }
                 }
             }
diff --git a/svx/inc/svx/sdr/contact/viewcontactofgraphic.hxx b/svx/inc/svx/sdr/contact/viewcontactofgraphic.hxx
index 4344350..f3d2340 100644
--- a/svx/inc/svx/sdr/contact/viewcontactofgraphic.hxx
+++ b/svx/inc/svx/sdr/contact/viewcontactofgraphic.hxx
@@ -46,8 +46,7 @@ namespace sdr
             // helpers for constructing various primitive visualisations in various states
             drawinglayer::primitive2d::Primitive2DSequence createVIP2DSForPresObj(
                 const basegfx::B2DHomMatrix& rObjectMatrix,
-                const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute,
-                const GraphicAttr& rLocalGrafInfo) const;
+                const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute) const;
             drawinglayer::primitive2d::Primitive2DSequence createVIP2DSForDraft(
                 const basegfx::B2DHomMatrix& rObjectMatrix,
                 const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute) const;
diff --git a/svx/source/sdr/contact/viewcontactofgraphic.cxx b/svx/source/sdr/contact/viewcontactofgraphic.cxx
index 543e826..048e760 100644
--- a/svx/source/sdr/contact/viewcontactofgraphic.cxx
+++ b/svx/source/sdr/contact/viewcontactofgraphic.cxx
@@ -93,8 +93,7 @@ namespace sdr
 
         drawinglayer::primitive2d::Primitive2DSequence ViewContactOfGraphic::createVIP2DSForPresObj(
             const basegfx::B2DHomMatrix& rObjectMatrix,
-            const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute,
-            const GraphicAttr& rLocalGrafInfo) const
+            const drawinglayer::attribute::SdrLineFillShadowTextAttribute& rAttribute) const
         {
             drawinglayer::primitive2d::Primitive2DSequence xRetval;
             GraphicObject aEmptyGraphicObject;
@@ -143,11 +142,12 @@ namespace sdr
                     * aSmallerMatrix;
 
                 const GraphicObject& rGraphicObject = GetGrafObject().GetGraphicObject(false);
+                const GraphicAttr aLocalGrafInfo;
                 const drawinglayer::primitive2d::Primitive2DReference xReferenceB(new drawinglayer::primitive2d::SdrGrafPrimitive2D(
                     aSmallerMatrix,
                     drawinglayer::attribute::SdrLineFillShadowTextAttribute(),
                     rGraphicObject,
-                    rLocalGrafInfo));
+                    aLocalGrafInfo));
 
                 drawinglayer::primitive2d::appendPrimitive2DReferenceToPrimitive2DSequence(xRetval, xReferenceB);
             }
@@ -379,7 +379,7 @@ namespace sdr
             {
                 // it's an EmptyPresObj, create the SdrGrafPrimitive2D without content and another scaled one
                 // with the content which is the placeholder graphic
-                xRetval = createVIP2DSForPresObj(aObjectMatrix, aAttribute, aLocalGrafInfo);
+                xRetval = createVIP2DSForPresObj(aObjectMatrix, aAttribute);
             }
             else if(visualisationUsesDraft())
             {


More information about the Libreoffice-commits mailing list