Dear All, I have thrown together some code for text rotation using FreeType2. The basic stuff works, but there are lots of interactions with other parts of DirectFB that I don't understand, so I thought I would ask for advice now before continuing.
For some background about rotation in FreeType, look at this tutorial: http://www.freetype.org/freetype2/docs/tutorial/step1.html To add rotation to the API, I have extended the DFBFontDescription to include a rotation field, with a corresponding DFDESC flag: diff -ur DirectFB-1.0.0.orig/include/directfb.h DirectFB-1.0.0/include/directfb.h --- DirectFB-1.0.0.orig/include/directfb.h 2007-03-03 20:07:37.000000000 +0000 +++ DirectFB-1.0.0/include/directfb.h 2007-09-30 17:40:55.000000000 +0100 @@ -859,6 +859,7 @@ proportional fonts */ DFDESC_FRACT_HEIGHT = 0x00000020, /* fractional height is set */ DFDESC_FRACT_WIDTH = 0x00000040, /* fractional width is set */ + DFDESC_ROTATION = 0x00000080, /* rotation is set */ } DFBFontDescriptionFlags; /* @@ -888,6 +889,7 @@ int fract_height; int fract_width; + int rotation; } DFBFontDescription; /* I treat these rotation values as quarter-turns anti-clockwise, 0<=rotation<=3. It would be straightforward to supply an arbitrary angle to FreeType, but (a) I don't need it; (b) it would be much harder to implement for any bitmap font providers, and (c) it could make the DisplayString positioning stuff (see below) even more complex. If people do want to allow an arbitrary rotation, we should consider going further and allowing an arbitrary transformation. The rotation is applied in interfaces/IDirectFBFont/idirectfbfont_ft2.c, in Construct(), after the call to FT_New_Face: @@ -714,6 +720,33 @@ return DFB_FAILURE; } + if ((desc->flags & DFDESC_ROTATION) && desc->rotation) { + FT_Matrix* matrix_p = malloc(sizeof(FT_Matrix)); + switch (desc->rotation) { + case 1: matrix_p->xx = 0<<16; matrix_p->xy = -1<<16; + matrix_p->yx = 1<<16; matrix_p->yy = 0<<16; + break; + case 2: matrix_p->xx = -1<<16; matrix_p->xy = 0<<16; + matrix_p->yx = 0<<16; matrix_p->yy = -1<<16; + break; + case 3: matrix_p->xx = 0<<16; matrix_p->xy = 1<<16; + matrix_p->yx = -1<<16; matrix_p->yy = 0<<16; + break; + } + pthread_mutex_lock ( &library_mutex ); + FT_Set_Transform( face, matrix_p, NULL ); + pthread_mutex_unlock ( &library_mutex ); + } + It's straightforward, as you can see, and it seems to work. (I'm not sure if FreeType keeps a copy of the matrix or whether I'm responsible for keeping it around for the life of the face; the malloc() is a temporary hack until I sort this out.) The complex bit is making DrawString work. The approach that I took was to replace the 'advance' field in struct CoreGlyphData with a pair of 'xadvance' and 'yadvance' fields, which can be initialised from the advance.x and advance.y values supplied by FreeType (they are negative when appropriate). Naively I thought that I could simply change a couple of places like: diff -ur DirectFB-1.0.0.orig/src/core/gfxcard.c DirectFB-1.0.0/src/core/gfxcard.c --- DirectFB-1.0.0.orig/src/core/gfxcard.c 2007-03-03 20:23:01.000000000 +0000 +++ DirectFB-1.0.0/src/core/gfxcard.c 2007-09-30 17:05:36.000000000 +0100 @@ -1679,7 +1679,8 @@ } } - x += glyph->advance; + x += glyph->xadvance; + y += glyph->yadvance; prev = current; } Unfortunately, there is more complexity; in particular there are the string width calculating functions, and the logic for centering and right-aligning text. I haven't even used most of this stuff. So: if a user asks for the "width" of a string in a font that is rotated to be vertical, what should they be told? A couple of other areas where I had to make temporary hacks to get it to compile are dgiff fonts and fixed_advance. If someone who better understands all of this would like to help out, that would be much appreciated. Otherwise, some suggestions about how it should all work would be useful. Regards, Phil. _______________________________________________ directfb-dev mailing list [email protected] http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev
