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