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