1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_vcl.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include <rtl/logfile.hxx> 32*cdf0e10cSrcweir #include <cppuhelper/compbase1.hxx> 33*cdf0e10cSrcweir 34*cdf0e10cSrcweir #include <com/sun/star/geometry/RealSize2D.hpp> 35*cdf0e10cSrcweir #include <com/sun/star/geometry/RealPoint2D.hpp> 36*cdf0e10cSrcweir #include <com/sun/star/geometry/RealRectangle2D.hpp> 37*cdf0e10cSrcweir #include <com/sun/star/geometry/IntegerSize2D.hpp> 38*cdf0e10cSrcweir #include <com/sun/star/geometry/IntegerPoint2D.hpp> 39*cdf0e10cSrcweir #include <com/sun/star/geometry/IntegerRectangle2D.hpp> 40*cdf0e10cSrcweir #include <com/sun/star/geometry/RealBezierSegment2D.hpp> 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir #include <com/sun/star/rendering/ColorSpaceType.hpp> 43*cdf0e10cSrcweir #include <com/sun/star/rendering/RenderingIntent.hpp> 44*cdf0e10cSrcweir #include <com/sun/star/rendering/XGraphicDevice.hpp> 45*cdf0e10cSrcweir #include <com/sun/star/rendering/XBitmap.hpp> 46*cdf0e10cSrcweir #include <com/sun/star/rendering/XPolyPolygon2D.hpp> 47*cdf0e10cSrcweir #include <com/sun/star/rendering/IntegerBitmapLayout.hpp> 48*cdf0e10cSrcweir #include <com/sun/star/rendering/XIntegerBitmap.hpp> 49*cdf0e10cSrcweir #include <com/sun/star/rendering/ColorComponentTag.hpp> 50*cdf0e10cSrcweir 51*cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx> 52*cdf0e10cSrcweir #include <basegfx/vector/b2dsize.hxx> 53*cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx> 54*cdf0e10cSrcweir #include <basegfx/range/b2drectangle.hxx> 55*cdf0e10cSrcweir #include <basegfx/vector/b2isize.hxx> 56*cdf0e10cSrcweir #include <basegfx/point/b2ipoint.hxx> 57*cdf0e10cSrcweir #include <basegfx/range/b2irectangle.hxx> 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir // #i79917# 60*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx> 61*cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx> 62*cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygon.hxx> 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir #include <tools/poly.hxx> 65*cdf0e10cSrcweir #include <tools/diagnose_ex.h> 66*cdf0e10cSrcweir #include <rtl/uuid.h> 67*cdf0e10cSrcweir 68*cdf0e10cSrcweir #include <vcl/salbtype.hxx> 69*cdf0e10cSrcweir #include <vcl/bmpacc.hxx> 70*cdf0e10cSrcweir #include <vcl/bitmapex.hxx> 71*cdf0e10cSrcweir 72*cdf0e10cSrcweir #include <canvasbitmap.hxx> 73*cdf0e10cSrcweir #include <vcl/canvastools.hxx> 74*cdf0e10cSrcweir #include <hash_map> 75*cdf0e10cSrcweir 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir using namespace ::com::sun::star; 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir namespace vcl 80*cdf0e10cSrcweir { 81*cdf0e10cSrcweir namespace unotools 82*cdf0e10cSrcweir { 83*cdf0e10cSrcweir // #i79917# removed helpers bezierSequenceFromPolygon and 84*cdf0e10cSrcweir // pointSequenceFromPolygon here 85*cdf0e10cSrcweir // Also all helpers using tools Polygon and PolyPolygon will get mapped to the 86*cdf0e10cSrcweir // B2DPolygon helpers for these cases, see comments with the same TaskID below. 87*cdf0e10cSrcweir // TODO: Remove those wrapped methods 88*cdf0e10cSrcweir 89*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 90*cdf0e10cSrcweir 91*cdf0e10cSrcweir uno::Reference< rendering::XPolyPolygon2D > xPolyPolygonFromPolygon( const uno::Reference< rendering::XGraphicDevice >& xGraphicDevice, 92*cdf0e10cSrcweir const ::Polygon& inputPolygon ) 93*cdf0e10cSrcweir { 94*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::xPolyPolygonFromPolygon()" ); 95*cdf0e10cSrcweir 96*cdf0e10cSrcweir // #i79917# map to basegfx 97*cdf0e10cSrcweir const basegfx::B2DPolygon aB2DPolygon(inputPolygon.getB2DPolygon()); 98*cdf0e10cSrcweir return basegfx::unotools::xPolyPolygonFromB2DPolygon(xGraphicDevice, aB2DPolygon); 99*cdf0e10cSrcweir } 100*cdf0e10cSrcweir 101*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 102*cdf0e10cSrcweir 103*cdf0e10cSrcweir uno::Reference< rendering::XPolyPolygon2D > xPolyPolygonFromPolyPolygon( const uno::Reference< rendering::XGraphicDevice >& xGraphicDevice, 104*cdf0e10cSrcweir const ::PolyPolygon& inputPolyPolygon ) 105*cdf0e10cSrcweir { 106*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::xPolyPolygonFromPolyPolygon()" ); 107*cdf0e10cSrcweir 108*cdf0e10cSrcweir // #i79917# map to basegfx 109*cdf0e10cSrcweir const basegfx::B2DPolyPolygon aB2DPolyPolygon(inputPolyPolygon.getB2DPolyPolygon()); 110*cdf0e10cSrcweir return basegfx::unotools::xPolyPolygonFromB2DPolyPolygon(xGraphicDevice, aB2DPolyPolygon); 111*cdf0e10cSrcweir } 112*cdf0e10cSrcweir 113*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 114*cdf0e10cSrcweir 115*cdf0e10cSrcweir ::Polygon polygonFromPoint2DSequence( const uno::Sequence< geometry::RealPoint2D >& points ) 116*cdf0e10cSrcweir { 117*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::polygonFromPoint2DSequence()" ); 118*cdf0e10cSrcweir 119*cdf0e10cSrcweir const sal_uInt16 nCurrSize( sal::static_int_cast<sal_uInt16>(points.getLength()) ); 120*cdf0e10cSrcweir 121*cdf0e10cSrcweir ::Polygon aPoly( nCurrSize ); 122*cdf0e10cSrcweir 123*cdf0e10cSrcweir sal_uInt16 nCurrPoint; 124*cdf0e10cSrcweir for( nCurrPoint=0; nCurrPoint<nCurrSize; ++nCurrPoint ) 125*cdf0e10cSrcweir aPoly[nCurrPoint] = pointFromRealPoint2D( points[nCurrPoint] ); 126*cdf0e10cSrcweir 127*cdf0e10cSrcweir return aPoly; 128*cdf0e10cSrcweir } 129*cdf0e10cSrcweir 130*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 131*cdf0e10cSrcweir 132*cdf0e10cSrcweir ::PolyPolygon polyPolygonFromPoint2DSequenceSequence( const uno::Sequence< uno::Sequence< geometry::RealPoint2D > >& points ) 133*cdf0e10cSrcweir { 134*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::polyPolygonFromPoint2DSequenceSequence()" ); 135*cdf0e10cSrcweir 136*cdf0e10cSrcweir ::PolyPolygon aRes; 137*cdf0e10cSrcweir 138*cdf0e10cSrcweir int nCurrPoly; 139*cdf0e10cSrcweir for( nCurrPoly=0; nCurrPoly<points.getLength(); ++nCurrPoly ) 140*cdf0e10cSrcweir { 141*cdf0e10cSrcweir aRes.Insert( polygonFromPoint2DSequence( points[nCurrPoly] ) ); 142*cdf0e10cSrcweir } 143*cdf0e10cSrcweir 144*cdf0e10cSrcweir return aRes; 145*cdf0e10cSrcweir } 146*cdf0e10cSrcweir 147*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir ::Polygon polygonFromBezier2DSequence( const uno::Sequence< geometry::RealBezierSegment2D >& curves ) 150*cdf0e10cSrcweir { 151*cdf0e10cSrcweir // #i79917# map to basegfx 152*cdf0e10cSrcweir const basegfx::B2DPolygon aB2DPolygon(basegfx::unotools::polygonFromBezier2DSequence(curves)); 153*cdf0e10cSrcweir return ::Polygon(aB2DPolygon); 154*cdf0e10cSrcweir } 155*cdf0e10cSrcweir 156*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 157*cdf0e10cSrcweir 158*cdf0e10cSrcweir ::PolyPolygon polyPolygonFromBezier2DSequenceSequence( const uno::Sequence< uno::Sequence< geometry::RealBezierSegment2D > >& curves ) 159*cdf0e10cSrcweir { 160*cdf0e10cSrcweir // #i79917# map to basegfx 161*cdf0e10cSrcweir const basegfx::B2DPolyPolygon aB2DPolyPolygon(basegfx::unotools::polyPolygonFromBezier2DSequenceSequence(curves)); 162*cdf0e10cSrcweir return ::PolyPolygon(aB2DPolyPolygon); 163*cdf0e10cSrcweir } 164*cdf0e10cSrcweir 165*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir uno::Reference< rendering::XBitmap > xBitmapFromBitmap( const uno::Reference< rendering::XGraphicDevice >& /*xGraphicDevice*/, 168*cdf0e10cSrcweir const ::Bitmap& inputBitmap ) 169*cdf0e10cSrcweir { 170*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::xBitmapFromBitmap()" ); 171*cdf0e10cSrcweir 172*cdf0e10cSrcweir return new vcl::unotools::VclCanvasBitmap( BitmapEx( inputBitmap ) ); 173*cdf0e10cSrcweir } 174*cdf0e10cSrcweir 175*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir uno::Reference< rendering::XBitmap > xBitmapFromBitmapEx( const uno::Reference< rendering::XGraphicDevice >& /*xGraphicDevice*/, 178*cdf0e10cSrcweir const ::BitmapEx& inputBitmap ) 179*cdf0e10cSrcweir { 180*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::xBitmapFromBitmapEx()" ); 181*cdf0e10cSrcweir 182*cdf0e10cSrcweir return new vcl::unotools::VclCanvasBitmap( inputBitmap ); 183*cdf0e10cSrcweir } 184*cdf0e10cSrcweir 185*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir const uno::Sequence< sal_Int8 > getTunnelIdentifier( TunnelIdentifierType eType ) 188*cdf0e10cSrcweir { 189*cdf0e10cSrcweir static std::hash_map< int, uno::Sequence< sal_Int8 > > aIds; 190*cdf0e10cSrcweir std::hash_map< int, uno::Sequence< sal_Int8 > >::iterator it = 191*cdf0e10cSrcweir aIds.find( eType ); 192*cdf0e10cSrcweir if( it == aIds.end() ) 193*cdf0e10cSrcweir { 194*cdf0e10cSrcweir uno::Sequence< sal_Int8 > aNewId( 16 ); 195*cdf0e10cSrcweir rtl_createUuid( (sal_uInt8*)aNewId.getArray(), NULL, sal_True ); 196*cdf0e10cSrcweir aIds[ eType ] = aNewId; 197*cdf0e10cSrcweir it = aIds.find( eType ); 198*cdf0e10cSrcweir } 199*cdf0e10cSrcweir return it->second; 200*cdf0e10cSrcweir } 201*cdf0e10cSrcweir 202*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 203*cdf0e10cSrcweir 204*cdf0e10cSrcweir namespace 205*cdf0e10cSrcweir { 206*cdf0e10cSrcweir inline bool operator==( const rendering::IntegerBitmapLayout& rLHS, 207*cdf0e10cSrcweir const rendering::IntegerBitmapLayout& rRHS ) 208*cdf0e10cSrcweir { 209*cdf0e10cSrcweir return 210*cdf0e10cSrcweir rLHS.ScanLineBytes == rRHS.ScanLineBytes && 211*cdf0e10cSrcweir rLHS.ScanLineStride == rRHS.ScanLineStride && 212*cdf0e10cSrcweir rLHS.PlaneStride == rRHS.PlaneStride && 213*cdf0e10cSrcweir rLHS.ColorSpace == rRHS.ColorSpace && 214*cdf0e10cSrcweir rLHS.Palette == rRHS.Palette && 215*cdf0e10cSrcweir rLHS.IsMsbFirst == rRHS.IsMsbFirst; 216*cdf0e10cSrcweir } 217*cdf0e10cSrcweir 218*cdf0e10cSrcweir bool readBmp( sal_Int32 nWidth, 219*cdf0e10cSrcweir sal_Int32 nHeight, 220*cdf0e10cSrcweir const rendering::IntegerBitmapLayout& rLayout, 221*cdf0e10cSrcweir const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap, 222*cdf0e10cSrcweir ScopedBitmapWriteAccess& rWriteAcc, 223*cdf0e10cSrcweir ScopedBitmapWriteAccess& rAlphaAcc ) 224*cdf0e10cSrcweir { 225*cdf0e10cSrcweir rendering::IntegerBitmapLayout aCurrLayout; 226*cdf0e10cSrcweir geometry::IntegerRectangle2D aRect; 227*cdf0e10cSrcweir uno::Sequence<sal_Int8> aPixelData; 228*cdf0e10cSrcweir uno::Sequence<rendering::RGBColor> aRGBColors; 229*cdf0e10cSrcweir uno::Sequence<rendering::ARGBColor> aARGBColors; 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir for( aRect.Y1=0; aRect.Y1<nHeight; ++aRect.Y1 ) 232*cdf0e10cSrcweir { 233*cdf0e10cSrcweir aRect.X1 = 0; aRect.X2 = nWidth; aRect.Y2 = aRect.Y1+1; 234*cdf0e10cSrcweir try 235*cdf0e10cSrcweir { 236*cdf0e10cSrcweir aPixelData = xInputBitmap->getData(aCurrLayout,aRect); 237*cdf0e10cSrcweir } 238*cdf0e10cSrcweir catch( rendering::VolatileContentDestroyedException& ) 239*cdf0e10cSrcweir { 240*cdf0e10cSrcweir // re-read bmp from the start 241*cdf0e10cSrcweir return false; 242*cdf0e10cSrcweir } 243*cdf0e10cSrcweir if( !(aCurrLayout == rLayout) ) 244*cdf0e10cSrcweir return false; // re-read bmp from the start 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir if( rAlphaAcc.get() ) 247*cdf0e10cSrcweir { 248*cdf0e10cSrcweir // read ARGB color 249*cdf0e10cSrcweir aARGBColors = rLayout.ColorSpace->convertIntegerToARGB(aPixelData); 250*cdf0e10cSrcweir 251*cdf0e10cSrcweir if( rWriteAcc->HasPalette() ) 252*cdf0e10cSrcweir { 253*cdf0e10cSrcweir for( sal_Int32 x=0; x<nWidth; ++x ) 254*cdf0e10cSrcweir { 255*cdf0e10cSrcweir const rendering::ARGBColor& rColor=aARGBColors[x]; 256*cdf0e10cSrcweir rWriteAcc->SetPixel( aRect.Y1, x, 257*cdf0e10cSrcweir (sal_uInt8)rWriteAcc->GetBestPaletteIndex( 258*cdf0e10cSrcweir BitmapColor( toByteColor(rColor.Red), 259*cdf0e10cSrcweir toByteColor(rColor.Green), 260*cdf0e10cSrcweir toByteColor(rColor.Blue))) ); 261*cdf0e10cSrcweir rAlphaAcc->SetPixel( aRect.Y1, x, 262*cdf0e10cSrcweir BitmapColor( 255 - toByteColor(rColor.Alpha) )); 263*cdf0e10cSrcweir } 264*cdf0e10cSrcweir } 265*cdf0e10cSrcweir else 266*cdf0e10cSrcweir { 267*cdf0e10cSrcweir for( sal_Int32 x=0; x<nWidth; ++x ) 268*cdf0e10cSrcweir { 269*cdf0e10cSrcweir const rendering::ARGBColor& rColor=aARGBColors[x]; 270*cdf0e10cSrcweir rWriteAcc->SetPixel( aRect.Y1, x, 271*cdf0e10cSrcweir BitmapColor( toByteColor(rColor.Red), 272*cdf0e10cSrcweir toByteColor(rColor.Green), 273*cdf0e10cSrcweir toByteColor(rColor.Blue) )); 274*cdf0e10cSrcweir rAlphaAcc->SetPixel( aRect.Y1, x, 275*cdf0e10cSrcweir BitmapColor( 255 - toByteColor(rColor.Alpha) )); 276*cdf0e10cSrcweir } 277*cdf0e10cSrcweir } 278*cdf0e10cSrcweir } 279*cdf0e10cSrcweir else 280*cdf0e10cSrcweir { 281*cdf0e10cSrcweir // read RGB color 282*cdf0e10cSrcweir aRGBColors = rLayout.ColorSpace->convertIntegerToRGB(aPixelData); 283*cdf0e10cSrcweir if( rWriteAcc->HasPalette() ) 284*cdf0e10cSrcweir { 285*cdf0e10cSrcweir for( sal_Int32 x=0; x<nWidth; ++x ) 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir const rendering::RGBColor& rColor=aRGBColors[x]; 288*cdf0e10cSrcweir rWriteAcc->SetPixel( aRect.Y1, x, 289*cdf0e10cSrcweir (sal_uInt8)rWriteAcc->GetBestPaletteIndex( 290*cdf0e10cSrcweir BitmapColor( toByteColor(rColor.Red), 291*cdf0e10cSrcweir toByteColor(rColor.Green), 292*cdf0e10cSrcweir toByteColor(rColor.Blue))) ); 293*cdf0e10cSrcweir } 294*cdf0e10cSrcweir } 295*cdf0e10cSrcweir else 296*cdf0e10cSrcweir { 297*cdf0e10cSrcweir for( sal_Int32 x=0; x<nWidth; ++x ) 298*cdf0e10cSrcweir { 299*cdf0e10cSrcweir const rendering::RGBColor& rColor=aRGBColors[x]; 300*cdf0e10cSrcweir rWriteAcc->SetPixel( aRect.Y1, x, 301*cdf0e10cSrcweir BitmapColor( toByteColor(rColor.Red), 302*cdf0e10cSrcweir toByteColor(rColor.Green), 303*cdf0e10cSrcweir toByteColor(rColor.Blue) )); 304*cdf0e10cSrcweir } 305*cdf0e10cSrcweir } 306*cdf0e10cSrcweir } 307*cdf0e10cSrcweir } 308*cdf0e10cSrcweir 309*cdf0e10cSrcweir return true; 310*cdf0e10cSrcweir } 311*cdf0e10cSrcweir } 312*cdf0e10cSrcweir 313*cdf0e10cSrcweir ::BitmapEx VCL_DLLPUBLIC bitmapExFromXBitmap( const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap ) 314*cdf0e10cSrcweir { 315*cdf0e10cSrcweir RTL_LOGFILE_CONTEXT( aLog, "::vcl::unotools::bitmapExFromXBitmap()" ); 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir if( !xInputBitmap.is() ) 318*cdf0e10cSrcweir return ::BitmapEx(); 319*cdf0e10cSrcweir 320*cdf0e10cSrcweir // tunnel directly for known implementation 321*cdf0e10cSrcweir // ---------------------------------------------------------------- 322*cdf0e10cSrcweir VclCanvasBitmap* pImplBitmap = dynamic_cast<VclCanvasBitmap*>(xInputBitmap.get()); 323*cdf0e10cSrcweir if( pImplBitmap ) 324*cdf0e10cSrcweir return pImplBitmap->getBitmapEx(); 325*cdf0e10cSrcweir 326*cdf0e10cSrcweir // retrieve data via UNO interface 327*cdf0e10cSrcweir // ---------------------------------------------------------------- 328*cdf0e10cSrcweir 329*cdf0e10cSrcweir // volatile bitmaps are a bit more complicated to read 330*cdf0e10cSrcweir // from.. 331*cdf0e10cSrcweir uno::Reference<rendering::XVolatileBitmap> xVolatileBitmap( 332*cdf0e10cSrcweir xInputBitmap, uno::UNO_QUERY); 333*cdf0e10cSrcweir 334*cdf0e10cSrcweir // loop a few times, until successfully read (for XVolatileBitmap) 335*cdf0e10cSrcweir for( int i=0; i<10; ++i ) 336*cdf0e10cSrcweir { 337*cdf0e10cSrcweir sal_Int32 nDepth=0; 338*cdf0e10cSrcweir sal_Int32 nAlphaDepth=0; 339*cdf0e10cSrcweir const rendering::IntegerBitmapLayout aLayout( 340*cdf0e10cSrcweir xInputBitmap->getMemoryLayout()); 341*cdf0e10cSrcweir 342*cdf0e10cSrcweir OSL_ENSURE(aLayout.ColorSpace.is(), 343*cdf0e10cSrcweir "Cannot convert image without color space!"); 344*cdf0e10cSrcweir if( !aLayout.ColorSpace.is() ) 345*cdf0e10cSrcweir return ::BitmapEx(); 346*cdf0e10cSrcweir 347*cdf0e10cSrcweir nDepth = aLayout.ColorSpace->getBitsPerPixel(); 348*cdf0e10cSrcweir 349*cdf0e10cSrcweir if( xInputBitmap->hasAlpha() ) 350*cdf0e10cSrcweir { 351*cdf0e10cSrcweir // determine alpha channel depth 352*cdf0e10cSrcweir const uno::Sequence<sal_Int8> aTags( 353*cdf0e10cSrcweir aLayout.ColorSpace->getComponentTags() ); 354*cdf0e10cSrcweir const uno::Sequence<sal_Int32> aDepths( 355*cdf0e10cSrcweir aLayout.ColorSpace->getComponentBitCounts() ); 356*cdf0e10cSrcweir const sal_Int8* pStart(aTags.getConstArray()); 357*cdf0e10cSrcweir const sal_Size nLen(aTags.getLength()); 358*cdf0e10cSrcweir const sal_Int8* pEnd(pStart+nLen); 359*cdf0e10cSrcweir 360*cdf0e10cSrcweir const std::ptrdiff_t nAlphaIndex = 361*cdf0e10cSrcweir std::find(pStart,pEnd, 362*cdf0e10cSrcweir rendering::ColorComponentTag::ALPHA) - pStart; 363*cdf0e10cSrcweir 364*cdf0e10cSrcweir if( nAlphaIndex < sal::static_int_cast<std::ptrdiff_t>(nLen) ) 365*cdf0e10cSrcweir { 366*cdf0e10cSrcweir nAlphaDepth = aLayout.ColorSpace->getComponentBitCounts()[nAlphaIndex] > 1 ? 8 : 1; 367*cdf0e10cSrcweir nDepth -= nAlphaDepth; 368*cdf0e10cSrcweir } 369*cdf0e10cSrcweir } 370*cdf0e10cSrcweir 371*cdf0e10cSrcweir BitmapPalette aPalette; 372*cdf0e10cSrcweir if( aLayout.Palette.is() ) 373*cdf0e10cSrcweir { 374*cdf0e10cSrcweir uno::Reference< rendering::XColorSpace > xPaletteColorSpace( 375*cdf0e10cSrcweir aLayout.Palette->getColorSpace()); 376*cdf0e10cSrcweir ENSURE_OR_THROW(xPaletteColorSpace.is(), 377*cdf0e10cSrcweir "Palette without color space"); 378*cdf0e10cSrcweir 379*cdf0e10cSrcweir const sal_Int32 nEntryCount( aLayout.Palette->getNumberOfEntries() ); 380*cdf0e10cSrcweir if( nEntryCount <= 256 ) 381*cdf0e10cSrcweir { 382*cdf0e10cSrcweir if( nEntryCount <= 2 ) 383*cdf0e10cSrcweir nDepth = 1; 384*cdf0e10cSrcweir else 385*cdf0e10cSrcweir nDepth = 8; 386*cdf0e10cSrcweir 387*cdf0e10cSrcweir const sal_uInt16 nPaletteEntries( 388*cdf0e10cSrcweir sal::static_int_cast<sal_uInt16>( 389*cdf0e10cSrcweir std::min(sal_Int32(255), nEntryCount))); 390*cdf0e10cSrcweir 391*cdf0e10cSrcweir // copy palette entries 392*cdf0e10cSrcweir aPalette.SetEntryCount(nPaletteEntries); 393*cdf0e10cSrcweir uno::Reference<rendering::XBitmapPalette> xPalette( aLayout.Palette ); 394*cdf0e10cSrcweir uno::Reference<rendering::XColorSpace> xPalColorSpace( xPalette->getColorSpace() ); 395*cdf0e10cSrcweir 396*cdf0e10cSrcweir uno::Sequence<double> aPaletteEntry; 397*cdf0e10cSrcweir for( sal_uInt16 j=0; j<nPaletteEntries; ++j ) 398*cdf0e10cSrcweir { 399*cdf0e10cSrcweir if( !xPalette->getIndex(aPaletteEntry,j) && 400*cdf0e10cSrcweir nAlphaDepth == 0 ) 401*cdf0e10cSrcweir { 402*cdf0e10cSrcweir nAlphaDepth = 1; 403*cdf0e10cSrcweir } 404*cdf0e10cSrcweir uno::Sequence<rendering::RGBColor> aColors=xPalColorSpace->convertToRGB(aPaletteEntry); 405*cdf0e10cSrcweir ENSURE_OR_THROW(aColors.getLength() == 1, 406*cdf0e10cSrcweir "Palette returned more or less than one entry"); 407*cdf0e10cSrcweir const rendering::RGBColor& rColor=aColors[0]; 408*cdf0e10cSrcweir aPalette[j] = BitmapColor(toByteColor(rColor.Red), 409*cdf0e10cSrcweir toByteColor(rColor.Green), 410*cdf0e10cSrcweir toByteColor(rColor.Blue)); 411*cdf0e10cSrcweir } 412*cdf0e10cSrcweir } 413*cdf0e10cSrcweir } 414*cdf0e10cSrcweir 415*cdf0e10cSrcweir const ::Size aPixelSize( 416*cdf0e10cSrcweir sizeFromIntegerSize2D(xInputBitmap->getSize())); 417*cdf0e10cSrcweir 418*cdf0e10cSrcweir // normalize bitcount 419*cdf0e10cSrcweir nDepth = 420*cdf0e10cSrcweir ( nDepth <= 1 ) ? 1 : 421*cdf0e10cSrcweir ( nDepth <= 4 ) ? 4 : 422*cdf0e10cSrcweir ( nDepth <= 8 ) ? 8 : 24; 423*cdf0e10cSrcweir 424*cdf0e10cSrcweir ::Bitmap aBitmap( aPixelSize, 425*cdf0e10cSrcweir sal::static_int_cast<sal_uInt16>(nDepth), 426*cdf0e10cSrcweir aLayout.Palette.is() ? &aPalette : NULL ); 427*cdf0e10cSrcweir ::Bitmap aAlpha; 428*cdf0e10cSrcweir if( nAlphaDepth ) 429*cdf0e10cSrcweir aAlpha = ::Bitmap( aPixelSize, 430*cdf0e10cSrcweir sal::static_int_cast<sal_uInt16>(nAlphaDepth), 431*cdf0e10cSrcweir &::Bitmap::GetGreyPalette( 432*cdf0e10cSrcweir sal::static_int_cast<sal_uInt16>(1L << nAlphaDepth)) ); 433*cdf0e10cSrcweir 434*cdf0e10cSrcweir { // limit scoped access 435*cdf0e10cSrcweir ScopedBitmapWriteAccess pWriteAccess( aBitmap.AcquireWriteAccess(), 436*cdf0e10cSrcweir aBitmap ); 437*cdf0e10cSrcweir ScopedBitmapWriteAccess pAlphaWriteAccess( nAlphaDepth ? aAlpha.AcquireWriteAccess() : NULL, 438*cdf0e10cSrcweir aAlpha ); 439*cdf0e10cSrcweir 440*cdf0e10cSrcweir ENSURE_OR_THROW(pWriteAccess.get() != NULL, 441*cdf0e10cSrcweir "Cannot get write access to bitmap"); 442*cdf0e10cSrcweir 443*cdf0e10cSrcweir const sal_Int32 nWidth(aPixelSize.Width()); 444*cdf0e10cSrcweir const sal_Int32 nHeight(aPixelSize.Height()); 445*cdf0e10cSrcweir 446*cdf0e10cSrcweir if( !readBmp(nWidth,nHeight,aLayout,xInputBitmap, 447*cdf0e10cSrcweir pWriteAccess,pAlphaWriteAccess) ) 448*cdf0e10cSrcweir continue; 449*cdf0e10cSrcweir } // limit scoped access 450*cdf0e10cSrcweir 451*cdf0e10cSrcweir if( nAlphaDepth ) 452*cdf0e10cSrcweir return ::BitmapEx( aBitmap, 453*cdf0e10cSrcweir AlphaMask( aAlpha ) ); 454*cdf0e10cSrcweir else 455*cdf0e10cSrcweir return ::BitmapEx( aBitmap ); 456*cdf0e10cSrcweir } 457*cdf0e10cSrcweir 458*cdf0e10cSrcweir // failed to read data 10 times - bail out 459*cdf0e10cSrcweir return ::BitmapEx(); 460*cdf0e10cSrcweir } 461*cdf0e10cSrcweir 462*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 463*cdf0e10cSrcweir 464*cdf0e10cSrcweir geometry::RealSize2D size2DFromSize( const Size& rSize ) 465*cdf0e10cSrcweir { 466*cdf0e10cSrcweir return geometry::RealSize2D( rSize.Width(), 467*cdf0e10cSrcweir rSize.Height() ); 468*cdf0e10cSrcweir } 469*cdf0e10cSrcweir 470*cdf0e10cSrcweir geometry::RealPoint2D point2DFromPoint( const Point& rPoint ) 471*cdf0e10cSrcweir { 472*cdf0e10cSrcweir return geometry::RealPoint2D( rPoint.X(), 473*cdf0e10cSrcweir rPoint.Y() ); 474*cdf0e10cSrcweir } 475*cdf0e10cSrcweir 476*cdf0e10cSrcweir geometry::RealRectangle2D rectangle2DFromRectangle( const Rectangle& rRect ) 477*cdf0e10cSrcweir { 478*cdf0e10cSrcweir return geometry::RealRectangle2D( rRect.Left(), rRect.Top(), 479*cdf0e10cSrcweir rRect.Right(), rRect.Bottom() ); 480*cdf0e10cSrcweir } 481*cdf0e10cSrcweir 482*cdf0e10cSrcweir Size sizeFromRealSize2D( const geometry::RealSize2D& rSize ) 483*cdf0e10cSrcweir { 484*cdf0e10cSrcweir return Size( static_cast<long>(rSize.Width + .5), 485*cdf0e10cSrcweir static_cast<long>(rSize.Height + .5) ); 486*cdf0e10cSrcweir } 487*cdf0e10cSrcweir 488*cdf0e10cSrcweir Point pointFromRealPoint2D( const geometry::RealPoint2D& rPoint ) 489*cdf0e10cSrcweir { 490*cdf0e10cSrcweir return Point( static_cast<long>(rPoint.X + .5), 491*cdf0e10cSrcweir static_cast<long>(rPoint.Y + .5) ); 492*cdf0e10cSrcweir } 493*cdf0e10cSrcweir 494*cdf0e10cSrcweir Rectangle rectangleFromRealRectangle2D( const geometry::RealRectangle2D& rRect ) 495*cdf0e10cSrcweir { 496*cdf0e10cSrcweir return Rectangle( static_cast<long>(rRect.X1 + .5), 497*cdf0e10cSrcweir static_cast<long>(rRect.Y1 + .5), 498*cdf0e10cSrcweir static_cast<long>(rRect.X2 + .5), 499*cdf0e10cSrcweir static_cast<long>(rRect.Y2 + .5) ); 500*cdf0e10cSrcweir } 501*cdf0e10cSrcweir 502*cdf0e10cSrcweir ::Size sizeFromB2DSize( const ::basegfx::B2DVector& rVec ) 503*cdf0e10cSrcweir { 504*cdf0e10cSrcweir return ::Size( FRound( rVec.getX() ), 505*cdf0e10cSrcweir FRound( rVec.getY() ) ); 506*cdf0e10cSrcweir } 507*cdf0e10cSrcweir 508*cdf0e10cSrcweir ::Point pointFromB2DPoint( const ::basegfx::B2DPoint& rPoint ) 509*cdf0e10cSrcweir { 510*cdf0e10cSrcweir return ::Point( FRound( rPoint.getX() ), 511*cdf0e10cSrcweir FRound( rPoint.getY() ) ); 512*cdf0e10cSrcweir } 513*cdf0e10cSrcweir 514*cdf0e10cSrcweir ::Rectangle rectangleFromB2DRectangle( const ::basegfx::B2DRange& rRect ) 515*cdf0e10cSrcweir { 516*cdf0e10cSrcweir return ::Rectangle( FRound( rRect.getMinX() ), 517*cdf0e10cSrcweir FRound( rRect.getMinY() ), 518*cdf0e10cSrcweir FRound( rRect.getMaxX() ), 519*cdf0e10cSrcweir FRound( rRect.getMaxY() ) ); 520*cdf0e10cSrcweir } 521*cdf0e10cSrcweir 522*cdf0e10cSrcweir Size sizeFromB2ISize( const ::basegfx::B2IVector& rVec ) 523*cdf0e10cSrcweir { 524*cdf0e10cSrcweir return ::Size( rVec.getX(), 525*cdf0e10cSrcweir rVec.getY() ); 526*cdf0e10cSrcweir } 527*cdf0e10cSrcweir 528*cdf0e10cSrcweir Point pointFromB2IPoint( const ::basegfx::B2IPoint& rPoint ) 529*cdf0e10cSrcweir { 530*cdf0e10cSrcweir return ::Point( rPoint.getX(), 531*cdf0e10cSrcweir rPoint.getY() ); 532*cdf0e10cSrcweir } 533*cdf0e10cSrcweir 534*cdf0e10cSrcweir Rectangle rectangleFromB2IRectangle( const ::basegfx::B2IRange& rRect ) 535*cdf0e10cSrcweir { 536*cdf0e10cSrcweir return ::Rectangle( rRect.getMinX(), 537*cdf0e10cSrcweir rRect.getMinY(), 538*cdf0e10cSrcweir rRect.getMaxX(), 539*cdf0e10cSrcweir rRect.getMaxY() ); 540*cdf0e10cSrcweir } 541*cdf0e10cSrcweir 542*cdf0e10cSrcweir ::basegfx::B2DVector b2DSizeFromSize( const ::Size& rSize ) 543*cdf0e10cSrcweir { 544*cdf0e10cSrcweir return ::basegfx::B2DVector( rSize.Width(), 545*cdf0e10cSrcweir rSize.Height() ); 546*cdf0e10cSrcweir } 547*cdf0e10cSrcweir 548*cdf0e10cSrcweir ::basegfx::B2DPoint b2DPointFromPoint( const ::Point& rPoint ) 549*cdf0e10cSrcweir { 550*cdf0e10cSrcweir return ::basegfx::B2DPoint( rPoint.X(), 551*cdf0e10cSrcweir rPoint.Y() ); 552*cdf0e10cSrcweir } 553*cdf0e10cSrcweir 554*cdf0e10cSrcweir ::basegfx::B2DRange b2DRectangleFromRectangle( const ::Rectangle& rRect ) 555*cdf0e10cSrcweir { 556*cdf0e10cSrcweir return ::basegfx::B2DRange( rRect.Left(), 557*cdf0e10cSrcweir rRect.Top(), 558*cdf0e10cSrcweir rRect.Right(), 559*cdf0e10cSrcweir rRect.Bottom() ); 560*cdf0e10cSrcweir } 561*cdf0e10cSrcweir 562*cdf0e10cSrcweir basegfx::B2IVector b2ISizeFromSize( const Size& rSize ) 563*cdf0e10cSrcweir { 564*cdf0e10cSrcweir return ::basegfx::B2IVector( rSize.Width(), 565*cdf0e10cSrcweir rSize.Height() ); 566*cdf0e10cSrcweir } 567*cdf0e10cSrcweir 568*cdf0e10cSrcweir basegfx::B2IPoint b2IPointFromPoint( const Point& rPoint ) 569*cdf0e10cSrcweir { 570*cdf0e10cSrcweir return ::basegfx::B2IPoint( rPoint.X(), 571*cdf0e10cSrcweir rPoint.Y() ); 572*cdf0e10cSrcweir } 573*cdf0e10cSrcweir 574*cdf0e10cSrcweir basegfx::B2IRange b2IRectangleFromRectangle( const Rectangle& rRect ) 575*cdf0e10cSrcweir { 576*cdf0e10cSrcweir return ::basegfx::B2IRange( rRect.Left(), 577*cdf0e10cSrcweir rRect.Top(), 578*cdf0e10cSrcweir rRect.Right(), 579*cdf0e10cSrcweir rRect.Bottom() ); 580*cdf0e10cSrcweir } 581*cdf0e10cSrcweir 582*cdf0e10cSrcweir geometry::IntegerSize2D integerSize2DFromSize( const Size& rSize ) 583*cdf0e10cSrcweir { 584*cdf0e10cSrcweir return geometry::IntegerSize2D( rSize.Width(), 585*cdf0e10cSrcweir rSize.Height() ); 586*cdf0e10cSrcweir } 587*cdf0e10cSrcweir 588*cdf0e10cSrcweir geometry::IntegerPoint2D integerPoint2DFromPoint( const Point& rPoint ) 589*cdf0e10cSrcweir { 590*cdf0e10cSrcweir return geometry::IntegerPoint2D( rPoint.X(), 591*cdf0e10cSrcweir rPoint.Y() ); 592*cdf0e10cSrcweir } 593*cdf0e10cSrcweir 594*cdf0e10cSrcweir geometry::IntegerRectangle2D integerRectangle2DFromRectangle( const Rectangle& rRectangle ) 595*cdf0e10cSrcweir { 596*cdf0e10cSrcweir return geometry::IntegerRectangle2D( rRectangle.Left(), rRectangle.Top(), 597*cdf0e10cSrcweir rRectangle.Right(), rRectangle.Bottom() ); 598*cdf0e10cSrcweir } 599*cdf0e10cSrcweir 600*cdf0e10cSrcweir Size sizeFromIntegerSize2D( const geometry::IntegerSize2D& rSize ) 601*cdf0e10cSrcweir { 602*cdf0e10cSrcweir return Size( rSize.Width, 603*cdf0e10cSrcweir rSize.Height ); 604*cdf0e10cSrcweir } 605*cdf0e10cSrcweir 606*cdf0e10cSrcweir Point pointFromIntegerPoint2D( const geometry::IntegerPoint2D& rPoint ) 607*cdf0e10cSrcweir { 608*cdf0e10cSrcweir return Point( rPoint.X, 609*cdf0e10cSrcweir rPoint.Y ); 610*cdf0e10cSrcweir } 611*cdf0e10cSrcweir 612*cdf0e10cSrcweir Rectangle rectangleFromIntegerRectangle2D( const geometry::IntegerRectangle2D& rRectangle ) 613*cdf0e10cSrcweir { 614*cdf0e10cSrcweir return Rectangle( rRectangle.X1, rRectangle.Y1, 615*cdf0e10cSrcweir rRectangle.X2, rRectangle.Y2 ); 616*cdf0e10cSrcweir } 617*cdf0e10cSrcweir 618*cdf0e10cSrcweir namespace 619*cdf0e10cSrcweir { 620*cdf0e10cSrcweir class StandardColorSpace : public cppu::WeakImplHelper1< com::sun::star::rendering::XColorSpace > 621*cdf0e10cSrcweir { 622*cdf0e10cSrcweir private: 623*cdf0e10cSrcweir uno::Sequence< sal_Int8 > m_aComponentTags; 624*cdf0e10cSrcweir 625*cdf0e10cSrcweir virtual ::sal_Int8 SAL_CALL getType( ) throw (uno::RuntimeException) 626*cdf0e10cSrcweir { 627*cdf0e10cSrcweir return rendering::ColorSpaceType::RGB; 628*cdf0e10cSrcweir } 629*cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( ) throw (uno::RuntimeException) 630*cdf0e10cSrcweir { 631*cdf0e10cSrcweir return m_aComponentTags; 632*cdf0e10cSrcweir } 633*cdf0e10cSrcweir virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) throw (uno::RuntimeException) 634*cdf0e10cSrcweir { 635*cdf0e10cSrcweir return rendering::RenderingIntent::PERCEPTUAL; 636*cdf0e10cSrcweir } 637*cdf0e10cSrcweir virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) throw (uno::RuntimeException) 638*cdf0e10cSrcweir { 639*cdf0e10cSrcweir return uno::Sequence< beans::PropertyValue >(); 640*cdf0e10cSrcweir } 641*cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor, 642*cdf0e10cSrcweir const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException, 643*cdf0e10cSrcweir uno::RuntimeException) 644*cdf0e10cSrcweir { 645*cdf0e10cSrcweir // TODO(P3): if we know anything about target 646*cdf0e10cSrcweir // colorspace, this can be greatly sped up 647*cdf0e10cSrcweir uno::Sequence<rendering::ARGBColor> aIntermediate( 648*cdf0e10cSrcweir convertToARGB(deviceColor)); 649*cdf0e10cSrcweir return targetColorSpace->convertFromARGB(aIntermediate); 650*cdf0e10cSrcweir } 651*cdf0e10cSrcweir virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 652*cdf0e10cSrcweir { 653*cdf0e10cSrcweir const double* pIn( deviceColor.getConstArray() ); 654*cdf0e10cSrcweir const sal_Size nLen( deviceColor.getLength() ); 655*cdf0e10cSrcweir ENSURE_ARG_OR_THROW2(nLen%4==0, 656*cdf0e10cSrcweir "number of channels no multiple of 4", 657*cdf0e10cSrcweir static_cast<rendering::XColorSpace*>(this), 0); 658*cdf0e10cSrcweir 659*cdf0e10cSrcweir uno::Sequence< rendering::RGBColor > aRes(nLen/4); 660*cdf0e10cSrcweir rendering::RGBColor* pOut( aRes.getArray() ); 661*cdf0e10cSrcweir for( sal_Size i=0; i<nLen; i+=4 ) 662*cdf0e10cSrcweir { 663*cdf0e10cSrcweir *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]); 664*cdf0e10cSrcweir pIn += 4; 665*cdf0e10cSrcweir } 666*cdf0e10cSrcweir return aRes; 667*cdf0e10cSrcweir } 668*cdf0e10cSrcweir virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 669*cdf0e10cSrcweir { 670*cdf0e10cSrcweir const double* pIn( deviceColor.getConstArray() ); 671*cdf0e10cSrcweir const sal_Size nLen( deviceColor.getLength() ); 672*cdf0e10cSrcweir ENSURE_ARG_OR_THROW2(nLen%4==0, 673*cdf0e10cSrcweir "number of channels no multiple of 4", 674*cdf0e10cSrcweir static_cast<rendering::XColorSpace*>(this), 0); 675*cdf0e10cSrcweir 676*cdf0e10cSrcweir uno::Sequence< rendering::ARGBColor > aRes(nLen/4); 677*cdf0e10cSrcweir rendering::ARGBColor* pOut( aRes.getArray() ); 678*cdf0e10cSrcweir for( sal_Size i=0; i<nLen; i+=4 ) 679*cdf0e10cSrcweir { 680*cdf0e10cSrcweir *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]); 681*cdf0e10cSrcweir pIn += 4; 682*cdf0e10cSrcweir } 683*cdf0e10cSrcweir return aRes; 684*cdf0e10cSrcweir } 685*cdf0e10cSrcweir virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 686*cdf0e10cSrcweir { 687*cdf0e10cSrcweir const double* pIn( deviceColor.getConstArray() ); 688*cdf0e10cSrcweir const sal_Size nLen( deviceColor.getLength() ); 689*cdf0e10cSrcweir ENSURE_ARG_OR_THROW2(nLen%4==0, 690*cdf0e10cSrcweir "number of channels no multiple of 4", 691*cdf0e10cSrcweir static_cast<rendering::XColorSpace*>(this), 0); 692*cdf0e10cSrcweir 693*cdf0e10cSrcweir uno::Sequence< rendering::ARGBColor > aRes(nLen/4); 694*cdf0e10cSrcweir rendering::ARGBColor* pOut( aRes.getArray() ); 695*cdf0e10cSrcweir for( sal_Size i=0; i<nLen; i+=4 ) 696*cdf0e10cSrcweir { 697*cdf0e10cSrcweir *pOut++ = rendering::ARGBColor(pIn[3],pIn[3]*pIn[0],pIn[3]*pIn[1],pIn[3]*pIn[2]); 698*cdf0e10cSrcweir pIn += 4; 699*cdf0e10cSrcweir } 700*cdf0e10cSrcweir return aRes; 701*cdf0e10cSrcweir } 702*cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 703*cdf0e10cSrcweir { 704*cdf0e10cSrcweir const rendering::RGBColor* pIn( rgbColor.getConstArray() ); 705*cdf0e10cSrcweir const sal_Size nLen( rgbColor.getLength() ); 706*cdf0e10cSrcweir 707*cdf0e10cSrcweir uno::Sequence< double > aRes(nLen*4); 708*cdf0e10cSrcweir double* pColors=aRes.getArray(); 709*cdf0e10cSrcweir for( sal_Size i=0; i<nLen; ++i ) 710*cdf0e10cSrcweir { 711*cdf0e10cSrcweir *pColors++ = pIn->Red; 712*cdf0e10cSrcweir *pColors++ = pIn->Green; 713*cdf0e10cSrcweir *pColors++ = pIn->Blue; 714*cdf0e10cSrcweir *pColors++ = 1.0; 715*cdf0e10cSrcweir ++pIn; 716*cdf0e10cSrcweir } 717*cdf0e10cSrcweir return aRes; 718*cdf0e10cSrcweir } 719*cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 720*cdf0e10cSrcweir { 721*cdf0e10cSrcweir const rendering::ARGBColor* pIn( rgbColor.getConstArray() ); 722*cdf0e10cSrcweir const sal_Size nLen( rgbColor.getLength() ); 723*cdf0e10cSrcweir 724*cdf0e10cSrcweir uno::Sequence< double > aRes(nLen*4); 725*cdf0e10cSrcweir double* pColors=aRes.getArray(); 726*cdf0e10cSrcweir for( sal_Size i=0; i<nLen; ++i ) 727*cdf0e10cSrcweir { 728*cdf0e10cSrcweir *pColors++ = pIn->Red; 729*cdf0e10cSrcweir *pColors++ = pIn->Green; 730*cdf0e10cSrcweir *pColors++ = pIn->Blue; 731*cdf0e10cSrcweir *pColors++ = pIn->Alpha; 732*cdf0e10cSrcweir ++pIn; 733*cdf0e10cSrcweir } 734*cdf0e10cSrcweir return aRes; 735*cdf0e10cSrcweir } 736*cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 737*cdf0e10cSrcweir { 738*cdf0e10cSrcweir const rendering::ARGBColor* pIn( rgbColor.getConstArray() ); 739*cdf0e10cSrcweir const sal_Size nLen( rgbColor.getLength() ); 740*cdf0e10cSrcweir 741*cdf0e10cSrcweir uno::Sequence< double > aRes(nLen*4); 742*cdf0e10cSrcweir double* pColors=aRes.getArray(); 743*cdf0e10cSrcweir for( sal_Size i=0; i<nLen; ++i ) 744*cdf0e10cSrcweir { 745*cdf0e10cSrcweir *pColors++ = pIn->Red/pIn->Alpha; 746*cdf0e10cSrcweir *pColors++ = pIn->Green/pIn->Alpha; 747*cdf0e10cSrcweir *pColors++ = pIn->Blue/pIn->Alpha; 748*cdf0e10cSrcweir *pColors++ = pIn->Alpha; 749*cdf0e10cSrcweir ++pIn; 750*cdf0e10cSrcweir } 751*cdf0e10cSrcweir return aRes; 752*cdf0e10cSrcweir } 753*cdf0e10cSrcweir 754*cdf0e10cSrcweir public: 755*cdf0e10cSrcweir StandardColorSpace() : m_aComponentTags(4) 756*cdf0e10cSrcweir { 757*cdf0e10cSrcweir sal_Int8* pTags = m_aComponentTags.getArray(); 758*cdf0e10cSrcweir pTags[0] = rendering::ColorComponentTag::RGB_RED; 759*cdf0e10cSrcweir pTags[1] = rendering::ColorComponentTag::RGB_GREEN; 760*cdf0e10cSrcweir pTags[2] = rendering::ColorComponentTag::RGB_BLUE; 761*cdf0e10cSrcweir pTags[3] = rendering::ColorComponentTag::ALPHA; 762*cdf0e10cSrcweir } 763*cdf0e10cSrcweir }; 764*cdf0e10cSrcweir } 765*cdf0e10cSrcweir 766*cdf0e10cSrcweir uno::Reference<rendering::XColorSpace> VCL_DLLPUBLIC createStandardColorSpace() 767*cdf0e10cSrcweir { 768*cdf0e10cSrcweir return new StandardColorSpace(); 769*cdf0e10cSrcweir } 770*cdf0e10cSrcweir 771*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 772*cdf0e10cSrcweir 773*cdf0e10cSrcweir uno::Sequence< double > colorToStdColorSpaceSequence( const Color& rColor ) 774*cdf0e10cSrcweir { 775*cdf0e10cSrcweir uno::Sequence< double > aRet(4); 776*cdf0e10cSrcweir double* pRet = aRet.getArray(); 777*cdf0e10cSrcweir 778*cdf0e10cSrcweir pRet[0] = toDoubleColor(rColor.GetRed()); 779*cdf0e10cSrcweir pRet[1] = toDoubleColor(rColor.GetGreen()); 780*cdf0e10cSrcweir pRet[2] = toDoubleColor(rColor.GetBlue()); 781*cdf0e10cSrcweir 782*cdf0e10cSrcweir // VCL's notion of alpha is different from the rest of the world's 783*cdf0e10cSrcweir pRet[3] = 1.0 - toDoubleColor(rColor.GetTransparency()); 784*cdf0e10cSrcweir 785*cdf0e10cSrcweir return aRet; 786*cdf0e10cSrcweir } 787*cdf0e10cSrcweir 788*cdf0e10cSrcweir Color stdColorSpaceSequenceToColor( const uno::Sequence< double >& rColor ) 789*cdf0e10cSrcweir { 790*cdf0e10cSrcweir ENSURE_ARG_OR_THROW( rColor.getLength() == 4, 791*cdf0e10cSrcweir "color must have 4 channels" ); 792*cdf0e10cSrcweir 793*cdf0e10cSrcweir Color aColor; 794*cdf0e10cSrcweir 795*cdf0e10cSrcweir aColor.SetRed ( toByteColor(rColor[0]) ); 796*cdf0e10cSrcweir aColor.SetGreen( toByteColor(rColor[1]) ); 797*cdf0e10cSrcweir aColor.SetBlue ( toByteColor(rColor[2]) ); 798*cdf0e10cSrcweir // VCL's notion of alpha is different from the rest of the world's 799*cdf0e10cSrcweir aColor.SetTransparency( 255 - toByteColor(rColor[3]) ); 800*cdf0e10cSrcweir 801*cdf0e10cSrcweir return aColor; 802*cdf0e10cSrcweir } 803*cdf0e10cSrcweir 804*cdf0e10cSrcweir uno::Sequence< double > VCL_DLLPUBLIC colorToDoubleSequence( 805*cdf0e10cSrcweir const Color& rColor, 806*cdf0e10cSrcweir const uno::Reference< rendering::XColorSpace >& xColorSpace ) 807*cdf0e10cSrcweir { 808*cdf0e10cSrcweir uno::Sequence<rendering::ARGBColor> aSeq(1); 809*cdf0e10cSrcweir aSeq[0] = rendering::ARGBColor( 810*cdf0e10cSrcweir 1.0-toDoubleColor(rColor.GetTransparency()), 811*cdf0e10cSrcweir toDoubleColor(rColor.GetRed()), 812*cdf0e10cSrcweir toDoubleColor(rColor.GetGreen()), 813*cdf0e10cSrcweir toDoubleColor(rColor.GetBlue()) ); 814*cdf0e10cSrcweir 815*cdf0e10cSrcweir return xColorSpace->convertFromARGB(aSeq); 816*cdf0e10cSrcweir } 817*cdf0e10cSrcweir 818*cdf0e10cSrcweir Color VCL_DLLPUBLIC doubleSequenceToColor( 819*cdf0e10cSrcweir const uno::Sequence< double > rColor, 820*cdf0e10cSrcweir const uno::Reference< rendering::XColorSpace >& xColorSpace ) 821*cdf0e10cSrcweir { 822*cdf0e10cSrcweir const rendering::ARGBColor& rARGBColor( 823*cdf0e10cSrcweir xColorSpace->convertToARGB(rColor)[0]); 824*cdf0e10cSrcweir 825*cdf0e10cSrcweir return Color( 255-toByteColor(rARGBColor.Alpha), 826*cdf0e10cSrcweir toByteColor(rARGBColor.Red), 827*cdf0e10cSrcweir toByteColor(rARGBColor.Green), 828*cdf0e10cSrcweir toByteColor(rARGBColor.Blue) ); 829*cdf0e10cSrcweir } 830*cdf0e10cSrcweir 831*cdf0e10cSrcweir //--------------------------------------------------------------------------------------- 832*cdf0e10cSrcweir 833*cdf0e10cSrcweir } // namespace vcltools 834*cdf0e10cSrcweir 835*cdf0e10cSrcweir } // namespace canvas 836*cdf0e10cSrcweir 837*cdf0e10cSrcweir // eof 838