2015-01-19 6 views
5

Pango-Syntax unterstützt einige Text nur Markup. Soweit ich sehen kann, erstreckt sich dies nicht auf das Einbetten von Bildern.Pango + Kairo; Gibt es einen bestehenden Ansatz für die Handhabung von <img> Stil Tags im Text?

Umsehen kann ich nicht viel in der Art einer vorhandenen Implementierung finden, aber ich habe pango + cairo Arbeit nicht getan, damit ich die offensichtliche Gemeinschaft dafür vermisse.

Soweit ich sagen kann, wäre ein vernünftiger Ansatz, nur eine Zeichenfolge zu analysieren, irgendwelche Tags herauszuziehen, Cairo-Bilder zu erstellen und dann das Pango-Layout um sie herum entsprechend zu ändern.

Es scheint auch etwas, was jemand zuvor getan haben könnte.

Im gezielt nach einer Antwort auf diese Fragen:

  1. Hat pango + kairo bereits dieses Problem lösen, und ich habe falsch verstanden nur die Dokumentation?
  2. Wurde so etwas schon einmal gemacht, und wo ist eine Referenz?
  3. Ist das ein vernünftiger Ansatz, oder sollte ich etwas anderes versuchen, und was?

(auch beachten i Rubin verwenden, kann, so dass meine Optionen beeinflussen)

+0

Kurz raten: Sie sind der erste hinein.Pango ist kein vollständiger HTML-Renderer - nur eine Text-Layout-Engine. Aber trotzdem eine gut platzierte Frage - vielleicht war da schon jemand hingegangen. – jsbueno

Antwort

4

Ich habe die Quelle des Markup-Parsers durchgemacht und es für „Form“ nicht zulässt, dass Attribute (die Art und Weise Pango fast enthält Grafiken), aber es ist möglich, es "von Hand" zu tun.

Da es im Web absolut kein Beispiel-Code ist, ist hier Pango/Kairo/Bilder 101

Für eine einfache Demo, Ich habe ein 800x400-Fenster hinzugefügt, um eine GtkDrawingArea und das „zeichnen“ Signal angeschlossen. Bevor der Hauptprogrammschleife eintritt, initialisiert ich es mit dem folgenden Code:

PangoLayout  *Pango; 
void init_drawingArea (GtkWidget *pWidget) 
{ 
    cairo_surface_t *pImg = cairo_image_surface_create_from_png ("linux.png"); 
    PangoRectangle r = {0, 0, PANGO_SCALE * cairo_image_surface_get_width (pImg), 
           PANGO_SCALE * cairo_image_surface_get_height(pImg)}; 
    PangoContext *ctxt = gtk_widget_get_pango_context (pWidget); 
    PangoAttrList *attList = pango_attr_list_new(); 
    PangoAttribute *attr; 

    Pango = pango_layout_new (ctxt); 

    pango_cairo_context_set_shape_renderer (ctxt, render, NULL, NULL); 
    pango_layout_set_text (Pango, pszLorem, -1); 
    pango_layout_set_width(Pango, PANGO_SCALE * 800); 
    attr = pango_attr_shape_new_with_data(&r, &r, pImg, NULL, NULL); 
    attr->start_index = 0; attr->end_index = 1; 
    pango_attr_list_insert (attList, attr); 

    attr = pango_attr_shape_new_with_data(&r, &r, pImg, NULL, NULL); 
    attr->start_index = 152; attr->end_index = 153; 
    pango_attr_list_insert (attList, attr); 

    pango_layout_set_attributes (Pango, attList); 
} 

Die Form Renderer Kontext gesetzt zu machen() und ein PangoLayout wird erzeugt und initialisiert. Es erstellt dann 2 Shape-Attribute, setzt die Benutzerdaten auf eine Cairo-Oberfläche, die wir aus einer PNG-Datei auffüllen, und wendet die Attribute auf die Zeichen 0 und 152 des Textes an.

Die "Draw" Signalverarbeitung ist unkompliziert.

gboolean onDraw (GtkWidget *pWidget, cairo_t *cr, gpointer user_data) 
{ 
    pango_cairo_show_layout (cr, Pango); 
    return 1; 
} 

und die Render() PangoCairoShapeRenderFunc Funktion aufgerufen wird nach Bedarf:

void render (cairo_t *cr, PangoAttrShape *pShape, gboolean do_path, gpointer data) 
{ 
    cairo_surface_t *img = (cairo_surface_t *)pShape->data; 
    double dx, dy; 

    cairo_get_current_point(cr, &dx, &dy); 
    cairo_set_source_surface(cr, img, dx, dy); 
    cairo_rectangle (cr, dx, dy, pShape->ink_rect.width/PANGO_SCALE, 
           pShape->ink_rect.height/PANGO_SCALE); 
    cairo_fill(cr); 
} 

den aktuellen Punkt aus Kairo machen, zieht er ein Rechteck und füllt es mit dem Bild. This really sucks!

Und das ist so ziemlich alles, was es tut. Bilder wurden als nachträglicher Einfall hinzugefügt und es zeigt sich. Sie unterliegen denselben Regeln wie alle anderen Glyphen und sind daher auf das Äquivalent der CSS-Darstellung beschränkt: Inline.

Ich habe den Code auf http://immortalsofar.com/PangoDemo/ gestellt, wenn jemand damit spielen will. Ich bin hier angekommen, um die Einschränkungen von GtkTextBuffer zu umgehen. Ich denke, ich muss einfach tiefer gehen.

+0

Ich habe mein Problem gelöst, indem ich nur html + css ausgegeben habe und einen Browser mit Rendering umgehen ließ. Ihre Antwort zeigt mehr Verständnis für das Problem als ich ursprünglich hatte und ist wahrscheinlich ein vernünftiges Sprungbrett für jemand anderen versucht, dieses Problem zu lösen, Prost für die Bemühungen :) – Vusak

+1

Vielen Dank. In der Gtk/Pango-Welt fehlt wirklich ein Programmierer-Handbuch, die detaillierte Dokumentation ist nicht schlecht, aber wie man alles zusammenstellt ... Oh ja, und herumkommen GtkTextBuffers Begrenzung hat mich während meiner Suche nach dem perfekten Nicht-Ich hierher gebracht HTML-basierter Markdown-Editor – Lothar

Verwandte Themen