xref: /AOO41X/main/drawinglayer/source/attribute/sdrfillgraphicattribute.cxx (revision e7d686686afb4d382768f76e473eb6fb3d4e57e3)
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                      maGraphicLogicSize;
46             basegfx::B2DVector                      maSize;
47             basegfx::B2DVector                      maOffset;
48             basegfx::B2DVector                      maOffsetPosition;
49             basegfx::B2DVector                      maRectPoint;
50 
51             // bitfield
52             unsigned                                mbTiling : 1;
53             unsigned                                mbStretch : 1;
54             unsigned                                mbLogSize : 1;
55 
ImpSdrFillGraphicAttribute(const Graphic & rFillGraphic,const basegfx::B2DVector & rGraphicLogicSize,const basegfx::B2DVector & rSize,const basegfx::B2DVector & rOffset,const basegfx::B2DVector & rOffsetPosition,const basegfx::B2DVector & rRectPoint,bool bTiling,bool bStretch,bool bLogSize)56             ImpSdrFillGraphicAttribute(
57                 const Graphic& rFillGraphic,
58                 const basegfx::B2DVector& rGraphicLogicSize,
59                 const basegfx::B2DVector& rSize,
60                 const basegfx::B2DVector& rOffset,
61                 const basegfx::B2DVector& rOffsetPosition,
62                 const basegfx::B2DVector& rRectPoint,
63                 bool bTiling,
64                 bool bStretch,
65                 bool bLogSize)
66             :   mnRefCount(0),
67                 maFillGraphic(rFillGraphic),
68                 maGraphicLogicSize(rGraphicLogicSize),
69                 maSize(rSize),
70                 maOffset(rOffset),
71                 maOffsetPosition(rOffsetPosition),
72                 maRectPoint(rRectPoint),
73                 mbTiling(bTiling),
74                 mbStretch(bStretch),
75                 mbLogSize(bLogSize)
76             {
77             }
78 
79             // data read access
getFillGraphic() const80             const Graphic& getFillGraphic() const { return maFillGraphic; }
getGraphicLogicSize() const81             const basegfx::B2DVector& getGraphicLogicSize() const { return maGraphicLogicSize; }
getSize() const82             const basegfx::B2DVector& getSize() const { return maSize; }
getOffset() const83             const basegfx::B2DVector& getOffset() const { return maOffset; }
getOffsetPosition() const84             const basegfx::B2DVector& getOffsetPosition() const { return maOffsetPosition; }
getRectPoint() const85             const basegfx::B2DVector& getRectPoint() const { return maRectPoint; }
getTiling() const86             bool getTiling() const { return mbTiling; }
getStretch() const87             bool getStretch() const { return mbStretch; }
getLogSize() const88             bool getLogSize() const { return mbLogSize; }
89 
operator ==(const ImpSdrFillGraphicAttribute & rCandidate) const90             bool operator==(const ImpSdrFillGraphicAttribute& rCandidate) const
91             {
92                 return (getFillGraphic() == rCandidate.getFillGraphic()
93                     && getGraphicLogicSize() == rCandidate.getGraphicLogicSize()
94                     && getSize() == rCandidate.getSize()
95                     && getOffset() == rCandidate.getOffset()
96                     && getOffsetPosition() == rCandidate.getOffsetPosition()
97                     && getRectPoint() == rCandidate.getRectPoint()
98                     && getTiling() == rCandidate.getTiling()
99                     && getStretch() == rCandidate.getStretch()
100                     && getLogSize() == rCandidate.getLogSize());
101             }
102 
get_global_default()103             static ImpSdrFillGraphicAttribute* get_global_default()
104             {
105                 static ImpSdrFillGraphicAttribute* pDefault = 0;
106 
107                 if(!pDefault)
108                 {
109                     pDefault = new ImpSdrFillGraphicAttribute(
110                         Graphic(),
111                         basegfx::B2DVector(),
112                         basegfx::B2DVector(),
113                         basegfx::B2DVector(),
114                         basegfx::B2DVector(),
115                         basegfx::B2DVector(),
116                         false,
117                         false,
118                         false);
119 
120                     // never delete; start with RefCount 1, not 0
121                     pDefault->mnRefCount++;
122                 }
123 
124                 return pDefault;
125             }
126         };
127 
SdrFillGraphicAttribute(const Graphic & rFillGraphic,const basegfx::B2DVector & rGraphicLogicSize,const basegfx::B2DVector & rSize,const basegfx::B2DVector & rOffset,const basegfx::B2DVector & rOffsetPosition,const basegfx::B2DVector & rRectPoint,bool bTiling,bool bStretch,bool bLogSize)128         SdrFillGraphicAttribute::SdrFillGraphicAttribute(
129             const Graphic& rFillGraphic,
130             const basegfx::B2DVector& rGraphicLogicSize,
131             const basegfx::B2DVector& rSize,
132             const basegfx::B2DVector& rOffset,
133             const basegfx::B2DVector& rOffsetPosition,
134             const basegfx::B2DVector& rRectPoint,
135             bool bTiling,
136             bool bStretch,
137             bool bLogSize)
138         :   mpSdrFillGraphicAttribute(
139                 new ImpSdrFillGraphicAttribute(
140                     rFillGraphic,
141                     rGraphicLogicSize,
142                     rSize,
143                     rOffset,
144                     rOffsetPosition,
145                     rRectPoint,
146                     bTiling,
147                     bStretch,
148                     bLogSize))
149         {
150         }
151 
SdrFillGraphicAttribute()152         SdrFillGraphicAttribute::SdrFillGraphicAttribute()
153         :   mpSdrFillGraphicAttribute(ImpSdrFillGraphicAttribute::get_global_default())
154         {
155             mpSdrFillGraphicAttribute->mnRefCount++;
156         }
157 
SdrFillGraphicAttribute(const SdrFillGraphicAttribute & rCandidate)158         SdrFillGraphicAttribute::SdrFillGraphicAttribute(const SdrFillGraphicAttribute& rCandidate)
159         :   mpSdrFillGraphicAttribute(rCandidate.mpSdrFillGraphicAttribute)
160         {
161             mpSdrFillGraphicAttribute->mnRefCount++;
162         }
163 
~SdrFillGraphicAttribute()164         SdrFillGraphicAttribute::~SdrFillGraphicAttribute()
165         {
166             if(mpSdrFillGraphicAttribute->mnRefCount)
167             {
168                 mpSdrFillGraphicAttribute->mnRefCount--;
169             }
170             else
171             {
172                 delete mpSdrFillGraphicAttribute;
173             }
174         }
175 
isDefault() const176         bool SdrFillGraphicAttribute::isDefault() const
177         {
178             return mpSdrFillGraphicAttribute == ImpSdrFillGraphicAttribute::get_global_default();
179         }
180 
operator =(const SdrFillGraphicAttribute & rCandidate)181         SdrFillGraphicAttribute& SdrFillGraphicAttribute::operator=(const SdrFillGraphicAttribute& rCandidate)
182         {
183             if(rCandidate.mpSdrFillGraphicAttribute != mpSdrFillGraphicAttribute)
184             {
185                 if(mpSdrFillGraphicAttribute->mnRefCount)
186                 {
187                     mpSdrFillGraphicAttribute->mnRefCount--;
188                 }
189                 else
190                 {
191                     delete mpSdrFillGraphicAttribute;
192                 }
193 
194                 mpSdrFillGraphicAttribute = rCandidate.mpSdrFillGraphicAttribute;
195                 mpSdrFillGraphicAttribute->mnRefCount++;
196             }
197 
198             return *this;
199         }
200 
operator ==(const SdrFillGraphicAttribute & rCandidate) const201         bool SdrFillGraphicAttribute::operator==(const SdrFillGraphicAttribute& rCandidate) const
202         {
203             if(rCandidate.mpSdrFillGraphicAttribute == mpSdrFillGraphicAttribute)
204             {
205                 return true;
206             }
207 
208             if(rCandidate.isDefault() != isDefault())
209             {
210                 return false;
211             }
212 
213             return (*rCandidate.mpSdrFillGraphicAttribute == *mpSdrFillGraphicAttribute);
214         }
215 
getFillGraphic() const216         const Graphic& SdrFillGraphicAttribute::getFillGraphic() const
217         {
218             return mpSdrFillGraphicAttribute->getFillGraphic();
219         }
220 
getGraphicLogicSize() const221         const basegfx::B2DVector& SdrFillGraphicAttribute::getGraphicLogicSize() const
222         {
223             return mpSdrFillGraphicAttribute->getGraphicLogicSize();
224         }
225 
getSize() const226         const basegfx::B2DVector& SdrFillGraphicAttribute::getSize() const
227         {
228             return mpSdrFillGraphicAttribute->getSize();
229         }
230 
getOffset() const231         const basegfx::B2DVector& SdrFillGraphicAttribute::getOffset() const
232         {
233             return mpSdrFillGraphicAttribute->getOffset();
234         }
235 
getOffsetPosition() const236         const basegfx::B2DVector& SdrFillGraphicAttribute::getOffsetPosition() const
237         {
238             return mpSdrFillGraphicAttribute->getOffsetPosition();
239         }
240 
getRectPoint() const241         const basegfx::B2DVector& SdrFillGraphicAttribute::getRectPoint() const
242         {
243             return mpSdrFillGraphicAttribute->getRectPoint();
244         }
245 
getTiling() const246         bool SdrFillGraphicAttribute::getTiling() const
247         {
248             return mpSdrFillGraphicAttribute->getTiling();
249         }
250 
getStretch() const251         bool SdrFillGraphicAttribute::getStretch() const
252         {
253             return mpSdrFillGraphicAttribute->getStretch();
254         }
255 
getLogSize() const256         bool SdrFillGraphicAttribute::getLogSize() const
257         {
258             return mpSdrFillGraphicAttribute->getLogSize();
259         }
260 
createFillGraphicAttribute(const basegfx::B2DRange & rRange) const261         FillGraphicAttribute SdrFillGraphicAttribute::createFillGraphicAttribute(const basegfx::B2DRange& rRange) const
262         {
263             // get logical size of bitmap (before expanding eventually)
264             Graphic aGraphic(getFillGraphic());
265 
266             // init values with defaults
267             basegfx::B2DPoint aBitmapSize(1.0, 1.0);
268             basegfx::B2DVector aBitmapTopLeft(0.0, 0.0);
269 
270             // are changes needed?
271             if(getTiling() || !getStretch())
272             {
273                 // init values with range sizes
274                 const double fRangeWidth(0.0 != rRange.getWidth() ? rRange.getWidth() : 1.0);
275                 const double fRangeHeight(0.0 != rRange.getHeight() ? rRange.getHeight() : 1.0);
276                 aBitmapSize = basegfx::B2DPoint(fRangeWidth, fRangeHeight);
277 
278                 // size changes
279                 if(0.0 != getSize().getX())
280                 {
281                     if(getSize().getX() < 0.0)
282                     {
283                         aBitmapSize.setX(aBitmapSize.getX() * (getSize().getX() * -0.01));
284                     }
285                     else
286                     {
287                         aBitmapSize.setX(getSize().getX());
288                     }
289                 }
290                 else
291                 {
292                     // #124002# use GraphicLogicSize directly, do not try to use GetPrefSize
293                     // of the graphic, that may not be adapted to the MapMode of the target
294                     aBitmapSize.setX(getGraphicLogicSize().getX());
295                 }
296 
297                 if(0.0 != getSize().getY())
298                 {
299                     if(getSize().getY() < 0.0)
300                     {
301                         aBitmapSize.setY(aBitmapSize.getY() * (getSize().getY() * -0.01));
302                     }
303                     else
304                     {
305                         aBitmapSize.setY(getSize().getY());
306                     }
307                 }
308                 else
309                 {
310                     // #124002# use GraphicLogicSize directly, do not try to use GetPrefSize
311                     // of the graphic, that may not be adapted to the MapMode of the target
312                     aBitmapSize.setY(getGraphicLogicSize().getY());
313                 }
314 
315                 // get values, force to centered if necessary
316                 const basegfx::B2DVector aRectPoint(getTiling() ? getRectPoint() : basegfx::B2DVector(0.0, 0.0));
317 
318                 // position changes X
319                 if(0.0 == aRectPoint.getX())
320                 {
321                     aBitmapTopLeft.setX((fRangeWidth - aBitmapSize.getX()) * 0.5);
322                 }
323                 else if(1.0 == aRectPoint.getX())
324                 {
325                     aBitmapTopLeft.setX(fRangeWidth - aBitmapSize.getX());
326                 }
327 
328                 if(getTiling() && 0.0 != getOffsetPosition().getX())
329                 {
330                     aBitmapTopLeft.setX(aBitmapTopLeft.getX() + (aBitmapSize.getX() * (getOffsetPosition().getX() * 0.01)));
331                 }
332 
333                 // position changes Y
334                 if(0.0 == aRectPoint.getY())
335                 {
336                     aBitmapTopLeft.setY((fRangeHeight - aBitmapSize.getY()) * 0.5);
337                 }
338                 else if(1.0 == aRectPoint.getY())
339                 {
340                     aBitmapTopLeft.setY(fRangeHeight - aBitmapSize.getY());
341                 }
342 
343                 if(getTiling() && 0.0 != getOffsetPosition().getY())
344                 {
345                     aBitmapTopLeft.setY(aBitmapTopLeft.getY() + (aBitmapSize.getY() * (getOffsetPosition().getY() * 0.01)));
346                 }
347 
348                 // apply bitmap size scaling to unit rectangle
349                 aBitmapTopLeft.setX(aBitmapTopLeft.getX() / fRangeWidth);
350                 aBitmapTopLeft.setY(aBitmapTopLeft.getY() / fRangeHeight);
351                 aBitmapSize.setX(aBitmapSize.getX() / fRangeWidth);
352                 aBitmapSize.setY(aBitmapSize.getY() / fRangeHeight);
353             }
354 
355             // get offset in percent
356             const double fOffsetX(basegfx::clamp(getOffset().getX() * 0.01, 0.0, 1.0));
357             const double fOffsetY(basegfx::clamp(getOffset().getY() * 0.01, 0.0, 1.0));
358 
359             // create FillGraphicAttribute
360             return FillGraphicAttribute(
361                 aGraphic,
362                 basegfx::B2DRange(aBitmapTopLeft, aBitmapTopLeft + aBitmapSize),
363                 getTiling(),
364                 fOffsetX,
365                 fOffsetY);
366         }
367     } // end of namespace attribute
368 } // end of namespace drawinglayer
369 
370 //////////////////////////////////////////////////////////////////////////////
371 // eof
372