-
-
Notifications
You must be signed in to change notification settings - Fork 44
Description
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
andRELEASE
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.
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).
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: