LCOV - code coverage report
Current view: top level - canvas/source/tools - canvastools.cxx (source / functions) Hit Total Coverage
Test: commit 10e77ab3ff6f4314137acd6e2702a6e5c1ce1fae Lines: 1 610 0.2 %
Date: 2014-11-03 Functions: 2 83 2.4 %
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             : 
      21             : #include <canvas/debug.hxx>
      22             : #include <tools/diagnose_ex.h>
      23             : 
      24             : #include <com/sun/star/geometry/AffineMatrix2D.hpp>
      25             : #include <com/sun/star/geometry/Matrix2D.hpp>
      26             : #include <com/sun/star/awt/Rectangle.hpp>
      27             : #include <com/sun/star/util/Endianness.hpp>
      28             : #include <com/sun/star/rendering/XIntegerBitmapColorSpace.hpp>
      29             : #include <com/sun/star/rendering/IntegerBitmapLayout.hpp>
      30             : #include <com/sun/star/rendering/ColorSpaceType.hpp>
      31             : #include <com/sun/star/rendering/ColorComponentTag.hpp>
      32             : #include <com/sun/star/rendering/RenderingIntent.hpp>
      33             : #include <com/sun/star/rendering/RenderState.hpp>
      34             : #include <com/sun/star/rendering/ViewState.hpp>
      35             : #include <com/sun/star/rendering/XCanvas.hpp>
      36             : #include <com/sun/star/rendering/XColorSpace.hpp>
      37             : #include <com/sun/star/rendering/CompositeOperation.hpp>
      38             : #include <com/sun/star/beans/XPropertySet.hpp>
      39             : #include <com/sun/star/lang/XServiceInfo.hpp>
      40             : 
      41             : #include <basegfx/matrix/b2dhommatrix.hxx>
      42             : #include <basegfx/range/b2drange.hxx>
      43             : #include <basegfx/range/b2irange.hxx>
      44             : #include <basegfx/range/b2drectangle.hxx>
      45             : #include <basegfx/point/b2dpoint.hxx>
      46             : #include <basegfx/point/b2ipoint.hxx>
      47             : #include <basegfx/vector/b2ivector.hxx>
      48             : #include <basegfx/polygon/b2dpolygon.hxx>
      49             : #include <basegfx/polygon/b2dpolygontools.hxx>
      50             : #include <basegfx/polygon/b2dpolypolygontools.hxx>
      51             : #include <basegfx/tools/canvastools.hxx>
      52             : #include <basegfx/numeric/ftools.hxx>
      53             : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      54             : 
      55             : #include <cppuhelper/compbase1.hxx>
      56             : #include <rtl/instance.hxx>
      57             : #include <toolkit/helper/vclunohelper.hxx>
      58             : #include <vcl/window.hxx>
      59             : #include <vcl/canvastools.hxx>
      60             : 
      61             : #include <canvas/canvastools.hxx>
      62             : 
      63             : #include <limits>
      64             : 
      65             : 
      66             : using namespace ::com::sun::star;
      67             : 
      68             : namespace com { namespace sun { namespace star { namespace rendering
      69             : {
      70           0 :     bool operator==( const RenderState& renderState1,
      71             :                      const RenderState& renderState2 )
      72             :     {
      73           0 :         if( renderState1.Clip != renderState2.Clip )
      74           0 :             return false;
      75             : 
      76           0 :         if( renderState1.DeviceColor != renderState2.DeviceColor )
      77           0 :             return false;
      78             : 
      79           0 :         if( renderState1.CompositeOperation != renderState2.CompositeOperation )
      80           0 :             return false;
      81             : 
      82           0 :         ::basegfx::B2DHomMatrix mat1, mat2;
      83           0 :         ::canvas::tools::getRenderStateTransform( mat1, renderState1 );
      84           0 :         ::canvas::tools::getRenderStateTransform( mat2, renderState2 );
      85           0 :         if( mat1 != mat2 )
      86           0 :             return false;
      87             : 
      88           0 :         return true;
      89             :     }
      90             : 
      91           0 :     bool operator==( const ViewState& viewState1,
      92             :                      const ViewState& viewState2 )
      93             :     {
      94           0 :         if( viewState1.Clip != viewState2.Clip )
      95           0 :             return false;
      96             : 
      97           0 :         ::basegfx::B2DHomMatrix mat1, mat2;
      98           0 :         ::canvas::tools::getViewStateTransform( mat1, viewState1 );
      99           0 :         ::canvas::tools::getViewStateTransform( mat2, viewState2 );
     100           0 :         if( mat1 != mat2 )
     101           0 :             return false;
     102             : 
     103           0 :         return true;
     104             :     }
     105             : }}}}
     106             : 
     107             : namespace canvas
     108             : {
     109             :     namespace tools
     110             :     {
     111           0 :         geometry::RealSize2D createInfiniteSize2D()
     112             :         {
     113             :             return geometry::RealSize2D(
     114           0 :                 ::std::numeric_limits<double>::infinity(),
     115           0 :                 ::std::numeric_limits<double>::infinity() );
     116             :         }
     117             : 
     118           0 :         rendering::RenderState& initRenderState( rendering::RenderState& renderState )
     119             :         {
     120             :             // setup identity transform
     121           0 :             setIdentityAffineMatrix2D( renderState.AffineTransform );
     122           0 :             renderState.Clip = uno::Reference< rendering::XPolyPolygon2D >();
     123           0 :             renderState.DeviceColor = uno::Sequence< double >();
     124           0 :             renderState.CompositeOperation = rendering::CompositeOperation::OVER;
     125             : 
     126           0 :             return renderState;
     127             :         }
     128             : 
     129           0 :         rendering::ViewState& initViewState( rendering::ViewState& viewState )
     130             :         {
     131             :             // setup identity transform
     132           0 :             setIdentityAffineMatrix2D( viewState.AffineTransform );
     133           0 :             viewState.Clip = uno::Reference< rendering::XPolyPolygon2D >();
     134             : 
     135           0 :             return viewState;
     136             :         }
     137             : 
     138           0 :         ::basegfx::B2DHomMatrix& getViewStateTransform( ::basegfx::B2DHomMatrix&    transform,
     139             :                                                         const rendering::ViewState& viewState )
     140             :         {
     141           0 :             return ::basegfx::unotools::homMatrixFromAffineMatrix( transform, viewState.AffineTransform );
     142             :         }
     143             : 
     144           0 :         rendering::ViewState& setViewStateTransform( rendering::ViewState&          viewState,
     145             :                                                      const ::basegfx::B2DHomMatrix& transform )
     146             :         {
     147           0 :             ::basegfx::unotools::affineMatrixFromHomMatrix( viewState.AffineTransform, transform );
     148             : 
     149           0 :             return viewState;
     150             :         }
     151             : 
     152           0 :         ::basegfx::B2DHomMatrix& getRenderStateTransform( ::basegfx::B2DHomMatrix&      transform,
     153             :                                                           const rendering::RenderState& renderState )
     154             :         {
     155           0 :             return ::basegfx::unotools::homMatrixFromAffineMatrix( transform, renderState.AffineTransform );
     156             :         }
     157             : 
     158           0 :         rendering::RenderState& setRenderStateTransform( rendering::RenderState&        renderState,
     159             :                                                          const ::basegfx::B2DHomMatrix& transform )
     160             :         {
     161           0 :             ::basegfx::unotools::affineMatrixFromHomMatrix( renderState.AffineTransform, transform );
     162             : 
     163           0 :             return renderState;
     164             :         }
     165             : 
     166           0 :         rendering::RenderState& appendToRenderState( rendering::RenderState&        renderState,
     167             :                                                    const ::basegfx::B2DHomMatrix&   rTransform )
     168             :         {
     169           0 :             ::basegfx::B2DHomMatrix transform;
     170             : 
     171           0 :             getRenderStateTransform( transform, renderState );
     172           0 :             return setRenderStateTransform( renderState, transform * rTransform );
     173             :         }
     174             : 
     175           0 :         rendering::RenderState& prependToRenderState( rendering::RenderState&           renderState,
     176             :                                                       const ::basegfx::B2DHomMatrix&    rTransform )
     177             :         {
     178           0 :             ::basegfx::B2DHomMatrix transform;
     179             : 
     180           0 :             getRenderStateTransform( transform, renderState );
     181           0 :             return setRenderStateTransform( renderState, rTransform * transform );
     182             :         }
     183             : 
     184           0 :         ::basegfx::B2DHomMatrix& mergeViewAndRenderTransform( ::basegfx::B2DHomMatrix&      combinedTransform,
     185             :                                                               const rendering::ViewState&   viewState,
     186             :                                                               const rendering::RenderState& renderState )
     187             :         {
     188           0 :             ::basegfx::B2DHomMatrix viewTransform;
     189             : 
     190           0 :             ::basegfx::unotools::homMatrixFromAffineMatrix( combinedTransform, renderState.AffineTransform );
     191           0 :             ::basegfx::unotools::homMatrixFromAffineMatrix( viewTransform, viewState.AffineTransform );
     192             : 
     193             :             // this statement performs combinedTransform = viewTransform * combinedTransform
     194           0 :             combinedTransform *= viewTransform;
     195             : 
     196           0 :             return combinedTransform;
     197             :         }
     198             : 
     199           0 :         geometry::AffineMatrix2D& setIdentityAffineMatrix2D( geometry::AffineMatrix2D& matrix )
     200             :         {
     201           0 :             matrix.m00 = 1.0;
     202           0 :             matrix.m01 = 0.0;
     203           0 :             matrix.m02 = 0.0;
     204           0 :             matrix.m10 = 0.0;
     205           0 :             matrix.m11 = 1.0;
     206           0 :             matrix.m12 = 0.0;
     207             : 
     208           0 :             return matrix;
     209             :         }
     210             : 
     211           0 :         geometry::Matrix2D& setIdentityMatrix2D( geometry::Matrix2D& matrix )
     212             :         {
     213           0 :             matrix.m00 = 1.0;
     214           0 :             matrix.m01 = 0.0;
     215           0 :             matrix.m10 = 0.0;
     216           0 :             matrix.m11 = 1.0;
     217             : 
     218           0 :             return matrix;
     219             :         }
     220             : 
     221             :         namespace
     222             :         {
     223           0 :             class StandardColorSpace : public cppu::WeakImplHelper1< com::sun::star::rendering::XIntegerBitmapColorSpace >
     224             :             {
     225             :             private:
     226             :                 uno::Sequence< sal_Int8 >  maComponentTags;
     227             :                 uno::Sequence< sal_Int32 > maBitCounts;
     228             : 
     229           0 :                 virtual ::sal_Int8 SAL_CALL getType(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     230             :                 {
     231           0 :                     return rendering::ColorSpaceType::RGB;
     232             :                 }
     233           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     234             :                 {
     235           0 :                     return maComponentTags;
     236             :                 }
     237           0 :                 virtual ::sal_Int8 SAL_CALL getRenderingIntent(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     238             :                 {
     239           0 :                     return rendering::RenderingIntent::PERCEPTUAL;
     240             :                 }
     241           0 :                 virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     242             :                 {
     243           0 :                     return uno::Sequence< beans::PropertyValue >();
     244             :                 }
     245           0 :                 virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
     246             :                                                                             const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
     247             :                                                                                                                                                       uno::RuntimeException, std::exception) SAL_OVERRIDE
     248             :                 {
     249             :                     // TODO(P3): if we know anything about target
     250             :                     // colorspace, this can be greatly sped up
     251             :                     uno::Sequence<rendering::ARGBColor> aIntermediate(
     252           0 :                         convertToARGB(deviceColor));
     253           0 :                     return targetColorSpace->convertFromARGB(aIntermediate);
     254             :                 }
     255           0 :                 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     256             :                 {
     257           0 :                     const double*  pIn( deviceColor.getConstArray() );
     258           0 :                     const sal_Size nLen( deviceColor.getLength() );
     259           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     260             :                                          "number of channels no multiple of 4",
     261             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     262             : 
     263           0 :                     uno::Sequence< rendering::RGBColor > aRes(nLen/4);
     264           0 :                     rendering::RGBColor* pOut( aRes.getArray() );
     265           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     266             :                     {
     267           0 :                         *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
     268           0 :                         pIn += 4;
     269             :                     }
     270           0 :                     return aRes;
     271             :                 }
     272           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     273             :                 {
     274             :                     SAL_WARN_IF(deviceColor.getLength() == 0, "canvas", "empty deviceColor argument");
     275           0 :                     const double*  pIn( deviceColor.getConstArray() );
     276           0 :                     const sal_Size nLen( deviceColor.getLength() );
     277           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     278             :                                          "number of channels no multiple of 4",
     279             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     280             : 
     281           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     282           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     283           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     284             :                     {
     285           0 :                         *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]);
     286           0 :                         pIn += 4;
     287             :                     }
     288           0 :                     return aRes;
     289             :                 }
     290           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     291             :                 {
     292           0 :                     const double*  pIn( deviceColor.getConstArray() );
     293           0 :                     const sal_Size nLen( deviceColor.getLength() );
     294           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     295             :                                          "number of channels no multiple of 4",
     296             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     297             : 
     298           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     299           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     300           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     301             :                     {
     302           0 :                         *pOut++ = rendering::ARGBColor(pIn[3],pIn[3]*pIn[0],pIn[3]*pIn[1],pIn[3]*pIn[2]);
     303           0 :                         pIn += 4;
     304             :                     }
     305           0 :                     return aRes;
     306             :                 }
     307           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     308             :                 {
     309           0 :                     const rendering::RGBColor* pIn( rgbColor.getConstArray() );
     310           0 :                     const sal_Size             nLen( rgbColor.getLength() );
     311             : 
     312           0 :                     uno::Sequence< double > aRes(nLen*4);
     313           0 :                     double* pColors=aRes.getArray();
     314           0 :                     for( sal_Size i=0; i<nLen; ++i )
     315             :                     {
     316           0 :                         *pColors++ = pIn->Red;
     317           0 :                         *pColors++ = pIn->Green;
     318           0 :                         *pColors++ = pIn->Blue;
     319           0 :                         *pColors++ = 1.0;
     320           0 :                         ++pIn;
     321             :                     }
     322           0 :                     return aRes;
     323             :                 }
     324           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     325             :                 {
     326           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     327           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     328             : 
     329           0 :                     uno::Sequence< double > aRes(nLen*4);
     330           0 :                     double* pColors=aRes.getArray();
     331           0 :                     for( sal_Size i=0; i<nLen; ++i )
     332             :                     {
     333           0 :                         *pColors++ = pIn->Red;
     334           0 :                         *pColors++ = pIn->Green;
     335           0 :                         *pColors++ = pIn->Blue;
     336           0 :                         *pColors++ = pIn->Alpha;
     337           0 :                         ++pIn;
     338             :                     }
     339           0 :                     return aRes;
     340             :                 }
     341           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     342             :                 {
     343           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     344           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     345             : 
     346           0 :                     uno::Sequence< double > aRes(nLen*4);
     347           0 :                     double* pColors=aRes.getArray();
     348           0 :                     for( sal_Size i=0; i<nLen; ++i )
     349             :                     {
     350           0 :                         *pColors++ = pIn->Red/pIn->Alpha;
     351           0 :                         *pColors++ = pIn->Green/pIn->Alpha;
     352           0 :                         *pColors++ = pIn->Blue/pIn->Alpha;
     353           0 :                         *pColors++ = pIn->Alpha;
     354           0 :                         ++pIn;
     355             :                     }
     356           0 :                     return aRes;
     357             :                 }
     358             : 
     359             :                 // XIntegerBitmapColorSpace
     360           0 :                 virtual ::sal_Int32 SAL_CALL getBitsPerPixel(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     361             :                 {
     362           0 :                     return 32;
     363             :                 }
     364           0 :                 virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     365             :                 {
     366           0 :                     return maBitCounts;
     367             :                 }
     368           0 :                 virtual ::sal_Int8 SAL_CALL getEndianness(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     369             :                 {
     370           0 :                     return util::Endianness::LITTLE;
     371             :                 }
     372           0 :                 virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
     373             :                                                                                      const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
     374             :                                                                                                                                                                uno::RuntimeException, std::exception) SAL_OVERRIDE
     375             :                 {
     376           0 :                     if( dynamic_cast<StandardColorSpace*>(targetColorSpace.get()) )
     377             :                     {
     378           0 :                         const sal_Int8* pIn( deviceColor.getConstArray() );
     379           0 :                         const sal_Size  nLen( deviceColor.getLength() );
     380           0 :                         ENSURE_ARG_OR_THROW2(nLen%4==0,
     381             :                                              "number of channels no multiple of 4",
     382             :                                              static_cast<rendering::XColorSpace*>(this), 0);
     383             : 
     384           0 :                         uno::Sequence<double> aRes(nLen);
     385           0 :                         double* pOut( aRes.getArray() );
     386           0 :                         for( sal_Size i=0; i<nLen; i+=4 )
     387             :                         {
     388           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     389           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     390           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     391           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     392             :                         }
     393           0 :                         return aRes;
     394             :                     }
     395             :                     else
     396             :                     {
     397             :                         // TODO(P3): if we know anything about target
     398             :                         // colorspace, this can be greatly sped up
     399             :                         uno::Sequence<rendering::ARGBColor> aIntermediate(
     400           0 :                             convertIntegerToARGB(deviceColor));
     401           0 :                         return targetColorSpace->convertFromARGB(aIntermediate);
     402             :                     }
     403             :                 }
     404           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
     405             :                                                                                          const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
     406             :                                                                                                                                                                               uno::RuntimeException, std::exception) SAL_OVERRIDE
     407             :                 {
     408           0 :                     if( dynamic_cast<StandardColorSpace*>(targetColorSpace.get()) )
     409             :                     {
     410             :                         // it's us, so simply pass-through the data
     411           0 :                         return deviceColor;
     412             :                     }
     413             :                     else
     414             :                     {
     415             :                         // TODO(P3): if we know anything about target
     416             :                         // colorspace, this can be greatly sped up
     417             :                         uno::Sequence<rendering::ARGBColor> aIntermediate(
     418           0 :                             convertIntegerToARGB(deviceColor));
     419           0 :                         return targetColorSpace->convertIntegerFromARGB(aIntermediate);
     420             :                     }
     421             :                 }
     422           0 :                 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     423             :                 {
     424           0 :                     const sal_Int8* pIn( deviceColor.getConstArray() );
     425           0 :                     const sal_Size  nLen( deviceColor.getLength() );
     426           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     427             :                                          "number of channels no multiple of 4",
     428             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     429             : 
     430           0 :                     uno::Sequence< rendering::RGBColor > aRes(nLen/4);
     431           0 :                     rendering::RGBColor* pOut( aRes.getArray() );
     432           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     433             :                     {
     434             :                         *pOut++ = rendering::RGBColor(
     435           0 :                             vcl::unotools::toDoubleColor(pIn[0]),
     436           0 :                             vcl::unotools::toDoubleColor(pIn[1]),
     437           0 :                             vcl::unotools::toDoubleColor(pIn[2]));
     438           0 :                         pIn += 4;
     439             :                     }
     440           0 :                     return aRes;
     441             :                 }
     442             : 
     443           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     444             :                 {
     445           0 :                     const sal_Int8* pIn( deviceColor.getConstArray() );
     446           0 :                     const sal_Size  nLen( deviceColor.getLength() );
     447           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     448             :                                          "number of channels no multiple of 4",
     449             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     450             : 
     451           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     452           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     453           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     454             :                     {
     455             :                         *pOut++ = rendering::ARGBColor(
     456           0 :                             vcl::unotools::toDoubleColor(pIn[3]),
     457           0 :                             vcl::unotools::toDoubleColor(pIn[0]),
     458           0 :                             vcl::unotools::toDoubleColor(pIn[1]),
     459           0 :                             vcl::unotools::toDoubleColor(pIn[2]));
     460           0 :                         pIn += 4;
     461             :                     }
     462           0 :                     return aRes;
     463             :                 }
     464             : 
     465           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     466             :                 {
     467           0 :                     const sal_Int8* pIn( deviceColor.getConstArray() );
     468           0 :                     const sal_Size  nLen( deviceColor.getLength() );
     469           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     470             :                                          "number of channels no multiple of 4",
     471             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     472             : 
     473           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     474           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     475           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     476             :                     {
     477           0 :                         const sal_Int8 nAlpha( pIn[3] );
     478             :                         *pOut++ = rendering::ARGBColor(
     479           0 :                             vcl::unotools::toDoubleColor(nAlpha),
     480           0 :                             vcl::unotools::toDoubleColor(nAlpha*pIn[0]),
     481           0 :                             vcl::unotools::toDoubleColor(nAlpha*pIn[1]),
     482           0 :                             vcl::unotools::toDoubleColor(nAlpha*pIn[2]));
     483           0 :                         pIn += 4;
     484             :                     }
     485           0 :                     return aRes;
     486             :                 }
     487             : 
     488           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     489             :                 {
     490           0 :                     const rendering::RGBColor* pIn( rgbColor.getConstArray() );
     491           0 :                     const sal_Size             nLen( rgbColor.getLength() );
     492             : 
     493           0 :                     uno::Sequence< sal_Int8 > aRes(nLen*4);
     494           0 :                     sal_Int8* pColors=aRes.getArray();
     495           0 :                     for( sal_Size i=0; i<nLen; ++i )
     496             :                     {
     497           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Red);
     498           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Green);
     499           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
     500           0 :                         *pColors++ = 0;
     501           0 :                         ++pIn;
     502             :                     }
     503           0 :                     return aRes;
     504             :                 }
     505             : 
     506           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     507             :                 {
     508           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     509           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     510             : 
     511           0 :                     uno::Sequence< sal_Int8 > aRes(nLen*4);
     512           0 :                     sal_Int8* pColors=aRes.getArray();
     513           0 :                     for( sal_Size i=0; i<nLen; ++i )
     514             :                     {
     515           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Red);
     516           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Green);
     517           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
     518           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Alpha);
     519           0 :                         ++pIn;
     520             :                     }
     521           0 :                     return aRes;
     522             :                 }
     523             : 
     524           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     525             :                 {
     526           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     527           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     528             : 
     529           0 :                     uno::Sequence< sal_Int8 > aRes(nLen*4);
     530           0 :                     sal_Int8* pColors=aRes.getArray();
     531           0 :                     for( sal_Size i=0; i<nLen; ++i )
     532             :                     {
     533           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Red/pIn->Alpha);
     534           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Green/pIn->Alpha);
     535           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Blue/pIn->Alpha);
     536           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Alpha);
     537           0 :                         ++pIn;
     538             :                     }
     539           0 :                     return aRes;
     540             :                 }
     541             : 
     542             :             public:
     543           0 :                 StandardColorSpace() :
     544             :                     maComponentTags(4),
     545           0 :                     maBitCounts(4)
     546             :                 {
     547           0 :                     sal_Int8*  pTags = maComponentTags.getArray();
     548           0 :                     sal_Int32* pBitCounts = maBitCounts.getArray();
     549           0 :                     pTags[0] = rendering::ColorComponentTag::RGB_RED;
     550           0 :                     pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
     551           0 :                     pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
     552           0 :                     pTags[3] = rendering::ColorComponentTag::ALPHA;
     553             : 
     554             :                     pBitCounts[0] =
     555           0 :                     pBitCounts[1] =
     556           0 :                     pBitCounts[2] =
     557           0 :                     pBitCounts[3] = 8;
     558           0 :                 }
     559             :             };
     560             : 
     561           0 :             class StandardNoAlphaColorSpace : public cppu::WeakImplHelper1< com::sun::star::rendering::XIntegerBitmapColorSpace >
     562             :             {
     563             :             private:
     564             :                 uno::Sequence< sal_Int8 >  maComponentTags;
     565             :                 uno::Sequence< sal_Int32 > maBitCounts;
     566             : 
     567           0 :                 virtual ::sal_Int8 SAL_CALL getType(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     568             :                 {
     569           0 :                     return rendering::ColorSpaceType::RGB;
     570             :                 }
     571           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     572             :                 {
     573           0 :                     return maComponentTags;
     574             :                 }
     575           0 :                 virtual ::sal_Int8 SAL_CALL getRenderingIntent(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     576             :                 {
     577           0 :                     return rendering::RenderingIntent::PERCEPTUAL;
     578             :                 }
     579           0 :                 virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     580             :                 {
     581           0 :                     return uno::Sequence< beans::PropertyValue >();
     582             :                 }
     583           0 :                 virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
     584             :                                                                             const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
     585             :                                                                                                                                                       uno::RuntimeException, std::exception) SAL_OVERRIDE
     586             :                 {
     587             :                     // TODO(P3): if we know anything about target
     588             :                     // colorspace, this can be greatly sped up
     589             :                     uno::Sequence<rendering::ARGBColor> aIntermediate(
     590           0 :                         convertToARGB(deviceColor));
     591           0 :                     return targetColorSpace->convertFromARGB(aIntermediate);
     592             :                 }
     593           0 :                 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     594             :                 {
     595           0 :                     const double*  pIn( deviceColor.getConstArray() );
     596           0 :                     const sal_Size nLen( deviceColor.getLength() );
     597           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     598             :                                          "number of channels no multiple of 4",
     599             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     600             : 
     601           0 :                     uno::Sequence< rendering::RGBColor > aRes(nLen/4);
     602           0 :                     rendering::RGBColor* pOut( aRes.getArray() );
     603           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     604             :                     {
     605           0 :                         *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
     606           0 :                         pIn += 4;
     607             :                     }
     608           0 :                     return aRes;
     609             :                 }
     610           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     611             :                 {
     612           0 :                     const double*  pIn( deviceColor.getConstArray() );
     613           0 :                     const sal_Size nLen( deviceColor.getLength() );
     614           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     615             :                                          "number of channels no multiple of 4",
     616             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     617             : 
     618           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     619           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     620           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     621             :                     {
     622           0 :                         *pOut++ = rendering::ARGBColor(1.0,pIn[0],pIn[1],pIn[2]);
     623           0 :                         pIn += 4;
     624             :                     }
     625           0 :                     return aRes;
     626             :                 }
     627           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     628             :                 {
     629           0 :                     const double*  pIn( deviceColor.getConstArray() );
     630           0 :                     const sal_Size nLen( deviceColor.getLength() );
     631           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     632             :                                          "number of channels no multiple of 4",
     633             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     634             : 
     635           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     636           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     637           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     638             :                     {
     639           0 :                         *pOut++ = rendering::ARGBColor(1.0,pIn[0],pIn[1],pIn[2]);
     640           0 :                         pIn += 4;
     641             :                     }
     642           0 :                     return aRes;
     643             :                 }
     644           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     645             :                 {
     646           0 :                     const rendering::RGBColor* pIn( rgbColor.getConstArray() );
     647           0 :                     const sal_Size             nLen( rgbColor.getLength() );
     648             : 
     649           0 :                     uno::Sequence< double > aRes(nLen*4);
     650           0 :                     double* pColors=aRes.getArray();
     651           0 :                     for( sal_Size i=0; i<nLen; ++i )
     652             :                     {
     653           0 :                         *pColors++ = pIn->Red;
     654           0 :                         *pColors++ = pIn->Green;
     655           0 :                         *pColors++ = pIn->Blue;
     656           0 :                         *pColors++ = 1.0; // the value does not matter
     657           0 :                         ++pIn;
     658             :                     }
     659           0 :                     return aRes;
     660             :                 }
     661           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     662             :                 {
     663           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     664           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     665             : 
     666           0 :                     uno::Sequence< double > aRes(nLen*4);
     667           0 :                     double* pColors=aRes.getArray();
     668           0 :                     for( sal_Size i=0; i<nLen; ++i )
     669             :                     {
     670           0 :                         *pColors++ = pIn->Red;
     671           0 :                         *pColors++ = pIn->Green;
     672           0 :                         *pColors++ = pIn->Blue;
     673           0 :                         *pColors++ = 1.0; // the value does not matter
     674           0 :                         ++pIn;
     675             :                     }
     676           0 :                     return aRes;
     677             :                 }
     678           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     679             :                 {
     680           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     681           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     682             : 
     683           0 :                     uno::Sequence< double > aRes(nLen*4);
     684           0 :                     double* pColors=aRes.getArray();
     685           0 :                     for( sal_Size i=0; i<nLen; ++i )
     686             :                     {
     687           0 :                         *pColors++ = pIn->Red/pIn->Alpha;
     688           0 :                         *pColors++ = pIn->Green/pIn->Alpha;
     689           0 :                         *pColors++ = pIn->Blue/pIn->Alpha;
     690           0 :                         *pColors++ = 1.0; // the value does not matter
     691           0 :                         ++pIn;
     692             :                     }
     693           0 :                     return aRes;
     694             :                 }
     695             : 
     696             :                 // XIntegerBitmapColorSpace
     697           0 :                 virtual ::sal_Int32 SAL_CALL getBitsPerPixel(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     698             :                 {
     699           0 :                     return 32;
     700             :                 }
     701           0 :                 virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     702             :                 {
     703           0 :                     return maBitCounts;
     704             :                 }
     705           0 :                 virtual ::sal_Int8 SAL_CALL getEndianness(  ) throw (uno::RuntimeException, std::exception) SAL_OVERRIDE
     706             :                 {
     707           0 :                     return util::Endianness::LITTLE;
     708             :                 }
     709           0 :                 virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
     710             :                                                                                      const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
     711             :                                                                                                                                                                uno::RuntimeException, std::exception) SAL_OVERRIDE
     712             :                 {
     713           0 :                     if( dynamic_cast<StandardNoAlphaColorSpace*>(targetColorSpace.get()) )
     714             :                     {
     715           0 :                         const sal_Int8* pIn( deviceColor.getConstArray() );
     716           0 :                         const sal_Size  nLen( deviceColor.getLength() );
     717           0 :                         ENSURE_ARG_OR_THROW2(nLen%4==0,
     718             :                                              "number of channels no multiple of 4",
     719             :                                              static_cast<rendering::XColorSpace*>(this), 0);
     720             : 
     721           0 :                         uno::Sequence<double> aRes(nLen);
     722           0 :                         double* pOut( aRes.getArray() );
     723           0 :                         for( sal_Size i=0; i<nLen; i+=4 )
     724             :                         {
     725           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     726           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     727           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     728           0 :                             *pOut++ = 1.0;
     729             :                         }
     730           0 :                         return aRes;
     731             :                     }
     732             :                     else
     733             :                     {
     734             :                         // TODO(P3): if we know anything about target
     735             :                         // colorspace, this can be greatly sped up
     736             :                         uno::Sequence<rendering::ARGBColor> aIntermediate(
     737           0 :                             convertIntegerToARGB(deviceColor));
     738           0 :                         return targetColorSpace->convertFromARGB(aIntermediate);
     739             :                     }
     740             :                 }
     741           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
     742             :                                                                                          const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
     743             :                                                                                                                                                                               uno::RuntimeException, std::exception) SAL_OVERRIDE
     744             :                 {
     745           0 :                     if( dynamic_cast<StandardNoAlphaColorSpace*>(targetColorSpace.get()) )
     746             :                     {
     747             :                         // it's us, so simply pass-through the data
     748           0 :                         return deviceColor;
     749             :                     }
     750             :                     else
     751             :                     {
     752             :                         // TODO(P3): if we know anything about target
     753             :                         // colorspace, this can be greatly sped up
     754             :                         uno::Sequence<rendering::ARGBColor> aIntermediate(
     755           0 :                             convertIntegerToARGB(deviceColor));
     756           0 :                         return targetColorSpace->convertIntegerFromARGB(aIntermediate);
     757             :                     }
     758             :                 }
     759           0 :                 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     760             :                 {
     761           0 :                     const sal_Int8* pIn( deviceColor.getConstArray() );
     762           0 :                     const sal_Size  nLen( deviceColor.getLength() );
     763           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     764             :                                          "number of channels no multiple of 4",
     765             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     766             : 
     767           0 :                     uno::Sequence< rendering::RGBColor > aRes(nLen/4);
     768           0 :                     rendering::RGBColor* pOut( aRes.getArray() );
     769           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     770             :                     {
     771             :                         *pOut++ = rendering::RGBColor(
     772           0 :                             vcl::unotools::toDoubleColor(pIn[0]),
     773           0 :                             vcl::unotools::toDoubleColor(pIn[1]),
     774           0 :                             vcl::unotools::toDoubleColor(pIn[2]));
     775           0 :                         pIn += 4;
     776             :                     }
     777           0 :                     return aRes;
     778             :                 }
     779             : 
     780           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     781             :                 {
     782           0 :                     const sal_Int8* pIn( deviceColor.getConstArray() );
     783           0 :                     const sal_Size  nLen( deviceColor.getLength() );
     784           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     785             :                                          "number of channels no multiple of 4",
     786             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     787             : 
     788           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     789           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     790           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     791             :                     {
     792             :                         *pOut++ = rendering::ARGBColor(
     793             :                             1.0,
     794           0 :                             vcl::unotools::toDoubleColor(pIn[0]),
     795           0 :                             vcl::unotools::toDoubleColor(pIn[1]),
     796           0 :                             vcl::unotools::toDoubleColor(pIn[2]));
     797           0 :                         pIn += 4;
     798             :                     }
     799           0 :                     return aRes;
     800             :                 }
     801             : 
     802           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     803             :                 {
     804           0 :                     const sal_Int8* pIn( deviceColor.getConstArray() );
     805           0 :                     const sal_Size  nLen( deviceColor.getLength() );
     806           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     807             :                                          "number of channels no multiple of 4",
     808             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     809             : 
     810           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     811           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     812           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     813             :                     {
     814             :                         *pOut++ = rendering::ARGBColor(
     815             :                             1.0,
     816           0 :                             vcl::unotools::toDoubleColor(pIn[0]),
     817           0 :                             vcl::unotools::toDoubleColor(pIn[1]),
     818           0 :                             vcl::unotools::toDoubleColor(pIn[2]));
     819           0 :                         pIn += 4;
     820             :                     }
     821           0 :                     return aRes;
     822             :                 }
     823             : 
     824           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     825             :                 {
     826           0 :                     const rendering::RGBColor* pIn( rgbColor.getConstArray() );
     827           0 :                     const sal_Size             nLen( rgbColor.getLength() );
     828             : 
     829           0 :                     uno::Sequence< sal_Int8 > aRes(nLen*4);
     830           0 :                     sal_Int8* pColors=aRes.getArray();
     831           0 :                     for( sal_Size i=0; i<nLen; ++i )
     832             :                     {
     833           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Red);
     834           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Green);
     835           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
     836           0 :                         *pColors++ = 1.0;
     837           0 :                         ++pIn;
     838             :                     }
     839           0 :                     return aRes;
     840             :                 }
     841             : 
     842           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     843             :                 {
     844           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     845           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     846             : 
     847           0 :                     uno::Sequence< sal_Int8 > aRes(nLen*4);
     848           0 :                     sal_Int8* pColors=aRes.getArray();
     849           0 :                     for( sal_Size i=0; i<nLen; ++i )
     850             :                     {
     851           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Red);
     852           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Green);
     853           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
     854           0 :                         *pColors++ = -1;
     855           0 :                         ++pIn;
     856             :                     }
     857           0 :                     return aRes;
     858             :                 }
     859             : 
     860           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException, std::exception) SAL_OVERRIDE
     861             :                 {
     862           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     863           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     864             : 
     865           0 :                     uno::Sequence< sal_Int8 > aRes(nLen*4);
     866           0 :                     sal_Int8* pColors=aRes.getArray();
     867           0 :                     for( sal_Size i=0; i<nLen; ++i )
     868             :                     {
     869           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Red/pIn->Alpha);
     870           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Green/pIn->Alpha);
     871           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Blue/pIn->Alpha);
     872           0 :                         *pColors++ = -1;
     873           0 :                         ++pIn;
     874             :                     }
     875           0 :                     return aRes;
     876             :                 }
     877             : 
     878             :             public:
     879           0 :                 StandardNoAlphaColorSpace() :
     880             :                     maComponentTags(3),
     881           0 :                     maBitCounts(3)
     882             :                 {
     883           0 :                     sal_Int8*  pTags = maComponentTags.getArray();
     884           0 :                     sal_Int32* pBitCounts = maBitCounts.getArray();
     885           0 :                     pTags[0] = rendering::ColorComponentTag::RGB_RED;
     886           0 :                     pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
     887           0 :                     pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
     888             : 
     889             :                     pBitCounts[0] =
     890           0 :                     pBitCounts[1] =
     891           0 :                     pBitCounts[2] = 8;
     892           0 :                 }
     893             :             };
     894             : 
     895             :             struct StandardColorSpaceHolder : public rtl::StaticWithInit<uno::Reference<rendering::XIntegerBitmapColorSpace>,
     896             :                                                                          StandardColorSpaceHolder>
     897             :             {
     898           0 :                 uno::Reference<rendering::XIntegerBitmapColorSpace> operator()()
     899             :                 {
     900           0 :                     return new StandardColorSpace();
     901             :                 }
     902             :             };
     903             : 
     904             :             struct StandardNoAlphaColorSpaceHolder : public rtl::StaticWithInit<uno::Reference<rendering::XIntegerBitmapColorSpace>,
     905             :                                                                          StandardNoAlphaColorSpaceHolder>
     906             :             {
     907           0 :                 uno::Reference<rendering::XIntegerBitmapColorSpace> operator()()
     908             :                 {
     909           0 :                     return new StandardNoAlphaColorSpace();
     910             :                 }
     911             :             };
     912             :         }
     913             : 
     914           0 :         uno::Reference<rendering::XIntegerBitmapColorSpace> getStdColorSpace()
     915             :         {
     916           0 :             return StandardColorSpaceHolder::get();
     917             :         }
     918             : 
     919           0 :         uno::Reference<rendering::XIntegerBitmapColorSpace> getStdColorSpaceWithoutAlpha()
     920             :         {
     921           0 :             return StandardNoAlphaColorSpaceHolder::get();
     922             :         }
     923             : 
     924           0 :         rendering::IntegerBitmapLayout getStdMemoryLayout( const geometry::IntegerSize2D& rBmpSize )
     925             :         {
     926           0 :             rendering::IntegerBitmapLayout aLayout;
     927             : 
     928           0 :             aLayout.ScanLines = rBmpSize.Height;
     929           0 :             aLayout.ScanLineBytes = rBmpSize.Width*4;
     930           0 :             aLayout.ScanLineStride = aLayout.ScanLineBytes;
     931           0 :             aLayout.PlaneStride = 0;
     932           0 :             aLayout.ColorSpace = getStdColorSpace();
     933           0 :             aLayout.Palette.clear();
     934           0 :             aLayout.IsMsbFirst = sal_False;
     935             : 
     936           0 :             return aLayout;
     937             :         }
     938             : 
     939           0 :         ::Color stdIntSequenceToColor( const uno::Sequence<sal_Int8>& rColor )
     940             :         {
     941             : #ifdef OSL_BIGENDIAN
     942             :             const sal_Int8* pCols( rColor.getConstArray() );
     943             :             return ::Color( pCols[3], pCols[0], pCols[1], pCols[2] );
     944             : #else
     945           0 :             return ::Color( *reinterpret_cast< const ::ColorData* >(rColor.getConstArray()) );
     946             : #endif
     947             :         }
     948             : 
     949           0 :         uno::Sequence<sal_Int8> colorToStdIntSequence( const ::Color& rColor )
     950             :         {
     951           0 :             uno::Sequence<sal_Int8> aRet(4);
     952           0 :             sal_Int8* pCols( aRet.getArray() );
     953             : #ifdef OSL_BIGENDIAN
     954             :             pCols[0] = rColor.GetRed();
     955             :             pCols[1] = rColor.GetGreen();
     956             :             pCols[2] = rColor.GetBlue();
     957             :             pCols[3] = 255-rColor.GetTransparency();
     958             : #else
     959           0 :             *reinterpret_cast<sal_Int32*>(pCols) = rColor.GetColor();
     960             : #endif
     961           0 :             return aRet;
     962             :         }
     963             : 
     964             :         // Create a corrected view transformation out of the give one,
     965             :         // which ensures that the rectangle given by (0,0) and
     966             :         // rSpriteSize is mapped with its left,top corner to (0,0)
     967             :         // again. This is required to properly render sprite
     968             :         // animations to buffer bitmaps.
     969           0 :         ::basegfx::B2DHomMatrix& calcRectToOriginTransform( ::basegfx::B2DHomMatrix&            o_transform,
     970             :                                                             const ::basegfx::B2DRange&          i_srcRect,
     971             :                                                             const ::basegfx::B2DHomMatrix&      i_transformation )
     972             :         {
     973           0 :             if( i_srcRect.isEmpty() )
     974           0 :                 return o_transform=i_transformation;
     975             : 
     976             :             // transform by given transformation
     977           0 :             ::basegfx::B2DRectangle aTransformedRect;
     978             : 
     979             :             calcTransformedRectBounds( aTransformedRect,
     980             :                                        i_srcRect,
     981           0 :                                        i_transformation );
     982             : 
     983             :             // now move resulting left,top point of bounds to (0,0)
     984             :             const basegfx::B2DHomMatrix aCorrectedTransform(basegfx::tools::createTranslateB2DHomMatrix(
     985           0 :                 -aTransformedRect.getMinX(), -aTransformedRect.getMinY()));
     986             : 
     987             :             // prepend to original transformation
     988           0 :             o_transform = aCorrectedTransform * i_transformation;
     989             : 
     990           0 :             return o_transform;
     991             :         }
     992             : 
     993           0 :         ::basegfx::B2DRange& calcTransformedRectBounds( ::basegfx::B2DRange&            outRect,
     994             :                                                         const ::basegfx::B2DRange&      inRect,
     995             :                                                         const ::basegfx::B2DHomMatrix&  transformation )
     996             :         {
     997           0 :             outRect.reset();
     998             : 
     999           0 :             if( inRect.isEmpty() )
    1000           0 :                 return outRect;
    1001             : 
    1002             :             // transform all four extremal points of the rectangle,
    1003             :             // take bounding rect of those.
    1004             : 
    1005             :             // transform left-top point
    1006           0 :             outRect.expand( transformation * inRect.getMinimum() );
    1007             : 
    1008             :             // transform bottom-right point
    1009           0 :             outRect.expand( transformation * inRect.getMaximum() );
    1010             : 
    1011           0 :             ::basegfx::B2DPoint aPoint;
    1012             : 
    1013             :             // transform top-right point
    1014           0 :             aPoint.setX( inRect.getMaxX() );
    1015           0 :             aPoint.setY( inRect.getMinY() );
    1016             : 
    1017           0 :             aPoint *= transformation;
    1018           0 :             outRect.expand( aPoint );
    1019             : 
    1020             :             // transform bottom-left point
    1021           0 :             aPoint.setX( inRect.getMinX() );
    1022           0 :             aPoint.setY( inRect.getMaxY() );
    1023             : 
    1024           0 :             aPoint *= transformation;
    1025           0 :             outRect.expand( aPoint );
    1026             : 
    1027             :             // over and out.
    1028           0 :             return outRect;
    1029             :         }
    1030             : 
    1031           0 :         bool isInside( const ::basegfx::B2DRange&       rContainedRect,
    1032             :                        const ::basegfx::B2DRange&       rTransformRect,
    1033             :                        const ::basegfx::B2DHomMatrix&   rTransformation )
    1034             :         {
    1035           0 :             if( rContainedRect.isEmpty() || rTransformRect.isEmpty() )
    1036           0 :                 return false;
    1037             : 
    1038             :             ::basegfx::B2DPolygon aPoly(
    1039           0 :                 ::basegfx::tools::createPolygonFromRect( rTransformRect ) );
    1040           0 :             aPoly.transform( rTransformation );
    1041             : 
    1042             :             return ::basegfx::tools::isInside( aPoly,
    1043             :                                                ::basegfx::tools::createPolygonFromRect(
    1044             :                                                    rContainedRect ),
    1045           0 :                                                true );
    1046             :         }
    1047             : 
    1048             :         namespace
    1049             :         {
    1050           0 :             bool clipAreaImpl( ::basegfx::B2IRange*       o_pDestArea,
    1051             :                                ::basegfx::B2IRange&       io_rSourceArea,
    1052             :                                ::basegfx::B2IPoint&       io_rDestPoint,
    1053             :                                const ::basegfx::B2IRange& rSourceBounds,
    1054             :                                const ::basegfx::B2IRange& rDestBounds )
    1055             :             {
    1056             :                 const ::basegfx::B2IPoint aSourceTopLeft(
    1057           0 :                     io_rSourceArea.getMinimum() );
    1058             : 
    1059           0 :                 ::basegfx::B2IRange aLocalSourceArea( io_rSourceArea );
    1060             : 
    1061             :                 // clip source area (which must be inside rSourceBounds)
    1062           0 :                 aLocalSourceArea.intersect( rSourceBounds );
    1063             : 
    1064           0 :                 if( aLocalSourceArea.isEmpty() )
    1065           0 :                     return false;
    1066             : 
    1067             :                 // calc relative new source area points (relative to orig
    1068             :                 // source area)
    1069             :                 const ::basegfx::B2IVector aUpperLeftOffset(
    1070           0 :                     aLocalSourceArea.getMinimum()-aSourceTopLeft );
    1071             :                 const ::basegfx::B2IVector aLowerRightOffset(
    1072           0 :                     aLocalSourceArea.getMaximum()-aSourceTopLeft );
    1073             : 
    1074           0 :                 ::basegfx::B2IRange aLocalDestArea( io_rDestPoint + aUpperLeftOffset,
    1075           0 :                                                     io_rDestPoint + aLowerRightOffset );
    1076             : 
    1077             :                 // clip dest area (which must be inside rDestBounds)
    1078           0 :                 aLocalDestArea.intersect( rDestBounds );
    1079             : 
    1080           0 :                 if( aLocalDestArea.isEmpty() )
    1081           0 :                     return false;
    1082             : 
    1083             :                 // calc relative new dest area points (relative to orig
    1084             :                 // source area)
    1085             :                 const ::basegfx::B2IVector aDestUpperLeftOffset(
    1086           0 :                     aLocalDestArea.getMinimum()-io_rDestPoint );
    1087             :                 const ::basegfx::B2IVector aDestLowerRightOffset(
    1088           0 :                     aLocalDestArea.getMaximum()-io_rDestPoint );
    1089             : 
    1090           0 :                 io_rSourceArea = ::basegfx::B2IRange( aSourceTopLeft + aDestUpperLeftOffset,
    1091           0 :                                                       aSourceTopLeft + aDestLowerRightOffset );
    1092           0 :                 io_rDestPoint  = aLocalDestArea.getMinimum();
    1093             : 
    1094           0 :                 if( o_pDestArea )
    1095           0 :                     *o_pDestArea = aLocalDestArea;
    1096             : 
    1097           0 :                 return true;
    1098             :             }
    1099             :         }
    1100             : 
    1101           0 :         bool clipScrollArea( ::basegfx::B2IRange&                  io_rSourceArea,
    1102             :                              ::basegfx::B2IPoint&                  io_rDestPoint,
    1103             :                              ::std::vector< ::basegfx::B2IRange >& o_ClippedAreas,
    1104             :                              const ::basegfx::B2IRange&            rBounds )
    1105             :         {
    1106           0 :             ::basegfx::B2IRange aResultingDestArea;
    1107             : 
    1108             :             // compute full destination area (to determine uninitialized
    1109             :             // areas below)
    1110           0 :             const ::basegfx::B2I64Tuple& rRange( io_rSourceArea.getRange() );
    1111             :             ::basegfx::B2IRange aInputDestArea( io_rDestPoint.getX(),
    1112             :                                                 io_rDestPoint.getY(),
    1113           0 :                                                 (io_rDestPoint.getX()
    1114           0 :                                                  + static_cast<sal_Int32>(rRange.getX())),
    1115           0 :                                                 (io_rDestPoint.getY()
    1116           0 :                                                  + static_cast<sal_Int32>(rRange.getY())) );
    1117             :             // limit to output area (no point updating outside of it)
    1118           0 :             aInputDestArea.intersect( rBounds );
    1119             : 
    1120             :             // clip to rBounds
    1121           0 :             if( !clipAreaImpl( &aResultingDestArea,
    1122             :                                io_rSourceArea,
    1123             :                                io_rDestPoint,
    1124             :                                rBounds,
    1125           0 :                                rBounds ) )
    1126           0 :                 return false;
    1127             : 
    1128             :             // finally, compute all areas clipped off the total
    1129             :             // destination area.
    1130             :             ::basegfx::computeSetDifference( o_ClippedAreas,
    1131             :                                              aInputDestArea,
    1132           0 :                                              aResultingDestArea );
    1133             : 
    1134           0 :             return true;
    1135             :         }
    1136             : 
    1137           0 :         ::basegfx::B2IRange spritePixelAreaFromB2DRange( const ::basegfx::B2DRange& rRange )
    1138             :         {
    1139           0 :             if( rRange.isEmpty() )
    1140           0 :                 return ::basegfx::B2IRange();
    1141             : 
    1142             :             const ::basegfx::B2IPoint aTopLeft( ::basegfx::fround( rRange.getMinX() ),
    1143           0 :                                                 ::basegfx::fround( rRange.getMinY() ) );
    1144             :             return ::basegfx::B2IRange( aTopLeft,
    1145           0 :                                         aTopLeft + ::basegfx::B2IPoint(
    1146             :                                             ::basegfx::fround( rRange.getWidth() ),
    1147           0 :                                             ::basegfx::fround( rRange.getHeight() ) ) );
    1148             :         }
    1149             : 
    1150           0 :         uno::Sequence< uno::Any >& getDeviceInfo( const uno::Reference< rendering::XCanvas >& i_rxCanvas,
    1151             :                                                   uno::Sequence< uno::Any >&                  o_rxParams )
    1152             :         {
    1153           0 :             o_rxParams.realloc( 0 );
    1154             : 
    1155           0 :             if( i_rxCanvas.is() )
    1156             :             {
    1157             :                 try
    1158             :                 {
    1159           0 :                     uno::Reference< rendering::XGraphicDevice > xDevice( i_rxCanvas->getDevice(),
    1160           0 :                                                                          uno::UNO_QUERY_THROW );
    1161             : 
    1162             :                     uno::Reference< lang::XServiceInfo >  xServiceInfo( xDevice,
    1163           0 :                                                                         uno::UNO_QUERY_THROW );
    1164             :                     uno::Reference< beans::XPropertySet > xPropSet( xDevice,
    1165           0 :                                                                     uno::UNO_QUERY_THROW );
    1166             : 
    1167           0 :                     o_rxParams.realloc( 2 );
    1168             : 
    1169           0 :                     o_rxParams[ 0 ] = uno::makeAny( xServiceInfo->getImplementationName() );
    1170           0 :                     o_rxParams[ 1 ] = uno::makeAny( xPropSet->getPropertyValue( "DeviceHandle" ) );
    1171             :                 }
    1172           0 :                 catch( const uno::Exception& )
    1173             :                 {
    1174             :                     // ignore, but return empty sequence
    1175             :                 }
    1176             :             }
    1177             : 
    1178           0 :             return o_rxParams;
    1179             :         }
    1180             : 
    1181           0 :         awt::Rectangle getAbsoluteWindowRect( const awt::Rectangle&                  rRect,
    1182             :                                               const uno::Reference< awt::XWindow2 >& xWin  )
    1183             :         {
    1184           0 :             awt::Rectangle aRetVal( rRect );
    1185             : 
    1186           0 :             vcl::Window* pWindow = VCLUnoHelper::GetWindow(xWin);
    1187           0 :             if( pWindow )
    1188             :             {
    1189             :                 ::Point aPoint( aRetVal.X,
    1190           0 :                                 aRetVal.Y );
    1191             : 
    1192           0 :                 aPoint = pWindow->OutputToScreenPixel( aPoint );
    1193             : 
    1194           0 :                 aRetVal.X = aPoint.X();
    1195           0 :                 aRetVal.Y = aPoint.Y();
    1196             :             }
    1197             : 
    1198           0 :             return aRetVal;
    1199             :         }
    1200             : 
    1201           0 :         ::basegfx::B2DPolyPolygon getBoundMarksPolyPolygon( const ::basegfx::B2DRange& rRange )
    1202             :         {
    1203           0 :             ::basegfx::B2DPolyPolygon aPolyPoly;
    1204           0 :             ::basegfx::B2DPolygon     aPoly;
    1205             : 
    1206           0 :             const double nX0( rRange.getMinX() );
    1207           0 :             const double nY0( rRange.getMinY() );
    1208           0 :             const double nX1( rRange.getMaxX() );
    1209           0 :             const double nY1( rRange.getMaxY() );
    1210             : 
    1211             :             aPoly.append( ::basegfx::B2DPoint( nX0+4,
    1212           0 :                                                nY0 ) );
    1213             :             aPoly.append( ::basegfx::B2DPoint( nX0,
    1214           0 :                                                nY0 ) );
    1215             :             aPoly.append( ::basegfx::B2DPoint( nX0,
    1216           0 :                                                nY0+4 ) );
    1217           0 :             aPolyPoly.append( aPoly ); aPoly.clear();
    1218             : 
    1219             :             aPoly.append( ::basegfx::B2DPoint( nX1-4,
    1220           0 :                                                nY0 ) );
    1221             :             aPoly.append( ::basegfx::B2DPoint( nX1,
    1222           0 :                                                nY0 ) );
    1223             :             aPoly.append( ::basegfx::B2DPoint( nX1,
    1224           0 :                                                nY0+4 ) );
    1225           0 :             aPolyPoly.append( aPoly ); aPoly.clear();
    1226             : 
    1227             :             aPoly.append( ::basegfx::B2DPoint( nX0+4,
    1228           0 :                                                nY1 ) );
    1229             :             aPoly.append( ::basegfx::B2DPoint( nX0,
    1230           0 :                                                nY1 ) );
    1231             :             aPoly.append( ::basegfx::B2DPoint( nX0,
    1232           0 :                                                nY1-4 ) );
    1233           0 :             aPolyPoly.append( aPoly ); aPoly.clear();
    1234             : 
    1235             :             aPoly.append( ::basegfx::B2DPoint( nX1-4,
    1236           0 :                                                nY1 ) );
    1237             :             aPoly.append( ::basegfx::B2DPoint( nX1,
    1238           0 :                                                nY1 ) );
    1239             :             aPoly.append( ::basegfx::B2DPoint( nX1,
    1240           0 :                                                nY1-4 ) );
    1241           0 :             aPolyPoly.append( aPoly );
    1242             : 
    1243           0 :             return aPolyPoly;
    1244             :         }
    1245             : 
    1246           0 :         int calcGradientStepCount( ::basegfx::B2DHomMatrix&      rTotalTransform,
    1247             :                                    const rendering::ViewState&   viewState,
    1248             :                                    const rendering::RenderState& renderState,
    1249             :                                    const rendering::Texture&     texture,
    1250             :                                    int                           nColorSteps )
    1251             :         {
    1252             :             // calculate overall texture transformation (directly from
    1253             :             // texture to device space).
    1254           0 :             ::basegfx::B2DHomMatrix aMatrix;
    1255             : 
    1256           0 :             rTotalTransform.identity();
    1257             :             ::basegfx::unotools::homMatrixFromAffineMatrix( rTotalTransform,
    1258           0 :                                                             texture.AffineTransform );
    1259             :             ::canvas::tools::mergeViewAndRenderTransform(aMatrix,
    1260             :                                                          viewState,
    1261           0 :                                                          renderState);
    1262           0 :             rTotalTransform *= aMatrix; // prepend total view/render transformation
    1263             : 
    1264             :             // determine size of gradient in device coordinate system
    1265             :             // (to e.g. determine sensible number of gradient steps)
    1266           0 :             ::basegfx::B2DPoint aLeftTop( 0.0, 0.0 );
    1267           0 :             ::basegfx::B2DPoint aLeftBottom( 0.0, 1.0 );
    1268           0 :             ::basegfx::B2DPoint aRightTop( 1.0, 0.0 );
    1269           0 :             ::basegfx::B2DPoint aRightBottom( 1.0, 1.0 );
    1270             : 
    1271           0 :             aLeftTop    *= rTotalTransform;
    1272           0 :             aLeftBottom *= rTotalTransform;
    1273           0 :             aRightTop   *= rTotalTransform;
    1274           0 :             aRightBottom*= rTotalTransform;
    1275             : 
    1276             :             // longest line in gradient bound rect
    1277             :             const int nGradientSize(
    1278             :                 static_cast<int>(
    1279             :                     ::std::max(
    1280           0 :                         ::basegfx::B2DVector(aRightBottom-aLeftTop).getLength(),
    1281           0 :                         ::basegfx::B2DVector(aRightTop-aLeftBottom).getLength() ) + 1.0 ) );
    1282             : 
    1283             :             // typical number for pixel of the same color (strip size)
    1284           0 :             const int nStripSize( nGradientSize < 50 ? 2 : 4 );
    1285             : 
    1286             :             // use at least three steps, and at utmost the number of color
    1287             :             // steps
    1288             :             return ::std::max( 3,
    1289             :                                ::std::min(
    1290           0 :                                    nGradientSize / nStripSize,
    1291           0 :                                    nColorSteps ) );
    1292             :         }
    1293             : 
    1294             :     } // namespace tools
    1295             : 
    1296        1143 : } // namespace canvas
    1297             : 
    1298             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10