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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了如何在Haskell gtk2hs中将Cairo绘图渲染到打印机相关的知识,希望对你有一定的参考价值。

我正在使用GTK3 build of gtk2hs。我在Render monad有一个开罗画,我想把它送到打印机。

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

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

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

答案

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

幸运的是,更新它们应该很容易。看看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. 暴露一个消耗renderWithCairo。让用户连接printContextGetCairoContext和新的renderWith-like。
  2. 不要暴露printContextGetCairoContext;用它替换它 printContextRender :: PrintContextClass self => self -> Render a -> IO a 并让printContextRender将对printContextGetCairoContext的调用与renderWith式清理合并。

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

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

快乐的黑客!

以上是关于如何在Haskell gtk2hs中将Cairo绘图渲染到打印机的主要内容,如果未能解决你的问题,请参考以下文章

Haskell、GHC、win32、开罗

如何在 Haskell 中将数据类型转换为 BSON?

如何使用“ord”函数在 Haskell 中将 Char 转换为 Int?

如何在 Haskell 中将 main :: IO () 重写为由一个 main :: IO() 组成的两个函数

在 Haskell 中将字符串转换为整数/浮点数?

在 Haskell 中将字符串转换为类型构造函数