[cairo] solutions for display text with Asian fonts

Jihe Wei jihe.wei at gmail.com
Tue Jun 5 07:11:35 PDT 2012


Hi,Uli
thank you.cairo_show_glyphs() works,can display english words correctly.
but Asian fonts(Chinese, Japanese and Korean), how to, anyidea?

I tried FT_Select_Charmap( face, FT_ENCODING_UNICODE ), details  as below,
*1. init*
    FT_Library library;
    FT_Face freetype_face;
    cairo_font_face_t *cairo_face;
    cairo_glyph_t glyph;
    FT_Init_FreeType(&library);
    FT_New_Face(library, "/usr/share/fonts/simhei.ttf", 0, &freetype_face);
    cairo_face = (cairo_font_face_t *)
cairo_ft_font_face_create_for_ft_face( freetype_face, 0);
    cairo_t *cr;
    cairo_surface_t * surface =
cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
            390, 400);
    cr = cairo_create(surface);

    cairo_set_font_face(cr, cairo_face);
    cairo_set_font_size(cr, TEXT_SIZE);
    cairo_set_source_rgb(cr, 1.0, 1.0, 1.0);
    cairo_paint(cr);
    cairo_set_source_rgb(cr,0, 0, 1.0);
*2. try draw on cairo_t*
    void draw(cairo_t *cr, int width, int height) {
    glyph_array_t glyphs;
    glyph_array_init(&glyphs, 1, TEXT_SIZE);
    glyph_array_add_text(&glyphs, cr, "English", 0.0);
    glyph_array_rel_move_to(&glyphs, TEXT_SIZE * 1.5, 0.0);
    glyph_array_add_text(&glyphs, cr, "中文", 0.0);
    glyph_array_show(&glyphs, cr);
   }
*3. glyph_array_add_text*
void glyph_array_add_text(glyph_array_t *glyphs, cairo_t *cr, const char
*s, double spacing) {
    cairo_scaled_font_t *scaled_font;
    cairo_status_t status;
    FT_Face face;
    unsigned long charcode;
    unsigned int index;
    cairo_text_extents_t extents;
    const char *p;
    FT_Vector kerning;
    double kern_x;
    int first = true;
    scaled_font = cairo_get_scaled_font(cr);
    status = cairo_scaled_font_status(scaled_font);
    face = cairo_ft_scaled_font_lock_face(scaled_font);

    FT_Select_Charmap( face, FT_ENCODING_UNICODE );
    FT_Set_Char_Size(face, 16 << 6, 16 << 6, 300, 300);
    p = s;
    while (*p) {
        charcode = *p;
        index = FT_Get_Char_Index(face, charcode);
        glyphs->glyph_list[glyphs->num_glyphs].index = index;
        if (first) {
            first = false;
            glyphs->glyph_list[glyphs->num_glyphs].x = glyphs->x;
            glyphs->glyph_list[glyphs->num_glyphs].y = glyphs->y;
        } else {
            cairo_glyph_extents(cr, &glyphs->glyph_list[glyphs->num_glyphs
- 1],
                    1, &extents);
            FT_Get_Kerning(face,
                    glyphs->glyph_list[glyphs->num_glyphs - 1].index,
                    glyphs->glyph_list[glyphs->num_glyphs].index,
                    FT_KERNING_UNSCALED, &kerning);
            kern_x = DOUBLE_FROM_26_6(kerning.x);
            glyphs->glyph_list[glyphs->num_glyphs].x =
                    glyphs->glyph_list[glyphs->num_glyphs - 1].x
                            + extents.x_advance + kern_x + spacing;
            glyphs->glyph_list[glyphs->num_glyphs].y =
                    glyphs->glyph_list[glyphs->num_glyphs - 1].y
                            + extents.y_advance;
        }
        cairo_glyph_extents(cr, &glyphs->glyph_list[glyphs->num_glyphs], 1,
                &extents);
        glyphs->x = glyphs->glyph_list[glyphs->num_glyphs].x +
extents.x_advance
                + spacing;
        glyphs->y = glyphs->glyph_list[glyphs->num_glyphs].y
                + extents.y_advance;
        p++;
        glyphs->num_glyphs++;
    }
    cairo_ft_scaled_font_unlock_face(scaled_font);
}
*4. glyph_array_show*
    void glyph_array_show(glyph_array_t *glyphs, cairo_t *cr) {
    cairo_show_glyphs(cr, glyphs->glyph_list, glyphs->num_glyphs);
}

Thanks
Wei


2012/6/4 Uli Schlachter <psychon at znc.in>

> Hi,
>
>
> On 04.06.2012 09:57, Jihe Wei wrote:
>
>> When we try to show text with multi-language,
>> like Asian fonts(Chinese, Japanese and Korean).
>> But can't display them except some squares.
>>
>> also
>> http://blog.vlad1.com/2007/12/**11/graphics-in-mozilla/<http://blog.vlad1.com/2007/12/11/graphics-in-mozilla/>
>> says "The toy font API that’s present in Cairo can be ignored,
>> as it does not support international text and is there only for
>> convenience
>> for smaller projects."
>>
>> so what's your opinion?
>>
>
> So let's first make it clear what said toy font API is:
> cairo_show_text() and cairo_select_font_face()
>
> What should applications use instead? The docs point at
> cairo_show_glyphs() / cairo_show_text_glyphs() and font-backend specific
> functions like e.g. cairo_ft_font_face_create_for_**pattern().
>
> However, for these APIs, you are rendering glyphs instead of a text.
> Converting your text into glyphs is something that cairo does not do for
> you (unless you use the toy text API). If you want a solution that should
> work everywhere, you should take a look at Pango[0]. With PangoCairo, you
> can make Pango draw to a cairo_t and thus continue using cairo. Pango will
> convert your text to glyphs and use the non-toy API for doing its job.
>
> Hopefully this helped.
> Uli
>
> [0] http://www.pango.org
>
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.cairographics.org/archives/cairo/attachments/20120605/7b3ffd4b/attachment.htm>


More information about the cairo mailing list