The gintro Nim bindings do not compile with latest harfbuzz-4.4.1


My feeling is, that one problem is, that harfbuzz uses some freetype2 data types, and freetype2 seems to declare some basic type symbols as pointers or handles, like

typedef struct FT_FaceRec_*  FT_Face;

See Base Interface - FreeType-2.12.1 API Reference

But the Freetype2 GIR file is just:

cat /usr/share/gir-1.0/freetype2-2.0.gir 
<?xml version="1.0"?>
<repository version="1.2"
  <namespace name="freetype2" version="2.0"
    <record name="Bitmap" c:type="FT_Bitmap"/>
    <record name="Face" c:type="FT_Face"/>
    <record name="Library" c:type="FT_Library"/>
    <alias name="Int32" c:type="FT_Int32">
      <type name="int32"/>
    <function name="library_version" c:identifier="FT_Library_Version">
      <return-value transfer-ownership="none">
        <type name="none" c:type="void"/>

Currently I wonder how I get from gobject-introspection the info that FT_Face is indeed a pointer.

To make the actual problem more clear:

grep -A22 “hb_ft_face_create” /usr/share/gir-1.0/HarfBuzz-0.0.gir

        <parameter name="ft_face"
          <doc xml:space="preserve"
               line="816">FT_Face to work upon</doc>
          <type name="freetype2.Face" c:type="FT_Face"/>

My feeling is, that the bindings generator script (gen.nim) misses the fact that “ft_face” is actually a pointer.

For me this currently looks like a freetype2 or gobject-introspection bug? I wonder why it was compiling for older harfbuzz versions.

Shall I search for some form of bugzilla issue tracker and report it there? Better report for freetype or for gobject-introspection?

I think earlier functions with FT_Face were not introspectable:

    <function name="ft_face_create"

And now, with latest harfbuzz, GITypeInfo: libgirepository API Reference gives false for c:type=“FT_Face”.

That is really ugly. I think I have to patch the function g-type-info-is-pointer() to return TRUE for these freetype data types.


OK, I have applied this patch for now:

$ diff ~/gintrotest/test/gen.nim gen.nim 
< # v 0.9.9 2022-JUL-10
> # v 0.9.9 2022-MAY-17
<   var p = gTypeInfoIsPointer(t)
<   if not p:
<     let tag = gTypeInfoGetTag(t)
<     if tag == GITypeTag.INTERFACE:
<       let iface = gTypeInfoGetInterface(t)
<       if gBaseInfoGetNamespace(iface) == "freetype2" and gBaseInfoGetName(iface) == "Face":
<         p = true # see issue
>   let p = gTypeInfoIsPointer(t)

Looks like it’s a Harfbuzz bug as the new version brock other bindings as well. Please see this issue.

For me it is actually more a freetype2 issue, due to

typedef struct FT_FaceRec_*  FT_Face;

It is ugly, and only real solution which I can see is to modify the freetype2 library in a way that typedef structs are value objects and not pointers, but that may break other stuff.

Remember that freetype2’s GIR is hand-written, because freetype is not a GObject-based library, and as such there are no expectations its API conforms to the practices used by GObject-based libraries.

Theoretically, record elements for C types that are really aliases to pointers should use disguised="1" to indicate that they are really a pointer in disguise. The main issue is that, over the years, we started using disguised="1" also for opaque types.

We’d have to solve gobject-introspection#101, and add a whole new attribute.

1 Like

This topic was automatically closed 14 days after the last reply. New replies are no longer allowed.