Example #1
0
        public void TryMeasureCharacterBounds()
        {
            string text = "a b\nc";

            GlyphMetric[] expectedGlyphMetrics = new GlyphMetric[] {
                new GlyphMetric('a', new RectangleF(10, 10, 10, 10), false),
                new GlyphMetric(' ', new RectangleF(40, 10, 30, 10), false),
                new GlyphMetric('b', new RectangleF(70, 10, 10, 10), false),
                new GlyphMetric('\n', new RectangleF(100, 10, 0, 10), true),
                new GlyphMetric('c', new RectangleF(10, 40, 10, 10), false),
            };
            Font font = CreateFont(text);

            int scaleFactor = 72 * font.EmSize; // 72 * emSize means 1 point = 1px
            IReadOnlyList <GlyphMetric> glyphMetrics;

            Assert.True(TextMeasurer.TryMeasureCharacterBounds(text, new RendererOptions(font, 72 * font.EmSize), out glyphMetrics));

            Assert.Equal(text.Length, glyphMetrics.Count);
            int i = 0;

            foreach (GlyphMetric glyphMetric in glyphMetrics)
            {
                Assert.Equal(expectedGlyphMetrics[i++], glyphMetric);
            }
        }
Example #2
0
        public void MeasuringWordWithAccentedCharacterDoesNotThrow(char c)
        {
            FontFamily arial = new FontCollection().Install(TestFonts.OpenSansFile);
            var        font  = new Font(arial, 1f, FontStyle.Regular);

            FontRectangle size = TextMeasurer.Measure($"abc{c}def", new RendererOptions(font, 72));
        }
Example #3
0
        public Task Initialize(MatrixParams mparams)
        {
            this.sizex = mparams.SizeX;
            this.sizey = mparams.SizeY;
            var size = new Size((int)this.sizex, (int)this.sizey);

            this.pbuf = new RGBPixel[sizex, sizey];

            Font font  = null;
            var  fonts = new FontCollection();

            foreach (var f in fontpfade)
            {
                if (System.IO.File.Exists(f))
                {
                    fonts.Install(f);
                }
            }
            try{
                font = SystemFonts.CreateFont(this.FontFamily, this.Size, this.Style);
            }
            catch (Exception d) {}
            FontRectangle sz     = TextMeasurer.Measure(this.Text, new RendererOptions(font));
            Size          _tsize = new Size(Convert.ToInt32(sz.Width + 1), Convert.ToInt32(sz.Height + 1));

            this._image = new Image <Rgba32>(_tsize.Width, _tsize.Height);
            _image.Mutate(ctx =>
            {
                //ctx.Fill(Rgba32.Black);
                ctx.DrawText(this.Text, font, Brushes.Solid(Color.White), Pens.Solid(Color.Beige, 1), PointF.Empty);
            });

            _tpos = _image.Width / 2;
            return(Task.CompletedTask);
        }
Example #4
0
        public void AddWaterMark(Image image, string watermark)
        {
            var collection = new FontCollection();
            var family     = collection.Install("Font/Ganttlets.ttf");
            var font       = family.CreateFont(12, FontStyle.Italic);

            var imgSize = image.Size();

            var size = TextMeasurer.Measure(watermark, new RendererOptions(font));

            var scalingFactor = Math.Min(imgSize.Width / size.Width, imgSize.Height / size.Height);

            var scaledFont = new Font(font, scalingFactor * font.Size);

            var center             = new PointF(imgSize.Width / 2, imgSize.Height / 2);
            var textGraphicOptions = new TextGraphicsOptions()
            {
                TextOptions =
                {
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment   = VerticalAlignment.Center
                }
            };

            image.Mutate(context => context.DrawText(textGraphicOptions, watermark, scaledFont, Color.Aqua, center));
        }
Example #5
0
        public void MeasuringWordWithAccentedCharacterDoesNotThrow(char c)
        {
            FontFamily arial = SystemFonts.Find("Arial");
            Font       font  = new Font(arial, 1f, FontStyle.Regular);

            SizeF size = TextMeasurer.Measure($"abc{c}def", new RendererOptions(font, 72));
        }
Example #6
0
        public static IImageProcessingContext <TPixel> ApplyScalingWaterMarkWordWrap <TPixel>(this IImageProcessingContext <TPixel> processingContext, Font font, string text, TPixel color, float padding)
            where TPixel : struct, IPixel <TPixel>
        {
            return(processingContext.Apply(img => {
                float targetWidth = img.Width - (padding * 2);
                float targetHeight = img.Height - (padding * 2);

                float targetMinHeight = img.Height - (padding * 3);

                var scaledFont = font;
                SizeF s = new SizeF(float.MaxValue, float.MaxValue);

                float scaleFactor = (scaledFont.Size / 2);
                int trapCount = (int)scaledFont.Size * 2;
                if (trapCount < 10)
                {
                    trapCount = 10;
                }

                bool isTooSmall = false;

                while ((s.Height > targetHeight || s.Height < targetMinHeight) && trapCount > 0)
                {
                    if (s.Height > targetHeight)
                    {
                        if (isTooSmall)
                        {
                            scaleFactor = scaleFactor / 2;
                        }

                        scaledFont = new Font(scaledFont, scaledFont.Size - scaleFactor);
                        isTooSmall = false;
                    }

                    if (s.Height < targetMinHeight)
                    {
                        if (!isTooSmall)
                        {
                            scaleFactor = scaleFactor / 2;
                        }
                        scaledFont = new Font(scaledFont, scaledFont.Size + scaleFactor);
                        isTooSmall = true;
                    }
                    trapCount--;

                    s = TextMeasurer.Measure(text, new RendererOptions(scaledFont)
                    {
                        WrappingWidth = targetWidth
                    });
                }

                var center = new PointF(padding, img.Height / 2);
                img.Mutate(i => i.DrawText(text, scaledFont, color, center, new TextGraphicsOptions(true)
                {
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment = VerticalAlignment.Center,
                    WrapTextWidth = targetWidth
                }));
            }));
        }
Example #7
0
        public void TextFailsToRender()
        {
            var text = "2016-12-10";

            // first make sure the text rectangle actually overlaps
            var destArea = new RectangleF(PointF.Empty, this.Actual.Size());
            var textArea = TextMeasurer.MeasureBounds(text, new RendererOptions(Drawing.Arial10, new Point(-10, 3)));

            Assert.IsTrue(destArea.IntersectsWith(textArea.AsRect()));

            // THIS SHOULD IDEALLY NOT THROW
            Assert.ThrowsException <ImageProcessingException>(
                () =>
                this.Actual.Mutate(
                    x => { x.DrawText(text, Drawing.Arial10, Color.White, new PointF(-10, 3)); }));

            // but our custom safe method side steps the problem
            this.Actual.Mutate(x => { x.DrawTextSafe(text, Drawing.Arial10, Color.White, new PointF(-10, 3)); });

            this.Expected = Drawing.NewImage(100, 100, Color.Black);
            this.Expected.Mutate(
                x => x.DrawText("016-12-10", Drawing.Arial10, Color.White, new PointF((float)(-10f + 4.741211f), 3)));

            this.AssertImagesEqual();
        }
        private static Image <T> RenderImage <T>(this FontAtlas fa, T color) where T : struct, IPixel <T>
        {
            // TODO we need the extra pixels here because ImageSharp renders out of bounds and crashes.
            var img = new Image <T>(Configuration.Default, fa.Width + 2, fa.Height);
            var tgo = new TextGraphicsOptions(true);

            tgo.AntialiasSubpixelDepth = 8;

            for (var i = 0; i < fa.MapCount; i++)
            {
                var gm   = fa[i];
                var font = gm.Font;

                foreach (var gd in gm)
                {
                    // TODO lower level control to render single character? This API sucks balls for FA layout + rendering
                    var charStr = char.ConvertFromUtf32(gd.Character);
                    var pos     = (Vector2)gd.Bounds.TopLeft;
                    var ro      = new RendererOptions(font);
                    TextMeasurer.TryMeasureCharacterBounds(charStr.AsSpan(), ro, out var cbs);
                    var cb = cbs[0];
                    img.Mutate(c => c.DrawText(tgo, charStr, font, color, pos - (Vector2)cb.Bounds.Location));
                }
            }

            return(img);
        }
Example #9
0
        static void Main(string[] args)
        {
            using var module = PiTop4Board.Instance;

            var display = module.Display;

            Console.WriteLine("press enter key to render square");
            Console.ReadLine();
            display.Draw((d, cr) =>
            {
                var square = new RectangularPolygon(0, 0, cr.Width / 2, cr.Height / 2);

                d.Fill(Color.White, square);
            });

            Console.WriteLine("press enter key to render text");
            Console.ReadLine();

            var font = SystemFonts.Collection.Find("Roboto").CreateFont(10);

            module.Display.Draw((context, cr) => {
                context.Clear(Color.Black);
                var rect = TextMeasurer.Measure("Diego was here", new RendererOptions(font));
                var x    = (cr.Width - rect.Width) / 2;
                var y    = (cr.Height + (rect.Height)) / 2;
                context.DrawText("Hello\nWorld", font, Color.White, new PointF(0, 0));
            });

            Console.WriteLine("press enter key to exit");
            Console.ReadLine();
        }
Example #10
0
        public (int, RectangleF) GetAdjustedFont(string graphicString, float containerWidth, float containerHeight, int maxFontSize,
                                                 int minFontSize)
        {
            var sizeRect = new RectangleF();

            for (int adjustedSize = maxFontSize; adjustedSize >= minFontSize; adjustedSize--)
            {
                var testFont      = new Font(_dummyFont, adjustedSize);
                var renderOptions = new RendererOptions(testFont)
                {
                    WrappingWidth = containerWidth
                };

                // Test the string with the new size
                sizeRect = TextMeasurer.MeasureBounds(graphicString, renderOptions);
                float volume = sizeRect.Height * sizeRect.Width;

                if (volume < containerWidth * containerHeight)
                {
                    // Good font, return it
                    return(adjustedSize, sizeRect);
                }
            }

            return(minFontSize, sizeRect);
        }
Example #11
0
        private static IEnumerable <string> SplitTextForMaxWidth(float width, Font font, string input)
        {
            var    render      = new RendererOptions(font);
            var    words       = input.Replace("\n", " ").Split(' ');
            string currentLine = null;

            foreach (var word in words)
            {
                if (currentLine == null)
                {
                    currentLine = "";
                }

                if (GetWidth(currentLine + word + " ") > width)
                {
                    yield return(currentLine.Trim());

                    currentLine = word;
                }
                else
                {
                    currentLine += " " + word;
                }
            }

            if (currentLine != null)
            {
                yield return(currentLine);
            }

            float GetWidth(string line)
            {
                return(TextMeasurer.Measure(line, render).Width);
            }
        }
Example #12
0
        public static Stream Render(string text, Image <Rgba32> image)
        {
            var words = text.Split(' ');

            var font = Arial.CreateFont(2, FontStyle.Regular);

            var canvasPoint = new PointF(image.Width * 0.125F, image.Height * 0.70F);
            var canvasSize  = new SizeF(image.Width * 0.75F, image.Height * 0.3F);

            font = GetLargestFont(canvasSize, font, text);

            var render = new RendererOptions(font);

            foreach (var line in SplitTextForMaxWidth(canvasSize.Width, font, text))
            {
                var textSize = TextMeasurer.Measure(line, render);
                var point    = new PointF(canvasPoint.X + (canvasSize.Width - textSize.Width) / 2, canvasPoint.Y);
                image.Mutate(cl => cl.DrawText(line, font, Brushes.Solid(Color.WhiteSmoke), Pens.Solid(Color.Black, 1), point));
                canvasPoint.Y += textSize.Height;
            }

            var str = new MemoryStream();

            image.SaveAsJpeg(str);
            str.Seek(0, SeekOrigin.Begin);
            return(str);
        }
Example #13
0
        public Vector2 GetCursorPosition()
        {
            var mousePos = InputTracker.MousePosition;

            if (IsMouseHoveringOver)
            {
                // Iterate all combinations of letters and get closest

                var xPosList = new List <float>()
                {
                    0
                };
                for (int i = 1; i <= Text.Length; i++)
                {
                    var substr = Text.Substring(0, i);
                    var size   = TextMeasurer.Measure(substr, new RendererOptions(Label.DrawableText.Font));

                    xPosList.Add(size.Width);
                }

                var relativePos = mousePos - (Label.AbsolutePosition + new Vector2(CursorControl.Size.X, 0));
                var minDistance = xPosList.Min(n => Math.Abs(relativePos.X - n));
                var closest     = xPosList.First(n => Math.Abs(relativePos.X - n) == minDistance);
                CursorIndex = xPosList.IndexOf(closest);

                return(new Vector2(closest + Label.Position.X - 1, 3));
            }
            return(Vector2.Zero);
        }
Example #14
0
        // Colors: Red,Blue,Purple,#006666
        private static IImageProcessingContext DrawWatermark(this IImageProcessingContext context, WatermarkSettings settings)
        {
            var imgSize = context.GetCurrentSize();

            // measure the text size
            var size = TextMeasurer.Measure(settings.Text, new RendererOptions(settings.TextFont));

            //find out how much we need to scale the text to fill the space (up or down)
            var scalingFactor = Math.Min(imgSize.Width / size.Width, imgSize.Height / size.Height) / 3;

            //create a new settings.TextFont
            var scaledFont = new Font(settings.TextFont, scalingFactor * settings.TextFont.Size);
            var center     = settings.Position switch
            {
                WatermarkPosition.Top => new PointF(imgSize.Width / 2, (imgSize.Height / 9)),
                WatermarkPosition.TopLeft => new PointF(imgSize.Width / 2, (imgSize.Height / 9)),
                WatermarkPosition.TopRight => new PointF(imgSize.Width / 2, (imgSize.Height / 9)),
                _ => new PointF(imgSize.Width / 2, imgSize.Height - (imgSize.Height / 9)),
            };

            var textGraphicOptions = new TextGraphicsOptions(true)
            {
                HorizontalAlignment = HorizontalAlignment.Center,
                VerticalAlignment   = VerticalAlignment.Center,
            };

            // Apply Banner
            context.DrawBanner(settings)
            .DrawText(textGraphicOptions, settings.Text, scaledFont, settings.TextColor, center);

            return(context);
        }
Example #15
0
        public void TryMeasureCharacterBounds()
        {
            string text = "a b\nc";
            var    expectedGlyphMetrics = new GlyphMetric[] {
                new GlyphMetric('a', new FontRectangle(10, 0, 10, 10), false),
                new GlyphMetric(' ', new FontRectangle(40, 0, 30, 10), false),
                new GlyphMetric('b', new FontRectangle(70, 0, 10, 10), false),
                new GlyphMetric('\n', new FontRectangle(100, 0, 0, 10), true),
                new GlyphMetric('c', new FontRectangle(10, 30, 10, 10), false),
            };
            Font font = CreateFont(text);

            int scaleFactor = 72 * font.EmSize; // 72 * emSize means 1 point = 1px

            Assert.True(TextMeasurer.TryMeasureCharacterBounds(text.AsSpan(), new RendererOptions(font, 72 * font.EmSize), out GlyphMetric[] glyphMetrics));

            Assert.Equal(text.Length, glyphMetrics.Length);
            for (int i = 0; i < glyphMetrics.Length; i++)
            {
                GlyphMetric expected = expectedGlyphMetrics[i];
                GlyphMetric actual   = glyphMetrics[i];
                Assert.Equal(expected.Character, actual.Character);
                Assert.Equal(expected.IsControlCharacter, actual.IsControlCharacter);
                // 4 dp as there is minor offset difference in the float values
                Assert.Equal(expected.Bounds.X, actual.Bounds.X, 4);
                Assert.Equal(expected.Bounds.Y, actual.Bounds.Y, 4);
                Assert.Equal(expected.Bounds.Height, actual.Bounds.Height, 4);
                Assert.Equal(expected.Bounds.Width, actual.Bounds.Width, 4);
            }
        }
        public static void DrawText(this Image image, Font font, string text, bool bottom)
        {
            if (string.IsNullOrWhiteSpace(text))
            {
                return;
            }

            var rect = TextMeasurer.Measure(text, new RendererOptions(font, DPI)
            {
                WrappingWidth = image.Width,
            });

            var position = new PointF(
                0.0f,
                bottom ? image.Height - Margin - rect.Height : Margin);

            image.Mutate(x => x.DrawText(new TextGraphicsOptions
            {
                TextOptions = new TextOptions
                {
                    DpiX                = DPI,
                    DpiY                = DPI,
                    WrapTextWidth       = image.Width,
                    HorizontalAlignment = HorizontalAlignment.Center
                }
            }, text, font, Brushes.Solid(Color.White), Pens.Solid(Color.Black, 2.0f), position));
        }
        /// <summary>
        /// Add a password to the image.
        /// </summary>
        /// <param name="curImg">Image to add password to.</param>
        /// <param name="pass">Password to add to top left corner.</param>
        /// <returns>Image with the password in the top left corner.</returns>
        private (Stream, string) AddPassword(byte[] curImg, string pass)
        {
            // draw lower, it looks better
            pass = pass.TrimTo(10, true).ToLowerInvariant();
            using (var img = Image.Load(curImg, out var format))
            {
                // choose font size based on the image height, so that it's visible
                var font = _fonts.NotoSans.CreateFont(img.Height / 12, FontStyle.Bold);
                img.Mutate(x =>
                {
                    // measure the size of the text to be drawing
                    var size = TextMeasurer.Measure(pass, new RendererOptions(font, new PointF(0, 0)));

                    // fill the background with black, add 5 pixels on each side to make it look better
                    x.FillPolygon(Rgba32.FromHex("00000080"),
                                  new PointF(0, 0),
                                  new PointF(size.Width + 5, 0),
                                  new PointF(size.Width + 5, size.Height + 10),
                                  new PointF(0, size.Height + 10));

                    // draw the password over the background
                    x.DrawText(pass,
                               font,
                               Brushes.Solid(Rgba32.White),
                               new PointF(0, 0));
                });
                // return image as a stream for easy sending
                return(img.ToStream(format), format.FileExtensions.FirstOrDefault() ?? "png");
            }
        }
Example #18
0
        public static IImageProcessingContext <TPixel> ApplyScalingWaterMarkSimple <TPixel>(this IImageProcessingContext <TPixel> processingContext, Font font, string text, TPixel color, float padding)
            where TPixel : struct, IPixel <TPixel>
        {
            return(processingContext.Apply(img =>
            {
                float targetWidth = img.Width - (padding * 2);
                float targetHeight = img.Height - (padding * 2);

                // measure the text size
                SizeF size = TextMeasurer.Measure(text, new RendererOptions(font));

                //find out how much we need to scale the text to fill the space (up or down)
                float scalingFactor = Math.Min(img.Width / size.Width, img.Height / size.Height);

                //create a new font
                Font scaledFont = new Font(font, scalingFactor * font.Size);

                var center = new PointF(img.Width / 2, img.Height / 2);
                var textGraphicOptions = new TextGraphicsOptions(true)
                {
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment = VerticalAlignment.Center
                };
                img.Mutate(i => i.DrawText(textGraphicOptions, text, scaledFont, color, center));
            }));
        }
Example #19
0
        public void DoesntThrowExceptionWhenOverlappingRightEdge_Issue688 <TPixel>(TestImageProvider <TPixel> provider)
            where TPixel : struct, IPixel <TPixel>
        {
            Font  font    = CreateFont("OpenSans-Regular.ttf", 36);
            Color color   = Color.Black;
            float padding = 5;
            var   text    = "A short piece of text";

            using (var img = provider.GetImage())
            {
                float targetWidth  = img.Width - (padding * 2);
                float targetHeight = img.Height - (padding * 2);

                // measure the text size
                SizeF size = TextMeasurer.Measure(text, new RendererOptions(font));

                //find out how much we need to scale the text to fill the space (up or down)
                float scalingFactor = Math.Min(img.Width / size.Width, img.Height / size.Height);

                //create a new font
                Font scaledFont = new Font(font, scalingFactor * font.Size);

                var center             = new PointF(img.Width / 2, img.Height / 2);
                var textGraphicOptions = new TextGraphicsOptions(true)
                {
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment   = VerticalAlignment.Center
                };

                img.Mutate(i => i.DrawText(textGraphicOptions, text, scaledFont, color, center));
            }
        }
        private static IImageProcessingContext ApplyScalingWaterMarkSimple(IImageProcessingContext processingContext,
                                                                           Font font,
                                                                           string text,
                                                                           Color color,
                                                                           float padding)
        {
            Size imgSize = processingContext.GetCurrentSize();

            float targetWidth  = imgSize.Width - (padding * 2);
            float targetHeight = imgSize.Height - (padding * 2);

            // measure the text size
            FontRectangle size = TextMeasurer.Measure(text, new RendererOptions(font));

            //find out how much we need to scale the text to fill the space (up or down)
            float scalingFactor = Math.Min(imgSize.Width / size.Width, imgSize.Height / size.Height);

            //create a new font
            Font scaledFont = new Font(font, scalingFactor * font.Size);

            var center             = new PointF(imgSize.Width / 2, imgSize.Height / 2);
            var textGraphicOptions = new TextGraphicsOptions()
            {
                TextOptions =
                {
                    HorizontalAlignment = HorizontalAlignment.Center,
                    VerticalAlignment   = VerticalAlignment.Center
                }
            };

            return(processingContext.DrawText(textGraphicOptions, text, scaledFont, color, center));
        }
        private static void DrawStats(int rank, int level, int ep, Image <Rgba32> output, Vector2 posRank, Vector2 posLevel, Vector2 posEP, Rgba32 color)
        {
            // measure each string and split the margin between them??
            var font = new Font(_titleFont, 42, FontStyle.Bold);

            var rankText  = $"Rank: {rank}";
            var levelText = $"Level: {level}";
            var epText    = $"EP: {ep}";

            //var fontSpan = new FontSpan(font, 72); //imagesharp renders at 72

            var rankSize = TextMeasurer.Measure(rankText, font, 72);           // find the width of the rank text
            var epSize   = TextMeasurer.Measure(epText, font, 72);             // find the width of the EP text

            var left  = posRank.X + rankSize.Width;                            // find the point the rankText stops
            var right = posEP.X - epSize.Width;                                // find the point the epText starts

            var posLevel2 = new Vector2(left + (right - left) / 2, posRank.Y); // find the point halfway between the 2 other bits of text

            output.DrawText(rankText, font, color, posRank, new ImageSharp.Drawing.TextGraphicsOptions
            {
                VerticalAlignment   = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Left
            });
            output.DrawText(levelText, font, color, posLevel2, new ImageSharp.Drawing.TextGraphicsOptions
            {
                VerticalAlignment   = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Center
            });
            output.DrawText(epText, font, color, posEP, new ImageSharp.Drawing.TextGraphicsOptions
            {
                VerticalAlignment   = VerticalAlignment.Center,
                HorizontalAlignment = HorizontalAlignment.Right
            });
        }
Example #22
0
        public static Font ScaleFont(Font font, string text, float targetWidth, float targetHeight)
        {
            var maxFontSize = font.Size;
            var minFontSize = 0f;

            while (maxFontSize - minFontSize > 0.1f)
            {
                var actual = TextMeasurer.MeasureBounds(text, new RendererOptions(font)
                {
                    WrappingWidth = targetWidth
                });

                if (actual.Height > targetHeight || actual.Width > targetWidth)
                {
                    maxFontSize = font.Size;
                }
                else
                {
                    minFontSize = font.Size;
                }

                font = new Font(font, (maxFontSize + minFontSize) / 2);
            }

            return(new Font(font, minFontSize));
        }
Example #23
0
        public OpenXmlSize MeasureText(IOpenXmlTextStyle defaultTextStyle, IOpenXmlTheme theme, OpenXmlUnit?width)
        {
            // TODO: subtract border
            // TODO: measure each pararaph individually

            int level = 1;
            IOpenXmlParagraphTextStyle defaultParagraphTextStyle = defaultTextStyle.GetParagraphTextStyle(level);

            string        text     = this.GetText();
            string        typeface = theme.ResolveFontTypeface(this.GetFont() ?? defaultParagraphTextStyle.LatinTypeface);
            double        fontSize = this.GetFontSize() ?? defaultParagraphTextStyle.Size ?? 9.0;
            double        kerning  = this.GetKerning() ?? defaultParagraphTextStyle.Kerning ?? 0.0;
            OpenXmlMargin margin   = this.GetTextMargin();

            Font font = SystemFonts.Find(typeface).CreateFont((float)fontSize);

            RendererOptions options = new RendererOptions(font, 72)
            {
                WrappingWidth = width.HasValue ? (float)(width.Value - margin.Left - margin.Right).AsPoints() : -1.0f,
                ApplyKerning  = kerning != 0.0,
                LineSpacing   = 1 / 1.2f
            };

            FontRectangle rect   = TextMeasurer.Measure(text, options);
            OpenXmlSize   result = new OpenXmlSize(
                width.HasValue ? width.Value : (OpenXmlUnit.Points(rect.Width) + margin.Left + margin.Right),
                OpenXmlUnit.Points(rect.Height * 1.2) + margin.Top + margin.Bottom
                );

            return(result);
        }
        private string GetBase64StringOfImageWithText(string base64Image, string text)
        {
            string str = "";

            var bytes = Convert.FromBase64String(base64Image);

            // Creates a new image with all the pixels set as transparent.
            using (var image = Image.Load(bytes))
            {
                image.Mutate(context =>
                {
                    var textGraphicsOptions = new TextGraphicsOptions(true)
                    {
                        HorizontalAlignment = HorizontalAlignment.Center,
                        VerticalAlignment   = VerticalAlignment.Center
                    };

                    //Pick any font size, since it will be replaced later
                    var initialFont   = SystemFonts.CreateFont("Arial", 10);
                    var size          = TextMeasurer.Measure(text, new RendererOptions(initialFont));
                    var scalingFactor = Math.Min(image.Width / 2 / size.Width, image.Height / 2 / size.Height);

                    var font = new Font(initialFont, scalingFactor * initialFont.Size, FontStyle.Bold);

                    var textColor = GetContrastColorBW(image);

                    var center = new PointF(image.Width / 2, image.Height / 2);
                    context.DrawText(textGraphicsOptions, text, font, textColor, center);
                });

                str = image.ToBase64String <Rgba32>(PngFormat.Instance);
            }

            return(str);
        }
Example #25
0
        public static void RenderTextProcessor(
            FontFamily fontFamily,
            string text,
            float pointSize = 12,
            IEnumerable <FontFamily> fallbackFonts = null)
        {
            Font        font        = new(fontFamily, pointSize);
            TextOptions textOptions = new(font)
            {
                Dpi = 96,
            };

            if (fallbackFonts != null)
            {
                textOptions.FallbackFontFamilies = fallbackFonts.ToArray();
            }

            FontRectangle textSize = TextMeasurer.Measure(text, textOptions);

            textOptions.Origin = new PointF(5, 5);

            using var img = new Image <Rgba32>((int)Math.Ceiling(textSize.Width) + 20, (int)Math.Ceiling(textSize.Height) + 20);
            img.Mutate(x => x.Fill(Color.White).ApplyProcessor(new DrawTextProcessor(x.GetDrawingOptions(), textOptions, text, new SolidBrush(Color.Black), null)));

            string fullPath = CreatePath(font.Name, text + ".caching.png");

            Directory.CreateDirectory(IOPath.GetDirectoryName(fullPath));
            img.Save(fullPath);
        }
Example #26
0
        public void TextFailsToRender()
        {
            var text = "2016-12-10";

            // first make sure the text rectangle actually overlaps
            var destArea = new RectangleF(PointF.Empty, this.ActualImage.Size());
            var textArea = TextMeasurer.MeasureBounds(text, new RendererOptions(Drawing.Roboto10, new Point(-10, 3)));

            Assert.IsTrue(destArea.IntersectsWith(textArea.AsRect()));

            // THIS SHOULD IDEALLY NOT THROW
            Assert.ThrowsException <ImageProcessingException>(
                () =>
                this.ActualImage.Mutate(
                    x => { x.DrawText(text, Drawing.Roboto10, Color.White, new PointF(-10, 3)); }));

            // but our custom safe method side steps the problem
            this.ActualImage.Mutate(x => { x.DrawTextSafe(text, Drawing.Roboto10, Color.White, new PointF(-10, 3)); });

            this.ExpectedImage = Drawing.NewImage(100, 100, Color.Black);
            this.ExpectedImage.Mutate(
                x => x.DrawText("016-12-10", Drawing.Roboto10, Color.White, new PointF(-3.8232422f, 3)));

            // if we're on a system where Arial isn't installed, we fall back to roboto font,
            // thus we allow a slight tolerance on the image
            var tolerance = SystemFonts.TryFind(Drawing.Arial, out _) ? 0.0 : 1.5E-06;

            this.AssertImagesEqual(tolerance);
        }
        public static void DrawTextAnySize(this IImageProcessingContext context, TextGraphicsOptions op, string?text, FontFamily font, Color color, Rectangle bounds)
        {
            if (string.IsNullOrEmpty(text))
            {
                return;
            }

            int  fontSize    = 64;
            bool fits        = false;
            Font currentFont = font.CreateFont(fontSize);

            while (!fits)
            {
                currentFont = font.CreateFont(fontSize);
                SizeF size = TextMeasurer.Measure(text, new RendererOptions(currentFont));
                fits = size.Height <= bounds.Height && size.Width <= bounds.Width;

                if (!fits)
                {
                    fontSize -= 2;
                }

                if (fontSize <= 2)
                {
                    return;
                }
            }

            context.DrawText(op, text, currentFont, color, new Point(bounds.X, bounds.Y));
        }
        public static void DrawText(this IImageProcessingContext context, TextGraphicsOptions op, string?text, Font font, Color color, Rectangle bounds)
        {
            if (string.IsNullOrEmpty(text))
            {
                return;
            }

            op.WrapTextWidth = bounds.Width;

            RendererOptions rOp = new RendererOptions(font);

            rOp.WrappingWidth = bounds.Width;

            bool fits = false;

            while (!fits)
            {
                SizeF size = TextMeasurer.Measure(text, rOp);
                fits = size.Height <= bounds.Height && size.Width <= bounds.Width;

                if (!fits)
                {
                    text = text.Truncate(text.Length - 5);
                }
            }

            context.DrawText(op, text, font, color, new Point(bounds.X, bounds.Y));
        }
        static void Main(string[] args)
        {
            var squareSize      = 512;
            var backgroundColor = Rgba32.Salmon;
            var font            = SystemFonts.CreateFont("Arial", 300);
            var text            = "KS";

            var textSize = TextMeasurer.Measure(text, new RendererOptions(font, 72));

            Console.WriteLine($"Measured size: {textSize.Width}, {textSize.Height}, Text: {text}");

            using (var img = new Image <Rgba32>(squareSize, squareSize)) {
                var textGraphicsOptions = new TextGraphicsOptions(true);
                var textPosition        = new PointF(squareSize / 2f - textSize.Width / 2, squareSize / 2f - textSize.Height / 2f);
                img.Mutate(ctx => ctx
                           .Fill(backgroundColor)
                           .DrawText(text, font, Rgba32.White, textPosition));

                byte[] buffer;
                using (var ms = new MemoryStream()) {
                    img.SaveAsPng(ms);
                    ms.Seek(0, SeekOrigin.Begin);
                    buffer = ms.ToArray();
                }

                var base64Image = Convert.ToBase64String(buffer);
                Console.WriteLine("\x1b]1337;File=inline=1;width=100px;height=100px:" + base64Image + "\a\n");

                File.WriteAllBytes("result.png", buffer);
            }
        }
Example #30
0
        public void VerticalAlignmentTests(
            VerticalAlignment vertical,
            HorizontalAlignment horizental,
            float top, float left)
        {
            string text = "hello world\nhello";
            Font   font = CreateFont(text);

            int scaleFactor = 72 * font.EmSize; // 72 * emSize means 1 point = 1px
            var span        = new RendererOptions(font, scaleFactor)
            {
                HorizontalAlignment = horizental,
                VerticalAlignment   = vertical
            };

            IReadOnlyList <GlyphLayout> glyphsToRender = new TextLayout().GenerateLayout(text.AsSpan(), span);
            IFontInstance fontInst   = span.Font.Instance;
            float         lineHeight = (fontInst.LineHeight * span.Font.Size) / (fontInst.EmSize * 72);

            lineHeight *= scaleFactor;
            FontRectangle bound = TextMeasurer.GetBounds(glyphsToRender, new Vector2(span.DpiX, span.DpiY));

            Assert.Equal(310, bound.Width, 3);
            Assert.Equal(40, bound.Height, 3);
            Assert.Equal(left, bound.Left, 3);
            Assert.Equal(top, bound.Top, 3);
        }
Example #31
0
    public static TextBlock createTextBlock(string text, Font font, Paint paint, float maxWidth, int maxLines, TextMeasurer measurer)
    {
      TextBlock textBlock = new TextBlock();
      BreakIterator lineInstance = BreakIterator.getLineInstance();
      lineInstance.setText(text);
      int num1 = 0;
      int num2 = 0;
      int num3 = String.instancehelper_length(text);
label_1:
      while (num1 < num3 && num2 < maxLines)
      {
        int num4 = TextUtilities.nextLineBreak(text, num1, maxWidth, lineInstance, measurer);
        if (num4 == -1)
        {
          textBlock.addLine(String.instancehelper_substring(text, num1), font, paint);
          return textBlock;
        }
        else
        {
          textBlock.addLine(String.instancehelper_substring(text, num1, num4), font, paint);
          ++num2;
          num1 = num4;
          while (true)
          {
            if (num1 < String.instancehelper_length(text) && (int) String.instancehelper_charAt(text, num1) == 10)
              ++num1;
            else
              goto label_1;
          }
        }
      }
      if (num1 < num3)
      {
        TextLine lastLine = textBlock.getLastLine();
        TextFragment lastTextFragment = lastLine.getLastTextFragment();
        string text1 = lastTextFragment.getText();
        string text2 = "...";
        if (String.instancehelper_length(text1) > 3)
          text2 = new StringBuffer().append(String.instancehelper_substring(text1, 0, String.instancehelper_length(text1) - 3)).append("...").toString();
        lastLine.removeFragment(lastTextFragment);
        TextFragment.__\u003Cclinit\u003E();
        TextFragment fragment = new TextFragment(text2, lastTextFragment.getFont(), lastTextFragment.getPaint());
        lastLine.addFragment(fragment);
      }
      return textBlock;
    }
Example #32
0
 public static TextBlock createTextBlock(string text, Font font, Paint paint, float maxWidth, TextMeasurer measurer)
 {
   return TextUtilities.createTextBlock(text, font, paint, maxWidth, int.MaxValue, measurer);
 }