/
ImageSourceHandlers.cs
112 lines (101 loc) · 3.46 KB
/
ImageSourceHandlers.cs
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
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
{
public interface IImageSourceHandler : IRegisterable
{
Task<NSImage> LoadImageAsync(ImageSource imagesource, CancellationToken cancelationToken = default(CancellationToken),
float scale = 1);
}
public sealed class FileImageSourceHandler : IImageSourceHandler
{
public Task<NSImage> LoadImageAsync(ImageSource imagesource,
CancellationToken cancelationToken = default(CancellationToken), float scale = 1f)
{
NSImage image = null;
var filesource = imagesource as FileImageSource;
var file = filesource?.File;
if (!string.IsNullOrEmpty(file))
image = File.Exists(file) ? new NSImage(file) : NSImage.ImageNamed(file);
if (image == null)
{
Log.Warning(nameof(FileImageSourceHandler), "Could not find image: {0}", imagesource);
}
return Task.FromResult(image);
}
}
public sealed class StreamImagesourceHandler : IImageSourceHandler
{
public async Task<NSImage> LoadImageAsync(ImageSource imagesource,
CancellationToken cancelationToken = default(CancellationToken), float scale = 1f)
{
NSImage image = null;
var streamsource = imagesource as StreamImageSource;
if (streamsource?.Stream == null) return null;
using (
var streamImage = await ((IStreamImageSource)streamsource).GetStreamAsync(cancelationToken).ConfigureAwait(false))
{
if (streamImage != null)
image = NSImage.FromStream(streamImage);
}
return image;
}
}
public sealed class ImageLoaderSourceHandler : IImageSourceHandler
{
public async Task<NSImage> LoadImageAsync(ImageSource imagesource,
CancellationToken cancelationToken = default(CancellationToken), float scale = 1f)
{
NSImage image = null;
var imageLoader = imagesource as UriImageSource;
if (imageLoader != null && imageLoader.Uri != null)
{
using (var streamImage = await imageLoader.GetStreamAsync(cancelationToken).ConfigureAwait(false))
{
if (streamImage != null)
image = NSImage.FromStream(streamImage);
}
}
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);
}
}
}