2016-04-18 2 views
6

J'ai un système qui a seulement les bibliothèques de freetype2 et de cairo disponibles. Ce que je veux réaliser est:Mise en page de polices et rendu avec cairo et freetype

  • obtenir les glyphes pour un texte UTF-8
  • layouting le texte, le stockage d'informations de position (par moi-même)
  • obtenir des chemins caire pour chaque glyphe pour le rendu

Malheureusement, la documentation n'explique pas vraiment comment cela doit être fait, puisqu'ils s'attendent à ce que l'on utilise une bibliothèque de niveau supérieur comme Pango.

Ce que je pense peut-être raison est la suivante: Créer une police réduite avec cairo_scaled_font_create puis récupérer les glyphes pour le texte en utilisant cairo_scaled_font_text_to_glyphs. cairo_glyph_extents donne ensuite l'étendue de chaque glyphe. Mais comment puis-je obtenir des choses comme le crénage et l'avance? Aussi, comment puis-je obtenir des chemins pour chaque police?

Y a-t-il d'autres ressources sur ce sujet? Ces fonctions sont-elles le moyen attendu?

+0

Avez-vous regardé [cette page doc Caire] (http://www.cairographics.org/manual/ cairo-FreeType-Fonts.html)? Je n'ai jamais utilisé FreeType avec Cairo, donc je ne sais pas si c'est la clé, mais si cela résout votre problème, je peux poster comme réponse. – oldtechaa

+0

Cette page explique comment créer un 'cairo_font_face_t' en utilisant une police freetype. Vous utilisez ensuite cette police pour créer une police à l'échelle. De là, le chemin n'est pas clair. – maxdev

+0

Vous pouvez ensuite utiliser la fonctionnalité de texte de Cairo pour utiliser votre FreeType 'cairo_font_face_t', mettre le texte en page et le rendre. Ce n'est pas recommandé voir [la page du Caire] (http://www.cairographics.org/manual/cairo-text.html#cairo-text.description) concernant l'utilisation de Pango. Cela devrait fonctionner, puisque vous ne pouvez pas utiliser Pango aussi.Pourquoi la machine n'a-t-elle pas d'autres bibliothèques disponibles? – oldtechaa

Répondre

4

Bon, alors j'ai trouvé ce dont j'avais besoin.

Vous devez d'abord créer un cairo_scaled_font_t qui représente une police dans une taille spécifique. Pour ce faire, vous pouvez simplement utiliser cairo_get_scaled_font après avoir défini une police, il crée une police mise à l'échelle pour les paramètres actuels dans le contexte.

Ensuite, vous convertissez le texte d'entrée en utilisant cairo_scaled_font_text_to_glyphs, ce qui donne un tableau de glyphes et également des clusters en sortie. Les mappages de cluster représentent la partie de la chaîne UTF-8 qui appartient aux glyphes correspondants dans le tableau glyph.

Pour obtenir l'étendue des glyphes, cairo_scaled_font_glyph_extents est utilisé. Il donne les dimensions, les avancées et les repères de chaque glyphe/ensemble de glyphes.

Enfin, les chemins pour les glyphes peuvent être mis dans le contexte en utilisant cairo_glyph_path. Ces chemins peuvent ensuite être dessinés comme souhaité.

L'exemple suivant convertit une chaîne d'entrée Glyphes, récupère leur étendue et les rend:

const char* text = "Hello world"; 
int fontSize = 14; 
cairo_font_face_t* fontFace = ...; 

// get the scaled font object 
cairo_set_font_face(cr, fontFace); 
cairo_set_font_size(cr, fontSize); 
auto scaled_face = cairo_get_scaled_font(cr); 

// get glyphs for the text 
cairo_glyph_t* glyphs = NULL; 
int glyph_count; 
cairo_text_cluster_t* clusters = NULL; 
int cluster_count; 
cairo_text_cluster_flags_t clusterflags; 

auto stat = cairo_scaled_font_text_to_glyphs(scaled_face, 0, 0, text, strlen(text), &glyphs, &glyph_count, &clusters, &cluster_count, 
     &clusterflags); 

// check if conversion was successful 
if (stat == CAIRO_STATUS_SUCCESS) { 

    // text paints on bottom line 
    cairo_translate(cr, 0, fontSize); 

    // draw each cluster 
    int glyph_index = 0; 
    int byte_index = 0; 

    for (int i = 0; i < cluster_count; i++) { 
     cairo_text_cluster_t* cluster = &clusters[i]; 
     cairo_glyph_t* clusterglyphs = &glyphs[glyph_index]; 

     // get extents for the glyphs in the cluster 
     cairo_text_extents_t extents; 
     cairo_scaled_font_glyph_extents(scaled_face, clusterglyphs, cluster->num_glyphs, &extents); 
     // ... for later use 

     // put paths for current cluster to context 
     cairo_glyph_path(cr, clusterglyphs, cluster->num_glyphs); 

     // draw black text with green stroke 
     cairo_set_source_rgba(cr, 0.2, 0.2, 0.2, 1.0); 
     cairo_fill_preserve(cr); 
     cairo_set_source_rgba(cr, 0, 1, 0, 1.0); 
     cairo_set_line_width(cr, 0.5); 
     cairo_stroke(cr); 

     // glyph/byte position 
     glyph_index += cluster->num_glyphs; 
     byte_index += cluster->num_bytes; 
    } 
} 
1

Ces fonctions semblent être les meilleures, compte tenu du système de texte du Caire. Cela montre encore plus que Cairo n'est pas vraiment destiné au texte. Il ne sera pas capable de faire du crénage ou des chemins vraiment. Pango, je crois, aurait son propre code complexe pour faire ces choses. Pour le meilleur avancement de Ghost, je recommanderais le portage de Pango, puisque vous (ou quelqu'un d'autre) le voudrez probablement de toute façon.

+0

Voir mon dernier commentaire - Je veux que cairo me donne les informations de mise en page et les chemins pour un glyphe. Cette information doit être là, car Pango s'appuie dessus. Je ne trouve tout simplement pas de bonne documentation à ce sujet. Eh bien, le problème c'est que Pango a besoin de trucs comme fontconfig et la librairie gnome que je ne veux pas dans Ghost - ces libs imposent des décisions de conception que je ne veux pas accepter, juste pour faire apparaître mes personnages. Merci pour votre aide jusqu'ici si agréable de voir l'intérêt :) – maxdev

+1

Je dirais alors d'utiliser les fonctions que vous avez décrites. Ils semblent être le chemin à parcourir. Le problème ici est vraiment que Cairo est si limitant, sans crénage et sans moyen clair de créer facilement un chemin à partir des glyphes. Vous pouvez pratiquement utiliser 'show_glyphs' ou' show_text_glyphs' pour afficher les glyphes. Je vais éditer ma réponse maintenant je comprends un peu plus. – oldtechaa

+0

Voir autre réponse, merci pour les efforts si! :-) – maxdev