232 lines
7.5 KiB
Python
232 lines
7.5 KiB
Python
#!/usr/bin/env vpython3
|
|
#
|
|
# [VPYTHON:BEGIN]
|
|
# wheel: <
|
|
# name: "infra/python/wheels/freetype-py/${vpython_platform}"
|
|
# version: "version:2.2.0.chromium.4"
|
|
# >
|
|
# [VPYTHON:END]
|
|
|
|
# Copyright 2019 The ANGLE Project Authors. All rights reserved.
|
|
# Use of this source code is governed by a BSD-style license that can be
|
|
# found in the LICENSE file.
|
|
#
|
|
# gen_vk_overlay_fonts.py:
|
|
# Code generation for overlay fonts. Should be run if the font file under overlay/ is changed,
|
|
# or the font sizes declared in this file are modified. The font is assumed to be monospace.
|
|
# The output will contain ASCII characters in order from ' ' to '~'. The output will be images
|
|
# with 95 layers, with each smaller font size having half the size of the previous to form a mip
|
|
# chain.
|
|
# NOTE: don't run this script directly. Run scripts/run_code_generation.py.
|
|
|
|
import sys
|
|
|
|
if len(sys.argv) < 2:
|
|
from freetype import *
|
|
|
|
out_file_cpp = 'Overlay_font_autogen.cpp'
|
|
out_file_h = 'Overlay_font_autogen.h'
|
|
font_file = 'overlay/DejaVuSansMono-Bold.ttf'
|
|
|
|
template_out_file_h = u"""// GENERATED FILE - DO NOT EDIT.
|
|
// Generated by {script_name} using {font_file}.
|
|
//
|
|
// Copyright 2022 The ANGLE Project Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
//
|
|
// {out_file_name}:
|
|
// Autogenerated overlay font data.
|
|
|
|
#include "libANGLE/Overlay.h"
|
|
|
|
namespace gl
|
|
{{
|
|
namespace overlay
|
|
{{
|
|
constexpr uint32_t kFontMipCount = {font_count};
|
|
constexpr uint32_t kFontCharacters = {char_count};
|
|
constexpr uint32_t kFontGlyphWidth = {max_font_width};
|
|
constexpr uint32_t kFontGlyphHeight = {max_font_height};
|
|
constexpr uint32_t kFontMipDataSize[kFontMipCount] = {{{font_mip_data_sizes}}};
|
|
constexpr uint32_t kFontMipDataOffset[kFontMipCount] = {{{font_mip_data_offsets}}};
|
|
constexpr uint32_t kFontTotalDataSize = {total_font_data_size};
|
|
{font_mips}
|
|
}} // namespace overlay
|
|
}} // namespace gl
|
|
|
|
"""
|
|
|
|
template_out_file_cpp = u"""// GENERATED FILE - DO NOT EDIT.
|
|
// Generated by {script_name} using images from {font_file}.
|
|
//
|
|
// Copyright 2022 The ANGLE Project Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style license that can be
|
|
// found in the LICENSE file.
|
|
//
|
|
// {out_file_name}:
|
|
// Autogenerated overlay font data.
|
|
|
|
#include "libANGLE/Overlay.h"
|
|
#include "libANGLE/Overlay_font_autogen.h"
|
|
|
|
#include <numeric>
|
|
|
|
namespace gl
|
|
{{
|
|
using namespace overlay;
|
|
|
|
// Save binary size if the font images are never to be used.
|
|
#if ANGLE_ENABLE_OVERLAY
|
|
namespace
|
|
{{
|
|
constexpr uint8_t kFontData[{total_font_data_size}] = {{
|
|
// clang-format off
|
|
{all_font_data}
|
|
// clang-format on
|
|
}};
|
|
}} // anonymous namespace
|
|
|
|
const uint8_t *OverlayState::getFontData() const
|
|
{{
|
|
return kFontData;
|
|
}}
|
|
#else
|
|
const uint8_t *OverlayState::getFontData() const
|
|
{{
|
|
return nullptr;
|
|
}}
|
|
#endif
|
|
}} // namespace gl
|
|
"""
|
|
|
|
|
|
def main():
|
|
if len(sys.argv) == 2 and sys.argv[1] == 'inputs':
|
|
# disabled because of issues on Windows. http://anglebug.com/3892
|
|
# print(font_file)
|
|
return
|
|
if len(sys.argv) == 2 and sys.argv[1] == 'outputs':
|
|
print(','.join([out_file_cpp, out_file_h]))
|
|
return
|
|
|
|
# Font sizes are chosen such that the sizes form a mip chain.
|
|
font_defs = [('large', 29), ('small', 14)]
|
|
chars = ' !"#$%&\'()*+,-./0123456789:;<=>?' + \
|
|
'@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_' + \
|
|
'`abcdefghijklmnopqrstuvwxyz{|}~'
|
|
char_count = len(chars)
|
|
|
|
font_glyph_widths = []
|
|
font_glyph_heights = []
|
|
font_data = ""
|
|
font_mips = []
|
|
current_font_mip = 0
|
|
font_data_sizes = []
|
|
font_data_offsets = []
|
|
total_font_data_size = 0
|
|
|
|
# Load the font file.
|
|
face = Face(font_file)
|
|
assert (face.is_fixed_width)
|
|
|
|
for font_name, font_size in font_defs:
|
|
|
|
# Since the font is fixed width, we can retrieve its size right away.
|
|
face.set_char_size(font_size << 6)
|
|
glyph_width = face.size.max_advance >> 6
|
|
glyph_ascender = face.size.ascender >> 6
|
|
glyph_descender = face.size.descender >> 6
|
|
glyph_height = glyph_ascender - glyph_descender
|
|
font_glyph_widths.append(glyph_width)
|
|
font_glyph_heights.append(glyph_height)
|
|
|
|
# Make sure the fonts form a mipchain
|
|
if current_font_mip > 0:
|
|
assert (glyph_width == font_glyph_widths[current_font_mip - 1] // 2)
|
|
assert (glyph_height == font_glyph_heights[current_font_mip - 1] // 2)
|
|
|
|
font_tag = font_name.capitalize()
|
|
font_mip = str(current_font_mip)
|
|
font_mip_symbol = 'kFontMip' + font_tag
|
|
|
|
font_data += '// ' + font_tag + '\n'
|
|
|
|
# Font pixels are packed in 32-bit values.
|
|
font_data_size = char_count * glyph_width * glyph_height
|
|
font_data_sizes.append(font_data_size)
|
|
font_data_offsets.append(total_font_data_size)
|
|
total_font_data_size += font_data_size
|
|
|
|
for charIndex in range(char_count):
|
|
char = chars[charIndex]
|
|
font_data += "// '" + char + "'\n"
|
|
|
|
# Render the character.
|
|
face.load_char(char)
|
|
bitmap = face.glyph.bitmap
|
|
left = face.glyph.bitmap_left
|
|
top = face.glyph.bitmap_top
|
|
width = bitmap.width
|
|
rows = bitmap.rows
|
|
pitch = bitmap.pitch
|
|
|
|
offset_x = left
|
|
offset_y = glyph_height - (top - glyph_descender)
|
|
|
|
# Some glyphs like '#', '&' etc generate a larger glyph than the "fixed" font width.
|
|
if offset_x + width > glyph_width:
|
|
offset_x = glyph_width - width
|
|
if offset_x < 0:
|
|
width += offset_x
|
|
offset_x = 0
|
|
|
|
assert (offset_x + width <= glyph_width)
|
|
assert (offset_y + rows <= glyph_height)
|
|
|
|
# Write the character bitmap in the font image.
|
|
for y in range(glyph_height):
|
|
for x in range(glyph_width):
|
|
if y < offset_y or y >= offset_y + rows or x < offset_x or x >= offset_x + width:
|
|
font_data += ' 0,'
|
|
else:
|
|
pixel_value = bitmap.buffer[(y - offset_y) * pitch + (x - offset_x)]
|
|
if pixel_value == 0:
|
|
font_data += ' 0,'
|
|
else:
|
|
font_data += '0x{:02X},'.format(pixel_value)
|
|
font_data += '\n'
|
|
|
|
font_mips.append('constexpr uint32_t ' + font_mip_symbol + ' = ' + font_mip + ';')
|
|
current_font_mip += 1
|
|
|
|
with open(out_file_h, 'w') as outfile:
|
|
outfile.write(
|
|
template_out_file_h.format(
|
|
script_name=__file__,
|
|
font_file=font_file,
|
|
out_file_name=out_file_h,
|
|
font_count=len(font_defs),
|
|
char_count=char_count,
|
|
max_font_width=font_glyph_widths[0],
|
|
max_font_height=font_glyph_heights[0],
|
|
font_mip_data_sizes=','.join([str(s) for s in font_data_sizes]),
|
|
font_mip_data_offsets=','.join([str(s) for s in font_data_offsets]),
|
|
total_font_data_size=total_font_data_size,
|
|
font_mips='\n'.join(font_mips)))
|
|
outfile.close()
|
|
|
|
with open(out_file_cpp, 'w') as outfile:
|
|
outfile.write(
|
|
template_out_file_cpp.format(
|
|
script_name=__file__,
|
|
font_file=font_file,
|
|
out_file_name=out_file_cpp,
|
|
total_font_data_size=total_font_data_size,
|
|
all_font_data=font_data))
|
|
outfile.close()
|
|
|
|
|
|
if __name__ == '__main__':
|
|
sys.exit(main())
|