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 maBitmapEx
.Invert(); // convert transparency to alpha
36 const Size
& rBitmapSize
= getBitmapEx().GetSizePixel();
38 if(rBitmapSize
.Width() != rBitmapSize
.Height() || rBitmapSize
.Width() < 7)
40 OSL_ENSURE(false, "DiscreteShadowPrimitive2D: wrong bitmap format (!)");
41 maBitmapEx
= BitmapEx();
45 const BitmapEx
& DiscreteShadow::getTopLeft() const
47 if(maTopLeft
.IsEmpty())
49 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
50 const_cast< DiscreteShadow
* >(this)->maTopLeft
= getBitmapEx();
51 const_cast< DiscreteShadow
* >(this)->maTopLeft
.Crop(
52 ::tools::Rectangle(Point(0, 0), Size((nQuarter
* 2) + 1, (nQuarter
* 2) + 1)));
58 const BitmapEx
& DiscreteShadow::getTop() const
62 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
63 const_cast< DiscreteShadow
* >(this)->maTop
= getBitmapEx();
64 const_cast< DiscreteShadow
* >(this)->maTop
.Crop(
65 ::tools::Rectangle(Point((nQuarter
* 2) + 1, 0), Size(1, nQuarter
)));
71 const BitmapEx
& DiscreteShadow::getTopRight() const
73 if(maTopRight
.IsEmpty())
75 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
76 const_cast< DiscreteShadow
* >(this)->maTopRight
= getBitmapEx();
77 const_cast< DiscreteShadow
* >(this)->maTopRight
.Crop(
78 ::tools::Rectangle(Point((nQuarter
* 2) + 2, 0), Size((nQuarter
* 2) + 1, (nQuarter
* 2) + 1)));
84 const BitmapEx
& DiscreteShadow::getRight() const
88 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
89 const_cast< DiscreteShadow
* >(this)->maRight
= getBitmapEx();
90 const_cast< DiscreteShadow
* >(this)->maRight
.Crop(
91 ::tools::Rectangle(Point((nQuarter
* 3) + 3, (nQuarter
* 2) + 1), Size(nQuarter
, 1)));
97 const BitmapEx
& DiscreteShadow::getBottomRight() const
99 if(maBottomRight
.IsEmpty())
101 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
102 const_cast< DiscreteShadow
* >(this)->maBottomRight
= getBitmapEx();
103 const_cast< DiscreteShadow
* >(this)->maBottomRight
.Crop(
104 ::tools::Rectangle(Point((nQuarter
* 2) + 2, (nQuarter
* 2) + 2), Size((nQuarter
* 2) + 1, (nQuarter
* 2) + 1)));
107 return maBottomRight
;
110 const BitmapEx
& DiscreteShadow::getBottom() const
112 if(maBottom
.IsEmpty())
114 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
115 const_cast< DiscreteShadow
* >(this)->maBottom
= getBitmapEx();
116 const_cast< DiscreteShadow
* >(this)->maBottom
.Crop(
117 ::tools::Rectangle(Point((nQuarter
* 2) + 1, (nQuarter
* 3) + 3), Size(1, nQuarter
)));
123 const BitmapEx
& DiscreteShadow::getBottomLeft() const
125 if(maBottomLeft
.IsEmpty())
127 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
128 const_cast< DiscreteShadow
* >(this)->maBottomLeft
= getBitmapEx();
129 const_cast< DiscreteShadow
* >(this)->maBottomLeft
.Crop(
130 ::tools::Rectangle(Point(0, (nQuarter
* 2) + 2), Size((nQuarter
* 2) + 1, (nQuarter
* 2) + 1)));
136 const BitmapEx
& DiscreteShadow::getLeft() const
140 const sal_Int32
nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
141 const_cast< DiscreteShadow
* >(this)->maLeft
= getBitmapEx();
142 const_cast< DiscreteShadow
* >(this)->maLeft
.Crop(
143 ::tools::Rectangle(Point(0, (nQuarter
* 2) + 1), Size(nQuarter
, 1)));
149 } // end of namespace
152 namespace drawinglayer::primitive2d
154 Primitive2DReference
DiscreteShadowPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D
& /*rViewInformation*/) const
156 Primitive2DContainer xRetval
;
158 if(getDiscreteShadow().getBitmapEx().IsEmpty())
161 const sal_Int32
nQuarter((getDiscreteShadow().getBitmapEx().GetSizePixel().Width() - 3) >> 2);
162 const basegfx::B2DVector
aScale(getTransform() * basegfx::B2DVector(1.0, 1.0));
163 const double fSingleX(getDiscreteUnit() / aScale
.getX());
164 const double fSingleY(getDiscreteUnit() / aScale
.getY());
165 const double fBorderX(fSingleX
* nQuarter
);
166 const double fBorderY(fSingleY
* nQuarter
);
167 const double fBigLenX((fBorderX
* 2.0) + fSingleX
);
168 const double fBigLenY((fBorderY
* 2.0) + fSingleY
);
174 new BitmapPrimitive2D(
175 getDiscreteShadow().getTopLeft(),
176 basegfx::utils::createScaleTranslateB2DHomMatrix(
184 new BitmapPrimitive2D(
185 getDiscreteShadow().getTop(),
186 basegfx::utils::createScaleTranslateB2DHomMatrix(
187 1.0 - (2.0 * (fBorderX
+ fSingleX
)) + fSingleX
,
194 new BitmapPrimitive2D(
195 getDiscreteShadow().getTopRight(),
196 basegfx::utils::createScaleTranslateB2DHomMatrix(
204 new BitmapPrimitive2D(
205 getDiscreteShadow().getRight(),
206 basegfx::utils::createScaleTranslateB2DHomMatrix(
208 1.0 - (2.0 * (fBorderY
+ fSingleY
)) + fSingleY
,
210 fBorderY
+ fSingleY
));
214 new BitmapPrimitive2D(
215 getDiscreteShadow().getBottomRight(),
216 basegfx::utils::createScaleTranslateB2DHomMatrix(
219 1.0 - (fBorderX
+ fSingleX
) + fSingleX
,
220 1.0 - (fBorderY
+ fSingleY
) + fSingleY
));
224 new BitmapPrimitive2D(
225 getDiscreteShadow().getBottom(),
226 basegfx::utils::createScaleTranslateB2DHomMatrix(
227 1.0 - (2.0 * (fBorderX
+ fSingleX
)) + fSingleX
,
234 new BitmapPrimitive2D(
235 getDiscreteShadow().getBottomLeft(),
236 basegfx::utils::createScaleTranslateB2DHomMatrix(
244 new BitmapPrimitive2D(
245 getDiscreteShadow().getLeft(),
246 basegfx::utils::createScaleTranslateB2DHomMatrix(
248 1.0 - (2.0 * (fBorderY
+ fSingleY
)) + fSingleY
,
250 fBorderY
+ fSingleY
));
252 // put all in object transformation to get to target positions
254 new TransformPrimitive2D(
259 DiscreteShadowPrimitive2D::DiscreteShadowPrimitive2D(
260 const basegfx::B2DHomMatrix
& rTransform
,
261 const DiscreteShadow
& rDiscreteShadow
)
262 : maTransform(rTransform
),
263 maDiscreteShadow(rDiscreteShadow
)
267 bool DiscreteShadowPrimitive2D::operator==(const BasePrimitive2D
& rPrimitive
) const
269 if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive
))
271 const DiscreteShadowPrimitive2D
& rCompare
= static_cast<const DiscreteShadowPrimitive2D
&>(rPrimitive
);
273 return (getTransform() == rCompare
.getTransform()
274 && getDiscreteShadow() == rCompare
.getDiscreteShadow());
280 basegfx::B2DRange
DiscreteShadowPrimitive2D::getB2DRange(const geometry::ViewInformation2D
& rViewInformation
) const
282 if(getDiscreteShadow().getBitmapEx().IsEmpty())
284 // no graphics without valid bitmap definition
285 return basegfx::B2DRange();
289 // prepare normal objectrange
290 basegfx::B2DRange
aRetval(0.0, 0.0, 1.0, 1.0);
291 aRetval
.transform(getTransform());
293 // extract discrete shadow size and grow
294 const basegfx::B2DVector
aScale(rViewInformation
.getViewTransformation() * basegfx::B2DVector(1.0, 1.0));
295 const sal_Int32
nQuarter((getDiscreteShadow().getBitmapEx().GetSizePixel().Width() - 3) >> 2);
296 const double fGrowX((1.0 / aScale
.getX()) * nQuarter
);
297 const double fGrowY((1.0 / aScale
.getY()) * nQuarter
);
298 aRetval
.grow(std::max(fGrowX
, fGrowY
));
305 sal_uInt32
DiscreteShadowPrimitive2D::getPrimitive2DID() const
307 return PRIMITIVE2D_ID_DISCRETESHADOWPRIMITIVE2D
;
310 } // end of namespace
312 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */