Pango +开罗;是否有用于处理< img>的现有方法?文字中的样式标签? [英] Pango + Cairo; is there an existing approach for handling <img> style tags in text?

查看:183
本文介绍了Pango +开罗;是否有用于处理< img>的现有方法?文字中的样式标签?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

Pango语法支持某些纯文本标记.据我所知,这还不包括嵌入图像.

环顾四周,我无法在现有实现中找到很多东西,但是我之前没有做过pango + cairo工作,因此我可能会因此而错过明显的社区.

据我所知,一种合理的方法是只分析一个字符串,拉出任何标签,创建开罗图像,然后相应地修改它们周围的pango布局.

似乎也有人曾经做过的事.

我正在专门寻找有关以下问题的答案:

  1. pango + cairo是否已经解决了这个问题,而我只是误读了文档?
  2. 以前有做过这样的事情吗,引用在哪里?
  3. 这是一种合理的方法,还是我应该尝试其他方法?

(还请注意,我使用的是红宝石,因此可能会影响我的选择)

解决方案

我已经遍历了标记解析器的源代码,它不允许使用"shape"属性(Pango几乎合并了图形的方式),但是有可能可以手动"完成.

由于网上绝对没有示例代码,因此这里是Pango/Cairo/Images 101.

对于一个简单的演示,我创建了一个800x400的窗口,添加了一个GtkDrawingArea并连接了"draw"信号.在进入主程序循环之前,我使用以下代码对其进行了初始化:

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

上下文的形状渲染器设置为render(),并创建和初始化PangoLayout.然后,它创建2个形状属性,将用户数据设置到我们从png文件填充的cairo表面上,并将该属性应用于文本的字符0和152.

绘制"信号处理非常简单.

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

并根据需要调用render()PangoCairoShapeRenderFunc函数:

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

从开罗获取当前点,它绘制一个矩形并用图像填充它.

这几乎就是它的全部.图片被添加为事后想法,并显示出来.它们受任何其他字形的相同规则约束,因此仅限于CSS的等效显示:内联.

如果有人愿意,我会将代码放在 http://immortalsofar.com/PangoDemo/上一起玩.我,我来到这里是为了解决GtkTextBuffer的局限性.猜猜我将不得不更深入.

Pango syntax supports some text only markup. As far as i can see this does not extend to embedding images as well.

Looking around I cannot find much in the way of an existing implementation, but i havent done pango+cairo work before so i might be missing the obvious community for it.

As far as i can tell a reasonable approach would be to just analyse a string, pull out any tags, create cairo images, and then modify the pango layout around them accordingly.

It also seems like something someone might have done before.

Im specifically looking for an answer on these questions:

  1. Does pango+cairo already solve this and I have just misread the docs?
  2. Has something like this been done before, and where is a reference?
  3. Is this a reasonable approach, or should i try something else, and what?

(also note i am using ruby, so that may affect my options)

解决方案

I've been through the source of the markup parser and it does not allow for "shape" attributes (the way Pango almost incorporates graphics) but it is possible to do it "by hand".

Since there is absolutely no example code on the Web, here's Pango/Cairo/Images 101.

For a simple demo, I created an 800x400 window, added a GtkDrawingArea and connected up 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's shape renderer is set to render () and a PangoLayout is created and initialized. It then creates 2 shape attributes, sets the user data to a cairo surface which we populate from a png file and applies the attributes to characters 0 and 152 of the text.

The "draw" signal processing is straightforward.

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

and the render () PangoCairoShapeRenderFunc function 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, it draws a rectangle and fills it with the image.

And that's pretty much all it does. Images were added as an afterthought and it shows. They are subject to the same rules as any other glyph so they are limited to the equivalent of CSS's display: inline.

I've put the code up at http://immortalsofar.com/PangoDemo/ if anyone wants to play with it. Me, I arrived here trying to get around GtkTextBuffer's limitations. Guess I'll just have to go deeper.

这篇关于Pango +开罗;是否有用于处理< img>的现有方法?文字中的样式标签?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆