35 #define MIN_TAB_WIDTH 60
55 while( pLay && !pLay->
GetLen() )
58 while( pPor && bSkip )
64 pLay = bSkip ? pLay->
GetNext() :
nullptr;
70 if( !
GetInfo().GetParaPortion()->HasFly() )
132 std::vector<TextFrameIndex> aKashidaPos;
135 std::vector<TextFrameIndex> aKashidaPosDropped(aKashidaPos.size());
136 sal_Int32 nKashidaIdx = 0;
137 while ( rKashidas && nIdx < nEnd )
145 if( nNextScript < nNext )
150 sal_Int32 nKashidasInAttr = rSI.
KashidaJustify (
nullptr,
nullptr, nIdx, nNext - nIdx );
151 if (nKashidasInAttr > 0)
159 sal_Int32 nKashidasDropped = 0;
162 nKashidasDropped = nKashidasInAttr;
163 rKashidas -= nKashidasDropped;
170 rInf.
GetText(), sal_Int32(nIdx), sal_Int32(nNext - nIdx),
172 reinterpret_cast<sal_Int32*
>(aKashidaPos.data() + nKashidaIdx),
173 reinterpret_cast<sal_Int32*>(aKashidaPosDropped.data()));
175 if ( nKashidasDropped )
178 rKashidas -= nKashidasDropped;
182 nKashidaIdx += nKashidasInAttr;
188 return (rKashidas > 0);
199 bool bAddSpaceChanged =
false;
202 while ( nIdx < nEnd )
210 if( nNextScript < nNext )
215 sal_Int32 nKashidasInAttr = rSI.
KashidaJustify (
nullptr,
nullptr, nIdx, nNext - nIdx );
220 sal_Int32 nKashidasDropped = 0;
221 while ( rKashidas && nGluePortion && nKashidasInAttr > 0 &&
228 if( !rKashidas || !nGluePortion )
231 nSpaceAdd = nGluePortionWidth / sal_Int32(nGluePortion);
232 bAddSpaceChanged =
true;
234 if( nKashidasDropped )
237 if ( bAddSpaceChanged )
241 if ( !bAddSpaceChanged )
254 "CalcNewBlock: Why?" );
255 OSL_ENSURE( pCurrent->
Height(),
"SwTextAdjuster::CalcBlockAdjust: missing CalcLine()" );
260 sal_uInt16 nSpaceIdx = 0;
288 const bool bDoNotJustifyLinesWithManualBreak =
290 bool bDoNotJustifyTab =
false;
296 if ( ( bDoNotJustifyLinesWithManualBreak || bDoNotJustifyTab ) &&
308 bDoNotJustifyTab =
true;
312 bDoNotJustifyTab =
false;
318 nGluePortion = nGluePortion + static_cast<SwTextPortion*>(pPos)->GetSpaceCnt(
GetInfo(), nCharCnt );
336 nGluePortion = nGluePortion + static_cast<SwDoubleLinePortion*>(pMulti)->GetSpaceCnt();
337 else if ( pMulti->
IsBidi() )
338 nGluePortion = nGluePortion + static_cast<SwBidiPortion*>(pMulti)->GetSpaceCnt(
GetInfo() );
351 sal_Int32 nKashidas = 0;
352 if( nGluePortion && rSI.
CountKashida() && !bSkipKashida )
369 tools::Long nSpaceAdd = nGluePortionWidth / sal_Int32(nGluePortion);
374 if( !
lcl_CheckKashidaWidth( rSI, aInf, aItr, nKashidas, nGluePortion, nGluePortionWidth, nSpaceAdd ))
386 pPos->
Width( static_cast<SwGluePortion*>(pPos)->GetFixWidth() );
390 const tools::Long nSpaceAdd = - nGluePortionWidth / (sal_Int32(nCharCnt) - 1);
392 pPos->
Width( static_cast<SwGluePortion*>(pPos)->GetFixWidth() );
403 if ( pPos == pStopAt )
414 OSL_ENSURE( pCurrent->
Height(),
"SwTextAdjuster::CalcBlockAdjust: missing CalcLine()" );
415 OSL_ENSURE( !pCurrent->
GetpKanaComp(),
"pKanaComp already exists!!" );
417 pCurrent->
SetKanaComp( std::make_unique<std::deque<sal_uInt16>>() );
419 const sal_uInt16 nNull = 0;
424 bool bNoCompression =
false;
444 nKanaDiffSum += nMaxWidthDiff;
448 if ( nMaxWidthDiff && !nRepaintOfst )
460 nRest = ! bNoCompression &&
472 nRest = ! bNoCompression ?
476 bNoCompression =
false;
481 sal_uLong nCompress = ( 10000 * nRest ) / nKanaDiffSum;
483 if ( nCompress >= 10000 )
489 nCompress = 10000 - nCompress;
491 ( pCurrent->
GetKanaComp() )[ nKanaIdx ] = static_cast<sal_uInt16>(nCompress);
504 sal_uInt16 nCompress = ( pCurrent->
GetKanaComp() )[ nKanaIdx ];
512 const sal_uInt16 nMinWidth = pPos->
Width();
521 pPos->
Width( nMinWidth +
522 ( ( 10000 - nCompress ) * nMaxWidthDiff ) / 10000 );
523 nDecompress += pPos->
Width() - nMinWidth;
527 pPos->
Width( static_cast<sal_uInt16>(pPos->
Width() - nDecompress) );
531 static_cast<SwTabPortion*>(pPos)->SetFixWidth( pPos->
Width() );
533 if ( ++nKanaIdx < pCurrent->GetKanaComp().size() )
534 nCompress = ( pCurrent->
GetKanaComp() )[ nKanaIdx ];
549 const sal_uInt16 nLineHeight = pCurrent->
Height();
551 sal_uInt16 nPrtWidth = pCurrent->
PrtWidth();
561 SwRect aCurrRect( nLeftMar + nPrtWidth,
Y() + nRealHeight - nLineHeight,
562 nRealWidth - nPrtWidth, nLineHeight );
565 while( pFly &&
tools::Long( nPrtWidth )< nRealWidth )
569 if( pFly->
GetFix() > nPrtWidth )
571 nPrtWidth += pFly->
Width() + 1;
572 aCurrRect.
Left( nLeftMar + nPrtWidth );
582 pRight->
PrtWidth( sal_uInt16( nRealWidth - nPrtWidth ) );
591 pCurrent->
PrtWidth( sal_uInt16( nRealWidth ) );
611 bool bMultiTab =
false;
618 ( bTabCompat ? ! pPos->
InTabGrp() : ! bMultiTab ) )
624 static_cast<SwGluePortion*>(pPos)->MoveAllGlue( pGlue );
642 static_cast<SwGluePortion*>(pPos)->
MoveHalfGlue( pGlue );
650 static_cast<SwGluePortion*>(pPos)->
MoveHalfGlue( pGlue );
661 nLen = nLen + pPos->
GetLen();
665 if( ! bTabCompat && ! bMultiTab && SvxAdjust::Right ==
GetAdjust() )
672 OSL_ENSURE( pCurrent->
IsFormatAdj(),
"CalcAdjLine: Why?" );
680 case SvxAdjust::Right:
681 case SvxAdjust::Center:
687 case SvxAdjust::Block:
708 SwRect aLineVert( rCurrRect );
723 if( aFlyRect.HasArea() )
726 SwRect aLocal( aFlyRect );
728 if( nCurrWidth > aLocal.
Left() )
729 aLocal.
Left( nCurrWidth );
733 if( nRealWidth < nLocalWidth )
734 aLocal.
Width( nRealWidth - aLocal.
Left() );
737 pFlyPortion->
Height( sal_uInt16( rCurrRect.
Height() ) );
748 "CalcDropAdjust: No reason for DropAdjustment." );
750 const sal_uInt16 nLineNumber =
GetLineNr();
776 static_cast<SwGluePortion*>(pPor) :
nullptr;
777 if( pRight && pRight != pLeft )
780 const auto nDropLineStart =
782 auto nMinLeft = nDropLineStart;
797 const auto nLineStart =
799 if( nMinLeft > nLineStart )
800 nMinLeft = nLineStart;
806 if( nMinLeft < nDropLineStart )
810 const auto nGlue = nDropLineStart - nMinLeft;
832 if( rRepaint.
Top() >
Y() )
837 if( rRepaint.
Bottom() < nBottom )
838 rRepaint.
Bottom( nBottom );
void MoveAllGlue(SwGluePortion *pTarget)
std::deque< sal_uInt16 > * GetpKanaComp() const
bool SeekAndChgAttrIter(TextFrameIndex nPos, OutputDevice *pOut)
Executes ChgPhysFnt if Seek() returns true and change font to merge character border with neighbours...
void SwitchVerticalToHorizontal(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from vertical to horizontal layout...
void SetKanaComp(std::unique_ptr< std::deque< sal_uInt16 >> pNew)
void SetFormatAdj(const bool bNew)
sal_uInt16 GetLineNr() const
TextFrameIndex NextScriptChg(TextFrameIndex nPos) const
void CalcNewBlock(SwLineLayout *pCurr, const SwLinePortion *pStopAt, SwTwips nReal=0, bool bSkipKashida=false)
sal_uInt16 Height() const
SwMarginPortion * CalcLeftMargin()
std::deque< sal_uInt16 > & GetKanaComp()
const SwLineLayout * NextLine()
TextFrameIndex GetStart() const
void Left(const tools::Long nLeft)
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout...
void MoveGlue(SwGluePortion *pTarget, const tools::Long nPrtGlue)
The purpose of this class is to be the universal interface between formatting/text output and the pos...
void MarkKashidasInvalid(sal_Int32 nCnt, const TextFrameIndex *pKashidaPositions)
Marks nCnt kashida positions as invalid pKashidaPositions: array of char indices relative to the para...
ComplexTextLayoutFlags GetLayoutMode() const
TextFrameIndex GetNextAttr() const
void SetLayoutMode(ComplexTextLayoutFlags nTextLayoutMode)
const SwLineLayout * Next()
void Pos(const Point &rNew)
SwTwips CalcKanaAdj(SwLineLayout *pCurr)
sal_uInt16 GetFix() const
Of course Writer needs its own rectangles.
Collection of SwLineLayout instances, represents the paragraph text in Writer layout.
bool IsMarginPortion() const
SwRect GetFrame(const SwRect &rPortion) const
void SetNoKashidaLine(TextFrameIndex nStt, TextFrameIndex nLen)
Use regular blank justification instead of kashdida justification for the given line of text...
sal_uInt16 GetLLSpaceAddCount() const
void CalcAdjLine(SwLineLayout *pCurr)
bool IsBreakPortion() const
const BorderLinePrimitive2D *pCandidateB assert(pCandidateA)
void Width(tools::Long nNew)
bool InFixMargGrp() const
static bool lcl_CheckKashidaPositions(SwScriptInfo &rSI, SwTextSizeInfo &rInf, SwTextIter &rItr, sal_Int32 &rKashidas, TextFrameIndex &nGluePortion)
static bool IsArabicText(const OUString &rText, TextFrameIndex nStt, TextFrameIndex nLen)
Checks if text is Arabic text.
void CalcFlyAdjust(SwLineLayout *pCurr)
virtual SwLinePortion * Append(SwLinePortion *pPortion)
virtual void Height(const sal_uInt16 nNew, const bool bText=true) override
SwTwips GetLineStart() const
Collection of SwLinePortion instances, representing one line of text.
vcl::RenderContext * GetOut()
SwParaPortion * GetParaPortion()
bool IsFlyPortion() const
SwLinePortion * GetFirstPortion() const
SwFlyPortion * CalcFlyPortion(const tools::Long nRealWidth, const SwRect &rCurrRect)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
SwTwips GetLeftMargin() const
bool IsTabLeftPortion() const
sal_uInt16 GetLineHeight() const
TextFrameIndex GetIdx() const
bool IsDropPortion() const
sal_uInt16 GetMaxWidthDiff(const SwLinePortion *nKey)
void MoveHalfGlue(SwGluePortion *pTarget)
TextFrameIndex GetLen() const
static bool lcl_CheckKashidaWidth(SwScriptInfo &rSI, SwTextSizeInfo &rInf, SwTextIter &rItr, sal_Int32 &rKashidas, TextFrameIndex &nGluePortion, const tools::Long nGluePortionWidth, tools::Long &nSpaceAdd)
const OUString & GetText() const
bool IsMultiPortion() const
tools::Long GetMinKashida() const
void SwitchLTRtoRTL(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from LTR to RTL layout.
Base class for anything that can be part of a line in the Writer layout.
void Bottom(const tools::Long nBottom)
void ClearNoKashidaLine(TextFrameIndex nStt, TextFrameIndex nLen)
Clear forced blank justification for a given line.
void SwitchRTLtoLTR(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from RTL to LTR layout.
TextFrameIndex GetLength() const
PortionType GetWhichPor() const
SwLinePortion * FindLastPortion()
IDocumentSettingAccess const & getIDocumentSettingAccess() const
SvxAdjust GetAdjust() const
bool IsLastCenter() const
SwTextSizeInfo & GetInfo()
bool IsRightToLeft() const
void Top(const tools::Long nTop)
void ClearKashidaInvalid(size_t nKashPos)
SwScriptInfo & GetScriptInfo()
double getLength(const B2DPolygon &rCandidate)
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
SwMarginPortion * CalcRightMargin(SwLineLayout *pCurr, SwTwips nReal=0)
sal_Int32 ValidateKashidas(const OUString &rTxt, sal_Int32 nIdx, sal_Int32 nLen, sal_Int32 nKashCount, const sal_Int32 *pKashidaPos, sal_Int32 *pKashidaPosDropped) const
const SwLineLayout * GetNext() const
sal_uInt16 GetLineWidth() const
size_t CountKashida() const
const SwLineLayout * GetCurr() const
sal_Int32 KashidaJustify(tools::Long *pKernArray, tools::Long *pScrArray, TextFrameIndex nStt, TextFrameIndex nLen, tools::Long nSpaceAdd=0) const
Performs a kashida justification on the kerning array.
#define SPACING_PRECISION_FACTOR
bool HasTabulator() const
SwTextFrame * GetTextFrame()
void PrtWidth(sal_uInt16 nNewWidth)
void GetKashidaPositions(TextFrameIndex nStt, TextFrameIndex nLen, std::vector< TextFrameIndex > &rKashidaPosition)
retrieves kashida opportunities for a given text range.
void SetOffset(const SwTwips nNew)
TextFrameIndex GetEnd() const
void AdjustRight(const SwLineLayout *pCurr)
In the outer loop all portions are inspected - the GluePortions at the end are processed first...
sal_uInt16 GetDropLines() const
SwLinePortion * GetNextPortion() const
void SetIdx(const TextFrameIndex nNew)
o3tl::strong_int< sal_Int32, struct Tag_TextFrameIndex > TextFrameIndex
Denotes a character index in a text frame at a layout level, after extent mapping from a text node at...
void Height(tools::Long nNew)
const sal_Int32 COMPLETE_STRING
void SetLLSpaceAdd(tools::Long nNew, sal_uInt16 nIdx)