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