mirror of
https://github.com/flutter/flutter.git
synced 2026-02-20 02:29:02 +08:00
Allow optional codepoints to be expressed to the font subset generator. (flutter/engine#44864)
This is the engine side change to fix https://github.com/flutter/flutter/issues/132711. There will be a subsequent framework change to express the space character as an "optional" character.
This commit is contained in:
parent
a1a247f7a2
commit
ab84ec613c
@ -13,15 +13,22 @@
|
||||
|
||||
#include "hb_wrappers.h"
|
||||
|
||||
hb_codepoint_t ParseCodepoint(const std::string& arg) {
|
||||
hb_codepoint_t ParseCodepoint(std::string_view arg, bool& optional) {
|
||||
constexpr std::string_view kOptionalPrefix = "optional:";
|
||||
if (arg.substr(0, kOptionalPrefix.length()) == kOptionalPrefix) {
|
||||
optional = true;
|
||||
arg = arg.substr(kOptionalPrefix.length());
|
||||
} else {
|
||||
optional = false;
|
||||
}
|
||||
uint64_t value = 0;
|
||||
// Check for \u123, u123, otherwise let strtoul work it out.
|
||||
if (arg[0] == 'u') {
|
||||
value = strtoul(arg.c_str() + 1, nullptr, 16);
|
||||
value = strtoul(arg.data() + 1, nullptr, 16);
|
||||
} else if (arg[0] == '\\' && arg[1] == 'u') {
|
||||
value = strtoul(arg.c_str() + 2, nullptr, 16);
|
||||
value = strtoul(arg.data() + 2, nullptr, 16);
|
||||
} else {
|
||||
value = strtoul(arg.c_str(), nullptr, 0);
|
||||
value = strtoul(arg.data(), nullptr, 0);
|
||||
}
|
||||
if (value == 0 || value > std::numeric_limits<hb_codepoint_t>::max()) {
|
||||
std::cerr << "The value '" << arg << "' (" << value
|
||||
@ -43,6 +50,10 @@ void Usage() {
|
||||
"and must be input as decimal numbers (123), hexadecimal "
|
||||
"numbers (0x7B), or unicode hexadecimal characters (\\u7B)."
|
||||
<< std::endl;
|
||||
std::cout << "Codepoints can be prefixed by the string \"optional:\" to "
|
||||
"specify that the codepoint can be omitted if it isn't found "
|
||||
"in the input font file."
|
||||
<< std::endl;
|
||||
std::cout << "Input terminates with a newline." << std::endl;
|
||||
std::cout
|
||||
<< "This program will de-duplicate codepoints if the same codepoint is "
|
||||
@ -113,13 +124,21 @@ int main(int argc, char** argv) {
|
||||
hb_face_collect_unicodes(font_face.get(), actual_codepoints.get());
|
||||
std::string raw_codepoint;
|
||||
while (std::cin >> raw_codepoint) {
|
||||
auto codepoint = ParseCodepoint(raw_codepoint);
|
||||
bool optional = false;
|
||||
auto codepoint =
|
||||
ParseCodepoint(std::string_view(raw_codepoint), optional);
|
||||
if (!codepoint) {
|
||||
std::cerr << "Invalid codepoint for " << raw_codepoint << "; exiting."
|
||||
<< std::endl;
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (!hb_set_has(actual_codepoints.get(), codepoint)) {
|
||||
if (optional) {
|
||||
// Code point is optional, so omit it.
|
||||
continue;
|
||||
}
|
||||
|
||||
std::cerr << "Codepoint " << raw_codepoint
|
||||
<< " not found in font, aborting." << std::endl;
|
||||
return -1;
|
||||
|
||||
@ -60,6 +60,13 @@ COMPARE_TESTS = (
|
||||
(False, '1.ttf', MATERIAL_TTF, [r'57348'
|
||||
]), # False because different codepoint
|
||||
(True, '2.ttf', MATERIAL_TTF, [r'0xE003', r'0xE004']),
|
||||
(True, '2.ttf', MATERIAL_TTF, [r'0xE003', r'optional:0xE004'
|
||||
]), # Optional codepoint that is found
|
||||
(True, '2.ttf', MATERIAL_TTF, [
|
||||
r'0xE003',
|
||||
r'0xE004',
|
||||
r'optional:0x12',
|
||||
]), # Optional codepoint that is not found
|
||||
(True, '2.ttf', MATERIAL_TTF, [
|
||||
r'0xE003',
|
||||
r'0xE004',
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user