1 /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
3 * This file is part of the LibreOffice project.
5 * This Source Code Form is subject to the terms of the Mozilla Public
6 * License, v. 2.0. If a copy of the MPL was not distributed with this
7 * file, You can obtain one at http://mozilla.org/MPL/2.0/.
9 * This file incorporates work covered by the following license notice:
11 * Licensed to the Apache Software Foundation (ASF) under one or more
12 * contributor license agreements. See the NOTICE file distributed
13 * with this work for additional information regarding copyright
14 * ownership. The ASF licenses this file to you under the Apache
15 * License, Version 2.0 (the "License"); you may not use this file
16 * except in compliance with the License. You may obtain a copy of
17 * the License at http://www.apache.org/licenses/LICENSE-2.0 .
22 #include <comphelper/diagnose_ex.hxx>
23 #include <shapeattributelayer.hxx>
25 #include <com/sun/star/awt/FontUnderline.hpp>
26 #include <com/sun/star/awt/FontWeight.hpp>
27 #include <com/sun/star/animations/AnimationAdditiveMode.hpp>
30 using namespace ::com::sun::star
;
33 namespace slideshow::internal
37 This method updates all state IDs from possible
38 children. Whenever a child's state ID changed, we
41 void ShapeAttributeLayer::updateStateIds()
46 if( mnTransformationState
!= mpChild
->getTransformationState() )
47 ++mnTransformationState
;
48 if( mnClipState
!= mpChild
->getClipState() )
50 if( mnAlphaState
!= mpChild
->getAlphaState() )
52 if( mnPositionState
!= mpChild
->getPositionState() )
54 if( mnContentState
!= mpChild
->getContentState() )
56 if( mnVisibilityState
!= mpChild
->getVisibilityState() )
60 /** Calc attribute value.
62 This method determines the current attribute value,
63 appropriately combining it with children values (by
64 evaluating the mnAdditiveMode member).
66 template< typename T
> T
ShapeAttributeLayer::calcValue( const T
& rCurrValue
,
67 bool bThisInstanceValid
,
68 bool (ShapeAttributeLayer::*pIsValid
)() const,
69 T (ShapeAttributeLayer::*pGetValue
)() const ) const
71 // deviated from the (*shared_ptr).*mpFuncPtr notation
72 // here, since gcc does not seem to parse that as a member
73 // function call anymore.
74 const bool bChildInstanceValueValid( haveChild() && (mpChild
.get()->*pIsValid
)() );
76 if( bThisInstanceValid
)
78 if( bChildInstanceValueValid
)
80 // merge with child value
81 switch( mnAdditiveMode
)
84 // FALTHROUGH intended
85 case animations::AnimationAdditiveMode::NONE
:
86 // FALTHROUGH intended
87 case animations::AnimationAdditiveMode::BASE
:
88 // FALTHROUGH intended
89 case animations::AnimationAdditiveMode::REPLACE
:
90 // TODO(F2): reverse-engineer the semantics of these
93 // currently, treat them the same and replace
94 // the child value by our own
97 case animations::AnimationAdditiveMode::SUM
:
98 return rCurrValue
+ ((*mpChild
).*pGetValue
)();
100 case animations::AnimationAdditiveMode::MULTIPLY
:
101 return rCurrValue
* ((*mpChild
).*pGetValue
)();
106 // this object is the only one defining
107 // the value, so take it
113 return bChildInstanceValueValid
?
114 ((*mpChild
).*pGetValue
)() :
115 T(); // pass on child value, regardless
116 // if it's valid or not. If not, it's
121 ShapeAttributeLayer::ShapeAttributeLayer( const ShapeAttributeLayerSharedPtr
& rChildLayer
) :
122 mpChild( rChildLayer
),
137 meFillStyle( drawing::FillStyle_NONE
),
138 meLineStyle( drawing::LineStyle_NONE
),
139 meCharPosture( awt::FontSlant_NONE
),
147 mnTransformationState( rChildLayer
? rChildLayer
->getTransformationState() : 0 ),
148 mnClipState( rChildLayer
? rChildLayer
->getClipState() : 0),
149 mnAlphaState( rChildLayer
? rChildLayer
->getAlphaState() : 0),
150 mnPositionState( rChildLayer
? rChildLayer
->getPositionState() : 0 ),
151 mnContentState( rChildLayer
? rChildLayer
->getContentState() : 0 ),
152 mnVisibilityState( rChildLayer
? rChildLayer
->getVisibilityState() : 0 ),
154 mnAdditiveMode( animations::AnimationAdditiveMode::BASE
),
156 mbVisibility( false ),
158 mbWidthValid( false ),
159 mbHeightValid( false ),
160 mbPosXValid( false ),
161 mbPosYValid( false ),
162 mbClipValid( false ),
164 mbFontFamilyValid( false ),
166 mbRotationAngleValid( false ),
167 mbShearXAngleValid( false ),
168 mbShearYAngleValid( false ),
170 mbAlphaValid( false ),
172 mbCharScaleValid( false ),
174 mbDimColorValid( false ),
175 mbFillColorValid( false ),
176 mbLineColorValid( false ),
177 mbCharColorValid( false ),
179 mbFillStyleValid( false ),
180 mbLineStyleValid( false ),
181 mbCharWeightValid( false ),
182 mbUnderlineModeValid( false ),
183 mbCharPostureValid( false ),
184 mbVisibilityValid( false )
188 bool ShapeAttributeLayer::revokeChildLayer( const ShapeAttributeLayerSharedPtr
& rChildLayer
)
190 ENSURE_OR_RETURN_FALSE( rChildLayer
,
191 "ShapeAttributeLayer::revokeChildLayer(): Will not remove NULL child" );
194 return false; // no children, nothing to revoke.
196 if( mpChild
== rChildLayer
)
198 // we have it - replace by removed child's sibling.
199 mpChild
= rChildLayer
->getChildLayer();
201 // if we're now the first one, defensively increment _all_
202 // state ids: possibly all underlying attributes have now
203 // changed to default
206 // TODO(P1): Check whether it pays off to check more
207 // detailed, which attributes really change
208 ++mnTransformationState
;
218 // we don't have it - pass on the request
219 if( !mpChild
->revokeChildLayer( rChildLayer
) )
220 return false; // nobody has it - bail out
223 // something might have changed - update ids.
229 const ShapeAttributeLayerSharedPtr
& ShapeAttributeLayer::getChildLayer() const
234 void ShapeAttributeLayer::setAdditiveMode( sal_Int16 nMode
)
236 if( mnAdditiveMode
!= nMode
)
238 // TODO(P1): Check whether it pays off to check more
239 // detailed, which attributes really change
241 // defensively increment all states - possibly each of them
242 // will change with different additive mode
243 ++mnTransformationState
;
251 mnAdditiveMode
= nMode
;
254 bool ShapeAttributeLayer::isWidthValid() const
256 return mbWidthValid
|| (haveChild() && mpChild
->isWidthValid());
259 double ShapeAttributeLayer::getWidth() const
261 return calcValue
< double >(
264 &ShapeAttributeLayer::isWidthValid
,
265 &ShapeAttributeLayer::getWidth
);
268 void ShapeAttributeLayer::setWidth( const double& rNewWidth
)
270 ENSURE_OR_THROW( std::isfinite(rNewWidth
),
271 "ShapeAttributeLayer::setWidth(): Invalid width" );
273 maSize
.setWidth( rNewWidth
);
275 ++mnTransformationState
;
278 bool ShapeAttributeLayer::isHeightValid() const
280 return mbHeightValid
|| ( haveChild() && mpChild
->isHeightValid() );
283 double ShapeAttributeLayer::getHeight() const
285 return calcValue
< double >(
288 &ShapeAttributeLayer::isHeightValid
,
289 &ShapeAttributeLayer::getHeight
);
292 void ShapeAttributeLayer::setHeight( const double& rNewHeight
)
294 ENSURE_OR_THROW( std::isfinite(rNewHeight
),
295 "ShapeAttributeLayer::setHeight(): Invalid height" );
297 maSize
.setHeight( rNewHeight
);
298 mbHeightValid
= true;
299 ++mnTransformationState
;
302 void ShapeAttributeLayer::setSize( const ::basegfx::B2DSize
& rNewSize
)
304 ENSURE_OR_THROW( std::isfinite(rNewSize
.getWidth()) &&
305 std::isfinite(rNewSize
.getHeight()),
306 "ShapeAttributeLayer::setSize(): Invalid size" );
309 mbWidthValid
= mbHeightValid
= true;
310 ++mnTransformationState
;
313 bool ShapeAttributeLayer::isPosXValid() const
315 return mbPosXValid
|| ( haveChild() && mpChild
->isPosXValid() );
318 double ShapeAttributeLayer::getPosX() const
320 return calcValue
< double >(
323 &ShapeAttributeLayer::isPosXValid
,
324 &ShapeAttributeLayer::getPosX
);
327 void ShapeAttributeLayer::setPosX( const double& rNewX
)
329 ENSURE_OR_THROW( std::isfinite(rNewX
),
330 "ShapeAttributeLayer::setPosX(): Invalid position" );
332 maPosition
.setX( rNewX
);
337 bool ShapeAttributeLayer::isPosYValid() const
339 return mbPosYValid
|| ( haveChild() && mpChild
->isPosYValid() );
342 double ShapeAttributeLayer::getPosY() const
344 return calcValue
< double >(
347 &ShapeAttributeLayer::isPosYValid
,
348 &ShapeAttributeLayer::getPosY
);
351 void ShapeAttributeLayer::setPosY( const double& rNewY
)
353 ENSURE_OR_THROW( std::isfinite(rNewY
),
354 "ShapeAttributeLayer::setPosY(): Invalid position" );
356 maPosition
.setY( rNewY
);
361 void ShapeAttributeLayer::setPosition( const ::basegfx::B2DPoint
& rNewPos
)
363 maPosition
= rNewPos
;
364 mbPosXValid
= mbPosYValid
= true;
368 bool ShapeAttributeLayer::isRotationAngleValid() const
370 return mbRotationAngleValid
|| ( haveChild() && mpChild
->isRotationAngleValid() );
373 double ShapeAttributeLayer::getRotationAngle() const
375 return calcValue
< double >(
377 mbRotationAngleValid
,
378 &ShapeAttributeLayer::isRotationAngleValid
,
379 &ShapeAttributeLayer::getRotationAngle
);
382 void ShapeAttributeLayer::setRotationAngle( const double& rNewAngle
)
384 ENSURE_OR_THROW( std::isfinite(rNewAngle
),
385 "ShapeAttributeLayer::setRotationAngle(): Invalid angle" );
387 mnRotationAngle
= rNewAngle
;
388 mbRotationAngleValid
= true;
389 ++mnTransformationState
;
392 bool ShapeAttributeLayer::isShearXAngleValid() const
394 return mbShearXAngleValid
|| ( haveChild() && mpChild
->isShearXAngleValid() );
397 double ShapeAttributeLayer::getShearXAngle() const
399 return calcValue( mnShearXAngle
,
401 &ShapeAttributeLayer::isShearXAngleValid
,
402 &ShapeAttributeLayer::getShearXAngle
);
405 void ShapeAttributeLayer::setShearXAngle( const double& rNewAngle
)
407 ENSURE_OR_THROW( std::isfinite(rNewAngle
),
408 "ShapeAttributeLayer::setShearXAngle(): Invalid angle" );
410 mnShearXAngle
= rNewAngle
;
411 mbShearXAngleValid
= true;
412 ++mnTransformationState
;
415 bool ShapeAttributeLayer::isShearYAngleValid() const
417 return mbShearYAngleValid
|| ( haveChild() && mpChild
->isShearYAngleValid() );
420 double ShapeAttributeLayer::getShearYAngle() const
422 return calcValue( mnShearYAngle
,
424 &ShapeAttributeLayer::isShearYAngleValid
,
425 &ShapeAttributeLayer::getShearYAngle
);
428 void ShapeAttributeLayer::setShearYAngle( const double& rNewAngle
)
430 ENSURE_OR_THROW( std::isfinite(rNewAngle
),
431 "ShapeAttributeLayer::setShearYAngle(): Invalid angle" );
433 mnShearYAngle
= rNewAngle
;
434 mbShearYAngleValid
= true;
435 ++mnTransformationState
;
438 bool ShapeAttributeLayer::isAlphaValid() const
440 return mbAlphaValid
|| ( haveChild() && mpChild
->isAlphaValid() );
443 double ShapeAttributeLayer::getAlpha() const
445 return calcValue( mnAlpha
,
447 &ShapeAttributeLayer::isAlphaValid
,
448 &ShapeAttributeLayer::getAlpha
);
451 void ShapeAttributeLayer::setAlpha( const double& rNewValue
)
453 ENSURE_OR_THROW( std::isfinite(rNewValue
),
454 "ShapeAttributeLayer::setAlpha(): Invalid alpha" );
461 bool ShapeAttributeLayer::isClipValid() const
463 return mbClipValid
|| ( haveChild() && mpChild
->isClipValid() );
466 ::basegfx::B2DPolyPolygon
ShapeAttributeLayer::getClip() const
468 // TODO(F1): Implement polygon algebra for additive modes
471 else if( haveChild() )
472 return mpChild
->getClip();
474 return ::basegfx::B2DPolyPolygon();
477 void ShapeAttributeLayer::setClip( const ::basegfx::B2DPolyPolygon
& rNewClip
)
484 bool ShapeAttributeLayer::isDimColorValid() const
486 return mbDimColorValid
|| ( haveChild() && mpChild
->isDimColorValid() );
489 RGBColor
ShapeAttributeLayer::getDimColor() const
491 return calcValue( maDimColor
,
493 &ShapeAttributeLayer::isDimColorValid
,
494 &ShapeAttributeLayer::getDimColor
);
497 void ShapeAttributeLayer::setDimColor( const RGBColor
& nNewColor
)
499 maDimColor
= nNewColor
;
500 mbDimColorValid
= true;
504 bool ShapeAttributeLayer::isFillColorValid() const
506 return mbFillColorValid
|| ( haveChild() && mpChild
->isFillColorValid() );
509 RGBColor
ShapeAttributeLayer::getFillColor() const
511 return calcValue( maFillColor
,
513 &ShapeAttributeLayer::isFillColorValid
,
514 &ShapeAttributeLayer::getFillColor
);
517 void ShapeAttributeLayer::setFillColor( const RGBColor
& nNewColor
)
519 maFillColor
= nNewColor
;
520 mbFillColorValid
= true;
524 bool ShapeAttributeLayer::isLineColorValid() const
526 return mbLineColorValid
|| ( haveChild() && mpChild
->isLineColorValid() );
529 RGBColor
ShapeAttributeLayer::getLineColor() const
531 return calcValue( maLineColor
,
533 &ShapeAttributeLayer::isLineColorValid
,
534 &ShapeAttributeLayer::getLineColor
);
537 void ShapeAttributeLayer::setLineColor( const RGBColor
& nNewColor
)
539 maLineColor
= nNewColor
;
540 mbLineColorValid
= true;
544 bool ShapeAttributeLayer::isFillStyleValid() const
546 return mbFillStyleValid
|| ( haveChild() && mpChild
->isFillStyleValid() );
549 sal_Int16
ShapeAttributeLayer::getFillStyle() const
551 // mnAdditiveMode is ignored, cannot combine strings in
553 if( mbFillStyleValid
)
554 return sal::static_int_cast
<sal_Int16
>(meFillStyle
);
555 else if( haveChild() )
556 return sal::static_int_cast
<sal_Int16
>(mpChild
->getFillStyle());
558 return sal::static_int_cast
<sal_Int16
>(drawing::FillStyle_SOLID
);
561 void ShapeAttributeLayer::setFillStyle( const sal_Int16
& rStyle
)
563 // TODO(Q1): Check range here.
564 meFillStyle
= static_cast<drawing::FillStyle
>(rStyle
);
565 mbFillStyleValid
= true;
569 bool ShapeAttributeLayer::isLineStyleValid() const
571 return mbLineStyleValid
|| ( haveChild() && mpChild
->isLineStyleValid() );
574 sal_Int16
ShapeAttributeLayer::getLineStyle() const
576 // mnAdditiveMode is ignored, cannot combine strings in
578 if( mbLineStyleValid
)
579 return sal::static_int_cast
<sal_Int16
>(meLineStyle
);
580 else if( haveChild() )
581 return sal::static_int_cast
<sal_Int16
>(mpChild
->getLineStyle());
583 return sal::static_int_cast
<sal_Int16
>(drawing::LineStyle_SOLID
);
586 void ShapeAttributeLayer::setLineStyle( const sal_Int16
& rStyle
)
588 // TODO(Q1): Check range here.
589 meLineStyle
= static_cast<drawing::LineStyle
>(rStyle
);
590 mbLineStyleValid
= true;
594 bool ShapeAttributeLayer::isVisibilityValid() const
596 return mbVisibilityValid
|| ( haveChild() && mpChild
->isVisibilityValid() );
599 bool ShapeAttributeLayer::getVisibility() const
601 // mnAdditiveMode is ignored, SMIL spec requires to not combine
602 // bools in any sensible way
603 if( mbVisibilityValid
)
605 else if( haveChild() )
606 return mpChild
->getVisibility();
608 return true; // default is always visible
611 void ShapeAttributeLayer::setVisibility( const bool& bVisible
)
613 mbVisibility
= bVisible
;
614 mbVisibilityValid
= true;
618 bool ShapeAttributeLayer::isCharColorValid() const
620 return mbCharColorValid
|| ( haveChild() && mpChild
->isCharColorValid() );
623 RGBColor
ShapeAttributeLayer::getCharColor() const
625 return calcValue( maCharColor
,
627 &ShapeAttributeLayer::isCharColorValid
,
628 &ShapeAttributeLayer::getCharColor
);
631 void ShapeAttributeLayer::setCharColor( const RGBColor
& nNewColor
)
633 maCharColor
= nNewColor
;
634 mbCharColorValid
= true;
638 bool ShapeAttributeLayer::isCharWeightValid() const
640 return mbCharWeightValid
|| ( haveChild() && mpChild
->isCharWeightValid() );
643 double ShapeAttributeLayer::getCharWeight() const
645 // mnAdditiveMode is ignored, cannot combine strings in
647 if( mbCharWeightValid
)
649 else if( haveChild() )
650 return mpChild
->getCharWeight();
652 return awt::FontWeight::NORMAL
;
655 void ShapeAttributeLayer::setCharWeight( const double& rValue
)
657 // TODO(Q1): Check range here.
658 mnCharWeight
= rValue
;
659 mbCharWeightValid
= true;
663 bool ShapeAttributeLayer::isUnderlineModeValid() const
665 return mbUnderlineModeValid
|| ( haveChild() && mpChild
->isUnderlineModeValid() );
668 sal_Int16
ShapeAttributeLayer::getUnderlineMode() const
670 // mnAdditiveMode is ignored, SMIL spec requires to not combine
671 // bools in any sensible way
672 if( mbUnderlineModeValid
)
673 return mnUnderlineMode
;
674 else if( haveChild() )
675 return mpChild
->getUnderlineMode();
677 return awt::FontUnderline::NONE
; // default is no underline
680 void ShapeAttributeLayer::setUnderlineMode( const sal_Int16
& rUnderlineMode
)
682 // TODO(Q1): Check range here.
683 mnUnderlineMode
= rUnderlineMode
;
684 mbUnderlineModeValid
= true;
688 bool ShapeAttributeLayer::isFontFamilyValid() const
690 return mbFontFamilyValid
|| ( haveChild() && mpChild
->isFontFamilyValid() );
693 OUString
ShapeAttributeLayer::getFontFamily() const
695 // mnAdditiveMode is ignored, cannot combine strings in
697 if( mbFontFamilyValid
)
699 else if( haveChild() )
700 return mpChild
->getFontFamily();
705 void ShapeAttributeLayer::setFontFamily( const OUString
& rName
)
707 maFontFamily
= rName
;
708 mbFontFamilyValid
= true;
712 bool ShapeAttributeLayer::isCharPostureValid() const
714 return mbCharPostureValid
|| ( haveChild() && mpChild
->isCharPostureValid() );
717 sal_Int16
ShapeAttributeLayer::getCharPosture() const
719 // mnAdditiveMode is ignored, cannot combine strings in
721 if( mbCharPostureValid
)
722 return sal::static_int_cast
<sal_Int16
>(meCharPosture
);
723 else if( haveChild() )
724 return sal::static_int_cast
<sal_Int16
>(mpChild
->getCharPosture());
726 return sal::static_int_cast
<sal_Int16
>(awt::FontSlant_NONE
);
729 void ShapeAttributeLayer::setCharPosture( const sal_Int16
& rStyle
)
731 // TODO(Q1): Check range here.
732 meCharPosture
= static_cast<awt::FontSlant
>(rStyle
);
733 mbCharPostureValid
= true;
737 bool ShapeAttributeLayer::isCharScaleValid() const
739 return mbCharScaleValid
|| ( haveChild() && mpChild
->isCharScaleValid() );
742 double ShapeAttributeLayer::getCharScale() const
744 return calcValue( mnCharScale
,
746 &ShapeAttributeLayer::isCharScaleValid
,
747 &ShapeAttributeLayer::getCharScale
);
750 void ShapeAttributeLayer::setCharScale( const double& rNewHeight
)
752 ENSURE_OR_THROW( std::isfinite(rNewHeight
),
753 "ShapeAttributeLayer::setCharScale(): Invalid height" );
755 mnCharScale
= rNewHeight
;
756 mbCharScaleValid
= true;
760 State::StateId
ShapeAttributeLayer::getTransformationState() const
763 ::std::max( mnTransformationState
,
764 mpChild
->getTransformationState() ) :
765 mnTransformationState
;
768 State::StateId
ShapeAttributeLayer::getClipState() const
771 ::std::max( mnClipState
,
772 mpChild
->getClipState() ) :
776 State::StateId
ShapeAttributeLayer::getAlphaState() const
779 ::std::max( mnAlphaState
,
780 mpChild
->getAlphaState() ) :
784 State::StateId
ShapeAttributeLayer::getPositionState() const
787 ::std::max( mnPositionState
,
788 mpChild
->getPositionState() ) :
792 State::StateId
ShapeAttributeLayer::getContentState() const
795 ::std::max( mnContentState
,
796 mpChild
->getContentState() ) :
800 State::StateId
ShapeAttributeLayer::getVisibilityState() const
803 ::std::max( mnVisibilityState
,
804 mpChild
->getVisibilityState() ) :
810 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */