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