【问题标题】:Python fonttools: Check if font supports multi codepoint emojiPython fonttools:检查字体是否支持多代码点表情符号
【发布时间】:2019-08-17 18:40:33
【问题描述】:

我正在尝试检查字体是否具有多代码点表情符号的字形,例如“????????‍♂️”、“????‍????”要么 ”????????”在 Python 3.x 中。

对于像“????”这样的单个代码点表情符号要么 ”????”我可以使用 Python fonttols 通过以下代码验证他们的支持:

from fontTools.ttLib import TTFont

def __isEmojiSupportedByFont(emoji: str) -> bool:
    font = TTFont(r"C:\Windows\Fonts\seguiemj.ttf")
    emojiCodepoint = ord(str) # Only works for single codepoint emoji
    for table in font['cmap'].tables:
        for char_code, glyph_name in table.cmap.items():
            if char_code == emojiCodepoint:
                return True
    return False

由于cmp 中只有单个代码点表情符号,我该如何为多代码点表情符号执行此操作?

【问题讨论】:

    标签: python-3.x emoji python-unicode codepoint


    【解决方案1】:

    要检查多代码点表情符号,我必须“查询”GSUB Lookup List

    在 python 中检查字体是否支持 Emoji 的更简单方法是使用 HarfBuzz 或更准确的 harfpy

    我想出的解决办法是:

    from uharfbuzz import Face, Font, Buffer, ot_font_set_funcs, shape
    
    def __isEmojiSupportedByFont(self, emoji: str) -> bool:
        # Load font:
        with open(r"C:\Windows\Fonts\seguiemj.ttf", 'rb') as fontfile:
            self.fontdata = fontfile.read()
    
        # Load font (has to be done for call):
        face = Face(self.fontdata)
        font = Font(face)
        upem = face.upem
        font.scale = (upem, upem)
        ot_font_set_funcs(font)
    
        # Create text buffer:
        buf = Buffer()
        buf.add_str(emoji)
        buf.guess_segment_properties()
    
        # Shape text:
        features = {"kern": True, "liga": True}
        shape(font, buf, features)
    
        # Remove all variant selectors:
        while len(infos) > 0 and infos[-1].codepoint == 3:
            infos = infos[:-1]
    
        # Filter empty:
        if len(infos) <= 0:
            return False
    
        # Remove uncombined, ending with skin tone like "??":
        lastCp = infos[-1].codepoint
        if lastCp == 1076 or lastCp == 1079 or lastCp == 1082 or lastCp == 1085 or lastCp == 1088:
            return False
    
        # If there is a code point 0 or 3 => Emoji not fully supported by font:
        return all(info.codepoint != 0 and info.codepoint != 3 for info in infos)
    

    感谢khaledhosnyjustvanrossum GitHub/fonttols

    【讨论】:

    • 您从哪里获得代码点 1076、1079、1082、1085、1088?它们不对应肤色点 1F3FB-1F3FF
    猜你喜欢
    • 2018-06-05
    • 2014-06-01
    • 2011-07-13
    • 2019-02-21
    • 2016-12-08
    • 2021-06-24
    • 2017-01-04
    • 1970-01-01
    相关资源
    最近更新 更多