如何在 Haskell gtk2hs 中将开罗绘图渲染到打印机
How do I render a Cairo drawing to a printer in Haskell gtk2hs
我正在使用 GTK3 build of gtk2hs. I have a Cairo drawing in the Render
monad,我想将它发送到打印机。
我看到有一个 Surface
类型封装了 Cairo 后端。例如,可以使用 withSVGSurface
, and there are similar functions for PDF, Postscript and PNG. Once you have a Surface
you can apply a Render
action (i.e. actually draw on it) using renderWith
创建 SVG 表面。这非常简单,我可以看到如何使用这些功能将图纸导出为文件。
但是打印似乎不是这样工作的。 printOptDrawPage
signal provides its callback with a printContext
值。这有一个函数 printContextGetCairoContext
其中 returns 开罗 Context
。但是,库文档没有此 Context
类型的条目,而且我找不到任何使用它的函数。
看起来应该有 printContextGetSurface
函数,或者有一种方法可以将 Context
转换为 Surface
。我错过了什么吗?
哈,哎呀,好尴尬!看来这个部门的绑定有点不完整。
幸运的是,更新它们应该很容易。看一下 Render
monad 的定义:
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)
我认为两个补丁之一在这里是明智的:
- 公开一个消耗
Cairo
的 renderWith
-like。让用户连接 printContextGetCairoContext
与新的 renderWith
-相似。
根本不暴露printContextGetCairoContext
;将其替换为
printContextRender :: PrintContextClass self => self -> Render a -> IO a
并printContextRender
将对printContextGetCairoContext
的调用与renderWith
风格的清理合并。
我喜欢选项 (1),因为它的故事很干净 backwards-compatibility;但我更喜欢 (2) API-design 方面的东西。由于您所描述的原因,此模块可能没有太多用处,因此我倾向于补丁 (2)。
我还注意到,您可能需要稍微查看一下 gtk 文档,以检查 Cairo 上下文清理是否由其他人负责(例如,PrintOperation 的)。
祝黑客愉快!
我正在使用 GTK3 build of gtk2hs. I have a Cairo drawing in the Render
monad,我想将它发送到打印机。
我看到有一个 Surface
类型封装了 Cairo 后端。例如,可以使用 withSVGSurface
, and there are similar functions for PDF, Postscript and PNG. Once you have a Surface
you can apply a Render
action (i.e. actually draw on it) using renderWith
创建 SVG 表面。这非常简单,我可以看到如何使用这些功能将图纸导出为文件。
但是打印似乎不是这样工作的。 printOptDrawPage
signal provides its callback with a printContext
值。这有一个函数 printContextGetCairoContext
其中 returns 开罗 Context
。但是,库文档没有此 Context
类型的条目,而且我找不到任何使用它的函数。
看起来应该有 printContextGetSurface
函数,或者有一种方法可以将 Context
转换为 Surface
。我错过了什么吗?
哈,哎呀,好尴尬!看来这个部门的绑定有点不完整。
幸运的是,更新它们应该很容易。看一下 Render
monad 的定义:
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)
我认为两个补丁之一在这里是明智的:
- 公开一个消耗
Cairo
的renderWith
-like。让用户连接printContextGetCairoContext
与新的renderWith
-相似。 根本不暴露
printContextGetCairoContext
;将其替换为printContextRender :: PrintContextClass self => self -> Render a -> IO a
并
printContextRender
将对printContextGetCairoContext
的调用与renderWith
风格的清理合并。
我喜欢选项 (1),因为它的故事很干净 backwards-compatibility;但我更喜欢 (2) API-design 方面的东西。由于您所描述的原因,此模块可能没有太多用处,因此我倾向于补丁 (2)。
我还注意到,您可能需要稍微查看一下 gtk 文档,以检查 Cairo 上下文清理是否由其他人负责(例如,PrintOperation 的)。
祝黑客愉快!