Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Improve/fix OpenMoji Colorfont (and Black) #93

Open
b-g opened this issue Dec 2, 2019 · 46 comments
Open

Improve/fix OpenMoji Colorfont (and Black) #93

b-g opened this issue Dec 2, 2019 · 46 comments

Comments

@b-g
Copy link
Member

@b-g b-g commented Dec 2, 2019

The OpenMoji colorfont is currently just a proof of concept and only works in Firefox.

We hope to improve this to proper colorfont in the near future (or at least in the long run). Sorry + stay tuned and follow this thread for updates!

@b-g
Copy link
Member Author

@b-g b-g commented Dec 2, 2019

@b-g
Copy link
Member Author

@b-g b-g commented Dec 2, 2019

This is to gather a few links.

Currently we use https://github.com/hfg-gmuend/openmoji/blob/master/font/README.md basically SVGinOT Color Font Builder a 3-4 year old and stale project. The resulting Colorfont seem just partly to support the standard. They just work in Firefox :(

Other links:

@bohnacker
Copy link
Member

@bohnacker bohnacker commented Dec 3, 2019

To simplify the discussion:
Which format should we support? Right now, there are four:
PNG based: Google's CBDT/CBLC tables and Apple's SBIX table
Vector based: Microsoft's overlapped glyphs (COLR/CPAL tables) and Mozilla and Adobe’s SVG (SVG table)

These formats are supported as follows at the time (source: https://pixelambacht.nl/2014/multicolor-fonts/):
Bildschirmfoto 2019-12-03 um 19 30 53
Bildschirmfoto 2019-12-03 um 19 30 43

Checking with https://pixelambacht.nl/chromacheck/ there also seems to be supported SBIX in Chrome.

My opinion: there's no way around SVG because it's much more powerful than COLR. I guess, sooner or later all browsers will support SVG Color Fonts.

Our situation:
Bildschirmfoto 2019-12-03 um 19 23 40
From left to right: Chrome, Firefox, Safari (I'm on Mac, so no quick check for Edge, ...)

Safari should support SVG Color Fonts. So, that's a bug.

@b-g
Copy link
Member Author

@b-g b-g commented Dec 3, 2019

Hi @bohnacker, many thanks for putting this together. I'm agnostic and happy to support a single standard e.g. SVG properly ... just it should be 100%. Currently our colorfont is just rendered in Firefox, but should also usable in Safari, Adobe CC, Sketch, Affinity ... which is not the case. Also @dnlutz is strongly in favor of SVG ... Hence I think SVG is the best bet, however I couldn't find a good tooling for it back at the beginning of 2019. Also note: Google Noto Emoji tooling is PNG based.

@AndydeCleyre
Copy link

@AndydeCleyre AndydeCleyre commented Dec 6, 2019

I don't know what joypixels (emojione) is doing, but their color font seems to display nicely in browsers and qt apps (including konsole) on Arch linux with the repo package, which fetches joypixels-android.ttf.

@danielleontiev
Copy link

@danielleontiev danielleontiev commented Dec 6, 2019

The b/w font looks damaged as well for me in LaTeX:
uwSWqRS

@b-g b-g changed the title Improve/fix OpenMoji Colorfont Improve/fix OpenMoji Colorfont (and Black) Dec 9, 2019
@b-g
Copy link
Member Author

@b-g b-g commented Dec 9, 2019

Hi @bohnacker, https://www.glyphrstudio.com/online/ a free online font editor might be interesting in terms of debugging the black font. (But also no colorfont support currently glyphr-studio/Glyphr-Studio-1#270)

@b-g
Copy link
Member Author

@b-g b-g commented Dec 9, 2019

Related font issue from #96:

Not sure how valid this is but using the black openmoji font and vscode, it shows ones we support as a single character and others as multiple characters

However we do have a pirate flag emoji so maybe this is also an issue with the font that we haven't realised?

image

@b-g b-g added the bug label Dec 9, 2019
@bohnacker
Copy link
Member

@bohnacker bohnacker commented Jan 3, 2020

I checked a few things with our color and black fonts and compared it with the fonts "EmojiOne Color" and "Twitter Color Emoji". I chose those because they are not from a vendor of operating systems (Apple, Windows, Google). EmojiOne is an Opentype font while the one from Twitter is Truetype. Ours is Truetype too.

It appears that our fonts are not that bad in general, but there are quite some things to improve.

The following screenshot is made in InDesign on Mac and it seems to handle the Openmoji Color font perfectly. Openmoji Black has some problems. The conversion from SVG to Truetype glyphs ignores stroke-linecap="round" and stroke-linejoin="round" (most obvious on the smiley and the TM-sign). Also, overlapping paths are not converted well (hand, soccer ball, santa claus).
Screenshot InDesign Mac

For the black font I see two possible solutions:

  1. Remove all strokes from all our source emojis and convert it to filled areas.
  2. Find a better conversion algorithm.
    The first solution is not very practical and desirable. I think it's good to have line elements in the source files as much as possible. Otherwise improving the source emojis will be a hassle.

I found another problem with our fonts in InDesign. Ligatures sometimes are split into parts when text gets wrapped. It happend with the hand and the horse but not with the dark santa claus and the flags. I'll try to find out why.
Screenshot InDesign wrapping


Comparision of the behaviour in browsers:

Firefox (Mac and Windows):
Some problems with our color font shows up. Some strokes are not scaled correctly. I'm mot complete sure why. Maybe it's because there are elements on the color layer that have both a fill color and a stroke color. Or it has something to do with transforms that are still in some emojis. Edit: Quite sure it's the first guess... the hand with yellow skin is displayed correctly, all others not because they get a stroke color while building.
Screenshot Firefox Mac

Safari (Mac):
Only EmojiOne works (maybe because it's Opentype):
Screenshot Safari Mac

Edge (Windows):
Handles our color emojis perfectly.
Screenshot Edge Windows

@bohnacker
Copy link
Member

@bohnacker bohnacker commented Jan 5, 2020

Maybe we could use some other libraries like this to convert all strokes in the black SVGs to areas before creating the truetype glyphs:
https://www.npmjs.com/package/js-clipper

It seems to support all we need (stroke-linecap="round" and stroke-linejoin="round"). The fact that it is not developed further on is not a problem in my opinion because it has no dependencies.

Or has anybody good experiences with other libraries for path operations?

@b-g
Copy link
Member Author

@b-g b-g commented Jan 5, 2020

Hi @bohnacker! A belated happy new year + many thanks for the investigation! That sounds a lot more promising than I've anticipated! Yay! A few comments/thoughts:

OpenMoji Black

  • I would vote to introduce a dedicated build process which converts all problematic strokes to shapes ... but not to alter the src svg files
  • Instead of js-clipper I would rather bet on paper.js (in node.js) with the paperjs-offset plugin. (See also the discussion on Parametrized stroke outlining / expanding / offsetting with paper.js)
  • Q: Would we have to convert every stroke or just the ones with stroke-linecap="round" and stroke-linejoin="round" attributes?

OpenMoji Color

  • Q: Is the issue with svgs which have both a fill color and a stroke color a Firefox bug only? If so ... should we simply ignore it?
  • Q: Should we ditch current color font generator or stick with it? I can offer to improve the generator "scfbuild" to support properly generating the two fonts without the current hustle ... but this makes only sense if the scfbuild is worth the invest. (I guess it won't be possible to generate a colorfont in opentype flavor with scfbuild, or?)

@bohnacker
Copy link
Member

@bohnacker bohnacker commented Jan 6, 2020

Hi @b-g, some answers to your questions and suggestions:

I would vote to introduce a dedicated build process which converts all problematic strokes to shapes ... but not to alter the src svg files

Yes, I think so too. That's the only approach that makes sense.

Instead of js-clipper I would rather bet on paper.js (in node.js) with the paperjs-offset plugin. (See also the discussion on Parametrized stroke outlining / expanding / offsetting with paper.js)

I also agree. I had a look at js-clipper and found that it converts all curves to polygons. The result will be glyphs that will look bad when scaling them up a lot. Still we have to check if paperjs is doing everything correctly.

Would we have to convert every stroke or just the ones with stroke-linecap="round" and stroke-linejoin="round" attributes?

Best would be to convert every stroke beforehand because scfbuild (or whereever this is done) has also problems with paths that are crossing itself (see hand and soccer ball in the above examples). In the end (as a glyph) everything will be areas.

Q: Is the issue with svgs which have both a fill color and a stroke color a Firefox bug only? If so ... should we simply ignore it?

As far as I've seen, it's a Firefox only bug. Maybe we could ignore it and hope for a bug fix on the Firefox side.

Q: Should we ditch current color font generator or stick with it? I can offer to improve the generator "scfbuild" to support properly generating the two fonts without the current hustle ... but this makes only sense if the scfbuild is worth the invest. (I guess it won't be possible to generate a colorfont in opentype flavor with scfbuild, or?)

I think we could stick with scfbuild. In general it is doing a good job as far as I've seen. I don't know if it is possible to switch to opentype using scfbuild. I think the truetype glyph creation is done with the fontforge library which should also be capable of generating opentype glyphs. But there might still be a lot more things to change...

@mikemaccana
Copy link

@mikemaccana mikemaccana commented Jan 6, 2020

Note this image is 5 years out of date (it's from 2014):

70079230-9e50d800-1604-11ea-843c-20e66e936bfe

COLR works fine in Chrome now

https://pixelambacht.nl/chromacheck/

@b-g
Copy link
Member Author

@b-g b-g commented Jan 7, 2020

@mikemaccana Thanks for the heads up! :)

@bohnacker Many thanks + agree! Should I go ahead and improve scfbuild with a dedicated --black-only flag so that we can streamline the font build process, or is this too earlier and currently not helpful?

@mikemaccana
Copy link

@mikemaccana mikemaccana commented Jan 7, 2020

PS is there a webpage we can see openmoji rendered in COLR format, as a webfont?

@bohnacker
Copy link
Member

@bohnacker bohnacker commented Jan 8, 2020

@b-g: If you want you can streamline the font building but it's not urgent from my side. I'll start testing paperjs stroke conversion and exploring the other bugs.

@mikemaccana: We haven't build the font in COLR format (and I'm quite sure that we can't do that in the near future). We concentrate on debugging the SVG color font.

@b-g
Copy link
Member Author

@b-g b-g commented Apr 6, 2020

via @carlinmack

The OpenMoji colour font kinda works! You can easily test this by

image

Note that Pinata is rendered in OpenMoji now. Yay!

@dnlutz
But it also shows that the size of the glyphs is way too small! We should tweak the size in https://github.com/hfg-gmuend/openmoji/blob/master/font/scfbuild-color.yml#L8. What size would you suggest?

@dnlutz
Copy link
Contributor

@dnlutz dnlutz commented Apr 24, 2020

I would suggest to scale the OpenMoji by factor 1.3
The Y-position is perfect in relation to the baseline.
color_font_scaling

@carlinmack
Copy link
Contributor

@carlinmack carlinmack commented Apr 24, 2020

Looks good!

We should highlight where the baseline is in openmoji-template.svg

@b-g
Copy link
Member Author

@b-g b-g commented May 5, 2020

Done. Scaled up by 1.3.

Scale 1 / Scale 1
Screenshot 2020-05-05 at 08 20 18

Scale 1.3 / Scale 1
Screenshot 2020-05-05 at 08 35 22

Scale 1.3 / Scale 1.3
Screenshot 2020-05-05 at 08 54 33

cc @dnlutz

@dnlutz
Copy link
Contributor

@dnlutz dnlutz commented May 6, 2020

Tip top / thank you! These emoji sizes now work much better within "normal" text fonts.

@b-g
Copy link
Member Author

@b-g b-g commented May 27, 2020

Thanks @mavit! This is a good pointer! Would you have time to give it spin? ;) Our color font generator seems not the best bet in the long run ... We are keen to have better and more fonts to render OpenMojis on more platforms.

@mavit
Copy link
Contributor

@mavit mavit commented Jul 19, 2020

Status update for nanoemoji. It worked for building COLR TTFs when I first tried it, but by the time I got around to containerising the build it had broken because of googlefonts/picosvg#65.

@b-g
Copy link
Member Author

@b-g b-g commented Jul 20, 2020

Hi @mavit! Many thanks for keeping us posted! Building color fonts via nanoemoji would be mega! Fingers crossed that the bug is soon resolved!

mavit added a commit to mavit/openmoji that referenced this issue Aug 21, 2020
This is done via the container at https://gitlab.com/mavit/nanoemoji-container.

For me, the resulting COLR TTFs work in Firefox and in the Gnome desktop
on Fedora 32 (although they display rather small).

Caveats:
- It may be premature to replace `scfbuild` for SVG builds.  If we decide to go ahead without `scfbuild`, then we’ll want to remove the remaining files related to it.  If we decide to keep `scfbuild`, then we’ll want to revert those parts of this patch.  In either case we’ll want to update the readme to link to the new outputs.
- I’ve tested this with Podman, not Docker.

Relates to hfg-gmuend#93.
@Voultapher
Copy link

@Voultapher Voultapher commented Nov 28, 2020

googlefonts/picosvg#65 has been closed. Just played around with nanoemoji 0.4.1 and openmoji 13.0 and got it to work in chrome and firefox:

linux chromium openmoji-color-cff2_colr_0.otf:

cff2_colr_0-chrome

While nanoemoji can generate colr v1 fonts these don't seem to be supported by browsers yet.

Here are the fonts I generated if you want to avoid having to build them yourselves:

openmoji-nanoemoji.zip

@mavit
Copy link
Contributor

@mavit mavit commented Nov 28, 2020

While nanoemoji can generate colr v1 fonts these don't seem to be supported by browsers yet.

It depends on your OS. They mostly work fine on Linux, but not on MacOS. I don't think we've heard either way about Windows, yet.

@FoundOne
Copy link

@FoundOne FoundOne commented Jan 16, 2021

I'm testing the new font form the zip file above. I really like the simplicity of the design of openmoji and I'm glad that I can use it form applications which just use freetype2, but this rendered font is incredibly small, compared to the other emoji fonts. I can barely see what's depicted in a normal text (12-14pt) on my 1080p display of my laptop. The font looks really great when I set it to be more than 20pt.
Edit: Also I've noticed some emojis are missing in yweb (webkit2gtk).

@mavit
Copy link
Contributor

@mavit mavit commented Jan 17, 2021

I'm testing the new font form the zip file above
...
but this rendered font is incredibly small

See #260.

@MelihDarcanxyz
Copy link

@MelihDarcanxyz MelihDarcanxyz commented Aug 19, 2021

via @carlinmack

The OpenMoji colour font kinda works! You can easily test this by

My Firefox browser shows everything with colors but unfortunately, I can't get colorful emojis on Brave (Chromium spin-off).

@shaurya1709
Copy link

@shaurya1709 shaurya1709 commented Aug 29, 2021

I think a change to the way fonts are compiled would be nice. Nanoemoji would be a good candidate.
There is an older version by @Voultapher that loads the colourful emojis in Brave and is compiled with nanoemoji.
(I don't know python so I can't compile a version for my use)

@carlinmack
Copy link
Contributor

@carlinmack carlinmack commented Aug 29, 2021

see #260 for the saga of using nanoemoji instead :)

@RobertWinslow
Copy link
Contributor

@RobertWinslow RobertWinslow commented Feb 14, 2022

Here's an oddity I found. The line height of the font is too high when viewed in some browsers, namely Chrome or Safari on MacOS.
See this example screenshot:
openmoji-lineheight

This is caused by certain glyphs having elements placed far outside where they should be. The commonality between the broken glyphs is that in their SVG source, they have an element which is rotated around a point other than the origin. When certain browsers display these glyphs, they rotate those pieces around (0,0) instead of the point they are supposed to rotate them around. If the transform attribute is set using a matrix or a rotation about the origin, these browsers display the resulting glyphs fine.

I found that when using FontForge to build a vanilla ttf version of the font, the same glyphs were misrendered in the same way. So I suspect the ultimate source of the error lies in FontForge's SVG importation function.

@RobertWinslow
Copy link
Contributor

@RobertWinslow RobertWinslow commented Mar 8, 2022

I am working on an implementation of the black font using FontForge's import tools.

I'd like some feedback on a couple minor implementation details:

  • All of the regional flags look the same in outline form. They are each just a blank rectangle. Would it would be sensible to exclude regional flag characters from the black ttf?

    • Simply excluding the characters would lead to a fallback glyph being used: likely some other emoji font, and worse case a blank square. This would be at least as informative to the user, and seems like the best option to me.
    • If Regional Indicator Symbol Letters were added to OpenMoji, as discussed in issue 351, then excluding regional flags from the font would result in the flags being rendered as a pair of letter glyphs. This would of course require extra work.
    • A third option, which would require substantially more work, is to include in each flag's source a "line-supplement" group which contains the region's indicator characters. This is similar to what some other color emoji fonts use as a monochrome fallback: screenshot of Microsoft's emoji font displaying flag fallbacks in Google Chrome
  • There are some characters which are present in Unicode in both emoji and non-emoji forms, distinguished by a variation selector FE0F. Should both codepoints be encoded into the font?

    • EG: "👁" has codepoint 1F441, while "👁️" has codepoint 1F441-FE0F. OpenMoji's data files only associate the eye emoji with the former codepoint. In many applications, these two codepoints are treated as the same. However, with my font in its current implementation, some applications will render the latter codepoint in the system's default emoji font because 1F441-FE0F isn't technically present in OpenMoji.
    • Looking at Unicode's emoji test file, it seems there are about 200 such characters.
    • If both codepoints are used, then I'm not sure where to put the list of such characters; I don't see a relevant data field in OpenMoji's data files. The easiest thing to do would just be to include a array of codepoints in my build script, but that's less future proof.

@b-g
Copy link
Member Author

@b-g b-g commented Mar 9, 2022

@RobertWinslow Many thanks for the thoughts! Super! Please gives a day to ponder on the questions and to double check once more the quality of the generated glyphs of OpenMoji-MonoChrome.ttf. Stay tuned.

@dnlutz
Copy link
Contributor

@dnlutz dnlutz commented Mar 10, 2022

Dear @RobertWinslow thank you for your work on the fonts! The overall curve quality looks really good (as good as it can get with our mixed quality source svgs ; )

However, the fonts are really a tough topic and I have discovered a some issues when checking the files in InDesign:

duplicates
Duplicates: Some glyphs appear multiple times in an untraceable order.

fill
Fillings: Some characters have areas completely filled with black.

Do you think these issues could be resolved by code? We try to avoid manual interventions during the font built process – the effort can quickly become unmanageable ; )

At the moment the width of the glyph equals the bounding box of the paths, all emoji should get a uniform with.

I hope I have not discouraged you and I don't know if all this is feasible – but the fonts are definitely a tough job (since the start of OpenMoji in 2018).

Many Greetings

Daniel

@RobertWinslow
Copy link
Contributor

@RobertWinslow RobertWinslow commented Mar 11, 2022

@dnlutz

Duplicates: Some glyphs appear multiple times in an untraceable order.

I suspect this is related to the way I'm handling skin-tone variations. I'm planning to try another way of handling those, though I have no clue whether it will resolve this particular issue. Alternatively, the issue might lay in how TrueType handles ligatures. OpenType handles ligatures more gracefully, so switching from ttf to otf might resolve it.

I had considered leaving skin-tone variants out of the font (it's a monochrome font, after all), but this would cause problems for glyphs with mixed skin tones, as the skin-tone codepoint occurs in the middle of the ligature.

Fillings: Some characters have areas completely filled with black. Do you think these issues could be resolved by code?

Unfortunately, I'm not sure whether they can be. There used to be very many more of these errors, and I was able to resolve most of them by cleaning up the source files. That was the impetus behind this pull request. A lot of the remaining fill errors are bespoke to individual glyphs rather than systemic issues.

For example, I've spent a while looking at the leg of that orangutan: 🦧. The issue there is that the path for the leg loops back around and self-intersects without actually being closed with a z command. This causes FontForge to 'helpfully' interpret it as a solid shape before the expandStroke method has a chance to be called.

image

A very very similar, but not quite identical, problem plagues the handshake 🤝 glyph. And now looking at the gear
2699, its source also has one of these 'pseudo-closed' paths.

The 🦧 glyph in the font could be corrected by:

  • Altering the leg path in some way - Making it properly closed with a z command, or 'splitting' the path by inserting an m 0 0 command in between two other commands.
  • Or by using a different build process. What needs to be done for each glyph is: Load up the black svg, convert strokes to paths, merge all paths into a single element, and then import that element's outline as the outline of a glyph. That's exactly what I'm having FontForge do. It's clearly not doing it exactly as I'd like it to, but I wasn't able to find another easy-to-use tool to automate the process. And even if another tool were used, it might just introduce it's own new set of rendering errors. 'Better the devil you know' so they say.

All that said, some of those filled glyphs aren't actually mis-rendering. I recognize 'keyboard' E1D1 and ◭ 25ED. That's just the 'line-supplement' layer being drawn.

At the moment the width of the glyph equals the bounding box of the paths, all emoji should get a uniform with.

Okay. That's an easy change.

I hope I have not discouraged you and I don't know if all this is feasible – but the fonts are definitely a tough job

Haha, if I were that easily discouraged, I wouldn't have gotten this far along. Thanks for the feedback. Like you say, it's a tough project.

@RobertWinslow
Copy link
Contributor

@RobertWinslow RobertWinslow commented Apr 2, 2022

@dnlutz

Could you take a look at this new version of the font, to see if the duplicate glyph issue has been resolved?
I changed the method I used to handle the skintone variants.

Re: Giving the glyphs a uniform width. If the glyphs are scaled up by a factor of 1.3, should the width also be set 30% bigger than normal? If yes, then the font ends up unusually wide. If no, some glyphs are so wide that either they will overflow their bounding box or they will need to be scaled back down a bit. See the eye (👁️ 1F441) for an example of a very wide vector source. In the script I used to generate the font file, I included multiple parameters to adjust the width of glyphs. I'm just not sure what they should be set to.

@dnlutz
Copy link
Contributor

@dnlutz dnlutz commented Apr 6, 2022

dear @RobertWinslow
there seem to be less duplicates now. but there are still some, for example "People Holding Hands" exists several times. also the fill bugs are still there:
220406 fill
metrics / scaling: it would be ideal when all the glyphs retained the 72 px bounding box from the source svgs (emoji + bounding box should be scaled in the same ratio). i hope this makes sense. many greetings daniel

@RobertWinslow
Copy link
Contributor

@RobertWinslow RobertWinslow commented May 5, 2022

Minor update on the above mentioned duplicate-glyph issue. I thought I had fixed skintone variants showing up as duplicate glyphs. But actually, I had just accidentally removed many of the skintone variants. Further testing has fixed the latter issue, but I suspect the issue of "duplicate" glyphs might not be solvable. (They aren't actually duplicates, just identical.)

@shaurya1709
Copy link

@shaurya1709 shaurya1709 commented May 12, 2022

The only color format I know of which is cross-browser compatible is COLR(v0). Chromium(and Chromium-based browsers) do support COLRv1 since chrome 98.

@dnlutz
Copy link
Contributor

@dnlutz dnlutz commented May 12, 2022

Is it possible for users to change the colors in COLRv1 fonts?

@dnlutz
Copy link
Contributor

@dnlutz dnlutz commented May 12, 2022

Okay … I just spotted this article: https://css-tricks.com/colrv1-and-css-font-palette-web-typography/
Maybe we should go all in with COLRv1 and dump all other font formats?

@mavit
Copy link
Contributor

@mavit mavit commented May 15, 2022

Maybe we should go all in with COLRv1 and dump all other font formats?

That would certainly simplify things if we can, but I thought COLR wasn't supported by Adobe Illustrator? Is that still true, and, if so, is it a showstopper?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests