@ -11,10 +11,10 @@ namespace Avalonia.Media.TextFormatting
private readonly double _ paragraphWidth ;
private readonly TextParagraphProperties _ paragraphProperties ;
private TextLineMetrics _ textLineMetrics ;
private readonly FlowDirection _f lowDirection ;
private readonly FlowDirection _ resolvedF lowDirection;
public TextLineImpl ( List < DrawableTextRun > textRuns , int firstTextSourceIndex , int length , double paragraphWidth ,
TextParagraphProperties paragraphProperties , FlowDirection f lowDirection = FlowDirection . LeftToRight ,
TextParagraphProperties paragraphProperties , FlowDirection resolvedF lowDirection = FlowDirection . LeftToRight ,
TextLineBreak ? lineBreak = null , bool hasCollapsed = false )
{
FirstTextSourceIndex = firstTextSourceIndex ;
@ -26,7 +26,7 @@ namespace Avalonia.Media.TextFormatting
_ paragraphWidth = paragraphWidth ;
_ paragraphProperties = paragraphProperties ;
_f lowDirection = f lowDirection;
_ resolvedF lowDirection = resolvedF lowDirection;
}
/// <inheritdoc/>
@ -137,7 +137,7 @@ namespace Avalonia.Media.TextFormatting
}
var collapsedLine = new TextLineImpl ( collapsedRuns , FirstTextSourceIndex , Length , _ paragraphWidth , _ paragraphProperties ,
_f lowDirection , TextLineBreak , true ) ;
_ resolvedF lowDirection, TextLineBreak , true ) ;
if ( collapsedRuns . Count > 0 )
{
@ -168,7 +168,7 @@ namespace Avalonia.Media.TextFormatting
return shapedTextCharacters . GlyphRun . GetCharacterHitFromDistance ( distance , out _ ) ;
}
return _f lowDirection = = FlowDirection . LeftToRight ?
return _ resolvedF lowDirection = = FlowDirection . LeftToRight ?
new CharacterHit ( FirstTextSourceIndex ) :
new CharacterHit ( FirstTextSourceIndex + Length ) ;
}
@ -261,7 +261,7 @@ namespace Avalonia.Media.TextFormatting
//Look at the left and right edge of the current run
if ( currentRun . IsLeftToRight )
{
if ( _f lowDirection = = FlowDirection . LeftToRight & & ( lastRun = = null | | lastRun . IsLeftToRight ) )
if ( _ resolvedF lowDirection = = FlowDirection . LeftToRight & & ( lastRun = = null | | lastRun . IsLeftToRight ) )
{
if ( characterIndex < = currentPosition )
{
@ -846,7 +846,7 @@ namespace Avalonia.Media.TextFormatting
// Build up the collection of ordered runs.
var run = _ textRuns [ 0 ] ;
OrderedBidiRun orderedRun = new ( run , GetRunBidiLevel ( run , _f lowDirection ) ) ;
OrderedBidiRun orderedRun = new ( run , GetRunBidiLevel ( run , _ resolvedF lowDirection) ) ;
var current = orderedRun ;
@ -854,7 +854,7 @@ namespace Avalonia.Media.TextFormatting
{
run = _ textRuns [ i ] ;
current . Next = new OrderedBidiRun ( run , GetRunBidiLevel ( run , _f lowDirection ) ) ;
current . Next = new OrderedBidiRun ( run , GetRunBidiLevel ( run , _ resolvedF lowDirection) ) ;
current = current . Next ;
}
@ -873,7 +873,7 @@ namespace Avalonia.Media.TextFormatting
{
var currentRun = _ textRuns [ i ] ;
var level = GetRunBidiLevel ( currentRun , _f lowDirection ) ;
var level = GetRunBidiLevel ( currentRun , _ resolvedF lowDirection) ;
if ( level > max )
{
@ -1353,8 +1353,7 @@ namespace Avalonia.Media.TextFormatting
}
}
var start = GetParagraphOffsetX ( width , widthIncludingWhitespace , _ paragraphWidth ,
_ paragraphProperties . TextAlignment , _ paragraphProperties . FlowDirection ) ;
var start = GetParagraphOffsetX ( width , widthIncludingWhitespace ) ;
if ( ! double . IsNaN ( lineHeight ) & & ! MathUtilities . IsZero ( lineHeight ) )
{
@ -1368,6 +1367,55 @@ namespace Avalonia.Media.TextFormatting
- ascent , trailingWhitespaceLength , width , widthIncludingWhitespace ) ;
}
/// <summary>
/// Gets the text line offset x.
/// </summary>
/// <param name="width">The line width.</param>
/// <param name="widthIncludingTrailingWhitespace">The paragraph width including whitespace.</param>
/// <returns>The paragraph offset.</returns>
private double GetParagraphOffsetX ( double width , double widthIncludingTrailingWhitespace )
{
if ( double . IsPositiveInfinity ( _ paragraphWidth ) )
{
return 0 ;
}
var textAlignment = _ paragraphProperties . TextAlignment ;
var paragraphFlowDirection = _ paragraphProperties . FlowDirection ;
switch ( textAlignment )
{
case TextAlignment . Start :
{
textAlignment = paragraphFlowDirection = = FlowDirection . LeftToRight ? TextAlignment . Left : TextAlignment . Right ;
break ;
}
case TextAlignment . End :
{
textAlignment = paragraphFlowDirection = = FlowDirection . RightToLeft ? TextAlignment . Left : TextAlignment . Right ;
break ;
}
case TextAlignment . DetectFromContent :
{
textAlignment = _ resolvedFlowDirection = = FlowDirection . LeftToRight ? TextAlignment . Left : TextAlignment . Right ;
break ;
}
}
switch ( textAlignment )
{
case TextAlignment . Center :
return Math . Max ( 0 , ( _ paragraphWidth - width ) / 2 ) ;
case TextAlignment . Right :
return Math . Max ( 0 , _ paragraphWidth - widthIncludingTrailingWhitespace ) ;
default :
return 0 ;
}
}
private sealed class OrderedBidiRun
{
public OrderedBidiRun ( DrawableTextRun run , sbyte level )