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>
29 #include <vcl/graphicfilter.hxx>
30 #include <svl/outstrm.hxx>
31 #include <svtools/DocumentToGraphicRenderer.hxx>
35 GraphicExportFilter::GraphicExportFilter( uno::Reference
< uno::XComponentContext
> xContext
)
36 : mxContext(std::move(xContext
))
39 , mbSelectionOnly(false)
42 GraphicExportFilter::~GraphicExportFilter()
46 sal_Bool
GraphicExportFilter::supportsService(const OUString
& sServiceName
)
48 return cppu::supportsService(this, sServiceName
);
50 OUString
GraphicExportFilter::getImplementationName()
52 return "com.sun.star.comp.GraphicExportFilter";
54 css::uno::Sequence
< OUString
> GraphicExportFilter::getSupportedServiceNames()
56 return { "com.sun.star.document.ExportFilter" };
59 void GraphicExportFilter::gatherProperties( const uno::Sequence
< beans::PropertyValue
> & rProperties
)
61 OUString aInternalFilterName
;
63 for ( const beans::PropertyValue
& rProperty
: rProperties
)
65 if ( rProperty
.Name
== "FilterName" )
67 rProperty
.Value
>>= aInternalFilterName
;
68 const sal_Int32 nLen
= aInternalFilterName
.getLength();
69 aInternalFilterName
= aInternalFilterName
.replaceFirst("calc_", "");
70 if (aInternalFilterName
.getLength() == nLen
)
71 aInternalFilterName
= aInternalFilterName
.replaceFirst("writer_", "");
72 if (aInternalFilterName
.getLength() == nLen
)
73 aInternalFilterName
= aInternalFilterName
.replaceFirst("web_", "");
74 if (aInternalFilterName
.getLength() == nLen
)
75 aInternalFilterName
= aInternalFilterName
.replaceFirst("draw_", "");
76 if (aInternalFilterName
.getLength() == nLen
)
77 aInternalFilterName
= aInternalFilterName
.replaceFirst("impress_", "");
79 else if ( rProperty
.Name
== "FilterData" )
81 rProperty
.Value
>>= maFilterDataSequence
;
83 else if ( rProperty
.Name
== "OutputStream" )
85 rProperty
.Value
>>= mxOutputStream
;
87 else if ( rProperty
.Name
== "SelectionOnly" )
89 rProperty
.Value
>>= mbSelectionOnly
;
93 for ( const beans::PropertyValue
& rProp
: std::as_const(maFilterDataSequence
) )
95 if ( rProp
.Name
== "PixelWidth" )
97 rProp
.Value
>>= mnTargetWidth
;
99 else if ( rProp
.Name
== "PixelHeight" )
101 rProp
.Value
>>= mnTargetHeight
;
105 if ( aInternalFilterName
.isEmpty() )
108 GraphicFilter
aGraphicFilter( true );
110 sal_uInt16 nFilterCount
= aGraphicFilter
.GetExportFormatCount();
113 for ( nFormat
= 0; nFormat
< nFilterCount
; nFormat
++ )
115 if ( aGraphicFilter
.GetExportInternalFilterName( nFormat
) == aInternalFilterName
)
118 if ( nFormat
< nFilterCount
)
120 maFilterExtension
= aGraphicFilter
.GetExportFormatShortName( nFormat
);
124 sal_Bool SAL_CALL
GraphicExportFilter::filter( const uno::Sequence
< beans::PropertyValue
> & rDescriptor
)
126 gatherProperties(rDescriptor
);
128 if (mbSelectionOnly
&& mxDocument
.is())
130 uno::Reference
< frame::XModel
> xModel( mxDocument
, uno::UNO_QUERY
);
133 uno::Reference
< frame::XController
> xController( xModel
->getCurrentController());
134 if (xController
.is())
136 uno::Reference
< drawing::XShapes
> xShapes
;
137 uno::Reference
< drawing::XShape
> xShape
;
138 if (DocumentToGraphicRenderer::isShapeSelected( xShapes
, xShape
, xController
))
139 return filterExportShape( rDescriptor
, xShapes
, xShape
);
144 return filterRenderDocument();
147 bool GraphicExportFilter::filterRenderDocument() const
149 DocumentToGraphicRenderer
aRenderer( mxDocument
, mbSelectionOnly
);
150 sal_Int32 nCurrentPage
= aRenderer
.getCurrentPage();
151 Size aDocumentSizePixel
= aRenderer
.getDocumentSizeInPixels(nCurrentPage
);
153 Size
aTargetSizePixel(mnTargetWidth
, mnTargetHeight
);
155 if (mnTargetWidth
== 0 || mnTargetHeight
== 0)
156 aTargetSizePixel
= aDocumentSizePixel
;
158 Graphic aGraphic
= aRenderer
.renderToGraphic(nCurrentPage
, aDocumentSizePixel
, aTargetSizePixel
, COL_WHITE
, /*bExtOutDevData=*/false);
160 GraphicFilter
& rFilter
= GraphicFilter::GetGraphicFilter();
162 sal_uInt16 nFilterFormat
= rFilter
.GetExportFormatNumberForShortName( maFilterExtension
);
164 SvMemoryStream aMemStream
;
165 const GraphicConversionParameters
aParameters(aTargetSizePixel
, true, true);
167 const ErrCode nResult
= rFilter
.ExportGraphic( aGraphic
.GetBitmapEx(aParameters
), u
"", aMemStream
,
168 nFilterFormat
, &maFilterDataSequence
);
170 if ( nResult
== ERRCODE_NONE
)
172 SvOutputStream
aOutputStream( mxOutputStream
);
174 aOutputStream
.WriteStream( aMemStream
);
182 bool GraphicExportFilter::filterExportShape(
183 const css::uno::Sequence
< css::beans::PropertyValue
> & rDescriptor
,
184 const css::uno::Reference
< css::drawing::XShapes
> & rxShapes
,
185 const css::uno::Reference
< css::drawing::XShape
> & rxShape
) const
187 uno::Reference
< lang::XComponent
> xSourceDoc
;
189 xSourceDoc
.set( rxShapes
, uno::UNO_QUERY_THROW
);
190 else if (rxShape
.is())
191 xSourceDoc
.set( rxShape
, uno::UNO_QUERY_THROW
);
192 if (!xSourceDoc
.is())
195 uno::Reference
< drawing::XGraphicExportFilter
> xGraphicExporter
=
196 drawing::GraphicExportFilter::create( mxContext
);
197 if (!xGraphicExporter
.is())
200 // Need to replace the internal filter name with the short name
202 uno::Sequence
< beans::PropertyValue
> aDescriptor( rDescriptor
);
203 for (sal_Int32 i
= 0; i
< aDescriptor
.getLength(); ++i
)
205 if (aDescriptor
[i
].Name
== "FilterName")
207 aDescriptor
.getArray()[i
].Value
<<= maFilterExtension
;
212 xGraphicExporter
->setSourceDocument( xSourceDoc
);
213 return xGraphicExporter
->filter( aDescriptor
);
216 void SAL_CALL
GraphicExportFilter::cancel( )
220 void SAL_CALL
GraphicExportFilter::setSourceDocument( const uno::Reference
< lang::XComponent
> & xDocument
)
222 mxDocument
= xDocument
;
225 void SAL_CALL
GraphicExportFilter::initialize( const uno::Sequence
< uno::Any
> & )
229 extern "C" SAL_DLLPUBLIC_EXPORT
css::uno::XInterface
*
230 filter_GraphicExportFilter_get_implementation(
231 css::uno::XComponentContext
* context
, css::uno::Sequence
<css::uno::Any
> const&)
233 return cppu::acquire(new GraphicExportFilter(context
));
235 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */