[cairo] Intermittent issues using cairo_rotate to rotate an array of text glyphs

Behdad Esfahbod behdad.esfahbod at gmail.com
Thu Jan 7 16:29:47 PST 2016


This is *definitely* a bug, and not how cairo is expected to work.  Looks like
a cache is missing a few parameters or something like that.

On 16-01-07 10:21 AM, Matthew Conway wrote:
> I have modified my code to set the font after doing the transform (previously
> was setting before doing the transform) but doing this doesn't seem to make
> any difference.
> 
> Here's an edited version of the code I've implemented outlining key points for
> cairo and font interactions...
> 
> 
> void draw_glyphs( cairo_t *cr, FT_Face face, unsigned int const x, unsigned
> int const y, paint_t paint )
> {
>     cairo_save( cr );
> 
>     cairo_translate( cr, x, y );
>     cairo_rotate( cr, 1.5708 );
> 
>     /* The freetype {x,y}_scale is a 16.16 value to convert from font units
> 26.6 pixels.  The cairo scaling factor is the size of the em square in pixels.  */
>     cairo_matrix_t font_scale;
>     float units_per_EM_scaled = (float)face->units_per_EM / 64.0f;
>     double sx = (double)( (float)face->size->metrics.x_scale / 65536.0f *
> units_per_EM_scaled );
>     double sy = (double)( (float)face->size->metrics.y_scale / 65536.0f *
> units_per_EM_scaled );
>     cairo_matrix_init_scale( &font_scale, sx, sy );
>     cairo_set_font_matrix( cr, &font_scale);
> 
>     cairo_font_face_t *font_face;
>     font_face = cairo_ft_font_face_create_for_ft_face( face, 0 );
>     cairo_set_font_face( cr, font_face );
> 
>     cairo_set_source_rgba( cr, paint->red, paint->green, paint->blue,
> paint->alpha );
>     cairo_show_glyphs( cr, glyphs, num_glyphs );
> 
>     cairo_identity_matrix( cr );
>     cairo_set_font_face( cr, NULL);
>     cairo_font_face_destroy( font_face );
> 
>     cairo_restore( cr );
> }
> 
> 
> I re-ran the code after commenting out the line:
> 
> /* cairo_set_font_face( cr, font_face ); */
> 
> This resulted in a default font face being used (looks like a cursive font?),
> but the rotation worked perfectly. I never saw any mixed horizontal and
> vertical characters, which to me, indicates there's an issue somewhere in
> Cairo when drawing a "non-default" font face after being rotated.
> 
> 
> BTW, I also re-ran the code using a scaled font and locking / unlocking it,
> but doing that also shows the issue.
> 
> 
> Thanks,
> Matt.
> 
> 
> On 06/01/16 18:38, Bill Spitzak wrote:
>> You have to set the font after you do the transform.
>>
>> However I did not expect this mess, I thought what Cairo did was draw the
>> font as though the transform it was using before was still in effect (ie
>> "font lock", similar to the proposed "line width lock").
>>
>> On Wed, Jan 6, 2016 at 7:45 AM, Matthew Conway <mconway at espial.com
>> <mailto:mconway at espial.com>> wrote:
>>
>>     I'm trying to rotate an array of glyphs (where each glyph represents a
>>     textual character).
>>
>>     Consider the following:
>>
>>     ----------------
>>     | A TEXT LABEL |
>>     ----------------
>>
>>     Where the rectangle is a solid coloured background and the text is drawn
>>     (centered) on top of the rectangle (think subtitles being displayed on a
>>     TV screen).
>>
>>     For some situations, I need to rotate the text label (rectangle and
>>     text) 90 degrees clockwise. I do not expect the text rotation to be
>>     vertical as shown here:
>>
>>     |̄ ̄ ̄ |
>>     | A |
>>     |   |
>>     | T |
>>     | E |
>>     | X |
>>     | T |
>>     |   |
>>     | L |
>>     | A |
>>     | B |
>>     | E |
>>     | L |
>>     |___|
>>
>>     Instead, I am expecting the text to be rotated (in position) with the label.
>>
>>     Sometimes (about 25% of the time), Cairo seems to be rotating random
>>     text characters and drawing them over the top of other correctly rotated
>>     characters.
>>
>>     /* Draw the labels background */
>>     cairo_rectangle( cr, x, y, width, height );
>>     cairo_set_source_rgba( cr, red, green, blue, alpha );
>>     cairo_fill( vg->cairo_context );
>>
>>     /* Rotate 90 degrees clockwise and show the text */cairo_translate( cr,
>>     x, y );
>>     cairo_rotate( cr, 1.5708 );
>>     cairo_show_glyphs( cr, glyphs, num_glyphs );
>>
>>
>>     Notes:
>>     1. The glyphs are created by freetype libraries.
>>     2. The system is using Wayland to draw the text labels.
>>
>>
>>     I've tried quite a few things, the most successful was to add a call to
>>     show_glyphs before translating, which reduces the issue to show
>>     approximatley 5% of the time:
>>
>>     /* Rotate 90 degrees clockwise and show the text */
>>     cairo_show_glyphs( cr, glyphs, num_glyphs );
>>     cairo_translate( cr, x, y );
>>     cairo_rotate( cr, 1.5708 );
>>     cairo_show_glyphs( cr, glyphs, num_glyphs );
>>
>>
>>     I've taken a photo of the screen to show what the issue looks like, it
>>     can be viewed here:
>>     http://postimg.org/image/x4g4fne5h/
>>
>>
>>     I'm using:
>>     - latest cairo 1.14.6
>>     - freetype to create the font glyphs
>>     - Wayland
>>
>>
>>     Thanks,
>>     Matt.
>>     -- 
>>     cairo mailing list
>>     cairo at cairographics.org <mailto:cairo at cairographics.org>
>>     http://lists.cairographics.org/mailman/listinfo/cairo
>>
>>
> 
> 
> 


More information about the cairo mailing list