【发布时间】:2011-09-19 06:13:56
【问题描述】:
我正在编写的应用程序使用 libcairo 来输出矢量图形;对于支持多页(PDF、PostScript)的输出格式,一切正常,但我也希望支持 SVG 和光栅图像格式。
我目前只是使用showPage 推送页面,否则我会溢出底部边距,并且我希望保持这种代码结构。我提出了两种理论上可能的解决方案:
a) 一个 helper monad,它包裹 Cairo 的 Render monad,但提供了一个 flushPage 动作,当它链接到它时,将当前的 Render 动作推送到一个内部页面堆栈上,一个 liftRender 动作会,好吧,通过将Render 动作链接到先前缓冲的动作和一个辅助函数来提取Render () 动作列表,将其提升到 monad 中,每个页面一个。所以我会简单地调用我的主渲染函数,而不是 Render () 动作,它会返回一个分页包装器动作,然后我会从中提取单个页面并处理它们 - 对于多页格式,我可以简单地链接它们在一起,在它们之间插入showPage 动作,而对于单页格式,我会单独呈现它们。例如,它的外观如下:
-- original code
renderMe :: Render ()
renderMe = do
newPath
moveTo 10 10
lineTo 20 20
lineTo 10 30
lineTo 10 10
fill
showPage
newPath
moveTo 10 10
lineTo 20 20
lineTo 10 30
lineTo 10 10
fill
-- new code
renderPages :: PagedRender ()
renderPages = do
liftRender (do
newPath
moveTo 10 10
lineTo 20 20
lineTo 10 30
lineTo 10 10
fill)
flushPage
liftRender (do
newPath
moveTo 10 10
lineTo 20 20
lineTo 10 30
lineTo 10 10
fill)
flushPage
b) 一种 cairo 表面类型,它在外部类似于多页文档,但在外部生成一系列单页文档。这将是理想的,因为它根本不需要对渲染代码进行任何更改,但我不确定是否可以在不弄乱源代码级别的情况下做到这一点。
那么,实际的问题是:上述解决方案是否已经存在? 有没有人写过“分页包装单子”或“多页 SVG 表面”?而且,如果答案是“不”;其中哪一个更可取,您将如何实施?
【问题讨论】: