Skip to content

Commit

Permalink
Merge pull request #193 from AvaloniaUI/textmate-support-bold-italic-…
Browse files Browse the repository at this point in the history
…underline

Textmate - support bold, italic and underline font styles
  • Loading branch information
Takoooooo authored Jan 28, 2022
2 parents 8bd1f0b + ad034e1 commit 5991c17
Show file tree
Hide file tree
Showing 4 changed files with 146 additions and 65 deletions.
37 changes: 37 additions & 0 deletions src/AvaloniaEdit.Demo/Resources/SampleFiles/text.log
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,43 @@
03/22 08:51:06 INFO :...read_physical_netif: index #4, interface CTCD0 has address 9.67.116.98, ifidx 4
03/22 08:51:06 INFO :...read_physical_netif: index #5, interface CTCD2 has address 9.67.117.98, ifidx 5
03/22 08:51:06 INFO :...read_physical_netif: index #6, interface LOOPBACK has address 127.0.0.1, ifidx 0
03/22 08:51:01 INFO :.main: *************** RSVP Agent started ***************
03/22 08:51:01 INFO :...locate_configFile: Specified configuration file: /u/user10/rsvpd1.conf
03/22 08:51:01 INFO :.main: Using log level 511
03/22 08:51:01 INFO :..settcpimage: Get TCP images rc - EDC8112I Operation not supported on socket.
03/22 08:51:01 INFO :..settcpimage: Associate with TCP/IP image name = TCPCS
03/22 08:51:02 INFO :..reg_process: registering process with the system
03/22 08:51:02 INFO :..reg_process: attempt OS/390 registration
03/22 08:51:02 INFO :..reg_process: return from registration rc=0
03/22 08:51:06 TRACE :...read_physical_netif: Home list entries returned = 7
03/22 08:51:06 INFO :...read_physical_netif: index #0, interface VLINK1 has address 129.1.1.1, ifidx 0
03/22 08:51:06 INFO :...read_physical_netif: index #1, interface TR1 has address 9.37.65.139, ifidx 1
03/22 08:51:06 INFO :...read_physical_netif: index #2, interface LINK11 has address 9.67.100.1, ifidx 2
03/22 08:51:06 INFO :...read_physical_netif: index #3, interface LINK12 has address 9.67.101.1, ifidx 3
03/22 08:51:06 INFO :...read_physical_netif: index #4, interface CTCD0 has address 9.67.116.98, ifidx 4
03/22 08:51:06 INFO :...read_physical_netif: index #5, interface CTCD2 has address 9.67.117.98, ifidx 5
03/22 08:51:06 INFO :...read_physical_netif: index #6, interface LOOPBACK has address 127.0.0.1, ifidx 0
03/22 08:51:06 ERROR :...read_physical_netif: index #6, interface LOOPBACK has address 127.0.0.1, ifidx 0
ConsoleApplication1.MyCustomException: some message .... ---> System.Exception: Oh noes, something went wrong
at ConsoleApplication1.SomeObject.OtherMethod() in C:\ConsoleApplication1\SomeObject.cs:line 24
at ConsoleApplication1.SomeObject..ctor() in C:\ConsoleApplication1\SomeObject.cs:line 14
at ConsoleApplication1.SomeObject..ctor() in C:\ConsoleApplication1\SomeObject.cs:line 18
at ConsoleApplication1.Program.DoSomething() in C:\ConsoleApplication1\Program.cs:line 23
at ConsoleApplication1.Program.Main(String[] args) in C:\ConsoleApplication1\Program.cs:line 13
03/22 08:51:06 INFO :....mailslot_create: creating mailslot for timer
03/22 08:51:06 INFO :...mailbox_register: mailbox allocated for timer
03/22 08:51:06 INFO :.....mailslot_create: creating mailslot for RSVP
03/22 08:51:06 INFO :....mailbox_register: mailbox allocated for rsvp
03/22 08:51:06 INFO :.....mailslot_create: creating mailslot for RSVP via UDP
03/22 08:51:06 WARNING:.....mailslot_create: setsockopt(MCAST_ADD) failed - EDC8116I Address not available.
03/22 08:51:06 INFO :....mailbox_register: mailbox allocated for rsvp-udp
03/22 08:51:06 TRACE :..entity_initialize: interface 129.1.1.1, entity for rsvp allocated and initialized
03/22 08:51:06 INFO :.....mailslot_create: creating mailslot for RSVP
03/22 08:51:06 INFO :....mailbox_register: mailbox allocated for rsvp
03/22 08:51:06 INFO :.....mailslot_create: creating mailslot for RSVP via UDP
03/22 08:51:06 WARNING:.....mailslot_create: setsockopt(MCAST_ADD) failed - EDC8116I Address not available.
03/22 08:51:06 INFO :....mailbox_register: mailbox allocated for rsvp-udp
03/22 08:51:06 TRACE :..entity_initialize: interface 9.37.65.139, entity for rsvp allocated and
03/22 08:51:06 INFO :....mailslot_create: creating mailslot for timer
03/22 08:51:06 INFO :...mailbox_register: mailbox allocated for timer
03/22 08:51:06 INFO :.....mailslot_create: creating mailslot for RSVP
Expand Down
82 changes: 43 additions & 39 deletions src/AvaloniaEdit.TextMate/GenericLineTransformer.cs
Original file line number Diff line number Diff line change
@@ -1,6 +1,4 @@
using Avalonia.Media;
using Avalonia.Media.Immutable;

using AvaloniaEdit.Document;
using AvaloniaEdit.Rendering;

Expand All @@ -15,62 +13,68 @@ protected override void ColorizeLine(DocumentLine line)

protected abstract void TransformLine(DocumentLine line, ITextRunConstructionContext context);

public void SetTextOpacity(DocumentLine line, int startIndex, int length, double opacity)
public void SetTextStyle(
DocumentLine line,
int startIndex,
int length,
IBrush foreground,
IBrush background,
FontStyle fontStyle,
FontWeight fontWeigth,
bool isUnderline)
{
int startOffset = 0;
int endOffset = 0;

if (startIndex >= 0 && length > 0)
{
if ((line.Offset + startIndex + length) > line.EndOffset)
{
length = (line.EndOffset - startIndex) - line.Offset - startIndex;
}

int startOffset = line.Offset + startIndex;
int endoffset = line.Offset + startIndex + length;

if (startOffset < CurrentContext.Document.TextLength && endoffset < CurrentContext.Document.TextLength)
{
ChangeLinePart(startOffset, endoffset, e =>
{
if (e.TextRunProperties.ForegroundBrush is ISolidColorBrush solidBrush)
{
e.TextRunProperties.ForegroundBrush = new ImmutableSolidColorBrush(solidBrush.Color, opacity);
}
});
}
startOffset = line.Offset + startIndex;
endOffset = line.Offset + startIndex + length;
}
else
{
ChangeLinePart(line.Offset, line.EndOffset, e =>
{
if (e.TextRunProperties.ForegroundBrush is ISolidColorBrush solidBrush)
{
e.TextRunProperties.ForegroundBrush = new ImmutableSolidColorBrush(solidBrush.Color, opacity);
}
});
startOffset = line.Offset;
endOffset = line.EndOffset;
}

if (startOffset > CurrentContext.Document.TextLength ||
endOffset > CurrentContext.Document.TextLength)
return;

ChangeLinePart(
startOffset,
endOffset,
visualLine => ChangeVisualLine(visualLine, foreground, background, fontStyle, fontWeigth, isUnderline));
}

public void SetTextStyle(DocumentLine line, int startIndex, int length, IBrush foreground)
void ChangeVisualLine(
VisualLineElement visualLine,
IBrush foreground,
IBrush background,
FontStyle fontStyle,
FontWeight fontWeigth,
bool isUnderline)
{
if (startIndex >= 0 && length > 0)
{
if ((line.Offset + startIndex + length) > line.EndOffset)
{
length = (line.EndOffset - startIndex) - line.Offset - startIndex;
}
if (foreground != null)
visualLine.TextRunProperties.ForegroundBrush = foreground;

int startOffset = line.Offset + startIndex;
int endoffset = line.Offset + startIndex + length;
if (background != null)
visualLine.TextRunProperties.BackgroundBrush = background;

if (startOffset < CurrentContext.Document.TextLength && endoffset < CurrentContext.Document.TextLength)
{
ChangeLinePart(startOffset, endoffset, e => { e.TextRunProperties.ForegroundBrush = foreground; });
}
}
else
visualLine.TextRunProperties.Underline = isUnderline;

if (visualLine.TextRunProperties.Typeface.Style != fontStyle ||
visualLine.TextRunProperties.Typeface.Weight != fontWeigth)
{
ChangeLinePart(line.Offset, line.EndOffset, e => { e.TextRunProperties.ForegroundBrush = foreground; });
visualLine.TextRunProperties.Typeface = new Typeface(
visualLine.TextRunProperties.Typeface.FontFamily, fontStyle, fontWeigth);
}

}
}
}
32 changes: 18 additions & 14 deletions src/AvaloniaEdit.TextMate/TextMateColoringTransformer.cs
Original file line number Diff line number Diff line change
Expand Up @@ -92,17 +92,13 @@ public void SetGrammar(IGrammar grammar)
}
}

bool ForegroundTextTransformation.IColorMap.Contains(int foregroundColor)
IBrush ForegroundTextTransformation.IColorMap.GetBrush(int colorId)
{
if (_brushes == null)
return false;
return null;

return _brushes.ContainsKey(foregroundColor);
}

IBrush ForegroundTextTransformation.IColorMap.GetForegroundBrush(int foregroundColor)
{
return _brushes[foregroundColor];
_brushes.TryGetValue(colorId, out IBrush result);
return result;
}

protected override void TransformLine(DocumentLine line, ITextRunConstructionContext context)
Expand Down Expand Up @@ -142,16 +138,24 @@ private void ProcessTokens(int lineNumber, List<TMToken> tokens)

var lineOffset = _document.GetLineByNumber(lineNumber).Offset;

int foreground = 0;
int background = 0;
int fontStyle = 0;

foreach (var themeRule in _theme.Match(token.Scopes))
{
if (themeRule.foreground > 0 && _brushes.ContainsKey(themeRule.foreground))
{
_transformations.Add(new ForegroundTextTransformation(this, lineOffset + startIndex,
lineOffset + endIndex, themeRule.foreground));
if (foreground == 0 && themeRule.foreground > 0)
foreground = themeRule.foreground;

if (background == 0 && themeRule.background > 0)
background = themeRule.background;

break;
}
if (fontStyle == 0 && themeRule.fontStyle > 0)
fontStyle = themeRule.fontStyle;
}

_transformations.Add(new ForegroundTextTransformation(this, lineOffset + startIndex,
lineOffset + endIndex, foreground, background, fontStyle));
}
}

Expand Down
60 changes: 48 additions & 12 deletions src/AvaloniaEdit.TextMate/TextTransformation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,30 +24,34 @@ public class ForegroundTextTransformation : TextTransformation
{
public interface IColorMap
{
bool Contains(int foregroundColor);
IBrush GetForegroundBrush(int foregroundColor);
IBrush GetBrush(int color);
}

public ForegroundTextTransformation(IColorMap colorMap, int startOffset, int endOffset, int brushId) : base(startOffset, endOffset)
int _foreground;
int _background;
int _fontStyle;

public ForegroundTextTransformation(
IColorMap colorMap,
int startOffset,
int endOffset,
int foreground,
int background,
int fontStyle) : base(startOffset, endOffset)
{
_colorMap = colorMap;
Foreground = brushId;
_foreground = foreground;
_background = background;
_fontStyle = fontStyle;
}

public int Foreground { get; set; }

public override void Transform(GenericLineTransformer transformer, DocumentLine line)
{
if (Length == 0)
{
return;
}

if (!_colorMap.Contains(Foreground))
{
return;
}

var formattedOffset = 0;
var endOffset = line.EndOffset;

Expand All @@ -61,7 +65,39 @@ public override void Transform(GenericLineTransformer transformer, DocumentLine
endOffset = EndOffset;
}

transformer.SetTextStyle(line, formattedOffset, endOffset - line.Offset - formattedOffset, _colorMap.GetForegroundBrush(Foreground));
transformer.SetTextStyle(line, formattedOffset, endOffset - line.Offset - formattedOffset,
_colorMap.GetBrush(_foreground),
_colorMap.GetBrush(_background),
GetFontStyle(),
GetFontWeight(),
IsUnderline());
}

FontStyle GetFontStyle()
{
if (_fontStyle != TextMateSharp.Themes.FontStyle.NotSet &&
(_fontStyle & TextMateSharp.Themes.FontStyle.Italic) != 0)
return FontStyle.Italic;

return FontStyle.Normal;
}

FontWeight GetFontWeight()
{
if (_fontStyle != TextMateSharp.Themes.FontStyle.NotSet &&
(_fontStyle & TextMateSharp.Themes.FontStyle.Bold) != 0)
return FontWeight.Bold;

return FontWeight.Regular;
}

bool IsUnderline()
{
if (_fontStyle != TextMateSharp.Themes.FontStyle.NotSet &&
(_fontStyle & TextMateSharp.Themes.FontStyle.Underline) != 0)
return true;

return false;
}

IColorMap _colorMap;
Expand Down

0 comments on commit 5991c17

Please sign in to comment.