Browse Source

Fixed TextBlock text wrapping.

And added render test (so far only to D2D backend)
pull/543/head
Steven Kirk 10 years ago
parent
commit
ec35cdde79
  1. 1
      src/Avalonia.Controls/Avalonia.Controls.csproj
  2. 4
      src/Avalonia.Controls/TextBlock.cs
  3. 3
      src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj
  4. 57
      src/Avalonia.SceneGraph/Media/FormattedText.cs
  5. 4
      src/Avalonia.SceneGraph/Media/TextWrapping.cs
  6. 4
      src/Avalonia.SceneGraph/Platform/IPlatformRenderInterface.cs
  7. 3
      src/Avalonia.SceneGraph/Rendering/RendererMixin.cs
  8. 3
      src/Gtk/Avalonia.Cairo/CairoPlatform.cs
  9. 2
      src/Skia/Avalonia.Skia/PlatformRenderInterface.cs
  10. 5
      src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs
  11. 6
      src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs
  12. 3
      tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.csproj
  13. 47
      tests/Avalonia.RenderTests/Controls/TextBlockTests.cs
  14. 5
      tests/Avalonia.RenderTests/TestBase.cs
  15. 3
      tests/Avalonia.UnitTests/TestServices.cs
  16. BIN
      tests/TestFiles/Direct2D1/Controls/TextBlock/Wrapping_NoWrap.expected.png

1
src/Avalonia.Controls/Avalonia.Controls.csproj

@ -164,7 +164,6 @@
<Compile Include="ToolTip.cs" />
<Compile Include="UserControl.cs" />
<Compile Include="Templates\TemplateExtensions.cs" />
<Compile Include="TextWrapping.cs" />
<Compile Include="Utils\AncestorFinder.cs" />
<Compile Include="Utils\IEnumerableUtils.cs" />
<Compile Include="Utils\StringUtils.cs" />

4
src/Avalonia.Controls/TextBlock.cs

@ -99,6 +99,7 @@ namespace Avalonia.Controls
/// </summary>
static TextBlock()
{
ClipToBoundsProperty.OverrideDefaultValue<TextBlock>(true);
AffectsRender(ForegroundProperty);
AffectsRender(FontWeightProperty);
AffectsRender(FontSizeProperty);
@ -355,7 +356,8 @@ namespace Avalonia.Controls
FontSize,
FontStyle,
TextAlignment,
FontWeight);
FontWeight,
TextWrapping);
result.Constraint = constraint;
return result;
}

3
src/Avalonia.SceneGraph/Avalonia.SceneGraph.csproj

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
@ -68,6 +68,7 @@
<Compile Include="Media\BrushMappingMode.cs" />
<Compile Include="Media\Color.cs" />
<Compile Include="Media\Colors.cs" />
<Compile Include="Media\TextWrapping.cs" />
<Compile Include="Media\TransformGroup.cs" />
<Compile Include="Media\DashStyle.cs" />
<Compile Include="Media\DrawingContext.cs" />

57
src/Avalonia.SceneGraph/Media/FormattedText.cs

@ -21,13 +21,15 @@ namespace Avalonia.Media
/// <param name="fontStyle">The font style.</param>
/// <param name="textAlignment">The text alignment.</param>
/// <param name="fontWeight">The font weight.</param>
/// <param name="wrapping">The text wrapping mode.</param>
public FormattedText(
string text,
string fontFamilyName,
double fontSize,
FontStyle fontStyle,
TextAlignment textAlignment,
FontWeight fontWeight)
FontStyle fontStyle = FontStyle.Normal,
TextAlignment textAlignment = TextAlignment.Left,
FontWeight fontWeight = FontWeight.Normal,
TextWrapping wrapping = TextWrapping.Wrap)
{
Contract.Requires<ArgumentNullException>(text != null);
Contract.Requires<ArgumentNullException>(fontFamilyName != null);
@ -39,6 +41,7 @@ namespace Avalonia.Media
FontStyle = fontStyle;
FontWeight = fontWeight;
TextAlignment = textAlignment;
Wrapping = wrapping;
var platform = AvaloniaLocator.Current.GetService<IPlatformRenderInterface>();
@ -53,7 +56,8 @@ namespace Avalonia.Media
fontSize,
fontStyle,
textAlignment,
fontWeight);
fontWeight,
wrapping);
}
/// <summary>
@ -76,63 +80,42 @@ namespace Avalonia.Media
/// <summary>
/// Gets the font family.
/// </summary>
public string FontFamilyName
{
get;
private set;
}
public string FontFamilyName { get; }
/// <summary>
/// Gets the font size.
/// </summary>
public double FontSize
{
get;
private set;
}
public double FontSize { get; }
/// <summary>
/// Gets the font style.
/// </summary>
public FontStyle FontStyle
{
get;
private set;
}
public FontStyle FontStyle { get; }
/// <summary>
/// Gets the font weight.
/// </summary>
public FontWeight FontWeight
{
get;
private set;
}
public FontWeight FontWeight { get; }
/// <summary>
/// Gets the text.
/// </summary>
public string Text
{
get;
private set;
}
public string Text { get; }
/// <summary>
/// Gets platform-specific platform implementation.
/// </summary>
public IFormattedTextImpl PlatformImpl
{
get; }
public IFormattedTextImpl PlatformImpl { get; }
/// <summary>
/// Gets the text alignment.
/// </summary>
public TextAlignment TextAlignment
{
get;
private set;
}
public TextAlignment TextAlignment { get; }
/// <summary>
/// Gets the text wrapping.
/// </summary>
public TextWrapping Wrapping { get; }
/// <summary>
/// Disposes of unmanaged resources associated with the formatted text.

4
src/Avalonia.Controls/TextWrapping.cs → src/Avalonia.SceneGraph/Media/TextWrapping.cs

@ -1,10 +1,10 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
namespace Avalonia.Controls
namespace Avalonia.Media
{
/// <summary>
/// Controls the wrapping mode in a <see cref="TextBlock"/>.
/// Controls the wrapping mode of text.
/// </summary>
public enum TextWrapping
{

4
src/Avalonia.SceneGraph/Platform/IPlatformRenderInterface.cs

@ -20,6 +20,7 @@ namespace Avalonia.Platform
/// <param name="fontStyle">The font style.</param>
/// <param name="textAlignment">The text alignment.</param>
/// <param name="fontWeight">The font weight.</param>
/// <param name="wrapping">The text wrapping mode.</param>
/// <returns>An <see cref="IFormattedTextImpl"/>.</returns>
IFormattedTextImpl CreateFormattedText(
string text,
@ -27,7 +28,8 @@ namespace Avalonia.Platform
double fontSize,
FontStyle fontStyle,
TextAlignment textAlignment,
FontWeight fontWeight);
FontWeight fontWeight,
TextWrapping wrapping);
/// <summary>
/// Creates a stream geometry implementation.

3
src/Avalonia.SceneGraph/Rendering/RendererMixin.cs

@ -62,7 +62,8 @@ namespace Avalonia.Rendering
var txt = new FormattedText("Frame #" + s_frameNum + " FPS: " + s_fps, "Arial", 18,
FontStyle.Normal,
TextAlignment.Left,
FontWeight.Normal))
FontWeight.Normal,
TextWrapping.NoWrap))
{
ctx.FillRectangle(Brushes.White, new Rect(pt, txt.Measure()));
ctx.DrawText(Brushes.Black, pt, txt);

3
src/Gtk/Avalonia.Cairo/CairoPlatform.cs

@ -44,7 +44,8 @@ namespace Avalonia.Cairo
double fontSize,
FontStyle fontStyle,
TextAlignment textAlignment,
Avalonia.Media.FontWeight fontWeight)
Avalonia.Media.FontWeight fontWeight,
TextWrapping wrapping)
{
return new FormattedTextImpl(s_pangoContext, text, fontFamily, fontSize, fontStyle, textAlignment, fontWeight);
}

2
src/Skia/Avalonia.Skia/PlatformRenderInterface.cs

@ -18,7 +18,7 @@ namespace Avalonia.Skia
}
public IFormattedTextImpl CreateFormattedText(string text, string fontFamilyName, double fontSize, FontStyle fontStyle,
TextAlignment textAlignment, FontWeight fontWeight)
TextAlignment textAlignment, FontWeight fontWeight, TextWrapping wrapping)
{
return FormattedTextImpl.Create(text, fontFamilyName, fontSize, fontStyle, textAlignment, fontWeight);
}

5
src/Windows/Avalonia.Direct2D1/Direct2D1Platform.cs

@ -49,9 +49,10 @@ namespace Avalonia.Direct2D1
double fontSize,
FontStyle fontStyle,
TextAlignment textAlignment,
FontWeight fontWeight)
FontWeight fontWeight,
TextWrapping wrapping)
{
return new FormattedTextImpl(text, fontFamily, fontSize, fontStyle, textAlignment, fontWeight);
return new FormattedTextImpl(text, fontFamily, fontSize, fontStyle, textAlignment, fontWeight, wrapping);
}
public IRenderTarget CreateRenderer(IPlatformHandle handle)

6
src/Windows/Avalonia.Direct2D1/Media/FormattedTextImpl.cs

@ -18,7 +18,8 @@ namespace Avalonia.Direct2D1.Media
double fontSize,
FontStyle fontStyle,
TextAlignment textAlignment,
FontWeight fontWeight)
FontWeight fontWeight,
TextWrapping wrapping)
{
var factory = AvaloniaLocator.Current.GetService<DWrite.Factory>();
@ -29,6 +30,9 @@ namespace Avalonia.Direct2D1.Media
(DWrite.FontStyle)fontStyle,
(float)fontSize))
{
format.WordWrapping = wrapping == TextWrapping.Wrap ?
DWrite.WordWrapping.Wrap : DWrite.WordWrapping.NoWrap;
TextLayout = new DWrite.TextLayout(
factory,
text ?? string.Empty,

3
tests/Avalonia.RenderTests/Avalonia.Direct2D1.RenderTests.csproj

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?>
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
@ -73,6 +73,7 @@
<Otherwise />
</Choose>
<ItemGroup>
<Compile Include="Controls\TextBlockTests.cs" />
<Compile Include="Media\ImageBrushTests.cs" />
<Compile Include="Media\VisualBrushTests.cs" />
<Compile Include="Controls\ImageTests.cs" />

47
tests/Avalonia.RenderTests/Controls/TextBlockTests.cs

@ -0,0 +1,47 @@
// Copyright (c) The Avalonia Project. All rights reserved.
// Licensed under the MIT license. See licence.md file in the project root for full license information.
using Avalonia.Controls;
using Avalonia.Layout;
using Avalonia.Media;
using Xunit;
#if AVALONIA_CAIRO
namespace Avalonia.Cairo.RenderTests.Controls
#elif AVALONIA_SKIA
namespace Avalonia.Skia.RenderTests
#else
namespace Avalonia.Direct2D1.RenderTests.Controls
#endif
{
public class TextBlockTests : TestBase
{
public TextBlockTests()
: base(@"Controls\TextBlock")
{
}
[Fact]
public void Wrapping_NoWrap()
{
Decorator target = new Decorator
{
Padding = new Thickness(8),
Width = 200,
Height = 200,
Child = new TextBlock
{
Background = Brushes.Red,
FontSize = 12,
Foreground = Brushes.Black,
Text = "Neque porro quisquam est qui dolorem ipsum quia dolor sit amet, consectetur, adipisci velit",
VerticalAlignment = VerticalAlignment.Top,
TextWrapping = TextWrapping.NoWrap,
}
};
RenderToFile(target);
CompareImages();
}
}
}

5
tests/Avalonia.RenderTests/TestBase.cs

@ -58,6 +58,11 @@ namespace Avalonia.Direct2D1.RenderTests
protected void RenderToFile(Control target, [CallerMemberName] string testName = "")
{
if (!Directory.Exists(OutputPath))
{
Directory.CreateDirectory(OutputPath);
}
string path = Path.Combine(OutputPath, testName + ".out.png");
using (RenderTargetBitmap bitmap = new RenderTargetBitmap(

3
tests/Avalonia.UnitTests/TestServices.cs

@ -143,7 +143,8 @@ namespace Avalonia.UnitTests
It.IsAny<double>(),
It.IsAny<FontStyle>(),
It.IsAny<TextAlignment>(),
It.IsAny<FontWeight>()) == Mock.Of<IFormattedTextImpl>() &&
It.IsAny<FontWeight>(),
It.IsAny<TextWrapping>()) == Mock.Of<IFormattedTextImpl>() &&
x.CreateStreamGeometry() == Mock.Of<IStreamGeometryImpl>(
y => y.Open() == Mock.Of<IStreamGeometryContextImpl>()));
}

BIN
tests/TestFiles/Direct2D1/Controls/TextBlock/Wrapping_NoWrap.expected.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.2 KiB

Loading…
Cancel
Save