-
Notifications
You must be signed in to change notification settings - Fork 120
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 rendering #65
Comments
Here is my version of lines and text. Perhaps it can help. But I used generics. |
I wish I wrote more comments too :)
The main difference is that I get the vectors for larger fonts and then down-sample these rasterized glyphs. It seems that this produces clearer and thinner glyphs at smaller font heights.
I'm confident that what you're seeing in the zoom is an accurate representation of the pixels below your mouse cursor. Edit: Oops, you're right (again), there is a bug there! It seems that moving the mouse over the top text render show the zoom of the lower text render. The zoom is accurate but just for the wrong image :). I'll fix and update again sometime soonish (when I've finished a few other fixes and embellishments).
OK, I haven't noticed that myself but evidently there's a bug somewhere. This code has been cobbled together in the last 24hrs from a small graphics library of mine (that's unrelated to Graphics32). I'm not sure it this bug is related to this recoding or if it also exists in my other library. GR32_Text2 is monolithic because it's an amalgamation of 2 modules. It's intended as proof of concept (that we can do quite a lot better) as I was disappointed with the quality of text rendering in the TextVPR sample. Edit2: I've just realised that the bolding and blurring I'm seeing in TextVPR may well be due to an improperly adjusted the Gamma. This may be much ado about nothing after all. |
Ah! but, but... that's cheating :-)
I provided both the source and the zoomed image, so you can see for yourself that it isn't. |
Yes, that would explain why it wasn't there originally. AFAIK the gamma stuff was introduced later. |
Yes, DEFAULT_GAMMA is 2.2 (in GR32_Gamma.pas) which seems very high IMHO. |
Reproduced. The default gamma was recently changed from 1.6 to to 2.2 by @CWBudde: dc6db6a |
Thanks, that's helpful information too. (Sorry not to reply earlier.) |
So... "Works as designed" or do you still think that we need to fix anything here? If the existing renderer is good enough, but you know of something that could be done better, you could merge your improvements into the existing? |
Regarding the gamma setting: There is probably some confusion about it. This goes back to the research by Maxim Shemanarev, which has been used as a reference by many others (probably by Mattias as well). To make it short: Today monitors require a certain GAMMA setting to display colors correctly. Since (good) monitors use mostly sRGB nowadays you should use this for a perfect color representation. If you can't use it, a gamma factor of 2.2 comes very close to this. Since windows itself does not apply any gamma preprocessing itself, it's up to the user to do it. So far GR32 used a gama factor of 1.6 for drawing of primitives. This means that all bitmaps implicidly contain a gamma factor, so that drawing only mean to blit the image to the graphic card memory. With an implied gamma setting you need to ensure that the rendering also applies the gamma correction upon drawing at some point. This said, it seems that drawing the fonts with a proper gamma value doesn't seem to work as fonts look to bold. The reason for this can be:
In our case the latter (and the first) could be the problem, because not the color values are multiplied as it should, but the alpha values. Since these are multiplied with the color values later, the gamma handling will be done implicitly, but I'm not sure whether it will still be in twice (as it is also in the alpha value as well). It is on my todo list to look into this issue, but not today or this week, I fear. |
Regarding the gamma value again: We probably really need a way to have an independent gamma setting for each bitmap in a way that rendering will apply the right gamma value for that particular bitmap. Within the PNG library I already take a certain gamma chunk (containing gamma information) into account in a way that I match it. The main issue with converting the gamma values is the loss of precision. So sooner or later we should also consider to make 16 bit in the future. But that would also require to have (temporary) bitmaps with 16 bit precision per color channel. |
That's OK. Just have it done by yesterday :-) Maybe I haven't understood this properly, but shouldn't correction only be applied at the end stage. I.e. when something is finally displayed on the screen? If this is correct then the only place where gamma should be applied automatically would be in TImage32/TPaintBox32. |
Basically it would be satisfying to apply it only upon drawing onto the screen. However, if not double buffered you usually draw the result quite often onto the screen, so this drawing code should (in the past) be as fast as possible (just a blit). Another reason about why to use preprocessed images is the precision, especially with only 8 bit per color channel. While operations with a linear scaling will be simple and straight forward, your precision is also equaly spaced accross the entire range. But our eye does not perceive the brightness linearly. it typically perceives darker colors better. Thus the preprocessing makes sense as you can get an even better precision. Unfortunately - as always - GR32 does not yet use its full potential because the colors are converted by a simple 8 bit table, which has the precision loss already built-in :-( So in order to make use of the full potential, all drawing code should (optionally!) work with an internal precision of 16 bit per color and apply the gamma factor with a 16bit table. Only than the full brightness range will be used. The same holds for blending two bitmaps. If done correct, the gamma factors need to be matched before. Per pixel this should be done with 16 bit internal precision. After this operation it can be converted back to 8 bit. While this is necessary for high quality rendering and good image processing, it might be overkill for simple drawing operations. IMHO Gr32 should offer both, depending on what the user wants. We just need to implement it and find good defaults (in terms of performance and quality). |
I'm currently reading "What every coder should know about gamma" which should clear up some thing for me. There's even a section on anti-aliasing. Here's a quote:
|
Also good to know the sentence after that:
This explains why we need an additional (independent!) gamma setting for the font rendering in order to make it look as desired (more or less). |
I don't think we need to make significant changes now, but there are some things that need attention:
It would also be ideal if character glyphs (or even just vectors) were cached, as this could improve performance. I'll try to investigate point 2 above but I don't have the resources to tackle the others, though they are features in GR32_Text2. (GR32_Text2 isn't affected by gamma even though it also uses PolyPolygonFS because I use a larger font for rendering and shrink the result to the expected font size.) I would recommend a text gamma of 1.0 or even a little less. |
I've had a closer look at this and the both GR32_Text_VCL and GR32_Text2 render الله (Char($FDF2)) correctly.
I've tried pretty hard but I haven't been able to duplicate this. Anyhow, just before I close this thread, here an update to GR32_Text2... |
That's because you fixed it :-)
Do you have an example of this? I remember seeing something like that in another project I worked on but that was at least 15 years ago and AFAIR it was a bug in the font.
No. It seems to do the escapement of the individual glyphs correctly but fails to also rotate the base line. |
Not reproduced. |
Yep, while I was mucking around with |
I have just implemented a cache in the VCL TextToPath functions. It has doubled the performance of the text test in the benchmark examples. Where do I collect my paycheck? :-) I have added it using conditional defines and it is implemented with generics |
I don't think Graphics32 text rendering is optimal, and I've attached a sample project that compares the existing text rendering with some code I developed for another project. If this generates significant interest I'd be happy to work up a new text module (though I'd need help with cross-platform support).
![Text2](https://user-images.githubusercontent.com/5280692/55851932-342f8280-5b9e-11e9-8c4c-7f885a2d8975.PNG)
Text2.zip
The text was updated successfully, but these errors were encountered: