diff options
author | Kurt Zenker <kz@openoffice.org> | 2008-06-24 10:41:34 +0000 |
---|---|---|
committer | Kurt Zenker <kz@openoffice.org> | 2008-06-24 10:41:34 +0000 |
commit | 9d3e9d5f5da6baef8f3ea9deb17ef6b04f6b22b2 (patch) | |
tree | b3bf9aa185c4390a8ba161835568ad18928a0699 /vcl/source | |
parent | 7f6e151b25ca63e4eee637324bc2aeeae1b032c8 (diff) |
INTEGRATION: CWS canvas05 (1.13.56); FILE MERGED
2008/04/21 07:47:36 thb 1.13.56.5: RESYNC: (1.13-1.14); FILE MERGED
2008/04/04 22:06:55 thb 1.13.56.4: Fixed typo in alpha channel sequence index
2008/03/13 16:56:55 thb 1.13.56.3: Adapting VCL ColorSpace impls to API change; implementing some cheap paths for color space conversions
2007/10/02 11:03:26 thb 1.13.56.2: #i10000# WaE fix for Solaris
2007/10/01 13:40:13 thb 1.13.56.1: #i78888# #i78925# #i79258# #i79437# #i79846# Merge from CWS picom
Diffstat (limited to 'vcl/source')
-rw-r--r-- | vcl/source/helper/canvastools.cxx | 521 |
1 files changed, 384 insertions, 137 deletions
diff --git a/vcl/source/helper/canvastools.cxx b/vcl/source/helper/canvastools.cxx index cf6abc986eb1..3a239d7c3b3c 100644 --- a/vcl/source/helper/canvastools.cxx +++ b/vcl/source/helper/canvastools.cxx @@ -7,7 +7,7 @@ * OpenOffice.org - a multi-platform office productivity suite * * $RCSfile: canvastools.cxx,v $ - * $Revision: 1.14 $ + * $Revision: 1.15 $ * * This file is part of OpenOffice.org. * @@ -30,51 +30,27 @@ // MARKER(update_precomp.py): autogen include statement, do not remove #include "precompiled_vcl.hxx" + #include <rtl/logfile.hxx> +#include <cppuhelper/compbase1.hxx> -#ifndef _COM_SUN_STAR_GEOMETRY_REALSIZE2D_HPP__ #include <com/sun/star/geometry/RealSize2D.hpp> -#endif -#ifndef _COM_SUN_STAR_GEOMETRY_REALPOINT2D_HPP__ #include <com/sun/star/geometry/RealPoint2D.hpp> -#endif -#ifndef _COM_SUN_STAR_GEOMETRY_REALRECTANGLE2D_HPP__ #include <com/sun/star/geometry/RealRectangle2D.hpp> -#endif -#ifndef _COM_SUN_STAR_GEOMETRY_INTEGERSIZE2D_HPP__ #include <com/sun/star/geometry/IntegerSize2D.hpp> -#endif -#ifndef _COM_SUN_STAR_GEOMETRY_INTEGERPOINT2D_HPP__ #include <com/sun/star/geometry/IntegerPoint2D.hpp> -#endif -#ifndef _COM_SUN_STAR_GEOMETRY_INTEGERRECTANGLE2D_HPP__ #include <com/sun/star/geometry/IntegerRectangle2D.hpp> -#endif +#include <com/sun/star/geometry/RealBezierSegment2D.hpp> -#ifndef _COM_SUN_STAR_RENDERING_XGRAPHICDEVICE_HPP__ +#include <com/sun/star/rendering/ColorSpaceType.hpp> +#include <com/sun/star/rendering/RenderingIntent.hpp> #include <com/sun/star/rendering/XGraphicDevice.hpp> -#endif -#ifndef _COM_SUN_STAR_RENDERING_XBITMAP_HPP__ #include <com/sun/star/rendering/XBitmap.hpp> -#endif -#ifndef _COM_SUN_STAR_RENDERING_XPOLYPOLYGON2D_HPP__ #include <com/sun/star/rendering/XPolyPolygon2D.hpp> -#endif -#ifndef _COM_SUN_STAR_GEOMETRY_REALBEZIERSEGMENT2D_HPP__ -#include <com/sun/star/geometry/RealBezierSegment2D.hpp> -#endif -#ifndef _COM_SUN_STAR_RENDERING_INTEGERBITMAPFORMAT_HPP__ -#include <com/sun/star/rendering/IntegerBitmapFormat.hpp> -#endif -#ifndef _COM_SUN_STAR_RENDERING_INTEGERBITMAPLAYOUT_HPP__ #include <com/sun/star/rendering/IntegerBitmapLayout.hpp> -#endif -#ifndef _COM_SUN_STAR_RENDERING_ENDIANNESS_HPP__ -#include <com/sun/star/rendering/Endianness.hpp> -#endif -#ifndef _COM_SUN_STAR_RENDERING_XINTEGERBITMAP_HPP__ #include <com/sun/star/rendering/XIntegerBitmap.hpp> -#endif +#include <com/sun/star/rendering/ColorComponentTag.hpp> + #include <basegfx/matrix/b2dhommatrix.hxx> #include <basegfx/vector/b2dsize.hxx> #include <basegfx/point/b2dpoint.hxx> @@ -89,6 +65,7 @@ #include <basegfx/polygon/b2dpolypolygon.hxx> #include <tools/poly.hxx> +#include <tools/diagnose_ex.h> #include <rtl/uuid.h> #include <vcl/salbtype.hxx> @@ -227,140 +204,229 @@ namespace vcl //--------------------------------------------------------------------------------------- - ::BitmapEx bitmapExFromXBitmap( const uno::Reference< rendering::XGraphicDevice >& xGraphicDevice, - const uno::Reference< rendering::XIntegerBitmap >& xInputBitmap ) + namespace { - RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::bitmapExFromXBitmap()" ); - - if( !xGraphicDevice.is() || !xInputBitmap.is() ) - return ::BitmapEx(); - - uno::Reference< lang::XUnoTunnel > xTunnel( xInputBitmap, uno::UNO_QUERY ); - if( xTunnel.is() ) + inline bool operator==( const rendering::IntegerBitmapLayout& rLHS, + const rendering::IntegerBitmapLayout& rRHS ) { - const uno::Sequence< sal_Int8 >& rTest = getTunnelIdentifier( Id_BitmapEx ); - sal_Int64 nPtr = xTunnel->getSomething( rTest ); - if( nPtr != 0 ) - { - return BitmapEx( *(BitmapEx*)sal_IntPtr(nPtr) ); - } + return + rLHS.ScanLineBytes == rRHS.ScanLineBytes && + rLHS.ScanLineStride == rRHS.ScanLineStride && + rLHS.PlaneStride == rRHS.PlaneStride && + rLHS.ColorSpace == rRHS.ColorSpace && + rLHS.Palette == rRHS.Palette && + rLHS.IsMsbFirst == rRHS.IsMsbFirst; } - rendering::IntegerBitmapLayout aFormat; - const Size aPixelSize( sizeFromIntegerSize2D( xInputBitmap->getSize() ) ); - const uno::Sequence< sal_Int8 > data( xInputBitmap->getData( - aFormat, - geometry::IntegerRectangle2D(0,0,aPixelSize.Width(),aPixelSize.Height()) ) ); - - ::Bitmap aBitmap( aPixelSize, 24 ); // create 24bpp Bitmap - ::Bitmap aAlpha( aPixelSize, 8 ); // create 8bpp alpha Bitmap - + bool readBmp( sal_Int32 nWidth, + sal_Int32 nHeight, + const rendering::IntegerBitmapLayout& rLayout, + const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap, + ScopedBitmapWriteAccess& rWriteAcc, + ScopedBitmapWriteAccess& rAlphaAcc ) { - ScopedBitmapWriteAccess pWriteAccess( aBitmap.AcquireWriteAccess(), - aBitmap ); - ScopedBitmapWriteAccess pAlphaWriteAccess( aAlpha.AcquireWriteAccess(), - aAlpha ); + rendering::IntegerBitmapLayout aCurrLayout; + geometry::IntegerRectangle2D aRect; + uno::Sequence<sal_Int8> aPixelData; + uno::Sequence<rendering::RGBColor> aRGBColors; + uno::Sequence<rendering::ARGBColor> aARGBColors; - if( pWriteAccess.get() != NULL && - pAlphaWriteAccess.get() != NULL ) + for( aRect.Y1=0; aRect.Y1<nHeight; ++aRect.Y1 ) { - // for the time being, always read as BGRA - int nCurrPos(0); - for( int y=0; y<aPixelSize.Height(); ++y ) + aRect.X1 = 0; aRect.X2 = nWidth; aRect.Y2 = aRect.Y1+1; + try { - for( int x=0; x<aPixelSize.Width(); ++x ) - { - pWriteAccess->SetPixel( y, x, BitmapColor( data[ nCurrPos+2 ], - data[ nCurrPos+1 ], - data[ nCurrPos ] ) ); - nCurrPos += 3; + aPixelData = xInputBitmap->getData(aCurrLayout,aRect); + } + catch( rendering::VolatileContentDestroyedException& ) + { + // re-read bmp from the start + return false; + } + if( !(aCurrLayout == rLayout) ) + return false; // re-read bmp from the start - pAlphaWriteAccess->SetPixel( y, x, BitmapColor( 255 - data[ nCurrPos++ ] ) ); + if( rAlphaAcc.get() ) + { + // read ARGB color + aARGBColors = rLayout.ColorSpace->convertIntegerToARGB(aPixelData); + for( sal_Int32 x=0; x<nWidth; ++x ) + { + const rendering::ARGBColor& rColor=aARGBColors[x]; + rWriteAcc->SetPixel( aRect.Y1, x, + BitmapColor( toByteColor(rColor.Red), + toByteColor(rColor.Green), + toByteColor(rColor.Blue) )); + rAlphaAcc->SetPixel( aRect.Y1, x, + BitmapColor( 255 - toByteColor(rColor.Alpha) )); + } + } + else + { + // read RGB color + aRGBColors = rLayout.ColorSpace->convertIntegerToRGB(aPixelData); + for( sal_Int32 x=0; x<nWidth; ++x ) + { + const rendering::RGBColor& rColor=aRGBColors[x]; + rWriteAcc->SetPixel( aRect.Y1, x, + BitmapColor( toByteColor(rColor.Red), + toByteColor(rColor.Green), + toByteColor(rColor.Blue) )); } } } - } - - return ::BitmapEx( aBitmap, - AlphaMask( aAlpha ) ); - } - - //--------------------------------------------------------------------------------------- - - uno::Sequence< double > colorToDoubleSequence( const uno::Reference< rendering::XGraphicDevice >& /*xGraphicDevice*/, - const Color& rColor ) - { - // TODO: handle color space conversions, when defined on canvas/graphicDevice - uno::Sequence< double > aRet(4); - double* pRet = aRet.getArray(); - - pRet[0] = rColor.GetRed() / 255.0; - pRet[1] = rColor.GetGreen() / 255.0; - pRet[2] = rColor.GetBlue() / 255.0; - - // out notion of alpha is different from the rest of the world's - pRet[3] = 1.0 - rColor.GetTransparency() / 255.0; - return aRet; + return true; + } } - uno::Sequence< sal_Int8 > colorToIntSequence( const uno::Reference< rendering::XGraphicDevice >& /*xGraphicDevice*/, - const Color& rColor ) + ::BitmapEx VCL_DLLPUBLIC bitmapExFromXBitmap( const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap ) { - // TODO: handle color space conversions, when defined on canvas/graphicDevice - uno::Sequence< sal_Int8 > aRet(4); - sal_Int8* pRet = aRet.getArray(); - - pRet[0] = rColor.GetRed(); - pRet[1] = rColor.GetGreen(); - pRet[2] = rColor.GetBlue(); - - // out notion of alpha is different from the rest of the world's - pRet[3] = 255 - rColor.GetTransparency(); + RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::bitmapExFromXBitmap()" ); - return aRet; - } + if( !xInputBitmap.is() ) + return ::BitmapEx(); - Color sequenceToColor( const uno::Reference< rendering::XGraphicDevice >& /*xGraphicDevice*/, - const uno::Sequence< sal_Int8 >& rColor ) - { - OSL_ENSURE( rColor.getLength() > 2, "sequenceToColor: need at least three channels" ); + // tunnel directly for known implementation + // ---------------------------------------------------------------- + VclCanvasBitmap* pImplBitmap = dynamic_cast<VclCanvasBitmap*>(xInputBitmap.get()); + if( pImplBitmap ) + return pImplBitmap->getBitmapEx(); - // TODO: handle color space conversions, when defined on canvas/graphicDevice - Color aColor; + // retrieve data via UNO interface + // ---------------------------------------------------------------- - aColor.SetRed ( rColor[0] ); - aColor.SetGreen( rColor[1] ); - aColor.SetBlue ( rColor[2] ); + // volatile bitmaps are a bit more complicated to read + // from.. + uno::Reference<rendering::XVolatileBitmap> xVolatileBitmap( + xInputBitmap, uno::UNO_QUERY); - if( rColor.getLength() > 3 ) + // loop a few times, until successfully read (for XVolatileBitmap) + for( int i=0; i<10; ++i ) { - // out notion of alpha is different from the rest of the world's - aColor.SetTransparency( 255 - rColor[3] ); - } + sal_Int32 nDepth=0; + sal_Int32 nAlphaDepth=0; + const rendering::IntegerBitmapLayout aLayout( + xInputBitmap->getMemoryLayout()); - return aColor; - } + OSL_ENSURE(aLayout.ColorSpace.is(), + "Cannot convert image without color space!"); + if( !aLayout.ColorSpace.is() ) + return ::BitmapEx(); - Color sequenceToColor( const uno::Reference< rendering::XGraphicDevice >& /*xGraphicDevice*/, - const uno::Sequence< double >& rColor ) - { - OSL_ENSURE( rColor.getLength() > 2, "sequenceToColor: need at least three channels" ); + nDepth = aLayout.ColorSpace->getBitsPerPixel(); - // TODO: handle color space conversions, when defined on canvas/graphicDevice - Color aColor; + if( xInputBitmap->hasAlpha() ) + { + // determine alpha channel depth + const uno::Sequence<sal_Int8> aTags( + aLayout.ColorSpace->getComponentTags() ); + const uno::Sequence<sal_Int32> aDepths( + aLayout.ColorSpace->getComponentBitCounts() ); + const sal_Int8* pStart(aTags.getConstArray()); + const sal_Size nLen(aTags.getLength()); + const sal_Int8* pEnd(pStart+nLen); + + const std::ptrdiff_t nAlphaIndex = + std::find(pStart,pEnd, + rendering::ColorComponentTag::ALPHA) - pStart; + + if( nAlphaIndex < sal::static_int_cast<std::ptrdiff_t>(nLen) ) + { + nAlphaDepth = aLayout.ColorSpace->getComponentBitCounts()[nAlphaIndex] > 1 ? 8 : 1; + nDepth -= nAlphaDepth; + } + } - aColor.SetRed ( static_cast<UINT8>( 255*rColor[0] + .5 ) ); - aColor.SetGreen( static_cast<UINT8>( 255*rColor[1] + .5 ) ); - aColor.SetBlue ( static_cast<UINT8>( 255*rColor[2] + .5 ) ); + BitmapPalette aPalette; + if( aLayout.Palette.is() ) + { + uno::Reference< rendering::XColorSpace > xPaletteColorSpace( + aLayout.Palette->getColorSpace()); + ENSURE_OR_THROW(xPaletteColorSpace.is(), + "Palette without color space"); - if( rColor.getLength() > 3 ) - { - // out notion of alpha is different from the rest of the world's - aColor.SetTransparency( static_cast<UINT8>( 255 - 255*rColor[3] + .5 ) ); + const sal_Int32 nEntryCount( aLayout.Palette->getNumberOfEntries() ); + if( nEntryCount <= 256 ) + { + if( nEntryCount <= 2 ) + nDepth = 1; + else + nDepth = 8; + + const USHORT nPaletteEntries( + sal::static_int_cast<USHORT>( + std::min(sal_Int32(255), nEntryCount))); + + // copy palette entries + aPalette.SetEntryCount(nPaletteEntries); + uno::Reference<rendering::XBitmapPalette> xPalette( aLayout.Palette ); + uno::Reference<rendering::XColorSpace> xPalColorSpace( xPalette->getColorSpace() ); + + uno::Sequence<double> aPaletteEntry; + for( USHORT j=0; j<nPaletteEntries; ++j ) + { + if( !xPalette->getIndex(aPaletteEntry,j) && + nAlphaDepth == 0 ) + { + nAlphaDepth = 1; + } + uno::Sequence<rendering::RGBColor> aColors=xPalColorSpace->convertToRGB(aPaletteEntry); + ENSURE_OR_THROW(aColors.getLength() == 1, + "Palette returned more or less than one entry"); + const rendering::RGBColor& rColor=aColors[0]; + aPalette[j] = BitmapColor(toByteColor(rColor.Red), + toByteColor(rColor.Green), + toByteColor(rColor.Blue)); + } + } + } + + const ::Size aPixelSize( + sizeFromIntegerSize2D(xInputBitmap->getSize())); + + // normalize bitcount + nDepth = + ( nDepth <= 1 ) ? 1 : + ( nDepth <= 4 ) ? 4 : + ( nDepth <= 8 ) ? 8 : 24; + + ::Bitmap aBitmap( aPixelSize, + sal::static_int_cast<USHORT>(nDepth), + aLayout.Palette.is() ? &aPalette : NULL ); + ::Bitmap aAlpha; + if( nAlphaDepth ) + aAlpha = ::Bitmap( aPixelSize, + sal::static_int_cast<USHORT>(nAlphaDepth), + &::Bitmap::GetGreyPalette( + sal::static_int_cast<USHORT>(1L << nAlphaDepth)) ); + + { // limit scoped access + ScopedBitmapWriteAccess pWriteAccess( aBitmap.AcquireWriteAccess(), + aBitmap ); + ScopedBitmapWriteAccess pAlphaWriteAccess( aAlpha.AcquireWriteAccess(), + aAlpha ); + + ENSURE_OR_THROW(pWriteAccess.get() != NULL, + "Cannot get write access to bitmap"); + + const sal_Int32 nWidth(aPixelSize.Width()); + const sal_Int32 nHeight(aPixelSize.Height()); + + if( !readBmp(nWidth,nHeight,aLayout,xInputBitmap, + pWriteAccess,pAlphaWriteAccess) ) + continue; + } // limit scoped access + + if( nAlphaDepth ) + return ::BitmapEx( aBitmap, + AlphaMask( aAlpha ) ); + else + return ::BitmapEx( aBitmap ); } - return aColor; + // failed to read data 10 times - bail out + return ::BitmapEx(); } //--------------------------------------------------------------------------------------- @@ -519,6 +585,187 @@ namespace vcl rRectangle.X2, rRectangle.Y2 ); } + namespace + { + class StandardColorSpace : public cppu::WeakImplHelper1< com::sun::star::rendering::XColorSpace > + { + private: + uno::Sequence< sal_Int8 > m_aComponentTags; + + virtual ::sal_Int8 SAL_CALL getType( ) throw (uno::RuntimeException) + { + return rendering::ColorSpaceType::RGB; + } + virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( ) throw (uno::RuntimeException) + { + return m_aComponentTags; + } + virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) throw (uno::RuntimeException) + { + return rendering::RenderingIntent::PERCEPTUAL; + } + virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) throw (uno::RuntimeException) + { + return uno::Sequence< beans::PropertyValue >(); + } + virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor, + const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException, + uno::RuntimeException) + { + // TODO(P3): if we know anything about target + // colorspace, this can be greatly sped up + uno::Sequence<rendering::ARGBColor> aIntermediate( + convertToARGB(deviceColor)); + return targetColorSpace->convertFromARGB(aIntermediate); + } + virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) + { + const double* pIn( deviceColor.getConstArray() ); + const sal_Size nLen( deviceColor.getLength() ); + ENSURE_ARG_OR_THROW2(nLen%4==0, + "number of channels no multiple of 4", + static_cast<rendering::XColorSpace*>(this), 0); + + uno::Sequence< rendering::RGBColor > aRes(nLen/4); + rendering::RGBColor* pOut( aRes.getArray() ); + for( sal_Size i=0; i<nLen; i+=4 ) + { + *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]); + pIn += 4; + } + return aRes; + } + virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) + { + const double* pIn( deviceColor.getConstArray() ); + const sal_Size nLen( deviceColor.getLength() ); + ENSURE_ARG_OR_THROW2(nLen%4==0, + "number of channels no multiple of 4", + static_cast<rendering::XColorSpace*>(this), 0); + + uno::Sequence< rendering::ARGBColor > aRes(nLen/4); + rendering::ARGBColor* pOut( aRes.getArray() ); + for( sal_Size i=0; i<nLen; i+=4 ) + { + *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]); + pIn += 4; + } + return aRes; + } + virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) + { + const rendering::RGBColor* pIn( rgbColor.getConstArray() ); + const sal_Size nLen( rgbColor.getLength() ); + + uno::Sequence< double > aRes(nLen*4); + double* pColors=aRes.getArray(); + for( sal_Size i=0; i<nLen; ++i ) + { + *pColors++ = pIn->Red; + *pColors++ = pIn->Green; + *pColors++ = pIn->Blue; + *pColors++ = 1.0; + ++pIn; + } + return aRes; + } + virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) + { + const rendering::ARGBColor* pIn( rgbColor.getConstArray() ); + const sal_Size nLen( rgbColor.getLength() ); + + uno::Sequence< double > aRes(nLen*4); + double* pColors=aRes.getArray(); + for( sal_Size i=0; i<nLen; ++i ) + { + *pColors++ = pIn->Red; + *pColors++ = pIn->Green; + *pColors++ = pIn->Blue; + *pColors++ = pIn->Alpha; + ++pIn; + } + return aRes; + } + + public: + StandardColorSpace() : m_aComponentTags(4) + { + sal_Int8* pTags = m_aComponentTags.getArray(); + pTags[0] = rendering::ColorComponentTag::RGB_RED; + pTags[1] = rendering::ColorComponentTag::RGB_GREEN; + pTags[2] = rendering::ColorComponentTag::RGB_BLUE; + pTags[3] = rendering::ColorComponentTag::ALPHA; + } + }; + } + + uno::Reference<rendering::XColorSpace> VCL_DLLPUBLIC createStandardColorSpace() + { + return new StandardColorSpace(); + } + + //--------------------------------------------------------------------------------------- + + uno::Sequence< double > colorToStdColorSpaceSequence( const Color& rColor ) + { + uno::Sequence< double > aRet(4); + double* pRet = aRet.getArray(); + + pRet[0] = toDoubleColor(rColor.GetRed()); + pRet[1] = toDoubleColor(rColor.GetGreen()); + pRet[2] = toDoubleColor(rColor.GetBlue()); + + // VCL's notion of alpha is different from the rest of the world's + pRet[3] = 1.0 - toDoubleColor(rColor.GetTransparency()); + + return aRet; + } + + Color stdColorSpaceSequenceToColor( const uno::Sequence< double >& rColor ) + { + ENSURE_ARG_OR_THROW( rColor.getLength() == 4, + "color must have 4 channels" ); + + Color aColor; + + aColor.SetRed ( toByteColor(rColor[0]) ); + aColor.SetGreen( toByteColor(rColor[1]) ); + aColor.SetBlue ( toByteColor(rColor[2]) ); + // VCL's notion of alpha is different from the rest of the world's + aColor.SetTransparency( 255 - toByteColor(rColor[3]) ); + + return aColor; + } + + uno::Sequence< double > VCL_DLLPUBLIC colorToDoubleSequence( + const Color& rColor, + const uno::Reference< rendering::XColorSpace >& xColorSpace ) + { + uno::Sequence<rendering::ARGBColor> aSeq(1); + aSeq[0] = rendering::ARGBColor( + 1.0-toDoubleColor(rColor.GetTransparency()), + toDoubleColor(rColor.GetRed()), + toDoubleColor(rColor.GetGreen()), + toDoubleColor(rColor.GetBlue()) ); + + return xColorSpace->convertFromARGB(aSeq); + } + + Color VCL_DLLPUBLIC doubleSequenceToColor( + const uno::Sequence< double > rColor, + const uno::Reference< rendering::XColorSpace >& xColorSpace ) + { + const rendering::ARGBColor& rARGBColor( + xColorSpace->convertToARGB(rColor)[0]); + + return Color( 255-toByteColor(rARGBColor.Alpha), + toByteColor(rARGBColor.Red), + toByteColor(rARGBColor.Green), + toByteColor(rARGBColor.Blue) ); + } + + //--------------------------------------------------------------------------------------- + } // namespace vcltools } // namespace canvas |