xref: /AOO41X/main/sd/source/ui/slidesorter/view/SlsFramePainter.cxx (revision 1ecadb572e7010ff3b3382ad9bf179dbc6efadbb)
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 #include "precompiled_sd.hxx"
29 
30 #include "SlsFramePainter.hxx"
31 #include <vcl/outdev.hxx>
32 #include <vcl/bmpacc.hxx>
33 
34 
35 namespace sd { namespace slidesorter { namespace view {
36 
37 FramePainter::FramePainter (const BitmapEx& rShadowBitmap)
38     : maTopLeft(rShadowBitmap,-1,-1),
39       maTop(rShadowBitmap,0,-1),
40       maTopRight(rShadowBitmap,+1,-1),
41       maLeft(rShadowBitmap,-1,0),
42       maRight(rShadowBitmap,+1,0),
43       maBottomLeft(rShadowBitmap,-1,+1),
44       maBottom(rShadowBitmap,0,+1),
45       maBottomRight(rShadowBitmap,+1,+1),
46       maCenter(rShadowBitmap,0,0),
47       mbIsValid(false)
48 {
49     if (rShadowBitmap.GetSizePixel().Width() == rShadowBitmap.GetSizePixel().Height()
50         && (rShadowBitmap.GetSizePixel().Width()-1)%2 == 0
51         && ((rShadowBitmap.GetSizePixel().Width()-1)/2)%2 == 1)
52     {
53         mbIsValid = true;
54     }
55     else
56     {
57         OSL_ASSERT(rShadowBitmap.GetSizePixel().Width() == rShadowBitmap.GetSizePixel().Height());
58         OSL_ASSERT((rShadowBitmap.GetSizePixel().Width()-1)%2 == 0);
59         OSL_ASSERT(((rShadowBitmap.GetSizePixel().Width()-1)/2)%2 == 1);
60     }
61 }
62 
63 
64 
65 
66 FramePainter::~FramePainter (void)
67 {
68 }
69 
70 
71 
72 
73 void FramePainter::PaintFrame (
74     OutputDevice& rDevice,
75     const Rectangle aBox) const
76 {
77     if ( ! mbIsValid)
78         return;
79 
80     // Paint the shadow.
81     maTopLeft.PaintCorner(rDevice, aBox.TopLeft());
82     maTopRight.PaintCorner(rDevice, aBox.TopRight());
83     maBottomLeft.PaintCorner(rDevice, aBox.BottomLeft());
84     maBottomRight.PaintCorner(rDevice, aBox.BottomRight());
85     maLeft.PaintSide(rDevice, aBox.TopLeft(), aBox.BottomLeft(), maTopLeft, maBottomLeft);
86     maRight.PaintSide(rDevice, aBox.TopRight(), aBox.BottomRight(), maTopRight, maBottomRight);
87     maTop.PaintSide(rDevice, aBox.TopLeft(), aBox.TopRight(), maTopLeft, maTopRight);
88     maBottom.PaintSide(rDevice, aBox.BottomLeft(), aBox.BottomRight(), maBottomLeft, maBottomRight);
89     maCenter.PaintCenter(rDevice,aBox);
90 }
91 
92 
93 
94 
95 void FramePainter::AdaptColor (
96     const Color aNewColor,
97     const bool bEraseCenter)
98 {
99     // Get the source color.
100     if (maCenter.maBitmap.IsEmpty())
101         return;
102     BitmapReadAccess* pReadAccess = maCenter.maBitmap.GetBitmap().AcquireReadAccess();
103     if (pReadAccess == NULL)
104         return;
105     const Color aSourceColor = pReadAccess->GetColor(0,0);
106     maCenter.maBitmap.GetBitmap().ReleaseAccess(pReadAccess);
107 
108     // Erase the center bitmap.
109     if (bEraseCenter)
110         maCenter.maBitmap.SetEmpty();
111 
112     // Replace the color in all bitmaps.
113     maTopLeft.maBitmap.Replace(aSourceColor, aNewColor, 0);
114     maTop.maBitmap.Replace(aSourceColor, aNewColor, 0);
115     maTopRight.maBitmap.Replace(aSourceColor, aNewColor, 0);
116     maLeft.maBitmap.Replace(aSourceColor, aNewColor, 0);
117     maCenter.maBitmap.Replace(aSourceColor, aNewColor, 0);
118     maRight.maBitmap.Replace(aSourceColor, aNewColor, 0);
119     maBottomLeft.maBitmap.Replace(aSourceColor, aNewColor, 0);
120     maBottom.maBitmap.Replace(aSourceColor, aNewColor, 0);
121     maBottomRight.maBitmap.Replace(aSourceColor, aNewColor, 0);
122 }
123 
124 
125 
126 
127 //===== FramePainter::OffsetBitmap ============================================
128 
129 FramePainter::OffsetBitmap::OffsetBitmap (
130     const BitmapEx& rBitmap,
131     const sal_Int32 nHorizontalPosition,
132     const sal_Int32 nVerticalPosition)
133     : maBitmap(),
134       maOffset()
135 {
136     OSL_ASSERT(nHorizontalPosition>=-1 && nHorizontalPosition<=+1);
137     OSL_ASSERT(nVerticalPosition>=-1 && nVerticalPosition<=+1);
138 
139     const sal_Int32 nS (1);
140     const sal_Int32 nC (::std::max<sal_Int32>(0,(rBitmap.GetSizePixel().Width()-nS)/2));
141     const sal_Int32 nO (nC/2);
142 
143     const Point aOrigin(
144         nHorizontalPosition<0 ? 0 : (nHorizontalPosition == 0 ? nC : nC+nS),
145         nVerticalPosition<0 ? 0 : (nVerticalPosition == 0 ? nC : nC+nS));
146     const Size aSize(
147         nHorizontalPosition==0 ? nS : nC,
148         nVerticalPosition==0 ? nS : nC);
149     maBitmap = BitmapEx(rBitmap, aOrigin, aSize);
150     if (maBitmap.IsEmpty())
151         return;
152     maOffset = Point(
153         nHorizontalPosition<0 ? -nO : nHorizontalPosition>0 ? -nO : 0,
154         nVerticalPosition<0 ? -nO : nVerticalPosition>0 ? -nO : 0);
155 
156     // Enlarge the side bitmaps so that painting the frame requires less
157     // paint calls.
158     const sal_Int32 nSideBitmapSize (64);
159     if (nHorizontalPosition == 0 && nVerticalPosition == 0)
160     {
161         maBitmap.Scale(Size(nSideBitmapSize,nSideBitmapSize), BMP_SCALE_FAST);
162     }
163     else if (nHorizontalPosition == 0)
164     {
165         maBitmap.Scale(Size(nSideBitmapSize,aSize.Height()), BMP_SCALE_FAST);
166     }
167     else if (nVerticalPosition == 0)
168     {
169         maBitmap.Scale(Size(maBitmap.GetSizePixel().Width(), nSideBitmapSize), BMP_SCALE_FAST);
170     }
171 }
172 
173 
174 
175 
176 void FramePainter::OffsetBitmap::PaintCorner (
177     OutputDevice& rDevice,
178     const Point& rAnchor) const
179 {
180     if ( ! maBitmap.IsEmpty())
181         rDevice.DrawBitmapEx(rAnchor+maOffset, maBitmap);
182 }
183 
184 
185 
186 
187 void FramePainter::OffsetBitmap::PaintSide (
188     OutputDevice& rDevice,
189     const Point& rAnchor1,
190     const Point& rAnchor2,
191     const OffsetBitmap& rCornerBitmap1,
192     const OffsetBitmap& rCornerBitmap2) const
193 {
194     if (maBitmap.IsEmpty())
195         return;
196 
197     const Size aBitmapSize (maBitmap.GetSizePixel());
198     if (rAnchor1.Y() == rAnchor2.Y())
199     {
200         // Side is horizontal.
201         const sal_Int32 nY (rAnchor1.Y() + maOffset.Y());
202         const sal_Int32 nLeft (
203             rAnchor1.X()
204             + rCornerBitmap1.maBitmap.GetSizePixel().Width()
205             + rCornerBitmap1.maOffset.X());
206         const sal_Int32 nRight (
207             rAnchor2.X()
208             + rCornerBitmap2.maOffset.X()\
209             - 1);
210         for (sal_Int32 nX=nLeft; nX<=nRight; nX+=aBitmapSize.Width())
211         {
212             rDevice.DrawBitmapEx(
213                 Point(nX,nY),
214                 Size(std::min(aBitmapSize.Width(),static_cast<long>(nRight-nX+1)),aBitmapSize.Height()),
215                 maBitmap);
216         }
217     }
218     else if (rAnchor1.X() == rAnchor2.X())
219     {
220         // Side is vertical.
221         const sal_Int32 nX (rAnchor1.X() + maOffset.X());
222         const sal_Int32 nTop (
223             rAnchor1.Y()
224             + rCornerBitmap1.maBitmap.GetSizePixel().Height()
225             + rCornerBitmap1.maOffset.Y());
226         const sal_Int32 nBottom (
227             rAnchor2.Y()
228             + rCornerBitmap2.maOffset.Y()
229             - 1);
230         for (sal_Int32 nY=nTop; nY<=nBottom; nY+=aBitmapSize.Height())
231         {
232             rDevice.DrawBitmapEx(
233                 Point(nX,nY),
234                 Size(aBitmapSize.Width(), std::min(aBitmapSize.Height(), static_cast<long>(nBottom-nY+1))),
235                 maBitmap);
236         }
237     }
238     else
239     {
240         // Diagonal sides indicatee an error.
241         OSL_ASSERT(false);
242     }
243 }
244 
245 
246 
247 
248 void FramePainter::OffsetBitmap::PaintCenter (
249     OutputDevice& rDevice,
250     const Rectangle& rBox) const
251 {
252     const Size aBitmapSize (maBitmap.GetSizePixel());
253     for (sal_Int32 nY=rBox.Top(); nY<=rBox.Bottom(); nY+=aBitmapSize.Height())
254         for (sal_Int32 nX=rBox.Left(); nX<=rBox.Right(); nX+=aBitmapSize.Width())
255             rDevice.DrawBitmapEx(
256                 Point(nX,nY),
257                 Size(
258                     ::std::min(aBitmapSize.Width(), rBox.Right()-nX+1),
259                     std::min(aBitmapSize.Height(), rBox.Bottom()-nY+1)),
260                 maBitmap);
261 }
262 
263 
264 
265 } } } // end of namespace sd::slidesorter::view
266