1 /************************************************************** 2 * 3 * Licensed to the Apache Software Foundation (ASF) under one 4 * or more contributor license agreements. See the NOTICE file 5 * distributed with this work for additional information 6 * regarding copyright ownership. The ASF licenses this file 7 * to you under the Apache License, Version 2.0 (the 8 * "License"); you may not use this file except in compliance 9 * with the License. You may obtain a copy of the License at 10 * 11 * http://www.apache.org/licenses/LICENSE-2.0 12 * 13 * Unless required by applicable law or agreed to in writing, 14 * software distributed under the License is distributed on an 15 * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY 16 * KIND, either express or implied. See the License for the 17 * specific language governing permissions and limitations 18 * under the License. 19 * 20 *************************************************************/ 21 22 23 24 #include "oox/helper/graphichelper.hxx" 25 26 #include <com/sun/star/awt/Point.hpp> 27 #include <com/sun/star/awt/Size.hpp> 28 #include <com/sun/star/awt/XDevice.hpp> 29 #include <com/sun/star/awt/XUnitConversion.hpp> 30 #include <com/sun/star/beans/XPropertySet.hpp> 31 #include <com/sun/star/frame/XFramesSupplier.hpp> 32 #include <com/sun/star/graphic/GraphicObject.hpp> 33 #include <com/sun/star/graphic/XGraphicProvider.hpp> 34 #include <com/sun/star/util/MeasureUnit.hpp> 35 #include <comphelper/seqstream.hxx> 36 #include "oox/helper/containerhelper.hxx" 37 #include "oox/helper/propertyset.hxx" 38 #include "oox/token/tokens.hxx" 39 40 namespace oox { 41 42 // ============================================================================ 43 44 using namespace ::com::sun::star::awt; 45 using namespace ::com::sun::star::beans; 46 using namespace ::com::sun::star::frame; 47 using namespace ::com::sun::star::graphic; 48 using namespace ::com::sun::star::io; 49 using namespace ::com::sun::star::lang; 50 using namespace ::com::sun::star::uno; 51 52 using ::rtl::OUString; 53 54 // ============================================================================ 55 56 namespace { 57 58 inline sal_Int32 lclConvertScreenPixelToHmm( double fPixel, double fPixelPerHmm ) 59 { 60 return static_cast< sal_Int32 >( (fPixelPerHmm > 0.0) ? (fPixel / fPixelPerHmm + 0.5) : 0.0 ); 61 } 62 63 } // namespace 64 65 // ============================================================================ 66 67 GraphicHelper::GraphicHelper( const Reference< XComponentContext >& rxContext, const Reference< XFrame >& rxTargetFrame, const StorageRef& rxStorage ) : 68 mxContext( rxContext ), 69 mxStorage( rxStorage ), 70 maGraphicObjScheme( CREATE_OUSTRING( "vnd.sun.star.GraphicObject:" ) ) 71 { 72 OSL_ENSURE( mxContext.is(), "GraphicHelper::GraphicHelper - missing component context" ); 73 Reference< XMultiServiceFactory > xFactory( mxContext->getServiceManager(), UNO_QUERY ); 74 OSL_ENSURE( xFactory.is(), "GraphicHelper::GraphicHelper - missing service factory" ); 75 if( xFactory.is() ) 76 mxGraphicProvider.set( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.graphic.GraphicProvider" ) ), UNO_QUERY ); 77 78 //! TODO: get colors from system 79 maSystemPalette[ XML_3dDkShadow ] = 0x716F64; 80 maSystemPalette[ XML_3dLight ] = 0xF1EFE2; 81 maSystemPalette[ XML_activeBorder ] = 0xD4D0C8; 82 maSystemPalette[ XML_activeCaption ] = 0x0054E3; 83 maSystemPalette[ XML_appWorkspace ] = 0x808080; 84 maSystemPalette[ XML_background ] = 0x004E98; 85 maSystemPalette[ XML_btnFace ] = 0xECE9D8; 86 maSystemPalette[ XML_btnHighlight ] = 0xFFFFFF; 87 maSystemPalette[ XML_btnShadow ] = 0xACA899; 88 maSystemPalette[ XML_btnText ] = 0x000000; 89 maSystemPalette[ XML_captionText ] = 0xFFFFFF; 90 maSystemPalette[ XML_gradientActiveCaption ] = 0x3D95FF; 91 maSystemPalette[ XML_gradientInactiveCaption ] = 0xD8E4F8; 92 maSystemPalette[ XML_grayText ] = 0xACA899; 93 maSystemPalette[ XML_highlight ] = 0x316AC5; 94 maSystemPalette[ XML_highlightText ] = 0xFFFFFF; 95 maSystemPalette[ XML_hotLight ] = 0x000080; 96 maSystemPalette[ XML_inactiveBorder ] = 0xD4D0C8; 97 maSystemPalette[ XML_inactiveCaption ] = 0x7A96DF; 98 maSystemPalette[ XML_inactiveCaptionText ] = 0xD8E4F8; 99 maSystemPalette[ XML_infoBk ] = 0xFFFFE1; 100 maSystemPalette[ XML_infoText ] = 0x000000; 101 maSystemPalette[ XML_menu ] = 0xFFFFFF; 102 maSystemPalette[ XML_menuBar ] = 0xECE9D8; 103 maSystemPalette[ XML_menuHighlight ] = 0x316AC5; 104 maSystemPalette[ XML_menuText ] = 0x000000; 105 maSystemPalette[ XML_scrollBar ] = 0xD4D0C8; 106 maSystemPalette[ XML_window ] = 0xFFFFFF; 107 maSystemPalette[ XML_windowFrame ] = 0x000000; 108 maSystemPalette[ XML_windowText ] = 0x000000; 109 110 // if no target frame has been passed (e.g. OLE objects), try to fallback to the active frame 111 // TODO: we need some mechanism to keep and pass the parent frame 112 Reference< XFrame > xFrame = rxTargetFrame; 113 if( !xFrame.is() && xFactory.is() ) try 114 { 115 Reference< XFramesSupplier > xFramesSupp( xFactory->createInstance( CREATE_OUSTRING( "com.sun.star.frame.Desktop" ) ), UNO_QUERY_THROW ); 116 xFrame = xFramesSupp->getActiveFrame(); 117 } 118 catch( Exception& ) 119 { 120 } 121 122 // get the metric of the output device 123 OSL_ENSURE( xFrame.is(), "GraphicHelper::GraphicHelper - cannot get target frame" ); 124 maDeviceInfo.PixelPerMeterX = maDeviceInfo.PixelPerMeterY = 3500.0; // some default just in case 125 if( xFrame.is() ) try 126 { 127 Reference< XDevice > xDevice( xFrame->getContainerWindow(), UNO_QUERY_THROW ); 128 mxUnitConversion.set( xDevice, UNO_QUERY ); 129 OSL_ENSURE( mxUnitConversion.is(), "GraphicHelper::GraphicHelper - cannot get unit converter" ); 130 maDeviceInfo = xDevice->getInfo(); 131 } 132 catch( Exception& ) 133 { 134 OSL_ENSURE( false, "GraphicHelper::GraphicHelper - cannot get output device info" ); 135 } 136 mfPixelPerHmmX = maDeviceInfo.PixelPerMeterX / 100000.0; 137 mfPixelPerHmmY = maDeviceInfo.PixelPerMeterY / 100000.0; 138 } 139 140 GraphicHelper::~GraphicHelper() 141 { 142 } 143 144 // System colors and predefined colors ---------------------------------------- 145 146 sal_Int32 GraphicHelper::getSystemColor( sal_Int32 nToken, sal_Int32 nDefaultRgb ) const 147 { 148 return ContainerHelper::getMapElement( maSystemPalette, nToken, nDefaultRgb ); 149 } 150 151 sal_Int32 GraphicHelper::getSchemeColor( sal_Int32 /*nToken*/ ) const 152 { 153 OSL_ENSURE( false, "GraphicHelper::getSchemeColor - scheme colors not implemented" ); 154 return API_RGB_TRANSPARENT; 155 } 156 157 sal_Int32 GraphicHelper::getPaletteColor( sal_Int32 /*nPaletteIdx*/ ) const 158 { 159 OSL_ENSURE( false, "GraphicHelper::getPaletteColor - palette colors not implemented" ); 160 return API_RGB_TRANSPARENT; 161 } 162 163 // Device info and device dependent unit conversion --------------------------- 164 165 const DeviceInfo& GraphicHelper::getDeviceInfo() const 166 { 167 return maDeviceInfo; 168 } 169 170 sal_Int32 GraphicHelper::convertScreenPixelXToHmm( double fPixelX ) const 171 { 172 return lclConvertScreenPixelToHmm( fPixelX, mfPixelPerHmmX ); 173 } 174 175 sal_Int32 GraphicHelper::convertScreenPixelYToHmm( double fPixelY ) const 176 { 177 return lclConvertScreenPixelToHmm( fPixelY, mfPixelPerHmmY ); 178 } 179 180 Point GraphicHelper::convertScreenPixelToHmm( const Point& rPixel ) const 181 { 182 return Point( convertScreenPixelXToHmm( rPixel.X ), convertScreenPixelYToHmm( rPixel.Y ) ); 183 } 184 185 Size GraphicHelper::convertScreenPixelToHmm( const Size& rPixel ) const 186 { 187 return Size( convertScreenPixelXToHmm( rPixel.Width ), convertScreenPixelYToHmm( rPixel.Height ) ); 188 } 189 190 double GraphicHelper::convertHmmToScreenPixelX( sal_Int32 nHmmX ) const 191 { 192 return nHmmX * mfPixelPerHmmX; 193 } 194 195 double GraphicHelper::convertHmmToScreenPixelY( sal_Int32 nHmmY ) const 196 { 197 return nHmmY * mfPixelPerHmmY; 198 } 199 200 Point GraphicHelper::convertHmmToScreenPixel( const Point& rHmm ) const 201 { 202 return Point( 203 static_cast< sal_Int32 >( convertHmmToScreenPixelX( rHmm.X ) + 0.5 ), 204 static_cast< sal_Int32 >( convertHmmToScreenPixelY( rHmm.Y ) + 0.5 ) ); 205 } 206 207 Size GraphicHelper::convertHmmToScreenPixel( const Size& rHmm ) const 208 { 209 return Size( 210 static_cast< sal_Int32 >( convertHmmToScreenPixelX( rHmm.Width ) + 0.5 ), 211 static_cast< sal_Int32 >( convertHmmToScreenPixelY( rHmm.Height ) + 0.5 ) ); 212 } 213 214 Point GraphicHelper::convertAppFontToHmm( const Point& rAppFont ) const 215 { 216 if( mxUnitConversion.is() ) try 217 { 218 Point aPixel = mxUnitConversion->convertPointToPixel( rAppFont, ::com::sun::star::util::MeasureUnit::APPFONT ); 219 return convertScreenPixelToHmm( aPixel ); 220 } 221 catch( Exception& ) 222 { 223 } 224 return Point( 0, 0 ); 225 } 226 227 Size GraphicHelper::convertAppFontToHmm( const Size& rAppFont ) const 228 { 229 if( mxUnitConversion.is() ) try 230 { 231 Size aPixel = mxUnitConversion->convertSizeToPixel( rAppFont, ::com::sun::star::util::MeasureUnit::APPFONT ); 232 return convertScreenPixelToHmm( aPixel ); 233 } 234 catch( Exception& ) 235 { 236 } 237 return Size( 0, 0 ); 238 } 239 240 Point GraphicHelper::convertHmmToAppFont( const Point& rHmm ) const 241 { 242 if( mxUnitConversion.is() ) try 243 { 244 Point aPixel = convertHmmToScreenPixel( rHmm ); 245 return mxUnitConversion->convertPointToLogic( aPixel, ::com::sun::star::util::MeasureUnit::APPFONT ); 246 } 247 catch( Exception& ) 248 { 249 } 250 return Point( 0, 0 ); 251 } 252 253 Size GraphicHelper::convertHmmToAppFont( const Size& rHmm ) const 254 { 255 if( mxUnitConversion.is() ) try 256 { 257 Size aPixel = convertHmmToScreenPixel( rHmm ); 258 return mxUnitConversion->convertSizeToLogic( aPixel, ::com::sun::star::util::MeasureUnit::APPFONT ); 259 } 260 catch( Exception& ) 261 { 262 } 263 return Size( 0, 0 ); 264 } 265 266 // Graphics and graphic objects ---------------------------------------------- 267 268 Reference< XGraphic > GraphicHelper::importGraphic( const Reference< XInputStream >& rxInStrm ) const 269 { 270 Reference< XGraphic > xGraphic; 271 if( rxInStrm.is() && mxGraphicProvider.is() ) try 272 { 273 Sequence< PropertyValue > aArgs( 1 ); 274 aArgs[ 0 ].Name = CREATE_OUSTRING( "InputStream" ); 275 aArgs[ 0 ].Value <<= rxInStrm; 276 xGraphic = mxGraphicProvider->queryGraphic( aArgs ); 277 } 278 catch( Exception& ) 279 { 280 } 281 return xGraphic; 282 } 283 284 Reference< XGraphic > GraphicHelper::importGraphic( const StreamDataSequence& rGraphicData ) const 285 { 286 Reference< XGraphic > xGraphic; 287 if( rGraphicData.hasElements() ) 288 { 289 Reference< XInputStream > xInStrm( new ::comphelper::SequenceInputStream( rGraphicData ) ); 290 xGraphic = importGraphic( xInStrm ); 291 } 292 return xGraphic; 293 } 294 295 Reference< XGraphic > GraphicHelper::importEmbeddedGraphic( const OUString& rStreamName ) const 296 { 297 Reference< XGraphic > xGraphic; 298 OSL_ENSURE( rStreamName.getLength() > 0, "GraphicHelper::importEmbeddedGraphic - empty stream name" ); 299 if( rStreamName.getLength() > 0 ) 300 { 301 EmbeddedGraphicMap::const_iterator aIt = maEmbeddedGraphics.find( rStreamName ); 302 if( aIt == maEmbeddedGraphics.end() ) 303 { 304 xGraphic = importGraphic( mxStorage->openInputStream( rStreamName ) ); 305 if( xGraphic.is() ) 306 maEmbeddedGraphics[ rStreamName ] = xGraphic; 307 } 308 else 309 xGraphic = aIt->second; 310 } 311 return xGraphic; 312 } 313 314 OUString GraphicHelper::createGraphicObject( const Reference< XGraphic >& rxGraphic ) const 315 { 316 OUString aGraphicObjUrl; 317 if( mxContext.is() && rxGraphic.is() ) try 318 { 319 Reference< XGraphicObject > xGraphicObj( GraphicObject::create( mxContext ), UNO_SET_THROW ); 320 xGraphicObj->setGraphic( rxGraphic ); 321 maGraphicObjects.push_back( xGraphicObj ); 322 aGraphicObjUrl = maGraphicObjScheme + xGraphicObj->getUniqueID(); 323 } 324 catch( Exception& ) 325 { 326 } 327 return aGraphicObjUrl; 328 } 329 330 OUString GraphicHelper::importGraphicObject( const Reference< XInputStream >& rxInStrm ) const 331 { 332 return createGraphicObject( importGraphic( rxInStrm ) ); 333 } 334 335 OUString GraphicHelper::importGraphicObject( const StreamDataSequence& rGraphicData ) const 336 { 337 return createGraphicObject( importGraphic( rGraphicData ) ); 338 } 339 340 OUString GraphicHelper::importEmbeddedGraphicObject( const OUString& rStreamName ) const 341 { 342 Reference< XGraphic > xGraphic = importEmbeddedGraphic( rStreamName ); 343 return xGraphic.is() ? createGraphicObject( xGraphic ) : OUString(); 344 } 345 346 Size GraphicHelper::getOriginalSize( const Reference< XGraphic >& xGraphic ) const 347 { 348 Size aSizeHmm; 349 PropertySet aPropSet( xGraphic ); 350 if( aPropSet.getProperty( aSizeHmm, PROP_Size100thMM ) && (aSizeHmm.Width == 0) && (aSizeHmm.Height == 0) ) // MAPMODE_PIXEL used? 351 { 352 Size aSizePixel( 0, 0 ); 353 if( aPropSet.getProperty( aSizePixel, PROP_SizePixel ) ) 354 aSizeHmm = convertScreenPixelToHmm( aSizePixel ); 355 } 356 return aSizeHmm; 357 } 358 359 // ============================================================================ 360 361 } // namespace oox 362