go-text / typesetting

High quality text shaping in pure Go.
Other
88 stars 11 forks source link

Add support for font selection #17

Closed benoitkugler closed 11 months ago

benoitkugler commented 2 years ago

Proposal

This is a draft proposal to add support for font discovery and semi-automatic font selection to go-text.

The problem to solve

One of the task go-text is currently not able to perform is to choose a font to use for a text run, given a font description. This is required for instance to implement rendering of HTML files (which is my main use case for go-text).

Before outlining the proposed solution, let me precise what I mean by "font description" and "choose a font".

Font description

A font description is a possibly incomplete list of attributes that describe the intention of a document author about the text font.

More precisely, using the CSS terminology, a font description is composed of a font family name (or a special keyword to describe commonly used families) and some style attributes, like stretching, weight and style.

Font resolution

When rendering a document, a layout engine has to resolve this description against the actual fonts it has at its disposal. This requires a list of the font files and for each of them, several properties such as

The issue

Using a font library, you can pretty easily query the information mentioned above. However, this would require to load every font files on your machine (many hundreds for standard systems).

One solution

The solution used on Linux systems, implemented in the fontconfig library, is to build once for all an index, that is a list of footprints or patterns (one for every font), which are lightweight summaries of the font content. Building this index is time consuming, but loading it from the disk is really fast, meaning that once it has been build, you don't have to worry about performance anymore. The second goal of the library is then to be able to resolve a font file from a font description. This is roughly speaking implemented by comparing the font description against every footprint (which again is very efficient since you don't have to load the font file in memory).

The actual proposal for go-text

I propose to implement and add to go-text a simplified version of fontconfig, with two main parts :

A possible implementation sketch

As implementation guidelines, I would follow the fontconfig implementation for the first part, and the CSS specification (see font-kit) for the second.

As a starting point, we could use something like the following types :

type FontDescription struct {
     Family []string // many families possible
     Style 
     Stretch
     Weight
 }

type Footprint struct {
       Source Source
       Family string
       Style
       Stretch
       Weight
       RuneCoverage 
       LanguageCoverage
}   

type Source struct {
    FileID string
    FontIndex int // to support font collections
    InstanceIndex int // to support variable fonts
    FontFormat // optional, to make font loading easier if we support multiple font formats
}

The first part of the package is about creating, saving and loading a []Footprint. The second is about selecting a Footprint given a FontDescription and a text input.

This is only a sketch of a possible implementation and I'm happy to discuss changes or alternatives !

Scope and relation with the current go-text API

This proposal is mostly additive, and operates in early stages of the shaping. The font resolution step is somewhat a generalization of the font fallback API provided by SplitByFontGlyphs. A new package should be created (fontkit ? fontconfig ? font/database ?).

Prior art

This proposal takes inspiration from the following existing projects :

whereswaldon commented 2 years ago

Hey @benoitkugler, thanks for writing this up! This is an important problem, and it has a lot of complexity (as you have highlighted). Also, I know very little about this aspect of fonts, so I appreciate all of the context you provided.

I do have some questions and thoughts about your proposal:

Thanks for getting the discussion started here! I don't think any of the above is intractable. I just raised the concerns that were apparent to me on first reading so that we can talk through them.

benoitkugler commented 2 years ago

I do have some questions and thoughts about your proposal:

Thanks for the feedback and the accurate questions !

how do other operating systems like Windows and macOS handle this problem

They provide their own API : CoreText on macOS and DirectWrite on Windows. (But I'm not familiar with these APIs)

The first time an application runs using this library to present text, does the interface have to block waiting for us to generate this index file? Interfaces generally want to present text, which will require loading and using a font. In the pathological case (a font designer's laptop, say) the user could have thousands of fonts that must be indexed. I assume that would take a very noticeable amount of time.

Very good point. The indexing step is indeed noticeable (about 5 seconds) on my laptop, so it should be run as a background task or as a setup step. Not ideal for GUI apps...

Where is the index of fonts stored? It seems like it would be wasteful and expensive for each application using this library to maintain its own redundant copy of the font index, but storing them in a shared location brings its own challenges, most notably versioning and concurrency.

Fair point again. I have not thought about other solutions than per-application database. As an idea, I end up with a 170kb index file on my laptop.

How do we know when we need to perform an update to the index?

Good question as well. Maybe it's fine to let the user decide ? As a comparison point, how Fyne and Gio currently deals with user fonts ?

Is there a way that we can re-use the operating system's existing font cache? Either by wrapping it in a consistent cross-platform interface for querying it or by reading the contents and converting them to our own format? That would allow us to skip generating the index by traversing all of the files ourselves.

This is the solution adopted by font-kit : they call to the appropriate system-dependent library. This indeed avoid to generate our own index. I am a bit shaky about taking this approach, because I would rather avoid writing different code for different platforms, with probably different behavior and issues... But this is maybe the best (only ?) option..

Thanks for getting the discussion started here! I don't think any of the above is intractable. I just raised the concerns that were apparent to me on first reading so that we can talk through them.

I realize that my proposal is rather naïve and maybe not suitable for GUI toolkits. I had in mind a server application, where the startup time is not an issue (or where you can scan the fonts before starting), and where fonts on the system are not changing frequently. The constraints for GUI applications are maybe too demanding for this approach to work...

whereswaldon commented 2 years ago

They provide their own API : CoreText on macOS and DirectWrite on Windows. (But I'm not familiar with these APIs)

Okay, cool. We'll have to look into the font querying aspect of these APIs to see what kind of info they provide and how similar it is to our index format. Maybe we can trivially scrape that API to build an index?

Very good point. The indexing step is indeed noticeable (about 5 seconds) on my laptop, so it should be run as a background task or as a setup step. Not ideal for GUI apps...

Yeah, we definitely need a mechanism for acquiring fonts faster than this for app startup. If we could build something that let an application resolve a small number of fonts very quickly (and potentially with suboptimal results) while the index was being built, I think that would handle this.

Fair point again. I have not thought about other solutions than per-application database. As an idea, I end up with a 170kb index file on my laptop.

Okay, so the disk waste isn't a big deal. I'd be more concerned about the computation and I/O load of regenerating the database.

Good question as well. Maybe it's fine to let the user decide ? As a comparison point, how Fyne and Gio currently deals with user fonts ?

I don't think the user will generally know/care when their system fonts change. I'd rather provide a function that applications can call to check the current index against the installed fonts and reconcile them if need be.

As far as how Fyne/Gio solve this, I think we don't. I don't know 100% for sure about Fyne, but Gio at least requires applications to bundle fonts within their applications. The app parses the bundled fonts at startup and then does simple matching against that list of fonts when shaping strings. It's possible to load system fonts manually, but we don't provide any mechanism to do it.

This is the solution adopted by font-kit : they call to the appropriate system-dependent library. This indeed avoid to generate our own index. I am a bit shaky about taking this approach, because I would rather avoid writing different code for different platforms, with probably different behavior and issues... But this is maybe the best (only ?) option..

Yeah, I'm not eager to create platform-specific code either. I think we should still provide a means of generating an index without that, but it would be cool to accelerate the process by converting the platform's existing font database into our index format. That would almost certainly be faster than generating it ourselves, and it would have the added benefit of being updated when the system font hooks occurred.

I realize that my proposal is rather naïve and maybe not suitable for GUI toolkits. I had in mind a server application, where the startup time is not an issue (or where you can scan the fonts before starting), and where fonts on the system are not changing frequently. The constraints for GUI applications are maybe too demanding for this approach to work...

The server use-case is very legitimate. I think we're unlikely to create a single function that works well for both GUI and batch-processing use-cases, but I think we can create a common index format with functions that help build the index, and then we can specialize ways of using those functions for the GUI and server. GUIs would rather incrementally build the database in the background after resolving the bare minimum fonts (probably), or would rather use the index in a degraded mode rather than wait for the full index to be built.

sbinet commented 2 years ago

a drive-by comment: is the intention to reuse the index files produced by fontconfig or to create a new set of index files that are inspired by fontconfig design (possibly with a different format or on-disk representation)?

benoitkugler commented 2 years ago

a drive-by comment: is the intention to reuse the index files produced by fontconfig or to create a new set of index files that are inspired by fontconfig design (possibly with a different format or on-disk representation)?

@sbinet Well, my first intention was to create a new set, but it seems to induce serious challenges, as @whereswaldon noticed.

benoitkugler commented 2 years ago

@whereswaldon

I think we should still provide a means of generating an index without that, but it would be cool to accelerate the process by converting the platform's existing font database into our index format. That would almost certainly be faster than generating it ourselves, and it would have the added benefit of being updated when the system font hooks occurred.

Would you suggest to use the platform's existing font database only as the first build step ? or for every execution ? That is, converting the platform database into our index format and save it on disk ? Or load it at each execution into memory ?

Yeah, we definitely need a mechanism for acquiring fonts faster than this for app startup. If we could build something that let an application resolve a small number of fonts very quickly (and potentially with suboptimal results) while the index was being built, I think that would handle this.

GUIs would rather incrementally build the database in the background after resolving the bare minimum fonts (probably), or would rather use the index in a degraded mode rather than wait for the full index to be built.

I really like this idea. I think it should not be hard to load a few fonts (since the performance issue is only linked to the number of fonts you scan). It is not clear too me how to choose them though. Maybe a hard coded, os-dependent, list of fonts which should always be present on standard machines ?

whereswaldon commented 2 years ago

a drive-by comment: is the intention to reuse the index files produced by fontconfig or to create a new set of index files that are inspired by fontconfig design (possibly with a different format or on-disk representation)?

@sbinet Well, my first intention was to create a new set, but it seems to induce serious challenges, as @whereswaldon noticed.

My thought was to potentially create a new index format, but maybe accelerate the indexing process by scraping the existing platform font registry.

Would you suggest to use the platform's existing font database only as the first build step ? or for every execution ? That is, converting the platform database into our index format and save it on disk ? Or load it at each execution into memory ?

My first instinct is that we'd need to check the font index's consistency at every application startup. The simplest (but least performant) option is to store the index only in memory and regenerate it from the system fonts each time. I suspect a better approach would be to persist the index, then perform a background incremental consistency check of the index against the system fonts. This means that applications would pick up new fonts (albeit with some delay) when restarted.

It might make sense to implement the memory-only method first, then explore everything else as potential optimizations.

I think it should not be hard to load a few fonts (since the performance issue is only linked to the number of fonts you scan). It is not clear too me how to choose them though. Maybe a hard coded, os-dependent, list of fonts which should always be present on standard machines ?

I'm glad that doesn't seem impossible! I think a hard-coded list may be fine, or perhaps a mechanism like "choose the first font with characteristic X on the machine". For instance, Linux is notoriously unstandardized. I'm not sure there is a font that is known to be available on all Linux machines. However, we could scan the fonts and return the first serif, sans, mono, and whatever other high-level characteristics are important. We could also try a hard-coded list of fonts prior to the scan in an effort to skip it. "Does the machine have DejaVu? If yes, just use those."

This is taking shape in my head as an API that communicates with an asynchronous font indexing process. You can make requests for a font, and those requests block until at least one font candidate is known to the index. The best known candidate at a point in time is returned to a requestor. When the indexing process is complete, the best match of all system fonts will be the best known candidate. The pathological case is if the system has zero fonts that match. The design I suggest will force applications to block until the end of indexing if they request a font with no matches.

We could also allow the application developer to bundle fonts into the app and register them with the index in advance. This guarantees that a candidate will always be found quickly, allowing fast application startup. Then again, we could simply allow the app developer to provide a set of startup fonts and then force them to wait until indexing is totally complete before requesting others. That's a simpler design, but it means applications are bigger due to the need to bundle the font data.

Speaking for Gio, I think we'd love to not need to bundle font data into the application if there's a viable path to doing so.

Sorry that the above is kind of a rambling mess. Those are the thoughts I have right now. Hopefully they spark something useful. :D

benoitkugler commented 2 years ago

After a quick research, I found that font-kit use these bindings to call CoreText on macOS. The issue is that I've not found similar bindings for Go. Does somebody knows if there is an easy way to hook such system API without having to write the bindings ourselves ? If not, the solution to use system font library seems less attractive...

Having said that, if we manage to implement an asynchronous font indexing process, it seems fine to use our own, fontconfig-inspired index....

As you said, one important feature would be to perform a background incremental consistency check of the index. (By the way, I think fontconfig actually have something similar implemented, although I've dropped it from my port, because I found it very intricated. I now better understand the need for it !) The idea could be to also store the file tree state into the index (with modification time stamps I guess, or maybe a hash ?), not just the list of font patterns. Then, when walking the file system, you can quickly check if files should be added, deleted or updated.

Assuming everything else works, and that we use a shared index file, there is still the question of creating/updating the database from different applications. We would need a way to ensure at least one write succeed (as well as read). By the way, correct me if I'm wrong, but I think we do not really care to properly handle concurrent write, since both processes should write the exact same index. Anyway, maybe lockedfile is a good fit ?

benoitkugler commented 2 years ago

We could also allow the application developer to bundle fonts into the app and register them with the index in advance. This guarantees that a candidate will always be found quickly, allowing fast application startup. Then again, we could simply allow the app developer to provide a set of startup fonts and then force them to wait until indexing is totally complete before requesting others. That's a simpler design, but it means applications are bigger due to the need to bundle the font data.

@whereswaldon I think we want this feature anyway, since I would need to also add fonts from memory (after downloading them from the net for instance). So we should provide something like a AddFont(source font.Resource), the source content being either bundled with the app or obtained from an other source.

benoitkugler commented 2 years ago

We could also allow the application developer to bundle fonts into the app and register them with the index in advance. This guarantees that a candidate will always be found quickly, allowing fast application startup. Then again, we could simply allow the app developer to provide a set of startup fonts and then force them to wait until indexing is totally complete before requesting others. That's a simpler design, but it means applications are bigger due to the need to bundle the font data.

Speaking for Gio, I think we'd love to not need to bundle font data into the application if there's a viable path to doing so.

Quick idea: we could maybe allow the user to give hints to the index process to where to look for fonts. So that, during the initial font scan, the font wanted by the developer is quickly fetched. This could take the form of a font directory or a font file name.

andydotxyz commented 2 years ago

Good question as well. Maybe it's fine to let the user decide ? As a comparison point, how Fyne and Gio currently deals with user fonts ?

I don't think the user will generally know/care when their system fonts change. I'd rather provide a function that applications can call to check the current index against the installed fonts and reconcile them if need be.

I don't think that the user (and possibly even developer) will know, or should have to, if a new font is installed. In Fyne where things like this happen we do a quick check on app start for changes since last and in some cases register for file change notifications to reload

As far as how Fyne/Gio solve this, I think we don't. I don't know 100% for sure about Fyne, but Gio at least requires applications to bundle fonts within their applications. The app parses the bundled fonts at startup and then does simple matching against that list of fonts when shaping strings. It's possible to load system fonts manually, but we don't provide any mechanism to do it.

Basically the same for Fyne, except that we bundle in the toolkit so developers don't have to.

andydotxyz commented 2 years ago

Quick idea: we could maybe allow the user to give hints to the index process to where to look for fonts. So that, during the initial font scan, the font wanted by the developer is quickly fetched. This could take the form of a font directory or a font file name.

This may relate to FileID string in the initial sketch, but I don't think we should depend upon file/directory paradigm. Fonts could be available through other means. iOS and Android introduce many exciting challenges if you assume a standard filesystem.

benoitkugler commented 2 years ago

This may relate to FileID string in the initial sketch, but I don't think we should depend upon file/directory paradigm. Fonts could be available through other means. iOS and Android introduce many exciting challenges if you assume a standard filesystem.

Huh, fair enough. So we should probably express the hint as a font description. This is what @whereswaldon already suggested : we would do a "partial" scan, returning as soon as possible. I'm still a bit worried of the scan time. Maybe we could only scan the font family name : I think it may be implemented more efficiently than querying the whole font footprint.

whereswaldon commented 2 years ago

So what's our next step? Do we need to start trying to implement this font scanning for different platforms and get a sense of the speed and options for how we would achieve a partial scan?

benoitkugler commented 2 years ago

So what's our next step? Do we need to start trying to implement this font scanning for different platforms and get a sense of the speed and options for how we would achieve a partial scan?

Makes sense to me. One check I would like to make is how long a scan for only family names is. I have almost the logic ready in fontconfig, I just need to adjust the font library to add a "partial" loading mode (and hook it up in fontconfig).

benoitkugler commented 2 years ago

Maybe an other step would be to properly assess the cost of using system libraries. At a first glance, it seems to involve writing quite extended bindings, but I may have missed something.

whereswaldon commented 2 years ago

Yeah, assessing the use of system libraries is important. I think we'd prefer to not add CGO dependencies if we can help it, but I'm unsure whether that's possible (especially to support mobile platforms like iOS/Android).

andydotxyz commented 2 years ago

I wonder if this is actually quite a large item of work, but peripheral to shaping / rendering etc. Should it therefore be in a separate repo which can be utilised if apps want to do such system lookups? That might avoid potential concern about initial lookup times as it would be specifically opt-in...

benoitkugler commented 2 years ago

I wonder if this is actually quite a large item of work, but peripheral to shaping / rendering etc. Should it therefore be in a separate repo which can be utilised if apps want to do such system lookups? That might avoid potential concern about initial lookup times as it would be specifically opt-in...

Thanks for bringing this up !

I definitively agree that it should be an opt-in feature.

However, I think it is still rather closely connected to text shaping : in my use case, the high-level shaping process should include a font selection step. I mean that the input of the shaper would be text + font description and the shaper would automatically choose the font.

We should try to decouple the font selection step from the rest of the logic as much as possible, but I suspect it won't be that easy. The main reason it that, when you have a large number of candidate fonts, you don't want to load them all in memory. This implies that you can't really perform a preliminary font descriptions->font.Faces step and then forgot about the font descriptions.

Thus, this implies an additional layer reasoning on font descriptions, not on resolved font.Face.

We could provide two kinds of API : one to work with font.Faces and a second to work with font descriptions. Or we could unify both using for instance a

type Fontmap interface{
     // ResolveFont select the closest face to 'description' supporting the given codepoint 'r'
     ResolveFont(description FontDescription, r rune) font.Face
}

In the case where you already know the font.Face you want to use, you would implement a Fontmap as simply returning this face. In the more general case where you want automatic selection, you would use the font pattern index considered in this thread.

benoitkugler commented 2 years ago

I've played a bit with the idea of a "partial font scan", meaning that we query only a minimum of information, not the full font footprint, in order to have an acceptable initial lookup time.

Querying only the family name of the font, the scan time is an order faster. I get the following numbers on my Linux laptop, scanning the /usr/share/fonts folder (containing 1980 files) : 0.25 secs scanning 1782 font files, accepting Opentype/Truetype, Type1 and bitmap (PCF) fonts 0.05 secs scanning 844 font files, only accepting Opentype/Truetype files

It sounds reasonable to me, especially if we add a shortcut logic. What do you think ?

If you want to try on your devices, the (prototype) functionality is exposed in the PartialScanFontDirectories function.

andydotxyz commented 2 years ago

We could provide two kinds of API : one to work with font.Faces and a second to work with font descriptions.

Combined with

In the case where you already know the font.Face you want to use, you would implement a Fontmap as simply returning this face.

And it feels like we will have to write more code or understand more about the library to perform the simplest of tasks (I have a font and some text, please shape and render). It just feels like scope creep for a typesetting API, and given that the APIs currently take Font faces as input it would be (as you hinted) a potentially large change to the input types as well. Given that neither Gio nor Fyne have added this functionality yet but have viable text rendering it seems like it's not core in the same way that shaping and rendering are.

From what I can understand you're proposing that we integrate into shaping the ability to look up fonts based on hints instead of resolved fonts? If that is the desire then how is it not possible that the font hint -> font resolution could be done before calling shaping? Unless I am missing something the glyphs in a font cannot provide such hints that would alter the chosen font in neighbouring sections?

benoitkugler commented 2 years ago

I see your point about adding complexity for simpler task. So indeed, we should add this font resolution step only as an additional API and not modify the current one.

how is it not possible that the font hint -> font resolution could be done before calling shaping

I was probably not clear, but I meant that I would like to have a all in all shaping function that is capable of choosing the fonts and then shaping the text. The basic flow would be given one font description, to resolve the font faces and then call SplitByFontGlyphs. However, this approach does not scale if you have a lot of font matching, because you would load them all in memory to build the font.Faces. That's why we would probably need something like the proposed Fontmap.

Sorry for this blurry thoughts, it will get more precise when we move on !

whereswaldon commented 2 years ago

Yeah, this task has a lot of complexity. We should be able to offer the API @benoitkugler wants by layering a font resolution API on top of what we have now.

andydotxyz commented 2 years ago

Given that we have moved to a monorepo I think we need to be very careful about scope and how much code/dependency is brought in by default. A basic app is going to be 3MB larger by including the go-text/typesetting code as it exists now and we haven't yet approached how rendering and other core features will get handled.

whereswaldon commented 2 years ago

A basic app is going to be 3MB larger by including the go-text/typesetting code as it exists now

How did you measure this? That seems like a lot. It's certainly much more than I expected.

andydotxyz commented 2 years ago

How did you measure this?

Because feature/go-text is a branch on the Fyne repository I built the same app using develop and go-text and compared.

benoitkugler commented 2 years ago

If the font resolution layer is in a separate package, and the main shaping package only provides a hook, for example as an interface, without importing the additional package, applications which don't need this feature won't see their binary size grow, right ?

Regarding binary size, it is probably coming from the various unicode tables that harfbuzz need. Maybe we can optimize that..

benoitkugler commented 2 years ago

I'll try to summarize the current state of the discussion, feel free to correct the following statements if they are biased !

There is interest in system font discovery to avoid bundling fonts with the executable.

The initial (first use of the app) lookup time must be tiny : to do so a partial scan (matching only font family for instance, and returning early) is possible : it would return a limited number of font.Face(s), directly usable.

The proper scan process must include a check for consistency, and be able to incrementally update an existing index, so that the scan may be triggered periodically (say at each app startup), to maintain the index up to date with fonts being installed/removed.

The font index persistent storage should be shared by all the applications using go-text. This introduces versioning and concurrency issues that need to be solved. A first step could be instead to use a per-app database.

Regarding the creation of the font index, two options have been considered :

Regarding the interaction of this feature with the current API :

My personal conclusion/current understanding is then :

Additional thought : maybe this feature is just not suitable for the go-text scope ? In this case I would start to implement it as a new package in textlayout (and see later on how to use it with go-text shaping pipeline).

gedw99 commented 2 years ago

Is there any intent to support the web and Google Font API https://developers.google.com/fonts/docs/getting_started

There is an API to ask what fonts are available too. You need an API Key though. https://developers.google.com/fonts/docs/developer_api

Typically a golang dev would put the fonts onto their server, and so then server them to the gio wasm client. then they dont need to use https://developers.google.com/fonts/docs/developer_api

whereswaldon commented 2 years ago

@benoitkugler I think your summary is accurate.

since it seems possible to implement a fast initial lookup, I would rather go for the pure go implementation of font scanning.

I agree.

maybe this feature is just not suitable for the go-text scope?

I thought that finding system fonts was in scope. If we wanted, we could put it in a separate repo (again), but I think a pure-go option would be great. However, on mobile OSes (a major target for Gio/Fyne) it may not be possible to implement this feature in pure go. The CGO would be hidden behind build tags though, so it may not matter.

@gedw99 brings up a good point about WASM support. I definitely think that resolving system fonts using a browser API would be possible. However, I do not think that looking up fonts via the Google Fonts service is in scope. Application developers who want to do that would need to build that support themselves.

Typically a golang dev would put the fonts onto their server, and so then server them to the gio wasm client

I would actually hope that devs would use the browser to attempt to use fonts already available on the device, but I suppose that isn't always possible. Either way, we plan to support loading fonts from memory (allowing the network use-case) and from the OS.

benoitkugler commented 2 years ago

I've opened #18 as a much simpler change to support automatic font selection. It is compatible with this proposal, but I would also personally be happy with #18 accepted and this current issue postponed.

benoitkugler commented 2 years ago

However, on mobile OSes (a major target for Gio/Fyne) it may not be possible to implement this feature in pure go. The CGO would be hidden behind build tags though, so it may not matter.

@whereswaldon I'm not sure to grasp the issue with mobile Oses. Could you add some context or point me towards references ?

whereswaldon commented 2 years ago

@benoitkugler My original concern was that on Android/iOS, it might not be possible to enumerate the fonts using the file system. I thought access to them might be mediated through a Java/Obj-C API. However, this post suggests that at least Android does present them on the file system. iOS is still an open question.

whereswaldon commented 1 year ago

We haven't added to this discussion in a while, but scanning the system for fonts is still an important feature to explore. What is the best way to move that forward? @benoitkugler Do you want someone to try to rebase the font-scan branch onto main?

benoitkugler commented 1 year ago

@whereswaldon I should be able do it in the next days. I wasn't sure we reached a consensus on the implementation details, but I can definitively rebase and open a PR to discuss concrete issues !

whereswaldon commented 1 year ago

I think that would be great. Thank you!

benoitkugler commented 11 months ago

Closed by #63