1*25ea7f45SAndrew Rist /************************************************************** 2cdf0e10cSrcweir * 3*25ea7f45SAndrew Rist * Licensed to the Apache Software Foundation (ASF) under one 4*25ea7f45SAndrew Rist * or more contributor license agreements. See the NOTICE file 5*25ea7f45SAndrew Rist * distributed with this work for additional information 6*25ea7f45SAndrew Rist * regarding copyright ownership. The ASF licenses this file 7*25ea7f45SAndrew Rist * to you under the Apache License, Version 2.0 (the 8*25ea7f45SAndrew Rist * "License"); you may not use this file except in compliance 9*25ea7f45SAndrew Rist * with the License. You may obtain a copy of the License at 10*25ea7f45SAndrew Rist * 11*25ea7f45SAndrew Rist * http://www.apache.org/licenses/LICENSE-2.0 12*25ea7f45SAndrew Rist * 13*25ea7f45SAndrew Rist * Unless required by applicable law or agreed to in writing, 14*25ea7f45SAndrew Rist * software distributed under the License is distributed on an 15*25ea7f45SAndrew Rist * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*25ea7f45SAndrew Rist * KIND, either express or implied. See the License for the 17*25ea7f45SAndrew Rist * specific language governing permissions and limitations 18*25ea7f45SAndrew Rist * under the License. 19*25ea7f45SAndrew Rist * 20*25ea7f45SAndrew Rist *************************************************************/ 21*25ea7f45SAndrew Rist 22*25ea7f45SAndrew Rist 23cdf0e10cSrcweir 24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 25cdf0e10cSrcweir #include "precompiled_canvas.hxx" 26cdf0e10cSrcweir 27cdf0e10cSrcweir #include <canvas/debug.hxx> 28cdf0e10cSrcweir #include <tools/diagnose_ex.h> 29cdf0e10cSrcweir 30cdf0e10cSrcweir #include <com/sun/star/geometry/AffineMatrix2D.hpp> 31cdf0e10cSrcweir #include <com/sun/star/geometry/Matrix2D.hpp> 32cdf0e10cSrcweir #include <com/sun/star/awt/Rectangle.hpp> 33cdf0e10cSrcweir #include <com/sun/star/util/Endianness.hpp> 34cdf0e10cSrcweir #include <com/sun/star/rendering/XIntegerBitmapColorSpace.hpp> 35cdf0e10cSrcweir #include <com/sun/star/rendering/IntegerBitmapLayout.hpp> 36cdf0e10cSrcweir #include <com/sun/star/rendering/ColorSpaceType.hpp> 37cdf0e10cSrcweir #include <com/sun/star/rendering/ColorComponentTag.hpp> 38cdf0e10cSrcweir #include <com/sun/star/rendering/RenderingIntent.hpp> 39cdf0e10cSrcweir #include <com/sun/star/rendering/RenderState.hpp> 40cdf0e10cSrcweir #include <com/sun/star/rendering/ViewState.hpp> 41cdf0e10cSrcweir #include <com/sun/star/rendering/XCanvas.hpp> 42cdf0e10cSrcweir #include <com/sun/star/rendering/XColorSpace.hpp> 43cdf0e10cSrcweir #include <com/sun/star/rendering/CompositeOperation.hpp> 44cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp> 45cdf0e10cSrcweir #include <com/sun/star/lang/XServiceInfo.hpp> 46cdf0e10cSrcweir 47cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrix.hxx> 48cdf0e10cSrcweir #include <basegfx/range/b2drange.hxx> 49cdf0e10cSrcweir #include <basegfx/range/b2irange.hxx> 50cdf0e10cSrcweir #include <basegfx/range/b2drectangle.hxx> 51cdf0e10cSrcweir #include <basegfx/point/b2dpoint.hxx> 52cdf0e10cSrcweir #include <basegfx/point/b2ipoint.hxx> 53cdf0e10cSrcweir #include <basegfx/vector/b2ivector.hxx> 54cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx> 55cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygontools.hxx> 56cdf0e10cSrcweir #include <basegfx/polygon/b2dpolypolygontools.hxx> 57cdf0e10cSrcweir #include <basegfx/tools/canvastools.hxx> 58cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx> 59cdf0e10cSrcweir #include <basegfx/matrix/b2dhommatrixtools.hxx> 60cdf0e10cSrcweir 61cdf0e10cSrcweir #include <cppuhelper/compbase1.hxx> 62cdf0e10cSrcweir #include <rtl/instance.hxx> 63cdf0e10cSrcweir #include <toolkit/helper/vclunohelper.hxx> 64cdf0e10cSrcweir #include <vcl/window.hxx> 65cdf0e10cSrcweir #include <vcl/canvastools.hxx> 66cdf0e10cSrcweir 67cdf0e10cSrcweir #include <canvas/canvastools.hxx> 68cdf0e10cSrcweir 69cdf0e10cSrcweir #include <limits> 70cdf0e10cSrcweir 71cdf0e10cSrcweir 72cdf0e10cSrcweir using namespace ::com::sun::star; 73cdf0e10cSrcweir 74cdf0e10cSrcweir namespace com { namespace sun { namespace star { namespace rendering 75cdf0e10cSrcweir { operator ==(const RenderState & renderState1,const RenderState & renderState2)76cdf0e10cSrcweir bool operator==( const RenderState& renderState1, 77cdf0e10cSrcweir const RenderState& renderState2 ) 78cdf0e10cSrcweir { 79cdf0e10cSrcweir if( renderState1.Clip != renderState2.Clip ) 80cdf0e10cSrcweir return false; 81cdf0e10cSrcweir 82cdf0e10cSrcweir if( renderState1.DeviceColor != renderState2.DeviceColor ) 83cdf0e10cSrcweir return false; 84cdf0e10cSrcweir 85cdf0e10cSrcweir if( renderState1.CompositeOperation != renderState2.CompositeOperation ) 86cdf0e10cSrcweir return false; 87cdf0e10cSrcweir 88cdf0e10cSrcweir ::basegfx::B2DHomMatrix mat1, mat2; 89cdf0e10cSrcweir ::canvas::tools::getRenderStateTransform( mat1, renderState1 ); 90cdf0e10cSrcweir ::canvas::tools::getRenderStateTransform( mat2, renderState2 ); 91cdf0e10cSrcweir if( mat1 != mat2 ) 92cdf0e10cSrcweir return false; 93cdf0e10cSrcweir 94cdf0e10cSrcweir return true; 95cdf0e10cSrcweir } 96cdf0e10cSrcweir operator ==(const ViewState & viewState1,const ViewState & viewState2)97cdf0e10cSrcweir bool operator==( const ViewState& viewState1, 98cdf0e10cSrcweir const ViewState& viewState2 ) 99cdf0e10cSrcweir { 100cdf0e10cSrcweir if( viewState1.Clip != viewState2.Clip ) 101cdf0e10cSrcweir return false; 102cdf0e10cSrcweir 103cdf0e10cSrcweir ::basegfx::B2DHomMatrix mat1, mat2; 104cdf0e10cSrcweir ::canvas::tools::getViewStateTransform( mat1, viewState1 ); 105cdf0e10cSrcweir ::canvas::tools::getViewStateTransform( mat2, viewState2 ); 106cdf0e10cSrcweir if( mat1 != mat2 ) 107cdf0e10cSrcweir return false; 108cdf0e10cSrcweir 109cdf0e10cSrcweir return true; 110cdf0e10cSrcweir } 111cdf0e10cSrcweir }}}} 112cdf0e10cSrcweir 113cdf0e10cSrcweir namespace canvas 114cdf0e10cSrcweir { 115cdf0e10cSrcweir namespace tools 116cdf0e10cSrcweir { createInfiniteSize2D()117cdf0e10cSrcweir geometry::RealSize2D createInfiniteSize2D() 118cdf0e10cSrcweir { 119cdf0e10cSrcweir return geometry::RealSize2D( 120cdf0e10cSrcweir ::std::numeric_limits<double>::infinity(), 121cdf0e10cSrcweir ::std::numeric_limits<double>::infinity() ); 122cdf0e10cSrcweir } 123cdf0e10cSrcweir initRenderState(rendering::RenderState & renderState)124cdf0e10cSrcweir rendering::RenderState& initRenderState( rendering::RenderState& renderState ) 125cdf0e10cSrcweir { 126cdf0e10cSrcweir // setup identity transform 127cdf0e10cSrcweir setIdentityAffineMatrix2D( renderState.AffineTransform ); 128cdf0e10cSrcweir renderState.Clip = uno::Reference< rendering::XPolyPolygon2D >(); 129cdf0e10cSrcweir renderState.DeviceColor = uno::Sequence< double >(); 130cdf0e10cSrcweir renderState.CompositeOperation = rendering::CompositeOperation::OVER; 131cdf0e10cSrcweir 132cdf0e10cSrcweir return renderState; 133cdf0e10cSrcweir } 134cdf0e10cSrcweir initViewState(rendering::ViewState & viewState)135cdf0e10cSrcweir rendering::ViewState& initViewState( rendering::ViewState& viewState ) 136cdf0e10cSrcweir { 137cdf0e10cSrcweir // setup identity transform 138cdf0e10cSrcweir setIdentityAffineMatrix2D( viewState.AffineTransform ); 139cdf0e10cSrcweir viewState.Clip = uno::Reference< rendering::XPolyPolygon2D >(); 140cdf0e10cSrcweir 141cdf0e10cSrcweir return viewState; 142cdf0e10cSrcweir } 143cdf0e10cSrcweir getViewStateTransform(::basegfx::B2DHomMatrix & transform,const rendering::ViewState & viewState)144cdf0e10cSrcweir ::basegfx::B2DHomMatrix& getViewStateTransform( ::basegfx::B2DHomMatrix& transform, 145cdf0e10cSrcweir const rendering::ViewState& viewState ) 146cdf0e10cSrcweir { 147cdf0e10cSrcweir return ::basegfx::unotools::homMatrixFromAffineMatrix( transform, viewState.AffineTransform ); 148cdf0e10cSrcweir } 149cdf0e10cSrcweir setViewStateTransform(rendering::ViewState & viewState,const::basegfx::B2DHomMatrix & transform)150cdf0e10cSrcweir rendering::ViewState& setViewStateTransform( rendering::ViewState& viewState, 151cdf0e10cSrcweir const ::basegfx::B2DHomMatrix& transform ) 152cdf0e10cSrcweir { 153cdf0e10cSrcweir ::basegfx::unotools::affineMatrixFromHomMatrix( viewState.AffineTransform, transform ); 154cdf0e10cSrcweir 155cdf0e10cSrcweir return viewState; 156cdf0e10cSrcweir } 157cdf0e10cSrcweir getRenderStateTransform(::basegfx::B2DHomMatrix & transform,const rendering::RenderState & renderState)158cdf0e10cSrcweir ::basegfx::B2DHomMatrix& getRenderStateTransform( ::basegfx::B2DHomMatrix& transform, 159cdf0e10cSrcweir const rendering::RenderState& renderState ) 160cdf0e10cSrcweir { 161cdf0e10cSrcweir return ::basegfx::unotools::homMatrixFromAffineMatrix( transform, renderState.AffineTransform ); 162cdf0e10cSrcweir } 163cdf0e10cSrcweir setRenderStateTransform(rendering::RenderState & renderState,const::basegfx::B2DHomMatrix & transform)164cdf0e10cSrcweir rendering::RenderState& setRenderStateTransform( rendering::RenderState& renderState, 165cdf0e10cSrcweir const ::basegfx::B2DHomMatrix& transform ) 166cdf0e10cSrcweir { 167cdf0e10cSrcweir ::basegfx::unotools::affineMatrixFromHomMatrix( renderState.AffineTransform, transform ); 168cdf0e10cSrcweir 169cdf0e10cSrcweir return renderState; 170cdf0e10cSrcweir } 171cdf0e10cSrcweir appendToRenderState(rendering::RenderState & renderState,const::basegfx::B2DHomMatrix & rTransform)172cdf0e10cSrcweir rendering::RenderState& appendToRenderState( rendering::RenderState& renderState, 173cdf0e10cSrcweir const ::basegfx::B2DHomMatrix& rTransform ) 174cdf0e10cSrcweir { 175cdf0e10cSrcweir ::basegfx::B2DHomMatrix transform; 176cdf0e10cSrcweir 177cdf0e10cSrcweir getRenderStateTransform( transform, renderState ); 178cdf0e10cSrcweir return setRenderStateTransform( renderState, transform * rTransform ); 179cdf0e10cSrcweir } 180cdf0e10cSrcweir appendToViewState(rendering::ViewState & viewState,const::basegfx::B2DHomMatrix & rTransform)181cdf0e10cSrcweir rendering::ViewState& appendToViewState( rendering::ViewState& viewState, 182cdf0e10cSrcweir const ::basegfx::B2DHomMatrix& rTransform ) 183cdf0e10cSrcweir { 184cdf0e10cSrcweir ::basegfx::B2DHomMatrix transform; 185cdf0e10cSrcweir 186cdf0e10cSrcweir getViewStateTransform( transform, viewState ); 187cdf0e10cSrcweir return setViewStateTransform( viewState, transform * rTransform ); 188cdf0e10cSrcweir } 189cdf0e10cSrcweir prependToRenderState(rendering::RenderState & renderState,const::basegfx::B2DHomMatrix & rTransform)190cdf0e10cSrcweir rendering::RenderState& prependToRenderState( rendering::RenderState& renderState, 191cdf0e10cSrcweir const ::basegfx::B2DHomMatrix& rTransform ) 192cdf0e10cSrcweir { 193cdf0e10cSrcweir ::basegfx::B2DHomMatrix transform; 194cdf0e10cSrcweir 195cdf0e10cSrcweir getRenderStateTransform( transform, renderState ); 196cdf0e10cSrcweir return setRenderStateTransform( renderState, rTransform * transform ); 197cdf0e10cSrcweir } 198cdf0e10cSrcweir prependToViewState(rendering::ViewState & viewState,const::basegfx::B2DHomMatrix & rTransform)199cdf0e10cSrcweir rendering::ViewState& prependToViewState( rendering::ViewState& viewState, 200cdf0e10cSrcweir const ::basegfx::B2DHomMatrix& rTransform ) 201cdf0e10cSrcweir { 202cdf0e10cSrcweir ::basegfx::B2DHomMatrix transform; 203cdf0e10cSrcweir 204cdf0e10cSrcweir getViewStateTransform( transform, viewState ); 205cdf0e10cSrcweir return setViewStateTransform( viewState, rTransform * transform ); 206cdf0e10cSrcweir } 207cdf0e10cSrcweir mergeViewAndRenderTransform(::basegfx::B2DHomMatrix & combinedTransform,const rendering::ViewState & viewState,const rendering::RenderState & renderState)208cdf0e10cSrcweir ::basegfx::B2DHomMatrix& mergeViewAndRenderTransform( ::basegfx::B2DHomMatrix& combinedTransform, 209cdf0e10cSrcweir const rendering::ViewState& viewState, 210cdf0e10cSrcweir const rendering::RenderState& renderState ) 211cdf0e10cSrcweir { 212cdf0e10cSrcweir ::basegfx::B2DHomMatrix viewTransform; 213cdf0e10cSrcweir 214cdf0e10cSrcweir ::basegfx::unotools::homMatrixFromAffineMatrix( combinedTransform, renderState.AffineTransform ); 215cdf0e10cSrcweir ::basegfx::unotools::homMatrixFromAffineMatrix( viewTransform, viewState.AffineTransform ); 216cdf0e10cSrcweir 217cdf0e10cSrcweir // this statement performs combinedTransform = viewTransform * combinedTransform 218cdf0e10cSrcweir combinedTransform *= viewTransform; 219cdf0e10cSrcweir 220cdf0e10cSrcweir return combinedTransform; 221cdf0e10cSrcweir } 222cdf0e10cSrcweir mergeViewAndRenderState(rendering::ViewState & resultViewState,const rendering::ViewState & viewState,const rendering::RenderState & renderState,const uno::Reference<rendering::XCanvas> &)223cdf0e10cSrcweir rendering::ViewState& mergeViewAndRenderState( rendering::ViewState& resultViewState, 224cdf0e10cSrcweir const rendering::ViewState& viewState, 225cdf0e10cSrcweir const rendering::RenderState& renderState, 226cdf0e10cSrcweir const uno::Reference< rendering::XCanvas >& /*xCanvas*/ ) 227cdf0e10cSrcweir { 228cdf0e10cSrcweir ::basegfx::B2DHomMatrix aTmpMatrix; 229cdf0e10cSrcweir geometry::AffineMatrix2D convertedMatrix; 230cdf0e10cSrcweir 231cdf0e10cSrcweir resultViewState.Clip = NULL; // TODO(F2): intersect clippings 232cdf0e10cSrcweir 233cdf0e10cSrcweir return setViewStateTransform( 234cdf0e10cSrcweir resultViewState, 235cdf0e10cSrcweir mergeViewAndRenderTransform( aTmpMatrix, 236cdf0e10cSrcweir viewState, 237cdf0e10cSrcweir renderState ) ); 238cdf0e10cSrcweir } 239cdf0e10cSrcweir setIdentityAffineMatrix2D(geometry::AffineMatrix2D & matrix)240cdf0e10cSrcweir geometry::AffineMatrix2D& setIdentityAffineMatrix2D( geometry::AffineMatrix2D& matrix ) 241cdf0e10cSrcweir { 242cdf0e10cSrcweir matrix.m00 = 1.0; 243cdf0e10cSrcweir matrix.m01 = 0.0; 244cdf0e10cSrcweir matrix.m02 = 0.0; 245cdf0e10cSrcweir matrix.m10 = 0.0; 246cdf0e10cSrcweir matrix.m11 = 1.0; 247cdf0e10cSrcweir matrix.m12 = 0.0; 248cdf0e10cSrcweir 249cdf0e10cSrcweir return matrix; 250cdf0e10cSrcweir } 251cdf0e10cSrcweir setIdentityMatrix2D(geometry::Matrix2D & matrix)252cdf0e10cSrcweir geometry::Matrix2D& setIdentityMatrix2D( geometry::Matrix2D& matrix ) 253cdf0e10cSrcweir { 254cdf0e10cSrcweir matrix.m00 = 1.0; 255cdf0e10cSrcweir matrix.m01 = 0.0; 256cdf0e10cSrcweir matrix.m10 = 0.0; 257cdf0e10cSrcweir matrix.m11 = 1.0; 258cdf0e10cSrcweir 259cdf0e10cSrcweir return matrix; 260cdf0e10cSrcweir } 261cdf0e10cSrcweir 262cdf0e10cSrcweir namespace 263cdf0e10cSrcweir { 264cdf0e10cSrcweir class StandardColorSpace : public cppu::WeakImplHelper1< com::sun::star::rendering::XIntegerBitmapColorSpace > 265cdf0e10cSrcweir { 266cdf0e10cSrcweir private: 267cdf0e10cSrcweir uno::Sequence< sal_Int8 > maComponentTags; 268cdf0e10cSrcweir uno::Sequence< sal_Int32 > maBitCounts; 269cdf0e10cSrcweir getType()270cdf0e10cSrcweir virtual ::sal_Int8 SAL_CALL getType( ) throw (uno::RuntimeException) 271cdf0e10cSrcweir { 272cdf0e10cSrcweir return rendering::ColorSpaceType::RGB; 273cdf0e10cSrcweir } getComponentTags()274cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int8 > SAL_CALL getComponentTags( ) throw (uno::RuntimeException) 275cdf0e10cSrcweir { 276cdf0e10cSrcweir return maComponentTags; 277cdf0e10cSrcweir } getRenderingIntent()278cdf0e10cSrcweir virtual ::sal_Int8 SAL_CALL getRenderingIntent( ) throw (uno::RuntimeException) 279cdf0e10cSrcweir { 280cdf0e10cSrcweir return rendering::RenderingIntent::PERCEPTUAL; 281cdf0e10cSrcweir } getProperties()282cdf0e10cSrcweir virtual uno::Sequence< beans::PropertyValue > SAL_CALL getProperties( ) throw (uno::RuntimeException) 283cdf0e10cSrcweir { 284cdf0e10cSrcweir return uno::Sequence< beans::PropertyValue >(); 285cdf0e10cSrcweir } convertColorSpace(const uno::Sequence<double> & deviceColor,const uno::Reference<rendering::XColorSpace> & targetColorSpace)286cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertColorSpace( const uno::Sequence< double >& deviceColor, 287cdf0e10cSrcweir const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException, 288cdf0e10cSrcweir uno::RuntimeException) 289cdf0e10cSrcweir { 290cdf0e10cSrcweir // TODO(P3): if we know anything about target 291cdf0e10cSrcweir // colorspace, this can be greatly sped up 292cdf0e10cSrcweir uno::Sequence<rendering::ARGBColor> aIntermediate( 293cdf0e10cSrcweir convertToARGB(deviceColor)); 294cdf0e10cSrcweir return targetColorSpace->convertFromARGB(aIntermediate); 295cdf0e10cSrcweir } convertToRGB(const uno::Sequence<double> & deviceColor)296cdf0e10cSrcweir virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertToRGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 297cdf0e10cSrcweir { 298cdf0e10cSrcweir const double* pIn( deviceColor.getConstArray() ); 299cdf0e10cSrcweir const sal_Size nLen( deviceColor.getLength() ); 300cdf0e10cSrcweir ENSURE_ARG_OR_THROW2(nLen%4==0, 301cdf0e10cSrcweir "number of channels no multiple of 4", 302cdf0e10cSrcweir static_cast<rendering::XColorSpace*>(this), 0); 303cdf0e10cSrcweir 304cdf0e10cSrcweir uno::Sequence< rendering::RGBColor > aRes(nLen/4); 305cdf0e10cSrcweir rendering::RGBColor* pOut( aRes.getArray() ); 306cdf0e10cSrcweir for( sal_Size i=0; i<nLen; i+=4 ) 307cdf0e10cSrcweir { 308cdf0e10cSrcweir *pOut++ = rendering::RGBColor(pIn[0],pIn[1],pIn[2]); 309cdf0e10cSrcweir pIn += 4; 310cdf0e10cSrcweir } 311cdf0e10cSrcweir return aRes; 312cdf0e10cSrcweir } convertToARGB(const uno::Sequence<double> & deviceColor)313cdf0e10cSrcweir virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 314cdf0e10cSrcweir { 315cdf0e10cSrcweir const double* pIn( deviceColor.getConstArray() ); 316cdf0e10cSrcweir const sal_Size nLen( deviceColor.getLength() ); 317cdf0e10cSrcweir ENSURE_ARG_OR_THROW2(nLen%4==0, 318cdf0e10cSrcweir "number of channels no multiple of 4", 319cdf0e10cSrcweir static_cast<rendering::XColorSpace*>(this), 0); 320cdf0e10cSrcweir 321cdf0e10cSrcweir uno::Sequence< rendering::ARGBColor > aRes(nLen/4); 322cdf0e10cSrcweir rendering::ARGBColor* pOut( aRes.getArray() ); 323cdf0e10cSrcweir for( sal_Size i=0; i<nLen; i+=4 ) 324cdf0e10cSrcweir { 325cdf0e10cSrcweir *pOut++ = rendering::ARGBColor(pIn[3],pIn[0],pIn[1],pIn[2]); 326cdf0e10cSrcweir pIn += 4; 327cdf0e10cSrcweir } 328cdf0e10cSrcweir return aRes; 329cdf0e10cSrcweir } convertToPARGB(const uno::Sequence<double> & deviceColor)330cdf0e10cSrcweir virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertToPARGB( const uno::Sequence< double >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 331cdf0e10cSrcweir { 332cdf0e10cSrcweir const double* pIn( deviceColor.getConstArray() ); 333cdf0e10cSrcweir const sal_Size nLen( deviceColor.getLength() ); 334cdf0e10cSrcweir ENSURE_ARG_OR_THROW2(nLen%4==0, 335cdf0e10cSrcweir "number of channels no multiple of 4", 336cdf0e10cSrcweir static_cast<rendering::XColorSpace*>(this), 0); 337cdf0e10cSrcweir 338cdf0e10cSrcweir uno::Sequence< rendering::ARGBColor > aRes(nLen/4); 339cdf0e10cSrcweir rendering::ARGBColor* pOut( aRes.getArray() ); 340cdf0e10cSrcweir for( sal_Size i=0; i<nLen; i+=4 ) 341cdf0e10cSrcweir { 342cdf0e10cSrcweir *pOut++ = rendering::ARGBColor(pIn[3],pIn[3]*pIn[0],pIn[3]*pIn[1],pIn[3]*pIn[2]); 343cdf0e10cSrcweir pIn += 4; 344cdf0e10cSrcweir } 345cdf0e10cSrcweir return aRes; 346cdf0e10cSrcweir } convertFromRGB(const uno::Sequence<rendering::RGBColor> & rgbColor)347cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 348cdf0e10cSrcweir { 349cdf0e10cSrcweir const rendering::RGBColor* pIn( rgbColor.getConstArray() ); 350cdf0e10cSrcweir const sal_Size nLen( rgbColor.getLength() ); 351cdf0e10cSrcweir 352cdf0e10cSrcweir uno::Sequence< double > aRes(nLen*4); 353cdf0e10cSrcweir double* pColors=aRes.getArray(); 354cdf0e10cSrcweir for( sal_Size i=0; i<nLen; ++i ) 355cdf0e10cSrcweir { 356cdf0e10cSrcweir *pColors++ = pIn->Red; 357cdf0e10cSrcweir *pColors++ = pIn->Green; 358cdf0e10cSrcweir *pColors++ = pIn->Blue; 359cdf0e10cSrcweir *pColors++ = 1.0; 360cdf0e10cSrcweir ++pIn; 361cdf0e10cSrcweir } 362cdf0e10cSrcweir return aRes; 363cdf0e10cSrcweir } convertFromARGB(const uno::Sequence<rendering::ARGBColor> & rgbColor)364cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 365cdf0e10cSrcweir { 366cdf0e10cSrcweir const rendering::ARGBColor* pIn( rgbColor.getConstArray() ); 367cdf0e10cSrcweir const sal_Size nLen( rgbColor.getLength() ); 368cdf0e10cSrcweir 369cdf0e10cSrcweir uno::Sequence< double > aRes(nLen*4); 370cdf0e10cSrcweir double* pColors=aRes.getArray(); 371cdf0e10cSrcweir for( sal_Size i=0; i<nLen; ++i ) 372cdf0e10cSrcweir { 373cdf0e10cSrcweir *pColors++ = pIn->Red; 374cdf0e10cSrcweir *pColors++ = pIn->Green; 375cdf0e10cSrcweir *pColors++ = pIn->Blue; 376cdf0e10cSrcweir *pColors++ = pIn->Alpha; 377cdf0e10cSrcweir ++pIn; 378cdf0e10cSrcweir } 379cdf0e10cSrcweir return aRes; 380cdf0e10cSrcweir } convertFromPARGB(const uno::Sequence<rendering::ARGBColor> & rgbColor)381cdf0e10cSrcweir virtual uno::Sequence< double > SAL_CALL convertFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 382cdf0e10cSrcweir { 383cdf0e10cSrcweir const rendering::ARGBColor* pIn( rgbColor.getConstArray() ); 384cdf0e10cSrcweir const sal_Size nLen( rgbColor.getLength() ); 385cdf0e10cSrcweir 386cdf0e10cSrcweir uno::Sequence< double > aRes(nLen*4); 387cdf0e10cSrcweir double* pColors=aRes.getArray(); 388cdf0e10cSrcweir for( sal_Size i=0; i<nLen; ++i ) 389cdf0e10cSrcweir { 390cdf0e10cSrcweir *pColors++ = pIn->Red/pIn->Alpha; 391cdf0e10cSrcweir *pColors++ = pIn->Green/pIn->Alpha; 392cdf0e10cSrcweir *pColors++ = pIn->Blue/pIn->Alpha; 393cdf0e10cSrcweir *pColors++ = pIn->Alpha; 394cdf0e10cSrcweir ++pIn; 395cdf0e10cSrcweir } 396cdf0e10cSrcweir return aRes; 397cdf0e10cSrcweir } 398cdf0e10cSrcweir 399cdf0e10cSrcweir // XIntegerBitmapColorSpace getBitsPerPixel()400cdf0e10cSrcweir virtual ::sal_Int32 SAL_CALL getBitsPerPixel( ) throw (uno::RuntimeException) 401cdf0e10cSrcweir { 402cdf0e10cSrcweir return 32; 403cdf0e10cSrcweir } getComponentBitCounts()404cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int32 > SAL_CALL getComponentBitCounts( ) throw (uno::RuntimeException) 405cdf0e10cSrcweir { 406cdf0e10cSrcweir return maBitCounts; 407cdf0e10cSrcweir } getEndianness()408cdf0e10cSrcweir virtual ::sal_Int8 SAL_CALL getEndianness( ) throw (uno::RuntimeException) 409cdf0e10cSrcweir { 410cdf0e10cSrcweir return util::Endianness::LITTLE; 411cdf0e10cSrcweir } convertFromIntegerColorSpace(const uno::Sequence<::sal_Int8> & deviceColor,const uno::Reference<rendering::XColorSpace> & targetColorSpace)412cdf0e10cSrcweir virtual uno::Sequence<double> SAL_CALL convertFromIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor, 413cdf0e10cSrcweir const uno::Reference< rendering::XColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException, 414cdf0e10cSrcweir uno::RuntimeException) 415cdf0e10cSrcweir { 416cdf0e10cSrcweir if( dynamic_cast<StandardColorSpace*>(targetColorSpace.get()) ) 417cdf0e10cSrcweir { 418cdf0e10cSrcweir const sal_Int8* pIn( deviceColor.getConstArray() ); 419cdf0e10cSrcweir const sal_Size nLen( deviceColor.getLength() ); 420cdf0e10cSrcweir ENSURE_ARG_OR_THROW2(nLen%4==0, 421cdf0e10cSrcweir "number of channels no multiple of 4", 422cdf0e10cSrcweir static_cast<rendering::XColorSpace*>(this), 0); 423cdf0e10cSrcweir 424cdf0e10cSrcweir uno::Sequence<double> aRes(nLen); 425cdf0e10cSrcweir double* pOut( aRes.getArray() ); 426cdf0e10cSrcweir for( sal_Size i=0; i<nLen; i+=4 ) 427cdf0e10cSrcweir { 428cdf0e10cSrcweir *pOut++ = vcl::unotools::toDoubleColor(*pIn++); 429cdf0e10cSrcweir *pOut++ = vcl::unotools::toDoubleColor(*pIn++); 430cdf0e10cSrcweir *pOut++ = vcl::unotools::toDoubleColor(*pIn++); 431cdf0e10cSrcweir *pOut++ = vcl::unotools::toDoubleColor(255-*pIn++); 432cdf0e10cSrcweir } 433cdf0e10cSrcweir return aRes; 434cdf0e10cSrcweir } 435cdf0e10cSrcweir else 436cdf0e10cSrcweir { 437cdf0e10cSrcweir // TODO(P3): if we know anything about target 438cdf0e10cSrcweir // colorspace, this can be greatly sped up 439cdf0e10cSrcweir uno::Sequence<rendering::ARGBColor> aIntermediate( 440cdf0e10cSrcweir convertIntegerToARGB(deviceColor)); 441cdf0e10cSrcweir return targetColorSpace->convertFromARGB(aIntermediate); 442cdf0e10cSrcweir } 443cdf0e10cSrcweir } convertToIntegerColorSpace(const uno::Sequence<::sal_Int8> & deviceColor,const uno::Reference<rendering::XIntegerBitmapColorSpace> & targetColorSpace)444cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertToIntegerColorSpace( const uno::Sequence< ::sal_Int8 >& deviceColor, 445cdf0e10cSrcweir const uno::Reference< rendering::XIntegerBitmapColorSpace >& targetColorSpace ) throw (lang::IllegalArgumentException, 446cdf0e10cSrcweir uno::RuntimeException) 447cdf0e10cSrcweir { 448cdf0e10cSrcweir if( dynamic_cast<StandardColorSpace*>(targetColorSpace.get()) ) 449cdf0e10cSrcweir { 450cdf0e10cSrcweir // it's us, so simply pass-through the data 451cdf0e10cSrcweir return deviceColor; 452cdf0e10cSrcweir } 453cdf0e10cSrcweir else 454cdf0e10cSrcweir { 455cdf0e10cSrcweir // TODO(P3): if we know anything about target 456cdf0e10cSrcweir // colorspace, this can be greatly sped up 457cdf0e10cSrcweir uno::Sequence<rendering::ARGBColor> aIntermediate( 458cdf0e10cSrcweir convertIntegerToARGB(deviceColor)); 459cdf0e10cSrcweir return targetColorSpace->convertIntegerFromARGB(aIntermediate); 460cdf0e10cSrcweir } 461cdf0e10cSrcweir } convertIntegerToRGB(const uno::Sequence<::sal_Int8> & deviceColor)462cdf0e10cSrcweir virtual uno::Sequence< rendering::RGBColor > SAL_CALL convertIntegerToRGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 463cdf0e10cSrcweir { 464cdf0e10cSrcweir const sal_Int8* pIn( deviceColor.getConstArray() ); 465cdf0e10cSrcweir const sal_Size nLen( deviceColor.getLength() ); 466cdf0e10cSrcweir ENSURE_ARG_OR_THROW2(nLen%4==0, 467cdf0e10cSrcweir "number of channels no multiple of 4", 468cdf0e10cSrcweir static_cast<rendering::XColorSpace*>(this), 0); 469cdf0e10cSrcweir 470cdf0e10cSrcweir uno::Sequence< rendering::RGBColor > aRes(nLen/4); 471cdf0e10cSrcweir rendering::RGBColor* pOut( aRes.getArray() ); 472cdf0e10cSrcweir for( sal_Size i=0; i<nLen; i+=4 ) 473cdf0e10cSrcweir { 474cdf0e10cSrcweir *pOut++ = rendering::RGBColor( 475cdf0e10cSrcweir vcl::unotools::toDoubleColor(pIn[0]), 476cdf0e10cSrcweir vcl::unotools::toDoubleColor(pIn[1]), 477cdf0e10cSrcweir vcl::unotools::toDoubleColor(pIn[2])); 478cdf0e10cSrcweir pIn += 4; 479cdf0e10cSrcweir } 480cdf0e10cSrcweir return aRes; 481cdf0e10cSrcweir } 482cdf0e10cSrcweir convertIntegerToARGB(const uno::Sequence<::sal_Int8> & deviceColor)483cdf0e10cSrcweir virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 484cdf0e10cSrcweir { 485cdf0e10cSrcweir const sal_Int8* pIn( deviceColor.getConstArray() ); 486cdf0e10cSrcweir const sal_Size nLen( deviceColor.getLength() ); 487cdf0e10cSrcweir ENSURE_ARG_OR_THROW2(nLen%4==0, 488cdf0e10cSrcweir "number of channels no multiple of 4", 489cdf0e10cSrcweir static_cast<rendering::XColorSpace*>(this), 0); 490cdf0e10cSrcweir 491cdf0e10cSrcweir uno::Sequence< rendering::ARGBColor > aRes(nLen/4); 492cdf0e10cSrcweir rendering::ARGBColor* pOut( aRes.getArray() ); 493cdf0e10cSrcweir for( sal_Size i=0; i<nLen; i+=4 ) 494cdf0e10cSrcweir { 495cdf0e10cSrcweir *pOut++ = rendering::ARGBColor( 496cdf0e10cSrcweir vcl::unotools::toDoubleColor(255-pIn[3]), 497cdf0e10cSrcweir vcl::unotools::toDoubleColor(pIn[0]), 498cdf0e10cSrcweir vcl::unotools::toDoubleColor(pIn[1]), 499cdf0e10cSrcweir vcl::unotools::toDoubleColor(pIn[2])); 500cdf0e10cSrcweir pIn += 4; 501cdf0e10cSrcweir } 502cdf0e10cSrcweir return aRes; 503cdf0e10cSrcweir } 504cdf0e10cSrcweir convertIntegerToPARGB(const uno::Sequence<::sal_Int8> & deviceColor)505cdf0e10cSrcweir virtual uno::Sequence< rendering::ARGBColor > SAL_CALL convertIntegerToPARGB( const uno::Sequence< ::sal_Int8 >& deviceColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 506cdf0e10cSrcweir { 507cdf0e10cSrcweir const sal_Int8* pIn( deviceColor.getConstArray() ); 508cdf0e10cSrcweir const sal_Size nLen( deviceColor.getLength() ); 509cdf0e10cSrcweir ENSURE_ARG_OR_THROW2(nLen%4==0, 510cdf0e10cSrcweir "number of channels no multiple of 4", 511cdf0e10cSrcweir static_cast<rendering::XColorSpace*>(this), 0); 512cdf0e10cSrcweir 513cdf0e10cSrcweir uno::Sequence< rendering::ARGBColor > aRes(nLen/4); 514cdf0e10cSrcweir rendering::ARGBColor* pOut( aRes.getArray() ); 515cdf0e10cSrcweir for( sal_Size i=0; i<nLen; i+=4 ) 516cdf0e10cSrcweir { 517cdf0e10cSrcweir const sal_Int8 nAlpha( 255-pIn[3] ); 518cdf0e10cSrcweir *pOut++ = rendering::ARGBColor( 519cdf0e10cSrcweir vcl::unotools::toDoubleColor(nAlpha), 520cdf0e10cSrcweir vcl::unotools::toDoubleColor(nAlpha*pIn[0]), 521cdf0e10cSrcweir vcl::unotools::toDoubleColor(nAlpha*pIn[1]), 522cdf0e10cSrcweir vcl::unotools::toDoubleColor(nAlpha*pIn[2])); 523cdf0e10cSrcweir pIn += 4; 524cdf0e10cSrcweir } 525cdf0e10cSrcweir return aRes; 526cdf0e10cSrcweir } 527cdf0e10cSrcweir convertIntegerFromRGB(const uno::Sequence<rendering::RGBColor> & rgbColor)528cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromRGB( const uno::Sequence< rendering::RGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 529cdf0e10cSrcweir { 530cdf0e10cSrcweir const rendering::RGBColor* pIn( rgbColor.getConstArray() ); 531cdf0e10cSrcweir const sal_Size nLen( rgbColor.getLength() ); 532cdf0e10cSrcweir 533cdf0e10cSrcweir uno::Sequence< sal_Int8 > aRes(nLen*4); 534cdf0e10cSrcweir sal_Int8* pColors=aRes.getArray(); 535cdf0e10cSrcweir for( sal_Size i=0; i<nLen; ++i ) 536cdf0e10cSrcweir { 537cdf0e10cSrcweir *pColors++ = vcl::unotools::toByteColor(pIn->Red); 538cdf0e10cSrcweir *pColors++ = vcl::unotools::toByteColor(pIn->Green); 539cdf0e10cSrcweir *pColors++ = vcl::unotools::toByteColor(pIn->Blue); 540cdf0e10cSrcweir *pColors++ = 0; 541cdf0e10cSrcweir ++pIn; 542cdf0e10cSrcweir } 543cdf0e10cSrcweir return aRes; 544cdf0e10cSrcweir } 545cdf0e10cSrcweir convertIntegerFromARGB(const uno::Sequence<rendering::ARGBColor> & rgbColor)546cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 547cdf0e10cSrcweir { 548cdf0e10cSrcweir const rendering::ARGBColor* pIn( rgbColor.getConstArray() ); 549cdf0e10cSrcweir const sal_Size nLen( rgbColor.getLength() ); 550cdf0e10cSrcweir 551cdf0e10cSrcweir uno::Sequence< sal_Int8 > aRes(nLen*4); 552cdf0e10cSrcweir sal_Int8* pColors=aRes.getArray(); 553cdf0e10cSrcweir for( sal_Size i=0; i<nLen; ++i ) 554cdf0e10cSrcweir { 555cdf0e10cSrcweir *pColors++ = vcl::unotools::toByteColor(pIn->Red); 556cdf0e10cSrcweir *pColors++ = vcl::unotools::toByteColor(pIn->Green); 557cdf0e10cSrcweir *pColors++ = vcl::unotools::toByteColor(pIn->Blue); 558cdf0e10cSrcweir *pColors++ = 255-vcl::unotools::toByteColor(pIn->Alpha); 559cdf0e10cSrcweir ++pIn; 560cdf0e10cSrcweir } 561cdf0e10cSrcweir return aRes; 562cdf0e10cSrcweir } 563cdf0e10cSrcweir convertIntegerFromPARGB(const uno::Sequence<rendering::ARGBColor> & rgbColor)564cdf0e10cSrcweir virtual uno::Sequence< ::sal_Int8 > SAL_CALL convertIntegerFromPARGB( const uno::Sequence< rendering::ARGBColor >& rgbColor ) throw (lang::IllegalArgumentException, uno::RuntimeException) 565cdf0e10cSrcweir { 566cdf0e10cSrcweir const rendering::ARGBColor* pIn( rgbColor.getConstArray() ); 567cdf0e10cSrcweir const sal_Size nLen( rgbColor.getLength() ); 568cdf0e10cSrcweir 569cdf0e10cSrcweir uno::Sequence< sal_Int8 > aRes(nLen*4); 570cdf0e10cSrcweir sal_Int8* pColors=aRes.getArray(); 571cdf0e10cSrcweir for( sal_Size i=0; i<nLen; ++i ) 572cdf0e10cSrcweir { 573cdf0e10cSrcweir *pColors++ = vcl::unotools::toByteColor(pIn->Red/pIn->Alpha); 574cdf0e10cSrcweir *pColors++ = vcl::unotools::toByteColor(pIn->Green/pIn->Alpha); 575cdf0e10cSrcweir *pColors++ = vcl::unotools::toByteColor(pIn->Blue/pIn->Alpha); 576cdf0e10cSrcweir *pColors++ = 255-vcl::unotools::toByteColor(pIn->Alpha); 577cdf0e10cSrcweir ++pIn; 578cdf0e10cSrcweir } 579cdf0e10cSrcweir return aRes; 580cdf0e10cSrcweir } 581cdf0e10cSrcweir 582cdf0e10cSrcweir public: StandardColorSpace()583cdf0e10cSrcweir StandardColorSpace() : 584cdf0e10cSrcweir maComponentTags(4), 585cdf0e10cSrcweir maBitCounts(4) 586cdf0e10cSrcweir { 587cdf0e10cSrcweir sal_Int8* pTags = maComponentTags.getArray(); 588cdf0e10cSrcweir sal_Int32* pBitCounts = maBitCounts.getArray(); 589cdf0e10cSrcweir pTags[0] = rendering::ColorComponentTag::RGB_RED; 590cdf0e10cSrcweir pTags[1] = rendering::ColorComponentTag::RGB_GREEN; 591cdf0e10cSrcweir pTags[2] = rendering::ColorComponentTag::RGB_BLUE; 592cdf0e10cSrcweir pTags[3] = rendering::ColorComponentTag::ALPHA; 593cdf0e10cSrcweir 594cdf0e10cSrcweir pBitCounts[0] = 595cdf0e10cSrcweir pBitCounts[1] = 596cdf0e10cSrcweir pBitCounts[2] = 597cdf0e10cSrcweir pBitCounts[3] = 8; 598cdf0e10cSrcweir } 599cdf0e10cSrcweir }; 600cdf0e10cSrcweir 601cdf0e10cSrcweir struct StandardColorSpaceHolder : public rtl::StaticWithInit<uno::Reference<rendering::XIntegerBitmapColorSpace>, 602cdf0e10cSrcweir StandardColorSpaceHolder> 603cdf0e10cSrcweir { operator ()canvas::tools::__anon85958e0f0111::StandardColorSpaceHolder604cdf0e10cSrcweir uno::Reference<rendering::XIntegerBitmapColorSpace> operator()() 605cdf0e10cSrcweir { 606cdf0e10cSrcweir return new StandardColorSpace(); 607cdf0e10cSrcweir } 608cdf0e10cSrcweir }; 609cdf0e10cSrcweir } 610cdf0e10cSrcweir getStdColorSpace()611cdf0e10cSrcweir uno::Reference<rendering::XIntegerBitmapColorSpace> getStdColorSpace() 612cdf0e10cSrcweir { 613cdf0e10cSrcweir return StandardColorSpaceHolder::get(); 614cdf0e10cSrcweir } 615cdf0e10cSrcweir getStdMemoryLayout(const geometry::IntegerSize2D & rBmpSize)616cdf0e10cSrcweir rendering::IntegerBitmapLayout getStdMemoryLayout( const geometry::IntegerSize2D& rBmpSize ) 617cdf0e10cSrcweir { 618cdf0e10cSrcweir rendering::IntegerBitmapLayout aLayout; 619cdf0e10cSrcweir 620cdf0e10cSrcweir aLayout.ScanLines = rBmpSize.Height; 621cdf0e10cSrcweir aLayout.ScanLineBytes = rBmpSize.Width*4; 622cdf0e10cSrcweir aLayout.ScanLineStride = aLayout.ScanLineBytes; 623cdf0e10cSrcweir aLayout.PlaneStride = 0; 624cdf0e10cSrcweir aLayout.ColorSpace = getStdColorSpace(); 625cdf0e10cSrcweir aLayout.Palette.clear(); 626cdf0e10cSrcweir aLayout.IsMsbFirst = sal_False; 627cdf0e10cSrcweir 628cdf0e10cSrcweir return aLayout; 629cdf0e10cSrcweir } 630cdf0e10cSrcweir stdIntSequenceToColor(const uno::Sequence<sal_Int8> & rColor)631cdf0e10cSrcweir ::Color stdIntSequenceToColor( const uno::Sequence<sal_Int8>& rColor ) 632cdf0e10cSrcweir { 633cdf0e10cSrcweir #ifdef OSL_BIGENDIAN 634cdf0e10cSrcweir const sal_Int8* pCols( rColor.getConstArray() ); 635cdf0e10cSrcweir return ::Color( pCols[3], pCols[0], pCols[1], pCols[2] ); 636cdf0e10cSrcweir #else 637cdf0e10cSrcweir return ::Color( *reinterpret_cast< const ::ColorData* >(rColor.getConstArray()) ); 638cdf0e10cSrcweir #endif 639cdf0e10cSrcweir } 640cdf0e10cSrcweir colorToStdIntSequence(const::Color & rColor)641cdf0e10cSrcweir uno::Sequence<sal_Int8> colorToStdIntSequence( const ::Color& rColor ) 642cdf0e10cSrcweir { 643cdf0e10cSrcweir uno::Sequence<sal_Int8> aRet(4); 644cdf0e10cSrcweir sal_Int8* pCols( aRet.getArray() ); 645cdf0e10cSrcweir #ifdef OSL_BIGENDIAN 646cdf0e10cSrcweir pCols[0] = rColor.GetRed(); 647cdf0e10cSrcweir pCols[1] = rColor.GetGreen(); 648cdf0e10cSrcweir pCols[2] = rColor.GetBlue(); 649cdf0e10cSrcweir pCols[3] = 255-rColor.GetTransparency(); 650cdf0e10cSrcweir #else 651cdf0e10cSrcweir *reinterpret_cast<sal_Int32*>(pCols) = rColor.GetColor(); 652cdf0e10cSrcweir #endif 653cdf0e10cSrcweir return aRet; 654cdf0e10cSrcweir } 655cdf0e10cSrcweir 656cdf0e10cSrcweir // Create a corrected view transformation out of the give one, 657cdf0e10cSrcweir // which ensures that the rectangle given by (0,0) and 658cdf0e10cSrcweir // rSpriteSize is mapped with its left,top corner to (0,0) 659cdf0e10cSrcweir // again. This is required to properly render sprite 660cdf0e10cSrcweir // animations to buffer bitmaps. calcRectToOriginTransform(::basegfx::B2DHomMatrix & o_transform,const::basegfx::B2DRange & i_srcRect,const::basegfx::B2DHomMatrix & i_transformation)661cdf0e10cSrcweir ::basegfx::B2DHomMatrix& calcRectToOriginTransform( ::basegfx::B2DHomMatrix& o_transform, 662cdf0e10cSrcweir const ::basegfx::B2DRange& i_srcRect, 663cdf0e10cSrcweir const ::basegfx::B2DHomMatrix& i_transformation ) 664cdf0e10cSrcweir { 665cdf0e10cSrcweir if( i_srcRect.isEmpty() ) 666cdf0e10cSrcweir return o_transform=i_transformation; 667cdf0e10cSrcweir 668cdf0e10cSrcweir // transform by given transformation 669cdf0e10cSrcweir ::basegfx::B2DRectangle aTransformedRect; 670cdf0e10cSrcweir 671cdf0e10cSrcweir calcTransformedRectBounds( aTransformedRect, 672cdf0e10cSrcweir i_srcRect, 673cdf0e10cSrcweir i_transformation ); 674cdf0e10cSrcweir 675cdf0e10cSrcweir // now move resulting left,top point of bounds to (0,0) 676cdf0e10cSrcweir const basegfx::B2DHomMatrix aCorrectedTransform(basegfx::tools::createTranslateB2DHomMatrix( 677cdf0e10cSrcweir -aTransformedRect.getMinX(), -aTransformedRect.getMinY())); 678cdf0e10cSrcweir 679cdf0e10cSrcweir // prepend to original transformation 680cdf0e10cSrcweir o_transform = aCorrectedTransform * i_transformation; 681cdf0e10cSrcweir 682cdf0e10cSrcweir return o_transform; 683cdf0e10cSrcweir } 684cdf0e10cSrcweir calcTransformedRectBounds(::basegfx::B2DRange & outRect,const::basegfx::B2DRange & inRect,const::basegfx::B2DHomMatrix & transformation)685cdf0e10cSrcweir ::basegfx::B2DRange& calcTransformedRectBounds( ::basegfx::B2DRange& outRect, 686cdf0e10cSrcweir const ::basegfx::B2DRange& inRect, 687cdf0e10cSrcweir const ::basegfx::B2DHomMatrix& transformation ) 688cdf0e10cSrcweir { 689cdf0e10cSrcweir outRect.reset(); 690cdf0e10cSrcweir 691cdf0e10cSrcweir if( inRect.isEmpty() ) 692cdf0e10cSrcweir return outRect; 693cdf0e10cSrcweir 694cdf0e10cSrcweir // transform all four extremal points of the rectangle, 695cdf0e10cSrcweir // take bounding rect of those. 696cdf0e10cSrcweir 697cdf0e10cSrcweir // transform left-top point 698cdf0e10cSrcweir outRect.expand( transformation * inRect.getMinimum() ); 699cdf0e10cSrcweir 700cdf0e10cSrcweir // transform bottom-right point 701cdf0e10cSrcweir outRect.expand( transformation * inRect.getMaximum() ); 702cdf0e10cSrcweir 703cdf0e10cSrcweir ::basegfx::B2DPoint aPoint; 704cdf0e10cSrcweir 705cdf0e10cSrcweir // transform top-right point 706cdf0e10cSrcweir aPoint.setX( inRect.getMaxX() ); 707cdf0e10cSrcweir aPoint.setY( inRect.getMinY() ); 708cdf0e10cSrcweir 709cdf0e10cSrcweir aPoint *= transformation; 710cdf0e10cSrcweir outRect.expand( aPoint ); 711cdf0e10cSrcweir 712cdf0e10cSrcweir // transform bottom-left point 713cdf0e10cSrcweir aPoint.setX( inRect.getMinX() ); 714cdf0e10cSrcweir aPoint.setY( inRect.getMaxY() ); 715cdf0e10cSrcweir 716cdf0e10cSrcweir aPoint *= transformation; 717cdf0e10cSrcweir outRect.expand( aPoint ); 718cdf0e10cSrcweir 719cdf0e10cSrcweir // over and out. 720cdf0e10cSrcweir return outRect; 721cdf0e10cSrcweir } 722cdf0e10cSrcweir calcRectToRectTransform(::basegfx::B2DHomMatrix & o_transform,const::basegfx::B2DRange & destRect,const::basegfx::B2DRange & srcRect,const::basegfx::B2DHomMatrix & transformation)723cdf0e10cSrcweir ::basegfx::B2DHomMatrix& calcRectToRectTransform( ::basegfx::B2DHomMatrix& o_transform, 724cdf0e10cSrcweir const ::basegfx::B2DRange& destRect, 725cdf0e10cSrcweir const ::basegfx::B2DRange& srcRect, 726cdf0e10cSrcweir const ::basegfx::B2DHomMatrix& transformation ) 727cdf0e10cSrcweir { 728cdf0e10cSrcweir if( srcRect.isEmpty() || 729cdf0e10cSrcweir destRect.isEmpty() ) 730cdf0e10cSrcweir { 731cdf0e10cSrcweir return o_transform=transformation; 732cdf0e10cSrcweir } 733cdf0e10cSrcweir 734cdf0e10cSrcweir // transform inputRect by transformation 735cdf0e10cSrcweir ::basegfx::B2DRectangle aTransformedRect; 736cdf0e10cSrcweir calcTransformedRectBounds( aTransformedRect, 737cdf0e10cSrcweir srcRect, 738cdf0e10cSrcweir transformation ); 739cdf0e10cSrcweir 740cdf0e10cSrcweir // now move resulting left,top point of bounds to (0,0) 741cdf0e10cSrcweir basegfx::B2DHomMatrix aCorrectedTransform(basegfx::tools::createTranslateB2DHomMatrix( 742cdf0e10cSrcweir -aTransformedRect.getMinX(), -aTransformedRect.getMinY())); 743cdf0e10cSrcweir 744cdf0e10cSrcweir // scale to match outRect 745cdf0e10cSrcweir const double xDenom( aTransformedRect.getWidth() ); 746cdf0e10cSrcweir const double yDenom( aTransformedRect.getHeight() ); 747cdf0e10cSrcweir if( xDenom != 0.0 && yDenom != 0.0 ) 748cdf0e10cSrcweir aCorrectedTransform.scale( destRect.getWidth() / xDenom, 749cdf0e10cSrcweir destRect.getHeight() / yDenom ); 750cdf0e10cSrcweir // TODO(E2): error handling 751cdf0e10cSrcweir 752cdf0e10cSrcweir // translate to final position 753cdf0e10cSrcweir aCorrectedTransform.translate( destRect.getMinX(), 754cdf0e10cSrcweir destRect.getMinY() ); 755cdf0e10cSrcweir 756cdf0e10cSrcweir ::basegfx::B2DHomMatrix transform( transformation ); 757cdf0e10cSrcweir o_transform = aCorrectedTransform * transform; 758cdf0e10cSrcweir 759cdf0e10cSrcweir return o_transform; 760cdf0e10cSrcweir } 761cdf0e10cSrcweir isInside(const::basegfx::B2DRange & rContainedRect,const::basegfx::B2DRange & rTransformRect,const::basegfx::B2DHomMatrix & rTransformation)762cdf0e10cSrcweir bool isInside( const ::basegfx::B2DRange& rContainedRect, 763cdf0e10cSrcweir const ::basegfx::B2DRange& rTransformRect, 764cdf0e10cSrcweir const ::basegfx::B2DHomMatrix& rTransformation ) 765cdf0e10cSrcweir { 766cdf0e10cSrcweir if( rContainedRect.isEmpty() || rTransformRect.isEmpty() ) 767cdf0e10cSrcweir return false; 768cdf0e10cSrcweir 769cdf0e10cSrcweir ::basegfx::B2DPolygon aPoly( 770cdf0e10cSrcweir ::basegfx::tools::createPolygonFromRect( rTransformRect ) ); 771cdf0e10cSrcweir aPoly.transform( rTransformation ); 772cdf0e10cSrcweir 773cdf0e10cSrcweir return ::basegfx::tools::isInside( aPoly, 774cdf0e10cSrcweir ::basegfx::tools::createPolygonFromRect( 775cdf0e10cSrcweir rContainedRect ), 776cdf0e10cSrcweir true ); 777cdf0e10cSrcweir } 778cdf0e10cSrcweir 779cdf0e10cSrcweir namespace 780cdf0e10cSrcweir { clipAreaImpl(::basegfx::B2IRange * o_pDestArea,::basegfx::B2IRange & io_rSourceArea,::basegfx::B2IPoint & io_rDestPoint,const::basegfx::B2IRange & rSourceBounds,const::basegfx::B2IRange & rDestBounds)781cdf0e10cSrcweir bool clipAreaImpl( ::basegfx::B2IRange* o_pDestArea, 782cdf0e10cSrcweir ::basegfx::B2IRange& io_rSourceArea, 783cdf0e10cSrcweir ::basegfx::B2IPoint& io_rDestPoint, 784cdf0e10cSrcweir const ::basegfx::B2IRange& rSourceBounds, 785cdf0e10cSrcweir const ::basegfx::B2IRange& rDestBounds ) 786cdf0e10cSrcweir { 787cdf0e10cSrcweir const ::basegfx::B2IPoint aSourceTopLeft( 788cdf0e10cSrcweir io_rSourceArea.getMinimum() ); 789cdf0e10cSrcweir 790cdf0e10cSrcweir ::basegfx::B2IRange aLocalSourceArea( io_rSourceArea ); 791cdf0e10cSrcweir 792cdf0e10cSrcweir // clip source area (which must be inside rSourceBounds) 793cdf0e10cSrcweir aLocalSourceArea.intersect( rSourceBounds ); 794cdf0e10cSrcweir 795cdf0e10cSrcweir if( aLocalSourceArea.isEmpty() ) 796cdf0e10cSrcweir return false; 797cdf0e10cSrcweir 798cdf0e10cSrcweir // calc relative new source area points (relative to orig 799cdf0e10cSrcweir // source area) 800cdf0e10cSrcweir const ::basegfx::B2IVector aUpperLeftOffset( 801cdf0e10cSrcweir aLocalSourceArea.getMinimum()-aSourceTopLeft ); 802cdf0e10cSrcweir const ::basegfx::B2IVector aLowerRightOffset( 803cdf0e10cSrcweir aLocalSourceArea.getMaximum()-aSourceTopLeft ); 804cdf0e10cSrcweir 805cdf0e10cSrcweir ::basegfx::B2IRange aLocalDestArea( io_rDestPoint + aUpperLeftOffset, 806cdf0e10cSrcweir io_rDestPoint + aLowerRightOffset ); 807cdf0e10cSrcweir 808cdf0e10cSrcweir // clip dest area (which must be inside rDestBounds) 809cdf0e10cSrcweir aLocalDestArea.intersect( rDestBounds ); 810cdf0e10cSrcweir 811cdf0e10cSrcweir if( aLocalDestArea.isEmpty() ) 812cdf0e10cSrcweir return false; 813cdf0e10cSrcweir 814cdf0e10cSrcweir // calc relative new dest area points (relative to orig 815cdf0e10cSrcweir // source area) 816cdf0e10cSrcweir const ::basegfx::B2IVector aDestUpperLeftOffset( 817cdf0e10cSrcweir aLocalDestArea.getMinimum()-io_rDestPoint ); 818cdf0e10cSrcweir const ::basegfx::B2IVector aDestLowerRightOffset( 819cdf0e10cSrcweir aLocalDestArea.getMaximum()-io_rDestPoint ); 820cdf0e10cSrcweir 821cdf0e10cSrcweir io_rSourceArea = ::basegfx::B2IRange( aSourceTopLeft + aDestUpperLeftOffset, 822cdf0e10cSrcweir aSourceTopLeft + aDestLowerRightOffset ); 823cdf0e10cSrcweir io_rDestPoint = aLocalDestArea.getMinimum(); 824cdf0e10cSrcweir 825cdf0e10cSrcweir if( o_pDestArea ) 826cdf0e10cSrcweir *o_pDestArea = aLocalDestArea; 827cdf0e10cSrcweir 828cdf0e10cSrcweir return true; 829cdf0e10cSrcweir } 830cdf0e10cSrcweir } 831cdf0e10cSrcweir clipScrollArea(::basegfx::B2IRange & io_rSourceArea,::basegfx::B2IPoint & io_rDestPoint,::std::vector<::basegfx::B2IRange> & o_ClippedAreas,const::basegfx::B2IRange & rBounds)832cdf0e10cSrcweir bool clipScrollArea( ::basegfx::B2IRange& io_rSourceArea, 833cdf0e10cSrcweir ::basegfx::B2IPoint& io_rDestPoint, 834cdf0e10cSrcweir ::std::vector< ::basegfx::B2IRange >& o_ClippedAreas, 835cdf0e10cSrcweir const ::basegfx::B2IRange& rBounds ) 836cdf0e10cSrcweir { 837cdf0e10cSrcweir ::basegfx::B2IRange aResultingDestArea; 838cdf0e10cSrcweir 839cdf0e10cSrcweir // compute full destination area (to determine uninitialized 840cdf0e10cSrcweir // areas below) 841cdf0e10cSrcweir const ::basegfx::B2I64Tuple& rRange( io_rSourceArea.getRange() ); 842cdf0e10cSrcweir ::basegfx::B2IRange aInputDestArea( io_rDestPoint.getX(), 843cdf0e10cSrcweir io_rDestPoint.getY(), 844cdf0e10cSrcweir (io_rDestPoint.getX() 845cdf0e10cSrcweir + static_cast<sal_Int32>(rRange.getX())), 846cdf0e10cSrcweir (io_rDestPoint.getY() 847cdf0e10cSrcweir + static_cast<sal_Int32>(rRange.getY())) ); 848cdf0e10cSrcweir // limit to output area (no point updating outside of it) 849cdf0e10cSrcweir aInputDestArea.intersect( rBounds ); 850cdf0e10cSrcweir 851cdf0e10cSrcweir // clip to rBounds 852cdf0e10cSrcweir if( !clipAreaImpl( &aResultingDestArea, 853cdf0e10cSrcweir io_rSourceArea, 854cdf0e10cSrcweir io_rDestPoint, 855cdf0e10cSrcweir rBounds, 856cdf0e10cSrcweir rBounds ) ) 857cdf0e10cSrcweir return false; 858cdf0e10cSrcweir 859cdf0e10cSrcweir // finally, compute all areas clipped off the total 860cdf0e10cSrcweir // destination area. 861cdf0e10cSrcweir ::basegfx::computeSetDifference( o_ClippedAreas, 862cdf0e10cSrcweir aInputDestArea, 863cdf0e10cSrcweir aResultingDestArea ); 864cdf0e10cSrcweir 865cdf0e10cSrcweir return true; 866cdf0e10cSrcweir } 867cdf0e10cSrcweir clipBlit(::basegfx::B2IRange & io_rSourceArea,::basegfx::B2IPoint & io_rDestPoint,const::basegfx::B2IRange & rSourceBounds,const::basegfx::B2IRange & rDestBounds)868cdf0e10cSrcweir bool clipBlit( ::basegfx::B2IRange& io_rSourceArea, 869cdf0e10cSrcweir ::basegfx::B2IPoint& io_rDestPoint, 870cdf0e10cSrcweir const ::basegfx::B2IRange& rSourceBounds, 871cdf0e10cSrcweir const ::basegfx::B2IRange& rDestBounds ) 872cdf0e10cSrcweir { 873cdf0e10cSrcweir return clipAreaImpl( NULL, 874cdf0e10cSrcweir io_rSourceArea, 875cdf0e10cSrcweir io_rDestPoint, 876cdf0e10cSrcweir rSourceBounds, 877cdf0e10cSrcweir rDestBounds ); 878cdf0e10cSrcweir } 879cdf0e10cSrcweir spritePixelAreaFromB2DRange(const::basegfx::B2DRange & rRange)880cdf0e10cSrcweir ::basegfx::B2IRange spritePixelAreaFromB2DRange( const ::basegfx::B2DRange& rRange ) 881cdf0e10cSrcweir { 882cdf0e10cSrcweir if( rRange.isEmpty() ) 883cdf0e10cSrcweir return ::basegfx::B2IRange(); 884cdf0e10cSrcweir 885cdf0e10cSrcweir const ::basegfx::B2IPoint aTopLeft( ::basegfx::fround( rRange.getMinX() ), 886cdf0e10cSrcweir ::basegfx::fround( rRange.getMinY() ) ); 887cdf0e10cSrcweir return ::basegfx::B2IRange( aTopLeft, 888cdf0e10cSrcweir aTopLeft + ::basegfx::B2IPoint( 889cdf0e10cSrcweir ::basegfx::fround( rRange.getWidth() ), 890cdf0e10cSrcweir ::basegfx::fround( rRange.getHeight() ) ) ); 891cdf0e10cSrcweir } 892cdf0e10cSrcweir getDeviceInfo(const uno::Reference<rendering::XCanvas> & i_rxCanvas,uno::Sequence<uno::Any> & o_rxParams)893cdf0e10cSrcweir uno::Sequence< uno::Any >& getDeviceInfo( const uno::Reference< rendering::XCanvas >& i_rxCanvas, 894cdf0e10cSrcweir uno::Sequence< uno::Any >& o_rxParams ) 895cdf0e10cSrcweir { 896cdf0e10cSrcweir o_rxParams.realloc( 0 ); 897cdf0e10cSrcweir 898cdf0e10cSrcweir if( i_rxCanvas.is() ) 899cdf0e10cSrcweir { 900cdf0e10cSrcweir try 901cdf0e10cSrcweir { 902cdf0e10cSrcweir uno::Reference< rendering::XGraphicDevice > xDevice( i_rxCanvas->getDevice(), 903cdf0e10cSrcweir uno::UNO_QUERY_THROW ); 904cdf0e10cSrcweir 905cdf0e10cSrcweir uno::Reference< lang::XServiceInfo > xServiceInfo( xDevice, 906cdf0e10cSrcweir uno::UNO_QUERY_THROW ); 907cdf0e10cSrcweir uno::Reference< beans::XPropertySet > xPropSet( xDevice, 908cdf0e10cSrcweir uno::UNO_QUERY_THROW ); 909cdf0e10cSrcweir 910cdf0e10cSrcweir o_rxParams.realloc( 2 ); 911cdf0e10cSrcweir 912cdf0e10cSrcweir o_rxParams[ 0 ] = uno::makeAny( xServiceInfo->getImplementationName() ); 913cdf0e10cSrcweir o_rxParams[ 1 ] = uno::makeAny( xPropSet->getPropertyValue( 914cdf0e10cSrcweir ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM("DeviceHandle") ) ) ); 915cdf0e10cSrcweir } 916cdf0e10cSrcweir catch( uno::Exception& ) 917cdf0e10cSrcweir { 918cdf0e10cSrcweir // ignore, but return empty sequence 919cdf0e10cSrcweir } 920cdf0e10cSrcweir } 921cdf0e10cSrcweir 922cdf0e10cSrcweir return o_rxParams; 923cdf0e10cSrcweir } 924cdf0e10cSrcweir getAbsoluteWindowRect(const awt::Rectangle & rRect,const uno::Reference<awt::XWindow2> & xWin)925cdf0e10cSrcweir awt::Rectangle getAbsoluteWindowRect( const awt::Rectangle& rRect, 926cdf0e10cSrcweir const uno::Reference< awt::XWindow2 >& xWin ) 927cdf0e10cSrcweir { 928cdf0e10cSrcweir awt::Rectangle aRetVal( rRect ); 929cdf0e10cSrcweir 930cdf0e10cSrcweir ::Window* pWindow = VCLUnoHelper::GetWindow(xWin); 931cdf0e10cSrcweir if( pWindow ) 932cdf0e10cSrcweir { 933cdf0e10cSrcweir ::Point aPoint( aRetVal.X, 934cdf0e10cSrcweir aRetVal.Y ); 935cdf0e10cSrcweir 936cdf0e10cSrcweir aPoint = pWindow->OutputToScreenPixel( aPoint ); 937cdf0e10cSrcweir 938cdf0e10cSrcweir aRetVal.X = aPoint.X(); 939cdf0e10cSrcweir aRetVal.Y = aPoint.Y(); 940cdf0e10cSrcweir } 941cdf0e10cSrcweir 942cdf0e10cSrcweir return aRetVal; 943cdf0e10cSrcweir } 944cdf0e10cSrcweir getBoundMarksPolyPolygon(const::basegfx::B2DRange & rRange)945cdf0e10cSrcweir ::basegfx::B2DPolyPolygon getBoundMarksPolyPolygon( const ::basegfx::B2DRange& rRange ) 946cdf0e10cSrcweir { 947cdf0e10cSrcweir ::basegfx::B2DPolyPolygon aPolyPoly; 948cdf0e10cSrcweir ::basegfx::B2DPolygon aPoly; 949cdf0e10cSrcweir 950cdf0e10cSrcweir const double nX0( rRange.getMinX() ); 951cdf0e10cSrcweir const double nY0( rRange.getMinY() ); 952cdf0e10cSrcweir const double nX1( rRange.getMaxX() ); 953cdf0e10cSrcweir const double nY1( rRange.getMaxY() ); 954cdf0e10cSrcweir 955cdf0e10cSrcweir aPoly.append( ::basegfx::B2DPoint( nX0+4, 956cdf0e10cSrcweir nY0 ) ); 957cdf0e10cSrcweir aPoly.append( ::basegfx::B2DPoint( nX0, 958cdf0e10cSrcweir nY0 ) ); 959cdf0e10cSrcweir aPoly.append( ::basegfx::B2DPoint( nX0, 960cdf0e10cSrcweir nY0+4 ) ); 961cdf0e10cSrcweir aPolyPoly.append( aPoly ); aPoly.clear(); 962cdf0e10cSrcweir 963cdf0e10cSrcweir aPoly.append( ::basegfx::B2DPoint( nX1-4, 964cdf0e10cSrcweir nY0 ) ); 965cdf0e10cSrcweir aPoly.append( ::basegfx::B2DPoint( nX1, 966cdf0e10cSrcweir nY0 ) ); 967cdf0e10cSrcweir aPoly.append( ::basegfx::B2DPoint( nX1, 968cdf0e10cSrcweir nY0+4 ) ); 969cdf0e10cSrcweir aPolyPoly.append( aPoly ); aPoly.clear(); 970cdf0e10cSrcweir 971cdf0e10cSrcweir aPoly.append( ::basegfx::B2DPoint( nX0+4, 972cdf0e10cSrcweir nY1 ) ); 973cdf0e10cSrcweir aPoly.append( ::basegfx::B2DPoint( nX0, 974cdf0e10cSrcweir nY1 ) ); 975cdf0e10cSrcweir aPoly.append( ::basegfx::B2DPoint( nX0, 976cdf0e10cSrcweir nY1-4 ) ); 977cdf0e10cSrcweir aPolyPoly.append( aPoly ); aPoly.clear(); 978cdf0e10cSrcweir 979cdf0e10cSrcweir aPoly.append( ::basegfx::B2DPoint( nX1-4, 980cdf0e10cSrcweir nY1 ) ); 981cdf0e10cSrcweir aPoly.append( ::basegfx::B2DPoint( nX1, 982cdf0e10cSrcweir nY1 ) ); 983cdf0e10cSrcweir aPoly.append( ::basegfx::B2DPoint( nX1, 984cdf0e10cSrcweir nY1-4 ) ); 985cdf0e10cSrcweir aPolyPoly.append( aPoly ); 986cdf0e10cSrcweir 987cdf0e10cSrcweir return aPolyPoly; 988cdf0e10cSrcweir } 989cdf0e10cSrcweir calcGradientStepCount(::basegfx::B2DHomMatrix & rTotalTransform,const rendering::ViewState & viewState,const rendering::RenderState & renderState,const rendering::Texture & texture,int nColorSteps)990cdf0e10cSrcweir int calcGradientStepCount( ::basegfx::B2DHomMatrix& rTotalTransform, 991cdf0e10cSrcweir const rendering::ViewState& viewState, 992cdf0e10cSrcweir const rendering::RenderState& renderState, 993cdf0e10cSrcweir const rendering::Texture& texture, 994cdf0e10cSrcweir int nColorSteps ) 995cdf0e10cSrcweir { 996cdf0e10cSrcweir // calculate overall texture transformation (directly from 997cdf0e10cSrcweir // texture to device space). 998cdf0e10cSrcweir ::basegfx::B2DHomMatrix aMatrix; 999cdf0e10cSrcweir 1000cdf0e10cSrcweir rTotalTransform.identity(); 1001cdf0e10cSrcweir ::basegfx::unotools::homMatrixFromAffineMatrix( rTotalTransform, 1002cdf0e10cSrcweir texture.AffineTransform ); 1003cdf0e10cSrcweir ::canvas::tools::mergeViewAndRenderTransform(aMatrix, 1004cdf0e10cSrcweir viewState, 1005cdf0e10cSrcweir renderState); 1006cdf0e10cSrcweir rTotalTransform *= aMatrix; // prepend total view/render transformation 1007cdf0e10cSrcweir 1008cdf0e10cSrcweir // determine size of gradient in device coordinate system 1009cdf0e10cSrcweir // (to e.g. determine sensible number of gradient steps) 1010cdf0e10cSrcweir ::basegfx::B2DPoint aLeftTop( 0.0, 0.0 ); 1011cdf0e10cSrcweir ::basegfx::B2DPoint aLeftBottom( 0.0, 1.0 ); 1012cdf0e10cSrcweir ::basegfx::B2DPoint aRightTop( 1.0, 0.0 ); 1013cdf0e10cSrcweir ::basegfx::B2DPoint aRightBottom( 1.0, 1.0 ); 1014cdf0e10cSrcweir 1015cdf0e10cSrcweir aLeftTop *= rTotalTransform; 1016cdf0e10cSrcweir aLeftBottom *= rTotalTransform; 1017cdf0e10cSrcweir aRightTop *= rTotalTransform; 1018cdf0e10cSrcweir aRightBottom*= rTotalTransform; 1019cdf0e10cSrcweir 1020cdf0e10cSrcweir // longest line in gradient bound rect 1021cdf0e10cSrcweir const int nGradientSize( 1022cdf0e10cSrcweir static_cast<int>( 1023cdf0e10cSrcweir ::std::max( 1024cdf0e10cSrcweir ::basegfx::B2DVector(aRightBottom-aLeftTop).getLength(), 1025cdf0e10cSrcweir ::basegfx::B2DVector(aRightTop-aLeftBottom).getLength() ) + 1.0 ) ); 1026cdf0e10cSrcweir 1027cdf0e10cSrcweir // typical number for pixel of the same color (strip size) 1028cdf0e10cSrcweir const int nStripSize( nGradientSize < 50 ? 2 : 4 ); 1029cdf0e10cSrcweir 1030cdf0e10cSrcweir // use at least three steps, and at utmost the number of color 1031cdf0e10cSrcweir // steps 1032cdf0e10cSrcweir return ::std::max( 3, 1033cdf0e10cSrcweir ::std::min( 1034cdf0e10cSrcweir nGradientSize / nStripSize, 1035cdf0e10cSrcweir nColorSteps ) ); 1036cdf0e10cSrcweir } 1037cdf0e10cSrcweir 1038cdf0e10cSrcweir } // namespace tools 1039cdf0e10cSrcweir 1040cdf0e10cSrcweir } // namespace canvas 1041