潘戈+开罗;是不是有处理文本中 <img> 样式标签的现有方法?

Posted

技术标签:

【中文标题】潘戈+开罗;是不是有处理文本中 <img> 样式标签的现有方法?【英文标题】:Pango + Cairo; is there an existing approach for handling <img> style tags in text?潘戈+开罗;是否有处理文本中 <img> 样式标签的现有方法? 【发布时间】:2015-01-19 02:31:33 【问题描述】:

Pango 语法支持一些纯文本标记。据我所知,这并没有扩展到嵌入图像。

环顾四周,我找不到太多现有实现的方式,但我之前没有做过 pango+cairo 的工作,所以我可能会错过明显的社区。​​p>

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

这似乎也有人以前做过。

我专门寻找这些问题的答案:

    pango+cairo 是否已经解决了这个问题,而我只是误读了文档? 以前做过类似的事情吗?参考资料在哪里? 这是一种合理的方法,还是我应该尝试其他方法,以及什么?

(还要注意我使用的是 ruby​​,所以这可能会影响我的选择)

【问题讨论】:

简短的猜测:你是第一个进入它的人。 Pango 不是一个完整的 html 渲染器 - 只是一个文本布局引擎。但是,这是一个很好的问题——也许以前有人跟踪过。 【参考方案1】:

我已经浏览过标记解析器的源代码,它不允许“形状”属性(Pango 几乎包含图形的方式),但可以“手动”完成。

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

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

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

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

这就是它所做的一切。图像是事后添加的,它显示了。它们受制于与任何其他字形相同的规则,因此它们仅限于相当于 CSS 的 display: inline。

如果有人想玩它,我已将代码放在http://immortalsofar.com/PangoDemo/。我,我来到这里试图绕过 GtkTextBuffer 的限制。我想我只需要更深入。

【讨论】:

我最终通过输出 html+css 并让浏览器处理渲染来解决我的问题。您的回答比我最初对问题的理解更多,并且可能是其他试图解决此问题的人的合理垫脚石,为努力欢呼:) 非常感谢。 Gtk/Pango 世界真的缺少程序员手册,详细的文档还不错,但是如何将它们放在一起......哦,是的,绕过 GtkTextBuffer 的限制也是我在寻求编写完美的非基于 HTML 的降价编辑器 迈克,感谢这个演示! immortalsofar.com 上的代码许可证是什么?我没有看到具体的说法。除了此答案的现有 CC-BY-SA 之外,您是否愿意许可 LGPL、BSD 或 MIT? 没有许可证,只能自己动手。完整的公共领域。 @Mike 非常感谢!我拿走了你的代码并用它运行(有信用)---github.com/cxw42/pfft/blob/…。使用 pangocairo 的完整 Markdown->PDF 转换器的一部分。 :) .

以上是关于潘戈+开罗;是不是有处理文本中 <img> 样式标签的现有方法?的主要内容,如果未能解决你的问题,请参考以下文章

开罗的笔画对齐

从文本中提取图片路径(java 解析富文本处理 img 标签)

在js中一个存储html文本的对象,怎样过滤其中的所有的img标签

将 SVG 作为开罗图像表面加载的最佳方法是啥?

3列表格中同一行的V&H中心img和文本

有没有办法在开罗保存路径并恢复它?