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 <tools/diagnose_ex.h>
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>
29 #include <rtl/math.hxx>
32 using namespace ::com::sun::star
;
35 namespace slideshow::internal
39 This method updates all state IDs from possible
40 children. Whenever a child's state ID changed, we
43 void ShapeAttributeLayer::updateStateIds()
48 if( mnTransformationState
!= mpChild
->getTransformationState() )
49 ++mnTransformationState
;
50 if( mnClipState
!= mpChild
->getClipState() )
52 if( mnAlphaState
!= mpChild
->getAlphaState() )
54 if( mnPositionState
!= mpChild
->getPositionState() )
56 if( mnContentState
!= mpChild
->getContentState() )
58 if( mnVisibilityState
!= mpChild
->getVisibilityState() )
62 /** Calc attribute value.
64 This method determines the current attribute value,
65 appropriately combining it with children values (by
66 evaluating the mnAdditiveMode member).
68 template< typename T
> T
ShapeAttributeLayer::calcValue( const T
& rCurrValue
,
69 bool bThisInstanceValid
,
70 bool (ShapeAttributeLayer::*pIsValid
)() const,
71 T (ShapeAttributeLayer::*pGetValue
)() const ) const
73 // deviated from the (*shared_ptr).*mpFuncPtr notation
74 // here, since gcc does not seem to parse that as a member
75 // function call anymore.
76 const bool bChildInstanceValueValid( haveChild() && (mpChild
.get()->*pIsValid
)() );
78 if( bThisInstanceValid
)
80 if( bChildInstanceValueValid
)
82 // merge with child value
83 switch( mnAdditiveMode
)
86 // FALTHROUGH intended
87 case animations::AnimationAdditiveMode::NONE
:
88 // FALTHROUGH intended
89 case animations::AnimationAdditiveMode::BASE
:
90 // FALTHROUGH intended
91 case animations::AnimationAdditiveMode::REPLACE
:
92 // TODO(F2): reverse-engineer the semantics of these
95 // currently, treat them the same and replace
96 // the child value by our own
99 case animations::AnimationAdditiveMode::SUM
:
100 return rCurrValue
+ ((*mpChild
).*pGetValue
)();
102 case animations::AnimationAdditiveMode::MULTIPLY
:
103 return rCurrValue
* ((*mpChild
).*pGetValue
)();
108 // this object is the only one defining
109 // the value, so take it
115 return bChildInstanceValueValid
?
116 ((*mpChild
).*pGetValue
)() :
117 T(); // pass on child value, regardless
118 // if it's valid or not. If not, it's
123 ShapeAttributeLayer::ShapeAttributeLayer( const ShapeAttributeLayerSharedPtr
& rChildLayer
) :
124 mpChild( rChildLayer
),
139 meFillStyle( drawing::FillStyle_NONE
),
140 meLineStyle( drawing::LineStyle_NONE
),
141 meCharPosture( awt::FontSlant_NONE
),
149 mnTransformationState( rChildLayer
? rChildLayer
->getTransformationState() : 0 ),
150 mnClipState( rChildLayer
? rChildLayer
->getClipState() : 0),
151 mnAlphaState( rChildLayer
? rChildLayer
->getAlphaState() : 0),
152 mnPositionState( rChildLayer
? rChildLayer
->getPositionState() : 0 ),
153 mnContentState( rChildLayer
? rChildLayer
->getContentState() : 0 ),
154 mnVisibilityState( rChildLayer
? rChildLayer
->getVisibilityState() : 0 ),
156 mnAdditiveMode( animations::AnimationAdditiveMode::BASE
),
158 mbVisibility( false ),
160 mbWidthValid( false ),
161 mbHeightValid( false ),
162 mbPosXValid( false ),
163 mbPosYValid( false ),
164 mbClipValid( false ),
166 mbFontFamilyValid( false ),
168 mbRotationAngleValid( false ),
169 mbShearXAngleValid( false ),
170 mbShearYAngleValid( false ),
172 mbAlphaValid( false ),
174 mbCharScaleValid( false ),
176 mbDimColorValid( false ),
177 mbFillColorValid( false ),
178 mbLineColorValid( false ),
179 mbCharColorValid( false ),
181 mbFillStyleValid( false ),
182 mbLineStyleValid( false ),
183 mbCharWeightValid( false ),
184 mbUnderlineModeValid( false ),
185 mbCharPostureValid( false ),
186 mbVisibilityValid( false )
190 bool ShapeAttributeLayer::revokeChildLayer( const ShapeAttributeLayerSharedPtr
& rChildLayer
)
192 ENSURE_OR_RETURN_FALSE( rChildLayer
,
193 "ShapeAttributeLayer::revokeChildLayer(): Will not remove NULL child" );
196 return false; // no children, nothing to revoke.
198 if( mpChild
== rChildLayer
)
200 // we have it - replace by removed child's sibling.
201 mpChild
= rChildLayer
->getChildLayer();
203 // if we're now the first one, defensively increment _all_
204 // state ids: possibly all underlying attributes have now
205 // changed to default
208 // TODO(P1): Check whether it pays off to check more
209 // detailed, which attributes really change
210 ++mnTransformationState
;
220 // we don't have it - pass on the request
221 if( !mpChild
->revokeChildLayer( rChildLayer
) )
222 return false; // nobody has it - bail out
225 // something might have changed - update ids.
231 const ShapeAttributeLayerSharedPtr
& ShapeAttributeLayer::getChildLayer() const
236 void ShapeAttributeLayer::setAdditiveMode( sal_Int16 nMode
)
238 if( mnAdditiveMode
!= nMode
)
240 // TODO(P1): Check whether it pays off to check more
241 // detailed, which attributes really change
243 // defensively increment all states - possibly each of them
244 // will change with different additive mode
245 ++mnTransformationState
;
253 mnAdditiveMode
= nMode
;
256 bool ShapeAttributeLayer::isWidthValid() const
258 return mbWidthValid
|| (haveChild() && mpChild
->isWidthValid());
261 double ShapeAttributeLayer::getWidth() const
263 return calcValue
< double >(
266 &ShapeAttributeLayer::isWidthValid
,
267 &ShapeAttributeLayer::getWidth
);
270 void ShapeAttributeLayer::setWidth( const double& rNewWidth
)
272 ENSURE_OR_THROW( std::isfinite(rNewWidth
),
273 "ShapeAttributeLayer::setWidth(): Invalid width" );
275 maSize
.setX( rNewWidth
);
277 ++mnTransformationState
;
280 bool ShapeAttributeLayer::isHeightValid() const
282 return mbHeightValid
|| ( haveChild() && mpChild
->isHeightValid() );
285 double ShapeAttributeLayer::getHeight() const
287 return calcValue
< double >(
290 &ShapeAttributeLayer::isHeightValid
,
291 &ShapeAttributeLayer::getHeight
);
294 void ShapeAttributeLayer::setHeight( const double& rNewHeight
)
296 ENSURE_OR_THROW( std::isfinite(rNewHeight
),
297 "ShapeAttributeLayer::setHeight(): Invalid height" );
299 maSize
.setY( rNewHeight
);
300 mbHeightValid
= true;
301 ++mnTransformationState
;
304 void ShapeAttributeLayer::setSize( const ::basegfx::B2DSize
& rNewSize
)
306 ENSURE_OR_THROW( std::isfinite(rNewSize
.getX()) &&
307 std::isfinite(rNewSize
.getY()),
308 "ShapeAttributeLayer::setSize(): Invalid size" );
311 mbWidthValid
= mbHeightValid
= true;
312 ++mnTransformationState
;
315 bool ShapeAttributeLayer::isPosXValid() const
317 return mbPosXValid
|| ( haveChild() && mpChild
->isPosXValid() );
320 double ShapeAttributeLayer::getPosX() const
322 return calcValue
< double >(
325 &ShapeAttributeLayer::isPosXValid
,
326 &ShapeAttributeLayer::getPosX
);
329 void ShapeAttributeLayer::setPosX( const double& rNewX
)
331 ENSURE_OR_THROW( std::isfinite(rNewX
),
332 "ShapeAttributeLayer::setPosX(): Invalid position" );
334 maPosition
.setX( rNewX
);
339 bool ShapeAttributeLayer::isPosYValid() const
341 return mbPosYValid
|| ( haveChild() && mpChild
->isPosYValid() );
344 double ShapeAttributeLayer::getPosY() const
346 return calcValue
< double >(
349 &ShapeAttributeLayer::isPosYValid
,
350 &ShapeAttributeLayer::getPosY
);
353 void ShapeAttributeLayer::setPosY( const double& rNewY
)
355 ENSURE_OR_THROW( std::isfinite(rNewY
),
356 "ShapeAttributeLayer::setPosY(): Invalid position" );
358 maPosition
.setY( rNewY
);
363 void ShapeAttributeLayer::setPosition( const ::basegfx::B2DPoint
& rNewPos
)
365 maPosition
= rNewPos
;
366 mbPosXValid
= mbPosYValid
= true;
370 bool ShapeAttributeLayer::isRotationAngleValid() const
372 return mbRotationAngleValid
|| ( haveChild() && mpChild
->isRotationAngleValid() );
375 double ShapeAttributeLayer::getRotationAngle() const
377 return calcValue
< double >(
379 mbRotationAngleValid
,
380 &ShapeAttributeLayer::isRotationAngleValid
,
381 &ShapeAttributeLayer::getRotationAngle
);
384 void ShapeAttributeLayer::setRotationAngle( const double& rNewAngle
)
386 ENSURE_OR_THROW( std::isfinite(rNewAngle
),
387 "ShapeAttributeLayer::setRotationAngle(): Invalid angle" );
389 mnRotationAngle
= rNewAngle
;
390 mbRotationAngleValid
= true;
391 ++mnTransformationState
;
394 bool ShapeAttributeLayer::isShearXAngleValid() const
396 return mbShearXAngleValid
|| ( haveChild() && mpChild
->isShearXAngleValid() );
399 double ShapeAttributeLayer::getShearXAngle() const
401 return calcValue( mnShearXAngle
,
403 &ShapeAttributeLayer::isShearXAngleValid
,
404 &ShapeAttributeLayer::getShearXAngle
);
407 void ShapeAttributeLayer::setShearXAngle( const double& rNewAngle
)
409 ENSURE_OR_THROW( std::isfinite(rNewAngle
),
410 "ShapeAttributeLayer::setShearXAngle(): Invalid angle" );
412 mnShearXAngle
= rNewAngle
;
413 mbShearXAngleValid
= true;
414 ++mnTransformationState
;
417 bool ShapeAttributeLayer::isShearYAngleValid() const
419 return mbShearYAngleValid
|| ( haveChild() && mpChild
->isShearYAngleValid() );
422 double ShapeAttributeLayer::getShearYAngle() const
424 return calcValue( mnShearYAngle
,
426 &ShapeAttributeLayer::isShearYAngleValid
,
427 &ShapeAttributeLayer::getShearYAngle
);
430 void ShapeAttributeLayer::setShearYAngle( const double& rNewAngle
)
432 ENSURE_OR_THROW( std::isfinite(rNewAngle
),
433 "ShapeAttributeLayer::setShearYAngle(): Invalid angle" );
435 mnShearYAngle
= rNewAngle
;
436 mbShearYAngleValid
= true;
437 ++mnTransformationState
;
440 bool ShapeAttributeLayer::isAlphaValid() const
442 return mbAlphaValid
|| ( haveChild() && mpChild
->isAlphaValid() );
445 double ShapeAttributeLayer::getAlpha() const
447 return calcValue( mnAlpha
,
449 &ShapeAttributeLayer::isAlphaValid
,
450 &ShapeAttributeLayer::getAlpha
);
453 void ShapeAttributeLayer::setAlpha( const double& rNewValue
)
455 ENSURE_OR_THROW( std::isfinite(rNewValue
),
456 "ShapeAttributeLayer::setAlpha(): Invalid alpha" );
463 bool ShapeAttributeLayer::isClipValid() const
465 return mbClipValid
|| ( haveChild() && mpChild
->isClipValid() );
468 ::basegfx::B2DPolyPolygon
ShapeAttributeLayer::getClip() const
470 // TODO(F1): Implement polygon algebra for additive modes
473 else if( haveChild() )
474 return mpChild
->getClip();
476 return ::basegfx::B2DPolyPolygon();
479 void ShapeAttributeLayer::setClip( const ::basegfx::B2DPolyPolygon
& rNewClip
)
486 bool ShapeAttributeLayer::isDimColorValid() const
488 return mbDimColorValid
|| ( haveChild() && mpChild
->isDimColorValid() );
491 RGBColor
ShapeAttributeLayer::getDimColor() const
493 return calcValue( maDimColor
,
495 &ShapeAttributeLayer::isDimColorValid
,
496 &ShapeAttributeLayer::getDimColor
);
499 void ShapeAttributeLayer::setDimColor( const RGBColor
& nNewColor
)
501 maDimColor
= nNewColor
;
502 mbDimColorValid
= true;
506 bool ShapeAttributeLayer::isFillColorValid() const
508 return mbFillColorValid
|| ( haveChild() && mpChild
->isFillColorValid() );
511 RGBColor
ShapeAttributeLayer::getFillColor() const
513 return calcValue( maFillColor
,
515 &ShapeAttributeLayer::isFillColorValid
,
516 &ShapeAttributeLayer::getFillColor
);
519 void ShapeAttributeLayer::setFillColor( const RGBColor
& nNewColor
)
521 maFillColor
= nNewColor
;
522 mbFillColorValid
= true;
526 bool ShapeAttributeLayer::isLineColorValid() const
528 return mbLineColorValid
|| ( haveChild() && mpChild
->isLineColorValid() );
531 RGBColor
ShapeAttributeLayer::getLineColor() const
533 return calcValue( maLineColor
,
535 &ShapeAttributeLayer::isLineColorValid
,
536 &ShapeAttributeLayer::getLineColor
);
539 void ShapeAttributeLayer::setLineColor( const RGBColor
& nNewColor
)
541 maLineColor
= nNewColor
;
542 mbLineColorValid
= true;
546 bool ShapeAttributeLayer::isFillStyleValid() const
548 return mbFillStyleValid
|| ( haveChild() && mpChild
->isFillStyleValid() );
551 sal_Int16
ShapeAttributeLayer::getFillStyle() const
553 // mnAdditiveMode is ignored, cannot combine strings in
555 if( mbFillStyleValid
)
556 return sal::static_int_cast
<sal_Int16
>(meFillStyle
);
557 else if( haveChild() )
558 return sal::static_int_cast
<sal_Int16
>(mpChild
->getFillStyle());
560 return sal::static_int_cast
<sal_Int16
>(drawing::FillStyle_SOLID
);
563 void ShapeAttributeLayer::setFillStyle( const sal_Int16
& rStyle
)
565 // TODO(Q1): Check range here.
566 meFillStyle
= static_cast<drawing::FillStyle
>(rStyle
);
567 mbFillStyleValid
= true;
571 bool ShapeAttributeLayer::isLineStyleValid() const
573 return mbLineStyleValid
|| ( haveChild() && mpChild
->isLineStyleValid() );
576 sal_Int16
ShapeAttributeLayer::getLineStyle() const
578 // mnAdditiveMode is ignored, cannot combine strings in
580 if( mbLineStyleValid
)
581 return sal::static_int_cast
<sal_Int16
>(meLineStyle
);
582 else if( haveChild() )
583 return sal::static_int_cast
<sal_Int16
>(mpChild
->getLineStyle());
585 return sal::static_int_cast
<sal_Int16
>(drawing::LineStyle_SOLID
);
588 void ShapeAttributeLayer::setLineStyle( const sal_Int16
& rStyle
)
590 // TODO(Q1): Check range here.
591 meLineStyle
= static_cast<drawing::LineStyle
>(rStyle
);
592 mbLineStyleValid
= true;
596 bool ShapeAttributeLayer::isVisibilityValid() const
598 return mbVisibilityValid
|| ( haveChild() && mpChild
->isVisibilityValid() );
601 bool ShapeAttributeLayer::getVisibility() const
603 // mnAdditiveMode is ignored, SMIL spec requires to not combine
604 // bools in any sensible way
605 if( mbVisibilityValid
)
607 else if( haveChild() )
608 return mpChild
->getVisibility();
610 return true; // default is always visible
613 void ShapeAttributeLayer::setVisibility( const bool& bVisible
)
615 mbVisibility
= bVisible
;
616 mbVisibilityValid
= true;
620 bool ShapeAttributeLayer::isCharColorValid() const
622 return mbCharColorValid
|| ( haveChild() && mpChild
->isCharColorValid() );
625 RGBColor
ShapeAttributeLayer::getCharColor() const
627 return calcValue( maCharColor
,
629 &ShapeAttributeLayer::isCharColorValid
,
630 &ShapeAttributeLayer::getCharColor
);
633 void ShapeAttributeLayer::setCharColor( const RGBColor
& nNewColor
)
635 maCharColor
= nNewColor
;
636 mbCharColorValid
= true;
640 bool ShapeAttributeLayer::isCharWeightValid() const
642 return mbCharWeightValid
|| ( haveChild() && mpChild
->isCharWeightValid() );
645 double ShapeAttributeLayer::getCharWeight() const
647 // mnAdditiveMode is ignored, cannot combine strings in
649 if( mbCharWeightValid
)
651 else if( haveChild() )
652 return mpChild
->getCharWeight();
654 return awt::FontWeight::NORMAL
;
657 void ShapeAttributeLayer::setCharWeight( const double& rValue
)
659 // TODO(Q1): Check range here.
660 mnCharWeight
= rValue
;
661 mbCharWeightValid
= true;
665 bool ShapeAttributeLayer::isUnderlineModeValid() const
667 return mbUnderlineModeValid
|| ( haveChild() && mpChild
->isUnderlineModeValid() );
670 sal_Int16
ShapeAttributeLayer::getUnderlineMode() const
672 // mnAdditiveMode is ignored, SMIL spec requires to not combine
673 // bools in any sensible way
674 if( mbUnderlineModeValid
)
675 return mnUnderlineMode
;
676 else if( haveChild() )
677 return mpChild
->getUnderlineMode();
679 return awt::FontUnderline::NONE
; // default is no underline
682 void ShapeAttributeLayer::setUnderlineMode( const sal_Int16
& rUnderlineMode
)
684 // TODO(Q1): Check range here.
685 mnUnderlineMode
= rUnderlineMode
;
686 mbUnderlineModeValid
= true;
690 bool ShapeAttributeLayer::isFontFamilyValid() const
692 return mbFontFamilyValid
|| ( haveChild() && mpChild
->isFontFamilyValid() );
695 OUString
ShapeAttributeLayer::getFontFamily() const
697 // mnAdditiveMode is ignored, cannot combine strings in
699 if( mbFontFamilyValid
)
701 else if( haveChild() )
702 return mpChild
->getFontFamily();
707 void ShapeAttributeLayer::setFontFamily( const OUString
& rName
)
709 maFontFamily
= rName
;
710 mbFontFamilyValid
= true;
714 bool ShapeAttributeLayer::isCharPostureValid() const
716 return mbCharPostureValid
|| ( haveChild() && mpChild
->isCharPostureValid() );
719 sal_Int16
ShapeAttributeLayer::getCharPosture() const
721 // mnAdditiveMode is ignored, cannot combine strings in
723 if( mbCharPostureValid
)
724 return sal::static_int_cast
<sal_Int16
>(meCharPosture
);
725 else if( haveChild() )
726 return sal::static_int_cast
<sal_Int16
>(mpChild
->getCharPosture());
728 return sal::static_int_cast
<sal_Int16
>(awt::FontSlant_NONE
);
731 void ShapeAttributeLayer::setCharPosture( const sal_Int16
& rStyle
)
733 // TODO(Q1): Check range here.
734 meCharPosture
= static_cast<awt::FontSlant
>(rStyle
);
735 mbCharPostureValid
= true;
739 bool ShapeAttributeLayer::isCharScaleValid() const
741 return mbCharScaleValid
|| ( haveChild() && mpChild
->isCharScaleValid() );
744 double ShapeAttributeLayer::getCharScale() const
746 return calcValue( mnCharScale
,
748 &ShapeAttributeLayer::isCharScaleValid
,
749 &ShapeAttributeLayer::getCharScale
);
752 void ShapeAttributeLayer::setCharScale( const double& rNewHeight
)
754 ENSURE_OR_THROW( std::isfinite(rNewHeight
),
755 "ShapeAttributeLayer::setCharScale(): Invalid height" );
757 mnCharScale
= rNewHeight
;
758 mbCharScaleValid
= true;
762 State::StateId
ShapeAttributeLayer::getTransformationState() const
765 ::std::max( mnTransformationState
,
766 mpChild
->getTransformationState() ) :
767 mnTransformationState
;
770 State::StateId
ShapeAttributeLayer::getClipState() const
773 ::std::max( mnClipState
,
774 mpChild
->getClipState() ) :
778 State::StateId
ShapeAttributeLayer::getAlphaState() const
781 ::std::max( mnAlphaState
,
782 mpChild
->getAlphaState() ) :
786 State::StateId
ShapeAttributeLayer::getPositionState() const
789 ::std::max( mnPositionState
,
790 mpChild
->getPositionState() ) :
794 State::StateId
ShapeAttributeLayer::getContentState() const
797 ::std::max( mnContentState
,
798 mpChild
->getContentState() ) :
802 State::StateId
ShapeAttributeLayer::getVisibilityState() const
805 ::std::max( mnVisibilityState
,
806 mpChild
->getVisibilityState() ) :
812 /* vim:set shiftwidth=4 softtabstop=4 expandtab: */