dotnet / dotnet/winforms

Text size is a bit off using Graphics and very wrong using GraphicsPath

Open
#7,485 4 comments 0 reactions 1 assignee Claimed by @JeremyKuhne View on GitHub
area-System.Drawing help wanted
Dominant language
C#
Stars
4.9k
Forks
1.1k
Avg merge
1d 13m
Merged PRs (30d)
85

Description

### .NET version

.NET Framework 4.7.2

### Did it work in .NET Framework?

No

### Did it work in any of the earlier releases of .NET Core or .NET 5+?

probably in none

### Issue description

What was my initial goal:
- create a rectangle which by resizing, fits text into itself
- this rectangle should show the bounds of the text and the text should fit tightly into the rectangle (just like the blue `GraphicsPath` sample does but its size is wrong)

This seems like an impossible task with current WinForms API because there are two string size calculations which produce different results and both are wrong. `Graphics` is approx. to 90 % right while `GraphicsPath` is like 60 % right or less,

Drawing a string with font size 60 points on coordinates [200, 200] with Graphics and GraphicsPath produces two very different results (shown by text).
String size calculation using `Graphics.MeasureString` and `GraphicsPath.GetBounds` methods produces two very different results (shown by rectangles).

- bounding rectangle of the Graphics is OK with the position
- bounding rectangle of the GraphicsPath is sligtly shifted compared to the position (and I am not really able to calculate why and how)
- both Graphics and GraphicsPath should have top left corner at [200, 200]
- a bit about this is explained here https://stackoverflow.com/questions/51006343/winforms-drawing-a-path-in-the-right-place

![image](https://user-images.githubusercontent.com/64279914/180624332-90ee8b1b-98b1-456d-ad87-0bd706d73688.png)

### Steps to reproduce

[WindowsFormsApp2.zip](https://github.com/dotnet/winforms/files/9174742/WindowsFormsApp2.zip)

Note: because of the `GraphicsPath` behavior, the best size calculation (fit into rectangle) can be done by bruteforcing font size from largest to lowest using `GraphicsPath` with `GetBounds`. However the result works fine only for drawing by `GraphicsPath` (if drawn by `Graphics` with font size calculated using `GraphicsPath`, the text will be much bigger because font sizes returned by `GraphicsPath` are very small (unrealistic))
- what `GraphicsPath` only does well is calculating the bounding rectangle of the string (wrong font size and shifted position!)


Edit: this project shows how to get the drawn position of `GraphicsPath` right, however it is kinda complicated because if `GraphicsPath` contains multiple objects, this must probably be done for every object (create an additional `GraphicsPath` object, measure size and offset, drop the `GraphicsPath` object and then use the correction to draw the actual `GraphicsPath` object):
[GraphicsPath corrected drawing location.zip](https://github.com/dotnet/winforms/files/9176292/GraphicsPath.corrected.drawing.location.zip)
- the font size compared to Graphics.MeasureString issue persists
![image](https://user-images.githubusercontent.com/64279914/180659235-30e778e8-4b8d-4fe3-8db7-dce6a4c3c658.png)

![image](https://user-images.githubusercontent.com/64279914/180659258-87cedbaf-aef5-4b5e-9f95-2197a5768c9b.png)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.