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