1 /*************************************************************************
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
5 * Copyright 2008 by Sun Microsystems, Inc.
7 * OpenOffice.org - a multi-platform office productivity suite
9 * $RCSfile: canvastools.cxx,v $
12 * This file is part of OpenOffice.org.
14 * OpenOffice.org is free software: you can redistribute it and/or modify
15 * it under the terms of the GNU Lesser General Public License version 3
16 * only, as published by the Free Software Foundation.
18 * OpenOffice.org is distributed in the hope that it will be useful,
19 * but WITHOUT ANY WARRANTY; without even the implied warranty of
20 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
21 * GNU Lesser General Public License version 3 for more details
22 * (a copy is included in the LICENSE file that accompanied this code).
24 * You should have received a copy of the GNU Lesser General Public License
25 * version 3 along with OpenOffice.org. If not, see
26 * <http://www.openoffice.org/license.html>
27 * for a copy of the LGPLv3 License.
29 ************************************************************************/
31 // MARKER(update_precomp.py): autogen include statement, do not remove
32 #include "precompiled_canvas.hxx"
34 #include <canvas/debug.hxx>
35 #include <tools/diagnose_ex.h>
37 #include <com/sun/star/geometry/AffineMatrix2D.hpp>
38 #include <com/sun/star/geometry/Matrix2D.hpp>
39 #include <com/sun/star/awt/Rectangle.hpp>
40 #include <com/sun/star/util/Endianness.hpp>
41 #include <com/sun/star/rendering/XIntegerBitmapColorSpace.hpp>
42 #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
43 #include <com/sun/star/rendering/ColorSpaceType.hpp>
44 #include <com/sun/star/rendering/ColorComponentTag.hpp>
45 #include <com/sun/star/rendering/RenderingIntent.hpp>
46 #include <com/sun/star/rendering/RenderState.hpp>
47 #include <com/sun/star/rendering/ViewState.hpp>
48 #include <com/sun/star/rendering/XCanvas.hpp>
49 #include <com/sun/star/rendering/XColorSpace.hpp>
50 #include <com/sun/star/rendering/CompositeOperation.hpp>
51 #include <com/sun/star/beans/XPropertySet.hpp>
52 #include <com/sun/star/lang/XServiceInfo.hpp>
54 #include <basegfx/matrix/b2dhommatrix.hxx>
55 #include <basegfx/range/b2drange.hxx>
56 #include <basegfx/range/b2irange.hxx>
57 #include <basegfx/range/b2drectangle.hxx>
58 #include <basegfx/point/b2dpoint.hxx>
59 #include <basegfx/point/b2ipoint.hxx>
60 #include <basegfx/vector/b2ivector.hxx>
61 #include <basegfx/polygon/b2dpolygon.hxx>
62 #include <basegfx/polygon/b2dpolygontools.hxx>
63 #include <basegfx/polygon/b2dpolypolygontools.hxx>
64 #include <basegfx/tools/canvastools.hxx>
65 #include <basegfx/numeric/ftools.hxx>
67 #include <cppuhelper/compbase1.hxx>
68 #include <rtl/instance.hxx>
69 #include <toolkit/helper/vclunohelper.hxx>
70 #include <vcl/window.hxx>
71 #include <vcl/canvastools.hxx>
73 #include <canvas/canvastools.hxx>
78 using namespace ::com::sun::star
;
80 namespace com
{ namespace sun
{ namespace star
{ namespace rendering
82 bool operator==( const RenderState
& renderState1
,
83 const RenderState
& renderState2
)
85 if( renderState1
.Clip
!= renderState2
.Clip
)
88 if( renderState1
.DeviceColor
!= renderState2
.DeviceColor
)
91 if( renderState1
.CompositeOperation
!= renderState2
.CompositeOperation
)
94 ::basegfx::B2DHomMatrix mat1
, mat2
;
95 ::canvas::tools::getRenderStateTransform( mat1
, renderState1
);
96 ::canvas::tools::getRenderStateTransform( mat2
, renderState2
);
103 bool operator==( const ViewState
& viewState1
,
104 const ViewState
& viewState2
)
106 if( viewState1
.Clip
!= viewState2
.Clip
)
109 ::basegfx::B2DHomMatrix mat1
, mat2
;
110 ::canvas::tools::getViewStateTransform( mat1
, viewState1
);
111 ::canvas::tools::getViewStateTransform( mat2
, viewState2
);
123 geometry::RealSize2D
createInfiniteSize2D()
125 return geometry::RealSize2D(
126 ::std::numeric_limits
<double>::infinity(),
127 ::std::numeric_limits
<double>::infinity() );
130 rendering::RenderState
& initRenderState( rendering::RenderState
& renderState
)
132 // setup identity transform
133 setIdentityAffineMatrix2D( renderState
.AffineTransform
);
134 renderState
.Clip
= uno::Reference
< rendering::XPolyPolygon2D
>();
135 renderState
.DeviceColor
= uno::Sequence
< double >();
136 renderState
.CompositeOperation
= rendering::CompositeOperation::OVER
;
141 rendering::ViewState
& initViewState( rendering::ViewState
& viewState
)
143 // setup identity transform
144 setIdentityAffineMatrix2D( viewState
.AffineTransform
);
145 viewState
.Clip
= uno::Reference
< rendering::XPolyPolygon2D
>();
150 ::basegfx::B2DHomMatrix
& getViewStateTransform( ::basegfx::B2DHomMatrix
& transform
,
151 const rendering::ViewState
& viewState
)
153 return ::basegfx::unotools::homMatrixFromAffineMatrix( transform
, viewState
.AffineTransform
);
156 rendering::ViewState
& setViewStateTransform( rendering::ViewState
& viewState
,
157 const ::basegfx::B2DHomMatrix
& transform
)
159 ::basegfx::unotools::affineMatrixFromHomMatrix( viewState
.AffineTransform
, transform
);
164 ::basegfx::B2DHomMatrix
& getRenderStateTransform( ::basegfx::B2DHomMatrix
& transform
,
165 const rendering::RenderState
& renderState
)
167 return ::basegfx::unotools::homMatrixFromAffineMatrix( transform
, renderState
.AffineTransform
);
170 rendering::RenderState
& setRenderStateTransform( rendering::RenderState
& renderState
,
171 const ::basegfx::B2DHomMatrix
& transform
)
173 ::basegfx::unotools::affineMatrixFromHomMatrix( renderState
.AffineTransform
, transform
);
178 rendering::RenderState
& appendToRenderState( rendering::RenderState
& renderState
,
179 const ::basegfx::B2DHomMatrix
& rTransform
)
181 ::basegfx::B2DHomMatrix transform
;
183 getRenderStateTransform( transform
, renderState
);
184 return setRenderStateTransform( renderState
, transform
* rTransform
);
187 rendering::ViewState
& appendToViewState( rendering::ViewState
& viewState
,
188 const ::basegfx::B2DHomMatrix
& rTransform
)
190 ::basegfx::B2DHomMatrix transform
;
192 getViewStateTransform( transform
, viewState
);
193 return setViewStateTransform( viewState
, transform
* rTransform
);
196 rendering::RenderState
& prependToRenderState( rendering::RenderState
& renderState
,
197 const ::basegfx::B2DHomMatrix
& rTransform
)
199 ::basegfx::B2DHomMatrix transform
;
201 getRenderStateTransform( transform
, renderState
);
202 return setRenderStateTransform( renderState
, rTransform
* transform
);
205 rendering::ViewState
& prependToViewState( rendering::ViewState
& viewState
,
206 const ::basegfx::B2DHomMatrix
& rTransform
)
208 ::basegfx::B2DHomMatrix transform
;
210 getViewStateTransform( transform
, viewState
);
211 return setViewStateTransform( viewState
, rTransform
* transform
);
214 ::basegfx::B2DHomMatrix
& mergeViewAndRenderTransform( ::basegfx::B2DHomMatrix
& combinedTransform
,
215 const rendering::ViewState
& viewState
,
216 const rendering::RenderState
& renderState
)
218 ::basegfx::B2DHomMatrix viewTransform
;
220 ::basegfx::unotools::homMatrixFromAffineMatrix( combinedTransform
, renderState
.AffineTransform
);
221 ::basegfx::unotools::homMatrixFromAffineMatrix( viewTransform
, viewState
.AffineTransform
);
223 // this statement performs combinedTransform = viewTransform * combinedTransform
224 combinedTransform
*= viewTransform
;
226 return combinedTransform
;
229 rendering::ViewState
& mergeViewAndRenderState( rendering::ViewState
& resultViewState
,
230 const rendering::ViewState
& viewState
,
231 const rendering::RenderState
& renderState
,
232 const uno::Reference
< rendering::XCanvas
>& /*xCanvas*/ )
234 ::basegfx::B2DHomMatrix aTmpMatrix
;
235 geometry::AffineMatrix2D convertedMatrix
;
237 resultViewState
.Clip
= NULL
; // TODO(F2): intersect clippings
239 return setViewStateTransform(
241 mergeViewAndRenderTransform( aTmpMatrix
,
246 geometry::AffineMatrix2D
& setIdentityAffineMatrix2D( geometry::AffineMatrix2D
& matrix
)
258 geometry::Matrix2D
& setIdentityMatrix2D( geometry::Matrix2D
& matrix
)
270 class StandardColorSpace
: public cppu::WeakImplHelper1
< com::sun::star::rendering::XIntegerBitmapColorSpace
>
273 uno::Sequence
< sal_Int8
> maComponentTags
;
274 uno::Sequence
< sal_Int32
> maBitCounts
;
276 virtual ::sal_Int8 SAL_CALL
getType( ) throw (uno::RuntimeException
)
278 return rendering::ColorSpaceType::RGB
;
280 virtual uno::Sequence
< ::sal_Int8
> SAL_CALL
getComponentTags( ) throw (uno::RuntimeException
)
282 return maComponentTags
;
284 virtual ::sal_Int8 SAL_CALL
getRenderingIntent( ) throw (uno::RuntimeException
)
286 return rendering::RenderingIntent::PERCEPTUAL
;
288 virtual uno::Sequence
< beans::PropertyValue
> SAL_CALL
getProperties( ) throw (uno::RuntimeException
)
290 return uno::Sequence
< beans::PropertyValue
>();
292 virtual uno::Sequence
< double > SAL_CALL
convertColorSpace( const uno::Sequence
< double >& deviceColor
,
293 const uno::Reference
< rendering::XColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,
294 uno::RuntimeException
)
296 // TODO(P3): if we know anything about target
297 // colorspace, this can be greatly sped up
298 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
299 convertToARGB(deviceColor
));
300 return targetColorSpace
->convertFromARGB(aIntermediate
);
302 virtual uno::Sequence
< rendering::RGBColor
> SAL_CALL
convertToRGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
304 const double* pIn( deviceColor
.getConstArray() );
305 const sal_Size
nLen( deviceColor
.getLength() );
306 ENSURE_ARG_OR_THROW2(nLen
%4==0,
307 "number of channels no multiple of 4",
308 static_cast<rendering::XColorSpace
*>(this), 0);
310 uno::Sequence
< rendering::RGBColor
> aRes(nLen
/4);
311 rendering::RGBColor
* pOut( aRes
.getArray() );
312 for( sal_Size i
=0; i
<nLen
; i
+=4 )
314 *pOut
++ = rendering::RGBColor(pIn
[0],pIn
[1],pIn
[2]);
319 virtual uno::Sequence
< rendering::ARGBColor
> SAL_CALL
convertToARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
321 const double* pIn( deviceColor
.getConstArray() );
322 const sal_Size
nLen( deviceColor
.getLength() );
323 ENSURE_ARG_OR_THROW2(nLen
%4==0,
324 "number of channels no multiple of 4",
325 static_cast<rendering::XColorSpace
*>(this), 0);
327 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/4);
328 rendering::ARGBColor
* pOut( aRes
.getArray() );
329 for( sal_Size i
=0; i
<nLen
; i
+=4 )
331 *pOut
++ = rendering::ARGBColor(pIn
[3],pIn
[0],pIn
[1],pIn
[2]);
336 virtual uno::Sequence
< rendering::ARGBColor
> SAL_CALL
convertToPARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
338 const double* pIn( deviceColor
.getConstArray() );
339 const sal_Size
nLen( deviceColor
.getLength() );
340 ENSURE_ARG_OR_THROW2(nLen
%4==0,
341 "number of channels no multiple of 4",
342 static_cast<rendering::XColorSpace
*>(this), 0);
344 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/4);
345 rendering::ARGBColor
* pOut( aRes
.getArray() );
346 for( sal_Size i
=0; i
<nLen
; i
+=4 )
348 *pOut
++ = rendering::ARGBColor(pIn
[3],pIn
[3]*pIn
[0],pIn
[3]*pIn
[1],pIn
[3]*pIn
[2]);
353 virtual uno::Sequence
< double > SAL_CALL
convertFromRGB( const uno::Sequence
< rendering::RGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
355 const rendering::RGBColor
* pIn( rgbColor
.getConstArray() );
356 const sal_Size
nLen( rgbColor
.getLength() );
358 uno::Sequence
< double > aRes(nLen
*4);
359 double* pColors
=aRes
.getArray();
360 for( sal_Size i
=0; i
<nLen
; ++i
)
362 *pColors
++ = pIn
->Red
;
363 *pColors
++ = pIn
->Green
;
364 *pColors
++ = pIn
->Blue
;
370 virtual uno::Sequence
< double > SAL_CALL
convertFromARGB( const uno::Sequence
< rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
372 const rendering::ARGBColor
* pIn( rgbColor
.getConstArray() );
373 const sal_Size
nLen( rgbColor
.getLength() );
375 uno::Sequence
< double > aRes(nLen
*4);
376 double* pColors
=aRes
.getArray();
377 for( sal_Size i
=0; i
<nLen
; ++i
)
379 *pColors
++ = pIn
->Red
;
380 *pColors
++ = pIn
->Green
;
381 *pColors
++ = pIn
->Blue
;
382 *pColors
++ = pIn
->Alpha
;
387 virtual uno::Sequence
< double > SAL_CALL
convertFromPARGB( const uno::Sequence
< rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
389 const rendering::ARGBColor
* pIn( rgbColor
.getConstArray() );
390 const sal_Size
nLen( rgbColor
.getLength() );
392 uno::Sequence
< double > aRes(nLen
*4);
393 double* pColors
=aRes
.getArray();
394 for( sal_Size i
=0; i
<nLen
; ++i
)
396 *pColors
++ = pIn
->Red
/pIn
->Alpha
;
397 *pColors
++ = pIn
->Green
/pIn
->Alpha
;
398 *pColors
++ = pIn
->Blue
/pIn
->Alpha
;
399 *pColors
++ = pIn
->Alpha
;
405 // XIntegerBitmapColorSpace
406 virtual ::sal_Int32 SAL_CALL
getBitsPerPixel( ) throw (uno::RuntimeException
)
410 virtual uno::Sequence
< ::sal_Int32
> SAL_CALL
getComponentBitCounts( ) throw (uno::RuntimeException
)
414 virtual ::sal_Int8 SAL_CALL
getEndianness( ) throw (uno::RuntimeException
)
416 return util::Endianness::LITTLE
;
418 virtual uno::Sequence
<double> SAL_CALL
convertFromIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
419 const uno::Reference
< rendering::XColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,
420 uno::RuntimeException
)
422 if( dynamic_cast<StandardColorSpace
*>(targetColorSpace
.get()) )
424 const sal_Int8
* pIn( deviceColor
.getConstArray() );
425 const sal_Size
nLen( deviceColor
.getLength() );
426 ENSURE_ARG_OR_THROW2(nLen
%4==0,
427 "number of channels no multiple of 4",
428 static_cast<rendering::XColorSpace
*>(this), 0);
430 uno::Sequence
<double> aRes(nLen
);
431 double* pOut( aRes
.getArray() );
432 for( sal_Size i
=0; i
<nLen
; i
+=4 )
434 *pOut
++ = vcl::unotools::toDoubleColor(*pIn
++);
435 *pOut
++ = vcl::unotools::toDoubleColor(*pIn
++);
436 *pOut
++ = vcl::unotools::toDoubleColor(*pIn
++);
437 *pOut
++ = vcl::unotools::toDoubleColor(255-*pIn
++);
443 // TODO(P3): if we know anything about target
444 // colorspace, this can be greatly sped up
445 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
446 convertIntegerToARGB(deviceColor
));
447 return targetColorSpace
->convertFromARGB(aIntermediate
);
450 virtual uno::Sequence
< ::sal_Int8
> SAL_CALL
convertToIntegerColorSpace( const uno::Sequence
< ::sal_Int8
>& deviceColor
,
451 const uno::Reference
< rendering::XIntegerBitmapColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,
452 uno::RuntimeException
)
454 if( dynamic_cast<StandardColorSpace
*>(targetColorSpace
.get()) )
456 // it's us, so simply pass-through the data
461 // TODO(P3): if we know anything about target
462 // colorspace, this can be greatly sped up
463 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
464 convertIntegerToARGB(deviceColor
));
465 return targetColorSpace
->convertIntegerFromARGB(aIntermediate
);
468 virtual uno::Sequence
< rendering::RGBColor
> SAL_CALL
convertIntegerToRGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
470 const sal_Int8
* pIn( deviceColor
.getConstArray() );
471 const sal_Size
nLen( deviceColor
.getLength() );
472 ENSURE_ARG_OR_THROW2(nLen
%4==0,
473 "number of channels no multiple of 4",
474 static_cast<rendering::XColorSpace
*>(this), 0);
476 uno::Sequence
< rendering::RGBColor
> aRes(nLen
/4);
477 rendering::RGBColor
* pOut( aRes
.getArray() );
478 for( sal_Size i
=0; i
<nLen
; i
+=4 )
480 *pOut
++ = rendering::RGBColor(
481 vcl::unotools::toDoubleColor(pIn
[0]),
482 vcl::unotools::toDoubleColor(pIn
[1]),
483 vcl::unotools::toDoubleColor(pIn
[2]));
489 virtual uno::Sequence
< rendering::ARGBColor
> SAL_CALL
convertIntegerToARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
491 const sal_Int8
* pIn( deviceColor
.getConstArray() );
492 const sal_Size
nLen( deviceColor
.getLength() );
493 ENSURE_ARG_OR_THROW2(nLen
%4==0,
494 "number of channels no multiple of 4",
495 static_cast<rendering::XColorSpace
*>(this), 0);
497 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/4);
498 rendering::ARGBColor
* pOut( aRes
.getArray() );
499 for( sal_Size i
=0; i
<nLen
; i
+=4 )
501 *pOut
++ = rendering::ARGBColor(
502 vcl::unotools::toDoubleColor(255-pIn
[3]),
503 vcl::unotools::toDoubleColor(pIn
[0]),
504 vcl::unotools::toDoubleColor(pIn
[1]),
505 vcl::unotools::toDoubleColor(pIn
[2]));
511 virtual uno::Sequence
< rendering::ARGBColor
> SAL_CALL
convertIntegerToPARGB( const uno::Sequence
< ::sal_Int8
>& deviceColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
513 const sal_Int8
* pIn( deviceColor
.getConstArray() );
514 const sal_Size
nLen( deviceColor
.getLength() );
515 ENSURE_ARG_OR_THROW2(nLen
%4==0,
516 "number of channels no multiple of 4",
517 static_cast<rendering::XColorSpace
*>(this), 0);
519 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/4);
520 rendering::ARGBColor
* pOut( aRes
.getArray() );
521 for( sal_Size i
=0; i
<nLen
; i
+=4 )
523 const sal_Int8
nAlpha( 255-pIn
[3] );
524 *pOut
++ = rendering::ARGBColor(
525 vcl::unotools::toDoubleColor(nAlpha
),
526 vcl::unotools::toDoubleColor(nAlpha
*pIn
[0]),
527 vcl::unotools::toDoubleColor(nAlpha
*pIn
[1]),
528 vcl::unotools::toDoubleColor(nAlpha
*pIn
[2]));
534 virtual uno::Sequence
< ::sal_Int8
> SAL_CALL
convertIntegerFromRGB( const uno::Sequence
< rendering::RGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
536 const rendering::RGBColor
* pIn( rgbColor
.getConstArray() );
537 const sal_Size
nLen( rgbColor
.getLength() );
539 uno::Sequence
< sal_Int8
> aRes(nLen
*4);
540 sal_Int8
* pColors
=aRes
.getArray();
541 for( sal_Size i
=0; i
<nLen
; ++i
)
543 *pColors
++ = vcl::unotools::toByteColor(pIn
->Red
);
544 *pColors
++ = vcl::unotools::toByteColor(pIn
->Green
);
545 *pColors
++ = vcl::unotools::toByteColor(pIn
->Blue
);
552 virtual uno::Sequence
< ::sal_Int8
> SAL_CALL
convertIntegerFromARGB( const uno::Sequence
< rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
554 const rendering::ARGBColor
* pIn( rgbColor
.getConstArray() );
555 const sal_Size
nLen( rgbColor
.getLength() );
557 uno::Sequence
< sal_Int8
> aRes(nLen
*4);
558 sal_Int8
* pColors
=aRes
.getArray();
559 for( sal_Size i
=0; i
<nLen
; ++i
)
561 *pColors
++ = vcl::unotools::toByteColor(pIn
->Red
);
562 *pColors
++ = vcl::unotools::toByteColor(pIn
->Green
);
563 *pColors
++ = vcl::unotools::toByteColor(pIn
->Blue
);
564 *pColors
++ = 255-vcl::unotools::toByteColor(pIn
->Alpha
);
570 virtual uno::Sequence
< ::sal_Int8
> SAL_CALL
convertIntegerFromPARGB( const uno::Sequence
< rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
572 const rendering::ARGBColor
* pIn( rgbColor
.getConstArray() );
573 const sal_Size
nLen( rgbColor
.getLength() );
575 uno::Sequence
< sal_Int8
> aRes(nLen
*4);
576 sal_Int8
* pColors
=aRes
.getArray();
577 for( sal_Size i
=0; i
<nLen
; ++i
)
579 *pColors
++ = vcl::unotools::toByteColor(pIn
->Red
/pIn
->Alpha
);
580 *pColors
++ = vcl::unotools::toByteColor(pIn
->Green
/pIn
->Alpha
);
581 *pColors
++ = vcl::unotools::toByteColor(pIn
->Blue
/pIn
->Alpha
);
582 *pColors
++ = 255-vcl::unotools::toByteColor(pIn
->Alpha
);
589 StandardColorSpace() :
593 sal_Int8
* pTags
= maComponentTags
.getArray();
594 sal_Int32
* pBitCounts
= maBitCounts
.getArray();
595 pTags
[0] = rendering::ColorComponentTag::RGB_RED
;
596 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
597 pTags
[2] = rendering::ColorComponentTag::RGB_BLUE
;
598 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
607 struct StandardColorSpaceHolder
: public rtl::StaticWithInit
<uno::Reference
<rendering::XIntegerBitmapColorSpace
>,
608 StandardColorSpaceHolder
>
610 uno::Reference
<rendering::XIntegerBitmapColorSpace
> operator()()
612 return new StandardColorSpace();
617 uno::Reference
<rendering::XIntegerBitmapColorSpace
> getStdColorSpace()
619 return StandardColorSpaceHolder::get();
622 rendering::IntegerBitmapLayout
getStdMemoryLayout( const geometry::IntegerSize2D
& rBmpSize
)
624 rendering::IntegerBitmapLayout aLayout
;
626 aLayout
.ScanLines
= rBmpSize
.Height
;
627 aLayout
.ScanLineBytes
= rBmpSize
.Width
*4;
628 aLayout
.ScanLineStride
= aLayout
.ScanLineBytes
;
629 aLayout
.PlaneStride
= 0;
630 aLayout
.ColorSpace
= getStdColorSpace();
631 aLayout
.Palette
.clear();
632 aLayout
.IsMsbFirst
= sal_False
;
637 ::Color
stdIntSequenceToColor( const uno::Sequence
<sal_Int8
>& rColor
)
640 const sal_Int8
* pCols( rColor
.getConstArray() );
641 return ::Color( pCols
[3], pCols
[0], pCols
[1], pCols
[2] );
643 return ::Color( *reinterpret_cast< const ::ColorData
* >(rColor
.getConstArray()) );
647 uno::Sequence
<sal_Int8
> colorToStdIntSequence( const ::Color
& rColor
)
649 uno::Sequence
<sal_Int8
> aRet(4);
650 sal_Int8
* pCols( aRet
.getArray() );
652 pCols
[0] = rColor
.GetRed();
653 pCols
[1] = rColor
.GetGreen();
654 pCols
[2] = rColor
.GetBlue();
655 pCols
[3] = 255-rColor
.GetTransparency();
657 *reinterpret_cast<sal_Int32
*>(pCols
) = rColor
.GetColor();
662 // Create a corrected view transformation out of the give one,
663 // which ensures that the rectangle given by (0,0) and
664 // rSpriteSize is mapped with its left,top corner to (0,0)
665 // again. This is required to properly render sprite
666 // animations to buffer bitmaps.
667 ::basegfx::B2DHomMatrix
& calcRectToOriginTransform( ::basegfx::B2DHomMatrix
& o_transform
,
668 const ::basegfx::B2DRange
& i_srcRect
,
669 const ::basegfx::B2DHomMatrix
& i_transformation
)
671 if( i_srcRect
.isEmpty() )
672 return o_transform
=i_transformation
;
674 // transform by given transformation
675 ::basegfx::B2DRectangle aTransformedRect
;
677 calcTransformedRectBounds( aTransformedRect
,
681 // now move resulting left,top point of bounds to (0,0)
682 ::basegfx::B2DHomMatrix aCorrectedTransform
;
683 aCorrectedTransform
.translate( -aTransformedRect
.getMinX(),
684 -aTransformedRect
.getMinY() );
686 // prepend to original transformation
687 o_transform
= aCorrectedTransform
* i_transformation
;
692 ::basegfx::B2DRange
& calcTransformedRectBounds( ::basegfx::B2DRange
& outRect
,
693 const ::basegfx::B2DRange
& inRect
,
694 const ::basegfx::B2DHomMatrix
& transformation
)
698 if( inRect
.isEmpty() )
701 // transform all four extremal points of the rectangle,
702 // take bounding rect of those.
704 // transform left-top point
705 outRect
.expand( transformation
* inRect
.getMinimum() );
707 // transform bottom-right point
708 outRect
.expand( transformation
* inRect
.getMaximum() );
710 ::basegfx::B2DPoint aPoint
;
712 // transform top-right point
713 aPoint
.setX( inRect
.getMaxX() );
714 aPoint
.setY( inRect
.getMinY() );
716 aPoint
*= transformation
;
717 outRect
.expand( aPoint
);
719 // transform bottom-left point
720 aPoint
.setX( inRect
.getMinX() );
721 aPoint
.setY( inRect
.getMaxY() );
723 aPoint
*= transformation
;
724 outRect
.expand( aPoint
);
730 ::basegfx::B2DHomMatrix
& calcRectToRectTransform( ::basegfx::B2DHomMatrix
& o_transform
,
731 const ::basegfx::B2DRange
& destRect
,
732 const ::basegfx::B2DRange
& srcRect
,
733 const ::basegfx::B2DHomMatrix
& transformation
)
735 if( srcRect
.isEmpty() ||
738 return o_transform
=transformation
;
741 // transform inputRect by transformation
742 ::basegfx::B2DRectangle aTransformedRect
;
743 calcTransformedRectBounds( aTransformedRect
,
747 // now move resulting left,top point of bounds to (0,0)
748 ::basegfx::B2DHomMatrix aCorrectedTransform
;
749 aCorrectedTransform
.translate( -aTransformedRect
.getMinX(),
750 -aTransformedRect
.getMinY() );
752 // scale to match outRect
753 const double xDenom( aTransformedRect
.getWidth() );
754 const double yDenom( aTransformedRect
.getHeight() );
755 if( xDenom
!= 0.0 && yDenom
!= 0.0 )
756 aCorrectedTransform
.scale( destRect
.getWidth() / xDenom
,
757 destRect
.getHeight() / yDenom
);
758 // TODO(E2): error handling
760 // translate to final position
761 aCorrectedTransform
.translate( destRect
.getMinX(),
762 destRect
.getMinY() );
764 ::basegfx::B2DHomMatrix
transform( transformation
);
765 o_transform
= aCorrectedTransform
* transform
;
770 bool isInside( const ::basegfx::B2DRange
& rContainedRect
,
771 const ::basegfx::B2DRange
& rTransformRect
,
772 const ::basegfx::B2DHomMatrix
& rTransformation
)
774 if( rContainedRect
.isEmpty() || rTransformRect
.isEmpty() )
777 ::basegfx::B2DPolygon
aPoly(
778 ::basegfx::tools::createPolygonFromRect( rTransformRect
) );
779 aPoly
.transform( rTransformation
);
781 return ::basegfx::tools::isInside( aPoly
,
782 ::basegfx::tools::createPolygonFromRect(
789 bool clipAreaImpl( ::basegfx::B2IRange
* o_pDestArea
,
790 ::basegfx::B2IRange
& io_rSourceArea
,
791 ::basegfx::B2IPoint
& io_rDestPoint
,
792 const ::basegfx::B2IRange
& rSourceBounds
,
793 const ::basegfx::B2IRange
& rDestBounds
)
795 const ::basegfx::B2IPoint
aSourceTopLeft(
796 io_rSourceArea
.getMinimum() );
798 ::basegfx::B2IRange
aLocalSourceArea( io_rSourceArea
);
800 // clip source area (which must be inside rSourceBounds)
801 aLocalSourceArea
.intersect( rSourceBounds
);
803 if( aLocalSourceArea
.isEmpty() )
806 // calc relative new source area points (relative to orig
808 const ::basegfx::B2IVector
aUpperLeftOffset(
809 aLocalSourceArea
.getMinimum()-aSourceTopLeft
);
810 const ::basegfx::B2IVector
aLowerRightOffset(
811 aLocalSourceArea
.getMaximum()-aSourceTopLeft
);
813 ::basegfx::B2IRange
aLocalDestArea( io_rDestPoint
+ aUpperLeftOffset
,
814 io_rDestPoint
+ aLowerRightOffset
);
816 // clip dest area (which must be inside rDestBounds)
817 aLocalDestArea
.intersect( rDestBounds
);
819 if( aLocalDestArea
.isEmpty() )
822 // calc relative new dest area points (relative to orig
824 const ::basegfx::B2IVector
aDestUpperLeftOffset(
825 aLocalDestArea
.getMinimum()-io_rDestPoint
);
826 const ::basegfx::B2IVector
aDestLowerRightOffset(
827 aLocalDestArea
.getMaximum()-io_rDestPoint
);
829 io_rSourceArea
= ::basegfx::B2IRange( aSourceTopLeft
+ aDestUpperLeftOffset
,
830 aSourceTopLeft
+ aDestLowerRightOffset
);
831 io_rDestPoint
= aLocalDestArea
.getMinimum();
834 *o_pDestArea
= aLocalDestArea
;
840 bool clipScrollArea( ::basegfx::B2IRange
& io_rSourceArea
,
841 ::basegfx::B2IPoint
& io_rDestPoint
,
842 ::std::vector
< ::basegfx::B2IRange
>& o_ClippedAreas
,
843 const ::basegfx::B2IRange
& rBounds
)
845 ::basegfx::B2IRange aResultingDestArea
;
847 // compute full destination area (to determine uninitialized
849 const ::basegfx::B2I64Tuple
& rRange( io_rSourceArea
.getRange() );
850 ::basegfx::B2IRange
aInputDestArea( io_rDestPoint
.getX(),
851 io_rDestPoint
.getY(),
852 (io_rDestPoint
.getX()
853 + static_cast<sal_Int32
>(rRange
.getX())),
854 (io_rDestPoint
.getY()
855 + static_cast<sal_Int32
>(rRange
.getY())) );
856 // limit to output area (no point updating outside of it)
857 aInputDestArea
.intersect( rBounds
);
860 if( !clipAreaImpl( &aResultingDestArea
,
867 // finally, compute all areas clipped off the total
869 ::basegfx::computeSetDifference( o_ClippedAreas
,
871 aResultingDestArea
);
876 bool clipBlit( ::basegfx::B2IRange
& io_rSourceArea
,
877 ::basegfx::B2IPoint
& io_rDestPoint
,
878 const ::basegfx::B2IRange
& rSourceBounds
,
879 const ::basegfx::B2IRange
& rDestBounds
)
881 return clipAreaImpl( NULL
,
888 ::basegfx::B2IRange
spritePixelAreaFromB2DRange( const ::basegfx::B2DRange
& rRange
)
890 if( rRange
.isEmpty() )
891 return ::basegfx::B2IRange();
893 const ::basegfx::B2IPoint
aTopLeft( ::basegfx::fround( rRange
.getMinX() ),
894 ::basegfx::fround( rRange
.getMinY() ) );
895 return ::basegfx::B2IRange( aTopLeft
,
896 aTopLeft
+ ::basegfx::B2IPoint(
897 ::basegfx::fround( rRange
.getWidth() ),
898 ::basegfx::fround( rRange
.getHeight() ) ) );
901 uno::Sequence
< uno::Any
>& getDeviceInfo( const uno::Reference
< rendering::XCanvas
>& i_rxCanvas
,
902 uno::Sequence
< uno::Any
>& o_rxParams
)
904 o_rxParams
.realloc( 0 );
906 if( i_rxCanvas
.is() )
910 uno::Reference
< rendering::XGraphicDevice
> xDevice( i_rxCanvas
->getDevice(),
911 uno::UNO_QUERY_THROW
);
913 uno::Reference
< lang::XServiceInfo
> xServiceInfo( xDevice
,
914 uno::UNO_QUERY_THROW
);
915 uno::Reference
< beans::XPropertySet
> xPropSet( xDevice
,
916 uno::UNO_QUERY_THROW
);
918 o_rxParams
.realloc( 2 );
920 o_rxParams
[ 0 ] = uno::makeAny( xServiceInfo
->getImplementationName() );
921 o_rxParams
[ 1 ] = uno::makeAny( xPropSet
->getPropertyValue(
922 ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DeviceHandle") ) ) );
924 catch( uno::Exception
& )
926 // ignore, but return empty sequence
933 awt::Rectangle
getAbsoluteWindowRect( const awt::Rectangle
& rRect
,
934 const uno::Reference
< awt::XWindow2
>& xWin
)
936 awt::Rectangle
aRetVal( rRect
);
938 ::Window
* pWindow
= VCLUnoHelper::GetWindow(xWin
);
941 ::Point
aPoint( aRetVal
.X
,
944 aPoint
= pWindow
->OutputToScreenPixel( aPoint
);
946 aRetVal
.X
= aPoint
.X();
947 aRetVal
.Y
= aPoint
.Y();
953 ::basegfx::B2DPolyPolygon
getBoundMarksPolyPolygon( const ::basegfx::B2DRange
& rRange
)
955 ::basegfx::B2DPolyPolygon aPolyPoly
;
956 ::basegfx::B2DPolygon aPoly
;
958 const double nX0( rRange
.getMinX() );
959 const double nY0( rRange
.getMinY() );
960 const double nX1( rRange
.getMaxX() );
961 const double nY1( rRange
.getMaxY() );
963 aPoly
.append( ::basegfx::B2DPoint( nX0
+4,
965 aPoly
.append( ::basegfx::B2DPoint( nX0
,
967 aPoly
.append( ::basegfx::B2DPoint( nX0
,
969 aPolyPoly
.append( aPoly
); aPoly
.clear();
971 aPoly
.append( ::basegfx::B2DPoint( nX1
-4,
973 aPoly
.append( ::basegfx::B2DPoint( nX1
,
975 aPoly
.append( ::basegfx::B2DPoint( nX1
,
977 aPolyPoly
.append( aPoly
); aPoly
.clear();
979 aPoly
.append( ::basegfx::B2DPoint( nX0
+4,
981 aPoly
.append( ::basegfx::B2DPoint( nX0
,
983 aPoly
.append( ::basegfx::B2DPoint( nX0
,
985 aPolyPoly
.append( aPoly
); aPoly
.clear();
987 aPoly
.append( ::basegfx::B2DPoint( nX1
-4,
989 aPoly
.append( ::basegfx::B2DPoint( nX1
,
991 aPoly
.append( ::basegfx::B2DPoint( nX1
,
993 aPolyPoly
.append( aPoly
);
1000 } // namespace canvas