GlyphSetPosition.cs 4.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122
  1. //MIT, 2016-present, WinterDev
  2. using System.Collections.Generic;
  3. using Typography.OpenFont;
  4. using Typography.OpenFont.Tables;
  5. namespace Typography.TextLayout
  6. {
  7. /// <summary>
  8. /// glyph set position manager
  9. /// </summary>
  10. class GlyphSetPosition
  11. {
  12. #if DEBUG
  13. readonly Typeface dbugTypeface;
  14. #endif
  15. readonly GPOS _gposTable;
  16. internal List<GPOS.LookupTable> _lookupTables;
  17. #if DEBUG
  18. public string dbugScriptLang;
  19. #endif
  20. public GlyphSetPosition(Typeface typeface, uint scriptTag, uint langTag)
  21. {
  22. this.ScriptTag = scriptTag; //script tag
  23. this.LangTag = langTag; //lang tag
  24. //check if this lang has
  25. _gposTable = typeface.GPOSTable;
  26. if (_gposTable == null) { return; }
  27. ScriptTable scriptTable = _gposTable.ScriptList[scriptTag];
  28. if (scriptTable == null) { return; } // early exit if no lookup tables
  29. ScriptTable.LangSysTable selectedLang = scriptTable.defaultLang;
  30. if (selectedLang == null) return; //no default
  31. if (LangTag != 0 && scriptTable.langSysTables != null)//use default
  32. {
  33. //find matching lang
  34. for (int i = 0; i < scriptTable.langSysTables.Length; ++i)
  35. {
  36. if (scriptTable.langSysTables[i].langSysTagIden == LangTag)
  37. {
  38. //found
  39. selectedLang = scriptTable.langSysTables[i];
  40. break;
  41. }
  42. }
  43. }
  44. #if DEBUG
  45. dbugTypeface = typeface;
  46. if (selectedLang.HasRequireFeature)
  47. {
  48. System.Diagnostics.Debugger.Break();
  49. }
  50. #endif
  51. //other feature
  52. if (selectedLang.featureIndexList == null) { return; }// early exit
  53. //---------
  54. //get features
  55. _lookupTables = new List<GPOS.LookupTable>();
  56. for (int i = 0; i < selectedLang.featureIndexList.Length; ++i)
  57. {
  58. FeatureList.FeatureTable feature = _gposTable.FeatureList.featureTables[selectedLang.featureIndexList[i]];
  59. bool includeThisFeature = false;
  60. switch (feature.TagName)
  61. {
  62. case "mark"://mark=> mark to base
  63. case "mkmk"://mkmk => mark to mask
  64. //current version we implement this 2 features
  65. includeThisFeature = true;
  66. break;
  67. case "kern":
  68. //test with Candara font
  69. includeThisFeature = true;
  70. //If palt is activated, there is no requirement that kern must also be activated.
  71. //If kern is activated, palt must also be activated if it exists.
  72. //https://www.microsoft.com/typography/OTSpec/features_pt.htm#palt
  73. break;
  74. //case "palt":
  75. // break;
  76. case "abvm":
  77. case "blwm":
  78. case "dist":
  79. includeThisFeature = true;
  80. break;
  81. default:
  82. System.Diagnostics.Debug.WriteLine("gpos_skip_tag:" + feature.TagName);
  83. break;
  84. }
  85. if (includeThisFeature)
  86. {
  87. foreach (ushort lookupIndex in feature.LookupListIndices)
  88. {
  89. _lookupTables.Add(_gposTable.LookupList[lookupIndex]);
  90. }
  91. }
  92. }
  93. }
  94. public uint ScriptTag { get; }
  95. public uint LangTag { get; }
  96. public void DoGlyphPosition(IGlyphPositions glyphPositions)
  97. {
  98. //early exit if no lookup tables
  99. //load
  100. if (_lookupTables == null) { return; }
  101. //
  102. int j = _lookupTables.Count;
  103. for (int i = 0; i < j; ++i)
  104. {
  105. _lookupTables[i].DoGlyphPosition(glyphPositions, 0, glyphPositions.Count);
  106. }
  107. }
  108. }
  109. }