Removed MaxOverhang and fixed MeasuredOverhang to work out both left and right overhang
This commit is contained in:
Родитель
823e8aa268
Коммит
04eda89e11
|
@ -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>
|
||||
|
|
Загрузка…
Ссылка в новой задаче