Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

TextFormatter port #216

Merged
merged 36 commits into from
Aug 2, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
36 commits
Select commit Hold shift + click to select a range
9a84b61
Start porting to Avalonia's TextFormatter
Gillibald Mar 7, 2022
b659e87
Add missing methods via extensions
Gillibald Mar 7, 2022
94cbc94
First successfull render
Gillibald Mar 9, 2022
5e228f0
Use latest Avalonia preview
Gillibald Mar 9, 2022
6684fe6
Fix CreateTextRun
Gillibald Mar 9, 2022
6152625
Fix LinkElementGenerator
Gillibald Mar 9, 2022
19dc0f3
Redo Avalonia port of AvalonEdit.Rendering
Gillibald Mar 10, 2022
48ca598
More fixes
Gillibald Mar 11, 2022
5ca9e4a
More fixes
Gillibald Mar 11, 2022
10efcfb
Merge branch 'master' into feature/TextFormatterPort
Gillibald Mar 11, 2022
7618d48
Merge branch 'master' into feature/TextFormatterPort
Gillibald Mar 29, 2022
c41ff6a
More fixes
Gillibald Mar 30, 2022
bd2592b
Merge branch 'feature/TextFormatterPort' of https://github.com/Avalon…
Gillibald Mar 30, 2022
ddeffb9
1.35 is working as previously for LineHeight
danipen Mar 30, 2022
9e0fa63
Add button to view tabs/spaces/EOL
danipen Mar 30, 2022
b80d16b
More fixes
Gillibald Apr 4, 2022
2023fa3
Merge branch 'feature/TextFormatterPort' of https://github.com/Avalon…
Gillibald Apr 4, 2022
f48f5f0
Merge branch 'master' into feature/TextFormatterPort
Gillibald Apr 4, 2022
d12730e
Fix release build
Gillibald Apr 11, 2022
5f24608
Merge branch 'feature/TextFormatterPort' of https://github.com/Avalon…
Gillibald Apr 11, 2022
b11e3be
Merge branch 'master' into feature/TextFormatterPort
Gillibald Apr 11, 2022
dff6483
Update Avalonia
Gillibald Apr 21, 2022
6045c38
Update deps
Gillibald Apr 27, 2022
977d287
Remove redundant tests
Gillibald Apr 27, 2022
3100a15
Enable Cascadia Code font (if available) to enable font ligatures
danipen May 16, 2022
62da7cc
Use better defaults for NonPrintableCharacterBrushProperty
danipen May 16, 2022
3edec2c
Merge branch 'master' into feature/TextFormatterPort
Gillibald May 17, 2022
bd6e137
Update deps
Gillibald May 18, 2022
b111bab
Update deps
Gillibald May 28, 2022
d8b3021
Merge
Gillibald May 28, 2022
7ed1992
Merge branch 'master' into feature/TextFormatterPort
Gillibald May 28, 2022
749f350
Update deps
Gillibald Aug 2, 2022
2a49e38
Merge branch 'feature/TextFormatterPort' of https://github.com/Avalon…
Gillibald Aug 2, 2022
5c573d4
Merge
Gillibald Aug 2, 2022
11037c2
Fix Demo text decorations
Gillibald Aug 2, 2022
e3f2957
Adjust version
Gillibald Aug 2, 2022
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
<PropertyGroup>
<LangVersion>latest</LangVersion>
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
<AvaloniaVersion>0.10.12</AvaloniaVersion>
<AvaloniaVersion>0.10.999-cibuild0022712-beta</AvaloniaVersion>
<TextMateSharpVersion>1.0.41</TextMateSharpVersion>
<NewtonsoftJsonVersion>13.0.1</NewtonsoftJsonVersion>
<Version>0.10.12.2</Version>
<Version>0.10.999-cibuild0022712-beta</Version>
</PropertyGroup>
</Project>
1 change: 1 addition & 0 deletions NuGet.config
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,6 @@
<clear />
<add key="nuget.org" value="https://api.nuget.org/v3/index.json" protocolVersion="3" />
<add key="AvaloniaCI" value="https://nuget.avaloniaui.net/repository/avalonia-all/index.json" />
<add key="CI Feed" value="https://pkgs.dev.azure.com/AvaloniaUI/AvaloniaUI/_packaging/avalonia-all/nuget/v3/index.json" />
</packageSources>
</configuration>
2 changes: 2 additions & 0 deletions src/AvaloniaEdit.Demo/AvaloniaEdit.Demo.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,9 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)" />
<PackageReference Include="Avalonia.Desktop" Version="$(AvaloniaVersion)" />
<PackageReference Include="Avalonia.Themes.Fluent" Version="$(AvaloniaVersion)"/>
<ProjectReference Include="..\AvaloniaEdit\AvaloniaEdit.csproj" />
<ProjectReference Include="..\AvaloniaEdit.TextMate\AvaloniaEdit.TextMate.csproj" />
</ItemGroup>
Expand Down
13 changes: 8 additions & 5 deletions src/AvaloniaEdit.Demo/MainWindow.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -17,16 +17,19 @@
<Path Fill="White" Data="M2.75 5C2.33579 5 2 5.33579 2 5.75C2 6.16421 2.33579 6.5 2.75 6.5H21.25C21.6642 6.5 22 6.16421 22 5.75C22 5.33579 21.6642 5 21.25 5H2.75Z M2.75 11.5C2.33579 11.5 2 11.8358 2 12.25C2 12.6642 2.33579 13 2.75 13H19C20.3807 13 21.5 14.1193 21.5 15.5C21.5 16.8807 20.3807 18 19 18H14.5607L15.2803 17.2803C15.5732 16.9874 15.5732 16.5126 15.2803 16.2197C14.9874 15.9268 14.5126 15.9268 14.2197 16.2197L12.2197 18.2197C11.9268 18.5126 11.9268 18.9874 12.2197 19.2803L14.2197 21.2803C14.5126 21.5732 14.9874 21.5732 15.2803 21.2803C15.5732 20.9874 15.5732 20.5126 15.2803 20.2197L14.5607 19.5H19C21.2091 19.5 23 17.7091 23 15.5C23 13.2909 21.2091 11.5 19 11.5H2.75Z M2 18.75C2 18.3358 2.33579 18 2.75 18H9.25C9.66421 18 10 18.3358 10 18.75C10 19.1642 9.66421 19.5 9.25 19.5H2.75C2.33579 19.5 2 19.1642 2 18.75Z" />
</ToggleButton.Content>
</ToggleButton>
<Button Name="addControlBtn" Content="Add Button" />
<Button Name="clearControlBtn" Content="Clear Buttons" />
<ComboBox Name="syntaxModeCombo" />
<Button Name="changeThemeBtn" Content="Change theme"/>
<ToggleButton Name="viewTabs" Content="View tabs" IsChecked="{Binding #Editor.Options.ShowTabs}" VerticalAlignment="Stretch" VerticalContentAlignment="Center"/>
<ToggleButton Name="viewSpaces" Content="View spaces" IsChecked="{Binding #Editor.Options.ShowSpaces}" VerticalAlignment="Stretch" VerticalContentAlignment="Center"/>
<ToggleButton Name="viewEOL" Content="View EOL" IsChecked="{Binding #Editor.Options.ShowEndOfLine}" VerticalAlignment="Stretch" VerticalContentAlignment="Center"/>
<Button Name="addControlBtn" Content="Add Button" VerticalAlignment="Stretch" VerticalContentAlignment="Center"/>
<Button Name="clearControlBtn" Content="Clear Buttons" VerticalAlignment="Stretch" VerticalContentAlignment="Center"/>
<ComboBox Name="syntaxModeCombo" VerticalAlignment="Stretch" VerticalContentAlignment="Center"/>
<Button Name="changeThemeBtn" Content="Change theme" VerticalAlignment="Stretch" VerticalContentAlignment="Center"/>
</StackPanel>
<StackPanel Name="StatusBar" Background="Purple" Height="25" DockPanel.Dock="Bottom" Orientation="Horizontal">
<TextBlock Name="StatusText" Text="Ready" Margin="5 0 0 0" VerticalAlignment="Center" FontSize="12"/>
</StackPanel>
<AvalonEdit:TextEditor Name="Editor"
FontFamily="Consolas,Menlo,Monospace"
FontFamily="Cascadia Code,Consolas,Menlo,Monospace"
Margin="30"
Foreground="#D4D4D4"
HorizontalScrollBarVisibility="Auto"
Expand Down
51 changes: 39 additions & 12 deletions src/AvaloniaEdit.Demo/MainWindow.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -17,10 +17,10 @@
using AvaloniaEdit.Rendering;
using AvaloniaEdit.TextMate;
using TextMateSharp.Grammars;

using Avalonia.Diagnostics;
namespace AvaloniaEdit.Demo
{
using Pair = KeyValuePair<int, IControl>;
using Pair = KeyValuePair<int, Control>;

public class MainWindow : Window
{
Expand All @@ -40,19 +40,20 @@ public class MainWindow : Window

public MainWindow()
{

InitializeComponent();

_textEditor = this.FindControl<TextEditor>("Editor");
_textEditor.Background = Brushes.Transparent;
_textEditor.ShowLineNumbers = true;
_textEditor.ContextMenu = new ContextMenu
{
Items = new List<MenuItem>
{
_textEditor.ContextMenu = new ContextMenu
{
Items = new List<MenuItem>
{
new MenuItem { Header = "Copy", InputGesture = new KeyGesture(Key.C, KeyModifiers.Control) },
new MenuItem { Header = "Paste", InputGesture = new KeyGesture(Key.V, KeyModifiers.Control) },
new MenuItem { Header = "Cut", InputGesture = new KeyGesture(Key.X, KeyModifiers.Control) }
}
}
};
_textEditor.TextArea.Background = this.Background;
_textEditor.TextArea.TextEntered += textEditor_TextArea_TextEntered;
Expand Down Expand Up @@ -106,7 +107,7 @@ public MainWindow()

private void Caret_PositionChanged(object sender, EventArgs e)
{
_statusTextBlock.Text = string.Format("Line {0} Column {1}",
_statusTextBlock.Text = string.Format("Line {0} Column {1}",
_textEditor.TextArea.Caret.Line,
_textEditor.TextArea.Caret.Column);
}
Expand Down Expand Up @@ -170,13 +171,13 @@ private void InitializeComponent()
AvaloniaXamlLoader.Load(this);
}

private void AddControlButton_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
private void AddControlButton_Click(object sender, RoutedEventArgs e)
{
_generator.controls.Add(new Pair(_textEditor.CaretOffset, new Button() { Content = "Click me" }));
_textEditor.TextArea.TextView.Redraw();
}

private void ClearControlButton_Click(object sender, Avalonia.Interactivity.RoutedEventArgs e)
private void ClearControlButton_Click(object sender, RoutedEventArgs e)
{
//TODO: delete elements using back key
_generator.controls.Clear();
Expand Down Expand Up @@ -259,15 +260,41 @@ protected override void ColorizeLine(DocumentLine line)
ChangeLinePart(
line.Offset + indexOfUnderline,
line.Offset + indexOfUnderline + "underline".Length,
visualLine => visualLine.TextRunProperties.Underline = true);
visualLine =>
{
if (visualLine.TextRunProperties.TextDecorations != null)
{
var textDecorations = new TextDecorationCollection(visualLine.TextRunProperties.TextDecorations) { TextDecorations.Underline[0] };

visualLine.TextRunProperties.SetTextDecorations(textDecorations);
}
else
{
visualLine.TextRunProperties.SetTextDecorations(TextDecorations.Underline);
}
}
);
}

if (indexOfStrikeThrough != -1)
{
ChangeLinePart(
line.Offset + indexOfStrikeThrough,
line.Offset + indexOfStrikeThrough + "strikethrough".Length,
visualLine => visualLine.TextRunProperties.Strikethrough = true);
visualLine =>
{
if (visualLine.TextRunProperties.TextDecorations != null)
{
var textDecorations = new TextDecorationCollection(visualLine.TextRunProperties.TextDecorations) { TextDecorations.Strikethrough[0] };

visualLine.TextRunProperties.SetTextDecorations(textDecorations);
}
else
{
visualLine.TextRunProperties.SetTextDecorations(TextDecorations.Strikethrough);
}
}
);
}
}
}
Expand Down
1 change: 1 addition & 0 deletions src/AvaloniaEdit.TextMate/AvaloniaEdit.TextMate.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
</ItemGroup>

<ItemGroup>
<PackageReference Include="Avalonia" Version="$(AvaloniaVersion)" />
<PackageReference Include="TextMateSharp" Version="$(TextMateSharpVersion)" />
<PackageReference Include="TextMateSharp.Grammars" Version="$(TextMateSharpVersion)" />
</ItemGroup>
Expand Down
13 changes: 8 additions & 5 deletions src/AvaloniaEdit.TextMate/GenericLineTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -77,18 +77,21 @@ void ChangeVisualLine(
bool isUnderline)
{
if (foreground != null)
visualLine.TextRunProperties.ForegroundBrush = foreground;
visualLine.TextRunProperties.SetForegroundBrush(foreground);

if (background != null)
visualLine.TextRunProperties.BackgroundBrush = background;
visualLine.TextRunProperties.SetBackgroundBrush(background);

visualLine.TextRunProperties.Underline = isUnderline;
if (isUnderline)
{
visualLine.TextRunProperties.SetTextDecorations(TextDecorations.Underline);
}

if (visualLine.TextRunProperties.Typeface.Style != fontStyle ||
visualLine.TextRunProperties.Typeface.Weight != fontWeigth)
{
visualLine.TextRunProperties.Typeface = new Typeface(
visualLine.TextRunProperties.Typeface.FontFamily, fontStyle, fontWeigth);
visualLine.TextRunProperties.SetTypeface(new Typeface(
visualLine.TextRunProperties.Typeface.FontFamily, fontStyle, fontWeigth));
}

}
Expand Down
2 changes: 1 addition & 1 deletion src/AvaloniaEdit.TextMate/TextMateColoringTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -232,7 +232,7 @@ public void ModelTokensChanged(ModelTokensChangedEvent e)

_textView.Redraw(
firstLineToRedraw.Offset,
(lastLineToRedraw.Offset + lastLineToRedraw.TotalLength) - firstLineToRedraw.Offset);
(lastLineToRedraw.Offset + lastLineToRedraw.TotalLength) - firstLineToRedraw.Offset, DispatcherPriority.Normal);
});
}

Expand Down
78 changes: 38 additions & 40 deletions src/AvaloniaEdit/Editing/Caret.cs
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,11 @@ internal Caret(TextArea textArea)
_textView = textArea.TextView;
_position = new TextViewPosition(1, 1, 0);

_caretAdorner = new CaretLayer(textArea);
_textView.InsertLayer(_caretAdorner, KnownLayer.Caret, LayerInsertionPosition.Replace);
_textView.VisualLinesChanged += TextView_VisualLinesChanged;
_textView.ScrollOffsetChanged += TextView_ScrollOffsetChanged;
}
_caretAdorner = new CaretLayer(textArea);
_textView.InsertLayer(_caretAdorner, KnownLayer.Caret, LayerInsertionPosition.Replace);
_textView.VisualLinesChanged += TextView_VisualLinesChanged;
_textView.ScrollOffsetChanged += TextView_ScrollOffsetChanged;
}

internal void UpdateIfVisible()
{
Expand Down Expand Up @@ -402,41 +402,39 @@ private Rect CalcCaretRectangle(VisualLine visualLine)
lineBottom - lineTop);
}

private Rect CalcCaretOverstrikeRectangle(VisualLine visualLine)
{
if (!_visualColumnValid)
{
RevalidateVisualColumn(visualLine);
}

var currentPos = _position.VisualColumn;
// The text being overwritten in overstrike mode is everything up to the next normal caret stop
var nextPos = visualLine.GetNextCaretPosition(currentPos, LogicalDirection.Forward, CaretPositioningMode.Normal, true);
var textLine = visualLine.GetTextLine(currentPos);

Rect r;
if (currentPos < visualLine.VisualLength)
{
// If the caret is within the text, use GetTextBounds() for the text being overwritten.
// This is necessary to ensure the rectangle is calculated correctly in bidirectional text.
r = textLine.GetTextBounds(currentPos, nextPos - currentPos);
r = r.WithY(r.Y + visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.LineTop));
}
else
{
// If the caret is at the end of the line (or in virtual space),
// use the visual X position of currentPos and nextPos (one or more of which will be in virtual space)
var xPos = visualLine.GetTextLineVisualXPosition(textLine, currentPos);
var xPos2 = visualLine.GetTextLineVisualXPosition(textLine, nextPos);
var lineTop = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.TextTop);
var lineBottom = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.TextBottom);
r = new Rect(xPos, lineTop, xPos2 - xPos, lineBottom - lineTop);
}
// If the caret is too small (e.g. in front of zero-width character), ensure it's still visible
if (r.Width < CaretWidth)
r = r.WithWidth(CaretWidth);
return r;
}
Rect CalcCaretOverstrikeRectangle(VisualLine visualLine)
{
if (!_visualColumnValid) {
RevalidateVisualColumn(visualLine);
}

int currentPos = _position.VisualColumn;
// The text being overwritten in overstrike mode is everything up to the next normal caret stop
int nextPos = visualLine.GetNextCaretPosition(currentPos, LogicalDirection.Forward, CaretPositioningMode.Normal, true);
var textLine = visualLine.GetTextLine(currentPos);

Rect r;
if (currentPos < visualLine.VisualLength) {
// If the caret is within the text, use GetTextBounds() for the text being overwritten.
// This is necessary to ensure the rectangle is calculated correctly in bidirectional text.
var textBounds = textLine.GetTextBounds(currentPos, nextPos - currentPos)[0];
r = textBounds.Rectangle;
var y = r.Y + visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.LineTop);
r = r.WithY(y);
} else {
// If the caret is at the end of the line (or in virtual space),
// use the visual X position of currentPos and nextPos (one or more of which will be in virtual space)
double xPos = visualLine.GetTextLineVisualXPosition(textLine, currentPos);
double xPos2 = visualLine.GetTextLineVisualXPosition(textLine, nextPos);
double lineTop = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.TextTop);
double lineBottom = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.TextBottom);
r = new Rect(xPos, lineTop, xPos2 - xPos, lineBottom - lineTop);
}
// If the caret is too small (e.g. in front of zero-width character), ensure it's still visible
if (r.Width < CaretWidth)
r = r.WithWidth(CaretWidth);
return r;
}

/// <summary>
/// Returns the caret rectangle. The coordinate system is in device-independent pixels from the top of the document.
Expand Down
3 changes: 2 additions & 1 deletion src/AvaloniaEdit/Editing/CaretNavigationCommandHandler.cs
Original file line number Diff line number Diff line change
Expand Up @@ -22,10 +22,11 @@
using Avalonia;
using AvaloniaEdit.Document;
using AvaloniaEdit.Rendering;
using AvaloniaEdit.Text;
using AvaloniaEdit.Utils;
using Avalonia.Input;
using Avalonia.Input.Platform;
using Avalonia.Media.TextFormatting;
using LogicalDirection = AvaloniaEdit.Document.LogicalDirection;

namespace AvaloniaEdit.Editing
{
Expand Down
Loading