harfbuzz icon indicating copy to clipboard operation
harfbuzz copied to clipboard

[introspection] Enable hb-cairo

Open khaledhosny opened this issue 1 year ago • 38 comments

khaledhosny avatar Mar 05 '23 07:03 khaledhosny

This is not working for me, though. If I try something like hb.cairo_font_face_create_for_font(font), I get:

gi.repository.GLib.GError: g-invoke-error-quark: Could not locate hb_cairo_font_face_create_for_font: 'hb_cairo_font_face_create_for_font': dlsym(0x7ff91e8adad0, hb_cairo_font_face_create_for_font): symbol not found (1)

But my installation is botched, so it might be only me.

khaledhosny avatar Mar 05 '23 07:03 khaledhosny

Build also have the following warnings:

../src/hb-cairo.cc:725: Warning: HarfBuzz: hb_cairo_font_face_set_font_init_func: argument func: Missing (scope) annotation for callback without GDestroyNotify (valid: call, async, forever)
../src/hb-cairo.cc:725: Warning: HarfBuzz: hb_cairo_font_face_set_font_init_func: argument destroy: Missing (scope) annotation for callback without GDestroyNotify (valid: call, async, forever)
../src/hb-cairo.cc:849: Warning: HarfBuzz: hb_cairo_glyphs_from_buffer: argument glyphs: Unresolved type: 'cairo_glyph_t**'
../src/hb-cairo.cc:849: Warning: HarfBuzz: hb_cairo_glyphs_from_buffer: argument clusters: Unresolved type: 'cairo_text_cluster_t**'

khaledhosny avatar Mar 05 '23 07:03 khaledhosny

../src/hb-cairo.cc:725: Warning: HarfBuzz: hb_cairo_font_face_set_font_init_func: argument func: Missing (scope) annotation for callback without GDestroyNotify (valid: call, async, forever)
../src/hb-cairo.cc:725: Warning: HarfBuzz: hb_cairo_font_face_set_font_init_func: argument destroy: Missing (scope) annotation for callback without GDestroyNotify (valid: call, async, forever)

Fixed these.

khaledhosny avatar Mar 05 '23 07:03 khaledhosny

../src/hb-cairo.cc:849: Warning: HarfBuzz: hb_cairo_glyphs_from_buffer: argument glyphs: Unresolved type: 'cairo_glyph_t**'
../src/hb-cairo.cc:849: Warning: HarfBuzz: hb_cairo_glyphs_from_buffer: argument clusters: Unresolved type: 'cairo_text_cluster_t**'

This seems to be a cairo-1.0.gir limitation, these types do not seem to be defined there.

khaledhosny avatar Mar 05 '23 07:03 khaledhosny

This is not working for me, though. If I try something like hb.cairo_font_face_create_for_font(font), I get:

gi.repository.GLib.GError: g-invoke-error-quark: Could not locate hb_cairo_font_face_create_for_font: 'hb_cairo_font_face_create_for_font': dlsym(0x7ff91e8adad0, hb_cairo_font_face_create_for_font): symbol not found (1)

But my installation is botched, so it might be only me.

Did you link to harfbuzz-cairo?

behdad avatar Mar 05 '23 19:03 behdad

This is not working for me, though. If I try something like hb.cairo_font_face_create_for_font(font), I get:

gi.repository.GLib.GError: g-invoke-error-quark: Could not locate hb_cairo_font_face_create_for_font: 'hb_cairo_font_face_create_for_font': dlsym(0x7ff91e8adad0, hb_cairo_font_face_create_for_font): symbol not found (1)

But my installation is botched, so it might be only me.

I get a weirder error:

gi.repository.GLib.GError: g-invoke-error-quark: Could not locate hb_cairo_font_face_create_for_font: 'hb_cairo_font_face_create_for_font': build/src/libharfbuzz-gobject.so.0: undefined symbol: hb_cairo_font_face_create_for_font (1)

behdad avatar Mar 05 '23 19:03 behdad

This is not working for me, though. If I try something like hb.cairo_font_face_create_for_font(font), I get:

gi.repository.GLib.GError: g-invoke-error-quark: Could not locate hb_cairo_font_face_create_for_font: 'hb_cairo_font_face_create_for_font': dlsym(0x7ff91e8adad0, hb_cairo_font_face_create_for_font): symbol not found (1)

But my installation is botched, so it might be only me.

I get a weirder error:

gi.repository.GLib.GError: g-invoke-error-quark: Could not locate hb_cairo_font_face_create_for_font: 'hb_cairo_font_face_create_for_font': build/src/libharfbuzz-gobject.so.0: undefined symbol: hb_cairo_font_face_create_for_font (1)

Linking with libharfbuzz_cairo fixes this one, but now I get:

Traceback (most recent call last):
  File "src/sample.py", line 26, in <module>
    hb.cairo_font_face_create_for_font (font)
TypeError: Couldn't find foreign struct converter for 'cairo.FontFace'

khaledhosny avatar Mar 05 '23 19:03 khaledhosny

Traceback (most recent call last): File "src/sample.py", line 26, in hb.cairo_font_face_create_for_font (font) TypeError: Couldn't find foreign struct converter for 'cairo.FontFace'

Humm we're just passing pointers around. Is there an annotation that says it's an opaque pointer?

behdad avatar Mar 05 '23 19:03 behdad

Traceback (most recent call last): File "src/sample.py", line 26, in hb.cairo_font_face_create_for_font (font) TypeError: Couldn't find foreign struct converter for 'cairo.FontFace'

Humm we're just passing pointers around. Is there an annotation that says it's an opaque pointer?

cairo-1.0.gir seems to know what cairo.FontFace is, so I wonder what we are still missing.

khaledhosny avatar Mar 05 '23 19:03 khaledhosny

I get a similar error while using Pango as well:

import gi
gi.require_version('cairo', '1.0')
gi.require_version('Pango', '1.0')
gi.require_version('PangoCairo', '1.0')
from gi.repository import cairo, Pango, PangoCairo

desc = Pango.font_description_from_string ("Sans Bold 27")
fontmap = PangoCairo.FontMap.get_default ()
context = fontmap.create_context ()
font = context.load_font (desc)
PangoCairo.Font.get_scaled_font (font)
Traceback (most recent call last):
  File "test.py", line 14, in <module>
    PangoCairo.Font.get_scaled_font (font)
TypeError: Couldn't find foreign struct converter for 'cairo.ScaledFont'

So I’m starting to think either using cairo types from GI is broken, or we need some magic incantation to get it to work.

khaledhosny avatar Mar 05 '23 20:03 khaledhosny

If I'm reading this right, looks like cairo gi bindings are handwritten, and very incomplete to my eyes: https://github.com/GNOME/gobject-introspection/blob/main/gir/cairo-1.0.gir.in

Eg. the simplest function, cairo_image_surface_create() has no parameters annotated:

  <function name="image_surface_create" c:identifier="cairo_image_surface_create">
      <return-value transfer-ownership="none">
    <type name="none" c:type="void"/>
      </return-value>
      <parameters>
      </parameters>
    </function>

indeed, when I try to call that function, which should take three parameters, I get this error in Python:

TypeError: cairo.image_surface_create() takes exactly 0 arguments (3 given)

Did cairo GI bindings ever work?

behdad avatar Mar 07 '23 22:03 behdad

Did cairo GI bindings ever work?

I don’t really know, it seems like you can use some cairo with gtk, but probably that is the subset that was ever tested?

khaledhosny avatar Mar 07 '23 22:03 khaledhosny

Did cairo GI bindings ever work?

No. Cairo does not have introspection data, outside of the small hand-written GIR that is only used to expose the boxed types of cairo-gobject needed to introspect GTK. Every language that provides a Cairo binding has to have a native binding.

Of course, since the Cairo introspection data is handwritten, it can get out of sync.

ebassi avatar Mar 08 '23 14:03 ebassi

So is there anyway we can get hb-cairo introspection to work, namely the error in https://github.com/harfbuzz/harfbuzz/pull/4150#issuecomment-1455182140 above?

khaledhosny avatar Mar 08 '23 15:03 khaledhosny

You should install pycairo and import it:

import cairo
from gi.repository import Pango, PangoCairo

instead of using:

from gi.repository import cairo, Pango, PangoCairo

This is typically how Cairo is used in Python.

ebassi avatar Mar 08 '23 15:03 ebassi

I tried that already, and I still get the same error:

import cairo
import gi
gi.require_version('Pango', '1.0')
gi.require_version('PangoCairo', '1.0')
from gi.repository import Pango, PangoCairo

desc = Pango.font_description_from_string ("Sans Bold 27")
fontmap = PangoCairo.FontMap.get_default ()
context = fontmap.create_context ()
font = context.load_font (desc)
PangoCairo.Font.get_scaled_font (font)
Traceback (most recent call last):
  File "test.py", line 11, in <module>
    PangoCairo.Font.get_scaled_font (font)
TypeError: Couldn't find foreign struct converter for 'cairo.ScaledFont'

khaledhosny avatar Mar 08 '23 16:03 khaledhosny

Then that's a pygobject and/or pycairo bug:

  • https://gitlab.gnome.org/GNOME/pygobject/-/issues
  • https://github.com/pygobject/pycairo/issues

ebassi avatar Mar 08 '23 17:03 ebassi

Sounds similar to this issue https://gitlab.gnome.org/GNOME/pygobject/-/issues/16, so likely a pygobject issue.

khaledhosny avatar Mar 09 '23 18:03 khaledhosny

Sounds similar to this issue https://gitlab.gnome.org/GNOME/pygobject/-/issues/16, so likely a pygobject issue.

However, CairoFontFace does have a record in: https://github.com/GNOME/gobject-introspection/blob/main/gir/cairo-1.0.gir.in

Same error when you search, other people (mostly on Ubuntu) solved by installing cairo gobject... But that doesn't seem to be my problem here.

behdad avatar Mar 09 '23 18:03 behdad

Sounds similar to this issue https://gitlab.gnome.org/GNOME/pygobject/-/issues/16, so likely a pygobject issue.

However, CairoFontFace does have a record in: https://github.com/GNOME/gobject-introspection/blob/main/gir/cairo-1.0.gir.in

Same error when you search, other people (mostly on Ubuntu) solved by installing cairo gobject... But that doesn't seem to be my problem here.

Yes, but based on this commit (which fixes the cairo.Matrix issue above), manual conversion code is still needed. The pygi-foreign-cairo.c file has nothing for FontFace or ScaledFont.

khaledhosny avatar Mar 09 '23 18:03 khaledhosny

Sounds similar to this issue https://gitlab.gnome.org/GNOME/pygobject/-/issues/16, so likely a pygobject issue.

However, CairoFontFace does have a record in: https://github.com/GNOME/gobject-introspection/blob/main/gir/cairo-1.0.gir.in Same error when you search, other people (mostly on Ubuntu) solved by installing cairo gobject... But that doesn't seem to be my problem here.

Yes, but based on this commit (which fixes the cairo.Matrix issue above), manual conversion code is still needed. The pygi-foreign-cairo.c file has nothing for FontFace or ScaledFont.

Wonder if this is not enough: https://gitlab.gnome.org/GNOME/pygobject/-/blob/master/gi/pygi-foreign-cairo.c#L281

behdad avatar Mar 09 '23 18:03 behdad

That only really helps for properties and signal handlers, not for function arguments and return values, unless those arguments take a GValue.

ebassi avatar Mar 09 '23 18:03 ebassi

I see. Thanks. Okay, I'm binding font-face and scaled-font now.

behdad avatar Mar 09 '23 18:03 behdad

I see. Thanks. Okay, I'm binding font-face and scaled-font now.

I confirm it works with my MR: https://gitlab.gnome.org/GNOME/pygobject/-/merge_requests/236

behdad avatar Mar 09 '23 19:03 behdad

I see. Thanks. Okay, I'm binding font-face and scaled-font now.

I confirm it works with my MR: https://gitlab.gnome.org/GNOME/pygobject/-/merge_requests/236

Excellent!

khaledhosny avatar Mar 09 '23 19:03 khaledhosny

Now, there is still this warning while building HarfBuzz:

../src/hb-cairo.cc:849: Warning: HarfBuzz: hb_cairo_glyphs_from_buffer: argument glyphs: Unresolved type: 'cairo_glyph_t**'
../src/hb-cairo.cc:849: Warning: HarfBuzz: hb_cairo_glyphs_from_buffer: argument clusters: Unresolved type: 'cairo_text_cluster_t**'

khaledhosny avatar Mar 09 '23 19:03 khaledhosny

Now, there is still this warning while building HarfBuzz:

../src/hb-cairo.cc:849: Warning: HarfBuzz: hb_cairo_glyphs_from_buffer: argument glyphs: Unresolved type: 'cairo_glyph_t**'
../src/hb-cairo.cc:849: Warning: HarfBuzz: hb_cairo_glyphs_from_buffer: argument clusters: Unresolved type: 'cairo_text_cluster_t**'

Yeah that one needs more work

behdad avatar Mar 09 '23 19:03 behdad

Now, there is still this warning while building HarfBuzz:

../src/hb-cairo.cc:849: Warning: HarfBuzz: hb_cairo_glyphs_from_buffer: argument glyphs: Unresolved type: 'cairo_glyph_t**'
../src/hb-cairo.cc:849: Warning: HarfBuzz: hb_cairo_glyphs_from_buffer: argument clusters: Unresolved type: 'cairo_text_cluster_t**'

Yeah that one needs more work

It's not even bound in cairo-gobject. So needs to go there first. Then in gobject-introspection handcoded cairo-1.0.gir.in, then in pygobject. I'll try to take a look.

behdad avatar Mar 09 '23 19:03 behdad

It's not even bound in cairo-gobject. So needs to go there first. Then in gobject-introspection handcoded cairo-1.0.gir.in, then in pygobject. I'll try to take a look.

https://gitlab.freedesktop.org/cairo/cairo/-/merge_requests/468

behdad avatar Mar 09 '23 20:03 behdad

Then in gobject-introspection handcoded cairo-1.0.gir.in,

https://gitlab.gnome.org/GNOME/gobject-introspection/-/merge_requests/392

behdad avatar Mar 09 '23 20:03 behdad