| /************************************************************** |
| * |
| * Licensed to the Apache Software Foundation (ASF) under one |
| * or more contributor license agreements. See the NOTICE file |
| * distributed with this work for additional information |
| * regarding copyright ownership. The ASF licenses this file |
| * to you under the Apache License, Version 2.0 (the |
| * "License"); you may not use this file except in compliance |
| * with the License. You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, |
| * software distributed under the License is distributed on an |
| * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY |
| * KIND, either express or implied. See the License for the |
| * specific language governing permissions and limitations |
| * under the License. |
| * |
| *************************************************************/ |
| |
| |
| |
| // MARKER(update_precomp.py): autogen include statement, do not remove |
| #include "precompiled_svx.hxx" |
| |
| #include <vector> |
| #include <vos/mutex.hxx> |
| #include <com/sun/star/io/XOutputStream.hpp> |
| #include <com/sun/star/container/XChild.hpp> |
| #include <com/sun/star/frame/XModel.hpp> |
| #include <com/sun/star/document/XFilter.hpp> |
| #include <com/sun/star/document/XExporter.hpp> |
| #include <com/sun/star/document/XMimeTypeInfo.hpp> |
| #include <com/sun/star/lang/XServiceInfo.hpp> |
| #include <com/sun/star/lang/XComponent.hpp> |
| #include <com/sun/star/drawing/XShape.hpp> |
| #include <com/sun/star/drawing/XDrawPage.hpp> |
| #include <com/sun/star/graphic/XGraphic.hpp> |
| #include <com/sun/star/graphic/XGraphicRenderer.hpp> |
| #include <com/sun/star/task/XStatusIndicator.hpp> |
| #include <com/sun/star/task/XInteractionHandler.hpp> |
| #include <com/sun/star/task/XInteractionContinuation.hpp> |
| |
| #include <comphelper/interaction.hxx> |
| #include <framework/interaction.hxx> |
| #include <com/sun/star/drawing/GraphicFilterRequest.hpp> |
| #include <com/sun/star/util/URL.hpp> |
| #include <cppuhelper/implbase4.hxx> |
| #include <osl/diagnose.h> |
| #include <osl/mutex.hxx> |
| #include <vcl/metaact.hxx> |
| #include <vcl/svapp.hxx> |
| #include <vcl/virdev.hxx> |
| #include <svtools/FilterConfigItem.hxx> |
| #include <svl/outstrm.hxx> |
| #include <svx/sdr/contact/objectcontactofobjlistpainter.hxx> |
| #include <svx/sdr/contact/viewobjectcontact.hxx> |
| #include <svx/sdr/contact/viewcontact.hxx> |
| #include <svx/sdr/contact/displayinfo.hxx> |
| #include <svx/sdr/contact/viewcontactofsdrobj.hxx> |
| #include <editeng/numitem.hxx> |
| #include <svx/svdpagv.hxx> |
| #include <svx/svdograf.hxx> |
| #include "svx/xoutbmp.hxx" |
| #include "svtools/filter.hxx" |
| #include "svx/unoapi.hxx" |
| #include <svx/svdpage.hxx> |
| #include <svx/svdmodel.hxx> |
| #include <svx/fmview.hxx> |
| #include <svx/fmmodel.hxx> |
| #include <svx/unopage.hxx> |
| #include <svx/pageitem.hxx> |
| #include <editeng/eeitem.hxx> |
| #include <svx/svdoutl.hxx> |
| #include <editeng/flditem.hxx> |
| |
| #include "boost/scoped_ptr.hpp" |
| |
| #define MAX_EXT_PIX 2048 |
| |
| using namespace ::comphelper; |
| using namespace ::osl; |
| using namespace ::vos; |
| using ::rtl::OUString; |
| using namespace ::cppu; |
| using namespace ::com::sun::star; |
| using namespace ::com::sun::star::uno; |
| using namespace ::com::sun::star::util; |
| using namespace ::com::sun::star::container; |
| using namespace ::com::sun::star::drawing; |
| using namespace ::com::sun::star::lang; |
| using namespace ::com::sun::star::document; |
| using namespace ::com::sun::star::frame; |
| using namespace ::com::sun::star::beans; |
| using namespace ::com::sun::star::task; |
| #include <svx/sdr/contact/viewobjectcontactredirector.hxx> |
| #include <svx/sdr/contact/viewobjectcontact.hxx> |
| #include <svx/sdr/contact/viewcontact.hxx> |
| |
| // #i102251# |
| #include <editeng/editstat.hxx> |
| |
| ////////////////////////////////////////////////////////////////////////////// |
| |
| namespace svx |
| { |
| struct ExportSettings |
| { |
| OUString maFilterName; |
| OUString maMediaType; |
| URL maURL; |
| com::sun::star::uno::Reference< com::sun::star::io::XOutputStream > mxOutputStream; |
| com::sun::star::uno::Reference< com::sun::star::graphic::XGraphicRenderer > mxGraphicRenderer; |
| com::sun::star::uno::Reference< com::sun::star::task::XStatusIndicator > mxStatusIndicator; |
| com::sun::star::uno::Reference< com::sun::star::task::XInteractionHandler > mxInteractionHandler; |
| |
| sal_Int32 mnWidth; |
| sal_Int32 mnHeight; |
| sal_Bool mbExportOnlyBackground; |
| sal_Bool mbVerboseComments; |
| sal_Bool mbScrollText; |
| sal_Bool mbUseHighContrast; |
| sal_Bool mbTranslucent; |
| |
| Sequence< PropertyValue > maFilterData; |
| |
| Fraction maScaleX; |
| Fraction maScaleY; |
| |
| ExportSettings( SdrModel* pDoc ); |
| }; |
| |
| ExportSettings::ExportSettings( SdrModel* pDoc ) |
| : mnWidth( 0 ) |
| , mnHeight( 0 ) |
| , mbExportOnlyBackground( false ) |
| , mbVerboseComments( false ) |
| , mbScrollText( false ) |
| , mbUseHighContrast( false ) |
| , mbTranslucent( sal_False ) |
| , maScaleX( 1, 1 ) |
| , maScaleY( 1, 1 ) |
| { |
| if( pDoc ) |
| { |
| maScaleX = pDoc->GetScaleFraction(); |
| maScaleY = pDoc->GetScaleFraction(); |
| } |
| } |
| |
| /** implements a component to export shapes or pages to external graphic formats. |
| |
| @implements com.sun.star.drawing.GraphicExportFilter |
| */ |
| class GraphicExporter : public WeakImplHelper4< XFilter, XExporter, XServiceInfo, XMimeTypeInfo > |
| { |
| public: |
| GraphicExporter(); |
| virtual ~GraphicExporter(); |
| |
| // XFilter |
| virtual sal_Bool SAL_CALL filter( const Sequence< PropertyValue >& aDescriptor ) throw(RuntimeException); |
| virtual void SAL_CALL cancel( ) throw(RuntimeException); |
| |
| // XExporter |
| virtual void SAL_CALL setSourceDocument( const Reference< XComponent >& xDoc ) throw(IllegalArgumentException, RuntimeException); |
| |
| // XServiceInfo |
| virtual OUString SAL_CALL getImplementationName( ) throw(RuntimeException); |
| virtual sal_Bool SAL_CALL supportsService( const OUString& ServiceName ) throw(RuntimeException); |
| virtual Sequence< OUString > SAL_CALL getSupportedServiceNames( ) throw(RuntimeException); |
| |
| // XMimeTypeInfo |
| virtual sal_Bool SAL_CALL supportsMimeType( const ::rtl::OUString& MimeTypeName ) throw (RuntimeException); |
| virtual Sequence< OUString > SAL_CALL getSupportedMimeTypeNames( ) throw (RuntimeException); |
| |
| VirtualDevice* CreatePageVDev( SdrPage* pPage, sal_uIntPtr nWidthPixel, sal_uIntPtr nHeightPixel ) const; |
| |
| DECL_LINK( CalcFieldValueHdl, EditFieldInfo* ); |
| |
| void ParseSettings( const Sequence< PropertyValue >& aDescriptor, ExportSettings& rSettings ); |
| bool GetGraphic( ExportSettings& rSettings, Graphic& aGraphic, sal_Bool bVectorType ); |
| |
| private: |
| Reference< XShape > mxShape; |
| Reference< XDrawPage > mxPage; |
| Reference< XShapes > mxShapes; |
| |
| SvxDrawPage* mpUnoPage; |
| |
| Link maOldCalcFieldValueHdl; |
| sal_Int32 mnPageNumber; |
| SdrPage* mpCurrentPage; |
| SdrModel* mpDoc; |
| }; |
| |
| SVX_DLLPUBLIC Reference< XInterface > SAL_CALL GraphicExporter_createInstance(const Reference< XMultiServiceFactory > & ) |
| throw( Exception ) |
| { |
| return (XWeak*)new GraphicExporter(); |
| } |
| |
| SVX_DLLPUBLIC Sequence< OUString > SAL_CALL GraphicExporter_getSupportedServiceNames() |
| throw() |
| { |
| Sequence< OUString > aSupportedServiceNames( 1 ); |
| aSupportedServiceNames[0] = OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.drawing.GraphicExportFilter" ) ); |
| return aSupportedServiceNames; |
| } |
| |
| SVX_DLLPUBLIC OUString SAL_CALL GraphicExporter_getImplementationName() |
| throw() |
| { |
| return OUString( RTL_CONSTASCII_USTRINGPARAM( "com.sun.star.comp.Draw.GraphicExporter" ) ); |
| } |
| |
| /** creates a bitmap that is optionaly transparent from a metafile |
| */ |
| BitmapEx GetBitmapFromMetaFile( const GDIMetaFile& rMtf, sal_Bool bTransparent, const Size* pSize ) |
| { |
| BitmapEx aBmpEx; |
| |
| if(bTransparent) |
| { |
| // use new primitive conversion tooling |
| basegfx::B2DRange aRange(basegfx::B2DPoint(0.0, 0.0)); |
| sal_uInt32 nMaximumQuadraticPixels(500000); |
| |
| if(pSize) |
| { |
| // use 100th mm for primitive bitmap converter tool, input is pixel |
| // use a real OutDev to get the correct DPI, the static LogicToLogic assumes 72dpi which is wrong (!) |
| const Size aSize100th(Application::GetDefaultDevice()->PixelToLogic(*pSize, MapMode(MAP_100TH_MM))); |
| |
| aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height())); |
| |
| // when explicitely pixels are requested from the GraphicExporter, use a *very* high limit |
| // of 16gb (4096x4096 pixels), else use the default for the converters |
| nMaximumQuadraticPixels = std::min(sal_uInt32(4096 * 4096), sal_uInt32(pSize->Width() * pSize->Height())); |
| } |
| else |
| { |
| // use 100th mm for primitive bitmap converter tool |
| const Size aSize100th(Application::GetDefaultDevice()->LogicToLogic(rMtf.GetPrefSize(), rMtf.GetPrefMapMode(), MapMode(MAP_100TH_MM))); |
| |
| aRange.expand(basegfx::B2DPoint(aSize100th.Width(), aSize100th.Height())); |
| } |
| |
| aBmpEx = convertMetafileToBitmapEx(rMtf, aRange, nMaximumQuadraticPixels); |
| } |
| else |
| { |
| const SvtOptionsDrawinglayer aDrawinglayerOpt; |
| Size aTargetSize(0, 0); |
| |
| if(pSize) |
| { |
| // #122820# If a concrete target size in pixels is given, use it |
| aTargetSize = *pSize; |
| |
| // get hairline and full bound rect to evtl. reduce given target pixel size when |
| // it is known that it will be expanded to get the right and bottom hairlines right |
| Rectangle aHairlineRect; |
| const Rectangle aRect(rMtf.GetBoundRect(*Application::GetDefaultDevice(), &aHairlineRect)); |
| |
| if(!aRect.IsEmpty() && !aHairlineRect.IsEmpty()) |
| { |
| if(aRect.Right() == aHairlineRect.Right() || aRect.Bottom() == aHairlineRect.Bottom()) |
| { |
| if(aTargetSize.Width()) |
| { |
| aTargetSize.Width() -= 1; |
| } |
| |
| if(aTargetSize.Height()) |
| { |
| aTargetSize.Height() -= 1; |
| } |
| } |
| } |
| } |
| |
| const GraphicConversionParameters aParameters( |
| aTargetSize, |
| true, // allow unlimited size |
| aDrawinglayerOpt.IsAntiAliasing(), |
| aDrawinglayerOpt.IsSnapHorVerLinesToDiscrete()); |
| const Graphic aGraphic(rMtf); |
| |
| aBmpEx = BitmapEx(aGraphic.GetBitmap(aParameters)); |
| aBmpEx.SetPrefMapMode( rMtf.GetPrefMapMode() ); |
| aBmpEx.SetPrefSize( rMtf.GetPrefSize() ); |
| } |
| |
| return aBmpEx; |
| } |
| |
| Size* CalcSize( sal_Int32 nWidth, sal_Int32 nHeight, const Size& aBoundSize, Size& aOutSize ) |
| { |
| if( (nWidth == 0) && (nHeight == 0) ) |
| return NULL; |
| |
| if( (nWidth == 0) && (nHeight != 0) && (aBoundSize.Height() != 0) ) |
| { |
| nWidth = ( nHeight * aBoundSize.Width() ) / aBoundSize.Height(); |
| } |
| else if( (nWidth != 0) && (nHeight == 0) && (aBoundSize.Width() != 0) ) |
| { |
| nHeight = ( nWidth * aBoundSize.Height() ) / aBoundSize.Width(); |
| } |
| |
| aOutSize.Width() = nWidth; |
| aOutSize.Height() = nHeight; |
| |
| return &aOutSize; |
| } |
| } |
| |
| class ImplExportCheckVisisbilityRedirector : public ::sdr::contact::ViewObjectContactRedirector |
| { |
| public: |
| ImplExportCheckVisisbilityRedirector( SdrPage* pCurrentPage ); |
| virtual ~ImplExportCheckVisisbilityRedirector(); |
| |
| virtual drawinglayer::primitive2d::Primitive2DSequence createRedirectedPrimitive2DSequence( |
| const sdr::contact::ViewObjectContact& rOriginal, |
| const sdr::contact::DisplayInfo& rDisplayInfo); |
| |
| private: |
| SdrPage* mpCurrentPage; |
| }; |
| |
| ImplExportCheckVisisbilityRedirector::ImplExportCheckVisisbilityRedirector( SdrPage* pCurrentPage ) |
| : ViewObjectContactRedirector(), mpCurrentPage( pCurrentPage ) |
| { |
| } |
| |
| ImplExportCheckVisisbilityRedirector::~ImplExportCheckVisisbilityRedirector() |
| { |
| } |
| |
| drawinglayer::primitive2d::Primitive2DSequence ImplExportCheckVisisbilityRedirector::createRedirectedPrimitive2DSequence( |
| const sdr::contact::ViewObjectContact& rOriginal, |
| const sdr::contact::DisplayInfo& rDisplayInfo) |
| { |
| SdrObject* pObject = rOriginal.GetViewContact().TryToGetSdrObject(); |
| |
| if(pObject) |
| { |
| SdrPage* pPage = mpCurrentPage; |
| if( pPage == 0 ) |
| pPage = pObject->GetPage(); |
| |
| if( (pPage == 0) || pPage->checkVisibility(rOriginal, rDisplayInfo, false) ) |
| { |
| return ::sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo); |
| } |
| |
| return drawinglayer::primitive2d::Primitive2DSequence(); |
| } |
| else |
| { |
| // not an object, maybe a page |
| return ::sdr::contact::ViewObjectContactRedirector::createRedirectedPrimitive2DSequence(rOriginal, rDisplayInfo); |
| } |
| } |
| |
| using namespace ::svx; |
| |
| GraphicExporter::GraphicExporter() |
| : mpUnoPage( NULL ), mnPageNumber(-1), mpCurrentPage(0), mpDoc( NULL ) |
| { |
| } |
| |
| GraphicExporter::~GraphicExporter() |
| { |
| } |
| |
| IMPL_LINK(GraphicExporter, CalcFieldValueHdl, EditFieldInfo*, pInfo) |
| { |
| if( pInfo ) |
| { |
| if( mpCurrentPage ) |
| { |
| pInfo->SetSdrPage( mpCurrentPage ); |
| } |
| else if( mnPageNumber != -1 ) |
| { |
| const SvxFieldData* pField = pInfo->GetField().GetField(); |
| if( pField && pField->ISA( SvxPageField ) ) |
| { |
| String aPageNumValue; |
| sal_Bool bUpper = sal_False; |
| |
| switch(mpDoc->GetPageNumType()) |
| { |
| case SVX_CHARS_UPPER_LETTER: |
| aPageNumValue += (sal_Unicode)(char)((mnPageNumber - 1) % 26 + 'A'); |
| break; |
| case SVX_CHARS_LOWER_LETTER: |
| aPageNumValue += (sal_Unicode)(char)((mnPageNumber - 1) % 26 + 'a'); |
| break; |
| case SVX_ROMAN_UPPER: |
| bUpper = sal_True; |
| case SVX_ROMAN_LOWER: |
| aPageNumValue += SvxNumberFormat::CreateRomanString(mnPageNumber, bUpper); |
| break; |
| case SVX_NUMBER_NONE: |
| aPageNumValue.Erase(); |
| aPageNumValue += sal_Unicode(' '); |
| break; |
| default: |
| aPageNumValue += String::CreateFromInt32( (sal_Int32)mnPageNumber ); |
| } |
| |
| pInfo->SetRepresentation( aPageNumValue ); |
| |
| return(0); |
| } |
| } |
| } |
| |
| long nRet = maOldCalcFieldValueHdl.Call( pInfo ); |
| |
| if( pInfo && mpCurrentPage ) |
| pInfo->SetSdrPage( 0 ); |
| |
| return nRet; |
| } |
| |
| /** creates an virtual device for the given page |
| |
| @return the returned VirtualDevice is owned by the caller |
| */ |
| VirtualDevice* GraphicExporter::CreatePageVDev( SdrPage* pPage, sal_uIntPtr nWidthPixel, sal_uIntPtr nHeightPixel ) const |
| { |
| VirtualDevice* pVDev = new VirtualDevice(); |
| MapMode aMM( MAP_100TH_MM ); |
| |
| Point aPoint( 0, 0 ); |
| Size aPageSize(pPage->GetSize()); |
| |
| // use scaling? |
| if( nWidthPixel ) |
| { |
| const Fraction aFrac( (long) nWidthPixel, pVDev->LogicToPixel( aPageSize, aMM ).Width() ); |
| |
| aMM.SetScaleX( aFrac ); |
| |
| if( nHeightPixel == 0 ) |
| aMM.SetScaleY( aFrac ); |
| } |
| |
| if( nHeightPixel ) |
| { |
| const Fraction aFrac( (long) nHeightPixel, pVDev->LogicToPixel( aPageSize, aMM ).Height() ); |
| |
| if( nWidthPixel == 0 ) |
| aMM.SetScaleX( aFrac ); |
| |
| aMM.SetScaleY( aFrac ); |
| } |
| |
| pVDev->SetMapMode( aMM ); |
| bool bSuccess(false); |
| |
| // #122820# If available, use pixel size directly |
| if(nWidthPixel && nHeightPixel) |
| { |
| bSuccess = pVDev->SetOutputSizePixel(Size(nWidthPixel, nHeightPixel)); |
| } |
| else |
| { |
| bSuccess = pVDev->SetOutputSize(aPageSize); |
| } |
| |
| if(bSuccess) |
| { |
| SdrView* pView = new SdrView(mpDoc, pVDev); |
| pView->SetPageVisible( sal_False ); |
| pView->SetBordVisible( sal_False ); |
| pView->SetGridVisible( sal_False ); |
| pView->SetHlplVisible( sal_False ); |
| pView->SetGlueVisible( sal_False ); |
| pView->ShowSdrPage(pPage); |
| Region aRegion (Rectangle( aPoint, aPageSize ) ); |
| |
| ImplExportCheckVisisbilityRedirector aRedirector( mpCurrentPage ); |
| |
| pView->CompleteRedraw(pVDev, aRegion, &aRedirector); |
| delete pView; |
| } |
| else |
| { |
| OSL_ENSURE(false, "Could not get a VirtualDevice of requested size (!)"); |
| } |
| |
| return pVDev; |
| } |
| |
| void GraphicExporter::ParseSettings( const Sequence< PropertyValue >& aDescriptor, ExportSettings& rSettings ) |
| { |
| sal_Int32 nArgs = aDescriptor.getLength(); |
| const PropertyValue* pValues = aDescriptor.getConstArray(); |
| while( nArgs-- ) |
| { |
| if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FilterName" ) ) ) |
| { |
| pValues->Value >>= rSettings.maFilterName; |
| } |
| else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "MediaType" ) ) ) |
| { |
| pValues->Value >>= rSettings.maMediaType; |
| } |
| else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "URL" ) ) ) |
| { |
| if( !( pValues->Value >>= rSettings.maURL ) ) |
| { |
| pValues->Value >>= rSettings.maURL.Complete; |
| } |
| } |
| else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "OutputStream" ) ) ) |
| { |
| pValues->Value >>= rSettings.mxOutputStream; |
| } |
| else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "GraphicRenderer" ) ) ) |
| { |
| pValues->Value >>= rSettings.mxGraphicRenderer; |
| } |
| else if ( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "StatusIndicator" ) ) ) |
| { |
| pValues->Value >>= rSettings.mxStatusIndicator; |
| } |
| else if ( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "InteractionHandler" ) ) ) |
| { |
| pValues->Value >>= rSettings.mxInteractionHandler; |
| } |
| else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Width" ) ) ) // for compatibility reasons, deprecated |
| { |
| pValues->Value >>= rSettings.mnWidth; |
| } |
| else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Height" ) ) ) // for compatibility reasons, deprecated |
| { |
| pValues->Value >>= rSettings.mnHeight; |
| } |
| else if( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ExportOnlyBackground" ) ) ) // for compatibility reasons, deprecated |
| { |
| pValues->Value >>= rSettings.mbExportOnlyBackground; |
| } |
| else if ( pValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "FilterData" ) ) ) |
| { |
| pValues->Value >>= rSettings.maFilterData; |
| |
| sal_Int32 nFilterArgs = rSettings.maFilterData.getLength(); |
| PropertyValue* pDataValues = rSettings.maFilterData.getArray(); |
| while( nFilterArgs-- ) |
| { |
| if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Translucent" ) ) ) |
| { |
| if ( !( pDataValues->Value >>= rSettings.mbTranslucent ) ) // SJ: TODO: The GIF Transparency is stored as int32 in |
| { // configuration files, this has to be changed to boolean |
| sal_Int32 nTranslucent = 0; |
| if ( pDataValues->Value >>= nTranslucent ) |
| rSettings.mbTranslucent = nTranslucent != 0; |
| } |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PixelWidth" ) ) ) |
| { |
| pDataValues->Value >>= rSettings.mnWidth; |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PixelHeight" ) ) ) |
| { |
| pDataValues->Value >>= rSettings.mnHeight; |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Width" ) ) ) // for compatibility reasons, deprecated |
| { |
| pDataValues->Value >>= rSettings.mnWidth; |
| pDataValues->Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PixelWidth" ) ); |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "Height" ) ) ) // for compatibility reasons, deprecated |
| { |
| pDataValues->Value >>= rSettings.mnHeight; |
| pDataValues->Name = OUString( RTL_CONSTASCII_USTRINGPARAM( "PixelHeight" ) ); |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ExportOnlyBackground" ) ) ) |
| { |
| pDataValues->Value >>= rSettings.mbExportOnlyBackground; |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "HighContrast" ) ) ) |
| { |
| pDataValues->Value >>= rSettings.mbUseHighContrast; |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "PageNumber" ) ) ) |
| { |
| pDataValues->Value >>= mnPageNumber; |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "VerboseComments" ) ) ) |
| { |
| // #110496# Read flag for verbose metafile comments |
| pDataValues->Value >>= rSettings.mbVerboseComments; |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScrollText" ) ) ) |
| { |
| // #110496# Read flag solitary scroll text metafile |
| pDataValues->Value >>= rSettings.mbScrollText; |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "CurrentPage" ) ) ) |
| { |
| Reference< XDrawPage > xPage; |
| pDataValues->Value >>= xPage; |
| if( xPage.is() ) |
| { |
| SvxDrawPage* pUnoPage = SvxDrawPage::getImplementation( xPage ); |
| if( pUnoPage && pUnoPage->GetSdrPage() ) |
| mpCurrentPage = pUnoPage->GetSdrPage(); |
| } |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScaleXNumerator" ) ) ) |
| { |
| sal_Int32 nVal = 1; |
| if( pDataValues->Value >>= nVal ) |
| rSettings.maScaleX = Fraction( nVal, rSettings.maScaleX.GetDenominator() ); |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScaleXDenominator" ) ) ) |
| { |
| sal_Int32 nVal = 1; |
| if( pDataValues->Value >>= nVal ) |
| rSettings.maScaleX = Fraction( rSettings.maScaleX.GetNumerator(), nVal ); |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScaleYNumerator" ) ) ) |
| { |
| sal_Int32 nVal = 1; |
| if( pDataValues->Value >>= nVal ) |
| rSettings.maScaleY = Fraction( nVal, rSettings.maScaleY.GetDenominator() ); |
| } |
| else if( pDataValues->Name.equalsAsciiL( RTL_CONSTASCII_STRINGPARAM( "ScaleYDenominator" ) ) ) |
| { |
| sal_Int32 nVal = 1; |
| if( pDataValues->Value >>= nVal ) |
| rSettings.maScaleY = Fraction( rSettings.maScaleY.GetNumerator(), nVal ); |
| } |
| |
| pDataValues++; |
| } |
| } |
| |
| pValues++; |
| } |
| |
| // putting the StatusIndicator that we got from the MediaDescriptor into our local FilterData copy |
| if ( rSettings.mxStatusIndicator.is() ) |
| { |
| rtl::OUString sStatusIndicator( RTL_CONSTASCII_USTRINGPARAM( "StatusIndicator" ) ); |
| int i = rSettings.maFilterData.getLength(); |
| rSettings.maFilterData.realloc( i + 1 ); |
| rSettings.maFilterData[ i ].Name = sStatusIndicator; |
| rSettings.maFilterData[ i ].Value <<= rSettings.mxStatusIndicator; |
| } |
| } |
| |
| bool GraphicExporter::GetGraphic( ExportSettings& rSettings, Graphic& aGraphic, sal_Bool bVectorType ) |
| { |
| if( !mpDoc || !mpUnoPage ) |
| return false; |
| |
| SdrPage* pPage = mpUnoPage->GetSdrPage(); |
| if( !pPage ) |
| return false; |
| |
| VirtualDevice aVDev; |
| const MapMode aMap( mpDoc->GetScaleUnit(), Point(), rSettings.maScaleX, rSettings.maScaleY ); |
| |
| SdrOutliner& rOutl=mpDoc->GetDrawOutliner(NULL); |
| maOldCalcFieldValueHdl = rOutl.GetCalcFieldValueHdl(); |
| rOutl.SetCalcFieldValueHdl( LINK(this, GraphicExporter, CalcFieldValueHdl) ); |
| rOutl.SetBackgroundColor( pPage->GetPageBackgroundColor() ); |
| |
| // #i102251# |
| const sal_uInt32 nOldCntrl(rOutl.GetControlWord()); |
| sal_uInt32 nCntrl = nOldCntrl & ~EE_CNTRL_ONLINESPELLING; |
| rOutl.SetControlWord(nCntrl); |
| |
| SdrObject* pTempBackgroundShape = 0; |
| std::vector< SdrObject* > aShapes; |
| bool bRet = true; |
| |
| // export complete page? |
| if ( !mxShape.is() ) |
| { |
| if( rSettings.mbExportOnlyBackground ) |
| { |
| const SdrPageProperties* pCorrectProperties = pPage->getCorrectSdrPageProperties(); |
| |
| if(pCorrectProperties) |
| { |
| pTempBackgroundShape = new SdrRectObj(Rectangle(Point(0,0), pPage->GetSize())); |
| pTempBackgroundShape->SetMergedItemSet(pCorrectProperties->GetItemSet()); |
| pTempBackgroundShape->SetMergedItem(XLineStyleItem(XLINE_NONE)); |
| pTempBackgroundShape->NbcSetStyleSheet(pCorrectProperties->GetStyleSheet(), true); |
| aShapes.push_back(pTempBackgroundShape); |
| } |
| } |
| else |
| { |
| const Size aSize( pPage->GetSize() ); |
| |
| // generate a bitmap to convert it to a pixel format. |
| // For gif pictures there can also be a vector format used (bTranslucent) |
| if ( !bVectorType && !rSettings.mbTranslucent ) |
| { |
| long nWidthPix = 0; |
| long nHeightPix = 0; |
| if ( rSettings.mnWidth > 0 && rSettings.mnHeight > 0 ) |
| { |
| nWidthPix = rSettings.mnWidth; |
| nHeightPix = rSettings.mnHeight; |
| } |
| else |
| { |
| const Size aSizePix( Application::GetDefaultDevice()->LogicToPixel( aSize, aMap ) ); |
| if (aSizePix.Width() > MAX_EXT_PIX || aSizePix.Height() > MAX_EXT_PIX) |
| { |
| if (aSizePix.Width() > MAX_EXT_PIX) |
| nWidthPix = MAX_EXT_PIX; |
| else |
| nWidthPix = aSizePix.Width(); |
| if (aSizePix.Height() > MAX_EXT_PIX) |
| nHeightPix = MAX_EXT_PIX; |
| else |
| nHeightPix = aSizePix.Height(); |
| |
| double fWidthDif = aSizePix.Width() / nWidthPix; |
| double fHeightDif = aSizePix.Height() / nHeightPix; |
| |
| if (fWidthDif > fHeightDif) |
| nHeightPix = static_cast<long>(aSizePix.Height() / fWidthDif); |
| else |
| nWidthPix = static_cast<long>(aSizePix.Width() / fHeightDif); |
| } |
| else |
| { |
| nWidthPix = aSizePix.Width(); |
| nHeightPix = aSizePix.Height(); |
| } |
| } |
| |
| boost::scoped_ptr< SdrView > pLocalView; |
| if( PTR_CAST( FmFormModel, mpDoc ) ) |
| { |
| pLocalView.reset( new FmFormView( PTR_CAST( FmFormModel, mpDoc ), &aVDev ) ); |
| } |
| else |
| { |
| pLocalView.reset( new SdrView( mpDoc, &aVDev ) ); |
| } |
| |
| |
| VirtualDevice* pVDev = CreatePageVDev( pPage, nWidthPix, nHeightPix ); |
| |
| if( pVDev ) |
| { |
| aGraphic = pVDev->GetBitmap( Point(), pVDev->GetOutputSize() ); |
| aGraphic.SetPrefMapMode( aMap ); |
| aGraphic.SetPrefSize( aSize ); |
| delete pVDev; |
| } |
| } |
| // create a metafile to export a vector format |
| else |
| { |
| GDIMetaFile aMtf; |
| |
| aVDev.SetMapMode( aMap ); |
| if( rSettings.mbUseHighContrast ) |
| aVDev.SetDrawMode( aVDev.GetDrawMode() | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT ); |
| aVDev.EnableOutput( sal_False ); |
| aMtf.Record( &aVDev ); |
| Size aNewSize; |
| |
| // create a view |
| SdrView* pView; |
| |
| if( PTR_CAST( FmFormModel, mpDoc ) ) |
| { |
| pView = new FmFormView( PTR_CAST( FmFormModel, mpDoc ), &aVDev ); |
| } |
| else |
| { |
| pView = new SdrView( mpDoc, &aVDev ); |
| } |
| |
| pView->SetBordVisible( sal_False ); |
| pView->SetPageVisible( sal_False ); |
| pView->ShowSdrPage( pPage ); |
| |
| if ( pView && pPage ) |
| { |
| pView->SetBordVisible( sal_False ); |
| pView->SetPageVisible( sal_False ); |
| pView->ShowSdrPage( pPage ); |
| |
| const Point aNewOrg( pPage->GetLftBorder(), pPage->GetUppBorder() ); |
| aNewSize = Size( aSize.Width() - pPage->GetLftBorder() - pPage->GetRgtBorder(), |
| aSize.Height() - pPage->GetUppBorder() - pPage->GetLwrBorder() ); |
| const Rectangle aClipRect( aNewOrg, aNewSize ); |
| MapMode aVMap( aMap ); |
| |
| aVDev.Push(); |
| aVMap.SetOrigin( Point( -aNewOrg.X(), -aNewOrg.Y() ) ); |
| aVDev.SetRelativeMapMode( aVMap ); |
| aVDev.IntersectClipRegion( aClipRect ); |
| |
| // Use new StandardCheckVisisbilityRedirector |
| ImplExportCheckVisisbilityRedirector aRedirector( mpCurrentPage ); |
| |
| pView->CompleteRedraw(&aVDev, Region(Rectangle(Point(), aNewSize)), &aRedirector); |
| |
| aVDev.Pop(); |
| |
| aMtf.Stop(); |
| aMtf.WindStart(); |
| aMtf.SetPrefMapMode( aMap ); |
| aMtf.SetPrefSize( aNewSize ); |
| |
| // AW: Here the current version was filtering out the META_CLIPREGION_ACTIONs |
| // from the metafile. I asked some other developers why this was done, but no |
| // one knew a direct reason. Since it's in for long time, it may be an old |
| // piece of code. MetaFiles save and load ClipRegions with polygons with preserving |
| // the polygons, so a resolution-indepent roundtrip is supported. Removed this |
| // code since it destroys some MetaFiles where ClipRegions are used. Anyways, |
| // just filtering them out is a hack, at least the encapsulated content would need |
| // to be clipped geometrically. |
| aGraphic = Graphic(aMtf); |
| } |
| |
| if ( pView ) |
| { |
| pView->HideSdrPage(); |
| delete pView; |
| } |
| |
| if( rSettings.mbTranslucent ) |
| { |
| Size aOutSize; |
| aGraphic = GetBitmapFromMetaFile( aGraphic.GetGDIMetaFile(), sal_True, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aNewSize, aOutSize ) ); |
| } |
| } |
| } |
| } |
| |
| // export only single shape or shape collection |
| else |
| { |
| // build list of SdrObject |
| if( mxShapes.is() ) |
| { |
| Reference< XShape > xShape; |
| const sal_Int32 nCount = mxShapes->getCount(); |
| |
| for( sal_Int32 nIndex = 0; nIndex < nCount; nIndex++ ) |
| { |
| mxShapes->getByIndex( nIndex ) >>= xShape; |
| SdrObject* pObj = GetSdrObjectFromXShape( xShape ); |
| if( pObj ) |
| aShapes.push_back( pObj ); |
| } |
| } |
| else |
| { |
| // only one shape |
| SdrObject* pObj = GetSdrObjectFromXShape( mxShape ); |
| if( pObj ) |
| aShapes.push_back( pObj ); |
| } |
| |
| if( aShapes.empty() ) |
| bRet = false; |
| } |
| |
| if( bRet && !aShapes.empty() ) |
| { |
| // special treatment for only one SdrGrafObj that has text |
| sal_Bool bSingleGraphic = sal_False; |
| |
| if( 1 == aShapes.size() ) |
| { |
| if( !bVectorType ) |
| { |
| SdrObject* pObj = aShapes.front(); |
| if( pObj && pObj->ISA( SdrGrafObj ) && !( (SdrGrafObj*) pObj )->HasText() ) |
| { |
| aGraphic = ( (SdrGrafObj*) pObj )->GetTransformedGraphic(); |
| if ( aGraphic.GetType() == GRAPHIC_BITMAP ) |
| { |
| Size aSizePixel( aGraphic.GetSizePixel() ); |
| if( rSettings.mnWidth && rSettings.mnHeight && |
| ( ( rSettings.mnWidth != aSizePixel.Width() ) || |
| ( rSettings.mnHeight != aSizePixel.Height() ) ) ) |
| { |
| BitmapEx aBmpEx( aGraphic.GetBitmapEx() ); |
| // export: use highest quality |
| aBmpEx.Scale( Size( rSettings.mnWidth, rSettings.mnHeight ), BMP_SCALE_LANCZOS ); |
| aGraphic = aBmpEx; |
| } |
| |
| // #118804# only accept for bitmap graphics, else the |
| // conversion to bitmap will happen anywhere without size control |
| // as evtl. defined in rSettings.mnWidth/mnHeight |
| bSingleGraphic = sal_True; |
| } |
| } |
| } |
| else if( rSettings.mbScrollText ) |
| { |
| SdrObject* pObj = aShapes.front(); |
| if( pObj && pObj->ISA( SdrTextObj ) |
| && ( (SdrTextObj*) pObj )->HasText() ) |
| { |
| Rectangle aScrollRectangle; |
| Rectangle aPaintRectangle; |
| |
| const boost::scoped_ptr< GDIMetaFile > pMtf( |
| ( (SdrTextObj*) pObj )->GetTextScrollMetaFileAndRectangle( |
| aScrollRectangle, aPaintRectangle ) ); |
| |
| // take the larger one of the two rectangles (that |
| // should be the bound rect of the retrieved |
| // metafile) |
| Rectangle aTextRect; |
| |
| if( aScrollRectangle.IsInside( aPaintRectangle ) ) |
| aTextRect = aScrollRectangle; |
| else |
| aTextRect = aPaintRectangle; |
| |
| // setup pref size and mapmode |
| pMtf->SetPrefSize( aTextRect.GetSize() ); |
| |
| // set actual origin (mtf is at actual shape |
| // output position) |
| MapMode aLocalMapMode( aMap ); |
| aLocalMapMode.SetOrigin( |
| Point( -aPaintRectangle.Left(), |
| -aPaintRectangle.Top() ) ); |
| pMtf->SetPrefMapMode( aLocalMapMode ); |
| |
| pMtf->AddAction( new MetaCommentAction( |
| "XTEXT_SCROLLRECT", 0, |
| reinterpret_cast<sal_uInt8 const*>(&aScrollRectangle), |
| sizeof( Rectangle ) ) ); |
| pMtf->AddAction( new MetaCommentAction( |
| "XTEXT_PAINTRECT", 0, |
| reinterpret_cast<sal_uInt8 const*>(&aPaintRectangle), |
| sizeof( Rectangle ) ) ); |
| |
| aGraphic = Graphic( *pMtf ); |
| |
| bSingleGraphic = sal_True; |
| } |
| } |
| } |
| |
| if( !bSingleGraphic ) |
| { |
| // create a metafile for all shapes |
| VirtualDevice aOut; |
| |
| // calculate bound rect for all shapes |
| Rectangle aBound; |
| |
| { |
| std::vector< SdrObject* >::iterator aIter = aShapes.begin(); |
| const std::vector< SdrObject* >::iterator aEnd = aShapes.end(); |
| |
| while( aIter != aEnd ) |
| { |
| SdrObject* pObj = (*aIter++); |
| Rectangle aR1(pObj->GetCurrentBoundRect()); |
| if (aBound.IsEmpty()) |
| aBound=aR1; |
| else |
| aBound.Union(aR1); |
| } |
| } |
| |
| aOut.EnableOutput( sal_False ); |
| aOut.SetMapMode( aMap ); |
| if( rSettings.mbUseHighContrast ) |
| aOut.SetDrawMode( aVDev.GetDrawMode() | DRAWMODE_SETTINGSLINE | DRAWMODE_SETTINGSFILL | DRAWMODE_SETTINGSTEXT | DRAWMODE_SETTINGSGRADIENT ); |
| |
| GDIMetaFile aMtf; |
| aMtf.Clear(); |
| aMtf.Record( &aOut ); |
| |
| MapMode aOutMap( aMap ); |
| aOutMap.SetOrigin( Point( -aBound.TopLeft().X(), -aBound.TopLeft().Y() ) ); |
| aOut.SetRelativeMapMode( aOutMap ); |
| |
| sdr::contact::DisplayInfo aDisplayInfo; |
| |
| if(mpCurrentPage) |
| { |
| if(mpCurrentPage->TRG_HasMasterPage() && pPage->IsMasterPage()) |
| { |
| // MasterPage is processed as another page's SubContent |
| aDisplayInfo.SetProcessLayers(mpCurrentPage->TRG_GetMasterPageVisibleLayers()); |
| aDisplayInfo.SetSubContentActive(true); |
| } |
| } |
| |
| if(!aShapes.empty()) |
| { |
| // more effective way to paint a vector of SdrObjects. Hand over the processed page |
| // to have it in the |
| sdr::contact::ObjectContactOfObjListPainter aMultiObjectPainter(aOut, aShapes, mpCurrentPage); |
| ImplExportCheckVisisbilityRedirector aCheckVisibilityRedirector(mpCurrentPage); |
| aMultiObjectPainter.SetViewObjectContactRedirector(&aCheckVisibilityRedirector); |
| |
| aMultiObjectPainter.ProcessDisplay(aDisplayInfo); |
| } |
| |
| aMtf.Stop(); |
| aMtf.WindStart(); |
| |
| const Size aExtSize( aOut.PixelToLogic( Size( 0, 0 ) ) ); |
| Size aBoundSize( aBound.GetWidth() + ( aExtSize.Width() ), |
| aBound.GetHeight() + ( aExtSize.Height() ) ); |
| |
| aMtf.SetPrefMapMode( aMap ); |
| aMtf.SetPrefSize( aBoundSize ); |
| |
| if( !bVectorType ) |
| { |
| Size aOutSize; |
| aGraphic = GetBitmapFromMetaFile( aMtf, rSettings.mbTranslucent, CalcSize( rSettings.mnWidth, rSettings.mnHeight, aBoundSize, aOutSize ) ); |
| } |
| else |
| { |
| aGraphic = aMtf; |
| } |
| } |
| } |
| |
| if(pTempBackgroundShape) |
| { |
| SdrObject::Free(pTempBackgroundShape); |
| } |
| |
| rOutl.SetCalcFieldValueHdl( maOldCalcFieldValueHdl ); |
| |
| // #i102251# |
| rOutl.SetControlWord(nOldCntrl); |
| |
| return bRet; |
| |
| } |
| |
| // XFilter |
| sal_Bool SAL_CALL GraphicExporter::filter( const Sequence< PropertyValue >& aDescriptor ) |
| throw(RuntimeException) |
| { |
| OGuard aGuard( Application::GetSolarMutex() ); |
| |
| if( NULL == mpUnoPage ) |
| return sal_False; |
| |
| GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter(); |
| |
| if( NULL == pFilter || NULL == mpUnoPage->GetSdrPage() || NULL == mpDoc ) |
| return sal_False; |
| |
| // get the arguments from the descriptor |
| ExportSettings aSettings( mpDoc ); |
| ParseSettings( aDescriptor, aSettings ); |
| |
| const sal_uInt16 nFilter = aSettings.maMediaType.getLength() |
| ? pFilter->GetExportFormatNumberForMediaType( aSettings.maMediaType ) |
| : pFilter->GetExportFormatNumberForShortName( aSettings.maFilterName ); |
| sal_Bool bVectorType = !pFilter->IsExportPixelFormat( nFilter ); |
| |
| // create the output stuff |
| Graphic aGraphic; |
| |
| sal_uInt16 nStatus = GetGraphic( aSettings, aGraphic, bVectorType ) ? GRFILTER_OK : GRFILTER_FILTERERROR; |
| |
| if( nStatus == GRFILTER_OK ) |
| { |
| // export graphic only if it has a size |
| const Size aGraphSize( aGraphic.GetPrefSize() ); |
| if ( ( aGraphSize.Width() == 0 ) || ( aGraphSize.Height() == 0 ) ) |
| { |
| nStatus = GRFILTER_FILTERERROR; |
| } |
| else |
| { |
| // now we have a graphic, so export it |
| if( aSettings.mxGraphicRenderer.is() ) |
| { |
| // render graphic directly into given renderer |
| aSettings.mxGraphicRenderer->render( aGraphic.GetXGraphic() ); |
| } |
| else if( aSettings.mxOutputStream.is() ) |
| { |
| // TODO: Either utilize optional XSeekable functionality for the |
| // SvOutputStream, or adapt the graphic filter to not seek anymore. |
| SvMemoryStream aStream( 1024, 1024 ); |
| |
| nStatus = pFilter->ExportGraphic( aGraphic, String(), aStream, nFilter, &aSettings.maFilterData ); |
| |
| // copy temp stream to XOutputStream |
| SvOutputStream aOutputStream( aSettings.mxOutputStream ); |
| aStream.Seek(0); |
| aOutputStream << aStream; |
| } |
| else |
| { |
| INetURLObject aURLObject( aSettings.maURL.Complete ); |
| DBG_ASSERT( aURLObject.GetProtocol() != INET_PROT_NOT_VALID, "invalid URL" ); |
| |
| nStatus = XOutBitmap::ExportGraphic( aGraphic, aURLObject, *pFilter, nFilter, &aSettings.maFilterData ); |
| } |
| } |
| } |
| |
| if ( aSettings.mxInteractionHandler.is() && ( nStatus != GRFILTER_OK ) ) |
| { |
| Any aInteraction; |
| Sequence< ::com::sun::star::uno::Reference< ::com::sun::star::task::XInteractionContinuation > > lContinuations(1); |
| ::comphelper::OInteractionApprove* pApprove = new ::comphelper::OInteractionApprove(); |
| lContinuations[0] = Reference< XInteractionContinuation >(static_cast< XInteractionContinuation* >(pApprove), UNO_QUERY); |
| |
| GraphicFilterRequest aErrorCode; |
| aErrorCode.ErrCode = nStatus; |
| aInteraction <<= aErrorCode; |
| aSettings.mxInteractionHandler->handle( framework::InteractionRequest::CreateRequest( aInteraction, lContinuations ) ); |
| } |
| return nStatus == GRFILTER_OK; |
| } |
| |
| void SAL_CALL GraphicExporter::cancel() |
| throw(RuntimeException) |
| { |
| } |
| |
| // XExporter |
| |
| /** the source 'document' could be a XDrawPage, a XShape or a generic XShapes */ |
| void SAL_CALL GraphicExporter::setSourceDocument( const Reference< lang::XComponent >& xComponent ) |
| throw(IllegalArgumentException, RuntimeException) |
| { |
| OGuard aGuard( Application::GetSolarMutex() ); |
| |
| mxShapes = NULL; |
| mpUnoPage = NULL; |
| |
| try |
| { |
| // any break inside this one loop while will throw a IllegalArgumentException |
| do |
| { |
| mxPage = Reference< XDrawPage >::query( xComponent ); |
| mxShapes = Reference< XShapes >::query( xComponent ); |
| mxShape = Reference< XShape >::query( xComponent ); |
| |
| // Step 1: try a generic XShapes |
| if( !mxPage.is() && !mxShape.is() && mxShapes.is() ) |
| { |
| // we do not support empty shape collections |
| if( 0 == mxShapes->getCount() ) |
| break; |
| |
| // get first shape to detect corresponding page and model |
| mxShapes->getByIndex(0) >>= mxShape; |
| } |
| else |
| { |
| mxShapes = NULL; |
| } |
| |
| // Step 2: try a shape |
| if( mxShape.is() ) |
| { |
| if( NULL == GetSdrObjectFromXShape( mxShape ) ) |
| break; |
| |
| // get page for this shape |
| Reference< XChild > xChild( mxShape, UNO_QUERY ); |
| if( !xChild.is() ) |
| break; |
| |
| Reference< XInterface > xInt; |
| do |
| { |
| xInt = xChild->getParent(); |
| mxPage = Reference< XDrawPage >::query( xInt ); |
| if( !mxPage.is() ) |
| xChild = Reference< XChild >::query( xInt ); |
| } |
| while( !mxPage.is() && xChild.is() ); |
| |
| if( !mxPage.is() ) |
| break; |
| } |
| |
| // Step 3: check the page |
| if( !mxPage.is() ) |
| break; |
| |
| mpUnoPage = SvxDrawPage::getImplementation( mxPage ); |
| |
| if( NULL == mpUnoPage || NULL == mpUnoPage->GetSdrPage() ) |
| break; |
| |
| mpDoc = mpUnoPage->GetSdrPage()->GetModel(); |
| |
| // Step 4: If we got a generic XShapes test all contained shapes |
| // if they belong to the same XDrawPage |
| |
| if( mxShapes.is() ) |
| { |
| SdrPage* pPage = mpUnoPage->GetSdrPage(); |
| SdrObject* pObj; |
| Reference< XShape > xShape; |
| |
| sal_Bool bOk = sal_True; |
| |
| const sal_Int32 nCount = mxShapes->getCount(); |
| |
| // test all but the first shape if they have the same page than |
| // the first shape |
| for( sal_Int32 nIndex = 1; bOk && ( nIndex < nCount ); nIndex++ ) |
| { |
| mxShapes->getByIndex( nIndex ) >>= xShape; |
| pObj = GetSdrObjectFromXShape( xShape ); |
| bOk = pObj && pObj->GetPage() == pPage; |
| } |
| |
| if( !bOk ) |
| break; |
| } |
| |
| // no errors so far |
| return; |
| } |
| while( 0 ); |
| } |
| catch( Exception& ) |
| { |
| } |
| |
| throw IllegalArgumentException(); |
| } |
| |
| // XServiceInfo |
| OUString SAL_CALL GraphicExporter::getImplementationName( ) |
| throw(RuntimeException) |
| { |
| return GraphicExporter_getImplementationName(); |
| } |
| |
| sal_Bool SAL_CALL GraphicExporter::supportsService( const OUString& ServiceName ) |
| throw(RuntimeException) |
| { |
| Sequence< OUString > aSeq( GraphicExporter_getSupportedServiceNames() ); |
| sal_Int32 nArgs = aSeq.getLength(); |
| const OUString* pService = aSeq.getConstArray(); |
| while( nArgs-- ) |
| if( *pService++ == ServiceName ) |
| return sal_True; |
| |
| return sal_False; |
| } |
| |
| Sequence< OUString > SAL_CALL GraphicExporter::getSupportedServiceNames( ) |
| throw(RuntimeException) |
| { |
| return GraphicExporter_getSupportedServiceNames(); |
| } |
| |
| // XMimeTypeInfo |
| sal_Bool SAL_CALL GraphicExporter::supportsMimeType( const OUString& MimeTypeName ) throw (RuntimeException) |
| { |
| const String aMimeTypeName( MimeTypeName ); |
| |
| GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter(); |
| sal_uInt16 nCount = pFilter->GetExportFormatCount(); |
| sal_uInt16 nFilter; |
| for( nFilter = 0; nFilter < nCount; nFilter++ ) |
| { |
| if( aMimeTypeName.Equals( pFilter->GetExportFormatMediaType( nFilter ) ) ) |
| { |
| return sal_True; |
| } |
| } |
| |
| return sal_False; |
| } |
| |
| Sequence< OUString > SAL_CALL GraphicExporter::getSupportedMimeTypeNames( ) throw (RuntimeException) |
| { |
| GraphicFilter* pFilter = GraphicFilter::GetGraphicFilter(); |
| sal_uInt16 nCount = pFilter->GetExportFormatCount(); |
| sal_uInt16 nFilter; |
| sal_uInt16 nFound = 0; |
| |
| Sequence< OUString > aSeq( nCount ); |
| OUString* pStr = aSeq.getArray(); |
| |
| for( nFilter = 0; nFilter < nCount; nFilter++ ) |
| { |
| OUString aMimeType( pFilter->GetExportFormatMediaType( nFilter ) ); |
| if( aMimeType.getLength() ) |
| { |
| *pStr++ = aMimeType; |
| nFound++; |
| } |
| } |
| |
| if( nFound < nCount ) |
| aSeq.realloc( nFound ); |
| |
| return aSeq; |
| } |
| |
| Graphic SvxGetGraphicForShape( SdrObject& rShape, bool bVector ) |
| { |
| Graphic aGraphic; |
| try |
| { |
| rtl::Reference< GraphicExporter > xExporter( new GraphicExporter() ); |
| Reference< XComponent > xComp( rShape.getUnoShape(), UNO_QUERY_THROW ); |
| xExporter->setSourceDocument( xComp ); |
| ExportSettings aSettings( rShape.GetModel() ); |
| xExporter->GetGraphic( aSettings, aGraphic, bVector ); |
| } |
| catch( Exception& ) |
| { |
| DBG_ERROR("SvxGetGraphicForShape(), exception caught!"); |
| } |
| return aGraphic; |
| } |
| |