Resolves: #i123950# unified and redefined CropPrimitive2D::get2DDecomposition
(cherry picked from commit 08d42c4da0a3f6dc105080102c1b1de4bce987a1) Change-Id: I2d5f52de8e9fa595012a953affbaba9d54f4f2a9
This commit is contained in:
committed by
Caolán McNamara
parent
55d2f55ddf
commit
fb0cce507f
@@ -74,97 +74,62 @@ namespace drawinglayer
|
||||
|
||||
if(getChildren().hasElements())
|
||||
{
|
||||
// decompose to have current translate and scale
|
||||
basegfx::B2DVector aScale, aTranslate;
|
||||
double fRotate, fShearX;
|
||||
// get original object scale in unit coordinates (no mirroring)
|
||||
const basegfx::B2DVector aObjectScale(basegfx::absolute(getTransformation() * basegfx::B2DVector(1.0, 1.0)));
|
||||
|
||||
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))
|
||||
// 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())
|
||||
{
|
||||
aScale.setX(aScale.getX() * -1.0);
|
||||
aScale.setY(aScale.getY() * -1.0);
|
||||
fRotate = 0.0;
|
||||
}
|
||||
// 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);
|
||||
|
||||
// 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);
|
||||
// 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(bMirroredX)
|
||||
// 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))
|
||||
{
|
||||
aTargetTranslate.setX(aTargetTranslate.getX() + getCropRight());
|
||||
aTargetScale.setX(aTargetScale.getX() - getCropLeft() - getCropRight());
|
||||
}
|
||||
else
|
||||
{
|
||||
aTargetTranslate.setX(aTargetTranslate.getX() - getCropLeft());
|
||||
aTargetScale.setX(aTargetScale.getX() + getCropRight() + getCropLeft());
|
||||
}
|
||||
// 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());
|
||||
|
||||
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());
|
||||
}
|
||||
aNewTransform.invert();
|
||||
|
||||
// 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());
|
||||
// apply crop enlargement in unit coordinates
|
||||
aNewTransform = basegfx::tools::createScaleTranslateB2DHomMatrix(
|
||||
aNewRange.getRange(),
|
||||
aNewRange.getMinimum()) * aNewTransform;
|
||||
|
||||
if(aCropped.isEmpty())
|
||||
{
|
||||
// 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;
|
||||
// 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(
|
||||
aNewObjectTransform,
|
||||
aNewTransform,
|
||||
getChildren()));
|
||||
|
||||
if(aCurrent.isInside(aCropped))
|
||||
if(aUnitRange.isInside(aNewRange))
|
||||
{
|
||||
// crop just shrunk so that its inside content,
|
||||
// no need to use a mask since not really cropped.
|
||||
// the new range is completely inside the old range (unit range),
|
||||
// so no masking is needed
|
||||
xRetval = Primitive2DSequence(&xTransformPrimitive, 1);
|
||||
}
|
||||
else
|
||||
@@ -183,6 +148,7 @@ namespace drawinglayer
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return xRetval;
|
||||
}
|
||||
|
@@ -42,8 +42,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;
|
||||
|
@@ -83,8 +83,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;
|
||||
@@ -133,11 +132,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);
|
||||
}
|
||||
@@ -373,7 +373,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())
|
||||
{
|
||||
|
Reference in New Issue
Block a user