LibreOffice Module sdext (master)  1
PresenterGeometryHelper.cxx
Go to the documentation of this file.
1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 /*
3  * This file is part of the LibreOffice project.
4  *
5  * This Source Code Form is subject to the terms of the Mozilla Public
6  * License, v. 2.0. If a copy of the MPL was not distributed with this
7  * file, You can obtain one at http://mozilla.org/MPL/2.0/.
8  *
9  * This file incorporates work covered by the following license notice:
10  *
11  * Licensed to the Apache Software Foundation (ASF) under one or more
12  * contributor license agreements. See the NOTICE file distributed
13  * with this work for additional information regarding copyright
14  * ownership. The ASF licenses this file to you under the Apache
15  * License, Version 2.0 (the "License"); you may not use this file
16  * except in compliance with the License. You may obtain a copy of
17  * the License at http://www.apache.org/licenses/LICENSE-2.0 .
18  */
19 
21 
22 #include <math.h>
23 #include <algorithm>
24 
25 using namespace ::com::sun::star;
26 using namespace ::com::sun::star::uno;
27 
28 namespace {
29 
30 sal_Int32 Right (const awt::Rectangle& rBox)
31 {
32  return rBox.X + rBox.Width - 1;
33 }
34 
35 sal_Int32 Bottom (const awt::Rectangle& rBox)
36 {
37  return rBox.Y + rBox.Height - 1;
38 }
39 
40 sal_Int32 Width (const sal_Int32 nLeft, const sal_Int32 nRight)
41 {
42  return nRight - nLeft + 1;
43 }
44 
45 sal_Int32 Height (const sal_Int32 nTop, const sal_Int32 nBottom)
46 {
47  return nBottom - nTop + 1;
48 }
49 
50 } // end of anonymous namespace
51 
52 namespace sdext { namespace presenter {
53 
54 sal_Int32 PresenterGeometryHelper::Floor (const double nValue)
55 {
56  return sal::static_int_cast<sal_Int32>(floor(nValue));
57 }
58 
59 sal_Int32 PresenterGeometryHelper::Ceil (const double nValue)
60 {
61  return sal::static_int_cast<sal_Int32>(ceil(nValue));
62 }
63 
64 sal_Int32 PresenterGeometryHelper::Round (const double nValue)
65 {
66  return sal::static_int_cast<sal_Int32>(floor(0.5 + nValue));
67 }
68 
70  const geometry::RealRectangle2D& rBox)
71 {
72  const sal_Int32 nLeft (Floor(rBox.X1));
73  const sal_Int32 nTop (Floor(rBox.Y1));
74  const sal_Int32 nRight (Ceil(rBox.X2));
75  const sal_Int32 nBottom (Ceil(rBox.Y2));
76  return awt::Rectangle (nLeft,nTop,nRight-nLeft,nBottom-nTop);
77 }
78 
80  const geometry::RealRectangle2D& rBox)
81 {
82  return awt::Rectangle (
83  Round(rBox.X1),
84  Round(rBox.Y1),
85  Round(rBox.X2 - rBox.X1),
86  Round(rBox.Y2 - rBox.Y1));
87 }
88 
89 geometry::RealRectangle2D PresenterGeometryHelper::ConvertRectangle (
90  const css::awt::Rectangle& rBox)
91 {
92  return geometry::RealRectangle2D(
93  rBox.X,
94  rBox.Y,
95  rBox.X + rBox.Width,
96  rBox.Y + rBox.Height);
97 }
98 
100  const css::awt::Rectangle& rBox,
101  const sal_Int32 nXOffset,
102  const sal_Int32 nYOffset)
103 {
104  return awt::Rectangle(rBox.X + nXOffset, rBox.Y + nYOffset, rBox.Width, rBox.Height);
105 }
106 
108  const css::awt::Rectangle& rBox1,
109  const css::awt::Rectangle& rBox2)
110 {
111  const sal_Int32 nLeft (::std::max(rBox1.X, rBox2.X));
112  const sal_Int32 nTop (::std::max(rBox1.Y, rBox2.Y));
113  const sal_Int32 nRight (::std::min(Right(rBox1), Right(rBox2)));
114  const sal_Int32 nBottom (::std::min(Bottom(rBox1), Bottom(rBox2)));
115  if (nLeft >= nRight || nTop >= nBottom)
116  return awt::Rectangle();
117  else
118  return awt::Rectangle(nLeft,nTop, Width(nLeft,nRight), Height(nTop,nBottom));
119 }
120 
121 geometry::RealRectangle2D PresenterGeometryHelper::Intersection (
122  const geometry::RealRectangle2D& rBox1,
123  const geometry::RealRectangle2D& rBox2)
124 {
125  const double nLeft (::std::max(rBox1.X1, rBox2.X1));
126  const double nTop (::std::max(rBox1.Y1, rBox2.Y1));
127  const double nRight (::std::min(rBox1.X2, rBox2.X2));
128  const double nBottom (::std::min(rBox1.Y2, rBox2.Y2));
129  if (nLeft >= nRight || nTop >= nBottom)
130  return geometry::RealRectangle2D(0,0,0,0);
131  else
132  return geometry::RealRectangle2D(nLeft,nTop, nRight, nBottom);
133 }
134 
136  const css::geometry::RealRectangle2D& rBox,
137  const css::geometry::RealPoint2D& rPoint)
138 {
139  return rBox.X1 <= rPoint.X
140  && rBox.Y1 <= rPoint.Y
141  && rBox.X2 >= rPoint.X
142  && rBox.Y2 >= rPoint.Y;
143 }
144 
146  const css::awt::Rectangle& rBox1,
147  const css::awt::Rectangle& rBox2)
148 {
149  return rBox1.X >= rBox2.X
150  && rBox1.Y >= rBox2.Y
151  && rBox1.X+rBox1.Width <= rBox2.X+rBox2.Width
152  && rBox1.Y+rBox1.Height <= rBox2.Y+rBox2.Height;
153 }
154 
155 geometry::RealRectangle2D PresenterGeometryHelper::Union (
156  const geometry::RealRectangle2D& rBox1,
157  const geometry::RealRectangle2D& rBox2)
158 {
159  const double nLeft (::std::min(rBox1.X1, rBox2.X1));
160  const double nTop (::std::min(rBox1.Y1, rBox2.Y1));
161  const double nRight (::std::max(rBox1.X2, rBox2.X2));
162  const double nBottom (::std::max(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 
170  const css::awt::Rectangle& rBox1,
171  const css::awt::Rectangle& rBox2)
172 {
173  return rBox1.X+rBox1.Width <= rBox2.X
174  || rBox1.Y+rBox1.Height <= rBox2.Y
175  || rBox1.X >= rBox2.X+rBox2.Width
176  || rBox1.Y >= rBox2.Y+rBox2.Height;
177 }
178 
179 Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon(
180  const awt::Rectangle& rBox,
181  const Reference<rendering::XGraphicDevice>& rxDevice)
182 {
183  if ( ! rxDevice.is())
184  return nullptr;
185 
186  Sequence<Sequence<geometry::RealPoint2D> > aPoints(1);
187  aPoints[0] = Sequence<geometry::RealPoint2D>(4);
188  aPoints[0][0] = geometry::RealPoint2D(rBox.X, rBox.Y);
189  aPoints[0][1] = geometry::RealPoint2D(rBox.X, rBox.Y+rBox.Height);
190  aPoints[0][2] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y+rBox.Height);
191  aPoints[0][3] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y);
192  Reference<rendering::XLinePolyPolygon2D> xPolygon (
193  rxDevice->createCompatibleLinePolyPolygon(aPoints));
194  if (xPolygon.is())
195  xPolygon->setClosed(0, true);
196 
197  return xPolygon;
198 }
199 
200 Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon(
201  const geometry::RealRectangle2D& rBox,
202  const Reference<rendering::XGraphicDevice>& rxDevice)
203 {
204  if ( ! rxDevice.is())
205  return nullptr;
206 
207  Sequence<Sequence<geometry::RealPoint2D> > aPoints(1);
208  aPoints[0] = Sequence<geometry::RealPoint2D>(4);
209  aPoints[0][0] = geometry::RealPoint2D(rBox.X1, rBox.Y1);
210  aPoints[0][1] = geometry::RealPoint2D(rBox.X1, rBox.Y2);
211  aPoints[0][2] = geometry::RealPoint2D(rBox.X2, rBox.Y2);
212  aPoints[0][3] = geometry::RealPoint2D(rBox.X2, rBox.Y1);
213  Reference<rendering::XLinePolyPolygon2D> xPolygon (
214  rxDevice->createCompatibleLinePolyPolygon(aPoints));
215  if (xPolygon.is())
216  xPolygon->setClosed(0, true);
217 
218  return xPolygon;
219 }
220 
221 Reference<rendering::XPolyPolygon2D> PresenterGeometryHelper::CreatePolygon(
222  const ::std::vector<css::awt::Rectangle>& rBoxes,
223  const Reference<rendering::XGraphicDevice>& rxDevice)
224 {
225  if ( ! rxDevice.is())
226  return nullptr;
227 
228  const sal_Int32 nCount (rBoxes.size());
229  Sequence<Sequence<geometry::RealPoint2D> > aPoints(nCount);
230  for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
231  {
232  const awt::Rectangle& rBox (rBoxes[nIndex]);
233  aPoints[nIndex] = Sequence<geometry::RealPoint2D>(4);
234  aPoints[nIndex][0] = geometry::RealPoint2D(rBox.X, rBox.Y);
235  aPoints[nIndex][1] = geometry::RealPoint2D(rBox.X, rBox.Y+rBox.Height);
236  aPoints[nIndex][2] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y+rBox.Height);
237  aPoints[nIndex][3] = geometry::RealPoint2D(rBox.X+rBox.Width, rBox.Y);
238  }
239 
240  Reference<rendering::XLinePolyPolygon2D> xPolygon (
241  rxDevice->createCompatibleLinePolyPolygon(aPoints));
242  if (xPolygon.is())
243  for (sal_Int32 nIndex=0; nIndex<nCount; ++nIndex)
244  xPolygon->setClosed(nIndex, true);
245 
246  return xPolygon;
247 }
248 
249 } }
250 
251 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
static sal_Int32 Round(const double nValue)
sal_Int32 nIndex
static bool AreRectanglesDisjoint(const css::awt::Rectangle &rBox1, const css::awt::Rectangle &rBox2)
static sal_Int32 Ceil(const double nValue)
static css::geometry::RealRectangle2D Union(const css::geometry::RealRectangle2D &rBox1, const css::geometry::RealRectangle2D &rBox2)
int nCount
static css::awt::Rectangle TranslateRectangle(const css::awt::Rectangle &rBox, const sal_Int32 nXOffset, const sal_Int32 nYOffset)
Right
static sal_Int32 Floor(const double nValue)
static css::awt::Rectangle ConvertRectangleWithConstantSize(const css::geometry::RealRectangle2D &rBox)
Convert the given rectangle to integer coordinates so that width and height remain constant when only...
static css::awt::Rectangle ConvertRectangle(const css::geometry::RealRectangle2D &rBox)
Return the bounding box with integer coordinates of the given rectangle.
static css::uno::Reference< css::rendering::XPolyPolygon2D > CreatePolygon(const css::awt::Rectangle &rBox, const css::uno::Reference< css::rendering::XGraphicDevice > &rxDevice)
static css::awt::Rectangle Intersection(const css::awt::Rectangle &rBox1, const css::awt::Rectangle &rBox2)
static bool IsInside(const css::geometry::RealRectangle2D &rBox, const css::geometry::RealPoint2D &rPoint)