1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
20 #include "GraphicExportFilter.hxx"
22 #include <com/sun/star/drawing/GraphicExportFilter.hpp>
23 #include <com/sun/star/drawing/XShape.hpp>
24 #include <com/sun/star/drawing/XShapes.hpp>
25 #include <com/sun/star/frame/XModel.hpp>
27 #include <cppuhelper/supportsservice.hxx>
28 #include <vcl/graphicfilter.hxx>
29 #include <svl/outstrm.hxx>
30 #include <svtools/DocumentToGraphicRenderer.hxx>
34 GraphicExportFilter::GraphicExportFilter( const uno::Reference
< uno::XComponentContext
> & rxContext
)
35 : mxContext(rxContext
)
38 , mbSelectionOnly(false)
41 GraphicExportFilter::~GraphicExportFilter()
45 sal_Bool
GraphicExportFilter::supportsService(const OUString
& sServiceName
)
47 return cppu::supportsService(this, sServiceName
);
49 OUString
GraphicExportFilter::getImplementationName()
51 return "com.sun.star.comp.GraphicExportFilter";
53 css::uno::Sequence
< OUString
> GraphicExportFilter::getSupportedServiceNames()
55 return { "com.sun.star.document.ExportFilter" };
58 void GraphicExportFilter::gatherProperties( const uno::Sequence
< beans::PropertyValue
> & rProperties
)
60 OUString aInternalFilterName
;
62 for ( const beans::PropertyValue
& rProperty
: rProperties
)
64 if ( rProperty
.Name
== "FilterName" )
66 rProperty
.Value
>>= aInternalFilterName
;
67 const sal_Int32 nLen
= aInternalFilterName
.getLength();
68 aInternalFilterName
= aInternalFilterName
.replaceFirst("calc_", "");
69 if (aInternalFilterName
.getLength() == nLen
)
70 aInternalFilterName
= aInternalFilterName
.replaceFirst("writer_", "");
71 if (aInternalFilterName
.getLength() == nLen
)
72 aInternalFilterName
= aInternalFilterName
.replaceFirst("web_", "");
73 if (aInternalFilterName
.getLength() == nLen
)
74 aInternalFilterName
= aInternalFilterName
.replaceFirst("draw_", "");
75 if (aInternalFilterName
.getLength() == nLen
)
76 aInternalFilterName
= aInternalFilterName
.replaceFirst("impress_", "");
78 else if ( rProperty
.Name
== "FilterData" )
80 rProperty
.Value
>>= maFilterDataSequence
;
82 else if ( rProperty
.Name
== "OutputStream" )
84 rProperty
.Value
>>= mxOutputStream
;
86 else if ( rProperty
.Name
== "SelectionOnly" )
88 rProperty
.Value
>>= mbSelectionOnly
;
92 for ( const beans::PropertyValue
& rProp
: std::as_const(maFilterDataSequence
) )
94 if ( rProp
.Name
== "PixelWidth" )
96 rProp
.Value
>>= mnTargetWidth
;
98 else if ( rProp
.Name
== "PixelHeight" )
100 rProp
.Value
>>= mnTargetHeight
;
104 if ( aInternalFilterName
.isEmpty() )
107 GraphicFilter
aGraphicFilter( true );
109 sal_uInt16 nFilterCount
= aGraphicFilter
.GetExportFormatCount();
112 for ( nFormat
= 0; nFormat
< nFilterCount
; nFormat
++ )
114 if ( aGraphicFilter
.GetExportInternalFilterName( nFormat
) == aInternalFilterName
)
117 if ( nFormat
< nFilterCount
)
119 maFilterExtension
= aGraphicFilter
.GetExportFormatShortName( nFormat
);
123 sal_Bool SAL_CALL
GraphicExportFilter::filter( const uno::Sequence
< beans::PropertyValue
> & rDescriptor
)
125 gatherProperties(rDescriptor
);
127 if (mbSelectionOnly
&& mxDocument
.is())
129 uno::Reference
< frame::XModel
> xModel( mxDocument
, uno::UNO_QUERY
);
132 uno::Reference
< frame::XController
> xController( xModel
->getCurrentController());
133 if (xController
.is())
135 uno::Reference
< drawing::XShapes
> xShapes
;
136 uno::Reference
< drawing::XShape
> xShape
;
137 if (DocumentToGraphicRenderer::isShapeSelected( xShapes
, xShape
, xController
))
138 return filterExportShape( rDescriptor
, xShapes
, xShape
);
143 return filterRenderDocument();
146 bool GraphicExportFilter::filterRenderDocument() const
148 DocumentToGraphicRenderer
aRenderer( mxDocument
, mbSelectionOnly
);
149 sal_Int32 nCurrentPage
= aRenderer
.getCurrentPage();
150 Size aDocumentSizePixel
= aRenderer
.getDocumentSizeInPixels(nCurrentPage
);
152 Size
aTargetSizePixel(mnTargetWidth
, mnTargetHeight
);
154 if (mnTargetWidth
== 0 || mnTargetHeight
== 0)
155 aTargetSizePixel
= aDocumentSizePixel
;
157 Graphic aGraphic
= aRenderer
.renderToGraphic(nCurrentPage
, aDocumentSizePixel
, aTargetSizePixel
, COL_WHITE
, /*bExtOutDevData=*/false);
159 GraphicFilter
& rFilter
= GraphicFilter::GetGraphicFilter();
161 sal_uInt16 nFilterFormat
= rFilter
.GetExportFormatNumberForShortName( maFilterExtension
);
163 SvMemoryStream aMemStream
;
164 const GraphicConversionParameters
aParameters(aTargetSizePixel
, true, true);
166 const ErrCode nResult
= rFilter
.ExportGraphic( aGraphic
.GetBitmapEx(aParameters
), OUString(), aMemStream
,
167 nFilterFormat
, &maFilterDataSequence
);
169 if ( nResult
== ERRCODE_NONE
)
171 SvOutputStream
aOutputStream( mxOutputStream
);
173 aOutputStream
.WriteStream( aMemStream
);
181 bool GraphicExportFilter::filterExportShape(
182 const css::uno::Sequence
< css::beans::PropertyValue
> & rDescriptor
,
183 const css::uno::Reference
< css::drawing::XShapes
> & rxShapes
,
184 const css::uno::Reference
< css::drawing::XShape
> & rxShape
) const
186 uno::Reference
< lang::XComponent
> xSourceDoc
;
188 xSourceDoc
.set( rxShapes
, uno::UNO_QUERY_THROW
);
189 else if (rxShape
.is())
190 xSourceDoc
.set( rxShape
, uno::UNO_QUERY_THROW
);
191 if (!xSourceDoc
.is())
194 uno::Reference
< drawing::XGraphicExportFilter
> xGraphicExporter
=
195 drawing::GraphicExportFilter::create( mxContext
);
196 if (!xGraphicExporter
.is())
199 // Need to replace the internal filter name with the short name
201 uno::Sequence
< beans::PropertyValue
> aDescriptor( rDescriptor
);
202 for (sal_Int32 i
= 0; i
< aDescriptor
.getLength(); ++i
)
204 if (aDescriptor
[i
].Name
== "FilterName")
206 aDescriptor
[i
].Value
<<= maFilterExtension
;
211 xGraphicExporter
->setSourceDocument( xSourceDoc
);
212 return xGraphicExporter
->filter( aDescriptor
);
215 void SAL_CALL
GraphicExportFilter::cancel( )
219 void SAL_CALL
GraphicExportFilter::setSourceDocument( const uno::Reference
< lang::XComponent
> & xDocument
)
221 mxDocument
= xDocument
;
224 void SAL_CALL
GraphicExportFilter::initialize( const uno::Sequence
< uno::Any
> & )
228 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
229 filter_GraphicExportFilter_get_implementation(
230 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
232 return cppu::acquire(new GraphicExportFilter(context
));
234 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */