1*b1cdbd2cSJim Jagielski /************************************************************** 2*b1cdbd2cSJim Jagielski * 3*b1cdbd2cSJim Jagielski * Licensed to the Apache Software Foundation (ASF) under one 4*b1cdbd2cSJim Jagielski * or more contributor license agreements. See the NOTICE file 5*b1cdbd2cSJim Jagielski * distributed with this work for additional information 6*b1cdbd2cSJim Jagielski * regarding copyright ownership. The ASF licenses this file 7*b1cdbd2cSJim Jagielski * to you under the Apache License, Version 2.0 (the 8*b1cdbd2cSJim Jagielski * "License"); you may not use this file except in compliance 9*b1cdbd2cSJim Jagielski * with the License. You may obtain a copy of the License at 10*b1cdbd2cSJim Jagielski * 11*b1cdbd2cSJim Jagielski * http://www.apache.org/licenses/LICENSE-2.0 12*b1cdbd2cSJim Jagielski * 13*b1cdbd2cSJim Jagielski * Unless required by applicable law or agreed to in writing, 14*b1cdbd2cSJim Jagielski * software distributed under the License is distributed on an 15*b1cdbd2cSJim Jagielski * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16*b1cdbd2cSJim Jagielski * KIND, either express or implied. See the License for the 17*b1cdbd2cSJim Jagielski * specific language governing permissions and limitations 18*b1cdbd2cSJim Jagielski * under the License. 19*b1cdbd2cSJim Jagielski * 20*b1cdbd2cSJim Jagielski *************************************************************/ 21*b1cdbd2cSJim Jagielski 22*b1cdbd2cSJim Jagielski 23*b1cdbd2cSJim Jagielski 24*b1cdbd2cSJim Jagielski // MARKER(update_precomp.py): autogen include statement, do not remove 25*b1cdbd2cSJim Jagielski #include "precompiled_cppcanvas.hxx" 26*b1cdbd2cSJim Jagielski 27*b1cdbd2cSJim Jagielski #include <rtl/logfile.hxx> 28*b1cdbd2cSJim Jagielski 29*b1cdbd2cSJim Jagielski #include <com/sun/star/rendering/XCanvas.hpp> 30*b1cdbd2cSJim Jagielski #include <com/sun/star/rendering/TexturingMode.hpp> 31*b1cdbd2cSJim Jagielski 32*b1cdbd2cSJim Jagielski #include <tools/gen.hxx> 33*b1cdbd2cSJim Jagielski #include <vcl/canvastools.hxx> 34*b1cdbd2cSJim Jagielski 35*b1cdbd2cSJim Jagielski #include <basegfx/range/b2drectangle.hxx> 36*b1cdbd2cSJim Jagielski #include <basegfx/tools/canvastools.hxx> 37*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolypolygon.hxx> 38*b1cdbd2cSJim Jagielski #include <basegfx/polygon/b2dpolypolygontools.hxx> 39*b1cdbd2cSJim Jagielski #include <basegfx/matrix/b2dhommatrix.hxx> 40*b1cdbd2cSJim Jagielski #include <canvas/canvastools.hxx> 41*b1cdbd2cSJim Jagielski 42*b1cdbd2cSJim Jagielski #include <boost/utility.hpp> 43*b1cdbd2cSJim Jagielski 44*b1cdbd2cSJim Jagielski #include "cachedprimitivebase.hxx" 45*b1cdbd2cSJim Jagielski #include "polypolyaction.hxx" 46*b1cdbd2cSJim Jagielski #include "outdevstate.hxx" 47*b1cdbd2cSJim Jagielski #include "mtftools.hxx" 48*b1cdbd2cSJim Jagielski 49*b1cdbd2cSJim Jagielski 50*b1cdbd2cSJim Jagielski using namespace ::com::sun::star; 51*b1cdbd2cSJim Jagielski 52*b1cdbd2cSJim Jagielski namespace cppcanvas 53*b1cdbd2cSJim Jagielski { 54*b1cdbd2cSJim Jagielski namespace internal 55*b1cdbd2cSJim Jagielski { 56*b1cdbd2cSJim Jagielski namespace 57*b1cdbd2cSJim Jagielski { 58*b1cdbd2cSJim Jagielski class PolyPolyAction : public CachedPrimitiveBase 59*b1cdbd2cSJim Jagielski { 60*b1cdbd2cSJim Jagielski public: 61*b1cdbd2cSJim Jagielski PolyPolyAction( const ::basegfx::B2DPolyPolygon&, 62*b1cdbd2cSJim Jagielski const CanvasSharedPtr&, 63*b1cdbd2cSJim Jagielski const OutDevState&, 64*b1cdbd2cSJim Jagielski bool bFill, 65*b1cdbd2cSJim Jagielski bool bStroke ); 66*b1cdbd2cSJim Jagielski PolyPolyAction( const ::basegfx::B2DPolyPolygon&, 67*b1cdbd2cSJim Jagielski const CanvasSharedPtr&, 68*b1cdbd2cSJim Jagielski const OutDevState&, 69*b1cdbd2cSJim Jagielski bool bFill, 70*b1cdbd2cSJim Jagielski bool bStroke, 71*b1cdbd2cSJim Jagielski int nTransparency ); 72*b1cdbd2cSJim Jagielski 73*b1cdbd2cSJim Jagielski virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation, 74*b1cdbd2cSJim Jagielski const Subset& rSubset ) const; 75*b1cdbd2cSJim Jagielski 76*b1cdbd2cSJim Jagielski virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const; 77*b1cdbd2cSJim Jagielski virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation, 78*b1cdbd2cSJim Jagielski const Subset& rSubset ) const; 79*b1cdbd2cSJim Jagielski 80*b1cdbd2cSJim Jagielski virtual sal_Int32 getActionCount() const; 81*b1cdbd2cSJim Jagielski 82*b1cdbd2cSJim Jagielski private: 83*b1cdbd2cSJim Jagielski using Action::render; 84*b1cdbd2cSJim Jagielski virtual bool render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive, 85*b1cdbd2cSJim Jagielski const ::basegfx::B2DHomMatrix& rTransformation ) const; 86*b1cdbd2cSJim Jagielski 87*b1cdbd2cSJim Jagielski const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly; 88*b1cdbd2cSJim Jagielski const ::basegfx::B2DRange maBounds; 89*b1cdbd2cSJim Jagielski const CanvasSharedPtr mpCanvas; 90*b1cdbd2cSJim Jagielski 91*b1cdbd2cSJim Jagielski // stroke color is now implicit: the maState.DeviceColor member 92*b1cdbd2cSJim Jagielski rendering::RenderState maState; 93*b1cdbd2cSJim Jagielski 94*b1cdbd2cSJim Jagielski uno::Sequence< double > maFillColor; 95*b1cdbd2cSJim Jagielski }; 96*b1cdbd2cSJim Jagielski PolyPolyAction(const::basegfx::B2DPolyPolygon & rPolyPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,bool bFill,bool bStroke)97*b1cdbd2cSJim Jagielski PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly, 98*b1cdbd2cSJim Jagielski const CanvasSharedPtr& rCanvas, 99*b1cdbd2cSJim Jagielski const OutDevState& rState, 100*b1cdbd2cSJim Jagielski bool bFill, 101*b1cdbd2cSJim Jagielski bool bStroke ) : 102*b1cdbd2cSJim Jagielski CachedPrimitiveBase( rCanvas, false ), 103*b1cdbd2cSJim Jagielski mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ), 104*b1cdbd2cSJim Jagielski maBounds( ::basegfx::tools::getRange(rPolyPoly) ), 105*b1cdbd2cSJim Jagielski mpCanvas( rCanvas ), 106*b1cdbd2cSJim Jagielski maState(), 107*b1cdbd2cSJim Jagielski maFillColor() 108*b1cdbd2cSJim Jagielski { 109*b1cdbd2cSJim Jagielski tools::initRenderState(maState,rState); 110*b1cdbd2cSJim Jagielski 111*b1cdbd2cSJim Jagielski if( bFill ) 112*b1cdbd2cSJim Jagielski maFillColor = rState.fillColor; 113*b1cdbd2cSJim Jagielski 114*b1cdbd2cSJim Jagielski if( bStroke ) 115*b1cdbd2cSJim Jagielski maState.DeviceColor = rState.lineColor; 116*b1cdbd2cSJim Jagielski } 117*b1cdbd2cSJim Jagielski PolyPolyAction(const::basegfx::B2DPolyPolygon & rPolyPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,bool bFill,bool bStroke,int nTransparency)118*b1cdbd2cSJim Jagielski PolyPolyAction::PolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly, 119*b1cdbd2cSJim Jagielski const CanvasSharedPtr& rCanvas, 120*b1cdbd2cSJim Jagielski const OutDevState& rState, 121*b1cdbd2cSJim Jagielski bool bFill, 122*b1cdbd2cSJim Jagielski bool bStroke, 123*b1cdbd2cSJim Jagielski int nTransparency ) : 124*b1cdbd2cSJim Jagielski CachedPrimitiveBase( rCanvas, false ), 125*b1cdbd2cSJim Jagielski mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ), 126*b1cdbd2cSJim Jagielski maBounds( ::basegfx::tools::getRange(rPolyPoly) ), 127*b1cdbd2cSJim Jagielski mpCanvas( rCanvas ), 128*b1cdbd2cSJim Jagielski maState(), 129*b1cdbd2cSJim Jagielski maFillColor() 130*b1cdbd2cSJim Jagielski { 131*b1cdbd2cSJim Jagielski tools::initRenderState(maState,rState); 132*b1cdbd2cSJim Jagielski 133*b1cdbd2cSJim Jagielski if( bFill ) 134*b1cdbd2cSJim Jagielski { 135*b1cdbd2cSJim Jagielski maFillColor = rState.fillColor; 136*b1cdbd2cSJim Jagielski 137*b1cdbd2cSJim Jagielski if( maFillColor.getLength() < 4 ) 138*b1cdbd2cSJim Jagielski maFillColor.realloc( 4 ); 139*b1cdbd2cSJim Jagielski 140*b1cdbd2cSJim Jagielski // TODO(F1): Color management 141*b1cdbd2cSJim Jagielski // adapt fill color transparency 142*b1cdbd2cSJim Jagielski maFillColor[3] = 1.0 - nTransparency / 100.0; 143*b1cdbd2cSJim Jagielski } 144*b1cdbd2cSJim Jagielski 145*b1cdbd2cSJim Jagielski if( bStroke ) 146*b1cdbd2cSJim Jagielski { 147*b1cdbd2cSJim Jagielski maState.DeviceColor = rState.lineColor; 148*b1cdbd2cSJim Jagielski 149*b1cdbd2cSJim Jagielski if( maState.DeviceColor.getLength() < 4 ) 150*b1cdbd2cSJim Jagielski maState.DeviceColor.realloc( 4 ); 151*b1cdbd2cSJim Jagielski 152*b1cdbd2cSJim Jagielski // TODO(F1): Color management 153*b1cdbd2cSJim Jagielski // adapt fill color transparency 154*b1cdbd2cSJim Jagielski maState.DeviceColor[3] = 1.0 - nTransparency / 100.0; 155*b1cdbd2cSJim Jagielski } 156*b1cdbd2cSJim Jagielski } 157*b1cdbd2cSJim Jagielski render(uno::Reference<rendering::XCachedPrimitive> & rCachedPrimitive,const::basegfx::B2DHomMatrix & rTransformation) const158*b1cdbd2cSJim Jagielski bool PolyPolyAction::render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive, 159*b1cdbd2cSJim Jagielski const ::basegfx::B2DHomMatrix& rTransformation ) const 160*b1cdbd2cSJim Jagielski { 161*b1cdbd2cSJim Jagielski RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::PolyPolyAction::render()" ); 162*b1cdbd2cSJim Jagielski RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::PolyPolyAction: 0x%X", this ); 163*b1cdbd2cSJim Jagielski 164*b1cdbd2cSJim Jagielski rendering::RenderState aLocalState( maState ); 165*b1cdbd2cSJim Jagielski ::canvas::tools::prependToRenderState(aLocalState, rTransformation); 166*b1cdbd2cSJim Jagielski 167*b1cdbd2cSJim Jagielski #ifdef SPECIAL_DEBUG 168*b1cdbd2cSJim Jagielski aLocalState.Clip.clear(); 169*b1cdbd2cSJim Jagielski aLocalState.DeviceColor = 170*b1cdbd2cSJim Jagielski ::vcl::unotools::colorToDoubleSequence( mpCanvas->getUNOCanvas()->getDevice(), 171*b1cdbd2cSJim Jagielski ::Color( 0x80FF0000 ) ); 172*b1cdbd2cSJim Jagielski 173*b1cdbd2cSJim Jagielski if( maState.Clip.is() ) 174*b1cdbd2cSJim Jagielski mpCanvas->getUNOCanvas()->fillPolyPolygon( maState.Clip, 175*b1cdbd2cSJim Jagielski mpCanvas->getViewState(), 176*b1cdbd2cSJim Jagielski aLocalState ); 177*b1cdbd2cSJim Jagielski 178*b1cdbd2cSJim Jagielski aLocalState.DeviceColor = maState.DeviceColor; 179*b1cdbd2cSJim Jagielski #endif 180*b1cdbd2cSJim Jagielski 181*b1cdbd2cSJim Jagielski if( maFillColor.getLength() ) 182*b1cdbd2cSJim Jagielski { 183*b1cdbd2cSJim Jagielski // TODO(E3): Use DBO's finalizer here, 184*b1cdbd2cSJim Jagielski // fillPolyPolygon() might throw 185*b1cdbd2cSJim Jagielski const uno::Sequence< double > aTmpColor( aLocalState.DeviceColor ); 186*b1cdbd2cSJim Jagielski aLocalState.DeviceColor = maFillColor; 187*b1cdbd2cSJim Jagielski 188*b1cdbd2cSJim Jagielski rCachedPrimitive = mpCanvas->getUNOCanvas()->fillPolyPolygon( mxPolyPoly, 189*b1cdbd2cSJim Jagielski mpCanvas->getViewState(), 190*b1cdbd2cSJim Jagielski aLocalState ); 191*b1cdbd2cSJim Jagielski 192*b1cdbd2cSJim Jagielski aLocalState.DeviceColor = aTmpColor; 193*b1cdbd2cSJim Jagielski } 194*b1cdbd2cSJim Jagielski 195*b1cdbd2cSJim Jagielski if( aLocalState.DeviceColor.getLength() ) 196*b1cdbd2cSJim Jagielski { 197*b1cdbd2cSJim Jagielski rCachedPrimitive = mpCanvas->getUNOCanvas()->drawPolyPolygon( mxPolyPoly, 198*b1cdbd2cSJim Jagielski mpCanvas->getViewState(), 199*b1cdbd2cSJim Jagielski aLocalState ); 200*b1cdbd2cSJim Jagielski } 201*b1cdbd2cSJim Jagielski 202*b1cdbd2cSJim Jagielski return true; 203*b1cdbd2cSJim Jagielski } 204*b1cdbd2cSJim Jagielski render(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const205*b1cdbd2cSJim Jagielski bool PolyPolyAction::render( const ::basegfx::B2DHomMatrix& rTransformation, 206*b1cdbd2cSJim Jagielski const Subset& rSubset ) const 207*b1cdbd2cSJim Jagielski { 208*b1cdbd2cSJim Jagielski // TODO(F1): Split up poly-polygon into polygons, or even 209*b1cdbd2cSJim Jagielski // line segments, when subsets are requested. 210*b1cdbd2cSJim Jagielski 211*b1cdbd2cSJim Jagielski // polygon only contains a single action, fail if subset 212*b1cdbd2cSJim Jagielski // requests different range 213*b1cdbd2cSJim Jagielski if( rSubset.mnSubsetBegin != 0 || 214*b1cdbd2cSJim Jagielski rSubset.mnSubsetEnd != 1 ) 215*b1cdbd2cSJim Jagielski return false; 216*b1cdbd2cSJim Jagielski 217*b1cdbd2cSJim Jagielski return CachedPrimitiveBase::render( rTransformation ); 218*b1cdbd2cSJim Jagielski } 219*b1cdbd2cSJim Jagielski getBounds(const::basegfx::B2DHomMatrix & rTransformation) const220*b1cdbd2cSJim Jagielski ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const 221*b1cdbd2cSJim Jagielski { 222*b1cdbd2cSJim Jagielski rendering::RenderState aLocalState( maState ); 223*b1cdbd2cSJim Jagielski ::canvas::tools::prependToRenderState(aLocalState, rTransformation); 224*b1cdbd2cSJim Jagielski 225*b1cdbd2cSJim Jagielski return tools::calcDevicePixelBounds( 226*b1cdbd2cSJim Jagielski maBounds, 227*b1cdbd2cSJim Jagielski mpCanvas->getViewState(), 228*b1cdbd2cSJim Jagielski aLocalState ); 229*b1cdbd2cSJim Jagielski } 230*b1cdbd2cSJim Jagielski getBounds(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const231*b1cdbd2cSJim Jagielski ::basegfx::B2DRange PolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation, 232*b1cdbd2cSJim Jagielski const Subset& rSubset ) const 233*b1cdbd2cSJim Jagielski { 234*b1cdbd2cSJim Jagielski // TODO(F1): Split up poly-polygon into polygons, or even 235*b1cdbd2cSJim Jagielski // line segments, when subsets are requested. 236*b1cdbd2cSJim Jagielski 237*b1cdbd2cSJim Jagielski // polygon only contains a single action, empty bounds 238*b1cdbd2cSJim Jagielski // if subset requests different range 239*b1cdbd2cSJim Jagielski if( rSubset.mnSubsetBegin != 0 || 240*b1cdbd2cSJim Jagielski rSubset.mnSubsetEnd != 1 ) 241*b1cdbd2cSJim Jagielski return ::basegfx::B2DRange(); 242*b1cdbd2cSJim Jagielski 243*b1cdbd2cSJim Jagielski return getBounds( rTransformation ); 244*b1cdbd2cSJim Jagielski } 245*b1cdbd2cSJim Jagielski getActionCount() const246*b1cdbd2cSJim Jagielski sal_Int32 PolyPolyAction::getActionCount() const 247*b1cdbd2cSJim Jagielski { 248*b1cdbd2cSJim Jagielski // TODO(F1): Split up poly-polygon into polygons, or even 249*b1cdbd2cSJim Jagielski // line segments, when subsets are requested. 250*b1cdbd2cSJim Jagielski return 1; 251*b1cdbd2cSJim Jagielski } 252*b1cdbd2cSJim Jagielski 253*b1cdbd2cSJim Jagielski 254*b1cdbd2cSJim Jagielski // ------------------------------------------------------------------------------- 255*b1cdbd2cSJim Jagielski 256*b1cdbd2cSJim Jagielski class TexturedPolyPolyAction : public CachedPrimitiveBase 257*b1cdbd2cSJim Jagielski { 258*b1cdbd2cSJim Jagielski public: 259*b1cdbd2cSJim Jagielski TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly, 260*b1cdbd2cSJim Jagielski const CanvasSharedPtr& rCanvas, 261*b1cdbd2cSJim Jagielski const OutDevState& rState, 262*b1cdbd2cSJim Jagielski const rendering::Texture& rTexture ); 263*b1cdbd2cSJim Jagielski 264*b1cdbd2cSJim Jagielski virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation, 265*b1cdbd2cSJim Jagielski const Subset& rSubset ) const; 266*b1cdbd2cSJim Jagielski 267*b1cdbd2cSJim Jagielski virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const; 268*b1cdbd2cSJim Jagielski virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation, 269*b1cdbd2cSJim Jagielski const Subset& rSubset ) const; 270*b1cdbd2cSJim Jagielski 271*b1cdbd2cSJim Jagielski virtual sal_Int32 getActionCount() const; 272*b1cdbd2cSJim Jagielski 273*b1cdbd2cSJim Jagielski private: 274*b1cdbd2cSJim Jagielski using Action::render; 275*b1cdbd2cSJim Jagielski virtual bool render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive, 276*b1cdbd2cSJim Jagielski const ::basegfx::B2DHomMatrix& rTransformation ) const; 277*b1cdbd2cSJim Jagielski 278*b1cdbd2cSJim Jagielski const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly; 279*b1cdbd2cSJim Jagielski const ::basegfx::B2DRectangle maBounds; 280*b1cdbd2cSJim Jagielski const CanvasSharedPtr mpCanvas; 281*b1cdbd2cSJim Jagielski 282*b1cdbd2cSJim Jagielski // stroke color is now implicit: the maState.DeviceColor member 283*b1cdbd2cSJim Jagielski rendering::RenderState maState; 284*b1cdbd2cSJim Jagielski const rendering::Texture maTexture; 285*b1cdbd2cSJim Jagielski }; 286*b1cdbd2cSJim Jagielski TexturedPolyPolyAction(const::basegfx::B2DPolyPolygon & rPolyPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,const rendering::Texture & rTexture)287*b1cdbd2cSJim Jagielski TexturedPolyPolyAction::TexturedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly, 288*b1cdbd2cSJim Jagielski const CanvasSharedPtr& rCanvas, 289*b1cdbd2cSJim Jagielski const OutDevState& rState, 290*b1cdbd2cSJim Jagielski const rendering::Texture& rTexture ) : 291*b1cdbd2cSJim Jagielski CachedPrimitiveBase( rCanvas, true ), 292*b1cdbd2cSJim Jagielski mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ), 293*b1cdbd2cSJim Jagielski maBounds( ::basegfx::tools::getRange(rPolyPoly) ), 294*b1cdbd2cSJim Jagielski mpCanvas( rCanvas ), 295*b1cdbd2cSJim Jagielski maState(), 296*b1cdbd2cSJim Jagielski maTexture( rTexture ) 297*b1cdbd2cSJim Jagielski { 298*b1cdbd2cSJim Jagielski tools::initRenderState(maState,rState); 299*b1cdbd2cSJim Jagielski } 300*b1cdbd2cSJim Jagielski render(uno::Reference<rendering::XCachedPrimitive> & rCachedPrimitive,const::basegfx::B2DHomMatrix & rTransformation) const301*b1cdbd2cSJim Jagielski bool TexturedPolyPolyAction::render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive, 302*b1cdbd2cSJim Jagielski const ::basegfx::B2DHomMatrix& rTransformation ) const 303*b1cdbd2cSJim Jagielski { 304*b1cdbd2cSJim Jagielski RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::PolyPolyAction::render()" ); 305*b1cdbd2cSJim Jagielski RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::PolyPolyAction: 0x%X", this ); 306*b1cdbd2cSJim Jagielski 307*b1cdbd2cSJim Jagielski rendering::RenderState aLocalState( maState ); 308*b1cdbd2cSJim Jagielski ::canvas::tools::prependToRenderState(aLocalState, rTransformation); 309*b1cdbd2cSJim Jagielski 310*b1cdbd2cSJim Jagielski uno::Sequence< rendering::Texture > aSeq(1); 311*b1cdbd2cSJim Jagielski aSeq[0] = maTexture; 312*b1cdbd2cSJim Jagielski 313*b1cdbd2cSJim Jagielski rCachedPrimitive = mpCanvas->getUNOCanvas()->fillTexturedPolyPolygon( mxPolyPoly, 314*b1cdbd2cSJim Jagielski mpCanvas->getViewState(), 315*b1cdbd2cSJim Jagielski aLocalState, 316*b1cdbd2cSJim Jagielski aSeq ); 317*b1cdbd2cSJim Jagielski return true; 318*b1cdbd2cSJim Jagielski } 319*b1cdbd2cSJim Jagielski render(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const320*b1cdbd2cSJim Jagielski bool TexturedPolyPolyAction::render( const ::basegfx::B2DHomMatrix& rTransformation, 321*b1cdbd2cSJim Jagielski const Subset& rSubset ) const 322*b1cdbd2cSJim Jagielski { 323*b1cdbd2cSJim Jagielski // TODO(F1): Split up poly-polygon into polygons, or even 324*b1cdbd2cSJim Jagielski // line segments, when subsets are requested. 325*b1cdbd2cSJim Jagielski 326*b1cdbd2cSJim Jagielski // polygon only contains a single action, fail if subset 327*b1cdbd2cSJim Jagielski // requests different range 328*b1cdbd2cSJim Jagielski if( rSubset.mnSubsetBegin != 0 || 329*b1cdbd2cSJim Jagielski rSubset.mnSubsetEnd != 1 ) 330*b1cdbd2cSJim Jagielski return false; 331*b1cdbd2cSJim Jagielski 332*b1cdbd2cSJim Jagielski return CachedPrimitiveBase::render( rTransformation ); 333*b1cdbd2cSJim Jagielski } 334*b1cdbd2cSJim Jagielski getBounds(const::basegfx::B2DHomMatrix & rTransformation) const335*b1cdbd2cSJim Jagielski ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const 336*b1cdbd2cSJim Jagielski { 337*b1cdbd2cSJim Jagielski rendering::RenderState aLocalState( maState ); 338*b1cdbd2cSJim Jagielski ::canvas::tools::prependToRenderState(aLocalState, rTransformation); 339*b1cdbd2cSJim Jagielski 340*b1cdbd2cSJim Jagielski return tools::calcDevicePixelBounds( 341*b1cdbd2cSJim Jagielski maBounds, 342*b1cdbd2cSJim Jagielski mpCanvas->getViewState(), 343*b1cdbd2cSJim Jagielski aLocalState ); 344*b1cdbd2cSJim Jagielski } 345*b1cdbd2cSJim Jagielski getBounds(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const346*b1cdbd2cSJim Jagielski ::basegfx::B2DRange TexturedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation, 347*b1cdbd2cSJim Jagielski const Subset& rSubset ) const 348*b1cdbd2cSJim Jagielski { 349*b1cdbd2cSJim Jagielski // TODO(F1): Split up poly-polygon into polygons, or even 350*b1cdbd2cSJim Jagielski // line segments, when subsets are requested. 351*b1cdbd2cSJim Jagielski 352*b1cdbd2cSJim Jagielski // polygon only contains a single action, empty bounds 353*b1cdbd2cSJim Jagielski // if subset requests different range 354*b1cdbd2cSJim Jagielski if( rSubset.mnSubsetBegin != 0 || 355*b1cdbd2cSJim Jagielski rSubset.mnSubsetEnd != 1 ) 356*b1cdbd2cSJim Jagielski return ::basegfx::B2DRange(); 357*b1cdbd2cSJim Jagielski 358*b1cdbd2cSJim Jagielski return getBounds( rTransformation ); 359*b1cdbd2cSJim Jagielski } 360*b1cdbd2cSJim Jagielski getActionCount() const361*b1cdbd2cSJim Jagielski sal_Int32 TexturedPolyPolyAction::getActionCount() const 362*b1cdbd2cSJim Jagielski { 363*b1cdbd2cSJim Jagielski // TODO(F1): Split up poly-polygon into polygons, or even 364*b1cdbd2cSJim Jagielski // line segments, when subsets are requested. 365*b1cdbd2cSJim Jagielski return 1; 366*b1cdbd2cSJim Jagielski } 367*b1cdbd2cSJim Jagielski 368*b1cdbd2cSJim Jagielski // ------------------------------------------------------------------------------- 369*b1cdbd2cSJim Jagielski 370*b1cdbd2cSJim Jagielski class StrokedPolyPolyAction : public CachedPrimitiveBase 371*b1cdbd2cSJim Jagielski { 372*b1cdbd2cSJim Jagielski public: 373*b1cdbd2cSJim Jagielski StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly, 374*b1cdbd2cSJim Jagielski const CanvasSharedPtr& rCanvas, 375*b1cdbd2cSJim Jagielski const OutDevState& rState, 376*b1cdbd2cSJim Jagielski const rendering::StrokeAttributes& rStrokeAttributes ); 377*b1cdbd2cSJim Jagielski 378*b1cdbd2cSJim Jagielski virtual bool render( const ::basegfx::B2DHomMatrix& rTransformation, 379*b1cdbd2cSJim Jagielski const Subset& rSubset ) const; 380*b1cdbd2cSJim Jagielski 381*b1cdbd2cSJim Jagielski virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const; 382*b1cdbd2cSJim Jagielski virtual ::basegfx::B2DRange getBounds( const ::basegfx::B2DHomMatrix& rTransformation, 383*b1cdbd2cSJim Jagielski const Subset& rSubset ) const; 384*b1cdbd2cSJim Jagielski 385*b1cdbd2cSJim Jagielski virtual sal_Int32 getActionCount() const; 386*b1cdbd2cSJim Jagielski 387*b1cdbd2cSJim Jagielski private: 388*b1cdbd2cSJim Jagielski using Action::render; 389*b1cdbd2cSJim Jagielski virtual bool render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive, 390*b1cdbd2cSJim Jagielski const ::basegfx::B2DHomMatrix& rTransformation ) const; 391*b1cdbd2cSJim Jagielski 392*b1cdbd2cSJim Jagielski const uno::Reference< rendering::XPolyPolygon2D > mxPolyPoly; 393*b1cdbd2cSJim Jagielski const ::basegfx::B2DRectangle maBounds; 394*b1cdbd2cSJim Jagielski const CanvasSharedPtr mpCanvas; 395*b1cdbd2cSJim Jagielski rendering::RenderState maState; 396*b1cdbd2cSJim Jagielski const rendering::StrokeAttributes maStrokeAttributes; 397*b1cdbd2cSJim Jagielski }; 398*b1cdbd2cSJim Jagielski StrokedPolyPolyAction(const::basegfx::B2DPolyPolygon & rPolyPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,const rendering::StrokeAttributes & rStrokeAttributes)399*b1cdbd2cSJim Jagielski StrokedPolyPolyAction::StrokedPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPolyPoly, 400*b1cdbd2cSJim Jagielski const CanvasSharedPtr& rCanvas, 401*b1cdbd2cSJim Jagielski const OutDevState& rState, 402*b1cdbd2cSJim Jagielski const rendering::StrokeAttributes& rStrokeAttributes ) : 403*b1cdbd2cSJim Jagielski CachedPrimitiveBase( rCanvas, false ), 404*b1cdbd2cSJim Jagielski mxPolyPoly( ::basegfx::unotools::xPolyPolygonFromB2DPolyPolygon( rCanvas->getUNOCanvas()->getDevice(), rPolyPoly) ), 405*b1cdbd2cSJim Jagielski maBounds( ::basegfx::tools::getRange(rPolyPoly) ), 406*b1cdbd2cSJim Jagielski mpCanvas( rCanvas ), 407*b1cdbd2cSJim Jagielski maState(), 408*b1cdbd2cSJim Jagielski maStrokeAttributes( rStrokeAttributes ) 409*b1cdbd2cSJim Jagielski { 410*b1cdbd2cSJim Jagielski tools::initRenderState(maState,rState); 411*b1cdbd2cSJim Jagielski maState.DeviceColor = rState.lineColor; 412*b1cdbd2cSJim Jagielski } 413*b1cdbd2cSJim Jagielski render(uno::Reference<rendering::XCachedPrimitive> & rCachedPrimitive,const::basegfx::B2DHomMatrix & rTransformation) const414*b1cdbd2cSJim Jagielski bool StrokedPolyPolyAction::render( uno::Reference< rendering::XCachedPrimitive >& rCachedPrimitive, 415*b1cdbd2cSJim Jagielski const ::basegfx::B2DHomMatrix& rTransformation ) const 416*b1cdbd2cSJim Jagielski { 417*b1cdbd2cSJim Jagielski RTL_LOGFILE_CONTEXT( aLog, "::cppcanvas::internal::PolyPolyAction::render()" ); 418*b1cdbd2cSJim Jagielski RTL_LOGFILE_CONTEXT_TRACE1( aLog, "::cppcanvas::internal::PolyPolyAction: 0x%X", this ); 419*b1cdbd2cSJim Jagielski 420*b1cdbd2cSJim Jagielski rendering::RenderState aLocalState( maState ); 421*b1cdbd2cSJim Jagielski ::canvas::tools::prependToRenderState(aLocalState, rTransformation); 422*b1cdbd2cSJim Jagielski 423*b1cdbd2cSJim Jagielski rCachedPrimitive = mpCanvas->getUNOCanvas()->strokePolyPolygon( mxPolyPoly, 424*b1cdbd2cSJim Jagielski mpCanvas->getViewState(), 425*b1cdbd2cSJim Jagielski aLocalState, 426*b1cdbd2cSJim Jagielski maStrokeAttributes ); 427*b1cdbd2cSJim Jagielski return true; 428*b1cdbd2cSJim Jagielski } 429*b1cdbd2cSJim Jagielski render(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const430*b1cdbd2cSJim Jagielski bool StrokedPolyPolyAction::render( const ::basegfx::B2DHomMatrix& rTransformation, 431*b1cdbd2cSJim Jagielski const Subset& rSubset ) const 432*b1cdbd2cSJim Jagielski { 433*b1cdbd2cSJim Jagielski // TODO(F1): Split up poly-polygon into polygons, or even 434*b1cdbd2cSJim Jagielski // line segments, when subsets are requested. 435*b1cdbd2cSJim Jagielski 436*b1cdbd2cSJim Jagielski // polygon only contains a single action, fail if subset 437*b1cdbd2cSJim Jagielski // requests different range 438*b1cdbd2cSJim Jagielski if( rSubset.mnSubsetBegin != 0 || 439*b1cdbd2cSJim Jagielski rSubset.mnSubsetEnd != 1 ) 440*b1cdbd2cSJim Jagielski return false; 441*b1cdbd2cSJim Jagielski 442*b1cdbd2cSJim Jagielski return CachedPrimitiveBase::render( rTransformation ); 443*b1cdbd2cSJim Jagielski } 444*b1cdbd2cSJim Jagielski getBounds(const::basegfx::B2DHomMatrix & rTransformation) const445*b1cdbd2cSJim Jagielski ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation ) const 446*b1cdbd2cSJim Jagielski { 447*b1cdbd2cSJim Jagielski rendering::RenderState aLocalState( maState ); 448*b1cdbd2cSJim Jagielski ::canvas::tools::prependToRenderState(aLocalState, rTransformation); 449*b1cdbd2cSJim Jagielski 450*b1cdbd2cSJim Jagielski return tools::calcDevicePixelBounds( 451*b1cdbd2cSJim Jagielski maBounds, 452*b1cdbd2cSJim Jagielski mpCanvas->getViewState(), 453*b1cdbd2cSJim Jagielski aLocalState ); 454*b1cdbd2cSJim Jagielski } 455*b1cdbd2cSJim Jagielski getBounds(const::basegfx::B2DHomMatrix & rTransformation,const Subset & rSubset) const456*b1cdbd2cSJim Jagielski ::basegfx::B2DRange StrokedPolyPolyAction::getBounds( const ::basegfx::B2DHomMatrix& rTransformation, 457*b1cdbd2cSJim Jagielski const Subset& rSubset ) const 458*b1cdbd2cSJim Jagielski { 459*b1cdbd2cSJim Jagielski // TODO(F1): Split up poly-polygon into polygons, or even 460*b1cdbd2cSJim Jagielski // line segments, when subsets are requested. 461*b1cdbd2cSJim Jagielski 462*b1cdbd2cSJim Jagielski // polygon only contains a single action, empty bounds 463*b1cdbd2cSJim Jagielski // if subset requests different range 464*b1cdbd2cSJim Jagielski if( rSubset.mnSubsetBegin != 0 || 465*b1cdbd2cSJim Jagielski rSubset.mnSubsetEnd != 1 ) 466*b1cdbd2cSJim Jagielski return ::basegfx::B2DRange(); 467*b1cdbd2cSJim Jagielski 468*b1cdbd2cSJim Jagielski return getBounds( rTransformation ); 469*b1cdbd2cSJim Jagielski } 470*b1cdbd2cSJim Jagielski getActionCount() const471*b1cdbd2cSJim Jagielski sal_Int32 StrokedPolyPolyAction::getActionCount() const 472*b1cdbd2cSJim Jagielski { 473*b1cdbd2cSJim Jagielski // TODO(F1): Split up poly-polygon into polygons, or even 474*b1cdbd2cSJim Jagielski // line segments, when subsets are requested. 475*b1cdbd2cSJim Jagielski return 1; 476*b1cdbd2cSJim Jagielski } 477*b1cdbd2cSJim Jagielski } 478*b1cdbd2cSJim Jagielski createPolyPolyAction(const::basegfx::B2DPolyPolygon & rPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState)479*b1cdbd2cSJim Jagielski ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly, 480*b1cdbd2cSJim Jagielski const CanvasSharedPtr& rCanvas, 481*b1cdbd2cSJim Jagielski const OutDevState& rState ) 482*b1cdbd2cSJim Jagielski { 483*b1cdbd2cSJim Jagielski OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet, 484*b1cdbd2cSJim Jagielski "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" ); 485*b1cdbd2cSJim Jagielski return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState, 486*b1cdbd2cSJim Jagielski rState.isFillColorSet, 487*b1cdbd2cSJim Jagielski rState.isLineColorSet ) ); 488*b1cdbd2cSJim Jagielski } 489*b1cdbd2cSJim Jagielski createPolyPolyAction(const::basegfx::B2DPolyPolygon & rPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,const rendering::Texture & rTexture)490*b1cdbd2cSJim Jagielski ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly, 491*b1cdbd2cSJim Jagielski const CanvasSharedPtr& rCanvas, 492*b1cdbd2cSJim Jagielski const OutDevState& rState, 493*b1cdbd2cSJim Jagielski const rendering::Texture& rTexture ) 494*b1cdbd2cSJim Jagielski { 495*b1cdbd2cSJim Jagielski return ActionSharedPtr( new TexturedPolyPolyAction( rPoly, rCanvas, rState, rTexture ) ); 496*b1cdbd2cSJim Jagielski } 497*b1cdbd2cSJim Jagielski createLinePolyPolyAction(const::basegfx::B2DPolyPolygon & rPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState)498*b1cdbd2cSJim Jagielski ActionSharedPtr PolyPolyActionFactory::createLinePolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly, 499*b1cdbd2cSJim Jagielski const CanvasSharedPtr& rCanvas, 500*b1cdbd2cSJim Jagielski const OutDevState& rState ) 501*b1cdbd2cSJim Jagielski { 502*b1cdbd2cSJim Jagielski OSL_ENSURE( rState.isLineColorSet, 503*b1cdbd2cSJim Jagielski "PolyPolyActionFactory::createLinePolyPolyAction() called with empty line color" ); 504*b1cdbd2cSJim Jagielski 505*b1cdbd2cSJim Jagielski return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState, 506*b1cdbd2cSJim Jagielski false, 507*b1cdbd2cSJim Jagielski rState.isLineColorSet ) ); 508*b1cdbd2cSJim Jagielski } 509*b1cdbd2cSJim Jagielski createPolyPolyAction(const::basegfx::B2DPolyPolygon & rPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,const rendering::StrokeAttributes & rStrokeAttributes)510*b1cdbd2cSJim Jagielski ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly, 511*b1cdbd2cSJim Jagielski const CanvasSharedPtr& rCanvas, 512*b1cdbd2cSJim Jagielski const OutDevState& rState, 513*b1cdbd2cSJim Jagielski const rendering::StrokeAttributes& rStrokeAttributes ) 514*b1cdbd2cSJim Jagielski { 515*b1cdbd2cSJim Jagielski OSL_ENSURE( rState.isLineColorSet, 516*b1cdbd2cSJim Jagielski "PolyPolyActionFactory::createPolyPolyAction() for strokes called with empty line color" ); 517*b1cdbd2cSJim Jagielski return ActionSharedPtr( new StrokedPolyPolyAction( rPoly, rCanvas, rState, rStrokeAttributes ) ); 518*b1cdbd2cSJim Jagielski } 519*b1cdbd2cSJim Jagielski createPolyPolyAction(const::basegfx::B2DPolyPolygon & rPoly,const CanvasSharedPtr & rCanvas,const OutDevState & rState,int nTransparency)520*b1cdbd2cSJim Jagielski ActionSharedPtr PolyPolyActionFactory::createPolyPolyAction( const ::basegfx::B2DPolyPolygon& rPoly, 521*b1cdbd2cSJim Jagielski const CanvasSharedPtr& rCanvas, 522*b1cdbd2cSJim Jagielski const OutDevState& rState, 523*b1cdbd2cSJim Jagielski int nTransparency ) 524*b1cdbd2cSJim Jagielski { 525*b1cdbd2cSJim Jagielski OSL_ENSURE( rState.isLineColorSet || rState.isFillColorSet, 526*b1cdbd2cSJim Jagielski "PolyPolyActionFactory::createPolyPolyAction() with empty line and fill color" ); 527*b1cdbd2cSJim Jagielski return ActionSharedPtr( new PolyPolyAction( rPoly, rCanvas, rState, 528*b1cdbd2cSJim Jagielski rState.isFillColorSet, 529*b1cdbd2cSJim Jagielski rState.isLineColorSet, 530*b1cdbd2cSJim Jagielski nTransparency ) ); 531*b1cdbd2cSJim Jagielski } 532*b1cdbd2cSJim Jagielski 533*b1cdbd2cSJim Jagielski } 534*b1cdbd2cSJim Jagielski } 535