companion icon indicating copy to clipboard operation
companion copied to clipboard

[BUG] Variation Selector not honored in button text

Open arikorn opened this issue 2 months ago • 4 comments

Make sure you're on the latest stable or beta build

  • [x] I have tested this on the latest stable or beta release

Is this a bug in companion itself or a module?

  • [x] I believe this to be a bug in companion and not a specific module

Is there an existing issue for this?

  • [x] I have searched the existing issues

Describe the bug

(This one's a bit esoteric but, hey, the default rendering looks a bit garish to me! and it doesn't honor text and bg color)

The character known as U+1F500 Twisted Rightwards Arrows (🔀) is supposed to turn monochrome when U+FE0E Variation Selector-15 is appended: 🔀︎ (that's a three-byte character).

The latter shows correctly in the Admin WebUI's input field:

Image

but not in the button

Image

Same applies for 🔁 U+1F501

(I imagine this one is either "easy" or "impossible" to fix...)

Steps To Reproduce

You should be able to cut-and-paste the character from the description, above.

Expected Behavior

See description

Environment (please complete the following information)

- OS: Windows 10
- Browser: Chrome (not relevant)
- Companion Version: v4.2.0+8448

Additional context

No response

arikorn avatar Oct 03 '25 04:10 arikorn

My first guesses on this is

  • Perhaps the font we use doesnt include this?
  • The unicode segmenter could be getting the splitting wrong?
  • The canvas library could be doing something wrong

So no concrete ideas, just that it could be anything 😆

Julusian avatar Oct 08 '25 20:10 Julusian

Yeah, I'm pretty sure it's the third one. I did a little testing after posting and

  1. (Missing in font) Possibly. You're using a "strange" emoji font, but even with the official Google Noto font I couldn't get differentiation (esp. in part 3, below)
  2. (Unicode segmenter) When I track it in the debugger, the character going into the fillText call still looks correct and is a 3-byte character, as expected.
  3. (Canvas library) I wrote stub test programs using (a) node-canvas (i.e., the one known as 'canvas'), (b) "@napi-rs" canvas, and (c) skia-canvas. The two that work with loaded fonts don't differentiate between w/ and w/o the variation selector. Node-canvas couldn't render loaded fonts and with its built-in font couldn't render the character with a variation-selector but at least it acknowledged that there was a difference.

In a more flexible environment than Companion one might be able specify the monochrome font (NotoEmoji-Regular), though the glyph there is different again than what the Variation-Selector gives (it's a filled square with the glyph cut out of it, i.e. transparent).

I'm willing to classify this as "impossible" for now. In the end I just made PNG files which, while 1,000x larger than the unicode, does the job...

arikorn avatar Oct 08 '25 22:10 arikorn

(Deleted previous comment -- it's a bit less clear than I had hoped... will rethink and repost as appropriate)

arikorn avatar Oct 09 '25 06:10 arikorn

OK, I've confirmed that option 1: the monochrome variation is not in the font. (Method: define classes in CSS with font-family set to a custom-loaded font and with fallback to Adobe "NotDef" font, which maps everything else to a crossed-out box).

However, it's a bit more complicated: On the good news side: Chrome (on Windows) can differentiate between the emoji-character with and without the variation-selector, and defaults to Microsoft's Segoe UI Symbol for the monochrome version (i.e. with selector).

Unfortunately option 3 (the canvas library doing something wrong) may also be true: if I add the Segoe UI Symbol font to the end of Companion's DEFAULT_FONTS, it is ignored, i.e., the color-emoji is shown regardless. (If the Segoe comes first, it's glyph is correctly shown, but since the font itself use the same glyph w/ and w/o selector, it's not a solution, see screenshot, below.) So while I can't say if it would work correctly if we found a font that has both color and monochrome glyphs in it, it does seem that the napi-rs/canvas (and skia-canvas) either ignore the selector or don't look for a fallback font in the case of variation selectors. FWIW, node-canvas, aka canvas, sort-of does it right: if "Segoe UI Symbol" is anywhere in the font list, node-canvas will draw the monochrome glyph when the variation-selector is used, and a different glyph without the variation-selector. Technically this behavior is incorrect when the Segoe font is first in the list, but at least it works.

Here's a screenshot for the font part, rendered in Chrome on Windows 10 (notice, also, the transparency in the "Noto Emoji" font; also, fill color was set to gray so you can see which ones respond to the fill color):

Image

arikorn avatar Oct 10 '25 05:10 arikorn