############################################################ # Batak GSUB features for the Medan font. # # For full documentation, see # https://lindenbergsoftware.com/en/notes/constructing-fonts-for-batak/ # # # © 2020 Lindenberg Software LLC. # # Permission is hereby granted, free of charge, to any person obtaining a copy # of this software and associated documentation files (the "Software"), to deal # in the Software without restriction, including without limitation the rights # to use, copy, modify, merge, publish, distribute, sublicense, and/or sell # copies of the Software, and to permit persons to whom the Software is # furnished to do so, subject to the following conditions: # # The above copyright notice and this permission notice shall be included in # all copies or substantial portions of the Software. # # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR # IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, # FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE # AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER # LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, # OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE # SOFTWARE. ############################################################ ############################################################ # Language systems. # ############################################################ languagesystem batk dflt; languagesystem batk BTX; languagesystem batk BTM; ############################################################ # Glyph classes. # ############################################################ @consonant_batak = [ # Variant glyphs are not needed here. a-batak aSima-batak ha-batak haSima-batak haMandai-batak ba-batak baKaro-batak pa-batak paSima-batak na-batak naMandai-batak wa-batak waSima-batak waPak-batak ga-batak gaSima-batak ja-batak da-batak ra-batak raSima-batak ma-batak maSima-batak taSouth-batak taNorth-batak sa-batak saSima-batak saMandai-batak ya-batak yaSima-batak nga-batak la-batak laSima-batak nya-batak ca-batak nda-batak mba-batak ]; @vowelAbove_batak = [ eSignPak-batak eeSign-batak uSignSima-batak oSignKaro-batak ]; @vowelBelow_batak = [ uSign-batak uSign-batak.paMandai uSign-batak.simple ]; @vowelPost_batak = [ eSign-batak iSign-batak iSignKaro-batak oSign-batak ]; @vowelSign_batak = [ @vowelAbove_batak @vowelBelow_batak @vowelPost_batak ]; @consonantSign_batak = [ ngSign-batak hSign-batak ]; @virama_batak = [ pangolat-batak panongonan-batak ]; @vowelOrConsonantMark = [ @vowelAbove_batak @vowelBelow_batak @consonantSign_batak ]; @below_base_batak = [ @vowelBelow_batak ]; @post_base_batak = [ @vowelPost_batak @virama_batak ]; ############################################################ # Validation. # # The Universal Shaping Engine does basic validation, but an additional check is necessary # to enforce the rule that virama signs can’t follow dependent vowels. ############################################################ lookup insert_dotted_circle_batak { lookupflag 0; sub pangolat-batak by dottedCircle pangolat-batak; sub panongonan-batak by dottedCircle panongonan-batak; } insert_dotted_circle_batak; feature ccmp { lookup validate_batak { lookupflag 0; sub @vowelSign_batak @virama_batak' lookup insert_dotted_circle_batak; } validate_batak; } ccmp; ############################################################ # Reordering. # # If a dependent vowel precedes a sequence of consonant and virama, then the # dependent vowel has to move to after the consonant. # Since OpenType doesn’t have a reordering substitution, we do this by copying the # dependent vowel to before the virama, and deleting it from before the consonant. # This can’t be done in the USE’s feature application I phase, as it only operates on individual # clusters, and the USE treats the consonant-virama sequence as a separate cluster. # It therefore has to be done in the feature application II phase. Of the features applied in # that phase, rclt seems the least inappropriate. ############################################################ lookup remove_vowel_batak { lookupflag 0; sub @vowelSign_batak by __.invisible; } remove_vowel_batak; lookup insert_eSign_batak { lookupflag 0; sub pangolat-batak by eSign-batak pangolat-batak; sub panongonan-batak by eSign-batak panongonan-batak; } insert_eSign_batak; lookup insert_eSignPak_batak { lookupflag 0; sub pangolat-batak by eSignPak-batak pangolat-batak; sub panongonan-batak by eSignPak-batak panongonan-batak; } insert_eSignPak_batak; lookup insert_eeSign_batak { lookupflag 0; sub pangolat-batak by eeSign-batak pangolat-batak; sub panongonan-batak by eeSign-batak panongonan-batak; } insert_eeSign_batak; lookup insert_iSign_batak { lookupflag 0; sub pangolat-batak by iSign-batak pangolat-batak; sub panongonan-batak by iSign-batak panongonan-batak; } insert_iSign_batak; lookup insert_iSignKaro_batak { lookupflag 0; sub pangolat-batak by iSignKaro-batak pangolat-batak; sub panongonan-batak by iSignKaro-batak panongonan-batak; } insert_iSignKaro_batak; lookup insert_oSign_batak { lookupflag 0; sub pangolat-batak by oSign-batak pangolat-batak; sub panongonan-batak by oSign-batak panongonan-batak; } insert_oSign_batak; lookup insert_oSignKaro_batak { lookupflag 0; sub pangolat-batak by oSignKaro-batak pangolat-batak; sub panongonan-batak by oSignKaro-batak panongonan-batak; } insert_oSignKaro_batak; lookup insert_uSign_batak { lookupflag 0; sub pangolat-batak by uSign-batak pangolat-batak; sub panongonan-batak by uSign-batak panongonan-batak; } insert_uSign_batak; lookup insert_uSignSima_batak { lookupflag 0; sub pangolat-batak by uSignSima-batak pangolat-batak; sub panongonan-batak by uSignSima-batak panongonan-batak; } insert_uSignSima_batak; feature rclt { lookup reorder_batak { lookupflag UseMarkFilteringSet @vowelOrConsonantMark; sub eSign-batak' lookup remove_vowel_batak @consonant_batak' @virama_batak' lookup insert_eSign_batak; sub eSignPak-batak' lookup remove_vowel_batak @consonant_batak' @virama_batak' lookup insert_eSignPak_batak; sub eeSign-batak' lookup remove_vowel_batak @consonant_batak' @virama_batak' lookup insert_eeSign_batak; sub iSign-batak' lookup remove_vowel_batak @consonant_batak' @virama_batak' lookup insert_iSign_batak; sub iSignKaro-batak' lookup remove_vowel_batak @consonant_batak' @virama_batak' lookup insert_iSignKaro_batak; sub oSign-batak' lookup remove_vowel_batak @consonant_batak' @virama_batak' lookup insert_oSign_batak; sub oSignKaro-batak' lookup remove_vowel_batak @consonant_batak' @virama_batak' lookup insert_oSignKaro_batak; sub uSign-batak' lookup remove_vowel_batak @consonant_batak' @virama_batak' lookup insert_uSign_batak; sub uSignSima-batak' lookup remove_vowel_batak @consonant_batak' @virama_batak' lookup insert_uSignSima_batak; } reorder_batak; } rclt; ############################################################ # Localized forms. # # Karo prefers a symmetric form of ja. # The below-base vowel u below pa is mirrored in Mandailing. ############################################################ feature rclt { script batk; language BTX; lookup karo_ja_batak { lookupflag 0; sub ja-batak by ja-batak.v1; } karo_ja_batak; language BTM; lookup flip_uSign_batak { lookupflag UseMarkFilteringSet @below_base_batak; sub pa-batak uSign-batak' by uSign-batak.paMandai; } flip_uSign_batak; } rclt; ############################################################ # Ligatures. # # The below-base vowel u forms ligatures with a number of consonants, and uses # contextual forms with others. ############################################################ feature liga { lookup liga_uSign_batak { lookupflag UseMarkFilteringSet @below_base_batak; sub a-batak uSign-batak by a_uSign-batak; sub ha-batak uSign-batak by ha_uSign-batak; sub haMandai-batak uSign-batak by haMandai_uSign-batak; sub ba-batak uSign-batak by ba_uSign-batak; sub na-batak uSign-batak by na_uSign-batak; sub naMandai-batak uSign-batak by naMandai_uSign-batak; sub wa-batak uSign-batak by wa_uSign-batak; sub ga-batak uSign-batak by ga_uSign-batak; sub ja-batak uSign-batak by ja_uSign-batak; sub ja-batak.v1 uSign-batak by ja_uSign-batak.v1; sub da-batak uSign-batak by da_uSign-batak; sub ra-batak uSign-batak by ra_uSign-batak; sub ma-batak uSign-batak by ma_uSign-batak; sub maSima-batak uSign-batak by maSima_uSign-batak; sub taSouth-batak uSign-batak by taSouth_uSign-batak; sub taNorth-batak uSign-batak by taNorth_uSign-batak; sub saMandai-batak uSign-batak by saMandai_uSign-batak; sub nga-batak uSign-batak by nga_uSign-batak; sub la-batak uSign-batak by la_uSign-batak; sub nya-batak uSign-batak by nya_uSign-batak; } liga_uSign_batak; lookup simple_uSign_batak { lookupflag UseMarkFilteringSet @below_base_batak; sub [aSima-batak haSima-batak waSima-batak gaSima-batak raSima-batak maSima-batak] uSign-batak' by uSign-batak.simple; } simple_uSign_batak; } liga; ############################################################ # Character variants. # # Several characters have variant glyphs. We enable them separately per character. ############################################################ feature cv01 { sub a-batak from [a-batak.v1]; } cv01; feature cv02 { sub ha-batak from [ha-batak.v1]; } cv02; feature cv03 { lookup flip_uSign_batak; } cv03; feature cv04 { sub na-batak from [na-batak.v1]; sub na_uSign-batak from [na_uSign-batak.v1]; } cv04; feature cv05 { lookup waSima_variant_batak { lookupflag UseMarkFilteringSet @below_base_batak; sub waSima-batak uSign-batak.simple by waSima_uSign-batak.v1; } waSima_variant_batak; } cv05; feature cv06 { sub ja-batak from [ja-batak.v1]; sub ja_uSign-batak from [ja_uSign-batak.v1]; } cv06; feature cv07 { sub ra-batak from [ra-batak.v1]; } cv07; feature cv08 { sub ma-batak from [ma-batak.v1 ma-batak.v2]; sub ma_uSign-batak from [ma_uSign-batak.v1 ma_uSign-batak.v2]; } cv08; feature cv09 { sub sa-batak from [sa-batak.v1 sa-batak.v2 sa-batak.v3 sa-batak.v4]; } cv09; feature cv10 { sub la_uSign-batak by la-batak uSign-batak; } cv10; feature cv11 { sub ca-batak from [ca-batak.v1]; } cv11; feature cv12 { sub nda-batak from [nda-batak.v1 nda-batak.v2 nda-batak.v3]; } cv12; feature cv13 { sub mba-batak from [mba-batak.v1]; } cv13;