Removed MaxOverhang and fixed MeasuredOverhang to work out both left and right overhang

This commit is contained in:
Brad Robinson 2019-08-08 18:54:37 +10:00
Родитель 823e8aa268
Коммит 04eda89e11
4 изменённых файлов: 64 добавлений и 63 удалений

Просмотреть файл

@ -230,12 +230,30 @@ namespace SandboxDriver
if (_textBlock.MeasuredOverhang.Left > 0)
{
using (var paint = new SKPaint() { Color = new SKColor(0xFFf0f0f0), StrokeWidth = 1 })
using (var paint = new SKPaint() { Color = new SKColor(0xFF00fff0), StrokeWidth = 1 })
{
canvas.DrawLine(new SKPoint(margin - _textBlock.MeasuredOverhang.Left, 0), new SKPoint(margin - _textBlock.MeasuredOverhang.Left, (float)canvasHeight), paint);
}
}
if (_textBlock.MeasuredOverhang.Right > 0)
{
using (var paint = new SKPaint() { Color = new SKColor(0xFF00ff00), StrokeWidth = 1 })
{
float x;
if (_textBlock.MaxWidth.HasValue)
{
x = margin + _textBlock.MaxWidth.Value;
}
else
{
x = margin + _textBlock.MeasuredWidth;
}
x += _textBlock.MeasuredOverhang.Right;
canvas.DrawLine(new SKPoint(x, 0), new SKPoint(x, (float)canvasHeight), paint);
}
}
_textBlock.Paint(canvas, new SKPoint(margin, margin), options);
if (ci != null)

Просмотреть файл

@ -419,13 +419,18 @@ namespace Topten.RichTextKit
internal Buffer<int> CodePointBuffer;
/// <summary>
/// Calculate how by how much text at the left margin overhangs the margin
/// Calculate any overhang for this text line
/// </summary>
/// <returns>The amount of overhang</returns>
internal float CalculateRequiredLeftMargin()
/// <param name="right"></param>
/// <param name="leftOverhang"></param>
/// <param name="rightOverhang"></param>
internal void UpdateOverhang(float right, ref float leftOverhang, ref float rightOverhang)
{
if (RunKind == FontRunKind.TrailingWhitespace)
return;
if (Glyphs.Length == 0)
return 0;
return;
using (var paint = new SKPaint())
{
@ -450,18 +455,25 @@ namespace Topten.RichTextKit
{
fixed (ushort* pGlyphs = Glyphs.Underlying)
{
paint.GetGlyphWidths((IntPtr)(pGlyphs + Start), sizeof(ushort), out var bounds);
if (bounds != null && bounds.Length >= 1)
paint.GetGlyphWidths((IntPtr)(pGlyphs + Start), sizeof(ushort) * Glyphs.Length, out var bounds);
if (bounds != null)
{
var lhs = XCoord + bounds[0].Left;
if (lhs < 0)
return -lhs;
for (int i = 0; i < bounds.Length; i++)
{
float gx = GlyphPositions[i].X;
var loh = -(gx + bounds[i].Left);
if (loh > leftOverhang)
leftOverhang = loh;
var roh = (gx + bounds[i].Right + 1) - right;
if (roh > rightOverhang)
rightOverhang = roh;
}
}
}
}
}
return 0;
}
/// <summary>

Просмотреть файл

@ -245,8 +245,8 @@ namespace Topten.RichTextKit
_caretIndicies.Clear();
_measuredHeight = 0;
_measuredWidth = 0;
_minLeftMargin = 0;
_requiredLeftMargin = null;
_leftOverhang = null;
_rightOverhang = null;
// Only layout if actually have some text
if (_codePoints.Length != 0)
@ -445,39 +445,11 @@ namespace Topten.RichTextKit
}
/// <summary>
/// Returns the maximum possible overhang based on the fonts used in this text block
/// </summary>
/// <remarks>
/// Some font's can overhang the left and right margins. eg: a lowercase 'j' at
/// the start of a line will often overhang to the left of the left margin.
///
/// This property returns the maximum overhang in each direction based on the fonts
/// used, but not the actual text or final layout. This can be useful to get a
/// consistent maximum possible overhang, although the returned value is often
/// excessive (depending on the font).
///
/// Currently only the left overhang is calculated.
///
/// The return rectangle describes overhang amounts for each edge - not rectangle
/// co-ordinates.
/// </remarks>
public SKRect MaxOverhang
{
get
{
Layout();
return new SKRect(_minLeftMargin, 0, 0, 0);
}
}
/// <summary>
/// Gets the actual measured overhang in each direction based on the
/// fonts used, and the supplied text.
/// </summary>
/// <remarks>
/// Currently only the left overhang is calculated.
///
/// The return rectangle describes overhang amounts for each edge - not
/// rectangle co-ordinates.
/// </remarks>
@ -486,23 +458,19 @@ namespace Topten.RichTextKit
get
{
Layout();
if (!_requiredLeftMargin.HasValue)
if (!_leftOverhang.HasValue)
{
float required = 0;
var right = _maxWidth ?? MeasuredWidth;
float leftOverhang = 0;
float rightOverhang = 0;
foreach (var l in _lines)
{
if (l.Runs.Count == 0)
continue;
var r = l.Runs[0];
if (r.RunKind == FontRunKind.TrailingWhitespace)
continue;
var m = r.CalculateRequiredLeftMargin();
if (m > required)
required = m;
l.UpdateOverhang(right, ref leftOverhang, ref rightOverhang);
}
_requiredLeftMargin = required;
_leftOverhang = leftOverhang;
_rightOverhang = rightOverhang;
}
return new SKRect(_requiredLeftMargin.Value, 0, 0, 0);
return new SKRect(_leftOverhang.Value, 0, _rightOverhang.Value, 0);
}
}
@ -779,14 +747,14 @@ namespace Topten.RichTextKit
float _measuredWidth;
/// <summary>
/// The minimum left margin
/// The required left overhang
/// </summary>
float _minLeftMargin;
float? _leftOverhang = null;
/// <summary>
/// The required left margin
/// The required left overhang
/// </summary>
float? _requiredLeftMargin = null;
float? _rightOverhang = null;
/// <summary>
/// The final laid out set of lines
@ -953,11 +921,6 @@ namespace Topten.RichTextKit
var shaper = TextShaper.ForTypeface(typeface);
var shaped = shaper.Shape(_textShapingBuffers, codePoints, style, direction, codePoints.Start);
// Update minimum required left margin
if (shaped.XMin < 0 && -shaped.XMin > _minLeftMargin)
{
_minLeftMargin = -shaped.XMin;
}
// Create the run
var fontRun = FontRun.Pool.Get();

Просмотреть файл

@ -293,6 +293,14 @@ namespace Topten.RichTextKit
}
}
internal void UpdateOverhang(float right, ref float leftOverhang, ref float rightOverhang)
{
foreach (var r in Runs)
{
r.UpdateOverhang(right, ref leftOverhang, ref rightOverhang);
}
}
/// <summary>
/// Internal List of runs
/// </summary>