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_toolkit.hxx" 30 31 #include <toolkit/awt/vclxgraphics.hxx> 32 #include <toolkit/awt/vclxdevice.hxx> 33 #include <toolkit/helper/macros.hxx> 34 #include <toolkit/helper/vclunohelper.hxx> 35 #include <cppuhelper/typeprovider.hxx> 36 #include <rtl/memory.h> 37 #include <rtl/uuid.h> 38 39 #include <vcl/svapp.hxx> 40 #include <vcl/outdev.hxx> 41 #include <vcl/gradient.hxx> 42 #include <tools/debug.hxx> 43 44 45 // ---------------------------------------------------- 46 // class VCLXGraphics 47 // ---------------------------------------------------- 48 49 // ::com::sun::star::uno::XInterface 50 ::com::sun::star::uno::Any VCLXGraphics::queryInterface( const ::com::sun::star::uno::Type & rType ) throw(::com::sun::star::uno::RuntimeException) 51 { 52 ::com::sun::star::uno::Any aRet = ::cppu::queryInterface( rType, 53 SAL_STATIC_CAST( ::com::sun::star::awt::XGraphics*, this ), 54 SAL_STATIC_CAST( ::com::sun::star::lang::XTypeProvider*, this ), 55 SAL_STATIC_CAST( ::com::sun::star::lang::XUnoTunnel*, this ) ); 56 return (aRet.hasValue() ? aRet : OWeakObject::queryInterface( rType )); 57 } 58 59 // ::com::sun::star::lang::XUnoTunnel 60 IMPL_XUNOTUNNEL( VCLXGraphics ) 61 62 // ::com::sun::star::lang::XTypeProvider 63 IMPL_XTYPEPROVIDER_START( VCLXGraphics ) 64 getCppuType( ( ::com::sun::star::uno::Reference< ::com::sun::star::awt::XGraphics>* ) NULL ) 65 IMPL_XTYPEPROVIDER_END 66 67 VCLXGraphics::VCLXGraphics() : mrMutex( Application::GetSolarMutex() ) 68 { 69 mpOutputDevice = NULL; 70 mpClipRegion = NULL; 71 } 72 73 VCLXGraphics::~VCLXGraphics() 74 { 75 List* pLst = mpOutputDevice ? mpOutputDevice->GetUnoGraphicsList() : NULL; 76 if ( pLst ) 77 pLst->Remove( this ); 78 79 delete mpClipRegion; 80 } 81 82 void VCLXGraphics::SetOutputDevice( OutputDevice* pOutDev ) 83 { 84 mpOutputDevice = pOutDev; 85 mxDevice = NULL; 86 } 87 88 void VCLXGraphics::Init( OutputDevice* pOutDev ) 89 { 90 DBG_ASSERT( !mpOutputDevice, "VCLXGraphics::Init allready has pOutDev !" ); 91 mpOutputDevice = pOutDev; 92 93 maFont = mpOutputDevice->GetFont(); 94 maTextColor = COL_BLACK; 95 maTextFillColor = COL_TRANSPARENT; 96 maLineColor = COL_BLACK; 97 maFillColor = COL_WHITE; 98 meRasterOp = ROP_OVERPAINT; 99 mpClipRegion = NULL; 100 101 // Register at OutputDevice 102 List* pLst = mpOutputDevice->GetUnoGraphicsList(); 103 if ( !pLst ) 104 pLst = mpOutputDevice->CreateUnoGraphicsList(); 105 pLst->Insert( this, LIST_APPEND ); 106 } 107 108 void VCLXGraphics::InitOutputDevice( sal_uInt16 nFlags ) 109 { 110 if(mpOutputDevice) 111 { 112 vos::OGuard aVclGuard( Application::GetSolarMutex() ); 113 114 if ( nFlags & INITOUTDEV_FONT ) 115 { 116 mpOutputDevice->SetFont( maFont ); 117 mpOutputDevice->SetTextColor( maTextColor ); 118 mpOutputDevice->SetTextFillColor( maTextFillColor ); 119 } 120 121 if ( nFlags & INITOUTDEV_COLORS ) 122 { 123 mpOutputDevice->SetLineColor( maLineColor ); 124 mpOutputDevice->SetFillColor( maFillColor ); 125 } 126 127 if ( nFlags & INITOUTDEV_RASTEROP ) 128 { 129 mpOutputDevice->SetRasterOp( meRasterOp ); 130 } 131 132 if ( nFlags & INITOUTDEV_CLIPREGION ) 133 { 134 if( mpClipRegion ) 135 mpOutputDevice->SetClipRegion( *mpClipRegion ); 136 else 137 mpOutputDevice->SetClipRegion(); 138 } 139 } 140 } 141 142 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice > VCLXGraphics::getDevice() throw(::com::sun::star::uno::RuntimeException) 143 { 144 ::vos::OGuard aGuard( GetMutex() ); 145 146 if( !mxDevice.is() && mpOutputDevice ) 147 { 148 VCLXDevice* pDev = new VCLXDevice; 149 pDev->SetOutputDevice( mpOutputDevice ); 150 mxDevice = pDev; 151 } 152 return mxDevice; 153 } 154 155 ::com::sun::star::awt::SimpleFontMetric VCLXGraphics::getFontMetric() throw(::com::sun::star::uno::RuntimeException) 156 { 157 ::vos::OGuard aGuard( GetMutex() ); 158 159 ::com::sun::star::awt::SimpleFontMetric aM; 160 if( mpOutputDevice ) 161 { 162 mpOutputDevice->SetFont( maFont ); 163 aM = VCLUnoHelper::CreateFontMetric( mpOutputDevice->GetFontMetric() ); 164 } 165 return aM; 166 } 167 168 void VCLXGraphics::setFont( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XFont >& rxFont ) throw(::com::sun::star::uno::RuntimeException) 169 { 170 ::vos::OGuard aGuard( GetMutex() ); 171 172 maFont = VCLUnoHelper::CreateFont( rxFont ); 173 } 174 175 void VCLXGraphics::selectFont( const ::com::sun::star::awt::FontDescriptor& rDescription ) throw(::com::sun::star::uno::RuntimeException) 176 { 177 ::vos::OGuard aGuard( GetMutex() ); 178 179 maFont = VCLUnoHelper::CreateFont( rDescription, Font() ); 180 } 181 182 void VCLXGraphics::setTextColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException) 183 { 184 ::vos::OGuard aGuard( GetMutex() ); 185 186 maTextColor = Color( (sal_uInt32)nColor ); 187 } 188 189 void VCLXGraphics::setTextFillColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException) 190 { 191 ::vos::OGuard aGuard( GetMutex() ); 192 193 maTextFillColor = Color( (sal_uInt32)nColor ); 194 } 195 196 void VCLXGraphics::setLineColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException) 197 { 198 ::vos::OGuard aGuard( GetMutex() ); 199 200 maLineColor = Color( (sal_uInt32)nColor ); 201 } 202 203 void VCLXGraphics::setFillColor( sal_Int32 nColor ) throw(::com::sun::star::uno::RuntimeException) 204 { 205 ::vos::OGuard aGuard( GetMutex() ); 206 207 maFillColor = Color( (sal_uInt32)nColor ); 208 } 209 210 void VCLXGraphics::setRasterOp( ::com::sun::star::awt::RasterOperation eROP ) throw(::com::sun::star::uno::RuntimeException) 211 { 212 ::vos::OGuard aGuard( GetMutex() ); 213 214 meRasterOp = (RasterOp)eROP; 215 } 216 217 void VCLXGraphics::setClipRegion( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XRegion >& rxRegion ) throw(::com::sun::star::uno::RuntimeException) 218 { 219 ::vos::OGuard aGuard( GetMutex() ); 220 221 delete mpClipRegion; 222 if ( rxRegion.is() ) 223 mpClipRegion = new Region( VCLUnoHelper::GetRegion( rxRegion ) ); 224 else 225 mpClipRegion = NULL; 226 } 227 228 void VCLXGraphics::intersectClipRegion( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XRegion >& rxRegion ) throw(::com::sun::star::uno::RuntimeException) 229 { 230 ::vos::OGuard aGuard( GetMutex() ); 231 232 if ( rxRegion.is() ) 233 { 234 Region aRegion( VCLUnoHelper::GetRegion( rxRegion ) ); 235 if ( !mpClipRegion ) 236 mpClipRegion = new Region( aRegion ); 237 else 238 mpClipRegion->Intersect( aRegion ); 239 } 240 } 241 242 void VCLXGraphics::push( ) throw(::com::sun::star::uno::RuntimeException) 243 { 244 ::vos::OGuard aGuard( GetMutex() ); 245 246 247 if( mpOutputDevice ) 248 mpOutputDevice->Push(); 249 } 250 251 void VCLXGraphics::pop( ) throw(::com::sun::star::uno::RuntimeException) 252 { 253 ::vos::OGuard aGuard( GetMutex() ); 254 255 256 if( mpOutputDevice ) 257 mpOutputDevice->Pop(); 258 } 259 260 void VCLXGraphics::copy( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDevice >& rxSource, sal_Int32 nSourceX, sal_Int32 nSourceY, sal_Int32 nSourceWidth, sal_Int32 nSourceHeight, sal_Int32 nDestX, sal_Int32 nDestY, sal_Int32 nDestWidth, sal_Int32 nDestHeight ) throw(::com::sun::star::uno::RuntimeException) 261 { 262 ::vos::OGuard aGuard( GetMutex() ); 263 264 if ( mpOutputDevice ) 265 { 266 VCLXDevice* pFromDev = VCLXDevice::GetImplementation( rxSource ); 267 DBG_ASSERT( pFromDev, "VCLXGraphics::copy - invalid device" ); 268 if ( pFromDev ) 269 { 270 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP ); 271 mpOutputDevice->DrawOutDev( Point( nDestX, nDestY ), Size( nDestWidth, nDestHeight ), 272 Point( nSourceX, nSourceY ), Size( nSourceWidth, nSourceHeight ), *pFromDev->GetOutputDevice() ); 273 } 274 } 275 } 276 277 void VCLXGraphics::draw( const ::com::sun::star::uno::Reference< ::com::sun::star::awt::XDisplayBitmap >& rxBitmapHandle, sal_Int32 nSourceX, sal_Int32 nSourceY, sal_Int32 nSourceWidth, sal_Int32 nSourceHeight, sal_Int32 nDestX, sal_Int32 nDestY, sal_Int32 nDestWidth, sal_Int32 nDestHeight ) throw(::com::sun::star::uno::RuntimeException) 278 { 279 ::vos::OGuard aGuard( GetMutex() ); 280 281 if( mpOutputDevice ) 282 { 283 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP); 284 ::com::sun::star::uno::Reference< ::com::sun::star::awt::XBitmap > xBitmap( rxBitmapHandle, ::com::sun::star::uno::UNO_QUERY ); 285 BitmapEx aBmpEx = VCLUnoHelper::GetBitmap( xBitmap ); 286 287 Point aPos(nDestX - nSourceX, nDestY - nSourceY); 288 Size aSz = aBmpEx.GetSizePixel(); 289 290 if(nDestWidth != nSourceWidth) 291 { 292 float zoomX = (float)nDestWidth / (float)nSourceWidth; 293 aSz.Width() = (long) ((float)aSz.Width() * zoomX); 294 } 295 296 if(nDestHeight != nSourceHeight) 297 { 298 float zoomY = (float)nDestHeight / (float)nSourceHeight; 299 aSz.Height() = (long) ((float)aSz.Height() * zoomY); 300 } 301 302 if(nSourceX || nSourceY || aSz.Width() != nSourceWidth || aSz.Height() != nSourceHeight) 303 mpOutputDevice->IntersectClipRegion(Region(Rectangle(nDestX, nDestY, nDestX + nDestWidth - 1, nDestY + nDestHeight - 1))); 304 305 mpOutputDevice->DrawBitmapEx( aPos, aSz, aBmpEx ); 306 } 307 } 308 309 void VCLXGraphics::drawPixel( sal_Int32 x, sal_Int32 y ) throw(::com::sun::star::uno::RuntimeException) 310 { 311 ::vos::OGuard aGuard( GetMutex() ); 312 313 if( mpOutputDevice ) 314 { 315 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS ); 316 mpOutputDevice->DrawPixel( Point( x, y ) ); 317 } 318 } 319 320 void VCLXGraphics::drawLine( sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) throw(::com::sun::star::uno::RuntimeException) 321 { 322 ::vos::OGuard aGuard( GetMutex() ); 323 324 if( mpOutputDevice ) 325 { 326 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS ); 327 mpOutputDevice->DrawLine( Point( x1, y1 ), Point( x2, y2 ) ); 328 } 329 } 330 331 void VCLXGraphics::drawRect( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height ) throw(::com::sun::star::uno::RuntimeException) 332 { 333 ::vos::OGuard aGuard( GetMutex() ); 334 335 if( mpOutputDevice ) 336 { 337 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS ); 338 mpOutputDevice->DrawRect( Rectangle( Point( x, y ), Size( width, height ) ) ); 339 } 340 } 341 342 void VCLXGraphics::drawRoundedRect( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 nHorzRound, sal_Int32 nVertRound ) throw(::com::sun::star::uno::RuntimeException) 343 { 344 ::vos::OGuard aGuard( GetMutex() ); 345 346 if( mpOutputDevice ) 347 { 348 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS ); 349 mpOutputDevice->DrawRect( Rectangle( Point( x, y ), Size( width, height ) ), nHorzRound, nVertRound ); 350 } 351 } 352 353 void VCLXGraphics::drawPolyLine( const ::com::sun::star::uno::Sequence< sal_Int32 >& DataX, const ::com::sun::star::uno::Sequence< sal_Int32 >& DataY ) throw(::com::sun::star::uno::RuntimeException) 354 { 355 ::vos::OGuard aGuard( GetMutex() ); 356 357 if( mpOutputDevice ) 358 { 359 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS ); 360 mpOutputDevice->DrawPolyLine( VCLUnoHelper::CreatePolygon( DataX, DataY ) ); 361 } 362 } 363 364 void VCLXGraphics::drawPolygon( const ::com::sun::star::uno::Sequence< sal_Int32 >& DataX, const ::com::sun::star::uno::Sequence< sal_Int32 >& DataY ) throw(::com::sun::star::uno::RuntimeException) 365 { 366 ::vos::OGuard aGuard( GetMutex() ); 367 368 if( mpOutputDevice ) 369 { 370 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS ); 371 mpOutputDevice->DrawPolygon( VCLUnoHelper::CreatePolygon( DataX, DataY ) ); 372 } 373 } 374 375 void VCLXGraphics::drawPolyPolygon( const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< sal_Int32 > >& DataX, const ::com::sun::star::uno::Sequence< ::com::sun::star::uno::Sequence< sal_Int32 > >& DataY ) throw(::com::sun::star::uno::RuntimeException) 376 { 377 ::vos::OGuard aGuard( GetMutex() ); 378 379 if( mpOutputDevice ) 380 { 381 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS ); 382 sal_uInt16 nPolys = (sal_uInt16) DataX.getLength(); 383 PolyPolygon aPolyPoly( nPolys ); 384 for ( sal_uInt16 n = 0; n < nPolys; n++ ) 385 aPolyPoly[n] = VCLUnoHelper::CreatePolygon( DataX.getConstArray()[n], DataY.getConstArray()[n] ); 386 387 mpOutputDevice->DrawPolyPolygon( aPolyPoly ); 388 } 389 } 390 391 void VCLXGraphics::drawEllipse( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height ) throw(::com::sun::star::uno::RuntimeException) 392 { 393 ::vos::OGuard aGuard( GetMutex() ); 394 395 if( mpOutputDevice ) 396 { 397 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS ); 398 mpOutputDevice->DrawEllipse( Rectangle( Point( x, y ), Size( width, height ) ) ); 399 } 400 } 401 402 void VCLXGraphics::drawArc( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) throw(::com::sun::star::uno::RuntimeException) 403 { 404 ::vos::OGuard aGuard( GetMutex() ); 405 406 if( mpOutputDevice ) 407 { 408 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS ); 409 mpOutputDevice->DrawArc( Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) ); 410 } 411 } 412 413 void VCLXGraphics::drawPie( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) throw(::com::sun::star::uno::RuntimeException) 414 { 415 ::vos::OGuard aGuard( GetMutex() ); 416 417 if( mpOutputDevice ) 418 { 419 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS ); 420 mpOutputDevice->DrawPie( Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) ); 421 } 422 } 423 424 void VCLXGraphics::drawChord( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, sal_Int32 x1, sal_Int32 y1, sal_Int32 x2, sal_Int32 y2 ) throw(::com::sun::star::uno::RuntimeException) 425 { 426 ::vos::OGuard aGuard( GetMutex() ); 427 428 if( mpOutputDevice ) 429 { 430 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS ); 431 mpOutputDevice->DrawChord( Rectangle( Point( x, y ), Size( width, height ) ), Point( x1, y1 ), Point( x2, y2 ) ); 432 } 433 } 434 435 void VCLXGraphics::drawGradient( sal_Int32 x, sal_Int32 y, sal_Int32 width, sal_Int32 height, const ::com::sun::star::awt::Gradient& rGradient ) throw(::com::sun::star::uno::RuntimeException) 436 { 437 ::vos::OGuard aGuard( GetMutex() ); 438 439 if( mpOutputDevice ) 440 { 441 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS ); 442 Gradient aGradient((GradientStyle)rGradient.Style, rGradient.StartColor, rGradient.EndColor); 443 aGradient.SetAngle(rGradient.Angle); 444 aGradient.SetBorder(rGradient.Border); 445 aGradient.SetOfsX(rGradient.XOffset); 446 aGradient.SetOfsY(rGradient.YOffset); 447 aGradient.SetStartIntensity(rGradient.StartIntensity); 448 aGradient.SetEndIntensity(rGradient.EndIntensity); 449 aGradient.SetSteps(rGradient.StepCount); 450 mpOutputDevice->DrawGradient( Rectangle( Point( x, y ), Size( width, height ) ), aGradient ); 451 } 452 } 453 454 void VCLXGraphics::drawText( sal_Int32 x, sal_Int32 y, const ::rtl::OUString& rText ) throw(::com::sun::star::uno::RuntimeException) 455 { 456 ::vos::OGuard aGuard( GetMutex() ); 457 458 if( mpOutputDevice ) 459 { 460 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS |INITOUTDEV_FONT); 461 mpOutputDevice->DrawText( Point( x, y ), rText ); 462 } 463 } 464 465 void VCLXGraphics::drawTextArray( sal_Int32 x, sal_Int32 y, const ::rtl::OUString& rText, const ::com::sun::star::uno::Sequence< sal_Int32 >& rLongs ) throw(::com::sun::star::uno::RuntimeException) 466 { 467 ::vos::OGuard aGuard( GetMutex() ); 468 469 if( mpOutputDevice ) 470 { 471 InitOutputDevice( INITOUTDEV_CLIPREGION|INITOUTDEV_RASTEROP|INITOUTDEV_COLORS|INITOUTDEV_FONT ); 472 mpOutputDevice->DrawTextArray( Point( x, y ), rText, rLongs.getConstArray() ); 473 } 474 } 475 476 477 478 479