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