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