[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