Pango + Cairo; Is there an existing approach for handling <img> style tags in text?
Pango syntax only supports text markup. As far as I can see, this does not apply to embedding images either.
Looking around, I can't find much on the way to the existing implementation, but I never did pango + cairo, so I could skip the obvious community for this.
As far as I can tell, a sensible approach would be to simply parse the string, pull out any tags, create Cairo images, and then change the pango layout around them accordingly.
It also looks like something someone could have done before.
I am specifically looking for the answer to these questions:
- Can pango + cairo solve this, and I just read the docs incorrectly?
- Something like this has been done before, and where is the link?
- Is this a sensible approach, or should I try something else, so what?
(also note that I am using ruby, so this may affect my settings)
I went through the source of the markup parser, and it does not take into account the "shape" attributes (the way Pango almost includes graphics), but this can be done "manually."
Since there is no sample code on the Internet, here is Pango / Cairo / Images 101.
For a simple demonstration, I created a 800x400 window, added GtkDrawingArea, and connected the draw signal. Before entering the main program loop, I initialized it with the following 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); } The context form renderer is set to render (), and PangoLayout is created and initialized. Then he creates 2 attributes of the figure, sets user data on the surface of Cairo, which we fill out from the png file, and applies the attributes to characters 0 and 152 of the text.
Signal processing "draw" is simple.
gboolean onDraw (GtkWidget *pWidget, cairo_t *cr, gpointer user_data) { pango_cairo_show_layout (cr, Pango); return 1; } and the render () function of PangoCairoShapeRenderFunc is called as needed:
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); } Taking the current point from Cairo, she draws a rectangle and fills it with an image. 
And thatβs almost all he does. Images were added as an afterthought, and this is visible. They follow the same rules as any other character, so they are limited to the CSS: inline display equivalent.
I put the code in http://immortalsofar.com/PangoDemo/ if someone wants to play with it. I came here trying to get around the limitations of GtkTextBuffer. I guess I just need to go deeper.