Haiku-native vector glyph format?

I don’t understand this, we currently ship Noto Emoji which is a perfectly normal monochrome font containing most of them. They have done a rather good job with it, too: Noto Emoji - Google Fonts

And if we want color ones, we can pick from the color version of that font: GitHub - googlefonts/noto-emoji: Noto Emoji fonts
Note that it is shipped as a font file, but also as PNG and SVG files. So nothing prevents storing these as BResources in an app and using them. We can even try converting the SVGs to HVIF format. And then, we can use them as a normal icon, not as a font.

So there are several completely unrelated problems here:

  • How do we want emojis to look when used inside text (such as in a forum or an instant messaging client where you’re expected to find them used this way),
  • How do we want them to look when used as UI elements (should it be the same theme or something different? Surely in this case it should fit with the existing “toolbar” set of icons?)
  • In either of these cases, how do we encode them. For the first one, Unicode and font rendering makes sense, for the second one, maybe not so
  • And finally, how do we store the graphics. The Noto Color emoji is 10MB for 3500 icons (at least that’s how much I found in the SVG directory), so that would be about 3KB per icon, it seems a bit much. They are using a bitmap storage format (I think it’s PNG files) so that’s not great. Surely a color vector system would be better, and we have HVIF right there.

HVIF can be improved by allowing the sharing of shapes and colors when related icons are grouped together. That was the intended purpose of this thread. Should I edit it to that effect?

HVIF is perfectly fine for it’s usecase.
Changing it to do that would effectively be a new format, and should be designed specifically then. But I don’t see any need to be honest.

edit: UI elements can be done with HVUf, a BPicture, hardcoded drawing instructions, an image file etc.

The blobs are back, actually with the new version of noto emoji : )

Well, in that case it is solving a problem that doesn’t yet exist.

So, how about this, try to mame better use of what we already have:

  • HVIF for icons in the GUI
  • Existing PNG based fonts rendering emojis in text

Let’s try to see if there are places where we want to use these more, and what the exact usage is, and maybe more importantly, the things that are not convenient to do or not efficient. I think we can go pretty far with HVIF as it exists now already, before we start to worry about sharing even more things between icons.

I think without that, there is nothing to benchmark against?

1 Like

An HVIF derivative format allowing shared elements was the proposal. If it can grow remains to be seen. A nice, compact binary format that fares well against SVG in most of its usecases is what I find attractive about HVIF. Let’s see how far we can go from here.

GUI elements need to follow the color schemes of the color preferences and themes. Engineering those shared colors would be a start at least.

PNG based emoji are not vectotized but a general SVG to HVIF importer would show how HVIF stacks up against SVG in all cases. Let’s at least keep that. Is there a ticket for that or is it needed? I’ll search.

re:SVG to HVIF

Issue found that may be a blocker to arbitrary SVG imports: https://dev.haiku-os.org/ticket/13978

Most seem to be based on existing Icon-o-Matic code when dealing with importing SVG. So much for replacing SVG with HVIF all the time. :thinking:

HVIF is meant for a very specific role: relatively simple and small images. It is not meant as a generic equivalent to SVG. That’s how it manages to be smaller than SVG.

If your plan is to have something as generic as SVG, you have to “pay the price” for it in terms of compactness. If you need a generic format, SVG isn’t that bad, really (if you optimize and compress it).

In fact HVIF is a good example of what I said earlier: it ended up the way it is because it was done with the simplicity and cleanliness of the BeOS icons in mind. To represent these, a low number of shapes was needed. It doesn’t do very well on anything else (but emojis are similar, in that they need to be simple and readable at small sizes).

Consider for example Mac OS, which went with super photorealistic icons instead. If a specific format was developped for these, vector formats might be ruled out quite quickly, because in these cases, it would possibly be larger than a bitmap file, and considerably slower to render.

So, let’s not mix everything here. What do you want to do? A generic image format like SVG, or something specific just for emojis? In the latter case, do you want to do all the possible emojis ever, or pick a theme and try to optimize that specific one?

In these situations, the more generic solution isn’t always the best.

1 Like

Fine. Let’s drop the emoji image discussion for now and focus on ways to make a better SVG replacement. If it ends up being a built-up HVIF alternative or IFF DR2D derivative instead, let that be a non-issue.

Here’s a proposal:

Basic Specifications

  • 16-bit coordinate components in integer format (32 bits total for X and Y components put together)
  • subshapes and color palettes indicated in the header for common usage (as previously mentioned) to save on rerendering common vector forms to bitmap format
  • subshapes, once rendered, should have mirroring, offset translation and texture rotation features common to a modern GPU

Implementation Suggestions

  • all points grouped together so they can be scaled using vector ops (16 bit coordinate componant by 16 bit scale factor multiply, discarding low 16 bits of 32 bit result for scaled component results)
  • gradients allowed in color definitions to keep shape count low like HVIF and compatibility with SVG achievable

Feel free to add suggestions.

I just think anyone should be able to use any font in whatever way they choose. No need to do any work for a user, no conversions or pack as resources. Just pick a font with the icons you like and start using it. It is already done today by many apps, I guess it makes app development faster and resource reuse better as many apps can share a font. However I think the font format for icons is still rather primitive, unless OpenType did something interesting. And that is why I think the original idea is worth exploring.

Color icon fonts are png files encapsulated in a png. This format grew out of liminations of the web (it’s faster to load one large file than many small ones over http). We can support it, but I’m not convinced it’s the solution that matches our needs the best for native apps. BResource solves a similar problem for us: it’s better to store one big file on BFS than many small ones.

Then there is the convenience of using already existing fonts. Sure, they exist and we can support them in app_server and there’s no reason not to. But I wouldn’t go as far as recommending it for native apps?

Good day,

Wouldn’t be this something like NerdFonts?:

Those ttf fonts can be used in Haiku without issues, AFAIK.

Regards,
RR

Welcome to the thread! TrueType is monochrome. Some glyphs need to have more than a foreground and background color. I was thinking more like an SVG alternative that is not XML based.

Interesting proposal. Are you thinking of using a translator to convert SVGs to your format or having a dedicated editor like Icon-O-Matic to draw images in your format? A translator would make it simple to develop the format but would limit some features such as shape and color sharing. A full-fledged editor would allow you to do much, much more, but would also require a lot of time to develop.

The choice is yours. Choose wisely :wink:

This all feels a bit NIH, and from my experience, using standards ends up with a more long term solution. Because if you start to invent niche solutions, those solutions will either need to be very flexible or dropped when a standard comes in. Otherwise you end up with a mess of some parts working in one scenario, but not others, and some parts not having feature parity with the new standard.

BeOS used TTF for a reason, because creating your own fonts, much like skinning an OS UI, is nice in theory, but the devil is in the detail. If there is an existing standard, would be good to implement that. Then and only then, add in extensions and allow custom formats - if there is a real need for it.

1 Like

GitHub - google/iconvg: IconVG is a compact, binary format for simple vector graphics: icons, logos, glyphs and emoji. should be mentioned in the “prior art” section. I think there was some discussion, including research of other formats, either when this was designed, or when something else was being designed and had to explain why iconvg was not perfect for their needs.

But it also doesn’t explore the idea of sharing shapes/paths/gradients between multiple images, which is worth exploring if you have a lot of similar images to encode

Maybe this is what you’re thinking of. It includes discussion of alternatives to HVIF and a simple file size comparison between SVG, HVIF, and TinyVG.

I was thinking of making it a spin-off of HVIF so the Font-o-Matic editor could share code with Icon-o-Matic. Now I’m not so sure. I’ll have to look at the HVIF specification again. Now that I’m aware of the 256 node limit in Shapes and in the total number of shapes, I see that HVIF might not work out-of-the-box the way I hoped. I’ll also have to scope out the competition.

It would be possible to make the shapes section null terminated instead of having a count at the beginning. The HVIF format would then support unlimited shapes at a total cost of 0 bytes :melting_face:

Would that be for definitions or invocations as well? If the invocation were stored in a byte, that would not be 0-cost.

Ah, you’re right.

Something else I was considering for subshapes was a dependency mapped subshape being potentially rendered out of other subshapes itself. As a font-glyph example in a Times Roman-like font, the capital H is 2 capital I’s connected with a cross piece. Likewise the capital A is a y-mirrored capital V with a cross piece.

To render these quickly, the dependency map would be implemented using a thread pool like Ninja build does for compiling.

Am I starting to overengineer this?