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/primitive2d/baseprimitive2d.hxx>
28 #include <drawinglayer/geometry/viewinformation2d.hxx>
29 #include <basegfx/tools/canvastools.hxx>
30 
31 //////////////////////////////////////////////////////////////////////////////
32 
33 using namespace com::sun::star;
34 
35 //////////////////////////////////////////////////////////////////////////////
36 
37 namespace drawinglayer
38 {
39 	namespace primitive2d
40 	{
BasePrimitive2D()41 		BasePrimitive2D::BasePrimitive2D()
42 		:	BasePrimitive2DImplBase(m_aMutex)
43 		{
44 		}
45 
~BasePrimitive2D()46         BasePrimitive2D::~BasePrimitive2D()
47         {
48         }
49 
operator ==(const BasePrimitive2D & rPrimitive) const50 		bool BasePrimitive2D::operator==( const BasePrimitive2D& rPrimitive ) const
51 		{
52 			return (getPrimitive2DID() == rPrimitive.getPrimitive2DID());
53 		}
54 
getB2DRange(const geometry::ViewInformation2D & rViewInformation) const55 		basegfx::B2DRange BasePrimitive2D::getB2DRange(const geometry::ViewInformation2D& rViewInformation) const
56 		{
57 			return getB2DRangeFromPrimitive2DSequence(get2DDecomposition(rViewInformation), rViewInformation);
58 		}
59 
get2DDecomposition(const geometry::ViewInformation2D &) const60 		Primitive2DSequence BasePrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
61 		{
62 			return Primitive2DSequence();
63 		}
64 
getDecomposition(const uno::Sequence<beans::PropertyValue> & rViewParameters)65 		Primitive2DSequence SAL_CALL BasePrimitive2D::getDecomposition( const uno::Sequence< beans::PropertyValue >& rViewParameters ) throw ( uno::RuntimeException )
66 		{
67 			const geometry::ViewInformation2D aViewInformation(rViewParameters);
68 			return get2DDecomposition(aViewInformation);
69 		}
70 
getRange(const uno::Sequence<beans::PropertyValue> & rViewParameters)71 		com::sun::star::geometry::RealRectangle2D SAL_CALL BasePrimitive2D::getRange( const uno::Sequence< beans::PropertyValue >& rViewParameters ) throw ( uno::RuntimeException )
72 		{
73 			const geometry::ViewInformation2D aViewInformation(rViewParameters);
74 			return basegfx::unotools::rectangle2DFromB2DRectangle(getB2DRange(aViewInformation));
75 		}
76 	} // end of namespace primitive2d
77 } // end of namespace drawinglayer
78 
79 //////////////////////////////////////////////////////////////////////////////
80 
81 namespace drawinglayer
82 {
83 	namespace primitive2d
84 	{
create2DDecomposition(const geometry::ViewInformation2D &) const85 		Primitive2DSequence BufferedDecompositionPrimitive2D::create2DDecomposition(const geometry::ViewInformation2D& /*rViewInformation*/) const
86 		{
87 			return Primitive2DSequence();
88 		}
89 
BufferedDecompositionPrimitive2D()90 		BufferedDecompositionPrimitive2D::BufferedDecompositionPrimitive2D()
91 		:	BasePrimitive2D(),
92             maBuffered2DDecomposition()
93 		{
94 		}
95 
get2DDecomposition(const geometry::ViewInformation2D & rViewInformation) const96 		Primitive2DSequence BufferedDecompositionPrimitive2D::get2DDecomposition(const geometry::ViewInformation2D& rViewInformation) const
97 		{
98 			::osl::MutexGuard aGuard( m_aMutex );
99 
100 			if(!getBuffered2DDecomposition().hasElements())
101 			{
102 				const Primitive2DSequence aNewSequence(create2DDecomposition(rViewInformation));
103 				const_cast< BufferedDecompositionPrimitive2D* >(this)->setBuffered2DDecomposition(aNewSequence);
104 			}
105 
106 			return getBuffered2DDecomposition();
107 		}
108 	} // end of namespace primitive2d
109 } // end of namespace drawinglayer
110 
111 //////////////////////////////////////////////////////////////////////////////
112 // tooling
113 
114 namespace drawinglayer
115 {
116 	namespace primitive2d
117 	{
118         // convert helper stl vector of primitives to Primitive2DSequence
Primitive2DVectorToPrimitive2DSequence(const Primitive2DVector & rSource,bool bInvert)119         Primitive2DSequence Primitive2DVectorToPrimitive2DSequence(const Primitive2DVector& rSource, bool bInvert)
120         {
121             const sal_uInt32 nSize(rSource.size());
122             Primitive2DSequence aRetval;
123 
124             aRetval.realloc(nSize);
125 
126             for(sal_uInt32 a(0); a < nSize; a++)
127             {
128                 aRetval[bInvert ? nSize - 1 - a : a] = rSource[a];
129             }
130 
131             // all entries taken over to Uno References as owners. To avoid
132             // errors with users of this mechanism to delete pointers to BasePrimitive2D
133             // itself, clear given vector
134             const_cast< Primitive2DVector& >(rSource).clear();
135 
136             return aRetval;
137         }
138 
139 		// get B2DRange from a given Primitive2DReference
getB2DRangeFromPrimitive2DReference(const Primitive2DReference & rCandidate,const geometry::ViewInformation2D & aViewInformation)140 		basegfx::B2DRange getB2DRangeFromPrimitive2DReference(const Primitive2DReference& rCandidate, const geometry::ViewInformation2D& aViewInformation)
141 		{
142 			basegfx::B2DRange aRetval;
143 
144 			if(rCandidate.is())
145 			{
146 				// try to get C++ implementation base
147 				const BasePrimitive2D* pCandidate(dynamic_cast< BasePrimitive2D* >(rCandidate.get()));
148 
149 				if(pCandidate)
150 				{
151 					// use it if possible
152 					aRetval.expand(pCandidate->getB2DRange(aViewInformation));
153 				}
154 				else
155 				{
156 					// use UNO API call instead
157 					const uno::Sequence< beans::PropertyValue >& rViewParameters(aViewInformation.getViewInformationSequence());
158 					aRetval.expand(basegfx::unotools::b2DRectangleFromRealRectangle2D(rCandidate->getRange(rViewParameters)));
159 				}
160 			}
161 
162 			return aRetval;
163 		}
164 
165 		// get B2DRange from a given Primitive2DSequence
getB2DRangeFromPrimitive2DSequence(const Primitive2DSequence & rCandidate,const geometry::ViewInformation2D & aViewInformation)166 		basegfx::B2DRange getB2DRangeFromPrimitive2DSequence(const Primitive2DSequence& rCandidate, const geometry::ViewInformation2D& aViewInformation)
167 		{
168 			basegfx::B2DRange aRetval;
169 
170 			if(rCandidate.hasElements())
171 			{
172 				const sal_Int32 nCount(rCandidate.getLength());
173 
174 				for(sal_Int32 a(0L); a < nCount; a++)
175 				{
176 					aRetval.expand(getB2DRangeFromPrimitive2DReference(rCandidate[a], aViewInformation));
177 				}
178 			}
179 
180 			return aRetval;
181 		}
182 
arePrimitive2DReferencesEqual(const Primitive2DReference & rxA,const Primitive2DReference & rxB)183 		bool arePrimitive2DReferencesEqual(const Primitive2DReference& rxA, const Primitive2DReference& rxB)
184 		{
185 			const sal_Bool bAIs(rxA.is());
186 
187 			if(bAIs != rxB.is())
188 			{
189 				return false;
190 			}
191 
192 			if(!bAIs)
193 			{
194 				return true;
195 			}
196 
197 			const BasePrimitive2D* pA(dynamic_cast< const BasePrimitive2D* >(rxA.get()));
198 			const BasePrimitive2D* pB(dynamic_cast< const BasePrimitive2D* >(rxB.get()));
199 			const bool bAEqualZero(pA == 0L);
200 
201 			if(bAEqualZero != (pB == 0L))
202 			{
203 				return false;
204 			}
205 
206 			if(bAEqualZero)
207 			{
208 				return false;
209 			}
210 
211 			return (pA->operator==(*pB));
212 		}
213 
arePrimitive2DSequencesEqual(const Primitive2DSequence & rA,const Primitive2DSequence & rB)214 		bool arePrimitive2DSequencesEqual(const Primitive2DSequence& rA, const Primitive2DSequence& rB)
215 		{
216 			const sal_Bool bAHasElements(rA.hasElements());
217 
218 			if(bAHasElements != rB.hasElements())
219 			{
220 				return false;
221 			}
222 
223 			if(!bAHasElements)
224 			{
225 				return true;
226 			}
227 
228 			const sal_Int32 nCount(rA.getLength());
229 
230 			if(nCount != rB.getLength())
231 			{
232 				return false;
233 			}
234 
235 			for(sal_Int32 a(0L); a < nCount; a++)
236 			{
237 				if(!arePrimitive2DReferencesEqual(rA[a], rB[a]))
238 				{
239 					return false;
240 				}
241 			}
242 
243 			return true;
244 		}
245 
246 		// concatenate sequence
appendPrimitive2DSequenceToPrimitive2DSequence(Primitive2DSequence & rDest,const Primitive2DSequence & rSource)247 		void appendPrimitive2DSequenceToPrimitive2DSequence(Primitive2DSequence& rDest, const Primitive2DSequence& rSource)
248 		{
249 			if(rSource.hasElements())
250 			{
251 				if(rDest.hasElements())
252 				{
253 					const sal_Int32 nSourceCount(rSource.getLength());
254 					const sal_Int32 nDestCount(rDest.getLength());
255 					const sal_Int32 nTargetCount(nSourceCount + nDestCount);
256 					sal_Int32 nInsertPos(nDestCount);
257 
258 					rDest.realloc(nTargetCount);
259 
260 					for(sal_Int32 a(0L); a < nSourceCount; a++)
261 					{
262 						if(rSource[a].is())
263 						{
264 							rDest[nInsertPos++] = rSource[a];
265 						}
266 					}
267 
268 					if(nInsertPos != nTargetCount)
269 					{
270 						rDest.realloc(nInsertPos);
271 					}
272 				}
273 				else
274 				{
275 					rDest = rSource;
276 				}
277 			}
278 		}
279 
280 		// concatenate single Primitive2D
appendPrimitive2DReferenceToPrimitive2DSequence(Primitive2DSequence & rDest,const Primitive2DReference & rSource)281 		void appendPrimitive2DReferenceToPrimitive2DSequence(Primitive2DSequence& rDest, const Primitive2DReference& rSource)
282 		{
283 			if(rSource.is())
284 			{
285 				const sal_Int32 nDestCount(rDest.getLength());
286 				rDest.realloc(nDestCount + 1L);
287 				rDest[nDestCount] = rSource;
288 			}
289 		}
290 
291 	} // end of namespace primitive2d
292 } // end of namespace drawinglayer
293 
294 //////////////////////////////////////////////////////////////////////////////
295 // eof
296