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 "PresenterGeometryHelper.hxx" 28 29 #include <math.h> 30 #include <algorithm> 31 32 using namespace ::com::sun::star; 33 using namespace ::com::sun::star::uno; 34 35 namespace { 36 37 sal_Int32 Right (const awt::Rectangle& rBox) 38 { 39 return rBox.X + rBox.Width - 1; 40 } 41 42 sal_Int32 Bottom (const awt::Rectangle& rBox) 43 { 44 return rBox.Y + rBox.Height - 1; 45 } 46 47 sal_Int32 Width (const sal_Int32 nLeft, const sal_Int32 nRight) 48 { 49 return nRight - nLeft + 1; 50 } 51 52 sal_Int32 Height (const sal_Int32 nTop, const sal_Int32 nBottom) 53 { 54 return nBottom - nTop + 1; 55 } 56 57 58 } // end of anonymous namespace 59 60 61 62 namespace sdext { namespace presenter { 63 64 sal_Int32 PresenterGeometryHelper::Floor (const double nValue) 65 { 66 return sal::static_int_cast<sal_Int32>(floor(nValue)); 67 } 68 69 70 71 72 sal_Int32 PresenterGeometryHelper::Ceil (const double nValue) 73 { 74 return sal::static_int_cast<sal_Int32>(ceil(nValue)); 75 } 76 77 78 79 80 sal_Int32 PresenterGeometryHelper::Round (const double nValue) 81 { 82 return sal::static_int_cast<sal_Int32>(floor(0.5 + nValue)); 83 } 84 85 86 87 88 awt::Rectangle PresenterGeometryHelper::ConvertRectangle ( 89 const geometry::RealRectangle2D& rBox) 90 { 91 const sal_Int32 nLeft (Floor(rBox.X1)); 92 const sal_Int32 nTop (Floor(rBox.Y1)); 93 const sal_Int32 nRight (Ceil(rBox.X2)); 94 const sal_Int32 nBottom (Ceil(rBox.Y2)); 95 return awt::Rectangle (nLeft,nTop,nRight-nLeft,nBottom-nTop); 96 } 97 98 99 100 101 awt::Rectangle PresenterGeometryHelper::ConvertRectangleWithConstantSize ( 102 const geometry::RealRectangle2D& rBox) 103 { 104 return awt::Rectangle ( 105 Round(rBox.X1), 106 Round(rBox.Y1), 107 Round(rBox.X2 - rBox.X1), 108 Round(rBox.Y2 - rBox.Y1)); 109 } 110 111 112 113 114 geometry::RealRectangle2D PresenterGeometryHelper::ConvertRectangle ( 115 const css::awt::Rectangle& rBox) 116 { 117 return geometry::RealRectangle2D( 118 rBox.X, 119 rBox.Y, 120 rBox.X + rBox.Width, 121 rBox.Y + rBox.Height); 122 } 123 124 125 126 127 awt::Rectangle PresenterGeometryHelper::TranslateRectangle ( 128 const css::awt::Rectangle& rBox, 129 const sal_Int32 nXOffset, 130 const sal_Int32 nYOffset) 131 { 132 return awt::Rectangle(rBox.X + nXOffset, rBox.Y + nYOffset, rBox.Width, rBox.Height); 133 } 134 135 136 137 138 awt::Rectangle PresenterGeometryHelper::Intersection ( 139 const css::awt::Rectangle& rBox1, 140 const css::awt::Rectangle& rBox2) 141 { 142 const sal_Int32 nLeft (::std::max(rBox1.X, rBox2.X)); 143 const sal_Int32 nTop (::std::max(rBox1.Y, rBox2.Y)); 144 const sal_Int32 nRight (::std::min(Right(rBox1), Right(rBox2))); 145 const sal_Int32 nBottom (::std::min(Bottom(rBox1), Bottom(rBox2))); 146 if (nLeft >= nRight || nTop >= nBottom) 147 return awt::Rectangle(); 148 else 149 return awt::Rectangle(nLeft,nTop, Width(nLeft,nRight), Height(nTop,nBottom)); 150 } 151 152 153 154 155 geometry::RealRectangle2D PresenterGeometryHelper::Intersection ( 156 const geometry::RealRectangle2D& rBox1, 157 const geometry::RealRectangle2D& rBox2) 158 { 159 const double nLeft (::std::max(rBox1.X1, rBox2.X1)); 160 const double nTop (::std::max(rBox1.Y1, rBox2.Y1)); 161 const double nRight (::std::min(rBox1.X2, rBox2.X2)); 162 const double nBottom (::std::min(rBox1.Y2, rBox2.Y2)); 163 if (nLeft >= nRight || nTop >= nBottom) 164 return geometry::RealRectangle2D(0,0,0,0); 165 else 166 return geometry::RealRectangle2D(nLeft,nTop, nRight, nBottom); 167 } 168 169 170 171 172 bool PresenterGeometryHelper::IsInside ( 173 const css::geometry::RealRectangle2D& rBox, 174 const css::geometry::RealPoint2D& rPoint) 175 { 176 return rBox.X1 <= rPoint.X 177 && rBox.Y1 <= rPoint.Y 178 && rBox.X2 >= rPoint.X 179 && rBox.Y2 >= rPoint.Y; 180 } 181 182 183 184 185 bool PresenterGeometryHelper::IsInside ( 186 const css::awt::Rectangle& rBox1, 187 const css::awt::Rectangle& rBox2) 188 { 189 return rBox1.X >= rBox2.X 190 && rBox1.Y >= rBox2.Y 191 && rBox1.X+rBox1.Width <= rBox2.X+rBox2.Width 192 && rBox1.Y+rBox1.Height <= rBox2.Y+rBox2.Height; 193 } 194 195 196 197 198 awt::Rectangle PresenterGeometryHelper::Union ( 199 const css::awt::Rectangle& rBox1, 200 const css::awt::Rectangle& rBox2) 201 { 202 if (rBox1.Width<=0 || rBox1.Height<=0) 203 return rBox2; 204 else if (rBox2.Width<=0 || rBox2.Height<=0) 205 return rBox1; 206 207 const sal_Int32 nLeft (::std::min(rBox1.X, rBox2.X)); 208 const sal_Int32 nTop (::std::min(rBox1.Y, rBox2.Y)); 209 const sal_Int32 nRight (::std::max(Right(rBox1), Right(rBox2))); 210 const sal_Int32 nBottom (::std::max(Bottom(rBox1), Bottom(rBox2))); 211 if (nLeft >= nRight || nTop >= nBottom) 212 return awt::Rectangle(); 213 else 214 return awt::Rectangle(nLeft,nTop, Width(nLeft,nRight), Height(nTop,nBottom)); 215 } 216 217 218 219 220 geometry::RealRectangle2D PresenterGeometryHelper::Union ( 221 const geometry::RealRectangle2D& rBox1, 222 const geometry::RealRectangle2D& rBox2) 223 { 224 const double nLeft (::std::min(rBox1.X1, rBox2.X1)); 225 const double nTop (::std::min(rBox1.Y1, rBox2.Y1)); 226 const double nRight (::std::max(rBox1.X2, rBox2.X2)); 227 const double nBottom (::std::max(rBox1.Y2, rBox2.Y2)); 228 if (nLeft >= nRight || nTop >= nBottom) 229 return geometry::RealRectangle2D(0,0,0,0); 230 else 231 return geometry::RealRectangle2D(nLeft,nTop, nRight, nBottom); 232 } 233 234 235 236 237 bool PresenterGeometryHelper::AreRectanglesDisjoint ( 238 const css::awt::Rectangle& rBox1, 239 const css::awt::Rectangle& rBox2) 240 { 241 return rBox1.X+rBox1.Width <= rBox2.X 242 || rBox1.Y+rBox1.Height <= rBox2.Y 243 || rBox1.X >= rBox2.X+rBox2.Width 244 || rBox1.Y >= rBox2.Y+rBox2.Height; 245 } 246 247 248 249 250 Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon( 251 const awt::Rectangle& rBox, 252 const Reference<rendering::XGraphicDevice>& rxDevice) 253 { 254 if ( ! rxDevice.is()) 255 return NULL; 256 257 Sequence<Sequence<geometry::RealPoint2D> > aPoints(1); 258 aPoints[0] = Sequence<geometry::RealPoint2D>(4); 259 aPoints[0][0] = geometry::RealPoint2D(rBox.X, rBox.Y); 260 aPoints[0][1] = geometry::RealPoint2D(rBox.X, rBox.Y+rBox.Height); 261 aPoints[0][2] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y+rBox.Height); 262 aPoints[0][3] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y); 263 Reference<rendering::XLinePolyPolygon2D> xPolygon ( 264 rxDevice->createCompatibleLinePolyPolygon(aPoints)); 265 Reference<rendering::XPolyPolygon2D> xRectangle (xPolygon, UNO_QUERY); 266 if (xRectangle.is()) 267 xRectangle->setClosed(0, sal_True); 268 269 return xRectangle; 270 } 271 272 273 274 275 Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon( 276 const geometry::RealRectangle2D& rBox, 277 const Reference<rendering::XGraphicDevice>& rxDevice) 278 { 279 if ( ! rxDevice.is()) 280 return NULL; 281 282 Sequence<Sequence<geometry::RealPoint2D> > aPoints(1); 283 aPoints[0] = Sequence<geometry::RealPoint2D>(4); 284 aPoints[0][0] = geometry::RealPoint2D(rBox.X1, rBox.Y1); 285 aPoints[0][1] = geometry::RealPoint2D(rBox.X1, rBox.Y2); 286 aPoints[0][2] = geometry::RealPoint2D(rBox.X2, rBox.Y2); 287 aPoints[0][3] = geometry::RealPoint2D(rBox.X2, rBox.Y1); 288 Reference<rendering::XLinePolyPolygon2D> xPolygon ( 289 rxDevice->createCompatibleLinePolyPolygon(aPoints)); 290 Reference<rendering::XPolyPolygon2D> xRectangle (xPolygon, UNO_QUERY); 291 if (xRectangle.is()) 292 xRectangle->setClosed(0, sal_True); 293 294 return xRectangle; 295 } 296 297 298 299 300 Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon( 301 const ::std::vector<css::awt::Rectangle>& rBoxes, 302 const Reference<rendering::XGraphicDevice>& rxDevice) 303 { 304 if ( ! rxDevice.is()) 305 return NULL; 306 307 const sal_Int32 nCount (rBoxes.size()); 308 Sequence<Sequence<geometry::RealPoint2D> > aPoints(nCount); 309 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex) 310 { 311 const awt::Rectangle& rBox (rBoxes[nIndex]); 312 aPoints[nIndex] = Sequence<geometry::RealPoint2D>(4); 313 aPoints[nIndex][0] = geometry::RealPoint2D(rBox.X, rBox.Y); 314 aPoints[nIndex][1] = geometry::RealPoint2D(rBox.X, rBox.Y+rBox.Height); 315 aPoints[nIndex][2] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y+rBox.Height); 316 aPoints[nIndex][3] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y); 317 } 318 319 Reference<rendering::XLinePolyPolygon2D> xPolygon ( 320 rxDevice->createCompatibleLinePolyPolygon(aPoints)); 321 Reference<rendering::XPolyPolygon2D> xRectangle (xPolygon, UNO_QUERY); 322 if (xRectangle.is()) 323 for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex) 324 xRectangle->setClosed(nIndex, sal_True); 325 326 return xRectangle; 327 } 328 329 330 } } 331