Files
MicrosoftIris/UIX/Microsoft/Iris/Drawing/TextFlow.cs
T

199 lines
6.4 KiB
C#
Raw Normal View History

2022-03-03 08:14:05 -06:00
// Decompiled with JetBrains decompiler
// Type: Microsoft.Iris.Drawing.TextFlow
// Assembly: UIX, Version=4.8.0.0, Culture=neutral, PublicKeyToken=ddd0da4d3e678217
// MVID: A56C6C9D-B7F6-46A9-8BDE-B3D9B8D60B11
// Assembly location: C:\Program Files\Zune\UIX.dll
using Microsoft.Iris.Library;
using Microsoft.Iris.OS;
using Microsoft.Iris.Render;
using Microsoft.Iris.RenderAPI.Drawing;
namespace Microsoft.Iris.Drawing
{
internal sealed class TextFlow : DisposableObject
{
private object _runsList;
private Vector _lineBounds;
private Rectangle _bounds;
private Rectangle _fitBounds;
private TextRun _lastFitRun;
private TextRun _firstFitOnFinalLineRun;
private int _firstVisibleIndex;
private int _lastVisibleIndex;
internal TextFlow()
{
_bounds = new Rectangle(int.MaxValue, int.MaxValue, int.MinValue, int.MinValue);
ResetFitTracking();
ResetVisibleTracking();
}
protected override void OnDispose()
{
if (_runsList != null)
{
if (_runsList is TextRun runsList)
{
runsList.UnregisterUsage(this);
}
else
{
foreach (SharedDisposableObject runs in (Vector)_runsList)
runs.UnregisterUsage(this);
}
}
base.OnDispose();
}
public TextRun this[int index] => _runsList is TextRun runsList ? runsList : (TextRun)((Vector)_runsList)[index];
public int Count
{
get
{
if (_runsList is Vector runsList)
return runsList.Count;
return _runsList == null ? 0 : 1;
}
}
public Vector LineBounds => _lineBounds;
internal Rectangle GetLastLineBounds(int lineAlignmentOffset)
{
Rectangle left = Rectangle.Zero;
for (int index = Count - 1; index >= 0; --index)
{
TextRun run = this[index];
if (IsOnLastLine(run))
{
Point position = run.Position;
Size size = run.Size;
int x = position.X + lineAlignmentOffset;
int y = position.Y;
int num1 = x + size.Width;
int num2 = y + size.Height;
Rectangle right = new Rectangle(x, y, num1 - x, num2 - y);
left = !left.IsZero ? Rectangle.Union(left, right) : right;
}
else
break;
}
return left;
}
internal bool IsOnLastLine(TextRun run) => run.Line == LastFitRun.Line;
public Rectangle Bounds => _bounds;
public Rectangle FitBounds => _fitBounds;
public TextRun LastFitRun => _lastFitRun;
public TextRun FirstFitRunOnFinalLine => _firstFitOnFinalLineRun;
public int FirstVisibleIndex => _firstVisibleIndex;
public int LastVisibleIndex => _lastVisibleIndex;
public bool HasVisibleRuns => _firstVisibleIndex != -1;
public void Add(TextRun run)
{
_bounds = Rectangle.Union(_bounds, run.LayoutBounds);
if (_runsList == null)
{
_runsList = run;
_lineBounds = new Vector();
_lineBounds.Add(run.RenderBounds);
}
else
{
if (!(_runsList is Vector vector))
{
object runsList = _runsList;
vector = new Vector();
vector.Add(runsList);
_runsList = vector;
}
if (run.UnderlineStyle != NativeApi.UnderlineStyle.None)
{
Rectangle underlineBounds = run.UnderlineBounds;
int line1 = run.Line;
for (int index = vector.Count - 1; index > 0; --index)
{
Point position = ((TextRun)vector[index]).Position;
int line2 = ((TextRun)vector[index]).Line;
if (position.X >= underlineBounds.Left && line1 == line2)
((TextRun)vector[index]).UnderlineStyle = run.UnderlineStyle;
else
break;
}
}
if (_lineBounds.Count < run.Line)
{
_lineBounds.Add(run.RenderBounds);
}
else
{
RectangleF lineBound = (RectangleF)_lineBounds[run.Line - 1];
if ((int)lineBound.Y > (int)run.RenderBounds.Y || lineBound.IsEmpty)
_lineBounds[run.Line - 1] = run.RenderBounds;
}
vector.Add(run);
}
run.RegisterUsage(this);
}
public void AddFit(TextRun run)
{
_fitBounds = Rectangle.Union(_fitBounds, run.LayoutBounds);
if (run.LayoutBounds.IsEmpty)
return;
if (_firstFitOnFinalLineRun == null || run.Line > _firstFitOnFinalLineRun.Line)
_firstFitOnFinalLineRun = run;
_lastFitRun = run;
}
public void AddVisible(int runIndex)
{
this[runIndex].Visible = true;
if (_firstVisibleIndex == -1)
_firstVisibleIndex = runIndex;
_lastVisibleIndex = runIndex;
}
public void ResetFitTracking()
{
_lastFitRun = null;
_fitBounds = new Rectangle(int.MaxValue, int.MaxValue, int.MinValue, int.MinValue);
}
public void ResetVisibleTracking()
{
_firstVisibleIndex = -1;
_lastVisibleIndex = int.MinValue;
}
public void ClearSprites()
{
if (_runsList == null)
return;
if (_runsList is TextRun runsList)
{
runsList.TextSprite = null;
runsList.HighlightSprite = null;
}
else
{
foreach (TextRun runs in (Vector)_runsList)
{
runs.TextSprite = null;
runs.HighlightSprite = null;
}
}
}
}
}