LoginSignup
0
0

ラスター画像フォントを作ってターミナルで表示する実験(その1)

Last updated at Posted at 2023-10-25

端末にミスキーのカスタム絵文字を表示したくてラスター画像フォントを作るのが一番かなと思って実験してみました。

pip install fonttools
wget https://s3.arkjp.net/misskey/806660c1-09cf-4e17-8025-fbc3cf9aed0c.png
from fontTools.ttLib import TTFont
from fontTools.fontBuilder import FontBuilder
from fontTools.ttLib.ttFont import newTable
from fontTools.ttLib.tables._s_b_i_x import table__s_b_i_x
from fontTools.ttLib.tables import sbixGlyph, sbixStrike
from fontTools.pens.t2CharStringPen import T2CharStringPen

fb = FontBuilder(unitsPerEm = 1000, isTTF=False)
fb.setupGlyphOrder([".notdef", ".null", ".CR", ":mi_:"])
fb.setupCharacterMap({0x10FFFF: ":mi_:"})
advanceWidths = {".notdef": 1000, ".null": 0, ".CR": 0, ":mi_:": 1000} #

familyName = "MisskeyCustomEmojiFont"
styleName = "Monospace"
version = "0.1"

nameStrings = dict(
    familyName=dict(en=familyName, ja="ミスキーカスタム絵文字フォント"),
    styleName=dict(en=styleName, ja="Mono"),
    uniqueFontIdentifier="fontBuilder: " + familyName + "." + styleName,
    fullName=familyName + "-" + styleName,
    psName=familyName + "-" + styleName,
    version="Version " + version,
)


# Create an sbix table
sbix = newTable("sibx")
sbix_table = table__s_b_i_x()

glyphs = [".notdef", ".null", ".CR", ":mi_:"]

#ppem = 12
ppem = 256
sbix_strike = sbixStrike.Strike(ppem=ppem, resolution=72)

for glyph_name, image_path in zip(glyphs, ["806660c1-09cf-4e17-8025-fbc3cf9aed0c.png", "806660c1-09cf-4e17-8025-fbc3cf9aed0c.png",
                                           "806660c1-09cf-4e17-8025-fbc3cf9aed0c.png", "806660c1-09cf-4e17-8025-fbc3cf9aed0c.png"]):
    with open(image_path, "rb") as image_file:
        image_data = image_file.read()

        sbix_glyph = sbixGlyph.Glyph(glyphName=glyph_name, graphicType="png ", imageData=image_data) # referenceGlyphName=glyph_name,
        sbix_strike.glyphs[glyph_name] = sbix_glyph

sbix_table.numStrikes += 1
sbix_table.strikes[ppem] = sbix_strike

fb.font["sbix"] = sbix_table


pen = T2CharStringPen(1000, None)
pen.moveTo((0, 0))
pen.lineTo((0, 1000))
pen.lineTo((1000, 1000))
pen.lineTo((1000, 0))
pen.closePath()

charString = pen.getCharString()
charStrings = {
    ".notdef": charString,
    ".null": charString,
    ".CR": charString,
    ":mi_:": charString,}


fb.setupCFF(nameStrings["psName"], {"FullName": nameStrings["psName"]}, charStrings, {})
lsb = {gn: cs.calcBounds(None)[0] for gn, cs in charStrings.items()}
lsb2 = {gn: cs.calcBounds(None)[1] for gn, cs in charStrings.items()}

h_metrics = {}
for gn, advanceWidth in advanceWidths.items():
#    metrics[gn] = (0, 0)
#    h_metrics[gn] = (advanceWidth, lsb[gn])
    h_metrics[gn] = (advanceWidth, 0)
fb.setupHorizontalMetrics(h_metrics)

v_metrics = {}
for gn, advanceWidth in advanceWidths.items():
#    v_metrics[gn] = (1000, lsb2[gn])
    v_metrics[gn] = (1000, 0)
fb.setupVerticalMetrics(v_metrics)

fb.setupHorizontalHeader(ascent=1000, descent=0) # ascent=824, descent=200
fb.setupVerticalHeader(ascent=1000, descent=0) # ascent=824, descent=200
fb.setupNameTable(nameStrings)
fb.setupOS2(sTypoAscender=1000, sTypoDescender=0, usWinAscent=1000, usWinDescent=0)
fb.setupPost()
#fb.setupDummyDSIG()

font_path = "./my_font.otf"
# Save the font to a file
fb.save(font_path)

import os
os.system("cp %s ~/.local/share/fonts/" % font_path)
os.system("fc-cache -f")

端末の再起動が必要かも?

$ python -c "print('\U0010FFFF')"

mi_terminal.png

続き

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0