1*cdf0e10cSrcweir /*************************************************************************
2*cdf0e10cSrcweir  *
3*cdf0e10cSrcweir  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4*cdf0e10cSrcweir  *
5*cdf0e10cSrcweir  * Copyright 2000, 2010 Oracle and/or its affiliates.
6*cdf0e10cSrcweir  *
7*cdf0e10cSrcweir  * OpenOffice.org - a multi-platform office productivity suite
8*cdf0e10cSrcweir  *
9*cdf0e10cSrcweir  * This file is part of OpenOffice.org.
10*cdf0e10cSrcweir  *
11*cdf0e10cSrcweir  * OpenOffice.org is free software: you can redistribute it and/or modify
12*cdf0e10cSrcweir  * it under the terms of the GNU Lesser General Public License version 3
13*cdf0e10cSrcweir  * only, as published by the Free Software Foundation.
14*cdf0e10cSrcweir  *
15*cdf0e10cSrcweir  * OpenOffice.org is distributed in the hope that it will be useful,
16*cdf0e10cSrcweir  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17*cdf0e10cSrcweir  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18*cdf0e10cSrcweir  * GNU Lesser General Public License version 3 for more details
19*cdf0e10cSrcweir  * (a copy is included in the LICENSE file that accompanied this code).
20*cdf0e10cSrcweir  *
21*cdf0e10cSrcweir  * You should have received a copy of the GNU Lesser General Public License
22*cdf0e10cSrcweir  * version 3 along with OpenOffice.org.  If not, see
23*cdf0e10cSrcweir  * <http://www.openoffice.org/license.html>
24*cdf0e10cSrcweir  * for a copy of the LGPLv3 License.
25*cdf0e10cSrcweir  *
26*cdf0e10cSrcweir  ************************************************************************/
27*cdf0e10cSrcweir 
28*cdf0e10cSrcweir #include "oox/drawingml/fillproperties.hxx"
29*cdf0e10cSrcweir 
30*cdf0e10cSrcweir #include <com/sun/star/lang/XMultiServiceFactory.hpp>
31*cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
32*cdf0e10cSrcweir #include <com/sun/star/awt/Gradient.hpp>
33*cdf0e10cSrcweir #include <com/sun/star/text/GraphicCrop.hpp>
34*cdf0e10cSrcweir #include <com/sun/star/awt/Size.hpp>
35*cdf0e10cSrcweir #include <com/sun/star/drawing/BitmapMode.hpp>
36*cdf0e10cSrcweir #include <com/sun/star/drawing/ColorMode.hpp>
37*cdf0e10cSrcweir #include <com/sun/star/drawing/FillStyle.hpp>
38*cdf0e10cSrcweir #include <com/sun/star/drawing/RectanglePoint.hpp>
39*cdf0e10cSrcweir #include <com/sun/star/graphic/XGraphicTransformer.hpp>
40*cdf0e10cSrcweir #include "oox/helper/graphichelper.hxx"
41*cdf0e10cSrcweir #include "oox/drawingml/drawingmltypes.hxx"
42*cdf0e10cSrcweir #include "oox/drawingml/shapepropertymap.hxx"
43*cdf0e10cSrcweir #include "oox/token/tokens.hxx"
44*cdf0e10cSrcweir 
45*cdf0e10cSrcweir using namespace ::com::sun::star;
46*cdf0e10cSrcweir using namespace ::com::sun::star::drawing;
47*cdf0e10cSrcweir using namespace ::com::sun::star::graphic;
48*cdf0e10cSrcweir 
49*cdf0e10cSrcweir using ::rtl::OUString;
50*cdf0e10cSrcweir using ::com::sun::star::uno::Reference;
51*cdf0e10cSrcweir using ::com::sun::star::uno::Exception;
52*cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY;
53*cdf0e10cSrcweir using ::com::sun::star::uno::UNO_QUERY_THROW;
54*cdf0e10cSrcweir using ::com::sun::star::geometry::IntegerRectangle2D;
55*cdf0e10cSrcweir 
56*cdf0e10cSrcweir namespace oox {
57*cdf0e10cSrcweir namespace drawingml {
58*cdf0e10cSrcweir 
59*cdf0e10cSrcweir // ============================================================================
60*cdf0e10cSrcweir 
61*cdf0e10cSrcweir namespace {
62*cdf0e10cSrcweir 
63*cdf0e10cSrcweir BitmapMode lclGetBitmapMode( sal_Int32 nToken )
64*cdf0e10cSrcweir {
65*cdf0e10cSrcweir     switch( nToken )
66*cdf0e10cSrcweir     {
67*cdf0e10cSrcweir         case XML_tile:      return BitmapMode_REPEAT;
68*cdf0e10cSrcweir         case XML_stretch:   return BitmapMode_STRETCH;
69*cdf0e10cSrcweir     }
70*cdf0e10cSrcweir     return BitmapMode_NO_REPEAT;
71*cdf0e10cSrcweir }
72*cdf0e10cSrcweir 
73*cdf0e10cSrcweir RectanglePoint lclGetRectanglePoint( sal_Int32 nToken )
74*cdf0e10cSrcweir {
75*cdf0e10cSrcweir     switch( nToken )
76*cdf0e10cSrcweir     {
77*cdf0e10cSrcweir         case XML_tl:    return RectanglePoint_LEFT_TOP;
78*cdf0e10cSrcweir         case XML_t:     return RectanglePoint_MIDDLE_TOP;
79*cdf0e10cSrcweir         case XML_tr:    return RectanglePoint_RIGHT_TOP;
80*cdf0e10cSrcweir         case XML_l:     return RectanglePoint_LEFT_MIDDLE;
81*cdf0e10cSrcweir         case XML_ctr:   return RectanglePoint_MIDDLE_MIDDLE;
82*cdf0e10cSrcweir         case XML_r:     return RectanglePoint_RIGHT_MIDDLE;
83*cdf0e10cSrcweir         case XML_bl:    return RectanglePoint_LEFT_BOTTOM;
84*cdf0e10cSrcweir         case XML_b:     return RectanglePoint_MIDDLE_BOTTOM;
85*cdf0e10cSrcweir         case XML_br:    return RectanglePoint_RIGHT_BOTTOM;
86*cdf0e10cSrcweir     }
87*cdf0e10cSrcweir     return RectanglePoint_LEFT_TOP;
88*cdf0e10cSrcweir }
89*cdf0e10cSrcweir 
90*cdf0e10cSrcweir const awt::Size lclGetOriginalSize( const GraphicHelper& rGraphicHelper, const Reference< XGraphic >& rxGraphic )
91*cdf0e10cSrcweir {
92*cdf0e10cSrcweir     awt::Size aSizeHmm( 0, 0 );
93*cdf0e10cSrcweir     try
94*cdf0e10cSrcweir     {
95*cdf0e10cSrcweir         Reference< beans::XPropertySet > xGraphicPropertySet( rxGraphic, UNO_QUERY_THROW );
96*cdf0e10cSrcweir         if( xGraphicPropertySet->getPropertyValue( CREATE_OUSTRING( "Size100thMM" ) ) >>= aSizeHmm )
97*cdf0e10cSrcweir         {
98*cdf0e10cSrcweir             if( !aSizeHmm.Width && !aSizeHmm.Height )
99*cdf0e10cSrcweir             {   // MAPMODE_PIXEL USED :-(
100*cdf0e10cSrcweir                 awt::Size aSourceSizePixel( 0, 0 );
101*cdf0e10cSrcweir                 if( xGraphicPropertySet->getPropertyValue( CREATE_OUSTRING( "SizePixel" ) ) >>= aSourceSizePixel )
102*cdf0e10cSrcweir                     aSizeHmm = rGraphicHelper.convertScreenPixelToHmm( aSourceSizePixel );
103*cdf0e10cSrcweir             }
104*cdf0e10cSrcweir         }
105*cdf0e10cSrcweir     }
106*cdf0e10cSrcweir     catch( Exception& )
107*cdf0e10cSrcweir     {
108*cdf0e10cSrcweir     }
109*cdf0e10cSrcweir     return aSizeHmm;
110*cdf0e10cSrcweir }
111*cdf0e10cSrcweir 
112*cdf0e10cSrcweir } // namespace
113*cdf0e10cSrcweir 
114*cdf0e10cSrcweir // ============================================================================
115*cdf0e10cSrcweir 
116*cdf0e10cSrcweir void GradientFillProperties::assignUsed( const GradientFillProperties& rSourceProps )
117*cdf0e10cSrcweir {
118*cdf0e10cSrcweir     if( !rSourceProps.maGradientStops.empty() )
119*cdf0e10cSrcweir         maGradientStops = rSourceProps.maGradientStops;
120*cdf0e10cSrcweir     moFillToRect.assignIfUsed( rSourceProps.moFillToRect );
121*cdf0e10cSrcweir     moTileRect.assignIfUsed( rSourceProps.moTileRect );
122*cdf0e10cSrcweir     moGradientPath.assignIfUsed( rSourceProps.moGradientPath );
123*cdf0e10cSrcweir     moShadeAngle.assignIfUsed( rSourceProps.moShadeAngle );
124*cdf0e10cSrcweir     moShadeFlip.assignIfUsed( rSourceProps.moShadeFlip );
125*cdf0e10cSrcweir     moShadeScaled.assignIfUsed( rSourceProps.moShadeScaled );
126*cdf0e10cSrcweir     moRotateWithShape.assignIfUsed( rSourceProps.moRotateWithShape );
127*cdf0e10cSrcweir }
128*cdf0e10cSrcweir 
129*cdf0e10cSrcweir // ============================================================================
130*cdf0e10cSrcweir 
131*cdf0e10cSrcweir void PatternFillProperties::assignUsed( const PatternFillProperties& rSourceProps )
132*cdf0e10cSrcweir {
133*cdf0e10cSrcweir     maPattFgColor.assignIfUsed( rSourceProps.maPattFgColor );
134*cdf0e10cSrcweir     maPattBgColor.assignIfUsed( rSourceProps.maPattBgColor );
135*cdf0e10cSrcweir     moPattPreset.assignIfUsed( rSourceProps.moPattPreset );
136*cdf0e10cSrcweir }
137*cdf0e10cSrcweir 
138*cdf0e10cSrcweir // ============================================================================
139*cdf0e10cSrcweir 
140*cdf0e10cSrcweir void BlipFillProperties::assignUsed( const BlipFillProperties& rSourceProps )
141*cdf0e10cSrcweir {
142*cdf0e10cSrcweir     if( rSourceProps.mxGraphic.is() )
143*cdf0e10cSrcweir         mxGraphic = rSourceProps.mxGraphic;
144*cdf0e10cSrcweir     moBitmapMode.assignIfUsed( rSourceProps.moBitmapMode );
145*cdf0e10cSrcweir     moFillRect.assignIfUsed( rSourceProps.moFillRect );
146*cdf0e10cSrcweir     moTileOffsetX.assignIfUsed( rSourceProps.moTileOffsetX );
147*cdf0e10cSrcweir     moTileOffsetY.assignIfUsed( rSourceProps.moTileOffsetY );
148*cdf0e10cSrcweir     moTileScaleX.assignIfUsed( rSourceProps.moTileScaleX );
149*cdf0e10cSrcweir     moTileScaleY.assignIfUsed( rSourceProps.moTileScaleY );
150*cdf0e10cSrcweir     moTileAlign.assignIfUsed( rSourceProps.moTileAlign );
151*cdf0e10cSrcweir     moTileFlip.assignIfUsed( rSourceProps.moTileFlip );
152*cdf0e10cSrcweir     moRotateWithShape.assignIfUsed( rSourceProps.moRotateWithShape );
153*cdf0e10cSrcweir     moColorEffect.assignIfUsed( rSourceProps.moColorEffect );
154*cdf0e10cSrcweir     moBrightness.assignIfUsed( rSourceProps.moBrightness );
155*cdf0e10cSrcweir     moContrast.assignIfUsed( rSourceProps.moContrast );
156*cdf0e10cSrcweir     maColorChangeFrom.assignIfUsed( rSourceProps.maColorChangeFrom );
157*cdf0e10cSrcweir     maColorChangeTo.assignIfUsed( rSourceProps.maColorChangeTo );
158*cdf0e10cSrcweir }
159*cdf0e10cSrcweir 
160*cdf0e10cSrcweir // ============================================================================
161*cdf0e10cSrcweir 
162*cdf0e10cSrcweir void FillProperties::assignUsed( const FillProperties& rSourceProps )
163*cdf0e10cSrcweir {
164*cdf0e10cSrcweir     moFillType.assignIfUsed( rSourceProps.moFillType );
165*cdf0e10cSrcweir     maFillColor.assignIfUsed( rSourceProps.maFillColor );
166*cdf0e10cSrcweir     maGradientProps.assignUsed( rSourceProps.maGradientProps );
167*cdf0e10cSrcweir     maPatternProps.assignUsed( rSourceProps.maPatternProps );
168*cdf0e10cSrcweir     maBlipProps.assignUsed( rSourceProps.maBlipProps );
169*cdf0e10cSrcweir }
170*cdf0e10cSrcweir 
171*cdf0e10cSrcweir Color FillProperties::getBestSolidColor() const
172*cdf0e10cSrcweir {
173*cdf0e10cSrcweir     Color aSolidColor;
174*cdf0e10cSrcweir     if( moFillType.has() ) switch( moFillType.get() )
175*cdf0e10cSrcweir     {
176*cdf0e10cSrcweir         case XML_solidFill:
177*cdf0e10cSrcweir             aSolidColor = maFillColor;
178*cdf0e10cSrcweir         break;
179*cdf0e10cSrcweir         case XML_gradFill:
180*cdf0e10cSrcweir             if( !maGradientProps.maGradientStops.empty() )
181*cdf0e10cSrcweir                 aSolidColor = maGradientProps.maGradientStops.begin()->second;
182*cdf0e10cSrcweir         break;
183*cdf0e10cSrcweir         case XML_pattFill:
184*cdf0e10cSrcweir             aSolidColor = maPatternProps.maPattBgColor.isUsed() ? maPatternProps.maPattBgColor : maPatternProps.maPattFgColor;
185*cdf0e10cSrcweir         break;
186*cdf0e10cSrcweir     }
187*cdf0e10cSrcweir     return aSolidColor;
188*cdf0e10cSrcweir }
189*cdf0e10cSrcweir 
190*cdf0e10cSrcweir void FillProperties::pushToPropMap( ShapePropertyMap& rPropMap,
191*cdf0e10cSrcweir         const GraphicHelper& rGraphicHelper, sal_Int32 nShapeRotation, sal_Int32 nPhClr ) const
192*cdf0e10cSrcweir {
193*cdf0e10cSrcweir     if( moFillType.has() )
194*cdf0e10cSrcweir     {
195*cdf0e10cSrcweir         FillStyle eFillStyle = FillStyle_NONE;
196*cdf0e10cSrcweir         switch( moFillType.get() )
197*cdf0e10cSrcweir         {
198*cdf0e10cSrcweir             case XML_noFill:
199*cdf0e10cSrcweir                 eFillStyle = FillStyle_NONE;
200*cdf0e10cSrcweir             break;
201*cdf0e10cSrcweir 
202*cdf0e10cSrcweir             case XML_solidFill:
203*cdf0e10cSrcweir                 if( maFillColor.isUsed() )
204*cdf0e10cSrcweir                 {
205*cdf0e10cSrcweir                     rPropMap.setProperty( SHAPEPROP_FillColor, maFillColor.getColor( rGraphicHelper, nPhClr ) );
206*cdf0e10cSrcweir                     if( maFillColor.hasTransparency() )
207*cdf0e10cSrcweir                         rPropMap.setProperty( SHAPEPROP_FillTransparency, maFillColor.getTransparency() );
208*cdf0e10cSrcweir                     eFillStyle = FillStyle_SOLID;
209*cdf0e10cSrcweir                 }
210*cdf0e10cSrcweir             break;
211*cdf0e10cSrcweir 
212*cdf0e10cSrcweir             case XML_gradFill:
213*cdf0e10cSrcweir                 // do not create gradient struct if property is not supported...
214*cdf0e10cSrcweir                 if( rPropMap.supportsProperty( SHAPEPROP_FillGradient ) )
215*cdf0e10cSrcweir                 {
216*cdf0e10cSrcweir                     awt::Gradient aGradient;
217*cdf0e10cSrcweir                     aGradient.Angle = 900;
218*cdf0e10cSrcweir                     aGradient.StartIntensity = 100;
219*cdf0e10cSrcweir                     aGradient.EndIntensity = 100;
220*cdf0e10cSrcweir 
221*cdf0e10cSrcweir                     size_t nColorCount = maGradientProps.maGradientStops.size();
222*cdf0e10cSrcweir                     if( nColorCount > 1 )
223*cdf0e10cSrcweir                     {
224*cdf0e10cSrcweir                         aGradient.StartColor = maGradientProps.maGradientStops.begin()->second.getColor( rGraphicHelper, nPhClr );
225*cdf0e10cSrcweir                         aGradient.EndColor = maGradientProps.maGradientStops.rbegin()->second.getColor( rGraphicHelper, nPhClr );
226*cdf0e10cSrcweir                     }
227*cdf0e10cSrcweir 
228*cdf0e10cSrcweir                     // "rotate with shape" not set, or set to false -> do not rotate
229*cdf0e10cSrcweir                     if ( !maGradientProps.moRotateWithShape.get( false ) )
230*cdf0e10cSrcweir                         nShapeRotation = 0;
231*cdf0e10cSrcweir 
232*cdf0e10cSrcweir                     sal_Int32 nDmlAngle = 0;
233*cdf0e10cSrcweir                     if( maGradientProps.moGradientPath.has() )
234*cdf0e10cSrcweir                     {
235*cdf0e10cSrcweir                         aGradient.Style = (maGradientProps.moGradientPath.get() == XML_circle) ? awt::GradientStyle_ELLIPTICAL : awt::GradientStyle_RECT;
236*cdf0e10cSrcweir                         // position of gradient center (limited to [30%;70%], otherwise gradient is too hidden)
237*cdf0e10cSrcweir                         IntegerRectangle2D aFillToRect = maGradientProps.moFillToRect.get( IntegerRectangle2D( 0, 0, MAX_PERCENT, MAX_PERCENT ) );
238*cdf0e10cSrcweir                         sal_Int32 nCenterX = (MAX_PERCENT + aFillToRect.X1 - aFillToRect.X2) / 2;
239*cdf0e10cSrcweir                         aGradient.XOffset = getLimitedValue< sal_Int16, sal_Int32 >( nCenterX / PER_PERCENT, 30, 70 );
240*cdf0e10cSrcweir                         sal_Int32 nCenterY = (MAX_PERCENT + aFillToRect.Y1 - aFillToRect.Y2) / 2;
241*cdf0e10cSrcweir                         aGradient.YOffset = getLimitedValue< sal_Int16, sal_Int32 >( nCenterY / PER_PERCENT, 30, 70 );
242*cdf0e10cSrcweir                         ::std::swap( aGradient.StartColor, aGradient.EndColor );
243*cdf0e10cSrcweir                         nDmlAngle = nShapeRotation;
244*cdf0e10cSrcweir                     }
245*cdf0e10cSrcweir                     else
246*cdf0e10cSrcweir                     {
247*cdf0e10cSrcweir                         /*  Try to detect a VML axial gradient. This type of
248*cdf0e10cSrcweir                             gradient is simulated by a 3-point linear gradient
249*cdf0e10cSrcweir                             with equal start and end color. */
250*cdf0e10cSrcweir                         bool bAxial = (nColorCount == 3) && (aGradient.StartColor == aGradient.EndColor);
251*cdf0e10cSrcweir                         aGradient.Style = bAxial ? awt::GradientStyle_AXIAL : awt::GradientStyle_LINEAR;
252*cdf0e10cSrcweir                         if( bAxial )
253*cdf0e10cSrcweir                         {
254*cdf0e10cSrcweir                             GradientFillProperties::GradientStopMap::const_iterator aIt = maGradientProps.maGradientStops.begin();
255*cdf0e10cSrcweir                             // API StartColor is inner color in axial gradient
256*cdf0e10cSrcweir                             aGradient.StartColor = (++aIt)->second.getColor( rGraphicHelper, nPhClr );
257*cdf0e10cSrcweir                         }
258*cdf0e10cSrcweir                         nDmlAngle = maGradientProps.moShadeAngle.get( 0 ) - nShapeRotation;
259*cdf0e10cSrcweir                     }
260*cdf0e10cSrcweir                     // convert DrawingML angle (in 1/60000 degrees) to API angle (in 1/10 degrees)
261*cdf0e10cSrcweir                     aGradient.Angle = static_cast< sal_Int16 >( (4500 - (nDmlAngle / (PER_DEGREE / 10))) % 3600 );
262*cdf0e10cSrcweir 
263*cdf0e10cSrcweir                     // push gradient or named gradient to property map
264*cdf0e10cSrcweir                     if( rPropMap.setProperty( SHAPEPROP_FillGradient, aGradient ) )
265*cdf0e10cSrcweir                         eFillStyle = FillStyle_GRADIENT;
266*cdf0e10cSrcweir                 }
267*cdf0e10cSrcweir             break;
268*cdf0e10cSrcweir 
269*cdf0e10cSrcweir             case XML_blipFill:
270*cdf0e10cSrcweir                 // do not start complex graphic transformation if property is not supported...
271*cdf0e10cSrcweir                 if( maBlipProps.mxGraphic.is() && rPropMap.supportsProperty( SHAPEPROP_FillBitmapUrl ) )
272*cdf0e10cSrcweir                 {
273*cdf0e10cSrcweir                     // TODO: "rotate with shape" is not possible with our current core
274*cdf0e10cSrcweir 
275*cdf0e10cSrcweir                     OUString aGraphicUrl = rGraphicHelper.createGraphicObject( maBlipProps.mxGraphic );
276*cdf0e10cSrcweir                     // push bitmap or named bitmap to property map
277*cdf0e10cSrcweir                     if( (aGraphicUrl.getLength() > 0) && rPropMap.setProperty( SHAPEPROP_FillBitmapUrl, aGraphicUrl ) )
278*cdf0e10cSrcweir                         eFillStyle = FillStyle_BITMAP;
279*cdf0e10cSrcweir 
280*cdf0e10cSrcweir                     // set other bitmap properties, if bitmap has been inserted into the map
281*cdf0e10cSrcweir                     if( eFillStyle == FillStyle_BITMAP )
282*cdf0e10cSrcweir                     {
283*cdf0e10cSrcweir                         // bitmap mode (single, repeat, stretch)
284*cdf0e10cSrcweir                         BitmapMode eBitmapMode = lclGetBitmapMode( maBlipProps.moBitmapMode.get( XML_TOKEN_INVALID ) );
285*cdf0e10cSrcweir                         rPropMap.setProperty( SHAPEPROP_FillBitmapMode, eBitmapMode );
286*cdf0e10cSrcweir 
287*cdf0e10cSrcweir                         // additional settings for repeated bitmap
288*cdf0e10cSrcweir                         if( eBitmapMode == BitmapMode_REPEAT )
289*cdf0e10cSrcweir                         {
290*cdf0e10cSrcweir                             // anchor position inside bitmap
291*cdf0e10cSrcweir                             RectanglePoint eRectPoint = lclGetRectanglePoint( maBlipProps.moTileAlign.get( XML_tl ) );
292*cdf0e10cSrcweir                             rPropMap.setProperty( SHAPEPROP_FillBitmapRectanglePoint, eRectPoint );
293*cdf0e10cSrcweir 
294*cdf0e10cSrcweir                             awt::Size aOriginalSize = lclGetOriginalSize( rGraphicHelper, maBlipProps.mxGraphic );
295*cdf0e10cSrcweir                             if( (aOriginalSize.Width > 0) && (aOriginalSize.Height > 0) )
296*cdf0e10cSrcweir                             {
297*cdf0e10cSrcweir                                 // size of one bitmap tile (given as 1/1000 percent of bitmap size), convert to 1/100 mm
298*cdf0e10cSrcweir                                 double fScaleX = maBlipProps.moTileScaleX.get( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT );
299*cdf0e10cSrcweir                                 sal_Int32 nFillBmpSizeX = getLimitedValue< sal_Int32, double >( aOriginalSize.Width * fScaleX, 1, SAL_MAX_INT32 );
300*cdf0e10cSrcweir                                 rPropMap.setProperty( SHAPEPROP_FillBitmapSizeX, nFillBmpSizeX );
301*cdf0e10cSrcweir                                 double fScaleY = maBlipProps.moTileScaleY.get( MAX_PERCENT ) / static_cast< double >( MAX_PERCENT );
302*cdf0e10cSrcweir                                 sal_Int32 nFillBmpSizeY = getLimitedValue< sal_Int32, double >( aOriginalSize.Height * fScaleY, 1, SAL_MAX_INT32 );
303*cdf0e10cSrcweir                                 rPropMap.setProperty( SHAPEPROP_FillBitmapSizeY, nFillBmpSizeY );
304*cdf0e10cSrcweir 
305*cdf0e10cSrcweir                                 // offset of the first bitmap tile (given as EMUs), convert to percent
306*cdf0e10cSrcweir                                 sal_Int16 nTileOffsetX = getDoubleIntervalValue< sal_Int16 >( maBlipProps.moTileOffsetX.get( 0 ) / 3.6 / aOriginalSize.Width, 0, 100 );
307*cdf0e10cSrcweir                                 rPropMap.setProperty( SHAPEPROP_FillBitmapOffsetX, nTileOffsetX );
308*cdf0e10cSrcweir                                 sal_Int16 nTileOffsetY = getDoubleIntervalValue< sal_Int16 >( maBlipProps.moTileOffsetY.get( 0 ) / 3.6 / aOriginalSize.Height, 0, 100 );
309*cdf0e10cSrcweir                                 rPropMap.setProperty( SHAPEPROP_FillBitmapOffsetY, nTileOffsetY );
310*cdf0e10cSrcweir                             }
311*cdf0e10cSrcweir                         }
312*cdf0e10cSrcweir                     }
313*cdf0e10cSrcweir                 }
314*cdf0e10cSrcweir             break;
315*cdf0e10cSrcweir 
316*cdf0e10cSrcweir             case XML_pattFill:
317*cdf0e10cSrcweir             {
318*cdf0e10cSrcweir                 // todo
319*cdf0e10cSrcweir                 Color aColor = getBestSolidColor();
320*cdf0e10cSrcweir                 if( aColor.isUsed() )
321*cdf0e10cSrcweir                 {
322*cdf0e10cSrcweir                     rPropMap.setProperty( SHAPEPROP_FillColor, aColor.getColor( rGraphicHelper, nPhClr ) );
323*cdf0e10cSrcweir                     if( aColor.hasTransparency() )
324*cdf0e10cSrcweir                         rPropMap.setProperty( SHAPEPROP_FillTransparency, aColor.getTransparency() );
325*cdf0e10cSrcweir                     eFillStyle = FillStyle_SOLID;
326*cdf0e10cSrcweir                 }
327*cdf0e10cSrcweir             }
328*cdf0e10cSrcweir             break;
329*cdf0e10cSrcweir 
330*cdf0e10cSrcweir             case XML_grpFill:
331*cdf0e10cSrcweir                 // todo
332*cdf0e10cSrcweir                 eFillStyle = FillStyle_NONE;
333*cdf0e10cSrcweir             break;
334*cdf0e10cSrcweir         }
335*cdf0e10cSrcweir 
336*cdf0e10cSrcweir         // set final fill style property
337*cdf0e10cSrcweir         rPropMap.setProperty( SHAPEPROP_FillStyle, eFillStyle );
338*cdf0e10cSrcweir     }
339*cdf0e10cSrcweir }
340*cdf0e10cSrcweir 
341*cdf0e10cSrcweir // ============================================================================
342*cdf0e10cSrcweir 
343*cdf0e10cSrcweir void GraphicProperties::assignUsed( const GraphicProperties& rSourceProps )
344*cdf0e10cSrcweir {
345*cdf0e10cSrcweir     maBlipProps.assignUsed( rSourceProps.maBlipProps );
346*cdf0e10cSrcweir }
347*cdf0e10cSrcweir 
348*cdf0e10cSrcweir void GraphicProperties::pushToPropMap( PropertyMap& rPropMap, const GraphicHelper& rGraphicHelper, sal_Int32 nPhClr ) const
349*cdf0e10cSrcweir {
350*cdf0e10cSrcweir     if( maBlipProps.mxGraphic.is() )
351*cdf0e10cSrcweir     {
352*cdf0e10cSrcweir         // created transformed graphic
353*cdf0e10cSrcweir         Reference< XGraphic > xGraphic = maBlipProps.mxGraphic;
354*cdf0e10cSrcweir         if( maBlipProps.maColorChangeFrom.isUsed() && maBlipProps.maColorChangeTo.isUsed() )
355*cdf0e10cSrcweir         {
356*cdf0e10cSrcweir             sal_Int32 nFromColor = maBlipProps.maColorChangeFrom.getColor( rGraphicHelper, nPhClr );
357*cdf0e10cSrcweir             sal_Int32 nToColor = maBlipProps.maColorChangeTo.getColor( rGraphicHelper, nPhClr );
358*cdf0e10cSrcweir             if ( (nFromColor != nToColor) || maBlipProps.maColorChangeTo.hasTransparency() ) try
359*cdf0e10cSrcweir             {
360*cdf0e10cSrcweir                 sal_Int16 nToTransparence = maBlipProps.maColorChangeTo.getTransparency();
361*cdf0e10cSrcweir                 sal_Int8 nToAlpha = static_cast< sal_Int8 >( (100 - nToTransparence) / 39.062 );   // ?!? correct ?!?
362*cdf0e10cSrcweir                 Reference< XGraphicTransformer > xTransformer( maBlipProps.mxGraphic, UNO_QUERY_THROW );
363*cdf0e10cSrcweir                 xGraphic = xTransformer->colorChange( maBlipProps.mxGraphic, nFromColor, 9, nToColor, nToAlpha );
364*cdf0e10cSrcweir             }
365*cdf0e10cSrcweir             catch( Exception& )
366*cdf0e10cSrcweir             {
367*cdf0e10cSrcweir             }
368*cdf0e10cSrcweir         }
369*cdf0e10cSrcweir 
370*cdf0e10cSrcweir         OUString aGraphicUrl = rGraphicHelper.createGraphicObject( xGraphic );
371*cdf0e10cSrcweir         if( aGraphicUrl.getLength() > 0 )
372*cdf0e10cSrcweir             rPropMap[ PROP_GraphicURL ] <<= aGraphicUrl;
373*cdf0e10cSrcweir 
374*cdf0e10cSrcweir 		// cropping
375*cdf0e10cSrcweir 		if ( maBlipProps.moClipRect.has() )
376*cdf0e10cSrcweir 		{
377*cdf0e10cSrcweir 			geometry::IntegerRectangle2D oClipRect( maBlipProps.moClipRect.get() );
378*cdf0e10cSrcweir 			awt::Size aOriginalSize( rGraphicHelper.getOriginalSize( xGraphic ) );
379*cdf0e10cSrcweir 			if ( aOriginalSize.Width && aOriginalSize.Height )
380*cdf0e10cSrcweir 			{
381*cdf0e10cSrcweir 				text::GraphicCrop aGraphCrop( 0, 0, 0, 0 );
382*cdf0e10cSrcweir 				if ( oClipRect.X1 )
383*cdf0e10cSrcweir 					aGraphCrop.Left = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Width ) * oClipRect.X1 ) / 100000 );
384*cdf0e10cSrcweir 				if ( oClipRect.Y1 )
385*cdf0e10cSrcweir 					aGraphCrop.Top = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Height ) * oClipRect.Y1 ) / 100000 );
386*cdf0e10cSrcweir 				if ( oClipRect.X2 )
387*cdf0e10cSrcweir 					aGraphCrop.Right = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Width ) * oClipRect.X2 ) / 100000 );
388*cdf0e10cSrcweir 				if ( oClipRect.Y2 )
389*cdf0e10cSrcweir 					aGraphCrop.Bottom = static_cast< sal_Int32 >( ( static_cast< double >( aOriginalSize.Height ) * oClipRect.Y2 ) / 100000 );
390*cdf0e10cSrcweir 				rPropMap[ PROP_GraphicCrop ] <<= aGraphCrop;
391*cdf0e10cSrcweir 			}
392*cdf0e10cSrcweir 		}
393*cdf0e10cSrcweir     }
394*cdf0e10cSrcweir 
395*cdf0e10cSrcweir     // color effect
396*cdf0e10cSrcweir     ColorMode eColorMode = ColorMode_STANDARD;
397*cdf0e10cSrcweir     switch( maBlipProps.moColorEffect.get( XML_TOKEN_INVALID ) )
398*cdf0e10cSrcweir     {
399*cdf0e10cSrcweir         case XML_biLevel:   eColorMode = ColorMode_MONO;    break;
400*cdf0e10cSrcweir         case XML_grayscl:   eColorMode = ColorMode_GREYS;   break;
401*cdf0e10cSrcweir     }
402*cdf0e10cSrcweir     rPropMap[ PROP_GraphicColorMode ] <<= eColorMode;
403*cdf0e10cSrcweir 
404*cdf0e10cSrcweir     // brightness and contrast
405*cdf0e10cSrcweir     sal_Int16 nBrightness = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moBrightness.get( 0 ) / PER_PERCENT, -100, 100 );
406*cdf0e10cSrcweir     if( nBrightness != 0 )
407*cdf0e10cSrcweir         rPropMap[ PROP_AdjustLuminance ] <<= nBrightness;
408*cdf0e10cSrcweir     sal_Int16 nContrast = getLimitedValue< sal_Int16, sal_Int32 >( maBlipProps.moContrast.get( 0 ) / PER_PERCENT, -100, 100 );
409*cdf0e10cSrcweir     if( nContrast != 0 )
410*cdf0e10cSrcweir         rPropMap[ PROP_AdjustContrast ] <<= nContrast;
411*cdf0e10cSrcweir }
412*cdf0e10cSrcweir 
413*cdf0e10cSrcweir // ============================================================================
414*cdf0e10cSrcweir 
415*cdf0e10cSrcweir } // namespace drawingml
416*cdf0e10cSrcweir } // namespace oox
417*cdf0e10cSrcweir 
418