#![allow(dead_code)]

use super::map;
use super::{layout_kerx_table, layout_morx_table, layout_trak_table};
use crate::hb::aat::layout_common::{AatApplyContext, HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED};
use crate::hb::{
    buffer::hb_buffer_t, hb_font_t, hb_tag_t, ot_shape_plan::hb_ot_shape_plan_t, GlyphInfo,
};
use crate::Feature;

pub type FeatureType = u8;

pub const FEATURE_TYPE_INVALID: u8 = 0xFF;
pub const FEATURE_TYPE_ALL_TYPOGRAPHIC: u8 = 0;
pub const FEATURE_TYPE_LIGATURES: u8 = 1;
pub const FEATURE_TYPE_CURSIVE_CONNECTION: u8 = 2;
pub const FEATURE_TYPE_LETTER_CASE: u8 = 3;
pub const FEATURE_TYPE_VERTICAL_SUBSTITUTION: u8 = 4;
pub const FEATURE_TYPE_LINGUISTIC_REARRANGEMENT: u8 = 5;
pub const FEATURE_TYPE_NUMBER_SPACING: u8 = 6;
pub const FEATURE_TYPE_SMART_SWASH_TYPE: u8 = 8;
pub const FEATURE_TYPE_DIACRITICS_TYPE: u8 = 9;
pub const FEATURE_TYPE_VERTICAL_POSITION: u8 = 10;
pub const FEATURE_TYPE_FRACTIONS: u8 = 11;
pub const FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE: u8 = 13;
pub const FEATURE_TYPE_TYPOGRAPHIC_EXTRAS: u8 = 14;
pub const FEATURE_TYPE_MATHEMATICAL_EXTRAS: u8 = 15;
pub const FEATURE_TYPE_ORNAMENT_SETS_TYPE: u8 = 16;
pub const FEATURE_TYPE_CHARACTER_ALTERNATIVES: u8 = 17;
pub const FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE: u8 = 18;
pub const FEATURE_TYPE_STYLE_OPTIONS: u8 = 19;
pub const FEATURE_TYPE_CHARACTER_SHAPE: u8 = 20;
pub const FEATURE_TYPE_NUMBER_CASE: u8 = 21;
pub const FEATURE_TYPE_TEXT_SPACING: u8 = 22;
pub const FEATURE_TYPE_TRANSLITERATION: u8 = 23;
pub const FEATURE_TYPE_ANNOTATION_TYPE: u8 = 24;
pub const FEATURE_TYPE_KANA_SPACING_TYPE: u8 = 25;
pub const FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE: u8 = 26;
pub const FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE: u8 = 27;
pub const FEATURE_TYPE_RUBY_KANA: u8 = 28;
pub const FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE: u8 = 29;
pub const FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE: u8 = 30;
pub const FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE: u8 = 31;
pub const FEATURE_TYPE_ITALIC_CJK_ROMAN: u8 = 32;
pub const FEATURE_TYPE_CASE_SENSITIVE_LAYOUT: u8 = 33;
pub const FEATURE_TYPE_ALTERNATE_KANA: u8 = 34;
pub const FEATURE_TYPE_STYLISTIC_ALTERNATIVES: u8 = 35;
pub const FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES: u8 = 36;
pub const FEATURE_TYPE_LOWER_CASE: u8 = 37;
pub const FEATURE_TYPE_UPPER_CASE: u8 = 38;
pub const FEATURE_TYPE_LANGUAGE_TAG_TYPE: u8 = 39;
pub const FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE: u8 = 103;

pub type FeatureSelector = u8;

pub const FEATURE_SELECTOR_INVALID: u8 = 0xFF;

/* Selectors for #FEATURE_TYPE_ALL_TYPOGRAPHIC */
pub const FEATURE_SELECTOR_ALL_TYPE_FEATURES_ON: u8 = 0;
pub const FEATURE_SELECTOR_ALL_TYPE_FEATURES_OFF: u8 = 1;

/* Selectors for #FEATURE_TYPE_LIGATURES */
pub const FEATURE_SELECTOR_REQUIRED_LIGATURES_ON: u8 = 0;
pub const FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF: u8 = 1;
pub const FEATURE_SELECTOR_COMMON_LIGATURES_ON: u8 = 2;
pub const FEATURE_SELECTOR_COMMON_LIGATURES_OFF: u8 = 3;
pub const FEATURE_SELECTOR_RARE_LIGATURES_ON: u8 = 4;
pub const FEATURE_SELECTOR_RARE_LIGATURES_OFF: u8 = 5;
pub const FEATURE_SELECTOR_LOGOS_ON: u8 = 6;
pub const FEATURE_SELECTOR_LOGOS_OFF: u8 = 7;
pub const FEATURE_SELECTOR_REBUS_PICTURES_ON: u8 = 8;
pub const FEATURE_SELECTOR_REBUS_PICTURES_OFF: u8 = 9;
pub const FEATURE_SELECTOR_DIPHTHONG_LIGATURES_ON: u8 = 10;
pub const FEATURE_SELECTOR_DIPHTHONG_LIGATURES_OFF: u8 = 11;
pub const FEATURE_SELECTOR_SQUARED_LIGATURES_ON: u8 = 12;
pub const FEATURE_SELECTOR_SQUARED_LIGATURES_OFF: u8 = 13;
pub const FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_ON: u8 = 14;
pub const FEATURE_SELECTOR_ABBREV_SQUARED_LIGATURES_OFF: u8 = 15;
pub const FEATURE_SELECTOR_SYMBOL_LIGATURES_ON: u8 = 16;
pub const FEATURE_SELECTOR_SYMBOL_LIGATURES_OFF: u8 = 17;
pub const FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON: u8 = 18;
pub const FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF: u8 = 19;
pub const FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON: u8 = 20;
pub const FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF: u8 = 21;

/* Selectors for #FEATURE_TYPE_LIGATURES */
pub const FEATURE_SELECTOR_UNCONNECTED: u8 = 0;
pub const FEATURE_SELECTOR_PARTIALLY_CONNECTED: u8 = 1;
pub const FEATURE_SELECTOR_CURSIVE: u8 = 2;

/* Selectors for #FEATURE_TYPE_LETTER_CASE */
pub const FEATURE_SELECTOR_UPPER_AND_LOWER_CASE: u8 = 0; /* deprecated */
pub const FEATURE_SELECTOR_ALL_CAPS: u8 = 1; /* deprecated */
pub const FEATURE_SELECTOR_ALL_LOWER_CASE: u8 = 2; /* deprecated */
pub const FEATURE_SELECTOR_SMALL_CAPS: u8 = 3; /* deprecated */
pub const FEATURE_SELECTOR_INITIAL_CAPS: u8 = 4; /* deprecated */
pub const FEATURE_SELECTOR_INITIAL_CAPS_AND_SMALL_CAPS: u8 = 5; /* deprecated */

/* Selectors for #FEATURE_TYPE_VERTICAL_SUBSTITUTION */
pub const FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON: u8 = 0;
pub const FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF: u8 = 1;

/* Selectors for #FEATURE_TYPE_LINGUISTIC_REARRANGEMENT */
pub const FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_ON: u8 = 0;
pub const FEATURE_SELECTOR_LINGUISTIC_REARRANGEMENT_OFF: u8 = 1;

/* Selectors for #FEATURE_TYPE_NUMBER_SPACING */
pub const FEATURE_SELECTOR_MONOSPACED_NUMBERS: u8 = 0;
pub const FEATURE_SELECTOR_PROPORTIONAL_NUMBERS: u8 = 1;
pub const FEATURE_SELECTOR_THIRD_WIDTH_NUMBERS: u8 = 2;
pub const FEATURE_SELECTOR_QUARTER_WIDTH_NUMBERS: u8 = 3;

/* Selectors for #FEATURE_TYPE_SMART_SWASH_TYPE */
pub const FEATURE_SELECTOR_WORD_INITIAL_SWASHES_ON: u8 = 0;
pub const FEATURE_SELECTOR_WORD_INITIAL_SWASHES_OFF: u8 = 1;
pub const FEATURE_SELECTOR_WORD_FINAL_SWASHES_ON: u8 = 2;
pub const FEATURE_SELECTOR_WORD_FINAL_SWASHES_OFF: u8 = 3;
pub const FEATURE_SELECTOR_LINE_INITIAL_SWASHES_ON: u8 = 4;
pub const FEATURE_SELECTOR_LINE_INITIAL_SWASHES_OFF: u8 = 5;
pub const FEATURE_SELECTOR_LINE_FINAL_SWASHES_ON: u8 = 6;
pub const FEATURE_SELECTOR_LINE_FINAL_SWASHES_OFF: u8 = 7;
pub const FEATURE_SELECTOR_NON_FINAL_SWASHES_ON: u8 = 8;
pub const FEATURE_SELECTOR_NON_FINAL_SWASHES_OFF: u8 = 9;

/* Selectors for #FEATURE_TYPE_DIACRITICS_TYPE */
pub const FEATURE_SELECTOR_SHOW_DIACRITICS: u8 = 0;
pub const FEATURE_SELECTOR_HIDE_DIACRITICS: u8 = 1;
pub const FEATURE_SELECTOR_DECOMPOSE_DIACRITICS: u8 = 2;

/* Selectors for #FEATURE_TYPE_VERTICAL_POSITION */
pub const FEATURE_SELECTOR_NORMAL_POSITION: u8 = 0;
pub const FEATURE_SELECTOR_SUPERIORS: u8 = 1;
pub const FEATURE_SELECTOR_INFERIORS: u8 = 2;
pub const FEATURE_SELECTOR_ORDINALS: u8 = 3;
pub const FEATURE_SELECTOR_SCIENTIFIC_INFERIORS: u8 = 4;

/* Selectors for #FEATURE_TYPE_FRACTIONS */
pub const FEATURE_SELECTOR_NO_FRACTIONS: u8 = 0;
pub const FEATURE_SELECTOR_VERTICAL_FRACTIONS: u8 = 1;
pub const FEATURE_SELECTOR_DIAGONAL_FRACTIONS: u8 = 2;

/* Selectors for #FEATURE_TYPE_OVERLAPPING_CHARACTERS_TYPE */
pub const FEATURE_SELECTOR_PREVENT_OVERLAP_ON: u8 = 0;
pub const FEATURE_SELECTOR_PREVENT_OVERLAP_OFF: u8 = 1;

/* Selectors for #FEATURE_TYPE_TYPOGRAPHIC_EXTRAS */
pub const FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_ON: u8 = 0;
pub const FEATURE_SELECTOR_HYPHENS_TO_EM_DASH_OFF: u8 = 1;
pub const FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_ON: u8 = 2;
pub const FEATURE_SELECTOR_HYPHEN_TO_EN_DASH_OFF: u8 = 3;
pub const FEATURE_SELECTOR_SLASHED_ZERO_ON: u8 = 4;
pub const FEATURE_SELECTOR_SLASHED_ZERO_OFF: u8 = 5;
pub const FEATURE_SELECTOR_FORM_INTERROBANG_ON: u8 = 6;
pub const FEATURE_SELECTOR_FORM_INTERROBANG_OFF: u8 = 7;
pub const FEATURE_SELECTOR_SMART_QUOTES_ON: u8 = 8;
pub const FEATURE_SELECTOR_SMART_QUOTES_OFF: u8 = 9;
pub const FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_ON: u8 = 10;
pub const FEATURE_SELECTOR_PERIODS_TO_ELLIPSIS_OFF: u8 = 11;

/* Selectors for #FEATURE_TYPE_MATHEMATICAL_EXTRAS */
pub const FEATURE_SELECTOR_HYPHEN_TO_MINUS_ON: u8 = 0;
pub const FEATURE_SELECTOR_HYPHEN_TO_MINUS_OFF: u8 = 1;
pub const FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_ON: u8 = 2;
pub const FEATURE_SELECTOR_ASTERISK_TO_MULTIPLY_OFF: u8 = 3;
pub const FEATURE_SELECTOR_SLASH_TO_DIVIDE_ON: u8 = 4;
pub const FEATURE_SELECTOR_SLASH_TO_DIVIDE_OFF: u8 = 5;
pub const FEATURE_SELECTOR_INEQUALITY_LIGATURES_ON: u8 = 6;
pub const FEATURE_SELECTOR_INEQUALITY_LIGATURES_OFF: u8 = 7;
pub const FEATURE_SELECTOR_EXPONENTS_ON: u8 = 8;
pub const FEATURE_SELECTOR_EXPONENTS_OFF: u8 = 9;
pub const FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON: u8 = 10;
pub const FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF: u8 = 11;

/* Selectors for #FEATURE_TYPE_ORNAMENT_SETS_TYPE */
pub const FEATURE_SELECTOR_NO_ORNAMENTS: u8 = 0;
pub const FEATURE_SELECTOR_DINGBATS: u8 = 1;
pub const FEATURE_SELECTOR_PI_CHARACTERS: u8 = 2;
pub const FEATURE_SELECTOR_FLEURONS: u8 = 3;
pub const FEATURE_SELECTOR_DECORATIVE_BORDERS: u8 = 4;
pub const FEATURE_SELECTOR_INTERNATIONAL_SYMBOLS: u8 = 5;
pub const FEATURE_SELECTOR_MATH_SYMBOLS: u8 = 6;

/* Selectors for #FEATURE_TYPE_CHARACTER_ALTERNATIVES */
pub const FEATURE_SELECTOR_NO_ALTERNATES: u8 = 0;

/* Selectors for #FEATURE_TYPE_DESIGN_COMPLEXITY_TYPE */
pub const FEATURE_SELECTOR_DESIGN_LEVEL1: u8 = 0;
pub const FEATURE_SELECTOR_DESIGN_LEVEL2: u8 = 1;
pub const FEATURE_SELECTOR_DESIGN_LEVEL3: u8 = 2;
pub const FEATURE_SELECTOR_DESIGN_LEVEL4: u8 = 3;
pub const FEATURE_SELECTOR_DESIGN_LEVEL5: u8 = 4;

/* Selectors for #FEATURE_TYPE_STYLE_OPTIONS */
pub const FEATURE_SELECTOR_NO_STYLE_OPTIONS: u8 = 0;
pub const FEATURE_SELECTOR_DISPLAY_TEXT: u8 = 1;
pub const FEATURE_SELECTOR_ENGRAVED_TEXT: u8 = 2;
pub const FEATURE_SELECTOR_ILLUMINATED_CAPS: u8 = 3;
pub const FEATURE_SELECTOR_TITLING_CAPS: u8 = 4;
pub const FEATURE_SELECTOR_TALL_CAPS: u8 = 5;

/* Selectors for #FEATURE_TYPE_CHARACTER_SHAPE */
pub const FEATURE_SELECTOR_TRADITIONAL_CHARACTERS: u8 = 0;
pub const FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS: u8 = 1;
pub const FEATURE_SELECTOR_JIS1978_CHARACTERS: u8 = 2;
pub const FEATURE_SELECTOR_JIS1983_CHARACTERS: u8 = 3;
pub const FEATURE_SELECTOR_JIS1990_CHARACTERS: u8 = 4;
pub const FEATURE_SELECTOR_TRADITIONAL_ALT_ONE: u8 = 5;
pub const FEATURE_SELECTOR_TRADITIONAL_ALT_TWO: u8 = 6;
pub const FEATURE_SELECTOR_TRADITIONAL_ALT_THREE: u8 = 7;
pub const FEATURE_SELECTOR_TRADITIONAL_ALT_FOUR: u8 = 8;
pub const FEATURE_SELECTOR_TRADITIONAL_ALT_FIVE: u8 = 9;
pub const FEATURE_SELECTOR_EXPERT_CHARACTERS: u8 = 10;
pub const FEATURE_SELECTOR_JIS2004_CHARACTERS: u8 = 11;
pub const FEATURE_SELECTOR_HOJO_CHARACTERS: u8 = 12;
pub const FEATURE_SELECTOR_NLCCHARACTERS: u8 = 13;
pub const FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS: u8 = 14;

/* Selectors for #FEATURE_TYPE_NUMBER_CASE */
pub const FEATURE_SELECTOR_LOWER_CASE_NUMBERS: u8 = 0;
pub const FEATURE_SELECTOR_UPPER_CASE_NUMBERS: u8 = 1;

/* Selectors for #FEATURE_TYPE_TEXT_SPACING */
pub const FEATURE_SELECTOR_PROPORTIONAL_TEXT: u8 = 0;
pub const FEATURE_SELECTOR_MONOSPACED_TEXT: u8 = 1;
pub const FEATURE_SELECTOR_HALF_WIDTH_TEXT: u8 = 2;
pub const FEATURE_SELECTOR_THIRD_WIDTH_TEXT: u8 = 3;
pub const FEATURE_SELECTOR_QUARTER_WIDTH_TEXT: u8 = 4;
pub const FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT: u8 = 5;
pub const FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT: u8 = 6;

/* Selectors for #FEATURE_TYPE_TRANSLITERATION */
pub const FEATURE_SELECTOR_NO_TRANSLITERATION: u8 = 0;
pub const FEATURE_SELECTOR_HANJA_TO_HANGUL: u8 = 1;
pub const FEATURE_SELECTOR_HIRAGANA_TO_KATAKANA: u8 = 2;
pub const FEATURE_SELECTOR_KATAKANA_TO_HIRAGANA: u8 = 3;
pub const FEATURE_SELECTOR_KANA_TO_ROMANIZATION: u8 = 4;
pub const FEATURE_SELECTOR_ROMANIZATION_TO_HIRAGANA: u8 = 5;
pub const FEATURE_SELECTOR_ROMANIZATION_TO_KATAKANA: u8 = 6;
pub const FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_ONE: u8 = 7;
pub const FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_TWO: u8 = 8;
pub const FEATURE_SELECTOR_HANJA_TO_HANGUL_ALT_THREE: u8 = 9;

/* Selectors for #FEATURE_TYPE_ANNOTATION_TYPE */
pub const FEATURE_SELECTOR_NO_ANNOTATION: u8 = 0;
pub const FEATURE_SELECTOR_BOX_ANNOTATION: u8 = 1;
pub const FEATURE_SELECTOR_ROUNDED_BOX_ANNOTATION: u8 = 2;
pub const FEATURE_SELECTOR_CIRCLE_ANNOTATION: u8 = 3;
pub const FEATURE_SELECTOR_INVERTED_CIRCLE_ANNOTATION: u8 = 4;
pub const FEATURE_SELECTOR_PARENTHESIS_ANNOTATION: u8 = 5;
pub const FEATURE_SELECTOR_PERIOD_ANNOTATION: u8 = 6;
pub const FEATURE_SELECTOR_ROMAN_NUMERAL_ANNOTATION: u8 = 7;
pub const FEATURE_SELECTOR_DIAMOND_ANNOTATION: u8 = 8;
pub const FEATURE_SELECTOR_INVERTED_BOX_ANNOTATION: u8 = 9;
pub const FEATURE_SELECTOR_INVERTED_ROUNDED_BOX_ANNOTATION: u8 = 10;

/* Selectors for #FEATURE_TYPE_KANA_SPACING_TYPE */
pub const FEATURE_SELECTOR_FULL_WIDTH_KANA: u8 = 0;
pub const FEATURE_SELECTOR_PROPORTIONAL_KANA: u8 = 1;

/* Selectors for #FEATURE_TYPE_IDEOGRAPHIC_SPACING_TYPE */
pub const FEATURE_SELECTOR_FULL_WIDTH_IDEOGRAPHS: u8 = 0;
pub const FEATURE_SELECTOR_PROPORTIONAL_IDEOGRAPHS: u8 = 1;
pub const FEATURE_SELECTOR_HALF_WIDTH_IDEOGRAPHS: u8 = 2;

/* Selectors for #FEATURE_TYPE_UNICODE_DECOMPOSITION_TYPE */
pub const FEATURE_SELECTOR_CANONICAL_COMPOSITION_ON: u8 = 0;
pub const FEATURE_SELECTOR_CANONICAL_COMPOSITION_OFF: u8 = 1;
pub const FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_ON: u8 = 2;
pub const FEATURE_SELECTOR_COMPATIBILITY_COMPOSITION_OFF: u8 = 3;
pub const FEATURE_SELECTOR_TRANSCODING_COMPOSITION_ON: u8 = 4;
pub const FEATURE_SELECTOR_TRANSCODING_COMPOSITION_OFF: u8 = 5;

/* Selectors for #FEATURE_TYPE_RUBY_KANA */
pub const FEATURE_SELECTOR_NO_RUBY_KANA: u8 = 0; /* deprecated - use FEATURE_SELECTOR_RUBY_KANA_OFF instead */
pub const FEATURE_SELECTOR_RUBY_KANA: u8 = 1; /* deprecated - use FEATURE_SELECTOR_RUBY_KANA_ON instead */
pub const FEATURE_SELECTOR_RUBY_KANA_ON: u8 = 2;
pub const FEATURE_SELECTOR_RUBY_KANA_OFF: u8 = 3;

/* Selectors for #FEATURE_TYPE_CJK_SYMBOL_ALTERNATIVES_TYPE */
pub const FEATURE_SELECTOR_NO_CJK_SYMBOL_ALTERNATIVES: u8 = 0;
pub const FEATURE_SELECTOR_CJK_SYMBOL_ALT_ONE: u8 = 1;
pub const FEATURE_SELECTOR_CJK_SYMBOL_ALT_TWO: u8 = 2;
pub const FEATURE_SELECTOR_CJK_SYMBOL_ALT_THREE: u8 = 3;
pub const FEATURE_SELECTOR_CJK_SYMBOL_ALT_FOUR: u8 = 4;
pub const FEATURE_SELECTOR_CJK_SYMBOL_ALT_FIVE: u8 = 5;

/* Selectors for #FEATURE_TYPE_IDEOGRAPHIC_ALTERNATIVES_TYPE */
pub const FEATURE_SELECTOR_NO_IDEOGRAPHIC_ALTERNATIVES: u8 = 0;
pub const FEATURE_SELECTOR_IDEOGRAPHIC_ALT_ONE: u8 = 1;
pub const FEATURE_SELECTOR_IDEOGRAPHIC_ALT_TWO: u8 = 2;
pub const FEATURE_SELECTOR_IDEOGRAPHIC_ALT_THREE: u8 = 3;
pub const FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FOUR: u8 = 4;
pub const FEATURE_SELECTOR_IDEOGRAPHIC_ALT_FIVE: u8 = 5;

/* Selectors for #FEATURE_TYPE_CJK_VERTICAL_ROMAN_PLACEMENT_TYPE */
pub const FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_CENTERED: u8 = 0;
pub const FEATURE_SELECTOR_CJK_VERTICAL_ROMAN_HBASELINE: u8 = 1;

/* Selectors for #FEATURE_TYPE_ITALIC_CJK_ROMAN */
pub const FEATURE_SELECTOR_NO_CJK_ITALIC_ROMAN: u8 = 0; /* deprecated - use FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF instead */
pub const FEATURE_SELECTOR_CJK_ITALIC_ROMAN: u8 = 1; /* deprecated - use FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON instead */
pub const FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON: u8 = 2;
pub const FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF: u8 = 3;

/* Selectors for #FEATURE_TYPE_CASE_SENSITIVE_LAYOUT */
pub const FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON: u8 = 0;
pub const FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF: u8 = 1;
pub const FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON: u8 = 2;
pub const FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF: u8 = 3;

/* Selectors for #FEATURE_TYPE_ALTERNATE_KANA */
pub const FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON: u8 = 0;
pub const FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF: u8 = 1;
pub const FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON: u8 = 2;
pub const FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF: u8 = 3;

/* Selectors for #FEATURE_TYPE_STYLISTIC_ALTERNATIVES */
pub const FEATURE_SELECTOR_NO_STYLISTIC_ALTERNATES: u8 = 0;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON: u8 = 2;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF: u8 = 3;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON: u8 = 4;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF: u8 = 5;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON: u8 = 6;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF: u8 = 7;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON: u8 = 8;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF: u8 = 9;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON: u8 = 10;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF: u8 = 11;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON: u8 = 12;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF: u8 = 13;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON: u8 = 14;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF: u8 = 15;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON: u8 = 16;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF: u8 = 17;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON: u8 = 18;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF: u8 = 19;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON: u8 = 20;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF: u8 = 21;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON: u8 = 22;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF: u8 = 23;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON: u8 = 24;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF: u8 = 25;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON: u8 = 26;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF: u8 = 27;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON: u8 = 28;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF: u8 = 29;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON: u8 = 30;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF: u8 = 31;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON: u8 = 32;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF: u8 = 33;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON: u8 = 34;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF: u8 = 35;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON: u8 = 36;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF: u8 = 37;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON: u8 = 38;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF: u8 = 39;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON: u8 = 40;
pub const FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF: u8 = 41;

/* Selectors for #FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES */
pub const FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON: u8 = 0;
pub const FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF: u8 = 1;
pub const FEATURE_SELECTOR_SWASH_ALTERNATES_ON: u8 = 2;
pub const FEATURE_SELECTOR_SWASH_ALTERNATES_OFF: u8 = 3;
pub const FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON: u8 = 4;
pub const FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF: u8 = 5;

/* Selectors for #FEATURE_TYPE_LOWER_CASE */
pub const FEATURE_SELECTOR_DEFAULT_LOWER_CASE: u8 = 0;
pub const FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS: u8 = 1;
pub const FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS: u8 = 2;

/* Selectors for #FEATURE_TYPE_UPPER_CASE */
pub const FEATURE_SELECTOR_DEFAULT_UPPER_CASE: u8 = 0;
pub const FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS: u8 = 1;
pub const FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS: u8 = 2;

/* Selectors for #FEATURE_TYPE_CJK_ROMAN_SPACING_TYPE */
pub const FEATURE_SELECTOR_HALF_WIDTH_CJK_ROMAN: u8 = 0;
pub const FEATURE_SELECTOR_PROPORTIONAL_CJK_ROMAN: u8 = 1;
pub const FEATURE_SELECTOR_DEFAULT_CJK_ROMAN: u8 = 2;
pub const FEATURE_SELECTOR_FULL_WIDTH_CJK_ROMAN: u8 = 3;

/// HB: hb_aat_feature_mapping_t
///
/// See <https://github.com/harfbuzz/harfbuzz/blob/2c22a65f0cb99544c36580b9703a43b5dc97a9e1/src/hb-aat-layout.hh#L38>
pub struct FeatureMapping {
    pub ot_feature_tag: hb_tag_t,
    pub aat_feature_type: FeatureType,
    pub selector_to_enable: u8,
    pub selector_to_disable: u8,
}

impl FeatureMapping {
    const fn new(
        ot_feature_tag: &[u8; 4],
        aat_feature_type: FeatureType,
        selector_to_enable: u8,
        selector_to_disable: u8,
    ) -> Self {
        FeatureMapping {
            ot_feature_tag: hb_tag_t::new(ot_feature_tag),
            aat_feature_type,
            selector_to_enable,
            selector_to_disable,
        }
    }
}

/// Mapping from OpenType feature tags to AAT feature names and selectors.
///
/// Table data courtesy of Apple.
/// Converted from mnemonics to integers when moving to this file.
#[rustfmt::skip]
pub static feature_mappings: &[FeatureMapping] = &[
    FeatureMapping::new(b"afrc", FEATURE_TYPE_FRACTIONS, FEATURE_SELECTOR_VERTICAL_FRACTIONS, FEATURE_SELECTOR_NO_FRACTIONS),
    FeatureMapping::new(b"c2pc", FEATURE_TYPE_UPPER_CASE, FEATURE_SELECTOR_UPPER_CASE_PETITE_CAPS, FEATURE_SELECTOR_DEFAULT_UPPER_CASE),
    FeatureMapping::new(b"c2sc", FEATURE_TYPE_UPPER_CASE, FEATURE_SELECTOR_UPPER_CASE_SMALL_CAPS, FEATURE_SELECTOR_DEFAULT_UPPER_CASE),
    FeatureMapping::new(b"calt", FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_ON, FEATURE_SELECTOR_CONTEXTUAL_ALTERNATES_OFF),
    FeatureMapping::new(b"case", FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_ON, FEATURE_SELECTOR_CASE_SENSITIVE_LAYOUT_OFF),
    FeatureMapping::new(b"clig", FEATURE_TYPE_LIGATURES, FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_ON, FEATURE_SELECTOR_CONTEXTUAL_LIGATURES_OFF),
    FeatureMapping::new(b"cpsp", FEATURE_TYPE_CASE_SENSITIVE_LAYOUT, FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_ON, FEATURE_SELECTOR_CASE_SENSITIVE_SPACING_OFF),
    FeatureMapping::new(b"cswh", FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_ON, FEATURE_SELECTOR_CONTEXTUAL_SWASH_ALTERNATES_OFF),
    FeatureMapping::new(b"dlig", FEATURE_TYPE_LIGATURES, FEATURE_SELECTOR_RARE_LIGATURES_ON, FEATURE_SELECTOR_RARE_LIGATURES_OFF),
    FeatureMapping::new(b"expt", FEATURE_TYPE_CHARACTER_SHAPE, FEATURE_SELECTOR_EXPERT_CHARACTERS, 16),
    FeatureMapping::new(b"frac", FEATURE_TYPE_FRACTIONS, FEATURE_SELECTOR_DIAGONAL_FRACTIONS, FEATURE_SELECTOR_NO_FRACTIONS),
    FeatureMapping::new(b"fwid", FEATURE_TYPE_TEXT_SPACING, FEATURE_SELECTOR_MONOSPACED_TEXT, 7),
    FeatureMapping::new(b"halt", FEATURE_TYPE_TEXT_SPACING, FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT, 7),
    FeatureMapping::new(b"hist", 40, 0, 1),
    FeatureMapping::new(b"hkna", FEATURE_TYPE_ALTERNATE_KANA, FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_ON, FEATURE_SELECTOR_ALTERNATE_HORIZ_KANA_OFF),
    FeatureMapping::new(b"hlig", FEATURE_TYPE_LIGATURES, FEATURE_SELECTOR_HISTORICAL_LIGATURES_ON, FEATURE_SELECTOR_HISTORICAL_LIGATURES_OFF),
    FeatureMapping::new(b"hngl", FEATURE_TYPE_TRANSLITERATION, FEATURE_SELECTOR_HANJA_TO_HANGUL, FEATURE_SELECTOR_NO_TRANSLITERATION),
    FeatureMapping::new(b"hojo", FEATURE_TYPE_CHARACTER_SHAPE, FEATURE_SELECTOR_HOJO_CHARACTERS, 16),
    FeatureMapping::new(b"hwid", FEATURE_TYPE_TEXT_SPACING, FEATURE_SELECTOR_HALF_WIDTH_TEXT, 7),
    FeatureMapping::new(b"ital", FEATURE_TYPE_ITALIC_CJK_ROMAN, FEATURE_SELECTOR_CJK_ITALIC_ROMAN_ON, FEATURE_SELECTOR_CJK_ITALIC_ROMAN_OFF),
    FeatureMapping::new(b"jp04", FEATURE_TYPE_CHARACTER_SHAPE, FEATURE_SELECTOR_JIS2004_CHARACTERS, 16),
    FeatureMapping::new(b"jp78", FEATURE_TYPE_CHARACTER_SHAPE, FEATURE_SELECTOR_JIS1978_CHARACTERS, 16),
    FeatureMapping::new(b"jp83", FEATURE_TYPE_CHARACTER_SHAPE, FEATURE_SELECTOR_JIS1983_CHARACTERS, 16),
    FeatureMapping::new(b"jp90", FEATURE_TYPE_CHARACTER_SHAPE, FEATURE_SELECTOR_JIS1990_CHARACTERS, 16),
    FeatureMapping::new(b"liga", FEATURE_TYPE_LIGATURES, FEATURE_SELECTOR_COMMON_LIGATURES_ON, FEATURE_SELECTOR_COMMON_LIGATURES_OFF),
    FeatureMapping::new(b"lnum", FEATURE_TYPE_NUMBER_CASE, FEATURE_SELECTOR_UPPER_CASE_NUMBERS, 2),
    FeatureMapping::new(b"mgrk", FEATURE_TYPE_MATHEMATICAL_EXTRAS, FEATURE_SELECTOR_MATHEMATICAL_GREEK_ON, FEATURE_SELECTOR_MATHEMATICAL_GREEK_OFF),
    FeatureMapping::new(b"nlck", FEATURE_TYPE_CHARACTER_SHAPE, FEATURE_SELECTOR_NLCCHARACTERS, 16),
    FeatureMapping::new(b"onum", FEATURE_TYPE_NUMBER_CASE, FEATURE_SELECTOR_LOWER_CASE_NUMBERS, 2),
    FeatureMapping::new(b"ordn", FEATURE_TYPE_VERTICAL_POSITION, FEATURE_SELECTOR_ORDINALS, FEATURE_SELECTOR_NORMAL_POSITION),
    FeatureMapping::new(b"palt", FEATURE_TYPE_TEXT_SPACING, FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, 7),
    FeatureMapping::new(b"pcap", FEATURE_TYPE_LOWER_CASE, FEATURE_SELECTOR_LOWER_CASE_PETITE_CAPS, FEATURE_SELECTOR_DEFAULT_LOWER_CASE),
    FeatureMapping::new(b"pkna", FEATURE_TYPE_TEXT_SPACING, FEATURE_SELECTOR_PROPORTIONAL_TEXT, 7),
    FeatureMapping::new(b"pnum", FEATURE_TYPE_NUMBER_SPACING, FEATURE_SELECTOR_PROPORTIONAL_NUMBERS, 4),
    FeatureMapping::new(b"pwid", FEATURE_TYPE_TEXT_SPACING, FEATURE_SELECTOR_PROPORTIONAL_TEXT, 7),
    FeatureMapping::new(b"qwid", FEATURE_TYPE_TEXT_SPACING, FEATURE_SELECTOR_QUARTER_WIDTH_TEXT, 7),
    FeatureMapping::new(b"rlig", FEATURE_TYPE_LIGATURES, FEATURE_SELECTOR_REQUIRED_LIGATURES_ON, FEATURE_SELECTOR_REQUIRED_LIGATURES_OFF),
    FeatureMapping::new(b"ruby", FEATURE_TYPE_RUBY_KANA, FEATURE_SELECTOR_RUBY_KANA_ON, FEATURE_SELECTOR_RUBY_KANA_OFF),
    FeatureMapping::new(b"sinf", FEATURE_TYPE_VERTICAL_POSITION, FEATURE_SELECTOR_SCIENTIFIC_INFERIORS, FEATURE_SELECTOR_NORMAL_POSITION),
    FeatureMapping::new(b"smcp", FEATURE_TYPE_LOWER_CASE, FEATURE_SELECTOR_LOWER_CASE_SMALL_CAPS, FEATURE_SELECTOR_DEFAULT_LOWER_CASE),
    FeatureMapping::new(b"smpl", FEATURE_TYPE_CHARACTER_SHAPE, FEATURE_SELECTOR_SIMPLIFIED_CHARACTERS, 16),
    FeatureMapping::new(b"ss01", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_ONE_ON, FEATURE_SELECTOR_STYLISTIC_ALT_ONE_OFF),
    FeatureMapping::new(b"ss02", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_TWO_ON, FEATURE_SELECTOR_STYLISTIC_ALT_TWO_OFF),
    FeatureMapping::new(b"ss03", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_THREE_ON, FEATURE_SELECTOR_STYLISTIC_ALT_THREE_OFF),
    FeatureMapping::new(b"ss04", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_ON, FEATURE_SELECTOR_STYLISTIC_ALT_FOUR_OFF),
    FeatureMapping::new(b"ss05", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_ON, FEATURE_SELECTOR_STYLISTIC_ALT_FIVE_OFF),
    FeatureMapping::new(b"ss06", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_SIX_ON, FEATURE_SELECTOR_STYLISTIC_ALT_SIX_OFF),
    FeatureMapping::new(b"ss07", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_ON, FEATURE_SELECTOR_STYLISTIC_ALT_SEVEN_OFF),
    FeatureMapping::new(b"ss08", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_ON, FEATURE_SELECTOR_STYLISTIC_ALT_EIGHT_OFF),
    FeatureMapping::new(b"ss09", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_NINE_ON, FEATURE_SELECTOR_STYLISTIC_ALT_NINE_OFF),
    FeatureMapping::new(b"ss10", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_TEN_ON, FEATURE_SELECTOR_STYLISTIC_ALT_TEN_OFF),
    FeatureMapping::new(b"ss11", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_ON, FEATURE_SELECTOR_STYLISTIC_ALT_ELEVEN_OFF),
    FeatureMapping::new(b"ss12", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_ON, FEATURE_SELECTOR_STYLISTIC_ALT_TWELVE_OFF),
    FeatureMapping::new(b"ss13", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_ON, FEATURE_SELECTOR_STYLISTIC_ALT_THIRTEEN_OFF),
    FeatureMapping::new(b"ss14", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_ON, FEATURE_SELECTOR_STYLISTIC_ALT_FOURTEEN_OFF),
    FeatureMapping::new(b"ss15", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_ON, FEATURE_SELECTOR_STYLISTIC_ALT_FIFTEEN_OFF),
    FeatureMapping::new(b"ss16", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_ON, FEATURE_SELECTOR_STYLISTIC_ALT_SIXTEEN_OFF),
    FeatureMapping::new(b"ss17", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_ON, FEATURE_SELECTOR_STYLISTIC_ALT_SEVENTEEN_OFF),
    FeatureMapping::new(b"ss18", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_ON, FEATURE_SELECTOR_STYLISTIC_ALT_EIGHTEEN_OFF),
    FeatureMapping::new(b"ss19", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_ON, FEATURE_SELECTOR_STYLISTIC_ALT_NINETEEN_OFF),
    FeatureMapping::new(b"ss20", FEATURE_TYPE_STYLISTIC_ALTERNATIVES, FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_ON, FEATURE_SELECTOR_STYLISTIC_ALT_TWENTY_OFF),
    FeatureMapping::new(b"subs", FEATURE_TYPE_VERTICAL_POSITION, FEATURE_SELECTOR_INFERIORS, FEATURE_SELECTOR_NORMAL_POSITION),
    FeatureMapping::new(b"sups", FEATURE_TYPE_VERTICAL_POSITION, FEATURE_SELECTOR_SUPERIORS, FEATURE_SELECTOR_NORMAL_POSITION),
    FeatureMapping::new(b"swsh", FEATURE_TYPE_CONTEXTUAL_ALTERNATIVES, FEATURE_SELECTOR_SWASH_ALTERNATES_ON, FEATURE_SELECTOR_SWASH_ALTERNATES_OFF),
    FeatureMapping::new(b"titl", FEATURE_TYPE_STYLE_OPTIONS, FEATURE_SELECTOR_TITLING_CAPS, FEATURE_SELECTOR_NO_STYLE_OPTIONS),
    FeatureMapping::new(b"tnam", FEATURE_TYPE_CHARACTER_SHAPE, FEATURE_SELECTOR_TRADITIONAL_NAMES_CHARACTERS, 16),
    FeatureMapping::new(b"tnum", FEATURE_TYPE_NUMBER_SPACING, FEATURE_SELECTOR_MONOSPACED_NUMBERS, 4),
    FeatureMapping::new(b"trad", FEATURE_TYPE_CHARACTER_SHAPE, FEATURE_SELECTOR_TRADITIONAL_CHARACTERS, 16),
    FeatureMapping::new(b"twid", FEATURE_TYPE_TEXT_SPACING, FEATURE_SELECTOR_THIRD_WIDTH_TEXT, 7),
    FeatureMapping::new(b"unic", FEATURE_TYPE_LETTER_CASE, 14, 15),
    FeatureMapping::new(b"valt", FEATURE_TYPE_TEXT_SPACING, FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, 7),
    FeatureMapping::new(b"vert", FEATURE_TYPE_VERTICAL_SUBSTITUTION, FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF),
    FeatureMapping::new(b"vhal", FEATURE_TYPE_TEXT_SPACING, FEATURE_SELECTOR_ALT_HALF_WIDTH_TEXT, 7),
    FeatureMapping::new(b"vkna", FEATURE_TYPE_ALTERNATE_KANA, FEATURE_SELECTOR_ALTERNATE_VERT_KANA_ON, FEATURE_SELECTOR_ALTERNATE_VERT_KANA_OFF),
    FeatureMapping::new(b"vpal", FEATURE_TYPE_TEXT_SPACING, FEATURE_SELECTOR_ALT_PROPORTIONAL_TEXT, 7),
    FeatureMapping::new(b"vrt2", FEATURE_TYPE_VERTICAL_SUBSTITUTION, FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_ON, FEATURE_SELECTOR_SUBSTITUTE_VERTICAL_FORMS_OFF),
    FeatureMapping::new(b"vrtr", FEATURE_TYPE_VERTICAL_SUBSTITUTION, 2, 3),
    FeatureMapping::new(b"zero", FEATURE_TYPE_TYPOGRAPHIC_EXTRAS, FEATURE_SELECTOR_SLASHED_ZERO_ON, FEATURE_SELECTOR_SLASHED_ZERO_OFF),
];

pub const DELETED_GLYPH: u32 = 0xFFFF;

/// HB: hb_aat_layout_substitute
///
/// See <https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-aat-layout.cc#L285>
#[doc(alias = "hb_aat_layout_substitute")]
pub fn substitute(
    plan: &hb_ot_shape_plan_t,
    face: &hb_font_t,
    buffer: &mut hb_buffer_t,
    features: &[Feature],
) {
    let mut aat_map = map::AatMap::default();
    if !features.is_empty() {
        let mut builder = map::AatMapBuilder::default();
        for feature in features {
            builder.add_feature(face, feature);
        }
        builder.compile(face, &mut aat_map);
    }

    let mut c = AatApplyContext::new(plan, face, buffer);
    layout_morx_table::apply(
        &mut c,
        if features.is_empty() {
            &plan.aat_map
        } else {
            &aat_map
        },
    );
}

fn is_deleted_glyph(info: &GlyphInfo) -> bool {
    info.is_aat_deleted()
}

/// HB: hb_aat_layout_remove_deleted_glyphs
///
/// See <https://github.com/harfbuzz/harfbuzz/blob/2c22a65f0cb99544c36580b9703a43b5dc97a9e1/src/hb-aat-layout.cc#L337>
#[doc(alias = "hb_aat_layout_remove_deleted_glyphs")]
pub fn remove_deleted_glyphs(buffer: &mut hb_buffer_t) {
    if (buffer.scratch_flags & HB_BUFFER_SCRATCH_FLAG_AAT_HAS_DELETED) != 0 {
        buffer.delete_glyphs_inplace(is_deleted_glyph);
    }
}

/// HB: hb_aat_layout_position
///
/// See <https://github.com/harfbuzz/harfbuzz/blob/2c22a65f0cb99544c36580b9703a43b5dc97a9e1/src/hb-aat-layout.cc#L363>
#[doc(alias = "hb_aat_layout_position")]
pub fn position(plan: &hb_ot_shape_plan_t, face: &hb_font_t, buffer: &mut hb_buffer_t) {
    let mut c = AatApplyContext::new(plan, face, buffer);
    layout_kerx_table::apply(&mut c);
}

/// HB: hb_aat_layout_track
///
/// See <https://github.com/harfbuzz/harfbuzz/blob/2c22a65f0cb99544c36580b9703a43b5dc97a9e1/src/hb-aat-layout.cc#L398>
#[doc(alias = "hb_aat_layout_track")]
pub fn track(plan: &hb_ot_shape_plan_t, face: &hb_font_t, buffer: &mut hb_buffer_t) {
    layout_trak_table::apply(plan, face, buffer);
}
