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