1464702f4SAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3464702f4SAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4464702f4SAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5464702f4SAndrew Rist  * distributed with this work for additional information
6464702f4SAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7464702f4SAndrew Rist  * to you under the Apache License, Version 2.0 (the
8464702f4SAndrew Rist  * "License"); you may not use this file except in compliance
9464702f4SAndrew Rist  * with the License.  You may obtain a copy of the License at
10464702f4SAndrew Rist  *
11464702f4SAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12464702f4SAndrew Rist  *
13464702f4SAndrew Rist  * Unless required by applicable law or agreed to in writing,
14464702f4SAndrew Rist  * software distributed under the License is distributed on an
15464702f4SAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16464702f4SAndrew Rist  * KIND, either express or implied.  See the License for the
17464702f4SAndrew Rist  * specific language governing permissions and limitations
18464702f4SAndrew Rist  * under the License.
19464702f4SAndrew Rist  *
20464702f4SAndrew Rist  *************************************************************/
21464702f4SAndrew Rist 
22464702f4SAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_drawinglayer.hxx"
26cdf0e10cSrcweir 
27035a2f44SArmin Le Grand #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
28035a2f44SArmin Le Grand #include <drawinglayer/attribute/fillgraphicattribute.hxx>
29035a2f44SArmin Le Grand #include <vcl/graph.hxx>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
32cdf0e10cSrcweir 
33cdf0e10cSrcweir namespace drawinglayer
34cdf0e10cSrcweir {
35cdf0e10cSrcweir 	namespace attribute
36cdf0e10cSrcweir 	{
37035a2f44SArmin Le Grand 		class ImpSdrFillGraphicAttribute
38cdf0e10cSrcweir 		{
39cdf0e10cSrcweir         public:
40cdf0e10cSrcweir 		    // refcounter
41cdf0e10cSrcweir 		    sal_uInt32								mnRefCount;
42cdf0e10cSrcweir 
43cdf0e10cSrcweir             // data definitions
44035a2f44SArmin Le Grand 			Graphic                                 maFillGraphic;
45cdf0e10cSrcweir 			basegfx::B2DVector						maSize;
46cdf0e10cSrcweir 			basegfx::B2DVector						maOffset;
47cdf0e10cSrcweir 			basegfx::B2DVector						maOffsetPosition;
48cdf0e10cSrcweir 			basegfx::B2DVector						maRectPoint;
49cdf0e10cSrcweir 
50cdf0e10cSrcweir 			// bitfield
51cdf0e10cSrcweir 			unsigned								mbTiling : 1;
52cdf0e10cSrcweir 			unsigned								mbStretch : 1;
53cdf0e10cSrcweir 			unsigned								mbLogSize : 1;
54cdf0e10cSrcweir 
55035a2f44SArmin Le Grand 			ImpSdrFillGraphicAttribute(
56035a2f44SArmin Le Grand 				const Graphic& rFillGraphic,
57cdf0e10cSrcweir                 const basegfx::B2DVector& rSize,
58cdf0e10cSrcweir                 const basegfx::B2DVector& rOffset,
59cdf0e10cSrcweir 				const basegfx::B2DVector& rOffsetPosition,
60cdf0e10cSrcweir                 const basegfx::B2DVector& rRectPoint,
61cdf0e10cSrcweir 				bool bTiling,
62cdf0e10cSrcweir                 bool bStretch,
63cdf0e10cSrcweir                 bool bLogSize)
64cdf0e10cSrcweir 		    :	mnRefCount(0),
65035a2f44SArmin Le Grand 		    	maFillGraphic(rFillGraphic),
66cdf0e10cSrcweir 			    maSize(rSize),
67cdf0e10cSrcweir 			    maOffset(rOffset),
68cdf0e10cSrcweir 			    maOffsetPosition(rOffsetPosition),
69cdf0e10cSrcweir 			    maRectPoint(rRectPoint),
70cdf0e10cSrcweir 			    mbTiling(bTiling),
71cdf0e10cSrcweir 			    mbStretch(bStretch),
72cdf0e10cSrcweir 			    mbLogSize(bLogSize)
73cdf0e10cSrcweir 		    {
74cdf0e10cSrcweir 		    }
75cdf0e10cSrcweir 
76cdf0e10cSrcweir 			// data read access
77035a2f44SArmin Le Grand             const Graphic& getFillGraphic() const { return maFillGraphic; }
78cdf0e10cSrcweir             const basegfx::B2DVector& getSize() const { return maSize; }
79cdf0e10cSrcweir             const basegfx::B2DVector& getOffset() const { return maOffset; }
80cdf0e10cSrcweir             const basegfx::B2DVector& getOffsetPosition() const { return maOffsetPosition; }
81cdf0e10cSrcweir             const basegfx::B2DVector& getRectPoint() const { return maRectPoint; }
82cdf0e10cSrcweir             bool getTiling() const { return mbTiling; }
83cdf0e10cSrcweir             bool getStretch() const { return mbStretch; }
84cdf0e10cSrcweir             bool getLogSize() const { return mbLogSize; }
85cdf0e10cSrcweir 
86035a2f44SArmin Le Grand             bool operator==(const ImpSdrFillGraphicAttribute& rCandidate) const
87cdf0e10cSrcweir             {
88035a2f44SArmin Le Grand 			    return (getFillGraphic() == rCandidate.getFillGraphic()
89cdf0e10cSrcweir 				    && getSize() == rCandidate.getSize()
90cdf0e10cSrcweir 				    && getOffset() == rCandidate.getOffset()
91cdf0e10cSrcweir 				    && getOffsetPosition() == rCandidate.getOffsetPosition()
92cdf0e10cSrcweir 				    && getRectPoint() == rCandidate.getRectPoint()
93cdf0e10cSrcweir 				    && getTiling() == rCandidate.getTiling()
94cdf0e10cSrcweir 				    && getStretch() == rCandidate.getStretch()
95cdf0e10cSrcweir 				    && getLogSize() == rCandidate.getLogSize());
96cdf0e10cSrcweir             }
97cdf0e10cSrcweir 
98035a2f44SArmin Le Grand             static ImpSdrFillGraphicAttribute* get_global_default()
99cdf0e10cSrcweir             {
100035a2f44SArmin Le Grand                 static ImpSdrFillGraphicAttribute* pDefault = 0;
101cdf0e10cSrcweir 
102cdf0e10cSrcweir                 if(!pDefault)
103cdf0e10cSrcweir                 {
104035a2f44SArmin Le Grand                     pDefault = new ImpSdrFillGraphicAttribute(
105035a2f44SArmin Le Grand 			            Graphic(),
106cdf0e10cSrcweir                         basegfx::B2DVector(),
107cdf0e10cSrcweir                         basegfx::B2DVector(),
108cdf0e10cSrcweir 			            basegfx::B2DVector(),
109cdf0e10cSrcweir                         basegfx::B2DVector(),
110cdf0e10cSrcweir 			            false,
111cdf0e10cSrcweir                         false,
112cdf0e10cSrcweir                         false);
113cdf0e10cSrcweir 
114cdf0e10cSrcweir                     // never delete; start with RefCount 1, not 0
115cdf0e10cSrcweir     			    pDefault->mnRefCount++;
116cdf0e10cSrcweir                 }
117cdf0e10cSrcweir 
118cdf0e10cSrcweir                 return pDefault;
119cdf0e10cSrcweir             }
120cdf0e10cSrcweir 		};
121cdf0e10cSrcweir 
122035a2f44SArmin Le Grand         SdrFillGraphicAttribute::SdrFillGraphicAttribute(
123035a2f44SArmin Le Grand 			const Graphic& rFillGraphic,
124cdf0e10cSrcweir             const basegfx::B2DVector& rSize,
125cdf0e10cSrcweir             const basegfx::B2DVector& rOffset,
126cdf0e10cSrcweir 			const basegfx::B2DVector& rOffsetPosition,
127cdf0e10cSrcweir             const basegfx::B2DVector& rRectPoint,
128cdf0e10cSrcweir 			bool bTiling,
129cdf0e10cSrcweir             bool bStretch,
130cdf0e10cSrcweir             bool bLogSize)
131035a2f44SArmin Le Grand 		:	mpSdrFillGraphicAttribute(
132035a2f44SArmin Le Grand                 new ImpSdrFillGraphicAttribute(
133035a2f44SArmin Le Grand                     rFillGraphic,
13470d3707aSArmin Le Grand                     rSize,
13570d3707aSArmin Le Grand                     rOffset,
13670d3707aSArmin Le Grand                     rOffsetPosition,
13770d3707aSArmin Le Grand                     rRectPoint,
13870d3707aSArmin Le Grand                     bTiling,
13970d3707aSArmin Le Grand                     bStretch,
14070d3707aSArmin Le Grand                     bLogSize))
141cdf0e10cSrcweir 		{
142cdf0e10cSrcweir 		}
143cdf0e10cSrcweir 
144035a2f44SArmin Le Grand 		SdrFillGraphicAttribute::SdrFillGraphicAttribute()
145035a2f44SArmin Le Grand         :	mpSdrFillGraphicAttribute(ImpSdrFillGraphicAttribute::get_global_default())
146cdf0e10cSrcweir 		{
147035a2f44SArmin Le Grand 			mpSdrFillGraphicAttribute->mnRefCount++;
148cdf0e10cSrcweir 		}
149cdf0e10cSrcweir 
150035a2f44SArmin Le Grand         SdrFillGraphicAttribute::SdrFillGraphicAttribute(const SdrFillGraphicAttribute& rCandidate)
151035a2f44SArmin Le Grand 		:	mpSdrFillGraphicAttribute(rCandidate.mpSdrFillGraphicAttribute)
152cdf0e10cSrcweir 		{
153035a2f44SArmin Le Grand 			mpSdrFillGraphicAttribute->mnRefCount++;
154cdf0e10cSrcweir 		}
155cdf0e10cSrcweir 
156035a2f44SArmin Le Grand 		SdrFillGraphicAttribute::~SdrFillGraphicAttribute()
157cdf0e10cSrcweir 		{
158035a2f44SArmin Le Grand 			if(mpSdrFillGraphicAttribute->mnRefCount)
159cdf0e10cSrcweir 			{
160035a2f44SArmin Le Grand 				mpSdrFillGraphicAttribute->mnRefCount--;
161cdf0e10cSrcweir 			}
162cdf0e10cSrcweir 			else
163cdf0e10cSrcweir 			{
164035a2f44SArmin Le Grand 				delete mpSdrFillGraphicAttribute;
165cdf0e10cSrcweir 			}
166cdf0e10cSrcweir 		}
167cdf0e10cSrcweir 
168035a2f44SArmin Le Grand         bool SdrFillGraphicAttribute::isDefault() const
169cdf0e10cSrcweir         {
170035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute == ImpSdrFillGraphicAttribute::get_global_default();
171cdf0e10cSrcweir         }
172cdf0e10cSrcweir 
173035a2f44SArmin Le Grand         SdrFillGraphicAttribute& SdrFillGraphicAttribute::operator=(const SdrFillGraphicAttribute& rCandidate)
174cdf0e10cSrcweir 		{
175035a2f44SArmin Le Grand 			if(rCandidate.mpSdrFillGraphicAttribute != mpSdrFillGraphicAttribute)
176cdf0e10cSrcweir 			{
177035a2f44SArmin Le Grand 				if(mpSdrFillGraphicAttribute->mnRefCount)
178cdf0e10cSrcweir 				{
179035a2f44SArmin Le Grand 					mpSdrFillGraphicAttribute->mnRefCount--;
180cdf0e10cSrcweir 				}
181cdf0e10cSrcweir 				else
182cdf0e10cSrcweir 				{
183035a2f44SArmin Le Grand 					delete mpSdrFillGraphicAttribute;
184cdf0e10cSrcweir 				}
185cdf0e10cSrcweir 
186035a2f44SArmin Le Grand 				mpSdrFillGraphicAttribute = rCandidate.mpSdrFillGraphicAttribute;
187035a2f44SArmin Le Grand 				mpSdrFillGraphicAttribute->mnRefCount++;
188cdf0e10cSrcweir 			}
189cdf0e10cSrcweir 
190cdf0e10cSrcweir 			return *this;
191cdf0e10cSrcweir 		}
192cdf0e10cSrcweir 
193035a2f44SArmin Le Grand 		bool SdrFillGraphicAttribute::operator==(const SdrFillGraphicAttribute& rCandidate) const
194cdf0e10cSrcweir 		{
195035a2f44SArmin Le Grand 			if(rCandidate.mpSdrFillGraphicAttribute == mpSdrFillGraphicAttribute)
196cdf0e10cSrcweir 			{
197cdf0e10cSrcweir 				return true;
198cdf0e10cSrcweir 			}
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 			if(rCandidate.isDefault() != isDefault())
201cdf0e10cSrcweir 			{
202cdf0e10cSrcweir 				return false;
203cdf0e10cSrcweir 			}
204cdf0e10cSrcweir 
205035a2f44SArmin Le Grand 			return (*rCandidate.mpSdrFillGraphicAttribute == *mpSdrFillGraphicAttribute);
206cdf0e10cSrcweir 		}
207cdf0e10cSrcweir 
208035a2f44SArmin Le Grand         const Graphic& SdrFillGraphicAttribute::getFillGraphic() const
209cdf0e10cSrcweir         {
210035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getFillGraphic();
211cdf0e10cSrcweir         }
212cdf0e10cSrcweir 
213035a2f44SArmin Le Grand         const basegfx::B2DVector& SdrFillGraphicAttribute::getSize() const
214cdf0e10cSrcweir         {
215035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getSize();
216cdf0e10cSrcweir         }
217cdf0e10cSrcweir 
218035a2f44SArmin Le Grand         const basegfx::B2DVector& SdrFillGraphicAttribute::getOffset() const
219cdf0e10cSrcweir         {
220035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getOffset();
221cdf0e10cSrcweir         }
222cdf0e10cSrcweir 
223035a2f44SArmin Le Grand         const basegfx::B2DVector& SdrFillGraphicAttribute::getOffsetPosition() const
224cdf0e10cSrcweir         {
225035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getOffsetPosition();
226cdf0e10cSrcweir         }
227cdf0e10cSrcweir 
228035a2f44SArmin Le Grand         const basegfx::B2DVector& SdrFillGraphicAttribute::getRectPoint() const
229cdf0e10cSrcweir         {
230035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getRectPoint();
231cdf0e10cSrcweir         }
232cdf0e10cSrcweir 
233035a2f44SArmin Le Grand         bool SdrFillGraphicAttribute::getTiling() const
234cdf0e10cSrcweir         {
235035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getTiling();
236cdf0e10cSrcweir         }
237cdf0e10cSrcweir 
238035a2f44SArmin Le Grand         bool SdrFillGraphicAttribute::getStretch() const
239cdf0e10cSrcweir         {
240035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getStretch();
241cdf0e10cSrcweir         }
242cdf0e10cSrcweir 
243035a2f44SArmin Le Grand         bool SdrFillGraphicAttribute::getLogSize() const
244cdf0e10cSrcweir         {
245035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getLogSize();
246cdf0e10cSrcweir         }
247cdf0e10cSrcweir 
248035a2f44SArmin Le Grand         FillGraphicAttribute SdrFillGraphicAttribute::createFillGraphicAttribute(const basegfx::B2DRange& rRange) const
249cdf0e10cSrcweir 		{
250cdf0e10cSrcweir 			// get logical size of bitmap (before expanding eventually)
251035a2f44SArmin Le Grand 			Graphic aGraphic(getFillGraphic());
252035a2f44SArmin Le Grand 			const basegfx::B2DVector aLogicalSize(aGraphic.GetPrefSize().getWidth(), aGraphic.GetPrefSize().getHeight());
253cdf0e10cSrcweir 
254*64b14621SArmin Le Grand 			// init values with defaults for stretched
255cdf0e10cSrcweir 			basegfx::B2DPoint aBitmapSize(1.0, 1.0);
256cdf0e10cSrcweir 			basegfx::B2DVector aBitmapTopLeft(0.0, 0.0);
257cdf0e10cSrcweir 
258*64b14621SArmin Le Grand 			//UUUU are changes needed? When streched we are already done, all other values will have no influence
259cdf0e10cSrcweir 			if(getTiling() || !getStretch())
260cdf0e10cSrcweir 			{
261cdf0e10cSrcweir 				// init values with range sizes
262cdf0e10cSrcweir 				const double fRangeWidth(0.0 != rRange.getWidth() ? rRange.getWidth() : 1.0);
263cdf0e10cSrcweir 				const double fRangeHeight(0.0 != rRange.getHeight() ? rRange.getHeight() : 1.0);
264cdf0e10cSrcweir 				aBitmapSize = basegfx::B2DPoint(fRangeWidth, fRangeHeight);
265cdf0e10cSrcweir 
266cdf0e10cSrcweir 				// size changes
267cdf0e10cSrcweir 				if(0.0 != getSize().getX())
268cdf0e10cSrcweir 				{
269cdf0e10cSrcweir 					if(getSize().getX() < 0.0)
270cdf0e10cSrcweir 					{
271cdf0e10cSrcweir 						aBitmapSize.setX(aBitmapSize.getX() * (getSize().getX() * -0.01));
272cdf0e10cSrcweir 					}
273cdf0e10cSrcweir 					else
274cdf0e10cSrcweir 					{
275cdf0e10cSrcweir 						aBitmapSize.setX(getSize().getX());
276cdf0e10cSrcweir 					}
277cdf0e10cSrcweir 				}
278cdf0e10cSrcweir 				else
279cdf0e10cSrcweir 				{
280cdf0e10cSrcweir 					aBitmapSize.setX(aLogicalSize.getX());
281cdf0e10cSrcweir 				}
282cdf0e10cSrcweir 
283cdf0e10cSrcweir 				if(0.0 != getSize().getY())
284cdf0e10cSrcweir 				{
285cdf0e10cSrcweir 					if(getSize().getY() < 0.0)
286cdf0e10cSrcweir 					{
287cdf0e10cSrcweir 						aBitmapSize.setY(aBitmapSize.getY() * (getSize().getY() * -0.01));
288cdf0e10cSrcweir 					}
289cdf0e10cSrcweir 					else
290cdf0e10cSrcweir 					{
291cdf0e10cSrcweir 						aBitmapSize.setY(getSize().getY());
292cdf0e10cSrcweir 					}
293cdf0e10cSrcweir 				}
294cdf0e10cSrcweir 				else
295cdf0e10cSrcweir 				{
296cdf0e10cSrcweir 					aBitmapSize.setY(aLogicalSize.getY());
297cdf0e10cSrcweir 				}
298cdf0e10cSrcweir 
299cdf0e10cSrcweir 				// position changes X
300*64b14621SArmin Le Grand 				if(0.0 == getRectPoint().getX())
301cdf0e10cSrcweir 				{
302cdf0e10cSrcweir 					aBitmapTopLeft.setX((fRangeWidth - aBitmapSize.getX()) * 0.5);
303cdf0e10cSrcweir 				}
304*64b14621SArmin Le Grand 				else if(1.0 == getRectPoint().getX())
305cdf0e10cSrcweir 				{
306cdf0e10cSrcweir 					aBitmapTopLeft.setX(fRangeWidth - aBitmapSize.getX());
307cdf0e10cSrcweir 				}
308cdf0e10cSrcweir 
309*64b14621SArmin Le Grand                 // offset positions are only meaningful when tiled
310cdf0e10cSrcweir 				if(getTiling() && 0.0 != getOffsetPosition().getX())
311cdf0e10cSrcweir 				{
312cdf0e10cSrcweir 					aBitmapTopLeft.setX(aBitmapTopLeft.getX() + (aBitmapSize.getX() * (getOffsetPosition().getX() * 0.01)));
313cdf0e10cSrcweir 				}
314cdf0e10cSrcweir 
315cdf0e10cSrcweir 				// position changes Y
316*64b14621SArmin Le Grand 				if(0.0 == getRectPoint().getY())
317cdf0e10cSrcweir 				{
318cdf0e10cSrcweir 					aBitmapTopLeft.setY((fRangeHeight - aBitmapSize.getY()) * 0.5);
319cdf0e10cSrcweir 				}
320*64b14621SArmin Le Grand 				else if(1.0 == getRectPoint().getY())
321cdf0e10cSrcweir 				{
322cdf0e10cSrcweir 					aBitmapTopLeft.setY(fRangeHeight - aBitmapSize.getY());
323cdf0e10cSrcweir 				}
324cdf0e10cSrcweir 
325*64b14621SArmin Le Grand                 // offset positions are only meaningful when tiled
326cdf0e10cSrcweir 				if(getTiling() && 0.0 != getOffsetPosition().getY())
327cdf0e10cSrcweir 				{
328cdf0e10cSrcweir 					aBitmapTopLeft.setY(aBitmapTopLeft.getY() + (aBitmapSize.getY() * (getOffsetPosition().getY() * 0.01)));
329cdf0e10cSrcweir 				}
330cdf0e10cSrcweir 
331cdf0e10cSrcweir 				// apply bitmap size scaling to unit rectangle
332cdf0e10cSrcweir 				aBitmapTopLeft.setX(aBitmapTopLeft.getX() / fRangeWidth);
333cdf0e10cSrcweir 				aBitmapTopLeft.setY(aBitmapTopLeft.getY() / fRangeHeight);
334cdf0e10cSrcweir 				aBitmapSize.setX(aBitmapSize.getX() / fRangeWidth);
335cdf0e10cSrcweir 				aBitmapSize.setY(aBitmapSize.getY() / fRangeHeight);
336cdf0e10cSrcweir 			}
337cdf0e10cSrcweir 
338035a2f44SArmin Le Grand             // get offset in percent
339035a2f44SArmin Le Grand             const double fOffsetX(basegfx::clamp(getOffset().getX() * 0.01, 0.0, 1.0));
340035a2f44SArmin Le Grand             const double fOffsetY(basegfx::clamp(getOffset().getY() * 0.01, 0.0, 1.0));
341035a2f44SArmin Le Grand 
342035a2f44SArmin Le Grand             // create FillGraphicAttribute
343035a2f44SArmin Le Grand             return FillGraphicAttribute(
344035a2f44SArmin Le Grand                 aGraphic,
345035a2f44SArmin Le Grand                 basegfx::B2DRange(aBitmapTopLeft, aBitmapTopLeft + aBitmapSize),
346035a2f44SArmin Le Grand                 getTiling(),
347035a2f44SArmin Le Grand                 fOffsetX,
348035a2f44SArmin Le Grand                 fOffsetY);
349cdf0e10cSrcweir 		}
350cdf0e10cSrcweir 	} // end of namespace attribute
351cdf0e10cSrcweir } // end of namespace drawinglayer
352cdf0e10cSrcweir 
353cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
354cdf0e10cSrcweir // eof
355