Skip to content

Commit

Permalink
重构字体构建逻辑
Browse files Browse the repository at this point in the history
  • Loading branch information
TakWolf committed Jul 7, 2024
1 parent 57f64b6 commit 868d7f1
Show file tree
Hide file tree
Showing 7 changed files with 301 additions and 347 deletions.
15 changes: 5 additions & 10 deletions tools/build.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,34 +7,29 @@
from tools.configs.fallback import FallbackConfig
from tools.configs.font import FontConfig
from tools.services import update_service, dump_service, publish_service, info_service, template_service, image_service
from tools.services.font_service import DesignContext, FontContext
from tools.services.font_service import DesignContext


def main():
update_service.setup_ark_pixel_glyphs()

if path_define.build_dir.exists():
shutil.rmtree(path_define.build_dir)

update_service.setup_ark_pixel_glyphs()

font_configs = {font_size: FontConfig.load(font_size) for font_size in configs.font_sizes}
dump_configs = DumpConfig.load()
fallback_configs = FallbackConfig.load()

for font_size, font_config in font_configs.items():
for dump_config in dump_configs[font_size]:
dump_service.dump_font(dump_config)

for fallback_config in fallback_configs[font_size]:
dump_service.apply_fallback(fallback_config)

design_context = DesignContext.load(font_config, path_define.patch_glyphs_dir)
design_context.format_glyph_files()
design_context.fallback(DesignContext.load(font_config, path_define.ark_pixel_glyphs_dir))
design_context.fallback(DesignContext.load(font_config, path_define.fallback_glyphs_dir))
design_context = DesignContext.load(font_config)
for width_mode in configs.width_modes:
font_context = FontContext(design_context, width_mode)
for font_format in itertools.chain(configs.font_formats, configs.font_collection_formats):
font_context.make_fonts(font_format)
design_context.make_fonts(width_mode, font_format)
publish_service.make_release_zip(font_size, width_mode, font_format)
info_service.make_font_info(design_context, width_mode)
info_service.make_alphabet_txt(design_context, width_mode)
Expand Down
12 changes: 3 additions & 9 deletions tools/build_www.py
Original file line number Diff line number Diff line change
@@ -1,10 +1,9 @@
from tools import configs
from tools.configs import path_define
from tools.configs.dump import DumpConfig
from tools.configs.fallback import FallbackConfig
from tools.configs.font import FontConfig
from tools.services import update_service, dump_service, template_service
from tools.services.font_service import DesignContext, FontContext
from tools.services.font_service import DesignContext


def main():
Expand All @@ -13,21 +12,16 @@ def main():
font_configs = {font_size: FontConfig.load(font_size) for font_size in configs.font_sizes}
dump_configs = DumpConfig.load()
fallback_configs = FallbackConfig.load()

for font_size, font_config in font_configs.items():
for dump_config in dump_configs[font_size]:
dump_service.dump_font(dump_config)

for fallback_config in fallback_configs[font_size]:
dump_service.apply_fallback(fallback_config)

design_context = DesignContext.load(font_config, path_define.patch_glyphs_dir)
design_context.format_glyph_files()
design_context.fallback(DesignContext.load(font_config, path_define.ark_pixel_glyphs_dir))
design_context.fallback(DesignContext.load(font_config, path_define.fallback_glyphs_dir))
design_context = DesignContext.load(font_config)
for width_mode in configs.width_modes:
font_context = FontContext(design_context, width_mode)
font_context.make_fonts('woff2')
design_context.make_fonts(width_mode, 'woff2')
template_service.make_alphabet_html(design_context, width_mode)
template_service.make_demo_html(design_context)
template_service.make_index_html(font_configs)
Expand Down
9 changes: 8 additions & 1 deletion tools/check.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,13 @@
from tools import configs
from tools.configs.font import FontConfig
from tools.services import check_service


def main():
pass
for font_size in configs.font_sizes:
font_config = FontConfig.load(font_size)
check_service.check_font_config(font_config)
check_service.check_glyph_files(font_config)


if __name__ == '__main__':
Expand Down
8 changes: 7 additions & 1 deletion tools/format.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
from tools import configs
from tools.configs.font import FontConfig
from tools.services import format_service


def main():
pass
for font_size in configs.font_sizes:
font_config = FontConfig.load(font_size)
format_service.format_glyph_files(font_config)


if __name__ == '__main__':
Expand Down
73 changes: 73 additions & 0 deletions tools/services/check_service.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import itertools
import unicodedata
from io import BytesIO

import unidata_blocks
from pixel_font_knife import glyph_file_util

from tools import configs
from tools.configs import path_define
from tools.configs.font import FontConfig


def check_font_config(font_config: FontConfig):
for width_mode, layout_param in font_config.layout_params.items():
if width_mode == 'monospaced':
assert layout_param.line_height == font_config.font_size, f"[{font_config.font_size}px] Font config illegal 'monospaced.line_height': {layout_param.line_height}"
else:
assert width_mode == 'proportional', f"[{font_config.font_size}px] Font config illegal 'width_mode': {width_mode}"
assert (layout_param.line_height - font_config.font_size) % 2 == 0, f"[{font_config.font_size}px] Font config illegal 'proportional.line_height': {layout_param.line_height}"


def check_glyph_files(font_config: FontConfig):
for width_mode_dir_name in itertools.chain(['common'], configs.width_modes):
width_mode_dir = path_define.patch_glyphs_dir.joinpath(str(font_config.font_size), width_mode_dir_name)
context = glyph_file_util.load_context(width_mode_dir)
for code_point, flavor_group in context.items():
assert '' in flavor_group, f'[{font_config.font_size}px] Missing default flavor: {width_mode_dir_name} {code_point:04X}'

if code_point == -1:
code_name = 'notdef'
block = None
file_dir = width_mode_dir
east_asian_width = 'F'
else:
code_name = f'{code_point:04X}'
block = unidata_blocks.get_block_by_code_point(code_point)
file_dir = width_mode_dir.joinpath(f'{block.code_start:04X}-{block.code_end:04X} {block.name}')
if block.code_start == 0x4E00:
file_dir = file_dir.joinpath(f'{code_name[0:-2]}-')
east_asian_width = unicodedata.east_asian_width(chr(code_point))

for glyph_file in set(flavor_group.values()):
if len(glyph_file.flavors) > 0:
file_name = f'{code_name} {','.join(sorted(glyph_file.flavors, key=lambda x: configs.language_file_flavors.index(x)))}.png'
else:
file_name = f'{code_name}.png'
file_path = file_dir.joinpath(file_name)
assert glyph_file.file_path == file_path, f"[{font_config.font_size}px] Glyph file path is not standardized: '{glyph_file.file_path}' -> '{file_path}'"

if width_mode_dir_name == 'common' or width_mode_dir_name == 'monospaced':
assert glyph_file.height == font_config.font_size, f"[{font_config.font_size}px] Glyph data error: '{glyph_file.file_path}'"

# H/Halfwidth or Na/Narrow
if east_asian_width == 'H' or east_asian_width == 'Na':
assert glyph_file.width == font_config.font_size / 2, f"[{font_config.font_size}px] Glyph data error: '{glyph_file.file_path}'"
# F/Fullwidth or W/Wide
elif east_asian_width == 'F' or east_asian_width == 'W':
assert glyph_file.width == font_config.font_size, f"[{font_config.font_size}px] Glyph data error: '{glyph_file.file_path}'"
# A/Ambiguous or N/Neutral
else:
assert glyph_file.width == font_config.font_size / 2 or glyph_file.width == font_config.font_size, f"[{font_config.font_size}px] Glyph data error: '{glyph_file.file_path}'"

if block is not None:
if 'CJK Unified Ideographs' in block.name:
assert all(alpha == 0 for alpha in glyph_file.bitmap[0]), f"[{font_config.font_size}px] Glyph data error: '{glyph_file.file_path}'"
assert all(glyph_file.bitmap[i][-1] == 0 for i in range(0, len(glyph_file.bitmap))), f"[{font_config.font_size}px] Glyph data error: '{glyph_file.file_path}'"

if width_mode_dir_name == 'proportional':
assert glyph_file.height == font_config.line_height, f"[{font_config.font_size}px] Glyph data error: '{glyph_file.file_path}'"

glyph_bytes = BytesIO()
glyph_file.bitmap.dump_png(glyph_bytes)
assert glyph_file.file_path.read_bytes() == glyph_bytes.getvalue(), f"[{font_config.font_size}px] Glyph file data is not standardized: '{glyph_file.file_path}'"
Loading

0 comments on commit 868d7f1

Please sign in to comment.