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_vcl.hxx"
34 #include <rtl/logfile.hxx>
35 #include <cppuhelper/compbase1.hxx>
37 #include <com/sun/star/geometry/RealSize2D.hpp>
38 #include <com/sun/star/geometry/RealPoint2D.hpp>
39 #include <com/sun/star/geometry/RealRectangle2D.hpp>
40 #include <com/sun/star/geometry/IntegerSize2D.hpp>
41 #include <com/sun/star/geometry/IntegerPoint2D.hpp>
42 #include <com/sun/star/geometry/IntegerRectangle2D.hpp>
43 #include <com/sun/star/geometry/RealBezierSegment2D.hpp>
45 #include <com/sun/star/rendering/ColorSpaceType.hpp>
46 #include <com/sun/star/rendering/RenderingIntent.hpp>
47 #include <com/sun/star/rendering/XGraphicDevice.hpp>
48 #include <com/sun/star/rendering/XBitmap.hpp>
49 #include <com/sun/star/rendering/XPolyPolygon2D.hpp>
50 #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
51 #include <com/sun/star/rendering/XIntegerBitmap.hpp>
52 #include <com/sun/star/rendering/ColorComponentTag.hpp>
54 #include <basegfx/matrix/b2dhommatrix.hxx>
55 #include <basegfx/vector/b2dsize.hxx>
56 #include <basegfx/point/b2dpoint.hxx>
57 #include <basegfx/range/b2drectangle.hxx>
58 #include <basegfx/vector/b2isize.hxx>
59 #include <basegfx/point/b2ipoint.hxx>
60 #include <basegfx/range/b2irectangle.hxx>
63 #include <basegfx/polygon/b2dpolygon.hxx>
64 #include <basegfx/tools/canvastools.hxx>
65 #include <basegfx/polygon/b2dpolypolygon.hxx>
67 #include <tools/poly.hxx>
68 #include <tools/diagnose_ex.h>
71 #include <vcl/salbtype.hxx>
72 #include <vcl/bmpacc.hxx>
73 #include <vcl/bitmapex.hxx>
75 #include <vcl/canvasbitmap.hxx>
76 #include <vcl/canvastools.hxx>
80 using namespace ::com::sun::star
;
86 // #i79917# removed helpers bezierSequenceFromPolygon and
87 // pointSequenceFromPolygon here
88 // Also all helpers using tools Polygon and PolyPolygon will get mapped to the
89 // B2DPolygon helpers for these cases, see comments with the same TaskID below.
90 // TODO: Remove those wrapped methods
92 //---------------------------------------------------------------------------------------
94 uno::Reference
< rendering::XPolyPolygon2D
> xPolyPolygonFromPolygon( const uno::Reference
< rendering::XGraphicDevice
>& xGraphicDevice
,
95 const ::Polygon
& inputPolygon
)
97 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::xPolyPolygonFromPolygon()" );
99 // #i79917# map to basegfx
100 const basegfx::B2DPolygon
aB2DPolygon(inputPolygon
.getB2DPolygon());
101 return basegfx::unotools::xPolyPolygonFromB2DPolygon(xGraphicDevice
, aB2DPolygon
);
104 //---------------------------------------------------------------------------------------
106 uno::Reference
< rendering::XPolyPolygon2D
> xPolyPolygonFromPolyPolygon( const uno::Reference
< rendering::XGraphicDevice
>& xGraphicDevice
,
107 const ::PolyPolygon
& inputPolyPolygon
)
109 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::xPolyPolygonFromPolyPolygon()" );
111 // #i79917# map to basegfx
112 const basegfx::B2DPolyPolygon
aB2DPolyPolygon(inputPolyPolygon
.getB2DPolyPolygon());
113 return basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(xGraphicDevice
, aB2DPolyPolygon
);
116 //---------------------------------------------------------------------------------------
118 ::Polygon
polygonFromPoint2DSequence( const uno::Sequence
< geometry::RealPoint2D
>& points
)
120 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::polygonFromPoint2DSequence()" );
122 const USHORT
nCurrSize( sal::static_int_cast
<USHORT
>(points
.getLength()) );
124 ::Polygon
aPoly( nCurrSize
);
127 for( nCurrPoint
=0; nCurrPoint
<nCurrSize
; ++nCurrPoint
)
128 aPoly
[nCurrPoint
] = pointFromRealPoint2D( points
[nCurrPoint
] );
133 //---------------------------------------------------------------------------------------
135 ::PolyPolygon
polyPolygonFromPoint2DSequenceSequence( const uno::Sequence
< uno::Sequence
< geometry::RealPoint2D
> >& points
)
137 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::polyPolygonFromPoint2DSequenceSequence()" );
142 for( nCurrPoly
=0; nCurrPoly
<points
.getLength(); ++nCurrPoly
)
144 aRes
.Insert( polygonFromPoint2DSequence( points
[nCurrPoly
] ) );
150 //---------------------------------------------------------------------------------------
152 ::Polygon
polygonFromBezier2DSequence( const uno::Sequence
< geometry::RealBezierSegment2D
>& curves
)
154 // #i79917# map to basegfx
155 const basegfx::B2DPolygon
aB2DPolygon(basegfx::unotools::polygonFromBezier2DSequence(curves
));
156 return ::Polygon(aB2DPolygon
);
159 //---------------------------------------------------------------------------------------
161 ::PolyPolygon
polyPolygonFromBezier2DSequenceSequence( const uno::Sequence
< uno::Sequence
< geometry::RealBezierSegment2D
> >& curves
)
163 // #i79917# map to basegfx
164 const basegfx::B2DPolyPolygon
aB2DPolyPolygon(basegfx::unotools::polyPolygonFromBezier2DSequenceSequence(curves
));
165 return ::PolyPolygon(aB2DPolyPolygon
);
168 //---------------------------------------------------------------------------------------
170 uno::Reference
< rendering::XBitmap
> xBitmapFromBitmap( const uno::Reference
< rendering::XGraphicDevice
>& /*xGraphicDevice*/,
171 const ::Bitmap
& inputBitmap
)
173 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::xBitmapFromBitmap()" );
175 return new vcl::unotools::VclCanvasBitmap( BitmapEx( inputBitmap
) );
178 //---------------------------------------------------------------------------------------
180 uno::Reference
< rendering::XBitmap
> xBitmapFromBitmapEx( const uno::Reference
< rendering::XGraphicDevice
>& /*xGraphicDevice*/,
181 const ::BitmapEx
& inputBitmap
)
183 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::xBitmapFromBitmapEx()" );
185 return new vcl::unotools::VclCanvasBitmap( inputBitmap
);
188 //---------------------------------------------------------------------------------------
190 const uno::Sequence
< sal_Int8
> getTunnelIdentifier( TunnelIdentifierType eType
)
192 static std::hash_map
< int, uno::Sequence
< sal_Int8
> > aIds
;
193 std::hash_map
< int, uno::Sequence
< sal_Int8
> >::iterator it
=
195 if( it
== aIds
.end() )
197 uno::Sequence
< sal_Int8
> aNewId( 16 );
198 rtl_createUuid( (sal_uInt8
*)aNewId
.getArray(), NULL
, sal_True
);
199 aIds
[ eType
] = aNewId
;
200 it
= aIds
.find( eType
);
205 //---------------------------------------------------------------------------------------
209 inline bool operator==( const rendering::IntegerBitmapLayout
& rLHS
,
210 const rendering::IntegerBitmapLayout
& rRHS
)
213 rLHS
.ScanLineBytes
== rRHS
.ScanLineBytes
&&
214 rLHS
.ScanLineStride
== rRHS
.ScanLineStride
&&
215 rLHS
.PlaneStride
== rRHS
.PlaneStride
&&
216 rLHS
.ColorSpace
== rRHS
.ColorSpace
&&
217 rLHS
.Palette
== rRHS
.Palette
&&
218 rLHS
.IsMsbFirst
== rRHS
.IsMsbFirst
;
221 bool readBmp( sal_Int32 nWidth
,
223 const rendering::IntegerBitmapLayout
& rLayout
,
224 const uno::Reference
< rendering::XIntegerReadOnlyBitmap
>& xInputBitmap
,
225 ScopedBitmapWriteAccess
& rWriteAcc
,
226 ScopedBitmapWriteAccess
& rAlphaAcc
)
228 rendering::IntegerBitmapLayout aCurrLayout
;
229 geometry::IntegerRectangle2D aRect
;
230 uno::Sequence
<sal_Int8
> aPixelData
;
231 uno::Sequence
<rendering::RGBColor
> aRGBColors
;
232 uno::Sequence
<rendering::ARGBColor
> aARGBColors
;
234 for( aRect
.Y1
=0; aRect
.Y1
<nHeight
; ++aRect
.Y1
)
236 aRect
.X1
= 0; aRect
.X2
= nWidth
; aRect
.Y2
= aRect
.Y1
+1;
239 aPixelData
= xInputBitmap
->getData(aCurrLayout
,aRect
);
241 catch( rendering::VolatileContentDestroyedException
& )
243 // re-read bmp from the start
246 if( !(aCurrLayout
== rLayout
) )
247 return false; // re-read bmp from the start
249 if( rAlphaAcc
.get() )
252 aARGBColors
= rLayout
.ColorSpace
->convertIntegerToARGB(aPixelData
);
254 if( rWriteAcc
->HasPalette() )
256 for( sal_Int32 x
=0; x
<nWidth
; ++x
)
258 const rendering::ARGBColor
& rColor
=aARGBColors
[x
];
259 rWriteAcc
->SetPixel( aRect
.Y1
, x
,
260 (BYTE
)rWriteAcc
->GetBestPaletteIndex(
261 BitmapColor( toByteColor(rColor
.Red
),
262 toByteColor(rColor
.Green
),
263 toByteColor(rColor
.Blue
))) );
264 rAlphaAcc
->SetPixel( aRect
.Y1
, x
,
265 BitmapColor( 255 - toByteColor(rColor
.Alpha
) ));
270 for( sal_Int32 x
=0; x
<nWidth
; ++x
)
272 const rendering::ARGBColor
& rColor
=aARGBColors
[x
];
273 rWriteAcc
->SetPixel( aRect
.Y1
, x
,
274 BitmapColor( toByteColor(rColor
.Red
),
275 toByteColor(rColor
.Green
),
276 toByteColor(rColor
.Blue
) ));
277 rAlphaAcc
->SetPixel( aRect
.Y1
, x
,
278 BitmapColor( 255 - toByteColor(rColor
.Alpha
) ));
285 aRGBColors
= rLayout
.ColorSpace
->convertIntegerToRGB(aPixelData
);
286 if( rWriteAcc
->HasPalette() )
288 for( sal_Int32 x
=0; x
<nWidth
; ++x
)
290 const rendering::RGBColor
& rColor
=aRGBColors
[x
];
291 rWriteAcc
->SetPixel( aRect
.Y1
, x
,
292 (BYTE
)rWriteAcc
->GetBestPaletteIndex(
293 BitmapColor( toByteColor(rColor
.Red
),
294 toByteColor(rColor
.Green
),
295 toByteColor(rColor
.Blue
))) );
300 for( sal_Int32 x
=0; x
<nWidth
; ++x
)
302 const rendering::RGBColor
& rColor
=aRGBColors
[x
];
303 rWriteAcc
->SetPixel( aRect
.Y1
, x
,
304 BitmapColor( toByteColor(rColor
.Red
),
305 toByteColor(rColor
.Green
),
306 toByteColor(rColor
.Blue
) ));
316 ::BitmapEx VCL_DLLPUBLIC
bitmapExFromXBitmap( const uno::Reference
< rendering::XIntegerReadOnlyBitmap
>& xInputBitmap
)
318 RTL_LOGFILE_CONTEXT( aLog
, "::vcl::unotools::bitmapExFromXBitmap()" );
320 if( !xInputBitmap
.is() )
323 // tunnel directly for known implementation
324 // ----------------------------------------------------------------
325 VclCanvasBitmap
* pImplBitmap
= dynamic_cast<VclCanvasBitmap
*>(xInputBitmap
.get());
327 return pImplBitmap
->getBitmapEx();
329 // retrieve data via UNO interface
330 // ----------------------------------------------------------------
332 // volatile bitmaps are a bit more complicated to read
334 uno::Reference
<rendering::XVolatileBitmap
> xVolatileBitmap(
335 xInputBitmap
, uno::UNO_QUERY
);
337 // loop a few times, until successfully read (for XVolatileBitmap)
338 for( int i
=0; i
<10; ++i
)
341 sal_Int32 nAlphaDepth
=0;
342 const rendering::IntegerBitmapLayout
aLayout(
343 xInputBitmap
->getMemoryLayout());
345 OSL_ENSURE(aLayout
.ColorSpace
.is(),
346 "Cannot convert image without color space!");
347 if( !aLayout
.ColorSpace
.is() )
350 nDepth
= aLayout
.ColorSpace
->getBitsPerPixel();
352 if( xInputBitmap
->hasAlpha() )
354 // determine alpha channel depth
355 const uno::Sequence
<sal_Int8
> aTags(
356 aLayout
.ColorSpace
->getComponentTags() );
357 const uno::Sequence
<sal_Int32
> aDepths(
358 aLayout
.ColorSpace
->getComponentBitCounts() );
359 const sal_Int8
* pStart(aTags
.getConstArray());
360 const sal_Size
nLen(aTags
.getLength());
361 const sal_Int8
* pEnd(pStart
+nLen
);
363 const std::ptrdiff_t nAlphaIndex
=
364 std::find(pStart
,pEnd
,
365 rendering::ColorComponentTag::ALPHA
) - pStart
;
367 if( nAlphaIndex
< sal::static_int_cast
<std::ptrdiff_t>(nLen
) )
369 nAlphaDepth
= aLayout
.ColorSpace
->getComponentBitCounts()[nAlphaIndex
] > 1 ? 8 : 1;
370 nDepth
-= nAlphaDepth
;
374 BitmapPalette aPalette
;
375 if( aLayout
.Palette
.is() )
377 uno::Reference
< rendering::XColorSpace
> xPaletteColorSpace(
378 aLayout
.Palette
->getColorSpace());
379 ENSURE_OR_THROW(xPaletteColorSpace
.is(),
380 "Palette without color space");
382 const sal_Int32
nEntryCount( aLayout
.Palette
->getNumberOfEntries() );
383 if( nEntryCount
<= 256 )
385 if( nEntryCount
<= 2 )
390 const USHORT
nPaletteEntries(
391 sal::static_int_cast
<USHORT
>(
392 std::min(sal_Int32(255), nEntryCount
)));
394 // copy palette entries
395 aPalette
.SetEntryCount(nPaletteEntries
);
396 uno::Reference
<rendering::XBitmapPalette
> xPalette( aLayout
.Palette
);
397 uno::Reference
<rendering::XColorSpace
> xPalColorSpace( xPalette
->getColorSpace() );
399 uno::Sequence
<double> aPaletteEntry
;
400 for( USHORT j
=0; j
<nPaletteEntries
; ++j
)
402 if( !xPalette
->getIndex(aPaletteEntry
,j
) &&
407 uno::Sequence
<rendering::RGBColor
> aColors
=xPalColorSpace
->convertToRGB(aPaletteEntry
);
408 ENSURE_OR_THROW(aColors
.getLength() == 1,
409 "Palette returned more or less than one entry");
410 const rendering::RGBColor
& rColor
=aColors
[0];
411 aPalette
[j
] = BitmapColor(toByteColor(rColor
.Red
),
412 toByteColor(rColor
.Green
),
413 toByteColor(rColor
.Blue
));
418 const ::Size
aPixelSize(
419 sizeFromIntegerSize2D(xInputBitmap
->getSize()));
421 // normalize bitcount
423 ( nDepth
<= 1 ) ? 1 :
424 ( nDepth
<= 4 ) ? 4 :
425 ( nDepth
<= 8 ) ? 8 : 24;
427 ::Bitmap
aBitmap( aPixelSize
,
428 sal::static_int_cast
<USHORT
>(nDepth
),
429 aLayout
.Palette
.is() ? &aPalette
: NULL
);
432 aAlpha
= ::Bitmap( aPixelSize
,
433 sal::static_int_cast
<USHORT
>(nAlphaDepth
),
434 &::Bitmap::GetGreyPalette(
435 sal::static_int_cast
<USHORT
>(1L << nAlphaDepth
)) );
437 { // limit scoped access
438 ScopedBitmapWriteAccess
pWriteAccess( aBitmap
.AcquireWriteAccess(),
440 ScopedBitmapWriteAccess
pAlphaWriteAccess( nAlphaDepth
? aAlpha
.AcquireWriteAccess() : NULL
,
443 ENSURE_OR_THROW(pWriteAccess
.get() != NULL
,
444 "Cannot get write access to bitmap");
446 const sal_Int32
nWidth(aPixelSize
.Width());
447 const sal_Int32
nHeight(aPixelSize
.Height());
449 if( !readBmp(nWidth
,nHeight
,aLayout
,xInputBitmap
,
450 pWriteAccess
,pAlphaWriteAccess
) )
452 } // limit scoped access
455 return ::BitmapEx( aBitmap
,
456 AlphaMask( aAlpha
) );
458 return ::BitmapEx( aBitmap
);
461 // failed to read data 10 times - bail out
465 //---------------------------------------------------------------------------------------
467 geometry::RealSize2D
size2DFromSize( const Size
& rSize
)
469 return geometry::RealSize2D( rSize
.Width(),
473 geometry::RealPoint2D
point2DFromPoint( const Point
& rPoint
)
475 return geometry::RealPoint2D( rPoint
.X(),
479 geometry::RealRectangle2D
rectangle2DFromRectangle( const Rectangle
& rRect
)
481 return geometry::RealRectangle2D( rRect
.Left(), rRect
.Top(),
482 rRect
.Right(), rRect
.Bottom() );
485 Size
sizeFromRealSize2D( const geometry::RealSize2D
& rSize
)
487 return Size( static_cast<long>(rSize
.Width
+ .5),
488 static_cast<long>(rSize
.Height
+ .5) );
491 Point
pointFromRealPoint2D( const geometry::RealPoint2D
& rPoint
)
493 return Point( static_cast<long>(rPoint
.X
+ .5),
494 static_cast<long>(rPoint
.Y
+ .5) );
497 Rectangle
rectangleFromRealRectangle2D( const geometry::RealRectangle2D
& rRect
)
499 return Rectangle( static_cast<long>(rRect
.X1
+ .5),
500 static_cast<long>(rRect
.Y1
+ .5),
501 static_cast<long>(rRect
.X2
+ .5),
502 static_cast<long>(rRect
.Y2
+ .5) );
505 ::Size
sizeFromB2DSize( const ::basegfx::B2DVector
& rVec
)
507 return ::Size( FRound( rVec
.getX() ),
508 FRound( rVec
.getY() ) );
511 ::Point
pointFromB2DPoint( const ::basegfx::B2DPoint
& rPoint
)
513 return ::Point( FRound( rPoint
.getX() ),
514 FRound( rPoint
.getY() ) );
517 ::Rectangle
rectangleFromB2DRectangle( const ::basegfx::B2DRange
& rRect
)
519 return ::Rectangle( FRound( rRect
.getMinX() ),
520 FRound( rRect
.getMinY() ),
521 FRound( rRect
.getMaxX() ),
522 FRound( rRect
.getMaxY() ) );
525 Size
sizeFromB2ISize( const ::basegfx::B2IVector
& rVec
)
527 return ::Size( rVec
.getX(),
531 Point
pointFromB2IPoint( const ::basegfx::B2IPoint
& rPoint
)
533 return ::Point( rPoint
.getX(),
537 Rectangle
rectangleFromB2IRectangle( const ::basegfx::B2IRange
& rRect
)
539 return ::Rectangle( rRect
.getMinX(),
545 ::basegfx::B2DVector
b2DSizeFromSize( const ::Size
& rSize
)
547 return ::basegfx::B2DVector( rSize
.Width(),
551 ::basegfx::B2DPoint
b2DPointFromPoint( const ::Point
& rPoint
)
553 return ::basegfx::B2DPoint( rPoint
.X(),
557 ::basegfx::B2DRange
b2DRectangleFromRectangle( const ::Rectangle
& rRect
)
559 return ::basegfx::B2DRange( rRect
.Left(),
565 basegfx::B2IVector
b2ISizeFromSize( const Size
& rSize
)
567 return ::basegfx::B2IVector( rSize
.Width(),
571 basegfx::B2IPoint
b2IPointFromPoint( const Point
& rPoint
)
573 return ::basegfx::B2IPoint( rPoint
.X(),
577 basegfx::B2IRange
b2IRectangleFromRectangle( const Rectangle
& rRect
)
579 return ::basegfx::B2IRange( rRect
.Left(),
585 geometry::IntegerSize2D
integerSize2DFromSize( const Size
& rSize
)
587 return geometry::IntegerSize2D( rSize
.Width(),
591 geometry::IntegerPoint2D
integerPoint2DFromPoint( const Point
& rPoint
)
593 return geometry::IntegerPoint2D( rPoint
.X(),
597 geometry::IntegerRectangle2D
integerRectangle2DFromRectangle( const Rectangle
& rRectangle
)
599 return geometry::IntegerRectangle2D( rRectangle
.Left(), rRectangle
.Top(),
600 rRectangle
.Right(), rRectangle
.Bottom() );
603 Size
sizeFromIntegerSize2D( const geometry::IntegerSize2D
& rSize
)
605 return Size( rSize
.Width
,
609 Point
pointFromIntegerPoint2D( const geometry::IntegerPoint2D
& rPoint
)
611 return Point( rPoint
.X
,
615 Rectangle
rectangleFromIntegerRectangle2D( const geometry::IntegerRectangle2D
& rRectangle
)
617 return Rectangle( rRectangle
.X1
, rRectangle
.Y1
,
618 rRectangle
.X2
, rRectangle
.Y2
);
623 class StandardColorSpace
: public cppu::WeakImplHelper1
< com::sun::star::rendering::XColorSpace
>
626 uno::Sequence
< sal_Int8
> m_aComponentTags
;
628 virtual ::sal_Int8 SAL_CALL
getType( ) throw (uno::RuntimeException
)
630 return rendering::ColorSpaceType::RGB
;
632 virtual uno::Sequence
< ::sal_Int8
> SAL_CALL
getComponentTags( ) throw (uno::RuntimeException
)
634 return m_aComponentTags
;
636 virtual ::sal_Int8 SAL_CALL
getRenderingIntent( ) throw (uno::RuntimeException
)
638 return rendering::RenderingIntent::PERCEPTUAL
;
640 virtual uno::Sequence
< beans::PropertyValue
> SAL_CALL
getProperties( ) throw (uno::RuntimeException
)
642 return uno::Sequence
< beans::PropertyValue
>();
644 virtual uno::Sequence
< double > SAL_CALL
convertColorSpace( const uno::Sequence
< double >& deviceColor
,
645 const uno::Reference
< rendering::XColorSpace
>& targetColorSpace
) throw (lang::IllegalArgumentException
,
646 uno::RuntimeException
)
648 // TODO(P3): if we know anything about target
649 // colorspace, this can be greatly sped up
650 uno::Sequence
<rendering::ARGBColor
> aIntermediate(
651 convertToARGB(deviceColor
));
652 return targetColorSpace
->convertFromARGB(aIntermediate
);
654 virtual uno::Sequence
< rendering::RGBColor
> SAL_CALL
convertToRGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
656 const double* pIn( deviceColor
.getConstArray() );
657 const sal_Size
nLen( deviceColor
.getLength() );
658 ENSURE_ARG_OR_THROW2(nLen
%4==0,
659 "number of channels no multiple of 4",
660 static_cast<rendering::XColorSpace
*>(this), 0);
662 uno::Sequence
< rendering::RGBColor
> aRes(nLen
/4);
663 rendering::RGBColor
* pOut( aRes
.getArray() );
664 for( sal_Size i
=0; i
<nLen
; i
+=4 )
666 *pOut
++ = rendering::RGBColor(pIn
[0],pIn
[1],pIn
[2]);
671 virtual uno::Sequence
< rendering::ARGBColor
> SAL_CALL
convertToARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
673 const double* pIn( deviceColor
.getConstArray() );
674 const sal_Size
nLen( deviceColor
.getLength() );
675 ENSURE_ARG_OR_THROW2(nLen
%4==0,
676 "number of channels no multiple of 4",
677 static_cast<rendering::XColorSpace
*>(this), 0);
679 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/4);
680 rendering::ARGBColor
* pOut( aRes
.getArray() );
681 for( sal_Size i
=0; i
<nLen
; i
+=4 )
683 *pOut
++ = rendering::ARGBColor(pIn
[3],pIn
[0],pIn
[1],pIn
[2]);
688 virtual uno::Sequence
< rendering::ARGBColor
> SAL_CALL
convertToPARGB( const uno::Sequence
< double >& deviceColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
690 const double* pIn( deviceColor
.getConstArray() );
691 const sal_Size
nLen( deviceColor
.getLength() );
692 ENSURE_ARG_OR_THROW2(nLen
%4==0,
693 "number of channels no multiple of 4",
694 static_cast<rendering::XColorSpace
*>(this), 0);
696 uno::Sequence
< rendering::ARGBColor
> aRes(nLen
/4);
697 rendering::ARGBColor
* pOut( aRes
.getArray() );
698 for( sal_Size i
=0; i
<nLen
; i
+=4 )
700 *pOut
++ = rendering::ARGBColor(pIn
[3],pIn
[3]*pIn
[0],pIn
[3]*pIn
[1],pIn
[3]*pIn
[2]);
705 virtual uno::Sequence
< double > SAL_CALL
convertFromRGB( const uno::Sequence
< rendering::RGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
707 const rendering::RGBColor
* pIn( rgbColor
.getConstArray() );
708 const sal_Size
nLen( rgbColor
.getLength() );
710 uno::Sequence
< double > aRes(nLen
*4);
711 double* pColors
=aRes
.getArray();
712 for( sal_Size i
=0; i
<nLen
; ++i
)
714 *pColors
++ = pIn
->Red
;
715 *pColors
++ = pIn
->Green
;
716 *pColors
++ = pIn
->Blue
;
722 virtual uno::Sequence
< double > SAL_CALL
convertFromARGB( const uno::Sequence
< rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
724 const rendering::ARGBColor
* pIn( rgbColor
.getConstArray() );
725 const sal_Size
nLen( rgbColor
.getLength() );
727 uno::Sequence
< double > aRes(nLen
*4);
728 double* pColors
=aRes
.getArray();
729 for( sal_Size i
=0; i
<nLen
; ++i
)
731 *pColors
++ = pIn
->Red
;
732 *pColors
++ = pIn
->Green
;
733 *pColors
++ = pIn
->Blue
;
734 *pColors
++ = pIn
->Alpha
;
739 virtual uno::Sequence
< double > SAL_CALL
convertFromPARGB( const uno::Sequence
< rendering::ARGBColor
>& rgbColor
) throw (lang::IllegalArgumentException
, uno::RuntimeException
)
741 const rendering::ARGBColor
* pIn( rgbColor
.getConstArray() );
742 const sal_Size
nLen( rgbColor
.getLength() );
744 uno::Sequence
< double > aRes(nLen
*4);
745 double* pColors
=aRes
.getArray();
746 for( sal_Size i
=0; i
<nLen
; ++i
)
748 *pColors
++ = pIn
->Red
/pIn
->Alpha
;
749 *pColors
++ = pIn
->Green
/pIn
->Alpha
;
750 *pColors
++ = pIn
->Blue
/pIn
->Alpha
;
751 *pColors
++ = pIn
->Alpha
;
758 StandardColorSpace() : m_aComponentTags(4)
760 sal_Int8
* pTags
= m_aComponentTags
.getArray();
761 pTags
[0] = rendering::ColorComponentTag::RGB_RED
;
762 pTags
[1] = rendering::ColorComponentTag::RGB_GREEN
;
763 pTags
[2] = rendering::ColorComponentTag::RGB_BLUE
;
764 pTags
[3] = rendering::ColorComponentTag::ALPHA
;
769 uno::Reference
<rendering::XColorSpace
> VCL_DLLPUBLIC
createStandardColorSpace()
771 return new StandardColorSpace();
774 //---------------------------------------------------------------------------------------
776 uno::Sequence
< double > colorToStdColorSpaceSequence( const Color
& rColor
)
778 uno::Sequence
< double > aRet(4);
779 double* pRet
= aRet
.getArray();
781 pRet
[0] = toDoubleColor(rColor
.GetRed());
782 pRet
[1] = toDoubleColor(rColor
.GetGreen());
783 pRet
[2] = toDoubleColor(rColor
.GetBlue());
785 // VCL's notion of alpha is different from the rest of the world's
786 pRet
[3] = 1.0 - toDoubleColor(rColor
.GetTransparency());
791 Color
stdColorSpaceSequenceToColor( const uno::Sequence
< double >& rColor
)
793 ENSURE_ARG_OR_THROW( rColor
.getLength() == 4,
794 "color must have 4 channels" );
798 aColor
.SetRed ( toByteColor(rColor
[0]) );
799 aColor
.SetGreen( toByteColor(rColor
[1]) );
800 aColor
.SetBlue ( toByteColor(rColor
[2]) );
801 // VCL's notion of alpha is different from the rest of the world's
802 aColor
.SetTransparency( 255 - toByteColor(rColor
[3]) );
807 uno::Sequence
< double > VCL_DLLPUBLIC
colorToDoubleSequence(
809 const uno::Reference
< rendering::XColorSpace
>& xColorSpace
)
811 uno::Sequence
<rendering::ARGBColor
> aSeq(1);
812 aSeq
[0] = rendering::ARGBColor(
813 1.0-toDoubleColor(rColor
.GetTransparency()),
814 toDoubleColor(rColor
.GetRed()),
815 toDoubleColor(rColor
.GetGreen()),
816 toDoubleColor(rColor
.GetBlue()) );
818 return xColorSpace
->convertFromARGB(aSeq
);
821 Color VCL_DLLPUBLIC
doubleSequenceToColor(
822 const uno::Sequence
< double > rColor
,
823 const uno::Reference
< rendering::XColorSpace
>& xColorSpace
)
825 const rendering::ARGBColor
& rARGBColor(
826 xColorSpace
->convertToARGB(rColor
)[0]);
828 return Color( 255-toByteColor(rARGBColor
.Alpha
),
829 toByteColor(rARGBColor
.Red
),
830 toByteColor(rARGBColor
.Green
),
831 toByteColor(rARGBColor
.Blue
) );
834 //---------------------------------------------------------------------------------------
836 } // namespace vcltools
838 } // namespace canvas