gtk-rs / gtk-rs-core

Rust bindings for GNOME libraries
https://gtk-rs.org/gtk-rs-core
MIT License
279 stars 110 forks source link

`pango::Renderer` can't be subclassed #103

Open jsparber opened 3 years ago

jsparber commented 3 years ago

pango::Renderer is mostly useful for creating custom Renderer but it can't be subclassed.

bilelmoussaoui commented 3 years ago

looks not that hard to write, do you want to work on it?

jsparber commented 3 years ago

No, sorry I don't have time right now. I just saw that it was missing, and thought I open an issue for it.

bilelmoussaoui commented 3 years ago

I asked because I thought maybe you needed it for Fractal before next release. In general, everything in gtk-rs-core doesn't have subclassing support except few types in Gio.

jsparber commented 3 years ago

i initially thought i would need it, but thankfully the thing i'm trying to do is some what simpler then what i expected.

sdroege commented 2 years ago

Let's close this then for now until someone has a use-case for this. It's going to be a bit of work to implement and is best done following a specific target use case so we can make sure it actually works correctly.

osa1 commented 2 years ago

How much work is needed here? Are there any similar examples in the repo that I can look and port for this? I want to experiment with rendering pango layouts on OpenGL surfaces.

sdroege commented 2 years ago

Check any of the other classes in e.g. gio/src/subclass or gtk/src/subclass. The equivalent of that is needed here too

bilelmoussaoui commented 2 years ago

Let us reopen this so interested people can find it easily

Lyude commented 2 years ago

How much work is needed here? Are there any similar examples in the repo that I can look and port for this? I want to experiment with rendering pango layouts on OpenGL surfaces.

Did you ever make any progress with this? I ask because I'll probably give implementing this a shot, since I'd like to play around with using a custom PangoRenderer for neovim-gtk

bilelmoussaoui commented 2 years ago

Nothing as far as i know, let us know if you have any questions :)

osa1 commented 2 years ago

Did you ever make any progress with this? I ask because I'll probably give implementing this a shot, since I'd like to play around with using a custom PangoRenderer for neovim-gtk

Nope. What I do instead is I generate texture atlases by generating single-character pango layouts and rendering them to a cairo image surface and then uploading the generated texture to the GPU as a part of a texture. I then do the text shaping manually. Since I only render monospaced fonts it works fine. It wouldn't work for anything more complicated.

Since neovim UI is basically a grid of characters I think the same approach would work for you too.

sdroege commented 2 years ago

That wouldn't work for ligatures, would it? And wide characters like emojis or Chinese would probably also need some special care.

osa1 commented 2 years ago

Yes, it only works for monospace characters as text shaping is simple for monospace characters.

In my app I support ligatures, but they are handled specially. I generate glyphs for supported ligatures separately, and use an efficient lexer when rendering to find if a token (in its entirety, not a substring of it) is a ligature.

I'd be interested in learning other approaches to do as much of the work as possible on the GPU while still doing proper text shaping (with Pango, or maybe using HarfBuzz directly).

Lyude commented 2 years ago

Did you ever make any progress with this? I ask because I'll probably give implementing this a shot, since I'd like to play around with using a custom PangoRenderer for neovim-gtk

Nope. What I do instead is I generate texture atlases by generating single-character pango layouts and rendering them to a cairo image surface and then uploading the generated texture to the GPU as a part of a texture. I then do the text shaping manually. Since I only render monospaced fonts it works fine. It wouldn't work for anything more complicated.

Since neovim UI is basically a grid of characters I think the same approach would work for you too.

I think I might give the pangorenderer stuff a shot first, since the main reason I'm looking into this is because I'd like to see if I can avoid using cairo for the most part with rendering in gtk4.

Nothing as far as i know, let us know if you have any questions :)

Actually I do have one question! I think I have most of this figured out, except for one thing. In the documentation for Pango.Renderer it mentions both that this is an abstract class, and that it contains a pointer to a PangoMatrix. I've gone through some of the code in both gtk4-rs and gtk-rs-core, but it's not immediately apparent to me if there's any other examples of subclassable-abstract classes with their own data - so I'm not entirely sure how to expose that. Does anyone know the answer to this?

sdroege commented 2 years ago

Actually I do have one question! I think I have most of this figured out, except for one thing. In the documentation for Pango.Renderer it mentions both that this is an abstract class, and that it contains a pointer to a PangoMatrix. I've gone through some of the code in both gtk4-rs and gtk-rs-core, but it's not immediately apparent to me if there's any other examples of subclassable-abstract classes with their own data - so I'm not entirely sure how to expose that.

You mean the matrix in struct PangoRenderer? There's no difference in that regard between abstract and non-abstract classes. You can already access that nowadays with matrix and set_matrix