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_canvas.hxx" 30 31 #include "dx_surfacebitmap.hxx" 32 #include "dx_impltools.hxx" 33 #include "dx_surfacegraphics.hxx" 34 #include "dx_graphicsprovider.hxx" 35 36 #include <canvas/debug.hxx> 37 #include <tools/diagnose_ex.h> 38 39 #include <basegfx/matrix/b2dhommatrix.hxx> 40 #include <basegfx/range/b2irange.hxx> 41 42 #if defined(DX_DEBUG_IMAGES) 43 # if OSL_DEBUG_LEVEL > 0 44 # include <imdebug.h> 45 # undef min 46 # undef max 47 # endif 48 #endif 49 50 using namespace ::com::sun::star; 51 52 namespace dxcanvas 53 { 54 namespace 55 { 56 ////////////////////////////////////////////////////////////////////////////////// 57 // DXColorBuffer 58 ////////////////////////////////////////////////////////////////////////////////// 59 60 struct DXColorBuffer : public canvas::IColorBuffer 61 { 62 public: 63 DXColorBuffer( const COMReference<surface_type>& rSurface, 64 const ::basegfx::B2IVector& rSize ) : 65 mpSurface(rSurface), 66 maSize(rSize), 67 mbAlpha(false) 68 { 69 } 70 71 // implementation of the 'IColorBuffer' interface 72 public: 73 74 virtual sal_uInt8* lock() const; 75 virtual void unlock() const; 76 virtual sal_uInt32 getWidth() const; 77 virtual sal_uInt32 getHeight() const; 78 virtual sal_uInt32 getStride() const; 79 virtual Format getFormat() const; 80 81 private: 82 83 ::basegfx::B2IVector maSize; 84 #if DIRECTX_VERSION < 0x0900 85 mutable DDSURFACEDESC aSurfaceDesc; 86 #else 87 mutable D3DLOCKED_RECT maLockedRect; 88 #endif 89 mutable COMReference<surface_type> mpSurface; 90 bool mbAlpha; 91 }; 92 93 sal_uInt8* DXColorBuffer::lock() const 94 { 95 #if DIRECTX_VERSION < 0x0900 96 rtl_fillMemory((void *)&aSurfaceDesc,sizeof(DDSURFACEDESC),0); 97 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); 98 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY; 99 if(SUCCEEDED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL))) 100 return static_cast<sal_uInt8 *>(aSurfaceDesc.lpSurface); 101 #else 102 if(SUCCEEDED(mpSurface->LockRect(&maLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY))) 103 return static_cast<sal_uInt8 *>(maLockedRect.pBits); 104 #endif 105 return NULL; 106 } 107 108 void DXColorBuffer::unlock() const 109 { 110 #if DIRECTX_VERSION < 0x0900 111 mpSurface->Unlock(NULL); 112 #else 113 mpSurface->UnlockRect(); 114 #endif 115 } 116 117 sal_uInt32 DXColorBuffer::getWidth() const 118 { 119 return maSize.getX(); 120 } 121 122 sal_uInt32 DXColorBuffer::getHeight() const 123 { 124 return maSize.getY(); 125 } 126 127 sal_uInt32 DXColorBuffer::getStride() const 128 { 129 #if DIRECTX_VERSION < 0x0900 130 return aSurfaceDesc.lPitch; 131 #else 132 return maLockedRect.Pitch; 133 #endif 134 } 135 136 canvas::IColorBuffer::Format DXColorBuffer::getFormat() const 137 { 138 return canvas::IColorBuffer::FMT_X8R8G8B8; 139 } 140 141 ////////////////////////////////////////////////////////////////////////////////// 142 // GDIColorBuffer 143 ////////////////////////////////////////////////////////////////////////////////// 144 145 struct GDIColorBuffer : public canvas::IColorBuffer 146 { 147 public: 148 149 GDIColorBuffer( const BitmapSharedPtr& rSurface, 150 const ::basegfx::B2IVector& rSize ) : 151 mpGDIPlusBitmap(rSurface), 152 maSize(rSize), 153 mbAlpha(true) 154 { 155 } 156 157 // implementation of the 'IColorBuffer' interface 158 public: 159 160 virtual sal_uInt8* lock() const; 161 virtual void unlock() const; 162 virtual sal_uInt32 getWidth() const; 163 virtual sal_uInt32 getHeight() const; 164 virtual sal_uInt32 getStride() const; 165 virtual Format getFormat() const; 166 167 private: 168 169 ::basegfx::B2IVector maSize; 170 mutable Gdiplus::BitmapData aBmpData; 171 BitmapSharedPtr mpGDIPlusBitmap; 172 bool mbAlpha; 173 }; 174 175 sal_uInt8* GDIColorBuffer::lock() const 176 { 177 aBmpData.Width = maSize.getX(); 178 aBmpData.Height = maSize.getY(); 179 aBmpData.Stride = 4*aBmpData.Width; 180 aBmpData.PixelFormat = PixelFormat32bppARGB; 181 aBmpData.Scan0 = NULL; 182 const Gdiplus::Rect aRect( 0,0,aBmpData.Width,aBmpData.Height ); 183 if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect, 184 Gdiplus::ImageLockModeRead, 185 PixelFormat32bppARGB, 186 &aBmpData ) ) 187 { 188 return NULL; 189 } 190 191 return static_cast<sal_uInt8*>(aBmpData.Scan0); 192 } 193 194 void GDIColorBuffer::unlock() const 195 { 196 mpGDIPlusBitmap->UnlockBits( &aBmpData ); 197 } 198 199 sal_uInt32 GDIColorBuffer::getWidth() const 200 { 201 return maSize.getX(); 202 } 203 204 sal_uInt32 GDIColorBuffer::getHeight() const 205 { 206 return maSize.getY(); 207 } 208 209 sal_uInt32 GDIColorBuffer::getStride() const 210 { 211 return aBmpData.Stride; 212 } 213 214 canvas::IColorBuffer::Format GDIColorBuffer::getFormat() const 215 { 216 return canvas::IColorBuffer::FMT_A8R8G8B8; 217 } 218 } 219 220 ////////////////////////////////////////////////////////////////////////////////// 221 // DXSurfaceBitmap::DXSurfaceBitmap 222 ////////////////////////////////////////////////////////////////////////////////// 223 224 DXSurfaceBitmap::DXSurfaceBitmap( const ::basegfx::B2IVector& rSize, 225 const canvas::ISurfaceProxyManagerSharedPtr& rMgr, 226 const IDXRenderModuleSharedPtr& rRenderModule, 227 bool bWithAlpha ) : 228 mpGdiPlusUser( GDIPlusUser::createInstance() ), 229 maSize(rSize), 230 mpRenderModule(rRenderModule), 231 mpSurfaceManager(rMgr), 232 mpSurfaceProxy(), 233 mpSurface(), 234 mpGDIPlusBitmap(), 235 mpGraphics(), 236 mpColorBuffer(), 237 mbIsSurfaceDirty(true), 238 mbAlpha(bWithAlpha) 239 { 240 init(); 241 } 242 243 ////////////////////////////////////////////////////////////////////////////////// 244 // DXSurfaceBitmap::getSize 245 ////////////////////////////////////////////////////////////////////////////////// 246 247 ::basegfx::B2IVector DXSurfaceBitmap::getSize() const 248 { 249 return maSize; 250 } 251 252 ////////////////////////////////////////////////////////////////////////////////// 253 // DXSurfaceBitmap::init 254 ////////////////////////////////////////////////////////////////////////////////// 255 256 void DXSurfaceBitmap::init() 257 { 258 // create container for pixel data 259 if(mbAlpha) 260 { 261 mpGDIPlusBitmap.reset( 262 new Gdiplus::Bitmap( 263 maSize.getX(), 264 maSize.getY(), 265 PixelFormat32bppARGB 266 )); 267 mpGraphics.reset( tools::createGraphicsFromBitmap(mpGDIPlusBitmap) ); 268 269 // create the colorbuffer object, which is basically a simple 270 // wrapper around the directx surface. the colorbuffer is the 271 // interface which is used by the surfaceproxy to support any 272 // kind of underlying structure for the pixel data container. 273 mpColorBuffer.reset(new GDIColorBuffer(mpGDIPlusBitmap,maSize)); 274 } 275 else 276 { 277 mpSurface = mpRenderModule->createSystemMemorySurface(maSize); 278 279 // create the colorbuffer object, which is basically a simple 280 // wrapper around the directx surface. the colorbuffer is the 281 // interface which is used by the surfaceproxy to support any 282 // kind of underlying structure for the pixel data container. 283 mpColorBuffer.reset(new DXColorBuffer(mpSurface,maSize)); 284 } 285 286 // create a (possibly hardware accelerated) mirror surface. 287 mpSurfaceProxy = mpSurfaceManager->createSurfaceProxy(mpColorBuffer); 288 } 289 290 ////////////////////////////////////////////////////////////////////////////////// 291 // DXSurfaceBitmap::resize 292 ////////////////////////////////////////////////////////////////////////////////// 293 294 bool DXSurfaceBitmap::resize( const ::basegfx::B2IVector& rSize ) 295 { 296 if(maSize != rSize) 297 { 298 maSize = rSize; 299 init(); 300 } 301 302 return true; 303 } 304 305 ////////////////////////////////////////////////////////////////////////////////// 306 // DXSurfaceBitmap::clear 307 ////////////////////////////////////////////////////////////////////////////////// 308 309 void DXSurfaceBitmap::clear() 310 { 311 GraphicsSharedPtr pGraphics(getGraphics()); 312 Gdiplus::Color transColor(255,0,0,0); 313 pGraphics->SetCompositingMode( Gdiplus::CompositingModeSourceCopy ); 314 pGraphics->Clear( transColor ); 315 } 316 317 ////////////////////////////////////////////////////////////////////////////////// 318 // DXSurfaceBitmap::hasAlpha 319 ////////////////////////////////////////////////////////////////////////////////// 320 321 bool DXSurfaceBitmap::hasAlpha() const 322 { 323 return mbAlpha; 324 } 325 326 ////////////////////////////////////////////////////////////////////////////////// 327 // DXSurfaceBitmap::getGraphics 328 ////////////////////////////////////////////////////////////////////////////////// 329 330 GraphicsSharedPtr DXSurfaceBitmap::getGraphics() 331 { 332 // since clients will most probably draw directly 333 // to the GDI+ bitmap, we need to mark it as dirty 334 // to ensure that the corrosponding dxsurface will 335 // be updated. 336 mbIsSurfaceDirty = true; 337 338 if(hasAlpha()) 339 return mpGraphics; 340 else 341 return createSurfaceGraphics(mpSurface); 342 } 343 344 ////////////////////////////////////////////////////////////////////////////////// 345 // DXSurfaceBitmap::getBitmap 346 ////////////////////////////////////////////////////////////////////////////////// 347 348 BitmapSharedPtr DXSurfaceBitmap::getBitmap() const 349 { 350 if(hasAlpha()) 351 return mpGDIPlusBitmap; 352 353 BitmapSharedPtr pResult; 354 355 #if DIRECTX_VERSION < 0x0900 356 DDSURFACEDESC aSurfaceDesc; 357 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0); 358 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); 359 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY; 360 361 // lock the directx surface to receive the pointer to the surface memory. 362 if(SUCCEEDED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL))) 363 { 364 // decide about the format we pass the gdi+, the directx surface is always 365 // 32bit, either with or without alpha component. 366 Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB; 367 368 // construct a gdi+ bitmap from the raw pixel data. 369 pResult.reset(new Gdiplus::Bitmap( maSize.getX(),maSize.getY(), 370 aSurfaceDesc.lPitch, 371 nFormat, 372 (BYTE *)aSurfaceDesc.lpSurface )); 373 374 // unlock the directx surface 375 mpSurface->Unlock(NULL); 376 } 377 #else 378 D3DLOCKED_RECT aLockedRect; 379 if(SUCCEEDED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY))) 380 { 381 // decide about the format we pass the gdi+, the directx surface is always 382 // 32bit, either with or without alpha component. 383 Gdiplus::PixelFormat nFormat = hasAlpha() ? PixelFormat32bppARGB : PixelFormat32bppRGB; 384 385 // construct a gdi+ bitmap from the raw pixel data. 386 pResult.reset(new Gdiplus::Bitmap( maSize.getX(),maSize.getY(), 387 aLockedRect.Pitch, 388 nFormat, 389 (BYTE *)aLockedRect.pBits )); 390 391 mpSurface->UnlockRect(); 392 } 393 #endif 394 395 return pResult; 396 } 397 398 ////////////////////////////////////////////////////////////////////////////////// 399 // DXSurfaceBitmap::draw 400 ////////////////////////////////////////////////////////////////////////////////// 401 402 bool DXSurfaceBitmap::draw( double fAlpha, 403 const ::basegfx::B2DPoint& rPos, 404 const ::basegfx::B2DPolyPolygon& rClipPoly, 405 const ::basegfx::B2DHomMatrix& rTransform ) 406 { 407 if( mbIsSurfaceDirty ) 408 { 409 mpSurfaceProxy->setColorBufferDirty(); 410 mbIsSurfaceDirty = false; 411 } 412 413 return mpSurfaceProxy->draw( fAlpha, rPos, rClipPoly, rTransform ); 414 } 415 416 ////////////////////////////////////////////////////////////////////////////////// 417 // DXSurfaceBitmap::draw 418 ////////////////////////////////////////////////////////////////////////////////// 419 420 bool DXSurfaceBitmap::draw( double fAlpha, 421 const ::basegfx::B2DPoint& rPos, 422 const ::basegfx::B2DRange& rArea, 423 const ::basegfx::B2DHomMatrix& rTransform ) 424 { 425 if( mbIsSurfaceDirty ) 426 { 427 mpSurfaceProxy->setColorBufferDirty(); 428 mbIsSurfaceDirty = false; 429 } 430 431 return mpSurfaceProxy->draw( fAlpha, rPos, rArea, rTransform ); 432 } 433 434 ////////////////////////////////////////////////////////////////////////////////// 435 // DXSurfaceBitmap::draw 436 ////////////////////////////////////////////////////////////////////////////////// 437 438 bool DXSurfaceBitmap::draw( double fAlpha, 439 const ::basegfx::B2DPoint& rPos, 440 const ::basegfx::B2DHomMatrix& rTransform ) 441 { 442 if( mbIsSurfaceDirty ) 443 { 444 mpSurfaceProxy->setColorBufferDirty(); 445 mbIsSurfaceDirty = false; 446 } 447 448 return mpSurfaceProxy->draw( fAlpha, rPos, rTransform ); 449 } 450 451 ////////////////////////////////////////////////////////////////////////////////// 452 // DXSurfaceBitmap::draw 453 ////////////////////////////////////////////////////////////////////////////////// 454 455 bool DXSurfaceBitmap::draw( const ::basegfx::B2IRange& rArea ) 456 { 457 if( mbIsSurfaceDirty ) 458 { 459 mpSurfaceProxy->setColorBufferDirty(); 460 mbIsSurfaceDirty = false; 461 } 462 463 const double fAlpha(1.0); 464 const ::basegfx::B2DHomMatrix aTransform; 465 const ::basegfx::B2DRange aIEEEArea( rArea ); 466 return mpSurfaceProxy->draw(fAlpha, 467 ::basegfx::B2DPoint(), 468 aIEEEArea, 469 aTransform); 470 } 471 472 ////////////////////////////////////////////////////////////////////////////////// 473 // DXSurfaceBitmap::imageDebugger 474 ////////////////////////////////////////////////////////////////////////////////// 475 #if defined(DX_DEBUG_IMAGES) 476 # if OSL_DEBUG_LEVEL > 0 477 void DXSurfaceBitmap::imageDebugger() 478 { 479 #if DIRECTX_VERSION < 0x0900 480 DDSURFACEDESC aSurfaceDesc; 481 rtl_fillMemory( &aSurfaceDesc,sizeof(DDSURFACEDESC),0 ); 482 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); 483 484 if( FAILED(mpSurface->Lock( NULL, 485 &aSurfaceDesc, 486 DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY, 487 NULL)) ) 488 return; 489 490 imdebug("bgra w=%d h=%d %p", aSurfaceDesc.dwWidth, aSurfaceDesc.dwHeight, aSurfaceDesc.lpSurface); 491 492 mpSurface->Unlock(NULL); 493 #else 494 D3DLOCKED_RECT aLockedRect; 495 if( FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY)) ) 496 return; 497 498 imdebug("bgra w=%d h=%d %p", maSize.getX(), 499 maSize.getY(), aLockedRect.pBits); 500 mpSurface->UnlockRect(); 501 #endif 502 } 503 # endif 504 #endif 505 506 ////////////////////////////////////////////////////////////////////////////////// 507 // DXSurfaceBitmap::getData 508 ////////////////////////////////////////////////////////////////////////////////// 509 510 uno::Sequence< sal_Int8 > DXSurfaceBitmap::getData( rendering::IntegerBitmapLayout& /*bitmapLayout*/, 511 const geometry::IntegerRectangle2D& rect ) 512 { 513 if(hasAlpha()) 514 { 515 uno::Sequence< sal_Int8 > aRes( (rect.X2-rect.X1)*(rect.Y2-rect.Y1)*4 ); // TODO(F1): Be format-agnostic here 516 517 const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) ); 518 519 Gdiplus::BitmapData aBmpData; 520 aBmpData.Width = rect.X2-rect.X1; 521 aBmpData.Height = rect.Y2-rect.Y1; 522 aBmpData.Stride = 4*aBmpData.Width; 523 aBmpData.PixelFormat = PixelFormat32bppARGB; 524 aBmpData.Scan0 = aRes.getArray(); 525 526 // TODO(F1): Support more pixel formats natively 527 528 // read data from bitmap 529 if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect, 530 Gdiplus::ImageLockModeRead | Gdiplus::ImageLockModeUserInputBuf, 531 PixelFormat32bppARGB, // TODO(F1): Adapt to 532 // Graphics native 533 // format/change 534 // getMemoryLayout 535 &aBmpData ) ) 536 { 537 // failed to lock, bail out 538 return uno::Sequence< sal_Int8 >(); 539 } 540 541 mpGDIPlusBitmap->UnlockBits( &aBmpData ); 542 543 return aRes; 544 } 545 else 546 { 547 sal_uInt32 nWidth = rect.X2-rect.X1; 548 sal_uInt32 nHeight = rect.Y2-rect.Y1; 549 550 uno::Sequence< sal_Int8 > aRes(nWidth*nHeight*4); 551 552 #if DIRECTX_VERSION < 0x0900 553 DDSURFACEDESC aSurfaceDesc; 554 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0); 555 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); 556 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY; 557 558 // lock the directx surface to receive the pointer to the surface memory. 559 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL))) 560 return uno::Sequence< sal_Int8 >(); 561 562 sal_uInt8 *pSrc = (sal_uInt8 *)((((BYTE *)aSurfaceDesc.lpSurface)+(rect.Y1*aSurfaceDesc.lPitch))+rect.X1); 563 sal_uInt8 *pDst = (sal_uInt8 *)aRes.getArray(); 564 sal_uInt32 nSegmentSizeInBytes = nWidth<<4; 565 for(sal_uInt32 y=0; y<nHeight; ++y) 566 { 567 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes); 568 pDst += nSegmentSizeInBytes; 569 pSrc += aSurfaceDesc.lPitch; 570 } 571 572 mpSurface->Unlock(NULL); 573 #else 574 D3DLOCKED_RECT aLockedRect; 575 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY))) 576 return uno::Sequence< sal_Int8 >(); 577 578 sal_uInt8 *pSrc = (sal_uInt8 *)((((BYTE *)aLockedRect.pBits)+(rect.Y1*aLockedRect.Pitch))+rect.X1); 579 sal_uInt8 *pDst = (sal_uInt8 *)aRes.getArray(); 580 sal_uInt32 nSegmentSizeInBytes = nWidth<<4; 581 for(sal_uInt32 y=0; y<nHeight; ++y) 582 { 583 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes); 584 pDst += nSegmentSizeInBytes; 585 pSrc += aLockedRect.Pitch; 586 } 587 588 mpSurface->UnlockRect(); 589 #endif 590 return aRes; 591 } 592 } 593 594 ////////////////////////////////////////////////////////////////////////////////// 595 // DXSurfaceBitmap::setData 596 ////////////////////////////////////////////////////////////////////////////////// 597 598 void DXSurfaceBitmap::setData( const uno::Sequence< sal_Int8 >& data, 599 const rendering::IntegerBitmapLayout& /*bitmapLayout*/, 600 const geometry::IntegerRectangle2D& rect ) 601 { 602 if(hasAlpha()) 603 { 604 const Gdiplus::Rect aRect( tools::gdiPlusRectFromIntegerRectangle2D( rect ) ); 605 606 Gdiplus::BitmapData aBmpData; 607 aBmpData.Width = rect.X2-rect.X1; 608 aBmpData.Height = rect.Y2-rect.Y1; 609 aBmpData.Stride = 4*aBmpData.Width; 610 aBmpData.PixelFormat = PixelFormat32bppARGB; 611 aBmpData.Scan0 = (void*)data.getConstArray(); 612 613 // TODO(F1): Support more pixel formats natively 614 615 if( Gdiplus::Ok != mpGDIPlusBitmap->LockBits( &aRect, 616 Gdiplus::ImageLockModeWrite | Gdiplus::ImageLockModeUserInputBuf, 617 PixelFormat32bppARGB, // TODO: Adapt to 618 // Graphics native 619 // format/change 620 // getMemoryLayout 621 &aBmpData ) ) 622 { 623 throw uno::RuntimeException(); 624 } 625 626 // commit data to bitmap 627 mpGDIPlusBitmap->UnlockBits( &aBmpData ); 628 } 629 else 630 { 631 sal_uInt32 nWidth = rect.X2-rect.X1; 632 sal_uInt32 nHeight = rect.Y2-rect.Y1; 633 634 #if DIRECTX_VERSION < 0x0900 635 DDSURFACEDESC aSurfaceDesc; 636 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0); 637 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); 638 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY; 639 640 // lock the directx surface to receive the pointer to the surface memory. 641 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL))) 642 throw uno::RuntimeException(); 643 644 sal_uInt8 *pSrc = (sal_uInt8 *)data.getConstArray(); 645 sal_uInt8 *pDst = (sal_uInt8 *)((((BYTE *)aSurfaceDesc.lpSurface)+(rect.Y1*aSurfaceDesc.lPitch))+rect.X1); 646 sal_uInt32 nSegmentSizeInBytes = nWidth<<4; 647 for(sal_uInt32 y=0; y<nHeight; ++y) 648 { 649 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes); 650 pSrc += nSegmentSizeInBytes; 651 pDst += aSurfaceDesc.lPitch; 652 } 653 654 mpSurface->Unlock(NULL); 655 #else 656 // lock the directx surface to receive the pointer to the surface memory. 657 D3DLOCKED_RECT aLockedRect; 658 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY))) 659 throw uno::RuntimeException(); 660 661 sal_uInt8 *pSrc = (sal_uInt8 *)data.getConstArray(); 662 sal_uInt8 *pDst = (sal_uInt8 *)((((BYTE *)aLockedRect.pBits)+(rect.Y1*aLockedRect.Pitch))+rect.X1); 663 sal_uInt32 nSegmentSizeInBytes = nWidth<<4; 664 for(sal_uInt32 y=0; y<nHeight; ++y) 665 { 666 rtl_copyMemory(pDst,pSrc,nSegmentSizeInBytes); 667 pSrc += nSegmentSizeInBytes; 668 pDst += aLockedRect.Pitch; 669 } 670 671 mpSurface->UnlockRect(); 672 #endif 673 } 674 675 mbIsSurfaceDirty = true; 676 } 677 678 ////////////////////////////////////////////////////////////////////////////////// 679 // DXSurfaceBitmap::setPixel 680 ////////////////////////////////////////////////////////////////////////////////// 681 682 void DXSurfaceBitmap::setPixel( const uno::Sequence< sal_Int8 >& color, 683 const rendering::IntegerBitmapLayout& /*bitmapLayout*/, 684 const geometry::IntegerPoint2D& pos ) 685 { 686 if(hasAlpha()) 687 { 688 const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() ); 689 690 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width, 691 "CanvasHelper::setPixel: X coordinate out of bounds" ); 692 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height, 693 "CanvasHelper::setPixel: Y coordinate out of bounds" ); 694 ENSURE_ARG_OR_THROW( color.getLength() > 3, 695 "CanvasHelper::setPixel: not enough color components" ); 696 697 if( Gdiplus::Ok != mpGDIPlusBitmap->SetPixel( pos.X, pos.Y, 698 Gdiplus::Color( tools::sequenceToArgb( color )))) 699 { 700 throw uno::RuntimeException(); 701 } 702 } 703 else 704 { 705 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(), 706 "CanvasHelper::setPixel: X coordinate out of bounds" ); 707 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(), 708 "CanvasHelper::setPixel: Y coordinate out of bounds" ); 709 ENSURE_ARG_OR_THROW( color.getLength() > 3, 710 "CanvasHelper::setPixel: not enough color components" ); 711 712 Gdiplus::Color aColor(tools::sequenceToArgb(color)); 713 714 #if DIRECTX_VERSION < 0x0900 715 DDSURFACEDESC aSurfaceDesc; 716 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0); 717 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); 718 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_WRITEONLY; 719 720 // lock the directx surface to receive the pointer to the surface memory. 721 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL))) 722 throw uno::RuntimeException(); 723 724 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aSurfaceDesc.lpSurface)+(pos.Y*aSurfaceDesc.lPitch))+pos.X); 725 *pDst = aColor.GetValue(); 726 mpSurface->Unlock(NULL); 727 #else 728 // lock the directx surface to receive the pointer to the surface memory. 729 D3DLOCKED_RECT aLockedRect; 730 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY))) 731 throw uno::RuntimeException(); 732 733 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aLockedRect.pBits)+(pos.Y*aLockedRect.Pitch))+pos.X); 734 *pDst = aColor.GetValue(); 735 mpSurface->UnlockRect(); 736 #endif 737 } 738 739 mbIsSurfaceDirty = true; 740 } 741 742 ////////////////////////////////////////////////////////////////////////////////// 743 // DXSurfaceBitmap::getPixel 744 ////////////////////////////////////////////////////////////////////////////////// 745 746 uno::Sequence< sal_Int8 > DXSurfaceBitmap::getPixel( rendering::IntegerBitmapLayout& /*bitmapLayout*/, 747 const geometry::IntegerPoint2D& pos ) 748 { 749 if(hasAlpha()) 750 { 751 const geometry::IntegerSize2D aSize( maSize.getX(),maSize.getY() ); 752 753 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < aSize.Width, 754 "CanvasHelper::getPixel: X coordinate out of bounds" ); 755 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < aSize.Height, 756 "CanvasHelper::getPixel: Y coordinate out of bounds" ); 757 758 Gdiplus::Color aColor; 759 760 if( Gdiplus::Ok != mpGDIPlusBitmap->GetPixel( pos.X, pos.Y, &aColor ) ) 761 return uno::Sequence< sal_Int8 >(); 762 763 return tools::argbToIntSequence(aColor.GetValue()); 764 } 765 else 766 { 767 ENSURE_ARG_OR_THROW( pos.X >= 0 && pos.X < maSize.getX(), 768 "CanvasHelper::getPixel: X coordinate out of bounds" ); 769 ENSURE_ARG_OR_THROW( pos.Y >= 0 && pos.Y < maSize.getY(), 770 "CanvasHelper::getPixel: Y coordinate out of bounds" ); 771 772 #if DIRECTX_VERSION < 0x0900 773 DDSURFACEDESC aSurfaceDesc; 774 rtl_fillMemory(&aSurfaceDesc,sizeof(DDSURFACEDESC),0); 775 aSurfaceDesc.dwSize = sizeof(DDSURFACEDESC); 776 const DWORD dwFlags = DDLOCK_NOSYSLOCK|DDLOCK_SURFACEMEMORYPTR|DDLOCK_WAIT|DDLOCK_READONLY; 777 778 // lock the directx surface to receive the pointer to the surface memory. 779 if(FAILED(mpSurface->Lock(NULL,&aSurfaceDesc,dwFlags,NULL))) 780 throw uno::RuntimeException(); 781 782 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aSurfaceDesc.lpSurface)+(pos.Y*aSurfaceDesc.lPitch))+pos.X); 783 Gdiplus::Color aColor(*pDst); 784 mpSurface->Unlock(NULL); 785 #else 786 // lock the directx surface to receive the pointer to the surface memory. 787 D3DLOCKED_RECT aLockedRect; 788 if(FAILED(mpSurface->LockRect(&aLockedRect,NULL,D3DLOCK_NOSYSLOCK|D3DLOCK_READONLY))) 789 throw uno::RuntimeException(); 790 791 sal_uInt32 *pDst = (sal_uInt32 *)((((BYTE *)aLockedRect.pBits)+(pos.Y*aLockedRect.Pitch))+pos.X); 792 Gdiplus::Color aColor(*pDst); 793 mpSurface->UnlockRect(); 794 #endif 795 796 return tools::argbToIntSequence(aColor.GetValue()); 797 } 798 } 799 800 ////////////////////////////////////////////////////////////////////////////////// 801 // End of file 802 ////////////////////////////////////////////////////////////////////////////////// 803 } 804 805