2015-01-19 32 views
5

La sintassi di Pango supporta alcuni markup di solo testo. Per quanto posso vedere, questo non si estende alle immagini di incorporamento.Pango + Cairo; esiste un approccio esistente per la gestione dei tag di stile <img> nel testo?

Guardarsi intorno non riesco a trovare molto nel modo di un'implementazione esistente, ma non ho fatto il lavoro di pango + cairo prima quindi potrei mancare all'evidente comunità per questo.

Per quanto posso dire, un approccio ragionevole sarebbe semplicemente analizzare una stringa, estrarre eventuali tag, creare immagini di cairo e quindi modificare di conseguenza il layout di pango che li circonda.

Sembra anche qualcosa che qualcuno avrebbe potuto fare prima.

Im specificamente alla ricerca di una risposta su queste domande:

  1. Does Pango + già cairo risolvere questo ed ho appena letto male i documenti?
  2. Qualcosa di simile è stato fatto prima, e dov'è un riferimento?
  3. È un approccio ragionevole, o dovrei provare qualcos'altro, e cosa?

(nota anche sto usando rubino, in modo che possono interessare le mie opzioni)

+0

Breve ipotesi: tu sei il primo.Pango non è un programma di rendering html completo: solo un motore di layout del testo. Ma una domanda ben piazzata - forse qualcuno l'aveva già trascinato prima. – jsbueno

risposta

4

che ho passato l'origine del parser markup e non permette di "forma" attributi (il modo Pango quasi incorpora la grafica) ma è possibile farlo "a mano".

Poiché non v'è assolutamente alcun codice di esempio sul Web, ecco Pango/Il Cairo/Immagini 101.

Per una semplice demo, ho creato una finestra di 800x400, aggiunto un GtkDrawingArea e collegato il segnale "disegnare". Prima di entrare nel ciclo principale del programma, ho inizializzato con il seguente codice:

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); 
} 

rendering forma del contesto è impostato render() e una PangoLayout viene creata e inizializzata. Quindi crea 2 attributi di forma, imposta i dati dell'utente su una superficie di cairo che popoliamo da un file png e applica gli attributi ai caratteri 0 e 152 del testo.

L'elaborazione del segnale "draw" è semplice.

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

e il rendering() funzione PangoCairoShapeRenderFunc è chiamato come necessario:

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); 
} 

Prendendo il punto corrente da cairo, si disegna un rettangolo e lo riempie con l'immagine. This really sucks!

E questo è praticamente tutto ciò che fa. Le immagini sono state aggiunte come un ripensamento e mostra. Sono soggetti alle stesse regole di ogni altro glifo, quindi sono limitati all'equivalente della visualizzazione del CSS: inline.

Ho messo il codice su http://immortalsofar.com/PangoDemo/ se qualcuno vuole giocare con esso. Io, sono arrivato qui cercando di aggirare i limiti di GtkTextBuffer. Credo che dovrò andare più a fondo.

+0

Ho finito per risolvere il mio problema con l'output di html + css e lasciando che un browser gestisca il rendering. La tua risposta mostra più comprensione del problema di quanto avessi inizialmente ed è probabilmente una pietra miliare ragionevole per qualcun altro che cerca di risolvere questo problema, esultanza per gli sforzi :) – Vusak

+1

Grazie mille. Il mondo Gtk/Pango manca davvero un manuale per i programmatori, la documentazione dettagliata non è male ma come mettere tutto insieme ... Oh sì e andare in giro La limitazione di GtkTextBuffer è anche ciò che mi ha portato qui durante la mia ricerca per scrivere il perfetto Editor di markdown basato su HTML – Lothar