1*70f497fbSAndrew Rist /**************************************************************
2cdf0e10cSrcweir  *
3*70f497fbSAndrew Rist  * Licensed to the Apache Software Foundation (ASF) under one
4*70f497fbSAndrew Rist  * or more contributor license agreements.  See the NOTICE file
5*70f497fbSAndrew Rist  * distributed with this work for additional information
6*70f497fbSAndrew Rist  * regarding copyright ownership.  The ASF licenses this file
7*70f497fbSAndrew Rist  * to you under the Apache License, Version 2.0 (the
8*70f497fbSAndrew Rist  * "License"); you may not use this file except in compliance
9*70f497fbSAndrew Rist  * with the License.  You may obtain a copy of the License at
10*70f497fbSAndrew Rist  *
11*70f497fbSAndrew Rist  *   http://www.apache.org/licenses/LICENSE-2.0
12*70f497fbSAndrew Rist  *
13*70f497fbSAndrew Rist  * Unless required by applicable law or agreed to in writing,
14*70f497fbSAndrew Rist  * software distributed under the License is distributed on an
15*70f497fbSAndrew Rist  * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
16*70f497fbSAndrew Rist  * KIND, either express or implied.  See the License for the
17*70f497fbSAndrew Rist  * specific language governing permissions and limitations
18*70f497fbSAndrew Rist  * under the License.
19*70f497fbSAndrew Rist  *
20*70f497fbSAndrew Rist  *************************************************************/
21*70f497fbSAndrew Rist 
22*70f497fbSAndrew Rist 
23cdf0e10cSrcweir 
24cdf0e10cSrcweir // MARKER(update_precomp.py): autogen include statement, do not remove
25cdf0e10cSrcweir #include "precompiled_slideshow.hxx"
26cdf0e10cSrcweir 
27cdf0e10cSrcweir // must be first
28cdf0e10cSrcweir #include <canvas/debug.hxx>
29cdf0e10cSrcweir #include <tools/diagnose_ex.h>
30cdf0e10cSrcweir #include <shapeattributelayer.hxx>
31cdf0e10cSrcweir 
32cdf0e10cSrcweir #include <canvas/verbosetrace.hxx>
33cdf0e10cSrcweir 
34cdf0e10cSrcweir 
35cdf0e10cSrcweir #include <com/sun/star/awt/Rectangle.hpp>
36cdf0e10cSrcweir #include <com/sun/star/awt/FontUnderline.hpp>
37cdf0e10cSrcweir #include <com/sun/star/awt/FontWeight.hpp>
38cdf0e10cSrcweir #include <com/sun/star/beans/XPropertySet.hpp>
39cdf0e10cSrcweir #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
40cdf0e10cSrcweir 
41cdf0e10cSrcweir #include <basegfx/numeric/ftools.hxx>
42cdf0e10cSrcweir #include <basegfx/polygon/b2dpolygon.hxx>
43cdf0e10cSrcweir #include <rtl/math.hxx>
44cdf0e10cSrcweir 
45cdf0e10cSrcweir 
46cdf0e10cSrcweir using namespace ::com::sun::star;
47cdf0e10cSrcweir 
48cdf0e10cSrcweir 
49cdf0e10cSrcweir namespace slideshow
50cdf0e10cSrcweir {
51cdf0e10cSrcweir     namespace internal
52cdf0e10cSrcweir     {
53cdf0e10cSrcweir         /** Update state ids
54cdf0e10cSrcweir 
55cdf0e10cSrcweir         	This method updates all state IDs from possible
56cdf0e10cSrcweir         	children. Whenever a child's state ID changed, we
57cdf0e10cSrcweir         	increment ours.
58cdf0e10cSrcweir         */
updateStateIds()59cdf0e10cSrcweir         void ShapeAttributeLayer::updateStateIds()
60cdf0e10cSrcweir         {
61cdf0e10cSrcweir             if( haveChild() )
62cdf0e10cSrcweir             {
63cdf0e10cSrcweir                 if( mnTransformationState != mpChild->getTransformationState() )
64cdf0e10cSrcweir                     ++mnTransformationState;
65cdf0e10cSrcweir                 if( mnClipState != mpChild->getClipState() )
66cdf0e10cSrcweir                     ++mnClipState;
67cdf0e10cSrcweir                 if( mnAlphaState != mpChild->getAlphaState() )
68cdf0e10cSrcweir                     ++mnAlphaState;
69cdf0e10cSrcweir                 if( mnPositionState != mpChild->getPositionState() )
70cdf0e10cSrcweir                     ++mnPositionState;
71cdf0e10cSrcweir                 if( mnContentState != mpChild->getContentState() )
72cdf0e10cSrcweir                     ++mnContentState;
73cdf0e10cSrcweir                 if( mnVisibilityState != mpChild->getVisibilityState() )
74cdf0e10cSrcweir                     ++mnVisibilityState;
75cdf0e10cSrcweir             }
76cdf0e10cSrcweir         }
77cdf0e10cSrcweir 
78cdf0e10cSrcweir         /** Calc attribute value.
79cdf0e10cSrcweir 
80cdf0e10cSrcweir         	This method determines the current attribute value,
81cdf0e10cSrcweir         	appropriately combining it with children values (by
82cdf0e10cSrcweir         	evaluating the mnAdditiveMode member).
83cdf0e10cSrcweir          */
calcValue(const T & rCurrValue,bool bThisInstanceValid,bool (ShapeAttributeLayer::* pIsValid)()const,T (ShapeAttributeLayer::* pGetValue)()const) const84cdf0e10cSrcweir         template< typename T > T ShapeAttributeLayer::calcValue( const T& 					rCurrValue,
85cdf0e10cSrcweir                                                                  bool						bThisInstanceValid,
86cdf0e10cSrcweir                                                                  bool (ShapeAttributeLayer::*pIsValid)() const,
87cdf0e10cSrcweir                                                                  T 	 (ShapeAttributeLayer::*pGetValue)() const ) const
88cdf0e10cSrcweir         {
89cdf0e10cSrcweir             // deviated from the (*shared_ptr).*mpFuncPtr notation
90cdf0e10cSrcweir             // here, since gcc does not seem to parse that as a member
91cdf0e10cSrcweir             // function call anymore.
92cdf0e10cSrcweir             const bool bChildInstanceValueValid( haveChild() ? (mpChild.get()->*pIsValid)() : false );
93cdf0e10cSrcweir 
94cdf0e10cSrcweir             if( bThisInstanceValid )
95cdf0e10cSrcweir             {
96cdf0e10cSrcweir                 if( bChildInstanceValueValid )
97cdf0e10cSrcweir                 {
98cdf0e10cSrcweir                     // merge with child value
99cdf0e10cSrcweir                     switch( mnAdditiveMode )
100cdf0e10cSrcweir                     {
101cdf0e10cSrcweir                         default:
102cdf0e10cSrcweir                             // FALTHROUGH intended
103cdf0e10cSrcweir                         case animations::AnimationAdditiveMode::NONE:
104cdf0e10cSrcweir                             // FALTHROUGH intended
105cdf0e10cSrcweir                         case animations::AnimationAdditiveMode::BASE:
106cdf0e10cSrcweir                             // FALTHROUGH intended
107cdf0e10cSrcweir                         case animations::AnimationAdditiveMode::REPLACE:
108cdf0e10cSrcweir                             // TODO(F2): reverse-engineer the semantics of these
109cdf0e10cSrcweir                             // values
110cdf0e10cSrcweir 
111cdf0e10cSrcweir                             // currently, treat them the same and replace
112cdf0e10cSrcweir                             // the child value by our own
113cdf0e10cSrcweir                             return rCurrValue;
114cdf0e10cSrcweir 
115cdf0e10cSrcweir                         case animations::AnimationAdditiveMode::SUM:
116cdf0e10cSrcweir                             return rCurrValue + ((*mpChild).*pGetValue)();
117cdf0e10cSrcweir 
118cdf0e10cSrcweir                         case animations::AnimationAdditiveMode::MULTIPLY:
119cdf0e10cSrcweir                             return rCurrValue * ((*mpChild).*pGetValue)();
120cdf0e10cSrcweir                     }
121cdf0e10cSrcweir                 }
122cdf0e10cSrcweir                 else
123cdf0e10cSrcweir                 {
124cdf0e10cSrcweir                     // this object is the only one defining
125cdf0e10cSrcweir                     // the value, so take it
126cdf0e10cSrcweir                     return rCurrValue;
127cdf0e10cSrcweir                 }
128cdf0e10cSrcweir             }
129cdf0e10cSrcweir             else
130cdf0e10cSrcweir             {
131cdf0e10cSrcweir                 return bChildInstanceValueValid ?
132cdf0e10cSrcweir                     ((*mpChild).*pGetValue)() :
133cdf0e10cSrcweir                     T(); 			// pass on child value, regardless
134cdf0e10cSrcweir                 					// if it's valid or not. If not, it's
135cdf0e10cSrcweir                 					// a default anyway
136cdf0e10cSrcweir             }
137cdf0e10cSrcweir         }
138cdf0e10cSrcweir 
ShapeAttributeLayer(const ShapeAttributeLayerSharedPtr & rChildLayer)139cdf0e10cSrcweir         ShapeAttributeLayer::ShapeAttributeLayer( const ShapeAttributeLayerSharedPtr& rChildLayer ) :
140cdf0e10cSrcweir             mpChild( rChildLayer ),
141cdf0e10cSrcweir 
142cdf0e10cSrcweir             maSize(),
143cdf0e10cSrcweir             maPosition(),
144cdf0e10cSrcweir             maClip(),
145cdf0e10cSrcweir 
146cdf0e10cSrcweir             maFontFamily(),
147cdf0e10cSrcweir 
148cdf0e10cSrcweir             mnRotationAngle(),
149cdf0e10cSrcweir             mnShearXAngle(),
150cdf0e10cSrcweir             mnShearYAngle(),
151cdf0e10cSrcweir             mnAlpha(),
152cdf0e10cSrcweir             mnCharRotationAngle(),
153cdf0e10cSrcweir             mnCharScale(),
154cdf0e10cSrcweir             mnCharWeight(),
155cdf0e10cSrcweir 
156cdf0e10cSrcweir             meFillStyle( drawing::FillStyle_NONE ),
157cdf0e10cSrcweir             meLineStyle( drawing::LineStyle_NONE ),
158cdf0e10cSrcweir             meCharPosture( awt::FontSlant_NONE ),
159cdf0e10cSrcweir             mnUnderlineMode(),
160cdf0e10cSrcweir 
161cdf0e10cSrcweir             maDimColor(),
162cdf0e10cSrcweir             maFillColor(),
163cdf0e10cSrcweir             maLineColor(),
164cdf0e10cSrcweir             maCharColor(),
165cdf0e10cSrcweir 
166cdf0e10cSrcweir             mnTransformationState( rChildLayer ? rChildLayer->getTransformationState() : 0 ),
167cdf0e10cSrcweir             mnClipState( rChildLayer ? rChildLayer->getClipState() : 0),
168cdf0e10cSrcweir             mnAlphaState( rChildLayer ? rChildLayer->getAlphaState() : 0),
169cdf0e10cSrcweir             mnPositionState( rChildLayer ? rChildLayer->getPositionState() : 0 ),
170cdf0e10cSrcweir             mnContentState( rChildLayer ? rChildLayer->getContentState() : 0 ),
171cdf0e10cSrcweir             mnVisibilityState( rChildLayer ? rChildLayer->getVisibilityState() : 0 ),
172cdf0e10cSrcweir 
173cdf0e10cSrcweir             mnAdditiveMode( animations::AnimationAdditiveMode::BASE ),
174cdf0e10cSrcweir 
175cdf0e10cSrcweir             mbVisibility( false ),
176cdf0e10cSrcweir 
177cdf0e10cSrcweir             mbWidthValid( false ),
178cdf0e10cSrcweir             mbHeightValid( false ),
179cdf0e10cSrcweir             mbPosXValid( false ),
180cdf0e10cSrcweir             mbPosYValid( false ),
181cdf0e10cSrcweir             mbClipValid( false ),
182cdf0e10cSrcweir 
183cdf0e10cSrcweir             mbFontFamilyValid( false ),
184cdf0e10cSrcweir 
185cdf0e10cSrcweir             mbRotationAngleValid( false ),
186cdf0e10cSrcweir             mbShearXAngleValid( false ),
187cdf0e10cSrcweir             mbShearYAngleValid( false ),
188cdf0e10cSrcweir 
189cdf0e10cSrcweir             mbAlphaValid( false ),
190cdf0e10cSrcweir 
191cdf0e10cSrcweir             mbCharRotationAngleValid( false ),
192cdf0e10cSrcweir             mbCharScaleValid( false ),
193cdf0e10cSrcweir 
194cdf0e10cSrcweir             mbDimColorValid( false ),
195cdf0e10cSrcweir             mbFillColorValid( false ),
196cdf0e10cSrcweir             mbLineColorValid( false ),
197cdf0e10cSrcweir             mbCharColorValid( false ),
198cdf0e10cSrcweir 
199cdf0e10cSrcweir             mbFillStyleValid( false ),
200cdf0e10cSrcweir             mbLineStyleValid( false ),
201cdf0e10cSrcweir             mbCharWeightValid( false ),
202cdf0e10cSrcweir             mbUnderlineModeValid( false ),
203cdf0e10cSrcweir             mbCharPostureValid( false ),
204cdf0e10cSrcweir             mbVisibilityValid( false )
205cdf0e10cSrcweir         {
206cdf0e10cSrcweir         }
207cdf0e10cSrcweir 
revokeChildLayer(const ShapeAttributeLayerSharedPtr & rChildLayer)208cdf0e10cSrcweir         bool ShapeAttributeLayer::revokeChildLayer( const ShapeAttributeLayerSharedPtr& rChildLayer )
209cdf0e10cSrcweir         {
210cdf0e10cSrcweir             ENSURE_OR_RETURN_FALSE( rChildLayer,
211cdf0e10cSrcweir                                "ShapeAttributeLayer::revokeChildLayer(): Will not remove NULL child" );
212cdf0e10cSrcweir 
213cdf0e10cSrcweir             if( !haveChild() )
214cdf0e10cSrcweir                 return false; // no children, nothing to revoke.
215cdf0e10cSrcweir 
216cdf0e10cSrcweir             if( mpChild == rChildLayer )
217cdf0e10cSrcweir             {
218cdf0e10cSrcweir                 // we have it - replace by removed child's sibling.
219cdf0e10cSrcweir                 mpChild = rChildLayer->getChildLayer();
220cdf0e10cSrcweir 
221cdf0e10cSrcweir                 // if we're now the first one, defensively increment _all_
222cdf0e10cSrcweir                 // state ids: possibly all underlying attributes have now
223cdf0e10cSrcweir                 // changed to default
224cdf0e10cSrcweir                 if( !haveChild() )
225cdf0e10cSrcweir                 {
226cdf0e10cSrcweir                     // TODO(P1): Check whether it pays off to check more
227cdf0e10cSrcweir                     // detailed, which attributes really change
228cdf0e10cSrcweir                     ++mnTransformationState;
229cdf0e10cSrcweir                     ++mnClipState;
230cdf0e10cSrcweir                     ++mnAlphaState;
231cdf0e10cSrcweir                     ++mnPositionState;
232cdf0e10cSrcweir                     ++mnContentState;
233cdf0e10cSrcweir                     ++mnVisibilityState;
234cdf0e10cSrcweir                 }
235cdf0e10cSrcweir             }
236cdf0e10cSrcweir             else
237cdf0e10cSrcweir             {
238cdf0e10cSrcweir                 // we don't have it - pass on the request
239cdf0e10cSrcweir                 if( !mpChild->revokeChildLayer( rChildLayer ) )
240cdf0e10cSrcweir                     return false; // nobody has it - bail out
241cdf0e10cSrcweir             }
242cdf0e10cSrcweir 
243cdf0e10cSrcweir             // something might have changed - update ids.
244cdf0e10cSrcweir             updateStateIds();
245cdf0e10cSrcweir 
246cdf0e10cSrcweir             return true;
247cdf0e10cSrcweir         }
248cdf0e10cSrcweir 
getChildLayer() const249cdf0e10cSrcweir         ShapeAttributeLayerSharedPtr  ShapeAttributeLayer::getChildLayer() const
250cdf0e10cSrcweir         {
251cdf0e10cSrcweir             return mpChild;
252cdf0e10cSrcweir         }
253cdf0e10cSrcweir 
setAdditiveMode(sal_Int16 nMode)254cdf0e10cSrcweir         void ShapeAttributeLayer::setAdditiveMode( sal_Int16 nMode )
255cdf0e10cSrcweir         {
256cdf0e10cSrcweir             if( mnAdditiveMode != nMode )
257cdf0e10cSrcweir             {
258cdf0e10cSrcweir                 // TODO(P1): Check whether it pays off to check more
259cdf0e10cSrcweir                 // detailed, which attributes really change
260cdf0e10cSrcweir 
261cdf0e10cSrcweir                 // defensively increment all states - possibly each of them
262cdf0e10cSrcweir                 // will change with different additive mode
263cdf0e10cSrcweir                 ++mnTransformationState;
264cdf0e10cSrcweir                 ++mnClipState;
265cdf0e10cSrcweir                 ++mnAlphaState;
266cdf0e10cSrcweir                 ++mnPositionState;
267cdf0e10cSrcweir                 ++mnContentState;
268cdf0e10cSrcweir                 ++mnVisibilityState;
269cdf0e10cSrcweir             }
270cdf0e10cSrcweir 
271cdf0e10cSrcweir             mnAdditiveMode = nMode;
272cdf0e10cSrcweir         }
273cdf0e10cSrcweir 
isWidthValid() const274cdf0e10cSrcweir         bool ShapeAttributeLayer::isWidthValid() const
275cdf0e10cSrcweir         {
276cdf0e10cSrcweir             return mbWidthValid ? true : haveChild() ? mpChild->isWidthValid() : false;
277cdf0e10cSrcweir         }
278cdf0e10cSrcweir 
getWidth() const279cdf0e10cSrcweir         double ShapeAttributeLayer::getWidth() const
280cdf0e10cSrcweir         {
281cdf0e10cSrcweir             return calcValue< double >(
282cdf0e10cSrcweir                 maSize.getX(),
283cdf0e10cSrcweir                 mbWidthValid,
284cdf0e10cSrcweir                 &ShapeAttributeLayer::isWidthValid,
285cdf0e10cSrcweir                 &ShapeAttributeLayer::getWidth );
286cdf0e10cSrcweir         }
287cdf0e10cSrcweir 
setWidth(const double & rNewWidth)288cdf0e10cSrcweir         void ShapeAttributeLayer::setWidth( const double& rNewWidth )
289cdf0e10cSrcweir         {
290cdf0e10cSrcweir             ENSURE_OR_THROW( ::rtl::math::isFinite(rNewWidth),
291cdf0e10cSrcweir                               "ShapeAttributeLayer::setWidth(): Invalid width" );
292cdf0e10cSrcweir 
293cdf0e10cSrcweir             maSize.setX( rNewWidth );
294cdf0e10cSrcweir             mbWidthValid = true;
295cdf0e10cSrcweir             ++mnTransformationState;
296cdf0e10cSrcweir         }
297cdf0e10cSrcweir 
isHeightValid() const298cdf0e10cSrcweir         bool ShapeAttributeLayer::isHeightValid() const
299cdf0e10cSrcweir         {
300cdf0e10cSrcweir             return mbHeightValid ? true : haveChild() ? mpChild->isHeightValid() : false;
301cdf0e10cSrcweir         }
302cdf0e10cSrcweir 
getHeight() const303cdf0e10cSrcweir         double ShapeAttributeLayer::getHeight() const
304cdf0e10cSrcweir         {
305cdf0e10cSrcweir             return calcValue< double >(
306cdf0e10cSrcweir                 maSize.getY(),
307cdf0e10cSrcweir                 mbHeightValid,
308cdf0e10cSrcweir                 &ShapeAttributeLayer::isHeightValid,
309cdf0e10cSrcweir                 &ShapeAttributeLayer::getHeight );
310cdf0e10cSrcweir         }
311cdf0e10cSrcweir 
setHeight(const double & rNewHeight)312cdf0e10cSrcweir         void ShapeAttributeLayer::setHeight( const double& rNewHeight )
313cdf0e10cSrcweir         {
314cdf0e10cSrcweir             ENSURE_OR_THROW( ::rtl::math::isFinite(rNewHeight),
315cdf0e10cSrcweir                               "ShapeAttributeLayer::setHeight(): Invalid height" );
316cdf0e10cSrcweir 
317cdf0e10cSrcweir             maSize.setY( rNewHeight );
318cdf0e10cSrcweir             mbHeightValid = true;
319cdf0e10cSrcweir             ++mnTransformationState;
320cdf0e10cSrcweir         }
321cdf0e10cSrcweir 
setSize(const::basegfx::B2DSize & rNewSize)322cdf0e10cSrcweir         void ShapeAttributeLayer::setSize( const ::basegfx::B2DSize& rNewSize )
323cdf0e10cSrcweir         {
324cdf0e10cSrcweir             ENSURE_OR_THROW( ::rtl::math::isFinite(rNewSize.getX()) &&
325cdf0e10cSrcweir                               ::rtl::math::isFinite(rNewSize.getY()),
326cdf0e10cSrcweir                               "ShapeAttributeLayer::setSize(): Invalid size" );
327cdf0e10cSrcweir 
328cdf0e10cSrcweir             maSize = rNewSize;
329cdf0e10cSrcweir             mbWidthValid = mbHeightValid = true;
330cdf0e10cSrcweir             ++mnTransformationState;
331cdf0e10cSrcweir         }
332cdf0e10cSrcweir 
isPosXValid() const333cdf0e10cSrcweir         bool ShapeAttributeLayer::isPosXValid() const
334cdf0e10cSrcweir         {
335cdf0e10cSrcweir             return mbPosXValid ? true : haveChild() ? mpChild->isPosXValid() : false;
336cdf0e10cSrcweir         }
337cdf0e10cSrcweir 
getPosX() const338cdf0e10cSrcweir         double ShapeAttributeLayer::getPosX() const
339cdf0e10cSrcweir         {
340cdf0e10cSrcweir             return calcValue< double >(
341cdf0e10cSrcweir                 maPosition.getX(),
342cdf0e10cSrcweir                 mbPosXValid,
343cdf0e10cSrcweir                 &ShapeAttributeLayer::isPosXValid,
344cdf0e10cSrcweir                 &ShapeAttributeLayer::getPosX );
345cdf0e10cSrcweir         }
346cdf0e10cSrcweir 
setPosX(const double & rNewX)347cdf0e10cSrcweir         void ShapeAttributeLayer::setPosX( const double& rNewX )
348cdf0e10cSrcweir         {
349cdf0e10cSrcweir             ENSURE_OR_THROW( ::rtl::math::isFinite(rNewX),
350cdf0e10cSrcweir                               "ShapeAttributeLayer::setPosX(): Invalid position" );
351cdf0e10cSrcweir 
352cdf0e10cSrcweir             maPosition.setX( rNewX );
353cdf0e10cSrcweir             mbPosXValid = true;
354cdf0e10cSrcweir             ++mnPositionState;
355cdf0e10cSrcweir         }
356cdf0e10cSrcweir 
isPosYValid() const357cdf0e10cSrcweir         bool ShapeAttributeLayer::isPosYValid() const
358cdf0e10cSrcweir         {
359cdf0e10cSrcweir             return mbPosYValid ? true : haveChild() ? mpChild->isPosYValid() : false;
360cdf0e10cSrcweir         }
361cdf0e10cSrcweir 
getPosY() const362cdf0e10cSrcweir         double ShapeAttributeLayer::getPosY() const
363cdf0e10cSrcweir         {
364cdf0e10cSrcweir             return calcValue< double >(
365cdf0e10cSrcweir                 maPosition.getY(),
366cdf0e10cSrcweir                 mbPosYValid,
367cdf0e10cSrcweir                 &ShapeAttributeLayer::isPosYValid,
368cdf0e10cSrcweir                 &ShapeAttributeLayer::getPosY );
369cdf0e10cSrcweir         }
370cdf0e10cSrcweir 
setPosY(const double & rNewY)371cdf0e10cSrcweir         void ShapeAttributeLayer::setPosY( const double& rNewY )
372cdf0e10cSrcweir         {
373cdf0e10cSrcweir             ENSURE_OR_THROW( ::rtl::math::isFinite(rNewY),
374cdf0e10cSrcweir                               "ShapeAttributeLayer::setPosY(): Invalid position" );
375cdf0e10cSrcweir 
376cdf0e10cSrcweir             maPosition.setY( rNewY );
377cdf0e10cSrcweir             mbPosYValid = true;
378cdf0e10cSrcweir             ++mnPositionState;
379cdf0e10cSrcweir         }
380cdf0e10cSrcweir 
setPosition(const::basegfx::B2DPoint & rNewPos)381cdf0e10cSrcweir         void ShapeAttributeLayer::setPosition( const ::basegfx::B2DPoint& rNewPos )
382cdf0e10cSrcweir         {
383cdf0e10cSrcweir             maPosition = rNewPos;
384cdf0e10cSrcweir             mbPosXValid = mbPosYValid = true;
385cdf0e10cSrcweir             ++mnPositionState;
386cdf0e10cSrcweir         }
387cdf0e10cSrcweir 
isRotationAngleValid() const388cdf0e10cSrcweir         bool ShapeAttributeLayer::isRotationAngleValid() const
389cdf0e10cSrcweir         {
390cdf0e10cSrcweir             return mbRotationAngleValid ? true : haveChild() ? mpChild->isRotationAngleValid() : false;
391cdf0e10cSrcweir         }
392cdf0e10cSrcweir 
getRotationAngle() const393cdf0e10cSrcweir         double ShapeAttributeLayer::getRotationAngle() const
394cdf0e10cSrcweir         {
395cdf0e10cSrcweir             return calcValue< double >(
396cdf0e10cSrcweir                 mnRotationAngle,
397cdf0e10cSrcweir                 mbRotationAngleValid,
398cdf0e10cSrcweir                 &ShapeAttributeLayer::isRotationAngleValid,
399cdf0e10cSrcweir                 &ShapeAttributeLayer::getRotationAngle );
400cdf0e10cSrcweir         }
401cdf0e10cSrcweir 
setRotationAngle(const double & rNewAngle)402cdf0e10cSrcweir         void ShapeAttributeLayer::setRotationAngle( const double& rNewAngle )
403cdf0e10cSrcweir         {
404cdf0e10cSrcweir             ENSURE_OR_THROW( ::rtl::math::isFinite(rNewAngle),
405cdf0e10cSrcweir                               "ShapeAttributeLayer::setRotationAngle(): Invalid angle" );
406cdf0e10cSrcweir 
407cdf0e10cSrcweir             mnRotationAngle = rNewAngle;
408cdf0e10cSrcweir             mbRotationAngleValid = true;
409cdf0e10cSrcweir             ++mnTransformationState;
410cdf0e10cSrcweir         }
411cdf0e10cSrcweir 
isShearXAngleValid() const412cdf0e10cSrcweir         bool ShapeAttributeLayer::isShearXAngleValid() const
413cdf0e10cSrcweir         {
414cdf0e10cSrcweir             return mbShearXAngleValid ? true : haveChild() ? mpChild->isShearXAngleValid() : false;
415cdf0e10cSrcweir         }
416cdf0e10cSrcweir 
getShearXAngle() const417cdf0e10cSrcweir         double ShapeAttributeLayer::getShearXAngle() const
418cdf0e10cSrcweir         {
419cdf0e10cSrcweir             return calcValue( mnShearXAngle,
420cdf0e10cSrcweir                               mbShearXAngleValid,
421cdf0e10cSrcweir                               &ShapeAttributeLayer::isShearXAngleValid,
422cdf0e10cSrcweir                               &ShapeAttributeLayer::getShearXAngle );
423cdf0e10cSrcweir         }
424cdf0e10cSrcweir 
setShearXAngle(const double & rNewAngle)425cdf0e10cSrcweir         void ShapeAttributeLayer::setShearXAngle( const double& rNewAngle )
426cdf0e10cSrcweir         {
427cdf0e10cSrcweir             ENSURE_OR_THROW( ::rtl::math::isFinite(rNewAngle),
428cdf0e10cSrcweir                               "ShapeAttributeLayer::setShearXAngle(): Invalid angle" );
429cdf0e10cSrcweir 
430cdf0e10cSrcweir             mnShearXAngle = rNewAngle;
431cdf0e10cSrcweir             mbShearXAngleValid = true;
432cdf0e10cSrcweir             ++mnTransformationState;
433cdf0e10cSrcweir         }
434cdf0e10cSrcweir 
isShearYAngleValid() const435cdf0e10cSrcweir         bool ShapeAttributeLayer::isShearYAngleValid() const
436cdf0e10cSrcweir         {
437cdf0e10cSrcweir             return mbShearYAngleValid ? true : haveChild() ? mpChild->isShearYAngleValid() : false;
438cdf0e10cSrcweir         }
439cdf0e10cSrcweir 
getShearYAngle() const440cdf0e10cSrcweir         double ShapeAttributeLayer::getShearYAngle() const
441cdf0e10cSrcweir         {
442cdf0e10cSrcweir             return calcValue( mnShearYAngle,
443cdf0e10cSrcweir                               mbShearYAngleValid,
444cdf0e10cSrcweir                               &ShapeAttributeLayer::isShearYAngleValid,
445cdf0e10cSrcweir                               &ShapeAttributeLayer::getShearYAngle );
446cdf0e10cSrcweir         }
447cdf0e10cSrcweir 
setShearYAngle(const double & rNewAngle)448cdf0e10cSrcweir         void ShapeAttributeLayer::setShearYAngle( const double& rNewAngle )
449cdf0e10cSrcweir         {
450cdf0e10cSrcweir             ENSURE_OR_THROW( ::rtl::math::isFinite(rNewAngle),
451cdf0e10cSrcweir                               "ShapeAttributeLayer::setShearYAngle(): Invalid angle" );
452cdf0e10cSrcweir 
453cdf0e10cSrcweir             mnShearYAngle = rNewAngle;
454cdf0e10cSrcweir             mbShearYAngleValid = true;
455cdf0e10cSrcweir             ++mnTransformationState;
456cdf0e10cSrcweir         }
457cdf0e10cSrcweir 
isAlphaValid() const458cdf0e10cSrcweir         bool ShapeAttributeLayer::isAlphaValid() const
459cdf0e10cSrcweir         {
460cdf0e10cSrcweir             return mbAlphaValid ? true : haveChild() ? mpChild->isAlphaValid() : false;
461cdf0e10cSrcweir         }
462cdf0e10cSrcweir 
getAlpha() const463cdf0e10cSrcweir         double ShapeAttributeLayer::getAlpha() const
464cdf0e10cSrcweir         {
465cdf0e10cSrcweir             return calcValue( mnAlpha,
466cdf0e10cSrcweir                               mbAlphaValid,
467cdf0e10cSrcweir                               &ShapeAttributeLayer::isAlphaValid,
468cdf0e10cSrcweir                               &ShapeAttributeLayer::getAlpha );
469cdf0e10cSrcweir         }
470cdf0e10cSrcweir 
setAlpha(const double & rNewValue)471cdf0e10cSrcweir         void ShapeAttributeLayer::setAlpha( const double& rNewValue )
472cdf0e10cSrcweir         {
473cdf0e10cSrcweir             ENSURE_OR_THROW( ::rtl::math::isFinite(rNewValue),
474cdf0e10cSrcweir                               "ShapeAttributeLayer::setAlpha(): Invalid alpha" );
475cdf0e10cSrcweir 
476cdf0e10cSrcweir             mnAlpha = rNewValue;
477cdf0e10cSrcweir             mbAlphaValid = true;
478cdf0e10cSrcweir             ++mnAlphaState;
479cdf0e10cSrcweir         }
480cdf0e10cSrcweir 
isClipValid() const481cdf0e10cSrcweir         bool ShapeAttributeLayer::isClipValid() const
482cdf0e10cSrcweir         {
483cdf0e10cSrcweir             return mbClipValid ? true : haveChild() ? mpChild->isClipValid() : false;
484cdf0e10cSrcweir         }
485cdf0e10cSrcweir 
getClip() const486cdf0e10cSrcweir         ::basegfx::B2DPolyPolygon ShapeAttributeLayer::getClip() const
487cdf0e10cSrcweir         {
488cdf0e10cSrcweir             // TODO(F1): Implement polygon algebra for additive modes
489cdf0e10cSrcweir             if( mbClipValid )
490cdf0e10cSrcweir                 return maClip;
491cdf0e10cSrcweir             else if( haveChild() )
492cdf0e10cSrcweir                 return mpChild->getClip();
493cdf0e10cSrcweir             else
494cdf0e10cSrcweir                 return ::basegfx::B2DPolyPolygon();
495cdf0e10cSrcweir         }
496cdf0e10cSrcweir 
setClip(const::basegfx::B2DPolyPolygon & rNewClip)497cdf0e10cSrcweir         void ShapeAttributeLayer::setClip( const ::basegfx::B2DPolyPolygon& rNewClip )
498cdf0e10cSrcweir         {
499cdf0e10cSrcweir             maClip = rNewClip;
500cdf0e10cSrcweir             mbClipValid = true;
501cdf0e10cSrcweir             ++mnClipState;
502cdf0e10cSrcweir         }
503cdf0e10cSrcweir 
isDimColorValid() const504cdf0e10cSrcweir         bool ShapeAttributeLayer::isDimColorValid() const
505cdf0e10cSrcweir         {
506cdf0e10cSrcweir             return mbDimColorValid ? true : haveChild() ? mpChild->isDimColorValid() : false;
507cdf0e10cSrcweir         }
508cdf0e10cSrcweir 
getDimColor() const509cdf0e10cSrcweir         RGBColor ShapeAttributeLayer::getDimColor() const
510cdf0e10cSrcweir         {
511cdf0e10cSrcweir             return calcValue( maDimColor,
512cdf0e10cSrcweir                               mbDimColorValid,
513cdf0e10cSrcweir                               &ShapeAttributeLayer::isDimColorValid,
514cdf0e10cSrcweir                               &ShapeAttributeLayer::getDimColor );
515cdf0e10cSrcweir         }
516cdf0e10cSrcweir 
setDimColor(const RGBColor & nNewColor)517cdf0e10cSrcweir         void ShapeAttributeLayer::setDimColor( const RGBColor& nNewColor )
518cdf0e10cSrcweir         {
519cdf0e10cSrcweir             maDimColor = nNewColor;
520cdf0e10cSrcweir             mbDimColorValid = true;
521cdf0e10cSrcweir             ++mnContentState;
522cdf0e10cSrcweir         }
523cdf0e10cSrcweir 
isFillColorValid() const524cdf0e10cSrcweir         bool ShapeAttributeLayer::isFillColorValid() const
525cdf0e10cSrcweir         {
526cdf0e10cSrcweir             return mbFillColorValid ? true : haveChild() ? mpChild->isFillColorValid() : false;
527cdf0e10cSrcweir         }
528cdf0e10cSrcweir 
getFillColor() const529cdf0e10cSrcweir         RGBColor ShapeAttributeLayer::getFillColor() const
530cdf0e10cSrcweir         {
531cdf0e10cSrcweir             return calcValue( maFillColor,
532cdf0e10cSrcweir                               mbFillColorValid,
533cdf0e10cSrcweir                               &ShapeAttributeLayer::isFillColorValid,
534cdf0e10cSrcweir                               &ShapeAttributeLayer::getFillColor );
535cdf0e10cSrcweir         }
536cdf0e10cSrcweir 
setFillColor(const RGBColor & nNewColor)537cdf0e10cSrcweir         void ShapeAttributeLayer::setFillColor( const RGBColor& nNewColor )
538cdf0e10cSrcweir         {
539cdf0e10cSrcweir             maFillColor = nNewColor;
540cdf0e10cSrcweir             mbFillColorValid = true;
541cdf0e10cSrcweir             ++mnContentState;
542cdf0e10cSrcweir         }
543cdf0e10cSrcweir 
isLineColorValid() const544cdf0e10cSrcweir         bool ShapeAttributeLayer::isLineColorValid() const
545cdf0e10cSrcweir         {
546cdf0e10cSrcweir             return mbLineColorValid ? true : haveChild() ? mpChild->isLineColorValid() : false;
547cdf0e10cSrcweir         }
548cdf0e10cSrcweir 
getLineColor() const549cdf0e10cSrcweir         RGBColor  ShapeAttributeLayer::getLineColor() const
550cdf0e10cSrcweir         {
551cdf0e10cSrcweir             return calcValue( maLineColor,
552cdf0e10cSrcweir                               mbLineColorValid,
553cdf0e10cSrcweir                               &ShapeAttributeLayer::isLineColorValid,
554cdf0e10cSrcweir                               &ShapeAttributeLayer::getLineColor );
555cdf0e10cSrcweir         }
556cdf0e10cSrcweir 
setLineColor(const RGBColor & nNewColor)557cdf0e10cSrcweir         void ShapeAttributeLayer::setLineColor( const RGBColor& nNewColor )
558cdf0e10cSrcweir         {
559cdf0e10cSrcweir             maLineColor = nNewColor;
560cdf0e10cSrcweir             mbLineColorValid = true;
561cdf0e10cSrcweir             ++mnContentState;
562cdf0e10cSrcweir         }
563cdf0e10cSrcweir 
isFillStyleValid() const564cdf0e10cSrcweir         bool ShapeAttributeLayer::isFillStyleValid() const
565cdf0e10cSrcweir         {
566cdf0e10cSrcweir             return mbFillStyleValid ? true : haveChild() ? mpChild->isFillStyleValid() : false;
567cdf0e10cSrcweir         }
568cdf0e10cSrcweir 
getFillStyle() const569cdf0e10cSrcweir         sal_Int16 ShapeAttributeLayer::getFillStyle() const
570cdf0e10cSrcweir         {
571cdf0e10cSrcweir             // mnAdditiveMode is ignored, cannot combine strings in
572cdf0e10cSrcweir             // any sensible way
573cdf0e10cSrcweir             if( mbFillStyleValid )
574cdf0e10cSrcweir                 return sal::static_int_cast<sal_Int16>(meFillStyle);
575cdf0e10cSrcweir             else if( haveChild() )
576cdf0e10cSrcweir                 return sal::static_int_cast<sal_Int16>(mpChild->getFillStyle());
577cdf0e10cSrcweir             else
578cdf0e10cSrcweir                 return sal::static_int_cast<sal_Int16>(drawing::FillStyle_SOLID);
579cdf0e10cSrcweir         }
580cdf0e10cSrcweir 
setFillStyle(const sal_Int16 & rStyle)581cdf0e10cSrcweir         void ShapeAttributeLayer::setFillStyle( const sal_Int16& rStyle )
582cdf0e10cSrcweir         {
583cdf0e10cSrcweir             // TODO(Q1): Check range here.
584cdf0e10cSrcweir             meFillStyle = (drawing::FillStyle)rStyle;
585cdf0e10cSrcweir             mbFillStyleValid = true;
586cdf0e10cSrcweir             ++mnContentState;
587cdf0e10cSrcweir         }
588cdf0e10cSrcweir 
isLineStyleValid() const589cdf0e10cSrcweir         bool ShapeAttributeLayer::isLineStyleValid() const
590cdf0e10cSrcweir         {
591cdf0e10cSrcweir             return mbLineStyleValid ? true : haveChild() ? mpChild->isLineStyleValid() : false;
592cdf0e10cSrcweir         }
593cdf0e10cSrcweir 
getLineStyle() const594cdf0e10cSrcweir         sal_Int16 ShapeAttributeLayer::getLineStyle() const
595cdf0e10cSrcweir         {
596cdf0e10cSrcweir             // mnAdditiveMode is ignored, cannot combine strings in
597cdf0e10cSrcweir             // any sensible way
598cdf0e10cSrcweir             if( mbLineStyleValid )
599cdf0e10cSrcweir                 return sal::static_int_cast<sal_Int16>(meLineStyle);
600cdf0e10cSrcweir             else if( haveChild() )
601cdf0e10cSrcweir                 return sal::static_int_cast<sal_Int16>(mpChild->getLineStyle());
602cdf0e10cSrcweir             else
603cdf0e10cSrcweir                 return sal::static_int_cast<sal_Int16>(drawing::LineStyle_SOLID);
604cdf0e10cSrcweir         }
605cdf0e10cSrcweir 
setLineStyle(const sal_Int16 & rStyle)606cdf0e10cSrcweir         void ShapeAttributeLayer::setLineStyle( const sal_Int16& rStyle )
607cdf0e10cSrcweir         {
608cdf0e10cSrcweir             // TODO(Q1): Check range here.
609cdf0e10cSrcweir             meLineStyle = (drawing::LineStyle)rStyle;
610cdf0e10cSrcweir             mbLineStyleValid = true;
611cdf0e10cSrcweir             ++mnContentState;
612cdf0e10cSrcweir         }
613cdf0e10cSrcweir 
isVisibilityValid() const614cdf0e10cSrcweir         bool ShapeAttributeLayer::isVisibilityValid() const
615cdf0e10cSrcweir         {
616cdf0e10cSrcweir             return mbVisibilityValid ? true : haveChild() ? mpChild->isVisibilityValid() : false;
617cdf0e10cSrcweir         }
618cdf0e10cSrcweir 
getVisibility() const619cdf0e10cSrcweir         bool ShapeAttributeLayer::getVisibility() const
620cdf0e10cSrcweir         {
621cdf0e10cSrcweir             // mnAdditiveMode is ignored, SMIL spec requires to not combine
622cdf0e10cSrcweir             // bools in any sensible way
623cdf0e10cSrcweir             if( mbVisibilityValid )
624cdf0e10cSrcweir                 return mbVisibility;
625cdf0e10cSrcweir             else if( haveChild() )
626cdf0e10cSrcweir                 return mpChild->getVisibility();
627cdf0e10cSrcweir             else
628cdf0e10cSrcweir                 return true; // default is always visible
629cdf0e10cSrcweir         }
630cdf0e10cSrcweir 
setVisibility(const bool & bVisible)631cdf0e10cSrcweir         void ShapeAttributeLayer::setVisibility( const bool& bVisible )
632cdf0e10cSrcweir         {
633cdf0e10cSrcweir             mbVisibility = bVisible;
634cdf0e10cSrcweir             mbVisibilityValid = true;
635cdf0e10cSrcweir             ++mnVisibilityState;
636cdf0e10cSrcweir         }
637cdf0e10cSrcweir 
isCharColorValid() const638cdf0e10cSrcweir         bool ShapeAttributeLayer::isCharColorValid() const
639cdf0e10cSrcweir         {
640cdf0e10cSrcweir             return mbCharColorValid ? true : haveChild() ? mpChild->isCharColorValid() : false;
641cdf0e10cSrcweir         }
642cdf0e10cSrcweir 
getCharColor() const643cdf0e10cSrcweir         RGBColor ShapeAttributeLayer::getCharColor() const
644cdf0e10cSrcweir         {
645cdf0e10cSrcweir             return calcValue( maCharColor,
646cdf0e10cSrcweir                               mbCharColorValid,
647cdf0e10cSrcweir                               &ShapeAttributeLayer::isCharColorValid,
648cdf0e10cSrcweir                               &ShapeAttributeLayer::getCharColor );
649cdf0e10cSrcweir         }
650cdf0e10cSrcweir 
setCharColor(const RGBColor & nNewColor)651cdf0e10cSrcweir         void ShapeAttributeLayer::setCharColor( const RGBColor& nNewColor )
652cdf0e10cSrcweir         {
653cdf0e10cSrcweir             maCharColor = nNewColor;
654cdf0e10cSrcweir             mbCharColorValid = true;
655cdf0e10cSrcweir             ++mnContentState;
656cdf0e10cSrcweir         }
657cdf0e10cSrcweir 
isCharRotationAngleValid() const658cdf0e10cSrcweir         bool ShapeAttributeLayer::isCharRotationAngleValid() const
659cdf0e10cSrcweir         {
660cdf0e10cSrcweir             return mbCharRotationAngleValid ? true : haveChild() ? mpChild->isCharRotationAngleValid() : false;
661cdf0e10cSrcweir         }
662cdf0e10cSrcweir 
getCharRotationAngle() const663cdf0e10cSrcweir         double ShapeAttributeLayer::getCharRotationAngle() const
664cdf0e10cSrcweir         {
665cdf0e10cSrcweir             return calcValue( mnCharRotationAngle,
666cdf0e10cSrcweir                               mbCharRotationAngleValid,
667cdf0e10cSrcweir                               &ShapeAttributeLayer::isCharRotationAngleValid,
668cdf0e10cSrcweir                               &ShapeAttributeLayer::getCharRotationAngle );
669cdf0e10cSrcweir         }
670cdf0e10cSrcweir 
setCharRotationAngle(const double & rNewAngle)671cdf0e10cSrcweir         void ShapeAttributeLayer::setCharRotationAngle( const double& rNewAngle )
672cdf0e10cSrcweir         {
673cdf0e10cSrcweir             ENSURE_OR_THROW( ::rtl::math::isFinite(rNewAngle),
674cdf0e10cSrcweir                               "ShapeAttributeLayer::setCharRotationAngle(): Invalid angle" );
675cdf0e10cSrcweir 
676cdf0e10cSrcweir             mnCharRotationAngle = rNewAngle;
677cdf0e10cSrcweir             mbCharRotationAngleValid = true;
678cdf0e10cSrcweir             ++mnContentState;
679cdf0e10cSrcweir         }
680cdf0e10cSrcweir 
isCharWeightValid() const681cdf0e10cSrcweir         bool ShapeAttributeLayer::isCharWeightValid() const
682cdf0e10cSrcweir         {
683cdf0e10cSrcweir             return mbCharWeightValid ? true : haveChild() ? mpChild->isCharWeightValid() : false;
684cdf0e10cSrcweir         }
685cdf0e10cSrcweir 
getCharWeight() const686cdf0e10cSrcweir         double ShapeAttributeLayer::getCharWeight() const
687cdf0e10cSrcweir         {
688cdf0e10cSrcweir             // mnAdditiveMode is ignored, cannot combine strings in
689cdf0e10cSrcweir             // any sensible way
690cdf0e10cSrcweir             if( mbCharWeightValid )
691cdf0e10cSrcweir                 return mnCharWeight;
692cdf0e10cSrcweir             else if( haveChild() )
693cdf0e10cSrcweir                 return mpChild->getCharWeight();
694cdf0e10cSrcweir             else
695cdf0e10cSrcweir                 return awt::FontWeight::NORMAL;
696cdf0e10cSrcweir         }
697cdf0e10cSrcweir 
setCharWeight(const double & rValue)698cdf0e10cSrcweir         void ShapeAttributeLayer::setCharWeight( const double& rValue )
699cdf0e10cSrcweir         {
700cdf0e10cSrcweir             // TODO(Q1): Check range here.
701cdf0e10cSrcweir             mnCharWeight = rValue;
702cdf0e10cSrcweir             mbCharWeightValid = true;
703cdf0e10cSrcweir             ++mnContentState;
704cdf0e10cSrcweir         }
705cdf0e10cSrcweir 
isUnderlineModeValid() const706cdf0e10cSrcweir         bool ShapeAttributeLayer::isUnderlineModeValid() const
707cdf0e10cSrcweir         {
708cdf0e10cSrcweir             return mbUnderlineModeValid ? true : haveChild() ? mpChild->isUnderlineModeValid() : false;
709cdf0e10cSrcweir         }
710cdf0e10cSrcweir 
getUnderlineMode() const711cdf0e10cSrcweir         sal_Int16 ShapeAttributeLayer::getUnderlineMode() const
712cdf0e10cSrcweir         {
713cdf0e10cSrcweir             // mnAdditiveMode is ignored, SMIL spec requires to not combine
714cdf0e10cSrcweir             // bools in any sensible way
715cdf0e10cSrcweir             if( mbUnderlineModeValid )
716cdf0e10cSrcweir                 return mnUnderlineMode;
717cdf0e10cSrcweir             else if( haveChild() )
718cdf0e10cSrcweir                 return mpChild->getUnderlineMode();
719cdf0e10cSrcweir             else
720cdf0e10cSrcweir                 return awt::FontUnderline::NONE; // default is no underline
721cdf0e10cSrcweir         }
722cdf0e10cSrcweir 
setUnderlineMode(const sal_Int16 & rUnderlineMode)723cdf0e10cSrcweir         void ShapeAttributeLayer::setUnderlineMode( const sal_Int16& rUnderlineMode )
724cdf0e10cSrcweir         {
725cdf0e10cSrcweir             // TODO(Q1): Check range here.
726cdf0e10cSrcweir             mnUnderlineMode = rUnderlineMode;
727cdf0e10cSrcweir             mbUnderlineModeValid = true;
728cdf0e10cSrcweir             ++mnContentState;
729cdf0e10cSrcweir         }
730cdf0e10cSrcweir 
isFontFamilyValid() const731cdf0e10cSrcweir         bool ShapeAttributeLayer::isFontFamilyValid() const
732cdf0e10cSrcweir         {
733cdf0e10cSrcweir             return mbFontFamilyValid ? true : haveChild() ? mpChild->isFontFamilyValid() : false;
734cdf0e10cSrcweir         }
735cdf0e10cSrcweir 
getFontFamily() const736cdf0e10cSrcweir         ::rtl::OUString ShapeAttributeLayer::getFontFamily() const
737cdf0e10cSrcweir         {
738cdf0e10cSrcweir             // mnAdditiveMode is ignored, cannot combine strings in
739cdf0e10cSrcweir             // any sensible way
740cdf0e10cSrcweir             if( mbFontFamilyValid )
741cdf0e10cSrcweir                 return maFontFamily;
742cdf0e10cSrcweir             else if( haveChild() )
743cdf0e10cSrcweir                 return mpChild->getFontFamily();
744cdf0e10cSrcweir             else
745cdf0e10cSrcweir                 return ::rtl::OUString();
746cdf0e10cSrcweir         }
747cdf0e10cSrcweir 
setFontFamily(const::rtl::OUString & rName)748cdf0e10cSrcweir         void ShapeAttributeLayer::setFontFamily( const ::rtl::OUString& rName )
749cdf0e10cSrcweir         {
750cdf0e10cSrcweir             maFontFamily = rName;
751cdf0e10cSrcweir             mbFontFamilyValid = true;
752cdf0e10cSrcweir             ++mnContentState;
753cdf0e10cSrcweir         }
754cdf0e10cSrcweir 
isCharPostureValid() const755cdf0e10cSrcweir         bool ShapeAttributeLayer::isCharPostureValid() const
756cdf0e10cSrcweir         {
757cdf0e10cSrcweir             return mbCharPostureValid ? true : haveChild() ? mpChild->isCharPostureValid() : false;
758cdf0e10cSrcweir         }
759cdf0e10cSrcweir 
getCharPosture() const760cdf0e10cSrcweir         sal_Int16 ShapeAttributeLayer::getCharPosture() const
761cdf0e10cSrcweir         {
762cdf0e10cSrcweir             // mnAdditiveMode is ignored, cannot combine strings in
763cdf0e10cSrcweir             // any sensible way
764cdf0e10cSrcweir             if( mbCharPostureValid )
765cdf0e10cSrcweir                 return sal::static_int_cast<sal_Int16>(meCharPosture);
766cdf0e10cSrcweir             else if( haveChild() )
767cdf0e10cSrcweir                 return sal::static_int_cast<sal_Int16>(mpChild->getCharPosture());
768cdf0e10cSrcweir             else
769cdf0e10cSrcweir                 return sal::static_int_cast<sal_Int16>(awt::FontSlant_NONE);
770cdf0e10cSrcweir         }
771cdf0e10cSrcweir 
setCharPosture(const sal_Int16 & rStyle)772cdf0e10cSrcweir         void ShapeAttributeLayer::setCharPosture( const sal_Int16& rStyle )
773cdf0e10cSrcweir         {
774cdf0e10cSrcweir             // TODO(Q1): Check range here.
775cdf0e10cSrcweir             meCharPosture = (awt::FontSlant)rStyle;
776cdf0e10cSrcweir             mbCharPostureValid = true;
777cdf0e10cSrcweir             ++mnContentState;
778cdf0e10cSrcweir         }
779cdf0e10cSrcweir 
isCharScaleValid() const780cdf0e10cSrcweir         bool ShapeAttributeLayer::isCharScaleValid() const
781cdf0e10cSrcweir         {
782cdf0e10cSrcweir             return mbCharScaleValid ? true : haveChild() ? mpChild->isCharScaleValid() : false;
783cdf0e10cSrcweir         }
784cdf0e10cSrcweir 
getCharScale() const785cdf0e10cSrcweir         double ShapeAttributeLayer::getCharScale() const
786cdf0e10cSrcweir         {
787cdf0e10cSrcweir             return calcValue( mnCharScale,
788cdf0e10cSrcweir                               mbCharScaleValid,
789cdf0e10cSrcweir                               &ShapeAttributeLayer::isCharScaleValid,
790cdf0e10cSrcweir                               &ShapeAttributeLayer::getCharScale );
791cdf0e10cSrcweir         }
792cdf0e10cSrcweir 
setCharScale(const double & rNewHeight)793cdf0e10cSrcweir         void ShapeAttributeLayer::setCharScale( const double& rNewHeight )
794cdf0e10cSrcweir         {
795cdf0e10cSrcweir             ENSURE_OR_THROW( ::rtl::math::isFinite(rNewHeight),
796cdf0e10cSrcweir                               "ShapeAttributeLayer::setCharScale(): Invalid height" );
797cdf0e10cSrcweir 
798cdf0e10cSrcweir             mnCharScale = rNewHeight;
799cdf0e10cSrcweir             mbCharScaleValid = true;
800cdf0e10cSrcweir             ++mnContentState;
801cdf0e10cSrcweir         }
802cdf0e10cSrcweir 
getTransformationState() const803cdf0e10cSrcweir         State::StateId ShapeAttributeLayer::getTransformationState() const
804cdf0e10cSrcweir         {
805cdf0e10cSrcweir             return haveChild() ?
806cdf0e10cSrcweir                 ::std::max( mnTransformationState,
807cdf0e10cSrcweir                             mpChild->getTransformationState() ) :
808cdf0e10cSrcweir                 mnTransformationState;
809cdf0e10cSrcweir         }
810cdf0e10cSrcweir 
getClipState() const811cdf0e10cSrcweir         State::StateId ShapeAttributeLayer::getClipState() const
812cdf0e10cSrcweir         {
813cdf0e10cSrcweir             return haveChild() ?
814cdf0e10cSrcweir                 ::std::max( mnClipState,
815cdf0e10cSrcweir                             mpChild->getClipState() ) :
816cdf0e10cSrcweir                 mnClipState;
817cdf0e10cSrcweir         }
818cdf0e10cSrcweir 
getAlphaState() const819cdf0e10cSrcweir         State::StateId ShapeAttributeLayer::getAlphaState() const
820cdf0e10cSrcweir         {
821cdf0e10cSrcweir             return haveChild() ?
822cdf0e10cSrcweir                 ::std::max( mnAlphaState,
823cdf0e10cSrcweir                             mpChild->getAlphaState() ) :
824cdf0e10cSrcweir                 mnAlphaState;
825cdf0e10cSrcweir         }
826cdf0e10cSrcweir 
getPositionState() const827cdf0e10cSrcweir         State::StateId ShapeAttributeLayer::getPositionState() const
828cdf0e10cSrcweir  		{
829cdf0e10cSrcweir             return haveChild() ?
830cdf0e10cSrcweir                 ::std::max( mnPositionState,
831cdf0e10cSrcweir                             mpChild->getPositionState() ) :
832cdf0e10cSrcweir                 mnPositionState;
833cdf0e10cSrcweir         }
834cdf0e10cSrcweir 
getContentState() const835cdf0e10cSrcweir         State::StateId ShapeAttributeLayer::getContentState() const
836cdf0e10cSrcweir         {
837cdf0e10cSrcweir             return haveChild() ?
838cdf0e10cSrcweir                 ::std::max( mnContentState,
839cdf0e10cSrcweir                             mpChild->getContentState() ) :
840cdf0e10cSrcweir                 mnContentState;
841cdf0e10cSrcweir         }
842cdf0e10cSrcweir 
getVisibilityState() const843cdf0e10cSrcweir         State::StateId ShapeAttributeLayer::getVisibilityState() const
844cdf0e10cSrcweir         {
845cdf0e10cSrcweir             return haveChild() ?
846cdf0e10cSrcweir                 ::std::max( mnVisibilityState,
847cdf0e10cSrcweir                             mpChild->getVisibilityState() ) :
848cdf0e10cSrcweir                 mnVisibilityState;
849cdf0e10cSrcweir         }
850cdf0e10cSrcweir 
851cdf0e10cSrcweir     }
852cdf0e10cSrcweir }
853