LCOV - code coverage report
Current view: top level - svx/source/svdraw - svdotextdecomposition.cxx (source / functions) Hit Total Coverage
Test: libreoffice_filtered.info Lines: 260 562 46.3 %
Date: 2012-08-25 Functions: 15 35 42.9 %
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed Branches: 302 1056 28.6 %

           Branch data     Line data    Source code
       1                 :            : /* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
       2                 :            : /*************************************************************************
       3                 :            :  *
       4                 :            :  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       5                 :            :  *
       6                 :            :  * Copyright 2000, 2010 Oracle and/or its affiliates.
       7                 :            :  *
       8                 :            :  * OpenOffice.org - a multi-platform office productivity suite
       9                 :            :  *
      10                 :            :  * This file is part of OpenOffice.org.
      11                 :            :  *
      12                 :            :  * OpenOffice.org is free software: you can redistribute it and/or modify
      13                 :            :  * it under the terms of the GNU Lesser General Public License version 3
      14                 :            :  * only, as published by the Free Software Foundation.
      15                 :            :  *
      16                 :            :  * OpenOffice.org is distributed in the hope that it will be useful,
      17                 :            :  * but WITHOUT ANY WARRANTY; without even the implied warranty of
      18                 :            :  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
      19                 :            :  * GNU Lesser General Public License version 3 for more details
      20                 :            :  * (a copy is included in the LICENSE file that accompanied this code).
      21                 :            :  *
      22                 :            :  * You should have received a copy of the GNU Lesser General Public License
      23                 :            :  * version 3 along with OpenOffice.org.  If not, see
      24                 :            :  * <http://www.openoffice.org/license.html>
      25                 :            :  * for a copy of the LGPLv3 License.
      26                 :            :  *
      27                 :            :  ************************************************************************/
      28                 :            : 
      29                 :            : 
      30                 :            : #include <svx/svdotext.hxx>
      31                 :            : #include <svx/svdoutl.hxx>
      32                 :            : #include <basegfx/vector/b2dvector.hxx>
      33                 :            : #include <svx/sdr/primitive2d/sdrtextprimitive2d.hxx>
      34                 :            : #include <drawinglayer/primitive2d/textprimitive2d.hxx>
      35                 :            : #include <drawinglayer/primitive2d/textdecoratedprimitive2d.hxx>
      36                 :            : #include <basegfx/range/b2drange.hxx>
      37                 :            : #include <editeng/editstat.hxx>
      38                 :            : #include <tools/helpers.hxx>
      39                 :            : #include <svx/sdtfchim.hxx>
      40                 :            : #include <svl/itemset.hxx>
      41                 :            : #include <basegfx/polygon/b2dpolygontools.hxx>
      42                 :            : #include <basegfx/polygon/b2dpolygon.hxx>
      43                 :            : #include <drawinglayer/animation/animationtiming.hxx>
      44                 :            : #include <basegfx/color/bcolor.hxx>
      45                 :            : #include <vcl/svapp.hxx>
      46                 :            : #include <editeng/eeitemid.hxx>
      47                 :            : #include <editeng/escpitem.hxx>
      48                 :            : #include <editeng/svxenum.hxx>
      49                 :            : #include <editeng/flditem.hxx>
      50                 :            : #include <drawinglayer/primitive2d/texthierarchyprimitive2d.hxx>
      51                 :            : #include <vcl/metaact.hxx>
      52                 :            : #include <drawinglayer/primitive2d/wrongspellprimitive2d.hxx>
      53                 :            : #include <drawinglayer/primitive2d/graphicprimitive2d.hxx>
      54                 :            : #include <drawinglayer/primitive2d/textlayoutdevice.hxx>
      55                 :            : #include <svx/unoapi.hxx>
      56                 :            : #include <drawinglayer/geometry/viewinformation2d.hxx>
      57                 :            : #include <editeng/outlobj.hxx>
      58                 :            : #include <basegfx/matrix/b2dhommatrixtools.hxx>
      59                 :            : 
      60                 :            : //////////////////////////////////////////////////////////////////////////////
      61                 :            : // helpers
      62                 :            : 
      63                 :            : namespace
      64                 :            : {
      65                 :      46990 :     drawinglayer::primitive2d::Primitive2DSequence impConvertVectorToPrimitive2DSequence(const std::vector< drawinglayer::primitive2d::BasePrimitive2D* >& rPrimitiveVector)
      66                 :            :     {
      67                 :      46990 :         const sal_Int32 nCount(rPrimitiveVector.size());
      68                 :      46990 :         drawinglayer::primitive2d::Primitive2DSequence aRetval(nCount);
      69                 :            : 
      70         [ +  + ]:      98211 :         for(sal_Int32 a(0L); a < nCount; a++)
      71                 :            :         {
      72 [ +  - ][ +  - ]:      51221 :             aRetval[a] = drawinglayer::primitive2d::Primitive2DReference(rPrimitiveVector[a]);
         [ +  - ][ +  - ]
                 [ +  - ]
      73                 :            :         }
      74                 :            : 
      75                 :      46990 :         return aRetval;
      76                 :            :     }
      77                 :            : 
      78 [ +  - ][ +  - ]:      13696 :     class impTextBreakupHandler
      79                 :            :     {
      80                 :            :     private:
      81                 :            :         std::vector< drawinglayer::primitive2d::BasePrimitive2D* >  maTextPortionPrimitives;
      82                 :            :         std::vector< drawinglayer::primitive2d::BasePrimitive2D* >  maLinePrimitives;
      83                 :            :         std::vector< drawinglayer::primitive2d::BasePrimitive2D* >  maParagraphPrimitives;
      84                 :            : 
      85                 :            :         SdrOutliner&                                                mrOutliner;
      86                 :            :         basegfx::B2DHomMatrix                                       maNewTransformA;
      87                 :            :         basegfx::B2DHomMatrix                                       maNewTransformB;
      88                 :            : 
      89                 :            :         // the visible area for contour text decomposition
      90                 :            :         basegfx::B2DVector                                          maScale;
      91                 :            : 
      92                 :            :         // ClipRange for BlockText decomposition; only text portions completely
      93                 :            :         // inside are to be accepted, so this is different from geometric clipping
      94                 :            :         // (which would allow e.g. upper parts of portions to remain). Only used for
      95                 :            :         // BlockText (see there)
      96                 :            :         basegfx::B2DRange                                           maClipRange;
      97                 :            : 
      98                 :            :         DECL_LINK(decomposeContourTextPrimitive, DrawPortionInfo* );
      99                 :            :         DECL_LINK(decomposeBlockTextPrimitive, DrawPortionInfo* );
     100                 :            :         DECL_LINK(decomposeStretchTextPrimitive, DrawPortionInfo* );
     101                 :            : 
     102                 :            :         DECL_LINK(decomposeContourBulletPrimitive, DrawBulletInfo* );
     103                 :            :         DECL_LINK(decomposeBlockBulletPrimitive, DrawBulletInfo* );
     104                 :            :         DECL_LINK(decomposeStretchBulletPrimitive, DrawBulletInfo* );
     105                 :            : 
     106                 :            :         bool impIsUnderlineAbove(const Font& rFont) const;
     107                 :            :         void impCreateTextPortionPrimitive(const DrawPortionInfo& rInfo);
     108                 :            :         drawinglayer::primitive2d::BasePrimitive2D* impCheckFieldPrimitive(drawinglayer::primitive2d::BasePrimitive2D* pPrimitive, const DrawPortionInfo& rInfo) const;
     109                 :            :         void impFlushTextPortionPrimitivesToLinePrimitives();
     110                 :            :         void impFlushLinePrimitivesToParagraphPrimitives();
     111                 :            :         void impHandleDrawPortionInfo(const DrawPortionInfo& rInfo);
     112                 :            :         void impHandleDrawBulletInfo(const DrawBulletInfo& rInfo);
     113                 :            : 
     114                 :            :     public:
     115                 :      13696 :         impTextBreakupHandler(SdrOutliner& rOutliner)
     116                 :            :         :   maTextPortionPrimitives(),
     117                 :            :             maLinePrimitives(),
     118                 :            :             maParagraphPrimitives(),
     119                 :            :             mrOutliner(rOutliner),
     120                 :            :             maNewTransformA(),
     121                 :            :             maNewTransformB(),
     122                 :            :             maScale(),
     123 [ +  - ][ +  - ]:      13696 :             maClipRange()
         [ +  - ][ +  - ]
                 [ +  - ]
     124                 :            :         {
     125                 :      13696 :         }
     126                 :            : 
     127                 :          0 :         void decomposeContourTextPrimitive(const basegfx::B2DHomMatrix& rNewTransformA, const basegfx::B2DHomMatrix& rNewTransformB, const basegfx::B2DVector& rScale)
     128                 :            :         {
     129                 :          0 :             maScale = rScale;
     130                 :          0 :             maNewTransformA = rNewTransformA;
     131                 :          0 :             maNewTransformB = rNewTransformB;
     132                 :          0 :             mrOutliner.SetDrawPortionHdl(LINK(this, impTextBreakupHandler, decomposeContourTextPrimitive));
     133                 :          0 :             mrOutliner.SetDrawBulletHdl(LINK(this, impTextBreakupHandler, decomposeContourBulletPrimitive));
     134                 :          0 :             mrOutliner.StripPortions();
     135                 :          0 :             mrOutliner.SetDrawPortionHdl(Link());
     136                 :          0 :             mrOutliner.SetDrawBulletHdl(Link());
     137                 :          0 :         }
     138                 :            : 
     139                 :      13696 :         void decomposeBlockTextPrimitive(
     140                 :            :             const basegfx::B2DHomMatrix& rNewTransformA,
     141                 :            :             const basegfx::B2DHomMatrix& rNewTransformB,
     142                 :            :             const basegfx::B2DRange& rClipRange)
     143                 :            :         {
     144                 :      13696 :             maNewTransformA = rNewTransformA;
     145                 :      13696 :             maNewTransformB = rNewTransformB;
     146                 :      13696 :             maClipRange = rClipRange;
     147                 :      13696 :             mrOutliner.SetDrawPortionHdl(LINK(this, impTextBreakupHandler, decomposeBlockTextPrimitive));
     148                 :      13696 :             mrOutliner.SetDrawBulletHdl(LINK(this, impTextBreakupHandler, decomposeBlockBulletPrimitive));
     149                 :      13696 :             mrOutliner.StripPortions();
     150                 :      13696 :             mrOutliner.SetDrawPortionHdl(Link());
     151                 :      13696 :             mrOutliner.SetDrawBulletHdl(Link());
     152                 :      13696 :         }
     153                 :            : 
     154                 :          0 :         void decomposeStretchTextPrimitive(const basegfx::B2DHomMatrix& rNewTransformA, const basegfx::B2DHomMatrix& rNewTransformB)
     155                 :            :         {
     156                 :          0 :             maNewTransformA = rNewTransformA;
     157                 :          0 :             maNewTransformB = rNewTransformB;
     158                 :          0 :             mrOutliner.SetDrawPortionHdl(LINK(this, impTextBreakupHandler, decomposeStretchTextPrimitive));
     159                 :          0 :             mrOutliner.SetDrawBulletHdl(LINK(this, impTextBreakupHandler, decomposeStretchBulletPrimitive));
     160                 :          0 :             mrOutliner.StripPortions();
     161                 :          0 :             mrOutliner.SetDrawPortionHdl(Link());
     162                 :          0 :             mrOutliner.SetDrawBulletHdl(Link());
     163                 :          0 :         }
     164                 :            : 
     165                 :            :         drawinglayer::primitive2d::Primitive2DSequence getPrimitive2DSequence();
     166                 :            :     };
     167                 :            : 
     168                 :       1815 :     bool impTextBreakupHandler::impIsUnderlineAbove(const Font& rFont) const
     169                 :            :     {
     170         [ +  - ]:       1815 :         if(!rFont.IsVertical())
     171                 :            :         {
     172                 :       1815 :             return false;
     173                 :            :         }
     174                 :            : 
     175 [ #  # ][ #  # ]:          0 :         if((LANGUAGE_JAPANESE == rFont.GetLanguage()) || (LANGUAGE_JAPANESE == rFont.GetCJKContextLanguage()))
                 [ #  # ]
     176                 :            :         {
     177                 :            :             // the underline is right for Japanese only
     178                 :          0 :             return true;
     179                 :            :         }
     180                 :            : 
     181                 :       1815 :         return false;
     182                 :            :     }
     183                 :            : 
     184                 :      18454 :     void impTextBreakupHandler::impCreateTextPortionPrimitive(const DrawPortionInfo& rInfo)
     185                 :            :     {
     186 [ +  + ][ +  - ]:      18454 :         if(rInfo.mrText.Len() && rInfo.mnTextLen)
                 [ +  + ]
     187                 :            :         {
     188                 :      17927 :             basegfx::B2DVector aFontScaling;
     189                 :            :             drawinglayer::attribute::FontAttribute aFontAttribute(
     190                 :            :                 drawinglayer::primitive2d::getFontAttributeFromVclFont(
     191                 :            :                     aFontScaling,
     192                 :            :                     rInfo.mrFont,
     193         [ +  - ]:      17927 :                     rInfo.IsRTL(),
     194         [ +  - ]:      17927 :                     false));
     195         [ +  - ]:      17927 :             basegfx::B2DHomMatrix aNewTransform;
     196                 :            : 
     197                 :            :             // add font scale to new transform
     198         [ +  - ]:      17927 :             aNewTransform.scale(aFontScaling.getX(), aFontScaling.getY());
     199                 :            : 
     200                 :            :             // look for proportional font scaling, if necessary, scale accordingly
     201         [ +  + ]:      17927 :             if(100 != rInfo.mrFont.GetPropr())
     202                 :            :             {
     203                 :        769 :                 const double fFactor(rInfo.mrFont.GetPropr() / 100.0);
     204         [ +  - ]:        769 :                 aNewTransform.scale(fFactor, fFactor);
     205                 :            :             }
     206                 :            : 
     207                 :            :             // apply font rotate
     208 [ +  - ][ -  + ]:      17927 :             if(rInfo.mrFont.GetOrientation())
     209                 :            :             {
     210 [ #  # ][ #  # ]:          0 :                 aNewTransform.rotate(-rInfo.mrFont.GetOrientation() * F_PI1800);
     211                 :            :             }
     212                 :            : 
     213                 :            :             // look for escapement, if necessary, translate accordingly
     214         [ +  + ]:      17927 :             if(rInfo.mrFont.GetEscapement())
     215                 :            :             {
     216                 :       1502 :                 sal_Int16 nEsc(rInfo.mrFont.GetEscapement());
     217                 :            : 
     218         [ -  + ]:       1502 :                 if(DFLT_ESC_AUTO_SUPER == nEsc)
     219                 :            :                 {
     220                 :          0 :                     nEsc = 33;
     221                 :            :                 }
     222         [ -  + ]:       1502 :                 else if(DFLT_ESC_AUTO_SUB == nEsc)
     223                 :            :                 {
     224                 :          0 :                     nEsc = -20;
     225                 :            :                 }
     226                 :            : 
     227         [ -  + ]:       1502 :                 if(nEsc > 100)
     228                 :            :                 {
     229                 :          0 :                     nEsc = 100;
     230                 :            :                 }
     231         [ -  + ]:       1502 :                 else if(nEsc < -100)
     232                 :            :                 {
     233                 :          0 :                     nEsc = -100;
     234                 :            :                 }
     235                 :            : 
     236                 :       1502 :                 const double fEscapement(nEsc / -100.0);
     237         [ +  - ]:       1502 :                 aNewTransform.translate(0.0, fEscapement * aFontScaling.getY());
     238                 :            :             }
     239                 :            : 
     240                 :            :             // apply transformA
     241         [ +  - ]:      17927 :             aNewTransform *= maNewTransformA;
     242                 :            : 
     243                 :            :             // apply local offset
     244         [ +  - ]:      17927 :             aNewTransform.translate(rInfo.mrStartPos.X(), rInfo.mrStartPos.Y());
     245                 :            : 
     246                 :            :             // also apply embedding object's transform
     247         [ +  - ]:      17927 :             aNewTransform *= maNewTransformB;
     248                 :            : 
     249                 :            :             // prepare DXArray content. To make it independent from font size (and such from
     250                 :            :             // the text transformation), scale it to unit coordinates
     251         [ +  - ]:      17927 :             ::std::vector< double > aDXArray;
     252                 :            :             static bool bDisableTextArray(false);
     253                 :            : 
     254 [ +  - ][ +  - ]:      17927 :             if(!bDisableTextArray && rInfo.mpDXArray && rInfo.mnTextLen)
                 [ +  - ]
     255                 :            :             {
     256         [ +  - ]:      17927 :                 aDXArray.reserve(rInfo.mnTextLen);
     257                 :            : 
     258         [ +  + ]:     130502 :                 for(xub_StrLen a(0); a < rInfo.mnTextLen; a++)
     259                 :            :                 {
     260         [ +  - ]:     112575 :                     aDXArray.push_back((double)rInfo.mpDXArray[a]);
     261                 :            :                 }
     262                 :            :             }
     263                 :            : 
     264                 :            :             // create complex text primitive and append
     265         [ +  - ]:      17927 :             const Color aFontColor(rInfo.mrFont.GetColor());
     266                 :      17927 :             const basegfx::BColor aBFontColor(aFontColor.getBColor());
     267                 :            : 
     268                 :            :             // prepare wordLineMode (for underline and strikeout)
     269                 :            :             // NOT for bullet texts. It is set (this may be an error by itself), but needs to be suppressed to hinder e.g. '1)'
     270                 :            :             // to be split which would not look like the original
     271 [ +  + ][ +  - ]:      17927 :             const bool bWordLineMode(rInfo.mrFont.IsWordLineMode() && !rInfo.mbEndOfBullet);
                 [ +  - ]
     272                 :            : 
     273                 :            :             // prepare new primitive
     274                 :      17927 :             drawinglayer::primitive2d::BasePrimitive2D* pNewPrimitive = 0;
     275                 :            :             const bool bDecoratedIsNeeded(
     276         [ +  - ]:      17927 :                    UNDERLINE_NONE != rInfo.mrFont.GetOverline()
     277         [ +  - ]:      16382 :                 || UNDERLINE_NONE != rInfo.mrFont.GetUnderline()
     278         [ +  - ]:      15954 :                 || STRIKEOUT_NONE != rInfo.mrFont.GetStrikeout()
     279         [ +  - ]:      15925 :                 || EMPHASISMARK_NONE != (rInfo.mrFont.GetEmphasisMark() & EMPHASISMARK_STYLE)
     280         [ +  - ]:      15909 :                 || RELIEF_NONE != rInfo.mrFont.GetRelief()
     281         [ +  - ]:      15909 :                 || rInfo.mrFont.IsShadow()
     282 [ +  + ][ +  + ]:      98006 :                 || bWordLineMode);
         [ +  + ][ +  + ]
         [ +  - ][ +  - ]
                 [ -  + ]
     283                 :            : 
     284         [ +  + ]:      17927 :             if(bDecoratedIsNeeded)
     285                 :            :             {
     286                 :            :                 // TextDecoratedPortionPrimitive2D needed, prepare some more data
     287                 :            :                 // get overline and underline color. If it's on automatic (0xffffffff) use FontColor instead
     288                 :       2018 :                 const Color aUnderlineColor(rInfo.maTextLineColor);
     289         [ +  + ]:       2018 :                 const basegfx::BColor aBUnderlineColor((0xffffffff == aUnderlineColor.GetColor()) ? aBFontColor : aUnderlineColor.getBColor());
     290                 :       2018 :                 const Color aOverlineColor(rInfo.maOverlineColor);
     291         [ +  + ]:       2018 :                 const basegfx::BColor aBOverlineColor((0xffffffff == aOverlineColor.GetColor()) ? aBFontColor : aOverlineColor.getBColor());
     292                 :            : 
     293                 :            :                 // prepare overline and underline data
     294                 :            :                 const drawinglayer::primitive2d::TextLine eFontOverline(
     295 [ +  - ][ +  - ]:       2018 :                     drawinglayer::primitive2d::mapFontUnderlineToTextLine(rInfo.mrFont.GetOverline()));
     296                 :            :                 const drawinglayer::primitive2d::TextLine eFontUnderline(
     297 [ +  - ][ +  - ]:       2018 :                     drawinglayer::primitive2d::mapFontUnderlineToTextLine(rInfo.mrFont.GetUnderline()));
     298                 :            : 
     299                 :            :                 // check UnderlineAbove
     300                 :            :                 const bool bUnderlineAbove(
     301 [ +  + ][ +  - ]:       2018 :                     drawinglayer::primitive2d::TEXT_LINE_NONE != eFontUnderline && impIsUnderlineAbove(rInfo.mrFont));
                 [ -  + ]
     302                 :            : 
     303                 :            :                 // prepare strikeout data
     304                 :            :                 const drawinglayer::primitive2d::TextStrikeout eTextStrikeout(
     305 [ +  - ][ +  - ]:       2018 :                     drawinglayer::primitive2d::mapFontStrikeoutToTextStrikeout(rInfo.mrFont.GetStrikeout()));
     306                 :            : 
     307                 :            :                 // prepare emphasis mark data
     308                 :       2018 :                 drawinglayer::primitive2d::TextEmphasisMark eTextEmphasisMark(drawinglayer::primitive2d::TEXT_EMPHASISMARK_NONE);
     309                 :            : 
     310 [ +  - ][ +  +  :       2018 :                 switch(rInfo.mrFont.GetEmphasisMark() & EMPHASISMARK_STYLE)
                +  +  + ]
     311                 :            :                 {
     312                 :        649 :                     case EMPHASISMARK_DOT : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_DOT; break;
     313                 :        749 :                     case EMPHASISMARK_CIRCLE : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_CIRCLE; break;
     314                 :        305 :                     case EMPHASISMARK_DISC : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_DISC; break;
     315                 :        148 :                     case EMPHASISMARK_ACCENT : eTextEmphasisMark = drawinglayer::primitive2d::TEXT_EMPHASISMARK_ACCENT; break;
     316                 :            :                 }
     317                 :            : 
     318         [ +  - ]:       2018 :                 const bool bEmphasisMarkAbove(rInfo.mrFont.GetEmphasisMark() & EMPHASISMARK_POS_ABOVE);
     319         [ +  - ]:       2018 :                 const bool bEmphasisMarkBelow(rInfo.mrFont.GetEmphasisMark() & EMPHASISMARK_POS_BELOW);
     320                 :            : 
     321                 :            :                 // prepare font relief data
     322                 :       2018 :                 drawinglayer::primitive2d::TextRelief eTextRelief(drawinglayer::primitive2d::TEXT_RELIEF_NONE);
     323                 :            : 
     324         [ +  - ]:       2018 :                 switch(rInfo.mrFont.GetRelief())
              [ +  -  + ]
     325                 :            :                 {
     326                 :       1372 :                     case RELIEF_EMBOSSED : eTextRelief = drawinglayer::primitive2d::TEXT_RELIEF_EMBOSSED; break;
     327                 :          0 :                     case RELIEF_ENGRAVED : eTextRelief = drawinglayer::primitive2d::TEXT_RELIEF_ENGRAVED; break;
     328                 :        646 :                     default : break; // RELIEF_NONE, FontRelief_FORCE_EQUAL_SIZE
     329                 :            :                 }
     330                 :            : 
     331                 :            :                 // prepare shadow/outline data
     332         [ +  - ]:       2018 :                 const bool bShadow(rInfo.mrFont.IsShadow());
     333                 :            : 
     334                 :            :                 // TextDecoratedPortionPrimitive2D is needed, create one
     335                 :            :                 pNewPrimitive = new drawinglayer::primitive2d::TextDecoratedPortionPrimitive2D(
     336                 :            : 
     337                 :            :                     // attributes for TextSimplePortionPrimitive2D
     338                 :            :                     aNewTransform,
     339                 :            :                     rInfo.mrText,
     340                 :            :                     rInfo.mnTextStart,
     341                 :            :                     rInfo.mnTextLen,
     342                 :            :                     aDXArray,
     343                 :            :                     aFontAttribute,
     344                 :            :                     rInfo.mpLocale ? *rInfo.mpLocale : ::com::sun::star::lang::Locale(),
     345                 :            :                     aBFontColor,
     346                 :            : 
     347                 :            :                     // attributes for TextDecoratedPortionPrimitive2D
     348                 :            :                     aBOverlineColor,
     349                 :            :                     aBUnderlineColor,
     350                 :            :                     eFontOverline,
     351                 :            :                     eFontUnderline,
     352                 :            :                     bUnderlineAbove,
     353                 :            :                     eTextStrikeout,
     354                 :            :                     bWordLineMode,
     355                 :            :                     eTextEmphasisMark,
     356                 :            :                     bEmphasisMarkAbove,
     357                 :            :                     bEmphasisMarkBelow,
     358                 :            :                     eTextRelief,
     359 [ +  - ][ +  - ]:       2018 :                     bShadow);
     360                 :            :             }
     361                 :            :             else
     362                 :            :             {
     363                 :            :                 // TextSimplePortionPrimitive2D is enough
     364                 :            :                 pNewPrimitive = new drawinglayer::primitive2d::TextSimplePortionPrimitive2D(
     365                 :            :                     aNewTransform,
     366                 :            :                     rInfo.mrText,
     367                 :            :                     rInfo.mnTextStart,
     368                 :            :                     rInfo.mnTextLen,
     369                 :            :                     aDXArray,
     370                 :            :                     aFontAttribute,
     371                 :            :                     rInfo.mpLocale ? *rInfo.mpLocale : ::com::sun::star::lang::Locale(),
     372                 :            :                     aBFontColor,
     373                 :            :                     rInfo.mbFilled,
     374 [ +  + ][ +  - ]:      15909 :                     rInfo.mnWidthToFill);
     375                 :            :             }
     376                 :            : 
     377         [ +  + ]:      17927 :             if(rInfo.mbEndOfBullet)
     378                 :            :             {
     379                 :            :                 // embed in TextHierarchyBulletPrimitive2D
     380 [ +  - ][ +  - ]:        420 :                 const drawinglayer::primitive2d::Primitive2DReference aNewReference(pNewPrimitive);
     381         [ +  - ]:        420 :                 const drawinglayer::primitive2d::Primitive2DSequence aNewSequence(&aNewReference, 1);
     382 [ +  - ][ +  - ]:        420 :                 pNewPrimitive = new drawinglayer::primitive2d::TextHierarchyBulletPrimitive2D(aNewSequence);
     383                 :            :             }
     384                 :            : 
     385         [ +  + ]:      17927 :             if(rInfo.mpFieldData)
     386                 :            :             {
     387         [ +  - ]:        888 :                 pNewPrimitive = impCheckFieldPrimitive(pNewPrimitive, rInfo);
     388                 :            :             }
     389                 :            : 
     390         [ +  - ]:      17927 :             maTextPortionPrimitives.push_back(pNewPrimitive);
     391                 :            : 
     392                 :            :             // support for WrongSpellVector. Create WrongSpellPrimitives as needed
     393 [ -  + ][ #  # ]:      17927 :             if(rInfo.mpWrongSpellVector && !aDXArray.empty())
                 [ -  + ]
     394                 :            :             {
     395                 :          0 :                 const sal_uInt32 nSize(rInfo.mpWrongSpellVector->size());
     396                 :          0 :                 const sal_uInt32 nDXCount(aDXArray.size());
     397                 :          0 :                 const basegfx::BColor aSpellColor(1.0, 0.0, 0.0); // red, hard coded
     398                 :            : 
     399         [ #  # ]:          0 :                 for(sal_uInt32 a(0); a < nSize; a++)
     400                 :            :                 {
     401                 :          0 :                     const EEngineData::WrongSpellClass& rCandidate = (*rInfo.mpWrongSpellVector)[a];
     402                 :            : 
     403 [ #  # ][ #  # ]:          0 :                     if(rCandidate.nStart >= rInfo.mnTextStart && rCandidate.nEnd >= rInfo.mnTextStart && rCandidate.nEnd > rCandidate.nStart)
                 [ #  # ]
     404                 :            :                     {
     405                 :          0 :                         const sal_uInt32 nStart(rCandidate.nStart - rInfo.mnTextStart);
     406                 :          0 :                         const sal_uInt32 nEnd(rCandidate.nEnd - rInfo.mnTextStart);
     407                 :          0 :                         double fStart(0.0);
     408                 :          0 :                         double fEnd(0.0);
     409                 :            : 
     410 [ #  # ][ #  # ]:          0 :                         if(nStart > 0 && nStart - 1 < nDXCount)
     411                 :            :                         {
     412         [ #  # ]:          0 :                             fStart = aDXArray[nStart - 1];
     413                 :            :                         }
     414                 :            : 
     415 [ #  # ][ #  # ]:          0 :                         if(nEnd > 0 && nEnd - 1 < nDXCount)
     416                 :            :                         {
     417         [ #  # ]:          0 :                             fEnd = aDXArray[nEnd - 1];
     418                 :            :                         }
     419                 :            : 
     420         [ #  # ]:          0 :                         if(!basegfx::fTools::equal(fStart, fEnd))
     421                 :            :                         {
     422 [ #  # ][ #  # ]:          0 :                             if(rInfo.IsRTL())
     423                 :            :                             {
     424                 :            :                                 // #i98523#
     425                 :            :                                 // When the portion is RTL, mirror the redlining using the
     426                 :            :                                 // full portion width
     427         [ #  # ]:          0 :                                 const double fTextWidth(aDXArray[aDXArray.size() - 1]);
     428                 :            : 
     429                 :          0 :                                 fStart = fTextWidth - fStart;
     430                 :          0 :                                 fEnd = fTextWidth - fEnd;
     431                 :            :                             }
     432                 :            : 
     433                 :            :                             // need to take FontScaling out of values; it's already part of
     434                 :            :                             // aNewTransform and would be double applied
     435                 :          0 :                             const double fFontScaleX(aFontScaling.getX());
     436                 :            : 
     437 [ #  # ][ #  # ]:          0 :                             if(!basegfx::fTools::equal(fFontScaleX, 1.0)
           [ #  #  #  # ]
     438                 :          0 :                                 && !basegfx::fTools::equalZero(fFontScaleX))
     439                 :            :                             {
     440                 :          0 :                                 fStart /= fFontScaleX;
     441                 :          0 :                                 fEnd /= fFontScaleX;
     442                 :            :                             }
     443                 :            : 
     444                 :            :                             maTextPortionPrimitives.push_back(new drawinglayer::primitive2d::WrongSpellPrimitive2D(
     445                 :            :                                 aNewTransform,
     446                 :            :                                 fStart,
     447                 :            :                                 fEnd,
     448 [ #  # ][ #  # ]:          0 :                                 aSpellColor));
     449                 :            :                         }
     450                 :            :                     }
     451                 :          0 :                 }
     452 [ +  - ][ +  - ]:      17927 :             }
     453                 :            :         }
     454                 :      18454 :     }
     455                 :            : 
     456                 :        888 :     drawinglayer::primitive2d::BasePrimitive2D* impTextBreakupHandler::impCheckFieldPrimitive(drawinglayer::primitive2d::BasePrimitive2D* pPrimitive, const DrawPortionInfo& rInfo) const
     457                 :            :     {
     458         [ +  - ]:        888 :         if(rInfo.mpFieldData)
     459                 :            :         {
     460                 :            :             // Support for FIELD_SEQ_BEGIN, FIELD_SEQ_END. If used, create a TextHierarchyFieldPrimitive2D
     461                 :            :             // which holds the field type and, if applicable, the URL
     462         [ -  + ]:        888 :             const SvxURLField* pURLField = dynamic_cast< const SvxURLField* >(rInfo.mpFieldData);
     463         [ -  + ]:        888 :             const SvxPageField* pPageField = dynamic_cast< const SvxPageField* >(rInfo.mpFieldData);
     464                 :            : 
     465                 :            :             // embed current primitive to a sequence
     466         [ +  - ]:        888 :             drawinglayer::primitive2d::Primitive2DSequence aSequence;
     467                 :            : 
     468         [ +  - ]:        888 :             if(pPrimitive)
     469                 :            :             {
     470         [ +  - ]:        888 :                 aSequence.realloc(1);
     471 [ +  - ][ +  - ]:        888 :                 aSequence[0] = drawinglayer::primitive2d::Primitive2DReference(pPrimitive);
         [ +  - ][ +  - ]
     472                 :            :             }
     473                 :            : 
     474         [ -  + ]:        888 :             if(pURLField)
     475                 :            :             {
     476         [ #  # ]:          0 :                 pPrimitive = new drawinglayer::primitive2d::TextHierarchyFieldPrimitive2D(aSequence, drawinglayer::primitive2d::FIELD_TYPE_URL, pURLField->GetURL());
     477                 :            :             }
     478         [ +  + ]:        888 :             else if(pPageField)
     479                 :            :             {
     480 [ +  - ][ +  - ]:        178 :                 pPrimitive = new drawinglayer::primitive2d::TextHierarchyFieldPrimitive2D(aSequence, drawinglayer::primitive2d::FIELD_TYPE_PAGE, String());
         [ +  - ][ +  - ]
     481                 :            :             }
     482                 :            :             else
     483                 :            :             {
     484 [ +  - ][ +  - ]:        710 :                 pPrimitive = new drawinglayer::primitive2d::TextHierarchyFieldPrimitive2D(aSequence, drawinglayer::primitive2d::FIELD_TYPE_COMMON, String());
         [ +  - ][ +  - ]
     485         [ +  - ]:        888 :             }
     486                 :            :         }
     487                 :            : 
     488                 :        888 :         return pPrimitive;
     489                 :            :     }
     490                 :            : 
     491                 :      17953 :     void impTextBreakupHandler::impFlushTextPortionPrimitivesToLinePrimitives()
     492                 :            :     {
     493                 :            :         // only create a line primitive when we had content; there is no need for
     494                 :            :         // empty line primitives (contrary to paragraphs, see below).
     495         [ +  + ]:      17953 :         if(!maTextPortionPrimitives.empty())
     496                 :            :         {
     497         [ +  - ]:      17426 :             drawinglayer::primitive2d::Primitive2DSequence aLineSequence(impConvertVectorToPrimitive2DSequence(maTextPortionPrimitives));
     498                 :      17426 :             maTextPortionPrimitives.clear();
     499 [ +  - ][ +  - ]:      17426 :             maLinePrimitives.push_back(new drawinglayer::primitive2d::TextHierarchyLinePrimitive2D(aLineSequence));
                 [ +  - ]
     500                 :            :         }
     501                 :      17953 :     }
     502                 :            : 
     503                 :      15868 :     void impTextBreakupHandler::impFlushLinePrimitivesToParagraphPrimitives()
     504                 :            :     {
     505                 :            :         // ALWAYS create a paragraph primitive, even when no content was added. This is done to
     506                 :            :         // have the correct paragraph count even with empty paragraphs. Those paragraphs will
     507                 :            :         // have an empty sub-PrimitiveSequence.
     508         [ +  - ]:      15868 :         drawinglayer::primitive2d::Primitive2DSequence aParagraphSequence(impConvertVectorToPrimitive2DSequence(maLinePrimitives));
     509                 :      15868 :         maLinePrimitives.clear();
     510 [ +  - ][ +  - ]:      15868 :         maParagraphPrimitives.push_back(new drawinglayer::primitive2d::TextHierarchyParagraphPrimitive2D(aParagraphSequence));
                 [ +  - ]
     511                 :      15868 :     }
     512                 :            : 
     513                 :      18454 :     void impTextBreakupHandler::impHandleDrawPortionInfo(const DrawPortionInfo& rInfo)
     514                 :            :     {
     515                 :      18454 :         impCreateTextPortionPrimitive(rInfo);
     516                 :            : 
     517 [ -  + ][ +  + ]:      18454 :         if(rInfo.mbEndOfLine || rInfo.mbEndOfParagraph)
     518                 :            :         {
     519                 :      17953 :             impFlushTextPortionPrimitivesToLinePrimitives();
     520                 :            :         }
     521                 :            : 
     522         [ +  + ]:      18454 :         if(rInfo.mbEndOfParagraph)
     523                 :            :         {
     524                 :      15868 :             impFlushLinePrimitivesToParagraphPrimitives();
     525                 :            :         }
     526                 :      18454 :     }
     527                 :            : 
     528                 :          0 :     void impTextBreakupHandler::impHandleDrawBulletInfo(const DrawBulletInfo& rInfo)
     529                 :            :     {
     530         [ #  # ]:          0 :         basegfx::B2DHomMatrix aNewTransform;
     531                 :            : 
     532                 :            :         // add size to new transform
     533         [ #  # ]:          0 :         aNewTransform.scale(rInfo.maBulletSize.getWidth(), rInfo.maBulletSize.getHeight());
     534                 :            : 
     535                 :            :         // apply transformA
     536         [ #  # ]:          0 :         aNewTransform *= maNewTransformA;
     537                 :            : 
     538                 :            :         // apply local offset
     539         [ #  # ]:          0 :         aNewTransform.translate(rInfo.maBulletPosition.X(), rInfo.maBulletPosition.Y());
     540                 :            : 
     541                 :            :         // also apply embedding object's transform
     542         [ #  # ]:          0 :         aNewTransform *= maNewTransformB;
     543                 :            : 
     544                 :            :         // prepare empty GraphicAttr
     545         [ #  # ]:          0 :         const GraphicAttr aGraphicAttr;
     546                 :            : 
     547                 :            :         // create GraphicPrimitive2D
     548                 :            :         const drawinglayer::primitive2d::Primitive2DReference aNewReference(new drawinglayer::primitive2d::GraphicPrimitive2D(
     549                 :            :             aNewTransform,
     550                 :            :             rInfo.maBulletGraphicObject,
     551 [ #  # ][ #  # ]:          0 :             aGraphicAttr));
                 [ #  # ]
     552                 :            : 
     553                 :            :         // embed in TextHierarchyBulletPrimitive2D
     554         [ #  # ]:          0 :         const drawinglayer::primitive2d::Primitive2DSequence aNewSequence(&aNewReference, 1);
     555         [ #  # ]:          0 :         drawinglayer::primitive2d::BasePrimitive2D* pNewPrimitive = new drawinglayer::primitive2d::TextHierarchyBulletPrimitive2D(aNewSequence);
     556                 :            : 
     557                 :            :         // add to output
     558 [ #  # ][ #  # ]:          0 :         maTextPortionPrimitives.push_back(pNewPrimitive);
         [ #  # ][ #  # ]
     559                 :          0 :     }
     560                 :            : 
     561                 :          0 :     IMPL_LINK(impTextBreakupHandler, decomposeContourTextPrimitive, DrawPortionInfo*, pInfo)
     562                 :            :     {
     563                 :            :         // for contour text, ignore (clip away) all portions which are below
     564                 :            :         // the visible area given by maScale
     565 [ #  # ][ #  # ]:          0 :         if(pInfo && (double)pInfo->mrStartPos.Y() < maScale.getY())
                 [ #  # ]
     566                 :            :         {
     567                 :          0 :             impHandleDrawPortionInfo(*pInfo);
     568                 :            :         }
     569                 :            : 
     570                 :          0 :         return 0;
     571                 :            :     }
     572                 :            : 
     573                 :      18454 :     IMPL_LINK(impTextBreakupHandler, decomposeBlockTextPrimitive, DrawPortionInfo*, pInfo)
     574                 :            :     {
     575         [ +  - ]:      18454 :         if(pInfo)
     576                 :            :         {
     577                 :            :             // Is clipping wanted? This is text clipping; only accept a portion
     578                 :            :             // if it's completely in the range
     579         [ -  + ]:      18454 :             if(!maClipRange.isEmpty())
     580                 :            :             {
     581                 :            :                 // Test start position first; this allows to not get the text range at
     582                 :            :                 // all if text is far outside
     583                 :          0 :                 const basegfx::B2DPoint aStartPosition(pInfo->mrStartPos.X(), pInfo->mrStartPos.Y());
     584                 :            : 
     585 [ #  # ][ #  # ]:          0 :                 if(!maClipRange.isInside(aStartPosition))
     586                 :            :                 {
     587                 :          0 :                     return 0;
     588                 :            :                 }
     589                 :            : 
     590                 :            :                 // Start position is inside. Get TextBoundRect and TopLeft next
     591         [ #  # ]:          0 :                 drawinglayer::primitive2d::TextLayouterDevice aTextLayouterDevice;
     592         [ #  # ]:          0 :                 aTextLayouterDevice.setFont(pInfo->mrFont);
     593                 :            : 
     594                 :            :                 const basegfx::B2DRange aTextBoundRect(
     595                 :            :                     aTextLayouterDevice.getTextBoundRect(
     596         [ #  # ]:          0 :                         pInfo->mrText, pInfo->mnTextStart, pInfo->mnTextLen));
     597         [ #  # ]:          0 :                 const basegfx::B2DPoint aTopLeft(aTextBoundRect.getMinimum() + aStartPosition);
     598                 :            : 
     599 [ #  # ][ #  # ]:          0 :                 if(!maClipRange.isInside(aTopLeft))
     600                 :            :                 {
     601                 :          0 :                     return 0;
     602                 :            :                 }
     603                 :            : 
     604                 :            :                 // TopLeft is inside. Get BottomRight and check
     605         [ #  # ]:          0 :                 const basegfx::B2DPoint aBottomRight(aTextBoundRect.getMaximum() + aStartPosition);
     606                 :            : 
     607 [ #  # ][ #  # ]:          0 :                 if(!maClipRange.isInside(aBottomRight))
     608                 :            :                 {
     609                 :          0 :                     return 0;
     610 [ #  # ][ #  # ]:          0 :                 }
         [ #  # ][ #  # ]
                 [ #  # ]
     611                 :            : 
     612                 :            :                 // all inside, clip was successful
     613                 :            :             }
     614                 :      18454 :             impHandleDrawPortionInfo(*pInfo);
     615                 :            :         }
     616                 :            : 
     617                 :      18454 :         return 0;
     618                 :            :     }
     619                 :            : 
     620                 :          0 :     IMPL_LINK(impTextBreakupHandler, decomposeStretchTextPrimitive, DrawPortionInfo*, pInfo)
     621                 :            :     {
     622         [ #  # ]:          0 :         if(pInfo)
     623                 :            :         {
     624                 :          0 :             impHandleDrawPortionInfo(*pInfo);
     625                 :            :         }
     626                 :            : 
     627                 :          0 :         return 0;
     628                 :            :     }
     629                 :            : 
     630                 :          0 :     IMPL_LINK(impTextBreakupHandler, decomposeContourBulletPrimitive, DrawBulletInfo*, pInfo)
     631                 :            :     {
     632         [ #  # ]:          0 :         if(pInfo)
     633                 :            :         {
     634                 :          0 :             impHandleDrawBulletInfo(*pInfo);
     635                 :            :         }
     636                 :            : 
     637                 :          0 :         return 0;
     638                 :            :     }
     639                 :            : 
     640                 :          0 :     IMPL_LINK(impTextBreakupHandler, decomposeBlockBulletPrimitive, DrawBulletInfo*, pInfo)
     641                 :            :     {
     642         [ #  # ]:          0 :         if(pInfo)
     643                 :            :         {
     644                 :          0 :             impHandleDrawBulletInfo(*pInfo);
     645                 :            :         }
     646                 :            : 
     647                 :          0 :         return 0;
     648                 :            :     }
     649                 :            : 
     650                 :          0 :     IMPL_LINK(impTextBreakupHandler, decomposeStretchBulletPrimitive, DrawBulletInfo*, pInfo)
     651                 :            :     {
     652         [ #  # ]:          0 :         if(pInfo)
     653                 :            :         {
     654                 :          0 :             impHandleDrawBulletInfo(*pInfo);
     655                 :            :         }
     656                 :            : 
     657                 :          0 :         return 0;
     658                 :            :     }
     659                 :            : 
     660                 :      13696 :     drawinglayer::primitive2d::Primitive2DSequence impTextBreakupHandler::getPrimitive2DSequence()
     661                 :            :     {
     662         [ -  + ]:      13696 :         if(!maTextPortionPrimitives.empty())
     663                 :            :         {
     664                 :            :             // collect non-closed lines
     665                 :          0 :             impFlushTextPortionPrimitivesToLinePrimitives();
     666                 :            :         }
     667                 :            : 
     668         [ -  + ]:      13696 :         if(!maLinePrimitives.empty())
     669                 :            :         {
     670                 :            :             // collect non-closed paragraphs
     671                 :          0 :             impFlushLinePrimitivesToParagraphPrimitives();
     672                 :            :         }
     673                 :            : 
     674                 :      13696 :         return impConvertVectorToPrimitive2DSequence(maParagraphPrimitives);
     675                 :            :     }
     676                 :            : } // end of anonymous namespace
     677                 :            : 
     678                 :            : //////////////////////////////////////////////////////////////////////////////
     679                 :            : // primitive decompositions
     680                 :            : 
     681                 :          0 : void SdrTextObj::impDecomposeContourTextPrimitive(
     682                 :            :     drawinglayer::primitive2d::Primitive2DSequence& rTarget,
     683                 :            :     const drawinglayer::primitive2d::SdrContourTextPrimitive2D& rSdrContourTextPrimitive,
     684                 :            :     const drawinglayer::geometry::ViewInformation2D& aViewInformation) const
     685                 :            : {
     686                 :            :     // decompose matrix to have position and size of text
     687                 :          0 :     basegfx::B2DVector aScale, aTranslate;
     688                 :            :     double fRotate, fShearX;
     689         [ #  # ]:          0 :     rSdrContourTextPrimitive.getObjectTransform().decompose(aScale, aTranslate, fRotate, fShearX);
     690                 :            : 
     691                 :            :     // prepare contour polygon, force to non-mirrored for laying out
     692         [ #  # ]:          0 :     basegfx::B2DPolyPolygon aPolyPolygon(rSdrContourTextPrimitive.getUnitPolyPolygon());
     693 [ #  # ][ #  # ]:          0 :     aPolyPolygon.transform(basegfx::tools::createScaleB2DHomMatrix(fabs(aScale.getX()), fabs(aScale.getY())));
                 [ #  # ]
     694                 :            : 
     695                 :            :     // prepare outliner
     696         [ #  # ]:          0 :     SdrOutliner& rOutliner = ImpGetDrawOutliner();
     697                 :          0 :     const Size aNullSize;
     698         [ #  # ]:          0 :     rOutliner.SetPaperSize(aNullSize);
     699         [ #  # ]:          0 :     rOutliner.SetPolygon(aPolyPolygon);
     700         [ #  # ]:          0 :     rOutliner.SetUpdateMode(true);
     701         [ #  # ]:          0 :     rOutliner.SetText(rSdrContourTextPrimitive.getOutlinerParaObject());
     702                 :            : 
     703                 :            :     // set visualizing page at Outliner; needed e.g. for PageNumberField decomposition
     704         [ #  # ]:          0 :     rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage()));
     705                 :            : 
     706                 :            :     // prepare matrices to apply to newly created primitives
     707         [ #  # ]:          0 :     basegfx::B2DHomMatrix aNewTransformA;
     708                 :            : 
     709                 :            :     // mirroring. We are now in the polygon sizes. When mirroring in X and Y,
     710                 :            :     // move the null point which was top left to bottom right.
     711                 :          0 :     const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0));
     712                 :          0 :     const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0));
     713                 :            : 
     714                 :            :     // in-between the translations of the single primitives will take place. Afterwards,
     715                 :            :     // the object's transformations need to be applied
     716                 :            :     const basegfx::B2DHomMatrix aNewTransformB(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
     717                 :            :         bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0,
     718 [ #  # ][ #  # ]:          0 :         fShearX, fRotate, aTranslate.getX(), aTranslate.getY()));
                 [ #  # ]
     719                 :            : 
     720                 :            :     // now break up text primitives.
     721         [ #  # ]:          0 :     impTextBreakupHandler aConverter(rOutliner);
     722         [ #  # ]:          0 :     aConverter.decomposeContourTextPrimitive(aNewTransformA, aNewTransformB, aScale);
     723                 :            : 
     724                 :            :     // cleanup outliner
     725         [ #  # ]:          0 :     rOutliner.Clear();
     726                 :          0 :     rOutliner.setVisualizedPage(0);
     727                 :            : 
     728 [ #  # ][ #  # ]:          0 :     rTarget = aConverter.getPrimitive2DSequence();
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
                 [ #  # ]
     729                 :          0 : }
     730                 :            : 
     731                 :         31 : void SdrTextObj::impDecomposeAutoFitTextPrimitive(
     732                 :            :     drawinglayer::primitive2d::Primitive2DSequence& rTarget,
     733                 :            :     const drawinglayer::primitive2d::SdrAutoFitTextPrimitive2D& rSdrAutofitTextPrimitive,
     734                 :            :     const drawinglayer::geometry::ViewInformation2D& aViewInformation) const
     735                 :            : {
     736                 :            :     // decompose matrix to have position and size of text
     737                 :         31 :     basegfx::B2DVector aScale, aTranslate;
     738                 :            :     double fRotate, fShearX;
     739         [ +  - ]:         31 :     rSdrAutofitTextPrimitive.getTextRangeTransform().decompose(aScale, aTranslate, fRotate, fShearX);
     740                 :            : 
     741                 :            :     // use B2DRange aAnchorTextRange for calculations
     742         [ +  - ]:         31 :     basegfx::B2DRange aAnchorTextRange(aTranslate);
     743         [ +  - ]:         31 :     aAnchorTextRange.expand(aTranslate + aScale);
     744                 :            : 
     745                 :            :     // prepare outliner
     746 [ +  - ][ +  - ]:         31 :     const SfxItemSet& rTextItemSet = rSdrAutofitTextPrimitive.getSdrText()->GetItemSet();
     747         [ +  - ]:         31 :     SdrOutliner& rOutliner = ImpGetDrawOutliner();
     748         [ +  - ]:         31 :     SdrTextVertAdjust eVAdj = GetTextVerticalAdjust(rTextItemSet);
     749         [ +  - ]:         31 :     SdrTextHorzAdjust eHAdj = GetTextHorizontalAdjust(rTextItemSet);
     750         [ +  - ]:         31 :     const sal_uInt32 nOriginalControlWord(rOutliner.GetControlWord());
     751                 :         31 :     const Size aNullSize;
     752                 :            : 
     753                 :            :     // set visualizing page at Outliner; needed e.g. for PageNumberField decomposition
     754         [ +  - ]:         31 :     rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage()));
     755                 :            : 
     756         [ +  - ]:         31 :     rOutliner.SetControlWord(nOriginalControlWord|EE_CNTRL_AUTOPAGESIZE|EE_CNTRL_STRETCHING);
     757         [ +  - ]:         31 :     rOutliner.SetMinAutoPaperSize(aNullSize);
     758         [ +  - ]:         31 :     rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000));
     759                 :            : 
     760                 :            :     // add one to rage sizes to get back to the old Rectangle and outliner measurements
     761         [ +  - ]:         31 :     const sal_uInt32 nAnchorTextWidth(FRound(aAnchorTextRange.getWidth() + 1L));
     762         [ +  - ]:         31 :     const sal_uInt32 nAnchorTextHeight(FRound(aAnchorTextRange.getHeight() + 1L));
     763 [ +  - ][ +  - ]:         31 :     const OutlinerParaObject* pOutlinerParaObject = rSdrAutofitTextPrimitive.getSdrText()->GetOutlinerParaObject();
     764                 :            :     OSL_ENSURE(pOutlinerParaObject, "impDecomposeBlockTextPrimitive used with no OutlinerParaObject (!)");
     765         [ +  - ]:         31 :     const bool bVerticalWritintg(pOutlinerParaObject->IsVertical());
     766                 :         31 :     const Size aAnchorTextSize(Size(nAnchorTextWidth, nAnchorTextHeight));
     767                 :            : 
     768 [ +  - ][ +  - ]:         31 :     if((rSdrAutofitTextPrimitive.getWordWrap() || IsTextFrame()))
                 [ +  - ]
     769                 :            :     {
     770         [ +  - ]:         31 :         rOutliner.SetMaxAutoPaperSize(aAnchorTextSize);
     771                 :            :     }
     772                 :            : 
     773 [ +  - ][ +  - ]:         31 :     if(SDRTEXTHORZADJUST_BLOCK == eHAdj && !bVerticalWritintg)
     774                 :            :     {
     775         [ +  - ]:         31 :         rOutliner.SetMinAutoPaperSize(Size(nAnchorTextWidth, 0));
     776                 :            :     }
     777                 :            : 
     778 [ -  + ][ #  # ]:         31 :     if(SDRTEXTVERTADJUST_BLOCK == eVAdj && bVerticalWritintg)
     779                 :            :     {
     780         [ #  # ]:          0 :         rOutliner.SetMinAutoPaperSize(Size(0, nAnchorTextHeight));
     781                 :            :     }
     782                 :            : 
     783         [ +  - ]:         31 :     rOutliner.SetPaperSize(aNullSize);
     784         [ +  - ]:         31 :     rOutliner.SetUpdateMode(true);
     785         [ +  - ]:         31 :     rOutliner.SetText(*pOutlinerParaObject);
     786         [ +  - ]:         31 :     ImpAutoFitText(rOutliner,aAnchorTextSize,bVerticalWritintg);
     787                 :            : 
     788                 :            :     // set visualizing page at Outliner; needed e.g. for PageNumberField decomposition
     789         [ +  - ]:         31 :     rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage()));
     790                 :            : 
     791                 :            :     // now get back the layouted text size from outliner
     792         [ +  - ]:         31 :     const Size aOutlinerTextSiz(rOutliner.GetPaperSize());
     793                 :         31 :     const basegfx::B2DVector aOutlinerScale(aOutlinerTextSiz.Width(), aOutlinerTextSiz.Height());
     794                 :         31 :     basegfx::B2DVector aAdjustTranslate(0.0, 0.0);
     795                 :            : 
     796                 :            :     // correct horizontal translation using the now known text size
     797 [ -  + ][ +  - ]:         31 :     if(SDRTEXTHORZADJUST_CENTER == eHAdj || SDRTEXTHORZADJUST_RIGHT == eHAdj)
     798                 :            :     {
     799         [ #  # ]:          0 :         const double fFree(aAnchorTextRange.getWidth() - aOutlinerScale.getX());
     800                 :            : 
     801         [ #  # ]:          0 :         if(SDRTEXTHORZADJUST_CENTER == eHAdj)
     802                 :            :         {
     803                 :          0 :             aAdjustTranslate.setX(fFree / 2.0);
     804                 :            :         }
     805                 :            : 
     806         [ #  # ]:          0 :         if(SDRTEXTHORZADJUST_RIGHT == eHAdj)
     807                 :            :         {
     808                 :          0 :             aAdjustTranslate.setX(fFree);
     809                 :            :         }
     810                 :            :     }
     811                 :            : 
     812                 :            :     // correct vertical translation using the now known text size
     813 [ +  - ][ -  + ]:         31 :     if(SDRTEXTVERTADJUST_CENTER == eVAdj || SDRTEXTVERTADJUST_BOTTOM == eVAdj)
     814                 :            :     {
     815         [ #  # ]:          0 :         const double fFree(aAnchorTextRange.getHeight() - aOutlinerScale.getY());
     816                 :            : 
     817         [ #  # ]:          0 :         if(SDRTEXTVERTADJUST_CENTER == eVAdj)
     818                 :            :         {
     819                 :          0 :             aAdjustTranslate.setY(fFree / 2.0);
     820                 :            :         }
     821                 :            : 
     822         [ #  # ]:          0 :         if(SDRTEXTVERTADJUST_BOTTOM == eVAdj)
     823                 :            :         {
     824                 :          0 :             aAdjustTranslate.setY(fFree);
     825                 :            :         }
     826                 :            :     }
     827                 :            : 
     828                 :            :     // prepare matrices to apply to newly created primitives. aNewTransformA
     829                 :            :     // will get coordinates in aOutlinerScale size and positive in X, Y.
     830         [ +  - ]:         31 :     basegfx::B2DHomMatrix aNewTransformA;
     831         [ +  - ]:         31 :     basegfx::B2DHomMatrix aNewTransformB;
     832                 :            : 
     833                 :            :     // translate relative to given primitive to get same rotation and shear
     834                 :            :     // as the master shape we are working on. For vertical, use the top-right
     835                 :            :     // corner
     836         [ -  + ]:         31 :     const double fStartInX(bVerticalWritintg ? aAdjustTranslate.getX() + aOutlinerScale.getX() : aAdjustTranslate.getX());
     837         [ +  - ]:         31 :     aNewTransformA.translate(fStartInX, aAdjustTranslate.getY());
     838                 :            : 
     839                 :            :     // mirroring. We are now in aAnchorTextRange sizes. When mirroring in X and Y,
     840                 :            :     // move the null point which was top left to bottom right.
     841                 :         31 :     const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0));
     842                 :         31 :     const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0));
     843 [ -  + ][ +  - ]:         31 :     aNewTransformB.scale(bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0);
                 [ -  + ]
     844                 :            : 
     845                 :            :     // in-between the translations of the single primitives will take place. Afterwards,
     846                 :            :     // the object's transformations need to be applied
     847         [ +  - ]:         31 :     aNewTransformB.shearX(fShearX);
     848         [ +  - ]:         31 :     aNewTransformB.rotate(fRotate);
     849         [ +  - ]:         31 :     aNewTransformB.translate(aTranslate.getX(), aTranslate.getY());
     850                 :            : 
     851         [ +  - ]:         31 :     basegfx::B2DRange aClipRange;
     852                 :            : 
     853                 :            :     // now break up text primitives.
     854         [ +  - ]:         31 :     impTextBreakupHandler aConverter(rOutliner);
     855         [ +  - ]:         31 :     aConverter.decomposeBlockTextPrimitive(aNewTransformA, aNewTransformB, aClipRange);
     856                 :            : 
     857                 :            :     // cleanup outliner
     858         [ +  - ]:         31 :     rOutliner.Clear();
     859                 :         31 :     rOutliner.setVisualizedPage(0);
     860         [ +  - ]:         31 :     rOutliner.SetControlWord(nOriginalControlWord);
     861                 :            : 
     862 [ +  - ][ +  - ]:         31 :     rTarget = aConverter.getPrimitive2DSequence();
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
     863                 :         31 : }
     864                 :            : 
     865                 :      13665 : void SdrTextObj::impDecomposeBlockTextPrimitive(
     866                 :            :     drawinglayer::primitive2d::Primitive2DSequence& rTarget,
     867                 :            :     const drawinglayer::primitive2d::SdrBlockTextPrimitive2D& rSdrBlockTextPrimitive,
     868                 :            :     const drawinglayer::geometry::ViewInformation2D& aViewInformation) const
     869                 :            : {
     870                 :            :     // decompose matrix to have position and size of text
     871                 :      13665 :     basegfx::B2DVector aScale, aTranslate;
     872                 :            :     double fRotate, fShearX;
     873         [ +  - ]:      13665 :     rSdrBlockTextPrimitive.getTextRangeTransform().decompose(aScale, aTranslate, fRotate, fShearX);
     874                 :            : 
     875                 :            :     // use B2DRange aAnchorTextRange for calculations
     876         [ +  - ]:      13665 :     basegfx::B2DRange aAnchorTextRange(aTranslate);
     877         [ +  - ]:      13665 :     aAnchorTextRange.expand(aTranslate + aScale);
     878                 :            : 
     879                 :            :     // prepare outliner
     880                 :      13665 :     const bool bIsCell(rSdrBlockTextPrimitive.getCellText());
     881         [ +  - ]:      13665 :     SdrOutliner& rOutliner = ImpGetDrawOutliner();
     882                 :      13665 :     SdrTextHorzAdjust eHAdj = rSdrBlockTextPrimitive.getSdrTextHorzAdjust();
     883                 :      13665 :     SdrTextVertAdjust eVAdj = rSdrBlockTextPrimitive.getSdrTextVertAdjust();
     884         [ +  - ]:      13665 :     const sal_uInt32 nOriginalControlWord(rOutliner.GetControlWord());
     885                 :      13665 :     const Size aNullSize;
     886                 :            : 
     887                 :            :     // set visualizing page at Outliner; needed e.g. for PageNumberField decomposition
     888         [ +  - ]:      13665 :     rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage()));
     889         [ +  - ]:      13665 :     rOutliner.SetFixedCellHeight(rSdrBlockTextPrimitive.isFixedCellHeight());
     890         [ +  - ]:      13665 :     rOutliner.SetControlWord(nOriginalControlWord|EE_CNTRL_AUTOPAGESIZE);
     891         [ +  - ]:      13665 :     rOutliner.SetMinAutoPaperSize(aNullSize);
     892         [ +  - ]:      13665 :     rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000));
     893                 :            : 
     894                 :            :     // add one to rage sizes to get back to the old Rectangle and outliner measurements
     895         [ +  - ]:      13665 :     const sal_uInt32 nAnchorTextWidth(FRound(aAnchorTextRange.getWidth() + 1L));
     896         [ +  - ]:      13665 :     const sal_uInt32 nAnchorTextHeight(FRound(aAnchorTextRange.getHeight() + 1L));
     897         [ +  - ]:      13665 :     const bool bVerticalWritintg(rSdrBlockTextPrimitive.getOutlinerParaObject().IsVertical());
     898                 :      13665 :     const Size aAnchorTextSize(Size(nAnchorTextWidth, nAnchorTextHeight));
     899                 :            : 
     900         [ -  + ]:      13665 :     if(bIsCell)
     901                 :            :     {
     902                 :            :         // cell text is formated neither like a text object nor like a object
     903                 :            :         // text, so use a special setup here
     904         [ #  # ]:          0 :         rOutliner.SetMaxAutoPaperSize(aAnchorTextSize);
     905                 :            : 
     906                 :            :         // #i106214# To work with an unchangeable PaperSize (CellSize in
     907                 :            :         // this case) Set(Min|Max)AutoPaperSize and SetPaperSize have to be used.
     908                 :            :         // #i106214# This was not completely correct; to still measure the real
     909                 :            :         // text height to allow vertical adjust (and vice versa for VerticalWritintg)
     910                 :            :         // only one aspect has to be set, but the other one to zero
     911         [ #  # ]:          0 :         if(bVerticalWritintg)
     912                 :            :         {
     913                 :            :             // measure the horizontal text size
     914         [ #  # ]:          0 :             rOutliner.SetMinAutoPaperSize(Size(0, aAnchorTextSize.Height()));
     915                 :            :         }
     916                 :            :         else
     917                 :            :         {
     918                 :            :             // measure the vertical text size
     919         [ #  # ]:          0 :             rOutliner.SetMinAutoPaperSize(Size(aAnchorTextSize.Width(), 0));
     920                 :            :         }
     921                 :            : 
     922         [ #  # ]:          0 :         rOutliner.SetPaperSize(aAnchorTextSize);
     923         [ #  # ]:          0 :         rOutliner.SetUpdateMode(true);
     924         [ #  # ]:          0 :         rOutliner.SetText(rSdrBlockTextPrimitive.getOutlinerParaObject());
     925                 :            :     }
     926                 :            :     else
     927                 :            :     {
     928                 :            :         // check if block text is used (only one of them can be true)
     929 [ +  + ][ +  - ]:      13665 :         const bool bHorizontalIsBlock(SDRTEXTHORZADJUST_BLOCK == eHAdj && !bVerticalWritintg);
     930 [ -  + ][ #  # ]:      13665 :         const bool bVerticalIsBlock(SDRTEXTVERTADJUST_BLOCK == eVAdj && bVerticalWritintg);
     931                 :            : 
     932                 :            :         // set minimal paper size horizontally/vertically if needed
     933         [ +  + ]:      13665 :         if(bHorizontalIsBlock)
     934                 :            :         {
     935         [ +  - ]:       2250 :             rOutliner.SetMinAutoPaperSize(Size(nAnchorTextWidth, 0));
     936                 :            :         }
     937         [ -  + ]:      11415 :         else if(bVerticalIsBlock)
     938                 :            :         {
     939         [ #  # ]:          0 :             rOutliner.SetMinAutoPaperSize(Size(0, nAnchorTextHeight));
     940                 :            :         }
     941                 :            : 
     942 [ +  + ][ +  + ]:      13665 :         if((rSdrBlockTextPrimitive.getWordWrap() || IsTextFrame()) && !rSdrBlockTextPrimitive.getUnlimitedPage())
         [ +  - ][ +  + ]
     943                 :            :         {
     944                 :            :             // #i103454# maximal paper size hor/ver needs to be limited to text
     945                 :            :             // frame size. If it's block text, still allow the 'other' direction
     946                 :            :             // to grow to get a correct real text size when using GetPaperSize().
     947                 :            :             // When just using aAnchorTextSize as maximum, GetPaperSize()
     948                 :            :             // would just return aAnchorTextSize again: this means, the wanted
     949                 :            :             // 'measurement' of the real size of block text would not work
     950                 :      13657 :             Size aMaxAutoPaperSize(aAnchorTextSize);
     951                 :            : 
     952         [ +  + ]:      13657 :             if(bHorizontalIsBlock)
     953                 :            :             {
     954                 :            :                 // allow to grow vertical for horizontal blocks
     955                 :       2250 :                 aMaxAutoPaperSize.setHeight(1000000);
     956                 :            :             }
     957         [ -  + ]:      11407 :             else if(bVerticalIsBlock)
     958                 :            :             {
     959                 :            :                 // allow to grow horizontal for vertical blocks
     960                 :          0 :                 aMaxAutoPaperSize.setWidth(1000000);
     961                 :            :             }
     962                 :            : 
     963         [ +  - ]:      13657 :             rOutliner.SetMaxAutoPaperSize(aMaxAutoPaperSize);
     964                 :            :         }
     965                 :            : 
     966         [ +  - ]:      13665 :         rOutliner.SetPaperSize(aNullSize);
     967         [ +  - ]:      13665 :         rOutliner.SetUpdateMode(true);
     968         [ +  - ]:      13665 :         rOutliner.SetText(rSdrBlockTextPrimitive.getOutlinerParaObject());
     969                 :            :     }
     970                 :            : 
     971         [ +  - ]:      13665 :     rOutliner.SetControlWord(nOriginalControlWord);
     972                 :            : 
     973                 :            :     // now get back the layouted text size from outliner
     974         [ +  - ]:      13665 :     const Size aOutlinerTextSiz(rOutliner.GetPaperSize());
     975                 :      13665 :     const basegfx::B2DVector aOutlinerScale(aOutlinerTextSiz.Width(), aOutlinerTextSiz.Height());
     976                 :      13665 :     basegfx::B2DVector aAdjustTranslate(0.0, 0.0);
     977                 :            : 
     978                 :            :     // For draw objects containing text correct hor/ver alignment if text is bigger
     979                 :            :     // than the object itself. Without that correction, the text would always be
     980                 :            :     // formatted to the left edge (or top edge when vertical) of the draw object.
     981 [ +  - ][ +  + ]:      13665 :     if(!IsTextFrame() && !bIsCell)
                 [ +  + ]
     982                 :            :     {
     983 [ +  - ][ +  + ]:         26 :         if(aAnchorTextRange.getWidth() < aOutlinerScale.getX() && !bVerticalWritintg)
         [ +  - ][ +  + ]
     984                 :            :         {
     985                 :            :             // Horizontal case here. Correct only if eHAdj == SDRTEXTHORZADJUST_BLOCK,
     986                 :            :             // else the alignment is wanted.
     987         [ +  - ]:         18 :             if(SDRTEXTHORZADJUST_BLOCK == eHAdj)
     988                 :            :             {
     989                 :         18 :                 eHAdj = SDRTEXTHORZADJUST_CENTER;
     990                 :            :             }
     991                 :            :         }
     992                 :            : 
     993 [ +  - ][ -  + ]:         26 :         if(aAnchorTextRange.getHeight() < aOutlinerScale.getY() && bVerticalWritintg)
         [ #  # ][ -  + ]
     994                 :            :         {
     995                 :            :             // Vertical case here. Correct only if eHAdj == SDRTEXTVERTADJUST_BLOCK,
     996                 :            :             // else the alignment is wanted.
     997         [ #  # ]:          0 :             if(SDRTEXTVERTADJUST_BLOCK == eVAdj)
     998                 :            :             {
     999                 :          0 :                 eVAdj = SDRTEXTVERTADJUST_CENTER;
    1000                 :            :             }
    1001                 :            :         }
    1002                 :            :     }
    1003                 :            : 
    1004                 :            :     // correct horizontal translation using the now known text size
    1005 [ +  + ][ +  + ]:      13665 :     if(SDRTEXTHORZADJUST_CENTER == eHAdj || SDRTEXTHORZADJUST_RIGHT == eHAdj)
    1006                 :            :     {
    1007         [ +  - ]:       8854 :         const double fFree(aAnchorTextRange.getWidth() - aOutlinerScale.getX());
    1008                 :            : 
    1009         [ +  + ]:       8854 :         if(SDRTEXTHORZADJUST_CENTER == eHAdj)
    1010                 :            :         {
    1011                 :       5233 :             aAdjustTranslate.setX(fFree / 2.0);
    1012                 :            :         }
    1013                 :            : 
    1014         [ +  + ]:       8854 :         if(SDRTEXTHORZADJUST_RIGHT == eHAdj)
    1015                 :            :         {
    1016                 :       3621 :             aAdjustTranslate.setX(fFree);
    1017                 :            :         }
    1018                 :            :     }
    1019                 :            : 
    1020                 :            :     // correct vertical translation using the now known text size
    1021 [ +  + ][ +  + ]:      13665 :     if(SDRTEXTVERTADJUST_CENTER == eVAdj || SDRTEXTVERTADJUST_BOTTOM == eVAdj)
    1022                 :            :     {
    1023         [ +  - ]:       6467 :         const double fFree(aAnchorTextRange.getHeight() - aOutlinerScale.getY());
    1024                 :            : 
    1025         [ +  + ]:       6467 :         if(SDRTEXTVERTADJUST_CENTER == eVAdj)
    1026                 :            :         {
    1027                 :       4640 :             aAdjustTranslate.setY(fFree / 2.0);
    1028                 :            :         }
    1029                 :            : 
    1030         [ +  + ]:       6467 :         if(SDRTEXTVERTADJUST_BOTTOM == eVAdj)
    1031                 :            :         {
    1032                 :       1827 :             aAdjustTranslate.setY(fFree);
    1033                 :            :         }
    1034                 :            :     }
    1035                 :            : 
    1036                 :            :     // prepare matrices to apply to newly created primitives. aNewTransformA
    1037                 :            :     // will get coordinates in aOutlinerScale size and positive in X, Y.
    1038                 :            :     // Translate relative to given primitive to get same rotation and shear
    1039                 :            :     // as the master shape we are working on. For vertical, use the top-right
    1040                 :            :     // corner
    1041         [ -  + ]:      13665 :     const double fStartInX(bVerticalWritintg ? aAdjustTranslate.getX() + aOutlinerScale.getX() : aAdjustTranslate.getX());
    1042                 :      13665 :     const basegfx::B2DTuple aAdjOffset(fStartInX, aAdjustTranslate.getY());
    1043         [ +  - ]:      13665 :     basegfx::B2DHomMatrix aNewTransformA(basegfx::tools::createTranslateB2DHomMatrix(aAdjOffset.getX(), aAdjOffset.getY()));
    1044                 :            : 
    1045                 :            :     // mirroring. We are now in aAnchorTextRange sizes. When mirroring in X and Y,
    1046                 :            :     // move the null point which was top left to bottom right.
    1047                 :      13665 :     const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0));
    1048                 :      13665 :     const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0));
    1049                 :            : 
    1050                 :            :     // in-between the translations of the single primitives will take place. Afterwards,
    1051                 :            :     // the object's transformations need to be applied
    1052                 :            :     const basegfx::B2DHomMatrix aNewTransformB(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
    1053                 :            :         bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0,
    1054 [ -  + ][ +  - ]:      13665 :         fShearX, fRotate, aTranslate.getX(), aTranslate.getY()));
                 [ -  + ]
    1055                 :            : 
    1056                 :            :     // create ClipRange (if needed)
    1057         [ +  - ]:      13665 :     basegfx::B2DRange aClipRange;
    1058                 :            : 
    1059         [ -  + ]:      13665 :     if(rSdrBlockTextPrimitive.getClipOnBounds())
    1060                 :            :     {
    1061         [ #  # ]:          0 :         aClipRange.expand(-aAdjOffset);
    1062         [ #  # ]:          0 :         aClipRange.expand(basegfx::B2DTuple(aAnchorTextSize.Width(), aAnchorTextSize.Height()) - aAdjOffset);
    1063                 :            :     }
    1064                 :            : 
    1065                 :            :     // now break up text primitives.
    1066         [ +  - ]:      13665 :     impTextBreakupHandler aConverter(rOutliner);
    1067         [ +  - ]:      13665 :     aConverter.decomposeBlockTextPrimitive(aNewTransformA, aNewTransformB, aClipRange);
    1068                 :            : 
    1069                 :            :     // cleanup outliner
    1070         [ +  - ]:      13665 :     rOutliner.Clear();
    1071                 :      13665 :     rOutliner.setVisualizedPage(0);
    1072                 :            : 
    1073 [ +  - ][ +  - ]:      13665 :     rTarget = aConverter.getPrimitive2DSequence();
         [ +  - ][ +  - ]
         [ +  - ][ +  - ]
    1074                 :      13665 : }
    1075                 :            : 
    1076                 :          0 : void SdrTextObj::impDecomposeStretchTextPrimitive(
    1077                 :            :     drawinglayer::primitive2d::Primitive2DSequence& rTarget,
    1078                 :            :     const drawinglayer::primitive2d::SdrStretchTextPrimitive2D& rSdrStretchTextPrimitive,
    1079                 :            :     const drawinglayer::geometry::ViewInformation2D& aViewInformation) const
    1080                 :            : {
    1081                 :            :     // decompose matrix to have position and size of text
    1082                 :          0 :     basegfx::B2DVector aScale, aTranslate;
    1083                 :            :     double fRotate, fShearX;
    1084         [ #  # ]:          0 :     rSdrStretchTextPrimitive.getTextRangeTransform().decompose(aScale, aTranslate, fRotate, fShearX);
    1085                 :            : 
    1086                 :            :     // use non-mirrored B2DRange aAnchorTextRange for calculations
    1087         [ #  # ]:          0 :     basegfx::B2DRange aAnchorTextRange(aTranslate);
    1088         [ #  # ]:          0 :     aAnchorTextRange.expand(aTranslate + aScale);
    1089                 :            : 
    1090                 :            :     // prepare outliner
    1091         [ #  # ]:          0 :     SdrOutliner& rOutliner = ImpGetDrawOutliner();
    1092         [ #  # ]:          0 :     const sal_uInt32 nOriginalControlWord(rOutliner.GetControlWord());
    1093                 :          0 :     const Size aNullSize;
    1094                 :            : 
    1095         [ #  # ]:          0 :     rOutliner.SetControlWord(nOriginalControlWord|EE_CNTRL_STRETCHING|EE_CNTRL_AUTOPAGESIZE);
    1096         [ #  # ]:          0 :     rOutliner.SetFixedCellHeight(rSdrStretchTextPrimitive.isFixedCellHeight());
    1097         [ #  # ]:          0 :     rOutliner.SetMinAutoPaperSize(aNullSize);
    1098         [ #  # ]:          0 :     rOutliner.SetMaxAutoPaperSize(Size(1000000,1000000));
    1099         [ #  # ]:          0 :     rOutliner.SetPaperSize(aNullSize);
    1100         [ #  # ]:          0 :     rOutliner.SetUpdateMode(true);
    1101         [ #  # ]:          0 :     rOutliner.SetText(rSdrStretchTextPrimitive.getOutlinerParaObject());
    1102                 :            : 
    1103                 :            :     // set visualizing page at Outliner; needed e.g. for PageNumberField decomposition
    1104         [ #  # ]:          0 :     rOutliner.setVisualizedPage(GetSdrPageFromXDrawPage(aViewInformation.getVisualizedPage()));
    1105                 :            : 
    1106                 :            :     // now get back the laid out text size from outliner
    1107         [ #  # ]:          0 :     const Size aOutlinerTextSiz(rOutliner.CalcTextSize());
    1108                 :            :     const basegfx::B2DVector aOutlinerScale(
    1109                 :          0 :         basegfx::fTools::equalZero(aOutlinerTextSiz.Width()) ? 1.0 : aOutlinerTextSiz.Width(),
    1110 [ #  # ][ #  # ]:          0 :         basegfx::fTools::equalZero(aOutlinerTextSiz.Height()) ? 1.0 : aOutlinerTextSiz.Height());
    1111                 :            : 
    1112                 :            :     // prepare matrices to apply to newly created primitives
    1113         [ #  # ]:          0 :     basegfx::B2DHomMatrix aNewTransformA;
    1114                 :            : 
    1115                 :            :     // #i101957# Check for vertical text. If used, aNewTransformA
    1116                 :            :     // needs to translate the text initially around object width to orient
    1117                 :            :     // it relative to the topper right instead of the topper left
    1118         [ #  # ]:          0 :     const bool bVertical(rSdrStretchTextPrimitive.getOutlinerParaObject().IsVertical());
    1119                 :            : 
    1120         [ #  # ]:          0 :     if(bVertical)
    1121                 :            :     {
    1122         [ #  # ]:          0 :         aNewTransformA.translate(aScale.getX(), 0.0);
    1123                 :            :     }
    1124                 :            : 
    1125                 :            :     // calculate global char stretching scale parameters. Use non-mirrored sizes
    1126                 :            :     // to layout without mirroring
    1127                 :          0 :     const double fScaleX(fabs(aScale.getX()) / aOutlinerScale.getX());
    1128                 :          0 :     const double fScaleY(fabs(aScale.getY()) / aOutlinerScale.getY());
    1129         [ #  # ]:          0 :     rOutliner.SetGlobalCharStretching((sal_Int16)FRound(fScaleX * 100.0), (sal_Int16)FRound(fScaleY * 100.0));
    1130                 :            : 
    1131                 :            :     // mirroring. We are now in aAnchorTextRange sizes. When mirroring in X and Y,
    1132                 :            :     // move the null point which was top left to bottom right.
    1133                 :          0 :     const bool bMirrorX(basegfx::fTools::less(aScale.getX(), 0.0));
    1134                 :          0 :     const bool bMirrorY(basegfx::fTools::less(aScale.getY(), 0.0));
    1135                 :            : 
    1136                 :            :     // in-between the translations of the single primitives will take place. Afterwards,
    1137                 :            :     // the object's transformations need to be applied
    1138                 :            :     const basegfx::B2DHomMatrix aNewTransformB(basegfx::tools::createScaleShearXRotateTranslateB2DHomMatrix(
    1139                 :            :         bMirrorX ? -1.0 : 1.0, bMirrorY ? -1.0 : 1.0,
    1140 [ #  # ][ #  # ]:          0 :         fShearX, fRotate, aTranslate.getX(), aTranslate.getY()));
                 [ #  # ]
    1141                 :            : 
    1142                 :            :     // now break up text primitives.
    1143         [ #  # ]:          0 :     impTextBreakupHandler aConverter(rOutliner);
    1144         [ #  # ]:          0 :     aConverter.decomposeStretchTextPrimitive(aNewTransformA, aNewTransformB);
    1145                 :            : 
    1146                 :            :     // cleanup outliner
    1147         [ #  # ]:          0 :     rOutliner.SetControlWord(nOriginalControlWord);
    1148         [ #  # ]:          0 :     rOutliner.Clear();
    1149                 :          0 :     rOutliner.setVisualizedPage(0);
    1150                 :            : 
    1151 [ #  # ][ #  # ]:          0 :     rTarget = aConverter.getPrimitive2DSequence();
         [ #  # ][ #  # ]
         [ #  # ][ #  # ]
    1152                 :          0 : }
    1153                 :            : 
    1154                 :            : //////////////////////////////////////////////////////////////////////////////
    1155                 :            : // timing generators
    1156                 :            : #define ENDLESS_LOOP    (0xffffffff)
    1157                 :            : #define ENDLESS_TIME    ((double)0xffffffff)
    1158                 :            : #define PIXEL_DPI       (96.0)
    1159                 :            : 
    1160                 :          0 : void SdrTextObj::impGetBlinkTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList) const
    1161                 :            : {
    1162         [ #  # ]:          0 :     if(SDRTEXTANI_BLINK == GetTextAniKind())
    1163                 :            :     {
    1164                 :            :         // get values
    1165         [ #  # ]:          0 :         const SfxItemSet& rSet = GetObjectItemSet();
    1166         [ #  # ]:          0 :         const sal_uInt32 nRepeat((sal_uInt32)((SdrTextAniCountItem&)rSet.Get(SDRATTR_TEXT_ANICOUNT)).GetValue());
    1167         [ #  # ]:          0 :         bool bVisisbleWhenStopped(((SdrTextAniStopInsideItem&)rSet.Get(SDRATTR_TEXT_ANISTOPINSIDE)).GetValue());
    1168         [ #  # ]:          0 :         double fDelay((double)((SdrTextAniDelayItem&)rSet.Get(SDRATTR_TEXT_ANIDELAY)).GetValue());
    1169                 :            : 
    1170         [ #  # ]:          0 :         if(0.0 == fDelay)
    1171                 :            :         {
    1172                 :            :             // use default
    1173                 :          0 :             fDelay = 250.0;
    1174                 :            :         }
    1175                 :            : 
    1176                 :            :         // prepare loop and add
    1177 [ #  # ][ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLoop  aLoop(nRepeat ? nRepeat : ENDLESS_LOOP);
    1178         [ #  # ]:          0 :         drawinglayer::animation::AnimationEntryFixed aStart(fDelay, 0.0);
    1179         [ #  # ]:          0 :         aLoop.append(aStart);
    1180         [ #  # ]:          0 :         drawinglayer::animation::AnimationEntryFixed aEnd(fDelay, 1.0);
    1181         [ #  # ]:          0 :         aLoop.append(aEnd);
    1182         [ #  # ]:          0 :         rAnimList.append(aLoop);
    1183                 :            : 
    1184                 :            :         // add stopped state if loop is not endless
    1185         [ #  # ]:          0 :         if(0L != nRepeat)
    1186                 :            :         {
    1187 [ #  # ][ #  # ]:          0 :             drawinglayer::animation::AnimationEntryFixed aStop(ENDLESS_TIME, bVisisbleWhenStopped ? 0.0 : 1.0);
    1188 [ #  # ][ #  # ]:          0 :             rAnimList.append(aStop);
    1189 [ #  # ][ #  # ]:          0 :         }
                 [ #  # ]
    1190                 :            :     }
    1191                 :          0 : }
    1192                 :            : 
    1193                 :          0 : void impCreateScrollTiming(const SfxItemSet& rSet, drawinglayer::animation::AnimationEntryList& rAnimList, bool bForward, double fTimeFullPath, double fFrequency)
    1194                 :            : {
    1195                 :          0 :     bool bVisisbleWhenStopped(((SdrTextAniStopInsideItem&)rSet.Get(SDRATTR_TEXT_ANISTOPINSIDE)).GetValue());
    1196                 :          0 :     bool bVisisbleWhenStarted(((SdrTextAniStartInsideItem&)rSet.Get(SDRATTR_TEXT_ANISTOPINSIDE )).GetValue());
    1197                 :          0 :     const sal_uInt32 nRepeat(((SdrTextAniCountItem&)rSet.Get(SDRATTR_TEXT_ANICOUNT)).GetValue());
    1198                 :            : 
    1199         [ #  # ]:          0 :     if(bVisisbleWhenStarted)
    1200                 :            :     {
    1201                 :            :         // move from center to outside
    1202 [ #  # ][ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLinear aInOut(fTimeFullPath * 0.5, fFrequency, 0.5, bForward ? 1.0 : 0.0);
    1203 [ #  # ][ #  # ]:          0 :         rAnimList.append(aInOut);
    1204                 :            :     }
    1205                 :            : 
    1206                 :            :     // loop. In loop, move through
    1207 [ #  # ][ #  # ]:          0 :     if(nRepeat || 0L == nRepeat)
    1208                 :            :     {
    1209 [ #  # ][ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLoop aLoop(nRepeat ? nRepeat : ENDLESS_LOOP);
    1210 [ #  # ][ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLinear aThrough(fTimeFullPath, fFrequency, bForward ? 0.0 : 1.0, bForward ? 1.0 : 0.0);
                 [ #  # ]
    1211         [ #  # ]:          0 :         aLoop.append(aThrough);
    1212 [ #  # ][ #  # ]:          0 :         rAnimList.append(aLoop);
                 [ #  # ]
    1213                 :            :     }
    1214                 :            : 
    1215 [ #  # ][ #  # ]:          0 :     if(0L != nRepeat && bVisisbleWhenStopped)
    1216                 :            :     {
    1217                 :            :         // move from outside to center
    1218 [ #  # ][ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLinear aOutIn(fTimeFullPath * 0.5, fFrequency, bForward ? 0.0 : 1.0, 0.5);
    1219         [ #  # ]:          0 :         rAnimList.append(aOutIn);
    1220                 :            : 
    1221                 :            :         // add timing for staying at the end
    1222         [ #  # ]:          0 :         drawinglayer::animation::AnimationEntryFixed aEnd(ENDLESS_TIME, 0.5);
    1223 [ #  # ][ #  # ]:          0 :         rAnimList.append(aEnd);
                 [ #  # ]
    1224                 :            :     }
    1225                 :          0 : }
    1226                 :            : 
    1227                 :          0 : void impCreateAlternateTiming(const SfxItemSet& rSet, drawinglayer::animation::AnimationEntryList& rAnimList, double fRelativeTextLength, bool bForward, double fTimeFullPath, double fFrequency)
    1228                 :            : {
    1229         [ #  # ]:          0 :     if(basegfx::fTools::more(fRelativeTextLength, 0.5))
    1230                 :            :     {
    1231                 :            :         // this is the case when fTextLength > fFrameLength, text is bigger than animation frame.
    1232                 :            :         // In that case, correct direction
    1233                 :          0 :         bForward = !bForward;
    1234                 :            :     }
    1235                 :            : 
    1236         [ #  # ]:          0 :     const double fStartPosition(bForward ? fRelativeTextLength : 1.0 - fRelativeTextLength);
    1237         [ #  # ]:          0 :     const double fEndPosition(bForward ? 1.0 - fRelativeTextLength : fRelativeTextLength);
    1238                 :          0 :     bool bVisisbleWhenStopped(((SdrTextAniStopInsideItem&)rSet.Get(SDRATTR_TEXT_ANISTOPINSIDE)).GetValue());
    1239                 :          0 :     bool bVisisbleWhenStarted(((SdrTextAniStartInsideItem&)rSet.Get(SDRATTR_TEXT_ANISTOPINSIDE )).GetValue());
    1240                 :          0 :     const sal_uInt32 nRepeat(((SdrTextAniCountItem&)rSet.Get(SDRATTR_TEXT_ANICOUNT)).GetValue());
    1241                 :            : 
    1242         [ #  # ]:          0 :     if(!bVisisbleWhenStarted)
    1243                 :            :     {
    1244                 :            :         // move from outside to center
    1245 [ #  # ][ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLinear aOutIn(fTimeFullPath * 0.5, fFrequency, bForward ? 0.0 : 1.0, 0.5);
    1246 [ #  # ][ #  # ]:          0 :         rAnimList.append(aOutIn);
    1247                 :            :     }
    1248                 :            : 
    1249                 :            :     // loop. In loop, move out and in again. fInnerMovePath may be negative when text is bigger then frame,
    1250                 :            :     // so use absolute value
    1251                 :          0 :     const double fInnerMovePath(fabs(1.0 - (fRelativeTextLength * 2.0)));
    1252                 :          0 :     const double fTimeForInnerPath(fTimeFullPath * fInnerMovePath);
    1253                 :          0 :     const double fHalfInnerPath(fTimeForInnerPath * 0.5);
    1254                 :          0 :     const sal_uInt32 nDoubleRepeat(nRepeat / 2L);
    1255                 :            : 
    1256 [ #  # ][ #  # ]:          0 :     if(nDoubleRepeat || 0L == nRepeat)
    1257                 :            :     {
    1258                 :            :         // double forth and back loop
    1259 [ #  # ][ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLoop aLoop(nDoubleRepeat ? nDoubleRepeat : ENDLESS_LOOP);
    1260         [ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLinear aTime0(fHalfInnerPath, fFrequency, 0.5, fEndPosition);
    1261         [ #  # ]:          0 :         aLoop.append(aTime0);
    1262         [ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLinear aTime1(fTimeForInnerPath, fFrequency, fEndPosition, fStartPosition);
    1263         [ #  # ]:          0 :         aLoop.append(aTime1);
    1264         [ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLinear aTime2(fHalfInnerPath, fFrequency, fStartPosition, 0.5);
    1265         [ #  # ]:          0 :         aLoop.append(aTime2);
    1266 [ #  # ][ #  # ]:          0 :         rAnimList.append(aLoop);
         [ #  # ][ #  # ]
                 [ #  # ]
    1267                 :            :     }
    1268                 :            : 
    1269         [ #  # ]:          0 :     if(nRepeat % 2L)
    1270                 :            :     {
    1271                 :            :         // repeat is uneven, so we need one more forth and back to center
    1272         [ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLinear aTime0(fHalfInnerPath, fFrequency, 0.5, fEndPosition);
    1273         [ #  # ]:          0 :         rAnimList.append(aTime0);
    1274         [ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLinear aTime1(fHalfInnerPath, fFrequency, fEndPosition, 0.5);
    1275 [ #  # ][ #  # ]:          0 :         rAnimList.append(aTime1);
                 [ #  # ]
    1276                 :            :     }
    1277                 :            : 
    1278         [ #  # ]:          0 :     if(0L != nRepeat)
    1279                 :            :     {
    1280         [ #  # ]:          0 :         if(bVisisbleWhenStopped)
    1281                 :            :         {
    1282                 :            :             // add timing for staying at the end
    1283         [ #  # ]:          0 :             drawinglayer::animation::AnimationEntryFixed aEnd(ENDLESS_TIME, 0.5);
    1284 [ #  # ][ #  # ]:          0 :             rAnimList.append(aEnd);
    1285                 :            :         }
    1286                 :            :         else
    1287                 :            :         {
    1288                 :            :             // move from center to outside
    1289 [ #  # ][ #  # ]:          0 :             drawinglayer::animation::AnimationEntryLinear aInOut(fTimeFullPath * 0.5, fFrequency, 0.5, bForward ? 1.0 : 0.0);
    1290 [ #  # ][ #  # ]:          0 :             rAnimList.append(aInOut);
    1291                 :            :         }
    1292                 :            :     }
    1293                 :          0 : }
    1294                 :            : 
    1295                 :          0 : void impCreateSlideTiming(const SfxItemSet& rSet, drawinglayer::animation::AnimationEntryList& rAnimList, bool bForward, double fTimeFullPath, double fFrequency)
    1296                 :            : {
    1297                 :            :     // move in from outside, start outside
    1298         [ #  # ]:          0 :     const double fStartPosition(bForward ? 0.0 : 1.0);
    1299         [ #  # ]:          0 :     const sal_uInt32 nRepeat(((SdrTextAniCountItem&)rSet.Get(SDRATTR_TEXT_ANICOUNT)).GetValue());
    1300                 :            : 
    1301                 :            :     // move from outside to center
    1302         [ #  # ]:          0 :     drawinglayer::animation::AnimationEntryLinear aOutIn(fTimeFullPath * 0.5, fFrequency, fStartPosition, 0.5);
    1303         [ #  # ]:          0 :     rAnimList.append(aOutIn);
    1304                 :            : 
    1305                 :            :     // loop. In loop, move out and in again
    1306 [ #  # ][ #  # ]:          0 :     if(nRepeat > 1L || 0L == nRepeat)
    1307                 :            :     {
    1308 [ #  # ][ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLoop aLoop(nRepeat ? nRepeat - 1L : ENDLESS_LOOP);
    1309         [ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLinear aTime0(fTimeFullPath * 0.5, fFrequency, 0.5, fStartPosition);
    1310         [ #  # ]:          0 :         aLoop.append(aTime0);
    1311         [ #  # ]:          0 :         drawinglayer::animation::AnimationEntryLinear aTime1(fTimeFullPath * 0.5, fFrequency, fStartPosition, 0.5);
    1312         [ #  # ]:          0 :         aLoop.append(aTime1);
    1313 [ #  # ][ #  # ]:          0 :         rAnimList.append(aLoop);
         [ #  # ][ #  # ]
    1314                 :            :     }
    1315                 :            : 
    1316                 :            :     // always visible when stopped, so add timing for staying at the end when not endless
    1317         [ #  # ]:          0 :     if(0L != nRepeat)
    1318                 :            :     {
    1319         [ #  # ]:          0 :         drawinglayer::animation::AnimationEntryFixed aEnd(ENDLESS_TIME, 0.5);
    1320 [ #  # ][ #  # ]:          0 :         rAnimList.append(aEnd);
    1321         [ #  # ]:          0 :     }
    1322                 :          0 : }
    1323                 :            : 
    1324                 :          0 : void SdrTextObj::impGetScrollTextTiming(drawinglayer::animation::AnimationEntryList& rAnimList, double fFrameLength, double fTextLength) const
    1325                 :            : {
    1326                 :          0 :     const SdrTextAniKind eAniKind(GetTextAniKind());
    1327                 :            : 
    1328 [ #  # ][ #  # ]:          0 :     if(SDRTEXTANI_SCROLL == eAniKind || SDRTEXTANI_ALTERNATE == eAniKind || SDRTEXTANI_SLIDE == eAniKind)
                 [ #  # ]
    1329                 :            :     {
    1330                 :            :         // get data. Goal is to calculate fTimeFullPath which is the time needed to
    1331                 :            :         // move animation from (0.0) to (1.0) state
    1332         [ #  # ]:          0 :         const SfxItemSet& rSet = GetObjectItemSet();
    1333         [ #  # ]:          0 :         double fAnimationDelay((double)((SdrTextAniDelayItem&)rSet.Get(SDRATTR_TEXT_ANIDELAY)).GetValue());
    1334         [ #  # ]:          0 :         double fSingleStepWidth((double)((SdrTextAniAmountItem&)rSet.Get(SDRATTR_TEXT_ANIAMOUNT)).GetValue());
    1335         [ #  # ]:          0 :         const SdrTextAniDirection eDirection(GetTextAniDirection());
    1336 [ #  # ][ #  # ]:          0 :         const bool bForward(SDRTEXTANI_RIGHT == eDirection || SDRTEXTANI_DOWN == eDirection);
    1337                 :            : 
    1338         [ #  # ]:          0 :         if(basegfx::fTools::equalZero(fAnimationDelay))
    1339                 :            :         {
    1340                 :            :             // default to 1/20 second
    1341                 :          0 :             fAnimationDelay = 50.0;
    1342                 :            :         }
    1343                 :            : 
    1344         [ #  # ]:          0 :         if(basegfx::fTools::less(fSingleStepWidth, 0.0))
    1345                 :            :         {
    1346                 :            :             // data is in pixels, convert to logic. Imply PIXEL_DPI dpi.
    1347                 :            :             // It makes no sense to keep the view-transformation centered
    1348                 :            :             // definitions, so get rid of them here.
    1349                 :          0 :             fSingleStepWidth = (-fSingleStepWidth * (2540.0 / PIXEL_DPI));
    1350                 :            :         }
    1351                 :            : 
    1352         [ #  # ]:          0 :         if(basegfx::fTools::equalZero(fSingleStepWidth))
    1353                 :            :         {
    1354                 :            :             // default to 1 millimeter
    1355                 :          0 :             fSingleStepWidth = 100.0;
    1356                 :            :         }
    1357                 :            : 
    1358                 :            :         // use the length of the full animation path and the number of steps
    1359                 :            :         // to get the full path time
    1360                 :          0 :         const double fFullPathLength(fFrameLength + fTextLength);
    1361                 :          0 :         const double fNumberOfSteps(fFullPathLength / fSingleStepWidth);
    1362                 :          0 :         double fTimeFullPath(fNumberOfSteps * fAnimationDelay);
    1363                 :            : 
    1364         [ #  # ]:          0 :         if(fTimeFullPath < fAnimationDelay)
    1365                 :            :         {
    1366                 :          0 :             fTimeFullPath = fAnimationDelay;
    1367                 :            :         }
    1368                 :            : 
    1369   [ #  #  #  # ]:          0 :         switch(eAniKind)
    1370                 :            :         {
    1371                 :            :             case SDRTEXTANI_SCROLL :
    1372                 :            :             {
    1373         [ #  # ]:          0 :                 impCreateScrollTiming(rSet, rAnimList, bForward, fTimeFullPath, fAnimationDelay);
    1374                 :          0 :                 break;
    1375                 :            :             }
    1376                 :            :             case SDRTEXTANI_ALTERNATE :
    1377                 :            :             {
    1378                 :          0 :                 double fRelativeTextLength(fTextLength / (fFrameLength + fTextLength));
    1379         [ #  # ]:          0 :                 impCreateAlternateTiming(rSet, rAnimList, fRelativeTextLength, bForward, fTimeFullPath, fAnimationDelay);
    1380                 :          0 :                 break;
    1381                 :            :             }
    1382                 :            :             case SDRTEXTANI_SLIDE :
    1383                 :            :             {
    1384         [ #  # ]:          0 :                 impCreateSlideTiming(rSet, rAnimList, bForward, fTimeFullPath, fAnimationDelay);
    1385                 :          0 :                 break;
    1386                 :            :             }
    1387                 :          0 :             default : break; // SDRTEXTANI_NONE, SDRTEXTANI_BLINK
    1388                 :            :         }
    1389                 :            :     }
    1390                 :          0 : }
    1391                 :            : 
    1392                 :            : 
    1393                 :            : /* vim:set shiftwidth=4 softtabstop=4 expandtab: */

Generated by: LCOV version 1.10