1 /*************************************************************************
2  *
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * Copyright 2000, 2010 Oracle and/or its affiliates.
6  *
7  * OpenOffice.org - a multi-platform office productivity suite
8  *
9  * This file is part of OpenOffice.org.
10  *
11  * OpenOffice.org is free software: you can redistribute it and/or modify
12  * it under the terms of the GNU Lesser General Public License version 3
13  * only, as published by the Free Software Foundation.
14  *
15  * OpenOffice.org is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18  * GNU Lesser General Public License version 3 for more details
19  * (a copy is included in the LICENSE file that accompanied this code).
20  *
21  * You should have received a copy of the GNU Lesser General Public License
22  * version 3 along with OpenOffice.org.  If not, see
23  * <http://www.openoffice.org/license.html>
24  * for a copy of the LGPLv3 License.
25  *
26  ************************************************************************/
27 
28 // MARKER(update_precomp.py): autogen include statement, do not remove
29 #include "precompiled_sdext.hxx"
30 
31 #include "PresenterUIPainter.hxx"
32 
33 #include "PresenterCanvasHelper.hxx"
34 #include "PresenterGeometryHelper.hxx"
35 #include <com/sun/star/rendering/CompositeOperation.hpp>
36 #include <com/sun/star/rendering/XPolyPolygon2D.hpp>
37 
38 using namespace ::com::sun::star;
39 using namespace ::com::sun::star::uno;
40 
41 namespace sdext { namespace presenter {
42 
43 
44 void PresenterUIPainter::PaintHorizontalBitmapComposite (
45     const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
46     const css::awt::Rectangle& rRepaintBox,
47     const css::awt::Rectangle& rBoundingBox,
48     const css::uno::Reference<css::rendering::XBitmap>& rxLeftBitmap,
49     const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap,
50     const css::uno::Reference<css::rendering::XBitmap>& rxRightBitmap)
51 {
52     if (PresenterGeometryHelper::AreRectanglesDisjoint(rRepaintBox, rBoundingBox))
53     {
54         // The bounding box lies completly outside the repaint area.
55         // Nothing has to be repainted.
56         return;
57     }
58 
59     // Get bitmap sizes.
60     geometry::IntegerSize2D aLeftBitmapSize;
61     if (rxLeftBitmap.is())
62         aLeftBitmapSize = rxLeftBitmap->getSize();
63     geometry::IntegerSize2D aCenterBitmapSize;
64     if (rxRepeatableCenterBitmap.is())
65         aCenterBitmapSize = rxRepeatableCenterBitmap->getSize();
66     geometry::IntegerSize2D aRightBitmapSize;
67     if (rxRightBitmap.is())
68         aRightBitmapSize = rxRightBitmap->getSize();
69 
70     // Prepare painting.
71     rendering::ViewState aViewState (
72         geometry::AffineMatrix2D(1,0,0, 0,1,0),
73         NULL);
74 
75     rendering::RenderState aRenderState (
76         geometry::AffineMatrix2D(1,0,0, 0,1,0),
77         NULL,
78         Sequence<double>(4),
79         rendering::CompositeOperation::SOURCE);
80 
81     // Paint the left bitmap once.
82     if (rxLeftBitmap.is())
83     {
84         const awt::Rectangle aLeftBoundingBox (
85             rBoundingBox.X,
86             rBoundingBox.Y,
87             ::std::min(aLeftBitmapSize.Width, rBoundingBox.Width),
88             rBoundingBox.Height);
89         aViewState.Clip = Reference<rendering::XPolyPolygon2D>(
90             PresenterGeometryHelper::CreatePolygon(
91                 PresenterGeometryHelper::Intersection(rRepaintBox, aLeftBoundingBox),
92                 rxCanvas->getDevice()));
93         aRenderState.AffineTransform.m02 = aLeftBoundingBox.X;
94         aRenderState.AffineTransform.m12
95             = aLeftBoundingBox.Y + (aLeftBoundingBox.Height - aLeftBitmapSize.Height) / 2;
96         rxCanvas->drawBitmap(rxLeftBitmap, aViewState, aRenderState);
97     }
98 
99     // Paint the right bitmap once.
100     if (rxRightBitmap.is())
101     {
102         const awt::Rectangle aRightBoundingBox (
103             rBoundingBox.X + rBoundingBox.Width - aRightBitmapSize.Width,
104             rBoundingBox.Y,
105             ::std::min(aRightBitmapSize.Width, rBoundingBox.Width),
106             rBoundingBox.Height);
107         aViewState.Clip = Reference<rendering::XPolyPolygon2D>(
108             PresenterGeometryHelper::CreatePolygon(
109                 PresenterGeometryHelper::Intersection(rRepaintBox, aRightBoundingBox),
110                 rxCanvas->getDevice()));
111         aRenderState.AffineTransform.m02
112             = aRightBoundingBox.X + aRightBoundingBox.Width - aRightBitmapSize.Width;
113         aRenderState.AffineTransform.m12
114             = aRightBoundingBox.Y + (aRightBoundingBox.Height - aRightBitmapSize.Height) / 2;
115         rxCanvas->drawBitmap(rxRightBitmap, aViewState, aRenderState);
116     }
117 
118     // Paint the center bitmap to fill the remaining space.
119     if (rxRepeatableCenterBitmap.is())
120     {
121         const awt::Rectangle aCenterBoundingBox (
122             rBoundingBox.X + aLeftBitmapSize.Width,
123             rBoundingBox.Y,
124             rBoundingBox.Width - aLeftBitmapSize.Width - aRightBitmapSize.Width,
125             rBoundingBox.Height);
126         if (aCenterBoundingBox.Width > 0)
127         {
128             aViewState.Clip = Reference<rendering::XPolyPolygon2D>(
129                 PresenterGeometryHelper::CreatePolygon(
130                     PresenterGeometryHelper::Intersection(rRepaintBox, aCenterBoundingBox),
131                     rxCanvas->getDevice()));
132             sal_Int32 nX (aCenterBoundingBox.X);
133             const sal_Int32 nRight (aCenterBoundingBox.X + aCenterBoundingBox.Width - 1);
134             aRenderState.AffineTransform.m12
135                 = aCenterBoundingBox.Y + (aCenterBoundingBox.Height-aCenterBitmapSize.Height) / 2;
136             while(nX <= nRight)
137             {
138                 aRenderState.AffineTransform.m02 = nX;
139                 rxCanvas->drawBitmap(rxRepeatableCenterBitmap, aViewState, aRenderState);
140                 nX += aCenterBitmapSize.Width;
141             }
142         }
143     }
144 }
145 
146 
147 
148 
149 void PresenterUIPainter::PaintVerticalBitmapComposite (
150     const css::uno::Reference<css::rendering::XCanvas>& rxCanvas,
151     const css::awt::Rectangle& rRepaintBox,
152     const css::awt::Rectangle& rBoundingBox,
153     const css::uno::Reference<css::rendering::XBitmap>& rxTopBitmap,
154     const css::uno::Reference<css::rendering::XBitmap>& rxRepeatableCenterBitmap,
155     const css::uno::Reference<css::rendering::XBitmap>& rxBottomBitmap)
156 {
157     if (PresenterGeometryHelper::AreRectanglesDisjoint(rRepaintBox, rBoundingBox))
158     {
159         // The bounding box lies completly outside the repaint area.
160         // Nothing has to be repainted.
161         return;
162     }
163 
164     // Get bitmap sizes.
165     geometry::IntegerSize2D aTopBitmapSize;
166     if (rxTopBitmap.is())
167         aTopBitmapSize = rxTopBitmap->getSize();
168     geometry::IntegerSize2D aCenterBitmapSize;
169     if (rxRepeatableCenterBitmap.is())
170         aCenterBitmapSize = rxRepeatableCenterBitmap->getSize();
171     geometry::IntegerSize2D aBottomBitmapSize;
172     if (rxBottomBitmap.is())
173         aBottomBitmapSize = rxBottomBitmap->getSize();
174 
175     // Prepare painting.
176     rendering::ViewState aViewState (
177         geometry::AffineMatrix2D(1,0,0, 0,1,0),
178         NULL);
179 
180     rendering::RenderState aRenderState (
181         geometry::AffineMatrix2D(1,0,0, 0,1,0),
182         NULL,
183         Sequence<double>(4),
184         rendering::CompositeOperation::SOURCE);
185 
186     // Paint the top bitmap once.
187     if (rxTopBitmap.is())
188     {
189         const awt::Rectangle aTopBoundingBox (
190             rBoundingBox.X,
191             rBoundingBox.Y,
192             rBoundingBox.Width,
193             ::std::min(aTopBitmapSize.Height, rBoundingBox.Height));
194         aViewState.Clip = Reference<rendering::XPolyPolygon2D>(
195             PresenterGeometryHelper::CreatePolygon(
196                 PresenterGeometryHelper::Intersection(rRepaintBox, aTopBoundingBox),
197                 rxCanvas->getDevice()));
198         aRenderState.AffineTransform.m02
199             = aTopBoundingBox.X + (aTopBoundingBox.Width - aTopBitmapSize.Width) / 2;
200         aRenderState.AffineTransform.m12 = aTopBoundingBox.Y;
201         rxCanvas->drawBitmap(rxTopBitmap, aViewState, aRenderState);
202     }
203 
204     // Paint the bottom bitmap once.
205     if (rxBottomBitmap.is())
206     {
207         const sal_Int32 nBBoxHeight (::std::min(aBottomBitmapSize.Height, rBoundingBox.Height));
208         const awt::Rectangle aBottomBoundingBox (
209             rBoundingBox.X,
210             rBoundingBox.Y  + rBoundingBox.Height - nBBoxHeight,
211             rBoundingBox.Width,
212             nBBoxHeight);
213         aViewState.Clip = Reference<rendering::XPolyPolygon2D>(
214             PresenterGeometryHelper::CreatePolygon(
215                 PresenterGeometryHelper::Intersection(rRepaintBox, aBottomBoundingBox),
216                 rxCanvas->getDevice()));
217         aRenderState.AffineTransform.m02
218             = aBottomBoundingBox.X + (aBottomBoundingBox.Width - aBottomBitmapSize.Width) / 2;
219         aRenderState.AffineTransform.m12
220             = aBottomBoundingBox.Y + aBottomBoundingBox.Height - aBottomBitmapSize.Height;
221         rxCanvas->drawBitmap(rxBottomBitmap, aViewState, aRenderState);
222     }
223 
224     // Paint the center bitmap to fill the remaining space.
225     if (rxRepeatableCenterBitmap.is())
226     {
227         const awt::Rectangle aCenterBoundingBox (
228             rBoundingBox.X,
229             rBoundingBox.Y + aTopBitmapSize.Height,
230             rBoundingBox.Width,
231             rBoundingBox.Height - aTopBitmapSize.Height - aBottomBitmapSize.Height);
232         if (aCenterBoundingBox.Height > 0)
233         {
234             aViewState.Clip = Reference<rendering::XPolyPolygon2D>(
235                 PresenterGeometryHelper::CreatePolygon(
236                     PresenterGeometryHelper::Intersection(rRepaintBox, aCenterBoundingBox),
237                     rxCanvas->getDevice()));
238             sal_Int32 nY (aCenterBoundingBox.Y);
239             const sal_Int32 nBottom (aCenterBoundingBox.Y + aCenterBoundingBox.Height - 1);
240             aRenderState.AffineTransform.m02
241                 = aCenterBoundingBox.X + (aCenterBoundingBox.Width-aCenterBitmapSize.Width) / 2;
242             while(nY <= nBottom)
243             {
244                 aRenderState.AffineTransform.m12 = nY;
245                 rxCanvas->drawBitmap(rxRepeatableCenterBitmap, aViewState, aRenderState);
246                 nY += aCenterBitmapSize.Height;
247             }
248         }
249     }
250 }
251 
252 
253 
254 
255 
256 } } // end of namespace sdext::presenter
257