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

Matthew Conway mconway at espial.com
Fri Jan 8 00:46:26 PST 2016


Is there an official bug database / mailing list for Cairo? If so, would 
you like me to raise this bug (if it's not already been done)?


On 08/01/16 00:29, Behdad Esfahbod wrote:
> 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