Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Text gets chopped when rotated >60 degrees #175

Closed
4 tasks done
kutukvpavel opened this issue Nov 7, 2021 · 6 comments
Closed
4 tasks done

Text gets chopped when rotated >60 degrees #175

kutukvpavel opened this issue Nov 7, 2021 · 6 comments
Labels
blocking bug Something isn't working
Milestone

Comments

@kutukvpavel
Copy link

kutukvpavel commented Nov 7, 2021

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of ImageSharp.Drawing
  • I have verified if the problem exist in both DEBUG and RELEASE mode
  • I have searched open and closed issues to ensure it has not already been reported

Description

I'm trying to fill some rectangles and place tags (text) into them so that the tags are centered and rotated to match orientation of each rectangle. This means that I'm using DrawText either with a -90° rotation transform or without one. In case of the former, each character of the output text gets its bottom part cut at a consistent height that seems to depend on character index.

Take a look at 3 vertically oriented rectangles, two brown and one blue.
Example

I've done some testing and observed that the issue occures for angles above ~60°. Angle sign does not matter. For example, this happens when I set the angle to +100° (set of rectangles is a random solution for an optimization problem, disregard the position changes).
Example at 100deg

Steps to Reproduce

First, I generate an image to draw on (it's padded to allow some rectangles that cross the expected boundary).

public static float ImageExtraSpaceMultiplier { get; set; } = 1.2f;

public static Image<Rgba32> CreateImage(Rectangle bounds, out float xOffset, out float yOffset)
{
            Image<Rgba32> image = new Image<Rgba32>(
                (int)Math.Ceiling(bounds.Width * ImageExtraSpaceMultiplier),
                (int)Math.Ceiling(bounds.Height * ImageExtraSpaceMultiplier));
            float _xOffset = bounds.Width * (ImageExtraSpaceMultiplier - 1) / 2;
            float _yOffset = bounds.Height * (ImageExtraSpaceMultiplier - 1) / 2;

            image.Mutate(x => x.BackgroundColor(Color.Black));
            image.Mutate(x => x.Draw(Color.White, 2.0f, new RectangleF(
                bounds.X + _xOffset,
                bounds.Y + _yOffset,
                bounds.Width, bounds.Height)));

            xOffset = _xOffset;
            yOffset = _yOffset;
            return image;
}

Then I draw a bunch of rectangles. I've tested it with a different font/size combination, no luck. Uncomment Draw() call to draw TextMeasure rectangle and see that it's always rendered correctly. The issue is somewhere inside DrawText.

public static Font TagFont { get; set; } = new Font(SystemFonts.Find("Arial"), 200);

public static void AddRects(this Image<Rgba32> image, float xOffset, float yOffset, 
            IEnumerable<PlottableRect> rectangles)
{
            foreach (var item in rectangles)
            {
                if (item.Area == 0) continue;
                RectangleF r = item.Rect;
                r.Offset(xOffset, yOffset);
                image.Mutate(x => x.Fill(item.Color, r));
                if (item.Tag == null) continue;
                bool o = item.Orientation;
                var textPoint = RectangleF.Center(r);
                var tMeasure = TextMeasurer.Measure(item.Tag, new RendererOptions(TagFont));
                float tLenOffset = -tMeasure.Width / 2;
                float tHOffset = -tMeasure.Height / 2;
                textPoint.Offset(o ? tHOffset : tLenOffset, o ? -tLenOffset : tHOffset);
                image.Mutate(x => 
                {
                    var rdo = o ? new DrawingOptions { Transform = GetTextRotationMatrix(textPoint) } 
                        : new DrawingOptions();
                    x.DrawText(rdo, item.Tag, TagFont, Color.White, textPoint);
                    //x.Draw(rdo, Color.White, 5.0f, new RectangleF(textPoint, new SizeF(tMeasure.Width, tMeasure.Height)));
                });
            }
}

private static System.Numerics.Matrix3x2 GetTextRotationMatrix(PointF p)
{
            return Matrix3x2Extensions.CreateRotationDegrees(-90, p);
}

public class PlottableRect
{
        private Rectangle _Rect;
        public Rectangle Rect { get => _Rect; //This accessor copies the Rectangle struct isolating _Rect
            protected set
            {
                _Rect = value;
            }
        }
        public Color Color { get; set; }
        public virtual string Tag { get; set; }
        public int Area { get => _Rect.Width * _Rect.Height; }
        public bool Orientation { get => _Rect.Height > _Rect.Width; } //Vertical
}

Afterwards I resize and save the image (as PNG). I tested the code without final resizing, the problem persists.

System Configuration

  • ImageSharp.Drawing version: beta13
  • Other ImageSharp packages and versions: main = 1.0.4
  • Environment (Operating system, version and so on): Win7x64, Win10x64 LTSC 1809
  • .NET Framework version: .NET Core 3.1
  • Additional information:
@JimBobSquarePants
Copy link
Member

Hi @kutukvpavel sorry for the slow reply here. I wanted to complete a few things first.

I've just pushed an update into the MyGet feed 1.0.0-beta13.15 which will most likely fix any issues you have. Can you please give it a try and let me know?

@kutukvpavel
Copy link
Author

Thanks for addressing this issue @JimBobSquarePants !

Unfortunately, no luck with 13.15 either. I installed beta13.15 prerelease from MyGet, ported some API, rebuilt everything clean, and checked the package dll version, so I'm indeed running 13.15. But the images produced are exactly the same.

Btw, this is my app repo, in case you'd like to have a look at the code/test it on your machine: https://github.com/kutukvpavel/FloorTilingOptimization

@antonfirsov
Copy link
Member

@kutukvpavel can you create a simplified, self contained repro, demonstrating the problem by drawing only one tile with constant image, rectangle sizes and offsets?

That would (1) immediately clarify if this is a bug (vs. potential usage issue in your application), (2) save us a lot of time, leading to a faster issue triage and bugfix.

@kutukvpavel
Copy link
Author

No problem, @antonfirsov . Here you are: https://github.com/kutukvpavel/ImageSharpDemo .
This is what I get (supposed to be "0,t=0"):
result

@JimBobSquarePants
Copy link
Member

JimBobSquarePants commented Nov 23, 2021

@antonfirsov I've just pulled down the code from the sample and the usage appears correct. Can confirm 60 degrees appears to be the cutoff for correct rendering also. Definitely a drawing issue and not a fonts one.

@JimBobSquarePants JimBobSquarePants added bug Something isn't working and removed needs triage labels Nov 23, 2021
@JimBobSquarePants JimBobSquarePants added this to the 1.0.0-rc.1 milestone Nov 23, 2021
@replaysMike
Copy link
Contributor

a PR is available that fixes this issue - PR 191

JimBobSquarePants added a commit that referenced this issue Jan 13, 2022
…ts-chopped-when-rotated

fixes #175 - Text gets chopped when rotated >60 degrees.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
blocking bug Something isn't working
Projects
None yet
Development

No branches or pull requests

4 participants