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