xref: /AOO41X/main/drawinglayer/source/attribute/sdrfillgraphicattribute.cxx (revision 54628ca40d27d15cc98fe861da7fff7e60c2f7d6)
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 
23 
24 // MARKER(update_precomp.py): autogen include statement, do not remove
25 #include "precompiled_drawinglayer.hxx"
26 
27 #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
28 #include <drawinglayer/attribute/fillgraphicattribute.hxx>
29 #include <vcl/graph.hxx>
30 
31 //////////////////////////////////////////////////////////////////////////////
32 
33 namespace drawinglayer
34 {
35     namespace attribute
36     {
37         class ImpSdrFillGraphicAttribute
38         {
39         public:
40             // refcounter
41             sal_uInt32                              mnRefCount;
42 
43             // data definitions
44             Graphic                                 maFillGraphic;
45             basegfx::B2DVector                      maSize;
46             basegfx::B2DVector                      maOffset;
47             basegfx::B2DVector                      maOffsetPosition;
48             basegfx::B2DVector                      maRectPoint;
49 
50             // bitfield
51             unsigned                                mbTiling : 1;
52             unsigned                                mbStretch : 1;
53             unsigned                                mbLogSize : 1;
54 
55             ImpSdrFillGraphicAttribute(
56                 const Graphic& rFillGraphic,
57                 const basegfx::B2DVector& rSize,
58                 const basegfx::B2DVector& rOffset,
59                 const basegfx::B2DVector& rOffsetPosition,
60                 const basegfx::B2DVector& rRectPoint,
61                 bool bTiling,
62                 bool bStretch,
63                 bool bLogSize)
64             :   mnRefCount(0),
65                 maFillGraphic(rFillGraphic),
66                 maSize(rSize),
67                 maOffset(rOffset),
68                 maOffsetPosition(rOffsetPosition),
69                 maRectPoint(rRectPoint),
70                 mbTiling(bTiling),
71                 mbStretch(bStretch),
72                 mbLogSize(bLogSize)
73             {
74             }
75 
76             // data read access
77             const Graphic& getFillGraphic() const { return maFillGraphic; }
78             const basegfx::B2DVector& getSize() const { return maSize; }
79             const basegfx::B2DVector& getOffset() const { return maOffset; }
80             const basegfx::B2DVector& getOffsetPosition() const { return maOffsetPosition; }
81             const basegfx::B2DVector& getRectPoint() const { return maRectPoint; }
82             bool getTiling() const { return mbTiling; }
83             bool getStretch() const { return mbStretch; }
84             bool getLogSize() const { return mbLogSize; }
85 
86             bool operator==(const ImpSdrFillGraphicAttribute& rCandidate) const
87             {
88                 return (getFillGraphic() == rCandidate.getFillGraphic()
89                     && getSize() == rCandidate.getSize()
90                     && getOffset() == rCandidate.getOffset()
91                     && getOffsetPosition() == rCandidate.getOffsetPosition()
92                     && getRectPoint() == rCandidate.getRectPoint()
93                     && getTiling() == rCandidate.getTiling()
94                     && getStretch() == rCandidate.getStretch()
95                     && getLogSize() == rCandidate.getLogSize());
96             }
97 
98             static ImpSdrFillGraphicAttribute* get_global_default()
99             {
100                 static ImpSdrFillGraphicAttribute* pDefault = 0;
101 
102                 if(!pDefault)
103                 {
104                     pDefault = new ImpSdrFillGraphicAttribute(
105                         Graphic(),
106                         basegfx::B2DVector(),
107                         basegfx::B2DVector(),
108                         basegfx::B2DVector(),
109                         basegfx::B2DVector(),
110                         false,
111                         false,
112                         false);
113 
114                     // never delete; start with RefCount 1, not 0
115                     pDefault->mnRefCount++;
116                 }
117 
118                 return pDefault;
119             }
120         };
121 
122         SdrFillGraphicAttribute::SdrFillGraphicAttribute(
123             const Graphic& rFillGraphic,
124             const basegfx::B2DVector& rSize,
125             const basegfx::B2DVector& rOffset,
126             const basegfx::B2DVector& rOffsetPosition,
127             const basegfx::B2DVector& rRectPoint,
128             bool bTiling,
129             bool bStretch,
130             bool bLogSize)
131         :   mpSdrFillGraphicAttribute(
132                 new ImpSdrFillGraphicAttribute(
133                     rFillGraphic,
134                     rSize,
135                     rOffset,
136                     rOffsetPosition,
137                     rRectPoint,
138                     bTiling,
139                     bStretch,
140                     bLogSize))
141         {
142         }
143 
144         SdrFillGraphicAttribute::SdrFillGraphicAttribute()
145         :   mpSdrFillGraphicAttribute(ImpSdrFillGraphicAttribute::get_global_default())
146         {
147             mpSdrFillGraphicAttribute->mnRefCount++;
148         }
149 
150         SdrFillGraphicAttribute::SdrFillGraphicAttribute(const SdrFillGraphicAttribute& rCandidate)
151         :   mpSdrFillGraphicAttribute(rCandidate.mpSdrFillGraphicAttribute)
152         {
153             mpSdrFillGraphicAttribute->mnRefCount++;
154         }
155 
156         SdrFillGraphicAttribute::~SdrFillGraphicAttribute()
157         {
158             if(mpSdrFillGraphicAttribute->mnRefCount)
159             {
160                 mpSdrFillGraphicAttribute->mnRefCount--;
161             }
162             else
163             {
164                 delete mpSdrFillGraphicAttribute;
165             }
166         }
167 
168         bool SdrFillGraphicAttribute::isDefault() const
169         {
170             return mpSdrFillGraphicAttribute == ImpSdrFillGraphicAttribute::get_global_default();
171         }
172 
173         SdrFillGraphicAttribute& SdrFillGraphicAttribute::operator=(const SdrFillGraphicAttribute& rCandidate)
174         {
175             if(rCandidate.mpSdrFillGraphicAttribute != mpSdrFillGraphicAttribute)
176             {
177                 if(mpSdrFillGraphicAttribute->mnRefCount)
178                 {
179                     mpSdrFillGraphicAttribute->mnRefCount--;
180                 }
181                 else
182                 {
183                     delete mpSdrFillGraphicAttribute;
184                 }
185 
186                 mpSdrFillGraphicAttribute = rCandidate.mpSdrFillGraphicAttribute;
187                 mpSdrFillGraphicAttribute->mnRefCount++;
188             }
189 
190             return *this;
191         }
192 
193         bool SdrFillGraphicAttribute::operator==(const SdrFillGraphicAttribute& rCandidate) const
194         {
195             if(rCandidate.mpSdrFillGraphicAttribute == mpSdrFillGraphicAttribute)
196             {
197                 return true;
198             }
199 
200             if(rCandidate.isDefault() != isDefault())
201             {
202                 return false;
203             }
204 
205             return (*rCandidate.mpSdrFillGraphicAttribute == *mpSdrFillGraphicAttribute);
206         }
207 
208         const Graphic& SdrFillGraphicAttribute::getFillGraphic() const
209         {
210             return mpSdrFillGraphicAttribute->getFillGraphic();
211         }
212 
213         const basegfx::B2DVector& SdrFillGraphicAttribute::getSize() const
214         {
215             return mpSdrFillGraphicAttribute->getSize();
216         }
217 
218         const basegfx::B2DVector& SdrFillGraphicAttribute::getOffset() const
219         {
220             return mpSdrFillGraphicAttribute->getOffset();
221         }
222 
223         const basegfx::B2DVector& SdrFillGraphicAttribute::getOffsetPosition() const
224         {
225             return mpSdrFillGraphicAttribute->getOffsetPosition();
226         }
227 
228         const basegfx::B2DVector& SdrFillGraphicAttribute::getRectPoint() const
229         {
230             return mpSdrFillGraphicAttribute->getRectPoint();
231         }
232 
233         bool SdrFillGraphicAttribute::getTiling() const
234         {
235             return mpSdrFillGraphicAttribute->getTiling();
236         }
237 
238         bool SdrFillGraphicAttribute::getStretch() const
239         {
240             return mpSdrFillGraphicAttribute->getStretch();
241         }
242 
243         bool SdrFillGraphicAttribute::getLogSize() const
244         {
245             return mpSdrFillGraphicAttribute->getLogSize();
246         }
247 
248         FillGraphicAttribute SdrFillGraphicAttribute::createFillGraphicAttribute(const basegfx::B2DRange& rRange) const
249         {
250             // get logical size of bitmap (before expanding eventually)
251             Graphic aGraphic(getFillGraphic());
252             const basegfx::B2DVector aLogicalSize(aGraphic.GetPrefSize().getWidth(), aGraphic.GetPrefSize().getHeight());
253 
254             // init values with defaults
255             basegfx::B2DPoint aBitmapSize(1.0, 1.0);
256             basegfx::B2DVector aBitmapTopLeft(0.0, 0.0);
257 
258             // are changes needed?
259             if(getTiling() || !getStretch())
260             {
261                 // init values with range sizes
262                 const double fRangeWidth(0.0 != rRange.getWidth() ? rRange.getWidth() : 1.0);
263                 const double fRangeHeight(0.0 != rRange.getHeight() ? rRange.getHeight() : 1.0);
264                 aBitmapSize = basegfx::B2DPoint(fRangeWidth, fRangeHeight);
265 
266                 // size changes
267                 if(0.0 != getSize().getX())
268                 {
269                     if(getSize().getX() < 0.0)
270                     {
271                         aBitmapSize.setX(aBitmapSize.getX() * (getSize().getX() * -0.01));
272                     }
273                     else
274                     {
275                         aBitmapSize.setX(getSize().getX());
276                     }
277                 }
278                 else
279                 {
280                     aBitmapSize.setX(aLogicalSize.getX());
281                 }
282 
283                 if(0.0 != getSize().getY())
284                 {
285                     if(getSize().getY() < 0.0)
286                     {
287                         aBitmapSize.setY(aBitmapSize.getY() * (getSize().getY() * -0.01));
288                     }
289                     else
290                     {
291                         aBitmapSize.setY(getSize().getY());
292                     }
293                 }
294                 else
295                 {
296                     aBitmapSize.setY(aLogicalSize.getY());
297                 }
298 
299                 // get values, force to centered if necessary
300                 const basegfx::B2DVector aRectPoint(getTiling() ? getRectPoint() : basegfx::B2DVector(0.0, 0.0));
301 
302                 // position changes X
303                 if(0.0 == aRectPoint.getX())
304                 {
305                     aBitmapTopLeft.setX((fRangeWidth - aBitmapSize.getX()) * 0.5);
306                 }
307                 else if(1.0 == aRectPoint.getX())
308                 {
309                     aBitmapTopLeft.setX(fRangeWidth - aBitmapSize.getX());
310                 }
311 
312                 if(getTiling() && 0.0 != getOffsetPosition().getX())
313                 {
314                     aBitmapTopLeft.setX(aBitmapTopLeft.getX() + (aBitmapSize.getX() * (getOffsetPosition().getX() * 0.01)));
315                 }
316 
317                 // position changes Y
318                 if(0.0 == aRectPoint.getY())
319                 {
320                     aBitmapTopLeft.setY((fRangeHeight - aBitmapSize.getY()) * 0.5);
321                 }
322                 else if(1.0 == aRectPoint.getY())
323                 {
324                     aBitmapTopLeft.setY(fRangeHeight - aBitmapSize.getY());
325                 }
326 
327                 if(getTiling() && 0.0 != getOffsetPosition().getY())
328                 {
329                     aBitmapTopLeft.setY(aBitmapTopLeft.getY() + (aBitmapSize.getY() * (getOffsetPosition().getY() * 0.01)));
330                 }
331 
332                 // apply bitmap size scaling to unit rectangle
333                 aBitmapTopLeft.setX(aBitmapTopLeft.getX() / fRangeWidth);
334                 aBitmapTopLeft.setY(aBitmapTopLeft.getY() / fRangeHeight);
335                 aBitmapSize.setX(aBitmapSize.getX() / fRangeWidth);
336                 aBitmapSize.setY(aBitmapSize.getY() / fRangeHeight);
337             }
338 
339             // get offset in percent
340             const double fOffsetX(basegfx::clamp(getOffset().getX() * 0.01, 0.0, 1.0));
341             const double fOffsetY(basegfx::clamp(getOffset().getY() * 0.01, 0.0, 1.0));
342 
343             // create FillGraphicAttribute
344             return FillGraphicAttribute(
345                 aGraphic,
346                 basegfx::B2DRange(aBitmapTopLeft, aBitmapTopLeft + aBitmapSize),
347                 getTiling(),
348                 fOffsetX,
349                 fOffsetY);
350         }
351     } // end of namespace attribute
352 } // end of namespace drawinglayer
353 
354 //////////////////////////////////////////////////////////////////////////////
355 // eof
356