diff --git a/Topten.RichTextKit.Test/WordBoundaryTest.cs b/Topten.RichTextKit.Test/WordBoundaryTest.cs
index 9a783c4..44a7174 100644
--- a/Topten.RichTextKit.Test/WordBoundaryTest.cs
+++ b/Topten.RichTextKit.Test/WordBoundaryTest.cs
@@ -91,6 +91,32 @@ public void Punctuation2()
Assert.Equal(9, boundaries[2]);
}
+ [Fact]
+ public void Punctuation3()
+ {
+ var str = ".Hello World";
+ var boundaries = WordBoundaryAlgorithm.FindWordBoundaries(new Utf32Buffer(str).AsSlice()).ToList();
+
+ Assert.Equal(3, boundaries.Count);
+ Assert.Equal(0, boundaries[0]);
+ Assert.Equal(1, boundaries[1]);
+ Assert.Equal(7, boundaries[2]);
+ }
+
+ [Fact]
+ public void Punctuation4()
+ {
+ var str = ".Hello.World.";
+ var boundaries = WordBoundaryAlgorithm.FindWordBoundaries(new Utf32Buffer(str).AsSlice()).ToList();
+
+ Assert.Equal(5, boundaries.Count);
+ Assert.Equal(0, boundaries[0]);
+ Assert.Equal(1, boundaries[1]);
+ Assert.Equal(6, boundaries[2]);
+ Assert.Equal(7, boundaries[3]);
+ Assert.Equal(12, boundaries[4]);
+ }
+
[Fact]
public void TestIsWordBoundary()
{
diff --git a/Topten.RichTextKit/Editor/TextDocument.cs b/Topten.RichTextKit/Editor/TextDocument.cs
index b0d780e..a156ac9 100644
--- a/Topten.RichTextKit/Editor/TextDocument.cs
+++ b/Topten.RichTextKit/Editor/TextDocument.cs
@@ -333,6 +333,54 @@ public float MeasuredWidth
}
}
+ ///
+ /// The total width of the content of the document
+ ///
+ ///
+ /// For line-wrap or non-line-wrap documents this is
+ /// the width of the widest paragraph.
+ ///
+ public float MeasuredContentWidth
+ {
+ get
+ {
+ Layout();
+ return _measuredWidth;
+ }
+ }
+
+ ///
+ /// Gets the actual measured overhang in each direction based on the
+ /// fonts used, and the supplied text.
+ ///
+ ///
+ /// The return rectangle describes overhang amounts for each edge - not
+ /// rectangle co-ordinates.
+ ///
+ public SKRect MeasuredOverhang
+ {
+ get
+ {
+ Layout();
+ if (_paragraphs.Count == 0)
+ return new SKRect();
+
+ var overhang = _paragraphs[0].TextBlock.MeasuredOverhang;
+ float topOverhang = overhang.Top;
+ float bottomOverhang = _paragraphs[_paragraphs.Count - 1].TextBlock.MeasuredOverhang.Bottom;
+ float leftOverhang = overhang.Left;
+ float rightOverhang = overhang.Right;
+ for (int i = 1; i < _paragraphs.Count; i++)
+ {
+ overhang = _paragraphs[i].TextBlock.MeasuredOverhang;
+ leftOverhang = Math.Max(leftOverhang, overhang.Left);
+ rightOverhang = Math.Max(rightOverhang, overhang.Right);
+ }
+
+ return new SKRect(leftOverhang, topOverhang, rightOverhang, bottomOverhang);
+ }
+ }
+
///
/// Gets the total length of the document in code points
///
@@ -415,7 +463,40 @@ public IStyle GetStyleAtOffset(int offset)
throw new NotImplementedException();
// Get style from text block
- return para.TextBlock.GetStyleAtOffset(offset);
+ return para.TextBlock.GetStyleAtOffset(indexInPara);
+ }
+
+ ///
+ /// Get the text for a part of the document
+ ///
+ /// The text to retrieve
+ /// The styled text
+ public StyledText Extract(TextRange range)
+ {
+ var other = new StyledText();
+
+ // Normalize and clamp range
+ range = range.Normalized.Clamp(Length - 1);
+
+ // Get all subruns
+ foreach (var subrun in _paragraphs.GetInterectingRuns(range.Start, range.Length))
+ {
+ // Get the paragraph
+ var para = _paragraphs[subrun.Index];
+ if (para.TextBlock == null)
+ throw new NotImplementedException();
+
+ var styledText = para.TextBlock.Extract(subrun.Offset, subrun.Length);
+ foreach (var sr in styledText.StyleRuns)
+ {
+ other.AddText(sr.CodePoints, sr.Style);
+ }
+ }
+
+ // Convert paragraph separators to new lines
+ other.CodePoints.Replace('\u2029', '\n');
+
+ return other;
}
///
@@ -805,13 +886,44 @@ public void ReplaceText(ITextDocumentView view, TextRange range, Slice code
}
var styledText = new StyledText(codePoints);
- if (styledText != null)
+ if (styleToUse != null)
{
styledText.ApplyStyle(0, styledText.Length, styleToUse);
}
ReplaceTextInternal(view, range, styledText, semantics, -1);
}
+ ///
+ /// Replaces a range of text with the specified text
+ ///
+ /// The view initiating the operation
+ /// The range to be replaced
+ /// The text to replace with
+ /// Controls how undo operations are coalesced and view selections updated"
+ public void ReplaceText(ITextDocumentView view, TextRange range, StyledText styledText, EditSemantics semantics)
+ {
+ // Check range is valid
+ if (range.Minimum < 0 || range.Maximum > this.Length)
+ throw new ArgumentException("Invalid range", nameof(range));
+
+ if (IsImeComposing)
+ FinishImeComposition(view);
+
+ // Convert new lines to paragraph separators
+ if (PlainTextMode)
+ styledText.CodePoints.Replace('\n', '\u2029');
+
+ // Break at the first line break
+ if (SingleLineMode)
+ {
+ int breakPos = styledText.CodePoints.SubSlice(0, styledText.Length).IndexOfAny('\n', '\r', '\u2029');
+ if (breakPos >= 0)
+ styledText.DeleteText(breakPos, styledText.Length - breakPos);
+ }
+
+ ReplaceTextInternal(view, range, styledText, semantics, -1);
+ }
+
///
/// Indicates if an IME composition is currently in progress
///
@@ -973,7 +1085,7 @@ int GetParagraphForCodePointIndex(CaretPosition position, out int indexInParagra
Layout();
// Search paragraphs
- int paraIndex = _paragraphs.BinarySearch(position.CodePointIndex, (para, a) =>
+ int paraIndex = _paragraphs.BinarySearch(position.CodePointIndex, (para, a) =>
{
if (a < para.CodePointIndex)
return 1;
@@ -1409,6 +1521,7 @@ int InsertInternal(int position, StyledText text)
bool _layoutValid = false;
bool _lineWrap = true;
internal List _paragraphs;
+
UndoManager _undoManager;
List _views = new List();
ITextDocumentView _initiatingView;
diff --git a/Topten.RichTextKit/FontRun.cs b/Topten.RichTextKit/FontRun.cs
index 1b5e3d9..a97068f 100644
--- a/Topten.RichTextKit/FontRun.cs
+++ b/Topten.RichTextKit/FontRun.cs
@@ -464,15 +464,36 @@ private FontRun SplitRTL(int splitAtCodePoint)
/// Calculate any overhang for this text line
///
///
+ /// True to update topOverhang.
+ /// True to update bottomOverhang.
///
///
- internal void UpdateOverhang(float right, ref float leftOverhang, ref float rightOverhang)
+ ///
+ ///
+ internal void UpdateOverhang(float right, bool updateTop, bool updateBottom, ref float leftOverhang, ref float rightOverhang, ref float topOverhang, ref float bottomOverhang)
{
if (RunKind == FontRunKind.TrailingWhitespace)
return;
if (Glyphs.Length == 0)
return;
+
+ if (Style.LineHeight < 1)
+ {
+ // If LineHeight is less than 100%, the line can have top and bottom overhang
+ if (updateTop)
+ {
+ var toh = -(TextHeight * (Style.LineHeight - 1) / 2);
+ if (toh > topOverhang)
+ topOverhang = toh;
+ }
+ if (updateBottom)
+ {
+ var boh = -(TextHeight * (Style.LineHeight - 1) / 2);
+ if (boh > bottomOverhang)
+ bottomOverhang = boh;
+ }
+ }
using (var paint = new SKPaint())
{
@@ -509,7 +530,7 @@ internal void UpdateOverhang(float right, ref float leftOverhang, ref float righ
leftOverhang = loh;
var roh = (gx + bounds[i].Right + 1) - right;
- if (roh > rightOverhang)
+ if (roh > rightOverhang)
rightOverhang = roh;
}
}
@@ -638,11 +659,18 @@ internal void Paint(PaintTextContext ctx)
// Get glyph positions
var glyphPositions = GlyphPositions.ToArray();
+ var scaledFontSize = this.Style.FontSize * glyphScale;
+
// Create the font
if (_font == null)
{
- _font = new SKFont(this.Typeface, this.Style.FontSize * glyphScale);
+ _font = new SKFont(this.Typeface, scaledFontSize);
}
+ else if (_font.Size != scaledFontSize)
+ {
+ _font.Size = scaledFontSize;
+ }
+
_font.Hinting = ctx.Options.Hinting;
_font.Edging = ctx.Options.Edging;
_font.Subpixel = ctx.Options.SubpixelPositioning;
@@ -741,10 +769,10 @@ internal void Paint(PaintTextContext ctx)
float strikeYPos = Line.YCoord + Line.BaseLine + (_font.Metrics.StrikeoutPosition ?? 0) + glyphVOffset;
ctx.Canvas.DrawLine(new SKPoint(XCoord, strikeYPos), new SKPoint(XCoord + Width, strikeYPos), paintHalo);
}
- ctx.Canvas.DrawText(_textBlob, 0, 0, paintHalo);
+ ctx.Canvas.DrawText(_textBlob, 0, glyphVOffset, paintHalo);
}
- ctx.Canvas.DrawText(_textBlob, 0, 0, paint);
+ ctx.Canvas.DrawText(_textBlob, 0, glyphVOffset, paint);
}
}
diff --git a/Topten.RichTextKit/IStyleExtensions.cs b/Topten.RichTextKit/IStyleExtensions.cs
index a8cd76b..01187fd 100644
--- a/Topten.RichTextKit/IStyleExtensions.cs
+++ b/Topten.RichTextKit/IStyleExtensions.cs
@@ -31,7 +31,7 @@ public static class IStyleExtensions
/// A key string
public static string Key(this IStyle This)
{
- return $"{This.FontFamily}.{This.FontSize}.{This.FontWeight}.{This.FontWidth}.{This.FontItalic}.{This.Underline}.{This.StrikeThrough}.{This.LineHeight}.{This.TextColor}.{This.BackgroundColor}.{This.LetterSpacing}.{This.FontVariant}.{This.TextDirection}.{This.ReplacementCharacter}";
+ return $"{This.FontFamily}.{This.FontSize}.{This.FontWeight}.{This.FontWidth}.{This.FontItalic}.{This.Underline}.{This.StrikeThrough}.{This.LineHeight}.{This.TextColor}.{This.BackgroundColor}.{This.LetterSpacing}.{This.FontVariant}.{This.TextDirection}.{This.ReplacementCharacter}.{This.HaloWidth}.{This.HaloColor}.{This.HaloBlur}";
}
///
@@ -89,10 +89,13 @@ public static bool IsSame(this IStyle This, IStyle other)
return false;
if (This.StrikeThrough != other.StrikeThrough)
return false;
+ if (This.HaloBlur != other.HaloBlur)
+ return false;
+ if (This.HaloColor != other.HaloColor)
+ return false;
+ if (This.HaloWidth != other.HaloWidth)
+ return false;
return true;
}
-
-
-
}
}
diff --git a/Topten.RichTextKit/LineBreakAlgorithm/WordBoundaryAlgorithm.cs b/Topten.RichTextKit/LineBreakAlgorithm/WordBoundaryAlgorithm.cs
index 9ca80ab..db329bd 100644
--- a/Topten.RichTextKit/LineBreakAlgorithm/WordBoundaryAlgorithm.cs
+++ b/Topten.RichTextKit/LineBreakAlgorithm/WordBoundaryAlgorithm.cs
@@ -77,6 +77,8 @@ public static IEnumerable FindWordBoundaries(Slice codePoints)
// Switch to a different word kind without a space
// just emit a word boundary here
yield return i;
+ // Update wordGroup to the new boundary class
+ wordGroup = bg;
}
}
}
diff --git a/Topten.RichTextKit/StyleManager.cs b/Topten.RichTextKit/StyleManager.cs
index 1e26b39..d8b1f72 100644
--- a/Topten.RichTextKit/StyleManager.cs
+++ b/Topten.RichTextKit/StyleManager.cs
@@ -265,7 +265,7 @@ public IStyle Update(
string fontFamily = null,
float? fontSize = null,
int? fontWeight = null,
- SKFontStyleWidth? fontWidth = 0,
+ SKFontStyleWidth? fontWidth = null,
bool? fontItalic = null,
UnderlineStyle? underline = null,
StrikeThroughStyle? strikeThrough = null,
diff --git a/Topten.RichTextKit/TextBlock.cs b/Topten.RichTextKit/TextBlock.cs
index 1b29bda..f6f6001 100644
--- a/Topten.RichTextKit/TextBlock.cs
+++ b/Topten.RichTextKit/TextBlock.cs
@@ -348,6 +348,8 @@ public void Layout()
_measuredWidth = 0;
_leftOverhang = null;
_rightOverhang = null;
+ _topOverhang = null;
+ _bottomOverhang = null;
_truncated = false;
// Only layout if actually have some text
@@ -610,14 +612,20 @@ public SKRect MeasuredOverhang
var right = _maxWidth ?? MeasuredWidth;
float leftOverhang = 0;
float rightOverhang = 0;
- foreach (var l in _lines)
+ float topOverhang = 0;
+ float bottomOverhang = 0;
+ for (int l = 0; l < _lines.Count; l++)
{
- l.UpdateOverhang(right, ref leftOverhang, ref rightOverhang);
+ bool updateTop = l == 0;
+ bool updateBottom = l == (_lines.Count - 1);
+ _lines[l].UpdateOverhang(right, updateTop, updateBottom, ref leftOverhang, ref rightOverhang, ref topOverhang, ref bottomOverhang);
}
_leftOverhang = leftOverhang;
_rightOverhang = rightOverhang;
+ _topOverhang = topOverhang;
+ _bottomOverhang = bottomOverhang;
}
- return new SKRect(_leftOverhang.Value, 0, _rightOverhang.Value, 0);
+ return new SKRect(_leftOverhang.Value, _topOverhang.Value, _rightOverhang.Value, _bottomOverhang.Value);
}
}
@@ -1034,6 +1042,16 @@ void InvalidateLayout()
///
float? _rightOverhang = null;
+ ///
+ /// The required top overhang
+ ///
+ float? _topOverhang = null;
+
+ ///
+ /// The required bottom overhang
+ ///
+ float? _bottomOverhang = null;
+
///
/// Indicates if the text was truncated by max height/max lines limitations
///
@@ -1334,6 +1352,9 @@ public bool CanShapeWith(UnshapedRun next)
{
return typeface == next.typeface &&
style.FontSize == next.style.FontSize &&
+ style.LetterSpacing == next.style.LetterSpacing &&
+ style.FontVariant == next.style.FontVariant &&
+ style.LineHeight == next.style.LineHeight &&
asFallbackFor == next.asFallbackFor &&
direction == next.direction &&
start + length == next.start;
@@ -1413,6 +1434,7 @@ void BreakLines()
// Skip line breaks
bool breakLine = false;
+ bool isRequired = false;
while (lbrIndex < lineBreakPositions.Count)
{
// Past this run?
@@ -1447,6 +1469,7 @@ void BreakLines()
if (lbr.Required)
{
breakLine = true;
+ isRequired = true;
break;
}
}
@@ -1475,10 +1498,24 @@ void BreakLines()
fr = _fontRuns[frIndex];
var room = _maxWidthResolved - fr.XCoord;
frSplitIndex = frIndex;
- codePointIndexSplit = fr.FindBreakPosition(room, frSplitIndex == frIndexStartOfLine);
- codePointIndexWrap = codePointIndexSplit;
- while (codePointIndexWrap < _codePoints.Length && UnicodeClasses.LineBreakClass(_codePoints[codePointIndexWrap]) == LineBreakClass.SP)
- codePointIndexWrap++;
+
+ var hasValidLinebreak = codePointIndexSplit >= fr.Start && codePointIndexSplit <= fr.End;
+
+ // Only break at character if there is no required line break we can use.
+ if (!(isRequired && hasValidLinebreak))
+ {
+ var breakPosition = fr.FindBreakPosition(room, frSplitIndex == frIndexStartOfLine);
+
+ // Prefer breaking at a character rather than a line break position.
+ if (!hasValidLinebreak || breakPosition > codePointIndexSplit)
+ {
+ codePointIndexSplit = breakPosition;
+ codePointIndexWrap = codePointIndexSplit;
+ while (codePointIndexWrap < _codePoints.Length &&
+ UnicodeClasses.LineBreakClass(_codePoints[codePointIndexWrap]) == LineBreakClass.SP)
+ codePointIndexWrap++;
+ }
+ }
}
// Split it
diff --git a/Topten.RichTextKit/TextLine.cs b/Topten.RichTextKit/TextLine.cs
index 1f2734d..18cdf52 100644
--- a/Topten.RichTextKit/TextLine.cs
+++ b/Topten.RichTextKit/TextLine.cs
@@ -382,11 +382,11 @@ void updateClosest(float xPosition, int codePointIndex, TextDirection dir)
}
}
- internal void UpdateOverhang(float right, ref float leftOverhang, ref float rightOverhang)
+ internal void UpdateOverhang(float right, bool updateTop, bool updateBottom, ref float leftOverhang, ref float rightOverhang, ref float topOverhang, ref float bottomOverhang)
{
foreach (var r in Runs)
{
- r.UpdateOverhang(right, ref leftOverhang, ref rightOverhang);
+ r.UpdateOverhang(right, updateTop, updateBottom, ref leftOverhang, ref rightOverhang, ref topOverhang, ref bottomOverhang);
}
}
diff --git a/Topten.RichTextKit/Topten.RichTextKit.csproj b/Topten.RichTextKit/Topten.RichTextKit.csproj
index 878c17e..c996bf2 100644
--- a/Topten.RichTextKit/Topten.RichTextKit.csproj
+++ b/Topten.RichTextKit/Topten.RichTextKit.csproj
@@ -3,9 +3,9 @@
- netstandard2.0;netcoreapp2.1;net462;net5.0
+ netstandard2.0;net462;net5.0
-
+
True
True
@@ -20,12 +20,15 @@
+
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
+
+
+
+
diff --git a/Topten.RichTextKit/Unicode/UnicodeTrie.cs b/Topten.RichTextKit/Unicode/UnicodeTrie.cs
index 540b6fe..9fc3d58 100644
--- a/Topten.RichTextKit/Unicode/UnicodeTrie.cs
+++ b/Topten.RichTextKit/Unicode/UnicodeTrie.cs
@@ -40,10 +40,10 @@ public UnicodeTrie(Stream stream)
using (var bw = new BinaryReader(infl2, Encoding.UTF8, true))
{
_data = new int[dataLength];
- for (int i = 0; i < _data.Length; i++)
- {
- _data[i] = bw.ReadInt32();
- }
+
+ // Read the entire stream, then convert to int[]
+ var byteData = bw.ReadBytes(_data.Length * sizeof(int));
+ Buffer.BlockCopy(byteData, 0, _data, 0, byteData.Length);
}
}
diff --git a/build.js b/build.js
index 0f4af2a..3e88e37 100644
--- a/build.js
+++ b/build.js
@@ -23,7 +23,7 @@ if (bt.options.official)
// Build docs
if (!bt.options.nodoc)
{
- bt.run(`docsanity`);
+ bt.run(`docsanity-net5`);
bt.run(`git add doc`);
bt.run(`git commit --allow-empty -m "Updated documentation"`);
}
diff --git a/doc/.common.page b/doc/.common.page
index dccf764..81ed651 100644
--- a/doc/.common.page
+++ b/doc/.common.page
@@ -529,7 +529,9 @@ navTree:
- text: MarginLeft|./ref/Topten.RichTextKit.Editor.TextDocument.MarginLeft
- text: MarginRight|./ref/Topten.RichTextKit.Editor.TextDocument.MarginRight
- text: MarginTop|./ref/Topten.RichTextKit.Editor.TextDocument.MarginTop
+ - text: MeasuredContentWidth|./ref/Topten.RichTextKit.Editor.TextDocument.MeasuredContentWidth
- text: MeasuredHeight|./ref/Topten.RichTextKit.Editor.TextDocument.MeasuredHeight
+ - text: MeasuredOverhang|./ref/Topten.RichTextKit.Editor.TextDocument.MeasuredOverhang
- text: MeasuredWidth|./ref/Topten.RichTextKit.Editor.TextDocument.MeasuredWidth
- text: PageWidth|./ref/Topten.RichTextKit.Editor.TextDocument.PageWidth
- text: PlainTextMode|./ref/Topten.RichTextKit.Editor.TextDocument.PlainTextMode
@@ -538,6 +540,7 @@ navTree:
- text: UndoManager|./ref/Topten.RichTextKit.Editor.TextDocument.UndoManager
- text: Methods
subItems:
+ - text: Extract|./ref/Topten.RichTextKit.Editor.TextDocument.Extract
- text: FinishImeComposition|./ref/Topten.RichTextKit.Editor.TextDocument.FinishImeComposition
- text: GetCaretInfo|./ref/Topten.RichTextKit.Editor.TextDocument.GetCaretInfo
- text: GetOvertypeRange|./ref/Topten.RichTextKit.Editor.TextDocument.GetOvertypeRange
diff --git a/doc/index.page b/doc/index.page
index a97e874..7770418 100644
--- a/doc/index.page
+++ b/doc/index.page
@@ -32,8 +32,8 @@ RichTextKit is a rich-text layout, measurement and rendering library for SkiaSha
## Under Development
-RichTextKit is still under development. It works fine on Windows under net45 and
-netcoreapp2.1 but hasn't been tested on other platforms.
+RichTextKit is still under development. It works fine on Windows under net462 and
+net5.0 but hasn't been tested on other platforms.
Also, text layout in general and Unicode and international text specifically are a
complicated topics - almost certainly there are issues I'm unaware of and I'm
diff --git a/doc/install.page b/doc/install.page
index e5893ea..ddfaf03 100644
--- a/doc/install.page
+++ b/doc/install.page
@@ -4,7 +4,7 @@ isMarkdown: false
---
Installation
NuGet
-RichTextKit is available as a NuGet package for net45 and netcoreapp2.1 frameworks:
+RichTextKit is available as a NuGet package for net462 and net5.0 frameworks:
Install-Package Topten.RichTextKit
Note that RichTextKit is currently still under development and has only been tested on
diff --git a/doc/ref/Topten.RichTextKit.Editor.TextDocument.Extract.page b/doc/ref/Topten.RichTextKit.Editor.TextDocument.Extract.page
new file mode 100644
index 0000000..af5678d
--- /dev/null
+++ b/doc/ref/Topten.RichTextKit.Editor.TextDocument.Extract.page
@@ -0,0 +1,55 @@
+---
+title: "TextDocument.Extract"
+isMarkdown: false
+import: "../.common.page"
+---
+
+ TextDocument.Extract Method
+
+
+
+
+ Assembly: Topten.RichTextKit.dll
+ Namespace: Topten.RichTextKit.Editor
+
+ Declaring Type: TextDocument
+
+
+
+
+
+
+
+
+
+
+Get the text for a part of the document
+
+
+public Topten.RichTextKit.StyledText Extract(Topten.RichTextKit.TextRange range);
+
+
+Parameters
+Returns
+
+
+
+
+
+
+
diff --git a/doc/ref/Topten.RichTextKit.Editor.TextDocument.MeasuredContentWidth.page b/doc/ref/Topten.RichTextKit.Editor.TextDocument.MeasuredContentWidth.page
new file mode 100644
index 0000000..62dd331
--- /dev/null
+++ b/doc/ref/Topten.RichTextKit.Editor.TextDocument.MeasuredContentWidth.page
@@ -0,0 +1,40 @@
+---
+title: "TextDocument.MeasuredContentWidth"
+isMarkdown: false
+import: "../.common.page"
+---
+
+TextDocument.MeasuredContentWidth Property
+
+
+
+
+ Assembly: Topten.RichTextKit.dll
+ Namespace: Topten.RichTextKit.Editor
+
+ Declaring Type: TextDocument
+
+
+
+
+
+
+The total width of the content of the document
+
+
+public float MeasuredContentWidth { get; }
+
+For line-wrap or non-line-wrap documents this is
+the width of the widest paragraph.
+
+Property Type
+
+
+
+
+
diff --git a/doc/ref/Topten.RichTextKit.Editor.TextDocument.MeasuredOverhang.page b/doc/ref/Topten.RichTextKit.Editor.TextDocument.MeasuredOverhang.page
new file mode 100644
index 0000000..e45b629
--- /dev/null
+++ b/doc/ref/Topten.RichTextKit.Editor.TextDocument.MeasuredOverhang.page
@@ -0,0 +1,41 @@
+---
+title: "TextDocument.MeasuredOverhang"
+isMarkdown: false
+import: "../.common.page"
+---
+
+TextDocument.MeasuredOverhang Property
+
+
+
+
+ Assembly: Topten.RichTextKit.dll
+ Namespace: Topten.RichTextKit.Editor
+
+ Declaring Type: TextDocument
+
+
+
+
+
+
+Gets the actual measured overhang in each direction based on the
+fonts used, and the supplied text.
+
+
+public SkiaSharp.SKRect MeasuredOverhang { get; }
+
+The return rectangle describes overhang amounts for each edge - not
+rectangle co-ordinates.
+
+Property Type
+
+ | SkiaSharp.SKRect |
+ |
+
+
+
+
+
+
+
diff --git a/doc/ref/Topten.RichTextKit.Editor.TextDocument.ReplaceText.page b/doc/ref/Topten.RichTextKit.Editor.TextDocument.ReplaceText.page
index d182669..09b91c9 100644
--- a/doc/ref/Topten.RichTextKit.Editor.TextDocument.ReplaceText.page
+++ b/doc/ref/Topten.RichTextKit.Editor.TextDocument.ReplaceText.page
@@ -23,24 +23,75 @@ import: "../.common.page"
Overloads
- | ReplaceText(ITextDocumentView, Topten.RichTextKit.TextRange, string, EditSemantics) |
+ ReplaceText(ITextDocumentView, Topten.RichTextKit.TextRange, Topten.RichTextKit.StyledText, EditSemantics) |
Replaces a range of text with the specified text
|
- | ReplaceText(ITextDocumentView, Topten.RichTextKit.TextRange, Topten.RichTextKit.Utils.Slice<int>, EditSemantics) |
+ ReplaceText(ITextDocumentView, Topten.RichTextKit.TextRange, string, EditSemantics, Topten.RichTextKit.IStyle) |
+ Replaces a range of text with the specified text
+ |
+
+
+ | ReplaceText(ITextDocumentView, Topten.RichTextKit.TextRange, Topten.RichTextKit.Utils.Slice<int>, EditSemantics, Topten.RichTextKit.IStyle) |
Replaces a range of text with the specified text
|
-
+
Replaces a range of text with the specified text
-public void ReplaceText(ITextDocumentView view, Topten.RichTextKit.TextRange range, string text, EditSemantics semantics);
+public void ReplaceText(ITextDocumentView view, Topten.RichTextKit.TextRange range, Topten.RichTextKit.StyledText styledText, EditSemantics semantics);
+
+
+Parameters
+
+
+
+
+
+
+Replaces a range of text with the specified text
+
+
+public void ReplaceText(ITextDocumentView view, Topten.RichTextKit.TextRange range, string text, EditSemantics semantics, Topten.RichTextKit.IStyle styleToUse = null);
Parameters
@@ -74,6 +125,14 @@ import: "../.common.page"
EditSemantics semantics
Controls how undo operations are coalesced and view selections updated
+ |
+
+
+ |
+
+ Topten.RichTextKit.IStyle styleToUse
+ = null |
+ The style to use for the added text (optional)
|
@@ -81,12 +140,12 @@ import: "../.common.page"
-
+
Replaces a range of text with the specified text
-public void ReplaceText(ITextDocumentView view, Topten.RichTextKit.TextRange range, Topten.RichTextKit.Utils.Slice<int> codePoints, EditSemantics semantics);
+public void ReplaceText(ITextDocumentView view, Topten.RichTextKit.TextRange range, Topten.RichTextKit.Utils.Slice<int> codePoints, EditSemantics semantics, Topten.RichTextKit.IStyle styleToUse = null);
Parameters
@@ -120,6 +179,14 @@ import: "../.common.page"
EditSemantics semantics
Controls how undo operations are coalesced and view selections updated
+ |
+
+
+ |
+
+ Topten.RichTextKit.IStyle styleToUse
+ = null |
+ The style to use for the added text (optional)
|
diff --git a/doc/ref/Topten.RichTextKit.Editor.TextDocument.page b/doc/ref/Topten.RichTextKit.Editor.TextDocument.page
index e7cd54c..1797533 100644
--- a/doc/ref/Topten.RichTextKit.Editor.TextDocument.page
+++ b/doc/ref/Topten.RichTextKit.Editor.TextDocument.page
@@ -91,11 +91,22 @@ import: "../.common.page"
| MarginTop |
The document's top margin
+ |
+
+
+ | MeasuredContentWidth |
+ The total width of the content of the document
|
| MeasuredHeight |
The total height of the document
+ |
+
+
+ | MeasuredOverhang |
+ Gets the actual measured overhang in each direction based on the
+fonts used, and the supplied text.
|
@@ -132,6 +143,11 @@ import: "../.common.page"
Methods
+
+ | Extract(Topten.RichTextKit.TextRange) |
+ Get the text for a part of the document
+ |
+
| FinishImeComposition(ITextDocumentView) |
Complete an IME composition
@@ -190,12 +206,17 @@ current word, line, paragraph or document
|
- | ReplaceText(ITextDocumentView, Topten.RichTextKit.TextRange, string, EditSemantics) |
+ ReplaceText(ITextDocumentView, Topten.RichTextKit.TextRange, Topten.RichTextKit.StyledText, EditSemantics) |
+ Replaces a range of text with the specified text
+ |
+
+
+ | ReplaceText(ITextDocumentView, Topten.RichTextKit.TextRange, string, EditSemantics, Topten.RichTextKit.IStyle) |
Replaces a range of text with the specified text
|
- | ReplaceText(ITextDocumentView, Topten.RichTextKit.TextRange, Topten.RichTextKit.Utils.Slice<int>, EditSemantics) |
+ ReplaceText(ITextDocumentView, Topten.RichTextKit.TextRange, Topten.RichTextKit.Utils.Slice<int>, EditSemantics, Topten.RichTextKit.IStyle) |
Replaces a range of text with the specified text
|
diff --git a/doc/ref/Topten.RichTextKit.StyleManager.Update.page b/doc/ref/Topten.RichTextKit.StyleManager.Update.page
index 7d7d71a..ba54be8 100644
--- a/doc/ref/Topten.RichTextKit.StyleManager.Update.page
+++ b/doc/ref/Topten.RichTextKit.StyleManager.Update.page
@@ -27,7 +27,7 @@ import: "../.common.page"
style.
-public IStyle Update(string fontFamily = null, Nullable<float> fontSize = null, Nullable<int> fontWeight = null, Nullable<SkiaSharp.SKFontStyleWidth> fontWidth = 0, Nullable<bool> fontItalic = null, Nullable<UnderlineStyle> underline = null, Nullable<StrikeThroughStyle> strikeThrough = null, Nullable<float> lineHeight = null, Nullable<SkiaSharp.SKColor> textColor = null, Nullable<SkiaSharp.SKColor> backgroundColor = null, Nullable<SkiaSharp.SKColor> haloColor = null, Nullable<float> haloWidth = null, Nullable<float> haloBlur = null, Nullable<float> letterSpacing = null, Nullable<FontVariant> fontVariant = null, Nullable<TextDirection> textDirection = null, Nullable<char> replacementCharacter = null);
+public IStyle Update(string fontFamily = null, Nullable<float> fontSize = null, Nullable<int> fontWeight = null, Nullable<SkiaSharp.SKFontStyleWidth> fontWidth = null, Nullable<bool> fontItalic = null, Nullable<UnderlineStyle> underline = null, Nullable<StrikeThroughStyle> strikeThrough = null, Nullable<float> lineHeight = null, Nullable<SkiaSharp.SKColor> textColor = null, Nullable<SkiaSharp.SKColor> backgroundColor = null, Nullable<SkiaSharp.SKColor> haloColor = null, Nullable<float> haloWidth = null, Nullable<float> haloBlur = null, Nullable<float> letterSpacing = null, Nullable<FontVariant> fontVariant = null, Nullable<TextDirection> textDirection = null, Nullable<char> replacementCharacter = null);
Parameters
@@ -59,7 +59,7 @@ style.
|
Nullable<SkiaSharp.SKFontStyleWidth> fontWidth
- = 0 |
+ = null
The new font width
|
diff --git a/docsrc/index.page b/docsrc/index.page
index a97e874..7770418 100644
--- a/docsrc/index.page
+++ b/docsrc/index.page
@@ -32,8 +32,8 @@ RichTextKit is a rich-text layout, measurement and rendering library for SkiaSha
## Under Development
-RichTextKit is still under development. It works fine on Windows under net45 and
-netcoreapp2.1 but hasn't been tested on other platforms.
+RichTextKit is still under development. It works fine on Windows under net462 and
+net5.0 but hasn't been tested on other platforms.
Also, text layout in general and Unicode and international text specifically are a
complicated topics - almost certainly there are issues I'm unaware of and I'm
diff --git a/docsrc/install.md b/docsrc/install.md
index 661da94..3110d41 100644
--- a/docsrc/install.md
+++ b/docsrc/install.md
@@ -6,7 +6,7 @@ title: Installation
## NuGet
-RichTextKit is available as a NuGet package for `net45` and `netcoreapp2.1` frameworks:
+RichTextKit is available as a NuGet package for `net462` and `net5.0` frameworks:
~~~
Install-Package Topten.RichTextKit
diff --git a/readme.md b/readme.md
index b4a350a..a415b3a 100644
--- a/readme.md
+++ b/readme.md
@@ -25,8 +25,8 @@ RichTextKit is a rich-text layout, measurement and rendering library for SkiaSha
## Under Development
-RichTextKit is still under development. It works fine on Windows under net45 and
-netcoreapp2.1 but hasn't been tested on other platforms.
+RichTextKit is still under development. It works fine on Windows under net462 and
+net5.0 but hasn't been tested on other platforms.
Also, text layout in general and Unicode and international text specifically are a
complicated topics - almost certainly there are issues I'm unaware of and I'm
diff --git a/version.cs b/version.cs
index c2ffb2a..c905572 100644
--- a/version.cs
+++ b/version.cs
@@ -2,14 +2,14 @@
// Generated by build tool, do not edit
using System;
using System.Reflection;
-[assembly: AssemblyCopyright("Copyright © 2019-2022 Topten Software. All Rights Reserved")]
-[assembly: AssemblyVersion("0.4.165")]
-[assembly: AssemblyFileVersion("0.4.165")]
+[assembly: AssemblyCopyright("Copyright © 2019-2024 Topten Software. All Rights Reserved")]
+[assembly: AssemblyVersion("0.4.167")]
+[assembly: AssemblyFileVersion("0.4.167")]
[assembly: AssemblyCompany("Topten Software")]
[assembly: AssemblyProduct("Topten.RichTextKit")]
static class BuildInfo
{
- public static DateTime Date = new DateTime(2022, 12, 7, 0, 42, 24, DateTimeKind.Utc);
+ public static DateTime Date = new DateTime(2024, 3, 6, 1, 23, 57, DateTimeKind.Utc);
}
\ No newline at end of file
diff --git a/version.json b/version.json
index 1d9c2e9..d5a700d 100644
--- a/version.json
+++ b/version.json
@@ -1,7 +1,7 @@
{
"major": 0,
"minor": 4,
- "build": 165,
+ "build": 167,
"suffix": "",
"copyrightYear": 2019,
"productName": "Topten.RichTextKit",
diff --git a/version.props b/version.props
index fddaa8a..0a83fbf 100644
--- a/version.props
+++ b/version.props
@@ -2,7 +2,7 @@
- 0.4.165
+ 0.4.167
\ No newline at end of file