xref: /trunk/main/drawinglayer/source/primitive2d/discreteshadowprimitive2d.cxx (revision a3cdc23e488c57f3433f22cd4458e65c27aa499c)
1 /**************************************************************
2  *
3  * Licensed to the Apache Software Foundation (ASF) under one
4  * or more contributor license agreements.  See the NOTICE file
5  * distributed with this work for additional information
6  * regarding copyright ownership.  The ASF licenses this file
7  * to you under the Apache License, Version 2.0 (the
8  * "License"); you may not use this file except in compliance
9  * with the License.  You may obtain a copy of the License at
10  *
11  *   http://www.apache.org/licenses/LICENSE-2.0
12  *
13  * Unless required by applicable law or agreed to in writing,
14  * software distributed under the License is distributed on an
15  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16  * KIND, either express or implied.  See the License for the
17  * specific language governing permissions and limitations
18  * under the License.
19  *
20  *************************************************************/
21 
22 // MARKER(update_precomp.py): autogen include statement, do not remove
23 #include "precompiled_drawinglayer.hxx"
24 
25 #include <drawinglayer/primitive2d/discreteshadowprimitive2d.hxx>
26 #include <drawinglayer/primitive2d/drawinglayer_primitivetypes2d.hxx>
27 #include <drawinglayer/primitive2d/bitmapprimitive2d.hxx>
28 #include <basegfx/matrix/b2dhommatrixtools.hxx>
29 #include <drawinglayer/primitive2d/transformprimitive2d.hxx>
30 #include <drawinglayer/geometry/viewinformation2d.hxx>
31 
32 namespace drawinglayer
33 {
34     namespace primitive2d
35     {
36         DiscreteShadow::DiscreteShadow(const BitmapEx& rBitmapEx)
37         :   maBitmapEx(rBitmapEx),
38             maTopLeft(),
39             maTop(),
40             maTopRight(),
41             maRight(),
42             maBottomRight(),
43             maBottom(),
44             maBottomLeft(),
45             maLeft()
46         {
47             const Size& rBitmapSize = getBitmapEx().GetSizePixel();
48 
49             if(rBitmapSize.Width() != rBitmapSize.Height() || rBitmapSize.Width() < 7)
50             {
51                 OSL_ENSURE(false, "DiscreteShadowPrimitive2D: wrong bitmap format (!)");
52                 maBitmapEx = BitmapEx();
53             }
54         }
55 
56         const BitmapEx& DiscreteShadow::getTopLeft() const
57         {
58             if(maTopLeft.IsEmpty())
59             {
60                 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
61                 const_cast< DiscreteShadow* >(this)->maTopLeft = getBitmapEx();
62                 const_cast< DiscreteShadow* >(this)->maTopLeft.Crop(
63                     Rectangle(Point(0, 0), Size((nQuarter * 2) + 1, (nQuarter * 2) + 1)));
64             }
65 
66             return maTopLeft;
67         }
68 
69         const BitmapEx& DiscreteShadow::getTop() const
70         {
71             if(maTop.IsEmpty())
72             {
73                 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
74                 const_cast< DiscreteShadow* >(this)->maTop = getBitmapEx();
75                 const_cast< DiscreteShadow* >(this)->maTop.Crop(
76                     Rectangle(Point((nQuarter * 2) + 1, 0), Size(1, nQuarter)));
77             }
78 
79             return maTop;
80         }
81 
82         const BitmapEx& DiscreteShadow::getTopRight() const
83         {
84             if(maTopRight.IsEmpty())
85             {
86                 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
87                 const_cast< DiscreteShadow* >(this)->maTopRight = getBitmapEx();
88                 const_cast< DiscreteShadow* >(this)->maTopRight.Crop(
89                     Rectangle(Point((nQuarter * 2) + 2, 0), Size((nQuarter * 2) + 1, (nQuarter * 2) + 1)));
90             }
91 
92             return maTopRight;
93         }
94 
95         const BitmapEx& DiscreteShadow::getRight() const
96         {
97             if(maRight.IsEmpty())
98             {
99                 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
100                 const_cast< DiscreteShadow* >(this)->maRight = getBitmapEx();
101                 const_cast< DiscreteShadow* >(this)->maRight.Crop(
102                     Rectangle(Point((nQuarter * 3) + 3, (nQuarter * 2) + 1), Size(nQuarter, 1)));
103             }
104 
105             return maRight;
106         }
107 
108         const BitmapEx& DiscreteShadow::getBottomRight() const
109         {
110             if(maBottomRight.IsEmpty())
111             {
112                 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
113                 const_cast< DiscreteShadow* >(this)->maBottomRight = getBitmapEx();
114                 const_cast< DiscreteShadow* >(this)->maBottomRight.Crop(
115                     Rectangle(Point((nQuarter * 2) + 2, (nQuarter * 2) + 2), Size((nQuarter * 2) + 1, (nQuarter * 2) + 1)));
116             }
117 
118             return maBottomRight;
119         }
120 
121         const BitmapEx& DiscreteShadow::getBottom() const
122         {
123             if(maBottom.IsEmpty())
124             {
125                 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
126                 const_cast< DiscreteShadow* >(this)->maBottom = getBitmapEx();
127                 const_cast< DiscreteShadow* >(this)->maBottom.Crop(
128                     Rectangle(Point((nQuarter * 2) + 1, (nQuarter * 3) + 3), Size(1, nQuarter)));
129             }
130 
131             return maBottom;
132         }
133 
134         const BitmapEx& DiscreteShadow::getBottomLeft() const
135         {
136             if(maBottomLeft.IsEmpty())
137             {
138                 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
139                 const_cast< DiscreteShadow* >(this)->maBottomLeft = getBitmapEx();
140                 const_cast< DiscreteShadow* >(this)->maBottomLeft.Crop(
141                     Rectangle(Point(0, (nQuarter * 2) + 2), Size((nQuarter * 2) + 1, (nQuarter * 2) + 1)));
142             }
143 
144             return maBottomLeft;
145         }
146 
147         const BitmapEx& DiscreteShadow::getLeft() const
148         {
149             if(maLeft.IsEmpty())
150             {
151                 const sal_Int32 nQuarter((getBitmapEx().GetSizePixel().Width() - 3) >> 2);
152                 const_cast< DiscreteShadow* >(this)->maLeft = getBitmapEx();
153                 const_cast< DiscreteShadow* >(this)->maLeft.Crop(
154                     Rectangle(Point(0, (nQuarter * 2) + 1), Size(nQuarter, 1)));
155             }
156 
157             return maLeft;
158         }
159 
160     } // end of namespace primitive2d
161 } // end of namespace drawinglayer
162 
163 //////////////////////////////////////////////////////////////////////////////
164 
165 namespace drawinglayer
166 {
167     namespace primitive2d
168     {
169         Primitive2DSequence DiscreteShadowPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
170         {
171             Primitive2DSequence xRetval;
172 
173             if(!getDiscreteShadow().getBitmapEx().IsEmpty())
174             {
175                 const sal_Int32 nQuarter((getDiscreteShadow().getBitmapEx().GetSizePixel().Width() - 3) >> 2);
176                 const basegfx::B2DVector aScale(getTransform() * basegfx::B2DVector(1.0, 1.0));
177                 const double fSingleX(getDiscreteUnit() / aScale.getX());
178                 const double fSingleY(getDiscreteUnit() / aScale.getY());
179                 const double fBorderX(fSingleX * nQuarter);
180                 const double fBorderY(fSingleY * nQuarter);
181                 const double fBigLenX((fBorderX * 2.0) + fSingleX);
182                 const double fBigLenY((fBorderY * 2.0) + fSingleY);
183 
184                 xRetval.realloc(8);
185 
186                 // TopLeft
187                 xRetval[0] = Primitive2DReference(
188                     new BitmapPrimitive2D(
189                         getDiscreteShadow().getTopLeft(),
190                         basegfx::tools::createScaleTranslateB2DHomMatrix(
191                             fBigLenX,
192                             fBigLenY,
193                             -fBorderX,
194                             -fBorderY)));
195 
196                 // Top
197                 xRetval[1] = Primitive2DReference(
198                     new BitmapPrimitive2D(
199                         getDiscreteShadow().getTop(),
200                         basegfx::tools::createScaleTranslateB2DHomMatrix(
201                             1.0 - (2.0 * (fBorderX + fSingleX)) + fSingleX,
202                             fBorderY,
203                             fBorderX + fSingleX,
204                             -fBorderY)));
205 
206                 // TopRight
207                 xRetval[2] = Primitive2DReference(
208                     new BitmapPrimitive2D(
209                         getDiscreteShadow().getTopRight(),
210                         basegfx::tools::createScaleTranslateB2DHomMatrix(
211                             fBigLenX,
212                             fBigLenY,
213                             1.0 - fBorderX,
214                             -fBorderY)));
215 
216                 // Right
217                 xRetval[3] = Primitive2DReference(
218                     new BitmapPrimitive2D(
219                         getDiscreteShadow().getRight(),
220                         basegfx::tools::createScaleTranslateB2DHomMatrix(
221                             fBorderX,
222                             1.0 - (2.0 * (fBorderY + fSingleY)) + fSingleY,
223                             1.0 + fSingleX,
224                             fBorderY + fSingleY)));
225 
226                 // BottomRight
227                 xRetval[4] = Primitive2DReference(
228                     new BitmapPrimitive2D(
229                         getDiscreteShadow().getBottomRight(),
230                         basegfx::tools::createScaleTranslateB2DHomMatrix(
231                             fBigLenX,
232                             fBigLenY,
233                             1.0 - (fBorderX + fSingleX) + fSingleX,
234                             1.0 - (fBorderY + fSingleY) + fSingleY)));
235 
236                 // Bottom
237                 xRetval[5] = Primitive2DReference(
238                     new BitmapPrimitive2D(
239                         getDiscreteShadow().getBottom(),
240                         basegfx::tools::createScaleTranslateB2DHomMatrix(
241                             1.0 - (2.0 * (fBorderX + fSingleX)) + fSingleX,
242                             fBorderY,
243                             fBorderX + fSingleX,
244                             1.0 + fSingleY)));
245 
246                 // BottomLeft
247                 xRetval[6] = Primitive2DReference(
248                     new BitmapPrimitive2D(
249                         getDiscreteShadow().getBottomLeft(),
250                         basegfx::tools::createScaleTranslateB2DHomMatrix(
251                             fBigLenX,
252                             fBigLenY,
253                             -fBorderX,
254                             1.0 - fBorderY)));
255 
256                 // Left
257                 xRetval[7] = Primitive2DReference(
258                     new BitmapPrimitive2D(
259                         getDiscreteShadow().getLeft(),
260                         basegfx::tools::createScaleTranslateB2DHomMatrix(
261                             fBorderX,
262                             1.0 - (2.0 * (fBorderY + fSingleY)) + fSingleY,
263                             -fBorderX,
264                             fBorderY + fSingleY)));
265 
266                 // put all in object transformation to get to target positions
267                 const Primitive2DReference xTransformed(
268                     new TransformPrimitive2D(
269                         getTransform(),
270                         xRetval));
271 
272                 xRetval = Primitive2DSequence(&xTransformed, 1);
273             }
274 
275             return xRetval;
276         }
277 
278         DiscreteShadowPrimitive2D::DiscreteShadowPrimitive2D(
279             const basegfx::B2DHomMatrix& rTransform,
280             const DiscreteShadow& rDiscreteShadow)
281         :   DiscreteMetricDependentPrimitive2D(),
282             maTransform(rTransform),
283             maDiscreteShadow(rDiscreteShadow)
284         {
285         }
286 
287         bool DiscreteShadowPrimitive2D::operator==(const BasePrimitive2D& rPrimitive) const
288         {
289             if(DiscreteMetricDependentPrimitive2D::operator==(rPrimitive))
290             {
291                 const DiscreteShadowPrimitive2D& rCompare = (DiscreteShadowPrimitive2D&)rPrimitive;
292 
293                 return (getTransform() == rCompare.getTransform()
294                     && getDiscreteShadow() == rCompare.getDiscreteShadow());
295             }
296 
297             return false;
298         }
299 
300         basegfx::B2DRange DiscreteShadowPrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
301         {
302             if(getDiscreteShadow().getBitmapEx().IsEmpty())
303             {
304                 // no graphics without valid bitmap definition
305                 return basegfx::B2DRange();
306             }
307             else
308             {
309                 // prepare normal objectrange
310                 basegfx::B2DRange aRetval(0.0, 0.0, 1.0, 1.0);
311                 aRetval.transform(getTransform());
312 
313                 // extract discrete shadow size and grow
314                 const basegfx::B2DVector aScale(rViewInformation.getViewTransformation() * basegfx::B2DVector(1.0, 1.0));
315                 const sal_Int32 nQuarter((getDiscreteShadow().getBitmapEx().GetSizePixel().Width() - 3) >> 2);
316                 const double fGrowX((1.0 / aScale.getX()) * nQuarter);
317                 const double fGrowY((1.0 / aScale.getY()) * nQuarter);
318                 aRetval.grow(std::max(fGrowX, fGrowY));
319 
320                 return aRetval;
321             }
322         }
323 
324         // provide unique ID
325         ImplPrimitrive2DIDBlock(DiscreteShadowPrimitive2D, PRIMITIVE2D_ID_DISCRETESHADOWPRIMITIVE2D)
326 
327     } // end of namespace primitive2d
328 } // end of namespace drawinglayer
329 
330 /* vim: set noet sw=4 ts=4: */
331