xref: /trunk/main/vcl/source/gdi/bmpacc3.cxx (revision e6f63103)
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 
SetLineColor()40 void BitmapWriteAccess::SetLineColor()
41 {
42 	delete mpLineColor;
43 	mpLineColor = NULL;
44 }
45 
46 // ------------------------------------------------------------------
47 
SetLineColor(const Color & rColor)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 
GetLineColor() const60 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 
SetFillColor()74 void BitmapWriteAccess::SetFillColor()
75 {
76 	delete mpFillColor;
77 	mpFillColor = NULL;
78 }
79 
80 // ------------------------------------------------------------------
81 
SetFillColor(const Color & rColor)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 
GetFillColor() const94 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 
Erase(const Color & rColor)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 
DrawLine(const Point & rStart,const Point & rEnd)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 
FillRect(const Rectangle & rRect)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 
DrawRect(const Rectangle & rRect)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 
FillPolygon(const Polygon & rPoly)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             RectangleVector aRectangles;
327             aRegion.GetRegionRectangles(aRectangles);
328 
329             for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
330             {
331                 for(long nY = aRectIter->Top(), nEndY = aRectIter->Bottom(); nY <= nEndY; nY++)
332                 {
333                     for(long nX = aRectIter->Left(), nEndX = aRectIter->Right(); nX <= nEndX; nX++)
334                     {
335                         SetPixel(nY, nX, rFillColor);
336                     }
337                 }
338             }
339 
340 			//RegionHandle aRegHandle( aRegion.BeginEnumRects() );
341             //
342 			//while( aRegion.GetEnumRects( aRegHandle, aRect ) )
343 			//	for( long nY = aRect.Top(), nEndY = aRect.Bottom(); nY <= nEndY; nY++ )
344 			//		for( long nX = aRect.Left(), nEndX = aRect.Right(); nX <= nEndX; nX++ )
345 			//			SetPixel( nY, nX, rFillColor );
346             //
347 			//aRegion.EndEnumRects( aRegHandle );
348 		}
349 	}
350 }
351 
352 // ------------------------------------------------------------------
353 
DrawPolygon(const Polygon & rPoly)354 void BitmapWriteAccess::DrawPolygon( const Polygon& rPoly )
355 {
356 	if( mpFillColor )
357 		FillPolygon( rPoly );
358 
359 	if( mpLineColor && ( !mpFillColor || ( *mpFillColor != *mpLineColor ) ) )
360 	{
361 		const sal_uInt16 nSize = rPoly.GetSize();
362 
363 		for( sal_uInt16 i = 0, nSize1 = nSize - 1; i < nSize1; i++ )
364 			DrawLine( rPoly[ i ], rPoly[ i + 1 ] );
365 
366 		if( rPoly[ nSize - 1 ] != rPoly[ 0 ] )
367 			DrawLine( rPoly[ nSize - 1 ], rPoly[ 0 ] );
368 	}
369 }
370 
371 // ------------------------------------------------------------------
372 
FillPolyPolygon(const PolyPolygon & rPolyPoly)373 void BitmapWriteAccess::FillPolyPolygon( const PolyPolygon& rPolyPoly )
374 {
375 	const sal_uInt16 nCount = rPolyPoly.Count();
376 
377 	if( nCount && mpFillColor )
378 	{
379 		const BitmapColor&	rFillColor = *mpFillColor;
380 		Region				aRegion( rPolyPoly );
381 		//Rectangle			aRect;
382 
383 		aRegion.Intersect( Rectangle( Point(), Size( Width(), Height() ) ) );
384 
385 		if( !aRegion.IsEmpty() )
386 		{
387             RectangleVector aRectangles;
388             aRegion.GetRegionRectangles(aRectangles);
389 
390             for(RectangleVector::const_iterator aRectIter(aRectangles.begin()); aRectIter != aRectangles.end(); aRectIter++)
391             {
392                 for(long nY = aRectIter->Top(), nEndY = aRectIter->Bottom(); nY <= nEndY; nY++)
393                 {
394                     for(long nX = aRectIter->Left(), nEndX = aRectIter->Right(); nX <= nEndX; nX++)
395                     {
396                         SetPixel(nY, nX, rFillColor);
397                     }
398                 }
399             }
400 
401             //RegionHandle aRegHandle( aRegion.BeginEnumRects() );
402 			//
403 			//while( aRegion.GetEnumRects( aRegHandle, aRect ) )
404 			//	for( long nY = aRect.Top(), nEndY = aRect.Bottom(); nY <= nEndY; nY++ )
405 			//		for( long nX = aRect.Left(), nEndX = aRect.Right(); nX <= nEndX; nX++ )
406 			//			SetPixel( nY, nX, rFillColor );
407             //
408 			//aRegion.EndEnumRects( aRegHandle );
409 		}
410 	}
411 }
412 
413 // ------------------------------------------------------------------
414 
DrawPolyPolygon(const PolyPolygon & rPolyPoly)415 void BitmapWriteAccess::DrawPolyPolygon( const PolyPolygon& rPolyPoly )
416 {
417 	if( mpFillColor )
418 		FillPolyPolygon( rPolyPoly );
419 
420 	if( mpLineColor && ( !mpFillColor || ( *mpFillColor != *mpLineColor ) ) )
421 	{
422 		for( sal_uInt16 n = 0, nCount = rPolyPoly.Count(); n < nCount; )
423 		{
424 			const Polygon&	rPoly = rPolyPoly[ n++ ];
425 			const sal_uInt16	nSize = rPoly.GetSize();
426 
427 			if( nSize )
428 			{
429 				for( sal_uInt16 i = 0, nSize1 = nSize - 1; i < nSize1; i++ )
430 					DrawLine( rPoly[ i ], rPoly[ i + 1 ] );
431 
432 				if( rPoly[ nSize - 1 ] != rPoly[ 0 ] )
433 					DrawLine( rPoly[ nSize - 1 ], rPoly[ 0 ] );
434 			}
435 		}
436 	}
437 }
438