xref: /AOO42X/main/vcl/source/gdi/bmpacc3.cxx (revision cdf0e10c4e3984b49a9502b011690b615761d4a3)
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