Behdad Esfahbod's daily notes on GNOME, Pango, Fedora, Persian Computing, Bob Dylan, and Dan Bern!

My Photo
Name:
Location: Toronto, Ontario, Canada

Ask Google.

Contact info
Google
Hacker Emblem Become a Friend of GNOME I Power Blogger
follow me on Twitter
Archives
July 2003
August 2003
October 2003
November 2003
December 2003
March 2004
April 2004
May 2004
July 2004
August 2004
September 2004
November 2004
March 2005
April 2005
May 2005
June 2005
July 2005
August 2005
September 2005
October 2005
November 2005
December 2005
January 2006
February 2006
March 2006
April 2006
May 2006
June 2006
July 2006
August 2006
September 2006
October 2006
November 2006
December 2006
January 2007
February 2007
March 2007
April 2007
May 2007
June 2007
July 2007
August 2007
September 2007
October 2007
November 2007
December 2007
January 2008
February 2008
March 2008
April 2008
May 2008
June 2008
July 2008
August 2008
October 2008
November 2008
December 2008
January 2009
March 2009
April 2009
May 2009
June 2009
July 2009
August 2009
November 2009
December 2009
March 2010
April 2010
May 2010
June 2010
July 2010
October 2010
November 2010
April 2011
May 2011
August 2011
September 2011
October 2011
November 2011
November 2012
June 2013
January 2014
May 2015
McEs, A Hacker Life
Friday, May 01, 2015
 How to use custom application fonts with Pango

I am at the Libre Graphics Meeting in Toronto this week, which means that I got to talk to GIMP and Inkscape developers after many years, and was reminded that Pango still does not make it easy to use custom (aka. application) fonts, and it still does not allow turning OpenType features on or off.  So I decided to give Pango some love.

OpenType features is bug 738505.  Akira and Matthias wrote the initial patch, but there are certain complexities in handling the attributes that needs to be fixed before this can go in.  I'll see if I can get myself to do that tomorrow.

Custom fonts is a different issue.  And by custom fonts I mean when an application wants to use a font file that it ships, but is not installed in the system or user font directories.  Most of the times when people have this request, they also don't want any system fonts, ie, they only want their custom fonts.  A font viewer is a basic example of this that we never had a good solution for.

Webfonts, and other embedded fonts, are another use case.  Eg, a document might bundle fonts that it uses.  Many times, the document would want to refer to the font using font family name, so in that case you want the font to be added to the system fonts and go through the font matching process.

Back in 2006 when we considered pangocairo the only backend we care about, I proposed that we add pangocairo API to use a certain cairo_face_t.  The thinking was that by doing it in the pangocairo layer, we don't have to do it in individual platform backends (pangofc, pangowin32, pangoatsui / pangocoretext).  That, however, never happened, because I was too lazy to implement it, but also because it was actually a lot of tricky work, to make the generic pangofc layer understand this custom object...

I have since changed my mind on how this should be done.  Over the years different groups asked how they do this, I've had suggested different variations of the same solution: custom Fontconfig config; and Win32 / CoreText APIs on other platforms.  Ie, do it at font host layer, not Pango layer.  It's a legitimate approach, if not most convenient.

Here is one way to do it, using fontconfig API:

Before calling into Pango, do this:
This way Pango will only see your fonts.  If you want to add your fonts but also see the system fonts, you can skip the first step.  That will make your custom fonts visible to all Pango users within the process, including Gtk+ and its font selection dialog.  If, instead, you want to limit it to a particular document, we need something more involved; we talk about further down.

Recently I needed to do something similar in Noto's test suite, which is written in Python.  Since we currently don't have fontconfig Python bindings, I either would have had to be bothered to do a ctypes binding of the few functions I needed, or find an even simpler solution.  Which is:

Before calling into Pango, do this:
That's it.  Here's are the two steps for Noto: 1 and 2.

Now, this sounds easy, and works for very limited usecases.  But for it to be useful in apps like The GIMP or Inkscape, there are a few issues that need to be handled.  And I'm writing this post to raise enough interest from Akira, Matthias, Khaled, and others, to help fix these so we can have a great custom-font experience.  Writing a tutorial when these are all fixed would be great, but for now, this post is documentation enough!

First, the custom XML currently has to have a cachedir element or fontconfig warns.  That's annoying to say the least.  Filed here.  For now, you can use "<cachedir prefix="xdg">fontconfig</cachedir>" and that should work with recent-enough versions of fontconfig that understand the prefix="xdg".  Older version will ignore it and try to create a fontconfig directory under the current directory and use as cache, so beware of that.

Python / JS / etc bindings for fontconfig will be useful if we are pushing in this direction.  Filed here.

Another problem with the suggested setups above is that it works for non-GTK use-cases, like a game, test suite, etc.  But in most usecases, you definitely don't want your menus and other GUI elements to use the custom fonts.  In the case of a document editor or graphics editor, you might want to add custom fonts per document.  You can do that by using a separate PangoFcFontMap instance for each custom need.  I outlined that like this before:
  1. FcConfigCreate()
  2. FcConfigAppFontAddFile()
  3. pango_cairo_font_map_new_for_font_type()
  4. Use that PangoFontMap to create your context, etc.
  5. Every time you want to use Pango with that context, FcConfigSetCurrent the above config.  Then reset it back to whatever it was before.
This will allow you to use Pango with custom-only fonts in parts of the application.  If you also want the system fonts to be visible in this private font map, you can use the obscurely named FcInitLoadConfigAndFonts() instead of FcConfigCreate().

That's not awfully bad.  Except that the last step is very cumbersome and a recipe for disaster.  That step can be avoided if we have API to attach a custom FcConfig to a PangoFcFontMap.  Owen and I talked about it years ago and I filed a bug, but never happened... until yesterday.

I added pango_fc_font_map_set_config() yesterday, and just added pango_fc_font_map_config_changed().  So you can attach your private FcConfig to a private PangoFcFontMap, inform the font map every time you change the FcConfig (eg, add more fonts to it), and you should be able to use that font map to create layouts and use normally, without switching FcConfig's all the time.  However, remember: I wrote the code, but I didn't test it.  So a brave first user is wanted.

Then there's the set of issues with Fontconfig; the fact that to add font or configuration to an FcConfig, you need to have those in files, and can't add from memory blobs.  Fixing that should be fairly easy, and I filed those last year.  Would be great if we can fix them soon.  Here's one for font blobs, and another for configuration XML.

Another issue with using custom fonts is that every time you add a custom font, Fontconfig has to scan it.  Ie, you get no benefit from the Fontconfig font cache.  This can be really slow for huge fonts.  And became five times slower when the Adobe CFF rasterizer was integrated in FreeType.  I tried a few different approaches to speed it up.  Removing the (prematurely added) FC_HASH helped.  But there's more that can be done.  That bug is here.

Now, here's the one remaining issue that I don't have a full answer for: by sidestepping the default fontconfig configuration, you will miss some essential features.  Right now those are: synthetic italics, synthetic bold, and scaling of bitmap fonts.  The reason is that these are encoded in configuration files instead of in the library.  That sounds slightly over-engineered, and I like to improve it, but as of right now, that is the way it is.  You also will lose system-wide and user's configuration.

Sometimes that's not a problem.  For example, in the Noto test suite, we don't want any system or user configuration or any synthetic emboldening or italics, so the FcConfigCreate() approach suites those kinds of scenarios perfectly well.  Same about the preview part of a font-viewer, or other use cases where being system-independent is a goal.  But in other situations it might not be desirable.

I can, of course, suggest that anyone creating a custom FcConfig to add the essential configuration to it; Eg. bitmap scaling, synthetic bold and italic, essential aliases, user's configuration.  But that still leaves out generic aliases, system config, etc.  And I don't like that approach, because that spreads our default configuration all around Fontconfig clients and will create a mess that we would have to clean up every time we change how we do configuration.  It's a leaky abstraction.

Quite fortunately, there's an almost-perfect solution for that.  The obscure FcInitLoadConfig() function creates a new FcConfig and loads the default configuration files, but does not load any fonts referred to from those configuration files.  As such, you can go ahead and add your own fonts to it, but still benefit from the configuration.  Don't complain, if the configuration does undesirable font aliasing or other stuff.  I'm hugely relieved that this might do exactly what we need.  I have not tested this, so if you test, please kindly let me know how it works.  I cannot think of obvious undesirable behaviors from this approach.

So, to wrap up, assuming you would use Pango to be released soon, this is how you do custom fonts with PangoCairoFc:
  1. Create a custom FcConfig:
    • Use FcConfigCreate() if you don't want any system / user fonts or configuration whatsoever, neither you want any synthetic or other manipulations,
    • Use FcInitLoadConfig() if you want system / user configuration, but no system / user fonts,
    •  Use FcInitLoadConfigAndFonts() if you want system / user configuration and fonts visible in your private font map,
  2. Call FcConfigParseAndLoad() to add any custom configuration you want to add.  Such configuration can add custom font directories, or you can use next step,
  3. Call FcConfigAppFontAddFile() or FcConfigAppFontAddDir() to add custom fonts,
  4. Call pango_cairo_font_map_new_for_font_type(CAIRO_FONT_TYPE_FT), to create a private PangoCairoFcFontMap, which is a subclass of PangoFcFontMap, which is a subclass of PangoFontMap,
  5. Call pango_fc_font_map_set_config() to attach your custom FcConfig to your private PangoFcFontMap,
  6. Call pango_fc_font_map_config_changed() whenever you add new fonts to your custom FcConfig,
  7. Use that PangoFontMap to create your context, etc, and use normally.
You can optimize the logic to use the default font map if there are no custom fonts involved, and do the above otherwise.

This can trivially be adapted to the PangoFT2 backend by the way.

If your application has its own font dialog, then you can implement that using the private font map as well, and things should work.  But if you use the GTK+ font dialog, currently you can't attach your private font map to the font dialog instance.  I filed a request for that.

While there, let me address the issue of having or not having to restart applications when new fonts are installed.  As I covered in my State of Text Rendering in 2009 and presented at the Gran Canaria Desktop Summit, online font addition/removal should Just Work in GNOME.  I implemented that in 2008.  Indeed, it does in simple applications.  They are a bit slow (~4 seconds before new font shows up), so I filed a bug to shorten the delay.  However, a lot is not working:
As for pangocairo API to use a cairo_font_face_t, I still think that would be useful, but much less so than before.  Also, it won't be very useful until cairo adds API to create a cairo_font_face_t from a font file or memory blob.  Right now the only way to do that is to write code for the FreeType, Win32, and ATSUI / CoreText font backends of cairo separately.

Even if you try to do that, you will hit a very well-known problem with AddFontMemResourceEx(); which is: if you try to add a custom font with a family name that matches that of an existing font on the system, when you try to use the font, you might end up using the version installed on the system.  Ie. you can add fonts to the system, but you can't reliably address them.  The hack that Firefox, HarfBuzz, and others use to work around this is to modify the font data before calling AddFontMemResourceEx() to set a unique font family name on it, so they can be sure there will be no collision.  Here's the HarfBuzz code for that.

Anyway, I hope this write up helps developers, after confusing them, implement custom fonts in their applications, and motivate others to help me fix remaining issues and generate examples and better documentation.

While writing this, I ended up doing some bug triage and closing obsolete issues around Pango, Fontconfig, and cairo, which is always nice :D.

Anyway, this alone makes me really happy that I attended LGM.  The HarfBuzz Documentation Sprint was also very productive, but takes a couple more weeks to get to a stage that we can show off what we produced.

Labels: , , ,

Thursday, August 11, 2011
 Can I has intel tablet?

So I missed the intel party it seems. I assume the tablets are GLES2-ready and have a fair pixel density. If that is the case, I can make good use of one for OpenGL-based text rendering I'm experimenting with. If there are leftovers at the summit, I'd happily take one!

kthxbye :)

Labels: , , , ,

Sunday, August 07, 2011
 Arrived at the Desktop Summit

Just got to the Desktop Summit in Berlin. It's lovely seeing everyone after two years.

I'm running Text Layout Summit August 9th to 12th, so come find me for some font and text chat!

Labels: , , ,

Wednesday, June 30, 2010
 June

June 18th was my last day at Red Hat.

I spent last week road-tripping to Eastern Canada with my friends.

In a couple of weeks I will start working for Google Canada in the Waterloo office. I will be working for a large part on HarfBuzz as part of the Chrome / ChromeOS team.

Unfortunately the setup also means that I have to skip this year's GUADEC as I can't get a visa on time :(.

I will keep my current GNOME duties, namely maintaining the text stack (fribidi, fontconfig, harfbuzz, pango, etc) as well as vte. The break may give me some time hacking on things I couldn't get the time to hack on before even. We'll see.

That's all for June.

Labels: , ,

Wednesday, November 18, 2009
 Pango vs HarfBuzz

Since the rewritten HarfBuzz is shaping up fast and getting lots of Buzz these days, I get asked the same question again and again: "Will HarfBuzz replace Pango?" This post tries to answer that.


Short answer: No, not at all! Pango is here to stay. It will change, but only get better.


Long answer:

Pango provides two levels of API: A low-level and a high-level.

Low level API: What I can the "three pillars of pango":

High-level API: Pango's high-level API consists of the PangoLayout object, aka "here's a piece of text render it in this box I don't care what you do."

Of these, HarfBuzz only does shaping. That is, hb_shape() is functionally equivalent to pango_shape().


API implications: Here is how moving to HarfBuzz affects the Pango API:

Pango Modules: pango_shape() calls into Pango shaper modules to get the actual shaping done. There are two kinds Pango shaper modules depending on what they do (the API is the same, so Pango doesn't differentiate between the two classes):
Now, as HarfBuzz becomes the shaping engine on Linux, all those script-specific modules will be removed and basic-fc will simply call into hb_shape(). That's indeed what the basic-fc.c in the harfbuzz-ng-external does.

Later on, when we add support for native win32, CoreText, Graphite, and m17n to HarfBuzz, all those other modules will also be replaced by HarfBuzz-calling equivalents.

Which one to use: Pango or HarfBuzz? Depends.

PangoLayout is designed to be the 'render this text in this box I don't care how' kind of API. That's a perfect fit for GUI toolkits like GTK+, but not suitable for lots of other uses, for example:
while in many of those cases PangoLayout can be made to work (with much pain, mind you), Pango still provides the lower level API and lots of other bits and pieces to get something going. What it doesn't give full control on however is font selection, which happens to be a deal-breaker for many of those usecases (browsers following CSS rules, etc).

So, each of those kinds of applications need to assess the pros and cons of using Pango vs using HarBuzz and providing all the other bits themselves. For example, HarfBuzz doesn't provide:
There's also a hybrid use possible: to borrow those pieces from Pango on platforms that it's feasable, but drive HarfBuzz directly. It all depends. When in doubt, ask! We have a mailing list.

That said, Firefox will use HarfBuzz as soon as it's ready (there are patches circulating around). Google is using old HarfBuzz for their Webkit and will port to the new one. I'm also attending the Webkit-GTK hackfest in December to port that to the new HarfBuzz. We'll work towards sharing the HarfBuzz-dealing code among Webkit backends.

This is already a long post. Let me finish now. Hope I made it a tiny bit more clear.

Labels: , , ,

Wednesday, November 04, 2009
 HarfBuzz HackFest

Here is a quick update re HarfBuzz:

During May and August I finished rewriting the OpenType Layout engine to use mmap()ed font files. This is in Pango 1.26.x already. Pango and fontconfig also received a lot more optimization love. That deserves a long and separate blogpost. The net result is that the text stack's memory usage is considerably lower now. All this goodness will be in the upcoming Fedora 12.

In October, I attended the 33rd Internationalization and Unicode Conference in San Jose to present the free software text stack (useless slides) as well as present and promote HarfBuzz (useless slides). That was a very fruitful event and I received lots of interest from many major industry players. With the liberal license that we are releasing HarfBuzz under, we expect broad adoption, which is exactly what we are looking for.

This week, Jonathan Kew and myself are having a small HarfBuzz HackFest here in Mozilla's Toronto office. Here's what we have got done so far:
At the rate this is developing, by the end of the week we should have basic shaper (Latin, Cyrillic, CJK, ...) and Arabic+Syriac working perfectly and tackling Indic family. We're closer to 1.0 than you may think!

Labels: , , ,

Tuesday, November 25, 2008
 Text-on-path with cairo

Cairotwisted is the name a piece of code I wrote using pangocairo to lay text on a path. Over the years many people have found it useful, so here is a public post to make sure it's easier to find on the interwebs.

cairotwisted
The code is shipped in Pango tarball under examples/cairotwisted.c and can be browsed here. Click on the thumbnail to see the full size image output.

At the core of it there is a function to map one path onto another one. This is done by parameterizing the second path and computing it's gradient (see the code).

Parameterizing a Bezier curve uniformly is not easy though. I currently flatten curves to lines and use that, but that has its own down sides as the error introduced in the gradient can magnify out of bound. Any ideas?

Labels: , , ,

Monday, June 02, 2008
 Online font installation

Just submitted patches for GTK+ and gnome-settings-daemon to monitor all fontconfig configuration and react to changes.

What this means is that with the patches in place:
Interestingly, no changes in Pango were needed.

Next step, detect missing fonts and make PackageKit show a notification offering to install needed fonts.

Labels: , , ,

Wednesday, November 28, 2007
 The Most Beautiful Persian OpenType Font

Glad I asked for it last month!

Apparently the Supreme Council of ICT of Iran has released the first ever OpenType Persian Nastaliq font. This is of great importance because previously all Persian Nastaliq solutions were Windows-only systems requiring custom rendering engine installed and only worked with select applications. Not anymore!

Anyway, very nice outcome of a governmental-funded project in Iran. I quite appreciate that. The font can be downloaded here.

Now to the interesting part. Again, Pango 1.18.3 and gedit:

IranNastaliq in Pango

The font itself is far from perfect in its OpenType tables, but it's a great start. I've been wanting that for so long... The only issue is that the font doesn't hold a clear license. Got to sort that out and voila! I know, I'm clearly excited. Very excited.

Labels: , , , , , ,

Tuesday, October 16, 2007
 Episode VI: Return of Federico

Federico:

Funny, how I read your post after Boston Summit, and I've had in fact discussed both issues with Owen Taylor while there. Lets see:

First, increasing cairo scaled font cache size: You saw a 230 KB process size increase when increasing cache size from 256 to 2048. Well, here's a little secret I decided not to disclose until someone notices it, and you kinda qualify now: Cairo doesn't free glyph renderings after uploading them to the X server! You definitely need them if you are using the image surface, but most processes don't. So, you've got the smart X server hashing and reusing glyph renderings, and cairo-using processes keeping a copy around, for no good. Fix that and happily increase cache size to 2048 without 230 KB size increase!

Next, time spent in HarfBuzz, and particularly recreating and enlarging buffers all the time. As my summit hacking project I took on optimizing HarfBuzz. In short, I did:
All in all, in my measurements, these three made repeated text layout 10 to 20 percent faster for 1) very long paragraphs, and 2) using fonts with many many looksup like Nafees Nastaliq (more than 100). They made no difference for regular small text+font combinations.

Mandatory screenshot of Nafees Nastaliq after I fixed a bug to tolerate a font bug in the GDEF table. I'm surprised how good actually it worked with the synthesized GDEF Pango put together for it, but now it works perfect (again):

Nafees Nastaliq in Pango

Labels: , , , ,

Wednesday, June 20, 2007
 Debian Patch Review

Thanks everyone for comments on JDS patch review yesterday. Thanks to lool for the link, I reviewed Debian's pango and vte patches this morning on the way to office.All in all, seems like someone's been doing their homework. Nice!

Who's next? It could be you!

Labels: , ,

Tuesday, June 19, 2007
 JDS Patch Review

(Note: After receiving two comments and rereading my previous post, I removed it in accordance to CoC which I have volunteerly signed. Well, we're cool now.)

Seeing people commenting on JDS patches for their packages, I couldn't help but checking pango, cairo, and vte patches they ship. Having reviewed them, I thought I should provide some feedback :). I'm posting here, hoping that other GNOME hackers pick this up too. Later we can move on to collectively review other vendors' patches too, and help the over-busy maintainers push the right patches upstream and drop/fix the wrong ones. Not every project has a sebuild, right? ;) Brian Cameron has been doing a great job doing that for opensolaris already, but there's more room.
All in all, very good for cairo, but can do better for vte and pango.

Labels: , , ,

Thursday, May 24, 2007
 Foundations of Gtk+ Development

Yesterday I shortly reviewed the new Gtk+ book by Andrew Krause, Foundations of Gtk+ Development, that I received as an ebook thanks to Apress.

I just searched Pango and cairo in it and read those parts. All in all, pretty good. Doesn't get into Pango at all, just defined PangoFontDescription and Pango markup and uses those with Gtk+ widgets all over the place. As for cairo, it has a short (2 3 page) intro to using cairo to draw paths.

The ebook is quite searchable which is a huge advantage over the dead=tree version. So far so good, but I doubt that I'll do a more in depth review staring at the monitor (or printing the 600+ page beast). Of course the fact that I lost my last pair of glasses this past weekend doesn't help either...

Labels: , , , , ,

Tuesday, May 22, 2007
 Bug Fixing...

...in seventeen minutes.

Labels: ,

Wednesday, May 16, 2007
 Pango OpenType Update

All other modules are ported to new OpenType API now. I really hope I've not broken any of them in the way.

In other news, Pango's Arabic module is now extended to support the N'Ko script. I believe Pango is the first Unicode rendering system to support N'Ko!

Seems like my optimization in Pango's line-breaking algorithm introduced a bug that I hope is fixed now.

Also came across this hilarious bug titled "My microwave doesn't work any more because of gnome"!

Labels: , , , , ,

Monday, May 14, 2007
 Advanced OpenType Features in Pango

Last week I worked on bringing Pango's OpenType engine into shape. Something that has been long overdue. Not anymore.

Pango can now select arbitrary OpenType script and language systems, and in near future arbitrary OpenType features too. The basic, arabic, and syriac modules are ported to use these features. More modules to follow.

Finishing off that feature is addition of another one, that pango will read env vars PANGO_LANGUAGE or LANGUAGE and use that for making better guesses to tag runs of text with languages.

Pango-OpenType

First window is rendering of Pango's test-mixed.txt using the command line pango-view tool.

Second window is the same, but with env var PANGO_LANGUAGE="en:ur". As you can notice, an Arabic font more suitable in style for Urdu is selected instead of my default Persian fonts.

Third window is vertical rendering of the same text. If you look at the last, Japanese, line, in the vertical window, the brackets around the text are correctly rotated, unlike previous versions of Pango.

This and previous works are all in Pango 1.17.0.

Labels: ,

Friday, May 04, 2007
 PangoCairo arbitrary shape rendering

On Tuesday I met Travis Griggs, the author of cairo Smalltalk bindings, who was presenting about cairo at IT360°. He made his slide deck using cairo and Pango, using a background and font that resembled Egyptian papyrus scroll using the cairo beetle logo instead of bullet points. I asked him how he did that and of course the hard way. I then explained how pango supports shape attributes that can be used by a custom made PangoRenderer to render arbitrary shapes.

Last night I thought there should be an easier way to do that, and so I added pango_cairo_context_set_shape_renderer().

Obligatory screenshot:

PangoCairo shape rendering

Source code.

Lets see how long I can go with a Pango feature a day. Today excluded as I'll be driving to LGM. Weekends too as I've finally got myself spending the weekend with species other than computers.

Labels: , , ,

Thursday, May 03, 2007
 Avoiding extra work

When working on justification support in Pango, I found a loop that could use some optimization.

The loop in question is to decide how much of a piece of text (called item. For normal text it typically is the rest of the paragraph) we can fit into the current line. The implementation was removing one character at a time from the end until we find a break spot and the width of remaining chars fits the available width.

Think about it. If the entire item fits the available width the loop is not reached at all, but otherwise, unless the paragraph fits in exactly two lines, we are doing a lot of extra work. Say the paragraph takes 10 lines. Then for the first line we have to remove 9 lines worth of text before finding the right break point. For next line we have to remove 8 lines... and so on. It's quadratic in the number of lines, so to speak.

What I did was to start inserting chars from the beginning of the item until no more fits.

For a really long paragraph (pango/pango-view/test-long-paragraph.txt) the number of times the loop contents are run came down from ~1,000,000 to about 13,000. Not bad.

This was all in my quest to make gedit run faster when viewing a REALLY LONG paragraph. I was under the impression that some silly quadratic algorithms in Pango are responsible for the slow speed, but apparently I'm wrong. In short, Gtk+ recreates the Pango layout on EVERY CURSOR MOVEMENT OR CURSOR BLINKING. This is mostly a result of having a very extensible and powerful text object in Gtk+ that supports multiple marks, some of them may be cursors. I've already attached a patch to improve it for cursor blinking, but that's not very interesting. I want to be able to put my finger on the left or right arrow and don't see a gedit that is frozen as a result. Way to go...

Labels: , ,

Wednesday, May 02, 2007
 Justified text with Pango

...is not unsupported anymore.

pango-view-justify

The first paragraph has positive letter spacing, and then justified. As you see the third line didn't hvae any space chars and so is justified by applying more letter spacing. Now the Latin part has unfairly long words and short lines, but Arabic works much better than I expected.

It's a very simple greedy algorithm. Mathias Hasselmann start writing patches, and hours later and three ~100 line patches, I've got it all working and nicely interacting with letter-spacing too.

Six year old bugzilla entry here.

Labels: , ,

Friday, April 13, 2007
 Metrics hinting and kerning do mix

Metrics hinting is the act of round the advance width of a glyph to whole pixels. It's essential for getting good looking text redering on displays with not-so-high resolutions.

Kerning is the act of adjusting the space between certain pairs of adjacent glyphs. This, too, is essential for high quality text rendering.

Both Pango and Qt have been doing metrics hinting, and doing kerning, practically since forever. But both had this bug that the kerning adjustment were not rounded to whole pixels. So, a single fractional kerning pair could end up canceling all the metrics hinting effort... This was most evident with fonts that have more than a few kerning pairs, like DejaVu Sans. Most apparent in the string "rrrrrrrrrrrrrrrr" with that font.

The bug is no more. Fixed in Qt last week, and in Pango today. Pango commit here.

Before/after:


Further reading: there is a lot more to do in this area. An informative post from David Turner, and an excellent paper from Owen Taylor.

I want to implement some of that stuff in cairo/pango for next major releases, but more important is that all these details are being taken care of in the HarfBuzz unified shaper project that Pango and Qt developers are developing together. Exciting times.

Labels: , , , , ,