1ddde725dSArmin Le Grand /************************************************************** 2ddde725dSArmin Le Grand * 3ddde725dSArmin Le Grand * Licensed to the Apache Software Foundation (ASF) under one 4ddde725dSArmin Le Grand * or more contributor license agreements. See the NOTICE file 5ddde725dSArmin Le Grand * distributed with this work for additional information 6ddde725dSArmin Le Grand * regarding copyright ownership. The ASF licenses this file 7ddde725dSArmin Le Grand * to you under the Apache License, Version 2.0 (the 8ddde725dSArmin Le Grand * "License"); you may not use this file except in compliance 9ddde725dSArmin Le Grand * with the License. You may obtain a copy of the License at 10ddde725dSArmin Le Grand * 11ddde725dSArmin Le Grand * http://www.apache.org/licenses/LICENSE-2.0 12ddde725dSArmin Le Grand * 13ddde725dSArmin Le Grand * Unless required by applicable law or agreed to in writing, 14ddde725dSArmin Le Grand * software distributed under the License is distributed on an 15ddde725dSArmin Le Grand * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16ddde725dSArmin Le Grand * KIND, either express or implied. See the License for the 17ddde725dSArmin Le Grand * specific language governing permissions and limitations 18ddde725dSArmin Le Grand * under the License. 19ddde725dSArmin Le Grand * 20ddde725dSArmin Le Grand *************************************************************/ 21ddde725dSArmin Le Grand 22ddde725dSArmin Le Grand // MARKER(update_precomp.py): autogen include statement, do not remove 23ddde725dSArmin Le Grand #include "precompiled_drawinglayer.hxx" 24ddde725dSArmin Le Grand 25ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/cropprimitive2d.hxx> 26ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx> 27ddde725dSArmin Le Grand #include <basegfx/matrix/b2dhommatrix.hxx> 28ddde725dSArmin Le Grand #include <basegfx/matrix/b2dhommatrixtools.hxx> 29ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/transformprimitive2d.hxx> 30ddde725dSArmin Le Grand #include <basegfx/polygon/b2dpolygon.hxx> 31ddde725dSArmin Le Grand #include <basegfx/polygon/b2dpolygontools.hxx> 32ddde725dSArmin Le Grand #include <drawinglayer/primitive2d/maskprimitive2d.hxx> 33ddde725dSArmin Le Grand 34ddde725dSArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 35ddde725dSArmin Le Grand 36ddde725dSArmin Le Grand using namespace com::sun::star; 37ddde725dSArmin Le Grand 38ddde725dSArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 39ddde725dSArmin Le Grand 40ddde725dSArmin Le Grand namespace drawinglayer 41ddde725dSArmin Le Grand { 42ddde725dSArmin Le Grand namespace primitive2d 43ddde725dSArmin Le Grand { CropPrimitive2D(const Primitive2DSequence & rChildren,const basegfx::B2DHomMatrix & rTransformation,double fCropLeft,double fCropTop,double fCropRight,double fCropBottom)44ddde725dSArmin Le Grand CropPrimitive2D::CropPrimitive2D( 45ddde725dSArmin Le Grand const Primitive2DSequence& rChildren, 46ddde725dSArmin Le Grand const basegfx::B2DHomMatrix& rTransformation, 47ddde725dSArmin Le Grand double fCropLeft, 48ddde725dSArmin Le Grand double fCropTop, 49ddde725dSArmin Le Grand double fCropRight, 50ddde725dSArmin Le Grand double fCropBottom) 51ddde725dSArmin Le Grand : GroupPrimitive2D(rChildren), 52ddde725dSArmin Le Grand maTransformation(rTransformation), 53ddde725dSArmin Le Grand mfCropLeft(fCropLeft), 54ddde725dSArmin Le Grand mfCropTop(fCropTop), 55ddde725dSArmin Le Grand mfCropRight(fCropRight), 56ddde725dSArmin Le Grand mfCropBottom(fCropBottom) 57ddde725dSArmin Le Grand { 58ddde725dSArmin Le Grand } 59ddde725dSArmin Le Grand operator ==(const BasePrimitive2D & rPrimitive) const60ddde725dSArmin Le Grand bool CropPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const 61ddde725dSArmin Le Grand { 62ddde725dSArmin Le Grand if(GroupPrimitive2D::operator==(rPrimitive)) 63ddde725dSArmin Le Grand { 64ddde725dSArmin Le Grand const CropPrimitive2D& rCompare = static_cast< const CropPrimitive2D& >(rPrimitive); 65ddde725dSArmin Le Grand 66ddde725dSArmin Le Grand return (getTransformation() == rCompare.getTransformation() 67ddde725dSArmin Le Grand && getCropLeft() == rCompare.getCropLeft() 68ddde725dSArmin Le Grand && getCropTop() == rCompare.getCropTop() 69ddde725dSArmin Le Grand && getCropRight() == rCompare.getCropRight() 70ddde725dSArmin Le Grand && getCropBottom() == rCompare.getCropBottom()); 71ddde725dSArmin Le Grand } 72ddde725dSArmin Le Grand 73ddde725dSArmin Le Grand return false; 74ddde725dSArmin Le Grand } 75ddde725dSArmin Le Grand get2DDecomposition(const geometry::ViewInformation2D &) const76ddde725dSArmin Le Grand Primitive2DSequence CropPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const 77ddde725dSArmin Le Grand { 78ddde725dSArmin Le Grand Primitive2DSequence xRetval; 79ddde725dSArmin Le Grand 80ddde725dSArmin Le Grand if(getChildren().hasElements()) 81ddde725dSArmin Le Grand { 82*c0d661f1SArmin Le Grand // get original object scale in unit coordinates (no mirroring) 83*c0d661f1SArmin Le Grand const basegfx::B2DVector aObjectScale(basegfx::absolute(getTransformation() * basegfx::B2DVector(1.0, 1.0))); 84ddde725dSArmin Le Grand 85*c0d661f1SArmin Le Grand // we handle cropping, so when no width or no height, content will be empty, 86*c0d661f1SArmin Le Grand // so only do something when we have a width and a height 87*c0d661f1SArmin Le Grand if(!aObjectScale.equalZero()) 88ddde725dSArmin Le Grand { 89*c0d661f1SArmin Le Grand // calculate crop distances in unit coordinates. They are already combined with CropScaleFactor, thus 90*c0d661f1SArmin Le Grand // are relative only to object scale 91*c0d661f1SArmin Le Grand const double fBackScaleX(basegfx::fTools::equalZero(aObjectScale.getX()) ? 1.0 : 1.0 / fabs(aObjectScale.getX())); 92*c0d661f1SArmin Le Grand const double fBackScaleY(basegfx::fTools::equalZero(aObjectScale.getY()) ? 1.0 : 1.0 / fabs(aObjectScale.getY())); 93*c0d661f1SArmin Le Grand const double fLeft(getCropLeft() * fBackScaleX); 94*c0d661f1SArmin Le Grand const double fTop(getCropTop() * fBackScaleY); 95*c0d661f1SArmin Le Grand const double fRight(getCropRight() * fBackScaleX); 96*c0d661f1SArmin Le Grand const double fBottom(getCropBottom() * fBackScaleY); 97*c0d661f1SArmin Le Grand 98*c0d661f1SArmin Le Grand // calc new unit range for comparisons; the original range is the unit range 99*c0d661f1SArmin Le Grand const basegfx::B2DRange aUnitRange(0.0, 0.0, 1.0, 1.0); 100*c0d661f1SArmin Le Grand const basegfx::B2DRange aNewRange( 101*c0d661f1SArmin Le Grand -fLeft, 102*c0d661f1SArmin Le Grand -fTop, 103*c0d661f1SArmin Le Grand 1.0 + fRight, 104*c0d661f1SArmin Le Grand 1.0 + fBottom); 105*c0d661f1SArmin Le Grand 106*c0d661f1SArmin Le Grand // if we have no overlap the crop has removed everything, so we do only 107*c0d661f1SArmin Le Grand // have to create content if this is not the case 108*c0d661f1SArmin Le Grand if(aNewRange.overlaps(aUnitRange)) 109ddde725dSArmin Le Grand { 110*c0d661f1SArmin Le Grand // create new transform; first take out old transform to get 111*c0d661f1SArmin Le Grand // to unit coordinates by inverting. Inverting should be flawless 112*c0d661f1SArmin Le Grand // since we already cheched that object size is not zero in X or Y 113*c0d661f1SArmin Le Grand basegfx::B2DHomMatrix aNewTransform(getTransformation()); 114*c0d661f1SArmin Le Grand 115*c0d661f1SArmin Le Grand aNewTransform.invert(); 116*c0d661f1SArmin Le Grand 117*c0d661f1SArmin Le Grand // apply crop enlargement in unit coordinates 118*c0d661f1SArmin Le Grand aNewTransform = basegfx::tools::createScaleTranslateB2DHomMatrix( 119*c0d661f1SArmin Le Grand aNewRange.getRange(), 120*c0d661f1SArmin Le Grand aNewRange.getMinimum()) * aNewTransform; 121*c0d661f1SArmin Le Grand 122*c0d661f1SArmin Le Grand // apply original transformation. Since we have manipulated the crop 123*c0d661f1SArmin Le Grand // in unit coordinates we do not need to care about mirroring or 124*c0d661f1SArmin Le Grand // a corrected point for eventual shear or rotation, this all comes for 125*c0d661f1SArmin Le Grand // free 126*c0d661f1SArmin Le Grand aNewTransform = getTransformation() * aNewTransform; 127*c0d661f1SArmin Le Grand 128*c0d661f1SArmin Le Grand // prepare TransformPrimitive2D with xPrimitive 129*c0d661f1SArmin Le Grand const Primitive2DReference xTransformPrimitive( 130*c0d661f1SArmin Le Grand new TransformPrimitive2D( 131*c0d661f1SArmin Le Grand aNewTransform, 132*c0d661f1SArmin Le Grand getChildren())); 133*c0d661f1SArmin Le Grand 134*c0d661f1SArmin Le Grand if(aUnitRange.isInside(aNewRange)) 135*c0d661f1SArmin Le Grand { 136*c0d661f1SArmin Le Grand // the new range is completely inside the old range (unit range), 137*c0d661f1SArmin Le Grand // so no masking is needed 138*c0d661f1SArmin Le Grand xRetval = Primitive2DSequence(&xTransformPrimitive, 1); 139*c0d661f1SArmin Le Grand } 140*c0d661f1SArmin Le Grand else 141*c0d661f1SArmin Le Grand { 142*c0d661f1SArmin Le Grand // mask with original object's bounds 143*c0d661f1SArmin Le Grand basegfx::B2DPolyPolygon aMaskPolyPolygon(basegfx::tools::createUnitPolygon()); 144*c0d661f1SArmin Le Grand aMaskPolyPolygon.transform(getTransformation()); 145*c0d661f1SArmin Le Grand 146*c0d661f1SArmin Le Grand // create maskPrimitive with aMaskPolyPolygon and aMaskContentVector 147*c0d661f1SArmin Le Grand const Primitive2DReference xMask( 148*c0d661f1SArmin Le Grand new MaskPrimitive2D( 149*c0d661f1SArmin Le Grand aMaskPolyPolygon, 150*c0d661f1SArmin Le Grand Primitive2DSequence(&xTransformPrimitive, 1))); 151*c0d661f1SArmin Le Grand 152*c0d661f1SArmin Le Grand xRetval = Primitive2DSequence(&xMask, 1); 153*c0d661f1SArmin Le Grand } 154ddde725dSArmin Le Grand } 155ddde725dSArmin Le Grand } 156ddde725dSArmin Le Grand } 157ddde725dSArmin Le Grand 158ddde725dSArmin Le Grand return xRetval; 159ddde725dSArmin Le Grand } 160ddde725dSArmin Le Grand 161ddde725dSArmin Le Grand // provide unique ID 162ddde725dSArmin Le Grand ImplPrimitrive2DIDBlock(CropPrimitive2D, PRIMITIVE2D_ID_CROPPRIMITIVE2D) 163ddde725dSArmin Le Grand 164ddde725dSArmin Le Grand } // end of namespace primitive2d 165ddde725dSArmin Le Grand } // end of namespace drawinglayer 166ddde725dSArmin Le Grand 167ddde725dSArmin Le Grand ////////////////////////////////////////////////////////////////////////////// 168ddde725dSArmin Le Grand // eof 169