haskell - 使用 libcairo 和 Haskell 的多页 SVG

标签 haskell svg cairo

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

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

a) 一个包裹 Cairo 的辅助单子(monad) Render monad,但提供了 flushPage链接到其中时,将当前渲染操作推送到内部页面堆栈上,即 liftRender行动将很好地提升 Render通过将操作链接到先前缓冲的操作上,将操作添加到 monad 中,并使用辅助函数来提取 Render () 列表操作,每一页一个。所以我会简单地调用我的主渲染函数,而不是 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 表面类型,其作用类似于外部的多页文档,但在外部生成一系列单页文档。这将是理想的,因为它根本不需要对渲染代码进行任何更改,但我不确定是否可以在不干扰源代码级别的 cairo 本身的情况下做到这一点。

那么,实际的问题是:上述解决方案是否已经存在?例如,是否有人编写过“分页包装器 monad”或“多页 SVG 表面”?并且,如果答案是“否”;其中哪一个更可取,您将如何实现它?

最佳答案

如果有人感兴趣,我在 #haskell 的 friend 们的友好帮助下找到了答案。

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

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

关于haskell - 使用 libcairo 和 Haskell 的多页 SVG,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/7467089/

相关文章:

haskell - Xmonad 切换全屏/xmobar

r - 获取错误 : Graphics API version mismatch

r - 安装/使用 Cairo/R 2.12.1 的困难

haskell - Cabal 不更新二进制符号链接(symbolic link)

haskell - Haskell 中的重载(show 和 num)

javascript - d3.js Insert() 函数添加子元素 - 而不是兄弟元素

html - 无法让剪辑路径与外部 svg 一起使用

algorithm - 具有多个渐变的 SVG 透明度

Cairo C 程序不会绘制到 x11 窗口

haskell - 在 Haskell 中具有 -> a -> a 的功能?