golang/freetype

append emoji at the text is not showing emoji on the image output.

emildd opened this issue Β· 18 comments

how to configuration about emoticon support?

I'm sorry, but I don't understand the question. Can you re-phrase it?

First of all, you will need a font file that contains Emoji images. Even so, I don't think that golang/freetype currently supports such emoji fonts, and probably won't do so any time soon, as it would be a lot of work and I don't have a lot of spare time at the moment.

One reason that it would be a lot of work is that there doesn't appear to be a clear standard for colored or partially transparent glyphs. https://en.wikipedia.org/wiki/OpenType#Color lists three competing approaches, built on PNG, SVG or neither.

@nigeltao Any pointers on where to look? See the referenced gg issue. We get this error when trying to use an emoji font, such as Apple Color Emoji.ttf:

panic: freetype: unsupported TrueType feature: cmap encoding

That font has a cmap encoding of 4, which isn't one of the supported values in golang/freetype.

I don't know much about TTF. Is this just a matter of parsing a couple more cmap "subtables"?

Are you trying to use that Emoji font specifically for its emoji images, or are you just trying to set basic "hello, world" text in a given font that happens to also have (unused) emoji?

If the latter, it's probably just a matter of parsing one more cmap encoding. As per https://www.microsoft.com/typography/otspec/name.htm, Unicode/4 is pretty much the same as Unicode/3. Provided you don't need a new cmap format (not cmap encoding), i.e. you don't need something other than format-4 or format-12, that's probably all you need to do.

I don't have that particular font on my linux computer, but I suspect that the golang.org/x/image/font/sfnt package (a work in progress) will accept "Apple Color Emoji.ttf". Either way, it's probably useful information as to whether the golang.org/x/image/font/sfnt package can handle it, even if github.com/golang/freetype can't.

If the former (which is what the OP bug report is about), then that's a lot more work. Supporting emoji fonts will take much more work than simply tweaking the accepted encodings. For one thing, the API would need to change to work with multi-color glyphs. Even so, as previously mentioned, there are three competing approaches, each needing significant new code:

For Microsoft's take (COLR, CPAL etc tables), look at "Tables Related to Color Fonts" at https://www.microsoft.com/typography/OTSPEC/otff.htm#otttables for the spec.

For Google's take (PNG images), we do already have a image/png decoder, but you'd still need to hook it all up and adding extra dependencies is sad.

For Mozilla/Adobe's take (SVG images), we'd need an SVG decoder, which we don't have and would be a massive amount of work, and even more dependencies.

@nigeltao it was for the images (not necessarily the colors).

Well, emojis would be weird without color.

I do it all the time! Here at the top of the screen, for example.

I've just pushed a commit that I suspect will let you render black+white (but not color) emoji. I don't know what fonts you're using, so I haven't confirmed that, though.

I'm also leaving this issue open, as I think that the OP refers to color emoji.

Note that black-and-whiteness is a property of each font file, not the Go code. It's not like we can take the black-and-white forms of "Apple Color Emoji.ttc", since that font file doesn't supply black-and-white forms, only color forms.

@nigeltao
I am trying to use that Emoji font specifically for its emoji images. The font I am using is NotoColorEmoji.ttf.

I want to confirm that is golang/freetype can handle this case?

golang/freetype can not handle this case, for the reasons I said above.

hpoul commented

@nigeltao i was wondering if anything changed in the last 3 years regarding colored emojis? :-) I was able to seamlessly draw back/white emojis, but color fonts (i tried the mentioned NotoColorEmoji) didn't draw anything - It seems there is a sfnt implementation which mentions something about a color glyth, but I couldn't quite find a useful example to draw strings πŸ€”οΈ

Nothing's changed in the last 3 years. My previous comment stands:

If the former (which is what the OP bug report is about), then that's a lot more work. Supporting emoji fonts will take much more work than simply tweaking the accepted encodings. For one thing, the API would need to change to work with multi-color glyphs. Even so, as previously mentioned, there are three competing approaches, each needing significant new code:

As for golang.org/x/image/font/sfnt, it mentions color glyphs only to return an error to say it doesn't implement color glyphs:

// ErrColoredGlyph indicates that the requested glyph is not a monochrome
// vector glyph, such as a colored (bitmap or vector) emoji glyph.
ErrColoredGlyph = errors.New("sfnt: colored glyph")

@nigeltao @hpoul how to draw back/white emojis, I couldn't quite find a useful example , can you show me a useful example? thank you !

hpoul commented

@lishaoh I'm pretty clueless, but the best i could come up with was using github.com/AndreKR/multiface and just merging the text font rubik with the noto emoji font (non color version) ..

createFont(fontPath string, emojiFontPath string, size float64)
func createFont(fontPath string, emojiFontPath string, size float64) (font.Face, error) {
	face := new(multiface.Face)
	opts := &truetype.Options{Size: size, DPI: 96}
	font1, err := readFont(fontPath)
	if err != nil {
		return nil, err
	}
	fc := truetype.NewFace(font1, opts)
	face.AddTruetypeFace(fc, font1)

	font2, err := readFont(emojiFontPath)
	if err != nil {
		return nil, err
	}
	fc = truetype.NewFace(font2, opts)
	face.AddTruetypeFace(fc, font2)

	return face, nil
}

And then i used github.com/fogleman/gg to draw the string.. worked for me..

@hpoul thank you very much ! I try again

@hpoul hi ! I want to know did you define the readFont() function yourself?