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
PaintHorizontalBitmapComposite(const css::uno::Reference<css::rendering::XCanvas> & rxCanvas,const css::awt::Rectangle & rRepaintBox,const css::awt::Rectangle & rBoundingBox,const css::uno::Reference<css::rendering::XBitmap> & rxLeftBitmap,const css::uno::Reference<css::rendering::XBitmap> & rxRepeatableCenterBitmap,const css::uno::Reference<css::rendering::XBitmap> & rxRightBitmap)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
PaintVerticalBitmapComposite(const css::uno::Reference<css::rendering::XCanvas> & rxCanvas,const css::awt::Rectangle & rRepaintBox,const css::awt::Rectangle & rBoundingBox,const css::uno::Reference<css::rendering::XBitmap> & rxTopBitmap,const css::uno::Reference<css::rendering::XBitmap> & rxRepeatableCenterBitmap,const css::uno::Reference<css::rendering::XBitmap> & rxBottomBitmap)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