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