From 54687bd5dcf322096a8c8cf8dbc1374cb5ce49f9 Mon Sep 17 00:00:00 2001 From: =?utf8?q?Jean-Philippe=20Bruy=C3=A8re?= Date: Tue, 4 Mar 2025 13:52:08 +0100 Subject: [PATCH] move textBuffer to drawing2d and several other text classes and measure --- Crow/src/ExtensionsMethods.cs | 33 +------ .../Text => Drawing2D/src}/CharLocation.cs | 0 .../src/ExtensionsMethods.cs | 38 ++++++- {Crow/src/Text => Drawing2D/src}/LineSpan.cs | 0 {Crow/src/2d => Drawing2D/src}/Measure.cs | 0 Drawing2D/src/TextBuffer.cs | 99 +++++++++++++++++++ .../src/Text => Drawing2D/src}/TextChange.cs | 0 {Crow/src/Text => Drawing2D/src}/TextLine.cs | 0 .../src}/TextLineCollection.cs | 0 {Crow/src/Text => Drawing2D/src}/TextSpan.cs | 0 10 files changed, 134 insertions(+), 36 deletions(-) rename {Crow/src/Text => Drawing2D/src}/CharLocation.cs (100%) rename Crow/src/Text/Extensions.cs => Drawing2D/src/ExtensionsMethods.cs (61%) rename {Crow/src/Text => Drawing2D/src}/LineSpan.cs (100%) rename {Crow/src/2d => Drawing2D/src}/Measure.cs (100%) create mode 100644 Drawing2D/src/TextBuffer.cs rename {Crow/src/Text => Drawing2D/src}/TextChange.cs (100%) rename {Crow/src/Text => Drawing2D/src}/TextLine.cs (100%) rename {Crow/src/Text => Drawing2D/src}/TextLineCollection.cs (100%) rename {Crow/src/Text => Drawing2D/src}/TextSpan.cs (100%) diff --git a/Crow/src/ExtensionsMethods.cs b/Crow/src/ExtensionsMethods.cs index ed226b8a..302caec9 100644 --- a/Crow/src/ExtensionsMethods.cs +++ b/Crow/src/ExtensionsMethods.cs @@ -179,32 +179,14 @@ namespace Crow } return Alignment.Center; } - public static void Raise(this EventHandler handler, object sender, EventArgs e) - { - handler?.Invoke (sender, e); - } - public static void Raise(this EventHandler handler, object sender, T e) - { - handler?.Invoke (sender, e); - } - public static byte[] GetBytes(this string str) - { - byte[] bytes = new byte[str.Length * sizeof(char)]; - System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length); - return bytes; - } - public static bool IsWhiteSpaceOrNewLine (this char c) - { - return c == '\t' || c.IsAnyLineBreakCharacter() || char.IsWhiteSpace (c); - } - public static object GetDefaultValue(this object obj) + /*public static object GetDefaultValue(this object obj) { Type t = obj.GetType (); if (t.IsValueType) return Activator.CreateInstance (t); return null; - } + }*/ public static FileSystemInfo [] GetFileSystemInfosOrdered (this DirectoryInfo di) { try { @@ -213,17 +195,6 @@ namespace Crow return null; } } - - internal static bool IsAnyLineBreakCharacter (this char c) - => c == '\n' || c == '\r' || c == '\u0085' || c == '\u2028' || c == '\u2029'; - - public static bool TryGetResource (this Assembly a, string resId, out Stream stream) { - stream = null; - if (a == null) - return false; - stream = a.GetManifestResourceStream (resId); - return stream != null; - } } } diff --git a/Crow/src/Text/CharLocation.cs b/Drawing2D/src/CharLocation.cs similarity index 100% rename from Crow/src/Text/CharLocation.cs rename to Drawing2D/src/CharLocation.cs diff --git a/Crow/src/Text/Extensions.cs b/Drawing2D/src/ExtensionsMethods.cs similarity index 61% rename from Crow/src/Text/Extensions.cs rename to Drawing2D/src/ExtensionsMethods.cs index 77360ddd..dba42420 100644 --- a/Crow/src/Text/Extensions.cs +++ b/Drawing2D/src/ExtensionsMethods.cs @@ -1,12 +1,40 @@ -// Copyright (c) 2013-2021 Jean-Philippe Bruyère +// Copyright (c) 2013-2022 Jean-Philippe Bruyère // // This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using Crow.Text; using System; +using System.IO; +using System.Linq; +using System.Linq.Expressions; +using System.Reflection; + +using Drawing2D; -namespace Crow.Text +namespace Crow { - public static class Extensions - { + public static class ExtensionsMethods + { + public static void Raise(this EventHandler handler, object sender, EventArgs e) + { + handler?.Invoke (sender, e); + } + public static void Raise(this EventHandler handler, object sender, T e) + { + handler?.Invoke (sender, e); + } + public static byte[] GetBytes(this string str) + { + byte[] bytes = new byte[str.Length * sizeof(char)]; + System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length); + return bytes; + } + public static bool IsWhiteSpaceOrNewLine (this char c) + { + return c == '\t' || c.IsAnyLineBreakCharacter() || char.IsWhiteSpace (c); + } + internal static bool IsAnyLineBreakCharacter (this char c) + => c == '\n' || c == '\r' || c == '\u0085' || c == '\u2028' || c == '\u2029'; public static ReadOnlySpan GetLine (this ReadOnlySpan str, TextLine ls) { if (ls.Start >= str.Length) return "".AsSpan (); @@ -47,6 +75,6 @@ namespace Crow.Text return "\r\n".AsSpan (); } } - } } + diff --git a/Crow/src/Text/LineSpan.cs b/Drawing2D/src/LineSpan.cs similarity index 100% rename from Crow/src/Text/LineSpan.cs rename to Drawing2D/src/LineSpan.cs diff --git a/Crow/src/2d/Measure.cs b/Drawing2D/src/Measure.cs similarity index 100% rename from Crow/src/2d/Measure.cs rename to Drawing2D/src/Measure.cs diff --git a/Drawing2D/src/TextBuffer.cs b/Drawing2D/src/TextBuffer.cs new file mode 100644 index 00000000..ff85e2ff --- /dev/null +++ b/Drawing2D/src/TextBuffer.cs @@ -0,0 +1,99 @@ +// Copyright (c) 2021-2025 Jean-Philippe Bruyère +// +// This code is licensed under the MIT license (MIT) (http://opensource.org/licenses/MIT) + +using System; +using System.Linq; +using System.Collections.Generic; +using Crow.Text; +using Crow; + +namespace CrowEditBase +{ + public class TextBuffer { + static int bufferExpension = 100; + int length; + Memory buffer; + ReadOnlyMemory origBuffer; + LineCollection lines; + public bool mixedLineBreak = false; + public string lineBreak = null; + + internal LineCollection GetLineListCopy() => new LineCollection(lines.ToArray()); + public Span Span => buffer.Span.Slice(0, length); + public ReadOnlySpan ReadOnlySpan => buffer.Span.Slice(0, length); + public bool IsEmpty => length == 0; + public bool IsDirty => !origBuffer.Span.Equals(Span, StringComparison.Ordinal); + public int LinesCount => lines.Count; + public int Length => length; + public ReadOnlyMemory ReadOnlyCopy { + get { + return ReadOnlySpan.ToArray(); + } + } + public void ResetDirtyState () { + origBuffer = Span.ToArray(); + } + public TextBuffer(ReadOnlySpan origText) { + length = origText.Length; + buffer = new char[length + bufferExpension]; + origText.CopyTo(buffer.Span); + lines = new LineCollection (10); + if (IsEmpty) + lines.Add (new TextLine (0, 0, 0)); + else + lines.Update (Span); + ResetDirtyState (); + } + public void Update (TextChange change) { + ReadOnlySpan orig = buffer.Span; + char[] newBuff = null; + Span tmp; + if (buffer.Length < length + change.CharDiff) { + newBuff = new char[length + change.CharDiff + bufferExpension]; + tmp = newBuff; + orig.Slice(0, change.Start).CopyTo(tmp); + if (change.CharDiff == 0) + orig.Slice(change.End, length - change.End).CopyTo(tmp.Slice(change.End)); + } else + tmp = buffer.Span; + + if (change.CharDiff != 0) + orig.Slice(change.End, length - change.End).CopyTo(tmp.Slice(change.End2)); + if (!string.IsNullOrEmpty (change.ChangedText)) + change.ChangedText.AsSpan ().CopyTo (tmp.Slice (change.Start)); + + if (newBuff != null) + buffer = newBuff; + length += change.CharDiff; + + lines.Update (change); + } + public string GetLineBreak () { + if (string.IsNullOrEmpty (lineBreak)) { + mixedLineBreak = false; + + if (lines.Count == 0 || lines[0].LineBreakLength == 0) + lineBreak = Environment.NewLine; + else { + lineBreak = ReadOnlySpan.GetLineBreak (lines[0]).ToString (); + for (int i = 1; i < lines.Count; i++) { + if (!ReadOnlySpan.GetLineBreak (lines[i]).SequenceEqual (lineBreak)) { + mixedLineBreak = true; + break; + } + } + } + } + return lineBreak; + } + public CharLocation GetLocation (int absolutePosition) => lines.GetLocation (absolutePosition); + public TextLine GetLine (int index) => lines[index]; + public void SetLine (int index, TextLine line) => lines[index] = line; + public ReadOnlySpan GetText (TextLine line) => GetText(line.Span); + public ReadOnlySpan GetText (TextSpan textSpan) => buffer.Span.Slice(textSpan.Start, textSpan.Length); + public int GetAbsolutePosition (CharLocation loc) => lines.GetAbsolutePosition (loc); + public CharLocation EndLocation => new CharLocation (lines.Count - 1, lines[lines.Count - 1].Length); + public override string ToString() => ReadOnlySpan.ToString(); + } +} \ No newline at end of file diff --git a/Crow/src/Text/TextChange.cs b/Drawing2D/src/TextChange.cs similarity index 100% rename from Crow/src/Text/TextChange.cs rename to Drawing2D/src/TextChange.cs diff --git a/Crow/src/Text/TextLine.cs b/Drawing2D/src/TextLine.cs similarity index 100% rename from Crow/src/Text/TextLine.cs rename to Drawing2D/src/TextLine.cs diff --git a/Crow/src/Text/TextLineCollection.cs b/Drawing2D/src/TextLineCollection.cs similarity index 100% rename from Crow/src/Text/TextLineCollection.cs rename to Drawing2D/src/TextLineCollection.cs diff --git a/Crow/src/Text/TextSpan.cs b/Drawing2D/src/TextSpan.cs similarity index 100% rename from Crow/src/Text/TextSpan.cs rename to Drawing2D/src/TextSpan.cs -- 2.47.3