如何用gi-cairo与Haskell渲染SVG?为何生成空文件?
问题原因与解决方案
核心差异
原生Graphics.Rendering.Cairo的withSVGSurface会在回调执行完毕后,自动调用cairo_surface_finish,确保所有绘图操作的缓存数据被写入文件;而gi-cairo的withSVGSurface是直接绑定Cairo的底层C API,没有封装这个自动收尾步骤。Cairo的SVG表面必须显式完成收尾,否则文件会因未写入任何数据而变成空文件。
修复后的gi-cairo代码
只需在回调中手动调用surfaceFinish,就能确保绘图数据被写入SVG文件:
import GI.Cairo.Render import GI.Cairo.Render.Connector import qualified GI.Cairo as Cairo main :: IO () main = do withSVGSurface "test.svg" 1000 1000 (\srf -> do renderWith srf $ do setSourceRGB 1 1 1 paint setSourceRGB 1 0 0 moveTo 10 10 lineTo 100 100 lineTo 200 100 lineTo 200 400 stroke fill showPage -- 关键步骤:手动触发表面数据写入 Cairo.surfaceFinish srf)
补充说明
- GI系列绑定(含gi-cairo)更贴近Cairo的原始C接口,不会像原生Haskell的cairo库那样做额外的封装优化,很多资源收尾操作需要手动处理。
surfaceFinish会强制Cairo将所有未输出的绘图数据写入文件,并关闭关联的文件句柄,是确保SVG表面生成有效文件的可靠方式。
内容的提问来源于stack exchange,提问作者JeanJouX
相关产品推荐
相关产品推荐

