From 8e2d3d8e825520fbf066ef44748d11d31b921222 Mon Sep 17 00:00:00 2001 From: Jany Belluz Date: Thu, 19 Oct 2023 16:15:51 +0100 Subject: [PATCH] Fix InDesign default composer kerning when mixing two scripts with a language selected --- .../featureWriters/kernFeatureWriter.py | 41 +++++++++++-------- .../featureWriters/kernFeatureWriter_test.py | 8 ++++ 2 files changed, 33 insertions(+), 16 deletions(-) diff --git a/Lib/ufo2ft/featureWriters/kernFeatureWriter.py b/Lib/ufo2ft/featureWriters/kernFeatureWriter.py index 0ce7c7e8..9b1ff126 100644 --- a/Lib/ufo2ft/featureWriters/kernFeatureWriter.py +++ b/Lib/ufo2ft/featureWriters/kernFeatureWriter.py @@ -573,24 +573,29 @@ def _registerLookups( lookups: dict[str, dict[str, ast.LookupBlock]], feaLanguagesByScript: Mapping[str, list[str]], ) -> None: + # InDesign bugfix: register kerning lookups for all LTR scripts under + # both DFLT and all other LTR scripts so that the basic composer kerns + # everything correctly, in particular: when no language is selected + # (hence the need to put everything in DFLT) and when e.g. Russian + # language is selected but the text contains Latin words (hence the + # need to have all LTR scripts register the lookups of all other + # scritps). This is nonsense for conformant OpenType implementations + # but the default composer of InDesign is terrible. + lookupsLTR: list[ast.LookupBlock] = [] + lookupsRTL: list[ast.LookupBlock] = [] + for script, scriptLookups in sorted(lookups.items()): + if script != COMMON_SCRIPT and script not in DIST_ENABLED_SCRIPTS: + if script_horizontal_direction(script, "LTR") == "LTR": + lookupsLTR.extend(scriptLookups.values()) + elif script_horizontal_direction(script, "LTR") == "RTL": + lookupsRTL.extend(scriptLookups.values()) + # Ensure we have kerning for pure common script runs (e.g. ">1") isKernBlock = feature.name == "kern" dfltLookups: list[ast.LookupBlock] = [] - if isKernBlock and COMMON_SCRIPT in lookups: - dfltLookups.extend(lookups[COMMON_SCRIPT].values()) - - # InDesign bugfix: register kerning lookups for all LTR scripts under DFLT - # so that the basic composer, without a language selected, will still kern. - # Register LTR lookups if any, otherwise RTL lookups. if isKernBlock: - lookupsLTR: list[ast.LookupBlock] = [] - lookupsRTL: list[ast.LookupBlock] = [] - for script, scriptLookups in sorted(lookups.items()): - if script != COMMON_SCRIPT and script not in DIST_ENABLED_SCRIPTS: - if script_horizontal_direction(script, "LTR") == "LTR": - lookupsLTR.extend(scriptLookups.values()) - elif script_horizontal_direction(script, "LTR") == "RTL": - lookupsRTL.extend(scriptLookups.values()) + if COMMON_SCRIPT in lookups: + dfltLookups.extend(lookups[COMMON_SCRIPT].values()) dfltLookups.extend(lookupsLTR or lookupsRTL) if dfltLookups: @@ -620,11 +625,15 @@ def _registerLookups( feature.statements.append(ast.Comment("")) # We have something for this script. First add the default # lookups, then the script-specific ones - lookupsForThisScript = [] + lookupsForThisScript: list[ast.LookupBlock] = [] for dfltScript in DFLT_SCRIPTS: if dfltScript in lookups: lookupsForThisScript.extend(lookups[dfltScript].values()) - lookupsForThisScript.extend(lookups[script].values()) + if isKernBlock and script_horizontal_direction(script, "LTR") == "LTR": + # InDesign: add lookups of all other LTR scripts for an LTR script. + lookupsForThisScript.extend(lookupsLTR) + else: + lookupsForThisScript.extend(lookups[script].values()) # Register the lookups for all languages defined in the feature # file for the script, otherwise kerning is not applied if any # language is set at all. diff --git a/tests/featureWriters/kernFeatureWriter_test.py b/tests/featureWriters/kernFeatureWriter_test.py index 9653c3bb..575ccfc5 100644 --- a/tests/featureWriters/kernFeatureWriter_test.py +++ b/tests/featureWriters/kernFeatureWriter_test.py @@ -1532,9 +1532,11 @@ def test_kern_split_and_drop(FontClass, caplog): script grek; language dflt; lookup kern_Grek; + lookup kern_Latn; script latn; language dflt; + lookup kern_Grek; lookup kern_Latn; } kern; @@ -1896,15 +1898,21 @@ def test_kern_zyyy_zinh(FontClass): language dflt; lookup kern_Default; lookup kern_Grek; + lookup kern_Hani; + lookup kern_Hrkt; script hani; language dflt; lookup kern_Default; + lookup kern_Grek; lookup kern_Hani; + lookup kern_Hrkt; script kana; language dflt; lookup kern_Default; + lookup kern_Grek; + lookup kern_Hani; lookup kern_Hrkt; } kern;