Phil Endecott wrote:
> 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.

What about using degrees, but only allow 0, 90, 180 and 270?

> 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.

Yes, looks straightforward :)

> (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;
>        }

Ok.

> 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?

I'd expect the vertical size, because I know the text is rotated and I
break the text in vertical strips.

For string extents with rectangle return values, it should have the same
orientation as usual.

> A couple of other areas where I had to make temporary hacks to get it 
> to compile are dgiff fonts and fixed_advance.

A font could refuse to implement rotated text. Hmm, wouldn't it be
possible to do the rotation in generic code, but with probably more
overhead at load time.

> 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.

So far it looks good. Feel free to ask more questions.

-- 
Best regards,
  Denis Oliver Kropp

.------------------------------------------.
| DirectFB - Hardware accelerated graphics |
| http://www.directfb.org/                 |
"------------------------------------------"

_______________________________________________
directfb-dev mailing list
[email protected]
http://mail.directfb.org/cgi-bin/mailman/listinfo/directfb-dev

Reply via email to