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