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 <com/sun/star/container/XNameContainer.hpp>
21 #include "oox/helper/graphichelper.hxx"
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 <comphelper/seqstream.hxx>
35 #include <vcl/wmf.hxx>
36 #include "oox/helper/containerhelper.hxx"
37 #include "oox/helper/propertyset.hxx"
38 #include "oox/token/properties.hxx"
39 #include "oox/token/tokens.hxx"
43 // ============================================================================
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
;
54 // ============================================================================
58 inline sal_Int32
lclConvertScreenPixelToHmm( double fPixel
, double fPixelPerHmm
)
60 return static_cast< sal_Int32
>( (fPixelPerHmm
> 0.0) ? (fPixel
/ fPixelPerHmm
+ 0.5) : 0.0 );
65 // ============================================================================
67 GraphicHelper::GraphicHelper( const Reference
< XComponentContext
>& rxContext
, const Reference
< XFrame
>& rxTargetFrame
, const StorageRef
& rxStorage
) :
68 mxContext( rxContext
),
69 mxStorage( rxStorage
),
70 maGraphicObjScheme( "vnd.sun.star.GraphicObject:" )
72 OSL_ENSURE( mxContext
.is(), "GraphicHelper::GraphicHelper - missing component context" );
74 mxGraphicProvider
.set( graphic::GraphicProvider::create( mxContext
) );
76 //! TODO: get colors from system
77 maSystemPalette
[ XML_3dDkShadow
] = 0x716F64;
78 maSystemPalette
[ XML_3dLight
] = 0xF1EFE2;
79 maSystemPalette
[ XML_activeBorder
] = 0xD4D0C8;
80 maSystemPalette
[ XML_activeCaption
] = 0x0054E3;
81 maSystemPalette
[ XML_appWorkspace
] = 0x808080;
82 maSystemPalette
[ XML_background
] = 0x004E98;
83 maSystemPalette
[ XML_btnFace
] = 0xECE9D8;
84 maSystemPalette
[ XML_btnHighlight
] = 0xFFFFFF;
85 maSystemPalette
[ XML_btnShadow
] = 0xACA899;
86 maSystemPalette
[ XML_btnText
] = 0x000000;
87 maSystemPalette
[ XML_captionText
] = 0xFFFFFF;
88 maSystemPalette
[ XML_gradientActiveCaption
] = 0x3D95FF;
89 maSystemPalette
[ XML_gradientInactiveCaption
] = 0xD8E4F8;
90 maSystemPalette
[ XML_grayText
] = 0xACA899;
91 maSystemPalette
[ XML_highlight
] = 0x316AC5;
92 maSystemPalette
[ XML_highlightText
] = 0xFFFFFF;
93 maSystemPalette
[ XML_hotLight
] = 0x000080;
94 maSystemPalette
[ XML_inactiveBorder
] = 0xD4D0C8;
95 maSystemPalette
[ XML_inactiveCaption
] = 0x7A96DF;
96 maSystemPalette
[ XML_inactiveCaptionText
] = 0xD8E4F8;
97 maSystemPalette
[ XML_infoBk
] = 0xFFFFE1;
98 maSystemPalette
[ XML_infoText
] = 0x000000;
99 maSystemPalette
[ XML_menu
] = 0xFFFFFF;
100 maSystemPalette
[ XML_menuBar
] = 0xECE9D8;
101 maSystemPalette
[ XML_menuHighlight
] = 0x316AC5;
102 maSystemPalette
[ XML_menuText
] = 0x000000;
103 maSystemPalette
[ XML_scrollBar
] = 0xD4D0C8;
104 maSystemPalette
[ XML_window
] = 0xFFFFFF;
105 maSystemPalette
[ XML_windowFrame
] = 0x000000;
106 maSystemPalette
[ XML_windowText
] = 0x000000;
108 // if no target frame has been passed (e.g. OLE objects), try to fallback to the active frame
109 // TODO: we need some mechanism to keep and pass the parent frame
110 Reference
< XFrame
> xFrame
= rxTargetFrame
;
111 if( !xFrame
.is() && mxContext
.is() ) try
113 Reference
< XDesktop2
> xFramesSupp
= Desktop::create( mxContext
);
114 xFrame
= xFramesSupp
->getActiveFrame();
120 // get the metric of the output device
121 OSL_ENSURE( xFrame
.is(), "GraphicHelper::GraphicHelper - cannot get target frame" );
122 maDeviceInfo
.PixelPerMeterX
= maDeviceInfo
.PixelPerMeterY
= 3500.0; // some default just in case
123 if( xFrame
.is() ) try
125 Reference
< awt::XDevice
> xDevice( xFrame
->getContainerWindow(), UNO_QUERY_THROW
);
126 mxUnitConversion
.set( xDevice
, UNO_QUERY
);
127 OSL_ENSURE( mxUnitConversion
.is(), "GraphicHelper::GraphicHelper - cannot get unit converter" );
128 maDeviceInfo
= xDevice
->getInfo();
132 OSL_FAIL( "GraphicHelper::GraphicHelper - cannot get output device info" );
134 mfPixelPerHmmX
= maDeviceInfo
.PixelPerMeterX
/ 100000.0;
135 mfPixelPerHmmY
= maDeviceInfo
.PixelPerMeterY
/ 100000.0;
138 GraphicHelper::~GraphicHelper()
142 // System colors and predefined colors ----------------------------------------
144 sal_Int32
GraphicHelper::getSystemColor( sal_Int32 nToken
, sal_Int32 nDefaultRgb
) const
146 return ContainerHelper::getMapElement( maSystemPalette
, nToken
, nDefaultRgb
);
149 sal_Int32
GraphicHelper::getSchemeColor( sal_Int32
/*nToken*/ ) const
151 OSL_FAIL( "GraphicHelper::getSchemeColor - scheme colors not implemented" );
152 return API_RGB_TRANSPARENT
;
155 sal_Int32
GraphicHelper::getPaletteColor( sal_Int32
/*nPaletteIdx*/ ) const
157 OSL_FAIL( "GraphicHelper::getPaletteColor - palette colors not implemented" );
158 return API_RGB_TRANSPARENT
;
161 // Device info and device dependent unit conversion ---------------------------
163 const awt::DeviceInfo
& GraphicHelper::getDeviceInfo() const
168 sal_Int32
GraphicHelper::convertScreenPixelXToHmm( double fPixelX
) const
170 return lclConvertScreenPixelToHmm( fPixelX
, mfPixelPerHmmX
);
173 sal_Int32
GraphicHelper::convertScreenPixelYToHmm( double fPixelY
) const
175 return lclConvertScreenPixelToHmm( fPixelY
, mfPixelPerHmmY
);
178 awt::Size
GraphicHelper::convertScreenPixelToHmm( const awt::Size
& rPixel
) const
180 return awt::Size( convertScreenPixelXToHmm( rPixel
.Width
), convertScreenPixelYToHmm( rPixel
.Height
) );
183 double GraphicHelper::convertHmmToScreenPixelX( sal_Int32 nHmmX
) const
185 return nHmmX
* mfPixelPerHmmX
;
188 double GraphicHelper::convertHmmToScreenPixelY( sal_Int32 nHmmY
) const
190 return nHmmY
* mfPixelPerHmmY
;
193 awt::Point
GraphicHelper::convertHmmToScreenPixel( const awt::Point
& rHmm
) const
196 static_cast< sal_Int32
>( convertHmmToScreenPixelX( rHmm
.X
) + 0.5 ),
197 static_cast< sal_Int32
>( convertHmmToScreenPixelY( rHmm
.Y
) + 0.5 ) );
200 awt::Size
GraphicHelper::convertHmmToScreenPixel( const awt::Size
& rHmm
) const
203 static_cast< sal_Int32
>( convertHmmToScreenPixelX( rHmm
.Width
) + 0.5 ),
204 static_cast< sal_Int32
>( convertHmmToScreenPixelY( rHmm
.Height
) + 0.5 ) );
207 awt::Point
GraphicHelper::convertHmmToAppFont( const awt::Point
& rHmm
) const
209 if( mxUnitConversion
.is() ) try
211 awt::Point aPixel
= convertHmmToScreenPixel( rHmm
);
212 return mxUnitConversion
->convertPointToLogic( aPixel
, ::com::sun::star::util::MeasureUnit::APPFONT
);
217 return awt::Point( 0, 0 );
220 awt::Size
GraphicHelper::convertHmmToAppFont( const awt::Size
& rHmm
) const
222 if( mxUnitConversion
.is() ) try
224 awt::Size aPixel
= convertHmmToScreenPixel( rHmm
);
225 return mxUnitConversion
->convertSizeToLogic( aPixel
, ::com::sun::star::util::MeasureUnit::APPFONT
);
230 return awt::Size( 0, 0 );
233 // Graphics and graphic objects ----------------------------------------------
235 Reference
< XGraphic
> GraphicHelper::importGraphic( const Reference
< XInputStream
>& rxInStrm
,
236 const WMF_EXTERNALHEADER
* pExtHeader
) const
238 Reference
< XGraphic
> xGraphic
;
239 if( rxInStrm
.is() && mxGraphicProvider
.is() ) try
241 Sequence
< PropertyValue
> aArgs( 1 );
242 aArgs
[ 0 ].Name
= "InputStream";
243 aArgs
[ 0 ].Value
<<= rxInStrm
;
245 if ( pExtHeader
&& pExtHeader
->mapMode
> 0 )
247 aArgs
.realloc( aArgs
.getLength() + 1 );
248 Sequence
< PropertyValue
> aFilterData( 3 );
249 aFilterData
[ 0 ].Name
= "ExternalWidth";
250 aFilterData
[ 0 ].Value
<<= pExtHeader
->xExt
;
251 aFilterData
[ 1 ].Name
= "ExternalHeight";
252 aFilterData
[ 1 ].Value
<<= pExtHeader
->yExt
;
253 aFilterData
[ 2 ].Name
= "ExternalMapMode";
254 aFilterData
[ 2 ].Value
<<= pExtHeader
->mapMode
;
255 aArgs
[ 1 ].Name
= "FilterData";
256 aArgs
[ 1 ].Value
<<= aFilterData
;
259 xGraphic
= mxGraphicProvider
->queryGraphic( aArgs
);
267 Reference
< XGraphic
> GraphicHelper::importGraphic( const StreamDataSequence
& rGraphicData
) const
269 Reference
< XGraphic
> xGraphic
;
270 if( rGraphicData
.hasElements() )
272 Reference
< XInputStream
> xInStrm( new ::comphelper::SequenceInputStream( rGraphicData
) );
273 xGraphic
= importGraphic( xInStrm
);
278 Reference
< XGraphic
> GraphicHelper::importEmbeddedGraphic( const OUString
& rStreamName
) const
280 Reference
< XGraphic
> xGraphic
;
281 OSL_ENSURE( !rStreamName
.isEmpty(), "GraphicHelper::importEmbeddedGraphic - empty stream name" );
282 if( !rStreamName
.isEmpty() )
284 EmbeddedGraphicMap::const_iterator aIt
= maEmbeddedGraphics
.find( rStreamName
);
285 if( aIt
== maEmbeddedGraphics
.end() )
287 xGraphic
= importGraphic( mxStorage
->openInputStream( rStreamName
) );
289 maEmbeddedGraphics
[ rStreamName
] = xGraphic
;
292 xGraphic
= aIt
->second
;
297 OUString
GraphicHelper::createGraphicObject( const Reference
< XGraphic
>& rxGraphic
) const
299 OUString aGraphicObjUrl
;
300 if( mxContext
.is() && rxGraphic
.is() ) try
302 Reference
< XGraphicObject
> xGraphicObj( graphic::GraphicObject::create( mxContext
), UNO_SET_THROW
);
303 xGraphicObj
->setGraphic( rxGraphic
);
304 maGraphicObjects
.push_back( xGraphicObj
);
305 aGraphicObjUrl
= maGraphicObjScheme
+ xGraphicObj
->getUniqueID();
310 return aGraphicObjUrl
;
313 OUString
GraphicHelper::importGraphicObject( const Reference
< XInputStream
>& rxInStrm
,
314 const WMF_EXTERNALHEADER
* pExtHeader
) const
316 return createGraphicObject( importGraphic( rxInStrm
, pExtHeader
) );
319 OUString
GraphicHelper::importGraphicObject( const StreamDataSequence
& rGraphicData
) const
321 return createGraphicObject( importGraphic( rGraphicData
) );
324 OUString
GraphicHelper::importEmbeddedGraphicObject( const OUString
& rStreamName
) const
326 Reference
< XGraphic
> xGraphic
= importEmbeddedGraphic( rStreamName
);
327 return xGraphic
.is() ? createGraphicObject( xGraphic
) : OUString();
330 awt::Size
GraphicHelper::getOriginalSize( const Reference
< XGraphic
>& xGraphic
) const
333 PropertySet
aPropSet( xGraphic
);
334 if( aPropSet
.getProperty( aSizeHmm
, PROP_Size100thMM
) && (aSizeHmm
.Width
== 0) && (aSizeHmm
.Height
== 0) ) // MAPMODE_PIXEL used?
336 awt::Size
aSizePixel( 0, 0 );
337 if( aPropSet
.getProperty( aSizePixel
, PROP_SizePixel
) )
338 aSizeHmm
= convertScreenPixelToHmm( aSizePixel
);
343 // ============================================================================
347 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */