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_svtools.hxx" 26 27 #include <rtl/uuid.h> 28 #include <vos/mutex.hxx> 29 #include <vcl/svapp.hxx> 30 #include <vcl/image.hxx> 31 #include <vcl/metaact.hxx> 32 #include <vcl/msgbox.hxx> 33 #include <vcl/imagerepository.hxx> 34 #include <tools/rcid.h> 35 #include <tools/resid.hxx> 36 #include <tools/resmgr.hxx> 37 #include <unotools/ucbstreamhelper.hxx> 38 #include <svtools/filter.hxx> 39 #include <svl/solar.hrc> 40 #include <vcl/salbtype.hxx> 41 #include <vcl/virdev.hxx> 42 #include <com/sun/star/io/XStream.hpp> 43 #include <com/sun/star/text/GraphicCrop.hpp> 44 45 #include "descriptor.hxx" 46 #include "graphic.hxx" 47 #include <svtools/grfmgr.hxx> 48 #include "provider.hxx" 49 50 using namespace com::sun::star; 51 52 namespace unographic { 53 54 #define UNO_NAME_GRAPHOBJ_URLPREFIX "vnd.sun.star.GraphicObject:" 55 56 // ------------------- 57 // - GraphicProvider - 58 // ------------------- 59 60 uno::Reference< uno::XInterface > SAL_CALL GraphicProvider_CreateInstance( const uno::Reference< lang::XMultiServiceFactory >& ) 61 { 62 return SAL_STATIC_CAST( ::cppu::OWeakObject*, new GraphicProvider ); 63 } 64 65 GraphicProvider::GraphicProvider() 66 { 67 } 68 69 // ------------------------------------------------------------------------------ 70 71 GraphicProvider::~GraphicProvider() 72 { 73 } 74 75 // ------------------------------------------------------------------------------ 76 77 ::rtl::OUString GraphicProvider::getImplementationName_Static() 78 throw() 79 { 80 return ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.graphic.GraphicProvider" ) ); 81 } 82 83 // ------------------------------------------------------------------------------ 84 85 uno::Sequence< ::rtl::OUString > GraphicProvider::getSupportedServiceNames_Static() 86 throw() 87 { 88 uno::Sequence< ::rtl::OUString > aSeq( 1 ); 89 90 aSeq.getArray()[ 0 ] = ::rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.graphic.GraphicProvider" ) ); 91 92 return aSeq; 93 } 94 95 // ------------------------------------------------------------------------------ 96 97 ::rtl::OUString SAL_CALL GraphicProvider::getImplementationName() 98 throw( uno::RuntimeException ) 99 { 100 return getImplementationName_Static(); 101 } 102 103 // ------------------------------------------------------------------------------ 104 105 sal_Bool SAL_CALL GraphicProvider::supportsService( const ::rtl::OUString& ServiceName ) 106 throw( uno::RuntimeException ) 107 { 108 uno::Sequence< ::rtl::OUString > aSNL( getSupportedServiceNames() ); 109 const ::rtl::OUString* pArray = aSNL.getConstArray(); 110 111 for( int i = 0; i < aSNL.getLength(); i++ ) 112 if( pArray[i] == ServiceName ) 113 return true; 114 115 return false; 116 } 117 118 // ------------------------------------------------------------------------------ 119 120 uno::Sequence< ::rtl::OUString > SAL_CALL GraphicProvider::getSupportedServiceNames() 121 throw( uno::RuntimeException ) 122 { 123 return getSupportedServiceNames_Static(); 124 } 125 126 // ------------------------------------------------------------------------------ 127 128 uno::Sequence< uno::Type > SAL_CALL GraphicProvider::getTypes() 129 throw(uno::RuntimeException) 130 { 131 uno::Sequence< uno::Type > aTypes( 3 ); 132 uno::Type* pTypes = aTypes.getArray(); 133 134 *pTypes++ = ::getCppuType((const uno::Reference< lang::XServiceInfo>*)0); 135 *pTypes++ = ::getCppuType((const uno::Reference< lang::XTypeProvider>*)0); 136 *pTypes++ = ::getCppuType((const uno::Reference< graphic::XGraphicProvider>*)0); 137 138 return aTypes; 139 } 140 141 // ------------------------------------------------------------------------------ 142 143 uno::Sequence< sal_Int8 > SAL_CALL GraphicProvider::getImplementationId() 144 throw(uno::RuntimeException) 145 { 146 vos::OGuard aGuard( Application::GetSolarMutex() ); 147 static uno::Sequence< sal_Int8 > aId; 148 149 if( aId.getLength() == 0 ) 150 { 151 aId.realloc( 16 ); 152 rtl_createUuid( reinterpret_cast< sal_uInt8* >( aId.getArray() ), 0, sal_True ); 153 } 154 155 return aId; 156 } 157 158 // ------------------------------------------------------------------------------ 159 160 uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadGraphicObject( const ::rtl::OUString& rResourceURL ) const 161 { 162 uno::Reference< ::graphic::XGraphic > xRet; 163 if( rResourceURL.compareToAscii( UNO_NAME_GRAPHOBJ_URLPREFIX, RTL_CONSTASCII_LENGTH( UNO_NAME_GRAPHOBJ_URLPREFIX ) ) == 0 ) 164 { 165 // graphic manager url 166 String aTmpStr( rResourceURL.copy( sizeof( UNO_NAME_GRAPHOBJ_URLPREFIX ) - 1 ) ); 167 ByteString aUniqueID( aTmpStr, RTL_TEXTENCODING_UTF8 ); 168 GraphicObject aGrafObj( aUniqueID ); 169 // I don't call aGrafObj.GetXGraphic because it will call us back 170 // into implLoadMemory ( with "private:memorygraphic" test ) 171 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic; 172 pUnoGraphic->init( aGrafObj.GetGraphic() ); 173 xRet = pUnoGraphic; 174 } 175 return xRet; 176 } 177 178 uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadMemory( const ::rtl::OUString& rResourceURL ) const 179 { 180 uno::Reference< ::graphic::XGraphic > xRet; 181 sal_Int32 nIndex = 0; 182 183 if( ( 0 == rResourceURL.getToken( 0, '/', nIndex ).compareToAscii( "private:memorygraphic" ) ) ) 184 { 185 sal_Int64 nGraphicAddress = rResourceURL.getToken( 0, '/', nIndex ).toInt64(); 186 187 if( nGraphicAddress ) 188 { 189 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic; 190 191 pUnoGraphic->init( *reinterpret_cast< ::Graphic* >( nGraphicAddress ) ); 192 xRet = pUnoGraphic; 193 } 194 } 195 196 return xRet; 197 } 198 199 // ------------------------------------------------------------------------------ 200 201 uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadRepositoryImage( const ::rtl::OUString& rResourceURL ) const 202 { 203 uno::Reference< ::graphic::XGraphic > xRet; 204 sal_Int32 nIndex = 0; 205 206 if( ( 0 == rResourceURL.getToken( 0, '/', nIndex ).compareToAscii( "private:graphicrepository" ) ) ) 207 { 208 String sPathName( rResourceURL.copy( nIndex ) ); 209 BitmapEx aBitmap; 210 if ( ::vcl::ImageRepository::loadImage( sPathName, aBitmap, false ) ) 211 { 212 Image aImage( aBitmap ); 213 xRet = aImage.GetXGraphic(); 214 } 215 } 216 return xRet; 217 } 218 219 220 // ------------------------------------------------------------------------------ 221 222 uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadStandardImage( const ::rtl::OUString& rResourceURL ) const 223 { 224 uno::Reference< ::graphic::XGraphic > xRet; 225 sal_Int32 nIndex = 0; 226 227 if( ( 0 == rResourceURL.getToken( 0, '/', nIndex ).compareToAscii( "private:standardimage" ) ) ) 228 { 229 rtl::OUString sImageName( rResourceURL.copy( nIndex ) ); 230 if ( sImageName.equalsAscii( "info" ) ) 231 { 232 xRet = InfoBox::GetStandardImage().GetXGraphic(); 233 } 234 else if ( sImageName.equalsAscii( "warning" ) ) 235 { 236 xRet = WarningBox::GetStandardImage().GetXGraphic(); 237 } 238 else if ( sImageName.equalsAscii( "error" ) ) 239 { 240 xRet = ErrorBox::GetStandardImage().GetXGraphic(); 241 } 242 else if ( sImageName.equalsAscii( "query" ) ) 243 { 244 xRet = QueryBox::GetStandardImage().GetXGraphic(); 245 } 246 } 247 return xRet; 248 } 249 250 // ------------------------------------------------------------------------------ 251 252 uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadBitmap( const uno::Reference< awt::XBitmap >& xBtm ) const 253 { 254 uno::Reference< ::graphic::XGraphic > xRet; 255 uno::Sequence< sal_Int8 > aBmpSeq( xBtm->getDIB() ); 256 uno::Sequence< sal_Int8 > aMaskSeq( xBtm->getMaskDIB() ); 257 SvMemoryStream aBmpStream( aBmpSeq.getArray(), aBmpSeq.getLength(), STREAM_READ ); 258 Bitmap aBmp; 259 aBmpStream >> aBmp; 260 261 BitmapEx aBmpEx; 262 263 if( aMaskSeq.getLength() ) 264 { 265 SvMemoryStream aMaskStream( aMaskSeq.getArray(), aMaskSeq.getLength(), STREAM_READ ); 266 Bitmap aMask; 267 aMaskStream >> aMask; 268 aBmpEx = BitmapEx( aBmp, aMask ); 269 } 270 else 271 aBmpEx = BitmapEx( aBmp ); 272 273 if( !aBmpEx.IsEmpty() ) 274 { 275 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic; 276 277 pUnoGraphic->init( aBmpEx ); 278 xRet = pUnoGraphic; 279 } 280 return xRet; 281 } 282 283 // ------------------------------------------------------------------------------ 284 285 uno::Reference< ::graphic::XGraphic > GraphicProvider::implLoadResource( const ::rtl::OUString& rResourceURL ) const 286 { 287 uno::Reference< ::graphic::XGraphic > xRet; 288 sal_Int32 nIndex = 0; 289 290 if( ( 0 == rResourceURL.getToken( 0, '/', nIndex ).compareToAscii( "private:resource" ) ) ) 291 { 292 ByteString aResMgrName( String( rResourceURL.getToken( 0, '/', nIndex ) ), RTL_TEXTENCODING_ASCII_US ); 293 294 ResMgr* pResMgr = ResMgr::CreateResMgr( aResMgrName.GetBuffer(), Application::GetSettings().GetUILocale() ); 295 296 if( pResMgr ) 297 { 298 const ::rtl::OUString aResourceType( rResourceURL.getToken( 0, '/', nIndex ) ); 299 const ResId aResId( rResourceURL.getToken( 0, '/', nIndex ).toInt32(), *pResMgr ); 300 301 if( aResourceType.getLength() ) 302 { 303 BitmapEx aBmpEx; 304 305 if( ( 0 == aResourceType.compareToAscii( "bitmap" ) ) || 306 ( 0 == aResourceType.compareToAscii( "bitmapex" ) ) ) 307 { 308 aResId.SetRT( RSC_BITMAP ); 309 310 if( pResMgr->IsAvailable( aResId ) ) 311 { 312 aBmpEx = BitmapEx( aResId ); 313 } 314 } 315 else if( 0 == aResourceType.compareToAscii( "image" ) ) 316 { 317 aResId.SetRT( RSC_IMAGE ); 318 319 if( pResMgr->IsAvailable( aResId ) ) 320 { 321 const Image aImage( aResId ); 322 aBmpEx = aImage.GetBitmapEx(); 323 } 324 } 325 else if( 0 == aResourceType.compareToAscii( "imagelist" ) ) 326 { 327 aResId.SetRT( RSC_IMAGELIST ); 328 329 if( pResMgr->IsAvailable( aResId ) ) 330 { 331 const ImageList aImageList( aResId ); 332 sal_Int32 nImageId = ( nIndex > -1 ) ? rResourceURL.getToken( 0, '/', nIndex ).toInt32() : 0; 333 334 if( 0 < nImageId ) 335 { 336 const Image aImage( aImageList.GetImage( sal::static_int_cast< sal_uInt16 >(nImageId) ) ); 337 aBmpEx = aImage.GetBitmapEx(); 338 } 339 else 340 { 341 aBmpEx = aImageList.GetAsHorizontalStrip(); 342 } 343 } 344 } 345 346 if( !aBmpEx.IsEmpty() ) 347 { 348 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic; 349 350 pUnoGraphic->init( aBmpEx ); 351 xRet = pUnoGraphic; 352 } 353 } 354 355 delete pResMgr; 356 } 357 } 358 359 return xRet; 360 } 361 362 // ------------------------------------------------------------------------------ 363 364 uno::Reference< beans::XPropertySet > SAL_CALL GraphicProvider::queryGraphicDescriptor( const uno::Sequence< beans::PropertyValue >& rMediaProperties ) 365 throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) 366 { 367 uno::Reference< beans::XPropertySet > xRet; 368 369 ::rtl::OUString aURL; 370 uno::Reference< io::XInputStream > xIStm; 371 uno::Reference< awt::XBitmap >xBtm; 372 373 for( sal_Int32 i = 0; ( i < rMediaProperties.getLength() ) && !xRet.is(); ++i ) 374 { 375 const ::rtl::OUString aName( rMediaProperties[ i ].Name ); 376 const uno::Any aValue( rMediaProperties[ i ].Value ); 377 378 if( COMPARE_EQUAL == aName.compareToAscii( "URL" ) ) 379 { 380 aValue >>= aURL; 381 } 382 else if( COMPARE_EQUAL == aName.compareToAscii( "InputStream" ) ) 383 { 384 aValue >>= xIStm; 385 } 386 else if( COMPARE_EQUAL == aName.compareToAscii( "Bitmap" ) ) 387 { 388 aValue >>= xBtm; 389 } 390 } 391 392 if( xIStm.is() ) 393 { 394 GraphicDescriptor* pDescriptor = new GraphicDescriptor; 395 pDescriptor->init( xIStm, aURL ); 396 xRet = pDescriptor; 397 } 398 else if( aURL.getLength() ) 399 { 400 uno::Reference< ::graphic::XGraphic > xGraphic( implLoadMemory( aURL ) ); 401 if( !xGraphic.is() ) 402 xGraphic = implLoadResource( aURL ); 403 if( !xGraphic.is() ) 404 xGraphic = implLoadGraphicObject( aURL ); 405 406 if ( !xGraphic.is() ) 407 xGraphic = implLoadRepositoryImage( aURL ); 408 409 if ( !xGraphic.is() ) 410 xGraphic = implLoadStandardImage( aURL ); 411 412 if( xGraphic.is() ) 413 { 414 xRet = uno::Reference< beans::XPropertySet >( xGraphic, uno::UNO_QUERY ); 415 } 416 else 417 { 418 GraphicDescriptor* pDescriptor = new GraphicDescriptor; 419 pDescriptor->init( aURL ); 420 xRet = pDescriptor; 421 } 422 } 423 else if( xBtm.is() ) 424 { 425 uno::Reference< ::graphic::XGraphic > xGraphic( implLoadBitmap( xBtm ) ); 426 if( xGraphic.is() ) 427 xRet = uno::Reference< beans::XPropertySet >( xGraphic, uno::UNO_QUERY ); 428 } 429 430 return xRet; 431 } 432 433 // ------------------------------------------------------------------------------ 434 435 uno::Reference< ::graphic::XGraphic > SAL_CALL GraphicProvider::queryGraphic( const uno::Sequence< ::beans::PropertyValue >& rMediaProperties ) 436 throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) 437 { 438 uno::Reference< ::graphic::XGraphic > xRet; 439 String aPath; 440 SvStream* pIStm = NULL; 441 442 uno::Reference< io::XInputStream > xIStm; 443 uno::Reference< awt::XBitmap >xBtm; 444 445 for( sal_Int32 i = 0; ( i < rMediaProperties.getLength() ) && !pIStm && !xRet.is(); ++i ) 446 { 447 const ::rtl::OUString aName( rMediaProperties[ i ].Name ); 448 const uno::Any aValue( rMediaProperties[ i ].Value ); 449 450 if( COMPARE_EQUAL == aName.compareToAscii( "URL" ) ) 451 { 452 ::rtl::OUString aURL; 453 aValue >>= aURL; 454 aPath = aURL; 455 } 456 else if( COMPARE_EQUAL == aName.compareToAscii( "InputStream" ) ) 457 { 458 aValue >>= xIStm; 459 } 460 else if( COMPARE_EQUAL == aName.compareToAscii( "Bitmap" ) ) 461 { 462 aValue >>= xBtm; 463 } 464 } 465 466 if( xIStm.is() ) 467 { 468 pIStm = ::utl::UcbStreamHelper::CreateStream( xIStm ); 469 } 470 else if( aPath.Len() ) 471 { 472 xRet = implLoadMemory( aPath ); 473 474 if( !xRet.is() ) 475 xRet = implLoadGraphicObject( aPath ); 476 477 if( !xRet.is() ) 478 xRet = implLoadResource( aPath ); 479 480 if ( !xRet.is() ) 481 xRet = implLoadRepositoryImage( aPath ); 482 483 if ( !xRet.is() ) 484 xRet = implLoadStandardImage( aPath ); 485 486 if( !xRet.is() ) 487 pIStm = ::utl::UcbStreamHelper::CreateStream( aPath, STREAM_READ ); 488 } 489 else if( xBtm.is() ) 490 { 491 xRet = implLoadBitmap( xBtm ); 492 } 493 494 if( pIStm ) 495 { 496 ::GraphicFilter* pFilter = ::GraphicFilter::GetGraphicFilter(); 497 498 if( pFilter ) 499 { 500 ::Graphic aVCLGraphic; 501 502 if( ( pFilter->ImportGraphic( aVCLGraphic, aPath, *pIStm ) == GRFILTER_OK ) && 503 ( aVCLGraphic.GetType() != GRAPHIC_NONE ) ) 504 { 505 ::unographic::Graphic* pUnoGraphic = new ::unographic::Graphic; 506 507 pUnoGraphic->init( aVCLGraphic ); 508 xRet = pUnoGraphic; 509 } 510 } 511 512 delete pIStm; 513 } 514 515 return xRet; 516 } 517 518 void ImplCalculateCropRect( ::Graphic& rGraphic, const text::GraphicCrop& rGraphicCropLogic, Rectangle& rGraphicCropPixel ) 519 { 520 if ( rGraphicCropLogic.Left || rGraphicCropLogic.Top || rGraphicCropLogic.Right || rGraphicCropLogic.Bottom ) 521 { 522 Size aSourceSizePixel( rGraphic.GetSizePixel() ); 523 if ( aSourceSizePixel.Width() && aSourceSizePixel.Height() ) 524 { 525 if ( rGraphicCropLogic.Left || rGraphicCropLogic.Top || rGraphicCropLogic.Right || rGraphicCropLogic.Bottom ) 526 { 527 Size aSize100thMM( 0, 0 ); 528 if( rGraphic.GetPrefMapMode().GetMapUnit() != MAP_PIXEL ) 529 { 530 aSize100thMM = OutputDevice::LogicToLogic( rGraphic.GetPrefSize(), rGraphic.GetPrefMapMode(), MAP_100TH_MM ); 531 } 532 else 533 { 534 aSize100thMM = Application::GetDefaultDevice()->PixelToLogic( rGraphic.GetPrefSize(), MAP_100TH_MM ); 535 } 536 if ( aSize100thMM.Width() && aSize100thMM.Height() ) 537 { 538 double fSourceSizePixelWidth = static_cast<double>(aSourceSizePixel.Width()); 539 double fSourceSizePixelHeight= static_cast<double>(aSourceSizePixel.Height()); 540 rGraphicCropPixel.Left() = static_cast< sal_Int32 >((fSourceSizePixelWidth * rGraphicCropLogic.Left ) / aSize100thMM.Width()); 541 rGraphicCropPixel.Top() = static_cast< sal_Int32 >((fSourceSizePixelHeight * rGraphicCropLogic.Top ) / aSize100thMM.Height()); 542 rGraphicCropPixel.Right() = static_cast< sal_Int32 >(( fSourceSizePixelWidth * ( aSize100thMM.Width() - rGraphicCropLogic.Right ) ) / aSize100thMM.Width() ); 543 rGraphicCropPixel.Bottom() = static_cast< sal_Int32 >(( fSourceSizePixelHeight * ( aSize100thMM.Height() - rGraphicCropLogic.Bottom ) ) / aSize100thMM.Height() ); 544 } 545 } 546 } 547 } 548 } 549 550 void ImplApplyBitmapScaling( ::Graphic& rGraphic, sal_Int32 nPixelWidth, sal_Int32 nPixelHeight ) 551 { 552 if ( nPixelWidth && nPixelHeight ) 553 { 554 BitmapEx aBmpEx( rGraphic.GetBitmapEx() ); 555 MapMode aPrefMapMode( aBmpEx.GetPrefMapMode() ); 556 Size aPrefSize( aBmpEx.GetPrefSize() ); 557 aBmpEx.Scale( Size( nPixelWidth, nPixelHeight ) ); 558 aBmpEx.SetPrefMapMode( aPrefMapMode ); 559 aBmpEx.SetPrefSize( aPrefSize ); 560 rGraphic = aBmpEx; 561 } 562 } 563 564 void ImplApplyBitmapResolution( ::Graphic& rGraphic, sal_Int32 nImageResolution, const Size& rVisiblePixelSize, const awt::Size& rLogicalSize ) 565 { 566 if ( nImageResolution && rLogicalSize.Width && rLogicalSize.Height ) 567 { 568 const double fImageResolution = static_cast<double>( nImageResolution ); 569 const double fSourceDPIX = ( static_cast<double>(rVisiblePixelSize.Width()) * 2540.0 ) / static_cast<double>(rLogicalSize.Width); 570 const double fSourceDPIY = ( static_cast<double>(rVisiblePixelSize.Height()) * 2540.0 ) / static_cast<double>(rLogicalSize.Height); 571 const sal_Int32 nSourcePixelWidth( rGraphic.GetSizePixel().Width() ); 572 const sal_Int32 nSourcePixelHeight( rGraphic.GetSizePixel().Height() ); 573 const double fSourcePixelWidth = static_cast<double>( nSourcePixelWidth ); 574 const double fSourcePixelHeight= static_cast<double>( nSourcePixelHeight ); 575 576 sal_Int32 nDestPixelWidth = nSourcePixelWidth; 577 sal_Int32 nDestPixelHeight = nSourcePixelHeight; 578 579 // check, if the bitmap DPI exceeds the maximum DPI 580 if( fSourceDPIX > fImageResolution ) 581 { 582 nDestPixelWidth = static_cast<sal_Int32>(( fSourcePixelWidth * fImageResolution ) / fSourceDPIX); 583 if ( !nDestPixelWidth || ( nDestPixelWidth > nSourcePixelWidth ) ) 584 nDestPixelWidth = nSourcePixelWidth; 585 } 586 if ( fSourceDPIY > fImageResolution ) 587 { 588 nDestPixelHeight= static_cast<sal_Int32>(( fSourcePixelHeight* fImageResolution ) / fSourceDPIY); 589 if ( !nDestPixelHeight || ( nDestPixelHeight > nSourcePixelHeight ) ) 590 nDestPixelHeight = nSourcePixelHeight; 591 } 592 if ( ( nDestPixelWidth != nSourcePixelWidth ) || ( nDestPixelHeight != nSourcePixelHeight ) ) 593 ImplApplyBitmapScaling( rGraphic, nDestPixelWidth, nDestPixelHeight ); 594 } 595 } 596 597 void ImplApplyFilterData( ::Graphic& rGraphic, uno::Sequence< beans::PropertyValue >& rFilterData ) 598 { 599 /* this method applies following attributes to the graphic, in the first step the 600 cropping area (logical size in 100thmm) is applied, in the second step the resolution 601 is applied, in the third step the graphic is scaled to the corresponding pixelsize. 602 if a parameter value is zero or not available the corresponding step will be skipped */ 603 604 sal_Int32 nPixelWidth = 0; 605 sal_Int32 nPixelHeight= 0; 606 sal_Int32 nImageResolution = 0; 607 awt::Size aLogicalSize( 0, 0 ); 608 text::GraphicCrop aCropLogic( 0, 0, 0, 0 ); 609 sal_Bool bRemoveCropArea = sal_True; 610 611 for( sal_Int32 i = 0; i < rFilterData.getLength(); ++i ) 612 { 613 const ::rtl::OUString aName( rFilterData[ i ].Name ); 614 const uno::Any aValue( rFilterData[ i ].Value ); 615 616 if( COMPARE_EQUAL == aName.compareToAscii( "PixelWidth" ) ) 617 aValue >>= nPixelWidth; 618 else if( COMPARE_EQUAL == aName.compareToAscii( "PixelHeight" ) ) 619 aValue >>= nPixelHeight; 620 else if( COMPARE_EQUAL == aName.compareToAscii( "LogicalSize" ) ) 621 aValue >>= aLogicalSize; 622 else if (COMPARE_EQUAL == aName.compareToAscii( "GraphicCropLogic" ) ) 623 aValue >>= aCropLogic; 624 else if (COMPARE_EQUAL == aName.compareToAscii( "RemoveCropArea" ) ) 625 aValue >>= bRemoveCropArea; 626 else if (COMPARE_EQUAL == aName.compareToAscii( "ImageResolution" ) ) 627 aValue >>= nImageResolution; 628 } 629 if ( rGraphic.GetType() == GRAPHIC_BITMAP ) 630 { 631 Rectangle aCropPixel( Point( 0, 0 ), rGraphic.GetSizePixel() ); 632 ImplCalculateCropRect( rGraphic, aCropLogic, aCropPixel ); 633 if ( bRemoveCropArea ) 634 { 635 BitmapEx aBmpEx( rGraphic.GetBitmapEx() ); 636 aBmpEx.Crop( aCropPixel ); 637 rGraphic = aBmpEx; 638 } 639 Size aVisiblePixelSize( bRemoveCropArea ? rGraphic.GetSizePixel() : aCropPixel.GetSize() ); 640 ImplApplyBitmapResolution( rGraphic, nImageResolution, aVisiblePixelSize, aLogicalSize ); 641 ImplApplyBitmapScaling( rGraphic, nPixelWidth, nPixelHeight ); 642 } 643 else if ( ( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) && nImageResolution ) 644 { 645 VirtualDevice aDummyVDev; 646 GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() ); 647 Size aMtfSize( aDummyVDev.LogicToLogic( aMtf.GetPrefSize(), aMtf.GetPrefMapMode(), MAP_100TH_MM ) ); 648 if ( aMtfSize.Width() && aMtfSize.Height() ) 649 { 650 MapMode aNewMapMode( MAP_100TH_MM ); 651 aNewMapMode.SetScaleX( static_cast< double >( aLogicalSize.Width ) / static_cast< double >( aMtfSize.Width() ) ); 652 aNewMapMode.SetScaleY( static_cast< double >( aLogicalSize.Height ) / static_cast< double >( aMtfSize.Height() ) ); 653 aDummyVDev.EnableOutput( sal_False ); 654 aDummyVDev.SetMapMode( aNewMapMode ); 655 656 for( sal_uInt32 i = 0, nObjCount = aMtf.GetActionCount(); i < nObjCount; i++ ) 657 { 658 MetaAction* pAction = aMtf.GetAction( i ); 659 switch( pAction->GetType() ) 660 { 661 // only optimizing common bitmap actions: 662 case( META_MAPMODE_ACTION ): 663 { 664 const_cast< MetaAction* >( pAction )->Execute( &aDummyVDev ); 665 break; 666 } 667 case( META_PUSH_ACTION ): 668 { 669 const MetaPushAction* pA = (const MetaPushAction*)pAction; 670 aDummyVDev.Push( pA->GetFlags() ); 671 break; 672 } 673 case( META_POP_ACTION ): 674 { 675 aDummyVDev.Pop(); 676 break; 677 } 678 case( META_BMPSCALE_ACTION ): 679 case( META_BMPEXSCALE_ACTION ): 680 { 681 BitmapEx aBmpEx; 682 Point aPos; 683 Size aSize; 684 if ( pAction->GetType() == META_BMPSCALE_ACTION ) 685 { 686 MetaBmpScaleAction* pScaleAction = dynamic_cast< MetaBmpScaleAction* >( pAction ); 687 aBmpEx = pScaleAction->GetBitmap(); 688 aPos = pScaleAction->GetPoint(); 689 aSize = pScaleAction->GetSize(); 690 } 691 else 692 { 693 MetaBmpExScaleAction* pScaleAction = dynamic_cast< MetaBmpExScaleAction* >( pAction ); 694 aBmpEx = pScaleAction->GetBitmapEx(); 695 aPos = pScaleAction->GetPoint(); 696 aSize = pScaleAction->GetSize(); 697 } 698 ::Graphic aGraphic( aBmpEx ); 699 const Size aSize100thmm( aDummyVDev.LogicToPixel( aSize ) ); 700 Size aSize100thmm2( aDummyVDev.PixelToLogic( aSize100thmm, MAP_100TH_MM ) ); 701 702 ImplApplyBitmapResolution( aGraphic, nImageResolution, 703 aGraphic.GetSizePixel(), awt::Size( aSize100thmm2.Width(), aSize100thmm2.Height() ) ); 704 705 MetaAction* pNewAction; 706 if ( pAction->GetType() == META_BMPSCALE_ACTION ) 707 pNewAction = new MetaBmpScaleAction ( aPos, aSize, aGraphic.GetBitmap() ); 708 else 709 pNewAction = new MetaBmpExScaleAction( aPos, aSize, aGraphic.GetBitmapEx() ); 710 711 aMtf.ReplaceAction( pNewAction, i ); 712 pAction->Delete(); 713 break; 714 } 715 default: 716 case( META_BMP_ACTION ): 717 case( META_BMPSCALEPART_ACTION ): 718 case( META_BMPEX_ACTION ): 719 case( META_BMPEXSCALEPART_ACTION ): 720 case( META_MASK_ACTION ): 721 case( META_MASKSCALE_ACTION ): 722 break; 723 } 724 } 725 rGraphic = aMtf; 726 } 727 } 728 } 729 730 // ------------------------------------------------------------------------------ 731 732 void SAL_CALL GraphicProvider::storeGraphic( const uno::Reference< ::graphic::XGraphic >& rxGraphic, const uno::Sequence< beans::PropertyValue >& rMediaProperties ) 733 throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) 734 { 735 SvStream* pOStm = NULL; 736 String aPath; 737 sal_Int32 i; 738 739 for( i = 0; ( i < rMediaProperties.getLength() ) && !pOStm; ++i ) 740 { 741 const ::rtl::OUString aName( rMediaProperties[ i ].Name ); 742 const uno::Any aValue( rMediaProperties[ i ].Value ); 743 744 if( COMPARE_EQUAL == aName.compareToAscii( "URL" ) ) 745 { 746 ::rtl::OUString aURL; 747 748 aValue >>= aURL; 749 pOStm = ::utl::UcbStreamHelper::CreateStream( aURL, STREAM_WRITE | STREAM_TRUNC ); 750 aPath = aURL; 751 } 752 else if( COMPARE_EQUAL == aName.compareToAscii( "OutputStream" ) ) 753 { 754 uno::Reference< io::XStream > xOStm; 755 756 aValue >>= xOStm; 757 758 if( xOStm.is() ) 759 pOStm = ::utl::UcbStreamHelper::CreateStream( xOStm ); 760 } 761 } 762 763 if( pOStm ) 764 { 765 uno::Sequence< beans::PropertyValue > aFilterDataSeq; 766 const char* pFilterShortName = NULL; 767 768 for( i = 0; i < rMediaProperties.getLength(); ++i ) 769 { 770 const ::rtl::OUString aName( rMediaProperties[ i ].Name ); 771 const uno::Any aValue( rMediaProperties[ i ].Value ); 772 773 if( COMPARE_EQUAL == aName.compareToAscii( "FilterData" ) ) 774 { 775 aValue >>= aFilterDataSeq; 776 } 777 else if( COMPARE_EQUAL == aName.compareToAscii( "MimeType" ) ) 778 { 779 ::rtl::OUString aMimeType; 780 781 aValue >>= aMimeType; 782 783 if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_BMP ) ) 784 pFilterShortName = "bmp"; 785 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_EPS ) ) 786 pFilterShortName = "eps"; 787 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_GIF ) ) 788 pFilterShortName = "gif"; 789 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_JPG ) ) 790 pFilterShortName = "jpg"; 791 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_MET ) ) 792 pFilterShortName = "met"; 793 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PNG ) ) 794 pFilterShortName = "png"; 795 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PCT ) ) 796 pFilterShortName = "pct"; 797 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PBM ) ) 798 pFilterShortName = "pbm"; 799 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PGM ) ) 800 pFilterShortName = "pgm"; 801 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PPM ) ) 802 pFilterShortName = "ppm"; 803 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_RAS ) ) 804 pFilterShortName = "ras"; 805 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_SVM ) ) 806 pFilterShortName = "svm"; 807 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_TIF ) ) 808 pFilterShortName = "tif"; 809 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_EMF ) ) 810 pFilterShortName = "emf"; 811 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_WMF ) ) 812 pFilterShortName = "wmf"; 813 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_XPM ) ) 814 pFilterShortName = "xpm"; 815 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_SVG ) ) 816 pFilterShortName = "svg"; 817 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_VCLGRAPHIC ) ) 818 pFilterShortName = MIMETYPE_VCLGRAPHIC; 819 } 820 } 821 822 if( pFilterShortName ) 823 { 824 ::GraphicFilter* pFilter = ::GraphicFilter::GetGraphicFilter(); 825 826 if( pFilter ) 827 { 828 const uno::Reference< XInterface > xIFace( rxGraphic, uno::UNO_QUERY ); 829 const ::Graphic* pGraphic = ::unographic::Graphic::getImplementation( xIFace ); 830 831 if( pGraphic && ( pGraphic->GetType() != GRAPHIC_NONE ) ) 832 { 833 ::Graphic aGraphic( *pGraphic ); 834 ImplApplyFilterData( aGraphic, aFilterDataSeq ); 835 836 /* sj: using a temporary memory stream, because some graphic filters are seeking behind 837 stream end (which leads to an invalid argument exception then). */ 838 SvMemoryStream aMemStrm; 839 aMemStrm.SetVersion( SOFFICE_FILEFORMAT_CURRENT ); 840 if( 0 == strcmp( pFilterShortName, MIMETYPE_VCLGRAPHIC ) ) 841 aMemStrm << aGraphic; 842 else 843 { 844 pFilter->ExportGraphic( aGraphic, aPath, aMemStrm, 845 pFilter->GetExportFormatNumberForShortName( ::rtl::OUString::createFromAscii( pFilterShortName ) ), 846 ( aFilterDataSeq.getLength() ? &aFilterDataSeq : NULL ) ); 847 } 848 aMemStrm.Seek( STREAM_SEEK_TO_END ); 849 pOStm->Write( aMemStrm.GetData(), aMemStrm.Tell() ); 850 } 851 } 852 } 853 delete pOStm; 854 } 855 } 856 857 } 858