1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
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/discreteshadowprimitive2d.hxx>
21 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
22 #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
23 #include <basegfx/matrix/b2dhommatrixtools.hxx>
24 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
25 #include <drawinglayer/geometry/viewinformation2d.hxx>
26 #include <osl/diagnose.h>
27 #include <toolkit/helper/vclunohelper.hxx>
30 namespace drawinglayer::primitive2d
32 DiscreteShadow::DiscreteShadow(const BitmapEx
& rBitmapEx
)
33 : maBitmapEx(rBitmapEx
)
35 const Size
& rBitmapSize
= getBitmapEx().GetSizePixel();
37 if(rBitmapSize
.Width() != rBitmapSize
.Height() || rBitmapSize
.Width() < 7)
39 OSL_ENSURE(false, "DiscreteShadowPrimitive2D: wrong bitmap format (!)");
40 maBitmapEx
= BitmapEx();
44 const BitmapEx
& DiscreteShadow::getTopLeft() const
46 if(maTopLeft
.IsEmpty())
48 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
49 const_cast< DiscreteShadow
* >(this)->maTopLeft
= getBitmapEx();
50 const_cast< DiscreteShadow
* >(this)->maTopLeft
.Crop(
51 ::tools::Rectangle(Point(0, 0), Size((nQuarter
* 2) + 1, (nQuarter
* 2) + 1)));
57 const BitmapEx
& DiscreteShadow::getTop() const
61 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
62 const_cast< DiscreteShadow
* >(this)->maTop
= getBitmapEx();
63 const_cast< DiscreteShadow
* >(this)->maTop
.Crop(
64 ::tools::Rectangle(Point((nQuarter
* 2) + 1, 0), Size(1, nQuarter
)));
70 const BitmapEx
& DiscreteShadow::getTopRight() const
72 if(maTopRight
.IsEmpty())
74 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
75 const_cast< DiscreteShadow
* >(this)->maTopRight
= getBitmapEx();
76 const_cast< DiscreteShadow
* >(this)->maTopRight
.Crop(
77 ::tools::Rectangle(Point((nQuarter
* 2) + 2, 0), Size((nQuarter
* 2) + 1, (nQuarter
* 2) + 1)));
83 const BitmapEx
& DiscreteShadow::getRight() const
87 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
88 const_cast< DiscreteShadow
* >(this)->maRight
= getBitmapEx();
89 const_cast< DiscreteShadow
* >(this)->maRight
.Crop(
90 ::tools::Rectangle(Point((nQuarter
* 3) + 3, (nQuarter
* 2) + 1), Size(nQuarter
, 1)));
96 const BitmapEx
& DiscreteShadow::getBottomRight() const
98 if(maBottomRight
.IsEmpty())
100 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
101 const_cast< DiscreteShadow
* >(this)->maBottomRight
= getBitmapEx();
102 const_cast< DiscreteShadow
* >(this)->maBottomRight
.Crop(
103 ::tools::Rectangle(Point((nQuarter
* 2) + 2, (nQuarter
* 2) + 2), Size((nQuarter
* 2) + 1, (nQuarter
* 2) + 1)));
106 return maBottomRight
;
109 const BitmapEx
& DiscreteShadow::getBottom() const
111 if(maBottom
.IsEmpty())
113 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
114 const_cast< DiscreteShadow
* >(this)->maBottom
= getBitmapEx();
115 const_cast< DiscreteShadow
* >(this)->maBottom
.Crop(
116 ::tools::Rectangle(Point((nQuarter
* 2) + 1, (nQuarter
* 3) + 3), Size(1, nQuarter
)));
122 const BitmapEx
& DiscreteShadow::getBottomLeft() const
124 if(maBottomLeft
.IsEmpty())
126 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
127 const_cast< DiscreteShadow
* >(this)->maBottomLeft
= getBitmapEx();
128 const_cast< DiscreteShadow
* >(this)->maBottomLeft
.Crop(
129 ::tools::Rectangle(Point(0, (nQuarter
* 2) + 2), Size((nQuarter
* 2) + 1, (nQuarter
* 2) + 1)));
135 const BitmapEx
& DiscreteShadow::getLeft() const
139 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
140 const_cast< DiscreteShadow
* >(this)->maLeft
= getBitmapEx();
141 const_cast< DiscreteShadow
* >(this)->maLeft
.Crop(
142 ::tools::Rectangle(Point(0, (nQuarter
* 2) + 1), Size(nQuarter
, 1)));
148 } // end of namespace
151 namespace drawinglayer::primitive2d
153 void DiscreteShadowPrimitive2D::create2DDecomposition(Primitive2DContainer
& rContainer
, const geometry::ViewInformation2D
& /*rViewInformation*/) const
155 Primitive2DContainer xRetval
;
157 if(getDiscreteShadow().getBitmapEx().IsEmpty())
160 const sal_Int32
nQuarter((getDiscreteShadow().getBitmapEx().GetSizePixel().Width() - 3) >> 2);
161 const basegfx::B2DVector
aScale(getTransform() * basegfx::B2DVector(1.0, 1.0));
162 const double fSingleX(getDiscreteUnit() / aScale
.getX());
163 const double fSingleY(getDiscreteUnit() / aScale
.getY());
164 const double fBorderX(fSingleX
* nQuarter
);
165 const double fBorderY(fSingleY
* nQuarter
);
166 const double fBigLenX((fBorderX
* 2.0) + fSingleX
);
167 const double fBigLenY((fBorderY
* 2.0) + fSingleY
);
172 xRetval
[0] = Primitive2DReference(
173 new BitmapPrimitive2D(
174 getDiscreteShadow().getTopLeft(),
175 basegfx::utils::createScaleTranslateB2DHomMatrix(
182 xRetval
[1] = Primitive2DReference(
183 new BitmapPrimitive2D(
184 getDiscreteShadow().getTop(),
185 basegfx::utils::createScaleTranslateB2DHomMatrix(
186 1.0 - (2.0 * (fBorderX
+ fSingleX
)) + fSingleX
,
192 xRetval
[2] = Primitive2DReference(
193 new BitmapPrimitive2D(
194 getDiscreteShadow().getTopRight(),
195 basegfx::utils::createScaleTranslateB2DHomMatrix(
202 xRetval
[3] = Primitive2DReference(
203 new BitmapPrimitive2D(
204 getDiscreteShadow().getRight(),
205 basegfx::utils::createScaleTranslateB2DHomMatrix(
207 1.0 - (2.0 * (fBorderY
+ fSingleY
)) + fSingleY
,
209 fBorderY
+ fSingleY
)));
212 xRetval
[4] = Primitive2DReference(
213 new BitmapPrimitive2D(
214 getDiscreteShadow().getBottomRight(),
215 basegfx::utils::createScaleTranslateB2DHomMatrix(
218 1.0 - (fBorderX
+ fSingleX
) + fSingleX
,
219 1.0 - (fBorderY
+ fSingleY
) + fSingleY
)));
222 xRetval
[5] = Primitive2DReference(
223 new BitmapPrimitive2D(
224 getDiscreteShadow().getBottom(),
225 basegfx::utils::createScaleTranslateB2DHomMatrix(
226 1.0 - (2.0 * (fBorderX
+ fSingleX
)) + fSingleX
,
232 xRetval
[6] = Primitive2DReference(
233 new BitmapPrimitive2D(
234 getDiscreteShadow().getBottomLeft(),
235 basegfx::utils::createScaleTranslateB2DHomMatrix(
242 xRetval
[7] = Primitive2DReference(
243 new BitmapPrimitive2D(
244 getDiscreteShadow().getLeft(),
245 basegfx::utils::createScaleTranslateB2DHomMatrix(
247 1.0 - (2.0 * (fBorderY
+ fSingleY
)) + fSingleY
,
249 fBorderY
+ fSingleY
)));
251 // put all in object transformation to get to target positions
252 rContainer
.push_back(
253 new TransformPrimitive2D(
255 std::move(xRetval
)));
258 DiscreteShadowPrimitive2D::DiscreteShadowPrimitive2D(
259 const basegfx::B2DHomMatrix
& rTransform
,
260 const DiscreteShadow
& rDiscreteShadow
)
261 : maTransform(rTransform
),
262 maDiscreteShadow(rDiscreteShadow
)
266 bool DiscreteShadowPrimitive2D::operator==(const BasePrimitive2D
& rPrimitive
) const
268 if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive
))
270 const DiscreteShadowPrimitive2D
& rCompare
= static_cast<const DiscreteShadowPrimitive2D
&>(rPrimitive
);
272 return (getTransform() == rCompare
.getTransform()
273 && getDiscreteShadow() == rCompare
.getDiscreteShadow());
279 basegfx::B2DRange
DiscreteShadowPrimitive2D::getB2DRange(const geometry::ViewInformation2D
& rViewInformation
) const
281 if(getDiscreteShadow().getBitmapEx().IsEmpty())
283 // no graphics without valid bitmap definition
284 return basegfx::B2DRange();
288 // prepare normal objectrange
289 basegfx::B2DRange
aRetval(0.0, 0.0, 1.0, 1.0);
290 aRetval
.transform(getTransform());
292 // extract discrete shadow size and grow
293 const basegfx::B2DVector
aScale(rViewInformation
.getViewTransformation() * basegfx::B2DVector(1.0, 1.0));
294 const sal_Int32
nQuarter((getDiscreteShadow().getBitmapEx().GetSizePixel().Width() - 3) >> 2);
295 const double fGrowX((1.0 / aScale
.getX()) * nQuarter
);
296 const double fGrowY((1.0 / aScale
.getY()) * nQuarter
);
297 aRetval
.grow(std::max(fGrowX
, fGrowY
));
304 sal_uInt32
DiscreteShadowPrimitive2D::getPrimitive2DID() const
306 return PRIMITIVE2D_ID_DISCRETESHADOWPRIMITIVE2D
;
309 } // end of namespace
311 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */