如何在Haskell gtk2hs

时间:2018-03-05 15:15:17

标签: haskell printing gtk2hs

我正在使用GTK3 build of gtk2hs。我在Render monad中有一张开罗绘图,我想把它发送给打印机。

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

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

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

1 个答案:

答案 0 :(得分:2)

哈哈,哎呀,这令人尴尬!看来绑定在这个部门有点不完整。

幸运的是,更新它们应该很容易。看一下Render monad的定义:

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

我们可以看到,您从Cairo获得的printContextGetCairoContext对象正是您需要通过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. 公开renderWith - 类似消费Cairo。让用户将printContextGetCairoContext与新renderWith相似。
  2. 根本不公开printContextGetCairoContext;用

    替换它
    printContextRender :: PrintContextClass self => self -> Render a -> IO a
    

    并让printContextRender将对printContextGetCairoContext的调用与renderWith式清理合并。

  3. 我喜欢选项(1),因为它具有干净的向后兼容性故事;但我喜欢(2)从API设计方面做得更好。由于这个模块可能因为你所描述的原因而没有多大用处,所以我倾向于补丁(2)。

    我还要注意,您可能需要查看一下gtk文档,以检查Cairo上下文清理是否是其他人的责任(例如,PrintOperation&#39; s)。 / p>

    快乐的黑客攻击!