Branch data Line data Source code
1 : : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : : /*************************************************************************
3 : : *
4 : : * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 : : *
6 : : * Copyright 2000, 2010 Oracle and/or its affiliates.
7 : : *
8 : : * OpenOffice.org - a multi-platform office productivity suite
9 : : *
10 : : * This file is part of OpenOffice.org.
11 : : *
12 : : * OpenOffice.org is free software: you can redistribute it and/or modify
13 : : * it under the terms of the GNU Lesser General Public License version 3
14 : : * only, as published by the Free Software Foundation.
15 : : *
16 : : * OpenOffice.org is distributed in the hope that it will be useful,
17 : : * but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : : * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : : * GNU Lesser General Public License version 3 for more details
20 : : * (a copy is included in the LICENSE file that accompanied this code).
21 : : *
22 : : * You should have received a copy of the GNU Lesser General Public License
23 : : * version 3 along with OpenOffice.org. If not, see
24 : : * <http://www.openoffice.org/license.html>
25 : : * for a copy of the LGPLv3 License.
26 : : *
27 : : ************************************************************************/
28 : :
29 : :
30 : : #include <canvas/debug.hxx>
31 : : #include <tools/diagnose_ex.h>
32 : :
33 : : #include <com/sun/star/geometry/AffineMatrix2D.hpp>
34 : : #include <com/sun/star/geometry/Matrix2D.hpp>
35 : : #include <com/sun/star/awt/Rectangle.hpp>
36 : : #include <com/sun/star/util/Endianness.hpp>
37 : : #include <com/sun/star/rendering/XIntegerBitmapColorSpace.hpp>
38 : : #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
39 : : #include <com/sun/star/rendering/ColorSpaceType.hpp>
40 : : #include <com/sun/star/rendering/ColorComponentTag.hpp>
41 : : #include <com/sun/star/rendering/RenderingIntent.hpp>
42 : : #include <com/sun/star/rendering/RenderState.hpp>
43 : : #include <com/sun/star/rendering/ViewState.hpp>
44 : : #include <com/sun/star/rendering/XCanvas.hpp>
45 : : #include <com/sun/star/rendering/XColorSpace.hpp>
46 : : #include <com/sun/star/rendering/CompositeOperation.hpp>
47 : : #include <com/sun/star/beans/XPropertySet.hpp>
48 : : #include <com/sun/star/lang/XServiceInfo.hpp>
49 : :
50 : : #include <basegfx/matrix/b2dhommatrix.hxx>
51 : : #include <basegfx/range/b2drange.hxx>
52 : : #include <basegfx/range/b2irange.hxx>
53 : : #include <basegfx/range/b2drectangle.hxx>
54 : : #include <basegfx/point/b2dpoint.hxx>
55 : : #include <basegfx/point/b2ipoint.hxx>
56 : : #include <basegfx/vector/b2ivector.hxx>
57 : : #include <basegfx/polygon/b2dpolygon.hxx>
58 : : #include <basegfx/polygon/b2dpolygontools.hxx>
59 : : #include <basegfx/polygon/b2dpolypolygontools.hxx>
60 : : #include <basegfx/tools/canvastools.hxx>
61 : : #include <basegfx/numeric/ftools.hxx>
62 : : #include <basegfx/matrix/b2dhommatrixtools.hxx>
63 : :
64 : : #include <cppuhelper/compbase1.hxx>
65 : : #include <rtl/instance.hxx>
66 : : #include <toolkit/helper/vclunohelper.hxx>
67 : : #include <vcl/window.hxx>
68 : : #include <vcl/canvastools.hxx>
69 : :
70 : : #include <canvas/canvastools.hxx>
71 : :
72 : : #include <limits>
73 : :
74 : :
75 : : using namespace ::com::sun::star;
76 : :
77 : : namespace com { namespace sun { namespace star { namespace rendering
78 : : {
79 : 0 : bool operator==( const RenderState& renderState1,
80 : : const RenderState& renderState2 )
81 : : {
82 [ # # ][ # # ]: 0 : if( renderState1.Clip != renderState2.Clip )
83 : 0 : return false;
84 : :
85 [ # # ][ # # ]: 0 : if( renderState1.DeviceColor != renderState2.DeviceColor )
86 : 0 : return false;
87 : :
88 [ # # ]: 0 : if( renderState1.CompositeOperation != renderState2.CompositeOperation )
89 : 0 : return false;
90 : :
91 [ # # ][ # # ]: 0 : ::basegfx::B2DHomMatrix mat1, mat2;
92 [ # # ]: 0 : ::canvas::tools::getRenderStateTransform( mat1, renderState1 );
93 [ # # ]: 0 : ::canvas::tools::getRenderStateTransform( mat2, renderState2 );
94 [ # # ][ # # ]: 0 : if( mat1 != mat2 )
95 : 0 : return false;
96 : :
97 [ # # ][ # # ]: 0 : return true;
98 : : }
99 : :
100 : 0 : bool operator==( const ViewState& viewState1,
101 : : const ViewState& viewState2 )
102 : : {
103 [ # # ][ # # ]: 0 : if( viewState1.Clip != viewState2.Clip )
104 : 0 : return false;
105 : :
106 [ # # ][ # # ]: 0 : ::basegfx::B2DHomMatrix mat1, mat2;
107 [ # # ]: 0 : ::canvas::tools::getViewStateTransform( mat1, viewState1 );
108 [ # # ]: 0 : ::canvas::tools::getViewStateTransform( mat2, viewState2 );
109 [ # # ][ # # ]: 0 : if( mat1 != mat2 )
110 : 0 : return false;
111 : :
112 [ # # ][ # # ]: 0 : return true;
113 : : }
114 : : }}}}
115 : :
116 : : namespace canvas
117 : : {
118 : : namespace tools
119 : : {
120 : 0 : geometry::RealSize2D createInfiniteSize2D()
121 : : {
122 : : return geometry::RealSize2D(
123 : 0 : ::std::numeric_limits<double>::infinity(),
124 : 0 : ::std::numeric_limits<double>::infinity() );
125 : : }
126 : :
127 : 0 : rendering::RenderState& initRenderState( rendering::RenderState& renderState )
128 : : {
129 : : // setup identity transform
130 : 0 : setIdentityAffineMatrix2D( renderState.AffineTransform );
131 [ # # ]: 0 : renderState.Clip = uno::Reference< rendering::XPolyPolygon2D >();
132 [ # # ]: 0 : renderState.DeviceColor = uno::Sequence< double >();
133 : 0 : renderState.CompositeOperation = rendering::CompositeOperation::OVER;
134 : :
135 : 0 : return renderState;
136 : : }
137 : :
138 : 0 : rendering::ViewState& initViewState( rendering::ViewState& viewState )
139 : : {
140 : : // setup identity transform
141 : 0 : setIdentityAffineMatrix2D( viewState.AffineTransform );
142 [ # # ]: 0 : viewState.Clip = uno::Reference< rendering::XPolyPolygon2D >();
143 : :
144 : 0 : return viewState;
145 : : }
146 : :
147 : 0 : ::basegfx::B2DHomMatrix& getViewStateTransform( ::basegfx::B2DHomMatrix& transform,
148 : : const rendering::ViewState& viewState )
149 : : {
150 : 0 : return ::basegfx::unotools::homMatrixFromAffineMatrix( transform, viewState.AffineTransform );
151 : : }
152 : :
153 : 0 : rendering::ViewState& setViewStateTransform( rendering::ViewState& viewState,
154 : : const ::basegfx::B2DHomMatrix& transform )
155 : : {
156 : 0 : ::basegfx::unotools::affineMatrixFromHomMatrix( viewState.AffineTransform, transform );
157 : :
158 : 0 : return viewState;
159 : : }
160 : :
161 : 0 : ::basegfx::B2DHomMatrix& getRenderStateTransform( ::basegfx::B2DHomMatrix& transform,
162 : : const rendering::RenderState& renderState )
163 : : {
164 : 0 : return ::basegfx::unotools::homMatrixFromAffineMatrix( transform, renderState.AffineTransform );
165 : : }
166 : :
167 : 0 : rendering::RenderState& setRenderStateTransform( rendering::RenderState& renderState,
168 : : const ::basegfx::B2DHomMatrix& transform )
169 : : {
170 : 0 : ::basegfx::unotools::affineMatrixFromHomMatrix( renderState.AffineTransform, transform );
171 : :
172 : 0 : return renderState;
173 : : }
174 : :
175 : 0 : rendering::RenderState& appendToRenderState( rendering::RenderState& renderState,
176 : : const ::basegfx::B2DHomMatrix& rTransform )
177 : : {
178 [ # # ]: 0 : ::basegfx::B2DHomMatrix transform;
179 : :
180 [ # # ]: 0 : getRenderStateTransform( transform, renderState );
181 [ # # ][ # # ]: 0 : return setRenderStateTransform( renderState, transform * rTransform );
[ # # ][ # # ]
182 : : }
183 : :
184 : 0 : rendering::RenderState& prependToRenderState( rendering::RenderState& renderState,
185 : : const ::basegfx::B2DHomMatrix& rTransform )
186 : : {
187 [ # # ]: 0 : ::basegfx::B2DHomMatrix transform;
188 : :
189 [ # # ]: 0 : getRenderStateTransform( transform, renderState );
190 [ # # ][ # # ]: 0 : return setRenderStateTransform( renderState, rTransform * transform );
[ # # ][ # # ]
191 : : }
192 : :
193 : 0 : ::basegfx::B2DHomMatrix& mergeViewAndRenderTransform( ::basegfx::B2DHomMatrix& combinedTransform,
194 : : const rendering::ViewState& viewState,
195 : : const rendering::RenderState& renderState )
196 : : {
197 [ # # ]: 0 : ::basegfx::B2DHomMatrix viewTransform;
198 : :
199 [ # # ]: 0 : ::basegfx::unotools::homMatrixFromAffineMatrix( combinedTransform, renderState.AffineTransform );
200 [ # # ]: 0 : ::basegfx::unotools::homMatrixFromAffineMatrix( viewTransform, viewState.AffineTransform );
201 : :
202 : : // this statement performs combinedTransform = viewTransform * combinedTransform
203 [ # # ]: 0 : combinedTransform *= viewTransform;
204 : :
205 [ # # ]: 0 : return combinedTransform;
206 : : }
207 : :
208 : 0 : geometry::AffineMatrix2D& setIdentityAffineMatrix2D( geometry::AffineMatrix2D& matrix )
209 : : {
210 : 0 : matrix.m00 = 1.0;
211 : 0 : matrix.m01 = 0.0;
212 : 0 : matrix.m02 = 0.0;
213 : 0 : matrix.m10 = 0.0;
214 : 0 : matrix.m11 = 1.0;
215 : 0 : matrix.m12 = 0.0;
216 : :
217 : 0 : return matrix;
218 : : }
219 : :
220 : 0 : geometry::Matrix2D& setIdentityMatrix2D( geometry::Matrix2D& matrix )
221 : : {
222 : 0 : matrix.m00 = 1.0;
223 : 0 : matrix.m01 = 0.0;
224 : 0 : matrix.m10 = 0.0;
225 : 0 : matrix.m11 = 1.0;
226 : :
227 : 0 : return matrix;
228 : : }
229 : :
230 : : namespace
231 : : {
232 [ # # ][ # # ]: 0 : class StandardColorSpace : public cppu::WeakImplHelper1< com::sun::star::rendering::XIntegerBitmapColorSpace >
[ # # ]
233 : : {
234 : : private:
235 : : uno::Sequence< sal_Int8 > maComponentTags;
236 : : uno::Sequence< sal_Int32 > maBitCounts;
237 : :
238 : 0 : virtual ::sal_Int8 SAL_CALL getType( ) throw (uno::RuntimeException)
239 : : {
240 : 0 : return rendering::ColorSpaceType::RGB;
241 : : }
242 : 0 : virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( ) throw (uno::RuntimeException)
243 : : {
244 : 0 : return maComponentTags;
245 : : }
246 : 0 : virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) throw (uno::RuntimeException)
247 : : {
248 : 0 : return rendering::RenderingIntent::PERCEPTUAL;
249 : : }
250 : 0 : virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) throw (uno::RuntimeException)
251 : : {
252 : 0 : return uno::Sequence< beans::PropertyValue >();
253 : : }
254 : 0 : virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
255 : : const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
256 : : uno::RuntimeException)
257 : : {
258 : : // TODO(P3): if we know anything about target
259 : : // colorspace, this can be greatly sped up
260 : : uno::Sequence<rendering::ARGBColor> aIntermediate(
261 [ # # ]: 0 : convertToARGB(deviceColor));
262 [ # # ][ # # ]: 0 : return targetColorSpace->convertFromARGB(aIntermediate);
[ # # ]
263 : : }
264 : 0 : virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
265 : : {
266 : 0 : const double* pIn( deviceColor.getConstArray() );
267 : 0 : const sal_Size nLen( deviceColor.getLength() );
268 [ # # ][ # # ]: 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
[ # # ][ # # ]
[ # # ]
269 : : "number of channels no multiple of 4",
270 : : static_cast<rendering::XColorSpace*>(this), 0);
271 : :
272 : 0 : uno::Sequence< rendering::RGBColor > aRes(nLen/4);
273 [ # # ]: 0 : rendering::RGBColor* pOut( aRes.getArray() );
274 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=4 )
275 : : {
276 : 0 : *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
277 : 0 : pIn += 4;
278 : : }
279 : 0 : return aRes;
280 : : }
281 : 0 : virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
282 : : {
283 : 0 : const double* pIn( deviceColor.getConstArray() );
284 : 0 : const sal_Size nLen( deviceColor.getLength() );
285 [ # # ][ # # ]: 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
[ # # ][ # # ]
[ # # ]
286 : : "number of channels no multiple of 4",
287 : : static_cast<rendering::XColorSpace*>(this), 0);
288 : :
289 : 0 : uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
290 [ # # ]: 0 : rendering::ARGBColor* pOut( aRes.getArray() );
291 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=4 )
292 : : {
293 : 0 : *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]);
294 : 0 : pIn += 4;
295 : : }
296 : 0 : return aRes;
297 : : }
298 : 0 : virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
299 : : {
300 : 0 : const double* pIn( deviceColor.getConstArray() );
301 : 0 : const sal_Size nLen( deviceColor.getLength() );
302 [ # # ][ # # ]: 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
[ # # ][ # # ]
[ # # ]
303 : : "number of channels no multiple of 4",
304 : : static_cast<rendering::XColorSpace*>(this), 0);
305 : :
306 : 0 : uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
307 [ # # ]: 0 : rendering::ARGBColor* pOut( aRes.getArray() );
308 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=4 )
309 : : {
310 : 0 : *pOut++ = rendering::ARGBColor(pIn[3],pIn[3]*pIn[0],pIn[3]*pIn[1],pIn[3]*pIn[2]);
311 : 0 : pIn += 4;
312 : : }
313 : 0 : return aRes;
314 : : }
315 : 0 : virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
316 : : {
317 : 0 : const rendering::RGBColor* pIn( rgbColor.getConstArray() );
318 : 0 : const sal_Size nLen( rgbColor.getLength() );
319 : :
320 : 0 : uno::Sequence< double > aRes(nLen*4);
321 [ # # ]: 0 : double* pColors=aRes.getArray();
322 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
323 : : {
324 : 0 : *pColors++ = pIn->Red;
325 : 0 : *pColors++ = pIn->Green;
326 : 0 : *pColors++ = pIn->Blue;
327 : 0 : *pColors++ = 1.0;
328 : 0 : ++pIn;
329 : : }
330 : 0 : return aRes;
331 : : }
332 : 0 : virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
333 : : {
334 : 0 : const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
335 : 0 : const sal_Size nLen( rgbColor.getLength() );
336 : :
337 : 0 : uno::Sequence< double > aRes(nLen*4);
338 [ # # ]: 0 : double* pColors=aRes.getArray();
339 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
340 : : {
341 : 0 : *pColors++ = pIn->Red;
342 : 0 : *pColors++ = pIn->Green;
343 : 0 : *pColors++ = pIn->Blue;
344 : 0 : *pColors++ = pIn->Alpha;
345 : 0 : ++pIn;
346 : : }
347 : 0 : return aRes;
348 : : }
349 : 0 : virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
350 : : {
351 : 0 : const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
352 : 0 : const sal_Size nLen( rgbColor.getLength() );
353 : :
354 : 0 : uno::Sequence< double > aRes(nLen*4);
355 [ # # ]: 0 : double* pColors=aRes.getArray();
356 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
357 : : {
358 : 0 : *pColors++ = pIn->Red/pIn->Alpha;
359 : 0 : *pColors++ = pIn->Green/pIn->Alpha;
360 : 0 : *pColors++ = pIn->Blue/pIn->Alpha;
361 : 0 : *pColors++ = pIn->Alpha;
362 : 0 : ++pIn;
363 : : }
364 : 0 : return aRes;
365 : : }
366 : :
367 : : // XIntegerBitmapColorSpace
368 : 0 : virtual ::sal_Int32 SAL_CALL getBitsPerPixel( ) throw (uno::RuntimeException)
369 : : {
370 : 0 : return 32;
371 : : }
372 : 0 : virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts( ) throw (uno::RuntimeException)
373 : : {
374 : 0 : return maBitCounts;
375 : : }
376 : 0 : virtual ::sal_Int8 SAL_CALL getEndianness( ) throw (uno::RuntimeException)
377 : : {
378 : 0 : return util::Endianness::LITTLE;
379 : : }
380 : 0 : virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
381 : : const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
382 : : uno::RuntimeException)
383 : : {
384 [ # # ][ # # ]: 0 : if( dynamic_cast<StandardColorSpace*>(targetColorSpace.get()) )
[ # # ]
385 : : {
386 : 0 : const sal_Int8* pIn( deviceColor.getConstArray() );
387 : 0 : const sal_Size nLen( deviceColor.getLength() );
388 [ # # ][ # # ]: 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
[ # # ][ # # ]
[ # # ]
389 : : "number of channels no multiple of 4",
390 : : static_cast<rendering::XColorSpace*>(this), 0);
391 : :
392 [ # # ]: 0 : uno::Sequence<double> aRes(nLen);
393 [ # # ]: 0 : double* pOut( aRes.getArray() );
394 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=4 )
395 : : {
396 : 0 : *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
397 : 0 : *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
398 : 0 : *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
399 : 0 : *pOut++ = vcl::unotools::toDoubleColor(255-*pIn++);
400 : : }
401 [ # # ][ # # ]: 0 : return aRes;
402 : : }
403 : : else
404 : : {
405 : : // TODO(P3): if we know anything about target
406 : : // colorspace, this can be greatly sped up
407 : : uno::Sequence<rendering::ARGBColor> aIntermediate(
408 [ # # ]: 0 : convertIntegerToARGB(deviceColor));
409 [ # # ][ # # ]: 0 : return targetColorSpace->convertFromARGB(aIntermediate);
[ # # ]
410 : : }
411 : : }
412 : 0 : virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
413 : : const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
414 : : uno::RuntimeException)
415 : : {
416 [ # # ][ # # ]: 0 : if( dynamic_cast<StandardColorSpace*>(targetColorSpace.get()) )
[ # # ]
417 : : {
418 : : // it's us, so simply pass-through the data
419 : 0 : return deviceColor;
420 : : }
421 : : else
422 : : {
423 : : // TODO(P3): if we know anything about target
424 : : // colorspace, this can be greatly sped up
425 : : uno::Sequence<rendering::ARGBColor> aIntermediate(
426 [ # # ]: 0 : convertIntegerToARGB(deviceColor));
427 [ # # ][ # # ]: 0 : return targetColorSpace->convertIntegerFromARGB(aIntermediate);
[ # # ]
428 : : }
429 : : }
430 : 0 : virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
431 : : {
432 : 0 : const sal_Int8* pIn( deviceColor.getConstArray() );
433 : 0 : const sal_Size nLen( deviceColor.getLength() );
434 [ # # ][ # # ]: 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
[ # # ][ # # ]
[ # # ]
435 : : "number of channels no multiple of 4",
436 : : static_cast<rendering::XColorSpace*>(this), 0);
437 : :
438 : 0 : uno::Sequence< rendering::RGBColor > aRes(nLen/4);
439 [ # # ]: 0 : rendering::RGBColor* pOut( aRes.getArray() );
440 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=4 )
441 : : {
442 : : *pOut++ = rendering::RGBColor(
443 : 0 : vcl::unotools::toDoubleColor(pIn[0]),
444 : 0 : vcl::unotools::toDoubleColor(pIn[1]),
445 : 0 : vcl::unotools::toDoubleColor(pIn[2]));
446 : 0 : pIn += 4;
447 : : }
448 : 0 : return aRes;
449 : : }
450 : :
451 : 0 : virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
452 : : {
453 : 0 : const sal_Int8* pIn( deviceColor.getConstArray() );
454 : 0 : const sal_Size nLen( deviceColor.getLength() );
455 [ # # ][ # # ]: 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
[ # # ][ # # ]
[ # # ]
456 : : "number of channels no multiple of 4",
457 : : static_cast<rendering::XColorSpace*>(this), 0);
458 : :
459 : 0 : uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
460 [ # # ]: 0 : rendering::ARGBColor* pOut( aRes.getArray() );
461 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=4 )
462 : : {
463 : : *pOut++ = rendering::ARGBColor(
464 : 0 : vcl::unotools::toDoubleColor(255-pIn[3]),
465 : 0 : vcl::unotools::toDoubleColor(pIn[0]),
466 : 0 : vcl::unotools::toDoubleColor(pIn[1]),
467 : 0 : vcl::unotools::toDoubleColor(pIn[2]));
468 : 0 : pIn += 4;
469 : : }
470 : 0 : return aRes;
471 : : }
472 : :
473 : 0 : virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
474 : : {
475 : 0 : const sal_Int8* pIn( deviceColor.getConstArray() );
476 : 0 : const sal_Size nLen( deviceColor.getLength() );
477 [ # # ][ # # ]: 0 : ENSURE_ARG_OR_THROW2(nLen%4==0,
[ # # ][ # # ]
[ # # ]
478 : : "number of channels no multiple of 4",
479 : : static_cast<rendering::XColorSpace*>(this), 0);
480 : :
481 : 0 : uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
482 [ # # ]: 0 : rendering::ARGBColor* pOut( aRes.getArray() );
483 [ # # ]: 0 : for( sal_Size i=0; i<nLen; i+=4 )
484 : : {
485 : 0 : const sal_Int8 nAlpha( 255-pIn[3] );
486 : : *pOut++ = rendering::ARGBColor(
487 : 0 : vcl::unotools::toDoubleColor(nAlpha),
488 : 0 : vcl::unotools::toDoubleColor(nAlpha*pIn[0]),
489 : 0 : vcl::unotools::toDoubleColor(nAlpha*pIn[1]),
490 : 0 : vcl::unotools::toDoubleColor(nAlpha*pIn[2]));
491 : 0 : pIn += 4;
492 : : }
493 : 0 : return aRes;
494 : : }
495 : :
496 : 0 : virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
497 : : {
498 : 0 : const rendering::RGBColor* pIn( rgbColor.getConstArray() );
499 : 0 : const sal_Size nLen( rgbColor.getLength() );
500 : :
501 : 0 : uno::Sequence< sal_Int8 > aRes(nLen*4);
502 [ # # ]: 0 : sal_Int8* pColors=aRes.getArray();
503 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
504 : : {
505 [ # # ]: 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Red);
506 [ # # ]: 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Green);
507 [ # # ]: 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
508 : 0 : *pColors++ = 0;
509 : 0 : ++pIn;
510 : : }
511 : 0 : return aRes;
512 : : }
513 : :
514 : 0 : virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
515 : : {
516 : 0 : const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
517 : 0 : const sal_Size nLen( rgbColor.getLength() );
518 : :
519 : 0 : uno::Sequence< sal_Int8 > aRes(nLen*4);
520 [ # # ]: 0 : sal_Int8* pColors=aRes.getArray();
521 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
522 : : {
523 [ # # ]: 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Red);
524 [ # # ]: 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Green);
525 [ # # ]: 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
526 [ # # ]: 0 : *pColors++ = 255-vcl::unotools::toByteColor(pIn->Alpha);
527 : 0 : ++pIn;
528 : : }
529 : 0 : return aRes;
530 : : }
531 : :
532 : 0 : virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
533 : : {
534 : 0 : const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
535 : 0 : const sal_Size nLen( rgbColor.getLength() );
536 : :
537 : 0 : uno::Sequence< sal_Int8 > aRes(nLen*4);
538 [ # # ]: 0 : sal_Int8* pColors=aRes.getArray();
539 [ # # ]: 0 : for( sal_Size i=0; i<nLen; ++i )
540 : : {
541 [ # # ]: 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Red/pIn->Alpha);
542 [ # # ]: 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Green/pIn->Alpha);
543 [ # # ]: 0 : *pColors++ = vcl::unotools::toByteColor(pIn->Blue/pIn->Alpha);
544 [ # # ]: 0 : *pColors++ = 255-vcl::unotools::toByteColor(pIn->Alpha);
545 : 0 : ++pIn;
546 : : }
547 : 0 : return aRes;
548 : : }
549 : :
550 : : public:
551 : 0 : StandardColorSpace() :
552 : : maComponentTags(4),
553 [ # # ][ # # ]: 0 : maBitCounts(4)
554 : : {
555 [ # # ]: 0 : sal_Int8* pTags = maComponentTags.getArray();
556 [ # # ]: 0 : sal_Int32* pBitCounts = maBitCounts.getArray();
557 : 0 : pTags[0] = rendering::ColorComponentTag::RGB_RED;
558 : 0 : pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
559 : 0 : pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
560 : 0 : pTags[3] = rendering::ColorComponentTag::ALPHA;
561 : :
562 : : pBitCounts[0] =
563 : 0 : pBitCounts[1] =
564 : 0 : pBitCounts[2] =
565 : 0 : pBitCounts[3] = 8;
566 : 0 : }
567 : : };
568 : :
569 : : struct StandardColorSpaceHolder : public rtl::StaticWithInit<uno::Reference<rendering::XIntegerBitmapColorSpace>,
570 : : StandardColorSpaceHolder>
571 : : {
572 : 0 : uno::Reference<rendering::XIntegerBitmapColorSpace> operator()()
573 : : {
574 [ # # ][ # # ]: 0 : return new StandardColorSpace();
575 : : }
576 : : };
577 : : }
578 : :
579 : 0 : uno::Reference<rendering::XIntegerBitmapColorSpace> getStdColorSpace()
580 : : {
581 : 0 : return StandardColorSpaceHolder::get();
582 : : }
583 : :
584 : 0 : rendering::IntegerBitmapLayout getStdMemoryLayout( const geometry::IntegerSize2D& rBmpSize )
585 : : {
586 : 0 : rendering::IntegerBitmapLayout aLayout;
587 : :
588 : 0 : aLayout.ScanLines = rBmpSize.Height;
589 : 0 : aLayout.ScanLineBytes = rBmpSize.Width*4;
590 : 0 : aLayout.ScanLineStride = aLayout.ScanLineBytes;
591 : 0 : aLayout.PlaneStride = 0;
592 [ # # ][ # # ]: 0 : aLayout.ColorSpace = getStdColorSpace();
593 : 0 : aLayout.Palette.clear();
594 : 0 : aLayout.IsMsbFirst = sal_False;
595 : :
596 : 0 : return aLayout;
597 : : }
598 : :
599 : 0 : ::Color stdIntSequenceToColor( const uno::Sequence<sal_Int8>& rColor )
600 : : {
601 : : #ifdef OSL_BIGENDIAN
602 : : const sal_Int8* pCols( rColor.getConstArray() );
603 : : return ::Color( pCols[3], pCols[0], pCols[1], pCols[2] );
604 : : #else
605 : 0 : return ::Color( *reinterpret_cast< const ::ColorData* >(rColor.getConstArray()) );
606 : : #endif
607 : : }
608 : :
609 : 0 : uno::Sequence<sal_Int8> colorToStdIntSequence( const ::Color& rColor )
610 : : {
611 : 0 : uno::Sequence<sal_Int8> aRet(4);
612 [ # # ]: 0 : sal_Int8* pCols( aRet.getArray() );
613 : : #ifdef OSL_BIGENDIAN
614 : : pCols[0] = rColor.GetRed();
615 : : pCols[1] = rColor.GetGreen();
616 : : pCols[2] = rColor.GetBlue();
617 : : pCols[3] = 255-rColor.GetTransparency();
618 : : #else
619 : 0 : *reinterpret_cast<sal_Int32*>(pCols) = rColor.GetColor();
620 : : #endif
621 : 0 : return aRet;
622 : : }
623 : :
624 : : // Create a corrected view transformation out of the give one,
625 : : // which ensures that the rectangle given by (0,0) and
626 : : // rSpriteSize is mapped with its left,top corner to (0,0)
627 : : // again. This is required to properly render sprite
628 : : // animations to buffer bitmaps.
629 : 0 : ::basegfx::B2DHomMatrix& calcRectToOriginTransform( ::basegfx::B2DHomMatrix& o_transform,
630 : : const ::basegfx::B2DRange& i_srcRect,
631 : : const ::basegfx::B2DHomMatrix& i_transformation )
632 : : {
633 [ # # ][ # # ]: 0 : if( i_srcRect.isEmpty() )
634 [ # # ]: 0 : return o_transform=i_transformation;
635 : :
636 : : // transform by given transformation
637 [ # # ]: 0 : ::basegfx::B2DRectangle aTransformedRect;
638 : :
639 : : calcTransformedRectBounds( aTransformedRect,
640 : : i_srcRect,
641 [ # # ]: 0 : i_transformation );
642 : :
643 : : // now move resulting left,top point of bounds to (0,0)
644 : : const basegfx::B2DHomMatrix aCorrectedTransform(basegfx::tools::createTranslateB2DHomMatrix(
645 [ # # ][ # # ]: 0 : -aTransformedRect.getMinX(), -aTransformedRect.getMinY()));
[ # # ]
646 : :
647 : : // prepend to original transformation
648 [ # # ][ # # ]: 0 : o_transform = aCorrectedTransform * i_transformation;
[ # # ]
649 : :
650 [ # # ]: 0 : return o_transform;
651 : : }
652 : :
653 : 0 : ::basegfx::B2DRange& calcTransformedRectBounds( ::basegfx::B2DRange& outRect,
654 : : const ::basegfx::B2DRange& inRect,
655 : : const ::basegfx::B2DHomMatrix& transformation )
656 : : {
657 [ # # ]: 0 : outRect.reset();
658 : :
659 [ # # ][ # # ]: 0 : if( inRect.isEmpty() )
660 : 0 : return outRect;
661 : :
662 : : // transform all four extremal points of the rectangle,
663 : : // take bounding rect of those.
664 : :
665 : : // transform left-top point
666 [ # # ][ # # ]: 0 : outRect.expand( transformation * inRect.getMinimum() );
[ # # ]
667 : :
668 : : // transform bottom-right point
669 [ # # ][ # # ]: 0 : outRect.expand( transformation * inRect.getMaximum() );
[ # # ]
670 : :
671 : 0 : ::basegfx::B2DPoint aPoint;
672 : :
673 : : // transform top-right point
674 [ # # ]: 0 : aPoint.setX( inRect.getMaxX() );
675 [ # # ]: 0 : aPoint.setY( inRect.getMinY() );
676 : :
677 [ # # ]: 0 : aPoint *= transformation;
678 [ # # ]: 0 : outRect.expand( aPoint );
679 : :
680 : : // transform bottom-left point
681 [ # # ]: 0 : aPoint.setX( inRect.getMinX() );
682 [ # # ]: 0 : aPoint.setY( inRect.getMaxY() );
683 : :
684 [ # # ]: 0 : aPoint *= transformation;
685 [ # # ]: 0 : outRect.expand( aPoint );
686 : :
687 : : // over and out.
688 : 0 : return outRect;
689 : : }
690 : :
691 : 0 : bool isInside( const ::basegfx::B2DRange& rContainedRect,
692 : : const ::basegfx::B2DRange& rTransformRect,
693 : : const ::basegfx::B2DHomMatrix& rTransformation )
694 : : {
695 [ # # ][ # # ]: 0 : if( rContainedRect.isEmpty() || rTransformRect.isEmpty() )
[ # # ][ # # ]
[ # # ]
696 : 0 : return false;
697 : :
698 : : ::basegfx::B2DPolygon aPoly(
699 [ # # ]: 0 : ::basegfx::tools::createPolygonFromRect( rTransformRect ) );
700 [ # # ]: 0 : aPoly.transform( rTransformation );
701 : :
702 : : return ::basegfx::tools::isInside( aPoly,
703 : : ::basegfx::tools::createPolygonFromRect(
704 : : rContainedRect ),
705 [ # # ][ # # ]: 0 : true );
[ # # ][ # # ]
706 : : }
707 : :
708 : : namespace
709 : : {
710 : 0 : bool clipAreaImpl( ::basegfx::B2IRange* o_pDestArea,
711 : : ::basegfx::B2IRange& io_rSourceArea,
712 : : ::basegfx::B2IPoint& io_rDestPoint,
713 : : const ::basegfx::B2IRange& rSourceBounds,
714 : : const ::basegfx::B2IRange& rDestBounds )
715 : : {
716 : : const ::basegfx::B2IPoint aSourceTopLeft(
717 [ # # ]: 0 : io_rSourceArea.getMinimum() );
718 : :
719 : 0 : ::basegfx::B2IRange aLocalSourceArea( io_rSourceArea );
720 : :
721 : : // clip source area (which must be inside rSourceBounds)
722 [ # # ]: 0 : aLocalSourceArea.intersect( rSourceBounds );
723 : :
724 [ # # ][ # # ]: 0 : if( aLocalSourceArea.isEmpty() )
725 : 0 : return false;
726 : :
727 : : // calc relative new source area points (relative to orig
728 : : // source area)
729 : : const ::basegfx::B2IVector aUpperLeftOffset(
730 [ # # ][ # # ]: 0 : aLocalSourceArea.getMinimum()-aSourceTopLeft );
731 : : const ::basegfx::B2IVector aLowerRightOffset(
732 [ # # ][ # # ]: 0 : aLocalSourceArea.getMaximum()-aSourceTopLeft );
733 : :
734 : : ::basegfx::B2IRange aLocalDestArea( io_rDestPoint + aUpperLeftOffset,
735 [ # # ][ # # ]: 0 : io_rDestPoint + aLowerRightOffset );
[ # # ]
736 : :
737 : : // clip dest area (which must be inside rDestBounds)
738 [ # # ]: 0 : aLocalDestArea.intersect( rDestBounds );
739 : :
740 [ # # ][ # # ]: 0 : if( aLocalDestArea.isEmpty() )
741 : 0 : return false;
742 : :
743 : : // calc relative new dest area points (relative to orig
744 : : // source area)
745 : : const ::basegfx::B2IVector aDestUpperLeftOffset(
746 [ # # ][ # # ]: 0 : aLocalDestArea.getMinimum()-io_rDestPoint );
747 : : const ::basegfx::B2IVector aDestLowerRightOffset(
748 [ # # ][ # # ]: 0 : aLocalDestArea.getMaximum()-io_rDestPoint );
749 : :
750 : : io_rSourceArea = ::basegfx::B2IRange( aSourceTopLeft + aDestUpperLeftOffset,
751 [ # # ][ # # ]: 0 : aSourceTopLeft + aDestLowerRightOffset );
[ # # ]
752 [ # # ][ # # ]: 0 : io_rDestPoint = aLocalDestArea.getMinimum();
753 : :
754 [ # # ]: 0 : if( o_pDestArea )
755 : 0 : *o_pDestArea = aLocalDestArea;
756 : :
757 : 0 : return true;
758 : : }
759 : : }
760 : :
761 : 0 : bool clipScrollArea( ::basegfx::B2IRange& io_rSourceArea,
762 : : ::basegfx::B2IPoint& io_rDestPoint,
763 : : ::std::vector< ::basegfx::B2IRange >& o_ClippedAreas,
764 : : const ::basegfx::B2IRange& rBounds )
765 : : {
766 [ # # ]: 0 : ::basegfx::B2IRange aResultingDestArea;
767 : :
768 : : // compute full destination area (to determine uninitialized
769 : : // areas below)
770 [ # # ]: 0 : const ::basegfx::B2I64Tuple& rRange( io_rSourceArea.getRange() );
771 : : ::basegfx::B2IRange aInputDestArea( io_rDestPoint.getX(),
772 : : io_rDestPoint.getY(),
773 : 0 : (io_rDestPoint.getX()
774 : 0 : + static_cast<sal_Int32>(rRange.getX())),
775 : 0 : (io_rDestPoint.getY()
776 [ # # ]: 0 : + static_cast<sal_Int32>(rRange.getY())) );
777 : : // limit to output area (no point updating outside of it)
778 [ # # ]: 0 : aInputDestArea.intersect( rBounds );
779 : :
780 : : // clip to rBounds
781 [ # # ]: 0 : if( !clipAreaImpl( &aResultingDestArea,
782 : : io_rSourceArea,
783 : : io_rDestPoint,
784 : : rBounds,
785 [ # # ]: 0 : rBounds ) )
786 : 0 : return false;
787 : :
788 : : // finally, compute all areas clipped off the total
789 : : // destination area.
790 : : ::basegfx::computeSetDifference( o_ClippedAreas,
791 : : aInputDestArea,
792 [ # # ]: 0 : aResultingDestArea );
793 : :
794 : 0 : return true;
795 : : }
796 : :
797 : 0 : ::basegfx::B2IRange spritePixelAreaFromB2DRange( const ::basegfx::B2DRange& rRange )
798 : : {
799 [ # # ][ # # ]: 0 : if( rRange.isEmpty() )
800 [ # # ]: 0 : return ::basegfx::B2IRange();
801 : :
802 : : const ::basegfx::B2IPoint aTopLeft( ::basegfx::fround( rRange.getMinX() ),
803 [ # # ][ # # ]: 0 : ::basegfx::fround( rRange.getMinY() ) );
804 : : return ::basegfx::B2IRange( aTopLeft,
805 : : aTopLeft + ::basegfx::B2IPoint(
806 : : ::basegfx::fround( rRange.getWidth() ),
807 [ # # ][ # # ]: 0 : ::basegfx::fround( rRange.getHeight() ) ) );
[ # # ][ # # ]
808 : : }
809 : :
810 : 0 : uno::Sequence< uno::Any >& getDeviceInfo( const uno::Reference< rendering::XCanvas >& i_rxCanvas,
811 : : uno::Sequence< uno::Any >& o_rxParams )
812 : : {
813 : 0 : o_rxParams.realloc( 0 );
814 : :
815 [ # # ]: 0 : if( i_rxCanvas.is() )
816 : : {
817 : : try
818 : : {
819 [ # # ]: 0 : uno::Reference< rendering::XGraphicDevice > xDevice( i_rxCanvas->getDevice(),
820 [ # # ][ # # ]: 0 : uno::UNO_QUERY_THROW );
821 : :
822 : : uno::Reference< lang::XServiceInfo > xServiceInfo( xDevice,
823 [ # # ]: 0 : uno::UNO_QUERY_THROW );
824 : : uno::Reference< beans::XPropertySet > xPropSet( xDevice,
825 [ # # ]: 0 : uno::UNO_QUERY_THROW );
826 : :
827 [ # # ]: 0 : o_rxParams.realloc( 2 );
828 : :
829 [ # # ][ # # ]: 0 : o_rxParams[ 0 ] = uno::makeAny( xServiceInfo->getImplementationName() );
[ # # ][ # # ]
830 [ # # ][ # # ]: 0 : o_rxParams[ 1 ] = uno::makeAny( xPropSet->getPropertyValue(
831 [ # # ][ # # ]: 0 : ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DeviceHandle") ) ) );
[ # # ][ # # ]
832 : : }
833 : 0 : catch( const uno::Exception& )
834 : : {
835 : : // ignore, but return empty sequence
836 : : }
837 : : }
838 : :
839 : 0 : return o_rxParams;
840 : : }
841 : :
842 : 0 : awt::Rectangle getAbsoluteWindowRect( const awt::Rectangle& rRect,
843 : : const uno::Reference< awt::XWindow2 >& xWin )
844 : : {
845 : 0 : awt::Rectangle aRetVal( rRect );
846 : :
847 : 0 : ::Window* pWindow = VCLUnoHelper::GetWindow(xWin);
848 [ # # ]: 0 : if( pWindow )
849 : : {
850 : : ::Point aPoint( aRetVal.X,
851 : 0 : aRetVal.Y );
852 : :
853 [ # # ]: 0 : aPoint = pWindow->OutputToScreenPixel( aPoint );
854 : :
855 : 0 : aRetVal.X = aPoint.X();
856 : 0 : aRetVal.Y = aPoint.Y();
857 : : }
858 : :
859 : 0 : return aRetVal;
860 : : }
861 : :
862 : 0 : ::basegfx::B2DPolyPolygon getBoundMarksPolyPolygon( const ::basegfx::B2DRange& rRange )
863 : : {
864 [ # # ]: 0 : ::basegfx::B2DPolyPolygon aPolyPoly;
865 [ # # ]: 0 : ::basegfx::B2DPolygon aPoly;
866 : :
867 [ # # ]: 0 : const double nX0( rRange.getMinX() );
868 [ # # ]: 0 : const double nY0( rRange.getMinY() );
869 [ # # ]: 0 : const double nX1( rRange.getMaxX() );
870 [ # # ]: 0 : const double nY1( rRange.getMaxY() );
871 : :
872 : : aPoly.append( ::basegfx::B2DPoint( nX0+4,
873 [ # # ]: 0 : nY0 ) );
874 : : aPoly.append( ::basegfx::B2DPoint( nX0,
875 [ # # ]: 0 : nY0 ) );
876 : : aPoly.append( ::basegfx::B2DPoint( nX0,
877 [ # # ]: 0 : nY0+4 ) );
878 [ # # ][ # # ]: 0 : aPolyPoly.append( aPoly ); aPoly.clear();
879 : :
880 : : aPoly.append( ::basegfx::B2DPoint( nX1-4,
881 [ # # ]: 0 : nY0 ) );
882 : : aPoly.append( ::basegfx::B2DPoint( nX1,
883 [ # # ]: 0 : nY0 ) );
884 : : aPoly.append( ::basegfx::B2DPoint( nX1,
885 [ # # ]: 0 : nY0+4 ) );
886 [ # # ][ # # ]: 0 : aPolyPoly.append( aPoly ); aPoly.clear();
887 : :
888 : : aPoly.append( ::basegfx::B2DPoint( nX0+4,
889 [ # # ]: 0 : nY1 ) );
890 : : aPoly.append( ::basegfx::B2DPoint( nX0,
891 [ # # ]: 0 : nY1 ) );
892 : : aPoly.append( ::basegfx::B2DPoint( nX0,
893 [ # # ]: 0 : nY1-4 ) );
894 [ # # ][ # # ]: 0 : aPolyPoly.append( aPoly ); aPoly.clear();
895 : :
896 : : aPoly.append( ::basegfx::B2DPoint( nX1-4,
897 [ # # ]: 0 : nY1 ) );
898 : : aPoly.append( ::basegfx::B2DPoint( nX1,
899 [ # # ]: 0 : nY1 ) );
900 : : aPoly.append( ::basegfx::B2DPoint( nX1,
901 [ # # ]: 0 : nY1-4 ) );
902 [ # # ]: 0 : aPolyPoly.append( aPoly );
903 : :
904 [ # # ]: 0 : return aPolyPoly;
905 : : }
906 : :
907 : 0 : int calcGradientStepCount( ::basegfx::B2DHomMatrix& rTotalTransform,
908 : : const rendering::ViewState& viewState,
909 : : const rendering::RenderState& renderState,
910 : : const rendering::Texture& texture,
911 : : int nColorSteps )
912 : : {
913 : : // calculate overall texture transformation (directly from
914 : : // texture to device space).
915 [ # # ]: 0 : ::basegfx::B2DHomMatrix aMatrix;
916 : :
917 [ # # ]: 0 : rTotalTransform.identity();
918 : : ::basegfx::unotools::homMatrixFromAffineMatrix( rTotalTransform,
919 [ # # ]: 0 : texture.AffineTransform );
920 : : ::canvas::tools::mergeViewAndRenderTransform(aMatrix,
921 : : viewState,
922 [ # # ]: 0 : renderState);
923 [ # # ]: 0 : rTotalTransform *= aMatrix; // prepend total view/render transformation
924 : :
925 : : // determine size of gradient in device coordinate system
926 : : // (to e.g. determine sensible number of gradient steps)
927 : 0 : ::basegfx::B2DPoint aLeftTop( 0.0, 0.0 );
928 : 0 : ::basegfx::B2DPoint aLeftBottom( 0.0, 1.0 );
929 : 0 : ::basegfx::B2DPoint aRightTop( 1.0, 0.0 );
930 : 0 : ::basegfx::B2DPoint aRightBottom( 1.0, 1.0 );
931 : :
932 [ # # ]: 0 : aLeftTop *= rTotalTransform;
933 [ # # ]: 0 : aLeftBottom *= rTotalTransform;
934 [ # # ]: 0 : aRightTop *= rTotalTransform;
935 [ # # ]: 0 : aRightBottom*= rTotalTransform;
936 : :
937 : : // longest line in gradient bound rect
938 : : const int nGradientSize(
939 : : static_cast<int>(
940 : : ::std::max(
941 [ # # ]: 0 : ::basegfx::B2DVector(aRightBottom-aLeftTop).getLength(),
942 [ # # ][ # # ]: 0 : ::basegfx::B2DVector(aRightTop-aLeftBottom).getLength() ) + 1.0 ) );
943 : :
944 : : // typical number for pixel of the same color (strip size)
945 [ # # ]: 0 : const int nStripSize( nGradientSize < 50 ? 2 : 4 );
946 : :
947 : : // use at least three steps, and at utmost the number of color
948 : : // steps
949 : : return ::std::max( 3,
950 : : ::std::min(
951 : : nGradientSize / nStripSize,
952 [ # # ][ # # ]: 0 : nColorSteps ) );
[ # # ]
953 : : }
954 : :
955 : : } // namespace tools
956 : :
957 : : } // namespace canvas
958 : :
959 : : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|