如何在 Haskell gtk2hs 中将开罗绘图渲染到打印机



我使用的是gtk2hs的GTK3版本。我在Render的单体中有一幅开罗图纸,我想把它送到打印机。

我看到有一种封装开罗后端的Surface类型。例如,可以使用withSVGSurface创建SVG表面,并且PDF,Postscript和PNG也有类似的功能。有了Surface后,您可以使用renderWith应用Render操作(即实际绘制)。这非常简单,我可以看到如何使用这些功能将图形导出为文件。

但是,打印似乎不是这样工作的。printOptDrawPage信号为其回调提供printContext值。这有一个函数printContextGetCairoContext返回开罗Context。但是,库文档没有此Context类型的条目,我找不到任何使用它的函数。

看起来应该有printContextGetSurface功能,或者一种将Context转换为Surface的方法。我错过了什么吗?

呵呵,哎呀,真尴尬!看来这个部门的绑定有点不完整。

幸运的是,更新它们应该很容易。看看Rendermonad的定义:

newtype Render m = Render { runRender :: ReaderT Cairo IO m }

我们可以看到,您从printContextGetCairoContext获得的Cairo对象正是您使用Render操作执行有用的操作所需的对象。renderWith函数的实现为您提供了应执行哪些清理操作的线索:

renderWith surface (Render m) = liftIO $
bracket (Internal.create surface)
(context -> do status <- Internal.status context
Internal.destroy context
unless (status == StatusSuccess) $
fail =<< Internal.statusToString status)
(context -> runReaderT m context)

我认为这里有两个补丁之一是明智的:

  1. 公开消耗CairorenderWith相似。让用户printContextGetCairoContext与新renderWith类似连接。
  2. 根本不要公开printContextGetCairoContext;将其替换为

    printContextRender :: PrintContextClass self => self -> Render a -> IO a
    

    printContextRenderprintContextGetCairoContext调用与renderWith式清理合并。

我喜欢选项 (1) 因为它干净的向后兼容性故事;但从 API 设计方面来看,我喜欢 (2) 要好得多。由于您所描述的原因,此模块可能没有太多用处,因此我倾向于补丁(2)。

我还想指出,您可能想稍微查看一下 gtk 文档,以检查开罗上下文清理是否是其他人的责任(例如,PrintOperation)。

快乐黑客!

最新更新