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