gi-cairo 和 cairo 库有什么区别

What is the difference between gi-cairo and cairo libraries

我正在制作一个程序,在用 Haskell 编写的 GTK 程序之上绘制一些矢量图形。

我把我的程序升级到gi-gtk library in replacement of Gtk2Hs to benefit of Gtk3 and when I see tutorial/example about drawing in Gtk windows with cairo and/or diagram, both gi-cairo and cairo(来自Gtk2Hs)同时需要

举个例子我可以看到:

import           GI.Gtk  
import qualified GI.Cairo (Context(..))

import qualified Graphics.Rendering.Cairo as Cairo
import qualified Graphics.Rendering.Cairo.Internal as Cairo (Render(runRender))
import qualified Graphics.Rendering.Cairo.Types as Cairo (Cairo(Cairo))

而且我不明白为什么必须同时导入GI.Cairo (gi-cairo) and Graphics.Rendering.Cairo (cairo)。

GI.Cairo是要取代Graphics.Rendering.Cairo还是要完成它?

Graphics.Rendering.Cairo 还在更新还是使用另一个库是个好主意?

关于这两个库的任何 information/explanations 都会有所帮助

TL;DR: 将任何基于 GTK2HS 的内容视为弃用。请改用带有 gi- 前缀的内容。

最初有 GTK2HS libraries,这是一个手动编写的 GTK 绑定(我想,不确定细节)。

这项工作的一部分是绑定到 Cairo library。 Cairo 函数都以一个 Cairo 上下文对象作为参数,用于携带当前颜色和线条样式等状态。 Haskell 绑定使用 Render 新类型中的 Reader monad 将其包装起来,因此您不必担心上下文对象。

然而,维护它既缓慢又费力,显然有更好的方法:GTK built-in 支持源代码中嵌入的元数据提供的其他语言绑定。因此,完全有可能自动生成所有 GTK 绑定,并将其扩展到使用 GTK 元数据系统的其他库。这就是 gi-gtk 及其亲戚所做的。

不幸的是,开罗不是那样工作的。它不包括实际绘图的 GTK 元数据 API,因此 gi-cairo interface 没有任何用处。

一段时间以来,解决这个问题的唯一方法是手动桥接 gi-gtk 系列和 GTK2HS Cairo 库之间的差距,但现在不是了。现在有一个完整的解决方案:

  • gi-cairo-render 库,它与旧的 GTK2HS 库本质上相同,但使用 gi-cairo 版本的上下文对象。

  • 关联的 gi-cairo-connector 库允许您在需要显式 Cairo 上下文对象的函数和在 Render monad 中工作的函数之间切换。

您通常需要明确的 Cairo 上下文才能使用 Pango 绘制文本。 Pango 库有自己的 Context 对象(令人困惑的是,这两种类型都称为 Context,您必须导入它们才能消除歧义)。您可以使用 createContext, and to do this in the middle of a Render action you have to extract the current context from the Render monad using one of the Connector 函数从 Cairo 上下文中获取 Pango 上下文。

您所引用的代码使用的是旧的手册; RenderrunRender 内部函数用于获取 Cairo 绑定的 GTK2HS 版本中的 Cairo 上下文。如果您查看调用这些函数的代码,您可能会发现它使用指针在 GI.Cairo.Context 类型和 Graphics.Rendering.Cairo.Types.Cairo 上下文类型之间强制执行某些不安全的操作,这两者在幕后都指向同一事物。