Example #1
0
        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));
        }
Example #2
0
        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);
        }