Explorar el Código

d02 Исправление ошибки для сборки

SVI hace 2 años
padre
commit
1b37dcd269
Se han modificado 100 ficheros con 9622 adiciones y 5388 borrados
  1. 13 13
      go.mod
  2. 27 26
      go.sum
  3. 2 1
      pkg/components/parsetime/parsehour/parsehour.go
  4. 1 1
      pkg/components/parsetime/parsetime_test.go
  5. 5 2
      pkg/components/section/section.go
  6. 191 54
      vendor/github.com/go-text/typesetting/harfbuzz/buffer.go
  7. 48 11
      vendor/github.com/go-text/typesetting/harfbuzz/fonts.go
  8. 41 10
      vendor/github.com/go-text/typesetting/harfbuzz/glyph.go
  9. 15 9
      vendor/github.com/go-text/typesetting/harfbuzz/harfbuzz.go
  10. 247 162
      vendor/github.com/go-text/typesetting/harfbuzz/ot_aat_layout.go
  11. 170 39
      vendor/github.com/go-text/typesetting/harfbuzz/ot_aat_map.go
  12. 126 62
      vendor/github.com/go-text/typesetting/harfbuzz/ot_arabic.go
  13. 161 0
      vendor/github.com/go-text/typesetting/harfbuzz/ot_arabic_pua_table.go
  14. 368 209
      vendor/github.com/go-text/typesetting/harfbuzz/ot_arabic_table.go
  15. 1 1
      vendor/github.com/go-text/typesetting/harfbuzz/ot_hangul.go
  16. 19 1
      vendor/github.com/go-text/typesetting/harfbuzz/ot_hebrew.go
  17. 186 412
      vendor/github.com/go-text/typesetting/harfbuzz/ot_indic.go
  18. 400 379
      vendor/github.com/go-text/typesetting/harfbuzz/ot_indic_machine.go
  19. 17 14
      vendor/github.com/go-text/typesetting/harfbuzz/ot_indic_machine.rl
  20. 161 181
      vendor/github.com/go-text/typesetting/harfbuzz/ot_indic_table.go
  21. 2 1
      vendor/github.com/go-text/typesetting/harfbuzz/ot_kern.go
  22. 21 63
      vendor/github.com/go-text/typesetting/harfbuzz/ot_khmer.go
  23. 160 142
      vendor/github.com/go-text/typesetting/harfbuzz/ot_khmer_machine.go
  24. 19 15
      vendor/github.com/go-text/typesetting/harfbuzz/ot_khmer_machine.rl
  25. 4 0
      vendor/github.com/go-text/typesetting/harfbuzz/ot_language.go
  26. 60 37
      vendor/github.com/go-text/typesetting/harfbuzz/ot_language_table.go
  27. 9 15
      vendor/github.com/go-text/typesetting/harfbuzz/ot_layout.go
  28. 130 48
      vendor/github.com/go-text/typesetting/harfbuzz/ot_layout_gpos.go
  29. 8 6
      vendor/github.com/go-text/typesetting/harfbuzz/ot_layout_gsub.go
  30. 188 145
      vendor/github.com/go-text/typesetting/harfbuzz/ot_layout_gsubgpos.go
  31. 96 52
      vendor/github.com/go-text/typesetting/harfbuzz/ot_map.go
  32. 73 119
      vendor/github.com/go-text/typesetting/harfbuzz/ot_myanmar.go
  33. 261 268
      vendor/github.com/go-text/typesetting/harfbuzz/ot_myanmar_machine.go
  34. 31 30
      vendor/github.com/go-text/typesetting/harfbuzz/ot_myanmar_machine.rl
  35. 8 15
      vendor/github.com/go-text/typesetting/harfbuzz/ot_shape_complex.go
  36. 18 5
      vendor/github.com/go-text/typesetting/harfbuzz/ot_shape_fallback.go
  37. 10 6
      vendor/github.com/go-text/typesetting/harfbuzz/ot_shape_normalize.go
  38. 62 45
      vendor/github.com/go-text/typesetting/harfbuzz/ot_shaper.go
  39. 2 0
      vendor/github.com/go-text/typesetting/harfbuzz/ot_tag.go
  40. 41 40
      vendor/github.com/go-text/typesetting/harfbuzz/ot_thai.go
  41. 48 42
      vendor/github.com/go-text/typesetting/harfbuzz/ot_use.go
  42. 631 296
      vendor/github.com/go-text/typesetting/harfbuzz/ot_use_machine.go
  43. 18 15
      vendor/github.com/go-text/typesetting/harfbuzz/ot_use_machine.rl
  44. 2 2
      vendor/github.com/go-text/typesetting/harfbuzz/ot_use_machine_defs.go
  45. 386 335
      vendor/github.com/go-text/typesetting/harfbuzz/ot_use_table.go
  46. 28 1
      vendor/github.com/go-text/typesetting/harfbuzz/ot_vowels_constraints.go
  47. 17 9
      vendor/github.com/go-text/typesetting/harfbuzz/set_digest.go
  48. 7 16
      vendor/github.com/go-text/typesetting/harfbuzz/shape.go
  49. 85 75
      vendor/github.com/go-text/typesetting/harfbuzz/unicode.go
  50. 7 6
      vendor/github.com/go-text/typesetting/language/scripts.go
  51. 1335 1232
      vendor/github.com/go-text/typesetting/language/scripts_table.go
  52. 137 2
      vendor/github.com/go-text/typesetting/opentype/api/cmap.go
  53. 161 0
      vendor/github.com/go-text/typesetting/opentype/api/cmap_arabic_pua_table.go
  54. 7 1
      vendor/github.com/go-text/typesetting/opentype/api/font.go
  55. 15 1
      vendor/github.com/go-text/typesetting/opentype/api/font/cff/interpreter/interpreter.go
  56. 40 34
      vendor/github.com/go-text/typesetting/opentype/api/font/font.go
  57. 2 2
      vendor/github.com/go-text/typesetting/opentype/api/font/glyphs.go
  58. 25 9
      vendor/github.com/go-text/typesetting/opentype/api/font/metrics.go
  59. 16 3
      vendor/github.com/go-text/typesetting/opentype/api/font/renderer.go
  60. 48 19
      vendor/github.com/go-text/typesetting/opentype/api/font/variations.go
  61. 20 9
      vendor/github.com/go-text/typesetting/opentype/loader/reader.go
  62. 49 0
      vendor/github.com/go-text/typesetting/opentype/tables/aat_ltag_gen.go
  63. 25 0
      vendor/github.com/go-text/typesetting/opentype/tables/aat_ltag_src.go
  64. 22 0
      vendor/github.com/go-text/typesetting/opentype/tables/os2_src.go
  65. 1 1
      vendor/github.com/go-text/typesetting/opentype/tables/ot_properties.go
  66. 25 0
      vendor/github.com/go-text/typesetting/shaping/input.go
  67. 20 4
      vendor/github.com/go-text/typesetting/shaping/shaper.go
  68. 64 8
      vendor/github.com/go-text/typesetting/shaping/wrapping.go
  69. 162 104
      vendor/github.com/go-text/typesetting/unicodedata/combining_classes.go
  70. 19 14
      vendor/github.com/go-text/typesetting/unicodedata/east_asian_width.go
  71. 0 250
      vendor/github.com/go-text/typesetting/unicodedata/emojis.go
  72. 2205 0
      vendor/github.com/go-text/typesetting/unicodedata/general_category.go
  73. 89 51
      vendor/github.com/go-text/typesetting/unicodedata/grapheme_break.go
  74. 7 2
      vendor/github.com/go-text/typesetting/unicodedata/indic.go
  75. 152 71
      vendor/github.com/go-text/typesetting/unicodedata/linebreak.go
  76. 9 1
      vendor/github.com/go-text/typesetting/unicodedata/mirroring.go
  77. 8 3
      vendor/github.com/go-text/typesetting/unicodedata/sentence_break.go
  78. 3 0
      vendor/github.com/go-text/typesetting/unicodedata/unicode.go
  79. 19 0
      vendor/github.com/jsummers/gobmp/COPYING.txt
  80. 3 22
      vendor/github.com/jsummers/gobmp/readme.md
  81. 1 1
      vendor/github.com/muesli/termenv/color.go
  82. 6 2
      vendor/github.com/muesli/termenv/termenv_unix.go
  83. 4 0
      vendor/github.com/yuin/goldmark/README.md
  84. 3 3
      vendor/github.com/yuin/goldmark/parser/raw_html.go
  85. 10 6
      vendor/github.com/yuin/goldmark/renderer/html/html.go
  86. 14 7
      vendor/github.com/yuin/goldmark/text/reader.go
  87. 28 5
      vendor/golang.org/x/image/tiff/reader.go
  88. 24 4
      vendor/golang.org/x/net/html/render.go
  89. 8 1
      vendor/golang.org/x/net/html/token.go
  90. 5 5
      vendor/golang.org/x/sync/errgroup/errgroup.go
  91. 14 0
      vendor/golang.org/x/sync/errgroup/go120.go
  92. 15 0
      vendor/golang.org/x/sync/errgroup/pre_go120.go
  93. 1 1
      vendor/golang.org/x/sys/unix/mkall.sh
  94. 6 4
      vendor/golang.org/x/sys/unix/mkerrors.sh
  95. 14 0
      vendor/golang.org/x/sys/unix/mmap_nomremap.go
  96. 53 0
      vendor/golang.org/x/sys/unix/mremap.go
  97. 0 15
      vendor/golang.org/x/sys/unix/syscall_aix.go
  98. 0 14
      vendor/golang.org/x/sys/unix/syscall_bsd.go
  99. 28 22
      vendor/golang.org/x/sys/unix/syscall_darwin.go
  100. 69 19
      vendor/golang.org/x/sys/unix/syscall_linux.go

+ 13 - 13
go.mod

@@ -18,37 +18,37 @@ require (
 	github.com/fsnotify/fsnotify v1.6.0 // indirect
 	github.com/fsnotify/fsnotify v1.6.0 // indirect
 	github.com/fyne-io/gl-js v0.0.0-20230506162202-1fdaa286a934 // indirect
 	github.com/fyne-io/gl-js v0.0.0-20230506162202-1fdaa286a934 // indirect
 	github.com/fyne-io/glfw-js v0.0.0-20220517201726-bebc2019cd33 // indirect
 	github.com/fyne-io/glfw-js v0.0.0-20220517201726-bebc2019cd33 // indirect
-	github.com/fyne-io/image v0.0.0-20221020213044-f609c6a24345 // indirect
+	github.com/fyne-io/image v0.0.0-20230811065323-ed435dc8bca6 // indirect
 	github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect
 	github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 // indirect
 	github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b // indirect
 	github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b // indirect
-	github.com/go-text/typesetting v0.0.0-20230531140649-96e0b46eecac // indirect
+	github.com/go-text/typesetting v0.0.0-20230803102845-24e03d8b5372 // indirect
 	github.com/godbus/dbus/v5 v5.1.0 // indirect
 	github.com/godbus/dbus/v5 v5.1.0 // indirect
 	github.com/goki/freetype v1.0.1 // indirect
 	github.com/goki/freetype v1.0.1 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/golang/snappy v0.0.4 // indirect
 	github.com/gopherjs/gopherjs v1.17.2 // indirect
 	github.com/gopherjs/gopherjs v1.17.2 // indirect
-	github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e // indirect
+	github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 // indirect
 	github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
 	github.com/lucasb-eyer/go-colorful v1.2.0 // indirect
 	github.com/mattn/go-isatty v0.0.19 // indirect
 	github.com/mattn/go-isatty v0.0.19 // indirect
 	github.com/mattn/go-localereader v0.0.1 // indirect
 	github.com/mattn/go-localereader v0.0.1 // indirect
-	github.com/mattn/go-runewidth v0.0.14 // indirect
+	github.com/mattn/go-runewidth v0.0.15 // indirect
 	github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
 	github.com/muesli/ansi v0.0.0-20230316100256-276c6243b2f6 // indirect
 	github.com/muesli/cancelreader v0.2.2 // indirect
 	github.com/muesli/cancelreader v0.2.2 // indirect
 	github.com/muesli/reflow v0.3.0 // indirect
 	github.com/muesli/reflow v0.3.0 // indirect
-	github.com/muesli/termenv v0.15.1 // indirect
+	github.com/muesli/termenv v0.15.2 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/pmezard/go-difflib v1.0.0 // indirect
 	github.com/rivo/uniseg v0.4.4 // indirect
 	github.com/rivo/uniseg v0.4.4 // indirect
 	github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
 	github.com/srwiley/oksvg v0.0.0-20221011165216-be6e8873101c // indirect
 	github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
 	github.com/srwiley/rasterx v0.0.0-20220730225603-2ab79fcdd4ef // indirect
 	github.com/stretchr/testify v1.8.4 // indirect
 	github.com/stretchr/testify v1.8.4 // indirect
 	github.com/tevino/abool v1.2.0 // indirect
 	github.com/tevino/abool v1.2.0 // indirect
-	github.com/yuin/goldmark v1.5.4 // indirect
-	golang.org/x/image v0.7.0 // indirect
+	github.com/yuin/goldmark v1.5.5 // indirect
+	golang.org/x/image v0.11.0 // indirect
 	golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda // indirect
 	golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda // indirect
-	golang.org/x/net v0.10.0 // indirect
-	golang.org/x/sync v0.2.0 // indirect
-	golang.org/x/sys v0.8.0 // indirect
-	golang.org/x/term v0.8.0 // indirect
-	golang.org/x/text v0.9.0 // indirect
+	golang.org/x/net v0.14.0 // indirect
+	golang.org/x/sync v0.3.0 // indirect
+	golang.org/x/sys v0.11.0 // indirect
+	golang.org/x/term v0.11.0 // indirect
+	golang.org/x/text v0.12.0 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
 	gopkg.in/yaml.v3 v3.0.1 // indirect
-	honnef.co/go/js/dom v0.0.0-20221001195520-26252dedbe70 // indirect
+	honnef.co/go/js/dom v0.0.0-20230808055721-96db8f4d5e3b // indirect
 )
 )

+ 27 - 26
go.sum

@@ -95,8 +95,8 @@ github.com/fyne-io/glfw-js v0.0.0-20220120001248-ee7290d23504/go.mod h1:gLRWYfYn
 github.com/fyne-io/glfw-js v0.0.0-20220517201726-bebc2019cd33 h1:0Ayg0/do/sqX2R7NonoLZvWxGrd9utTVf3A0QvCbC88=
 github.com/fyne-io/glfw-js v0.0.0-20220517201726-bebc2019cd33 h1:0Ayg0/do/sqX2R7NonoLZvWxGrd9utTVf3A0QvCbC88=
 github.com/fyne-io/glfw-js v0.0.0-20220517201726-bebc2019cd33/go.mod h1:gLRWYfYnMA9TONeppRSikMdXlHQ97xVsPojddUv3b/E=
 github.com/fyne-io/glfw-js v0.0.0-20220517201726-bebc2019cd33/go.mod h1:gLRWYfYnMA9TONeppRSikMdXlHQ97xVsPojddUv3b/E=
 github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2/go.mod h1:eO7W361vmlPOrykIg+Rsh1SZ3tQBaOsfzZhsIOb/Lm0=
 github.com/fyne-io/image v0.0.0-20220602074514-4956b0afb3d2/go.mod h1:eO7W361vmlPOrykIg+Rsh1SZ3tQBaOsfzZhsIOb/Lm0=
-github.com/fyne-io/image v0.0.0-20221020213044-f609c6a24345 h1:ONkcbJmsWUOHyjUm0wlnkFc/uaacFFtStVbsG6qJfew=
-github.com/fyne-io/image v0.0.0-20221020213044-f609c6a24345/go.mod h1:eO7W361vmlPOrykIg+Rsh1SZ3tQBaOsfzZhsIOb/Lm0=
+github.com/fyne-io/image v0.0.0-20230811065323-ed435dc8bca6 h1:kZNUHSV3ZTddRiWy5JHK6RgB3zdH/875SYXmt3EoNvQ=
+github.com/fyne-io/image v0.0.0-20230811065323-ed435dc8bca6/go.mod h1:aX1w6epS9BQn2bePY+3rkQejetaffeFhXl0s8QjXJJk=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/ghodss/yaml v1.0.0/go.mod h1:4dBDuWmgqj2HViK6kFavaiC9ZROes6MMH2rRYeMEF04=
 github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk=
 github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6 h1:zDw5v7qm4yH7N8C8uWd+8Ii9rROdgWxQuGoJ9WDXxfk=
 github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
 github.com/go-gl/gl v0.0.0-20211210172815-726fda9656d6/go.mod h1:9YTyiznxEY1fVinfM7RvRcjRHbw2xLBJ3AAGIT0I4Nw=
@@ -108,10 +108,10 @@ github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b h1:GgabKamyOY
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-gl/glfw/v3.3/glfw v0.0.0-20221017161538-93cebf72946b/go.mod h1:tQ2UAYgL5IevRw8kRxooKSPJfGvJ9fJQFa0TUsXzTg8=
 github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
 github.com/go-ole/go-ole v1.2.6/go.mod h1:pprOEPIfldk/42T2oK7lQ4v4JSDwmV0As9GaiUsvbm0=
 github.com/go-text/typesetting v0.0.0-20230405155246-bf9c697c6e16/go.mod h1:zvWM81wAVW6QfVDI6yxfbCuoLnobSYTuMsrXU/u11y8=
 github.com/go-text/typesetting v0.0.0-20230405155246-bf9c697c6e16/go.mod h1:zvWM81wAVW6QfVDI6yxfbCuoLnobSYTuMsrXU/u11y8=
-github.com/go-text/typesetting v0.0.0-20230531140649-96e0b46eecac h1:WYYkOfY2AXxFDOZXR7PUqANYcPYRCl6+etu3Ih0cyUw=
-github.com/go-text/typesetting v0.0.0-20230531140649-96e0b46eecac/go.mod h1:KmrpWuSMFcO2yjmyhGpnBGQHSKAoEgMTSSzvLDzCuEA=
+github.com/go-text/typesetting v0.0.0-20230803102845-24e03d8b5372 h1:FQivqchis6bE2/9uF70M2gmmLpe82esEm2QadL0TEJo=
+github.com/go-text/typesetting v0.0.0-20230803102845-24e03d8b5372/go.mod h1:evDBbvNR/KaVFZ2ZlDSOWWXIUKq0wCOEtzLxRM8SG3k=
 github.com/go-text/typesetting-utils v0.0.0-20230326210548-458646692de6/go.mod h1:RaqFwjcYyM5BjbYGwON0H5K0UqwO3sJlo9ukKha80ZE=
 github.com/go-text/typesetting-utils v0.0.0-20230326210548-458646692de6/go.mod h1:RaqFwjcYyM5BjbYGwON0H5K0UqwO3sJlo9ukKha80ZE=
-github.com/go-text/typesetting-utils v0.0.0-20230412163830-89e4bcfa3ecc h1:9Kf84pnrmmjdRzZIkomfjowmGUhHs20jkrWYw/I6CYc=
+github.com/go-text/typesetting-utils v0.0.0-20230616150549-2a7df14b6a22 h1:LBQTFxP2MfsyEDqSKmUBZaDuDHN1vpqDyOZjcqS7MYI=
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/godbus/dbus/v5 v5.0.4/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
 github.com/godbus/dbus/v5 v5.1.0 h1:4KLkAxT3aOY8Li4FRJe/KvhoNFFxo0m6fNuFUO8QJUk=
 github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
 github.com/godbus/dbus/v5 v5.1.0/go.mod h1:xhWf0FNVPg57R7Z0UbKHbJfkEywrmjJnf7w5xrFpKfA=
@@ -221,8 +221,9 @@ github.com/josephspurrier/goversioninfo v1.4.0/go.mod h1:JWzv5rKQr+MmW+LvM412ToT
 github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/json-iterator/go v1.1.11/go.mod h1:KdQUCv79m/52Kvf8AW2vK1V8akMuk1QjK/uOdHXbAo4=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.0.0-20190106144839-af01ea7f8024/go.mod h1:6v2b51hI/fHJwM22ozAgKL4VKDeJcHhJFhtBdhmNjmU=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
 github.com/jstemmer/go-junit-report v0.9.1/go.mod h1:Brl9GWCQeLvo8nXZwPNNblvFj/XSXhF0NWZEnDohbsk=
-github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e h1:LvL4XsI70QxOGHed6yhQtAU34Kx3Qq2wwBzGFKY8zKk=
 github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
 github.com/jsummers/gobmp v0.0.0-20151104160322-e2ba15ffa76e/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
+github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25 h1:YLvr1eE6cdCqjOe972w/cYF+FjW34v27+9Vo5106B4M=
+github.com/jsummers/gobmp v0.0.0-20230614200233-a9de23ed2e25/go.mod h1:kLgvv7o6UM+0QSf0QjAse3wReFDsb9qbZJdfexWlrQw=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/jtolds/gls v4.20.0+incompatible/go.mod h1:QJZ7F/aHp+rZTRtaJ1ow/lLfFfVYBRgL+9YlvaHOwJU=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
@@ -242,8 +243,8 @@ github.com/mattn/go-isatty v0.0.19/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D
 github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
 github.com/mattn/go-localereader v0.0.1 h1:ygSAOl7ZXTx4RdPYinUpg6W99U8jWvWi9Ye2JC/oIi4=
 github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
 github.com/mattn/go-localereader v0.0.1/go.mod h1:8fBrzywKY7BI3czFoHkuzRoWE9C+EiG4R1k4Cjx5p88=
 github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
 github.com/mattn/go-runewidth v0.0.12/go.mod h1:RAqKPSqVFrSLVXbA8x7dzmKdmGzieGRCM46jaSJTDAk=
-github.com/mattn/go-runewidth v0.0.14 h1:+xnbZSEeDbOIg5/mE6JF0w6n9duR1l3/WmbinWVwUuU=
-github.com/mattn/go-runewidth v0.0.14/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
+github.com/mattn/go-runewidth v0.0.15 h1:UNAjwbU9l54TA3KzvqLGxwWjHmMgBUVhBiTjelZgg3U=
+github.com/mattn/go-runewidth v0.0.15/go.mod h1:Jdepj2loyihRzMpdS35Xk/zdY8IAYHsh153qUoGf23w=
 github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
 github.com/mcuadros/go-version v0.0.0-20190830083331-035f6764e8d2/go.mod h1:76rfSfYPWj01Z85hUf/ituArm797mNKcvINh1OlsZKo=
 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 github.com/miekg/dns v1.0.14/go.mod h1:W1PPwlIAgtquWBMBEV9nkV9Cazfe8ScdGz/Lj7v3Nrg=
 github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
 github.com/mitchellh/cli v1.0.0/go.mod h1:hNIlj7HEI86fIcpObd7a0FcrxTWetlwJDGcceTlRvqc=
@@ -263,8 +264,8 @@ github.com/muesli/cancelreader v0.2.2 h1:3I4Kt4BQjOR54NavqnDogx/MIoWBFa0StPA8ELU
 github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
 github.com/muesli/cancelreader v0.2.2/go.mod h1:3XuTXfFS2VjM+HTLZY9Ak0l6eUKfijIfMUZ4EgX0QYo=
 github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
 github.com/muesli/reflow v0.3.0 h1:IFsN6K9NfGtjeggFP+68I4chLZV2yIKsXJFNZ+eWh6s=
 github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
 github.com/muesli/reflow v0.3.0/go.mod h1:pbwTDkVPibjO2kyvBQRBxTWEEGDGq0FlB1BIKtnHY/8=
-github.com/muesli/termenv v0.15.1 h1:UzuTb/+hhlBugQz28rpzey4ZuKcZ03MeKsoG7IJZIxs=
-github.com/muesli/termenv v0.15.1/go.mod h1:HeAQPTzpfs016yGtA4g00CsdYnVLJvxsS4ANqrZs2sQ=
+github.com/muesli/termenv v0.15.2 h1:GohcuySI0QmI3wN8Ok9PtKGkgkFIk7y6Vpb5PvrY+Wo=
+github.com/muesli/termenv v0.15.2/go.mod h1:Epx+iuz8sNs7mNKhxzH4fWXGNpZwUaJKRS1noLXviQ8=
 github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
 github.com/neelance/astrewrite v0.0.0-20160511093645-99348263ae86/go.mod h1:kHJEU3ofeGjhHklVoIGuVj85JJwZ6kWPaJwCIxgnFmo=
 github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
 github.com/neelance/sourcemap v0.0.0-20200213170602-2833bce08e4c/go.mod h1:Qr6/a/Q4r9LP1IltGz7tA7iOK1WonHEYhu1HRBA7ZiM=
 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
 github.com/nfnt/resize v0.0.0-20180221191011-83c6a9932646/go.mod h1:jpp1/29i3P1S/RLdc7JQKbRpFeM1dOBd8T9ki5s+AY8=
@@ -339,8 +340,8 @@ github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9dec
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.3.5/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.0/go.mod h1:mwnBkeHKe2W/ZEtQ+71ViKU8L12m81fl3OWwC1Zlc8k=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 github.com/yuin/goldmark v1.4.13/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
-github.com/yuin/goldmark v1.5.4 h1:2uY/xC0roWy8IBEGLgB1ywIoEJFGmRrX21YQcvGZzjU=
-github.com/yuin/goldmark v1.5.4/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
+github.com/yuin/goldmark v1.5.5 h1:IJznPe8wOzfIKETmMkd06F8nXkmlhaHqFRM9l1hAGsU=
+github.com/yuin/goldmark v1.5.5/go.mod h1:6yULJ656Px+3vBD8DxQVa3kxgyrAnzto9xy5taEt/CY=
 go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
 go.etcd.io/etcd/api/v3 v3.5.0/go.mod h1:cbVKeC6lCfl7j/8jBhAK6aIYO9XOjdptoxU/nLQcPvs=
 go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
 go.etcd.io/etcd/client/pkg/v3 v3.5.0/go.mod h1:IJHfcCEKxYu1Os13ZdwCwIUTUVGYTSAM3YSwc9/Ac1g=
 go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
 go.etcd.io/etcd/client/v2 v2.305.0/go.mod h1:h9puh54ZTgAKtEbut2oe9P4L/oqKCVB6xsXlzd7alYQ=
@@ -378,8 +379,8 @@ golang.org/x/image v0.0.0-20190227222117-0694c2d4d067/go.mod h1:kZ7UVZpmo3dzQBMx
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20190802002840-cff245a6509b/go.mod h1:FeLwcggjj3mMvU+oOTbSwawSJRM1uh48EjtB4UJZlP0=
 golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
 golang.org/x/image v0.0.0-20211028202545-6944b10bf410/go.mod h1:023OzeP/+EPmXeapQh35lcL3II3LrY8Ic+EFFKVhULM=
 golang.org/x/image v0.3.0/go.mod h1:fXd9211C/0VTlYuAcOhW8dY/RtEJqODXOWBDpmYBf+A=
 golang.org/x/image v0.3.0/go.mod h1:fXd9211C/0VTlYuAcOhW8dY/RtEJqODXOWBDpmYBf+A=
-golang.org/x/image v0.7.0 h1:gzS29xtG1J5ybQlv0PuyfE3nmc6R4qB73m6LUUmvFuw=
-golang.org/x/image v0.7.0/go.mod h1:nd/q4ef1AKKYl/4kft7g+6UyGbdiqWqTP1ZAbRoV7Rg=
+golang.org/x/image v0.11.0 h1:ds2RoQvBvYTiJkwpSFDwCcDFNX7DqjL2WsUgTNk0Ooo=
+golang.org/x/image v0.11.0/go.mod h1:bglhjqbqVuEb9e9+eNR45Jfu7D+T4Qan+NhQk8Ck2P8=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
 golang.org/x/lint v0.0.0-20190301231843-5614ed5bae6f/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE=
@@ -449,8 +450,8 @@ golang.org/x/net v0.0.0-20210805182204-aaa1db679c0d/go.mod h1:9nx3DQGgdP8bBQD5qx
 golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20211118161319-6a13c67c3ce4/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
 golang.org/x/net v0.6.0/go.mod h1:2Tu9+aMcznHK/AK1HMvgo6xiTLG5rD5rZLDS+rp2Bjs=
-golang.org/x/net v0.10.0 h1:X2//UzNDwYmtCLn7To6G58Wr6f5ahEAQgKNzv9Y951M=
-golang.org/x/net v0.10.0/go.mod h1:0qNGK6F8kojg2nk9dLZ2mShWaEBan6FAoqfSigmmuDg=
+golang.org/x/net v0.14.0 h1:BONx9s002vGdD9umnlX1Po8vOZmrgH34qlHcD1MfK14=
+golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190226205417-e64efc72b421/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
 golang.org/x/oauth2 v0.0.0-20190604053449-0f29369cfe45/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw=
@@ -476,8 +477,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.2.0 h1:PUR+T4wwASmuSTYdKjYHI5TD22Wy5ogLU5qZCOLxBrI=
-golang.org/x/sync v0.2.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
+golang.org/x/sync v0.3.0 h1:ftCYgMx6zT/asHUrPw8BLLscYtGznsLAnjq5RH9P66E=
+golang.org/x/sync v0.3.0/go.mod h1:FU7BRWz2tNW+3quACPkgCx/L+uEAv1htQ0V83Z9Rj+Y=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20180909124046-d0be0721c37e/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
@@ -534,13 +535,13 @@ golang.org/x/sys v0.0.0-20220908164124-27713097b956/go.mod h1:oPkhp1MJrh7nUepCBc
 golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.1.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.5.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
-golang.org/x/sys v0.8.0 h1:EBmGv8NaZBZTWvrbjNoL6HVt+IVy3QDQpJs7VRIw3tU=
-golang.org/x/sys v0.8.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
+golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
+golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
 golang.org/x/term v0.5.0/go.mod h1:jMB1sMXY+tzblOD4FWmEbocvup2/aLOaQEp7JmGp78k=
-golang.org/x/term v0.8.0 h1:n5xxQn2i3PC0yLAbjTpNT85q/Kgzcr2gIoX9OrJUols=
-golang.org/x/term v0.8.0/go.mod h1:xPskH00ivmX89bAKVGSKKtLOWNx2+17Eiy94tnKShWo=
+golang.org/x/term v0.11.0 h1:F9tnn/DA/Im8nCwm+fX+1/eBwi4qFjRT++MhtVC4ZX0=
+golang.org/x/term v0.11.0/go.mod h1:zC9APTIj3jG3FdV/Ons+XE1riIZXG4aZ4GTHiPZJPIU=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.0.0-20170915032832-14c0d48ead0c/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
 golang.org/x/text v0.3.1-0.20180807135948-17ff2d5776d2/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
@@ -552,8 +553,8 @@ golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ=
 golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.6.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
 golang.org/x/text v0.7.0/go.mod h1:mrYo+phRRbMaCq/xk9113O4dZlRixOauAjOtrjsXDZ8=
-golang.org/x/text v0.9.0 h1:2sjJmO8cDvYveuX97RDLsxlyUxLl+GHoLxBiRdHllBE=
-golang.org/x/text v0.9.0/go.mod h1:e1OnstbJyHTd6l/uOt8jFFHp6TRDWZR/bV3emEE/zU8=
+golang.org/x/text v0.12.0 h1:k+n5B8goJNdU7hSvEtMUz3d1Q6D/XW4COJSJR6fN0mc=
+golang.org/x/text v0.12.0/go.mod h1:TvPlkZtksWOMsz7fbANvkp4WM8x/WCo/om8BMLbz+aE=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20181108054448-85acf8d2951c/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
 golang.org/x/time v0.0.0-20191024005414-555d28b269f0/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ=
@@ -739,8 +740,8 @@ gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 gopkg.in/yaml.v3 v3.0.1/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
 honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2/go.mod h1:sUMDUKNB2ZcVjt92UnLy3cdGs+wDAcrPdV3JP6sVgA4=
 honnef.co/go/js/dom v0.0.0-20210725211120-f030747120f2/go.mod h1:sUMDUKNB2ZcVjt92UnLy3cdGs+wDAcrPdV3JP6sVgA4=
-honnef.co/go/js/dom v0.0.0-20221001195520-26252dedbe70 h1:2ZZFiPwRLxiNX2E/YO6Jgw1pCjDRDgmx20PGyw/cw+M=
-honnef.co/go/js/dom v0.0.0-20221001195520-26252dedbe70/go.mod h1:sUMDUKNB2ZcVjt92UnLy3cdGs+wDAcrPdV3JP6sVgA4=
+honnef.co/go/js/dom v0.0.0-20230808055721-96db8f4d5e3b h1:xXAdf0+OXZAdmc4cewENXYdfry1u03Fax3ucj3F9Duw=
+honnef.co/go/js/dom v0.0.0-20230808055721-96db8f4d5e3b/go.mod h1:sUMDUKNB2ZcVjt92UnLy3cdGs+wDAcrPdV3JP6sVgA4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190102054323-c2f93a96b099/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190106161140-3f1c8253044a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=
 honnef.co/go/tools v0.0.0-20190418001031-e561f6794a2a/go.mod h1:rf3lG4BRIbNafJWhAfAdb/ePZxsR/4RtNHQocxwk9r4=

+ 2 - 1
pkg/components/parsetime/parsehour/parsehour.go

@@ -44,7 +44,8 @@ func (sf *ParseHour) Reset() {
 }
 }
 
 
 // Parse -- устанавливает значение часов
 // Parse -- устанавливает значение часов
-//   Значение часов может быть больше 24
+//
+//	Значение часов может быть больше 24
 func (sf *ParseHour) Parse(strHour string) error {
 func (sf *ParseHour) Parse(strHour string) error {
 	sf.block.Lock()
 	sf.block.Lock()
 	defer sf.block.Unlock()
 	defer sf.block.Unlock()

+ 1 - 1
pkg/components/parsetime/parsetime_test.go

@@ -38,7 +38,7 @@ func (sf *tester) create() {
 	if val := sf.pars.Get(); val != 0 {
 	if val := sf.pars.Get(); val != 0 {
 		sf.t.Errorf("create(): valInt(%d)!=0\n", val)
 		sf.t.Errorf("create(): valInt(%d)!=0\n", val)
 	}
 	}
-	_=sf.pars.String()
+	_ = sf.pars.String()
 }
 }
 
 
 // Парсинг строки времени
 // Парсинг строки времени

+ 5 - 2
pkg/components/section/section.go

@@ -6,6 +6,7 @@ import (
 	"log"
 	"log"
 
 
 	"wartank/pkg/components/lst_string"
 	"wartank/pkg/components/lst_string"
+	"wartank/pkg/components/parsetime"
 	"wartank/pkg/components/section/down_time"
 	"wartank/pkg/components/section/down_time"
 	"wartank/pkg/components/section/section_mode"
 	"wartank/pkg/components/section/section_mode"
 	"wartank/pkg/components/section/zone"
 	"wartank/pkg/components/section/zone"
@@ -63,14 +64,16 @@ func (sf *Section) SetCountDown(sec int) error {
 
 
 // ParseCountDown -- устанавливает новое значение обратного счётчика времени (string)
 // ParseCountDown -- устанавливает новое значение обратного счётчика времени (string)
 func (sf *Section) ParseCountDown(sec string) error {
 func (sf *Section) ParseCountDown(sec string) error {
-	sf.countDown = down_time.ParseCountTime(sf, sec)
+	pt := parsetime.NewParseTime()
+	pt.Parse(sec)
+	_sec := pt.Get()
+	sf.countDown = down_time.NewCountTime(sf, _sec)
 	// if err := sf.countDown.Set(sec); err != nil {
 	// if err := sf.countDown.Set(sec); err != nil {
 	// 	return fmt.Errorf("Section.SetCountDown(): err=\n\t%w", err)
 	// 	return fmt.Errorf("Section.SetCountDown(): err=\n\t%w", err)
 	// }
 	// }
 	return nil
 	return nil
 }
 }
 
 
-
 // CountDown -- объект оставшегося времени
 // CountDown -- объект оставшегося времени
 func (sf *Section) CountDown() types.ICountTime {
 func (sf *Section) CountDown() types.ICountTime {
 	return sf.countDown
 	return sf.countDown

+ 191 - 54
vendor/github.com/go-text/typesetting/harfbuzz/buffer.go

@@ -1,8 +1,6 @@
 package harfbuzz
 package harfbuzz
 
 
 import (
 import (
-	"math"
-
 	"github.com/go-text/typesetting/language"
 	"github.com/go-text/typesetting/language"
 	"github.com/go-text/typesetting/opentype/tables"
 	"github.com/go-text/typesetting/opentype/tables"
 )
 )
@@ -30,15 +28,18 @@ const (
 	bsfHasDefaultIgnorables
 	bsfHasDefaultIgnorables
 	bsfHasSpaceFallback
 	bsfHasSpaceFallback
 	bsfHasGPOSAttachment
 	bsfHasGPOSAttachment
-	bsfHasUnsafeToBreak
+	// bsfHasUnsafeToBreak
 	bsfHasCGJ
 	bsfHasCGJ
+	bsfHasGlyphFlags
+	bsfHasBrokenSyllable
+
 	bsfDefault bufferScratchFlags = 0x00000000
 	bsfDefault bufferScratchFlags = 0x00000000
 
 
-	// reserved for complex shapers' internal use.
-	bsfComplex0 bufferScratchFlags = 0x01000000
-	bsfComplex1 bufferScratchFlags = 0x02000000
-	bsfComplex2 bufferScratchFlags = 0x04000000
-	bsfComplex3 bufferScratchFlags = 0x08000000
+	// reserved for shapers' internal use.
+	bsfShaper0 bufferScratchFlags = 0x01000000
+	bsfShaper1 bufferScratchFlags = 0x02000000
+	bsfShaper2 bufferScratchFlags = 0x04000000
+	bsfShaper3 bufferScratchFlags = 0x08000000
 )
 )
 
 
 // maximum length of additional context added outside
 // maximum length of additional context added outside
@@ -100,7 +101,7 @@ type Buffer struct {
 
 
 	serial       uint
 	serial       uint
 	idx          int                // Cursor into `info` and `pos` arrays
 	idx          int                // Cursor into `info` and `pos` arrays
-	scratchFlags bufferScratchFlags /* Have space-fallback, etc. */
+	scratchFlags bufferScratchFlags // Have space-fallback, etc.
 
 
 	haveOutput bool
 	haveOutput bool
 
 
@@ -111,9 +112,9 @@ type Buffer struct {
 // It should then be populated with `AddRunes` and shapped with `Shape`.
 // It should then be populated with `AddRunes` and shapped with `Shape`.
 func NewBuffer() *Buffer {
 func NewBuffer() *Buffer {
 	return &Buffer{
 	return &Buffer{
-		ClusterLevel:  MonotoneGraphemes,
-		maxOps:        maxOpsDefault,
-		planCache:     map[Face][]*shapePlan{},
+		ClusterLevel: MonotoneGraphemes,
+		maxOps:       maxOpsDefault,
+		planCache:    map[Face][]*shapePlan{},
 	}
 	}
 }
 }
 
 
@@ -218,6 +219,7 @@ func (b *Buffer) GuessSegmentProperties() {
 // Clear resets `b` to its initial empty state (including user settings).
 // Clear resets `b` to its initial empty state (including user settings).
 // This method should be used to reuse the allocated memory.
 // This method should be used to reuse the allocated memory.
 func (b *Buffer) Clear() {
 func (b *Buffer) Clear() {
+	b.ClusterLevel = 0
 	b.Flags = 0
 	b.Flags = 0
 	b.Invisible = 0
 	b.Invisible = 0
 	b.NotFound = 0
 	b.NotFound = 0
@@ -246,10 +248,17 @@ func (b *Buffer) cur(i int) *GlyphInfo { return &b.Info[b.idx+i] }
 func (b *Buffer) curPos(i int) *GlyphPosition { return &b.Pos[b.idx+i] }
 func (b *Buffer) curPos(i int) *GlyphPosition { return &b.Pos[b.idx+i] }
 
 
 // returns the last glyph of `outInfo`
 // returns the last glyph of `outInfo`
-func (b Buffer) prev() *GlyphInfo {
+func (b *Buffer) prev() *GlyphInfo {
 	return &b.outInfo[len(b.outInfo)-1]
 	return &b.outInfo[len(b.outInfo)-1]
 }
 }
 
 
+func (b *Buffer) digest() (d setDigest) {
+	for _, glyph := range b.Info {
+		d.add(gID(glyph.Glyph))
+	}
+	return d
+}
+
 // func (b Buffer) has_separate_output() bool { return info != b.outInfo }
 // func (b Buffer) has_separate_output() bool { return info != b.outInfo }
 
 
 func (b *Buffer) backtrackLen() int {
 func (b *Buffer) backtrackLen() int {
@@ -356,6 +365,49 @@ func (b *Buffer) resetMasks(mask GlyphMask) {
 	}
 	}
 }
 }
 
 
+// Adds glyph flags in mask to infos with clusters between start and end.
+// The start index will be from out-buffer if [fromOutBuffer] is true.
+// If [interior] is true, then the cluster having the minimum value is skipped.
+func (b *Buffer) setGlyphFlags(mask GlyphMask, start, end int, interior, fromOutBuffer bool) {
+	end = min(end, len(b.Info))
+
+	if interior && !fromOutBuffer && end-start < 2 {
+		return
+	}
+
+	b.scratchFlags |= bsfHasGlyphFlags
+
+	info := b.Info
+	if !fromOutBuffer || !b.haveOutput {
+		if !interior {
+			for i := start; i < end; i++ {
+				info[i].Mask |= mask
+			}
+		} else {
+			cluster := b.findMinCluster(info, start, end, maxInt)
+			b.infosSetGlyphFlags(info, start, end, cluster, mask)
+		}
+	} else {
+		// assert (start <= out_len);
+		// assert (idx <= end);
+		outInfo := b.outInfo
+		if !interior {
+			for i := start; i < len(outInfo); i++ {
+				outInfo[i].Mask |= mask
+			}
+			for i := b.idx; i < end; i++ {
+				info[i].Mask |= mask
+			}
+		} else {
+			cluster := b.findMinCluster(info, b.idx, end, maxInt)
+			cluster = b.findMinCluster(outInfo, start, len(outInfo), cluster)
+
+			b.infosSetGlyphFlags(outInfo, start, len(outInfo), cluster, mask)
+			b.infosSetGlyphFlags(info, b.idx, end, cluster, mask)
+		}
+	}
+}
+
 func (b *Buffer) setMasks(value, mask GlyphMask, clusterStart, clusterEnd int) {
 func (b *Buffer) setMasks(value, mask GlyphMask, clusterStart, clusterEnd int) {
 	notMask := ^mask
 	notMask := ^mask
 	value &= mask
 	value &= mask
@@ -387,18 +439,22 @@ func (b *Buffer) mergeClusters(start, end int) {
 		cluster = min(cluster, b.Info[i].Cluster)
 		cluster = min(cluster, b.Info[i].Cluster)
 	}
 	}
 
 
-	/* Extend end */
-	for end < len(b.Info) && b.Info[end-1].Cluster == b.Info[end].Cluster {
-		end++
+	// Extend end
+	if cluster != b.Info[end-1].Cluster {
+		for end < len(b.Info) && b.Info[end-1].Cluster == b.Info[end].Cluster {
+			end++
+		}
 	}
 	}
 
 
-	/* Extend start */
-	for b.idx < start && b.Info[start-1].Cluster == b.Info[start].Cluster {
-		start--
+	// Extend start
+	if cluster != b.Info[start].Cluster {
+		for b.idx < start && b.Info[start-1].Cluster == b.Info[start].Cluster {
+			start--
+		}
 	}
 	}
 
 
-	/* If we hit the start of buffer, continue in out-buffer. */
-	if b.idx == start {
+	// If we hit the start of buffer, continue in out-buffer.
+	if b.idx == start && b.Info[start].Cluster != cluster {
 		startC := b.Info[start].Cluster
 		startC := b.Info[start].Cluster
 		for i := len(b.outInfo); i != 0 && b.outInfo[i-1].Cluster == startC; i-- {
 		for i := len(b.outInfo); i != 0 && b.outInfo[i-1].Cluster == startC; i-- {
 			b.outInfo[i-1].setCluster(cluster, 0)
 			b.outInfo[i-1].setCluster(cluster, 0)
@@ -412,20 +468,21 @@ func (b *Buffer) mergeClusters(start, end int) {
 
 
 // merge clusters for deleting current glyph, and skip it.
 // merge clusters for deleting current glyph, and skip it.
 func (b *Buffer) deleteGlyph() {
 func (b *Buffer) deleteGlyph() {
-	/* The logic here is duplicated in hb_ot_hide_default_ignorables(). */
+	// The logic here is duplicated in hb_ot_hide_default_ignorables().
 
 
 	cluster := b.Info[b.idx].Cluster
 	cluster := b.Info[b.idx].Cluster
-	if b.idx+1 < len(b.Info) && cluster == b.Info[b.idx+1].Cluster {
+	if L := len(b.outInfo); b.idx+1 < len(b.Info) && cluster == b.Info[b.idx+1].Cluster ||
+		L != 0 && cluster == b.outInfo[L-1].Cluster {
 		/* Cluster survives; do nothing. */
 		/* Cluster survives; do nothing. */
 		goto done
 		goto done
 	}
 	}
 
 
-	if len(b.outInfo) != 0 {
+	if L := len(b.outInfo); L != 0 {
 		/* Merge cluster backward. */
 		/* Merge cluster backward. */
-		if cluster < b.outInfo[len(b.outInfo)-1].Cluster {
+		if cluster < b.outInfo[L-1].Cluster {
 			mask := b.Info[b.idx].Mask
 			mask := b.Info[b.idx].Mask
-			oldCluster := b.outInfo[len(b.outInfo)-1].Cluster
-			for i := len(b.outInfo); i != 0 && b.outInfo[i-1].Cluster == oldCluster; i-- {
+			oldCluster := b.outInfo[L-1].Cluster
+			for i := L; i != 0 && b.outInfo[i-1].Cluster == oldCluster; i-- {
 				b.outInfo[i-1].setCluster(cluster, mask)
 				b.outInfo[i-1].setCluster(cluster, mask)
 			}
 			}
 		}
 		}
@@ -442,53 +499,133 @@ done:
 	b.skipGlyph()
 	b.skipGlyph()
 }
 }
 
 
+func (b *Buffer) deleteGlyphsInplace(filter func(*GlyphInfo) bool) {
+	// Merge clusters and delete filtered glyphs.
+	// NOTE! We can't use out-buffer as we have positioning data.
+	var (
+		j    int
+		info = b.Info
+		pos  = b.Pos
+	)
+	for i := range info {
+		if filter(&info[i]) {
+			/* Merge clusters.
+			* Same logic as buffer.deleteGlyph(), but for in-place removal. */
+
+			cluster := info[i].Cluster
+			if i+1 < len(b.Info) && cluster == info[i+1].Cluster {
+				// Cluster survives; do nothing.
+				continue
+			}
+
+			if j != 0 {
+				// Merge cluster backward.
+				if cluster < info[j-1].Cluster {
+					mask := info[i].Mask
+					oldCluster := info[j-1].Cluster
+					for k := j; k != 0 && info[k-1].Cluster == oldCluster; k-- {
+						info[k-1].setCluster(cluster, mask)
+					}
+				}
+				continue
+			}
+
+			if i+1 < len(b.Info) {
+				// Merge cluster forward.
+				b.mergeClusters(i, i+2)
+			}
+
+			continue
+		}
+
+		if j != i {
+			info[j] = info[i]
+			pos[j] = pos[i]
+		}
+		j++
+	}
+	b.Info = b.Info[:j]
+	b.Pos = b.Pos[:j]
+}
+
 // unsafeToBreak adds the flag `GlyphFlagUnsafeToBreak`
 // unsafeToBreak adds the flag `GlyphFlagUnsafeToBreak`
 // when needed, between `start` and `end`.
 // when needed, between `start` and `end`.
 func (b *Buffer) unsafeToBreak(start, end int) {
 func (b *Buffer) unsafeToBreak(start, end int) {
-	if end-start < 2 {
+	b.setGlyphFlags(GlyphUnsafeToBreak|GlyphUnsafeToConcat, start, end, true, false)
+}
+
+func (b *Buffer) safeToInsertTatweel(start, end int) {
+	if (b.Flags & ProduceSafeToInsertTatweel) == 0 {
+		b.unsafeToBreak(start, end)
 		return
 		return
 	}
 	}
-	b.unsafeToBreakImpl(start, end)
+	b.setGlyphFlags(GlyphSafeToInsertTatweel, start, end, true, false)
 }
 }
 
 
-func (b *Buffer) unsafeToBreakImpl(start, end int) {
-	cluster := findMinCluster(b.Info, start, end, maxInt)
-	b.unsafeToBreakSetMask(b.Info, start, end, cluster)
+// start = 0, end = maxInt
+func (b *Buffer) unsafeToConcat(start, end int) {
+	if (b.Flags & ProduceUnsafeToConcat) == 0 {
+		return
+	}
+	b.setGlyphFlags(GlyphUnsafeToConcat, start, end, true, false)
 }
 }
 
 
-// return the smallest cluster between `cluster` and  infos[start:end]
-func findMinCluster(infos []GlyphInfo, start, end, cluster int) int {
-	for i := start; i < end; i++ {
-		cluster = min(cluster, infos[i].Cluster)
+func (b *Buffer) unsafeToBreakFromOutbuffer(start, end int) {
+	b.setGlyphFlags(GlyphUnsafeToBreak|GlyphUnsafeToConcat, start, end, true, true)
+}
+
+func (b *Buffer) unsafeToConcatFromOutbuffer(start, end int) {
+	if (b.Flags & ProduceUnsafeToConcat) == 0 {
+		return
 	}
 	}
-	return cluster
+	b.setGlyphFlags(GlyphUnsafeToConcat, start, end, false, true)
 }
 }
 
 
-func (b *Buffer) unsafeToBreakSetMask(infos []GlyphInfo,
-	start, end, cluster int,
-) {
-	for i := start; i < end; i++ {
-		if cluster != infos[i].Cluster {
-			b.scratchFlags |= bsfHasUnsafeToBreak
-			infos[i].Mask |= GlyphUnsafeToBreak
+// return the smallest cluster between `cluster` and  infos[start:end]
+func (b *Buffer) findMinCluster(infos []GlyphInfo, start, end, cluster int) int {
+	if start == end {
+		return cluster
+	}
+	if b.ClusterLevel == Characters {
+		for i := start; i < end; i++ {
+			cluster = min(cluster, infos[i].Cluster)
 		}
 		}
+		return cluster
 	}
 	}
+	return min(cluster, min(infos[start].Cluster, infos[end-1].Cluster))
 }
 }
 
 
-func (b *Buffer) unsafeToBreakFromOutbuffer(start, end int) {
-	if !b.haveOutput {
-		b.unsafeToBreakImpl(start, end)
+func (b *Buffer) infosSetGlyphFlags(infos []GlyphInfo, start, end, cluster int, mask GlyphMask) {
+	if start == end {
+		return
+	}
+
+	clusterFirst := infos[start].Cluster
+	clusterLast := infos[end-1].Cluster
+
+	if b.ClusterLevel == Characters || (cluster != clusterFirst && cluster != clusterLast) {
+		for i := start; i < end; i++ {
+			if cluster != infos[i].Cluster {
+				b.scratchFlags |= bsfHasGlyphFlags
+				infos[i].Mask |= mask
+			}
+		}
 		return
 		return
 	}
 	}
 
 
-	//   assert (start <= out_len);
-	//   assert (idx <= end);
+	/* Monotone clusters */
 
 
-	cluster := math.MaxInt32
-	cluster = findMinCluster(b.outInfo, start, len(b.outInfo), cluster)
-	cluster = findMinCluster(b.Info, b.idx, end, cluster)
-	b.unsafeToBreakSetMask(b.outInfo, start, len(b.outInfo), cluster)
-	b.unsafeToBreakSetMask(b.Info, b.idx, end, cluster)
+	if cluster == clusterFirst {
+		for i := end; start < i && infos[i-1].Cluster != clusterFirst; i-- {
+			b.scratchFlags |= bsfHasGlyphFlags
+			infos[i-1].Mask |= mask
+		}
+	} else /* cluster == clusterLast */ {
+		for i := start; i < end && infos[i].Cluster != clusterLast; i++ {
+			b.scratchFlags |= bsfHasGlyphFlags
+			infos[i].Mask |= mask
+		}
+	}
 }
 }
 
 
 // reset `b.outInfo`, and adjust `pos` to have
 // reset `b.outInfo`, and adjust `pos` to have

+ 48 - 11
vendor/github.com/go-text/typesetting/harfbuzz/fonts.go

@@ -27,6 +27,32 @@ type Font struct {
 	Ptem float32
 	Ptem float32
 
 
 	// Horizontal and vertical scale of the font.
 	// Horizontal and vertical scale of the font.
+	//
+	// The font scale is a number related to, but not the same as,
+	// font size. Typically the client establishes a scale factor
+	// to be used between the two. For example, 64, or 256, which
+	// would be the fractional-precision part of the font scale.
+	// This is necessary because [Position] values are integer
+	// types and you need to leave room for fractional values
+	// in there.
+	//
+	// For example, to set the font size to 20, with 64
+	// levels of fractional precision you would use a scale of
+	// 20 * 64.
+	//
+	// In the example above, even what font size 20 means is up to
+	// you. It might be 20 pixels, or 20 points, or 20 millimeters.
+	// HarfBuzz does not care about that. You can set the point
+	// size of the font using [Ptem], and the pixel
+	// size using [Face.Ppem]
+	//
+	// The choice of scale is yours but needs to be consistent between
+	// what you set here, and what you expect out of [Position]
+	// as well has draw / paint API output values.
+	//
+	// Fonts default to a scale equal to the UPEM value of their face.
+	// A font with this setting is sometimes called an "unscaled" font.
+	//
 	// The resulting positions are computed with: fontUnit * Scale / faceUpem,
 	// The resulting positions are computed with: fontUnit * Scale / faceUpem,
 	// where faceUpem is given by the face.
 	// where faceUpem is given by the face.
 	//
 	//
@@ -142,8 +168,14 @@ func (f *Font) GlyphHAdvance(glyph GID) Position {
 // Fetches the advance for a glyph ID in the font,
 // Fetches the advance for a glyph ID in the font,
 // for vertical text segments.
 // for vertical text segments.
 func (f *Font) getGlyphVAdvance(glyph GID) Position {
 func (f *Font) getGlyphVAdvance(glyph GID) Position {
-	adv := f.face.VerticalAdvance(glyph)
-	return f.emScalefY(adv)
+	if f.face.HasVerticalMetrics() {
+		adv := f.face.VerticalAdvance(glyph)
+		return f.emScalefY(adv)
+	} else {
+		fontExtents := f.fontHExtentsWithFallback()
+		advance := Position(-(fontExtents.Ascender - fontExtents.Descender))
+		return advance
+	}
 }
 }
 
 
 // Subtracts the origin coordinates from an (X,Y) point coordinate,
 // Subtracts the origin coordinates from an (X,Y) point coordinate,
@@ -238,6 +270,19 @@ func (f *Font) getGlyphContourPointForOrigin(glyph GID, pointIndex uint16, direc
 	return x, y, ok
 	return x, y, ok
 }
 }
 
 
+func (f *Font) fontHExtentsWithFallback() api.FontExtents {
+	extents, ok := f.face.FontHExtents()
+	extents.Ascender = float32(f.emScalefY(extents.Ascender))
+	extents.Descender = float32(f.emScalefY(extents.Descender))
+	extents.LineGap = float32(f.emScalefY(extents.LineGap))
+	if !ok {
+		extents.Ascender = float32(f.YScale) * 0.8
+		extents.Descender = extents.Ascender - float32(f.YScale)
+		extents.LineGap = 0
+	}
+	return extents
+}
+
 // ExtentsForDirection fetches the extents for a font in a text segment of the
 // ExtentsForDirection fetches the extents for a font in a text segment of the
 // specified direction, applying the scaling.
 // specified direction, applying the scaling.
 //
 //
@@ -249,15 +294,7 @@ func (f *Font) ExtentsForDirection(direction Direction) api.FontExtents {
 		ok      bool
 		ok      bool
 	)
 	)
 	if direction.isHorizontal() {
 	if direction.isHorizontal() {
-		extents, ok = f.face.FontHExtents()
-		extents.Ascender = float32(f.emScalefY(extents.Ascender))
-		extents.Descender = float32(f.emScalefY(extents.Descender))
-		extents.LineGap = float32(f.emScalefY(extents.LineGap))
-		if !ok {
-			extents.Ascender = float32(f.YScale) * 0.8
-			extents.Descender = extents.Ascender - float32(f.YScale)
-			extents.LineGap = 0
-		}
+		return f.fontHExtentsWithFallback()
 	} else {
 	} else {
 		extents, ok = f.face.FontVExtents()
 		extents, ok = f.face.FontVExtents()
 		extents.Ascender = float32(f.emScalefX(extents.Ascender))
 		extents.Ascender = float32(f.emScalefX(extents.Ascender))

+ 41 - 10
vendor/github.com/go-text/typesetting/harfbuzz/glyph.go

@@ -80,12 +80,47 @@ const (
 	// if breaking input text at the beginning of this cluster and shaping the two sides
 	// if breaking input text at the beginning of this cluster and shaping the two sides
 	// separately.
 	// separately.
 	// This can be used to optimize paragraph layout, by avoiding re-shaping
 	// This can be used to optimize paragraph layout, by avoiding re-shaping
-	// of each line after line-breaking, or limiting the reshaping to a small piece around the
-	// breaking point only.
-	GlyphUnsafeToBreak GlyphMask = 0x00000001
+	// of each line after line-breaking.
+	GlyphUnsafeToBreak GlyphMask = 1 << iota
+
+	// Indicates that if input text is changed on one side of the beginning of the cluster this glyph
+	// is part of, then the shaping results for the other side might change.
+	// Note that the absence of this flag will NOT by itself mean that it IS safe to concat text.
+	// Only two pieces of text both of which clear of this flag can be concatenated safely.
+	// This can be used to optimize paragraph layout, by avoiding re-shaping of each line
+	// after line-breaking, by limiting the reshaping to a small piece around the
+	// breaking positin only, even if the breaking position carries the
+	// [GlyphUnsafeToBreak] or when hyphenation or other text transformation
+	// happens at line-break position, in the following way:
+	// 	1. Iterate back from the line-break position until the first cluster start position that is
+	// 		NOT unsafe-to-concat,
+	// 	2. Shape the segment from there till the end of line,
+	// 	3. Check whether the resulting glyph-run also is clear of the unsafe-to-concat at its start-of-text position;
+	// 		if it is, just splice it into place and the line is shaped; If not, move on to a position further
+	// 		back that is clear of unsafe-to-concat and retry from there, and repeat.
+	// At the start of next line a similar algorithm can be implemented. That is:
+	// 	1. Iterate forward from the line-break position until the first cluster start position that is NOT unsafe-to-concat,
+	// 	2. Shape the segment from beginning of the line to that position,
+	// 	3. Check whether the resulting glyph-run also is clear of the unsafe-to-concat at its end-of-text position;
+	// 		if it is, just splice it into place and the beginning is shaped; If not, move on to a position further forward that is clear
+	// 	 	of unsafe-to-concat and retry up to there, and repeat.
+	// A slight complication will arise in the implementation of the algorithm above, because while our buffer API has a way to
+	// return flags for position corresponding to start-of-text, there is currently no position
+	// corresponding to end-of-text.  This limitation can be alleviated by shaping more text than needed
+	// and looking for unsafe-to-concat flag within text clusters.
+	// The [GlyphUnsafeToBreak] flag will always imply this flag.
+	// To use this flag, you must enable the buffer flag [ProduceUnsafeToConcat] during
+	// shaping, otherwise the buffer flag will not be reliably produced.
+	GlyphUnsafeToConcat
+
+	// In scripts that use elongation (Arabic, Mongolian, Syriac, etc.), this flag signifies
+	// that it is safe to insert a U+0640 TATWEEL character before this cluster for elongation.
+	// This flag does not determine the script-specific elongation places, but only
+	// when it is safe to do the elongation without interrupting text shaping.
+	GlyphSafeToInsertTatweel
 
 
 	// OR of all defined flags
 	// OR of all defined flags
-	glyphFlagDefined GlyphMask = GlyphUnsafeToBreak
+	glyphFlagDefined GlyphMask = GlyphUnsafeToBreak | GlyphUnsafeToConcat | GlyphSafeToInsertTatweel
 )
 )
 
 
 // GlyphInfo holds information about the
 // GlyphInfo holds information about the
@@ -156,7 +191,7 @@ type GlyphInfo struct {
 
 
 // String returns a simple description of the glyph of the form Glyph=Cluster(mask)
 // String returns a simple description of the glyph of the form Glyph=Cluster(mask)
 func (info GlyphInfo) String() string {
 func (info GlyphInfo) String() string {
-	return fmt.Sprintf("%d=%d(%d)", info.Glyph, info.Cluster, info.Mask)
+	return fmt.Sprintf("%d=%d(0x%x)", info.Glyph, info.Cluster, info.Mask&glyphFlagDefined)
 }
 }
 
 
 func (info *GlyphInfo) setUnicodeProps(buffer *Buffer) {
 func (info *GlyphInfo) setUnicodeProps(buffer *Buffer) {
@@ -173,11 +208,7 @@ func (info *GlyphInfo) setGeneralCategory(genCat generalCategory) {
 
 
 func (info *GlyphInfo) setCluster(cluster int, mask GlyphMask) {
 func (info *GlyphInfo) setCluster(cluster int, mask GlyphMask) {
 	if info.Cluster != cluster {
 	if info.Cluster != cluster {
-		if mask&GlyphUnsafeToBreak != 0 {
-			info.Mask |= GlyphUnsafeToBreak
-		} else {
-			info.Mask &= ^GlyphUnsafeToBreak
-		}
+		info.Mask = (info.Mask & ^glyphFlagDefined) | (mask & glyphFlagDefined)
 	}
 	}
 	info.Cluster = cluster
 	info.Cluster = cluster
 }
 }

+ 15 - 9
vendor/github.com/go-text/typesetting/harfbuzz/harfbuzz.go

@@ -22,15 +22,11 @@ import (
 	"github.com/go-text/typesetting/opentype/tables"
 	"github.com/go-text/typesetting/opentype/tables"
 )
 )
 
 
-// based on upstream commit 449c4296a11a8b3d3882d4a4d6705281f5ff52e5
-// pending the change for Unicode 14 that are not merged yet, starting at
-// 195c05df9925c7c4a4982a286ef9c416b2cde3af
+// based on upstream commit 5d543d64222c6ce45332d0c188790f90691ef112
 
 
-// debugMode is only used in test:
-//   - 0 : nothing
-//   - 1 : only the main steps are printed
-//   - 2 : details informations are printed
-const debugMode = 0
+// debugMode is only used in test: if true, it prints detailed information
+// about shaping
+const debugMode = false
 
 
 type (
 type (
 	GID = api.GID
 	GID = api.GID
@@ -67,7 +63,7 @@ func getHorizontalDirection(script language.Script) Direction {
 		return RightToLeft
 		return RightToLeft
 
 
 	/* https://github.com/harfbuzz/harfbuzz/issues/1000 */
 	/* https://github.com/harfbuzz/harfbuzz/issues/1000 */
-	case language.Old_Hungarian, language.Old_Italic, language.Runic:
+	case language.Old_Hungarian, language.Old_Italic, language.Runic, language.Tifinagh:
 		return 0
 		return 0
 	}
 	}
 
 
@@ -153,6 +149,16 @@ const (
 	// not be inserted in the rendering of incorrect
 	// not be inserted in the rendering of incorrect
 	// character sequences (such at <0905 093E>).
 	// character sequences (such at <0905 093E>).
 	DoNotinsertDottedCircle
 	DoNotinsertDottedCircle
+
+	// Flag indicating that the [GlyphUnsafeToConcat]
+	// glyph-flag should be produced by the shaper. By default
+	// it will not be produced since it incurs a cost.
+	ProduceUnsafeToConcat
+
+	// Flag indicating that the [GlyphSafeToInsertTatweel]
+	// glyph-flag should be produced by the shaper. By default
+	// it will not be produced.
+	ProduceSafeToInsertTatweel
 )
 )
 
 
 // ClusterLevel allows selecting more fine-grained Cluster handling.
 // ClusterLevel allows selecting more fine-grained Cluster handling.

+ 247 - 162
vendor/github.com/go-text/typesetting/harfbuzz/ot_aat_layout.go

@@ -77,6 +77,8 @@ const (
 	aatLayoutFeatureTypeLowerCase = 37
 	aatLayoutFeatureTypeLowerCase = 37
 	// [Upper Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type38)
 	// [Upper Case](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type38)
 	aatLayoutFeatureTypeUpperCase = 38
 	aatLayoutFeatureTypeUpperCase = 38
+	// [Language Tag](https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html#Type39)
+	aatLayoutFeatureTypeLanguageTagType = 39
 )
 )
 
 
 // The selectors defined for specifying AAT feature settings.
 // The selectors defined for specifying AAT feature settings.
@@ -85,6 +87,10 @@ type aatLayoutFeatureSelector = uint16
 const (
 const (
 	/* Selectors for #aatLayoutFeatureTypeLigatures */
 	/* Selectors for #aatLayoutFeatureTypeLigatures */
 	// for #aatLayoutFeatureTypeLigatures
 	// for #aatLayoutFeatureTypeLigatures
+	aatLayoutFeatureSelectorRequiredLigaturesOn = 0
+	// for #aatLayoutFeatureTypeLigatures
+	aatLayoutFeatureSelectorRequiredLigaturesOff = 1
+	// for #aatLayoutFeatureTypeLigatures
 	aatLayoutFeatureSelectorCommonLigaturesOn = 2
 	aatLayoutFeatureSelectorCommonLigaturesOn = 2
 	// for #aatLayoutFeatureTypeLigatures
 	// for #aatLayoutFeatureTypeLigatures
 	aatLayoutFeatureSelectorCommonLigaturesOff = 3
 	aatLayoutFeatureSelectorCommonLigaturesOff = 3
@@ -354,10 +360,10 @@ const (
 	aatLayoutFeatureSelectorUpperCasePetiteCaps = 2
 	aatLayoutFeatureSelectorUpperCasePetiteCaps = 2
 )
 )
 
 
-/* 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. */
+// 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.
 var featureMappings = [...]aatFeatureMapping{
 var featureMappings = [...]aatFeatureMapping{
 	{loader.NewTag('a', 'f', 'r', 'c'), aatLayoutFeatureTypeFractions, aatLayoutFeatureSelectorVerticalFractions, aatLayoutFeatureSelectorNoFractions},
 	{loader.NewTag('a', 'f', 'r', 'c'), aatLayoutFeatureTypeFractions, aatLayoutFeatureSelectorVerticalFractions, aatLayoutFeatureSelectorNoFractions},
 	{loader.NewTag('c', '2', 'p', 'c'), aatLayoutFeatureTypeUpperCase, aatLayoutFeatureSelectorUpperCasePetiteCaps, aatLayoutFeatureSelectorDefaultUpperCase},
 	{loader.NewTag('c', '2', 'p', 'c'), aatLayoutFeatureTypeUpperCase, aatLayoutFeatureSelectorUpperCasePetiteCaps, aatLayoutFeatureSelectorDefaultUpperCase},
@@ -372,7 +378,7 @@ var featureMappings = [...]aatFeatureMapping{
 	{loader.NewTag('f', 'r', 'a', 'c'), aatLayoutFeatureTypeFractions, aatLayoutFeatureSelectorDiagonalFractions, aatLayoutFeatureSelectorNoFractions},
 	{loader.NewTag('f', 'r', 'a', 'c'), aatLayoutFeatureTypeFractions, aatLayoutFeatureSelectorDiagonalFractions, aatLayoutFeatureSelectorNoFractions},
 	{loader.NewTag('f', 'w', 'i', 'd'), aatLayoutFeatureTypeTextSpacing, aatLayoutFeatureSelectorMonospacedText, 7},
 	{loader.NewTag('f', 'w', 'i', 'd'), aatLayoutFeatureTypeTextSpacing, aatLayoutFeatureSelectorMonospacedText, 7},
 	{loader.NewTag('h', 'a', 'l', 't'), aatLayoutFeatureTypeTextSpacing, aatLayoutFeatureSelectorAltHalfWidthText, 7},
 	{loader.NewTag('h', 'a', 'l', 't'), aatLayoutFeatureTypeTextSpacing, aatLayoutFeatureSelectorAltHalfWidthText, 7},
-	{loader.NewTag('h', 'i', 's', 't'), aatLayoutFeatureTypeLigatures, aatLayoutFeatureSelectorHistoricalLigaturesOn, aatLayoutFeatureSelectorHistoricalLigaturesOff},
+	{loader.NewTag('h', 'i', 's', 't'), 40, 0, 1},
 	{loader.NewTag('h', 'k', 'n', 'a'), aatLayoutFeatureTypeAlternateKana, aatLayoutFeatureSelectorAlternateHorizKanaOn, aatLayoutFeatureSelectorAlternateHorizKanaOff},
 	{loader.NewTag('h', 'k', 'n', 'a'), aatLayoutFeatureTypeAlternateKana, aatLayoutFeatureSelectorAlternateHorizKanaOn, aatLayoutFeatureSelectorAlternateHorizKanaOff},
 	{loader.NewTag('h', 'l', 'i', 'g'), aatLayoutFeatureTypeLigatures, aatLayoutFeatureSelectorHistoricalLigaturesOn, aatLayoutFeatureSelectorHistoricalLigaturesOff},
 	{loader.NewTag('h', 'l', 'i', 'g'), aatLayoutFeatureTypeLigatures, aatLayoutFeatureSelectorHistoricalLigaturesOn, aatLayoutFeatureSelectorHistoricalLigaturesOff},
 	{loader.NewTag('h', 'n', 'g', 'l'), aatLayoutFeatureTypeTransliteration, aatLayoutFeatureSelectorHanjaToHangul, aatLayoutFeatureSelectorNoTransliteration},
 	{loader.NewTag('h', 'n', 'g', 'l'), aatLayoutFeatureTypeTransliteration, aatLayoutFeatureSelectorHanjaToHangul, aatLayoutFeatureSelectorNoTransliteration},
@@ -395,6 +401,7 @@ var featureMappings = [...]aatFeatureMapping{
 	{loader.NewTag('p', 'n', 'u', 'm'), aatLayoutFeatureTypeNumberSpacing, aatLayoutFeatureSelectorProportionalNumbers, 4},
 	{loader.NewTag('p', 'n', 'u', 'm'), aatLayoutFeatureTypeNumberSpacing, aatLayoutFeatureSelectorProportionalNumbers, 4},
 	{loader.NewTag('p', 'w', 'i', 'd'), aatLayoutFeatureTypeTextSpacing, aatLayoutFeatureSelectorProportionalText, 7},
 	{loader.NewTag('p', 'w', 'i', 'd'), aatLayoutFeatureTypeTextSpacing, aatLayoutFeatureSelectorProportionalText, 7},
 	{loader.NewTag('q', 'w', 'i', 'd'), aatLayoutFeatureTypeTextSpacing, aatLayoutFeatureSelectorQuarterWidthText, 7},
 	{loader.NewTag('q', 'w', 'i', 'd'), aatLayoutFeatureTypeTextSpacing, aatLayoutFeatureSelectorQuarterWidthText, 7},
+	{loader.NewTag('r', 'l', 'i', 'g'), aatLayoutFeatureTypeLigatures, aatLayoutFeatureSelectorRequiredLigaturesOn, aatLayoutFeatureSelectorRequiredLigaturesOff},
 	{loader.NewTag('r', 'u', 'b', 'y'), aatLayoutFeatureTypeRubyKana, aatLayoutFeatureSelectorRubyKanaOn, aatLayoutFeatureSelectorRubyKanaOff},
 	{loader.NewTag('r', 'u', 'b', 'y'), aatLayoutFeatureTypeRubyKana, aatLayoutFeatureSelectorRubyKanaOn, aatLayoutFeatureSelectorRubyKanaOff},
 	{loader.NewTag('s', 'i', 'n', 'f'), aatLayoutFeatureTypeVerticalPosition, aatLayoutFeatureSelectorScientificInferiors, aatLayoutFeatureSelectorNormalPosition},
 	{loader.NewTag('s', 'i', 'n', 'f'), aatLayoutFeatureTypeVerticalPosition, aatLayoutFeatureSelectorScientificInferiors, aatLayoutFeatureSelectorNormalPosition},
 	{loader.NewTag('s', 'm', 'c', 'p'), aatLayoutFeatureTypeLowerCase, aatLayoutFeatureSelectorLowerCaseSmallCaps, aatLayoutFeatureSelectorDefaultLowerCase},
 	{loader.NewTag('s', 'm', 'c', 'p'), aatLayoutFeatureTypeLowerCase, aatLayoutFeatureSelectorLowerCaseSmallCaps, aatLayoutFeatureSelectorDefaultLowerCase},
@@ -434,11 +441,145 @@ var featureMappings = [...]aatFeatureMapping{
 	{loader.NewTag('v', 'k', 'n', 'a'), aatLayoutFeatureTypeAlternateKana, aatLayoutFeatureSelectorAlternateVertKanaOn, aatLayoutFeatureSelectorAlternateVertKanaOff},
 	{loader.NewTag('v', 'k', 'n', 'a'), aatLayoutFeatureTypeAlternateKana, aatLayoutFeatureSelectorAlternateVertKanaOn, aatLayoutFeatureSelectorAlternateVertKanaOff},
 	{loader.NewTag('v', 'p', 'a', 'l'), aatLayoutFeatureTypeTextSpacing, aatLayoutFeatureSelectorAltProportionalText, 7},
 	{loader.NewTag('v', 'p', 'a', 'l'), aatLayoutFeatureTypeTextSpacing, aatLayoutFeatureSelectorAltProportionalText, 7},
 	{loader.NewTag('v', 'r', 't', '2'), aatLayoutFeatureTypeVerticalSubstitution, aatLayoutFeatureSelectorSubstituteVerticalFormsOn, aatLayoutFeatureSelectorSubstituteVerticalFormsOff},
 	{loader.NewTag('v', 'r', 't', '2'), aatLayoutFeatureTypeVerticalSubstitution, aatLayoutFeatureSelectorSubstituteVerticalFormsOn, aatLayoutFeatureSelectorSubstituteVerticalFormsOff},
+	{loader.NewTag('v', 'r', 't', 'r'), aatLayoutFeatureTypeVerticalSubstitution, 2, 3},
 	{loader.NewTag('z', 'e', 'r', 'o'), aatLayoutFeatureTypeTypographicExtras, aatLayoutFeatureSelectorSlashedZeroOn, aatLayoutFeatureSelectorSlashedZeroOff},
 	{loader.NewTag('z', 'e', 'r', 'o'), aatLayoutFeatureTypeTypographicExtras, aatLayoutFeatureSelectorSlashedZeroOn, aatLayoutFeatureSelectorSlashedZeroOff},
 }
 }
 
 
 /* Note: This context is used for kerning, even without AAT, hence the condition. */
 /* Note: This context is used for kerning, even without AAT, hence the condition. */
 
 
+type aatApplyContext struct {
+	plan      *otShapePlan
+	font      *Font
+	face      Face
+	buffer    *Buffer
+	gdefTable *tables.GDEF
+	ankrTable tables.Ankr
+
+	rangeFlags    []rangeFlags
+	subtableFlags GlyphMask
+}
+
+func newAatApplyContext(plan *otShapePlan, font *Font, buffer *Buffer) *aatApplyContext {
+	var out aatApplyContext
+	out.plan = plan
+	out.font = font
+	out.face = font.face
+	out.buffer = buffer
+	out.gdefTable = &font.face.GDEF
+	return &out
+}
+
+func (c *aatApplyContext) hasAnyFlags(flag GlyphMask) bool {
+	for _, fl := range c.rangeFlags {
+		if fl.flags&flag != 0 {
+			return true
+		}
+	}
+	return false
+}
+
+func (c *aatApplyContext) applyMorx(chain font.MorxChain) {
+	//  Coverage, see https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html
+	const (
+		Vertical      = 0x80
+		Backwards     = 0x40
+		AllDirections = 0x20
+		Logical       = 0x10
+	)
+
+	for i, subtable := range chain.Subtables {
+
+		if !c.hasAnyFlags(subtable.Flags) {
+			continue
+		}
+
+		c.subtableFlags = subtable.Flags
+		if subtable.Coverage&AllDirections == 0 && c.buffer.Props.Direction.isVertical() !=
+			(subtable.Coverage&Vertical != 0) {
+			continue
+		}
+
+		/* Buffer contents is always in logical direction.  Determine if
+		we need to reverse before applying this subtable.  We reverse
+		back after if we did reverse indeed.
+
+		Quoting the spec:
+		"""
+		Bits 28 and 30 of the coverage field control the order in which
+		glyphs are processed when the subtable is run by the layout engine.
+		Bit 28 is used to indicate if the glyph processing direction is
+		the same as logical order or layout order. Bit 30 is used to
+		indicate whether glyphs are processed forwards or backwards within
+		that order.
+
+		Bit 30	Bit 28	Interpretation for Horizontal Text
+		0	0	The subtable is processed in layout order 	(the same order as the glyphs, which is
+			always left-to-right).
+		1	0	The subtable is processed in reverse layout order (the order opposite that of the glyphs, which is
+			always right-to-left).
+		0	1	The subtable is processed in logical order (the same order as the characters, which may be
+			left-to-right or right-to-left).
+		1	1	The subtable is processed in reverse logical order 	(the order opposite that of the characters, which
+			may be right-to-left or left-to-right).
+		"""
+		*/
+		var reverse bool
+		if subtable.Coverage&Logical != 0 {
+			reverse = subtable.Coverage&Backwards != 0
+		} else {
+			reverse = subtable.Coverage&Backwards != 0 != c.buffer.Props.Direction.isBackward()
+		}
+
+		if debugMode {
+			fmt.Printf("MORX - start chainsubtable %d\n", i)
+		}
+
+		if reverse {
+			c.buffer.Reverse()
+		}
+
+		c.applyMorxSubtable(subtable)
+
+		if reverse {
+			c.buffer.Reverse()
+		}
+
+		if debugMode {
+			fmt.Printf("MORX - end chainsubtable %d\n", i)
+			fmt.Println(c.buffer.Info)
+		}
+
+	}
+}
+
+func (c *aatApplyContext) applyMorxSubtable(subtable font.MorxSubtable) bool {
+	if debugMode {
+		fmt.Printf("\tMORX subtable %T\n", subtable.Data)
+	}
+	switch data := subtable.Data.(type) {
+	case font.MorxRearrangementSubtable:
+		var dc driverContextRearrangement
+		driver := newStateTableDriver(font.AATStateTable(data), c.buffer, c.face)
+		driver.drive(&dc, c)
+	case font.MorxContextualSubtable:
+		dc := driverContextContextual{table: data, gdef: c.gdefTable, hasGlyphClass: c.gdefTable.GlyphClassDef != nil}
+		driver := newStateTableDriver(data.Machine, c.buffer, c.face)
+		driver.drive(&dc, c)
+		return dc.ret
+	case font.MorxLigatureSubtable:
+		dc := driverContextLigature{table: data}
+		driver := newStateTableDriver(data.Machine, c.buffer, c.face)
+		driver.drive(&dc, c)
+	case font.MorxInsertionSubtable:
+		dc := driverContextInsertion{insertionAction: data.Insertions}
+		driver := newStateTableDriver(data.Machine, c.buffer, c.face)
+		driver.drive(&dc, c)
+	case font.MorxNonContextualSubtable:
+		return c.applyNonContextualSubtable(data)
+	}
+	return false
+}
+
 /**
 /**
  *
  *
  * Functions for querying AAT Layout features in the font face.
  * Functions for querying AAT Layout features in the font face.
@@ -467,7 +608,7 @@ type driverContext interface {
 	transition(s stateTableDriver, entry tables.AATStateEntry)
 	transition(s stateTableDriver, entry tables.AATStateEntry)
 }
 }
 
 
-func (s stateTableDriver) drive(c driverContext) {
+func (s stateTableDriver) drive(c driverContext, ac *aatApplyContext) {
 	const (
 	const (
 		stateStartOfText = uint16(0)
 		stateStartOfText = uint16(0)
 
 
@@ -480,13 +621,43 @@ func (s stateTableDriver) drive(c driverContext) {
 	}
 	}
 
 
 	state := stateStartOfText
 	state := stateStartOfText
+	// If there's only one range, we already checked the flag.
+	var lastRange int = -1 // index in ac.rangeFlags, or -1
+	if len(ac.rangeFlags) > 1 {
+		lastRange = 0
+	}
 	for s.buffer.idx = 0; ; {
 	for s.buffer.idx = 0; ; {
+		// This block is copied in NoncontextualSubtable::apply. Keep in sync.
+		if lastRange != -1 {
+			range_ := lastRange
+			if s.buffer.idx < len(s.buffer.Info) {
+				cluster := s.buffer.cur(0).Cluster
+				for cluster < ac.rangeFlags[range_].clusterFirst {
+					range_--
+				}
+				for cluster > ac.rangeFlags[range_].clusterLast {
+					range_++
+				}
+
+				lastRange = range_
+			}
+			if !(ac.rangeFlags[range_].flags&ac.subtableFlags != 0) {
+				if s.buffer.idx == len(s.buffer.Info) {
+					break
+				}
+
+				state = stateStartOfText
+				s.buffer.nextGlyph()
+				continue
+			}
+		}
+
 		class := classEndOfText
 		class := classEndOfText
 		if s.buffer.idx < len(s.buffer.Info) {
 		if s.buffer.idx < len(s.buffer.Info) {
 			class = s.machine.GetClass(s.buffer.Info[s.buffer.idx].Glyph)
 			class = s.machine.GetClass(s.buffer.Info[s.buffer.idx].Glyph)
 		}
 		}
 
 
-		if debugMode >= 2 {
+		if debugMode {
 			fmt.Printf("\t\tState machine - state %d, class %d at index %d\n", state, class, s.buffer.idx)
 			fmt.Printf("\t\tState machine - state %d, class %d at index %d\n", state, class, s.buffer.idx)
 		}
 		}
 
 
@@ -548,7 +719,7 @@ func (s stateTableDriver) drive(c driverContext) {
 
 
 		state = nextState
 		state = nextState
 
 
-		if debugMode >= 2 {
+		if debugMode {
 			fmt.Printf("\t\tState machine - new state %d\n", state)
 			fmt.Printf("\t\tState machine - new state %d\n", state)
 		}
 		}
 
 
@@ -572,140 +743,6 @@ func (s stateTableDriver) drive(c driverContext) {
 	}
 	}
 }
 }
 
 
-type aatApplyContext struct {
-	plan      *otShapePlan
-	font      *Font
-	face      Face
-	buffer    *Buffer
-	gdefTable *tables.GDEF
-	ankrTable tables.Ankr
-}
-
-func newAatApplyContext(plan *otShapePlan, font *Font, buffer *Buffer) *aatApplyContext {
-	var out aatApplyContext
-	out.plan = plan
-	out.font = font
-	out.face = font.face
-	out.buffer = buffer
-	out.gdefTable = &font.face.GDEF
-	return &out
-}
-
-func (c *aatApplyContext) applyMorx(chain font.MorxChain, flags GlyphMask) {
-	//  Coverage, see https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6morx.html
-	const (
-		Vertical      = 0x80
-		Backwards     = 0x40
-		AllDirections = 0x20
-		Logical       = 0x10
-	)
-
-	for i, subtable := range chain.Subtables {
-
-		if subtable.Flags&flags == 0 {
-			continue
-		}
-
-		if subtable.Coverage&AllDirections == 0 && c.buffer.Props.Direction.isVertical() !=
-			(subtable.Coverage&Vertical != 0) {
-			continue
-		}
-
-		/* Buffer contents is always in logical direction.  Determine if
-		we need to reverse before applying this subtable.  We reverse
-		back after if we did reverse indeed.
-
-		Quoting the spec:
-		"""
-		Bits 28 and 30 of the coverage field control the order in which
-		glyphs are processed when the subtable is run by the layout engine.
-		Bit 28 is used to indicate if the glyph processing direction is
-		the same as logical order or layout order. Bit 30 is used to
-		indicate whether glyphs are processed forwards or backwards within
-		that order.
-
-		Bit 30	Bit 28	Interpretation for Horizontal Text
-		0	0	The subtable is processed in layout order 	(the same order as the glyphs, which is
-			always left-to-right).
-		1	0	The subtable is processed in reverse layout order (the order opposite that of the glyphs, which is
-			always right-to-left).
-		0	1	The subtable is processed in logical order (the same order as the characters, which may be
-			left-to-right or right-to-left).
-		1	1	The subtable is processed in reverse logical order 	(the order opposite that of the characters, which
-			may be right-to-left or left-to-right).
-		"""
-		*/
-		var reverse bool
-		if subtable.Coverage&Logical != 0 {
-			reverse = subtable.Coverage&Backwards != 0
-		} else {
-			reverse = subtable.Coverage&Backwards != 0 != c.buffer.Props.Direction.isBackward()
-		}
-
-		if debugMode >= 2 {
-			fmt.Printf("MORX - start chainsubtable %d\n", i)
-		}
-
-		if reverse {
-			reverseGraphemes(c.buffer)
-		}
-
-		c.applyMorxSubtable(subtable)
-
-		if reverse {
-			reverseGraphemes(c.buffer)
-		}
-
-		if debugMode >= 2 {
-			fmt.Printf("MORX - end chainsubtable %d\n", i)
-			fmt.Println(c.buffer.Info)
-		}
-
-	}
-}
-
-func (c *aatApplyContext) applyMorxSubtable(subtable font.MorxSubtable) bool {
-	if debugMode >= 2 {
-		fmt.Printf("\tMORX subtable %T\n", subtable.Data)
-	}
-	switch data := subtable.Data.(type) {
-	case font.MorxRearrangementSubtable:
-		var dc driverContextRearrangement
-		driver := newStateTableDriver(font.AATStateTable(data), c.buffer, c.face)
-		driver.drive(&dc)
-	case font.MorxContextualSubtable:
-		dc := driverContextContextual{table: data, gdef: c.gdefTable, hasGlyphClass: c.gdefTable.GlyphClassDef != nil}
-		driver := newStateTableDriver(data.Machine, c.buffer, c.face)
-		driver.drive(&dc)
-		return dc.ret
-	case font.MorxLigatureSubtable:
-		dc := driverContextLigature{table: data}
-		driver := newStateTableDriver(data.Machine, c.buffer, c.face)
-		driver.drive(&dc)
-	case font.MorxInsertionSubtable:
-		dc := driverContextInsertion{insertionAction: data.Insertions}
-		driver := newStateTableDriver(data.Machine, c.buffer, c.face)
-		driver.drive(&dc)
-	case font.MorxNonContextualSubtable:
-		var ret bool
-		gdef := c.gdefTable
-		hasGlyphClass := gdef.GlyphClassDef != nil
-		info := c.buffer.Info
-		for i := range c.buffer.Info {
-			replacement, has := data.Class.Class(gID(info[i].Glyph))
-			if has {
-				info[i].Glyph = GID(replacement)
-				if hasGlyphClass {
-					info[i].glyphProps = gdef.GlyphProps(gID(replacement))
-				}
-				ret = true
-			}
-		}
-		return ret
-	}
-	return false
-}
-
 // MorxRearrangemen flags
 // MorxRearrangemen flags
 const (
 const (
 	/* If set, make the current glyph the first
 	/* If set, make the current glyph the first
@@ -779,7 +816,7 @@ func (d *driverContextRearrangement) transition(driver stateTableDriver, entry t
 		reverseL := m>>4 == 3
 		reverseL := m>>4 == 3
 		reverseR := m&0x0F == 3
 		reverseR := m&0x0F == 3
 
 
-		if d.end-d.start >= l+r {
+		if d.end-d.start >= l+r && d.end-d.start <= maxContextLength {
 			buffer.mergeClusters(d.start, min(buffer.idx+1, len(buffer.Info)))
 			buffer.mergeClusters(d.start, min(buffer.idx+1, len(buffer.Info)))
 			buffer.mergeClusters(d.start, d.end)
 			buffer.mergeClusters(d.start, d.end)
 
 
@@ -902,7 +939,7 @@ func (driverContextLigature) isActionable(_ stateTableDriver, entry tables.AATSt
 func (dc *driverContextLigature) transition(driver stateTableDriver, entry tables.AATStateEntry) {
 func (dc *driverContextLigature) transition(driver stateTableDriver, entry tables.AATStateEntry) {
 	buffer := driver.buffer
 	buffer := driver.buffer
 
 
-	if debugMode >= 2 {
+	if debugMode {
 		fmt.Printf("\tLigature - Ligature transition at %d\n", buffer.idx)
 		fmt.Printf("\tLigature - Ligature transition at %d\n", buffer.idx)
 	}
 	}
 
 
@@ -915,7 +952,7 @@ func (dc *driverContextLigature) transition(driver stateTableDriver, entry table
 		dc.matchPositions[dc.matchLength%len(dc.matchPositions)] = len(buffer.outInfo)
 		dc.matchPositions[dc.matchLength%len(dc.matchPositions)] = len(buffer.outInfo)
 		dc.matchLength++
 		dc.matchLength++
 
 
-		if debugMode >= 2 {
+		if debugMode {
 			fmt.Printf("\tLigature - Set component at %d\n", len(buffer.outInfo))
 			fmt.Printf("\tLigature - Set component at %d\n", len(buffer.outInfo))
 		}
 		}
 
 
@@ -923,7 +960,7 @@ func (dc *driverContextLigature) transition(driver stateTableDriver, entry table
 
 
 	if dc.isActionable(driver, entry) {
 	if dc.isActionable(driver, entry) {
 
 
-		if debugMode >= 2 {
+		if debugMode {
 			fmt.Printf("\tLigature - Perform action with %d\n", dc.matchLength)
 			fmt.Printf("\tLigature - Perform action with %d\n", dc.matchLength)
 		}
 		}
 
 
@@ -946,14 +983,14 @@ func (dc *driverContextLigature) transition(driver stateTableDriver, entry table
 		for do := true; do; do = action&tables.MLActionLast == 0 {
 		for do := true; do; do = action&tables.MLActionLast == 0 {
 			if cursor == 0 {
 			if cursor == 0 {
 				/* Stack underflow.  Clear the stack. */
 				/* Stack underflow.  Clear the stack. */
-				if debugMode >= 2 {
+				if debugMode {
 					fmt.Println("\tLigature - Stack underflow")
 					fmt.Println("\tLigature - Stack underflow")
 				}
 				}
 				dc.matchLength = 0
 				dc.matchLength = 0
 				break
 				break
 			}
 			}
 
 
-			if debugMode >= 2 {
+			if debugMode {
 				fmt.Printf("\tLigature - Moving to stack position %d\n", cursor-1)
 				fmt.Printf("\tLigature - Moving to stack position %d\n", cursor-1)
 			}
 			}
 
 
@@ -977,7 +1014,7 @@ func (dc *driverContextLigature) transition(driver stateTableDriver, entry table
 			componentData := dc.table.Components[componentIdx]
 			componentData := dc.table.Components[componentIdx]
 			ligatureIdx += int(componentData)
 			ligatureIdx += int(componentData)
 
 
-			if debugMode >= 2 {
+			if debugMode {
 				fmt.Printf("\tLigature - Action store %d last %d\n", action&tables.MLActionStore, action&tables.MLActionLast)
 				fmt.Printf("\tLigature - Action store %d last %d\n", action&tables.MLActionStore, action&tables.MLActionLast)
 			}
 			}
 
 
@@ -987,7 +1024,7 @@ func (dc *driverContextLigature) transition(driver stateTableDriver, entry table
 				}
 				}
 				lig := dc.table.Ligatures[ligatureIdx]
 				lig := dc.table.Ligatures[ligatureIdx]
 
 
-				if debugMode >= 2 {
+				if debugMode {
 					fmt.Printf("\tLigature - Produced ligature %d\n", lig)
 					fmt.Printf("\tLigature - Produced ligature %d\n", lig)
 				}
 				}
 
 
@@ -997,7 +1034,7 @@ func (dc *driverContextLigature) transition(driver stateTableDriver, entry table
 				/* Now go and delete all subsequent components. */
 				/* Now go and delete all subsequent components. */
 				for dc.matchLength-1 > cursor {
 				for dc.matchLength-1 > cursor {
 
 
-					if debugMode >= 2 {
+					if debugMode {
 						fmt.Println("\tLigature - Skipping ligature component")
 						fmt.Println("\tLigature - Skipping ligature component")
 					}
 					}
 
 
@@ -1171,6 +1208,46 @@ func (dc *driverContextInsertion) transition(driver stateTableDriver, entry tabl
 	}
 	}
 }
 }
 
 
+func (c *aatApplyContext) applyNonContextualSubtable(data font.MorxNonContextualSubtable) bool {
+	var ret bool
+	gdef := c.gdefTable
+	hasGlyphClass := gdef.GlyphClassDef != nil
+	info := c.buffer.Info
+	// If there's only one range, we already checked the flag.
+	var lastRange int = -1 // index in ac.rangeFlags, or -1
+	if len(c.rangeFlags) > 1 {
+		lastRange = 0
+	}
+	for i := range info {
+		// This block is copied in NoncontextualSubtable::apply. Keep in sync.
+		if lastRange != -1 {
+			range_ := lastRange
+			cluster := info[i].Cluster
+			for cluster < c.rangeFlags[range_].clusterFirst {
+				range_--
+			}
+			for cluster > c.rangeFlags[range_].clusterLast {
+				range_++
+			}
+
+			lastRange = range_
+			if c.rangeFlags[range_].flags&c.subtableFlags == 0 {
+				continue
+			}
+		}
+
+		replacement, has := data.Class.Class(gID(info[i].Glyph))
+		if has {
+			info[i].Glyph = GID(replacement)
+			if hasGlyphClass {
+				info[i].glyphProps = gdef.GlyphProps(gID(replacement))
+			}
+			ret = true
+		}
+	}
+	return ret
+}
+
 ///////
 ///////
 
 
 type aatFeatureMapping struct {
 type aatFeatureMapping struct {
@@ -1198,11 +1275,20 @@ func aatLayoutFindFeatureMapping(tag font.Tag) *aatFeatureMapping {
 	return nil
 	return nil
 }
 }
 
 
-func (sp *otShapePlan) aatLayoutSubstitute(font *Font, buffer *Buffer) {
+func (sp *otShapePlan) aatLayoutSubstitute(font *Font, buffer *Buffer, features []Feature) {
 	morx := font.face.Morx
 	morx := font.face.Morx
+	builder := newAatMapBuilder(font.face.Font, sp.props)
+	for _, feature := range features {
+		builder.addFeature(feature)
+	}
+	var map_ aatMap
+	builder.compile(&map_)
+
 	c := newAatApplyContext(sp, font, buffer)
 	c := newAatApplyContext(sp, font, buffer)
+	c.buffer.unsafeToConcat(0, maxInt)
 	for i, chain := range morx {
 	for i, chain := range morx {
-		c.applyMorx(chain, c.plan.aatMap.chainFlags[i])
+		c.rangeFlags = map_.chainFlags[i]
+		c.applyMorx(chain)
 	}
 	}
 	// NOTE: we dont support obsolete 'mort' table
 	// NOTE: we dont support obsolete 'mort' table
 }
 }
@@ -1216,10 +1302,8 @@ func aatLayoutZeroWidthDeletedGlyphs(buffer *Buffer) {
 	}
 	}
 }
 }
 
 
-func aatLayoutRemoveDeletedGlyphsInplace(buffer *Buffer) {
-	otLayoutDeleteGlyphsInplace(buffer, func(info *GlyphInfo) bool {
-		return info.Glyph == 0xFFFF
-	})
+func aatLayoutRemoveDeletedGlyphs(buffer *Buffer) {
+	buffer.deleteGlyphsInplace(func(info *GlyphInfo) bool { return info.Glyph == 0xFFFF })
 }
 }
 
 
 func (sp *otShapePlan) aatLayoutPosition(font *Font, buffer *Buffer) {
 func (sp *otShapePlan) aatLayoutPosition(font *Font, buffer *Buffer) {
@@ -1233,6 +1317,7 @@ func (sp *otShapePlan) aatLayoutPosition(font *Font, buffer *Buffer) {
 func (c *aatApplyContext) applyKernx(kerx font.Kernx) {
 func (c *aatApplyContext) applyKernx(kerx font.Kernx) {
 	var ret, seenCrossStream bool
 	var ret, seenCrossStream bool
 
 
+	c.buffer.unsafeToConcat(0, maxInt)
 	for i, st := range kerx {
 	for i, st := range kerx {
 		var reverse bool
 		var reverse bool
 
 
@@ -1245,7 +1330,7 @@ func (c *aatApplyContext) applyKernx(kerx font.Kernx) {
 		}
 		}
 		reverse = st.IsBackwards() != c.buffer.Props.Direction.isBackward()
 		reverse = st.IsBackwards() != c.buffer.Props.Direction.isBackward()
 
 
-		if debugMode >= 2 {
+		if debugMode {
 			fmt.Printf("AAT kerx : start subtable %d\n", i)
 			fmt.Printf("AAT kerx : start subtable %d\n", i)
 		}
 		}
 
 
@@ -1277,7 +1362,7 @@ func (c *aatApplyContext) applyKernx(kerx font.Kernx) {
 			c.buffer.Reverse()
 			c.buffer.Reverse()
 		}
 		}
 
 
-		if debugMode >= 2 {
+		if debugMode {
 			fmt.Printf("AAT kerx : end subtable %d\n", i)
 			fmt.Printf("AAT kerx : end subtable %d\n", i)
 			fmt.Println(c.buffer.Pos)
 			fmt.Println(c.buffer.Pos)
 		}
 		}
@@ -1286,7 +1371,7 @@ func (c *aatApplyContext) applyKernx(kerx font.Kernx) {
 }
 }
 
 
 func (c *aatApplyContext) applyKerxSubtable(st font.KernSubtable) bool {
 func (c *aatApplyContext) applyKerxSubtable(st font.KernSubtable) bool {
-	if debugMode >= 2 {
+	if debugMode {
 		fmt.Printf("\tKERNX table %T\n", st.Data)
 		fmt.Printf("\tKERNX table %T\n", st.Data)
 	}
 	}
 	switch data := st.Data.(type) {
 	switch data := st.Data.(type) {
@@ -1305,7 +1390,7 @@ func (c *aatApplyContext) applyKerxSubtable(st font.KernSubtable) bool {
 		}
 		}
 		dc := driverContextKerx1{c: c, table: data, crossStream: crossStream}
 		dc := driverContextKerx1{c: c, table: data, crossStream: crossStream}
 		driver := newStateTableDriver(data.Machine, c.buffer, c.face)
 		driver := newStateTableDriver(data.Machine, c.buffer, c.face)
-		driver.drive(&dc)
+		driver.drive(&dc, c)
 	case font.Kern2:
 	case font.Kern2:
 		if !c.plan.requestedKerning {
 		if !c.plan.requestedKerning {
 			return false
 			return false
@@ -1329,7 +1414,7 @@ func (c *aatApplyContext) applyKerxSubtable(st font.KernSubtable) bool {
 		}
 		}
 		dc := driverContextKerx4{c: c, table: data, actionType: data.ActionType()}
 		dc := driverContextKerx4{c: c, table: data, actionType: data.ActionType()}
 		driver := newStateTableDriver(data.Machine, c.buffer, c.face)
 		driver := newStateTableDriver(data.Machine, c.buffer, c.face)
-		driver.drive(&dc)
+		driver.drive(&dc, c)
 	case font.Kern6:
 	case font.Kern6:
 		if !c.plan.requestedKerning {
 		if !c.plan.requestedKerning {
 			return false
 			return false

+ 170 - 39
vendor/github.com/go-text/typesetting/harfbuzz/ot_aat_map.go

@@ -9,8 +9,48 @@ import (
 
 
 // ported from harfbuzz/src/hb-aat-map.cc, hb-att-map.hh Copyright © 2018  Google, Inc. Behdad Esfahbod
 // ported from harfbuzz/src/hb-aat-map.cc, hb-att-map.hh Copyright © 2018  Google, Inc. Behdad Esfahbod
 
 
+type rangeFlags struct {
+	flags        GlyphMask
+	clusterFirst int
+	clusterLast  int // end - 1
+}
+
 type aatMap struct {
 type aatMap struct {
-	chainFlags []GlyphMask
+	chainFlags [][]rangeFlags
+}
+
+func (map_ *aatMap) resizeChainFlags(N int) {
+	if cap(map_.chainFlags) >= N {
+		map_.chainFlags = map_.chainFlags[0:N]
+	} else {
+		map_.chainFlags = make([][]rangeFlags, N)
+	}
+}
+
+type aatFeatureRange struct {
+	info       aatFeatureInfo
+	start, end int
+}
+
+type aatFeatureEvent struct {
+	index   int
+	start   bool
+	feature aatFeatureInfo
+}
+
+func (a aatFeatureEvent) isLess(b aatFeatureEvent) bool {
+	if a.index < b.index {
+		return true
+	} else if a.index > b.index {
+		return false
+	} else {
+		if !a.start && b.start {
+			return true
+		} else if a.start && !b.start {
+			return false
+		}
+		return a.feature.isLess(b.feature)
+	}
 }
 }
 
 
 type aatFeatureInfo struct {
 type aatFeatureInfo struct {
@@ -25,7 +65,7 @@ func (fi aatFeatureInfo) key() uint32 {
 
 
 const selMask = ^aatLayoutFeatureSelector(1)
 const selMask = ^aatLayoutFeatureSelector(1)
 
 
-func cmpAATFeatureInfo(a, b aatFeatureInfo) bool {
+func (a aatFeatureInfo) isLess(b aatFeatureInfo) bool {
 	if a.type_ != b.type_ {
 	if a.type_ != b.type_ {
 		return a.type_ < b.type_
 		return a.type_ < b.type_
 	}
 	}
@@ -36,16 +76,30 @@ func cmpAATFeatureInfo(a, b aatFeatureInfo) bool {
 }
 }
 
 
 type aatMapBuilder struct {
 type aatMapBuilder struct {
-	tables   *font.Font
-	features []aatFeatureInfo // sorted by (type_, setting) after compilation
+	tables *font.Font
+	props  SegmentProperties
+
+	features        []aatFeatureRange
+	currentFeatures []aatFeatureInfo // sorted by (type_, setting) after compilation
+	rangeFirst      int
+	rangeLast       int
+}
+
+func newAatMapBuilder(tables *font.Font, props SegmentProperties) aatMapBuilder {
+	return aatMapBuilder{
+		tables:     tables,
+		props:      props,
+		rangeFirst: FeatureGlobalStart,
+		rangeLast:  FeatureGlobalEnd,
+	}
 }
 }
 
 
-// binary search into `features`, comparing type_ and setting only
+// binary search into `currentFeatures`, comparing type_ and setting only
 func (mb *aatMapBuilder) hasFeature(info aatFeatureInfo) bool {
 func (mb *aatMapBuilder) hasFeature(info aatFeatureInfo) bool {
 	key := info.key()
 	key := info.key()
-	for i, j := 0, len(mb.features); i < j; {
+	for i, j := 0, len(mb.currentFeatures); i < j; {
 		h := i + (j-i)/2
 		h := i + (j-i)/2
-		entry := mb.features[h].key()
+		entry := mb.currentFeatures[h].key()
 		if key < entry {
 		if key < entry {
 			j = h
 			j = h
 		} else if entry < key {
 		} else if entry < key {
@@ -59,8 +113,13 @@ func (mb *aatMapBuilder) hasFeature(info aatFeatureInfo) bool {
 
 
 func (mb *aatMapBuilder) compileMap(map_ *aatMap) {
 func (mb *aatMapBuilder) compileMap(map_ *aatMap) {
 	morx := mb.tables.Morx
 	morx := mb.tables.Morx
-	for _, chain := range morx {
-		map_.chainFlags = append(map_.chainFlags, mb.compileMorxFlag(chain))
+	map_.resizeChainFlags(len(morx))
+	for i, chain := range morx {
+		map_.chainFlags[i] = append(map_.chainFlags[i], rangeFlags{
+			flags:        mb.compileMorxFlag(chain),
+			clusterFirst: mb.rangeFirst,
+			clusterLast:  mb.rangeLast,
+		})
 	}
 	}
 
 
 	// TODO: for now we dont support deprecated mort table
 	// TODO: for now we dont support deprecated mort table
@@ -89,44 +148,51 @@ func (mb *aatMapBuilder) compileMorxFlag(chain font.MorxChain) GlyphMask {
 			type_ = aatLayoutFeatureTypeLowerCase
 			type_ = aatLayoutFeatureTypeLowerCase
 			setting = aatLayoutFeatureSelectorLowerCaseSmallCaps
 			setting = aatLayoutFeatureSelectorLowerCaseSmallCaps
 			goto retry
 			goto retry
+		} else if type_ == aatLayoutFeatureTypeLanguageTagType && setting != 0 && langMatches(string(mb.tables.Ltag.Language(setting-1)), string(mb.props.Language)) {
+			flags &= feature.DisableFlags
+			flags |= feature.EnableFlags
 		}
 		}
 	}
 	}
 	return flags
 	return flags
 }
 }
 
 
-func (mb *aatMapBuilder) addFeature(tag loader.Tag, value uint32) {
+func (mb *aatMapBuilder) addFeature(feature Feature) {
 	feat := mb.tables.Feat
 	feat := mb.tables.Feat
 	if len(feat.Names) == 0 {
 	if len(feat.Names) == 0 {
 		return
 		return
 	}
 	}
 
 
-	if tag == loader.NewTag('a', 'a', 'l', 't') {
+	if feature.Tag == loader.NewTag('a', 'a', 'l', 't') {
 		if fn := feat.GetFeature(aatLayoutFeatureTypeCharacterAlternatives); fn == nil || len(fn.SettingTable) == 0 {
 		if fn := feat.GetFeature(aatLayoutFeatureTypeCharacterAlternatives); fn == nil || len(fn.SettingTable) == 0 {
 			return
 			return
 		}
 		}
-		info := aatFeatureInfo{
-			type_:       aatLayoutFeatureTypeCharacterAlternatives,
-			setting:     aatLayoutFeatureSelector(value),
-			isExclusive: true,
+		range_ := aatFeatureRange{
+			info: aatFeatureInfo{
+				type_:       aatLayoutFeatureTypeCharacterAlternatives,
+				setting:     aatLayoutFeatureSelector(feature.Value),
+				isExclusive: true,
+			},
+			start: feature.Start,
+			end:   feature.End,
 		}
 		}
-		mb.features = append(mb.features, info)
+		mb.features = append(mb.features, range_)
 		return
 		return
 	}
 	}
 
 
-	mapping := aatLayoutFindFeatureMapping(tag)
+	mapping := aatLayoutFindFeatureMapping(feature.Tag)
 	if mapping == nil {
 	if mapping == nil {
 		return
 		return
 	}
 	}
 
 
-	feature := feat.GetFeature(mapping.aatFeatureType)
-	if feature == nil || len(feature.SettingTable) == 0 {
+	featureName := feat.GetFeature(mapping.aatFeatureType)
+	if featureName == nil || len(featureName.SettingTable) == 0 {
 		/* Special case: compileMorxFlag() will fall back to the deprecated version of
 		/* Special case: compileMorxFlag() will fall back to the deprecated version of
 		 * small-caps if necessary, so we need to check for that possibility.
 		 * small-caps if necessary, so we need to check for that possibility.
 		 * https://github.com/harfbuzz/harfbuzz/issues/2307 */
 		 * https://github.com/harfbuzz/harfbuzz/issues/2307 */
 		if mapping.aatFeatureType == aatLayoutFeatureTypeLowerCase &&
 		if mapping.aatFeatureType == aatLayoutFeatureTypeLowerCase &&
 			mapping.selectorToEnable == aatLayoutFeatureSelectorLowerCaseSmallCaps {
 			mapping.selectorToEnable == aatLayoutFeatureSelectorLowerCaseSmallCaps {
-			feature = feat.GetFeature(aatLayoutFeatureTypeLetterCase)
-			if feature == nil || len(feature.SettingTable) == 0 {
+			featureName = feat.GetFeature(aatLayoutFeatureTypeLetterCase)
+			if featureName == nil || len(featureName.SettingTable) == 0 {
 				return
 				return
 			}
 			}
 		} else {
 		} else {
@@ -136,34 +202,99 @@ func (mb *aatMapBuilder) addFeature(tag loader.Tag, value uint32) {
 
 
 	var info aatFeatureInfo
 	var info aatFeatureInfo
 	info.type_ = mapping.aatFeatureType
 	info.type_ = mapping.aatFeatureType
-	if value != 0 {
+	if feature.Value != 0 {
 		info.setting = mapping.selectorToEnable
 		info.setting = mapping.selectorToEnable
 	} else {
 	} else {
 		info.setting = mapping.selectorToDisable
 		info.setting = mapping.selectorToDisable
 	}
 	}
-	info.isExclusive = feature.IsExclusive()
-	mb.features = append(mb.features, info)
+	info.isExclusive = featureName.IsExclusive()
+	mb.features = append(mb.features, aatFeatureRange{
+		info:  info,
+		start: feature.Start,
+		end:   feature.End,
+	})
 }
 }
 
 
 func (mb *aatMapBuilder) compile(m *aatMap) {
 func (mb *aatMapBuilder) compile(m *aatMap) {
-	// sort features and merge duplicates
-	if len(mb.features) != 0 {
-		sort.SliceStable(mb.features, func(i, j int) bool {
-			return cmpAATFeatureInfo(mb.features[i], mb.features[j])
+	// Compute active features per range, and compile each.
+
+	// Sort features by start/end events.
+	var featureEvents []aatFeatureEvent
+	for _, feature := range mb.features {
+		if feature.start == feature.end {
+			continue
+		}
+
+		featureEvents = append(featureEvents, aatFeatureEvent{
+			index:   feature.start,
+			start:   true,
+			feature: feature.info,
+		}, aatFeatureEvent{
+			index:   feature.end,
+			start:   false,
+			feature: feature.info,
 		})
 		})
-		j := 0
-		for i := 1; i < len(mb.features); i++ {
-			/* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off
-			* respectively, so we mask out the low-order bit when checking for "duplicates"
-			* (selectors referring to the same feature setting) here. */
-			if mb.features[i].type_ != mb.features[j].type_ ||
-				(!mb.features[i].isExclusive && ((mb.features[i].setting & selMask) != (mb.features[j].setting & selMask))) {
-				j++
-				mb.features[j] = mb.features[i]
+	}
+	sort.SliceStable(featureEvents, func(i, j int) bool { return featureEvents[i].isLess(featureEvents[j]) })
+
+	// Add a strategic final event.
+	{
+		featureEvents = append(featureEvents, aatFeatureEvent{
+			index:   -1, /* This value does magic. */
+			start:   false,
+			feature: aatFeatureInfo{},
+		})
+	}
+
+	// Scan events and save features for each range.
+	var activeFeatures []aatFeatureInfo
+	lastIndex := 0
+	for _, event := range featureEvents {
+		if event.index != lastIndex {
+			// Save a snapshot of active features and the range.
+
+			// sort features and merge duplicates
+			mb.currentFeatures = activeFeatures
+			mb.rangeFirst = lastIndex
+			mb.rangeLast = event.index - 1
+			if len(mb.currentFeatures) != 0 {
+				sort.SliceStable(mb.currentFeatures, func(i, j int) bool {
+					return mb.currentFeatures[i].isLess(mb.currentFeatures[j])
+				})
+				j := 0
+				for i := 1; i < len(mb.currentFeatures); i++ {
+					/* Nonexclusive feature selectors come in even/odd pairs to turn a setting on/off
+					* respectively, so we mask out the low-order bit when checking for "duplicates"
+					* (selectors referring to the same feature setting) here. */
+					if mb.currentFeatures[i].type_ != mb.currentFeatures[j].type_ ||
+						(!mb.currentFeatures[i].isExclusive && ((mb.currentFeatures[i].setting & selMask) != (mb.currentFeatures[j].setting & selMask))) {
+						j++
+						mb.currentFeatures[j] = mb.currentFeatures[i]
+					}
+				}
+				mb.currentFeatures = mb.currentFeatures[:j+1]
+			}
+
+			mb.compileMap(m)
+
+			lastIndex = event.index
+		}
+
+		if event.start {
+			activeFeatures = append(activeFeatures, event.feature)
+		} else {
+			for i, f := range activeFeatures {
+				if f.key() == event.feature.key() {
+					// remove the item
+					activeFeatures = append(activeFeatures[:i], activeFeatures[i+1:]...)
+					break
+				}
 			}
 			}
 		}
 		}
-		mb.features = mb.features[:j+1]
 	}
 	}
 
 
-	mb.compileMap(m)
+	for _, chainFlags := range m.chainFlags {
+		// With our above setup this value is one less than desired; adjust it.
+		chainFlags[len(chainFlags)-1].clusterLast = FeatureGlobalEnd
+	}
 }
 }

+ 126 - 62
vendor/github.com/go-text/typesetting/harfbuzz/ot_arabic.go

@@ -8,14 +8,13 @@ import (
 	"github.com/go-text/typesetting/opentype/api/font"
 	"github.com/go-text/typesetting/opentype/api/font"
 	"github.com/go-text/typesetting/opentype/loader"
 	"github.com/go-text/typesetting/opentype/loader"
 	"github.com/go-text/typesetting/opentype/tables"
 	"github.com/go-text/typesetting/opentype/tables"
-	ucd "github.com/go-text/typesetting/unicodedata"
 )
 )
 
 
 // ported from harfbuzz/src/hb-ot-shape-complex-arabic.cc, hb-ot-shape-complex-arabic-fallback.hh Copyright © 2010,2012  Google, Inc. Behdad Esfahbod
 // ported from harfbuzz/src/hb-ot-shape-complex-arabic.cc, hb-ot-shape-complex-arabic-fallback.hh Copyright © 2010,2012  Google, Inc. Behdad Esfahbod
 
 
 var _ otComplexShaper = (*complexShaperArabic)(nil)
 var _ otComplexShaper = (*complexShaperArabic)(nil)
 
 
-const flagArabicHasStch = bsfComplex0
+const flagArabicHasStch = bsfShaper0
 
 
 /* See:
 /* See:
  * https://github.com/harfbuzz/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */
  * https://github.com/harfbuzz/harfbuzz/commit/6e6f82b6f3dde0fc6c3c7d991d9ec6cfff57823d#commitcomment-14248516 */
@@ -44,6 +43,22 @@ func isWord(genCat generalCategory) bool {
  * Joining types:
  * Joining types:
  */
  */
 
 
+// arabicJoining is a property used to shape Arabic runes.
+// See the table arabicJoinings.
+type arabicJoining byte
+
+const (
+	ajU          arabicJoining = 'U' // Un-joining, e.g. Full Stop
+	ajR          arabicJoining = 'R' // Right-joining, e.g. Arabic Letter Dal
+	ajAlaph      arabicJoining = 'a' // Alaph group (included in kind R)
+	ajDalathRish arabicJoining = 'd' // Dalat Rish group (included in kind R)
+	ajD          arabicJoining = 'D' // Dual-joining, e.g. Arabic Letter Ain
+	ajC          arabicJoining = 'C' // Join-Causing, e.g. Tatweel, ZWJ
+	ajL          arabicJoining = 'L' // Left-joining, i.e. fictional
+	ajT          arabicJoining = 'T' // Transparent, e.g. Arabic Fatha
+	ajG          arabicJoining = 'G' // Ignored, e.g. LRE, RLE, ZWNBSP
+)
+
 // index into arabicStateTable
 // index into arabicStateTable
 const (
 const (
 	joiningTypeU = iota
 	joiningTypeU = iota
@@ -58,23 +73,23 @@ const (
 )
 )
 
 
 func getJoiningType(u rune, genCat generalCategory) uint8 {
 func getJoiningType(u rune, genCat generalCategory) uint8 {
-	if jType, ok := ucd.ArabicJoinings[u]; ok {
+	if jType, ok := arabicJoinings[u]; ok {
 		switch jType {
 		switch jType {
-		case ucd.U:
+		case ajU:
 			return joiningTypeU
 			return joiningTypeU
-		case ucd.L:
+		case ajL:
 			return joiningTypeL
 			return joiningTypeL
-		case ucd.R:
+		case ajR:
 			return joiningTypeR
 			return joiningTypeR
-		case ucd.D:
+		case ajD:
 			return joiningTypeD
 			return joiningTypeD
-		case ucd.Alaph:
+		case ajAlaph:
 			return joiningGroupAlaph
 			return joiningGroupAlaph
-		case ucd.DalathRish:
+		case ajDalathRish:
 			return joiningGroupDalathRish
 			return joiningGroupDalathRish
-		case ucd.T:
+		case ajT:
 			return joiningTypeT
 			return joiningTypeT
-		case ucd.C:
+		case ajC:
 			return joiningTypeC
 			return joiningTypeC
 		}
 		}
 	}
 	}
@@ -98,7 +113,6 @@ var arabicFeatures = [...]loader.Tag{
 	loader.NewTag('m', 'e', 'd', 'i'),
 	loader.NewTag('m', 'e', 'd', 'i'),
 	loader.NewTag('m', 'e', 'd', '2'),
 	loader.NewTag('m', 'e', 'd', '2'),
 	loader.NewTag('i', 'n', 'i', 't'),
 	loader.NewTag('i', 'n', 'i', 't'),
-	0,
 }
 }
 
 
 /* Same order as the feature array */
 /* Same order as the feature array */
@@ -181,16 +195,13 @@ func (cs *complexShaperArabic) collectFeatures(plan *otShapePlanner) {
 	* work.  However, testing shows that rlig and calt are applied
 	* work.  However, testing shows that rlig and calt are applied
 	* together for Mongolian in Uniscribe.  As such, we only add a
 	* together for Mongolian in Uniscribe.  As such, we only add a
 	* pause for Arabic, not other scripts.
 	* pause for Arabic, not other scripts.
-	*
-	* A pause after calt is required to make KFGQPC Uthmanic Script HAFS
-	* work correctly.  See https://github.com/harfbuzz/harfbuzz/issues/505
 	 */
 	 */
 
 
 	map_.enableFeature(loader.NewTag('s', 't', 'c', 'h'))
 	map_.enableFeature(loader.NewTag('s', 't', 'c', 'h'))
 	map_.addGSUBPause(recordStch)
 	map_.addGSUBPause(recordStch)
 
 
-	map_.enableFeature(loader.NewTag('c', 'c', 'm', 'p'))
-	map_.enableFeature(loader.NewTag('l', 'o', 'c', 'l'))
+	map_.enableFeatureExt(loader.NewTag('c', 'c', 'm', 'p'), ffManualZWJ, 1)
+	map_.enableFeatureExt(loader.NewTag('l', 'o', 'c', 'l'), ffManualZWJ, 1)
 
 
 	map_.addGSUBPause(nil)
 	map_.addGSUBPause(nil)
 
 
@@ -200,7 +211,7 @@ func (cs *complexShaperArabic) collectFeatures(plan *otShapePlanner) {
 		if hasFallback {
 		if hasFallback {
 			fl = ffHasFallback
 			fl = ffHasFallback
 		}
 		}
-		map_.addFeatureExt(arabFeat, fl, 1)
+		map_.addFeatureExt(arabFeat, ffManualZWJ|fl, 1)
 		map_.addGSUBPause(nil)
 		map_.addGSUBPause(nil)
 	}
 	}
 
 
@@ -213,10 +224,15 @@ func (cs *complexShaperArabic) collectFeatures(plan *otShapePlanner) {
 	if plan.props.Script == language.Arabic {
 	if plan.props.Script == language.Arabic {
 		map_.addGSUBPause(arabicFallbackShape)
 		map_.addGSUBPause(arabicFallbackShape)
 	}
 	}
-	/* No pause after rclt.  See 98460779bae19e4d64d29461ff154b3527bf8420. */
-	map_.enableFeatureExt(loader.NewTag('r', 'c', 'l', 't'), ffManualZWJ, 1)
 	map_.enableFeatureExt(loader.NewTag('c', 'a', 'l', 't'), ffManualZWJ, 1)
 	map_.enableFeatureExt(loader.NewTag('c', 'a', 'l', 't'), ffManualZWJ, 1)
-	map_.addGSUBPause(nil)
+	/* https://github.com/harfbuzz/harfbuzz/issues/1573 */
+	if !map_.hasFeature(loader.NewTag('r', 'c', 'l', 't')) {
+		map_.addGSUBPause(nil)
+		map_.enableFeatureExt(loader.NewTag('r', 'c', 'l', 't'), ffManualZWJ, 1)
+	}
+
+	map_.enableFeatureExt(loader.NewTag('l', 'i', 'g', 'a'), ffManualZWJ, 1)
+	map_.enableFeatureExt(loader.NewTag('c', 'l', 'i', 'g'), ffManualZWJ, 1)
 
 
 	/* The spec includes 'cswh'.  Earlier versions of Windows
 	/* The spec includes 'cswh'.  Earlier versions of Windows
 	* used to enable this by default, but testing suggests
 	* used to enable this by default, but testing suggests
@@ -227,7 +243,7 @@ func (cs *complexShaperArabic) collectFeatures(plan *otShapePlanner) {
 	* to fixup broken glyph sequences.  Oh well...
 	* to fixup broken glyph sequences.  Oh well...
 	* Test case: U+0643,U+0640,U+0631. */
 	* Test case: U+0643,U+0640,U+0631. */
 	//map_.enable_feature (newTag('c','s','w','h'));
 	//map_.enable_feature (newTag('c','s','w','h'));
-	map_.enableFeature(loader.NewTag('m', 's', 'e', 't'))
+	map_.enableFeatureExt(loader.NewTag('m', 's', 'e', 't'), ffManualZWJ, 1)
 }
 }
 
 
 type arabicShapePlan struct {
 type arabicShapePlan struct {
@@ -258,7 +274,7 @@ func (cs *complexShaperArabic) dataCreate(plan *otShapePlan) {
 	cs.plan = newArabicPlan(plan)
 	cs.plan = newArabicPlan(plan)
 }
 }
 
 
-func arabicJoining(buffer *Buffer) {
+func applyArabicJoining(buffer *Buffer) {
 	info := buffer.Info
 	info := buffer.Info
 	prev, state := -1, uint16(0)
 	prev, state := -1, uint16(0)
 
 
@@ -287,7 +303,18 @@ func arabicJoining(buffer *Buffer) {
 
 
 		if entry.prevAction != arabNone && prev != -1 {
 		if entry.prevAction != arabNone && prev != -1 {
 			info[prev].complexAux = entry.prevAction
 			info[prev].complexAux = entry.prevAction
-			buffer.unsafeToBreak(prev, i+1)
+			buffer.safeToInsertTatweel(prev, i+1)
+		} else {
+			if prev == -1 {
+				if thisType >= joiningTypeR {
+					buffer.unsafeToConcatFromOutbuffer(0, i+1)
+				}
+			} else {
+				if thisType >= joiningTypeR ||
+					(2 <= state && state <= 5) /* States that have a possible prevAction. */ {
+					buffer.unsafeToConcat(prev, i+1)
+				}
+			}
 		}
 		}
 
 
 		info[i].complexAux = entry.currAction
 		info[i].complexAux = entry.currAction
@@ -306,6 +333,9 @@ func arabicJoining(buffer *Buffer) {
 		entry := &arabicStateTable[state][thisType]
 		entry := &arabicStateTable[state][thisType]
 		if entry.prevAction != arabNone && prev != -1 {
 		if entry.prevAction != arabNone && prev != -1 {
 			info[prev].complexAux = entry.prevAction
 			info[prev].complexAux = entry.prevAction
+			buffer.safeToInsertTatweel(prev, len(buffer.Info))
+		} else if 2 <= state && state <= 5 /* States that have a possible prevAction. */ {
+			buffer.unsafeToConcat(prev, len(buffer.Info))
 		}
 		}
 		break
 		break
 	}
 	}
@@ -322,7 +352,7 @@ func mongolianVariationSelectors(buffer *Buffer) {
 }
 }
 
 
 func (arabicPlan arabicShapePlan) setupMasks(buffer *Buffer, script language.Script) {
 func (arabicPlan arabicShapePlan) setupMasks(buffer *Buffer, script language.Script) {
-	arabicJoining(buffer)
+	applyArabicJoining(buffer)
 	if script == language.Mongolian {
 	if script == language.Mongolian {
 		mongolianVariationSelectors(buffer)
 		mongolianVariationSelectors(buffer)
 	}
 	}
@@ -337,11 +367,11 @@ func (cs *complexShaperArabic) setupMasks(plan *otShapePlan, buffer *Buffer, _ *
 	cs.plan.setupMasks(buffer, plan.props.Script)
 	cs.plan.setupMasks(buffer, plan.props.Script)
 }
 }
 
 
-func arabicFallbackShape(plan *otShapePlan, font *Font, buffer *Buffer) {
+func arabicFallbackShape(plan *otShapePlan, font *Font, buffer *Buffer) bool {
 	arabicPlan := plan.shaper.(*complexShaperArabic).plan
 	arabicPlan := plan.shaper.(*complexShaperArabic).plan
 
 
 	if !arabicPlan.doFallback {
 	if !arabicPlan.doFallback {
-		return
+		return false
 	}
 	}
 
 
 	fallbackPlan := arabicPlan.fallbackPlan
 	fallbackPlan := arabicPlan.fallbackPlan
@@ -351,20 +381,21 @@ func arabicFallbackShape(plan *otShapePlan, font *Font, buffer *Buffer) {
 	}
 	}
 
 
 	fallbackPlan.shape(font, buffer)
 	fallbackPlan.shape(font, buffer)
+	return true
 }
 }
 
 
-//  /*
-//   * Stretch feature: "stch".
-//   * See example here:
-//   * https://docs.microsoft.com/en-us/typography/script-development/syriac
-//   * We implement this in a generic way, such that the Arabic subtending
-//   * marks can use it as well.
-//   */
+//
+//  Stretch feature: "stch".
+//  See example here:
+//  https://docs.microsoft.com/en-us/typography/script-development/syriac
+//  We implement this in a generic way, such that the Arabic subtending
+//  marks can use it as well.
+//
 
 
-func recordStch(plan *otShapePlan, _ *Font, buffer *Buffer) {
+func recordStch(plan *otShapePlan, _ *Font, buffer *Buffer) bool {
 	arabicPlan := plan.shaper.(*complexShaperArabic).plan
 	arabicPlan := plan.shaper.(*complexShaperArabic).plan
 	if !arabicPlan.hasStch {
 	if !arabicPlan.hasStch {
-		return
+		return false
 	}
 	}
 
 
 	/* 'stch' feature was just applied.  Look for anything that multiplied,
 	/* 'stch' feature was just applied.  Look for anything that multiplied,
@@ -384,6 +415,8 @@ func recordStch(plan *otShapePlan, _ *Font, buffer *Buffer) {
 			buffer.scratchFlags |= flagArabicHasStch
 			buffer.scratchFlags |= flagArabicHasStch
 		}
 		}
 	}
 	}
+
+	return false
 }
 }
 
 
 func inRange(sa uint8) bool {
 func inRange(sa uint8) bool {
@@ -459,7 +492,7 @@ func (cs *complexShaperArabic) postprocessGlyphs(plan *otShapePlan, buffer *Buff
 			}
 			}
 			i++ // Don't touch i again.
 			i++ // Don't touch i again.
 
 
-			if debugMode >= 1 {
+			if debugMode {
 				fmt.Printf("ARABIC - step %d: stretch at (%d,%d,%d)\n", step+1, context, start, end)
 				fmt.Printf("ARABIC - step %d: stretch at (%d,%d,%d)\n", step+1, context, start, end)
 				fmt.Printf("ARABIC - rest of word:    count=%d width %d\n", start-context, wTotal)
 				fmt.Printf("ARABIC - rest of word:    count=%d width %d\n", start-context, wTotal)
 				fmt.Printf("ARABIC - fixed tiles:     count=%d width=%d\n", nFixed, wFixed)
 				fmt.Printf("ARABIC - fixed tiles:     count=%d width=%d\n", nFixed, wFixed)
@@ -487,7 +520,7 @@ func (cs *complexShaperArabic) postprocessGlyphs(plan *otShapePlan, buffer *Buff
 
 
 			if step == MEASURE {
 			if step == MEASURE {
 				extraGlyphsNeeded += nCopies * nRepeating
 				extraGlyphsNeeded += nCopies * nRepeating
-				if debugMode >= 1 {
+				if debugMode {
 					fmt.Printf("ARABIC - will add extra %d copies of repeating tiles\n", nCopies)
 					fmt.Printf("ARABIC - will add extra %d copies of repeating tiles\n", nCopies)
 				}
 				}
 			} else {
 			} else {
@@ -501,7 +534,7 @@ func (cs *complexShaperArabic) postprocessGlyphs(plan *otShapePlan, buffer *Buff
 						repeat += nCopies
 						repeat += nCopies
 					}
 					}
 
 
-					if debugMode >= 1 {
+					if debugMode {
 						fmt.Printf("ARABIC - appending %d copies of glyph %d; j=%d\n", repeat, info[k-1].codepoint, j)
 						fmt.Printf("ARABIC - appending %d copies of glyph %d; j=%d\n", repeat, info[k-1].codepoint, j)
 					}
 					}
 					for n := 0; n < repeat; n++ {
 					for n := 0; n < repeat; n++ {
@@ -535,6 +568,11 @@ var modifierCombiningMarks = [...]rune{
 	0x06E3, /* ARABIC SMALL LOW SEEN */
 	0x06E3, /* ARABIC SMALL LOW SEEN */
 	0x06E7, /* ARABIC SMALL HIGH YEH */
 	0x06E7, /* ARABIC SMALL HIGH YEH */
 	0x06E8, /* ARABIC SMALL HIGH NOON */
 	0x06E8, /* ARABIC SMALL HIGH NOON */
+	0x08CA, /* ARABIC SMALL HIGH FARSI YEH */
+	0x08CB, /* ARABIC SMALL HIGH YEH BARREE WITH TWO DOTS BELOW */
+	0x08CD, /* ARABIC SMALL HIGH ZAH */
+	0x08CE, /* ARABIC LARGE ROUND DOT ABOVE */
+	0x08CF, /* ARABIC LARGE ROUND DOT BELOW */
 	0x08D3, /* ARABIC SMALL LOW WAW */
 	0x08D3, /* ARABIC SMALL LOW WAW */
 	0x08F3, /* ARABIC SMALL HIGH WAW */
 	0x08F3, /* ARABIC SMALL HIGH WAW */
 }
 }
@@ -552,19 +590,19 @@ func infoIsMcm(info *GlyphInfo) bool {
 func (cs *complexShaperArabic) reorderMarks(_ *otShapePlan, buffer *Buffer, start, end int) {
 func (cs *complexShaperArabic) reorderMarks(_ *otShapePlan, buffer *Buffer, start, end int) {
 	info := buffer.Info
 	info := buffer.Info
 
 
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Printf("ARABIC - Reordering marks from %d to %d\n", start, end)
 		fmt.Printf("ARABIC - Reordering marks from %d to %d\n", start, end)
 	}
 	}
 
 
 	i := start
 	i := start
 	for cc := uint8(220); cc <= 230; cc += 10 {
 	for cc := uint8(220); cc <= 230; cc += 10 {
-		if debugMode >= 1 {
-			fmt.Printf("ARABIC - Looking for %d's starting at %d\n", cc, i)
+		if debugMode {
+			fmt.Printf("ARABIC - Looking for combining class %d's starting at %d\n", cc, i)
 		}
 		}
 		for i < end && info[i].getModifiedCombiningClass() < cc {
 		for i < end && info[i].getModifiedCombiningClass() < cc {
 			i++
 			i++
 		}
 		}
-		if debugMode >= 1 {
+		if debugMode {
 			fmt.Printf("ARABIC - Looking for %d's stopped at %d\n", cc, i)
 			fmt.Printf("ARABIC - Looking for %d's stopped at %d\n", cc, i)
 		}
 		}
 
 
@@ -585,7 +623,7 @@ func (cs *complexShaperArabic) reorderMarks(_ *otShapePlan, buffer *Buffer, star
 			continue
 			continue
 		}
 		}
 
 
-		if debugMode >= 1 {
+		if debugMode {
 			fmt.Printf("ARABIC - Found %d's from %d to %d", cc, i, j)
 			fmt.Printf("ARABIC - Found %d's from %d to %d", cc, i, j)
 			// shift it!
 			// shift it!
 			fmt.Printf("ARABIC - Shifting %d's: %d %d", cc, i, j)
 			fmt.Printf("ARABIC - Shifting %d's: %d %d", cc, i, j)
@@ -623,13 +661,17 @@ func (cs *complexShaperArabic) reorderMarks(_ *otShapePlan, buffer *Buffer, star
 	}
 	}
 }
 }
 
 
-/* Features ordered the same as the entries in ucd.ArabicShaping rows,
- * followed by rlig.  Don't change. */
+// Features ordered the same as the entries in [arabicShaping] rows,
+// followed by rlig.  Don't change.
+// We currently support one subtable per lookup, and one lookup
+// per feature.  But we allow duplicate features, so we use that!
 var arabicFallbackFeatures = [...]loader.Tag{
 var arabicFallbackFeatures = [...]loader.Tag{
-	loader.NewTag('i', 's', 'o', 'l'),
-	loader.NewTag('f', 'i', 'n', 'a'),
 	loader.NewTag('i', 'n', 'i', 't'),
 	loader.NewTag('i', 'n', 'i', 't'),
 	loader.NewTag('m', 'e', 'd', 'i'),
 	loader.NewTag('m', 'e', 'd', 'i'),
+	loader.NewTag('f', 'i', 'n', 'a'),
+	loader.NewTag('i', 's', 'o', 'l'),
+	loader.NewTag('r', 'l', 'i', 'g'),
+	loader.NewTag('r', 'l', 'i', 'g'),
 	loader.NewTag('r', 'l', 'i', 'g'),
 	loader.NewTag('r', 'l', 'i', 'g'),
 }
 }
 
 
@@ -649,8 +691,8 @@ func arabicFallbackSynthesizeLookupSingle(ft *Font, featureIndex int) *lookupGSU
 	var glyphs, substitutes []gID
 	var glyphs, substitutes []gID
 
 
 	// populate arrays
 	// populate arrays
-	for u := rune(ucd.FirstArabicShape); u <= ucd.LastArabicShape; u++ {
-		s := rune(ucd.ArabicShaping[u-ucd.FirstArabicShape][featureIndex])
+	for u := rune(firstArabicShape); u <= lastArabicShape; u++ {
+		s := rune(arabicShaping[u-firstArabicShape][featureIndex])
 		uGlyph, hasU := ft.face.NominalGlyph(u)
 		uGlyph, hasU := ft.face.NominalGlyph(u)
 		sGlyph, hasS := ft.face.NominalGlyph(s)
 		sGlyph, hasS := ft.face.NominalGlyph(s)
 
 
@@ -692,16 +734,16 @@ func (a glyphsIndirections) Swap(i, j int) {
 }
 }
 func (a glyphsIndirections) Less(i, j int) bool { return a.glyphs[i] < a.glyphs[j] }
 func (a glyphsIndirections) Less(i, j int) bool { return a.glyphs[i] < a.glyphs[j] }
 
 
-func arabicFallbackSynthesizeLookupLigature(ft *Font) *lookupGSUB {
+func arabicFallbackSynthesizeLookupLigature(ft *Font, ligatureTable []arabicTableEntry, lookupFlags uint16) *lookupGSUB {
 	var (
 	var (
 		firstGlyphs            []gID
 		firstGlyphs            []gID
 		firstGlyphsIndirection []int // original index into ArabicLigatures
 		firstGlyphsIndirection []int // original index into ArabicLigatures
 	)
 	)
 
 
-	/* Populate arrays */
+	// Populate arrays
 
 
 	// sort out the first-glyphs
 	// sort out the first-glyphs
-	for firstGlyphIdx, lig := range ucd.ArabicLigatures {
+	for firstGlyphIdx, lig := range ligatureTable {
 		firstGlyph, ok := ft.face.NominalGlyph(lig.First)
 		firstGlyph, ok := ft.face.NominalGlyph(lig.First)
 		if !ok {
 		if !ok {
 			continue
 			continue
@@ -721,25 +763,39 @@ func arabicFallbackSynthesizeLookupLigature(ft *Font) *lookupGSUB {
 
 
 	// now that the first-glyphs are sorted, walk again, populate ligatures.
 	// now that the first-glyphs are sorted, walk again, populate ligatures.
 	for _, firstGlyphIdx := range firstGlyphsIndirection {
 	for _, firstGlyphIdx := range firstGlyphsIndirection {
-		ligs := ucd.ArabicLigatures[firstGlyphIdx].Ligatures
+		ligs := ligatureTable[firstGlyphIdx].Ligatures
 		var ligatureSet tables.LigatureSet
 		var ligatureSet tables.LigatureSet
 		for _, v := range ligs {
 		for _, v := range ligs {
-			secondU, ligatureU := v[0], v[1]
-			secondGlyph, hasSecond := ft.face.NominalGlyph(secondU)
+			ligatureU := v.ligature
 			ligatureGlyph, hasLigature := ft.face.NominalGlyph(ligatureU)
 			ligatureGlyph, hasLigature := ft.face.NominalGlyph(ligatureU)
-			if secondU == 0 || !hasSecond || !hasLigature {
+			if !hasLigature {
 				continue
 				continue
 			}
 			}
+
+			components := v.components
+			var componentGIDs []gID
+			for _, componentU := range components {
+				componentGlyph, hasComponent := ft.face.NominalGlyph(componentU)
+				if !hasComponent {
+					break
+				}
+				componentGIDs = append(componentGIDs, gID(componentGlyph))
+			}
+
+			if len(components) != len(componentGIDs) {
+				continue
+			}
+
 			ligatureSet.Ligatures = append(ligatureSet.Ligatures, tables.Ligature{
 			ligatureSet.Ligatures = append(ligatureSet.Ligatures, tables.Ligature{
 				LigatureGlyph:     gID(ligatureGlyph),
 				LigatureGlyph:     gID(ligatureGlyph),
-				ComponentGlyphIDs: []uint16{uint16(secondGlyph)}, // ligatures are 2-component
+				ComponentGlyphIDs: componentGIDs, // ligatures are 2-component
 			})
 			})
 		}
 		}
 		out.LigatureSets = append(out.LigatureSets, ligatureSet)
 		out.LigatureSets = append(out.LigatureSets, ligatureSet)
 	}
 	}
 
 
 	return &lookupGSUB{
 	return &lookupGSUB{
-		LookupOptions: font.LookupOptions{Flag: otIgnoreMarks},
+		LookupOptions: font.LookupOptions{Flag: lookupFlags},
 		Subtables: []tables.GSUBLookup{
 		Subtables: []tables.GSUBLookup{
 			out,
 			out,
 		},
 		},
@@ -747,13 +803,21 @@ func arabicFallbackSynthesizeLookupLigature(ft *Font) *lookupGSUB {
 }
 }
 
 
 func arabicFallbackSynthesizeLookup(font *Font, featureIndex int) *lookupGSUB {
 func arabicFallbackSynthesizeLookup(font *Font, featureIndex int) *lookupGSUB {
-	if featureIndex < 4 {
+	switch featureIndex {
+	case 0, 1, 2, 3:
 		return arabicFallbackSynthesizeLookupSingle(font, featureIndex)
 		return arabicFallbackSynthesizeLookupSingle(font, featureIndex)
+	case 4:
+		return arabicFallbackSynthesizeLookupLigature(font, arabicLigature3Table[:], otIgnoreMarks)
+	case 5:
+		return arabicFallbackSynthesizeLookupLigature(font, arabicLigatureTable[:], otIgnoreMarks)
+	case 6:
+		return arabicFallbackSynthesizeLookupLigature(font, arabicLigatureMarkTable[:], 0)
+	default:
+		panic("unexpected arabic fallback feature index")
 	}
 	}
-	return arabicFallbackSynthesizeLookupLigature(font)
 }
 }
 
 
-const arabicFallbackMaxLookups = 5
+const arabicFallbackMaxLookups = len(arabicFallbackFeatures)
 
 
 type arabicFallbackPlan struct {
 type arabicFallbackPlan struct {
 	accelArray [arabicFallbackMaxLookups]otLayoutLookupAccelerator
 	accelArray [arabicFallbackMaxLookups]otLayoutLookupAccelerator

+ 161 - 0
vendor/github.com/go-text/typesetting/harfbuzz/ot_arabic_pua_table.go

@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: Unlicense OR BSD-3-Clause
+
+package harfbuzz
+
+// Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
+
+// Legacy Simplified Arabic encoding. Returns 0 if not found.
+func arabicPUASimpMap(r rune) rune {
+	switch {
+	case 0x20 <= r && r <= 0x22:
+		return [...]rune{0xf120, 0xf121, 0xf122}[r-0x20]
+	case 0x25 == r:
+		return 0xf125
+	case 0x28 <= r && r <= 0x3b:
+		return [...]rune{0xf128, 0xf129, 0xf12a, 0xf12b, 0xf15e, 0xf12d, 0xf12e, 0xf12f, 0xf1b0, 0xf1b1, 0xf1b2, 0xf1b3, 0xf1b4, 0xf1b5, 0xf1b6, 0xf1b7, 0xf1b8, 0xf1b9, 0xf13a, 0xf13b}[r-0x28]
+	case 0x3d == r:
+		return 0xf13d
+	case 0x3f == r:
+		return 0xf13f
+	case 0x5b <= r && r <= 0x5d:
+		return [...]rune{0xf15b, 0xf15c, 0xf15d}[r-0x5b]
+	case 0xab == r:
+		return 0xf123
+	case 0xbb == r:
+		return 0xf124
+	case 0xd7 == r:
+		return 0xf126
+	case 0xf7 == r:
+		return 0xf127
+	case 0x60c == r:
+		return 0xf12c
+	case 0x61b == r:
+		return 0xf13b
+	case 0x61f == r:
+		return 0xf13f
+	case 0x621 <= r && r <= 0x65e:
+		return [...]rune{0xf1ad, 0xf145, 0xf143, 0xf1bb, 0xf147, 0xf1ba, 0xf141, 0xf14a, 0xf1a9, 0xf14c, 0xf14e, 0xf151, 0xf154, 0xf157, 0xf158, 0xf159, 0xf15a, 0xf160, 0xf162, 0xf164, 0xf166, 0xf168, 0xf169, 0xf16a, 0xf16e, 0xf172, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf15f, 0xf175, 0xf178, 0xf17a, 0xf17c, 0xf17e, 0xf1e1, 0xf1a4, 0xf1a5, 0xf1ac, 0xf1a8, 0xf1c7, 0xf1c8, 0xf1cb, 0xf1c4, 0xf1c5, 0xf1ca, 0xf1c9, 0xf1c6, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100}[r-0x621]
+	case 0x660 <= r && r <= 0x669:
+		return [...]rune{0xf130, 0xf131, 0xf132, 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, 0xf138, 0xf139}[r-0x660]
+	case 0x66b <= r && r <= 0x66c:
+		return [...]rune{0xf15e, 0xf15e}[r-0x66b]
+	case 0x200c <= r && r <= 0x200f:
+		return [...]rune{0xf10c, 0xf10d, 0xf10e, 0xf10f}[r-0x200c]
+	case 0x2018 <= r && r <= 0x2019:
+		return [...]rune{0xf13c, 0xf13e}[r-0x2018]
+	case 0xfe81 <= r && r <= 0xfefc:
+		return [...]rune{0xf145, 0xf146, 0xf143, 0xf144, 0xf1bb, 0xf1bb, 0xf147, 0xf148, 0xf1ba, 0xf1af, 0xf1ae, 0xf1ae, 0xf141, 0xf142, 0xf14a, 0xf14a, 0xf149, 0xf149, 0xf1a9, 0xf1aa, 0xf14c, 0xf14c, 0xf14b, 0xf14b, 0xf14e, 0xf14e, 0xf14d, 0xf14d, 0xf151, 0xf150, 0xf14f, 0xf14f, 0xf154, 0xf153, 0xf152, 0xf152, 0xf157, 0xf156, 0xf155, 0xf155, 0xf158, 0xf158, 0xf159, 0xf159, 0xf15a, 0xf15a, 0xf160, 0xf160, 0xf162, 0xf162, 0xf161, 0xf161, 0xf164, 0xf164, 0xf163, 0xf163, 0xf166, 0xf166, 0xf165, 0xf165, 0xf168, 0xf168, 0xf167, 0xf167, 0xf169, 0xf169, 0xf169, 0xf169, 0xf16a, 0xf16a, 0xf16a, 0xf16a, 0xf16e, 0xf16d, 0xf16b, 0xf16c, 0xf172, 0xf171, 0xf16f, 0xf170, 0xf175, 0xf175, 0xf173, 0xf174, 0xf178, 0xf178, 0xf176, 0xf177, 0xf17a, 0xf17a, 0xf179, 0xf179, 0xf17c, 0xf17c, 0xf17b, 0xf17b, 0xf17e, 0xf17e, 0xf17d, 0xf17d, 0xf1e1, 0xf1e1, 0xf17f, 0xf17f, 0xf1a4, 0xf1a3, 0xf1a1, 0xf1a2, 0xf1a5, 0xf1a5, 0xf1ac, 0xf1ab, 0xf1a8, 0xf1a7, 0xf1a6, 0xf1a6, 0xf1c0, 0xf1c1, 0xf1be, 0xf1bf, 0xf1c2, 0xf1c3, 0xf1bd, 0xf1bc}[r-0xfe81]
+	}
+	return 0
+}
+
+// Legacy Traditional Arabic encoding. Returns 0 if not found.
+func arabicPUATradMap(r rune) rune {
+	switch {
+	case 0x20 <= r && r <= 0x22:
+		return [...]rune{0xf220, 0xf221, 0xf222}[r-0x20]
+	case 0x25 == r:
+		return 0xf225
+	case 0x28 <= r && r <= 0x2f:
+		return [...]rune{0xf228, 0xf229, 0xf22a, 0xf22b, 0xf25e, 0xf22d, 0xf22e, 0xf22f}[r-0x28]
+	case 0x3a <= r && r <= 0x3b:
+		return [...]rune{0xf23a, 0xf23b}[r-0x3a]
+	case 0x3d == r:
+		return 0xf23d
+	case 0x3f == r:
+		return 0xf23f
+	case 0x5b == r:
+		return 0xf25b
+	case 0x5d == r:
+		return 0xf25d
+	case 0xab == r:
+		return 0xf223
+	case 0xbb == r:
+		return 0xf224
+	case 0xd7 == r:
+		return 0xf226
+	case 0xf7 == r:
+		return 0xf227
+	case 0x60c == r:
+		return 0xf22c
+	case 0x61b == r:
+		return 0xf23b
+	case 0x61f == r:
+		return 0xf23f
+	case 0x621 <= r && r <= 0x65e:
+		return [...]rune{0xf2d5, 0xf245, 0xf243, 0xf2da, 0xf247, 0xf2d9, 0xf241, 0xf24c, 0xf2d1, 0xf250, 0xf254, 0xf258, 0xf260, 0xf264, 0xf265, 0xf267, 0xf269, 0xf26b, 0xf270, 0xf274, 0xf278, 0xf27e, 0xf2a2, 0xf2a3, 0xf2aa, 0xf2ae, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf25f, 0xf2b2, 0xf2b6, 0xf2ba, 0xf2be, 0xf2c2, 0xf2c6, 0xf2ca, 0xf2cb, 0xf2d4, 0xf2d0, 0xf2e7, 0xf2e8, 0xf2eb, 0xf2e4, 0xf2e5, 0xf2ea, 0xf2e9, 0xf2e6, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200}[r-0x621]
+	case 0x660 <= r && r <= 0x669:
+		return [...]rune{0xf230, 0xf231, 0xf232, 0xf233, 0xf234, 0xf235, 0xf236, 0xf237, 0xf238, 0xf239}[r-0x660]
+	case 0x66b <= r && r <= 0x66c:
+		return [...]rune{0xf25e, 0xf25e}[r-0x66b]
+	case 0x200c <= r && r <= 0x200f:
+		return [...]rune{0xf20c, 0xf20d, 0xf20e, 0xf20f}[r-0x200c]
+	case 0x201c <= r && r <= 0x201d:
+		return [...]rune{0xf23c, 0xf23e}[r-0x201c]
+	case 0xfc08 == r:
+		return 0xf202
+	case 0xfc0a == r:
+		return 0xf21d
+	case 0xfc0e == r:
+		return 0xf203
+	case 0xfc10 == r:
+		return 0xf21e
+	case 0xfc12 == r:
+		return 0xf204
+	case 0xfc32 == r:
+		return 0xf29f
+	case 0xfc3f <= r && r <= 0xfc42:
+		return [...]rune{0xf212, 0xf213, 0xf214, 0xf205}[r-0xfc3f]
+	case 0xfc44 == r:
+		return 0xf21c
+	case 0xfc4e == r:
+		return 0xf206
+	case 0xfc50 == r:
+		return 0xf21f
+	case 0xfc5e == r:
+		return 0xf2ef
+	case 0xfc60 <= r && r <= 0xfc62:
+		return [...]rune{0xf2ec, 0xf2ed, 0xf2f0}[r-0xfc60]
+	case 0xfc6a == r:
+		return 0xf215
+	case 0xfc6d == r:
+		return 0xf292
+	case 0xfc70 == r:
+		return 0xf216
+	case 0xfc73 == r:
+		return 0xf293
+	case 0xfc86 == r:
+		return 0xf295
+	case 0xfc91 == r:
+		return 0xf217
+	case 0xfc94 == r:
+		return 0xf294
+	case 0xfc9c <= r && r <= 0xfc9f:
+		return [...]rune{0xf280, 0xf281, 0xf282, 0xf296}[r-0xfc9c]
+	case 0xfca1 <= r && r <= 0xfca4:
+		return [...]rune{0xf283, 0xf284, 0xf285, 0xf297}[r-0xfca1]
+	case 0xfca8 == r:
+		return 0xf29a
+	case 0xfcaa == r:
+		return 0xf29b
+	case 0xfcac == r:
+		return 0xf29c
+	case 0xfcb0 == r:
+		return 0xf218
+	case 0xfcc9 <= r && r <= 0xfcd3:
+		return [...]rune{0xf286, 0xf287, 0xf288, 0xf29d, 0xf21a, 0xf289, 0xf28a, 0xf28b, 0xf29e, 0xf28d, 0xf28e}[r-0xfcc9]
+	case 0xfcd5 == r:
+		return 0xf298
+	case 0xfcda <= r && r <= 0xfcdd:
+		return [...]rune{0xf28f, 0xf290, 0xf291, 0xf299}[r-0xfcda]
+	case 0xfd30 == r:
+		return 0xf219
+	case 0xfd3e <= r && r <= 0xfd3f:
+		return [...]rune{0xf27b, 0xf27d}[r-0xfd3e]
+	case 0xfd88 == r:
+		return 0xf210
+	case 0xfe81 <= r && r <= 0xfefc:
+		return [...]rune{0xf245, 0xf246, 0xf243, 0xf244, 0xf2da, 0xf2db, 0xf247, 0xf248, 0xf2d9, 0xf2d8, 0xf2d6, 0xf2d7, 0xf241, 0xf242, 0xf24c, 0xf24b, 0xf249, 0xf24a, 0xf2d1, 0xf2d2, 0xf250, 0xf24f, 0xf24d, 0xf24e, 0xf254, 0xf253, 0xf251, 0xf252, 0xf258, 0xf257, 0xf255, 0xf256, 0xf260, 0xf25c, 0xf259, 0xf25a, 0xf264, 0xf263, 0xf261, 0xf262, 0xf265, 0xf266, 0xf267, 0xf268, 0xf269, 0xf26a, 0xf26b, 0xf26c, 0xf270, 0xf26f, 0xf26d, 0xf26e, 0xf274, 0xf273, 0xf271, 0xf272, 0xf278, 0xf277, 0xf275, 0xf276, 0xf27e, 0xf27c, 0xf279, 0xf27a, 0xf2a2, 0xf2a1, 0xf27f, 0xf2f1, 0xf2a6, 0xf2a5, 0xf2a3, 0xf2a4, 0xf2aa, 0xf2a9, 0xf2a7, 0xf2a8, 0xf2ae, 0xf2ad, 0xf2ab, 0xf2ac, 0xf2b2, 0xf2b1, 0xf2af, 0xf2b0, 0xf2b6, 0xf2b5, 0xf2b3, 0xf2b4, 0xf2ba, 0xf2b9, 0xf2b7, 0xf2b8, 0xf2be, 0xf2bd, 0xf2bb, 0xf2bc, 0xf2c2, 0xf2c1, 0xf2bf, 0xf2c0, 0xf2c6, 0xf2c5, 0xf2c3, 0xf2c4, 0xf2ca, 0xf2c9, 0xf2c7, 0xf2c8, 0xf2cb, 0xf2cc, 0xf2d4, 0xf2d3, 0xf2d0, 0xf2cf, 0xf2cd, 0xf2ce, 0xf2e0, 0xf2e1, 0xf2de, 0xf2df, 0xf2e2, 0xf2e3, 0xf2dc, 0xf2dd}[r-0xfe81]
+	}
+	return 0
+}

+ 368 - 209
vendor/github.com/go-text/typesetting/unicodedata/arabic.go → vendor/github.com/go-text/typesetting/harfbuzz/ot_arabic_table.go

@@ -1,12 +1,12 @@
 // SPDX-License-Identifier: Unlicense OR BSD-3-Clause
 // SPDX-License-Identifier: Unlicense OR BSD-3-Clause
 
 
-package unicodedata
-
-import "github.com/go-text/typesetting/language"
+package harfbuzz
 
 
 // Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
 // Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
 
 
-var ArabicJoinings = map[rune]ArabicJoining{ // 775 entries
+import "github.com/go-text/typesetting/language"
+
+var arabicJoinings = map[rune]arabicJoining{ // 828 entries
 	0x0600:  'U',
 	0x0600:  'U',
 	0x0601:  'U',
 	0x0601:  'U',
 	0x0602:  'U',
 	0x0602:  'U',
@@ -320,6 +320,39 @@ var ArabicJoinings = map[rune]ArabicJoining{ // 775 entries
 	0x0868:  'D',
 	0x0868:  'D',
 	0x0869:  'R',
 	0x0869:  'R',
 	0x086a:  'R',
 	0x086a:  'R',
+	0x0870:  'R',
+	0x0871:  'R',
+	0x0872:  'R',
+	0x0873:  'R',
+	0x0874:  'R',
+	0x0875:  'R',
+	0x0876:  'R',
+	0x0877:  'R',
+	0x0878:  'R',
+	0x0879:  'R',
+	0x087a:  'R',
+	0x087b:  'R',
+	0x087c:  'R',
+	0x087d:  'R',
+	0x087e:  'R',
+	0x087f:  'R',
+	0x0880:  'R',
+	0x0881:  'R',
+	0x0882:  'R',
+	0x0883:  'C',
+	0x0884:  'C',
+	0x0885:  'C',
+	0x0886:  'D',
+	0x0887:  'U',
+	0x0888:  'U',
+	0x0889:  'D',
+	0x088a:  'D',
+	0x088b:  'D',
+	0x088c:  'D',
+	0x088d:  'D',
+	0x088e:  'R',
+	0x0890:  'U',
+	0x0891:  'U',
 	0x08a0:  'D',
 	0x08a0:  'D',
 	0x08a1:  'D',
 	0x08a1:  'D',
 	0x08a2:  'D',
 	0x08a2:  'D',
@@ -341,6 +374,7 @@ var ArabicJoinings = map[rune]ArabicJoining{ // 775 entries
 	0x08b2:  'R',
 	0x08b2:  'R',
 	0x08b3:  'D',
 	0x08b3:  'D',
 	0x08b4:  'D',
 	0x08b4:  'D',
+	0x08b5:  'D',
 	0x08b6:  'D',
 	0x08b6:  'D',
 	0x08b7:  'D',
 	0x08b7:  'D',
 	0x08b8:  'D',
 	0x08b8:  'D',
@@ -359,6 +393,7 @@ var ArabicJoinings = map[rune]ArabicJoining{ // 775 entries
 	0x08c5:  'D',
 	0x08c5:  'D',
 	0x08c6:  'D',
 	0x08c6:  'D',
 	0x08c7:  'D',
 	0x08c7:  'D',
+	0x08c8:  'D',
 	0x08e2:  'U',
 	0x08e2:  'U',
 	0x1806:  'U',
 	0x1806:  'U',
 	0x1807:  'D',
 	0x1807:  'D',
@@ -683,6 +718,24 @@ var ArabicJoinings = map[rune]ArabicJoining{ // 775 entries
 	0x10f52: 'D',
 	0x10f52: 'D',
 	0x10f53: 'D',
 	0x10f53: 'D',
 	0x10f54: 'R',
 	0x10f54: 'R',
+	0x10f70: 'D',
+	0x10f71: 'D',
+	0x10f72: 'D',
+	0x10f73: 'D',
+	0x10f74: 'R',
+	0x10f75: 'R',
+	0x10f76: 'D',
+	0x10f77: 'D',
+	0x10f78: 'D',
+	0x10f79: 'D',
+	0x10f7a: 'D',
+	0x10f7b: 'D',
+	0x10f7c: 'D',
+	0x10f7d: 'D',
+	0x10f7e: 'D',
+	0x10f7f: 'D',
+	0x10f80: 'D',
+	0x10f81: 'D',
 	0x10fb0: 'D',
 	0x10fb0: 'D',
 	0x10fb1: 'U',
 	0x10fb1: 'U',
 	0x10fb2: 'D',
 	0x10fb2: 'D',
@@ -784,221 +837,327 @@ var ArabicJoinings = map[rune]ArabicJoining{ // 775 entries
 	0x1e94b: 'T',
 	0x1e94b: 'T',
 }
 }
 
 
-const FirstArabicShape = 0x0621
-const LastArabicShape = 0x06d3
+const firstArabicShape = 0x0621
+const lastArabicShape = 0x06d3
 
 
-// ArabicShaping defines the shaping for arabic runes. Each entry is indexed by
+// arabicShaping defines the shaping for arabic runes. Each entry is indexed by
 // the shape, between 0 and 3:
 // the shape, between 0 and 3:
-//   - 0: isolated
-//   - 1: final
-//   - 2: initial
-//   - 3: medial
-// See also the bounds given by FirstArabicShape and LastArabicShape.
-var ArabicShaping = [...][4]uint16{ // required memory: 2 KB
-	{65152, 1569, 1569, 1569},
-	{65153, 65154, 1570, 1570},
-	{65155, 65156, 1571, 1571},
-	{65157, 65158, 1572, 1572},
-	{65159, 65160, 1573, 1573},
-	{65161, 65162, 65163, 65164},
-	{65165, 65166, 1575, 1575},
-	{65167, 65168, 65169, 65170},
-	{65171, 65172, 1577, 1577},
-	{65173, 65174, 65175, 65176},
-	{65177, 65178, 65179, 65180},
-	{65181, 65182, 65183, 65184},
-	{65185, 65186, 65187, 65188},
-	{65189, 65190, 65191, 65192},
-	{65193, 65194, 1583, 1583},
-	{65195, 65196, 1584, 1584},
-	{65197, 65198, 1585, 1585},
-	{65199, 65200, 1586, 1586},
-	{65201, 65202, 65203, 65204},
-	{65205, 65206, 65207, 65208},
-	{65209, 65210, 65211, 65212},
-	{65213, 65214, 65215, 65216},
-	{65217, 65218, 65219, 65220},
-	{65221, 65222, 65223, 65224},
-	{65225, 65226, 65227, 65228},
-	{65229, 65230, 65231, 65232},
-	{1595, 1595, 1595, 1595},
-	{1596, 1596, 1596, 1596},
-	{1597, 1597, 1597, 1597},
-	{1598, 1598, 1598, 1598},
-	{1599, 1599, 1599, 1599},
-	{1600, 1600, 1600, 1600},
-	{65233, 65234, 65235, 65236},
-	{65237, 65238, 65239, 65240},
-	{65241, 65242, 65243, 65244},
-	{65245, 65246, 65247, 65248},
-	{65249, 65250, 65251, 65252},
-	{65253, 65254, 65255, 65256},
-	{65257, 65258, 65259, 65260},
-	{65261, 65262, 1608, 1608},
-	{65263, 65264, 64488, 64489},
-	{65265, 65266, 65267, 65268},
-	{1611, 1611, 1611, 1611},
-	{1612, 1612, 1612, 1612},
-	{1613, 1613, 1613, 1613},
-	{1614, 1614, 1614, 1614},
-	{1615, 1615, 1615, 1615},
-	{1616, 1616, 1616, 1616},
-	{1617, 1617, 1617, 1617},
-	{1618, 1618, 1618, 1618},
-	{1619, 1619, 1619, 1619},
-	{1620, 1620, 1620, 1620},
-	{1621, 1621, 1621, 1621},
-	{1622, 1622, 1622, 1622},
-	{1623, 1623, 1623, 1623},
-	{1624, 1624, 1624, 1624},
-	{1625, 1625, 1625, 1625},
-	{1626, 1626, 1626, 1626},
-	{1627, 1627, 1627, 1627},
-	{1628, 1628, 1628, 1628},
-	{1629, 1629, 1629, 1629},
-	{1630, 1630, 1630, 1630},
-	{1631, 1631, 1631, 1631},
-	{1632, 1632, 1632, 1632},
-	{1633, 1633, 1633, 1633},
-	{1634, 1634, 1634, 1634},
-	{1635, 1635, 1635, 1635},
-	{1636, 1636, 1636, 1636},
-	{1637, 1637, 1637, 1637},
-	{1638, 1638, 1638, 1638},
-	{1639, 1639, 1639, 1639},
-	{1640, 1640, 1640, 1640},
-	{1641, 1641, 1641, 1641},
-	{1642, 1642, 1642, 1642},
-	{1643, 1643, 1643, 1643},
-	{1644, 1644, 1644, 1644},
-	{1645, 1645, 1645, 1645},
-	{1646, 1646, 1646, 1646},
-	{1647, 1647, 1647, 1647},
-	{1648, 1648, 1648, 1648},
-	{64336, 64337, 1649, 1649},
-	{1650, 1650, 1650, 1650},
-	{1651, 1651, 1651, 1651},
-	{1652, 1652, 1652, 1652},
-	{1653, 1653, 1653, 1653},
-	{1654, 1654, 1654, 1654},
-	{64477, 1655, 1655, 1655},
-	{1656, 1656, 1656, 1656},
-	{64358, 64359, 64360, 64361},
-	{64350, 64351, 64352, 64353},
-	{64338, 64339, 64340, 64341},
-	{1660, 1660, 1660, 1660},
-	{1661, 1661, 1661, 1661},
-	{64342, 64343, 64344, 64345},
-	{64354, 64355, 64356, 64357},
-	{64346, 64347, 64348, 64349},
-	{1665, 1665, 1665, 1665},
-	{1666, 1666, 1666, 1666},
-	{64374, 64375, 64376, 64377},
-	{64370, 64371, 64372, 64373},
-	{1669, 1669, 1669, 1669},
-	{64378, 64379, 64380, 64381},
-	{64382, 64383, 64384, 64385},
-	{64392, 64393, 1672, 1672},
-	{1673, 1673, 1673, 1673},
-	{1674, 1674, 1674, 1674},
-	{1675, 1675, 1675, 1675},
-	{64388, 64389, 1676, 1676},
-	{64386, 64387, 1677, 1677},
-	{64390, 64391, 1678, 1678},
-	{1679, 1679, 1679, 1679},
-	{1680, 1680, 1680, 1680},
-	{64396, 64397, 1681, 1681},
-	{1682, 1682, 1682, 1682},
-	{1683, 1683, 1683, 1683},
-	{1684, 1684, 1684, 1684},
-	{1685, 1685, 1685, 1685},
-	{1686, 1686, 1686, 1686},
-	{1687, 1687, 1687, 1687},
-	{64394, 64395, 1688, 1688},
-	{1689, 1689, 1689, 1689},
-	{1690, 1690, 1690, 1690},
-	{1691, 1691, 1691, 1691},
-	{1692, 1692, 1692, 1692},
-	{1693, 1693, 1693, 1693},
-	{1694, 1694, 1694, 1694},
-	{1695, 1695, 1695, 1695},
-	{1696, 1696, 1696, 1696},
-	{1697, 1697, 1697, 1697},
-	{1698, 1698, 1698, 1698},
-	{1699, 1699, 1699, 1699},
-	{64362, 64363, 64364, 64365},
-	{1701, 1701, 1701, 1701},
-	{64366, 64367, 64368, 64369},
-	{1703, 1703, 1703, 1703},
-	{1704, 1704, 1704, 1704},
-	{64398, 64399, 64400, 64401},
-	{1706, 1706, 1706, 1706},
-	{1707, 1707, 1707, 1707},
-	{1708, 1708, 1708, 1708},
-	{64467, 64468, 64469, 64470},
-	{1710, 1710, 1710, 1710},
-	{64402, 64403, 64404, 64405},
-	{1712, 1712, 1712, 1712},
-	{64410, 64411, 64412, 64413},
-	{1714, 1714, 1714, 1714},
-	{64406, 64407, 64408, 64409},
-	{1716, 1716, 1716, 1716},
-	{1717, 1717, 1717, 1717},
-	{1718, 1718, 1718, 1718},
-	{1719, 1719, 1719, 1719},
-	{1720, 1720, 1720, 1720},
-	{1721, 1721, 1721, 1721},
-	{64414, 64415, 1722, 1722},
-	{64416, 64417, 64418, 64419},
-	{1724, 1724, 1724, 1724},
-	{1725, 1725, 1725, 1725},
-	{64426, 64427, 64428, 64429},
-	{1727, 1727, 1727, 1727},
-	{64420, 64421, 1728, 1728},
-	{64422, 64423, 64424, 64425},
-	{1730, 1730, 1730, 1730},
-	{1731, 1731, 1731, 1731},
-	{1732, 1732, 1732, 1732},
-	{64480, 64481, 1733, 1733},
-	{64473, 64474, 1734, 1734},
-	{64471, 64472, 1735, 1735},
-	{64475, 64476, 1736, 1736},
-	{64482, 64483, 1737, 1737},
-	{1738, 1738, 1738, 1738},
-	{64478, 64479, 1739, 1739},
-	{64508, 64509, 64510, 64511},
-	{1741, 1741, 1741, 1741},
-	{1742, 1742, 1742, 1742},
-	{1743, 1743, 1743, 1743},
-	{64484, 64485, 64486, 64487},
-	{1745, 1745, 1745, 1745},
-	{64430, 64431, 1746, 1746},
-	{64432, 64433, 1747, 1747},
+//   - 0: initial
+//   - 1: medial
+//   - 2: final
+//   - 3: isolated
+// See also the bounds given by [firstArabicShape] and [lastArabicShape].
+var arabicShaping = [...][4]uint16{ // required memory: 2 KB
+	{0x0000, 0x0000, 0x0000, 0xfe80},
+	{0x0000, 0x0000, 0xfe82, 0xfe81},
+	{0x0000, 0x0000, 0xfe84, 0xfe83},
+	{0x0000, 0x0000, 0xfe86, 0xfe85},
+	{0x0000, 0x0000, 0xfe88, 0xfe87},
+	{0xfe8b, 0xfe8c, 0xfe8a, 0xfe89},
+	{0x0000, 0x0000, 0xfe8e, 0xfe8d},
+	{0xfe91, 0xfe92, 0xfe90, 0xfe8f},
+	{0x0000, 0x0000, 0xfe94, 0xfe93},
+	{0xfe97, 0xfe98, 0xfe96, 0xfe95},
+	{0xfe9b, 0xfe9c, 0xfe9a, 0xfe99},
+	{0xfe9f, 0xfea0, 0xfe9e, 0xfe9d},
+	{0xfea3, 0xfea4, 0xfea2, 0xfea1},
+	{0xfea7, 0xfea8, 0xfea6, 0xfea5},
+	{0x0000, 0x0000, 0xfeaa, 0xfea9},
+	{0x0000, 0x0000, 0xfeac, 0xfeab},
+	{0x0000, 0x0000, 0xfeae, 0xfead},
+	{0x0000, 0x0000, 0xfeb0, 0xfeaf},
+	{0xfeb3, 0xfeb4, 0xfeb2, 0xfeb1},
+	{0xfeb7, 0xfeb8, 0xfeb6, 0xfeb5},
+	{0xfebb, 0xfebc, 0xfeba, 0xfeb9},
+	{0xfebf, 0xfec0, 0xfebe, 0xfebd},
+	{0xfec3, 0xfec4, 0xfec2, 0xfec1},
+	{0xfec7, 0xfec8, 0xfec6, 0xfec5},
+	{0xfecb, 0xfecc, 0xfeca, 0xfec9},
+	{0xfecf, 0xfed0, 0xfece, 0xfecd},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfed3, 0xfed4, 0xfed2, 0xfed1},
+	{0xfed7, 0xfed8, 0xfed6, 0xfed5},
+	{0xfedb, 0xfedc, 0xfeda, 0xfed9},
+	{0xfedf, 0xfee0, 0xfede, 0xfedd},
+	{0xfee3, 0xfee4, 0xfee2, 0xfee1},
+	{0xfee7, 0xfee8, 0xfee6, 0xfee5},
+	{0xfeeb, 0xfeec, 0xfeea, 0xfee9},
+	{0x0000, 0x0000, 0xfeee, 0xfeed},
+	{0xfbe8, 0xfbe9, 0xfef0, 0xfeef},
+	{0xfef3, 0xfef4, 0xfef2, 0xfef1},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0xfb51, 0xfb50},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0xfbdd},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfb68, 0xfb69, 0xfb67, 0xfb66},
+	{0xfb60, 0xfb61, 0xfb5f, 0xfb5e},
+	{0xfb54, 0xfb55, 0xfb53, 0xfb52},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfb58, 0xfb59, 0xfb57, 0xfb56},
+	{0xfb64, 0xfb65, 0xfb63, 0xfb62},
+	{0xfb5c, 0xfb5d, 0xfb5b, 0xfb5a},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfb78, 0xfb79, 0xfb77, 0xfb76},
+	{0xfb74, 0xfb75, 0xfb73, 0xfb72},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfb7c, 0xfb7d, 0xfb7b, 0xfb7a},
+	{0xfb80, 0xfb81, 0xfb7f, 0xfb7e},
+	{0x0000, 0x0000, 0xfb89, 0xfb88},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0xfb85, 0xfb84},
+	{0x0000, 0x0000, 0xfb83, 0xfb82},
+	{0x0000, 0x0000, 0xfb87, 0xfb86},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0xfb8d, 0xfb8c},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0xfb8b, 0xfb8a},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfb6c, 0xfb6d, 0xfb6b, 0xfb6a},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfb70, 0xfb71, 0xfb6f, 0xfb6e},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfb90, 0xfb91, 0xfb8f, 0xfb8e},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfbd5, 0xfbd6, 0xfbd4, 0xfbd3},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfb94, 0xfb95, 0xfb93, 0xfb92},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfb9c, 0xfb9d, 0xfb9b, 0xfb9a},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfb98, 0xfb99, 0xfb97, 0xfb96},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0xfb9f, 0xfb9e},
+	{0xfba2, 0xfba3, 0xfba1, 0xfba0},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfbac, 0xfbad, 0xfbab, 0xfbaa},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0xfba5, 0xfba4},
+	{0xfba8, 0xfba9, 0xfba7, 0xfba6},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0xfbe1, 0xfbe0},
+	{0x0000, 0x0000, 0xfbda, 0xfbd9},
+	{0x0000, 0x0000, 0xfbd8, 0xfbd7},
+	{0x0000, 0x0000, 0xfbdc, 0xfbdb},
+	{0x0000, 0x0000, 0xfbe3, 0xfbe2},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0xfbdf, 0xfbde},
+	{0xfbfe, 0xfbff, 0xfbfd, 0xfbfc},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0xfbe6, 0xfbe7, 0xfbe5, 0xfbe4},
+	{0x0000, 0x0000, 0x0000, 0x0000},
+	{0x0000, 0x0000, 0xfbaf, 0xfbae},
+	{0x0000, 0x0000, 0xfbb1, 0xfbb0},
 }
 }
 
 
-// ArabicLigatures exposes lam-alef ligatures
-var ArabicLigatures = [...]struct {
+type arabicLig struct {
+	components []rune // currently with length 1 or 2
+	ligature   rune
+}
+
+type arabicTableEntry struct {
 	First     rune
 	First     rune
-	Ligatures [4][2]rune // {second, ligature}
-}{
-	{0xfedf, [4][2]rune{
-		{0xfe82, 0xfef5},
-		{0xfe84, 0xfef7},
-		{0xfe88, 0xfef9},
-		{0xfe8e, 0xfefb},
+	Ligatures []arabicLig
+}
+
+// arabicLigatureTable exposes lam-alef ligatures
+var arabicLigatureTable = [...]arabicTableEntry{
+	{0xfe91, []arabicLig{
+		{[]rune{0xfea0}, 0xfc9c},
+		{[]rune{0xfea4}, 0xfc9d},
+		{[]rune{0xfea8}, 0xfc9e},
+		{[]rune{0xfee2}, 0xfc08},
+		{[]rune{0xfee4}, 0xfc9f},
+	}},
+	{0xfe92, []arabicLig{
+		{[]rune{0xfeae}, 0xfc6a},
+		{[]rune{0xfee6}, 0xfc6d},
+		{[]rune{0xfef2}, 0xfc6f},
+	}},
+	{0xfe97, []arabicLig{
+		{[]rune{0xfea0}, 0xfca1},
+		{[]rune{0xfea4}, 0xfca2},
+		{[]rune{0xfea8}, 0xfca3},
+		{[]rune{0xfee2}, 0xfc0e},
+		{[]rune{0xfee4}, 0xfca4},
+	}},
+	{0xfe98, []arabicLig{
+		{[]rune{0xfeae}, 0xfc70},
+		{[]rune{0xfee6}, 0xfc73},
+		{[]rune{0xfef2}, 0xfc75},
+	}},
+	{0xfe9b, []arabicLig{
+		{[]rune{0xfee2}, 0xfc12},
+	}},
+	{0xfe9f, []arabicLig{
+		{[]rune{0xfee4}, 0xfca8},
+	}},
+	{0xfea3, []arabicLig{
+		{[]rune{0xfee4}, 0xfcaa},
+	}},
+	{0xfea7, []arabicLig{
+		{[]rune{0xfee4}, 0xfcac},
 	}},
 	}},
-	{0xfee0, [4][2]rune{
-		{0xfe82, 0xfef6},
-		{0xfe84, 0xfef8},
-		{0xfe88, 0xfefa},
-		{0xfe8e, 0xfefc},
+	{0xfeb3, []arabicLig{
+		{[]rune{0xfee4}, 0xfcb0},
+	}},
+	{0xfeb7, []arabicLig{
+		{[]rune{0xfee4}, 0xfd30},
+	}},
+	{0xfed3, []arabicLig{
+		{[]rune{0xfef2}, 0xfc32},
+	}},
+	{0xfedf, []arabicLig{
+		{[]rune{0xfe82}, 0xfef5},
+		{[]rune{0xfe84}, 0xfef7},
+		{[]rune{0xfe88}, 0xfef9},
+		{[]rune{0xfe8e}, 0xfefb},
+		{[]rune{0xfe9e}, 0xfc3f},
+		{[]rune{0xfea0}, 0xfcc9},
+		{[]rune{0xfea2}, 0xfc40},
+		{[]rune{0xfea4}, 0xfcca},
+		{[]rune{0xfea6}, 0xfc41},
+		{[]rune{0xfea8}, 0xfccb},
+		{[]rune{0xfee2}, 0xfc42},
+		{[]rune{0xfee4}, 0xfccc},
+		{[]rune{0xfeec}, 0xfccd},
+		{[]rune{0xfef2}, 0xfc44},
+	}},
+	{0xfee0, []arabicLig{
+		{[]rune{0xfe82}, 0xfef6},
+		{[]rune{0xfe84}, 0xfef8},
+		{[]rune{0xfe88}, 0xfefa},
+		{[]rune{0xfe8e}, 0xfefc},
+		{[]rune{0xfef0}, 0xfc86},
+	}},
+	{0xfee3, []arabicLig{
+		{[]rune{0xfea0}, 0xfcce},
+		{[]rune{0xfea4}, 0xfccf},
+		{[]rune{0xfea8}, 0xfcd0},
+		{[]rune{0xfee4}, 0xfcd1},
+	}},
+	{0xfee7, []arabicLig{
+		{[]rune{0xfea0}, 0xfcd2},
+		{[]rune{0xfea4}, 0xfcd3},
+		{[]rune{0xfee2}, 0xfc4e},
+		{[]rune{0xfee4}, 0xfcd5},
+	}},
+	{0xfee8, []arabicLig{
+		{[]rune{0xfef2}, 0xfc8f},
+	}},
+	{0xfef3, []arabicLig{
+		{[]rune{0xfea0}, 0xfcda},
+		{[]rune{0xfea4}, 0xfcdb},
+		{[]rune{0xfea8}, 0xfcdc},
+		{[]rune{0xfee4}, 0xfcdd},
+	}},
+	{0xfef4, []arabicLig{
+		{[]rune{0xfeae}, 0xfc91},
+		{[]rune{0xfee6}, 0xfc94},
+	}},
+}
+
+var arabicLigatureMarkTable = [...]arabicTableEntry{
+	{0x0651, []arabicLig{
+		{[]rune{0x064b}, 0xf2ee},
+		{[]rune{0x064c}, 0xfc5e},
+		{[]rune{0x064e}, 0xfc60},
+		{[]rune{0x064f}, 0xfc61},
+		{[]rune{0x0650}, 0xfc62},
+	}},
+}
+
+var arabicLigature3Table = [...]arabicTableEntry{
+	{0xfedf, []arabicLig{
+		{[]rune{0xfee0, 0xfeea}, 0xf201},
+		{[]rune{0xfee4, 0xfea4}, 0xfd88},
+		{[]rune{0xfee4, 0xfea0}, 0xf211},
 	}},
 	}},
 }
 }
 
 
-// HasArabicJoining return 'true' if the given script has arabic joining.
-func HasArabicJoining(script language.Script) bool {
+// hasArabicJoining return 'true' if the given script has arabic joining.
+func hasArabicJoining(script language.Script) bool {
 	switch script {
 	switch script {
-	case language.Adlam, language.Arabic, language.Chorasmian, language.Hanifi_Rohingya, language.Mandaic, language.Manichaean, language.Mongolian, language.Nko, language.Phags_Pa, language.Psalter_Pahlavi, language.Sogdian, language.Syriac:
+	case language.Adlam, language.Arabic, language.Chorasmian, language.Hanifi_Rohingya, language.Mandaic, language.Manichaean, language.Mongolian, language.Nko, language.Old_Uyghur, language.Phags_Pa, language.Psalter_Pahlavi, language.Sogdian, language.Syriac:
 		return true
 		return true
 	default:
 	default:
 		return false
 		return false

+ 1 - 1
vendor/github.com/go-text/typesetting/harfbuzz/ot_hangul.go

@@ -91,7 +91,7 @@ func (cs *complexShaperHangul) preprocessText(_ *otShapePlan, buffer *Buffer, fo
 	*
 	*
 	*   - LV can be precomposed, or decomposed.  Lets call those
 	*   - LV can be precomposed, or decomposed.  Lets call those
 	*     <LV> and <L,V>,
 	*     <LV> and <L,V>,
-	*   - LVT can be fully precomposed, partically precomposed, or
+	*   - LVT can be fully precomposed, partially precomposed, or
 	*     fully decomposed.  Ie. <LVT>, <LV,T>, or <L,V,T>.
 	*     fully decomposed.  Ie. <LVT>, <LV,T>, or <L,V,T>.
 	*
 	*
 	* The composition / decomposition is mechanical.  However, not
 	* The composition / decomposition is mechanical.  However, not

+ 19 - 1
vendor/github.com/go-text/typesetting/harfbuzz/ot_hebrew.go

@@ -58,7 +58,7 @@ func (complexShaperHebrew) compose(c *otNormalizeContext, a, b rune) (rune, bool
 			if a == 0x05D9 { /* YOD */
 			if a == 0x05D9 { /* YOD */
 				return 0xFB1D, true
 				return 0xFB1D, true
 			}
 			}
-		case 0x05B7: /* patah */
+		case 0x05B7: /* PATAH */
 			if a == 0x05F2 { /* YIDDISH YOD YOD */
 			if a == 0x05F2 { /* YIDDISH YOD YOD */
 				return 0xFB1F, true
 				return 0xFB1F, true
 			} else if a == 0x05D0 { /* ALEF */
 			} else if a == 0x05D0 { /* ALEF */
@@ -120,3 +120,21 @@ func (complexShaperHebrew) gposTag() tables.Tag {
 	// https://github.com/harfbuzz/harfbuzz/issues/347#issuecomment-267838368
 	// https://github.com/harfbuzz/harfbuzz/issues/347#issuecomment-267838368
 	return loader.NewTag('h', 'e', 'b', 'r')
 	return loader.NewTag('h', 'e', 'b', 'r')
 }
 }
+
+func (complexShaperHebrew) reorderMarks(_ *otShapePlan, buffer *Buffer, start, end int) {
+	info := buffer.Info
+
+	for i := start + 2; i < end; i++ {
+		c0 := info[i-2].getModifiedCombiningClass()
+		c1 := info[i-1].getModifiedCombiningClass()
+		c2 := info[i-0].getModifiedCombiningClass()
+
+		if (c0 == mcc17 || c0 == mcc18) /* patach or qamats */ &&
+			(c1 == mcc10 || c1 == mcc14) /* sheva or hiriq */ &&
+			(c2 == mcc22 || c2 == combiningClassBelow) /* meteg or below */ {
+			buffer.mergeClusters(i-1, i+1)
+			info[i-1], info[i] = info[i], info[i-1] // swap
+			break
+		}
+	}
+}

+ 186 - 412
vendor/github.com/go-text/typesetting/harfbuzz/ot_indic.go

@@ -16,6 +16,32 @@ import (
 //   - when `true`, Uniscribe behavior is reproduced
 //   - when `true`, Uniscribe behavior is reproduced
 var UniscribeBugCompatible = false
 var UniscribeBugCompatible = false
 
 
+// Keep in sync with the code generator.
+const (
+	posStart = iota
+
+	posRaToBecomeReph
+	posPreM
+	posPreC
+
+	posBaseC
+	posAfterMain
+
+	posAboveC
+
+	posBeforeSub
+	posBelowC
+	posAfterSub
+
+	posBeforePost
+	posPostC
+	posAfterPost
+
+	posSmvd
+
+	posEnd
+)
+
 var _ otComplexShaper = (*complexShaperIndic)(nil)
 var _ otComplexShaper = (*complexShaperIndic)(nil)
 
 
 // Indic shaper.
 // Indic shaper.
@@ -31,12 +57,13 @@ type complexShaperIndic struct {
  * cannot happen in a consonant syllable.  The plus side however is, we can call the
  * cannot happen in a consonant syllable.  The plus side however is, we can call the
  * consonant syllable logic from the vowel syllable function and get it all right! */
  * consonant syllable logic from the vowel syllable function and get it all right! */
 const (
 const (
-	medialFlags    = 1 << otCM
-	consonantFlags = 1<<otC | 1<<otCS | 1<<otRa | medialFlags | 1<<otV | 1<<otPLACEHOLDER | 1<<otDOTTEDCIRCLE
-	joinerFlags    = 1<<otZWJ | 1<<otZWNJ
+	consonantFlags = 1<<indSM_ex_C | 1<<indSM_ex_CS |
+		1<<indSM_ex_Ra | 1<<indSM_ex_CM | 1<<indSM_ex_V |
+		1<<indSM_ex_PLACEHOLDER | 1<<indSM_ex_DOTTEDCIRCLE
+	joinerFlags = 1<<indSM_ex_ZWJ | 1<<indSM_ex_ZWNJ
 )
 )
 
 
-func isOneOf(info *GlyphInfo, flags uint) bool {
+func isOneOf(info *GlyphInfo, flags uint32) bool {
 	/* If it ligated, all bets are off. */
 	/* If it ligated, all bets are off. */
 	if info.ligated() {
 	if info.ligated() {
 		return false
 		return false
@@ -53,199 +80,13 @@ func isConsonant(info *GlyphInfo) bool {
 }
 }
 
 
 func isHalant(info *GlyphInfo) bool {
 func isHalant(info *GlyphInfo) bool {
-	return isOneOf(info, 1<<otH)
-}
-
-func isDeva(u rune) bool { return u & ^0x7F == 0x0900 }
-func isBeng(u rune) bool { return u & ^0x7F == 0x0980 }
-func isGuru(u rune) bool { return u & ^0x7F == 0x0A00 }
-func isGujr(u rune) bool { return u & ^0x7F == 0x0A80 }
-func isOrya(u rune) bool { return u & ^0x7F == 0x0B00 }
-func isTaml(u rune) bool { return u & ^0x7F == 0x0B80 }
-func isTelu(u rune) bool { return u & ^0x7F == 0x0C00 }
-func isKnda(u rune) bool { return u & ^0x7F == 0x0C80 }
-func isMlym(u rune) bool { return u & ^0x7F == 0x0D00 }
-func isSinh(u rune) bool { return u & ^0x7F == 0x0D80 }
-
-func matraPositionIndic(u rune, side uint8) uint8 {
-	switch side {
-	case posPreC:
-		return posPreM
-	case posPostC:
-		switch {
-		case isDeva(u):
-			return posAfterSub
-		case isBeng(u):
-			return posAfterPost
-		case isGuru(u):
-			return posAfterPost
-		case isGujr(u):
-			return posAfterPost
-		case isOrya(u):
-			return posAfterPost
-		case isTaml(u):
-			return posAfterPost
-		case isTelu(u):
-			if u <= 0x0C42 {
-				return posBeforeSub
-			}
-			return posAfterSub
-		case isKnda(u):
-			if u < 0x0CC3 || u > 0xCD6 {
-				return posBeforeSub
-			}
-			return posAfterSub
-		case isMlym(u):
-			return posAfterPost
-		case isSinh(u):
-			return posAfterSub
-		default:
-			return posAfterSub
-		}
-	case posAboveC: /* BENG and MLYM don't have top matras. */
-		switch {
-		case isDeva(u):
-			return posAfterSub
-		case isGuru(u):
-			return posAfterPost /* Deviate from spec */
-		case isGujr(u):
-			return posAfterSub
-		case isOrya(u):
-			return posAfterMain
-		case isTaml(u):
-			return posAfterSub
-		case isTelu(u):
-			return posBeforeSub
-		case isKnda(u):
-			return posBeforeSub
-		case isSinh(u):
-			return posAfterSub
-		default:
-			return posAfterSub
-
-		}
-	case posBelowC:
-		switch {
-		case isDeva(u):
-			return posAfterSub
-		case isBeng(u):
-			return posAfterSub
-		case isGuru(u):
-			return posAfterPost
-		case isGujr(u):
-			return posAfterPost
-		case isOrya(u):
-			return posAfterSub
-		case isTaml(u):
-			return posAfterPost
-		case isTelu(u):
-			return posBeforeSub
-		case isKnda(u):
-			return posBeforeSub
-		case isMlym(u):
-			return posAfterPost
-		case isSinh(u):
-			return posAfterSub
-		default:
-			return posAfterSub
-		}
-	}
-	return side
-}
-
-func isRa(u rune) bool {
-	switch u {
-	case 0x0930, /* Devanagari */
-		0x09B0, /* Bengali */
-		0x09F0, /* Bengali */
-		0x0A30, /* Gurmukhi */ /* No Reph */
-		0x0AB0, /* Gujarati */
-		0x0B30, /* Oriya */
-		0x0BB0, /* Tamil */  /* No Reph */
-		0x0C30, /* Telugu */ /* Reph formed only with ZWJ */
-		0x0CB0, /* Kannada */
-		0x0D30, /* Malayalam */ /* No Reph, Logical Repha */
-		0x0DBB: /* Sinhala */   /* Reph formed only with ZWJ */
-		return true
-	default:
-		return false
-	}
+	return isOneOf(info, 1<<indSM_ex_H)
 }
 }
 
 
 func (info *GlyphInfo) setIndicProperties() {
 func (info *GlyphInfo) setIndicProperties() {
 	u := info.codepoint
 	u := info.codepoint
-	info.complexCategory, info.complexAux = computeIndicProperties(u)
-}
-
-func computeIndicProperties(u rune) (cat, pos uint8) {
 	type_ := indicGetCategories(u)
 	type_ := indicGetCategories(u)
-	cat = uint8(type_ & 0xFF)
-	pos = uint8(type_ >> 8)
-
-	/*
-	 * Re-assign category
-	 */
-
-	/* The following act more like the Bindus. */
-	if 0x0953 <= u && u <= 0x0954 {
-		cat = otSM
-		/* The following act like consonants. */
-	} else if (0x0A72 <= u && u <= 0x0A73) || (0x1CF5 <= u && u <= 0x1CF6) {
-		cat = otC
-	} else if 0x1CE2 <= u && u <= 0x1CE8 {
-		cat = otA
-	} else if u == 0x1CED {
-		cat = otA
-		/* The following take marks in standalone clusters, similar to Avagraha. */
-	} else if 0xA8F2 <= u && u <= 0xA8F7 || 0x1CE9 <= u && u <= 0x1CEC || 0x1CEE <= u && u <= 0x1CF1 {
-		cat = otSymbol
-	} else if u == 0x0A51 {
-		/* https://github.com/harfbuzz/harfbuzz/issues/524 */
-		cat = otM
-		pos = posBelowC
-
-		/* According to ScriptExtensions.txt, these Grantha marks may also be used in Tamil,
-		 * so the Indic shaper needs to know their categories. */
-	} else if u == 0x11301 || u == 0x11303 {
-		cat = otSM
-	} else if u == 0x1133B || u == 0x1133C {
-		cat = otN
-	} else if u == 0x0AFB {
-		cat = otN /* https://github.com/harfbuzz/harfbuzz/issues/552 */
-	} else if u == 0x0B55 {
-		cat = otN /* https://github.com/harfbuzz/harfbuzz/issues/2849 */
-	} else if u == 0x0980 {
-		cat = otPLACEHOLDER /* https://github.com/harfbuzz/harfbuzz/issues/538 */
-	} else if u == 0x09FC {
-		cat = otPLACEHOLDER /* https://github.com/harfbuzz/harfbuzz/pull/1613 */
-	} else if u == 0x0C80 {
-		cat = otPLACEHOLDER /* https://github.com/harfbuzz/harfbuzz/pull/623 */
-	} else if 0x2010 <= u && u <= 0x2011 {
-		cat = otPLACEHOLDER
-	} else if u == 0x25CC {
-		cat = otDOTTEDCIRCLE
-	}
-
-	/*
-	 * Re-assign position.
-	 */
-
-	if 1<<cat&consonantFlags != 0 {
-		pos = posBaseC
-		if isRa(u) {
-			cat = otRa
-		}
-	} else if cat == otM {
-		pos = matraPositionIndic(u, pos)
-	} else if 1<<cat&(1<<otSM /* | FLAG (otVd) */ |1<<otA|1<<otSymbol) != 0 {
-		pos = posSmvd
-	}
-
-	if u == 0x0B01 {
-		pos = posBeforeSub /* Oriya Bindu is BeforeSub in the spec. */
-	}
-
-	return cat, pos
+	info.complexCategory, info.complexAux = uint8(type_&0xFF), uint8(type_>>8)
 }
 }
 
 
 type indicWouldSubstituteFeature struct {
 type indicWouldSubstituteFeature struct {
@@ -278,12 +119,6 @@ func (ws indicWouldSubstituteFeature) wouldSubstitute(glyphs []GID, font *Font)
  * instead of adding a new flag in these structs.
  * instead of adding a new flag in these structs.
  */
  */
 
 
-// base_position_t
-const (
-	basePosLastSinhala = iota
-	basePosLast
-)
-
 // reph_position_t
 // reph_position_t
 const (
 const (
 	rephPosAfterMain  = posAfterMain
 	rephPosAfterMain  = posAfterMain
@@ -310,7 +145,6 @@ type indicConfig struct {
 	script     language.Script
 	script     language.Script
 	hasOldSpec bool
 	hasOldSpec bool
 	virama     rune
 	virama     rune
-	basePos    uint8
 	rephPos    uint8
 	rephPos    uint8
 	rephMode   uint8
 	rephMode   uint8
 	blwfMode   uint8
 	blwfMode   uint8
@@ -318,42 +152,34 @@ type indicConfig struct {
 
 
 var indicConfigs = [...]indicConfig{
 var indicConfigs = [...]indicConfig{
 	/* Default.  Should be first. */
 	/* Default.  Should be first. */
-	{0, false, 0, basePosLast, rephPosBeforePost, rephModeImplicit, blwfModePreAndPost},
-	{language.Devanagari, true, 0x094D, basePosLast, rephPosBeforePost, rephModeImplicit, blwfModePreAndPost},
-	{language.Bengali, true, 0x09CD, basePosLast, rephPosAfterSub, rephModeImplicit, blwfModePreAndPost},
-	{language.Gurmukhi, true, 0x0A4D, basePosLast, rephPosBeforeSub, rephModeImplicit, blwfModePreAndPost},
-	{language.Gujarati, true, 0x0ACD, basePosLast, rephPosBeforePost, rephModeImplicit, blwfModePreAndPost},
-	{language.Oriya, true, 0x0B4D, basePosLast, rephPosAfterMain, rephModeImplicit, blwfModePreAndPost},
-	{language.Tamil, true, 0x0BCD, basePosLast, rephPosAfterPost, rephModeImplicit, blwfModePreAndPost},
-	{language.Telugu, true, 0x0C4D, basePosLast, rephPosAfterPost, rephModeExplicit, blwfModePostOnly},
-	{language.Kannada, true, 0x0CCD, basePosLast, rephPosAfterPost, rephModeImplicit, blwfModePostOnly},
-	{language.Malayalam, true, 0x0D4D, basePosLast, rephPosAfterMain, rephModeLogRepha, blwfModePreAndPost},
-	{
-		language.Sinhala, false, 0x0DCA, basePosLastSinhala,
-		rephPosAfterPost, rephModeExplicit, blwfModePreAndPost,
-	},
+	{0, false, 0, rephPosBeforePost, rephModeImplicit, blwfModePreAndPost},
+	{language.Devanagari, true, 0x094D, rephPosBeforePost, rephModeImplicit, blwfModePreAndPost},
+	{language.Bengali, true, 0x09CD, rephPosAfterSub, rephModeImplicit, blwfModePreAndPost},
+	{language.Gurmukhi, true, 0x0A4D, rephPosBeforeSub, rephModeImplicit, blwfModePreAndPost},
+	{language.Gujarati, true, 0x0ACD, rephPosBeforePost, rephModeImplicit, blwfModePreAndPost},
+	{language.Oriya, true, 0x0B4D, rephPosAfterMain, rephModeImplicit, blwfModePreAndPost},
+	{language.Tamil, true, 0x0BCD, rephPosAfterPost, rephModeImplicit, blwfModePreAndPost},
+	{language.Telugu, true, 0x0C4D, rephPosAfterPost, rephModeExplicit, blwfModePostOnly},
+	{language.Kannada, true, 0x0CCD, rephPosAfterPost, rephModeImplicit, blwfModePostOnly},
+	{language.Malayalam, true, 0x0D4D, rephPosAfterMain, rephModeLogRepha, blwfModePreAndPost},
 }
 }
 
 
-/*
- * Indic shaper.
- */
-
 var indicFeatures = [...]otMapFeature{
 var indicFeatures = [...]otMapFeature{
 	/*
 	/*
 	* Basic features.
 	* Basic features.
 	* These features are applied in order, one at a time, after initial_reordering.
 	* These features are applied in order, one at a time, after initial_reordering.
 	 */
 	 */
-	{loader.NewTag('n', 'u', 'k', 't'), ffGlobalManualJoiners},
-	{loader.NewTag('a', 'k', 'h', 'n'), ffGlobalManualJoiners},
-	{loader.NewTag('r', 'p', 'h', 'f'), ffManualJoiners},
-	{loader.NewTag('r', 'k', 'r', 'f'), ffGlobalManualJoiners},
-	{loader.NewTag('p', 'r', 'e', 'f'), ffManualJoiners},
-	{loader.NewTag('b', 'l', 'w', 'f'), ffManualJoiners},
-	{loader.NewTag('a', 'b', 'v', 'f'), ffManualJoiners},
-	{loader.NewTag('h', 'a', 'l', 'f'), ffManualJoiners},
-	{loader.NewTag('p', 's', 't', 'f'), ffManualJoiners},
-	{loader.NewTag('v', 'a', 't', 'u'), ffGlobalManualJoiners},
-	{loader.NewTag('c', 'j', 'c', 't'), ffGlobalManualJoiners},
+	{loader.NewTag('n', 'u', 'k', 't'), ffGlobalManualJoiners | ffPerSyllable},
+	{loader.NewTag('a', 'k', 'h', 'n'), ffGlobalManualJoiners | ffPerSyllable},
+	{loader.NewTag('r', 'p', 'h', 'f'), ffManualJoiners | ffPerSyllable},
+	{loader.NewTag('r', 'k', 'r', 'f'), ffGlobalManualJoiners | ffPerSyllable},
+	{loader.NewTag('p', 'r', 'e', 'f'), ffManualJoiners | ffPerSyllable},
+	{loader.NewTag('b', 'l', 'w', 'f'), ffManualJoiners | ffPerSyllable},
+	{loader.NewTag('a', 'b', 'v', 'f'), ffManualJoiners | ffPerSyllable},
+	{loader.NewTag('h', 'a', 'l', 'f'), ffManualJoiners | ffPerSyllable},
+	{loader.NewTag('p', 's', 't', 'f'), ffManualJoiners | ffPerSyllable},
+	{loader.NewTag('v', 'a', 't', 'u'), ffGlobalManualJoiners | ffPerSyllable},
+	{loader.NewTag('c', 'j', 'c', 't'), ffGlobalManualJoiners | ffPerSyllable},
 	/*
 	/*
 	* Other features.
 	* Other features.
 	* These features are applied all at once, after final_reordering
 	* These features are applied all at once, after final_reordering
@@ -361,12 +187,12 @@ var indicFeatures = [...]otMapFeature{
 	* Default Bengali font in Windows for example has intermixed
 	* Default Bengali font in Windows for example has intermixed
 	* lookups for init,pres,abvs,blws features.
 	* lookups for init,pres,abvs,blws features.
 	 */
 	 */
-	{loader.NewTag('i', 'n', 'i', 't'), ffManualJoiners},
-	{loader.NewTag('p', 'r', 'e', 's'), ffGlobalManualJoiners},
-	{loader.NewTag('a', 'b', 'v', 's'), ffGlobalManualJoiners},
-	{loader.NewTag('b', 'l', 'w', 's'), ffGlobalManualJoiners},
-	{loader.NewTag('p', 's', 't', 's'), ffGlobalManualJoiners},
-	{loader.NewTag('h', 'a', 'l', 'n'), ffGlobalManualJoiners},
+	{loader.NewTag('i', 'n', 'i', 't'), ffManualJoiners | ffPerSyllable},
+	{loader.NewTag('p', 'r', 'e', 's'), ffGlobalManualJoiners | ffPerSyllable},
+	{loader.NewTag('a', 'b', 'v', 's'), ffGlobalManualJoiners | ffPerSyllable},
+	{loader.NewTag('b', 'l', 'w', 's'), ffGlobalManualJoiners | ffPerSyllable},
+	{loader.NewTag('p', 's', 't', 's'), ffGlobalManualJoiners | ffPerSyllable},
+	{loader.NewTag('h', 'a', 'l', 'n'), ffGlobalManualJoiners | ffPerSyllable},
 }
 }
 
 
 // in the same order as the indicFeatures array
 // in the same order as the indicFeatures array
@@ -400,10 +226,10 @@ func (cs *complexShaperIndic) collectFeatures(plan *otShapePlanner) {
 	/* Do this before any lookups have been applied. */
 	/* Do this before any lookups have been applied. */
 	map_.addGSUBPause(setupSyllablesIndic)
 	map_.addGSUBPause(setupSyllablesIndic)
 
 
-	map_.enableFeature(loader.NewTag('l', 'o', 'c', 'l'))
+	map_.enableFeatureExt(loader.NewTag('l', 'o', 'c', 'l'), ffPerSyllable, 1)
 	/* The Indic specs do not require ccmp, but we apply it here since if
 	/* The Indic specs do not require ccmp, but we apply it here since if
 	* there is a use of it, it's typically at the beginning. */
 	* there is a use of it, it's typically at the beginning. */
-	map_.enableFeature(loader.NewTag('c', 'c', 'm', 'p'))
+	map_.enableFeatureExt(loader.NewTag('c', 'c', 'm', 'p'), ffPerSyllable, 1)
 
 
 	i := 0
 	i := 0
 	map_.addGSUBPause(cs.initialReorderingIndic)
 	map_.addGSUBPause(cs.initialReorderingIndic)
@@ -418,12 +244,11 @@ func (cs *complexShaperIndic) collectFeatures(plan *otShapePlanner) {
 	for ; i < indicNumFeatures; i++ {
 	for ; i < indicNumFeatures; i++ {
 		map_.addFeatureExt(indicFeatures[i].tag, indicFeatures[i].flags, 1)
 		map_.addFeatureExt(indicFeatures[i].tag, indicFeatures[i].flags, 1)
 	}
 	}
-
-	map_.addGSUBPause(clearSyllables)
 }
 }
 
 
 func (complexShaperIndic) overrideFeatures(plan *otShapePlanner) {
 func (complexShaperIndic) overrideFeatures(plan *otShapePlanner) {
 	plan.map_.disableFeature(loader.NewTag('l', 'i', 'g', 'a'))
 	plan.map_.disableFeature(loader.NewTag('l', 'i', 'g', 'a'))
+	plan.map_.addGSUBPause(nil)
 }
 }
 
 
 type indicShapePlan struct {
 type indicShapePlan struct {
@@ -542,12 +367,13 @@ func (cs *complexShaperIndic) setupMasks(plan *otShapePlan, buffer *Buffer, _ *F
 	}
 	}
 }
 }
 
 
-func setupSyllablesIndic(_ *otShapePlan, _ *Font, buffer *Buffer) {
+func setupSyllablesIndic(_ *otShapePlan, _ *Font, buffer *Buffer) bool {
 	findSyllablesIndic(buffer)
 	findSyllablesIndic(buffer)
 	iter, count := buffer.syllableIterator()
 	iter, count := buffer.syllableIterator()
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 		buffer.unsafeToBreak(start, end)
 		buffer.unsafeToBreak(start, end)
 	}
 	}
+	return false
 }
 }
 
 
 func foundSyllableIndic(syllableType uint8, ts, te int, info []GlyphInfo, syllableSerial *uint8) {
 func foundSyllableIndic(syllableType uint8, ts, te int, info []GlyphInfo, syllableSerial *uint8) {
@@ -561,10 +387,6 @@ func foundSyllableIndic(syllableType uint8, ts, te int, info []GlyphInfo, syllab
 }
 }
 
 
 func (indicPlan *indicShapePlan) updateConsonantPositionsIndic(font *Font, buffer *Buffer) {
 func (indicPlan *indicShapePlan) updateConsonantPositionsIndic(font *Font, buffer *Buffer) {
-	if indicPlan.config.basePos != basePosLast {
-		return
-	}
-
 	virama := indicPlan.loadViramaGlyph(font)
 	virama := indicPlan.loadViramaGlyph(font)
 	if virama != 0 {
 	if virama != 0 {
 		info := buffer.Info
 		info := buffer.Info
@@ -587,9 +409,9 @@ func (indicPlan *indicShapePlan) initialReorderingConsonantSyllable(font *Font,
 	* Ra+h+ZWJ must behave like Ra+ZWJ+h... */
 	* Ra+h+ZWJ must behave like Ra+ZWJ+h... */
 	if buffer.Props.Script == language.Kannada &&
 	if buffer.Props.Script == language.Kannada &&
 		start+3 <= end &&
 		start+3 <= end &&
-		isOneOf(&info[start], 1<<otRa) &&
-		isOneOf(&info[start+1], 1<<otH) &&
-		isOneOf(&info[start+2], 1<<otZWJ) {
+		isOneOf(&info[start], 1<<indSM_ex_Ra) &&
+		isOneOf(&info[start+1], 1<<indSM_ex_H) &&
+		isOneOf(&info[start+2], 1<<indSM_ex_ZWJ) {
 		buffer.mergeClusters(start+1, start+3)
 		buffer.mergeClusters(start+1, start+3)
 		info[start+1], info[start+2] = info[start+2], info[start+1]
 		info[start+1], info[start+2] = info[start+2], info[start+1]
 	}
 	}
@@ -618,7 +440,7 @@ func (indicPlan *indicShapePlan) initialReorderingConsonantSyllable(font *Font,
 		limit := start
 		limit := start
 		if indicPlan.maskArray[indicRphf] != 0 && start+3 <= end &&
 		if indicPlan.maskArray[indicRphf] != 0 && start+3 <= end &&
 			((indicPlan.config.rephMode == rephModeImplicit && !isJoiner(&info[start+2])) ||
 			((indicPlan.config.rephMode == rephModeImplicit && !isJoiner(&info[start+2])) ||
-				(indicPlan.config.rephMode == rephModeExplicit && info[start+2].complexCategory == otZWJ)) {
+				(indicPlan.config.rephMode == rephModeExplicit && info[start+2].complexCategory == indSM_ex_ZWJ)) {
 			/* See if it matches the 'rphf' feature. */
 			/* See if it matches the 'rphf' feature. */
 			glyphs := [3]GID{info[start].Glyph, info[start+1].Glyph, 0}
 			glyphs := [3]GID{info[start].Glyph, info[start+1].Glyph, 0}
 			if indicPlan.config.rephMode == rephModeExplicit {
 			if indicPlan.config.rephMode == rephModeExplicit {
@@ -634,7 +456,7 @@ func (indicPlan *indicShapePlan) initialReorderingConsonantSyllable(font *Font,
 				base = start
 				base = start
 				hasReph = true
 				hasReph = true
 			}
 			}
-		} else if indicPlan.config.rephMode == rephModeLogRepha && info[start].complexCategory == otRepha {
+		} else if indicPlan.config.rephMode == rephModeLogRepha && info[start].complexCategory == indSM_ex_Repha {
 			limit += 1
 			limit += 1
 			for limit < end && isJoiner(&info[limit]) {
 			for limit < end && isJoiner(&info[limit]) {
 				limit++
 				limit++
@@ -643,79 +465,46 @@ func (indicPlan *indicShapePlan) initialReorderingConsonantSyllable(font *Font,
 			hasReph = true
 			hasReph = true
 		}
 		}
 
 
-		switch indicPlan.config.basePos {
-		case basePosLast:
-			{
-				/* . starting from the end of the syllable, move backwards */
-				i := end
-				seenBelow := false
-				for do := true; do; do = i > limit {
-					i--
-					/* . until a consonant is found */
-					if isConsonant(&info[i]) {
-						/* . that does not have a below-base or post-base form
-						 * (post-base forms have to follow below-base forms), */
-						if info[i].complexAux != posBelowC &&
-							(info[i].complexAux != posPostC || seenBelow) {
-							base = i
-							break
-						}
-						if info[i].complexAux == posBelowC {
-							seenBelow = true
-						}
-
-						/* . or that is not a pre-base-reordering Ra,
-						 *
-						 * IMPLEMENTATION NOTES:
-						 *
-						 * Our pre-base-reordering Ra's are marked posPostC, so will be skipped
-						 * by the logic above already.
-						 */
-
-						/* . or arrive at the first consonant. The consonant stopped at will
-						 * be the base. */
+		{
+			/* . starting from the end of the syllable, move backwards */
+			i := end
+			seenBelow := false
+			for do := true; do; do = i > limit {
+				i--
+				/* . until a consonant is found */
+				if isConsonant(&info[i]) {
+					/* . that does not have a below-base or post-base form
+					 * (post-base forms have to follow below-base forms), */
+					if info[i].complexAux != posBelowC &&
+						(info[i].complexAux != posPostC || seenBelow) {
 						base = i
 						base = i
-					} else {
-						/* A ZWJ after a Halant stops the base search, and requests an explicit
-						 * half form.
-						 * A ZWJ before a Halant, requests a subjoined form instead, and hence
-						 * search continues.  This is particularly important for Bengali
-						 * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */
-						if start < i &&
-							info[i].complexCategory == otZWJ &&
-							info[i-1].complexCategory == otH {
-							break
-						}
+						break
 					}
 					}
-				}
-			}
-		case basePosLastSinhala:
-			{
-				/* Sinhala base positioning is slightly different from main Indic, in that:
-				 * 1. Its ZWJ behavior is different,
-				 * 2. We don't need to look into the font for consonant positions.
-				 */
-
-				if !hasReph {
-					base = limit
-				}
-
-				/* Find the last base consonant that is not blocked by ZWJ.  If there is
-				 * a ZWJ right before a base consonant, that would request a subjoined form. */
-				for i := limit; i < end; i++ {
-					if isConsonant(&info[i]) {
-						if limit < i && info[i-1].complexCategory == otZWJ {
-							break
-						} else {
-							base = i
-						}
+					if info[i].complexAux == posBelowC {
+						seenBelow = true
 					}
 					}
-				}
 
 
-				/* Mark all subsequent consonants as below. */
-				for i := base + 1; i < end; i++ {
-					if isConsonant(&info[i]) {
-						info[i].complexAux = posBelowC
+					/* . or that is not a pre-base-reordering Ra,
+					 *
+					 * IMPLEMENTATION NOTES:
+					 *
+					 * Our pre-base-reordering Ra's are marked posPostC, so will be skipped
+					 * by the logic above already.
+					 */
+
+					/* . or arrive at the first consonant. The consonant stopped at will
+					 * be the base. */
+					base = i
+				} else {
+					/* A ZWJ after a Halant stops the base search, and requests an explicit
+					 * half form.
+					 * A ZWJ before a Halant, requests a subjoined form instead, and hence
+					 * search continues.  This is particularly important for Bengali
+					 * sequence Ra,H,Ya that should form Ya-Phalaa by subjoining Ya. */
+					if start < i &&
+						info[i].complexCategory == indSM_ex_ZWJ &&
+						info[i-1].complexCategory == indSM_ex_H {
+						break
 					}
 					}
 				}
 				}
 			}
 			}
@@ -772,20 +561,6 @@ func (indicPlan *indicShapePlan) initialReorderingConsonantSyllable(font *Font,
 		info[base].complexAux = posBaseC
 		info[base].complexAux = posBaseC
 	}
 	}
 
 
-	/* Mark final consonants.  A final consonant is one appearing after a matra.
-	* Happens in Sinhala. */
-	for i := base + 1; i < end; i++ {
-		if info[i].complexCategory == otM {
-			for j := i + 1; j < end; j++ {
-				if isConsonant(&info[j]) {
-					info[j].complexAux = posFinalC
-					break
-				}
-			}
-			break
-		}
-	}
-
 	/* Handle beginning Ra */
 	/* Handle beginning Ra */
 	if hasReph {
 	if hasReph {
 		info[start].complexAux = posRaToBecomeReph
 		info[start].complexAux = posRaToBecomeReph
@@ -822,17 +597,17 @@ func (indicPlan *indicShapePlan) initialReorderingConsonantSyllable(font *Font,
 	if indicPlan.isOldSpec {
 	if indicPlan.isOldSpec {
 		disallowDoubleHalants := buffer.Props.Script == language.Kannada
 		disallowDoubleHalants := buffer.Props.Script == language.Kannada
 		for i := base + 1; i < end; i++ {
 		for i := base + 1; i < end; i++ {
-			if info[i].complexCategory == otH {
+			if info[i].complexCategory == indSM_ex_H {
 				var j int
 				var j int
 				for j = end - 1; j > i; j-- {
 				for j = end - 1; j > i; j-- {
 					if isConsonant(&info[j]) ||
 					if isConsonant(&info[j]) ||
-						(disallowDoubleHalants && info[j].complexCategory == otH) {
+						(disallowDoubleHalants && info[j].complexCategory == indSM_ex_H) {
 						break
 						break
 					}
 					}
 				}
 				}
-				if info[j].complexCategory != otH && j > i {
+				if info[j].complexCategory != indSM_ex_H && j > i {
 					/* Move Halant to after last consonant. */
 					/* Move Halant to after last consonant. */
-					if debugMode >= 2 {
+					if debugMode {
 						fmt.Printf("INDIC - halant: switching glyph %d to %d (and shifting between)", i, j)
 						fmt.Printf("INDIC - halant: switching glyph %d to %d (and shifting between)", i, j)
 					}
 					}
 					t := info[i]
 					t := info[i]
@@ -848,17 +623,13 @@ func (indicPlan *indicShapePlan) initialReorderingConsonantSyllable(font *Font,
 	{
 	{
 		var lastPos uint8 = posStart
 		var lastPos uint8 = posStart
 		for i := start; i < end; i++ {
 		for i := start; i < end; i++ {
-			if 1<<info[i].complexCategory&(joinerFlags|1<<otN|1<<otRS|medialFlags|1<<otH) != 0 {
+			if 1<<info[i].complexCategory&(joinerFlags|1<<indSM_ex_N|1<<indSM_ex_RS|1<<indSM_ex_CM|1<<indSM_ex_H) != 0 {
 				info[i].complexAux = lastPos
 				info[i].complexAux = lastPos
-				if info[i].complexCategory == otH && info[i].complexAux == posPreM {
+				if info[i].complexCategory == indSM_ex_H && info[i].complexAux == posPreM {
 					/*
 					/*
 					* Uniscribe doesn't move the Halant with Left Matra.
 					* Uniscribe doesn't move the Halant with Left Matra.
-					* TEST: U+092B,U+093F,U+094DE
-					* We follow.  This is important for the Sinhala
-					* U+0DDA split matra since it decomposes to U+0DD9,U+0DCA
-					* where U+0DD9 is a left matra and U+0DCA is the virama.
-					* We don't want to move the virama with the left matra.
-					* TEST: U+0D9A,U+0DDA
+					* TEST: U+092B,U+093F,U+094D
+					* We follow.
 					 */
 					 */
 					for j := i; j > start; j-- {
 					for j := i; j > start; j-- {
 						if info[j-1].complexAux != posPreM {
 						if info[j-1].complexAux != posPreM {
@@ -868,6 +639,11 @@ func (indicPlan *indicShapePlan) initialReorderingConsonantSyllable(font *Font,
 					}
 					}
 				}
 				}
 			} else if info[i].complexAux != posSmvd {
 			} else if info[i].complexAux != posSmvd {
+				if info[i].complexCategory == indSM_ex_MPst &&
+					i > start && info[i-1].complexCategory == indSM_ex_SM {
+					info[i-1].complexAux = info[i].complexAux
+				}
+
 				lastPos = info[i].complexAux
 				lastPos = info[i].complexAux
 			}
 			}
 		}
 		}
@@ -885,7 +661,7 @@ func (indicPlan *indicShapePlan) initialReorderingConsonantSyllable(font *Font,
 					}
 					}
 				}
 				}
 				last = i
 				last = i
-			} else if info[i].complexCategory == otM {
+			} else if ic := info[i].complexCategory; ic == indSM_ex_M || ic == indSM_ex_MPst {
 				last = i
 				last = i
 			}
 			}
 		}
 		}
@@ -900,20 +676,43 @@ func (indicPlan *indicShapePlan) initialReorderingConsonantSyllable(font *Font,
 
 
 		/* Sit tight, rock 'n roll! */
 		/* Sit tight, rock 'n roll! */
 
 
-		if debugMode >= 2 {
+		if debugMode {
 			fmt.Printf("INDIC - post-base: sorting between glyph %d and %d\n", start, end)
 			fmt.Printf("INDIC - post-base: sorting between glyph %d and %d\n", start, end)
 		}
 		}
 
 
 		subSlice := info[start:end]
 		subSlice := info[start:end]
 		sort.SliceStable(subSlice, func(i, j int) bool { return subSlice[i].complexAux < subSlice[j].complexAux })
 		sort.SliceStable(subSlice, func(i, j int) bool { return subSlice[i].complexAux < subSlice[j].complexAux })
-		/* Find base again */
+
+		// Find base again; also flip left-matra sequence.
+		firstLeftMatra := end
+		lastLeftMatra := end
 		base = end
 		base = end
 		for i := start; i < end; i++ {
 		for i := start; i < end; i++ {
 			if info[i].complexAux == posBaseC {
 			if info[i].complexAux == posBaseC {
 				base = i
 				base = i
 				break
 				break
+			} else if info[i].complexAux == posPreM {
+				if firstLeftMatra == end {
+					firstLeftMatra = i
+				}
+				lastLeftMatra = i
+			}
+		}
+
+		/* https://github.com/harfbuzz/harfbuzz/issues/3863 */
+		if firstLeftMatra < lastLeftMatra {
+			/* No need to merge clusters, handled later. */
+			buffer.reverseRange(firstLeftMatra, lastLeftMatra+1)
+			/* Reverse back nuktas, etc. */
+			i := firstLeftMatra
+			for j := i; j <= lastLeftMatra; j++ {
+				if ic := info[j].complexCategory; ic == indSM_ex_M || ic == indSM_ex_MPst {
+					buffer.reverseRange(i, j+1)
+					i = j + 1
+				}
 			}
 			}
 		}
 		}
+
 		// Things are out-of-control for post base positions, they may shuffle
 		// Things are out-of-control for post base positions, they may shuffle
 		// around like crazy.  In old-spec mode, we move halants around, so in
 		// around like crazy.  In old-spec mode, we move halants around, so in
 		// that case merge all clusters after base.  Otherwise, check the sort
 		// that case merge all clusters after base.  Otherwise, check the sort
@@ -1025,10 +824,10 @@ func (indicPlan *indicShapePlan) initialReorderingConsonantSyllable(font *Font,
 		 * Test case: U+0924,U+094D,U+0930,U+094d,U+200D,U+0915
 		 * Test case: U+0924,U+094D,U+0930,U+094d,U+200D,U+0915
 		 */
 		 */
 		for i := start; i+1 < base; i++ {
 		for i := start; i+1 < base; i++ {
-			if info[i].complexCategory == otRa &&
-				info[i+1].complexCategory == otH &&
+			if info[i].complexCategory == indSM_ex_Ra &&
+				info[i+1].complexCategory == indSM_ex_H &&
 				(i+2 == base ||
 				(i+2 == base ||
-					info[i+2].complexCategory != otZWJ) {
+					info[i+2].complexCategory != indSM_ex_ZWJ) {
 				info[i].Mask |= indicPlan.maskArray[indicBlwf]
 				info[i].Mask |= indicPlan.maskArray[indicBlwf]
 				info[i+1].Mask |= indicPlan.maskArray[indicBlwf]
 				info[i+1].Mask |= indicPlan.maskArray[indicBlwf]
 			}
 			}
@@ -1056,7 +855,7 @@ func (indicPlan *indicShapePlan) initialReorderingConsonantSyllable(font *Font,
 	/* Apply ZWJ/ZWNJ effects */
 	/* Apply ZWJ/ZWNJ effects */
 	for i := start + 1; i < end; i++ {
 	for i := start + 1; i < end; i++ {
 		if isJoiner(&info[i]) {
 		if isJoiner(&info[i]) {
-			nonJoiner := info[i].complexCategory == otZWNJ
+			nonJoiner := info[i].complexCategory == indSM_ex_ZWNJ
 			j := i
 			j := i
 
 
 			for do := true; do; do = (j > start && !isConsonant(&info[j])) {
 			for do := true; do; do = (j > start && !isConsonant(&info[j])) {
@@ -1084,7 +883,7 @@ func (indicPlan *indicShapePlan) initialReorderingStandaloneCluster(font *Font,
 		/* For dotted-circle, this is what Uniscribe does:
 		/* For dotted-circle, this is what Uniscribe does:
 		 * If dotted-circle is the last glyph, it just does nothing.
 		 * If dotted-circle is the last glyph, it just does nothing.
 		 * Ie. It doesn't form Reph. */
 		 * Ie. It doesn't form Reph. */
-		if buffer.Info[end-1].complexCategory == otDOTTEDCIRCLE {
+		if buffer.Info[end-1].complexCategory == indSM_ex_DOTTEDCIRCLE {
 			return
 			return
 		}
 		}
 	}
 	}
@@ -1102,23 +901,25 @@ func (indicPlan *indicShapePlan) initialReorderingSyllableIndic(font *Font, buff
 	}
 	}
 }
 }
 
 
-func (cs *complexShaperIndic) initialReorderingIndic(_ *otShapePlan, font *Font, buffer *Buffer) {
-	if debugMode >= 1 {
+func (cs *complexShaperIndic) initialReorderingIndic(_ *otShapePlan, font *Font, buffer *Buffer) bool {
+	if debugMode {
 		fmt.Println("INDIC - start reordering indic initial")
 		fmt.Println("INDIC - start reordering indic initial")
 	}
 	}
 
 
 	cs.plan.updateConsonantPositionsIndic(font, buffer)
 	cs.plan.updateConsonantPositionsIndic(font, buffer)
-	syllabicInsertDottedCircles(font, buffer, indicBrokenCluster,
-		otDOTTEDCIRCLE, otRepha, posEnd)
+	ret := syllabicInsertDottedCircles(font, buffer, indicBrokenCluster,
+		indSM_ex_DOTTEDCIRCLE, indSM_ex_Repha, posEnd)
 
 
 	iter, count := buffer.syllableIterator()
 	iter, count := buffer.syllableIterator()
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 		cs.plan.initialReorderingSyllableIndic(font, buffer, start, end)
 		cs.plan.initialReorderingSyllableIndic(font, buffer, start, end)
 	}
 	}
 
 
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("INDIC - end reordering indic initial")
 		fmt.Println("INDIC - end reordering indic initial")
 	}
 	}
+
+	return ret
 }
 }
 
 
 func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan, buffer *Buffer, start, end int) {
 func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan, buffer *Buffer, start, end int) {
@@ -1137,7 +938,7 @@ func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan,
 			if info[i].Glyph == viramaGlyph &&
 			if info[i].Glyph == viramaGlyph &&
 				info[i].ligated() && info[i].multiplied() {
 				info[i].ligated() && info[i].multiplied() {
 				/* This will make sure that this glyph passes isHalant() test. */
 				/* This will make sure that this glyph passes isHalant() test. */
-				info[i].complexCategory = otH
+				info[i].complexCategory = indSM_ex_H
 				info[i].clearLigatedAndMultiplied()
 				info[i].clearLigatedAndMultiplied()
 			}
 			}
 		}
 		}
@@ -1167,12 +968,17 @@ func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan,
 							for base < end && isHalant(&info[base]) {
 							for base < end && isHalant(&info[base]) {
 								base++
 								base++
 							}
 							}
-							info[base].complexAux = posBaseC
+							if base < end {
+								info[base].complexAux = posBaseC
+							}
 
 
 							tryPref = false
 							tryPref = false
 						}
 						}
 						break
 						break
 					}
 					}
+					if base == end {
+						break
+					}
 				}
 				}
 			}
 			}
 			/* For Malayalam, skip over unformed below- (but NOT post-) forms. */
 			/* For Malayalam, skip over unformed below- (but NOT post-) forms. */
@@ -1201,11 +1007,11 @@ func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan,
 			break
 			break
 		}
 		}
 	}
 	}
-	if base == end && start < base && isOneOf(&info[base-1], 1<<otZWJ) {
+	if base == end && start < base && isOneOf(&info[base-1], 1<<indSM_ex_ZWJ) {
 		base--
 		base--
 	}
 	}
 	if base < end {
 	if base < end {
-		for start < base && isOneOf(&info[base], 1<<otN|1<<otH) {
+		for start < base && isOneOf(&info[base], 1<<indSM_ex_N|1<<indSM_ex_H) {
 			base--
 			base--
 		}
 		}
 	}
 	}
@@ -1251,7 +1057,7 @@ func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan,
 		 */
 		 */
 		if buffer.Props.Script != language.Malayalam && buffer.Props.Script != language.Tamil {
 		if buffer.Props.Script != language.Malayalam && buffer.Props.Script != language.Tamil {
 		search:
 		search:
-			for newPos > start && !isOneOf(&info[newPos], 1<<otM|1<<otH) {
+			for newPos > start && !isOneOf(&info[newPos], 1<<indSM_ex_M|1<<indSM_ex_MPst|1<<indSM_ex_H) {
 				newPos--
 				newPos--
 			}
 			}
 			/* If we found no Halant we are done.
 			/* If we found no Halant we are done.
@@ -1260,7 +1066,7 @@ func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan,
 			if isHalant(&info[newPos]) && info[newPos].complexAux != posPreM {
 			if isHalant(&info[newPos]) && info[newPos].complexAux != posPreM {
 				if newPos+1 < end {
 				if newPos+1 < end {
 					/* . If ZWJ follows this halant, matra is NOT repositioned after this halant. */
 					/* . If ZWJ follows this halant, matra is NOT repositioned after this halant. */
-					if info[newPos+1].complexCategory == otZWJ {
+					if info[newPos+1].complexCategory == indSM_ex_ZWJ {
 						/* Keep searching. */
 						/* Keep searching. */
 						if newPos > start {
 						if newPos > start {
 							newPos--
 							newPos--
@@ -1290,7 +1096,7 @@ func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan,
 						base--
 						base--
 					}
 					}
 
 
-					if debugMode >= 2 {
+					if debugMode {
 						fmt.Printf("INDIC - matras: switching glyph %d to %d (and shifting between)", oldPos, newPos)
 						fmt.Printf("INDIC - matras: switching glyph %d to %d (and shifting between)", oldPos, newPos)
 					}
 					}
 
 
@@ -1334,7 +1140,7 @@ func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan,
 	*   to make it work without the reordering.
 	*   to make it work without the reordering.
 	 */
 	 */
 	if start+1 < end && info[start].complexAux == posRaToBecomeReph &&
 	if start+1 < end && info[start].complexAux == posRaToBecomeReph &&
-		(info[start].complexCategory == otRepha) != info[start].ligatedAndDidntMultiply() {
+		(info[start].complexCategory == indSM_ex_Repha) != info[start].ligatedAndDidntMultiply() {
 		var newRephPos int
 		var newRephPos int
 		rephPos := indicPlan.config.rephPos
 		rephPos := indicPlan.config.rephPos
 
 
@@ -1444,7 +1250,7 @@ func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan,
 			 */
 			 */
 			if !indicPlan.uniscribeBugCompatible && isHalant(&info[newRephPos]) {
 			if !indicPlan.uniscribeBugCompatible && isHalant(&info[newRephPos]) {
 				for i := base + 1; i < newRephPos; i++ {
 				for i := base + 1; i < newRephPos; i++ {
-					if info[i].complexCategory == otM {
+					if ic := info[i].complexCategory; ic == indSM_ex_M || ic == indSM_ex_MPst {
 						/* Ok, got it. */
 						/* Ok, got it. */
 						newRephPos--
 						newRephPos--
 					}
 					}
@@ -1457,7 +1263,7 @@ func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan,
 	reph_move:
 	reph_move:
 		{
 		{
 
 
-			if debugMode >= 2 {
+			if debugMode {
 				fmt.Printf("INDIC - reph: switching glyph %d to %d (and shifting between)", start, newRephPos)
 				fmt.Printf("INDIC - reph: switching glyph %d to %d (and shifting between)", start, newRephPos)
 			}
 			}
 
 
@@ -1505,7 +1311,7 @@ func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan,
 					* We want to position matra after them.
 					* We want to position matra after them.
 					 */
 					 */
 					if buffer.Props.Script != language.Malayalam && buffer.Props.Script != language.Tamil {
 					if buffer.Props.Script != language.Malayalam && buffer.Props.Script != language.Tamil {
-						for newPos > start && !isOneOf(&info[newPos-1], 1<<otM|1<<otH) {
+						for newPos > start && !isOneOf(&info[newPos-1], 1<<indSM_ex_M|1<<indSM_ex_MPst|1<<indSM_ex_H) {
 							newPos--
 							newPos--
 						}
 						}
 					}
 					}
@@ -1522,7 +1328,7 @@ func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan,
 						oldPos := i
 						oldPos := i
 						buffer.mergeClusters(newPos, oldPos+1)
 						buffer.mergeClusters(newPos, oldPos+1)
 
 
-						if debugMode >= 2 {
+						if debugMode {
 							fmt.Printf("INDIC - pre-base: switching glyph %d to %d (and shifting between)", oldPos, newPos)
 							fmt.Printf("INDIC - pre-base: switching glyph %d to %d (and shifting between)", oldPos, newPos)
 						}
 						}
 
 
@@ -1553,24 +1359,24 @@ func (indicPlan *indicShapePlan) finalReorderingSyllableIndic(plan *otShapePlan,
 
 
 	// Finish off the clusters and go home!
 	// Finish off the clusters and go home!
 	if indicPlan.uniscribeBugCompatible {
 	if indicPlan.uniscribeBugCompatible {
-		/* Uniscribe merges the entire syllable into a single cluster... Except for Tamil & Sinhala.
+		/* Uniscribe merges the entire syllable into a single cluster... Except for Tamil.
 		 * This means, half forms are submerged into the main consonant's cluster.
 		 * This means, half forms are submerged into the main consonant's cluster.
 		 * This is unnecessary, and makes cursor positioning harder, but that's what
 		 * This is unnecessary, and makes cursor positioning harder, but that's what
 		 * Uniscribe does. */
 		 * Uniscribe does. */
 		switch plan.props.Script {
 		switch plan.props.Script {
-		case language.Tamil, language.Sinhala:
+		case language.Tamil:
 		default:
 		default:
 			buffer.mergeClusters(start, end)
 			buffer.mergeClusters(start, end)
 		}
 		}
 	}
 	}
 }
 }
 
 
-func (indicPlan *indicShapePlan) finalReorderingIndic(plan *otShapePlan, font *Font, buffer *Buffer) {
+func (indicPlan *indicShapePlan) finalReorderingIndic(plan *otShapePlan, font *Font, buffer *Buffer) bool {
 	if len(buffer.Info) == 0 {
 	if len(buffer.Info) == 0 {
-		return
+		return false
 	}
 	}
 
 
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("INDIC - start reordering indic final")
 		fmt.Println("INDIC - start reordering indic final")
 	}
 	}
 
 
@@ -1579,13 +1385,17 @@ func (indicPlan *indicShapePlan) finalReorderingIndic(plan *otShapePlan, font *F
 		indicPlan.finalReorderingSyllableIndic(plan, buffer, start, end)
 		indicPlan.finalReorderingSyllableIndic(plan, buffer, start, end)
 	}
 	}
 
 
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("INDIC - end reordering indic final")
 		fmt.Println("INDIC - end reordering indic final")
 	}
 	}
+
+	return false
 }
 }
 
 
-func (complexShaperIndic) preprocessText(_ *otShapePlan, buffer *Buffer, _ *Font) {
-	preprocessTextVowelConstraints(buffer)
+func (ci complexShaperIndic) preprocessText(_ *otShapePlan, buffer *Buffer, _ *Font) {
+	if !ci.plan.uniscribeBugCompatible {
+		preprocessTextVowelConstraints(buffer)
+	}
 }
 }
 
 
 func (cs *complexShaperIndic) decompose(c *otNormalizeContext, ab rune) (rune, rune, bool) {
 func (cs *complexShaperIndic) decompose(c *otNormalizeContext, ab rune) (rune, rune, bool) {
@@ -1603,42 +1413,6 @@ func (cs *complexShaperIndic) decompose(c *otNormalizeContext, ab rune) (rune, r
 		 */
 		 */
 	}
 	}
 
 
-	if ab == 0x0DDA || (0x0DDC <= ab && ab <= 0x0DDE) {
-		/*
-		 * Sinhala split matras...  Let the fun begin.
-		 *
-		 * These four characters have Unicode decompositions.  However, Uniscribe
-		 * decomposes them "Khmer-style", that is, it uses the character itself to
-		 * get the second half.  The first half of all four decompositions is always
-		 * U+0DD9.
-		 *
-		 * Now, there are buggy fonts, namely, the widely used lklug.ttf, that are
-		 * broken with Uniscribe.  But we need to support them.  As such, we only
-		 * do the Uniscribe-style decomposition if the character is transformed into
-		 * its "sec.half" form by the 'pstf' feature.  Otherwise, we fall back to
-		 * Unicode decomposition.
-		 *
-		 * Note that we can't unconditionally use Unicode decomposition.  That would
-		 * break some other fonts, that are designed to work with Uniscribe, and
-		 * don't have positioning features for the Unicode-style decomposition.
-		 *
-		 * Argh...
-		 *
-		 * The Uniscribe behavior is now documented in the newly published Sinhala
-		 * spec in 2012:
-		 *
-		 *   https://docs.microsoft.com/en-us/typography/script-development/sinhala#shaping
-		 */
-
-		indicPlan := cs.plan
-		glyph, ok := c.font.face.NominalGlyph(ab)
-		if indicPlan.uniscribeBugCompatible ||
-			(ok && indicPlan.pstf.wouldSubstitute([]GID{glyph}, c.font)) {
-			/* Ok, safe to use Uniscribe-style decomposition. */
-			return 0x0DD9, ab, true
-		}
-	}
-
 	return uni.decompose(ab)
 	return uni.decompose(ab)
 }
 }
 
 

+ 400 - 379
vendor/github.com/go-text/typesetting/harfbuzz/ot_indic_machine.go

@@ -14,25 +14,28 @@ const (
 	indicNonIndicCluster
 	indicNonIndicCluster
 )
 )
 
 
-const indicSyllableMachine_ex_A = 10
-const indicSyllableMachine_ex_C = 1
-const indicSyllableMachine_ex_CM = 17
-const indicSyllableMachine_ex_CS = 19
-const indicSyllableMachine_ex_DOTTEDCIRCLE = 12
-const indicSyllableMachine_ex_H = 4
-const indicSyllableMachine_ex_M = 7
-const indicSyllableMachine_ex_N = 3
-const indicSyllableMachine_ex_PLACEHOLDER = 11
-const indicSyllableMachine_ex_RS = 13
-const indicSyllableMachine_ex_Ra = 16
-const indicSyllableMachine_ex_Repha = 15
-const indicSyllableMachine_ex_SM = 8
-const indicSyllableMachine_ex_Symbol = 18
-const indicSyllableMachine_ex_V = 2
-const indicSyllableMachine_ex_ZWJ = 6
-const indicSyllableMachine_ex_ZWNJ = 5
-
-var _indicSyllableMachine_actions []byte = []byte{
+const indSM_ex_A = 9
+const indSM_ex_C = 1
+const indSM_ex_CM = 16
+const indSM_ex_CS = 18
+const indSM_ex_DOTTEDCIRCLE = 11
+const indSM_ex_H = 4
+const indSM_ex_M = 7
+const indSM_ex_MPst = 13
+const indSM_ex_N = 3
+const indSM_ex_PLACEHOLDER = 10
+const indSM_ex_RS = 12
+const indSM_ex_Ra = 15
+const indSM_ex_Repha = 14
+const indSM_ex_SM = 8
+const indSM_ex_Symbol = 17
+const indSM_ex_V = 2
+const indSM_ex_VD = 9
+const indSM_ex_X = 0
+const indSM_ex_ZWJ = 6
+const indSM_ex_ZWNJ = 5
+
+var _indSM_actions []byte = []byte{
 	0, 1, 0, 1, 1, 1, 2, 1, 6,
 	0, 1, 0, 1, 1, 1, 2, 1, 6,
 	1, 7, 1, 8, 1, 9, 1, 10,
 	1, 7, 1, 8, 1, 9, 1, 10,
 	1, 11, 1, 12, 1, 13, 1, 14,
 	1, 11, 1, 12, 1, 13, 1, 14,
@@ -41,335 +44,349 @@ var _indicSyllableMachine_actions []byte = []byte{
 	5,
 	5,
 }
 }
 
 
-var _indicSyllableMachine_key_offsets []int16 = []int16{
-	0, 1, 6, 9, 13, 18, 19, 20,
-	25, 31, 36, 37, 40, 44, 49, 50,
-	51, 56, 62, 68, 74, 75, 78, 82,
-	87, 88, 89, 94, 99, 105, 106, 109,
-	113, 118, 119, 120, 125, 130, 134, 135,
-	152, 161, 169, 176, 182, 186, 189, 190,
-	192, 199, 205, 211, 218, 224, 229, 235,
-	239, 244, 248, 256, 265, 274, 282, 289,
-	295, 304, 312, 319, 325, 328, 329, 331,
-	338, 344, 351, 357, 362, 368, 372, 376,
-	381, 385, 393, 402, 407, 415, 423, 430,
-	436, 445, 451, 454, 455, 457, 464, 470,
-	477, 483, 488, 496, 502, 506, 510, 515,
-	519, 528, 534, 539, 548, 556, 563, 569,
-	578, 584, 587, 588, 590, 597, 603, 610,
-	616, 621, 629, 635, 639, 643, 648, 652,
-	666, 675, 688, 695, 698, 699, 701, 710,
-	715, 719, 722, 723, 725,
+var _indSM_key_offsets []int16 = []int16{
+	0, 1, 7, 12, 17, 18, 24, 31,
+	37, 38, 43, 48, 49, 55, 62, 69,
+	76, 77, 82, 87, 88, 94, 100, 107,
+	108, 113, 118, 119, 125, 131, 136, 137,
+	155, 165, 174, 182, 188, 192, 195, 196,
+	198, 205, 211, 217, 225, 232, 238, 242,
+	249, 253, 258, 262, 271, 281, 291, 300,
+	308, 314, 324, 333, 341, 347, 350, 351,
+	353, 360, 366, 374, 381, 387, 391, 398,
+	402, 406, 411, 415, 424, 434, 440, 449,
+	458, 466, 472, 482, 488, 491, 492, 494,
+	501, 507, 515, 522, 528, 532, 541, 548,
+	552, 556, 561, 565, 575, 582, 588, 598,
+	607, 615, 621, 631, 637, 640, 641, 643,
+	650, 656, 664, 671, 677, 681, 690, 697,
+	701, 705, 710, 714, 729, 739, 753, 761,
+	765, 769, 770, 772, 782, 787, 791, 794,
+	795, 797,
 }
 }
 
 
-var _indicSyllableMachine_trans_keys []byte = []byte{
-	8, 4, 7, 8, 5, 6, 7, 5,
-	6, 7, 8, 5, 6, 4, 7, 8,
-	5, 6, 6, 16, 4, 7, 8, 5,
-	6, 4, 7, 8, 13, 5, 6, 4,
-	7, 8, 5, 6, 8, 7, 5, 6,
-	7, 8, 5, 6, 4, 7, 8, 5,
-	6, 6, 16, 4, 7, 8, 5, 6,
+var _indSM_trans_keys []byte = []byte{
+	8, 4, 7, 8, 13, 5, 6, 7,
+	8, 13, 5, 6, 7, 8, 13, 5,
+	6, 13, 4, 7, 8, 13, 5, 6,
+	4, 7, 8, 12, 13, 5, 6, 4,
+	7, 8, 13, 5, 6, 8, 7, 8,
+	13, 5, 6, 7, 8, 13, 5, 6,
+	13, 4, 7, 8, 13, 5, 6, 4,
+	7, 8, 12, 13, 5, 6, 4, 7,
+	8, 12, 13, 5, 6, 4, 7, 8,
+	12, 13, 5, 6, 8, 7, 8, 13,
+	5, 6, 7, 8, 13, 5, 6, 13,
 	4, 7, 8, 13, 5, 6, 4, 7,
 	4, 7, 8, 13, 5, 6, 4, 7,
-	8, 13, 5, 6, 4, 7, 8, 13,
-	5, 6, 8, 7, 5, 6, 7, 8,
-	5, 6, 4, 7, 8, 5, 6, 6,
-	16, 4, 7, 8, 5, 6, 4, 7,
-	8, 5, 6, 4, 7, 8, 13, 5,
-	6, 8, 7, 5, 6, 7, 8, 5,
-	6, 4, 7, 8, 5, 6, 6, 16,
-	4, 7, 8, 5, 6, 4, 7, 8,
-	5, 6, 7, 8, 5, 6, 8, 1,
-	2, 3, 4, 5, 6, 7, 8, 10,
-	13, 15, 16, 17, 18, 19, 11, 12,
-	3, 4, 5, 6, 7, 8, 10, 13,
-	17, 3, 4, 7, 8, 10, 17, 5,
-	6, 4, 7, 8, 10, 17, 5, 6,
-	1, 5, 6, 8, 10, 16, 8, 10,
-	5, 6, 5, 8, 10, 10, 5, 10,
-	1, 3, 8, 10, 16, 5, 6, 1,
-	8, 10, 16, 5, 6, 1, 5, 6,
-	8, 10, 16, 3, 4, 5, 6, 7,
-	8, 10, 4, 5, 6, 7, 8, 10,
-	7, 8, 10, 5, 6, 4, 7, 8,
-	10, 5, 6, 5, 6, 8, 10, 3,
-	8, 10, 5, 6, 5, 6, 8, 10,
-	3, 4, 7, 8, 10, 17, 5, 6,
-	3, 4, 5, 6, 7, 8, 10, 13,
-	17, 3, 4, 5, 6, 7, 8, 10,
-	13, 17, 3, 4, 5, 6, 7, 8,
-	10, 17, 4, 5, 6, 7, 8, 10,
-	17, 1, 5, 6, 8, 10, 16, 3,
-	4, 5, 6, 7, 8, 10, 13, 17,
-	3, 4, 7, 8, 10, 17, 5, 6,
-	4, 7, 8, 10, 17, 5, 6, 1,
-	5, 6, 8, 10, 16, 5, 8, 10,
-	10, 5, 10, 1, 3, 8, 10, 16,
-	5, 6, 1, 8, 10, 16, 5, 6,
-	3, 4, 5, 6, 7, 8, 10, 4,
-	5, 6, 7, 8, 10, 7, 8, 10,
-	5, 6, 4, 7, 8, 10, 5, 6,
-	5, 6, 8, 10, 8, 10, 5, 6,
-	3, 8, 10, 5, 6, 5, 6, 8,
-	10, 3, 4, 7, 8, 10, 17, 5,
-	6, 3, 4, 5, 6, 7, 8, 10,
-	13, 17, 4, 7, 8, 5, 6, 3,
-	4, 5, 6, 7, 8, 10, 17, 3,
-	4, 7, 8, 10, 17, 5, 6, 4,
-	7, 8, 10, 17, 5, 6, 1, 5,
-	6, 8, 10, 16, 3, 4, 5, 6,
-	7, 8, 10, 13, 17, 1, 5, 6,
-	8, 10, 16, 5, 8, 10, 10, 5,
-	10, 1, 3, 8, 10, 16, 5, 6,
-	1, 8, 10, 16, 5, 6, 3, 4,
-	5, 6, 7, 8, 10, 4, 5, 6,
-	7, 8, 10, 7, 8, 10, 5, 6,
-	3, 4, 7, 8, 10, 17, 5, 6,
-	4, 7, 8, 10, 5, 6, 5, 6,
-	8, 10, 8, 10, 5, 6, 3, 8,
-	10, 5, 6, 5, 6, 8, 10, 3,
-	4, 5, 6, 7, 8, 10, 13, 17,
-	4, 7, 8, 13, 5, 6, 4, 7,
-	8, 5, 6, 3, 4, 5, 6, 7,
-	8, 10, 13, 17, 3, 4, 7, 8,
-	10, 17, 5, 6, 4, 7, 8, 10,
-	17, 5, 6, 1, 5, 6, 8, 10,
-	16, 3, 4, 5, 6, 7, 8, 10,
-	13, 17, 1, 5, 6, 8, 10, 16,
-	5, 8, 10, 10, 5, 10, 1, 3,
-	8, 10, 16, 5, 6, 1, 8, 10,
-	16, 5, 6, 3, 4, 5, 6, 7,
-	8, 10, 4, 5, 6, 7, 8, 10,
-	7, 8, 10, 5, 6, 3, 4, 7,
-	8, 10, 17, 5, 6, 4, 7, 8,
-	10, 5, 6, 5, 6, 8, 10, 8,
-	10, 5, 6, 3, 8, 10, 5, 6,
-	5, 6, 8, 10, 1, 2, 3, 4,
-	5, 6, 7, 8, 10, 13, 16, 17,
-	11, 12, 3, 4, 5, 6, 7, 8,
-	10, 13, 17, 1, 2, 3, 4, 5,
-	6, 7, 8, 10, 12, 13, 16, 17,
-	4, 7, 8, 10, 13, 5, 6, 5,
-	8, 10, 10, 5, 10, 1, 3, 4,
-	7, 8, 10, 16, 5, 6, 3, 8,
-	10, 5, 6, 8, 10, 5, 6, 5,
-	8, 10, 10, 5, 10, 1, 11, 16,
+	8, 13, 5, 6, 4, 7, 8, 12,
+	13, 5, 6, 8, 7, 8, 13, 5,
+	6, 7, 8, 13, 5, 6, 13, 4,
+	7, 8, 13, 5, 6, 4, 7, 8,
+	13, 5, 6, 7, 8, 13, 5, 6,
+	8, 1, 2, 3, 4, 5, 6, 7,
+	8, 9, 12, 13, 14, 15, 16, 17,
+	18, 10, 11, 3, 4, 5, 6, 7,
+	8, 9, 12, 13, 16, 3, 4, 7,
+	8, 9, 13, 16, 5, 6, 4, 7,
+	8, 9, 13, 16, 5, 6, 1, 5,
+	6, 8, 9, 15, 8, 9, 5, 6,
+	5, 8, 9, 9, 5, 9, 1, 3,
+	8, 9, 15, 5, 6, 1, 8, 9,
+	15, 5, 6, 1, 5, 6, 8, 9,
+	15, 3, 4, 7, 8, 9, 13, 5,
+	6, 4, 7, 8, 9, 13, 5, 6,
+	7, 8, 9, 13, 5, 6, 5, 8,
+	9, 13, 4, 7, 8, 9, 13, 5,
+	6, 5, 6, 8, 9, 3, 8, 9,
+	5, 6, 5, 6, 8, 9, 3, 4,
+	7, 8, 9, 13, 16, 5, 6, 3,
+	4, 5, 6, 7, 8, 9, 12, 13,
+	16, 3, 4, 5, 6, 7, 8, 9,
+	12, 13, 16, 3, 4, 5, 6, 7,
+	8, 9, 13, 16, 4, 5, 6, 7,
+	8, 9, 13, 16, 1, 5, 6, 8,
+	9, 15, 3, 4, 5, 6, 7, 8,
+	9, 12, 13, 16, 3, 4, 7, 8,
+	9, 13, 16, 5, 6, 4, 7, 8,
+	9, 13, 16, 5, 6, 1, 5, 6,
+	8, 9, 15, 5, 8, 9, 9, 5,
+	9, 1, 3, 8, 9, 15, 5, 6,
+	1, 8, 9, 15, 5, 6, 3, 4,
+	7, 8, 9, 13, 5, 6, 4, 7,
+	8, 9, 13, 5, 6, 7, 8, 9,
+	13, 5, 6, 5, 8, 9, 13, 4,
+	7, 8, 9, 13, 5, 6, 5, 6,
+	8, 9, 8, 9, 5, 6, 3, 8,
+	9, 5, 6, 5, 6, 8, 9, 3,
+	4, 7, 8, 9, 13, 16, 5, 6,
+	3, 4, 5, 6, 7, 8, 9, 12,
+	13, 16, 4, 7, 8, 13, 5, 6,
+	3, 4, 5, 6, 7, 8, 9, 13,
+	16, 3, 4, 7, 8, 9, 13, 16,
+	5, 6, 4, 7, 8, 9, 13, 16,
+	5, 6, 1, 5, 6, 8, 9, 15,
+	3, 4, 5, 6, 7, 8, 9, 12,
+	13, 16, 1, 5, 6, 8, 9, 15,
+	5, 8, 9, 9, 5, 9, 1, 3,
+	8, 9, 15, 5, 6, 1, 8, 9,
+	15, 5, 6, 3, 4, 7, 8, 9,
+	13, 5, 6, 4, 7, 8, 9, 13,
+	5, 6, 7, 8, 9, 13, 5, 6,
+	5, 8, 9, 13, 3, 4, 7, 8,
+	9, 13, 16, 5, 6, 4, 7, 8,
+	9, 13, 5, 6, 5, 6, 8, 9,
+	8, 9, 5, 6, 3, 8, 9, 5,
+	6, 5, 6, 8, 9, 3, 4, 5,
+	6, 7, 8, 9, 12, 13, 16, 4,
+	7, 8, 12, 13, 5, 6, 4, 7,
+	8, 13, 5, 6, 3, 4, 5, 6,
+	7, 8, 9, 12, 13, 16, 3, 4,
+	7, 8, 9, 13, 16, 5, 6, 4,
+	7, 8, 9, 13, 16, 5, 6, 1,
+	5, 6, 8, 9, 15, 3, 4, 5,
+	6, 7, 8, 9, 12, 13, 16, 1,
+	5, 6, 8, 9, 15, 5, 8, 9,
+	9, 5, 9, 1, 3, 8, 9, 15,
+	5, 6, 1, 8, 9, 15, 5, 6,
+	3, 4, 7, 8, 9, 13, 5, 6,
+	4, 7, 8, 9, 13, 5, 6, 7,
+	8, 9, 13, 5, 6, 5, 8, 9,
+	13, 3, 4, 7, 8, 9, 13, 16,
+	5, 6, 4, 7, 8, 9, 13, 5,
+	6, 5, 6, 8, 9, 8, 9, 5,
+	6, 3, 8, 9, 5, 6, 5, 6,
+	8, 9, 1, 2, 3, 4, 5, 6,
+	7, 8, 9, 12, 13, 15, 16, 10,
+	11, 3, 4, 5, 6, 7, 8, 9,
+	12, 13, 16, 1, 2, 3, 4, 5,
+	6, 7, 8, 9, 11, 12, 13, 15,
+	16, 4, 7, 8, 9, 12, 13, 5,
+	6, 5, 8, 9, 13, 5, 8, 9,
+	13, 9, 5, 9, 1, 3, 4, 7,
+	8, 9, 13, 15, 5, 6, 3, 8,
+	9, 5, 6, 8, 9, 5, 6, 5,
+	8, 9, 9, 5, 9, 1, 10, 15,
 }
 }
 
 
-var _indicSyllableMachine_single_lengths []byte = []byte{
-	1, 3, 1, 2, 3, 1, 1, 3,
-	4, 3, 1, 1, 2, 3, 1, 1,
-	3, 4, 4, 4, 1, 1, 2, 3,
-	1, 1, 3, 3, 4, 1, 1, 2,
-	3, 1, 1, 3, 3, 2, 1, 15,
-	9, 6, 5, 6, 2, 3, 1, 2,
-	5, 4, 6, 7, 6, 3, 4, 4,
-	3, 4, 6, 9, 9, 8, 7, 6,
-	9, 6, 5, 6, 3, 1, 2, 5,
-	4, 7, 6, 3, 4, 4, 2, 3,
-	4, 6, 9, 3, 8, 6, 5, 6,
-	9, 6, 3, 1, 2, 5, 4, 7,
-	6, 3, 6, 4, 4, 2, 3, 4,
-	9, 4, 3, 9, 6, 5, 6, 9,
-	6, 3, 1, 2, 5, 4, 7, 6,
-	3, 6, 4, 4, 2, 3, 4, 12,
-	9, 13, 5, 3, 1, 2, 7, 3,
-	2, 3, 1, 2, 3,
+var _indSM_single_lengths []byte = []byte{
+	1, 4, 3, 3, 1, 4, 5, 4,
+	1, 3, 3, 1, 4, 5, 5, 5,
+	1, 3, 3, 1, 4, 4, 5, 1,
+	3, 3, 1, 4, 4, 3, 1, 16,
+	10, 7, 6, 6, 2, 3, 1, 2,
+	5, 4, 6, 6, 5, 4, 4, 5,
+	4, 3, 4, 7, 10, 10, 9, 8,
+	6, 10, 7, 6, 6, 3, 1, 2,
+	5, 4, 6, 5, 4, 4, 5, 4,
+	2, 3, 4, 7, 10, 4, 9, 7,
+	6, 6, 10, 6, 3, 1, 2, 5,
+	4, 6, 5, 4, 4, 7, 5, 4,
+	2, 3, 4, 10, 5, 4, 10, 7,
+	6, 6, 10, 6, 3, 1, 2, 5,
+	4, 6, 5, 4, 4, 7, 5, 4,
+	2, 3, 4, 13, 10, 14, 6, 4,
+	4, 1, 2, 8, 3, 2, 3, 1,
+	2, 3,
 }
 }
 
 
-var _indicSyllableMachine_range_lengths []byte = []byte{
-	0, 1, 1, 1, 1, 0, 0, 1,
-	1, 1, 0, 1, 1, 1, 0, 0,
-	1, 1, 1, 1, 0, 1, 1, 1,
-	0, 0, 1, 1, 1, 0, 1, 1,
-	1, 0, 0, 1, 1, 1, 0, 1,
+var _indSM_range_lengths []byte = []byte{
+	0, 1, 1, 1, 0, 1, 1, 1,
+	0, 1, 1, 0, 1, 1, 1, 1,
+	0, 1, 1, 0, 1, 1, 1, 0,
+	1, 1, 0, 1, 1, 1, 0, 1,
 	0, 1, 1, 0, 1, 0, 0, 0,
 	0, 1, 1, 0, 1, 0, 0, 0,
-	1, 1, 0, 0, 0, 1, 1, 0,
-	1, 0, 1, 0, 0, 0, 0, 0,
-	0, 1, 1, 0, 0, 0, 0, 1,
-	1, 0, 0, 1, 1, 0, 1, 1,
-	0, 1, 0, 1, 0, 1, 1, 0,
-	0, 0, 0, 0, 0, 1, 1, 0,
-	0, 1, 1, 1, 0, 1, 1, 0,
-	0, 1, 1, 0, 1, 1, 0, 0,
-	0, 0, 0, 0, 1, 1, 0, 0,
-	1, 1, 1, 0, 1, 1, 0, 1,
-	0, 0, 1, 0, 0, 0, 1, 1,
-	1, 0, 0, 0, 0,
+	1, 1, 0, 1, 1, 1, 0, 1,
+	0, 1, 0, 1, 0, 0, 0, 0,
+	0, 0, 1, 1, 0, 0, 0, 0,
+	1, 1, 1, 1, 1, 0, 1, 0,
+	1, 1, 0, 1, 0, 1, 0, 1,
+	1, 0, 0, 0, 0, 0, 0, 1,
+	1, 1, 1, 1, 0, 1, 1, 0,
+	1, 1, 0, 0, 1, 1, 0, 1,
+	1, 0, 0, 0, 0, 0, 0, 1,
+	1, 1, 1, 1, 0, 1, 1, 0,
+	1, 1, 0, 1, 0, 0, 1, 0,
+	0, 0, 0, 1, 1, 1, 0, 0,
+	0, 0,
 }
 }
 
 
-var _indicSyllableMachine_index_offsets []int16 = []int16{
-	0, 2, 7, 10, 14, 19, 21, 23,
-	28, 34, 39, 41, 44, 48, 53, 55,
-	57, 62, 68, 74, 80, 82, 85, 89,
-	94, 96, 98, 103, 108, 114, 116, 119,
-	123, 128, 130, 132, 137, 142, 146, 148,
-	165, 175, 183, 190, 197, 201, 205, 207,
-	210, 217, 223, 230, 238, 245, 250, 256,
-	261, 266, 271, 279, 289, 299, 308, 316,
-	323, 333, 341, 348, 355, 359, 361, 364,
-	371, 377, 385, 392, 397, 403, 408, 412,
-	417, 422, 430, 440, 445, 454, 462, 469,
-	476, 486, 493, 497, 499, 502, 509, 515,
-	523, 530, 535, 543, 549, 554, 558, 563,
-	568, 578, 584, 589, 599, 607, 614, 621,
-	631, 638, 642, 644, 647, 654, 660, 668,
-	675, 680, 688, 694, 699, 703, 708, 713,
-	727, 737, 751, 758, 762, 764, 767, 776,
-	781, 785, 789, 791, 794,
+var _indSM_index_offsets []int16 = []int16{
+	0, 2, 8, 13, 18, 20, 26, 33,
+	39, 41, 46, 51, 53, 59, 66, 73,
+	80, 82, 87, 92, 94, 100, 106, 113,
+	115, 120, 125, 127, 133, 139, 144, 146,
+	164, 175, 184, 192, 199, 203, 207, 209,
+	212, 219, 225, 232, 240, 247, 253, 258,
+	265, 270, 275, 280, 289, 300, 311, 321,
+	330, 337, 348, 357, 365, 372, 376, 378,
+	381, 388, 394, 402, 409, 415, 420, 427,
+	432, 436, 441, 446, 455, 466, 472, 482,
+	491, 499, 506, 517, 524, 528, 530, 533,
+	540, 546, 554, 561, 567, 572, 581, 588,
+	593, 597, 602, 607, 618, 625, 631, 642,
+	651, 659, 666, 677, 684, 688, 690, 693,
+	700, 706, 714, 721, 727, 732, 741, 748,
+	753, 757, 762, 767, 782, 793, 808, 816,
+	821, 826, 828, 831, 841, 846, 850, 854,
+	856, 859,
 }
 }
 
 
-var _indicSyllableMachine_indicies []byte = []byte{
-	1, 0, 2, 4, 1, 3, 0, 4,
-	3, 0, 4, 1, 3, 0, 5, 4,
-	1, 3, 0, 6, 0, 7, 0, 8,
-	4, 1, 3, 0, 2, 4, 1, 9,
-	3, 0, 11, 13, 14, 12, 10, 14,
-	10, 13, 12, 10, 13, 14, 12, 10,
-	15, 13, 14, 12, 10, 16, 10, 17,
-	10, 18, 13, 14, 12, 10, 11, 13,
-	14, 19, 12, 10, 11, 13, 14, 20,
-	12, 10, 22, 24, 25, 26, 23, 21,
-	25, 21, 24, 23, 27, 24, 25, 23,
-	21, 28, 24, 25, 23, 21, 29, 21,
-	30, 21, 22, 24, 25, 23, 21, 31,
-	24, 25, 23, 21, 33, 35, 36, 37,
-	34, 32, 36, 32, 35, 34, 32, 35,
-	36, 34, 32, 38, 35, 36, 34, 32,
-	39, 32, 40, 32, 33, 35, 36, 34,
-	32, 41, 35, 36, 34, 32, 24, 1,
-	23, 0, 43, 42, 45, 46, 47, 48,
-	49, 50, 24, 25, 51, 26, 53, 54,
-	55, 56, 57, 52, 44, 59, 60, 61,
-	62, 4, 1, 63, 9, 64, 58, 65,
-	60, 4, 1, 63, 64, 66, 58, 60,
-	4, 1, 63, 64, 66, 58, 45, 67,
-	68, 1, 63, 45, 58, 1, 63, 69,
-	58, 63, 70, 63, 58, 63, 58, 63,
-	63, 58, 45, 71, 1, 63, 45, 69,
-	58, 45, 1, 63, 45, 69, 58, 45,
-	69, 68, 1, 63, 45, 58, 72, 7,
-	73, 74, 4, 1, 63, 58, 7, 73,
-	74, 4, 1, 63, 58, 4, 1, 63,
-	73, 58, 75, 4, 1, 63, 76, 58,
-	67, 77, 1, 63, 58, 67, 1, 63,
-	69, 58, 69, 77, 1, 63, 58, 59,
-	60, 4, 1, 63, 64, 66, 58, 59,
-	60, 61, 66, 4, 1, 63, 9, 64,
-	58, 79, 80, 81, 82, 13, 14, 83,
-	20, 84, 78, 85, 80, 86, 82, 13,
-	14, 83, 84, 78, 80, 86, 82, 13,
-	14, 83, 84, 78, 87, 88, 89, 14,
-	83, 87, 78, 90, 80, 91, 92, 13,
-	14, 83, 19, 84, 78, 93, 80, 13,
-	14, 83, 84, 86, 78, 80, 13, 14,
-	83, 84, 86, 78, 87, 94, 89, 14,
-	83, 87, 78, 83, 95, 83, 78, 83,
-	78, 83, 83, 78, 87, 96, 14, 83,
-	87, 94, 78, 87, 14, 83, 87, 94,
-	78, 97, 17, 98, 99, 13, 14, 83,
-	78, 17, 98, 99, 13, 14, 83, 78,
-	13, 14, 83, 98, 78, 100, 13, 14,
-	83, 101, 78, 88, 102, 14, 83, 78,
-	14, 83, 94, 78, 88, 14, 83, 94,
-	78, 94, 102, 14, 83, 78, 90, 80,
-	13, 14, 83, 84, 86, 78, 90, 80,
-	91, 86, 13, 14, 83, 19, 84, 78,
-	11, 13, 14, 12, 78, 79, 80, 86,
-	82, 13, 14, 83, 84, 78, 104, 48,
-	24, 25, 51, 55, 105, 103, 48, 24,
-	25, 51, 55, 105, 103, 106, 107, 108,
-	25, 51, 106, 103, 47, 48, 109, 110,
-	24, 25, 51, 26, 55, 103, 106, 111,
-	108, 25, 51, 106, 103, 51, 112, 51,
-	103, 51, 103, 51, 51, 103, 106, 113,
-	25, 51, 106, 111, 103, 106, 25, 51,
-	106, 111, 103, 114, 30, 115, 116, 24,
-	25, 51, 103, 30, 115, 116, 24, 25,
-	51, 103, 24, 25, 51, 115, 103, 47,
-	48, 24, 25, 51, 55, 105, 103, 117,
-	24, 25, 51, 118, 103, 107, 119, 25,
-	51, 103, 25, 51, 111, 103, 107, 25,
-	51, 111, 103, 111, 119, 25, 51, 103,
-	47, 48, 109, 105, 24, 25, 51, 26,
-	55, 103, 22, 24, 25, 26, 23, 120,
-	22, 24, 25, 23, 120, 122, 123, 124,
-	125, 35, 36, 126, 37, 127, 121, 128,
-	123, 35, 36, 126, 127, 125, 121, 123,
-	35, 36, 126, 127, 125, 121, 129, 130,
-	131, 36, 126, 129, 121, 122, 123, 124,
-	52, 35, 36, 126, 37, 127, 121, 129,
-	132, 131, 36, 126, 129, 121, 126, 133,
-	126, 121, 126, 121, 126, 126, 121, 129,
-	134, 36, 126, 129, 132, 121, 129, 36,
-	126, 129, 132, 121, 135, 40, 136, 137,
-	35, 36, 126, 121, 40, 136, 137, 35,
-	36, 126, 121, 35, 36, 126, 136, 121,
-	122, 123, 35, 36, 126, 127, 125, 121,
-	138, 35, 36, 126, 139, 121, 130, 140,
-	36, 126, 121, 36, 126, 132, 121, 130,
-	36, 126, 132, 121, 132, 140, 36, 126,
-	121, 45, 46, 47, 48, 109, 105, 24,
-	25, 51, 26, 45, 55, 52, 103, 59,
-	141, 61, 62, 4, 1, 63, 9, 64,
-	58, 45, 46, 47, 48, 142, 143, 24,
-	144, 145, 52, 26, 45, 55, 58, 22,
-	24, 144, 63, 26, 146, 58, 145, 147,
-	145, 58, 145, 58, 145, 145, 58, 45,
-	71, 22, 24, 144, 63, 45, 146, 58,
-	149, 43, 151, 150, 148, 43, 151, 150,
-	148, 151, 152, 151, 148, 151, 148, 151,
-	151, 148, 45, 52, 45, 120,
+var _indSM_indicies []byte = []byte{
+	1, 0, 2, 4, 5, 4, 3, 0,
+	4, 6, 4, 3, 0, 4, 5, 4,
+	3, 0, 4, 0, 7, 4, 5, 4,
+	3, 0, 2, 4, 5, 8, 4, 3,
+	0, 10, 12, 13, 12, 11, 9, 14,
+	9, 12, 15, 12, 11, 9, 12, 13,
+	12, 11, 9, 12, 9, 16, 12, 13,
+	12, 11, 9, 10, 12, 13, 17, 12,
+	11, 9, 10, 12, 13, 18, 12, 11,
+	9, 20, 22, 23, 24, 22, 21, 19,
+	25, 19, 22, 27, 22, 21, 26, 22,
+	23, 22, 21, 19, 22, 26, 20, 22,
+	23, 22, 21, 19, 28, 22, 23, 22,
+	21, 19, 30, 32, 33, 34, 32, 31,
+	29, 35, 29, 32, 36, 32, 31, 29,
+	32, 33, 32, 31, 29, 32, 29, 30,
+	32, 33, 32, 31, 29, 37, 32, 33,
+	32, 31, 29, 22, 38, 22, 21, 0,
+	40, 39, 42, 43, 44, 45, 46, 47,
+	22, 23, 48, 24, 22, 50, 51, 52,
+	53, 54, 49, 41, 56, 57, 58, 59,
+	4, 5, 60, 8, 4, 61, 55, 62,
+	57, 4, 5, 60, 4, 61, 63, 55,
+	57, 4, 5, 60, 4, 61, 63, 55,
+	42, 64, 65, 1, 60, 42, 55, 1,
+	60, 66, 55, 60, 67, 60, 55, 60,
+	55, 60, 60, 55, 42, 68, 1, 60,
+	42, 66, 55, 42, 1, 60, 42, 66,
+	55, 42, 66, 65, 1, 60, 42, 55,
+	69, 70, 4, 5, 60, 4, 71, 55,
+	70, 4, 5, 60, 4, 71, 55, 4,
+	5, 60, 4, 71, 55, 60, 67, 60,
+	4, 55, 72, 4, 5, 60, 4, 73,
+	55, 64, 74, 1, 60, 55, 64, 1,
+	60, 66, 55, 66, 74, 1, 60, 55,
+	56, 57, 4, 5, 60, 4, 61, 63,
+	55, 56, 57, 58, 63, 4, 5, 60,
+	8, 4, 61, 55, 76, 77, 78, 79,
+	12, 13, 80, 18, 12, 81, 75, 82,
+	77, 83, 79, 12, 13, 80, 12, 81,
+	75, 77, 83, 79, 12, 13, 80, 12,
+	81, 75, 84, 85, 86, 14, 80, 84,
+	75, 87, 77, 88, 89, 12, 13, 80,
+	17, 12, 81, 75, 90, 77, 12, 13,
+	80, 12, 81, 83, 75, 77, 12, 13,
+	80, 12, 81, 83, 75, 84, 91, 86,
+	14, 80, 84, 75, 80, 92, 80, 75,
+	80, 75, 80, 80, 75, 84, 93, 14,
+	80, 84, 91, 75, 84, 14, 80, 84,
+	91, 75, 94, 95, 12, 13, 80, 12,
+	96, 75, 95, 12, 13, 80, 12, 96,
+	75, 12, 13, 80, 12, 96, 75, 80,
+	92, 80, 12, 75, 97, 12, 13, 80,
+	12, 98, 75, 85, 99, 14, 80, 75,
+	14, 80, 91, 75, 85, 14, 80, 91,
+	75, 91, 99, 14, 80, 75, 87, 77,
+	12, 13, 80, 12, 81, 83, 75, 87,
+	77, 88, 83, 12, 13, 80, 17, 12,
+	81, 75, 10, 12, 13, 12, 11, 75,
+	76, 77, 83, 79, 12, 13, 80, 12,
+	81, 75, 101, 45, 22, 23, 48, 22,
+	52, 102, 100, 45, 22, 23, 48, 22,
+	52, 102, 100, 103, 104, 105, 25, 48,
+	103, 100, 44, 45, 106, 107, 22, 23,
+	48, 24, 22, 52, 100, 103, 108, 105,
+	25, 48, 103, 100, 48, 109, 48, 100,
+	48, 100, 48, 48, 100, 103, 110, 25,
+	48, 103, 108, 100, 103, 25, 48, 103,
+	108, 100, 111, 112, 22, 23, 48, 22,
+	113, 100, 112, 22, 23, 48, 22, 113,
+	100, 22, 23, 48, 22, 113, 100, 48,
+	109, 48, 22, 100, 44, 45, 22, 23,
+	48, 22, 52, 102, 100, 114, 22, 23,
+	48, 22, 115, 100, 104, 116, 25, 48,
+	100, 25, 48, 108, 100, 104, 25, 48,
+	108, 100, 108, 116, 25, 48, 100, 44,
+	45, 106, 102, 22, 23, 48, 24, 22,
+	52, 100, 20, 22, 23, 24, 22, 21,
+	117, 20, 22, 23, 22, 21, 117, 119,
+	120, 121, 122, 32, 33, 123, 34, 32,
+	124, 118, 125, 120, 32, 33, 123, 32,
+	124, 122, 118, 120, 32, 33, 123, 32,
+	124, 122, 118, 126, 127, 128, 35, 123,
+	126, 118, 119, 120, 121, 49, 32, 33,
+	123, 34, 32, 124, 118, 126, 129, 128,
+	35, 123, 126, 118, 123, 130, 123, 118,
+	123, 118, 123, 123, 118, 126, 131, 35,
+	123, 126, 129, 118, 126, 35, 123, 126,
+	129, 118, 132, 133, 32, 33, 123, 32,
+	134, 118, 133, 32, 33, 123, 32, 134,
+	118, 32, 33, 123, 32, 134, 118, 123,
+	130, 123, 32, 118, 119, 120, 32, 33,
+	123, 32, 124, 122, 118, 135, 32, 33,
+	123, 32, 136, 118, 127, 137, 35, 123,
+	118, 35, 123, 129, 118, 127, 35, 123,
+	129, 118, 129, 137, 35, 123, 118, 42,
+	43, 44, 45, 106, 102, 22, 23, 48,
+	24, 22, 42, 52, 49, 100, 56, 138,
+	58, 59, 4, 5, 60, 8, 4, 61,
+	55, 42, 43, 44, 45, 139, 140, 22,
+	141, 142, 49, 24, 22, 42, 52, 55,
+	20, 22, 141, 60, 24, 22, 143, 55,
+	60, 67, 60, 22, 55, 142, 144, 142,
+	22, 55, 142, 55, 142, 142, 55, 42,
+	68, 20, 22, 141, 60, 22, 42, 143,
+	55, 146, 40, 148, 147, 145, 40, 148,
+	147, 145, 148, 149, 148, 145, 148, 145,
+	148, 148, 145, 42, 49, 42, 117,
 }
 }
 
 
-var _indicSyllableMachine_trans_targs []byte = []byte{
-	39, 45, 50, 2, 51, 5, 6, 53,
-	57, 58, 39, 67, 11, 73, 68, 14,
-	15, 75, 80, 81, 84, 39, 89, 21,
-	95, 90, 98, 39, 24, 25, 97, 103,
-	39, 112, 30, 118, 113, 121, 33, 34,
-	120, 126, 39, 137, 39, 40, 60, 85,
-	87, 105, 106, 91, 107, 127, 128, 99,
-	135, 140, 39, 41, 43, 8, 59, 46,
-	54, 42, 1, 44, 48, 0, 47, 49,
-	52, 3, 4, 55, 7, 56, 39, 61,
-	63, 18, 83, 69, 76, 62, 9, 64,
-	78, 71, 65, 17, 82, 66, 10, 70,
-	72, 74, 12, 13, 77, 16, 79, 39,
-	86, 26, 88, 101, 93, 19, 104, 20,
-	92, 94, 96, 22, 23, 100, 27, 102,
-	39, 39, 108, 110, 28, 35, 114, 122,
-	109, 111, 124, 116, 29, 115, 117, 119,
-	31, 32, 123, 36, 125, 129, 130, 134,
-	131, 132, 37, 133, 39, 136, 38, 138,
-	139,
+var _indSM_trans_targs []byte = []byte{
+	31, 37, 42, 2, 43, 46, 4, 50,
+	51, 31, 60, 9, 66, 69, 61, 11,
+	74, 75, 78, 31, 83, 17, 89, 92,
+	93, 84, 31, 19, 98, 31, 107, 24,
+	113, 116, 117, 108, 26, 122, 127, 31,
+	134, 31, 32, 53, 79, 81, 100, 101,
+	85, 102, 123, 124, 94, 132, 137, 31,
+	33, 35, 6, 52, 38, 47, 34, 1,
+	36, 40, 0, 39, 41, 44, 45, 3,
+	48, 5, 49, 31, 54, 56, 14, 77,
+	62, 70, 55, 7, 57, 72, 64, 58,
+	13, 76, 59, 8, 63, 65, 67, 68,
+	10, 71, 12, 73, 31, 80, 20, 82,
+	96, 87, 15, 99, 16, 86, 88, 90,
+	91, 18, 95, 21, 97, 31, 31, 103,
+	105, 22, 27, 109, 118, 104, 106, 120,
+	111, 23, 110, 112, 114, 115, 25, 119,
+	28, 121, 125, 126, 131, 128, 129, 29,
+	130, 31, 133, 30, 135, 136,
 }
 }
 
 
-var _indicSyllableMachine_trans_actions []byte = []byte{
+var _indSM_trans_actions []byte = []byte{
 	21, 0, 5, 0, 5, 0, 0, 5,
 	21, 0, 5, 0, 5, 0, 0, 5,
-	5, 5, 23, 5, 0, 5, 0, 0,
-	0, 5, 5, 5, 5, 29, 5, 0,
-	36, 0, 36, 31, 0, 0, 36, 5,
-	25, 5, 0, 5, 0, 5, 0, 0,
-	5, 5, 27, 0, 7, 5, 5, 36,
-	0, 39, 39, 0, 5, 36, 5, 36,
-	5, 0, 9, 5, 0, 0, 5, 0,
-	5, 5, 0, 5, 5, 0, 0, 5,
-	5, 0, 0, 0, 0, 5, 11, 5,
-	0, 0, 5, 0, 5, 5, 0, 5,
-	5, 5, 5, 0, 5, 5, 0, 0,
-	5, 5, 0, 0, 0, 0, 5, 17,
-	36, 0, 36, 5, 5, 0, 36, 0,
-	0, 5, 36, 0, 0, 0, 0, 5,
-	19, 13, 5, 0, 0, 0, 0, 5,
-	5, 5, 5, 5, 0, 0, 5, 5,
-	0, 0, 0, 0, 5, 0, 33, 33,
-	0, 0, 0, 0, 15, 5, 0, 0,
-	0,
+	5, 23, 5, 0, 5, 0, 0, 0,
+	5, 5, 5, 29, 5, 0, 36, 0,
+	36, 0, 31, 0, 5, 25, 5, 0,
+	5, 0, 5, 0, 0, 5, 0, 27,
+	0, 7, 5, 5, 36, 0, 39, 39,
+	0, 5, 36, 5, 36, 5, 0, 9,
+	5, 0, 0, 5, 0, 5, 5, 0,
+	5, 5, 0, 0, 5, 5, 5, 0,
+	0, 0, 5, 11, 5, 0, 0, 5,
+	0, 5, 5, 0, 5, 5, 5, 5,
+	0, 5, 5, 0, 0, 5, 5, 5,
+	0, 0, 0, 5, 17, 36, 0, 36,
+	5, 5, 0, 36, 0, 0, 5, 36,
+	36, 0, 0, 0, 5, 19, 13, 5,
+	0, 0, 0, 0, 5, 5, 5, 5,
+	5, 0, 0, 5, 5, 5, 0, 0,
+	0, 5, 0, 33, 33, 0, 0, 0,
+	0, 15, 5, 0, 0, 0,
 }
 }
 
 
-var _indicSyllableMachine_to_state_actions []byte = []byte{
-	0, 0, 0, 0, 0, 0, 0, 0,
+var _indSM_to_state_actions []byte = []byte{
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
@@ -386,11 +403,11 @@ var _indicSyllableMachine_to_state_actions []byte = []byte{
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0,
 }
 }
 
 
-var _indicSyllableMachine_from_state_actions []byte = []byte{
-	0, 0, 0, 0, 0, 0, 0, 0,
+var _indSM_from_state_actions []byte = []byte{
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
@@ -407,42 +424,43 @@ var _indicSyllableMachine_from_state_actions []byte = []byte{
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0,
 }
 }
 
 
-var _indicSyllableMachine_eof_trans []int16 = []int16{
-	1, 1, 1, 1, 1, 1, 1, 1,
-	1, 11, 11, 11, 11, 11, 11, 11,
-	11, 11, 11, 22, 22, 28, 22, 22,
-	22, 22, 22, 22, 33, 33, 33, 33,
-	33, 33, 33, 33, 33, 1, 43, 0,
-	59, 59, 59, 59, 59, 59, 59, 59,
-	59, 59, 59, 59, 59, 59, 59, 59,
-	59, 59, 59, 59, 79, 79, 79, 79,
-	79, 79, 79, 79, 79, 79, 79, 79,
-	79, 79, 79, 79, 79, 79, 79, 79,
-	79, 79, 79, 79, 79, 104, 104, 104,
-	104, 104, 104, 104, 104, 104, 104, 104,
-	104, 104, 104, 104, 104, 104, 104, 104,
-	104, 121, 121, 122, 122, 122, 122, 122,
-	122, 122, 122, 122, 122, 122, 122, 122,
-	122, 122, 122, 122, 122, 122, 122, 104,
-	59, 59, 59, 59, 59, 59, 59, 149,
-	149, 149, 149, 149, 121,
+var _indSM_eof_trans []int16 = []int16{
+	1, 1, 1, 1, 1, 1, 1, 10,
+	10, 10, 10, 10, 10, 10, 10, 20,
+	20, 27, 20, 27, 20, 20, 30, 30,
+	30, 30, 30, 30, 30, 1, 40, 0,
+	56, 56, 56, 56, 56, 56, 56, 56,
+	56, 56, 56, 56, 56, 56, 56, 56,
+	56, 56, 56, 56, 56, 76, 76, 76,
+	76, 76, 76, 76, 76, 76, 76, 76,
+	76, 76, 76, 76, 76, 76, 76, 76,
+	76, 76, 76, 76, 76, 76, 76, 101,
+	101, 101, 101, 101, 101, 101, 101, 101,
+	101, 101, 101, 101, 101, 101, 101, 101,
+	101, 101, 101, 101, 118, 118, 119, 119,
+	119, 119, 119, 119, 119, 119, 119, 119,
+	119, 119, 119, 119, 119, 119, 119, 119,
+	119, 119, 119, 101, 56, 56, 56, 56,
+	56, 56, 56, 56, 146, 146, 146, 146,
+	146, 118,
 }
 }
 
 
-const indicSyllableMachine_start int = 39
-const indicSyllableMachine_first_final int = 39
-const indicSyllableMachine_error int = -1
+const indSM_start int = 31
+const indSM_first_final int = 31
+const indSM_error int = -1
 
 
-const indicSyllableMachine_en_main int = 39
+const indSM_en_main int = 31
 
 
 func findSyllablesIndic(buffer *Buffer) {
 func findSyllablesIndic(buffer *Buffer) {
 	var p, ts, te, act, cs int
 	var p, ts, te, act, cs int
 	info := buffer.Info
 	info := buffer.Info
 
 
 	{
 	{
-		cs = indicSyllableMachine_start
+		cs = indSM_start
 		ts = 0
 		ts = 0
 		te = 0
 		te = 0
 		act = 0
 		act = 0
@@ -463,22 +481,22 @@ func findSyllablesIndic(buffer *Buffer) {
 			goto _test_eof
 			goto _test_eof
 		}
 		}
 	_resume:
 	_resume:
-		_acts = int(_indicSyllableMachine_from_state_actions[cs])
-		_nacts = uint(_indicSyllableMachine_actions[_acts])
+		_acts = int(_indSM_from_state_actions[cs])
+		_nacts = uint(_indSM_actions[_acts])
 		_acts++
 		_acts++
 		for ; _nacts > 0; _nacts-- {
 		for ; _nacts > 0; _nacts-- {
 			_acts++
 			_acts++
-			switch _indicSyllableMachine_actions[_acts-1] {
+			switch _indSM_actions[_acts-1] {
 			case 1:
 			case 1:
 				ts = p
 				ts = p
 
 
 			}
 			}
 		}
 		}
 
 
-		_keys = int(_indicSyllableMachine_key_offsets[cs])
-		_trans = int(_indicSyllableMachine_index_offsets[cs])
+		_keys = int(_indSM_key_offsets[cs])
+		_trans = int(_indSM_index_offsets[cs])
 
 
-		_klen = int(_indicSyllableMachine_single_lengths[cs])
+		_klen = int(_indSM_single_lengths[cs])
 		if _klen > 0 {
 		if _klen > 0 {
 			_lower := int(_keys)
 			_lower := int(_keys)
 			var _mid int
 			var _mid int
@@ -490,9 +508,9 @@ func findSyllablesIndic(buffer *Buffer) {
 
 
 				_mid = _lower + ((_upper - _lower) >> 1)
 				_mid = _lower + ((_upper - _lower) >> 1)
 				switch {
 				switch {
-				case (info[p].complexCategory) < _indicSyllableMachine_trans_keys[_mid]:
+				case (info[p].complexCategory) < _indSM_trans_keys[_mid]:
 					_upper = _mid - 1
 					_upper = _mid - 1
-				case (info[p].complexCategory) > _indicSyllableMachine_trans_keys[_mid]:
+				case (info[p].complexCategory) > _indSM_trans_keys[_mid]:
 					_lower = _mid + 1
 					_lower = _mid + 1
 				default:
 				default:
 					_trans += int(_mid - int(_keys))
 					_trans += int(_mid - int(_keys))
@@ -503,7 +521,7 @@ func findSyllablesIndic(buffer *Buffer) {
 			_trans += _klen
 			_trans += _klen
 		}
 		}
 
 
-		_klen = int(_indicSyllableMachine_range_lengths[cs])
+		_klen = int(_indSM_range_lengths[cs])
 		if _klen > 0 {
 		if _klen > 0 {
 			_lower := int(_keys)
 			_lower := int(_keys)
 			var _mid int
 			var _mid int
@@ -515,9 +533,9 @@ func findSyllablesIndic(buffer *Buffer) {
 
 
 				_mid = _lower + (((_upper - _lower) >> 1) & ^1)
 				_mid = _lower + (((_upper - _lower) >> 1) & ^1)
 				switch {
 				switch {
-				case (info[p].complexCategory) < _indicSyllableMachine_trans_keys[_mid]:
+				case (info[p].complexCategory) < _indSM_trans_keys[_mid]:
 					_upper = _mid - 2
 					_upper = _mid - 2
-				case (info[p].complexCategory) > _indicSyllableMachine_trans_keys[_mid+1]:
+				case (info[p].complexCategory) > _indSM_trans_keys[_mid+1]:
 					_lower = _mid + 2
 					_lower = _mid + 2
 				default:
 				default:
 					_trans += int((_mid - int(_keys)) >> 1)
 					_trans += int((_mid - int(_keys)) >> 1)
@@ -528,20 +546,20 @@ func findSyllablesIndic(buffer *Buffer) {
 		}
 		}
 
 
 	_match:
 	_match:
-		_trans = int(_indicSyllableMachine_indicies[_trans])
+		_trans = int(_indSM_indicies[_trans])
 	_eof_trans:
 	_eof_trans:
-		cs = int(_indicSyllableMachine_trans_targs[_trans])
+		cs = int(_indSM_trans_targs[_trans])
 
 
-		if _indicSyllableMachine_trans_actions[_trans] == 0 {
+		if _indSM_trans_actions[_trans] == 0 {
 			goto _again
 			goto _again
 		}
 		}
 
 
-		_acts = int(_indicSyllableMachine_trans_actions[_trans])
-		_nacts = uint(_indicSyllableMachine_actions[_acts])
+		_acts = int(_indSM_trans_actions[_trans])
+		_nacts = uint(_indSM_actions[_acts])
 		_acts++
 		_acts++
 		for ; _nacts > 0; _nacts-- {
 		for ; _nacts > 0; _nacts-- {
 			_acts++
 			_acts++
-			switch _indicSyllableMachine_actions[_acts-1] {
+			switch _indSM_actions[_acts-1] {
 			case 2:
 			case 2:
 				te = p + 1
 				te = p + 1
 
 
@@ -585,6 +603,7 @@ func findSyllablesIndic(buffer *Buffer) {
 				p--
 				p--
 				{
 				{
 					foundSyllableIndic(indicBrokenCluster, ts, te, info, &syllableSerial)
 					foundSyllableIndic(indicBrokenCluster, ts, te, info, &syllableSerial)
+					buffer.scratchFlags |= bsfHasBrokenSyllable
 				}
 				}
 			case 12:
 			case 12:
 				te = p
 				te = p
@@ -616,6 +635,7 @@ func findSyllablesIndic(buffer *Buffer) {
 				p = (te) - 1
 				p = (te) - 1
 				{
 				{
 					foundSyllableIndic(indicBrokenCluster, ts, te, info, &syllableSerial)
 					foundSyllableIndic(indicBrokenCluster, ts, te, info, &syllableSerial)
+					buffer.scratchFlags |= bsfHasBrokenSyllable
 				}
 				}
 			case 18:
 			case 18:
 				switch act {
 				switch act {
@@ -628,6 +648,7 @@ func findSyllablesIndic(buffer *Buffer) {
 					{
 					{
 						p = (te) - 1
 						p = (te) - 1
 						foundSyllableIndic(indicBrokenCluster, ts, te, info, &syllableSerial)
 						foundSyllableIndic(indicBrokenCluster, ts, te, info, &syllableSerial)
+						buffer.scratchFlags |= bsfHasBrokenSyllable
 					}
 					}
 				case 6:
 				case 6:
 					{
 					{
@@ -640,12 +661,12 @@ func findSyllablesIndic(buffer *Buffer) {
 		}
 		}
 
 
 	_again:
 	_again:
-		_acts = int(_indicSyllableMachine_to_state_actions[cs])
-		_nacts = uint(_indicSyllableMachine_actions[_acts])
+		_acts = int(_indSM_to_state_actions[cs])
+		_nacts = uint(_indSM_actions[_acts])
 		_acts++
 		_acts++
 		for ; _nacts > 0; _nacts-- {
 		for ; _nacts > 0; _nacts-- {
 			_acts++
 			_acts++
-			switch _indicSyllableMachine_actions[_acts-1] {
+			switch _indSM_actions[_acts-1] {
 			case 0:
 			case 0:
 				ts = 0
 				ts = 0
 
 
@@ -660,8 +681,8 @@ func findSyllablesIndic(buffer *Buffer) {
 		{
 		{
 		}
 		}
 		if p == eof {
 		if p == eof {
-			if _indicSyllableMachine_eof_trans[cs] > 0 {
-				_trans = int(_indicSyllableMachine_eof_trans[cs] - 1)
+			if _indSM_eof_trans[cs] > 0 {
+				_trans = int(_indSM_eof_trans[cs] - 1)
 				goto _eof_trans
 				goto _eof_trans
 			}
 			}
 		}
 		}

+ 17 - 14
vendor/github.com/go-text/typesetting/harfbuzz/ot_indic_machine.rl

@@ -15,7 +15,7 @@ const  (
 )
 )
 
 
 %%{
 %%{
-  machine indicSyllableMachine;
+  machine indSM;
   alphtype byte;
   alphtype byte;
   write exports;
   write exports;
   write data;
   write data;
@@ -23,6 +23,8 @@ const  (
 
 
 %%{
 %%{
 
 
+
+export X    = 0;
 export C    = 1;
 export C    = 1;
 export V    = 2;
 export V    = 2;
 export N    = 3;
 export N    = 3;
@@ -31,15 +33,17 @@ export ZWNJ = 5;
 export ZWJ  = 6;
 export ZWJ  = 6;
 export M    = 7;
 export M    = 7;
 export SM   = 8;
 export SM   = 8;
-export A    = 10;
-export PLACEHOLDER = 11;
-export DOTTEDCIRCLE = 12;
-export RS    = 13;
-export Repha = 15;
-export Ra    = 16;
-export CM    = 17;
-export Symbol= 18;
-export CS    = 19;
+export A    = 9;
+export VD   = 9;
+export PLACEHOLDER = 10;
+export DOTTEDCIRCLE = 11;
+export RS    = 12;
+export MPst  = 13;
+export Repha = 14;
+export Ra    = 15;
+export CM    = 16;
+export Symbol= 17;
+export CS    = 18;
 
 
 c = (C | Ra);			# is_consonant
 c = (C | Ra);			# is_consonant
 n = ((ZWNJ?.RS)? (N.N?)?);	# is_consonant_modifier
 n = ((ZWNJ?.RS)? (N.N?)?);	# is_consonant_modifier
@@ -47,10 +51,9 @@ z = ZWJ|ZWNJ;			# is_joiner
 reph = (Ra H | Repha);		# possible reph
 reph = (Ra H | Repha);		# possible reph
 
 
 cn = c.ZWJ?.n?;
 cn = c.ZWJ?.n?;
-forced_rakar = ZWJ H ZWJ Ra;
 symbol = Symbol.N?;
 symbol = Symbol.N?;
-matra_group = z*.M.N?.(H | forced_rakar)?;
-syllable_tail = (z?.SM.SM?.ZWNJ?)? A*;
+matra_group = z*.(M | SM? MPst).N?.H?;
+syllable_tail = (z?.SM.SM?.ZWNJ?)? (A | VD)*;
 halant_group = (z?.H.(ZWJ.N?)?);
 halant_group = (z?.H.(ZWJ.N?)?);
 final_halant_group = halant_group | H.ZWNJ;
 final_halant_group = halant_group | H.ZWNJ;
 medial_group = CM?;
 medial_group = CM?;
@@ -70,7 +73,7 @@ main := |*
 	vowel_syllable		=> { foundSyllableIndic (indicVowelSyllable,ts, te, info, &syllableSerial); };
 	vowel_syllable		=> { foundSyllableIndic (indicVowelSyllable,ts, te, info, &syllableSerial); };
 	standalone_cluster	=> { foundSyllableIndic (indicStandaloneCluster,ts, te, info, &syllableSerial); };
 	standalone_cluster	=> { foundSyllableIndic (indicStandaloneCluster,ts, te, info, &syllableSerial); };
 	symbol_cluster		=> { foundSyllableIndic (indicSymbolCluster,ts, te, info, &syllableSerial); };
 	symbol_cluster		=> { foundSyllableIndic (indicSymbolCluster,ts, te, info, &syllableSerial); };
-	broken_cluster		=> { foundSyllableIndic (indicBrokenCluster,ts, te, info, &syllableSerial); };
+	broken_cluster		=> { foundSyllableIndic (indicBrokenCluster,ts, te, info, &syllableSerial); buffer.scratchFlags |= bsfHasBrokenSyllable; };
 	other			=> { foundSyllableIndic (indicNonIndicCluster,ts, te, info, &syllableSerial); };
 	other			=> { foundSyllableIndic (indicNonIndicCluster,ts, te, info, &syllableSerial); };
 *|;
 *|;
 
 

+ 161 - 181
vendor/github.com/go-text/typesetting/harfbuzz/ot_indic_table.go

@@ -1,246 +1,210 @@
-package harfbuzz
-
-// Code generated by unicodedata/generate/main.go DO NOT EDIT.
+// SPDX-License-Identifier: Unlicense OR BSD-3-Clause
 
 
-const (
-	otX            = 0
-	otC            = 1
-	otV            = 2
-	otN            = 3
-	otH            = 4
-	otZWNJ         = 5
-	otZWJ          = 6
-	otM            = 7
-	otSM           = 8
-	otA            = 10
-	otPLACEHOLDER  = 11
-	otDOTTEDCIRCLE = 12
-	otRS           = 13
-	otCoeng        = 14
-	otRepha        = 15
-	otRa           = 16
-	otCM           = 17
-	otSymbol       = 18
-	otCS           = 19
-	otVAbv         = 26
-	otVBlw         = 27
-	otVPre         = 28
-	otVPst         = 29
-)
-const (
-	posStart          = 0
-	posRaToBecomeReph = 1
-	posPreM           = 2
-	posPreC           = 3
-	posBaseC          = 4
-	posAfterMain      = 5
-	posAboveC         = 6
-	posBeforeSub      = 7
-	posBelowC         = 8
-	posAfterSub       = 9
-	posBeforePost     = 10
-	posPostC          = 11
-	posAfterPost      = 12
-	posFinalC         = 13
-	posSmvd           = 14
-	posEnd            = 15
-)
+package harfbuzz
 
 
+// Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
 var indicTable = [...]uint16{
 var indicTable = [...]uint16{
 
 
 	/* Basic Latin */
 	/* Basic Latin */
-	0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf0b, 0xf00, 0xf00,
-	/* 0030 */ 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
+	0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x40a, 0xe00, 0xe00,
+	/* 0030 */ 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
 
 
 	/* Latin-1 Supplement */
 	/* Latin-1 Supplement */
 
 
-	/* 00B0 */ 0xf00, 0xf00, 0xf08, 0xf08, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
-	/* 00C0 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
-	/* 00D0 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf0b,
+	/* 00B0 */ 0xe00, 0xe00, 0xd08, 0xd08, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
+	/* 00C0 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
+	/* 00D0 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x40a,
 
 
 	/* Devanagari */
 	/* Devanagari */
 
 
-	/* 0900 */ 0x608, 0x608, 0x608, 0xb08, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02,
-	/* 0910 */ 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0920 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0930 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0x607, 0xb07, 0xf03, 0xf12, 0xb07, 0x307,
-	/* 0940 */ 0xb07, 0x807, 0x807, 0x807, 0x807, 0x607, 0x607, 0x607, 0x607, 0xb07, 0xb07, 0xb07, 0xb07, 0x804, 0x307, 0xb07,
-	/* 0950 */ 0xf00, 0xf0a, 0xf0a, 0xf00, 0xf00, 0x607, 0x807, 0x807, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0960 */ 0xf02, 0xf02, 0x807, 0x807, 0xf00, 0xf00, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b,
-	/* 0970 */ 0xf00, 0xf00, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
+	/* 0900 */ 0xd08, 0xd08, 0xd08, 0xd08, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402,
+	/* 0910 */ 0x402, 0x402, 0x402, 0x402, 0x402, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0920 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0930 */ 0x40f, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x907, 0x907, 0xe03, 0xd11, 0x907, 0x207,
+	/* 0940 */ 0x907, 0x907, 0x907, 0x907, 0x907, 0x907, 0x907, 0x907, 0x907, 0x907, 0x907, 0x907, 0x907, 0x804, 0x207, 0x907,
+	/* 0950 */ 0xe00, 0xd09, 0xd09, 0xd08, 0xd08, 0x907, 0x907, 0x907, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0960 */ 0x402, 0x402, 0x907, 0x907, 0xe00, 0xe00, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a,
+	/* 0970 */ 0xe00, 0xe00, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
 
 
 	/* Bengali */
 	/* Bengali */
 
 
-	/* 0980 */ 0xf0b, 0x608, 0xb08, 0xb08, 0xf00, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf00, 0xf00, 0xf02,
-	/* 0990 */ 0xf02, 0xf00, 0xf00, 0xf02, 0xf02, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 09A0 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 09B0 */ 0xf01, 0xf00, 0xf01, 0xf00, 0xf00, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf00, 0xf03, 0xf12, 0xb07, 0x307,
-	/* 09C0 */ 0xb07, 0x807, 0x807, 0x807, 0x807, 0xf00, 0xf00, 0x307, 0x307, 0xf00, 0xf00, 0xb07, 0xb07, 0x804, 0xf01, 0xf00,
-	/* 09D0 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xb07, 0xf00, 0xf00, 0xf00, 0xf00, 0xf01, 0xf01, 0xf00, 0xf01,
-	/* 09E0 */ 0xf02, 0xf02, 0x807, 0x807, 0xf00, 0xf00, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b,
-	/* 09F0 */ 0xf01, 0xf01, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf08, 0xf00, 0x608, 0xf00,
+	/* 0980 */ 0x40a, 0xd08, 0xd08, 0xd08, 0xe00, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0xe00, 0xe00, 0x402,
+	/* 0990 */ 0x402, 0xe00, 0xe00, 0x402, 0x402, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 09A0 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0xe00, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 09B0 */ 0x40f, 0xe00, 0x401, 0xe00, 0xe00, 0xe00, 0x401, 0x401, 0x401, 0x401, 0xe00, 0xe00, 0xe03, 0xd11, 0xc07, 0x207,
+	/* 09C0 */ 0xc07, 0x907, 0x907, 0x907, 0x907, 0xe00, 0xe00, 0x207, 0x207, 0xe00, 0xe00, 0xc07, 0xc07, 0x804, 0x401, 0xe00,
+	/* 09D0 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xc07, 0xe00, 0xe00, 0xe00, 0xe00, 0x401, 0x401, 0xe00, 0x401,
+	/* 09E0 */ 0x402, 0x402, 0x907, 0x907, 0xe00, 0xe00, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a,
+	/* 09F0 */ 0x40f, 0x401, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x40a, 0xe00, 0xd08, 0xe00,
 
 
 	/* Gurmukhi */
 	/* Gurmukhi */
 
 
-	/* 0A00 */ 0xf00, 0x608, 0x608, 0xb08, 0xf00, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf00, 0xf00, 0xf00, 0xf00, 0xf02,
-	/* 0A10 */ 0xf02, 0xf00, 0xf00, 0xf02, 0xf02, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0A20 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0A30 */ 0xf01, 0xf00, 0xf01, 0xf01, 0xf00, 0xf01, 0xf01, 0xf00, 0xf01, 0xf01, 0xf00, 0xf00, 0xf03, 0xf00, 0xb07, 0x307,
-	/* 0A40 */ 0xb07, 0x807, 0x807, 0xf00, 0xf00, 0xf00, 0xf00, 0x607, 0x607, 0xf00, 0xf00, 0x607, 0x607, 0x804, 0xf00, 0xf00,
-	/* 0A50 */ 0xf00, 0xf0a, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf01, 0xf00,
-	/* 0A60 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b,
-	/* 0A70 */ 0x608, 0x608, 0xf0b, 0xf0b, 0xf00, 0x811, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
+	/* 0A00 */ 0xe00, 0xd08, 0xd08, 0xd08, 0xe00, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0xe00, 0xe00, 0xe00, 0xe00, 0x402,
+	/* 0A10 */ 0x402, 0xe00, 0xe00, 0x402, 0x402, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0A20 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0xe00, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0A30 */ 0x40f, 0xe00, 0x401, 0x401, 0xe00, 0x401, 0x401, 0xe00, 0x401, 0x401, 0xe00, 0xe00, 0xe03, 0xe00, 0xc07, 0x207,
+	/* 0A40 */ 0xc0d, 0xc07, 0xc07, 0xe00, 0xe00, 0xe00, 0xe00, 0xc07, 0xc07, 0xe00, 0xe00, 0xc07, 0xc07, 0x804, 0xe00, 0xe00,
+	/* 0A50 */ 0xe00, 0x807, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x401, 0x401, 0x401, 0x401, 0xe00, 0x401, 0xe00,
+	/* 0A60 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a,
+	/* 0A70 */ 0xd08, 0xd08, 0x401, 0x401, 0xe00, 0x410, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
 
 
 	/* Gujarati */
 	/* Gujarati */
 
 
-	/* 0A80 */ 0xf00, 0x608, 0x608, 0xb08, 0xf00, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf00, 0xf02,
-	/* 0A90 */ 0xf02, 0xf02, 0xf00, 0xf02, 0xf02, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0AA0 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0AB0 */ 0xf01, 0xf00, 0xf01, 0xf01, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf00, 0xf03, 0xf12, 0xb07, 0x307,
-	/* 0AC0 */ 0xb07, 0x807, 0x807, 0x807, 0x807, 0x607, 0xf00, 0x607, 0x607, 0xb07, 0xf00, 0xb07, 0xb07, 0x804, 0xf00, 0xf00,
-	/* 0AD0 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
-	/* 0AE0 */ 0xf02, 0xf02, 0x807, 0x807, 0xf00, 0xf00, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b,
-	/* 0AF0 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf01, 0xf0a, 0xf0a, 0xf0a, 0xf03, 0xf03, 0xf03,
+	/* 0A80 */ 0xe00, 0xd08, 0xd08, 0xd08, 0xe00, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0xe00, 0x402,
+	/* 0A90 */ 0x402, 0x402, 0xe00, 0x402, 0x402, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0AA0 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0xe00, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0AB0 */ 0x40f, 0xe00, 0x401, 0x401, 0xe00, 0x401, 0x401, 0x401, 0x401, 0x401, 0xe00, 0xe00, 0xe03, 0xd11, 0xc07, 0x207,
+	/* 0AC0 */ 0xc07, 0xc07, 0xc07, 0xc07, 0xc07, 0x907, 0xe00, 0x907, 0x907, 0xc07, 0xe00, 0xc07, 0xc07, 0x804, 0xe00, 0xe00,
+	/* 0AD0 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
+	/* 0AE0 */ 0x402, 0x402, 0xc07, 0xc07, 0xe00, 0xe00, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a,
+	/* 0AF0 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x401, 0xd09, 0xe03, 0xd09, 0xe03, 0xe03, 0xe03,
 
 
 	/* Oriya */
 	/* Oriya */
 
 
-	/* 0B00 */ 0xf00, 0x608, 0xb08, 0xb08, 0xf00, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf00, 0xf00, 0xf02,
-	/* 0B10 */ 0xf02, 0xf00, 0xf00, 0xf02, 0xf02, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0B20 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0B30 */ 0xf01, 0xf00, 0xf01, 0xf01, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf00, 0xf03, 0xf12, 0xb07, 0x607,
-	/* 0B40 */ 0xb07, 0x807, 0x807, 0x807, 0x807, 0xf00, 0xf00, 0x307, 0x607, 0xf00, 0xf00, 0xb07, 0xb07, 0x804, 0xf00, 0xf00,
-	/* 0B50 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0x607, 0x607, 0xb07, 0xf00, 0xf00, 0xf00, 0xf00, 0xf01, 0xf01, 0xf00, 0xf01,
-	/* 0B60 */ 0xf02, 0xf02, 0x807, 0x807, 0xf00, 0xf00, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b,
-	/* 0B70 */ 0xf00, 0xf01, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
+	/* 0B00 */ 0xe00, 0x708, 0xd08, 0xd08, 0xe00, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0xe00, 0xe00, 0x402,
+	/* 0B10 */ 0x402, 0xe00, 0xe00, 0x402, 0x402, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0B20 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0xe00, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0B30 */ 0x40f, 0xe00, 0x401, 0x401, 0xe00, 0x401, 0x401, 0x401, 0x401, 0x401, 0xe00, 0xe00, 0xe03, 0xd11, 0xc07, 0x507,
+	/* 0B40 */ 0xc07, 0x907, 0x907, 0x907, 0x907, 0xe00, 0xe00, 0x207, 0x507, 0xe00, 0xe00, 0xc07, 0xc07, 0x804, 0xe00, 0xe00,
+	/* 0B50 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe03, 0x507, 0xc07, 0xe00, 0xe00, 0xe00, 0xe00, 0x401, 0x401, 0xe00, 0x401,
+	/* 0B60 */ 0x402, 0x402, 0x907, 0x907, 0xe00, 0xe00, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a,
+	/* 0B70 */ 0xe00, 0x401, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
 
 
 	/* Tamil */
 	/* Tamil */
 
 
-	/* 0B80 */ 0xf00, 0xf00, 0x608, 0xf00, 0xf00, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf00, 0xf00, 0xf00, 0xf02, 0xf02,
-	/* 0B90 */ 0xf02, 0xf00, 0xf02, 0xf02, 0xf02, 0xf01, 0xf00, 0xf00, 0xf00, 0xf01, 0xf01, 0xf00, 0xf01, 0xf00, 0xf01, 0xf01,
-	/* 0BA0 */ 0xf00, 0xf00, 0xf00, 0xf01, 0xf01, 0xf00, 0xf00, 0xf00, 0xf01, 0xf01, 0xf01, 0xf00, 0xf00, 0xf00, 0xf01, 0xf01,
-	/* 0BB0 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf00, 0xf00, 0xf00, 0xb07, 0xb07,
-	/* 0BC0 */ 0x607, 0xb07, 0xb07, 0xf00, 0xf00, 0xf00, 0x307, 0x307, 0x307, 0xf00, 0xb07, 0xb07, 0xb07, 0x604, 0xf00, 0xf00,
-	/* 0BD0 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xb07, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
-	/* 0BE0 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b,
-	/* 0BF0 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
+	/* 0B80 */ 0xe00, 0xe00, 0xd08, 0xe00, 0xe00, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0xe00, 0xe00, 0xe00, 0x402, 0x402,
+	/* 0B90 */ 0x402, 0xe00, 0x402, 0x402, 0x402, 0x401, 0xe00, 0xe00, 0xe00, 0x401, 0x401, 0xe00, 0x401, 0xe00, 0x401, 0x401,
+	/* 0BA0 */ 0xe00, 0xe00, 0xe00, 0x401, 0x401, 0xe00, 0xe00, 0xe00, 0x401, 0x401, 0x401, 0xe00, 0xe00, 0xe00, 0x401, 0x401,
+	/* 0BB0 */ 0x40f, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0xe00, 0xe00, 0xe00, 0xe00, 0xc07, 0xc07,
+	/* 0BC0 */ 0x907, 0xc07, 0xc07, 0xe00, 0xe00, 0xe00, 0x207, 0x207, 0x207, 0xe00, 0xc07, 0xc07, 0xc07, 0x604, 0xe00, 0xe00,
+	/* 0BD0 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xc07, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
+	/* 0BE0 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a,
+	/* 0BF0 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
 
 
 	/* Telugu */
 	/* Telugu */
 
 
-	/* 0C00 */ 0x608, 0xb08, 0xb08, 0xb08, 0x608, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf00, 0xf02, 0xf02,
-	/* 0C10 */ 0xf02, 0xf00, 0xf02, 0xf02, 0xf02, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0C20 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0C30 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf00, 0xf00, 0xf12, 0x607, 0x607,
-	/* 0C40 */ 0x607, 0xb07, 0xb07, 0xb07, 0xb07, 0xf00, 0x607, 0x607, 0x807, 0xf00, 0x607, 0x607, 0x607, 0x604, 0xf00, 0xf00,
-	/* 0C50 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0x607, 0x807, 0xf00, 0xf01, 0xf01, 0xf01, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
-	/* 0C60 */ 0xf02, 0xf02, 0x807, 0x807, 0xf00, 0xf00, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b,
-	/* 0C70 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
+	/* 0C00 */ 0xd08, 0xd08, 0xd08, 0xd08, 0xd08, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0xe00, 0x402, 0x402,
+	/* 0C10 */ 0x402, 0xe00, 0x402, 0x402, 0x402, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0C20 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0xe00, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0C30 */ 0x40f, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0xe00, 0xe00, 0xe03, 0xd11, 0x707, 0x707,
+	/* 0C40 */ 0x707, 0x707, 0x707, 0x907, 0x907, 0xe00, 0x707, 0x707, 0x707, 0xe00, 0x707, 0x707, 0x707, 0x604, 0xe00, 0xe00,
+	/* 0C50 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x707, 0x707, 0xe00, 0x401, 0x401, 0x401, 0xe00, 0xe00, 0x401, 0xe00, 0xe00,
+	/* 0C60 */ 0x402, 0x402, 0x707, 0x707, 0xe00, 0xe00, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a,
+	/* 0C70 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
 
 
 	/* Kannada */
 	/* Kannada */
 
 
-	/* 0C80 */ 0xf08, 0x608, 0xb08, 0xb08, 0xf00, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf00, 0xf02, 0xf02,
-	/* 0C90 */ 0xf02, 0xf00, 0xf02, 0xf02, 0xf02, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0CA0 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0CB0 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf00, 0xf03, 0xf12, 0xb07, 0x607,
-	/* 0CC0 */ 0xb07, 0xb07, 0xb07, 0xb07, 0xb07, 0xf00, 0x607, 0xb07, 0xb07, 0xf00, 0xb07, 0xb07, 0x607, 0x604, 0xf00, 0xf00,
-	/* 0CD0 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xb07, 0xb07, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf01, 0xf00,
-	/* 0CE0 */ 0xf02, 0xf02, 0x807, 0x807, 0xf00, 0xf00, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b,
-	/* 0CF0 */ 0xf00, 0xf13, 0xf13, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
+	/* 0C80 */ 0x40a, 0xd08, 0xd08, 0xd08, 0xe00, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0xe00, 0x402, 0x402,
+	/* 0C90 */ 0x402, 0xe00, 0x402, 0x402, 0x402, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0CA0 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0xe00, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0CB0 */ 0x40f, 0x401, 0x401, 0x401, 0xe00, 0x401, 0x401, 0x401, 0x401, 0x401, 0xe00, 0xe00, 0xe03, 0xd11, 0x707, 0x707,
+	/* 0CC0 */ 0x707, 0x707, 0x707, 0x907, 0x907, 0xe00, 0x707, 0x907, 0x907, 0xe00, 0x907, 0x907, 0x707, 0x604, 0xe00, 0xe00,
+	/* 0CD0 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x907, 0x907, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x401, 0x401, 0xe00,
+	/* 0CE0 */ 0x402, 0x402, 0x707, 0x707, 0xe00, 0xe00, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a,
+	/* 0CF0 */ 0xe00, 0x412, 0x412, 0xd08, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
 
 
 	/* Malayalam */
 	/* Malayalam */
 
 
-	/* 0D00 */ 0x608, 0x608, 0xb08, 0xb08, 0xf08, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf00, 0xf02, 0xf02,
-	/* 0D10 */ 0xf02, 0xf00, 0xf02, 0xf02, 0xf02, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0D20 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0D30 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0x607, 0x607, 0xf12, 0xb07, 0xb07,
-	/* 0D40 */ 0xb07, 0xb07, 0xb07, 0x807, 0x807, 0xf00, 0x307, 0x307, 0x307, 0xf00, 0xb07, 0xb07, 0xb07, 0x604, 0xf0f, 0xf00,
-	/* 0D50 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf01, 0xf01, 0xf01, 0xb07, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf02,
-	/* 0D60 */ 0xf02, 0xf02, 0x807, 0x807, 0xf00, 0xf00, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b,
-	/* 0D70 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-
-	/* Sinhala */
-
-	/* 0D80 */ 0xf00, 0x608, 0xb08, 0xb08, 0xf00, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02,
-	/* 0D90 */ 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf00, 0xf00, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0DA0 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 0DB0 */ 0xf01, 0xf01, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf01, 0xf00, 0xf00,
-	/* 0DC0 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00, 0xf00, 0xf00, 0x604, 0xf00, 0xf00, 0xf00, 0xf00, 0xb07,
-	/* 0DD0 */ 0xb07, 0xb07, 0x607, 0x607, 0x807, 0xf00, 0x807, 0xf00, 0xb07, 0x307, 0x607, 0x307, 0xb07, 0xb07, 0xb07, 0xb07,
-	/* 0DE0 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b,
-	/* 0DF0 */ 0xf00, 0xf00, 0xb07, 0xb07, 0xf00, 0xf00, 0xf00, 0xf00,
+	/* 0D00 */ 0xd08, 0xd08, 0xd08, 0xd08, 0x40a, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0xe00, 0x402, 0x402,
+	/* 0D10 */ 0x402, 0xe00, 0x402, 0x402, 0x402, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0D20 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 0D30 */ 0x40f, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x907, 0x907, 0xd11, 0xc07, 0xc07,
+	/* 0D40 */ 0xc07, 0xc07, 0xc07, 0xc07, 0xc07, 0xe00, 0x207, 0x207, 0x207, 0xe00, 0xc07, 0xc07, 0xc07, 0x604, 0xe0e, 0xe00,
+	/* 0D50 */ 0xe00, 0xe00, 0xe00, 0xe00, 0x401, 0x401, 0x401, 0xc07, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x402,
+	/* 0D60 */ 0x402, 0x402, 0xc07, 0xc07, 0xe00, 0xe00, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a,
+	/* 0D70 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
 
 
 	/* Myanmar */
 	/* Myanmar */
 
 
-	/* 1000 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 1010 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 1020 */ 0xf01, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xb07, 0xb07, 0x607, 0x607, 0x807,
-	/* 1030 */ 0x807, 0x307, 0x607, 0x607, 0x607, 0x607, 0x608, 0xf03, 0xb08, 0xf0e, 0x607, 0xb11, 0x811, 0x811, 0x811, 0xf01,
-	/* 1040 */ 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf00, 0xf0b, 0xf00, 0xf00, 0xf0b, 0xf00,
-	/* 1050 */ 0xf01, 0xf01, 0xf02, 0xf02, 0xf02, 0xf02, 0xb07, 0xb07, 0x807, 0x807, 0xf01, 0xf01, 0xf01, 0xf01, 0x811, 0x811,
-	/* 1060 */ 0x811, 0xf01, 0xb07, 0xf03, 0xf03, 0xf01, 0xf01, 0xb07, 0xb07, 0xf03, 0xf03, 0xf03, 0xf03, 0xf03, 0xf01, 0xf01,
-	/* 1070 */ 0xf01, 0x607, 0x607, 0x607, 0x607, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 1080 */ 0xf01, 0xf01, 0x811, 0xb07, 0x307, 0x607, 0x607, 0xf03, 0xf03, 0xf03, 0xf03, 0xf03, 0xf03, 0xf03, 0xf01, 0xf03,
-	/* 1090 */ 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf03, 0xf03, 0xb07, 0x607, 0xf00, 0xf00,
+	/* 1000 */ 0x401, 0x401, 0x401, 0x401, 0x40f, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 1010 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x40f, 0x401, 0x401, 0x401, 0x401,
+	/* 1020 */ 0x401, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0xb17, 0xb17, 0x614, 0x614, 0x815,
+	/* 1030 */ 0x815, 0x316, 0xd09, 0x614, 0x614, 0x614, 0xd09, 0xe03, 0xd08, 0xe04, 0xe20, 0xe26, 0xe24, 0xe25, 0xe23, 0x401,
+	/* 1040 */ 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0xe00, 0xe00, 0x401, 0xe00,
+	/* 1050 */ 0x401, 0x401, 0x402, 0x402, 0x402, 0x402, 0xb17, 0xb17, 0x815, 0x815, 0x40f, 0x401, 0x401, 0x401, 0xe26, 0xe26,
+	/* 1060 */ 0xe29, 0x401, 0xb17, 0xe27, 0xe27, 0x401, 0x401, 0xb17, 0xb17, 0xe27, 0xe27, 0xe27, 0xe27, 0xe27, 0x401, 0x401,
+	/* 1070 */ 0x401, 0x614, 0x614, 0x614, 0x614, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 1080 */ 0x401, 0x401, 0xe25, 0xb17, 0x316, 0x614, 0x614, 0xd08, 0xd08, 0xd08, 0xd08, 0xd08, 0xd08, 0xd08, 0x401, 0xd08,
+	/* 1090 */ 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0xd08, 0xd08, 0xd08, 0x614, 0xe00, 0xe00,
 
 
 	/* Khmer */
 	/* Khmer */
 
 
-	/* 1780 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 1790 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* 17A0 */ 0xf01, 0xf01, 0xf01, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02, 0xf02,
-	/* 17B0 */ 0xf02, 0xf02, 0xf02, 0xf02, 0xf00, 0xf00, 0xb07, 0x607, 0x607, 0x607, 0x607, 0x807, 0x807, 0x807, 0x607, 0xb07,
-	/* 17C0 */ 0xb07, 0x307, 0x307, 0x307, 0xb07, 0xb07, 0x608, 0xb08, 0xb07, 0x60d, 0x60d, 0x608, 0x611, 0x607, 0x608, 0x608,
-	/* 17D0 */ 0x608, 0x607, 0xf0e, 0x608, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf12, 0x608, 0xf00, 0xf00,
-	/* 17E0 */ 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
+	/* 1780 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 1790 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x40f, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* 17A0 */ 0x401, 0x401, 0x401, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402, 0x402,
+	/* 17B0 */ 0x402, 0x402, 0x402, 0x402, 0xe00, 0xe00, 0xb17, 0x614, 0x614, 0x614, 0x614, 0x815, 0x815, 0x815, 0x614, 0xb17,
+	/* 17C0 */ 0xb17, 0x316, 0x316, 0x316, 0xb17, 0xb17, 0xe1a, 0xe1b, 0xe1b, 0xe19, 0xe19, 0xe1a, 0xe19, 0xe1a, 0xe1a, 0xe1a,
+	/* 17D0 */ 0xe1a, 0xe1a, 0xe04, 0xe1b, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x40a, 0xe00, 0xe00, 0xd11, 0xe1b, 0xe00, 0xe00,
+	/* 17E0 */ 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
 
 
 	/* Vedic Extensions */
 	/* Vedic Extensions */
 
 
-	/* 1CD0 */ 0xf0a, 0xf0a, 0xf0a, 0xf00, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a,
-	/* 1CE0 */ 0xf0a, 0xf0a, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
-	/* 1CF0 */ 0xf00, 0xf00, 0xf01, 0xf01, 0xf0a, 0xf13, 0xf13, 0xf0a, 0xf0a, 0xf0a, 0xf0b, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
+	/* 1CD0 */ 0xd09, 0xd09, 0xd09, 0xe00, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09,
+	/* 1CE0 */ 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd11, 0xd11, 0xd11, 0xd11, 0xd09, 0xd11, 0xd11,
+	/* 1CF0 */ 0xd11, 0xd11, 0x401, 0x401, 0xd09, 0x401, 0x401, 0xd09, 0xd09, 0xd09, 0x40a, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
 
 
 	/* General Punctuation */
 	/* General Punctuation */
-	0xf00, 0xf00, 0xf00, 0xf00, 0xf05, 0xf06, 0xf00, 0xf00,
-	/* 2010 */ 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf00, 0xf00, 0xf00,
+	0xe00, 0xe00, 0xe00, 0xe00, 0xe05, 0xe06, 0xe00, 0xe00,
+	/* 2010 */ 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
+	/* 2020 */ 0xe00, 0xe00, 0x40a, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
 
 
 	/* Superscripts and Subscripts */
 	/* Superscripts and Subscripts */
 
 
-	/* 2070 */ 0xf00, 0xf00, 0xf00, 0xf00, 0xf08, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00,
-	/* 2080 */ 0xf00, 0xf00, 0xf08, 0xf08, 0xf08, 0xf00, 0xf00, 0xf00,
+	/* 2070 */ 0xe00, 0xe00, 0xe00, 0xe00, 0xd08, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00,
+	/* 2080 */ 0xe00, 0xe00, 0xd08, 0xd08, 0xd08, 0xe00, 0xe00, 0xe00,
+
+	/* Geometric Shapes */
+	0xe00, 0xe00, 0xe00, 0x40a, 0x40a, 0x40a, 0x40a, 0xe00,
 
 
 	/* Devanagari Extended */
 	/* Devanagari Extended */
 
 
-	/* A8E0 */ 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a, 0xf0a,
-	/* A8F0 */ 0xf0a, 0xf0a, 0xf08, 0xf08, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf00, 0xf02, 0x607,
+	/* A8E0 */ 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09, 0xd09,
+	/* A8F0 */ 0xd09, 0xd09, 0xd11, 0xd11, 0xd11, 0xd11, 0xd11, 0xd11, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0xe00, 0x402, 0x907,
 
 
 	/* Myanmar Extended-B */
 	/* Myanmar Extended-B */
 
 
-	/* A9E0 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0x607, 0xf00, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* A9F0 */ 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf0b, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf00,
+	/* A9E0 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x614, 0xe00, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* A9F0 */ 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x40a, 0x401, 0x401, 0x401, 0x401, 0x401, 0xe00,
 
 
 	/* Myanmar Extended-A */
 	/* Myanmar Extended-A */
 
 
-	/* AA60 */ 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01, 0xf01,
-	/* AA70 */ 0xf00, 0xf01, 0xf01, 0xf01, 0xf0b, 0xf0b, 0xf0b, 0xf00, 0xf00, 0xf00, 0xf01, 0xf03, 0xf03, 0xf03, 0xf01, 0xf01,
-} /* Table items: 1792; occupancy: 70% */
+	/* AA60 */ 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401, 0x401,
+	/* AA70 */ 0xe00, 0x401, 0x401, 0x401, 0x40a, 0x40a, 0x40a, 0xe00, 0xe00, 0xe00, 0x401, 0xe27, 0xe03, 0xe03, 0x401, 0x401,
+
+	/* Variation Selectors */
+
+	/* FE00 */ 0xe28, 0xe28, 0xe28, 0xe28, 0xe28, 0xe28, 0xe28, 0xe28, 0xe28, 0xe28, 0xe28, 0xe28, 0xe28, 0xe28, 0xe28, 0xe28,
+
+	/* Grantha */
+
+	/* 11300 */ 0xe00, 0xd08, 0xd08, 0xd08, 0xe00, 0xe00, 0xe00, 0xe00,
+
+	0xe00, 0xe00, 0xe00, 0xe03, 0xe03, 0xe00, 0xe00, 0xe00,
+} /* Table items: 1728; occupancy: 71% */
 
 
 const (
 const (
-	offsetIndic0x0028u = 0
-	offsetIndic0x00b0u = 24
-	offsetIndic0x0900u = 64
-	offsetIndic0x1000u = 1336
-	offsetIndic0x1780u = 1496
-	offsetIndic0x1cd0u = 1608
-	offsetIndic0x2008u = 1656
-	offsetIndic0x2070u = 1672
-	offsetIndic0xa8e0u = 1696
-	offsetIndic0xa9e0u = 1728
-	offsetIndic0xaa60u = 1760
+	offsetIndic0x0028u  = 0
+	offsetIndic0x00b0u  = 24
+	offsetIndic0x0900u  = 64
+	offsetIndic0x1000u  = 1216
+	offsetIndic0x1780u  = 1376
+	offsetIndic0x1cd0u  = 1488
+	offsetIndic0x2008u  = 1536
+	offsetIndic0x2070u  = 1568
+	offsetIndic0x25f8u  = 1592
+	offsetIndic0xa8e0u  = 1600
+	offsetIndic0xa9e0u  = 1632
+	offsetIndic0xaa60u  = 1664
+	offsetIndic0xfe00u  = 1696
+	offsetIndic0x11300u = 1712
+	offsetIndic0x11338u = 1720
 )
 )
 
 
 func indicGetCategories(u rune) uint16 {
 func indicGetCategories(u rune) uint16 {
 	switch u >> 12 {
 	switch u >> 12 {
 	case 0x0:
 	case 0x0:
 		if u == 0x00A0 {
 		if u == 0x00A0 {
-			return 0xf0b
+			return 0x40a
 		}
 		}
 		if 0x0028 <= u && u <= 0x003F {
 		if 0x0028 <= u && u <= 0x003F {
 			return indicTable[u-0x0028+offsetIndic0x0028u]
 			return indicTable[u-0x0028+offsetIndic0x0028u]
@@ -248,7 +212,7 @@ func indicGetCategories(u rune) uint16 {
 		if 0x00B0 <= u && u <= 0x00D7 {
 		if 0x00B0 <= u && u <= 0x00D7 {
 			return indicTable[u-0x00B0+offsetIndic0x00b0u]
 			return indicTable[u-0x00B0+offsetIndic0x00b0u]
 		}
 		}
-		if 0x0900 <= u && u <= 0x0DF7 {
+		if 0x0900 <= u && u <= 0x0D7F {
 			return indicTable[u-0x0900+offsetIndic0x0900u]
 			return indicTable[u-0x0900+offsetIndic0x0900u]
 		}
 		}
 
 
@@ -265,14 +229,17 @@ func indicGetCategories(u rune) uint16 {
 
 
 	case 0x2:
 	case 0x2:
 		if u == 0x25CC {
 		if u == 0x25CC {
-			return 0xf0b
+			return 0x40b
 		}
 		}
-		if 0x2008 <= u && u <= 0x2017 {
+		if 0x2008 <= u && u <= 0x2027 {
 			return indicTable[u-0x2008+offsetIndic0x2008u]
 			return indicTable[u-0x2008+offsetIndic0x2008u]
 		}
 		}
 		if 0x2070 <= u && u <= 0x2087 {
 		if 0x2070 <= u && u <= 0x2087 {
 			return indicTable[u-0x2070+offsetIndic0x2070u]
 			return indicTable[u-0x2070+offsetIndic0x2070u]
 		}
 		}
+		if 0x25F8 <= u && u <= 0x25FF {
+			return indicTable[u-0x25F8+offsetIndic0x25f8u]
+		}
 
 
 	case 0xA:
 	case 0xA:
 		if 0xA8E0 <= u && u <= 0xA8FF {
 		if 0xA8E0 <= u && u <= 0xA8FF {
@@ -285,6 +252,19 @@ func indicGetCategories(u rune) uint16 {
 			return indicTable[u-0xAA60+offsetIndic0xaa60u]
 			return indicTable[u-0xAA60+offsetIndic0xaa60u]
 		}
 		}
 
 
+	case 0xF:
+		if 0xFE00 <= u && u <= 0xFE0F {
+			return indicTable[u-0xFE00+offsetIndic0xfe00u]
+		}
+
+	case 0x11:
+		if 0x11300 <= u && u <= 0x11307 {
+			return indicTable[u-0x11300+offsetIndic0x11300u]
+		}
+		if 0x11338 <= u && u <= 0x1133F {
+			return indicTable[u-0x11338+offsetIndic0x11338u]
+		}
+
 	}
 	}
-	return 0xf00
+	return 0xe00
 }
 }

+ 2 - 1
vendor/github.com/go-text/typesetting/harfbuzz/ot_kern.go

@@ -12,6 +12,7 @@ func simpleKern(kernTable fontP.Kernx) fontP.SimpleKerns {
 }
 }
 
 
 func kern(driver fontP.SimpleKerns, crossStream bool, font *Font, buffer *Buffer, kernMask GlyphMask, scale bool) {
 func kern(driver fontP.SimpleKerns, crossStream bool, font *Font, buffer *Buffer, kernMask GlyphMask, scale bool) {
+	buffer.unsafeToConcat(0, maxInt)
 	c := newOtApplyContext(1, font, buffer)
 	c := newOtApplyContext(1, font, buffer)
 	c.setLookupMask(kernMask)
 	c.setLookupMask(kernMask)
 	c.setLookupProps(uint32(otIgnoreMarks))
 	c.setLookupProps(uint32(otIgnoreMarks))
@@ -26,7 +27,7 @@ func kern(driver fontP.SimpleKerns, crossStream bool, font *Font, buffer *Buffer
 		}
 		}
 
 
 		skippyIter.reset(idx, 1)
 		skippyIter.reset(idx, 1)
-		if !skippyIter.next() {
+		if ok, _ := skippyIter.next(); !ok {
 			idx++
 			idx++
 			continue
 			continue
 		}
 		}

+ 21 - 63
vendor/github.com/go-text/typesetting/harfbuzz/ot_khmer.go

@@ -21,11 +21,11 @@ var khmerFeatures = [...]otMapFeature{
 	* Basic features.
 	* Basic features.
 	* These features are applied in order, one at a time, after reordering.
 	* These features are applied in order, one at a time, after reordering.
 	 */
 	 */
-	{loader.NewTag('p', 'r', 'e', 'f'), ffManualJoiners},
-	{loader.NewTag('b', 'l', 'w', 'f'), ffManualJoiners},
-	{loader.NewTag('a', 'b', 'v', 'f'), ffManualJoiners},
-	{loader.NewTag('p', 's', 't', 'f'), ffManualJoiners},
-	{loader.NewTag('c', 'f', 'a', 'r'), ffManualJoiners},
+	{loader.NewTag('p', 'r', 'e', 'f'), ffManualJoiners | ffPerSyllable},
+	{loader.NewTag('b', 'l', 'w', 'f'), ffManualJoiners | ffPerSyllable},
+	{loader.NewTag('a', 'b', 'v', 'f'), ffManualJoiners | ffPerSyllable},
+	{loader.NewTag('p', 's', 't', 'f'), ffManualJoiners | ffPerSyllable},
+	{loader.NewTag('c', 'f', 'a', 'r'), ffManualJoiners | ffPerSyllable},
 	/*
 	/*
 	* Other features.
 	* Other features.
 	* These features are applied all at once after clearing syllables.
 	* These features are applied all at once after clearing syllables.
@@ -70,15 +70,16 @@ func (cs *complexShaperKhmer) collectFeatures(plan *otShapePlanner) {
 	*
 	*
 	* https://github.com/harfbuzz/harfbuzz/issues/974
 	* https://github.com/harfbuzz/harfbuzz/issues/974
 	 */
 	 */
-	map_.enableFeature(loader.NewTag('l', 'o', 'c', 'l'))
-	map_.enableFeature(loader.NewTag('c', 'c', 'm', 'p'))
+	map_.enableFeatureExt(loader.NewTag('l', 'o', 'c', 'l'), ffPerSyllable, 1)
+	map_.enableFeatureExt(loader.NewTag('c', 'c', 'm', 'p'), ffPerSyllable, 1)
 
 
 	i := 0
 	i := 0
 	for ; i < khmerBasicFeatures; i++ {
 	for ; i < khmerBasicFeatures; i++ {
 		map_.addFeatureExt(khmerFeatures[i].tag, khmerFeatures[i].flags, 1)
 		map_.addFeatureExt(khmerFeatures[i].tag, khmerFeatures[i].flags, 1)
 	}
 	}
 
 
-	map_.addGSUBPause(clearSyllables)
+	// https://github.com/harfbuzz/harfbuzz/issues/3531
+	map_.addGSUBPause(nil)
 
 
 	for ; i < khmerNumFeatures; i++ {
 	for ; i < khmerNumFeatures; i++ {
 		map_.addFeatureExt(khmerFeatures[i].tag, khmerFeatures[i].flags, 1)
 		map_.addFeatureExt(khmerFeatures[i].tag, khmerFeatures[i].flags, 1)
@@ -130,64 +131,19 @@ func (cs *complexShaperKhmer) setupMasks(_ *otShapePlan, buffer *Buffer, _ *Font
 	}
 	}
 }
 }
 
 
-/* Note: This enum is duplicated in the -machine.rl source file.
- * Not sure how to avoid duplication. */
-const (
-	otRobatic = 20
-	otXgroup  = 21
-	otYgroup  = 22
-)
-
 func setKhmerProperties(info *GlyphInfo) {
 func setKhmerProperties(info *GlyphInfo) {
 	u := info.codepoint
 	u := info.codepoint
 	type_ := indicGetCategories(u)
 	type_ := indicGetCategories(u)
-	cat := uint8(type_ & 0xFF)
-	pos := uint8(type_ >> 8)
-
-	/*
-	 * Re-assign category
-	 *
-	 * These categories are experimentally extracted from what Uniscribe allows.
-	 */
-	switch u {
-	case 0x179A:
-		cat = otRa
-
-	case 0x17CC, 0x17C9, 0x17CA:
-		cat = otRobatic
-
-	case 0x17C6, 0x17CB, 0x17CD, 0x17CE, 0x17CF, 0x17D0, 0x17D1:
-		cat = otXgroup
-
-	case 0x17C7, 0x17C8, 0x17DD, 0x17D3: /* Just guessing. Uniscribe doesn't categorize it. */
-		cat = otYgroup
-	}
-
-	/*
-	 * Re-assign position.
-	 */
-	if cat == otM {
-		switch pos {
-		case posPreC:
-			cat = otVPre
-		case posBelowC:
-			cat = otVBlw
-		case posAboveC:
-			cat = otVAbv
-		case posPostC:
-			cat = otVPst
-		}
-	}
-
-	info.complexCategory = cat
+	info.complexCategory = uint8(type_ & 0xFF)
 }
 }
 
 
-func setupSyllablesKhmer(_ *otShapePlan, _ *Font, buffer *Buffer) {
+func setupSyllablesKhmer(_ *otShapePlan, _ *Font, buffer *Buffer) bool {
 	findSyllablesKhmer(buffer)
 	findSyllablesKhmer(buffer)
 	iter, count := buffer.syllableIterator()
 	iter, count := buffer.syllableIterator()
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 		buffer.unsafeToBreak(start, end)
 		buffer.unsafeToBreak(start, end)
 	}
 	}
+	return false
 }
 }
 
 
 func foundSyllableKhmer(syllableType uint8, ts, te int, info []GlyphInfo, syllableSerial *uint8) {
 func foundSyllableKhmer(syllableType uint8, ts, te int, info []GlyphInfo, syllableSerial *uint8) {
@@ -230,10 +186,10 @@ func (khmerPlan *khmerShapePlan) reorderConsonantSyllable(buffer *Buffer, start,
 		 * the 'pref' OpenType feature applied to them.
 		 * the 'pref' OpenType feature applied to them.
 		 * """
 		 * """
 		 */
 		 */
-		if info[i].complexCategory == otCoeng && numCoengs <= 2 && i+1 < end {
+		if info[i].complexCategory == khmSM_ex_H && numCoengs <= 2 && i+1 < end {
 			numCoengs++
 			numCoengs++
 
 
-			if info[i+1].complexCategory == otRa {
+			if info[i+1].complexCategory == khmSM_ex_Ra {
 				for j := 0; j < 2; j++ {
 				for j := 0; j < 2; j++ {
 					info[i+j].Mask |= khmerPlan.maskArray[khmerPref]
 					info[i+j].Mask |= khmerPlan.maskArray[khmerPref]
 				}
 				}
@@ -260,7 +216,7 @@ func (khmerPlan *khmerShapePlan) reorderConsonantSyllable(buffer *Buffer, start,
 
 
 				numCoengs = 2 /* Done. */
 				numCoengs = 2 /* Done. */
 			}
 			}
-		} else if info[i].complexCategory == otVPre { /* Reorder left matra piece. */
+		} else if info[i].complexCategory == khmSM_ex_VPre { /* Reorder left matra piece. */
 			/* Move to the start. */
 			/* Move to the start. */
 			buffer.mergeClusters(start, i+1)
 			buffer.mergeClusters(start, i+1)
 			t := info[i]
 			t := info[i]
@@ -279,20 +235,22 @@ func (cs *complexShaperKhmer) reorderSyllableKhmer(buffer *Buffer, start, end in
 	}
 	}
 }
 }
 
 
-func (cs *complexShaperKhmer) reorderKhmer(_ *otShapePlan, font *Font, buffer *Buffer) {
-	if debugMode >= 1 {
+func (cs *complexShaperKhmer) reorderKhmer(_ *otShapePlan, font *Font, buffer *Buffer) bool {
+	if debugMode {
 		fmt.Println("KHMER - start reordering khmer")
 		fmt.Println("KHMER - start reordering khmer")
 	}
 	}
 
 
-	syllabicInsertDottedCircles(font, buffer, khmerBrokenCluster, otDOTTEDCIRCLE, otRepha, -1)
+	ret := syllabicInsertDottedCircles(font, buffer, khmerBrokenCluster, khmSM_ex_DOTTEDCIRCLE, -1, -1)
 	iter, count := buffer.syllableIterator()
 	iter, count := buffer.syllableIterator()
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 		cs.reorderSyllableKhmer(buffer, start, end)
 		cs.reorderSyllableKhmer(buffer, start, end)
 	}
 	}
 
 
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("KHMER - end reordering khmer")
 		fmt.Println("KHMER - end reordering khmer")
 	}
 	}
+
+	return ret
 }
 }
 
 
 func (complexShaperKhmer) decompose(c *otNormalizeContext, ab rune) (rune, rune, bool) {
 func (complexShaperKhmer) decompose(c *otNormalizeContext, ab rune) (rune, rune, bool) {

+ 160 - 142
vendor/github.com/go-text/typesetting/harfbuzz/ot_khmer_machine.go

@@ -10,173 +10,188 @@ const (
 	khmerNonKhmerCluster
 	khmerNonKhmerCluster
 )
 )
 
 
-const khmerSyllableMachine_ex_C = 1
-const khmerSyllableMachine_ex_Coeng = 14
-const khmerSyllableMachine_ex_DOTTEDCIRCLE = 12
-const khmerSyllableMachine_ex_PLACEHOLDER = 11
-const khmerSyllableMachine_ex_Ra = 16
-const khmerSyllableMachine_ex_Robatic = 20
-const khmerSyllableMachine_ex_V = 2
-const khmerSyllableMachine_ex_VAbv = 26
-const khmerSyllableMachine_ex_VBlw = 27
-const khmerSyllableMachine_ex_VPre = 28
-const khmerSyllableMachine_ex_VPst = 29
-const khmerSyllableMachine_ex_Xgroup = 21
-const khmerSyllableMachine_ex_Ygroup = 22
-const khmerSyllableMachine_ex_ZWJ = 6
-const khmerSyllableMachine_ex_ZWNJ = 5
-
-var _khmerSyllableMachine_actions []byte = []byte{
+const khmSM_ex_C = 1
+const khmSM_ex_DOTTEDCIRCLE = 11
+const khmSM_ex_H = 4
+const khmSM_ex_PLACEHOLDER = 10
+const khmSM_ex_Ra = 15
+const khmSM_ex_Robatic = 25
+const khmSM_ex_V = 2
+const khmSM_ex_VAbv = 20
+const khmSM_ex_VBlw = 21
+const khmSM_ex_VPre = 22
+const khmSM_ex_VPst = 23
+const khmSM_ex_Xgroup = 26
+const khmSM_ex_Ygroup = 27
+const khmSM_ex_ZWJ = 6
+const khmSM_ex_ZWNJ = 5
+
+var _khmSM_actions []byte = []byte{
 	0, 1, 0, 1, 1, 1, 2, 1, 5,
 	0, 1, 0, 1, 1, 1, 2, 1, 5,
 	1, 6, 1, 7, 1, 8, 1, 9,
 	1, 6, 1, 7, 1, 8, 1, 9,
 	1, 10, 1, 11, 2, 2, 3, 2,
 	1, 10, 1, 11, 2, 2, 3, 2,
 	2, 4,
 	2, 4,
 }
 }
 
 
-var _khmerSyllableMachine_key_offsets []byte = []byte{
-	0, 5, 8, 12, 15, 18, 21, 25,
-	28, 32, 35, 38, 42, 45, 48, 51,
-	55, 58, 62, 65, 70, 84, 94, 103,
-	109, 110, 115, 122, 130, 139, 142, 146,
-	155, 161, 162, 167, 174, 182, 185, 195,
+var _khmSM_key_offsets []byte = []byte{
+	0, 5, 8, 11, 15, 18, 21, 25,
+	28, 32, 35, 40, 45, 48, 51, 55,
+	58, 61, 65, 68, 72, 75, 90, 100,
+	103, 113, 122, 123, 129, 134, 141, 149,
+	158, 168, 171, 181, 190, 191, 197, 202,
+	209, 217, 226,
 }
 }
 
 
-var _khmerSyllableMachine_trans_keys []byte = []byte{
-	20, 21, 26, 5, 6, 21, 5, 6,
-	21, 26, 5, 6, 21, 5, 6, 16,
-	1, 2, 21, 5, 6, 21, 26, 5,
-	6, 21, 5, 6, 21, 26, 5, 6,
-	21, 5, 6, 21, 5, 6, 21, 26,
-	5, 6, 21, 5, 6, 16, 1, 2,
-	21, 5, 6, 21, 26, 5, 6, 21,
-	5, 6, 21, 26, 5, 6, 21, 5,
-	6, 20, 21, 26, 5, 6, 14, 16,
-	21, 22, 26, 27, 28, 29, 1, 2,
-	5, 6, 11, 12, 14, 20, 21, 22,
-	26, 27, 28, 29, 5, 6, 14, 21,
-	22, 26, 27, 28, 29, 5, 6, 14,
-	21, 22, 29, 5, 6, 22, 14, 21,
-	22, 5, 6, 14, 21, 22, 26, 29,
-	5, 6, 14, 21, 22, 26, 27, 29,
-	5, 6, 14, 21, 22, 26, 27, 28,
-	29, 5, 6, 16, 1, 2, 21, 26,
-	5, 6, 14, 21, 22, 26, 27, 28,
-	29, 5, 6, 14, 21, 22, 29, 5,
-	6, 22, 14, 21, 22, 5, 6, 14,
-	21, 22, 26, 29, 5, 6, 14, 21,
-	22, 26, 27, 29, 5, 6, 16, 1,
-	2, 14, 20, 21, 22, 26, 27, 28,
-	29, 5, 6, 14, 21, 22, 26, 27,
-	28, 29, 5, 6,
+var _khmSM_trans_keys []byte = []byte{
+	20, 25, 26, 5, 6, 26, 5, 6,
+	15, 1, 2, 20, 26, 5, 6, 26,
+	5, 6, 26, 5, 6, 20, 26, 5,
+	6, 26, 5, 6, 20, 26, 5, 6,
+	26, 5, 6, 20, 25, 26, 5, 6,
+	20, 25, 26, 5, 6, 26, 5, 6,
+	15, 1, 2, 20, 26, 5, 6, 26,
+	5, 6, 26, 5, 6, 20, 26, 5,
+	6, 26, 5, 6, 20, 26, 5, 6,
+	26, 5, 6, 4, 15, 20, 21, 22,
+	23, 25, 26, 27, 1, 2, 5, 6,
+	10, 11, 4, 20, 21, 22, 23, 25,
+	26, 27, 5, 6, 15, 1, 2, 4,
+	20, 21, 22, 23, 25, 26, 27, 5,
+	6, 4, 20, 21, 22, 23, 26, 27,
+	5, 6, 27, 4, 23, 26, 27, 5,
+	6, 4, 26, 27, 5, 6, 4, 20,
+	23, 26, 27, 5, 6, 4, 20, 21,
+	23, 26, 27, 5, 6, 4, 20, 21,
+	22, 23, 26, 27, 5, 6, 4, 20,
+	21, 22, 23, 25, 26, 27, 5, 6,
+	15, 1, 2, 4, 20, 21, 22, 23,
+	25, 26, 27, 5, 6, 4, 20, 21,
+	22, 23, 26, 27, 5, 6, 27, 4,
+	23, 26, 27, 5, 6, 4, 26, 27,
+	5, 6, 4, 20, 23, 26, 27, 5,
+	6, 4, 20, 21, 23, 26, 27, 5,
+	6, 4, 20, 21, 22, 23, 26, 27,
+	5, 6, 20, 26, 5, 6,
 }
 }
 
 
-var _khmerSyllableMachine_single_lengths []byte = []byte{
-	3, 1, 2, 1, 1, 1, 2, 1,
-	2, 1, 1, 2, 1, 1, 1, 2,
-	1, 2, 1, 3, 8, 8, 7, 4,
-	1, 3, 5, 6, 7, 1, 2, 7,
-	4, 1, 3, 5, 6, 1, 8, 7,
+var _khmSM_single_lengths []byte = []byte{
+	3, 1, 1, 2, 1, 1, 2, 1,
+	2, 1, 3, 3, 1, 1, 2, 1,
+	1, 2, 1, 2, 1, 9, 8, 1,
+	8, 7, 1, 4, 3, 5, 6, 7,
+	8, 1, 8, 7, 1, 4, 3, 5,
+	6, 7, 2,
 }
 }
 
 
-var _khmerSyllableMachine_range_lengths []byte = []byte{
+var _khmSM_range_lengths []byte = []byte{
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1, 3, 1, 1, 1,
-	0, 1, 1, 1, 1, 1, 1, 1,
-	1, 0, 1, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 1, 3, 1, 1,
+	1, 1, 0, 1, 1, 1, 1, 1,
+	1, 1, 1, 1, 0, 1, 1, 1,
+	1, 1, 1,
 }
 }
 
 
-var _khmerSyllableMachine_index_offsets []byte = []byte{
-	0, 5, 8, 12, 15, 18, 21, 25,
-	28, 32, 35, 38, 42, 45, 48, 51,
-	55, 58, 62, 65, 70, 82, 92, 101,
-	107, 109, 114, 121, 129, 138, 141, 145,
-	154, 160, 162, 167, 174, 182, 185, 195,
+var _khmSM_index_offsets []int16 = []int16{
+	0, 5, 8, 11, 15, 18, 21, 25,
+	28, 32, 35, 40, 45, 48, 51, 55,
+	58, 61, 65, 68, 72, 75, 88, 98,
+	101, 111, 120, 122, 128, 133, 140, 148,
+	157, 167, 170, 180, 189, 191, 197, 202,
+	209, 217, 226,
 }
 }
 
 
-var _khmerSyllableMachine_indicies []byte = []byte{
-	2, 3, 4, 1, 0, 3, 1, 0,
-	3, 4, 1, 0, 4, 5, 0, 6,
-	6, 0, 8, 7, 0, 10, 4, 9,
-	0, 10, 9, 0, 12, 4, 11, 0,
-	12, 11, 0, 15, 14, 13, 15, 17,
-	14, 16, 17, 18, 16, 19, 19, 16,
-	21, 20, 16, 23, 17, 22, 16, 23,
-	22, 16, 25, 17, 24, 16, 25, 24,
-	16, 26, 15, 17, 14, 16, 30, 28,
-	15, 19, 17, 23, 25, 21, 28, 29,
-	2, 27, 33, 2, 3, 6, 4, 10,
-	12, 8, 32, 31, 35, 3, 6, 4,
-	10, 12, 8, 34, 31, 35, 4, 6,
-	8, 5, 31, 6, 31, 35, 8, 6,
-	7, 31, 35, 10, 6, 4, 8, 36,
-	31, 35, 12, 6, 4, 10, 8, 37,
-	31, 33, 3, 6, 4, 10, 12, 8,
-	34, 31, 28, 28, 31, 15, 17, 14,
-	38, 41, 15, 19, 17, 23, 25, 21,
-	40, 39, 41, 17, 19, 21, 18, 39,
-	19, 39, 41, 21, 19, 20, 39, 41,
-	23, 19, 17, 21, 42, 39, 41, 25,
-	19, 17, 23, 21, 43, 39, 44, 44,
-	39, 30, 26, 15, 19, 17, 23, 25,
-	21, 45, 39, 30, 15, 19, 17, 23,
-	25, 21, 40, 39,
+var _khmSM_indicies []byte = []byte{
+	2, 3, 4, 1, 0, 4, 1, 0,
+	5, 5, 0, 2, 4, 1, 0, 2,
+	6, 0, 8, 7, 0, 2, 10, 9,
+	0, 10, 9, 0, 2, 12, 11, 0,
+	12, 11, 0, 2, 13, 4, 1, 0,
+	16, 17, 18, 15, 14, 18, 15, 19,
+	20, 20, 14, 16, 18, 15, 14, 16,
+	21, 14, 23, 22, 14, 16, 25, 24,
+	14, 25, 24, 14, 16, 27, 26, 14,
+	27, 26, 14, 30, 29, 16, 25, 27,
+	23, 17, 18, 20, 29, 31, 13, 28,
+	33, 2, 10, 12, 8, 13, 4, 5,
+	34, 32, 35, 35, 32, 33, 2, 10,
+	12, 8, 3, 4, 5, 36, 32, 37,
+	2, 10, 12, 8, 4, 5, 38, 32,
+	5, 32, 37, 8, 2, 5, 6, 32,
+	37, 8, 5, 7, 32, 37, 2, 8,
+	10, 5, 39, 32, 37, 2, 10, 8,
+	12, 5, 40, 32, 33, 2, 10, 12,
+	8, 4, 5, 38, 32, 33, 2, 10,
+	12, 8, 3, 4, 5, 38, 32, 42,
+	42, 41, 30, 16, 25, 27, 23, 17,
+	18, 20, 43, 41, 44, 16, 25, 27,
+	23, 18, 20, 45, 41, 20, 41, 44,
+	23, 16, 20, 21, 41, 44, 23, 20,
+	22, 41, 44, 16, 23, 25, 20, 46,
+	41, 44, 16, 25, 23, 27, 20, 47,
+	41, 30, 16, 25, 27, 23, 18, 20,
+	45, 41, 16, 18, 15, 48,
 }
 }
 
 
-var _khmerSyllableMachine_trans_targs []byte = []byte{
-	20, 1, 28, 22, 23, 3, 24, 5,
-	25, 7, 26, 9, 27, 20, 10, 31,
-	20, 32, 12, 33, 14, 34, 16, 35,
-	18, 36, 39, 20, 21, 30, 37, 20,
-	0, 29, 2, 4, 6, 8, 20, 20,
-	11, 13, 15, 17, 38, 19,
+var _khmSM_trans_targs []byte = []byte{
+	21, 1, 27, 31, 25, 26, 4, 5,
+	28, 7, 29, 9, 30, 32, 21, 12,
+	37, 41, 35, 21, 36, 15, 16, 38,
+	18, 39, 20, 40, 21, 22, 33, 42,
+	21, 23, 10, 24, 0, 2, 3, 6,
+	8, 21, 34, 11, 13, 14, 17, 19,
+	21,
 }
 }
 
 
-var _khmerSyllableMachine_trans_actions []byte = []byte{
+var _khmSM_trans_actions []byte = []byte{
 	15, 0, 5, 5, 5, 0, 0, 0,
 	15, 0, 5, 5, 5, 0, 0, 0,
-	5, 0, 5, 0, 5, 19, 0, 21,
-	17, 5, 0, 0, 0, 5, 0, 5,
-	0, 5, 21, 7, 5, 24, 0, 9,
-	0, 0, 0, 0, 0, 0, 13, 11,
-	0, 0, 0, 0, 21, 0,
+	5, 0, 5, 0, 5, 5, 17, 0,
+	5, 21, 21, 19, 0, 0, 0, 5,
+	0, 5, 0, 5, 7, 5, 0, 24,
+	9, 0, 0, 5, 0, 0, 0, 0,
+	0, 11, 21, 0, 0, 0, 0, 0,
+	13,
 }
 }
 
 
-var _khmerSyllableMachine_to_state_actions []byte = []byte{
+var _khmSM_to_state_actions []byte = []byte{
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 1, 0, 0, 0,
+	0, 0, 0, 0, 0, 1, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0,
 }
 }
 
 
-var _khmerSyllableMachine_from_state_actions []byte = []byte{
+var _khmSM_from_state_actions []byte = []byte{
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 3, 0, 0, 0,
+	0, 0, 0, 0, 0, 3, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0,
 }
 }
 
 
-var _khmerSyllableMachine_eof_trans []byte = []byte{
+var _khmSM_eof_trans []int16 = []int16{
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 14, 17, 17, 17, 17, 17,
-	17, 17, 17, 17, 0, 32, 32, 32,
-	32, 32, 32, 32, 32, 32, 39, 40,
-	40, 40, 40, 40, 40, 40, 40, 40,
+	1, 1, 1, 15, 20, 15, 15, 15,
+	15, 15, 15, 15, 15, 0, 33, 33,
+	33, 33, 33, 33, 33, 33, 33, 33,
+	33, 42, 42, 42, 42, 42, 42, 42,
+	42, 42, 49,
 }
 }
 
 
-const khmerSyllableMachine_start int = 20
-const khmerSyllableMachine_first_final int = 20
-const khmerSyllableMachine_error int = -1
+const khmSM_start int = 21
+const khmSM_first_final int = 21
+const khmSM_error int = -1
 
 
-const khmerSyllableMachine_en_main int = 20
+const khmSM_en_main int = 21
 
 
 func findSyllablesKhmer(buffer *Buffer) {
 func findSyllablesKhmer(buffer *Buffer) {
 	var p, ts, te, act, cs int
 	var p, ts, te, act, cs int
 	info := buffer.Info
 	info := buffer.Info
 
 
 	{
 	{
-		cs = khmerSyllableMachine_start
+		cs = khmSM_start
 		ts = 0
 		ts = 0
 		te = 0
 		te = 0
 		act = 0
 		act = 0
@@ -197,22 +212,22 @@ func findSyllablesKhmer(buffer *Buffer) {
 			goto _test_eof
 			goto _test_eof
 		}
 		}
 	_resume:
 	_resume:
-		_acts = int(_khmerSyllableMachine_from_state_actions[cs])
-		_nacts = uint(_khmerSyllableMachine_actions[_acts])
+		_acts = int(_khmSM_from_state_actions[cs])
+		_nacts = uint(_khmSM_actions[_acts])
 		_acts++
 		_acts++
 		for ; _nacts > 0; _nacts-- {
 		for ; _nacts > 0; _nacts-- {
 			_acts++
 			_acts++
-			switch _khmerSyllableMachine_actions[_acts-1] {
+			switch _khmSM_actions[_acts-1] {
 			case 1:
 			case 1:
 				ts = p
 				ts = p
 
 
 			}
 			}
 		}
 		}
 
 
-		_keys = int(_khmerSyllableMachine_key_offsets[cs])
-		_trans = int(_khmerSyllableMachine_index_offsets[cs])
+		_keys = int(_khmSM_key_offsets[cs])
+		_trans = int(_khmSM_index_offsets[cs])
 
 
-		_klen = int(_khmerSyllableMachine_single_lengths[cs])
+		_klen = int(_khmSM_single_lengths[cs])
 		if _klen > 0 {
 		if _klen > 0 {
 			_lower := int(_keys)
 			_lower := int(_keys)
 			var _mid int
 			var _mid int
@@ -224,9 +239,9 @@ func findSyllablesKhmer(buffer *Buffer) {
 
 
 				_mid = _lower + ((_upper - _lower) >> 1)
 				_mid = _lower + ((_upper - _lower) >> 1)
 				switch {
 				switch {
-				case (info[p].complexCategory) < _khmerSyllableMachine_trans_keys[_mid]:
+				case (info[p].complexCategory) < _khmSM_trans_keys[_mid]:
 					_upper = _mid - 1
 					_upper = _mid - 1
-				case (info[p].complexCategory) > _khmerSyllableMachine_trans_keys[_mid]:
+				case (info[p].complexCategory) > _khmSM_trans_keys[_mid]:
 					_lower = _mid + 1
 					_lower = _mid + 1
 				default:
 				default:
 					_trans += int(_mid - int(_keys))
 					_trans += int(_mid - int(_keys))
@@ -237,7 +252,7 @@ func findSyllablesKhmer(buffer *Buffer) {
 			_trans += _klen
 			_trans += _klen
 		}
 		}
 
 
-		_klen = int(_khmerSyllableMachine_range_lengths[cs])
+		_klen = int(_khmSM_range_lengths[cs])
 		if _klen > 0 {
 		if _klen > 0 {
 			_lower := int(_keys)
 			_lower := int(_keys)
 			var _mid int
 			var _mid int
@@ -249,9 +264,9 @@ func findSyllablesKhmer(buffer *Buffer) {
 
 
 				_mid = _lower + (((_upper - _lower) >> 1) & ^1)
 				_mid = _lower + (((_upper - _lower) >> 1) & ^1)
 				switch {
 				switch {
-				case (info[p].complexCategory) < _khmerSyllableMachine_trans_keys[_mid]:
+				case (info[p].complexCategory) < _khmSM_trans_keys[_mid]:
 					_upper = _mid - 2
 					_upper = _mid - 2
-				case (info[p].complexCategory) > _khmerSyllableMachine_trans_keys[_mid+1]:
+				case (info[p].complexCategory) > _khmSM_trans_keys[_mid+1]:
 					_lower = _mid + 2
 					_lower = _mid + 2
 				default:
 				default:
 					_trans += int((_mid - int(_keys)) >> 1)
 					_trans += int((_mid - int(_keys)) >> 1)
@@ -262,20 +277,20 @@ func findSyllablesKhmer(buffer *Buffer) {
 		}
 		}
 
 
 	_match:
 	_match:
-		_trans = int(_khmerSyllableMachine_indicies[_trans])
+		_trans = int(_khmSM_indicies[_trans])
 	_eof_trans:
 	_eof_trans:
-		cs = int(_khmerSyllableMachine_trans_targs[_trans])
+		cs = int(_khmSM_trans_targs[_trans])
 
 
-		if _khmerSyllableMachine_trans_actions[_trans] == 0 {
+		if _khmSM_trans_actions[_trans] == 0 {
 			goto _again
 			goto _again
 		}
 		}
 
 
-		_acts = int(_khmerSyllableMachine_trans_actions[_trans])
-		_nacts = uint(_khmerSyllableMachine_actions[_acts])
+		_acts = int(_khmSM_trans_actions[_trans])
+		_nacts = uint(_khmSM_actions[_acts])
 		_acts++
 		_acts++
 		for ; _nacts > 0; _nacts-- {
 		for ; _nacts > 0; _nacts-- {
 			_acts++
 			_acts++
-			switch _khmerSyllableMachine_actions[_acts-1] {
+			switch _khmSM_actions[_acts-1] {
 			case 2:
 			case 2:
 				te = p + 1
 				te = p + 1
 
 
@@ -299,6 +314,7 @@ func findSyllablesKhmer(buffer *Buffer) {
 				p--
 				p--
 				{
 				{
 					foundSyllableKhmer(khmerBrokenCluster, ts, te, info, &syllableSerial)
 					foundSyllableKhmer(khmerBrokenCluster, ts, te, info, &syllableSerial)
+					buffer.scratchFlags |= bsfHasBrokenSyllable
 				}
 				}
 			case 8:
 			case 8:
 				te = p
 				te = p
@@ -315,6 +331,7 @@ func findSyllablesKhmer(buffer *Buffer) {
 				p = (te) - 1
 				p = (te) - 1
 				{
 				{
 					foundSyllableKhmer(khmerBrokenCluster, ts, te, info, &syllableSerial)
 					foundSyllableKhmer(khmerBrokenCluster, ts, te, info, &syllableSerial)
+					buffer.scratchFlags |= bsfHasBrokenSyllable
 				}
 				}
 			case 11:
 			case 11:
 				switch act {
 				switch act {
@@ -322,6 +339,7 @@ func findSyllablesKhmer(buffer *Buffer) {
 					{
 					{
 						p = (te) - 1
 						p = (te) - 1
 						foundSyllableKhmer(khmerBrokenCluster, ts, te, info, &syllableSerial)
 						foundSyllableKhmer(khmerBrokenCluster, ts, te, info, &syllableSerial)
+						buffer.scratchFlags |= bsfHasBrokenSyllable
 					}
 					}
 				case 3:
 				case 3:
 					{
 					{
@@ -334,12 +352,12 @@ func findSyllablesKhmer(buffer *Buffer) {
 		}
 		}
 
 
 	_again:
 	_again:
-		_acts = int(_khmerSyllableMachine_to_state_actions[cs])
-		_nacts = uint(_khmerSyllableMachine_actions[_acts])
+		_acts = int(_khmSM_to_state_actions[cs])
+		_nacts = uint(_khmSM_actions[_acts])
 		_acts++
 		_acts++
 		for ; _nacts > 0; _nacts-- {
 		for ; _nacts > 0; _nacts-- {
 			_acts++
 			_acts++
-			switch _khmerSyllableMachine_actions[_acts-1] {
+			switch _khmSM_actions[_acts-1] {
 			case 0:
 			case 0:
 				ts = 0
 				ts = 0
 
 
@@ -354,8 +372,8 @@ func findSyllablesKhmer(buffer *Buffer) {
 		{
 		{
 		}
 		}
 		if p == eof {
 		if p == eof {
-			if _khmerSyllableMachine_eof_trans[cs] > 0 {
-				_trans = int(_khmerSyllableMachine_eof_trans[cs] - 1)
+			if _khmSM_eof_trans[cs] > 0 {
+				_trans = int(_khmSM_eof_trans[cs] - 1)
 				goto _eof_trans
 				goto _eof_trans
 			}
 			}
 		}
 		}

+ 19 - 15
vendor/github.com/go-text/typesetting/harfbuzz/ot_khmer_machine.rl

@@ -12,7 +12,7 @@ const (
 )
 )
 
 
 %%{
 %%{
-  machine khmerSyllableMachine;
+  machine khmSM;
   alphtype byte;
   alphtype byte;
   write exports;
   write exports;
   write data;
   write data;
@@ -20,21 +20,25 @@ const (
 
 
 %%{
 %%{
 
 
+# We use category H for spec category Coeng
+
 export C    = 1;
 export C    = 1;
 export V    = 2;
 export V    = 2;
+export H    = 4;
 export ZWNJ = 5;
 export ZWNJ = 5;
 export ZWJ  = 6;
 export ZWJ  = 6;
-export PLACEHOLDER = 11;
-export DOTTEDCIRCLE = 12;
-export Coeng= 14;
-export Ra   = 16;
-export Robatic = 20;
-export Xgroup  = 21;
-export Ygroup  = 22;
-export VAbv = 26;
-export VBlw = 27;
-export VPre = 28;
-export VPst = 29;
+export PLACEHOLDER = 10;
+export DOTTEDCIRCLE = 11;
+export Ra   = 15;
+
+export VAbv = 20;
+export VBlw = 21;
+export VPre = 22;
+export VPst = 23;
+
+export Robatic = 25;
+export Xgroup  = 26;
+export Ygroup  = 27;
 
 
 c = (C | Ra | V);
 c = (C | Ra | V);
 cn = c.((ZWJ|ZWNJ)?.Robatic)?;
 cn = c.((ZWJ|ZWNJ)?.Robatic)?;
@@ -45,16 +49,16 @@ ygroup = Ygroup*;
 # This grammar was experimentally extracted from what Uniscribe allows.
 # This grammar was experimentally extracted from what Uniscribe allows.
 
 
 matra_group = VPre? xgroup VBlw? xgroup (joiner?.VAbv)? xgroup VPst?;
 matra_group = VPre? xgroup VBlw? xgroup (joiner?.VAbv)? xgroup VPst?;
-syllable_tail = xgroup matra_group xgroup (Coeng.c)? ygroup;
+syllable_tail = xgroup matra_group xgroup (H.c)? ygroup;
 
 
 
 
-broken_cluster =	(Coeng.cn)* (Coeng | syllable_tail);
+broken_cluster =	Robatic? (H.cn)* (H | syllable_tail);
 consonant_syllable =	(cn|PLACEHOLDER|DOTTEDCIRCLE) broken_cluster;
 consonant_syllable =	(cn|PLACEHOLDER|DOTTEDCIRCLE) broken_cluster;
 other =			any;
 other =			any;
 
 
 main := |*
 main := |*
 	consonant_syllable	=> { foundSyllableKhmer (khmerConsonantSyllable, ts, te, info, &syllableSerial); };
 	consonant_syllable	=> { foundSyllableKhmer (khmerConsonantSyllable, ts, te, info, &syllableSerial); };
-	broken_cluster		=> { foundSyllableKhmer (khmerBrokenCluster, ts, te, info, &syllableSerial); };
+	broken_cluster		=> { foundSyllableKhmer (khmerBrokenCluster, ts, te, info, &syllableSerial); buffer.scratchFlags |= bsfHasBrokenSyllable; };
 	other			=> { foundSyllableKhmer (khmerNonKhmerCluster, ts, te, info, &syllableSerial); };
 	other			=> { foundSyllableKhmer (khmerNonKhmerCluster, ts, te, info, &syllableSerial); };
 *|;
 *|;
 
 

+ 4 - 0
vendor/github.com/go-text/typesetting/harfbuzz/ot_language.go

@@ -51,6 +51,10 @@ func bfindLanguage(lang string) int {
 
 
 func subtagMatches(langStr string, subtag string) bool {
 func subtagMatches(langStr string, subtag string) bool {
 	LS := len(subtag)
 	LS := len(subtag)
+	if len(langStr) < LS {
+		return false
+	}
+
 	for {
 	for {
 		s := strings.Index(langStr, subtag)
 		s := strings.Index(langStr, subtag)
 		if s == -1 {
 		if s == -1 {

+ 60 - 37
vendor/github.com/go-text/typesetting/harfbuzz/ot_language_table.go

@@ -49,7 +49,8 @@ var otLanguages = [...]langTag{
 	{"aii", 0x53595220},     /* Assyrian Neo-Aramaic -> Syriac */
 	{"aii", 0x53595220},     /* Assyrian Neo-Aramaic -> Syriac */
 	/*{"aio",	0x41494f20},*/ /* Aiton */
 	/*{"aio",	0x41494f20},*/ /* Aiton */
 	{"aiw", 0x41524920},     /* Aari */
 	{"aiw", 0x41524920},     /* Aari */
-	{"ajp", 0x41524120},     /* South Levantine Arabic -> Arabic */
+	{"ajp", 0x41524120},     /* South Levantine Arabic (retired code) (retired code) -> Arabic */
+	{"ajt", 0x41524120},     /* Judeo-Tunisian Arabic (retired code) (retired code) -> Arabic */
 	{"ak", 0x414b4120},      /* Akan [macrolanguage] */
 	{"ak", 0x414b4120},      /* Akan [macrolanguage] */
 	{"akb", 0x414b4220},     /* Batak Angkola */
 	{"akb", 0x414b4220},     /* Batak Angkola */
 	{"akb", 0x42544b20},     /* Batak Angkola -> Batak */
 	{"akb", 0x42544b20},     /* Batak Angkola -> Batak */
@@ -62,8 +63,8 @@ var otLanguages = [...]langTag{
 	{"an", 0x41524720},      /* Aragonese */
 	{"an", 0x41524720},      /* Aragonese */
 	/*{"ang",	0x414e4720},*/ /* Old English (ca. 450-1100) -> Anglo-Saxon */
 	/*{"ang",	0x414e4720},*/ /* Old English (ca. 450-1100) -> Anglo-Saxon */
 	{"aoa", 0x43505020},     /* Angolar -> Creoles */
 	{"aoa", 0x43505020},     /* Angolar -> Creoles */
-	{"apa", 0x41544820},     /* Apache [family] -> Athapaskan */
-	{"apc", 0x41524120},     /* North Levantine Arabic -> Arabic */
+	{"apa", 0x41544820},     /* Apache [collection] -> Athapaskan */
+	{"apc", 0x41524120},     /* Levantine Arabic -> Arabic */
 	{"apd", 0x41524120},     /* Sudanese Arabic -> Arabic */
 	{"apd", 0x41524120},     /* Sudanese Arabic -> Arabic */
 	{"apj", 0x41544820},     /* Jicarilla Apache -> Athapaskan */
 	{"apj", 0x41544820},     /* Jicarilla Apache -> Athapaskan */
 	{"apk", 0x41544820},     /* Kiowa Apache -> Athapaskan */
 	{"apk", 0x41544820},     /* Kiowa Apache -> Athapaskan */
@@ -82,7 +83,7 @@ var otLanguages = [...]langTag{
 	{"arz", 0x41524120},     /* Egyptian Arabic -> Arabic */
 	{"arz", 0x41524120},     /* Egyptian Arabic -> Arabic */
 	{"as", 0x41534d20},      /* Assamese */
 	{"as", 0x41534d20},      /* Assamese */
 	/*{"ast",	0x41535420},*/ /* Asturian */
 	/*{"ast",	0x41535420},*/ /* Asturian */
-	/*{"ath",	0x41544820},*/ /* Athapascan [family] -> Athapaskan */
+	/*{"ath",	0x41544820},*/ /* Athapascan [collection] -> Athapaskan */
 	{"atj", 0x52435220},     /* Atikamekw -> R-Cree */
 	{"atj", 0x52435220},     /* Atikamekw -> R-Cree */
 	{"atv", 0x414c5420},     /* Northern Altai -> Altai */
 	{"atv", 0x414c5420},     /* Northern Altai -> Altai */
 	{"auj", 0x42425220},     /* Awjilah -> Berber */
 	{"auj", 0x42425220},     /* Awjilah -> Berber */
@@ -106,10 +107,10 @@ var otLanguages = [...]langTag{
 	{"azn", 0x4e414820},     /* Western Durango Nahuatl -> Nahuatl */
 	{"azn", 0x4e414820},     /* Western Durango Nahuatl -> Nahuatl */
 	{"azz", 0x4e414820},     /* Highland Puebla Nahuatl -> Nahuatl */
 	{"azz", 0x4e414820},     /* Highland Puebla Nahuatl -> Nahuatl */
 	{"ba", 0x42534820},      /* Bashkir */
 	{"ba", 0x42534820},      /* Bashkir */
-	{"bad", 0x42414430},     /* Banda [family] */
+	{"bad", 0x42414430},     /* Banda [collection] */
 	{"bag", 0},              /* Tuki != Baghelkhandi */
 	{"bag", 0},              /* Tuki != Baghelkhandi */
 	{"bah", 0x43505020},     /* Bahamas Creole English -> Creoles */
 	{"bah", 0x43505020},     /* Bahamas Creole English -> Creoles */
-	{"bai", 0x424d4c20},     /* Bamileke [family] */
+	{"bai", 0x424d4c20},     /* Bamileke [collection] */
 	{"bal", 0x424c4920},     /* Baluchi [macrolanguage] */
 	{"bal", 0x424c4920},     /* Baluchi [macrolanguage] */
 	/*{"ban",	0x42414e20},*/ /* Balinese */
 	/*{"ban",	0x42414e20},*/ /* Balinese */
 	/*{"bar",	0x42415220},*/ /* Bavarian */
 	/*{"bar",	0x42415220},*/ /* Bavarian */
@@ -131,7 +132,7 @@ var otLanguages = [...]langTag{
 	{"bea", 0x41544820},     /* Beaver -> Athapaskan */
 	{"bea", 0x41544820},     /* Beaver -> Athapaskan */
 	{"beb", 0x42544920},     /* Bebele -> Beti */
 	{"beb", 0x42544920},     /* Bebele -> Beti */
 	/*{"bem",	0x42454d20},*/ /* Bemba (Zambia) */
 	/*{"bem",	0x42454d20},*/ /* Bemba (Zambia) */
-	{"ber", 0x42425220},     /* Berber [family] */
+	{"ber", 0x42425220},     /* Berber [collection] */
 	{"bew", 0x43505020},     /* Betawi -> Creoles */
 	{"bew", 0x43505020},     /* Betawi -> Creoles */
 	{"bfl", 0x42414430},     /* Banda-Ndélé -> Banda */
 	{"bfl", 0x42414430},     /* Banda-Ndélé -> Banda */
 	{"bfq", 0x42414420},     /* Badaga */
 	{"bfq", 0x42414420},     /* Badaga */
@@ -199,7 +200,7 @@ var otLanguages = [...]langTag{
 	{"btd", 0x42544b20},     /* Batak Dairi -> Batak */
 	{"btd", 0x42544b20},     /* Batak Dairi -> Batak */
 	{"bti", 0},              /* Burate != Beti */
 	{"bti", 0},              /* Burate != Beti */
 	{"btj", 0x4d4c5920},     /* Bacanese Malay -> Malay */
 	{"btj", 0x4d4c5920},     /* Bacanese Malay -> Malay */
-	/*{"btk",	0x42544b20},*/ /* Batak [family] */
+	/*{"btk",	0x42544b20},*/ /* Batak [collection] */
 	{"btm", 0x42544d20},     /* Batak Mandailing */
 	{"btm", 0x42544d20},     /* Batak Mandailing */
 	{"btm", 0x42544b20},     /* Batak Mandailing -> Batak */
 	{"btm", 0x42544b20},     /* Batak Mandailing -> Batak */
 	{"bto", 0x42494b20},     /* Rinconada Bikol -> Bikol */
 	{"bto", 0x42494b20},     /* Rinconada Bikol -> Bikol */
@@ -252,6 +253,8 @@ var otLanguages = [...]langTag{
 	{"chh", 0},              /* Chinook != Chattisgarhi */
 	{"chh", 0},              /* Chinook != Chattisgarhi */
 	{"chj", 0x4343484e},     /* Ojitlán Chinantec -> Chinantec */
 	{"chj", 0x4343484e},     /* Ojitlán Chinantec -> Chinantec */
 	{"chk", 0x43484b30},     /* Chuukese */
 	{"chk", 0x43484b30},     /* Chuukese */
+	{"chm", 0x484d4120},     /* Mari (Russia) [macrolanguage] -> High Mari */
+	{"chm", 0x4c4d4120},     /* Mari (Russia) [macrolanguage] -> Low Mari */
 	{"chn", 0x43505020},     /* Chinook jargon -> Creoles */
 	{"chn", 0x43505020},     /* Chinook jargon -> Creoles */
 	/*{"cho",	0x43484f20},*/ /* Choctaw */
 	/*{"cho",	0x43484f20},*/ /* Choctaw */
 	{"chp", 0x43485020},     /* Chipewyan */
 	{"chp", 0x43485020},     /* Chipewyan */
@@ -293,10 +296,10 @@ var otLanguages = [...]langTag{
 	/*{"cop",	0x434f5020},*/ /* Coptic */
 	/*{"cop",	0x434f5020},*/ /* Coptic */
 	{"coq", 0x41544820},     /* Coquille -> Athapaskan */
 	{"coq", 0x41544820},     /* Coquille -> Athapaskan */
 	{"cpa", 0x4343484e},     /* Palantla Chinantec -> Chinantec */
 	{"cpa", 0x4343484e},     /* Palantla Chinantec -> Chinantec */
-	{"cpe", 0x43505020},     /* English-based creoles and pidgins [family] -> Creoles */
-	{"cpf", 0x43505020},     /* French-based creoles and pidgins [family] -> Creoles */
+	{"cpe", 0x43505020},     /* English-based creoles and pidgins [collection] -> Creoles */
+	{"cpf", 0x43505020},     /* French-based creoles and pidgins [collection] -> Creoles */
 	{"cpi", 0x43505020},     /* Chinese Pidgin English -> Creoles */
 	{"cpi", 0x43505020},     /* Chinese Pidgin English -> Creoles */
-	/*{"cpp",	0x43505020},*/ /* Portuguese-based creoles and pidgins [family] -> Creoles */
+	/*{"cpp",	0x43505020},*/ /* Portuguese-based creoles and pidgins [collection] -> Creoles */
 	{"cpx", 0x5a485320},     /* Pu-Xian Chinese -> Chinese, Simplified */
 	{"cpx", 0x5a485320},     /* Pu-Xian Chinese -> Chinese, Simplified */
 	{"cqd", 0x484d4e20},     /* Chuanqiandian Cluster Miao -> Hmong */
 	{"cqd", 0x484d4e20},     /* Chuanqiandian Cluster Miao -> Hmong */
 	{"cqu", 0x51554820},     /* Chilean Quechua (retired code) (retired code) -> Quechua (Bolivia) */
 	{"cqu", 0x51554820},     /* Chilean Quechua (retired code) (retired code) -> Quechua (Bolivia) */
@@ -316,7 +319,7 @@ var otLanguages = [...]langTag{
 	{"crm", 0x4d435220},     /* Moose Cree */
 	{"crm", 0x4d435220},     /* Moose Cree */
 	{"crm", 0x4c435220},     /* Moose Cree -> L-Cree */
 	{"crm", 0x4c435220},     /* Moose Cree -> L-Cree */
 	{"crm", 0x43524520},     /* Moose Cree -> Cree */
 	{"crm", 0x43524520},     /* Moose Cree -> Cree */
-	{"crp", 0x43505020},     /* Creoles and pidgins [family] -> Creoles */
+	{"crp", 0x43505020},     /* Creoles and pidgins [collection] -> Creoles */
 	{"crr", 0},              /* Carolina Algonquian != Carrier */
 	{"crr", 0},              /* Carolina Algonquian != Carrier */
 	{"crs", 0x43505020},     /* Seselwa Creole French -> Creoles */
 	{"crs", 0x43505020},     /* Seselwa Creole French -> Creoles */
 	{"crt", 0},              /* Iyojwa'ja Chorote != Crimean Tatar */
 	{"crt", 0},              /* Iyojwa'ja Chorote != Crimean Tatar */
@@ -427,7 +430,7 @@ var otLanguages = [...]langTag{
 	{"et", 0x45544920},      /* Estonian [macrolanguage] */
 	{"et", 0x45544920},      /* Estonian [macrolanguage] */
 	{"eto", 0x42544920},     /* Eton (Cameroon) -> Beti */
 	{"eto", 0x42544920},     /* Eton (Cameroon) -> Beti */
 	{"eu", 0x45555120},      /* Basque */
 	{"eu", 0x45555120},      /* Basque */
-	{"euq", 0},              /* Basque [family] != Basque */
+	{"euq", 0},              /* Basque [collection] != Basque */
 	{"eve", 0x45564e20},     /* Even */
 	{"eve", 0x45564e20},     /* Even */
 	{"evn", 0x45564b20},     /* Evenki */
 	{"evn", 0x45564b20},     /* Evenki */
 	{"ewo", 0x42544920},     /* Ewondo -> Beti */
 	{"ewo", 0x42544920},     /* Ewondo -> Beti */
@@ -615,11 +618,13 @@ var otLanguages = [...]langTag{
 	{"ijc", 0x494a4f20},     /* Izon -> Ijo */
 	{"ijc", 0x494a4f20},     /* Izon -> Ijo */
 	{"ije", 0x494a4f20},     /* Biseni -> Ijo */
 	{"ije", 0x494a4f20},     /* Biseni -> Ijo */
 	{"ijn", 0x494a4f20},     /* Kalabari -> Ijo */
 	{"ijn", 0x494a4f20},     /* Kalabari -> Ijo */
-	/*{"ijo",	0x494a4f20},*/ /* Ijo [family] */
+	/*{"ijo",	0x494a4f20},*/ /* Ijo [collection] */
 	{"ijs", 0x494a4f20},     /* Southeast Ijo -> Ijo */
 	{"ijs", 0x494a4f20},     /* Southeast Ijo -> Ijo */
 	{"ik", 0x49504b20},      /* Inupiaq [macrolanguage] -> Inupiat */
 	{"ik", 0x49504b20},      /* Inupiaq [macrolanguage] -> Inupiat */
 	{"ike", 0x494e5520},     /* Eastern Canadian Inuktitut -> Inuktitut */
 	{"ike", 0x494e5520},     /* Eastern Canadian Inuktitut -> Inuktitut */
+	{"ike", 0x494e554b},     /* Eastern Canadian Inuktitut -> Nunavik Inuktitut */
 	{"ikt", 0x494e5520},     /* Inuinnaqtun -> Inuktitut */
 	{"ikt", 0x494e5520},     /* Inuinnaqtun -> Inuktitut */
+	{"ikt", 0x494e554b},     /* Inuinnaqtun -> Nunavik Inuktitut */
 	/*{"ilo",	0x494c4f20},*/ /* Iloko -> Ilokano */
 	/*{"ilo",	0x494c4f20},*/ /* Iloko -> Ilokano */
 	{"in", 0x494e4420},      /* Indonesian (retired code) (retired code) */
 	{"in", 0x494e4420},      /* Indonesian (retired code) (retired code) */
 	{"in", 0x4d4c5920},      /* Indonesian (retired code) (retired code) -> Malay */
 	{"in", 0x4d4c5920},      /* Indonesian (retired code) (retired code) -> Malay */
@@ -633,6 +638,7 @@ var otLanguages = [...]langTag{
 	{"it", 0x49544120},      /* Italian */
 	{"it", 0x49544120},      /* Italian */
 	{"itz", 0x4d594e20},     /* Itzá -> Mayan */
 	{"itz", 0x4d594e20},     /* Itzá -> Mayan */
 	{"iu", 0x494e5520},      /* Inuktitut [macrolanguage] */
 	{"iu", 0x494e5520},      /* Inuktitut [macrolanguage] */
+	{"iu", 0x494e554b},      /* Inuktitut [macrolanguage] -> Nunavik Inuktitut */
 	{"iw", 0x49575220},      /* Hebrew (retired code) (retired code) */
 	{"iw", 0x49575220},      /* Hebrew (retired code) (retired code) */
 	{"ixl", 0x4d594e20},     /* Ixil -> Mayan */
 	{"ixl", 0x4d594e20},     /* Ixil -> Mayan */
 	{"ja", 0x4a414e20},      /* Japanese */
 	{"ja", 0x4a414e20},      /* Japanese */
@@ -662,7 +668,7 @@ var otLanguages = [...]langTag{
 	{"kab", 0x42425220},     /* Kabyle -> Berber */
 	{"kab", 0x42425220},     /* Kabyle -> Berber */
 	{"kac", 0},              /* Kachin != Kachchi */
 	{"kac", 0},              /* Kachin != Kachchi */
 	{"kam", 0x4b4d4220},     /* Kamba (Kenya) */
 	{"kam", 0x4b4d4220},     /* Kamba (Kenya) */
-	{"kar", 0x4b524e20},     /* Karen [family] */
+	{"kar", 0x4b524e20},     /* Karen [collection] */
 	/*{"kaw",	0x4b415720},*/ /* Kawi (Old Javanese) */
 	/*{"kaw",	0x4b415720},*/ /* Kawi (Old Javanese) */
 	{"kbd", 0x4b414220},     /* Kabardian */
 	{"kbd", 0x4b414220},     /* Kabardian */
 	{"kby", 0x4b4e5220},     /* Manga Kanuri -> Kanuri */
 	{"kby", 0x4b4e5220},     /* Manga Kanuri -> Kanuri */
@@ -800,7 +806,7 @@ var otLanguages = [...]langTag{
 	{"lac", 0x4d594e20},     /* Lacandon -> Mayan */
 	{"lac", 0x4d594e20},     /* Lacandon -> Mayan */
 	{"lad", 0x4a554420},     /* Ladino */
 	{"lad", 0x4a554420},     /* Ladino */
 	{"lah", 0},              /* Lahnda [macrolanguage] != Lahuli */
 	{"lah", 0},              /* Lahnda [macrolanguage] != Lahuli */
-	{"lak", 0},              /* Laka (Nigeria) != Lak */
+	{"lak", 0},              /* Laka (Nigeria) (retired code) (retired code) != Lak */
 	{"lam", 0},              /* Lamba != Lambani */
 	{"lam", 0},              /* Lamba != Lambani */
 	{"laz", 0},              /* Aribwatsa != Laz */
 	{"laz", 0},              /* Aribwatsa != Laz */
 	{"lb", 0x4c545a20},      /* Luxembourgish */
 	{"lb", 0x4c545a20},      /* Luxembourgish */
@@ -871,7 +877,7 @@ var otLanguages = [...]langTag{
 	{"mam", 0x4d414d20},     /* Mam */
 	{"mam", 0x4d414d20},     /* Mam */
 	{"mam", 0x4d594e20},     /* Mam -> Mayan */
 	{"mam", 0x4d594e20},     /* Mam -> Mayan */
 	{"man", 0x4d4e4b20},     /* Mandingo [macrolanguage] -> Maninka */
 	{"man", 0x4d4e4b20},     /* Mandingo [macrolanguage] -> Maninka */
-	{"map", 0},              /* Austronesian [family] != Mapudungun */
+	{"map", 0},              /* Austronesian [collection] != Mapudungun */
 	{"maw", 0},              /* Mampruli != Marwari */
 	{"maw", 0},              /* Mampruli != Marwari */
 	{"max", 0x4d4c5920},     /* North Moluccan Malay -> Malay */
 	{"max", 0x4d4c5920},     /* North Moluccan Malay -> Malay */
 	{"max", 0x43505020},     /* North Moluccan Malay -> Creoles */
 	{"max", 0x43505020},     /* North Moluccan Malay -> Creoles */
@@ -928,8 +934,10 @@ var otLanguages = [...]langTag{
 	{"mnp", 0x5a485320},     /* Min Bei Chinese -> Chinese, Simplified */
 	{"mnp", 0x5a485320},     /* Min Bei Chinese -> Chinese, Simplified */
 	{"mns", 0x4d414e20},     /* Mansi */
 	{"mns", 0x4d414e20},     /* Mansi */
 	{"mnw", 0x4d4f4e20},     /* Mon */
 	{"mnw", 0x4d4f4e20},     /* Mon */
+	{"mnw", 0x4d4f4e54},     /* Mon -> Thailand Mon */
 	{"mnx", 0},              /* Manikion != Manx */
 	{"mnx", 0},              /* Manikion != Manx */
 	{"mo", 0x4d4f4c20},      /* Moldavian (retired code) (retired code) */
 	{"mo", 0x4d4f4c20},      /* Moldavian (retired code) (retired code) */
+	{"mo", 0x524f4d20},      /* Moldavian (retired code) (retired code) -> Romanian */
 	{"mod", 0x43505020},     /* Mobilian -> Creoles */
 	{"mod", 0x43505020},     /* Mobilian -> Creoles */
 	/*{"moh",	0x4d4f4820},*/ /* Mohawk */
 	/*{"moh",	0x4d4f4820},*/ /* Mohawk */
 	{"mok", 0},              /* Morori != Moksha */
 	{"mok", 0},              /* Morori != Moksha */
@@ -951,7 +959,7 @@ var otLanguages = [...]langTag{
 	{"mts", 0},              /* Yora != Maltese */
 	{"mts", 0},              /* Yora != Maltese */
 	{"mud", 0x43505020},     /* Mednyj Aleut -> Creoles */
 	{"mud", 0x43505020},     /* Mednyj Aleut -> Creoles */
 	{"mui", 0x4d4c5920},     /* Musi -> Malay */
 	{"mui", 0x4d4c5920},     /* Musi -> Malay */
-	{"mun", 0},              /* Munda [family] != Mundari */
+	{"mun", 0},              /* Munda [collection] != Mundari */
 	{"mup", 0x52414a20},     /* Malvi -> Rajasthani */
 	{"mup", 0x52414a20},     /* Malvi -> Rajasthani */
 	{"muq", 0x484d4e20},     /* Eastern Xiangxi Miao -> Hmong */
 	{"muq", 0x484d4e20},     /* Eastern Xiangxi Miao -> Hmong */
 	/*{"mus",	0x4d555320},*/ /* Creek -> Muscogee */
 	/*{"mus",	0x4d555320},*/ /* Creek -> Muscogee */
@@ -966,7 +974,7 @@ var otLanguages = [...]langTag{
 	{"mww", 0x484d4e20},     /* Hmong Daw -> Hmong */
 	{"mww", 0x484d4e20},     /* Hmong Daw -> Hmong */
 	{"my", 0x42524d20},      /* Burmese */
 	{"my", 0x42524d20},      /* Burmese */
 	{"mym", 0x4d454e20},     /* Me’en */
 	{"mym", 0x4d454e20},     /* Me’en */
-	/*{"myn",	0x4d594e20},*/ /* Mayan [family] */
+	/*{"myn",	0x4d594e20},*/ /* Mayan [collection] */
 	{"myq", 0x4d4e4b20},     /* Forest Maninka (retired code) (retired code) -> Maninka */
 	{"myq", 0x4d4e4b20},     /* Forest Maninka (retired code) (retired code) -> Maninka */
 	{"myv", 0x45525a20},     /* Erzya */
 	{"myv", 0x45525a20},     /* Erzya */
 	{"mzb", 0x42425220},     /* Tumzabt -> Berber */
 	{"mzb", 0x42425220},     /* Tumzabt -> Berber */
@@ -975,7 +983,7 @@ var otLanguages = [...]langTag{
 	{"na", 0x4e415520},      /* Nauru -> Nauruan */
 	{"na", 0x4e415520},      /* Nauru -> Nauruan */
 	{"nag", 0x4e414720},     /* Naga Pidgin -> Naga-Assamese */
 	{"nag", 0x4e414720},     /* Naga Pidgin -> Naga-Assamese */
 	{"nag", 0x43505020},     /* Naga Pidgin -> Creoles */
 	{"nag", 0x43505020},     /* Naga Pidgin -> Creoles */
-	/*{"nah",	0x4e414820},*/ /* Nahuatl [family] */
+	/*{"nah",	0x4e414820},*/ /* Nahuatl [collection] */
 	{"nan", 0x5a485320},     /* Min Nan Chinese -> Chinese, Simplified */
 	{"nan", 0x5a485320},     /* Min Nan Chinese -> Chinese, Simplified */
 	/*{"nap",	0x4e415020},*/ /* Neapolitan */
 	/*{"nap",	0x4e415020},*/ /* Neapolitan */
 	{"nas", 0},              /* Naasioi != Naskapi */
 	{"nas", 0},              /* Naasioi != Naskapi */
@@ -1083,7 +1091,7 @@ var otLanguages = [...]langTag{
 	{"otw", 0x4f4a4220},     /* Ottawa -> Ojibway */
 	{"otw", 0x4f4a4220},     /* Ottawa -> Ojibway */
 	{"oua", 0x42425220},     /* Tagargrent -> Berber */
 	{"oua", 0x42425220},     /* Tagargrent -> Berber */
 	{"pa", 0x50414e20},      /* Punjabi */
 	{"pa", 0x50414e20},      /* Punjabi */
-	{"paa", 0},              /* Papuan [family] != Palestinian Aramaic */
+	{"paa", 0},              /* Papuan [collection] != Palestinian Aramaic */
 	/*{"pag",	0x50414720},*/ /* Pangasinan */
 	/*{"pag",	0x50414720},*/ /* Pangasinan */
 	{"pal", 0},              /* Pahlavi != Pali */
 	{"pal", 0},              /* Pahlavi != Pali */
 	/*{"pam",	0x50414d20},*/ /* Pampanga -> Pampangan */
 	/*{"pam",	0x50414d20},*/ /* Pampanga -> Pampangan */
@@ -1133,6 +1141,7 @@ var otLanguages = [...]langTag{
 	{"ppa", 0x42414720},     /* Pao (retired code) (retired code) -> Baghelkhandi */
 	{"ppa", 0x42414720},     /* Pao (retired code) (retired code) -> Baghelkhandi */
 	{"pre", 0x43505020},     /* Principense -> Creoles */
 	{"pre", 0x43505020},     /* Principense -> Creoles */
 	/*{"pro",	0x50524f20},*/ /* Old Provençal (to 1500) -> Provençal / Old Provençal */
 	/*{"pro",	0x50524f20},*/ /* Old Provençal (to 1500) -> Provençal / Old Provençal */
+	{"prp", 0x47554a20},     /* Parsi (retired code) (retired code) -> Gujarati */
 	{"prs", 0x44524920},     /* Dari */
 	{"prs", 0x44524920},     /* Dari */
 	{"prs", 0x46415220},     /* Dari -> Persian */
 	{"prs", 0x46415220},     /* Dari -> Persian */
 	{"ps", 0x50415320},      /* Pashto [macrolanguage] */
 	{"ps", 0x50415320},      /* Pashto [macrolanguage] */
@@ -1298,6 +1307,9 @@ var otLanguages = [...]langTag{
 	{"sgo", 0},              /* Songa (retired code) (retired code) != Sango */
 	{"sgo", 0},              /* Songa (retired code) (retired code) != Sango */
 	/*{"sgs",	0x53475320},*/ /* Samogitian */
 	/*{"sgs",	0x53475320},*/ /* Samogitian */
 	{"sgw", 0x43484720},     /* Sebat Bet Gurage -> Chaha Gurage */
 	{"sgw", 0x43484720},     /* Sebat Bet Gurage -> Chaha Gurage */
+	{"sh", 0x424f5320},      /* Serbo-Croatian [macrolanguage] -> Bosnian */
+	{"sh", 0x48525620},      /* Serbo-Croatian [macrolanguage] -> Croatian */
+	{"sh", 0x53524220},      /* Serbo-Croatian [macrolanguage] -> Serbian */
 	{"shi", 0x53484920},     /* Tachelhit */
 	{"shi", 0x53484920},     /* Tachelhit */
 	{"shi", 0x42425220},     /* Tachelhit -> Berber */
 	{"shi", 0x42425220},     /* Tachelhit -> Berber */
 	{"shl", 0x51494e20},     /* Shendu -> Chin */
 	{"shl", 0x51494e20},     /* Shendu -> Chin */
@@ -1319,15 +1331,17 @@ var otLanguages = [...]langTag{
 	{"skw", 0x43505020},     /* Skepi Creole Dutch -> Creoles */
 	{"skw", 0x43505020},     /* Skepi Creole Dutch -> Creoles */
 	{"sky", 0},              /* Sikaiana != Slovak */
 	{"sky", 0},              /* Sikaiana != Slovak */
 	{"sl", 0x534c5620},      /* Slovenian */
 	{"sl", 0x534c5620},      /* Slovenian */
-	{"sla", 0},              /* Slavic [family] != Slavey */
+	{"sla", 0},              /* Slavic [collection] != Slavey */
 	{"sm", 0x534d4f20},      /* Samoan */
 	{"sm", 0x534d4f20},      /* Samoan */
 	{"sma", 0x53534d20},     /* Southern Sami */
 	{"sma", 0x53534d20},     /* Southern Sami */
+	{"smd", 0x4d424e20},     /* Sama (retired code) (retired code) -> Mbundu */
 	{"smj", 0x4c534d20},     /* Lule Sami */
 	{"smj", 0x4c534d20},     /* Lule Sami */
 	{"sml", 0},              /* Central Sama != Somali */
 	{"sml", 0},              /* Central Sama != Somali */
 	{"smn", 0x49534d20},     /* Inari Sami */
 	{"smn", 0x49534d20},     /* Inari Sami */
 	{"sms", 0x534b5320},     /* Skolt Sami */
 	{"sms", 0x534b5320},     /* Skolt Sami */
 	{"smt", 0x51494e20},     /* Simte -> Chin */
 	{"smt", 0x51494e20},     /* Simte -> Chin */
 	{"sn", 0x534e4130},      /* Shona */
 	{"sn", 0x534e4130},      /* Shona */
+	{"snb", 0x49424120},     /* Sebuyau (retired code) (retired code) -> Iban */
 	{"snh", 0},              /* Shinabo (retired code) (retired code) != Sinhala (Sinhalese) */
 	{"snh", 0},              /* Shinabo (retired code) (retired code) != Sinhala (Sinhalese) */
 	/*{"snk",	0x534e4b20},*/ /* Soninke */
 	/*{"snk",	0x534e4b20},*/ /* Soninke */
 	{"so", 0x534d4c20},      /* Somali */
 	{"so", 0x534d4c20},      /* Somali */
@@ -1385,7 +1399,7 @@ var otLanguages = [...]langTag{
 	{"tch", 0x43505020},     /* Turks And Caicos Creole English -> Creoles */
 	{"tch", 0x43505020},     /* Turks And Caicos Creole English -> Creoles */
 	{"tcp", 0x51494e20},     /* Tawr Chin -> Chin */
 	{"tcp", 0x51494e20},     /* Tawr Chin -> Chin */
 	{"tcs", 0x43505020},     /* Torres Strait Creole -> Creoles */
 	{"tcs", 0x43505020},     /* Torres Strait Creole -> Creoles */
-	{"tcy", 0x54554c20},     /* Tulu -> Tumbuka */
+	{"tcy", 0x54554c20},     /* Tulu */
 	{"tcz", 0x51494e20},     /* Thado Chin -> Chin */
 	{"tcz", 0x51494e20},     /* Thado Chin -> Chin */
 	/*{"tdd",	0x54444420},*/ /* Tai Nüa -> Dehong Dai */
 	/*{"tdd",	0x54444420},*/ /* Tai Nüa -> Dehong Dai */
 	{"tdx", 0x4d4c4720},     /* Tandroy-Mahafaly Malagasy -> Malagasy */
 	{"tdx", 0x4d4c4720},     /* Tandroy-Mahafaly Malagasy -> Malagasy */
@@ -1412,6 +1426,7 @@ var otLanguages = [...]langTag{
 	{"tia", 0x42425220},     /* Tidikelt Tamazight -> Berber */
 	{"tia", 0x42425220},     /* Tidikelt Tamazight -> Berber */
 	{"tig", 0x54475220},     /* Tigre */
 	{"tig", 0x54475220},     /* Tigre */
 	/*{"tiv",	0x54495620},*/ /* Tiv */
 	/*{"tiv",	0x54495620},*/ /* Tiv */
+	/*{"tjl",	0x544a4c20},*/ /* Tai Laing */
 	{"tjo", 0x42425220},     /* Temacine Tamazight -> Berber */
 	{"tjo", 0x42425220},     /* Temacine Tamazight -> Berber */
 	{"tk", 0x544b4d20},      /* Turkmen */
 	{"tk", 0x544b4d20},      /* Turkmen */
 	{"tkg", 0x4d4c4720},     /* Tesaka Malagasy -> Malagasy */
 	{"tkg", 0x4d4c4720},     /* Tesaka Malagasy -> Malagasy */
@@ -1439,7 +1454,7 @@ var otLanguages = [...]langTag{
 	{"tpi", 0x43505020},     /* Tok Pisin -> Creoles */
 	{"tpi", 0x43505020},     /* Tok Pisin -> Creoles */
 	{"tr", 0x54524b20},      /* Turkish */
 	{"tr", 0x54524b20},      /* Turkish */
 	{"trf", 0x43505020},     /* Trinidadian Creole English -> Creoles */
 	{"trf", 0x43505020},     /* Trinidadian Creole English -> Creoles */
-	{"trk", 0},              /* Turkic [family] != Turkish */
+	{"trk", 0},              /* Turkic [collection] != Turkish */
 	{"tru", 0x54554120},     /* Turoyo -> Turoyo Aramaic */
 	{"tru", 0x54554120},     /* Turoyo -> Turoyo Aramaic */
 	{"tru", 0x53595220},     /* Turoyo -> Syriac */
 	{"tru", 0x53595220},     /* Turoyo -> Syriac */
 	{"ts", 0x54534720},      /* Tsonga */
 	{"ts", 0x54534720},      /* Tsonga */
@@ -1451,8 +1466,8 @@ var otLanguages = [...]langTag{
 	{"ttq", 0x544d4820},     /* Tawallammat Tamajaq -> Tamashek */
 	{"ttq", 0x544d4820},     /* Tawallammat Tamajaq -> Tamashek */
 	{"ttq", 0x42425220},     /* Tawallammat Tamajaq -> Berber */
 	{"ttq", 0x42425220},     /* Tawallammat Tamajaq -> Berber */
 	{"tua", 0},              /* Wiarumus != Turoyo Aramaic */
 	{"tua", 0},              /* Wiarumus != Turoyo Aramaic */
-	{"tul", 0},              /* Tula != Tumbuka */
-	/*{"tum",	0x54554d20},*/ /* Tumbuka -> Tulu */
+	{"tul", 0},              /* Tula != Tulu */
+	/*{"tum",	0x54554d20},*/ /* Tumbuka */
 	{"tuu", 0x41544820},     /* Tututni -> Athapaskan */
 	{"tuu", 0x41544820},     /* Tututni -> Athapaskan */
 	{"tuv", 0},              /* Turkana != Tuvin */
 	{"tuv", 0},              /* Turkana != Tuvin */
 	{"tuy", 0x4b414c20},     /* Tugen -> Kalenjin */
 	{"tuy", 0x4b414c20},     /* Tugen -> Kalenjin */
@@ -1550,6 +1565,7 @@ var otLanguages = [...]langTag{
 	{"yba", 0},              /* Yala != Yoruba */
 	{"yba", 0},              /* Yala != Yoruba */
 	{"ybb", 0x424d4c20},     /* Yemba -> Bamileke */
 	{"ybb", 0x424d4c20},     /* Yemba -> Bamileke */
 	{"ybd", 0x41524b20},     /* Yangbye (retired code) (retired code) -> Rakhine */
 	{"ybd", 0x41524b20},     /* Yangbye (retired code) (retired code) -> Rakhine */
+	{"ycr", 0},              /* Yilan Creole != Y-Cree */
 	{"ydd", 0x4a494920},     /* Eastern Yiddish -> Yiddish */
 	{"ydd", 0x4a494920},     /* Eastern Yiddish -> Yiddish */
 	/*{"ygp",	0x59475020},*/ /* Gepo */
 	/*{"ygp",	0x59475020},*/ /* Gepo */
 	{"yi", 0x4a494920},      /* Yiddish [macrolanguage] */
 	{"yi", 0x4a494920},      /* Yiddish [macrolanguage] */
@@ -1575,13 +1591,14 @@ var otLanguages = [...]langTag{
 	{"zh", 0x5a485320},      /* Chinese, Simplified [macrolanguage] */
 	{"zh", 0x5a485320},      /* Chinese, Simplified [macrolanguage] */
 	{"zhd", 0x5a484120},     /* Dai Zhuang -> Zhuang */
 	{"zhd", 0x5a484120},     /* Dai Zhuang -> Zhuang */
 	{"zhn", 0x5a484120},     /* Nong Zhuang -> Zhuang */
 	{"zhn", 0x5a484120},     /* Nong Zhuang -> Zhuang */
+	{"zkb", 0x4b484120},     /* Koibal (retired code) (retired code) -> Khakass */
 	{"zlj", 0x5a484120},     /* Liujiang Zhuang -> Zhuang */
 	{"zlj", 0x5a484120},     /* Liujiang Zhuang -> Zhuang */
 	{"zlm", 0x4d4c5920},     /* Malay */
 	{"zlm", 0x4d4c5920},     /* Malay */
 	{"zln", 0x5a484120},     /* Lianshan Zhuang -> Zhuang */
 	{"zln", 0x5a484120},     /* Lianshan Zhuang -> Zhuang */
 	{"zlq", 0x5a484120},     /* Liuqian Zhuang -> Zhuang */
 	{"zlq", 0x5a484120},     /* Liuqian Zhuang -> Zhuang */
 	{"zmi", 0x4d4c5920},     /* Negeri Sembilan Malay -> Malay */
 	{"zmi", 0x4d4c5920},     /* Negeri Sembilan Malay -> Malay */
 	{"zmz", 0x42414430},     /* Mbandja -> Banda */
 	{"zmz", 0x42414430},     /* Mbandja -> Banda */
-	{"znd", 0},              /* Zande [family] != Zande */
+	{"znd", 0},              /* Zande [collection] != Zande */
 	{"zne", 0x5a4e4420},     /* Zande */
 	{"zne", 0x5a4e4420},     /* Zande */
 	{"zom", 0x51494e20},     /* Zou -> Chin */
 	{"zom", 0x51494e20},     /* Zou -> Chin */
 	{"zqe", 0x5a484120},     /* Qiubei Zhuang -> Zhuang */
 	{"zqe", 0x5a484120},     /* Qiubei Zhuang -> Zhuang */
@@ -2131,7 +2148,7 @@ func tagsFromComplexLanguage(langStr string) []loader.Tag {
 		if strings.HasPrefix(langStr[1:], "nw-") &&
 		if strings.HasPrefix(langStr[1:], "nw-") &&
 			subtagMatches(langStr, "th") {
 			subtagMatches(langStr, "th") {
 			/* Mon; Thailand */
 			/* Mon; Thailand */
-			return []loader.Tag{0x4d4f4e54} /*  */
+			return []loader.Tag{0x4d4f4e54} /* Thailand Mon */
 		}
 		}
 
 
 	case 'n':
 	case 'n':
@@ -2309,15 +2326,15 @@ func ambiguousTagToLanguage(tag loader.Tag) language.Language {
 	case 0x41524b20: /* Rakhine */
 	case 0x41524b20: /* Rakhine */
 		return "rki" /* language.NewLanguage("rki") Rakhine */
 		return "rki" /* language.NewLanguage("rki") Rakhine */
 	case 0x41544820: /* Athapaskan */
 	case 0x41544820: /* Athapaskan */
-		return "ath" /* language.NewLanguage("ath") Athapascan [family] */
+		return "ath" /* language.NewLanguage("ath") Athapascan [collection] */
 	case 0x42425220: /* Berber */
 	case 0x42425220: /* Berber */
-		return "ber" /* language.NewLanguage("ber") Berber [family] */
+		return "ber" /* language.NewLanguage("ber") Berber [collection] */
 	case 0x42494b20: /* Bikol */
 	case 0x42494b20: /* Bikol */
 		return "bik" /* language.NewLanguage("bik") Bikol [macrolanguage] */
 		return "bik" /* language.NewLanguage("bik") Bikol [macrolanguage] */
 	case 0x42544b20: /* Batak */
 	case 0x42544b20: /* Batak */
-		return "btk" /* language.NewLanguage("btk") Batak [family] */
+		return "btk" /* language.NewLanguage("btk") Batak [collection] */
 	case 0x43505020: /* Creoles */
 	case 0x43505020: /* Creoles */
-		return "crp" /* language.NewLanguage("crp") Creoles and pidgins [family] */
+		return "crp" /* language.NewLanguage("crp") Creoles and pidgins [collection] */
 	case 0x43525220: /* Carrier */
 	case 0x43525220: /* Carrier */
 		return "crx" /* language.NewLanguage("crx") Carrier */
 		return "crx" /* language.NewLanguage("crx") Carrier */
 	case 0x44475220: /* Dogri (macrolanguage) */
 	case 0x44475220: /* Dogri (macrolanguage) */
@@ -2334,6 +2351,8 @@ func ambiguousTagToLanguage(tag loader.Tag) language.Language {
 		return "fa" /* language.NewLanguage("fa") Persian [macrolanguage] */
 		return "fa" /* language.NewLanguage("fa") Persian [macrolanguage] */
 	case 0x474f4e20: /* Gondi */
 	case 0x474f4e20: /* Gondi */
 		return "gon" /* language.NewLanguage("gon") Gondi [macrolanguage] */
 		return "gon" /* language.NewLanguage("gon") Gondi [macrolanguage] */
+	case 0x484d4120: /* High Mari */
+		return "mrj" /* language.NewLanguage("mrj") Western Mari */
 	case 0x484d4e20: /* Hmong */
 	case 0x484d4e20: /* Hmong */
 		return "hmn" /* language.NewLanguage("hmn") Hmong [macrolanguage] */
 		return "hmn" /* language.NewLanguage("hmn") Hmong [macrolanguage] */
 	case 0x484e4420: /* Hindko */
 	case 0x484e4420: /* Hindko */
@@ -2343,7 +2362,7 @@ func ambiguousTagToLanguage(tag loader.Tag) language.Language {
 	case 0x49424120: /* Iban */
 	case 0x49424120: /* Iban */
 		return "iba" /* language.NewLanguage("iba") Iban */
 		return "iba" /* language.NewLanguage("iba") Iban */
 	case 0x494a4f20: /* Ijo */
 	case 0x494a4f20: /* Ijo */
-		return "ijo" /* language.NewLanguage("ijo") Ijo [family] */
+		return "ijo" /* language.NewLanguage("ijo") Ijo [collection] */
 	case 0x494e5520: /* Inuktitut */
 	case 0x494e5520: /* Inuktitut */
 		return "iu" /* language.NewLanguage("iu") Inuktitut [macrolanguage] */
 		return "iu" /* language.NewLanguage("iu") Inuktitut [macrolanguage] */
 	case 0x49504b20: /* Inupiat */
 	case 0x49504b20: /* Inupiat */
@@ -2369,11 +2388,13 @@ func ambiguousTagToLanguage(tag loader.Tag) language.Language {
 	case 0x4b504c20: /* Kpelle */
 	case 0x4b504c20: /* Kpelle */
 		return "kpe" /* language.NewLanguage("kpe") Kpelle [macrolanguage] */
 		return "kpe" /* language.NewLanguage("kpe") Kpelle [macrolanguage] */
 	case 0x4b524e20: /* Karen */
 	case 0x4b524e20: /* Karen */
-		return "kar" /* language.NewLanguage("kar") Karen [family] */
+		return "kar" /* language.NewLanguage("kar") Karen [collection] */
 	case 0x4b554920: /* Kui */
 	case 0x4b554920: /* Kui */
 		return "uki" /* language.NewLanguage("uki") Kui (India) */
 		return "uki" /* language.NewLanguage("uki") Kui (India) */
 	case 0x4b555220: /* Kurdish */
 	case 0x4b555220: /* Kurdish */
 		return "ku" /* language.NewLanguage("ku") Kurdish [macrolanguage] */
 		return "ku" /* language.NewLanguage("ku") Kurdish [macrolanguage] */
+	case 0x4c4d4120: /* Low Mari */
+		return "mhr" /* language.NewLanguage("mhr") Eastern Mari */
 	case 0x4c554820: /* Luyia */
 	case 0x4c554820: /* Luyia */
 		return "luy" /* language.NewLanguage("luy") Luyia [macrolanguage] */
 		return "luy" /* language.NewLanguage("luy") Luyia [macrolanguage] */
 	case 0x4c564920: /* Latvian */
 	case 0x4c564920: /* Latvian */
@@ -2390,12 +2411,12 @@ func ambiguousTagToLanguage(tag loader.Tag) language.Language {
 		return "man" /* language.NewLanguage("man") Mandingo [macrolanguage] */
 		return "man" /* language.NewLanguage("man") Mandingo [macrolanguage] */
 	case 0x4d4f4c20: /* Moldavian */
 	case 0x4d4f4c20: /* Moldavian */
 		return "ro-md" /* language.NewLanguage("ro-MD") Romanian; Moldova */
 		return "ro-md" /* language.NewLanguage("ro-MD") Romanian; Moldova */
-	case 0x4d4f4e54: /*  */
+	case 0x4d4f4e54: /* Thailand Mon */
 		return "mnw-th" /* language.NewLanguage("mnw-TH") Mon; Thailand */
 		return "mnw-th" /* language.NewLanguage("mnw-TH") Mon; Thailand */
 	case 0x4d594e20: /* Mayan */
 	case 0x4d594e20: /* Mayan */
-		return "myn" /* language.NewLanguage("myn") Mayan [family] */
+		return "myn" /* language.NewLanguage("myn") Mayan [collection] */
 	case 0x4e414820: /* Nahuatl */
 	case 0x4e414820: /* Nahuatl */
-		return "nah" /* language.NewLanguage("nah") Nahuatl [family] */
+		return "nah" /* language.NewLanguage("nah") Nahuatl [collection] */
 	case 0x4e455020: /* Nepali */
 	case 0x4e455020: /* Nepali */
 		return "ne" /* language.NewLanguage("ne") Nepali [macrolanguage] */
 		return "ne" /* language.NewLanguage("ne") Nepali [macrolanguage] */
 	case 0x4e495320: /* Nisi */
 	case 0x4e495320: /* Nisi */
@@ -2422,6 +2443,8 @@ func ambiguousTagToLanguage(tag loader.Tag) language.Language {
 		return "qwh" /* language.NewLanguage("qwh") Huaylas Ancash Quechua */
 		return "qwh" /* language.NewLanguage("qwh") Huaylas Ancash Quechua */
 	case 0x52414a20: /* Rajasthani */
 	case 0x52414a20: /* Rajasthani */
 		return "raj" /* language.NewLanguage("raj") Rajasthani [macrolanguage] */
 		return "raj" /* language.NewLanguage("raj") Rajasthani [macrolanguage] */
+	case 0x524f4d20: /* Romanian */
+		return "ro" /* language.NewLanguage("ro") Romanian */
 	case 0x524f5920: /* Romany */
 	case 0x524f5920: /* Romany */
 		return "rom" /* language.NewLanguage("rom") Romany [macrolanguage] */
 		return "rom" /* language.NewLanguage("rom") Romany [macrolanguage] */
 	case 0x53514920: /* Albanian */
 	case 0x53514920: /* Albanian */

+ 9 - 15
vendor/github.com/go-text/typesetting/harfbuzz/ot_layout.go

@@ -146,7 +146,7 @@ func (sp *otShapePlan) otLayoutKern(font *Font, buffer *Buffer) {
 
 
 var otTagLatinScript = loader.NewTag('l', 'a', 't', 'n')
 var otTagLatinScript = loader.NewTag('l', 'a', 't', 'n')
 
 
-// SelectScript selects an OpenType script from the `scriptTags` array,
+// selectScript selects an OpenType script from the `scriptTags` array,
 // returning its index in the Scripts slice and the script tag.
 // returning its index in the Scripts slice and the script tag.
 //
 //
 // If `table` does not have any of the requested scripts, then `DFLT`,
 // If `table` does not have any of the requested scripts, then `DFLT`,
@@ -155,7 +155,7 @@ var otTagLatinScript = loader.NewTag('l', 'a', 't', 'n')
 //
 //
 // An additional boolean if returned : it is `true` if one of the requested scripts is selected, or `false` if a fallback
 // An additional boolean if returned : it is `true` if one of the requested scripts is selected, or `false` if a fallback
 // script is selected or if no scripts are selected.
 // script is selected or if no scripts are selected.
-func SelectScript(table *font.Layout, scriptTags []tables.Tag) (int, tables.Tag, bool) {
+func selectScript(table *font.Layout, scriptTags []tables.Tag) (int, tables.Tag, bool) {
 	for _, tag := range scriptTags {
 	for _, tag := range scriptTags {
 		if scriptIndex := table.FindScript(tag); scriptIndex != -1 {
 		if scriptIndex := table.FindScript(tag); scriptIndex != -1 {
 			return scriptIndex, tag, true
 			return scriptIndex, tag, true
@@ -181,12 +181,12 @@ func SelectScript(table *font.Layout, scriptTags []tables.Tag) (int, tables.Tag,
 	return NoScriptIndex, NoScriptIndex, false
 	return NoScriptIndex, NoScriptIndex, false
 }
 }
 
 
-// SelectLanguage fetches the index of the first language tag from `languageTags` in the specified layout table,
+// selectLanguage fetches the index of the first language tag from `languageTags` in the specified layout table,
 // underneath `scriptIndex`.
 // underneath `scriptIndex`.
 // It not found, the `dflt` language tag is searched.
 // It not found, the `dflt` language tag is searched.
 // Return `true` if the requested language tag is found, `false` otherwise.
 // Return `true` if the requested language tag is found, `false` otherwise.
 // If `scriptIndex` is `NoScriptIndex` or if no language is found, `DefaultLanguageIndex` is returned.
 // If `scriptIndex` is `NoScriptIndex` or if no language is found, `DefaultLanguageIndex` is returned.
-func SelectLanguage(table *font.Layout, scriptIndex int, languageTags []tables.Tag) (int, bool) {
+func selectLanguage(table *font.Layout, scriptIndex int, languageTags []tables.Tag) (int, bool) {
 	if scriptIndex == NoScriptIndex {
 	if scriptIndex == NoScriptIndex {
 		return DefaultLanguageIndex, false
 		return DefaultLanguageIndex, false
 	}
 	}
@@ -217,7 +217,7 @@ func findFeature(g *font.Layout, featureTag tables.Tag) uint16 {
 // Fetches the index of a given feature tag in the specified face's GSUB table
 // Fetches the index of a given feature tag in the specified face's GSUB table
 // or GPOS table, underneath the specified script and language.
 // or GPOS table, underneath the specified script and language.
 // Return `NoFeatureIndex` it the the feature is not found.
 // Return `NoFeatureIndex` it the the feature is not found.
-func FindFeatureForLang(table *font.Layout, scriptIndex, languageIndex int, featureTag tables.Tag) uint16 {
+func findFeatureForLang(table *font.Layout, scriptIndex, languageIndex int, featureTag tables.Tag) uint16 {
 	if scriptIndex == NoScriptIndex {
 	if scriptIndex == NoScriptIndex {
 		return NoFeatureIndex
 		return NoFeatureIndex
 	}
 	}
@@ -235,11 +235,11 @@ func FindFeatureForLang(table *font.Layout, scriptIndex, languageIndex int, feat
 // Fetches the tag of a requested feature index in the given layout table,
 // Fetches the tag of a requested feature index in the given layout table,
 // underneath the specified script and language. Returns -1 if no feature is requested.
 // underneath the specified script and language. Returns -1 if no feature is requested.
 func getRequiredFeature(g *font.Layout, scriptIndex, languageIndex int) (uint16, tables.Tag) {
 func getRequiredFeature(g *font.Layout, scriptIndex, languageIndex int) (uint16, tables.Tag) {
-	if scriptIndex == NoScriptIndex || languageIndex == DefaultLanguageIndex {
+	if scriptIndex == NoScriptIndex {
 		return NoFeatureIndex, 0
 		return NoFeatureIndex, 0
 	}
 	}
 
 
-	l := g.Scripts[scriptIndex].LangSys[languageIndex]
+	l := g.Scripts[scriptIndex].GetLangSys(uint16(languageIndex))
 	if l.RequiredFeatureIndex == 0xFFFF {
 	if l.RequiredFeatureIndex == 0xFFFF {
 		return NoFeatureIndex, 0
 		return NoFeatureIndex, 0
 	}
 	}
@@ -356,22 +356,16 @@ func otLayoutPositionFinishOffsets(_ *Font, buffer *Buffer) {
 	positionFinishOffsetsGPOS(buffer)
 	positionFinishOffsetsGPOS(buffer)
 }
 }
 
 
-func clearSyllables(_ *otShapePlan, _ *Font, buffer *Buffer) {
-	info := buffer.Info
-	for i := range info {
-		info[i].syllable = 0
-	}
-}
-
 func glyphInfoSubstituted(info *GlyphInfo) bool {
 func glyphInfoSubstituted(info *GlyphInfo) bool {
 	return (info.glyphProps & substituted) != 0
 	return (info.glyphProps & substituted) != 0
 }
 }
 
 
-func clearSubstitutionFlags(_ *otShapePlan, _ *Font, buffer *Buffer) {
+func clearSubstitutionFlags(_ *otShapePlan, _ *Font, buffer *Buffer) bool {
 	info := buffer.Info
 	info := buffer.Info
 	for i := range info {
 	for i := range info {
 		info[i].glyphProps &= ^substituted
 		info[i].glyphProps &= ^substituted
 	}
 	}
+	return false
 }
 }
 
 
 func reverseGraphemes(b *Buffer) {
 func reverseGraphemes(b *Buffer) {

+ 130 - 48
vendor/github.com/go-text/typesetting/harfbuzz/ot_layout_gpos.go

@@ -107,7 +107,7 @@ func positionFinishOffsetsGPOS(buffer *Buffer) {
 	/* Handle attachments */
 	/* Handle attachments */
 	if buffer.scratchFlags&bsfHasGPOSAttachment != 0 {
 	if buffer.scratchFlags&bsfHasGPOSAttachment != 0 {
 
 
-		if debugMode >= 2 {
+		if debugMode {
 			fmt.Println("POSITION - handling attachments")
 			fmt.Println("POSITION - handling attachments")
 		}
 		}
 
 
@@ -133,7 +133,7 @@ func (c *otApplyContext) applyGPOS(table tables.GPOSLookup) bool {
 		return false
 		return false
 	}
 	}
 
 
-	if debugMode >= 2 {
+	if debugMode {
 		fmt.Printf("\tAPPLY - type %T at index %d\n", table, c.buffer.idx)
 		fmt.Printf("\tAPPLY - type %T at index %d\n", table, c.buffer.idx)
 	}
 	}
 
 
@@ -149,22 +149,15 @@ func (c *otApplyContext) applyGPOS(table tables.GPOSLookup) bool {
 	case tables.PairPos:
 	case tables.PairPos:
 		skippyIter := &c.iterInput
 		skippyIter := &c.iterInput
 		skippyIter.reset(buffer.idx, 1)
 		skippyIter.reset(buffer.idx, 1)
-		if !skippyIter.next() {
+		if ok, unsafeTo := skippyIter.next(); !ok {
+			buffer.unsafeToConcat(buffer.idx, unsafeTo)
 			return false
 			return false
 		}
 		}
 		switch inner := data.Data.(type) {
 		switch inner := data.Data.(type) {
 		case tables.PairPosData1:
 		case tables.PairPosData1:
-			set := inner.PairSets[index]
-			record := set.FindGlyph(gID(buffer.Info[skippyIter.idx].Glyph))
-			if record == nil {
-				return false
-			}
-			c.applyGPOSPair(inner.ValueFormat1, inner.ValueFormat2, record.ValueRecord1, record.ValueRecord2, skippyIter.idx)
+			return c.applyGPOSPair1(inner, index)
 		case tables.PairPosData2:
 		case tables.PairPosData2:
-			class1, _ := inner.ClassDef1.Class(gID(glyphID))
-			class2, _ := inner.ClassDef2.Class(gID(buffer.Info[skippyIter.idx].Glyph))
-			vals := inner.Record(class1, class2)
-			c.applyGPOSPair(inner.ValueFormat1, inner.ValueFormat2, vals.ValueRecord1, vals.ValueRecord2, skippyIter.idx)
+			return c.applyGPOSPair2(inner)
 		}
 		}
 
 
 	case tables.CursivePos:
 	case tables.CursivePos:
@@ -287,19 +280,65 @@ func reverseCursiveMinorOffset(pos []GlyphPosition, i int, direction Direction,
 	pos[j].attachType = type_
 	pos[j].attachType = type_
 }
 }
 
 
-func (c *otApplyContext) applyGPOSPair(f1, f2 tables.ValueFormat, v1, v2 tables.ValueRecord, pos int) {
+func (c *otApplyContext) applyGPOSPair1(inner tables.PairPosData1, index int) bool {
 	buffer := c.buffer
 	buffer := c.buffer
+	skippyIter := &c.iterInput
+	pos := skippyIter.idx
+	set := inner.PairSets[index]
+	record := set.FindGlyph(gID(buffer.Info[skippyIter.idx].Glyph))
+	if record == nil {
+		buffer.unsafeToConcat(buffer.idx, pos+1)
+		return false
+	}
 
 
-	ap1 := c.applyGPOSValueRecord(f1, v1, buffer.curPos(0))
-	ap2 := c.applyGPOSValueRecord(f2, v2, &buffer.Pos[pos])
+	ap1 := c.applyGPOSValueRecord(inner.ValueFormat1, record.ValueRecord1, buffer.curPos(0))
+	ap2 := c.applyGPOSValueRecord(inner.ValueFormat2, record.ValueRecord2, &buffer.Pos[pos])
 
 
 	if ap1 || ap2 {
 	if ap1 || ap2 {
 		buffer.unsafeToBreak(buffer.idx, pos+1)
 		buffer.unsafeToBreak(buffer.idx, pos+1)
 	}
 	}
+
+	if inner.ValueFormat2 != 0 {
+		// https://github.com/harfbuzz/harfbuzz/issues/3824
+		// https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116
+		pos++
+		buffer.unsafeToBreak(buffer.idx, pos+1)
+	}
 	buffer.idx = pos
 	buffer.idx = pos
-	if f2 != 0 {
-		buffer.idx++
+	return true
+}
+
+func (c *otApplyContext) applyGPOSPair2(inner tables.PairPosData2) bool {
+	buffer := c.buffer
+	skippyIter := &c.iterInput
+
+	glyphID := buffer.cur(0).Glyph
+	class2, ok2 := inner.ClassDef2.Class(gID(buffer.Info[skippyIter.idx].Glyph))
+	if !ok2 {
+		buffer.unsafeToConcat(buffer.idx, skippyIter.idx+1)
+		return false
+	}
+
+	class1, _ := inner.ClassDef1.Class(gID(glyphID))
+	vals := inner.Record(class1, class2)
+
+	ap1 := c.applyGPOSValueRecord(inner.ValueFormat1, vals.ValueRecord1, buffer.curPos(0))
+	ap2 := c.applyGPOSValueRecord(inner.ValueFormat2, vals.ValueRecord2, &buffer.Pos[skippyIter.idx])
+
+	if ap1 || ap2 {
+		buffer.unsafeToBreak(buffer.idx, skippyIter.idx+1)
+	} else {
+		buffer.unsafeToConcat(buffer.idx, skippyIter.idx+1)
+	}
+
+	if inner.ValueFormat2 != 0 {
+		// https://github.com/harfbuzz/harfbuzz/issues/3824
+		// https://github.com/harfbuzz/harfbuzz/issues/3888#issuecomment-1326781116
+		skippyIter.idx++
+		buffer.unsafeToBreak(buffer.idx, skippyIter.idx+1)
 	}
 	}
+	buffer.idx = skippyIter.idx
+	return true
 }
 }
 
 
 func (c *otApplyContext) applyGPOSCursive(data tables.CursivePos, covIndex int) bool {
 func (c *otApplyContext) applyGPOSCursive(data tables.CursivePos, covIndex int) bool {
@@ -312,23 +351,26 @@ func (c *otApplyContext) applyGPOSCursive(data tables.CursivePos, covIndex int)
 
 
 	skippyIter := &c.iterInput
 	skippyIter := &c.iterInput
 	skippyIter.reset(buffer.idx, 1)
 	skippyIter.reset(buffer.idx, 1)
-	if !skippyIter.prev() {
+	if ok, unsafeFrom := skippyIter.prev(); !ok {
+		buffer.unsafeToConcatFromOutbuffer(unsafeFrom, buffer.idx+1)
 		return false
 		return false
 	}
 	}
 
 
 	prevIndex, ok := data.Cov().Index(gID(buffer.Info[skippyIter.idx].Glyph))
 	prevIndex, ok := data.Cov().Index(gID(buffer.Info[skippyIter.idx].Glyph))
 	if !ok {
 	if !ok {
+		buffer.unsafeToConcatFromOutbuffer(skippyIter.idx, buffer.idx+1)
 		return false
 		return false
 	}
 	}
 	prevRecord := data.EntryExits[prevIndex]
 	prevRecord := data.EntryExits[prevIndex]
 	if prevRecord.ExitAnchor == nil {
 	if prevRecord.ExitAnchor == nil {
+		buffer.unsafeToConcatFromOutbuffer(skippyIter.idx, buffer.idx+1)
 		return false
 		return false
 	}
 	}
 
 
 	i := skippyIter.idx
 	i := skippyIter.idx
 	j := buffer.idx
 	j := buffer.idx
 
 
-	buffer.unsafeToBreak(i, j)
+	buffer.unsafeToBreak(i, j+1)
 	exitX, exitY := c.getAnchor(prevRecord.ExitAnchor, buffer.Info[i].Glyph)
 	exitX, exitY := c.getAnchor(prevRecord.ExitAnchor, buffer.Info[i].Glyph)
 	entryX, entryY := c.getAnchor(thisRecord.EntryAnchor, buffer.Info[j].Glyph)
 	entryX, entryY := c.getAnchor(thisRecord.EntryAnchor, buffer.Info[j].Glyph)
 
 
@@ -399,10 +441,15 @@ func (c *otApplyContext) applyGPOSCursive(data tables.CursivePos, covIndex int)
 		pos[child].XOffset = xOffset
 		pos[child].XOffset = xOffset
 	}
 	}
 
 
-	/* If parent was attached to child, break them free.
+	/* If parent was attached to child, separate them.
 	 * https://github.com/harfbuzz/harfbuzz/issues/2469 */
 	 * https://github.com/harfbuzz/harfbuzz/issues/2469 */
 	if pos[parent].attachChain == -pos[child].attachChain {
 	if pos[parent].attachChain == -pos[child].attachChain {
 		pos[parent].attachChain = 0
 		pos[parent].attachChain = 0
+		if c.direction.isHorizontal() {
+			pos[parent].YOffset = 0
+		} else {
+			pos[parent].XOffset = 0
+		}
 	}
 	}
 
 
 	buffer.idx++
 	buffer.idx++
@@ -459,7 +506,7 @@ func (c *otApplyContext) applyGPOSMarks(marks tables.MarkArray, markIndex, glyph
 		return false
 		return false
 	}
 	}
 
 
-	buffer.unsafeToBreak(glyphPos, buffer.idx)
+	buffer.unsafeToBreak(glyphPos, buffer.idx+1)
 	markX, markY := c.getAnchor(markAnchor, buffer.cur(0).Glyph)
 	markX, markY := c.getAnchor(markAnchor, buffer.cur(0).Glyph)
 	baseX, baseY := c.getAnchor(glyphAnchor, buffer.Info[glyphPos].Glyph)
 	baseX, baseY := c.getAnchor(glyphAnchor, buffer.Info[glyphPos].Glyph)
 
 
@@ -477,37 +524,58 @@ func (c *otApplyContext) applyGPOSMarks(marks tables.MarkArray, markIndex, glyph
 func (c *otApplyContext) applyGPOSMarkToBase(data tables.MarkBasePos, markIndex int) bool {
 func (c *otApplyContext) applyGPOSMarkToBase(data tables.MarkBasePos, markIndex int) bool {
 	buffer := c.buffer
 	buffer := c.buffer
 
 
-	// now we search backwards for a non-mark glyph
+	// Now we search backwards for a non-mark glyph.
+	// We don't use skippy_iter.prev() to avoid O(n^2) behavior.
+
 	skippyIter := &c.iterInput
 	skippyIter := &c.iterInput
-	skippyIter.reset(buffer.idx, 1)
 	skippyIter.matcher.lookupProps = uint32(otIgnoreMarks)
 	skippyIter.matcher.lookupProps = uint32(otIgnoreMarks)
-	for {
-		if !skippyIter.prev() {
-			return false
+
+	if c.lastBaseUntil > buffer.idx {
+		c.lastBaseUntil = 0
+		c.lastBase = -1
+	}
+
+	for j := buffer.idx; j > c.lastBaseUntil; j-- {
+		ma := skippyIter.match(&buffer.Info[j-1])
+		if ma == match {
+			// https://github.com/harfbuzz/harfbuzz/issues/4124
+
+			// We only want to attach to the first of a MultipleSubst sequence.
+			// https://github.com/harfbuzz/harfbuzz/issues/740
+			// Reject others...
+			// ...but stop if we find a mark in the MultipleSubst sequence:
+			// https://github.com/harfbuzz/harfbuzz/issues/1020
+			idx := j - 1
+			accept := !buffer.Info[idx].multiplied() || buffer.Info[idx].getLigComp() == 0 ||
+				idx == 0 || buffer.Info[idx-1].isMark() ||
+				buffer.Info[idx].getLigID() != buffer.Info[idx-1].getLigID() ||
+				buffer.Info[idx].getLigComp() != buffer.Info[idx-1].getLigComp()+1
+
+			_, covered := data.BaseCoverage.Index(gID(buffer.Info[idx].Glyph))
+			if !accept && !covered {
+				ma = skip
+			}
 		}
 		}
-		// We only want to attach to the first of a MultipleSubst sequence.
-		// https://github.com/harfbuzz/harfbuzz/issues/740
-		// Reject others...
-		// ...but stop if we find a mark in the MultipleSubst sequence:
-		// https://github.com/harfbuzz/harfbuzz/issues/1020
-		if !buffer.Info[skippyIter.idx].multiplied() || buffer.Info[skippyIter.idx].getLigComp() == 0 ||
-			skippyIter.idx == 0 || buffer.Info[skippyIter.idx-1].isMark() ||
-			buffer.Info[skippyIter.idx].getLigID() != buffer.Info[skippyIter.idx-1].getLigID() ||
-			buffer.Info[skippyIter.idx].getLigComp() != buffer.Info[skippyIter.idx-1].getLigComp()+1 {
+		if ma == match {
+			c.lastBase = j - 1
 			break
 			break
 		}
 		}
-		skippyIter.reject()
 	}
 	}
 
 
-	/* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
-	//if (!_hb_glyph_info_is_base_glyph (&buffer.Info[skippyIter.idx])) { return false; }
+	c.lastBaseUntil = buffer.idx
+	if c.lastBase == -1 {
+		buffer.unsafeToConcatFromOutbuffer(0, buffer.idx+1)
+		return false
+	}
 
 
-	baseIndex, ok := data.BaseCoverage.Index(gID(buffer.Info[skippyIter.idx].Glyph))
+	idx := c.lastBase
+	baseIndex, ok := data.BaseCoverage.Index(gID(buffer.Info[idx].Glyph))
 	if !ok {
 	if !ok {
+		buffer.unsafeToConcatFromOutbuffer(idx, buffer.idx+1)
 		return false
 		return false
 	}
 	}
 
 
-	return c.applyGPOSMarks(data.MarkArray, markIndex, baseIndex, data.BaseArray.Anchors(), skippyIter.idx)
+	return c.applyGPOSMarks(data.MarkArray, markIndex, baseIndex, data.BaseArray.Anchors(), idx)
 }
 }
 
 
 func (c *otApplyContext) applyGPOSMarkToLigature(data tables.MarkLigPos, markIndex int) bool {
 func (c *otApplyContext) applyGPOSMarkToLigature(data tables.MarkLigPos, markIndex int) bool {
@@ -515,15 +583,29 @@ func (c *otApplyContext) applyGPOSMarkToLigature(data tables.MarkLigPos, markInd
 
 
 	// now we search backwards for a non-mark glyph
 	// now we search backwards for a non-mark glyph
 	skippyIter := &c.iterInput
 	skippyIter := &c.iterInput
-	skippyIter.reset(buffer.idx, 1)
 	skippyIter.matcher.lookupProps = uint32(otIgnoreMarks)
 	skippyIter.matcher.lookupProps = uint32(otIgnoreMarks)
-	if !skippyIter.prev() {
+	if c.lastBaseUntil > buffer.idx {
+		c.lastBaseUntil = 0
+		c.lastBase = -1
+	}
+
+	for j := buffer.idx; j > c.lastBaseUntil; j-- {
+		ma := skippyIter.match(&buffer.Info[j-1])
+		if ma == match {
+			c.lastBase = j - 1
+			break
+		}
+	}
+	c.lastBaseUntil = buffer.idx
+	if c.lastBase == -1 {
+		c.buffer.unsafeToConcatFromOutbuffer(0, buffer.idx+1)
 		return false
 		return false
 	}
 	}
 
 
-	j := skippyIter.idx
-	ligIndex, ok := data.LigatureCoverage.Index(gID(buffer.Info[j].Glyph))
+	idx := c.lastBase
+	ligIndex, ok := data.LigatureCoverage.Index(gID(buffer.Info[idx].Glyph))
 	if !ok {
 	if !ok {
+		c.buffer.unsafeToConcatFromOutbuffer(idx, c.buffer.idx+1)
 		return false
 		return false
 	}
 	}
 
 
@@ -539,7 +621,7 @@ func (c *otApplyContext) applyGPOSMarkToLigature(data tables.MarkLigPos, markInd
 	// is identical to the ligature ID of the found ligature.  If yes, we
 	// is identical to the ligature ID of the found ligature.  If yes, we
 	// can directly use the component index.  If not, we attach the mark
 	// can directly use the component index.  If not, we attach the mark
 	// glyph to the last component of the ligature.
 	// glyph to the last component of the ligature.
-	ligID := buffer.Info[j].getLigID()
+	ligID := buffer.Info[idx].getLigID()
 	markID := buffer.cur(0).getLigID()
 	markID := buffer.cur(0).getLigID()
 	markComp := buffer.cur(0).getLigComp()
 	markComp := buffer.cur(0).getLigComp()
 	compIndex := compCount - 1
 	compIndex := compCount - 1
@@ -547,7 +629,7 @@ func (c *otApplyContext) applyGPOSMarkToLigature(data tables.MarkLigPos, markInd
 		compIndex = min(compCount, int(buffer.cur(0).getLigComp())) - 1
 		compIndex = min(compCount, int(buffer.cur(0).getLigComp())) - 1
 	}
 	}
 
 
-	return c.applyGPOSMarks(data.MarkArray, markIndex, compIndex, ligAttach, skippyIter.idx)
+	return c.applyGPOSMarks(data.MarkArray, markIndex, compIndex, ligAttach, idx)
 }
 }
 
 
 func (c *otApplyContext) applyGPOSMarkToMark(data tables.MarkMarkPos, mark1Index int) bool {
 func (c *otApplyContext) applyGPOSMarkToMark(data tables.MarkMarkPos, mark1Index int) bool {
@@ -557,7 +639,7 @@ func (c *otApplyContext) applyGPOSMarkToMark(data tables.MarkMarkPos, mark1Index
 	skippyIter := &c.iterInput
 	skippyIter := &c.iterInput
 	skippyIter.reset(buffer.idx, 1)
 	skippyIter.reset(buffer.idx, 1)
 	skippyIter.matcher.lookupProps = c.lookupProps &^ uint32(ignoreFlags)
 	skippyIter.matcher.lookupProps = c.lookupProps &^ uint32(ignoreFlags)
-	if !skippyIter.prev() {
+	if ok, _ := skippyIter.prev(); !ok {
 		return false
 		return false
 	}
 	}
 
 

+ 8 - 6
vendor/github.com/go-text/typesetting/harfbuzz/ot_layout_gsub.go

@@ -136,7 +136,7 @@ func (c *otApplyContext) applyGSUB(table tables.GSUBLookup) bool {
 		return false
 		return false
 	}
 	}
 
 
-	if debugMode >= 2 {
+	if debugMode {
 		fmt.Printf("\tAPPLY - type %T at index %d\n", table, c.buffer.idx)
 		fmt.Printf("\tAPPLY - type %T at index %d\n", table, c.buffer.idx)
 	}
 	}
 
 
@@ -191,18 +191,19 @@ func (c *otApplyContext) applyGSUB(table tables.GSUBLookup) bool {
 			return false // no chaining to this type
 			return false // no chaining to this type
 		}
 		}
 		lB, lL := len(data.BacktrackCoverages), len(data.LookaheadCoverages)
 		lB, lL := len(data.BacktrackCoverages), len(data.LookaheadCoverages)
+
 		hasMatch, startIndex := c.matchBacktrack(get1N(&c.indices, 0, lB), matchCoverage(data.BacktrackCoverages))
 		hasMatch, startIndex := c.matchBacktrack(get1N(&c.indices, 0, lB), matchCoverage(data.BacktrackCoverages))
 		if !hasMatch {
 		if !hasMatch {
 			return false
 			return false
 		}
 		}
 
 
-		hasMatch, endIndex := c.matchLookahead(get1N(&c.indices, 0, lL), matchCoverage(data.LookaheadCoverages), 1)
+		hasMatch, endIndex := c.matchLookahead(get1N(&c.indices, 0, lL), matchCoverage(data.LookaheadCoverages), c.buffer.idx+1)
 		if !hasMatch {
 		if !hasMatch {
 			return false
 			return false
 		}
 		}
 
 
 		c.buffer.unsafeToBreakFromOutbuffer(startIndex, endIndex)
 		c.buffer.unsafeToBreakFromOutbuffer(startIndex, endIndex)
-		c.setGlyphProps(GID(data.SubstituteGlyphIDs[index]))
+		c.setGlyphClass(GID(data.SubstituteGlyphIDs[index]))
 		c.buffer.cur(0).Glyph = GID(data.SubstituteGlyphIDs[index])
 		c.buffer.cur(0).Glyph = GID(data.SubstituteGlyphIDs[index])
 		// Note: We DON'T decrease buffer.idx.  The main loop does it
 		// Note: We DON'T decrease buffer.idx.  The main loop does it
 		// for us.  This is useful for preventing surprises if someone
 		// for us.  This is useful for preventing surprises if someone
@@ -234,7 +235,7 @@ func (c *otApplyContext) applySubsSequence(seq []gID) {
 			if ligID == 0 {
 			if ligID == 0 {
 				c.buffer.cur(0).setLigPropsForMark(0, uint8(i))
 				c.buffer.cur(0).setLigPropsForMark(0, uint8(i))
 			}
 			}
-			c.setGlyphPropsExt(GID(g), klass, false, true)
+			c.setGlyphClassExt(GID(g), klass, false, true)
 			c.buffer.outputGlyphIndex(GID(g))
 			c.buffer.outputGlyphIndex(GID(g))
 		}
 		}
 		c.buffer.skipGlyph()
 		c.buffer.skipGlyph()
@@ -284,11 +285,12 @@ func (c *otApplyContext) applySubsLigature(ligatureSet []tables.Ligature) bool {
 
 
 		var matchPositions [maxContextLength]int
 		var matchPositions [maxContextLength]int
 
 
-		ok, matchLength, totalComponentCount := c.matchInput(lig.ComponentGlyphIDs, matchGlyph, &matchPositions)
+		ok, matchEnd, totalComponentCount := c.matchInput(lig.ComponentGlyphIDs, matchGlyph, &matchPositions)
 		if !ok {
 		if !ok {
+			c.buffer.unsafeToConcat(c.buffer.idx, matchEnd)
 			continue
 			continue
 		}
 		}
-		c.ligateInput(count, matchPositions, matchLength, lig.LigatureGlyph, totalComponentCount)
+		c.ligateInput(count, matchPositions, matchEnd, lig.LigatureGlyph, totalComponentCount)
 
 
 		return true
 		return true
 	}
 	}

+ 188 - 145
vendor/github.com/go-text/typesetting/harfbuzz/ot_layout_gsubgpos.go

@@ -83,7 +83,7 @@ type getSubtablesContext []applicable
 // one for GSUB, one for GPOS (known at compile time)
 // one for GSUB, one for GPOS (known at compile time)
 type otProxyMeta struct {
 type otProxyMeta struct {
 	recurseFunc recurseFunc
 	recurseFunc recurseFunc
-	tableIndex  int
+	tableIndex  uint8 // 0 for GSUB, 1 for GPOS
 	inplace     bool
 	inplace     bool
 }
 }
 
 
@@ -126,7 +126,7 @@ func matchCoverage(covs []tables.Coverage) matcherFunc {
 }
 }
 
 
 const (
 const (
-	no = iota
+	no uint8 = iota
 	yes
 	yes
 	maybe
 	maybe
 )
 )
@@ -137,9 +137,18 @@ type otApplyContextMatcher struct {
 	mask        GlyphMask
 	mask        GlyphMask
 	ignoreZWNJ  bool
 	ignoreZWNJ  bool
 	ignoreZWJ   bool
 	ignoreZWJ   bool
+	perSyllable bool
 	syllable    uint8
 	syllable    uint8
 }
 }
 
 
+func (m *otApplyContextMatcher) setSyllable(syllable uint8) {
+	if m.perSyllable {
+		m.syllable = syllable
+	} else {
+		m.syllable = 0
+	}
+}
+
 func (m otApplyContextMatcher) mayMatch(info *GlyphInfo, glyphData []uint16) uint8 {
 func (m otApplyContextMatcher) mayMatch(info *GlyphInfo, glyphData []uint16) uint8 {
 	if info.Mask&m.mask == 0 || (m.syllable != 0 && m.syllable != info.syllable) {
 	if info.Mask&m.mask == 0 || (m.syllable != 0 && m.syllable != info.syllable) {
 		return no
 		return no
@@ -194,13 +203,11 @@ func (it *skippingIterator) init(c *otApplyContext, contextMatch bool) {
 	} else {
 	} else {
 		it.matcher.mask = c.lookupMask
 		it.matcher.mask = c.lookupMask
 	}
 	}
+	// Per syllable matching is only for GSUB.
+	it.matcher.perSyllable = c.tableIndex == 0 && c.perSyllable
+	it.matcher.setSyllable(0)
 }
 }
 
 
-// 	 void set_lookup_props (uint lookupProps)
-// 	 {
-// 	   matcher.set_lookup_props (lookupProps);
-// 	 }
-
 func (it *skippingIterator) setMatchFunc(matchFunc matcherFunc, glyphData []uint16) {
 func (it *skippingIterator) setMatchFunc(matchFunc matcherFunc, glyphData []uint16) {
 	it.matcher.matchFunc = matchFunc
 	it.matcher.matchFunc = matchFunc
 	it.matchGlyphDataArray = glyphData
 	it.matchGlyphDataArray = glyphData
@@ -212,51 +219,77 @@ func (it *skippingIterator) reset(startIndex, numItems int) {
 	it.numItems = numItems
 	it.numItems = numItems
 	it.end = len(it.c.buffer.Info)
 	it.end = len(it.c.buffer.Info)
 	if startIndex == it.c.buffer.idx {
 	if startIndex == it.c.buffer.idx {
-		it.matcher.syllable = it.c.buffer.cur(0).syllable
+		it.matcher.setSyllable(it.c.buffer.cur(0).syllable)
 	} else {
 	} else {
-		it.matcher.syllable = 0
+		it.matcher.setSyllable(0)
 	}
 	}
 }
 }
 
 
-func (it *skippingIterator) reject() {
-	it.numItems++
-	if len(it.matchGlyphDataArray) != 0 {
-		it.matchGlyphDataStart--
+func (it *skippingIterator) maySkip(info *GlyphInfo) uint8 { return it.matcher.maySkip(it.c, info) }
+
+type matchRes uint8
+
+const (
+	match matchRes = iota
+	notMatch
+	skip
+)
+
+func (it *skippingIterator) match(info *GlyphInfo) matchRes {
+	skipR := it.matcher.maySkip(it.c, info)
+	if skipR == yes {
+		return skip
 	}
 	}
+
+	matchR := it.matcher.mayMatch(info, it.matchGlyphDataArray[it.matchGlyphDataStart:])
+	if matchR == yes || (matchR == maybe && skipR == no) {
+		return match
+	}
+
+	if skipR == no {
+		return notMatch
+	}
+
+	return skip
 }
 }
 
 
-func (it *skippingIterator) maySkip(info *GlyphInfo) uint8 { return it.matcher.maySkip(it.c, info) }
+func (it *skippingIterator) next() (_ bool, unsafeTo int) {
+	// The alternate condition below is faster at string boundaries,
+	// but produces subpar "unsafe-to-concat" values.
+	stop := it.end - it.numItems
+	if (it.c.buffer.Flags & ProduceUnsafeToConcat) != 0 {
+		stop = it.end - 1
+	}
 
 
-func (it *skippingIterator) next() bool {
-	for it.idx+it.numItems < it.end {
+	for it.idx < stop {
 		it.idx++
 		it.idx++
 		info := &it.c.buffer.Info[it.idx]
 		info := &it.c.buffer.Info[it.idx]
-
-		skip := it.matcher.maySkip(it.c, info)
-		if skip == yes {
-			continue
-		}
-
-		match := it.matcher.mayMatch(info, it.matchGlyphDataArray[it.matchGlyphDataStart:])
-		if match == yes || (match == maybe && skip == no) {
+		switch it.match(info) {
+		case match:
 			it.numItems--
 			it.numItems--
 			if len(it.matchGlyphDataArray) != 0 {
 			if len(it.matchGlyphDataArray) != 0 {
 				it.matchGlyphDataStart++
 				it.matchGlyphDataStart++
 			}
 			}
-			return true
-		}
-
-		if skip == no {
-			return false
+			return true, 0
+		case notMatch:
+			return false, it.idx + 1
+		case skip:
+			continue
 		}
 		}
 	}
 	}
-	return false
+	return false, it.end
 }
 }
 
 
-func (it *skippingIterator) prev() bool {
+func (it *skippingIterator) prev() (_ bool, unsafeFrom int) {
+	// The alternate condition below is faster at string boundaries,
+	// but produces subpar "unsafe-to-concat" values.
+	stop := it.numItems - 1
+	if (it.c.buffer.Flags & ProduceUnsafeToConcat) != 0 {
+		stop = 0
+	}
+
 	L := len(it.c.buffer.outInfo)
 	L := len(it.c.buffer.outInfo)
-	//    assert (num_items > 0);
-	for it.idx > it.numItems-1 {
+	for it.idx > stop {
 		it.idx--
 		it.idx--
 		var info *GlyphInfo
 		var info *GlyphInfo
 		if it.idx < L {
 		if it.idx < L {
@@ -267,25 +300,20 @@ func (it *skippingIterator) prev() bool {
 			info = &it.c.buffer.Info[it.idx]
 			info = &it.c.buffer.Info[it.idx]
 		}
 		}
 
 
-		skip := it.matcher.maySkip(it.c, info)
-		if skip == yes {
-			continue
-		}
-
-		match := it.matcher.mayMatch(info, it.matchGlyphDataArray[it.matchGlyphDataStart:])
-		if match == yes || (match == maybe && skip == no) {
+		switch it.match(info) {
+		case match:
 			it.numItems--
 			it.numItems--
 			if len(it.matchGlyphDataArray) != 0 {
 			if len(it.matchGlyphDataArray) != 0 {
 				it.matchGlyphDataStart++
 				it.matchGlyphDataStart++
 			}
 			}
-			return true
-		}
-
-		if skip == no {
-			return false
+			return true, 0
+		case notMatch:
+			return false, max(1, it.idx) - 1
+		case skip:
+			continue
 		}
 		}
 	}
 	}
-	return false
+	return false, 0
 }
 }
 
 
 type recurseFunc = func(c *otApplyContext, lookupIndex uint16) bool
 type recurseFunc = func(c *otApplyContext, lookupIndex uint16) bool
@@ -299,11 +327,13 @@ type otApplyContext struct {
 	varStore    tables.ItemVarStore
 	varStore    tables.ItemVarStore
 	indices     []uint16 // see get1N()
 	indices     []uint16 // see get1N()
 
 
+	digest setDigest
+
 	iterContext skippingIterator
 	iterContext skippingIterator
 	iterInput   skippingIterator
 	iterInput   skippingIterator
 
 
 	nestingLevelLeft int
 	nestingLevelLeft int
-	tableIndex       int
+	tableIndex       uint8 // 0 for GSUB, 1 for GPOS
 	lookupMask       GlyphMask
 	lookupMask       GlyphMask
 	lookupProps      uint32
 	lookupProps      uint32
 	randomState      uint32
 	randomState      uint32
@@ -313,15 +343,21 @@ type otApplyContext struct {
 	hasGlyphClasses bool
 	hasGlyphClasses bool
 	autoZWNJ        bool
 	autoZWNJ        bool
 	autoZWJ         bool
 	autoZWJ         bool
+	perSyllable     bool
+	newSyllables    uint8 // 0xFF for undefined
 	random          bool
 	random          bool
+
+	lastBase      int // GPOS uses
+	lastBaseUntil int // GPOS uses
 }
 }
 
 
-func newOtApplyContext(tableIndex int, font *Font, buffer *Buffer) otApplyContext {
+func newOtApplyContext(tableIndex uint8, font *Font, buffer *Buffer) otApplyContext {
 	var out otApplyContext
 	var out otApplyContext
 	out.font = font
 	out.font = font
 	out.buffer = buffer
 	out.buffer = buffer
 	out.gdef = font.face.GDEF
 	out.gdef = font.face.GDEF
 	out.varStore = out.gdef.ItemVarStore
 	out.varStore = out.gdef.ItemVarStore
+	out.digest = buffer.digest()
 	out.direction = buffer.Props.Direction
 	out.direction = buffer.Props.Direction
 	out.lookupMask = 1
 	out.lookupMask = 1
 	out.tableIndex = tableIndex
 	out.tableIndex = tableIndex
@@ -331,7 +367,8 @@ func newOtApplyContext(tableIndex int, font *Font, buffer *Buffer) otApplyContex
 	out.autoZWNJ = true
 	out.autoZWNJ = true
 	out.autoZWJ = true
 	out.autoZWJ = true
 	out.randomState = 1
 	out.randomState = 1
-
+	out.newSyllables = 0xFF
+	out.lastBase = -1
 	out.initIters()
 	out.initIters()
 	return out
 	return out
 }
 }
@@ -346,16 +383,6 @@ func (c *otApplyContext) setLookupMask(mask GlyphMask) {
 	c.initIters()
 	c.initIters()
 }
 }
 
 
-func (c *otApplyContext) setAutoZWNJ(autoZwnj bool) {
-	c.autoZWNJ = autoZwnj
-	c.initIters()
-}
-
-func (c *otApplyContext) setAutoZWJ(autoZwj bool) {
-	c.autoZWJ = autoZwj
-	c.initIters()
-}
-
 func (c *otApplyContext) setLookupProps(lookupProps uint32) {
 func (c *otApplyContext) setLookupProps(lookupProps uint32) {
 	c.lookupProps = lookupProps
 	c.lookupProps = lookupProps
 	c.initIters()
 	c.initIters()
@@ -413,35 +440,45 @@ func (c *otApplyContext) matchPropertiesMark(glyph GID, glyphProps uint16, match
 	return true
 	return true
 }
 }
 
 
-func (c *otApplyContext) setGlyphProps(glyphIndex GID) {
-	c.setGlyphPropsExt(glyphIndex, 0, false, false)
+func (c *otApplyContext) setGlyphClass(glyphIndex GID) {
+	c.setGlyphClassExt(glyphIndex, 0, false, false)
 }
 }
 
 
-func (c *otApplyContext) setGlyphPropsExt(glyphIndex GID, classGuess uint16, ligature, component bool) {
-	addIn := c.buffer.cur(0).glyphProps & preserve
-	addIn |= substituted
+func (c *otApplyContext) setGlyphClassExt(glyphIndex_ GID, classGuess uint16, ligature, component bool) {
+	glyphIndex := gID(glyphIndex_)
+
+	c.digest.add(glyphIndex)
+
+	if c.newSyllables != 0xFF {
+		c.buffer.cur(0).syllable = c.newSyllables
+	}
+
+	props := c.buffer.cur(0).glyphProps | substituted
 	if ligature {
 	if ligature {
-		addIn |= ligated
-		/* In the only place that the MULTIPLIED bit is used, Uniscribe
-		* seems to only care about the "last" transformation between
-		* Ligature and Multiple substitutions.  Ie. if you ligate, expand,
-		* and ligate again, it forgives the multiplication and acts as
-		* if only ligation happened.  As such, clear MULTIPLIED bit.
-		 */
-		addIn &= ^multiplied
+		props |= ligated
+		// In the only place that the MULTIPLIED bit is used, Uniscribe
+		// seems to only care about the "last" transformation between
+		// Ligature and Multiple substitutions.  Ie. if you ligate, expand,
+		// and ligate again, it forgives the multiplication and acts as
+		// if only ligation happened.  As such, clear MULTIPLIED bit.
+		props &= ^multiplied
 	}
 	}
 	if component {
 	if component {
-		addIn |= multiplied
+		props |= multiplied
 	}
 	}
 	if c.hasGlyphClasses {
 	if c.hasGlyphClasses {
-		c.buffer.cur(0).glyphProps = addIn | c.gdef.GlyphProps(gID(glyphIndex))
+		props &= preserve
+		c.buffer.cur(0).glyphProps = props | c.gdef.GlyphProps(glyphIndex)
 	} else if classGuess != 0 {
 	} else if classGuess != 0 {
-		c.buffer.cur(0).glyphProps = addIn | classGuess
+		props &= preserve
+		c.buffer.cur(0).glyphProps = props | classGuess
+	} else {
+		c.buffer.cur(0).glyphProps = props
 	}
 	}
 }
 }
 
 
 func (c *otApplyContext) replaceGlyph(glyphIndex GID) {
 func (c *otApplyContext) replaceGlyph(glyphIndex GID) {
-	c.setGlyphProps(glyphIndex)
+	c.setGlyphClass(glyphIndex)
 	c.buffer.replaceGlyphIndex(glyphIndex)
 	c.buffer.replaceGlyphIndex(glyphIndex)
 }
 }
 
 
@@ -465,7 +502,7 @@ func (c *otApplyContext) applyRuleSet(ruleSet tables.SequenceRuleSet, match matc
 func (c *otApplyContext) applyChainRuleSet(ruleSet tables.ChainedClassSequenceRuleSet, match [3]matcherFunc) bool {
 func (c *otApplyContext) applyChainRuleSet(ruleSet tables.ChainedClassSequenceRuleSet, match [3]matcherFunc) bool {
 	for i, rule := range ruleSet.ChainedSeqRules {
 	for i, rule := range ruleSet.ChainedSeqRules {
 
 
-		if debugMode >= 2 {
+		if debugMode {
 			fmt.Println("APPLY - chain rule number", i)
 			fmt.Println("APPLY - chain rule number", i)
 		}
 		}
 
 
@@ -479,15 +516,17 @@ func (c *otApplyContext) applyChainRuleSet(ruleSet tables.ChainedClassSequenceRu
 
 
 // `input` starts with second glyph (`inputCount` = len(input)+1)
 // `input` starts with second glyph (`inputCount` = len(input)+1)
 func (c *otApplyContext) contextApplyLookup(input []uint16, lookupRecord []tables.SequenceLookupRecord, lookupContext matcherFunc) bool {
 func (c *otApplyContext) contextApplyLookup(input []uint16, lookupRecord []tables.SequenceLookupRecord, lookupContext matcherFunc) bool {
-	matchLength := 0
+	matchEnd := 0
 	var matchPositions [maxContextLength]int
 	var matchPositions [maxContextLength]int
-	hasMatch, matchLength, _ := c.matchInput(input, lookupContext, &matchPositions)
-	if !hasMatch {
+	hasMatch, matchEnd, _ := c.matchInput(input, lookupContext, &matchPositions)
+	if hasMatch {
+		c.buffer.unsafeToBreak(c.buffer.idx, matchEnd)
+		c.applyLookup(len(input)+1, &matchPositions, lookupRecord, matchEnd)
+		return true
+	} else {
+		c.buffer.unsafeToConcat(c.buffer.idx, matchEnd)
 		return false
 		return false
 	}
 	}
-	c.buffer.unsafeToBreak(c.buffer.idx, c.buffer.idx+matchLength)
-	c.applyLookup(len(input)+1, &matchPositions, lookupRecord, matchLength)
-	return true
 }
 }
 
 
 //	`input` starts with second glyph (`inputCount` = len(input)+1)
 //	`input` starts with second glyph (`inputCount` = len(input)+1)
@@ -498,23 +537,27 @@ func (c *otApplyContext) chainContextApplyLookup(backtrack, input, lookahead []u
 ) bool {
 ) bool {
 	var matchPositions [maxContextLength]int
 	var matchPositions [maxContextLength]int
 
 
-	hasMatch, matchLength, _ := c.matchInput(input, lookupContexts[1], &matchPositions)
-	if !hasMatch {
+	hasMatch, matchEnd, _ := c.matchInput(input, lookupContexts[1], &matchPositions)
+	endIndex := matchEnd
+	if !(hasMatch && endIndex != 0) {
+		c.buffer.unsafeToConcat(c.buffer.idx, endIndex)
 		return false
 		return false
 	}
 	}
 
 
-	hasMatch, startIndex := c.matchBacktrack(backtrack, lookupContexts[0])
+	hasMatch, endIndex = c.matchLookahead(lookahead, lookupContexts[2], matchEnd)
 	if !hasMatch {
 	if !hasMatch {
+		c.buffer.unsafeToConcat(c.buffer.idx, endIndex)
 		return false
 		return false
 	}
 	}
 
 
-	hasMatch, endIndex := c.matchLookahead(lookahead, lookupContexts[2], matchLength)
+	hasMatch, startIndex := c.matchBacktrack(backtrack, lookupContexts[0])
 	if !hasMatch {
 	if !hasMatch {
+		c.buffer.unsafeToConcatFromOutbuffer(startIndex, endIndex)
 		return false
 		return false
 	}
 	}
 
 
 	c.buffer.unsafeToBreakFromOutbuffer(startIndex, endIndex)
 	c.buffer.unsafeToBreakFromOutbuffer(startIndex, endIndex)
-	c.applyLookup(len(input)+1, &matchPositions, lookupRecord, matchLength)
+	c.applyLookup(len(input)+1, &matchPositions, lookupRecord, matchEnd)
 	return true
 	return true
 }
 }
 
 
@@ -603,7 +646,7 @@ func (c *wouldApplyContext) wouldMatchInput(input []uint16, matchFunc matcherFun
 // `input` starts with second glyph (`inputCount` = len(input)+1)
 // `input` starts with second glyph (`inputCount` = len(input)+1)
 func (c *otApplyContext) matchInput(input []uint16, matchFunc matcherFunc,
 func (c *otApplyContext) matchInput(input []uint16, matchFunc matcherFunc,
 	matchPositions *[maxContextLength]int,
 	matchPositions *[maxContextLength]int,
-) (bool, int, uint8) {
+) (_ bool, endPosition int, totalComponentCount uint8) {
 	count := len(input) + 1
 	count := len(input) + 1
 	if count > maxContextLength {
 	if count > maxContextLength {
 		return false, 0, 0
 		return false, 0, 0
@@ -637,8 +680,6 @@ func (c *otApplyContext) matchInput(input []uint16, matchFunc matcherFunc,
 	*     https://github.com/harfbuzz/harfbuzz/issues/545
 	*     https://github.com/harfbuzz/harfbuzz/issues/545
 	 */
 	 */
 
 
-	totalComponentCount := buffer.cur(0).getLigNumComps()
-
 	firstLigID := buffer.cur(0).getLigID()
 	firstLigID := buffer.cur(0).getLigID()
 	firstLigComp := buffer.cur(0).getLigComp()
 	firstLigComp := buffer.cur(0).getLigComp()
 
 
@@ -648,10 +689,9 @@ func (c *otApplyContext) matchInput(input []uint16, matchFunc matcherFunc,
 		ligbaseMaySkip
 		ligbaseMaySkip
 	)
 	)
 	ligbase := ligbaseNotChecked
 	ligbase := ligbaseNotChecked
-	matchPositions[0] = buffer.idx
 	for i := 1; i < count; i++ {
 	for i := 1; i < count; i++ {
-		if !skippyIter.next() {
-			return false, 0, 0
+		if ok, unsafeTo := skippyIter.next(); !ok {
+			return false, unsafeTo, 0
 		}
 		}
 
 
 		matchPositions[i] = skippyIter.idx
 		matchPositions[i] = skippyIter.idx
@@ -701,18 +741,20 @@ func (c *otApplyContext) matchInput(input []uint16, matchFunc matcherFunc,
 		totalComponentCount += buffer.Info[skippyIter.idx].getLigNumComps()
 		totalComponentCount += buffer.Info[skippyIter.idx].getLigNumComps()
 	}
 	}
 
 
-	endOffset := skippyIter.idx - buffer.idx + 1
+	endPosition = skippyIter.idx + 1
+	totalComponentCount += buffer.cur(0).getLigNumComps()
+	matchPositions[0] = buffer.idx
 
 
-	return true, endOffset, totalComponentCount
+	return true, endPosition, totalComponentCount
 }
 }
 
 
 // `count` and `matchPositions` include the first glyph
 // `count` and `matchPositions` include the first glyph
 func (c *otApplyContext) ligateInput(count int, matchPositions [maxContextLength]int,
 func (c *otApplyContext) ligateInput(count int, matchPositions [maxContextLength]int,
-	matchLength int, ligGlyph gID, totalComponentCount uint8,
+	matchEnd int, ligGlyph gID, totalComponentCount uint8,
 ) {
 ) {
 	buffer := c.buffer
 	buffer := c.buffer
 
 
-	buffer.mergeClusters(buffer.idx, buffer.idx+matchLength)
+	buffer.mergeClusters(buffer.idx, matchEnd)
 
 
 	/* - If a base and one or more marks ligate, consider that as a base, NOT
 	/* - If a base and one or more marks ligate, consider that as a base, NOT
 	*   ligature, such that all following marks can still attach to it.
 	*   ligature, such that all following marks can still attach to it.
@@ -774,7 +816,7 @@ func (c *otApplyContext) ligateInput(count int, matchPositions [maxContextLength
 	}
 	}
 
 
 	// ReplaceGlyph_with_ligature
 	// ReplaceGlyph_with_ligature
-	c.setGlyphPropsExt(GID(ligGlyph), klass, true, false)
+	c.setGlyphClassExt(GID(ligGlyph), klass, true, false)
 	buffer.replaceGlyphIndex(GID(ligGlyph))
 	buffer.replaceGlyphIndex(GID(ligGlyph))
 
 
 	for i := 1; i < count; i++ {
 	for i := 1; i < count; i++ {
@@ -845,7 +887,7 @@ func (c *otApplyContext) applyLookup(count int, matchPositions *[maxContextLengt
 	* Adjust. */
 	* Adjust. */
 	{
 	{
 		bl := buffer.backtrackLen()
 		bl := buffer.backtrackLen()
-		end = bl + matchLength
+		end = bl + matchLength - buffer.idx
 
 
 		delta := bl - buffer.idx
 		delta := bl - buffer.idx
 		/* Convert positions to new indexing. */
 		/* Convert positions to new indexing. */
@@ -860,9 +902,10 @@ func (c *otApplyContext) applyLookup(count int, matchPositions *[maxContextLengt
 			continue
 			continue
 		}
 		}
 
 
-		/* Don't recurse to ourself at same position.
-		 * Note that this test is too naive, it doesn't catch longer loops. */
-		if idx == 0 && lk.LookupListIndex == c.lookupIndex {
+		origLen := buffer.backtrackLen() + buffer.lookaheadLen()
+
+		// This can happen if earlier recursed lookups deleted many entries.
+		if matchPositions[idx] >= origLen {
 			continue
 			continue
 		}
 		}
 
 
@@ -872,9 +915,7 @@ func (c *otApplyContext) applyLookup(count int, matchPositions *[maxContextLengt
 			break
 			break
 		}
 		}
 
 
-		origLen := buffer.backtrackLen() + buffer.lookaheadLen()
-
-		if debugMode >= 2 {
+		if debugMode {
 			fmt.Printf("\t\tAPPLY nested lookup %d\n", lk.LookupListIndex)
 			fmt.Printf("\t\tAPPLY nested lookup %d\n", lk.LookupListIndex)
 		}
 		}
 
 
@@ -889,42 +930,44 @@ func (c *otApplyContext) applyLookup(count int, matchPositions *[maxContextLengt
 			continue
 			continue
 		}
 		}
 
 
-		/* Recursed lookup changed buffer len. Adjust.
-		 *
-		 * TODO:
-		 *
-		 * Right now, if buffer length increased by n, we assume n new glyphs
-		 * were added right after the current position, and if buffer length
-		 * was decreased by n, we assume n match positions after the current
-		 * one where removed.  The former (buffer length increased) case is
-		 * fine, but the decrease case can be improved in at least two ways,
-		 * both of which are significant:
-		 *
-		 *   - If recursed-to lookup is MultipleSubst and buffer length
-		 *     decreased, then it's current match position that was deleted,
-		 *     NOT the one after it.
-		 *
-		 *   - If buffer length was decreased by n, it does not necessarily
-		 *     mean that n match positions where removed, as there might
-		 *     have been marks and default-ignorables in the sequence.  We
-		 *     should instead drop match positions between current-position
-		 *     and current-position + n instead.
-		 *
-		 * It should be possible to construct tests for both of these cases.
-		 */
-
+		// Recursed lookup changed buffer len. Adjust.
+		//
+		// TODO:
+		//
+		// Right now, if buffer length increased by n, we assume n new glyphs
+		// were added right after the current position, and if buffer length
+		// was decreased by n, we assume n match positions after the current
+		// one where removed.  The former (buffer length increased) case is
+		// fine, but the decrease case can be improved in at least two ways,
+		// both of which are significant:
+		//
+		//   - If recursed-to lookup is MultipleSubst and buffer length
+		//     decreased, then it's current match position that was deleted,
+		//     NOT the one after it.
+		//
+		//   - If buffer length was decreased by n, it does not necessarily
+		//     mean that n match positions where removed, as there recursed-to
+		//     lookup might had a different LookupFlag.  Here's a constructed
+		//     case of that:
+		//     https://github.com/harfbuzz/harfbuzz/discussions/3538
+		//
+		// It should be possible to construct tests for both of these cases.
+		//
 		end += delta
 		end += delta
-		if end <= int(matchPositions[idx]) {
-			/* End might end up being smaller than matchPositions[idx] if the recursed
-			* lookup ended up removing many items, more than we have had matched.
-			* Just never rewind end back and get out of here.
-			* https://bugs.chromium.org/p/chromium/issues/detail?id=659496 */
+		if end < int(matchPositions[idx]) {
+			// End might end up being smaller than match_positions[idx] if the recursed
+			// lookup ended up removing many items.
+			// Just never rewind end beyond start of current position, since that is
+			// not possible in the recursed lookup.  Also adjust delta as such.
+			//
+			// https://bugs.chromium.org/p/chromium/issues/detail?id=659496
+			// https://github.com/harfbuzz/harfbuzz/issues/1611
+			//
+			delta += matchPositions[idx] - end
 			end = matchPositions[idx]
 			end = matchPositions[idx]
-			/* There can't be any further changes. */
-			break
 		}
 		}
 
 
-		next := idx + 1 /* next now is the position after the recursed lookup. */
+		next := idx + 1 // next now is the position after the recursed lookup.
 
 
 		if delta > 0 {
 		if delta > 0 {
 			if delta+count > maxContextLength {
 			if delta+count > maxContextLength {
@@ -956,28 +999,28 @@ func (c *otApplyContext) applyLookup(count int, matchPositions *[maxContextLengt
 	buffer.moveTo(end)
 	buffer.moveTo(end)
 }
 }
 
 
-func (c *otApplyContext) matchBacktrack(backtrack []uint16, matchFunc matcherFunc) (bool, int) {
+func (c *otApplyContext) matchBacktrack(backtrack []uint16, matchFunc matcherFunc) (_ bool, matchStart int) {
 	skippyIter := &c.iterContext
 	skippyIter := &c.iterContext
 	skippyIter.reset(c.buffer.backtrackLen(), len(backtrack))
 	skippyIter.reset(c.buffer.backtrackLen(), len(backtrack))
 	skippyIter.setMatchFunc(matchFunc, backtrack)
 	skippyIter.setMatchFunc(matchFunc, backtrack)
 
 
 	for i := 0; i < len(backtrack); i++ {
 	for i := 0; i < len(backtrack); i++ {
-		if !skippyIter.prev() {
-			return false, 0
+		if ok, unsafeFrom := skippyIter.prev(); !ok {
+			return false, unsafeFrom
 		}
 		}
 	}
 	}
 
 
 	return true, skippyIter.idx
 	return true, skippyIter.idx
 }
 }
 
 
-func (c *otApplyContext) matchLookahead(lookahead []uint16, matchFunc matcherFunc, offset int) (bool, int) {
+func (c *otApplyContext) matchLookahead(lookahead []uint16, matchFunc matcherFunc, startIndex int) (_ bool, endIndex int) {
 	skippyIter := &c.iterContext
 	skippyIter := &c.iterContext
-	skippyIter.reset(c.buffer.idx+offset-1, len(lookahead))
+	skippyIter.reset(startIndex-1, len(lookahead))
 	skippyIter.setMatchFunc(matchFunc, lookahead)
 	skippyIter.setMatchFunc(matchFunc, lookahead)
 
 
 	for i := 0; i < len(lookahead); i++ {
 	for i := 0; i < len(lookahead); i++ {
-		if !skippyIter.next() {
-			return false, 0
+		if ok, unsafeTo := skippyIter.next(); !ok {
+			return false, unsafeTo
 		}
 		}
 	}
 	}
 
 

+ 96 - 52
vendor/github.com/go-text/typesetting/harfbuzz/ot_map.go

@@ -7,6 +7,7 @@ import (
 	"sort"
 	"sort"
 
 
 	"github.com/go-text/typesetting/opentype/api/font"
 	"github.com/go-text/typesetting/opentype/api/font"
+	"github.com/go-text/typesetting/opentype/loader"
 	"github.com/go-text/typesetting/opentype/tables"
 	"github.com/go-text/typesetting/opentype/tables"
 )
 )
 
 
@@ -15,12 +16,14 @@ import (
 type otMapFeatureFlags uint8
 type otMapFeatureFlags uint8
 
 
 const (
 const (
-	ffGLOBAL              otMapFeatureFlags = 1 << iota /* Feature applies to all characters; results in no mask allocated for it. */
-	ffHasFallback                                       /* Has fallback implementation, so include mask bit even if feature not found. */
-	ffManualZWNJ                                        /* Don't skip over ZWNJ when matching **context**. */
-	ffManualZWJ                                         /* Don't skip over ZWJ when matching **input**. */
-	ffGlobalSearch                                      /* If feature not found in LangSys, look for it in global feature list and pick one. */
-	ffRandom                                            /* Randomly select a glyph from an AlternateSubstFormat1 subtable. */
+	ffGLOBAL       otMapFeatureFlags = 1 << iota /* Feature applies to all characters; results in no mask allocated for it. */
+	ffHasFallback                                /* Has fallback implementation, so include mask bit even if feature not found. */
+	ffManualZWNJ                                 /* Don't skip over ZWNJ when matching **context**. */
+	ffManualZWJ                                  /* Don't skip over ZWJ when matching **input**. */
+	ffGlobalSearch                               /* If feature not found in LangSys, look for it in global feature list and pick one. */
+	ffRandom                                     /* Randomly select a glyph from an AlternateSubstFormat1 subtable. */
+	ffPerSyllable                                /* Contain lookup application to within syllable. */
+
 	ffNone                otMapFeatureFlags = 0
 	ffNone                otMapFeatureFlags = 0
 	ffManualJoiners                         = ffManualZWNJ | ffManualZWJ
 	ffManualJoiners                         = ffManualZWNJ | ffManualZWJ
 	ffGlobalManualJoiners                   = ffGLOBAL | ffManualJoiners
 	ffGlobalManualJoiners                   = ffGLOBAL | ffManualJoiners
@@ -73,11 +76,11 @@ func newOtMapBuilder(tables *font.Font, props SegmentProperties) otMapBuilder {
 	* features not available in either table and not waste precious bits for them. */
 	* features not available in either table and not waste precious bits for them. */
 	scriptTags, languageTags := newOTTagsFromScriptAndLanguage(props.Script, props.Language)
 	scriptTags, languageTags := newOTTagsFromScriptAndLanguage(props.Script, props.Language)
 
 
-	out.scriptIndex[0], out.chosenScript[0], out.foundScript[0] = SelectScript(&tables.GSUB.Layout, scriptTags)
-	out.languageIndex[0], _ = SelectLanguage(&tables.GSUB.Layout, out.scriptIndex[0], languageTags)
+	out.scriptIndex[0], out.chosenScript[0], out.foundScript[0] = selectScript(&tables.GSUB.Layout, scriptTags)
+	out.languageIndex[0], _ = selectLanguage(&tables.GSUB.Layout, out.scriptIndex[0], languageTags)
 
 
-	out.scriptIndex[1], out.chosenScript[1], out.foundScript[1] = SelectScript(&tables.GPOS.Layout, scriptTags)
-	out.languageIndex[1], _ = SelectLanguage(&tables.GPOS.Layout, out.scriptIndex[1], languageTags)
+	out.scriptIndex[1], out.chosenScript[1], out.foundScript[1] = selectScript(&tables.GPOS.Layout, scriptTags)
+	out.languageIndex[1], _ = selectLanguage(&tables.GPOS.Layout, out.scriptIndex[1], languageTags)
 
 
 	return out
 	return out
 }
 }
@@ -95,7 +98,9 @@ func (mb *otMapBuilder) addFeatureExt(tag tables.Tag, flags otMapFeatureFlags, v
 	mb.featureInfos = append(mb.featureInfos, info)
 	mb.featureInfos = append(mb.featureInfos, info)
 }
 }
 
 
-type pauseFunc func(plan *otShapePlan, font *Font, buffer *Buffer)
+// Pause functions return true if new glyph indices might have been
+// added to the buffer.  This is used to update buffer digest.
+type pauseFunc func(plan *otShapePlan, font *Font, buffer *Buffer) bool
 
 
 func (mb *otMapBuilder) addPause(tableIndex int, fn pauseFunc) {
 func (mb *otMapBuilder) addPause(tableIndex int, fn pauseFunc) {
 	s := stageInfo{
 	s := stageInfo{
@@ -112,6 +117,8 @@ func (mb *otMapBuilder) addGPOSPause(fn pauseFunc) { mb.addPause(1, fn) }
 func (mb *otMapBuilder) enableFeatureExt(tag tables.Tag, flags otMapFeatureFlags, value uint32) {
 func (mb *otMapBuilder) enableFeatureExt(tag tables.Tag, flags otMapFeatureFlags, value uint32) {
 	mb.addFeatureExt(tag, ffGLOBAL|flags, value)
 	mb.addFeatureExt(tag, ffGLOBAL|flags, value)
 }
 }
+
+// shortand for enableFeatureExt(tag, None, 1)
 func (mb *otMapBuilder) enableFeature(tag tables.Tag)  { mb.enableFeatureExt(tag, ffNone, 1) }
 func (mb *otMapBuilder) enableFeature(tag tables.Tag)  { mb.enableFeatureExt(tag, ffNone, 1) }
 func (mb *otMapBuilder) addFeature(tag tables.Tag)     { mb.addFeatureExt(tag, ffNone, 1) }
 func (mb *otMapBuilder) addFeature(tag tables.Tag)     { mb.addFeatureExt(tag, ffNone, 1) }
 func (mb *otMapBuilder) disableFeature(tag tables.Tag) { mb.addFeatureExt(tag, ffGLOBAL, 0) }
 func (mb *otMapBuilder) disableFeature(tag tables.Tag) { mb.addFeatureExt(tag, ffGLOBAL, 0) }
@@ -199,7 +206,7 @@ func (mb *otMapBuilder) compile(m *otMap, key otShapePlanKey) {
 			if requiredFeatureTag[tableIndex] == info.Tag {
 			if requiredFeatureTag[tableIndex] == info.Tag {
 				requiredFeatureStage[tableIndex] = info.stage[tableIndex]
 				requiredFeatureStage[tableIndex] = info.stage[tableIndex]
 			}
 			}
-			featureIndex[tableIndex] = FindFeatureForLang(table, mb.scriptIndex[tableIndex], mb.languageIndex[tableIndex], info.Tag)
+			featureIndex[tableIndex] = findFeatureForLang(table, mb.scriptIndex[tableIndex], mb.languageIndex[tableIndex], info.Tag)
 			found = found || featureIndex[tableIndex] != NoFeatureIndex
 			found = found || featureIndex[tableIndex] != NoFeatureIndex
 		}
 		}
 		if !found && (info.flags&ffGlobalSearch) != 0 {
 		if !found && (info.flags&ffGlobalSearch) != 0 {
@@ -219,6 +226,7 @@ func (mb *otMapBuilder) compile(m *otMap, key otShapePlanKey) {
 		map_.autoZWNJ = info.flags&ffManualZWNJ == 0
 		map_.autoZWNJ = info.flags&ffManualZWNJ == 0
 		map_.autoZWJ = info.flags&ffManualZWJ == 0
 		map_.autoZWJ = info.flags&ffManualZWJ == 0
 		map_.random = info.flags&ffRandom != 0
 		map_.random = info.flags&ffRandom != 0
+		map_.perSyllable = info.flags&ffPerSyllable != 0
 		if (info.flags&ffGLOBAL) != 0 && info.maxValue == 1 {
 		if (info.flags&ffGLOBAL) != 0 && info.maxValue == 1 {
 			// uses the global bit
 			// uses the global bit
 			map_.shift = globalBitShift
 			map_.shift = globalBitShift
@@ -232,7 +240,7 @@ func (mb *otMapBuilder) compile(m *otMap, key otShapePlanKey) {
 		map_.mask1 = (1 << map_.shift) & map_.mask
 		map_.mask1 = (1 << map_.shift) & map_.mask
 		map_.needsFallback = !found
 		map_.needsFallback = !found
 
 
-		if debugMode >= 1 {
+		if debugMode {
 			fmt.Printf("\tMAP - adding feature %s (%d) for stage %v\n", info.Tag, info.Tag, info.stage)
 			fmt.Printf("\tMAP - adding feature %s (%d) for stage %v\n", info.Tag, info.Tag, info.stage)
 		}
 		}
 
 
@@ -245,13 +253,15 @@ func (mb *otMapBuilder) compile(m *otMap, key otShapePlanKey) {
 
 
 	// collect lookup indices for features
 	// collect lookup indices for features
 	for tableIndex, table := range tables {
 	for tableIndex, table := range tables {
+		// Collect lookup indices for features
 		stageIndex := 0
 		stageIndex := 0
 		lastNumLookups := 0
 		lastNumLookups := 0
 		for stage := 0; stage < mb.currentStage[tableIndex]; stage++ {
 		for stage := 0; stage < mb.currentStage[tableIndex]; stage++ {
 			if requiredFeatureIndex[tableIndex] != NoFeatureIndex &&
 			if requiredFeatureIndex[tableIndex] != NoFeatureIndex &&
 				requiredFeatureStage[tableIndex] == stage {
 				requiredFeatureStage[tableIndex] == stage {
+				const emptyTag = 0x20202020 // ("    ")
 				m.addLookups(table, tableIndex, requiredFeatureIndex[tableIndex],
 				m.addLookups(table, tableIndex, requiredFeatureIndex[tableIndex],
-					key[tableIndex], globalBitMask, true, true, false)
+					key[tableIndex], globalBitMask, true, true, false, false, emptyTag)
 			}
 			}
 
 
 			for _, feat := range m.features {
 			for _, feat := range m.features {
@@ -262,7 +272,10 @@ func (mb *otMapBuilder) compile(m *otMap, key otShapePlanKey) {
 						feat.mask,
 						feat.mask,
 						feat.autoZWNJ,
 						feat.autoZWNJ,
 						feat.autoZWJ,
 						feat.autoZWJ,
-						feat.random)
+						feat.random,
+						feat.perSyllable,
+						feat.tag,
+					)
 				}
 				}
 			}
 			}
 			// sort lookups and merge duplicates
 			// sort lookups and merge duplicates
@@ -282,7 +295,7 @@ func (mb *otMapBuilder) compile(m *otMap, key otShapePlanKey) {
 						ls[j].autoZWJ = ls[j].autoZWJ && ls[i].autoZWJ
 						ls[j].autoZWJ = ls[j].autoZWJ && ls[i].autoZWJ
 					}
 					}
 				}
 				}
-				m.lookups[tableIndex] = m.lookups[tableIndex][:j+1]
+				m.lookups[tableIndex] = ls[:j+1]
 			}
 			}
 
 
 			lastNumLookups = len(m.lookups[tableIndex])
 			lastNumLookups = len(m.lookups[tableIndex])
@@ -299,6 +312,17 @@ func (mb *otMapBuilder) compile(m *otMap, key otShapePlanKey) {
 	}
 	}
 }
 }
 
 
+func (mb *otMapBuilder) hasFeature(tag loader.Tag) bool {
+	tables := [2]*font.Layout{&mb.tables.GSUB.Layout, &mb.tables.GPOS.Layout}
+
+	for tableIndex, table := range tables {
+		if findFeatureForLang(table, mb.scriptIndex[tableIndex], mb.languageIndex[tableIndex], tag) != NoFeatureIndex {
+			return true
+		}
+	}
+	return false
+}
+
 type featureMap struct {
 type featureMap struct {
 	tag           tables.Tag /* should be first for our bsearch to work */
 	tag           tables.Tag /* should be first for our bsearch to work */
 	index         [2]uint16  /* GSUB/GPOS */
 	index         [2]uint16  /* GSUB/GPOS */
@@ -310,11 +334,10 @@ type featureMap struct {
 	autoZWNJ      bool      // = 1;
 	autoZWNJ      bool      // = 1;
 	autoZWJ       bool      // = 1;
 	autoZWJ       bool      // = 1;
 	random        bool      // = 1;
 	random        bool      // = 1;
-
-	// int cmp (const hb_tag_t tag_) const
-	// { return tag_ < tag ? -1 : tag_ > tag ? 1 : 0; }
+	perSyllable   bool
 }
 }
 
 
+// by tag
 func bsearchFeature(features []featureMap, tag tables.Tag) *featureMap {
 func bsearchFeature(features []featureMap, tag tables.Tag) *featureMap {
 	low, high := 0, len(features)
 	low, high := 0, len(features)
 	for low < high {
 	for low < high {
@@ -332,11 +355,13 @@ func bsearchFeature(features []featureMap, tag tables.Tag) *featureMap {
 }
 }
 
 
 type lookupMap struct {
 type lookupMap struct {
-	index    uint16
-	autoZWNJ bool // = 1;
-	autoZWJ  bool // = 1;
-	random   bool // = 1;
-	mask     GlyphMask
+	index       uint16
+	autoZWNJ    bool // = 1;
+	autoZWJ     bool // = 1;
+	random      bool // = 1;
+	perSyllable bool
+	featureTag  loader.Tag
+	mask        GlyphMask
 
 
 	// HB_INTERNAL static int cmp (const void *pa, const void *pb)
 	// HB_INTERNAL static int cmp (const void *pa, const void *pb)
 	// {
 	// {
@@ -412,16 +437,18 @@ func (m *otMap) getStageLookups(tableIndex, stage int) []lookupMap {
 }
 }
 
 
 func (m *otMap) addLookups(table *font.Layout, tableIndex int, featureIndex uint16, variationsIndex int,
 func (m *otMap) addLookups(table *font.Layout, tableIndex int, featureIndex uint16, variationsIndex int,
-	mask GlyphMask, autoZwnj, autoZwj, random bool,
+	mask GlyphMask, autoZwnj, autoZwj, random, perSyllable bool, featureTag loader.Tag,
 ) {
 ) {
 	lookupIndices := getFeatureLookupsWithVar(table, featureIndex, variationsIndex)
 	lookupIndices := getFeatureLookupsWithVar(table, featureIndex, variationsIndex)
 	for _, lookupInd := range lookupIndices {
 	for _, lookupInd := range lookupIndices {
 		lookup := lookupMap{
 		lookup := lookupMap{
-			mask:     mask,
-			index:    lookupInd,
-			autoZWNJ: autoZwnj,
-			autoZWJ:  autoZwj,
-			random:   random,
+			mask:        mask,
+			index:       lookupInd,
+			autoZWNJ:    autoZwnj,
+			autoZWJ:     autoZwj,
+			random:      random,
+			perSyllable: perSyllable,
+			featureTag:  featureTag,
 		}
 		}
 		m.lookups[tableIndex] = append(m.lookups[tableIndex], lookup)
 		m.lookups[tableIndex] = append(m.lookups[tableIndex], lookup)
 	}
 	}
@@ -429,28 +456,28 @@ func (m *otMap) addLookups(table *font.Layout, tableIndex int, featureIndex uint
 
 
 // apply the GSUB table
 // apply the GSUB table
 func (m *otMap) substitute(plan *otShapePlan, font *Font, buffer *Buffer) {
 func (m *otMap) substitute(plan *otShapePlan, font *Font, buffer *Buffer) {
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("SUBSTITUTE - start table GSUB")
 		fmt.Println("SUBSTITUTE - start table GSUB")
 	}
 	}
 
 
 	proxy := otProxy{otProxyMeta: proxyGSUB, accels: font.gsubAccels}
 	proxy := otProxy{otProxyMeta: proxyGSUB, accels: font.gsubAccels}
 	m.apply(proxy, plan, font, buffer)
 	m.apply(proxy, plan, font, buffer)
 
 
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("SUBSTITUTE - end table GSUB")
 		fmt.Println("SUBSTITUTE - end table GSUB")
 	}
 	}
 }
 }
 
 
 // apply the GPOS table
 // apply the GPOS table
 func (m *otMap) position(plan *otShapePlan, font *Font, buffer *Buffer) {
 func (m *otMap) position(plan *otShapePlan, font *Font, buffer *Buffer) {
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("POSITION - start table GPOS")
 		fmt.Println("POSITION - start table GPOS")
 	}
 	}
 
 
 	proxy := otProxy{otProxyMeta: proxyGPOS, accels: font.gposAccels}
 	proxy := otProxy{otProxyMeta: proxyGPOS, accels: font.gposAccels}
 	m.apply(proxy, plan, font, buffer)
 	m.apply(proxy, plan, font, buffer)
 
 
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("POSITION - end table GPOS")
 		fmt.Println("POSITION - end table GPOS")
 	}
 	}
 }
 }
@@ -463,42 +490,59 @@ func (m *otMap) apply(proxy otProxy, plan *otShapePlan, font *Font, buffer *Buff
 
 
 	for stageI, stage := range m.stages[tableIndex] {
 	for stageI, stage := range m.stages[tableIndex] {
 
 
-		if debugMode >= 2 {
+		if debugMode {
 			fmt.Printf("\tAPPLY - stage %d\n", stageI)
 			fmt.Printf("\tAPPLY - stage %d\n", stageI)
 		}
 		}
 
 
 		for ; i < stage.lastLookup; i++ {
 		for ; i < stage.lastLookup; i++ {
-			lookupIndex := m.lookups[tableIndex][i].index
+			lookup := m.lookups[tableIndex][i]
+			lookupIndex := lookup.index
 
 
-			if debugMode >= 1 {
+			if debugMode {
 				fmt.Printf("\t\tLookup %d start\n", lookupIndex)
 				fmt.Printf("\t\tLookup %d start\n", lookupIndex)
 			}
 			}
 
 
-			c.lookupIndex = lookupIndex
-			c.setLookupMask(m.lookups[tableIndex][i].mask)
-			c.setAutoZWJ(m.lookups[tableIndex][i].autoZWJ)
-			c.setAutoZWNJ(m.lookups[tableIndex][i].autoZWNJ)
-			c.random = m.lookups[tableIndex][i].random
-
-			// pathological cases
-			if len(c.buffer.Info) > c.buffer.maxLen {
-				return
+			// c.digest is a digest of all the current glyphs in the buffer
+			// (plus some past glyphs).
+			//
+			// Only try applying the lookup if there is any overlap. */
+			accel := &proxy.accels[lookupIndex]
+			if accel.digest.mayHaveDigest(c.digest) {
+
+				c.lookupIndex = lookupIndex
+				c.lookupMask = lookup.mask
+				c.autoZWJ = lookup.autoZWJ
+				c.autoZWNJ = lookup.autoZWNJ
+				c.random = lookup.random
+				c.perSyllable = lookup.perSyllable
+
+				// pathological cases
+				if len(c.buffer.Info) > c.buffer.maxLen {
+					return
+				}
+				c.applyString(proxy.otProxyMeta, accel)
 			}
 			}
-			c.applyString(proxy.otProxyMeta, &proxy.accels[lookupIndex])
 
 
-			if debugMode >= 1 {
-				fmt.Println("\t\tLookup end")
-				fmt.Println(c.buffer.Info)
+			if debugMode {
+				fmt.Print("\t\tLookup end : ")
+				if proxy.tableIndex == 0 {
+					fmt.Println(c.buffer.Info)
+				} else {
+					fmt.Println(c.buffer.Pos)
+				}
 			}
 			}
 
 
 		}
 		}
 
 
 		if stage.pauseFunc != nil {
 		if stage.pauseFunc != nil {
-			if debugMode >= 1 {
+			if debugMode {
 				fmt.Println("\t\tExecuting pause function")
 				fmt.Println("\t\tExecuting pause function")
 			}
 			}
 
 
-			stage.pauseFunc(plan, font, buffer)
+			if stage.pauseFunc(plan, font, buffer) {
+				// Refresh working buffer digest since buffer changed.
+				c.digest = buffer.digest()
+			}
 		}
 		}
 	}
 	}
 }
 }

+ 73 - 119
vendor/github.com/go-text/typesetting/harfbuzz/ot_myanmar.go

@@ -16,6 +16,30 @@ type complexShaperMyanmar struct {
 
 
 var _ otComplexShaper = complexShaperMyanmar{}
 var _ otComplexShaper = complexShaperMyanmar{}
 
 
+func setMyanmarProperties(info *GlyphInfo) {
+	u := info.codepoint
+	type_ := indicGetCategories(u)
+	cat := uint8(type_ & 0xFF)
+	// pos := uint8(type_ >> 8)
+
+	info.complexCategory = cat
+	// info.complexAux = pos
+}
+
+/* Note:
+ *
+ * We treat Vowels and placeholders as if they were consonants.  This is safe because Vowels
+ * cannot happen in a consonant syllable.  The plus side however is, we can call the
+ * consonant syllable logic from the vowel syllable function and get it all right!
+ *
+ * Keep in sync with consonant_categories in the generator. */
+const consonantFlagsMyanmar = (1 << myaSM_ex_C) | 1<<myaSM_ex_CS | myaSM_ex_Ra |
+	1<<myaSM_ex_IV | 1<<myaSM_ex_GB | 1<<myaSM_ex_DOTTEDCIRCLE
+
+func isConsonantMyanmar(info *GlyphInfo) bool {
+	return isOneOf(info, consonantFlagsMyanmar)
+}
+
 /*
 /*
  * Basic features.
  * Basic features.
  * These features are applied in order, one at a time, after reordering.
  * These features are applied in order, one at a time, after reordering.
@@ -52,11 +76,11 @@ func (complexShaperMyanmar) collectFeatures(plan *otShapePlanner) {
 	map_.addGSUBPause(reorderMyanmar)
 	map_.addGSUBPause(reorderMyanmar)
 
 
 	for _, feat := range myanmarBasicFeatures {
 	for _, feat := range myanmarBasicFeatures {
-		map_.enableFeatureExt(feat, ffManualZWJ, 1)
+		map_.enableFeatureExt(feat, ffManualZWJ|ffPerSyllable, 1)
 		map_.addGSUBPause(nil)
 		map_.addGSUBPause(nil)
 	}
 	}
 
 
-	map_.addGSUBPause(clearSyllables)
+	map_.addGSUBPause(nil)
 
 
 	for _, feat := range myanmarOtherFeatures {
 	for _, feat := range myanmarOtherFeatures {
 		map_.enableFeatureExt(feat, ffManualZWJ, 1)
 		map_.enableFeatureExt(feat, ffManualZWJ, 1)
@@ -64,8 +88,7 @@ func (complexShaperMyanmar) collectFeatures(plan *otShapePlanner) {
 }
 }
 
 
 func (complexShaperMyanmar) setupMasks(_ *otShapePlan, buffer *Buffer, _ *Font) {
 func (complexShaperMyanmar) setupMasks(_ *otShapePlan, buffer *Buffer, _ *Font) {
-	/* We cannot setup masks here.  We save information about characters
-	* and setup masks later on in a pause-callback. */
+	// No masks, we just save information about characters.
 
 
 	info := buffer.Info
 	info := buffer.Info
 	for i := range info {
 	for i := range info {
@@ -83,12 +106,13 @@ func foundSyllableMyanmar(syllableType uint8, ts, te int, info []GlyphInfo, syll
 	}
 	}
 }
 }
 
 
-func setupSyllablesMyanmar(_ *otShapePlan, _ *Font, buffer *Buffer) {
+func setupSyllablesMyanmar(_ *otShapePlan, _ *Font, buffer *Buffer) bool {
 	findSyllablesMyanmar(buffer)
 	findSyllablesMyanmar(buffer)
 	iter, count := buffer.syllableIterator()
 	iter, count := buffer.syllableIterator()
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 		buffer.unsafeToBreak(start, end)
 		buffer.unsafeToBreak(start, end)
 	}
 	}
+	return false
 }
 }
 
 
 /* Rules from:
 /* Rules from:
@@ -101,9 +125,9 @@ func initialReorderingConsonantSyllableMyanmar(buffer *Buffer, start, end int) {
 
 
 	limit := start
 	limit := start
 	if start+3 <= end &&
 	if start+3 <= end &&
-		info[start].complexCategory == otRa &&
-		info[start+1].complexCategory == otAs &&
-		info[start+2].complexCategory == otH {
+		info[start].complexCategory == myaSM_ex_Ra &&
+		info[start+1].complexCategory == myaSM_ex_As &&
+		info[start+2].complexCategory == myaSM_ex_H {
 		limit += 3
 		limit += 3
 		base = start
 		base = start
 		hasReph = true
 		hasReph = true
@@ -114,7 +138,7 @@ func initialReorderingConsonantSyllableMyanmar(buffer *Buffer, start, end int) {
 	}
 	}
 
 
 	for i := limit; i < end; i++ {
 	for i := limit; i < end; i++ {
-		if isConsonant(&info[i]) {
+		if isConsonantMyanmar(&info[i]) {
 			base = i
 			base = i
 			break
 			break
 		}
 		}
@@ -140,33 +164,34 @@ func initialReorderingConsonantSyllableMyanmar(buffer *Buffer, start, end int) {
 	/* The following loop may be ugly, but it implements all of
 	/* The following loop may be ugly, but it implements all of
 	 * Myanmar reordering! */
 	 * Myanmar reordering! */
 	for ; i < end; i++ {
 	for ; i < end; i++ {
-		if info[i].complexCategory == otMR /* Pre-base reordering */ {
+		if info[i].complexCategory == myaSM_ex_MR /* Pre-base reordering */ {
 			info[i].complexAux = posPreC
 			info[i].complexAux = posPreC
 			continue
 			continue
 		}
 		}
-		if info[i].complexAux < posBaseC /* Left matra */ {
+		if info[i].complexCategory == myaSM_ex_VPre /* Left matra */ {
+			info[i].complexAux = posPreM
 			continue
 			continue
 		}
 		}
-		if info[i].complexCategory == otVS {
+		if info[i].complexCategory == myaSM_ex_VS {
 			info[i].complexAux = info[i-1].complexAux
 			info[i].complexAux = info[i-1].complexAux
 			continue
 			continue
 		}
 		}
 
 
-		if pos == posAfterMain && info[i].complexCategory == otVBlw {
+		if pos == posAfterMain && info[i].complexCategory == myaSM_ex_VBlw {
 			pos = posBelowC
 			pos = posBelowC
 			info[i].complexAux = pos
 			info[i].complexAux = pos
 			continue
 			continue
 		}
 		}
 
 
-		if pos == posBelowC && info[i].complexCategory == otA {
+		if pos == posBelowC && info[i].complexCategory == myaSM_ex_A {
 			info[i].complexAux = posBeforeSub
 			info[i].complexAux = posBeforeSub
 			continue
 			continue
 		}
 		}
-		if pos == posBelowC && info[i].complexCategory == otVBlw {
+		if pos == posBelowC && info[i].complexCategory == myaSM_ex_VBlw {
 			info[i].complexAux = pos
 			info[i].complexAux = pos
 			continue
 			continue
 		}
 		}
-		if pos == posBelowC && info[i].complexCategory != otA {
+		if pos == posBelowC && info[i].complexCategory != myaSM_ex_A {
 			pos = posAfterSub
 			pos = posAfterSub
 			info[i].complexAux = pos
 			info[i].complexAux = pos
 			continue
 			continue
@@ -176,6 +201,31 @@ func initialReorderingConsonantSyllableMyanmar(buffer *Buffer, start, end int) {
 
 
 	/* Sit tight, rock 'n roll! */
 	/* Sit tight, rock 'n roll! */
 	buffer.sort(start, end, func(a, b *GlyphInfo) int { return int(a.complexAux) - int(b.complexAux) })
 	buffer.sort(start, end, func(a, b *GlyphInfo) int { return int(a.complexAux) - int(b.complexAux) })
+
+	/* Flip left-matra sequence. */
+	firstLeftMatra := end
+	lastLeftMatra := end
+	for i := start; i < end; i++ {
+		if info[i].complexAux == posPreM {
+			if firstLeftMatra == end {
+				firstLeftMatra = i
+			}
+			lastLeftMatra = i
+		}
+	}
+	/* https://github.com/harfbuzz/harfbuzz/issues/3863 */
+	if firstLeftMatra < lastLeftMatra {
+		// No need to merge clusters, done already?
+		buffer.reverseRange(firstLeftMatra, lastLeftMatra+1)
+		// Reverse back VS, etc.
+		i := firstLeftMatra
+		for j := i; j <= lastLeftMatra; j++ {
+			if info[j].complexCategory == myaSM_ex_VPre {
+				buffer.reverseRange(i, j+1)
+				i = j + 1
+			}
+		}
+	}
 }
 }
 
 
 func reorderSyllableMyanmar(buffer *Buffer, start, end int) {
 func reorderSyllableMyanmar(buffer *Buffer, start, end int) {
@@ -187,119 +237,23 @@ func reorderSyllableMyanmar(buffer *Buffer, start, end int) {
 	}
 	}
 }
 }
 
 
-func reorderMyanmar(_ *otShapePlan, font *Font, buffer *Buffer) {
-	if debugMode >= 1 {
-		fmt.Println("MYANMAR - start reordering myanmar")
+func reorderMyanmar(_ *otShapePlan, font *Font, buffer *Buffer) bool {
+	if debugMode {
+		fmt.Println("MYANMAR - start reordering myanmar", buffer.Info)
 	}
 	}
 
 
-	syllabicInsertDottedCircles(font, buffer, myanmarBrokenCluster, otGB, -1, -1)
+	ret := syllabicInsertDottedCircles(font, buffer, myanmarBrokenCluster, myaSM_ex_DOTTEDCIRCLE, -1, -1)
 
 
 	iter, count := buffer.syllableIterator()
 	iter, count := buffer.syllableIterator()
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 		reorderSyllableMyanmar(buffer, start, end)
 		reorderSyllableMyanmar(buffer, start, end)
 	}
 	}
 
 
-	if debugMode >= 1 {
-		fmt.Println("MYANMAR - end reordering myanmar")
-	}
-}
-
-/* Note: This enum is duplicated in the -machine.rl source file.
- * Not sure how to avoid duplication. */
-const (
-	otAs = 18  /* Asat */
-	otD0 = 20  /* Digit zero */
-	otDB = otN /* Dot below */
-	otGB = otPLACEHOLDER
-	otMH = 21 /* Various consonant medial types */
-	otMR = 22 /* Various consonant medial types */
-	otMW = 23 /* Various consonant medial types */
-	otMY = 24 /* Various consonant medial types */
-	otPT = 25 /* Pwo and other tones */
-	// otVAbv = 26
-	// otVBlw = 27
-	// otVPre = 28
-	// otVPst = 29
-	otVS = 30 /* Variation selectors */
-	otP  = 31 /* Punctuation */
-	otD  = 32 /* Digits except zero */
-	otML = 33 /* Various consonant medial types */
-)
-
-func computeMyanmarProperties(u rune) (cat, pos uint8) {
-	type_ := indicGetCategories(u)
-	cat = uint8(type_ & 0xFF)
-	pos = uint8(type_ >> 8)
-
-	/* Myanmar
-	* https://docs.microsoft.com/en-us/typography/script-development/myanmar#analyze */
-	if 0xFE00 <= u && u <= 0xFE0F {
-		cat = otVS
-	}
-
-	switch u {
-	case 0x104E:
-		cat = otC /* The spec says C, IndicSyllableCategory doesn't have. */
-	case 0x002D, 0x00A0, 0x00D7, 0x2012, 0x2013, 0x2014, 0x2015, 0x2022,
-		0x25CC, 0x25FB, 0x25FC, 0x25FD, 0x25FE:
-		cat = otGB
-	case 0x1004, 0x101B, 0x105A:
-		cat = otRa
-	case 0x1032, 0x1036:
-		cat = otA
-	case 0x1039:
-		cat = otH
-	case 0x103A:
-		cat = otAs
-	case 0x1041, 0x1042, 0x1043, 0x1044, 0x1045, 0x1046, 0x1047, 0x1048,
-		0x1049, 0x1090, 0x1091, 0x1092, 0x1093, 0x1094, 0x1095, 0x1096, 0x1097, 0x1098, 0x1099:
-		cat = otD
-	case 0x1040:
-		cat = otD /* The spec says D0, but Uniscribe doesn't seem to do. */
-	case 0x103E:
-		cat = otMH
-	case 0x1060:
-		cat = otML
-	case 0x103C:
-		cat = otMR
-	case 0x103D, 0x1082:
-		cat = otMW
-	case 0x103B, 0x105E, 0x105F:
-		cat = otMY
-	case 0x1063, 0x1064, 0x1069, 0x106A, 0x106B, 0x106C, 0x106D, 0xAA7B:
-		cat = otPT
-	case 0x1038, 0x1087, 0x1088, 0x1089, 0x108A, 0x108B, 0x108C, 0x108D,
-		0x108F, 0x109A, 0x109B, 0x109C:
-		cat = otSM
-	case 0x104A, 0x104B:
-		cat = otP
-	case 0xAA74, 0xAA75, 0xAA76:
-		/* https://github.com/harfbuzz/harfbuzz/issues/218 */
-		cat = otC
+	if debugMode {
+		fmt.Println("MYANMAR - end reordering myanmar", buffer.Info)
 	}
 	}
 
 
-	if cat == otM {
-		switch pos {
-		case posPreC:
-			cat = otVPre
-			pos = posPreM
-		case posAboveC:
-			cat = otVAbv
-		case posBelowC:
-			cat = otVBlw
-		case posPostC:
-			cat = otVPst
-		}
-	}
-
-	return cat, pos
-}
-
-func setMyanmarProperties(info *GlyphInfo) {
-	u := info.codepoint
-	cat, pos := computeMyanmarProperties(u)
-	info.complexCategory = cat
-	info.complexAux = pos
+	return ret
 }
 }
 
 
 func (complexShaperMyanmar) marksBehavior() (zeroWidthMarks, bool) {
 func (complexShaperMyanmar) marksBehavior() (zeroWidthMarks, bool) {

+ 261 - 268
vendor/github.com/go-text/typesetting/harfbuzz/ot_myanmar_machine.go

@@ -7,300 +7,296 @@ package harfbuzz
 // myanmar_syllable_type_t
 // myanmar_syllable_type_t
 const (
 const (
 	myanmarConsonantSyllable = iota
 	myanmarConsonantSyllable = iota
-	myanmarPunctuationCluster
 	myanmarBrokenCluster
 	myanmarBrokenCluster
 	myanmarNonMyanmarCluster
 	myanmarNonMyanmarCluster
 )
 )
 
 
-const myanmarSyllableMachine_ex_A = 10
-const myanmarSyllableMachine_ex_As = 18
-const myanmarSyllableMachine_ex_C = 1
-const myanmarSyllableMachine_ex_CS = 19
-const myanmarSyllableMachine_ex_D = 32
-const myanmarSyllableMachine_ex_D0 = 20
-const myanmarSyllableMachine_ex_DB = 3
-const myanmarSyllableMachine_ex_GB = 11
-const myanmarSyllableMachine_ex_H = 4
-const myanmarSyllableMachine_ex_IV = 2
-const myanmarSyllableMachine_ex_MH = 21
-const myanmarSyllableMachine_ex_ML = 33
-const myanmarSyllableMachine_ex_MR = 22
-const myanmarSyllableMachine_ex_MW = 23
-const myanmarSyllableMachine_ex_MY = 24
-const myanmarSyllableMachine_ex_P = 31
-const myanmarSyllableMachine_ex_PT = 25
-const myanmarSyllableMachine_ex_Ra = 16
-const myanmarSyllableMachine_ex_V = 8
-const myanmarSyllableMachine_ex_VAbv = 26
-const myanmarSyllableMachine_ex_VBlw = 27
-const myanmarSyllableMachine_ex_VPre = 28
-const myanmarSyllableMachine_ex_VPst = 29
-const myanmarSyllableMachine_ex_VS = 30
-const myanmarSyllableMachine_ex_ZWJ = 6
-const myanmarSyllableMachine_ex_ZWNJ = 5
-
-var _myanmarSyllableMachine_actions []byte = []byte{
+const myaSM_ex_A = 9
+const myaSM_ex_As = 32
+const myaSM_ex_C = 1
+const myaSM_ex_CS = 18
+const myaSM_ex_DB = 3
+const myaSM_ex_DOTTEDCIRCLE = 11
+const myaSM_ex_GB = 10
+const myaSM_ex_H = 4
+const myaSM_ex_IV = 2
+const myaSM_ex_MH = 35
+const myaSM_ex_ML = 41
+const myaSM_ex_MR = 36
+const myaSM_ex_MW = 37
+const myaSM_ex_MY = 38
+const myaSM_ex_PT = 39
+const myaSM_ex_Ra = 15
+const myaSM_ex_SM = 8
+const myaSM_ex_VAbv = 20
+const myaSM_ex_VBlw = 21
+const myaSM_ex_VPre = 22
+const myaSM_ex_VPst = 23
+const myaSM_ex_VS = 40
+const myaSM_ex_ZWJ = 6
+const myaSM_ex_ZWNJ = 5
+
+var _myaSM_actions []byte = []byte{
 	0, 1, 0, 1, 1, 1, 2, 1, 3,
 	0, 1, 0, 1, 1, 1, 2, 1, 3,
 	1, 4, 1, 5, 1, 6, 1, 7,
 	1, 4, 1, 5, 1, 6, 1, 7,
-	1, 8, 1, 9,
+	1, 8,
 }
 }
 
 
-var _myanmarSyllableMachine_key_offsets []int16 = []int16{
-	0, 25, 43, 49, 52, 57, 64, 69,
-	73, 84, 91, 100, 108, 118, 121, 137,
-	149, 159, 168, 176, 187, 198, 211, 224,
-	239, 253, 270, 276, 279, 284, 291, 296,
-	300, 311, 318, 327, 335, 345, 348, 366,
-	382, 394, 404, 413, 421, 432, 443, 456,
-	469, 484, 498, 515, 533, 550, 573, 578,
+var _myaSM_key_offsets []int16 = []int16{
+	0, 24, 42, 48, 51, 62, 69, 76,
+	81, 85, 93, 102, 112, 117, 120, 129,
+	137, 148, 158, 174, 186, 197, 210, 223,
+	238, 252, 269, 275, 278, 289, 296, 303,
+	308, 312, 320, 329, 339, 344, 347, 365,
+	374, 382, 393, 403, 419, 431, 442, 455,
+	468, 483, 497, 514, 532, 549, 572,
 }
 }
 
 
-var _myanmarSyllableMachine_trans_keys []byte = []byte{
-	3, 4, 8, 10, 11, 16, 18, 19,
-	21, 22, 23, 24, 25, 26, 27, 28,
-	29, 30, 31, 32, 33, 1, 2, 5,
-	6, 3, 4, 8, 10, 18, 21, 22,
-	23, 24, 25, 26, 27, 28, 29, 30,
-	33, 5, 6, 8, 18, 25, 29, 5,
-	6, 8, 5, 6, 8, 25, 29, 5,
-	6, 3, 8, 10, 18, 25, 5, 6,
-	8, 18, 25, 5, 6, 8, 25, 5,
-	6, 3, 8, 10, 18, 21, 25, 26,
-	29, 33, 5, 6, 3, 8, 10, 25,
-	29, 5, 6, 3, 8, 10, 18, 25,
-	26, 29, 5, 6, 3, 8, 10, 25,
-	26, 29, 5, 6, 3, 8, 10, 18,
-	25, 26, 29, 33, 5, 6, 16, 1,
-	2, 3, 8, 10, 18, 21, 22, 23,
-	24, 25, 26, 27, 28, 29, 33, 5,
-	6, 3, 8, 10, 18, 25, 26, 27,
-	28, 29, 33, 5, 6, 3, 8, 10,
-	25, 26, 27, 28, 29, 5, 6, 3,
-	8, 10, 25, 26, 27, 29, 5, 6,
-	3, 8, 10, 25, 27, 29, 5, 6,
-	3, 8, 10, 25, 26, 27, 28, 29,
-	30, 5, 6, 3, 8, 10, 18, 25,
-	26, 27, 28, 29, 5, 6, 3, 8,
-	10, 21, 23, 25, 26, 27, 28, 29,
-	33, 5, 6, 3, 8, 10, 18, 21,
-	25, 26, 27, 28, 29, 33, 5, 6,
-	3, 8, 10, 18, 21, 22, 23, 25,
-	26, 27, 28, 29, 33, 5, 6, 3,
-	8, 10, 21, 22, 23, 25, 26, 27,
-	28, 29, 33, 5, 6, 3, 4, 8,
-	10, 18, 21, 22, 23, 24, 25, 26,
-	27, 28, 29, 33, 5, 6, 8, 18,
-	25, 29, 5, 6, 8, 5, 6, 8,
-	25, 29, 5, 6, 3, 8, 10, 18,
-	25, 5, 6, 8, 18, 25, 5, 6,
-	8, 25, 5, 6, 3, 8, 10, 18,
-	21, 25, 26, 29, 33, 5, 6, 3,
-	8, 10, 25, 29, 5, 6, 3, 8,
-	10, 18, 25, 26, 29, 5, 6, 3,
-	8, 10, 25, 26, 29, 5, 6, 3,
-	8, 10, 18, 25, 26, 29, 33, 5,
-	6, 16, 1, 2, 3, 4, 8, 10,
-	18, 21, 22, 23, 24, 25, 26, 27,
-	28, 29, 30, 33, 5, 6, 3, 8,
-	10, 18, 21, 22, 23, 24, 25, 26,
-	27, 28, 29, 33, 5, 6, 3, 8,
-	10, 18, 25, 26, 27, 28, 29, 33,
-	5, 6, 3, 8, 10, 25, 26, 27,
-	28, 29, 5, 6, 3, 8, 10, 25,
-	26, 27, 29, 5, 6, 3, 8, 10,
-	25, 27, 29, 5, 6, 3, 8, 10,
-	25, 26, 27, 28, 29, 30, 5, 6,
-	3, 8, 10, 18, 25, 26, 27, 28,
-	29, 5, 6, 3, 8, 10, 21, 23,
-	25, 26, 27, 28, 29, 33, 5, 6,
-	3, 8, 10, 18, 21, 25, 26, 27,
-	28, 29, 33, 5, 6, 3, 8, 10,
-	18, 21, 22, 23, 25, 26, 27, 28,
-	29, 33, 5, 6, 3, 8, 10, 21,
-	22, 23, 25, 26, 27, 28, 29, 33,
-	5, 6, 3, 4, 8, 10, 18, 21,
-	22, 23, 24, 25, 26, 27, 28, 29,
-	33, 5, 6, 3, 4, 8, 10, 18,
-	21, 22, 23, 24, 25, 26, 27, 28,
-	29, 30, 33, 5, 6, 3, 4, 8,
-	10, 18, 21, 22, 23, 24, 25, 26,
-	27, 28, 29, 33, 5, 6, 3, 4,
-	8, 10, 11, 16, 18, 21, 22, 23,
-	24, 25, 26, 27, 28, 29, 30, 32,
-	33, 1, 2, 5, 6, 11, 16, 32,
-	1, 2, 8,
+var _myaSM_trans_keys []byte = []byte{
+	3, 4, 8, 9, 15, 18, 20, 21,
+	22, 23, 32, 35, 36, 37, 38, 39,
+	40, 41, 1, 2, 5, 6, 10, 11,
+	3, 4, 8, 9, 20, 21, 22, 23,
+	32, 35, 36, 37, 38, 39, 40, 41,
+	5, 6, 8, 23, 32, 39, 5, 6,
+	8, 5, 6, 3, 8, 9, 20, 23,
+	32, 35, 39, 41, 5, 6, 3, 8,
+	9, 23, 39, 5, 6, 3, 8, 9,
+	32, 39, 5, 6, 8, 32, 39, 5,
+	6, 8, 39, 5, 6, 3, 8, 9,
+	20, 23, 39, 5, 6, 3, 8, 9,
+	20, 23, 32, 39, 5, 6, 3, 8,
+	9, 20, 23, 32, 39, 41, 5, 6,
+	8, 23, 39, 5, 6, 15, 1, 2,
+	3, 8, 9, 20, 21, 23, 39, 5,
+	6, 3, 8, 9, 21, 23, 39, 5,
+	6, 3, 8, 9, 20, 21, 22, 23,
+	39, 40, 5, 6, 3, 8, 9, 20,
+	21, 22, 23, 39, 5, 6, 3, 8,
+	9, 20, 21, 22, 23, 32, 35, 36,
+	37, 38, 39, 41, 5, 6, 3, 8,
+	9, 20, 21, 22, 23, 32, 39, 41,
+	5, 6, 3, 8, 9, 20, 21, 22,
+	23, 32, 39, 5, 6, 3, 8, 9,
+	20, 21, 22, 23, 35, 37, 39, 41,
+	5, 6, 3, 8, 9, 20, 21, 22,
+	23, 32, 35, 39, 41, 5, 6, 3,
+	8, 9, 20, 21, 22, 23, 32, 35,
+	36, 37, 39, 41, 5, 6, 3, 8,
+	9, 20, 21, 22, 23, 35, 36, 37,
+	39, 41, 5, 6, 3, 4, 8, 9,
+	20, 21, 22, 23, 32, 35, 36, 37,
+	38, 39, 41, 5, 6, 8, 23, 32,
+	39, 5, 6, 8, 5, 6, 3, 8,
+	9, 20, 23, 32, 35, 39, 41, 5,
+	6, 3, 8, 9, 23, 39, 5, 6,
+	3, 8, 9, 32, 39, 5, 6, 8,
+	32, 39, 5, 6, 8, 39, 5, 6,
+	3, 8, 9, 20, 23, 39, 5, 6,
+	3, 8, 9, 20, 23, 32, 39, 5,
+	6, 3, 8, 9, 20, 23, 32, 39,
+	41, 5, 6, 8, 23, 39, 5, 6,
+	15, 1, 2, 3, 4, 8, 9, 20,
+	21, 22, 23, 32, 35, 36, 37, 38,
+	39, 40, 41, 5, 6, 3, 8, 9,
+	20, 21, 23, 39, 5, 6, 3, 8,
+	9, 21, 23, 39, 5, 6, 3, 8,
+	9, 20, 21, 22, 23, 39, 40, 5,
+	6, 3, 8, 9, 20, 21, 22, 23,
+	39, 5, 6, 3, 8, 9, 20, 21,
+	22, 23, 32, 35, 36, 37, 38, 39,
+	41, 5, 6, 3, 8, 9, 20, 21,
+	22, 23, 32, 39, 41, 5, 6, 3,
+	8, 9, 20, 21, 22, 23, 32, 39,
+	5, 6, 3, 8, 9, 20, 21, 22,
+	23, 35, 37, 39, 41, 5, 6, 3,
+	8, 9, 20, 21, 22, 23, 32, 35,
+	39, 41, 5, 6, 3, 8, 9, 20,
+	21, 22, 23, 32, 35, 36, 37, 39,
+	41, 5, 6, 3, 8, 9, 20, 21,
+	22, 23, 35, 36, 37, 39, 41, 5,
+	6, 3, 4, 8, 9, 20, 21, 22,
+	23, 32, 35, 36, 37, 38, 39, 41,
+	5, 6, 3, 4, 8, 9, 20, 21,
+	22, 23, 32, 35, 36, 37, 38, 39,
+	40, 41, 5, 6, 3, 4, 8, 9,
+	20, 21, 22, 23, 32, 35, 36, 37,
+	38, 39, 41, 5, 6, 3, 4, 8,
+	9, 15, 20, 21, 22, 23, 32, 35,
+	36, 37, 38, 39, 40, 41, 1, 2,
+	5, 6, 10, 11, 15, 1, 2, 10,
+	11,
 }
 }
 
 
-var _myanmarSyllableMachine_single_lengths []byte = []byte{
-	21, 16, 4, 1, 3, 5, 3, 2,
-	9, 5, 7, 6, 8, 1, 14, 10,
-	8, 7, 6, 9, 9, 11, 11, 13,
-	12, 15, 4, 1, 3, 5, 3, 2,
-	9, 5, 7, 6, 8, 1, 16, 14,
-	10, 8, 7, 6, 9, 9, 11, 11,
-	13, 12, 15, 16, 15, 19, 3, 1,
+var _myaSM_single_lengths []byte = []byte{
+	18, 16, 4, 1, 9, 5, 5, 3,
+	2, 6, 7, 8, 3, 1, 7, 6,
+	9, 8, 14, 10, 9, 11, 11, 13,
+	12, 15, 4, 1, 9, 5, 5, 3,
+	2, 6, 7, 8, 3, 1, 16, 7,
+	6, 9, 8, 14, 10, 9, 11, 11,
+	13, 12, 15, 16, 15, 17, 1,
 }
 }
 
 
-var _myanmarSyllableMachine_range_lengths []byte = []byte{
-	2, 1, 1, 1, 1, 1, 1, 1,
+var _myaSM_range_lengths []byte = []byte{
+	3, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
 	1, 1, 1, 1, 1, 1, 1, 1,
-	1, 1, 1, 1, 1, 2, 1, 0,
+	1, 1, 1, 1, 1, 3, 2,
 }
 }
 
 
-var _myanmarSyllableMachine_index_offsets []int16 = []int16{
-	0, 24, 42, 48, 51, 56, 63, 68,
-	72, 83, 90, 99, 107, 117, 120, 136,
-	148, 158, 167, 175, 186, 197, 210, 223,
-	238, 252, 269, 275, 278, 283, 290, 295,
-	299, 310, 317, 326, 334, 344, 347, 365,
-	381, 393, 403, 412, 420, 431, 442, 455,
-	468, 483, 497, 514, 532, 549, 571, 576,
+var _myaSM_index_offsets []int16 = []int16{
+	0, 22, 40, 46, 49, 60, 67, 74,
+	79, 83, 91, 100, 110, 115, 118, 127,
+	135, 146, 156, 172, 184, 195, 208, 221,
+	236, 250, 267, 273, 276, 287, 294, 301,
+	306, 310, 318, 327, 337, 342, 345, 363,
+	372, 380, 391, 401, 417, 429, 440, 453,
+	466, 481, 495, 512, 530, 547, 568,
 }
 }
 
 
-var _myanmarSyllableMachine_indicies []byte = []byte{
-	2, 3, 5, 6, 1, 7, 8, 9,
-	10, 11, 12, 13, 14, 15, 16, 17,
-	18, 19, 20, 1, 21, 1, 4, 0,
-	23, 24, 26, 27, 28, 29, 30, 31,
-	32, 33, 34, 35, 36, 37, 38, 39,
-	25, 22, 26, 40, 33, 37, 25, 22,
-	26, 25, 22, 26, 33, 37, 25, 22,
-	41, 26, 33, 42, 33, 25, 22, 26,
-	42, 33, 25, 22, 26, 33, 25, 22,
-	23, 26, 27, 43, 44, 33, 45, 37,
-	43, 25, 22, 23, 26, 27, 33, 37,
-	25, 22, 23, 26, 27, 43, 33, 45,
-	37, 25, 22, 23, 26, 27, 33, 45,
-	37, 25, 22, 23, 26, 27, 43, 33,
-	45, 37, 43, 25, 22, 1, 1, 22,
-	23, 26, 27, 28, 29, 30, 31, 32,
-	33, 34, 35, 36, 37, 39, 25, 22,
-	23, 26, 27, 46, 33, 34, 35, 36,
-	37, 39, 25, 22, 23, 26, 27, 33,
-	34, 35, 36, 37, 25, 22, 23, 26,
-	27, 33, 34, 35, 37, 25, 22, 23,
-	26, 27, 33, 35, 37, 25, 22, 23,
-	26, 27, 33, 34, 35, 36, 37, 46,
-	25, 22, 23, 26, 27, 46, 33, 34,
-	35, 36, 37, 25, 22, 23, 26, 27,
-	29, 31, 33, 34, 35, 36, 37, 39,
-	25, 22, 23, 26, 27, 46, 29, 33,
-	34, 35, 36, 37, 39, 25, 22, 23,
-	26, 27, 47, 29, 30, 31, 33, 34,
-	35, 36, 37, 39, 25, 22, 23, 26,
-	27, 29, 30, 31, 33, 34, 35, 36,
-	37, 39, 25, 22, 23, 24, 26, 27,
+var _myaSM_indicies []byte = []byte{
+	2, 3, 5, 6, 7, 8, 9, 10,
+	11, 12, 13, 14, 15, 16, 17, 18,
+	19, 20, 1, 4, 1, 0, 22, 23,
+	25, 26, 27, 28, 29, 30, 31, 32,
+	33, 34, 35, 36, 37, 38, 24, 21,
+	25, 30, 39, 36, 24, 21, 25, 24,
+	21, 22, 25, 26, 40, 30, 41, 42,
+	36, 41, 24, 21, 22, 25, 26, 30,
+	36, 24, 21, 43, 25, 36, 44, 36,
+	24, 21, 25, 44, 36, 24, 21, 25,
+	36, 24, 21, 22, 25, 26, 40, 30,
+	36, 24, 21, 22, 25, 26, 40, 30,
+	41, 36, 24, 21, 22, 25, 26, 40,
+	30, 41, 36, 41, 24, 21, 25, 30,
+	36, 24, 21, 1, 1, 21, 22, 25,
+	26, 27, 28, 30, 36, 24, 21, 22,
+	25, 26, 28, 30, 36, 24, 21, 22,
+	25, 26, 27, 28, 29, 30, 36, 45,
+	24, 21, 22, 25, 26, 27, 28, 29,
+	30, 36, 24, 21, 22, 25, 26, 27,
 	28, 29, 30, 31, 32, 33, 34, 35,
 	28, 29, 30, 31, 32, 33, 34, 35,
-	36, 37, 39, 25, 22, 5, 50, 14,
-	18, 49, 48, 5, 49, 48, 5, 14,
-	18, 49, 48, 51, 5, 14, 52, 14,
-	49, 48, 5, 52, 14, 49, 48, 5,
-	14, 49, 48, 2, 5, 6, 53, 54,
-	14, 55, 18, 53, 49, 48, 2, 5,
-	6, 14, 18, 49, 48, 2, 5, 6,
-	53, 14, 55, 18, 49, 48, 2, 5,
-	6, 14, 55, 18, 49, 48, 2, 5,
-	6, 53, 14, 55, 18, 53, 49, 48,
-	56, 56, 48, 2, 3, 5, 6, 8,
-	10, 11, 12, 13, 14, 15, 16, 17,
-	18, 19, 21, 49, 48, 2, 5, 6,
-	8, 10, 11, 12, 13, 14, 15, 16,
-	17, 18, 21, 49, 48, 2, 5, 6,
-	57, 14, 15, 16, 17, 18, 21, 49,
-	48, 2, 5, 6, 14, 15, 16, 17,
-	18, 49, 48, 2, 5, 6, 14, 15,
-	16, 18, 49, 48, 2, 5, 6, 14,
-	16, 18, 49, 48, 2, 5, 6, 14,
-	15, 16, 17, 18, 57, 49, 48, 2,
-	5, 6, 57, 14, 15, 16, 17, 18,
-	49, 48, 2, 5, 6, 10, 12, 14,
-	15, 16, 17, 18, 21, 49, 48, 2,
-	5, 6, 57, 10, 14, 15, 16, 17,
-	18, 21, 49, 48, 2, 5, 6, 58,
-	10, 11, 12, 14, 15, 16, 17, 18,
-	21, 49, 48, 2, 5, 6, 10, 11,
-	12, 14, 15, 16, 17, 18, 21, 49,
-	48, 2, 3, 5, 6, 8, 10, 11,
-	12, 13, 14, 15, 16, 17, 18, 21,
-	49, 48, 23, 24, 26, 27, 59, 29,
-	30, 31, 32, 33, 34, 35, 36, 37,
-	38, 39, 25, 22, 23, 60, 26, 27,
-	28, 29, 30, 31, 32, 33, 34, 35,
-	36, 37, 39, 25, 22, 2, 3, 5,
-	6, 1, 1, 8, 10, 11, 12, 13,
-	14, 15, 16, 17, 18, 19, 1, 21,
-	1, 49, 48, 1, 1, 1, 1, 61,
-	62, 61,
+	36, 38, 24, 21, 22, 25, 26, 27,
+	28, 29, 30, 45, 36, 38, 24, 21,
+	22, 25, 26, 27, 28, 29, 30, 45,
+	36, 24, 21, 22, 25, 26, 27, 28,
+	29, 30, 32, 34, 36, 38, 24, 21,
+	22, 25, 26, 27, 28, 29, 30, 45,
+	32, 36, 38, 24, 21, 22, 25, 26,
+	27, 28, 29, 30, 46, 32, 33, 34,
+	36, 38, 24, 21, 22, 25, 26, 27,
+	28, 29, 30, 32, 33, 34, 36, 38,
+	24, 21, 22, 23, 25, 26, 27, 28,
+	29, 30, 31, 32, 33, 34, 35, 36,
+	38, 24, 21, 5, 12, 49, 18, 48,
+	47, 5, 48, 47, 2, 5, 6, 50,
+	12, 51, 52, 18, 51, 48, 47, 2,
+	5, 6, 12, 18, 48, 47, 53, 5,
+	18, 54, 18, 48, 47, 5, 54, 18,
+	48, 47, 5, 18, 48, 47, 2, 5,
+	6, 50, 12, 18, 48, 47, 2, 5,
+	6, 50, 12, 51, 18, 48, 47, 2,
+	5, 6, 50, 12, 51, 18, 51, 48,
+	47, 5, 12, 18, 48, 47, 55, 55,
+	47, 2, 3, 5, 6, 9, 10, 11,
+	12, 13, 14, 15, 16, 17, 18, 19,
+	20, 48, 47, 2, 5, 6, 9, 10,
+	12, 18, 48, 47, 2, 5, 6, 10,
+	12, 18, 48, 47, 2, 5, 6, 9,
+	10, 11, 12, 18, 56, 48, 47, 2,
+	5, 6, 9, 10, 11, 12, 18, 48,
+	47, 2, 5, 6, 9, 10, 11, 12,
+	13, 14, 15, 16, 17, 18, 20, 48,
+	47, 2, 5, 6, 9, 10, 11, 12,
+	56, 18, 20, 48, 47, 2, 5, 6,
+	9, 10, 11, 12, 56, 18, 48, 47,
+	2, 5, 6, 9, 10, 11, 12, 14,
+	16, 18, 20, 48, 47, 2, 5, 6,
+	9, 10, 11, 12, 56, 14, 18, 20,
+	48, 47, 2, 5, 6, 9, 10, 11,
+	12, 57, 14, 15, 16, 18, 20, 48,
+	47, 2, 5, 6, 9, 10, 11, 12,
+	14, 15, 16, 18, 20, 48, 47, 2,
+	3, 5, 6, 9, 10, 11, 12, 13,
+	14, 15, 16, 17, 18, 20, 48, 47,
+	22, 23, 25, 26, 27, 28, 29, 30,
+	58, 32, 33, 34, 35, 36, 37, 38,
+	24, 21, 22, 59, 25, 26, 27, 28,
+	29, 30, 31, 32, 33, 34, 35, 36,
+	38, 24, 21, 2, 3, 5, 6, 1,
+	9, 10, 11, 12, 13, 14, 15, 16,
+	17, 18, 19, 20, 1, 48, 1, 47,
+	1, 1, 1, 60,
 }
 }
 
 
-var _myanmarSyllableMachine_trans_targs []byte = []byte{
-	0, 1, 26, 37, 0, 27, 33, 51,
-	39, 54, 40, 46, 47, 48, 29, 42,
-	43, 44, 32, 50, 55, 45, 0, 2,
-	13, 0, 3, 9, 14, 15, 21, 22,
-	23, 5, 17, 18, 19, 8, 25, 20,
-	4, 6, 7, 10, 12, 11, 16, 24,
-	0, 0, 28, 30, 31, 34, 36, 35,
-	38, 41, 49, 52, 53, 0, 0,
+var _myaSM_trans_targs []byte = []byte{
+	0, 1, 26, 37, 0, 27, 29, 51,
+	54, 39, 40, 41, 28, 43, 44, 46,
+	47, 48, 30, 50, 45, 0, 2, 13,
+	0, 3, 5, 14, 15, 16, 4, 18,
+	19, 21, 22, 23, 6, 25, 20, 12,
+	9, 10, 11, 7, 8, 17, 24, 0,
+	0, 36, 33, 34, 35, 31, 32, 38,
+	42, 49, 52, 53, 0,
 }
 }
 
 
-var _myanmarSyllableMachine_trans_actions []byte = []byte{
-	13, 0, 0, 0, 7, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 15, 0,
-	0, 5, 0, 0, 0, 0, 0, 0,
+var _myaSM_trans_actions []byte = []byte{
+	11, 0, 0, 0, 7, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 13, 0, 0,
+	5, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
-	17, 11, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 19, 9,
+	0, 0, 0, 0, 0, 0, 0, 15,
+	9, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 17,
 }
 }
 
 
-var _myanmarSyllableMachine_to_state_actions []byte = []byte{
+var _myaSM_to_state_actions []byte = []byte{
 	1, 0, 0, 0, 0, 0, 0, 0,
 	1, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0,
 }
 }
 
 
-var _myanmarSyllableMachine_from_state_actions []byte = []byte{
+var _myaSM_from_state_actions []byte = []byte{
 	3, 0, 0, 0, 0, 0, 0, 0,
 	3, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
 	0, 0, 0, 0, 0, 0, 0, 0,
-	0, 0, 0, 0, 0, 0, 0, 0,
+	0, 0, 0, 0, 0, 0, 0,
 }
 }
 
 
-var _myanmarSyllableMachine_eof_trans []int16 = []int16{
-	0, 23, 23, 23, 23, 23, 23, 23,
-	23, 23, 23, 23, 23, 23, 23, 23,
-	23, 23, 23, 23, 23, 23, 23, 23,
-	23, 23, 49, 49, 49, 49, 49, 49,
-	49, 49, 49, 49, 49, 49, 49, 49,
-	49, 49, 49, 49, 49, 49, 49, 49,
-	49, 49, 49, 23, 23, 49, 62, 62,
+var _myaSM_eof_trans []int16 = []int16{
+	0, 22, 22, 22, 22, 22, 22, 22,
+	22, 22, 22, 22, 22, 22, 22, 22,
+	22, 22, 22, 22, 22, 22, 22, 22,
+	22, 22, 48, 48, 48, 48, 48, 48,
+	48, 48, 48, 48, 48, 48, 48, 48,
+	48, 48, 48, 48, 48, 48, 48, 48,
+	48, 48, 48, 22, 22, 48, 61,
 }
 }
 
 
-const myanmarSyllableMachine_start int = 0
-const myanmarSyllableMachine_first_final int = 0
-const myanmarSyllableMachine_error int = -1
+const myaSM_start int = 0
+const myaSM_first_final int = 0
+const myaSM_error int = -1
 
 
-const myanmarSyllableMachine_en_main int = 0
+const myaSM_en_main int = 0
 
 
 func findSyllablesMyanmar(buffer *Buffer) {
 func findSyllablesMyanmar(buffer *Buffer) {
 	var p, ts, te, act, cs int
 	var p, ts, te, act, cs int
 	info := buffer.Info
 	info := buffer.Info
 
 
 	{
 	{
-		cs = myanmarSyllableMachine_start
+		cs = myaSM_start
 		ts = 0
 		ts = 0
 		te = 0
 		te = 0
 		act = 0
 		act = 0
@@ -321,22 +317,22 @@ func findSyllablesMyanmar(buffer *Buffer) {
 			goto _test_eof
 			goto _test_eof
 		}
 		}
 	_resume:
 	_resume:
-		_acts = int(_myanmarSyllableMachine_from_state_actions[cs])
-		_nacts = uint(_myanmarSyllableMachine_actions[_acts])
+		_acts = int(_myaSM_from_state_actions[cs])
+		_nacts = uint(_myaSM_actions[_acts])
 		_acts++
 		_acts++
 		for ; _nacts > 0; _nacts-- {
 		for ; _nacts > 0; _nacts-- {
 			_acts++
 			_acts++
-			switch _myanmarSyllableMachine_actions[_acts-1] {
+			switch _myaSM_actions[_acts-1] {
 			case 1:
 			case 1:
 				ts = p
 				ts = p
 
 
 			}
 			}
 		}
 		}
 
 
-		_keys = int(_myanmarSyllableMachine_key_offsets[cs])
-		_trans = int(_myanmarSyllableMachine_index_offsets[cs])
+		_keys = int(_myaSM_key_offsets[cs])
+		_trans = int(_myaSM_index_offsets[cs])
 
 
-		_klen = int(_myanmarSyllableMachine_single_lengths[cs])
+		_klen = int(_myaSM_single_lengths[cs])
 		if _klen > 0 {
 		if _klen > 0 {
 			_lower := int(_keys)
 			_lower := int(_keys)
 			var _mid int
 			var _mid int
@@ -348,9 +344,9 @@ func findSyllablesMyanmar(buffer *Buffer) {
 
 
 				_mid = _lower + ((_upper - _lower) >> 1)
 				_mid = _lower + ((_upper - _lower) >> 1)
 				switch {
 				switch {
-				case (info[p].complexCategory) < _myanmarSyllableMachine_trans_keys[_mid]:
+				case (info[p].complexCategory) < _myaSM_trans_keys[_mid]:
 					_upper = _mid - 1
 					_upper = _mid - 1
-				case (info[p].complexCategory) > _myanmarSyllableMachine_trans_keys[_mid]:
+				case (info[p].complexCategory) > _myaSM_trans_keys[_mid]:
 					_lower = _mid + 1
 					_lower = _mid + 1
 				default:
 				default:
 					_trans += int(_mid - int(_keys))
 					_trans += int(_mid - int(_keys))
@@ -361,7 +357,7 @@ func findSyllablesMyanmar(buffer *Buffer) {
 			_trans += _klen
 			_trans += _klen
 		}
 		}
 
 
-		_klen = int(_myanmarSyllableMachine_range_lengths[cs])
+		_klen = int(_myaSM_range_lengths[cs])
 		if _klen > 0 {
 		if _klen > 0 {
 			_lower := int(_keys)
 			_lower := int(_keys)
 			var _mid int
 			var _mid int
@@ -373,9 +369,9 @@ func findSyllablesMyanmar(buffer *Buffer) {
 
 
 				_mid = _lower + (((_upper - _lower) >> 1) & ^1)
 				_mid = _lower + (((_upper - _lower) >> 1) & ^1)
 				switch {
 				switch {
-				case (info[p].complexCategory) < _myanmarSyllableMachine_trans_keys[_mid]:
+				case (info[p].complexCategory) < _myaSM_trans_keys[_mid]:
 					_upper = _mid - 2
 					_upper = _mid - 2
-				case (info[p].complexCategory) > _myanmarSyllableMachine_trans_keys[_mid+1]:
+				case (info[p].complexCategory) > _myaSM_trans_keys[_mid+1]:
 					_lower = _mid + 2
 					_lower = _mid + 2
 				default:
 				default:
 					_trans += int((_mid - int(_keys)) >> 1)
 					_trans += int((_mid - int(_keys)) >> 1)
@@ -386,20 +382,20 @@ func findSyllablesMyanmar(buffer *Buffer) {
 		}
 		}
 
 
 	_match:
 	_match:
-		_trans = int(_myanmarSyllableMachine_indicies[_trans])
+		_trans = int(_myaSM_indicies[_trans])
 	_eof_trans:
 	_eof_trans:
-		cs = int(_myanmarSyllableMachine_trans_targs[_trans])
+		cs = int(_myaSM_trans_targs[_trans])
 
 
-		if _myanmarSyllableMachine_trans_actions[_trans] == 0 {
+		if _myaSM_trans_actions[_trans] == 0 {
 			goto _again
 			goto _again
 		}
 		}
 
 
-		_acts = int(_myanmarSyllableMachine_trans_actions[_trans])
-		_nacts = uint(_myanmarSyllableMachine_actions[_acts])
+		_acts = int(_myaSM_trans_actions[_trans])
+		_nacts = uint(_myaSM_actions[_acts])
 		_acts++
 		_acts++
 		for ; _nacts > 0; _nacts-- {
 		for ; _nacts > 0; _nacts-- {
 			_acts++
 			_acts++
-			switch _myanmarSyllableMachine_actions[_acts-1] {
+			switch _myaSM_actions[_acts-1] {
 			case 2:
 			case 2:
 				te = p + 1
 				te = p + 1
 				{
 				{
@@ -411,33 +407,30 @@ func findSyllablesMyanmar(buffer *Buffer) {
 					foundSyllableMyanmar(myanmarNonMyanmarCluster, ts, te, info, &syllableSerial)
 					foundSyllableMyanmar(myanmarNonMyanmarCluster, ts, te, info, &syllableSerial)
 				}
 				}
 			case 4:
 			case 4:
-				te = p + 1
-				{
-					foundSyllableMyanmar(myanmarPunctuationCluster, ts, te, info, &syllableSerial)
-				}
-			case 5:
 				te = p + 1
 				te = p + 1
 				{
 				{
 					foundSyllableMyanmar(myanmarBrokenCluster, ts, te, info, &syllableSerial)
 					foundSyllableMyanmar(myanmarBrokenCluster, ts, te, info, &syllableSerial)
+					buffer.scratchFlags |= bsfHasBrokenSyllable
 				}
 				}
-			case 6:
+			case 5:
 				te = p + 1
 				te = p + 1
 				{
 				{
 					foundSyllableMyanmar(myanmarNonMyanmarCluster, ts, te, info, &syllableSerial)
 					foundSyllableMyanmar(myanmarNonMyanmarCluster, ts, te, info, &syllableSerial)
 				}
 				}
-			case 7:
+			case 6:
 				te = p
 				te = p
 				p--
 				p--
 				{
 				{
 					foundSyllableMyanmar(myanmarConsonantSyllable, ts, te, info, &syllableSerial)
 					foundSyllableMyanmar(myanmarConsonantSyllable, ts, te, info, &syllableSerial)
 				}
 				}
-			case 8:
+			case 7:
 				te = p
 				te = p
 				p--
 				p--
 				{
 				{
 					foundSyllableMyanmar(myanmarBrokenCluster, ts, te, info, &syllableSerial)
 					foundSyllableMyanmar(myanmarBrokenCluster, ts, te, info, &syllableSerial)
+					buffer.scratchFlags |= bsfHasBrokenSyllable
 				}
 				}
-			case 9:
+			case 8:
 				te = p
 				te = p
 				p--
 				p--
 				{
 				{
@@ -447,12 +440,12 @@ func findSyllablesMyanmar(buffer *Buffer) {
 		}
 		}
 
 
 	_again:
 	_again:
-		_acts = int(_myanmarSyllableMachine_to_state_actions[cs])
-		_nacts = uint(_myanmarSyllableMachine_actions[_acts])
+		_acts = int(_myaSM_to_state_actions[cs])
+		_nacts = uint(_myaSM_actions[_acts])
 		_acts++
 		_acts++
 		for ; _nacts > 0; _nacts-- {
 		for ; _nacts > 0; _nacts-- {
 			_acts++
 			_acts++
-			switch _myanmarSyllableMachine_actions[_acts-1] {
+			switch _myaSM_actions[_acts-1] {
 			case 0:
 			case 0:
 				ts = 0
 				ts = 0
 
 
@@ -467,8 +460,8 @@ func findSyllablesMyanmar(buffer *Buffer) {
 		{
 		{
 		}
 		}
 		if p == eof {
 		if p == eof {
-			if _myanmarSyllableMachine_eof_trans[cs] > 0 {
-				_trans = int(_myanmarSyllableMachine_eof_trans[cs] - 1)
+			if _myaSM_eof_trans[cs] > 0 {
+				_trans = int(_myaSM_eof_trans[cs] - 1)
 				goto _eof_trans
 				goto _eof_trans
 			}
 			}
 		}
 		}

+ 31 - 30
vendor/github.com/go-text/typesetting/harfbuzz/ot_myanmar_machine.rl

@@ -7,13 +7,12 @@ package harfbuzz
 // myanmar_syllable_type_t
 // myanmar_syllable_type_t
 const  (
 const  (
   myanmarConsonantSyllable = iota
   myanmarConsonantSyllable = iota
-  myanmarPunctuationCluster
   myanmarBrokenCluster
   myanmarBrokenCluster
   myanmarNonMyanmarCluster
   myanmarNonMyanmarCluster
 )
 )
 
 
 %%{
 %%{
-  machine myanmarSyllableMachine;
+  machine myaSM;
   alphtype byte;
   alphtype byte;
   write exports;
   write exports;
   write data;
   write data;
@@ -21,32 +20,36 @@ const  (
 
 
 %%{
 %%{
 
 
-export A    = 10;
-export As   = 18;
+# Spec category D is folded into GB; D0 is not implemented by Uniscribe and as such folded into D
+# Spec category P is folded into GB
+
 export C    = 1;
 export C    = 1;
-export D    = 32;
-export D0   = 20;
-export DB   = 3;
-export GB   = 11;
-export H    = 4;
 export IV   = 2;
 export IV   = 2;
-export MH   = 21;
-export ML   = 33;
-export MR   = 22;
-export MW   = 23;
-export MY   = 24;
-export PT   = 25;
-export V    = 8;
-export VAbv = 26;
-export VBlw = 27;
-export VPre = 28;
-export VPst = 29;
-export VS   = 30;
-export ZWJ  = 6;
+export DB   = 3;	# Dot below	     = OT_N
+export H    = 4;
 export ZWNJ = 5;
 export ZWNJ = 5;
-export Ra   = 16;
-export P    = 31;
-export CS   = 19;
+export ZWJ  = 6;
+export SM    = 8;	# Visarga and Shan tones
+export GB   = 10;	# 		     = OT_PLACEHOLDER
+export DOTTEDCIRCLE = 11;
+export A    = 9;
+export Ra   = 15;
+export CS   = 18;
+
+export VAbv = 20;
+export VBlw = 21;
+export VPre = 22;
+export VPst = 23;
+
+# 32+ are for Myanmar-specific values
+export As   = 32;	# Asat
+export MH   = 35;	# Medial Ha
+export MR   = 36;	# Medial Ra
+export MW   = 37;	# Medial Wa, Shan Wa
+export MY   = 38;	# Medial Ya, Mon Na, Mon Ma
+export PT   = 39;	# Pwo and other tones
+export VS   = 40;	# Variation selectors
+export ML   = 41;	# Medial Mon La
 
 
 j = ZWJ|ZWNJ;			# Joiners
 j = ZWJ|ZWNJ;			# Joiners
 k = (Ra As H);			# Kinzi
 k = (Ra As H);			# Kinzi
@@ -58,19 +61,17 @@ main_vowel_group = (VPre.VS?)* VAbv* VBlw* A* (DB As?)?;
 post_vowel_group = VPst MH? ML? As* VAbv* A* (DB As?)?;
 post_vowel_group = VPst MH? ML? As* VAbv* A* (DB As?)?;
 pwo_tone_group = PT A* DB? As?;
 pwo_tone_group = PT A* DB? As?;
 
 
-complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* V* j?;
+complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* SM* j?;
 syllable_tail = (H (c|IV).VS?)* (H | complex_syllable_tail);
 syllable_tail = (H (c|IV).VS?)* (H | complex_syllable_tail);
 
 
-consonant_syllable =	(k|CS)? (c|IV|D|GB).VS? syllable_tail;
-punctuation_cluster =	P V;
+consonant_syllable =	(k|CS)? (c|IV|GB|DOTTEDCIRCLE).VS? syllable_tail;
 broken_cluster =	k? VS? syllable_tail;
 broken_cluster =	k? VS? syllable_tail;
 other =			any;
 other =			any;
 
 
 main := |*
 main := |*
 	consonant_syllable	=> { foundSyllableMyanmar (myanmarConsonantSyllable, ts, te, info, &syllableSerial); };
 	consonant_syllable	=> { foundSyllableMyanmar (myanmarConsonantSyllable, ts, te, info, &syllableSerial); };
 	j			=> { foundSyllableMyanmar (myanmarNonMyanmarCluster, ts, te, info, &syllableSerial); };
 	j			=> { foundSyllableMyanmar (myanmarNonMyanmarCluster, ts, te, info, &syllableSerial); };
-	punctuation_cluster	=> { foundSyllableMyanmar (myanmarPunctuationCluster, ts, te, info, &syllableSerial); };
-	broken_cluster		=> { foundSyllableMyanmar (myanmarBrokenCluster, ts, te, info, &syllableSerial); };
+	broken_cluster		=> { foundSyllableMyanmar (myanmarBrokenCluster, ts, te, info, &syllableSerial); buffer.scratchFlags |= bsfHasBrokenSyllable };
 	other			=> { foundSyllableMyanmar (myanmarNonMyanmarCluster, ts, te, info, &syllableSerial); };
 	other			=> { foundSyllableMyanmar (myanmarNonMyanmarCluster, ts, te, info, &syllableSerial); };
 *|;
 *|;
 
 

+ 8 - 15
vendor/github.com/go-text/typesetting/harfbuzz/ot_shape_complex.go

@@ -80,7 +80,7 @@ func (planner *otShapePlanner) categorizeComplex() otComplexShaper {
 	case language.Hebrew:
 	case language.Hebrew:
 		return complexShaperHebrew{}
 		return complexShaperHebrew{}
 	case language.Bengali, language.Devanagari, language.Gujarati, language.Gurmukhi, language.Kannada,
 	case language.Bengali, language.Devanagari, language.Gujarati, language.Gurmukhi, language.Kannada,
-		language.Malayalam, language.Oriya, language.Tamil, language.Telugu, language.Sinhala:
+		language.Malayalam, language.Oriya, language.Tamil, language.Telugu:
 		/* If the designer designed the font for the 'DFLT' script,
 		/* If the designer designed the font for the 'DFLT' script,
 		 * (or we ended up arbitrarily pick 'latn'), use the default shaper.
 		 * (or we ended up arbitrarily pick 'latn'), use the default shaper.
 		 * Otherwise, use the specific shaper.
 		 * Otherwise, use the specific shaper.
@@ -116,7 +116,7 @@ func (planner *otShapePlanner) categorizeComplex() otComplexShaper {
 		 * https://github.com/harfbuzz/harfbuzz/issues/1162 */
 		 * https://github.com/harfbuzz/harfbuzz/issues/1162 */
 		return complexShaperDefault{dumb: true, disableNorm: true}
 		return complexShaperDefault{dumb: true, disableNorm: true}
 	case language.Tibetan,
 	case language.Tibetan,
-		language.Mongolian,
+		language.Mongolian, language.Sinhala,
 		language.Buhid, language.Hanunoo, language.Tagalog, language.Tagbanwa,
 		language.Buhid, language.Hanunoo, language.Tagalog, language.Tagbanwa,
 		language.Limbu, language.Tai_Le,
 		language.Limbu, language.Tai_Le,
 		language.Buginese, language.Kharoshthi, language.Syloti_Nagri, language.Tifinagh,
 		language.Buginese, language.Kharoshthi, language.Syloti_Nagri, language.Tifinagh,
@@ -196,26 +196,18 @@ func (cs complexShaperDefault) normalizationPreference() normalizationMode {
 
 
 func syllabicInsertDottedCircles(font *Font, buffer *Buffer, brokenSyllableType,
 func syllabicInsertDottedCircles(font *Font, buffer *Buffer, brokenSyllableType,
 	dottedcircleCategory uint8, rephaCategory, dottedCirclePosition int,
 	dottedcircleCategory uint8, rephaCategory, dottedCirclePosition int,
-) {
+) bool {
 	if (buffer.Flags & DoNotinsertDottedCircle) != 0 {
 	if (buffer.Flags & DoNotinsertDottedCircle) != 0 {
-		return
+		return false
 	}
 	}
 
 
-	hasBrokenSyllables := false
-	info := buffer.Info
-	for _, inf := range info {
-		if (inf.syllable & 0x0F) == brokenSyllableType {
-			hasBrokenSyllables = true
-			break
-		}
-	}
-	if !hasBrokenSyllables {
-		return
+	if (buffer.scratchFlags & bsfHasBrokenSyllable) == 0 {
+		return false
 	}
 	}
 
 
 	dottedcircleGlyph, ok := font.face.NominalGlyph(0x25CC)
 	dottedcircleGlyph, ok := font.face.NominalGlyph(0x25CC)
 	if !ok {
 	if !ok {
-		return
+		return false
 	}
 	}
 
 
 	dottedcircle := GlyphInfo{
 	dottedcircle := GlyphInfo{
@@ -255,4 +247,5 @@ func syllabicInsertDottedCircles(font *Font, buffer *Buffer, brokenSyllableType,
 		}
 		}
 	}
 	}
 	buffer.swapBuffers()
 	buffer.swapBuffers()
+	return true
 }
 }

+ 18 - 5
vendor/github.com/go-text/typesetting/harfbuzz/ot_shape_fallback.go

@@ -150,7 +150,8 @@ func zeroMarkAdvances(buffer *Buffer, start, end int, adjustOffsetsWhenZeroing b
 }
 }
 
 
 func positionMark(font *Font, buffer *Buffer, baseExtents *GlyphExtents,
 func positionMark(font *Font, buffer *Buffer, baseExtents *GlyphExtents,
-	i int, combiningClass uint8) {
+	i int, combiningClass uint8,
+) {
 	markExtents, ok := font.GlyphExtents(buffer.Info[i].Glyph)
 	markExtents, ok := font.GlyphExtents(buffer.Info[i].Glyph)
 	if !ok {
 	if !ok {
 		return
 		return
@@ -225,7 +226,8 @@ func positionMark(font *Font, buffer *Buffer, baseExtents *GlyphExtents,
 }
 }
 
 
 func positionAroundBase(plan *otShapePlan, font *Font, buffer *Buffer,
 func positionAroundBase(plan *otShapePlan, font *Font, buffer *Buffer,
-	base, end int, adjustOffsetsWhenZeroing bool) {
+	base, end int, adjustOffsetsWhenZeroing bool,
+) {
 	buffer.unsafeToBreak(base, end)
 	buffer.unsafeToBreak(base, end)
 
 
 	baseExtents, ok := font.GlyphExtents(buffer.Info[base].Glyph)
 	baseExtents, ok := font.GlyphExtents(buffer.Info[base].Glyph)
@@ -312,7 +314,8 @@ func positionAroundBase(plan *otShapePlan, font *Font, buffer *Buffer,
 }
 }
 
 
 func positionCluster(plan *otShapePlan, font *Font, buffer *Buffer,
 func positionCluster(plan *otShapePlan, font *Font, buffer *Buffer,
-	start, end int, adjustOffsetsWhenZeroing bool) {
+	start, end int, adjustOffsetsWhenZeroing bool,
+) {
 	if end-start < 2 {
 	if end-start < 2 {
 		return
 		return
 	}
 	}
@@ -337,7 +340,8 @@ func positionCluster(plan *otShapePlan, font *Font, buffer *Buffer,
 }
 }
 
 
 func fallbackMarkPosition(plan *otShapePlan, font *Font, buffer *Buffer,
 func fallbackMarkPosition(plan *otShapePlan, font *Font, buffer *Buffer,
-	adjustOffsetsWhenZeroing bool) {
+	adjustOffsetsWhenZeroing bool,
+) {
 	var start int
 	var start int
 	info := buffer.Info
 	info := buffer.Info
 	for i := 1; i < len(info); i++ {
 	for i := 1; i < len(info); i++ {
@@ -351,7 +355,7 @@ func fallbackMarkPosition(plan *otShapePlan, font *Font, buffer *Buffer,
 
 
 // adjusts width of various spaces.
 // adjusts width of various spaces.
 func fallbackSpaces(font *Font, buffer *Buffer) {
 func fallbackSpaces(font *Font, buffer *Buffer) {
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("POSITION - applying fallback spaces")
 		fmt.Println("POSITION - applying fallback spaces")
 	}
 	}
 	info := buffer.Info
 	info := buffer.Info
@@ -362,6 +366,15 @@ func fallbackSpaces(font *Font, buffer *Buffer) {
 			continue
 			continue
 		}
 		}
 
 
+		// If font had no ASCII space and we used the invisible glyph, give it a 1/4 EM default advance.
+		if buffer.Invisible != 0 && info[i].Glyph == buffer.Invisible {
+			if horizontal {
+				pos[i].XAdvance = +font.XScale / 4
+			} else {
+				pos[i].YAdvance = -font.YScale / 4
+			}
+		}
+
 		spaceType := inf.getUnicodeSpaceFallbackType()
 		spaceType := inf.getUnicodeSpaceFallbackType()
 
 
 		switch spaceType {
 		switch spaceType {

+ 10 - 6
vendor/github.com/go-text/typesetting/harfbuzz/ot_shape_normalize.go

@@ -152,7 +152,10 @@ func (c *otNormalizeContext) decomposeCurrentCharacter(shortest bool) {
 
 
 	if buffer.cur(0).isUnicodeSpace() {
 	if buffer.cur(0).isUnicodeSpace() {
 		spaceType := uni.spaceFallbackType(u)
 		spaceType := uni.spaceFallbackType(u)
-		if spaceGlyph, ok := c.font.face.NominalGlyph(0x0020); spaceType != notSpace && ok {
+		if spaceGlyph, ok := c.font.face.NominalGlyph(0x0020); spaceType != notSpace && (ok || buffer.Invisible != 0) {
+			if !ok {
+				spaceGlyph = buffer.Invisible
+			}
 			buffer.cur(0).setUnicodeSpaceFallbackType(spaceType)
 			buffer.cur(0).setUnicodeSpaceFallbackType(spaceType)
 			nextChar(buffer, spaceGlyph)
 			nextChar(buffer, spaceGlyph)
 			buffer.scratchFlags |= bsfHasSpaceFallback
 			buffer.scratchFlags |= bsfHasSpaceFallback
@@ -173,8 +176,9 @@ func (c *otNormalizeContext) decomposeCurrentCharacter(shortest bool) {
 }
 }
 
 
 func (c *otNormalizeContext) handleVariationSelectorCluster(end int) {
 func (c *otNormalizeContext) handleVariationSelectorCluster(end int) {
+	/* Currently if there's a variation-selector we give-up on normalization, it's just too hard. */
 	buffer := c.buffer
 	buffer := c.buffer
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Printf("NORMALIZE - variation selector cluster at index %d\n", buffer.idx)
 		fmt.Printf("NORMALIZE - variation selector cluster at index %d\n", buffer.idx)
 	}
 	}
 	font := c.font
 	font := c.font
@@ -210,7 +214,7 @@ func (c *otNormalizeContext) handleVariationSelectorCluster(end int) {
 
 
 func (c *otNormalizeContext) decomposeMultiCharCluster(end int, shortCircuit bool) {
 func (c *otNormalizeContext) decomposeMultiCharCluster(end int, shortCircuit bool) {
 	buffer := c.buffer
 	buffer := c.buffer
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Printf("NORMALIZE - decompose multi char cluster at index %d\n", buffer.idx)
 		fmt.Printf("NORMALIZE - decompose multi char cluster at index %d\n", buffer.idx)
 	}
 	}
 
 
@@ -325,7 +329,7 @@ func otShapeNormalize(plan *otShapePlan, buffer *Buffer, font *Font) {
 	/* Second round, reorder (inplace) */
 	/* Second round, reorder (inplace) */
 
 
 	if !allSimple {
 	if !allSimple {
-		if debugMode >= 1 {
+		if debugMode {
 			fmt.Println("NORMALIZE - start reorder")
 			fmt.Println("NORMALIZE - start reorder")
 		}
 		}
 		count = len(buffer.Info)
 		count = len(buffer.Info)
@@ -353,7 +357,7 @@ func otShapeNormalize(plan *otShapePlan, buffer *Buffer, font *Font) {
 
 
 			i = end
 			i = end
 		}
 		}
-		if debugMode >= 1 {
+		if debugMode {
 			fmt.Println("NORMALIZE - end reorder")
 			fmt.Println("NORMALIZE - end reorder")
 		}
 		}
 	}
 	}
@@ -376,7 +380,7 @@ func otShapeNormalize(plan *otShapePlan, buffer *Buffer, font *Font) {
 		(mode == nmComposedDiacritics ||
 		(mode == nmComposedDiacritics ||
 			mode == nmComposedDiacriticsNoShortCircuit) {
 			mode == nmComposedDiacriticsNoShortCircuit) {
 
 
-		if debugMode >= 1 {
+		if debugMode {
 			fmt.Println("NORMALIZE - recompose")
 			fmt.Println("NORMALIZE - recompose")
 		}
 		}
 
 

+ 62 - 45
vendor/github.com/go-text/typesetting/harfbuzz/ot_shaper.go

@@ -30,7 +30,6 @@ type otShapePlanner struct {
 	shaper                        otComplexShaper
 	shaper                        otComplexShaper
 	props                         SegmentProperties
 	props                         SegmentProperties
 	tables                        *font.Font // also used by the map builders
 	tables                        *font.Font // also used by the map builders
-	aatMap                        aatMapBuilder
 	map_                          otMapBuilder
 	map_                          otMapBuilder
 	applyMorx                     bool
 	applyMorx                     bool
 	scriptZeroMarks               bool
 	scriptZeroMarks               bool
@@ -42,7 +41,6 @@ func newOtShapePlanner(tables *font.Font, props SegmentProperties) *otShapePlann
 	out.props = props
 	out.props = props
 	out.tables = tables
 	out.tables = tables
 	out.map_ = newOtMapBuilder(tables, props)
 	out.map_ = newOtMapBuilder(tables, props)
-	out.aatMap = aatMapBuilder{tables: tables}
 
 
 	/* https://github.com/harfbuzz/harfbuzz/issues/2124 */
 	/* https://github.com/harfbuzz/harfbuzz/issues/2124 */
 	out.applyMorx = len(tables.Morx) != 0 && (props.Direction.isHorizontal() || len(tables.GSUB.Lookups) == 0)
 	out.applyMorx = len(tables.Morx) != 0 && (props.Direction.isHorizontal() || len(tables.GSUB.Lookups) == 0)
@@ -64,9 +62,6 @@ func (planner *otShapePlanner) compile(plan *otShapePlan, key otShapePlanKey) {
 	plan.props = planner.props
 	plan.props = planner.props
 	plan.shaper = planner.shaper
 	plan.shaper = planner.shaper
 	planner.map_.compile(&plan.map_, key)
 	planner.map_.compile(&plan.map_, key)
-	if planner.applyMorx {
-		planner.aatMap.compile(&plan.aatMap)
-	}
 
 
 	plan.fracMask = plan.map_.getMask1(loader.NewTag('f', 'r', 'a', 'c'))
 	plan.fracMask = plan.map_.getMask1(loader.NewTag('f', 'r', 'a', 'c'))
 	plan.numrMask = plan.map_.getMask1(loader.NewTag('n', 'u', 'm', 'r'))
 	plan.numrMask = plan.map_.getMask1(loader.NewTag('n', 'u', 'm', 'r'))
@@ -143,8 +138,7 @@ type otShapePlan struct {
 	shaper otComplexShaper
 	shaper otComplexShaper
 	props  SegmentProperties
 	props  SegmentProperties
 
 
-	aatMap aatMap
-	map_   otMap
+	map_ otMap
 
 
 	fracMask GlyphMask
 	fracMask GlyphMask
 	numrMask GlyphMask
 	numrMask GlyphMask
@@ -182,11 +176,7 @@ func (sp *otShapePlan) init0(tables *font.Font, props SegmentProperties, userFea
 }
 }
 
 
 func (sp *otShapePlan) substitute(font *Font, buffer *Buffer) {
 func (sp *otShapePlan) substitute(font *Font, buffer *Buffer) {
-	if sp.applyMorx {
-		sp.aatLayoutSubstitute(font, buffer)
-	} else {
-		sp.map_.substitute(sp, font, buffer)
-	}
+	sp.map_.substitute(sp, font, buffer)
 }
 }
 
 
 func (sp *otShapePlan) position(font *Font, buffer *Buffer) {
 func (sp *otShapePlan) position(font *Font, buffer *Buffer) {
@@ -289,13 +279,6 @@ func (planner *otShapePlanner) collectFeatures(userFeatures []Feature) {
 		map_.addFeatureExt(f.Tag, ftag, f.Value)
 		map_.addFeatureExt(f.Tag, ftag, f.Value)
 	}
 	}
 
 
-	if planner.applyMorx {
-		aatMap := &planner.aatMap
-		for _, f := range userFeatures {
-			aatMap.addFeature(f.Tag, f.Value)
-		}
-	}
-
 	planner.shaper.overrideFeatures(planner)
 	planner.shaper.overrideFeatures(planner)
 }
 }
 
 
@@ -558,8 +541,8 @@ func synthesizeGlyphClasses(buffer *Buffer) {
 
 
 func (c *otContext) substituteBeforePosition() {
 func (c *otContext) substituteBeforePosition() {
 	buffer := c.buffer
 	buffer := c.buffer
-	// normalize and sets Glyph
 
 
+	// substituteDefault : normalize and sets Glyph
 	c.otRotateChars()
 	c.otRotateChars()
 
 
 	otShapeNormalize(c.plan, buffer, c.font)
 	otShapeNormalize(c.plan, buffer, c.font)
@@ -571,7 +554,11 @@ func (c *otContext) substituteBeforePosition() {
 		fallbackMarkPositionRecategorizeMarks(buffer)
 		fallbackMarkPositionRecategorizeMarks(buffer)
 	}
 	}
 
 
-	// Glyph fields are now set up ...
+	if debugMode {
+		fmt.Println("BEFORE SUBSTITUTE:", c.buffer.Info)
+	}
+
+	// substitutePan : glyph fields are now set up ...
 	// ... apply complex substitution from font
 	// ... apply complex substitution from font
 
 
 	layoutSubstituteStart(c.font, buffer)
 	layoutSubstituteStart(c.font, buffer)
@@ -580,20 +567,30 @@ func (c *otContext) substituteBeforePosition() {
 		synthesizeGlyphClasses(c.buffer)
 		synthesizeGlyphClasses(c.buffer)
 	}
 	}
 
 
+	if c.plan.applyMorx {
+		c.plan.aatLayoutSubstitute(c.font, c.buffer, c.userFeatures)
+	}
+
 	c.plan.substitute(c.font, buffer)
 	c.plan.substitute(c.font, buffer)
+
+	//
+	if c.plan.applyMorx && c.plan.applyGpos {
+		aatLayoutRemoveDeletedGlyphs(buffer)
+	}
 }
 }
 
 
 func (c *otContext) substituteAfterPosition() {
 func (c *otContext) substituteAfterPosition() {
-	hideDefaultIgnorables(c.buffer, c.font)
-	if c.plan.applyMorx {
-		aatLayoutRemoveDeletedGlyphsInplace(c.buffer)
+	if c.plan.applyMorx && !c.plan.applyGpos {
+		aatLayoutRemoveDeletedGlyphs(c.buffer)
 	}
 	}
 
 
-	if debugMode >= 1 {
-		fmt.Printf("POSTPROCESS glyphs start (%T)\n", c.plan.shaper)
+	hideDefaultIgnorables(c.buffer, c.font)
+
+	if debugMode {
+		fmt.Println("POSTPROCESS glyphs start")
 	}
 	}
 	c.plan.shaper.postprocessGlyphs(c.plan, c.buffer, c.font)
 	c.plan.shaper.postprocessGlyphs(c.plan, c.buffer, c.font)
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("POSTPROCESS glyphs end ")
 		fmt.Println("POSTPROCESS glyphs end ")
 	}
 	}
 }
 }
@@ -650,7 +647,7 @@ func (c *otContext) positionComplex() {
 	* hanging over the next glyph after the final reordering.
 	* hanging over the next glyph after the final reordering.
 	*
 	*
 	* Note: If fallback positioning happens, we don't care about
 	* Note: If fallback positioning happens, we don't care about
-	* this as it will be overriden. */
+	* this as it will be overridden. */
 	adjustOffsetsWhenZeroing := c.plan.adjustMarkPositioningWhenZeroing && c.buffer.Props.Direction.isForward()
 	adjustOffsetsWhenZeroing := c.plan.adjustMarkPositioningWhenZeroing && c.buffer.Props.Direction.isForward()
 
 
 	// we change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back.
 	// we change glyph origin to what GPOS expects (horizontal), apply GPOS, change it back.
@@ -697,7 +694,7 @@ func (c *otContext) position() {
 
 
 	c.positionDefault()
 	c.positionDefault()
 
 
-	if debugMode >= 2 {
+	if debugMode {
 		fmt.Println("AFTER DEFAULT POSITION", c.buffer.Pos)
 		fmt.Println("AFTER DEFAULT POSITION", c.buffer.Pos)
 	}
 	}
 
 
@@ -711,25 +708,47 @@ func (c *otContext) position() {
 /* Propagate cluster-level glyph flags to be the same on all cluster glyphs.
 /* Propagate cluster-level glyph flags to be the same on all cluster glyphs.
  * Simplifies using them. */
  * Simplifies using them. */
 func propagateFlags(buffer *Buffer) {
 func propagateFlags(buffer *Buffer) {
-	if buffer.scratchFlags&bsfHasUnsafeToBreak == 0 {
+	if buffer.scratchFlags&bsfHasGlyphFlags == 0 {
 		return
 		return
 	}
 	}
 
 
+	/* If we are producing SAFE_TO_INSERT_TATWEEL, then do two things:
+	 *
+	 * - If the places that the Arabic shaper marked as SAFE_TO_INSERT_TATWEEL,
+	 *   are UNSAFE_TO_BREAK, then clear the SAFE_TO_INSERT_TATWEEL,
+	 * - Any place that is SAFE_TO_INSERT_TATWEEL, is also now UNSAFE_TO_BREAK.
+	 *
+	 * We couldn't make this interaction earlier. It has to be done here.
+	 */
+	flipTatweel := buffer.Flags&ProduceSafeToInsertTatweel != 0
+
+	clearConcat := (buffer.Flags & ProduceUnsafeToConcat) == 0
+
 	info := buffer.Info
 	info := buffer.Info
 
 
 	iter, count := buffer.clusterIterator()
 	iter, count := buffer.clusterIterator()
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 		var mask uint32
 		var mask uint32
 		for i := start; i < end; i++ {
 		for i := start; i < end; i++ {
-			if info[i].Mask&GlyphUnsafeToBreak != 0 {
-				mask = GlyphUnsafeToBreak
-				break
-			}
+			mask |= info[i].Mask & glyphFlagDefined
 		}
 		}
-		if mask != 0 {
-			for i := start; i < end; i++ {
-				info[i].Mask |= mask
+
+		if flipTatweel {
+			if mask&GlyphUnsafeToBreak != 0 {
+				mask &= ^GlyphSafeToInsertTatweel
+			}
+			if mask&GlyphSafeToInsertTatweel != 0 {
+				mask |= GlyphUnsafeToBreak | GlyphUnsafeToConcat
 			}
 			}
+
+		}
+
+		if clearConcat {
+			mask &= ^GlyphUnsafeToConcat
+		}
+
+		for i := start; i < end; i++ {
+			info[i].Mask = mask
 		}
 		}
 	}
 	}
 }
 }
@@ -754,8 +773,6 @@ func newShaperOpentype(tables *font.Font, coords []float32) *shaperOpentype {
 	return &out
 	return &out
 }
 }
 
 
-func (shaperOpentype) kind() shaperKind { return skOpentype }
-
 func (sp *shaperOpentype) compile(props SegmentProperties, userFeatures []Feature) {
 func (sp *shaperOpentype) compile(props SegmentProperties, userFeatures []Feature) {
 	sp.plan.init0(sp.tables, props, userFeatures, sp.key)
 	sp.plan.init0(sp.tables, props, userFeatures, sp.key)
 }
 }
@@ -781,29 +798,29 @@ func (sp *shaperOpentype) shape(font *Font, buffer *Buffer, features []Feature)
 
 
 	c.buffer.formClusters()
 	c.buffer.formClusters()
 
 
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("FORMING CLUSTER :", c.buffer.Info)
 		fmt.Println("FORMING CLUSTER :", c.buffer.Info)
 	}
 	}
 
 
 	c.buffer.ensureNativeDirection()
 	c.buffer.ensureNativeDirection()
 
 
-	if debugMode >= 1 {
-		fmt.Printf("PREPROCESS text start (complex shaper %T)\n", c.plan.shaper)
+	if debugMode {
+		fmt.Printf("PREPROCESS text start\n")
 	}
 	}
 	c.plan.shaper.preprocessText(c.plan, c.buffer, c.font)
 	c.plan.shaper.preprocessText(c.plan, c.buffer, c.font)
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("PREPROCESS text end:", c.buffer.Info)
 		fmt.Println("PREPROCESS text end:", c.buffer.Info)
 	}
 	}
 
 
 	c.substituteBeforePosition() // apply GSUB
 	c.substituteBeforePosition() // apply GSUB
 
 
-	if debugMode >= 2 {
+	if debugMode {
 		fmt.Println("AFTER SUBSTITUTE", c.buffer.Info)
 		fmt.Println("AFTER SUBSTITUTE", c.buffer.Info)
 	}
 	}
 
 
 	c.position()
 	c.position()
 
 
-	if debugMode >= 2 {
+	if debugMode {
 		fmt.Println("AFTER POSITION", c.buffer.Pos)
 		fmt.Println("AFTER POSITION", c.buffer.Pos)
 	}
 	}
 
 

+ 2 - 0
vendor/github.com/go-text/typesetting/harfbuzz/ot_tag.go

@@ -25,6 +25,8 @@ func oldTagFromScript(script language.Script) tables.Tag {
 	switch script {
 	switch script {
 	case 0:
 	case 0:
 		return tagDefaultScript
 		return tagDefaultScript
+	case language.Mathematical_notation:
+		return loader.NewTag('m', 'a', 't', 'h')
 
 
 	/* KATAKANA and HIRAGANA both map to 'kana' */
 	/* KATAKANA and HIRAGANA both map to 'kana' */
 	case language.Hiragana:
 	case language.Hiragana:

+ 41 - 40
vendor/github.com/go-text/typesetting/harfbuzz/ot_thai.go

@@ -244,11 +244,12 @@ func doThaiPuaShaping(buffer *Buffer, font *Font) {
 func isSaraAm(x rune) bool           { return x & ^0x0080 == 0x0E33 }
 func isSaraAm(x rune) bool           { return x & ^0x0080 == 0x0E33 }
 func nikhahitFromSaraAm(x rune) rune { return x - 0x0E33 + 0x0E4D }
 func nikhahitFromSaraAm(x rune) rune { return x - 0x0E33 + 0x0E4D }
 func saraAaFromSaraAm(x rune) rune   { return x - 1 }
 func saraAaFromSaraAm(x rune) rune   { return x - 1 }
-func isToneMark(x rune) bool {
+func isAboveBaseMark(x rune) bool {
 	u := x & ^0x0080
 	u := x & ^0x0080
 	return 0x0E34 <= u && u <= 0x0E37 ||
 	return 0x0E34 <= u && u <= 0x0E37 ||
 		0x0E47 <= u && u <= 0x0E4E ||
 		0x0E47 <= u && u <= 0x0E4E ||
-		0x0E31 <= u && u <= 0x0E31
+		u == 0x0E31 ||
+		u == 0x0E3B
 }
 }
 
 
 /* This function implements the shaping logic documented here:
 /* This function implements the shaping logic documented here:
@@ -260,43 +261,43 @@ func isToneMark(x rune) bool {
  * We implement that only if there exist no Thai GSUB in the font.
  * We implement that only if there exist no Thai GSUB in the font.
  */
  */
 func (complexShaperThai) preprocessText(plan *otShapePlan, buffer *Buffer, font *Font) {
 func (complexShaperThai) preprocessText(plan *otShapePlan, buffer *Buffer, font *Font) {
-	/* The following is NOT specified in the MS OT Thai spec, however, it seems
-	* to be what Uniscribe and other engines implement.  According to Eric Muller:
-	*
-	* When you have a SARA AM, decompose it in NIKHAHIT + SARA AA, *and* move the
-	* NIKHAHIT backwards over any tone mark (0E48-0E4B).
-	*
-	* <0E14, 0E4B, 0E33> . <0E14, 0E4D, 0E4B, 0E32>
-	*
-	* This reordering is legit only when the NIKHAHIT comes from a SARA AM, not
-	* when it's there to start with. The string <0E14, 0E4B, 0E4D> is probably
-	* not what a user wanted, but the rendering is nevertheless nikhahit above
-	* chattawa.
-	*
-	* Same for Lao.
-	*
-	* Note:
-	*
-	* Uniscribe also does some below-marks reordering.  Namely, it positions U+0E3A
-	* after U+0E38 and U+0E39.  We do that by modifying the ccc for U+0E3A.
-	* See unicode.modified_combining_class ().  Lao does NOT have a U+0E3A
-	* equivalent.
-	 */
-
-	/*
-	* Here are the characters of significance:
-	*
-	*			Thai	Lao
-	* SARA AM:		U+0E33	U+0EB3
-	* SARA AA:		U+0E32	U+0EB2
-	* Nikhahit:		U+0E4D	U+0ECD
-	*
-	* Testing shows that Uniscribe reorder the following marks:
-	* Thai:	<0E31,0E34..0E37,0E47..0E4E>
-	* Lao:	<0EB1,0EB4..0EB7,0EC7..0ECE>
-	*
-	* Note how the Lao versions are the same as Thai + 0x80.
-	 */
+	// The following is NOT specified in the MS OT Thai spec, however, it seems
+	// to be what Uniscribe and other engines implement.  According to Eric Muller:
+	//
+	// When you have a SARA AM, decompose it in NIKHAHIT + SARA AA, *and* move the
+	// NIKHAHIT backwards over any above-base marks.
+	//
+	// <0E14, 0E4B, 0E33> . <0E14, 0E4D, 0E4B, 0E32>
+	//
+	// This reordering is legit only when the NIKHAHIT comes from a SARA AM, not
+	// when it's there to start with. The string <0E14, 0E4B, 0E4D> is probably
+	// not what a user wanted, but the rendering is nevertheless nikhahit above
+	// chattawa.
+	//
+	// Same for Lao.
+	//
+	// Note:
+	//
+	// Uniscribe also does some below-marks reordering.  Namely, it positions U+0E3A
+	// after U+0E38 and U+0E39.  We do that by modifying the ccc for U+0E3A.
+	// See unicode.modified_combining_class ().  Lao does NOT have a U+0E3A
+	// equivalent.
+	//
+
+	//
+	// Here are the characters of significance:
+	//
+	//			Thai	Lao
+	// SARA AM:		U+0E33	U+0EB3
+	// SARA AA:		U+0E32	U+0EB2
+	// Nikhahit:		U+0E4D	U+0ECD
+	//
+	// Testing shows that Uniscribe reorder the following marks:
+	// Thai:	<0E31,0E34..0E37,     0E47..0E4E>
+	// Lao:	<0EB1,0EB4..0EB7,0EBB,0EC8..0ECD>
+	//
+	// Note how the Lao versions are the same as Thai + 0x80.
+	//
 
 
 	buffer.clearOutput()
 	buffer.clearOutput()
 	count := len(buffer.Info)
 	count := len(buffer.Info)
@@ -318,7 +319,7 @@ func (complexShaperThai) preprocessText(plan *otShapePlan, buffer *Buffer, font
 
 
 		/* Ok, let's see... */
 		/* Ok, let's see... */
 		start := end - 2
 		start := end - 2
-		for start > 0 && isToneMark(buffer.outInfo[start-1].codepoint) {
+		for start > 0 && isAboveBaseMark(buffer.outInfo[start-1].codepoint) {
 			start--
 			start--
 		}
 		}
 
 

+ 48 - 42
vendor/github.com/go-text/typesetting/harfbuzz/ot_use.go

@@ -5,7 +5,6 @@ import (
 
 
 	"github.com/go-text/typesetting/opentype/loader"
 	"github.com/go-text/typesetting/opentype/loader"
 	"github.com/go-text/typesetting/opentype/tables"
 	"github.com/go-text/typesetting/opentype/tables"
-	ucd "github.com/go-text/typesetting/unicodedata"
 )
 )
 
 
 // ported from harfbuzz/src/hb-ot-shape-complex-use.cc Copyright © 2015  Mozilla Foundation. Google, Inc. Jonathan Kew, Behdad Esfahbod
 // ported from harfbuzz/src/hb-ot-shape-complex-use.cc Copyright © 2015  Mozilla Foundation. Google, Inc. Jonathan Kew, Behdad Esfahbod
@@ -78,26 +77,26 @@ func (cs *complexShaperUSE) collectFeatures(plan *otShapePlanner) {
 	map_.addGSUBPause(cs.setupSyllablesUse)
 	map_.addGSUBPause(cs.setupSyllablesUse)
 
 
 	/* "Default glyph pre-processing group" */
 	/* "Default glyph pre-processing group" */
-	map_.enableFeature(loader.NewTag('l', 'o', 'c', 'l'))
-	map_.enableFeature(loader.NewTag('c', 'c', 'm', 'p'))
-	map_.enableFeature(loader.NewTag('n', 'u', 'k', 't'))
-	map_.enableFeatureExt(loader.NewTag('a', 'k', 'h', 'n'), ffManualZWJ, 1)
+	map_.enableFeatureExt(loader.NewTag('l', 'o', 'c', 'l'), ffPerSyllable, 1)
+	map_.enableFeatureExt(loader.NewTag('c', 'c', 'm', 'p'), ffPerSyllable, 1)
+	map_.enableFeatureExt(loader.NewTag('n', 'u', 'k', 't'), ffPerSyllable, 1)
+	map_.enableFeatureExt(loader.NewTag('a', 'k', 'h', 'n'), ffManualZWJ|ffPerSyllable, 1)
 
 
 	/* "Reordering group" */
 	/* "Reordering group" */
 	map_.addGSUBPause(clearSubstitutionFlags)
 	map_.addGSUBPause(clearSubstitutionFlags)
-	map_.addFeatureExt(loader.NewTag('r', 'p', 'h', 'f'), ffManualZWJ, 1)
+	map_.addFeatureExt(loader.NewTag('r', 'p', 'h', 'f'), ffManualZWJ|ffPerSyllable, 1)
 	map_.addGSUBPause(cs.recordRphfUse)
 	map_.addGSUBPause(cs.recordRphfUse)
 	map_.addGSUBPause(clearSubstitutionFlags)
 	map_.addGSUBPause(clearSubstitutionFlags)
-	map_.enableFeatureExt(loader.NewTag('p', 'r', 'e', 'f'), ffManualZWJ, 1)
+	map_.enableFeatureExt(loader.NewTag('p', 'r', 'e', 'f'), ffManualZWJ|ffPerSyllable, 1)
 	map_.addGSUBPause(recordPrefUse)
 	map_.addGSUBPause(recordPrefUse)
 
 
 	/* "Orthographic unit shaping group" */
 	/* "Orthographic unit shaping group" */
 	for _, basicFeat := range useBasicFeatures {
 	for _, basicFeat := range useBasicFeatures {
-		map_.enableFeatureExt(basicFeat, ffManualZWJ, 1)
+		map_.enableFeatureExt(basicFeat, ffManualZWJ|ffPerSyllable, 1)
 	}
 	}
 
 
 	map_.addGSUBPause(reorderUse)
 	map_.addGSUBPause(reorderUse)
-	map_.addGSUBPause(clearSyllables)
+	map_.addGSUBPause(nil)
 
 
 	/* "Topographical features" */
 	/* "Topographical features" */
 	for _, topoFeat := range useTopographicalFeatures {
 	for _, topoFeat := range useTopographicalFeatures {
@@ -116,7 +115,7 @@ func (cs *complexShaperUSE) dataCreate(plan *otShapePlan) {
 
 
 	usePlan.rphfMask = plan.map_.getMask1(loader.NewTag('r', 'p', 'h', 'f'))
 	usePlan.rphfMask = plan.map_.getMask1(loader.NewTag('r', 'p', 'h', 'f'))
 
 
-	if ucd.HasArabicJoining(plan.props.Script) {
+	if hasArabicJoining(plan.props.Script) {
 		pl := newArabicPlan(plan)
 		pl := newArabicPlan(plan)
 		usePlan.arabicPlan = &pl
 		usePlan.arabicPlan = &pl
 	}
 	}
@@ -152,7 +151,7 @@ func (cs *complexShaperUSE) setupRphfMask(buffer *Buffer) {
 	iter, count := buffer.syllableIterator()
 	iter, count := buffer.syllableIterator()
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 		limit := 1
 		limit := 1
-		if info[start].complexCategory != useSyllableMachine_ex_R {
+		if info[start].complexCategory != useSM_ex_R {
 			limit = min(3, end-start)
 			limit = min(3, end-start)
 		}
 		}
 		for i := start; i < start+limit; i++ {
 		for i := start; i < start+limit; i++ {
@@ -188,11 +187,12 @@ func (cs *complexShaperUSE) setupTopographicalMasks(plan *otShapePlan, buffer *B
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 		syllableType := info[start].syllable & 0x0F
 		syllableType := info[start].syllable & 0x0F
 		switch syllableType {
 		switch syllableType {
-		case useSymbolCluster, useHieroglyphCluster, useNonCluster:
+		case useHieroglyphCluster, useNonCluster:
 			// these don't join.  Nothing to do.
 			// these don't join.  Nothing to do.
 			lastForm = joiningFormNone
 			lastForm = joiningFormNone
 
 
-		case useViramaTerminatedCluster, useSakotTerminatedCluster, useStandardCluster, useNumberJoinerTerminatedCluster, useNumeralCluster, useBrokenCluster:
+		case useViramaTerminatedCluster, useSakotTerminatedCluster, useStandardCluster, useNumberJoinerTerminatedCluster,
+			useNumeralCluster, useSymbolCluster, useBrokenCluster:
 			join := lastForm == joiningFormFina || lastForm == joiningFormIsol
 			join := lastForm == joiningFormFina || lastForm == joiningFormIsol
 			if join {
 			if join {
 				// fixup previous syllable's form.
 				// fixup previous syllable's form.
@@ -220,7 +220,7 @@ func (cs *complexShaperUSE) setupTopographicalMasks(plan *otShapePlan, buffer *B
 	}
 	}
 }
 }
 
 
-func (cs *complexShaperUSE) setupSyllablesUse(plan *otShapePlan, _ *Font, buffer *Buffer) {
+func (cs *complexShaperUSE) setupSyllablesUse(plan *otShapePlan, _ *Font, buffer *Buffer) bool {
 	findSyllablesUse(buffer)
 	findSyllablesUse(buffer)
 	iter, count := buffer.syllableIterator()
 	iter, count := buffer.syllableIterator()
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 	for start, end := iter.next(); start < count; start, end = iter.next() {
@@ -228,14 +228,15 @@ func (cs *complexShaperUSE) setupSyllablesUse(plan *otShapePlan, _ *Font, buffer
 	}
 	}
 	cs.setupRphfMask(buffer)
 	cs.setupRphfMask(buffer)
 	cs.setupTopographicalMasks(plan, buffer)
 	cs.setupTopographicalMasks(plan, buffer)
+	return false
 }
 }
 
 
-func (cs *complexShaperUSE) recordRphfUse(plan *otShapePlan, _ *Font, buffer *Buffer) {
+func (cs *complexShaperUSE) recordRphfUse(plan *otShapePlan, _ *Font, buffer *Buffer) bool {
 	usePlan := cs.plan
 	usePlan := cs.plan
 
 
 	mask := usePlan.rphfMask
 	mask := usePlan.rphfMask
 	if mask == 0 {
 	if mask == 0 {
-		return
+		return false
 	}
 	}
 	info := buffer.Info
 	info := buffer.Info
 
 
@@ -244,14 +245,15 @@ func (cs *complexShaperUSE) recordRphfUse(plan *otShapePlan, _ *Font, buffer *Bu
 		// mark a substituted repha as USE(R).
 		// mark a substituted repha as USE(R).
 		for i := start; i < end && (info[i].Mask&mask) != 0; i++ {
 		for i := start; i < end && (info[i].Mask&mask) != 0; i++ {
 			if glyphInfoSubstituted(&info[i]) {
 			if glyphInfoSubstituted(&info[i]) {
-				info[i].complexCategory = useSyllableMachine_ex_R
+				info[i].complexCategory = useSM_ex_R
 				break
 				break
 			}
 			}
 		}
 		}
 	}
 	}
+	return false
 }
 }
 
 
-func recordPrefUse(_ *otShapePlan, _ *Font, buffer *Buffer) {
+func recordPrefUse(_ *otShapePlan, _ *Font, buffer *Buffer) bool {
 	info := buffer.Info
 	info := buffer.Info
 
 
 	iter, count := buffer.syllableIterator()
 	iter, count := buffer.syllableIterator()
@@ -259,15 +261,16 @@ func recordPrefUse(_ *otShapePlan, _ *Font, buffer *Buffer) {
 		// mark a substituted pref as VPre, as they behave the same way.
 		// mark a substituted pref as VPre, as they behave the same way.
 		for i := start; i < end; i++ {
 		for i := start; i < end; i++ {
 			if glyphInfoSubstituted(&info[i]) {
 			if glyphInfoSubstituted(&info[i]) {
-				info[i].complexCategory = useSyllableMachine_ex_VPre
+				info[i].complexCategory = useSM_ex_VPre
 				break
 				break
 			}
 			}
 		}
 		}
 	}
 	}
+	return false
 }
 }
 
 
 func isHalantUse(info *GlyphInfo) bool {
 func isHalantUse(info *GlyphInfo) bool {
-	return (info.complexCategory == useSyllableMachine_ex_H || info.complexCategory == useSyllableMachine_ex_HVM) &&
+	return (info.complexCategory == useSM_ex_H || info.complexCategory == useSM_ex_HVM || info.complexCategory == useSM_ex_IS) &&
 		!info.ligated()
 		!info.ligated()
 }
 }
 
 
@@ -277,6 +280,7 @@ func reorderSyllableUse(buffer *Buffer, start, end int) {
 	const mask = 1<<useViramaTerminatedCluster |
 	const mask = 1<<useViramaTerminatedCluster |
 		1<<useSakotTerminatedCluster |
 		1<<useSakotTerminatedCluster |
 		1<<useStandardCluster |
 		1<<useStandardCluster |
+		1<<useSymbolCluster |
 		1<<useBrokenCluster
 		1<<useBrokenCluster
 	if 1<<syllableType&mask == 0 {
 	if 1<<syllableType&mask == 0 {
 		return
 		return
@@ -284,24 +288,24 @@ func reorderSyllableUse(buffer *Buffer, start, end int) {
 
 
 	info := buffer.Info
 	info := buffer.Info
 
 
-	const postBaseFlags64 int64 = (1<<useSyllableMachine_ex_FAbv |
-		1<<useSyllableMachine_ex_FBlw |
-		1<<useSyllableMachine_ex_FPst |
-		1<<useSyllableMachine_ex_MAbv |
-		1<<useSyllableMachine_ex_MBlw |
-		1<<useSyllableMachine_ex_MPst |
-		1<<useSyllableMachine_ex_MPre |
-		1<<useSyllableMachine_ex_VAbv |
-		1<<useSyllableMachine_ex_VBlw |
-		1<<useSyllableMachine_ex_VPst |
-		1<<useSyllableMachine_ex_VPre |
-		1<<useSyllableMachine_ex_VMAbv |
-		1<<useSyllableMachine_ex_VMBlw |
-		1<<useSyllableMachine_ex_VMPst |
-		1<<useSyllableMachine_ex_VMPre)
+	const postBaseFlags64 int64 = (1<<useSM_ex_FAbv |
+		1<<useSM_ex_FBlw |
+		1<<useSM_ex_FPst |
+		1<<useSM_ex_MAbv |
+		1<<useSM_ex_MBlw |
+		1<<useSM_ex_MPst |
+		1<<useSM_ex_MPre |
+		1<<useSM_ex_VAbv |
+		1<<useSM_ex_VBlw |
+		1<<useSM_ex_VPst |
+		1<<useSM_ex_VPre |
+		1<<useSM_ex_VMAbv |
+		1<<useSM_ex_VMBlw |
+		1<<useSM_ex_VMPst |
+		1<<useSM_ex_VMPre)
 
 
 	/* Move things forward. */
 	/* Move things forward. */
-	if info[start].complexCategory == useSyllableMachine_ex_R && end-start > 1 {
+	if info[start].complexCategory == useSM_ex_R && end-start > 1 {
 		/* Got a repha.  Reorder it towards the end, but before the first post-base
 		/* Got a repha.  Reorder it towards the end, but before the first post-base
 		 * glyph. */
 		 * glyph. */
 		for i := start + 1; i < end; i++ {
 		for i := start + 1; i < end; i++ {
@@ -333,7 +337,7 @@ func reorderSyllableUse(buffer *Buffer, start, end int) {
 			/* If we hit a halant, move after it; otherwise move to the beginning, and
 			/* If we hit a halant, move after it; otherwise move to the beginning, and
 			* shift things in between forward. */
 			* shift things in between forward. */
 			j = i + 1
 			j = i + 1
-		} else if flag&(1<<useSyllableMachine_ex_VPre|1<<useSyllableMachine_ex_VMPre) != 0 &&
+		} else if flag&(1<<useSM_ex_VPre|1<<useSM_ex_VMPre) != 0 &&
 			/* Only move the first component of a MultipleSubst. */
 			/* Only move the first component of a MultipleSubst. */
 			info[i].getLigComp() == 0 && j < i {
 			info[i].getLigComp() == 0 && j < i {
 			buffer.mergeClusters(j, i+1)
 			buffer.mergeClusters(j, i+1)
@@ -344,20 +348,22 @@ func reorderSyllableUse(buffer *Buffer, start, end int) {
 	}
 	}
 }
 }
 
 
-func reorderUse(_ *otShapePlan, font *Font, buffer *Buffer) {
-	if debugMode >= 1 {
+func reorderUse(_ *otShapePlan, font *Font, buffer *Buffer) bool {
+	if debugMode {
 		fmt.Println("USE - start reordering USE")
 		fmt.Println("USE - start reordering USE")
 	}
 	}
-	syllabicInsertDottedCircles(font, buffer, useBrokenCluster,
-		useSyllableMachine_ex_B, useSyllableMachine_ex_R, -1)
+	ret := syllabicInsertDottedCircles(font, buffer, useBrokenCluster,
+		useSM_ex_B, useSM_ex_R, -1)
 
 
 	iter, count := buffer.syllableIterator()
 	iter, count := buffer.syllableIterator()
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 	for start, end := iter.next(); start < count; start, end = iter.next() {
 		reorderSyllableUse(buffer, start, end)
 		reorderSyllableUse(buffer, start, end)
 	}
 	}
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("USE - end reordering USE")
 		fmt.Println("USE - end reordering USE")
 	}
 	}
+
+	return ret
 }
 }
 
 
 func (cs *complexShaperUSE) preprocessText(_ *otShapePlan, buffer *Buffer, _ *Font) {
 func (cs *complexShaperUSE) preprocessText(_ *otShapePlan, buffer *Buffer, _ *Font) {

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 631 - 296
vendor/github.com/go-text/typesetting/harfbuzz/ot_use_machine.go


+ 18 - 15
vendor/github.com/go-text/typesetting/harfbuzz/ot_use_machine.rl

@@ -17,7 +17,7 @@ const (
 )
 )
 
 
 %%{
 %%{
-  machine useSyllableMachine;
+  machine useSM;
   alphtype byte;
   alphtype byte;
   write exports;
   write exports;
   write data;
   write data;
@@ -39,14 +39,16 @@ export H	= 12; # HALANT
 
 
 export HN	= 13; # HALANT_NUM
 export HN	= 13; # HALANT_NUM
 export ZWNJ	= 14; # Zero width non-joiner
 export ZWNJ	= 14; # Zero width non-joiner
+export WJ	= 16; # Word joiner
 export R	= 18; # REPHA
 export R	= 18; # REPHA
 export CS	= 43; # CONS_WITH_STACKER
 export CS	= 43; # CONS_WITH_STACKER
-export HVM	= 44; # HALANT_OR_VOWEL_MODIFIER
+export IS	= 44; # INVISIBLE_STACKER
 export Sk	= 48; # SAKOT
 export Sk	= 48; # SAKOT
 export G	= 49; # HIEROGLYPH
 export G	= 49; # HIEROGLYPH
 export J	= 50; # HIEROGLYPH_JOINER
 export J	= 50; # HIEROGLYPH_JOINER
 export SB	= 51; # HIEROGLYPH_SEGMENT_BEGIN
 export SB	= 51; # HIEROGLYPH_SEGMENT_BEGIN
 export SE	= 52; # HIEROGLYPH_SEGMENT_END
 export SE	= 52; # HIEROGLYPH_SEGMENT_END
+export HVM	= 53; # HALANT_OR_VOWEL_MODIFIER
 
 
 export FAbv	= 24; # CONS_FINAL_ABOVE
 export FAbv	= 24; # CONS_FINAL_ABOVE
 export FBlw	= 25; # CONS_FINAL_BELOW
 export FBlw	= 25; # CONS_FINAL_BELOW
@@ -71,11 +73,11 @@ export FMAbv	= 45; # CONS_FINAL_MOD	UIPC = Top
 export FMBlw	= 46; # CONS_FINAL_MOD	UIPC = Bottom
 export FMBlw	= 46; # CONS_FINAL_MOD	UIPC = Bottom
 export FMPst	= 47; # CONS_FINAL_MOD	UIPC = Not_Applicable
 export FMPst	= 47; # CONS_FINAL_MOD	UIPC = Not_Applicable
 
 
-h = H | HVM | Sk;
+h = H | HVM | IS | Sk;
 
 
 consonant_modifiers = CMAbv* CMBlw* ((h B | SUB) CMAbv? CMBlw*)*;
 consonant_modifiers = CMAbv* CMBlw* ((h B | SUB) CMAbv? CMBlw*)*;
 medial_consonants = MPre? MAbv? MBlw? MPst?;
 medial_consonants = MPre? MAbv? MBlw? MPst?;
-dependent_vowels = VPre* VAbv* VBlw* VPst*;
+dependent_vowels = VPre* VAbv* VBlw* VPst* | H;
 vowel_modifiers = HVM? VMPre* VMAbv* VMBlw* VMPst*;
 vowel_modifiers = HVM? VMPre* VMAbv* VMBlw* VMPst*;
 final_consonants = FAbv* FBlw* FPst*;
 final_consonants = FAbv* FBlw* FPst*;
 final_modifiers = FMAbv* FMBlw* | FMPst?;
 final_modifiers = FMAbv* FMBlw* | FMPst?;
@@ -99,7 +101,7 @@ symbol_cluster_tail = SMAbv+ SMBlw* | SMBlw+;
 
 
 virama_terminated_cluster_tail =
 virama_terminated_cluster_tail =
 	consonant_modifiers
 	consonant_modifiers
-	h
+	IS
 ;
 ;
 virama_terminated_cluster =
 virama_terminated_cluster =
 	complex_syllable_start
 	complex_syllable_start
@@ -117,27 +119,28 @@ standard_cluster =
 	complex_syllable_start
 	complex_syllable_start
 	complex_syllable_tail
 	complex_syllable_tail
 ;
 ;
+tail = complex_syllable_tail | sakot_terminated_cluster_tail | symbol_cluster_tail | virama_terminated_cluster_tail;
 broken_cluster =
 broken_cluster =
 	R?
 	R?
-	(complex_syllable_tail | number_joiner_terminated_cluster_tail | numeral_cluster_tail | symbol_cluster_tail | virama_terminated_cluster_tail | sakot_terminated_cluster_tail)
+	(tail | number_joiner_terminated_cluster_tail | numeral_cluster_tail)
 ;
 ;
 
 
 number_joiner_terminated_cluster = N number_joiner_terminated_cluster_tail;
 number_joiner_terminated_cluster = N number_joiner_terminated_cluster_tail;
 numeral_cluster = N numeral_cluster_tail?;
 numeral_cluster = N numeral_cluster_tail?;
-symbol_cluster = (O | GB) symbol_cluster_tail?;
+symbol_cluster = (O | GB) tail?;
 hieroglyph_cluster = SB+ | SB* G SE* (J SE* (G SE*)?)*;
 hieroglyph_cluster = SB+ | SB* G SE* (J SE* (G SE*)?)*;
 
 
 other = any;
 other = any;
 
 
 main := |*
 main := |*
-	virama_terminated_cluster		=> { foundSyllableUSE (useViramaTerminatedCluster,data, ts, te, info, &syllableSerial); };
-	sakot_terminated_cluster		=> { foundSyllableUSE (useSakotTerminatedCluster,data, ts, te, info, &syllableSerial); };
-	standard_cluster			=> { foundSyllableUSE (useStandardCluster,data, ts, te, info, &syllableSerial); };
-	number_joiner_terminated_cluster	=> { foundSyllableUSE (useNumberJoinerTerminatedCluster,data, ts, te, info, &syllableSerial); };
-	numeral_cluster				=> { foundSyllableUSE (useNumeralCluster,data, ts, te, info, &syllableSerial); };
-	symbol_cluster				=> { foundSyllableUSE (useSymbolCluster,data, ts, te, info, &syllableSerial); };
-	hieroglyph_cluster			=> { foundSyllableUSE (useHieroglyphCluster,data, ts, te, info, &syllableSerial); };
-	broken_cluster				=> { foundSyllableUSE (useBrokenCluster,data, ts, te, info, &syllableSerial); };
+	virama_terminated_cluster ZWNJ?		=> { foundSyllableUSE (useViramaTerminatedCluster,data, ts, te, info, &syllableSerial); };
+	sakot_terminated_cluster ZWNJ?		=> { foundSyllableUSE (useSakotTerminatedCluster,data, ts, te, info, &syllableSerial); };
+	standard_cluster ZWNJ?			=> { foundSyllableUSE (useStandardCluster,data, ts, te, info, &syllableSerial); };
+	number_joiner_terminated_cluster ZWNJ?	=> { foundSyllableUSE (useNumberJoinerTerminatedCluster,data, ts, te, info, &syllableSerial); };
+	numeral_cluster ZWNJ?				=> { foundSyllableUSE (useNumeralCluster,data, ts, te, info, &syllableSerial); };
+	symbol_cluster ZWNJ?				=> { foundSyllableUSE (useSymbolCluster,data, ts, te, info, &syllableSerial); };
+	hieroglyph_cluster ZWNJ?			=> { foundSyllableUSE (useHieroglyphCluster,data, ts, te, info, &syllableSerial); };
+	broken_cluster ZWNJ?				=> { foundSyllableUSE (useBrokenCluster,data, ts, te, info, &syllableSerial); buffer.scratchFlags |= bsfHasBrokenSyllable; };
 	other					=> { foundSyllableUSE (useNonCluster,data, ts, te, info, &syllableSerial); };
 	other					=> { foundSyllableUSE (useNonCluster,data, ts, te, info, &syllableSerial); };
 *|;
 *|;
 
 

+ 2 - 2
vendor/github.com/go-text/typesetting/harfbuzz/ot_use_machine_defs.go

@@ -3,7 +3,7 @@ package harfbuzz
 // logic needed by the USE rl parser
 // logic needed by the USE rl parser
 
 
 func notCCSDefaultIgnorable(i GlyphInfo) bool {
 func notCCSDefaultIgnorable(i GlyphInfo) bool {
-	return !(i.complexCategory == useSyllableMachine_ex_CGJ && i.isDefaultIgnorable())
+	return i.complexCategory != useSM_ex_CGJ
 }
 }
 
 
 type pairUSE struct {
 type pairUSE struct {
@@ -18,7 +18,7 @@ type machineIndexUSE struct {
 
 
 func preprocessInfoUSE(info []GlyphInfo) []machineIndexUSE {
 func preprocessInfoUSE(info []GlyphInfo) []machineIndexUSE {
 	filterMark := func(p pairUSE) bool {
 	filterMark := func(p pairUSE) bool {
-		if p.v.complexCategory == useSyllableMachine_ex_ZWNJ {
+		if p.v.complexCategory == useSM_ex_ZWNJ {
 			for i := p.i + 1; i < len(info); i++ {
 			for i := p.i + 1; i < len(info); i++ {
 				if notCCSDefaultIgnorable(info[i]) {
 				if notCCSDefaultIgnorable(info[i]) {
 					return !info[i].isUnicodeMark()
 					return !info[i].isUnicodeMark()

La diferencia del archivo ha sido suprimido porque es demasiado grande
+ 386 - 335
vendor/github.com/go-text/typesetting/harfbuzz/ot_use_table.go


+ 28 - 1
vendor/github.com/go-text/typesetting/harfbuzz/ot_vowels_constraints.go

@@ -1,8 +1,10 @@
+// SPDX-License-Identifier: Unlicense OR BSD-3-Clause
+
 package harfbuzz
 package harfbuzz
 
 
 import "github.com/go-text/typesetting/language"
 import "github.com/go-text/typesetting/language"
 
 
-// Code generated by unicodedata/generate/main.go DO NOT EDIT.
+// Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
 
 
 func outputDottedCircle(buffer *Buffer) {
 func outputDottedCircle(buffer *Buffer) {
 	buffer.outputRune(0x25CC)
 	buffer.outputRune(0x25CC)
@@ -243,6 +245,31 @@ func preprocessTextVowelConstraints(buffer *Buffer) {
 				matched = 0x11042 == buffer.cur(1).codepoint
 				matched = 0x11042 == buffer.cur(1).codepoint
 			}
 			}
 
 
+			buffer.nextGlyph()
+			if matched {
+				outputWithDottedCircle(buffer)
+			}
+		}
+	case language.Khojki:
+		for buffer.idx = 0; buffer.idx+1 < count; {
+			matched := false
+			switch buffer.cur(0).codepoint {
+			case 0x11200:
+				switch buffer.cur(1).codepoint {
+				case 0x1122C, 0x11231, 0x11233:
+					matched = true
+				}
+			case 0x11206:
+				matched = 0x1122C == buffer.cur(1).codepoint
+			case 0x1122C:
+				switch buffer.cur(1).codepoint {
+				case 0x11230, 0x11231:
+					matched = true
+				}
+			case 0x11240:
+				matched = 0x1122E == buffer.cur(1).codepoint
+			}
+
 			buffer.nextGlyph()
 			buffer.nextGlyph()
 			if matched {
 			if matched {
 				outputWithDottedCircle(buffer)
 				outputWithDottedCircle(buffer)

+ 17 - 9
vendor/github.com/go-text/typesetting/harfbuzz/set_digest.go

@@ -10,21 +10,21 @@ const maskBits = 4 * 8 // 4 = size(setDigestLowestBits)
 
 
 type setType = gID
 type setType = gID
 
 
-type setDigestLowestBits uint32
+type setBits uint32
 
 
-func maskFor(g setType, shift uint) setDigestLowestBits {
+func maskFor(g setType, shift uint) setBits {
 	return 1 << ((g >> shift) & (maskBits - 1))
 	return 1 << ((g >> shift) & (maskBits - 1))
 }
 }
 
 
-func (sd *setDigestLowestBits) add(g setType, shift uint) { *sd |= maskFor(g, shift) }
+func (sd *setBits) add(g setType, shift uint) { *sd |= maskFor(g, shift) }
 
 
-func (sd *setDigestLowestBits) addRange(a, b setType, shift uint) {
+func (sd *setBits) addRange(a, b setType, shift uint) {
 	if (b>>shift)-(a>>shift) >= maskBits-1 {
 	if (b>>shift)-(a>>shift) >= maskBits-1 {
-		*sd = ^setDigestLowestBits(0)
+		*sd = ^setBits(0)
 	} else {
 	} else {
 		mb := maskFor(b, shift)
 		mb := maskFor(b, shift)
 		ma := maskFor(a, shift)
 		ma := maskFor(a, shift)
-		var op setDigestLowestBits
+		var op setBits
 		if mb < ma {
 		if mb < ma {
 			op = 1
 			op = 1
 		}
 		}
@@ -32,16 +32,20 @@ func (sd *setDigestLowestBits) addRange(a, b setType, shift uint) {
 	}
 	}
 }
 }
 
 
-func (sd *setDigestLowestBits) addArray(arr []setType, shift uint) {
+func (sd *setBits) addArray(arr []setType, shift uint) {
 	for _, v := range arr {
 	for _, v := range arr {
 		sd.add(v, shift)
 		sd.add(v, shift)
 	}
 	}
 }
 }
 
 
-func (sd setDigestLowestBits) mayHave(g setType, shift uint) bool {
+func (sd setBits) mayHave(g setType, shift uint) bool {
 	return sd&maskFor(g, shift) != 0
 	return sd&maskFor(g, shift) != 0
 }
 }
 
 
+func (sd setBits) mayHaveSet(g setBits) bool {
+	return sd&g != 0
+}
+
 /* This is a combination of digests that performs "best".
 /* This is a combination of digests that performs "best".
  * There is not much science to this: it's a result of intuition
  * There is not much science to this: it's a result of intuition
  * and testing. */
  * and testing. */
@@ -64,7 +68,7 @@ const (
 // The frozen-set can be used instead of a digest, to trade more
 // The frozen-set can be used instead of a digest, to trade more
 // memory for 100% accuracy, but in practice, that doesn't look like
 // memory for 100% accuracy, but in practice, that doesn't look like
 // an attractive trade-off.
 // an attractive trade-off.
-type setDigest [3]setDigestLowestBits
+type setDigest [3]setBits
 
 
 // add adds the given rune to the set.
 // add adds the given rune to the set.
 func (sd *setDigest) add(g setType) {
 func (sd *setDigest) add(g setType) {
@@ -97,6 +101,10 @@ func (sd setDigest) mayHave(g setType) bool {
 	return sd[0].mayHave(g, shift0) && sd[1].mayHave(g, shift1) && sd[2].mayHave(g, shift2)
 	return sd[0].mayHave(g, shift0) && sd[1].mayHave(g, shift1) && sd[2].mayHave(g, shift2)
 }
 }
 
 
+func (sd setDigest) mayHaveDigest(o setDigest) bool {
+	return sd[0].mayHaveSet(o[0]) && sd[1].mayHaveSet(o[1]) && sd[2].mayHaveSet(o[2])
+}
+
 func (sd *setDigest) collectCoverage(cov tables.Coverage) {
 func (sd *setDigest) collectCoverage(cov tables.Coverage) {
 	switch cov := cov.(type) {
 	switch cov := cov.(type) {
 	case tables.Coverage1:
 	case tables.Coverage1:

+ 7 - 16
vendor/github.com/go-text/typesetting/harfbuzz/shape.go

@@ -29,14 +29,6 @@ func (b *Buffer) Shape(font *Font, features []Feature) {
 	shapePlan.execute(font, b, features)
 	shapePlan.execute(font, b, features)
 }
 }
 
 
-type shaperKind uint8
-
-const (
-	skFallback shaperKind = iota
-	skOpentype
-	skGraphite
-)
-
 // Shape plans are an internal mechanism. Each plan contains state
 // Shape plans are an internal mechanism. Each plan contains state
 // describing how HarfBuzz will shape a particular text segment, based on
 // describing how HarfBuzz will shape a particular text segment, based on
 // the combination of segment properties and the capabilities in the
 // the combination of segment properties and the capabilities in the
@@ -92,8 +84,7 @@ func (plan shapePlan) userFeaturesMatch(other shapePlan) bool {
 }
 }
 
 
 func (plan shapePlan) equal(other shapePlan) bool {
 func (plan shapePlan) equal(other shapePlan) bool {
-	return plan.props == other.props &&
-		plan.userFeaturesMatch(other) && plan.shaper.kind() == other.shaper.kind()
+	return plan.props == other.props && plan.userFeaturesMatch(other)
 }
 }
 
 
 // Constructs a shaping plan for a combination of @face, @userFeatures, @props,
 // Constructs a shaping plan for a combination of @face, @userFeatures, @props,
@@ -102,7 +93,7 @@ func (plan shapePlan) equal(other shapePlan) bool {
 func newShapePlan(font *Font, props SegmentProperties,
 func newShapePlan(font *Font, props SegmentProperties,
 	userFeatures []Feature, coords []float32,
 	userFeatures []Feature, coords []float32,
 ) *shapePlan {
 ) *shapePlan {
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Printf("NEW SHAPE PLAN: face:%p features:%v coords:%v\n", &font.face, userFeatures, coords)
 		fmt.Printf("NEW SHAPE PLAN: face:%p features:%v coords:%v\n", &font.face, userFeatures, coords)
 	}
 	}
 
 
@@ -110,7 +101,7 @@ func newShapePlan(font *Font, props SegmentProperties,
 
 
 	sp.init(true, font, props, userFeatures, coords)
 	sp.init(true, font, props, userFeatures, coords)
 
 
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Println("NEW SHAPE PLAN - compiling shaper plan")
 		fmt.Println("NEW SHAPE PLAN - compiling shaper plan")
 	}
 	}
 	sp.shaper.compile(props, userFeatures)
 	sp.shaper.compile(props, userFeatures)
@@ -121,8 +112,8 @@ func newShapePlan(font *Font, props SegmentProperties,
 // Executes the given shaping plan on the specified `buffer`, using
 // Executes the given shaping plan on the specified `buffer`, using
 // the given `font` and `features`.
 // the given `font` and `features`.
 func (sp *shapePlan) execute(font *Font, buffer *Buffer, features []Feature) {
 func (sp *shapePlan) execute(font *Font, buffer *Buffer, features []Feature) {
-	if debugMode >= 1 {
-		fmt.Printf("EXECUTE shape plan %p features:%v shaper:%T\n", sp, features, sp.shaper)
+	if debugMode {
+		fmt.Printf("EXECUTE shape plan %p features:%v shaper:%T\n", sp, features, sp.shaper.plan.shaper)
 	}
 	}
 
 
 	sp.shaper.shape(font, buffer, features)
 	sp.shaper.shape(font, buffer, features)
@@ -144,7 +135,7 @@ func (b *Buffer) newShapePlanCached(font *Font, props SegmentProperties,
 
 
 	for _, plan := range plans {
 	for _, plan := range plans {
 		if plan.equal(key) {
 		if plan.equal(key) {
-			if debugMode >= 1 {
+			if debugMode {
 				fmt.Printf("\tPLAN %p fulfilled from cache\n", plan)
 				fmt.Printf("\tPLAN %p fulfilled from cache\n", plan)
 			}
 			}
 			return plan
 			return plan
@@ -155,7 +146,7 @@ func (b *Buffer) newShapePlanCached(font *Font, props SegmentProperties,
 	plans = append(plans, plan)
 	plans = append(plans, plan)
 	b.planCache[font.face] = plans
 	b.planCache[font.face] = plans
 
 
-	if debugMode >= 1 {
+	if debugMode {
 		fmt.Printf("\tPLAN %p inserted into cache\n", plan)
 		fmt.Printf("\tPLAN %p inserted into cache\n", plan)
 	}
 	}
 
 

+ 85 - 75
vendor/github.com/go-text/typesetting/harfbuzz/unicode.go

@@ -3,7 +3,7 @@ package harfbuzz
 import (
 import (
 	"unicode"
 	"unicode"
 
 
-	"github.com/go-text/typesetting/unicodedata"
+	ucd "github.com/go-text/typesetting/unicodedata"
 )
 )
 
 
 // uni exposes some lookup functions for Unicode properties.
 // uni exposes some lookup functions for Unicode properties.
@@ -47,36 +47,36 @@ const (
 
 
 // correspondance with *unicode.RangeTable classes
 // correspondance with *unicode.RangeTable classes
 var generalCategories = [...]*unicode.RangeTable{
 var generalCategories = [...]*unicode.RangeTable{
-	control:            unicode.Cc,
-	format:             unicode.Cf,
+	control:            ucd.Cc,
+	format:             ucd.Cf,
 	unassigned:         nil,
 	unassigned:         nil,
-	privateUse:         unicode.Co,
-	surrogate:          unicode.Cs,
-	lowercaseLetter:    unicode.Ll,
-	modifierLetter:     unicode.Lm,
-	otherLetter:        unicode.Lo,
-	titlecaseLetter:    unicode.Lt,
-	uppercaseLetter:    unicode.Lu,
-	spacingMark:        unicode.Mc,
-	enclosingMark:      unicode.Me,
-	nonSpacingMark:     unicode.Mn,
-	decimalNumber:      unicode.Nd,
-	letterNumber:       unicode.Nl,
-	otherNumber:        unicode.No,
-	connectPunctuation: unicode.Pc,
-	dashPunctuation:    unicode.Pd,
-	closePunctuation:   unicode.Pe,
-	finalPunctuation:   unicode.Pf,
-	initialPunctuation: unicode.Pi,
-	otherPunctuation:   unicode.Po,
-	openPunctuation:    unicode.Ps,
-	currencySymbol:     unicode.Sc,
-	modifierSymbol:     unicode.Sk,
-	mathSymbol:         unicode.Sm,
-	otherSymbol:        unicode.So,
-	lineSeparator:      unicode.Zl,
-	paragraphSeparator: unicode.Zp,
-	spaceSeparator:     unicode.Zs,
+	privateUse:         ucd.Co,
+	surrogate:          ucd.Cs,
+	lowercaseLetter:    ucd.Ll,
+	modifierLetter:     ucd.Lm,
+	otherLetter:        ucd.Lo,
+	titlecaseLetter:    ucd.Lt,
+	uppercaseLetter:    ucd.Lu,
+	spacingMark:        ucd.Mc,
+	enclosingMark:      ucd.Me,
+	nonSpacingMark:     ucd.Mn,
+	decimalNumber:      ucd.Nd,
+	letterNumber:       ucd.Nl,
+	otherNumber:        ucd.No,
+	connectPunctuation: ucd.Pc,
+	dashPunctuation:    ucd.Pd,
+	closePunctuation:   ucd.Pe,
+	finalPunctuation:   ucd.Pf,
+	initialPunctuation: ucd.Pi,
+	otherPunctuation:   ucd.Po,
+	openPunctuation:    ucd.Ps,
+	currencySymbol:     ucd.Sc,
+	modifierSymbol:     ucd.Sk,
+	mathSymbol:         ucd.Sm,
+	otherSymbol:        ucd.So,
+	lineSeparator:      ucd.Zl,
+	paragraphSeparator: ucd.Zp,
+	spaceSeparator:     ucd.Zs,
 }
 }
 
 
 func (g generalCategory) isMark() bool {
 func (g generalCategory) isMark() bool {
@@ -286,14 +286,12 @@ var modifiedCombiningClass = [256]uint8{
 type unicodeFuncs struct{}
 type unicodeFuncs struct{}
 
 
 func (unicodeFuncs) modifiedCombiningClass(u rune) uint8 {
 func (unicodeFuncs) modifiedCombiningClass(u rune) uint8 {
-	/* This hack belongs to the USE shaper (for Tai Tham):
-	 * Reorder SAKOT to ensure it comes after any tone marks. */
+	// Reorder SAKOT to ensure it comes after any tone marks.
 	if u == 0x1A60 {
 	if u == 0x1A60 {
 		return 254
 		return 254
 	}
 	}
 
 
-	/* This hack belongs to the Tibetan shaper:
-	 * Reorder PADMA to ensure it comes after any vowel marks. */
+	// Reorder PADMA to ensure it comes after any vowel marks.
 	if u == 0x0FC6 {
 	if u == 0x0FC6 {
 		return 254
 		return 254
 	}
 	}
@@ -301,7 +299,7 @@ func (unicodeFuncs) modifiedCombiningClass(u rune) uint8 {
 	if u == 0x0F39 {
 	if u == 0x0F39 {
 		return 127
 		return 127
 	}
 	}
-	return modifiedCombiningClass[unicodedata.LookupCombiningClass(u)]
+	return modifiedCombiningClass[ucd.LookupCombiningClass(u)]
 }
 }
 
 
 // IsDefaultIgnorable returns `true` for
 // IsDefaultIgnorable returns `true` for
@@ -368,13 +366,13 @@ func (unicodeFuncs) generalCategory(ch rune) generalCategory {
 }
 }
 
 
 func (unicodeFuncs) isExtendedPictographic(ch rune) bool {
 func (unicodeFuncs) isExtendedPictographic(ch rune) bool {
-	return unicode.Is(unicodedata.Extended_Pictographic, ch)
+	return unicode.Is(ucd.Extended_Pictographic, ch)
 }
 }
 
 
 // returns the mirroring Glyph code point (for bi-directional
 // returns the mirroring Glyph code point (for bi-directional
 // replacement) of a code point, or itself
 // replacement) of a code point, or itself
 func (unicodeFuncs) mirroring(ch rune) rune {
 func (unicodeFuncs) mirroring(ch rune) rune {
-	out, _ := unicodedata.LookupMirrorChar(ch)
+	out, _ := ucd.LookupMirrorChar(ch)
 	return out
 	return out
 }
 }
 
 
@@ -446,32 +444,34 @@ func (unicodeFuncs) isVariationSelector(r rune) bool {
 	return (0xFE00 <= r && r <= 0xFE0F) || (0xE0100 <= r && r <= 0xE01EF)
 	return (0xFE00 <= r && r <= 0xFE0F) || (0xE0100 <= r && r <= 0xE01EF)
 }
 }
 
 
-func (unicodeFuncs) decompose(ab rune) (a, b rune, ok bool) { return unicodedata.Decompose(ab) }
-func (unicodeFuncs) compose(a, b rune) (rune, bool)         { return unicodedata.Compose(a, b) }
+func (unicodeFuncs) decompose(ab rune) (a, b rune, ok bool) { return ucd.Decompose(ab) }
+func (unicodeFuncs) compose(a, b rune) (rune, bool)         { return ucd.Compose(a, b) }
 
 
 /* Prepare */
 /* Prepare */
 
 
-/* Implement enough of Unicode Graphemes here that shaping
- * in reverse-direction wouldn't break graphemes.  Namely,
- * we mark all marks and ZWJ and ZWJ,Extended_Pictographic
- * sequences as continuations.  The foreach_grapheme()
- * macro uses this bit.
- *
- * https://www.unicode.org/reports/tr29/#Regex_Definitions
- */
+func isRegionalIndicator(r rune) bool { return 0x1F1E6 <= r && r <= 0x1F1FF }
+
+// Implement enough of Unicode Graphemes here that shaping
+// in reverse-direction wouldn't break graphemes.  Namely,
+// we mark all marks and ZWJ and ZWJ,Extended_Pictographic
+// sequences as continuations.  The foreach_grapheme()
+// macro uses this bit.
+//
+// https://www.unicode.org/reports/tr29/#Regex_Definitions
 func (b *Buffer) setUnicodeProps() {
 func (b *Buffer) setUnicodeProps() {
 	info := b.Info
 	info := b.Info
 	for i := 0; i < len(info); i++ {
 	for i := 0; i < len(info); i++ {
+		r := info[i].codepoint
 		info[i].setUnicodeProps(b)
 		info[i].setUnicodeProps(b)
 
 
 		/* Marks are already set as continuation by the above line.
 		/* Marks are already set as continuation by the above line.
 		 * Handle Emoji_Modifier and ZWJ-continuation. */
 		 * Handle Emoji_Modifier and ZWJ-continuation. */
-		if info[i].unicode.generalCategory() == modifierSymbol && (0x1F3FB <= info[i].codepoint && info[i].codepoint <= 0x1F3FF) {
+		if info[i].unicode.generalCategory() == modifierSymbol && (0x1F3FB <= r && r <= 0x1F3FF) {
 			info[i].setContinuation()
 			info[i].setContinuation()
-		} else if i != 0 && 0x1F1E6 <= info[i].codepoint && info[i].codepoint <= 0x1F1FF {
+		} else if i != 0 && isRegionalIndicator(r) {
 			/* Regional_Indicators are hairy as hell...
 			/* Regional_Indicators are hairy as hell...
 			* https://github.com/harfbuzz/harfbuzz/issues/2265 */
 			* https://github.com/harfbuzz/harfbuzz/issues/2265 */
-			if 0x1F1E6 <= info[i-1].codepoint && info[i-1].codepoint <= 0x1F1FF && !info[i-1].isContinuation() {
+			if isRegionalIndicator(info[i-1].codepoint) && !info[i-1].isContinuation() {
 				info[i].setContinuation()
 				info[i].setContinuation()
 			}
 			}
 		} else if info[i].isZwj() {
 		} else if info[i].isZwj() {
@@ -481,19 +481,20 @@ func (b *Buffer) setUnicodeProps() {
 				info[i].setUnicodeProps(b)
 				info[i].setUnicodeProps(b)
 				info[i].setContinuation()
 				info[i].setContinuation()
 			}
 			}
-		} else if 0xE0020 <= info[i].codepoint && info[i].codepoint <= 0xE007F {
-			/* Or part of the Other_Grapheme_Extend that is not marks.
-			 * As of Unicode 11 that is just:
-			 *
-			 * 200C          ; Other_Grapheme_Extend # Cf       ZERO WIDTH NON-JOINER
-			 * FF9E..FF9F    ; Other_Grapheme_Extend # Lm   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
-			 * E0020..E007F  ; Other_Grapheme_Extend # Cf  [96] TAG SPACE..CANCEL TAG
-			 *
-			 * ZWNJ is special, we don't want to merge it as there's no need, and keeping
-			 * it separate results in more granular clusters.  Ignore Katakana for now.
-			 * Tags are used for Emoji sub-region flag sequences:
-			 * https://github.com/harfbuzz/harfbuzz/issues/1556
-			 */
+		} else if (0xFF9E <= r && r <= 0xFF9F) || (0xE0020 <= r && r <= 0xE007F) {
+			// Or part of the Other_Grapheme_Extend that is not marks.
+			// As of Unicode 15 that is just:
+			//
+			// 200C          ; Other_Grapheme_Extend # Cf       ZERO WIDTH NON-JOINER
+			// FF9E..FF9F    ; Other_Grapheme_Extend # Lm   [2] HALFWIDTH KATAKANA VOICED SOUND MARK..HALFWIDTH KATAKANA SEMI-VOICED SOUND MARK
+			// E0020..E007F  ; Other_Grapheme_Extend # Cf  [96] TAG SPACE..CANCEL TAG
+			//
+			// ZWNJ is special, we don't want to merge it as there's no need, and keeping
+			// it separate results in more granular clusters.
+			// Tags are used for Emoji sub-region flag sequences:
+			// https://github.com/harfbuzz/harfbuzz/issues/1556
+			// Katakana ones were requested:
+			// https://github.com/harfbuzz/harfbuzz/issues/3844
 			info[i].setContinuation()
 			info[i].setContinuation()
 		}
 		}
 	}
 	}
@@ -547,19 +548,26 @@ func (b *Buffer) ensureNativeDirection() {
 	direction := b.Props.Direction
 	direction := b.Props.Direction
 	horizDir := getHorizontalDirection(b.Props.Script)
 	horizDir := getHorizontalDirection(b.Props.Script)
 
 
-	/* Numeric runs in natively-RTL scripts are actually native-LTR, so we reset
-	 * the horiz_dir if the run contains at least one decimal-number char, and no
-	 * letter chars (ideally we should be checking for chars with strong
-	 * directionality but hb-unicode currently lacks bidi categories).
-	 *
-	 * This allows digit sequences in Arabic etc to be shaped in "native"
-	 * direction, so that features like ligatures will work as intended.
-	 *
-	 * https://github.com/harfbuzz/harfbuzz/issues/501
-	 */
+	// Numeric runs in natively-RTL scripts are actually native-LTR, so we reset
+	// the horiz_dir if the run contains at least one decimal-number char, and no
+	// letter chars (ideally we should be checking for chars with strong
+	// directionality but hb-unicode currently lacks bidi categories).
+	//
+	// This allows digit sequences in Arabic etc to be shaped in "native"
+	// direction, so that features like ligatures will work as intended.
+	//
+	// https://github.com/harfbuzz/harfbuzz/issues/501
+	//
+	// Similar thing about Regional_Indicators; They are bidi=L, but Script=Common.
+	// If they are present in a run of natively-RTL text, they get assigned a script
+	// with natively RTL direction, which would result in wrong shaping if we
+	// assign such native RTL direction to them then. Detect that as well.
+	//
+	// https://github.com/harfbuzz/harfbuzz/issues/3314
+	//
 
 
 	if horizDir == RightToLeft && direction == LeftToRight {
 	if horizDir == RightToLeft && direction == LeftToRight {
-		var foundNumber, foundLetter bool
+		var foundNumber, foundLetter, foundRi bool
 		for _, info := range b.Info {
 		for _, info := range b.Info {
 			gc := info.unicode.generalCategory()
 			gc := info.unicode.generalCategory()
 			if gc == decimalNumber {
 			if gc == decimalNumber {
@@ -567,9 +575,11 @@ func (b *Buffer) ensureNativeDirection() {
 			} else if gc.isLetter() {
 			} else if gc.isLetter() {
 				foundLetter = true
 				foundLetter = true
 				break
 				break
+			} else if isRegionalIndicator(info.codepoint) {
+				foundRi = true
 			}
 			}
 		}
 		}
-		if foundNumber && !foundLetter {
+		if (foundNumber || foundRi) && !foundLetter {
 			horizDir = LeftToRight
 			horizDir = LeftToRight
 		}
 		}
 	}
 	}

+ 7 - 6
vendor/github.com/go-text/typesetting/language/scripts.go

@@ -12,8 +12,9 @@ import (
 type Script uint32
 type Script uint32
 
 
 // ParseScript simply converts a 4 bytes string into its binary encoding.
 // ParseScript simply converts a 4 bytes string into its binary encoding.
+// If [script] is longer, only its 4 first bytes are used.
 func ParseScript(script string) (Script, error) {
 func ParseScript(script string) (Script, error) {
-	if len(script) != 4 {
+	if len(script) < 4 {
 		return 0, fmt.Errorf("invalid script string: %s", script)
 		return 0, fmt.Errorf("invalid script string: %s", script)
 	}
 	}
 	return Script(binary.BigEndian.Uint32([]byte(script))), nil
 	return Script(binary.BigEndian.Uint32([]byte(script))), nil
@@ -23,15 +24,15 @@ func ParseScript(script string) (Script, error) {
 // Unicode Standard Annex #24), and returns Unknown if not found.
 // Unicode Standard Annex #24), and returns Unknown if not found.
 func LookupScript(r rune) Script {
 func LookupScript(r rune) Script {
 	// binary search
 	// binary search
-	for i, j := 0, len(scriptRanges); i < j; {
+	for i, j := 0, len(ScriptRanges); i < j; {
 		h := i + (j-i)/2
 		h := i + (j-i)/2
-		entry := scriptRanges[h]
-		if r < entry.start {
+		entry := ScriptRanges[h]
+		if r < entry.Start {
 			j = h
 			j = h
-		} else if entry.end < r {
+		} else if entry.End < r {
 			i = h + 1
 			i = h + 1
 		} else {
 		} else {
-			return entry.script
+			return entry.Script
 		}
 		}
 	}
 	}
 	return Unknown
 	return Unknown

+ 1335 - 1232
vendor/github.com/go-text/typesetting/language/scripts_table.go

@@ -5,1243 +5,1346 @@ package language
 // Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
 // Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
 
 
 const (
 const (
-	Adlam                  = Script(0x61646c6d)
-	Ahom                   = Script(0x61686f6d)
-	Anatolian_Hieroglyphs  = Script(0x686c7577)
-	Arabic                 = Script(0x61726162)
-	Armenian               = Script(0x61726d6e)
-	Avestan                = Script(0x61767374)
-	Balinese               = Script(0x62616c69)
-	Bamum                  = Script(0x62616d75)
-	Bassa_Vah              = Script(0x62617373)
-	Batak                  = Script(0x6261746b)
-	Bengali                = Script(0x62656e67)
-	Bhaiksuki              = Script(0x62686b73)
-	Bopomofo               = Script(0x626f706f)
-	Brahmi                 = Script(0x62726168)
-	Braille                = Script(0x62726169)
-	Buginese               = Script(0x62756769)
-	Buhid                  = Script(0x62756864)
-	Canadian_Aboriginal    = Script(0x63616e73)
-	Carian                 = Script(0x63617269)
-	Caucasian_Albanian     = Script(0x61676862)
-	Chakma                 = Script(0x63616b6d)
-	Cham                   = Script(0x6368616d)
-	Cherokee               = Script(0x63686572)
-	Chorasmian             = Script(0x63687273)
-	Common                 = Script(0x7a797979)
-	Coptic                 = Script(0x636f7074)
-	Cuneiform              = Script(0x78737578)
-	Cypriot                = Script(0x63707274)
-	Cyrillic               = Script(0x6379726c)
-	Deseret                = Script(0x64737274)
-	Devanagari             = Script(0x64657661)
-	Dives_Akuru            = Script(0x6469616b)
-	Dogra                  = Script(0x646f6772)
-	Duployan               = Script(0x6475706c)
-	Egyptian_Hieroglyphs   = Script(0x65677970)
-	Elbasan                = Script(0x656c6261)
-	Elymaic                = Script(0x656c796d)
-	Ethiopic               = Script(0x65746869)
-	Georgian               = Script(0x67656f72)
-	Glagolitic             = Script(0x676c6167)
-	Gothic                 = Script(0x676f7468)
-	Grantha                = Script(0x6772616e)
-	Greek                  = Script(0x6772656b)
-	Gujarati               = Script(0x67756a72)
-	Gunjala_Gondi          = Script(0x676f6e67)
-	Gurmukhi               = Script(0x67757275)
-	Han                    = Script(0x68616e69)
-	Hangul                 = Script(0x68616e67)
-	Hanifi_Rohingya        = Script(0x726f6867)
-	Hanunoo                = Script(0x68616e6f)
-	Hatran                 = Script(0x68617472)
-	Hebrew                 = Script(0x68656272)
-	Hiragana               = Script(0x68697261)
-	Imperial_Aramaic       = Script(0x61726d69)
-	Inherited              = Script(0x7a696e68)
-	Inscriptional_Pahlavi  = Script(0x70686c69)
-	Inscriptional_Parthian = Script(0x70727469)
-	Javanese               = Script(0x6a617661)
-	Kaithi                 = Script(0x6b746869)
-	Kannada                = Script(0x6b6e6461)
-	Katakana               = Script(0x6b616e61)
-	Katakana_Or_Hiragana   = Script(0x68726b74)
-	Kayah_Li               = Script(0x6b616c69)
-	Kharoshthi             = Script(0x6b686172)
-	Khitan_Small_Script    = Script(0x6b697473)
-	Khmer                  = Script(0x6b686d72)
-	Khojki                 = Script(0x6b686f6a)
-	Khudawadi              = Script(0x73696e64)
-	Lao                    = Script(0x6c616f6f)
-	Latin                  = Script(0x6c61746e)
-	Lepcha                 = Script(0x6c657063)
-	Limbu                  = Script(0x6c696d62)
-	Linear_A               = Script(0x6c696e61)
-	Linear_B               = Script(0x6c696e62)
-	Lisu                   = Script(0x6c697375)
-	Lycian                 = Script(0x6c796369)
-	Lydian                 = Script(0x6c796469)
-	Mahajani               = Script(0x6d61686a)
-	Makasar                = Script(0x6d616b61)
-	Malayalam              = Script(0x6d6c796d)
-	Mandaic                = Script(0x6d616e64)
-	Manichaean             = Script(0x6d616e69)
-	Marchen                = Script(0x6d617263)
-	Masaram_Gondi          = Script(0x676f6e6d)
-	Medefaidrin            = Script(0x6d656466)
-	Meetei_Mayek           = Script(0x6d746569)
-	Mende_Kikakui          = Script(0x6d656e64)
-	Meroitic_Cursive       = Script(0x6d657263)
-	Meroitic_Hieroglyphs   = Script(0x6d65726f)
-	Miao                   = Script(0x706c7264)
-	Modi                   = Script(0x6d6f6469)
-	Mongolian              = Script(0x6d6f6e67)
-	Mro                    = Script(0x6d726f6f)
-	Multani                = Script(0x6d756c74)
-	Myanmar                = Script(0x6d796d72)
-	Nabataean              = Script(0x6e626174)
-	Nandinagari            = Script(0x6e616e64)
-	New_Tai_Lue            = Script(0x74616c75)
-	Newa                   = Script(0x6e657761)
-	Nko                    = Script(0x6e6b6f6f)
-	Nushu                  = Script(0x6e736875)
-	Nyiakeng_Puachue_Hmong = Script(0x686d6e70)
-	Ogham                  = Script(0x6f67616d)
-	Ol_Chiki               = Script(0x6f6c636b)
-	Old_Hungarian          = Script(0x68756e67)
-	Old_Italic             = Script(0x6974616c)
-	Old_North_Arabian      = Script(0x6e617262)
-	Old_Permic             = Script(0x7065726d)
-	Old_Persian            = Script(0x7870656f)
-	Old_Sogdian            = Script(0x736f676f)
-	Old_South_Arabian      = Script(0x73617262)
-	Old_Turkic             = Script(0x6f726b68)
-	Oriya                  = Script(0x6f727961)
-	Osage                  = Script(0x6f736765)
-	Osmanya                = Script(0x6f736d61)
-	Pahawh_Hmong           = Script(0x686d6e67)
-	Palmyrene              = Script(0x70616c6d)
-	Pau_Cin_Hau            = Script(0x70617563)
-	Phags_Pa               = Script(0x70686167)
-	Phoenician             = Script(0x70686e78)
-	Psalter_Pahlavi        = Script(0x70686c70)
-	Rejang                 = Script(0x726a6e67)
-	Runic                  = Script(0x72756e72)
-	Samaritan              = Script(0x73616d72)
-	Saurashtra             = Script(0x73617572)
-	Sharada                = Script(0x73687264)
-	Shavian                = Script(0x73686177)
-	Siddham                = Script(0x73696464)
-	SignWriting            = Script(0x73676e77)
-	Sinhala                = Script(0x73696e68)
-	Sogdian                = Script(0x736f6764)
-	Sora_Sompeng           = Script(0x736f7261)
-	Soyombo                = Script(0x736f796f)
-	Sundanese              = Script(0x73756e64)
-	Syloti_Nagri           = Script(0x73796c6f)
-	Syriac                 = Script(0x73797263)
-	Tagalog                = Script(0x74676c67)
-	Tagbanwa               = Script(0x74616762)
-	Tai_Le                 = Script(0x74616c65)
-	Tai_Tham               = Script(0x6c616e61)
-	Tai_Viet               = Script(0x74617674)
-	Takri                  = Script(0x74616b72)
-	Tamil                  = Script(0x74616d6c)
-	Tangut                 = Script(0x74616e67)
-	Telugu                 = Script(0x74656c75)
-	Thaana                 = Script(0x74686161)
-	Thai                   = Script(0x74686169)
-	Tibetan                = Script(0x74696274)
-	Tifinagh               = Script(0x74666e67)
-	Tirhuta                = Script(0x74697268)
-	Ugaritic               = Script(0x75676172)
-	Unknown                = Script(0x7a7a7a7a)
-	Vai                    = Script(0x76616969)
-	Wancho                 = Script(0x7763686f)
-	Warang_Citi            = Script(0x77617261)
-	Yezidi                 = Script(0x79657a69)
-	Yi                     = Script(0x79696969)
-	Zanabazar_Square       = Script(0x7a616e62)
+	Adlam                        = Script(0x61646c6d) // adlm
+	Afaka                        = Script(0x6166616b) // afak
+	Ahom                         = Script(0x61686f6d) // ahom
+	Anatolian_Hieroglyphs        = Script(0x686c7577) // hluw
+	Arabic                       = Script(0x61726162) // arab
+	Armenian                     = Script(0x61726d6e) // armn
+	Avestan                      = Script(0x61767374) // avst
+	Balinese                     = Script(0x62616c69) // bali
+	Bamum                        = Script(0x62616d75) // bamu
+	Bassa_Vah                    = Script(0x62617373) // bass
+	Batak                        = Script(0x6261746b) // batk
+	Bengali                      = Script(0x62656e67) // beng
+	Bhaiksuki                    = Script(0x62686b73) // bhks
+	Blissymbols                  = Script(0x626c6973) // blis
+	Book_Pahlavi                 = Script(0x70686c76) // phlv
+	Bopomofo                     = Script(0x626f706f) // bopo
+	Brahmi                       = Script(0x62726168) // brah
+	Braille                      = Script(0x62726169) // brai
+	Buginese                     = Script(0x62756769) // bugi
+	Buhid                        = Script(0x62756864) // buhd
+	Canadian_Aboriginal          = Script(0x63616e73) // cans
+	Carian                       = Script(0x63617269) // cari
+	Caucasian_Albanian           = Script(0x61676862) // aghb
+	Chakma                       = Script(0x63616b6d) // cakm
+	Cham                         = Script(0x6368616d) // cham
+	Cherokee                     = Script(0x63686572) // cher
+	Chorasmian                   = Script(0x63687273) // chrs
+	Cirth                        = Script(0x63697274) // cirt
+	Code_for_unwritten_documents = Script(0x7a787878) // zxxx
+	Common                       = Script(0x7a797979) // zyyy
+	Coptic                       = Script(0x636f7074) // copt
+	Cuneiform                    = Script(0x78737578) // xsux
+	Cypriot                      = Script(0x63707274) // cprt
+	Cypro_Minoan                 = Script(0x63706d6e) // cpmn
+	Cyrillic                     = Script(0x6379726c) // cyrl
+	Deseret                      = Script(0x64737274) // dsrt
+	Devanagari                   = Script(0x64657661) // deva
+	Dives_Akuru                  = Script(0x6469616b) // diak
+	Dogra                        = Script(0x646f6772) // dogr
+	Duployan                     = Script(0x6475706c) // dupl
+	Egyptian_Hieroglyphs         = Script(0x65677970) // egyp
+	Egyptian_demotic             = Script(0x65677964) // egyd
+	Egyptian_hieratic            = Script(0x65677968) // egyh
+	Elbasan                      = Script(0x656c6261) // elba
+	Elymaic                      = Script(0x656c796d) // elym
+	Ethiopic                     = Script(0x65746869) // ethi
+	Georgian                     = Script(0x67656f72) // geor
+	Glagolitic                   = Script(0x676c6167) // glag
+	Gothic                       = Script(0x676f7468) // goth
+	Grantha                      = Script(0x6772616e) // gran
+	Greek                        = Script(0x6772656b) // grek
+	Gujarati                     = Script(0x67756a72) // gujr
+	Gunjala_Gondi                = Script(0x676f6e67) // gong
+	Gurmukhi                     = Script(0x67757275) // guru
+	Han                          = Script(0x68616e69) // hani
+	Hangul                       = Script(0x68616e67) // hang
+	Hanifi_Rohingya              = Script(0x726f6867) // rohg
+	Hanunoo                      = Script(0x68616e6f) // hano
+	Hatran                       = Script(0x68617472) // hatr
+	Hebrew                       = Script(0x68656272) // hebr
+	Hiragana                     = Script(0x68697261) // hira
+	Imperial_Aramaic             = Script(0x61726d69) // armi
+	Inherited                    = Script(0x7a696e68) // zinh
+	Inscriptional_Pahlavi        = Script(0x70686c69) // phli
+	Inscriptional_Parthian       = Script(0x70727469) // prti
+	Javanese                     = Script(0x6a617661) // java
+	Jurchen                      = Script(0x6a757263) // jurc
+	Kaithi                       = Script(0x6b746869) // kthi
+	Kannada                      = Script(0x6b6e6461) // knda
+	Katakana                     = Script(0x6b616e61) // kana
+	Katakana_Or_Hiragana         = Script(0x68726b74) // hrkt
+	Kawi                         = Script(0x6b617769) // kawi
+	Kayah_Li                     = Script(0x6b616c69) // kali
+	Kharoshthi                   = Script(0x6b686172) // khar
+	Khitan_Small_Script          = Script(0x6b697473) // kits
+	Khitan_large_script          = Script(0x6b69746c) // kitl
+	Khmer                        = Script(0x6b686d72) // khmr
+	Khojki                       = Script(0x6b686f6a) // khoj
+	Khudawadi                    = Script(0x73696e64) // sind
+	Kpelle                       = Script(0x6b70656c) // kpel
+	Lao                          = Script(0x6c616f6f) // laoo
+	Latin                        = Script(0x6c61746e) // latn
+	Leke                         = Script(0x6c656b65) // leke
+	Lepcha                       = Script(0x6c657063) // lepc
+	Limbu                        = Script(0x6c696d62) // limb
+	Linear_A                     = Script(0x6c696e61) // lina
+	Linear_B                     = Script(0x6c696e62) // linb
+	Lisu                         = Script(0x6c697375) // lisu
+	Loma                         = Script(0x6c6f6d61) // loma
+	Lycian                       = Script(0x6c796369) // lyci
+	Lydian                       = Script(0x6c796469) // lydi
+	Mahajani                     = Script(0x6d61686a) // mahj
+	Makasar                      = Script(0x6d616b61) // maka
+	Malayalam                    = Script(0x6d6c796d) // mlym
+	Mandaic                      = Script(0x6d616e64) // mand
+	Manichaean                   = Script(0x6d616e69) // mani
+	Marchen                      = Script(0x6d617263) // marc
+	Masaram_Gondi                = Script(0x676f6e6d) // gonm
+	Mathematical_notation        = Script(0x7a6d7468) // zmth
+	Mayan_hieroglyphs            = Script(0x6d617961) // maya
+	Medefaidrin                  = Script(0x6d656466) // medf
+	Meetei_Mayek                 = Script(0x6d746569) // mtei
+	Mende_Kikakui                = Script(0x6d656e64) // mend
+	Meroitic_Cursive             = Script(0x6d657263) // merc
+	Meroitic_Hieroglyphs         = Script(0x6d65726f) // mero
+	Miao                         = Script(0x706c7264) // plrd
+	Modi                         = Script(0x6d6f6469) // modi
+	Mongolian                    = Script(0x6d6f6e67) // mong
+	Mro                          = Script(0x6d726f6f) // mroo
+	Multani                      = Script(0x6d756c74) // mult
+	Myanmar                      = Script(0x6d796d72) // mymr
+	Nabataean                    = Script(0x6e626174) // nbat
+	Nag_Mundari                  = Script(0x6e61676d) // nagm
+	Nandinagari                  = Script(0x6e616e64) // nand
+	New_Tai_Lue                  = Script(0x74616c75) // talu
+	Newa                         = Script(0x6e657761) // newa
+	Nko                          = Script(0x6e6b6f6f) // nkoo
+	Nushu                        = Script(0x6e736875) // nshu
+	Nyiakeng_Puachue_Hmong       = Script(0x686d6e70) // hmnp
+	Ogham                        = Script(0x6f67616d) // ogam
+	Ol_Chiki                     = Script(0x6f6c636b) // olck
+	Old_Hungarian                = Script(0x68756e67) // hung
+	Old_Italic                   = Script(0x6974616c) // ital
+	Old_North_Arabian            = Script(0x6e617262) // narb
+	Old_Permic                   = Script(0x7065726d) // perm
+	Old_Persian                  = Script(0x7870656f) // xpeo
+	Old_Sogdian                  = Script(0x736f676f) // sogo
+	Old_South_Arabian            = Script(0x73617262) // sarb
+	Old_Turkic                   = Script(0x6f726b68) // orkh
+	Old_Uyghur                   = Script(0x6f756772) // ougr
+	Oriya                        = Script(0x6f727961) // orya
+	Osage                        = Script(0x6f736765) // osge
+	Osmanya                      = Script(0x6f736d61) // osma
+	Pahawh_Hmong                 = Script(0x686d6e67) // hmng
+	Palmyrene                    = Script(0x70616c6d) // palm
+	Pau_Cin_Hau                  = Script(0x70617563) // pauc
+	Phags_Pa                     = Script(0x70686167) // phag
+	Phoenician                   = Script(0x70686e78) // phnx
+	Psalter_Pahlavi              = Script(0x70686c70) // phlp
+	Ranjana                      = Script(0x72616e6a) // ranj
+	Rejang                       = Script(0x726a6e67) // rjng
+	Rongorongo                   = Script(0x726f726f) // roro
+	Runic                        = Script(0x72756e72) // runr
+	Samaritan                    = Script(0x73616d72) // samr
+	Sarati                       = Script(0x73617261) // sara
+	Saurashtra                   = Script(0x73617572) // saur
+	Sharada                      = Script(0x73687264) // shrd
+	Shavian                      = Script(0x73686177) // shaw
+	Shuishu                      = Script(0x73687569) // shui
+	Siddham                      = Script(0x73696464) // sidd
+	SignWriting                  = Script(0x73676e77) // sgnw
+	Sinhala                      = Script(0x73696e68) // sinh
+	Sogdian                      = Script(0x736f6764) // sogd
+	Sora_Sompeng                 = Script(0x736f7261) // sora
+	Soyombo                      = Script(0x736f796f) // soyo
+	Sundanese                    = Script(0x73756e64) // sund
+	Sunuwar                      = Script(0x73756e75) // sunu
+	Syloti_Nagri                 = Script(0x73796c6f) // sylo
+	Symbols                      = Script(0x7a73796d) // zsym
+	Syriac                       = Script(0x73797263) // syrc
+	Tagalog                      = Script(0x74676c67) // tglg
+	Tagbanwa                     = Script(0x74616762) // tagb
+	Tai_Le                       = Script(0x74616c65) // tale
+	Tai_Tham                     = Script(0x6c616e61) // lana
+	Tai_Viet                     = Script(0x74617674) // tavt
+	Takri                        = Script(0x74616b72) // takr
+	Tamil                        = Script(0x74616d6c) // taml
+	Tangsa                       = Script(0x746e7361) // tnsa
+	Tangut                       = Script(0x74616e67) // tang
+	Telugu                       = Script(0x74656c75) // telu
+	Tengwar                      = Script(0x74656e67) // teng
+	Thaana                       = Script(0x74686161) // thaa
+	Thai                         = Script(0x74686169) // thai
+	Tibetan                      = Script(0x74696274) // tibt
+	Tifinagh                     = Script(0x74666e67) // tfng
+	Tirhuta                      = Script(0x74697268) // tirh
+	Toto                         = Script(0x746f746f) // toto
+	Ugaritic                     = Script(0x75676172) // ugar
+	Unknown                      = Script(0x7a7a7a7a) // zzzz
+	Vai                          = Script(0x76616969) // vaii
+	Visible_Speech               = Script(0x76697370) // visp
+	Vithkuqi                     = Script(0x76697468) // vith
+	Wancho                       = Script(0x7763686f) // wcho
+	Warang_Citi                  = Script(0x77617261) // wara
+	Woleai                       = Script(0x776f6c65) // wole
+	Yezidi                       = Script(0x79657a69) // yezi
+	Yi                           = Script(0x79696969) // yiii
+	Zanabazar_Square             = Script(0x7a616e62) // zanb
 )
 )
 
 
 var scriptToTag = map[string]Script{
 var scriptToTag = map[string]Script{
-	"Adlam":                  1633971309,
-	"Ahom":                   1634234221,
-	"Anatolian_Hieroglyphs":  1751938423,
-	"Arabic":                 1634885986,
-	"Armenian":               1634889070,
-	"Avestan":                1635152756,
-	"Balinese":               1650551913,
-	"Bamum":                  1650552181,
-	"Bassa_Vah":              1650553715,
-	"Batak":                  1650553963,
-	"Bengali":                1650814567,
-	"Bhaiksuki":              1651010419,
-	"Bopomofo":               1651470447,
-	"Brahmi":                 1651663208,
-	"Braille":                1651663209,
-	"Buginese":               1651861353,
-	"Buhid":                  1651861604,
-	"Canadian_Aboriginal":    1667329651,
-	"Carian":                 1667330665,
-	"Caucasian_Albanian":     1634166882,
-	"Chakma":                 1667328877,
-	"Cham":                   1667785069,
-	"Cherokee":               1667786098,
-	"Chorasmian":             1667789427,
-	"Common":                 2054781305,
-	"Coptic":                 1668247668,
-	"Cuneiform":              2020832632,
-	"Cypriot":                1668313716,
-	"Cyrillic":               1668903532,
-	"Deseret":                1685287540,
-	"Devanagari":             1684371041,
-	"Dives_Akuru":            1684627819,
-	"Dogra":                  1685022578,
-	"Duployan":               1685418092,
-	"Egyptian_Hieroglyphs":   1701280112,
-	"Elbasan":                1701601889,
-	"Elymaic":                1701607789,
-	"Ethiopic":               1702127721,
-	"Georgian":               1734700914,
-	"Glagolitic":             1735156071,
-	"Gothic":                 1735357544,
-	"Grantha":                1735549294,
-	"Greek":                  1735550315,
-	"Gujarati":               1735748210,
-	"Gunjala_Gondi":          1735356007,
-	"Gurmukhi":               1735750261,
-	"Han":                    1751215721,
-	"Hangul":                 1751215719,
-	"Hanifi_Rohingya":        1919903847,
-	"Hanunoo":                1751215727,
-	"Hatran":                 1751217266,
-	"Hebrew":                 1751474802,
-	"Hiragana":               1751741025,
-	"Imperial_Aramaic":       1634889065,
-	"Inherited":              2053729896,
-	"Inscriptional_Pahlavi":  1885891689,
-	"Inscriptional_Parthian": 1886549097,
-	"Javanese":               1784772193,
-	"Kaithi":                 1802791017,
-	"Kannada":                1802396769,
-	"Katakana":               1801547361,
-	"Katakana_Or_Hiragana":   1752329076,
-	"Kayah_Li":               1801546857,
-	"Kharoshthi":             1802002802,
-	"Khitan_Small_Script":    1802073203,
-	"Khmer":                  1802005874,
-	"Khojki":                 1802006378,
-	"Khudawadi":              1936289380,
-	"Lao":                    1818324847,
-	"Latin":                  1818326126,
-	"Lepcha":                 1818587235,
-	"Limbu":                  1818848610,
-	"Linear_A":               1818848865,
-	"Linear_B":               1818848866,
-	"Lisu":                   1818850165,
-	"Lycian":                 1819894633,
-	"Lydian":                 1819894889,
-	"Mahajani":               1835100266,
-	"Makasar":                1835101025,
-	"Malayalam":              1835825517,
-	"Mandaic":                1835101796,
-	"Manichaean":             1835101801,
-	"Marchen":                1835102819,
-	"Masaram_Gondi":          1735356013,
-	"Medefaidrin":            1835361382,
-	"Meetei_Mayek":           1836344681,
-	"Mende_Kikakui":          1835363940,
-	"Meroitic_Cursive":       1835364963,
-	"Meroitic_Hieroglyphs":   1835364975,
-	"Miao":                   1886155364,
-	"Modi":                   1836016745,
-	"Mongolian":              1836019303,
-	"Mro":                    1836216175,
-	"Multani":                1836412020,
-	"Myanmar":                1836674418,
-	"Nabataean":              1851941236,
-	"Nandinagari":            1851879012,
-	"New_Tai_Lue":            1952541813,
-	"Newa":                   1852143457,
-	"Nko":                    1852534639,
-	"Nushu":                  1853057141,
-	"Nyiakeng_Puachue_Hmong": 1752002160,
-	"Ogham":                  1869046125,
-	"Ol_Chiki":               1869374315,
-	"Old_Hungarian":          1752526439,
-	"Old_Italic":             1769234796,
-	"Old_North_Arabian":      1851880034,
-	"Old_Permic":             1885696621,
-	"Old_Persian":            2020631919,
-	"Old_Sogdian":            1936680815,
-	"Old_South_Arabian":      1935766114,
-	"Old_Turkic":             1869769576,
-	"Oriya":                  1869773153,
-	"Osage":                  1869834085,
-	"Osmanya":                1869835617,
-	"Pahawh_Hmong":           1752002151,
-	"Palmyrene":              1885432941,
-	"Pau_Cin_Hau":            1885435235,
-	"Phags_Pa":               1885888871,
-	"Phoenician":             1885892216,
-	"Psalter_Pahlavi":        1885891696,
-	"Rejang":                 1919577703,
-	"Runic":                  1920298610,
-	"Samaritan":              1935764850,
-	"Saurashtra":             1935766898,
-	"Sharada":                1936224868,
-	"Shavian":                1936220535,
-	"Siddham":                1936286820,
-	"SignWriting":            1936158327,
-	"Sinhala":                1936289384,
-	"Sogdian":                1936680804,
-	"Sora_Sompeng":           1936683617,
-	"Soyombo":                1936685423,
-	"Sundanese":              1937075812,
-	"Syloti_Nagri":           1937337455,
-	"Syriac":                 1937338979,
-	"Tagalog":                1952935015,
-	"Tagbanwa":               1952540514,
-	"Tai_Le":                 1952541797,
-	"Tai_Tham":               1818324577,
-	"Tai_Viet":               1952544372,
-	"Takri":                  1952541554,
-	"Tamil":                  1952542060,
-	"Tangut":                 1952542311,
-	"Telugu":                 1952803957,
-	"Thaana":                 1952997729,
-	"Thai":                   1952997737,
-	"Tibetan":                1953063540,
-	"Tifinagh":               1952869991,
-	"Tirhuta":                1953067624,
-	"Ugaritic":               1969709426,
-	"Unknown":                2054847098,
-	"Vai":                    1986095465,
-	"Wancho":                 2003003503,
-	"Warang_Citi":            2002874977,
-	"Yezidi":                 2036693609,
-	"Yi":                     2036951401,
-	"Zanabazar_Square":       2053205602,
+	"Adlam":                        1633971309,
+	"Afaka":                        1634099563,
+	"Ahom":                         1634234221,
+	"Anatolian_Hieroglyphs":        1751938423,
+	"Arabic":                       1634885986,
+	"Armenian":                     1634889070,
+	"Avestan":                      1635152756,
+	"Balinese":                     1650551913,
+	"Bamum":                        1650552181,
+	"Bassa_Vah":                    1650553715,
+	"Batak":                        1650553963,
+	"Bengali":                      1650814567,
+	"Bhaiksuki":                    1651010419,
+	"Blissymbols":                  1651272051,
+	"Book_Pahlavi":                 1885891702,
+	"Bopomofo":                     1651470447,
+	"Brahmi":                       1651663208,
+	"Braille":                      1651663209,
+	"Buginese":                     1651861353,
+	"Buhid":                        1651861604,
+	"Canadian_Aboriginal":          1667329651,
+	"Carian":                       1667330665,
+	"Caucasian_Albanian":           1634166882,
+	"Chakma":                       1667328877,
+	"Cham":                         1667785069,
+	"Cherokee":                     1667786098,
+	"Chorasmian":                   1667789427,
+	"Cirth":                        1667854964,
+	"Code_for_unwritten_documents": 2054715512,
+	"Common":                       2054781305,
+	"Coptic":                       1668247668,
+	"Cuneiform":                    2020832632,
+	"Cypriot":                      1668313716,
+	"Cypro_Minoan":                 1668312430,
+	"Cyrillic":                     1668903532,
+	"Deseret":                      1685287540,
+	"Devanagari":                   1684371041,
+	"Dives_Akuru":                  1684627819,
+	"Dogra":                        1685022578,
+	"Duployan":                     1685418092,
+	"Egyptian_Hieroglyphs":         1701280112,
+	"Egyptian_demotic":             1701280100,
+	"Egyptian_hieratic":            1701280104,
+	"Elbasan":                      1701601889,
+	"Elymaic":                      1701607789,
+	"Ethiopic":                     1702127721,
+	"Georgian":                     1734700914,
+	"Glagolitic":                   1735156071,
+	"Gothic":                       1735357544,
+	"Grantha":                      1735549294,
+	"Greek":                        1735550315,
+	"Gujarati":                     1735748210,
+	"Gunjala_Gondi":                1735356007,
+	"Gurmukhi":                     1735750261,
+	"Han":                          1751215721,
+	"Hangul":                       1751215719,
+	"Hanifi_Rohingya":              1919903847,
+	"Hanunoo":                      1751215727,
+	"Hatran":                       1751217266,
+	"Hebrew":                       1751474802,
+	"Hiragana":                     1751741025,
+	"Imperial_Aramaic":             1634889065,
+	"Inherited":                    2053729896,
+	"Inscriptional_Pahlavi":        1885891689,
+	"Inscriptional_Parthian":       1886549097,
+	"Javanese":                     1784772193,
+	"Jurchen":                      1786081891,
+	"Kaithi":                       1802791017,
+	"Kannada":                      1802396769,
+	"Katakana":                     1801547361,
+	"Katakana_Or_Hiragana":         1752329076,
+	"Kawi":                         1801549673,
+	"Kayah_Li":                     1801546857,
+	"Kharoshthi":                   1802002802,
+	"Khitan_Small_Script":          1802073203,
+	"Khitan_large_script":          1802073196,
+	"Khmer":                        1802005874,
+	"Khojki":                       1802006378,
+	"Khudawadi":                    1936289380,
+	"Kpelle":                       1802528108,
+	"Lao":                          1818324847,
+	"Latin":                        1818326126,
+	"Leke":                         1818585957,
+	"Lepcha":                       1818587235,
+	"Limbu":                        1818848610,
+	"Linear_A":                     1818848865,
+	"Linear_B":                     1818848866,
+	"Lisu":                         1818850165,
+	"Loma":                         1819241825,
+	"Lycian":                       1819894633,
+	"Lydian":                       1819894889,
+	"Mahajani":                     1835100266,
+	"Makasar":                      1835101025,
+	"Malayalam":                    1835825517,
+	"Mandaic":                      1835101796,
+	"Manichaean":                   1835101801,
+	"Marchen":                      1835102819,
+	"Masaram_Gondi":                1735356013,
+	"Mathematical_notation":        2053993576,
+	"Mayan_hieroglyphs":            1835104609,
+	"Medefaidrin":                  1835361382,
+	"Meetei_Mayek":                 1836344681,
+	"Mende_Kikakui":                1835363940,
+	"Meroitic_Cursive":             1835364963,
+	"Meroitic_Hieroglyphs":         1835364975,
+	"Miao":                         1886155364,
+	"Modi":                         1836016745,
+	"Mongolian":                    1836019303,
+	"Mro":                          1836216175,
+	"Multani":                      1836412020,
+	"Myanmar":                      1836674418,
+	"Nabataean":                    1851941236,
+	"Nag_Mundari":                  1851877229,
+	"Nandinagari":                  1851879012,
+	"New_Tai_Lue":                  1952541813,
+	"Newa":                         1852143457,
+	"Nko":                          1852534639,
+	"Nushu":                        1853057141,
+	"Nyiakeng_Puachue_Hmong":       1752002160,
+	"Ogham":                        1869046125,
+	"Ol_Chiki":                     1869374315,
+	"Old_Hungarian":                1752526439,
+	"Old_Italic":                   1769234796,
+	"Old_North_Arabian":            1851880034,
+	"Old_Permic":                   1885696621,
+	"Old_Persian":                  2020631919,
+	"Old_Sogdian":                  1936680815,
+	"Old_South_Arabian":            1935766114,
+	"Old_Turkic":                   1869769576,
+	"Old_Uyghur":                   1869965170,
+	"Oriya":                        1869773153,
+	"Osage":                        1869834085,
+	"Osmanya":                      1869835617,
+	"Pahawh_Hmong":                 1752002151,
+	"Palmyrene":                    1885432941,
+	"Pau_Cin_Hau":                  1885435235,
+	"Phags_Pa":                     1885888871,
+	"Phoenician":                   1885892216,
+	"Psalter_Pahlavi":              1885891696,
+	"Ranjana":                      1918987882,
+	"Rejang":                       1919577703,
+	"Rongorongo":                   1919906415,
+	"Runic":                        1920298610,
+	"Samaritan":                    1935764850,
+	"Sarati":                       1935766113,
+	"Saurashtra":                   1935766898,
+	"Sharada":                      1936224868,
+	"Shavian":                      1936220535,
+	"Shuishu":                      1936225641,
+	"Siddham":                      1936286820,
+	"SignWriting":                  1936158327,
+	"Sinhala":                      1936289384,
+	"Sogdian":                      1936680804,
+	"Sora_Sompeng":                 1936683617,
+	"Soyombo":                      1936685423,
+	"Sundanese":                    1937075812,
+	"Sunuwar":                      1937075829,
+	"Syloti_Nagri":                 1937337455,
+	"Symbols":                      2054388077,
+	"Syriac":                       1937338979,
+	"Tagalog":                      1952935015,
+	"Tagbanwa":                     1952540514,
+	"Tai_Le":                       1952541797,
+	"Tai_Tham":                     1818324577,
+	"Tai_Viet":                     1952544372,
+	"Takri":                        1952541554,
+	"Tamil":                        1952542060,
+	"Tangsa":                       1953395553,
+	"Tangut":                       1952542311,
+	"Telugu":                       1952803957,
+	"Tengwar":                      1952804455,
+	"Thaana":                       1952997729,
+	"Thai":                         1952997737,
+	"Tibetan":                      1953063540,
+	"Tifinagh":                     1952869991,
+	"Tirhuta":                      1953067624,
+	"Toto":                         1953461359,
+	"Ugaritic":                     1969709426,
+	"Unknown":                      2054847098,
+	"Vai":                          1986095465,
+	"Visible_Speech":               1986622320,
+	"Vithkuqi":                     1986622568,
+	"Wancho":                       2003003503,
+	"Warang_Citi":                  2002874977,
+	"Woleai":                       2003790949,
+	"Yezidi":                       2036693609,
+	"Yi":                           2036951401,
+	"Zanabazar_Square":             2053205602,
 }
 }
 
 
-type scriptItem struct {
-	start, end rune
-	script     Script
+// ScriptRange is an inclusive range of runes
+// with constant script.
+type ScriptRange struct {
+	Start, End rune
+	Script     Script
 }
 }
 
 
-var scriptRanges = [...]scriptItem{
-	{start: 0x0, end: 0x40, script: 0x7a797979},
-	{start: 0x41, end: 0x5a, script: 0x6c61746e},
-	{start: 0x5b, end: 0x60, script: 0x7a797979},
-	{start: 0x61, end: 0x7a, script: 0x6c61746e},
-	{start: 0x7b, end: 0xa9, script: 0x7a797979},
-	{start: 0xaa, end: 0xaa, script: 0x6c61746e},
-	{start: 0xab, end: 0xb9, script: 0x7a797979},
-	{start: 0xba, end: 0xba, script: 0x6c61746e},
-	{start: 0xbb, end: 0xbf, script: 0x7a797979},
-	{start: 0xc0, end: 0xd6, script: 0x6c61746e},
-	{start: 0xd7, end: 0xd7, script: 0x7a797979},
-	{start: 0xd8, end: 0xf6, script: 0x6c61746e},
-	{start: 0xf7, end: 0xf7, script: 0x7a797979},
-	{start: 0xf8, end: 0x2b8, script: 0x6c61746e},
-	{start: 0x2b9, end: 0x2df, script: 0x7a797979},
-	{start: 0x2e0, end: 0x2e4, script: 0x6c61746e},
-	{start: 0x2e5, end: 0x2e9, script: 0x7a797979},
-	{start: 0x2ea, end: 0x2eb, script: 0x626f706f},
-	{start: 0x2ec, end: 0x2ff, script: 0x7a797979},
-	{start: 0x300, end: 0x36f, script: 0x7a696e68},
-	{start: 0x370, end: 0x373, script: 0x6772656b},
-	{start: 0x374, end: 0x374, script: 0x7a797979},
-	{start: 0x375, end: 0x377, script: 0x6772656b},
-	{start: 0x37a, end: 0x37d, script: 0x6772656b},
-	{start: 0x37e, end: 0x37e, script: 0x7a797979},
-	{start: 0x37f, end: 0x37f, script: 0x6772656b},
-	{start: 0x384, end: 0x384, script: 0x6772656b},
-	{start: 0x385, end: 0x385, script: 0x7a797979},
-	{start: 0x386, end: 0x386, script: 0x6772656b},
-	{start: 0x387, end: 0x387, script: 0x7a797979},
-	{start: 0x388, end: 0x38a, script: 0x6772656b},
-	{start: 0x38c, end: 0x38c, script: 0x6772656b},
-	{start: 0x38e, end: 0x3a1, script: 0x6772656b},
-	{start: 0x3a3, end: 0x3e1, script: 0x6772656b},
-	{start: 0x3e2, end: 0x3ef, script: 0x636f7074},
-	{start: 0x3f0, end: 0x3ff, script: 0x6772656b},
-	{start: 0x400, end: 0x484, script: 0x6379726c},
-	{start: 0x485, end: 0x486, script: 0x7a696e68},
-	{start: 0x487, end: 0x52f, script: 0x6379726c},
-	{start: 0x531, end: 0x556, script: 0x61726d6e},
-	{start: 0x559, end: 0x58a, script: 0x61726d6e},
-	{start: 0x58d, end: 0x58f, script: 0x61726d6e},
-	{start: 0x591, end: 0x5c7, script: 0x68656272},
-	{start: 0x5d0, end: 0x5ea, script: 0x68656272},
-	{start: 0x5ef, end: 0x5f4, script: 0x68656272},
-	{start: 0x600, end: 0x604, script: 0x61726162},
-	{start: 0x605, end: 0x605, script: 0x7a797979},
-	{start: 0x606, end: 0x60b, script: 0x61726162},
-	{start: 0x60c, end: 0x60c, script: 0x7a797979},
-	{start: 0x60d, end: 0x61a, script: 0x61726162},
-	{start: 0x61b, end: 0x61b, script: 0x7a797979},
-	{start: 0x61c, end: 0x61c, script: 0x61726162},
-	{start: 0x61e, end: 0x61e, script: 0x61726162},
-	{start: 0x61f, end: 0x61f, script: 0x7a797979},
-	{start: 0x620, end: 0x63f, script: 0x61726162},
-	{start: 0x640, end: 0x640, script: 0x7a797979},
-	{start: 0x641, end: 0x64a, script: 0x61726162},
-	{start: 0x64b, end: 0x655, script: 0x7a696e68},
-	{start: 0x656, end: 0x66f, script: 0x61726162},
-	{start: 0x670, end: 0x670, script: 0x7a696e68},
-	{start: 0x671, end: 0x6dc, script: 0x61726162},
-	{start: 0x6dd, end: 0x6dd, script: 0x7a797979},
-	{start: 0x6de, end: 0x6ff, script: 0x61726162},
-	{start: 0x700, end: 0x70d, script: 0x73797263},
-	{start: 0x70f, end: 0x74a, script: 0x73797263},
-	{start: 0x74d, end: 0x74f, script: 0x73797263},
-	{start: 0x750, end: 0x77f, script: 0x61726162},
-	{start: 0x780, end: 0x7b1, script: 0x74686161},
-	{start: 0x7c0, end: 0x7fa, script: 0x6e6b6f6f},
-	{start: 0x7fd, end: 0x7ff, script: 0x6e6b6f6f},
-	{start: 0x800, end: 0x82d, script: 0x73616d72},
-	{start: 0x830, end: 0x83e, script: 0x73616d72},
-	{start: 0x840, end: 0x85b, script: 0x6d616e64},
-	{start: 0x85e, end: 0x85e, script: 0x6d616e64},
-	{start: 0x860, end: 0x86a, script: 0x73797263},
-	{start: 0x8a0, end: 0x8b4, script: 0x61726162},
-	{start: 0x8b6, end: 0x8c7, script: 0x61726162},
-	{start: 0x8d3, end: 0x8e1, script: 0x61726162},
-	{start: 0x8e2, end: 0x8e2, script: 0x7a797979},
-	{start: 0x8e3, end: 0x8ff, script: 0x61726162},
-	{start: 0x900, end: 0x950, script: 0x64657661},
-	{start: 0x951, end: 0x954, script: 0x7a696e68},
-	{start: 0x955, end: 0x963, script: 0x64657661},
-	{start: 0x964, end: 0x965, script: 0x7a797979},
-	{start: 0x966, end: 0x97f, script: 0x64657661},
-	{start: 0x980, end: 0x983, script: 0x62656e67},
-	{start: 0x985, end: 0x98c, script: 0x62656e67},
-	{start: 0x98f, end: 0x990, script: 0x62656e67},
-	{start: 0x993, end: 0x9a8, script: 0x62656e67},
-	{start: 0x9aa, end: 0x9b0, script: 0x62656e67},
-	{start: 0x9b2, end: 0x9b2, script: 0x62656e67},
-	{start: 0x9b6, end: 0x9b9, script: 0x62656e67},
-	{start: 0x9bc, end: 0x9c4, script: 0x62656e67},
-	{start: 0x9c7, end: 0x9c8, script: 0x62656e67},
-	{start: 0x9cb, end: 0x9ce, script: 0x62656e67},
-	{start: 0x9d7, end: 0x9d7, script: 0x62656e67},
-	{start: 0x9dc, end: 0x9dd, script: 0x62656e67},
-	{start: 0x9df, end: 0x9e3, script: 0x62656e67},
-	{start: 0x9e6, end: 0x9fe, script: 0x62656e67},
-	{start: 0xa01, end: 0xa03, script: 0x67757275},
-	{start: 0xa05, end: 0xa0a, script: 0x67757275},
-	{start: 0xa0f, end: 0xa10, script: 0x67757275},
-	{start: 0xa13, end: 0xa28, script: 0x67757275},
-	{start: 0xa2a, end: 0xa30, script: 0x67757275},
-	{start: 0xa32, end: 0xa33, script: 0x67757275},
-	{start: 0xa35, end: 0xa36, script: 0x67757275},
-	{start: 0xa38, end: 0xa39, script: 0x67757275},
-	{start: 0xa3c, end: 0xa3c, script: 0x67757275},
-	{start: 0xa3e, end: 0xa42, script: 0x67757275},
-	{start: 0xa47, end: 0xa48, script: 0x67757275},
-	{start: 0xa4b, end: 0xa4d, script: 0x67757275},
-	{start: 0xa51, end: 0xa51, script: 0x67757275},
-	{start: 0xa59, end: 0xa5c, script: 0x67757275},
-	{start: 0xa5e, end: 0xa5e, script: 0x67757275},
-	{start: 0xa66, end: 0xa76, script: 0x67757275},
-	{start: 0xa81, end: 0xa83, script: 0x67756a72},
-	{start: 0xa85, end: 0xa8d, script: 0x67756a72},
-	{start: 0xa8f, end: 0xa91, script: 0x67756a72},
-	{start: 0xa93, end: 0xaa8, script: 0x67756a72},
-	{start: 0xaaa, end: 0xab0, script: 0x67756a72},
-	{start: 0xab2, end: 0xab3, script: 0x67756a72},
-	{start: 0xab5, end: 0xab9, script: 0x67756a72},
-	{start: 0xabc, end: 0xac5, script: 0x67756a72},
-	{start: 0xac7, end: 0xac9, script: 0x67756a72},
-	{start: 0xacb, end: 0xacd, script: 0x67756a72},
-	{start: 0xad0, end: 0xad0, script: 0x67756a72},
-	{start: 0xae0, end: 0xae3, script: 0x67756a72},
-	{start: 0xae6, end: 0xaf1, script: 0x67756a72},
-	{start: 0xaf9, end: 0xaff, script: 0x67756a72},
-	{start: 0xb01, end: 0xb03, script: 0x6f727961},
-	{start: 0xb05, end: 0xb0c, script: 0x6f727961},
-	{start: 0xb0f, end: 0xb10, script: 0x6f727961},
-	{start: 0xb13, end: 0xb28, script: 0x6f727961},
-	{start: 0xb2a, end: 0xb30, script: 0x6f727961},
-	{start: 0xb32, end: 0xb33, script: 0x6f727961},
-	{start: 0xb35, end: 0xb39, script: 0x6f727961},
-	{start: 0xb3c, end: 0xb44, script: 0x6f727961},
-	{start: 0xb47, end: 0xb48, script: 0x6f727961},
-	{start: 0xb4b, end: 0xb4d, script: 0x6f727961},
-	{start: 0xb55, end: 0xb57, script: 0x6f727961},
-	{start: 0xb5c, end: 0xb5d, script: 0x6f727961},
-	{start: 0xb5f, end: 0xb63, script: 0x6f727961},
-	{start: 0xb66, end: 0xb77, script: 0x6f727961},
-	{start: 0xb82, end: 0xb83, script: 0x74616d6c},
-	{start: 0xb85, end: 0xb8a, script: 0x74616d6c},
-	{start: 0xb8e, end: 0xb90, script: 0x74616d6c},
-	{start: 0xb92, end: 0xb95, script: 0x74616d6c},
-	{start: 0xb99, end: 0xb9a, script: 0x74616d6c},
-	{start: 0xb9c, end: 0xb9c, script: 0x74616d6c},
-	{start: 0xb9e, end: 0xb9f, script: 0x74616d6c},
-	{start: 0xba3, end: 0xba4, script: 0x74616d6c},
-	{start: 0xba8, end: 0xbaa, script: 0x74616d6c},
-	{start: 0xbae, end: 0xbb9, script: 0x74616d6c},
-	{start: 0xbbe, end: 0xbc2, script: 0x74616d6c},
-	{start: 0xbc6, end: 0xbc8, script: 0x74616d6c},
-	{start: 0xbca, end: 0xbcd, script: 0x74616d6c},
-	{start: 0xbd0, end: 0xbd0, script: 0x74616d6c},
-	{start: 0xbd7, end: 0xbd7, script: 0x74616d6c},
-	{start: 0xbe6, end: 0xbfa, script: 0x74616d6c},
-	{start: 0xc00, end: 0xc0c, script: 0x74656c75},
-	{start: 0xc0e, end: 0xc10, script: 0x74656c75},
-	{start: 0xc12, end: 0xc28, script: 0x74656c75},
-	{start: 0xc2a, end: 0xc39, script: 0x74656c75},
-	{start: 0xc3d, end: 0xc44, script: 0x74656c75},
-	{start: 0xc46, end: 0xc48, script: 0x74656c75},
-	{start: 0xc4a, end: 0xc4d, script: 0x74656c75},
-	{start: 0xc55, end: 0xc56, script: 0x74656c75},
-	{start: 0xc58, end: 0xc5a, script: 0x74656c75},
-	{start: 0xc60, end: 0xc63, script: 0x74656c75},
-	{start: 0xc66, end: 0xc6f, script: 0x74656c75},
-	{start: 0xc77, end: 0xc7f, script: 0x74656c75},
-	{start: 0xc80, end: 0xc8c, script: 0x6b6e6461},
-	{start: 0xc8e, end: 0xc90, script: 0x6b6e6461},
-	{start: 0xc92, end: 0xca8, script: 0x6b6e6461},
-	{start: 0xcaa, end: 0xcb3, script: 0x6b6e6461},
-	{start: 0xcb5, end: 0xcb9, script: 0x6b6e6461},
-	{start: 0xcbc, end: 0xcc4, script: 0x6b6e6461},
-	{start: 0xcc6, end: 0xcc8, script: 0x6b6e6461},
-	{start: 0xcca, end: 0xccd, script: 0x6b6e6461},
-	{start: 0xcd5, end: 0xcd6, script: 0x6b6e6461},
-	{start: 0xcde, end: 0xcde, script: 0x6b6e6461},
-	{start: 0xce0, end: 0xce3, script: 0x6b6e6461},
-	{start: 0xce6, end: 0xcef, script: 0x6b6e6461},
-	{start: 0xcf1, end: 0xcf2, script: 0x6b6e6461},
-	{start: 0xd00, end: 0xd0c, script: 0x6d6c796d},
-	{start: 0xd0e, end: 0xd10, script: 0x6d6c796d},
-	{start: 0xd12, end: 0xd44, script: 0x6d6c796d},
-	{start: 0xd46, end: 0xd48, script: 0x6d6c796d},
-	{start: 0xd4a, end: 0xd4f, script: 0x6d6c796d},
-	{start: 0xd54, end: 0xd63, script: 0x6d6c796d},
-	{start: 0xd66, end: 0xd7f, script: 0x6d6c796d},
-	{start: 0xd81, end: 0xd83, script: 0x73696e68},
-	{start: 0xd85, end: 0xd96, script: 0x73696e68},
-	{start: 0xd9a, end: 0xdb1, script: 0x73696e68},
-	{start: 0xdb3, end: 0xdbb, script: 0x73696e68},
-	{start: 0xdbd, end: 0xdbd, script: 0x73696e68},
-	{start: 0xdc0, end: 0xdc6, script: 0x73696e68},
-	{start: 0xdca, end: 0xdca, script: 0x73696e68},
-	{start: 0xdcf, end: 0xdd4, script: 0x73696e68},
-	{start: 0xdd6, end: 0xdd6, script: 0x73696e68},
-	{start: 0xdd8, end: 0xddf, script: 0x73696e68},
-	{start: 0xde6, end: 0xdef, script: 0x73696e68},
-	{start: 0xdf2, end: 0xdf4, script: 0x73696e68},
-	{start: 0xe01, end: 0xe3a, script: 0x74686169},
-	{start: 0xe3f, end: 0xe3f, script: 0x7a797979},
-	{start: 0xe40, end: 0xe5b, script: 0x74686169},
-	{start: 0xe81, end: 0xe82, script: 0x6c616f6f},
-	{start: 0xe84, end: 0xe84, script: 0x6c616f6f},
-	{start: 0xe86, end: 0xe8a, script: 0x6c616f6f},
-	{start: 0xe8c, end: 0xea3, script: 0x6c616f6f},
-	{start: 0xea5, end: 0xea5, script: 0x6c616f6f},
-	{start: 0xea7, end: 0xebd, script: 0x6c616f6f},
-	{start: 0xec0, end: 0xec4, script: 0x6c616f6f},
-	{start: 0xec6, end: 0xec6, script: 0x6c616f6f},
-	{start: 0xec8, end: 0xecd, script: 0x6c616f6f},
-	{start: 0xed0, end: 0xed9, script: 0x6c616f6f},
-	{start: 0xedc, end: 0xedf, script: 0x6c616f6f},
-	{start: 0xf00, end: 0xf47, script: 0x74696274},
-	{start: 0xf49, end: 0xf6c, script: 0x74696274},
-	{start: 0xf71, end: 0xf97, script: 0x74696274},
-	{start: 0xf99, end: 0xfbc, script: 0x74696274},
-	{start: 0xfbe, end: 0xfcc, script: 0x74696274},
-	{start: 0xfce, end: 0xfd4, script: 0x74696274},
-	{start: 0xfd5, end: 0xfd8, script: 0x7a797979},
-	{start: 0xfd9, end: 0xfda, script: 0x74696274},
-	{start: 0x1000, end: 0x109f, script: 0x6d796d72},
-	{start: 0x10a0, end: 0x10c5, script: 0x67656f72},
-	{start: 0x10c7, end: 0x10c7, script: 0x67656f72},
-	{start: 0x10cd, end: 0x10cd, script: 0x67656f72},
-	{start: 0x10d0, end: 0x10fa, script: 0x67656f72},
-	{start: 0x10fb, end: 0x10fb, script: 0x7a797979},
-	{start: 0x10fc, end: 0x10ff, script: 0x67656f72},
-	{start: 0x1100, end: 0x11ff, script: 0x68616e67},
-	{start: 0x1200, end: 0x1248, script: 0x65746869},
-	{start: 0x124a, end: 0x124d, script: 0x65746869},
-	{start: 0x1250, end: 0x1256, script: 0x65746869},
-	{start: 0x1258, end: 0x1258, script: 0x65746869},
-	{start: 0x125a, end: 0x125d, script: 0x65746869},
-	{start: 0x1260, end: 0x1288, script: 0x65746869},
-	{start: 0x128a, end: 0x128d, script: 0x65746869},
-	{start: 0x1290, end: 0x12b0, script: 0x65746869},
-	{start: 0x12b2, end: 0x12b5, script: 0x65746869},
-	{start: 0x12b8, end: 0x12be, script: 0x65746869},
-	{start: 0x12c0, end: 0x12c0, script: 0x65746869},
-	{start: 0x12c2, end: 0x12c5, script: 0x65746869},
-	{start: 0x12c8, end: 0x12d6, script: 0x65746869},
-	{start: 0x12d8, end: 0x1310, script: 0x65746869},
-	{start: 0x1312, end: 0x1315, script: 0x65746869},
-	{start: 0x1318, end: 0x135a, script: 0x65746869},
-	{start: 0x135d, end: 0x137c, script: 0x65746869},
-	{start: 0x1380, end: 0x1399, script: 0x65746869},
-	{start: 0x13a0, end: 0x13f5, script: 0x63686572},
-	{start: 0x13f8, end: 0x13fd, script: 0x63686572},
-	{start: 0x1400, end: 0x167f, script: 0x63616e73},
-	{start: 0x1680, end: 0x169c, script: 0x6f67616d},
-	{start: 0x16a0, end: 0x16ea, script: 0x72756e72},
-	{start: 0x16eb, end: 0x16ed, script: 0x7a797979},
-	{start: 0x16ee, end: 0x16f8, script: 0x72756e72},
-	{start: 0x1700, end: 0x170c, script: 0x74676c67},
-	{start: 0x170e, end: 0x1714, script: 0x74676c67},
-	{start: 0x1720, end: 0x1734, script: 0x68616e6f},
-	{start: 0x1735, end: 0x1736, script: 0x7a797979},
-	{start: 0x1740, end: 0x1753, script: 0x62756864},
-	{start: 0x1760, end: 0x176c, script: 0x74616762},
-	{start: 0x176e, end: 0x1770, script: 0x74616762},
-	{start: 0x1772, end: 0x1773, script: 0x74616762},
-	{start: 0x1780, end: 0x17dd, script: 0x6b686d72},
-	{start: 0x17e0, end: 0x17e9, script: 0x6b686d72},
-	{start: 0x17f0, end: 0x17f9, script: 0x6b686d72},
-	{start: 0x1800, end: 0x1801, script: 0x6d6f6e67},
-	{start: 0x1802, end: 0x1803, script: 0x7a797979},
-	{start: 0x1804, end: 0x1804, script: 0x6d6f6e67},
-	{start: 0x1805, end: 0x1805, script: 0x7a797979},
-	{start: 0x1806, end: 0x180e, script: 0x6d6f6e67},
-	{start: 0x1810, end: 0x1819, script: 0x6d6f6e67},
-	{start: 0x1820, end: 0x1878, script: 0x6d6f6e67},
-	{start: 0x1880, end: 0x18aa, script: 0x6d6f6e67},
-	{start: 0x18b0, end: 0x18f5, script: 0x63616e73},
-	{start: 0x1900, end: 0x191e, script: 0x6c696d62},
-	{start: 0x1920, end: 0x192b, script: 0x6c696d62},
-	{start: 0x1930, end: 0x193b, script: 0x6c696d62},
-	{start: 0x1940, end: 0x1940, script: 0x6c696d62},
-	{start: 0x1944, end: 0x194f, script: 0x6c696d62},
-	{start: 0x1950, end: 0x196d, script: 0x74616c65},
-	{start: 0x1970, end: 0x1974, script: 0x74616c65},
-	{start: 0x1980, end: 0x19ab, script: 0x74616c75},
-	{start: 0x19b0, end: 0x19c9, script: 0x74616c75},
-	{start: 0x19d0, end: 0x19da, script: 0x74616c75},
-	{start: 0x19de, end: 0x19df, script: 0x74616c75},
-	{start: 0x19e0, end: 0x19ff, script: 0x6b686d72},
-	{start: 0x1a00, end: 0x1a1b, script: 0x62756769},
-	{start: 0x1a1e, end: 0x1a1f, script: 0x62756769},
-	{start: 0x1a20, end: 0x1a5e, script: 0x6c616e61},
-	{start: 0x1a60, end: 0x1a7c, script: 0x6c616e61},
-	{start: 0x1a7f, end: 0x1a89, script: 0x6c616e61},
-	{start: 0x1a90, end: 0x1a99, script: 0x6c616e61},
-	{start: 0x1aa0, end: 0x1aad, script: 0x6c616e61},
-	{start: 0x1ab0, end: 0x1ac0, script: 0x7a696e68},
-	{start: 0x1b00, end: 0x1b4b, script: 0x62616c69},
-	{start: 0x1b50, end: 0x1b7c, script: 0x62616c69},
-	{start: 0x1b80, end: 0x1bbf, script: 0x73756e64},
-	{start: 0x1bc0, end: 0x1bf3, script: 0x6261746b},
-	{start: 0x1bfc, end: 0x1bff, script: 0x6261746b},
-	{start: 0x1c00, end: 0x1c37, script: 0x6c657063},
-	{start: 0x1c3b, end: 0x1c49, script: 0x6c657063},
-	{start: 0x1c4d, end: 0x1c4f, script: 0x6c657063},
-	{start: 0x1c50, end: 0x1c7f, script: 0x6f6c636b},
-	{start: 0x1c80, end: 0x1c88, script: 0x6379726c},
-	{start: 0x1c90, end: 0x1cba, script: 0x67656f72},
-	{start: 0x1cbd, end: 0x1cbf, script: 0x67656f72},
-	{start: 0x1cc0, end: 0x1cc7, script: 0x73756e64},
-	{start: 0x1cd0, end: 0x1cd2, script: 0x7a696e68},
-	{start: 0x1cd3, end: 0x1cd3, script: 0x7a797979},
-	{start: 0x1cd4, end: 0x1ce0, script: 0x7a696e68},
-	{start: 0x1ce1, end: 0x1ce1, script: 0x7a797979},
-	{start: 0x1ce2, end: 0x1ce8, script: 0x7a696e68},
-	{start: 0x1ce9, end: 0x1cec, script: 0x7a797979},
-	{start: 0x1ced, end: 0x1ced, script: 0x7a696e68},
-	{start: 0x1cee, end: 0x1cf3, script: 0x7a797979},
-	{start: 0x1cf4, end: 0x1cf4, script: 0x7a696e68},
-	{start: 0x1cf5, end: 0x1cf7, script: 0x7a797979},
-	{start: 0x1cf8, end: 0x1cf9, script: 0x7a696e68},
-	{start: 0x1cfa, end: 0x1cfa, script: 0x7a797979},
-	{start: 0x1d00, end: 0x1d25, script: 0x6c61746e},
-	{start: 0x1d26, end: 0x1d2a, script: 0x6772656b},
-	{start: 0x1d2b, end: 0x1d2b, script: 0x6379726c},
-	{start: 0x1d2c, end: 0x1d5c, script: 0x6c61746e},
-	{start: 0x1d5d, end: 0x1d61, script: 0x6772656b},
-	{start: 0x1d62, end: 0x1d65, script: 0x6c61746e},
-	{start: 0x1d66, end: 0x1d6a, script: 0x6772656b},
-	{start: 0x1d6b, end: 0x1d77, script: 0x6c61746e},
-	{start: 0x1d78, end: 0x1d78, script: 0x6379726c},
-	{start: 0x1d79, end: 0x1dbe, script: 0x6c61746e},
-	{start: 0x1dbf, end: 0x1dbf, script: 0x6772656b},
-	{start: 0x1dc0, end: 0x1df9, script: 0x7a696e68},
-	{start: 0x1dfb, end: 0x1dff, script: 0x7a696e68},
-	{start: 0x1e00, end: 0x1eff, script: 0x6c61746e},
-	{start: 0x1f00, end: 0x1f15, script: 0x6772656b},
-	{start: 0x1f18, end: 0x1f1d, script: 0x6772656b},
-	{start: 0x1f20, end: 0x1f45, script: 0x6772656b},
-	{start: 0x1f48, end: 0x1f4d, script: 0x6772656b},
-	{start: 0x1f50, end: 0x1f57, script: 0x6772656b},
-	{start: 0x1f59, end: 0x1f59, script: 0x6772656b},
-	{start: 0x1f5b, end: 0x1f5b, script: 0x6772656b},
-	{start: 0x1f5d, end: 0x1f5d, script: 0x6772656b},
-	{start: 0x1f5f, end: 0x1f7d, script: 0x6772656b},
-	{start: 0x1f80, end: 0x1fb4, script: 0x6772656b},
-	{start: 0x1fb6, end: 0x1fc4, script: 0x6772656b},
-	{start: 0x1fc6, end: 0x1fd3, script: 0x6772656b},
-	{start: 0x1fd6, end: 0x1fdb, script: 0x6772656b},
-	{start: 0x1fdd, end: 0x1fef, script: 0x6772656b},
-	{start: 0x1ff2, end: 0x1ff4, script: 0x6772656b},
-	{start: 0x1ff6, end: 0x1ffe, script: 0x6772656b},
-	{start: 0x2000, end: 0x200b, script: 0x7a797979},
-	{start: 0x200c, end: 0x200d, script: 0x7a696e68},
-	{start: 0x200e, end: 0x2064, script: 0x7a797979},
-	{start: 0x2066, end: 0x2070, script: 0x7a797979},
-	{start: 0x2071, end: 0x2071, script: 0x6c61746e},
-	{start: 0x2074, end: 0x207e, script: 0x7a797979},
-	{start: 0x207f, end: 0x207f, script: 0x6c61746e},
-	{start: 0x2080, end: 0x208e, script: 0x7a797979},
-	{start: 0x2090, end: 0x209c, script: 0x6c61746e},
-	{start: 0x20a0, end: 0x20bf, script: 0x7a797979},
-	{start: 0x20d0, end: 0x20f0, script: 0x7a696e68},
-	{start: 0x2100, end: 0x2125, script: 0x7a797979},
-	{start: 0x2126, end: 0x2126, script: 0x6772656b},
-	{start: 0x2127, end: 0x2129, script: 0x7a797979},
-	{start: 0x212a, end: 0x212b, script: 0x6c61746e},
-	{start: 0x212c, end: 0x2131, script: 0x7a797979},
-	{start: 0x2132, end: 0x2132, script: 0x6c61746e},
-	{start: 0x2133, end: 0x214d, script: 0x7a797979},
-	{start: 0x214e, end: 0x214e, script: 0x6c61746e},
-	{start: 0x214f, end: 0x215f, script: 0x7a797979},
-	{start: 0x2160, end: 0x2188, script: 0x6c61746e},
-	{start: 0x2189, end: 0x218b, script: 0x7a797979},
-	{start: 0x2190, end: 0x2426, script: 0x7a797979},
-	{start: 0x2440, end: 0x244a, script: 0x7a797979},
-	{start: 0x2460, end: 0x27ff, script: 0x7a797979},
-	{start: 0x2800, end: 0x28ff, script: 0x62726169},
-	{start: 0x2900, end: 0x2b73, script: 0x7a797979},
-	{start: 0x2b76, end: 0x2b95, script: 0x7a797979},
-	{start: 0x2b97, end: 0x2bff, script: 0x7a797979},
-	{start: 0x2c00, end: 0x2c2e, script: 0x676c6167},
-	{start: 0x2c30, end: 0x2c5e, script: 0x676c6167},
-	{start: 0x2c60, end: 0x2c7f, script: 0x6c61746e},
-	{start: 0x2c80, end: 0x2cf3, script: 0x636f7074},
-	{start: 0x2cf9, end: 0x2cff, script: 0x636f7074},
-	{start: 0x2d00, end: 0x2d25, script: 0x67656f72},
-	{start: 0x2d27, end: 0x2d27, script: 0x67656f72},
-	{start: 0x2d2d, end: 0x2d2d, script: 0x67656f72},
-	{start: 0x2d30, end: 0x2d67, script: 0x74666e67},
-	{start: 0x2d6f, end: 0x2d70, script: 0x74666e67},
-	{start: 0x2d7f, end: 0x2d7f, script: 0x74666e67},
-	{start: 0x2d80, end: 0x2d96, script: 0x65746869},
-	{start: 0x2da0, end: 0x2da6, script: 0x65746869},
-	{start: 0x2da8, end: 0x2dae, script: 0x65746869},
-	{start: 0x2db0, end: 0x2db6, script: 0x65746869},
-	{start: 0x2db8, end: 0x2dbe, script: 0x65746869},
-	{start: 0x2dc0, end: 0x2dc6, script: 0x65746869},
-	{start: 0x2dc8, end: 0x2dce, script: 0x65746869},
-	{start: 0x2dd0, end: 0x2dd6, script: 0x65746869},
-	{start: 0x2dd8, end: 0x2dde, script: 0x65746869},
-	{start: 0x2de0, end: 0x2dff, script: 0x6379726c},
-	{start: 0x2e00, end: 0x2e52, script: 0x7a797979},
-	{start: 0x2e80, end: 0x2e99, script: 0x68616e69},
-	{start: 0x2e9b, end: 0x2ef3, script: 0x68616e69},
-	{start: 0x2f00, end: 0x2fd5, script: 0x68616e69},
-	{start: 0x2ff0, end: 0x2ffb, script: 0x7a797979},
-	{start: 0x3000, end: 0x3004, script: 0x7a797979},
-	{start: 0x3005, end: 0x3005, script: 0x68616e69},
-	{start: 0x3006, end: 0x3006, script: 0x7a797979},
-	{start: 0x3007, end: 0x3007, script: 0x68616e69},
-	{start: 0x3008, end: 0x3020, script: 0x7a797979},
-	{start: 0x3021, end: 0x3029, script: 0x68616e69},
-	{start: 0x302a, end: 0x302d, script: 0x7a696e68},
-	{start: 0x302e, end: 0x302f, script: 0x68616e67},
-	{start: 0x3030, end: 0x3037, script: 0x7a797979},
-	{start: 0x3038, end: 0x303b, script: 0x68616e69},
-	{start: 0x303c, end: 0x303f, script: 0x7a797979},
-	{start: 0x3041, end: 0x3096, script: 0x68697261},
-	{start: 0x3099, end: 0x309a, script: 0x7a696e68},
-	{start: 0x309b, end: 0x309c, script: 0x7a797979},
-	{start: 0x309d, end: 0x309f, script: 0x68697261},
-	{start: 0x30a0, end: 0x30a0, script: 0x7a797979},
-	{start: 0x30a1, end: 0x30fa, script: 0x6b616e61},
-	{start: 0x30fb, end: 0x30fc, script: 0x7a797979},
-	{start: 0x30fd, end: 0x30ff, script: 0x6b616e61},
-	{start: 0x3105, end: 0x312f, script: 0x626f706f},
-	{start: 0x3131, end: 0x318e, script: 0x68616e67},
-	{start: 0x3190, end: 0x319f, script: 0x7a797979},
-	{start: 0x31a0, end: 0x31bf, script: 0x626f706f},
-	{start: 0x31c0, end: 0x31e3, script: 0x7a797979},
-	{start: 0x31f0, end: 0x31ff, script: 0x6b616e61},
-	{start: 0x3200, end: 0x321e, script: 0x68616e67},
-	{start: 0x3220, end: 0x325f, script: 0x7a797979},
-	{start: 0x3260, end: 0x327e, script: 0x68616e67},
-	{start: 0x327f, end: 0x32cf, script: 0x7a797979},
-	{start: 0x32d0, end: 0x32fe, script: 0x6b616e61},
-	{start: 0x32ff, end: 0x32ff, script: 0x7a797979},
-	{start: 0x3300, end: 0x3357, script: 0x6b616e61},
-	{start: 0x3358, end: 0x33ff, script: 0x7a797979},
-	{start: 0x3400, end: 0x4dbf, script: 0x68616e69},
-	{start: 0x4dc0, end: 0x4dff, script: 0x7a797979},
-	{start: 0x4e00, end: 0x9ffc, script: 0x68616e69},
-	{start: 0xa000, end: 0xa48c, script: 0x79696969},
-	{start: 0xa490, end: 0xa4c6, script: 0x79696969},
-	{start: 0xa4d0, end: 0xa4ff, script: 0x6c697375},
-	{start: 0xa500, end: 0xa62b, script: 0x76616969},
-	{start: 0xa640, end: 0xa69f, script: 0x6379726c},
-	{start: 0xa6a0, end: 0xa6f7, script: 0x62616d75},
-	{start: 0xa700, end: 0xa721, script: 0x7a797979},
-	{start: 0xa722, end: 0xa787, script: 0x6c61746e},
-	{start: 0xa788, end: 0xa78a, script: 0x7a797979},
-	{start: 0xa78b, end: 0xa7bf, script: 0x6c61746e},
-	{start: 0xa7c2, end: 0xa7ca, script: 0x6c61746e},
-	{start: 0xa7f5, end: 0xa7ff, script: 0x6c61746e},
-	{start: 0xa800, end: 0xa82c, script: 0x73796c6f},
-	{start: 0xa830, end: 0xa839, script: 0x7a797979},
-	{start: 0xa840, end: 0xa877, script: 0x70686167},
-	{start: 0xa880, end: 0xa8c5, script: 0x73617572},
-	{start: 0xa8ce, end: 0xa8d9, script: 0x73617572},
-	{start: 0xa8e0, end: 0xa8ff, script: 0x64657661},
-	{start: 0xa900, end: 0xa92d, script: 0x6b616c69},
-	{start: 0xa92e, end: 0xa92e, script: 0x7a797979},
-	{start: 0xa92f, end: 0xa92f, script: 0x6b616c69},
-	{start: 0xa930, end: 0xa953, script: 0x726a6e67},
-	{start: 0xa95f, end: 0xa95f, script: 0x726a6e67},
-	{start: 0xa960, end: 0xa97c, script: 0x68616e67},
-	{start: 0xa980, end: 0xa9cd, script: 0x6a617661},
-	{start: 0xa9cf, end: 0xa9cf, script: 0x7a797979},
-	{start: 0xa9d0, end: 0xa9d9, script: 0x6a617661},
-	{start: 0xa9de, end: 0xa9df, script: 0x6a617661},
-	{start: 0xa9e0, end: 0xa9fe, script: 0x6d796d72},
-	{start: 0xaa00, end: 0xaa36, script: 0x6368616d},
-	{start: 0xaa40, end: 0xaa4d, script: 0x6368616d},
-	{start: 0xaa50, end: 0xaa59, script: 0x6368616d},
-	{start: 0xaa5c, end: 0xaa5f, script: 0x6368616d},
-	{start: 0xaa60, end: 0xaa7f, script: 0x6d796d72},
-	{start: 0xaa80, end: 0xaac2, script: 0x74617674},
-	{start: 0xaadb, end: 0xaadf, script: 0x74617674},
-	{start: 0xaae0, end: 0xaaf6, script: 0x6d746569},
-	{start: 0xab01, end: 0xab06, script: 0x65746869},
-	{start: 0xab09, end: 0xab0e, script: 0x65746869},
-	{start: 0xab11, end: 0xab16, script: 0x65746869},
-	{start: 0xab20, end: 0xab26, script: 0x65746869},
-	{start: 0xab28, end: 0xab2e, script: 0x65746869},
-	{start: 0xab30, end: 0xab5a, script: 0x6c61746e},
-	{start: 0xab5b, end: 0xab5b, script: 0x7a797979},
-	{start: 0xab5c, end: 0xab64, script: 0x6c61746e},
-	{start: 0xab65, end: 0xab65, script: 0x6772656b},
-	{start: 0xab66, end: 0xab69, script: 0x6c61746e},
-	{start: 0xab6a, end: 0xab6b, script: 0x7a797979},
-	{start: 0xab70, end: 0xabbf, script: 0x63686572},
-	{start: 0xabc0, end: 0xabed, script: 0x6d746569},
-	{start: 0xabf0, end: 0xabf9, script: 0x6d746569},
-	{start: 0xac00, end: 0xd7a3, script: 0x68616e67},
-	{start: 0xd7b0, end: 0xd7c6, script: 0x68616e67},
-	{start: 0xd7cb, end: 0xd7fb, script: 0x68616e67},
-	{start: 0xf900, end: 0xfa6d, script: 0x68616e69},
-	{start: 0xfa70, end: 0xfad9, script: 0x68616e69},
-	{start: 0xfb00, end: 0xfb06, script: 0x6c61746e},
-	{start: 0xfb13, end: 0xfb17, script: 0x61726d6e},
-	{start: 0xfb1d, end: 0xfb36, script: 0x68656272},
-	{start: 0xfb38, end: 0xfb3c, script: 0x68656272},
-	{start: 0xfb3e, end: 0xfb3e, script: 0x68656272},
-	{start: 0xfb40, end: 0xfb41, script: 0x68656272},
-	{start: 0xfb43, end: 0xfb44, script: 0x68656272},
-	{start: 0xfb46, end: 0xfb4f, script: 0x68656272},
-	{start: 0xfb50, end: 0xfbc1, script: 0x61726162},
-	{start: 0xfbd3, end: 0xfd3d, script: 0x61726162},
-	{start: 0xfd3e, end: 0xfd3f, script: 0x7a797979},
-	{start: 0xfd50, end: 0xfd8f, script: 0x61726162},
-	{start: 0xfd92, end: 0xfdc7, script: 0x61726162},
-	{start: 0xfdf0, end: 0xfdfd, script: 0x61726162},
-	{start: 0xfe00, end: 0xfe0f, script: 0x7a696e68},
-	{start: 0xfe10, end: 0xfe19, script: 0x7a797979},
-	{start: 0xfe20, end: 0xfe2d, script: 0x7a696e68},
-	{start: 0xfe2e, end: 0xfe2f, script: 0x6379726c},
-	{start: 0xfe30, end: 0xfe52, script: 0x7a797979},
-	{start: 0xfe54, end: 0xfe66, script: 0x7a797979},
-	{start: 0xfe68, end: 0xfe6b, script: 0x7a797979},
-	{start: 0xfe70, end: 0xfe74, script: 0x61726162},
-	{start: 0xfe76, end: 0xfefc, script: 0x61726162},
-	{start: 0xfeff, end: 0xfeff, script: 0x7a797979},
-	{start: 0xff01, end: 0xff20, script: 0x7a797979},
-	{start: 0xff21, end: 0xff3a, script: 0x6c61746e},
-	{start: 0xff3b, end: 0xff40, script: 0x7a797979},
-	{start: 0xff41, end: 0xff5a, script: 0x6c61746e},
-	{start: 0xff5b, end: 0xff65, script: 0x7a797979},
-	{start: 0xff66, end: 0xff6f, script: 0x6b616e61},
-	{start: 0xff70, end: 0xff70, script: 0x7a797979},
-	{start: 0xff71, end: 0xff9d, script: 0x6b616e61},
-	{start: 0xff9e, end: 0xff9f, script: 0x7a797979},
-	{start: 0xffa0, end: 0xffbe, script: 0x68616e67},
-	{start: 0xffc2, end: 0xffc7, script: 0x68616e67},
-	{start: 0xffca, end: 0xffcf, script: 0x68616e67},
-	{start: 0xffd2, end: 0xffd7, script: 0x68616e67},
-	{start: 0xffda, end: 0xffdc, script: 0x68616e67},
-	{start: 0xffe0, end: 0xffe6, script: 0x7a797979},
-	{start: 0xffe8, end: 0xffee, script: 0x7a797979},
-	{start: 0xfff9, end: 0xfffd, script: 0x7a797979},
-	{start: 0x10000, end: 0x1000b, script: 0x6c696e62},
-	{start: 0x1000d, end: 0x10026, script: 0x6c696e62},
-	{start: 0x10028, end: 0x1003a, script: 0x6c696e62},
-	{start: 0x1003c, end: 0x1003d, script: 0x6c696e62},
-	{start: 0x1003f, end: 0x1004d, script: 0x6c696e62},
-	{start: 0x10050, end: 0x1005d, script: 0x6c696e62},
-	{start: 0x10080, end: 0x100fa, script: 0x6c696e62},
-	{start: 0x10100, end: 0x10102, script: 0x7a797979},
-	{start: 0x10107, end: 0x10133, script: 0x7a797979},
-	{start: 0x10137, end: 0x1013f, script: 0x7a797979},
-	{start: 0x10140, end: 0x1018e, script: 0x6772656b},
-	{start: 0x10190, end: 0x1019c, script: 0x7a797979},
-	{start: 0x101a0, end: 0x101a0, script: 0x6772656b},
-	{start: 0x101d0, end: 0x101fc, script: 0x7a797979},
-	{start: 0x101fd, end: 0x101fd, script: 0x7a696e68},
-	{start: 0x10280, end: 0x1029c, script: 0x6c796369},
-	{start: 0x102a0, end: 0x102d0, script: 0x63617269},
-	{start: 0x102e0, end: 0x102e0, script: 0x7a696e68},
-	{start: 0x102e1, end: 0x102fb, script: 0x7a797979},
-	{start: 0x10300, end: 0x10323, script: 0x6974616c},
-	{start: 0x1032d, end: 0x1032f, script: 0x6974616c},
-	{start: 0x10330, end: 0x1034a, script: 0x676f7468},
-	{start: 0x10350, end: 0x1037a, script: 0x7065726d},
-	{start: 0x10380, end: 0x1039d, script: 0x75676172},
-	{start: 0x1039f, end: 0x1039f, script: 0x75676172},
-	{start: 0x103a0, end: 0x103c3, script: 0x7870656f},
-	{start: 0x103c8, end: 0x103d5, script: 0x7870656f},
-	{start: 0x10400, end: 0x1044f, script: 0x64737274},
-	{start: 0x10450, end: 0x1047f, script: 0x73686177},
-	{start: 0x10480, end: 0x1049d, script: 0x6f736d61},
-	{start: 0x104a0, end: 0x104a9, script: 0x6f736d61},
-	{start: 0x104b0, end: 0x104d3, script: 0x6f736765},
-	{start: 0x104d8, end: 0x104fb, script: 0x6f736765},
-	{start: 0x10500, end: 0x10527, script: 0x656c6261},
-	{start: 0x10530, end: 0x10563, script: 0x61676862},
-	{start: 0x1056f, end: 0x1056f, script: 0x61676862},
-	{start: 0x10600, end: 0x10736, script: 0x6c696e61},
-	{start: 0x10740, end: 0x10755, script: 0x6c696e61},
-	{start: 0x10760, end: 0x10767, script: 0x6c696e61},
-	{start: 0x10800, end: 0x10805, script: 0x63707274},
-	{start: 0x10808, end: 0x10808, script: 0x63707274},
-	{start: 0x1080a, end: 0x10835, script: 0x63707274},
-	{start: 0x10837, end: 0x10838, script: 0x63707274},
-	{start: 0x1083c, end: 0x1083c, script: 0x63707274},
-	{start: 0x1083f, end: 0x1083f, script: 0x63707274},
-	{start: 0x10840, end: 0x10855, script: 0x61726d69},
-	{start: 0x10857, end: 0x1085f, script: 0x61726d69},
-	{start: 0x10860, end: 0x1087f, script: 0x70616c6d},
-	{start: 0x10880, end: 0x1089e, script: 0x6e626174},
-	{start: 0x108a7, end: 0x108af, script: 0x6e626174},
-	{start: 0x108e0, end: 0x108f2, script: 0x68617472},
-	{start: 0x108f4, end: 0x108f5, script: 0x68617472},
-	{start: 0x108fb, end: 0x108ff, script: 0x68617472},
-	{start: 0x10900, end: 0x1091b, script: 0x70686e78},
-	{start: 0x1091f, end: 0x1091f, script: 0x70686e78},
-	{start: 0x10920, end: 0x10939, script: 0x6c796469},
-	{start: 0x1093f, end: 0x1093f, script: 0x6c796469},
-	{start: 0x10980, end: 0x1099f, script: 0x6d65726f},
-	{start: 0x109a0, end: 0x109b7, script: 0x6d657263},
-	{start: 0x109bc, end: 0x109cf, script: 0x6d657263},
-	{start: 0x109d2, end: 0x109ff, script: 0x6d657263},
-	{start: 0x10a00, end: 0x10a03, script: 0x6b686172},
-	{start: 0x10a05, end: 0x10a06, script: 0x6b686172},
-	{start: 0x10a0c, end: 0x10a13, script: 0x6b686172},
-	{start: 0x10a15, end: 0x10a17, script: 0x6b686172},
-	{start: 0x10a19, end: 0x10a35, script: 0x6b686172},
-	{start: 0x10a38, end: 0x10a3a, script: 0x6b686172},
-	{start: 0x10a3f, end: 0x10a48, script: 0x6b686172},
-	{start: 0x10a50, end: 0x10a58, script: 0x6b686172},
-	{start: 0x10a60, end: 0x10a7f, script: 0x73617262},
-	{start: 0x10a80, end: 0x10a9f, script: 0x6e617262},
-	{start: 0x10ac0, end: 0x10ae6, script: 0x6d616e69},
-	{start: 0x10aeb, end: 0x10af6, script: 0x6d616e69},
-	{start: 0x10b00, end: 0x10b35, script: 0x61767374},
-	{start: 0x10b39, end: 0x10b3f, script: 0x61767374},
-	{start: 0x10b40, end: 0x10b55, script: 0x70727469},
-	{start: 0x10b58, end: 0x10b5f, script: 0x70727469},
-	{start: 0x10b60, end: 0x10b72, script: 0x70686c69},
-	{start: 0x10b78, end: 0x10b7f, script: 0x70686c69},
-	{start: 0x10b80, end: 0x10b91, script: 0x70686c70},
-	{start: 0x10b99, end: 0x10b9c, script: 0x70686c70},
-	{start: 0x10ba9, end: 0x10baf, script: 0x70686c70},
-	{start: 0x10c00, end: 0x10c48, script: 0x6f726b68},
-	{start: 0x10c80, end: 0x10cb2, script: 0x68756e67},
-	{start: 0x10cc0, end: 0x10cf2, script: 0x68756e67},
-	{start: 0x10cfa, end: 0x10cff, script: 0x68756e67},
-	{start: 0x10d00, end: 0x10d27, script: 0x726f6867},
-	{start: 0x10d30, end: 0x10d39, script: 0x726f6867},
-	{start: 0x10e60, end: 0x10e7e, script: 0x61726162},
-	{start: 0x10e80, end: 0x10ea9, script: 0x79657a69},
-	{start: 0x10eab, end: 0x10ead, script: 0x79657a69},
-	{start: 0x10eb0, end: 0x10eb1, script: 0x79657a69},
-	{start: 0x10f00, end: 0x10f27, script: 0x736f676f},
-	{start: 0x10f30, end: 0x10f59, script: 0x736f6764},
-	{start: 0x10fb0, end: 0x10fcb, script: 0x63687273},
-	{start: 0x10fe0, end: 0x10ff6, script: 0x656c796d},
-	{start: 0x11000, end: 0x1104d, script: 0x62726168},
-	{start: 0x11052, end: 0x1106f, script: 0x62726168},
-	{start: 0x1107f, end: 0x1107f, script: 0x62726168},
-	{start: 0x11080, end: 0x110c1, script: 0x6b746869},
-	{start: 0x110cd, end: 0x110cd, script: 0x6b746869},
-	{start: 0x110d0, end: 0x110e8, script: 0x736f7261},
-	{start: 0x110f0, end: 0x110f9, script: 0x736f7261},
-	{start: 0x11100, end: 0x11134, script: 0x63616b6d},
-	{start: 0x11136, end: 0x11147, script: 0x63616b6d},
-	{start: 0x11150, end: 0x11176, script: 0x6d61686a},
-	{start: 0x11180, end: 0x111df, script: 0x73687264},
-	{start: 0x111e1, end: 0x111f4, script: 0x73696e68},
-	{start: 0x11200, end: 0x11211, script: 0x6b686f6a},
-	{start: 0x11213, end: 0x1123e, script: 0x6b686f6a},
-	{start: 0x11280, end: 0x11286, script: 0x6d756c74},
-	{start: 0x11288, end: 0x11288, script: 0x6d756c74},
-	{start: 0x1128a, end: 0x1128d, script: 0x6d756c74},
-	{start: 0x1128f, end: 0x1129d, script: 0x6d756c74},
-	{start: 0x1129f, end: 0x112a9, script: 0x6d756c74},
-	{start: 0x112b0, end: 0x112ea, script: 0x73696e64},
-	{start: 0x112f0, end: 0x112f9, script: 0x73696e64},
-	{start: 0x11300, end: 0x11303, script: 0x6772616e},
-	{start: 0x11305, end: 0x1130c, script: 0x6772616e},
-	{start: 0x1130f, end: 0x11310, script: 0x6772616e},
-	{start: 0x11313, end: 0x11328, script: 0x6772616e},
-	{start: 0x1132a, end: 0x11330, script: 0x6772616e},
-	{start: 0x11332, end: 0x11333, script: 0x6772616e},
-	{start: 0x11335, end: 0x11339, script: 0x6772616e},
-	{start: 0x1133b, end: 0x1133b, script: 0x7a696e68},
-	{start: 0x1133c, end: 0x11344, script: 0x6772616e},
-	{start: 0x11347, end: 0x11348, script: 0x6772616e},
-	{start: 0x1134b, end: 0x1134d, script: 0x6772616e},
-	{start: 0x11350, end: 0x11350, script: 0x6772616e},
-	{start: 0x11357, end: 0x11357, script: 0x6772616e},
-	{start: 0x1135d, end: 0x11363, script: 0x6772616e},
-	{start: 0x11366, end: 0x1136c, script: 0x6772616e},
-	{start: 0x11370, end: 0x11374, script: 0x6772616e},
-	{start: 0x11400, end: 0x1145b, script: 0x6e657761},
-	{start: 0x1145d, end: 0x11461, script: 0x6e657761},
-	{start: 0x11480, end: 0x114c7, script: 0x74697268},
-	{start: 0x114d0, end: 0x114d9, script: 0x74697268},
-	{start: 0x11580, end: 0x115b5, script: 0x73696464},
-	{start: 0x115b8, end: 0x115dd, script: 0x73696464},
-	{start: 0x11600, end: 0x11644, script: 0x6d6f6469},
-	{start: 0x11650, end: 0x11659, script: 0x6d6f6469},
-	{start: 0x11660, end: 0x1166c, script: 0x6d6f6e67},
-	{start: 0x11680, end: 0x116b8, script: 0x74616b72},
-	{start: 0x116c0, end: 0x116c9, script: 0x74616b72},
-	{start: 0x11700, end: 0x1171a, script: 0x61686f6d},
-	{start: 0x1171d, end: 0x1172b, script: 0x61686f6d},
-	{start: 0x11730, end: 0x1173f, script: 0x61686f6d},
-	{start: 0x11800, end: 0x1183b, script: 0x646f6772},
-	{start: 0x118a0, end: 0x118f2, script: 0x77617261},
-	{start: 0x118ff, end: 0x118ff, script: 0x77617261},
-	{start: 0x11900, end: 0x11906, script: 0x6469616b},
-	{start: 0x11909, end: 0x11909, script: 0x6469616b},
-	{start: 0x1190c, end: 0x11913, script: 0x6469616b},
-	{start: 0x11915, end: 0x11916, script: 0x6469616b},
-	{start: 0x11918, end: 0x11935, script: 0x6469616b},
-	{start: 0x11937, end: 0x11938, script: 0x6469616b},
-	{start: 0x1193b, end: 0x11946, script: 0x6469616b},
-	{start: 0x11950, end: 0x11959, script: 0x6469616b},
-	{start: 0x119a0, end: 0x119a7, script: 0x6e616e64},
-	{start: 0x119aa, end: 0x119d7, script: 0x6e616e64},
-	{start: 0x119da, end: 0x119e4, script: 0x6e616e64},
-	{start: 0x11a00, end: 0x11a47, script: 0x7a616e62},
-	{start: 0x11a50, end: 0x11aa2, script: 0x736f796f},
-	{start: 0x11ac0, end: 0x11af8, script: 0x70617563},
-	{start: 0x11c00, end: 0x11c08, script: 0x62686b73},
-	{start: 0x11c0a, end: 0x11c36, script: 0x62686b73},
-	{start: 0x11c38, end: 0x11c45, script: 0x62686b73},
-	{start: 0x11c50, end: 0x11c6c, script: 0x62686b73},
-	{start: 0x11c70, end: 0x11c8f, script: 0x6d617263},
-	{start: 0x11c92, end: 0x11ca7, script: 0x6d617263},
-	{start: 0x11ca9, end: 0x11cb6, script: 0x6d617263},
-	{start: 0x11d00, end: 0x11d06, script: 0x676f6e6d},
-	{start: 0x11d08, end: 0x11d09, script: 0x676f6e6d},
-	{start: 0x11d0b, end: 0x11d36, script: 0x676f6e6d},
-	{start: 0x11d3a, end: 0x11d3a, script: 0x676f6e6d},
-	{start: 0x11d3c, end: 0x11d3d, script: 0x676f6e6d},
-	{start: 0x11d3f, end: 0x11d47, script: 0x676f6e6d},
-	{start: 0x11d50, end: 0x11d59, script: 0x676f6e6d},
-	{start: 0x11d60, end: 0x11d65, script: 0x676f6e67},
-	{start: 0x11d67, end: 0x11d68, script: 0x676f6e67},
-	{start: 0x11d6a, end: 0x11d8e, script: 0x676f6e67},
-	{start: 0x11d90, end: 0x11d91, script: 0x676f6e67},
-	{start: 0x11d93, end: 0x11d98, script: 0x676f6e67},
-	{start: 0x11da0, end: 0x11da9, script: 0x676f6e67},
-	{start: 0x11ee0, end: 0x11ef8, script: 0x6d616b61},
-	{start: 0x11fb0, end: 0x11fb0, script: 0x6c697375},
-	{start: 0x11fc0, end: 0x11ff1, script: 0x74616d6c},
-	{start: 0x11fff, end: 0x11fff, script: 0x74616d6c},
-	{start: 0x12000, end: 0x12399, script: 0x78737578},
-	{start: 0x12400, end: 0x1246e, script: 0x78737578},
-	{start: 0x12470, end: 0x12474, script: 0x78737578},
-	{start: 0x12480, end: 0x12543, script: 0x78737578},
-	{start: 0x13000, end: 0x1342e, script: 0x65677970},
-	{start: 0x13430, end: 0x13438, script: 0x65677970},
-	{start: 0x14400, end: 0x14646, script: 0x686c7577},
-	{start: 0x16800, end: 0x16a38, script: 0x62616d75},
-	{start: 0x16a40, end: 0x16a5e, script: 0x6d726f6f},
-	{start: 0x16a60, end: 0x16a69, script: 0x6d726f6f},
-	{start: 0x16a6e, end: 0x16a6f, script: 0x6d726f6f},
-	{start: 0x16ad0, end: 0x16aed, script: 0x62617373},
-	{start: 0x16af0, end: 0x16af5, script: 0x62617373},
-	{start: 0x16b00, end: 0x16b45, script: 0x686d6e67},
-	{start: 0x16b50, end: 0x16b59, script: 0x686d6e67},
-	{start: 0x16b5b, end: 0x16b61, script: 0x686d6e67},
-	{start: 0x16b63, end: 0x16b77, script: 0x686d6e67},
-	{start: 0x16b7d, end: 0x16b8f, script: 0x686d6e67},
-	{start: 0x16e40, end: 0x16e9a, script: 0x6d656466},
-	{start: 0x16f00, end: 0x16f4a, script: 0x706c7264},
-	{start: 0x16f4f, end: 0x16f87, script: 0x706c7264},
-	{start: 0x16f8f, end: 0x16f9f, script: 0x706c7264},
-	{start: 0x16fe0, end: 0x16fe0, script: 0x74616e67},
-	{start: 0x16fe1, end: 0x16fe1, script: 0x6e736875},
-	{start: 0x16fe2, end: 0x16fe3, script: 0x7a797979},
-	{start: 0x16fe4, end: 0x16fe4, script: 0x6b697473},
-	{start: 0x16ff0, end: 0x16ff1, script: 0x68616e69},
-	{start: 0x17000, end: 0x187f7, script: 0x74616e67},
-	{start: 0x18800, end: 0x18aff, script: 0x74616e67},
-	{start: 0x18b00, end: 0x18cd5, script: 0x6b697473},
-	{start: 0x18d00, end: 0x18d08, script: 0x74616e67},
-	{start: 0x1b000, end: 0x1b000, script: 0x6b616e61},
-	{start: 0x1b001, end: 0x1b11e, script: 0x68697261},
-	{start: 0x1b150, end: 0x1b152, script: 0x68697261},
-	{start: 0x1b164, end: 0x1b167, script: 0x6b616e61},
-	{start: 0x1b170, end: 0x1b2fb, script: 0x6e736875},
-	{start: 0x1bc00, end: 0x1bc6a, script: 0x6475706c},
-	{start: 0x1bc70, end: 0x1bc7c, script: 0x6475706c},
-	{start: 0x1bc80, end: 0x1bc88, script: 0x6475706c},
-	{start: 0x1bc90, end: 0x1bc99, script: 0x6475706c},
-	{start: 0x1bc9c, end: 0x1bc9f, script: 0x6475706c},
-	{start: 0x1bca0, end: 0x1bca3, script: 0x7a797979},
-	{start: 0x1d000, end: 0x1d0f5, script: 0x7a797979},
-	{start: 0x1d100, end: 0x1d126, script: 0x7a797979},
-	{start: 0x1d129, end: 0x1d166, script: 0x7a797979},
-	{start: 0x1d167, end: 0x1d169, script: 0x7a696e68},
-	{start: 0x1d16a, end: 0x1d17a, script: 0x7a797979},
-	{start: 0x1d17b, end: 0x1d182, script: 0x7a696e68},
-	{start: 0x1d183, end: 0x1d184, script: 0x7a797979},
-	{start: 0x1d185, end: 0x1d18b, script: 0x7a696e68},
-	{start: 0x1d18c, end: 0x1d1a9, script: 0x7a797979},
-	{start: 0x1d1aa, end: 0x1d1ad, script: 0x7a696e68},
-	{start: 0x1d1ae, end: 0x1d1e8, script: 0x7a797979},
-	{start: 0x1d200, end: 0x1d245, script: 0x6772656b},
-	{start: 0x1d2e0, end: 0x1d2f3, script: 0x7a797979},
-	{start: 0x1d300, end: 0x1d356, script: 0x7a797979},
-	{start: 0x1d360, end: 0x1d378, script: 0x7a797979},
-	{start: 0x1d400, end: 0x1d454, script: 0x7a797979},
-	{start: 0x1d456, end: 0x1d49c, script: 0x7a797979},
-	{start: 0x1d49e, end: 0x1d49f, script: 0x7a797979},
-	{start: 0x1d4a2, end: 0x1d4a2, script: 0x7a797979},
-	{start: 0x1d4a5, end: 0x1d4a6, script: 0x7a797979},
-	{start: 0x1d4a9, end: 0x1d4ac, script: 0x7a797979},
-	{start: 0x1d4ae, end: 0x1d4b9, script: 0x7a797979},
-	{start: 0x1d4bb, end: 0x1d4bb, script: 0x7a797979},
-	{start: 0x1d4bd, end: 0x1d4c3, script: 0x7a797979},
-	{start: 0x1d4c5, end: 0x1d505, script: 0x7a797979},
-	{start: 0x1d507, end: 0x1d50a, script: 0x7a797979},
-	{start: 0x1d50d, end: 0x1d514, script: 0x7a797979},
-	{start: 0x1d516, end: 0x1d51c, script: 0x7a797979},
-	{start: 0x1d51e, end: 0x1d539, script: 0x7a797979},
-	{start: 0x1d53b, end: 0x1d53e, script: 0x7a797979},
-	{start: 0x1d540, end: 0x1d544, script: 0x7a797979},
-	{start: 0x1d546, end: 0x1d546, script: 0x7a797979},
-	{start: 0x1d54a, end: 0x1d550, script: 0x7a797979},
-	{start: 0x1d552, end: 0x1d6a5, script: 0x7a797979},
-	{start: 0x1d6a8, end: 0x1d7cb, script: 0x7a797979},
-	{start: 0x1d7ce, end: 0x1d7ff, script: 0x7a797979},
-	{start: 0x1d800, end: 0x1da8b, script: 0x73676e77},
-	{start: 0x1da9b, end: 0x1da9f, script: 0x73676e77},
-	{start: 0x1daa1, end: 0x1daaf, script: 0x73676e77},
-	{start: 0x1e000, end: 0x1e006, script: 0x676c6167},
-	{start: 0x1e008, end: 0x1e018, script: 0x676c6167},
-	{start: 0x1e01b, end: 0x1e021, script: 0x676c6167},
-	{start: 0x1e023, end: 0x1e024, script: 0x676c6167},
-	{start: 0x1e026, end: 0x1e02a, script: 0x676c6167},
-	{start: 0x1e100, end: 0x1e12c, script: 0x686d6e70},
-	{start: 0x1e130, end: 0x1e13d, script: 0x686d6e70},
-	{start: 0x1e140, end: 0x1e149, script: 0x686d6e70},
-	{start: 0x1e14e, end: 0x1e14f, script: 0x686d6e70},
-	{start: 0x1e2c0, end: 0x1e2f9, script: 0x7763686f},
-	{start: 0x1e2ff, end: 0x1e2ff, script: 0x7763686f},
-	{start: 0x1e800, end: 0x1e8c4, script: 0x6d656e64},
-	{start: 0x1e8c7, end: 0x1e8d6, script: 0x6d656e64},
-	{start: 0x1e900, end: 0x1e94b, script: 0x61646c6d},
-	{start: 0x1e950, end: 0x1e959, script: 0x61646c6d},
-	{start: 0x1e95e, end: 0x1e95f, script: 0x61646c6d},
-	{start: 0x1ec71, end: 0x1ecb4, script: 0x7a797979},
-	{start: 0x1ed01, end: 0x1ed3d, script: 0x7a797979},
-	{start: 0x1ee00, end: 0x1ee03, script: 0x61726162},
-	{start: 0x1ee05, end: 0x1ee1f, script: 0x61726162},
-	{start: 0x1ee21, end: 0x1ee22, script: 0x61726162},
-	{start: 0x1ee24, end: 0x1ee24, script: 0x61726162},
-	{start: 0x1ee27, end: 0x1ee27, script: 0x61726162},
-	{start: 0x1ee29, end: 0x1ee32, script: 0x61726162},
-	{start: 0x1ee34, end: 0x1ee37, script: 0x61726162},
-	{start: 0x1ee39, end: 0x1ee39, script: 0x61726162},
-	{start: 0x1ee3b, end: 0x1ee3b, script: 0x61726162},
-	{start: 0x1ee42, end: 0x1ee42, script: 0x61726162},
-	{start: 0x1ee47, end: 0x1ee47, script: 0x61726162},
-	{start: 0x1ee49, end: 0x1ee49, script: 0x61726162},
-	{start: 0x1ee4b, end: 0x1ee4b, script: 0x61726162},
-	{start: 0x1ee4d, end: 0x1ee4f, script: 0x61726162},
-	{start: 0x1ee51, end: 0x1ee52, script: 0x61726162},
-	{start: 0x1ee54, end: 0x1ee54, script: 0x61726162},
-	{start: 0x1ee57, end: 0x1ee57, script: 0x61726162},
-	{start: 0x1ee59, end: 0x1ee59, script: 0x61726162},
-	{start: 0x1ee5b, end: 0x1ee5b, script: 0x61726162},
-	{start: 0x1ee5d, end: 0x1ee5d, script: 0x61726162},
-	{start: 0x1ee5f, end: 0x1ee5f, script: 0x61726162},
-	{start: 0x1ee61, end: 0x1ee62, script: 0x61726162},
-	{start: 0x1ee64, end: 0x1ee64, script: 0x61726162},
-	{start: 0x1ee67, end: 0x1ee6a, script: 0x61726162},
-	{start: 0x1ee6c, end: 0x1ee72, script: 0x61726162},
-	{start: 0x1ee74, end: 0x1ee77, script: 0x61726162},
-	{start: 0x1ee79, end: 0x1ee7c, script: 0x61726162},
-	{start: 0x1ee7e, end: 0x1ee7e, script: 0x61726162},
-	{start: 0x1ee80, end: 0x1ee89, script: 0x61726162},
-	{start: 0x1ee8b, end: 0x1ee9b, script: 0x61726162},
-	{start: 0x1eea1, end: 0x1eea3, script: 0x61726162},
-	{start: 0x1eea5, end: 0x1eea9, script: 0x61726162},
-	{start: 0x1eeab, end: 0x1eebb, script: 0x61726162},
-	{start: 0x1eef0, end: 0x1eef1, script: 0x61726162},
-	{start: 0x1f000, end: 0x1f02b, script: 0x7a797979},
-	{start: 0x1f030, end: 0x1f093, script: 0x7a797979},
-	{start: 0x1f0a0, end: 0x1f0ae, script: 0x7a797979},
-	{start: 0x1f0b1, end: 0x1f0bf, script: 0x7a797979},
-	{start: 0x1f0c1, end: 0x1f0cf, script: 0x7a797979},
-	{start: 0x1f0d1, end: 0x1f0f5, script: 0x7a797979},
-	{start: 0x1f100, end: 0x1f1ad, script: 0x7a797979},
-	{start: 0x1f1e6, end: 0x1f1ff, script: 0x7a797979},
-	{start: 0x1f200, end: 0x1f200, script: 0x68697261},
-	{start: 0x1f201, end: 0x1f202, script: 0x7a797979},
-	{start: 0x1f210, end: 0x1f23b, script: 0x7a797979},
-	{start: 0x1f240, end: 0x1f248, script: 0x7a797979},
-	{start: 0x1f250, end: 0x1f251, script: 0x7a797979},
-	{start: 0x1f260, end: 0x1f265, script: 0x7a797979},
-	{start: 0x1f300, end: 0x1f6d7, script: 0x7a797979},
-	{start: 0x1f6e0, end: 0x1f6ec, script: 0x7a797979},
-	{start: 0x1f6f0, end: 0x1f6fc, script: 0x7a797979},
-	{start: 0x1f700, end: 0x1f773, script: 0x7a797979},
-	{start: 0x1f780, end: 0x1f7d8, script: 0x7a797979},
-	{start: 0x1f7e0, end: 0x1f7eb, script: 0x7a797979},
-	{start: 0x1f800, end: 0x1f80b, script: 0x7a797979},
-	{start: 0x1f810, end: 0x1f847, script: 0x7a797979},
-	{start: 0x1f850, end: 0x1f859, script: 0x7a797979},
-	{start: 0x1f860, end: 0x1f887, script: 0x7a797979},
-	{start: 0x1f890, end: 0x1f8ad, script: 0x7a797979},
-	{start: 0x1f8b0, end: 0x1f8b1, script: 0x7a797979},
-	{start: 0x1f900, end: 0x1f978, script: 0x7a797979},
-	{start: 0x1f97a, end: 0x1f9cb, script: 0x7a797979},
-	{start: 0x1f9cd, end: 0x1fa53, script: 0x7a797979},
-	{start: 0x1fa60, end: 0x1fa6d, script: 0x7a797979},
-	{start: 0x1fa70, end: 0x1fa74, script: 0x7a797979},
-	{start: 0x1fa78, end: 0x1fa7a, script: 0x7a797979},
-	{start: 0x1fa80, end: 0x1fa86, script: 0x7a797979},
-	{start: 0x1fa90, end: 0x1faa8, script: 0x7a797979},
-	{start: 0x1fab0, end: 0x1fab6, script: 0x7a797979},
-	{start: 0x1fac0, end: 0x1fac2, script: 0x7a797979},
-	{start: 0x1fad0, end: 0x1fad6, script: 0x7a797979},
-	{start: 0x1fb00, end: 0x1fb92, script: 0x7a797979},
-	{start: 0x1fb94, end: 0x1fbca, script: 0x7a797979},
-	{start: 0x1fbf0, end: 0x1fbf9, script: 0x7a797979},
-	{start: 0x20000, end: 0x2a6dd, script: 0x68616e69},
-	{start: 0x2a700, end: 0x2b734, script: 0x68616e69},
-	{start: 0x2b740, end: 0x2b81d, script: 0x68616e69},
-	{start: 0x2b820, end: 0x2cea1, script: 0x68616e69},
-	{start: 0x2ceb0, end: 0x2ebe0, script: 0x68616e69},
-	{start: 0x2f800, end: 0x2fa1d, script: 0x68616e69},
-	{start: 0x30000, end: 0x3134a, script: 0x68616e69},
-	{start: 0xe0001, end: 0xe0001, script: 0x7a797979},
-	{start: 0xe0020, end: 0xe007f, script: 0x7a797979},
-	{start: 0xe0100, end: 0xe01ef, script: 0x7a696e68},
+// ScriptRanges is a sorted list of script ranges.
+var ScriptRanges = [...]ScriptRange{
+	{0x0, 0x40, 0x7a797979},
+	{0x41, 0x5a, 0x6c61746e},
+	{0x5b, 0x60, 0x7a797979},
+	{0x61, 0x7a, 0x6c61746e},
+	{0x7b, 0xa9, 0x7a797979},
+	{0xaa, 0xaa, 0x6c61746e},
+	{0xab, 0xb9, 0x7a797979},
+	{0xba, 0xba, 0x6c61746e},
+	{0xbb, 0xbf, 0x7a797979},
+	{0xc0, 0xd6, 0x6c61746e},
+	{0xd7, 0xd7, 0x7a797979},
+	{0xd8, 0xf6, 0x6c61746e},
+	{0xf7, 0xf7, 0x7a797979},
+	{0xf8, 0x2b8, 0x6c61746e},
+	{0x2b9, 0x2df, 0x7a797979},
+	{0x2e0, 0x2e4, 0x6c61746e},
+	{0x2e5, 0x2e9, 0x7a797979},
+	{0x2ea, 0x2eb, 0x626f706f},
+	{0x2ec, 0x2ff, 0x7a797979},
+	{0x300, 0x36f, 0x7a696e68},
+	{0x370, 0x373, 0x6772656b},
+	{0x374, 0x374, 0x7a797979},
+	{0x375, 0x377, 0x6772656b},
+	{0x37a, 0x37d, 0x6772656b},
+	{0x37e, 0x37e, 0x7a797979},
+	{0x37f, 0x37f, 0x6772656b},
+	{0x384, 0x384, 0x6772656b},
+	{0x385, 0x385, 0x7a797979},
+	{0x386, 0x386, 0x6772656b},
+	{0x387, 0x387, 0x7a797979},
+	{0x388, 0x38a, 0x6772656b},
+	{0x38c, 0x38c, 0x6772656b},
+	{0x38e, 0x3a1, 0x6772656b},
+	{0x3a3, 0x3e1, 0x6772656b},
+	{0x3e2, 0x3ef, 0x636f7074},
+	{0x3f0, 0x3ff, 0x6772656b},
+	{0x400, 0x484, 0x6379726c},
+	{0x485, 0x486, 0x7a696e68},
+	{0x487, 0x52f, 0x6379726c},
+	{0x531, 0x556, 0x61726d6e},
+	{0x559, 0x58a, 0x61726d6e},
+	{0x58d, 0x58f, 0x61726d6e},
+	{0x591, 0x5c7, 0x68656272},
+	{0x5d0, 0x5ea, 0x68656272},
+	{0x5ef, 0x5f4, 0x68656272},
+	{0x600, 0x604, 0x61726162},
+	{0x605, 0x605, 0x7a797979},
+	{0x606, 0x60b, 0x61726162},
+	{0x60c, 0x60c, 0x7a797979},
+	{0x60d, 0x61a, 0x61726162},
+	{0x61b, 0x61b, 0x7a797979},
+	{0x61c, 0x61e, 0x61726162},
+	{0x61f, 0x61f, 0x7a797979},
+	{0x620, 0x63f, 0x61726162},
+	{0x640, 0x640, 0x7a797979},
+	{0x641, 0x64a, 0x61726162},
+	{0x64b, 0x655, 0x7a696e68},
+	{0x656, 0x66f, 0x61726162},
+	{0x670, 0x670, 0x7a696e68},
+	{0x671, 0x6dc, 0x61726162},
+	{0x6dd, 0x6dd, 0x7a797979},
+	{0x6de, 0x6ff, 0x61726162},
+	{0x700, 0x70d, 0x73797263},
+	{0x70f, 0x74a, 0x73797263},
+	{0x74d, 0x74f, 0x73797263},
+	{0x750, 0x77f, 0x61726162},
+	{0x780, 0x7b1, 0x74686161},
+	{0x7c0, 0x7fa, 0x6e6b6f6f},
+	{0x7fd, 0x7ff, 0x6e6b6f6f},
+	{0x800, 0x82d, 0x73616d72},
+	{0x830, 0x83e, 0x73616d72},
+	{0x840, 0x85b, 0x6d616e64},
+	{0x85e, 0x85e, 0x6d616e64},
+	{0x860, 0x86a, 0x73797263},
+	{0x870, 0x88e, 0x61726162},
+	{0x890, 0x891, 0x61726162},
+	{0x898, 0x8e1, 0x61726162},
+	{0x8e2, 0x8e2, 0x7a797979},
+	{0x8e3, 0x8ff, 0x61726162},
+	{0x900, 0x950, 0x64657661},
+	{0x951, 0x954, 0x7a696e68},
+	{0x955, 0x963, 0x64657661},
+	{0x964, 0x965, 0x7a797979},
+	{0x966, 0x97f, 0x64657661},
+	{0x980, 0x983, 0x62656e67},
+	{0x985, 0x98c, 0x62656e67},
+	{0x98f, 0x990, 0x62656e67},
+	{0x993, 0x9a8, 0x62656e67},
+	{0x9aa, 0x9b0, 0x62656e67},
+	{0x9b2, 0x9b2, 0x62656e67},
+	{0x9b6, 0x9b9, 0x62656e67},
+	{0x9bc, 0x9c4, 0x62656e67},
+	{0x9c7, 0x9c8, 0x62656e67},
+	{0x9cb, 0x9ce, 0x62656e67},
+	{0x9d7, 0x9d7, 0x62656e67},
+	{0x9dc, 0x9dd, 0x62656e67},
+	{0x9df, 0x9e3, 0x62656e67},
+	{0x9e6, 0x9fe, 0x62656e67},
+	{0xa01, 0xa03, 0x67757275},
+	{0xa05, 0xa0a, 0x67757275},
+	{0xa0f, 0xa10, 0x67757275},
+	{0xa13, 0xa28, 0x67757275},
+	{0xa2a, 0xa30, 0x67757275},
+	{0xa32, 0xa33, 0x67757275},
+	{0xa35, 0xa36, 0x67757275},
+	{0xa38, 0xa39, 0x67757275},
+	{0xa3c, 0xa3c, 0x67757275},
+	{0xa3e, 0xa42, 0x67757275},
+	{0xa47, 0xa48, 0x67757275},
+	{0xa4b, 0xa4d, 0x67757275},
+	{0xa51, 0xa51, 0x67757275},
+	{0xa59, 0xa5c, 0x67757275},
+	{0xa5e, 0xa5e, 0x67757275},
+	{0xa66, 0xa76, 0x67757275},
+	{0xa81, 0xa83, 0x67756a72},
+	{0xa85, 0xa8d, 0x67756a72},
+	{0xa8f, 0xa91, 0x67756a72},
+	{0xa93, 0xaa8, 0x67756a72},
+	{0xaaa, 0xab0, 0x67756a72},
+	{0xab2, 0xab3, 0x67756a72},
+	{0xab5, 0xab9, 0x67756a72},
+	{0xabc, 0xac5, 0x67756a72},
+	{0xac7, 0xac9, 0x67756a72},
+	{0xacb, 0xacd, 0x67756a72},
+	{0xad0, 0xad0, 0x67756a72},
+	{0xae0, 0xae3, 0x67756a72},
+	{0xae6, 0xaf1, 0x67756a72},
+	{0xaf9, 0xaff, 0x67756a72},
+	{0xb01, 0xb03, 0x6f727961},
+	{0xb05, 0xb0c, 0x6f727961},
+	{0xb0f, 0xb10, 0x6f727961},
+	{0xb13, 0xb28, 0x6f727961},
+	{0xb2a, 0xb30, 0x6f727961},
+	{0xb32, 0xb33, 0x6f727961},
+	{0xb35, 0xb39, 0x6f727961},
+	{0xb3c, 0xb44, 0x6f727961},
+	{0xb47, 0xb48, 0x6f727961},
+	{0xb4b, 0xb4d, 0x6f727961},
+	{0xb55, 0xb57, 0x6f727961},
+	{0xb5c, 0xb5d, 0x6f727961},
+	{0xb5f, 0xb63, 0x6f727961},
+	{0xb66, 0xb77, 0x6f727961},
+	{0xb82, 0xb83, 0x74616d6c},
+	{0xb85, 0xb8a, 0x74616d6c},
+	{0xb8e, 0xb90, 0x74616d6c},
+	{0xb92, 0xb95, 0x74616d6c},
+	{0xb99, 0xb9a, 0x74616d6c},
+	{0xb9c, 0xb9c, 0x74616d6c},
+	{0xb9e, 0xb9f, 0x74616d6c},
+	{0xba3, 0xba4, 0x74616d6c},
+	{0xba8, 0xbaa, 0x74616d6c},
+	{0xbae, 0xbb9, 0x74616d6c},
+	{0xbbe, 0xbc2, 0x74616d6c},
+	{0xbc6, 0xbc8, 0x74616d6c},
+	{0xbca, 0xbcd, 0x74616d6c},
+	{0xbd0, 0xbd0, 0x74616d6c},
+	{0xbd7, 0xbd7, 0x74616d6c},
+	{0xbe6, 0xbfa, 0x74616d6c},
+	{0xc00, 0xc0c, 0x74656c75},
+	{0xc0e, 0xc10, 0x74656c75},
+	{0xc12, 0xc28, 0x74656c75},
+	{0xc2a, 0xc39, 0x74656c75},
+	{0xc3c, 0xc44, 0x74656c75},
+	{0xc46, 0xc48, 0x74656c75},
+	{0xc4a, 0xc4d, 0x74656c75},
+	{0xc55, 0xc56, 0x74656c75},
+	{0xc58, 0xc5a, 0x74656c75},
+	{0xc5d, 0xc5d, 0x74656c75},
+	{0xc60, 0xc63, 0x74656c75},
+	{0xc66, 0xc6f, 0x74656c75},
+	{0xc77, 0xc7f, 0x74656c75},
+	{0xc80, 0xc8c, 0x6b6e6461},
+	{0xc8e, 0xc90, 0x6b6e6461},
+	{0xc92, 0xca8, 0x6b6e6461},
+	{0xcaa, 0xcb3, 0x6b6e6461},
+	{0xcb5, 0xcb9, 0x6b6e6461},
+	{0xcbc, 0xcc4, 0x6b6e6461},
+	{0xcc6, 0xcc8, 0x6b6e6461},
+	{0xcca, 0xccd, 0x6b6e6461},
+	{0xcd5, 0xcd6, 0x6b6e6461},
+	{0xcdd, 0xcde, 0x6b6e6461},
+	{0xce0, 0xce3, 0x6b6e6461},
+	{0xce6, 0xcef, 0x6b6e6461},
+	{0xcf1, 0xcf3, 0x6b6e6461},
+	{0xd00, 0xd0c, 0x6d6c796d},
+	{0xd0e, 0xd10, 0x6d6c796d},
+	{0xd12, 0xd44, 0x6d6c796d},
+	{0xd46, 0xd48, 0x6d6c796d},
+	{0xd4a, 0xd4f, 0x6d6c796d},
+	{0xd54, 0xd63, 0x6d6c796d},
+	{0xd66, 0xd7f, 0x6d6c796d},
+	{0xd81, 0xd83, 0x73696e68},
+	{0xd85, 0xd96, 0x73696e68},
+	{0xd9a, 0xdb1, 0x73696e68},
+	{0xdb3, 0xdbb, 0x73696e68},
+	{0xdbd, 0xdbd, 0x73696e68},
+	{0xdc0, 0xdc6, 0x73696e68},
+	{0xdca, 0xdca, 0x73696e68},
+	{0xdcf, 0xdd4, 0x73696e68},
+	{0xdd6, 0xdd6, 0x73696e68},
+	{0xdd8, 0xddf, 0x73696e68},
+	{0xde6, 0xdef, 0x73696e68},
+	{0xdf2, 0xdf4, 0x73696e68},
+	{0xe01, 0xe3a, 0x74686169},
+	{0xe3f, 0xe3f, 0x7a797979},
+	{0xe40, 0xe5b, 0x74686169},
+	{0xe81, 0xe82, 0x6c616f6f},
+	{0xe84, 0xe84, 0x6c616f6f},
+	{0xe86, 0xe8a, 0x6c616f6f},
+	{0xe8c, 0xea3, 0x6c616f6f},
+	{0xea5, 0xea5, 0x6c616f6f},
+	{0xea7, 0xebd, 0x6c616f6f},
+	{0xec0, 0xec4, 0x6c616f6f},
+	{0xec6, 0xec6, 0x6c616f6f},
+	{0xec8, 0xece, 0x6c616f6f},
+	{0xed0, 0xed9, 0x6c616f6f},
+	{0xedc, 0xedf, 0x6c616f6f},
+	{0xf00, 0xf47, 0x74696274},
+	{0xf49, 0xf6c, 0x74696274},
+	{0xf71, 0xf97, 0x74696274},
+	{0xf99, 0xfbc, 0x74696274},
+	{0xfbe, 0xfcc, 0x74696274},
+	{0xfce, 0xfd4, 0x74696274},
+	{0xfd5, 0xfd8, 0x7a797979},
+	{0xfd9, 0xfda, 0x74696274},
+	{0x1000, 0x109f, 0x6d796d72},
+	{0x10a0, 0x10c5, 0x67656f72},
+	{0x10c7, 0x10c7, 0x67656f72},
+	{0x10cd, 0x10cd, 0x67656f72},
+	{0x10d0, 0x10fa, 0x67656f72},
+	{0x10fb, 0x10fb, 0x7a797979},
+	{0x10fc, 0x10ff, 0x67656f72},
+	{0x1100, 0x11ff, 0x68616e67},
+	{0x1200, 0x1248, 0x65746869},
+	{0x124a, 0x124d, 0x65746869},
+	{0x1250, 0x1256, 0x65746869},
+	{0x1258, 0x1258, 0x65746869},
+	{0x125a, 0x125d, 0x65746869},
+	{0x1260, 0x1288, 0x65746869},
+	{0x128a, 0x128d, 0x65746869},
+	{0x1290, 0x12b0, 0x65746869},
+	{0x12b2, 0x12b5, 0x65746869},
+	{0x12b8, 0x12be, 0x65746869},
+	{0x12c0, 0x12c0, 0x65746869},
+	{0x12c2, 0x12c5, 0x65746869},
+	{0x12c8, 0x12d6, 0x65746869},
+	{0x12d8, 0x1310, 0x65746869},
+	{0x1312, 0x1315, 0x65746869},
+	{0x1318, 0x135a, 0x65746869},
+	{0x135d, 0x137c, 0x65746869},
+	{0x1380, 0x1399, 0x65746869},
+	{0x13a0, 0x13f5, 0x63686572},
+	{0x13f8, 0x13fd, 0x63686572},
+	{0x1400, 0x167f, 0x63616e73},
+	{0x1680, 0x169c, 0x6f67616d},
+	{0x16a0, 0x16ea, 0x72756e72},
+	{0x16eb, 0x16ed, 0x7a797979},
+	{0x16ee, 0x16f8, 0x72756e72},
+	{0x1700, 0x1715, 0x74676c67},
+	{0x171f, 0x171f, 0x74676c67},
+	{0x1720, 0x1734, 0x68616e6f},
+	{0x1735, 0x1736, 0x7a797979},
+	{0x1740, 0x1753, 0x62756864},
+	{0x1760, 0x176c, 0x74616762},
+	{0x176e, 0x1770, 0x74616762},
+	{0x1772, 0x1773, 0x74616762},
+	{0x1780, 0x17dd, 0x6b686d72},
+	{0x17e0, 0x17e9, 0x6b686d72},
+	{0x17f0, 0x17f9, 0x6b686d72},
+	{0x1800, 0x1801, 0x6d6f6e67},
+	{0x1802, 0x1803, 0x7a797979},
+	{0x1804, 0x1804, 0x6d6f6e67},
+	{0x1805, 0x1805, 0x7a797979},
+	{0x1806, 0x1819, 0x6d6f6e67},
+	{0x1820, 0x1878, 0x6d6f6e67},
+	{0x1880, 0x18aa, 0x6d6f6e67},
+	{0x18b0, 0x18f5, 0x63616e73},
+	{0x1900, 0x191e, 0x6c696d62},
+	{0x1920, 0x192b, 0x6c696d62},
+	{0x1930, 0x193b, 0x6c696d62},
+	{0x1940, 0x1940, 0x6c696d62},
+	{0x1944, 0x194f, 0x6c696d62},
+	{0x1950, 0x196d, 0x74616c65},
+	{0x1970, 0x1974, 0x74616c65},
+	{0x1980, 0x19ab, 0x74616c75},
+	{0x19b0, 0x19c9, 0x74616c75},
+	{0x19d0, 0x19da, 0x74616c75},
+	{0x19de, 0x19df, 0x74616c75},
+	{0x19e0, 0x19ff, 0x6b686d72},
+	{0x1a00, 0x1a1b, 0x62756769},
+	{0x1a1e, 0x1a1f, 0x62756769},
+	{0x1a20, 0x1a5e, 0x6c616e61},
+	{0x1a60, 0x1a7c, 0x6c616e61},
+	{0x1a7f, 0x1a89, 0x6c616e61},
+	{0x1a90, 0x1a99, 0x6c616e61},
+	{0x1aa0, 0x1aad, 0x6c616e61},
+	{0x1ab0, 0x1ace, 0x7a696e68},
+	{0x1b00, 0x1b4c, 0x62616c69},
+	{0x1b50, 0x1b7e, 0x62616c69},
+	{0x1b80, 0x1bbf, 0x73756e64},
+	{0x1bc0, 0x1bf3, 0x6261746b},
+	{0x1bfc, 0x1bff, 0x6261746b},
+	{0x1c00, 0x1c37, 0x6c657063},
+	{0x1c3b, 0x1c49, 0x6c657063},
+	{0x1c4d, 0x1c4f, 0x6c657063},
+	{0x1c50, 0x1c7f, 0x6f6c636b},
+	{0x1c80, 0x1c88, 0x6379726c},
+	{0x1c90, 0x1cba, 0x67656f72},
+	{0x1cbd, 0x1cbf, 0x67656f72},
+	{0x1cc0, 0x1cc7, 0x73756e64},
+	{0x1cd0, 0x1cd2, 0x7a696e68},
+	{0x1cd3, 0x1cd3, 0x7a797979},
+	{0x1cd4, 0x1ce0, 0x7a696e68},
+	{0x1ce1, 0x1ce1, 0x7a797979},
+	{0x1ce2, 0x1ce8, 0x7a696e68},
+	{0x1ce9, 0x1cec, 0x7a797979},
+	{0x1ced, 0x1ced, 0x7a696e68},
+	{0x1cee, 0x1cf3, 0x7a797979},
+	{0x1cf4, 0x1cf4, 0x7a696e68},
+	{0x1cf5, 0x1cf7, 0x7a797979},
+	{0x1cf8, 0x1cf9, 0x7a696e68},
+	{0x1cfa, 0x1cfa, 0x7a797979},
+	{0x1d00, 0x1d25, 0x6c61746e},
+	{0x1d26, 0x1d2a, 0x6772656b},
+	{0x1d2b, 0x1d2b, 0x6379726c},
+	{0x1d2c, 0x1d5c, 0x6c61746e},
+	{0x1d5d, 0x1d61, 0x6772656b},
+	{0x1d62, 0x1d65, 0x6c61746e},
+	{0x1d66, 0x1d6a, 0x6772656b},
+	{0x1d6b, 0x1d77, 0x6c61746e},
+	{0x1d78, 0x1d78, 0x6379726c},
+	{0x1d79, 0x1dbe, 0x6c61746e},
+	{0x1dbf, 0x1dbf, 0x6772656b},
+	{0x1dc0, 0x1dff, 0x7a696e68},
+	{0x1e00, 0x1eff, 0x6c61746e},
+	{0x1f00, 0x1f15, 0x6772656b},
+	{0x1f18, 0x1f1d, 0x6772656b},
+	{0x1f20, 0x1f45, 0x6772656b},
+	{0x1f48, 0x1f4d, 0x6772656b},
+	{0x1f50, 0x1f57, 0x6772656b},
+	{0x1f59, 0x1f59, 0x6772656b},
+	{0x1f5b, 0x1f5b, 0x6772656b},
+	{0x1f5d, 0x1f5d, 0x6772656b},
+	{0x1f5f, 0x1f7d, 0x6772656b},
+	{0x1f80, 0x1fb4, 0x6772656b},
+	{0x1fb6, 0x1fc4, 0x6772656b},
+	{0x1fc6, 0x1fd3, 0x6772656b},
+	{0x1fd6, 0x1fdb, 0x6772656b},
+	{0x1fdd, 0x1fef, 0x6772656b},
+	{0x1ff2, 0x1ff4, 0x6772656b},
+	{0x1ff6, 0x1ffe, 0x6772656b},
+	{0x2000, 0x200b, 0x7a797979},
+	{0x200c, 0x200d, 0x7a696e68},
+	{0x200e, 0x2064, 0x7a797979},
+	{0x2066, 0x2070, 0x7a797979},
+	{0x2071, 0x2071, 0x6c61746e},
+	{0x2074, 0x207e, 0x7a797979},
+	{0x207f, 0x207f, 0x6c61746e},
+	{0x2080, 0x208e, 0x7a797979},
+	{0x2090, 0x209c, 0x6c61746e},
+	{0x20a0, 0x20c0, 0x7a797979},
+	{0x20d0, 0x20f0, 0x7a696e68},
+	{0x2100, 0x2125, 0x7a797979},
+	{0x2126, 0x2126, 0x6772656b},
+	{0x2127, 0x2129, 0x7a797979},
+	{0x212a, 0x212b, 0x6c61746e},
+	{0x212c, 0x2131, 0x7a797979},
+	{0x2132, 0x2132, 0x6c61746e},
+	{0x2133, 0x214d, 0x7a797979},
+	{0x214e, 0x214e, 0x6c61746e},
+	{0x214f, 0x215f, 0x7a797979},
+	{0x2160, 0x2188, 0x6c61746e},
+	{0x2189, 0x218b, 0x7a797979},
+	{0x2190, 0x2426, 0x7a797979},
+	{0x2440, 0x244a, 0x7a797979},
+	{0x2460, 0x27ff, 0x7a797979},
+	{0x2800, 0x28ff, 0x62726169},
+	{0x2900, 0x2b73, 0x7a797979},
+	{0x2b76, 0x2b95, 0x7a797979},
+	{0x2b97, 0x2bff, 0x7a797979},
+	{0x2c00, 0x2c5f, 0x676c6167},
+	{0x2c60, 0x2c7f, 0x6c61746e},
+	{0x2c80, 0x2cf3, 0x636f7074},
+	{0x2cf9, 0x2cff, 0x636f7074},
+	{0x2d00, 0x2d25, 0x67656f72},
+	{0x2d27, 0x2d27, 0x67656f72},
+	{0x2d2d, 0x2d2d, 0x67656f72},
+	{0x2d30, 0x2d67, 0x74666e67},
+	{0x2d6f, 0x2d70, 0x74666e67},
+	{0x2d7f, 0x2d7f, 0x74666e67},
+	{0x2d80, 0x2d96, 0x65746869},
+	{0x2da0, 0x2da6, 0x65746869},
+	{0x2da8, 0x2dae, 0x65746869},
+	{0x2db0, 0x2db6, 0x65746869},
+	{0x2db8, 0x2dbe, 0x65746869},
+	{0x2dc0, 0x2dc6, 0x65746869},
+	{0x2dc8, 0x2dce, 0x65746869},
+	{0x2dd0, 0x2dd6, 0x65746869},
+	{0x2dd8, 0x2dde, 0x65746869},
+	{0x2de0, 0x2dff, 0x6379726c},
+	{0x2e00, 0x2e5d, 0x7a797979},
+	{0x2e80, 0x2e99, 0x68616e69},
+	{0x2e9b, 0x2ef3, 0x68616e69},
+	{0x2f00, 0x2fd5, 0x68616e69},
+	{0x2ff0, 0x2ffb, 0x7a797979},
+	{0x3000, 0x3004, 0x7a797979},
+	{0x3005, 0x3005, 0x68616e69},
+	{0x3006, 0x3006, 0x7a797979},
+	{0x3007, 0x3007, 0x68616e69},
+	{0x3008, 0x3020, 0x7a797979},
+	{0x3021, 0x3029, 0x68616e69},
+	{0x302a, 0x302d, 0x7a696e68},
+	{0x302e, 0x302f, 0x68616e67},
+	{0x3030, 0x3037, 0x7a797979},
+	{0x3038, 0x303b, 0x68616e69},
+	{0x303c, 0x303f, 0x7a797979},
+	{0x3041, 0x3096, 0x68697261},
+	{0x3099, 0x309a, 0x7a696e68},
+	{0x309b, 0x309c, 0x7a797979},
+	{0x309d, 0x309f, 0x68697261},
+	{0x30a0, 0x30a0, 0x7a797979},
+	{0x30a1, 0x30fa, 0x6b616e61},
+	{0x30fb, 0x30fc, 0x7a797979},
+	{0x30fd, 0x30ff, 0x6b616e61},
+	{0x3105, 0x312f, 0x626f706f},
+	{0x3131, 0x318e, 0x68616e67},
+	{0x3190, 0x319f, 0x7a797979},
+	{0x31a0, 0x31bf, 0x626f706f},
+	{0x31c0, 0x31e3, 0x7a797979},
+	{0x31f0, 0x31ff, 0x6b616e61},
+	{0x3200, 0x321e, 0x68616e67},
+	{0x3220, 0x325f, 0x7a797979},
+	{0x3260, 0x327e, 0x68616e67},
+	{0x327f, 0x32cf, 0x7a797979},
+	{0x32d0, 0x32fe, 0x6b616e61},
+	{0x32ff, 0x32ff, 0x7a797979},
+	{0x3300, 0x3357, 0x6b616e61},
+	{0x3358, 0x33ff, 0x7a797979},
+	{0x3400, 0x4dbf, 0x68616e69},
+	{0x4dc0, 0x4dff, 0x7a797979},
+	{0x4e00, 0x9fff, 0x68616e69},
+	{0xa000, 0xa48c, 0x79696969},
+	{0xa490, 0xa4c6, 0x79696969},
+	{0xa4d0, 0xa4ff, 0x6c697375},
+	{0xa500, 0xa62b, 0x76616969},
+	{0xa640, 0xa69f, 0x6379726c},
+	{0xa6a0, 0xa6f7, 0x62616d75},
+	{0xa700, 0xa721, 0x7a797979},
+	{0xa722, 0xa787, 0x6c61746e},
+	{0xa788, 0xa78a, 0x7a797979},
+	{0xa78b, 0xa7ca, 0x6c61746e},
+	{0xa7d0, 0xa7d1, 0x6c61746e},
+	{0xa7d3, 0xa7d3, 0x6c61746e},
+	{0xa7d5, 0xa7d9, 0x6c61746e},
+	{0xa7f2, 0xa7ff, 0x6c61746e},
+	{0xa800, 0xa82c, 0x73796c6f},
+	{0xa830, 0xa839, 0x7a797979},
+	{0xa840, 0xa877, 0x70686167},
+	{0xa880, 0xa8c5, 0x73617572},
+	{0xa8ce, 0xa8d9, 0x73617572},
+	{0xa8e0, 0xa8ff, 0x64657661},
+	{0xa900, 0xa92d, 0x6b616c69},
+	{0xa92e, 0xa92e, 0x7a797979},
+	{0xa92f, 0xa92f, 0x6b616c69},
+	{0xa930, 0xa953, 0x726a6e67},
+	{0xa95f, 0xa95f, 0x726a6e67},
+	{0xa960, 0xa97c, 0x68616e67},
+	{0xa980, 0xa9cd, 0x6a617661},
+	{0xa9cf, 0xa9cf, 0x7a797979},
+	{0xa9d0, 0xa9d9, 0x6a617661},
+	{0xa9de, 0xa9df, 0x6a617661},
+	{0xa9e0, 0xa9fe, 0x6d796d72},
+	{0xaa00, 0xaa36, 0x6368616d},
+	{0xaa40, 0xaa4d, 0x6368616d},
+	{0xaa50, 0xaa59, 0x6368616d},
+	{0xaa5c, 0xaa5f, 0x6368616d},
+	{0xaa60, 0xaa7f, 0x6d796d72},
+	{0xaa80, 0xaac2, 0x74617674},
+	{0xaadb, 0xaadf, 0x74617674},
+	{0xaae0, 0xaaf6, 0x6d746569},
+	{0xab01, 0xab06, 0x65746869},
+	{0xab09, 0xab0e, 0x65746869},
+	{0xab11, 0xab16, 0x65746869},
+	{0xab20, 0xab26, 0x65746869},
+	{0xab28, 0xab2e, 0x65746869},
+	{0xab30, 0xab5a, 0x6c61746e},
+	{0xab5b, 0xab5b, 0x7a797979},
+	{0xab5c, 0xab64, 0x6c61746e},
+	{0xab65, 0xab65, 0x6772656b},
+	{0xab66, 0xab69, 0x6c61746e},
+	{0xab6a, 0xab6b, 0x7a797979},
+	{0xab70, 0xabbf, 0x63686572},
+	{0xabc0, 0xabed, 0x6d746569},
+	{0xabf0, 0xabf9, 0x6d746569},
+	{0xac00, 0xd7a3, 0x68616e67},
+	{0xd7b0, 0xd7c6, 0x68616e67},
+	{0xd7cb, 0xd7fb, 0x68616e67},
+	{0xf900, 0xfa6d, 0x68616e69},
+	{0xfa70, 0xfad9, 0x68616e69},
+	{0xfb00, 0xfb06, 0x6c61746e},
+	{0xfb13, 0xfb17, 0x61726d6e},
+	{0xfb1d, 0xfb36, 0x68656272},
+	{0xfb38, 0xfb3c, 0x68656272},
+	{0xfb3e, 0xfb3e, 0x68656272},
+	{0xfb40, 0xfb41, 0x68656272},
+	{0xfb43, 0xfb44, 0x68656272},
+	{0xfb46, 0xfb4f, 0x68656272},
+	{0xfb50, 0xfbc2, 0x61726162},
+	{0xfbd3, 0xfd3d, 0x61726162},
+	{0xfd3e, 0xfd3f, 0x7a797979},
+	{0xfd40, 0xfd8f, 0x61726162},
+	{0xfd92, 0xfdc7, 0x61726162},
+	{0xfdcf, 0xfdcf, 0x61726162},
+	{0xfdf0, 0xfdff, 0x61726162},
+	{0xfe00, 0xfe0f, 0x7a696e68},
+	{0xfe10, 0xfe19, 0x7a797979},
+	{0xfe20, 0xfe2d, 0x7a696e68},
+	{0xfe2e, 0xfe2f, 0x6379726c},
+	{0xfe30, 0xfe52, 0x7a797979},
+	{0xfe54, 0xfe66, 0x7a797979},
+	{0xfe68, 0xfe6b, 0x7a797979},
+	{0xfe70, 0xfe74, 0x61726162},
+	{0xfe76, 0xfefc, 0x61726162},
+	{0xfeff, 0xfeff, 0x7a797979},
+	{0xff01, 0xff20, 0x7a797979},
+	{0xff21, 0xff3a, 0x6c61746e},
+	{0xff3b, 0xff40, 0x7a797979},
+	{0xff41, 0xff5a, 0x6c61746e},
+	{0xff5b, 0xff65, 0x7a797979},
+	{0xff66, 0xff6f, 0x6b616e61},
+	{0xff70, 0xff70, 0x7a797979},
+	{0xff71, 0xff9d, 0x6b616e61},
+	{0xff9e, 0xff9f, 0x7a797979},
+	{0xffa0, 0xffbe, 0x68616e67},
+	{0xffc2, 0xffc7, 0x68616e67},
+	{0xffca, 0xffcf, 0x68616e67},
+	{0xffd2, 0xffd7, 0x68616e67},
+	{0xffda, 0xffdc, 0x68616e67},
+	{0xffe0, 0xffe6, 0x7a797979},
+	{0xffe8, 0xffee, 0x7a797979},
+	{0xfff9, 0xfffd, 0x7a797979},
+	{0x10000, 0x1000b, 0x6c696e62},
+	{0x1000d, 0x10026, 0x6c696e62},
+	{0x10028, 0x1003a, 0x6c696e62},
+	{0x1003c, 0x1003d, 0x6c696e62},
+	{0x1003f, 0x1004d, 0x6c696e62},
+	{0x10050, 0x1005d, 0x6c696e62},
+	{0x10080, 0x100fa, 0x6c696e62},
+	{0x10100, 0x10102, 0x7a797979},
+	{0x10107, 0x10133, 0x7a797979},
+	{0x10137, 0x1013f, 0x7a797979},
+	{0x10140, 0x1018e, 0x6772656b},
+	{0x10190, 0x1019c, 0x7a797979},
+	{0x101a0, 0x101a0, 0x6772656b},
+	{0x101d0, 0x101fc, 0x7a797979},
+	{0x101fd, 0x101fd, 0x7a696e68},
+	{0x10280, 0x1029c, 0x6c796369},
+	{0x102a0, 0x102d0, 0x63617269},
+	{0x102e0, 0x102e0, 0x7a696e68},
+	{0x102e1, 0x102fb, 0x7a797979},
+	{0x10300, 0x10323, 0x6974616c},
+	{0x1032d, 0x1032f, 0x6974616c},
+	{0x10330, 0x1034a, 0x676f7468},
+	{0x10350, 0x1037a, 0x7065726d},
+	{0x10380, 0x1039d, 0x75676172},
+	{0x1039f, 0x1039f, 0x75676172},
+	{0x103a0, 0x103c3, 0x7870656f},
+	{0x103c8, 0x103d5, 0x7870656f},
+	{0x10400, 0x1044f, 0x64737274},
+	{0x10450, 0x1047f, 0x73686177},
+	{0x10480, 0x1049d, 0x6f736d61},
+	{0x104a0, 0x104a9, 0x6f736d61},
+	{0x104b0, 0x104d3, 0x6f736765},
+	{0x104d8, 0x104fb, 0x6f736765},
+	{0x10500, 0x10527, 0x656c6261},
+	{0x10530, 0x10563, 0x61676862},
+	{0x1056f, 0x1056f, 0x61676862},
+	{0x10570, 0x1057a, 0x76697468},
+	{0x1057c, 0x1058a, 0x76697468},
+	{0x1058c, 0x10592, 0x76697468},
+	{0x10594, 0x10595, 0x76697468},
+	{0x10597, 0x105a1, 0x76697468},
+	{0x105a3, 0x105b1, 0x76697468},
+	{0x105b3, 0x105b9, 0x76697468},
+	{0x105bb, 0x105bc, 0x76697468},
+	{0x10600, 0x10736, 0x6c696e61},
+	{0x10740, 0x10755, 0x6c696e61},
+	{0x10760, 0x10767, 0x6c696e61},
+	{0x10780, 0x10785, 0x6c61746e},
+	{0x10787, 0x107b0, 0x6c61746e},
+	{0x107b2, 0x107ba, 0x6c61746e},
+	{0x10800, 0x10805, 0x63707274},
+	{0x10808, 0x10808, 0x63707274},
+	{0x1080a, 0x10835, 0x63707274},
+	{0x10837, 0x10838, 0x63707274},
+	{0x1083c, 0x1083c, 0x63707274},
+	{0x1083f, 0x1083f, 0x63707274},
+	{0x10840, 0x10855, 0x61726d69},
+	{0x10857, 0x1085f, 0x61726d69},
+	{0x10860, 0x1087f, 0x70616c6d},
+	{0x10880, 0x1089e, 0x6e626174},
+	{0x108a7, 0x108af, 0x6e626174},
+	{0x108e0, 0x108f2, 0x68617472},
+	{0x108f4, 0x108f5, 0x68617472},
+	{0x108fb, 0x108ff, 0x68617472},
+	{0x10900, 0x1091b, 0x70686e78},
+	{0x1091f, 0x1091f, 0x70686e78},
+	{0x10920, 0x10939, 0x6c796469},
+	{0x1093f, 0x1093f, 0x6c796469},
+	{0x10980, 0x1099f, 0x6d65726f},
+	{0x109a0, 0x109b7, 0x6d657263},
+	{0x109bc, 0x109cf, 0x6d657263},
+	{0x109d2, 0x109ff, 0x6d657263},
+	{0x10a00, 0x10a03, 0x6b686172},
+	{0x10a05, 0x10a06, 0x6b686172},
+	{0x10a0c, 0x10a13, 0x6b686172},
+	{0x10a15, 0x10a17, 0x6b686172},
+	{0x10a19, 0x10a35, 0x6b686172},
+	{0x10a38, 0x10a3a, 0x6b686172},
+	{0x10a3f, 0x10a48, 0x6b686172},
+	{0x10a50, 0x10a58, 0x6b686172},
+	{0x10a60, 0x10a7f, 0x73617262},
+	{0x10a80, 0x10a9f, 0x6e617262},
+	{0x10ac0, 0x10ae6, 0x6d616e69},
+	{0x10aeb, 0x10af6, 0x6d616e69},
+	{0x10b00, 0x10b35, 0x61767374},
+	{0x10b39, 0x10b3f, 0x61767374},
+	{0x10b40, 0x10b55, 0x70727469},
+	{0x10b58, 0x10b5f, 0x70727469},
+	{0x10b60, 0x10b72, 0x70686c69},
+	{0x10b78, 0x10b7f, 0x70686c69},
+	{0x10b80, 0x10b91, 0x70686c70},
+	{0x10b99, 0x10b9c, 0x70686c70},
+	{0x10ba9, 0x10baf, 0x70686c70},
+	{0x10c00, 0x10c48, 0x6f726b68},
+	{0x10c80, 0x10cb2, 0x68756e67},
+	{0x10cc0, 0x10cf2, 0x68756e67},
+	{0x10cfa, 0x10cff, 0x68756e67},
+	{0x10d00, 0x10d27, 0x726f6867},
+	{0x10d30, 0x10d39, 0x726f6867},
+	{0x10e60, 0x10e7e, 0x61726162},
+	{0x10e80, 0x10ea9, 0x79657a69},
+	{0x10eab, 0x10ead, 0x79657a69},
+	{0x10eb0, 0x10eb1, 0x79657a69},
+	{0x10efd, 0x10eff, 0x61726162},
+	{0x10f00, 0x10f27, 0x736f676f},
+	{0x10f30, 0x10f59, 0x736f6764},
+	{0x10f70, 0x10f89, 0x6f756772},
+	{0x10fb0, 0x10fcb, 0x63687273},
+	{0x10fe0, 0x10ff6, 0x656c796d},
+	{0x11000, 0x1104d, 0x62726168},
+	{0x11052, 0x11075, 0x62726168},
+	{0x1107f, 0x1107f, 0x62726168},
+	{0x11080, 0x110c2, 0x6b746869},
+	{0x110cd, 0x110cd, 0x6b746869},
+	{0x110d0, 0x110e8, 0x736f7261},
+	{0x110f0, 0x110f9, 0x736f7261},
+	{0x11100, 0x11134, 0x63616b6d},
+	{0x11136, 0x11147, 0x63616b6d},
+	{0x11150, 0x11176, 0x6d61686a},
+	{0x11180, 0x111df, 0x73687264},
+	{0x111e1, 0x111f4, 0x73696e68},
+	{0x11200, 0x11211, 0x6b686f6a},
+	{0x11213, 0x11241, 0x6b686f6a},
+	{0x11280, 0x11286, 0x6d756c74},
+	{0x11288, 0x11288, 0x6d756c74},
+	{0x1128a, 0x1128d, 0x6d756c74},
+	{0x1128f, 0x1129d, 0x6d756c74},
+	{0x1129f, 0x112a9, 0x6d756c74},
+	{0x112b0, 0x112ea, 0x73696e64},
+	{0x112f0, 0x112f9, 0x73696e64},
+	{0x11300, 0x11303, 0x6772616e},
+	{0x11305, 0x1130c, 0x6772616e},
+	{0x1130f, 0x11310, 0x6772616e},
+	{0x11313, 0x11328, 0x6772616e},
+	{0x1132a, 0x11330, 0x6772616e},
+	{0x11332, 0x11333, 0x6772616e},
+	{0x11335, 0x11339, 0x6772616e},
+	{0x1133b, 0x1133b, 0x7a696e68},
+	{0x1133c, 0x11344, 0x6772616e},
+	{0x11347, 0x11348, 0x6772616e},
+	{0x1134b, 0x1134d, 0x6772616e},
+	{0x11350, 0x11350, 0x6772616e},
+	{0x11357, 0x11357, 0x6772616e},
+	{0x1135d, 0x11363, 0x6772616e},
+	{0x11366, 0x1136c, 0x6772616e},
+	{0x11370, 0x11374, 0x6772616e},
+	{0x11400, 0x1145b, 0x6e657761},
+	{0x1145d, 0x11461, 0x6e657761},
+	{0x11480, 0x114c7, 0x74697268},
+	{0x114d0, 0x114d9, 0x74697268},
+	{0x11580, 0x115b5, 0x73696464},
+	{0x115b8, 0x115dd, 0x73696464},
+	{0x11600, 0x11644, 0x6d6f6469},
+	{0x11650, 0x11659, 0x6d6f6469},
+	{0x11660, 0x1166c, 0x6d6f6e67},
+	{0x11680, 0x116b9, 0x74616b72},
+	{0x116c0, 0x116c9, 0x74616b72},
+	{0x11700, 0x1171a, 0x61686f6d},
+	{0x1171d, 0x1172b, 0x61686f6d},
+	{0x11730, 0x11746, 0x61686f6d},
+	{0x11800, 0x1183b, 0x646f6772},
+	{0x118a0, 0x118f2, 0x77617261},
+	{0x118ff, 0x118ff, 0x77617261},
+	{0x11900, 0x11906, 0x6469616b},
+	{0x11909, 0x11909, 0x6469616b},
+	{0x1190c, 0x11913, 0x6469616b},
+	{0x11915, 0x11916, 0x6469616b},
+	{0x11918, 0x11935, 0x6469616b},
+	{0x11937, 0x11938, 0x6469616b},
+	{0x1193b, 0x11946, 0x6469616b},
+	{0x11950, 0x11959, 0x6469616b},
+	{0x119a0, 0x119a7, 0x6e616e64},
+	{0x119aa, 0x119d7, 0x6e616e64},
+	{0x119da, 0x119e4, 0x6e616e64},
+	{0x11a00, 0x11a47, 0x7a616e62},
+	{0x11a50, 0x11aa2, 0x736f796f},
+	{0x11ab0, 0x11abf, 0x63616e73},
+	{0x11ac0, 0x11af8, 0x70617563},
+	{0x11b00, 0x11b09, 0x64657661},
+	{0x11c00, 0x11c08, 0x62686b73},
+	{0x11c0a, 0x11c36, 0x62686b73},
+	{0x11c38, 0x11c45, 0x62686b73},
+	{0x11c50, 0x11c6c, 0x62686b73},
+	{0x11c70, 0x11c8f, 0x6d617263},
+	{0x11c92, 0x11ca7, 0x6d617263},
+	{0x11ca9, 0x11cb6, 0x6d617263},
+	{0x11d00, 0x11d06, 0x676f6e6d},
+	{0x11d08, 0x11d09, 0x676f6e6d},
+	{0x11d0b, 0x11d36, 0x676f6e6d},
+	{0x11d3a, 0x11d3a, 0x676f6e6d},
+	{0x11d3c, 0x11d3d, 0x676f6e6d},
+	{0x11d3f, 0x11d47, 0x676f6e6d},
+	{0x11d50, 0x11d59, 0x676f6e6d},
+	{0x11d60, 0x11d65, 0x676f6e67},
+	{0x11d67, 0x11d68, 0x676f6e67},
+	{0x11d6a, 0x11d8e, 0x676f6e67},
+	{0x11d90, 0x11d91, 0x676f6e67},
+	{0x11d93, 0x11d98, 0x676f6e67},
+	{0x11da0, 0x11da9, 0x676f6e67},
+	{0x11ee0, 0x11ef8, 0x6d616b61},
+	{0x11f00, 0x11f10, 0x6b617769},
+	{0x11f12, 0x11f3a, 0x6b617769},
+	{0x11f3e, 0x11f59, 0x6b617769},
+	{0x11fb0, 0x11fb0, 0x6c697375},
+	{0x11fc0, 0x11ff1, 0x74616d6c},
+	{0x11fff, 0x11fff, 0x74616d6c},
+	{0x12000, 0x12399, 0x78737578},
+	{0x12400, 0x1246e, 0x78737578},
+	{0x12470, 0x12474, 0x78737578},
+	{0x12480, 0x12543, 0x78737578},
+	{0x12f90, 0x12ff2, 0x63706d6e},
+	{0x13000, 0x13455, 0x65677970},
+	{0x14400, 0x14646, 0x686c7577},
+	{0x16800, 0x16a38, 0x62616d75},
+	{0x16a40, 0x16a5e, 0x6d726f6f},
+	{0x16a60, 0x16a69, 0x6d726f6f},
+	{0x16a6e, 0x16a6f, 0x6d726f6f},
+	{0x16a70, 0x16abe, 0x746e7361},
+	{0x16ac0, 0x16ac9, 0x746e7361},
+	{0x16ad0, 0x16aed, 0x62617373},
+	{0x16af0, 0x16af5, 0x62617373},
+	{0x16b00, 0x16b45, 0x686d6e67},
+	{0x16b50, 0x16b59, 0x686d6e67},
+	{0x16b5b, 0x16b61, 0x686d6e67},
+	{0x16b63, 0x16b77, 0x686d6e67},
+	{0x16b7d, 0x16b8f, 0x686d6e67},
+	{0x16e40, 0x16e9a, 0x6d656466},
+	{0x16f00, 0x16f4a, 0x706c7264},
+	{0x16f4f, 0x16f87, 0x706c7264},
+	{0x16f8f, 0x16f9f, 0x706c7264},
+	{0x16fe0, 0x16fe0, 0x74616e67},
+	{0x16fe1, 0x16fe1, 0x6e736875},
+	{0x16fe2, 0x16fe3, 0x68616e69},
+	{0x16fe4, 0x16fe4, 0x6b697473},
+	{0x16ff0, 0x16ff1, 0x68616e69},
+	{0x17000, 0x187f7, 0x74616e67},
+	{0x18800, 0x18aff, 0x74616e67},
+	{0x18b00, 0x18cd5, 0x6b697473},
+	{0x18d00, 0x18d08, 0x74616e67},
+	{0x1aff0, 0x1aff3, 0x6b616e61},
+	{0x1aff5, 0x1affb, 0x6b616e61},
+	{0x1affd, 0x1affe, 0x6b616e61},
+	{0x1b000, 0x1b000, 0x6b616e61},
+	{0x1b001, 0x1b11f, 0x68697261},
+	{0x1b120, 0x1b122, 0x6b616e61},
+	{0x1b132, 0x1b132, 0x68697261},
+	{0x1b150, 0x1b152, 0x68697261},
+	{0x1b155, 0x1b155, 0x6b616e61},
+	{0x1b164, 0x1b167, 0x6b616e61},
+	{0x1b170, 0x1b2fb, 0x6e736875},
+	{0x1bc00, 0x1bc6a, 0x6475706c},
+	{0x1bc70, 0x1bc7c, 0x6475706c},
+	{0x1bc80, 0x1bc88, 0x6475706c},
+	{0x1bc90, 0x1bc99, 0x6475706c},
+	{0x1bc9c, 0x1bc9f, 0x6475706c},
+	{0x1bca0, 0x1bca3, 0x7a797979},
+	{0x1cf00, 0x1cf2d, 0x7a696e68},
+	{0x1cf30, 0x1cf46, 0x7a696e68},
+	{0x1cf50, 0x1cfc3, 0x7a797979},
+	{0x1d000, 0x1d0f5, 0x7a797979},
+	{0x1d100, 0x1d126, 0x7a797979},
+	{0x1d129, 0x1d166, 0x7a797979},
+	{0x1d167, 0x1d169, 0x7a696e68},
+	{0x1d16a, 0x1d17a, 0x7a797979},
+	{0x1d17b, 0x1d182, 0x7a696e68},
+	{0x1d183, 0x1d184, 0x7a797979},
+	{0x1d185, 0x1d18b, 0x7a696e68},
+	{0x1d18c, 0x1d1a9, 0x7a797979},
+	{0x1d1aa, 0x1d1ad, 0x7a696e68},
+	{0x1d1ae, 0x1d1ea, 0x7a797979},
+	{0x1d200, 0x1d245, 0x6772656b},
+	{0x1d2c0, 0x1d2d3, 0x7a797979},
+	{0x1d2e0, 0x1d2f3, 0x7a797979},
+	{0x1d300, 0x1d356, 0x7a797979},
+	{0x1d360, 0x1d378, 0x7a797979},
+	{0x1d400, 0x1d454, 0x7a797979},
+	{0x1d456, 0x1d49c, 0x7a797979},
+	{0x1d49e, 0x1d49f, 0x7a797979},
+	{0x1d4a2, 0x1d4a2, 0x7a797979},
+	{0x1d4a5, 0x1d4a6, 0x7a797979},
+	{0x1d4a9, 0x1d4ac, 0x7a797979},
+	{0x1d4ae, 0x1d4b9, 0x7a797979},
+	{0x1d4bb, 0x1d4bb, 0x7a797979},
+	{0x1d4bd, 0x1d4c3, 0x7a797979},
+	{0x1d4c5, 0x1d505, 0x7a797979},
+	{0x1d507, 0x1d50a, 0x7a797979},
+	{0x1d50d, 0x1d514, 0x7a797979},
+	{0x1d516, 0x1d51c, 0x7a797979},
+	{0x1d51e, 0x1d539, 0x7a797979},
+	{0x1d53b, 0x1d53e, 0x7a797979},
+	{0x1d540, 0x1d544, 0x7a797979},
+	{0x1d546, 0x1d546, 0x7a797979},
+	{0x1d54a, 0x1d550, 0x7a797979},
+	{0x1d552, 0x1d6a5, 0x7a797979},
+	{0x1d6a8, 0x1d7cb, 0x7a797979},
+	{0x1d7ce, 0x1d7ff, 0x7a797979},
+	{0x1d800, 0x1da8b, 0x73676e77},
+	{0x1da9b, 0x1da9f, 0x73676e77},
+	{0x1daa1, 0x1daaf, 0x73676e77},
+	{0x1df00, 0x1df1e, 0x6c61746e},
+	{0x1df25, 0x1df2a, 0x6c61746e},
+	{0x1e000, 0x1e006, 0x676c6167},
+	{0x1e008, 0x1e018, 0x676c6167},
+	{0x1e01b, 0x1e021, 0x676c6167},
+	{0x1e023, 0x1e024, 0x676c6167},
+	{0x1e026, 0x1e02a, 0x676c6167},
+	{0x1e030, 0x1e06d, 0x6379726c},
+	{0x1e08f, 0x1e08f, 0x6379726c},
+	{0x1e100, 0x1e12c, 0x686d6e70},
+	{0x1e130, 0x1e13d, 0x686d6e70},
+	{0x1e140, 0x1e149, 0x686d6e70},
+	{0x1e14e, 0x1e14f, 0x686d6e70},
+	{0x1e290, 0x1e2ae, 0x746f746f},
+	{0x1e2c0, 0x1e2f9, 0x7763686f},
+	{0x1e2ff, 0x1e2ff, 0x7763686f},
+	{0x1e4d0, 0x1e4f9, 0x6e61676d},
+	{0x1e7e0, 0x1e7e6, 0x65746869},
+	{0x1e7e8, 0x1e7eb, 0x65746869},
+	{0x1e7ed, 0x1e7ee, 0x65746869},
+	{0x1e7f0, 0x1e7fe, 0x65746869},
+	{0x1e800, 0x1e8c4, 0x6d656e64},
+	{0x1e8c7, 0x1e8d6, 0x6d656e64},
+	{0x1e900, 0x1e94b, 0x61646c6d},
+	{0x1e950, 0x1e959, 0x61646c6d},
+	{0x1e95e, 0x1e95f, 0x61646c6d},
+	{0x1ec71, 0x1ecb4, 0x7a797979},
+	{0x1ed01, 0x1ed3d, 0x7a797979},
+	{0x1ee00, 0x1ee03, 0x61726162},
+	{0x1ee05, 0x1ee1f, 0x61726162},
+	{0x1ee21, 0x1ee22, 0x61726162},
+	{0x1ee24, 0x1ee24, 0x61726162},
+	{0x1ee27, 0x1ee27, 0x61726162},
+	{0x1ee29, 0x1ee32, 0x61726162},
+	{0x1ee34, 0x1ee37, 0x61726162},
+	{0x1ee39, 0x1ee39, 0x61726162},
+	{0x1ee3b, 0x1ee3b, 0x61726162},
+	{0x1ee42, 0x1ee42, 0x61726162},
+	{0x1ee47, 0x1ee47, 0x61726162},
+	{0x1ee49, 0x1ee49, 0x61726162},
+	{0x1ee4b, 0x1ee4b, 0x61726162},
+	{0x1ee4d, 0x1ee4f, 0x61726162},
+	{0x1ee51, 0x1ee52, 0x61726162},
+	{0x1ee54, 0x1ee54, 0x61726162},
+	{0x1ee57, 0x1ee57, 0x61726162},
+	{0x1ee59, 0x1ee59, 0x61726162},
+	{0x1ee5b, 0x1ee5b, 0x61726162},
+	{0x1ee5d, 0x1ee5d, 0x61726162},
+	{0x1ee5f, 0x1ee5f, 0x61726162},
+	{0x1ee61, 0x1ee62, 0x61726162},
+	{0x1ee64, 0x1ee64, 0x61726162},
+	{0x1ee67, 0x1ee6a, 0x61726162},
+	{0x1ee6c, 0x1ee72, 0x61726162},
+	{0x1ee74, 0x1ee77, 0x61726162},
+	{0x1ee79, 0x1ee7c, 0x61726162},
+	{0x1ee7e, 0x1ee7e, 0x61726162},
+	{0x1ee80, 0x1ee89, 0x61726162},
+	{0x1ee8b, 0x1ee9b, 0x61726162},
+	{0x1eea1, 0x1eea3, 0x61726162},
+	{0x1eea5, 0x1eea9, 0x61726162},
+	{0x1eeab, 0x1eebb, 0x61726162},
+	{0x1eef0, 0x1eef1, 0x61726162},
+	{0x1f000, 0x1f02b, 0x7a797979},
+	{0x1f030, 0x1f093, 0x7a797979},
+	{0x1f0a0, 0x1f0ae, 0x7a797979},
+	{0x1f0b1, 0x1f0bf, 0x7a797979},
+	{0x1f0c1, 0x1f0cf, 0x7a797979},
+	{0x1f0d1, 0x1f0f5, 0x7a797979},
+	{0x1f100, 0x1f1ad, 0x7a797979},
+	{0x1f1e6, 0x1f1ff, 0x7a797979},
+	{0x1f200, 0x1f200, 0x68697261},
+	{0x1f201, 0x1f202, 0x7a797979},
+	{0x1f210, 0x1f23b, 0x7a797979},
+	{0x1f240, 0x1f248, 0x7a797979},
+	{0x1f250, 0x1f251, 0x7a797979},
+	{0x1f260, 0x1f265, 0x7a797979},
+	{0x1f300, 0x1f6d7, 0x7a797979},
+	{0x1f6dc, 0x1f6ec, 0x7a797979},
+	{0x1f6f0, 0x1f6fc, 0x7a797979},
+	{0x1f700, 0x1f776, 0x7a797979},
+	{0x1f77b, 0x1f7d9, 0x7a797979},
+	{0x1f7e0, 0x1f7eb, 0x7a797979},
+	{0x1f7f0, 0x1f7f0, 0x7a797979},
+	{0x1f800, 0x1f80b, 0x7a797979},
+	{0x1f810, 0x1f847, 0x7a797979},
+	{0x1f850, 0x1f859, 0x7a797979},
+	{0x1f860, 0x1f887, 0x7a797979},
+	{0x1f890, 0x1f8ad, 0x7a797979},
+	{0x1f8b0, 0x1f8b1, 0x7a797979},
+	{0x1f900, 0x1fa53, 0x7a797979},
+	{0x1fa60, 0x1fa6d, 0x7a797979},
+	{0x1fa70, 0x1fa7c, 0x7a797979},
+	{0x1fa80, 0x1fa88, 0x7a797979},
+	{0x1fa90, 0x1fabd, 0x7a797979},
+	{0x1fabf, 0x1fac5, 0x7a797979},
+	{0x1face, 0x1fadb, 0x7a797979},
+	{0x1fae0, 0x1fae8, 0x7a797979},
+	{0x1faf0, 0x1faf8, 0x7a797979},
+	{0x1fb00, 0x1fb92, 0x7a797979},
+	{0x1fb94, 0x1fbca, 0x7a797979},
+	{0x1fbf0, 0x1fbf9, 0x7a797979},
+	{0x20000, 0x2a6df, 0x68616e69},
+	{0x2a700, 0x2b739, 0x68616e69},
+	{0x2b740, 0x2b81d, 0x68616e69},
+	{0x2b820, 0x2cea1, 0x68616e69},
+	{0x2ceb0, 0x2ebe0, 0x68616e69},
+	{0x2f800, 0x2fa1d, 0x68616e69},
+	{0x30000, 0x3134a, 0x68616e69},
+	{0x31350, 0x323af, 0x68616e69},
+	{0xe0001, 0xe0001, 0x7a797979},
+	{0xe0020, 0xe007f, 0x7a797979},
+	{0xe0100, 0xe01ef, 0x7a696e68},
 }
 }

+ 137 - 2
vendor/github.com/go-text/typesetting/opentype/api/cmap.go

@@ -36,7 +36,11 @@ func (c cmapID) key() uint32 { return uint32(c.platform)<<16 | uint32(c.encoding
 // ProcessCmap sanitize the given 'cmap' subtable, and select the best encoding
 // ProcessCmap sanitize the given 'cmap' subtable, and select the best encoding
 // when several subtables are given.
 // when several subtables are given.
 // When present, the variation selectors are returned.
 // When present, the variation selectors are returned.
-func ProcessCmap(cmap tables.Cmap) (Cmap, UnicodeVariations, error) {
+// [os2FontPage] is used for legacy arabic fonts.
+//
+// The returned values are copied from the input 'cmap', meaning they do not
+// retain any reference on the input storage.
+func ProcessCmap(cmap tables.Cmap, os2FontPage tables.FontPage) (Cmap, UnicodeVariations, error) {
 	var (
 	var (
 		candidateIds []cmapID
 		candidateIds []cmapID
 		candidates   []Cmap
 		candidates   []Cmap
@@ -84,7 +88,16 @@ func ProcessCmap(cmap tables.Cmap) (Cmap, UnicodeVariations, error) {
 
 
 	// Prefer symbol if available.
 	// Prefer symbol if available.
 	if index := findSubtable(cmapID{tables.PlatformMicrosoft, tables.PEMicrosoftSymbolCs}, candidateIds); index != -1 {
 	if index := findSubtable(cmapID{tables.PlatformMicrosoft, tables.PEMicrosoftSymbolCs}, candidateIds); index != -1 {
-		return candidates[index], uv, nil
+		cm := candidates[index]
+		switch os2FontPage {
+		case tables.FPNone:
+			cm = remaperSymbol{cm}
+		case tables.FPSimpArabic:
+			cm = remaperPUASimp{cm}
+		case tables.FPTradArabic:
+			cm = remaperPUATrad{cm}
+		}
+		return cm, uv, nil
 	}
 	}
 
 
 	/* 32-bit subtables. */
 	/* 32-bit subtables. */
@@ -540,3 +553,125 @@ func (t UnicodeVariations) GetGlyphVariant(r, selector rune) (GID, uint8) {
 	}
 	}
 	return 0, VariantNotFound
 	return 0, VariantNotFound
 }
 }
+
+// Handle legacy font with remap
+// TODO: the Iter() and RuneRanges() method does not include the additional mapping
+
+type remaperSymbol struct {
+	Cmap
+}
+
+func (rs remaperSymbol) Lookup(r rune) (GID, bool) {
+	// try without map first
+	if g, ok := rs.Cmap.Lookup(r); ok {
+		return g, true
+	}
+
+	if r <= 0x00FF {
+		/* For symbol-encoded OpenType fonts, we duplicate the
+		 * U+F000..F0FF range at U+0000..U+00FF.  That's what
+		 * Windows seems to do, and that's hinted about at:
+		 * https://docs.microsoft.com/en-us/typography/opentype/spec/recom
+		 * under "Non-Standard (Symbol) Fonts". */
+		mapped := 0xF000 + r
+		return rs.Lookup(mapped)
+	}
+
+	return 0, false
+}
+
+type remaperPUASimp struct {
+	Cmap
+}
+
+func (rs remaperPUASimp) Lookup(r rune) (GID, bool) {
+	// try without map first
+	if g, ok := rs.Cmap.Lookup(r); ok {
+		return g, true
+	}
+
+	if mapped := arabicPUASimpMap(r); mapped != 0 {
+		return rs.Lookup(mapped)
+	}
+
+	return 0, false
+}
+
+type remaperPUATrad struct {
+	Cmap
+}
+
+func (rs remaperPUATrad) Lookup(r rune) (GID, bool) {
+	// try without map first
+	if g, ok := rs.Cmap.Lookup(r); ok {
+		return g, true
+	}
+
+	if mapped := arabicPUATradMap(r); mapped != 0 {
+		return rs.Lookup(mapped)
+	}
+
+	return 0, false
+}
+
+// ---------------------------- efficent rune set support -----------------------------------------
+
+// CmapRuneRanger is implemented by cmaps whose coverage is defined in terms
+// of rune ranges
+type CmapRuneRanger interface {
+	// RuneRanges returns a list of (start, end) rune pairs, both included.
+	// `dst` is an optional buffer used to reduce allocations
+	RuneRanges(dst [][2]rune) [][2]rune
+}
+
+var (
+	_ CmapRuneRanger = cmap4(nil)
+	_ CmapRuneRanger = (*cmap6or10)(nil)
+	_ CmapRuneRanger = cmap12(nil)
+	_ CmapRuneRanger = cmap13(nil)
+)
+
+func (cm cmap4) RuneRanges(dst [][2]rune) [][2]rune {
+	if cap(dst) < len(cm) {
+		dst = make([][2]rune, 0, len(cm))
+	}
+	dst = dst[:0]
+	for _, e := range cm {
+		start, end := rune(e.start), rune(e.end)
+		if L := len(dst); L != 0 && dst[L-1][1] == start {
+			// grow the previous range
+			dst[L-1][1] = end
+		} else {
+			dst = append(dst, [2]rune{start, end})
+		}
+	}
+	return dst
+}
+
+func (cm *cmap6or10) RuneRanges(dst [][2]rune) [][2]rune {
+	if cap(dst) < 1 {
+		dst = [][2]rune{{}}
+	}
+	dst = dst[:1]
+	dst[0] = [2]rune{cm.firstCode, cm.firstCode + rune(len(cm.entries)) - 1}
+	return dst
+}
+
+func (cm cmap12) RuneRanges(dst [][2]rune) [][2]rune {
+	if cap(dst) < len(cm) {
+		dst = make([][2]rune, 0, len(cm))
+	}
+	dst = dst[:0]
+	for _, e := range cm {
+		start, end := rune(e.StartCharCode), rune(e.EndCharCode)
+		if L := len(dst); L != 0 && dst[L-1][1] == start {
+			// grow the previous range
+			dst[L-1][1] = end
+		} else {
+			dst = append(dst, [2]rune{start, end})
+		}
+	}
+	return dst
+}
+
+func (cm cmap13) RuneRanges(dst [][2]rune) [][2]rune { return cmap12(cm).RuneRanges(dst) }

+ 161 - 0
vendor/github.com/go-text/typesetting/opentype/api/cmap_arabic_pua_table.go

@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: Unlicense OR BSD-3-Clause
+
+package api
+
+// Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
+
+// Legacy Simplified Arabic encoding. Returns 0 if not found.
+func arabicPUASimpMap(r rune) rune {
+	switch {
+	case 0x20 <= r && r <= 0x22:
+		return [...]rune{0xf120, 0xf121, 0xf122}[r-0x20]
+	case 0x25 == r:
+		return 0xf125
+	case 0x28 <= r && r <= 0x3b:
+		return [...]rune{0xf128, 0xf129, 0xf12a, 0xf12b, 0xf15e, 0xf12d, 0xf12e, 0xf12f, 0xf1b0, 0xf1b1, 0xf1b2, 0xf1b3, 0xf1b4, 0xf1b5, 0xf1b6, 0xf1b7, 0xf1b8, 0xf1b9, 0xf13a, 0xf13b}[r-0x28]
+	case 0x3d == r:
+		return 0xf13d
+	case 0x3f == r:
+		return 0xf13f
+	case 0x5b <= r && r <= 0x5d:
+		return [...]rune{0xf15b, 0xf15c, 0xf15d}[r-0x5b]
+	case 0xab == r:
+		return 0xf123
+	case 0xbb == r:
+		return 0xf124
+	case 0xd7 == r:
+		return 0xf126
+	case 0xf7 == r:
+		return 0xf127
+	case 0x60c == r:
+		return 0xf12c
+	case 0x61b == r:
+		return 0xf13b
+	case 0x61f == r:
+		return 0xf13f
+	case 0x621 <= r && r <= 0x65e:
+		return [...]rune{0xf1ad, 0xf145, 0xf143, 0xf1bb, 0xf147, 0xf1ba, 0xf141, 0xf14a, 0xf1a9, 0xf14c, 0xf14e, 0xf151, 0xf154, 0xf157, 0xf158, 0xf159, 0xf15a, 0xf160, 0xf162, 0xf164, 0xf166, 0xf168, 0xf169, 0xf16a, 0xf16e, 0xf172, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf15f, 0xf175, 0xf178, 0xf17a, 0xf17c, 0xf17e, 0xf1e1, 0xf1a4, 0xf1a5, 0xf1ac, 0xf1a8, 0xf1c7, 0xf1c8, 0xf1cb, 0xf1c4, 0xf1c5, 0xf1ca, 0xf1c9, 0xf1c6, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100, 0xf100}[r-0x621]
+	case 0x660 <= r && r <= 0x669:
+		return [...]rune{0xf130, 0xf131, 0xf132, 0xf133, 0xf134, 0xf135, 0xf136, 0xf137, 0xf138, 0xf139}[r-0x660]
+	case 0x66b <= r && r <= 0x66c:
+		return [...]rune{0xf15e, 0xf15e}[r-0x66b]
+	case 0x200c <= r && r <= 0x200f:
+		return [...]rune{0xf10c, 0xf10d, 0xf10e, 0xf10f}[r-0x200c]
+	case 0x2018 <= r && r <= 0x2019:
+		return [...]rune{0xf13c, 0xf13e}[r-0x2018]
+	case 0xfe81 <= r && r <= 0xfefc:
+		return [...]rune{0xf145, 0xf146, 0xf143, 0xf144, 0xf1bb, 0xf1bb, 0xf147, 0xf148, 0xf1ba, 0xf1af, 0xf1ae, 0xf1ae, 0xf141, 0xf142, 0xf14a, 0xf14a, 0xf149, 0xf149, 0xf1a9, 0xf1aa, 0xf14c, 0xf14c, 0xf14b, 0xf14b, 0xf14e, 0xf14e, 0xf14d, 0xf14d, 0xf151, 0xf150, 0xf14f, 0xf14f, 0xf154, 0xf153, 0xf152, 0xf152, 0xf157, 0xf156, 0xf155, 0xf155, 0xf158, 0xf158, 0xf159, 0xf159, 0xf15a, 0xf15a, 0xf160, 0xf160, 0xf162, 0xf162, 0xf161, 0xf161, 0xf164, 0xf164, 0xf163, 0xf163, 0xf166, 0xf166, 0xf165, 0xf165, 0xf168, 0xf168, 0xf167, 0xf167, 0xf169, 0xf169, 0xf169, 0xf169, 0xf16a, 0xf16a, 0xf16a, 0xf16a, 0xf16e, 0xf16d, 0xf16b, 0xf16c, 0xf172, 0xf171, 0xf16f, 0xf170, 0xf175, 0xf175, 0xf173, 0xf174, 0xf178, 0xf178, 0xf176, 0xf177, 0xf17a, 0xf17a, 0xf179, 0xf179, 0xf17c, 0xf17c, 0xf17b, 0xf17b, 0xf17e, 0xf17e, 0xf17d, 0xf17d, 0xf1e1, 0xf1e1, 0xf17f, 0xf17f, 0xf1a4, 0xf1a3, 0xf1a1, 0xf1a2, 0xf1a5, 0xf1a5, 0xf1ac, 0xf1ab, 0xf1a8, 0xf1a7, 0xf1a6, 0xf1a6, 0xf1c0, 0xf1c1, 0xf1be, 0xf1bf, 0xf1c2, 0xf1c3, 0xf1bd, 0xf1bc}[r-0xfe81]
+	}
+	return 0
+}
+
+// Legacy Traditional Arabic encoding. Returns 0 if not found.
+func arabicPUATradMap(r rune) rune {
+	switch {
+	case 0x20 <= r && r <= 0x22:
+		return [...]rune{0xf220, 0xf221, 0xf222}[r-0x20]
+	case 0x25 == r:
+		return 0xf225
+	case 0x28 <= r && r <= 0x2f:
+		return [...]rune{0xf228, 0xf229, 0xf22a, 0xf22b, 0xf25e, 0xf22d, 0xf22e, 0xf22f}[r-0x28]
+	case 0x3a <= r && r <= 0x3b:
+		return [...]rune{0xf23a, 0xf23b}[r-0x3a]
+	case 0x3d == r:
+		return 0xf23d
+	case 0x3f == r:
+		return 0xf23f
+	case 0x5b == r:
+		return 0xf25b
+	case 0x5d == r:
+		return 0xf25d
+	case 0xab == r:
+		return 0xf223
+	case 0xbb == r:
+		return 0xf224
+	case 0xd7 == r:
+		return 0xf226
+	case 0xf7 == r:
+		return 0xf227
+	case 0x60c == r:
+		return 0xf22c
+	case 0x61b == r:
+		return 0xf23b
+	case 0x61f == r:
+		return 0xf23f
+	case 0x621 <= r && r <= 0x65e:
+		return [...]rune{0xf2d5, 0xf245, 0xf243, 0xf2da, 0xf247, 0xf2d9, 0xf241, 0xf24c, 0xf2d1, 0xf250, 0xf254, 0xf258, 0xf260, 0xf264, 0xf265, 0xf267, 0xf269, 0xf26b, 0xf270, 0xf274, 0xf278, 0xf27e, 0xf2a2, 0xf2a3, 0xf2aa, 0xf2ae, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf25f, 0xf2b2, 0xf2b6, 0xf2ba, 0xf2be, 0xf2c2, 0xf2c6, 0xf2ca, 0xf2cb, 0xf2d4, 0xf2d0, 0xf2e7, 0xf2e8, 0xf2eb, 0xf2e4, 0xf2e5, 0xf2ea, 0xf2e9, 0xf2e6, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200}[r-0x621]
+	case 0x660 <= r && r <= 0x669:
+		return [...]rune{0xf230, 0xf231, 0xf232, 0xf233, 0xf234, 0xf235, 0xf236, 0xf237, 0xf238, 0xf239}[r-0x660]
+	case 0x66b <= r && r <= 0x66c:
+		return [...]rune{0xf25e, 0xf25e}[r-0x66b]
+	case 0x200c <= r && r <= 0x200f:
+		return [...]rune{0xf20c, 0xf20d, 0xf20e, 0xf20f}[r-0x200c]
+	case 0x201c <= r && r <= 0x201d:
+		return [...]rune{0xf23c, 0xf23e}[r-0x201c]
+	case 0xfc08 == r:
+		return 0xf202
+	case 0xfc0a == r:
+		return 0xf21d
+	case 0xfc0e == r:
+		return 0xf203
+	case 0xfc10 == r:
+		return 0xf21e
+	case 0xfc12 == r:
+		return 0xf204
+	case 0xfc32 == r:
+		return 0xf29f
+	case 0xfc3f <= r && r <= 0xfc42:
+		return [...]rune{0xf212, 0xf213, 0xf214, 0xf205}[r-0xfc3f]
+	case 0xfc44 == r:
+		return 0xf21c
+	case 0xfc4e == r:
+		return 0xf206
+	case 0xfc50 == r:
+		return 0xf21f
+	case 0xfc5e == r:
+		return 0xf2ef
+	case 0xfc60 <= r && r <= 0xfc62:
+		return [...]rune{0xf2ec, 0xf2ed, 0xf2f0}[r-0xfc60]
+	case 0xfc6a == r:
+		return 0xf215
+	case 0xfc6d == r:
+		return 0xf292
+	case 0xfc70 == r:
+		return 0xf216
+	case 0xfc73 == r:
+		return 0xf293
+	case 0xfc86 == r:
+		return 0xf295
+	case 0xfc91 == r:
+		return 0xf217
+	case 0xfc94 == r:
+		return 0xf294
+	case 0xfc9c <= r && r <= 0xfc9f:
+		return [...]rune{0xf280, 0xf281, 0xf282, 0xf296}[r-0xfc9c]
+	case 0xfca1 <= r && r <= 0xfca4:
+		return [...]rune{0xf283, 0xf284, 0xf285, 0xf297}[r-0xfca1]
+	case 0xfca8 == r:
+		return 0xf29a
+	case 0xfcaa == r:
+		return 0xf29b
+	case 0xfcac == r:
+		return 0xf29c
+	case 0xfcb0 == r:
+		return 0xf218
+	case 0xfcc9 <= r && r <= 0xfcd3:
+		return [...]rune{0xf286, 0xf287, 0xf288, 0xf29d, 0xf21a, 0xf289, 0xf28a, 0xf28b, 0xf29e, 0xf28d, 0xf28e}[r-0xfcc9]
+	case 0xfcd5 == r:
+		return 0xf298
+	case 0xfcda <= r && r <= 0xfcdd:
+		return [...]rune{0xf28f, 0xf290, 0xf291, 0xf299}[r-0xfcda]
+	case 0xfd30 == r:
+		return 0xf219
+	case 0xfd3e <= r && r <= 0xfd3f:
+		return [...]rune{0xf27b, 0xf27d}[r-0xfd3e]
+	case 0xfd88 == r:
+		return 0xf210
+	case 0xfe81 <= r && r <= 0xfefc:
+		return [...]rune{0xf245, 0xf246, 0xf243, 0xf244, 0xf2da, 0xf2db, 0xf247, 0xf248, 0xf2d9, 0xf2d8, 0xf2d6, 0xf2d7, 0xf241, 0xf242, 0xf24c, 0xf24b, 0xf249, 0xf24a, 0xf2d1, 0xf2d2, 0xf250, 0xf24f, 0xf24d, 0xf24e, 0xf254, 0xf253, 0xf251, 0xf252, 0xf258, 0xf257, 0xf255, 0xf256, 0xf260, 0xf25c, 0xf259, 0xf25a, 0xf264, 0xf263, 0xf261, 0xf262, 0xf265, 0xf266, 0xf267, 0xf268, 0xf269, 0xf26a, 0xf26b, 0xf26c, 0xf270, 0xf26f, 0xf26d, 0xf26e, 0xf274, 0xf273, 0xf271, 0xf272, 0xf278, 0xf277, 0xf275, 0xf276, 0xf27e, 0xf27c, 0xf279, 0xf27a, 0xf2a2, 0xf2a1, 0xf27f, 0xf2f1, 0xf2a6, 0xf2a5, 0xf2a3, 0xf2a4, 0xf2aa, 0xf2a9, 0xf2a7, 0xf2a8, 0xf2ae, 0xf2ad, 0xf2ab, 0xf2ac, 0xf2b2, 0xf2b1, 0xf2af, 0xf2b0, 0xf2b6, 0xf2b5, 0xf2b3, 0xf2b4, 0xf2ba, 0xf2b9, 0xf2b7, 0xf2b8, 0xf2be, 0xf2bd, 0xf2bb, 0xf2bc, 0xf2c2, 0xf2c1, 0xf2bf, 0xf2c0, 0xf2c6, 0xf2c5, 0xf2c3, 0xf2c4, 0xf2ca, 0xf2c9, 0xf2c7, 0xf2c8, 0xf2cb, 0xf2cc, 0xf2d4, 0xf2d3, 0xf2d0, 0xf2cf, 0xf2cd, 0xf2ce, 0xf2e0, 0xf2e1, 0xf2de, 0xf2df, 0xf2e2, 0xf2e3, 0xf2dc, 0xf2dd}[r-0xfe81]
+	}
+	return 0
+}

+ 7 - 1
vendor/github.com/go-text/typesetting/opentype/api/font.go

@@ -181,9 +181,15 @@ type BitmapFormat uint8
 
 
 const (
 const (
 	_ BitmapFormat = iota
 	_ BitmapFormat = iota
+	// The [GlyphBitmap.Data] slice stores a black or white (0/1)
+	// bit image, whose length L satisfies
+	// L * 8 >= [GlyphBitmap.Width] * [GlyphBitmap.Height]
 	BlackAndWhite
 	BlackAndWhite
+	// The [GlyphBitmap.Data] slice stores a PNG encoded image
 	PNG
 	PNG
+	// The [GlyphBitmap.Data] slice stores a JPG encoded image
 	JPG
 	JPG
+	// The [GlyphBitmap.Data] slice stores a TIFF encoded image
 	TIFF
 	TIFF
 )
 )
 
 
@@ -204,6 +210,6 @@ type FontID struct {
 	Index uint16
 	Index uint16
 
 
 	// For variable fonts, stores 1 + the instance index.
 	// For variable fonts, stores 1 + the instance index.
-	// (0 to ignore variations).
+	// It is set to 0 to ignore variations, or for non variable fonts.
 	Instance uint16
 	Instance uint16
 }
 }

+ 15 - 1
vendor/github.com/go-text/typesetting/opentype/api/font/cff/interpreter/interpreter.go

@@ -7,6 +7,8 @@
 // which implement `PsOperatorHandler`.
 // which implement `PsOperatorHandler`.
 // It also provides helpers to interpret glyph outline descriptions,
 // It also provides helpers to interpret glyph outline descriptions,
 // shared between Type1 and CFF font formats.
 // shared between Type1 and CFF font formats.
+//
+// See https://adobe-type-tools.github.io/font-tech-notes/pdfs/5177.Type2.pdf
 package psinterpreter
 package psinterpreter
 
 
 import (
 import (
@@ -249,7 +251,19 @@ func (p *Machine) parseNumber() (hasResult bool, err error) {
 		if len(p.instructions) < 5 {
 		if len(p.instructions) < 5 {
 			return true, errInvalidCFFTable
 			return true, errInvalidCFFTable
 		}
 		}
-		number, hasResult = int32(be.Uint32(p.instructions[1:])), true
+		intValue := int32(be.Uint32(p.instructions[1:]))
+		if p.ctx == Type2Charstring {
+			// 5177.Type2.pdf section 3.2 "Charstring Number Encoding" says "If the
+			// charstring byte contains the value 255... [this] number is
+			// interpreted as a Fixed; that is, a signed number with 16 bits of
+			// fraction".
+			//
+			// we just round the 16.16 fixed point number to the closest integer value
+			number = (intValue >> 16) + (1 & (intValue >> 15)) // care with overflow
+			hasResult = true
+		} else {
+			number, hasResult = intValue, true
+		}
 		p.instructions = p.instructions[5:]
 		p.instructions = p.instructions[5:]
 	}
 	}
 
 

+ 40 - 34
vendor/github.com/go-text/typesetting/opentype/api/font/font.go

@@ -57,6 +57,7 @@ type Font struct {
 	Trak tables.Trak
 	Trak tables.Trak
 	Ankr tables.Ankr
 	Ankr tables.Ankr
 	Feat tables.Feat
 	Feat tables.Feat
+	Ltag tables.Ltag
 	Morx Morx
 	Morx Morx
 	Kern Kernx
 	Kern Kernx
 	Kerx Kernx
 	Kerx Kernx
@@ -77,7 +78,13 @@ func NewFont(ld *loader.Loader) (*Font, error) {
 		err error
 		err error
 	)
 	)
 
 
-	raw, err := ld.RawTable(loader.MustNewTag("cmap"))
+	// 'cmap' handling depend on os2
+	raw, _ := ld.RawTable(loader.MustNewTag("OS/2"))
+	os2, _, _ := tables.ParseOs2(raw)
+	fontPage := os2.FontPage()
+	out.os2, _ = newOs2(os2)
+
+	raw, err = ld.RawTable(loader.MustNewTag("cmap"))
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -85,12 +92,12 @@ func NewFont(ld *loader.Loader) (*Font, error) {
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
-	out.Cmap, out.cmapVar, err = api.ProcessCmap(tb)
+	out.Cmap, out.cmapVar, err = api.ProcessCmap(tb, fontPage)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	out.head, err = LoadHeadTable(ld)
+	out.head, _, err = LoadHeadTable(ld, nil)
 	if err != nil {
 	if err != nil {
 		return nil, err
 		return nil, err
 	}
 	}
@@ -120,10 +127,6 @@ func NewFont(ld *loader.Loader) (*Font, error) {
 
 
 	out.upem = out.head.Upem()
 	out.upem = out.head.Upem()
 
 
-	raw, _ = ld.RawTable(loader.MustNewTag("OS/2"))
-	os2, _, _ := tables.ParseOs2(raw)
-	out.os2, _ = newOs2(os2)
-
 	raw, _ = ld.RawTable(loader.MustNewTag("glyf"))
 	raw, _ = ld.RawTable(loader.MustNewTag("glyf"))
 	locaRaw, _ := ld.RawTable(loader.MustNewTag("loca"))
 	locaRaw, _ := ld.RawTable(loader.MustNewTag("loca"))
 	loca, err := tables.ParseLoca(locaRaw, int(maxp.NumGlyphs), out.head.IndexToLocFormat == 1)
 	loca, err := tables.ParseLoca(locaRaw, int(maxp.NumGlyphs), out.head.IndexToLocFormat == 1)
@@ -216,6 +219,9 @@ func NewFont(ld *loader.Loader) (*Font, error) {
 	raw, _ = ld.RawTable(loader.MustNewTag("feat"))
 	raw, _ = ld.RawTable(loader.MustNewTag("feat"))
 	out.Feat, _, _ = tables.ParseFeat(raw)
 	out.Feat, _, _ = tables.ParseFeat(raw)
 
 
+	raw, _ = ld.RawTable(loader.MustNewTag("ltag"))
+	out.Ltag, _, _ = tables.ParseLtag(raw)
+
 	return &out, nil
 	return &out, nil
 }
 }
 
 
@@ -223,22 +229,23 @@ var bhedTag = loader.MustNewTag("bhed")
 
 
 // LoadHeadTable loads the table corresponding to the 'head' tag.
 // LoadHeadTable loads the table corresponding to the 'head' tag.
 // If a 'bhed' Apple table is present, it replaces the 'head' one.
 // If a 'bhed' Apple table is present, it replaces the 'head' one.
-func LoadHeadTable(ld *loader.Loader) (tables.Head, error) {
-	var (
-		s   []byte
-		err error
-	)
+//
+// 'buffer' may be provided to reduce allocations; the return Head is guaranteed
+// not to retain any reference on 'buffer'.
+// If 'buffer' is nil or has not enough capacity, a new slice is allocated (and returned).
+func LoadHeadTable(ld *loader.Loader, buffer []byte) (tables.Head, []byte, error) {
+	var err error
 	// check 'bhed' first
 	// check 'bhed' first
 	if ld.HasTable(bhedTag) {
 	if ld.HasTable(bhedTag) {
-		s, err = ld.RawTable(bhedTag)
+		buffer, err = ld.RawTableTo(bhedTag, buffer)
 	} else {
 	} else {
-		s, err = ld.RawTable(loader.MustNewTag("head"))
+		buffer, err = ld.RawTableTo(loader.MustNewTag("head"), buffer)
 	}
 	}
 	if err != nil {
 	if err != nil {
-		return tables.Head{}, errors.New("missing required head (or bhed) table")
+		return tables.Head{}, nil, errors.New("missing required head (or bhed) table")
 	}
 	}
-	out, _, err := tables.ParseHead(s)
-	return out, err
+	out, _, err := tables.ParseHead(buffer)
+	return out, buffer, err
 }
 }
 
 
 // return nil if no table is valid (or present)
 // return nil if no table is valid (or present)
@@ -278,46 +285,45 @@ func loadCff(ld *loader.Loader, numGlyphs int) (*cff.Font, error) {
 	return cff, nil
 	return cff, nil
 }
 }
 
 
-func LoadHmtx(ld *loader.Loader, numGlyphs int) (*tables.Hhea, tables.Hmtx, error) {
-	raw, err := ld.RawTable(loader.MustNewTag("hhea"))
-	if err != nil {
-		return nil, tables.Hmtx{}, err
-	}
-	hhea, _, err := tables.ParseHhea(raw)
+func loadHVtmx(hheaRaw, htmxRaw []byte, numGlyphs int) (*tables.Hhea, tables.Hmtx, error) {
+	hhea, _, err := tables.ParseHhea(hheaRaw)
 	if err != nil {
 	if err != nil {
 		return nil, tables.Hmtx{}, err
 		return nil, tables.Hmtx{}, err
 	}
 	}
 
 
-	raw, err = ld.RawTable(loader.MustNewTag("hmtx"))
-	if err != nil {
-		return nil, tables.Hmtx{}, err
-	}
-	hmtx, _, err := tables.ParseHmtx(raw, int(hhea.NumOfLongMetrics), numGlyphs-int(hhea.NumOfLongMetrics))
+	hmtx, _, err := tables.ParseHmtx(htmxRaw, int(hhea.NumOfLongMetrics), numGlyphs-int(hhea.NumOfLongMetrics))
 	if err != nil {
 	if err != nil {
 		return nil, tables.Hmtx{}, err
 		return nil, tables.Hmtx{}, err
 	}
 	}
 	return &hhea, hmtx, nil
 	return &hhea, hmtx, nil
 }
 }
 
 
-func loadVmtx(ld *loader.Loader, numGlyphs int) (*tables.Hhea, tables.Hmtx, error) {
-	raw, err := ld.RawTable(loader.MustNewTag("vhea"))
+func LoadHmtx(ld *loader.Loader, numGlyphs int) (*tables.Hhea, tables.Hmtx, error) {
+	rawHead, err := ld.RawTable(loader.MustNewTag("hhea"))
 	if err != nil {
 	if err != nil {
 		return nil, tables.Hmtx{}, err
 		return nil, tables.Hmtx{}, err
 	}
 	}
-	vhea, _, err := tables.ParseHhea(raw)
+
+	rawMetrics, err := ld.RawTable(loader.MustNewTag("hmtx"))
 	if err != nil {
 	if err != nil {
 		return nil, tables.Hmtx{}, err
 		return nil, tables.Hmtx{}, err
 	}
 	}
 
 
-	raw, err = ld.RawTable(loader.MustNewTag("vmtx"))
+	return loadHVtmx(rawHead, rawMetrics, numGlyphs)
+}
+
+func loadVmtx(ld *loader.Loader, numGlyphs int) (*tables.Hhea, tables.Hmtx, error) {
+	rawHead, err := ld.RawTable(loader.MustNewTag("vhea"))
 	if err != nil {
 	if err != nil {
 		return nil, tables.Hmtx{}, err
 		return nil, tables.Hmtx{}, err
 	}
 	}
-	vmtx, _, err := tables.ParseHmtx(raw, int(vhea.NumOfLongMetrics), numGlyphs-int(vhea.NumOfLongMetrics))
+
+	rawMetrics, err := ld.RawTable(loader.MustNewTag("vmtx"))
 	if err != nil {
 	if err != nil {
 		return nil, tables.Hmtx{}, err
 		return nil, tables.Hmtx{}, err
 	}
 	}
-	return &vhea, vmtx, nil
+
+	return loadHVtmx(rawHead, rawMetrics, numGlyphs)
 }
 }
 
 
 func loadGDEF(ld *loader.Loader, axisCount int) (tables.GDEF, error) {
 func loadGDEF(ld *loader.Loader, axisCount int) (tables.GDEF, error) {

+ 2 - 2
vendor/github.com/go-text/typesetting/opentype/api/font/glyphs.go

@@ -70,8 +70,8 @@ func (f *Face) getPointsForGlyph(gid tables.GlyphID, currentDepth int, allPoints
 
 
 	hDelta := float32(g.XMin - getSideBearing(gid, f.hmtx))
 	hDelta := float32(g.XMin - getSideBearing(gid, f.hmtx))
 	vOrig := float32(g.YMax + getSideBearing(gid, f.vmtx))
 	vOrig := float32(g.YMax + getSideBearing(gid, f.vmtx))
-	hAdv := float32(f.getBaseAdvance(gid, f.hmtx))
-	vAdv := float32(f.getBaseAdvance(gid, f.vmtx))
+	hAdv := float32(f.getBaseAdvance(gid, f.hmtx, false))
+	vAdv := float32(f.getBaseAdvance(gid, f.vmtx, true))
 	phantoms[phantomLeft].X = hDelta
 	phantoms[phantomLeft].X = hDelta
 	phantoms[phantomRight].X = hAdv + hDelta
 	phantoms[phantomRight].X = hAdv + hDelta
 	phantoms[phantomTop].Y = vOrig
 	phantoms[phantomTop].Y = vOrig

+ 25 - 9
vendor/github.com/go-text/typesetting/opentype/api/font/metrics.go

@@ -182,12 +182,15 @@ func (f *Font) VariationGlyph(ch, varSelector rune) (GID, bool) {
 }
 }
 
 
 // do not take into account variations
 // do not take into account variations
-func (f *Font) getBaseAdvance(gid gID, table tables.Hmtx) int16 {
+func (f *Font) getBaseAdvance(gid gID, table tables.Hmtx, isVertical bool) int16 {
 	/* If `table` is empty, it means we don't have the metrics table
 	/* If `table` is empty, it means we don't have the metrics table
 	 * for this direction: return default advance.  Otherwise, it means that the
 	 * for this direction: return default advance.  Otherwise, it means that the
 	 * glyph index is out of bound: return zero. */
 	 * glyph index is out of bound: return zero. */
 	if table.IsEmpty() {
 	if table.IsEmpty() {
-		return int16(f.upem)
+		if isVertical {
+			return int16(f.upem)
+		}
+		return int16(f.upem / 2)
 	}
 	}
 
 
 	return table.Advance(gid)
 	return table.Advance(gid)
@@ -226,12 +229,12 @@ func (f *Face) getGlyphAdvanceVar(gid gID, isVertical bool) float32 {
 }
 }
 
 
 func (f *Face) HorizontalAdvance(gid GID) float32 {
 func (f *Face) HorizontalAdvance(gid GID) float32 {
-	advance := f.getBaseAdvance(gID(gid), f.hmtx)
+	advance := f.getBaseAdvance(gID(gid), f.hmtx, false)
 	if !f.isVar() {
 	if !f.isVar() {
 		return float32(advance)
 		return float32(advance)
 	}
 	}
 	if f.hvar != nil {
 	if f.hvar != nil {
-		return float32(advance) + getAdvanceVar(f.hvar, gID(gid), f.Coords)
+		return float32(advance) + getAdvanceDeltaUnscaled(f.hvar, gID(gid), f.Coords)
 	}
 	}
 	return f.getGlyphAdvanceVar(gID(gid), false)
 	return f.getGlyphAdvanceVar(gID(gid), false)
 }
 }
@@ -241,14 +244,19 @@ func (f *Face) isVar() bool {
 	return len(f.Coords) != 0 && len(f.Coords) == len(f.Font.fvar)
 	return len(f.Coords) != 0 && len(f.Coords) == len(f.Font.fvar)
 }
 }
 
 
+// HasVerticalMetrics returns true if a the 'vmtx' table is present.
+// If not, client should avoid calls to [VerticalAdvance], which will returns a
+// defaut value.
+func (f *Font) HasVerticalMetrics() bool { return !f.vmtx.IsEmpty() }
+
 func (f *Face) VerticalAdvance(gid GID) float32 {
 func (f *Face) VerticalAdvance(gid GID) float32 {
 	// return the opposite of the advance from the font
 	// return the opposite of the advance from the font
-	advance := f.getBaseAdvance(gID(gid), f.vmtx)
+	advance := f.getBaseAdvance(gID(gid), f.vmtx, true)
 	if !f.isVar() {
 	if !f.isVar() {
 		return -float32(advance)
 		return -float32(advance)
 	}
 	}
 	if f.vvar != nil {
 	if f.vvar != nil {
-		return -float32(advance) - getAdvanceVar(f.vvar, gID(gid), f.Coords)
+		return -float32(advance) - getAdvanceDeltaUnscaled(f.vvar, gID(gid), f.Coords)
 	}
 	}
 	return -f.getGlyphAdvanceVar(gID(gid), true)
 	return -f.getGlyphAdvanceVar(gID(gid), true)
 }
 }
@@ -269,7 +277,7 @@ func (f *Face) getVerticalSideBearing(glyph gID) int16 {
 		return sideBearing
 		return sideBearing
 	}
 	}
 	if f.vvar != nil {
 	if f.vvar != nil {
-		return sideBearing + int16(getSideBearingVar(f.vvar, glyph, f.Coords))
+		return sideBearing + int16(getLsbDeltaUnscaled(f.vvar, glyph, f.Coords))
 	}
 	}
 	return f.getGlyphSideBearingVar(glyph, true)
 	return f.getGlyphSideBearingVar(glyph, true)
 }
 }
@@ -288,8 +296,16 @@ func (f *Face) GlyphVOrigin(glyph GID) (x, y int32, found bool) {
 	}
 	}
 
 
 	if extents, ok := f.getExtentsFromGlyf(gID(glyph)); ok {
 	if extents, ok := f.getExtentsFromGlyf(gID(glyph)); ok {
-		tsb := f.getVerticalSideBearing(gID(glyph))
-		y = int32(extents.YBearing) + int32(tsb)
+		if f.HasVerticalMetrics() {
+			tsb := f.getVerticalSideBearing(gID(glyph))
+			y = int32(extents.YBearing) + int32(tsb)
+			return x, y, true
+		}
+
+		fontExtents, _ := f.FontHExtents()
+		advance := fontExtents.Ascender - fontExtents.Descender
+		diff := advance - -extents.Height
+		y = int32(extents.YBearing + (diff / 2))
 		return x, y, true
 		return x, y, true
 	}
 	}
 
 

+ 16 - 3
vendor/github.com/go-text/typesetting/opentype/api/font/renderer.go

@@ -12,8 +12,10 @@ import (
 	"github.com/go-text/typesetting/opentype/api"
 	"github.com/go-text/typesetting/opentype/api"
 )
 )
 
 
-var errEmptySbixTable = errors.New("empty 'sbix' table")
-var errEmptyBitmapTable = errors.New("empty bitmap table")
+var (
+	errEmptySbixTable   = errors.New("empty 'sbix' table")
+	errEmptyBitmapTable = errors.New("empty bitmap table")
+)
 
 
 // GlyphData returns the glyph content for [gid], or nil if
 // GlyphData returns the glyph content for [gid], or nil if
 // not found.
 // not found.
@@ -97,6 +99,11 @@ func (bt bitmap) glyphData(gid gID, xPpem, yPpem uint16) (api.GlyphBitmap, error
 		out.Format = api.PNG
 		out.Format = api.PNG
 	case 2, 5:
 	case 2, 5:
 		out.Format = api.BlackAndWhite
 		out.Format = api.BlackAndWhite
+		// ensure data length
+		L := out.Width * out.Height // in bits
+		if len(out.Data)*8 < L {
+			return api.GlyphBitmap{}, fmt.Errorf("EOF in glyph bitmap: expected %d, got %d", L, len(out.Data)*8)
+		}
 	default:
 	default:
 		return api.GlyphBitmap{}, fmt.Errorf("unsupported format %d in bitmap table", subtable.imageFormat)
 		return api.GlyphBitmap{}, fmt.Errorf("unsupported format %d in bitmap table", subtable.imageFormat)
 	}
 	}
@@ -264,10 +271,16 @@ func buildSegments(points []contourPoint) []api.Segment {
 	return out
 	return out
 }
 }
 
 
+type errGlyphOutOfRange int
+
+func (e errGlyphOutOfRange) Error() string {
+	return fmt.Sprintf("out of range glyph %d", e)
+}
+
 // apply variation when needed
 // apply variation when needed
 func (f *Face) glyphDataFromGlyf(glyph gID) (api.GlyphOutline, error) {
 func (f *Face) glyphDataFromGlyf(glyph gID) (api.GlyphOutline, error) {
 	if int(glyph) >= len(f.glyf) {
 	if int(glyph) >= len(f.glyf) {
-		return api.GlyphOutline{}, fmt.Errorf("out of range glyph %d", glyph)
+		return api.GlyphOutline{}, errGlyphOutOfRange(glyph)
 	}
 	}
 	var points []contourPoint
 	var points []contourPoint
 	f.getPointsForGlyph(glyph, 0, &points)
 	f.getPointsForGlyph(glyph, 0, &points)

+ 48 - 19
vendor/github.com/go-text/typesetting/opentype/api/font/variations.go

@@ -42,8 +42,9 @@ func (mv mvar) getVar(tag Tag, coords []float32) float32 {
 // ---------------------------------- gvar ----------------------------------
 // ---------------------------------- gvar ----------------------------------
 
 
 type gvar struct {
 type gvar struct {
-	sharedTuples [][]float32
-	variations   [][]tupleVariation // length glyphCount
+	sharedTuples         [][]float32        // with size tupleCount x axisCount
+	variations           [][]tupleVariation // with length glyphCount
+	sharedTupleActiveIdx []int              // with length tupleCount
 }
 }
 
 
 func newGvar(table tables.Gvar, glyf tables.Glyf) (gvar, error) {
 func newGvar(table tables.Gvar, glyf tables.Glyf) (gvar, error) {
@@ -52,8 +53,9 @@ func newGvar(table tables.Gvar, glyf tables.Glyf) (gvar, error) {
 	}
 	}
 
 
 	out := gvar{
 	out := gvar{
-		sharedTuples: make([][]float32, len(table.SharedTuples.SharedTuples)),
-		variations:   make([][]tupleVariation, len(table.GlyphVariationDatas)),
+		sharedTuples:         make([][]float32, len(table.SharedTuples.SharedTuples)),
+		variations:           make([][]tupleVariation, len(table.GlyphVariationDatas)),
+		sharedTupleActiveIdx: make([]int, len(table.SharedTuples.SharedTuples)),
 	}
 	}
 	for i, ts := range table.SharedTuples.SharedTuples {
 	for i, ts := range table.SharedTuples.SharedTuples {
 		out.sharedTuples[i] = ts.Values
 		out.sharedTuples[i] = ts.Values
@@ -72,6 +74,24 @@ func newGvar(table tables.Gvar, glyf tables.Glyf) (gvar, error) {
 		}
 		}
 		out.variations[i] = tvs
 		out.variations[i] = tvs
 	}
 	}
+
+	// For shared tuples that only have one axis active, share the index of
+	// that axis as a cache. This will speed up caclulateScalar() a lot
+	// for fonts with lots of axes and many "monovar" tuples.
+	for i, tuple := range out.sharedTuples {
+		idx := -1
+		for j, peak := range tuple {
+			if peak != 0 {
+				if idx != -1 { // two peaks or more, do not cache
+					idx = -1
+					break
+				}
+				idx = j
+			}
+		}
+		out.sharedTupleActiveIdx[i] = idx
+	}
+
 	return out, nil
 	return out, nil
 }
 }
 
 
@@ -83,23 +103,31 @@ type tupleVariation struct {
 	deltas []int16
 	deltas []int16
 }
 }
 
 
-// sharedTuples has length _ x axisCount
-func (t tupleVariation) calculateScalar(coords []float32, sharedTuples [][]float32) float32 {
+// sharedTuples has length tupleCount x axisCount
+// sharedTupleActiveIdx has length tupleCount
+func (t tupleVariation) calculateScalar(coords []float32, sharedTuples [][]float32, sharedTupleActiveIdx []int) float32 {
+	startIdx, endIdx := 0, len(coords)
 	peakTuple := t.PeakTuple.Values
 	peakTuple := t.PeakTuple.Values
-	if peakTuple == nil { // use shared tuple
+	if peakTuple == nil { // no peak specified -> use shared tuple
 		index := t.Index()
 		index := t.Index()
 		if int(index) >= len(sharedTuples) { // should not happend
 		if int(index) >= len(sharedTuples) { // should not happend
 			return 0.
 			return 0.
 		}
 		}
 		peakTuple = sharedTuples[index]
 		peakTuple = sharedTuples[index]
+
+		// use the cache to restrict the range
+		if v := sharedTupleActiveIdx[index]; v != -1 {
+			startIdx = v
+			endIdx = startIdx + 1
+		}
 	}
 	}
 
 
 	startTuple, endTuple := t.IntermediateTuples[0].Values, t.IntermediateTuples[1].Values
 	startTuple, endTuple := t.IntermediateTuples[0].Values, t.IntermediateTuples[1].Values
 	hasIntermediate := startTuple != nil
 	hasIntermediate := startTuple != nil
 
 
 	var scalar float32 = 1.
 	var scalar float32 = 1.
-	for i, v := range coords {
-		peak := peakTuple[i]
+	for i := startIdx; i < endIdx; i++ {
+		v, peak := coords[i], peakTuple[i]
 		if peak == 0 || v == peak {
 		if peak == 0 || v == peak {
 			continue
 			continue
 		}
 		}
@@ -294,14 +322,16 @@ func unpackDeltas(data []byte, pointNumbersCount int) ([]int16, error) {
 }
 }
 
 
 // update `points` in place
 // update `points` in place
-func (gvar gvar) applyDeltasToPoints(glyph tables.GlyphID, coords []float32, points []contourPoint) {
+func (gvar gvar) applyDeltasToPoints(glyph gID, coords []float32, points []contourPoint) {
 	// adapted from harfbuzz/src/hb-ot-var-gvar-table.hh
 	// adapted from harfbuzz/src/hb-ot-var-gvar-table.hh
 
 
 	if int(glyph) >= len(gvar.variations) { // should not happend
 	if int(glyph) >= len(gvar.variations) { // should not happend
 		return
 		return
 	}
 	}
-	/* Save original points for inferred delta calculation */
+
+	// save original points for inferred delta calculation
 	origPoints := append([]contourPoint(nil), points...)
 	origPoints := append([]contourPoint(nil), points...)
+	// flag is used to indicate referenced point
 	deltas := make([]contourPoint, len(points))
 	deltas := make([]contourPoint, len(points))
 
 
 	var endPoints []int // index into points
 	var endPoints []int // index into points
@@ -313,7 +343,7 @@ func (gvar gvar) applyDeltasToPoints(glyph tables.GlyphID, coords []float32, poi
 
 
 	varData := gvar.variations[glyph]
 	varData := gvar.variations[glyph]
 	for _, tuple := range varData {
 	for _, tuple := range varData {
-		scalar := tuple.calculateScalar(coords, gvar.sharedTuples)
+		scalar := tuple.calculateScalar(coords, gvar.sharedTuples, gvar.sharedTupleActiveIdx)
 		if scalar == 0 {
 		if scalar == 0 {
 			continue
 			continue
 		}
 		}
@@ -392,10 +422,9 @@ func (gvar gvar) applyDeltasToPoints(glyph tables.GlyphID, coords []float32, poi
 			startPoint = endPoint + 1
 			startPoint = endPoint + 1
 		}
 		}
 
 
-		/* apply specified / inferred deltas to points */
+		// apply specified / inferred deltas to points
 		for i, d := range deltas {
 		for i, d := range deltas {
-			points[i].X += d.X
-			points[i].Y += d.Y
+			points[i].translate(d.X, d.Y)
 		}
 		}
 	}
 	}
 }
 }
@@ -425,19 +454,19 @@ func inferDelta(targetVal, prevVal, nextVal, prevDelta, nextDelta float32) float
 		return nextDelta
 		return nextDelta
 	}
 	}
 
 
-	/* linear interpolation */
+	// linear interpolation
 	r := (targetVal - prevVal) / (nextVal - prevVal)
 	r := (targetVal - prevVal) / (nextVal - prevVal)
-	return (1.-r)*prevDelta + r*nextDelta
+	return prevDelta + r*(nextDelta-prevDelta)
 }
 }
 
 
 // ------------------------------ hvar/vvar ------------------------------
 // ------------------------------ hvar/vvar ------------------------------
 
 
-func getAdvanceVar(t *tables.HVAR, glyph tables.GlyphID, coords []float32) float32 {
+func getAdvanceDeltaUnscaled(t *tables.HVAR, glyph tables.GlyphID, coords []float32) float32 {
 	index := t.AdvanceWidthMapping.Index(glyph)
 	index := t.AdvanceWidthMapping.Index(glyph)
 	return t.ItemVariationStore.GetDelta(index, coords)
 	return t.ItemVariationStore.GetDelta(index, coords)
 }
 }
 
 
-func getSideBearingVar(t *tables.HVAR, glyph tables.GlyphID, coords []float32) float32 {
+func getLsbDeltaUnscaled(t *tables.HVAR, glyph tables.GlyphID, coords []float32) float32 {
 	if t.LsbMapping == nil {
 	if t.LsbMapping == nil {
 		return 0
 		return 0
 	}
 	}

+ 20 - 9
vendor/github.com/go-text/typesetting/opentype/loader/reader.go

@@ -126,9 +126,8 @@ func NewLoaders(file Resource) ([]*Loader, error) {
 	return out, nil
 	return out, nil
 }
 }
 
 
-func (pr *Loader) findTableBuffer(s tableSection) ([]byte, error) {
-	var buf []byte
-
+// dst is an optional storage which may be provided to reduce allocations.
+func (pr *Loader) findTableBuffer(s tableSection, dst []byte) ([]byte, error) {
 	if s.length != 0 && s.length < s.zLength {
 	if s.length != 0 && s.length < s.zLength {
 		zbuf := io.NewSectionReader(pr.file, int64(s.offset), int64(s.length))
 		zbuf := io.NewSectionReader(pr.file, int64(s.offset), int64(s.length))
 		r, err := zlib.NewReader(zbuf)
 		r, err := zlib.NewReader(zbuf)
@@ -137,17 +136,23 @@ func (pr *Loader) findTableBuffer(s tableSection) ([]byte, error) {
 		}
 		}
 		defer r.Close()
 		defer r.Close()
 
 
-		buf = make([]byte, s.zLength)
-		if _, err := io.ReadFull(r, buf); err != nil {
+		if cap(dst) < int(s.zLength) {
+			dst = make([]byte, s.zLength)
+		}
+		dst = dst[0:s.zLength]
+		if _, err := io.ReadFull(r, dst); err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
 	} else {
 	} else {
-		buf = make([]byte, s.length)
-		if _, err := pr.file.ReadAt(buf, int64(s.offset)); err != nil {
+		if cap(dst) < int(s.length) {
+			dst = make([]byte, s.length)
+		}
+		dst = dst[0:s.length]
+		if _, err := pr.file.ReadAt(dst, int64(s.offset)); err != nil {
 			return nil, err
 			return nil, err
 		}
 		}
 	}
 	}
-	return buf, nil
+	return dst, nil
 }
 }
 
 
 // HasTable returns true if [table] is present.
 // HasTable returns true if [table] is present.
@@ -159,12 +164,18 @@ func (pr *Loader) HasTable(table Tag) bool {
 // RawTable returns the binary content of the given table,
 // RawTable returns the binary content of the given table,
 // or an error if not found.
 // or an error if not found.
 func (pr *Loader) RawTable(tag Tag) ([]byte, error) {
 func (pr *Loader) RawTable(tag Tag) ([]byte, error) {
+	return pr.RawTableTo(tag, nil)
+}
+
+// RawTable writes the binary content of the given table to [dst], returning it,
+// or an error if not found.
+func (pr *Loader) RawTableTo(tag Tag, dst []byte) ([]byte, error) {
 	s, found := pr.tables[tag]
 	s, found := pr.tables[tag]
 	if !found {
 	if !found {
 		return nil, fmt.Errorf("missing table %s", tag)
 		return nil, fmt.Errorf("missing table %s", tag)
 	}
 	}
 
 
-	return pr.findTableBuffer(s)
+	return pr.findTableBuffer(s, dst)
 }
 }
 
 
 func parseOneFont(file Resource, offset uint32, relativeOffset bool) (parser *Loader, err error) {
 func parseOneFont(file Resource, offset uint32, relativeOffset bool) (parser *Loader, err error) {

+ 49 - 0
vendor/github.com/go-text/typesetting/opentype/tables/aat_ltag_gen.go

@@ -0,0 +1,49 @@
+// SPDX-License-Identifier: Unlicense OR BSD-3-Clause
+
+package tables
+
+import (
+	"encoding/binary"
+	"fmt"
+)
+
+// Code generated by binarygen from aat_ltag_src.go. DO NOT EDIT
+
+func ParseLtag(src []byte) (Ltag, int, error) {
+	var item Ltag
+	n := 0
+	if L := len(src); L < 12 {
+		return item, 0, fmt.Errorf("reading Ltag: "+"EOF: expected length: 12, got %d", L)
+	}
+	_ = src[11] // early bound checking
+	item.version = binary.BigEndian.Uint32(src[0:])
+	item.flags = binary.BigEndian.Uint32(src[4:])
+	item.numTags = binary.BigEndian.Uint32(src[8:])
+	n += 12
+
+	{
+		arrayLength := int(item.numTags)
+
+		if L := len(src); L < 12+arrayLength*4 {
+			return item, 0, fmt.Errorf("reading Ltag: "+"EOF: expected length: %d, got %d", 12+arrayLength*4, L)
+		}
+
+		item.tagRange = make([]stringRange, arrayLength) // allocation guarded by the previous check
+		for i := range item.tagRange {
+			item.tagRange[i].mustParse(src[12+i*4:])
+		}
+		n += arrayLength * 4
+	}
+	{
+
+		item.stringData = src[0:]
+		n = len(src)
+	}
+	return item, n, nil
+}
+
+func (item *stringRange) mustParse(src []byte) {
+	_ = src[3] // early bound checking
+	item.offset = binary.BigEndian.Uint16(src[0:])
+	item.length = binary.BigEndian.Uint16(src[2:])
+}

+ 25 - 0
vendor/github.com/go-text/typesetting/opentype/tables/aat_ltag_src.go

@@ -0,0 +1,25 @@
+// SPDX-License-Identifier: Unlicense OR BSD-3-Clause
+
+package tables
+
+import "github.com/go-text/typesetting/language"
+
+// Ltag is the language tags table
+// See https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6ltag.html
+type Ltag struct {
+	version    uint32        //	Table version; currently 1
+	flags      uint32        //	Table flags; currently none defined
+	numTags    uint32        //	Number of language tags which follow
+	tagRange   []stringRange `arrayCount:"ComputedField-numTags"` //	Range for each tag's string
+	stringData []byte        `subsliceStart:"AtStart" arrayCount:"ToEnd"`
+}
+
+type stringRange struct {
+	offset uint16 // Offset from the start of the table to the beginning of the string
+	length uint16 // String length (in bytes)
+}
+
+func (lt Ltag) Language(i uint16) language.Language {
+	r := lt.tagRange[i]
+	return language.NewLanguage(string(lt.stringData[r.offset : r.offset+r.length]))
+}

+ 22 - 0
vendor/github.com/go-text/typesetting/opentype/tables/os2_src.go

@@ -34,3 +34,25 @@ type Os2 struct {
 	usWinDescent        uint16
 	usWinDescent        uint16
 	HigherVersionData   []byte `arrayCount:"ToEnd"`
 	HigherVersionData   []byte `arrayCount:"ToEnd"`
 }
 }
+
+func (os *Os2) FontPage() FontPage {
+	if os.Version == 0 {
+		return FontPage(os.FsSelection & 0xFF00)
+	}
+	return FPNone
+}
+
+// See https://docs.microsoft.com/en-us/typography/legacy/legacy_arabic_fonts
+// https://github.com/Microsoft/Font-Validator/blob/520aaae/OTFontFileVal/val_OS2.cs#L644-L681
+type FontPage uint16
+
+const (
+	FPNone       FontPage = 0
+	FPHebrew     FontPage = 0xB100 /* Hebrew Windows 3.1 font page */
+	FPSimpArabic FontPage = 0xB200 /* Simplified Arabic Windows 3.1 font page */
+	FPTradArabic FontPage = 0xB300 /* Traditional Arabic Windows 3.1 font page */
+	FPOemArabic  FontPage = 0xB400 /* OEM Arabic Windows 3.1 font page */
+	FPSimpFarsi  FontPage = 0xBA00 /* Simplified Farsi Windows 3.1 font page */
+	FPTradFarsi  FontPage = 0xBB00 /* Traditional Farsi Windows 3.1 font page */
+	FPThai       FontPage = 0xDE00 /* Thai Windows 3.1 font page */
+)

+ 1 - 1
vendor/github.com/go-text/typesetting/opentype/tables/ot_properties.go

@@ -140,7 +140,7 @@ func (sc Script) GetLangSys(index uint16) LangSys {
 		if sc.DefaultLangSys != nil {
 		if sc.DefaultLangSys != nil {
 			return *sc.DefaultLangSys
 			return *sc.DefaultLangSys
 		}
 		}
-		return LangSys{}
+		return LangSys{RequiredFeatureIndex: 0xFFFF}
 	}
 	}
 	return sc.LangSys[index]
 	return sc.LangSys[index]
 }
 }

+ 25 - 0
vendor/github.com/go-text/typesetting/shaping/input.go

@@ -9,6 +9,7 @@ import (
 	"github.com/go-text/typesetting/font"
 	"github.com/go-text/typesetting/font"
 	"github.com/go-text/typesetting/harfbuzz"
 	"github.com/go-text/typesetting/harfbuzz"
 	"github.com/go-text/typesetting/language"
 	"github.com/go-text/typesetting/language"
+	"github.com/go-text/typesetting/opentype/loader"
 	"golang.org/x/image/math/fixed"
 	"golang.org/x/image/math/fixed"
 )
 )
 
 
@@ -24,6 +25,11 @@ type Input struct {
 	// Face is the font face to render the text in.
 	// Face is the font face to render the text in.
 	Face font.Face
 	Face font.Face
 
 
+	// FontFeatures activates or deactivates optional features
+	// provided by the font.
+	// The settings are applied to the whole [Text].
+	FontFeatures []FontFeature
+
 	// Size is the requested size of the font.
 	// Size is the requested size of the font.
 	// More generally, it is a scale factor applied to the resulting metrics.
 	// More generally, it is a scale factor applied to the resulting metrics.
 	// For instance, given a device resolution (in dpi) and a point size (like 14), the `Size` to
 	// For instance, given a device resolution (in dpi) and a point size (like 14), the `Size` to
@@ -37,6 +43,25 @@ type Input struct {
 	Language language.Language
 	Language language.Language
 }
 }
 
 
+// FontFeature sets one font feature.
+//
+// A font feature is an optionnal behavior a font might expose,
+// identified by a 4 bytes [Tag].
+// Most features are disabled by default; setting a non zero [Value]
+// enables it.
+//
+// An exemple of font feature is the replacement of fractions (like 1/2, 3/4)
+// by specialized glyphs, which would be activated by using
+//
+//	FontFeature{Tag: loader.MustNewTag("frac"), Value: 1}
+//
+// See also https://learn.microsoft.com/en-us/typography/opentype/spec/featurelist
+// and https://developer.mozilla.org/en-US/docs/Web/CSS/CSS_fonts/OpenType_fonts_guide
+type FontFeature struct {
+	Tag   loader.Tag
+	Value uint32
+}
+
 // Fontmap provides a general mechanism to select
 // Fontmap provides a general mechanism to select
 // a face to use when shaping text.
 // a face to use when shaping text.
 type Fontmap interface {
 type Fontmap interface {

+ 20 - 4
vendor/github.com/go-text/typesetting/shaping/shaper.go

@@ -16,6 +16,8 @@ type HarfbuzzShaper struct {
 	buf *harfbuzz.Buffer
 	buf *harfbuzz.Buffer
 
 
 	fonts fontLRU
 	fonts fontLRU
+
+	features []harfbuzz.Feature
 }
 }
 
 
 // SetFontCacheSize adjusts the size of the font cache within the shaper.
 // SetFontCacheSize adjusts the size of the font cache within the shaper.
@@ -94,8 +96,22 @@ func (t *HarfbuzzShaper) Shape(input Input) Output {
 	font.XScale = int32(input.Size.Ceil()) << scaleShift
 	font.XScale = int32(input.Size.Ceil()) << scaleShift
 	font.YScale = font.XScale
 	font.YScale = font.XScale
 
 
+	if L := len(input.FontFeatures); cap(t.features) < L {
+		t.features = make([]harfbuzz.Feature, L)
+	} else {
+		t.features = t.features[0:L]
+	}
+	for i, f := range input.FontFeatures {
+		t.features[i] = harfbuzz.Feature{
+			Tag:   f.Tag,
+			Value: f.Value,
+			Start: harfbuzz.FeatureGlobalStart,
+			End:   harfbuzz.FeatureGlobalEnd,
+		}
+	}
+
 	// Actually use harfbuzz to shape the text.
 	// Actually use harfbuzz to shape the text.
-	t.buf.Shape(font, nil)
+	t.buf.Shape(font, t.features)
 
 
 	// Convert the shaped text into an Output.
 	// Convert the shaped text into an Output.
 	glyphs := make([]Glyph, len(t.buf.Info))
 	glyphs := make([]Glyph, len(t.buf.Info))
@@ -168,10 +184,10 @@ func countClusters(glyphs []Glyph, textLen int, dir di.Direction) {
 			if nextCluster == -1 {
 			if nextCluster == -1 {
 				nextCluster = textLen
 				nextCluster = textLen
 			}
 			}
-			switch dir {
-			case di.DirectionLTR:
+			switch dir.Progression() {
+			case di.FromTopLeft:
 				runesInCluster = nextCluster - currentCluster
 				runesInCluster = nextCluster - currentCluster
-			case di.DirectionRTL:
+			case di.TowardTopLeft:
 				runesInCluster = previousCluster - currentCluster
 				runesInCluster = previousCluster - currentCluster
 			}
 			}
 			previousCluster = g
 			previousCluster = g

+ 64 - 8
vendor/github.com/go-text/typesetting/shaping/wrapping.go

@@ -580,6 +580,10 @@ type wrapBuffer struct {
 	alt []Output
 	alt []Output
 	// altAdvance is the sum of the advances of each run in alt.
 	// altAdvance is the sum of the advances of each run in alt.
 	altAdvance fixed.Int26_6
 	altAdvance fixed.Int26_6
+	// altSave is a slice into alt used to save and restore the state of the alt buffer.
+	altSave []Output
+	// altAdvanceSave is the altAdvance of the altSave field.
+	altAdvanceSave fixed.Int26_6
 	// best is a slice holding the best known line. When possible, it
 	// best is a slice holding the best known line. When possible, it
 	// is a subslice of line, but if line runs out of capacity it will
 	// is a subslice of line, but if line runs out of capacity it will
 	// be heap allocated.
 	// be heap allocated.
@@ -598,6 +602,8 @@ func (w *wrapBuffer) reset() {
 	}
 	}
 	w.alt = w.alt[:0]
 	w.alt = w.alt[:0]
 	w.altAdvance = 0
 	w.altAdvance = 0
+	w.altSave = w.alt[:0]
+	w.altAdvanceSave = 0
 	if cap(w.line) < 100 {
 	if cap(w.line) < 100 {
 		w.line = make([]Output, 0, 100)
 		w.line = make([]Output, 0, 100)
 	}
 	}
@@ -634,6 +640,8 @@ func (w *wrapBuffer) finalParagraph() []Line {
 func (w *wrapBuffer) startLine() {
 func (w *wrapBuffer) startLine() {
 	w.alt = w.alt[:0]
 	w.alt = w.alt[:0]
 	w.altAdvance = 0
 	w.altAdvance = 0
+	w.altSave = w.alt[:0]
+	w.altAdvanceSave = 0
 	w.best = nil
 	w.best = nil
 	w.bestInLine = false
 	w.bestInLine = false
 }
 }
@@ -644,6 +652,22 @@ func (w *wrapBuffer) candidateAppend(run Output) {
 	w.altAdvance = w.altAdvance + run.Advance
 	w.altAdvance = w.altAdvance + run.Advance
 }
 }
 
 
+// candidateSave captures the current state of the line candidate, enabling it to
+// be restored by a call to candidateRestore(). Only one state can be saved at a
+// time, and a subsequent call to candidateSave will override any current saved
+// state.
+func (w *wrapBuffer) candidateSave() {
+	w.altSave = w.alt
+	w.altAdvanceSave = w.altAdvance
+}
+
+// candidateRestore resets the state of the line candidate to the state at the time
+// of the most recent call to candidateSave().
+func (w *wrapBuffer) candidateRestore() {
+	w.alt = w.altSave
+	w.altAdvance = w.altAdvanceSave
+}
+
 func (w *wrapBuffer) candidateAdvance() fixed.Int26_6 {
 func (w *wrapBuffer) candidateAdvance() fixed.Int26_6 {
 	return w.altAdvance
 	return w.altAdvance
 }
 }
@@ -735,7 +759,7 @@ func (l *LineWrapper) WrapParagraph(config WrapConfig, maxWidth int, paragraph [
 		_, firstRun, hasFirst := runs.Next()
 		_, firstRun, hasFirst := runs.Next()
 		_, _, hasSecond := runs.Peek()
 		_, _, hasSecond := runs.Peek()
 		if hasFirst && !hasSecond {
 		if hasFirst && !hasSecond {
-			if firstRun.Advance.Ceil() < maxWidth {
+			if firstRun.Advance.Ceil() <= maxWidth {
 				return l.scratch.singleRunParagraph(firstRun), 0
 				return l.scratch.singleRunParagraph(firstRun), 0
 			}
 			}
 		}
 		}
@@ -839,7 +863,7 @@ func (l *LineWrapper) WrapNextLine(maxWidth int) (finalLine Line, truncated int,
 	truncating := l.config.TruncateAfterLines == 1
 	truncating := l.config.TruncateAfterLines == 1
 
 
 	// If we're not truncating, the iterator contains only one run, and that run fits, take the fast path.
 	// If we're not truncating, the iterator contains only one run, and that run fits, take the fast path.
-	if !(l.config.TextContinues && truncating) && firstRun.Runes.Offset == l.lineStartRune && firstRun.Advance.Ceil() < maxWidth {
+	if !(l.config.TextContinues && truncating) && firstRun.Runes.Offset == l.lineStartRune && firstRun.Advance.Ceil() <= maxWidth {
 		// Save current iterator state so we can peek ahead.
 		// Save current iterator state so we can peek ahead.
 		l.glyphRuns.Save()
 		l.glyphRuns.Save()
 		// Advance beyond firstRun, which we already know from the Peek() above.
 		// Advance beyond firstRun, which we already know from the Peek() above.
@@ -869,13 +893,33 @@ func (l *LineWrapper) WrapNextLine(maxWidth int) (finalLine Line, truncated int,
 	return finalLine, 0, done
 	return finalLine, 0, done
 }
 }
 
 
+// checkpoint captures both the current candidate line and the corresponding run iteration
+// state. These can be restored together by calling restore().
+func (l *LineWrapper) checkpoint() {
+	l.scratch.candidateSave()
+	l.glyphRuns.Save()
+}
+
+// restore resets the current candidate line and corresponding run iteration state to the
+// values at the last call to checkpoint().
+func (l *LineWrapper) restore() {
+	l.scratch.candidateRestore()
+	l.glyphRuns.Restore()
+}
+
 // wrapNextLine iteratively processes line breaking candidates, building a line within the
 // wrapNextLine iteratively processes line breaking candidates, building a line within the
 // wrapper's scratch [WrapBuffer]. It returns whether the paragraph is finished once it has
 // wrapper's scratch [WrapBuffer]. It returns whether the paragraph is finished once it has
 // successfully built a line.
 // successfully built a line.
 func (l *LineWrapper) wrapNextLine(config lineConfig) (done bool) {
 func (l *LineWrapper) wrapNextLine(config lineConfig) (done bool) {
-	for option, ok := l.breaker.nextWordBreak(); ok; option, ok = l.breaker.nextWordBreak() {
+	for {
+		l.checkpoint()
+		option, ok := l.breaker.nextWordBreak()
+		if !ok {
+			break
+		}
 		switch result, candidateRun := l.processBreakOption(option, config); result {
 		switch result, candidateRun := l.processBreakOption(option, config); result {
 		case breakInvalid:
 		case breakInvalid:
+			l.restore()
 			continue
 			continue
 		case fits:
 		case fits:
 			l.scratch.markCandidateBest(candidateRun)
 			l.scratch.markCandidateBest(candidateRun)
@@ -886,12 +930,15 @@ func (l *LineWrapper) wrapNextLine(config lineConfig) (done bool) {
 			return true
 			return true
 		case truncated:
 		case truncated:
 			// The candidateRun does not fit.
 			// The candidateRun does not fit.
-			l.scratch.markCandidateBest()
+			if !l.scratch.hasBest() {
+				l.scratch.markCandidateBest()
+			}
 			if l.config.BreakPolicy == Never {
 			if l.config.BreakPolicy == Never {
 				return true
 				return true
 			}
 			}
 			// Fall through to try grapheme breaking.
 			// Fall through to try grapheme breaking.
 		case newLineBeforeBreak:
 		case newLineBeforeBreak:
+			l.restore()
 			// We found a valid line that didn't use this break, so mark that it can be
 			// We found a valid line that didn't use this break, so mark that it can be
 			// reused on the next iteration.
 			// reused on the next iteration.
 			l.breaker.markWordOptionUnused()
 			l.breaker.markWordOptionUnused()
@@ -909,12 +956,21 @@ func (l *LineWrapper) wrapNextLine(config lineConfig) (done bool) {
 			}
 			}
 			// Fall through to try grapheme breaking.
 			// Fall through to try grapheme breaking.
 		}
 		}
+		// Ensure that the grapheme breaking has access to
+		// all runs we already tried in the iterator.
+		l.restore()
 		// segment using UAX#29 grapheme clustering here and try
 		// segment using UAX#29 grapheme clustering here and try
 		// breaking again using only those boundaries to find a viable break in cases
 		// breaking again using only those boundaries to find a viable break in cases
 		// where no UAX#14 breaks were viable above.
 		// where no UAX#14 breaks were viable above.
-		for option, ok := l.breaker.nextGraphemeBreak(); ok; option, ok = l.breaker.nextGraphemeBreak() {
+		for {
+			l.checkpoint()
+			option, ok := l.breaker.nextGraphemeBreak()
+			if !ok {
+				break
+			}
 			switch result, candidateRun := l.processBreakOption(option, config); result {
 			switch result, candidateRun := l.processBreakOption(option, config); result {
 			case breakInvalid:
 			case breakInvalid:
+				l.restore()
 				continue
 				continue
 			case fits:
 			case fits:
 				// If we found at least one viable line candidate, we aren't using the word break option.
 				// If we found at least one viable line candidate, we aren't using the word break option.
@@ -930,6 +986,7 @@ func (l *LineWrapper) wrapNextLine(config lineConfig) (done bool) {
 				}
 				}
 				return true
 				return true
 			case newLineBeforeBreak:
 			case newLineBeforeBreak:
+				l.restore()
 				// If we found at least one viable line candidate, we aren't using the word break option.
 				// If we found at least one viable line candidate, we aren't using the word break option.
 				l.breaker.markWordOptionUnused()
 				l.breaker.markWordOptionUnused()
 				l.breaker.markGraphemeOptionUnused()
 				l.breaker.markGraphemeOptionUnused()
@@ -978,12 +1035,12 @@ const (
 
 
 // processBreakOption evaluates whether the provided breakOption can fit onto the current line wrapping line.
 // processBreakOption evaluates whether the provided breakOption can fit onto the current line wrapping line.
 func (l *LineWrapper) processBreakOption(option breakOption, config lineConfig) (processBreakResult, Output) {
 func (l *LineWrapper) processBreakOption(option breakOption, config lineConfig) (processBreakResult, Output) {
+	// Discard break options on previous lines.
 	if option.breakAtRune < l.lineStartRune {
 	if option.breakAtRune < l.lineStartRune {
 		return breakInvalid, Output{}
 		return breakInvalid, Output{}
 	}
 	}
 
 
-	l.glyphRuns.Save()
-
+	// Fill candidate line with runs until the run containing the break option.
 	l.fillUntil(l.glyphRuns, option)
 	l.fillUntil(l.glyphRuns, option)
 
 
 	currRunIndex, run, _ := l.glyphRuns.Peek()
 	currRunIndex, run, _ := l.glyphRuns.Peek()
@@ -999,7 +1056,6 @@ func (l *LineWrapper) processBreakOption(option breakOption, config lineConfig)
 		if !l.scratch.hasBest() {
 		if !l.scratch.hasBest() {
 			return cannotFit, candidateRun
 			return cannotFit, candidateRun
 		} else {
 		} else {
-			l.glyphRuns.Restore()
 			return newLineBeforeBreak, candidateRun
 			return newLineBeforeBreak, candidateRun
 		}
 		}
 	} else if config.truncating && candidateLineWidth > config.truncatedMaxWidth {
 	} else if config.truncating && candidateLineWidth > config.truncatedMaxWidth {

+ 162 - 104
vendor/github.com/go-text/typesetting/unicodedata/combining_classes.go

@@ -26,8 +26,7 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x05d0, Hi: 0x05ea, Stride: 1},
 			{Lo: 0x05d0, Hi: 0x05ea, Stride: 1},
 			{Lo: 0x05ef, Hi: 0x05f4, Stride: 1},
 			{Lo: 0x05ef, Hi: 0x05f4, Stride: 1},
 			{Lo: 0x0600, Hi: 0x060f, Stride: 1},
 			{Lo: 0x0600, Hi: 0x060f, Stride: 1},
-			{Lo: 0x061b, Hi: 0x061c, Stride: 1},
-			{Lo: 0x061e, Hi: 0x064a, Stride: 1},
+			{Lo: 0x061b, Hi: 0x064a, Stride: 1},
 			{Lo: 0x0660, Hi: 0x066f, Stride: 1},
 			{Lo: 0x0660, Hi: 0x066f, Stride: 1},
 			{Lo: 0x0671, Hi: 0x06d5, Stride: 1},
 			{Lo: 0x0671, Hi: 0x06d5, Stride: 1},
 			{Lo: 0x06dd, Hi: 0x06de, Stride: 1},
 			{Lo: 0x06dd, Hi: 0x06de, Stride: 1},
@@ -46,8 +45,9 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x0840, Hi: 0x0858, Stride: 1},
 			{Lo: 0x0840, Hi: 0x0858, Stride: 1},
 			{Lo: 0x085e, Hi: 0x0860, Stride: 2},
 			{Lo: 0x085e, Hi: 0x0860, Stride: 2},
 			{Lo: 0x0861, Hi: 0x086a, Stride: 1},
 			{Lo: 0x0861, Hi: 0x086a, Stride: 1},
-			{Lo: 0x08a0, Hi: 0x08b4, Stride: 1},
-			{Lo: 0x08b6, Hi: 0x08c7, Stride: 1},
+			{Lo: 0x0870, Hi: 0x088e, Stride: 1},
+			{Lo: 0x0890, Hi: 0x0891, Stride: 1},
+			{Lo: 0x08a0, Hi: 0x08c9, Stride: 1},
 			{Lo: 0x08e2, Hi: 0x0900, Stride: 30},
 			{Lo: 0x08e2, Hi: 0x0900, Stride: 30},
 			{Lo: 0x0901, Hi: 0x093b, Stride: 1},
 			{Lo: 0x0901, Hi: 0x093b, Stride: 1},
 			{Lo: 0x093d, Hi: 0x094c, Stride: 1},
 			{Lo: 0x093d, Hi: 0x094c, Stride: 1},
@@ -132,7 +132,8 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x0c46, Hi: 0x0c48, Stride: 1},
 			{Lo: 0x0c46, Hi: 0x0c48, Stride: 1},
 			{Lo: 0x0c4a, Hi: 0x0c4c, Stride: 1},
 			{Lo: 0x0c4a, Hi: 0x0c4c, Stride: 1},
 			{Lo: 0x0c58, Hi: 0x0c5a, Stride: 1},
 			{Lo: 0x0c58, Hi: 0x0c5a, Stride: 1},
-			{Lo: 0x0c60, Hi: 0x0c63, Stride: 1},
+			{Lo: 0x0c5d, Hi: 0x0c60, Stride: 3},
+			{Lo: 0x0c61, Hi: 0x0c63, Stride: 1},
 			{Lo: 0x0c66, Hi: 0x0c6f, Stride: 1},
 			{Lo: 0x0c66, Hi: 0x0c6f, Stride: 1},
 			{Lo: 0x0c77, Hi: 0x0c8c, Stride: 1},
 			{Lo: 0x0c77, Hi: 0x0c8c, Stride: 1},
 			{Lo: 0x0c8e, Hi: 0x0c90, Stride: 1},
 			{Lo: 0x0c8e, Hi: 0x0c90, Stride: 1},
@@ -143,10 +144,10 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x0cc6, Hi: 0x0cc8, Stride: 1},
 			{Lo: 0x0cc6, Hi: 0x0cc8, Stride: 1},
 			{Lo: 0x0cca, Hi: 0x0ccc, Stride: 1},
 			{Lo: 0x0cca, Hi: 0x0ccc, Stride: 1},
 			{Lo: 0x0cd5, Hi: 0x0cd6, Stride: 1},
 			{Lo: 0x0cd5, Hi: 0x0cd6, Stride: 1},
-			{Lo: 0x0cde, Hi: 0x0ce0, Stride: 2},
-			{Lo: 0x0ce1, Hi: 0x0ce3, Stride: 1},
+			{Lo: 0x0cdd, Hi: 0x0cde, Stride: 1},
+			{Lo: 0x0ce0, Hi: 0x0ce3, Stride: 1},
 			{Lo: 0x0ce6, Hi: 0x0cef, Stride: 1},
 			{Lo: 0x0ce6, Hi: 0x0cef, Stride: 1},
-			{Lo: 0x0cf1, Hi: 0x0cf2, Stride: 1},
+			{Lo: 0x0cf1, Hi: 0x0cf3, Stride: 1},
 			{Lo: 0x0d00, Hi: 0x0d0c, Stride: 1},
 			{Lo: 0x0d00, Hi: 0x0d0c, Stride: 1},
 			{Lo: 0x0d0e, Hi: 0x0d10, Stride: 1},
 			{Lo: 0x0d0e, Hi: 0x0d10, Stride: 1},
 			{Lo: 0x0d12, Hi: 0x0d3a, Stride: 1},
 			{Lo: 0x0d12, Hi: 0x0d3a, Stride: 1},
@@ -179,8 +180,8 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x0ebb, Hi: 0x0ebd, Stride: 1},
 			{Lo: 0x0ebb, Hi: 0x0ebd, Stride: 1},
 			{Lo: 0x0ec0, Hi: 0x0ec4, Stride: 1},
 			{Lo: 0x0ec0, Hi: 0x0ec4, Stride: 1},
 			{Lo: 0x0ec6, Hi: 0x0ecc, Stride: 6},
 			{Lo: 0x0ec6, Hi: 0x0ecc, Stride: 6},
-			{Lo: 0x0ecd, Hi: 0x0ed0, Stride: 3},
-			{Lo: 0x0ed1, Hi: 0x0ed9, Stride: 1},
+			{Lo: 0x0ecd, Hi: 0x0ece, Stride: 1},
+			{Lo: 0x0ed0, Hi: 0x0ed9, Stride: 1},
 			{Lo: 0x0edc, Hi: 0x0edf, Stride: 1},
 			{Lo: 0x0edc, Hi: 0x0edf, Stride: 1},
 			{Lo: 0x0f00, Hi: 0x0f17, Stride: 1},
 			{Lo: 0x0f00, Hi: 0x0f17, Stride: 1},
 			{Lo: 0x0f1a, Hi: 0x0f34, Stride: 1},
 			{Lo: 0x0f1a, Hi: 0x0f34, Stride: 1},
@@ -223,9 +224,8 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x13f8, Hi: 0x13fd, Stride: 1},
 			{Lo: 0x13f8, Hi: 0x13fd, Stride: 1},
 			{Lo: 0x1400, Hi: 0x169c, Stride: 1},
 			{Lo: 0x1400, Hi: 0x169c, Stride: 1},
 			{Lo: 0x16a0, Hi: 0x16f8, Stride: 1},
 			{Lo: 0x16a0, Hi: 0x16f8, Stride: 1},
-			{Lo: 0x1700, Hi: 0x170c, Stride: 1},
-			{Lo: 0x170e, Hi: 0x1713, Stride: 1},
-			{Lo: 0x1720, Hi: 0x1733, Stride: 1},
+			{Lo: 0x1700, Hi: 0x1713, Stride: 1},
+			{Lo: 0x171f, Hi: 0x1733, Stride: 1},
 			{Lo: 0x1735, Hi: 0x1736, Stride: 1},
 			{Lo: 0x1735, Hi: 0x1736, Stride: 1},
 			{Lo: 0x1740, Hi: 0x1753, Stride: 1},
 			{Lo: 0x1740, Hi: 0x1753, Stride: 1},
 			{Lo: 0x1760, Hi: 0x176c, Stride: 1},
 			{Lo: 0x1760, Hi: 0x176c, Stride: 1},
@@ -235,8 +235,7 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x17d3, Hi: 0x17dc, Stride: 1},
 			{Lo: 0x17d3, Hi: 0x17dc, Stride: 1},
 			{Lo: 0x17e0, Hi: 0x17e9, Stride: 1},
 			{Lo: 0x17e0, Hi: 0x17e9, Stride: 1},
 			{Lo: 0x17f0, Hi: 0x17f9, Stride: 1},
 			{Lo: 0x17f0, Hi: 0x17f9, Stride: 1},
-			{Lo: 0x1800, Hi: 0x180e, Stride: 1},
-			{Lo: 0x1810, Hi: 0x1819, Stride: 1},
+			{Lo: 0x1800, Hi: 0x1819, Stride: 1},
 			{Lo: 0x1820, Hi: 0x1878, Stride: 1},
 			{Lo: 0x1820, Hi: 0x1878, Stride: 1},
 			{Lo: 0x1880, Hi: 0x18a8, Stride: 1},
 			{Lo: 0x1880, Hi: 0x18a8, Stride: 1},
 			{Lo: 0x18aa, Hi: 0x18b0, Stride: 6},
 			{Lo: 0x18aa, Hi: 0x18b0, Stride: 6},
@@ -260,9 +259,9 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x1abe, Hi: 0x1b00, Stride: 66},
 			{Lo: 0x1abe, Hi: 0x1b00, Stride: 66},
 			{Lo: 0x1b01, Hi: 0x1b33, Stride: 1},
 			{Lo: 0x1b01, Hi: 0x1b33, Stride: 1},
 			{Lo: 0x1b35, Hi: 0x1b43, Stride: 1},
 			{Lo: 0x1b35, Hi: 0x1b43, Stride: 1},
-			{Lo: 0x1b45, Hi: 0x1b4b, Stride: 1},
+			{Lo: 0x1b45, Hi: 0x1b4c, Stride: 1},
 			{Lo: 0x1b50, Hi: 0x1b6a, Stride: 1},
 			{Lo: 0x1b50, Hi: 0x1b6a, Stride: 1},
-			{Lo: 0x1b74, Hi: 0x1b7c, Stride: 1},
+			{Lo: 0x1b74, Hi: 0x1b7e, Stride: 1},
 			{Lo: 0x1b80, Hi: 0x1ba9, Stride: 1},
 			{Lo: 0x1b80, Hi: 0x1ba9, Stride: 1},
 			{Lo: 0x1bac, Hi: 0x1be5, Stride: 1},
 			{Lo: 0x1bac, Hi: 0x1be5, Stride: 1},
 			{Lo: 0x1be7, Hi: 0x1bf1, Stride: 1},
 			{Lo: 0x1be7, Hi: 0x1bf1, Stride: 1},
@@ -295,7 +294,7 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x2066, Hi: 0x2071, Stride: 1},
 			{Lo: 0x2066, Hi: 0x2071, Stride: 1},
 			{Lo: 0x2074, Hi: 0x208e, Stride: 1},
 			{Lo: 0x2074, Hi: 0x208e, Stride: 1},
 			{Lo: 0x2090, Hi: 0x209c, Stride: 1},
 			{Lo: 0x2090, Hi: 0x209c, Stride: 1},
-			{Lo: 0x20a0, Hi: 0x20bf, Stride: 1},
+			{Lo: 0x20a0, Hi: 0x20c0, Stride: 1},
 			{Lo: 0x20dd, Hi: 0x20e0, Stride: 1},
 			{Lo: 0x20dd, Hi: 0x20e0, Stride: 1},
 			{Lo: 0x20e2, Hi: 0x20e4, Stride: 1},
 			{Lo: 0x20e2, Hi: 0x20e4, Stride: 1},
 			{Lo: 0x2100, Hi: 0x218b, Stride: 1},
 			{Lo: 0x2100, Hi: 0x218b, Stride: 1},
@@ -303,9 +302,7 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x2440, Hi: 0x244a, Stride: 1},
 			{Lo: 0x2440, Hi: 0x244a, Stride: 1},
 			{Lo: 0x2460, Hi: 0x2b73, Stride: 1},
 			{Lo: 0x2460, Hi: 0x2b73, Stride: 1},
 			{Lo: 0x2b76, Hi: 0x2b95, Stride: 1},
 			{Lo: 0x2b76, Hi: 0x2b95, Stride: 1},
-			{Lo: 0x2b97, Hi: 0x2c2e, Stride: 1},
-			{Lo: 0x2c30, Hi: 0x2c5e, Stride: 1},
-			{Lo: 0x2c60, Hi: 0x2cee, Stride: 1},
+			{Lo: 0x2b97, Hi: 0x2cee, Stride: 1},
 			{Lo: 0x2cf2, Hi: 0x2cf3, Stride: 1},
 			{Lo: 0x2cf2, Hi: 0x2cf3, Stride: 1},
 			{Lo: 0x2cf9, Hi: 0x2d25, Stride: 1},
 			{Lo: 0x2cf9, Hi: 0x2d25, Stride: 1},
 			{Lo: 0x2d27, Hi: 0x2d2d, Stride: 6},
 			{Lo: 0x2d27, Hi: 0x2d2d, Stride: 6},
@@ -320,7 +317,7 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x2dc8, Hi: 0x2dce, Stride: 1},
 			{Lo: 0x2dc8, Hi: 0x2dce, Stride: 1},
 			{Lo: 0x2dd0, Hi: 0x2dd6, Stride: 1},
 			{Lo: 0x2dd0, Hi: 0x2dd6, Stride: 1},
 			{Lo: 0x2dd8, Hi: 0x2dde, Stride: 1},
 			{Lo: 0x2dd8, Hi: 0x2dde, Stride: 1},
-			{Lo: 0x2e00, Hi: 0x2e52, Stride: 1},
+			{Lo: 0x2e00, Hi: 0x2e5d, Stride: 1},
 			{Lo: 0x2e80, Hi: 0x2e99, Stride: 1},
 			{Lo: 0x2e80, Hi: 0x2e99, Stride: 1},
 			{Lo: 0x2e9b, Hi: 0x2ef3, Stride: 1},
 			{Lo: 0x2e9b, Hi: 0x2ef3, Stride: 1},
 			{Lo: 0x2f00, Hi: 0x2fd5, Stride: 1},
 			{Lo: 0x2f00, Hi: 0x2fd5, Stride: 1},
@@ -335,8 +332,7 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x31f0, Hi: 0x321e, Stride: 1},
 			{Lo: 0x31f0, Hi: 0x321e, Stride: 1},
 			{Lo: 0x3220, Hi: 0x3400, Stride: 1},
 			{Lo: 0x3220, Hi: 0x3400, Stride: 1},
 			{Lo: 0x4dbf, Hi: 0x4e00, Stride: 1},
 			{Lo: 0x4dbf, Hi: 0x4e00, Stride: 1},
-			{Lo: 0x9ffc, Hi: 0xa000, Stride: 4},
-			{Lo: 0xa001, Hi: 0xa48c, Stride: 1},
+			{Lo: 0x9fff, Hi: 0xa48c, Stride: 1},
 			{Lo: 0xa490, Hi: 0xa4c6, Stride: 1},
 			{Lo: 0xa490, Hi: 0xa4c6, Stride: 1},
 			{Lo: 0xa4d0, Hi: 0xa62b, Stride: 1},
 			{Lo: 0xa4d0, Hi: 0xa62b, Stride: 1},
 			{Lo: 0xa640, Hi: 0xa66e, Stride: 1},
 			{Lo: 0xa640, Hi: 0xa66e, Stride: 1},
@@ -344,9 +340,11 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0xa67e, Hi: 0xa69d, Stride: 1},
 			{Lo: 0xa67e, Hi: 0xa69d, Stride: 1},
 			{Lo: 0xa6a0, Hi: 0xa6ef, Stride: 1},
 			{Lo: 0xa6a0, Hi: 0xa6ef, Stride: 1},
 			{Lo: 0xa6f2, Hi: 0xa6f7, Stride: 1},
 			{Lo: 0xa6f2, Hi: 0xa6f7, Stride: 1},
-			{Lo: 0xa700, Hi: 0xa7bf, Stride: 1},
-			{Lo: 0xa7c2, Hi: 0xa7ca, Stride: 1},
-			{Lo: 0xa7f5, Hi: 0xa805, Stride: 1},
+			{Lo: 0xa700, Hi: 0xa7ca, Stride: 1},
+			{Lo: 0xa7d0, Hi: 0xa7d1, Stride: 1},
+			{Lo: 0xa7d3, Hi: 0xa7d5, Stride: 2},
+			{Lo: 0xa7d6, Hi: 0xa7d9, Stride: 1},
+			{Lo: 0xa7f2, Hi: 0xa805, Stride: 1},
 			{Lo: 0xa807, Hi: 0xa82b, Stride: 1},
 			{Lo: 0xa807, Hi: 0xa82b, Stride: 1},
 			{Lo: 0xa830, Hi: 0xa839, Stride: 1},
 			{Lo: 0xa830, Hi: 0xa839, Stride: 1},
 			{Lo: 0xa840, Hi: 0xa877, Stride: 1},
 			{Lo: 0xa840, Hi: 0xa877, Stride: 1},
@@ -395,12 +393,11 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0xfb3e, Hi: 0xfb40, Stride: 2},
 			{Lo: 0xfb3e, Hi: 0xfb40, Stride: 2},
 			{Lo: 0xfb41, Hi: 0xfb43, Stride: 2},
 			{Lo: 0xfb41, Hi: 0xfb43, Stride: 2},
 			{Lo: 0xfb44, Hi: 0xfb46, Stride: 2},
 			{Lo: 0xfb44, Hi: 0xfb46, Stride: 2},
-			{Lo: 0xfb47, Hi: 0xfbc1, Stride: 1},
-			{Lo: 0xfbd3, Hi: 0xfd3f, Stride: 1},
-			{Lo: 0xfd50, Hi: 0xfd8f, Stride: 1},
+			{Lo: 0xfb47, Hi: 0xfbc2, Stride: 1},
+			{Lo: 0xfbd3, Hi: 0xfd8f, Stride: 1},
 			{Lo: 0xfd92, Hi: 0xfdc7, Stride: 1},
 			{Lo: 0xfd92, Hi: 0xfdc7, Stride: 1},
-			{Lo: 0xfdf0, Hi: 0xfdfd, Stride: 1},
-			{Lo: 0xfe00, Hi: 0xfe19, Stride: 1},
+			{Lo: 0xfdcf, Hi: 0xfdf0, Stride: 33},
+			{Lo: 0xfdf1, Hi: 0xfe19, Stride: 1},
 			{Lo: 0xfe30, Hi: 0xfe52, Stride: 1},
 			{Lo: 0xfe30, Hi: 0xfe52, Stride: 1},
 			{Lo: 0xfe54, Hi: 0xfe66, Stride: 1},
 			{Lo: 0xfe54, Hi: 0xfe66, Stride: 1},
 			{Lo: 0xfe68, Hi: 0xfe6b, Stride: 1},
 			{Lo: 0xfe68, Hi: 0xfe6b, Stride: 1},
@@ -445,10 +442,20 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x104d8, Hi: 0x104fb, Stride: 1},
 			{Lo: 0x104d8, Hi: 0x104fb, Stride: 1},
 			{Lo: 0x10500, Hi: 0x10527, Stride: 1},
 			{Lo: 0x10500, Hi: 0x10527, Stride: 1},
 			{Lo: 0x10530, Hi: 0x10563, Stride: 1},
 			{Lo: 0x10530, Hi: 0x10563, Stride: 1},
-			{Lo: 0x1056f, Hi: 0x10600, Stride: 145},
-			{Lo: 0x10601, Hi: 0x10736, Stride: 1},
+			{Lo: 0x1056f, Hi: 0x1057a, Stride: 1},
+			{Lo: 0x1057c, Hi: 0x1058a, Stride: 1},
+			{Lo: 0x1058c, Hi: 0x10592, Stride: 1},
+			{Lo: 0x10594, Hi: 0x10595, Stride: 1},
+			{Lo: 0x10597, Hi: 0x105a1, Stride: 1},
+			{Lo: 0x105a3, Hi: 0x105b1, Stride: 1},
+			{Lo: 0x105b3, Hi: 0x105b9, Stride: 1},
+			{Lo: 0x105bb, Hi: 0x105bc, Stride: 1},
+			{Lo: 0x10600, Hi: 0x10736, Stride: 1},
 			{Lo: 0x10740, Hi: 0x10755, Stride: 1},
 			{Lo: 0x10740, Hi: 0x10755, Stride: 1},
 			{Lo: 0x10760, Hi: 0x10767, Stride: 1},
 			{Lo: 0x10760, Hi: 0x10767, Stride: 1},
+			{Lo: 0x10780, Hi: 0x10785, Stride: 1},
+			{Lo: 0x10787, Hi: 0x107b0, Stride: 1},
+			{Lo: 0x107b2, Hi: 0x107ba, Stride: 1},
 			{Lo: 0x10800, Hi: 0x10805, Stride: 1},
 			{Lo: 0x10800, Hi: 0x10805, Stride: 1},
 			{Lo: 0x10808, Hi: 0x1080a, Stride: 2},
 			{Lo: 0x10808, Hi: 0x1080a, Stride: 2},
 			{Lo: 0x1080b, Hi: 0x10835, Stride: 1},
 			{Lo: 0x1080b, Hi: 0x10835, Stride: 1},
@@ -493,13 +500,16 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x10f01, Hi: 0x10f27, Stride: 1},
 			{Lo: 0x10f01, Hi: 0x10f27, Stride: 1},
 			{Lo: 0x10f30, Hi: 0x10f45, Stride: 1},
 			{Lo: 0x10f30, Hi: 0x10f45, Stride: 1},
 			{Lo: 0x10f51, Hi: 0x10f59, Stride: 1},
 			{Lo: 0x10f51, Hi: 0x10f59, Stride: 1},
+			{Lo: 0x10f70, Hi: 0x10f81, Stride: 1},
+			{Lo: 0x10f86, Hi: 0x10f89, Stride: 1},
 			{Lo: 0x10fb0, Hi: 0x10fcb, Stride: 1},
 			{Lo: 0x10fb0, Hi: 0x10fcb, Stride: 1},
 			{Lo: 0x10fe0, Hi: 0x10ff6, Stride: 1},
 			{Lo: 0x10fe0, Hi: 0x10ff6, Stride: 1},
 			{Lo: 0x11000, Hi: 0x11045, Stride: 1},
 			{Lo: 0x11000, Hi: 0x11045, Stride: 1},
 			{Lo: 0x11047, Hi: 0x1104d, Stride: 1},
 			{Lo: 0x11047, Hi: 0x1104d, Stride: 1},
 			{Lo: 0x11052, Hi: 0x1106f, Stride: 1},
 			{Lo: 0x11052, Hi: 0x1106f, Stride: 1},
+			{Lo: 0x11071, Hi: 0x11075, Stride: 1},
 			{Lo: 0x11080, Hi: 0x110b8, Stride: 1},
 			{Lo: 0x11080, Hi: 0x110b8, Stride: 1},
-			{Lo: 0x110bb, Hi: 0x110c1, Stride: 1},
+			{Lo: 0x110bb, Hi: 0x110c2, Stride: 1},
 			{Lo: 0x110cd, Hi: 0x110d0, Stride: 3},
 			{Lo: 0x110cd, Hi: 0x110d0, Stride: 3},
 			{Lo: 0x110d1, Hi: 0x110e8, Stride: 1},
 			{Lo: 0x110d1, Hi: 0x110e8, Stride: 1},
 			{Lo: 0x110f0, Hi: 0x110f9, Stride: 1},
 			{Lo: 0x110f0, Hi: 0x110f9, Stride: 1},
@@ -513,7 +523,7 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x111e1, Hi: 0x111f4, Stride: 1},
 			{Lo: 0x111e1, Hi: 0x111f4, Stride: 1},
 			{Lo: 0x11200, Hi: 0x11211, Stride: 1},
 			{Lo: 0x11200, Hi: 0x11211, Stride: 1},
 			{Lo: 0x11213, Hi: 0x11234, Stride: 1},
 			{Lo: 0x11213, Hi: 0x11234, Stride: 1},
-			{Lo: 0x11237, Hi: 0x1123e, Stride: 1},
+			{Lo: 0x11237, Hi: 0x11241, Stride: 1},
 			{Lo: 0x11280, Hi: 0x11286, Stride: 1},
 			{Lo: 0x11280, Hi: 0x11286, Stride: 1},
 			{Lo: 0x11288, Hi: 0x1128a, Stride: 2},
 			{Lo: 0x11288, Hi: 0x1128a, Stride: 2},
 			{Lo: 0x1128b, Hi: 0x1128d, Stride: 1},
 			{Lo: 0x1128b, Hi: 0x1128d, Stride: 1},
@@ -549,11 +559,11 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x11650, Hi: 0x11659, Stride: 1},
 			{Lo: 0x11650, Hi: 0x11659, Stride: 1},
 			{Lo: 0x11660, Hi: 0x1166c, Stride: 1},
 			{Lo: 0x11660, Hi: 0x1166c, Stride: 1},
 			{Lo: 0x11680, Hi: 0x116b5, Stride: 1},
 			{Lo: 0x11680, Hi: 0x116b5, Stride: 1},
-			{Lo: 0x116b8, Hi: 0x116c0, Stride: 8},
-			{Lo: 0x116c1, Hi: 0x116c9, Stride: 1},
+			{Lo: 0x116b8, Hi: 0x116b9, Stride: 1},
+			{Lo: 0x116c0, Hi: 0x116c9, Stride: 1},
 			{Lo: 0x11700, Hi: 0x1171a, Stride: 1},
 			{Lo: 0x11700, Hi: 0x1171a, Stride: 1},
 			{Lo: 0x1171d, Hi: 0x1172a, Stride: 1},
 			{Lo: 0x1171d, Hi: 0x1172a, Stride: 1},
-			{Lo: 0x11730, Hi: 0x1173f, Stride: 1},
+			{Lo: 0x11730, Hi: 0x11746, Stride: 1},
 			{Lo: 0x11800, Hi: 0x11838, Stride: 1},
 			{Lo: 0x11800, Hi: 0x11838, Stride: 1},
 			{Lo: 0x1183b, Hi: 0x118a0, Stride: 101},
 			{Lo: 0x1183b, Hi: 0x118a0, Stride: 101},
 			{Lo: 0x118a1, Hi: 0x118f2, Stride: 1},
 			{Lo: 0x118a1, Hi: 0x118f2, Stride: 1},
@@ -575,7 +585,8 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x11a35, Hi: 0x11a46, Stride: 1},
 			{Lo: 0x11a35, Hi: 0x11a46, Stride: 1},
 			{Lo: 0x11a50, Hi: 0x11a98, Stride: 1},
 			{Lo: 0x11a50, Hi: 0x11a98, Stride: 1},
 			{Lo: 0x11a9a, Hi: 0x11aa2, Stride: 1},
 			{Lo: 0x11a9a, Hi: 0x11aa2, Stride: 1},
-			{Lo: 0x11ac0, Hi: 0x11af8, Stride: 1},
+			{Lo: 0x11ab0, Hi: 0x11af8, Stride: 1},
+			{Lo: 0x11b00, Hi: 0x11b09, Stride: 1},
 			{Lo: 0x11c00, Hi: 0x11c08, Stride: 1},
 			{Lo: 0x11c00, Hi: 0x11c08, Stride: 1},
 			{Lo: 0x11c0a, Hi: 0x11c36, Stride: 1},
 			{Lo: 0x11c0a, Hi: 0x11c36, Stride: 1},
 			{Lo: 0x11c38, Hi: 0x11c3e, Stride: 1},
 			{Lo: 0x11c38, Hi: 0x11c3e, Stride: 1},
@@ -601,19 +612,24 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x11d98, Hi: 0x11da0, Stride: 8},
 			{Lo: 0x11d98, Hi: 0x11da0, Stride: 8},
 			{Lo: 0x11da1, Hi: 0x11da9, Stride: 1},
 			{Lo: 0x11da1, Hi: 0x11da9, Stride: 1},
 			{Lo: 0x11ee0, Hi: 0x11ef8, Stride: 1},
 			{Lo: 0x11ee0, Hi: 0x11ef8, Stride: 1},
+			{Lo: 0x11f00, Hi: 0x11f10, Stride: 1},
+			{Lo: 0x11f12, Hi: 0x11f3a, Stride: 1},
+			{Lo: 0x11f3e, Hi: 0x11f40, Stride: 1},
+			{Lo: 0x11f43, Hi: 0x11f59, Stride: 1},
 			{Lo: 0x11fb0, Hi: 0x11fc0, Stride: 16},
 			{Lo: 0x11fb0, Hi: 0x11fc0, Stride: 16},
 			{Lo: 0x11fc1, Hi: 0x11ff1, Stride: 1},
 			{Lo: 0x11fc1, Hi: 0x11ff1, Stride: 1},
 			{Lo: 0x11fff, Hi: 0x12399, Stride: 1},
 			{Lo: 0x11fff, Hi: 0x12399, Stride: 1},
 			{Lo: 0x12400, Hi: 0x1246e, Stride: 1},
 			{Lo: 0x12400, Hi: 0x1246e, Stride: 1},
 			{Lo: 0x12470, Hi: 0x12474, Stride: 1},
 			{Lo: 0x12470, Hi: 0x12474, Stride: 1},
 			{Lo: 0x12480, Hi: 0x12543, Stride: 1},
 			{Lo: 0x12480, Hi: 0x12543, Stride: 1},
-			{Lo: 0x13000, Hi: 0x1342e, Stride: 1},
-			{Lo: 0x13430, Hi: 0x13438, Stride: 1},
+			{Lo: 0x12f90, Hi: 0x12ff2, Stride: 1},
+			{Lo: 0x13000, Hi: 0x13455, Stride: 1},
 			{Lo: 0x14400, Hi: 0x14646, Stride: 1},
 			{Lo: 0x14400, Hi: 0x14646, Stride: 1},
 			{Lo: 0x16800, Hi: 0x16a38, Stride: 1},
 			{Lo: 0x16800, Hi: 0x16a38, Stride: 1},
 			{Lo: 0x16a40, Hi: 0x16a5e, Stride: 1},
 			{Lo: 0x16a40, Hi: 0x16a5e, Stride: 1},
 			{Lo: 0x16a60, Hi: 0x16a69, Stride: 1},
 			{Lo: 0x16a60, Hi: 0x16a69, Stride: 1},
-			{Lo: 0x16a6e, Hi: 0x16a6f, Stride: 1},
+			{Lo: 0x16a6e, Hi: 0x16abe, Stride: 1},
+			{Lo: 0x16ac0, Hi: 0x16ac9, Stride: 1},
 			{Lo: 0x16ad0, Hi: 0x16aed, Stride: 1},
 			{Lo: 0x16ad0, Hi: 0x16aed, Stride: 1},
 			{Lo: 0x16af5, Hi: 0x16b00, Stride: 11},
 			{Lo: 0x16af5, Hi: 0x16b00, Stride: 11},
 			{Lo: 0x16b01, Hi: 0x16b2f, Stride: 1},
 			{Lo: 0x16b01, Hi: 0x16b2f, Stride: 1},
@@ -630,9 +646,14 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x17000, Hi: 0x187f7, Stride: 6135},
 			{Lo: 0x17000, Hi: 0x187f7, Stride: 6135},
 			{Lo: 0x18800, Hi: 0x18cd5, Stride: 1},
 			{Lo: 0x18800, Hi: 0x18cd5, Stride: 1},
 			{Lo: 0x18d00, Hi: 0x18d08, Stride: 8},
 			{Lo: 0x18d00, Hi: 0x18d08, Stride: 8},
-			{Lo: 0x1b000, Hi: 0x1b11e, Stride: 1},
-			{Lo: 0x1b150, Hi: 0x1b152, Stride: 1},
-			{Lo: 0x1b164, Hi: 0x1b167, Stride: 1},
+			{Lo: 0x1aff0, Hi: 0x1aff3, Stride: 1},
+			{Lo: 0x1aff5, Hi: 0x1affb, Stride: 1},
+			{Lo: 0x1affd, Hi: 0x1affe, Stride: 1},
+			{Lo: 0x1b000, Hi: 0x1b122, Stride: 1},
+			{Lo: 0x1b132, Hi: 0x1b150, Stride: 30},
+			{Lo: 0x1b151, Hi: 0x1b152, Stride: 1},
+			{Lo: 0x1b155, Hi: 0x1b164, Stride: 15},
+			{Lo: 0x1b165, Hi: 0x1b167, Stride: 1},
 			{Lo: 0x1b170, Hi: 0x1b2fb, Stride: 1},
 			{Lo: 0x1b170, Hi: 0x1b2fb, Stride: 1},
 			{Lo: 0x1bc00, Hi: 0x1bc6a, Stride: 1},
 			{Lo: 0x1bc00, Hi: 0x1bc6a, Stride: 1},
 			{Lo: 0x1bc70, Hi: 0x1bc7c, Stride: 1},
 			{Lo: 0x1bc70, Hi: 0x1bc7c, Stride: 1},
@@ -640,6 +661,9 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x1bc90, Hi: 0x1bc99, Stride: 1},
 			{Lo: 0x1bc90, Hi: 0x1bc99, Stride: 1},
 			{Lo: 0x1bc9c, Hi: 0x1bc9d, Stride: 1},
 			{Lo: 0x1bc9c, Hi: 0x1bc9d, Stride: 1},
 			{Lo: 0x1bc9f, Hi: 0x1bca3, Stride: 1},
 			{Lo: 0x1bc9f, Hi: 0x1bca3, Stride: 1},
+			{Lo: 0x1cf00, Hi: 0x1cf2d, Stride: 1},
+			{Lo: 0x1cf30, Hi: 0x1cf46, Stride: 1},
+			{Lo: 0x1cf50, Hi: 0x1cfc3, Stride: 1},
 			{Lo: 0x1d000, Hi: 0x1d0f5, Stride: 1},
 			{Lo: 0x1d000, Hi: 0x1d0f5, Stride: 1},
 			{Lo: 0x1d100, Hi: 0x1d126, Stride: 1},
 			{Lo: 0x1d100, Hi: 0x1d126, Stride: 1},
 			{Lo: 0x1d129, Hi: 0x1d164, Stride: 1},
 			{Lo: 0x1d129, Hi: 0x1d164, Stride: 1},
@@ -647,10 +671,11 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x1d173, Hi: 0x1d17a, Stride: 1},
 			{Lo: 0x1d173, Hi: 0x1d17a, Stride: 1},
 			{Lo: 0x1d183, Hi: 0x1d184, Stride: 1},
 			{Lo: 0x1d183, Hi: 0x1d184, Stride: 1},
 			{Lo: 0x1d18c, Hi: 0x1d1a9, Stride: 1},
 			{Lo: 0x1d18c, Hi: 0x1d1a9, Stride: 1},
-			{Lo: 0x1d1ae, Hi: 0x1d1e8, Stride: 1},
+			{Lo: 0x1d1ae, Hi: 0x1d1ea, Stride: 1},
 			{Lo: 0x1d200, Hi: 0x1d241, Stride: 1},
 			{Lo: 0x1d200, Hi: 0x1d241, Stride: 1},
-			{Lo: 0x1d245, Hi: 0x1d2e0, Stride: 155},
-			{Lo: 0x1d2e1, Hi: 0x1d2f3, Stride: 1},
+			{Lo: 0x1d245, Hi: 0x1d2c0, Stride: 123},
+			{Lo: 0x1d2c1, Hi: 0x1d2d3, Stride: 1},
+			{Lo: 0x1d2e0, Hi: 0x1d2f3, Stride: 1},
 			{Lo: 0x1d300, Hi: 0x1d356, Stride: 1},
 			{Lo: 0x1d300, Hi: 0x1d356, Stride: 1},
 			{Lo: 0x1d360, Hi: 0x1d378, Stride: 1},
 			{Lo: 0x1d360, Hi: 0x1d378, Stride: 1},
 			{Lo: 0x1d400, Hi: 0x1d454, Stride: 1},
 			{Lo: 0x1d400, Hi: 0x1d454, Stride: 1},
@@ -676,14 +701,24 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x1d7ce, Hi: 0x1da8b, Stride: 1},
 			{Lo: 0x1d7ce, Hi: 0x1da8b, Stride: 1},
 			{Lo: 0x1da9b, Hi: 0x1da9f, Stride: 1},
 			{Lo: 0x1da9b, Hi: 0x1da9f, Stride: 1},
 			{Lo: 0x1daa1, Hi: 0x1daaf, Stride: 1},
 			{Lo: 0x1daa1, Hi: 0x1daaf, Stride: 1},
+			{Lo: 0x1df00, Hi: 0x1df1e, Stride: 1},
+			{Lo: 0x1df25, Hi: 0x1df2a, Stride: 1},
+			{Lo: 0x1e030, Hi: 0x1e06d, Stride: 1},
 			{Lo: 0x1e100, Hi: 0x1e12c, Stride: 1},
 			{Lo: 0x1e100, Hi: 0x1e12c, Stride: 1},
 			{Lo: 0x1e137, Hi: 0x1e13d, Stride: 1},
 			{Lo: 0x1e137, Hi: 0x1e13d, Stride: 1},
 			{Lo: 0x1e140, Hi: 0x1e149, Stride: 1},
 			{Lo: 0x1e140, Hi: 0x1e149, Stride: 1},
 			{Lo: 0x1e14e, Hi: 0x1e14f, Stride: 1},
 			{Lo: 0x1e14e, Hi: 0x1e14f, Stride: 1},
+			{Lo: 0x1e290, Hi: 0x1e2ad, Stride: 1},
 			{Lo: 0x1e2c0, Hi: 0x1e2eb, Stride: 1},
 			{Lo: 0x1e2c0, Hi: 0x1e2eb, Stride: 1},
 			{Lo: 0x1e2f0, Hi: 0x1e2f9, Stride: 1},
 			{Lo: 0x1e2f0, Hi: 0x1e2f9, Stride: 1},
-			{Lo: 0x1e2ff, Hi: 0x1e800, Stride: 1281},
-			{Lo: 0x1e801, Hi: 0x1e8c4, Stride: 1},
+			{Lo: 0x1e2ff, Hi: 0x1e4d0, Stride: 465},
+			{Lo: 0x1e4d1, Hi: 0x1e4eb, Stride: 1},
+			{Lo: 0x1e4f0, Hi: 0x1e4f9, Stride: 1},
+			{Lo: 0x1e7e0, Hi: 0x1e7e6, Stride: 1},
+			{Lo: 0x1e7e8, Hi: 0x1e7eb, Stride: 1},
+			{Lo: 0x1e7ed, Hi: 0x1e7ee, Stride: 1},
+			{Lo: 0x1e7f0, Hi: 0x1e7fe, Stride: 1},
+			{Lo: 0x1e800, Hi: 0x1e8c4, Stride: 1},
 			{Lo: 0x1e8c7, Hi: 0x1e8cf, Stride: 1},
 			{Lo: 0x1e8c7, Hi: 0x1e8cf, Stride: 1},
 			{Lo: 0x1e900, Hi: 0x1e943, Stride: 1},
 			{Lo: 0x1e900, Hi: 0x1e943, Stride: 1},
 			{Lo: 0x1e94b, Hi: 0x1e950, Stride: 5},
 			{Lo: 0x1e94b, Hi: 0x1e950, Stride: 5},
@@ -729,38 +764,38 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x1f250, Hi: 0x1f251, Stride: 1},
 			{Lo: 0x1f250, Hi: 0x1f251, Stride: 1},
 			{Lo: 0x1f260, Hi: 0x1f265, Stride: 1},
 			{Lo: 0x1f260, Hi: 0x1f265, Stride: 1},
 			{Lo: 0x1f300, Hi: 0x1f6d7, Stride: 1},
 			{Lo: 0x1f300, Hi: 0x1f6d7, Stride: 1},
-			{Lo: 0x1f6e0, Hi: 0x1f6ec, Stride: 1},
+			{Lo: 0x1f6dc, Hi: 0x1f6ec, Stride: 1},
 			{Lo: 0x1f6f0, Hi: 0x1f6fc, Stride: 1},
 			{Lo: 0x1f6f0, Hi: 0x1f6fc, Stride: 1},
-			{Lo: 0x1f700, Hi: 0x1f773, Stride: 1},
-			{Lo: 0x1f780, Hi: 0x1f7d8, Stride: 1},
+			{Lo: 0x1f700, Hi: 0x1f776, Stride: 1},
+			{Lo: 0x1f77b, Hi: 0x1f7d9, Stride: 1},
 			{Lo: 0x1f7e0, Hi: 0x1f7eb, Stride: 1},
 			{Lo: 0x1f7e0, Hi: 0x1f7eb, Stride: 1},
-			{Lo: 0x1f800, Hi: 0x1f80b, Stride: 1},
+			{Lo: 0x1f7f0, Hi: 0x1f800, Stride: 16},
+			{Lo: 0x1f801, Hi: 0x1f80b, Stride: 1},
 			{Lo: 0x1f810, Hi: 0x1f847, Stride: 1},
 			{Lo: 0x1f810, Hi: 0x1f847, Stride: 1},
 			{Lo: 0x1f850, Hi: 0x1f859, Stride: 1},
 			{Lo: 0x1f850, Hi: 0x1f859, Stride: 1},
 			{Lo: 0x1f860, Hi: 0x1f887, Stride: 1},
 			{Lo: 0x1f860, Hi: 0x1f887, Stride: 1},
 			{Lo: 0x1f890, Hi: 0x1f8ad, Stride: 1},
 			{Lo: 0x1f890, Hi: 0x1f8ad, Stride: 1},
 			{Lo: 0x1f8b0, Hi: 0x1f8b1, Stride: 1},
 			{Lo: 0x1f8b0, Hi: 0x1f8b1, Stride: 1},
-			{Lo: 0x1f900, Hi: 0x1f978, Stride: 1},
-			{Lo: 0x1f97a, Hi: 0x1f9cb, Stride: 1},
-			{Lo: 0x1f9cd, Hi: 0x1fa53, Stride: 1},
+			{Lo: 0x1f900, Hi: 0x1fa53, Stride: 1},
 			{Lo: 0x1fa60, Hi: 0x1fa6d, Stride: 1},
 			{Lo: 0x1fa60, Hi: 0x1fa6d, Stride: 1},
-			{Lo: 0x1fa70, Hi: 0x1fa74, Stride: 1},
-			{Lo: 0x1fa78, Hi: 0x1fa7a, Stride: 1},
-			{Lo: 0x1fa80, Hi: 0x1fa86, Stride: 1},
-			{Lo: 0x1fa90, Hi: 0x1faa8, Stride: 1},
-			{Lo: 0x1fab0, Hi: 0x1fab6, Stride: 1},
-			{Lo: 0x1fac0, Hi: 0x1fac2, Stride: 1},
-			{Lo: 0x1fad0, Hi: 0x1fad6, Stride: 1},
+			{Lo: 0x1fa70, Hi: 0x1fa7c, Stride: 1},
+			{Lo: 0x1fa80, Hi: 0x1fa88, Stride: 1},
+			{Lo: 0x1fa90, Hi: 0x1fabd, Stride: 1},
+			{Lo: 0x1fabf, Hi: 0x1fac5, Stride: 1},
+			{Lo: 0x1face, Hi: 0x1fadb, Stride: 1},
+			{Lo: 0x1fae0, Hi: 0x1fae8, Stride: 1},
+			{Lo: 0x1faf0, Hi: 0x1faf8, Stride: 1},
 			{Lo: 0x1fb00, Hi: 0x1fb92, Stride: 1},
 			{Lo: 0x1fb00, Hi: 0x1fb92, Stride: 1},
 			{Lo: 0x1fb94, Hi: 0x1fbca, Stride: 1},
 			{Lo: 0x1fb94, Hi: 0x1fbca, Stride: 1},
 			{Lo: 0x1fbf0, Hi: 0x1fbf9, Stride: 1},
 			{Lo: 0x1fbf0, Hi: 0x1fbf9, Stride: 1},
-			{Lo: 0x20000, Hi: 0x2a6dd, Stride: 42717},
-			{Lo: 0x2a700, Hi: 0x2b734, Stride: 4148},
+			{Lo: 0x20000, Hi: 0x2a6df, Stride: 42719},
+			{Lo: 0x2a700, Hi: 0x2b739, Stride: 4153},
 			{Lo: 0x2b740, Hi: 0x2b81d, Stride: 221},
 			{Lo: 0x2b740, Hi: 0x2b81d, Stride: 221},
 			{Lo: 0x2b820, Hi: 0x2cea1, Stride: 5761},
 			{Lo: 0x2b820, Hi: 0x2cea1, Stride: 5761},
 			{Lo: 0x2ceb0, Hi: 0x2ebe0, Stride: 7472},
 			{Lo: 0x2ceb0, Hi: 0x2ebe0, Stride: 7472},
 			{Lo: 0x2f800, Hi: 0x2fa1d, Stride: 1},
 			{Lo: 0x2f800, Hi: 0x2fa1d, Stride: 1},
 			{Lo: 0x30000, Hi: 0x3134a, Stride: 4938},
 			{Lo: 0x30000, Hi: 0x3134a, Stride: 4938},
+			{Lo: 0x31350, Hi: 0x323af, Stride: 4191},
 			{Lo: 0xe0001, Hi: 0xe0020, Stride: 31},
 			{Lo: 0xe0001, Hi: 0xe0020, Stride: 31},
 			{Lo: 0xe0021, Hi: 0xe007f, Stride: 1},
 			{Lo: 0xe0021, Hi: 0xe007f, Stride: 1},
 			{Lo: 0xe0100, Hi: 0xe01ef, Stride: 1},
 			{Lo: 0xe0100, Hi: 0xe01ef, Stride: 1},
@@ -793,9 +828,10 @@ var combiningClasses = [256]*unicode.RangeTable{
 	7: {
 	7: {
 		R16: []unicode.Range16{
 		R16: []unicode.Range16{
 			{Lo: 0x093c, Hi: 0x0b3c, Stride: 128},
 			{Lo: 0x093c, Hi: 0x0b3c, Stride: 128},
-			{Lo: 0x0cbc, Hi: 0x1037, Stride: 891},
-			{Lo: 0x1b34, Hi: 0x1be6, Stride: 178},
-			{Lo: 0x1c37, Hi: 0xa9b3, Stride: 36220},
+			{Lo: 0x0c3c, Hi: 0x0cbc, Stride: 128},
+			{Lo: 0x1037, Hi: 0x1b34, Stride: 2813},
+			{Lo: 0x1be6, Hi: 0x1c37, Stride: 81},
+			{Lo: 0xa9b3, Hi: 0xa9b3, Stride: 1},
 		},
 		},
 		R32: []unicode.Range32{
 		R32: []unicode.Range32{
 			{Lo: 0x110ba, Hi: 0x11173, Stride: 185},
 			{Lo: 0x110ba, Hi: 0x11173, Stride: 185},
@@ -821,30 +857,32 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x0e3a, Hi: 0x0eba, Stride: 128},
 			{Lo: 0x0e3a, Hi: 0x0eba, Stride: 128},
 			{Lo: 0x0f84, Hi: 0x1039, Stride: 181},
 			{Lo: 0x0f84, Hi: 0x1039, Stride: 181},
 			{Lo: 0x103a, Hi: 0x1714, Stride: 1754},
 			{Lo: 0x103a, Hi: 0x1714, Stride: 1754},
-			{Lo: 0x1734, Hi: 0x17d2, Stride: 158},
-			{Lo: 0x1a60, Hi: 0x1b44, Stride: 228},
-			{Lo: 0x1baa, Hi: 0x1bab, Stride: 1},
-			{Lo: 0x1bf2, Hi: 0x1bf3, Stride: 1},
-			{Lo: 0x2d7f, Hi: 0xa806, Stride: 31367},
-			{Lo: 0xa82c, Hi: 0xa8c4, Stride: 152},
-			{Lo: 0xa953, Hi: 0xa9c0, Stride: 109},
-			{Lo: 0xaaf6, Hi: 0xabed, Stride: 247},
+			{Lo: 0x1715, Hi: 0x1734, Stride: 31},
+			{Lo: 0x17d2, Hi: 0x1a60, Stride: 654},
+			{Lo: 0x1b44, Hi: 0x1baa, Stride: 102},
+			{Lo: 0x1bab, Hi: 0x1bf2, Stride: 71},
+			{Lo: 0x1bf3, Hi: 0x2d7f, Stride: 4492},
+			{Lo: 0xa806, Hi: 0xa82c, Stride: 38},
+			{Lo: 0xa8c4, Hi: 0xa953, Stride: 143},
+			{Lo: 0xa9c0, Hi: 0xaaf6, Stride: 310},
+			{Lo: 0xabed, Hi: 0xabed, Stride: 1},
 		},
 		},
 		R32: []unicode.Range32{
 		R32: []unicode.Range32{
 			{Lo: 0x10a3f, Hi: 0x11046, Stride: 1543},
 			{Lo: 0x10a3f, Hi: 0x11046, Stride: 1543},
-			{Lo: 0x1107f, Hi: 0x110b9, Stride: 58},
-			{Lo: 0x11133, Hi: 0x11134, Stride: 1},
-			{Lo: 0x111c0, Hi: 0x11235, Stride: 117},
-			{Lo: 0x112ea, Hi: 0x1134d, Stride: 99},
-			{Lo: 0x11442, Hi: 0x114c2, Stride: 128},
-			{Lo: 0x115bf, Hi: 0x1163f, Stride: 128},
-			{Lo: 0x116b6, Hi: 0x1172b, Stride: 117},
-			{Lo: 0x11839, Hi: 0x1193d, Stride: 260},
-			{Lo: 0x1193e, Hi: 0x119e0, Stride: 162},
-			{Lo: 0x11a34, Hi: 0x11a47, Stride: 19},
-			{Lo: 0x11a99, Hi: 0x11c3f, Stride: 422},
-			{Lo: 0x11d44, Hi: 0x11d45, Stride: 1},
-			{Lo: 0x11d97, Hi: 0x11d97, Stride: 1},
+			{Lo: 0x11070, Hi: 0x1107f, Stride: 15},
+			{Lo: 0x110b9, Hi: 0x11133, Stride: 122},
+			{Lo: 0x11134, Hi: 0x111c0, Stride: 140},
+			{Lo: 0x11235, Hi: 0x112ea, Stride: 181},
+			{Lo: 0x1134d, Hi: 0x11442, Stride: 245},
+			{Lo: 0x114c2, Hi: 0x115bf, Stride: 253},
+			{Lo: 0x1163f, Hi: 0x116b6, Stride: 119},
+			{Lo: 0x1172b, Hi: 0x11839, Stride: 270},
+			{Lo: 0x1193d, Hi: 0x1193e, Stride: 1},
+			{Lo: 0x119e0, Hi: 0x11a34, Stride: 84},
+			{Lo: 0x11a47, Hi: 0x11a99, Stride: 82},
+			{Lo: 0x11c3f, Hi: 0x11d44, Stride: 261},
+			{Lo: 0x11d45, Hi: 0x11d97, Stride: 82},
+			{Lo: 0x11f41, Hi: 0x11f42, Stride: 1},
 		},
 		},
 	},
 	},
 	10: {
 	10: {
@@ -1052,7 +1090,7 @@ var combiningClasses = [256]*unicode.RangeTable{
 	},
 	},
 	218: {
 	218: {
 		R16: []unicode.Range16{
 		R16: []unicode.Range16{
-			{Lo: 0x302a, Hi: 0x302a, Stride: 1},
+			{Lo: 0x1dfa, Hi: 0x302a, Stride: 4656},
 		},
 		},
 	},
 	},
 	220: {
 	220: {
@@ -1080,8 +1118,9 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x0744, Hi: 0x0748, Stride: 2},
 			{Lo: 0x0744, Hi: 0x0748, Stride: 2},
 			{Lo: 0x07f2, Hi: 0x07fd, Stride: 11},
 			{Lo: 0x07f2, Hi: 0x07fd, Stride: 11},
 			{Lo: 0x0859, Hi: 0x085b, Stride: 1},
 			{Lo: 0x0859, Hi: 0x085b, Stride: 1},
-			{Lo: 0x08d3, Hi: 0x08e3, Stride: 16},
-			{Lo: 0x08e6, Hi: 0x08e9, Stride: 3},
+			{Lo: 0x0899, Hi: 0x089b, Stride: 1},
+			{Lo: 0x08cf, Hi: 0x08d3, Stride: 1},
+			{Lo: 0x08e3, Hi: 0x08e9, Stride: 3},
 			{Lo: 0x08ed, Hi: 0x08ef, Stride: 1},
 			{Lo: 0x08ed, Hi: 0x08ef, Stride: 1},
 			{Lo: 0x08f6, Hi: 0x08f9, Stride: 3},
 			{Lo: 0x08f6, Hi: 0x08f9, Stride: 3},
 			{Lo: 0x08fa, Hi: 0x0952, Stride: 88},
 			{Lo: 0x08fa, Hi: 0x0952, Stride: 88},
@@ -1092,8 +1131,10 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x1a7f, Hi: 0x1ab5, Stride: 54},
 			{Lo: 0x1a7f, Hi: 0x1ab5, Stride: 54},
 			{Lo: 0x1ab6, Hi: 0x1aba, Stride: 1},
 			{Lo: 0x1ab6, Hi: 0x1aba, Stride: 1},
 			{Lo: 0x1abd, Hi: 0x1abf, Stride: 2},
 			{Lo: 0x1abd, Hi: 0x1abf, Stride: 2},
-			{Lo: 0x1ac0, Hi: 0x1b6c, Stride: 172},
-			{Lo: 0x1cd5, Hi: 0x1cd9, Stride: 1},
+			{Lo: 0x1ac0, Hi: 0x1ac3, Stride: 3},
+			{Lo: 0x1ac4, Hi: 0x1aca, Stride: 6},
+			{Lo: 0x1b6c, Hi: 0x1cd5, Stride: 361},
+			{Lo: 0x1cd6, Hi: 0x1cd9, Stride: 1},
 			{Lo: 0x1cdc, Hi: 0x1cdf, Stride: 1},
 			{Lo: 0x1cdc, Hi: 0x1cdf, Stride: 1},
 			{Lo: 0x1ced, Hi: 0x1dc2, Stride: 213},
 			{Lo: 0x1ced, Hi: 0x1dc2, Stride: 213},
 			{Lo: 0x1dca, Hi: 0x1dcf, Stride: 5},
 			{Lo: 0x1dca, Hi: 0x1dcf, Stride: 5},
@@ -1107,12 +1148,16 @@ var combiningClasses = [256]*unicode.RangeTable{
 		R32: []unicode.Range32{
 		R32: []unicode.Range32{
 			{Lo: 0x101fd, Hi: 0x102e0, Stride: 227},
 			{Lo: 0x101fd, Hi: 0x102e0, Stride: 227},
 			{Lo: 0x10a0d, Hi: 0x10a3a, Stride: 45},
 			{Lo: 0x10a0d, Hi: 0x10a3a, Stride: 45},
-			{Lo: 0x10ae6, Hi: 0x10f46, Stride: 1120},
-			{Lo: 0x10f47, Hi: 0x10f4b, Stride: 4},
-			{Lo: 0x10f4d, Hi: 0x10f50, Stride: 1},
+			{Lo: 0x10ae6, Hi: 0x10efd, Stride: 1047},
+			{Lo: 0x10efe, Hi: 0x10eff, Stride: 1},
+			{Lo: 0x10f46, Hi: 0x10f47, Stride: 1},
+			{Lo: 0x10f4b, Hi: 0x10f4d, Stride: 2},
+			{Lo: 0x10f4e, Hi: 0x10f50, Stride: 1},
+			{Lo: 0x10f83, Hi: 0x10f85, Stride: 2},
 			{Lo: 0x1d17b, Hi: 0x1d182, Stride: 1},
 			{Lo: 0x1d17b, Hi: 0x1d182, Stride: 1},
 			{Lo: 0x1d18a, Hi: 0x1d18b, Stride: 1},
 			{Lo: 0x1d18a, Hi: 0x1d18b, Stride: 1},
-			{Lo: 0x1e8d0, Hi: 0x1e8d6, Stride: 1},
+			{Lo: 0x1e4ee, Hi: 0x1e8d0, Stride: 994},
+			{Lo: 0x1e8d1, Hi: 0x1e8d6, Stride: 1},
 		},
 		},
 	},
 	},
 	222: {
 	222: {
@@ -1175,6 +1220,9 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x081b, Hi: 0x0823, Stride: 1},
 			{Lo: 0x081b, Hi: 0x0823, Stride: 1},
 			{Lo: 0x0825, Hi: 0x0827, Stride: 1},
 			{Lo: 0x0825, Hi: 0x0827, Stride: 1},
 			{Lo: 0x0829, Hi: 0x082d, Stride: 1},
 			{Lo: 0x0829, Hi: 0x082d, Stride: 1},
+			{Lo: 0x0898, Hi: 0x089c, Stride: 4},
+			{Lo: 0x089d, Hi: 0x089f, Stride: 1},
+			{Lo: 0x08ca, Hi: 0x08ce, Stride: 1},
 			{Lo: 0x08d4, Hi: 0x08e1, Stride: 1},
 			{Lo: 0x08d4, Hi: 0x08e1, Stride: 1},
 			{Lo: 0x08e4, Hi: 0x08e5, Stride: 1},
 			{Lo: 0x08e4, Hi: 0x08e5, Stride: 1},
 			{Lo: 0x08e7, Hi: 0x08e8, Stride: 1},
 			{Lo: 0x08e7, Hi: 0x08e8, Stride: 1},
@@ -1192,6 +1240,9 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x1a76, Hi: 0x1a7c, Stride: 1},
 			{Lo: 0x1a76, Hi: 0x1a7c, Stride: 1},
 			{Lo: 0x1ab0, Hi: 0x1ab4, Stride: 1},
 			{Lo: 0x1ab0, Hi: 0x1ab4, Stride: 1},
 			{Lo: 0x1abb, Hi: 0x1abc, Stride: 1},
 			{Lo: 0x1abb, Hi: 0x1abc, Stride: 1},
+			{Lo: 0x1ac1, Hi: 0x1ac2, Stride: 1},
+			{Lo: 0x1ac5, Hi: 0x1ac9, Stride: 1},
+			{Lo: 0x1acb, Hi: 0x1ace, Stride: 1},
 			{Lo: 0x1b6b, Hi: 0x1b6d, Stride: 2},
 			{Lo: 0x1b6b, Hi: 0x1b6d, Stride: 2},
 			{Lo: 0x1b6e, Hi: 0x1b73, Stride: 1},
 			{Lo: 0x1b6e, Hi: 0x1b73, Stride: 1},
 			{Lo: 0x1cd0, Hi: 0x1cd2, Stride: 1},
 			{Lo: 0x1cd0, Hi: 0x1cd2, Stride: 1},
@@ -1229,7 +1280,8 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x10d25, Hi: 0x10d27, Stride: 1},
 			{Lo: 0x10d25, Hi: 0x10d27, Stride: 1},
 			{Lo: 0x10eab, Hi: 0x10eac, Stride: 1},
 			{Lo: 0x10eab, Hi: 0x10eac, Stride: 1},
 			{Lo: 0x10f48, Hi: 0x10f4a, Stride: 1},
 			{Lo: 0x10f48, Hi: 0x10f4a, Stride: 1},
-			{Lo: 0x10f4c, Hi: 0x11100, Stride: 436},
+			{Lo: 0x10f4c, Hi: 0x10f82, Stride: 54},
+			{Lo: 0x10f84, Hi: 0x11100, Stride: 380},
 			{Lo: 0x11101, Hi: 0x11102, Stride: 1},
 			{Lo: 0x11101, Hi: 0x11102, Stride: 1},
 			{Lo: 0x11366, Hi: 0x1136c, Stride: 1},
 			{Lo: 0x11366, Hi: 0x1136c, Stride: 1},
 			{Lo: 0x11370, Hi: 0x11374, Stride: 1},
 			{Lo: 0x11370, Hi: 0x11374, Stride: 1},
@@ -1243,9 +1295,12 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x1e01b, Hi: 0x1e021, Stride: 1},
 			{Lo: 0x1e01b, Hi: 0x1e021, Stride: 1},
 			{Lo: 0x1e023, Hi: 0x1e024, Stride: 1},
 			{Lo: 0x1e023, Hi: 0x1e024, Stride: 1},
 			{Lo: 0x1e026, Hi: 0x1e02a, Stride: 1},
 			{Lo: 0x1e026, Hi: 0x1e02a, Stride: 1},
-			{Lo: 0x1e130, Hi: 0x1e136, Stride: 1},
-			{Lo: 0x1e2ec, Hi: 0x1e2ef, Stride: 1},
-			{Lo: 0x1e944, Hi: 0x1e949, Stride: 1},
+			{Lo: 0x1e08f, Hi: 0x1e130, Stride: 161},
+			{Lo: 0x1e131, Hi: 0x1e136, Stride: 1},
+			{Lo: 0x1e2ae, Hi: 0x1e2ec, Stride: 62},
+			{Lo: 0x1e2ed, Hi: 0x1e2ef, Stride: 1},
+			{Lo: 0x1e4ef, Hi: 0x1e944, Stride: 1109},
+			{Lo: 0x1e945, Hi: 0x1e949, Stride: 1},
 		},
 		},
 	},
 	},
 	232: {
 	232: {
@@ -1254,6 +1309,9 @@ var combiningClasses = [256]*unicode.RangeTable{
 			{Lo: 0x0358, Hi: 0x1df6, Stride: 6814},
 			{Lo: 0x0358, Hi: 0x1df6, Stride: 6814},
 			{Lo: 0x302c, Hi: 0x302c, Stride: 1},
 			{Lo: 0x302c, Hi: 0x302c, Stride: 1},
 		},
 		},
+		R32: []unicode.Range32{
+			{Lo: 0x1e4ec, Hi: 0x1e4ed, Stride: 1},
+		},
 	},
 	},
 	233: {
 	233: {
 		R16: []unicode.Range16{
 		R16: []unicode.Range16{

+ 19 - 14
vendor/github.com/go-text/typesetting/unicodedata/east_asian_width.go

@@ -73,9 +73,14 @@ var LargeEastAsian = &unicode.RangeTable{
 		{Lo: 0x17000, Hi: 0x187f7, Stride: 1},
 		{Lo: 0x17000, Hi: 0x187f7, Stride: 1},
 		{Lo: 0x18800, Hi: 0x18cd5, Stride: 1},
 		{Lo: 0x18800, Hi: 0x18cd5, Stride: 1},
 		{Lo: 0x18d00, Hi: 0x18d08, Stride: 1},
 		{Lo: 0x18d00, Hi: 0x18d08, Stride: 1},
-		{Lo: 0x1b000, Hi: 0x1b11e, Stride: 1},
-		{Lo: 0x1b150, Hi: 0x1b152, Stride: 1},
-		{Lo: 0x1b164, Hi: 0x1b167, Stride: 1},
+		{Lo: 0x1aff0, Hi: 0x1aff3, Stride: 1},
+		{Lo: 0x1aff5, Hi: 0x1affb, Stride: 1},
+		{Lo: 0x1affd, Hi: 0x1affe, Stride: 1},
+		{Lo: 0x1b000, Hi: 0x1b122, Stride: 1},
+		{Lo: 0x1b132, Hi: 0x1b150, Stride: 30},
+		{Lo: 0x1b151, Hi: 0x1b152, Stride: 1},
+		{Lo: 0x1b155, Hi: 0x1b164, Stride: 15},
+		{Lo: 0x1b165, Hi: 0x1b167, Stride: 1},
 		{Lo: 0x1b170, Hi: 0x1b2fb, Stride: 1},
 		{Lo: 0x1b170, Hi: 0x1b2fb, Stride: 1},
 		{Lo: 0x1f004, Hi: 0x1f0cf, Stride: 203},
 		{Lo: 0x1f004, Hi: 0x1f0cf, Stride: 203},
 		{Lo: 0x1f18e, Hi: 0x1f191, Stride: 3},
 		{Lo: 0x1f18e, Hi: 0x1f191, Stride: 3},
@@ -106,21 +111,21 @@ var LargeEastAsian = &unicode.RangeTable{
 		{Lo: 0x1f6cc, Hi: 0x1f6d0, Stride: 4},
 		{Lo: 0x1f6cc, Hi: 0x1f6d0, Stride: 4},
 		{Lo: 0x1f6d1, Hi: 0x1f6d2, Stride: 1},
 		{Lo: 0x1f6d1, Hi: 0x1f6d2, Stride: 1},
 		{Lo: 0x1f6d5, Hi: 0x1f6d7, Stride: 1},
 		{Lo: 0x1f6d5, Hi: 0x1f6d7, Stride: 1},
+		{Lo: 0x1f6dc, Hi: 0x1f6df, Stride: 1},
 		{Lo: 0x1f6eb, Hi: 0x1f6ec, Stride: 1},
 		{Lo: 0x1f6eb, Hi: 0x1f6ec, Stride: 1},
 		{Lo: 0x1f6f4, Hi: 0x1f6fc, Stride: 1},
 		{Lo: 0x1f6f4, Hi: 0x1f6fc, Stride: 1},
 		{Lo: 0x1f7e0, Hi: 0x1f7eb, Stride: 1},
 		{Lo: 0x1f7e0, Hi: 0x1f7eb, Stride: 1},
-		{Lo: 0x1f90c, Hi: 0x1f93a, Stride: 1},
+		{Lo: 0x1f7f0, Hi: 0x1f90c, Stride: 284},
+		{Lo: 0x1f90d, Hi: 0x1f93a, Stride: 1},
 		{Lo: 0x1f93c, Hi: 0x1f945, Stride: 1},
 		{Lo: 0x1f93c, Hi: 0x1f945, Stride: 1},
-		{Lo: 0x1f947, Hi: 0x1f978, Stride: 1},
-		{Lo: 0x1f97a, Hi: 0x1f9cb, Stride: 1},
-		{Lo: 0x1f9cd, Hi: 0x1f9ff, Stride: 1},
-		{Lo: 0x1fa70, Hi: 0x1fa74, Stride: 1},
-		{Lo: 0x1fa78, Hi: 0x1fa7a, Stride: 1},
-		{Lo: 0x1fa80, Hi: 0x1fa86, Stride: 1},
-		{Lo: 0x1fa90, Hi: 0x1faa8, Stride: 1},
-		{Lo: 0x1fab0, Hi: 0x1fab6, Stride: 1},
-		{Lo: 0x1fac0, Hi: 0x1fac2, Stride: 1},
-		{Lo: 0x1fad0, Hi: 0x1fad6, Stride: 1},
+		{Lo: 0x1f947, Hi: 0x1f9ff, Stride: 1},
+		{Lo: 0x1fa70, Hi: 0x1fa7c, Stride: 1},
+		{Lo: 0x1fa80, Hi: 0x1fa88, Stride: 1},
+		{Lo: 0x1fa90, Hi: 0x1fabd, Stride: 1},
+		{Lo: 0x1fabf, Hi: 0x1fac5, Stride: 1},
+		{Lo: 0x1face, Hi: 0x1fadb, Stride: 1},
+		{Lo: 0x1fae0, Hi: 0x1fae8, Stride: 1},
+		{Lo: 0x1faf0, Hi: 0x1faf8, Stride: 1},
 		{Lo: 0x20000, Hi: 0x2fffd, Stride: 1},
 		{Lo: 0x20000, Hi: 0x2fffd, Stride: 1},
 		{Lo: 0x30000, Hi: 0x3fffd, Stride: 1},
 		{Lo: 0x30000, Hi: 0x3fffd, Stride: 1},
 	},
 	},

+ 0 - 250
vendor/github.com/go-text/typesetting/unicodedata/emojis.go

@@ -6,256 +6,6 @@ import "unicode"
 
 
 // Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
 // Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
 
 
-var Emoji = &unicode.RangeTable{
-	R16: []unicode.Range16{
-		{Lo: 0x0023, Hi: 0x002a, Stride: 7},
-		{Lo: 0x0030, Hi: 0x0039, Stride: 1},
-		{Lo: 0x00a9, Hi: 0x00ae, Stride: 5},
-		{Lo: 0x203c, Hi: 0x2049, Stride: 13},
-		{Lo: 0x2122, Hi: 0x2139, Stride: 23},
-		{Lo: 0x2194, Hi: 0x2199, Stride: 1},
-		{Lo: 0x21a9, Hi: 0x21aa, Stride: 1},
-		{Lo: 0x231a, Hi: 0x231b, Stride: 1},
-		{Lo: 0x2328, Hi: 0x23cf, Stride: 167},
-		{Lo: 0x23e9, Hi: 0x23f3, Stride: 1},
-		{Lo: 0x23f8, Hi: 0x23fa, Stride: 1},
-		{Lo: 0x24c2, Hi: 0x25aa, Stride: 232},
-		{Lo: 0x25ab, Hi: 0x25b6, Stride: 11},
-		{Lo: 0x25c0, Hi: 0x25fb, Stride: 59},
-		{Lo: 0x25fc, Hi: 0x25fe, Stride: 1},
-		{Lo: 0x2600, Hi: 0x2604, Stride: 1},
-		{Lo: 0x260e, Hi: 0x2614, Stride: 3},
-		{Lo: 0x2615, Hi: 0x2618, Stride: 3},
-		{Lo: 0x261d, Hi: 0x2620, Stride: 3},
-		{Lo: 0x2622, Hi: 0x2623, Stride: 1},
-		{Lo: 0x2626, Hi: 0x262e, Stride: 4},
-		{Lo: 0x262f, Hi: 0x2638, Stride: 9},
-		{Lo: 0x2639, Hi: 0x263a, Stride: 1},
-		{Lo: 0x2640, Hi: 0x2642, Stride: 2},
-		{Lo: 0x2648, Hi: 0x2653, Stride: 1},
-		{Lo: 0x265f, Hi: 0x2660, Stride: 1},
-		{Lo: 0x2663, Hi: 0x2665, Stride: 2},
-		{Lo: 0x2666, Hi: 0x2668, Stride: 2},
-		{Lo: 0x267b, Hi: 0x267e, Stride: 3},
-		{Lo: 0x267f, Hi: 0x2692, Stride: 19},
-		{Lo: 0x2693, Hi: 0x2697, Stride: 1},
-		{Lo: 0x2699, Hi: 0x269b, Stride: 2},
-		{Lo: 0x269c, Hi: 0x26a0, Stride: 4},
-		{Lo: 0x26a1, Hi: 0x26a7, Stride: 6},
-		{Lo: 0x26aa, Hi: 0x26ab, Stride: 1},
-		{Lo: 0x26b0, Hi: 0x26b1, Stride: 1},
-		{Lo: 0x26bd, Hi: 0x26be, Stride: 1},
-		{Lo: 0x26c4, Hi: 0x26c5, Stride: 1},
-		{Lo: 0x26c8, Hi: 0x26ce, Stride: 6},
-		{Lo: 0x26cf, Hi: 0x26d3, Stride: 2},
-		{Lo: 0x26d4, Hi: 0x26e9, Stride: 21},
-		{Lo: 0x26ea, Hi: 0x26f0, Stride: 6},
-		{Lo: 0x26f1, Hi: 0x26f5, Stride: 1},
-		{Lo: 0x26f7, Hi: 0x26fa, Stride: 1},
-		{Lo: 0x26fd, Hi: 0x2702, Stride: 5},
-		{Lo: 0x2705, Hi: 0x2708, Stride: 3},
-		{Lo: 0x2709, Hi: 0x270d, Stride: 1},
-		{Lo: 0x270f, Hi: 0x2712, Stride: 3},
-		{Lo: 0x2714, Hi: 0x2716, Stride: 2},
-		{Lo: 0x271d, Hi: 0x2721, Stride: 4},
-		{Lo: 0x2728, Hi: 0x2733, Stride: 11},
-		{Lo: 0x2734, Hi: 0x2744, Stride: 16},
-		{Lo: 0x2747, Hi: 0x274c, Stride: 5},
-		{Lo: 0x274e, Hi: 0x2753, Stride: 5},
-		{Lo: 0x2754, Hi: 0x2755, Stride: 1},
-		{Lo: 0x2757, Hi: 0x2763, Stride: 12},
-		{Lo: 0x2764, Hi: 0x2795, Stride: 49},
-		{Lo: 0x2796, Hi: 0x2797, Stride: 1},
-		{Lo: 0x27a1, Hi: 0x27bf, Stride: 15},
-		{Lo: 0x2934, Hi: 0x2935, Stride: 1},
-		{Lo: 0x2b05, Hi: 0x2b07, Stride: 1},
-		{Lo: 0x2b1b, Hi: 0x2b1c, Stride: 1},
-		{Lo: 0x2b50, Hi: 0x2b55, Stride: 5},
-		{Lo: 0x3030, Hi: 0x303d, Stride: 13},
-		{Lo: 0x3297, Hi: 0x3299, Stride: 2},
-	},
-	R32: []unicode.Range32{
-		{Lo: 0x1f004, Hi: 0x1f0cf, Stride: 203},
-		{Lo: 0x1f170, Hi: 0x1f171, Stride: 1},
-		{Lo: 0x1f17e, Hi: 0x1f17f, Stride: 1},
-		{Lo: 0x1f18e, Hi: 0x1f191, Stride: 3},
-		{Lo: 0x1f192, Hi: 0x1f19a, Stride: 1},
-		{Lo: 0x1f1e6, Hi: 0x1f1ff, Stride: 1},
-		{Lo: 0x1f201, Hi: 0x1f202, Stride: 1},
-		{Lo: 0x1f21a, Hi: 0x1f22f, Stride: 21},
-		{Lo: 0x1f232, Hi: 0x1f23a, Stride: 1},
-		{Lo: 0x1f250, Hi: 0x1f251, Stride: 1},
-		{Lo: 0x1f300, Hi: 0x1f321, Stride: 1},
-		{Lo: 0x1f324, Hi: 0x1f393, Stride: 1},
-		{Lo: 0x1f396, Hi: 0x1f397, Stride: 1},
-		{Lo: 0x1f399, Hi: 0x1f39b, Stride: 1},
-		{Lo: 0x1f39e, Hi: 0x1f3f0, Stride: 1},
-		{Lo: 0x1f3f3, Hi: 0x1f3f5, Stride: 1},
-		{Lo: 0x1f3f7, Hi: 0x1f4fd, Stride: 1},
-		{Lo: 0x1f4ff, Hi: 0x1f53d, Stride: 1},
-		{Lo: 0x1f549, Hi: 0x1f54e, Stride: 1},
-		{Lo: 0x1f550, Hi: 0x1f567, Stride: 1},
-		{Lo: 0x1f56f, Hi: 0x1f570, Stride: 1},
-		{Lo: 0x1f573, Hi: 0x1f57a, Stride: 1},
-		{Lo: 0x1f587, Hi: 0x1f58a, Stride: 3},
-		{Lo: 0x1f58b, Hi: 0x1f58d, Stride: 1},
-		{Lo: 0x1f590, Hi: 0x1f595, Stride: 5},
-		{Lo: 0x1f596, Hi: 0x1f5a4, Stride: 14},
-		{Lo: 0x1f5a5, Hi: 0x1f5a8, Stride: 3},
-		{Lo: 0x1f5b1, Hi: 0x1f5b2, Stride: 1},
-		{Lo: 0x1f5bc, Hi: 0x1f5c2, Stride: 6},
-		{Lo: 0x1f5c3, Hi: 0x1f5c4, Stride: 1},
-		{Lo: 0x1f5d1, Hi: 0x1f5d3, Stride: 1},
-		{Lo: 0x1f5dc, Hi: 0x1f5de, Stride: 1},
-		{Lo: 0x1f5e1, Hi: 0x1f5e3, Stride: 2},
-		{Lo: 0x1f5e8, Hi: 0x1f5ef, Stride: 7},
-		{Lo: 0x1f5f3, Hi: 0x1f5fa, Stride: 7},
-		{Lo: 0x1f5fb, Hi: 0x1f64f, Stride: 1},
-		{Lo: 0x1f680, Hi: 0x1f6c5, Stride: 1},
-		{Lo: 0x1f6cb, Hi: 0x1f6d2, Stride: 1},
-		{Lo: 0x1f6d5, Hi: 0x1f6d7, Stride: 1},
-		{Lo: 0x1f6e0, Hi: 0x1f6e5, Stride: 1},
-		{Lo: 0x1f6e9, Hi: 0x1f6eb, Stride: 2},
-		{Lo: 0x1f6ec, Hi: 0x1f6f0, Stride: 4},
-		{Lo: 0x1f6f3, Hi: 0x1f6fc, Stride: 1},
-		{Lo: 0x1f7e0, Hi: 0x1f7eb, Stride: 1},
-		{Lo: 0x1f90c, Hi: 0x1f93a, Stride: 1},
-		{Lo: 0x1f93c, Hi: 0x1f945, Stride: 1},
-		{Lo: 0x1f947, Hi: 0x1f978, Stride: 1},
-		{Lo: 0x1f97a, Hi: 0x1f9cb, Stride: 1},
-		{Lo: 0x1f9cd, Hi: 0x1f9ff, Stride: 1},
-		{Lo: 0x1fa70, Hi: 0x1fa74, Stride: 1},
-		{Lo: 0x1fa78, Hi: 0x1fa7a, Stride: 1},
-		{Lo: 0x1fa80, Hi: 0x1fa86, Stride: 1},
-		{Lo: 0x1fa90, Hi: 0x1faa8, Stride: 1},
-		{Lo: 0x1fab0, Hi: 0x1fab6, Stride: 1},
-		{Lo: 0x1fac0, Hi: 0x1fac2, Stride: 1},
-		{Lo: 0x1fad0, Hi: 0x1fad6, Stride: 1},
-	},
-	LatinOffset: 3,
-}
-
-var Emoji_Presentation = &unicode.RangeTable{
-	R16: []unicode.Range16{
-		{Lo: 0x231a, Hi: 0x231b, Stride: 1},
-		{Lo: 0x23e9, Hi: 0x23ec, Stride: 1},
-		{Lo: 0x23f0, Hi: 0x23f3, Stride: 3},
-		{Lo: 0x25fd, Hi: 0x25fe, Stride: 1},
-		{Lo: 0x2614, Hi: 0x2615, Stride: 1},
-		{Lo: 0x2648, Hi: 0x2653, Stride: 1},
-		{Lo: 0x267f, Hi: 0x2693, Stride: 20},
-		{Lo: 0x26a1, Hi: 0x26aa, Stride: 9},
-		{Lo: 0x26ab, Hi: 0x26bd, Stride: 18},
-		{Lo: 0x26be, Hi: 0x26c4, Stride: 6},
-		{Lo: 0x26c5, Hi: 0x26ce, Stride: 9},
-		{Lo: 0x26d4, Hi: 0x26ea, Stride: 22},
-		{Lo: 0x26f2, Hi: 0x26f3, Stride: 1},
-		{Lo: 0x26f5, Hi: 0x26fa, Stride: 5},
-		{Lo: 0x26fd, Hi: 0x2705, Stride: 8},
-		{Lo: 0x270a, Hi: 0x270b, Stride: 1},
-		{Lo: 0x2728, Hi: 0x274c, Stride: 36},
-		{Lo: 0x274e, Hi: 0x2753, Stride: 5},
-		{Lo: 0x2754, Hi: 0x2755, Stride: 1},
-		{Lo: 0x2757, Hi: 0x2795, Stride: 62},
-		{Lo: 0x2796, Hi: 0x2797, Stride: 1},
-		{Lo: 0x27b0, Hi: 0x27bf, Stride: 15},
-		{Lo: 0x2b1b, Hi: 0x2b1c, Stride: 1},
-		{Lo: 0x2b50, Hi: 0x2b55, Stride: 5},
-	},
-	R32: []unicode.Range32{
-		{Lo: 0x1f004, Hi: 0x1f0cf, Stride: 203},
-		{Lo: 0x1f18e, Hi: 0x1f191, Stride: 3},
-		{Lo: 0x1f192, Hi: 0x1f19a, Stride: 1},
-		{Lo: 0x1f1e6, Hi: 0x1f1ff, Stride: 1},
-		{Lo: 0x1f201, Hi: 0x1f21a, Stride: 25},
-		{Lo: 0x1f22f, Hi: 0x1f232, Stride: 3},
-		{Lo: 0x1f233, Hi: 0x1f236, Stride: 1},
-		{Lo: 0x1f238, Hi: 0x1f23a, Stride: 1},
-		{Lo: 0x1f250, Hi: 0x1f251, Stride: 1},
-		{Lo: 0x1f300, Hi: 0x1f320, Stride: 1},
-		{Lo: 0x1f32d, Hi: 0x1f335, Stride: 1},
-		{Lo: 0x1f337, Hi: 0x1f37c, Stride: 1},
-		{Lo: 0x1f37e, Hi: 0x1f393, Stride: 1},
-		{Lo: 0x1f3a0, Hi: 0x1f3ca, Stride: 1},
-		{Lo: 0x1f3cf, Hi: 0x1f3d3, Stride: 1},
-		{Lo: 0x1f3e0, Hi: 0x1f3f0, Stride: 1},
-		{Lo: 0x1f3f4, Hi: 0x1f3f8, Stride: 4},
-		{Lo: 0x1f3f9, Hi: 0x1f43e, Stride: 1},
-		{Lo: 0x1f440, Hi: 0x1f442, Stride: 2},
-		{Lo: 0x1f443, Hi: 0x1f4fc, Stride: 1},
-		{Lo: 0x1f4ff, Hi: 0x1f53d, Stride: 1},
-		{Lo: 0x1f54b, Hi: 0x1f54e, Stride: 1},
-		{Lo: 0x1f550, Hi: 0x1f567, Stride: 1},
-		{Lo: 0x1f57a, Hi: 0x1f595, Stride: 27},
-		{Lo: 0x1f596, Hi: 0x1f5a4, Stride: 14},
-		{Lo: 0x1f5fb, Hi: 0x1f64f, Stride: 1},
-		{Lo: 0x1f680, Hi: 0x1f6c5, Stride: 1},
-		{Lo: 0x1f6cc, Hi: 0x1f6d0, Stride: 4},
-		{Lo: 0x1f6d1, Hi: 0x1f6d2, Stride: 1},
-		{Lo: 0x1f6d5, Hi: 0x1f6d7, Stride: 1},
-		{Lo: 0x1f6eb, Hi: 0x1f6ec, Stride: 1},
-		{Lo: 0x1f6f4, Hi: 0x1f6fc, Stride: 1},
-		{Lo: 0x1f7e0, Hi: 0x1f7eb, Stride: 1},
-		{Lo: 0x1f90c, Hi: 0x1f93a, Stride: 1},
-		{Lo: 0x1f93c, Hi: 0x1f945, Stride: 1},
-		{Lo: 0x1f947, Hi: 0x1f978, Stride: 1},
-		{Lo: 0x1f97a, Hi: 0x1f9cb, Stride: 1},
-		{Lo: 0x1f9cd, Hi: 0x1f9ff, Stride: 1},
-		{Lo: 0x1fa70, Hi: 0x1fa74, Stride: 1},
-		{Lo: 0x1fa78, Hi: 0x1fa7a, Stride: 1},
-		{Lo: 0x1fa80, Hi: 0x1fa86, Stride: 1},
-		{Lo: 0x1fa90, Hi: 0x1faa8, Stride: 1},
-		{Lo: 0x1fab0, Hi: 0x1fab6, Stride: 1},
-		{Lo: 0x1fac0, Hi: 0x1fac2, Stride: 1},
-		{Lo: 0x1fad0, Hi: 0x1fad6, Stride: 1},
-	},
-}
-
-var Emoji_Modifier = &unicode.RangeTable{
-	R32: []unicode.Range32{
-		{Lo: 0x1f3fb, Hi: 0x1f3ff, Stride: 1},
-	},
-}
-
-var Emoji_Modifier_Base = &unicode.RangeTable{
-	R16: []unicode.Range16{
-		{Lo: 0x261d, Hi: 0x26f9, Stride: 220},
-		{Lo: 0x270a, Hi: 0x270d, Stride: 1},
-	},
-	R32: []unicode.Range32{
-		{Lo: 0x1f385, Hi: 0x1f3c2, Stride: 61},
-		{Lo: 0x1f3c3, Hi: 0x1f3c4, Stride: 1},
-		{Lo: 0x1f3c7, Hi: 0x1f3ca, Stride: 3},
-		{Lo: 0x1f3cb, Hi: 0x1f3cc, Stride: 1},
-		{Lo: 0x1f442, Hi: 0x1f443, Stride: 1},
-		{Lo: 0x1f446, Hi: 0x1f450, Stride: 1},
-		{Lo: 0x1f466, Hi: 0x1f478, Stride: 1},
-		{Lo: 0x1f47c, Hi: 0x1f481, Stride: 5},
-		{Lo: 0x1f482, Hi: 0x1f483, Stride: 1},
-		{Lo: 0x1f485, Hi: 0x1f487, Stride: 1},
-		{Lo: 0x1f48f, Hi: 0x1f491, Stride: 2},
-		{Lo: 0x1f4aa, Hi: 0x1f574, Stride: 202},
-		{Lo: 0x1f575, Hi: 0x1f57a, Stride: 5},
-		{Lo: 0x1f590, Hi: 0x1f595, Stride: 5},
-		{Lo: 0x1f596, Hi: 0x1f645, Stride: 175},
-		{Lo: 0x1f646, Hi: 0x1f647, Stride: 1},
-		{Lo: 0x1f64b, Hi: 0x1f64f, Stride: 1},
-		{Lo: 0x1f6a3, Hi: 0x1f6b4, Stride: 17},
-		{Lo: 0x1f6b5, Hi: 0x1f6b6, Stride: 1},
-		{Lo: 0x1f6c0, Hi: 0x1f6cc, Stride: 12},
-		{Lo: 0x1f90c, Hi: 0x1f90f, Stride: 3},
-		{Lo: 0x1f918, Hi: 0x1f91f, Stride: 1},
-		{Lo: 0x1f926, Hi: 0x1f930, Stride: 10},
-		{Lo: 0x1f931, Hi: 0x1f939, Stride: 1},
-		{Lo: 0x1f93c, Hi: 0x1f93e, Stride: 1},
-		{Lo: 0x1f977, Hi: 0x1f9b5, Stride: 62},
-		{Lo: 0x1f9b6, Hi: 0x1f9b8, Stride: 2},
-		{Lo: 0x1f9b9, Hi: 0x1f9bb, Stride: 2},
-		{Lo: 0x1f9cd, Hi: 0x1f9cf, Stride: 1},
-		{Lo: 0x1f9d1, Hi: 0x1f9dd, Stride: 1},
-	},
-}
-
 var Extended_Pictographic = &unicode.RangeTable{
 var Extended_Pictographic = &unicode.RangeTable{
 	R16: []unicode.Range16{
 	R16: []unicode.Range16{
 		{Lo: 0x00a9, Hi: 0x00ae, Stride: 5},
 		{Lo: 0x00a9, Hi: 0x00ae, Stride: 5},

+ 2205 - 0
vendor/github.com/go-text/typesetting/unicodedata/general_category.go

@@ -0,0 +1,2205 @@
+// SPDX-License-Identifier: Unlicense OR BSD-3-Clause
+
+package unicodedata
+
+import "unicode"
+
+// Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
+
+var Cc = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x0000, Hi: 0x001f, Stride: 1},
+		{Lo: 0x007f, Hi: 0x009f, Stride: 1},
+	},
+	LatinOffset: 2,
+}
+
+var Cf = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x00ad, Hi: 0x0600, Stride: 1363},
+		{Lo: 0x0601, Hi: 0x0605, Stride: 1},
+		{Lo: 0x061c, Hi: 0x06dd, Stride: 193},
+		{Lo: 0x070f, Hi: 0x0890, Stride: 385},
+		{Lo: 0x0891, Hi: 0x08e2, Stride: 81},
+		{Lo: 0x180e, Hi: 0x200b, Stride: 2045},
+		{Lo: 0x200c, Hi: 0x200f, Stride: 1},
+		{Lo: 0x202a, Hi: 0x202e, Stride: 1},
+		{Lo: 0x2060, Hi: 0x2064, Stride: 1},
+		{Lo: 0x2066, Hi: 0x206f, Stride: 1},
+		{Lo: 0xfeff, Hi: 0xfff9, Stride: 250},
+		{Lo: 0xfffa, Hi: 0xfffb, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x110bd, Hi: 0x110cd, Stride: 16},
+		{Lo: 0x13430, Hi: 0x1343f, Stride: 1},
+		{Lo: 0x1bca0, Hi: 0x1bca3, Stride: 1},
+		{Lo: 0x1d173, Hi: 0x1d17a, Stride: 1},
+		{Lo: 0xe0001, Hi: 0xe0020, Stride: 31},
+		{Lo: 0xe0021, Hi: 0xe007f, Stride: 1},
+	},
+}
+
+var Co = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0xe000, Hi: 0xf8ff, Stride: 6399},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0xf0000, Hi: 0xffffd, Stride: 65533},
+		{Lo: 0x100000, Hi: 0x10fffd, Stride: 65533},
+	},
+}
+
+var Cs = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0xd800, Hi: 0xdb7f, Stride: 895},
+		{Lo: 0xdb80, Hi: 0xdbff, Stride: 127},
+		{Lo: 0xdc00, Hi: 0xdfff, Stride: 1023},
+	},
+}
+
+var Ll = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x0061, Hi: 0x007a, Stride: 1},
+		{Lo: 0x00b5, Hi: 0x00df, Stride: 42},
+		{Lo: 0x00e0, Hi: 0x00f6, Stride: 1},
+		{Lo: 0x00f8, Hi: 0x00ff, Stride: 1},
+		{Lo: 0x0101, Hi: 0x0137, Stride: 2},
+		{Lo: 0x0138, Hi: 0x0148, Stride: 2},
+		{Lo: 0x0149, Hi: 0x0177, Stride: 2},
+		{Lo: 0x017a, Hi: 0x017e, Stride: 2},
+		{Lo: 0x017f, Hi: 0x0180, Stride: 1},
+		{Lo: 0x0183, Hi: 0x0185, Stride: 2},
+		{Lo: 0x0188, Hi: 0x018c, Stride: 4},
+		{Lo: 0x018d, Hi: 0x0192, Stride: 5},
+		{Lo: 0x0195, Hi: 0x0199, Stride: 4},
+		{Lo: 0x019a, Hi: 0x019b, Stride: 1},
+		{Lo: 0x019e, Hi: 0x01a1, Stride: 3},
+		{Lo: 0x01a3, Hi: 0x01a5, Stride: 2},
+		{Lo: 0x01a8, Hi: 0x01aa, Stride: 2},
+		{Lo: 0x01ab, Hi: 0x01ad, Stride: 2},
+		{Lo: 0x01b0, Hi: 0x01b4, Stride: 4},
+		{Lo: 0x01b6, Hi: 0x01b9, Stride: 3},
+		{Lo: 0x01ba, Hi: 0x01bd, Stride: 3},
+		{Lo: 0x01be, Hi: 0x01bf, Stride: 1},
+		{Lo: 0x01c6, Hi: 0x01cc, Stride: 3},
+		{Lo: 0x01ce, Hi: 0x01dc, Stride: 2},
+		{Lo: 0x01dd, Hi: 0x01ef, Stride: 2},
+		{Lo: 0x01f0, Hi: 0x01f3, Stride: 3},
+		{Lo: 0x01f5, Hi: 0x01f9, Stride: 4},
+		{Lo: 0x01fb, Hi: 0x0233, Stride: 2},
+		{Lo: 0x0234, Hi: 0x0239, Stride: 1},
+		{Lo: 0x023c, Hi: 0x023f, Stride: 3},
+		{Lo: 0x0240, Hi: 0x0242, Stride: 2},
+		{Lo: 0x0247, Hi: 0x024f, Stride: 2},
+		{Lo: 0x0250, Hi: 0x0293, Stride: 1},
+		{Lo: 0x0295, Hi: 0x02af, Stride: 1},
+		{Lo: 0x0371, Hi: 0x0373, Stride: 2},
+		{Lo: 0x0377, Hi: 0x037b, Stride: 4},
+		{Lo: 0x037c, Hi: 0x037d, Stride: 1},
+		{Lo: 0x0390, Hi: 0x03ac, Stride: 28},
+		{Lo: 0x03ad, Hi: 0x03ce, Stride: 1},
+		{Lo: 0x03d0, Hi: 0x03d1, Stride: 1},
+		{Lo: 0x03d5, Hi: 0x03d7, Stride: 1},
+		{Lo: 0x03d9, Hi: 0x03ef, Stride: 2},
+		{Lo: 0x03f0, Hi: 0x03f3, Stride: 1},
+		{Lo: 0x03f5, Hi: 0x03fb, Stride: 3},
+		{Lo: 0x03fc, Hi: 0x0430, Stride: 52},
+		{Lo: 0x0431, Hi: 0x045f, Stride: 1},
+		{Lo: 0x0461, Hi: 0x0481, Stride: 2},
+		{Lo: 0x048b, Hi: 0x04bf, Stride: 2},
+		{Lo: 0x04c2, Hi: 0x04ce, Stride: 2},
+		{Lo: 0x04cf, Hi: 0x052f, Stride: 2},
+		{Lo: 0x0560, Hi: 0x0588, Stride: 1},
+		{Lo: 0x10d0, Hi: 0x10fa, Stride: 1},
+		{Lo: 0x10fd, Hi: 0x10ff, Stride: 1},
+		{Lo: 0x13f8, Hi: 0x13fd, Stride: 1},
+		{Lo: 0x1c80, Hi: 0x1c88, Stride: 1},
+		{Lo: 0x1d00, Hi: 0x1d2b, Stride: 1},
+		{Lo: 0x1d6b, Hi: 0x1d77, Stride: 1},
+		{Lo: 0x1d79, Hi: 0x1d9a, Stride: 1},
+		{Lo: 0x1e01, Hi: 0x1e95, Stride: 2},
+		{Lo: 0x1e96, Hi: 0x1e9d, Stride: 1},
+		{Lo: 0x1e9f, Hi: 0x1eff, Stride: 2},
+		{Lo: 0x1f00, Hi: 0x1f07, Stride: 1},
+		{Lo: 0x1f10, Hi: 0x1f15, Stride: 1},
+		{Lo: 0x1f20, Hi: 0x1f27, Stride: 1},
+		{Lo: 0x1f30, Hi: 0x1f37, Stride: 1},
+		{Lo: 0x1f40, Hi: 0x1f45, Stride: 1},
+		{Lo: 0x1f50, Hi: 0x1f57, Stride: 1},
+		{Lo: 0x1f60, Hi: 0x1f67, Stride: 1},
+		{Lo: 0x1f70, Hi: 0x1f7d, Stride: 1},
+		{Lo: 0x1f80, Hi: 0x1f87, Stride: 1},
+		{Lo: 0x1f90, Hi: 0x1f97, Stride: 1},
+		{Lo: 0x1fa0, Hi: 0x1fa7, Stride: 1},
+		{Lo: 0x1fb0, Hi: 0x1fb4, Stride: 1},
+		{Lo: 0x1fb6, Hi: 0x1fb7, Stride: 1},
+		{Lo: 0x1fbe, Hi: 0x1fc2, Stride: 4},
+		{Lo: 0x1fc3, Hi: 0x1fc4, Stride: 1},
+		{Lo: 0x1fc6, Hi: 0x1fc7, Stride: 1},
+		{Lo: 0x1fd0, Hi: 0x1fd3, Stride: 1},
+		{Lo: 0x1fd6, Hi: 0x1fd7, Stride: 1},
+		{Lo: 0x1fe0, Hi: 0x1fe7, Stride: 1},
+		{Lo: 0x1ff2, Hi: 0x1ff4, Stride: 1},
+		{Lo: 0x1ff6, Hi: 0x1ff7, Stride: 1},
+		{Lo: 0x210a, Hi: 0x210e, Stride: 4},
+		{Lo: 0x210f, Hi: 0x2113, Stride: 4},
+		{Lo: 0x212f, Hi: 0x2139, Stride: 5},
+		{Lo: 0x213c, Hi: 0x213d, Stride: 1},
+		{Lo: 0x2146, Hi: 0x2149, Stride: 1},
+		{Lo: 0x214e, Hi: 0x2184, Stride: 54},
+		{Lo: 0x2c30, Hi: 0x2c5f, Stride: 1},
+		{Lo: 0x2c61, Hi: 0x2c65, Stride: 4},
+		{Lo: 0x2c66, Hi: 0x2c6c, Stride: 2},
+		{Lo: 0x2c71, Hi: 0x2c73, Stride: 2},
+		{Lo: 0x2c74, Hi: 0x2c76, Stride: 2},
+		{Lo: 0x2c77, Hi: 0x2c7b, Stride: 1},
+		{Lo: 0x2c81, Hi: 0x2ce3, Stride: 2},
+		{Lo: 0x2ce4, Hi: 0x2cec, Stride: 8},
+		{Lo: 0x2cee, Hi: 0x2cf3, Stride: 5},
+		{Lo: 0x2d00, Hi: 0x2d25, Stride: 1},
+		{Lo: 0x2d27, Hi: 0x2d2d, Stride: 6},
+		{Lo: 0xa641, Hi: 0xa66d, Stride: 2},
+		{Lo: 0xa681, Hi: 0xa69b, Stride: 2},
+		{Lo: 0xa723, Hi: 0xa72f, Stride: 2},
+		{Lo: 0xa730, Hi: 0xa731, Stride: 1},
+		{Lo: 0xa733, Hi: 0xa771, Stride: 2},
+		{Lo: 0xa772, Hi: 0xa778, Stride: 1},
+		{Lo: 0xa77a, Hi: 0xa77c, Stride: 2},
+		{Lo: 0xa77f, Hi: 0xa787, Stride: 2},
+		{Lo: 0xa78c, Hi: 0xa78e, Stride: 2},
+		{Lo: 0xa791, Hi: 0xa793, Stride: 2},
+		{Lo: 0xa794, Hi: 0xa795, Stride: 1},
+		{Lo: 0xa797, Hi: 0xa7a9, Stride: 2},
+		{Lo: 0xa7af, Hi: 0xa7b5, Stride: 6},
+		{Lo: 0xa7b7, Hi: 0xa7c3, Stride: 2},
+		{Lo: 0xa7c8, Hi: 0xa7ca, Stride: 2},
+		{Lo: 0xa7d1, Hi: 0xa7d9, Stride: 2},
+		{Lo: 0xa7f6, Hi: 0xa7fa, Stride: 4},
+		{Lo: 0xab30, Hi: 0xab5a, Stride: 1},
+		{Lo: 0xab60, Hi: 0xab68, Stride: 1},
+		{Lo: 0xab70, Hi: 0xabbf, Stride: 1},
+		{Lo: 0xfb00, Hi: 0xfb06, Stride: 1},
+		{Lo: 0xfb13, Hi: 0xfb17, Stride: 1},
+		{Lo: 0xff41, Hi: 0xff5a, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x10428, Hi: 0x1044f, Stride: 1},
+		{Lo: 0x104d8, Hi: 0x104fb, Stride: 1},
+		{Lo: 0x10597, Hi: 0x105a1, Stride: 1},
+		{Lo: 0x105a3, Hi: 0x105b1, Stride: 1},
+		{Lo: 0x105b3, Hi: 0x105b9, Stride: 1},
+		{Lo: 0x105bb, Hi: 0x105bc, Stride: 1},
+		{Lo: 0x10cc0, Hi: 0x10cf2, Stride: 1},
+		{Lo: 0x118c0, Hi: 0x118df, Stride: 1},
+		{Lo: 0x16e60, Hi: 0x16e7f, Stride: 1},
+		{Lo: 0x1d41a, Hi: 0x1d433, Stride: 1},
+		{Lo: 0x1d44e, Hi: 0x1d454, Stride: 1},
+		{Lo: 0x1d456, Hi: 0x1d467, Stride: 1},
+		{Lo: 0x1d482, Hi: 0x1d49b, Stride: 1},
+		{Lo: 0x1d4b6, Hi: 0x1d4b9, Stride: 1},
+		{Lo: 0x1d4bb, Hi: 0x1d4bd, Stride: 2},
+		{Lo: 0x1d4be, Hi: 0x1d4c3, Stride: 1},
+		{Lo: 0x1d4c5, Hi: 0x1d4cf, Stride: 1},
+		{Lo: 0x1d4ea, Hi: 0x1d503, Stride: 1},
+		{Lo: 0x1d51e, Hi: 0x1d537, Stride: 1},
+		{Lo: 0x1d552, Hi: 0x1d56b, Stride: 1},
+		{Lo: 0x1d586, Hi: 0x1d59f, Stride: 1},
+		{Lo: 0x1d5ba, Hi: 0x1d5d3, Stride: 1},
+		{Lo: 0x1d5ee, Hi: 0x1d607, Stride: 1},
+		{Lo: 0x1d622, Hi: 0x1d63b, Stride: 1},
+		{Lo: 0x1d656, Hi: 0x1d66f, Stride: 1},
+		{Lo: 0x1d68a, Hi: 0x1d6a5, Stride: 1},
+		{Lo: 0x1d6c2, Hi: 0x1d6da, Stride: 1},
+		{Lo: 0x1d6dc, Hi: 0x1d6e1, Stride: 1},
+		{Lo: 0x1d6fc, Hi: 0x1d714, Stride: 1},
+		{Lo: 0x1d716, Hi: 0x1d71b, Stride: 1},
+		{Lo: 0x1d736, Hi: 0x1d74e, Stride: 1},
+		{Lo: 0x1d750, Hi: 0x1d755, Stride: 1},
+		{Lo: 0x1d770, Hi: 0x1d788, Stride: 1},
+		{Lo: 0x1d78a, Hi: 0x1d78f, Stride: 1},
+		{Lo: 0x1d7aa, Hi: 0x1d7c2, Stride: 1},
+		{Lo: 0x1d7c4, Hi: 0x1d7c9, Stride: 1},
+		{Lo: 0x1d7cb, Hi: 0x1df00, Stride: 1845},
+		{Lo: 0x1df01, Hi: 0x1df09, Stride: 1},
+		{Lo: 0x1df0b, Hi: 0x1df1e, Stride: 1},
+		{Lo: 0x1df25, Hi: 0x1df2a, Stride: 1},
+		{Lo: 0x1e922, Hi: 0x1e943, Stride: 1},
+	},
+	LatinOffset: 4,
+}
+
+var Lm = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x02b0, Hi: 0x02c1, Stride: 1},
+		{Lo: 0x02c6, Hi: 0x02d1, Stride: 1},
+		{Lo: 0x02e0, Hi: 0x02e4, Stride: 1},
+		{Lo: 0x02ec, Hi: 0x02ee, Stride: 2},
+		{Lo: 0x0374, Hi: 0x037a, Stride: 6},
+		{Lo: 0x0559, Hi: 0x0640, Stride: 231},
+		{Lo: 0x06e5, Hi: 0x06e6, Stride: 1},
+		{Lo: 0x07f4, Hi: 0x07f5, Stride: 1},
+		{Lo: 0x07fa, Hi: 0x081a, Stride: 32},
+		{Lo: 0x0824, Hi: 0x0828, Stride: 4},
+		{Lo: 0x08c9, Hi: 0x0971, Stride: 168},
+		{Lo: 0x0e46, Hi: 0x0ec6, Stride: 128},
+		{Lo: 0x10fc, Hi: 0x17d7, Stride: 1755},
+		{Lo: 0x1843, Hi: 0x1aa7, Stride: 612},
+		{Lo: 0x1c78, Hi: 0x1c7d, Stride: 1},
+		{Lo: 0x1d2c, Hi: 0x1d6a, Stride: 1},
+		{Lo: 0x1d78, Hi: 0x1d9b, Stride: 35},
+		{Lo: 0x1d9c, Hi: 0x1dbf, Stride: 1},
+		{Lo: 0x2071, Hi: 0x207f, Stride: 14},
+		{Lo: 0x2090, Hi: 0x209c, Stride: 1},
+		{Lo: 0x2c7c, Hi: 0x2c7d, Stride: 1},
+		{Lo: 0x2d6f, Hi: 0x2e2f, Stride: 192},
+		{Lo: 0x3005, Hi: 0x3031, Stride: 44},
+		{Lo: 0x3032, Hi: 0x3035, Stride: 1},
+		{Lo: 0x303b, Hi: 0x309d, Stride: 98},
+		{Lo: 0x309e, Hi: 0x30fc, Stride: 94},
+		{Lo: 0x30fd, Hi: 0x30fe, Stride: 1},
+		{Lo: 0xa015, Hi: 0xa4f8, Stride: 1251},
+		{Lo: 0xa4f9, Hi: 0xa4fd, Stride: 1},
+		{Lo: 0xa60c, Hi: 0xa67f, Stride: 115},
+		{Lo: 0xa69c, Hi: 0xa69d, Stride: 1},
+		{Lo: 0xa717, Hi: 0xa71f, Stride: 1},
+		{Lo: 0xa770, Hi: 0xa788, Stride: 24},
+		{Lo: 0xa7f2, Hi: 0xa7f4, Stride: 1},
+		{Lo: 0xa7f8, Hi: 0xa7f9, Stride: 1},
+		{Lo: 0xa9cf, Hi: 0xa9e6, Stride: 23},
+		{Lo: 0xaa70, Hi: 0xaadd, Stride: 109},
+		{Lo: 0xaaf3, Hi: 0xaaf4, Stride: 1},
+		{Lo: 0xab5c, Hi: 0xab5f, Stride: 1},
+		{Lo: 0xab69, Hi: 0xff70, Stride: 21511},
+		{Lo: 0xff9e, Hi: 0xff9f, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x10780, Hi: 0x10785, Stride: 1},
+		{Lo: 0x10787, Hi: 0x107b0, Stride: 1},
+		{Lo: 0x107b2, Hi: 0x107ba, Stride: 1},
+		{Lo: 0x16b40, Hi: 0x16b43, Stride: 1},
+		{Lo: 0x16f93, Hi: 0x16f9f, Stride: 1},
+		{Lo: 0x16fe0, Hi: 0x16fe1, Stride: 1},
+		{Lo: 0x16fe3, Hi: 0x1aff0, Stride: 16397},
+		{Lo: 0x1aff1, Hi: 0x1aff3, Stride: 1},
+		{Lo: 0x1aff5, Hi: 0x1affb, Stride: 1},
+		{Lo: 0x1affd, Hi: 0x1affe, Stride: 1},
+		{Lo: 0x1e030, Hi: 0x1e06d, Stride: 1},
+		{Lo: 0x1e137, Hi: 0x1e13d, Stride: 1},
+		{Lo: 0x1e4eb, Hi: 0x1e94b, Stride: 1120},
+	},
+}
+
+var Lo = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x00aa, Hi: 0x00ba, Stride: 16},
+		{Lo: 0x01bb, Hi: 0x01c0, Stride: 5},
+		{Lo: 0x01c1, Hi: 0x01c3, Stride: 1},
+		{Lo: 0x0294, Hi: 0x05d0, Stride: 828},
+		{Lo: 0x05d1, Hi: 0x05ea, Stride: 1},
+		{Lo: 0x05ef, Hi: 0x05f2, Stride: 1},
+		{Lo: 0x0620, Hi: 0x063f, Stride: 1},
+		{Lo: 0x0641, Hi: 0x064a, Stride: 1},
+		{Lo: 0x066e, Hi: 0x066f, Stride: 1},
+		{Lo: 0x0671, Hi: 0x06d3, Stride: 1},
+		{Lo: 0x06d5, Hi: 0x06ee, Stride: 25},
+		{Lo: 0x06ef, Hi: 0x06fa, Stride: 11},
+		{Lo: 0x06fb, Hi: 0x06fc, Stride: 1},
+		{Lo: 0x06ff, Hi: 0x0710, Stride: 17},
+		{Lo: 0x0712, Hi: 0x072f, Stride: 1},
+		{Lo: 0x074d, Hi: 0x07a5, Stride: 1},
+		{Lo: 0x07b1, Hi: 0x07ca, Stride: 25},
+		{Lo: 0x07cb, Hi: 0x07ea, Stride: 1},
+		{Lo: 0x0800, Hi: 0x0815, Stride: 1},
+		{Lo: 0x0840, Hi: 0x0858, Stride: 1},
+		{Lo: 0x0860, Hi: 0x086a, Stride: 1},
+		{Lo: 0x0870, Hi: 0x0887, Stride: 1},
+		{Lo: 0x0889, Hi: 0x088e, Stride: 1},
+		{Lo: 0x08a0, Hi: 0x08c8, Stride: 1},
+		{Lo: 0x0904, Hi: 0x0939, Stride: 1},
+		{Lo: 0x093d, Hi: 0x0950, Stride: 19},
+		{Lo: 0x0958, Hi: 0x0961, Stride: 1},
+		{Lo: 0x0972, Hi: 0x0980, Stride: 1},
+		{Lo: 0x0985, Hi: 0x098c, Stride: 1},
+		{Lo: 0x098f, Hi: 0x0990, Stride: 1},
+		{Lo: 0x0993, Hi: 0x09a8, Stride: 1},
+		{Lo: 0x09aa, Hi: 0x09b0, Stride: 1},
+		{Lo: 0x09b2, Hi: 0x09b6, Stride: 4},
+		{Lo: 0x09b7, Hi: 0x09b9, Stride: 1},
+		{Lo: 0x09bd, Hi: 0x09ce, Stride: 17},
+		{Lo: 0x09dc, Hi: 0x09dd, Stride: 1},
+		{Lo: 0x09df, Hi: 0x09e1, Stride: 1},
+		{Lo: 0x09f0, Hi: 0x09f1, Stride: 1},
+		{Lo: 0x09fc, Hi: 0x0a05, Stride: 9},
+		{Lo: 0x0a06, Hi: 0x0a0a, Stride: 1},
+		{Lo: 0x0a0f, Hi: 0x0a10, Stride: 1},
+		{Lo: 0x0a13, Hi: 0x0a28, Stride: 1},
+		{Lo: 0x0a2a, Hi: 0x0a30, Stride: 1},
+		{Lo: 0x0a32, Hi: 0x0a33, Stride: 1},
+		{Lo: 0x0a35, Hi: 0x0a36, Stride: 1},
+		{Lo: 0x0a38, Hi: 0x0a39, Stride: 1},
+		{Lo: 0x0a59, Hi: 0x0a5c, Stride: 1},
+		{Lo: 0x0a5e, Hi: 0x0a72, Stride: 20},
+		{Lo: 0x0a73, Hi: 0x0a74, Stride: 1},
+		{Lo: 0x0a85, Hi: 0x0a8d, Stride: 1},
+		{Lo: 0x0a8f, Hi: 0x0a91, Stride: 1},
+		{Lo: 0x0a93, Hi: 0x0aa8, Stride: 1},
+		{Lo: 0x0aaa, Hi: 0x0ab0, Stride: 1},
+		{Lo: 0x0ab2, Hi: 0x0ab3, Stride: 1},
+		{Lo: 0x0ab5, Hi: 0x0ab9, Stride: 1},
+		{Lo: 0x0abd, Hi: 0x0ad0, Stride: 19},
+		{Lo: 0x0ae0, Hi: 0x0ae1, Stride: 1},
+		{Lo: 0x0af9, Hi: 0x0b05, Stride: 12},
+		{Lo: 0x0b06, Hi: 0x0b0c, Stride: 1},
+		{Lo: 0x0b0f, Hi: 0x0b10, Stride: 1},
+		{Lo: 0x0b13, Hi: 0x0b28, Stride: 1},
+		{Lo: 0x0b2a, Hi: 0x0b30, Stride: 1},
+		{Lo: 0x0b32, Hi: 0x0b33, Stride: 1},
+		{Lo: 0x0b35, Hi: 0x0b39, Stride: 1},
+		{Lo: 0x0b3d, Hi: 0x0b5c, Stride: 31},
+		{Lo: 0x0b5d, Hi: 0x0b5f, Stride: 2},
+		{Lo: 0x0b60, Hi: 0x0b61, Stride: 1},
+		{Lo: 0x0b71, Hi: 0x0b83, Stride: 18},
+		{Lo: 0x0b85, Hi: 0x0b8a, Stride: 1},
+		{Lo: 0x0b8e, Hi: 0x0b90, Stride: 1},
+		{Lo: 0x0b92, Hi: 0x0b95, Stride: 1},
+		{Lo: 0x0b99, Hi: 0x0b9a, Stride: 1},
+		{Lo: 0x0b9c, Hi: 0x0b9e, Stride: 2},
+		{Lo: 0x0b9f, Hi: 0x0ba3, Stride: 4},
+		{Lo: 0x0ba4, Hi: 0x0ba8, Stride: 4},
+		{Lo: 0x0ba9, Hi: 0x0baa, Stride: 1},
+		{Lo: 0x0bae, Hi: 0x0bb9, Stride: 1},
+		{Lo: 0x0bd0, Hi: 0x0c05, Stride: 53},
+		{Lo: 0x0c06, Hi: 0x0c0c, Stride: 1},
+		{Lo: 0x0c0e, Hi: 0x0c10, Stride: 1},
+		{Lo: 0x0c12, Hi: 0x0c28, Stride: 1},
+		{Lo: 0x0c2a, Hi: 0x0c39, Stride: 1},
+		{Lo: 0x0c3d, Hi: 0x0c58, Stride: 27},
+		{Lo: 0x0c59, Hi: 0x0c5a, Stride: 1},
+		{Lo: 0x0c5d, Hi: 0x0c60, Stride: 3},
+		{Lo: 0x0c61, Hi: 0x0c80, Stride: 31},
+		{Lo: 0x0c85, Hi: 0x0c8c, Stride: 1},
+		{Lo: 0x0c8e, Hi: 0x0c90, Stride: 1},
+		{Lo: 0x0c92, Hi: 0x0ca8, Stride: 1},
+		{Lo: 0x0caa, Hi: 0x0cb3, Stride: 1},
+		{Lo: 0x0cb5, Hi: 0x0cb9, Stride: 1},
+		{Lo: 0x0cbd, Hi: 0x0cdd, Stride: 32},
+		{Lo: 0x0cde, Hi: 0x0ce0, Stride: 2},
+		{Lo: 0x0ce1, Hi: 0x0cf1, Stride: 16},
+		{Lo: 0x0cf2, Hi: 0x0d04, Stride: 18},
+		{Lo: 0x0d05, Hi: 0x0d0c, Stride: 1},
+		{Lo: 0x0d0e, Hi: 0x0d10, Stride: 1},
+		{Lo: 0x0d12, Hi: 0x0d3a, Stride: 1},
+		{Lo: 0x0d3d, Hi: 0x0d4e, Stride: 17},
+		{Lo: 0x0d54, Hi: 0x0d56, Stride: 1},
+		{Lo: 0x0d5f, Hi: 0x0d61, Stride: 1},
+		{Lo: 0x0d7a, Hi: 0x0d7f, Stride: 1},
+		{Lo: 0x0d85, Hi: 0x0d96, Stride: 1},
+		{Lo: 0x0d9a, Hi: 0x0db1, Stride: 1},
+		{Lo: 0x0db3, Hi: 0x0dbb, Stride: 1},
+		{Lo: 0x0dbd, Hi: 0x0dc0, Stride: 3},
+		{Lo: 0x0dc1, Hi: 0x0dc6, Stride: 1},
+		{Lo: 0x0e01, Hi: 0x0e30, Stride: 1},
+		{Lo: 0x0e32, Hi: 0x0e33, Stride: 1},
+		{Lo: 0x0e40, Hi: 0x0e45, Stride: 1},
+		{Lo: 0x0e81, Hi: 0x0e82, Stride: 1},
+		{Lo: 0x0e84, Hi: 0x0e86, Stride: 2},
+		{Lo: 0x0e87, Hi: 0x0e8a, Stride: 1},
+		{Lo: 0x0e8c, Hi: 0x0ea3, Stride: 1},
+		{Lo: 0x0ea5, Hi: 0x0ea7, Stride: 2},
+		{Lo: 0x0ea8, Hi: 0x0eb0, Stride: 1},
+		{Lo: 0x0eb2, Hi: 0x0eb3, Stride: 1},
+		{Lo: 0x0ebd, Hi: 0x0ec0, Stride: 3},
+		{Lo: 0x0ec1, Hi: 0x0ec4, Stride: 1},
+		{Lo: 0x0edc, Hi: 0x0edf, Stride: 1},
+		{Lo: 0x0f00, Hi: 0x0f40, Stride: 64},
+		{Lo: 0x0f41, Hi: 0x0f47, Stride: 1},
+		{Lo: 0x0f49, Hi: 0x0f6c, Stride: 1},
+		{Lo: 0x0f88, Hi: 0x0f8c, Stride: 1},
+		{Lo: 0x1000, Hi: 0x102a, Stride: 1},
+		{Lo: 0x103f, Hi: 0x1050, Stride: 17},
+		{Lo: 0x1051, Hi: 0x1055, Stride: 1},
+		{Lo: 0x105a, Hi: 0x105d, Stride: 1},
+		{Lo: 0x1061, Hi: 0x1065, Stride: 4},
+		{Lo: 0x1066, Hi: 0x106e, Stride: 8},
+		{Lo: 0x106f, Hi: 0x1070, Stride: 1},
+		{Lo: 0x1075, Hi: 0x1081, Stride: 1},
+		{Lo: 0x108e, Hi: 0x1100, Stride: 114},
+		{Lo: 0x1101, Hi: 0x1248, Stride: 1},
+		{Lo: 0x124a, Hi: 0x124d, Stride: 1},
+		{Lo: 0x1250, Hi: 0x1256, Stride: 1},
+		{Lo: 0x1258, Hi: 0x125a, Stride: 2},
+		{Lo: 0x125b, Hi: 0x125d, Stride: 1},
+		{Lo: 0x1260, Hi: 0x1288, Stride: 1},
+		{Lo: 0x128a, Hi: 0x128d, Stride: 1},
+		{Lo: 0x1290, Hi: 0x12b0, Stride: 1},
+		{Lo: 0x12b2, Hi: 0x12b5, Stride: 1},
+		{Lo: 0x12b8, Hi: 0x12be, Stride: 1},
+		{Lo: 0x12c0, Hi: 0x12c2, Stride: 2},
+		{Lo: 0x12c3, Hi: 0x12c5, Stride: 1},
+		{Lo: 0x12c8, Hi: 0x12d6, Stride: 1},
+		{Lo: 0x12d8, Hi: 0x1310, Stride: 1},
+		{Lo: 0x1312, Hi: 0x1315, Stride: 1},
+		{Lo: 0x1318, Hi: 0x135a, Stride: 1},
+		{Lo: 0x1380, Hi: 0x138f, Stride: 1},
+		{Lo: 0x1401, Hi: 0x166c, Stride: 1},
+		{Lo: 0x166f, Hi: 0x167f, Stride: 1},
+		{Lo: 0x1681, Hi: 0x169a, Stride: 1},
+		{Lo: 0x16a0, Hi: 0x16ea, Stride: 1},
+		{Lo: 0x16f1, Hi: 0x16f8, Stride: 1},
+		{Lo: 0x1700, Hi: 0x1711, Stride: 1},
+		{Lo: 0x171f, Hi: 0x1731, Stride: 1},
+		{Lo: 0x1740, Hi: 0x1751, Stride: 1},
+		{Lo: 0x1760, Hi: 0x176c, Stride: 1},
+		{Lo: 0x176e, Hi: 0x1770, Stride: 1},
+		{Lo: 0x1780, Hi: 0x17b3, Stride: 1},
+		{Lo: 0x17dc, Hi: 0x1820, Stride: 68},
+		{Lo: 0x1821, Hi: 0x1842, Stride: 1},
+		{Lo: 0x1844, Hi: 0x1878, Stride: 1},
+		{Lo: 0x1880, Hi: 0x1884, Stride: 1},
+		{Lo: 0x1887, Hi: 0x18a8, Stride: 1},
+		{Lo: 0x18aa, Hi: 0x18b0, Stride: 6},
+		{Lo: 0x18b1, Hi: 0x18f5, Stride: 1},
+		{Lo: 0x1900, Hi: 0x191e, Stride: 1},
+		{Lo: 0x1950, Hi: 0x196d, Stride: 1},
+		{Lo: 0x1970, Hi: 0x1974, Stride: 1},
+		{Lo: 0x1980, Hi: 0x19ab, Stride: 1},
+		{Lo: 0x19b0, Hi: 0x19c9, Stride: 1},
+		{Lo: 0x1a00, Hi: 0x1a16, Stride: 1},
+		{Lo: 0x1a20, Hi: 0x1a54, Stride: 1},
+		{Lo: 0x1b05, Hi: 0x1b33, Stride: 1},
+		{Lo: 0x1b45, Hi: 0x1b4c, Stride: 1},
+		{Lo: 0x1b83, Hi: 0x1ba0, Stride: 1},
+		{Lo: 0x1bae, Hi: 0x1baf, Stride: 1},
+		{Lo: 0x1bba, Hi: 0x1be5, Stride: 1},
+		{Lo: 0x1c00, Hi: 0x1c23, Stride: 1},
+		{Lo: 0x1c4d, Hi: 0x1c4f, Stride: 1},
+		{Lo: 0x1c5a, Hi: 0x1c77, Stride: 1},
+		{Lo: 0x1ce9, Hi: 0x1cec, Stride: 1},
+		{Lo: 0x1cee, Hi: 0x1cf3, Stride: 1},
+		{Lo: 0x1cf5, Hi: 0x1cf6, Stride: 1},
+		{Lo: 0x1cfa, Hi: 0x2135, Stride: 1083},
+		{Lo: 0x2136, Hi: 0x2138, Stride: 1},
+		{Lo: 0x2d30, Hi: 0x2d67, Stride: 1},
+		{Lo: 0x2d80, Hi: 0x2d96, Stride: 1},
+		{Lo: 0x2da0, Hi: 0x2da6, Stride: 1},
+		{Lo: 0x2da8, Hi: 0x2dae, Stride: 1},
+		{Lo: 0x2db0, Hi: 0x2db6, Stride: 1},
+		{Lo: 0x2db8, Hi: 0x2dbe, Stride: 1},
+		{Lo: 0x2dc0, Hi: 0x2dc6, Stride: 1},
+		{Lo: 0x2dc8, Hi: 0x2dce, Stride: 1},
+		{Lo: 0x2dd0, Hi: 0x2dd6, Stride: 1},
+		{Lo: 0x2dd8, Hi: 0x2dde, Stride: 1},
+		{Lo: 0x3006, Hi: 0x303c, Stride: 54},
+		{Lo: 0x3041, Hi: 0x3096, Stride: 1},
+		{Lo: 0x309f, Hi: 0x30a1, Stride: 2},
+		{Lo: 0x30a2, Hi: 0x30fa, Stride: 1},
+		{Lo: 0x30ff, Hi: 0x3105, Stride: 6},
+		{Lo: 0x3106, Hi: 0x312f, Stride: 1},
+		{Lo: 0x3131, Hi: 0x318e, Stride: 1},
+		{Lo: 0x31a0, Hi: 0x31bf, Stride: 1},
+		{Lo: 0x31f0, Hi: 0x31ff, Stride: 1},
+		{Lo: 0x3400, Hi: 0x4dbf, Stride: 6591},
+		{Lo: 0x4e00, Hi: 0x9fff, Stride: 20991},
+		{Lo: 0xa000, Hi: 0xa014, Stride: 1},
+		{Lo: 0xa016, Hi: 0xa48c, Stride: 1},
+		{Lo: 0xa4d0, Hi: 0xa4f7, Stride: 1},
+		{Lo: 0xa500, Hi: 0xa60b, Stride: 1},
+		{Lo: 0xa610, Hi: 0xa61f, Stride: 1},
+		{Lo: 0xa62a, Hi: 0xa62b, Stride: 1},
+		{Lo: 0xa66e, Hi: 0xa6a0, Stride: 50},
+		{Lo: 0xa6a1, Hi: 0xa6e5, Stride: 1},
+		{Lo: 0xa78f, Hi: 0xa7f7, Stride: 104},
+		{Lo: 0xa7fb, Hi: 0xa801, Stride: 1},
+		{Lo: 0xa803, Hi: 0xa805, Stride: 1},
+		{Lo: 0xa807, Hi: 0xa80a, Stride: 1},
+		{Lo: 0xa80c, Hi: 0xa822, Stride: 1},
+		{Lo: 0xa840, Hi: 0xa873, Stride: 1},
+		{Lo: 0xa882, Hi: 0xa8b3, Stride: 1},
+		{Lo: 0xa8f2, Hi: 0xa8f7, Stride: 1},
+		{Lo: 0xa8fb, Hi: 0xa8fd, Stride: 2},
+		{Lo: 0xa8fe, Hi: 0xa90a, Stride: 12},
+		{Lo: 0xa90b, Hi: 0xa925, Stride: 1},
+		{Lo: 0xa930, Hi: 0xa946, Stride: 1},
+		{Lo: 0xa960, Hi: 0xa97c, Stride: 1},
+		{Lo: 0xa984, Hi: 0xa9b2, Stride: 1},
+		{Lo: 0xa9e0, Hi: 0xa9e4, Stride: 1},
+		{Lo: 0xa9e7, Hi: 0xa9ef, Stride: 1},
+		{Lo: 0xa9fa, Hi: 0xa9fe, Stride: 1},
+		{Lo: 0xaa00, Hi: 0xaa28, Stride: 1},
+		{Lo: 0xaa40, Hi: 0xaa42, Stride: 1},
+		{Lo: 0xaa44, Hi: 0xaa4b, Stride: 1},
+		{Lo: 0xaa60, Hi: 0xaa6f, Stride: 1},
+		{Lo: 0xaa71, Hi: 0xaa76, Stride: 1},
+		{Lo: 0xaa7a, Hi: 0xaa7e, Stride: 4},
+		{Lo: 0xaa7f, Hi: 0xaaaf, Stride: 1},
+		{Lo: 0xaab1, Hi: 0xaab5, Stride: 4},
+		{Lo: 0xaab6, Hi: 0xaab9, Stride: 3},
+		{Lo: 0xaaba, Hi: 0xaabd, Stride: 1},
+		{Lo: 0xaac0, Hi: 0xaac2, Stride: 2},
+		{Lo: 0xaadb, Hi: 0xaadc, Stride: 1},
+		{Lo: 0xaae0, Hi: 0xaaea, Stride: 1},
+		{Lo: 0xaaf2, Hi: 0xab01, Stride: 15},
+		{Lo: 0xab02, Hi: 0xab06, Stride: 1},
+		{Lo: 0xab09, Hi: 0xab0e, Stride: 1},
+		{Lo: 0xab11, Hi: 0xab16, Stride: 1},
+		{Lo: 0xab20, Hi: 0xab26, Stride: 1},
+		{Lo: 0xab28, Hi: 0xab2e, Stride: 1},
+		{Lo: 0xabc0, Hi: 0xabe2, Stride: 1},
+		{Lo: 0xac00, Hi: 0xd7a3, Stride: 11171},
+		{Lo: 0xd7b0, Hi: 0xd7c6, Stride: 1},
+		{Lo: 0xd7cb, Hi: 0xd7fb, Stride: 1},
+		{Lo: 0xf900, Hi: 0xfa6d, Stride: 1},
+		{Lo: 0xfa70, Hi: 0xfad9, Stride: 1},
+		{Lo: 0xfb1d, Hi: 0xfb1f, Stride: 2},
+		{Lo: 0xfb20, Hi: 0xfb28, Stride: 1},
+		{Lo: 0xfb2a, Hi: 0xfb36, Stride: 1},
+		{Lo: 0xfb38, Hi: 0xfb3c, Stride: 1},
+		{Lo: 0xfb3e, Hi: 0xfb40, Stride: 2},
+		{Lo: 0xfb41, Hi: 0xfb43, Stride: 2},
+		{Lo: 0xfb44, Hi: 0xfb46, Stride: 2},
+		{Lo: 0xfb47, Hi: 0xfbb1, Stride: 1},
+		{Lo: 0xfbd3, Hi: 0xfd3d, Stride: 1},
+		{Lo: 0xfd50, Hi: 0xfd8f, Stride: 1},
+		{Lo: 0xfd92, Hi: 0xfdc7, Stride: 1},
+		{Lo: 0xfdf0, Hi: 0xfdfb, Stride: 1},
+		{Lo: 0xfe70, Hi: 0xfe74, Stride: 1},
+		{Lo: 0xfe76, Hi: 0xfefc, Stride: 1},
+		{Lo: 0xff66, Hi: 0xff6f, Stride: 1},
+		{Lo: 0xff71, Hi: 0xff9d, Stride: 1},
+		{Lo: 0xffa0, Hi: 0xffbe, Stride: 1},
+		{Lo: 0xffc2, Hi: 0xffc7, Stride: 1},
+		{Lo: 0xffca, Hi: 0xffcf, Stride: 1},
+		{Lo: 0xffd2, Hi: 0xffd7, Stride: 1},
+		{Lo: 0xffda, Hi: 0xffdc, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x10000, Hi: 0x1000b, Stride: 1},
+		{Lo: 0x1000d, Hi: 0x10026, Stride: 1},
+		{Lo: 0x10028, Hi: 0x1003a, Stride: 1},
+		{Lo: 0x1003c, Hi: 0x1003d, Stride: 1},
+		{Lo: 0x1003f, Hi: 0x1004d, Stride: 1},
+		{Lo: 0x10050, Hi: 0x1005d, Stride: 1},
+		{Lo: 0x10080, Hi: 0x100fa, Stride: 1},
+		{Lo: 0x10280, Hi: 0x1029c, Stride: 1},
+		{Lo: 0x102a0, Hi: 0x102d0, Stride: 1},
+		{Lo: 0x10300, Hi: 0x1031f, Stride: 1},
+		{Lo: 0x1032d, Hi: 0x10340, Stride: 1},
+		{Lo: 0x10342, Hi: 0x10349, Stride: 1},
+		{Lo: 0x10350, Hi: 0x10375, Stride: 1},
+		{Lo: 0x10380, Hi: 0x1039d, Stride: 1},
+		{Lo: 0x103a0, Hi: 0x103c3, Stride: 1},
+		{Lo: 0x103c8, Hi: 0x103cf, Stride: 1},
+		{Lo: 0x10450, Hi: 0x1049d, Stride: 1},
+		{Lo: 0x10500, Hi: 0x10527, Stride: 1},
+		{Lo: 0x10530, Hi: 0x10563, Stride: 1},
+		{Lo: 0x10600, Hi: 0x10736, Stride: 1},
+		{Lo: 0x10740, Hi: 0x10755, Stride: 1},
+		{Lo: 0x10760, Hi: 0x10767, Stride: 1},
+		{Lo: 0x10800, Hi: 0x10805, Stride: 1},
+		{Lo: 0x10808, Hi: 0x1080a, Stride: 2},
+		{Lo: 0x1080b, Hi: 0x10835, Stride: 1},
+		{Lo: 0x10837, Hi: 0x10838, Stride: 1},
+		{Lo: 0x1083c, Hi: 0x1083f, Stride: 3},
+		{Lo: 0x10840, Hi: 0x10855, Stride: 1},
+		{Lo: 0x10860, Hi: 0x10876, Stride: 1},
+		{Lo: 0x10880, Hi: 0x1089e, Stride: 1},
+		{Lo: 0x108e0, Hi: 0x108f2, Stride: 1},
+		{Lo: 0x108f4, Hi: 0x108f5, Stride: 1},
+		{Lo: 0x10900, Hi: 0x10915, Stride: 1},
+		{Lo: 0x10920, Hi: 0x10939, Stride: 1},
+		{Lo: 0x10980, Hi: 0x109b7, Stride: 1},
+		{Lo: 0x109be, Hi: 0x109bf, Stride: 1},
+		{Lo: 0x10a00, Hi: 0x10a10, Stride: 16},
+		{Lo: 0x10a11, Hi: 0x10a13, Stride: 1},
+		{Lo: 0x10a15, Hi: 0x10a17, Stride: 1},
+		{Lo: 0x10a19, Hi: 0x10a35, Stride: 1},
+		{Lo: 0x10a60, Hi: 0x10a7c, Stride: 1},
+		{Lo: 0x10a80, Hi: 0x10a9c, Stride: 1},
+		{Lo: 0x10ac0, Hi: 0x10ac7, Stride: 1},
+		{Lo: 0x10ac9, Hi: 0x10ae4, Stride: 1},
+		{Lo: 0x10b00, Hi: 0x10b35, Stride: 1},
+		{Lo: 0x10b40, Hi: 0x10b55, Stride: 1},
+		{Lo: 0x10b60, Hi: 0x10b72, Stride: 1},
+		{Lo: 0x10b80, Hi: 0x10b91, Stride: 1},
+		{Lo: 0x10c00, Hi: 0x10c48, Stride: 1},
+		{Lo: 0x10d00, Hi: 0x10d23, Stride: 1},
+		{Lo: 0x10e80, Hi: 0x10ea9, Stride: 1},
+		{Lo: 0x10eb0, Hi: 0x10eb1, Stride: 1},
+		{Lo: 0x10f00, Hi: 0x10f1c, Stride: 1},
+		{Lo: 0x10f27, Hi: 0x10f30, Stride: 9},
+		{Lo: 0x10f31, Hi: 0x10f45, Stride: 1},
+		{Lo: 0x10f70, Hi: 0x10f81, Stride: 1},
+		{Lo: 0x10fb0, Hi: 0x10fc4, Stride: 1},
+		{Lo: 0x10fe0, Hi: 0x10ff6, Stride: 1},
+		{Lo: 0x11003, Hi: 0x11037, Stride: 1},
+		{Lo: 0x11071, Hi: 0x11072, Stride: 1},
+		{Lo: 0x11075, Hi: 0x11083, Stride: 14},
+		{Lo: 0x11084, Hi: 0x110af, Stride: 1},
+		{Lo: 0x110d0, Hi: 0x110e8, Stride: 1},
+		{Lo: 0x11103, Hi: 0x11126, Stride: 1},
+		{Lo: 0x11144, Hi: 0x11147, Stride: 3},
+		{Lo: 0x11150, Hi: 0x11172, Stride: 1},
+		{Lo: 0x11176, Hi: 0x11183, Stride: 13},
+		{Lo: 0x11184, Hi: 0x111b2, Stride: 1},
+		{Lo: 0x111c1, Hi: 0x111c4, Stride: 1},
+		{Lo: 0x111da, Hi: 0x111dc, Stride: 2},
+		{Lo: 0x11200, Hi: 0x11211, Stride: 1},
+		{Lo: 0x11213, Hi: 0x1122b, Stride: 1},
+		{Lo: 0x1123f, Hi: 0x11240, Stride: 1},
+		{Lo: 0x11280, Hi: 0x11286, Stride: 1},
+		{Lo: 0x11288, Hi: 0x1128a, Stride: 2},
+		{Lo: 0x1128b, Hi: 0x1128d, Stride: 1},
+		{Lo: 0x1128f, Hi: 0x1129d, Stride: 1},
+		{Lo: 0x1129f, Hi: 0x112a8, Stride: 1},
+		{Lo: 0x112b0, Hi: 0x112de, Stride: 1},
+		{Lo: 0x11305, Hi: 0x1130c, Stride: 1},
+		{Lo: 0x1130f, Hi: 0x11310, Stride: 1},
+		{Lo: 0x11313, Hi: 0x11328, Stride: 1},
+		{Lo: 0x1132a, Hi: 0x11330, Stride: 1},
+		{Lo: 0x11332, Hi: 0x11333, Stride: 1},
+		{Lo: 0x11335, Hi: 0x11339, Stride: 1},
+		{Lo: 0x1133d, Hi: 0x11350, Stride: 19},
+		{Lo: 0x1135d, Hi: 0x11361, Stride: 1},
+		{Lo: 0x11400, Hi: 0x11434, Stride: 1},
+		{Lo: 0x11447, Hi: 0x1144a, Stride: 1},
+		{Lo: 0x1145f, Hi: 0x11461, Stride: 1},
+		{Lo: 0x11480, Hi: 0x114af, Stride: 1},
+		{Lo: 0x114c4, Hi: 0x114c5, Stride: 1},
+		{Lo: 0x114c7, Hi: 0x11580, Stride: 185},
+		{Lo: 0x11581, Hi: 0x115ae, Stride: 1},
+		{Lo: 0x115d8, Hi: 0x115db, Stride: 1},
+		{Lo: 0x11600, Hi: 0x1162f, Stride: 1},
+		{Lo: 0x11644, Hi: 0x11680, Stride: 60},
+		{Lo: 0x11681, Hi: 0x116aa, Stride: 1},
+		{Lo: 0x116b8, Hi: 0x11700, Stride: 72},
+		{Lo: 0x11701, Hi: 0x1171a, Stride: 1},
+		{Lo: 0x11740, Hi: 0x11746, Stride: 1},
+		{Lo: 0x11800, Hi: 0x1182b, Stride: 1},
+		{Lo: 0x118ff, Hi: 0x11906, Stride: 1},
+		{Lo: 0x11909, Hi: 0x1190c, Stride: 3},
+		{Lo: 0x1190d, Hi: 0x11913, Stride: 1},
+		{Lo: 0x11915, Hi: 0x11916, Stride: 1},
+		{Lo: 0x11918, Hi: 0x1192f, Stride: 1},
+		{Lo: 0x1193f, Hi: 0x11941, Stride: 2},
+		{Lo: 0x119a0, Hi: 0x119a7, Stride: 1},
+		{Lo: 0x119aa, Hi: 0x119d0, Stride: 1},
+		{Lo: 0x119e1, Hi: 0x119e3, Stride: 2},
+		{Lo: 0x11a00, Hi: 0x11a0b, Stride: 11},
+		{Lo: 0x11a0c, Hi: 0x11a32, Stride: 1},
+		{Lo: 0x11a3a, Hi: 0x11a50, Stride: 22},
+		{Lo: 0x11a5c, Hi: 0x11a89, Stride: 1},
+		{Lo: 0x11a9d, Hi: 0x11ab0, Stride: 19},
+		{Lo: 0x11ab1, Hi: 0x11af8, Stride: 1},
+		{Lo: 0x11c00, Hi: 0x11c08, Stride: 1},
+		{Lo: 0x11c0a, Hi: 0x11c2e, Stride: 1},
+		{Lo: 0x11c40, Hi: 0x11c72, Stride: 50},
+		{Lo: 0x11c73, Hi: 0x11c8f, Stride: 1},
+		{Lo: 0x11d00, Hi: 0x11d06, Stride: 1},
+		{Lo: 0x11d08, Hi: 0x11d09, Stride: 1},
+		{Lo: 0x11d0b, Hi: 0x11d30, Stride: 1},
+		{Lo: 0x11d46, Hi: 0x11d60, Stride: 26},
+		{Lo: 0x11d61, Hi: 0x11d65, Stride: 1},
+		{Lo: 0x11d67, Hi: 0x11d68, Stride: 1},
+		{Lo: 0x11d6a, Hi: 0x11d89, Stride: 1},
+		{Lo: 0x11d98, Hi: 0x11ee0, Stride: 328},
+		{Lo: 0x11ee1, Hi: 0x11ef2, Stride: 1},
+		{Lo: 0x11f02, Hi: 0x11f04, Stride: 2},
+		{Lo: 0x11f05, Hi: 0x11f10, Stride: 1},
+		{Lo: 0x11f12, Hi: 0x11f33, Stride: 1},
+		{Lo: 0x11fb0, Hi: 0x12000, Stride: 80},
+		{Lo: 0x12001, Hi: 0x12399, Stride: 1},
+		{Lo: 0x12480, Hi: 0x12543, Stride: 1},
+		{Lo: 0x12f90, Hi: 0x12ff0, Stride: 1},
+		{Lo: 0x13000, Hi: 0x1342f, Stride: 1},
+		{Lo: 0x13441, Hi: 0x13446, Stride: 1},
+		{Lo: 0x14400, Hi: 0x14646, Stride: 1},
+		{Lo: 0x16800, Hi: 0x16a38, Stride: 1},
+		{Lo: 0x16a40, Hi: 0x16a5e, Stride: 1},
+		{Lo: 0x16a70, Hi: 0x16abe, Stride: 1},
+		{Lo: 0x16ad0, Hi: 0x16aed, Stride: 1},
+		{Lo: 0x16b00, Hi: 0x16b2f, Stride: 1},
+		{Lo: 0x16b63, Hi: 0x16b77, Stride: 1},
+		{Lo: 0x16b7d, Hi: 0x16b8f, Stride: 1},
+		{Lo: 0x16f00, Hi: 0x16f4a, Stride: 1},
+		{Lo: 0x16f50, Hi: 0x17000, Stride: 176},
+		{Lo: 0x187f7, Hi: 0x18800, Stride: 9},
+		{Lo: 0x18801, Hi: 0x18cd5, Stride: 1},
+		{Lo: 0x18d00, Hi: 0x18d08, Stride: 8},
+		{Lo: 0x1b000, Hi: 0x1b122, Stride: 1},
+		{Lo: 0x1b132, Hi: 0x1b150, Stride: 30},
+		{Lo: 0x1b151, Hi: 0x1b152, Stride: 1},
+		{Lo: 0x1b155, Hi: 0x1b164, Stride: 15},
+		{Lo: 0x1b165, Hi: 0x1b167, Stride: 1},
+		{Lo: 0x1b170, Hi: 0x1b2fb, Stride: 1},
+		{Lo: 0x1bc00, Hi: 0x1bc6a, Stride: 1},
+		{Lo: 0x1bc70, Hi: 0x1bc7c, Stride: 1},
+		{Lo: 0x1bc80, Hi: 0x1bc88, Stride: 1},
+		{Lo: 0x1bc90, Hi: 0x1bc99, Stride: 1},
+		{Lo: 0x1df0a, Hi: 0x1e100, Stride: 502},
+		{Lo: 0x1e101, Hi: 0x1e12c, Stride: 1},
+		{Lo: 0x1e14e, Hi: 0x1e290, Stride: 322},
+		{Lo: 0x1e291, Hi: 0x1e2ad, Stride: 1},
+		{Lo: 0x1e2c0, Hi: 0x1e2eb, Stride: 1},
+		{Lo: 0x1e4d0, Hi: 0x1e4ea, Stride: 1},
+		{Lo: 0x1e7e0, Hi: 0x1e7e6, Stride: 1},
+		{Lo: 0x1e7e8, Hi: 0x1e7eb, Stride: 1},
+		{Lo: 0x1e7ed, Hi: 0x1e7ee, Stride: 1},
+		{Lo: 0x1e7f0, Hi: 0x1e7fe, Stride: 1},
+		{Lo: 0x1e800, Hi: 0x1e8c4, Stride: 1},
+		{Lo: 0x1ee00, Hi: 0x1ee03, Stride: 1},
+		{Lo: 0x1ee05, Hi: 0x1ee1f, Stride: 1},
+		{Lo: 0x1ee21, Hi: 0x1ee22, Stride: 1},
+		{Lo: 0x1ee24, Hi: 0x1ee27, Stride: 3},
+		{Lo: 0x1ee29, Hi: 0x1ee32, Stride: 1},
+		{Lo: 0x1ee34, Hi: 0x1ee37, Stride: 1},
+		{Lo: 0x1ee39, Hi: 0x1ee3b, Stride: 2},
+		{Lo: 0x1ee42, Hi: 0x1ee47, Stride: 5},
+		{Lo: 0x1ee49, Hi: 0x1ee4d, Stride: 2},
+		{Lo: 0x1ee4e, Hi: 0x1ee4f, Stride: 1},
+		{Lo: 0x1ee51, Hi: 0x1ee52, Stride: 1},
+		{Lo: 0x1ee54, Hi: 0x1ee57, Stride: 3},
+		{Lo: 0x1ee59, Hi: 0x1ee61, Stride: 2},
+		{Lo: 0x1ee62, Hi: 0x1ee64, Stride: 2},
+		{Lo: 0x1ee67, Hi: 0x1ee6a, Stride: 1},
+		{Lo: 0x1ee6c, Hi: 0x1ee72, Stride: 1},
+		{Lo: 0x1ee74, Hi: 0x1ee77, Stride: 1},
+		{Lo: 0x1ee79, Hi: 0x1ee7c, Stride: 1},
+		{Lo: 0x1ee7e, Hi: 0x1ee80, Stride: 2},
+		{Lo: 0x1ee81, Hi: 0x1ee89, Stride: 1},
+		{Lo: 0x1ee8b, Hi: 0x1ee9b, Stride: 1},
+		{Lo: 0x1eea1, Hi: 0x1eea3, Stride: 1},
+		{Lo: 0x1eea5, Hi: 0x1eea9, Stride: 1},
+		{Lo: 0x1eeab, Hi: 0x1eebb, Stride: 1},
+		{Lo: 0x20000, Hi: 0x2a6df, Stride: 42719},
+		{Lo: 0x2a700, Hi: 0x2b739, Stride: 4153},
+		{Lo: 0x2b740, Hi: 0x2b81d, Stride: 221},
+		{Lo: 0x2b820, Hi: 0x2cea1, Stride: 5761},
+		{Lo: 0x2ceb0, Hi: 0x2ebe0, Stride: 7472},
+		{Lo: 0x2f800, Hi: 0x2fa1d, Stride: 1},
+		{Lo: 0x30000, Hi: 0x3134a, Stride: 4938},
+		{Lo: 0x31350, Hi: 0x323af, Stride: 4191},
+	},
+	LatinOffset: 1,
+}
+
+var Lt = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x01c5, Hi: 0x01cb, Stride: 3},
+		{Lo: 0x01f2, Hi: 0x1f88, Stride: 7574},
+		{Lo: 0x1f89, Hi: 0x1f8f, Stride: 1},
+		{Lo: 0x1f98, Hi: 0x1f9f, Stride: 1},
+		{Lo: 0x1fa8, Hi: 0x1faf, Stride: 1},
+		{Lo: 0x1fbc, Hi: 0x1fcc, Stride: 16},
+		{Lo: 0x1ffc, Hi: 0x1ffc, Stride: 1},
+	},
+}
+
+var Lu = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x0041, Hi: 0x005a, Stride: 1},
+		{Lo: 0x00c0, Hi: 0x00d6, Stride: 1},
+		{Lo: 0x00d8, Hi: 0x00de, Stride: 1},
+		{Lo: 0x0100, Hi: 0x0136, Stride: 2},
+		{Lo: 0x0139, Hi: 0x0147, Stride: 2},
+		{Lo: 0x014a, Hi: 0x0178, Stride: 2},
+		{Lo: 0x0179, Hi: 0x017d, Stride: 2},
+		{Lo: 0x0181, Hi: 0x0182, Stride: 1},
+		{Lo: 0x0184, Hi: 0x0186, Stride: 2},
+		{Lo: 0x0187, Hi: 0x0189, Stride: 2},
+		{Lo: 0x018a, Hi: 0x018b, Stride: 1},
+		{Lo: 0x018e, Hi: 0x0191, Stride: 1},
+		{Lo: 0x0193, Hi: 0x0194, Stride: 1},
+		{Lo: 0x0196, Hi: 0x0198, Stride: 1},
+		{Lo: 0x019c, Hi: 0x019d, Stride: 1},
+		{Lo: 0x019f, Hi: 0x01a0, Stride: 1},
+		{Lo: 0x01a2, Hi: 0x01a6, Stride: 2},
+		{Lo: 0x01a7, Hi: 0x01a9, Stride: 2},
+		{Lo: 0x01ac, Hi: 0x01ae, Stride: 2},
+		{Lo: 0x01af, Hi: 0x01b1, Stride: 2},
+		{Lo: 0x01b2, Hi: 0x01b3, Stride: 1},
+		{Lo: 0x01b5, Hi: 0x01b7, Stride: 2},
+		{Lo: 0x01b8, Hi: 0x01bc, Stride: 4},
+		{Lo: 0x01c4, Hi: 0x01cd, Stride: 3},
+		{Lo: 0x01cf, Hi: 0x01db, Stride: 2},
+		{Lo: 0x01de, Hi: 0x01ee, Stride: 2},
+		{Lo: 0x01f1, Hi: 0x01f4, Stride: 3},
+		{Lo: 0x01f6, Hi: 0x01f8, Stride: 1},
+		{Lo: 0x01fa, Hi: 0x0232, Stride: 2},
+		{Lo: 0x023a, Hi: 0x023b, Stride: 1},
+		{Lo: 0x023d, Hi: 0x023e, Stride: 1},
+		{Lo: 0x0241, Hi: 0x0243, Stride: 2},
+		{Lo: 0x0244, Hi: 0x0246, Stride: 1},
+		{Lo: 0x0248, Hi: 0x024e, Stride: 2},
+		{Lo: 0x0370, Hi: 0x0372, Stride: 2},
+		{Lo: 0x0376, Hi: 0x037f, Stride: 9},
+		{Lo: 0x0386, Hi: 0x0388, Stride: 2},
+		{Lo: 0x0389, Hi: 0x038a, Stride: 1},
+		{Lo: 0x038c, Hi: 0x038e, Stride: 2},
+		{Lo: 0x038f, Hi: 0x0391, Stride: 2},
+		{Lo: 0x0392, Hi: 0x03a1, Stride: 1},
+		{Lo: 0x03a3, Hi: 0x03ab, Stride: 1},
+		{Lo: 0x03cf, Hi: 0x03d2, Stride: 3},
+		{Lo: 0x03d3, Hi: 0x03d4, Stride: 1},
+		{Lo: 0x03d8, Hi: 0x03ee, Stride: 2},
+		{Lo: 0x03f4, Hi: 0x03f7, Stride: 3},
+		{Lo: 0x03f9, Hi: 0x03fa, Stride: 1},
+		{Lo: 0x03fd, Hi: 0x042f, Stride: 1},
+		{Lo: 0x0460, Hi: 0x0480, Stride: 2},
+		{Lo: 0x048a, Hi: 0x04c0, Stride: 2},
+		{Lo: 0x04c1, Hi: 0x04cd, Stride: 2},
+		{Lo: 0x04d0, Hi: 0x052e, Stride: 2},
+		{Lo: 0x0531, Hi: 0x0556, Stride: 1},
+		{Lo: 0x10a0, Hi: 0x10c5, Stride: 1},
+		{Lo: 0x10c7, Hi: 0x10cd, Stride: 6},
+		{Lo: 0x13a0, Hi: 0x13f5, Stride: 1},
+		{Lo: 0x1c90, Hi: 0x1cba, Stride: 1},
+		{Lo: 0x1cbd, Hi: 0x1cbf, Stride: 1},
+		{Lo: 0x1e00, Hi: 0x1e94, Stride: 2},
+		{Lo: 0x1e9e, Hi: 0x1efe, Stride: 2},
+		{Lo: 0x1f08, Hi: 0x1f0f, Stride: 1},
+		{Lo: 0x1f18, Hi: 0x1f1d, Stride: 1},
+		{Lo: 0x1f28, Hi: 0x1f2f, Stride: 1},
+		{Lo: 0x1f38, Hi: 0x1f3f, Stride: 1},
+		{Lo: 0x1f48, Hi: 0x1f4d, Stride: 1},
+		{Lo: 0x1f59, Hi: 0x1f5f, Stride: 2},
+		{Lo: 0x1f68, Hi: 0x1f6f, Stride: 1},
+		{Lo: 0x1fb8, Hi: 0x1fbb, Stride: 1},
+		{Lo: 0x1fc8, Hi: 0x1fcb, Stride: 1},
+		{Lo: 0x1fd8, Hi: 0x1fdb, Stride: 1},
+		{Lo: 0x1fe8, Hi: 0x1fec, Stride: 1},
+		{Lo: 0x1ff8, Hi: 0x1ffb, Stride: 1},
+		{Lo: 0x2102, Hi: 0x2107, Stride: 5},
+		{Lo: 0x210b, Hi: 0x210d, Stride: 1},
+		{Lo: 0x2110, Hi: 0x2112, Stride: 1},
+		{Lo: 0x2115, Hi: 0x2119, Stride: 4},
+		{Lo: 0x211a, Hi: 0x211d, Stride: 1},
+		{Lo: 0x2124, Hi: 0x212a, Stride: 2},
+		{Lo: 0x212b, Hi: 0x212d, Stride: 1},
+		{Lo: 0x2130, Hi: 0x2133, Stride: 1},
+		{Lo: 0x213e, Hi: 0x213f, Stride: 1},
+		{Lo: 0x2145, Hi: 0x2183, Stride: 62},
+		{Lo: 0x2c00, Hi: 0x2c2f, Stride: 1},
+		{Lo: 0x2c60, Hi: 0x2c62, Stride: 2},
+		{Lo: 0x2c63, Hi: 0x2c64, Stride: 1},
+		{Lo: 0x2c67, Hi: 0x2c6d, Stride: 2},
+		{Lo: 0x2c6e, Hi: 0x2c70, Stride: 1},
+		{Lo: 0x2c72, Hi: 0x2c75, Stride: 3},
+		{Lo: 0x2c7e, Hi: 0x2c80, Stride: 1},
+		{Lo: 0x2c82, Hi: 0x2ce2, Stride: 2},
+		{Lo: 0x2ceb, Hi: 0x2ced, Stride: 2},
+		{Lo: 0x2cf2, Hi: 0xa640, Stride: 31054},
+		{Lo: 0xa642, Hi: 0xa66c, Stride: 2},
+		{Lo: 0xa680, Hi: 0xa69a, Stride: 2},
+		{Lo: 0xa722, Hi: 0xa72e, Stride: 2},
+		{Lo: 0xa732, Hi: 0xa76e, Stride: 2},
+		{Lo: 0xa779, Hi: 0xa77d, Stride: 2},
+		{Lo: 0xa77e, Hi: 0xa786, Stride: 2},
+		{Lo: 0xa78b, Hi: 0xa78d, Stride: 2},
+		{Lo: 0xa790, Hi: 0xa792, Stride: 2},
+		{Lo: 0xa796, Hi: 0xa7aa, Stride: 2},
+		{Lo: 0xa7ab, Hi: 0xa7ae, Stride: 1},
+		{Lo: 0xa7b0, Hi: 0xa7b4, Stride: 1},
+		{Lo: 0xa7b6, Hi: 0xa7c4, Stride: 2},
+		{Lo: 0xa7c5, Hi: 0xa7c7, Stride: 1},
+		{Lo: 0xa7c9, Hi: 0xa7d0, Stride: 7},
+		{Lo: 0xa7d6, Hi: 0xa7d8, Stride: 2},
+		{Lo: 0xa7f5, Hi: 0xff21, Stride: 22316},
+		{Lo: 0xff22, Hi: 0xff3a, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x10400, Hi: 0x10427, Stride: 1},
+		{Lo: 0x104b0, Hi: 0x104d3, Stride: 1},
+		{Lo: 0x10570, Hi: 0x1057a, Stride: 1},
+		{Lo: 0x1057c, Hi: 0x1058a, Stride: 1},
+		{Lo: 0x1058c, Hi: 0x10592, Stride: 1},
+		{Lo: 0x10594, Hi: 0x10595, Stride: 1},
+		{Lo: 0x10c80, Hi: 0x10cb2, Stride: 1},
+		{Lo: 0x118a0, Hi: 0x118bf, Stride: 1},
+		{Lo: 0x16e40, Hi: 0x16e5f, Stride: 1},
+		{Lo: 0x1d400, Hi: 0x1d419, Stride: 1},
+		{Lo: 0x1d434, Hi: 0x1d44d, Stride: 1},
+		{Lo: 0x1d468, Hi: 0x1d481, Stride: 1},
+		{Lo: 0x1d49c, Hi: 0x1d49e, Stride: 2},
+		{Lo: 0x1d49f, Hi: 0x1d4a5, Stride: 3},
+		{Lo: 0x1d4a6, Hi: 0x1d4a9, Stride: 3},
+		{Lo: 0x1d4aa, Hi: 0x1d4ac, Stride: 1},
+		{Lo: 0x1d4ae, Hi: 0x1d4b5, Stride: 1},
+		{Lo: 0x1d4d0, Hi: 0x1d4e9, Stride: 1},
+		{Lo: 0x1d504, Hi: 0x1d505, Stride: 1},
+		{Lo: 0x1d507, Hi: 0x1d50a, Stride: 1},
+		{Lo: 0x1d50d, Hi: 0x1d514, Stride: 1},
+		{Lo: 0x1d516, Hi: 0x1d51c, Stride: 1},
+		{Lo: 0x1d538, Hi: 0x1d539, Stride: 1},
+		{Lo: 0x1d53b, Hi: 0x1d53e, Stride: 1},
+		{Lo: 0x1d540, Hi: 0x1d544, Stride: 1},
+		{Lo: 0x1d546, Hi: 0x1d54a, Stride: 4},
+		{Lo: 0x1d54b, Hi: 0x1d550, Stride: 1},
+		{Lo: 0x1d56c, Hi: 0x1d585, Stride: 1},
+		{Lo: 0x1d5a0, Hi: 0x1d5b9, Stride: 1},
+		{Lo: 0x1d5d4, Hi: 0x1d5ed, Stride: 1},
+		{Lo: 0x1d608, Hi: 0x1d621, Stride: 1},
+		{Lo: 0x1d63c, Hi: 0x1d655, Stride: 1},
+		{Lo: 0x1d670, Hi: 0x1d689, Stride: 1},
+		{Lo: 0x1d6a8, Hi: 0x1d6c0, Stride: 1},
+		{Lo: 0x1d6e2, Hi: 0x1d6fa, Stride: 1},
+		{Lo: 0x1d71c, Hi: 0x1d734, Stride: 1},
+		{Lo: 0x1d756, Hi: 0x1d76e, Stride: 1},
+		{Lo: 0x1d790, Hi: 0x1d7a8, Stride: 1},
+		{Lo: 0x1d7ca, Hi: 0x1e900, Stride: 4406},
+		{Lo: 0x1e901, Hi: 0x1e921, Stride: 1},
+	},
+	LatinOffset: 3,
+}
+
+var Mc = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x0903, Hi: 0x093b, Stride: 56},
+		{Lo: 0x093e, Hi: 0x0940, Stride: 1},
+		{Lo: 0x0949, Hi: 0x094c, Stride: 1},
+		{Lo: 0x094e, Hi: 0x094f, Stride: 1},
+		{Lo: 0x0982, Hi: 0x0983, Stride: 1},
+		{Lo: 0x09be, Hi: 0x09c0, Stride: 1},
+		{Lo: 0x09c7, Hi: 0x09c8, Stride: 1},
+		{Lo: 0x09cb, Hi: 0x09cc, Stride: 1},
+		{Lo: 0x09d7, Hi: 0x0a03, Stride: 44},
+		{Lo: 0x0a3e, Hi: 0x0a40, Stride: 1},
+		{Lo: 0x0a83, Hi: 0x0abe, Stride: 59},
+		{Lo: 0x0abf, Hi: 0x0ac0, Stride: 1},
+		{Lo: 0x0ac9, Hi: 0x0acb, Stride: 2},
+		{Lo: 0x0acc, Hi: 0x0b02, Stride: 54},
+		{Lo: 0x0b03, Hi: 0x0b3e, Stride: 59},
+		{Lo: 0x0b40, Hi: 0x0b47, Stride: 7},
+		{Lo: 0x0b48, Hi: 0x0b4b, Stride: 3},
+		{Lo: 0x0b4c, Hi: 0x0b57, Stride: 11},
+		{Lo: 0x0bbe, Hi: 0x0bbf, Stride: 1},
+		{Lo: 0x0bc1, Hi: 0x0bc2, Stride: 1},
+		{Lo: 0x0bc6, Hi: 0x0bc8, Stride: 1},
+		{Lo: 0x0bca, Hi: 0x0bcc, Stride: 1},
+		{Lo: 0x0bd7, Hi: 0x0c01, Stride: 42},
+		{Lo: 0x0c02, Hi: 0x0c03, Stride: 1},
+		{Lo: 0x0c41, Hi: 0x0c44, Stride: 1},
+		{Lo: 0x0c82, Hi: 0x0c83, Stride: 1},
+		{Lo: 0x0cbe, Hi: 0x0cc0, Stride: 2},
+		{Lo: 0x0cc1, Hi: 0x0cc4, Stride: 1},
+		{Lo: 0x0cc7, Hi: 0x0cc8, Stride: 1},
+		{Lo: 0x0cca, Hi: 0x0ccb, Stride: 1},
+		{Lo: 0x0cd5, Hi: 0x0cd6, Stride: 1},
+		{Lo: 0x0cf3, Hi: 0x0d02, Stride: 15},
+		{Lo: 0x0d03, Hi: 0x0d3e, Stride: 59},
+		{Lo: 0x0d3f, Hi: 0x0d40, Stride: 1},
+		{Lo: 0x0d46, Hi: 0x0d48, Stride: 1},
+		{Lo: 0x0d4a, Hi: 0x0d4c, Stride: 1},
+		{Lo: 0x0d57, Hi: 0x0d82, Stride: 43},
+		{Lo: 0x0d83, Hi: 0x0dcf, Stride: 76},
+		{Lo: 0x0dd0, Hi: 0x0dd1, Stride: 1},
+		{Lo: 0x0dd8, Hi: 0x0ddf, Stride: 1},
+		{Lo: 0x0df2, Hi: 0x0df3, Stride: 1},
+		{Lo: 0x0f3e, Hi: 0x0f3f, Stride: 1},
+		{Lo: 0x0f7f, Hi: 0x102b, Stride: 172},
+		{Lo: 0x102c, Hi: 0x1031, Stride: 5},
+		{Lo: 0x1038, Hi: 0x103b, Stride: 3},
+		{Lo: 0x103c, Hi: 0x1056, Stride: 26},
+		{Lo: 0x1057, Hi: 0x1062, Stride: 11},
+		{Lo: 0x1063, Hi: 0x1064, Stride: 1},
+		{Lo: 0x1067, Hi: 0x106d, Stride: 1},
+		{Lo: 0x1083, Hi: 0x1084, Stride: 1},
+		{Lo: 0x1087, Hi: 0x108c, Stride: 1},
+		{Lo: 0x108f, Hi: 0x109a, Stride: 11},
+		{Lo: 0x109b, Hi: 0x109c, Stride: 1},
+		{Lo: 0x1715, Hi: 0x1734, Stride: 31},
+		{Lo: 0x17b6, Hi: 0x17be, Stride: 8},
+		{Lo: 0x17bf, Hi: 0x17c5, Stride: 1},
+		{Lo: 0x17c7, Hi: 0x17c8, Stride: 1},
+		{Lo: 0x1923, Hi: 0x1926, Stride: 1},
+		{Lo: 0x1929, Hi: 0x192b, Stride: 1},
+		{Lo: 0x1930, Hi: 0x1931, Stride: 1},
+		{Lo: 0x1933, Hi: 0x1938, Stride: 1},
+		{Lo: 0x1a19, Hi: 0x1a1a, Stride: 1},
+		{Lo: 0x1a55, Hi: 0x1a57, Stride: 2},
+		{Lo: 0x1a61, Hi: 0x1a63, Stride: 2},
+		{Lo: 0x1a64, Hi: 0x1a6d, Stride: 9},
+		{Lo: 0x1a6e, Hi: 0x1a72, Stride: 1},
+		{Lo: 0x1b04, Hi: 0x1b35, Stride: 49},
+		{Lo: 0x1b3b, Hi: 0x1b3d, Stride: 2},
+		{Lo: 0x1b3e, Hi: 0x1b41, Stride: 1},
+		{Lo: 0x1b43, Hi: 0x1b44, Stride: 1},
+		{Lo: 0x1b82, Hi: 0x1ba1, Stride: 31},
+		{Lo: 0x1ba6, Hi: 0x1ba7, Stride: 1},
+		{Lo: 0x1baa, Hi: 0x1be7, Stride: 61},
+		{Lo: 0x1bea, Hi: 0x1bec, Stride: 1},
+		{Lo: 0x1bee, Hi: 0x1bf2, Stride: 4},
+		{Lo: 0x1bf3, Hi: 0x1c24, Stride: 49},
+		{Lo: 0x1c25, Hi: 0x1c2b, Stride: 1},
+		{Lo: 0x1c34, Hi: 0x1c35, Stride: 1},
+		{Lo: 0x1ce1, Hi: 0x1cf7, Stride: 22},
+		{Lo: 0x302e, Hi: 0x302f, Stride: 1},
+		{Lo: 0xa823, Hi: 0xa824, Stride: 1},
+		{Lo: 0xa827, Hi: 0xa880, Stride: 89},
+		{Lo: 0xa881, Hi: 0xa8b4, Stride: 51},
+		{Lo: 0xa8b5, Hi: 0xa8c3, Stride: 1},
+		{Lo: 0xa952, Hi: 0xa953, Stride: 1},
+		{Lo: 0xa983, Hi: 0xa9b4, Stride: 49},
+		{Lo: 0xa9b5, Hi: 0xa9ba, Stride: 5},
+		{Lo: 0xa9bb, Hi: 0xa9be, Stride: 3},
+		{Lo: 0xa9bf, Hi: 0xa9c0, Stride: 1},
+		{Lo: 0xaa2f, Hi: 0xaa30, Stride: 1},
+		{Lo: 0xaa33, Hi: 0xaa34, Stride: 1},
+		{Lo: 0xaa4d, Hi: 0xaa7b, Stride: 46},
+		{Lo: 0xaa7d, Hi: 0xaaeb, Stride: 110},
+		{Lo: 0xaaee, Hi: 0xaaef, Stride: 1},
+		{Lo: 0xaaf5, Hi: 0xabe3, Stride: 238},
+		{Lo: 0xabe4, Hi: 0xabe6, Stride: 2},
+		{Lo: 0xabe7, Hi: 0xabe9, Stride: 2},
+		{Lo: 0xabea, Hi: 0xabec, Stride: 2},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x11000, Hi: 0x11002, Stride: 2},
+		{Lo: 0x11082, Hi: 0x110b0, Stride: 46},
+		{Lo: 0x110b1, Hi: 0x110b2, Stride: 1},
+		{Lo: 0x110b7, Hi: 0x110b8, Stride: 1},
+		{Lo: 0x1112c, Hi: 0x11145, Stride: 25},
+		{Lo: 0x11146, Hi: 0x11182, Stride: 60},
+		{Lo: 0x111b3, Hi: 0x111b5, Stride: 1},
+		{Lo: 0x111bf, Hi: 0x111c0, Stride: 1},
+		{Lo: 0x111ce, Hi: 0x1122c, Stride: 94},
+		{Lo: 0x1122d, Hi: 0x1122e, Stride: 1},
+		{Lo: 0x11232, Hi: 0x11233, Stride: 1},
+		{Lo: 0x11235, Hi: 0x112e0, Stride: 171},
+		{Lo: 0x112e1, Hi: 0x112e2, Stride: 1},
+		{Lo: 0x11302, Hi: 0x11303, Stride: 1},
+		{Lo: 0x1133e, Hi: 0x1133f, Stride: 1},
+		{Lo: 0x11341, Hi: 0x11344, Stride: 1},
+		{Lo: 0x11347, Hi: 0x11348, Stride: 1},
+		{Lo: 0x1134b, Hi: 0x1134d, Stride: 1},
+		{Lo: 0x11357, Hi: 0x11362, Stride: 11},
+		{Lo: 0x11363, Hi: 0x11435, Stride: 210},
+		{Lo: 0x11436, Hi: 0x11437, Stride: 1},
+		{Lo: 0x11440, Hi: 0x11441, Stride: 1},
+		{Lo: 0x11445, Hi: 0x114b0, Stride: 107},
+		{Lo: 0x114b1, Hi: 0x114b2, Stride: 1},
+		{Lo: 0x114b9, Hi: 0x114bb, Stride: 2},
+		{Lo: 0x114bc, Hi: 0x114be, Stride: 1},
+		{Lo: 0x114c1, Hi: 0x115af, Stride: 238},
+		{Lo: 0x115b0, Hi: 0x115b1, Stride: 1},
+		{Lo: 0x115b8, Hi: 0x115bb, Stride: 1},
+		{Lo: 0x115be, Hi: 0x11630, Stride: 114},
+		{Lo: 0x11631, Hi: 0x11632, Stride: 1},
+		{Lo: 0x1163b, Hi: 0x1163c, Stride: 1},
+		{Lo: 0x1163e, Hi: 0x116ac, Stride: 110},
+		{Lo: 0x116ae, Hi: 0x116af, Stride: 1},
+		{Lo: 0x116b6, Hi: 0x11720, Stride: 106},
+		{Lo: 0x11721, Hi: 0x11726, Stride: 5},
+		{Lo: 0x1182c, Hi: 0x1182e, Stride: 1},
+		{Lo: 0x11838, Hi: 0x11930, Stride: 248},
+		{Lo: 0x11931, Hi: 0x11935, Stride: 1},
+		{Lo: 0x11937, Hi: 0x11938, Stride: 1},
+		{Lo: 0x1193d, Hi: 0x11940, Stride: 3},
+		{Lo: 0x11942, Hi: 0x119d1, Stride: 143},
+		{Lo: 0x119d2, Hi: 0x119d3, Stride: 1},
+		{Lo: 0x119dc, Hi: 0x119df, Stride: 1},
+		{Lo: 0x119e4, Hi: 0x11a39, Stride: 85},
+		{Lo: 0x11a57, Hi: 0x11a58, Stride: 1},
+		{Lo: 0x11a97, Hi: 0x11c2f, Stride: 408},
+		{Lo: 0x11c3e, Hi: 0x11ca9, Stride: 107},
+		{Lo: 0x11cb1, Hi: 0x11cb4, Stride: 3},
+		{Lo: 0x11d8a, Hi: 0x11d8e, Stride: 1},
+		{Lo: 0x11d93, Hi: 0x11d94, Stride: 1},
+		{Lo: 0x11d96, Hi: 0x11ef5, Stride: 351},
+		{Lo: 0x11ef6, Hi: 0x11f03, Stride: 13},
+		{Lo: 0x11f34, Hi: 0x11f35, Stride: 1},
+		{Lo: 0x11f3e, Hi: 0x11f3f, Stride: 1},
+		{Lo: 0x11f41, Hi: 0x16f51, Stride: 20496},
+		{Lo: 0x16f52, Hi: 0x16f87, Stride: 1},
+		{Lo: 0x16ff0, Hi: 0x16ff1, Stride: 1},
+		{Lo: 0x1d165, Hi: 0x1d166, Stride: 1},
+		{Lo: 0x1d16d, Hi: 0x1d172, Stride: 1},
+	},
+}
+
+var Me = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x0488, Hi: 0x0489, Stride: 1},
+		{Lo: 0x1abe, Hi: 0x20dd, Stride: 1567},
+		{Lo: 0x20de, Hi: 0x20e0, Stride: 1},
+		{Lo: 0x20e2, Hi: 0x20e4, Stride: 1},
+		{Lo: 0xa670, Hi: 0xa672, Stride: 1},
+	},
+}
+
+var Mn = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x0300, Hi: 0x036f, Stride: 1},
+		{Lo: 0x0483, Hi: 0x0487, Stride: 1},
+		{Lo: 0x0591, Hi: 0x05bd, Stride: 1},
+		{Lo: 0x05bf, Hi: 0x05c1, Stride: 2},
+		{Lo: 0x05c2, Hi: 0x05c4, Stride: 2},
+		{Lo: 0x05c5, Hi: 0x05c7, Stride: 2},
+		{Lo: 0x0610, Hi: 0x061a, Stride: 1},
+		{Lo: 0x064b, Hi: 0x065f, Stride: 1},
+		{Lo: 0x0670, Hi: 0x06d6, Stride: 102},
+		{Lo: 0x06d7, Hi: 0x06dc, Stride: 1},
+		{Lo: 0x06df, Hi: 0x06e4, Stride: 1},
+		{Lo: 0x06e7, Hi: 0x06e8, Stride: 1},
+		{Lo: 0x06ea, Hi: 0x06ed, Stride: 1},
+		{Lo: 0x0711, Hi: 0x0730, Stride: 31},
+		{Lo: 0x0731, Hi: 0x074a, Stride: 1},
+		{Lo: 0x07a6, Hi: 0x07b0, Stride: 1},
+		{Lo: 0x07eb, Hi: 0x07f3, Stride: 1},
+		{Lo: 0x07fd, Hi: 0x0816, Stride: 25},
+		{Lo: 0x0817, Hi: 0x0819, Stride: 1},
+		{Lo: 0x081b, Hi: 0x0823, Stride: 1},
+		{Lo: 0x0825, Hi: 0x0827, Stride: 1},
+		{Lo: 0x0829, Hi: 0x082d, Stride: 1},
+		{Lo: 0x0859, Hi: 0x085b, Stride: 1},
+		{Lo: 0x0898, Hi: 0x089f, Stride: 1},
+		{Lo: 0x08ca, Hi: 0x08e1, Stride: 1},
+		{Lo: 0x08e3, Hi: 0x0902, Stride: 1},
+		{Lo: 0x093a, Hi: 0x093c, Stride: 2},
+		{Lo: 0x0941, Hi: 0x0948, Stride: 1},
+		{Lo: 0x094d, Hi: 0x0951, Stride: 4},
+		{Lo: 0x0952, Hi: 0x0957, Stride: 1},
+		{Lo: 0x0962, Hi: 0x0963, Stride: 1},
+		{Lo: 0x0981, Hi: 0x09bc, Stride: 59},
+		{Lo: 0x09c1, Hi: 0x09c4, Stride: 1},
+		{Lo: 0x09cd, Hi: 0x09e2, Stride: 21},
+		{Lo: 0x09e3, Hi: 0x09fe, Stride: 27},
+		{Lo: 0x0a01, Hi: 0x0a02, Stride: 1},
+		{Lo: 0x0a3c, Hi: 0x0a41, Stride: 5},
+		{Lo: 0x0a42, Hi: 0x0a47, Stride: 5},
+		{Lo: 0x0a48, Hi: 0x0a4b, Stride: 3},
+		{Lo: 0x0a4c, Hi: 0x0a4d, Stride: 1},
+		{Lo: 0x0a51, Hi: 0x0a70, Stride: 31},
+		{Lo: 0x0a71, Hi: 0x0a75, Stride: 4},
+		{Lo: 0x0a81, Hi: 0x0a82, Stride: 1},
+		{Lo: 0x0abc, Hi: 0x0ac1, Stride: 5},
+		{Lo: 0x0ac2, Hi: 0x0ac5, Stride: 1},
+		{Lo: 0x0ac7, Hi: 0x0ac8, Stride: 1},
+		{Lo: 0x0acd, Hi: 0x0ae2, Stride: 21},
+		{Lo: 0x0ae3, Hi: 0x0afa, Stride: 23},
+		{Lo: 0x0afb, Hi: 0x0aff, Stride: 1},
+		{Lo: 0x0b01, Hi: 0x0b3c, Stride: 59},
+		{Lo: 0x0b3f, Hi: 0x0b41, Stride: 2},
+		{Lo: 0x0b42, Hi: 0x0b44, Stride: 1},
+		{Lo: 0x0b4d, Hi: 0x0b55, Stride: 8},
+		{Lo: 0x0b56, Hi: 0x0b62, Stride: 12},
+		{Lo: 0x0b63, Hi: 0x0b82, Stride: 31},
+		{Lo: 0x0bc0, Hi: 0x0bcd, Stride: 13},
+		{Lo: 0x0c00, Hi: 0x0c04, Stride: 4},
+		{Lo: 0x0c3c, Hi: 0x0c3e, Stride: 2},
+		{Lo: 0x0c3f, Hi: 0x0c40, Stride: 1},
+		{Lo: 0x0c46, Hi: 0x0c48, Stride: 1},
+		{Lo: 0x0c4a, Hi: 0x0c4d, Stride: 1},
+		{Lo: 0x0c55, Hi: 0x0c56, Stride: 1},
+		{Lo: 0x0c62, Hi: 0x0c63, Stride: 1},
+		{Lo: 0x0c81, Hi: 0x0cbc, Stride: 59},
+		{Lo: 0x0cbf, Hi: 0x0cc6, Stride: 7},
+		{Lo: 0x0ccc, Hi: 0x0ccd, Stride: 1},
+		{Lo: 0x0ce2, Hi: 0x0ce3, Stride: 1},
+		{Lo: 0x0d00, Hi: 0x0d01, Stride: 1},
+		{Lo: 0x0d3b, Hi: 0x0d3c, Stride: 1},
+		{Lo: 0x0d41, Hi: 0x0d44, Stride: 1},
+		{Lo: 0x0d4d, Hi: 0x0d62, Stride: 21},
+		{Lo: 0x0d63, Hi: 0x0d81, Stride: 30},
+		{Lo: 0x0dca, Hi: 0x0dd2, Stride: 8},
+		{Lo: 0x0dd3, Hi: 0x0dd4, Stride: 1},
+		{Lo: 0x0dd6, Hi: 0x0e31, Stride: 91},
+		{Lo: 0x0e34, Hi: 0x0e3a, Stride: 1},
+		{Lo: 0x0e47, Hi: 0x0e4e, Stride: 1},
+		{Lo: 0x0eb1, Hi: 0x0eb4, Stride: 3},
+		{Lo: 0x0eb5, Hi: 0x0ebc, Stride: 1},
+		{Lo: 0x0ec8, Hi: 0x0ece, Stride: 1},
+		{Lo: 0x0f18, Hi: 0x0f19, Stride: 1},
+		{Lo: 0x0f35, Hi: 0x0f39, Stride: 2},
+		{Lo: 0x0f71, Hi: 0x0f7e, Stride: 1},
+		{Lo: 0x0f80, Hi: 0x0f84, Stride: 1},
+		{Lo: 0x0f86, Hi: 0x0f87, Stride: 1},
+		{Lo: 0x0f8d, Hi: 0x0f97, Stride: 1},
+		{Lo: 0x0f99, Hi: 0x0fbc, Stride: 1},
+		{Lo: 0x0fc6, Hi: 0x102d, Stride: 103},
+		{Lo: 0x102e, Hi: 0x1030, Stride: 1},
+		{Lo: 0x1032, Hi: 0x1037, Stride: 1},
+		{Lo: 0x1039, Hi: 0x103a, Stride: 1},
+		{Lo: 0x103d, Hi: 0x103e, Stride: 1},
+		{Lo: 0x1058, Hi: 0x1059, Stride: 1},
+		{Lo: 0x105e, Hi: 0x1060, Stride: 1},
+		{Lo: 0x1071, Hi: 0x1074, Stride: 1},
+		{Lo: 0x1082, Hi: 0x1085, Stride: 3},
+		{Lo: 0x1086, Hi: 0x108d, Stride: 7},
+		{Lo: 0x109d, Hi: 0x135d, Stride: 704},
+		{Lo: 0x135e, Hi: 0x135f, Stride: 1},
+		{Lo: 0x1712, Hi: 0x1714, Stride: 1},
+		{Lo: 0x1732, Hi: 0x1733, Stride: 1},
+		{Lo: 0x1752, Hi: 0x1753, Stride: 1},
+		{Lo: 0x1772, Hi: 0x1773, Stride: 1},
+		{Lo: 0x17b4, Hi: 0x17b5, Stride: 1},
+		{Lo: 0x17b7, Hi: 0x17bd, Stride: 1},
+		{Lo: 0x17c6, Hi: 0x17c9, Stride: 3},
+		{Lo: 0x17ca, Hi: 0x17d3, Stride: 1},
+		{Lo: 0x17dd, Hi: 0x180b, Stride: 46},
+		{Lo: 0x180c, Hi: 0x180d, Stride: 1},
+		{Lo: 0x180f, Hi: 0x1885, Stride: 118},
+		{Lo: 0x1886, Hi: 0x18a9, Stride: 35},
+		{Lo: 0x1920, Hi: 0x1922, Stride: 1},
+		{Lo: 0x1927, Hi: 0x1928, Stride: 1},
+		{Lo: 0x1932, Hi: 0x1939, Stride: 7},
+		{Lo: 0x193a, Hi: 0x193b, Stride: 1},
+		{Lo: 0x1a17, Hi: 0x1a18, Stride: 1},
+		{Lo: 0x1a1b, Hi: 0x1a56, Stride: 59},
+		{Lo: 0x1a58, Hi: 0x1a5e, Stride: 1},
+		{Lo: 0x1a60, Hi: 0x1a62, Stride: 2},
+		{Lo: 0x1a65, Hi: 0x1a6c, Stride: 1},
+		{Lo: 0x1a73, Hi: 0x1a7c, Stride: 1},
+		{Lo: 0x1a7f, Hi: 0x1ab0, Stride: 49},
+		{Lo: 0x1ab1, Hi: 0x1abd, Stride: 1},
+		{Lo: 0x1abf, Hi: 0x1ace, Stride: 1},
+		{Lo: 0x1b00, Hi: 0x1b03, Stride: 1},
+		{Lo: 0x1b34, Hi: 0x1b36, Stride: 2},
+		{Lo: 0x1b37, Hi: 0x1b3a, Stride: 1},
+		{Lo: 0x1b3c, Hi: 0x1b42, Stride: 6},
+		{Lo: 0x1b6b, Hi: 0x1b73, Stride: 1},
+		{Lo: 0x1b80, Hi: 0x1b81, Stride: 1},
+		{Lo: 0x1ba2, Hi: 0x1ba5, Stride: 1},
+		{Lo: 0x1ba8, Hi: 0x1ba9, Stride: 1},
+		{Lo: 0x1bab, Hi: 0x1bad, Stride: 1},
+		{Lo: 0x1be6, Hi: 0x1be8, Stride: 2},
+		{Lo: 0x1be9, Hi: 0x1bed, Stride: 4},
+		{Lo: 0x1bef, Hi: 0x1bf1, Stride: 1},
+		{Lo: 0x1c2c, Hi: 0x1c33, Stride: 1},
+		{Lo: 0x1c36, Hi: 0x1c37, Stride: 1},
+		{Lo: 0x1cd0, Hi: 0x1cd2, Stride: 1},
+		{Lo: 0x1cd4, Hi: 0x1ce0, Stride: 1},
+		{Lo: 0x1ce2, Hi: 0x1ce8, Stride: 1},
+		{Lo: 0x1ced, Hi: 0x1cf4, Stride: 7},
+		{Lo: 0x1cf8, Hi: 0x1cf9, Stride: 1},
+		{Lo: 0x1dc0, Hi: 0x1dff, Stride: 1},
+		{Lo: 0x20d0, Hi: 0x20dc, Stride: 1},
+		{Lo: 0x20e1, Hi: 0x20e5, Stride: 4},
+		{Lo: 0x20e6, Hi: 0x20f0, Stride: 1},
+		{Lo: 0x2cef, Hi: 0x2cf1, Stride: 1},
+		{Lo: 0x2d7f, Hi: 0x2de0, Stride: 97},
+		{Lo: 0x2de1, Hi: 0x2dff, Stride: 1},
+		{Lo: 0x302a, Hi: 0x302d, Stride: 1},
+		{Lo: 0x3099, Hi: 0x309a, Stride: 1},
+		{Lo: 0xa66f, Hi: 0xa674, Stride: 5},
+		{Lo: 0xa675, Hi: 0xa67d, Stride: 1},
+		{Lo: 0xa69e, Hi: 0xa69f, Stride: 1},
+		{Lo: 0xa6f0, Hi: 0xa6f1, Stride: 1},
+		{Lo: 0xa802, Hi: 0xa806, Stride: 4},
+		{Lo: 0xa80b, Hi: 0xa825, Stride: 26},
+		{Lo: 0xa826, Hi: 0xa82c, Stride: 6},
+		{Lo: 0xa8c4, Hi: 0xa8c5, Stride: 1},
+		{Lo: 0xa8e0, Hi: 0xa8f1, Stride: 1},
+		{Lo: 0xa8ff, Hi: 0xa926, Stride: 39},
+		{Lo: 0xa927, Hi: 0xa92d, Stride: 1},
+		{Lo: 0xa947, Hi: 0xa951, Stride: 1},
+		{Lo: 0xa980, Hi: 0xa982, Stride: 1},
+		{Lo: 0xa9b3, Hi: 0xa9b6, Stride: 3},
+		{Lo: 0xa9b7, Hi: 0xa9b9, Stride: 1},
+		{Lo: 0xa9bc, Hi: 0xa9bd, Stride: 1},
+		{Lo: 0xa9e5, Hi: 0xaa29, Stride: 68},
+		{Lo: 0xaa2a, Hi: 0xaa2e, Stride: 1},
+		{Lo: 0xaa31, Hi: 0xaa32, Stride: 1},
+		{Lo: 0xaa35, Hi: 0xaa36, Stride: 1},
+		{Lo: 0xaa43, Hi: 0xaa4c, Stride: 9},
+		{Lo: 0xaa7c, Hi: 0xaab0, Stride: 52},
+		{Lo: 0xaab2, Hi: 0xaab4, Stride: 1},
+		{Lo: 0xaab7, Hi: 0xaab8, Stride: 1},
+		{Lo: 0xaabe, Hi: 0xaabf, Stride: 1},
+		{Lo: 0xaac1, Hi: 0xaaec, Stride: 43},
+		{Lo: 0xaaed, Hi: 0xaaf6, Stride: 9},
+		{Lo: 0xabe5, Hi: 0xabe8, Stride: 3},
+		{Lo: 0xabed, Hi: 0xfb1e, Stride: 20273},
+		{Lo: 0xfe00, Hi: 0xfe0f, Stride: 1},
+		{Lo: 0xfe20, Hi: 0xfe2f, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x101fd, Hi: 0x102e0, Stride: 227},
+		{Lo: 0x10376, Hi: 0x1037a, Stride: 1},
+		{Lo: 0x10a01, Hi: 0x10a03, Stride: 1},
+		{Lo: 0x10a05, Hi: 0x10a06, Stride: 1},
+		{Lo: 0x10a0c, Hi: 0x10a0f, Stride: 1},
+		{Lo: 0x10a38, Hi: 0x10a3a, Stride: 1},
+		{Lo: 0x10a3f, Hi: 0x10ae5, Stride: 166},
+		{Lo: 0x10ae6, Hi: 0x10d24, Stride: 574},
+		{Lo: 0x10d25, Hi: 0x10d27, Stride: 1},
+		{Lo: 0x10eab, Hi: 0x10eac, Stride: 1},
+		{Lo: 0x10efd, Hi: 0x10eff, Stride: 1},
+		{Lo: 0x10f46, Hi: 0x10f50, Stride: 1},
+		{Lo: 0x10f82, Hi: 0x10f85, Stride: 1},
+		{Lo: 0x11001, Hi: 0x11038, Stride: 55},
+		{Lo: 0x11039, Hi: 0x11046, Stride: 1},
+		{Lo: 0x11070, Hi: 0x11073, Stride: 3},
+		{Lo: 0x11074, Hi: 0x1107f, Stride: 11},
+		{Lo: 0x11080, Hi: 0x11081, Stride: 1},
+		{Lo: 0x110b3, Hi: 0x110b6, Stride: 1},
+		{Lo: 0x110b9, Hi: 0x110ba, Stride: 1},
+		{Lo: 0x110c2, Hi: 0x11100, Stride: 62},
+		{Lo: 0x11101, Hi: 0x11102, Stride: 1},
+		{Lo: 0x11127, Hi: 0x1112b, Stride: 1},
+		{Lo: 0x1112d, Hi: 0x11134, Stride: 1},
+		{Lo: 0x11173, Hi: 0x11180, Stride: 13},
+		{Lo: 0x11181, Hi: 0x111b6, Stride: 53},
+		{Lo: 0x111b7, Hi: 0x111be, Stride: 1},
+		{Lo: 0x111c9, Hi: 0x111cc, Stride: 1},
+		{Lo: 0x111cf, Hi: 0x1122f, Stride: 96},
+		{Lo: 0x11230, Hi: 0x11231, Stride: 1},
+		{Lo: 0x11234, Hi: 0x11236, Stride: 2},
+		{Lo: 0x11237, Hi: 0x1123e, Stride: 7},
+		{Lo: 0x11241, Hi: 0x112df, Stride: 158},
+		{Lo: 0x112e3, Hi: 0x112ea, Stride: 1},
+		{Lo: 0x11300, Hi: 0x11301, Stride: 1},
+		{Lo: 0x1133b, Hi: 0x1133c, Stride: 1},
+		{Lo: 0x11340, Hi: 0x11366, Stride: 38},
+		{Lo: 0x11367, Hi: 0x1136c, Stride: 1},
+		{Lo: 0x11370, Hi: 0x11374, Stride: 1},
+		{Lo: 0x11438, Hi: 0x1143f, Stride: 1},
+		{Lo: 0x11442, Hi: 0x11444, Stride: 1},
+		{Lo: 0x11446, Hi: 0x1145e, Stride: 24},
+		{Lo: 0x114b3, Hi: 0x114b8, Stride: 1},
+		{Lo: 0x114ba, Hi: 0x114bf, Stride: 5},
+		{Lo: 0x114c0, Hi: 0x114c2, Stride: 2},
+		{Lo: 0x114c3, Hi: 0x115b2, Stride: 239},
+		{Lo: 0x115b3, Hi: 0x115b5, Stride: 1},
+		{Lo: 0x115bc, Hi: 0x115bd, Stride: 1},
+		{Lo: 0x115bf, Hi: 0x115c0, Stride: 1},
+		{Lo: 0x115dc, Hi: 0x115dd, Stride: 1},
+		{Lo: 0x11633, Hi: 0x1163a, Stride: 1},
+		{Lo: 0x1163d, Hi: 0x1163f, Stride: 2},
+		{Lo: 0x11640, Hi: 0x116ab, Stride: 107},
+		{Lo: 0x116ad, Hi: 0x116b0, Stride: 3},
+		{Lo: 0x116b1, Hi: 0x116b5, Stride: 1},
+		{Lo: 0x116b7, Hi: 0x1171d, Stride: 102},
+		{Lo: 0x1171e, Hi: 0x1171f, Stride: 1},
+		{Lo: 0x11722, Hi: 0x11725, Stride: 1},
+		{Lo: 0x11727, Hi: 0x1172b, Stride: 1},
+		{Lo: 0x1182f, Hi: 0x11837, Stride: 1},
+		{Lo: 0x11839, Hi: 0x1183a, Stride: 1},
+		{Lo: 0x1193b, Hi: 0x1193c, Stride: 1},
+		{Lo: 0x1193e, Hi: 0x11943, Stride: 5},
+		{Lo: 0x119d4, Hi: 0x119d7, Stride: 1},
+		{Lo: 0x119da, Hi: 0x119db, Stride: 1},
+		{Lo: 0x119e0, Hi: 0x11a01, Stride: 33},
+		{Lo: 0x11a02, Hi: 0x11a0a, Stride: 1},
+		{Lo: 0x11a33, Hi: 0x11a38, Stride: 1},
+		{Lo: 0x11a3b, Hi: 0x11a3e, Stride: 1},
+		{Lo: 0x11a47, Hi: 0x11a51, Stride: 10},
+		{Lo: 0x11a52, Hi: 0x11a56, Stride: 1},
+		{Lo: 0x11a59, Hi: 0x11a5b, Stride: 1},
+		{Lo: 0x11a8a, Hi: 0x11a96, Stride: 1},
+		{Lo: 0x11a98, Hi: 0x11a99, Stride: 1},
+		{Lo: 0x11c30, Hi: 0x11c36, Stride: 1},
+		{Lo: 0x11c38, Hi: 0x11c3d, Stride: 1},
+		{Lo: 0x11c3f, Hi: 0x11c92, Stride: 83},
+		{Lo: 0x11c93, Hi: 0x11ca7, Stride: 1},
+		{Lo: 0x11caa, Hi: 0x11cb0, Stride: 1},
+		{Lo: 0x11cb2, Hi: 0x11cb3, Stride: 1},
+		{Lo: 0x11cb5, Hi: 0x11cb6, Stride: 1},
+		{Lo: 0x11d31, Hi: 0x11d36, Stride: 1},
+		{Lo: 0x11d3a, Hi: 0x11d3c, Stride: 2},
+		{Lo: 0x11d3d, Hi: 0x11d3f, Stride: 2},
+		{Lo: 0x11d40, Hi: 0x11d45, Stride: 1},
+		{Lo: 0x11d47, Hi: 0x11d90, Stride: 73},
+		{Lo: 0x11d91, Hi: 0x11d95, Stride: 4},
+		{Lo: 0x11d97, Hi: 0x11ef3, Stride: 348},
+		{Lo: 0x11ef4, Hi: 0x11f00, Stride: 12},
+		{Lo: 0x11f01, Hi: 0x11f36, Stride: 53},
+		{Lo: 0x11f37, Hi: 0x11f3a, Stride: 1},
+		{Lo: 0x11f40, Hi: 0x11f42, Stride: 2},
+		{Lo: 0x13440, Hi: 0x13447, Stride: 7},
+		{Lo: 0x13448, Hi: 0x13455, Stride: 1},
+		{Lo: 0x16af0, Hi: 0x16af4, Stride: 1},
+		{Lo: 0x16b30, Hi: 0x16b36, Stride: 1},
+		{Lo: 0x16f4f, Hi: 0x16f8f, Stride: 64},
+		{Lo: 0x16f90, Hi: 0x16f92, Stride: 1},
+		{Lo: 0x16fe4, Hi: 0x1bc9d, Stride: 19641},
+		{Lo: 0x1bc9e, Hi: 0x1cf00, Stride: 4706},
+		{Lo: 0x1cf01, Hi: 0x1cf2d, Stride: 1},
+		{Lo: 0x1cf30, Hi: 0x1cf46, Stride: 1},
+		{Lo: 0x1d167, Hi: 0x1d169, Stride: 1},
+		{Lo: 0x1d17b, Hi: 0x1d182, Stride: 1},
+		{Lo: 0x1d185, Hi: 0x1d18b, Stride: 1},
+		{Lo: 0x1d1aa, Hi: 0x1d1ad, Stride: 1},
+		{Lo: 0x1d242, Hi: 0x1d244, Stride: 1},
+		{Lo: 0x1da00, Hi: 0x1da36, Stride: 1},
+		{Lo: 0x1da3b, Hi: 0x1da6c, Stride: 1},
+		{Lo: 0x1da75, Hi: 0x1da84, Stride: 15},
+		{Lo: 0x1da9b, Hi: 0x1da9f, Stride: 1},
+		{Lo: 0x1daa1, Hi: 0x1daaf, Stride: 1},
+		{Lo: 0x1e000, Hi: 0x1e006, Stride: 1},
+		{Lo: 0x1e008, Hi: 0x1e018, Stride: 1},
+		{Lo: 0x1e01b, Hi: 0x1e021, Stride: 1},
+		{Lo: 0x1e023, Hi: 0x1e024, Stride: 1},
+		{Lo: 0x1e026, Hi: 0x1e02a, Stride: 1},
+		{Lo: 0x1e08f, Hi: 0x1e130, Stride: 161},
+		{Lo: 0x1e131, Hi: 0x1e136, Stride: 1},
+		{Lo: 0x1e2ae, Hi: 0x1e2ec, Stride: 62},
+		{Lo: 0x1e2ed, Hi: 0x1e2ef, Stride: 1},
+		{Lo: 0x1e4ec, Hi: 0x1e4ef, Stride: 1},
+		{Lo: 0x1e8d0, Hi: 0x1e8d6, Stride: 1},
+		{Lo: 0x1e944, Hi: 0x1e94a, Stride: 1},
+		{Lo: 0xe0100, Hi: 0xe01ef, Stride: 1},
+	},
+}
+
+var Nd = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x0030, Hi: 0x0039, Stride: 1},
+		{Lo: 0x0660, Hi: 0x0669, Stride: 1},
+		{Lo: 0x06f0, Hi: 0x06f9, Stride: 1},
+		{Lo: 0x07c0, Hi: 0x07c9, Stride: 1},
+		{Lo: 0x0966, Hi: 0x096f, Stride: 1},
+		{Lo: 0x09e6, Hi: 0x09ef, Stride: 1},
+		{Lo: 0x0a66, Hi: 0x0a6f, Stride: 1},
+		{Lo: 0x0ae6, Hi: 0x0aef, Stride: 1},
+		{Lo: 0x0b66, Hi: 0x0b6f, Stride: 1},
+		{Lo: 0x0be6, Hi: 0x0bef, Stride: 1},
+		{Lo: 0x0c66, Hi: 0x0c6f, Stride: 1},
+		{Lo: 0x0ce6, Hi: 0x0cef, Stride: 1},
+		{Lo: 0x0d66, Hi: 0x0d6f, Stride: 1},
+		{Lo: 0x0de6, Hi: 0x0def, Stride: 1},
+		{Lo: 0x0e50, Hi: 0x0e59, Stride: 1},
+		{Lo: 0x0ed0, Hi: 0x0ed9, Stride: 1},
+		{Lo: 0x0f20, Hi: 0x0f29, Stride: 1},
+		{Lo: 0x1040, Hi: 0x1049, Stride: 1},
+		{Lo: 0x1090, Hi: 0x1099, Stride: 1},
+		{Lo: 0x17e0, Hi: 0x17e9, Stride: 1},
+		{Lo: 0x1810, Hi: 0x1819, Stride: 1},
+		{Lo: 0x1946, Hi: 0x194f, Stride: 1},
+		{Lo: 0x19d0, Hi: 0x19d9, Stride: 1},
+		{Lo: 0x1a80, Hi: 0x1a89, Stride: 1},
+		{Lo: 0x1a90, Hi: 0x1a99, Stride: 1},
+		{Lo: 0x1b50, Hi: 0x1b59, Stride: 1},
+		{Lo: 0x1bb0, Hi: 0x1bb9, Stride: 1},
+		{Lo: 0x1c40, Hi: 0x1c49, Stride: 1},
+		{Lo: 0x1c50, Hi: 0x1c59, Stride: 1},
+		{Lo: 0xa620, Hi: 0xa629, Stride: 1},
+		{Lo: 0xa8d0, Hi: 0xa8d9, Stride: 1},
+		{Lo: 0xa900, Hi: 0xa909, Stride: 1},
+		{Lo: 0xa9d0, Hi: 0xa9d9, Stride: 1},
+		{Lo: 0xa9f0, Hi: 0xa9f9, Stride: 1},
+		{Lo: 0xaa50, Hi: 0xaa59, Stride: 1},
+		{Lo: 0xabf0, Hi: 0xabf9, Stride: 1},
+		{Lo: 0xff10, Hi: 0xff19, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x104a0, Hi: 0x104a9, Stride: 1},
+		{Lo: 0x10d30, Hi: 0x10d39, Stride: 1},
+		{Lo: 0x11066, Hi: 0x1106f, Stride: 1},
+		{Lo: 0x110f0, Hi: 0x110f9, Stride: 1},
+		{Lo: 0x11136, Hi: 0x1113f, Stride: 1},
+		{Lo: 0x111d0, Hi: 0x111d9, Stride: 1},
+		{Lo: 0x112f0, Hi: 0x112f9, Stride: 1},
+		{Lo: 0x11450, Hi: 0x11459, Stride: 1},
+		{Lo: 0x114d0, Hi: 0x114d9, Stride: 1},
+		{Lo: 0x11650, Hi: 0x11659, Stride: 1},
+		{Lo: 0x116c0, Hi: 0x116c9, Stride: 1},
+		{Lo: 0x11730, Hi: 0x11739, Stride: 1},
+		{Lo: 0x118e0, Hi: 0x118e9, Stride: 1},
+		{Lo: 0x11950, Hi: 0x11959, Stride: 1},
+		{Lo: 0x11c50, Hi: 0x11c59, Stride: 1},
+		{Lo: 0x11d50, Hi: 0x11d59, Stride: 1},
+		{Lo: 0x11da0, Hi: 0x11da9, Stride: 1},
+		{Lo: 0x11f50, Hi: 0x11f59, Stride: 1},
+		{Lo: 0x16a60, Hi: 0x16a69, Stride: 1},
+		{Lo: 0x16ac0, Hi: 0x16ac9, Stride: 1},
+		{Lo: 0x16b50, Hi: 0x16b59, Stride: 1},
+		{Lo: 0x1d7ce, Hi: 0x1d7ff, Stride: 1},
+		{Lo: 0x1e140, Hi: 0x1e149, Stride: 1},
+		{Lo: 0x1e2f0, Hi: 0x1e2f9, Stride: 1},
+		{Lo: 0x1e4f0, Hi: 0x1e4f9, Stride: 1},
+		{Lo: 0x1e950, Hi: 0x1e959, Stride: 1},
+		{Lo: 0x1fbf0, Hi: 0x1fbf9, Stride: 1},
+	},
+	LatinOffset: 1,
+}
+
+var Nl = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x16ee, Hi: 0x16f0, Stride: 1},
+		{Lo: 0x2160, Hi: 0x2182, Stride: 1},
+		{Lo: 0x2185, Hi: 0x2188, Stride: 1},
+		{Lo: 0x3007, Hi: 0x3021, Stride: 26},
+		{Lo: 0x3022, Hi: 0x3029, Stride: 1},
+		{Lo: 0x3038, Hi: 0x303a, Stride: 1},
+		{Lo: 0xa6e6, Hi: 0xa6ef, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x10140, Hi: 0x10174, Stride: 1},
+		{Lo: 0x10341, Hi: 0x1034a, Stride: 9},
+		{Lo: 0x103d1, Hi: 0x103d5, Stride: 1},
+		{Lo: 0x12400, Hi: 0x1246e, Stride: 1},
+	},
+}
+
+var No = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x00b2, Hi: 0x00b3, Stride: 1},
+		{Lo: 0x00b9, Hi: 0x00bc, Stride: 3},
+		{Lo: 0x00bd, Hi: 0x00be, Stride: 1},
+		{Lo: 0x09f4, Hi: 0x09f9, Stride: 1},
+		{Lo: 0x0b72, Hi: 0x0b77, Stride: 1},
+		{Lo: 0x0bf0, Hi: 0x0bf2, Stride: 1},
+		{Lo: 0x0c78, Hi: 0x0c7e, Stride: 1},
+		{Lo: 0x0d58, Hi: 0x0d5e, Stride: 1},
+		{Lo: 0x0d70, Hi: 0x0d78, Stride: 1},
+		{Lo: 0x0f2a, Hi: 0x0f33, Stride: 1},
+		{Lo: 0x1369, Hi: 0x137c, Stride: 1},
+		{Lo: 0x17f0, Hi: 0x17f9, Stride: 1},
+		{Lo: 0x19da, Hi: 0x2070, Stride: 1686},
+		{Lo: 0x2074, Hi: 0x2079, Stride: 1},
+		{Lo: 0x2080, Hi: 0x2089, Stride: 1},
+		{Lo: 0x2150, Hi: 0x215f, Stride: 1},
+		{Lo: 0x2189, Hi: 0x2460, Stride: 727},
+		{Lo: 0x2461, Hi: 0x249b, Stride: 1},
+		{Lo: 0x24ea, Hi: 0x24ff, Stride: 1},
+		{Lo: 0x2776, Hi: 0x2793, Stride: 1},
+		{Lo: 0x2cfd, Hi: 0x3192, Stride: 1173},
+		{Lo: 0x3193, Hi: 0x3195, Stride: 1},
+		{Lo: 0x3220, Hi: 0x3229, Stride: 1},
+		{Lo: 0x3248, Hi: 0x324f, Stride: 1},
+		{Lo: 0x3251, Hi: 0x325f, Stride: 1},
+		{Lo: 0x3280, Hi: 0x3289, Stride: 1},
+		{Lo: 0x32b1, Hi: 0x32bf, Stride: 1},
+		{Lo: 0xa830, Hi: 0xa835, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x10107, Hi: 0x10133, Stride: 1},
+		{Lo: 0x10175, Hi: 0x10178, Stride: 1},
+		{Lo: 0x1018a, Hi: 0x1018b, Stride: 1},
+		{Lo: 0x102e1, Hi: 0x102fb, Stride: 1},
+		{Lo: 0x10320, Hi: 0x10323, Stride: 1},
+		{Lo: 0x10858, Hi: 0x1085f, Stride: 1},
+		{Lo: 0x10879, Hi: 0x1087f, Stride: 1},
+		{Lo: 0x108a7, Hi: 0x108af, Stride: 1},
+		{Lo: 0x108fb, Hi: 0x108ff, Stride: 1},
+		{Lo: 0x10916, Hi: 0x1091b, Stride: 1},
+		{Lo: 0x109bc, Hi: 0x109bd, Stride: 1},
+		{Lo: 0x109c0, Hi: 0x109cf, Stride: 1},
+		{Lo: 0x109d2, Hi: 0x109ff, Stride: 1},
+		{Lo: 0x10a40, Hi: 0x10a48, Stride: 1},
+		{Lo: 0x10a7d, Hi: 0x10a7e, Stride: 1},
+		{Lo: 0x10a9d, Hi: 0x10a9f, Stride: 1},
+		{Lo: 0x10aeb, Hi: 0x10aef, Stride: 1},
+		{Lo: 0x10b58, Hi: 0x10b5f, Stride: 1},
+		{Lo: 0x10b78, Hi: 0x10b7f, Stride: 1},
+		{Lo: 0x10ba9, Hi: 0x10baf, Stride: 1},
+		{Lo: 0x10cfa, Hi: 0x10cff, Stride: 1},
+		{Lo: 0x10e60, Hi: 0x10e7e, Stride: 1},
+		{Lo: 0x10f1d, Hi: 0x10f26, Stride: 1},
+		{Lo: 0x10f51, Hi: 0x10f54, Stride: 1},
+		{Lo: 0x10fc5, Hi: 0x10fcb, Stride: 1},
+		{Lo: 0x11052, Hi: 0x11065, Stride: 1},
+		{Lo: 0x111e1, Hi: 0x111f4, Stride: 1},
+		{Lo: 0x1173a, Hi: 0x1173b, Stride: 1},
+		{Lo: 0x118ea, Hi: 0x118f2, Stride: 1},
+		{Lo: 0x11c5a, Hi: 0x11c6c, Stride: 1},
+		{Lo: 0x11fc0, Hi: 0x11fd4, Stride: 1},
+		{Lo: 0x16b5b, Hi: 0x16b61, Stride: 1},
+		{Lo: 0x16e80, Hi: 0x16e96, Stride: 1},
+		{Lo: 0x1d2c0, Hi: 0x1d2d3, Stride: 1},
+		{Lo: 0x1d2e0, Hi: 0x1d2f3, Stride: 1},
+		{Lo: 0x1d360, Hi: 0x1d378, Stride: 1},
+		{Lo: 0x1e8c7, Hi: 0x1e8cf, Stride: 1},
+		{Lo: 0x1ec71, Hi: 0x1ecab, Stride: 1},
+		{Lo: 0x1ecad, Hi: 0x1ecaf, Stride: 1},
+		{Lo: 0x1ecb1, Hi: 0x1ecb4, Stride: 1},
+		{Lo: 0x1ed01, Hi: 0x1ed2d, Stride: 1},
+		{Lo: 0x1ed2f, Hi: 0x1ed3d, Stride: 1},
+		{Lo: 0x1f100, Hi: 0x1f10c, Stride: 1},
+	},
+	LatinOffset: 3,
+}
+
+var Pc = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x005f, Hi: 0x203f, Stride: 8160},
+		{Lo: 0x2040, Hi: 0x2054, Stride: 20},
+		{Lo: 0xfe33, Hi: 0xfe34, Stride: 1},
+		{Lo: 0xfe4d, Hi: 0xfe4f, Stride: 1},
+		{Lo: 0xff3f, Hi: 0xff3f, Stride: 1},
+	},
+}
+
+var Pd = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x002d, Hi: 0x058a, Stride: 1373},
+		{Lo: 0x05be, Hi: 0x1400, Stride: 3650},
+		{Lo: 0x1806, Hi: 0x2010, Stride: 2058},
+		{Lo: 0x2011, Hi: 0x2015, Stride: 1},
+		{Lo: 0x2e17, Hi: 0x2e1a, Stride: 3},
+		{Lo: 0x2e3a, Hi: 0x2e3b, Stride: 1},
+		{Lo: 0x2e40, Hi: 0x2e5d, Stride: 29},
+		{Lo: 0x301c, Hi: 0x3030, Stride: 20},
+		{Lo: 0x30a0, Hi: 0xfe31, Stride: 52625},
+		{Lo: 0xfe32, Hi: 0xfe58, Stride: 38},
+		{Lo: 0xfe63, Hi: 0xff0d, Stride: 170},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x10ead, Hi: 0x10ead, Stride: 1},
+	},
+}
+
+var Pe = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x0029, Hi: 0x005d, Stride: 52},
+		{Lo: 0x007d, Hi: 0x0f3b, Stride: 3774},
+		{Lo: 0x0f3d, Hi: 0x169c, Stride: 1887},
+		{Lo: 0x2046, Hi: 0x207e, Stride: 56},
+		{Lo: 0x208e, Hi: 0x2309, Stride: 635},
+		{Lo: 0x230b, Hi: 0x232a, Stride: 31},
+		{Lo: 0x2769, Hi: 0x2775, Stride: 2},
+		{Lo: 0x27c6, Hi: 0x27e7, Stride: 33},
+		{Lo: 0x27e9, Hi: 0x27ef, Stride: 2},
+		{Lo: 0x2984, Hi: 0x2998, Stride: 2},
+		{Lo: 0x29d9, Hi: 0x29db, Stride: 2},
+		{Lo: 0x29fd, Hi: 0x2e23, Stride: 1062},
+		{Lo: 0x2e25, Hi: 0x2e29, Stride: 2},
+		{Lo: 0x2e56, Hi: 0x2e5c, Stride: 2},
+		{Lo: 0x3009, Hi: 0x3011, Stride: 2},
+		{Lo: 0x3015, Hi: 0x301b, Stride: 2},
+		{Lo: 0x301e, Hi: 0x301f, Stride: 1},
+		{Lo: 0xfd3e, Hi: 0xfe18, Stride: 218},
+		{Lo: 0xfe36, Hi: 0xfe44, Stride: 2},
+		{Lo: 0xfe48, Hi: 0xfe5a, Stride: 18},
+		{Lo: 0xfe5c, Hi: 0xfe5e, Stride: 2},
+		{Lo: 0xff09, Hi: 0xff3d, Stride: 52},
+		{Lo: 0xff5d, Hi: 0xff63, Stride: 3},
+	},
+	LatinOffset: 1,
+}
+
+var Pf = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x00bb, Hi: 0x2019, Stride: 8030},
+		{Lo: 0x201d, Hi: 0x203a, Stride: 29},
+		{Lo: 0x2e03, Hi: 0x2e05, Stride: 2},
+		{Lo: 0x2e0a, Hi: 0x2e0d, Stride: 3},
+		{Lo: 0x2e1d, Hi: 0x2e21, Stride: 4},
+	},
+}
+
+var Pi = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x00ab, Hi: 0x2018, Stride: 8045},
+		{Lo: 0x201b, Hi: 0x201c, Stride: 1},
+		{Lo: 0x201f, Hi: 0x2039, Stride: 26},
+		{Lo: 0x2e02, Hi: 0x2e04, Stride: 2},
+		{Lo: 0x2e09, Hi: 0x2e0c, Stride: 3},
+		{Lo: 0x2e1c, Hi: 0x2e20, Stride: 4},
+	},
+}
+
+var Po = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x0021, Hi: 0x0023, Stride: 1},
+		{Lo: 0x0025, Hi: 0x0027, Stride: 1},
+		{Lo: 0x002a, Hi: 0x002e, Stride: 2},
+		{Lo: 0x002f, Hi: 0x003a, Stride: 11},
+		{Lo: 0x003b, Hi: 0x003f, Stride: 4},
+		{Lo: 0x0040, Hi: 0x005c, Stride: 28},
+		{Lo: 0x00a1, Hi: 0x00a7, Stride: 6},
+		{Lo: 0x00b6, Hi: 0x00b7, Stride: 1},
+		{Lo: 0x00bf, Hi: 0x037e, Stride: 703},
+		{Lo: 0x0387, Hi: 0x055a, Stride: 467},
+		{Lo: 0x055b, Hi: 0x055f, Stride: 1},
+		{Lo: 0x0589, Hi: 0x05c0, Stride: 55},
+		{Lo: 0x05c3, Hi: 0x05c6, Stride: 3},
+		{Lo: 0x05f3, Hi: 0x05f4, Stride: 1},
+		{Lo: 0x0609, Hi: 0x060a, Stride: 1},
+		{Lo: 0x060c, Hi: 0x060d, Stride: 1},
+		{Lo: 0x061b, Hi: 0x061d, Stride: 2},
+		{Lo: 0x061e, Hi: 0x061f, Stride: 1},
+		{Lo: 0x066a, Hi: 0x066d, Stride: 1},
+		{Lo: 0x06d4, Hi: 0x0700, Stride: 44},
+		{Lo: 0x0701, Hi: 0x070d, Stride: 1},
+		{Lo: 0x07f7, Hi: 0x07f9, Stride: 1},
+		{Lo: 0x0830, Hi: 0x083e, Stride: 1},
+		{Lo: 0x085e, Hi: 0x0964, Stride: 262},
+		{Lo: 0x0965, Hi: 0x0970, Stride: 11},
+		{Lo: 0x09fd, Hi: 0x0a76, Stride: 121},
+		{Lo: 0x0af0, Hi: 0x0c77, Stride: 391},
+		{Lo: 0x0c84, Hi: 0x0df4, Stride: 368},
+		{Lo: 0x0e4f, Hi: 0x0e5a, Stride: 11},
+		{Lo: 0x0e5b, Hi: 0x0f04, Stride: 169},
+		{Lo: 0x0f05, Hi: 0x0f12, Stride: 1},
+		{Lo: 0x0f14, Hi: 0x0f85, Stride: 113},
+		{Lo: 0x0fd0, Hi: 0x0fd4, Stride: 1},
+		{Lo: 0x0fd9, Hi: 0x0fda, Stride: 1},
+		{Lo: 0x104a, Hi: 0x104f, Stride: 1},
+		{Lo: 0x10fb, Hi: 0x1360, Stride: 613},
+		{Lo: 0x1361, Hi: 0x1368, Stride: 1},
+		{Lo: 0x166e, Hi: 0x16eb, Stride: 125},
+		{Lo: 0x16ec, Hi: 0x16ed, Stride: 1},
+		{Lo: 0x1735, Hi: 0x1736, Stride: 1},
+		{Lo: 0x17d4, Hi: 0x17d6, Stride: 1},
+		{Lo: 0x17d8, Hi: 0x17da, Stride: 1},
+		{Lo: 0x1800, Hi: 0x1805, Stride: 1},
+		{Lo: 0x1807, Hi: 0x180a, Stride: 1},
+		{Lo: 0x1944, Hi: 0x1945, Stride: 1},
+		{Lo: 0x1a1e, Hi: 0x1a1f, Stride: 1},
+		{Lo: 0x1aa0, Hi: 0x1aa6, Stride: 1},
+		{Lo: 0x1aa8, Hi: 0x1aad, Stride: 1},
+		{Lo: 0x1b5a, Hi: 0x1b60, Stride: 1},
+		{Lo: 0x1b7d, Hi: 0x1b7e, Stride: 1},
+		{Lo: 0x1bfc, Hi: 0x1bff, Stride: 1},
+		{Lo: 0x1c3b, Hi: 0x1c3f, Stride: 1},
+		{Lo: 0x1c7e, Hi: 0x1c7f, Stride: 1},
+		{Lo: 0x1cc0, Hi: 0x1cc7, Stride: 1},
+		{Lo: 0x1cd3, Hi: 0x2016, Stride: 835},
+		{Lo: 0x2017, Hi: 0x2020, Stride: 9},
+		{Lo: 0x2021, Hi: 0x2027, Stride: 1},
+		{Lo: 0x2030, Hi: 0x2038, Stride: 1},
+		{Lo: 0x203b, Hi: 0x203e, Stride: 1},
+		{Lo: 0x2041, Hi: 0x2043, Stride: 1},
+		{Lo: 0x2047, Hi: 0x2051, Stride: 1},
+		{Lo: 0x2053, Hi: 0x2055, Stride: 2},
+		{Lo: 0x2056, Hi: 0x205e, Stride: 1},
+		{Lo: 0x2cf9, Hi: 0x2cfc, Stride: 1},
+		{Lo: 0x2cfe, Hi: 0x2cff, Stride: 1},
+		{Lo: 0x2d70, Hi: 0x2e00, Stride: 144},
+		{Lo: 0x2e01, Hi: 0x2e06, Stride: 5},
+		{Lo: 0x2e07, Hi: 0x2e08, Stride: 1},
+		{Lo: 0x2e0b, Hi: 0x2e0e, Stride: 3},
+		{Lo: 0x2e0f, Hi: 0x2e16, Stride: 1},
+		{Lo: 0x2e18, Hi: 0x2e19, Stride: 1},
+		{Lo: 0x2e1b, Hi: 0x2e1e, Stride: 3},
+		{Lo: 0x2e1f, Hi: 0x2e2a, Stride: 11},
+		{Lo: 0x2e2b, Hi: 0x2e2e, Stride: 1},
+		{Lo: 0x2e30, Hi: 0x2e39, Stride: 1},
+		{Lo: 0x2e3c, Hi: 0x2e3f, Stride: 1},
+		{Lo: 0x2e41, Hi: 0x2e43, Stride: 2},
+		{Lo: 0x2e44, Hi: 0x2e4f, Stride: 1},
+		{Lo: 0x2e52, Hi: 0x2e54, Stride: 1},
+		{Lo: 0x3001, Hi: 0x3003, Stride: 1},
+		{Lo: 0x303d, Hi: 0x30fb, Stride: 190},
+		{Lo: 0xa4fe, Hi: 0xa4ff, Stride: 1},
+		{Lo: 0xa60d, Hi: 0xa60f, Stride: 1},
+		{Lo: 0xa673, Hi: 0xa67e, Stride: 11},
+		{Lo: 0xa6f2, Hi: 0xa6f7, Stride: 1},
+		{Lo: 0xa874, Hi: 0xa877, Stride: 1},
+		{Lo: 0xa8ce, Hi: 0xa8cf, Stride: 1},
+		{Lo: 0xa8f8, Hi: 0xa8fa, Stride: 1},
+		{Lo: 0xa8fc, Hi: 0xa92e, Stride: 50},
+		{Lo: 0xa92f, Hi: 0xa95f, Stride: 48},
+		{Lo: 0xa9c1, Hi: 0xa9cd, Stride: 1},
+		{Lo: 0xa9de, Hi: 0xa9df, Stride: 1},
+		{Lo: 0xaa5c, Hi: 0xaa5f, Stride: 1},
+		{Lo: 0xaade, Hi: 0xaadf, Stride: 1},
+		{Lo: 0xaaf0, Hi: 0xaaf1, Stride: 1},
+		{Lo: 0xabeb, Hi: 0xfe10, Stride: 21029},
+		{Lo: 0xfe11, Hi: 0xfe16, Stride: 1},
+		{Lo: 0xfe19, Hi: 0xfe30, Stride: 23},
+		{Lo: 0xfe45, Hi: 0xfe46, Stride: 1},
+		{Lo: 0xfe49, Hi: 0xfe4c, Stride: 1},
+		{Lo: 0xfe50, Hi: 0xfe52, Stride: 1},
+		{Lo: 0xfe54, Hi: 0xfe57, Stride: 1},
+		{Lo: 0xfe5f, Hi: 0xfe61, Stride: 1},
+		{Lo: 0xfe68, Hi: 0xfe6a, Stride: 2},
+		{Lo: 0xfe6b, Hi: 0xff01, Stride: 150},
+		{Lo: 0xff02, Hi: 0xff03, Stride: 1},
+		{Lo: 0xff05, Hi: 0xff07, Stride: 1},
+		{Lo: 0xff0a, Hi: 0xff0e, Stride: 2},
+		{Lo: 0xff0f, Hi: 0xff1a, Stride: 11},
+		{Lo: 0xff1b, Hi: 0xff1f, Stride: 4},
+		{Lo: 0xff20, Hi: 0xff3c, Stride: 28},
+		{Lo: 0xff61, Hi: 0xff64, Stride: 3},
+		{Lo: 0xff65, Hi: 0xff65, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x10100, Hi: 0x10102, Stride: 1},
+		{Lo: 0x1039f, Hi: 0x103d0, Stride: 49},
+		{Lo: 0x1056f, Hi: 0x10857, Stride: 744},
+		{Lo: 0x1091f, Hi: 0x1093f, Stride: 32},
+		{Lo: 0x10a50, Hi: 0x10a58, Stride: 1},
+		{Lo: 0x10a7f, Hi: 0x10af0, Stride: 113},
+		{Lo: 0x10af1, Hi: 0x10af6, Stride: 1},
+		{Lo: 0x10b39, Hi: 0x10b3f, Stride: 1},
+		{Lo: 0x10b99, Hi: 0x10b9c, Stride: 1},
+		{Lo: 0x10f55, Hi: 0x10f59, Stride: 1},
+		{Lo: 0x10f86, Hi: 0x10f89, Stride: 1},
+		{Lo: 0x11047, Hi: 0x1104d, Stride: 1},
+		{Lo: 0x110bb, Hi: 0x110bc, Stride: 1},
+		{Lo: 0x110be, Hi: 0x110c1, Stride: 1},
+		{Lo: 0x11140, Hi: 0x11143, Stride: 1},
+		{Lo: 0x11174, Hi: 0x11175, Stride: 1},
+		{Lo: 0x111c5, Hi: 0x111c8, Stride: 1},
+		{Lo: 0x111cd, Hi: 0x111db, Stride: 14},
+		{Lo: 0x111dd, Hi: 0x111df, Stride: 1},
+		{Lo: 0x11238, Hi: 0x1123d, Stride: 1},
+		{Lo: 0x112a9, Hi: 0x1144b, Stride: 418},
+		{Lo: 0x1144c, Hi: 0x1144f, Stride: 1},
+		{Lo: 0x1145a, Hi: 0x1145b, Stride: 1},
+		{Lo: 0x1145d, Hi: 0x114c6, Stride: 105},
+		{Lo: 0x115c1, Hi: 0x115d7, Stride: 1},
+		{Lo: 0x11641, Hi: 0x11643, Stride: 1},
+		{Lo: 0x11660, Hi: 0x1166c, Stride: 1},
+		{Lo: 0x116b9, Hi: 0x1173c, Stride: 131},
+		{Lo: 0x1173d, Hi: 0x1173e, Stride: 1},
+		{Lo: 0x1183b, Hi: 0x11944, Stride: 265},
+		{Lo: 0x11945, Hi: 0x11946, Stride: 1},
+		{Lo: 0x119e2, Hi: 0x11a3f, Stride: 93},
+		{Lo: 0x11a40, Hi: 0x11a46, Stride: 1},
+		{Lo: 0x11a9a, Hi: 0x11a9c, Stride: 1},
+		{Lo: 0x11a9e, Hi: 0x11aa2, Stride: 1},
+		{Lo: 0x11b00, Hi: 0x11b09, Stride: 1},
+		{Lo: 0x11c41, Hi: 0x11c45, Stride: 1},
+		{Lo: 0x11c70, Hi: 0x11c71, Stride: 1},
+		{Lo: 0x11ef7, Hi: 0x11ef8, Stride: 1},
+		{Lo: 0x11f43, Hi: 0x11f4f, Stride: 1},
+		{Lo: 0x11fff, Hi: 0x12470, Stride: 1137},
+		{Lo: 0x12471, Hi: 0x12474, Stride: 1},
+		{Lo: 0x12ff1, Hi: 0x12ff2, Stride: 1},
+		{Lo: 0x16a6e, Hi: 0x16a6f, Stride: 1},
+		{Lo: 0x16af5, Hi: 0x16b37, Stride: 66},
+		{Lo: 0x16b38, Hi: 0x16b3b, Stride: 1},
+		{Lo: 0x16b44, Hi: 0x16e97, Stride: 851},
+		{Lo: 0x16e98, Hi: 0x16e9a, Stride: 1},
+		{Lo: 0x16fe2, Hi: 0x1bc9f, Stride: 19645},
+		{Lo: 0x1da87, Hi: 0x1da8b, Stride: 1},
+		{Lo: 0x1e95e, Hi: 0x1e95f, Stride: 1},
+	},
+	LatinOffset: 8,
+}
+
+var Ps = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x0028, Hi: 0x005b, Stride: 51},
+		{Lo: 0x007b, Hi: 0x0f3a, Stride: 3775},
+		{Lo: 0x0f3c, Hi: 0x169b, Stride: 1887},
+		{Lo: 0x201a, Hi: 0x201e, Stride: 4},
+		{Lo: 0x2045, Hi: 0x207d, Stride: 56},
+		{Lo: 0x208d, Hi: 0x2308, Stride: 635},
+		{Lo: 0x230a, Hi: 0x2329, Stride: 31},
+		{Lo: 0x2768, Hi: 0x2774, Stride: 2},
+		{Lo: 0x27c5, Hi: 0x27e6, Stride: 33},
+		{Lo: 0x27e8, Hi: 0x27ee, Stride: 2},
+		{Lo: 0x2983, Hi: 0x2997, Stride: 2},
+		{Lo: 0x29d8, Hi: 0x29da, Stride: 2},
+		{Lo: 0x29fc, Hi: 0x2e22, Stride: 1062},
+		{Lo: 0x2e24, Hi: 0x2e28, Stride: 2},
+		{Lo: 0x2e42, Hi: 0x2e55, Stride: 19},
+		{Lo: 0x2e57, Hi: 0x2e5b, Stride: 2},
+		{Lo: 0x3008, Hi: 0x3010, Stride: 2},
+		{Lo: 0x3014, Hi: 0x301a, Stride: 2},
+		{Lo: 0x301d, Hi: 0xfd3f, Stride: 52514},
+		{Lo: 0xfe17, Hi: 0xfe35, Stride: 30},
+		{Lo: 0xfe37, Hi: 0xfe43, Stride: 2},
+		{Lo: 0xfe47, Hi: 0xfe59, Stride: 18},
+		{Lo: 0xfe5b, Hi: 0xfe5d, Stride: 2},
+		{Lo: 0xff08, Hi: 0xff3b, Stride: 51},
+		{Lo: 0xff5b, Hi: 0xff5f, Stride: 4},
+		{Lo: 0xff62, Hi: 0xff62, Stride: 1},
+	},
+	LatinOffset: 1,
+}
+
+var Sc = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x0024, Hi: 0x00a2, Stride: 126},
+		{Lo: 0x00a3, Hi: 0x00a5, Stride: 1},
+		{Lo: 0x058f, Hi: 0x060b, Stride: 124},
+		{Lo: 0x07fe, Hi: 0x07ff, Stride: 1},
+		{Lo: 0x09f2, Hi: 0x09f3, Stride: 1},
+		{Lo: 0x09fb, Hi: 0x0af1, Stride: 246},
+		{Lo: 0x0bf9, Hi: 0x0e3f, Stride: 582},
+		{Lo: 0x17db, Hi: 0x20a0, Stride: 2245},
+		{Lo: 0x20a1, Hi: 0x20c0, Stride: 1},
+		{Lo: 0xa838, Hi: 0xfdfc, Stride: 21956},
+		{Lo: 0xfe69, Hi: 0xff04, Stride: 155},
+		{Lo: 0xffe0, Hi: 0xffe1, Stride: 1},
+		{Lo: 0xffe5, Hi: 0xffe6, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x11fdd, Hi: 0x11fe0, Stride: 1},
+		{Lo: 0x1e2ff, Hi: 0x1ecb0, Stride: 2481},
+	},
+	LatinOffset: 2,
+}
+
+var Sk = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x005e, Hi: 0x0060, Stride: 2},
+		{Lo: 0x00a8, Hi: 0x00af, Stride: 7},
+		{Lo: 0x00b4, Hi: 0x00b8, Stride: 4},
+		{Lo: 0x02c2, Hi: 0x02c5, Stride: 1},
+		{Lo: 0x02d2, Hi: 0x02df, Stride: 1},
+		{Lo: 0x02e5, Hi: 0x02eb, Stride: 1},
+		{Lo: 0x02ed, Hi: 0x02ef, Stride: 2},
+		{Lo: 0x02f0, Hi: 0x02ff, Stride: 1},
+		{Lo: 0x0375, Hi: 0x0384, Stride: 15},
+		{Lo: 0x0385, Hi: 0x0888, Stride: 1283},
+		{Lo: 0x1fbd, Hi: 0x1fbf, Stride: 2},
+		{Lo: 0x1fc0, Hi: 0x1fc1, Stride: 1},
+		{Lo: 0x1fcd, Hi: 0x1fcf, Stride: 1},
+		{Lo: 0x1fdd, Hi: 0x1fdf, Stride: 1},
+		{Lo: 0x1fed, Hi: 0x1fef, Stride: 1},
+		{Lo: 0x1ffd, Hi: 0x1ffe, Stride: 1},
+		{Lo: 0x309b, Hi: 0x309c, Stride: 1},
+		{Lo: 0xa700, Hi: 0xa716, Stride: 1},
+		{Lo: 0xa720, Hi: 0xa721, Stride: 1},
+		{Lo: 0xa789, Hi: 0xa78a, Stride: 1},
+		{Lo: 0xab5b, Hi: 0xab6a, Stride: 15},
+		{Lo: 0xab6b, Hi: 0xfbb2, Stride: 20551},
+		{Lo: 0xfbb3, Hi: 0xfbc2, Stride: 1},
+		{Lo: 0xff3e, Hi: 0xff40, Stride: 2},
+		{Lo: 0xffe3, Hi: 0xffe3, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x1f3fb, Hi: 0x1f3ff, Stride: 1},
+	},
+	LatinOffset: 3,
+}
+
+var Sm = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x002b, Hi: 0x003c, Stride: 17},
+		{Lo: 0x003d, Hi: 0x003e, Stride: 1},
+		{Lo: 0x007c, Hi: 0x007e, Stride: 2},
+		{Lo: 0x00ac, Hi: 0x00b1, Stride: 5},
+		{Lo: 0x00d7, Hi: 0x00f7, Stride: 32},
+		{Lo: 0x03f6, Hi: 0x0606, Stride: 528},
+		{Lo: 0x0607, Hi: 0x0608, Stride: 1},
+		{Lo: 0x2044, Hi: 0x2052, Stride: 14},
+		{Lo: 0x207a, Hi: 0x207c, Stride: 1},
+		{Lo: 0x208a, Hi: 0x208c, Stride: 1},
+		{Lo: 0x2118, Hi: 0x2140, Stride: 40},
+		{Lo: 0x2141, Hi: 0x2144, Stride: 1},
+		{Lo: 0x214b, Hi: 0x2190, Stride: 69},
+		{Lo: 0x2191, Hi: 0x2194, Stride: 1},
+		{Lo: 0x219a, Hi: 0x219b, Stride: 1},
+		{Lo: 0x21a0, Hi: 0x21a6, Stride: 3},
+		{Lo: 0x21ae, Hi: 0x21ce, Stride: 32},
+		{Lo: 0x21cf, Hi: 0x21d2, Stride: 3},
+		{Lo: 0x21d4, Hi: 0x21f4, Stride: 32},
+		{Lo: 0x21f5, Hi: 0x22ff, Stride: 1},
+		{Lo: 0x2320, Hi: 0x2321, Stride: 1},
+		{Lo: 0x237c, Hi: 0x239b, Stride: 31},
+		{Lo: 0x239c, Hi: 0x23b3, Stride: 1},
+		{Lo: 0x23dc, Hi: 0x23e1, Stride: 1},
+		{Lo: 0x25b7, Hi: 0x25c1, Stride: 10},
+		{Lo: 0x25f8, Hi: 0x25ff, Stride: 1},
+		{Lo: 0x266f, Hi: 0x27c0, Stride: 337},
+		{Lo: 0x27c1, Hi: 0x27c4, Stride: 1},
+		{Lo: 0x27c7, Hi: 0x27e5, Stride: 1},
+		{Lo: 0x27f0, Hi: 0x27ff, Stride: 1},
+		{Lo: 0x2900, Hi: 0x2982, Stride: 1},
+		{Lo: 0x2999, Hi: 0x29d7, Stride: 1},
+		{Lo: 0x29dc, Hi: 0x29fb, Stride: 1},
+		{Lo: 0x29fe, Hi: 0x2aff, Stride: 1},
+		{Lo: 0x2b30, Hi: 0x2b44, Stride: 1},
+		{Lo: 0x2b47, Hi: 0x2b4c, Stride: 1},
+		{Lo: 0xfb29, Hi: 0xfe62, Stride: 825},
+		{Lo: 0xfe64, Hi: 0xfe66, Stride: 1},
+		{Lo: 0xff0b, Hi: 0xff1c, Stride: 17},
+		{Lo: 0xff1d, Hi: 0xff1e, Stride: 1},
+		{Lo: 0xff5c, Hi: 0xff5e, Stride: 2},
+		{Lo: 0xffe2, Hi: 0xffe9, Stride: 7},
+		{Lo: 0xffea, Hi: 0xffec, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x1d6c1, Hi: 0x1d6db, Stride: 26},
+		{Lo: 0x1d6fb, Hi: 0x1d715, Stride: 26},
+		{Lo: 0x1d735, Hi: 0x1d74f, Stride: 26},
+		{Lo: 0x1d76f, Hi: 0x1d789, Stride: 26},
+		{Lo: 0x1d7a9, Hi: 0x1d7c3, Stride: 26},
+		{Lo: 0x1eef0, Hi: 0x1eef1, Stride: 1},
+	},
+	LatinOffset: 5,
+}
+
+var So = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x00a6, Hi: 0x00a9, Stride: 3},
+		{Lo: 0x00ae, Hi: 0x00b0, Stride: 2},
+		{Lo: 0x0482, Hi: 0x058d, Stride: 267},
+		{Lo: 0x058e, Hi: 0x060e, Stride: 128},
+		{Lo: 0x060f, Hi: 0x06de, Stride: 207},
+		{Lo: 0x06e9, Hi: 0x06fd, Stride: 20},
+		{Lo: 0x06fe, Hi: 0x07f6, Stride: 248},
+		{Lo: 0x09fa, Hi: 0x0b70, Stride: 374},
+		{Lo: 0x0bf3, Hi: 0x0bf8, Stride: 1},
+		{Lo: 0x0bfa, Hi: 0x0c7f, Stride: 133},
+		{Lo: 0x0d4f, Hi: 0x0d79, Stride: 42},
+		{Lo: 0x0f01, Hi: 0x0f03, Stride: 1},
+		{Lo: 0x0f13, Hi: 0x0f15, Stride: 2},
+		{Lo: 0x0f16, Hi: 0x0f17, Stride: 1},
+		{Lo: 0x0f1a, Hi: 0x0f1f, Stride: 1},
+		{Lo: 0x0f34, Hi: 0x0f38, Stride: 2},
+		{Lo: 0x0fbe, Hi: 0x0fc5, Stride: 1},
+		{Lo: 0x0fc7, Hi: 0x0fcc, Stride: 1},
+		{Lo: 0x0fce, Hi: 0x0fcf, Stride: 1},
+		{Lo: 0x0fd5, Hi: 0x0fd8, Stride: 1},
+		{Lo: 0x109e, Hi: 0x109f, Stride: 1},
+		{Lo: 0x1390, Hi: 0x1399, Stride: 1},
+		{Lo: 0x166d, Hi: 0x1940, Stride: 723},
+		{Lo: 0x19de, Hi: 0x19ff, Stride: 1},
+		{Lo: 0x1b61, Hi: 0x1b6a, Stride: 1},
+		{Lo: 0x1b74, Hi: 0x1b7c, Stride: 1},
+		{Lo: 0x2100, Hi: 0x2101, Stride: 1},
+		{Lo: 0x2103, Hi: 0x2106, Stride: 1},
+		{Lo: 0x2108, Hi: 0x2109, Stride: 1},
+		{Lo: 0x2114, Hi: 0x2116, Stride: 2},
+		{Lo: 0x2117, Hi: 0x211e, Stride: 7},
+		{Lo: 0x211f, Hi: 0x2123, Stride: 1},
+		{Lo: 0x2125, Hi: 0x2129, Stride: 2},
+		{Lo: 0x212e, Hi: 0x213a, Stride: 12},
+		{Lo: 0x213b, Hi: 0x214a, Stride: 15},
+		{Lo: 0x214c, Hi: 0x214d, Stride: 1},
+		{Lo: 0x214f, Hi: 0x218a, Stride: 59},
+		{Lo: 0x218b, Hi: 0x2195, Stride: 10},
+		{Lo: 0x2196, Hi: 0x2199, Stride: 1},
+		{Lo: 0x219c, Hi: 0x219f, Stride: 1},
+		{Lo: 0x21a1, Hi: 0x21a2, Stride: 1},
+		{Lo: 0x21a4, Hi: 0x21a5, Stride: 1},
+		{Lo: 0x21a7, Hi: 0x21ad, Stride: 1},
+		{Lo: 0x21af, Hi: 0x21cd, Stride: 1},
+		{Lo: 0x21d0, Hi: 0x21d1, Stride: 1},
+		{Lo: 0x21d3, Hi: 0x21d5, Stride: 2},
+		{Lo: 0x21d6, Hi: 0x21f3, Stride: 1},
+		{Lo: 0x2300, Hi: 0x2307, Stride: 1},
+		{Lo: 0x230c, Hi: 0x231f, Stride: 1},
+		{Lo: 0x2322, Hi: 0x2328, Stride: 1},
+		{Lo: 0x232b, Hi: 0x237b, Stride: 1},
+		{Lo: 0x237d, Hi: 0x239a, Stride: 1},
+		{Lo: 0x23b4, Hi: 0x23db, Stride: 1},
+		{Lo: 0x23e2, Hi: 0x2426, Stride: 1},
+		{Lo: 0x2440, Hi: 0x244a, Stride: 1},
+		{Lo: 0x249c, Hi: 0x24e9, Stride: 1},
+		{Lo: 0x2500, Hi: 0x25b6, Stride: 1},
+		{Lo: 0x25b8, Hi: 0x25c0, Stride: 1},
+		{Lo: 0x25c2, Hi: 0x25f7, Stride: 1},
+		{Lo: 0x2600, Hi: 0x266e, Stride: 1},
+		{Lo: 0x2670, Hi: 0x2767, Stride: 1},
+		{Lo: 0x2794, Hi: 0x27bf, Stride: 1},
+		{Lo: 0x2800, Hi: 0x28ff, Stride: 1},
+		{Lo: 0x2b00, Hi: 0x2b2f, Stride: 1},
+		{Lo: 0x2b45, Hi: 0x2b46, Stride: 1},
+		{Lo: 0x2b4d, Hi: 0x2b73, Stride: 1},
+		{Lo: 0x2b76, Hi: 0x2b95, Stride: 1},
+		{Lo: 0x2b97, Hi: 0x2bff, Stride: 1},
+		{Lo: 0x2ce5, Hi: 0x2cea, Stride: 1},
+		{Lo: 0x2e50, Hi: 0x2e51, Stride: 1},
+		{Lo: 0x2e80, Hi: 0x2e99, Stride: 1},
+		{Lo: 0x2e9b, Hi: 0x2ef3, Stride: 1},
+		{Lo: 0x2f00, Hi: 0x2fd5, Stride: 1},
+		{Lo: 0x2ff0, Hi: 0x2ffb, Stride: 1},
+		{Lo: 0x3004, Hi: 0x3012, Stride: 14},
+		{Lo: 0x3013, Hi: 0x3020, Stride: 13},
+		{Lo: 0x3036, Hi: 0x3037, Stride: 1},
+		{Lo: 0x303e, Hi: 0x303f, Stride: 1},
+		{Lo: 0x3190, Hi: 0x3191, Stride: 1},
+		{Lo: 0x3196, Hi: 0x319f, Stride: 1},
+		{Lo: 0x31c0, Hi: 0x31e3, Stride: 1},
+		{Lo: 0x3200, Hi: 0x321e, Stride: 1},
+		{Lo: 0x322a, Hi: 0x3247, Stride: 1},
+		{Lo: 0x3250, Hi: 0x3260, Stride: 16},
+		{Lo: 0x3261, Hi: 0x327f, Stride: 1},
+		{Lo: 0x328a, Hi: 0x32b0, Stride: 1},
+		{Lo: 0x32c0, Hi: 0x33ff, Stride: 1},
+		{Lo: 0x4dc0, Hi: 0x4dff, Stride: 1},
+		{Lo: 0xa490, Hi: 0xa4c6, Stride: 1},
+		{Lo: 0xa828, Hi: 0xa82b, Stride: 1},
+		{Lo: 0xa836, Hi: 0xa837, Stride: 1},
+		{Lo: 0xa839, Hi: 0xaa77, Stride: 574},
+		{Lo: 0xaa78, Hi: 0xaa79, Stride: 1},
+		{Lo: 0xfd40, Hi: 0xfd4f, Stride: 1},
+		{Lo: 0xfdcf, Hi: 0xfdfd, Stride: 46},
+		{Lo: 0xfdfe, Hi: 0xfdff, Stride: 1},
+		{Lo: 0xffe4, Hi: 0xffe8, Stride: 4},
+		{Lo: 0xffed, Hi: 0xffee, Stride: 1},
+		{Lo: 0xfffc, Hi: 0xfffd, Stride: 1},
+	},
+	R32: []unicode.Range32{
+		{Lo: 0x10137, Hi: 0x1013f, Stride: 1},
+		{Lo: 0x10179, Hi: 0x10189, Stride: 1},
+		{Lo: 0x1018c, Hi: 0x1018e, Stride: 1},
+		{Lo: 0x10190, Hi: 0x1019c, Stride: 1},
+		{Lo: 0x101a0, Hi: 0x101d0, Stride: 48},
+		{Lo: 0x101d1, Hi: 0x101fc, Stride: 1},
+		{Lo: 0x10877, Hi: 0x10878, Stride: 1},
+		{Lo: 0x10ac8, Hi: 0x1173f, Stride: 3191},
+		{Lo: 0x11fd5, Hi: 0x11fdc, Stride: 1},
+		{Lo: 0x11fe1, Hi: 0x11ff1, Stride: 1},
+		{Lo: 0x16b3c, Hi: 0x16b3f, Stride: 1},
+		{Lo: 0x16b45, Hi: 0x1bc9c, Stride: 20823},
+		{Lo: 0x1cf50, Hi: 0x1cfc3, Stride: 1},
+		{Lo: 0x1d000, Hi: 0x1d0f5, Stride: 1},
+		{Lo: 0x1d100, Hi: 0x1d126, Stride: 1},
+		{Lo: 0x1d129, Hi: 0x1d164, Stride: 1},
+		{Lo: 0x1d16a, Hi: 0x1d16c, Stride: 1},
+		{Lo: 0x1d183, Hi: 0x1d184, Stride: 1},
+		{Lo: 0x1d18c, Hi: 0x1d1a9, Stride: 1},
+		{Lo: 0x1d1ae, Hi: 0x1d1ea, Stride: 1},
+		{Lo: 0x1d200, Hi: 0x1d241, Stride: 1},
+		{Lo: 0x1d245, Hi: 0x1d300, Stride: 187},
+		{Lo: 0x1d301, Hi: 0x1d356, Stride: 1},
+		{Lo: 0x1d800, Hi: 0x1d9ff, Stride: 1},
+		{Lo: 0x1da37, Hi: 0x1da3a, Stride: 1},
+		{Lo: 0x1da6d, Hi: 0x1da74, Stride: 1},
+		{Lo: 0x1da76, Hi: 0x1da83, Stride: 1},
+		{Lo: 0x1da85, Hi: 0x1da86, Stride: 1},
+		{Lo: 0x1e14f, Hi: 0x1ecac, Stride: 2909},
+		{Lo: 0x1ed2e, Hi: 0x1f000, Stride: 722},
+		{Lo: 0x1f001, Hi: 0x1f02b, Stride: 1},
+		{Lo: 0x1f030, Hi: 0x1f093, Stride: 1},
+		{Lo: 0x1f0a0, Hi: 0x1f0ae, Stride: 1},
+		{Lo: 0x1f0b1, Hi: 0x1f0bf, Stride: 1},
+		{Lo: 0x1f0c1, Hi: 0x1f0cf, Stride: 1},
+		{Lo: 0x1f0d1, Hi: 0x1f0f5, Stride: 1},
+		{Lo: 0x1f10d, Hi: 0x1f1ad, Stride: 1},
+		{Lo: 0x1f1e6, Hi: 0x1f202, Stride: 1},
+		{Lo: 0x1f210, Hi: 0x1f23b, Stride: 1},
+		{Lo: 0x1f240, Hi: 0x1f248, Stride: 1},
+		{Lo: 0x1f250, Hi: 0x1f251, Stride: 1},
+		{Lo: 0x1f260, Hi: 0x1f265, Stride: 1},
+		{Lo: 0x1f300, Hi: 0x1f3fa, Stride: 1},
+		{Lo: 0x1f400, Hi: 0x1f6d7, Stride: 1},
+		{Lo: 0x1f6dc, Hi: 0x1f6ec, Stride: 1},
+		{Lo: 0x1f6f0, Hi: 0x1f6fc, Stride: 1},
+		{Lo: 0x1f700, Hi: 0x1f776, Stride: 1},
+		{Lo: 0x1f77b, Hi: 0x1f7d9, Stride: 1},
+		{Lo: 0x1f7e0, Hi: 0x1f7eb, Stride: 1},
+		{Lo: 0x1f7f0, Hi: 0x1f800, Stride: 16},
+		{Lo: 0x1f801, Hi: 0x1f80b, Stride: 1},
+		{Lo: 0x1f810, Hi: 0x1f847, Stride: 1},
+		{Lo: 0x1f850, Hi: 0x1f859, Stride: 1},
+		{Lo: 0x1f860, Hi: 0x1f887, Stride: 1},
+		{Lo: 0x1f890, Hi: 0x1f8ad, Stride: 1},
+		{Lo: 0x1f8b0, Hi: 0x1f8b1, Stride: 1},
+		{Lo: 0x1f900, Hi: 0x1fa53, Stride: 1},
+		{Lo: 0x1fa60, Hi: 0x1fa6d, Stride: 1},
+		{Lo: 0x1fa70, Hi: 0x1fa7c, Stride: 1},
+		{Lo: 0x1fa80, Hi: 0x1fa88, Stride: 1},
+		{Lo: 0x1fa90, Hi: 0x1fabd, Stride: 1},
+		{Lo: 0x1fabf, Hi: 0x1fac5, Stride: 1},
+		{Lo: 0x1face, Hi: 0x1fadb, Stride: 1},
+		{Lo: 0x1fae0, Hi: 0x1fae8, Stride: 1},
+		{Lo: 0x1faf0, Hi: 0x1faf8, Stride: 1},
+		{Lo: 0x1fb00, Hi: 0x1fb92, Stride: 1},
+		{Lo: 0x1fb94, Hi: 0x1fbca, Stride: 1},
+	},
+	LatinOffset: 2,
+}
+
+var Zl = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x2028, Hi: 0x2028, Stride: 1},
+	},
+}
+
+var Zp = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x2029, Hi: 0x2029, Stride: 1},
+	},
+}
+
+var Zs = &unicode.RangeTable{
+	R16: []unicode.Range16{
+		{Lo: 0x0020, Hi: 0x00a0, Stride: 128},
+		{Lo: 0x1680, Hi: 0x2000, Stride: 2432},
+		{Lo: 0x2001, Hi: 0x200a, Stride: 1},
+		{Lo: 0x202f, Hi: 0x205f, Stride: 48},
+		{Lo: 0x3000, Hi: 0x3000, Stride: 1},
+	},
+	LatinOffset: 1,
+}

+ 89 - 51
vendor/github.com/go-text/typesetting/unicodedata/graphemeBreak.go → vendor/github.com/go-text/typesetting/unicodedata/grapheme_break.go

@@ -30,7 +30,7 @@ var GraphemeBreakControl = &unicode.RangeTable{
 		{Lo: 0xfff1, Hi: 0xfffb, Stride: 1},
 		{Lo: 0xfff1, Hi: 0xfffb, Stride: 1},
 	},
 	},
 	R32: []unicode.Range32{
 	R32: []unicode.Range32{
-		{Lo: 0x13430, Hi: 0x13438, Stride: 1},
+		{Lo: 0x13430, Hi: 0x1343f, Stride: 1},
 		{Lo: 0x1bca0, Hi: 0x1bca3, Stride: 1},
 		{Lo: 0x1bca0, Hi: 0x1bca3, Stride: 1},
 		{Lo: 0x1d173, Hi: 0x1d17a, Stride: 1},
 		{Lo: 0x1d173, Hi: 0x1d17a, Stride: 1},
 		{Lo: 0xe0000, Hi: 0xe001f, Stride: 1},
 		{Lo: 0xe0000, Hi: 0xe001f, Stride: 1},
@@ -66,7 +66,8 @@ var GraphemeBreakExtend = &unicode.RangeTable{
 		{Lo: 0x0825, Hi: 0x0827, Stride: 1},
 		{Lo: 0x0825, Hi: 0x0827, Stride: 1},
 		{Lo: 0x0829, Hi: 0x082d, Stride: 1},
 		{Lo: 0x0829, Hi: 0x082d, Stride: 1},
 		{Lo: 0x0859, Hi: 0x085b, Stride: 1},
 		{Lo: 0x0859, Hi: 0x085b, Stride: 1},
-		{Lo: 0x08d3, Hi: 0x08e1, Stride: 1},
+		{Lo: 0x0898, Hi: 0x089f, Stride: 1},
+		{Lo: 0x08ca, Hi: 0x08e1, Stride: 1},
 		{Lo: 0x08e3, Hi: 0x0902, Stride: 1},
 		{Lo: 0x08e3, Hi: 0x0902, Stride: 1},
 		{Lo: 0x093a, Hi: 0x093c, Stride: 2},
 		{Lo: 0x093a, Hi: 0x093c, Stride: 2},
 		{Lo: 0x0941, Hi: 0x0948, Stride: 1},
 		{Lo: 0x0941, Hi: 0x0948, Stride: 1},
@@ -101,8 +102,8 @@ var GraphemeBreakExtend = &unicode.RangeTable{
 		{Lo: 0x0b82, Hi: 0x0bbe, Stride: 60},
 		{Lo: 0x0b82, Hi: 0x0bbe, Stride: 60},
 		{Lo: 0x0bc0, Hi: 0x0bcd, Stride: 13},
 		{Lo: 0x0bc0, Hi: 0x0bcd, Stride: 13},
 		{Lo: 0x0bd7, Hi: 0x0c00, Stride: 41},
 		{Lo: 0x0bd7, Hi: 0x0c00, Stride: 41},
-		{Lo: 0x0c04, Hi: 0x0c3e, Stride: 58},
-		{Lo: 0x0c3f, Hi: 0x0c40, Stride: 1},
+		{Lo: 0x0c04, Hi: 0x0c3c, Stride: 56},
+		{Lo: 0x0c3e, Hi: 0x0c40, Stride: 1},
 		{Lo: 0x0c46, Hi: 0x0c48, Stride: 1},
 		{Lo: 0x0c46, Hi: 0x0c48, Stride: 1},
 		{Lo: 0x0c4a, Hi: 0x0c4d, Stride: 1},
 		{Lo: 0x0c4a, Hi: 0x0c4d, Stride: 1},
 		{Lo: 0x0c55, Hi: 0x0c56, Stride: 1},
 		{Lo: 0x0c55, Hi: 0x0c56, Stride: 1},
@@ -127,7 +128,7 @@ var GraphemeBreakExtend = &unicode.RangeTable{
 		{Lo: 0x0e47, Hi: 0x0e4e, Stride: 1},
 		{Lo: 0x0e47, Hi: 0x0e4e, Stride: 1},
 		{Lo: 0x0eb1, Hi: 0x0eb4, Stride: 3},
 		{Lo: 0x0eb1, Hi: 0x0eb4, Stride: 3},
 		{Lo: 0x0eb5, Hi: 0x0ebc, Stride: 1},
 		{Lo: 0x0eb5, Hi: 0x0ebc, Stride: 1},
-		{Lo: 0x0ec8, Hi: 0x0ecd, Stride: 1},
+		{Lo: 0x0ec8, Hi: 0x0ece, Stride: 1},
 		{Lo: 0x0f18, Hi: 0x0f19, Stride: 1},
 		{Lo: 0x0f18, Hi: 0x0f19, Stride: 1},
 		{Lo: 0x0f35, Hi: 0x0f39, Stride: 2},
 		{Lo: 0x0f35, Hi: 0x0f39, Stride: 2},
 		{Lo: 0x0f71, Hi: 0x0f7e, Stride: 1},
 		{Lo: 0x0f71, Hi: 0x0f7e, Stride: 1},
@@ -148,7 +149,7 @@ var GraphemeBreakExtend = &unicode.RangeTable{
 		{Lo: 0x109d, Hi: 0x135d, Stride: 704},
 		{Lo: 0x109d, Hi: 0x135d, Stride: 704},
 		{Lo: 0x135e, Hi: 0x135f, Stride: 1},
 		{Lo: 0x135e, Hi: 0x135f, Stride: 1},
 		{Lo: 0x1712, Hi: 0x1714, Stride: 1},
 		{Lo: 0x1712, Hi: 0x1714, Stride: 1},
-		{Lo: 0x1732, Hi: 0x1734, Stride: 1},
+		{Lo: 0x1732, Hi: 0x1733, Stride: 1},
 		{Lo: 0x1752, Hi: 0x1753, Stride: 1},
 		{Lo: 0x1752, Hi: 0x1753, Stride: 1},
 		{Lo: 0x1772, Hi: 0x1773, Stride: 1},
 		{Lo: 0x1772, Hi: 0x1773, Stride: 1},
 		{Lo: 0x17b4, Hi: 0x17b5, Stride: 1},
 		{Lo: 0x17b4, Hi: 0x17b5, Stride: 1},
@@ -157,9 +158,9 @@ var GraphemeBreakExtend = &unicode.RangeTable{
 		{Lo: 0x17ca, Hi: 0x17d3, Stride: 1},
 		{Lo: 0x17ca, Hi: 0x17d3, Stride: 1},
 		{Lo: 0x17dd, Hi: 0x180b, Stride: 46},
 		{Lo: 0x17dd, Hi: 0x180b, Stride: 46},
 		{Lo: 0x180c, Hi: 0x180d, Stride: 1},
 		{Lo: 0x180c, Hi: 0x180d, Stride: 1},
-		{Lo: 0x1885, Hi: 0x1886, Stride: 1},
-		{Lo: 0x18a9, Hi: 0x1920, Stride: 119},
-		{Lo: 0x1921, Hi: 0x1922, Stride: 1},
+		{Lo: 0x180f, Hi: 0x1885, Stride: 118},
+		{Lo: 0x1886, Hi: 0x18a9, Stride: 35},
+		{Lo: 0x1920, Hi: 0x1922, Stride: 1},
 		{Lo: 0x1927, Hi: 0x1928, Stride: 1},
 		{Lo: 0x1927, Hi: 0x1928, Stride: 1},
 		{Lo: 0x1932, Hi: 0x1939, Stride: 7},
 		{Lo: 0x1932, Hi: 0x1939, Stride: 7},
 		{Lo: 0x193a, Hi: 0x193b, Stride: 1},
 		{Lo: 0x193a, Hi: 0x193b, Stride: 1},
@@ -170,7 +171,7 @@ var GraphemeBreakExtend = &unicode.RangeTable{
 		{Lo: 0x1a65, Hi: 0x1a6c, Stride: 1},
 		{Lo: 0x1a65, Hi: 0x1a6c, Stride: 1},
 		{Lo: 0x1a73, Hi: 0x1a7c, Stride: 1},
 		{Lo: 0x1a73, Hi: 0x1a7c, Stride: 1},
 		{Lo: 0x1a7f, Hi: 0x1ab0, Stride: 49},
 		{Lo: 0x1a7f, Hi: 0x1ab0, Stride: 49},
-		{Lo: 0x1ab1, Hi: 0x1ac0, Stride: 1},
+		{Lo: 0x1ab1, Hi: 0x1ace, Stride: 1},
 		{Lo: 0x1b00, Hi: 0x1b03, Stride: 1},
 		{Lo: 0x1b00, Hi: 0x1b03, Stride: 1},
 		{Lo: 0x1b34, Hi: 0x1b3a, Stride: 1},
 		{Lo: 0x1b34, Hi: 0x1b3a, Stride: 1},
 		{Lo: 0x1b3c, Hi: 0x1b42, Stride: 6},
 		{Lo: 0x1b3c, Hi: 0x1b42, Stride: 6},
@@ -189,8 +190,7 @@ var GraphemeBreakExtend = &unicode.RangeTable{
 		{Lo: 0x1ce2, Hi: 0x1ce8, Stride: 1},
 		{Lo: 0x1ce2, Hi: 0x1ce8, Stride: 1},
 		{Lo: 0x1ced, Hi: 0x1cf4, Stride: 7},
 		{Lo: 0x1ced, Hi: 0x1cf4, Stride: 7},
 		{Lo: 0x1cf8, Hi: 0x1cf9, Stride: 1},
 		{Lo: 0x1cf8, Hi: 0x1cf9, Stride: 1},
-		{Lo: 0x1dc0, Hi: 0x1df9, Stride: 1},
-		{Lo: 0x1dfb, Hi: 0x1dff, Stride: 1},
+		{Lo: 0x1dc0, Hi: 0x1dff, Stride: 1},
 		{Lo: 0x200c, Hi: 0x20d0, Stride: 196},
 		{Lo: 0x200c, Hi: 0x20d0, Stride: 196},
 		{Lo: 0x20d1, Hi: 0x20f0, Stride: 1},
 		{Lo: 0x20d1, Hi: 0x20f0, Stride: 1},
 		{Lo: 0x2cef, Hi: 0x2cf1, Stride: 1},
 		{Lo: 0x2cef, Hi: 0x2cf1, Stride: 1},
@@ -242,13 +242,18 @@ var GraphemeBreakExtend = &unicode.RangeTable{
 		{Lo: 0x10ae6, Hi: 0x10d24, Stride: 574},
 		{Lo: 0x10ae6, Hi: 0x10d24, Stride: 574},
 		{Lo: 0x10d25, Hi: 0x10d27, Stride: 1},
 		{Lo: 0x10d25, Hi: 0x10d27, Stride: 1},
 		{Lo: 0x10eab, Hi: 0x10eac, Stride: 1},
 		{Lo: 0x10eab, Hi: 0x10eac, Stride: 1},
+		{Lo: 0x10efd, Hi: 0x10eff, Stride: 1},
 		{Lo: 0x10f46, Hi: 0x10f50, Stride: 1},
 		{Lo: 0x10f46, Hi: 0x10f50, Stride: 1},
+		{Lo: 0x10f82, Hi: 0x10f85, Stride: 1},
 		{Lo: 0x11001, Hi: 0x11038, Stride: 55},
 		{Lo: 0x11001, Hi: 0x11038, Stride: 55},
 		{Lo: 0x11039, Hi: 0x11046, Stride: 1},
 		{Lo: 0x11039, Hi: 0x11046, Stride: 1},
-		{Lo: 0x1107f, Hi: 0x11081, Stride: 1},
+		{Lo: 0x11070, Hi: 0x11073, Stride: 3},
+		{Lo: 0x11074, Hi: 0x1107f, Stride: 11},
+		{Lo: 0x11080, Hi: 0x11081, Stride: 1},
 		{Lo: 0x110b3, Hi: 0x110b6, Stride: 1},
 		{Lo: 0x110b3, Hi: 0x110b6, Stride: 1},
 		{Lo: 0x110b9, Hi: 0x110ba, Stride: 1},
 		{Lo: 0x110b9, Hi: 0x110ba, Stride: 1},
-		{Lo: 0x11100, Hi: 0x11102, Stride: 1},
+		{Lo: 0x110c2, Hi: 0x11100, Stride: 62},
+		{Lo: 0x11101, Hi: 0x11102, Stride: 1},
 		{Lo: 0x11127, Hi: 0x1112b, Stride: 1},
 		{Lo: 0x11127, Hi: 0x1112b, Stride: 1},
 		{Lo: 0x1112d, Hi: 0x11134, Stride: 1},
 		{Lo: 0x1112d, Hi: 0x11134, Stride: 1},
 		{Lo: 0x11173, Hi: 0x11180, Stride: 13},
 		{Lo: 0x11173, Hi: 0x11180, Stride: 13},
@@ -259,8 +264,8 @@ var GraphemeBreakExtend = &unicode.RangeTable{
 		{Lo: 0x11230, Hi: 0x11231, Stride: 1},
 		{Lo: 0x11230, Hi: 0x11231, Stride: 1},
 		{Lo: 0x11234, Hi: 0x11236, Stride: 2},
 		{Lo: 0x11234, Hi: 0x11236, Stride: 2},
 		{Lo: 0x11237, Hi: 0x1123e, Stride: 7},
 		{Lo: 0x11237, Hi: 0x1123e, Stride: 7},
-		{Lo: 0x112df, Hi: 0x112e3, Stride: 4},
-		{Lo: 0x112e4, Hi: 0x112ea, Stride: 1},
+		{Lo: 0x11241, Hi: 0x112df, Stride: 158},
+		{Lo: 0x112e3, Hi: 0x112ea, Stride: 1},
 		{Lo: 0x11300, Hi: 0x11301, Stride: 1},
 		{Lo: 0x11300, Hi: 0x11301, Stride: 1},
 		{Lo: 0x1133b, Hi: 0x1133c, Stride: 1},
 		{Lo: 0x1133b, Hi: 0x1133c, Stride: 1},
 		{Lo: 0x1133e, Hi: 0x11340, Stride: 2},
 		{Lo: 0x1133e, Hi: 0x11340, Stride: 2},
@@ -319,14 +324,22 @@ var GraphemeBreakExtend = &unicode.RangeTable{
 		{Lo: 0x11d47, Hi: 0x11d90, Stride: 73},
 		{Lo: 0x11d47, Hi: 0x11d90, Stride: 73},
 		{Lo: 0x11d91, Hi: 0x11d95, Stride: 4},
 		{Lo: 0x11d91, Hi: 0x11d95, Stride: 4},
 		{Lo: 0x11d97, Hi: 0x11ef3, Stride: 348},
 		{Lo: 0x11d97, Hi: 0x11ef3, Stride: 348},
-		{Lo: 0x11ef4, Hi: 0x16af0, Stride: 19452},
-		{Lo: 0x16af1, Hi: 0x16af4, Stride: 1},
+		{Lo: 0x11ef4, Hi: 0x11f00, Stride: 12},
+		{Lo: 0x11f01, Hi: 0x11f36, Stride: 53},
+		{Lo: 0x11f37, Hi: 0x11f3a, Stride: 1},
+		{Lo: 0x11f40, Hi: 0x11f42, Stride: 2},
+		{Lo: 0x13440, Hi: 0x13447, Stride: 7},
+		{Lo: 0x13448, Hi: 0x13455, Stride: 1},
+		{Lo: 0x16af0, Hi: 0x16af4, Stride: 1},
 		{Lo: 0x16b30, Hi: 0x16b36, Stride: 1},
 		{Lo: 0x16b30, Hi: 0x16b36, Stride: 1},
 		{Lo: 0x16f4f, Hi: 0x16f8f, Stride: 64},
 		{Lo: 0x16f4f, Hi: 0x16f8f, Stride: 64},
 		{Lo: 0x16f90, Hi: 0x16f92, Stride: 1},
 		{Lo: 0x16f90, Hi: 0x16f92, Stride: 1},
 		{Lo: 0x16fe4, Hi: 0x1bc9d, Stride: 19641},
 		{Lo: 0x16fe4, Hi: 0x1bc9d, Stride: 19641},
-		{Lo: 0x1bc9e, Hi: 0x1d165, Stride: 5319},
-		{Lo: 0x1d167, Hi: 0x1d169, Stride: 1},
+		{Lo: 0x1bc9e, Hi: 0x1cf00, Stride: 4706},
+		{Lo: 0x1cf01, Hi: 0x1cf2d, Stride: 1},
+		{Lo: 0x1cf30, Hi: 0x1cf46, Stride: 1},
+		{Lo: 0x1d165, Hi: 0x1d167, Stride: 2},
+		{Lo: 0x1d168, Hi: 0x1d169, Stride: 1},
 		{Lo: 0x1d16e, Hi: 0x1d172, Stride: 1},
 		{Lo: 0x1d16e, Hi: 0x1d172, Stride: 1},
 		{Lo: 0x1d17b, Hi: 0x1d182, Stride: 1},
 		{Lo: 0x1d17b, Hi: 0x1d182, Stride: 1},
 		{Lo: 0x1d185, Hi: 0x1d18b, Stride: 1},
 		{Lo: 0x1d185, Hi: 0x1d18b, Stride: 1},
@@ -342,8 +355,11 @@ var GraphemeBreakExtend = &unicode.RangeTable{
 		{Lo: 0x1e01b, Hi: 0x1e021, Stride: 1},
 		{Lo: 0x1e01b, Hi: 0x1e021, Stride: 1},
 		{Lo: 0x1e023, Hi: 0x1e024, Stride: 1},
 		{Lo: 0x1e023, Hi: 0x1e024, Stride: 1},
 		{Lo: 0x1e026, Hi: 0x1e02a, Stride: 1},
 		{Lo: 0x1e026, Hi: 0x1e02a, Stride: 1},
-		{Lo: 0x1e130, Hi: 0x1e136, Stride: 1},
-		{Lo: 0x1e2ec, Hi: 0x1e2ef, Stride: 1},
+		{Lo: 0x1e08f, Hi: 0x1e130, Stride: 161},
+		{Lo: 0x1e131, Hi: 0x1e136, Stride: 1},
+		{Lo: 0x1e2ae, Hi: 0x1e2ec, Stride: 62},
+		{Lo: 0x1e2ed, Hi: 0x1e2ef, Stride: 1},
+		{Lo: 0x1e4ec, Hi: 0x1e4ef, Stride: 1},
 		{Lo: 0x1e8d0, Hi: 0x1e8d6, Stride: 1},
 		{Lo: 0x1e8d0, Hi: 0x1e8d6, Stride: 1},
 		{Lo: 0x1e944, Hi: 0x1e94a, Stride: 1},
 		{Lo: 0x1e944, Hi: 0x1e94a, Stride: 1},
 		{Lo: 0x1f3fb, Hi: 0x1f3ff, Stride: 1},
 		{Lo: 0x1f3fb, Hi: 0x1f3ff, Stride: 1},
@@ -785,6 +801,7 @@ var GraphemeBreakPrepend = &unicode.RangeTable{
 	R16: []unicode.Range16{
 	R16: []unicode.Range16{
 		{Lo: 0x0600, Hi: 0x0605, Stride: 1},
 		{Lo: 0x0600, Hi: 0x0605, Stride: 1},
 		{Lo: 0x06dd, Hi: 0x070f, Stride: 50},
 		{Lo: 0x06dd, Hi: 0x070f, Stride: 50},
+		{Lo: 0x0890, Hi: 0x0891, Stride: 1},
 		{Lo: 0x08e2, Hi: 0x0d4e, Stride: 1132},
 		{Lo: 0x08e2, Hi: 0x0d4e, Stride: 1132},
 	},
 	},
 	R32: []unicode.Range32{
 	R32: []unicode.Range32{
@@ -793,7 +810,7 @@ var GraphemeBreakPrepend = &unicode.RangeTable{
 		{Lo: 0x1193f, Hi: 0x11941, Stride: 2},
 		{Lo: 0x1193f, Hi: 0x11941, Stride: 2},
 		{Lo: 0x11a3a, Hi: 0x11a84, Stride: 74},
 		{Lo: 0x11a3a, Hi: 0x11a84, Stride: 74},
 		{Lo: 0x11a85, Hi: 0x11a89, Stride: 1},
 		{Lo: 0x11a85, Hi: 0x11a89, Stride: 1},
-		{Lo: 0x11d46, Hi: 0x11d46, Stride: 1},
+		{Lo: 0x11d46, Hi: 0x11f02, Stride: 444},
 	},
 	},
 }
 }
 
 
@@ -835,10 +852,10 @@ var GraphemeBreakSpacingMark = &unicode.RangeTable{
 		{Lo: 0x0cc1, Hi: 0x0cc3, Stride: 2},
 		{Lo: 0x0cc1, Hi: 0x0cc3, Stride: 2},
 		{Lo: 0x0cc4, Hi: 0x0cc7, Stride: 3},
 		{Lo: 0x0cc4, Hi: 0x0cc7, Stride: 3},
 		{Lo: 0x0cc8, Hi: 0x0cca, Stride: 2},
 		{Lo: 0x0cc8, Hi: 0x0cca, Stride: 2},
-		{Lo: 0x0ccb, Hi: 0x0d02, Stride: 55},
-		{Lo: 0x0d03, Hi: 0x0d3f, Stride: 60},
-		{Lo: 0x0d40, Hi: 0x0d46, Stride: 6},
-		{Lo: 0x0d47, Hi: 0x0d48, Stride: 1},
+		{Lo: 0x0ccb, Hi: 0x0cf3, Stride: 40},
+		{Lo: 0x0d02, Hi: 0x0d03, Stride: 1},
+		{Lo: 0x0d3f, Hi: 0x0d40, Stride: 1},
+		{Lo: 0x0d46, Hi: 0x0d48, Stride: 1},
 		{Lo: 0x0d4a, Hi: 0x0d4c, Stride: 1},
 		{Lo: 0x0d4a, Hi: 0x0d4c, Stride: 1},
 		{Lo: 0x0d82, Hi: 0x0d83, Stride: 1},
 		{Lo: 0x0d82, Hi: 0x0d83, Stride: 1},
 		{Lo: 0x0dd0, Hi: 0x0dd1, Stride: 1},
 		{Lo: 0x0dd0, Hi: 0x0dd1, Stride: 1},
@@ -849,7 +866,8 @@ var GraphemeBreakSpacingMark = &unicode.RangeTable{
 		{Lo: 0x0f7f, Hi: 0x1031, Stride: 178},
 		{Lo: 0x0f7f, Hi: 0x1031, Stride: 178},
 		{Lo: 0x103b, Hi: 0x103c, Stride: 1},
 		{Lo: 0x103b, Hi: 0x103c, Stride: 1},
 		{Lo: 0x1056, Hi: 0x1057, Stride: 1},
 		{Lo: 0x1056, Hi: 0x1057, Stride: 1},
-		{Lo: 0x1084, Hi: 0x17b6, Stride: 1842},
+		{Lo: 0x1084, Hi: 0x1715, Stride: 1681},
+		{Lo: 0x1734, Hi: 0x17b6, Stride: 130},
 		{Lo: 0x17be, Hi: 0x17c5, Stride: 1},
 		{Lo: 0x17be, Hi: 0x17c5, Stride: 1},
 		{Lo: 0x17c7, Hi: 0x17c8, Stride: 1},
 		{Lo: 0x17c7, Hi: 0x17c8, Stride: 1},
 		{Lo: 0x1923, Hi: 0x1926, Stride: 1},
 		{Lo: 0x1923, Hi: 0x1926, Stride: 1},
@@ -922,8 +940,7 @@ var GraphemeBreakSpacingMark = &unicode.RangeTable{
 		{Lo: 0x1163b, Hi: 0x1163c, Stride: 1},
 		{Lo: 0x1163b, Hi: 0x1163c, Stride: 1},
 		{Lo: 0x1163e, Hi: 0x116ac, Stride: 110},
 		{Lo: 0x1163e, Hi: 0x116ac, Stride: 110},
 		{Lo: 0x116ae, Hi: 0x116af, Stride: 1},
 		{Lo: 0x116ae, Hi: 0x116af, Stride: 1},
-		{Lo: 0x116b6, Hi: 0x11720, Stride: 106},
-		{Lo: 0x11721, Hi: 0x11726, Stride: 5},
+		{Lo: 0x116b6, Hi: 0x11726, Stride: 112},
 		{Lo: 0x1182c, Hi: 0x1182e, Stride: 1},
 		{Lo: 0x1182c, Hi: 0x1182e, Stride: 1},
 		{Lo: 0x11838, Hi: 0x11931, Stride: 249},
 		{Lo: 0x11838, Hi: 0x11931, Stride: 249},
 		{Lo: 0x11932, Hi: 0x11935, Stride: 1},
 		{Lo: 0x11932, Hi: 0x11935, Stride: 1},
@@ -940,7 +957,10 @@ var GraphemeBreakSpacingMark = &unicode.RangeTable{
 		{Lo: 0x11d8a, Hi: 0x11d8e, Stride: 1},
 		{Lo: 0x11d8a, Hi: 0x11d8e, Stride: 1},
 		{Lo: 0x11d93, Hi: 0x11d94, Stride: 1},
 		{Lo: 0x11d93, Hi: 0x11d94, Stride: 1},
 		{Lo: 0x11d96, Hi: 0x11ef5, Stride: 351},
 		{Lo: 0x11d96, Hi: 0x11ef5, Stride: 351},
-		{Lo: 0x11ef6, Hi: 0x16f51, Stride: 20571},
+		{Lo: 0x11ef6, Hi: 0x11f03, Stride: 13},
+		{Lo: 0x11f34, Hi: 0x11f35, Stride: 1},
+		{Lo: 0x11f3e, Hi: 0x11f3f, Stride: 1},
+		{Lo: 0x11f41, Hi: 0x16f51, Stride: 20496},
 		{Lo: 0x16f52, Hi: 0x16f87, Stride: 1},
 		{Lo: 0x16f52, Hi: 0x16f87, Stride: 1},
 		{Lo: 0x16ff0, Hi: 0x16ff1, Stride: 1},
 		{Lo: 0x16ff0, Hi: 0x16ff1, Stride: 1},
 		{Lo: 0x1d166, Hi: 0x1d16d, Stride: 7},
 		{Lo: 0x1d166, Hi: 0x1d16d, Stride: 7},
@@ -1002,7 +1022,9 @@ var graphemeBreakAll = &unicode.RangeTable{
 		{Lo: 0x0825, Hi: 0x0827, Stride: 1},
 		{Lo: 0x0825, Hi: 0x0827, Stride: 1},
 		{Lo: 0x0829, Hi: 0x082d, Stride: 1},
 		{Lo: 0x0829, Hi: 0x082d, Stride: 1},
 		{Lo: 0x0859, Hi: 0x085b, Stride: 1},
 		{Lo: 0x0859, Hi: 0x085b, Stride: 1},
-		{Lo: 0x08d3, Hi: 0x0903, Stride: 1},
+		{Lo: 0x0890, Hi: 0x0891, Stride: 1},
+		{Lo: 0x0898, Hi: 0x089f, Stride: 1},
+		{Lo: 0x08ca, Hi: 0x0903, Stride: 1},
 		{Lo: 0x093a, Hi: 0x093c, Stride: 1},
 		{Lo: 0x093a, Hi: 0x093c, Stride: 1},
 		{Lo: 0x093e, Hi: 0x094f, Stride: 1},
 		{Lo: 0x093e, Hi: 0x094f, Stride: 1},
 		{Lo: 0x0951, Hi: 0x0957, Stride: 1},
 		{Lo: 0x0951, Hi: 0x0957, Stride: 1},
@@ -1043,6 +1065,7 @@ var graphemeBreakAll = &unicode.RangeTable{
 		{Lo: 0x0bca, Hi: 0x0bcd, Stride: 1},
 		{Lo: 0x0bca, Hi: 0x0bcd, Stride: 1},
 		{Lo: 0x0bd7, Hi: 0x0c00, Stride: 41},
 		{Lo: 0x0bd7, Hi: 0x0c00, Stride: 41},
 		{Lo: 0x0c01, Hi: 0x0c04, Stride: 1},
 		{Lo: 0x0c01, Hi: 0x0c04, Stride: 1},
+		{Lo: 0x0c3c, Hi: 0x0c3c, Stride: 56},
 		{Lo: 0x0c3e, Hi: 0x0c44, Stride: 1},
 		{Lo: 0x0c3e, Hi: 0x0c44, Stride: 1},
 		{Lo: 0x0c46, Hi: 0x0c48, Stride: 1},
 		{Lo: 0x0c46, Hi: 0x0c48, Stride: 1},
 		{Lo: 0x0c4a, Hi: 0x0c4d, Stride: 1},
 		{Lo: 0x0c4a, Hi: 0x0c4d, Stride: 1},
@@ -1055,8 +1078,8 @@ var graphemeBreakAll = &unicode.RangeTable{
 		{Lo: 0x0cca, Hi: 0x0ccd, Stride: 1},
 		{Lo: 0x0cca, Hi: 0x0ccd, Stride: 1},
 		{Lo: 0x0cd5, Hi: 0x0cd5, Stride: 8},
 		{Lo: 0x0cd5, Hi: 0x0cd5, Stride: 8},
 		{Lo: 0x0cd6, Hi: 0x0ce2, Stride: 12},
 		{Lo: 0x0cd6, Hi: 0x0ce2, Stride: 12},
-		{Lo: 0x0ce3, Hi: 0x0d00, Stride: 29},
-		{Lo: 0x0d01, Hi: 0x0d03, Stride: 1},
+		{Lo: 0x0ce3, Hi: 0x0cf3, Stride: 16},
+		{Lo: 0x0d00, Hi: 0x0d03, Stride: 1},
 		{Lo: 0x0d3b, Hi: 0x0d3c, Stride: 1},
 		{Lo: 0x0d3b, Hi: 0x0d3c, Stride: 1},
 		{Lo: 0x0d3e, Hi: 0x0d44, Stride: 1},
 		{Lo: 0x0d3e, Hi: 0x0d44, Stride: 1},
 		{Lo: 0x0d46, Hi: 0x0d48, Stride: 1},
 		{Lo: 0x0d46, Hi: 0x0d48, Stride: 1},
@@ -1074,7 +1097,7 @@ var graphemeBreakAll = &unicode.RangeTable{
 		{Lo: 0x0e47, Hi: 0x0e4e, Stride: 1},
 		{Lo: 0x0e47, Hi: 0x0e4e, Stride: 1},
 		{Lo: 0x0eb1, Hi: 0x0eb3, Stride: 2},
 		{Lo: 0x0eb1, Hi: 0x0eb3, Stride: 2},
 		{Lo: 0x0eb4, Hi: 0x0ebc, Stride: 1},
 		{Lo: 0x0eb4, Hi: 0x0ebc, Stride: 1},
-		{Lo: 0x0ec8, Hi: 0x0ecd, Stride: 1},
+		{Lo: 0x0ec8, Hi: 0x0ece, Stride: 1},
 		{Lo: 0x0f18, Hi: 0x0f19, Stride: 1},
 		{Lo: 0x0f18, Hi: 0x0f19, Stride: 1},
 		{Lo: 0x0f35, Hi: 0x0f39, Stride: 2},
 		{Lo: 0x0f35, Hi: 0x0f39, Stride: 2},
 		{Lo: 0x0f3e, Hi: 0x0f3f, Stride: 1},
 		{Lo: 0x0f3e, Hi: 0x0f3f, Stride: 1},
@@ -1093,23 +1116,23 @@ var graphemeBreakAll = &unicode.RangeTable{
 		{Lo: 0x108d, Hi: 0x109d, Stride: 16},
 		{Lo: 0x108d, Hi: 0x109d, Stride: 16},
 		{Lo: 0x1100, Hi: 0x11ff, Stride: 1},
 		{Lo: 0x1100, Hi: 0x11ff, Stride: 1},
 		{Lo: 0x135d, Hi: 0x135f, Stride: 1},
 		{Lo: 0x135d, Hi: 0x135f, Stride: 1},
-		{Lo: 0x1712, Hi: 0x1714, Stride: 1},
+		{Lo: 0x1712, Hi: 0x1715, Stride: 1},
 		{Lo: 0x1732, Hi: 0x1734, Stride: 1},
 		{Lo: 0x1732, Hi: 0x1734, Stride: 1},
 		{Lo: 0x1752, Hi: 0x1753, Stride: 1},
 		{Lo: 0x1752, Hi: 0x1753, Stride: 1},
 		{Lo: 0x1772, Hi: 0x1773, Stride: 1},
 		{Lo: 0x1772, Hi: 0x1773, Stride: 1},
 		{Lo: 0x17b4, Hi: 0x17d3, Stride: 1},
 		{Lo: 0x17b4, Hi: 0x17d3, Stride: 1},
 		{Lo: 0x17dd, Hi: 0x180b, Stride: 46},
 		{Lo: 0x17dd, Hi: 0x180b, Stride: 46},
-		{Lo: 0x180c, Hi: 0x180e, Stride: 1},
-		{Lo: 0x1885, Hi: 0x1886, Stride: 1},
-		{Lo: 0x18a9, Hi: 0x1920, Stride: 119},
-		{Lo: 0x1921, Hi: 0x192b, Stride: 1},
+		{Lo: 0x180c, Hi: 0x180f, Stride: 1},
+		{Lo: 0x1885, Hi: 0x1885, Stride: 118},
+		{Lo: 0x1886, Hi: 0x18a9, Stride: 35},
+		{Lo: 0x1920, Hi: 0x192b, Stride: 1},
 		{Lo: 0x1930, Hi: 0x193b, Stride: 1},
 		{Lo: 0x1930, Hi: 0x193b, Stride: 1},
 		{Lo: 0x1a17, Hi: 0x1a1b, Stride: 1},
 		{Lo: 0x1a17, Hi: 0x1a1b, Stride: 1},
 		{Lo: 0x1a55, Hi: 0x1a5e, Stride: 1},
 		{Lo: 0x1a55, Hi: 0x1a5e, Stride: 1},
 		{Lo: 0x1a60, Hi: 0x1a62, Stride: 2},
 		{Lo: 0x1a60, Hi: 0x1a62, Stride: 2},
 		{Lo: 0x1a65, Hi: 0x1a7c, Stride: 1},
 		{Lo: 0x1a65, Hi: 0x1a7c, Stride: 1},
 		{Lo: 0x1a7f, Hi: 0x1ab0, Stride: 49},
 		{Lo: 0x1a7f, Hi: 0x1ab0, Stride: 49},
-		{Lo: 0x1ab1, Hi: 0x1ac0, Stride: 1},
+		{Lo: 0x1ab1, Hi: 0x1ace, Stride: 1},
 		{Lo: 0x1b00, Hi: 0x1b04, Stride: 1},
 		{Lo: 0x1b00, Hi: 0x1b04, Stride: 1},
 		{Lo: 0x1b34, Hi: 0x1b44, Stride: 1},
 		{Lo: 0x1b34, Hi: 0x1b44, Stride: 1},
 		{Lo: 0x1b6b, Hi: 0x1b73, Stride: 1},
 		{Lo: 0x1b6b, Hi: 0x1b73, Stride: 1},
@@ -1121,8 +1144,7 @@ var graphemeBreakAll = &unicode.RangeTable{
 		{Lo: 0x1cd4, Hi: 0x1ce8, Stride: 1},
 		{Lo: 0x1cd4, Hi: 0x1ce8, Stride: 1},
 		{Lo: 0x1ced, Hi: 0x1cf4, Stride: 7},
 		{Lo: 0x1ced, Hi: 0x1cf4, Stride: 7},
 		{Lo: 0x1cf7, Hi: 0x1cf9, Stride: 1},
 		{Lo: 0x1cf7, Hi: 0x1cf9, Stride: 1},
-		{Lo: 0x1dc0, Hi: 0x1df9, Stride: 1},
-		{Lo: 0x1dfb, Hi: 0x1dff, Stride: 1},
+		{Lo: 0x1dc0, Hi: 0x1dff, Stride: 1},
 		{Lo: 0x200b, Hi: 0x200f, Stride: 1},
 		{Lo: 0x200b, Hi: 0x200f, Stride: 1},
 		{Lo: 0x2028, Hi: 0x202e, Stride: 1},
 		{Lo: 0x2028, Hi: 0x202e, Stride: 1},
 		{Lo: 0x2060, Hi: 0x206f, Stride: 1},
 		{Lo: 0x2060, Hi: 0x206f, Stride: 1},
@@ -1183,13 +1205,18 @@ var graphemeBreakAll = &unicode.RangeTable{
 		{Lo: 0x10ae6, Hi: 0x10d24, Stride: 574},
 		{Lo: 0x10ae6, Hi: 0x10d24, Stride: 574},
 		{Lo: 0x10d25, Hi: 0x10d27, Stride: 1},
 		{Lo: 0x10d25, Hi: 0x10d27, Stride: 1},
 		{Lo: 0x10eab, Hi: 0x10eac, Stride: 1},
 		{Lo: 0x10eab, Hi: 0x10eac, Stride: 1},
+		{Lo: 0x10efd, Hi: 0x10eff, Stride: 1},
 		{Lo: 0x10f46, Hi: 0x10f50, Stride: 1},
 		{Lo: 0x10f46, Hi: 0x10f50, Stride: 1},
+		{Lo: 0x10f82, Hi: 0x10f85, Stride: 1},
 		{Lo: 0x11000, Hi: 0x11002, Stride: 1},
 		{Lo: 0x11000, Hi: 0x11002, Stride: 1},
 		{Lo: 0x11038, Hi: 0x11046, Stride: 1},
 		{Lo: 0x11038, Hi: 0x11046, Stride: 1},
-		{Lo: 0x1107f, Hi: 0x11082, Stride: 1},
+		{Lo: 0x11070, Hi: 0x11073, Stride: 3},
+		{Lo: 0x11074, Hi: 0x1107f, Stride: 11},
+		{Lo: 0x11080, Hi: 0x11082, Stride: 1},
 		{Lo: 0x110b0, Hi: 0x110ba, Stride: 1},
 		{Lo: 0x110b0, Hi: 0x110ba, Stride: 1},
-		{Lo: 0x110bd, Hi: 0x110cd, Stride: 16},
-		{Lo: 0x11100, Hi: 0x11102, Stride: 1},
+		{Lo: 0x110bd, Hi: 0x110c2, Stride: 5},
+		{Lo: 0x110cd, Hi: 0x11100, Stride: 51},
+		{Lo: 0x11101, Hi: 0x11102, Stride: 1},
 		{Lo: 0x11127, Hi: 0x11134, Stride: 1},
 		{Lo: 0x11127, Hi: 0x11134, Stride: 1},
 		{Lo: 0x11145, Hi: 0x11146, Stride: 1},
 		{Lo: 0x11145, Hi: 0x11146, Stride: 1},
 		{Lo: 0x11173, Hi: 0x11180, Stride: 13},
 		{Lo: 0x11173, Hi: 0x11180, Stride: 13},
@@ -1199,7 +1226,8 @@ var graphemeBreakAll = &unicode.RangeTable{
 		{Lo: 0x111c9, Hi: 0x111cc, Stride: 1},
 		{Lo: 0x111c9, Hi: 0x111cc, Stride: 1},
 		{Lo: 0x111ce, Hi: 0x111cf, Stride: 1},
 		{Lo: 0x111ce, Hi: 0x111cf, Stride: 1},
 		{Lo: 0x1122c, Hi: 0x11237, Stride: 1},
 		{Lo: 0x1122c, Hi: 0x11237, Stride: 1},
-		{Lo: 0x1123e, Hi: 0x112df, Stride: 161},
+		{Lo: 0x1123e, Hi: 0x1123e, Stride: 7},
+		{Lo: 0x11241, Hi: 0x112df, Stride: 158},
 		{Lo: 0x112e0, Hi: 0x112ea, Stride: 1},
 		{Lo: 0x112e0, Hi: 0x112ea, Stride: 1},
 		{Lo: 0x11300, Hi: 0x11303, Stride: 1},
 		{Lo: 0x11300, Hi: 0x11303, Stride: 1},
 		{Lo: 0x1133b, Hi: 0x1133c, Stride: 1},
 		{Lo: 0x1133b, Hi: 0x1133c, Stride: 1},
@@ -1218,7 +1246,8 @@ var graphemeBreakAll = &unicode.RangeTable{
 		{Lo: 0x115dc, Hi: 0x115dd, Stride: 1},
 		{Lo: 0x115dc, Hi: 0x115dd, Stride: 1},
 		{Lo: 0x11630, Hi: 0x11640, Stride: 1},
 		{Lo: 0x11630, Hi: 0x11640, Stride: 1},
 		{Lo: 0x116ab, Hi: 0x116b7, Stride: 1},
 		{Lo: 0x116ab, Hi: 0x116b7, Stride: 1},
-		{Lo: 0x1171d, Hi: 0x1172b, Stride: 1},
+		{Lo: 0x1171d, Hi: 0x1171f, Stride: 1},
+		{Lo: 0x11722, Hi: 0x1172b, Stride: 1},
 		{Lo: 0x1182c, Hi: 0x1183a, Stride: 1},
 		{Lo: 0x1182c, Hi: 0x1183a, Stride: 1},
 		{Lo: 0x11930, Hi: 0x11935, Stride: 1},
 		{Lo: 0x11930, Hi: 0x11935, Stride: 1},
 		{Lo: 0x11937, Hi: 0x11938, Stride: 1},
 		{Lo: 0x11937, Hi: 0x11938, Stride: 1},
@@ -1243,7 +1272,11 @@ var graphemeBreakAll = &unicode.RangeTable{
 		{Lo: 0x11d90, Hi: 0x11d91, Stride: 1},
 		{Lo: 0x11d90, Hi: 0x11d91, Stride: 1},
 		{Lo: 0x11d93, Hi: 0x11d97, Stride: 1},
 		{Lo: 0x11d93, Hi: 0x11d97, Stride: 1},
 		{Lo: 0x11ef3, Hi: 0x11ef6, Stride: 1},
 		{Lo: 0x11ef3, Hi: 0x11ef6, Stride: 1},
-		{Lo: 0x13430, Hi: 0x13438, Stride: 1},
+		{Lo: 0x11f00, Hi: 0x11f03, Stride: 1},
+		{Lo: 0x11f34, Hi: 0x11f3a, Stride: 1},
+		{Lo: 0x11f3e, Hi: 0x11f42, Stride: 1},
+		{Lo: 0x13430, Hi: 0x13440, Stride: 1},
+		{Lo: 0x13447, Hi: 0x13455, Stride: 1},
 		{Lo: 0x16af0, Hi: 0x16af4, Stride: 1},
 		{Lo: 0x16af0, Hi: 0x16af4, Stride: 1},
 		{Lo: 0x16b30, Hi: 0x16b36, Stride: 1},
 		{Lo: 0x16b30, Hi: 0x16b36, Stride: 1},
 		{Lo: 0x16f4f, Hi: 0x16f51, Stride: 2},
 		{Lo: 0x16f4f, Hi: 0x16f51, Stride: 2},
@@ -1253,6 +1286,8 @@ var graphemeBreakAll = &unicode.RangeTable{
 		{Lo: 0x16ff0, Hi: 0x16ff1, Stride: 1},
 		{Lo: 0x16ff0, Hi: 0x16ff1, Stride: 1},
 		{Lo: 0x1bc9d, Hi: 0x1bc9e, Stride: 1},
 		{Lo: 0x1bc9d, Hi: 0x1bc9e, Stride: 1},
 		{Lo: 0x1bca0, Hi: 0x1bca3, Stride: 1},
 		{Lo: 0x1bca0, Hi: 0x1bca3, Stride: 1},
+		{Lo: 0x1cf00, Hi: 0x1cf2d, Stride: 1},
+		{Lo: 0x1cf30, Hi: 0x1cf46, Stride: 1},
 		{Lo: 0x1d165, Hi: 0x1d169, Stride: 1},
 		{Lo: 0x1d165, Hi: 0x1d169, Stride: 1},
 		{Lo: 0x1d16d, Hi: 0x1d182, Stride: 1},
 		{Lo: 0x1d16d, Hi: 0x1d182, Stride: 1},
 		{Lo: 0x1d185, Hi: 0x1d18b, Stride: 1},
 		{Lo: 0x1d185, Hi: 0x1d18b, Stride: 1},
@@ -1268,8 +1303,11 @@ var graphemeBreakAll = &unicode.RangeTable{
 		{Lo: 0x1e01b, Hi: 0x1e021, Stride: 1},
 		{Lo: 0x1e01b, Hi: 0x1e021, Stride: 1},
 		{Lo: 0x1e023, Hi: 0x1e024, Stride: 1},
 		{Lo: 0x1e023, Hi: 0x1e024, Stride: 1},
 		{Lo: 0x1e026, Hi: 0x1e02a, Stride: 1},
 		{Lo: 0x1e026, Hi: 0x1e02a, Stride: 1},
-		{Lo: 0x1e130, Hi: 0x1e136, Stride: 1},
-		{Lo: 0x1e2ec, Hi: 0x1e2ef, Stride: 1},
+		{Lo: 0x1e08f, Hi: 0x1e130, Stride: 161},
+		{Lo: 0x1e131, Hi: 0x1e136, Stride: 1},
+		{Lo: 0x1e2ae, Hi: 0x1e2ec, Stride: 62},
+		{Lo: 0x1e2ed, Hi: 0x1e2ef, Stride: 1},
+		{Lo: 0x1e4ec, Hi: 0x1e4ef, Stride: 1},
 		{Lo: 0x1e8d0, Hi: 0x1e8d6, Stride: 1},
 		{Lo: 0x1e8d0, Hi: 0x1e8d6, Stride: 1},
 		{Lo: 0x1e944, Hi: 0x1e94a, Stride: 1},
 		{Lo: 0x1e944, Hi: 0x1e94a, Stride: 1},
 		{Lo: 0x1f1e6, Hi: 0x1f1ff, Stride: 1},
 		{Lo: 0x1f1e6, Hi: 0x1f1ff, Stride: 1},

+ 7 - 2
vendor/github.com/go-text/typesetting/unicodedata/indic.go

@@ -118,14 +118,17 @@ var IndicVowel_Dependent = &unicode.RangeTable{
 		{Lo: 0x10a05, Hi: 0x10a06, Stride: 1},
 		{Lo: 0x10a05, Hi: 0x10a06, Stride: 1},
 		{Lo: 0x10a0c, Hi: 0x10a0d, Stride: 1},
 		{Lo: 0x10a0c, Hi: 0x10a0d, Stride: 1},
 		{Lo: 0x11038, Hi: 0x11045, Stride: 1},
 		{Lo: 0x11038, Hi: 0x11045, Stride: 1},
+		{Lo: 0x11073, Hi: 0x11074, Stride: 1},
 		{Lo: 0x110b0, Hi: 0x110b8, Stride: 1},
 		{Lo: 0x110b0, Hi: 0x110b8, Stride: 1},
-		{Lo: 0x11127, Hi: 0x11132, Stride: 1},
+		{Lo: 0x110c2, Hi: 0x11127, Stride: 101},
+		{Lo: 0x11128, Hi: 0x11132, Stride: 1},
 		{Lo: 0x11145, Hi: 0x11146, Stride: 1},
 		{Lo: 0x11145, Hi: 0x11146, Stride: 1},
 		{Lo: 0x111b3, Hi: 0x111bf, Stride: 1},
 		{Lo: 0x111b3, Hi: 0x111bf, Stride: 1},
 		{Lo: 0x111cb, Hi: 0x111cc, Stride: 1},
 		{Lo: 0x111cb, Hi: 0x111cc, Stride: 1},
 		{Lo: 0x111ce, Hi: 0x1122c, Stride: 94},
 		{Lo: 0x111ce, Hi: 0x1122c, Stride: 94},
 		{Lo: 0x1122d, Hi: 0x11233, Stride: 1},
 		{Lo: 0x1122d, Hi: 0x11233, Stride: 1},
-		{Lo: 0x112e0, Hi: 0x112e8, Stride: 1},
+		{Lo: 0x11241, Hi: 0x112e0, Stride: 159},
+		{Lo: 0x112e1, Hi: 0x112e8, Stride: 1},
 		{Lo: 0x1133e, Hi: 0x11344, Stride: 1},
 		{Lo: 0x1133e, Hi: 0x11344, Stride: 1},
 		{Lo: 0x11347, Hi: 0x11348, Stride: 1},
 		{Lo: 0x11347, Hi: 0x11348, Stride: 1},
 		{Lo: 0x1134b, Hi: 0x1134c, Stride: 1},
 		{Lo: 0x1134b, Hi: 0x1134c, Stride: 1},
@@ -159,5 +162,7 @@ var IndicVowel_Dependent = &unicode.RangeTable{
 		{Lo: 0x11d90, Hi: 0x11d91, Stride: 1},
 		{Lo: 0x11d90, Hi: 0x11d91, Stride: 1},
 		{Lo: 0x11d93, Hi: 0x11d94, Stride: 1},
 		{Lo: 0x11d93, Hi: 0x11d94, Stride: 1},
 		{Lo: 0x11ef3, Hi: 0x11ef6, Stride: 1},
 		{Lo: 0x11ef3, Hi: 0x11ef6, Stride: 1},
+		{Lo: 0x11f34, Hi: 0x11f3a, Stride: 1},
+		{Lo: 0x11f3e, Hi: 0x11f40, Stride: 1},
 	},
 	},
 }
 }

+ 152 - 71
vendor/github.com/go-text/typesetting/unicodedata/linebreak.go

@@ -106,11 +106,14 @@ var BreakNU = &unicode.RangeTable{
 		{Lo: 0x11c50, Hi: 0x11c59, Stride: 1},
 		{Lo: 0x11c50, Hi: 0x11c59, Stride: 1},
 		{Lo: 0x11d50, Hi: 0x11d59, Stride: 1},
 		{Lo: 0x11d50, Hi: 0x11d59, Stride: 1},
 		{Lo: 0x11da0, Hi: 0x11da9, Stride: 1},
 		{Lo: 0x11da0, Hi: 0x11da9, Stride: 1},
+		{Lo: 0x11f50, Hi: 0x11f59, Stride: 1},
 		{Lo: 0x16a60, Hi: 0x16a69, Stride: 1},
 		{Lo: 0x16a60, Hi: 0x16a69, Stride: 1},
+		{Lo: 0x16ac0, Hi: 0x16ac9, Stride: 1},
 		{Lo: 0x16b50, Hi: 0x16b59, Stride: 1},
 		{Lo: 0x16b50, Hi: 0x16b59, Stride: 1},
 		{Lo: 0x1d7ce, Hi: 0x1d7ff, Stride: 1},
 		{Lo: 0x1d7ce, Hi: 0x1d7ff, Stride: 1},
 		{Lo: 0x1e140, Hi: 0x1e149, Stride: 1},
 		{Lo: 0x1e140, Hi: 0x1e149, Stride: 1},
 		{Lo: 0x1e2f0, Hi: 0x1e2f9, Stride: 1},
 		{Lo: 0x1e2f0, Hi: 0x1e2f9, Stride: 1},
+		{Lo: 0x1e4f0, Hi: 0x1e4f9, Stride: 1},
 		{Lo: 0x1e950, Hi: 0x1e959, Stride: 1},
 		{Lo: 0x1e950, Hi: 0x1e959, Stride: 1},
 		{Lo: 0x1fbf0, Hi: 0x1fbf9, Stride: 1},
 		{Lo: 0x1fbf0, Hi: 0x1fbf9, Stride: 1},
 	},
 	},
@@ -173,8 +176,9 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x0840, Hi: 0x0858, Stride: 1},
 		{Lo: 0x0840, Hi: 0x0858, Stride: 1},
 		{Lo: 0x085e, Hi: 0x0860, Stride: 2},
 		{Lo: 0x085e, Hi: 0x0860, Stride: 2},
 		{Lo: 0x0861, Hi: 0x086a, Stride: 1},
 		{Lo: 0x0861, Hi: 0x086a, Stride: 1},
-		{Lo: 0x08a0, Hi: 0x08b4, Stride: 1},
-		{Lo: 0x08b6, Hi: 0x08c7, Stride: 1},
+		{Lo: 0x0870, Hi: 0x088e, Stride: 1},
+		{Lo: 0x0890, Hi: 0x0891, Stride: 1},
+		{Lo: 0x08a0, Hi: 0x08c9, Stride: 1},
 		{Lo: 0x08e2, Hi: 0x0904, Stride: 34},
 		{Lo: 0x08e2, Hi: 0x0904, Stride: 34},
 		{Lo: 0x0905, Hi: 0x0939, Stride: 1},
 		{Lo: 0x0905, Hi: 0x0939, Stride: 1},
 		{Lo: 0x093d, Hi: 0x0950, Stride: 19},
 		{Lo: 0x093d, Hi: 0x0950, Stride: 19},
@@ -242,17 +246,19 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x0c2a, Hi: 0x0c39, Stride: 1},
 		{Lo: 0x0c2a, Hi: 0x0c39, Stride: 1},
 		{Lo: 0x0c3d, Hi: 0x0c58, Stride: 27},
 		{Lo: 0x0c3d, Hi: 0x0c58, Stride: 27},
 		{Lo: 0x0c59, Hi: 0x0c5a, Stride: 1},
 		{Lo: 0x0c59, Hi: 0x0c5a, Stride: 1},
-		{Lo: 0x0c60, Hi: 0x0c61, Stride: 1},
-		{Lo: 0x0c78, Hi: 0x0c80, Stride: 1},
+		{Lo: 0x0c5d, Hi: 0x0c60, Stride: 3},
+		{Lo: 0x0c61, Hi: 0x0c78, Stride: 23},
+		{Lo: 0x0c79, Hi: 0x0c80, Stride: 1},
 		{Lo: 0x0c85, Hi: 0x0c8c, Stride: 1},
 		{Lo: 0x0c85, Hi: 0x0c8c, Stride: 1},
 		{Lo: 0x0c8e, Hi: 0x0c90, Stride: 1},
 		{Lo: 0x0c8e, Hi: 0x0c90, Stride: 1},
 		{Lo: 0x0c92, Hi: 0x0ca8, Stride: 1},
 		{Lo: 0x0c92, Hi: 0x0ca8, Stride: 1},
 		{Lo: 0x0caa, Hi: 0x0cb3, Stride: 1},
 		{Lo: 0x0caa, Hi: 0x0cb3, Stride: 1},
 		{Lo: 0x0cb5, Hi: 0x0cb9, Stride: 1},
 		{Lo: 0x0cb5, Hi: 0x0cb9, Stride: 1},
-		{Lo: 0x0cbd, Hi: 0x0cde, Stride: 33},
-		{Lo: 0x0ce0, Hi: 0x0ce1, Stride: 1},
-		{Lo: 0x0cf1, Hi: 0x0cf2, Stride: 1},
-		{Lo: 0x0d04, Hi: 0x0d0c, Stride: 1},
+		{Lo: 0x0cbd, Hi: 0x0cdd, Stride: 32},
+		{Lo: 0x0cde, Hi: 0x0ce0, Stride: 2},
+		{Lo: 0x0ce1, Hi: 0x0cf1, Stride: 16},
+		{Lo: 0x0cf2, Hi: 0x0d04, Stride: 18},
+		{Lo: 0x0d05, Hi: 0x0d0c, Stride: 1},
 		{Lo: 0x0d0e, Hi: 0x0d10, Stride: 1},
 		{Lo: 0x0d0e, Hi: 0x0d10, Stride: 1},
 		{Lo: 0x0d12, Hi: 0x0d3a, Stride: 1},
 		{Lo: 0x0d12, Hi: 0x0d3a, Stride: 1},
 		{Lo: 0x0d3d, Hi: 0x0d4e, Stride: 17},
 		{Lo: 0x0d3d, Hi: 0x0d4e, Stride: 17},
@@ -309,9 +315,8 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x1681, Hi: 0x169a, Stride: 1},
 		{Lo: 0x1681, Hi: 0x169a, Stride: 1},
 		{Lo: 0x16a0, Hi: 0x16ea, Stride: 1},
 		{Lo: 0x16a0, Hi: 0x16ea, Stride: 1},
 		{Lo: 0x16ee, Hi: 0x16f8, Stride: 1},
 		{Lo: 0x16ee, Hi: 0x16f8, Stride: 1},
-		{Lo: 0x1700, Hi: 0x170c, Stride: 1},
-		{Lo: 0x170e, Hi: 0x1711, Stride: 1},
-		{Lo: 0x1720, Hi: 0x1731, Stride: 1},
+		{Lo: 0x1700, Hi: 0x1711, Stride: 1},
+		{Lo: 0x171f, Hi: 0x1731, Stride: 1},
 		{Lo: 0x1740, Hi: 0x1751, Stride: 1},
 		{Lo: 0x1740, Hi: 0x1751, Stride: 1},
 		{Lo: 0x1760, Hi: 0x176c, Stride: 1},
 		{Lo: 0x1760, Hi: 0x176c, Stride: 1},
 		{Lo: 0x176e, Hi: 0x1770, Stride: 1},
 		{Lo: 0x176e, Hi: 0x1770, Stride: 1},
@@ -329,7 +334,7 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x19e1, Hi: 0x1a16, Stride: 1},
 		{Lo: 0x19e1, Hi: 0x1a16, Stride: 1},
 		{Lo: 0x1a1e, Hi: 0x1a1f, Stride: 1},
 		{Lo: 0x1a1e, Hi: 0x1a1f, Stride: 1},
 		{Lo: 0x1b05, Hi: 0x1b33, Stride: 1},
 		{Lo: 0x1b05, Hi: 0x1b33, Stride: 1},
-		{Lo: 0x1b45, Hi: 0x1b4b, Stride: 1},
+		{Lo: 0x1b45, Hi: 0x1b4c, Stride: 1},
 		{Lo: 0x1b5c, Hi: 0x1b61, Stride: 5},
 		{Lo: 0x1b5c, Hi: 0x1b61, Stride: 5},
 		{Lo: 0x1b62, Hi: 0x1b6a, Stride: 1},
 		{Lo: 0x1b62, Hi: 0x1b6a, Stride: 1},
 		{Lo: 0x1b74, Hi: 0x1b7c, Stride: 1},
 		{Lo: 0x1b74, Hi: 0x1b7c, Stride: 1},
@@ -367,7 +372,7 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x2038, Hi: 0x203e, Stride: 6},
 		{Lo: 0x2038, Hi: 0x203e, Stride: 6},
 		{Lo: 0x203f, Hi: 0x2043, Stride: 1},
 		{Lo: 0x203f, Hi: 0x2043, Stride: 1},
 		{Lo: 0x204a, Hi: 0x2055, Stride: 1},
 		{Lo: 0x204a, Hi: 0x2055, Stride: 1},
-		{Lo: 0x2057, Hi: 0x2061, Stride: 5},
+		{Lo: 0x205c, Hi: 0x2061, Stride: 5},
 		{Lo: 0x2062, Hi: 0x2064, Stride: 1},
 		{Lo: 0x2062, Hi: 0x2064, Stride: 1},
 		{Lo: 0x2070, Hi: 0x2071, Stride: 1},
 		{Lo: 0x2070, Hi: 0x2071, Stride: 1},
 		{Lo: 0x2075, Hi: 0x207c, Stride: 1},
 		{Lo: 0x2075, Hi: 0x207c, Stride: 1},
@@ -469,9 +474,7 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x29fe, Hi: 0x2b54, Stride: 1},
 		{Lo: 0x29fe, Hi: 0x2b54, Stride: 1},
 		{Lo: 0x2b5a, Hi: 0x2b73, Stride: 1},
 		{Lo: 0x2b5a, Hi: 0x2b73, Stride: 1},
 		{Lo: 0x2b76, Hi: 0x2b95, Stride: 1},
 		{Lo: 0x2b76, Hi: 0x2b95, Stride: 1},
-		{Lo: 0x2b97, Hi: 0x2c2e, Stride: 1},
-		{Lo: 0x2c30, Hi: 0x2c5e, Stride: 1},
-		{Lo: 0x2c60, Hi: 0x2cee, Stride: 1},
+		{Lo: 0x2b97, Hi: 0x2cee, Stride: 1},
 		{Lo: 0x2cf2, Hi: 0x2cf3, Stride: 1},
 		{Lo: 0x2cf2, Hi: 0x2cf3, Stride: 1},
 		{Lo: 0x2cfd, Hi: 0x2d00, Stride: 3},
 		{Lo: 0x2cfd, Hi: 0x2d00, Stride: 3},
 		{Lo: 0x2d01, Hi: 0x2d25, Stride: 1},
 		{Lo: 0x2d01, Hi: 0x2d25, Stride: 1},
@@ -505,9 +508,11 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0xa67f, Hi: 0xa69d, Stride: 1},
 		{Lo: 0xa67f, Hi: 0xa69d, Stride: 1},
 		{Lo: 0xa6a0, Hi: 0xa6ef, Stride: 1},
 		{Lo: 0xa6a0, Hi: 0xa6ef, Stride: 1},
 		{Lo: 0xa6f2, Hi: 0xa700, Stride: 14},
 		{Lo: 0xa6f2, Hi: 0xa700, Stride: 14},
-		{Lo: 0xa701, Hi: 0xa7bf, Stride: 1},
-		{Lo: 0xa7c2, Hi: 0xa7ca, Stride: 1},
-		{Lo: 0xa7f5, Hi: 0xa801, Stride: 1},
+		{Lo: 0xa701, Hi: 0xa7ca, Stride: 1},
+		{Lo: 0xa7d0, Hi: 0xa7d1, Stride: 1},
+		{Lo: 0xa7d3, Hi: 0xa7d5, Stride: 2},
+		{Lo: 0xa7d6, Hi: 0xa7d9, Stride: 1},
+		{Lo: 0xa7f2, Hi: 0xa801, Stride: 1},
 		{Lo: 0xa803, Hi: 0xa805, Stride: 1},
 		{Lo: 0xa803, Hi: 0xa805, Stride: 1},
 		{Lo: 0xa807, Hi: 0xa80a, Stride: 1},
 		{Lo: 0xa807, Hi: 0xa80a, Stride: 1},
 		{Lo: 0xa80c, Hi: 0xa822, Stride: 1},
 		{Lo: 0xa80c, Hi: 0xa822, Stride: 1},
@@ -542,13 +547,14 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0xfb00, Hi: 0xfb06, Stride: 1},
 		{Lo: 0xfb00, Hi: 0xfb06, Stride: 1},
 		{Lo: 0xfb13, Hi: 0xfb17, Stride: 1},
 		{Lo: 0xfb13, Hi: 0xfb17, Stride: 1},
 		{Lo: 0xfb29, Hi: 0xfb50, Stride: 39},
 		{Lo: 0xfb29, Hi: 0xfb50, Stride: 39},
-		{Lo: 0xfb51, Hi: 0xfbc1, Stride: 1},
+		{Lo: 0xfb51, Hi: 0xfbc2, Stride: 1},
 		{Lo: 0xfbd3, Hi: 0xfd3d, Stride: 1},
 		{Lo: 0xfbd3, Hi: 0xfd3d, Stride: 1},
-		{Lo: 0xfd50, Hi: 0xfd8f, Stride: 1},
+		{Lo: 0xfd40, Hi: 0xfd8f, Stride: 1},
 		{Lo: 0xfd92, Hi: 0xfdc7, Stride: 1},
 		{Lo: 0xfd92, Hi: 0xfdc7, Stride: 1},
-		{Lo: 0xfdf0, Hi: 0xfdfb, Stride: 1},
-		{Lo: 0xfdfd, Hi: 0xfe70, Stride: 115},
-		{Lo: 0xfe71, Hi: 0xfe74, Stride: 1},
+		{Lo: 0xfdcf, Hi: 0xfdf0, Stride: 33},
+		{Lo: 0xfdf1, Hi: 0xfdfb, Stride: 1},
+		{Lo: 0xfdfd, Hi: 0xfdff, Stride: 1},
+		{Lo: 0xfe70, Hi: 0xfe74, Stride: 1},
 		{Lo: 0xfe76, Hi: 0xfefc, Stride: 1},
 		{Lo: 0xfe76, Hi: 0xfefc, Stride: 1},
 		{Lo: 0xffe8, Hi: 0xffee, Stride: 1},
 		{Lo: 0xffe8, Hi: 0xffee, Stride: 1},
 	},
 	},
@@ -580,10 +586,20 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x104d8, Hi: 0x104fb, Stride: 1},
 		{Lo: 0x104d8, Hi: 0x104fb, Stride: 1},
 		{Lo: 0x10500, Hi: 0x10527, Stride: 1},
 		{Lo: 0x10500, Hi: 0x10527, Stride: 1},
 		{Lo: 0x10530, Hi: 0x10563, Stride: 1},
 		{Lo: 0x10530, Hi: 0x10563, Stride: 1},
-		{Lo: 0x1056f, Hi: 0x10600, Stride: 145},
-		{Lo: 0x10601, Hi: 0x10736, Stride: 1},
+		{Lo: 0x1056f, Hi: 0x1057a, Stride: 1},
+		{Lo: 0x1057c, Hi: 0x1058a, Stride: 1},
+		{Lo: 0x1058c, Hi: 0x10592, Stride: 1},
+		{Lo: 0x10594, Hi: 0x10595, Stride: 1},
+		{Lo: 0x10597, Hi: 0x105a1, Stride: 1},
+		{Lo: 0x105a3, Hi: 0x105b1, Stride: 1},
+		{Lo: 0x105b3, Hi: 0x105b9, Stride: 1},
+		{Lo: 0x105bb, Hi: 0x105bc, Stride: 1},
+		{Lo: 0x10600, Hi: 0x10736, Stride: 1},
 		{Lo: 0x10740, Hi: 0x10755, Stride: 1},
 		{Lo: 0x10740, Hi: 0x10755, Stride: 1},
 		{Lo: 0x10760, Hi: 0x10767, Stride: 1},
 		{Lo: 0x10760, Hi: 0x10767, Stride: 1},
+		{Lo: 0x10780, Hi: 0x10785, Stride: 1},
+		{Lo: 0x10787, Hi: 0x107b0, Stride: 1},
+		{Lo: 0x107b2, Hi: 0x107ba, Stride: 1},
 		{Lo: 0x10800, Hi: 0x10805, Stride: 1},
 		{Lo: 0x10800, Hi: 0x10805, Stride: 1},
 		{Lo: 0x10808, Hi: 0x1080a, Stride: 2},
 		{Lo: 0x10808, Hi: 0x1080a, Stride: 2},
 		{Lo: 0x1080b, Hi: 0x10835, Stride: 1},
 		{Lo: 0x1080b, Hi: 0x10835, Stride: 1},
@@ -624,12 +640,16 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x10f00, Hi: 0x10f27, Stride: 1},
 		{Lo: 0x10f00, Hi: 0x10f27, Stride: 1},
 		{Lo: 0x10f30, Hi: 0x10f45, Stride: 1},
 		{Lo: 0x10f30, Hi: 0x10f45, Stride: 1},
 		{Lo: 0x10f51, Hi: 0x10f59, Stride: 1},
 		{Lo: 0x10f51, Hi: 0x10f59, Stride: 1},
+		{Lo: 0x10f70, Hi: 0x10f81, Stride: 1},
+		{Lo: 0x10f86, Hi: 0x10f89, Stride: 1},
 		{Lo: 0x10fb0, Hi: 0x10fcb, Stride: 1},
 		{Lo: 0x10fb0, Hi: 0x10fcb, Stride: 1},
 		{Lo: 0x10fe0, Hi: 0x10ff6, Stride: 1},
 		{Lo: 0x10fe0, Hi: 0x10ff6, Stride: 1},
 		{Lo: 0x11003, Hi: 0x11037, Stride: 1},
 		{Lo: 0x11003, Hi: 0x11037, Stride: 1},
 		{Lo: 0x11049, Hi: 0x1104d, Stride: 1},
 		{Lo: 0x11049, Hi: 0x1104d, Stride: 1},
 		{Lo: 0x11052, Hi: 0x11065, Stride: 1},
 		{Lo: 0x11052, Hi: 0x11065, Stride: 1},
-		{Lo: 0x11083, Hi: 0x110af, Stride: 1},
+		{Lo: 0x11071, Hi: 0x11072, Stride: 1},
+		{Lo: 0x11075, Hi: 0x11083, Stride: 14},
+		{Lo: 0x11084, Hi: 0x110af, Stride: 1},
 		{Lo: 0x110bb, Hi: 0x110bd, Stride: 1},
 		{Lo: 0x110bb, Hi: 0x110bd, Stride: 1},
 		{Lo: 0x110cd, Hi: 0x110d0, Stride: 3},
 		{Lo: 0x110cd, Hi: 0x110d0, Stride: 3},
 		{Lo: 0x110d1, Hi: 0x110e8, Stride: 1},
 		{Lo: 0x110d1, Hi: 0x110e8, Stride: 1},
@@ -645,6 +665,7 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x11200, Hi: 0x11211, Stride: 1},
 		{Lo: 0x11200, Hi: 0x11211, Stride: 1},
 		{Lo: 0x11213, Hi: 0x1122b, Stride: 1},
 		{Lo: 0x11213, Hi: 0x1122b, Stride: 1},
 		{Lo: 0x1123a, Hi: 0x1123d, Stride: 3},
 		{Lo: 0x1123a, Hi: 0x1123d, Stride: 3},
+		{Lo: 0x1123f, Hi: 0x11240, Stride: 1},
 		{Lo: 0x11280, Hi: 0x11286, Stride: 1},
 		{Lo: 0x11280, Hi: 0x11286, Stride: 1},
 		{Lo: 0x11288, Hi: 0x1128a, Stride: 2},
 		{Lo: 0x11288, Hi: 0x1128a, Stride: 2},
 		{Lo: 0x1128b, Hi: 0x1128d, Stride: 1},
 		{Lo: 0x1128b, Hi: 0x1128d, Stride: 1},
@@ -671,8 +692,8 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x11600, Hi: 0x1162f, Stride: 1},
 		{Lo: 0x11600, Hi: 0x1162f, Stride: 1},
 		{Lo: 0x11643, Hi: 0x11644, Stride: 1},
 		{Lo: 0x11643, Hi: 0x11644, Stride: 1},
 		{Lo: 0x11680, Hi: 0x116aa, Stride: 1},
 		{Lo: 0x11680, Hi: 0x116aa, Stride: 1},
-		{Lo: 0x116b8, Hi: 0x11800, Stride: 328},
-		{Lo: 0x11801, Hi: 0x1182b, Stride: 1},
+		{Lo: 0x116b8, Hi: 0x116b9, Stride: 1},
+		{Lo: 0x11800, Hi: 0x1182b, Stride: 1},
 		{Lo: 0x1183b, Hi: 0x118a0, Stride: 101},
 		{Lo: 0x1183b, Hi: 0x118a0, Stride: 101},
 		{Lo: 0x118a1, Hi: 0x118df, Stride: 1},
 		{Lo: 0x118a1, Hi: 0x118df, Stride: 1},
 		{Lo: 0x118ea, Hi: 0x118f2, Stride: 1},
 		{Lo: 0x118ea, Hi: 0x118f2, Stride: 1},
@@ -690,8 +711,8 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x11a3a, Hi: 0x11a46, Stride: 6},
 		{Lo: 0x11a3a, Hi: 0x11a46, Stride: 6},
 		{Lo: 0x11a50, Hi: 0x11a5c, Stride: 12},
 		{Lo: 0x11a50, Hi: 0x11a5c, Stride: 12},
 		{Lo: 0x11a5d, Hi: 0x11a89, Stride: 1},
 		{Lo: 0x11a5d, Hi: 0x11a89, Stride: 1},
-		{Lo: 0x11a9d, Hi: 0x11ac0, Stride: 35},
-		{Lo: 0x11ac1, Hi: 0x11af8, Stride: 1},
+		{Lo: 0x11a9d, Hi: 0x11ab0, Stride: 19},
+		{Lo: 0x11ab1, Hi: 0x11af8, Stride: 1},
 		{Lo: 0x11c00, Hi: 0x11c08, Stride: 1},
 		{Lo: 0x11c00, Hi: 0x11c08, Stride: 1},
 		{Lo: 0x11c0a, Hi: 0x11c2e, Stride: 1},
 		{Lo: 0x11c0a, Hi: 0x11c2e, Stride: 1},
 		{Lo: 0x11c40, Hi: 0x11c5a, Stride: 26},
 		{Lo: 0x11c40, Hi: 0x11c5a, Stride: 26},
@@ -707,21 +728,27 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x11d98, Hi: 0x11ee0, Stride: 328},
 		{Lo: 0x11d98, Hi: 0x11ee0, Stride: 328},
 		{Lo: 0x11ee1, Hi: 0x11ef2, Stride: 1},
 		{Lo: 0x11ee1, Hi: 0x11ef2, Stride: 1},
 		{Lo: 0x11ef7, Hi: 0x11ef8, Stride: 1},
 		{Lo: 0x11ef7, Hi: 0x11ef8, Stride: 1},
+		{Lo: 0x11f02, Hi: 0x11f04, Stride: 2},
+		{Lo: 0x11f05, Hi: 0x11f10, Stride: 1},
+		{Lo: 0x11f12, Hi: 0x11f33, Stride: 1},
 		{Lo: 0x11fb0, Hi: 0x11fc0, Stride: 16},
 		{Lo: 0x11fb0, Hi: 0x11fc0, Stride: 16},
 		{Lo: 0x11fc1, Hi: 0x11fdc, Stride: 1},
 		{Lo: 0x11fc1, Hi: 0x11fdc, Stride: 1},
 		{Lo: 0x11fe1, Hi: 0x11ff1, Stride: 1},
 		{Lo: 0x11fe1, Hi: 0x11ff1, Stride: 1},
 		{Lo: 0x12000, Hi: 0x12399, Stride: 1},
 		{Lo: 0x12000, Hi: 0x12399, Stride: 1},
 		{Lo: 0x12400, Hi: 0x1246e, Stride: 1},
 		{Lo: 0x12400, Hi: 0x1246e, Stride: 1},
 		{Lo: 0x12480, Hi: 0x12543, Stride: 1},
 		{Lo: 0x12480, Hi: 0x12543, Stride: 1},
+		{Lo: 0x12f90, Hi: 0x12ff2, Stride: 1},
 		{Lo: 0x13000, Hi: 0x13257, Stride: 1},
 		{Lo: 0x13000, Hi: 0x13257, Stride: 1},
 		{Lo: 0x1325e, Hi: 0x13281, Stride: 1},
 		{Lo: 0x1325e, Hi: 0x13281, Stride: 1},
 		{Lo: 0x13283, Hi: 0x13285, Stride: 1},
 		{Lo: 0x13283, Hi: 0x13285, Stride: 1},
 		{Lo: 0x1328a, Hi: 0x13378, Stride: 1},
 		{Lo: 0x1328a, Hi: 0x13378, Stride: 1},
-		{Lo: 0x1337c, Hi: 0x1342e, Stride: 1},
+		{Lo: 0x1337c, Hi: 0x1342f, Stride: 1},
+		{Lo: 0x13441, Hi: 0x13446, Stride: 1},
 		{Lo: 0x14400, Hi: 0x145cd, Stride: 1},
 		{Lo: 0x14400, Hi: 0x145cd, Stride: 1},
 		{Lo: 0x145d0, Hi: 0x14646, Stride: 1},
 		{Lo: 0x145d0, Hi: 0x14646, Stride: 1},
 		{Lo: 0x16800, Hi: 0x16a38, Stride: 1},
 		{Lo: 0x16800, Hi: 0x16a38, Stride: 1},
 		{Lo: 0x16a40, Hi: 0x16a5e, Stride: 1},
 		{Lo: 0x16a40, Hi: 0x16a5e, Stride: 1},
+		{Lo: 0x16a70, Hi: 0x16abe, Stride: 1},
 		{Lo: 0x16ad0, Hi: 0x16aed, Stride: 1},
 		{Lo: 0x16ad0, Hi: 0x16aed, Stride: 1},
 		{Lo: 0x16b00, Hi: 0x16b2f, Stride: 1},
 		{Lo: 0x16b00, Hi: 0x16b2f, Stride: 1},
 		{Lo: 0x16b3a, Hi: 0x16b43, Stride: 1},
 		{Lo: 0x16b3a, Hi: 0x16b43, Stride: 1},
@@ -735,21 +762,26 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x16f50, Hi: 0x16f93, Stride: 67},
 		{Lo: 0x16f50, Hi: 0x16f93, Stride: 67},
 		{Lo: 0x16f94, Hi: 0x16f9f, Stride: 1},
 		{Lo: 0x16f94, Hi: 0x16f9f, Stride: 1},
 		{Lo: 0x18b00, Hi: 0x18cd5, Stride: 1},
 		{Lo: 0x18b00, Hi: 0x18cd5, Stride: 1},
+		{Lo: 0x1aff0, Hi: 0x1aff3, Stride: 1},
+		{Lo: 0x1aff5, Hi: 0x1affb, Stride: 1},
+		{Lo: 0x1affd, Hi: 0x1affe, Stride: 1},
 		{Lo: 0x1bc00, Hi: 0x1bc6a, Stride: 1},
 		{Lo: 0x1bc00, Hi: 0x1bc6a, Stride: 1},
 		{Lo: 0x1bc70, Hi: 0x1bc7c, Stride: 1},
 		{Lo: 0x1bc70, Hi: 0x1bc7c, Stride: 1},
 		{Lo: 0x1bc80, Hi: 0x1bc88, Stride: 1},
 		{Lo: 0x1bc80, Hi: 0x1bc88, Stride: 1},
 		{Lo: 0x1bc90, Hi: 0x1bc99, Stride: 1},
 		{Lo: 0x1bc90, Hi: 0x1bc99, Stride: 1},
-		{Lo: 0x1bc9c, Hi: 0x1d000, Stride: 4964},
-		{Lo: 0x1d001, Hi: 0x1d0f5, Stride: 1},
+		{Lo: 0x1bc9c, Hi: 0x1cf50, Stride: 4788},
+		{Lo: 0x1cf51, Hi: 0x1cfc3, Stride: 1},
+		{Lo: 0x1d000, Hi: 0x1d0f5, Stride: 1},
 		{Lo: 0x1d100, Hi: 0x1d126, Stride: 1},
 		{Lo: 0x1d100, Hi: 0x1d126, Stride: 1},
 		{Lo: 0x1d129, Hi: 0x1d164, Stride: 1},
 		{Lo: 0x1d129, Hi: 0x1d164, Stride: 1},
 		{Lo: 0x1d16a, Hi: 0x1d16c, Stride: 1},
 		{Lo: 0x1d16a, Hi: 0x1d16c, Stride: 1},
 		{Lo: 0x1d183, Hi: 0x1d184, Stride: 1},
 		{Lo: 0x1d183, Hi: 0x1d184, Stride: 1},
 		{Lo: 0x1d18c, Hi: 0x1d1a9, Stride: 1},
 		{Lo: 0x1d18c, Hi: 0x1d1a9, Stride: 1},
-		{Lo: 0x1d1ae, Hi: 0x1d1e8, Stride: 1},
+		{Lo: 0x1d1ae, Hi: 0x1d1ea, Stride: 1},
 		{Lo: 0x1d200, Hi: 0x1d241, Stride: 1},
 		{Lo: 0x1d200, Hi: 0x1d241, Stride: 1},
-		{Lo: 0x1d245, Hi: 0x1d2e0, Stride: 155},
-		{Lo: 0x1d2e1, Hi: 0x1d2f3, Stride: 1},
+		{Lo: 0x1d245, Hi: 0x1d2c0, Stride: 123},
+		{Lo: 0x1d2c1, Hi: 0x1d2d3, Stride: 1},
+		{Lo: 0x1d2e0, Hi: 0x1d2f3, Stride: 1},
 		{Lo: 0x1d300, Hi: 0x1d356, Stride: 1},
 		{Lo: 0x1d300, Hi: 0x1d356, Stride: 1},
 		{Lo: 0x1d360, Hi: 0x1d378, Stride: 1},
 		{Lo: 0x1d360, Hi: 0x1d378, Stride: 1},
 		{Lo: 0x1d400, Hi: 0x1d454, Stride: 1},
 		{Lo: 0x1d400, Hi: 0x1d454, Stride: 1},
@@ -777,11 +809,20 @@ var BreakAL = &unicode.RangeTable{
 		{Lo: 0x1da6d, Hi: 0x1da74, Stride: 1},
 		{Lo: 0x1da6d, Hi: 0x1da74, Stride: 1},
 		{Lo: 0x1da76, Hi: 0x1da83, Stride: 1},
 		{Lo: 0x1da76, Hi: 0x1da83, Stride: 1},
 		{Lo: 0x1da85, Hi: 0x1da86, Stride: 1},
 		{Lo: 0x1da85, Hi: 0x1da86, Stride: 1},
-		{Lo: 0x1da8b, Hi: 0x1e100, Stride: 1653},
-		{Lo: 0x1e101, Hi: 0x1e12c, Stride: 1},
+		{Lo: 0x1da8b, Hi: 0x1df00, Stride: 1141},
+		{Lo: 0x1df01, Hi: 0x1df1e, Stride: 1},
+		{Lo: 0x1df25, Hi: 0x1df2a, Stride: 1},
+		{Lo: 0x1e030, Hi: 0x1e06d, Stride: 1},
+		{Lo: 0x1e100, Hi: 0x1e12c, Stride: 1},
 		{Lo: 0x1e137, Hi: 0x1e13d, Stride: 1},
 		{Lo: 0x1e137, Hi: 0x1e13d, Stride: 1},
 		{Lo: 0x1e14e, Hi: 0x1e14f, Stride: 1},
 		{Lo: 0x1e14e, Hi: 0x1e14f, Stride: 1},
+		{Lo: 0x1e290, Hi: 0x1e2ad, Stride: 1},
 		{Lo: 0x1e2c0, Hi: 0x1e2eb, Stride: 1},
 		{Lo: 0x1e2c0, Hi: 0x1e2eb, Stride: 1},
+		{Lo: 0x1e4d0, Hi: 0x1e4eb, Stride: 1},
+		{Lo: 0x1e7e0, Hi: 0x1e7e6, Stride: 1},
+		{Lo: 0x1e7e8, Hi: 0x1e7eb, Stride: 1},
+		{Lo: 0x1e7ed, Hi: 0x1e7ee, Stride: 1},
+		{Lo: 0x1e7f0, Hi: 0x1e7fe, Stride: 1},
 		{Lo: 0x1e800, Hi: 0x1e8c4, Stride: 1},
 		{Lo: 0x1e800, Hi: 0x1e8c4, Stride: 1},
 		{Lo: 0x1e8c7, Hi: 0x1e8cf, Stride: 1},
 		{Lo: 0x1e8c7, Hi: 0x1e8cf, Stride: 1},
 		{Lo: 0x1e900, Hi: 0x1e943, Stride: 1},
 		{Lo: 0x1e900, Hi: 0x1e943, Stride: 1},
@@ -874,7 +915,8 @@ var BreakPR = &unicode.RangeTable{
 		{Lo: 0x20a8, Hi: 0x20b5, Stride: 1},
 		{Lo: 0x20a8, Hi: 0x20b5, Stride: 1},
 		{Lo: 0x20b7, Hi: 0x20ba, Stride: 1},
 		{Lo: 0x20b7, Hi: 0x20ba, Stride: 1},
 		{Lo: 0x20bc, Hi: 0x20bd, Stride: 1},
 		{Lo: 0x20bc, Hi: 0x20bd, Stride: 1},
-		{Lo: 0x20bf, Hi: 0x20cf, Stride: 1},
+		{Lo: 0x20bf, Hi: 0x20c1, Stride: 2},
+		{Lo: 0x20c2, Hi: 0x20cf, Stride: 1},
 		{Lo: 0x2116, Hi: 0x2212, Stride: 252},
 		{Lo: 0x2116, Hi: 0x2212, Stride: 252},
 		{Lo: 0x2213, Hi: 0xfe69, Stride: 56406},
 		{Lo: 0x2213, Hi: 0xfe69, Stride: 56406},
 		{Lo: 0xff04, Hi: 0xffe1, Stride: 221},
 		{Lo: 0xff04, Hi: 0xffe1, Stride: 221},
@@ -896,8 +938,9 @@ var BreakPO = &unicode.RangeTable{
 		{Lo: 0x09f3, Hi: 0x09f9, Stride: 6},
 		{Lo: 0x09f3, Hi: 0x09f9, Stride: 6},
 		{Lo: 0x0d79, Hi: 0x2030, Stride: 4791},
 		{Lo: 0x0d79, Hi: 0x2030, Stride: 4791},
 		{Lo: 0x2031, Hi: 0x2037, Stride: 1},
 		{Lo: 0x2031, Hi: 0x2037, Stride: 1},
-		{Lo: 0x20a7, Hi: 0x20b6, Stride: 15},
-		{Lo: 0x20bb, Hi: 0x20be, Stride: 3},
+		{Lo: 0x2057, Hi: 0x20a7, Stride: 80},
+		{Lo: 0x20b6, Hi: 0x20bb, Stride: 5},
+		{Lo: 0x20be, Hi: 0x20c0, Stride: 2},
 		{Lo: 0x2103, Hi: 0x2109, Stride: 6},
 		{Lo: 0x2103, Hi: 0x2109, Stride: 6},
 		{Lo: 0xa838, Hi: 0xfdfc, Stride: 21956},
 		{Lo: 0xa838, Hi: 0xfdfc, Stride: 21956},
 		{Lo: 0xfe6a, Hi: 0xff05, Stride: 155},
 		{Lo: 0xfe6a, Hi: 0xff05, Stride: 155},
@@ -928,8 +971,9 @@ var BreakOP = &unicode.RangeTable{
 		{Lo: 0x29d8, Hi: 0x29da, Stride: 2},
 		{Lo: 0x29d8, Hi: 0x29da, Stride: 2},
 		{Lo: 0x29fc, Hi: 0x2e18, Stride: 1052},
 		{Lo: 0x29fc, Hi: 0x2e18, Stride: 1052},
 		{Lo: 0x2e22, Hi: 0x2e28, Stride: 2},
 		{Lo: 0x2e22, Hi: 0x2e28, Stride: 2},
-		{Lo: 0x2e42, Hi: 0x3008, Stride: 454},
-		{Lo: 0x300a, Hi: 0x3010, Stride: 2},
+		{Lo: 0x2e42, Hi: 0x2e55, Stride: 19},
+		{Lo: 0x2e57, Hi: 0x2e5b, Stride: 2},
+		{Lo: 0x3008, Hi: 0x3010, Stride: 2},
 		{Lo: 0x3014, Hi: 0x301a, Stride: 2},
 		{Lo: 0x3014, Hi: 0x301a, Stride: 2},
 		{Lo: 0x301d, Hi: 0xfd3f, Stride: 52514},
 		{Lo: 0x301d, Hi: 0xfd3f, Stride: 52514},
 		{Lo: 0xfe17, Hi: 0xfe35, Stride: 30},
 		{Lo: 0xfe17, Hi: 0xfe35, Stride: 30},
@@ -944,6 +988,7 @@ var BreakOP = &unicode.RangeTable{
 		{Lo: 0x13258, Hi: 0x1325a, Stride: 1},
 		{Lo: 0x13258, Hi: 0x1325a, Stride: 1},
 		{Lo: 0x13286, Hi: 0x13288, Stride: 2},
 		{Lo: 0x13286, Hi: 0x13288, Stride: 2},
 		{Lo: 0x13379, Hi: 0x13437, Stride: 190},
 		{Lo: 0x13379, Hi: 0x13437, Stride: 190},
+		{Lo: 0x1343c, Hi: 0x1343e, Stride: 2},
 		{Lo: 0x145ce, Hi: 0x1e95e, Stride: 41872},
 		{Lo: 0x145ce, Hi: 0x1e95e, Stride: 41872},
 		{Lo: 0x1e95f, Hi: 0x1e95f, Stride: 1},
 		{Lo: 0x1e95f, Hi: 0x1e95f, Stride: 1},
 	},
 	},
@@ -965,6 +1010,7 @@ var BreakCL = &unicode.RangeTable{
 		{Lo: 0x29d9, Hi: 0x29db, Stride: 2},
 		{Lo: 0x29d9, Hi: 0x29db, Stride: 2},
 		{Lo: 0x29fd, Hi: 0x2e23, Stride: 1062},
 		{Lo: 0x29fd, Hi: 0x2e23, Stride: 1062},
 		{Lo: 0x2e25, Hi: 0x2e29, Stride: 2},
 		{Lo: 0x2e25, Hi: 0x2e29, Stride: 2},
+		{Lo: 0x2e56, Hi: 0x2e5c, Stride: 2},
 		{Lo: 0x3001, Hi: 0x3002, Stride: 1},
 		{Lo: 0x3001, Hi: 0x3002, Stride: 1},
 		{Lo: 0x3009, Hi: 0x3011, Stride: 2},
 		{Lo: 0x3009, Hi: 0x3011, Stride: 2},
 		{Lo: 0x3015, Hi: 0x301b, Stride: 2},
 		{Lo: 0x3015, Hi: 0x301b, Stride: 2},
@@ -986,6 +1032,7 @@ var BreakCL = &unicode.RangeTable{
 		{Lo: 0x13282, Hi: 0x13287, Stride: 5},
 		{Lo: 0x13282, Hi: 0x13287, Stride: 5},
 		{Lo: 0x13289, Hi: 0x1337a, Stride: 241},
 		{Lo: 0x13289, Hi: 0x1337a, Stride: 241},
 		{Lo: 0x1337b, Hi: 0x13438, Stride: 189},
 		{Lo: 0x1337b, Hi: 0x13438, Stride: 189},
+		{Lo: 0x1343d, Hi: 0x1343f, Stride: 2},
 		{Lo: 0x145cf, Hi: 0x145cf, Stride: 1},
 		{Lo: 0x145cf, Hi: 0x145cf, Stride: 1},
 	},
 	},
 }
 }
@@ -1041,11 +1088,13 @@ var BreakGL = &unicode.RangeTable{
 		{Lo: 0x0f08, Hi: 0x0f0c, Stride: 4},
 		{Lo: 0x0f08, Hi: 0x0f0c, Stride: 4},
 		{Lo: 0x0f12, Hi: 0x0fd9, Stride: 199},
 		{Lo: 0x0f12, Hi: 0x0fd9, Stride: 199},
 		{Lo: 0x0fda, Hi: 0x180e, Stride: 2100},
 		{Lo: 0x0fda, Hi: 0x180e, Stride: 2100},
+		{Lo: 0x1dcd, Hi: 0x1dfc, Stride: 47},
 		{Lo: 0x2007, Hi: 0x2011, Stride: 10},
 		{Lo: 0x2007, Hi: 0x2011, Stride: 10},
 		{Lo: 0x202f, Hi: 0x202f, Stride: 1},
 		{Lo: 0x202f, Hi: 0x202f, Stride: 1},
 	},
 	},
 	R32: []unicode.Range32{
 	R32: []unicode.Range32{
 		{Lo: 0x13430, Hi: 0x13436, Stride: 1},
 		{Lo: 0x13430, Hi: 0x13436, Stride: 1},
+		{Lo: 0x13439, Hi: 0x1343b, Stride: 1},
 		{Lo: 0x16fe4, Hi: 0x16fe4, Stride: 1},
 		{Lo: 0x16fe4, Hi: 0x16fe4, Stride: 1},
 	},
 	},
 }
 }
@@ -1077,7 +1126,7 @@ var BreakEX = &unicode.RangeTable{
 	R16: []unicode.Range16{
 	R16: []unicode.Range16{
 		{Lo: 0x0021, Hi: 0x003f, Stride: 30},
 		{Lo: 0x0021, Hi: 0x003f, Stride: 30},
 		{Lo: 0x05c6, Hi: 0x061b, Stride: 85},
 		{Lo: 0x05c6, Hi: 0x061b, Stride: 85},
-		{Lo: 0x061e, Hi: 0x061f, Stride: 1},
+		{Lo: 0x061d, Hi: 0x061f, Stride: 1},
 		{Lo: 0x06d4, Hi: 0x07f9, Stride: 293},
 		{Lo: 0x06d4, Hi: 0x07f9, Stride: 293},
 		{Lo: 0x0f0d, Hi: 0x0f11, Stride: 1},
 		{Lo: 0x0f0d, Hi: 0x0f11, Stride: 1},
 		{Lo: 0x0f14, Hi: 0x1802, Stride: 2286},
 		{Lo: 0x0f14, Hi: 0x1802, Stride: 2286},
@@ -1086,6 +1135,7 @@ var BreakEX = &unicode.RangeTable{
 		{Lo: 0x1945, Hi: 0x2762, Stride: 3613},
 		{Lo: 0x1945, Hi: 0x2762, Stride: 3613},
 		{Lo: 0x2763, Hi: 0x2cf9, Stride: 1430},
 		{Lo: 0x2763, Hi: 0x2cf9, Stride: 1430},
 		{Lo: 0x2cfe, Hi: 0x2e2e, Stride: 304},
 		{Lo: 0x2cfe, Hi: 0x2e2e, Stride: 304},
+		{Lo: 0x2e53, Hi: 0x2e54, Stride: 1},
 		{Lo: 0xa60e, Hi: 0xa876, Stride: 616},
 		{Lo: 0xa60e, Hi: 0xa876, Stride: 616},
 		{Lo: 0xa877, Hi: 0xfe15, Stride: 21918},
 		{Lo: 0xa877, Hi: 0xfe15, Stride: 21918},
 		{Lo: 0xfe16, Hi: 0xfe56, Stride: 64},
 		{Lo: 0xfe16, Hi: 0xfe56, Stride: 64},
@@ -1211,10 +1261,11 @@ var BreakID = &unicode.RangeTable{
 		{Lo: 0xffe2, Hi: 0xffe4, Stride: 1},
 		{Lo: 0xffe2, Hi: 0xffe4, Stride: 1},
 	},
 	},
 	R32: []unicode.Range32{
 	R32: []unicode.Range32{
+		{Lo: 0x11f45, Hi: 0x11f4f, Stride: 1},
 		{Lo: 0x17000, Hi: 0x187f7, Stride: 1},
 		{Lo: 0x17000, Hi: 0x187f7, Stride: 1},
 		{Lo: 0x18800, Hi: 0x18aff, Stride: 1},
 		{Lo: 0x18800, Hi: 0x18aff, Stride: 1},
 		{Lo: 0x18d00, Hi: 0x18d08, Stride: 1},
 		{Lo: 0x18d00, Hi: 0x18d08, Stride: 1},
-		{Lo: 0x1b000, Hi: 0x1b11e, Stride: 1},
+		{Lo: 0x1b000, Hi: 0x1b122, Stride: 1},
 		{Lo: 0x1b170, Hi: 0x1b2fb, Stride: 1},
 		{Lo: 0x1b170, Hi: 0x1b2fb, Stride: 1},
 		{Lo: 0x1f000, Hi: 0x1f0ff, Stride: 1},
 		{Lo: 0x1f000, Hi: 0x1f0ff, Stride: 1},
 		{Lo: 0x1f10d, Hi: 0x1f10f, Stride: 1},
 		{Lo: 0x1f10d, Hi: 0x1f10f, Stride: 1},
@@ -1275,7 +1326,9 @@ var BreakID = &unicode.RangeTable{
 		{Lo: 0x1f9bc, Hi: 0x1f9cc, Stride: 1},
 		{Lo: 0x1f9bc, Hi: 0x1f9cc, Stride: 1},
 		{Lo: 0x1f9d0, Hi: 0x1f9de, Stride: 14},
 		{Lo: 0x1f9d0, Hi: 0x1f9de, Stride: 14},
 		{Lo: 0x1f9df, Hi: 0x1f9ff, Stride: 1},
 		{Lo: 0x1f9df, Hi: 0x1f9ff, Stride: 1},
-		{Lo: 0x1fa54, Hi: 0x1faff, Stride: 1},
+		{Lo: 0x1fa54, Hi: 0x1fac2, Stride: 1},
+		{Lo: 0x1fac6, Hi: 0x1faef, Stride: 1},
+		{Lo: 0x1faf9, Hi: 0x1faff, Stride: 1},
 		{Lo: 0x1fc00, Hi: 0x1fffd, Stride: 1},
 		{Lo: 0x1fc00, Hi: 0x1fffd, Stride: 1},
 		{Lo: 0x20000, Hi: 0x2fffd, Stride: 1},
 		{Lo: 0x20000, Hi: 0x2fffd, Stride: 1},
 		{Lo: 0x30000, Hi: 0x3fffd, Stride: 1},
 		{Lo: 0x30000, Hi: 0x3fffd, Stride: 1},
@@ -1314,6 +1367,7 @@ var BreakBA = &unicode.RangeTable{
 		{Lo: 0x1804, Hi: 0x1805, Stride: 1},
 		{Lo: 0x1804, Hi: 0x1805, Stride: 1},
 		{Lo: 0x1b5a, Hi: 0x1b5b, Stride: 1},
 		{Lo: 0x1b5a, Hi: 0x1b5b, Stride: 1},
 		{Lo: 0x1b5d, Hi: 0x1b60, Stride: 1},
 		{Lo: 0x1b5d, Hi: 0x1b60, Stride: 1},
+		{Lo: 0x1b7d, Hi: 0x1b7e, Stride: 1},
 		{Lo: 0x1c3b, Hi: 0x1c3f, Stride: 1},
 		{Lo: 0x1c3b, Hi: 0x1c3f, Stride: 1},
 		{Lo: 0x1c7e, Hi: 0x1c7f, Stride: 1},
 		{Lo: 0x1c7e, Hi: 0x1c7f, Stride: 1},
 		{Lo: 0x2000, Hi: 0x2006, Stride: 1},
 		{Lo: 0x2000, Hi: 0x2006, Stride: 1},
@@ -1334,10 +1388,11 @@ var BreakBA = &unicode.RangeTable{
 		{Lo: 0x2e40, Hi: 0x2e41, Stride: 1},
 		{Lo: 0x2e40, Hi: 0x2e41, Stride: 1},
 		{Lo: 0x2e43, Hi: 0x2e4a, Stride: 1},
 		{Lo: 0x2e43, Hi: 0x2e4a, Stride: 1},
 		{Lo: 0x2e4c, Hi: 0x2e4e, Stride: 2},
 		{Lo: 0x2e4c, Hi: 0x2e4e, Stride: 2},
-		{Lo: 0x2e4f, Hi: 0x3000, Stride: 433},
-		{Lo: 0xa4fe, Hi: 0xa4ff, Stride: 1},
-		{Lo: 0xa60d, Hi: 0xa60f, Stride: 2},
-		{Lo: 0xa6f3, Hi: 0xa6f7, Stride: 1},
+		{Lo: 0x2e4f, Hi: 0x2e5d, Stride: 14},
+		{Lo: 0x3000, Hi: 0xa4fe, Stride: 29950},
+		{Lo: 0xa4ff, Hi: 0xa60d, Stride: 270},
+		{Lo: 0xa60f, Hi: 0xa6f3, Stride: 228},
+		{Lo: 0xa6f4, Hi: 0xa6f7, Stride: 1},
 		{Lo: 0xa8ce, Hi: 0xa8cf, Stride: 1},
 		{Lo: 0xa8ce, Hi: 0xa8cf, Stride: 1},
 		{Lo: 0xa92e, Hi: 0xa92f, Stride: 1},
 		{Lo: 0xa92e, Hi: 0xa92f, Stride: 1},
 		{Lo: 0xa9c7, Hi: 0xa9c9, Stride: 1},
 		{Lo: 0xa9c7, Hi: 0xa9c9, Stride: 1},
@@ -1373,6 +1428,7 @@ var BreakBA = &unicode.RangeTable{
 		{Lo: 0x11a9a, Hi: 0x11a9c, Stride: 1},
 		{Lo: 0x11a9a, Hi: 0x11a9c, Stride: 1},
 		{Lo: 0x11aa1, Hi: 0x11aa2, Stride: 1},
 		{Lo: 0x11aa1, Hi: 0x11aa2, Stride: 1},
 		{Lo: 0x11c41, Hi: 0x11c45, Stride: 1},
 		{Lo: 0x11c41, Hi: 0x11c45, Stride: 1},
+		{Lo: 0x11f43, Hi: 0x11f44, Stride: 1},
 		{Lo: 0x11fff, Hi: 0x12470, Stride: 1137},
 		{Lo: 0x11fff, Hi: 0x12470, Stride: 1137},
 		{Lo: 0x12471, Hi: 0x12474, Stride: 1},
 		{Lo: 0x12471, Hi: 0x12474, Stride: 1},
 		{Lo: 0x16a6e, Hi: 0x16a6f, Stride: 1},
 		{Lo: 0x16a6e, Hi: 0x16a6f, Stride: 1},
@@ -1406,6 +1462,7 @@ var BreakBB = &unicode.RangeTable{
 		{Lo: 0x119e2, Hi: 0x11a3f, Stride: 93},
 		{Lo: 0x119e2, Hi: 0x11a3f, Stride: 93},
 		{Lo: 0x11a45, Hi: 0x11a9e, Stride: 89},
 		{Lo: 0x11a45, Hi: 0x11a9e, Stride: 89},
 		{Lo: 0x11a9f, Hi: 0x11aa0, Stride: 1},
 		{Lo: 0x11a9f, Hi: 0x11aa0, Stride: 1},
+		{Lo: 0x11b00, Hi: 0x11b09, Stride: 1},
 		{Lo: 0x11c70, Hi: 0x11c70, Stride: 1},
 		{Lo: 0x11c70, Hi: 0x11c70, Stride: 1},
 	},
 	},
 }
 }
@@ -1458,7 +1515,8 @@ var BreakCM = &unicode.RangeTable{
 		{Lo: 0x0825, Hi: 0x0827, Stride: 1},
 		{Lo: 0x0825, Hi: 0x0827, Stride: 1},
 		{Lo: 0x0829, Hi: 0x082d, Stride: 1},
 		{Lo: 0x0829, Hi: 0x082d, Stride: 1},
 		{Lo: 0x0859, Hi: 0x085b, Stride: 1},
 		{Lo: 0x0859, Hi: 0x085b, Stride: 1},
-		{Lo: 0x08d3, Hi: 0x08e1, Stride: 1},
+		{Lo: 0x0898, Hi: 0x089f, Stride: 1},
+		{Lo: 0x08ca, Hi: 0x08e1, Stride: 1},
 		{Lo: 0x08e3, Hi: 0x0903, Stride: 1},
 		{Lo: 0x08e3, Hi: 0x0903, Stride: 1},
 		{Lo: 0x093a, Hi: 0x093c, Stride: 1},
 		{Lo: 0x093a, Hi: 0x093c, Stride: 1},
 		{Lo: 0x093e, Hi: 0x094f, Stride: 1},
 		{Lo: 0x093e, Hi: 0x094f, Stride: 1},
@@ -1498,7 +1556,8 @@ var BreakCM = &unicode.RangeTable{
 		{Lo: 0x0bca, Hi: 0x0bcd, Stride: 1},
 		{Lo: 0x0bca, Hi: 0x0bcd, Stride: 1},
 		{Lo: 0x0bd7, Hi: 0x0c00, Stride: 41},
 		{Lo: 0x0bd7, Hi: 0x0c00, Stride: 41},
 		{Lo: 0x0c01, Hi: 0x0c04, Stride: 1},
 		{Lo: 0x0c01, Hi: 0x0c04, Stride: 1},
-		{Lo: 0x0c3e, Hi: 0x0c44, Stride: 1},
+		{Lo: 0x0c3c, Hi: 0x0c3e, Stride: 2},
+		{Lo: 0x0c3f, Hi: 0x0c44, Stride: 1},
 		{Lo: 0x0c46, Hi: 0x0c48, Stride: 1},
 		{Lo: 0x0c46, Hi: 0x0c48, Stride: 1},
 		{Lo: 0x0c4a, Hi: 0x0c4d, Stride: 1},
 		{Lo: 0x0c4a, Hi: 0x0c4d, Stride: 1},
 		{Lo: 0x0c55, Hi: 0x0c56, Stride: 1},
 		{Lo: 0x0c55, Hi: 0x0c56, Stride: 1},
@@ -1510,7 +1569,8 @@ var BreakCM = &unicode.RangeTable{
 		{Lo: 0x0cca, Hi: 0x0ccd, Stride: 1},
 		{Lo: 0x0cca, Hi: 0x0ccd, Stride: 1},
 		{Lo: 0x0cd5, Hi: 0x0cd6, Stride: 1},
 		{Lo: 0x0cd5, Hi: 0x0cd6, Stride: 1},
 		{Lo: 0x0ce2, Hi: 0x0ce3, Stride: 1},
 		{Lo: 0x0ce2, Hi: 0x0ce3, Stride: 1},
-		{Lo: 0x0d00, Hi: 0x0d03, Stride: 1},
+		{Lo: 0x0cf3, Hi: 0x0d00, Stride: 13},
+		{Lo: 0x0d01, Hi: 0x0d03, Stride: 1},
 		{Lo: 0x0d3b, Hi: 0x0d3c, Stride: 1},
 		{Lo: 0x0d3b, Hi: 0x0d3c, Stride: 1},
 		{Lo: 0x0d3e, Hi: 0x0d44, Stride: 1},
 		{Lo: 0x0d3e, Hi: 0x0d44, Stride: 1},
 		{Lo: 0x0d46, Hi: 0x0d48, Stride: 1},
 		{Lo: 0x0d46, Hi: 0x0d48, Stride: 1},
@@ -1533,18 +1593,18 @@ var BreakCM = &unicode.RangeTable{
 		{Lo: 0x0f99, Hi: 0x0fbc, Stride: 1},
 		{Lo: 0x0f99, Hi: 0x0fbc, Stride: 1},
 		{Lo: 0x0fc6, Hi: 0x135d, Stride: 919},
 		{Lo: 0x0fc6, Hi: 0x135d, Stride: 919},
 		{Lo: 0x135e, Hi: 0x135f, Stride: 1},
 		{Lo: 0x135e, Hi: 0x135f, Stride: 1},
-		{Lo: 0x1712, Hi: 0x1714, Stride: 1},
+		{Lo: 0x1712, Hi: 0x1715, Stride: 1},
 		{Lo: 0x1732, Hi: 0x1734, Stride: 1},
 		{Lo: 0x1732, Hi: 0x1734, Stride: 1},
 		{Lo: 0x1752, Hi: 0x1753, Stride: 1},
 		{Lo: 0x1752, Hi: 0x1753, Stride: 1},
 		{Lo: 0x1772, Hi: 0x1773, Stride: 1},
 		{Lo: 0x1772, Hi: 0x1773, Stride: 1},
 		{Lo: 0x180b, Hi: 0x180d, Stride: 1},
 		{Lo: 0x180b, Hi: 0x180d, Stride: 1},
-		{Lo: 0x1885, Hi: 0x1886, Stride: 1},
-		{Lo: 0x18a9, Hi: 0x1920, Stride: 119},
-		{Lo: 0x1921, Hi: 0x192b, Stride: 1},
+		{Lo: 0x180f, Hi: 0x1885, Stride: 118},
+		{Lo: 0x1886, Hi: 0x18a9, Stride: 35},
+		{Lo: 0x1920, Hi: 0x192b, Stride: 1},
 		{Lo: 0x1930, Hi: 0x193b, Stride: 1},
 		{Lo: 0x1930, Hi: 0x193b, Stride: 1},
 		{Lo: 0x1a17, Hi: 0x1a1b, Stride: 1},
 		{Lo: 0x1a17, Hi: 0x1a1b, Stride: 1},
 		{Lo: 0x1a7f, Hi: 0x1ab0, Stride: 49},
 		{Lo: 0x1a7f, Hi: 0x1ab0, Stride: 49},
-		{Lo: 0x1ab1, Hi: 0x1ac0, Stride: 1},
+		{Lo: 0x1ab1, Hi: 0x1ace, Stride: 1},
 		{Lo: 0x1b00, Hi: 0x1b04, Stride: 1},
 		{Lo: 0x1b00, Hi: 0x1b04, Stride: 1},
 		{Lo: 0x1b34, Hi: 0x1b44, Stride: 1},
 		{Lo: 0x1b34, Hi: 0x1b44, Stride: 1},
 		{Lo: 0x1b6b, Hi: 0x1b73, Stride: 1},
 		{Lo: 0x1b6b, Hi: 0x1b73, Stride: 1},
@@ -1556,8 +1616,9 @@ var BreakCM = &unicode.RangeTable{
 		{Lo: 0x1cd4, Hi: 0x1ce8, Stride: 1},
 		{Lo: 0x1cd4, Hi: 0x1ce8, Stride: 1},
 		{Lo: 0x1ced, Hi: 0x1cf4, Stride: 7},
 		{Lo: 0x1ced, Hi: 0x1cf4, Stride: 7},
 		{Lo: 0x1cf7, Hi: 0x1cf9, Stride: 1},
 		{Lo: 0x1cf7, Hi: 0x1cf9, Stride: 1},
-		{Lo: 0x1dc0, Hi: 0x1df9, Stride: 1},
-		{Lo: 0x1dfb, Hi: 0x1dff, Stride: 1},
+		{Lo: 0x1dc0, Hi: 0x1dcc, Stride: 1},
+		{Lo: 0x1dce, Hi: 0x1dfb, Stride: 1},
+		{Lo: 0x1dfd, Hi: 0x1dff, Stride: 1},
 		{Lo: 0x200c, Hi: 0x200e, Stride: 2},
 		{Lo: 0x200c, Hi: 0x200e, Stride: 2},
 		{Lo: 0x200f, Hi: 0x202a, Stride: 27},
 		{Lo: 0x200f, Hi: 0x202a, Stride: 27},
 		{Lo: 0x202b, Hi: 0x202e, Stride: 1},
 		{Lo: 0x202b, Hi: 0x202e, Stride: 1},
@@ -1608,12 +1669,17 @@ var BreakCM = &unicode.RangeTable{
 		{Lo: 0x10ae6, Hi: 0x10d24, Stride: 574},
 		{Lo: 0x10ae6, Hi: 0x10d24, Stride: 574},
 		{Lo: 0x10d25, Hi: 0x10d27, Stride: 1},
 		{Lo: 0x10d25, Hi: 0x10d27, Stride: 1},
 		{Lo: 0x10eab, Hi: 0x10eac, Stride: 1},
 		{Lo: 0x10eab, Hi: 0x10eac, Stride: 1},
+		{Lo: 0x10efd, Hi: 0x10eff, Stride: 1},
 		{Lo: 0x10f46, Hi: 0x10f50, Stride: 1},
 		{Lo: 0x10f46, Hi: 0x10f50, Stride: 1},
+		{Lo: 0x10f82, Hi: 0x10f85, Stride: 1},
 		{Lo: 0x11000, Hi: 0x11002, Stride: 1},
 		{Lo: 0x11000, Hi: 0x11002, Stride: 1},
 		{Lo: 0x11038, Hi: 0x11046, Stride: 1},
 		{Lo: 0x11038, Hi: 0x11046, Stride: 1},
-		{Lo: 0x1107f, Hi: 0x11082, Stride: 1},
+		{Lo: 0x11070, Hi: 0x11073, Stride: 3},
+		{Lo: 0x11074, Hi: 0x1107f, Stride: 11},
+		{Lo: 0x11080, Hi: 0x11082, Stride: 1},
 		{Lo: 0x110b0, Hi: 0x110ba, Stride: 1},
 		{Lo: 0x110b0, Hi: 0x110ba, Stride: 1},
-		{Lo: 0x11100, Hi: 0x11102, Stride: 1},
+		{Lo: 0x110c2, Hi: 0x11100, Stride: 62},
+		{Lo: 0x11101, Hi: 0x11102, Stride: 1},
 		{Lo: 0x11127, Hi: 0x11134, Stride: 1},
 		{Lo: 0x11127, Hi: 0x11134, Stride: 1},
 		{Lo: 0x11145, Hi: 0x11146, Stride: 1},
 		{Lo: 0x11145, Hi: 0x11146, Stride: 1},
 		{Lo: 0x11173, Hi: 0x11180, Stride: 13},
 		{Lo: 0x11173, Hi: 0x11180, Stride: 13},
@@ -1622,8 +1688,8 @@ var BreakCM = &unicode.RangeTable{
 		{Lo: 0x111c9, Hi: 0x111cc, Stride: 1},
 		{Lo: 0x111c9, Hi: 0x111cc, Stride: 1},
 		{Lo: 0x111ce, Hi: 0x111cf, Stride: 1},
 		{Lo: 0x111ce, Hi: 0x111cf, Stride: 1},
 		{Lo: 0x1122c, Hi: 0x11237, Stride: 1},
 		{Lo: 0x1122c, Hi: 0x11237, Stride: 1},
-		{Lo: 0x1123e, Hi: 0x112df, Stride: 161},
-		{Lo: 0x112e0, Hi: 0x112ea, Stride: 1},
+		{Lo: 0x1123e, Hi: 0x11241, Stride: 3},
+		{Lo: 0x112df, Hi: 0x112ea, Stride: 1},
 		{Lo: 0x11300, Hi: 0x11303, Stride: 1},
 		{Lo: 0x11300, Hi: 0x11303, Stride: 1},
 		{Lo: 0x1133b, Hi: 0x1133c, Stride: 1},
 		{Lo: 0x1133b, Hi: 0x1133c, Stride: 1},
 		{Lo: 0x1133e, Hi: 0x11344, Stride: 1},
 		{Lo: 0x1133e, Hi: 0x11344, Stride: 1},
@@ -1669,6 +1735,12 @@ var BreakCM = &unicode.RangeTable{
 		{Lo: 0x11d90, Hi: 0x11d91, Stride: 1},
 		{Lo: 0x11d90, Hi: 0x11d91, Stride: 1},
 		{Lo: 0x11d93, Hi: 0x11d97, Stride: 1},
 		{Lo: 0x11d93, Hi: 0x11d97, Stride: 1},
 		{Lo: 0x11ef3, Hi: 0x11ef6, Stride: 1},
 		{Lo: 0x11ef3, Hi: 0x11ef6, Stride: 1},
+		{Lo: 0x11f00, Hi: 0x11f01, Stride: 1},
+		{Lo: 0x11f03, Hi: 0x11f34, Stride: 49},
+		{Lo: 0x11f35, Hi: 0x11f3a, Stride: 1},
+		{Lo: 0x11f3e, Hi: 0x11f42, Stride: 1},
+		{Lo: 0x13440, Hi: 0x13447, Stride: 7},
+		{Lo: 0x13448, Hi: 0x13455, Stride: 1},
 		{Lo: 0x16af0, Hi: 0x16af4, Stride: 1},
 		{Lo: 0x16af0, Hi: 0x16af4, Stride: 1},
 		{Lo: 0x16b30, Hi: 0x16b36, Stride: 1},
 		{Lo: 0x16b30, Hi: 0x16b36, Stride: 1},
 		{Lo: 0x16f4f, Hi: 0x16f51, Stride: 2},
 		{Lo: 0x16f4f, Hi: 0x16f51, Stride: 2},
@@ -1677,6 +1749,8 @@ var BreakCM = &unicode.RangeTable{
 		{Lo: 0x16ff0, Hi: 0x16ff1, Stride: 1},
 		{Lo: 0x16ff0, Hi: 0x16ff1, Stride: 1},
 		{Lo: 0x1bc9d, Hi: 0x1bc9e, Stride: 1},
 		{Lo: 0x1bc9d, Hi: 0x1bc9e, Stride: 1},
 		{Lo: 0x1bca0, Hi: 0x1bca3, Stride: 1},
 		{Lo: 0x1bca0, Hi: 0x1bca3, Stride: 1},
+		{Lo: 0x1cf00, Hi: 0x1cf2d, Stride: 1},
+		{Lo: 0x1cf30, Hi: 0x1cf46, Stride: 1},
 		{Lo: 0x1d165, Hi: 0x1d169, Stride: 1},
 		{Lo: 0x1d165, Hi: 0x1d169, Stride: 1},
 		{Lo: 0x1d16d, Hi: 0x1d182, Stride: 1},
 		{Lo: 0x1d16d, Hi: 0x1d182, Stride: 1},
 		{Lo: 0x1d185, Hi: 0x1d18b, Stride: 1},
 		{Lo: 0x1d185, Hi: 0x1d18b, Stride: 1},
@@ -1692,8 +1766,11 @@ var BreakCM = &unicode.RangeTable{
 		{Lo: 0x1e01b, Hi: 0x1e021, Stride: 1},
 		{Lo: 0x1e01b, Hi: 0x1e021, Stride: 1},
 		{Lo: 0x1e023, Hi: 0x1e024, Stride: 1},
 		{Lo: 0x1e023, Hi: 0x1e024, Stride: 1},
 		{Lo: 0x1e026, Hi: 0x1e02a, Stride: 1},
 		{Lo: 0x1e026, Hi: 0x1e02a, Stride: 1},
-		{Lo: 0x1e130, Hi: 0x1e136, Stride: 1},
-		{Lo: 0x1e2ec, Hi: 0x1e2ef, Stride: 1},
+		{Lo: 0x1e08f, Hi: 0x1e130, Stride: 161},
+		{Lo: 0x1e131, Hi: 0x1e136, Stride: 1},
+		{Lo: 0x1e2ae, Hi: 0x1e2ec, Stride: 62},
+		{Lo: 0x1e2ed, Hi: 0x1e2ef, Stride: 1},
+		{Lo: 0x1e4ec, Hi: 0x1e4ef, Stride: 1},
 		{Lo: 0x1e8d0, Hi: 0x1e8d6, Stride: 1},
 		{Lo: 0x1e8d0, Hi: 0x1e8d6, Stride: 1},
 		{Lo: 0x1e944, Hi: 0x1e94a, Stride: 1},
 		{Lo: 0x1e944, Hi: 0x1e94a, Stride: 1},
 		{Lo: 0xe0001, Hi: 0xe0020, Stride: 31},
 		{Lo: 0xe0001, Hi: 0xe0020, Stride: 31},
@@ -1740,6 +1817,8 @@ var BreakEB = &unicode.RangeTable{
 		{Lo: 0x1f9b9, Hi: 0x1f9bb, Stride: 2},
 		{Lo: 0x1f9b9, Hi: 0x1f9bb, Stride: 2},
 		{Lo: 0x1f9cd, Hi: 0x1f9cf, Stride: 1},
 		{Lo: 0x1f9cd, Hi: 0x1f9cf, Stride: 1},
 		{Lo: 0x1f9d1, Hi: 0x1f9dd, Stride: 1},
 		{Lo: 0x1f9d1, Hi: 0x1f9dd, Stride: 1},
+		{Lo: 0x1fac3, Hi: 0x1fac5, Stride: 1},
+		{Lo: 0x1faf0, Hi: 0x1faf8, Stride: 1},
 	},
 	},
 }
 }
 
 
@@ -2330,8 +2409,10 @@ var BreakCJ = &unicode.RangeTable{
 		{Lo: 0xff67, Hi: 0xff70, Stride: 1},
 		{Lo: 0xff67, Hi: 0xff70, Stride: 1},
 	},
 	},
 	R32: []unicode.Range32{
 	R32: []unicode.Range32{
-		{Lo: 0x1b150, Hi: 0x1b152, Stride: 1},
-		{Lo: 0x1b164, Hi: 0x1b167, Stride: 1},
+		{Lo: 0x1b132, Hi: 0x1b150, Stride: 30},
+		{Lo: 0x1b151, Hi: 0x1b152, Stride: 1},
+		{Lo: 0x1b155, Hi: 0x1b164, Stride: 15},
+		{Lo: 0x1b165, Hi: 0x1b167, Stride: 1},
 	},
 	},
 }
 }
 
 
@@ -2348,7 +2429,7 @@ var BreakSA = &unicode.RangeTable{
 		{Lo: 0x0ea8, Hi: 0x0ebd, Stride: 1},
 		{Lo: 0x0ea8, Hi: 0x0ebd, Stride: 1},
 		{Lo: 0x0ec0, Hi: 0x0ec4, Stride: 1},
 		{Lo: 0x0ec0, Hi: 0x0ec4, Stride: 1},
 		{Lo: 0x0ec6, Hi: 0x0ec8, Stride: 2},
 		{Lo: 0x0ec6, Hi: 0x0ec8, Stride: 2},
-		{Lo: 0x0ec9, Hi: 0x0ecd, Stride: 1},
+		{Lo: 0x0ec9, Hi: 0x0ece, Stride: 1},
 		{Lo: 0x0edc, Hi: 0x0edf, Stride: 1},
 		{Lo: 0x0edc, Hi: 0x0edf, Stride: 1},
 		{Lo: 0x1000, Hi: 0x103f, Stride: 1},
 		{Lo: 0x1000, Hi: 0x103f, Stride: 1},
 		{Lo: 0x1050, Hi: 0x108f, Stride: 1},
 		{Lo: 0x1050, Hi: 0x108f, Stride: 1},
@@ -2374,7 +2455,7 @@ var BreakSA = &unicode.RangeTable{
 		{Lo: 0x11700, Hi: 0x1171a, Stride: 1},
 		{Lo: 0x11700, Hi: 0x1171a, Stride: 1},
 		{Lo: 0x1171d, Hi: 0x1172b, Stride: 1},
 		{Lo: 0x1171d, Hi: 0x1172b, Stride: 1},
 		{Lo: 0x1173a, Hi: 0x1173b, Stride: 1},
 		{Lo: 0x1173a, Hi: 0x1173b, Stride: 1},
-		{Lo: 0x1173f, Hi: 0x1173f, Stride: 1},
+		{Lo: 0x1173f, Hi: 0x11746, Stride: 1},
 	},
 	},
 }
 }
 
 

+ 9 - 1
vendor/github.com/go-text/typesetting/unicodedata/mirroring.go

@@ -4,7 +4,7 @@ package unicodedata
 
 
 // Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
 // Code generated by typesettings-utils/generators/unicodedata/cmd/main.go DO NOT EDIT.
 
 
-var mirroring = map[rune]rune{ // 420 entries
+var mirroring = map[rune]rune{ // 428 entries
 	0x0028: 0x0029,
 	0x0028: 0x0029,
 	0x0029: 0x0028,
 	0x0029: 0x0028,
 	0x003c: 0x003e,
 	0x003c: 0x003e,
@@ -387,6 +387,14 @@ var mirroring = map[rune]rune{ // 420 entries
 	0x2e27: 0x2e26,
 	0x2e27: 0x2e26,
 	0x2e28: 0x2e29,
 	0x2e28: 0x2e29,
 	0x2e29: 0x2e28,
 	0x2e29: 0x2e28,
+	0x2e55: 0x2e56,
+	0x2e56: 0x2e55,
+	0x2e57: 0x2e58,
+	0x2e58: 0x2e57,
+	0x2e59: 0x2e5a,
+	0x2e5a: 0x2e59,
+	0x2e5b: 0x2e5c,
+	0x2e5c: 0x2e5b,
 	0x3008: 0x3009,
 	0x3008: 0x3009,
 	0x3009: 0x3008,
 	0x3009: 0x3008,
 	0x300a: 0x300b,
 	0x300a: 0x300b,

+ 8 - 3
vendor/github.com/go-text/typesetting/unicodedata/sentenceBreak.go → vendor/github.com/go-text/typesetting/unicodedata/sentence_break.go

@@ -10,9 +10,10 @@ import "unicode"
 var STerm = &unicode.RangeTable{
 var STerm = &unicode.RangeTable{
 	R16: []unicode.Range16{
 	R16: []unicode.Range16{
 		{Lo: 0x0021, Hi: 0x003f, Stride: 30},
 		{Lo: 0x0021, Hi: 0x003f, Stride: 30},
-		{Lo: 0x0589, Hi: 0x061e, Stride: 149},
-		{Lo: 0x061f, Hi: 0x06d4, Stride: 181},
-		{Lo: 0x0700, Hi: 0x0702, Stride: 1},
+		{Lo: 0x0589, Hi: 0x061d, Stride: 148},
+		{Lo: 0x061e, Hi: 0x061f, Stride: 1},
+		{Lo: 0x06d4, Hi: 0x0700, Stride: 44},
+		{Lo: 0x0701, Hi: 0x0702, Stride: 1},
 		{Lo: 0x07f9, Hi: 0x0837, Stride: 62},
 		{Lo: 0x07f9, Hi: 0x0837, Stride: 62},
 		{Lo: 0x0839, Hi: 0x083d, Stride: 4},
 		{Lo: 0x0839, Hi: 0x083d, Stride: 4},
 		{Lo: 0x083e, Hi: 0x0964, Stride: 294},
 		{Lo: 0x083e, Hi: 0x0964, Stride: 294},
@@ -26,11 +27,13 @@ var STerm = &unicode.RangeTable{
 		{Lo: 0x1aa9, Hi: 0x1aab, Stride: 1},
 		{Lo: 0x1aa9, Hi: 0x1aab, Stride: 1},
 		{Lo: 0x1b5a, Hi: 0x1b5b, Stride: 1},
 		{Lo: 0x1b5a, Hi: 0x1b5b, Stride: 1},
 		{Lo: 0x1b5e, Hi: 0x1b5f, Stride: 1},
 		{Lo: 0x1b5e, Hi: 0x1b5f, Stride: 1},
+		{Lo: 0x1b7d, Hi: 0x1b7e, Stride: 1},
 		{Lo: 0x1c3b, Hi: 0x1c3c, Stride: 1},
 		{Lo: 0x1c3b, Hi: 0x1c3c, Stride: 1},
 		{Lo: 0x1c7e, Hi: 0x1c7f, Stride: 1},
 		{Lo: 0x1c7e, Hi: 0x1c7f, Stride: 1},
 		{Lo: 0x203c, Hi: 0x203d, Stride: 1},
 		{Lo: 0x203c, Hi: 0x203d, Stride: 1},
 		{Lo: 0x2047, Hi: 0x2049, Stride: 1},
 		{Lo: 0x2047, Hi: 0x2049, Stride: 1},
 		{Lo: 0x2e2e, Hi: 0x2e3c, Stride: 14},
 		{Lo: 0x2e2e, Hi: 0x2e3c, Stride: 14},
+		{Lo: 0x2e53, Hi: 0x2e54, Stride: 1},
 		{Lo: 0x3002, Hi: 0xa4ff, Stride: 29949},
 		{Lo: 0x3002, Hi: 0xa4ff, Stride: 29949},
 		{Lo: 0xa60e, Hi: 0xa60f, Stride: 1},
 		{Lo: 0xa60e, Hi: 0xa60f, Stride: 1},
 		{Lo: 0xa6f3, Hi: 0xa6f7, Stride: 4},
 		{Lo: 0xa6f3, Hi: 0xa6f7, Stride: 4},
@@ -47,6 +50,7 @@ var STerm = &unicode.RangeTable{
 	R32: []unicode.Range32{
 	R32: []unicode.Range32{
 		{Lo: 0x10a56, Hi: 0x10a57, Stride: 1},
 		{Lo: 0x10a56, Hi: 0x10a57, Stride: 1},
 		{Lo: 0x10f55, Hi: 0x10f59, Stride: 1},
 		{Lo: 0x10f55, Hi: 0x10f59, Stride: 1},
+		{Lo: 0x10f86, Hi: 0x10f89, Stride: 1},
 		{Lo: 0x11047, Hi: 0x11048, Stride: 1},
 		{Lo: 0x11047, Hi: 0x11048, Stride: 1},
 		{Lo: 0x110be, Hi: 0x110c1, Stride: 1},
 		{Lo: 0x110be, Hi: 0x110c1, Stride: 1},
 		{Lo: 0x11141, Hi: 0x11143, Stride: 1},
 		{Lo: 0x11141, Hi: 0x11143, Stride: 1},
@@ -65,6 +69,7 @@ var STerm = &unicode.RangeTable{
 		{Lo: 0x11a9b, Hi: 0x11a9c, Stride: 1},
 		{Lo: 0x11a9b, Hi: 0x11a9c, Stride: 1},
 		{Lo: 0x11c41, Hi: 0x11c42, Stride: 1},
 		{Lo: 0x11c41, Hi: 0x11c42, Stride: 1},
 		{Lo: 0x11ef7, Hi: 0x11ef8, Stride: 1},
 		{Lo: 0x11ef7, Hi: 0x11ef8, Stride: 1},
+		{Lo: 0x11f43, Hi: 0x11f44, Stride: 1},
 		{Lo: 0x16a6e, Hi: 0x16a6f, Stride: 1},
 		{Lo: 0x16a6e, Hi: 0x16a6f, Stride: 1},
 		{Lo: 0x16af5, Hi: 0x16b37, Stride: 66},
 		{Lo: 0x16af5, Hi: 0x16b37, Stride: 66},
 		{Lo: 0x16b38, Hi: 0x16b44, Stride: 12},
 		{Lo: 0x16b38, Hi: 0x16b44, Stride: 12},

+ 3 - 0
vendor/github.com/go-text/typesetting/unicodedata/unicode.go

@@ -136,6 +136,8 @@ func Decompose(ab rune) (a, b rune, ok bool) {
 	if a, b, ok = decomposeHangul(ab); ok {
 	if a, b, ok = decomposeHangul(ab); ok {
 		return a, b, true
 		return a, b, true
 	}
 	}
+
+	// Check if it's a single-character decomposition.
 	if m1, ok := decompose1[ab]; ok {
 	if m1, ok := decompose1[ab]; ok {
 		return m1, 0, true
 		return m1, 0, true
 	}
 	}
@@ -149,6 +151,7 @@ func Decompose(ab rune) (a, b rune, ok bool) {
 // points by canonical equivalence, returning the composed code, if successful.
 // points by canonical equivalence, returning the composed code, if successful.
 // It returns `false` otherwise
 // It returns `false` otherwise
 func Compose(a, b rune) (rune, bool) {
 func Compose(a, b rune) (rune, bool) {
+	// Hangul is handled algorithmically.
 	if ab, ok := composeHangul(a, b); ok {
 	if ab, ok := composeHangul(a, b); ok {
 		return ab, true
 		return ab, true
 	}
 	}

+ 19 - 0
vendor/github.com/jsummers/gobmp/COPYING.txt

@@ -0,0 +1,19 @@
+Copyright (c) 2012-2015 Jason Summers
+
+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.

+ 3 - 22
vendor/github.com/jsummers/gobmp/readme.md

@@ -40,27 +40,8 @@ Writing compressed images is not supported.
 License
 License
 -------
 -------
 
 
-Gobmp is distributed under an MIT-style license.
+Gobmp is distributed under an MIT-style license. Refer to the COPYING.txt
+file.
 
 
-Copyright &copy; 2012-2013 Jason Summers
+Copyright &copy; 2012-2015 Jason Summers
 <[jason1@pobox.com](mailto:jason1@pobox.com)>
 <[jason1@pobox.com](mailto:jason1@pobox.com)>
-
-<pre>
-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.
-</pre>

+ 1 - 1
vendor/github.com/muesli/termenv/color.go

@@ -68,7 +68,7 @@ func ConvertToRGB(c Color) colorful.Color {
 }
 }
 
 
 // Sequence returns the ANSI Sequence for the color.
 // Sequence returns the ANSI Sequence for the color.
-func (c NoColor) Sequence(bg bool) string {
+func (c NoColor) Sequence(_ bool) string {
 	return ""
 	return ""
 }
 }
 
 

+ 6 - 2
vendor/github.com/muesli/termenv/termenv_unix.go

@@ -25,6 +25,10 @@ func (o *Output) ColorProfile() Profile {
 		return Ascii
 		return Ascii
 	}
 	}
 
 
+	if o.environ.Getenv("GOOGLE_CLOUD_SHELL") == "true" {
+		return TrueColor
+	}
+
 	term := o.environ.Getenv("TERM")
 	term := o.environ.Getenv("TERM")
 	colorTerm := o.environ.Getenv("COLORTERM")
 	colorTerm := o.environ.Getenv("COLORTERM")
 
 
@@ -46,7 +50,7 @@ func (o *Output) ColorProfile() Profile {
 	}
 	}
 
 
 	switch term {
 	switch term {
-	case "xterm-kitty":
+	case "xterm-kitty", "wezterm":
 		return TrueColor
 		return TrueColor
 	case "linux":
 	case "linux":
 		return ANSI
 		return ANSI
@@ -284,6 +288,6 @@ func (o Output) termStatusReport(sequence int) (string, error) {
 // Windows for w and returns a function that restores w to its previous state.
 // Windows for w and returns a function that restores w to its previous state.
 // On non-Windows platforms, or if w does not refer to a terminal, then it
 // On non-Windows platforms, or if w does not refer to a terminal, then it
 // returns a non-nil no-op function and no error.
 // returns a non-nil no-op function and no error.
-func EnableVirtualTerminalProcessing(w io.Writer) (func() error, error) {
+func EnableVirtualTerminalProcessing(_ io.Writer) (func() error, error) {
 	return func() error { return nil }, nil
 	return func() error { return nil }, nil
 }
 }

+ 4 - 0
vendor/github.com/yuin/goldmark/README.md

@@ -440,6 +440,9 @@ Extensions
 - [goldmark-pdf](https://github.com/stephenafamo/goldmark-pdf): A PDF renderer that can be passed to `goldmark.WithRenderer()`.
 - [goldmark-pdf](https://github.com/stephenafamo/goldmark-pdf): A PDF renderer that can be passed to `goldmark.WithRenderer()`.
 - [goldmark-hashtag](https://github.com/abhinav/goldmark-hashtag): Adds support for `#hashtag`-based tagging to goldmark.
 - [goldmark-hashtag](https://github.com/abhinav/goldmark-hashtag): Adds support for `#hashtag`-based tagging to goldmark.
 - [goldmark-wikilink](https://github.com/abhinav/goldmark-wikilink): Adds support for `[[wiki]]`-style links to goldmark.
 - [goldmark-wikilink](https://github.com/abhinav/goldmark-wikilink): Adds support for `[[wiki]]`-style links to goldmark.
+- [goldmark-anchor](https://github.com/abhinav/goldmark-anchor): Adds anchors (permalinks) next to all headers in a document.
+- [goldmark-figure](https://github.com/mangoumbrella/goldmark-figure): Adds support for rendering paragraphs starting with an image to `<figure>` elements.
+- [goldmark-frontmatter](https://github.com/abhinav/goldmark-frontmatter): Adds support for YAML, TOML, and custom front matter to documents.
 - [goldmark-toc](https://github.com/abhinav/goldmark-toc): Adds support for generating tables-of-contents for goldmark documents.
 - [goldmark-toc](https://github.com/abhinav/goldmark-toc): Adds support for generating tables-of-contents for goldmark documents.
 - [goldmark-mermaid](https://github.com/abhinav/goldmark-mermaid): Adds support for rendering [Mermaid](https://mermaid-js.github.io/mermaid/) diagrams in goldmark documents.
 - [goldmark-mermaid](https://github.com/abhinav/goldmark-mermaid): Adds support for rendering [Mermaid](https://mermaid-js.github.io/mermaid/) diagrams in goldmark documents.
 - [goldmark-pikchr](https://github.com/jchenry/goldmark-pikchr): Adds support for rendering [Pikchr](https://pikchr.org/home/doc/trunk/homepage.md) diagrams in goldmark documents.
 - [goldmark-pikchr](https://github.com/jchenry/goldmark-pikchr): Adds support for rendering [Pikchr](https://pikchr.org/home/doc/trunk/homepage.md) diagrams in goldmark documents.
@@ -448,6 +451,7 @@ Extensions
 - [goldmark-fences](https://github.com/stefanfritsch/goldmark-fences): Support for pandoc-style [fenced divs](https://pandoc.org/MANUAL.html#divs-and-spans) in goldmark.
 - [goldmark-fences](https://github.com/stefanfritsch/goldmark-fences): Support for pandoc-style [fenced divs](https://pandoc.org/MANUAL.html#divs-and-spans) in goldmark.
 - [goldmark-d2](https://github.com/FurqanSoftware/goldmark-d2): Adds support for [D2](https://d2lang.com/) diagrams.
 - [goldmark-d2](https://github.com/FurqanSoftware/goldmark-d2): Adds support for [D2](https://d2lang.com/) diagrams.
 - [goldmark-katex](https://github.com/FurqanSoftware/goldmark-katex): Adds support for [KaTeX](https://katex.org/) math and equations.
 - [goldmark-katex](https://github.com/FurqanSoftware/goldmark-katex): Adds support for [KaTeX](https://katex.org/) math and equations.
+- [goldmark-img64](https://github.com/tenkoh/goldmark-img64): Adds support for embedding images into the document as DataURL (base64 encoded).
 
 
 
 
 goldmark internal(for extension developers)
 goldmark internal(for extension developers)

+ 3 - 3
vendor/github.com/yuin/goldmark/parser/raw_html.go

@@ -48,10 +48,10 @@ func (s *rawHTMLParser) Parse(parent ast.Node, block text.Reader, pc Context) as
 }
 }
 
 
 var tagnamePattern = `([A-Za-z][A-Za-z0-9-]*)`
 var tagnamePattern = `([A-Za-z][A-Za-z0-9-]*)`
-
+var spaceOrOneNewline = `(?:[ \t]|(?:\r\n|\n){0,1})`
 var attributePattern = `(?:[\r\n \t]+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:[\r\n \t]*=[\r\n \t]*(?:[^\"'=<>` + "`" + `\x00-\x20]+|'[^']*'|"[^"]*"))?)`
 var attributePattern = `(?:[\r\n \t]+[a-zA-Z_:][a-zA-Z0-9:._-]*(?:[\r\n \t]*=[\r\n \t]*(?:[^\"'=<>` + "`" + `\x00-\x20]+|'[^']*'|"[^"]*"))?)`
-var openTagRegexp = regexp.MustCompile("^<" + tagnamePattern + attributePattern + `*[ \t]*/?>`)
-var closeTagRegexp = regexp.MustCompile("^</" + tagnamePattern + `\s*>`)
+var openTagRegexp = regexp.MustCompile("^<" + tagnamePattern + attributePattern + `*` + spaceOrOneNewline + `*/?>`)
+var closeTagRegexp = regexp.MustCompile("^</" + tagnamePattern + spaceOrOneNewline + `*>`)
 
 
 var openProcessingInstruction = []byte("<?")
 var openProcessingInstruction = []byte("<?")
 var closeProcessingInstruction = []byte("?>")
 var closeProcessingInstruction = []byte("?>")

+ 10 - 6
vendor/github.com/yuin/goldmark/renderer/html/html.go

@@ -901,20 +901,24 @@ var bVb = []byte("vbscript:")
 var bFile = []byte("file:")
 var bFile = []byte("file:")
 var bData = []byte("data:")
 var bData = []byte("data:")
 
 
+func hasPrefix(s, prefix []byte) bool {
+	return len(s) >= len(prefix) && bytes.Equal(bytes.ToLower(s[0:len(prefix)]), bytes.ToLower(prefix))
+}
+
 // IsDangerousURL returns true if the given url seems a potentially dangerous url,
 // IsDangerousURL returns true if the given url seems a potentially dangerous url,
 // otherwise false.
 // otherwise false.
 func IsDangerousURL(url []byte) bool {
 func IsDangerousURL(url []byte) bool {
-	if bytes.HasPrefix(url, bDataImage) && len(url) >= 11 {
+	if hasPrefix(url, bDataImage) && len(url) >= 11 {
 		v := url[11:]
 		v := url[11:]
-		if bytes.HasPrefix(v, bPng) || bytes.HasPrefix(v, bGif) ||
-			bytes.HasPrefix(v, bJpeg) || bytes.HasPrefix(v, bWebp) ||
-			bytes.HasPrefix(v, bSvg) {
+		if hasPrefix(v, bPng) || hasPrefix(v, bGif) ||
+			hasPrefix(v, bJpeg) || hasPrefix(v, bWebp) ||
+			hasPrefix(v, bSvg) {
 			return false
 			return false
 		}
 		}
 		return true
 		return true
 	}
 	}
-	return bytes.HasPrefix(url, bJs) || bytes.HasPrefix(url, bVb) ||
-		bytes.HasPrefix(url, bFile) || bytes.HasPrefix(url, bData)
+	return hasPrefix(url, bJs) || hasPrefix(url, bVb) ||
+		hasPrefix(url, bFile) || hasPrefix(url, bData)
 }
 }
 
 
 func nodeToHTMLText(n ast.Node, source []byte) []byte {
 func nodeToHTMLText(n ast.Node, source []byte) []byte {

+ 14 - 7
vendor/github.com/yuin/goldmark/text/reader.go

@@ -1,6 +1,7 @@
 package text
 package text
 
 
 import (
 import (
+	"bytes"
 	"io"
 	"io"
 	"regexp"
 	"regexp"
 	"unicode/utf8"
 	"unicode/utf8"
@@ -537,24 +538,30 @@ func matchReader(r Reader, reg *regexp.Regexp) bool {
 }
 }
 
 
 func findSubMatchReader(r Reader, reg *regexp.Regexp) [][]byte {
 func findSubMatchReader(r Reader, reg *regexp.Regexp) [][]byte {
-	oldline, oldseg := r.Position()
+	oldLine, oldSeg := r.Position()
 	match := reg.FindReaderSubmatchIndex(r)
 	match := reg.FindReaderSubmatchIndex(r)
-	r.SetPosition(oldline, oldseg)
+	r.SetPosition(oldLine, oldSeg)
 	if match == nil {
 	if match == nil {
 		return nil
 		return nil
 	}
 	}
-	runes := make([]rune, 0, match[1]-match[0])
+	var bb bytes.Buffer
+	bb.Grow(match[1] - match[0])
 	for i := 0; i < match[1]; {
 	for i := 0; i < match[1]; {
 		r, size, _ := readRuneReader(r)
 		r, size, _ := readRuneReader(r)
 		i += size
 		i += size
-		runes = append(runes, r)
+		bb.WriteRune(r)
 	}
 	}
-	result := [][]byte{}
+	bs := bb.Bytes()
+	var result [][]byte
 	for i := 0; i < len(match); i += 2 {
 	for i := 0; i < len(match); i += 2 {
-		result = append(result, []byte(string(runes[match[i]:match[i+1]])))
+		if match[i] < 0 {
+			result = append(result, []byte{})
+			continue
+		}
+		result = append(result, bs[match[i]:match[i+1]])
 	}
 	}
 
 
-	r.SetPosition(oldline, oldseg)
+	r.SetPosition(oldLine, oldSeg)
 	r.Advance(match[1] - match[0])
 	r.Advance(match[1] - match[0])
 	return result
 	return result
 }
 }

+ 28 - 5
vendor/golang.org/x/image/tiff/reader.go

@@ -8,13 +8,13 @@
 package tiff // import "golang.org/x/image/tiff"
 package tiff // import "golang.org/x/image/tiff"
 
 
 import (
 import (
+	"bytes"
 	"compress/zlib"
 	"compress/zlib"
 	"encoding/binary"
 	"encoding/binary"
 	"fmt"
 	"fmt"
 	"image"
 	"image"
 	"image/color"
 	"image/color"
 	"io"
 	"io"
-	"io/ioutil"
 	"math"
 	"math"
 
 
 	"golang.org/x/image/ccitt"
 	"golang.org/x/image/ccitt"
@@ -579,6 +579,11 @@ func newDecoder(r io.Reader) (*decoder, error) {
 	default:
 	default:
 		return nil, UnsupportedError("color model")
 		return nil, UnsupportedError("color model")
 	}
 	}
+	if d.firstVal(tPhotometricInterpretation) != pRGB {
+		if len(d.features[tBitsPerSample]) != 1 {
+			return nil, UnsupportedError("extra samples")
+		}
+	}
 
 
 	return d, nil
 	return d, nil
 }
 }
@@ -629,6 +634,13 @@ func Decode(r io.Reader) (img image.Image, err error) {
 		blockWidth = int(d.firstVal(tTileWidth))
 		blockWidth = int(d.firstVal(tTileWidth))
 		blockHeight = int(d.firstVal(tTileLength))
 		blockHeight = int(d.firstVal(tTileLength))
 
 
+		// The specification says that tile widths and lengths must be a multiple of 16.
+		// We currently permit invalid sizes, but reject anything too small to limit the
+		// amount of work a malicious input can force us to perform.
+		if blockWidth < 8 || blockHeight < 8 {
+			return nil, FormatError("tile size is too small")
+		}
+
 		if blockWidth != 0 {
 		if blockWidth != 0 {
 			blocksAcross = (d.config.Width + blockWidth - 1) / blockWidth
 			blocksAcross = (d.config.Width + blockWidth - 1) / blockWidth
 		}
 		}
@@ -681,6 +693,11 @@ func Decode(r io.Reader) (img image.Image, err error) {
 		}
 		}
 	}
 	}
 
 
+	if blocksAcross == 0 || blocksDown == 0 {
+		return
+	}
+	// Maximum data per pixel is 8 bytes (RGBA64).
+	blockMaxDataSize := int64(blockWidth) * int64(blockHeight) * 8
 	for i := 0; i < blocksAcross; i++ {
 	for i := 0; i < blocksAcross; i++ {
 		blkW := blockWidth
 		blkW := blockWidth
 		if !blockPadding && i == blocksAcross-1 && d.config.Width%blockWidth != 0 {
 		if !blockPadding && i == blocksAcross-1 && d.config.Width%blockWidth != 0 {
@@ -708,15 +725,15 @@ func Decode(r io.Reader) (img image.Image, err error) {
 				inv := d.firstVal(tPhotometricInterpretation) == pWhiteIsZero
 				inv := d.firstVal(tPhotometricInterpretation) == pWhiteIsZero
 				order := ccittFillOrder(d.firstVal(tFillOrder))
 				order := ccittFillOrder(d.firstVal(tFillOrder))
 				r := ccitt.NewReader(io.NewSectionReader(d.r, offset, n), order, ccitt.Group3, blkW, blkH, &ccitt.Options{Invert: inv, Align: false})
 				r := ccitt.NewReader(io.NewSectionReader(d.r, offset, n), order, ccitt.Group3, blkW, blkH, &ccitt.Options{Invert: inv, Align: false})
-				d.buf, err = ioutil.ReadAll(r)
+				d.buf, err = readBuf(r, d.buf, blockMaxDataSize)
 			case cG4:
 			case cG4:
 				inv := d.firstVal(tPhotometricInterpretation) == pWhiteIsZero
 				inv := d.firstVal(tPhotometricInterpretation) == pWhiteIsZero
 				order := ccittFillOrder(d.firstVal(tFillOrder))
 				order := ccittFillOrder(d.firstVal(tFillOrder))
 				r := ccitt.NewReader(io.NewSectionReader(d.r, offset, n), order, ccitt.Group4, blkW, blkH, &ccitt.Options{Invert: inv, Align: false})
 				r := ccitt.NewReader(io.NewSectionReader(d.r, offset, n), order, ccitt.Group4, blkW, blkH, &ccitt.Options{Invert: inv, Align: false})
-				d.buf, err = ioutil.ReadAll(r)
+				d.buf, err = readBuf(r, d.buf, blockMaxDataSize)
 			case cLZW:
 			case cLZW:
 				r := lzw.NewReader(io.NewSectionReader(d.r, offset, n), lzw.MSB, 8)
 				r := lzw.NewReader(io.NewSectionReader(d.r, offset, n), lzw.MSB, 8)
-				d.buf, err = ioutil.ReadAll(r)
+				d.buf, err = readBuf(r, d.buf, blockMaxDataSize)
 				r.Close()
 				r.Close()
 			case cDeflate, cDeflateOld:
 			case cDeflate, cDeflateOld:
 				var r io.ReadCloser
 				var r io.ReadCloser
@@ -724,7 +741,7 @@ func Decode(r io.Reader) (img image.Image, err error) {
 				if err != nil {
 				if err != nil {
 					return nil, err
 					return nil, err
 				}
 				}
-				d.buf, err = ioutil.ReadAll(r)
+				d.buf, err = readBuf(r, d.buf, blockMaxDataSize)
 				r.Close()
 				r.Close()
 			case cPackBits:
 			case cPackBits:
 				d.buf, err = unpackBits(io.NewSectionReader(d.r, offset, n))
 				d.buf, err = unpackBits(io.NewSectionReader(d.r, offset, n))
@@ -748,6 +765,12 @@ func Decode(r io.Reader) (img image.Image, err error) {
 	return
 	return
 }
 }
 
 
+func readBuf(r io.Reader, buf []byte, lim int64) ([]byte, error) {
+	b := bytes.NewBuffer(buf[:0])
+	_, err := b.ReadFrom(io.LimitReader(r, lim))
+	return b.Bytes(), err
+}
+
 func init() {
 func init() {
 	image.RegisterFormat("tiff", leHeader, Decode, DecodeConfig)
 	image.RegisterFormat("tiff", leHeader, Decode, DecodeConfig)
 	image.RegisterFormat("tiff", beHeader, Decode, DecodeConfig)
 	image.RegisterFormat("tiff", beHeader, Decode, DecodeConfig)

+ 24 - 4
vendor/golang.org/x/net/html/render.go

@@ -194,9 +194,8 @@ func render1(w writer, n *Node) error {
 		}
 		}
 	}
 	}
 
 
-	// Render any child nodes.
-	switch n.Data {
-	case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp":
+	// Render any child nodes
+	if childTextNodesAreLiteral(n) {
 		for c := n.FirstChild; c != nil; c = c.NextSibling {
 		for c := n.FirstChild; c != nil; c = c.NextSibling {
 			if c.Type == TextNode {
 			if c.Type == TextNode {
 				if _, err := w.WriteString(c.Data); err != nil {
 				if _, err := w.WriteString(c.Data); err != nil {
@@ -213,7 +212,7 @@ func render1(w writer, n *Node) error {
 			// last element in the file, with no closing tag.
 			// last element in the file, with no closing tag.
 			return plaintextAbort
 			return plaintextAbort
 		}
 		}
-	default:
+	} else {
 		for c := n.FirstChild; c != nil; c = c.NextSibling {
 		for c := n.FirstChild; c != nil; c = c.NextSibling {
 			if err := render1(w, c); err != nil {
 			if err := render1(w, c); err != nil {
 				return err
 				return err
@@ -231,6 +230,27 @@ func render1(w writer, n *Node) error {
 	return w.WriteByte('>')
 	return w.WriteByte('>')
 }
 }
 
 
+func childTextNodesAreLiteral(n *Node) bool {
+	// Per WHATWG HTML 13.3, if the parent of the current node is a style,
+	// script, xmp, iframe, noembed, noframes, or plaintext element, and the
+	// current node is a text node, append the value of the node's data
+	// literally. The specification is not explicit about it, but we only
+	// enforce this if we are in the HTML namespace (i.e. when the namespace is
+	// "").
+	// NOTE: we also always include noscript elements, although the
+	// specification states that they should only be rendered as such if
+	// scripting is enabled for the node (which is not something we track).
+	if n.Namespace != "" {
+		return false
+	}
+	switch n.Data {
+	case "iframe", "noembed", "noframes", "noscript", "plaintext", "script", "style", "xmp":
+		return true
+	default:
+		return false
+	}
+}
+
 // writeQuoted writes s to w surrounded by quotes. Normally it will use double
 // writeQuoted writes s to w surrounded by quotes. Normally it will use double
 // quotes, but if s contains a double quote, it will use single quotes.
 // quotes, but if s contains a double quote, it will use single quotes.
 // It is used for writing the identifiers in a doctype declaration.
 // It is used for writing the identifiers in a doctype declaration.

+ 8 - 1
vendor/golang.org/x/net/html/token.go

@@ -913,7 +913,14 @@ func (z *Tokenizer) readTagAttrKey() {
 		case ' ', '\n', '\r', '\t', '\f', '/':
 		case ' ', '\n', '\r', '\t', '\f', '/':
 			z.pendingAttr[0].end = z.raw.end - 1
 			z.pendingAttr[0].end = z.raw.end - 1
 			return
 			return
-		case '=', '>':
+		case '=':
+			if z.pendingAttr[0].start+1 == z.raw.end {
+				// WHATWG 13.2.5.32, if we see an equals sign before the attribute name
+				// begins, we treat it as a character in the attribute name and continue.
+				continue
+			}
+			fallthrough
+		case '>':
 			z.raw.end--
 			z.raw.end--
 			z.pendingAttr[0].end = z.raw.end
 			z.pendingAttr[0].end = z.raw.end
 			return
 			return

+ 5 - 5
vendor/golang.org/x/sync/errgroup/errgroup.go

@@ -20,7 +20,7 @@ type token struct{}
 // A zero Group is valid, has no limit on the number of active goroutines,
 // A zero Group is valid, has no limit on the number of active goroutines,
 // and does not cancel on error.
 // and does not cancel on error.
 type Group struct {
 type Group struct {
-	cancel func()
+	cancel func(error)
 
 
 	wg sync.WaitGroup
 	wg sync.WaitGroup
 
 
@@ -43,7 +43,7 @@ func (g *Group) done() {
 // returns a non-nil error or the first time Wait returns, whichever occurs
 // returns a non-nil error or the first time Wait returns, whichever occurs
 // first.
 // first.
 func WithContext(ctx context.Context) (*Group, context.Context) {
 func WithContext(ctx context.Context) (*Group, context.Context) {
-	ctx, cancel := context.WithCancel(ctx)
+	ctx, cancel := withCancelCause(ctx)
 	return &Group{cancel: cancel}, ctx
 	return &Group{cancel: cancel}, ctx
 }
 }
 
 
@@ -52,7 +52,7 @@ func WithContext(ctx context.Context) (*Group, context.Context) {
 func (g *Group) Wait() error {
 func (g *Group) Wait() error {
 	g.wg.Wait()
 	g.wg.Wait()
 	if g.cancel != nil {
 	if g.cancel != nil {
-		g.cancel()
+		g.cancel(g.err)
 	}
 	}
 	return g.err
 	return g.err
 }
 }
@@ -76,7 +76,7 @@ func (g *Group) Go(f func() error) {
 			g.errOnce.Do(func() {
 			g.errOnce.Do(func() {
 				g.err = err
 				g.err = err
 				if g.cancel != nil {
 				if g.cancel != nil {
-					g.cancel()
+					g.cancel(g.err)
 				}
 				}
 			})
 			})
 		}
 		}
@@ -105,7 +105,7 @@ func (g *Group) TryGo(f func() error) bool {
 			g.errOnce.Do(func() {
 			g.errOnce.Do(func() {
 				g.err = err
 				g.err = err
 				if g.cancel != nil {
 				if g.cancel != nil {
-					g.cancel()
+					g.cancel(g.err)
 				}
 				}
 			})
 			})
 		}
 		}

+ 14 - 0
vendor/golang.org/x/sync/errgroup/go120.go

@@ -0,0 +1,14 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build go1.20
+// +build go1.20
+
+package errgroup
+
+import "context"
+
+func withCancelCause(parent context.Context) (context.Context, func(error)) {
+	return context.WithCancelCause(parent)
+}

+ 15 - 0
vendor/golang.org/x/sync/errgroup/pre_go120.go

@@ -0,0 +1,15 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build !go1.20
+// +build !go1.20
+
+package errgroup
+
+import "context"
+
+func withCancelCause(parent context.Context) (context.Context, func(error)) {
+	ctx, cancel := context.WithCancel(parent)
+	return ctx, func(error) { cancel() }
+}

+ 1 - 1
vendor/golang.org/x/sys/unix/mkall.sh

@@ -50,7 +50,7 @@ if [[ "$GOOS" = "linux" ]]; then
 	# Use the Docker-based build system
 	# Use the Docker-based build system
 	# Files generated through docker (use $cmd so you can Ctl-C the build or run)
 	# Files generated through docker (use $cmd so you can Ctl-C the build or run)
 	$cmd docker build --tag generate:$GOOS $GOOS
 	$cmd docker build --tag generate:$GOOS $GOOS
-	$cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && /bin/pwd):/build generate:$GOOS
+	$cmd docker run --interactive --tty --volume $(cd -- "$(dirname -- "$0")/.." && pwd):/build generate:$GOOS
 	exit
 	exit
 fi
 fi
 
 

+ 6 - 4
vendor/golang.org/x/sys/unix/mkerrors.sh

@@ -519,7 +519,7 @@ ccflags="$@"
 		$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
 		$2 ~ /^LOCK_(SH|EX|NB|UN)$/ ||
 		$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
 		$2 ~ /^LO_(KEY|NAME)_SIZE$/ ||
 		$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
 		$2 ~ /^LOOP_(CLR|CTL|GET|SET)_/ ||
-		$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
+		$2 ~ /^(AF|SOCK|SO|SOL|IPPROTO|IP|IPV6|TCP|MCAST|EVFILT|NOTE|SHUT|PROT|MAP|MREMAP|MFD|T?PACKET|MSG|SCM|MCL|DT|MADV|PR|LOCAL|TCPOPT|UDP)_/ ||
 		$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
 		$2 ~ /^NFC_(GENL|PROTO|COMM|RF|SE|DIRECTION|LLCP|SOCKPROTO)_/ ||
 		$2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
 		$2 ~ /^NFC_.*_(MAX)?SIZE$/ ||
 		$2 ~ /^RAW_PAYLOAD_/ ||
 		$2 ~ /^RAW_PAYLOAD_/ ||
@@ -624,7 +624,7 @@ ccflags="$@"
 		$2 ~ /^MEM/ ||
 		$2 ~ /^MEM/ ||
 		$2 ~ /^WG/ ||
 		$2 ~ /^WG/ ||
 		$2 ~ /^FIB_RULE_/ ||
 		$2 ~ /^FIB_RULE_/ ||
-		$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE)/ {printf("\t%s = C.%s\n", $2, $2)}
+		$2 ~ /^BLK[A-Z]*(GET$|SET$|BUF$|PART$|SIZE|IOMIN$|IOOPT$|ALIGNOFF$|DISCARD|ROTATIONAL$|ZEROOUT$|GETDISKSEQ$)/ {printf("\t%s = C.%s\n", $2, $2)}
 		$2 ~ /^__WCOREFLAG$/ {next}
 		$2 ~ /^__WCOREFLAG$/ {next}
 		$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
 		$2 ~ /^__W[A-Z0-9]+$/ {printf("\t%s = C.%s\n", substr($2,3), $2)}
 
 
@@ -741,7 +741,8 @@ main(void)
 		e = errors[i].num;
 		e = errors[i].num;
 		if(i > 0 && errors[i-1].num == e)
 		if(i > 0 && errors[i-1].num == e)
 			continue;
 			continue;
-		strcpy(buf, strerror(e));
+		strncpy(buf, strerror(e), sizeof(buf) - 1);
+		buf[sizeof(buf) - 1] = '\0';
 		// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
 		// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
 		if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
 		if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
 			buf[0] += a - A;
 			buf[0] += a - A;
@@ -760,7 +761,8 @@ main(void)
 		e = signals[i].num;
 		e = signals[i].num;
 		if(i > 0 && signals[i-1].num == e)
 		if(i > 0 && signals[i-1].num == e)
 			continue;
 			continue;
-		strcpy(buf, strsignal(e));
+		strncpy(buf, strsignal(e), sizeof(buf) - 1);
+		buf[sizeof(buf) - 1] = '\0';
 		// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
 		// lowercase first letter: Bad -> bad, but STREAM -> STREAM.
 		if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
 		if(A <= buf[0] && buf[0] <= Z && a <= buf[1] && buf[1] <= z)
 			buf[0] += a - A;
 			buf[0] += a - A;

+ 14 - 0
vendor/golang.org/x/sys/unix/mmap_nomremap.go

@@ -0,0 +1,14 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build aix || darwin || dragonfly || freebsd || openbsd || solaris
+// +build aix darwin dragonfly freebsd openbsd solaris
+
+package unix
+
+var mapper = &mmapper{
+	active: make(map[*byte][]byte),
+	mmap:   mmap,
+	munmap: munmap,
+}

+ 53 - 0
vendor/golang.org/x/sys/unix/mremap.go

@@ -0,0 +1,53 @@
+// Copyright 2023 The Go Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style
+// license that can be found in the LICENSE file.
+
+//go:build linux || netbsd
+// +build linux netbsd
+
+package unix
+
+import "unsafe"
+
+type mremapMmapper struct {
+	mmapper
+	mremap func(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
+}
+
+var mapper = &mremapMmapper{
+	mmapper: mmapper{
+		active: make(map[*byte][]byte),
+		mmap:   mmap,
+		munmap: munmap,
+	},
+	mremap: mremap,
+}
+
+func (m *mremapMmapper) Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
+	if newLength <= 0 || len(oldData) == 0 || len(oldData) != cap(oldData) || flags&mremapFixed != 0 {
+		return nil, EINVAL
+	}
+
+	pOld := &oldData[cap(oldData)-1]
+	m.Lock()
+	defer m.Unlock()
+	bOld := m.active[pOld]
+	if bOld == nil || &bOld[0] != &oldData[0] {
+		return nil, EINVAL
+	}
+	newAddr, errno := m.mremap(uintptr(unsafe.Pointer(&bOld[0])), uintptr(len(bOld)), uintptr(newLength), flags, 0)
+	if errno != nil {
+		return nil, errno
+	}
+	bNew := unsafe.Slice((*byte)(unsafe.Pointer(newAddr)), newLength)
+	pNew := &bNew[cap(bNew)-1]
+	if flags&mremapDontunmap == 0 {
+		delete(m.active, pOld)
+	}
+	m.active[pNew] = bNew
+	return bNew, nil
+}
+
+func Mremap(oldData []byte, newLength int, flags int) (data []byte, err error) {
+	return mapper.Mremap(oldData, newLength, flags)
+}

+ 0 - 15
vendor/golang.org/x/sys/unix/syscall_aix.go

@@ -535,21 +535,6 @@ func Fsync(fd int) error {
 //sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg
 //sys	sendmsg(s int, msg *Msghdr, flags int) (n int, err error) = nsendmsg
 
 
 //sys	munmap(addr uintptr, length uintptr) (err error)
 //sys	munmap(addr uintptr, length uintptr) (err error)
-
-var mapper = &mmapper{
-	active: make(map[*byte][]byte),
-	mmap:   mmap,
-	munmap: munmap,
-}
-
-func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
-	return mapper.Mmap(fd, offset, length, prot, flags)
-}
-
-func Munmap(b []byte) (err error) {
-	return mapper.Munmap(b)
-}
-
 //sys	Madvise(b []byte, advice int) (err error)
 //sys	Madvise(b []byte, advice int) (err error)
 //sys	Mprotect(b []byte, prot int) (err error)
 //sys	Mprotect(b []byte, prot int) (err error)
 //sys	Mlock(b []byte) (err error)
 //sys	Mlock(b []byte) (err error)

+ 0 - 14
vendor/golang.org/x/sys/unix/syscall_bsd.go

@@ -601,20 +601,6 @@ func Poll(fds []PollFd, timeout int) (n int, err error) {
 //	Gethostuuid(uuid *byte, timeout *Timespec) (err error)
 //	Gethostuuid(uuid *byte, timeout *Timespec) (err error)
 //	Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error)
 //	Ptrace(req int, pid int, addr uintptr, data int) (ret uintptr, err error)
 
 
-var mapper = &mmapper{
-	active: make(map[*byte][]byte),
-	mmap:   mmap,
-	munmap: munmap,
-}
-
-func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
-	return mapper.Mmap(fd, offset, length, prot, flags)
-}
-
-func Munmap(b []byte) (err error) {
-	return mapper.Munmap(b)
-}
-
 //sys	Madvise(b []byte, behav int) (err error)
 //sys	Madvise(b []byte, behav int) (err error)
 //sys	Mlock(b []byte) (err error)
 //sys	Mlock(b []byte) (err error)
 //sys	Mlockall(flags int) (err error)
 //sys	Mlockall(flags int) (err error)

+ 28 - 22
vendor/golang.org/x/sys/unix/syscall_darwin.go

@@ -510,30 +510,36 @@ func SysctlKinfoProcSlice(name string, args ...int) ([]KinfoProc, error) {
 		return nil, err
 		return nil, err
 	}
 	}
 
 
-	// Find size.
-	n := uintptr(0)
-	if err := sysctl(mib, nil, &n, nil, 0); err != nil {
-		return nil, err
-	}
-	if n == 0 {
-		return nil, nil
-	}
-	if n%SizeofKinfoProc != 0 {
-		return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
-	}
+	for {
+		// Find size.
+		n := uintptr(0)
+		if err := sysctl(mib, nil, &n, nil, 0); err != nil {
+			return nil, err
+		}
+		if n == 0 {
+			return nil, nil
+		}
+		if n%SizeofKinfoProc != 0 {
+			return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
+		}
 
 
-	// Read into buffer of that size.
-	buf := make([]KinfoProc, n/SizeofKinfoProc)
-	if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {
-		return nil, err
-	}
-	if n%SizeofKinfoProc != 0 {
-		return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
-	}
+		// Read into buffer of that size.
+		buf := make([]KinfoProc, n/SizeofKinfoProc)
+		if err := sysctl(mib, (*byte)(unsafe.Pointer(&buf[0])), &n, nil, 0); err != nil {
+			if err == ENOMEM {
+				// Process table grew. Try again.
+				continue
+			}
+			return nil, err
+		}
+		if n%SizeofKinfoProc != 0 {
+			return nil, fmt.Errorf("sysctl() returned a size of %d, which is not a multiple of %d", n, SizeofKinfoProc)
+		}
 
 
-	// The actual call may return less than the original reported required
-	// size so ensure we deal with that.
-	return buf[:n/SizeofKinfoProc], nil
+		// The actual call may return less than the original reported required
+		// size so ensure we deal with that.
+		return buf[:n/SizeofKinfoProc], nil
+	}
 }
 }
 
 
 //sys	sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)
 //sys	sendfile(infd int, outfd int, offset int64, len *int64, hdtr unsafe.Pointer, flags int) (err error)

+ 69 - 19
vendor/golang.org/x/sys/unix/syscall_linux.go

@@ -1699,12 +1699,23 @@ func PtracePokeUser(pid int, addr uintptr, data []byte) (count int, err error) {
 	return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data)
 	return ptracePoke(PTRACE_POKEUSR, PTRACE_PEEKUSR, pid, addr, data)
 }
 }
 
 
+// elfNT_PRSTATUS is a copy of the debug/elf.NT_PRSTATUS constant so
+// x/sys/unix doesn't need to depend on debug/elf and thus
+// compress/zlib, debug/dwarf, and other packages.
+const elfNT_PRSTATUS = 1
+
 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
 func PtraceGetRegs(pid int, regsout *PtraceRegs) (err error) {
-	return ptracePtr(PTRACE_GETREGS, pid, 0, unsafe.Pointer(regsout))
+	var iov Iovec
+	iov.Base = (*byte)(unsafe.Pointer(regsout))
+	iov.SetLen(int(unsafe.Sizeof(*regsout)))
+	return ptracePtr(PTRACE_GETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov))
 }
 }
 
 
 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
 func PtraceSetRegs(pid int, regs *PtraceRegs) (err error) {
-	return ptracePtr(PTRACE_SETREGS, pid, 0, unsafe.Pointer(regs))
+	var iov Iovec
+	iov.Base = (*byte)(unsafe.Pointer(regs))
+	iov.SetLen(int(unsafe.Sizeof(*regs)))
+	return ptracePtr(PTRACE_SETREGSET, pid, uintptr(elfNT_PRSTATUS), unsafe.Pointer(&iov))
 }
 }
 
 
 func PtraceSetOptions(pid int, options int) (err error) {
 func PtraceSetOptions(pid int, options int) (err error) {
@@ -1874,7 +1885,7 @@ func Getpgrp() (pid int) {
 //sys	PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)
 //sys	PerfEventOpen(attr *PerfEventAttr, pid int, cpu int, groupFd int, flags int) (fd int, err error)
 //sys	PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
 //sys	PivotRoot(newroot string, putold string) (err error) = SYS_PIVOT_ROOT
 //sys	Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
 //sys	Prctl(option int, arg2 uintptr, arg3 uintptr, arg4 uintptr, arg5 uintptr) (err error)
-//sys	Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) = SYS_PSELECT6
+//sys	pselect6(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *sigset_argpack) (n int, err error)
 //sys	read(fd int, p []byte) (n int, err error)
 //sys	read(fd int, p []byte) (n int, err error)
 //sys	Removexattr(path string, attr string) (err error)
 //sys	Removexattr(path string, attr string) (err error)
 //sys	Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error)
 //sys	Renameat2(olddirfd int, oldpath string, newdirfd int, newpath string, flags uint) (err error)
@@ -2113,21 +2124,7 @@ func writevRacedetect(iovecs []Iovec, n int) {
 
 
 // mmap varies by architecture; see syscall_linux_*.go.
 // mmap varies by architecture; see syscall_linux_*.go.
 //sys	munmap(addr uintptr, length uintptr) (err error)
 //sys	munmap(addr uintptr, length uintptr) (err error)
-
-var mapper = &mmapper{
-	active: make(map[*byte][]byte),
-	mmap:   mmap,
-	munmap: munmap,
-}
-
-func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) {
-	return mapper.Mmap(fd, offset, length, prot, flags)
-}
-
-func Munmap(b []byte) (err error) {
-	return mapper.Munmap(b)
-}
-
+//sys	mremap(oldaddr uintptr, oldlength uintptr, newlength uintptr, flags int, newaddr uintptr) (xaddr uintptr, err error)
 //sys	Madvise(b []byte, advice int) (err error)
 //sys	Madvise(b []byte, advice int) (err error)
 //sys	Mprotect(b []byte, prot int) (err error)
 //sys	Mprotect(b []byte, prot int) (err error)
 //sys	Mlock(b []byte) (err error)
 //sys	Mlock(b []byte) (err error)
@@ -2136,6 +2133,12 @@ func Munmap(b []byte) (err error) {
 //sys	Munlock(b []byte) (err error)
 //sys	Munlock(b []byte) (err error)
 //sys	Munlockall() (err error)
 //sys	Munlockall() (err error)
 
 
+const (
+	mremapFixed     = MREMAP_FIXED
+	mremapDontunmap = MREMAP_DONTUNMAP
+	mremapMaymove   = MREMAP_MAYMOVE
+)
+
 // Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd,
 // Vmsplice splices user pages from a slice of Iovecs into a pipe specified by fd,
 // using the specified flags.
 // using the specified flags.
 func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
 func Vmsplice(fd int, iovs []Iovec, flags int) (int, error) {
@@ -2420,6 +2423,54 @@ func PthreadSigmask(how int, set, oldset *Sigset_t) error {
 	return rtSigprocmask(how, set, oldset, _C__NSIG/8)
 	return rtSigprocmask(how, set, oldset, _C__NSIG/8)
 }
 }
 
 
+//sysnb	getresuid(ruid *_C_int, euid *_C_int, suid *_C_int)
+//sysnb	getresgid(rgid *_C_int, egid *_C_int, sgid *_C_int)
+
+func Getresuid() (ruid, euid, suid int) {
+	var r, e, s _C_int
+	getresuid(&r, &e, &s)
+	return int(r), int(e), int(s)
+}
+
+func Getresgid() (rgid, egid, sgid int) {
+	var r, e, s _C_int
+	getresgid(&r, &e, &s)
+	return int(r), int(e), int(s)
+}
+
+// Pselect is a wrapper around the Linux pselect6 system call.
+// This version does not modify the timeout argument.
+func Pselect(nfd int, r *FdSet, w *FdSet, e *FdSet, timeout *Timespec, sigmask *Sigset_t) (n int, err error) {
+	// Per https://man7.org/linux/man-pages/man2/select.2.html#NOTES,
+	// The Linux pselect6() system call modifies its timeout argument.
+	// [Not modifying the argument] is the behavior required by POSIX.1-2001.
+	var mutableTimeout *Timespec
+	if timeout != nil {
+		mutableTimeout = new(Timespec)
+		*mutableTimeout = *timeout
+	}
+
+	// The final argument of the pselect6() system call is not a
+	// sigset_t * pointer, but is instead a structure
+	var kernelMask *sigset_argpack
+	if sigmask != nil {
+		wordBits := 32 << (^uintptr(0) >> 63) // see math.intSize
+
+		// A sigset stores one bit per signal,
+		// offset by 1 (because signal 0 does not exist).
+		// So the number of words needed is ⌈__C_NSIG - 1 / wordBits⌉.
+		sigsetWords := (_C__NSIG - 1 + wordBits - 1) / (wordBits)
+
+		sigsetBytes := uintptr(sigsetWords * (wordBits / 8))
+		kernelMask = &sigset_argpack{
+			ss:    sigmask,
+			ssLen: sigsetBytes,
+		}
+	}
+
+	return pselect6(nfd, r, w, e, mutableTimeout, kernelMask)
+}
+
 /*
 /*
  * Unimplemented
  * Unimplemented
  */
  */
@@ -2461,7 +2512,6 @@ func PthreadSigmask(how int, set, oldset *Sigset_t) error {
 // MqTimedreceive
 // MqTimedreceive
 // MqTimedsend
 // MqTimedsend
 // MqUnlink
 // MqUnlink
-// Mremap
 // Msgctl
 // Msgctl
 // Msgget
 // Msgget
 // Msgrcv
 // Msgrcv

Algunos archivos no se mostraron porque demasiados archivos cambiaron en este cambio