Re: Using pango in KMSCON (terminal-emulator)



Hi David,

On 02/16/2013 04:33 PM, David Herrmann wrote:
Hi

I have been working on KMSCON [1] for over a year now and played with
different ways to render text. As I am no expert in font-rendering, I
thought I'd just ask for some advice/review so I can improve kmscon.

Sure.

kmscon is an attempt to replace the linux-console in user-space. For
the purpose of this discussion we can reduce it to an application
similar to libvte (ie., terminal-emulator). That is, it tries to

Interesting.  Didn't know about it.  I've definitely thought about such a
thing before...


render a table of statically sized cells with mostly one glyph per
cell. There are also multi-cell glyphs that span multiple cells.
However, no glyphs ever share a cell (no kerning, ...).

I have played with different font-backends, but I'd really like to
take advantage of all the features that pango provides.

Sure.  But there are limitations to how terminal emulators are supposed to
work that make it hard to plug in full-fledged shaping.


What do I need?

1) I want to feed user-specified font-configuration (name, size, ...)
into pango and then pango should select the right font(s)

It does that.


2) I want pango to provide me "normal" width/height for the selected
font so I can size my cells accordingly.

If the font *is* monospace, you get that.  Otherwise you get whatever Pango
thinks is appropriate.  That's exactly what libvte does, and has been working
just fine so far.


3) Whenever I have to draw a cell, I ask pango to give me a buffer for
the given Unicode char (or better: Unicode string which might contain
combining-characters)

The problem is: to correctly handle Unicode text, you need to give Pango
paragraph at a time.  Anything else will have its shortcomings.  libvte gives
Pango a cell at a time (including combining characters).  That works fine for
many scripts, but not for, say, Indic scripts, or for right-to-left text, or
Arabic shaping, etc.

If you are willing to let go of those, the question becomes, why do you want
to use Pango to begin with?  Ie. what writing systems do you want to support?
 You may not need to use Pango to begin with.


4) It's important that I get full access to the 2D buffer of the
glyph. I sometimes need to change stride/size/etc. and the
hardware-blitters have different constraints. Hence, I cannot use any
opaque "glyph"/gtk/etc. structures but instead need _direct_ buffer
access.

You can get that with pangocairo.  I hear you want to do your own blitting.
That's fine.



What do I currently do?

Font-Management:
1) I start with pango_ft2_font_map_new()
2) For each font I use I create a pango-context from this ft2 font-map.
3) I set the user-selected font-description for the pango-context
4) I render the standard ASCII character set to measure the standard
width, height and baseline
5) These standard sizes are then used as default cell-size

That sounds about right.  I assume you prefer not to have a cairo dependency
added in?  If you don't mind, pangocairo is the preferred backend.  pangoft2
is obsolete.


Glyph-Management:
1) For each glyph I create a temporary pango-layout
2) I set the utf8 text of a single cell (one unicode character with
combining marks) via pango_layout_set_text()
3) I discard everything but the first line
4) I call pango_layout_line_get_pixel_extents to trigger rendering
5) I create an FT_Bitmap of my fixed cell size (not the layout
extents!) and initialize to 0
6) I set FT_PIXEL_MODE_GREY on the bitmap
7) render into bitmap with pango_ft2_render_layout_line()
8) I discard the pango-layout and cache the FT_Bitmap in a hashtable
for future access

This works pretty nice for me. I get smooth AA fonts, I can select
font-names and sizes. The layout works correctly for multi-line
composed glyphs (like those Unicode multi-line integrals) and I am
pretty happy with it.

That's about what vte does, on a conceptual level.  For reference, this is
done in vtedraw.c, if you want to check out.


However, I'd appreciate if someone could tell me whether there are
ways to improve this? And I have some questions that I couldn't figure
out myself:

1) How do I disable AA fonts? How can I enable subpixel rendering?

I don't think pangoft2 supports subpixel rendering.  pangocairo does.  Not
sure about AA.  You may be able to get away with that by calling a function
using pango_ft2_font_map_set_default_substitute() and setting FC_ANTIALIAS in
there.


2) How can I detect system-defaults? That is, let the user define
whether to use AA-fonts, subpixel-rendering, font-name, ... I
currently configure this in kmscon-specific configuration but I'd
prefer font-config options.

You should already be getting fontconfig going.  Just ask for font named
"monospace".  There is not "system default" font size.  There *is* X / GNOME
specific stuff for that, but I assume that's not what you are looking for.


3) How am I notified about font-updates in the system? If the
currently used font is updated I'd like to clear my cache and let
pango re-render the glyphs.

For fontconfig changes, you can do something like this:

http://git.gnome.org/browse/gnome-settings-daemon/tree/plugins/xsettings/fontconfig-monitor.c


4) What should I use as default render-mode? High-DPI (>300?) no AA
but subpixel? Low-DPI AA but no subpixel? I have actually no idea what
looks best... And what to do if I cannot get DPI or subpixel-layout
information for a display?

If anything, you should enable subpixel for low DPI and siable for high.  It's
tricky though.  Best to not try to out-guess the user.  Just do nothing?


5) Does pango do glyph-substitution if used with pango_ft2_*? That is,
if a glyph isn't found in the current font, does it try to find
another font with this glyph?

Yes, Pango does that by default.


My pango-module is available at [2]. I also looked at libvte code.
Despite its dependency on gtk it doesn't do that much different to
kmscon. However, it uses gtk's rendering engine instead of dealing
with pango_ft2 directly. But I haven't figured out how to get easy
access to a glyph buffer without pango_ft2.

Right.  You can get to the pixel buffer using pangocairo.

behdad


Any comments are welcome!
Thanks
David

[1] https://github.com/dvdhrm/kmscon
[2] https://github.com/dvdhrm/kmscon/blob/master/src/font_pango.c


-- 
behdad
http://behdad.org/


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]