[Bug] FontImageSourse doesn't work on macOS (#8590) fixes #8469
authorVladislavAntonyuk <33021114+VladislavAntonyuk@users.noreply.github.com>
Mon, 2 Dec 2019 10:38:05 +0000 (12:38 +0200)
committerRui Marinho <me@ruimarinho.net>
Mon, 2 Dec 2019 10:38:05 +0000 (10:38 +0000)
* [Bug] FontImageSourse doesn't work on macOS

* revert VS changes

* ExportImageSourceHandler

* Revert info.plist

Xamarin.Forms.ControlGallery.MacOS/Resources/Fonts/ionicons.ttf [new file with mode: 0644]
Xamarin.Forms.ControlGallery.MacOS/Xamarin.Forms.ControlGallery.MacOS.csproj
Xamarin.Forms.Controls/GalleryPages/FontImageSourceGallery.cs
Xamarin.Forms.Platform.MacOS/ImageSourceHandlers.cs
Xamarin.Forms.Platform.MacOS/Properties/AssemblyInfo.cs

diff --git a/Xamarin.Forms.ControlGallery.MacOS/Resources/Fonts/ionicons.ttf b/Xamarin.Forms.ControlGallery.MacOS/Resources/Fonts/ionicons.ttf
new file mode 100644 (file)
index 0000000..cc67b2f
Binary files /dev/null and b/Xamarin.Forms.ControlGallery.MacOS/Resources/Fonts/ionicons.ttf differ
index cdfefed..e02eb8b 100644 (file)
     <BundleResource Include="Resources\Fonts\Roboto-Regular.ttf">
       <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
     </BundleResource>
+    <BundleResource Include="Resources\Fonts\ionicons.ttf">
+      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
+    </BundleResource>
   </ItemGroup>
   <ItemGroup>
     <InterfaceDefinition Include="Main.storyboard" />
index 9fc9953..98366d9 100644 (file)
@@ -19,6 +19,7 @@ namespace Xamarin.Forms.Controls
                        var fontFamily = "";
                        switch (Device.RuntimePlatform)
                        {
+                               case Device.macOS:
                                case Device.iOS:
                                        fontFamily = "Ionicons";
                                        break;
index f16271e..7aade52 100644 (file)
@@ -1,7 +1,11 @@
-using System.IO;
+using System;
+using System.IO;
 using System.Threading;
 using System.Threading.Tasks;
 using AppKit;
+using CoreGraphics;
+using CoreText;
+using Foundation;
 using Xamarin.Forms.Internals;
 
 namespace Xamarin.Forms.Platform.MacOS
@@ -68,4 +72,41 @@ namespace Xamarin.Forms.Platform.MacOS
                        return image;
                }
        }
+
+       public sealed class FontImageSourceHandler : IImageSourceHandler
+       {
+               readonly Color _defaultColor = Color.White;
+
+               public Task<NSImage> LoadImageAsync(
+                       ImageSource imagesource,
+                       CancellationToken cancelationToken = default(CancellationToken),
+                       float scale = 1f)
+               { 
+                       NSImage image = null;
+                       var fontsource = imagesource as FontImageSource;
+                       if (fontsource != null)
+                       {
+                               var font = NSFont.FromFontName(fontsource.FontFamily ?? string.Empty, (float)fontsource.Size) ??
+                                       NSFont.SystemFontOfSize((float)fontsource.Size);
+                               var iconcolor = fontsource.Color.IsDefault ? _defaultColor : fontsource.Color;
+                               var attString = new NSAttributedString(fontsource.Glyph, font: font, foregroundColor: iconcolor.ToNSColor());
+                               var imagesize = ((NSString)fontsource.Glyph).StringSize(attString.GetAttributes(0, out _));
+
+                               using (var context = new CGBitmapContext(IntPtr.Zero, (nint)imagesize.Width, (nint)imagesize.Height, 8, (nint)imagesize.Width * 4, NSColorSpace.GenericRGBColorSpace.ColorSpace, CGImageAlphaInfo.PremultipliedFirst))
+                               {
+                                       using (var ctline = new CTLine(attString))
+                                       {
+                                               ctline.Draw(context);
+                                       }
+
+                                       using (var cgImage = context.ToImage())
+                                       {
+                                               image = new NSImage(cgImage, imagesize);
+                                       }
+                               }
+                       }
+
+                       return Task.FromResult(image);
+               }
+       }
 }
\ No newline at end of file
index 7ee839f..682ed78 100644 (file)
@@ -6,6 +6,7 @@ using Xamarin.Forms.Platform.MacOS;
 [assembly: ExportImageSourceHandler(typeof(FileImageSource), typeof(FileImageSourceHandler))]
 [assembly: ExportImageSourceHandler(typeof(StreamImageSource), typeof(StreamImagesourceHandler))]
 [assembly: ExportImageSourceHandler(typeof(UriImageSource), typeof(ImageLoaderSourceHandler))]
+[assembly: ExportImageSourceHandler(typeof(FontImageSource), typeof(FontImageSourceHandler))]
 [assembly: ExportRenderer(typeof(Page), typeof(PageRenderer))]
 [assembly: ExportRenderer(typeof(CarouselPage), typeof(CarouselPageRenderer))]
 [assembly: ExportRenderer(typeof(MasterDetailPage), typeof(MasterDetailPageRenderer))]