internal UIImage RenderImage(IFontImageSource imageSource, float scale) { var font = FontManager.GetFont(imageSource.Font); var color = (imageSource.Color ?? Colors.White).ToPlatform(); var glyph = (NSString)imageSource.Glyph; var attString = new NSAttributedString(glyph, font, color); var imagesize = glyph.GetSizeUsingAttributes(attString.GetUIKitAttributes(0, out _)); UIGraphics.BeginImageContextWithOptions(imagesize, false, scale); var ctx = new NSStringDrawingContext(); var boundingRect = attString.GetBoundingRect(imagesize, 0, ctx); attString.DrawString(new CGRect( imagesize.Width / 2 - boundingRect.Size.Width / 2, imagesize.Height / 2 - boundingRect.Size.Height / 2, imagesize.Width, imagesize.Height)); var image = UIGraphics.GetImageFromCurrentImageContext(); UIGraphics.EndImageContext(); return(image.ImageWithRenderingMode(UIImageRenderingMode.AlwaysOriginal)); }
public Task <IImageSourceServiceResult <UIImage>?> GetImageAsync(IFontImageSource imageSource, float scale = 1, CancellationToken cancellationToken = default) { if (imageSource.IsEmpty) { return(FromResult(null)); } try { // TODO: use a cached way var image = RenderImage(imageSource, scale); if (image == null) { throw new InvalidOperationException("Unable to generate font image."); } var result = new ImageSourceServiceResult(image, true, () => image.Dispose()); return(FromResult(result)); } catch (Exception ex) { Logger?.LogWarning(ex, "Unable to generate font image '{Glyph}'.", imageSource.Glyph); throw; } }
public async Task <IImageSourceServiceResult <Drawable>?> GetDrawableAsync(IFontImageSource imageSource, Context context, CancellationToken cancellationToken = default) { if (imageSource.IsEmpty) { return(null); } var glyph = imageSource.Glyph; var size = FontManager.GetFontSize(imageSource.Font); var textSize = TypedValue.ApplyDimension(size.Unit, size.Value, context.Resources?.DisplayMetrics); var typeface = FontManager.GetTypeface(imageSource.Font); var color = (imageSource.Color ?? Graphics.Colors.White).ToPlatform(); try { var result = await Glide .With(context) .Load(new FontImageSourceModel(glyph, textSize, typeface, color)) .SubmitAsync(context, cancellationToken) .ConfigureAwait(false); if (result == null) { throw new InvalidOperationException("Unable to generate font image."); } return(result); } catch (Exception ex) { Logger?.LogWarning(ex, "Unable to generate font image '{Glyph}'.", glyph); throw; } }
public async Task <IImageSourceServiceResult <Image>?> GetImageAsync(IFontImageSource imageSource, Image image, CancellationToken cancellationToken = default) { if (imageSource.IsEmpty) { return(null); } try { //TODO : Fix me correctly later. var isLoadComplated = await image.LoadAsync(string.Empty, cancellationToken); if (!isLoadComplated) { throw new InvalidOperationException("Unable to load image file."); } var result = new ImageSourceServiceResult(image); return(result); } catch (Exception ex) { Logger?.LogWarning(ex, "Unable to generate font image '{Glyph}'.", imageSource.Glyph); throw; } }
string GetFontSource(IFontImageSource imageSource) { if (imageSource == null) { return(string.Empty); } var fontFamily = FontManager.GetFontFamily(imageSource.Font); var fontSource = fontFamily.Source; var allFamilies = fontFamily.Source.Split(new[] { ',' }, StringSplitOptions.RemoveEmptyEntries); if (allFamilies.Length > 1) { // There's really no perfect solution to handle font families with fallbacks (comma-separated) // So if the font family has fallbacks, only one is taken, because CanvasTextFormat // only supports one font family var source = imageSource.Font.Family ?? String.Empty; foreach (var family in allFamilies) { if (family.Contains(source, StringComparison.Ordinal)) { fontSource = family; break; } } } return(fontSource); }
internal CanvasImageSource RenderImageSource(IFontImageSource imageSource, float scale) { // TODO: The DPI not working as the view is not respecting the // value, so just reset to 1 to keep the correct size. scale = 1; var dpi = scale * DeviceDisplay.BaseLogicalDpi; var fontFamily = GetFontSource(imageSource); var fontSize = (float)imageSource.Font.Size; var color = (imageSource.Color ?? Colors.White).ToWindowsColor(); var textFormat = new CanvasTextFormat { FontFamily = fontFamily, FontSize = fontSize, HorizontalAlignment = CanvasHorizontalAlignment.Center, VerticalAlignment = CanvasVerticalAlignment.Center, Options = CanvasDrawTextOptions.Default }; var device = CanvasDevice.GetSharedDevice(); using var layout = new CanvasTextLayout(device, imageSource.Glyph, textFormat, 0, 0); // add a 1px padding all around var canvasWidth = (float)layout.DrawBounds.Width + 2; var canvasHeight = (float)layout.DrawBounds.Height + 2; var canvasImageSource = new CanvasImageSource(device, canvasWidth, canvasHeight, dpi); using (var ds = canvasImageSource.CreateDrawingSession(UI.Colors.Transparent)) { // offset by 1px as we added a 1px padding var x = (layout.DrawBounds.X * -1) + 1; var y = (layout.DrawBounds.Y * -1) + 1; ds.DrawTextLayout(layout, (float)x, (float)y, color); } return(canvasImageSource); }