[Libreoffice-commits] core.git: Branch 'private/mst/sw_redlinehide' - 96 commits - sw/source

Michael Stahl Michael.Stahl at cib.de
Thu May 24 16:45:56 UTC 2018


Rebased ref, commits from common ancestor:
commit 1ab9ebdad6245b9627445c7123309e3b70cbe17c
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 18:40:28 2018 +0200

    sw_redlinehide: what to do about SwParaPortion::GetDelta()
    
    This has type "long", which is unusal.  Presumably because it needed to
    represent numbers from -USHRT_MAX to +USHRT_MAX back in the day.
    
    Now we have sal_Int32 which happens to be signed and TextFrameIndex,
    but these are always positive currently; would it be too confusing
    to have a potentially negative TextFrameIndex here?
    
    Change-Id: I18c4893d9d24b59e98e9a3994139842ea25ae716

diff --git a/sw/source/core/text/frmform.cxx b/sw/source/core/text/frmform.cxx
index 40ed097b1200..176914b69040 100644
--- a/sw/source/core/text/frmform.cxx
+++ b/sw/source/core/text/frmform.cxx
@@ -779,7 +779,7 @@ void SwTextFrame::SetOfst_(TextFrameIndex const nNewOfst)
         SwCharRange &rReformat = pPara->GetReformat();
         rReformat.Start() = TextFrameIndex(0);
         rReformat.Len() = TextFrameIndex(GetText().getLength());
-        pPara->GetDelta() = rReformat.Len();
+        pPara->GetDelta() = sal_Int32(rReformat.Len());
     }
     InvalidateSize();
 }
@@ -1281,7 +1281,7 @@ bool SwTextFrame::FormatLine( SwTextFormatter &rLine, const bool bPrev )
     }
 
     // Calculating the good ol' nDelta
-    pPara->GetDelta() -= long(pNew->GetLen()) - long(nOldLen);
+    pPara->GetDelta() -= sal_Int32(pNew->GetLen()) - sal_Int32(nOldLen);
 
     // Stop!
     if( rLine.IsStop() )
commit 1c4b207e27cacc2c106b424f93142a82d43dc588
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 18:02:40 2018 +0200

    sw_redlinehide: add SwTextFrame::GetLangOfChar()
    
    The text formatting calls SwTextNode::GetLang(), which is a bit of a
    problem now, but fortunately it calls it only for 0 or 1 character,
    and in that case we can easily indirect this to a single call to
    SwTextNode::Lang() in the right node.
    
    Change-Id: Id151cd6ae277bd2880fc8fc63305110ec2bf88c2

diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index 11bfdab230fe..e7c51f082efc 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -506,6 +506,9 @@ public:
 
     TextFrameIndex GetDropLen(TextFrameIndex nWishLen) const;
 
+    LanguageType GetLangOfChar(TextFrameIndex nIndex, sal_uInt16 nScript,
+            bool bNoChar = false) const;
+
     virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ) override;
     virtual void CheckDirection( bool bVert ) override;
 
diff --git a/sw/source/core/text/guess.cxx b/sw/source/core/text/guess.cxx
index a629a62c2583..9bcb7bd33fe3 100644
--- a/sw/source/core/text/guess.cxx
+++ b/sw/source/core/text/guess.cxx
@@ -369,10 +369,13 @@ bool SwTextGuess::Guess( const SwTextPortion& rPor, SwTextFormatInfo &rInf,
 
                 // compare current script with script from last "real" character
                 if ( SwFontScript(nScript - 1) != rInf.GetFont()->GetActual() )
-                    aLang = rInf.GetTextFrame()->GetTextNode()->GetLang(
-                        CH_TXTATR_BREAKWORD == cFieldChr ?
-                        nDoNotStepOver :
-                        nLangIndex, 0, nScript );
+                {
+                    aLang = rInf.GetTextFrame()->GetLangOfChar(
+                        CH_TXTATR_BREAKWORD == cFieldChr
+                            ? nDoNotStepOver
+                            : nLangIndex,
+                        nScript, true);
+                }
             }
         }
 
diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
index 186261fda6ff..d4978aa72c73 100644
--- a/sw/source/core/text/itrcrsr.cxx
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -249,7 +249,7 @@ void SwTextMargin::CtorInitTextMargin( SwTextFrame *pNewFrame, SwTextSizeInfo *p
             rSpace.IsAutoFirst() )
         {
             nFirstLineOfs = GetFnt()->GetSize( GetFnt()->GetActual() ).Height();
-            LanguageType aLang = m_pFrame->GetTextNode()->GetLang( 0, 1, css::i18n::ScriptType::ASIAN);
+            LanguageType const aLang = m_pFrame->GetLangOfChar(0, css::i18n::ScriptType::ASIAN);
             if (aLang != LANGUAGE_KOREAN && aLang != LANGUAGE_JAPANESE)
                 nFirstLineOfs<<=1;
 
diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx
index 703591b7feed..8256d458357e 100644
--- a/sw/source/core/text/portxt.cxx
+++ b/sw/source/core/text/portxt.cxx
@@ -92,7 +92,7 @@ static TextFrameIndex lcl_AddSpace(const SwTextSizeInfo &rInf,
     if ( nEnd > nPos && ASIAN == nScript )
     {
         LanguageType aLang =
-            rInf.GetTextFrame()->GetTextNode()->GetLang( rInf.GetIdx(), 1, nScript );
+            rInf.GetTextFrame()->GetLangOfChar(rInf.GetIdx(), nScript);
 
         if (!MsLangId::isKorean(aLang))
         {
@@ -130,7 +130,7 @@ static TextFrameIndex lcl_AddSpace(const SwTextSizeInfo &rInf,
     if ( nEnd > nPos && COMPLEX == nScript )
     {
         LanguageType aLang =
-            rInf.GetTextFrame()->GetTextNode()->GetLang( rInf.GetIdx(), 1, nScript );
+            rInf.GetTextFrame()->GetLangOfChar(rInf.GetIdx(), nScript);
 
         if ( LANGUAGE_THAI == aLang )
         {
@@ -203,7 +203,7 @@ static TextFrameIndex lcl_AddSpace(const SwTextSizeInfo &rInf,
         if( ASIAN == nNextScript )
         {
             LanguageType aLang =
-                rInf.GetTextFrame()->GetTextNode()->GetLang( nPos, 1, nNextScript );
+                rInf.GetTextFrame()->GetLangOfChar(nPos, nNextScript);
 
             if (!MsLangId::isKorean(aLang))
                 ++nCnt;
diff --git a/sw/source/core/text/txtfrm.cxx b/sw/source/core/text/txtfrm.cxx
index 7bcd56a5efd1..df597a2d1513 100644
--- a/sw/source/core/text/txtfrm.cxx
+++ b/sw/source/core/text/txtfrm.cxx
@@ -773,6 +773,14 @@ SwDoc const& SwTextFrame::GetDoc() const
     return *GetTextNodeFirst()->GetDoc();
 }
 
+LanguageType SwTextFrame::GetLangOfChar(TextFrameIndex const nIndex,
+        sal_uInt16 const nScript, bool const bNoChar) const
+{
+    // a single character can be mapped uniquely!
+    std::pair<SwTextNode const*, sal_Int32> const pos(MapViewToModel(nIndex));
+    return pos.first->GetLang(pos.second, bNoChar ? 0 : 1, nScript);
+}
+
 void SwTextFrame::ResetPreps()
 {
     if ( GetCacheIdx() != USHRT_MAX )
commit 3b6d29adb40180094dc41651a7bc0e79c5d311bc
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 16:09:02 2018 +0200

    sw_redlinehide: SwScriptInfo conversion swcrsr.cxx,edattr.cxx,editsh.cxx
    
    Change-Id: I3676357fbba242fe7f5ed632d704a6704e802217

diff --git a/sw/source/core/crsr/swcrsr.cxx b/sw/source/core/crsr/swcrsr.cxx
index e84731cd9795..91e9e2e61551 100644
--- a/sw/source/core/crsr/swcrsr.cxx
+++ b/sw/source/core/crsr/swcrsr.cxx
@@ -1593,13 +1593,15 @@ SwCursor::DoSetBidiLevelLeftRight(
         }
         else
         {
-            const SwScriptInfo* pSI = SwScriptInfo::GetScriptInfo( rTNd );
+            SwTextFrame const* pFrame;
+            const SwScriptInfo* pSI = SwScriptInfo::GetScriptInfo(rTNd, &pFrame);
             if ( pSI )
             {
                 const sal_Int32 nMoveOverPos = io_rbLeft ?
                                                ( nPos ? nPos - 1 : 0 ) :
                                                 nPos;
-                SetCursorBidiLevel( pSI->DirType( nMoveOverPos ) );
+                TextFrameIndex nIndex(pFrame->MapModelToView(&rTNd, nMoveOverPos));
+                SetCursorBidiLevel( pSI->DirType(nIndex) );
             }
         }
     }
@@ -1736,8 +1738,9 @@ void SwCursor::DoSetBidiLevelUpDown()
     SwNode& rNode = GetPoint()->nNode.GetNode();
     if ( rNode.IsTextNode() )
     {
+        SwTextFrame const* pFrame;
         const SwScriptInfo* pSI =
-            SwScriptInfo::GetScriptInfo( *rNode.GetTextNode() );
+            SwScriptInfo::GetScriptInfo( *rNode.GetTextNode(), &pFrame );
         if ( pSI )
         {
             SwIndex& rIdx = GetPoint()->nContent;
@@ -1745,8 +1748,9 @@ void SwCursor::DoSetBidiLevelUpDown()
 
             if (nPos && nPos < rNode.GetTextNode()->GetText().getLength())
             {
-                const sal_uInt8 nCurrLevel = pSI->DirType( nPos );
-                const sal_uInt8 nPrevLevel = pSI->DirType( nPos - 1 );
+                TextFrameIndex const nIndex(pFrame->MapModelToView(rNode.GetTextNode(), nPos));
+                const sal_uInt8 nCurrLevel = pSI->DirType( nIndex );
+                const sal_uInt8 nPrevLevel = pSI->DirType( nIndex - TextFrameIndex(1) );
 
                 if ( nCurrLevel % 2 != nPrevLevel % 2 )
                 {
diff --git a/sw/source/core/edit/edattr.cxx b/sw/source/core/edit/edattr.cxx
index 63f026082b67..df5d6df3b8a9 100644
--- a/sw/source/core/edit/edattr.cxx
+++ b/sw/source/core/edit/edattr.cxx
@@ -307,8 +307,15 @@ std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> SwEditShell
                 const sal_Int32 nStt = (n == nSttNd) ? nSttCnt : 0;
                 const sal_Int32 nEnd = (n == nEndNd)
                     ? nEndCnt : pTextNd->GetText().getLength();
-                const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTextNd );
-                sal_uInt8 nScript = pScriptInfo ? pScriptInfo->ScriptType( nStt ) : css::i18n::ScriptType::WEAK;
+                SwTextFrame const* pFrame;
+                const SwScriptInfo *const pScriptInfo =
+                    SwScriptInfo::GetScriptInfo(*pTextNd, &pFrame);
+                TextFrameIndex const iStt(pScriptInfo
+                        ? pFrame->MapModelToView(pTextNd, nStt)
+                        : TextFrameIndex(-1/*invalid, do not use*/));
+                sal_uInt8 nScript = pScriptInfo
+                    ? pScriptInfo->ScriptType(iStt)
+                    : css::i18n::ScriptType::WEAK;
                 nWhich = GetWhichOfScript( nWhich, nScript );
 
                 // item from attribute set
@@ -340,7 +347,9 @@ std::vector<std::pair< const SfxPoolItem*, std::unique_ptr<SwPaM> >> SwEditShell
                         if( *pAttrEnd <= nStt )
                             continue;
 
-                        nScript = pScriptInfo ? pScriptInfo->ScriptType( nStt ) : css::i18n::ScriptType::WEAK;
+                        nScript = pScriptInfo
+                            ? pScriptInfo->ScriptType(iStt)
+                            : css::i18n::ScriptType::WEAK;
                         nWhich = GetWhichOfScript( nWhich, nScript );
                         const SfxItemSet* pAutoSet = CharFormat::GetItemSet( pHt->GetAttr() );
                         if( pAutoSet )
@@ -651,7 +660,9 @@ SvtScriptType SwEditShell::GetScriptType() const
                 if( pTNd )
                 {
                     // try to get SwScriptInfo
-                    const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd );
+                    SwTextFrame const* pFrame;
+                    const SwScriptInfo *const pScriptInfo =
+                        SwScriptInfo::GetScriptInfo(*pTNd, &pFrame);
 
                     sal_Int32 nPos = pStt->nContent.GetIndex();
                     //Task 90448: we need the scripttype of the previous
@@ -667,9 +678,9 @@ SvtScriptType SwEditShell::GetScriptType() const
 
                     if (!pTNd->GetText().isEmpty())
                     {
-                        nScript = pScriptInfo ?
-                                  pScriptInfo->ScriptType( nPos ) :
-                                  g_pBreakIt->GetBreakIter()->getScriptType( pTNd->GetText(), nPos );
+                        nScript = pScriptInfo
+                            ? pScriptInfo->ScriptType(pFrame->MapModelToView(pTNd, nPos))
+                            : g_pBreakIt->GetBreakIter()->getScriptType( pTNd->GetText(), nPos );
                     }
                     else
                         nScript = SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
@@ -689,7 +700,9 @@ SvtScriptType SwEditShell::GetScriptType() const
                         const OUString& rText = pTNd->GetText();
 
                         // try to get SwScriptInfo
-                        const SwScriptInfo* pScriptInfo = SwScriptInfo::GetScriptInfo( *pTNd );
+                        SwTextFrame const* pFrame;
+                        const SwScriptInfo *const pScriptInfo =
+                            SwScriptInfo::GetScriptInfo(*pTNd, &pFrame);
 
                         sal_Int32 nChg = aIdx == pStt->nNode
                                                 ? pStt->nContent.GetIndex()
@@ -706,8 +719,11 @@ SvtScriptType SwEditShell::GetScriptType() const
                         sal_uInt16 nScript;
                         while( nChg < nEndPos )
                         {
+                            TextFrameIndex const iChg(pScriptInfo
+                                    ? pFrame->MapModelToView(pTNd, nChg)
+                                    : TextFrameIndex(-1/*invalid, do not use*/));
                             nScript = pScriptInfo ?
-                                      pScriptInfo->ScriptType( nChg ) :
+                                      pScriptInfo->ScriptType( iChg ) :
                                       g_pBreakIt->GetBreakIter()->getScriptType(
                                                                 rText, nChg );
 
@@ -721,10 +737,20 @@ SvtScriptType SwEditShell::GetScriptType() const
 
                             sal_Int32 nFieldPos = nChg+1;
 
-                            nChg = pScriptInfo ?
-                                   pScriptInfo->NextScriptChg( nChg ) :
-                                   g_pBreakIt->GetBreakIter()->endOfScript(
+                            if (pScriptInfo)
+                            {
+                                std::pair<SwTextNode*, sal_Int32> const tmp(
+                                    pFrame->MapViewToModel(
+                                        pScriptInfo->NextScriptChg(iChg)));
+                                nChg = (tmp.first == pTNd)
+                                    ? tmp.second
+                                    : pTNd->Len();
+                            }
+                            else
+                            {
+                                nChg = g_pBreakIt->GetBreakIter()->endOfScript(
                                                     rText, nChg, nScript );
+                            }
 
                             nFieldPos = rText.indexOf(
                                             CH_TXTATR_BREAKWORD, nFieldPos);
diff --git a/sw/source/core/edit/editsh.cxx b/sw/source/core/edit/editsh.cxx
index d04548b7eb23..e3f443b25eec 100644
--- a/sw/source/core/edit/editsh.cxx
+++ b/sw/source/core/edit/editsh.cxx
@@ -145,7 +145,9 @@ void SwEditShell::Insert2(const OUString &rStr, const bool bForceExpandHints )
                 SwScriptInfo aScriptInfo;
                 aScriptInfo.InitScriptInfo(static_cast<SwTextNode&>(rNode),
                         pFrame->GetMergedPara(), pFrame->IsRightToLeft());
-                nLevel = aScriptInfo.DirType( nPrevPos );
+                TextFrameIndex const iPrevPos(pFrame->MapModelToView(
+                            &static_cast<SwTextNode&>(rNode), nPrevPos));
+                nLevel = aScriptInfo.DirType( iPrevPos );
             }
             else
             {
@@ -154,7 +156,9 @@ void SwEditShell::Insert2(const OUString &rStr, const bool bForceExpandHints )
                     // mystery why this doesn't use the other overload?
                     pSI->InitScriptInfo(static_cast<SwTextNode&>(rNode), pFrame->GetMergedPara());
                 }
-                nLevel = pSI->DirType( nPrevPos );
+                TextFrameIndex const iPrevPos(pFrame->MapModelToView(
+                            &static_cast<SwTextNode&>(rNode), nPrevPos));
+                nLevel = pSI->DirType(iPrevPos);
             }
 
             pTmpCursor->SetCursorBidiLevel( nLevel );
commit f38f3933419983ed757d36dd321a9cad82019c66
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 15:59:10 2018 +0200

    sw_redlinehide: SwScriptInfo::GetScriptInfo() should return frame too
    
    The SwScriptInfo comes from the frame, and if both are used together
    they have to match.
    
    Change-Id: I3de0754d9ff316180fc04708889886684d6868e5

diff --git a/sw/source/core/edit/editsh.cxx b/sw/source/core/edit/editsh.cxx
index b5f8dbc1cee8..d04548b7eb23 100644
--- a/sw/source/core/edit/editsh.cxx
+++ b/sw/source/core/edit/editsh.cxx
@@ -129,14 +129,16 @@ void SwEditShell::Insert2(const OUString &rStr, const bool bForceExpandHints )
             if ( nPrevPos )
                 --nPrevPos;
 
-            SwScriptInfo* pSI = SwScriptInfo::GetScriptInfo( static_cast<SwTextNode&>(rNode), true );
+            SwTextFrame const* pFrame;
+            SwScriptInfo *const pSI = SwScriptInfo::GetScriptInfo(
+                    static_cast<SwTextNode&>(rNode), &pFrame, true);
 
             sal_uInt8 nLevel = 0;
             if ( ! pSI )
             {
                 // seems to be an empty paragraph.
                 Point aPt; // why ???
-                SwTextFrame *const pFrame = static_cast<SwTextFrame*>(
+                pFrame = static_cast<SwTextFrame*>(
                         static_cast<SwTextNode&>(rNode).getLayoutFrame(
                             GetLayout(), &aPt, pTmpCursor->GetPoint(), false));
 
@@ -149,10 +151,6 @@ void SwEditShell::Insert2(const OUString &rStr, const bool bForceExpandHints )
             {
                 if (TextFrameIndex(COMPLETE_STRING) != pSI->GetInvalidityA())
                 {
-                    // note: if pSI was found, there must be a frame
-                    SwTextFrame *const pFrame = static_cast<SwTextFrame*>(
-                        static_cast<SwTextNode&>(rNode).getLayoutFrame(
-                            GetLayout(), nullptr, pTmpCursor->GetPoint(), false));
                     // mystery why this doesn't use the other overload?
                     pSI->InitScriptInfo(static_cast<SwTextNode&>(rNode), pFrame->GetMergedPara());
                 }
diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index a027b123ebdf..9386f1309e8e 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -28,6 +28,7 @@
 #include "TextFrameIndex.hxx"
 
 class SwTextNode;
+class SwTextFrame;
 class Point;
 class MultiSelection;
 typedef std::vector< sal_Int32 > PositionList;
@@ -366,8 +367,11 @@ public:
                                   TextFrameIndex nLen, LanguageType aLang,
                                   long nSpaceAdd, bool bIsSpaceStop );
 
+    /// return a frame for the node, ScriptInfo is its member...
+    /// (many clients need both frame and SI, and both have to match)
     static SwScriptInfo* GetScriptInfo( const SwTextNode& rNode,
-                                        bool bAllowInvalid = false );
+                                        SwTextFrame const** o_pFrame = nullptr,
+                                        bool bAllowInvalid = false);
 
     SwFontScript WhichFont(TextFrameIndex nIdx) const;
     static SwFontScript WhichFont(sal_Int32 nIdx, OUString const & rText);
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index b7a00c02fdbb..b2bf9438f3e3 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -2081,7 +2081,8 @@ TextFrameIndex SwScriptInfo::ThaiJustify( const OUString& rText, long* pKernArra
 }
 
 SwScriptInfo* SwScriptInfo::GetScriptInfo( const SwTextNode& rTNd,
-                                           bool bAllowInvalid )
+                                           SwTextFrame const**const o_ppFrame,
+                                           bool const bAllowInvalid)
 {
     SwIterator<SwTextFrame,SwTextNode> aIter( rTNd );
     SwScriptInfo* pScriptInfo = nullptr;
@@ -2093,7 +2094,13 @@ SwScriptInfo* SwScriptInfo::GetScriptInfo( const SwTextNode& rTNd,
         {
             if (bAllowInvalid ||
                 TextFrameIndex(COMPLETE_STRING) == pScriptInfo->GetInvalidityA())
+            {
+                if (o_ppFrame)
+                {
+                    *o_ppFrame = pLast;
+                }
                 break;
+            }
             pScriptInfo = nullptr;
         }
     }
commit 3db4d297690a9d04a9aad356487be7574ec617da
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 15:56:19 2018 +0200

    sw_redlinehide: SwScriptInfo conversion in itradj.cxx
    
    Have to reinterpret_cast arrays here to pass them to VCL.
    
    Change-Id: Ia0d1b9ab159e55bae01f1cabf3c137a9c8676c79

diff --git a/sw/source/core/text/itradj.cxx b/sw/source/core/text/itradj.cxx
index 524454d7a093..428c8d93fe51 100644
--- a/sw/source/core/text/itradj.cxx
+++ b/sw/source/core/text/itradj.cxx
@@ -131,8 +131,8 @@ static bool lcl_CheckKashidaPositions( SwScriptInfo& rSI, SwTextSizeInfo& rInf,
 
     // kashida positions found in SwScriptInfo are not necessarily valid in every font
     // if two characters are replaced by a ligature glyph, there will be no place for a kashida
-    std::unique_ptr<sal_Int32[]> pKashidaPos( new sal_Int32[ rKashidas ] );
-    std::unique_ptr<sal_Int32[]> pKashidaPosDropped( new sal_Int32[ rKashidas ] );
+    std::unique_ptr<TextFrameIndex[]> pKashidaPos(new TextFrameIndex[rKashidas]);
+    std::unique_ptr<TextFrameIndex[]> pKashidaPosDropped(new TextFrameIndex[rKashidas]);
     rSI.GetKashidaPositions ( nIdx, rItr.GetLength(), pKashidaPos.get() );
     sal_Int32 nKashidaIdx = 0;
     while ( rKashidas && nIdx < nEnd )
@@ -142,7 +142,7 @@ static bool lcl_CheckKashidaPositions( SwScriptInfo& rSI, SwTextSizeInfo& rInf,
 
         // is there also a script change before?
         // if there is, nNext should point to the script change
-        sal_Int32 nNextScript = rSI.NextScriptChg( nIdx );
+        TextFrameIndex const nNextScript = rSI.NextScriptChg( nIdx );
         if( nNextScript < nNext )
             nNext = nNextScript;
 
@@ -161,15 +161,17 @@ static bool lcl_CheckKashidaPositions( SwScriptInfo& rSI, SwTextSizeInfo& rInf,
             {
                 ComplexTextLayoutFlags nOldLayout = rInf.GetOut()->GetLayoutMode();
                 rInf.GetOut()->SetLayoutMode ( nOldLayout | ComplexTextLayoutFlags::BiDiRtl );
-                nKashidasDropped = rInf.GetOut()->ValidateKashidas ( rInf.GetText(), nIdx, nNext - nIdx,
-                                               nKashidasInAttr, pKashidaPos.get() + nKashidaIdx,
-                                               pKashidaPosDropped.get() );
+                nKashidasDropped = rInf.GetOut()->ValidateKashidas(
+                    rInf.GetText(), sal_Int32(nIdx), sal_Int32(nNext - nIdx),
+                    nKashidasInAttr,
+                    reinterpret_cast<sal_Int32*>(pKashidaPos.get() + nKashidaIdx),
+                    reinterpret_cast<sal_Int32*>(pKashidaPosDropped.get()));
                 rInf.GetOut()->SetLayoutMode ( nOldLayout );
                 if ( nKashidasDropped )
                 {
                     rSI.MarkKashidasInvalid(nKashidasDropped, pKashidaPosDropped.get());
                     rKashidas -= nKashidasDropped;
-                    nGluePortion -= nKashidasDropped;
+                    nGluePortion -= TextFrameIndex(nKashidasDropped);
                 }
             }
             nKashidaIdx += nKashidasInAttr;
@@ -199,11 +201,11 @@ static bool lcl_CheckKashidaWidth ( SwScriptInfo& rSI, SwTextSizeInfo& rInf, SwT
 
             // is there also a script change before?
             // if there is, nNext should point to the script change
-            sal_Int32 nNextScript = rSI.NextScriptChg( nIdx );
+            TextFrameIndex const nNextScript = rSI.NextScriptChg( nIdx );
             if( nNextScript < nNext )
                nNext = nNextScript;
 
-            if ( nNext == COMPLETE_STRING || nNext > nEnd )
+            if (nNext == TextFrameIndex(COMPLETE_STRING) || nNext > nEnd)
                 nNext = nEnd;
             sal_Int32 nKashidasInAttr = rSI.KashidaJustify ( nullptr, nullptr, nIdx, nNext - nIdx );
 
commit fa8bdf7b9bb35bbbd4e01a4bfa2a655fe9338693
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 14:26:53 2018 +0200

    sw_redlinehide: add a SwTextFrame::GetDropLen()
    
    Copy the SwTextNode::GetDropLen, as it can't be used in case the
    drop-text would include a delete redline, but the SwTextNode one is
    apparently needed by the WW8 filter.
    
    Change-Id: I26a8a15e977120d601d87a76d712005e2888b713

diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx
index 14e648f39abb..11bfdab230fe 100644
--- a/sw/source/core/inc/txtfrm.hxx
+++ b/sw/source/core/inc/txtfrm.hxx
@@ -504,6 +504,8 @@ public:
      */
     SwTwips GetFootnoteLine( const SwTextFootnote *pFootnote ) const;
 
+    TextFrameIndex GetDropLen(TextFrameIndex nWishLen) const;
+
     virtual void Format( vcl::RenderContext* pRenderContext, const SwBorderAttrs *pAttrs = nullptr ) override;
     virtual void CheckDirection( bool bVert ) override;
 
diff --git a/sw/source/core/text/txtdrop.cxx b/sw/source/core/text/txtdrop.cxx
index 2f8ca9d0decf..85138e2cd35f 100644
--- a/sw/source/core/text/txtdrop.cxx
+++ b/sw/source/core/text/txtdrop.cxx
@@ -169,6 +169,61 @@ sal_Int32 SwTextNode::GetDropLen( sal_Int32 nWishLen ) const
     return i;
 }
 
+/// nWishLen = 0 indicates that we want a whole word
+TextFrameIndex SwTextFrame::GetDropLen(TextFrameIndex const nWishLen) const
+{
+    TextFrameIndex nEnd(GetText().getLength());
+    if (nWishLen && nWishLen < nEnd)
+        nEnd = nWishLen;
+
+    if (! nWishLen)
+    {
+        // find first word
+        const SwAttrSet& rAttrSet = GetTextNodeForParaProps()->GetSwAttrSet();
+        const sal_uInt16 nTextScript = g_pBreakIt->GetRealScriptOfText(GetText(), 0);
+
+        LanguageType eLanguage;
+
+        switch ( nTextScript )
+        {
+        case i18n::ScriptType::ASIAN :
+            eLanguage = rAttrSet.GetCJKLanguage().GetLanguage();
+            break;
+        case i18n::ScriptType::COMPLEX :
+            eLanguage = rAttrSet.GetCTLLanguage().GetLanguage();
+            break;
+        default :
+            eLanguage = rAttrSet.GetLanguage().GetLanguage();
+            break;
+        }
+
+        Boundary aBound = g_pBreakIt->GetBreakIter()->getWordBoundary(
+            GetText(), 0, g_pBreakIt->GetLocale(eLanguage),
+            WordType::DICTIONARY_WORD, true );
+
+        nEnd = TextFrameIndex(aBound.endPos);
+    }
+
+    TextFrameIndex i(0);
+    for ( ; i < nEnd; ++i)
+    {
+        sal_Unicode const cChar = GetText()[sal_Int32(i)];
+        if (CH_TAB == cChar || CH_BREAK == cChar ||
+            CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar)
+        {
+#ifndef NDEBUG
+            if (CH_TXTATR_BREAKWORD == cChar || CH_TXTATR_INWORD == cChar)
+            {
+                std::pair<SwTextNode const*, sal_Int32> const pos(MapViewToModel(i));
+                assert(pos.first->GetTextAttrForCharAt(pos.second) != nullptr);
+            }
+#endif
+            break;
+        }
+    }
+    return i;
+}
+
 /**
  * If a dropcap is found the return value is true otherwise false. The
  * drop cap sizes passed back by reference are font height, drop height
@@ -510,7 +565,7 @@ SwDropPortion *SwTextFormatter::NewDropPortion( SwTextFormatInfo &rInf )
         return nullptr;
 
     TextFrameIndex nPorLen(pDropFormat->GetWholeWord() ? 0 : pDropFormat->GetChars());
-    nPorLen = m_pFrame->GetTextNode()->GetDropLen( nPorLen );
+    nPorLen = m_pFrame->GetDropLen( nPorLen );
     if( !nPorLen )
     {
         ClearDropFormat();
commit 691d7ed0cc34f7aaa8ddb88a4f73f4438e0eaf76
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 14:02:53 2018 +0200

    sw_redlinehide: SwScriptInfo conversion in txtdrop.cxx
    
    Change-Id: I65a8c7a1fc6a16dc602dfb73f8a17424ab01f162

diff --git a/sw/source/core/text/txtdrop.cxx b/sw/source/core/text/txtdrop.cxx
index b1ff0ec20386..2f8ca9d0decf 100644
--- a/sw/source/core/text/txtdrop.cxx
+++ b/sw/source/core/text/txtdrop.cxx
@@ -509,7 +509,7 @@ SwDropPortion *SwTextFormatter::NewDropPortion( SwTextFormatInfo &rInf )
     if( !pDropFormat )
         return nullptr;
 
-    sal_Int32 nPorLen = pDropFormat->GetWholeWord() ? 0 : pDropFormat->GetChars();
+    TextFrameIndex nPorLen(pDropFormat->GetWholeWord() ? 0 : pDropFormat->GetChars());
     nPorLen = m_pFrame->GetTextNode()->GetDropLen( nPorLen );
     if( !nPorLen )
     {
@@ -549,7 +549,7 @@ SwDropPortion *SwTextFormatter::NewDropPortion( SwTextFormatInfo &rInf )
 
     // build DropPortionParts:
     OSL_ENSURE( ! rInf.GetIdx(), "Drop Portion not at 0 position!" );
-    sal_Int32 nNextChg = 0;
+    TextFrameIndex nNextChg(0);
     const SwCharFormat* pFormat = pDropFormat->GetCharFormat();
     SwDropPortionPart* pCurrPart = nullptr;
 
@@ -570,8 +570,8 @@ SwDropPortion *SwTextFormatter::NewDropPortion( SwTextFormatInfo &rInf )
         pTmpFnt->SetVertical( 0, rInf.GetTextFrame()->IsVertical() );
 
         // find next attribute change / script change
-        const sal_Int32 nTmpIdx = nNextChg;
-        sal_Int32 nNextAttr = std::min( GetNextAttr(), rInf.GetText().getLength() );
+        const TextFrameIndex nTmpIdx = nNextChg;
+        TextFrameIndex nNextAttr = GetNextAttr();
         nNextChg = m_pScriptInfo->NextScriptChg( nTmpIdx );
         if( nNextChg > nNextAttr )
             nNextChg = nNextAttr;
commit 5e5ca04151eb47ef9b192a4213be7e36efe59e96
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 13:18:53 2018 +0200

    sw_redlinehide: SwScriptInfo conversion in itrform2.cxx
    
    Change-Id: Ia591961a27bed76fb762cfe9060f245b31ca2e01

diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 4b3455c79dbe..4080c85ce0ae 100755
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -603,10 +603,10 @@ void SwTextFormatter::BuildPortions( SwTextFormatInfo &rInf )
             {
                 // The distance between two different scripts is set
                 // to 20% of the fontheight.
-                sal_Int32 nTmp = rInf.GetIdx() + pPor->GetLen();
-                if( nTmp == m_pScriptInfo->NextScriptChg( nTmp - 1 ) &&
-                    nTmp != rInf.GetText().getLength() &&
-                    (m_pScriptInfo->ScriptType(nTmp - 1) == css::i18n::ScriptType::ASIAN ||
+                TextFrameIndex const nTmp = rInf.GetIdx() + pPor->GetLen();
+                if (nTmp == m_pScriptInfo->NextScriptChg(nTmp - TextFrameIndex(1)) &&
+                    nTmp != TextFrameIndex(rInf.GetText().getLength()) &&
+                    (m_pScriptInfo->ScriptType(nTmp - TextFrameIndex(1)) == css::i18n::ScriptType::ASIAN ||
                      m_pScriptInfo->ScriptType(nTmp) == css::i18n::ScriptType::ASIAN) )
                 {
                     const sal_uInt16 nDist = static_cast<sal_uInt16>(rInf.GetFont()->GetHeight()/5);
@@ -616,8 +616,8 @@ void SwTextFormatter::BuildPortions( SwTextFormatInfo &rInf )
                         // we do not want a kerning portion if any end
                         // would be a punctuation character
                         const CharClass& rCC = GetAppCharClass();
-                        if ( rCC.isLetterNumeric( rInf.GetText(), nTmp - 1 ) &&
-                             rCC.isLetterNumeric( rInf.GetText(), nTmp ) )
+                        if (rCC.isLetterNumeric(rInf.GetText(), sal_Int32(nTmp) - 1)
+                            && rCC.isLetterNumeric(rInf.GetText(), sal_Int32(nTmp)))
                         {
                             // does the kerning portion still fit into the line?
                             if ( rInf.X() + pPor->Width() + nDist <= rInf.Width() )
@@ -632,13 +632,14 @@ void SwTextFormatter::BuildPortions( SwTextFormatInfo &rInf )
 
         if ( bHasGrid && pGrid->IsSnapToChars() && pPor != pGridKernPortion && ! pMulti && ! pPor->InTabGrp() )
         {
-            sal_Int32 nTmp = rInf.GetIdx() + pPor->GetLen();
+            TextFrameIndex const nTmp = rInf.GetIdx() + pPor->GetLen();
             const SwTwips nRestWidth = rInf.Width() - rInf.X() - pPor->Width();
 
             const SwFontScript nCurrScript = m_pFont->GetActual(); // pScriptInfo->ScriptType( rInf.GetIdx() );
-            const SwFontScript nNextScript = nTmp >= rInf.GetText().getLength() ?
-                                     SwFontScript::CJK :
-                                     m_pScriptInfo->WhichFont(nTmp);
+            const SwFontScript nNextScript =
+                nTmp >= TextFrameIndex(rInf.GetText().getLength())
+                    ? SwFontScript::CJK
+                    : m_pScriptInfo->WhichFont(nTmp);
 
             // snap non-asian text to grid if next portion is ASIAN or
             // there are no more portions in this line
@@ -950,11 +951,11 @@ SwTextPortion *SwTextFormatter::NewTextPortion( SwTextFormatInfo &rInf )
     TextFrameIndex nNextChg = std::min(nNextAttr, TextFrameIndex(rInf.GetText().getLength()));
 
     // end of script type:
-    const sal_Int32 nNextScript = m_pScriptInfo->NextScriptChg( rInf.GetIdx() );
+    const TextFrameIndex nNextScript = m_pScriptInfo->NextScriptChg(rInf.GetIdx());
     nNextChg = std::min( nNextChg, nNextScript );
 
     // end of direction:
-    const sal_Int32 nNextDir = m_pScriptInfo->NextDirChg( rInf.GetIdx() );
+    const TextFrameIndex nNextDir = m_pScriptInfo->NextDirChg(rInf.GetIdx());
     nNextChg = std::min( nNextChg, nNextDir );
 
     // Turbo boost:
commit d4783a0b025c8ea63e2518072e5b18abcd5f224c
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 12:57:53 2018 +0200

    sw_redlinehide: convert SwFieldPortion::CheckScript()
    
    Change-Id: I85dd0a194e0a406c4a2af51676c996fcfc558961

diff --git a/sw/source/core/text/porfld.cxx b/sw/source/core/text/porfld.cxx
index a1d5e72f584f..d40ff3ed3dc0 100644
--- a/sw/source/core/text/porfld.cxx
+++ b/sw/source/core/text/porfld.cxx
@@ -211,9 +211,10 @@ void SwFieldPortion::CheckScript( const SwTextSizeInfo &rInf )
     // nNextScriptChg will be evaluated during SwFieldPortion::Format()
 
     if (nChg < aText.getLength() && nChg >= 0)
-        m_nNextScriptChg = g_pBreakIt->GetBreakIter()->endOfScript( aText, nChg, nScript );
+        m_nNextScriptChg = TextFrameIndex(
+                g_pBreakIt->GetBreakIter()->endOfScript(aText, nChg, nScript));
     else
-        m_nNextScriptChg = aText.getLength();
+        m_nNextScriptChg = TextFrameIndex(aText.getLength());
 
     SwFontScript nTmp;
     switch ( nScript ) {
@@ -238,7 +239,7 @@ void SwFieldPortion::CheckScript( const SwTextSizeInfo &rInf )
         UBiDiLevel nCurrDir;
         ubidi_getLogicalRun( pBidi, 0, &nEnd, &nCurrDir );
         ubidi_close( pBidi );
-        const sal_Int32 nNextDirChg = nEnd;
+        const TextFrameIndex nNextDirChg(nEnd);
         m_nNextScriptChg = std::min( m_nNextScriptChg, nNextDirChg );
 
         // #i89825# change the script type also to CTL
commit 0e96827f549181165b883978df94b7376d2c6f61
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 12:30:07 2018 +0200

    sw_redlinehide: disambiguate SwScriptInfo::GetBoundsOfHiddenRange()
    
    Remove the "fast-path" from the static to the member function,
    as it won't work with merged paragraphs.
    
    This was the only caller that used the PositionList parameter, so remove
    that.
    
    Change-Id: Ide00cccca4bbc5cd2447477c34cb7b04f9eccfc6

diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index 8ab6e7643598..a027b123ebdf 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -223,7 +223,7 @@ public:
                                         sal_Int32& rnStartPos, sal_Int32& rnEndPos,
                                         PositionList* pList = nullptr );
     bool GetBoundsOfHiddenRange(TextFrameIndex nPos, TextFrameIndex & rnStartPos,
-                                TextFrameIndex & rnEndPos, PositionList* pList = nullptr) const;
+                                TextFrameIndex & rnEndPos) const;
 
     static bool IsInHiddenRange( const SwTextNode& rNode, sal_Int32 nPos );
 
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index e11272ac25a0..b7a00c02fdbb 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -1521,6 +1521,8 @@ bool SwScriptInfo::GetBoundsOfHiddenRange( const SwTextNode& rNode, sal_Int32 nP
         }
     }
 
+    // sw_redlinehide: this won't work if it's merged
+#if 0
     const SwScriptInfo* pSI = SwScriptInfo::GetScriptInfo( rNode );
     if ( pSI )
     {
@@ -1533,6 +1535,7 @@ bool SwScriptInfo::GetBoundsOfHiddenRange( const SwTextNode& rNode, sal_Int32 nP
         rNode.SetHiddenCharAttribute( bNewHiddenCharsHidePara, bNewContainsHiddenChars );
     }
     else
+#endif
     {
 
         // No valid SwScriptInfo Object, we have to do it the hard way:
@@ -1576,8 +1579,7 @@ bool SwScriptInfo::GetBoundsOfHiddenRange( const SwTextNode& rNode, sal_Int32 nP
 }
 
 bool SwScriptInfo::GetBoundsOfHiddenRange(TextFrameIndex nPos,
-        TextFrameIndex & rnStartPos, TextFrameIndex & rnEndPos,
-        PositionList *const pList) const
+        TextFrameIndex & rnStartPos, TextFrameIndex & rnEndPos) const
 {
     rnStartPos = TextFrameIndex(COMPLETE_STRING);
     rnEndPos = TextFrameIndex(0);
@@ -1598,15 +1600,6 @@ bool SwScriptInfo::GetBoundsOfHiddenRange(TextFrameIndex nPos,
         }
     }
 
-    if ( pList )
-    {
-        for( size_t nX = 0; nX < nEnd; ++nX )
-        {
-            pList->push_back( GetHiddenChg( nX++ ) );
-            pList->push_back( GetHiddenChg( nX ) );
-        }
-    }
-
     return CountHiddenChg() > 0;
 }
 
commit 9c2e6cd661094b7a06caab0c353c69a818971db0
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 12:27:14 2018 +0200

    sw_redlinehide: SwScriptInfo::InitScriptInfo() init m_HiddenChg
    
    ... in the MergedPara case. For now, keep the CalcHiddenRanges()
    per-node, and rely on it marking all redlines as "visible" so
    the range comparison is quite simple.
    
    Change-Id: Ida0435800caf3efdea963079b756f47cc78e95a5

diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 7ec772a020a9..e11272ac25a0 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -720,19 +720,77 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
 
     // HIDDEN TEXT INFORMATION
 
-    Range aRange( 0, !rText.isEmpty() ? rText.getLength() - 1 : 0 );
-    MultiSelection aHiddenMulti( aRange );
-    CalcHiddenRanges( rNode, aHiddenMulti );
-
     m_HiddenChg.clear();
-    for( sal_Int32 i = 0; i < aHiddenMulti.GetRangeCount(); ++i )
+    if (pMerged)
+    {
+        SwTextNode const* pNode(nullptr);
+        TextFrameIndex nOffset(0);
+        for (auto iter = pMerged->extents.begin(); iter != pMerged->extents.end(); ++iter)
+        {
+            if (iter->pNode == pNode)
+            {
+                nOffset += TextFrameIndex(iter->nEnd - iter->nStart);
+                continue; // skip extents at end of previous node
+            }
+            pNode = iter->pNode;
+            Range aRange( 0, pNode->Len() > 0 ? pNode->Len() - 1 : 0 );
+            MultiSelection aHiddenMulti( aRange );
+            CalcHiddenRanges( *pNode, aHiddenMulti );
+
+            for (sal_Int32 i = 0; i < aHiddenMulti.GetRangeCount(); ++i)
+            {
+                const Range& rRange = aHiddenMulti.GetRange( i );
+                const sal_Int32 nStart = rRange.Min();
+                const sal_Int32 nEnd = rRange.Max() + 1;
+
+                while (true)
+                {
+                    // because of the selectRedLineDeleted call, never overlaps
+                    // extents, must be contained inside one extent
+                    assert(!(iter->nStart <= nStart && nStart < iter->nEnd && iter->nEnd < nEnd));
+                    assert(!(nStart < iter->nStart && iter->nStart < nEnd && nEnd <= iter->nEnd));
+                    if (iter->nStart <= nStart && nEnd <= iter->nEnd)
+                    {
+                        if (iter->nStart == nStart && !m_HiddenChg.empty()
+                            && m_HiddenChg.back() == nOffset)
+                        {
+                            // previous one went until end of extent, extend it
+                            m_HiddenChg.back() += TextFrameIndex(nEnd - iter->nStart);
+                        }
+                        else // new one
+                        {
+                            m_HiddenChg.push_back(nOffset + TextFrameIndex(nStart - iter->nStart));
+                            m_HiddenChg.push_back(nOffset + TextFrameIndex(nEnd - iter->nStart));
+                        }
+                        break;
+                    }
+                    else
+                    {
+                        nOffset += TextFrameIndex(iter->nEnd - iter->nStart);
+                        ++iter;
+                        // because selectRedLineDeleted, must find it in pNode
+                        assert(iter != pMerged->extents.end());
+                        assert(iter->pNode == pNode);
+                    }
+                }
+            }
+        }
+    }
+    else
     {
-        const Range& rRange = aHiddenMulti.GetRange( i );
-        const sal_Int32 nStart = rRange.Min();
-        const sal_Int32 nEnd = rRange.Max() + 1;
+        Range aRange( 0, !rText.isEmpty() ? rText.getLength() - 1 : 0 );
+        MultiSelection aHiddenMulti( aRange );
+        CalcHiddenRanges( rNode, aHiddenMulti );
 
-        m_HiddenChg.push_back( nStart );
-        m_HiddenChg.push_back( nEnd );
+        for (sal_Int32 i = 0; i < aHiddenMulti.GetRangeCount(); ++i)
+        {
+            const Range& rRange = aHiddenMulti.GetRange( i );
+            const sal_Int32 nStart = rRange.Min();
+            const sal_Int32 nEnd = rRange.Max() + 1;
+
+            m_HiddenChg.push_back( TextFrameIndex(nStart) );
+            m_HiddenChg.push_back( TextFrameIndex(nEnd) );
+        }
     }
 
     // SCRIPT AND SCRIPT RELATED INFORMATION
commit f64c5078e1e75f6ab50bbab3fa30701bb2713da8
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 10:44:06 2018 +0200

    sw_redlinehide: convert SwSubFont::DrawText_ to static SwScriptInfo
    
    Change-Id: I7bdcb5f787b6a82def4f7ca5aca29a16b6881e38

diff --git a/sw/source/core/txtnode/swfont.cxx b/sw/source/core/txtnode/swfont.cxx
index 82adaaa4b51c..ed23fff22623 100644
--- a/sw/source/core/txtnode/swfont.cxx
+++ b/sw/source/core/txtnode/swfont.cxx
@@ -1213,20 +1213,23 @@ void SwSubFont::DrawText_( SwDrawTextInfo &rInf, const bool bGrey )
         long nSpace = 0;
         if( rInf.GetSpace() )
         {
-            sal_Int32 nTmpEnd = nOldIdx + nOldLen;
-            if (nTmpEnd > oldStr.getLength())
-                nTmpEnd = oldStr.getLength();
+            TextFrameIndex nTmpEnd = nOldIdx + nOldLen;
+            if (nTmpEnd > TextFrameIndex(oldStr.getLength()))
+                nTmpEnd = TextFrameIndex(oldStr.getLength());
 
             const SwScriptInfo* pSI = rInf.GetScriptInfo();
 
             const bool bAsianFont =
                 ( rInf.GetFont() && SwFontScript::CJK == rInf.GetFont()->GetActual() );
-            for( sal_Int32 nTmp = nOldIdx; nTmp < nTmpEnd; ++nTmp )
+            for (TextFrameIndex nTmp = nOldIdx; nTmp < nTmpEnd; ++nTmp)
             {
-                if (CH_BLANK == oldStr[nTmp] || bAsianFont ||
-                    ( nTmp + 1 < oldStr.getLength() && pSI &&
-                      i18n::ScriptType::ASIAN == pSI->ScriptType( nTmp + 1 ) ) )
+                if (CH_BLANK == oldStr[sal_Int32(nTmp)] || bAsianFont ||
+                    (nTmp + TextFrameIndex(1) < TextFrameIndex(oldStr.getLength())
+                     && pSI
+                     && i18n::ScriptType::ASIAN == pSI->ScriptType(nTmp + TextFrameIndex(1))))
+                {
                     ++nSpace;
+                }
             }
 
             // if next portion if a hole portion we do not consider any
commit 8b0ef1261aadcaf7e5f37000f81392e0d100db8b
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 10:40:59 2018 +0200

    ... impl.
    
    Change-Id: I17393f2d4ea3dda63ab2becda5f44f959248b538

diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 49cb28187867..7ec772a020a9 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -1814,8 +1814,8 @@ bool SwScriptInfo::IsArabicText(const OUString& rText,
 
     // go forward if current position does not hold a regular character:
     const CharClass& rCC = GetAppCharClass();
-    sal_Int32 nIdx = nStt;
-    const sal_Int32 nEnd = nStt + nLen;
+    sal_Int32 nIdx = sal_Int32(nStt);
+    const sal_Int32 nEnd = sal_Int32(nStt + nLen);
     while ( nIdx < nEnd && !rCC.isLetterNumeric( rText, nIdx ) )
     {
         ++nIdx;
@@ -1996,25 +1996,25 @@ TextFrameIndex SwScriptInfo::ThaiJustify( const OUString& rText, long* pKernArra
                                      TextFrameIndex nNumberOfBlanks,
                                      long nSpaceAdd )
 {
-    SAL_WARN_IF( nStt + nLen > rText.getLength(), "sw.core", "String in ThaiJustify too small" );
+    SAL_WARN_IF( nStt + nLen > TextFrameIndex(rText.getLength()), "sw.core", "String in ThaiJustify too small" );
 
-    SwTwips nNumOfTwipsToDistribute = nSpaceAdd * nNumberOfBlanks /
+    SwTwips nNumOfTwipsToDistribute = nSpaceAdd * sal_Int32(nNumberOfBlanks) /
                                       SPACING_PRECISION_FACTOR;
 
     long nSpaceSum = 0;
-    sal_Int32 nCnt = 0;
+    TextFrameIndex nCnt(0);
 
-    for (sal_Int32 nI = 0; nI < nLen; ++nI)
+    for (sal_Int32 nI = 0; nI < sal_Int32(nLen); ++nI)
     {
-        const sal_Unicode cCh = rText[nStt + nI];
+        const sal_Unicode cCh = rText[sal_Int32(nStt) + nI];
 
         // check if character is not above or below base
         if ( ( 0xE34 > cCh || cCh > 0xE3A ) &&
              ( 0xE47 > cCh || cCh > 0xE4E ) && cCh != 0xE31 )
         {
-            if ( nNumberOfBlanks > 0 )
+            if (nNumberOfBlanks > TextFrameIndex(0))
             {
-                nSpaceAdd = nNumOfTwipsToDistribute / nNumberOfBlanks;
+                nSpaceAdd = nNumOfTwipsToDistribute / sal_Int32(nNumberOfBlanks);
                 --nNumberOfBlanks;
                 nNumOfTwipsToDistribute -= nSpaceAdd;
             }
@@ -2241,16 +2241,17 @@ void SwScriptInfo::CalcHiddenRanges( const SwTextNode& rNode, MultiSelection& rH
 TextFrameIndex SwScriptInfo::CountCJKCharacters(const OUString &rText,
     TextFrameIndex nPos, TextFrameIndex const nEnd, LanguageType aLang)
 {
-    sal_Int32 nCount = 0;
+    TextFrameIndex nCount(0);
     if (nEnd > nPos)
     {
         sal_Int32 nDone = 0;
         const lang::Locale &rLocale = g_pBreakIt->GetLocale( aLang );
         while ( nPos < nEnd )
         {
-            nPos = g_pBreakIt->GetBreakIter()->nextCharacters( rText, nPos,
+            nPos = TextFrameIndex(g_pBreakIt->GetBreakIter()->nextCharacters(
+                    rText, sal_Int32(nPos),
                     rLocale,
-                    i18n::CharacterIteratorMode::SKIPCELL, 1, nDone );
+                    i18n::CharacterIteratorMode::SKIPCELL, 1, nDone));
             nCount++;
         }
     }
@@ -2265,21 +2266,21 @@ void SwScriptInfo::CJKJustify( const OUString& rText, long* pKernArray,
                                      TextFrameIndex const nLen, LanguageType aLang,
                                      long nSpaceAdd, bool bIsSpaceStop )
 {
-    assert( pKernArray != nullptr && nStt >= 0 );
-    if (nLen > 0)
+    assert( pKernArray != nullptr && sal_Int32(nStt) >= 0 );
+    if (sal_Int32(nLen) > 0)
     {
         long nSpaceSum = 0;
         const lang::Locale &rLocale = g_pBreakIt->GetLocale( aLang );
         sal_Int32 nDone = 0;
-        sal_Int32 nNext = nStt;
-        for ( sal_Int32 nI = 0; nI < nLen ; ++nI )
+        sal_Int32 nNext(nStt);
+        for ( sal_Int32 nI = 0; nI < sal_Int32(nLen); ++nI )
         {
-            if ( nI + nStt == nNext )
+            if (nI + sal_Int32(nStt) == nNext)
             {
                 nNext = g_pBreakIt->GetBreakIter()->nextCharacters( rText, nNext,
                         rLocale,
                         i18n::CharacterIteratorMode::SKIPCELL, 1, nDone );
-                if (nNext < nStt + nLen || !bIsSpaceStop)
+                if (nNext < sal_Int32(nStt + nLen) || !bIsSpaceStop)
                     nSpaceSum += nSpaceAdd;
             }
             pKernArray[ nI ] += nSpaceSum;
commit dc72236cf951f8ed74888f631f1cfb02e5f60ca4
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Thu May 24 10:40:07 2018 +0200

    sw_redlinehide: static functions of SwScriptInfo
    
    Some of these are only called with TextFrameIndex, so just convert the
    parameter types to that for simplicity.
    
    Change-Id: I73d418bd42ec95b15548b3df44736de0092ad87d

diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index 9a92a06557cf..8ab6e7643598 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -332,7 +332,7 @@ public:
                  Start index of the text
      @return Returns if the language is an Arabic language
  */
-    static bool IsArabicText( const OUString& rText, sal_Int32 nStt, sal_Int32 nLen );
+    static bool IsArabicText(const OUString& rText, TextFrameIndex nStt, TextFrameIndex nLen);
 
 /** Performs a thai justification on the kerning array
 
@@ -352,16 +352,18 @@ public:
                 The value which has to be added to the cells.
     @return The number of extra spaces in the given range
 */
-    static sal_Int32 ThaiJustify( const OUString& rText, long* pKernArray,
-                                  long* pScrArray, sal_Int32 nIdx,
-                                  sal_Int32 nLen, sal_Int32 nNumberOfBlanks = 0,
+    static TextFrameIndex ThaiJustify( const OUString& rText, long* pKernArray,
+                                  long* pScrArray, TextFrameIndex nIdx,
+                                  TextFrameIndex nLen,
+                                  TextFrameIndex nNumberOfBlanks = TextFrameIndex(0),
                                   long nSpaceAdd = 0 );
 
-    static sal_Int32 CountCJKCharacters( const OUString &rText, sal_Int32 nPos, sal_Int32 nEnd, LanguageType aLang);
+    static TextFrameIndex CountCJKCharacters(const OUString &rText,
+            TextFrameIndex nPos, TextFrameIndex nEnd, LanguageType aLang);
 
     static void CJKJustify( const OUString& rText, long* pKernArray,
-                                  long* pScrArray, sal_Int32 nStt,
-                                  sal_Int32 nLen, LanguageType aLang,
+                                  long* pScrArray, TextFrameIndex nStt,
+                                  TextFrameIndex nLen, LanguageType aLang,
                                   long nSpaceAdd, bool bIsSpaceStop );
 
     static SwScriptInfo* GetScriptInfo( const SwTextNode& rNode,
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index faa412a44d6c..49cb28187867 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -1803,7 +1803,8 @@ sal_Int32 SwScriptInfo::KashidaJustify( long* pKernArray,
 // Checks if the current text is 'Arabic' text. Note that only the first
 // character has to be checked because a ctl portion only contains one
 // script, see NewTextPortion
-bool SwScriptInfo::IsArabicText( const OUString& rText, sal_Int32 nStt, sal_Int32 nLen )
+bool SwScriptInfo::IsArabicText(const OUString& rText,
+        TextFrameIndex const nStt, TextFrameIndex const nLen)
 {
     using namespace ::com::sun::star::i18n;
     static const ScriptTypeList typeList[] = {
@@ -1989,9 +1990,10 @@ void SwScriptInfo::MarkKashidasInvalid(sal_Int32 const nCnt,
     }
 }
 
-sal_Int32 SwScriptInfo::ThaiJustify( const OUString& rText, long* pKernArray,
-                                     long* pScrArray, sal_Int32 nStt,
-                                     sal_Int32 nLen, sal_Int32 nNumberOfBlanks,
+TextFrameIndex SwScriptInfo::ThaiJustify( const OUString& rText, long* pKernArray,
+                                     long* pScrArray, TextFrameIndex const nStt,
+                                     TextFrameIndex const nLen,
+                                     TextFrameIndex nNumberOfBlanks,
                                      long nSpaceAdd )
 {
     SAL_WARN_IF( nStt + nLen > rText.getLength(), "sw.core", "String in ThaiJustify too small" );
@@ -2236,7 +2238,8 @@ void SwScriptInfo::CalcHiddenRanges( const SwTextNode& rNode, MultiSelection& rH
     rNode.SetHiddenCharAttribute( bNewHiddenCharsHidePara, bNewContainsHiddenChars );
 }
 
-sal_Int32 SwScriptInfo::CountCJKCharacters( const OUString &rText, sal_Int32 nPos, sal_Int32 nEnd, LanguageType aLang)
+TextFrameIndex SwScriptInfo::CountCJKCharacters(const OUString &rText,
+    TextFrameIndex nPos, TextFrameIndex const nEnd, LanguageType aLang)
 {
     sal_Int32 nCount = 0;
     if (nEnd > nPos)
@@ -2258,8 +2261,8 @@ sal_Int32 SwScriptInfo::CountCJKCharacters( const OUString &rText, sal_Int32 nPo
 }
 
 void SwScriptInfo::CJKJustify( const OUString& rText, long* pKernArray,
-                                     long* pScrArray, sal_Int32 nStt,
-                                     sal_Int32 nLen, LanguageType aLang,
+                                     long* pScrArray, TextFrameIndex const nStt,
+                                     TextFrameIndex const nLen, LanguageType aLang,
                                      long nSpaceAdd, bool bIsSpaceStop )
 {
     assert( pKernArray != nullptr && nStt >= 0 );
commit 4ac705b2cbeabcc5b059c4e82ddb0260fa21214e
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Wed May 23 18:41:15 2018 +0200

    sw_redlinehide: portxt.cxx
    
    Not sure if these space-counting functions should use TextFrameIndex or
    not, but there's quite a lot of them and half already converted...
    
    Change-Id: I27adbd752eada7cfe8b4782a6e183563b4c057f3

diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx
index 81b6aaad6017..703591b7feed 100644
--- a/sw/source/core/text/portxt.cxx
+++ b/sw/source/core/text/portxt.cxx
@@ -49,8 +49,8 @@ using namespace ::com::sun::star::i18n::ScriptType;
 
 // Returns for how many characters an extra space has to be added
 // (for justified alignment).
-static sal_Int32 lcl_AddSpace( const SwTextSizeInfo &rInf, const OUString* pStr,
-                               const SwLinePortion& rPor )
+static TextFrameIndex lcl_AddSpace(const SwTextSizeInfo &rInf,
+        const OUString* pStr, const SwLinePortion& rPor)
 {
     TextFrameIndex nPos, nEnd;
     const SwScriptInfo* pSI = nullptr;
@@ -69,7 +69,7 @@ static sal_Int32 lcl_AddSpace( const SwTextSizeInfo &rInf, const OUString* pStr,
         pSI = &const_cast<SwParaPortion*>(rInf.GetParaPortion())->GetScriptInfo();
     }
 
-    sal_Int32 nCnt = 0;
+    TextFrameIndex nCnt(0);
     sal_uInt8 nScript = 0;
 
     // If portion consists of Asian characters and language is not
@@ -122,7 +122,7 @@ static sal_Int32 lcl_AddSpace( const SwTextSizeInfo &rInf, const OUString* pStr,
             // i60591: need to check result of KashidaJustify
             // determine if kashida justification is applicable
             if (nKashRes != -1)
-                return nKashRes;
+                return TextFrameIndex(nKashRes);
         }
     }
 
@@ -575,7 +575,7 @@ bool SwTextPortion::GetExpText( const SwTextSizeInfo &, OUString & ) const
 TextFrameIndex SwTextPortion::GetSpaceCnt(const SwTextSizeInfo &rInf,
                                           TextFrameIndex& rCharCnt) const
 {
-    sal_Int32 nCnt = 0;
+    TextFrameIndex nCnt(0);
     TextFrameIndex nPos(0);
 
     if ( rInf.SnapToGrid() )
@@ -613,7 +613,7 @@ TextFrameIndex SwTextPortion::GetSpaceCnt(const SwTextSizeInfo &rInf,
 
 long SwTextPortion::CalcSpacing( long nSpaceAdd, const SwTextSizeInfo &rInf ) const
 {
-    sal_Int32 nCnt = 0;
+    TextFrameIndex nCnt(0);
 
     if ( rInf.SnapToGrid() )
     {
@@ -639,7 +639,7 @@ long SwTextPortion::CalcSpacing( long nSpaceAdd, const SwTextSizeInfo &rInf ) co
             else
             {
                 nSpaceAdd = -nSpaceAdd;
-                nCnt = aStr.getLength();
+                nCnt = TextFrameIndex(aStr.getLength());
             }
         }
     }
@@ -665,7 +665,7 @@ long SwTextPortion::CalcSpacing( long nSpaceAdd, const SwTextSizeInfo &rInf ) co
         }
     }
 
-    return nCnt * nSpaceAdd / SPACING_PRECISION_FACTOR;
+    return sal_Int32(nCnt) * nSpaceAdd / SPACING_PRECISION_FACTOR;
 }
 
 void SwTextPortion::HandlePortion( SwPortionHandler& rPH ) const
commit 41932cdeb76dda8f9b20ff128d6a8d5150128155
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Wed May 23 18:35:01 2018 +0200

    sw_redlinehide: more portxt.cxx
    
    Change-Id: I0400794e30231d98e69569306aeaf9e43a5d5907

diff --git a/sw/source/core/text/portxt.cxx b/sw/source/core/text/portxt.cxx
index 1bef7cfafab0..81b6aaad6017 100644
--- a/sw/source/core/text/portxt.cxx
+++ b/sw/source/core/text/portxt.cxx
@@ -52,14 +52,14 @@ using namespace ::com::sun::star::i18n::ScriptType;
 static sal_Int32 lcl_AddSpace( const SwTextSizeInfo &rInf, const OUString* pStr,
                                const SwLinePortion& rPor )
 {
-    sal_Int32 nPos, nEnd;
+    TextFrameIndex nPos, nEnd;
     const SwScriptInfo* pSI = nullptr;
 
     if ( pStr )
     {
         // passing a string means we are inside a field
-        nPos = 0;
-        nEnd = pStr->getLength();
+        nPos = TextFrameIndex(0);
+        nEnd = TextFrameIndex(pStr->getLength());
     }
     else
     {
@@ -78,7 +78,8 @@ static sal_Int32 lcl_AddSpace( const SwTextSizeInfo &rInf, const OUString* pStr,
     if ( pSI )
         nScript = pSI->ScriptType( nPos );
     else
-        nScript = static_cast<sal_uInt8>(g_pBreakIt->GetBreakIter()->getScriptType( *pStr, nPos ));
+        nScript = static_cast<sal_uInt8>(
+            g_pBreakIt->GetBreakIter()->getScriptType(*pStr, sal_Int32(nPos)));
 
     // Note: rInf.GetIdx() can differ from nPos,
     // e.g., when rPor is a field portion. nPos referes to the string passed
@@ -152,18 +153,18 @@ static sal_Int32 lcl_AddSpace( const SwTextSizeInfo &rInf, const OUString* pStr,
     // Note: We do not want to add space to an isolated latin blank in front
     // of some complex characters in RTL environment
     const bool bDoNotAddSpace =
-            LATIN == nScript && ( nEnd == nPos + 1 ) && pSI &&
+            LATIN == nScript && (nEnd == nPos + TextFrameIndex(1)) && pSI &&
             ( i18n::ScriptType::COMPLEX ==
-              pSI->ScriptType( nPos + 1 ) ) &&
+              pSI->ScriptType(nPos + TextFrameIndex(1))) &&
             rInf.GetTextFrame() && rInf.GetTextFrame()->IsRightToLeft();
 
     if ( bDoNotAddSpace )
         return nCnt;
 
-    sal_Int32 nTextEnd = std::min(nEnd, pStr->getLength());
+    TextFrameIndex nTextEnd = std::min(nEnd, TextFrameIndex(pStr->getLength()));
     for ( ; nPos < nTextEnd; ++nPos )
     {
-        if( CH_BLANK == (*pStr)[ nPos ] )
+        if (CH_BLANK == (*pStr)[ sal_Int32(nPos) ])
             ++nCnt;
     }
 
@@ -173,7 +174,7 @@ static sal_Int32 lcl_AddSpace( const SwTextSizeInfo &rInf, const OUString* pStr,
     // nPos referes to the original string, even if a field string has
     // been passed to this function
     nPos = rInf.GetIdx() + rPor.GetLen();
-    if ( nPos < rInf.GetText().getLength() )
+    if (nPos < TextFrameIndex(rInf.GetText().getLength()))
     {
         sal_uInt8 nNextScript = 0;
         const SwLinePortion* pPor = rPor.GetPortion();
@@ -196,7 +197,8 @@ static sal_Int32 lcl_AddSpace( const SwTextSizeInfo &rInf, const OUString* pStr,
             nNextScript = static_cast<sal_uInt8>(g_pBreakIt->GetBreakIter()->getScriptType( aStr, 0 ));
         }
         else
-            nNextScript = static_cast<sal_uInt8>(g_pBreakIt->GetBreakIter()->getScriptType( rInf.GetText(), nPos ));
+            nNextScript = static_cast<sal_uInt8>(
+                g_pBreakIt->GetBreakIter()->getScriptType(rInf.GetText(), sal_Int32(nPos)));
 
         if( ASIAN == nNextScript )
         {
@@ -574,7 +576,7 @@ TextFrameIndex SwTextPortion::GetSpaceCnt(const SwTextSizeInfo &rInf,
                                           TextFrameIndex& rCharCnt) const
 {
     sal_Int32 nCnt = 0;
-    sal_Int32 nPos = 0;
+    TextFrameIndex nPos(0);
 
     if ( rInf.SnapToGrid() )
     {
@@ -597,7 +599,7 @@ TextFrameIndex SwTextPortion::GetSpaceCnt(const SwTextSizeInfo &rInf,
             const_cast<SwTextSizeInfo &>(rInf).SetOnWin( bOldOnWin );
 
             nCnt = nCnt + lcl_AddSpace( rInf, &aStr, *this );
-            nPos = aStr.getLength();
+            nPos = TextFrameIndex(aStr.getLength());
         }
     }
     else if( !IsDropPortion() )
commit c455ceb9716d39e00f1bbfd5a3e1520809fed257
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Wed May 23 18:01:48 2018 +0200

    sw_redlinehide: convert SwTextFrame::PrepareVisualMove()
    
    Change-Id: Icc9a7f44ad10f0ea556681d832bc3716e9341da7

diff --git a/sw/source/core/text/frmcrsr.cxx b/sw/source/core/text/frmcrsr.cxx
index c0ba1765beee..c7c53d83e4f9 100644
--- a/sw/source/core/text/frmcrsr.cxx
+++ b/sw/source/core/text/frmcrsr.cxx
@@ -1075,18 +1075,19 @@ void SwTextFrame::PrepareVisualMove(TextFrameIndex & nPos, sal_uInt8& nCursorLev
 
     // Bidi functions from icu 2.0
 
-    const sal_Unicode* pLineString = GetTextNode()->GetText().getStr();
+    const sal_Unicode* pLineString = GetText().getStr();
 
     UErrorCode nError = U_ZERO_ERROR;
-    UBiDi* pBidi = ubidi_openSized( nLen, 0, &nError );
-    ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(pLineString), nLen, nDefaultDir, nullptr, &nError );
+    UBiDi* pBidi = ubidi_openSized( sal_Int32(nLen), 0, &nError );
+    ubidi_setPara( pBidi, reinterpret_cast<const UChar *>(pLineString),
+                    sal_Int32(nLen), nDefaultDir, nullptr, &nError );
 
-    sal_Int32 nTmpPos = 0;
+    TextFrameIndex nTmpPos(0);
     bool bOutOfBounds = false;
 
     if ( nPos < nStt + nLen )
     {
-        nTmpPos = ubidi_getVisualIndex( pBidi, nPos, &nError );
+        nTmpPos = TextFrameIndex(ubidi_getVisualIndex( pBidi, sal_Int32(nPos), &nError ));
 
         // visual indices are always LTR aligned
         if ( bVisualRight )
@@ -1117,7 +1118,7 @@ void SwTextFrame::PrepareVisualMove(TextFrameIndex & nPos, sal_uInt8& nCursorLev
 
     if ( ! bOutOfBounds )
     {
-        nPos = ubidi_getLogicalIndex( pBidi, nTmpPos, &nError );
+        nPos = TextFrameIndex(ubidi_getLogicalIndex( pBidi, sal_Int32(nTmpPos), &nError ));
 
         if ( bForward )
         {
commit 18833b2add6f81f04fa03c7858e96263de9ec764
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Wed May 23 17:33:20 2018 +0200

    sw_redlinehide: split up SwScriptInfo::WhichFont confusion
    
    Change-Id: Ic300ddc7fba4294317096c17b9b907b8b794b646

diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index 0100a1b4cefd..9a92a06557cf 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -367,7 +367,8 @@ public:
     static SwScriptInfo* GetScriptInfo( const SwTextNode& rNode,
                                         bool bAllowInvalid = false );
 
-    static SwFontScript WhichFont(sal_Int32 nIdx, const OUString* pText, const SwScriptInfo* pSI);
+    SwFontScript WhichFont(TextFrameIndex nIdx) const;
+    static SwFontScript WhichFont(sal_Int32 nIdx, OUString const & rText);
 };
 
 #endif
diff --git a/sw/source/core/text/frmpaint.cxx b/sw/source/core/text/frmpaint.cxx
index 3a7de75f3067..217615337e37 100644
--- a/sw/source/core/text/frmpaint.cxx
+++ b/sw/source/core/text/frmpaint.cxx
@@ -190,7 +190,7 @@ void SwExtraPainter::PaintExtra( SwTwips nY, long nAsc, long nMax, bool bRed )
                                 : rLineInf.GetDivider() );
 
     // Get script type of line numbering:
-    pFnt->SetActual( SwScriptInfo::WhichFont( 0, &aTmp, nullptr ) );
+    pFnt->SetActual( SwScriptInfo::WhichFont(0, aTmp) );
 
     SwDrawTextInfo aDrawInf( pSh, *pSh->GetOut(), aTmp, 0, aTmp.getLength() );
     aDrawInf.SetSpace( 0 );
diff --git a/sw/source/core/text/itratr.cxx b/sw/source/core/text/itratr.cxx
index 4db4b7eac5ba..5f31abd3ae51 100644
--- a/sw/source/core/text/itratr.cxx
+++ b/sw/source/core/text/itratr.cxx
@@ -374,7 +374,7 @@ bool SwAttrIter::Seek(TextFrameIndex const nNewPos)
         }
     }
 
-    m_pFont->SetActual( SwScriptInfo::WhichFont( nNewPos, nullptr, m_pScriptInfo ) );
+    m_pFont->SetActual( m_pScriptInfo->WhichFont(nNewPos) );
 
     if( m_pRedline )
         m_nChgCnt = m_nChgCnt + m_pRedline->Seek(*m_pFont, newPos.first->GetIndex(), newPos.second, m_nPosition);
diff --git a/sw/source/core/text/itrcrsr.cxx b/sw/source/core/text/itrcrsr.cxx
index 636121362f0a..186261fda6ff 100644
--- a/sw/source/core/text/itrcrsr.cxx
+++ b/sw/source/core/text/itrcrsr.cxx
@@ -100,7 +100,7 @@ static void lcl_GetCharRectInsideField( SwTextSizeInfo& rInf, SwRect& rOrig,
         if ( pString )
         {
             // get script for field portion
-            rInf.GetFont()->SetActual( SwScriptInfo::WhichFont( 0, pString, nullptr ) );
+            rInf.GetFont()->SetActual( SwScriptInfo::WhichFont(0, *pString) );
 
             TextFrameIndex const nOldLen = pPor->GetLen();
             const_cast<SwLinePortion*>(pPor)->SetLen(TextFrameIndex(nLen - 1));
diff --git a/sw/source/core/text/itrform2.cxx b/sw/source/core/text/itrform2.cxx
index 86e59b0effdf..4b3455c79dbe 100755
--- a/sw/source/core/text/itrform2.cxx
+++ b/sw/source/core/text/itrform2.cxx
@@ -638,7 +638,7 @@ void SwTextFormatter::BuildPortions( SwTextFormatInfo &rInf )
             const SwFontScript nCurrScript = m_pFont->GetActual(); // pScriptInfo->ScriptType( rInf.GetIdx() );
             const SwFontScript nNextScript = nTmp >= rInf.GetText().getLength() ?
                                      SwFontScript::CJK :
-                                     SwScriptInfo::WhichFont( nTmp, nullptr, m_pScriptInfo );
+                                     m_pScriptInfo->WhichFont(nTmp);
 
             // snap non-asian text to grid if next portion is ASIAN or
             // there are no more portions in this line
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index ffa510b1a570..faa412a44d6c 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -680,13 +680,8 @@ SwScriptInfo::~SwScriptInfo()
 
 // Converts i18n Script Type (LATIN, ASIAN, COMPLEX, WEAK) to
 // Sw Script Types (SwFontScript::Latin, SwFontScript::CJK, SwFontScript::CTL), used to identify the font
-SwFontScript SwScriptInfo::WhichFont( sal_Int32 nIdx, const OUString* pText, const SwScriptInfo* pSI )
+static SwFontScript lcl_ScriptToFont(sal_uInt16 const nScript)
 {
-    assert((pSI || pText) && "How should I determine the script type?");
-    const sal_uInt16 nScript = pSI
-        ? pSI->ScriptType( nIdx )                         // use our SwScriptInfo if available
-        : g_pBreakIt->GetRealScriptOfText( *pText, nIdx ); // else  ask the break iterator
-
     switch ( nScript ) {
         case i18n::ScriptType::LATIN : return SwFontScript::Latin;
         case i18n::ScriptType::ASIAN : return SwFontScript::CJK;
@@ -697,6 +692,18 @@ SwFontScript SwScriptInfo::WhichFont( sal_Int32 nIdx, const OUString* pText, con
     return SwFontScript::Latin;
 }
 
+SwFontScript SwScriptInfo::WhichFont(TextFrameIndex const nIdx) const
+{
+    const sal_uInt16 nScript(ScriptType(nIdx));
+    return lcl_ScriptToFont(nScript);
+}
+
+SwFontScript SwScriptInfo::WhichFont(sal_Int32 nIdx, OUString const& rText)
+{
+    const sal_uInt16 nScript(g_pBreakIt->GetRealScriptOfText(rText, nIdx));
+    return lcl_ScriptToFont(nScript);
+}
+
 // searches for script changes in rText and stores them
 void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
         sw::MergedPara const*const pMerged)
diff --git a/sw/source/core/text/pormulti.cxx b/sw/source/core/text/pormulti.cxx
index 2e4cbf836ccd..0af3e2368d0a 100644
--- a/sw/source/core/text/pormulti.cxx
+++ b/sw/source/core/text/pormulti.cxx
@@ -309,14 +309,14 @@ SwDoubleLinePortion::SwDoubleLinePortion(
     if( pBracket->cPre > 255 )
     {
         OUString aText = OUString(pBracket->cPre);
-        nTmp = SwScriptInfo::WhichFont( 0, &aText, nullptr );
+        nTmp = SwScriptInfo::WhichFont(0, aText);
     }
     pBracket->nPreScript = nTmp;
     nTmp = SW_SCRIPTS;
     if( pBracket->cPost > 255 )
     {
         OUString aText = OUString(pBracket->cPost);
-        nTmp = SwScriptInfo::WhichFont( 0, &aText, nullptr );
+        nTmp = SwScriptInfo::WhichFont(0, aText);
     }
     pBracket->nPostScript = nTmp;
 
diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx
index ee4d788a4bc9..5c6b6e2a307d 100644
--- a/sw/source/core/text/redlnitr.cxx
+++ b/sw/source/core/text/redlnitr.cxx
@@ -150,9 +150,9 @@ void SwAttrIter::InitFontAndAttrHandler(SwTextNode const& rTextNode,
 
     assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
 
-    m_pFont->SetActual( SwScriptInfo::WhichFont( 0, nullptr, m_pScriptInfo ) );
+    m_pFont->SetActual( m_pScriptInfo->WhichFont(TextFrameIndex(0)) );
 
-    sal_Int32 nChg = 0;
+    TextFrameIndex nChg(0);
     size_t nCnt = 0;
 
     do
@@ -177,7 +177,7 @@ void SwAttrIter::InitFontAndAttrHandler(SwTextNode const& rTextNode,
             m_pFont->GetMagic( m_aMagicNo[ nTmp ], m_aFontIdx[ nTmp ], nTmp );
         }
     }
-    while (nChg < rText.getLength());
+    while (nChg < TextFrameIndex(rText.getLength()));
 }
 
 void SwAttrIter::CtorInitAttrIter(SwTextNode & rTextNode,
diff --git a/sw/source/core/text/txtftn.cxx b/sw/source/core/text/txtftn.cxx
index 6dba5849218b..bd9cf48c0967 100644
--- a/sw/source/core/text/txtftn.cxx
+++ b/sw/source/core/text/txtftn.cxx
@@ -1251,7 +1251,7 @@ SwFootnoteSave::SwFootnoteSave( const SwTextSizeInfo &rInf,
         {
             // examine text and set script
             OUString aTmpStr( rFootnote.GetViewNumStr( *pDoc ) );
-            pFnt->SetActual( SwScriptInfo::WhichFont( 0, &aTmpStr, nullptr ) );
+            pFnt->SetActual( SwScriptInfo::WhichFont(0, aTmpStr) );
         }
 
         const SwEndNoteInfo* pInfo;
commit 9094a95ab9b87d198d533804aa449401a06e017b
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Wed May 23 16:19:21 2018 +0200

    sw_redlinehide: trivial conversions in SwScriptInfo
    
    Change-Id: Idab0b0a351c5f1ee176f9a2c8f1d3780e21ecf26

diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index fa27754cf245..ffa510b1a570 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -730,10 +730,10 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
 
     // SCRIPT AND SCRIPT RELATED INFORMATION
 
-    sal_Int32 nChg = m_nInvalidityPos;
+    TextFrameIndex nChg = m_nInvalidityPos;
 
     // COMPLETE_STRING means the data structure is up to date
-    m_nInvalidityPos = COMPLETE_STRING;
+    m_nInvalidityPos = TextFrameIndex(COMPLETE_STRING);
 
     // this is the default direction
     m_nDefaultDir = static_cast<sal_uInt8>(bRTL ? UBIDI_RTL : UBIDI_LTR);
@@ -799,18 +799,18 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
     if ( nChg )
         --nChg;
 
-    const sal_Int32 nGrpStart = nCnt ? GetScriptChg( nCnt - 1 ) : 0;
+    const TextFrameIndex nGrpStart = nCnt ? GetScriptChg(nCnt - 1) : TextFrameIndex(0);
 
     // we go back in our group until we reach the first character of
     // type nScript
     while ( nChg > nGrpStart &&
-            nScript != g_pBreakIt->GetBreakIter()->getScriptType( rText, nChg ) )
+            nScript != g_pBreakIt->GetBreakIter()->getScriptType(rText, sal_Int32(nChg)))
         --nChg;
 
     // If we are at the start of a group, we do not trust nScript,
     // we better get nScript from the breakiterator:
     if ( nChg == nGrpStart )
-        nScript = static_cast<sal_uInt8>(g_pBreakIt->GetBreakIter()->getScriptType( rText, nChg ));
+        nScript = static_cast<sal_uInt8>(g_pBreakIt->GetBreakIter()->getScriptType(rText, sal_Int32(nChg)));
 
     // INVALID DATA FROM THE SCRIPT INFO ARRAYS HAS TO BE DELETED:
 
@@ -818,7 +818,7 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
     m_ScriptChanges.erase(m_ScriptChanges.begin() + nCnt, m_ScriptChanges.end());
 
     // get the start of the last compression group
-    sal_Int32 nLastCompression = nChg;
+    TextFrameIndex nLastCompression = nChg;
     if( nCntComp )
     {
         --nCntComp;
@@ -835,7 +835,7 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
             m_CompressionChanges.end());
 
     // get the start of the last kashida group
-    sal_Int32 nLastKashida = nChg;
+    TextFrameIndex nLastKashida = nChg;
     if( nCntKash && i18n::ScriptType::COMPLEX == nScript )
     {
         --nCntKash;
@@ -848,17 +848,17 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
     // TAKE CARE OF WEAK CHARACTERS: WE MUST FIND AN APPROPRIATE
     // SCRIPT FOR WEAK CHARACTERS AT THE BEGINNING OF A PARAGRAPH
 
-    if( WEAK == g_pBreakIt->GetBreakIter()->getScriptType( rText, nChg ) )
+    if (WEAK == g_pBreakIt->GetBreakIter()->getScriptType(rText, sal_Int32(nChg)))
     {
         // If the beginning of the current group is weak, this means that
         // all of the characters in this group are weak. We have to assign
         // the scripts to these characters depending on the fonts which are
         // set for these characters to display them.
-        sal_Int32 nEnd =
-                g_pBreakIt->GetBreakIter()->endOfScript( rText, nChg, WEAK );
+        TextFrameIndex nEnd = TextFrameIndex(
+            g_pBreakIt->GetBreakIter()->endOfScript(rText, sal_Int32(nChg), WEAK));
 
-        if (nEnd > rText.getLength() || nEnd < 0)
-            nEnd = rText.getLength();
+        if (nEnd > TextFrameIndex(rText.getLength()) || nEnd < TextFrameIndex(0))
+            nEnd = TextFrameIndex(rText.getLength());
 
         nScript = SvtLanguageOptions::GetI18NScriptTypeOfLanguage( GetAppLanguage() );
 
@@ -869,9 +869,9 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
         nChg = nEnd;
 
         // Get next script type or set to weak in order to exit
-        sal_uInt8 nNextScript = ( nEnd < rText.getLength() ) ?
-           static_cast<sal_uInt8>(g_pBreakIt->GetBreakIter()->getScriptType( rText, nEnd )) :
-           sal_uInt8(WEAK);
+        sal_uInt8 nNextScript = (nEnd < TextFrameIndex(rText.getLength()))
+            ? static_cast<sal_uInt8>(g_pBreakIt->GetBreakIter()->getScriptType(rText, sal_Int32(nEnd)))
+            : sal_uInt8(WEAK);
 
         if ( nScript != nNextScript )
         {
@@ -883,45 +883,53 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
 
     // UPDATE THE SCRIPT INFO ARRAYS:
 
-    while (nChg < rText.getLength() || (m_ScriptChanges.empty() && rText.isEmpty()))
+    while (nChg < TextFrameIndex(rText.getLength())
+           || (m_ScriptChanges.empty() && rText.isEmpty()))
     {
         SAL_WARN_IF( i18n::ScriptType::WEAK == nScript,
                 "sw.core", "Inserting WEAK into SwScriptInfo structure" );
 
-        sal_Int32 nSearchStt = nChg;
-        nChg = g_pBreakIt->GetBreakIter()->endOfScript( rText, nSearchStt, nScript );
+        TextFrameIndex nSearchStt = nChg;
+        nChg = TextFrameIndex(g_pBreakIt->GetBreakIter()->endOfScript(
+                    rText, sal_Int32(nSearchStt), nScript));
 
-        if (nChg > rText.getLength() || nChg < 0)
-            nChg = rText.getLength();
+        if (nChg > TextFrameIndex(rText.getLength()) || nChg < TextFrameIndex(0))
+            nChg = TextFrameIndex(rText.getLength());
 
         // #i28203#
         // for 'complex' portions, we make sure that a portion does not contain more
         // than one script:
         if( i18n::ScriptType::COMPLEX == nScript )
         {
-            const short nScriptType = ScriptTypeDetector::getCTLScriptType( rText, nSearchStt );
-            sal_Int32 nNextCTLScriptStart = nSearchStt;
+            const short nScriptType = ScriptTypeDetector::getCTLScriptType(
+                    rText, sal_Int32(nSearchStt) );
+            TextFrameIndex nNextCTLScriptStart = nSearchStt;
             short nCurrentScriptType = nScriptType;
             while( css::i18n::CTLScriptType::CTL_UNKNOWN == nCurrentScriptType || nScriptType == nCurrentScriptType )
             {
-                nNextCTLScriptStart = ScriptTypeDetector::endOfCTLScriptType( rText, nNextCTLScriptStart );
-                if( nNextCTLScriptStart >= rText.getLength() || nNextCTLScriptStart >= nChg )
+                nNextCTLScriptStart = TextFrameIndex(
+                        ScriptTypeDetector::endOfCTLScriptType(
+                            rText, sal_Int32(nNextCTLScriptStart)));
+                if (nNextCTLScriptStart >= TextFrameIndex(rText.getLength())
+                    || nNextCTLScriptStart >= nChg)
                     break;
-                nCurrentScriptType = ScriptTypeDetector::getCTLScriptType( rText, nNextCTLScriptStart );
+                nCurrentScriptType = ScriptTypeDetector::getCTLScriptType(
+                                        rText, sal_Int32(nNextCTLScriptStart));
             }
             nChg = std::min( nChg, nNextCTLScriptStart );
         }
 
         // special case for dotted circle since it can be used with complex
         // before a mark, so we want it associated with the mark's script
-        if (nChg < rText.getLength() && nChg > 0 && (i18n::ScriptType::WEAK ==
-            g_pBreakIt->GetBreakIter()->getScriptType(rText,nChg - 1)))
+        if (nChg < TextFrameIndex(rText.getLength()) && nChg > TextFrameIndex(0)
+            && (i18n::ScriptType::WEAK ==
+                g_pBreakIt->GetBreakIter()->getScriptType(rText, sal_Int32(nChg) - 1)))
         {
-            int8_t nType = u_charType(rText[nChg] );
+            int8_t nType = u_charType(rText[sal_Int32(nChg)]);
             if (nType == U_NON_SPACING_MARK || nType == U_ENCLOSING_MARK ||
                 nType == U_COMBINING_SPACING_MARK )
             {
-                m_ScriptChanges.emplace_back(nChg-1, nScript);
+                m_ScriptChanges.emplace_back(nChg-TextFrameIndex(1), nScript);
             }
             else
             {
@@ -941,11 +949,11 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
         {
             CompType ePrevState = NONE;
             CompType eState = NONE;
-            sal_Int32 nPrevChg = nLastCompression;
+            TextFrameIndex nPrevChg = nLastCompression;
 
             while ( nLastCompression < nChg )
             {
-                sal_Unicode cChar = rText[ nLastCompression ];
+                sal_Unicode cChar = rText[ sal_Int32(nLastCompression) ];
 
                 // examine current character
                 switch ( cChar )
@@ -1168,8 +1176,8 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
             } // end of kashida search
         }
 
-        if ( nChg < rText.getLength() )
-            nScript = static_cast<sal_uInt8>(g_pBreakIt->GetBreakIter()->getScriptType( rText, nChg ));
+        if (nChg < TextFrameIndex(rText.getLength()))
+            nScript = static_cast<sal_uInt8>(g_pBreakIt->GetBreakIter()->getScriptType(rText, sal_Int32(nChg)));
 
         nLastCompression = nChg;
         nLastKashida = nChg;
@@ -1177,11 +1185,11 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
 
 #if OSL_DEBUG_LEVEL > 0
     // check kashida data
-    long nTmpKashidaPos = -1;
+    TextFrameIndex nTmpKashidaPos(-1);
     bool bWrongKash = false;
     for (size_t i = 0; i < m_Kashida.size(); ++i)
     {
-        long nCurrKashidaPos = GetKashida( i );
+        TextFrameIndex nCurrKashidaPos = GetKashida( i );
         if ( nCurrKashidaPos <= nTmpKashidaPos )
         {
             bWrongKash = true;
@@ -1207,12 +1215,13 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
         {
             const sal_uInt8 nCurrDirType = GetDirType( nDirIdx );
                 // nStart is start of RTL run:
-                const sal_Int32 nStart = nDirIdx > 0 ? GetDirChg( nDirIdx - 1 ) : 0;
+            const TextFrameIndex nStart = nDirIdx > 0 ? GetDirChg(nDirIdx - 1) : TextFrameIndex(0);
                 // nEnd is end of RTL run:
-                const sal_Int32 nEnd = GetDirChg( nDirIdx );
+            const TextFrameIndex nEnd = GetDirChg( nDirIdx );
 
             if ( nCurrDirType % 2 == UBIDI_RTL  || // text in RTL run
-                ( nCurrDirType > UBIDI_LTR && !lcl_HasStrongLTR( rText, nStart, nEnd ) ) ) // non-strong text in embedded LTR run
+                (nCurrDirType > UBIDI_LTR && // non-strong text in embedded LTR run
+                 !lcl_HasStrongLTR(rText, sal_Int32(nStart), sal_Int32(nEnd))))
             {
                 // nScriptIdx points into the ScriptArrays:
                 size_t nScriptIdx = 0;
@@ -1224,7 +1233,9 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
                 while ( GetScriptChg( nScriptIdx ) <= nStart )
                     ++nScriptIdx;
 
-                const sal_Int32 nStartPosOfGroup = nScriptIdx ? GetScriptChg( nScriptIdx - 1 ) : 0;
+                const TextFrameIndex nStartPosOfGroup = nScriptIdx
+                        ? GetScriptChg(nScriptIdx - 1)
+                        : TextFrameIndex(0);
                 const sal_uInt8 nScriptTypeOfGroup = GetScriptType( nScriptIdx );
 
                 SAL_WARN_IF( nStartPosOfGroup > nStart || GetScriptChg( nScriptIdx ) <= nStart,
@@ -1233,7 +1244,7 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
                 // Check if we have to insert a new script change at
                 // position nStart. If nStartPosOfGroup < nStart,
                 // we have to insert a new script change:
-                if ( nStart > 0 && nStartPosOfGroup < nStart )
+                if (nStart > TextFrameIndex(0) && nStartPosOfGroup < nStart)
                 {
                     m_ScriptChanges.insert(m_ScriptChanges.begin() + nScriptIdx,
                                           ScriptChangeInfo(nStart, nScriptTypeOfGroup) );
@@ -1291,7 +1302,7 @@ void SwScriptInfo::UpdateBidiInfo( const OUString& rText )
     for ( int nIdx = 0; nIdx < nCount; ++nIdx )
     {
         ubidi_getLogicalRun( pBidi, nStart, &nEnd, &nCurrDir );
-        m_DirectionChanges.emplace_back(nEnd, nCurrDir);
+        m_DirectionChanges.emplace_back(TextFrameIndex(nEnd), nCurrDir);
         nStart = nEnd;
     }
 
@@ -1314,7 +1325,7 @@ TextFrameIndex SwScriptInfo::NextScriptChg(const TextFrameIndex nPos)  const
             return GetScriptChg( nX );
     }
 
-    return COMPLETE_STRING;
+    return TextFrameIndex(COMPLETE_STRING);
 }
 
 // returns the script of the character at the input position
@@ -1343,7 +1354,7 @@ TextFrameIndex SwScriptInfo::NextDirChg(const TextFrameIndex nPos,
             return GetDirChg( nX );
     }
 
-    return COMPLETE_STRING;
+    return TextFrameIndex(COMPLETE_STRING);
 }
 
 sal_uInt8 SwScriptInfo::DirType(const TextFrameIndex nPos) const
@@ -1503,14 +1514,14 @@ bool SwScriptInfo::GetBoundsOfHiddenRange(TextFrameIndex nPos,
         TextFrameIndex & rnStartPos, TextFrameIndex & rnEndPos,
         PositionList *const pList) const
 {
-    rnStartPos = COMPLETE_STRING;
-    rnEndPos = 0;
+    rnStartPos = TextFrameIndex(COMPLETE_STRING);
+    rnEndPos = TextFrameIndex(0);
 
     const size_t nEnd = CountHiddenChg();
     for( size_t nX = 0; nX < nEnd; ++nX )
     {
-        const sal_Int32 nHiddenStart = GetHiddenChg( nX++ );
-        const sal_Int32 nHiddenEnd = GetHiddenChg( nX );
+        const TextFrameIndex nHiddenStart = GetHiddenChg( nX++ );
+        const TextFrameIndex nHiddenEnd = GetHiddenChg( nX );
 
         if ( nHiddenStart > nPos )
             break;
@@ -1549,7 +1560,7 @@ SwScriptInfo::CompType SwScriptInfo::DbgCompType(const TextFrameIndex nPos) cons
     const size_t nEnd = CountCompChg();
     for( size_t nX = 0; nX < nEnd; ++nX )
     {
-        const sal_Int32 nChg = GetCompStart( nX );
+        const TextFrameIndex nChg = GetCompStart(nX);
 
         if ( nPos < nChg )
             return NONE;
@@ -1566,12 +1577,12 @@ SwScriptInfo::CompType SwScriptInfo::DbgCompType(const TextFrameIndex nPos) cons
 size_t SwScriptInfo::HasKana(TextFrameIndex const nStart, TextFrameIndex const nLen) const
 {
     const size_t nCnt = CountCompChg();
-    sal_Int32 nEnd = nStart + nLen;
+    TextFrameIndex nEnd = nStart + nLen;
 
     for( size_t nX = 0; nX < nCnt; ++nX )
     {
-        sal_Int32 nKanaStart  = GetCompStart( nX );
-        sal_Int32 nKanaEnd = nKanaStart + GetCompLen( nX );
+        TextFrameIndex nKanaStart  = GetCompStart(nX);
+        TextFrameIndex nKanaEnd = nKanaStart + GetCompLen(nX);
 
         if ( nKanaStart >= nEnd )
             return SAL_MAX_SIZE;
@@ -1602,14 +1613,14 @@ long SwScriptInfo::Compress(long* pKernArray, TextFrameIndex nIdx, TextFrameInde
     if ( SAL_MAX_SIZE == nCompIdx )
         return 0;
 
-    sal_Int32 nChg = GetCompStart( nCompIdx );
-    sal_Int32 nCompLen = GetCompLen( nCompIdx );
+    TextFrameIndex nChg = GetCompStart( nCompIdx );
+    TextFrameIndex nCompLen = GetCompLen( nCompIdx );
     sal_Int32 nI = 0;
     nLen += nIdx;
 
     if( nChg > nIdx )
     {
-        nI = nChg - nIdx;
+        nI = sal_Int32(nChg - nIdx);
         nIdx = nChg;
     }
     else if( nIdx < nChg + nCompLen )
@@ -1676,7 +1687,7 @@ long SwScriptInfo::Compress(long* pKernArray, TextFrameIndex nIdx, TextFrameInde
         if( nIdx >= nLen )
             break;
 
-        sal_Int32 nTmpChg = nLen;
+        TextFrameIndex nTmpChg = nLen;
         if( ++nCompIdx < nCompCount )
         {
             nTmpChg = GetCompStart( nCompIdx );
@@ -1721,7 +1732,7 @@ sal_Int32 SwScriptInfo::KashidaJustify( long* pKernArray,
         ++nCntKash;
     }
 
-    const sal_Int32 nEnd = nStt + nLen;
+    const TextFrameIndex nEnd = nStt + nLen;
 
     size_t nCntKashEnd = nCntKash;
     while ( nCntKashEnd < CountKashida() )
@@ -1748,12 +1759,14 @@ sal_Int32 SwScriptInfo::KashidaJustify( long* pKernArray,
         while (nCntKash < nCntKashEnd && !IsKashidaValid(nCntKash))
             ++nCntKash;
 
-        sal_Int32 nIdx = nCntKash < nCntKashEnd && IsKashidaValid(nCntKash) ? GetKashida(nCntKash) : nEnd;
+        TextFrameIndex nIdx = nCntKash < nCntKashEnd && IsKashidaValid(nCntKash)
+            ? GetKashida(nCntKash)
+            : nEnd;
         long nKashAdd = nSpaceAdd;
 
         while ( nIdx < nEnd )
         {
-            sal_Int32 nArrayPos = nIdx - nStt;
+            TextFrameIndex nArrayPos = nIdx - nStt;
 
             // next kashida position
             ++nCntKash;
@@ -1764,13 +1777,13 @@ sal_Int32 SwScriptInfo::KashidaJustify( long* pKernArray,
             if ( nIdx > nEnd )
                 nIdx = nEnd;
 
-            const sal_Int32 nArrayEnd = nIdx - nStt;
+            const TextFrameIndex nArrayEnd = nIdx - nStt;
 
             while ( nArrayPos < nArrayEnd )
             {
-                pKernArray[ nArrayPos ] += nKashAdd;
+                pKernArray[ sal_Int32(nArrayPos) ] += nKashAdd;
                 if ( pScrArray )
-                    pScrArray[ nArrayPos ] += nKashAdd;
+                    pScrArray[ sal_Int32(nArrayPos) ] += nKashAdd;
                 ++nArrayPos;
             }
             nKashAdd += nSpaceAdd;
@@ -1857,7 +1870,7 @@ bool SwScriptInfo::MarkOrClearKashidaInvalid(
         nCntKash++;
     }
 
-    const sal_Int32 nEnd = nStt + nLen;
+    const TextFrameIndex nEnd = nStt + nLen;
 
     while ( nCntKash < CountKashida() )
     {
@@ -1900,7 +1913,7 @@ void SwScriptInfo::GetKashidaPositions(
         nCntKash++;
     }
 
-    const sal_Int32 nEnd = nStt + nLen;
+    const TextFrameIndex nEnd = nStt + nLen;
 
     size_t nCntKashEnd = nCntKash;
     while ( nCntKashEnd < CountKashida() )
@@ -2018,7 +2031,8 @@ SwScriptInfo* SwScriptInfo::GetScriptInfo( const SwTextNode& rTNd,
         pScriptInfo = const_cast<SwScriptInfo*>(pLast->GetScriptInfo());
         if ( pScriptInfo )
         {
-            if ( bAllowInvalid || COMPLETE_STRING == pScriptInfo->GetInvalidityA() )
+            if (bAllowInvalid ||
+                TextFrameIndex(COMPLETE_STRING) == pScriptInfo->GetInvalidityA())
                 break;
             pScriptInfo = nullptr;
         }
commit 91f2f6edaf47dac818be29bc981784119870c66a
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Wed May 23 14:29:42 2018 +0200

    sw_redlinehide: SwScriptInfo must be inited with MergedPara
    
    Change-Id: Ie7c9e6aa960ec5d3ac90f1aef0ea6c2a7f7cb92b

diff --git a/sw/source/core/edit/editsh.cxx b/sw/source/core/edit/editsh.cxx
index 2d206ba1d935..b5f8dbc1cee8 100644
--- a/sw/source/core/edit/editsh.cxx
+++ b/sw/source/core/edit/editsh.cxx
@@ -135,19 +135,27 @@ void SwEditShell::Insert2(const OUString &rStr, const bool bForceExpandHints )
             if ( ! pSI )
             {
                 // seems to be an empty paragraph.
-                Point aPt;
-                SwContentFrame* pFrame =
-                        static_cast<SwTextNode&>(rNode).getLayoutFrame( GetLayout(), &aPt, pTmpCursor->GetPoint(),
-                                                    false );
+                Point aPt; // why ???
+                SwTextFrame *const pFrame = static_cast<SwTextFrame*>(
+                        static_cast<SwTextNode&>(rNode).getLayoutFrame(
+                            GetLayout(), &aPt, pTmpCursor->GetPoint(), false));
 
                 SwScriptInfo aScriptInfo;
-                aScriptInfo.InitScriptInfo( static_cast<SwTextNode&>(rNode), pFrame->IsRightToLeft() );
+                aScriptInfo.InitScriptInfo(static_cast<SwTextNode&>(rNode),
+                        pFrame->GetMergedPara(), pFrame->IsRightToLeft());
                 nLevel = aScriptInfo.DirType( nPrevPos );
             }
             else
             {
-                if ( COMPLETE_STRING != pSI->GetInvalidityA() )
-                    pSI->InitScriptInfo( static_cast<SwTextNode&>(rNode) );
+                if (TextFrameIndex(COMPLETE_STRING) != pSI->GetInvalidityA())
+                {
+                    // note: if pSI was found, there must be a frame
+                    SwTextFrame *const pFrame = static_cast<SwTextFrame*>(
+                        static_cast<SwTextNode&>(rNode).getLayoutFrame(
+                            GetLayout(), nullptr, pTmpCursor->GetPoint(), false));
+                    // mystery why this doesn't use the other overload?
+                    pSI->InitScriptInfo(static_cast<SwTextNode&>(rNode), pFrame->GetMergedPara());
+                }
                 nLevel = pSI->DirType( nPrevPos );
             }
 
diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index 6645c1105e30..0100a1b4cefd 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -32,6 +32,7 @@ class Point;
 class MultiSelection;
 typedef std::vector< sal_Int32 > PositionList;
 enum class SwFontScript;
+namespace sw { struct MergedPara; }
 
 #define SPACING_PRECISION_FACTOR 100
 
@@ -100,8 +101,8 @@ public:
     ~SwScriptInfo();
 
     // determines script changes
-    void InitScriptInfo( const SwTextNode& rNode, bool bRTL );
-    void InitScriptInfo( const SwTextNode& rNode );
+    void InitScriptInfo(const SwTextNode& rNode, sw::MergedPara const* pMerged, bool bRTL);
+    void InitScriptInfo(const SwTextNode& rNode, sw::MergedPara const* pMerged);
 
     // set/get position from which data is invalid
     void SetInvalidityA(const TextFrameIndex nPos)
diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx
index 2e4569db97af..fa27754cf245 100644
--- a/sw/source/core/text/porlay.cxx
+++ b/sw/source/core/text/porlay.cxx
@@ -698,16 +698,18 @@ SwFontScript SwScriptInfo::WhichFont( sal_Int32 nIdx, const OUString* pText, con
 }
 
 // searches for script changes in rText and stores them
-void SwScriptInfo::InitScriptInfo( const SwTextNode& rNode )
+void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
+        sw::MergedPara const*const pMerged)
 {
-    InitScriptInfo( rNode, m_nDefaultDir == UBIDI_RTL );
+    InitScriptInfo( rNode, pMerged, m_nDefaultDir == UBIDI_RTL );
 }
 
-void SwScriptInfo::InitScriptInfo( const SwTextNode& rNode, bool bRTL )
+void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode,
+        sw::MergedPara const*const pMerged, bool bRTL)
 {
     assert(g_pBreakIt && g_pBreakIt->GetBreakIter().is());
 
-    const OUString& rText = rNode.GetText();
+    const OUString& rText(pMerged ? pMerged->mergedText : rNode.GetText());
 
     // HIDDEN TEXT INFORMATION
 
@@ -748,9 +750,9 @@ void SwScriptInfo::InitScriptInfo( const SwTextNode& rNode, bool bRTL )
     // compression type
     const CharCompressType aCompEnum = rNode.getIDocumentSettingAccess()->getCharacterCompressionType();
 
+    auto const& rParaItems((pMerged ? *pMerged->pParaPropsNode : rNode).GetSwAttrSet());
     // justification type
-    const bool bAdjustBlock = SvxAdjust::Block ==
-                                  rNode.GetSwAttrSet().GetAdjust().GetAdjust();
+    const bool bAdjustBlock = SvxAdjust::Block == rParaItems.GetAdjust().GetAdjust();
 
     // FIND INVALID RANGES IN SCRIPT INFO ARRAYS:
 
@@ -1005,7 +1007,7 @@ void SwScriptInfo::InitScriptInfo( const SwTextNode& rNode, bool bRTL )
         // we search for connecting opportunities (kashida)
         else if ( bAdjustBlock && i18n::ScriptType::COMPLEX == nScript )
         {
-            SwScanner aScanner( rNode, rNode.GetText(), nullptr, ModelToViewHelper(),
+            SwScanner aScanner( rNode, rText, nullptr, ModelToViewHelper(),
                                 i18n::WordType::DICTIONARY_WORD,
                                 nLastKashida, nChg );
 
diff --git a/sw/source/core/text/redlnitr.cxx b/sw/source/core/text/redlnitr.cxx
index aeecc00bcada..ee4d788a4bc9 100644
--- a/sw/source/core/text/redlnitr.cxx
+++ b/sw/source/core/text/redlnitr.cxx
@@ -204,8 +204,8 @@ void SwAttrIter::CtorInitAttrIter(SwTextNode & rTextNode,
 
     // determine script changes if not already done for current paragraph
     assert(m_pScriptInfo);
-    if ( m_pScriptInfo->GetInvalidityA() != COMPLETE_STRING )
-         m_pScriptInfo->InitScriptInfo( rTextNode, bRTL );
+    if (m_pScriptInfo->GetInvalidityA() != TextFrameIndex(COMPLETE_STRING))
+         m_pScriptInfo->InitScriptInfo(rTextNode, m_pMergedPara, bRTL);
 
     InitFontAndAttrHandler(rTextNode,
             m_pMergedPara ? m_pMergedPara->mergedText : rTextNode.GetText(),
commit 6bd005a15b73636d5cbd192eff775c5c8e5bb259
Author: Michael Stahl <Michael.Stahl at cib.de>
Date:   Wed May 23 14:02:29 2018 +0200

    sw_redlinehide: SwScriptInfo header
    
    Only the non-static functions for now.
    
    Actually, aKashidaInvalid stores indexes into aKashida...
    
    Change-Id: Ie8b30e9c12ecda50e77470400042d9e343f9d33f

diff --git a/sw/source/core/inc/scriptinfo.hxx b/sw/source/core/inc/scriptinfo.hxx
index 1f715a49b519..6645c1105e30 100644
--- a/sw/source/core/inc/scriptinfo.hxx
+++ b/sw/source/core/inc/scriptinfo.hxx
@@ -25,6 +25,7 @@
 #include <swscanner.hxx>
 #include <rtl/ustrbuf.hxx>
 #include <osl/diagnose.h>
+#include "TextFrameIndex.hxx"
 
 class SwTextNode;
 class Point;
@@ -44,9 +45,9 @@ private:
     //! Records a single change in script type.
     struct ScriptChangeInfo
     {
-        sal_Int32 position; //!< Character position at which we change script
+        TextFrameIndex position; //!< Character position at which we change script
         sal_uInt8       type;     //!< Script type (Latin/Asian/Complex) that we change to.
-        ScriptChangeInfo(sal_Int32 pos, sal_uInt8 typ) : position(pos), type(typ) {};
+        ScriptChangeInfo(TextFrameIndex pos, sal_uInt8 typ) : position(pos), type(typ) {};
     };
     //TODO - This is sorted, so should probably be a std::set rather than vector.
     //       But we also use random access (probably unnecessarily).
@@ -54,42 +55,44 @@ private:
     //! Records a single change in direction.
     struct DirectionChangeInfo
     {
-        sal_Int32 position; //!< Character position at which we change direction.
+        TextFrameIndex position; //!< Character position at which we change direction.
         sal_uInt8       type;     //!< Direction that we change to.
-        DirectionChangeInfo(sal_Int32 pos, sal_uInt8 typ) : position(pos), type(typ) {};
+        DirectionChangeInfo(TextFrameIndex pos, sal_uInt8 typ) : position(pos), type(typ) {};
     };
     std::vector<DirectionChangeInfo> m_DirectionChanges;
-    std::deque< sal_Int32 > m_Kashida;
-    std::deque< sal_Int32 > m_KashidaInvalid;
-    std::deque< sal_Int32 > m_NoKashidaLine;
-    std::deque< sal_Int32 > m_NoKashidaLineEnd;
-    std::deque< sal_Int32 > m_HiddenChg;
+    std::deque<TextFrameIndex> m_Kashida;
+    /// indexes into m_Kashida
+    std::deque<size_t> m_KashidaInvalid;
+    std::deque<TextFrameIndex> m_NoKashidaLine;
+    std::deque<TextFrameIndex> m_NoKashidaLineEnd;
+    std::deque<TextFrameIndex> m_HiddenChg;
     //! Records a single change in compression.
     struct CompressionChangeInfo
     {
-        sal_Int32 position; //!< Character position where the change occurs.
-        sal_Int32 length;   //!< Length of the segment.
+        TextFrameIndex position; //!< Character position where the change occurs.
+        TextFrameIndex length;   //!< Length of the segment.
         CompType  type;     //!< Type of compression that we change to.
-        CompressionChangeInfo(sal_Int32 pos, sal_Int32 len, CompType typ) : position(pos), length(len), type(typ) {};
+        CompressionChangeInfo(TextFrameIndex pos, TextFrameIndex len, CompType typ) : position(pos), length(len), type(typ) {};
     };
     std::vector<CompressionChangeInfo> m_CompressionChanges;
 #ifdef DBG_UTIL
-    CompType DbgCompType( const sal_Int32 nPos ) const;
+    CompType DbgCompType(const TextFrameIndex nPos) const;
 #endif
 
-    sal_Int32 m_nInvalidityPos;
+    TextFrameIndex m_nInvalidityPos;
     sal_uInt8 m_nDefaultDir;
 
     void UpdateBidiInfo( const OUString& rText );
 
-    bool IsKashidaValid(sal_Int32 nKashPos) const;
-    void MarkKashidaInvalid(sal_Int32 nKashPos);
-    void ClearKashidaInvalid(sal_Int32 nKashPos);
-    bool MarkOrClearKashidaInvalid(sal_Int32 nStt, sal_Int32 nLen, bool bMark, sal_Int32 nMarkCount);
-    bool IsKashidaLine(sal_Int32 nCharIdx) const;
+    bool IsKashidaValid(size_t nKashPos) const;
+    void MarkKashidaInvalid(size_t nKashPos);
+    void ClearKashidaInvalid(size_t nKashPos);
+    bool MarkOrClearKashidaInvalid(TextFrameIndex nStt, TextFrameIndex nLen,
+            bool bMark, sal_Int32 nMarkCount);
+    bool IsKashidaLine(TextFrameIndex nCharIdx) const;
     // examines the range [ nStart, nStart + nEnd ] if there are kanas
     // returns start index of kana entry in array, otherwise SAL_MAX_SIZE
-    size_t HasKana( sal_Int32 nStart, const sal_Int32 nEnd ) const;
+    size_t HasKana(TextFrameIndex nStart, TextFrameIndex nEnd) const;
 
 public:
 
@@ -101,12 +104,12 @@ public:
     void InitScriptInfo( const SwTextNode& rNode );
 
     // set/get position from which data is invalid
-    void SetInvalidityA(const sal_Int32 nPos)
+    void SetInvalidityA(const TextFrameIndex nPos)
     {
         if (nPos < m_nInvalidityPos)

... etc. - the rest is truncated


More information about the Libreoffice-commits mailing list