xref: /aoo42x/main/vcl/source/gdi/bmpacc3.cxx (revision 9f62ea84)
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_vcl.hxx"
26 
27 #include <tools/poly.hxx>
28 
29 #include <vcl/salbtype.hxx>
30 #include <vcl/bitmap.hxx>
31 #include <vcl/region.hxx>
32 #include <vcl/bmpacc.hxx>
33 
34 #include <bmpfast.hxx>
35 
36 // ---------------------
37 // - BitmapWriteAccess -
38 // ---------------------
39 
40 void BitmapWriteAccess::SetLineColor()
41 {
42 	delete mpLineColor;
43 	mpLineColor = NULL;
44 }
45 
46 // ------------------------------------------------------------------
47 
48 void BitmapWriteAccess::SetLineColor( const Color& rColor )
49 {
50 	delete mpLineColor;
51 
52 	if( rColor.GetTransparency() == 255 )
53 		mpLineColor = NULL;
54 	else
55 		mpLineColor = ( HasPalette() ? new BitmapColor(  (sal_uInt8) GetBestPaletteIndex( rColor ) ) : new BitmapColor( rColor ) );
56 }
57 
58 // ------------------------------------------------------------------
59 
60 Color BitmapWriteAccess::GetLineColor() const
61 {
62 	Color aRet;
63 
64 	if( mpLineColor )
65 		aRet = (const Color&) *mpLineColor;
66 	else
67 		aRet.SetTransparency( 255 );
68 
69 	return aRet;
70 }
71 
72 // ------------------------------------------------------------------
73 
74 void BitmapWriteAccess::SetFillColor()
75 {
76 	delete mpFillColor;
77 	mpFillColor = NULL;
78 }
79 
80 // ------------------------------------------------------------------
81 
82 void BitmapWriteAccess::SetFillColor( const Color& rColor )
83 {
84 	delete mpFillColor;
85 
86 	if( rColor.GetTransparency() == 255 )
87 		mpFillColor = NULL;
88 	else
89 		mpFillColor = ( HasPalette() ? new BitmapColor(  (sal_uInt8) GetBestPaletteIndex( rColor ) ) : new BitmapColor( rColor ) );
90 }
91 
92 // ------------------------------------------------------------------
93 
94 Color BitmapWriteAccess::GetFillColor() const
95 {
96 	Color aRet;
97 
98 	if( mpFillColor )
99 		aRet = (const Color&) *mpFillColor;
100 	else
101 		aRet.SetTransparency( 255 );
102 
103 	return aRet;
104 }
105 
106 // ------------------------------------------------------------------
107 
108 void BitmapWriteAccess::Erase( const Color& rColor )
109 {
110     // convert the color format from RGB to palette index if needed
111     // TODO: provide and use Erase( BitmapColor& method)
112     BitmapColor aColor = rColor;
113     if( HasPalette() )
114         aColor = BitmapColor( (sal_uInt8)GetBestPaletteIndex( rColor) );
115     // try fast bitmap method first
116     if( ImplFastEraseBitmap( *mpBuffer, aColor ) )
117         return;
118 
119     // use the canonical method to clear the bitmap
120 	BitmapColor*	pOldFillColor = mpFillColor ? new BitmapColor( *mpFillColor ) : NULL;
121 	const Point		aPoint;
122 	const Rectangle	aRect( aPoint, maBitmap.GetSizePixel() );
123 
124 	SetFillColor( rColor );
125 	FillRect( aRect );
126 	delete mpFillColor;
127 	mpFillColor = pOldFillColor;
128 }
129 
130 // ------------------------------------------------------------------
131 
132 void BitmapWriteAccess::DrawLine( const Point& rStart, const Point& rEnd )
133 {
134 	if( mpLineColor )
135 	{
136 		const BitmapColor&	rLineColor = *mpLineColor;
137 		long 				nX, nY;
138 
139 		if ( rStart.X() == rEnd.X() )
140 		{
141 			// vertikale Line
142 			const long nEndY = rEnd.Y();
143 
144 			nX = rStart.X();
145 			nY = rStart.Y();
146 
147 			if ( nEndY > nY )
148 			{
149 				for (; nY <= nEndY; nY++ )
150 					SetPixel( nY, nX, rLineColor );
151 			}
152 			else
153 			{
154 				for (; nY >= nEndY; nY-- )
155 					SetPixel( nY, nX, rLineColor );
156 			}
157 		}
158 		else if ( rStart.Y() == rEnd.Y() )
159 		{
160 			// horizontale Line
161 			const long nEndX = rEnd.X();
162 
163 			nX = rStart.X();
164 			nY = rStart.Y();
165 
166 			if ( nEndX > nX )
167 			{
168 				for (; nX <= nEndX; nX++ )
169 					SetPixel( nY, nX, rLineColor );
170 			}
171 			else
172 			{
173 				for (; nX >= nEndX; nX-- )
174 					SetPixel( nY, nX, rLineColor );
175 			}
176 		}
177 		else
178 		{
179 			const long	nDX = labs( rEnd.X() - rStart.X() );
180 			const long	nDY = labs( rEnd.Y() - rStart.Y() );
181 			long		nX1;
182 			long		nY1;
183 			long		nX2;
184 			long		nY2;
185 
186 			if ( nDX >= nDY )
187 			{
188 				if ( rStart.X() < rEnd.X() )
189 				{
190 					nX1 = rStart.X();
191 					nY1 = rStart.Y();
192 					nX2 = rEnd.X();
193 					nY2 = rEnd.Y();
194 				}
195 				else
196 				{
197 					nX1 = rEnd.X();
198 					nY1 = rEnd.Y();
199 					nX2 = rStart.X();
200 					nY2 = rStart.Y();
201 				}
202 
203 				const long	nDYX = ( nDY - nDX ) << 1;
204 				const long	nDY2 = nDY << 1;
205 				long		nD = nDY2 - nDX;
206 				sal_Bool		bPos = nY1 < nY2;
207 
208 				for ( nX = nX1, nY = nY1; nX <= nX2; nX++ )
209 				{
210 					SetPixel( nY, nX, rLineColor );
211 
212 					if ( nD < 0 )
213 						nD += nDY2;
214 					else
215 					{
216 						nD += nDYX;
217 
218 						if ( bPos )
219 							nY++;
220 						else
221 							nY--;
222 					}
223 				}
224 			}
225 			else
226 			{
227 				if ( rStart.Y() < rEnd.Y() )
228 				{
229 					nX1 = rStart.X();
230 					nY1 = rStart.Y();
231 					nX2 = rEnd.X();
232 					nY2 = rEnd.Y();
233 				}
234 				else
235 				{
236 					nX1 = rEnd.X();
237 					nY1 = rEnd.Y();
238 					nX2 = rStart.X();
239 					nY2 = rStart.Y();
240 				}
241 
242 				const long	nDYX = ( nDX - nDY ) << 1;
243 				const long	nDY2 = nDX << 1;
244 				long		nD = nDY2 - nDY;
245 				sal_Bool		bPos = nX1 < nX2;
246 
247 				for ( nX = nX1, nY = nY1; nY <= nY2; nY++ )
248 				{
249 					SetPixel( nY, nX, rLineColor );
250 
251 					if ( nD < 0 )
252 						nD += nDY2;
253 					else
254 					{
255 						nD += nDYX;
256 
257 						if ( bPos )
258 							nX++;
259 						else
260 							nX--;
261 					}
262 				}
263 			}
264 		}
265 	}
266 }
267 
268 // ------------------------------------------------------------------
269 
270 void BitmapWriteAccess::FillRect( const Rectangle& rRect )
271 {
272 	if( mpFillColor )
273 	{
274 		const BitmapColor&	rFillColor = *mpFillColor;
275 		Point 				aPoint;
276 		Rectangle			aRect( aPoint, maBitmap.GetSizePixel() );
277 
278 		aRect.Intersection( rRect );
279 
280 		if( !aRect.IsEmpty() )
281 		{
282 			const long	nStartX = rRect.Left();
283 			const long	nStartY = rRect.Top();
284 			const long	nEndX = rRect.Right();
285 			const long	nEndY = rRect.Bottom();
286 
287 			for( long nY = nStartY; nY <= nEndY; nY++ )
288 				for( long nX = nStartX; nX <= nEndX; nX++ )
289 					SetPixel( nY, nX, rFillColor );
290 		}
291 	}
292 }
293 
294 // ------------------------------------------------------------------
295 
296 void BitmapWriteAccess::DrawRect( const Rectangle& rRect )
297 {
298 	if( mpFillColor )
299 		FillRect( rRect );
300 
301 	if( mpLineColor && ( !mpFillColor || ( *mpFillColor != *mpLineColor ) ) )
302 	{
303 		DrawLine( rRect.TopLeft(), rRect.TopRight() );
304 		DrawLine( rRect.TopRight(), rRect.BottomRight() );
305 		DrawLine( rRect.BottomRight(), rRect.BottomLeft() );
306 		DrawLine( rRect.BottomLeft(), rRect.TopLeft() );
307 	}
308 }
309 
310 // ------------------------------------------------------------------
311 
312 void BitmapWriteAccess::FillPolygon( const Polygon& rPoly )
313 {
314 	const sal_uInt16 nSize = rPoly.GetSize();
315 
316 	if( nSize && mpFillColor )
317 	{
318 		const BitmapColor&	rFillColor = *mpFillColor;
319 		Region				aRegion( rPoly );
320 		Rectangle			aRect;
321 
322 		aRegion.Intersect( Rectangle( Point(), Size( Width(), Height() ) ) );
323 
324 		if( !aRegion.IsEmpty() )
325 		{
326 			RegionHandle aRegHandle( aRegion.BeginEnumRects() );
327 
328 			while( aRegion.GetNextEnumRect( aRegHandle, aRect ) )
329 				for( long nY = aRect.Top(), nEndY = aRect.Bottom(); nY <= nEndY; nY++ )
330 					for( long nX = aRect.Left(), nEndX = aRect.Right(); nX <= nEndX; nX++ )
331 						SetPixel( nY, nX, rFillColor );
332 
333 			aRegion.EndEnumRects( aRegHandle );
334 		}
335 	}
336 }
337 
338 // ------------------------------------------------------------------
339 
340 void BitmapWriteAccess::DrawPolygon( const Polygon& rPoly )
341 {
342 	if( mpFillColor )
343 		FillPolygon( rPoly );
344 
345 	if( mpLineColor && ( !mpFillColor || ( *mpFillColor != *mpLineColor ) ) )
346 	{
347 		const sal_uInt16 nSize = rPoly.GetSize();
348 
349 		for( sal_uInt16 i = 0, nSize1 = nSize - 1; i < nSize1; i++ )
350 			DrawLine( rPoly[ i ], rPoly[ i + 1 ] );
351 
352 		if( rPoly[ nSize - 1 ] != rPoly[ 0 ] )
353 			DrawLine( rPoly[ nSize - 1 ], rPoly[ 0 ] );
354 	}
355 }
356 
357 // ------------------------------------------------------------------
358 
359 void BitmapWriteAccess::FillPolyPolygon( const PolyPolygon& rPolyPoly )
360 {
361 	const sal_uInt16 nCount = rPolyPoly.Count();
362 
363 	if( nCount && mpFillColor )
364 	{
365 		const BitmapColor&	rFillColor = *mpFillColor;
366 		Region				aRegion( rPolyPoly );
367 		Rectangle			aRect;
368 
369 		aRegion.Intersect( Rectangle( Point(), Size( Width(), Height() ) ) );
370 
371 		if( !aRegion.IsEmpty() )
372 		{
373 			RegionHandle aRegHandle( aRegion.BeginEnumRects() );
374 
375 			while( aRegion.GetNextEnumRect( aRegHandle, aRect ) )
376 				for( long nY = aRect.Top(), nEndY = aRect.Bottom(); nY <= nEndY; nY++ )
377 					for( long nX = aRect.Left(), nEndX = aRect.Right(); nX <= nEndX; nX++ )
378 						SetPixel( nY, nX, rFillColor );
379 
380 			aRegion.EndEnumRects( aRegHandle );
381 		}
382 	}
383 }
384 
385 // ------------------------------------------------------------------
386 
387 void BitmapWriteAccess::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
388 {
389 	if( mpFillColor )
390 		FillPolyPolygon( rPolyPoly );
391 
392 	if( mpLineColor && ( !mpFillColor || ( *mpFillColor != *mpLineColor ) ) )
393 	{
394 		for( sal_uInt16 n = 0, nCount = rPolyPoly.Count(); n < nCount; )
395 		{
396 			const Polygon&	rPoly = rPolyPoly[ n++ ];
397 			const sal_uInt16	nSize = rPoly.GetSize();
398 
399 			if( nSize )
400 			{
401 				for( sal_uInt16 i = 0, nSize1 = nSize - 1; i < nSize1; i++ )
402 					DrawLine( rPoly[ i ], rPoly[ i + 1 ] );
403 
404 				if( rPoly[ nSize - 1 ] != rPoly[ 0 ] )
405 					DrawLine( rPoly[ nSize - 1 ], rPoly[ 0 ] );
406 			}
407 		}
408 	}
409 }
410