2016-04-18 103 views
6

Ho un sistema che ha solo le librerie freetype2 e cairo disponibili. Quello che voglio ottenere è:Layout e rendering dei font con cairo e freetype

  • ottenere i glifi di testo UTF-8
  • layouting il testo, la memorizzazione delle informazioni di posizione (da me)
  • ottenere percorsi Cairo per ogni glifo per il rendering

Sfortunatamente la documentazione non spiega realmente come dovrebbe essere fatto, poiché si aspetta che uno usi una libreria di livello superiore come Pango.

Quello che penso potrebbe essere giusta è: Creare un font scalato con cairo_scaled_font_create e quindi recuperare i glifi per il testo utilizzando cairo_scaled_font_text_to_glyphs. cairo_glyph_extents quindi fornisce le estensioni per ciascun glifo. Ma come posso ottenere cose come il kerning e l'anticipo? Inoltre, come posso ottenere percorsi per ogni carattere?

Ci sono altre risorse su questo argomento? Queste funzioni sono la via prevista?

+0

Hai guardato [questa pagina doc Cairo] (http://www.cairographics.org/manual/ cairo-FreeType-Fonts.html)? Non ho mai usato FreeType con Cairo, quindi non so se questa è la chiave, ma se risolve il tuo problema, posso postare una risposta. – oldtechaa

+0

Questa pagina spiega come creare un 'cairo_font_face_t' usando un carattere freetype. Quindi si utilizza questo tipo di carattere per creare un carattere ridimensionato. Da lì in poi la strada non è chiara. – maxdev

+0

È quindi possibile utilizzare la funzionalità di testo di Cairo per utilizzare FreeType 'cairo_font_face_t', impaginare il testo e renderizzare. Non è raccomandato; vedere [la pagina del Cairo] (http://www.cairographics.org/manual/cairo-text.html#cairo-text.description) riguardante l'uso di Pango. Dovrebbe funzionare comunque, dal momento che non puoi usare anche Pango.Perché la macchina non ha altre librerie disponibili? – oldtechaa

risposta

4

Ok, ho trovato ciò che è necessario.

Per prima cosa è necessario creare un cairo_scaled_font_t che rappresenti un carattere di una dimensione specifica. Per fare ciò, si può semplicemente usare cairo_get_scaled_font dopo aver impostato un font, crea un font in scala per le impostazioni correnti nel contesto.

Successivamente, si converte il testo di input utilizzando cairo_scaled_font_text_to_glyphs, questo fornisce una serie di glifi e anche i cluster come output. I mapping dei cluster rappresentano quale parte della stringa UTF-8 appartiene ai glifi corrispondenti nell'array glifi.

Per ottenere le estensioni dei glifi, viene utilizzato cairo_scaled_font_glyph_extents. Fornisce dimensioni, avanzamenti e cuscinetti di ciascun glifo/set di glifi.

Infine, i percorsi per glifi possono essere inseriti nel contesto utilizzando cairo_glyph_path. Questi percorsi possono quindi essere disegnati come desiderato.

L'esempio seguente converte una stringa di input per i glifi, recupera le loro estensioni e li rende:

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

Queste funzioni sembrano essere il modo migliore, considerando il sistema di testo del Cairo. Mostra solo ancora di più che il Cairo non è davvero pensato per il testo. Non sarà in grado di fare realmente crenature o percorsi. Credo che Pango avrebbe il suo codice complesso per fare quelle cose.

Per il miglior avanzamento di Ghost, ti consiglio di eseguire il porting di Pango, poiché probabilmente tu (o qualcun altro) lo vorrai comunque.

+0

Vedere il mio ultimo commento - Voglio cairo per darmi le informazioni di layout e i percorsi per un glifo. Questa informazione deve essere lì, perché Pango si basa su di esso. Non riesco a trovare alcuna buona documentazione su di esso. Beh, il problema è che Pango richiede cose come fontconfig e la libreria gnome che non voglio in Ghost - queste librerie forzano le decisioni di progettazione che non voglio accettare, solo per mettere a posto i miei personaggi. Grazie per il tuo aiuto, per quanto sia bello vedere interesse :) – maxdev

+1

Direi quindi di utilizzare le funzioni che hai descritto. Sembrano essere la strada da percorrere. Il problema qui è che il Cairo è così limitante, senza crudeltà e senza un modo chiaro per creare facilmente un percorso dai glifi. Puoi praticamente usare solo 'show_glyphs' o' show_text_glyphs' per mostrare glifi. Modificherò la mia risposta ora capisco un po 'di più. – oldtechaa

+0

Vedi altra risposta, grazie per gli sforzi però! :-) – maxdev