Rebased ref, commits from common ancestor: commit fb2744064baa62744bfa9c734a88645c2bf629ba Author: Michael Stahl <michael.st...@cib.de> Date: Fri May 25 18:41:52 2018 +0200
sw_redlinehide: fix SwCursorShell::GetContentAtPos() redline code This calls SwTextFrame::GetCharRect() on the frame where the mouse cursor is, with SwPositions that may be in a unrelated SwTextNode. Bogus positions now triggers asserts, so let's fix it. Change-Id: Idedb335ffd79c299976ad91b683dfb30cd0ceac2 diff --git a/sw/source/core/crsr/crstrvl.cxx b/sw/source/core/crsr/crstrvl.cxx index 3864b07e9cf5..a8c8fada8c40 100644 --- a/sw/source/core/crsr/crstrvl.cxx +++ b/sw/source/core/crsr/crstrvl.cxx @@ -1493,11 +1493,17 @@ bool SwCursorShell::GetContentAtPos( const Point& rPt, if( pFieldRect && nullptr != ( pFrame = pTextNd->getLayoutFrame( GetLayout(), &aPt ) ) ) { + // not sure if this should be limited to one + // paragraph, or mark the entire redline; let's + // leave it limited to one for now... + sal_Int32 nStart; + sal_Int32 nEnd; + pRedl->CalcStartEnd(pTextNd->GetIndex(), nStart, nEnd); //get bounding box of range SwRect aStart; - pFrame->GetCharRect(aStart, *pRedl->Start(), &aTmpState); + pFrame->GetCharRect(aStart, SwPosition(*pTextNd, nStart), &aTmpState); SwRect aEnd; - pFrame->GetCharRect(aEnd, *pRedl->End(), &aTmpState); + pFrame->GetCharRect(aEnd, SwPosition(*pTextNd, nEnd), &aTmpState); if (aStart.Top() != aEnd.Top() || aStart.Bottom() != aEnd.Bottom()) { aStart.Left(pFrame->getFrameArea().Left()); commit a5d1645f95862938ba565490d09e8d6d128c8b6e Author: Michael Stahl <michael.st...@cib.de> Date: Fri May 25 14:04:33 2018 +0200 sw_redlinehide: hyphenation There's a loop over nodes, calling SwTextNode::Hyphenate() each time. Introduce a new class SwInterHyphInfoTextFrame that is used in the SwTextFrame functions, and SwTextNode::Hyphenate() converts between the 2 types. Not sure if this will hyphenate a word that is split across nodes in the model, but perhaps this is good enough in practice. Change-Id: I78dec370e15c372284c934d9658b2dd5b3b97ae0 diff --git a/sw/inc/splargs.hxx b/sw/inc/splargs.hxx index 11b39a10fa3a..efd4c33e6352 100644 --- a/sw/inc/splargs.hxx +++ b/sw/inc/splargs.hxx @@ -109,11 +109,15 @@ struct SwSpellArgs : SwArgsBase class SwInterHyphInfo { - css::uno::Reference< css::linguistic2::XHyphenatedWord > xHyphWord; + /// output: hyphenated word + css::uno::Reference<css::linguistic2::XHyphenatedWord> xHyphWord; + /// input: cursor point to locate the frame const Point aCursorPos; public: + /// input: requested range to hyphenate sal_Int32 nStart; sal_Int32 nEnd; + /// output: found word sal_Int32 nWordStart; sal_Int32 nWordLen; @@ -124,10 +128,6 @@ public: , nWordStart(0), nWordLen(0) { } - sal_Int32 GetEnd() const - { - return nEnd; - } const Point *GetCursorPos() const { return aCursorPos.X() || aCursorPos.Y() ? &aCursorPos : nullptr; diff --git a/sw/source/core/doc/docedt.cxx b/sw/source/core/doc/docedt.cxx index a139293fec7c..68087a0fb1b6 100644 --- a/sw/source/core/doc/docedt.cxx +++ b/sw/source/core/doc/docedt.cxx @@ -748,6 +748,8 @@ static bool lcl_HyphenateNode( const SwNodePtr& rpNd, void* pArgs ) SwHyphArgs *pHyphArgs = static_cast<SwHyphArgs*>(pArgs); if( pNode ) { + // sw_redlinehide: this will be called once per node for merged nodes; + // the fully deleted ones won't have frames so are skipped. SwContentFrame* pContentFrame = pNode->getLayoutFrame( pNode->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout() ); if( pContentFrame && !static_cast<SwTextFrame*>(pContentFrame)->IsHiddenNow() ) { diff --git a/sw/source/core/inc/txtfrm.hxx b/sw/source/core/inc/txtfrm.hxx index e7c51f082efc..3307378a1026 100644 --- a/sw/source/core/inc/txtfrm.hxx +++ b/sw/source/core/inc/txtfrm.hxx @@ -25,6 +25,8 @@ #include <ndtxt.hxx> #include "TextFrameIndex.hxx" +namespace com { namespace sun { namespace star { namespace linguistic2 { class XHyphenatedWord; } } } } + class SwCharRange; class SwTextNode; class SwTextFormatter; @@ -46,6 +48,31 @@ class SwScriptInfo; #define NON_PRINTING_CHARACTER_COLOR Color(0x26, 0x8b, 0xd2) +/// a clone of SwInterHyphInfo, but with TextFrameIndex instead of node index +class SwInterHyphInfoTextFrame +{ +private: + /// output: hyphenated word + css::uno::Reference<css::linguistic2::XHyphenatedWord> m_xHyphWord; +public: + /// input: requested range to hyphenate + TextFrameIndex nStart; + TextFrameIndex nEnd; + /// output: found word + TextFrameIndex nWordStart; + TextFrameIndex nWordLen; + + SwInterHyphInfoTextFrame(SwTextFrame const& rFrame, + SwTextNode const& rNode, SwInterHyphInfo const& rHyphInfo); + void UpdateTextNodeHyphInfo(SwTextFrame const& rFrame, + SwTextNode const& rNode, SwInterHyphInfo & o_rHyphInfo); + + void SetHyphWord(const css::uno::Reference<css::linguistic2::XHyphenatedWord> &xHW) + { + m_xHyphWord = xHW; + } +}; + namespace sw { struct Extent @@ -425,7 +452,7 @@ public: * We format a Line for interactive hyphenation * @return found */ - bool Hyphenate( SwInterHyphInfo &rInf ); + bool Hyphenate(SwInterHyphInfoTextFrame & rInf); /// Test grow inline SwTwips GrowTst( const SwTwips nGrow ); diff --git a/sw/source/core/text/itrform2.hxx b/sw/source/core/text/itrform2.hxx index bf9a6c8af749..ff430b8616d1 100644 --- a/sw/source/core/text/itrform2.hxx +++ b/sw/source/core/text/itrform2.hxx @@ -164,7 +164,7 @@ public: void RecalcRealHeight(); // We format a line for interactive hyphenation - bool Hyphenate( SwInterHyphInfo &rInf ); + bool Hyphenate(SwInterHyphInfoTextFrame & rInf); // A special method for QuoVadis texts: // nErgo is the page number of the ErgoSum Footnote diff --git a/sw/source/core/text/txthyph.cxx b/sw/source/core/text/txthyph.cxx index 929eb95fda2e..dfe2ab713a33 100644 --- a/sw/source/core/text/txthyph.cxx +++ b/sw/source/core/text/txthyph.cxx @@ -56,7 +56,7 @@ Reference< XHyphenatedWord > SwTextFormatInfo::HyphWord( /** * We format a row for interactive hyphenation */ -bool SwTextFrame::Hyphenate( SwInterHyphInfo &rHyphInf ) +bool SwTextFrame::Hyphenate(SwInterHyphInfoTextFrame & rHyphInf) { vcl::RenderContext* pRenderContext = getRootFrame()->GetCurrShell()->GetOut(); OSL_ENSURE( ! IsVertical() || ! IsSwapped(),"swapped frame at SwTextFrame::Hyphenate" ); @@ -97,7 +97,7 @@ bool SwTextFrame::Hyphenate( SwInterHyphInfo &rHyphInf ) aLine.Next(); } - const sal_Int32 nEnd = rHyphInf.GetEnd(); + const TextFrameIndex nEnd = rHyphInf.nEnd; while( !bRet && aLine.GetStart() < nEnd ) { bRet = aLine.Hyphenate( rHyphInf ); @@ -124,7 +124,7 @@ void SetParaPortion( SwTextInfo *pInf, SwParaPortion *pRoot ) pInf->m_pPara = pRoot; } -bool SwTextFormatter::Hyphenate( SwInterHyphInfo &rHyphInf ) +bool SwTextFormatter::Hyphenate(SwInterHyphInfoTextFrame & rHyphInf) { SwTextFormatInfo &rInf = GetInfo(); @@ -134,7 +134,7 @@ bool SwTextFormatter::Hyphenate( SwInterHyphInfo &rHyphInf ) if( !GetNext() && !rInf.GetTextFly().IsOn() && !m_pFrame->GetFollow() ) return false; - sal_Int32 nWrdStart = m_nStart; + TextFrameIndex nWrdStart = m_nStart; // We need to retain the old row // E.g.: The attribute for hyphenation was not set, but @@ -168,16 +168,16 @@ bool SwTextFormatter::Hyphenate( SwInterHyphInfo &rHyphInf ) // HyphPortion in the specified range. SwLinePortion *pPos = m_pCurr->GetPortion(); - const sal_Int32 nPamStart = rHyphInf.nStart; + const TextFrameIndex nPamStart = rHyphInf.nStart; nWrdStart = m_nStart; - const sal_Int32 nEnd = rHyphInf.GetEnd(); + const TextFrameIndex nEnd = rHyphInf.nEnd; while( pPos ) { // Either we are above or we are running into a HyphPortion // at the end of line or before a Fly. if( nWrdStart >= nEnd ) { - nWrdStart = 0; + nWrdStart = TextFrameIndex(0); break; } @@ -194,13 +194,13 @@ bool SwTextFormatter::Hyphenate( SwInterHyphInfo &rHyphInf ) } // When pPos is null, no hyphen position was found. if( !pPos ) - nWrdStart = 0; + nWrdStart = TextFrameIndex(0); } else // In case the whole line is zero-length, that's the same situation as // above when the portion iteration ends without explicitly breaking // from the loop. - nWrdStart = 0; + nWrdStart = TextFrameIndex(0); // the old LineLayout is set again ... delete m_pCurr; @@ -212,28 +212,30 @@ bool SwTextFormatter::Hyphenate( SwInterHyphInfo &rHyphInf ) OSL_ENSURE( IsParaLine(), "SwTextFormatter::Hyphenate: even not the first" ); } - if( nWrdStart==0 ) + if (nWrdStart == TextFrameIndex(0)) return false; // nWrdStart contains the position in string that should be hyphenated rHyphInf.nWordStart = nWrdStart; - sal_Int32 nLen = 0; - const sal_Int32 nEnd = nWrdStart; + TextFrameIndex nLen(0); + const TextFrameIndex nEnd = nWrdStart; // we search forwards Reference< XHyphenatedWord > xHyphWord; - Boundary aBound = - g_pBreakIt->GetBreakIter()->getWordBoundary( rInf.GetText(), nWrdStart, + Boundary const aBound = g_pBreakIt->GetBreakIter()->getWordBoundary( + rInf.GetText(), sal_Int32(nWrdStart), g_pBreakIt->GetLocale( rInf.GetFont()->GetLanguage() ), WordType::DICTIONARY_WORD, true ); - nWrdStart = aBound.startPos; - nLen = aBound.endPos - nWrdStart; - if ( nLen == 0 ) + nWrdStart = TextFrameIndex(aBound.startPos); + nLen = TextFrameIndex(aBound.endPos) - nWrdStart; + if (nLen == TextFrameIndex(0)) return false; - OUString aSelText( rInf.GetText().copy(nWrdStart, nLen) ); - const sal_Int32 nMinTrail = ( nWrdStart + nLen > nEnd ) ? nWrdStart + nLen - nEnd - 1 : 0; + OUString const aSelText(rInf.GetText().copy(sal_Int32(nWrdStart), sal_Int32(nLen))); + const sal_Int32 nMinTrail = (nWrdStart + nLen > nEnd) + ? sal_Int32(nWrdStart + nLen - nEnd) - 1 + : 0; //!! rHyphInf.SetHyphWord( ... ) must done here xHyphWord = rInf.HyphWord( aSelText, nMinTrail ); diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx index c226691ec26d..7523293b45ea 100644 --- a/sw/source/core/txtnode/txtedt.cxx +++ b/sw/source/core/txtnode/txtedt.cxx @@ -1614,6 +1614,31 @@ void SwTextFrame::CollectAutoCmplWrds( SwContentNode const * pActNode, sal_Int32 pNode->SetAutoCompleteWordDirty( false ); } +SwInterHyphInfoTextFrame::SwInterHyphInfoTextFrame( + SwTextFrame const& rFrame, SwTextNode const& rNode, + SwInterHyphInfo const& rHyphInfo) + : nStart(rFrame.MapModelToView(&rNode, rHyphInfo.nStart)) + , nEnd(rFrame.MapModelToView(&rNode, rHyphInfo.nEnd)) + , nWordStart(0) + , nWordLen(0) +{ +} + +void SwInterHyphInfoTextFrame::UpdateTextNodeHyphInfo(SwTextFrame const& rFrame, + SwTextNode const& rNode, SwInterHyphInfo & o_rHyphInfo) +{ + std::pair<SwTextNode const*, sal_Int32> const wordStart(rFrame.MapViewToModel(nWordStart)); + std::pair<SwTextNode const*, sal_Int32> const wordEnd(rFrame.MapViewToModel(nWordStart+nWordLen)); + if (wordStart.first != &rNode || wordEnd.first != &rNode) + { // not sure if this can happen since nStart/nEnd are in rNode + SAL_WARN("sw.core", "UpdateTextNodeHyphInfo: outside of node"); + return; + } + o_rHyphInfo.nWordStart = wordStart.second; + o_rHyphInfo.nWordLen = wordEnd.second - wordStart.second; + o_rHyphInfo.SetHyphWord(m_xHyphWord); +} + /// Find the SwTextFrame and call its Hyphenate bool SwTextNode::Hyphenate( SwInterHyphInfo &rHyphInf ) { @@ -1630,9 +1655,7 @@ bool SwTextNode::Hyphenate( SwInterHyphInfo &rHyphInf ) this->GetDoc()->getIDocumentLayoutAccess().GetCurrentLayout(), rHyphInf.GetCursorPos())); }); - if( pFrame ) - pFrame = &(pFrame->GetFrameAtOfst( rHyphInf.nStart )); - else + if (!pFrame) { // There was a comment here that claimed that the following assertion // shouldn't exist as it's triggered by "Trennung ueber Sonderbereiche", @@ -1640,21 +1663,25 @@ bool SwTextNode::Hyphenate( SwInterHyphInfo &rHyphInf ) OSL_ENSURE( pFrame, "!SwTextNode::Hyphenate: can't find any frame" ); return false; } + SwInterHyphInfoTextFrame aHyphInfo(*pFrame, *this, rHyphInf); + + pFrame = &(pFrame->GetFrameAtOfst( aHyphInfo.nStart )); while( pFrame ) { - if( pFrame->Hyphenate( rHyphInf ) ) + if (pFrame->Hyphenate(aHyphInfo)) { // The layout is not robust wrt. "direct formatting" // cf. layact.cxx, SwLayAction::TurboAction_(), if( !pCnt->IsValid() ... pFrame->SetCompletePaint(); + aHyphInfo.UpdateTextNodeHyphInfo(*pFrame, *this, rHyphInf); return true; } pFrame = pFrame->GetFollow(); if( pFrame ) { - rHyphInf.nEnd = rHyphInf.nEnd - (pFrame->GetOfst() - rHyphInf.nStart); - rHyphInf.nStart = pFrame->GetOfst(); + aHyphInfo.nEnd = aHyphInfo.nEnd - (pFrame->GetOfst() - aHyphInfo.nStart); + aHyphInfo.nStart = pFrame->GetOfst(); } } return false; commit 1747beec3eb9d68ec11caf91042d8cc511960420 Author: Michael Stahl <michael.st...@cib.de> Date: Fri May 25 10:42:34 2018 +0200 sw_redlinehide: make SwScanner independent of SwTextNode Abstract out the GetLang function into a parameter. SwScanner also uses a ModelToViewHelper but at this place it's used in "pass-through" mode which does an identity mapping. Change-Id: I45557c4e4446d1b4d95a206c414bbb6477593f8a diff --git a/sw/inc/swscanner.hxx b/sw/inc/swscanner.hxx index 86f48bb18807..70793def9257 100644 --- a/sw/inc/swscanner.hxx +++ b/sw/inc/swscanner.hxx @@ -23,14 +23,16 @@ #include <i18nlangtag/lang.h> #include "modeltoviewhelper.hxx" +#include <functional> + class SwTextNode; // Helper class that provides consecutively the words of a selected area // during spell check class SwScanner { + std::function<LanguageType (sal_Int32, sal_Int32, bool)> m_pGetLangOfChar; OUString m_aWord; - const SwTextNode& m_rNode; const OUString m_aPreDashReplacementText; OUString m_aText; const LanguageType* m_pLanguage; @@ -45,6 +47,12 @@ class SwScanner bool m_bClip; public: + SwScanner( std::function<LanguageType (sal_Int32, sal_Int32, bool)> pGetLangOfChar, + const OUString& rText, + const LanguageType* pLang, + const ModelToViewHelper& rConvMap, + sal_uInt16 nWordType, + sal_Int32 nStart, sal_Int32 nEnde, bool bClip = false ); SwScanner( const SwTextNode& rNd, const OUString& rText, const LanguageType* pLang, const ModelToViewHelper& rConvMap, diff --git a/sw/source/core/text/porlay.cxx b/sw/source/core/text/porlay.cxx index b2bf9438f3e3..dbd3f3211945 100644 --- a/sw/source/core/text/porlay.cxx +++ b/sw/source/core/text/porlay.cxx @@ -1080,9 +1080,22 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode, // we search for connecting opportunities (kashida) else if ( bAdjustBlock && i18n::ScriptType::COMPLEX == nScript ) { - SwScanner aScanner( rNode, rText, nullptr, ModelToViewHelper(), + // sw_redlinehide: this is the only place that uses SwScanner with + // frame text, so we convert to sal_Int32 here + std::function<LanguageType (sal_Int32, sal_Int32, bool)> const pGetLangOfCharM( + [&pMerged](sal_Int32 const nBegin, sal_uInt16 const nScript, bool const bNoChar) + { + std::pair<SwTextNode const*, sal_Int32> const pos( + sw::MapViewToModel(*pMerged, TextFrameIndex(nBegin))); + return pos.first->GetLang(pos.second, bNoChar ? 0 : 1, nScript); + }); + std::function<LanguageType (sal_Int32, sal_Int32, bool)> const pGetLangOfChar1( + [&rNode](sal_Int32 const nBegin, sal_uInt16 const nScript, bool const bNoChar) + { return rNode.GetLang(nBegin, bNoChar ? 0 : 1, nScript); }); + auto pGetLangOfChar(pMerged ? pGetLangOfCharM : pGetLangOfChar1); + SwScanner aScanner( pGetLangOfChar, rText, nullptr, ModelToViewHelper(), i18n::WordType::DICTIONARY_WORD, - nLastKashida, nChg ); + sal_Int32(nLastKashida), sal_Int32(nChg)); // the search has to be performed on a per word base while ( aScanner.NextWord() ) @@ -1235,7 +1248,7 @@ void SwScriptInfo::InitScriptInfo(const SwTextNode& rNode, if ( -1 != nKashidaPos ) { - m_Kashida.insert(m_Kashida.begin() + nCntKash, nKashidaPos); + m_Kashida.insert(m_Kashida.begin() + nCntKash, TextFrameIndex(nKashidaPos)); nCntKash++; } } // end of kashida search diff --git a/sw/source/core/txtnode/txtedt.cxx b/sw/source/core/txtnode/txtedt.cxx index 802ad9901872..c226691ec26d 100644 --- a/sw/source/core/txtnode/txtedt.cxx +++ b/sw/source/core/txtnode/txtedt.cxx @@ -728,7 +728,19 @@ OUString SwTextNode::GetCurWord( sal_Int32 nPos ) const SwScanner::SwScanner( const SwTextNode& rNd, const OUString& rText, const LanguageType* pLang, const ModelToViewHelper& rConvMap, sal_uInt16 nType, sal_Int32 nStart, sal_Int32 nEnde, bool bClp ) - : m_rNode( rNd ) + : SwScanner( + [&rNd](sal_Int32 const nBegin, sal_uInt16 const nScript, bool const bNoChar) + { return rNd.GetLang(nBegin, bNoChar ? 0 : 1, nScript); } + , rText, pLang, rConvMap, nType, nStart, nEnde, bClp) +{ +} + +SwScanner::SwScanner( + std::function<LanguageType (sal_Int32, sal_Int32, bool)> const pGetLangOfChar, + const OUString& rText, + const LanguageType* pLang, const ModelToViewHelper& rConvMap, + sal_uInt16 nType, sal_Int32 nStart, sal_Int32 nEnde, bool bClp ) + : m_pGetLangOfChar( pGetLangOfChar ) , m_aPreDashReplacementText(rText) , m_pLanguage( pLang ) , m_ModelToView( rConvMap ) @@ -775,7 +787,7 @@ SwScanner::SwScanner( const SwTextNode& rNd, const OUString& rText, { ModelToViewHelper::ModelPosition aModelBeginPos = m_ModelToView.ConvertToModelPosition( m_nBegin ); - m_aCurrentLang = rNd.GetLang( aModelBeginPos.mnPos ); + m_aCurrentLang = m_pGetLangOfChar(aModelBeginPos.mnPos, 0, true); } } @@ -837,7 +849,7 @@ bool SwScanner::NextWord() const sal_uInt16 nNextScriptType = g_pBreakIt->GetBreakIter()->getScriptType( m_aText, m_nBegin ); ModelToViewHelper::ModelPosition aModelBeginPos = m_ModelToView.ConvertToModelPosition( m_nBegin ); - m_aCurrentLang = m_rNode.GetLang( aModelBeginPos.mnPos, 1, nNextScriptType ); + m_aCurrentLang = m_pGetLangOfChar(aModelBeginPos.mnPos, nNextScriptType, false); } if ( m_nWordType != i18n::WordType::WORD_COUNT ) commit e71d8ea4d3dbc7455877ecd72d869f815528a8d5 Author: Michael Stahl <michael.st...@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 2010a5ed2140efce0f6187d72249b2333a93e3c7 Author: Michael Stahl <michael.st...@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..b89ade928e9e 100644 --- a/sw/source/core/text/itrcrsr.cxx +++ b/sw/source/core/text/itrcrsr.cxx @@ -249,7 +249,8 @@ 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( + TextFrameIndex(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 b1814b514717686db381fdfc07f0f13bcc4ce2d5 Author: Michael Stahl <michael.st...@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 39a50394e29ecfd25b2b9b45952f5495330a75b5 Author: Michael Stahl <michael.st...@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 bdb2002abca24432808e41dc4da01573388740e4 Author: Michael Stahl <michael.st...@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 c2cc7fc3217e6bc84666406e740337826b1f649f Author: Michael Stahl <michael.st...@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 1794464d58e6d5acd5156c0b8c1d1fe86159d6b8 Author: Michael Stahl <michael.st...@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 0e9da5af4c8449fe20590a0d4a2d4a3ef3032d8b Author: Michael Stahl <michael.st...@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 4388b4f6f29e75f184c5dc1b37c1e6d9ef663eda Author: Michael Stahl <michael.st...@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 de8d33eb524458609efb8654be167de58027e703 Author: Michael Stahl <michael.st...@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 c2b8106dd6a11abb96c8387432a147498f383629 Author: Michael Stahl <michael.st...@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 3a3d6b70e3780dbe971fafa572a444675237a41f Author: Michael Stahl <michael.st...@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 cd6057ac59877e126887ba83c4958a2ffc020d93 Author: Michael Stahl <michael.st...@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 9ba9f9fe137cffd0c65978f2f4684e00a1f780bb Author: Michael Stahl <michael.st...@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 9c9c47692b46289e2c47c7420672372b511ed80d Author: Michael Stahl <michael.st...@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 90554af2d5ec1e4bfeaab2bb0c91f39cea20d3ea Author: Michael Stahl <michael.st...@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 511904b0b117d7ef5738d18b9c2ef063ea1427b8 Author: Michael Stahl <michael.st...@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 36b2489d6cdb8f44fa11f04b028b7f0736aa541a Author: Michael Stahl <michael.st...@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 7b12392321a4..e3173840d91b 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 53184f198824..3d8225c79049 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 71a45af3245007bc79d7b58bb286941630167928 Author: Michael Stahl <michael.st...@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() ) ... etc. - the rest is truncated _______________________________________________ Libreoffice-commits mailing list libreoffice-comm...@lists.freedesktop.org https://lists.freedesktop.org/mailman/listinfo/libreoffice-commits