1 /************************************************************************* 2 * 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * Copyright 2000, 2010 Oracle and/or its affiliates. 6 * 7 * OpenOffice.org - a multi-platform office productivity suite 8 * 9 * This file is part of OpenOffice.org. 10 * 11 * OpenOffice.org is free software: you can redistribute it and/or modify 12 * it under the terms of the GNU Lesser General Public License version 3 13 * only, as published by the Free Software Foundation. 14 * 15 * OpenOffice.org is distributed in the hope that it will be useful, 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 * GNU Lesser General Public License version 3 for more details 19 * (a copy is included in the LICENSE file that accompanied this code). 20 * 21 * You should have received a copy of the GNU Lesser General Public License 22 * version 3 along with OpenOffice.org. If not, see 23 * <http://www.openoffice.org/license.html> 24 * for a copy of the LGPLv3 License. 25 * 26 ************************************************************************/ 27 28 // MARKER(update_precomp.py): autogen include statement, do not remove 29 #include "precompiled_sdext.hxx" 30 31 #include "PresenterUIPainter.hxx" 32 33 #include "PresenterCanvasHelper.hxx" 34 #include "PresenterGeometryHelper.hxx" 35 #include <com/sun/star/rendering/CompositeOperation.hpp> 36 #include <com/sun/star/rendering/XPolyPolygon2D.hpp> 37 38 using namespace ::com::sun::star; 39 using namespace ::com::sun::star::uno; 40 41 namespace sdext { namespace presenter { 42 43 44 void PresenterUIPainter::PaintHorizontalBitmapComposite ( 45 const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, 46 const css::awt::Rectangle& rRepaintBox, 47 const css::awt::Rectangle& rBoundingBox, 48 const css::uno::Reference<css::rendering::XBitmap>& rxLeftBitmap, 49 const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap, 50 const css::uno::Reference<css::rendering::XBitmap>& rxRightBitmap) 51 { 52 if (PresenterGeometryHelper::AreRectanglesDisjoint(rRepaintBox, rBoundingBox)) 53 { 54 // The bounding box lies completly outside the repaint area. 55 // Nothing has to be repainted. 56 return; 57 } 58 59 // Get bitmap sizes. 60 geometry::IntegerSize2D aLeftBitmapSize; 61 if (rxLeftBitmap.is()) 62 aLeftBitmapSize = rxLeftBitmap->getSize(); 63 geometry::IntegerSize2D aCenterBitmapSize; 64 if (rxRepeatableCenterBitmap.is()) 65 aCenterBitmapSize = rxRepeatableCenterBitmap->getSize(); 66 geometry::IntegerSize2D aRightBitmapSize; 67 if (rxRightBitmap.is()) 68 aRightBitmapSize = rxRightBitmap->getSize(); 69 70 // Prepare painting. 71 rendering::ViewState aViewState ( 72 geometry::AffineMatrix2D(1,0,0, 0,1,0), 73 NULL); 74 75 rendering::RenderState aRenderState ( 76 geometry::AffineMatrix2D(1,0,0, 0,1,0), 77 NULL, 78 Sequence<double>(4), 79 rendering::CompositeOperation::SOURCE); 80 81 // Paint the left bitmap once. 82 if (rxLeftBitmap.is()) 83 { 84 const awt::Rectangle aLeftBoundingBox ( 85 rBoundingBox.X, 86 rBoundingBox.Y, 87 ::std::min(aLeftBitmapSize.Width, rBoundingBox.Width), 88 rBoundingBox.Height); 89 aViewState.Clip = Reference<rendering::XPolyPolygon2D>( 90 PresenterGeometryHelper::CreatePolygon( 91 PresenterGeometryHelper::Intersection(rRepaintBox, aLeftBoundingBox), 92 rxCanvas->getDevice())); 93 aRenderState.AffineTransform.m02 = aLeftBoundingBox.X; 94 aRenderState.AffineTransform.m12 95 = aLeftBoundingBox.Y + (aLeftBoundingBox.Height - aLeftBitmapSize.Height) / 2; 96 rxCanvas->drawBitmap(rxLeftBitmap, aViewState, aRenderState); 97 } 98 99 // Paint the right bitmap once. 100 if (rxRightBitmap.is()) 101 { 102 const awt::Rectangle aRightBoundingBox ( 103 rBoundingBox.X + rBoundingBox.Width - aRightBitmapSize.Width, 104 rBoundingBox.Y, 105 ::std::min(aRightBitmapSize.Width, rBoundingBox.Width), 106 rBoundingBox.Height); 107 aViewState.Clip = Reference<rendering::XPolyPolygon2D>( 108 PresenterGeometryHelper::CreatePolygon( 109 PresenterGeometryHelper::Intersection(rRepaintBox, aRightBoundingBox), 110 rxCanvas->getDevice())); 111 aRenderState.AffineTransform.m02 112 = aRightBoundingBox.X + aRightBoundingBox.Width - aRightBitmapSize.Width; 113 aRenderState.AffineTransform.m12 114 = aRightBoundingBox.Y + (aRightBoundingBox.Height - aRightBitmapSize.Height) / 2; 115 rxCanvas->drawBitmap(rxRightBitmap, aViewState, aRenderState); 116 } 117 118 // Paint the center bitmap to fill the remaining space. 119 if (rxRepeatableCenterBitmap.is()) 120 { 121 const awt::Rectangle aCenterBoundingBox ( 122 rBoundingBox.X + aLeftBitmapSize.Width, 123 rBoundingBox.Y, 124 rBoundingBox.Width - aLeftBitmapSize.Width - aRightBitmapSize.Width, 125 rBoundingBox.Height); 126 if (aCenterBoundingBox.Width > 0) 127 { 128 aViewState.Clip = Reference<rendering::XPolyPolygon2D>( 129 PresenterGeometryHelper::CreatePolygon( 130 PresenterGeometryHelper::Intersection(rRepaintBox, aCenterBoundingBox), 131 rxCanvas->getDevice())); 132 sal_Int32 nX (aCenterBoundingBox.X); 133 const sal_Int32 nRight (aCenterBoundingBox.X + aCenterBoundingBox.Width - 1); 134 aRenderState.AffineTransform.m12 135 = aCenterBoundingBox.Y + (aCenterBoundingBox.Height-aCenterBitmapSize.Height) / 2; 136 while(nX <= nRight) 137 { 138 aRenderState.AffineTransform.m02 = nX; 139 rxCanvas->drawBitmap(rxRepeatableCenterBitmap, aViewState, aRenderState); 140 nX += aCenterBitmapSize.Width; 141 } 142 } 143 } 144 } 145 146 147 148 149 void PresenterUIPainter::PaintVerticalBitmapComposite ( 150 const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, 151 const css::awt::Rectangle& rRepaintBox, 152 const css::awt::Rectangle& rBoundingBox, 153 const css::uno::Reference<css::rendering::XBitmap>& rxTopBitmap, 154 const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap, 155 const css::uno::Reference<css::rendering::XBitmap>& rxBottomBitmap) 156 { 157 if (PresenterGeometryHelper::AreRectanglesDisjoint(rRepaintBox, rBoundingBox)) 158 { 159 // The bounding box lies completly outside the repaint area. 160 // Nothing has to be repainted. 161 return; 162 } 163 164 // Get bitmap sizes. 165 geometry::IntegerSize2D aTopBitmapSize; 166 if (rxTopBitmap.is()) 167 aTopBitmapSize = rxTopBitmap->getSize(); 168 geometry::IntegerSize2D aCenterBitmapSize; 169 if (rxRepeatableCenterBitmap.is()) 170 aCenterBitmapSize = rxRepeatableCenterBitmap->getSize(); 171 geometry::IntegerSize2D aBottomBitmapSize; 172 if (rxBottomBitmap.is()) 173 aBottomBitmapSize = rxBottomBitmap->getSize(); 174 175 // Prepare painting. 176 rendering::ViewState aViewState ( 177 geometry::AffineMatrix2D(1,0,0, 0,1,0), 178 NULL); 179 180 rendering::RenderState aRenderState ( 181 geometry::AffineMatrix2D(1,0,0, 0,1,0), 182 NULL, 183 Sequence<double>(4), 184 rendering::CompositeOperation::SOURCE); 185 186 // Paint the top bitmap once. 187 if (rxTopBitmap.is()) 188 { 189 const awt::Rectangle aTopBoundingBox ( 190 rBoundingBox.X, 191 rBoundingBox.Y, 192 rBoundingBox.Width, 193 ::std::min(aTopBitmapSize.Height, rBoundingBox.Height)); 194 aViewState.Clip = Reference<rendering::XPolyPolygon2D>( 195 PresenterGeometryHelper::CreatePolygon( 196 PresenterGeometryHelper::Intersection(rRepaintBox, aTopBoundingBox), 197 rxCanvas->getDevice())); 198 aRenderState.AffineTransform.m02 199 = aTopBoundingBox.X + (aTopBoundingBox.Width - aTopBitmapSize.Width) / 2; 200 aRenderState.AffineTransform.m12 = aTopBoundingBox.Y; 201 rxCanvas->drawBitmap(rxTopBitmap, aViewState, aRenderState); 202 } 203 204 // Paint the bottom bitmap once. 205 if (rxBottomBitmap.is()) 206 { 207 const sal_Int32 nBBoxHeight (::std::min(aBottomBitmapSize.Height, rBoundingBox.Height)); 208 const awt::Rectangle aBottomBoundingBox ( 209 rBoundingBox.X, 210 rBoundingBox.Y + rBoundingBox.Height - nBBoxHeight, 211 rBoundingBox.Width, 212 nBBoxHeight); 213 aViewState.Clip = Reference<rendering::XPolyPolygon2D>( 214 PresenterGeometryHelper::CreatePolygon( 215 PresenterGeometryHelper::Intersection(rRepaintBox, aBottomBoundingBox), 216 rxCanvas->getDevice())); 217 aRenderState.AffineTransform.m02 218 = aBottomBoundingBox.X + (aBottomBoundingBox.Width - aBottomBitmapSize.Width) / 2; 219 aRenderState.AffineTransform.m12 220 = aBottomBoundingBox.Y + aBottomBoundingBox.Height - aBottomBitmapSize.Height; 221 rxCanvas->drawBitmap(rxBottomBitmap, aViewState, aRenderState); 222 } 223 224 // Paint the center bitmap to fill the remaining space. 225 if (rxRepeatableCenterBitmap.is()) 226 { 227 const awt::Rectangle aCenterBoundingBox ( 228 rBoundingBox.X, 229 rBoundingBox.Y + aTopBitmapSize.Height, 230 rBoundingBox.Width, 231 rBoundingBox.Height - aTopBitmapSize.Height - aBottomBitmapSize.Height); 232 if (aCenterBoundingBox.Height > 0) 233 { 234 aViewState.Clip = Reference<rendering::XPolyPolygon2D>( 235 PresenterGeometryHelper::CreatePolygon( 236 PresenterGeometryHelper::Intersection(rRepaintBox, aCenterBoundingBox), 237 rxCanvas->getDevice())); 238 sal_Int32 nY (aCenterBoundingBox.Y); 239 const sal_Int32 nBottom (aCenterBoundingBox.Y + aCenterBoundingBox.Height - 1); 240 aRenderState.AffineTransform.m02 241 = aCenterBoundingBox.X + (aCenterBoundingBox.Width-aCenterBitmapSize.Width) / 2; 242 while(nY <= nBottom) 243 { 244 aRenderState.AffineTransform.m12 = nY; 245 rxCanvas->drawBitmap(rxRepeatableCenterBitmap, aViewState, aRenderState); 246 nY += aCenterBitmapSize.Height; 247 } 248 } 249 } 250 } 251 252 253 254 255 256 } } // end of namespace sdext::presenter 257