使用libcairo和Haskell的多页SVG

时间:2011-09-19 06:13:57

标签: haskell svg cairo

我正在编写的应用程序使用libcairo输出矢量图形;一切都适用于支持多页(PDF,PostScript)的输出格式,但我也想支持SVG和光栅图像格式。

我目前只是使用showPage推送页面,否则我会溢出底部边距,我希望保持代码的结构。我提出了两种可用的理论解决方案:

a)一个帮助monad,它包裹着Cairo的Render monad,但提供了一个flushPage动作,当它被链接到它时,将当前的Render动作推送到一个内部页面堆栈,{{1通过将liftRender动作链接到先前缓冲的动作,以及用于提取Render动作列表的辅助函数,每个页面一个动作,将动作提升到monad中。所以我只是简单地调用我的主渲染函数,但不是Render ()动作,而是返回一个分页包装动作,然后从中提取单个页面并处理它们 - 对于多页面格式,我可以只需将它们链接在一起,在它们之间插入Render ()个动作,而对于单页面格式,我会单独渲染它们。举个例子,这就是它的样子:

showPage

b)一种cairo表面类型,其外部像多页文档,但在外部生成一系列单页文档。这将是理想的,因为它根本不需要对渲染代码进行任何更改,但是我不确定是否可以在源代码级别处乱解cairo本身。

所以,实际问题:上述任何一种解决方案是否已经存在?如果有人写过“分页包装monad”或“多页SVG表面”?并且,如果答案是“否”;哪一项更可取,你会如何实施呢?

2 个答案:

答案 0 :(得分:2)

如果有人有兴趣,我会在#haskell的帮助下得到一些友好的帮助。

我的渲染函数返回Render [Render ()],而不是编写自定义包装器monad。我递归地渲染片段,传递一些状态,并且在每次迭代时,我检查当前操作是否会溢出当前页面。如果是,那么递归调用会附加一个新页面并再次尝试;否则,它将当前操作链接到首页。结果是Render ()个动作列表,每个页面一个。

然后,main函数将这些Render()动作从render函数的结果中取出。然后它检查所需的输出格式;如果它是像PostScript或PDF这样的多页面格式,它只是将动作链接在一起,在它们之间插入showPage动作。如果它是单页面格式,它会为每个页面创建一个新的渲染表面,并在其上呈现一个页面操作。第一页兼作初始渲染调用的上下文。

答案 1 :(得分:0)

如果您不必打印'doc',则可以将多层svg'g'节点显示为页面。 要进行分页,可以打开或关闭可见性。

如果打印过程有智能理解这一点,那么打印是否可行?

MARKT