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