LCOV - code coverage report
Current view: top level - libreoffice/canvas/source/tools - canvastools.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 0 606 0.0 %
Date: 2012-12-27 Functions: 0 81 0.0 %
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)
     230             :                 {
     231           0 :                     return rendering::ColorSpaceType::RGB;
     232             :                 }
     233           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags(  ) throw (uno::RuntimeException)
     234             :                 {
     235           0 :                     return maComponentTags;
     236             :                 }
     237           0 :                 virtual ::sal_Int8 SAL_CALL getRenderingIntent(  ) throw (uno::RuntimeException)
     238             :                 {
     239           0 :                     return rendering::RenderingIntent::PERCEPTUAL;
     240             :                 }
     241           0 :                 virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties(  ) throw (uno::RuntimeException)
     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)
     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)
     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)
     273             :                 {
     274           0 :                     const double*  pIn( deviceColor.getConstArray() );
     275           0 :                     const sal_Size nLen( deviceColor.getLength() );
     276           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     277             :                                          "number of channels no multiple of 4",
     278             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     279             : 
     280           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     281           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     282           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     283             :                     {
     284           0 :                         *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]);
     285           0 :                         pIn += 4;
     286             :                     }
     287           0 :                     return aRes;
     288             :                 }
     289           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     290             :                 {
     291           0 :                     const double*  pIn( deviceColor.getConstArray() );
     292           0 :                     const sal_Size nLen( deviceColor.getLength() );
     293           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     294             :                                          "number of channels no multiple of 4",
     295             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     296             : 
     297           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     298           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     299           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     300             :                     {
     301           0 :                         *pOut++ = rendering::ARGBColor(pIn[3],pIn[3]*pIn[0],pIn[3]*pIn[1],pIn[3]*pIn[2]);
     302           0 :                         pIn += 4;
     303             :                     }
     304           0 :                     return aRes;
     305             :                 }
     306           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     307             :                 {
     308           0 :                     const rendering::RGBColor* pIn( rgbColor.getConstArray() );
     309           0 :                     const sal_Size             nLen( rgbColor.getLength() );
     310             : 
     311           0 :                     uno::Sequence< double > aRes(nLen*4);
     312           0 :                     double* pColors=aRes.getArray();
     313           0 :                     for( sal_Size i=0; i<nLen; ++i )
     314             :                     {
     315           0 :                         *pColors++ = pIn->Red;
     316           0 :                         *pColors++ = pIn->Green;
     317           0 :                         *pColors++ = pIn->Blue;
     318           0 :                         *pColors++ = 1.0;
     319           0 :                         ++pIn;
     320             :                     }
     321           0 :                     return aRes;
     322             :                 }
     323           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     324             :                 {
     325           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     326           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     327             : 
     328           0 :                     uno::Sequence< double > aRes(nLen*4);
     329           0 :                     double* pColors=aRes.getArray();
     330           0 :                     for( sal_Size i=0; i<nLen; ++i )
     331             :                     {
     332           0 :                         *pColors++ = pIn->Red;
     333           0 :                         *pColors++ = pIn->Green;
     334           0 :                         *pColors++ = pIn->Blue;
     335           0 :                         *pColors++ = pIn->Alpha;
     336           0 :                         ++pIn;
     337             :                     }
     338           0 :                     return aRes;
     339             :                 }
     340           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     341             :                 {
     342           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     343           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     344             : 
     345           0 :                     uno::Sequence< double > aRes(nLen*4);
     346           0 :                     double* pColors=aRes.getArray();
     347           0 :                     for( sal_Size i=0; i<nLen; ++i )
     348             :                     {
     349           0 :                         *pColors++ = pIn->Red/pIn->Alpha;
     350           0 :                         *pColors++ = pIn->Green/pIn->Alpha;
     351           0 :                         *pColors++ = pIn->Blue/pIn->Alpha;
     352           0 :                         *pColors++ = pIn->Alpha;
     353           0 :                         ++pIn;
     354             :                     }
     355           0 :                     return aRes;
     356             :                 }
     357             : 
     358             :                 // XIntegerBitmapColorSpace
     359           0 :                 virtual ::sal_Int32 SAL_CALL getBitsPerPixel(  ) throw (uno::RuntimeException)
     360             :                 {
     361           0 :                     return 32;
     362             :                 }
     363           0 :                 virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts(  ) throw (uno::RuntimeException)
     364             :                 {
     365           0 :                     return maBitCounts;
     366             :                 }
     367           0 :                 virtual ::sal_Int8 SAL_CALL getEndianness(  ) throw (uno::RuntimeException)
     368             :                 {
     369           0 :                     return util::Endianness::LITTLE;
     370             :                 }
     371           0 :                 virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
     372             :                                                                                      const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
     373             :                                                                                                                                                                uno::RuntimeException)
     374             :                 {
     375           0 :                     if( dynamic_cast<StandardColorSpace*>(targetColorSpace.get()) )
     376             :                     {
     377           0 :                         const sal_Int8* pIn( deviceColor.getConstArray() );
     378           0 :                         const sal_Size  nLen( deviceColor.getLength() );
     379           0 :                         ENSURE_ARG_OR_THROW2(nLen%4==0,
     380             :                                              "number of channels no multiple of 4",
     381             :                                              static_cast<rendering::XColorSpace*>(this), 0);
     382             : 
     383           0 :                         uno::Sequence<double> aRes(nLen);
     384           0 :                         double* pOut( aRes.getArray() );
     385           0 :                         for( sal_Size i=0; i<nLen; i+=4 )
     386             :                         {
     387           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     388           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     389           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     390           0 :                             *pOut++ = vcl::unotools::toDoubleColor(255-*pIn++);
     391             :                         }
     392           0 :                         return aRes;
     393             :                     }
     394             :                     else
     395             :                     {
     396             :                         // TODO(P3): if we know anything about target
     397             :                         // colorspace, this can be greatly sped up
     398             :                         uno::Sequence<rendering::ARGBColor> aIntermediate(
     399           0 :                             convertIntegerToARGB(deviceColor));
     400           0 :                         return targetColorSpace->convertFromARGB(aIntermediate);
     401             :                     }
     402             :                 }
     403           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
     404             :                                                                                          const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
     405             :                                                                                                                                                                               uno::RuntimeException)
     406             :                 {
     407           0 :                     if( dynamic_cast<StandardColorSpace*>(targetColorSpace.get()) )
     408             :                     {
     409             :                         // it's us, so simply pass-through the data
     410           0 :                         return deviceColor;
     411             :                     }
     412             :                     else
     413             :                     {
     414             :                         // TODO(P3): if we know anything about target
     415             :                         // colorspace, this can be greatly sped up
     416             :                         uno::Sequence<rendering::ARGBColor> aIntermediate(
     417           0 :                             convertIntegerToARGB(deviceColor));
     418           0 :                         return targetColorSpace->convertIntegerFromARGB(aIntermediate);
     419             :                     }
     420             :                 }
     421           0 :                 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     422             :                 {
     423           0 :                     const sal_Int8* pIn( deviceColor.getConstArray() );
     424           0 :                     const sal_Size  nLen( deviceColor.getLength() );
     425           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     426             :                                          "number of channels no multiple of 4",
     427             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     428             : 
     429           0 :                     uno::Sequence< rendering::RGBColor > aRes(nLen/4);
     430           0 :                     rendering::RGBColor* pOut( aRes.getArray() );
     431           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     432             :                     {
     433             :                         *pOut++ = rendering::RGBColor(
     434           0 :                             vcl::unotools::toDoubleColor(pIn[0]),
     435           0 :                             vcl::unotools::toDoubleColor(pIn[1]),
     436           0 :                             vcl::unotools::toDoubleColor(pIn[2]));
     437           0 :                         pIn += 4;
     438             :                     }
     439           0 :                     return aRes;
     440             :                 }
     441             : 
     442           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     443             :                 {
     444           0 :                     const sal_Int8* pIn( deviceColor.getConstArray() );
     445           0 :                     const sal_Size  nLen( deviceColor.getLength() );
     446           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     447             :                                          "number of channels no multiple of 4",
     448             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     449             : 
     450           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     451           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     452           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     453             :                     {
     454             :                         *pOut++ = rendering::ARGBColor(
     455           0 :                             vcl::unotools::toDoubleColor(255-pIn[3]),
     456           0 :                             vcl::unotools::toDoubleColor(pIn[0]),
     457           0 :                             vcl::unotools::toDoubleColor(pIn[1]),
     458           0 :                             vcl::unotools::toDoubleColor(pIn[2]));
     459           0 :                         pIn += 4;
     460             :                     }
     461           0 :                     return aRes;
     462             :                 }
     463             : 
     464           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     465             :                 {
     466           0 :                     const sal_Int8* pIn( deviceColor.getConstArray() );
     467           0 :                     const sal_Size  nLen( deviceColor.getLength() );
     468           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     469             :                                          "number of channels no multiple of 4",
     470             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     471             : 
     472           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     473           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     474           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     475             :                     {
     476           0 :                         const sal_Int8 nAlpha( 255-pIn[3] );
     477             :                         *pOut++ = rendering::ARGBColor(
     478           0 :                             vcl::unotools::toDoubleColor(nAlpha),
     479           0 :                             vcl::unotools::toDoubleColor(nAlpha*pIn[0]),
     480           0 :                             vcl::unotools::toDoubleColor(nAlpha*pIn[1]),
     481           0 :                             vcl::unotools::toDoubleColor(nAlpha*pIn[2]));
     482           0 :                         pIn += 4;
     483             :                     }
     484           0 :                     return aRes;
     485             :                 }
     486             : 
     487           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     488             :                 {
     489           0 :                     const rendering::RGBColor* pIn( rgbColor.getConstArray() );
     490           0 :                     const sal_Size             nLen( rgbColor.getLength() );
     491             : 
     492           0 :                     uno::Sequence< sal_Int8 > aRes(nLen*4);
     493           0 :                     sal_Int8* pColors=aRes.getArray();
     494           0 :                     for( sal_Size i=0; i<nLen; ++i )
     495             :                     {
     496           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Red);
     497           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Green);
     498           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
     499           0 :                         *pColors++ = 0;
     500           0 :                         ++pIn;
     501             :                     }
     502           0 :                     return aRes;
     503             :                 }
     504             : 
     505           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     506             :                 {
     507           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     508           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     509             : 
     510           0 :                     uno::Sequence< sal_Int8 > aRes(nLen*4);
     511           0 :                     sal_Int8* pColors=aRes.getArray();
     512           0 :                     for( sal_Size i=0; i<nLen; ++i )
     513             :                     {
     514           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Red);
     515           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Green);
     516           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
     517           0 :                         *pColors++ = 255-vcl::unotools::toByteColor(pIn->Alpha);
     518           0 :                         ++pIn;
     519             :                     }
     520           0 :                     return aRes;
     521             :                 }
     522             : 
     523           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     524             :                 {
     525           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     526           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     527             : 
     528           0 :                     uno::Sequence< sal_Int8 > aRes(nLen*4);
     529           0 :                     sal_Int8* pColors=aRes.getArray();
     530           0 :                     for( sal_Size i=0; i<nLen; ++i )
     531             :                     {
     532           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Red/pIn->Alpha);
     533           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Green/pIn->Alpha);
     534           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Blue/pIn->Alpha);
     535           0 :                         *pColors++ = 255-vcl::unotools::toByteColor(pIn->Alpha);
     536           0 :                         ++pIn;
     537             :                     }
     538           0 :                     return aRes;
     539             :                 }
     540             : 
     541             :             public:
     542           0 :                 StandardColorSpace() :
     543             :                     maComponentTags(4),
     544           0 :                     maBitCounts(4)
     545             :                 {
     546           0 :                     sal_Int8*  pTags = maComponentTags.getArray();
     547           0 :                     sal_Int32* pBitCounts = maBitCounts.getArray();
     548           0 :                     pTags[0] = rendering::ColorComponentTag::RGB_RED;
     549           0 :                     pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
     550           0 :                     pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
     551           0 :                     pTags[3] = rendering::ColorComponentTag::ALPHA;
     552             : 
     553             :                     pBitCounts[0] =
     554           0 :                     pBitCounts[1] =
     555           0 :                     pBitCounts[2] =
     556           0 :                     pBitCounts[3] = 8;
     557           0 :                 }
     558             :             };
     559             : 
     560           0 :             class StandardNoAlphaColorSpace : public cppu::WeakImplHelper1< com::sun::star::rendering::XIntegerBitmapColorSpace >
     561             :             {
     562             :             private:
     563             :                 uno::Sequence< sal_Int8 >  maComponentTags;
     564             :                 uno::Sequence< sal_Int32 > maBitCounts;
     565             : 
     566           0 :                 virtual ::sal_Int8 SAL_CALL getType(  ) throw (uno::RuntimeException)
     567             :                 {
     568           0 :                     return rendering::ColorSpaceType::RGB;
     569             :                 }
     570           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags(  ) throw (uno::RuntimeException)
     571             :                 {
     572           0 :                     return maComponentTags;
     573             :                 }
     574           0 :                 virtual ::sal_Int8 SAL_CALL getRenderingIntent(  ) throw (uno::RuntimeException)
     575             :                 {
     576           0 :                     return rendering::RenderingIntent::PERCEPTUAL;
     577             :                 }
     578           0 :                 virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties(  ) throw (uno::RuntimeException)
     579             :                 {
     580           0 :                     return uno::Sequence< beans::PropertyValue >();
     581             :                 }
     582           0 :                 virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor,
     583             :                                                                             const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
     584             :                                                                                                                                                       uno::RuntimeException)
     585             :                 {
     586             :                     // TODO(P3): if we know anything about target
     587             :                     // colorspace, this can be greatly sped up
     588             :                     uno::Sequence<rendering::ARGBColor> aIntermediate(
     589           0 :                         convertToARGB(deviceColor));
     590           0 :                     return targetColorSpace->convertFromARGB(aIntermediate);
     591             :                 }
     592           0 :                 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     593             :                 {
     594           0 :                     const double*  pIn( deviceColor.getConstArray() );
     595           0 :                     const sal_Size nLen( deviceColor.getLength() );
     596           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     597             :                                          "number of channels no multiple of 4",
     598             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     599             : 
     600           0 :                     uno::Sequence< rendering::RGBColor > aRes(nLen/4);
     601           0 :                     rendering::RGBColor* pOut( aRes.getArray() );
     602           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     603             :                     {
     604           0 :                         *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]);
     605           0 :                         pIn += 4;
     606             :                     }
     607           0 :                     return aRes;
     608             :                 }
     609           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     610             :                 {
     611           0 :                     const double*  pIn( deviceColor.getConstArray() );
     612           0 :                     const sal_Size nLen( deviceColor.getLength() );
     613           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     614             :                                          "number of channels no multiple of 4",
     615             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     616             : 
     617           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     618           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     619           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     620             :                     {
     621           0 :                         *pOut++ = rendering::ARGBColor(1.0,pIn[0],pIn[1],pIn[2]);
     622           0 :                         pIn += 4;
     623             :                     }
     624           0 :                     return aRes;
     625             :                 }
     626           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     627             :                 {
     628           0 :                     const double*  pIn( deviceColor.getConstArray() );
     629           0 :                     const sal_Size nLen( deviceColor.getLength() );
     630           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     631             :                                          "number of channels no multiple of 4",
     632             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     633             : 
     634           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     635           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     636           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     637             :                     {
     638           0 :                         *pOut++ = rendering::ARGBColor(1.0,pIn[0],pIn[1],pIn[2]);
     639           0 :                         pIn += 4;
     640             :                     }
     641           0 :                     return aRes;
     642             :                 }
     643           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     644             :                 {
     645           0 :                     const rendering::RGBColor* pIn( rgbColor.getConstArray() );
     646           0 :                     const sal_Size             nLen( rgbColor.getLength() );
     647             : 
     648           0 :                     uno::Sequence< double > aRes(nLen*4);
     649           0 :                     double* pColors=aRes.getArray();
     650           0 :                     for( sal_Size i=0; i<nLen; ++i )
     651             :                     {
     652           0 :                         *pColors++ = pIn->Red;
     653           0 :                         *pColors++ = pIn->Green;
     654           0 :                         *pColors++ = pIn->Blue;
     655           0 :                         *pColors++ = 1.0; // the value does not matter
     656           0 :                         ++pIn;
     657             :                     }
     658           0 :                     return aRes;
     659             :                 }
     660           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     661             :                 {
     662           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     663           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     664             : 
     665           0 :                     uno::Sequence< double > aRes(nLen*4);
     666           0 :                     double* pColors=aRes.getArray();
     667           0 :                     for( sal_Size i=0; i<nLen; ++i )
     668             :                     {
     669           0 :                         *pColors++ = pIn->Red;
     670           0 :                         *pColors++ = pIn->Green;
     671           0 :                         *pColors++ = pIn->Blue;
     672           0 :                         *pColors++ = 1.0; // the value does not matter
     673           0 :                         ++pIn;
     674             :                     }
     675           0 :                     return aRes;
     676             :                 }
     677           0 :                 virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     678             :                 {
     679           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     680           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     681             : 
     682           0 :                     uno::Sequence< double > aRes(nLen*4);
     683           0 :                     double* pColors=aRes.getArray();
     684           0 :                     for( sal_Size i=0; i<nLen; ++i )
     685             :                     {
     686           0 :                         *pColors++ = pIn->Red/pIn->Alpha;
     687           0 :                         *pColors++ = pIn->Green/pIn->Alpha;
     688           0 :                         *pColors++ = pIn->Blue/pIn->Alpha;
     689           0 :                         *pColors++ = 1.0; // the value does not matter
     690           0 :                         ++pIn;
     691             :                     }
     692           0 :                     return aRes;
     693             :                 }
     694             : 
     695             :                 // XIntegerBitmapColorSpace
     696           0 :                 virtual ::sal_Int32 SAL_CALL getBitsPerPixel(  ) throw (uno::RuntimeException)
     697             :                 {
     698           0 :                     return 32;
     699             :                 }
     700           0 :                 virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts(  ) throw (uno::RuntimeException)
     701             :                 {
     702           0 :                     return maBitCounts;
     703             :                 }
     704           0 :                 virtual ::sal_Int8 SAL_CALL getEndianness(  ) throw (uno::RuntimeException)
     705             :                 {
     706           0 :                     return util::Endianness::LITTLE;
     707             :                 }
     708           0 :                 virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
     709             :                                                                                      const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
     710             :                                                                                                                                                                uno::RuntimeException)
     711             :                 {
     712           0 :                     if( dynamic_cast<StandardNoAlphaColorSpace*>(targetColorSpace.get()) )
     713             :                     {
     714           0 :                         const sal_Int8* pIn( deviceColor.getConstArray() );
     715           0 :                         const sal_Size  nLen( deviceColor.getLength() );
     716           0 :                         ENSURE_ARG_OR_THROW2(nLen%4==0,
     717             :                                              "number of channels no multiple of 4",
     718             :                                              static_cast<rendering::XColorSpace*>(this), 0);
     719             : 
     720           0 :                         uno::Sequence<double> aRes(nLen);
     721           0 :                         double* pOut( aRes.getArray() );
     722           0 :                         for( sal_Size i=0; i<nLen; i+=4 )
     723             :                         {
     724           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     725           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     726           0 :                             *pOut++ = vcl::unotools::toDoubleColor(*pIn++);
     727           0 :                             *pOut++ = 1.0;
     728             :                         }
     729           0 :                         return aRes;
     730             :                     }
     731             :                     else
     732             :                     {
     733             :                         // TODO(P3): if we know anything about target
     734             :                         // colorspace, this can be greatly sped up
     735             :                         uno::Sequence<rendering::ARGBColor> aIntermediate(
     736           0 :                             convertIntegerToARGB(deviceColor));
     737           0 :                         return targetColorSpace->convertFromARGB(aIntermediate);
     738             :                     }
     739             :                 }
     740           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor,
     741             :                                                                                          const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException,
     742             :                                                                                                                                                                               uno::RuntimeException)
     743             :                 {
     744           0 :                     if( dynamic_cast<StandardNoAlphaColorSpace*>(targetColorSpace.get()) )
     745             :                     {
     746             :                         // it's us, so simply pass-through the data
     747           0 :                         return deviceColor;
     748             :                     }
     749             :                     else
     750             :                     {
     751             :                         // TODO(P3): if we know anything about target
     752             :                         // colorspace, this can be greatly sped up
     753             :                         uno::Sequence<rendering::ARGBColor> aIntermediate(
     754           0 :                             convertIntegerToARGB(deviceColor));
     755           0 :                         return targetColorSpace->convertIntegerFromARGB(aIntermediate);
     756             :                     }
     757             :                 }
     758           0 :                 virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     759             :                 {
     760           0 :                     const sal_Int8* pIn( deviceColor.getConstArray() );
     761           0 :                     const sal_Size  nLen( deviceColor.getLength() );
     762           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     763             :                                          "number of channels no multiple of 4",
     764             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     765             : 
     766           0 :                     uno::Sequence< rendering::RGBColor > aRes(nLen/4);
     767           0 :                     rendering::RGBColor* pOut( aRes.getArray() );
     768           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     769             :                     {
     770             :                         *pOut++ = rendering::RGBColor(
     771           0 :                             vcl::unotools::toDoubleColor(pIn[0]),
     772           0 :                             vcl::unotools::toDoubleColor(pIn[1]),
     773           0 :                             vcl::unotools::toDoubleColor(pIn[2]));
     774           0 :                         pIn += 4;
     775             :                     }
     776           0 :                     return aRes;
     777             :                 }
     778             : 
     779           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     780             :                 {
     781           0 :                     const sal_Int8* pIn( deviceColor.getConstArray() );
     782           0 :                     const sal_Size  nLen( deviceColor.getLength() );
     783           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     784             :                                          "number of channels no multiple of 4",
     785             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     786             : 
     787           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     788           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     789           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     790             :                     {
     791             :                         *pOut++ = rendering::ARGBColor(
     792             :                             1.0,
     793           0 :                             vcl::unotools::toDoubleColor(pIn[0]),
     794           0 :                             vcl::unotools::toDoubleColor(pIn[1]),
     795           0 :                             vcl::unotools::toDoubleColor(pIn[2]));
     796           0 :                         pIn += 4;
     797             :                     }
     798           0 :                     return aRes;
     799             :                 }
     800             : 
     801           0 :                 virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     802             :                 {
     803           0 :                     const sal_Int8* pIn( deviceColor.getConstArray() );
     804           0 :                     const sal_Size  nLen( deviceColor.getLength() );
     805           0 :                     ENSURE_ARG_OR_THROW2(nLen%4==0,
     806             :                                          "number of channels no multiple of 4",
     807             :                                          static_cast<rendering::XColorSpace*>(this), 0);
     808             : 
     809           0 :                     uno::Sequence< rendering::ARGBColor > aRes(nLen/4);
     810           0 :                     rendering::ARGBColor* pOut( aRes.getArray() );
     811           0 :                     for( sal_Size i=0; i<nLen; i+=4 )
     812             :                     {
     813             :                         *pOut++ = rendering::ARGBColor(
     814             :                             1.0,
     815           0 :                             vcl::unotools::toDoubleColor(pIn[0]),
     816           0 :                             vcl::unotools::toDoubleColor(pIn[1]),
     817           0 :                             vcl::unotools::toDoubleColor(pIn[2]));
     818           0 :                         pIn += 4;
     819             :                     }
     820           0 :                     return aRes;
     821             :                 }
     822             : 
     823           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     824             :                 {
     825           0 :                     const rendering::RGBColor* pIn( rgbColor.getConstArray() );
     826           0 :                     const sal_Size             nLen( rgbColor.getLength() );
     827             : 
     828           0 :                     uno::Sequence< sal_Int8 > aRes(nLen*4);
     829           0 :                     sal_Int8* pColors=aRes.getArray();
     830           0 :                     for( sal_Size i=0; i<nLen; ++i )
     831             :                     {
     832           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Red);
     833           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Green);
     834           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
     835           0 :                         *pColors++ = 1.0;
     836           0 :                         ++pIn;
     837             :                     }
     838           0 :                     return aRes;
     839             :                 }
     840             : 
     841           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     842             :                 {
     843           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     844           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     845             : 
     846           0 :                     uno::Sequence< sal_Int8 > aRes(nLen*4);
     847           0 :                     sal_Int8* pColors=aRes.getArray();
     848           0 :                     for( sal_Size i=0; i<nLen; ++i )
     849             :                     {
     850           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Red);
     851           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Green);
     852           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Blue);
     853           0 :                         *pColors++ = -1;
     854           0 :                         ++pIn;
     855             :                     }
     856           0 :                     return aRes;
     857             :                 }
     858             : 
     859           0 :                 virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException)
     860             :                 {
     861           0 :                     const rendering::ARGBColor* pIn( rgbColor.getConstArray() );
     862           0 :                     const sal_Size              nLen( rgbColor.getLength() );
     863             : 
     864           0 :                     uno::Sequence< sal_Int8 > aRes(nLen*4);
     865           0 :                     sal_Int8* pColors=aRes.getArray();
     866           0 :                     for( sal_Size i=0; i<nLen; ++i )
     867             :                     {
     868           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Red/pIn->Alpha);
     869           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Green/pIn->Alpha);
     870           0 :                         *pColors++ = vcl::unotools::toByteColor(pIn->Blue/pIn->Alpha);
     871           0 :                         *pColors++ = -1;
     872           0 :                         ++pIn;
     873             :                     }
     874           0 :                     return aRes;
     875             :                 }
     876             : 
     877             :             public:
     878           0 :                 StandardNoAlphaColorSpace() :
     879             :                     maComponentTags(3),
     880           0 :                     maBitCounts(3)
     881             :                 {
     882           0 :                     sal_Int8*  pTags = maComponentTags.getArray();
     883           0 :                     sal_Int32* pBitCounts = maBitCounts.getArray();
     884           0 :                     pTags[0] = rendering::ColorComponentTag::RGB_RED;
     885           0 :                     pTags[1] = rendering::ColorComponentTag::RGB_GREEN;
     886           0 :                     pTags[2] = rendering::ColorComponentTag::RGB_BLUE;
     887             : 
     888             :                     pBitCounts[0] =
     889           0 :                     pBitCounts[1] =
     890           0 :                     pBitCounts[2] = 8;
     891           0 :                 }
     892             :             };
     893             : 
     894             :             struct StandardColorSpaceHolder : public rtl::StaticWithInit<uno::Reference<rendering::XIntegerBitmapColorSpace>,
     895             :                                                                          StandardColorSpaceHolder>
     896             :             {
     897           0 :                 uno::Reference<rendering::XIntegerBitmapColorSpace> operator()()
     898             :                 {
     899           0 :                     return new StandardColorSpace();
     900             :                 }
     901             :             };
     902             : 
     903             :             struct StandardNoAlphaColorSpaceHolder : public rtl::StaticWithInit<uno::Reference<rendering::XIntegerBitmapColorSpace>,
     904             :                                                                          StandardNoAlphaColorSpaceHolder>
     905             :             {
     906           0 :                 uno::Reference<rendering::XIntegerBitmapColorSpace> operator()()
     907             :                 {
     908           0 :                     return new StandardNoAlphaColorSpace();
     909             :                 }
     910             :             };
     911             :         }
     912             : 
     913           0 :         uno::Reference<rendering::XIntegerBitmapColorSpace> getStdColorSpace()
     914             :         {
     915           0 :             return StandardColorSpaceHolder::get();
     916             :         }
     917             : 
     918           0 :         uno::Reference<rendering::XIntegerBitmapColorSpace> getStdColorSpaceWithoutAlpha()
     919             :         {
     920           0 :             return StandardNoAlphaColorSpaceHolder::get();
     921             :         }
     922             : 
     923           0 :         rendering::IntegerBitmapLayout getStdMemoryLayout( const geometry::IntegerSize2D& rBmpSize )
     924             :         {
     925           0 :             rendering::IntegerBitmapLayout aLayout;
     926             : 
     927           0 :             aLayout.ScanLines = rBmpSize.Height;
     928           0 :             aLayout.ScanLineBytes = rBmpSize.Width*4;
     929           0 :             aLayout.ScanLineStride = aLayout.ScanLineBytes;
     930           0 :             aLayout.PlaneStride = 0;
     931           0 :             aLayout.ColorSpace = getStdColorSpace();
     932           0 :             aLayout.Palette.clear();
     933           0 :             aLayout.IsMsbFirst = sal_False;
     934             : 
     935           0 :             return aLayout;
     936             :         }
     937             : 
     938           0 :         ::Color stdIntSequenceToColor( const uno::Sequence<sal_Int8>& rColor )
     939             :         {
     940             : #ifdef OSL_BIGENDIAN
     941             :             const sal_Int8* pCols( rColor.getConstArray() );
     942             :             return ::Color( pCols[3], pCols[0], pCols[1], pCols[2] );
     943             : #else
     944           0 :             return ::Color( *reinterpret_cast< const ::ColorData* >(rColor.getConstArray()) );
     945             : #endif
     946             :         }
     947             : 
     948           0 :         uno::Sequence<sal_Int8> colorToStdIntSequence( const ::Color& rColor )
     949             :         {
     950           0 :             uno::Sequence<sal_Int8> aRet(4);
     951           0 :             sal_Int8* pCols( aRet.getArray() );
     952             : #ifdef OSL_BIGENDIAN
     953             :             pCols[0] = rColor.GetRed();
     954             :             pCols[1] = rColor.GetGreen();
     955             :             pCols[2] = rColor.GetBlue();
     956             :             pCols[3] = 255-rColor.GetTransparency();
     957             : #else
     958           0 :             *reinterpret_cast<sal_Int32*>(pCols) = rColor.GetColor();
     959             : #endif
     960           0 :             return aRet;
     961             :         }
     962             : 
     963             :         // Create a corrected view transformation out of the give one,
     964             :         // which ensures that the rectangle given by (0,0) and
     965             :         // rSpriteSize is mapped with its left,top corner to (0,0)
     966             :         // again. This is required to properly render sprite
     967             :         // animations to buffer bitmaps.
     968           0 :         ::basegfx::B2DHomMatrix& calcRectToOriginTransform( ::basegfx::B2DHomMatrix&            o_transform,
     969             :                                                             const ::basegfx::B2DRange&          i_srcRect,
     970             :                                                             const ::basegfx::B2DHomMatrix&      i_transformation )
     971             :         {
     972           0 :             if( i_srcRect.isEmpty() )
     973           0 :                 return o_transform=i_transformation;
     974             : 
     975             :             // transform by given transformation
     976           0 :             ::basegfx::B2DRectangle aTransformedRect;
     977             : 
     978             :             calcTransformedRectBounds( aTransformedRect,
     979             :                                        i_srcRect,
     980           0 :                                        i_transformation );
     981             : 
     982             :             // now move resulting left,top point of bounds to (0,0)
     983             :             const basegfx::B2DHomMatrix aCorrectedTransform(basegfx::tools::createTranslateB2DHomMatrix(
     984           0 :                 -aTransformedRect.getMinX(), -aTransformedRect.getMinY()));
     985             : 
     986             :             // prepend to original transformation
     987           0 :             o_transform = aCorrectedTransform * i_transformation;
     988             : 
     989           0 :             return o_transform;
     990             :         }
     991             : 
     992           0 :         ::basegfx::B2DRange& calcTransformedRectBounds( ::basegfx::B2DRange&            outRect,
     993             :                                                         const ::basegfx::B2DRange&      inRect,
     994             :                                                         const ::basegfx::B2DHomMatrix&  transformation )
     995             :         {
     996           0 :             outRect.reset();
     997             : 
     998           0 :             if( inRect.isEmpty() )
     999           0 :                 return outRect;
    1000             : 
    1001             :             // transform all four extremal points of the rectangle,
    1002             :             // take bounding rect of those.
    1003             : 
    1004             :             // transform left-top point
    1005           0 :             outRect.expand( transformation * inRect.getMinimum() );
    1006             : 
    1007             :             // transform bottom-right point
    1008           0 :             outRect.expand( transformation * inRect.getMaximum() );
    1009             : 
    1010           0 :             ::basegfx::B2DPoint aPoint;
    1011             : 
    1012             :             // transform top-right point
    1013           0 :             aPoint.setX( inRect.getMaxX() );
    1014           0 :             aPoint.setY( inRect.getMinY() );
    1015             : 
    1016           0 :             aPoint *= transformation;
    1017           0 :             outRect.expand( aPoint );
    1018             : 
    1019             :             // transform bottom-left point
    1020           0 :             aPoint.setX( inRect.getMinX() );
    1021           0 :             aPoint.setY( inRect.getMaxY() );
    1022             : 
    1023           0 :             aPoint *= transformation;
    1024           0 :             outRect.expand( aPoint );
    1025             : 
    1026             :             // over and out.
    1027           0 :             return outRect;
    1028             :         }
    1029             : 
    1030           0 :         bool isInside( const ::basegfx::B2DRange&       rContainedRect,
    1031             :                        const ::basegfx::B2DRange&       rTransformRect,
    1032             :                        const ::basegfx::B2DHomMatrix&   rTransformation )
    1033             :         {
    1034           0 :             if( rContainedRect.isEmpty() || rTransformRect.isEmpty() )
    1035           0 :                 return false;
    1036             : 
    1037             :             ::basegfx::B2DPolygon aPoly(
    1038           0 :                 ::basegfx::tools::createPolygonFromRect( rTransformRect ) );
    1039           0 :             aPoly.transform( rTransformation );
    1040             : 
    1041             :             return ::basegfx::tools::isInside( aPoly,
    1042             :                                                ::basegfx::tools::createPolygonFromRect(
    1043             :                                                    rContainedRect ),
    1044           0 :                                                true );
    1045             :         }
    1046             : 
    1047             :         namespace
    1048             :         {
    1049           0 :             bool clipAreaImpl( ::basegfx::B2IRange*       o_pDestArea,
    1050             :                                ::basegfx::B2IRange&       io_rSourceArea,
    1051             :                                ::basegfx::B2IPoint&       io_rDestPoint,
    1052             :                                const ::basegfx::B2IRange& rSourceBounds,
    1053             :                                const ::basegfx::B2IRange& rDestBounds )
    1054             :             {
    1055             :                 const ::basegfx::B2IPoint aSourceTopLeft(
    1056           0 :                     io_rSourceArea.getMinimum() );
    1057             : 
    1058           0 :                 ::basegfx::B2IRange aLocalSourceArea( io_rSourceArea );
    1059             : 
    1060             :                 // clip source area (which must be inside rSourceBounds)
    1061           0 :                 aLocalSourceArea.intersect( rSourceBounds );
    1062             : 
    1063           0 :                 if( aLocalSourceArea.isEmpty() )
    1064           0 :                     return false;
    1065             : 
    1066             :                 // calc relative new source area points (relative to orig
    1067             :                 // source area)
    1068             :                 const ::basegfx::B2IVector aUpperLeftOffset(
    1069           0 :                     aLocalSourceArea.getMinimum()-aSourceTopLeft );
    1070             :                 const ::basegfx::B2IVector aLowerRightOffset(
    1071           0 :                     aLocalSourceArea.getMaximum()-aSourceTopLeft );
    1072             : 
    1073             :                 ::basegfx::B2IRange aLocalDestArea( io_rDestPoint + aUpperLeftOffset,
    1074           0 :                                                     io_rDestPoint + aLowerRightOffset );
    1075             : 
    1076             :                 // clip dest area (which must be inside rDestBounds)
    1077           0 :                 aLocalDestArea.intersect( rDestBounds );
    1078             : 
    1079           0 :                 if( aLocalDestArea.isEmpty() )
    1080           0 :                     return false;
    1081             : 
    1082             :                 // calc relative new dest area points (relative to orig
    1083             :                 // source area)
    1084             :                 const ::basegfx::B2IVector aDestUpperLeftOffset(
    1085           0 :                     aLocalDestArea.getMinimum()-io_rDestPoint );
    1086             :                 const ::basegfx::B2IVector aDestLowerRightOffset(
    1087           0 :                     aLocalDestArea.getMaximum()-io_rDestPoint );
    1088             : 
    1089             :                 io_rSourceArea = ::basegfx::B2IRange( aSourceTopLeft + aDestUpperLeftOffset,
    1090           0 :                                                       aSourceTopLeft + aDestLowerRightOffset );
    1091           0 :                 io_rDestPoint  = aLocalDestArea.getMinimum();
    1092             : 
    1093           0 :                 if( o_pDestArea )
    1094           0 :                     *o_pDestArea = aLocalDestArea;
    1095             : 
    1096           0 :                 return true;
    1097             :             }
    1098             :         }
    1099             : 
    1100           0 :         bool clipScrollArea( ::basegfx::B2IRange&                  io_rSourceArea,
    1101             :                              ::basegfx::B2IPoint&                  io_rDestPoint,
    1102             :                              ::std::vector< ::basegfx::B2IRange >& o_ClippedAreas,
    1103             :                              const ::basegfx::B2IRange&            rBounds )
    1104             :         {
    1105           0 :             ::basegfx::B2IRange aResultingDestArea;
    1106             : 
    1107             :             // compute full destination area (to determine uninitialized
    1108             :             // areas below)
    1109           0 :             const ::basegfx::B2I64Tuple& rRange( io_rSourceArea.getRange() );
    1110             :             ::basegfx::B2IRange aInputDestArea( io_rDestPoint.getX(),
    1111             :                                                 io_rDestPoint.getY(),
    1112           0 :                                                 (io_rDestPoint.getX()
    1113           0 :                                                  + static_cast<sal_Int32>(rRange.getX())),
    1114           0 :                                                 (io_rDestPoint.getY()
    1115           0 :                                                  + static_cast<sal_Int32>(rRange.getY())) );
    1116             :             // limit to output area (no point updating outside of it)
    1117           0 :             aInputDestArea.intersect( rBounds );
    1118             : 
    1119             :             // clip to rBounds
    1120           0 :             if( !clipAreaImpl( &aResultingDestArea,
    1121             :                                io_rSourceArea,
    1122             :                                io_rDestPoint,
    1123             :                                rBounds,
    1124           0 :                                rBounds ) )
    1125           0 :                 return false;
    1126             : 
    1127             :             // finally, compute all areas clipped off the total
    1128             :             // destination area.
    1129             :             ::basegfx::computeSetDifference( o_ClippedAreas,
    1130             :                                              aInputDestArea,
    1131           0 :                                              aResultingDestArea );
    1132             : 
    1133           0 :             return true;
    1134             :         }
    1135             : 
    1136           0 :         ::basegfx::B2IRange spritePixelAreaFromB2DRange( const ::basegfx::B2DRange& rRange )
    1137             :         {
    1138           0 :             if( rRange.isEmpty() )
    1139           0 :                 return ::basegfx::B2IRange();
    1140             : 
    1141             :             const ::basegfx::B2IPoint aTopLeft( ::basegfx::fround( rRange.getMinX() ),
    1142           0 :                                                 ::basegfx::fround( rRange.getMinY() ) );
    1143             :             return ::basegfx::B2IRange( aTopLeft,
    1144             :                                         aTopLeft + ::basegfx::B2IPoint(
    1145             :                                             ::basegfx::fround( rRange.getWidth() ),
    1146           0 :                                             ::basegfx::fround( rRange.getHeight() ) ) );
    1147             :         }
    1148             : 
    1149           0 :         uno::Sequence< uno::Any >& getDeviceInfo( const uno::Reference< rendering::XCanvas >& i_rxCanvas,
    1150             :                                                   uno::Sequence< uno::Any >&                  o_rxParams )
    1151             :         {
    1152           0 :             o_rxParams.realloc( 0 );
    1153             : 
    1154           0 :             if( i_rxCanvas.is() )
    1155             :             {
    1156             :                 try
    1157             :                 {
    1158           0 :                     uno::Reference< rendering::XGraphicDevice > xDevice( i_rxCanvas->getDevice(),
    1159           0 :                                                                          uno::UNO_QUERY_THROW );
    1160             : 
    1161             :                     uno::Reference< lang::XServiceInfo >  xServiceInfo( xDevice,
    1162           0 :                                                                         uno::UNO_QUERY_THROW );
    1163             :                     uno::Reference< beans::XPropertySet > xPropSet( xDevice,
    1164           0 :                                                                     uno::UNO_QUERY_THROW );
    1165             : 
    1166           0 :                     o_rxParams.realloc( 2 );
    1167             : 
    1168           0 :                     o_rxParams[ 0 ] = uno::makeAny( xServiceInfo->getImplementationName() );
    1169           0 :                     o_rxParams[ 1 ] = uno::makeAny( xPropSet->getPropertyValue(
    1170           0 :                                                         ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("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 :             ::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             :                                    nGradientSize / nStripSize,
    1291           0 :                                    nColorSteps ) );
    1292             :         }
    1293             : 
    1294             :     } // namespace tools
    1295             : 
    1296             : } // namespace canvas
    1297             : 
    1298             : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10