Fix7320 font image source don't work on wpf (#7625) fixes #7320
authorYuriy Holembyovskyy <yholembyovskyy@gmail.com>
Fri, 27 Sep 2019 11:33:38 +0000 (14:33 +0300)
committerRui Marinho <me@ruimarinho.net>
Fri, 27 Sep 2019 11:33:38 +0000 (12:33 +0100)
* Added FontImageSourceHandler for WPF

* Spaces cleanup

* Replaced custom CreateBrush() method with built-in ToBrush() extension method

* Droped private.
Inverted if statement

* Added missing font.
Added Device case for WPF

* Fixed color conversion

Xamarin.Forms.ControlGallery.WPF/Assets/ionicons.ttf [new file with mode: 0644]
Xamarin.Forms.ControlGallery.WPF/Xamarin.Forms.ControlGallery.WPF.csproj
Xamarin.Forms.Controls/GalleryPages/FontImageSourceGallery.cs
Xamarin.Forms.Platform.WPF/Properties/AssemblyInfo.cs
Xamarin.Forms.Platform.WPF/Renderers/ImageRenderer.cs

diff --git a/Xamarin.Forms.ControlGallery.WPF/Assets/ionicons.ttf b/Xamarin.Forms.ControlGallery.WPF/Assets/ionicons.ttf
new file mode 100644 (file)
index 0000000..cc67b2f
Binary files /dev/null and b/Xamarin.Forms.ControlGallery.WPF/Assets/ionicons.ttf differ
index 81fa280..0110624 100644 (file)
     </EmbeddedResource>
     <Resource Include="Assets\fontawesome-webfont.ttf" />
     <Resource Include="Assets\pickax.ttf" />
+    <Resource Include="Assets\ionicons.ttf" />
     <None Include="Properties\Settings.settings">
       <Generator>SettingsSingleFileGenerator</Generator>
       <LastGenOutput>Settings.Designer.cs</LastGenOutput>
index bbf0734..9fc9953 100644 (file)
@@ -25,6 +25,9 @@ namespace Xamarin.Forms.Controls
                                case Device.UWP:
                                        fontFamily = "Assets/Fonts/ionicons.ttf#ionicons";
                                        break;
+                               case Device.WPF:
+                                       fontFamily = "Assets/ionicons.ttf#ionicons";
+                                       break;
                                case Device.Android:
                                default:
                                        fontFamily = "fonts/ionicons.ttf#";
index b852937..96e60ba 100644 (file)
@@ -43,6 +43,7 @@ using Xamarin.Forms.Platform.WPF;
 [assembly: ExportImageSourceHandler(typeof(FileImageSource), typeof(FileImageSourceHandler))]
 [assembly: ExportImageSourceHandler(typeof(StreamImageSource), typeof(StreamImageSourceHandler))]
 [assembly: ExportImageSourceHandler(typeof(UriImageSource), typeof(UriImageSourceHandler))]
+[assembly: ExportImageSourceHandler(typeof(FontImageSource), typeof(FontImageSourceHandler))]
 
 
 // Form and subclasses
index 519dfec..0326c3a 100644 (file)
@@ -144,7 +144,7 @@ namespace Xamarin.Forms.Platform.WPF
        }
 
        public sealed class UriImageSourceHandler : IImageSourceHandler
-       {
+       {               
                public Task<System.Windows.Media.ImageSource> LoadImageAsync(ImageSource imagesoure, CancellationToken cancelationToken = new CancellationToken())
                {
                        BitmapImage bitmapimage = null;
@@ -159,4 +159,62 @@ namespace Xamarin.Forms.Platform.WPF
                        return Task.FromResult<System.Windows.Media.ImageSource>(bitmapimage);
                }
        }
+
+       public sealed class FontImageSourceHandler : IImageSourceHandler
+       {
+               public Task<System.Windows.Media.ImageSource> LoadImageAsync(ImageSource imagesource, CancellationToken cancelationToken = default)
+               {                       
+                       var fontsource = imagesource as FontImageSource;
+                       var image = CreateGlyph(
+                                       fontsource.Glyph,
+                                       new FontFamily(new Uri("pack://application:,,,"), fontsource.FontFamily),
+                                       FontStyles.Normal,
+                                       FontWeights.Normal,
+                                       FontStretches.Normal,
+                                       fontsource.Size,
+                                       (fontsource.Color != Color.Default ? fontsource.Color : Color.White).ToBrush());
+                       return Task.FromResult(image);
+               }               
+
+               static System.Windows.Media.ImageSource CreateGlyph(
+                       string text,
+                       FontFamily fontFamily,
+                       FontStyle fontStyle,
+                       FontWeight fontWeight,
+                       FontStretch fontStretch,
+                       double fontSize,
+                       Brush foreBrush)
+        {
+            if (fontFamily == null || string.IsNullOrEmpty(text))
+            {
+                return null;
+            }
+            var typeface = new Typeface(fontFamily, fontStyle, fontWeight, fontStretch);
+            if (!typeface.TryGetGlyphTypeface(out GlyphTypeface glyphTypeface))
+            {
+                //if it does not work 
+                return null;
+            }
+
+            var glyphIndexes = new ushort[text.Length];
+            var advanceWidths = new double[text.Length];
+            for (int n = 0; n < text.Length; n++)
+            {
+                var glyphIndex = glyphTypeface.CharacterToGlyphMap[text[n]];
+                glyphIndexes[n] = glyphIndex;
+                var width = glyphTypeface.AdvanceWidths[glyphIndex] * 1.0;
+                advanceWidths[n] = width;
+            }
+
+            var gr = new GlyphRun(glyphTypeface,
+                0, false,
+                fontSize,
+                glyphIndexes,
+                new System.Windows.Point(0, 0),
+                advanceWidths,
+                null, null, null, null, null, null);
+            var glyphRunDrawing = new GlyphRunDrawing(foreBrush, gr);
+            return new DrawingImage(glyphRunDrawing);
+        }
+    }
 }
\ No newline at end of file