From 378ecc2a1a4ab95a7a9be17c9d907338894307da Mon Sep 17 00:00:00 2001 From: Roy Date: Tue, 19 Jul 2016 01:38:05 +0200 Subject: [PATCH] Android Custom Font support (#236) * Implemented basic Support for Android Custom fonts * Fixed Tabs * Removed Private * Changed behaviour to use UWP FontFamily style names * Fixed Bug --- .../Renderers/FontExtensions.cs | 85 +++++++++++++------ 1 file changed, 58 insertions(+), 27 deletions(-) diff --git a/Xamarin.Forms.Platform.Android/Renderers/FontExtensions.cs b/Xamarin.Forms.Platform.Android/Renderers/FontExtensions.cs index da458642c..d7394a10c 100644 --- a/Xamarin.Forms.Platform.Android/Renderers/FontExtensions.cs +++ b/Xamarin.Forms.Platform.Android/Renderers/FontExtensions.cs @@ -1,6 +1,8 @@ using System; using System.Collections.Generic; +using System.Text.RegularExpressions; using Android.Graphics; +using AApplication = Android.App.Application; namespace Xamarin.Forms.Platform.Android { @@ -8,6 +10,8 @@ namespace Xamarin.Forms.Platform.Android { static readonly Dictionary, Typeface> Typefaces = new Dictionary, Typeface>(); + static readonly Regex LoadFromAssets = new Regex(@"\w+\.((ttf)|(otf))\#\w*"); + static Typeface s_defaultTypeface; public static float ToScaledPixel(this Font self) @@ -21,11 +25,14 @@ namespace Xamarin.Forms.Platform.Android { case NamedSize.Micro: return 10; + case NamedSize.Small: return 12; + case NamedSize.Default: case NamedSize.Medium: return 14; + case NamedSize.Large: return 18; } @@ -44,21 +51,21 @@ namespace Xamarin.Forms.Platform.Android if (Typefaces.TryGetValue(key, out result)) return result; - var style = TypefaceStyle.Normal; - if ((self.FontAttributes & (FontAttributes.Bold | FontAttributes.Italic)) == (FontAttributes.Bold | FontAttributes.Italic)) - style = TypefaceStyle.BoldItalic; - else if ((self.FontAttributes & FontAttributes.Bold) != 0) - style = TypefaceStyle.Bold; - else if ((self.FontAttributes & FontAttributes.Italic) != 0) - style = TypefaceStyle.Italic; - - if (self.FontFamily != null) - result = Typeface.Create(self.FontFamily, style); - else + if (self.FontFamily == null) + { + var style = ToTypefaceStyle(self.FontAttributes); result = Typeface.Create(Typeface.Default, style); - - Typefaces[key] = result; - return result; + } + else if (LoadFromAssets.IsMatch(self.FontFamily)) + { + result = Typeface.CreateFromAsset(AApplication.Context.Assets, FontNameToFontFile(self.FontFamily)); + } + else + { + var style = ToTypefaceStyle(self.FontAttributes); + result = Typeface.Create(self.FontFamily, style); + } + return (Typefaces[key] = result); } internal static bool IsDefault(this IFontElement self) @@ -68,26 +75,50 @@ namespace Xamarin.Forms.Platform.Android internal static Typeface ToTypeface(this IFontElement self) { + if (self.IsDefault()) + return s_defaultTypeface ?? (s_defaultTypeface = Typeface.Default); + var key = new Tuple(self.FontFamily, self.FontAttributes); Typeface result; if (Typefaces.TryGetValue(key, out result)) return result; - var style = TypefaceStyle.Normal; - if ((self.FontAttributes & (FontAttributes.Bold | FontAttributes.Italic)) == (FontAttributes.Bold | FontAttributes.Italic)) - style = TypefaceStyle.BoldItalic; - else if ((self.FontAttributes & FontAttributes.Bold) != 0) - style = TypefaceStyle.Bold; - else if ((self.FontAttributes & FontAttributes.Italic) != 0) - style = TypefaceStyle.Italic; - - if (self.FontFamily != null) - result = Typeface.Create(self.FontFamily, style); - else + if (self.FontFamily == null) + { + var style = ToTypefaceStyle(self.FontAttributes); result = Typeface.Create(Typeface.Default, style); + } + else if (LoadFromAssets.IsMatch(self.FontFamily)) + { + result = Typeface.CreateFromAsset(AApplication.Context.Assets, FontNameToFontFile(self.FontFamily)); + } + else + { + var style = ToTypefaceStyle(self.FontAttributes); + result = Typeface.Create(self.FontFamily, style); + } + return (Typefaces[key] = result); + } - Typefaces[key] = result; - return result; + public static TypefaceStyle ToTypefaceStyle(FontAttributes attrs) + { + var style = TypefaceStyle.Normal; + if ((attrs & (FontAttributes.Bold | FontAttributes.Italic)) == (FontAttributes.Bold | FontAttributes.Italic)) + style = TypefaceStyle.BoldItalic; + else if ((attrs & FontAttributes.Bold) != 0) + style = TypefaceStyle.Bold; + else if ((attrs & FontAttributes.Italic) != 0) + style = TypefaceStyle.Italic; + return style; + } + + static string FontNameToFontFile(string fontFamily) + { + int hashtagIndex = fontFamily.IndexOf('#'); + if (hashtagIndex >= 0) + return fontFamily.Substring(0, hashtagIndex); + + throw new InvalidOperationException($"Can't parse the {nameof(fontFamily)} {fontFamily}"); } } } \ No newline at end of file