blob: fee84eb830c3e4d23892ef56a2115a1dad804941 [file] [log] [blame]
#!/usr/bin/env python3
# Copyright 2021 Google, Inc. All Rights Reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
# Google Author(s): Rod Sheeter
import argparse
import contextlib
from fontTools import ttLib
from fontTools.pens.ttGlyphPen import TTGlyphPen
from fontTools.ttLib.tables import sbixStrike
from fontTools.ttLib.tables import sbixGlyph
from nototools import tool_utils
# https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt#glyph-bitmap-data-formats
_CBDT_FORMAT_SMALL_METRIC_PNG = 17
def _del_table(font, tag):
if tag in font:
del font[tag]
def _make_sbix(cblc, cbdt):
# Ref https://gist.github.com/anthrotype/8c08eb372df2fb5da311887b32c2b9ac
sbix = ttLib.newTable("sbix")
# Apple Emoji uses this
resolution = 72
# Noto CBLC will tell you 109 ppem but that makes the sbix assets seem too big
ppem = 128
sbix_strike = sbixStrike.Strike(ppem=ppem, resolution=resolution)
sbix.strikes[sbix_strike.ppem] = sbix_strike
for strike in cbdt.strikeData:
for glyph_name, cbdt_bitmap in strike.items():
cbdt_bitmap.decompile() # populate .metrics, .imageData
assert cbdt_bitmap.getFormat() in {_CBDT_FORMAT_SMALL_METRIC_PNG} # only format for now
sbix_strike.glyphs[glyph_name] = sbixGlyph.Glyph(
glyphName=glyph_name,
graphicType="png",
imageData=cbdt_bitmap.imageData,
# Apple Color Emoji seem to always be 0
# but then our glyphs are too high
originOffsetY=-20,
#originOffsetX=cbdt_bitmap.metrics.BearingX,
#originOffsetY=cbdt_bitmap.metrics.BearingY,
)
return sbix
def _add_empty_glyf_glyphs(font):
pen = TTGlyphPen(None)
empty_glyph = pen.glyph()
font['loca'] = ttLib.newTable("loca")
font['glyf'] = glyf_table = ttLib.newTable("glyf")
glyf_table.glyphOrder = font.getGlyphOrder()
glyf_table.glyphs = {g: empty_glyph for g in glyf_table.glyphOrder}
def main():
parser = argparse.ArgumentParser(
description="Creates an SBIX (Apple style) bitmap font from a CBDT (Google style) bitmap font.")
parser.add_argument(
'-i', '--in_file', help='Input file', default="fonts/NotoColorEmoji.ttf")
parser.add_argument(
'-o', '--out_file', help='Output file', default="fonts/NotoColorEmoji_AppleCompatible.ttf")
args = parser.parse_args()
with contextlib.closing(ttLib.TTFont(args.in_file)) as font:
font["sbix"] = _make_sbix(font["CBLC"], font["CBDT"])
_add_empty_glyf_glyphs(font)
_del_table(font, "CBDT")
_del_table(font, "CBLC")
print(f"Writing {args.out_file}...")
font.save(args.out_file)
if __name__ == '__main__':
main()