LCOV - code coverage report
Current view: top level - vcl/source/helper - canvastools.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 148 281 52.7 %
Date: 2014-11-03 Functions: 18 39 46.2 %
Legend: Lines: hit not hit

          Line data    Source code
       1             : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2             : /*
       3             :  * This file is part of the LibreOffice project.
       4             :  *
       5             :  * This Source Code Form is subject to the terms of the Mozilla Public
       6             :  * License, v. 2.0. If a copy of the MPL was not distributed with this
       7             :  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
       8             :  *
       9             :  * This file incorporates work covered by the following license notice:
      10             :  *
      11             :  *   Licensed to the Apache Software Foundation (ASF) under one or more
      12             :  *   contributor license agreements. See the NOTICE file distributed
      13             :  *   with this work for additional information regarding copyright
      14             :  *   ownership. The ASF licenses this file to you under the Apache
      15             :  *   License, Version 2.0 (the "License"); you may not use this file
      16             :  *   except in compliance with the License. You may obtain a copy of
      17             :  *   the License at http://www.apache.org/licenses/LICENSE-2.0 .
      18             :  */
      19             : 
      20             : #include <cppuhelper/compbase1.hxx>
      21             : 
      22             : #include <com/sun/star/geometry/RealSize2D.hpp>
      23             : #include <com/sun/star/geometry/RealPoint2D.hpp>
      24             : #include <com/sun/star/geometry/RealRectangle2D.hpp>
      25             : #include <com/sun/star/geometry/IntegerSize2D.hpp>
      26             : #include <com/sun/star/geometry/IntegerPoint2D.hpp>
      27             : #include <com/sun/star/geometry/IntegerRectangle2D.hpp>
      28             : #include <com/sun/star/geometry/RealBezierSegment2D.hpp>
      29             : 
      30             : #include <com/sun/star/rendering/ColorSpaceType.hpp>
      31             : #include <com/sun/star/rendering/RenderingIntent.hpp>
      32             : #include <com/sun/star/rendering/XGraphicDevice.hpp>
      33             : #include <com/sun/star/rendering/XBitmap.hpp>
      34             : #include <com/sun/star/rendering/XPolyPolygon2D.hpp>
      35             : #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
      36             : #include <com/sun/star/rendering/XIntegerBitmap.hpp>
      37             : #include <com/sun/star/rendering/ColorComponentTag.hpp>
      38             : 
      39             : #include <basegfx/matrix/b2dhommatrix.hxx>
      40             : #include <basegfx/vector/b2dsize.hxx>
      41             : #include <basegfx/point/b2dpoint.hxx>
      42             : #include <basegfx/range/b2drectangle.hxx>
      43             : #include <basegfx/vector/b2isize.hxx>
      44             : #include <basegfx/point/b2ipoint.hxx>
      45             : #include <basegfx/range/b2irectangle.hxx>
      46             : #include <basegfx/polygon/b2dpolygon.hxx>
      47             : #include <basegfx/tools/canvastools.hxx>
      48             : #include <basegfx/polygon/b2dpolypolygon.hxx>
      49             : 
      50             : #include <tools/poly.hxx>
      51             : #include <tools/diagnose_ex.h>
      52             : #include <rtl/uuid.h>
      53             : 
      54             : #include <vcl/salbtype.hxx>
      55             : #include <vcl/bmpacc.hxx>
      56             : #include <vcl/bitmapex.hxx>
      57             : 
      58             : #include <canvasbitmap.hxx>
      59             : #include <vcl/canvastools.hxx>
      60             : #include <boost/unordered_map.hpp>
      61             : 
      62             : using namespace ::com::sun::star;
      63             : 
      64             : namespace vcl
      65             : {
      66             :     namespace unotools
      67             :     {
      68         292 :         uno::Reference< rendering::XBitmap > xBitmapFromBitmapEx( const uno::Reference< rendering::XGraphicDevice >&    /*xGraphicDevice*/,
      69             :                                                                   const ::BitmapEx&                                     inputBitmap )
      70             :         {
      71             :             SAL_INFO( "vcl.helper", "::vcl::unotools::xBitmapFromBitmapEx()" );
      72             : 
      73         292 :             return new vcl::unotools::VclCanvasBitmap( inputBitmap );
      74             :         }
      75             : 
      76             :         namespace
      77             :         {
      78          40 :             inline bool operator==( const rendering::IntegerBitmapLayout& rLHS,
      79             :                                     const rendering::IntegerBitmapLayout& rRHS )
      80             :             {
      81             :                 return
      82          80 :                     rLHS.ScanLineBytes       == rRHS.ScanLineBytes &&
      83          80 :                     rLHS.ScanLineStride      == rRHS.ScanLineStride &&
      84          80 :                     rLHS.PlaneStride         == rRHS.PlaneStride &&
      85          80 :                     rLHS.ColorSpace          == rRHS.ColorSpace &&
      86         120 :                     rLHS.Palette             == rRHS.Palette &&
      87          80 :                     rLHS.IsMsbFirst          == rRHS.IsMsbFirst;
      88             :             }
      89             : 
      90           4 :             bool readBmp( sal_Int32                                                  nWidth,
      91             :                           sal_Int32                                                  nHeight,
      92             :                           const rendering::IntegerBitmapLayout&                      rLayout,
      93             :                           const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap,
      94             :                           Bitmap::ScopedWriteAccess&                                   rWriteAcc,
      95             :                           Bitmap::ScopedWriteAccess&                                   rAlphaAcc )
      96             :             {
      97           4 :                 rendering::IntegerBitmapLayout      aCurrLayout;
      98           4 :                 geometry::IntegerRectangle2D        aRect;
      99           8 :                 uno::Sequence<sal_Int8>             aPixelData;
     100           8 :                 uno::Sequence<rendering::RGBColor>  aRGBColors;
     101           8 :                 uno::Sequence<rendering::ARGBColor> aARGBColors;
     102             : 
     103          44 :                 for( aRect.Y1=0; aRect.Y1<nHeight; ++aRect.Y1 )
     104             :                 {
     105          40 :                     aRect.X1 = 0; aRect.X2 = nWidth; aRect.Y2 = aRect.Y1+1;
     106             :                     try
     107             :                     {
     108          40 :                         aPixelData = xInputBitmap->getData(aCurrLayout,aRect);
     109             :                     }
     110           0 :                     catch( rendering::VolatileContentDestroyedException& )
     111             :                     {
     112             :                         // re-read bmp from the start
     113           0 :                         return false;
     114             :                     }
     115          40 :                     if( !(aCurrLayout == rLayout) )
     116           0 :                         return false; // re-read bmp from the start
     117             : 
     118          40 :                     if( rAlphaAcc.get() )
     119             :                     {
     120             :                         // read ARGB color
     121          20 :                         aARGBColors = rLayout.ColorSpace->convertIntegerToARGB(aPixelData);
     122             : 
     123          20 :                         if( rWriteAcc->HasPalette() )
     124             :                         {
     125           0 :                             for( sal_Int32 x=0; x<nWidth; ++x )
     126             :                             {
     127           0 :                                 const rendering::ARGBColor& rColor=aARGBColors[x];
     128             :                                 rWriteAcc->SetPixelIndex( aRect.Y1, x,
     129           0 :                                                      (sal_uInt8) rWriteAcc->GetBestPaletteIndex(
     130           0 :                                                          BitmapColor( toByteColor(rColor.Red),
     131           0 :                                                                       toByteColor(rColor.Green),
     132           0 :                                                                       toByteColor(rColor.Blue))) );
     133             :                                 rAlphaAcc->SetPixel( aRect.Y1, x,
     134           0 :                                                      BitmapColor( 255 - toByteColor(rColor.Alpha) ));
     135             :                             }
     136             :                         }
     137             :                         else
     138             :                         {
     139         220 :                             for( sal_Int32 x=0; x<nWidth; ++x )
     140             :                             {
     141         200 :                                 const rendering::ARGBColor& rColor=aARGBColors[x];
     142             :                                 rWriteAcc->SetPixel( aRect.Y1, x,
     143         200 :                                                      BitmapColor( toByteColor(rColor.Red),
     144         200 :                                                                   toByteColor(rColor.Green),
     145         600 :                                                                   toByteColor(rColor.Blue) ));
     146             :                                 rAlphaAcc->SetPixel( aRect.Y1, x,
     147         200 :                                                      BitmapColor( 255 - toByteColor(rColor.Alpha) ));
     148             :                             }
     149             :                         }
     150             :                     }
     151             :                     else
     152             :                     {
     153             :                         // read RGB color
     154          20 :                         aRGBColors = rLayout.ColorSpace->convertIntegerToRGB(aPixelData);
     155          20 :                         if( rWriteAcc->HasPalette() )
     156             :                         {
     157         220 :                             for( sal_Int32 x=0; x<nWidth; ++x )
     158             :                             {
     159         200 :                                 const rendering::RGBColor& rColor=aRGBColors[x];
     160             :                                 rWriteAcc->SetPixelIndex( aRect.Y1, x,
     161         200 :                                                      (sal_uInt8) rWriteAcc->GetBestPaletteIndex(
     162         200 :                                                          BitmapColor( toByteColor(rColor.Red),
     163         200 :                                                                       toByteColor(rColor.Green),
     164         800 :                                                                       toByteColor(rColor.Blue))) );
     165             :                             }
     166             :                         }
     167             :                         else
     168             :                         {
     169           0 :                             for( sal_Int32 x=0; x<nWidth; ++x )
     170             :                             {
     171           0 :                                 const rendering::RGBColor& rColor=aRGBColors[x];
     172             :                                 rWriteAcc->SetPixel( aRect.Y1, x,
     173           0 :                                                      BitmapColor( toByteColor(rColor.Red),
     174           0 :                                                                   toByteColor(rColor.Green),
     175           0 :                                                                   toByteColor(rColor.Blue) ));
     176             :                             }
     177             :                         }
     178             :                     }
     179             :                 }
     180             : 
     181           8 :                 return true;
     182             :             }
     183             :         }
     184             : 
     185         296 :         ::BitmapEx VCL_DLLPUBLIC bitmapExFromXBitmap( const uno::Reference< rendering::XIntegerReadOnlyBitmap >& xInputBitmap )
     186             :         {
     187             :             SAL_INFO( "vcl.helper", "::vcl::unotools::bitmapExFromXBitmap()" );
     188             : 
     189         296 :             if( !xInputBitmap.is() )
     190           0 :                 return ::BitmapEx();
     191             : 
     192             :             // tunnel directly for known implementation
     193         296 :             VclCanvasBitmap* pImplBitmap = dynamic_cast<VclCanvasBitmap*>(xInputBitmap.get());
     194         296 :             if( pImplBitmap )
     195         292 :                 return pImplBitmap->getBitmapEx();
     196             : 
     197             :             // retrieve data via UNO interface
     198             : 
     199             :             // volatile bitmaps are a bit more complicated to read
     200             :             // from..
     201             :             uno::Reference<rendering::XVolatileBitmap> xVolatileBitmap(
     202           4 :                 xInputBitmap, uno::UNO_QUERY);
     203             : 
     204             :             // loop a few times, until successfully read (for XVolatileBitmap)
     205           4 :             for( int i=0; i<10; ++i )
     206             :             {
     207           4 :                 sal_Int32 nDepth=0;
     208           4 :                 sal_Int32 nAlphaDepth=0;
     209             :                 const rendering::IntegerBitmapLayout aLayout(
     210           4 :                     xInputBitmap->getMemoryLayout());
     211             : 
     212             :                 OSL_ENSURE(aLayout.ColorSpace.is(),
     213             :                            "Cannot convert image without color space!");
     214           4 :                 if( !aLayout.ColorSpace.is() )
     215           0 :                     return ::BitmapEx();
     216             : 
     217           4 :                 nDepth = aLayout.ColorSpace->getBitsPerPixel();
     218             : 
     219           4 :                 if( xInputBitmap->hasAlpha() )
     220             :                 {
     221             :                     // determine alpha channel depth
     222             :                     const uno::Sequence<sal_Int8> aTags(
     223           2 :                         aLayout.ColorSpace->getComponentTags() );
     224           2 :                     const sal_Int8* pStart(aTags.getConstArray());
     225           2 :                     const sal_Size  nLen(aTags.getLength());
     226           2 :                     const sal_Int8* pEnd(pStart+nLen);
     227             : 
     228             :                     const std::ptrdiff_t nAlphaIndex =
     229             :                         std::find(pStart,pEnd,
     230           2 :                                   rendering::ColorComponentTag::ALPHA) - pStart;
     231             : 
     232           2 :                     if( nAlphaIndex < sal::static_int_cast<std::ptrdiff_t>(nLen) )
     233             :                     {
     234           2 :                         nAlphaDepth = aLayout.ColorSpace->getComponentBitCounts()[nAlphaIndex] > 1 ? 8 : 1;
     235           2 :                         nDepth -= nAlphaDepth;
     236           2 :                     }
     237             :                 }
     238             : 
     239           4 :                 BitmapPalette aPalette;
     240           4 :                 if( aLayout.Palette.is() )
     241             :                 {
     242             :                     uno::Reference< rendering::XColorSpace > xPaletteColorSpace(
     243           2 :                         aLayout.Palette->getColorSpace());
     244           2 :                     ENSURE_OR_THROW(xPaletteColorSpace.is(),
     245             :                                     "Palette without color space");
     246             : 
     247           2 :                     const sal_Int32 nEntryCount( aLayout.Palette->getNumberOfEntries() );
     248           2 :                     if( nEntryCount <= 256 )
     249             :                     {
     250           2 :                         if( nEntryCount <= 2 )
     251           0 :                             nDepth = 1;
     252             :                         else
     253           2 :                             nDepth = 8;
     254             : 
     255             :                         const sal_uInt16 nPaletteEntries(
     256             :                             sal::static_int_cast<sal_uInt16>(
     257           2 :                                 std::min(sal_Int32(255), nEntryCount)));
     258             : 
     259             :                         // copy palette entries
     260           2 :                         aPalette.SetEntryCount(nPaletteEntries);
     261           2 :                         uno::Reference<rendering::XBitmapPalette> xPalette( aLayout.Palette );
     262           4 :                         uno::Reference<rendering::XColorSpace>    xPalColorSpace( xPalette->getColorSpace() );
     263             : 
     264           4 :                         uno::Sequence<double> aPaletteEntry;
     265         512 :                         for( sal_uInt16 j=0; j<nPaletteEntries; ++j )
     266             :                         {
     267         510 :                             if( !xPalette->getIndex(aPaletteEntry,j) &&
     268             :                                 nAlphaDepth == 0 )
     269             :                             {
     270           0 :                                 nAlphaDepth = 1;
     271             :                             }
     272         510 :                             uno::Sequence<rendering::RGBColor> aColors=xPalColorSpace->convertToRGB(aPaletteEntry);
     273         510 :                             ENSURE_OR_THROW(aColors.getLength() == 1,
     274             :                                             "Palette returned more or less than one entry");
     275         510 :                             const rendering::RGBColor& rColor=aColors[0];
     276        1530 :                             aPalette[j] = BitmapColor(toByteColor(rColor.Red),
     277         510 :                                                       toByteColor(rColor.Green),
     278        1020 :                                                       toByteColor(rColor.Blue));
     279         512 :                         }
     280           2 :                     }
     281             :                 }
     282             : 
     283             :                 const ::Size aPixelSize(
     284           4 :                     sizeFromIntegerSize2D(xInputBitmap->getSize()));
     285             : 
     286             :                 // normalize bitcount
     287             :                 nDepth =
     288             :                     ( nDepth <= 1 ) ? 1 :
     289             :                     ( nDepth <= 4 ) ? 4 :
     290           4 :                     ( nDepth <= 8 ) ? 8 : 24;
     291             : 
     292             :                 ::Bitmap aBitmap( aPixelSize,
     293           4 :                                   sal::static_int_cast<sal_uInt16>(nDepth),
     294           8 :                                   aLayout.Palette.is() ? &aPalette : NULL );
     295           4 :                 ::Bitmap aAlpha;
     296           4 :                 if( nAlphaDepth )
     297           4 :                     aAlpha = ::Bitmap( aPixelSize,
     298           2 :                                        sal::static_int_cast<sal_uInt16>(nAlphaDepth),
     299             :                                        &::Bitmap::GetGreyPalette(
     300           4 :                                            sal::static_int_cast<sal_uInt16>(1L << nAlphaDepth)) );
     301             : 
     302             :                 { // limit scoped access
     303           4 :                     Bitmap::ScopedWriteAccess pWriteAccess( aBitmap );
     304             :                     Bitmap::ScopedWriteAccess pAlphaWriteAccess( nAlphaDepth ? aAlpha.AcquireWriteAccess() : NULL,
     305           8 :                                                                aAlpha );
     306             : 
     307           4 :                     ENSURE_OR_THROW(pWriteAccess.get() != NULL,
     308             :                                     "Cannot get write access to bitmap");
     309             : 
     310           4 :                     const sal_Int32 nWidth(aPixelSize.Width());
     311           4 :                     const sal_Int32 nHeight(aPixelSize.Height());
     312             : 
     313           4 :                     if( !readBmp(nWidth,nHeight,aLayout,xInputBitmap,
     314           4 :                                  pWriteAccess,pAlphaWriteAccess) )
     315           4 :                         continue;
     316             :                 } // limit scoped access
     317             : 
     318           4 :                 if( nAlphaDepth )
     319             :                     return ::BitmapEx( aBitmap,
     320           2 :                                        AlphaMask( aAlpha ) );
     321             :                 else
     322           2 :                     return ::BitmapEx( aBitmap );
     323           0 :             }
     324             : 
     325             :             // failed to read data 10 times - bail out
     326           0 :             return ::BitmapEx();
     327             :         }
     328             : 
     329           0 :         geometry::RealSize2D size2DFromSize( const Size& rSize )
     330             :         {
     331           0 :             return geometry::RealSize2D( rSize.Width(),
     332           0 :                                          rSize.Height() );
     333             :         }
     334             : 
     335          30 :         Size sizeFromRealSize2D( const geometry::RealSize2D& rSize )
     336             :         {
     337          30 :             return Size( static_cast<long>(rSize.Width + .5),
     338          60 :                          static_cast<long>(rSize.Height + .5) );
     339             :         }
     340             : 
     341           0 :         ::Size sizeFromB2DSize( const ::basegfx::B2DVector& rVec )
     342             :         {
     343             :             return ::Size( FRound( rVec.getX() ),
     344           0 :                            FRound( rVec.getY() ) );
     345             :         }
     346             : 
     347           0 :         ::Point pointFromB2DPoint( const ::basegfx::B2DPoint& rPoint )
     348             :         {
     349             :             return ::Point( FRound( rPoint.getX() ),
     350           0 :                             FRound( rPoint.getY() ) );
     351             :         }
     352             : 
     353         580 :         ::Rectangle rectangleFromB2DRectangle( const ::basegfx::B2DRange& rRect )
     354             :         {
     355             :             return ::Rectangle( FRound( rRect.getMinX() ),
     356             :                                 FRound( rRect.getMinY() ),
     357             :                                 FRound( rRect.getMaxX() ),
     358         580 :                                 FRound( rRect.getMaxY() ) );
     359             :         }
     360             : 
     361           0 :         Point pointFromB2IPoint( const ::basegfx::B2IPoint& rPoint )
     362             :         {
     363           0 :             return ::Point( rPoint.getX(),
     364           0 :                             rPoint.getY() );
     365             :         }
     366             : 
     367           0 :         Rectangle rectangleFromB2IRectangle( const ::basegfx::B2IRange& rRect )
     368             :         {
     369           0 :             return ::Rectangle( rRect.getMinX(),
     370           0 :                                 rRect.getMinY(),
     371           0 :                                 rRect.getMaxX(),
     372           0 :                                 rRect.getMaxY() );
     373             :         }
     374             : 
     375           0 :         ::basegfx::B2DVector b2DSizeFromSize( const ::Size& rSize )
     376             :         {
     377           0 :             return ::basegfx::B2DVector( rSize.Width(),
     378           0 :                                          rSize.Height() );
     379             :         }
     380             : 
     381           0 :         ::basegfx::B2DPoint b2DPointFromPoint( const ::Point& rPoint )
     382             :         {
     383           0 :             return ::basegfx::B2DPoint( rPoint.X(),
     384           0 :                                         rPoint.Y() );
     385             :         }
     386             : 
     387         624 :         ::basegfx::B2DRange b2DRectangleFromRectangle( const ::Rectangle& rRect )
     388             :         {
     389         624 :             return ::basegfx::B2DRange( rRect.Left(),
     390         624 :                                         rRect.Top(),
     391         624 :                                         rRect.Right(),
     392        2496 :                                         rRect.Bottom() );
     393             :         }
     394             : 
     395          60 :         geometry::IntegerSize2D integerSize2DFromSize( const Size& rSize )
     396             :         {
     397          60 :             return geometry::IntegerSize2D( rSize.Width(),
     398         120 :                                             rSize.Height() );
     399             :         }
     400             : 
     401           4 :         Size sizeFromIntegerSize2D( const geometry::IntegerSize2D& rSize )
     402             :         {
     403             :             return Size( rSize.Width,
     404           4 :                          rSize.Height );
     405             :         }
     406             : 
     407           0 :         Point pointFromIntegerPoint2D( const geometry::IntegerPoint2D& rPoint )
     408             :         {
     409             :             return Point( rPoint.X,
     410           0 :                           rPoint.Y );
     411             :         }
     412             : 
     413          60 :         Rectangle rectangleFromIntegerRectangle2D( const geometry::IntegerRectangle2D& rRectangle )
     414             :         {
     415             :             return Rectangle( rRectangle.X1, rRectangle.Y1,
     416          60 :                               rRectangle.X2, rRectangle.Y2 );
     417             :         }
     418             : 
     419             :         namespace
     420             :         {
     421           8 :             class StandardColorSpace : public cppu::WeakImplHelper1< com::sun::star::rendering::XColorSpace >
     422             :             {
     423             :             private:
     424             :                 uno::Sequence< sal_Int8 > m_aComponentTags;
     425             : 
     426           0 :                 virtual ::sal_Int8 SAL_CALL getType(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     427             :                 {
     428           0 :                     return rendering::ColorSpaceType::RGB;
     429             :                 }
     430           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     431             :                 {
     432           0 :                     return m_aComponentTags;
     433             :                 }
     434           0 :                 virtual ::sal_Int8 SAL_CALL getRenderingIntent(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     435             :                 {
     436           0 :                     return rendering::RenderingIntent::PERCEPTUAL;
     437             :                 }
     438           0 :                 virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     439             :                 {
     440           0 :                     return uno::Sequence< beans::PropertyValue >();
     441             :                 }
     442           0 :                 virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
     443             :                                                                             const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
     444             :                                                                                                                                                       uno::RuntimeException, std::exception) SAL_OVERRIDE
     445             :                 {
     446             :                     // TODO(P3): if we know anything about target
     447             :                     // colorspace, this can be greatly sped up
     448             :                     uno::Sequence<rendering::ARGBColor> aIntermediate(
     449           0 :                         convertToARGB(deviceColor));
     450           0 :                     return targetColorSpace->convertFromARGB(aIntermediate);
     451             :                 }
     452         510 :                 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     453             :                 {
     454         510 :                     const double*  pIn( deviceColor.getConstArray() );
     455         510 :                     const sal_Size nLen( deviceColor.getLength() );
     456         510 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     457             :                                          "number of channels no multiple of 4",
     458             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     459             : 
     460         510 :                     uno::Sequence< rendering::RGBColor > aRes(nLen/4);
     461         510 :                     rendering::RGBColor* pOut( aRes.getArray() );
     462        1020 :                     for( sal_Size i=0; i<nLen; i+=4 )
     463             :                     {
     464         510 :                         *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
     465         510 :                         pIn += 4;
     466             :                     }
     467         510 :                     return aRes;
     468             :                 }
     469           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     470             :                 {
     471           0 :                     const double*  pIn( deviceColor.getConstArray() );
     472           0 :                     const sal_Size nLen( deviceColor.getLength() );
     473           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     474             :                                          "number of channels no multiple of 4",
     475             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     476             : 
     477           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     478           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     479           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     480             :                     {
     481           0 :                         *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]);
     482           0 :                         pIn += 4;
     483             :                     }
     484           0 :                     return aRes;
     485             :                 }
     486           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     487             :                 {
     488           0 :                     const double*  pIn( deviceColor.getConstArray() );
     489           0 :                     const sal_Size nLen( deviceColor.getLength() );
     490           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     491             :                                          "number of channels no multiple of 4",
     492             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     493             : 
     494           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     495           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     496           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     497             :                     {
     498           0 :                         *pOut++ = rendering::ARGBColor(pIn[3],pIn[3]*pIn[0],pIn[3]*pIn[1],pIn[3]*pIn[2]);
     499           0 :                         pIn += 4;
     500             :                     }
     501           0 :                     return aRes;
     502             :                 }
     503           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     504             :                 {
     505           0 :                     const rendering::RGBColor* pIn( rgbColor.getConstArray() );
     506           0 :                     const sal_Size             nLen( rgbColor.getLength() );
     507             : 
     508           0 :                     uno::Sequence< double > aRes(nLen*4);
     509           0 :                     double* pColors=aRes.getArray();
     510           0 :                     for( sal_Size i=0; i<nLen; ++i )
     511             :                     {
     512           0 :                         *pColors++ = pIn->Red;
     513           0 :                         *pColors++ = pIn->Green;
     514           0 :                         *pColors++ = pIn->Blue;
     515           0 :                         *pColors++ = 1.0;
     516           0 :                         ++pIn;
     517             :                     }
     518           0 :                     return aRes;
     519             :                 }
     520           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     521             :                 {
     522           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     523           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     524             : 
     525           0 :                     uno::Sequence< double > aRes(nLen*4);
     526           0 :                     double* pColors=aRes.getArray();
     527           0 :                     for( sal_Size i=0; i<nLen; ++i )
     528             :                     {
     529           0 :                         *pColors++ = pIn->Red;
     530           0 :                         *pColors++ = pIn->Green;
     531           0 :                         *pColors++ = pIn->Blue;
     532           0 :                         *pColors++ = pIn->Alpha;
     533           0 :                         ++pIn;
     534             :                     }
     535           0 :                     return aRes;
     536             :                 }
     537           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     538             :                 {
     539           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     540           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     541             : 
     542           0 :                     uno::Sequence< double > aRes(nLen*4);
     543           0 :                     double* pColors=aRes.getArray();
     544           0 :                     for( sal_Size i=0; i<nLen; ++i )
     545             :                     {
     546           0 :                         *pColors++ = pIn->Red/pIn->Alpha;
     547           0 :                         *pColors++ = pIn->Green/pIn->Alpha;
     548           0 :                         *pColors++ = pIn->Blue/pIn->Alpha;
     549           0 :                         *pColors++ = pIn->Alpha;
     550           0 :                         ++pIn;
     551             :                     }
     552           0 :                     return aRes;
     553             :                 }
     554             : 
     555             :             public:
     556           4 :                 StandardColorSpace() : m_aComponentTags(4)
     557             :                 {
     558           4 :                     sal_Int8* pTags = m_aComponentTags.getArray();
     559           4 :                     pTags[0] = rendering::ColorComponentTag::RGB_RED;
     560           4 :                     pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
     561           4 :                     pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
     562           4 :                     pTags[3] = rendering::ColorComponentTag::ALPHA;
     563           4 :                 }
     564             :             };
     565             :         }
     566             : 
     567           4 :         uno::Reference<rendering::XColorSpace> VCL_DLLPUBLIC createStandardColorSpace()
     568             :         {
     569           4 :             return new StandardColorSpace();
     570             :         }
     571             : 
     572         510 :         uno::Sequence< double > colorToStdColorSpaceSequence( const Color& rColor )
     573             :         {
     574         510 :             uno::Sequence< double > aRet(4);
     575         510 :             double* pRet = aRet.getArray();
     576             : 
     577         510 :             pRet[0] = toDoubleColor(rColor.GetRed());
     578         510 :             pRet[1] = toDoubleColor(rColor.GetGreen());
     579         510 :             pRet[2] = toDoubleColor(rColor.GetBlue());
     580             : 
     581             :             // VCL's notion of alpha is different from the rest of the world's
     582         510 :             pRet[3] = 1.0 - toDoubleColor(rColor.GetTransparency());
     583             : 
     584         510 :             return aRet;
     585             :         }
     586             : 
     587           0 :         Color stdColorSpaceSequenceToColor( const uno::Sequence< double >& rColor        )
     588             :         {
     589           0 :             ENSURE_ARG_OR_THROW( rColor.getLength() == 4,
     590             :                                  "color must have 4 channels" );
     591             : 
     592           0 :             Color aColor;
     593             : 
     594           0 :             aColor.SetRed  ( toByteColor(rColor[0]) );
     595           0 :             aColor.SetGreen( toByteColor(rColor[1]) );
     596           0 :             aColor.SetBlue ( toByteColor(rColor[2]) );
     597             :             // VCL's notion of alpha is different from the rest of the world's
     598           0 :             aColor.SetTransparency( 255 - toByteColor(rColor[3]) );
     599             : 
     600           0 :             return aColor;
     601             :         }
     602             : 
     603           0 :         uno::Sequence< double > VCL_DLLPUBLIC colorToDoubleSequence(
     604             :             const Color&                                    rColor,
     605             :             const uno::Reference< rendering::XColorSpace >& xColorSpace )
     606             :         {
     607           0 :             uno::Sequence<rendering::ARGBColor> aSeq(1);
     608           0 :             aSeq[0] = rendering::ARGBColor(
     609           0 :                     1.0-toDoubleColor(rColor.GetTransparency()),
     610           0 :                     toDoubleColor(rColor.GetRed()),
     611           0 :                     toDoubleColor(rColor.GetGreen()),
     612           0 :                     toDoubleColor(rColor.GetBlue()) );
     613             : 
     614           0 :             return xColorSpace->convertFromARGB(aSeq);
     615             :         }
     616             : 
     617           0 :         Color VCL_DLLPUBLIC doubleSequenceToColor(
     618             :             const uno::Sequence< double >&                  rColor,
     619             :             const uno::Reference< rendering::XColorSpace >& xColorSpace )
     620             :         {
     621             :             const rendering::ARGBColor aARGBColor(
     622           0 :                 xColorSpace->convertToARGB(rColor)[0]);
     623             : 
     624           0 :             return Color( 255-toByteColor(aARGBColor.Alpha),
     625           0 :                           toByteColor(aARGBColor.Red),
     626           0 :                           toByteColor(aARGBColor.Green),
     627           0 :                           toByteColor(aARGBColor.Blue) );
     628             :         }
     629             : 
     630             :     } // namespace vcltools
     631             : 
     632        1233 : } // namespace canvas
     633             : 
     634             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10