1*cdf0e10cSrcweir /************************************************************************* 2*cdf0e10cSrcweir * 3*cdf0e10cSrcweir * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4*cdf0e10cSrcweir * 5*cdf0e10cSrcweir * Copyright 2000, 2010 Oracle and/or its affiliates. 6*cdf0e10cSrcweir * 7*cdf0e10cSrcweir * OpenOffice.org - a multi-platform office productivity suite 8*cdf0e10cSrcweir * 9*cdf0e10cSrcweir * This file is part of OpenOffice.org. 10*cdf0e10cSrcweir * 11*cdf0e10cSrcweir * OpenOffice.org is free software: you can redistribute it and/or modify 12*cdf0e10cSrcweir * it under the terms of the GNU Lesser General Public License version 3 13*cdf0e10cSrcweir * only, as published by the Free Software Foundation. 14*cdf0e10cSrcweir * 15*cdf0e10cSrcweir * OpenOffice.org is distributed in the hope that it will be useful, 16*cdf0e10cSrcweir * but WITHOUT ANY WARRANTY; without even the implied warranty of 17*cdf0e10cSrcweir * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18*cdf0e10cSrcweir * GNU Lesser General Public License version 3 for more details 19*cdf0e10cSrcweir * (a copy is included in the LICENSE file that accompanied this code). 20*cdf0e10cSrcweir * 21*cdf0e10cSrcweir * You should have received a copy of the GNU Lesser General Public License 22*cdf0e10cSrcweir * version 3 along with OpenOffice.org. If not, see 23*cdf0e10cSrcweir * <http://www.openoffice.org/license.html> 24*cdf0e10cSrcweir * for a copy of the LGPLv3 License. 25*cdf0e10cSrcweir * 26*cdf0e10cSrcweir ************************************************************************/ 27*cdf0e10cSrcweir 28*cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove 29*cdf0e10cSrcweir #include "precompiled_sdext.hxx" 30*cdf0e10cSrcweir 31*cdf0e10cSrcweir #include "PresenterCanvasHelper.hxx" 32*cdf0e10cSrcweir 33*cdf0e10cSrcweir #include "PresenterController.hxx" 34*cdf0e10cSrcweir #include "PresenterGeometryHelper.hxx" 35*cdf0e10cSrcweir #include <com/sun/star/rendering/CompositeOperation.hpp> 36*cdf0e10cSrcweir #include <com/sun/star/rendering/TextDirection.hpp> 37*cdf0e10cSrcweir #include <com/sun/star/rendering/TexturingMode.hpp> 38*cdf0e10cSrcweir 39*cdf0e10cSrcweir using namespace ::com::sun::star; 40*cdf0e10cSrcweir using namespace ::com::sun::star::uno; 41*cdf0e10cSrcweir 42*cdf0e10cSrcweir namespace sdext { namespace presenter { 43*cdf0e10cSrcweir 44*cdf0e10cSrcweir PresenterCanvasHelper::PresenterCanvasHelper (void) 45*cdf0e10cSrcweir : maDefaultViewState( 46*cdf0e10cSrcweir geometry::AffineMatrix2D(1,0,0, 0,1,0), 47*cdf0e10cSrcweir NULL), 48*cdf0e10cSrcweir maDefaultRenderState( 49*cdf0e10cSrcweir geometry::AffineMatrix2D(1,0,0, 0,1,0), 50*cdf0e10cSrcweir NULL, 51*cdf0e10cSrcweir Sequence<double>(4), 52*cdf0e10cSrcweir rendering::CompositeOperation::SOURCE) 53*cdf0e10cSrcweir { 54*cdf0e10cSrcweir } 55*cdf0e10cSrcweir 56*cdf0e10cSrcweir 57*cdf0e10cSrcweir 58*cdf0e10cSrcweir 59*cdf0e10cSrcweir PresenterCanvasHelper::~PresenterCanvasHelper (void) 60*cdf0e10cSrcweir { 61*cdf0e10cSrcweir } 62*cdf0e10cSrcweir 63*cdf0e10cSrcweir 64*cdf0e10cSrcweir 65*cdf0e10cSrcweir 66*cdf0e10cSrcweir void PresenterCanvasHelper::Paint ( 67*cdf0e10cSrcweir const SharedBitmapDescriptor& rpBitmap, 68*cdf0e10cSrcweir const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, 69*cdf0e10cSrcweir const css::awt::Rectangle& rRepaintBox, 70*cdf0e10cSrcweir const css::awt::Rectangle& rOuterBoundingBox, 71*cdf0e10cSrcweir const css::awt::Rectangle& rContentBoundingBox) const 72*cdf0e10cSrcweir { 73*cdf0e10cSrcweir PaintRectangle(rpBitmap,rxCanvas,rRepaintBox,rOuterBoundingBox,rContentBoundingBox, 74*cdf0e10cSrcweir maDefaultViewState, maDefaultRenderState); 75*cdf0e10cSrcweir } 76*cdf0e10cSrcweir 77*cdf0e10cSrcweir 78*cdf0e10cSrcweir 79*cdf0e10cSrcweir 80*cdf0e10cSrcweir void PresenterCanvasHelper::PaintRectangle ( 81*cdf0e10cSrcweir const SharedBitmapDescriptor& rpBitmap, 82*cdf0e10cSrcweir const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, 83*cdf0e10cSrcweir const css::awt::Rectangle& rRepaintBox, 84*cdf0e10cSrcweir const css::awt::Rectangle& rOuterBoundingBox, 85*cdf0e10cSrcweir const css::awt::Rectangle& rContentBoundingBox, 86*cdf0e10cSrcweir const css::rendering::ViewState& rDefaultViewState, 87*cdf0e10cSrcweir const css::rendering::RenderState& rDefaultRenderState) 88*cdf0e10cSrcweir { 89*cdf0e10cSrcweir if (rpBitmap.get() == NULL) 90*cdf0e10cSrcweir return; 91*cdf0e10cSrcweir 92*cdf0e10cSrcweir if ( ! rxCanvas.is() || ! rxCanvas->getDevice().is()) 93*cdf0e10cSrcweir return; 94*cdf0e10cSrcweir 95*cdf0e10cSrcweir // Create a clip polypolygon that has the content box as hole. 96*cdf0e10cSrcweir ::std::vector<awt::Rectangle> aRectangles; 97*cdf0e10cSrcweir aRectangles.reserve(2); 98*cdf0e10cSrcweir aRectangles.push_back( 99*cdf0e10cSrcweir PresenterGeometryHelper::Intersection(rRepaintBox, rOuterBoundingBox)); 100*cdf0e10cSrcweir if (rContentBoundingBox.Width > 0 && rContentBoundingBox.Height > 0) 101*cdf0e10cSrcweir aRectangles.push_back( 102*cdf0e10cSrcweir PresenterGeometryHelper::Intersection(rRepaintBox, rContentBoundingBox)); 103*cdf0e10cSrcweir Reference<rendering::XPolyPolygon2D> xPolyPolygon ( 104*cdf0e10cSrcweir PresenterGeometryHelper::CreatePolygon( 105*cdf0e10cSrcweir aRectangles, 106*cdf0e10cSrcweir rxCanvas->getDevice())); 107*cdf0e10cSrcweir if ( ! xPolyPolygon.is()) 108*cdf0e10cSrcweir return; 109*cdf0e10cSrcweir xPolyPolygon->setFillRule(rendering::FillRule_EVEN_ODD); 110*cdf0e10cSrcweir 111*cdf0e10cSrcweir if (rpBitmap->GetNormalBitmap().is()) 112*cdf0e10cSrcweir { 113*cdf0e10cSrcweir if (rpBitmap->meHorizontalTexturingMode == PresenterBitmapDescriptor::Repeat 114*cdf0e10cSrcweir || rpBitmap->meVerticalTexturingMode == PresenterBitmapDescriptor::Repeat) 115*cdf0e10cSrcweir { 116*cdf0e10cSrcweir PaintTiledBitmap( 117*cdf0e10cSrcweir Reference<rendering::XBitmap>(rpBitmap->GetNormalBitmap(), UNO_QUERY), 118*cdf0e10cSrcweir rxCanvas, 119*cdf0e10cSrcweir rRepaintBox, 120*cdf0e10cSrcweir xPolyPolygon, 121*cdf0e10cSrcweir rContentBoundingBox, 122*cdf0e10cSrcweir rDefaultViewState, 123*cdf0e10cSrcweir rDefaultRenderState); 124*cdf0e10cSrcweir } 125*cdf0e10cSrcweir else 126*cdf0e10cSrcweir { 127*cdf0e10cSrcweir PaintBitmap( 128*cdf0e10cSrcweir Reference<rendering::XBitmap>(rpBitmap->GetNormalBitmap(), UNO_QUERY), 129*cdf0e10cSrcweir awt::Point(rOuterBoundingBox.X, rOuterBoundingBox.Y), 130*cdf0e10cSrcweir rxCanvas, 131*cdf0e10cSrcweir rRepaintBox, 132*cdf0e10cSrcweir xPolyPolygon, 133*cdf0e10cSrcweir rDefaultViewState, 134*cdf0e10cSrcweir rDefaultRenderState); 135*cdf0e10cSrcweir } 136*cdf0e10cSrcweir } 137*cdf0e10cSrcweir else 138*cdf0e10cSrcweir { 139*cdf0e10cSrcweir PaintColor( 140*cdf0e10cSrcweir rpBitmap->maReplacementColor, 141*cdf0e10cSrcweir rxCanvas, 142*cdf0e10cSrcweir rRepaintBox, 143*cdf0e10cSrcweir xPolyPolygon, 144*cdf0e10cSrcweir rDefaultViewState, 145*cdf0e10cSrcweir rDefaultRenderState); 146*cdf0e10cSrcweir } 147*cdf0e10cSrcweir } 148*cdf0e10cSrcweir 149*cdf0e10cSrcweir 150*cdf0e10cSrcweir 151*cdf0e10cSrcweir 152*cdf0e10cSrcweir void PresenterCanvasHelper::PaintTiledBitmap ( 153*cdf0e10cSrcweir const css::uno::Reference<css::rendering::XBitmap>& rxTexture, 154*cdf0e10cSrcweir const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, 155*cdf0e10cSrcweir const css::awt::Rectangle& rRepaintBox, 156*cdf0e10cSrcweir const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon, 157*cdf0e10cSrcweir const css::awt::Rectangle& rHole, 158*cdf0e10cSrcweir const css::rendering::ViewState& rDefaultViewState, 159*cdf0e10cSrcweir const css::rendering::RenderState& rDefaultRenderState) 160*cdf0e10cSrcweir { 161*cdf0e10cSrcweir if ( ! rxCanvas.is() || ! rxCanvas->getDevice().is()) 162*cdf0e10cSrcweir return; 163*cdf0e10cSrcweir 164*cdf0e10cSrcweir if ( ! rxTexture.is()) 165*cdf0e10cSrcweir return; 166*cdf0e10cSrcweir 167*cdf0e10cSrcweir if ( ! rxPolygon.is()) 168*cdf0e10cSrcweir return; 169*cdf0e10cSrcweir 170*cdf0e10cSrcweir rendering::ViewState aViewState (rDefaultViewState); 171*cdf0e10cSrcweir aViewState.Clip = rxPolygon; 172*cdf0e10cSrcweir 173*cdf0e10cSrcweir // Create a local render state at which the location of the bitmap is 174*cdf0e10cSrcweir // set. 175*cdf0e10cSrcweir rendering::RenderState aRenderState (rDefaultRenderState); 176*cdf0e10cSrcweir 177*cdf0e10cSrcweir 178*cdf0e10cSrcweir // Tile the bitmap over the repaint box. 179*cdf0e10cSrcweir const geometry::IntegerSize2D aBitmapSize (rxTexture->getSize()); 180*cdf0e10cSrcweir const sal_Int32 nLeft = (rRepaintBox.X / aBitmapSize.Width) * aBitmapSize.Width; 181*cdf0e10cSrcweir const sal_Int32 nTop = (rRepaintBox.Y / aBitmapSize.Height) * aBitmapSize.Height; 182*cdf0e10cSrcweir const sal_Int32 nRight = ((rRepaintBox.X + rRepaintBox.Width - 1 + aBitmapSize.Width - 1) 183*cdf0e10cSrcweir / aBitmapSize.Width) * aBitmapSize.Width; 184*cdf0e10cSrcweir const sal_Int32 nBottom = ((rRepaintBox.Y + rRepaintBox.Height - 1 + aBitmapSize.Height - 1) 185*cdf0e10cSrcweir / aBitmapSize.Height) * aBitmapSize.Height; 186*cdf0e10cSrcweir 187*cdf0e10cSrcweir for (sal_Int32 nY=nTop; nY<=nBottom; nY+=aBitmapSize.Height) 188*cdf0e10cSrcweir for (sal_Int32 nX=nLeft; nX<=nRight; nX+=aBitmapSize.Width) 189*cdf0e10cSrcweir { 190*cdf0e10cSrcweir if (PresenterGeometryHelper::IsInside( 191*cdf0e10cSrcweir awt::Rectangle(nX,nY,aBitmapSize.Width,aBitmapSize.Height), 192*cdf0e10cSrcweir rHole)) 193*cdf0e10cSrcweir { 194*cdf0e10cSrcweir continue; 195*cdf0e10cSrcweir } 196*cdf0e10cSrcweir aRenderState.AffineTransform.m02 = nX; 197*cdf0e10cSrcweir aRenderState.AffineTransform.m12 = nY; 198*cdf0e10cSrcweir rxCanvas->drawBitmap( 199*cdf0e10cSrcweir rxTexture, 200*cdf0e10cSrcweir aViewState, 201*cdf0e10cSrcweir aRenderState); 202*cdf0e10cSrcweir } 203*cdf0e10cSrcweir } 204*cdf0e10cSrcweir 205*cdf0e10cSrcweir 206*cdf0e10cSrcweir 207*cdf0e10cSrcweir 208*cdf0e10cSrcweir void PresenterCanvasHelper::PaintBitmap ( 209*cdf0e10cSrcweir const css::uno::Reference<css::rendering::XBitmap>& rxBitmap, 210*cdf0e10cSrcweir const awt::Point& rLocation, 211*cdf0e10cSrcweir const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, 212*cdf0e10cSrcweir const css::awt::Rectangle& rRepaintBox, 213*cdf0e10cSrcweir const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon, 214*cdf0e10cSrcweir const css::rendering::ViewState& rDefaultViewState, 215*cdf0e10cSrcweir const css::rendering::RenderState& rDefaultRenderState) 216*cdf0e10cSrcweir { 217*cdf0e10cSrcweir if ( ! rxCanvas.is() || ! rxCanvas->getDevice().is()) 218*cdf0e10cSrcweir return; 219*cdf0e10cSrcweir 220*cdf0e10cSrcweir if ( ! rxBitmap.is()) 221*cdf0e10cSrcweir return; 222*cdf0e10cSrcweir 223*cdf0e10cSrcweir if ( ! rxPolygon.is()) 224*cdf0e10cSrcweir return; 225*cdf0e10cSrcweir 226*cdf0e10cSrcweir // Set the repaint box as clip rectangle at the view state. 227*cdf0e10cSrcweir rendering::ViewState aViewState (rDefaultViewState); 228*cdf0e10cSrcweir aViewState.Clip = PresenterGeometryHelper::CreatePolygon(rRepaintBox, rxCanvas->getDevice()); 229*cdf0e10cSrcweir 230*cdf0e10cSrcweir 231*cdf0e10cSrcweir // Setup the rendering state so that the bitmap is painted top left in 232*cdf0e10cSrcweir // the polygon bounding box. 233*cdf0e10cSrcweir rendering::RenderState aRenderState (rDefaultRenderState); 234*cdf0e10cSrcweir aRenderState.AffineTransform = geometry::AffineMatrix2D(1,0, rLocation.X, 0,1,rLocation.Y); 235*cdf0e10cSrcweir aRenderState.Clip = rxPolygon; 236*cdf0e10cSrcweir 237*cdf0e10cSrcweir rxCanvas->drawBitmap( 238*cdf0e10cSrcweir rxBitmap, 239*cdf0e10cSrcweir aViewState, 240*cdf0e10cSrcweir aRenderState); 241*cdf0e10cSrcweir } 242*cdf0e10cSrcweir 243*cdf0e10cSrcweir 244*cdf0e10cSrcweir 245*cdf0e10cSrcweir 246*cdf0e10cSrcweir void PresenterCanvasHelper::PaintColor ( 247*cdf0e10cSrcweir const css::util::Color nColor, 248*cdf0e10cSrcweir const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, 249*cdf0e10cSrcweir const css::awt::Rectangle& rRepaintBox, 250*cdf0e10cSrcweir const css::uno::Reference<css::rendering::XPolyPolygon2D>& rxPolygon, 251*cdf0e10cSrcweir const css::rendering::ViewState& rDefaultViewState, 252*cdf0e10cSrcweir const css::rendering::RenderState& rDefaultRenderState) 253*cdf0e10cSrcweir { 254*cdf0e10cSrcweir if ( ! rxCanvas.is() || ! rxCanvas->getDevice().is()) 255*cdf0e10cSrcweir return; 256*cdf0e10cSrcweir 257*cdf0e10cSrcweir if ( ! rxPolygon.is()) 258*cdf0e10cSrcweir return; 259*cdf0e10cSrcweir 260*cdf0e10cSrcweir // Set the repaint box as clip rectangle at the view state. 261*cdf0e10cSrcweir rendering::ViewState aViewState (rDefaultViewState); 262*cdf0e10cSrcweir aViewState.Clip = PresenterGeometryHelper::CreatePolygon(rRepaintBox, rxCanvas->getDevice()); 263*cdf0e10cSrcweir 264*cdf0e10cSrcweir 265*cdf0e10cSrcweir // Setup the rendering state to use the given color. 266*cdf0e10cSrcweir rendering::RenderState aRenderState (rDefaultRenderState); 267*cdf0e10cSrcweir SetDeviceColor(aRenderState, nColor); 268*cdf0e10cSrcweir 269*cdf0e10cSrcweir rxCanvas->fillPolyPolygon( 270*cdf0e10cSrcweir rxPolygon, 271*cdf0e10cSrcweir aViewState, 272*cdf0e10cSrcweir aRenderState); 273*cdf0e10cSrcweir } 274*cdf0e10cSrcweir 275*cdf0e10cSrcweir 276*cdf0e10cSrcweir 277*cdf0e10cSrcweir 278*cdf0e10cSrcweir void PresenterCanvasHelper::SetDeviceColor( 279*cdf0e10cSrcweir rendering::RenderState& rRenderState, 280*cdf0e10cSrcweir const util::Color aColor) 281*cdf0e10cSrcweir { 282*cdf0e10cSrcweir // Other component counts then 4 (RGBA) are not accepted (anymore). 283*cdf0e10cSrcweir 284*cdf0e10cSrcweir OSL_ASSERT(rRenderState.DeviceColor.getLength() == 4); 285*cdf0e10cSrcweir if (rRenderState.DeviceColor.getLength() == 4) 286*cdf0e10cSrcweir { 287*cdf0e10cSrcweir rRenderState.DeviceColor[0] = ((aColor >> 16) & 0x0ff) / 255.0; 288*cdf0e10cSrcweir rRenderState.DeviceColor[1] = ((aColor >> 8) & 0x0ff) / 255.0; 289*cdf0e10cSrcweir rRenderState.DeviceColor[2] = ((aColor >> 0) & 0x0ff) / 255.0; 290*cdf0e10cSrcweir rRenderState.DeviceColor[3] = 1.0 - ((aColor >> 24) & 0x0ff) / 255.0; 291*cdf0e10cSrcweir } 292*cdf0e10cSrcweir } 293*cdf0e10cSrcweir 294*cdf0e10cSrcweir 295*cdf0e10cSrcweir 296*cdf0e10cSrcweir 297*cdf0e10cSrcweir css::geometry::RealRectangle2D PresenterCanvasHelper::GetTextBoundingBox ( 298*cdf0e10cSrcweir const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, 299*cdf0e10cSrcweir const ::rtl::OUString& rsText, 300*cdf0e10cSrcweir const sal_Int8 nTextDirection) 301*cdf0e10cSrcweir { 302*cdf0e10cSrcweir if (rxFont.is() && rsText.getLength() > 0) 303*cdf0e10cSrcweir { 304*cdf0e10cSrcweir rendering::StringContext aContext (rsText, 0, rsText.getLength()); 305*cdf0e10cSrcweir Reference<rendering::XTextLayout> xLayout ( 306*cdf0e10cSrcweir rxFont->createTextLayout(aContext, nTextDirection, 0)); 307*cdf0e10cSrcweir return xLayout->queryTextBounds(); 308*cdf0e10cSrcweir } 309*cdf0e10cSrcweir else 310*cdf0e10cSrcweir { 311*cdf0e10cSrcweir return geometry::RealRectangle2D(0,0,0,0); 312*cdf0e10cSrcweir } 313*cdf0e10cSrcweir } 314*cdf0e10cSrcweir 315*cdf0e10cSrcweir 316*cdf0e10cSrcweir 317*cdf0e10cSrcweir 318*cdf0e10cSrcweir css::geometry::RealSize2D PresenterCanvasHelper::GetTextSize ( 319*cdf0e10cSrcweir const css::uno::Reference<css::rendering::XCanvasFont>& rxFont, 320*cdf0e10cSrcweir const ::rtl::OUString& rsText, 321*cdf0e10cSrcweir const sal_Int8 nTextDirection) 322*cdf0e10cSrcweir { 323*cdf0e10cSrcweir const geometry::RealRectangle2D aTextBBox (GetTextBoundingBox(rxFont, rsText, nTextDirection)); 324*cdf0e10cSrcweir return css::geometry::RealSize2D(aTextBBox.X2 - aTextBBox.X1, aTextBBox.Y2 - aTextBBox.Y1); 325*cdf0e10cSrcweir } 326*cdf0e10cSrcweir 327*cdf0e10cSrcweir 328*cdf0e10cSrcweir } } // end of namespace sdext::presenter 329