Closed BusyStudent closed 2 years ago
The difference could be the way SDL/nanovg load the fonts. There are many parameters to freetype. What I would try is build ftview or ftgrid from the freetype-demos and check out the various "hinting" and anti-aliasing modes, which sometimes give surprising differences. You'd probably have to patch nanovg, to use your desired font mode.
@mulle-nat @memononen But when i change the hinting in fons__tt_buildGlyphBitmap into different flags such as FT_LOAD_DEFAULT or FT_LOAD_NO_AUTOHINT,it didnot works It still perform as previous
I had already try all hintings and anti-aliasing modes
And and noticed the lsb in fontstash didnot be used in anywhere,what is the lsb used for I think the difference is the font metrics is not be handled correctly Because i saw the way of getting the font metrics in SDL_ttf is different from nanovg
in TTF_initFontMetrics
/* Make sure that our font face is scalable (global metrics) */
if (FT_IS_SCALABLE(face)) {
/* Get the scalable font metrics for this font */
FT_Fixed scale = face->size->metrics.y_scale;
font->ascent = FT_CEIL(FT_MulFix(face->ascender, scale));
font->descent = FT_CEIL(FT_MulFix(face->descender, scale));
font->height = FT_CEIL(FT_MulFix(face->ascender - face->descender, scale));
font->lineskip = FT_CEIL(FT_MulFix(face->height, scale));
underline_offset = FT_FLOOR(FT_MulFix(face->underline_position, scale));
font->line_thickness = FT_FLOOR(FT_MulFix(face->underline_thickness, scale));
} else {
/* Get the font metrics for this font, for the selected size */
font->ascent = FT_CEIL(face->size->metrics.ascender);
font->descent = FT_CEIL(face->size->metrics.descender);
font->height = FT_CEIL(face->size->metrics.height);
font->lineskip = FT_CEIL(face->size->metrics.height);
/* face->underline_position and face->underline_height are only
* relevant for scalable formats (see freetype.h FT_FaceRec) */
underline_offset = font->descent / 2;
font->line_thickness = 1;
}
As far as I understand nanovg, nanovg places each character into a small part of a large texture with a one pixel border around it. The actual rasterization is done by FreeType. Specifically here ftError = FT_Load_Glyph(font->font, glyph, FT_LOAD_RENDER | FT_LOAD_FORCE_AUTOHINT | FT_LOAD_TARGET_LIGHT);
I would suspect that FT_LOAD_TARGET_LIGHT
is the culprit, that's responsible for the visual difference. If it's not, I would start trial and erroring myself to success, as I have no further ideas :)
After omitting FT_LOAD_TARGET_LIGHT
, the visual difference still exist,it just make the text sharper.
@mulle-nat Did you get any progress of it?
I am not doing anything. As I wrote in my previous reply, I have no further ideas.
@BusyStudent Were you able to solve the problem ?
@BusyStudent Were you able to solve the problem ?
@mulle-nat Yes,I have find the reason,The reason is fontstash didnot handle bearingX and bearingY correctly, But I still didnot how to patch it by a clear way. It has big difference with SDL_ttf,And there are too many magic number
Here is my code,It works,but dirty
//in fons__getGlyph
glyph->index = g;
glyph->x0 = (short)gx;
glyph->y0 = (short)gy;
glyph->x1 = (short)(glyph->x0+gw);
glyph->y1 = (short)(glyph->y0+gh);
glyph->xadv = (short)(scale * advance * 10.0f);//Why 10.0f
glyph->xoff = (short)(x0 - pad);
glyph->yoff = (short)(y0 - pad) - y1;//< Just here
//in fons__tt_buildGlyphBitmap
*x0 = FT_FLOOR(metrics->horiBearingX);
*x1 = FT_CEIL(metrics->horiBearingX + metrics->width);
*y0 = -FT_FLOOR(metrics->horiBearingY);
*y1 = *y0 + FT_CEIL(metrics->height);
@mulle-nat oh,sorry.It only works on current font... I read the old version of SDL_ttf.
My finnal idea is to add harbuzz to get offset / advance like here
Interesting. I use harfbuzz in my projects, because it improved the looks, but that's about what I know. I didn't think of suggesting it to you, because I see it do better kerning (better spacing in the x-axis) only. But maybe it also also does y-axis offsets. So your idea sounds worth trying to me. Good luck.
@mulle-nat Did you doing anything? I try to add hb in fonsTextIterInit,but after calling hb_shape
. I received an all zero value array in hb_buffer_get_glyph_positions
@memononen
I also check freetype documents,It seems that fontstash didn't align glyphs in the baseline ,it just output the glyph directly and I was stuck in align the glyph in fons__getQuad
.
I have see the align code in SDL_ttf by getting y-axis offset fromascent - bitmap_top
,But when I port it to fontstash it works,but the lower case character was much higher than prev. I think the align algorithm still has something wrong
The way I use harfbuzz is that I am building my own freetype library and define it to use harfbuzz. So in effect, if harfbuzz were to fix your problem, it would be doing so transparently to nanovg by providing better values through freetype. Or at least that's how I believe it works.
Fixed,After using my reimplementation of fontstash
Strange text rendering results when I render English and Chinese characters at the same time
Here is the rendering results of nanovg and sdl_ttf![Screenshot_20220210_182822](https://user-images.githubusercontent.com/53860199/153411433-98915593-b149-4877-8508-0f8f1bac7d47.png)
Compared to SDL_ TTF,The Chinese glyphs and English glyphs seem to be not in the same line It was much lower than English glyphs
It looks doesnot very good
Here is the code
Here is the font msyh.zip
Can anyone help me?