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 
27*035a2f44SArmin Le Grand #include <drawinglayer/attribute/sdrfillgraphicattribute.hxx>
28*035a2f44SArmin Le Grand #include <drawinglayer/attribute/fillgraphicattribute.hxx>
29*035a2f44SArmin Le Grand #include <vcl/graph.hxx>
30cdf0e10cSrcweir 
31cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
32cdf0e10cSrcweir 
33cdf0e10cSrcweir namespace drawinglayer
34cdf0e10cSrcweir {
35cdf0e10cSrcweir 	namespace attribute
36cdf0e10cSrcweir 	{
37*035a2f44SArmin Le Grand 		class ImpSdrFillGraphicAttribute
38cdf0e10cSrcweir 		{
39cdf0e10cSrcweir         public:
40cdf0e10cSrcweir 		    // refcounter
41cdf0e10cSrcweir 		    sal_uInt32								mnRefCount;
42cdf0e10cSrcweir 
43cdf0e10cSrcweir             // data definitions
44*035a2f44SArmin 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 
55*035a2f44SArmin Le Grand 			ImpSdrFillGraphicAttribute(
56*035a2f44SArmin 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),
65*035a2f44SArmin 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
77*035a2f44SArmin 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 
86*035a2f44SArmin Le Grand             bool operator==(const ImpSdrFillGraphicAttribute& rCandidate) const
87cdf0e10cSrcweir             {
88*035a2f44SArmin 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 
98*035a2f44SArmin Le Grand             static ImpSdrFillGraphicAttribute* get_global_default()
99cdf0e10cSrcweir             {
100*035a2f44SArmin Le Grand                 static ImpSdrFillGraphicAttribute* pDefault = 0;
101cdf0e10cSrcweir 
102cdf0e10cSrcweir                 if(!pDefault)
103cdf0e10cSrcweir                 {
104*035a2f44SArmin Le Grand                     pDefault = new ImpSdrFillGraphicAttribute(
105*035a2f44SArmin 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 
122*035a2f44SArmin Le Grand         SdrFillGraphicAttribute::SdrFillGraphicAttribute(
123*035a2f44SArmin 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)
131*035a2f44SArmin Le Grand 		:	mpSdrFillGraphicAttribute(
132*035a2f44SArmin Le Grand                 new ImpSdrFillGraphicAttribute(
133*035a2f44SArmin 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 
144*035a2f44SArmin Le Grand 		SdrFillGraphicAttribute::SdrFillGraphicAttribute()
145*035a2f44SArmin Le Grand         :	mpSdrFillGraphicAttribute(ImpSdrFillGraphicAttribute::get_global_default())
146cdf0e10cSrcweir 		{
147*035a2f44SArmin Le Grand 			mpSdrFillGraphicAttribute->mnRefCount++;
148cdf0e10cSrcweir 		}
149cdf0e10cSrcweir 
150*035a2f44SArmin Le Grand         SdrFillGraphicAttribute::SdrFillGraphicAttribute(const SdrFillGraphicAttribute& rCandidate)
151*035a2f44SArmin Le Grand 		:	mpSdrFillGraphicAttribute(rCandidate.mpSdrFillGraphicAttribute)
152cdf0e10cSrcweir 		{
153*035a2f44SArmin Le Grand 			mpSdrFillGraphicAttribute->mnRefCount++;
154cdf0e10cSrcweir 		}
155cdf0e10cSrcweir 
156*035a2f44SArmin Le Grand 		SdrFillGraphicAttribute::~SdrFillGraphicAttribute()
157cdf0e10cSrcweir 		{
158*035a2f44SArmin Le Grand 			if(mpSdrFillGraphicAttribute->mnRefCount)
159cdf0e10cSrcweir 			{
160*035a2f44SArmin Le Grand 				mpSdrFillGraphicAttribute->mnRefCount--;
161cdf0e10cSrcweir 			}
162cdf0e10cSrcweir 			else
163cdf0e10cSrcweir 			{
164*035a2f44SArmin Le Grand 				delete mpSdrFillGraphicAttribute;
165cdf0e10cSrcweir 			}
166cdf0e10cSrcweir 		}
167cdf0e10cSrcweir 
168*035a2f44SArmin Le Grand         bool SdrFillGraphicAttribute::isDefault() const
169cdf0e10cSrcweir         {
170*035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute == ImpSdrFillGraphicAttribute::get_global_default();
171cdf0e10cSrcweir         }
172cdf0e10cSrcweir 
173*035a2f44SArmin Le Grand         SdrFillGraphicAttribute& SdrFillGraphicAttribute::operator=(const SdrFillGraphicAttribute& rCandidate)
174cdf0e10cSrcweir 		{
175*035a2f44SArmin Le Grand 			if(rCandidate.mpSdrFillGraphicAttribute != mpSdrFillGraphicAttribute)
176cdf0e10cSrcweir 			{
177*035a2f44SArmin Le Grand 				if(mpSdrFillGraphicAttribute->mnRefCount)
178cdf0e10cSrcweir 				{
179*035a2f44SArmin Le Grand 					mpSdrFillGraphicAttribute->mnRefCount--;
180cdf0e10cSrcweir 				}
181cdf0e10cSrcweir 				else
182cdf0e10cSrcweir 				{
183*035a2f44SArmin Le Grand 					delete mpSdrFillGraphicAttribute;
184cdf0e10cSrcweir 				}
185cdf0e10cSrcweir 
186*035a2f44SArmin Le Grand 				mpSdrFillGraphicAttribute = rCandidate.mpSdrFillGraphicAttribute;
187*035a2f44SArmin Le Grand 				mpSdrFillGraphicAttribute->mnRefCount++;
188cdf0e10cSrcweir 			}
189cdf0e10cSrcweir 
190cdf0e10cSrcweir 			return *this;
191cdf0e10cSrcweir 		}
192cdf0e10cSrcweir 
193*035a2f44SArmin Le Grand 		bool SdrFillGraphicAttribute::operator==(const SdrFillGraphicAttribute& rCandidate) const
194cdf0e10cSrcweir 		{
195*035a2f44SArmin Le Grand 			if(rCandidate.mpSdrFillGraphicAttribute == mpSdrFillGraphicAttribute)
196cdf0e10cSrcweir 			{
197cdf0e10cSrcweir 				return true;
198cdf0e10cSrcweir 			}
199cdf0e10cSrcweir 
200cdf0e10cSrcweir 			if(rCandidate.isDefault() != isDefault())
201cdf0e10cSrcweir 			{
202cdf0e10cSrcweir 				return false;
203cdf0e10cSrcweir 			}
204cdf0e10cSrcweir 
205*035a2f44SArmin Le Grand 			return (*rCandidate.mpSdrFillGraphicAttribute == *mpSdrFillGraphicAttribute);
206cdf0e10cSrcweir 		}
207cdf0e10cSrcweir 
208*035a2f44SArmin Le Grand         const Graphic& SdrFillGraphicAttribute::getFillGraphic() const
209cdf0e10cSrcweir         {
210*035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getFillGraphic();
211cdf0e10cSrcweir         }
212cdf0e10cSrcweir 
213*035a2f44SArmin Le Grand         const basegfx::B2DVector& SdrFillGraphicAttribute::getSize() const
214cdf0e10cSrcweir         {
215*035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getSize();
216cdf0e10cSrcweir         }
217cdf0e10cSrcweir 
218*035a2f44SArmin Le Grand         const basegfx::B2DVector& SdrFillGraphicAttribute::getOffset() const
219cdf0e10cSrcweir         {
220*035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getOffset();
221cdf0e10cSrcweir         }
222cdf0e10cSrcweir 
223*035a2f44SArmin Le Grand         const basegfx::B2DVector& SdrFillGraphicAttribute::getOffsetPosition() const
224cdf0e10cSrcweir         {
225*035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getOffsetPosition();
226cdf0e10cSrcweir         }
227cdf0e10cSrcweir 
228*035a2f44SArmin Le Grand         const basegfx::B2DVector& SdrFillGraphicAttribute::getRectPoint() const
229cdf0e10cSrcweir         {
230*035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getRectPoint();
231cdf0e10cSrcweir         }
232cdf0e10cSrcweir 
233*035a2f44SArmin Le Grand         bool SdrFillGraphicAttribute::getTiling() const
234cdf0e10cSrcweir         {
235*035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getTiling();
236cdf0e10cSrcweir         }
237cdf0e10cSrcweir 
238*035a2f44SArmin Le Grand         bool SdrFillGraphicAttribute::getStretch() const
239cdf0e10cSrcweir         {
240*035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getStretch();
241cdf0e10cSrcweir         }
242cdf0e10cSrcweir 
243*035a2f44SArmin Le Grand         bool SdrFillGraphicAttribute::getLogSize() const
244cdf0e10cSrcweir         {
245*035a2f44SArmin Le Grand             return mpSdrFillGraphicAttribute->getLogSize();
246cdf0e10cSrcweir         }
247cdf0e10cSrcweir 
248*035a2f44SArmin Le Grand         FillGraphicAttribute SdrFillGraphicAttribute::createFillGraphicAttribute(const basegfx::B2DRange& rRange) const
249cdf0e10cSrcweir 		{
250cdf0e10cSrcweir 			// get logical size of bitmap (before expanding eventually)
251*035a2f44SArmin Le Grand 			Graphic aGraphic(getFillGraphic());
252*035a2f44SArmin Le Grand 			const basegfx::B2DVector aLogicalSize(aGraphic.GetPrefSize().getWidth(), aGraphic.GetPrefSize().getHeight());
253cdf0e10cSrcweir 
254cdf0e10cSrcweir 			// init values with defaults
255cdf0e10cSrcweir 			basegfx::B2DPoint aBitmapSize(1.0, 1.0);
256cdf0e10cSrcweir 			basegfx::B2DVector aBitmapTopLeft(0.0, 0.0);
257cdf0e10cSrcweir 
258*035a2f44SArmin Le Grand 			// are changes needed?
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 				// get values, force to centered if necessary
300cdf0e10cSrcweir 				const basegfx::B2DVector aRectPoint(getTiling() ? getRectPoint() : basegfx::B2DVector(0.0, 0.0));
301cdf0e10cSrcweir 
302cdf0e10cSrcweir 				// position changes X
303cdf0e10cSrcweir 				if(0.0 == aRectPoint.getX())
304cdf0e10cSrcweir 				{
305cdf0e10cSrcweir 					aBitmapTopLeft.setX((fRangeWidth - aBitmapSize.getX()) * 0.5);
306cdf0e10cSrcweir 				}
307cdf0e10cSrcweir 				else if(1.0 == aRectPoint.getX())
308cdf0e10cSrcweir 				{
309cdf0e10cSrcweir 					aBitmapTopLeft.setX(fRangeWidth - aBitmapSize.getX());
310cdf0e10cSrcweir 				}
311cdf0e10cSrcweir 
312cdf0e10cSrcweir 				if(getTiling() && 0.0 != getOffsetPosition().getX())
313cdf0e10cSrcweir 				{
314cdf0e10cSrcweir 					aBitmapTopLeft.setX(aBitmapTopLeft.getX() + (aBitmapSize.getX() * (getOffsetPosition().getX() * 0.01)));
315cdf0e10cSrcweir 				}
316cdf0e10cSrcweir 
317cdf0e10cSrcweir 				// position changes Y
318cdf0e10cSrcweir 				if(0.0 == aRectPoint.getY())
319cdf0e10cSrcweir 				{
320cdf0e10cSrcweir 					aBitmapTopLeft.setY((fRangeHeight - aBitmapSize.getY()) * 0.5);
321cdf0e10cSrcweir 				}
322cdf0e10cSrcweir 				else if(1.0 == aRectPoint.getY())
323cdf0e10cSrcweir 				{
324cdf0e10cSrcweir 					aBitmapTopLeft.setY(fRangeHeight - aBitmapSize.getY());
325cdf0e10cSrcweir 				}
326cdf0e10cSrcweir 
327cdf0e10cSrcweir 				if(getTiling() && 0.0 != getOffsetPosition().getY())
328cdf0e10cSrcweir 				{
329cdf0e10cSrcweir 					aBitmapTopLeft.setY(aBitmapTopLeft.getY() + (aBitmapSize.getY() * (getOffsetPosition().getY() * 0.01)));
330cdf0e10cSrcweir 				}
331cdf0e10cSrcweir 
332cdf0e10cSrcweir 				// apply bitmap size scaling to unit rectangle
333cdf0e10cSrcweir 				aBitmapTopLeft.setX(aBitmapTopLeft.getX() / fRangeWidth);
334cdf0e10cSrcweir 				aBitmapTopLeft.setY(aBitmapTopLeft.getY() / fRangeHeight);
335cdf0e10cSrcweir 				aBitmapSize.setX(aBitmapSize.getX() / fRangeWidth);
336cdf0e10cSrcweir 				aBitmapSize.setY(aBitmapSize.getY() / fRangeHeight);
337cdf0e10cSrcweir 			}
338cdf0e10cSrcweir 
339*035a2f44SArmin Le Grand             // get offset in percent
340*035a2f44SArmin Le Grand             const double fOffsetX(basegfx::clamp(getOffset().getX() * 0.01, 0.0, 1.0));
341*035a2f44SArmin Le Grand             const double fOffsetY(basegfx::clamp(getOffset().getY() * 0.01, 0.0, 1.0));
342*035a2f44SArmin Le Grand 
343*035a2f44SArmin Le Grand             // create FillGraphicAttribute
344*035a2f44SArmin Le Grand             return FillGraphicAttribute(
345*035a2f44SArmin Le Grand                 aGraphic,
346*035a2f44SArmin Le Grand                 basegfx::B2DRange(aBitmapTopLeft, aBitmapTopLeft + aBitmapSize),
347*035a2f44SArmin Le Grand                 getTiling(),
348*035a2f44SArmin Le Grand                 fOffsetX,
349*035a2f44SArmin Le Grand                 fOffsetY);
350cdf0e10cSrcweir 		}
351cdf0e10cSrcweir 	} // end of namespace attribute
352cdf0e10cSrcweir } // end of namespace drawinglayer
353cdf0e10cSrcweir 
354cdf0e10cSrcweir //////////////////////////////////////////////////////////////////////////////
355cdf0e10cSrcweir // eof
356