[HarfBuzz] HarfBuzz API design

maciej.jablonski at sosco.com maciej.jablonski at sosco.com
Tue Sep 29 05:29:58 PDT 2009


Hi Behdad,

I have been using the old HarfBuzz code for some time and now I am doing some analysis on the language support in Qt.
There are some gaps there and I am hoping that some of them could be filled with help of new version of HarfBuzz.

I have some thoughts on shaping API of the new HarfBuzz.
Firstly, I wanted to share with the one on shaper's API.

My understanding is that new API allows to achieve something, which used to be achieved with several runs of shaper.
This is due to the features getting applied selectively to substrings with their start and end fields.

I can see though that many clients might not use this functinality anyway as their itemizer already performs the ultimate text split.

What is often the case that the document under shaping uses several styles that are used on and off on small pieces of text.
This could produce performance cost with parsing feature tables again and again.

I agree the current API provides a lot of flexibility and there is nothing under the way to provide a bit lower level APIs to enable some optimizations and more flexibility.

The shaping could be split into two steps. 
 * Precompiling features.
 * Actual shaping.
e.g. a quick proposition of API

void
hb_precompile_features_for_single_pass(
	     hb_precompiled_features_t** precompiled_features, // out
	     hb_face_t    *face, //in
           hb_font_t    *font, //in
           hb_feature_t *features, //in
           unsigned int  num_features); //in
void
hb_free_precompiled_features(
	     hb_precompiled_features_t* precompiled_features); 

void
hb_shape (hb_face_t    *face,
           hb_font_t    *font,
           hb_buffer_t  *buffer,
           hb_precompiled_features_t* precompiled_features);


Where hb_precompiled_features_t would be an opaque type prepared by the particual shaper subsystem. E.g. for open type hb_precompile_features could discard features that are irrelevant and unsupported within the given fontfamily and prepare lists with the indexes of lookup table.

e.g. showing how this could work in opentype font

Let us assume we have got the following features
	"ot:langsys" = "URD "
	"ot:liga" = "1"

Calling hb_precompile_features_for_single_pass with those features would produce the opaque hb_precompiled_features_t object, that for FreeType would store the following instruction:

	For GPOS use the following indexes of lookup tables: e.g. 
	1 (general isol),2 (urdu isol),3(general medi),5(general fina),6(urdu locl)


This way the shaper's client could store the precompiled features internally and reuse them to avoid parsing text in the parameter features as well as resolving script, lang and lookup table indices.

For instance, In Qt alone this behaviour could be used to an advantage as internally in Qt, text fragments often share common CharacterFormat.

As I recon the old harfbuzz code have an optimization that reuses GPOS and GSUB features when parameters does not change between shaper runs. The abovementioned split of functionality would add even more advantage. It would work even when two common feature settings interleaved frequently and it would not prevent HB_Face to be run from multiple threads.

Further step after having these two steps separate would be a possibility to implement querying of effective features e.g. to check whether the shaping is supposed to give satisfactory results.

Regards,

Maciej Jablonski




More information about the HarfBuzz mailing list