1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 // MARKER(update_precomp.py): autogen include statement, do not remove 25 #include "precompiled_sdext.hxx" 26 27 #include "PresenterUIPainter.hxx" 28 29 #include "PresenterCanvasHelper.hxx" 30 #include "PresenterGeometryHelper.hxx" 31 #include <com/sun/star/rendering/CompositeOperation.hpp> 32 #include <com/sun/star/rendering/XPolyPolygon2D.hpp> 33 34 using namespace ::com::sun::star; 35 using namespace ::com::sun::star::uno; 36 37 namespace sdext { namespace presenter { 38 39 40 void PresenterUIPainter::PaintHorizontalBitmapComposite ( 41 const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, 42 const css::awt::Rectangle& rRepaintBox, 43 const css::awt::Rectangle& rBoundingBox, 44 const css::uno::Reference<css::rendering::XBitmap>& rxLeftBitmap, 45 const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap, 46 const css::uno::Reference<css::rendering::XBitmap>& rxRightBitmap) 47 { 48 if (PresenterGeometryHelper::AreRectanglesDisjoint(rRepaintBox, rBoundingBox)) 49 { 50 // The bounding box lies completly outside the repaint area. 51 // Nothing has to be repainted. 52 return; 53 } 54 55 // Get bitmap sizes. 56 geometry::IntegerSize2D aLeftBitmapSize; 57 if (rxLeftBitmap.is()) 58 aLeftBitmapSize = rxLeftBitmap->getSize(); 59 geometry::IntegerSize2D aCenterBitmapSize; 60 if (rxRepeatableCenterBitmap.is()) 61 aCenterBitmapSize = rxRepeatableCenterBitmap->getSize(); 62 geometry::IntegerSize2D aRightBitmapSize; 63 if (rxRightBitmap.is()) 64 aRightBitmapSize = rxRightBitmap->getSize(); 65 66 // Prepare painting. 67 rendering::ViewState aViewState ( 68 geometry::AffineMatrix2D(1,0,0, 0,1,0), 69 NULL); 70 71 rendering::RenderState aRenderState ( 72 geometry::AffineMatrix2D(1,0,0, 0,1,0), 73 NULL, 74 Sequence<double>(4), 75 rendering::CompositeOperation::SOURCE); 76 77 // Paint the left bitmap once. 78 if (rxLeftBitmap.is()) 79 { 80 const awt::Rectangle aLeftBoundingBox ( 81 rBoundingBox.X, 82 rBoundingBox.Y, 83 ::std::min(aLeftBitmapSize.Width, rBoundingBox.Width), 84 rBoundingBox.Height); 85 aViewState.Clip = Reference<rendering::XPolyPolygon2D>( 86 PresenterGeometryHelper::CreatePolygon( 87 PresenterGeometryHelper::Intersection(rRepaintBox, aLeftBoundingBox), 88 rxCanvas->getDevice())); 89 aRenderState.AffineTransform.m02 = aLeftBoundingBox.X; 90 aRenderState.AffineTransform.m12 91 = aLeftBoundingBox.Y + (aLeftBoundingBox.Height - aLeftBitmapSize.Height) / 2; 92 rxCanvas->drawBitmap(rxLeftBitmap, aViewState, aRenderState); 93 } 94 95 // Paint the right bitmap once. 96 if (rxRightBitmap.is()) 97 { 98 const awt::Rectangle aRightBoundingBox ( 99 rBoundingBox.X + rBoundingBox.Width - aRightBitmapSize.Width, 100 rBoundingBox.Y, 101 ::std::min(aRightBitmapSize.Width, rBoundingBox.Width), 102 rBoundingBox.Height); 103 aViewState.Clip = Reference<rendering::XPolyPolygon2D>( 104 PresenterGeometryHelper::CreatePolygon( 105 PresenterGeometryHelper::Intersection(rRepaintBox, aRightBoundingBox), 106 rxCanvas->getDevice())); 107 aRenderState.AffineTransform.m02 108 = aRightBoundingBox.X + aRightBoundingBox.Width - aRightBitmapSize.Width; 109 aRenderState.AffineTransform.m12 110 = aRightBoundingBox.Y + (aRightBoundingBox.Height - aRightBitmapSize.Height) / 2; 111 rxCanvas->drawBitmap(rxRightBitmap, aViewState, aRenderState); 112 } 113 114 // Paint the center bitmap to fill the remaining space. 115 if (rxRepeatableCenterBitmap.is()) 116 { 117 const awt::Rectangle aCenterBoundingBox ( 118 rBoundingBox.X + aLeftBitmapSize.Width, 119 rBoundingBox.Y, 120 rBoundingBox.Width - aLeftBitmapSize.Width - aRightBitmapSize.Width, 121 rBoundingBox.Height); 122 if (aCenterBoundingBox.Width > 0) 123 { 124 aViewState.Clip = Reference<rendering::XPolyPolygon2D>( 125 PresenterGeometryHelper::CreatePolygon( 126 PresenterGeometryHelper::Intersection(rRepaintBox, aCenterBoundingBox), 127 rxCanvas->getDevice())); 128 sal_Int32 nX (aCenterBoundingBox.X); 129 const sal_Int32 nRight (aCenterBoundingBox.X + aCenterBoundingBox.Width - 1); 130 aRenderState.AffineTransform.m12 131 = aCenterBoundingBox.Y + (aCenterBoundingBox.Height-aCenterBitmapSize.Height) / 2; 132 while(nX <= nRight) 133 { 134 aRenderState.AffineTransform.m02 = nX; 135 rxCanvas->drawBitmap(rxRepeatableCenterBitmap, aViewState, aRenderState); 136 nX += aCenterBitmapSize.Width; 137 } 138 } 139 } 140 } 141 142 143 144 145 void PresenterUIPainter::PaintVerticalBitmapComposite ( 146 const css::uno::Reference<css::rendering::XCanvas>& rxCanvas, 147 const css::awt::Rectangle& rRepaintBox, 148 const css::awt::Rectangle& rBoundingBox, 149 const css::uno::Reference<css::rendering::XBitmap>& rxTopBitmap, 150 const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap, 151 const css::uno::Reference<css::rendering::XBitmap>& rxBottomBitmap) 152 { 153 if (PresenterGeometryHelper::AreRectanglesDisjoint(rRepaintBox, rBoundingBox)) 154 { 155 // The bounding box lies completly outside the repaint area. 156 // Nothing has to be repainted. 157 return; 158 } 159 160 // Get bitmap sizes. 161 geometry::IntegerSize2D aTopBitmapSize; 162 if (rxTopBitmap.is()) 163 aTopBitmapSize = rxTopBitmap->getSize(); 164 geometry::IntegerSize2D aCenterBitmapSize; 165 if (rxRepeatableCenterBitmap.is()) 166 aCenterBitmapSize = rxRepeatableCenterBitmap->getSize(); 167 geometry::IntegerSize2D aBottomBitmapSize; 168 if (rxBottomBitmap.is()) 169 aBottomBitmapSize = rxBottomBitmap->getSize(); 170 171 // Prepare painting. 172 rendering::ViewState aViewState ( 173 geometry::AffineMatrix2D(1,0,0, 0,1,0), 174 NULL); 175 176 rendering::RenderState aRenderState ( 177 geometry::AffineMatrix2D(1,0,0, 0,1,0), 178 NULL, 179 Sequence<double>(4), 180 rendering::CompositeOperation::SOURCE); 181 182 // Paint the top bitmap once. 183 if (rxTopBitmap.is()) 184 { 185 const awt::Rectangle aTopBoundingBox ( 186 rBoundingBox.X, 187 rBoundingBox.Y, 188 rBoundingBox.Width, 189 ::std::min(aTopBitmapSize.Height, rBoundingBox.Height)); 190 aViewState.Clip = Reference<rendering::XPolyPolygon2D>( 191 PresenterGeometryHelper::CreatePolygon( 192 PresenterGeometryHelper::Intersection(rRepaintBox, aTopBoundingBox), 193 rxCanvas->getDevice())); 194 aRenderState.AffineTransform.m02 195 = aTopBoundingBox.X + (aTopBoundingBox.Width - aTopBitmapSize.Width) / 2; 196 aRenderState.AffineTransform.m12 = aTopBoundingBox.Y; 197 rxCanvas->drawBitmap(rxTopBitmap, aViewState, aRenderState); 198 } 199 200 // Paint the bottom bitmap once. 201 if (rxBottomBitmap.is()) 202 { 203 const sal_Int32 nBBoxHeight (::std::min(aBottomBitmapSize.Height, rBoundingBox.Height)); 204 const awt::Rectangle aBottomBoundingBox ( 205 rBoundingBox.X, 206 rBoundingBox.Y + rBoundingBox.Height - nBBoxHeight, 207 rBoundingBox.Width, 208 nBBoxHeight); 209 aViewState.Clip = Reference<rendering::XPolyPolygon2D>( 210 PresenterGeometryHelper::CreatePolygon( 211 PresenterGeometryHelper::Intersection(rRepaintBox, aBottomBoundingBox), 212 rxCanvas->getDevice())); 213 aRenderState.AffineTransform.m02 214 = aBottomBoundingBox.X + (aBottomBoundingBox.Width - aBottomBitmapSize.Width) / 2; 215 aRenderState.AffineTransform.m12 216 = aBottomBoundingBox.Y + aBottomBoundingBox.Height - aBottomBitmapSize.Height; 217 rxCanvas->drawBitmap(rxBottomBitmap, aViewState, aRenderState); 218 } 219 220 // Paint the center bitmap to fill the remaining space. 221 if (rxRepeatableCenterBitmap.is()) 222 { 223 const awt::Rectangle aCenterBoundingBox ( 224 rBoundingBox.X, 225 rBoundingBox.Y + aTopBitmapSize.Height, 226 rBoundingBox.Width, 227 rBoundingBox.Height - aTopBitmapSize.Height - aBottomBitmapSize.Height); 228 if (aCenterBoundingBox.Height > 0) 229 { 230 aViewState.Clip = Reference<rendering::XPolyPolygon2D>( 231 PresenterGeometryHelper::CreatePolygon( 232 PresenterGeometryHelper::Intersection(rRepaintBox, aCenterBoundingBox), 233 rxCanvas->getDevice())); 234 sal_Int32 nY (aCenterBoundingBox.Y); 235 const sal_Int32 nBottom (aCenterBoundingBox.Y + aCenterBoundingBox.Height - 1); 236 aRenderState.AffineTransform.m02 237 = aCenterBoundingBox.X + (aCenterBoundingBox.Width-aCenterBitmapSize.Width) / 2; 238 while(nY <= nBottom) 239 { 240 aRenderState.AffineTransform.m12 = nY; 241 rxCanvas->drawBitmap(rxRepeatableCenterBitmap, aViewState, aRenderState); 242 nY += aCenterBitmapSize.Height; 243 } 244 } 245 } 246 } 247 248 249 250 251 252 } } // end of namespace sdext::presenter 253