Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/svg/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用libcairo和Haskell的多页SVG_Haskell_Svg_Cairo - Fatal编程技术网

使用libcairo和Haskell的多页SVG

使用libcairo和Haskell的多页SVG,haskell,svg,cairo,Haskell,Svg,Cairo,我正在编写的应用程序使用libcairo输出矢量图形;对于支持多页(PDF、PostScript)的输出格式,一切都很好,但是我也希望支持SVG和光栅图像格式 我现在只是使用showPage来推送页面,否则我会溢出底部的空白,我希望保持代码的这种结构。我提出了两种理论上可能的解决方案: a) 一个帮助器monad,它围绕Cairo的Rendermonad,但提供了一个flushPage操作,当链接到该操作中时,它会将当前呈现操作推到内部页面堆栈上,这是一个liftRender操作,它会,通过将R

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

我现在只是使用
showPage
来推送页面,否则我会溢出底部的空白,我希望保持代码的这种结构。我提出了两种理论上可能的解决方案:

a) 一个帮助器monad,它围绕Cairo的
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表面”?如果答案是“不”;其中哪一个更可取,您将如何实现它?

如果您不必打印“doc”,那么svg“g”节点的多层可以作为页面显示。 若要分页,则可以打开或关闭可见性

如果打印过程聪明地理解了这一点,那么打印是可能的吗


MarkT

如果有人感兴趣,多亏了哈斯凯尔公司的朋友们的友好帮助,我才弄明白

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


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

这并不是我想要的——我实际上是在将SVG和其他矢量格式输出到文件中,因为我使用libcairo来实现这一点,所以我没有必要的控制级别。