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 );
337 else if ( pMulti->
IsBidi() )
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 ))
390 const tools::Long nSpaceAdd = - nGluePortionWidth / (sal_Int32(nCharCnt) - 1);
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 ] = o3tl::narrowing<sal_uInt16>(nCompress);
504 sal_uInt16 nCompress = ( pCurrent->
GetKanaComp() )[ nKanaIdx ];
521 pPos->
Width( nMinWidth +
522 ( ( 10000 - nCompress ) * nMaxWidthDiff ) / 10000 );
523 nDecompress += pPos->
Width() - nMinWidth;
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 ) )
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 );
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_Int32 nLineNumber =
GetLineNr();
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 );
@ DO_NOT_JUSTIFY_LINES_WITH_MANUAL_BREAK
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...
virtual bool get(DocumentSettingId id) const =0
Return the specified document setting.
sal_Int32 ValidateKashidas(const OUString &rTxt, sal_Int32 nIdx, sal_Int32 nLen, sal_Int32 nKashCount, const sal_Int32 *pKashidaPos, sal_Int32 *pKashidaPosDropped) const
vcl::text::ComplexTextLayoutFlags GetLayoutMode() const
tools::Long GetMinKashida() const
void SetLayoutMode(vcl::text::ComplexTextLayoutFlags nTextLayoutMode)
bool SeekAndChgAttrIter(TextFrameIndex nPos, OutputDevice *pOut)
Executes ChgPhysFnt if Seek() returns true and change font to merge character border with neighbours.
TextFrameIndex GetNextAttr() const
IDocumentSettingAccess const & getIDocumentSettingAccess() const
sal_uInt16 GetFix() const
A glue portion is either a base class for other portions that want to have a certain width to push te...
void MoveHalfGlue(SwGluePortion *pTarget)
void MoveAllGlue(SwGluePortion *pTarget)
sal_uInt16 GetFixWidth() const
void MoveGlue(SwGluePortion *pTarget, const tools::Long nPrtGlue)
Collection of SwLinePortion instances, representing one line of text.
void SetKanaComp(std::unique_ptr< std::deque< sal_uInt16 > > pNew)
std::deque< sal_uInt16 > & GetKanaComp()
void SetFormatAdj(const bool bNew)
sal_uInt16 GetLLSpaceAddCount() const
SwLinePortion * GetFirstPortion() const
void SetLLSpaceAdd(tools::Long nNew, sal_uInt16 nIdx)
virtual void Height(const SwTwips nNew, const bool bText=true) override
SwMarginPortion * CalcLeftMargin()
std::deque< sal_uInt16 > * GetpKanaComp() const
Base class for anything that can be part of a line in the Writer layout.
void PrtWidth(SwTwips nNewWidth)
bool IsMarginPortion() const
SwLinePortion * GetNextPortion() const
PortionType GetWhichPor() const
virtual SwLinePortion * Append(SwLinePortion *pPortion)
TextFrameIndex GetLen() const
SwLinePortion * FindLastPortion()
bool IsDropPortion() const
bool IsTabLeftPortion() const
bool IsBreakPortion() const
bool IsMultiPortion() const
bool IsFlyPortion() const
bool InFixMargGrp() const
void AdjustRight(const SwLineLayout *pCurr)
In the outer loop all portions are inspected - the GluePortions at the end are processed first.
bool HasTabulator() const
Collection of SwLineLayout instances, represents the paragraph text in Writer layout.
SwScriptInfo & GetScriptInfo()
Of course Writer needs its own rectangles.
void Height(tools::Long nNew)
void Top(const tools::Long nTop)
void Bottom(const tools::Long nBottom)
void Pos(const Point &rNew)
void Left(const tools::Long nLeft)
void Width(tools::Long nNew)
void SetOffset(const SwTwips nNew)
void ClearNoKashidaLine(TextFrameIndex nStt, TextFrameIndex nLen)
Clear forced blank justification for a given line.
void MarkKashidasInvalid(sal_Int32 nCnt, const TextFrameIndex *pKashidaPositions)
Marks nCnt kashida positions as invalid pKashidaPositions: array of char indices relative to the para...
sal_Int32 KashidaJustify(KernArray *pKernArray, sal_Bool *pKashidaArray, TextFrameIndex nStt, TextFrameIndex nLen, tools::Long nSpaceAdd=0) const
Performs a kashida justification on the kerning array.
void ClearKashidaInvalid(size_t nKashPos)
void GetKashidaPositions(TextFrameIndex nStt, TextFrameIndex nLen, std::vector< TextFrameIndex > &rKashidaPosition)
retrieves kashida opportunities for a given text range.
size_t CountKashida() const
static bool IsArabicText(const OUString &rText, TextFrameIndex nStt, TextFrameIndex nLen)
Checks if text is Arabic text.
void SetNoKashidaLine(TextFrameIndex nStt, TextFrameIndex nLen)
Use regular blank justification instead of kashdida justification for the given line of text.
TextFrameIndex NextScriptChg(TextFrameIndex nPos) const
SwMarginPortion * CalcRightMargin(SwLineLayout *pCurr, SwTwips nReal=0)
void CalcAdjLine(SwLineLayout *pCurr)
SwFlyPortion * CalcFlyPortion(const tools::Long nRealWidth, const SwRect &rCurrRect)
void CalcFlyAdjust(SwLineLayout *pCurr)
void CalcNewBlock(SwLineLayout *pCurr, const SwLinePortion *pStopAt, SwTwips nReal=0, bool bSkipKashida=false)
SwTwips CalcKanaAdj(SwLineLayout *pCurr)
The purpose of this class is to be the universal interface between formatting/text output and the pos...
SwRect GetFrame(const SwRect &rPortion) const
void SwitchVerticalToHorizontal(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from vertical to horizontal layout.
void SwitchLTRtoRTL(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from LTR to RTL layout.
void SwitchRTLtoLTR(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from RTL to LTR layout.
void SwitchHorizontalToVertical(SwRect &rRect) const
Calculates the coordinates of a rectangle when switching from horizontal to vertical layout.
SwParaPortion * GetParaPortion()
const SwLineLayout * NextLine()
TextFrameIndex GetLength() const
TextFrameIndex GetEnd() const
const SwLineLayout * GetNext() const
TextFrameIndex GetStart() const
SwTwips GetLineHeight() const
const SwLineLayout * Next()
const SwLineLayout * GetCurr() const
sal_Int32 GetLineNr() const
SwTextFrame * GetTextFrame()
sal_uInt16 GetDropLines() const
SwTextSizeInfo & GetInfo()
bool IsLastCenter() const
SwTwips GetLeftMargin() const
SvxAdjust GetAdjust() const
SwTwips GetLineStart() const
sal_uInt16 GetLineWidth() const
This portion represents a part of the paragraph string.
vcl::RenderContext * GetOut()
void SetIdx(const TextFrameIndex nNew)
sal_uInt16 GetMaxWidthDiff(const SwLinePortion *nKey)
const OUString & GetText() const
TextFrameIndex GetIdx() const
static bool lcl_CheckKashidaPositions(SwScriptInfo &rSI, SwTextSizeInfo &rInf, SwTextIter &rItr, sal_Int32 &rKashidas, TextFrameIndex &nGluePortion)
static bool lcl_CheckKashidaWidth(SwScriptInfo &rSI, SwTextSizeInfo &rInf, SwTextIter &rItr, sal_Int32 &rKashidas, TextFrameIndex &nGluePortion, const tools::Long nGluePortionWidth, tools::Long &nSpaceAdd)
double getLength(const B2DPolygon &rCandidate)
constexpr std::enable_if_t< std::is_signed_v< T >, std::make_unsigned_t< T > > make_unsigned(T value)
#define SPACING_PRECISION_FACTOR
constexpr sal_Int32 COMPLETE_STRING