2016-04-18 25 views
6

Ich habe ein System, das nur die freetype2 und cairo Bibliotheken zur Verfügung hat. Was ich erreichen will ist:Font layouting & rendering mit cairo und freeetype

  • die Glyphen für einen UTF-8-Text bekommen
  • Layouten den Text, Positionsdaten zu speichern (von mir)
  • bekommen kairo Pfade für jede Glyphe für das Rendering

Leider erklärt die Dokumentation nicht wirklich, wie es gemacht werden sollte, da sie erwarten, dass man eine höhere Bibliothek wie Pango benutzt.

Was ich denke, richtig sein könnte, ist: Erstellen Sie eine skalierte Schriftart mit cairo_scaled_font_create und dann die Glyphen für den Text abrufen cairo_scaled_font_text_to_glyphs verwenden. cairo_glyph_extents gibt dann die Ausdehnungen für jede Glyphe an. Aber wie kann ich dann Kerning und den Fortschritt bekommen? Wie kann ich dann Pfade für jede Schriftart bekommen?

Gibt es mehr Ressourcen zu diesem Thema? Sind diese Funktionen der erwartete Weg?

+0

Haben Sie sah [Seite Kairo doc] (http://www.cairographics.org/manual/ cairo-FreeType-Fonts.html)? Ich habe FreeType nie mit Cairo benutzt, also weiß ich nicht, ob das der Schlüssel ist, aber wenn es dein Problem löst, kann ich als Antwort posten. – oldtechaa

+0

Auf dieser Seite wird erläutert, wie ein 'cairo_font_face_t' unter Verwendung einer Freetype-Schriftart erstellt wird. Sie verwenden dann diese Schriftart, um eine skalierte Schriftart zu erstellen. Von da an ist der Weg unklar. – maxdev

+0

Sie könnten dann Kairos Textfunktionen verwenden, um Ihren FreeType 'cairo_font_face_t' zu verwenden, den Text zu planen und zu rendern. Es wird nicht empfohlen; siehe [die Cairo-Seite] (http://www.cairographics.org/manual/cairo-text.html#cairo-text.description) bezüglich der Verwendung von Pango. Es sollte aber funktionieren, da du Pango nicht benutzen kannst.Warum sind auf der Maschine keine anderen Bibliotheken verfügbar? – oldtechaa

Antwort

4

Okay, also habe ich gefunden, was benötigt wird.

Zuerst müssen Sie eine cairo_scaled_font_t erstellen, die eine Schriftart in einer bestimmten Größe darstellt. Um dies zu tun, kann man einfach cairo_get_scaled_font nach dem Setzen einer Schriftart verwenden, erstellt es eine skalierte Schriftart für die aktuellen Einstellungen im Kontext.

Als nächstes konvertieren Sie den Eingabetext mit cairo_scaled_font_text_to_glyphs, dies ergibt ein Array von Glyphen und auch Cluster als Ausgabe. Die Clusterzuordnungen stellen dar, welcher Teil der UTF-8-Zeichenfolge zu den entsprechenden Glyphen im Glyphenarray gehört.

Um die Ausdehnung von Glyphen zu erhalten, wird cairo_scaled_font_glyph_extents verwendet. Es gibt Dimensionen, Fortschritte und Orientierungen für jede Glyphe/jeden Glyphensatz.

Schließlich können die Pfade für Glyphen mit cairo_glyph_path in den Kontext gestellt werden. Diese Pfade können dann wie gewünscht gezeichnet werden.

Das folgende Beispiel eine Eingabezeichenfolge zu Glyphen umwandelt, ruft ihre Ausdehnungen und macht sie:

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

Diese Funktionen scheinen der beste Weg zu sein, wenn man das Kairos Textsystem betrachtet. Es zeigt nur noch mehr, dass Kairo nicht wirklich für Text gedacht ist. Es wird nicht möglich sein, Kerning oder Pfade wirklich zu tun. Pango, glaube ich, hätte seinen eigenen komplexen Code, um diese Dinge zu tun.

Für die beste Weiterentwicklung von Ghost würde ich empfehlen, Pango zu portieren, da Sie (oder jemand anders) es wahrscheinlich irgendwann sowieso wollen.

+0

Siehe meinen letzten Kommentar - Ich möchte, dass Kairo mir die Layout-Informationen und Pfade für eine Glyphe gibt. Diese Information muss da sein, denn Pango basiert darauf. Ich kann einfach keine gute Dokumentation darüber finden. Nun, das Problem ist, Pango benötigt Sachen wie fontconfig und die gnome-Bibliothek, die ich nicht in Ghost haben will - diese libs erzwingen Design-Entscheidungen, die ich nicht akzeptieren will, nur um meine Charaktere auslegen zu lassen. Danke für deine Hilfe bisher aber schön Interesse zu sehen :) – maxdev

+1

würde ich dann sagen, um die Funktionen zu benutzen, die du beschrieben hast. Sie scheinen der richtige Weg zu sein. Das Problem hier ist wirklich, dass Kairo so einschränkend ist, ohne Kerning und keine klare Möglichkeit, einfach einen Pfad von den Glyphen zu erstellen. Sie können so gut wie nur 'show_glyphs' oder' show_text_glyphs' verwenden, um Glyphen anzuzeigen. Ich bearbeite meine Antwort jetzt verstehe ich ein wenig mehr. – oldtechaa

+0

Siehe andere Antwort, danke für die Bemühungen! :-) – maxdev