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/drawingml/fillpropertiesgroupcontext.hxx"
25 #include "oox/helper/attributelist.hxx"
26 #include "oox/helper/graphichelper.hxx"
27 #include "oox/core/xmlfilterbase.hxx"
28 #include "oox/drawingml/drawingmltypes.hxx"
29 #include "oox/drawingml/fillproperties.hxx"
30 
31 using ::rtl::OUString;
32 using namespace ::com::sun::star;
33 using namespace ::com::sun::star::uno;
34 using namespace ::com::sun::star::xml::sax;
35 using ::oox::core::ContextHandler;
36 using ::oox::core::XmlFilterBase;
37 
38 namespace oox {
39 namespace drawingml {
40 
41 // ============================================================================
42 
SolidFillContext(ContextHandler & rParent,const Reference<XFastAttributeList> &,FillProperties & rFillProps)43 SolidFillContext::SolidFillContext( ContextHandler& rParent,
44         const Reference< XFastAttributeList >&, FillProperties& rFillProps ) :
45     ColorContext( rParent, rFillProps.maFillColor )
46 {
47 }
48 
49 // ============================================================================
50 
GradientFillContext(ContextHandler & rParent,const Reference<XFastAttributeList> & rxAttribs,GradientFillProperties & rGradientProps)51 GradientFillContext::GradientFillContext( ContextHandler& rParent,
52         const Reference< XFastAttributeList >& rxAttribs, GradientFillProperties& rGradientProps ) :
53     ContextHandler( rParent ),
54     mrGradientProps( rGradientProps )
55 {
56     AttributeList aAttribs( rxAttribs );
57     mrGradientProps.moShadeFlip = aAttribs.getToken( XML_flip );
58     mrGradientProps.moRotateWithShape = aAttribs.getBool( XML_rotWithShape );
59 }
60 
createFastChildContext(sal_Int32 nElement,const Reference<XFastAttributeList> & rxAttribs)61 Reference< XFastContextHandler > GradientFillContext::createFastChildContext(
62         sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException)
63 {
64     AttributeList aAttribs( rxAttribs );
65     switch( nElement )
66     {
67         case A_TOKEN( gsLst ):
68             return this;    // for gs elements
69 
70         case A_TOKEN( gs ):
71             if( aAttribs.hasAttribute( XML_pos ) )
72             {
73                 double fPosition = getLimitedValue< double >( aAttribs.getDouble( XML_pos, 0.0 ) / 100000.0, 0.0, 1.0 );
74                 return new ColorContext( *this, mrGradientProps.maGradientStops[ fPosition ] );
75             }
76         break;
77 
78         case A_TOKEN( lin ):
79             mrGradientProps.moShadeAngle = aAttribs.getInteger( XML_ang );
80             mrGradientProps.moShadeScaled = aAttribs.getBool( XML_scaled );
81         break;
82 
83         case A_TOKEN( path ):
84             // always set a path type, this disables linear gradient in conversion
85             mrGradientProps.moGradientPath = aAttribs.getToken( XML_path, XML_rect );
86             return this;    // for fillToRect element
87 
88         case A_TOKEN( fillToRect ):
89             mrGradientProps.moFillToRect = GetRelativeRect( rxAttribs );
90         break;
91 
92         case A_TOKEN( tileRect ):
93             mrGradientProps.moTileRect = GetRelativeRect( rxAttribs );
94         break;
95     }
96     return 0;
97 }
98 
99 // ============================================================================
100 
PatternFillContext(ContextHandler & rParent,const Reference<XFastAttributeList> & rxAttribs,PatternFillProperties & rPatternProps)101 PatternFillContext::PatternFillContext( ContextHandler& rParent,
102         const Reference< XFastAttributeList >& rxAttribs, PatternFillProperties& rPatternProps ) :
103     ContextHandler( rParent ),
104     mrPatternProps( rPatternProps )
105 {
106     AttributeList aAttribs( rxAttribs );
107     mrPatternProps.moPattPreset = aAttribs.getToken( XML_prst );
108 }
109 
createFastChildContext(sal_Int32 nElement,const Reference<XFastAttributeList> &)110 Reference< XFastContextHandler > PatternFillContext::createFastChildContext(
111         sal_Int32 nElement, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
112 {
113     switch( nElement )
114     {
115         case A_TOKEN( bgClr ):
116             return new ColorContext( *this, mrPatternProps.maPattBgColor );
117         case A_TOKEN( fgClr ):
118             return new ColorContext( *this, mrPatternProps.maPattFgColor );
119     }
120     return 0;
121 }
122 
123 // ============================================================================
124 // ============================================================================
125 
ColorChangeContext(ContextHandler & rParent,const Reference<XFastAttributeList> & rxAttribs,BlipFillProperties & rBlipProps)126 ColorChangeContext::ColorChangeContext( ContextHandler& rParent,
127         const Reference< XFastAttributeList >& rxAttribs, BlipFillProperties& rBlipProps ) :
128     ContextHandler( rParent ),
129     mrBlipProps( rBlipProps )
130 {
131     mrBlipProps.maColorChangeFrom.setUnused();
132     mrBlipProps.maColorChangeTo.setUnused();
133     AttributeList aAttribs( rxAttribs );
134     mbUseAlpha = aAttribs.getBool( XML_useA, true );
135 }
136 
~ColorChangeContext()137 ColorChangeContext::~ColorChangeContext()
138 {
139     if( !mbUseAlpha )
140         mrBlipProps.maColorChangeTo.clearTransparence();
141 }
142 
createFastChildContext(sal_Int32 nElement,const Reference<XFastAttributeList> &)143 Reference< XFastContextHandler > ColorChangeContext::createFastChildContext(
144         sal_Int32 nElement, const Reference< XFastAttributeList >& ) throw (SAXException, RuntimeException)
145 {
146     switch( nElement )
147     {
148         case A_TOKEN( clrFrom ):
149             return new ColorContext( *this, mrBlipProps.maColorChangeFrom );
150         case A_TOKEN( clrTo ):
151             return new ColorContext( *this, mrBlipProps.maColorChangeTo );
152     }
153     return 0;
154 }
155 
156 // ============================================================================
157 
BlipContext(ContextHandler & rParent,const Reference<XFastAttributeList> & rxAttribs,BlipFillProperties & rBlipProps)158 BlipContext::BlipContext( ContextHandler& rParent,
159         const Reference< XFastAttributeList >& rxAttribs, BlipFillProperties& rBlipProps ) :
160     ContextHandler( rParent ),
161     mrBlipProps( rBlipProps )
162 {
163     AttributeList aAttribs( rxAttribs );
164     if( aAttribs.hasAttribute( R_TOKEN( embed ) ) )
165     {
166         // internal picture URL
167         OUString aFragmentPath = getFragmentPathFromRelId( aAttribs.getString( R_TOKEN( embed ), OUString() ) );
168         if( aFragmentPath.getLength() > 0 )
169             mrBlipProps.mxGraphic = getFilter().getGraphicHelper().importEmbeddedGraphic( aFragmentPath );
170     }
171     else if( aAttribs.hasAttribute( R_TOKEN( link ) ) )
172     {
173         // external URL
174         OUString aRelId = aAttribs.getString( R_TOKEN( link ), OUString() );
175         OUString aTargetLink = getFilter().getAbsoluteUrl( getRelations().getExternalTargetFromRelId( aRelId ) );
176         // TODO: load external picture
177     }
178 }
179 
createFastChildContext(sal_Int32 nElement,const Reference<XFastAttributeList> & rxAttribs)180 Reference< XFastContextHandler > BlipContext::createFastChildContext(
181         sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException)
182 {
183     AttributeList aAttribs( rxAttribs );
184     switch( nElement )
185     {
186         case A_TOKEN( biLevel ):
187         case A_TOKEN( grayscl ):
188             mrBlipProps.moColorEffect = getBaseToken( nElement );
189         break;
190 
191         case A_TOKEN( clrChange ):
192             return new ColorChangeContext( *this, rxAttribs, mrBlipProps );
193 
194         case A_TOKEN( lum ):
195             mrBlipProps.moBrightness = aAttribs.getInteger( XML_bright );
196             mrBlipProps.moContrast = aAttribs.getInteger( XML_contrast );
197         break;
198     }
199     return 0;
200 }
201 
202 // ============================================================================
203 
BlipFillContext(ContextHandler & rParent,const Reference<XFastAttributeList> & rxAttribs,BlipFillProperties & rBlipProps)204 BlipFillContext::BlipFillContext( ContextHandler& rParent,
205         const Reference< XFastAttributeList >& rxAttribs, BlipFillProperties& rBlipProps ) :
206     ContextHandler( rParent ),
207     mrBlipProps( rBlipProps )
208 {
209     AttributeList aAttribs( rxAttribs );
210     mrBlipProps.moRotateWithShape = aAttribs.getBool( XML_rotWithShape );
211 }
212 
createFastChildContext(sal_Int32 nElement,const Reference<XFastAttributeList> & rxAttribs)213 Reference< XFastContextHandler > BlipFillContext::createFastChildContext(
214         sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs ) throw (SAXException, RuntimeException)
215 {
216     AttributeList aAttribs( rxAttribs );
217     switch( nElement )
218     {
219         case A_TOKEN( blip ):
220             return new BlipContext( *this, rxAttribs, mrBlipProps );
221 
222         case A_TOKEN( srcRect ):
223 			{
224 				rtl::OUString aDefault( rtl::OUString( RTL_CONSTASCII_USTRINGPARAM( "0" ) ) );
225 				::com::sun::star::geometry::IntegerRectangle2D aClipRect;
226 				aClipRect.X1 = GetPercent( aAttribs.getString( XML_l, aDefault ) );
227 				aClipRect.Y1 = GetPercent( aAttribs.getString( XML_t, aDefault ) );
228 				aClipRect.X2 = GetPercent( aAttribs.getString( XML_r, aDefault ) );
229 				aClipRect.Y2 = GetPercent( aAttribs.getString( XML_b, aDefault ) );
230 				mrBlipProps.moClipRect = aClipRect;
231 			}
232         break;
233 
234         case A_TOKEN( tile ):
235             mrBlipProps.moBitmapMode = getBaseToken( nElement );
236             mrBlipProps.moTileOffsetX = aAttribs.getInteger( XML_tx );
237             mrBlipProps.moTileOffsetY = aAttribs.getInteger( XML_ty );
238             mrBlipProps.moTileScaleX = aAttribs.getInteger( XML_sx );
239             mrBlipProps.moTileScaleY = aAttribs.getInteger( XML_sy );
240             mrBlipProps.moTileAlign = aAttribs.getToken( XML_algn );
241             mrBlipProps.moTileFlip = aAttribs.getToken( XML_flip );
242         break;
243 
244         case A_TOKEN( stretch ):
245             mrBlipProps.moBitmapMode = getBaseToken( nElement );
246             return this;    // for fillRect element
247 
248         case A_TOKEN( fillRect ):
249             mrBlipProps.moFillRect = GetRelativeRect( rxAttribs );
250         break;
251     }
252     return 0;
253 }
254 
255 // ============================================================================
256 // ============================================================================
257 
FillPropertiesContext(ContextHandler & rParent,FillProperties & rFillProps)258 FillPropertiesContext::FillPropertiesContext( ContextHandler& rParent, FillProperties& rFillProps ) :
259     ContextHandler( rParent ),
260     mrFillProps( rFillProps )
261 {
262 }
263 
createFastChildContext(sal_Int32 nElement,const Reference<XFastAttributeList> & rxAttribs)264 Reference< XFastContextHandler > FillPropertiesContext::createFastChildContext(
265         sal_Int32 nElement, const Reference< XFastAttributeList >& rxAttribs )
266     throw ( SAXException, RuntimeException )
267 {
268     return createFillContext( *this, nElement, rxAttribs, mrFillProps );
269 }
270 
createFillContext(ContextHandler & rParent,sal_Int32 nElement,const Reference<XFastAttributeList> & rxAttribs,FillProperties & rFillProps)271 /*static*/ Reference< XFastContextHandler > FillPropertiesContext::createFillContext(
272         ContextHandler& rParent, sal_Int32 nElement,
273         const Reference< XFastAttributeList >& rxAttribs, FillProperties& rFillProps )
274 {
275     switch( nElement )
276     {
277         case A_TOKEN( noFill ):     { rFillProps.moFillType = getBaseToken( nElement ); return 0; };
278         case A_TOKEN( solidFill ):  { rFillProps.moFillType = getBaseToken( nElement ); return new SolidFillContext( rParent, rxAttribs, rFillProps ); };
279         case A_TOKEN( gradFill ):   { rFillProps.moFillType = getBaseToken( nElement ); return new GradientFillContext( rParent, rxAttribs, rFillProps.maGradientProps ); };
280         case A_TOKEN( pattFill ):   { rFillProps.moFillType = getBaseToken( nElement ); return new PatternFillContext( rParent, rxAttribs, rFillProps.maPatternProps ); };
281         case A_TOKEN( blipFill ):   { rFillProps.moFillType = getBaseToken( nElement ); return new BlipFillContext( rParent, rxAttribs, rFillProps.maBlipProps ); };
282         case A_TOKEN( grpFill ):    { rFillProps.moFillType = getBaseToken( nElement ); return 0; };    // TODO
283     }
284     return 0;
285 }
286 
287 // ============================================================================
288 
SimpleFillPropertiesContext(ContextHandler & rParent,Color & rColor)289 SimpleFillPropertiesContext::SimpleFillPropertiesContext( ContextHandler& rParent, Color& rColor ) :
290     FillPropertiesContext( rParent, *this ),
291     mrColor( rColor )
292 {
293 }
294 
~SimpleFillPropertiesContext()295 SimpleFillPropertiesContext::~SimpleFillPropertiesContext()
296 {
297     mrColor = getBestSolidColor();
298 }
299 
300 // ============================================================================
301 
302 } // namespace drawingml
303 } // namespace oox
304 
305