Line data Source code
1 : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
2 : /*
3 : * This file is part of the LibreOffice project.
4 : *
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/.
8 : *
9 : * This file incorporates work covered by the following license notice:
10 : *
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 .
18 : */
19 :
20 : #include <com/sun/star/container/XNameContainer.hpp>
21 : #include "oox/helper/graphichelper.hxx"
22 :
23 : #include <com/sun/star/awt/Point.hpp>
24 : #include <com/sun/star/awt/Size.hpp>
25 : #include <com/sun/star/awt/XDevice.hpp>
26 : #include <com/sun/star/awt/XUnitConversion.hpp>
27 : #include <com/sun/star/beans/XPropertySet.hpp>
28 : #include <com/sun/star/frame/Desktop.hpp>
29 : #include <com/sun/star/frame/XFramesSupplier.hpp>
30 : #include <com/sun/star/graphic/GraphicObject.hpp>
31 : #include <com/sun/star/graphic/GraphicProvider.hpp>
32 : #include <com/sun/star/graphic/XGraphicProvider.hpp>
33 : #include <com/sun/star/util/MeasureUnit.hpp>
34 : #include <osl/diagnose.h>
35 : #include <comphelper/seqstream.hxx>
36 : #include <vcl/wmf.hxx>
37 : #include <vcl/svapp.hxx>
38 : #include <tools/gen.hxx>
39 : #include "oox/helper/containerhelper.hxx"
40 : #include "oox/helper/propertyset.hxx"
41 : #include "oox/token/properties.hxx"
42 : #include "oox/token/tokens.hxx"
43 :
44 : namespace oox {
45 :
46 : using namespace ::com::sun::star;
47 : using namespace ::com::sun::star::beans;
48 : using namespace ::com::sun::star::frame;
49 : using namespace ::com::sun::star::graphic;
50 : using namespace ::com::sun::star::io;
51 : using namespace ::com::sun::star::lang;
52 : using namespace ::com::sun::star::uno;
53 :
54 : namespace {
55 :
56 64 : inline sal_Int32 lclConvertScreenPixelToHmm( double fPixel, double fPixelPerHmm )
57 : {
58 64 : return static_cast< sal_Int32 >( (fPixelPerHmm > 0.0) ? (fPixel / fPixelPerHmm + 0.5) : 0.0 );
59 : }
60 :
61 : } // namespace
62 :
63 2288 : GraphicHelper::GraphicHelper( const Reference< XComponentContext >& rxContext, const Reference< XFrame >& rxTargetFrame, const StorageRef& rxStorage ) :
64 : mxContext( rxContext ),
65 : mxStorage( rxStorage ),
66 2288 : maGraphicObjScheme( "vnd.sun.star.GraphicObject:" )
67 : {
68 : OSL_ENSURE( mxContext.is(), "GraphicHelper::GraphicHelper - missing component context" );
69 2288 : if( mxContext.is() )
70 2288 : mxGraphicProvider.set( graphic::GraphicProvider::create( mxContext ) );
71 :
72 : //! TODO: get colors from system
73 2288 : maSystemPalette[ XML_3dDkShadow ] = 0x716F64;
74 2288 : maSystemPalette[ XML_3dLight ] = 0xF1EFE2;
75 2288 : maSystemPalette[ XML_activeBorder ] = 0xD4D0C8;
76 2288 : maSystemPalette[ XML_activeCaption ] = 0x0054E3;
77 2288 : maSystemPalette[ XML_appWorkspace ] = 0x808080;
78 2288 : maSystemPalette[ XML_background ] = 0x004E98;
79 2288 : maSystemPalette[ XML_btnFace ] = 0xECE9D8;
80 2288 : maSystemPalette[ XML_btnHighlight ] = 0xFFFFFF;
81 2288 : maSystemPalette[ XML_btnShadow ] = 0xACA899;
82 2288 : maSystemPalette[ XML_btnText ] = 0x000000;
83 2288 : maSystemPalette[ XML_captionText ] = 0xFFFFFF;
84 2288 : maSystemPalette[ XML_gradientActiveCaption ] = 0x3D95FF;
85 2288 : maSystemPalette[ XML_gradientInactiveCaption ] = 0xD8E4F8;
86 2288 : maSystemPalette[ XML_grayText ] = 0xACA899;
87 2288 : maSystemPalette[ XML_highlight ] = 0x316AC5;
88 2288 : maSystemPalette[ XML_highlightText ] = 0xFFFFFF;
89 2288 : maSystemPalette[ XML_hotLight ] = 0x000080;
90 2288 : maSystemPalette[ XML_inactiveBorder ] = 0xD4D0C8;
91 2288 : maSystemPalette[ XML_inactiveCaption ] = 0x7A96DF;
92 2288 : maSystemPalette[ XML_inactiveCaptionText ] = 0xD8E4F8;
93 2288 : maSystemPalette[ XML_infoBk ] = 0xFFFFE1;
94 2288 : maSystemPalette[ XML_infoText ] = 0x000000;
95 2288 : maSystemPalette[ XML_menu ] = 0xFFFFFF;
96 2288 : maSystemPalette[ XML_menuBar ] = 0xECE9D8;
97 2288 : maSystemPalette[ XML_menuHighlight ] = 0x316AC5;
98 2288 : maSystemPalette[ XML_menuText ] = 0x000000;
99 2288 : maSystemPalette[ XML_scrollBar ] = 0xD4D0C8;
100 2288 : maSystemPalette[ XML_window ] = 0xFFFFFF;
101 2288 : maSystemPalette[ XML_windowFrame ] = 0x000000;
102 2288 : maSystemPalette[ XML_windowText ] = 0x000000;
103 :
104 : // if no target frame has been passed (e.g. OLE objects), try to fallback to the active frame
105 : // TODO: we need some mechanism to keep and pass the parent frame
106 2288 : Reference< XFrame > xFrame = rxTargetFrame;
107 2288 : if( !xFrame.is() && mxContext.is() ) try
108 : {
109 1691 : Reference< XDesktop2 > xFramesSupp = Desktop::create( mxContext );
110 1691 : xFrame = xFramesSupp->getActiveFrame();
111 : }
112 0 : catch( Exception& )
113 : {
114 : }
115 :
116 : // get the metric of the output device
117 : OSL_ENSURE( xFrame.is(), "GraphicHelper::GraphicHelper - cannot get target frame" );
118 : // some default just in case, 100 000 is 1 meter in MM100
119 2288 : Size aDefault = Application::GetDefaultDevice()->LogicToPixel(Size(100000, 100000), MapMode(MAP_100TH_MM));
120 2288 : maDeviceInfo.PixelPerMeterX = aDefault.Width();
121 2288 : maDeviceInfo.PixelPerMeterY = aDefault.Height();
122 2288 : if( xFrame.is() ) try
123 : {
124 667 : Reference< awt::XDevice > xDevice( xFrame->getContainerWindow(), UNO_QUERY_THROW );
125 667 : mxUnitConversion.set( xDevice, UNO_QUERY );
126 : OSL_ENSURE( mxUnitConversion.is(), "GraphicHelper::GraphicHelper - cannot get unit converter" );
127 667 : maDeviceInfo = xDevice->getInfo();
128 : }
129 0 : catch( Exception& )
130 : {
131 : OSL_FAIL( "GraphicHelper::GraphicHelper - cannot get output device info" );
132 : }
133 2288 : mfPixelPerHmmX = maDeviceInfo.PixelPerMeterX / 100000.0;
134 2288 : mfPixelPerHmmY = maDeviceInfo.PixelPerMeterY / 100000.0;
135 2288 : }
136 :
137 2791 : GraphicHelper::~GraphicHelper()
138 : {
139 2791 : }
140 :
141 : // System colors and predefined colors ----------------------------------------
142 :
143 4419 : sal_Int32 GraphicHelper::getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ) const
144 : {
145 4419 : return ContainerHelper::getMapElement( maSystemPalette, nToken, nDefaultRgb );
146 : }
147 :
148 0 : sal_Int32 GraphicHelper::getSchemeColor( sal_Int32 /*nToken*/ ) const
149 : {
150 : OSL_FAIL( "GraphicHelper::getSchemeColor - scheme colors not implemented" );
151 0 : return API_RGB_TRANSPARENT;
152 : }
153 :
154 0 : sal_Int32 GraphicHelper::getPaletteColor( sal_Int32 /*nPaletteIdx*/ ) const
155 : {
156 : OSL_FAIL( "GraphicHelper::getPaletteColor - palette colors not implemented" );
157 0 : return API_RGB_TRANSPARENT;
158 : }
159 :
160 156 : sal_Int32 GraphicHelper::getDefaultChartAreaFillStyle() const
161 : {
162 156 : return XML_solidFill;
163 : }
164 :
165 : // Device info and device dependent unit conversion ---------------------------
166 :
167 32 : sal_Int32 GraphicHelper::convertScreenPixelXToHmm( double fPixelX ) const
168 : {
169 32 : return lclConvertScreenPixelToHmm( fPixelX, mfPixelPerHmmX );
170 : }
171 :
172 32 : sal_Int32 GraphicHelper::convertScreenPixelYToHmm( double fPixelY ) const
173 : {
174 32 : return lclConvertScreenPixelToHmm( fPixelY, mfPixelPerHmmY );
175 : }
176 :
177 32 : awt::Size GraphicHelper::convertScreenPixelToHmm( const awt::Size& rPixel ) const
178 : {
179 32 : return awt::Size( convertScreenPixelXToHmm( rPixel.Width ), convertScreenPixelYToHmm( rPixel.Height ) );
180 : }
181 :
182 18 : double GraphicHelper::convertHmmToScreenPixelX( sal_Int32 nHmmX ) const
183 : {
184 18 : return nHmmX * mfPixelPerHmmX;
185 : }
186 :
187 18 : double GraphicHelper::convertHmmToScreenPixelY( sal_Int32 nHmmY ) const
188 : {
189 18 : return nHmmY * mfPixelPerHmmY;
190 : }
191 :
192 8 : awt::Point GraphicHelper::convertHmmToScreenPixel( const awt::Point& rHmm ) const
193 : {
194 : return awt::Point(
195 8 : static_cast< sal_Int32 >( convertHmmToScreenPixelX( rHmm.X ) + 0.5 ),
196 16 : static_cast< sal_Int32 >( convertHmmToScreenPixelY( rHmm.Y ) + 0.5 ) );
197 : }
198 :
199 10 : awt::Size GraphicHelper::convertHmmToScreenPixel( const awt::Size& rHmm ) const
200 : {
201 : return awt::Size(
202 10 : static_cast< sal_Int32 >( convertHmmToScreenPixelX( rHmm.Width ) + 0.5 ),
203 20 : static_cast< sal_Int32 >( convertHmmToScreenPixelY( rHmm.Height ) + 0.5 ) );
204 : }
205 :
206 8 : awt::Point GraphicHelper::convertHmmToAppFont( const awt::Point& rHmm ) const
207 : {
208 8 : if( mxUnitConversion.is() ) try
209 : {
210 8 : awt::Point aPixel = convertHmmToScreenPixel( rHmm );
211 8 : return mxUnitConversion->convertPointToLogic( aPixel, ::com::sun::star::util::MeasureUnit::APPFONT );
212 : }
213 0 : catch( Exception& )
214 : {
215 : }
216 0 : return awt::Point( 0, 0 );
217 : }
218 :
219 10 : awt::Size GraphicHelper::convertHmmToAppFont( const awt::Size& rHmm ) const
220 : {
221 10 : if( mxUnitConversion.is() ) try
222 : {
223 10 : awt::Size aPixel = convertHmmToScreenPixel( rHmm );
224 10 : return mxUnitConversion->convertSizeToLogic( aPixel, ::com::sun::star::util::MeasureUnit::APPFONT );
225 : }
226 0 : catch( Exception& )
227 : {
228 : }
229 0 : return awt::Size( 0, 0 );
230 : }
231 :
232 : // Graphics and graphic objects ----------------------------------------------
233 :
234 545 : Reference< XGraphic > GraphicHelper::importGraphic( const Reference< XInputStream >& rxInStrm,
235 : const WMF_EXTERNALHEADER* pExtHeader ) const
236 : {
237 545 : Reference< XGraphic > xGraphic;
238 545 : if( rxInStrm.is() && mxGraphicProvider.is() ) try
239 : {
240 545 : Sequence< PropertyValue > aArgs( 1 );
241 545 : aArgs[ 0 ].Name = "InputStream";
242 545 : aArgs[ 0 ].Value <<= rxInStrm;
243 :
244 545 : if ( pExtHeader && pExtHeader->mapMode > 0 )
245 : {
246 7 : aArgs.realloc( aArgs.getLength() + 1 );
247 7 : Sequence< PropertyValue > aFilterData( 3 );
248 7 : aFilterData[ 0 ].Name = "ExternalWidth";
249 7 : aFilterData[ 0 ].Value <<= pExtHeader->xExt;
250 7 : aFilterData[ 1 ].Name = "ExternalHeight";
251 7 : aFilterData[ 1 ].Value <<= pExtHeader->yExt;
252 7 : aFilterData[ 2 ].Name = "ExternalMapMode";
253 7 : aFilterData[ 2 ].Value <<= pExtHeader->mapMode;
254 7 : aArgs[ 1 ].Name = "FilterData";
255 7 : aArgs[ 1 ].Value <<= aFilterData;
256 : }
257 :
258 545 : xGraphic = mxGraphicProvider->queryGraphic( aArgs );
259 : }
260 0 : catch( Exception& )
261 : {
262 : }
263 545 : return xGraphic;
264 : }
265 :
266 0 : Reference< XGraphic > GraphicHelper::importGraphic( const StreamDataSequence& rGraphicData ) const
267 : {
268 0 : Reference< XGraphic > xGraphic;
269 0 : if( rGraphicData.hasElements() )
270 : {
271 0 : Reference< XInputStream > xInStrm( new ::comphelper::SequenceInputStream( rGraphicData ) );
272 0 : xGraphic = importGraphic( xInStrm );
273 : }
274 0 : return xGraphic;
275 : }
276 :
277 581 : Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStreamName, const WMF_EXTERNALHEADER* pExtHeader ) const
278 : {
279 581 : Reference< XGraphic > xGraphic;
280 : OSL_ENSURE( !rStreamName.isEmpty(), "GraphicHelper::importEmbeddedGraphic - empty stream name" );
281 581 : if( !rStreamName.isEmpty() )
282 : {
283 581 : EmbeddedGraphicMap::const_iterator aIt = maEmbeddedGraphics.find( rStreamName );
284 581 : if( aIt == maEmbeddedGraphics.end() )
285 : {
286 504 : xGraphic = importGraphic(mxStorage->openInputStream(rStreamName), pExtHeader);
287 504 : if( xGraphic.is() )
288 504 : maEmbeddedGraphics[ rStreamName ] = xGraphic;
289 : }
290 : else
291 77 : xGraphic = aIt->second;
292 : }
293 581 : return xGraphic;
294 : }
295 :
296 563 : OUString GraphicHelper::createGraphicObject( const Reference< XGraphic >& rxGraphic ) const
297 : {
298 563 : OUString aGraphicObjUrl;
299 563 : if( mxContext.is() && rxGraphic.is() ) try
300 : {
301 561 : Reference< XGraphicObject > xGraphicObj( graphic::GraphicObject::create( mxContext ), UNO_SET_THROW );
302 561 : xGraphicObj->setGraphic( rxGraphic );
303 561 : maGraphicObjects.push_back( xGraphicObj );
304 561 : aGraphicObjUrl = maGraphicObjScheme + xGraphicObj->getUniqueID();
305 : }
306 0 : catch( Exception& )
307 : {
308 : }
309 563 : return aGraphicObjUrl;
310 : }
311 :
312 40 : OUString GraphicHelper::importGraphicObject( const Reference< XInputStream >& rxInStrm,
313 : const WMF_EXTERNALHEADER* pExtHeader ) const
314 : {
315 40 : return createGraphicObject( importGraphic( rxInStrm, pExtHeader ) );
316 : }
317 :
318 0 : OUString GraphicHelper::importGraphicObject( const StreamDataSequence& rGraphicData ) const
319 : {
320 0 : return createGraphicObject( importGraphic( rGraphicData ) );
321 : }
322 :
323 158 : OUString GraphicHelper::importEmbeddedGraphicObject( const OUString& rStreamName ) const
324 : {
325 158 : Reference< XGraphic > xGraphic = importEmbeddedGraphic( rStreamName );
326 158 : return xGraphic.is() ? createGraphicObject( xGraphic ) : OUString();
327 : }
328 :
329 136 : awt::Size GraphicHelper::getOriginalSize( const Reference< XGraphic >& xGraphic ) const
330 : {
331 136 : awt::Size aSizeHmm;
332 136 : PropertySet aPropSet( xGraphic );
333 136 : if( aPropSet.getProperty( aSizeHmm, PROP_Size100thMM ) && (aSizeHmm.Width == 0) && (aSizeHmm.Height == 0) ) // MAPMODE_PIXEL used?
334 : {
335 31 : awt::Size aSizePixel( 0, 0 );
336 31 : if( aPropSet.getProperty( aSizePixel, PROP_SizePixel ) )
337 31 : aSizeHmm = convertScreenPixelToHmm( aSizePixel );
338 : }
339 136 : return aSizeHmm;
340 : }
341 :
342 246 : } // namespace oox
343 :
344 : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */
|