Advertisement

Rendering Text for GUI

Started by January 04, 2017 06:10 PM
7 comments, last by Nanoha 7 years, 10 months ago
Hi guys, I'm not sure where to post this, but since I'm new to rendering text, so I post it here.

I'm currently doing a job on rendering 2D text for UI from scratch using C++ and a graphics API. I have no idea on the workflow to render text.
I also need to be able to render Japanese texts along with its kanji characters.

The first thing that came up in my mind is, do I have to turn the font to image first so I can iterate the characters from the image? Is that the only way? I'm also worried
on how to handle these thousands of kanjis, or should I just pick whichever I need... manually?

Also, if I'm using texture fonts, then what about resolution? Would it be an issue? or should I just have it large and scale it down? Or is there other way?

It's still hazy for me on this one. Cheers..

With FreeType (https://www.freetype.org/) you can render glyphs from ttf (and some other) files on the fly.

You can render into bitmaps only needed glyphs at desired resolution.

You don't have to store multiple bitmaps for different resolutions, or split single big image font into many bitmaps, since entire set of possible used kanji at desired resolution might not fit into target hardware's caps.

Then you put that glyph cache in texture, build mesh with kanji's bounding rectangles, and render entire dialog/page/paragraph with single draw call.

Other option could be to compose dialog/page/paragraph image in single texture, as one quad or by rows.

Advertisement

Welcome to the hurtful world of text rendering.

If you are not familiar with Unicode, please take the time to read about it, as now your text input can no longer just be based on ascii... you now need to support either utf8, utf16, or utf32

Generally, what happens is only certain features of a language are actually supported. And to be honest... most of the Kanji in Japanese goes unused, and a massive chunk of them are actually unknown.

There's plenty of different solutions to this problem. Build a texture atlas dynamically at runtime. If a character shows up that you don't have in your atlas already, create it.

Prebake the atlas ahead of time.

Implement vector rendering.

Implement Chromium, etcetera, etcetera.

I use the Sean Barrett's STB truetype library to parse TT files with OpenGL in C++, then update a quad buffer at runtime for drawing. Fast and simple. STB is excellent because it's one independent file. Never tried to draw Kanji. However.. there are probably better methods than this approach. I would try the solution in vstrakh's reply first.

Fonts are a nightmare. I used FreeFype in my app as Vstrakh recommends. It was quite a lot of work compared to other methods I have used in the past but the results are wonderful. One thing I really like about it is that it allows me to have fonts in very high resolutions for devices with higher resolutions and lower resolution fonts for lower devices. The basic idea is you create a texture with all the glyphs on and then draw lots of quads each with a different glyph (letter etc) on. There is a lot involved though because even simple things such as some letters being smaller than others means you need to space each out differently etc. I didn't find FreeType overly helpful in this regard, it took me a lot of trial and error to figure it all out even with examples and a tutorial of sorts. I will say though it is powerful, flexible and produces appealing results at a good speed when using it as a texture atlas. I can't say for certain if it supports Japanese characters but it does support vertical layouts and mentions Japanese as one of the examples of something that could use a verital layout.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

I use NanoVG for my GUI needs, which gives OpenGL font rendering and vector drawing capabilities in one lightweight package. It uses Sean Barrett's library internally for TTF parsing, and can also optionally use Freetype. Prior to that I always used Win32 APIs for font rendering, but I have been enjoying the ease of this approach and performance doesn't seem like a problem so far.

Advertisement
Thanks for the answers guys. I'll check on what you guys have suggested, starting from vstrakh's answer first.

I forgot to mention that this isn't for Windows primarily, but for Android and iOS. Not to mention the iOS uses Metal and the Android is expected to have Vulkan optionally..reason why I don't bother saying what graphics API anymore as it's not the main issue.

Fonts are a nightmare. I used FreeFype in my app as Vstrakh recommends. It was quite a lot of work compared to other methods I have used in the past but the results are wonderful. One thing I really like about it is that it allows me to have fonts in very high resolutions for devices with higher resolutions and lower resolution fonts for lower devices. The basic idea is you create a texture with all the glyphs on and then draw lots of quads each with a different glyph (letter etc) on. There is a lot involved though because even simple things such as some letters being smaller than others means you need to space each out differently etc. I didn't find FreeType overly helpful in this regard, it took me a lot of trial and error to figure it all out even with examples and a tutorial of sorts. I will say though it is powerful, flexible and produces appealing results at a good speed when using it as a texture atlas. I can't say for certain if it supports Japanese characters but it does support vertical layouts and mentions Japanese as one of the examples of something that could use a verital layout.

You know FreeType gives you the information right? You init the face type, create the new face (font) and from there the face has face->glyph->advance.x, bearing is in face->glyph->bitmap_left and _top for offsets.

The first tutorial I found as I did it a while ago: http://lazyfoo.net/tutorials/OpenGL/23_freetype_fonts/index.php

"Those who would give up essential liberty to purchase a little temporary safety deserve neither liberty nor safety." --Benjamin Franklin

Fonts are a nightmare. I used FreeFype in my app as Vstrakh recommends. It was quite a lot of work compared to other methods I have used in the past but the results are wonderful. One thing I really like about it is that it allows me to have fonts in very high resolutions for devices with higher resolutions and lower resolution fonts for lower devices. The basic idea is you create a texture with all the glyphs on and then draw lots of quads each with a different glyph (letter etc) on. There is a lot involved though because even simple things such as some letters being smaller than others means you need to space each out differently etc. I didn't find FreeType overly helpful in this regard, it took me a lot of trial and error to figure it all out even with examples and a tutorial of sorts. I will say though it is powerful, flexible and produces appealing results at a good speed when using it as a texture atlas. I can't say for certain if it supports Japanese characters but it does support vertical layouts and mentions Japanese as one of the examples of something that could use a verital layout.

You know FreeType gives you the information right? You init the face type, create the new face (font) and from there the face has face->glyph->advance.x, bearing is in face->glyph->bitmap_left and _top for offsets.

The first tutorial I found as I did it a while ago: http://lazyfoo.net/tutorials/OpenGL/23_freetype_fonts/index.php

Yeah I am aware. I was referencing to you then having to use those values to move your quads into the right position. I found that part the most challenging aspect even with the documentation.

Interested in Fractals? Check out my App, Fractal Scout, free on the Google Play store.

This topic is closed to new replies.

Advertisement