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

Small font rendering really unclear (blurry, missing pixels etc) #293

Closed
4 tasks done
myblindy opened this issue Jul 27, 2022 · 10 comments · Fixed by #295
Closed
4 tasks done

Small font rendering really unclear (blurry, missing pixels etc) #293

myblindy opened this issue Jul 27, 2022 · 10 comments · Fixed by #295

Comments

@myblindy
Copy link

Prerequisites

  • I have written a descriptive issue title
  • I have verified that I am running the latest version of Fonts
  • 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

Rendering small fonts is unreadable with alpha blending enabled, due to the really imprecise, blurry way they're being rendered:

ImageSharp (default antialiasing settings):
image

GDI+ (clear type):
image

This is with Segoe UI at 10 pixels. The vertical lines especially aren't clear, and with alpha blending enabled they just disappear.

I also tried disabling antialiasing in the ImageSharp render, but that makes it even more obvious how imprecise it is:
image

I also tried hinting, which is supposed to help with this, but it doesn't seem to work at all:
image

For Open Sans it's even less readable, and hinting just produces long vertical lines:
image

Is there some set of options I can enable to make small font rendering clear?

Steps to Reproduce

I have a sample repo that I used to generate those images at https://github.com/myblindy/font_test

System Configuration

  • Fonts version: 1.0.0-beta18
  • Other Six Labors packages and versions: ImageSharp 2.1.3, ImageSharp.Drawing 1.0.0-beta15
  • Environment (Operating system, version and so on): Windows 10
  • .NET Framework version: .Net 6
  • Additional information: N/A
@JimBobSquarePants
Copy link
Member

There's actually two issues here.

  1. The rasterizer. We need LCD rasterization to compete with System.Drawing. We just use alpha blending and it's simply no match. I know PixelFarm have an implementation but I don't know when I'd ever get round to adding it to ImageSharp.Drawing (that's where the rasterizer lives). @tocsoft have you ever dabbled in this?

image

  1. The hinting. That appears to be a problem with the X hinting and will require careful stepping through to figure out what is happening. That one is a little heartbreaking as I thought we'd cracked it. 😔

Y-only hinting seems to be fine.
a

@JimBobSquarePants
Copy link
Member

JimBobSquarePants commented Jul 28, 2022

Noting that both XY and Y hinting work for the ttf version of OpenSans

a

@myblindy
Copy link
Author

myblindy commented Jul 28, 2022

I had stopped using the ttf version because it crashed with NRE in the previous release, I'll give it a try again.

So far I have this:

Segoe UI with Y hinting, still very blurry, and the vertical lines are not straight, look at o in particular:
image

Open Sans (ttf) with XY hinting, looks okay shape-wise, but everything is blurred (ie, high transparency which breaks alpha blending against a non-black background):
image

Edit: after staring at it for a while longer, the XY hinted Open Sans is actually damn near perfect for me, I just need it to have a solid white foundation and the antialiasing parts to be around it as necessary for alpha blending to work. If you're familiar with SDF font rendering, the ImageSharp renderer behaves as if the edge of the font starts at 0 and it immediately starts losing alpha strength as it gets farther away (which of course is not what an edge is).

@myblindy
Copy link
Author

Noting that both XY and Y hinting work for the ttf version of OpenSans

a

Also note that white text on a transparent background doesn't render on github, it's why I'm taking screen shots :)

@JimBobSquarePants
Copy link
Member

Also note that white text on a transparent background doesn't render on github, it's why I'm taking screen shots :)

Haha! I completely forgot since I'm so used to dark mode! I'll update my images.

@tocsoft
Copy link
Member

tocsoft commented Jul 29, 2022

... @tocsoft have you ever dabbled in this? ...

nope not something i've experimented with, however I would say the issue with 'LCD' rendering is they only work for LCD displays (not paper etc) and also you need to know the subpixel layout of the screen and the exact position on the screen where it will render, you can't rasterize the pixels once and move them, for example, as moving the it half a pixel in any direction will cause the relative subpixels layout to be different in relation to the target.

@JimBobSquarePants
Copy link
Member

@tocsoft Ah no, sorry. What I mean is colorized antialiasing as described here and used by Cleartype.
https://www.grc.com/cttech.htm
https://www.grc.com/cttech.htm

image

I know Antigrain have an implementation and PixelFarm wrote theirs based upon that but I'm not sure how we would integrate such an approach since we use the PixelBlender to do the rendering especially since we'd need to do it in a way that works with all our brushes like System.Drawing can as demonstrated with this linear brush example.

image

@tocsoft
Copy link
Member

tocsoft commented Jul 29, 2022

I knew what you meant, but that technique can only be useful when rendering to screen where you can take advantage of the color shifting of the pixels rendered, it will produce fringing and be pretty useless in any other medium, and you also can't composite the rendered text on to another picture (post generation as there is not transparency retained). So unless your planning on rendering the vectors and displaying them directly to screen then it'll be very likely to produce suboptimal results. This is all remembering that real time screen graphics rendering is not a scenario we are actually targeting with this library.

FYI, Antigrain and Cleartype (which System.Drawing uses cause its a relatively thin wrapper around the GDI screen rendering subsystem system) are both screen rendering technologies they where built to draw pixels on a screen which is why it makes sense for them.

@JimBobSquarePants
Copy link
Member

JimBobSquarePants commented Jul 29, 2022

@tocsoft Ah right... I wonder whether it is something we should consider in the future though as it seems more people are beginning to use the library in gaming. I guess they can simply bring their own rasterizer.

@myblindy Looks like I may be having some success with the interpreter. Here's Segoe UI at 10 pixels.

Hinting XY
Assigning food to tree

No Hinting
Assigning food to tree

Here's with (left) and without (right) hinting zoomed and compared.
image

I have a LOT of visual testing to do now.

@myblindy
Copy link
Author

myblindy commented Aug 3, 2022

Definitely an improvement, great work!

I'll keep an eye on how this shapes up (no pun intended), but for now I switched to the tried and true System.Drawing to get a working baseline version of the code. In the medium-to-long-term when cross-platform starts to matter I'll revisit ImageSharp and SkiaSharp and see where we stand!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants