diff --git a/samples/XamlTestApplicationPcl/TestScrollable.cs b/samples/XamlTestApplicationPcl/TestScrollable.cs
index 9d4c1d9b29..6a608b3465 100644
--- a/samples/XamlTestApplicationPcl/TestScrollable.cs
+++ b/samples/XamlTestApplicationPcl/TestScrollable.cs
@@ -62,17 +62,16 @@ namespace XamlTestApplication
for (var i = (int)_offset.Y; i < itemCount; ++i)
{
- using (var line = new FormattedText(
+ var line = new FormattedText(
"Item " + (i + 1),
TextBlock.GetFontFamily(this),
TextBlock.GetFontSize(this),
+ Size.Infinity,
TextBlock.GetFontStyle(this),
TextAlignment.Left,
- TextBlock.GetFontWeight(this)))
- {
- context.DrawText(Brushes.Black, new Point(-_offset.X, y), line);
- y += _lineSize.Height;
- }
+ TextBlock.GetFontWeight(this));
+ context.DrawText(Brushes.Black, new Point(-_offset.X, y), line);
+ y += _lineSize.Height;
}
}
@@ -88,18 +87,17 @@ namespace XamlTestApplication
protected override Size MeasureOverride(Size availableSize)
{
- using (var line = new FormattedText(
+ var line = new FormattedText(
"Item 100",
TextBlock.GetFontFamily(this),
TextBlock.GetFontSize(this),
+ Size.Infinity,
TextBlock.GetFontStyle(this),
TextAlignment.Left,
- TextBlock.GetFontWeight(this)))
- {
- line.Constraint = availableSize;
- _lineSize = line.Measure();
- return new Size(_lineSize.Width, _lineSize.Height * itemCount);
- }
+ TextBlock.GetFontWeight(this));
+ line.Constraint = availableSize;
+ _lineSize = line.Measure();
+ return new Size(_lineSize.Width, _lineSize.Height * itemCount);
}
protected override Size ArrangeOverride(Size finalSize)
diff --git a/src/Avalonia.Base/Avalonia.Base.csproj b/src/Avalonia.Base/Avalonia.Base.csproj
index 63f500270d..518f5b8f2e 100644
--- a/src/Avalonia.Base/Avalonia.Base.csproj
+++ b/src/Avalonia.Base/Avalonia.Base.csproj
@@ -72,7 +72,6 @@
-
diff --git a/src/Avalonia.Base/AvaloniaDisposable.cs b/src/Avalonia.Base/AvaloniaDisposable.cs
deleted file mode 100644
index 9e43a65f26..0000000000
--- a/src/Avalonia.Base/AvaloniaDisposable.cs
+++ /dev/null
@@ -1,41 +0,0 @@
-using System;
-using System.Collections.Generic;
-using System.Linq;
-using System.Text;
-using System.Threading.Tasks;
-using Avalonia.Platform;
-
-namespace Avalonia
-{
- public abstract class AvaloniaDisposable : IDisposable
- {
-#if DEBUG_DISPOSE
- public string DisposedAt { get; private set; }
-#endif
-
-
- public bool IsDisposed { get; private set; }
-
- public void Dispose()
- {
- IsDisposed = true;
-#if DEBUG_DISPOSE
- DisposedAt = AvaloniaLocator.Current.GetService().GetStackTrace();
-#endif
- DoDispose();
- }
-
- protected void CheckDisposed()
- {
- if (IsDisposed)
- throw new ObjectDisposedException(GetType().FullName
-#if DEBUG_DISPOSE
- , "Disposed at: \n" + DisposedAt
-#endif
-
- );
- }
-
- protected abstract void DoDispose();
- }
-}
diff --git a/src/Avalonia.Controls/Presenters/TextPresenter.cs b/src/Avalonia.Controls/Presenters/TextPresenter.cs
index d3cf4e5509..d29a6aaaef 100644
--- a/src/Avalonia.Controls/Presenters/TextPresenter.cs
+++ b/src/Avalonia.Controls/Presenters/TextPresenter.cs
@@ -226,16 +226,14 @@ namespace Avalonia.Controls.Presenters
else
{
// TODO: Pretty sure that measuring "X" isn't the right way to do this...
- using (var formattedText = new FormattedText(
+ return new FormattedText(
"X",
FontFamily,
FontSize,
+ availableSize,
FontStyle,
TextAlignment,
- FontWeight))
- {
- return formattedText.Measure();
- }
+ FontWeight).Measure();
}
}
diff --git a/src/Avalonia.Controls/Primitives/AccessText.cs b/src/Avalonia.Controls/Primitives/AccessText.cs
index 42a6f9123b..29032ae430 100644
--- a/src/Avalonia.Controls/Primitives/AccessText.cs
+++ b/src/Avalonia.Controls/Primitives/AccessText.cs
@@ -89,6 +89,7 @@ namespace Avalonia.Controls.Primitives
StripAccessKey(Text),
FontFamily,
FontSize,
+ constraint,
FontStyle,
TextAlignment,
FontWeight);
diff --git a/src/Avalonia.Controls/TextBlock.cs b/src/Avalonia.Controls/TextBlock.cs
index 028df729a5..1c8ed01e47 100644
--- a/src/Avalonia.Controls/TextBlock.cs
+++ b/src/Avalonia.Controls/TextBlock.cs
@@ -354,6 +354,7 @@ namespace Avalonia.Controls
Text ?? string.Empty,
FontFamily,
FontSize,
+ constraint,
FontStyle,
TextAlignment,
FontWeight,
@@ -370,7 +371,6 @@ namespace Avalonia.Controls
if (_formattedText != null)
{
_constraint = _formattedText.Constraint;
- _formattedText.Dispose();
_formattedText = null;
}
diff --git a/src/Avalonia.HtmlRenderer/Adapters/GraphicsAdapter.cs b/src/Avalonia.HtmlRenderer/Adapters/GraphicsAdapter.cs
index c9dd2a786c..72dd1d603c 100644
--- a/src/Avalonia.HtmlRenderer/Adapters/GraphicsAdapter.cs
+++ b/src/Avalonia.HtmlRenderer/Adapters/GraphicsAdapter.cs
@@ -117,7 +117,7 @@ namespace TheArtOfDev.HtmlRenderer.Avalonia.Adapters
FormattedText GetText(string str, RFont font)
{
var f = ((FontAdapter)font);
- return new FormattedText(str, f.Name, font.Size, f.FontStyle, TextAlignment.Left, f.Weight);
+ return new FormattedText(str, f.Name, font.Size, Size.Infinity, f.FontStyle, TextAlignment.Left, f.Weight);
}
public override void MeasureString(string str, RFont font, double maxWidth, out int charFit, out double charFitWidth)
diff --git a/src/Avalonia.Visuals/Media/FormattedText.cs b/src/Avalonia.Visuals/Media/FormattedText.cs
index f6aeaf5f5f..1308091b2f 100644
--- a/src/Avalonia.Visuals/Media/FormattedText.cs
+++ b/src/Avalonia.Visuals/Media/FormattedText.cs
@@ -10,7 +10,7 @@ namespace Avalonia.Media
///
/// Represents a piece of text with formatting.
///
- public class FormattedText : AvaloniaDisposable
+ public class FormattedText
{
///
/// Initializes a new instance of the class.
@@ -18,6 +18,7 @@ namespace Avalonia.Media
/// The text.
/// The font family.
/// The font size.
+ /// The text layout constraints.
/// The font style.
/// The text alignment.
/// The font weight.
@@ -26,6 +27,7 @@ namespace Avalonia.Media
string text,
string fontFamilyName,
double fontSize,
+ Size constraint,
FontStyle fontStyle = FontStyle.Normal,
TextAlignment textAlignment = TextAlignment.Left,
FontWeight fontWeight = FontWeight.Normal,
@@ -66,7 +68,8 @@ namespace Avalonia.Media
fontStyle,
textAlignment,
fontWeight,
- wrapping);
+ wrapping,
+ constraint);
}
///
@@ -74,16 +77,8 @@ namespace Avalonia.Media
///
public Size Constraint
{
- get
- {
- CheckDisposed();
- return PlatformImpl.Constraint;
- }
- set
- {
- CheckDisposed();
- PlatformImpl.Constraint = value;
- }
+ get { return PlatformImpl.Constraint; }
+ set { PlatformImpl = PlatformImpl.WithConstraint(value); }
}
///
@@ -114,7 +109,7 @@ namespace Avalonia.Media
///
/// Gets platform-specific platform implementation.
///
- public IFormattedTextImpl PlatformImpl { get; }
+ public IFormattedTextImpl PlatformImpl { get; private set; }
///
/// Gets the text alignment.
@@ -126,14 +121,6 @@ namespace Avalonia.Media
///
public TextWrapping Wrapping { get; }
- ///
- /// Disposes of unmanaged resources associated with the formatted text.
- ///
- protected override void DoDispose()
- {
- PlatformImpl.Dispose();
- }
-
///
/// Gets the lines in the text.
///
@@ -142,7 +129,6 @@ namespace Avalonia.Media
///
public IEnumerable GetLines()
{
- CheckDisposed();
return PlatformImpl.GetLines();
}
@@ -155,7 +141,6 @@ namespace Avalonia.Media
///
public TextHitTestResult HitTestPoint(Point point)
{
- CheckDisposed();
return PlatformImpl.HitTestPoint(point);
}
@@ -166,7 +151,6 @@ namespace Avalonia.Media
/// The character bounds.
public Rect HitTestTextPosition(int index)
{
- CheckDisposed();
return PlatformImpl.HitTestTextPosition(index);
}
@@ -178,7 +162,6 @@ namespace Avalonia.Media
/// The character bounds.
public IEnumerable HitTestTextRange(int index, int length)
{
- CheckDisposed();
return PlatformImpl.HitTestTextRange(index, length);
}
@@ -188,8 +171,7 @@ namespace Avalonia.Media
/// The bounds box of the text.
public Size Measure()
{
- CheckDisposed();
- return PlatformImpl.Measure();
+ return PlatformImpl.Size;
}
///
@@ -200,7 +182,6 @@ namespace Avalonia.Media
/// The length of the text range.
public void SetForegroundBrush(IBrush brush, int startIndex, int length)
{
- CheckDisposed();
PlatformImpl.SetForegroundBrush(brush, startIndex, length);
}
}
diff --git a/src/Avalonia.Visuals/Platform/IFormattedTextImpl.cs b/src/Avalonia.Visuals/Platform/IFormattedTextImpl.cs
index e3a44c437e..9ffa3d6228 100644
--- a/src/Avalonia.Visuals/Platform/IFormattedTextImpl.cs
+++ b/src/Avalonia.Visuals/Platform/IFormattedTextImpl.cs
@@ -10,12 +10,17 @@ namespace Avalonia.Platform
///
/// Defines the platform-specific interface for .
///
- public interface IFormattedTextImpl : IDisposable
+ public interface IFormattedTextImpl
{
///
- /// Gets or sets the constraint of the text.
+ /// Gets the constraint of the text.
///
- Size Constraint { get; set; }
+ Size Constraint { get; }
+
+ ///
+ /// The measured size of the text.
+ ///
+ Size Size { get; }
///
/// Gets the text.
@@ -54,12 +59,6 @@ namespace Avalonia.Platform
/// The character bounds.
IEnumerable HitTestTextRange(int index, int length);
- ///
- /// Gets the size of the text, taking into account.
- ///
- /// The bounds box of the text.
- Size Measure();
-
///
/// Sets the foreground brush for the specified text range.
///
@@ -67,5 +66,12 @@ namespace Avalonia.Platform
/// The start of the text range.
/// The length of the text range.
void SetForegroundBrush(IBrush brush, int startIndex, int length);
+
+ ///
+ /// Makes a clone of the formatted text with the specified constraint.
+ ///
+ /// The constraint.
+ /// The cloned formatted text.
+ IFormattedTextImpl WithConstraint(Size constraint);
}
}
diff --git a/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs b/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs
index c129cbd905..5cd5f9dadf 100644
--- a/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs
+++ b/src/Avalonia.Visuals/Platform/IPlatformRenderInterface.cs
@@ -21,6 +21,7 @@ namespace Avalonia.Platform
/// The text alignment.
/// The font weight.
/// The text wrapping mode.
+ /// The text layout constraints.
/// An .
IFormattedTextImpl CreateFormattedText(
string text,
@@ -29,7 +30,8 @@ namespace Avalonia.Platform
FontStyle fontStyle,
TextAlignment textAlignment,
FontWeight fontWeight,
- TextWrapping wrapping);
+ TextWrapping wrapping,
+ Size constraint);
///
/// Creates a stream geometry implementation.
diff --git a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
index 2c5b31e63e..a7315fbb39 100644
--- a/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
+++ b/src/Avalonia.Visuals/Rendering/DeferredRenderer.cs
@@ -105,17 +105,15 @@ namespace Avalonia.Rendering
}
var pt = new Point(40, 40);
- using (
- var txt = new FormattedText($"Frame #{_totalFrames} FPS: {_fps} Updates: {count}", "Arial", 18,
- FontStyle.Normal,
- TextAlignment.Left,
- FontWeight.Normal,
- TextWrapping.NoWrap))
- {
- context.Transform = Matrix.Identity;
- context.FillRectangle(Brushes.White, new Rect(pt, txt.Measure()));
- context.DrawText(Brushes.Black, pt, txt.PlatformImpl);
- }
+ var txt = new FormattedText($"Frame #{_totalFrames} FPS: {_fps} Updates: {count}", "Arial", 18,
+ Size.Infinity,
+ FontStyle.Normal,
+ TextAlignment.Left,
+ FontWeight.Normal,
+ TextWrapping.NoWrap);
+ context.Transform = Matrix.Identity;
+ context.FillRectangle(Brushes.White, new Rect(pt, txt.Measure()));
+ context.DrawText(Brushes.Black, pt, txt.PlatformImpl);
}
private void UpdateScene()
diff --git a/src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs b/src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs
index 749b44eb9d..3c59960c52 100644
--- a/src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs
+++ b/src/Avalonia.Visuals/Rendering/SceneGraph/TextNode.cs
@@ -11,7 +11,7 @@ namespace Avalonia.Rendering.SceneGraph
{
public TextNode(Matrix transform, IBrush foreground, Point origin, IFormattedTextImpl text)
{
- Bounds = new Rect(origin, text.Measure()) * transform;
+ Bounds = new Rect(origin, text.Size) * transform;
Transform = transform;
Foreground = foreground;
Origin = origin;
diff --git a/src/Gtk/Avalonia.Cairo/CairoPlatform.cs b/src/Gtk/Avalonia.Cairo/CairoPlatform.cs
index e59bcfffa1..4fc177d777 100644
--- a/src/Gtk/Avalonia.Cairo/CairoPlatform.cs
+++ b/src/Gtk/Avalonia.Cairo/CairoPlatform.cs
@@ -45,9 +45,10 @@ namespace Avalonia.Cairo
FontStyle fontStyle,
TextAlignment textAlignment,
Avalonia.Media.FontWeight fontWeight,
- TextWrapping wrapping)
+ TextWrapping wrapping,
+ Size constraint)
{
- return new FormattedTextImpl(s_pangoContext, text, fontFamily, fontSize, fontStyle, textAlignment, fontWeight);
+ return new FormattedTextImpl(s_pangoContext, text, fontFamily, fontSize, fontStyle, textAlignment, fontWeight, constraint);
}
public IRenderTarget CreateRenderTarget(IPlatformHandle handle)
diff --git a/src/Gtk/Avalonia.Cairo/Media/FormattedTextImpl.cs b/src/Gtk/Avalonia.Cairo/Media/FormattedTextImpl.cs
index 506773aaa0..1d1bde004f 100644
--- a/src/Gtk/Avalonia.Cairo/Media/FormattedTextImpl.cs
+++ b/src/Gtk/Avalonia.Cairo/Media/FormattedTextImpl.cs
@@ -12,7 +12,7 @@ namespace Avalonia.Cairo.Media
{
public class FormattedTextImpl : IFormattedTextImpl
{
- private Size _size;
+ private Size _constraint;
static double CorrectScale(double input)
{
@@ -26,51 +26,37 @@ namespace Avalonia.Cairo.Media
double fontSize,
FontStyle fontStyle,
TextAlignment textAlignment,
- FontWeight fontWeight)
+ FontWeight fontWeight,
+ Size constraint)
{
Contract.Requires(context != null);
Contract.Requires(text != null);
- Layout = new Pango.Layout(context);
- Text = text;
- Layout.SetText(text);
- Layout.FontDescription = new Pango.FontDescription
- {
- Family = fontFamily,
- Size = Pango.Units.FromDouble(CorrectScale(fontSize)),
- Style = (Pango.Style)fontStyle,
- Weight = fontWeight.ToCairo()
- };
- Layout.Alignment = textAlignment.ToCairo();
- Layout.Attributes = new Pango.AttrList();
+ Layout = Create(
+ context,
+ text,
+ fontFamily,
+ fontSize,
+ (Pango.Style)fontStyle,
+ textAlignment.ToCairo(),
+ fontWeight.ToCairo(),
+ constraint);
+ Size = Measure();
}
- public string Text { get; }
-
- public Size Constraint
+ public FormattedTextImpl(Pango.Layout layout)
{
- get
- {
- return _size;
- }
-
- set
- {
- _size = value;
- Layout.Width = double.IsPositiveInfinity(value.Width) ?
- -1 : Pango.Units.FromDouble(value.Width);
- }
+ Layout = layout;
+ Size = Measure();
}
- public Pango.Layout Layout
- {
- get;
- }
+ public string Text => Layout.Text;
- public void Dispose()
- {
- Layout.Dispose();
- }
+ public Size Constraint => _constraint;
+
+ public Size Size { get; }
+
+ public Pango.Layout Layout { get; }
public IEnumerable GetLines()
{
@@ -125,15 +111,6 @@ namespace Avalonia.Cairo.Media
return ranges;
}
- public Size Measure()
- {
- int width;
- int height;
- Layout.GetPixelSize(out width, out height);
-
- return new Size(width, height);
- }
-
public void SetForegroundBrush(IBrush brush, int startIndex, int count)
{
var scb = brush as SolidColorBrush;
@@ -150,5 +127,57 @@ namespace Avalonia.Cairo.Media
Layout.Attributes.Insert(brushAttr);
}
}
+
+ public IFormattedTextImpl WithConstraint(Size constraint)
+ {
+ return new FormattedTextImpl(Create(
+ Layout.Context,
+ Layout.Text,
+ Layout.FontDescription.Family,
+ Layout.FontDescription.Size,
+ Layout.FontDescription.Style,
+ Layout.Alignment,
+ Layout.FontDescription.Weight,
+ constraint));
+ }
+
+ private Pango.Layout Create(
+ Pango.Context context,
+ string text,
+ string fontFamily,
+ double fontSize,
+ Pango.Style fontStyle,
+ Pango.Alignment textAlignment,
+ Pango.Weight fontWeight,
+ Size constraint)
+ {
+ Contract.Requires(context != null);
+ Contract.Requires(text != null);
+ var result = new Pango.Layout(context);
+
+ result.SetText(text);
+
+ result.FontDescription = new Pango.FontDescription
+ {
+ Family = fontFamily,
+ Size = Pango.Units.FromDouble(CorrectScale(fontSize)),
+ Style = (Pango.Style)fontStyle,
+ Weight = fontWeight
+ };
+
+ result.Alignment = textAlignment;
+ result.Attributes = new Pango.AttrList();
+ result.Width = double.IsPositiveInfinity(constraint.Width) ? -1 : Pango.Units.FromDouble(constraint.Width);
+ return result;
+ }
+
+ private Size Measure()
+ {
+ int width;
+ int height;
+ Layout.GetPixelSize(out width, out height);
+
+ return new Size(width, height);
+ }
}
}
diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
index c3e7ce9d57..39445652bc 100644
--- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
+++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs
@@ -281,7 +281,7 @@ namespace Avalonia.Skia
public void DrawText(IBrush foreground, Point origin, IFormattedTextImpl text)
{
- using (var paint = CreatePaint(foreground, text.Measure()))
+ using (var paint = CreatePaint(foreground, text.Size))
{
var textImpl = text as FormattedTextImpl;
textImpl.Draw(this, Canvas, origin.ToSKPoint(), paint);
diff --git a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs
index f0bacb801f..95ae6c3195 100644
--- a/src/Skia/Avalonia.Skia/FormattedTextImpl.cs
+++ b/src/Skia/Avalonia.Skia/FormattedTextImpl.cs
@@ -13,7 +13,7 @@ namespace Avalonia.Skia
public class FormattedTextImpl : IFormattedTextImpl
{
public FormattedTextImpl(string text, string fontFamilyName, double fontSize, FontStyle fontStyle,
- TextAlignment textAlignment, FontWeight fontWeight, TextWrapping wrapping)
+ TextAlignment textAlignment, FontWeight fontWeight, TextWrapping wrapping, Size constraint)
{
Text = text ?? string.Empty;
@@ -36,27 +36,14 @@ namespace Avalonia.Skia
_paint.TextAlign = textAlignment.ToSKTextAlign();
_wrapping = wrapping;
+ _constraint = constraint;
Rebuild();
}
- public Size Constraint
- {
- get { return _constraint; }
- set
- {
- if (_constraint == value)
- return;
+ public Size Constraint => _constraint;
- _constraint = value;
-
- Rebuild();
- }
- }
-
- public void Dispose()
- {
- }
+ public Size Size => _size;
public IEnumerable GetLines()
{
@@ -159,11 +146,6 @@ namespace Avalonia.Skia
return result;
}
- public Size Measure()
- {
- return _size;
- }
-
public void SetForegroundBrush(IBrush brush, int startIndex, int length)
{
var key = new FBrushRange(startIndex, length);
@@ -185,6 +167,11 @@ namespace Avalonia.Skia
return Text;
}
+ public IFormattedTextImpl WithConstraint(Size constraint)
+ {
+ throw new NotImplementedException();
+ }
+
internal void Draw(DrawingContextImpl context,
SKCanvas canvas, SKPoint origin,
DrawingContextImpl.PaintWrapper foreground)
diff --git a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
index f8558c7428..d389808c1f 100644
--- a/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
+++ b/src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
@@ -15,9 +15,9 @@ namespace Avalonia.Skia
}
public IFormattedTextImpl CreateFormattedText(string text, string fontFamilyName, double fontSize, FontStyle fontStyle,
- TextAlignment textAlignment, FontWeight fontWeight, TextWrapping wrapping)
+ TextAlignment textAlignment, FontWeight fontWeight, TextWrapping wrapping, Size constraint)
{
- return new FormattedTextImpl(text, fontFamilyName, fontSize, fontStyle, textAlignment, fontWeight, wrapping);
+ return new FormattedTextImpl(text, fontFamilyName, fontSize, fontStyle, textAlignment, fontWeight, wrapping, constraint);
}
public IStreamGeometryImpl CreateStreamGeometry()
diff --git a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
index 8d8c175359..6b261d5f1a 100644
--- a/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
+++ b/src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
@@ -37,13 +37,16 @@ namespace Avalonia.Direct2D1
private static readonly SharpDX.WIC.ImagingFactory s_imagingFactory = new SharpDX.WIC.ImagingFactory();
- public static void Initialize() => AvaloniaLocator.CurrentMutable
- .Bind().ToConstant(s_instance)
- .Bind().ToConstant(s_instance)
- .BindToSelf(s_d2D1Factory)
- .BindToSelf(s_dwfactory)
- .BindToSelf(s_imagingFactory);
+ public static void Initialize()
+ {
+ AvaloniaLocator.CurrentMutable
+ .Bind().ToConstant(s_instance)
+ .Bind().ToConstant(s_instance)
+ .BindToSelf(s_d2D1Factory)
+ .BindToSelf(s_dwfactory)
+ .BindToSelf(s_imagingFactory);
SharpDX.Configuration.EnableReleaseOnFinalizer = true;
+ }
public IBitmapImpl CreateBitmap(int width, int height)
{
@@ -57,9 +60,18 @@ namespace Avalonia.Direct2D1
FontStyle fontStyle,
TextAlignment textAlignment,
FontWeight fontWeight,
- TextWrapping wrapping)
+ TextWrapping wrapping,
+ Size constraint)
{
- return new FormattedTextImpl(text, fontFamily, fontSize, fontStyle, textAlignment, fontWeight, wrapping);
+ return new FormattedTextImpl(
+ text,
+ fontFamily,
+ fontSize,
+ fontStyle,
+ textAlignment,
+ fontWeight,
+ wrapping,
+ constraint);
}
public IRenderer CreateRenderer(IRenderRoot root, IRenderLoop renderLoop)
diff --git a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
index 2747ad7ca0..14006f2c6f 100644
--- a/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
+++ b/src/Windows/Avalonia.Direct2D1/Media/DrawingContextImpl.cs
@@ -194,7 +194,7 @@ namespace Avalonia.Direct2D1.Media
{
var impl = (FormattedTextImpl)text;
- using (var brush = CreateBrush(foreground, impl.Measure()))
+ using (var brush = CreateBrush(foreground, impl.Size))
using (var renderer = new AvaloniaTextRenderer(this, _renderTarget, brush.PlatformBrush))
{
if (brush.PlatformBrush != null)
diff --git a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs
index b8e295e8ab..ec33f3e2e1 100644
--- a/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs
+++ b/src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs
@@ -19,47 +19,34 @@ namespace Avalonia.Direct2D1.Media
FontStyle fontStyle,
TextAlignment textAlignment,
FontWeight fontWeight,
- TextWrapping wrapping)
+ TextWrapping wrapping,
+ Size constraint)
{
- var factory = AvaloniaLocator.Current.GetService();
-
Text = text;
-
- using (var format = new DWrite.TextFormat(
- factory,
+ TextLayout = Create(
+ text,
fontFamily,
- (DWrite.FontWeight)fontWeight,
+ fontSize,
(DWrite.FontStyle)fontStyle,
- (float)fontSize))
- {
- format.WordWrapping = wrapping == TextWrapping.Wrap ?
- DWrite.WordWrapping.Wrap : DWrite.WordWrapping.NoWrap;
-
- TextLayout = new DWrite.TextLayout(
- factory,
- text ?? string.Empty,
- format,
- float.MaxValue,
- float.MaxValue);
- }
-
- TextLayout.TextAlignment = textAlignment.ToDirect2D();
+ (DWrite.TextAlignment)textAlignment,
+ (DWrite.FontWeight)fontWeight,
+ wrapping == TextWrapping.Wrap ? DWrite.WordWrapping.Wrap : DWrite.WordWrapping.NoWrap,
+ (float)constraint.Width,
+ (float)constraint.Height);
+ Size = Measure();
}
- public Size Constraint
+ public FormattedTextImpl(string text, DWrite.TextLayout textLayout)
{
- get
- {
- return new Size(TextLayout.MaxWidth, TextLayout.MaxHeight);
- }
-
- set
- {
- TextLayout.MaxWidth = (float)value.Width;
- TextLayout.MaxHeight = (float)value.Height;
- }
+ Text = text;
+ TextLayout = textLayout;
+ Size = Measure();
}
+ public Size Constraint => new Size(TextLayout.MaxWidth, TextLayout.MaxHeight);
+
+ public Size Size { get; }
+
public string Text { get; }
public DWrite.TextLayout TextLayout { get; }
@@ -114,7 +101,62 @@ namespace Avalonia.Direct2D1.Media
return result.Select(x => new Rect(x.Left, x.Top, x.Width, x.Height));
}
- public Size Measure()
+ public void SetForegroundBrush(IBrush brush, int startIndex, int count)
+ {
+ TextLayout.SetDrawingEffect(
+ new BrushWrapper(brush),
+ new DWrite.TextRange(startIndex, count));
+ }
+
+ public IFormattedTextImpl WithConstraint(Size constraint)
+ {
+ var factory = AvaloniaLocator.Current.GetService();
+ return new FormattedTextImpl(Text, Create(
+ Text,
+ TextLayout.FontFamilyName,
+ TextLayout.FontSize,
+ TextLayout.FontStyle,
+ TextLayout.TextAlignment,
+ TextLayout.FontWeight,
+ TextLayout.WordWrapping,
+ (float)constraint.Width,
+ (float)constraint.Height));
+ }
+
+ private static DWrite.TextLayout Create(
+ string text,
+ string fontFamily,
+ double fontSize,
+ DWrite.FontStyle fontStyle,
+ DWrite.TextAlignment textAlignment,
+ DWrite.FontWeight fontWeight,
+ DWrite.WordWrapping wrapping,
+ float constraintX,
+ float constraintY)
+ {
+ var factory = AvaloniaLocator.Current.GetService();
+
+ using (var format = new DWrite.TextFormat(
+ factory,
+ fontFamily,
+ fontWeight,
+ fontStyle,
+ (float)fontSize))
+ {
+ format.WordWrapping = wrapping;
+
+ var result = new DWrite.TextLayout(
+ factory,
+ text ?? string.Empty,
+ format,
+ constraintX,
+ constraintY);
+ result.TextAlignment = textAlignment;
+ return result;
+ }
+ }
+
+ private Size Measure()
{
var metrics = TextLayout.Metrics;
var width = metrics.WidthIncludingTrailingWhitespace;
@@ -126,12 +168,5 @@ namespace Avalonia.Direct2D1.Media
return new Size(width, TextLayout.Metrics.Height);
}
-
- public void SetForegroundBrush(IBrush brush, int startIndex, int count)
- {
- TextLayout.SetDrawingEffect(
- new BrushWrapper(brush),
- new DWrite.TextRange(startIndex, count));
- }
}
}
diff --git a/tests/Avalonia.RenderTests/Media/FormattedTextImplTests.cs b/tests/Avalonia.RenderTests/Media/FormattedTextImplTests.cs
index 395e6f8fd8..b2885b5adf 100644
--- a/tests/Avalonia.RenderTests/Media/FormattedTextImplTests.cs
+++ b/tests/Avalonia.RenderTests/Media/FormattedTextImplTests.cs
@@ -59,7 +59,8 @@ namespace Avalonia.Direct2D1.RenderTests.Media
fontStyle,
textAlignment,
fontWeight,
- wrapping);
+ wrapping,
+ Size.Infinity);
}
private IFormattedTextImpl Create(string text, double fontSize)
@@ -109,17 +110,15 @@ namespace Avalonia.Direct2D1.RenderTests.Media
//4.55273438 for font 12 size
double heightCorr = 0.3793945*fontSize;
#endif
- using (var fmt = Create(input, fontSize))
- {
- var size = fmt.Measure();
+ var fmt = Create(input, fontSize);
+ var size = fmt.Size;
- Assert.Equal(expWidth, size.Width, 2);
- Assert.Equal(expHeight + heightCorr, size.Height, 2);
+ Assert.Equal(expWidth, size.Width, 2);
+ Assert.Equal(expHeight + heightCorr, size.Height, 2);
- var linesHeight = fmt.GetLines().Sum(l => l.Height);
+ var linesHeight = fmt.GetLines().Sum(l => l.Height);
- Assert.Equal(expHeight, linesHeight, 2);
- }
+ Assert.Equal(expHeight, linesHeight, 2);
}
#if AVALONIA_CAIRO
@@ -143,16 +142,16 @@ namespace Avalonia.Direct2D1.RenderTests.Media
double widthConstraint,
TextWrapping wrap)
{
- using (var fmt = Create(input, FontSize, wrap))
- {
- if (widthConstraint != -1)
- {
- fmt.Constraint = new Size(widthConstraint, 10000);
- }
+ var fmt = Create(input, FontSize, wrap);
+ var constrained = fmt;
- var lines = fmt.GetLines().ToArray();
- Assert.Equal(linesCount, lines.Count());
+ if (widthConstraint != -1)
+ {
+ constrained = fmt.WithConstraint(new Size(widthConstraint, 10000));
}
+
+ var lines = constrained.GetLines().ToArray();
+ Assert.Equal(linesCount, lines.Count());
}
#if AVALONIA_CAIRO
@@ -186,14 +185,12 @@ namespace Avalonia.Direct2D1.RenderTests.Media
double x, double y,
bool isInside, bool isTrailing, int pos)
{
- using (var fmt = Create(input, FontSize))
- {
- var htRes = fmt.HitTestPoint(new Point(x, y));
+ var fmt = Create(input, FontSize);
+ var htRes = fmt.HitTestPoint(new Point(x, y));
- Assert.Equal(pos, htRes.TextPosition);
- Assert.Equal(isInside, htRes.IsInside);
- Assert.Equal(isTrailing, htRes.IsTrailing);
- }
+ Assert.Equal(pos, htRes.TextPosition);
+ Assert.Equal(isInside, htRes.IsInside);
+ Assert.Equal(isTrailing, htRes.IsTrailing);
}
#if AVALONIA_CAIRO
@@ -213,15 +210,13 @@ namespace Avalonia.Direct2D1.RenderTests.Media
public void Should_HitTestPosition_Correctly(string input,
int index, double x, double y, double width, double height)
{
- using (var fmt = Create(input, FontSize))
- {
- var r = fmt.HitTestTextPosition(index);
+ var fmt = Create(input, FontSize);
+ var r = fmt.HitTestTextPosition(index);
- Assert.Equal(x, r.X, 2);
- Assert.Equal(y, r.Y, 2);
- Assert.Equal(width, r.Width, 2);
- Assert.Equal(height, r.Height, 2);
- }
+ Assert.Equal(x, r.X, 2);
+ Assert.Equal(y, r.Y, 2);
+ Assert.Equal(width, r.Width, 2);
+ Assert.Equal(height, r.Height, 2);
}
#if AVALONIA_CAIRO
@@ -237,17 +232,20 @@ namespace Avalonia.Direct2D1.RenderTests.Media
double x, double y, double width, double height)
{
//parse expected
- using (var fmt = Create(input, FontSize, TextAlignment.Right))
+ var fmt = Create(input, FontSize, TextAlignment.Right);
+ var constrained = fmt;
+
+ if (widthConstraint != -1)
{
- fmt.Constraint = new Size(widthConstraint, 100);
+ constrained = fmt.WithConstraint(new Size(widthConstraint, 100));
+ }
- var r = fmt.HitTestTextPosition(index);
+ var r = constrained.HitTestTextPosition(index);
- Assert.Equal(x, r.X, 2);
- Assert.Equal(y, r.Y, 2);
- Assert.Equal(width, r.Width, 2);
- Assert.Equal(height, r.Height, 2);
- }
+ Assert.Equal(x, r.X, 2);
+ Assert.Equal(y, r.Y, 2);
+ Assert.Equal(width, r.Width, 2);
+ Assert.Equal(height, r.Height, 2);
}
#if AVALONIA_CAIRO
@@ -263,17 +261,20 @@ namespace Avalonia.Direct2D1.RenderTests.Media
double x, double y, double width, double height)
{
//parse expected
- using (var fmt = Create(input, FontSize, TextAlignment.Center))
+ var fmt = Create(input, FontSize, TextAlignment.Center);
+ var constrained = fmt;
+
+ if (widthConstraint != -1)
{
- fmt.Constraint = new Size(widthConstraint, 100);
+ constrained = fmt.WithConstraint(new Size(widthConstraint, 100));
+ }
- var r = fmt.HitTestTextPosition(index);
+ var r = constrained.HitTestTextPosition(index);
- Assert.Equal(x, r.X, 2);
- Assert.Equal(y, r.Y, 2);
- Assert.Equal(width, r.Width, 2);
- Assert.Equal(height, r.Height, 2);
- }
+ Assert.Equal(x, r.X, 2);
+ Assert.Equal(y, r.Y, 2);
+ Assert.Equal(width, r.Width, 2);
+ Assert.Equal(height, r.Height, 2);
}
#if AVALONIA_CAIRO
@@ -299,22 +300,20 @@ namespace Avalonia.Direct2D1.RenderTests.Media
return new Rect(v[0], v[1], v[2], v[3]);
}).ToArray();
- using (var fmt = Create(input, FontSize))
- {
- var htRes = fmt.HitTestTextRange(index, length).ToArray();
+ var fmt = Create(input, FontSize);
+ var htRes = fmt.HitTestTextRange(index, length).ToArray();
- Assert.Equal(rects.Length, htRes.Length);
+ Assert.Equal(rects.Length, htRes.Length);
- for (int i = 0; i < rects.Length; i++)
- {
- var exr = rects[i];
- var r = htRes[i];
+ for (int i = 0; i < rects.Length; i++)
+ {
+ var exr = rects[i];
+ var r = htRes[i];
- Assert.Equal(exr.X, r.X, 2);
- Assert.Equal(exr.Y, r.Y, 2);
- Assert.Equal(exr.Width, r.Width, 2);
- Assert.Equal(exr.Height, r.Height, 2);
- }
+ Assert.Equal(exr.X, r.X, 2);
+ Assert.Equal(exr.Y, r.Y, 2);
+ Assert.Equal(exr.Width, r.Width, 2);
+ Assert.Equal(exr.Height, r.Height, 2);
}
}
}
diff --git a/tests/Avalonia.UnitTests/TestServices.cs b/tests/Avalonia.UnitTests/TestServices.cs
index c53e4b44ca..6593216a10 100644
--- a/tests/Avalonia.UnitTests/TestServices.cs
+++ b/tests/Avalonia.UnitTests/TestServices.cs
@@ -163,6 +163,9 @@ namespace Avalonia.UnitTests
private static IPlatformRenderInterface CreateRenderInterfaceMock()
{
+ var formattedTextImpl = new Mock();
+ formattedTextImpl.Setup(x => x.WithConstraint(It.IsAny())).Returns(() => formattedTextImpl.Object);
+
return Mock.Of(x =>
x.CreateFormattedText(
It.IsAny(),
@@ -171,7 +174,8 @@ namespace Avalonia.UnitTests
It.IsAny(),
It.IsAny(),
It.IsAny(),
- It.IsAny()) == Mock.Of() &&
+ It.IsAny(),
+ It.IsAny()) == formattedTextImpl.Object &&
x.CreateStreamGeometry() == Mock.Of(
y => y.Open() == Mock.Of()));
}
diff --git a/tests/Avalonia.Visuals.UnitTests/Media/FormattedTextTests.cs b/tests/Avalonia.Visuals.UnitTests/Media/FormattedTextTests.cs
index 648595fa2b..f7b9c137ea 100644
--- a/tests/Avalonia.Visuals.UnitTests/Media/FormattedTextTests.cs
+++ b/tests/Avalonia.Visuals.UnitTests/Media/FormattedTextTests.cs
@@ -12,7 +12,8 @@ namespace Avalonia.Visuals.UnitTests.Media
Assert.Throws(() => new FormattedText(
"foo",
"Ariel",
- 0));
+ 0,
+ Size.Infinity));
}
[Fact]
@@ -22,6 +23,7 @@ namespace Avalonia.Visuals.UnitTests.Media
"foo",
"Ariel",
12,
+ Size.Infinity,
fontWeight: 0));
}
}
diff --git a/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs b/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs
index 713d55a14a..1b373d93a0 100644
--- a/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs
+++ b/tests/Avalonia.Visuals.UnitTests/VisualTree/MockRenderInterface.cs
@@ -15,7 +15,8 @@ namespace Avalonia.Visuals.UnitTests.VisualTree
FontStyle fontStyle,
TextAlignment textAlignment,
FontWeight fontWeight,
- TextWrapping wrapping)
+ TextWrapping wrapping,
+ Size constraint)
{
throw new NotImplementedException();
}