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