static void CollectScriptTable(ScriptList scList, Dictionary <string, ScriptLang> output) { if (scList == null) { return; } // foreach (var kv in scList) { ScriptTable scTable = kv.Value; //default and others { ScriptTable.LangSysTable langSys = scTable.defaultLang; ScriptLang sclang = new ScriptLang(scTable.ScriptTagName, langSys.LangSysTagIdenString); string key = sclang.ToString(); if (!output.ContainsKey(key)) { output.Add(key, sclang); } } // if (scTable.langSysTables != null && scTable.langSysTables.Length > 0) { foreach (ScriptTable.LangSysTable langSys in scTable.langSysTables) { var pair = new ScriptLang(scTable.ScriptTagName, langSys.LangSysTagIdenString); string key = pair.ToString(); if (!output.ContainsKey(key)) { output.Add(key, pair); } } } } }
private void RebuildTables() { _lookupTables.Clear(); // check if this lang has GSUB gsubTable = _typeface.GSUBTable; ScriptTable scriptTable = gsubTable.ScriptList[_language]; if (scriptTable == null) { return; } ScriptTable.LangSysTable selectedLang = null; if (scriptTable.langSysTables != null && scriptTable.langSysTables.Length > 0) { // TODO: review here selectedLang = scriptTable.langSysTables[0]; } else { selectedLang = scriptTable.defaultLang; } if (selectedLang.HasRequireFeature) { // TODO: review here } if (selectedLang.featureIndexList == null) { return; } // Enumerate features we want and add the corresponding lookup tables foreach (int featureIndex in selectedLang.featureIndexList) { FeatureList.FeatureTable feature = gsubTable.FeatureList.featureTables[featureIndex]; bool featureIsNeeded = false; switch (feature.TagName) { case "ccmp": // glyph composition/decomposition // this version we implement ccmp featureIsNeeded = EnableComposition; break; case "liga": // Standard Ligatures --enable by default featureIsNeeded = EnableLigation; break; } if (featureIsNeeded) { foreach (ushort lookupIndex in feature.LookupListIndices) { _lookupTables.Add(gsubTable.LookupList[lookupIndex]); } } } }
public GlyphSetPosition(Typeface typeface, string lang) { this.Lang = lang; this.typeface = typeface; //check if this lang has this.gposTable = typeface.GPOSTable; if (gposTable == null) { return; } ScriptTable scriptTable = gposTable.ScriptList[lang]; //--------- if (scriptTable == null) { return; } // early exit if no lookup tables //--------- ScriptTable.LangSysTable defaultLang = scriptTable.defaultLang; if (defaultLang == null) { return; } // early exit if no default language if (defaultLang.HasRequireFeature) { } //other feature if (defaultLang.featureIndexList != null) { //get features var features = new List <FeatureList.FeatureTable>(); for (int i = 0; i < defaultLang.featureIndexList.Length; ++i) { FeatureList.FeatureTable feature = gposTable.FeatureList.featureTables[defaultLang.featureIndexList[i]]; switch (feature.TagName) { case "mark": //mark=> mark to base case "mkmk": //mkmk => mark to mask //current version we implement this 2 features features.Add(feature); break; case "kern": //test with Candara font features.Add(feature); //If palt is activated, there is no requirement that kern must also be activated. //If kern is activated, palt must also be activated if it exists. //https://www.microsoft.com/typography/OTSpec/features_pt.htm#palt break; case "palt": break; default: break; } } //----------------------- lookupTables = new List <GPOS.LookupTable>(); int j = features.Count; for (int i = 0; i < j; ++i) { FeatureList.FeatureTable feature = features[i]; foreach (ushort lookupIndex in feature.LookupListIndices) { lookupTables.Add(gposTable.LookupList[lookupIndex]); } } } }
public GlyphSetPosition(Typeface typeface, string lang) { this.Lang = lang; this.typeface = typeface; //check if this lang has this.gposTable = typeface.GPOSTable; if (gposTable == null) { return; } ScriptTable scriptTable = gposTable.ScriptList.FindScriptTable(lang); //--------- if (scriptTable == null) { return; } //early exit if no lookup tables //--------- ScriptTable.LangSysTable defaultLang = scriptTable.defaultLang; if (defaultLang.HasRequireFeature) { } //other feature if (defaultLang.featureIndexList != null) { //get features var features = new List <FeatureList.FeatureTable>(); for (int i = 0; i < defaultLang.featureIndexList.Length; ++i) { FeatureList.FeatureTable feature = gposTable.FeatureList.featureTables[defaultLang.featureIndexList[i]]; switch (feature.TagName) { case "mark": //mark=> mark to base case "mkmk": //mkmk => mark to mask //current version we implement this 2 features features.Add(feature); break; default: { } break; } } //----------------------- lookupTables = new List <GPOS.LookupTable>(); int j = features.Count; for (int i = 0; i < j; ++i) { FeatureList.FeatureTable feature = features[i]; ushort[] lookupListIndices = feature.LookupListIndice; foreach (ushort lookupIndex in lookupListIndices) { lookupTables.Add(gposTable.GetLookupTable(lookupIndex)); } } } }
public GlyphSubStitution(Typeface typeface, string lang) { this.EnableLigation = true;//enable by default this.Lang = lang; this.typeface = typeface; //check if this lang has gsubTable = typeface.GSUBTable; ScriptTable scriptTable = gsubTable.ScriptList.FindScriptTable(lang); //--------- if (scriptTable == null) { return; } //early exit if no lookup tables //--------- ScriptTable.LangSysTable selectedLang = null; if (scriptTable.langSysTables != null && scriptTable.langSysTables.Length > 0) { //TODO: review here selectedLang = scriptTable.langSysTables[0]; } else { selectedLang = scriptTable.defaultLang; } if (selectedLang.HasRequireFeature) { //TODO: review here } //other feature if (selectedLang.featureIndexList != null) { //get features var features = new List <FeatureList.FeatureTable>(); for (int i = 0; i < selectedLang.featureIndexList.Length; ++i) { FeatureList.FeatureTable feature = gsubTable.FeatureList.featureTables[selectedLang.featureIndexList[i]]; switch (feature.TagName) { case "ccmp": //glyph composition/decomposition //this version we implement ccmp features.Add(feature); break; case "liga": //Standard Ligatures --enable by default features.Add(feature); break; } } //----------------------- lookupTables = new List <GSUB.LookupTable>(); int j = features.Count; for (int i = 0; i < j; ++i) { FeatureList.FeatureTable feature = features[i]; ushort[] lookupListIndices = feature.LookupListIndice; foreach (ushort lookupIndex in lookupListIndices) { GSUB.LookupTable lktable = gsubTable.GetLookupTable(lookupIndex); lktable.ForUseWithFeatureId = feature.TagName; lookupTables.Add(gsubTable.GetLookupTable(lookupIndex)); } } } }
public GlyphSetPosition(Typeface typeface, uint scriptTag, uint langTag) { this.ScriptTag = scriptTag; //script tag this.LangTag = langTag; //lang tag //check if this lang has _gposTable = typeface.GPOSTable; if (_gposTable == null) { return; } ScriptTable scriptTable = _gposTable.ScriptList[scriptTag]; if (scriptTable == null) { return; } // early exit if no lookup tables ScriptTable.LangSysTable selectedLang = scriptTable.defaultLang; if (selectedLang == null) { return; //no default } if (LangTag != 0 && scriptTable.langSysTables != null) //use default { //find matching lang for (int i = 0; i < scriptTable.langSysTables.Length; ++i) { if (scriptTable.langSysTables[i].langSysTagIden == LangTag) { //found selectedLang = scriptTable.langSysTables[i]; break; } } } #if DEBUG dbugTypeface = typeface; if (selectedLang.HasRequireFeature) { System.Diagnostics.Debugger.Break(); } #endif //other feature if (selectedLang.featureIndexList == null) { return; } // early exit //--------- //get features _lookupTables = new List <GPOS.LookupTable>(); for (int i = 0; i < selectedLang.featureIndexList.Length; ++i) { FeatureList.FeatureTable feature = _gposTable.FeatureList.featureTables[selectedLang.featureIndexList[i]]; bool includeThisFeature = false; switch (feature.TagName) { case "mark": //mark=> mark to base case "mkmk": //mkmk => mark to mask //current version we implement this 2 features includeThisFeature = true; break; case "kern": //test with Candara font includeThisFeature = true; //If palt is activated, there is no requirement that kern must also be activated. //If kern is activated, palt must also be activated if it exists. //https://www.microsoft.com/typography/OTSpec/features_pt.htm#palt break; //case "palt": // break; case "abvm": case "blwm": case "dist": includeThisFeature = true; break; default: System.Diagnostics.Debug.WriteLine("gpos_skip_tag:" + feature.TagName); break; } if (includeThisFeature) { foreach (ushort lookupIndex in feature.LookupListIndices) { _lookupTables.Add(_gposTable.LookupList[lookupIndex]); } } } }