L'application que j'écris utilise libcairo pour générer des graphiques vectoriels; tout fonctionne bien pour les formats de sortie qui prennent en charge plusieurs pages (PDF, PostScript), mais je voudrais également prendre en charge les formats d'image SVG et raster.SVG multi-pages utilisant libcairo et Haskell
Je suis actuellement simplement pousser les pages en utilisant showPage
chaque fois que je serais autrement déborder de la marge inférieure, et je voudrais garder le code structuré de cette façon. Je suis venu avec deux solutions theroretically possibles:
a) Une monade d'aide qui s'enroule autour Render
monade du Caire, mais fournit une action flushPage
qui, lorsqu'il est enchaîné en elle, pousse l'action en cours de rendu sur une pile de page interne, un liftRender
action qui, bien, lève une action Render
dans la monade en la chaînant sur l'action précédemment tamponnée, et une fonction d'assistance pour extraire une liste d'actions Render()
, une pour chaque page. Donc j'appellerais simplement ma fonction de rendu principale, mais au lieu d'une action Render()
, elle retournerait une action pagination-wrapper, à partir de laquelle j'extrais des pages individuelles et les traitions - pour les formats multi-pages, je pouvais simplement les enchaîner , en insérant showPage
actions entre eux, tandis que pour les formats d'une seule page, je les rendrais individuellement. À titre d'exemple, voici ce qu'il ressemblerait à ceci:
-- 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) Un type de surface caire qui agit comme un document de plusieurs pages à l'extérieur, mais produit une série de documents d'une seule page à l'extérieur. Ce serait idéal, car cela ne nécessiterait aucune modification du code de rendu, mais je ne suis pas sûr qu'il soit possible de le faire sans jouer avec le cairo lui-même au niveau de la source. Donc, la véritable question: L'une des solutions ci-dessus existe-t-elle déjà? Comme dans, est-ce que quelqu'un a écrit soit une «monade de pagination» ou une «surface SVG de plusieurs pages»? Et, dans le cas où la réponse est «non»; lequel est préférable et comment le mettre en œuvre?
Ce n'est pas exactement ce que je cherche - je suis en train de sortir des fichiers SVG et d'autres formats vectoriels dans des fichiers, et puisque j'utilise libcairo pour cela, je n'ai pas le niveau de contrôle requis pour cela. – tdammers