diff --git a/engine/src/flutter/tools/font-subset/fixtures/1variable.ttf b/engine/src/flutter/tools/font-subset/fixtures/1variable.ttf new file mode 100644 index 00000000000..b5702ad8349 Binary files /dev/null and b/engine/src/flutter/tools/font-subset/fixtures/1variable.ttf differ diff --git a/engine/src/flutter/tools/font-subset/fixtures/2variable.ttf b/engine/src/flutter/tools/font-subset/fixtures/2variable.ttf new file mode 100644 index 00000000000..031beabff15 Binary files /dev/null and b/engine/src/flutter/tools/font-subset/fixtures/2variable.ttf differ diff --git a/engine/src/flutter/tools/font-subset/fixtures/3variable.ttf b/engine/src/flutter/tools/font-subset/fixtures/3variable.ttf new file mode 100644 index 00000000000..d0e3f052530 Binary files /dev/null and b/engine/src/flutter/tools/font-subset/fixtures/3variable.ttf differ diff --git a/engine/src/flutter/tools/font-subset/fixtures/MaterialSymbols-Variable.ttf b/engine/src/flutter/tools/font-subset/fixtures/MaterialSymbols-Variable.ttf new file mode 100644 index 00000000000..a116bf2357d Binary files /dev/null and b/engine/src/flutter/tools/font-subset/fixtures/MaterialSymbols-Variable.ttf differ diff --git a/engine/src/flutter/tools/font-subset/main.cc b/engine/src/flutter/tools/font-subset/main.cc index fc53ef4e61a..fc9765b6161 100644 --- a/engine/src/flutter/tools/font-subset/main.cc +++ b/engine/src/flutter/tools/font-subset/main.cc @@ -59,14 +59,20 @@ struct HarfBuzzSubset { // The prior version of harfbuzz automatically dropped layout tables, // but in the new version they are kept by default. So re-add them to the // drop list to retain the same behaviour. - - hb_set_add(hb_subset_input_set(input, HB_SUBSET_SETS_DROP_TABLE_TAG), - HB_TAG('G', 'S', 'U', 'B')); - hb_set_add(hb_subset_input_set(input, HB_SUBSET_SETS_DROP_TABLE_TAG), - HB_TAG('G', 'P', 'O', 'S')); - hb_set_add(hb_subset_input_set(input, HB_SUBSET_SETS_DROP_TABLE_TAG), - HB_TAG('G', 'D', 'E', 'F')); - + if (!hb_ot_var_has_data(face) || hb_ot_var_get_axis_count(face) == 0) { + // we can only drop GSUB/GPOS/GDEF for non variable fonts, they may be + // needed for variable fonts (guessing we need to keep all of these, but + // in Material Symbols Icon variable fonts if we drop the GSUB table (they + // do not have GPOS/DEF) then the Fill=1,Weight=100 variation is rendered + // incorrect. (and other variations are probably less noticibly + // incorrect)) + hb_set_add(hb_subset_input_set(input, HB_SUBSET_SETS_DROP_TABLE_TAG), + HB_TAG('G', 'S', 'U', 'B')); + hb_set_add(hb_subset_input_set(input, HB_SUBSET_SETS_DROP_TABLE_TAG), + HB_TAG('G', 'P', 'O', 'S')); + hb_set_add(hb_subset_input_set(input, HB_SUBSET_SETS_DROP_TABLE_TAG), + HB_TAG('G', 'D', 'E', 'F')); + } return HarfbuzzWrappers::HbFacePtr(hb_subset_or_fail(face, input)); } }; diff --git a/engine/src/flutter/tools/font-subset/test.py b/engine/src/flutter/tools/font-subset/test.py index fff6f89b865..540b27c0274 100755 --- a/engine/src/flutter/tools/font-subset/test.py +++ b/engine/src/flutter/tools/font-subset/test.py @@ -28,6 +28,9 @@ PLATFORM_2_PATH = { SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) SRC_DIR = os.path.normpath(os.path.join(SCRIPT_DIR, '..', '..', '..')) MATERIAL_TTF = os.path.join(SCRIPT_DIR, 'fixtures', 'MaterialIcons-Regular.ttf') +VARIABLE_MATERIAL_TTF = os.path.join( + SCRIPT_DIR, 'fixtures', 'MaterialSymbols-Variable.ttf' +) IS_WINDOWS = sys.platform.startswith(('cygwin', 'win')) EXE = '.exe' if IS_WINDOWS else '' BAT = '.bat' if IS_WINDOWS else '' @@ -67,6 +70,27 @@ COMPARE_TESTS = ( r'0xE004', r'0xE021', ]), + # repeat tests with variable input font and verified variable output goldens + (True, '1variable.ttf', VARIABLE_MATERIAL_TTF, [r'57347']), + (True, '1variable.ttf', VARIABLE_MATERIAL_TTF, [r'0xE003']), + (True, '1variable.ttf', VARIABLE_MATERIAL_TTF, [r'\uE003']), + (False, '1variable.ttf', VARIABLE_MATERIAL_TTF, + [r'57348']), # False because different codepoint + (True, '2variable.ttf', VARIABLE_MATERIAL_TTF, [r'0xE003', r'0xE004']), + ( + True, '2variable.ttf', VARIABLE_MATERIAL_TTF, [ + r'0xE003', + r'0xE004', + r'57347', + ] + ), # Duplicated codepoint + ( + True, '3variable.ttf', VARIABLE_MATERIAL_TTF, [ + r'0xE003', + r'0xE004', + r'0xE021', + ] + ), ) FAIL_TESTS = [ @@ -95,6 +119,29 @@ FAIL_TESTS = [ ]), # empty input ([FONT_SUBSET, 'output.ttf', MATERIAL_TTF], []), # empty input ([FONT_SUBSET, 'output.ttf', MATERIAL_TTF], ['']), # empty input + # repeat tests with variable input font + ([FONT_SUBSET, 'output.ttf', VARIABLE_MATERIAL_TTF], [ + '0xFFFFFFFF', + ]), # Value too big. + ([FONT_SUBSET, 'output.ttf', VARIABLE_MATERIAL_TTF], [ + '-1', + ]), # invalid value + ([FONT_SUBSET, 'output.ttf', VARIABLE_MATERIAL_TTF], [ + 'foo', + ]), # no valid values + ([FONT_SUBSET, 'output.ttf', VARIABLE_MATERIAL_TTF], [ + '0xE003', + '0x12', + '0xE004', + ]), # codepoint not in font + ([FONT_SUBSET, 'non-existent-dir/output.ttf', VARIABLE_MATERIAL_TTF], [ + '0xE003', + ]), # dir doesn't exist + ([FONT_SUBSET, 'output.ttf', VARIABLE_MATERIAL_TTF], [ + ' ', + ]), # empty input + ([FONT_SUBSET, 'output.ttf', VARIABLE_MATERIAL_TTF], []), # empty input + ([FONT_SUBSET, 'output.ttf', VARIABLE_MATERIAL_TTF], ['']), # empty input ]