fdo#74697 Add Bluez 5 support for impress remote.
[LibreOffice.git] / drawinglayer / source / primitive2d / cropprimitive2d.cxx
blob8ce933afffe23d9496002dfede54c9cfe0c39038
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include <drawinglayer/primitive2d/cropprimitive2d.hxx>
21 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
22 #include <basegfx/matrix/b2dhommatrix.hxx>
23 #include <basegfx/matrix/b2dhommatrixtools.hxx>
24 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
25 #include <basegfx/polygon/b2dpolygon.hxx>
26 #include <basegfx/polygon/b2dpolygontools.hxx>
27 #include <drawinglayer/primitive2d/maskprimitive2d.hxx>
29 //////////////////////////////////////////////////////////////////////////////
31 using namespace com::sun::star;
33 //////////////////////////////////////////////////////////////////////////////
35 namespace drawinglayer
37 namespace primitive2d
39 CropPrimitive2D::CropPrimitive2D(
40 const Primitive2DSequence& rChildren,
41 const basegfx::B2DHomMatrix& rTransformation,
42 double fCropLeft,
43 double fCropTop,
44 double fCropRight,
45 double fCropBottom)
46 : GroupPrimitive2D(rChildren),
47 maTransformation(rTransformation),
48 mfCropLeft(fCropLeft),
49 mfCropTop(fCropTop),
50 mfCropRight(fCropRight),
51 mfCropBottom(fCropBottom)
55 bool CropPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
57 if(GroupPrimitive2D::operator==(rPrimitive))
59 const CropPrimitive2D& rCompare = static_cast< const CropPrimitive2D& >(rPrimitive);
61 return (getTransformation() == rCompare.getTransformation()
62 && getCropLeft() == rCompare.getCropLeft()
63 && getCropTop() == rCompare.getCropTop()
64 && getCropRight() == rCompare.getCropRight()
65 && getCropBottom() == rCompare.getCropBottom());
68 return false;
71 Primitive2DSequence CropPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
73 Primitive2DSequence xRetval;
75 if(getChildren().hasElements())
77 // decompose to have current translate and scale
78 basegfx::B2DVector aScale, aTranslate;
79 double fRotate, fShearX;
81 getTransformation().decompose(aScale, aTranslate, fRotate, fShearX);
83 // detect 180 degree rotation, this is the same as mirrored in X and Y,
84 // thus change to mirroring. Prefer mirroring here. Use the equal call
85 // with getSmallValue here, the original which uses rtl::math::approxEqual
86 // is too correct here. Maybe this changes with enhanced precision in aw080
87 // to the better so that this can be reduced to the more precise call again
88 if(basegfx::fTools::equal(fRotate, F_PI, 0.000000001))
90 aScale.setX(aScale.getX() * -1.0);
91 aScale.setY(aScale.getY() * -1.0);
92 fRotate = 0.0;
95 // create target translate and scale
96 const bool bMirroredX(aScale.getX() < 0.0);
97 const bool bMirroredY(aScale.getY() < 0.0);
98 basegfx::B2DVector aTargetScale(aScale);
99 basegfx::B2DVector aTargetTranslate(aTranslate);
101 if(bMirroredX)
103 aTargetTranslate.setX(aTargetTranslate.getX() + getCropRight());
104 aTargetScale.setX(aTargetScale.getX() - getCropLeft() - getCropRight());
106 else
108 aTargetTranslate.setX(aTargetTranslate.getX() - getCropLeft());
109 aTargetScale.setX(aTargetScale.getX() + getCropRight() + getCropLeft());
112 if(bMirroredY)
114 aTargetTranslate.setY(aTargetTranslate.getY() + getCropBottom());
115 aTargetScale.setY(aTargetScale.getY() - getCropTop() - getCropBottom());
117 else
119 aTargetTranslate.setY(aTargetTranslate.getY() - getCropTop());
120 aTargetScale.setY(aTargetScale.getY() + getCropBottom() + getCropTop());
123 // create ranges to make comparisons
124 const basegfx::B2DRange aCurrent(
125 aTranslate.getX(), aTranslate.getY(),
126 aTranslate.getX() + aScale.getX(), aTranslate.getY() + aScale.getY());
127 const basegfx::B2DRange aCropped(
128 aTargetTranslate.getX(), aTargetTranslate.getY(),
129 aTargetTranslate.getX() + aTargetScale.getX(), aTargetTranslate.getY() + aTargetScale.getY());
131 if(aCropped.isEmpty())
133 // nothing to return since cropped content is completely empty
135 else if(aCurrent.equal(aCropped))
137 // no crop, just use content
138 xRetval = getChildren();
140 else
142 // build new combined content transformation
143 basegfx::B2DHomMatrix aNewObjectTransform(getTransformation());
145 // remove content transform by inverting
146 aNewObjectTransform.invert();
148 // add target values and original shear/rotate
149 aNewObjectTransform = basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
150 aTargetScale.getX(),
151 aTargetScale.getY(),
152 fShearX,
153 fRotate,
154 aTargetTranslate.getX(),
155 aTargetTranslate.getY())
156 * aNewObjectTransform;
158 // prepare TransformPrimitive2D with xPrimitive
159 const Primitive2DReference xTransformPrimitive(
160 new TransformPrimitive2D(
161 aNewObjectTransform,
162 getChildren()));
164 if(aCurrent.isInside(aCropped))
166 // crop just shrunk so that its inside content,
167 // no need to use a mask since not really cropped.
168 xRetval = Primitive2DSequence(&xTransformPrimitive, 1);
170 else
172 // mask with original object's bounds
173 basegfx::B2DPolyPolygon aMaskPolyPolygon(basegfx::tools::createUnitPolygon());
174 aMaskPolyPolygon.transform(getTransformation());
176 // create maskPrimitive with aMaskPolyPolygon and aMaskContentVector
177 const Primitive2DReference xMask(
178 new MaskPrimitive2D(
179 aMaskPolyPolygon,
180 Primitive2DSequence(&xTransformPrimitive, 1)));
182 xRetval = Primitive2DSequence(&xMask, 1);
187 return xRetval;
190 // provide unique ID
191 ImplPrimitive2DIDBlock(CropPrimitive2D, PRIMITIVE2D_ID_CROPPRIMITIVE2D)
193 } // end of namespace primitive2d
194 } // end of namespace drawinglayer
196 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */