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 <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"
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
;
56 inline sal_Int32
lclConvertScreenPixelToHmm( double fPixel
, double fPixelPerHmm
)
58 return static_cast< sal_Int32
>( (fPixelPerHmm
> 0.0) ? (fPixel
/ fPixelPerHmm
+ 0.5) : 0.0 );
63 GraphicHelper::GraphicHelper( const Reference
< XComponentContext
>& rxContext
, const Reference
< XFrame
>& rxTargetFrame
, const StorageRef
& rxStorage
) :
64 mxContext( rxContext
),
65 mxStorage( rxStorage
),
66 maGraphicObjScheme( "vnd.sun.star.GraphicObject:" )
68 OSL_ENSURE( mxContext
.is(), "GraphicHelper::GraphicHelper - missing component context" );
70 mxGraphicProvider
.set( graphic::GraphicProvider::create( mxContext
) );
72 //! TODO: get colors from system
73 maSystemPalette
[ XML_3dDkShadow
] = 0x716F64;
74 maSystemPalette
[ XML_3dLight
] = 0xF1EFE2;
75 maSystemPalette
[ XML_activeBorder
] = 0xD4D0C8;
76 maSystemPalette
[ XML_activeCaption
] = 0x0054E3;
77 maSystemPalette
[ XML_appWorkspace
] = 0x808080;
78 maSystemPalette
[ XML_background
] = 0x004E98;
79 maSystemPalette
[ XML_btnFace
] = 0xECE9D8;
80 maSystemPalette
[ XML_btnHighlight
] = 0xFFFFFF;
81 maSystemPalette
[ XML_btnShadow
] = 0xACA899;
82 maSystemPalette
[ XML_btnText
] = 0x000000;
83 maSystemPalette
[ XML_captionText
] = 0xFFFFFF;
84 maSystemPalette
[ XML_gradientActiveCaption
] = 0x3D95FF;
85 maSystemPalette
[ XML_gradientInactiveCaption
] = 0xD8E4F8;
86 maSystemPalette
[ XML_grayText
] = 0xACA899;
87 maSystemPalette
[ XML_highlight
] = 0x316AC5;
88 maSystemPalette
[ XML_highlightText
] = 0xFFFFFF;
89 maSystemPalette
[ XML_hotLight
] = 0x000080;
90 maSystemPalette
[ XML_inactiveBorder
] = 0xD4D0C8;
91 maSystemPalette
[ XML_inactiveCaption
] = 0x7A96DF;
92 maSystemPalette
[ XML_inactiveCaptionText
] = 0xD8E4F8;
93 maSystemPalette
[ XML_infoBk
] = 0xFFFFE1;
94 maSystemPalette
[ XML_infoText
] = 0x000000;
95 maSystemPalette
[ XML_menu
] = 0xFFFFFF;
96 maSystemPalette
[ XML_menuBar
] = 0xECE9D8;
97 maSystemPalette
[ XML_menuHighlight
] = 0x316AC5;
98 maSystemPalette
[ XML_menuText
] = 0x000000;
99 maSystemPalette
[ XML_scrollBar
] = 0xD4D0C8;
100 maSystemPalette
[ XML_window
] = 0xFFFFFF;
101 maSystemPalette
[ XML_windowFrame
] = 0x000000;
102 maSystemPalette
[ XML_windowText
] = 0x000000;
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 Reference
< XFrame
> xFrame
= rxTargetFrame
;
107 if( !xFrame
.is() && mxContext
.is() ) try
109 Reference
< XDesktop2
> xFramesSupp
= Desktop::create( mxContext
);
110 xFrame
= xFramesSupp
->getActiveFrame();
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 Size aDefault
= Application::GetDefaultDevice()->LogicToPixel(Size(100000, 100000), MapMode(MapUnit::Map100thMM
));
120 maDeviceInfo
.PixelPerMeterX
= aDefault
.Width();
121 maDeviceInfo
.PixelPerMeterY
= aDefault
.Height();
122 if( xFrame
.is() ) try
124 Reference
< awt::XDevice
> xDevice( xFrame
->getContainerWindow(), UNO_QUERY_THROW
);
125 mxUnitConversion
.set( xDevice
, UNO_QUERY
);
126 OSL_ENSURE( mxUnitConversion
.is(), "GraphicHelper::GraphicHelper - cannot get unit converter" );
127 maDeviceInfo
= xDevice
->getInfo();
131 OSL_FAIL( "GraphicHelper::GraphicHelper - cannot get output device info" );
133 mfPixelPerHmmX
= maDeviceInfo
.PixelPerMeterX
/ 100000.0;
134 mfPixelPerHmmY
= maDeviceInfo
.PixelPerMeterY
/ 100000.0;
137 GraphicHelper::~GraphicHelper()
141 // System colors and predefined colors ----------------------------------------
143 sal_Int32
GraphicHelper::getSystemColor( sal_Int32 nToken
, sal_Int32 nDefaultRgb
) const
145 return ContainerHelper::getMapElement( maSystemPalette
, nToken
, nDefaultRgb
);
148 sal_Int32
GraphicHelper::getSchemeColor( sal_Int32
/*nToken*/ ) const
150 OSL_FAIL( "GraphicHelper::getSchemeColor - scheme colors not implemented" );
151 return API_RGB_TRANSPARENT
;
154 sal_Int32
GraphicHelper::getPaletteColor( sal_Int32
/*nPaletteIdx*/ ) const
156 OSL_FAIL( "GraphicHelper::getPaletteColor - palette colors not implemented" );
157 return API_RGB_TRANSPARENT
;
160 sal_Int32
GraphicHelper::getDefaultChartAreaFillStyle() const
162 return XML_solidFill
;
165 // Device info and device dependent unit conversion ---------------------------
167 sal_Int32
GraphicHelper::convertScreenPixelXToHmm( double fPixelX
) const
169 return lclConvertScreenPixelToHmm( fPixelX
, mfPixelPerHmmX
);
172 sal_Int32
GraphicHelper::convertScreenPixelYToHmm( double fPixelY
) const
174 return lclConvertScreenPixelToHmm( fPixelY
, mfPixelPerHmmY
);
177 awt::Size
GraphicHelper::convertScreenPixelToHmm( const awt::Size
& rPixel
) const
179 return awt::Size( convertScreenPixelXToHmm( rPixel
.Width
), convertScreenPixelYToHmm( rPixel
.Height
) );
182 double GraphicHelper::convertHmmToScreenPixelX( sal_Int32 nHmmX
) const
184 return nHmmX
* mfPixelPerHmmX
;
187 double GraphicHelper::convertHmmToScreenPixelY( sal_Int32 nHmmY
) const
189 return nHmmY
* mfPixelPerHmmY
;
192 awt::Point
GraphicHelper::convertHmmToScreenPixel( const awt::Point
& rHmm
) const
195 static_cast< sal_Int32
>( convertHmmToScreenPixelX( rHmm
.X
) + 0.5 ),
196 static_cast< sal_Int32
>( convertHmmToScreenPixelY( rHmm
.Y
) + 0.5 ) );
199 awt::Size
GraphicHelper::convertHmmToScreenPixel( const awt::Size
& rHmm
) const
202 static_cast< sal_Int32
>( convertHmmToScreenPixelX( rHmm
.Width
) + 0.5 ),
203 static_cast< sal_Int32
>( convertHmmToScreenPixelY( rHmm
.Height
) + 0.5 ) );
206 awt::Point
GraphicHelper::convertHmmToAppFont( const awt::Point
& rHmm
) const
208 if( mxUnitConversion
.is() ) try
210 awt::Point aPixel
= convertHmmToScreenPixel( rHmm
);
211 return mxUnitConversion
->convertPointToLogic( aPixel
, css::util::MeasureUnit::APPFONT
);
216 return awt::Point( 0, 0 );
219 awt::Size
GraphicHelper::convertHmmToAppFont( const awt::Size
& rHmm
) const
221 if( mxUnitConversion
.is() ) try
223 awt::Size aPixel
= convertHmmToScreenPixel( rHmm
);
224 return mxUnitConversion
->convertSizeToLogic( aPixel
, css::util::MeasureUnit::APPFONT
);
229 return awt::Size( 0, 0 );
232 // Graphics and graphic objects ----------------------------------------------
234 Reference
< XGraphic
> GraphicHelper::importGraphic( const Reference
< XInputStream
>& rxInStrm
,
235 const WMF_EXTERNALHEADER
* pExtHeader
) const
237 Reference
< XGraphic
> xGraphic
;
238 if( rxInStrm
.is() && mxGraphicProvider
.is() ) try
240 Sequence
< PropertyValue
> aArgs( 1 );
241 aArgs
[ 0 ].Name
= "InputStream";
242 aArgs
[ 0 ].Value
<<= rxInStrm
;
244 if ( pExtHeader
&& pExtHeader
->mapMode
> 0 )
246 aArgs
.realloc( aArgs
.getLength() + 1 );
247 Sequence
< PropertyValue
> aFilterData( 3 );
248 aFilterData
[ 0 ].Name
= "ExternalWidth";
249 aFilterData
[ 0 ].Value
<<= pExtHeader
->xExt
;
250 aFilterData
[ 1 ].Name
= "ExternalHeight";
251 aFilterData
[ 1 ].Value
<<= pExtHeader
->yExt
;
252 aFilterData
[ 2 ].Name
= "ExternalMapMode";
253 aFilterData
[ 2 ].Value
<<= pExtHeader
->mapMode
;
254 aArgs
[ 1 ].Name
= "FilterData";
255 aArgs
[ 1 ].Value
<<= aFilterData
;
258 xGraphic
= mxGraphicProvider
->queryGraphic( aArgs
);
266 Reference
< XGraphic
> GraphicHelper::importGraphic( const StreamDataSequence
& rGraphicData
) const
268 Reference
< XGraphic
> xGraphic
;
269 if( rGraphicData
.hasElements() )
271 Reference
< XInputStream
> xInStrm( new ::comphelper::SequenceInputStream( rGraphicData
) );
272 xGraphic
= importGraphic( xInStrm
);
277 Reference
< XGraphic
> GraphicHelper::importEmbeddedGraphic( const OUString
& rStreamName
, const WMF_EXTERNALHEADER
* pExtHeader
) const
279 Reference
< XGraphic
> xGraphic
;
280 OSL_ENSURE( !rStreamName
.isEmpty(), "GraphicHelper::importEmbeddedGraphic - empty stream name" );
281 if( !rStreamName
.isEmpty() )
283 EmbeddedGraphicMap::const_iterator aIt
= maEmbeddedGraphics
.find( rStreamName
);
284 if( aIt
== maEmbeddedGraphics
.end() )
286 xGraphic
= importGraphic(mxStorage
->openInputStream(rStreamName
), pExtHeader
);
288 maEmbeddedGraphics
[ rStreamName
] = xGraphic
;
291 xGraphic
= aIt
->second
;
296 OUString
GraphicHelper::createGraphicObject( const Reference
< XGraphic
>& rxGraphic
) const
298 OUString aGraphicObjUrl
;
299 if( mxContext
.is() && rxGraphic
.is() ) try
301 Reference
< XGraphicObject
> xGraphicObj( graphic::GraphicObject::create( mxContext
), UNO_SET_THROW
);
302 xGraphicObj
->setGraphic( rxGraphic
);
303 maGraphicObjects
.push_back( xGraphicObj
);
304 aGraphicObjUrl
= maGraphicObjScheme
+ xGraphicObj
->getUniqueID();
309 return aGraphicObjUrl
;
312 OUString
GraphicHelper::importGraphicObject( const Reference
< XInputStream
>& rxInStrm
,
313 const WMF_EXTERNALHEADER
* pExtHeader
) const
315 return createGraphicObject( importGraphic( rxInStrm
, pExtHeader
) );
318 OUString
GraphicHelper::importGraphicObject( const StreamDataSequence
& rGraphicData
) const
320 return createGraphicObject( importGraphic( rGraphicData
) );
323 OUString
GraphicHelper::importEmbeddedGraphicObject( const OUString
& rStreamName
) const
325 Reference
< XGraphic
> xGraphic
= importEmbeddedGraphic( rStreamName
);
326 return xGraphic
.is() ? createGraphicObject( xGraphic
) : OUString();
329 awt::Size
GraphicHelper::getOriginalSize( const Reference
< XGraphic
>& xGraphic
) const
332 PropertySet
aPropSet( xGraphic
);
333 if( aPropSet
.getProperty( aSizeHmm
, PROP_Size100thMM
) && (aSizeHmm
.Width
== 0) && (aSizeHmm
.Height
== 0) ) // MAPMODE_PIXEL used?
335 awt::Size
aSizePixel( 0, 0 );
336 if( aPropSet
.getProperty( aSizePixel
, PROP_SizePixel
) )
337 aSizeHmm
= convertScreenPixelToHmm( aSizePixel
);
344 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */