Font fixes
Fixed methods that return the system default fonts. Added font tests.
This commit is contained in:
Родитель
66ebe9ceaa
Коммит
310581b5d0
|
@ -49,7 +49,7 @@ namespace Samples
|
|||
var col1 = new Rectangle ();
|
||||
var col2 = new Rectangle ();
|
||||
|
||||
var text = new TextLayout (ctx);
|
||||
var text = new TextLayout ();
|
||||
text.Font = this.Font.WithSize (24);
|
||||
Console.WriteLine (text.Font.Size);
|
||||
|
||||
|
|
|
@ -0,0 +1,222 @@
|
|||
//
|
||||
// FontTests.cs
|
||||
//
|
||||
// Author:
|
||||
// Lluis Sanchez <lluis@xamarin.com>
|
||||
//
|
||||
// Copyright (c) 2013 Xamarin Inc.
|
||||
//
|
||||
// Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
// of this software and associated documentation files (the "Software"), to deal
|
||||
// in the Software without restriction, including without limitation the rights
|
||||
// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
// copies of the Software, and to permit persons to whom the Software is
|
||||
// furnished to do so, subject to the following conditions:
|
||||
//
|
||||
// The above copyright notice and this permission notice shall be included in
|
||||
// all copies or substantial portions of the Software.
|
||||
//
|
||||
// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
using System;
|
||||
|
||||
using NUnit.Framework;
|
||||
using Xwt.Drawing;
|
||||
|
||||
namespace Xwt
|
||||
{
|
||||
[TestFixture]
|
||||
public class FontTests
|
||||
{
|
||||
[Test]
|
||||
public void FromNameEmpty ()
|
||||
{
|
||||
var f = Font.FromName ("");
|
||||
Assert.AreEqual (Font.SystemFont, f);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithFamily ()
|
||||
{
|
||||
var f1 = Font.SystemFont;
|
||||
var f2 = f1.WithFamily ("Courier");
|
||||
Assert.AreEqual ("Courier", f2.Family);
|
||||
Assert.AreEqual (f1.Size, f2.Size);
|
||||
Assert.AreEqual (f1.Stretch, f2.Stretch);
|
||||
Assert.AreEqual (f1.Style, f2.Style);
|
||||
Assert.AreEqual (f1.Weight, f2.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithSize ()
|
||||
{
|
||||
var f1 = Font.SystemFont;
|
||||
var f2 = f1.WithSize (33);
|
||||
Assert.AreEqual (f1.Family, f2.Family);
|
||||
Assert.AreEqual (33d, f2.Size);
|
||||
Assert.AreEqual (f1.Stretch, f2.Stretch);
|
||||
Assert.AreEqual (f1.Style, f2.Style);
|
||||
Assert.AreEqual (f1.Weight, f2.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithStretch ()
|
||||
{
|
||||
var f1 = Font.SystemFont;
|
||||
var f2 = f1.WithStretch (FontStretch.Condensed);
|
||||
Assert.AreEqual (f1.Family, f2.Family);
|
||||
Assert.AreEqual (f1.Size, f2.Size);
|
||||
Assert.AreEqual (FontStretch.Condensed, f2.Stretch);
|
||||
Assert.AreEqual (f1.Style, f2.Style);
|
||||
Assert.AreEqual (f1.Weight, f2.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithStyle ()
|
||||
{
|
||||
var f1 = Font.SystemFont;
|
||||
var f2 = f1.WithStyle (FontStyle.Oblique);
|
||||
Assert.AreEqual (f1.Family, f2.Family);
|
||||
Assert.AreEqual (f1.Size, f2.Size);
|
||||
Assert.AreEqual (f1.Stretch, f2.Stretch);
|
||||
Assert.AreEqual (FontStyle.Oblique, f2.Style);
|
||||
Assert.AreEqual (f1.Weight, f2.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void WithWeight ()
|
||||
{
|
||||
var f1 = Font.SystemFont;
|
||||
var f2 = f1.WithWeight (FontWeight.Bold);
|
||||
Assert.AreEqual (f1.Family, f2.Family);
|
||||
Assert.AreEqual (f1.Size, f2.Size);
|
||||
Assert.AreEqual (f1.Stretch, f2.Stretch);
|
||||
Assert.AreEqual (f1.Style, f2.Style);
|
||||
Assert.AreEqual (FontWeight.Bold, f2.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromNameOnlyFamily ()
|
||||
{
|
||||
var f = Font.FromName ("Arial");
|
||||
Assert.AreEqual ("Arial", f.Family);
|
||||
Assert.AreEqual (Font.SystemFont.Size, f.Size);
|
||||
Assert.AreEqual (FontStretch.Normal, f.Stretch);
|
||||
Assert.AreEqual (FontStyle.Normal, f.Style);
|
||||
Assert.AreEqual (FontWeight.Normal, f.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromNameOnlySize ()
|
||||
{
|
||||
var f = Font.FromName ("33");
|
||||
Assert.AreEqual (Font.SystemFont.Family, f.Family);
|
||||
Assert.AreEqual (33d, f.Size);
|
||||
Assert.AreEqual (FontStretch.Normal, f.Stretch);
|
||||
Assert.AreEqual (FontStyle.Normal, f.Style);
|
||||
Assert.AreEqual (FontWeight.Normal, f.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromNameOnlyFamilyAndSize ()
|
||||
{
|
||||
var f = Font.FromName ("Arial 33");
|
||||
Assert.AreEqual ("Arial", f.Family);
|
||||
Assert.AreEqual (33d, f.Size);
|
||||
Assert.AreEqual (FontStretch.Normal, f.Stretch);
|
||||
Assert.AreEqual (FontStyle.Normal, f.Style);
|
||||
Assert.AreEqual (FontWeight.Normal, f.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromNameOnlyFamilyAndSizeWithFallbackSecondChoice ()
|
||||
{
|
||||
var f = Font.FromName ("Foobar, Arial, dummy, 33");
|
||||
Assert.AreEqual ("Arial", f.Family);
|
||||
Assert.AreEqual (33d, f.Size);
|
||||
Assert.AreEqual (FontStretch.Normal, f.Stretch);
|
||||
Assert.AreEqual (FontStyle.Normal, f.Style);
|
||||
Assert.AreEqual (FontWeight.Normal, f.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromNameOnlyFamilyAndSizeWithFallbackFirstChoice ()
|
||||
{
|
||||
var f = Font.FromName ("Arial, Foobar, dummy 33");
|
||||
Assert.AreEqual ("Arial", f.Family);
|
||||
Assert.AreEqual (33d, f.Size);
|
||||
Assert.AreEqual (FontStretch.Normal, f.Stretch);
|
||||
Assert.AreEqual (FontStyle.Normal, f.Style);
|
||||
Assert.AreEqual (FontWeight.Normal, f.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromNameOnlyFamilyAndSizeWithFallbackNoChoice ()
|
||||
{
|
||||
var f = Font.FromName ("Foobar, dummy 33");
|
||||
Assert.AreEqual (Font.SystemFont.Family, f.Family);
|
||||
Assert.AreEqual (33d, f.Size);
|
||||
Assert.AreEqual (FontStretch.Normal, f.Stretch);
|
||||
Assert.AreEqual (FontStyle.Normal, f.Style);
|
||||
Assert.AreEqual (FontWeight.Normal, f.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromNameWithStyle ()
|
||||
{
|
||||
var f = Font.FromName ("Arial, dummy italic 33");
|
||||
Assert.AreEqual ("Arial", f.Family);
|
||||
Assert.AreEqual (33d, f.Size);
|
||||
Assert.AreEqual (FontStretch.Normal, f.Stretch);
|
||||
Assert.AreEqual (FontStyle.Italic, f.Style);
|
||||
Assert.AreEqual (FontWeight.Normal, f.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromNameWithWeight ()
|
||||
{
|
||||
var f = Font.FromName ("Arial, dummy bold 33");
|
||||
Assert.AreEqual ("Arial", f.Family);
|
||||
Assert.AreEqual (33d, f.Size);
|
||||
Assert.AreEqual (FontStretch.Normal, f.Stretch);
|
||||
Assert.AreEqual (FontStyle.Normal, f.Style);
|
||||
Assert.AreEqual (FontWeight.Bold, f.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromNameWithStretch ()
|
||||
{
|
||||
var f = Font.FromName ("Arial, dummy condensed 33");
|
||||
Assert.AreEqual ("Arial", f.Family);
|
||||
Assert.AreEqual (33d, f.Size);
|
||||
Assert.AreEqual (FontStretch.Condensed, f.Stretch);
|
||||
Assert.AreEqual (FontStyle.Normal, f.Style);
|
||||
Assert.AreEqual (FontWeight.Normal, f.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FromNameWithAllStyles ()
|
||||
{
|
||||
var f = Font.FromName ("Arial, dummy expanded Oblique Light 33");
|
||||
Assert.AreEqual ("Arial", f.Family);
|
||||
Assert.AreEqual (33d, f.Size);
|
||||
Assert.AreEqual (FontStretch.Expanded, f.Stretch);
|
||||
Assert.AreEqual (FontStyle.Oblique, f.Style);
|
||||
Assert.AreEqual (FontWeight.Light, f.Weight);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void FontEquals ()
|
||||
{
|
||||
var f1 = Font.FromName ("Arial expanded Oblique Light 33");
|
||||
var f2 = Font.FromName ("Arial expanded Oblique Light 33");
|
||||
Assert.IsTrue (f1.Equals (f2));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -64,6 +64,7 @@
|
|||
<Compile Include="DrawingTests.cs" />
|
||||
<Compile Include="ReferenceImageVerifierDialog.cs" />
|
||||
<Compile Include="ReferenceImageManager.cs" />
|
||||
<Compile Include="FontTests.cs" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<None Include="Test.csproj" />
|
||||
|
|
|
@ -31,6 +31,7 @@ using Xwt.Drawing;
|
|||
using System.Globalization;
|
||||
using System.Reflection;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Xwt.GtkBackend
|
||||
{
|
||||
|
@ -38,67 +39,18 @@ namespace Xwt.GtkBackend
|
|||
{
|
||||
public override object GetSystemDefaultFont ()
|
||||
{
|
||||
if (Platform.IsMac || Platform.IsWindows) {
|
||||
Xwt.Drawing.Font font = null;
|
||||
GtkEngine.NativeToolkit.Invoke (delegate {
|
||||
font = Xwt.Drawing.Font.SystemFont;
|
||||
});
|
||||
return Create (font.Family, font.Size, FontStyle.Normal, FontWeight.Normal, FontStretch.Normal);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override object GetSystemDefaultMonospaceFont ()
|
||||
{
|
||||
if (Platform.IsMac || Platform.IsWindows) {
|
||||
Xwt.Drawing.Font font = null;
|
||||
GtkEngine.NativeToolkit.Invoke (delegate {
|
||||
font = Xwt.Drawing.Font.SystemMonospaceFont;
|
||||
});
|
||||
return Create (font.Family, font.Size, FontStyle.Normal, FontWeight.Normal, FontStretch.Normal);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override object GetSystemDefaultSansSerifFont ()
|
||||
{
|
||||
if (Platform.IsMac || Platform.IsWindows) {
|
||||
Xwt.Drawing.Font font = null;
|
||||
GtkEngine.NativeToolkit.Invoke (delegate {
|
||||
font = Xwt.Drawing.Font.SystemSansSerifFont;
|
||||
});
|
||||
return Create (font.Family, font.Size, FontStyle.Normal, FontWeight.Normal, FontStretch.Normal);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public override object GetSystemDefaultSerifFont ()
|
||||
{
|
||||
if (Platform.IsMac || Platform.IsWindows) {
|
||||
Xwt.Drawing.Font font = null;
|
||||
GtkEngine.NativeToolkit.Invoke (delegate {
|
||||
font = Xwt.Drawing.Font.SystemSerifFont;
|
||||
});
|
||||
return Create (font.Family, font.Size, FontStyle.Normal, FontWeight.Normal, FontStretch.Normal);
|
||||
}
|
||||
return null;
|
||||
var la = new Gtk.Label ("");
|
||||
return la.Style.FontDescription;
|
||||
}
|
||||
|
||||
public override IEnumerable<string> GetInstalledFonts ()
|
||||
{
|
||||
if (Platform.IsMac || Platform.IsWindows) {
|
||||
IEnumerable<string> fonts = null;
|
||||
GtkEngine.NativeToolkit.Invoke (delegate {
|
||||
fonts = Xwt.Drawing.Font.AvailableFontFamilies;
|
||||
});
|
||||
return fonts;
|
||||
}
|
||||
return new string[0];
|
||||
return Gdk.PangoHelper.ContextGet ().FontMap.Families.Select (f => f.Name);
|
||||
}
|
||||
|
||||
public override object Create (string fontName, double size, FontStyle style, FontWeight weight, FontStretch stretch)
|
||||
{
|
||||
return FontDescription.FromString (fontName + " " + size.ToString (CultureInfo.InvariantCulture));
|
||||
return FontDescription.FromString (fontName + ", " + style + " " + weight + " " + stretch + " " + size.ToString (CultureInfo.InvariantCulture));
|
||||
}
|
||||
|
||||
#region IFontBackendHandler implementation
|
||||
|
|
|
@ -33,31 +33,11 @@ namespace Xwt.GtkBackend
|
|||
{
|
||||
public class GtkEngine: ToolkitEngineBackend
|
||||
{
|
||||
static Toolkit nativeToolkit;
|
||||
|
||||
public override void InitializeApplication ()
|
||||
{
|
||||
Gtk.Application.Init ();
|
||||
}
|
||||
|
||||
public static Toolkit NativeToolkit {
|
||||
get {
|
||||
if (nativeToolkit == null) {
|
||||
if (Platform.IsMac) {
|
||||
if (!Toolkit.TryLoad (ToolkitType.XamMac, out nativeToolkit)) {
|
||||
if (!Toolkit.TryLoad (ToolkitType.Cocoa, out nativeToolkit)) {
|
||||
throw new InvalidOperationException ("Mac backend not found");
|
||||
}
|
||||
}
|
||||
} else if (Platform.IsWindows) {
|
||||
if (!Toolkit.TryLoad (ToolkitType.Wpf, out nativeToolkit))
|
||||
throw new InvalidOperationException ("Windows backend not found");
|
||||
}
|
||||
}
|
||||
return nativeToolkit;
|
||||
}
|
||||
}
|
||||
|
||||
public override void InitializeBackends ()
|
||||
{
|
||||
RegisterBackend<ICustomWidgetBackend, CustomWidgetBackend> ();
|
||||
|
|
|
@ -112,7 +112,16 @@ namespace Xwt.Backends
|
|||
|
||||
public abstract IEnumerable<string> GetInstalledFonts ();
|
||||
|
||||
/// <summary>
|
||||
/// Creates a new font. Returns null if the font family is not available in the system
|
||||
/// </summary>
|
||||
/// <param name="fontName">Font family name</param>
|
||||
/// <param name="size">Size in points</param>
|
||||
/// <param name="style">Style</param>
|
||||
/// <param name="weight">Weight</param>
|
||||
/// <param name="stretch">Stretch</param>
|
||||
public abstract object Create (string fontName, double size, FontStyle style, FontWeight weight, FontStretch stretch);
|
||||
|
||||
public abstract object Copy (object handle);
|
||||
|
||||
public abstract object SetSize (object handle, double size);
|
||||
|
|
|
@ -73,14 +73,12 @@ namespace Xwt.Drawing
|
|||
/// decimal number (size in points). Any one of the options may be absent. If FAMILY-LIST is absent, the default
|
||||
/// font family will be used. If STYLE-OPTIONS is missing, then all style options will be set to the default values.
|
||||
/// If SIZE is missing, the size in the resulting font description will be set to the default font size.
|
||||
/// If the font doesn't exist, it returns the system font.
|
||||
/// </remarks>
|
||||
public static Font FromName (string name)
|
||||
{
|
||||
var toolkit = Toolkit.CurrentEngine;
|
||||
var handler = toolkit.FontBackendHandler;
|
||||
string[] parts = name.Split (new char[] {' '}, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (parts.Length < 2)
|
||||
throw new ArgumentException ("Font family name or size not specified");
|
||||
|
||||
double size = -1;
|
||||
FontStyle style = FontStyle.Normal;
|
||||
|
@ -95,39 +93,50 @@ namespace Xwt.Drawing
|
|||
FontWeight fw;
|
||||
FontStretch fs;
|
||||
double siz;
|
||||
if (Enum.TryParse<FontStyle> (token, out st) && st != FontStyle.Normal)
|
||||
style = st;
|
||||
else if (Enum.TryParse<FontWeight> (token, out fw) && fw != FontWeight.Normal)
|
||||
weight = fw;
|
||||
else if (Enum.TryParse<FontStretch> (token, out fs) && fs != FontStretch.Normal)
|
||||
stretch = fs;
|
||||
else if (double.TryParse (token, out siz) && size != -1)
|
||||
if (double.TryParse (token, out siz)) // Try parsing the number first, since Enum.TryParse can also parse numbers
|
||||
size = siz;
|
||||
else if (Enum.TryParse<FontStyle> (token, true, out st) && st != FontStyle.Normal)
|
||||
style = st;
|
||||
else if (Enum.TryParse<FontWeight> (token, true, out fw) && fw != FontWeight.Normal)
|
||||
weight = fw;
|
||||
else if (Enum.TryParse<FontStretch> (token, true, out fs) && fs != FontStretch.Normal)
|
||||
stretch = fs;
|
||||
else if (token.Length > 0)
|
||||
break;
|
||||
|
||||
lasti = i;
|
||||
if (i <= 0)
|
||||
break;
|
||||
lasti = i;
|
||||
|
||||
i = name.LastIndexOf (' ', i - 1);
|
||||
} while (true);
|
||||
|
||||
string fname = GetSupportedFont (name.Substring (0, lasti));
|
||||
if (fname.Length == 0)
|
||||
fname = SystemFont.Family;
|
||||
string fname = lasti > 0 ? name.Substring (0, lasti) : string.Empty;
|
||||
fname = fname.Length > 0 ? GetSupportedFont (fname) : Font.SystemFont.Family;
|
||||
|
||||
if (size == -1)
|
||||
size = SystemFont.Size;
|
||||
|
||||
return new Font (handler.Create (fname, size, style, weight, stretch), toolkit);
|
||||
var fb = handler.Create (fname, size, style, weight, stretch);
|
||||
if (fb != null)
|
||||
return new Font (fb, toolkit);
|
||||
else
|
||||
return Font.SystemFont;
|
||||
}
|
||||
|
||||
static string GetSupportedFont (string fontNames)
|
||||
{
|
||||
int i = fontNames.IndexOf (',');
|
||||
if (i == -1)
|
||||
return fontNames.Trim ();
|
||||
|
||||
LoadInstalledFonts ();
|
||||
|
||||
int i = fontNames.IndexOf (',');
|
||||
if (i == -1) {
|
||||
var f = fontNames.Trim ();
|
||||
if (installedFonts.Contains (f))
|
||||
return f;
|
||||
else
|
||||
return GetDefaultFont (f);
|
||||
}
|
||||
|
||||
string[] names = fontNames.Split (new char[] {','}, StringSplitOptions.RemoveEmptyEntries);
|
||||
if (names.Length == 0)
|
||||
throw new ArgumentException ("Font family name not provided");
|
||||
|
@ -137,10 +146,16 @@ namespace Xwt.Drawing
|
|||
if (installedFonts.Contains (n))
|
||||
return n;
|
||||
}
|
||||
return names[0].Trim ();
|
||||
return GetDefaultFont (fontNames.Trim (' ',','));
|
||||
}
|
||||
|
||||
static HashSet<string> installedFonts = new HashSet<string> ();
|
||||
static string GetDefaultFont (string unknownFont)
|
||||
{
|
||||
Console.WriteLine ("Font '" + unknownFont + "' not available in the system. Using '" + Font.SystemFont.Family + "' instead");
|
||||
return Font.SystemFont.Family;
|
||||
}
|
||||
|
||||
static HashSet<string> installedFonts;
|
||||
static ReadOnlyCollection<string> installedFontsArray;
|
||||
|
||||
|
||||
|
@ -262,6 +277,20 @@ namespace Xwt.Drawing
|
|||
sb.Append (' ').Append (Size.ToString (CultureInfo.InvariantCulture));
|
||||
return sb.ToString ();
|
||||
}
|
||||
|
||||
public override bool Equals (object obj)
|
||||
{
|
||||
var other = obj as Font;
|
||||
if (other == null)
|
||||
return false;
|
||||
|
||||
return Family == other.Family && Style == other.Style && Weight == other.Weight && Stretch == other.Stretch && Size == other.Size;
|
||||
}
|
||||
|
||||
public override int GetHashCode ()
|
||||
{
|
||||
return ToString().GetHashCode ();
|
||||
}
|
||||
}
|
||||
|
||||
public enum FontStyle
|
||||
|
|
Загрузка…
Ссылка в новой задаче