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 if(rGraphic.getSvgData().get()) 632 { 633 // embedded Svg, no need to scale. Also no method to apply crop data currently 634 } 635 else 636 { 637 Rectangle aCropPixel( Point( 0, 0 ), rGraphic.GetSizePixel() ); 638 ImplCalculateCropRect( rGraphic, aCropLogic, aCropPixel ); 639 if ( bRemoveCropArea ) 640 { 641 BitmapEx aBmpEx( rGraphic.GetBitmapEx() ); 642 aBmpEx.Crop( aCropPixel ); 643 rGraphic = aBmpEx; 644 } 645 Size aVisiblePixelSize( bRemoveCropArea ? rGraphic.GetSizePixel() : aCropPixel.GetSize() ); 646 ImplApplyBitmapResolution( rGraphic, nImageResolution, aVisiblePixelSize, aLogicalSize ); 647 ImplApplyBitmapScaling( rGraphic, nPixelWidth, nPixelHeight ); 648 } 649 } 650 else if ( ( rGraphic.GetType() == GRAPHIC_GDIMETAFILE ) && nImageResolution ) 651 { 652 VirtualDevice aDummyVDev; 653 GDIMetaFile aMtf( rGraphic.GetGDIMetaFile() ); 654 Size aMtfSize( aDummyVDev.LogicToLogic( aMtf.GetPrefSize(), aMtf.GetPrefMapMode(), MAP_100TH_MM ) ); 655 if ( aMtfSize.Width() && aMtfSize.Height() ) 656 { 657 MapMode aNewMapMode( MAP_100TH_MM ); 658 aNewMapMode.SetScaleX( static_cast< double >( aLogicalSize.Width ) / static_cast< double >( aMtfSize.Width() ) ); 659 aNewMapMode.SetScaleY( static_cast< double >( aLogicalSize.Height ) / static_cast< double >( aMtfSize.Height() ) ); 660 aDummyVDev.EnableOutput( sal_False ); 661 aDummyVDev.SetMapMode( aNewMapMode ); 662 663 for( sal_uInt32 i = 0, nObjCount = aMtf.GetActionCount(); i < nObjCount; i++ ) 664 { 665 MetaAction* pAction = aMtf.GetAction( i ); 666 switch( pAction->GetType() ) 667 { 668 // only optimizing common bitmap actions: 669 case( META_MAPMODE_ACTION ): 670 { 671 const_cast< MetaAction* >( pAction )->Execute( &aDummyVDev ); 672 break; 673 } 674 case( META_PUSH_ACTION ): 675 { 676 const MetaPushAction* pA = (const MetaPushAction*)pAction; 677 aDummyVDev.Push( pA->GetFlags() ); 678 break; 679 } 680 case( META_POP_ACTION ): 681 { 682 aDummyVDev.Pop(); 683 break; 684 } 685 case( META_BMPSCALE_ACTION ): 686 case( META_BMPEXSCALE_ACTION ): 687 { 688 BitmapEx aBmpEx; 689 Point aPos; 690 Size aSize; 691 if ( pAction->GetType() == META_BMPSCALE_ACTION ) 692 { 693 MetaBmpScaleAction* pScaleAction = dynamic_cast< MetaBmpScaleAction* >( pAction ); 694 aBmpEx = pScaleAction->GetBitmap(); 695 aPos = pScaleAction->GetPoint(); 696 aSize = pScaleAction->GetSize(); 697 } 698 else 699 { 700 MetaBmpExScaleAction* pScaleAction = dynamic_cast< MetaBmpExScaleAction* >( pAction ); 701 aBmpEx = pScaleAction->GetBitmapEx(); 702 aPos = pScaleAction->GetPoint(); 703 aSize = pScaleAction->GetSize(); 704 } 705 ::Graphic aGraphic( aBmpEx ); 706 const Size aSize100thmm( aDummyVDev.LogicToPixel( aSize ) ); 707 Size aSize100thmm2( aDummyVDev.PixelToLogic( aSize100thmm, MAP_100TH_MM ) ); 708 709 ImplApplyBitmapResolution( aGraphic, nImageResolution, 710 aGraphic.GetSizePixel(), awt::Size( aSize100thmm2.Width(), aSize100thmm2.Height() ) ); 711 712 MetaAction* pNewAction; 713 if ( pAction->GetType() == META_BMPSCALE_ACTION ) 714 pNewAction = new MetaBmpScaleAction ( aPos, aSize, aGraphic.GetBitmap() ); 715 else 716 pNewAction = new MetaBmpExScaleAction( aPos, aSize, aGraphic.GetBitmapEx() ); 717 718 aMtf.ReplaceAction( pNewAction, i ); 719 pAction->Delete(); 720 break; 721 } 722 default: 723 case( META_BMP_ACTION ): 724 case( META_BMPSCALEPART_ACTION ): 725 case( META_BMPEX_ACTION ): 726 case( META_BMPEXSCALEPART_ACTION ): 727 case( META_MASK_ACTION ): 728 case( META_MASKSCALE_ACTION ): 729 break; 730 } 731 } 732 rGraphic = aMtf; 733 } 734 } 735 } 736 737 // ------------------------------------------------------------------------------ 738 739 void SAL_CALL GraphicProvider::storeGraphic( const uno::Reference< ::graphic::XGraphic >& rxGraphic, const uno::Sequence< beans::PropertyValue >& rMediaProperties ) 740 throw ( io::IOException, lang::IllegalArgumentException, lang::WrappedTargetException, uno::RuntimeException) 741 { 742 SvStream* pOStm = NULL; 743 String aPath; 744 sal_Int32 i; 745 746 for( i = 0; ( i < rMediaProperties.getLength() ) && !pOStm; ++i ) 747 { 748 const ::rtl::OUString aName( rMediaProperties[ i ].Name ); 749 const uno::Any aValue( rMediaProperties[ i ].Value ); 750 751 if( COMPARE_EQUAL == aName.compareToAscii( "URL" ) ) 752 { 753 ::rtl::OUString aURL; 754 755 aValue >>= aURL; 756 pOStm = ::utl::UcbStreamHelper::CreateStream( aURL, STREAM_WRITE | STREAM_TRUNC ); 757 aPath = aURL; 758 } 759 else if( COMPARE_EQUAL == aName.compareToAscii( "OutputStream" ) ) 760 { 761 uno::Reference< io::XStream > xOStm; 762 763 aValue >>= xOStm; 764 765 if( xOStm.is() ) 766 pOStm = ::utl::UcbStreamHelper::CreateStream( xOStm ); 767 } 768 } 769 770 if( pOStm ) 771 { 772 uno::Sequence< beans::PropertyValue > aFilterDataSeq; 773 const char* pFilterShortName = NULL; 774 775 for( i = 0; i < rMediaProperties.getLength(); ++i ) 776 { 777 const ::rtl::OUString aName( rMediaProperties[ i ].Name ); 778 const uno::Any aValue( rMediaProperties[ i ].Value ); 779 780 if( COMPARE_EQUAL == aName.compareToAscii( "FilterData" ) ) 781 { 782 aValue >>= aFilterDataSeq; 783 } 784 else if( COMPARE_EQUAL == aName.compareToAscii( "MimeType" ) ) 785 { 786 ::rtl::OUString aMimeType; 787 788 aValue >>= aMimeType; 789 790 if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_BMP ) ) 791 pFilterShortName = "bmp"; 792 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_EPS ) ) 793 pFilterShortName = "eps"; 794 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_GIF ) ) 795 pFilterShortName = "gif"; 796 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_JPG ) ) 797 pFilterShortName = "jpg"; 798 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_MET ) ) 799 pFilterShortName = "met"; 800 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PNG ) ) 801 pFilterShortName = "png"; 802 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PCT ) ) 803 pFilterShortName = "pct"; 804 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PBM ) ) 805 pFilterShortName = "pbm"; 806 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PGM ) ) 807 pFilterShortName = "pgm"; 808 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_PPM ) ) 809 pFilterShortName = "ppm"; 810 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_RAS ) ) 811 pFilterShortName = "ras"; 812 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_SVM ) ) 813 pFilterShortName = "svm"; 814 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_TIF ) ) 815 pFilterShortName = "tif"; 816 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_EMF ) ) 817 pFilterShortName = "emf"; 818 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_WMF ) ) 819 pFilterShortName = "wmf"; 820 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_XPM ) ) 821 pFilterShortName = "xpm"; 822 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_SVG ) ) 823 pFilterShortName = "svg"; 824 else if( COMPARE_EQUAL == aMimeType.compareToAscii( MIMETYPE_VCLGRAPHIC ) ) 825 pFilterShortName = MIMETYPE_VCLGRAPHIC; 826 } 827 } 828 829 if( pFilterShortName ) 830 { 831 ::GraphicFilter* pFilter = ::GraphicFilter::GetGraphicFilter(); 832 833 if( pFilter ) 834 { 835 const uno::Reference< XInterface > xIFace( rxGraphic, uno::UNO_QUERY ); 836 const ::Graphic* pGraphic = ::unographic::Graphic::getImplementation( xIFace ); 837 838 if( pGraphic && ( pGraphic->GetType() != GRAPHIC_NONE ) ) 839 { 840 ::Graphic aGraphic( *pGraphic ); 841 ImplApplyFilterData( aGraphic, aFilterDataSeq ); 842 843 /* sj: using a temporary memory stream, because some graphic filters are seeking behind 844 stream end (which leads to an invalid argument exception then). */ 845 SvMemoryStream aMemStrm; 846 aMemStrm.SetVersion( SOFFICE_FILEFORMAT_CURRENT ); 847 if( 0 == strcmp( pFilterShortName, MIMETYPE_VCLGRAPHIC ) ) 848 aMemStrm << aGraphic; 849 else 850 { 851 pFilter->ExportGraphic( aGraphic, aPath, aMemStrm, 852 pFilter->GetExportFormatNumberForShortName( ::rtl::OUString::createFromAscii( pFilterShortName ) ), 853 ( aFilterDataSeq.getLength() ? &aFilterDataSeq : NULL ) ); 854 } 855 aMemStrm.Seek( STREAM_SEEK_TO_END ); 856 pOStm->Write( aMemStrm.GetData(), aMemStrm.Tell() ); 857 } 858 } 859 } 860 delete pOStm; 861 } 862 } 863 864 } 865