Closed beibean closed 5 years ago
Size can be a bit different, because new version calculate metrics exactly as is should.
Discussion of "render any TTF into OLED with any size and best quality" can be endless, because technically impossible. Instead, i'd suggest you to describe exactly what you really need (list of sizes, bpp, font family, ...) and we will try to find solution.
About missed _
- use --dump
to check source chars. This may be problem not with font but with renderer.
Do you know if is there any possibility to use the method used in LittlevGL v5.3 just for getting the glyphs images?
Only if you rewrite convertor back to PHP and use built-in renderer :)
The PHP version uses FreeType to render the fonts. Is it ported to JS too? If so, it might be worth a try.
The PHP version uses FreeType to render the fonts.
Is it ported to JS too? If so, it might be worth a try.
I declined use of native FreeType, because installation difficulties would make package not useable for end customers. JS renderer, used here is well known opentype.js
, it's good enougth.
I declined use of native FreeType, because installation difficulties would make package not useable for end customers. JS renderer, used here is well known opentype.js, it's good enougth.
So there no reasonable way to improve quality?
So there no reasonable way to improve quality?
In general, problem of ideal write of ANY vector font to low resolution display has no technical solution. I'd say, proper font selection for specific size will give much better effect.
Attempt to drop hinting will be waste of time IMO. With some luck, you will exchange one problem to another - bold lines to blured contours.
I got no answer about _
. That may be some bug about cropping line bottom (but i hope not in font). Anyway, all this need a sample repo with reproducible samples and comments where to look. Inspecting with --dump
will quickly show all defects.
It may be possible to improve horisontal resolution 3x via subpixel smoothing, but i did not digged deep into. IMO spends in this direction are not reasonable (just use HiDPI display instead with much better result).
Using (or at least trying) FreeType is really not possible direction?
Attempt to drop hinting will be waste of time IMO. With some luck, you will exchange one problem to another - bold lines to blured contours.
What does hinting mean in this context? Could explain it or link something to read?
IMO spends in this direction are not reasonable (just use HiDPI display instead with much better result).
Anyway, better quality is better. :slightly_smiling_face: It would be nice to achieve the quality of the PHP converter. It really used some scaling and other tricks but these were only to modify the font size. So there were no hacks on the rendering itself.
Using (or at least trying) FreeType is really not possible direction?
Everything possible. And full rewrite to php possible too. But without me :)
What does hinting mean in this context? Could explain it or link something to read?
https://www.freetype.org/ttfautohint/ - see intro & docs. That's corrections for small sizes to improve visual quality
Anyway, better quality is better. :slightly_smiling_face:
It's better only until it costs nothing :). Subpixel smoothing will require at least 3x memory to increase source resolution. Also, dark color become more light. You can search algorythms in google, something exists, but i don't remember details. Bitmap fonts have limitation, after those they become not evffective. At some moment it's better switch to vector fonts instead of reinvent weel.
It would be nice to achieve the quality of the PHP converter. It really used some scaling and other tricks but these were only to modify the font size. So there were no hacks on the rendering itself.
It would be nice to have test repo with reproducible samples first, prior to discuss anything. Convertor has --dump
mode, and it's easy to check what it writes to font file.
If anyone wish to check hinting difference, hinting can be disabled here in option.
(just use HiDPI display instead with much better result)
We can't expect all embedded systems to have HiDPI displays.
I this our problem we need spend time to discuss? Problem is trivial - author need to create test repo with font file, and put into readme list of minimal CLI commands to reproduce results.
I did dump P of roboto and some freesans from internet with this command (set appropriate font path):
$ ./lv_font_conv.js --size 14 --bpp 4 --format dump --font ./node_modules/roboto-fontface/fonts/roboto/Roboto-Regular.woff --symbols P -o 1111
Effect is caused by location of vertical line between pixels (as a result, in freesans it's more gray).
Could not find difference with and without hinting, and it's strange. Tried to enforce hinting via ttfautohint
tool, but renderer crashed with error
$ ./lv_font_conv.js --size 14 --bpp 4 --format dump --font freesans_ttfa_hinted.ttf --symbols P -o 1111
Hinting error:Error: unknown instruction: 0x78
Note: further hinting errors are silenced
Probably, built-in hints are for very small sizes, and freetype may use autohinter for bigger size. Will ask opentype.js guys why renderer crashes.
Anyway, i'd suggest to use pixel-perfect fonts for specific size if you need best quality.
Reported https://github.com/opentypejs/opentype.js/issues/395, this should be fixed prior next attempt.
Reported opentypejs/opentype.js#395, this should be fixed prior next attempt.
Awesome!
For info. Seems it should be possible to assemble and use freetype2 via emscripten for use under node.js. But existing state of npm modules is very outdated:
Also take into account:
Freetype has GPL license.
Are you sure? The website says that it is dual licensed under the FreeType License and the GPL: https://www.freetype.org/license.html
@embeddedt you are right. It should not become a fatal problem.
If you find a way to build freetype as node.js lib (with JS-callable API) - kick me to take a look. Webassembly internals would be preferable, but not critical.
In last try i remenber, we did manual wrapper and that looked ugly https://github.com/fontello/wawoff2/blob/master/compress.js. I think, emscripten devs should have something better for us.
Hi,
I've been out of the lvgl project, and will go on holidays soon.
I will test in a few weeks with other fonts to see if they are rendered better (roboto is a good candidate) and fit the project and investigate using --dump
as puzrin suggests.
No good news about opentype.js. Hinting processor had no support of conditional jumps. Adding this support was trivial, but resulting images become broken. I suspect, there are more bugs in previously implemented parts - fixing those needs completely different spends.
I would not recommend to wait solution from opentype.js in realistic future. It would be better, if someone could investigate how to build freetype for node.js via emscripten. In this case i could replace renderer.
@puzrin FreeType is already ported to Emscripten. The question is how you want to expose the APIs to node.js
.
@embeddedt Under "build for node.js" i mean providing appropriate API-s.
As far as i understand from doc, emscripten has some support https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html. But i can't understand how is this expected to be initialized? Because as far as i know, init process is async (at least, webassembly init is async and this can't be avoided).
Because as far as i know, init process is async (at least, webassembly init is async and this can't be avoided).
Right. I think the rest of the font convertor would have to accommodate that.
That's not a big problem (i will do), if anyone can create a transpiled freetype package for node.js (if that's technically possible).
Draft will be ok too (build script & info how to init/call from node). I'm ready to help with node-specific details, how to properly arrange & publish package.
if anyone can create a transpiled freetype package for node.js (if that's technically possible).
Can you explain exactly what the steps would be to create that package, beyond simply including FreeType into an Emscripten program? Would I essentially have to bring out the FreeType APIs to JavaScript?
If you have some time, i'd suggest to look at https://github.com/fontello/wawoff2 as [bad] example. Just to be sure that's possible. Problem is, that solution uses manual wrappers & all functions done async to hide init.
As far as i understand, embind
is intended to generate JS glue automatically. But:
So, i see this steps:
It seems possible to create node.js
modules when compiling to WebAssembly (see the first half of this page): https://developers.google.com/web/updates/2019/01/emscripten-npm
Well, as far as i see from ems faq, they suggest promise-like loading interface with -s MODULARIZE=1
. That's fine.
Also, according to your link, docker should simplify builds.
What is not clear - how to create interface to call freetype2 methods and pass structs OR typed pointers. Google example use primitive types, those are not enough.
@puzrin It would be simplest, IMO, to build the renderer component in C, and create an API that is used by the higher-level components of the font convertor. That way, there would be a very reduced amount of binding code that would need to be written.
that solution uses manual wrappers
Unfortunately, I think that's unavoidable when trying to bind two very different languages.
embind
is intended to generate JS glue automatically
I'm not so sure about this. It looks like embind
is intended to generate JS glue when told information about the functions. Look at the super-simple C++ example: https://emscripten.org/docs/porting/connecting_cpp_and_javascript/embind.html#classes
Ok. C renderer will be useable too. I think, we could continue use opentype.js
to work with metrics data, and use FreeType2 only to draw single glyph.
Will you have a time to do such "draft" with build script for docker, useable for cwrap
call? With some minimal "caching" to not parse font very time for each glyph.
@puzrin I can get it to the point where you can build a module with FreeType and include it in the font convertor. Beyond that, I have little experience with FreeType, so I won't be of much use. I think you (or someone else) will have to write the relevant C routines for that.
I'm not strong in C (can do some simple things, when no choice) and not familiar with freetype too. I could try to describe desired C interface, if that helps.
@puzrin IT'd be a good starting point. I'm also not familiar with Freetype but let's see the required interface. Generating the bitmap shouldn't be too complicated.
Something like this:
// seems FT can autodetect font type
int create_fontface(Uint8Array font, uint16 size, &fontface_data);
int free_fontface(&fontface_data);
int render_glyph(&fontface_data, uint32 glyph_code, Uint8Array &rgba_buffer, uint32 uint32 buf_size_x, uint32 buf_size_y, uint32 glyph_pos_x, uint32 glyph_pos_y);
I think this should be testable without JS at all.
Or, as altermative, without cache (for first attempt):
int render_glyph(Uint8Array font, uint16 size, uint32 glyph_code, Uint8Array &rgba_buffer, uint32 uint32 buf_size_x, uint32 buf_size_y, uint32 glyph_pos_x, uint32 glyph_pos_y);
I think this should be testable without JS at all.
Sure creating byte array with the rendered image should be that simple. Do you need some assistance with that?
Do you need some assistance with that?
Yes.
Under example i mean "read font from file, render char P
and dump result array to console".
I've followed this tutorial and made it work without Docker.
Steps:
make
sudo make install
freetype_test
: gcc render.c -I/usr/include/freetype2 -L/usr/local/lib -lfreetype
Thank you! Could you do this changes:
FT_New_Face
loads code from file, that's not available in JS/Web. As described in signature, file data should be loaded from memory (i guess, some form of array, probably with length in separate param). I mean, main
should load file, call renderer and then dump result.I've created a git repo for it and updated with requested changes: https://github.com/kisvegabor/freetype_test
Thanks a lot. Give me several days to setup build scripts (never used docker before), then will try to use FT as backend. That should not take too much time, i'll keep you informed on progress.
Great, thank you!
@puzrin Is there any news with FreeType?
Not yet, sorry. Have to do other projects. But i remember about this issue.
Ok, thank you for the feedback.
I've tagged last stable version and commited API rewrite to be async https://github.com/littlevgl/lv_font_conv/commit/6bd7c74b18d76a15e973ed0a35c5c28b50b05f6b
That does not add "new features", but allows to call async init for emscripten-compiled libraries.
@kisvegabor, @embeddedt
There are some progress (see branches). Need help with freetype lib build. Current one (default) does NOT support woff (ttf is ok). Here is Dockerfile
Could you help with improving this? I mean:
To run via npm:
# build docker image, with emscripten & precompiled freetype
npm run build:dockerimage
# compile renderer glue for js (run shell file in our docker image)
npm run build:freetype
Probably need extra libs, more options & better paths instead of emmake make install
in docker config.
PS. please post samples to separate branches, don't touch existing ones.
Note, woff (not woff2) is "ttf + gzip". Probably, freetype was misconfigured somehow. I have no ideas why woff loading can fail, except decompression problems. From the other hand, FreeType has built-in zlib and i don't know why this may fail.
I've tested Roboto-Regular.woff.zip with my freetype_test repo and it worked well.
@kisvegabor
You used preinstalled system library, while we build it from sources. Problem is with configure
, it disables zlib (and built-in zlib too), required for woff. Note, is we use built-in ported freetype, woff works, but version is very old and should not be used for good hinting.
We updated branches with almost working new renderer, see freetype
. It still misalign glyphs, BUT ready to test everything else:
How to play:
git checkout freetype
# once
npm run build:dockerimage
# after checjout + Every time after built config or C source updated
npm run build:freetype
Note, steps above need because we did not commited wasm build to avoid multiple updates of big blobs. Will do that when all issues resolved.
It would be very nice is someone more experienced could help with emscripten. FreeType build issue does not depend on JS at all. What is needed:
make install
, and that plase wasm files to system folder. It would be better to keep those in /opt/...
or something similar.Tested FreeSans.
opentype:
freetype current:
ttfautohunt + freetype:
someone more experienced could help with emscripten.
I will look into it on the weekend.
https://github.com/littlevgl/lv_font_conv/commit/60e35b57d2159f5fc323a817859e44cdd408712f
Fixed woff support via kludge, until done properly + with harfbuzz. Idea is force it use system zlib and then add -s USE_ZLIB=1
to emcc options. Ugly but works.
I don't know why freetype does not fallback to autohinter when hinting info not exists for specific size. So, forced autohinter to be always on.
FreeSans before (FT_LOAD_DEFAULT flag):
FreeSans after (FT_LOAD_FORCE_AUTOHINT flag):
I don't know if additional option needed to disable autohinting. Will add later, if bugs reported.
Hi @puzrin,
First of all, congratulations for the great job done with de font converter 😉.
I was migrating from LittlevGL v5.3 to LittlevGL v6.0 and found some issues discussed here.
I already understood more or less the stuff related with new paradigma. Whichever, the thing I am worry about is the quality of the glyphs with new font converter.
As I show in this post, there is a bit lost in glyph quality. I guess is not about the new font converter at all but for the method of getting the .ttf into image.
What do you think? It might be an special case, but is important on my project.
Do you know if is there any possibility to use the method used in LittlevGL v5.3 just for getting the glyphs images?
Thanks in advance