mirror of
https://github.com/ValveSoftware/Proton.git
synced 2025-02-05 10:10:44 +03:00
fonts: Convert simsun.ttc / msyh.ttf / malgun.ttf to TrueType.
CW-Bug-Id: #21346
This commit is contained in:
parent
0ae43f9805
commit
a2eafa8d47
@ -1147,7 +1147,8 @@ $(FONTS_OBJ)/source-han/%.ttf: $$(%.ttf_CIDFONT) $$(%.ttf_FEATURES) $$(%.ttf_SEQ
|
||||
# to run it in a dedicated temporary directory to prevent concurrent instances
|
||||
# to step onto each other's feet
|
||||
(TEMP_DIR=`mktemp -d` && cd $$TEMP_DIR && afdko sfntedit -a CFF=$(abspath $($(notdir $@)).cff) $(abspath $@.tmp) && rm -fr $$TEMP_DIR)
|
||||
mv $@.tmp $@
|
||||
python3 $(FONTS)/scripts/otf2ttf.py -o $@ $@.tmp
|
||||
rm $@.tmp
|
||||
|
||||
$(FONTS_OBJ)/ume-gothic/%.ttf: $$(%.ttf_FONT) $$(%.ttf_NAMETABLE_PATCH)
|
||||
mkdir -p $(FONTS_OBJ)/ume-gothic
|
||||
|
1640
fonts/scripts/otf2ttf.LICENSE
Normal file
1640
fonts/scripts/otf2ttf.LICENSE
Normal file
File diff suppressed because one or more lines are too long
174
fonts/scripts/otf2ttf.py
Normal file
174
fonts/scripts/otf2ttf.py
Normal file
@ -0,0 +1,174 @@
|
||||
# Copied from https://github.com/adobe-type-tools/afdko/blob/develop/python/afdko/otf2ttf.py
|
||||
|
||||
import argparse
|
||||
import glob
|
||||
import logging
|
||||
import os
|
||||
import sys
|
||||
from functools import partial, singledispatch
|
||||
from itertools import chain
|
||||
from multiprocessing import Pool
|
||||
|
||||
from fontTools import configLogger
|
||||
from fontTools.misc.cliTools import makeOutputFileName
|
||||
from fontTools.pens.cu2quPen import Cu2QuPen
|
||||
from fontTools.pens.ttGlyphPen import TTGlyphPen
|
||||
from fontTools.ttLib import TTCollection, TTFont, TTLibError, newTable
|
||||
|
||||
log = logging.getLogger()
|
||||
configLogger(logger=log)
|
||||
|
||||
# default approximation error, measured in UPEM
|
||||
MAX_ERR = 1.0
|
||||
|
||||
# default 'post' table format
|
||||
POST_FORMAT = 2.0
|
||||
|
||||
# assuming the input contours' direction is correctly set (counter-clockwise),
|
||||
# we just flip it to clockwise
|
||||
REVERSE_DIRECTION = True
|
||||
|
||||
|
||||
def glyphs_to_quadratic(
|
||||
glyphs, max_err=MAX_ERR, reverse_direction=REVERSE_DIRECTION):
|
||||
quadGlyphs = {}
|
||||
for gname in glyphs.keys():
|
||||
glyph = glyphs[gname]
|
||||
ttPen = TTGlyphPen(glyphs)
|
||||
cu2quPen = Cu2QuPen(ttPen, max_err,
|
||||
reverse_direction=reverse_direction)
|
||||
glyph.draw(cu2quPen)
|
||||
quadGlyphs[gname] = ttPen.glyph()
|
||||
return quadGlyphs
|
||||
|
||||
|
||||
def update_hmtx(ttFont, glyf):
|
||||
hmtx = ttFont["hmtx"]
|
||||
for glyphName, glyph in glyf.glyphs.items():
|
||||
if hasattr(glyph, 'xMin'):
|
||||
hmtx[glyphName] = (hmtx[glyphName][0], glyph.xMin)
|
||||
|
||||
|
||||
@singledispatch
|
||||
def otf_to_ttf(ttFont, post_format=POST_FORMAT, **kwargs):
|
||||
if ttFont.sfntVersion != "OTTO":
|
||||
raise TTLibError("Not a OpenType font (bad sfntVersion)")
|
||||
assert "CFF " in ttFont
|
||||
|
||||
glyphOrder = ttFont.getGlyphOrder()
|
||||
|
||||
ttFont["loca"] = newTable("loca")
|
||||
ttFont["glyf"] = glyf = newTable("glyf")
|
||||
glyf.glyphOrder = glyphOrder
|
||||
glyf.glyphs = glyphs_to_quadratic(ttFont.getGlyphSet(), **kwargs)
|
||||
del ttFont["CFF "]
|
||||
if "VORG" in ttFont:
|
||||
del ttFont["VORG"]
|
||||
glyf.compile(ttFont)
|
||||
update_hmtx(ttFont, glyf)
|
||||
|
||||
ttFont["maxp"] = maxp = newTable("maxp")
|
||||
maxp.tableVersion = 0x00010000
|
||||
maxp.maxZones = 1
|
||||
maxp.maxTwilightPoints = 0
|
||||
maxp.maxStorage = 0
|
||||
maxp.maxFunctionDefs = 0
|
||||
maxp.maxInstructionDefs = 0
|
||||
maxp.maxStackElements = 0
|
||||
maxp.maxSizeOfInstructions = 0
|
||||
maxp.maxComponentElements = max(
|
||||
len(g.components if hasattr(g, 'components') else [])
|
||||
for g in glyf.glyphs.values())
|
||||
maxp.compile(ttFont)
|
||||
|
||||
post = ttFont["post"]
|
||||
post.formatType = post_format
|
||||
post.extraNames = []
|
||||
post.mapping = {}
|
||||
post.glyphOrder = glyphOrder
|
||||
try:
|
||||
post.compile(ttFont)
|
||||
except OverflowError:
|
||||
post.formatType = 3
|
||||
log.warning("Dropping glyph names, they do not fit in 'post' table.")
|
||||
|
||||
ttFont.sfntVersion = "\000\001\000\000"
|
||||
|
||||
|
||||
@otf_to_ttf.register(TTCollection)
|
||||
def _(fonts, **kwargs):
|
||||
skip = 0
|
||||
for font in fonts:
|
||||
try:
|
||||
otf_to_ttf(font, **kwargs)
|
||||
except TTLibError as warn:
|
||||
skip += 1
|
||||
log.warning(warn)
|
||||
|
||||
if skip == len(fonts):
|
||||
raise TTLibError("a Font Collection that has Not a OpenType font")
|
||||
|
||||
|
||||
def run(path, options):
|
||||
try:
|
||||
font = TTFont(path, fontNumber=options.face_index)
|
||||
extension = '.ttf'
|
||||
except TTLibError:
|
||||
font = TTCollection(path)
|
||||
extension = '.ttc'
|
||||
|
||||
if options.output and not os.path.isdir(options.output):
|
||||
output = options.output
|
||||
else:
|
||||
output = makeOutputFileName(path, outputDir=options.output,
|
||||
extension=extension,
|
||||
overWrite=options.overwrite)
|
||||
|
||||
try:
|
||||
otf_to_ttf(font,
|
||||
post_format=options.post_format,
|
||||
max_err=options.max_error,
|
||||
reverse_direction=options.reverse_direction)
|
||||
except TTLibError as warn:
|
||||
log.warning(f'"{path}" cannot be converted since it is {warn}.')
|
||||
else:
|
||||
font.save(output)
|
||||
|
||||
|
||||
def main(args=None):
|
||||
parser = argparse.ArgumentParser()
|
||||
parser.add_argument("input", nargs='+', metavar="INPUT")
|
||||
parser.add_argument("-o", "--output")
|
||||
parser.add_argument("-e", "--max-error", type=float, default=MAX_ERR)
|
||||
parser.add_argument("--post-format", type=float, default=POST_FORMAT)
|
||||
parser.add_argument(
|
||||
"--keep-direction", dest='reverse_direction', action='store_false')
|
||||
parser.add_argument("--face-index", type=int, default=-1)
|
||||
parser.add_argument("--overwrite", action='store_true')
|
||||
options = parser.parse_args(args)
|
||||
|
||||
if options.output and len(options.input) > 1:
|
||||
if not os.path.isdir(options.output):
|
||||
parser.error("-o/--output option must be a directory when "
|
||||
"processing multiple fonts")
|
||||
|
||||
files = list(chain.from_iterable(map(glob.glob, options.input)))
|
||||
|
||||
# Set the pool capacity to be the minimum of file quantity and CPU count,
|
||||
# at least 1.
|
||||
poolCapacity = max(min(os.cpu_count(), len(files)), 1)
|
||||
# Limit parallel capacity to 60 on win32 to avoid WaitForMultipleObjects
|
||||
# errors. See https://bugs.python.org/issue45077
|
||||
if poolCapacity > 60 and sys.platform == "win32":
|
||||
poolCapacity = 60
|
||||
# Do not use "with" statement, or code coverage will malfunction.
|
||||
pool = Pool(poolCapacity)
|
||||
try:
|
||||
pool.map(partial(run, options=options), files)
|
||||
finally:
|
||||
pool.close()
|
||||
pool.join()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
sys.exit(main())
|
Loading…
x
Reference in New Issue
Block a user