// get original object scale in unit coordinates (no mirroring) const basegfx::B2DVector aObjectScale(basegfx::absolute(getTransformation() * basegfx::B2DVector(1.0, 1.0)));
// 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()) return;
// calculate crop distances in unit coordinates. They are already combined with CropScaleFactor, thus // are relative only to object scale constdouble fBackScaleX(basegfx::fTools::equalZero(aObjectScale.getX()) ? 1.0 : 1.0 / fabs(aObjectScale.getX())); constdouble fBackScaleY(basegfx::fTools::equalZero(aObjectScale.getY()) ? 1.0 : 1.0 / fabs(aObjectScale.getY())); constdouble fLeft(getCropLeft() * fBackScaleX); constdouble fTop(getCropTop() * fBackScaleY); constdouble fRight(getCropRight() * fBackScaleX); constdouble 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)) return;
// create new transform; first take out old transform to get // to unit coordinates by inverting. Inverting should be flawless // since we already checked that object size is not zero in X or Y
basegfx::B2DHomMatrix aNewTransform(getTransformation());
aNewTransform.invert();
// apply crop enlargement in unit coordinates
aNewTransform = basegfx::utils::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 a possible shear or rotation, this all comes for // free
aNewTransform = getTransformation() * aNewTransform;
// prepare TransformPrimitive2D with xPrimitive const Primitive2DReference xTransformPrimitive( new TransformPrimitive2D(
aNewTransform,
Primitive2DContainer(getChildren())));
if(aUnitRange.isInside(aNewRange))
{ // the new range is completely inside the old range (unit range), // so no masking is needed
rVisitor.visit(xTransformPrimitive);
} else
{ // mask with original object's bounds
basegfx::B2DPolyPolygon aMaskPolyPolygon(basegfx::utils::createUnitPolygon());
aMaskPolyPolygon.transform(getTransformation());
// create maskPrimitive with aMaskPolyPolygon and aMaskContentVector const Primitive2DReference xMask( new MaskPrimitive2D(
std::move(aMaskPolyPolygon),
Primitive2DContainer { xTransformPrimitive }));
rVisitor.visit(xMask);
}
}
// provide unique ID
sal_uInt32 CropPrimitive2D::getPrimitive2DID() const
{ return PRIMITIVE2D_ID_CROPPRIMITIVE2D;
}
Die Informationen auf dieser Webseite wurden
nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit,
noch Qualität der bereit gestellten Informationen zugesichert.
Bemerkung:
Die farbliche Syntaxdarstellung und die Messung sind noch experimentell.