Parcourir la source

Implemented harfbuzz based freetype font renderer. (#30)

* Implemented harfbuzz based freetype font renderer.

Introduces support for open type font features, such as kerning,

* Removed unnecessary style.
Brucey il y a 1 an
Parent
commit
5a73cbdd22
100 fichiers modifiés avec 58207 ajouts et 0 suppressions
  1. 56 0
      hbfreetypefont.mod/common.bmx
  2. BIN
      hbfreetypefont.mod/examples/fonts/Vollkorn-Regular.otf
  3. 41 0
      hbfreetypefont.mod/examples/small_caps.bmx
  4. 181 0
      hbfreetypefont.mod/glue.c
  5. 38 0
      hbfreetypefont.mod/harfbuzz/.clang-format
  6. 10 0
      hbfreetypefont.mod/harfbuzz/.codecov.yml
  7. 20 0
      hbfreetypefont.mod/harfbuzz/.editorconfig
  8. 14 0
      hbfreetypefont.mod/harfbuzz/AUTHORS
  9. 32 0
      hbfreetypefont.mod/harfbuzz/BUILD.md
  10. 968 0
      hbfreetypefont.mod/harfbuzz/CMakeLists.txt
  11. 162 0
      hbfreetypefont.mod/harfbuzz/CONFIG.md
  12. 42 0
      hbfreetypefont.mod/harfbuzz/COPYING
  13. 3468 0
      hbfreetypefont.mod/harfbuzz/NEWS
  14. 1 0
      hbfreetypefont.mod/harfbuzz/README
  15. 104 0
      hbfreetypefont.mod/harfbuzz/README.md
  16. 35 0
      hbfreetypefont.mod/harfbuzz/README.python.md
  17. 37 0
      hbfreetypefont.mod/harfbuzz/RELEASING.md
  18. 20 0
      hbfreetypefont.mod/harfbuzz/SECURITY.md
  19. 47 0
      hbfreetypefont.mod/harfbuzz/TESTING.md
  20. 7 0
      hbfreetypefont.mod/harfbuzz/THANKS
  21. BIN
      hbfreetypefont.mod/harfbuzz/docs/HarfBuzz.png
  22. 2 0
      hbfreetypefont.mod/harfbuzz/docs/HarfBuzz.svg
  23. 259 0
      hbfreetypefont.mod/harfbuzz/docs/features.dot
  24. 226 0
      hbfreetypefont.mod/harfbuzz/docs/harfbuzz-docs.xml
  25. 0 0
      hbfreetypefont.mod/harfbuzz/docs/harfbuzz-overrides.txt
  26. 928 0
      hbfreetypefont.mod/harfbuzz/docs/harfbuzz-sections.txt
  27. 65 0
      hbfreetypefont.mod/harfbuzz/docs/meson.build
  28. 294 0
      hbfreetypefont.mod/harfbuzz/docs/repacker.md
  29. 178 0
      hbfreetypefont.mod/harfbuzz/docs/serializer.md
  30. 228 0
      hbfreetypefont.mod/harfbuzz/docs/subset-preprocessing.md
  31. 412 0
      hbfreetypefont.mod/harfbuzz/docs/usermanual-buffers-language-script-and-direction.xml
  32. 701 0
      hbfreetypefont.mod/harfbuzz/docs/usermanual-clusters.xml
  33. 518 0
      hbfreetypefont.mod/harfbuzz/docs/usermanual-fonts-and-faces.xml
  34. 316 0
      hbfreetypefont.mod/harfbuzz/docs/usermanual-getting-started.xml
  35. 14 0
      hbfreetypefont.mod/harfbuzz/docs/usermanual-glyph-information.xml
  36. 349 0
      hbfreetypefont.mod/harfbuzz/docs/usermanual-install-harfbuzz.xml
  37. 647 0
      hbfreetypefont.mod/harfbuzz/docs/usermanual-integration.xml
  38. 266 0
      hbfreetypefont.mod/harfbuzz/docs/usermanual-object-model.xml
  39. 336 0
      hbfreetypefont.mod/harfbuzz/docs/usermanual-opentype-features.xml
  40. 368 0
      hbfreetypefont.mod/harfbuzz/docs/usermanual-shaping-concepts.xml
  41. 218 0
      hbfreetypefont.mod/harfbuzz/docs/usermanual-utilities.xml
  42. 441 0
      hbfreetypefont.mod/harfbuzz/docs/usermanual-what-is-harfbuzz.xml
  43. 1 0
      hbfreetypefont.mod/harfbuzz/docs/version.xml.in
  44. 544 0
      hbfreetypefont.mod/harfbuzz/docs/wasm-shaper.md
  45. 24 0
      hbfreetypefont.mod/harfbuzz/harfbuzz.doap
  46. 511 0
      hbfreetypefont.mod/harfbuzz/meson.build
  47. 52 0
      hbfreetypefont.mod/harfbuzz/meson_options.txt
  48. 54 0
      hbfreetypefont.mod/harfbuzz/perf/README.md
  49. 319 0
      hbfreetypefont.mod/harfbuzz/perf/benchmark-font.cc
  50. 110 0
      hbfreetypefont.mod/harfbuzz/perf/benchmark-map.cc
  51. 44 0
      hbfreetypefont.mod/harfbuzz/perf/benchmark-ot.cc
  52. 151 0
      hbfreetypefont.mod/harfbuzz/perf/benchmark-set.cc
  53. 180 0
      hbfreetypefont.mod/harfbuzz/perf/benchmark-shape.cc
  54. 287 0
      hbfreetypefont.mod/harfbuzz/perf/benchmark-subset.cc
  55. BIN
      hbfreetypefont.mod/harfbuzz/perf/fonts/Amiri-Regular.ttf
  56. BIN
      hbfreetypefont.mod/harfbuzz/perf/fonts/NotoNastaliqUrdu-Regular.ttf
  57. BIN
      hbfreetypefont.mod/harfbuzz/perf/fonts/Roboto-Regular.ttf
  58. 62 0
      hbfreetypefont.mod/harfbuzz/perf/meson.build
  59. 6 0
      hbfreetypefont.mod/harfbuzz/perf/texts/duployan.txt
  60. 1893 0
      hbfreetypefont.mod/harfbuzz/perf/texts/en-thelittleprince.txt
  61. 12391 0
      hbfreetypefont.mod/harfbuzz/perf/texts/en-words.txt
  62. 133 0
      hbfreetypefont.mod/harfbuzz/perf/texts/fa-thelittleprince.txt
  63. 10000 0
      hbfreetypefont.mod/harfbuzz/perf/texts/fa-words.txt
  64. 10000 0
      hbfreetypefont.mod/harfbuzz/perf/texts/hi-words.txt
  65. 21 0
      hbfreetypefont.mod/harfbuzz/replace-enum-strings.cmake
  66. 250 0
      hbfreetypefont.mod/harfbuzz/src/ArabicPUASimplified.txt
  67. 295 0
      hbfreetypefont.mod/harfbuzz/src/ArabicPUATraditional.txt
  68. 1031 0
      hbfreetypefont.mod/harfbuzz/src/OT/Color/CBDT/CBDT.hh
  69. 2745 0
      hbfreetypefont.mod/harfbuzz/src/OT/Color/COLR/COLR.hh
  70. 137 0
      hbfreetypefont.mod/harfbuzz/src/OT/Color/COLR/colrv1-closure.hh
  71. 358 0
      hbfreetypefont.mod/harfbuzz/src/OT/Color/CPAL/CPAL.hh
  72. 448 0
      hbfreetypefont.mod/harfbuzz/src/OT/Color/sbix/sbix.hh
  73. 152 0
      hbfreetypefont.mod/harfbuzz/src/OT/Color/svg/svg.hh
  74. 352 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/Common/Coverage.hh
  75. 133 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh
  76. 239 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh
  77. 97 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/Common/RangeRecord.hh
  78. 1044 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GDEF/GDEF.hh
  79. 84 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/Anchor.hh
  80. 46 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/AnchorFormat1.hh
  81. 58 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/AnchorFormat2.hh
  82. 120 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh
  83. 87 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh
  84. 14 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/ChainContextPos.hh
  85. 33 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/Common.hh
  86. 14 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/ContextPos.hh
  87. 35 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/CursivePos.hh
  88. 311 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh
  89. 17 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/ExtensionPos.hh
  90. 171 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/GPOS.hh
  91. 57 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh
  92. 128 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh
  93. 41 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh
  94. 243 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh
  95. 41 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh
  96. 224 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh
  97. 42 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh
  98. 231 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh
  99. 51 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkRecord.hh
  100. 46 0
      hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/PairPos.hh

+ 56 - 0
hbfreetypefont.mod/common.bmx

@@ -0,0 +1,56 @@
+' Copyright (c) 2024 Bruce A Henderson
+' 
+' 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.
+' 
+SuperStrict
+
+
+Import Brl.FreeTypeFont
+Import Brl.Collections
+Import "source.bmx"
+
+Extern
+
+	Function bmx_hb_ft_font_create:Byte Ptr(ftface:Byte Ptr)
+	Function bmx_hb_ft_font_destroy(font:Byte Ptr)
+	Function bmx_hb_ft_font_features:Byte Ptr(style:Int, length:Int Var)
+	Function bmx_hb_buffer_create:Byte Ptr()
+	Function bmx_hb_buffer_destroy(buffer:Byte Ptr)
+	Function bmx_hb_buffer_calc_glyph_info(font:Byte Ptr, buffer:Byte Ptr, features:Byte Ptr, featuresLength:Int, char:Int, glyphInfo:SGlyphPosition Var)
+	Function bmx_hb_features_destroy(features:Byte Ptr)
+
+	Function bmx_hb_buffer_calc_glyphs_info:SGlyphPosition Ptr(font:Byte Ptr, buffer:Byte Ptr, features:Byte Ptr, featuresLength:Int, text:String, length:Int Var)
+	Function bmx_hb_buffer_calc_glyphs_info_destroy(glyphs:SGlyphPosition Ptr)
+End Extern
+
+Struct SGlyphPosition
+	Field glyphIndex:Int
+	Field xAdvance:Int
+	Field yAdvance:Int
+	Field xOffset:Int
+	Field yOffset:Int
+
+	Method Operator=:Int(rhs:SGlyphPosition)
+		Return glyphIndex = rhs.glyphIndex And ..
+			xAdvance = rhs.xAdvance And ..
+			yAdvance = rhs.yAdvance And ..
+			xOffset = rhs.xOffset And ..
+			yOffset = rhs.yOffset
+	End Method
+End Struct

BIN
hbfreetypefont.mod/examples/fonts/Vollkorn-Regular.otf


+ 41 - 0
hbfreetypefont.mod/examples/small_caps.bmx

@@ -0,0 +1,41 @@
+SuperStrict
+
+Framework sdl.sdlrendermax2d
+Import Text.HBFreeTypeFont
+
+Graphics 1024, 768, 0
+
+Local font:TImageFont = LoadImageFont( "fonts/Vollkorn-Regular.otf", 72, SMOOTHFONT )
+Local linfont:TImageFont = LoadImageFont( "fonts/Vollkorn-Regular.otf", 72, SMOOTHFONT | LININGFIGURESFONT )
+Local scfont:TImageFont = LoadImageFont( "fonts/Vollkorn-Regular.otf", 72, SMOOTHFONT | SMALLCAPSFONT )
+Local kfont:TImageFont = LoadImageFont( "fonts/Vollkorn-Regular.otf", 72, SMOOTHFONT | KERNFONT )
+Local kscfont:TImageFont = LoadImageFont( "fonts/Vollkorn-Regular.otf", 72, SMOOTHFONT | KERNFONT | SMALLCAPSFONT | ZEROFONT )
+
+While Not KeyDown( Key_Escape )
+
+	Cls
+
+	SetImageFont font
+
+	DrawText "Hello World 0123456789", 100, 100
+
+	SetImageFont linfont
+
+	DrawText "Hello World 0123456789", 100, 180
+
+	SetImageFont scfont
+
+	DrawText "Hello World 0123456789", 100, 260
+
+	SetImageFont kfont
+
+	DrawText "Hello World 0123456789", 100, 340
+
+	SetImageFont kscfont
+
+	DrawText "Hello World 0123456789", 100, 420
+
+	Flip
+
+Wend
+

+ 181 - 0
hbfreetypefont.mod/glue.c

@@ -0,0 +1,181 @@
+/*
+  Copyright (c) 2024 Bruce A Henderson
+ 
+  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.
+*/ 
+
+#include <hb-ft.h>
+#include "brl.mod/blitz.mod/blitz.h"
+
+#define SMALLCAPSFONT 0x100
+#define ALLSMALLCAPSFONT 0x200
+#define LIGATURESFONT 0x400
+#define DISCRETIONARY_LIGATURESFONT 0x800
+#define OLDSTYLEFIGURESFONT 0x1000
+#define TABULARFIGURESFONT 0x2000
+#define FRACTIONSFONT 0x4000
+#define SUPERSCRIPTFONT 0x8000
+#define SUBSCRIPTFONT 0x10000
+#define SWASHESFONT 0x20000
+#define STYLISTICALTERNATESFONT 0x40000
+#define CONTEXTUALALTERNATESFONT 0x80000
+#define HISTORICALFORMSFONT 0x100000
+#define DENOMINATORSFONT 0x200000
+#define NUMERATORFONT 0x400000
+#define LININGFIGURESFONT 0x800000
+#define SCIENTIFICINFERIORSFONT 0x1000000
+#define PROPORTIONALFIGURESFONT 0x2000000
+#define KERNFONT 0x4000000
+#define ZEROFONT 0x8000000
+
+struct {
+        int flag;
+        hb_feature_t feature;
+} style_features[] = {
+        {LIGATURESFONT, {HB_TAG('l', 'i', 'g', 'a'), 1, 0, (unsigned int)-1}},
+        {DISCRETIONARY_LIGATURESFONT, {HB_TAG('d', 'l', 'i', 'g'), 1, 0, (unsigned int)-1}},
+        {SMALLCAPSFONT, {HB_TAG('s', 'm', 'c', 'p'), 1, 0, (unsigned int)-1}},
+        {ALLSMALLCAPSFONT, {HB_TAG('c', '2', 's', 'c'), 1, 0, (unsigned int)-1}},
+        {OLDSTYLEFIGURESFONT, {HB_TAG('o', 'n', 'u', 'm'), 1, 0, (unsigned int)-1}},
+        {TABULARFIGURESFONT, {HB_TAG('t', 'n', 'u', 'm'), 1, 0, (unsigned int)-1}},
+        {FRACTIONSFONT, {HB_TAG('f', 'r', 'a', 'c'), 1, 0, (unsigned int)-1}},
+        {SUPERSCRIPTFONT, {HB_TAG('s', 'u', 'p', 's'), 1, 0, (unsigned int)-1}},
+        {SUBSCRIPTFONT, {HB_TAG('s', 'u', 'b', 's'), 1, 0, (unsigned int)-1}},
+        {SWASHESFONT, {HB_TAG('s', 'w', 's', 'h'), 1, 0, (unsigned int)-1}},
+        {STYLISTICALTERNATESFONT, {HB_TAG('s', 'a', 'l', 't'), 1, 0, (unsigned int)-1}},
+        {CONTEXTUALALTERNATESFONT, {HB_TAG('c', 'a', 'l', 't'), 1, 0, (unsigned int)-1}},
+        {HISTORICALFORMSFONT, {HB_TAG('h', 'i', 's', 't'), 1, 0, (unsigned int)-1}},
+        {DENOMINATORSFONT, {HB_TAG('d', 'n', 'o', 'm'), 1, 0, (unsigned int)-1}},
+        {NUMERATORFONT, {HB_TAG('n', 'u', 'm', 'r'), 1, 0, (unsigned int)-1}},
+        {LININGFIGURESFONT, {HB_TAG('l', 'n', 'u', 'm'), 1, 0, (unsigned int)-1}},
+        {SCIENTIFICINFERIORSFONT, {HB_TAG('s', 'i', 'n', 'f'), 1, 0, (unsigned int)-1}},
+        {PROPORTIONALFIGURESFONT, {HB_TAG('p', 'n', 'u', 'm'), 1, 0, (unsigned int)-1}},
+        {KERNFONT, {HB_TAG('k', 'e', 'r', 'n'), 1, 0, (unsigned int)-1}},
+        {ZEROFONT, {HB_TAG('z', 'e', 'r', 'o'), 1, 0, (unsigned int)-1}}
+};
+static int num_styles = sizeof(style_features) / sizeof(style_features[0]);
+
+typedef struct {
+    int glyphIndex;
+    int x_advance;
+    int y_advance;
+    int x_offset;
+    int y_offset;
+} MaxGlyphInfo;
+
+hb_font_t * bmx_hb_ft_font_create(FT_Face ft_face) {
+    return hb_ft_font_create(ft_face, NULL);
+}
+
+void bmx_hb_ft_font_destroy(hb_font_t * font) {
+    hb_font_destroy(font);
+}
+
+hb_feature_t * bmx_hb_ft_font_features( int style, int * length ) {
+    int count = 0;
+
+    for (int i = 0; i < num_styles; ++i) {
+        if (style & style_features[i].flag) {
+            ++count;
+        }
+    }
+
+    // If no styles are enabled, return NULL
+    if (count == 0) {
+        *length = 0;
+        return NULL;
+    }
+
+    // Allocate memory for the features array
+    hb_feature_t* features = (hb_feature_t*)malloc(count * sizeof(hb_feature_t));
+    if (!features) {
+        *length = 0;
+        return NULL;
+    }
+
+    // Populate the features array with the enabled features
+    int index = 0;
+    for (int i = 0; i < num_styles; ++i) {
+        if (style & style_features[i].flag) {
+            features[index++] = style_features[i].feature;
+        }
+    }
+
+    *length = count;
+    return features;
+}
+
+hb_buffer_t * bmx_hb_buffer_create() {
+    hb_buffer_t * buffer = hb_buffer_create();
+    return buffer;
+}
+
+void bmx_hb_buffer_destroy(hb_buffer_t * buffer) {
+    hb_buffer_destroy(buffer);
+}
+
+void bmx_hb_features_destroy(hb_feature_t * features) {
+    free(features);
+}
+
+void bmx_hb_buffer_calc_glyph_info(hb_font_t * font, hb_buffer_t * buffer, hb_feature_t * features, int featuresLength, int character, MaxGlyphInfo * glyphInfo) {
+    hb_buffer_clear_contents(buffer);
+    hb_buffer_add(buffer, character, 0);
+    hb_buffer_guess_segment_properties(buffer);
+
+    hb_shape(font, buffer, featuresLength > 0 ? features : NULL, featuresLength);
+
+    hb_glyph_info_t * infos = hb_buffer_get_glyph_infos(buffer, NULL);
+    hb_glyph_position_t * positions = hb_buffer_get_glyph_positions(buffer, NULL);
+
+    glyphInfo->glyphIndex = infos[0].codepoint;
+    glyphInfo->x_advance = positions[0].x_advance;
+    glyphInfo->y_advance = positions[0].y_advance;
+    glyphInfo->x_offset = positions[0].x_offset;
+    glyphInfo->y_offset = positions[0].y_offset;
+}
+
+MaxGlyphInfo * bmx_hb_buffer_calc_glyphs_info(hb_font_t * font, hb_buffer_t * buffer, hb_feature_t * features, int featuresLength, BBString * text, int * length) {
+    hb_buffer_clear_contents(buffer);
+    hb_buffer_add_utf16(buffer, text->buf, text->length, 0, text->length);
+    hb_buffer_guess_segment_properties(buffer);
+
+    hb_shape(font, buffer, featuresLength > 0 ? features : NULL, featuresLength);
+
+    int count = hb_buffer_get_length(buffer);
+    hb_glyph_info_t * infos = hb_buffer_get_glyph_infos(buffer, NULL);
+    hb_glyph_position_t * positions = hb_buffer_get_glyph_positions(buffer, NULL);
+
+    *length = count;
+    MaxGlyphInfo * glyphInfo = (MaxGlyphInfo*)malloc(count * sizeof(MaxGlyphInfo));
+
+    for (int i = 0; i < count; ++i) {
+        glyphInfo[i].glyphIndex = infos[i].codepoint;
+        glyphInfo[i].x_advance = positions[i].x_advance;
+        glyphInfo[i].y_advance = positions[i].y_advance;
+        glyphInfo[i].x_offset = positions[i].x_offset;
+        glyphInfo[i].y_offset = positions[i].y_offset;
+    }
+
+    return glyphInfo;
+}
+
+void bmx_hb_buffer_calc_glyphs_info_destroy(MaxGlyphInfo * glyphInfo) {
+    free(glyphInfo);
+}

+ 38 - 0
hbfreetypefont.mod/harfbuzz/.clang-format

@@ -0,0 +1,38 @@
+# The following tries to match the current code style, is imperfect for now
+# but good for new codes be added
+
+IndentWidth: 2
+TabWidth: 8
+UseTab: Always
+SpaceBeforeParens: Always
+AllowShortLoopsOnASingleLine: true
+BreakBeforeBraces: Custom
+BraceWrapping:
+  AfterEnum: true
+  AfterStruct: false
+  SplitEmptyFunction: false
+  AfterClass: true
+  AfterControlStatement: true
+  AfterEnum: false
+  AfterFunction: true
+  AfterNamespace: false
+  AfterStruct: true
+  AfterUnion: true
+  BeforeElse: true
+AlwaysBreakTemplateDeclarations: true
+AlignTrailingComments: true
+AlignEscapedNewlines: Left
+AllowShortBlocksOnASingleLine: true
+SpaceAfterCStyleCast: true
+AlwaysBreakAfterDefinitionReturnType: TopLevel
+BinPackParameters: false
+AllowShortFunctionsOnASingleLine: Inline
+AccessModifierOffset: 0
+AlignTrailingComments: true
+AllowShortIfStatementsOnASingleLine: true
+AlignAfterOpenBracket: Align
+AlignOperands: true
+AllowShortCaseLabelsOnASingleLine: true
+
+# We like to have this only for function parameters and structs fields, not always
+# AlignConsecutiveDeclarations: true

+ 10 - 0
hbfreetypefont.mod/harfbuzz/.codecov.yml

@@ -0,0 +1,10 @@
+comment: false
+
+coverage:
+  status:
+    project:
+      default:
+        informational: true
+    patch:
+      default:
+        informational: true

+ 20 - 0
hbfreetypefont.mod/harfbuzz/.editorconfig

@@ -0,0 +1,20 @@
+root = true
+
+[*]
+charset = utf-8
+trim_trailing_whitespace = true
+end_of_line = lf
+insert_final_newline = true
+
+[*.{c,cc,h,hh,rl}]
+tab_width = 8
+indent_size = 2
+indent_style = tab
+
+[*.{py,sh}]
+indent_style = tab
+
+[{meson.build,meson_options.txt}]
+tab_width = 8
+indent_style = space
+indent_size = 2

+ 14 - 0
hbfreetypefont.mod/harfbuzz/AUTHORS

@@ -0,0 +1,14 @@
+Behdad Esfahbod
+David Corbett
+David Turner
+Ebrahim Byagowi
+Garret Rieger
+Jonathan Kew
+Khaled Hosny
+Lars Knoll
+Martin Hosken
+Owen Taylor
+Roderick Sheeter
+Roozbeh Pournader
+Simon Hausmann
+Werner Lemberg

+ 32 - 0
hbfreetypefont.mod/harfbuzz/BUILD.md

@@ -0,0 +1,32 @@
+On Linux, install the development packages for FreeType, Cairo, and GLib. For
+example, on Ubuntu / Debian, you would do:
+
+    $ sudo apt-get install meson pkg-config ragel gtk-doc-tools gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev
+
+whereas on Fedora, RHEL, CentOS, and other Red Hat based systems you would do:
+
+    $ sudo dnf install meson pkgconfig gtk-doc gcc gcc-c++ freetype-devel glib2-devel cairo-devel
+
+and on ArchLinux and Manjaro:
+
+    $ sudo pacman -Suy meson pkg-config ragel gcc freetype2 glib2 glib2-devel cairo
+
+On macOS:
+
+    brew install pkg-config ragel gtk-doc freetype glib cairo meson
+
+Then use meson to build the project and run the tests, like:
+
+    meson build && ninja -Cbuild && meson test -Cbuild
+
+On Windows, meson can build the project like above if a working MSVC's cl.exe
+(`vcvarsall.bat`) or gcc/clang is already on your path, and if you use
+something like `meson build --wrap-mode=default` it fetches and compiles most
+of the dependencies also.  It is recommended to install CMake either manually
+or via the Visual Studio installer when building with MSVC, using meson.
+
+Our CI configurations are also a good source of learning how to build HarfBuzz.
+
+There is also amalgamated source provided with HarfBuzz which reduces whole process
+of building HarfBuzz to `g++ src/harfbuzz.cc -fno-exceptions` but there is
+no guarantee provided with buildability and reliability of features you get.

+ 968 - 0
hbfreetypefont.mod/harfbuzz/CMakeLists.txt

@@ -0,0 +1,968 @@
+cmake_minimum_required(VERSION 3.12)
+project(harfbuzz)
+
+message(WARN "HarfBuzz has a Meson port and tries to migrate all the other build systems to it, please consider using it as we might remove our cmake port soon.")
+
+set(CMAKE_CXX_STANDARD 11)
+set(CMAKE_CXX_STANDARD_REQUIRED ON)
+
+## Limit framework build to Xcode generator
+if (BUILD_FRAMEWORK)
+  # for a framework build on macOS, use:
+  # cmake -DBUILD_FRAMEWORK=ON -Bbuild -H. -GXcode && cmake --build build
+  if (NOT "${CMAKE_GENERATOR}" STREQUAL "Xcode")
+    message(FATAL_ERROR
+      "You should use Xcode generator with BUILD_FRAMEWORK enabled")
+  endif ()
+  set (CMAKE_OSX_ARCHITECTURES "$(ARCHS_STANDARD_32_64_BIT)")
+  set (CMAKE_MACOSX_RPATH ON)
+  set (BUILD_SHARED_LIBS ON)
+endif ()
+
+
+## Disallow in-source builds, as CMake generated make files can collide with autotools ones
+if (NOT MSVC AND "${PROJECT_BINARY_DIR}" STREQUAL "${PROJECT_SOURCE_DIR}")
+  message(FATAL_ERROR
+    "
+In-source builds are not permitted!  Make a separate folder for"
+    " building, e.g.,"
+    "
+  mkdir build; cd build; cmake .."
+    "
+Before that, remove the files created by this failed run with"
+    "
+  rm -rf CMakeCache.txt CMakeFiles")
+endif ()
+
+
+## HarfBuzz build configurations
+option(HB_HAVE_CAIRO "Enable cairo interop helpers" OFF)
+option(HB_HAVE_FREETYPE "Enable freetype interop helpers" OFF)
+option(HB_HAVE_GRAPHITE2 "Enable Graphite2 complementary shaper" OFF)
+option(HB_HAVE_GLIB "Enable glib unicode functions" OFF)
+option(HB_HAVE_ICU "Enable icu unicode functions" OFF)
+if (TARGET freetype)
+  set (HB_HAVE_FREETYPE ON)
+  add_definitions(-DHAVE_FREETYPE=1)
+endif ()
+if (APPLE)
+  option(HB_HAVE_CORETEXT "Enable CoreText shaper backend on macOS" ON)
+  set (CMAKE_MACOSX_RPATH ON)
+endif ()
+if (WIN32)
+  option(HB_HAVE_UNISCRIBE "Enable Uniscribe shaper backend on Windows" OFF)
+  option(HB_HAVE_GDI "Enable GDI integration helpers on Windows" OFF)
+  option(HB_HAVE_DIRECTWRITE "Enable DirectWrite shaper backend on Windows" OFF)
+endif ()
+option(HB_BUILD_UTILS "Build harfbuzz utils, needs cairo, freetype, and glib properly be installed" OFF)
+if (HB_BUILD_UTILS)
+  set (HB_HAVE_GLIB ON)
+  set (HB_HAVE_FREETYPE ON)
+endif ()
+
+option(HB_BUILD_SUBSET "Build harfbuzz-subset" ON)
+
+option(HB_HAVE_GOBJECT "Enable GObject Bindings" OFF)
+if (HB_HAVE_GOBJECT)
+  set (HB_HAVE_GLIB ON)
+endif ()
+
+option(HB_HAVE_INTROSPECTION "Enable building introspection (.gir/.typelib) files" OFF)
+if (HB_HAVE_INTROSPECTION)
+  set (HB_HAVE_GOBJECT ON)
+  set (HB_HAVE_GLIB ON)
+endif ()
+
+include_directories(AFTER
+  ${PROJECT_SOURCE_DIR}/src
+  ${PROJECT_BINARY_DIR}/src
+)
+
+# We need Python3_EXECUTABLE to be set for running the tests...
+find_package(Python3 COMPONENTS Interpreter)
+
+## Functions and headers
+include (CheckFunctionExists)
+include (CheckIncludeFile)
+include (CheckIncludeFiles)
+macro (check_funcs) # Similar to AC_CHECK_FUNCS of autotools
+  foreach (func_name ${ARGN})
+    string(TOUPPER ${func_name} definition_to_add)
+    check_function_exists(${func_name} HAVE_${definition_to_add})
+    if (${HAVE_${definition_to_add}})
+      add_definitions(-DHAVE_${definition_to_add})
+    endif ()
+  endforeach ()
+endmacro ()
+if (UNIX)
+  list(APPEND CMAKE_REQUIRED_LIBRARIES m)
+endif ()
+check_funcs(atexit mprotect sysconf getpagesize mmap isatty)
+check_include_file(unistd.h HAVE_UNISTD_H)
+if (${HAVE_UNISTD_H})
+  add_definitions(-DHAVE_UNISTD_H)
+endif ()
+check_include_file(sys/mman.h HAVE_SYS_MMAN_H)
+if (${HAVE_SYS_MMAN_H})
+  add_definitions(-DHAVE_SYS_MMAN_H)
+endif ()
+check_include_file(stdbool.h HAVE_STDBOOL_H)
+if (${HAVE_STDBOOL_H})
+  add_definitions(-DHAVE_STDBOOL_H)
+endif ()
+
+# These will be used while making pkg-config .pc files
+set(PC_REQUIRES_PRIV "")
+set(PC_LIBS_PRIV "")
+
+if (NOT MSVC)
+  set(THREADS_PREFER_PTHREAD_FLAG ON)
+  find_package(Threads)
+  if (CMAKE_USE_PTHREADS_INIT)
+    add_definitions("-DHAVE_PTHREAD")
+    list(APPEND THIRD_PARTY_LIBS Threads::Threads)
+    list(APPEND PC_LIBS_PRIV -pthread)
+  endif ()
+endif ()
+
+if (MSVC)
+  add_definitions(-wd4244 -wd4267 -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_WARNINGS)
+  add_definitions(-bigobj)
+endif ()
+
+
+## Detect if we are running inside a distribution or regular repository folder
+# if (EXISTS "${PROJECT_SOURCE_DIR}/ChangeLog")
+#   # perhaps we are on dist directory
+#   set (IN_HB_DIST TRUE)
+#   #set (HB_VERSION_H "${PROJECT_SOURCE_DIR}/src/hb-version.h")
+# endif ()
+
+file(READ meson.build MESONBUILD)
+string(REGEX MATCH "version: '(([0-9]+)\\.([0-9]+)\\.([0-9]+))'," HB_VERSION_MATCH ${MESONBUILD})
+set (HB_VERSION ${CMAKE_MATCH_1})
+set (HB_VERSION_MAJOR ${CMAKE_MATCH_2})
+set (HB_VERSION_MINOR ${CMAKE_MATCH_3})
+set (HB_VERSION_MICRO ${CMAKE_MATCH_4})
+
+## Define sources and headers of the project
+set (project_sources ${PROJECT_SOURCE_DIR}/src/harfbuzz.cc) # use amalgam source
+set (subset_project_sources
+     ${PROJECT_SOURCE_DIR}/src/hb-number.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-number.hh
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-cff1-table.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-cff2-table.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-post-table-v2subset.hh
+     ${PROJECT_SOURCE_DIR}/src/hb-static.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-cff-common.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-cff-common.hh
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-cff1.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-cff2.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-input.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-input.hh
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-instancer-iup.hh
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-instancer-iup.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-instancer-solver.hh
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-instancer-solver.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-accelerator.hh
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-plan.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-plan.hh
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-plan-member-list.hh
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-repacker.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-subset.cc
+     ${PROJECT_SOURCE_DIR}/src/hb-subset.hh
+     ${PROJECT_SOURCE_DIR}/src/hb-repacker.hh
+     ${PROJECT_SOURCE_DIR}/src/graph/graph.hh
+     ${PROJECT_SOURCE_DIR}/src/graph/gsubgpos-graph.hh
+     ${PROJECT_SOURCE_DIR}/src/graph/gsubgpos-context.hh
+     ${PROJECT_SOURCE_DIR}/src/graph/gsubgpos-context.cc
+     ${PROJECT_SOURCE_DIR}/src/graph/coverage-graph.hh
+     ${PROJECT_SOURCE_DIR}/src/graph/classdef-graph.hh
+     ${PROJECT_SOURCE_DIR}/src/graph/pairpos-graph.hh
+     ${PROJECT_SOURCE_DIR}/src/graph/markbasepos-graph.hh
+     ${PROJECT_SOURCE_DIR}/src/graph/split-helpers.hh
+     ${PROJECT_SOURCE_DIR}/src/graph/serialize.hh
+     ${PROJECT_SOURCE_DIR}/src/OT/Color/COLR/colrv1-closure.hh
+)
+set (project_extra_sources)
+set (project_headers
+     ${PROJECT_SOURCE_DIR}/src/hb-aat-layout.h
+     ${PROJECT_SOURCE_DIR}/src/hb-aat.h
+     ${PROJECT_SOURCE_DIR}/src/hb-blob.h
+     ${PROJECT_SOURCE_DIR}/src/hb-buffer.h
+     ${PROJECT_SOURCE_DIR}/src/hb-common.h
+     ${PROJECT_SOURCE_DIR}/src/hb-cplusplus.hh
+     ${PROJECT_SOURCE_DIR}/src/hb-deprecated.h
+     ${PROJECT_SOURCE_DIR}/src/hb-draw.h
+     ${PROJECT_SOURCE_DIR}/src/hb-face.h
+     ${PROJECT_SOURCE_DIR}/src/hb-font.h
+     ${PROJECT_SOURCE_DIR}/src/hb-map.h
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-color.h
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-deprecated.h
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-font.h
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-layout.h
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-math.h
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-meta.h
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-metrics.h
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-name.h
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-shape.h
+     ${PROJECT_SOURCE_DIR}/src/hb-ot-var.h
+     ${PROJECT_SOURCE_DIR}/src/hb-ot.h
+     ${PROJECT_SOURCE_DIR}/src/hb-paint.h
+     ${PROJECT_SOURCE_DIR}/src/hb-set.h
+     ${PROJECT_SOURCE_DIR}/src/hb-shape-plan.h
+     ${PROJECT_SOURCE_DIR}/src/hb-shape.h
+     ${PROJECT_SOURCE_DIR}/src/hb-style.h
+     ${PROJECT_SOURCE_DIR}/src/hb-unicode.h
+     ${PROJECT_SOURCE_DIR}/src/hb-version.h
+     ${PROJECT_SOURCE_DIR}/src/hb.h
+)
+set (subset_project_headers
+     ${PROJECT_SOURCE_DIR}/src/hb-subset.h
+     ${PROJECT_SOURCE_DIR}/src/hb-subset-repacker.h
+)
+
+## Find and include needed header folders and libraries
+if (HB_HAVE_FREETYPE AND NOT TARGET freetype)
+  include (FindFreetype)
+  if (NOT FREETYPE_FOUND)
+    message(FATAL_ERROR "HB_HAVE_FREETYPE was set, but we failed to find it. Maybe add a CMAKE_PREFIX_PATH= to your Freetype2 install prefix")
+  endif ()
+
+  list(APPEND THIRD_PARTY_LIBS ${FREETYPE_LIBRARIES})
+  include_directories(AFTER ${FREETYPE_INCLUDE_DIRS})
+  add_definitions(-DHAVE_FREETYPE=1)
+
+  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-ft.h)
+
+  # So check_funcs can find its headers
+  set (CMAKE_REQUIRED_INCLUDES ${CMAKE_REQUIRED_INCLUDES} ${FREETYPE_INCLUDE_DIRS})
+  set (CMAKE_REQUIRED_LIBRARIES ${CMAKE_REQUIRED_LIBRARIES} ${FREETYPE_LIBRARIES})
+
+  check_funcs(FT_Get_Var_Blend_Coordinates FT_Set_Var_Blend_Coordinates FT_Done_MM_Var)
+endif ()
+
+if (HB_HAVE_FREETYPE)
+  list(APPEND PC_REQUIRES_PRIV "freetype2 >= 12.0.6")
+endif ()
+
+if (HB_HAVE_GRAPHITE2)
+  add_definitions(-DHAVE_GRAPHITE2)
+
+  find_path(GRAPHITE2_INCLUDE_DIR graphite2/Font.h)
+  find_library(GRAPHITE2_LIBRARY graphite2)
+
+  include_directories(${GRAPHITE2_INCLUDE_DIR})
+
+  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-graphite2.h)
+
+  list(APPEND THIRD_PARTY_LIBS ${GRAPHITE2_LIBRARY})
+
+  list(APPEND PC_REQUIRES_PRIV "graphite2 >= 1.2.0")
+
+  mark_as_advanced(GRAPHITE2_INCLUDE_DIR GRAPHITE2_LIBRARY)
+endif ()
+
+if (HB_HAVE_GLIB)
+  add_definitions(-DHAVE_GLIB)
+
+  # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindGLIB.cmake
+  find_package(PkgConfig)
+  pkg_check_modules(PC_GLIB QUIET glib-2.0)
+
+  find_library(GLIB_LIBRARIES NAMES glib-2.0 HINTS ${PC_GLIB_LIBDIR} ${PC_GLIB_LIBRARY_DIRS})
+  find_path(GLIBCONFIG_INCLUDE_DIR NAMES glibconfig.h HINTS ${PC_LIBDIR} ${PC_LIBRARY_DIRS} ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0/include)
+  find_path(GLIB_INCLUDE_DIR NAMES glib.h HINTS ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0)
+
+  include_directories(${GLIBCONFIG_INCLUDE_DIR} ${GLIB_INCLUDE_DIR})
+
+  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-glib.h)
+
+  list(APPEND THIRD_PARTY_LIBS ${GLIB_LIBRARIES})
+
+  list(APPEND PC_REQUIRES_PRIV "glib-2.0 >= 2.19.1")
+
+  mark_as_advanced(GLIB_LIBRARIES GLIBCONFIG_INCLUDE_DIR GLIB_INCLUDE_DIR)
+endif ()
+
+if (HB_HAVE_ICU)
+  add_definitions(-DHAVE_ICU)
+
+  find_package(ICU REQUIRED COMPONENTS uc)
+
+  if (ICU_VERSION VERSION_GREATER_EQUAL 75.1)
+    set(CMAKE_CXX_STANDARD 17)
+  endif ()
+
+  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-icu.h)
+
+  list(APPEND THIRD_PARTY_LIBS ICU::uc)
+endif ()
+
+if (APPLE AND HB_HAVE_CORETEXT)
+  # Apple Advanced Typography
+  add_definitions(-DHAVE_CORETEXT)
+
+  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-coretext.h)
+
+  if (HB_IOS)
+    find_library(COREFOUNDATION CoreFoundation)
+    if (COREFOUNDATION)
+      list(APPEND THIRD_PARTY_LIBS ${COREFOUNDATION})
+      list(APPEND PC_LIBS_PRIV "-framework CoreFoundation")
+    endif ()
+    mark_as_advanced(COREFOUNDATION)
+
+    find_library(CORETEXT CoreText)
+    if (CORETEXT)
+      list(APPEND THIRD_PARTY_LIBS ${CORETEXT})
+      list(APPEND PC_LIBS_PRIV "-framework CoreText")
+    endif ()
+    mark_as_advanced(CORETEXT)
+
+    find_library(COREGRAPHICS CoreGraphics)
+    if (COREGRAPHICS)
+      list(APPEND THIRD_PARTY_LIBS ${COREGRAPHICS})
+      list(APPEND PC_LIBS_PRIV "-framework CoreGraphics")
+    endif ()
+    mark_as_advanced(COREGRAPHICS)
+  else ()
+    find_library(APPLICATION_SERVICES_FRAMEWORK ApplicationServices)
+    if (APPLICATION_SERVICES_FRAMEWORK)
+      list(APPEND THIRD_PARTY_LIBS ${APPLICATION_SERVICES_FRAMEWORK})
+      list(APPEND PC_LIBS_PRIV "-framework ApplicationServices")
+    endif ()
+
+    mark_as_advanced(APPLICATION_SERVICES_FRAMEWORK)
+  endif ()
+endif ()
+
+if (WIN32 AND HB_HAVE_GDI)
+  add_definitions(-DHAVE_GDI)
+  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-gdi.h)
+  list(APPEND THIRD_PARTY_LIBS gdi32)
+  list(APPEND PC_LIBS_PRIV -lgdi32)
+endif ()
+
+if (WIN32 AND HB_HAVE_UNISCRIBE)
+  add_definitions(-DHAVE_UNISCRIBE)
+  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-uniscribe.h)
+  list(APPEND THIRD_PARTY_LIBS usp10 gdi32 rpcrt4)
+  list(APPEND PC_LIBS_PRIV -lusp10 -lgdi32 -lrpcrt4)
+endif ()
+
+if (WIN32 AND HB_HAVE_DIRECTWRITE)
+  if (CMAKE_VERSION VERSION_GREATER 3.12)
+    check_include_files("windows.h;dwrite_1.h" HAVE_DWRITE_1_H LANGUAGE CXX)
+  else ()
+    check_include_files("windows.h;dwrite_1.h" HAVE_DWRITE_1_H)
+  endif ()
+  if (NOT HAVE_DWRITE_1_H)
+    message(FATAL_ERROR "DirectWrite was enabled explicitly, but required header is missing")
+  endif ()
+  add_definitions(-DHAVE_DIRECTWRITE)
+  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-directwrite.h)
+endif ()
+
+if (HB_HAVE_CAIRO)
+  # https://github.com/WebKit/webkit/blob/master/Source/cmake/FindCairo.cmake
+  find_package(PkgConfig)
+  pkg_check_modules(PC_CAIRO QUIET cairo)
+
+  find_path(CAIRO_INCLUDE_DIRS NAMES cairo.h HINTS ${PC_CAIRO_INCLUDEDIR} ${PC_CAIRO_INCLUDE_DIRS} PATH_SUFFIXES cairo)
+  find_library(CAIRO_LIBRARIESNAMES cairo HINTS ${PC_CAIRO_LIBDIR} ${PC_CAIRO_LIBRARY_DIRS})
+  if (NOT CAIRO_LIBRARIESNAMES)
+    message(FATAL_ERROR "HB_HAVE_CAIRO is ON but Cairo libraries are not found")
+  endif()
+  include_directories(${CAIRO_INCLUDE_DIRS})
+  mark_as_advanced(CAIRO_INCLUDE_DIRS CAIRO_LIBRARIESNAMES)
+  add_definitions(-DHAVE_CAIRO=1)
+  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-cairo.h)
+  list(APPEND THIRD_PARTY_LIBS ${CAIRO_LIBRARIESNAMES})
+endif()
+
+if (HB_HAVE_GOBJECT)
+  add_definitions(-DHAVE_GOBJECT)
+  include (FindPerl)
+
+  # Use the hints from glib-2.0.pc to find glib-mkenums
+  find_package(PkgConfig)
+  pkg_check_modules(PC_GLIB QUIET glib-2.0)
+  find_program(GLIB_MKENUMS glib-mkenums
+    HINTS ${PC_glib_mkenums}
+  )
+  set (GLIB_MKENUMS_CMD)
+
+  if (WIN32 AND NOT MINGW)
+    # In Visual Studio builds, shebang lines are not supported
+    # in the standard cmd.exe shell that we use, so we need to
+    # first determine whether glib-mkenums is a Python or PERL
+    # script
+    execute_process(COMMAND "${Python3_EXECUTABLE}" "${GLIB_MKENUMS}" --version
+      RESULT_VARIABLE GLIB_MKENUMS_PYTHON
+      OUTPUT_QUIET ERROR_QUIET
+    )
+    if (GLIB_MKENUMS_PYTHON EQUAL 0)
+      message("${GLIB_MKENUMS} is a Python script.")
+      set (GLIB_MKENUMS_CMD "${Python3_EXECUTABLE}" "${GLIB_MKENUMS}")
+    else ()
+      execute_process(COMMAND "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}" --version
+        RESULT_VARIABLE GLIB_MKENUMS_PERL
+        OUTPUT_QUIET ERROR_QUIET
+      )
+      if (GLIB_MKENUMS_PERL EQUAL 0)
+        message("${GLIB_MKENUMS} is a PERL script.")
+        set (GLIB_MKENUMS_CMD "${PERL_EXECUTABLE}" "${GLIB_MKENUMS}")
+      endif ()
+      if (NOT GLIB_MKENUMS_PERL EQUAL 0 AND NOT GLIB_MKENUMS_PYTHON EQUAL 0)
+        message(FATAL_ERROR "Unable to determine type of glib-mkenums script")
+      endif ()
+    endif ()
+  else ()
+    set (GLIB_MKENUMS_CMD "${GLIB_MKENUMS}")
+  endif ()
+  if (NOT GLIB_MKENUMS_CMD)
+    message(FATAL_ERROR "HB_HAVE_GOBJECT was set, but we failed to find glib-mkenums, which is required")
+  endif ()
+
+  pkg_check_modules(PC_GOBJECT QUIET gobject-2.0)
+
+  find_library(GOBJECT_LIBRARIES NAMES gobject-2.0 HINTS ${PC_GLIB_LIBDIR} ${PC_GLIB_LIBRARY_DIRS})
+  find_path(GOBJECT_INCLUDE_DIR NAMES glib-object.h HINTS ${PC_GLIB_INCLUDEDIR} ${PC_GLIB_INCLUDE_DIRS} PATH_SUFFIXES glib-2.0)
+
+  include_directories(${GOBJECTCONFIG_INCLUDE_DIR} ${GOBJECT_INCLUDE_DIR})
+  mark_as_advanced(GOBJECT_LIBRARIES GOBJECT_INCLUDE_DIR)
+
+  list(APPEND hb_gobject_sources ${PROJECT_SOURCE_DIR}/src/hb-gobject-structs.cc)
+  list(APPEND hb_gobject_gen_sources
+    ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc
+  )
+  list(APPEND hb_gobject_structs_headers
+    ${PROJECT_SOURCE_DIR}/src/hb-gobject-structs.h
+  )
+  list(APPEND hb_gobject_headers
+    ${PROJECT_SOURCE_DIR}/src/hb-gobject.h
+    ${hb_gobject_structs_headers}
+  )
+  list(APPEND hb_gobject_gen_headers
+    ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
+  )
+
+  add_custom_command(
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
+    COMMAND ${GLIB_MKENUMS_CMD}
+      --template=${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.h.tmpl
+      --identifier-prefix hb_
+      --symbol-prefix hb_gobject
+      ${hb_gobject_structs_headers}
+      ${project_headers}
+      > ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h.tmp
+    COMMAND "${CMAKE_COMMAND}"
+      "-DENUM_INPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h.tmp"
+      "-DENUM_OUTPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h"
+      -P ${PROJECT_SOURCE_DIR}/replace-enum-strings.cmake
+    DEPENDS ${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.h.tmpl
+      ${hb_gobject_header}
+      ${project_headers}
+  )
+
+  add_custom_command(
+    OUTPUT ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc
+    COMMAND ${GLIB_MKENUMS_CMD}
+      --template=${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.cc.tmpl
+      --identifier-prefix hb_
+      --symbol-prefix hb_gobject
+      ${hb_gobject_header}
+      ${project_headers}
+      > ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc.tmp
+    COMMAND "${CMAKE_COMMAND}"
+      "-DENUM_INPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc.tmp"
+      "-DENUM_OUTPUT_SRC=${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.cc"
+      -P ${PROJECT_SOURCE_DIR}/replace-enum-strings.cmake
+    DEPENDS ${PROJECT_SOURCE_DIR}/src/hb-gobject-enums.cc.tmpl
+      ${CMAKE_CURRENT_BINARY_DIR}/src/hb-gobject-enums.h
+      ${hb_gobject_header}
+      ${project_headers}
+  )
+endif ()
+
+
+## Define harfbuzz library
+add_library(harfbuzz ${project_sources} ${project_extra_sources} ${project_headers})
+target_link_libraries(harfbuzz ${THIRD_PARTY_LIBS})
+target_include_directories(harfbuzz PUBLIC
+                           "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/src>"
+                           "$<INSTALL_INTERFACE:${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz>")
+if (HB_HAVE_FREETYPE AND TARGET freetype)
+  target_link_libraries(harfbuzz freetype)
+endif ()
+
+
+## Define harfbuzz-icu library
+if (HB_HAVE_ICU)
+  add_library(harfbuzz-icu ${PROJECT_SOURCE_DIR}/src/hb-icu.cc ${PROJECT_SOURCE_DIR}/src/hb-icu.h)
+  add_dependencies(harfbuzz-icu harfbuzz)
+  target_link_libraries(harfbuzz-icu harfbuzz ${THIRD_PARTY_LIBS})
+
+  if (BUILD_SHARED_LIBS)
+    set_target_properties(harfbuzz harfbuzz-icu PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
+  endif ()
+endif ()
+
+
+## Define harfbuzz-subset library
+if (HB_BUILD_SUBSET)
+  add_library(harfbuzz-subset ${subset_project_sources} ${subset_project_headers})
+  list(APPEND project_headers ${PROJECT_SOURCE_DIR}/src/hb-subset.h ${PROJECT_SOURCE_DIR}/src/hb-subset-repacker.h)
+  add_dependencies(harfbuzz-subset harfbuzz)
+  target_link_libraries(harfbuzz-subset harfbuzz ${THIRD_PARTY_LIBS})
+
+  if (BUILD_SHARED_LIBS)
+    set_target_properties(harfbuzz harfbuzz-subset PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
+  endif ()
+endif ()
+
+if (UNIX OR MINGW OR VITA)
+  # Make symbols link locally
+  include (CheckCXXCompilerFlag)
+  CHECK_CXX_COMPILER_FLAG(-Bsymbolic-functions CXX_SUPPORTS_FLAG_BSYMB_FUNCS)
+  if (CXX_SUPPORTS_FLAG_BSYMB_FUNCS)
+    link_libraries(-Bsymbolic-functions)
+  endif ()
+
+  # As of CMake 3.0.0, the compiler id for Apple-provided Clang is now "AppleClang";
+  # thus we use MATCHES instead of STREQUAL to include either regular Clang or AppleClang
+  if (CMAKE_CXX_COMPILER_ID MATCHES "Clang" OR CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
+    # Make sure we don't link to libstdc++
+    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-rtti -fno-exceptions")
+    set (CMAKE_CXX_IMPLICIT_LINK_LIBRARIES "m") # libm
+    set (CMAKE_CXX_IMPLICIT_LINK_DIRECTORIES "")
+    set_target_properties(harfbuzz PROPERTIES LINKER_LANGUAGE C)
+    if (HB_BUILD_SUBSET)
+      set_target_properties(harfbuzz-subset PROPERTIES LINKER_LANGUAGE C)
+    endif ()
+
+    # No threadsafe statics as we do it ourselves
+    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-threadsafe-statics")
+  endif ()
+
+  CHECK_CXX_COMPILER_FLAG("-std=c++11" COMPILER_SUPPORTS_CXX11)
+  if (COMPILER_SUPPORTS_CXX11)
+    set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+  else()
+    message(STATUS "The compiler ${CMAKE_CXX_COMPILER} has no C++11 support. Please use a different C++ compiler.")
+  endif()
+endif ()
+
+
+## Define harfbuzz-gobject library
+if (HB_HAVE_GOBJECT)
+  add_library(harfbuzz-gobject
+    ${hb_gobject_sources}
+    ${hb_gobject_gen_sources}
+    ${hb_gobject_headers}
+    ${hb_gobject_gen_headers}
+  )
+  include_directories(BEFORE ${CMAKE_CURRENT_BINARY_DIR}/src)
+  add_dependencies(harfbuzz-gobject harfbuzz)
+  target_link_libraries(harfbuzz-gobject harfbuzz ${GOBJECT_LIBRARIES} ${THIRD_PARTY_LIBS})
+
+  if (BUILD_SHARED_LIBS)
+    set_target_properties(harfbuzz-gobject PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
+  endif ()
+endif ()
+
+## Define harfbuzz-cairo library
+if (HB_HAVE_CAIRO)
+  include_directories(${CAIRO_INCLUDE_DIRS})
+  add_library(harfbuzz-cairo ${PROJECT_SOURCE_DIR}/src/hb-cairo.cc ${PROJECT_SOURCE_DIR}/src/hb-static.cc ${PROJECT_SOURCE_DIR}/src/hb-cairo.h)
+  add_dependencies(harfbuzz-cairo harfbuzz)
+  target_link_libraries(harfbuzz-cairo harfbuzz ${THIRD_PARTY_LIBS})
+
+  if (BUILD_SHARED_LIBS)
+    set_target_properties(harfbuzz-cairo PROPERTIES VISIBILITY_INLINES_HIDDEN TRUE)
+  endif ()
+endif()
+
+if (BUILD_SHARED_LIBS AND WIN32 AND NOT MINGW)
+  add_definitions("-DHB_DLL_EXPORT")
+endif ()
+
+# On Windows, g-ir-scanner requires a DLL build in order for it to work
+if (WIN32)
+  if (NOT BUILD_SHARED_LIBS)
+    message("Building introspection files on Windows requires BUILD_SHARED_LIBS to be enabled.")
+    set (HB_HAVE_INTROSPECTION OFF)
+  endif ()
+endif ()
+
+if (HB_HAVE_INTROSPECTION)
+  find_package(PkgConfig)
+  pkg_check_modules(PC_GI QUIET gobject-introspection-1.0)
+
+  find_program(G_IR_SCANNER g-ir-scanner
+    HINTS ${PC_g_ir_scanner}
+  )
+
+  find_program(G_IR_COMPILER g-ir-compiler
+    HINTS ${PC_g_ir_compiler}
+  )
+
+  if (WIN32 AND NOT MINGW)
+    # Note that since we already enable HB_HAVE_GOBJECT
+    # we would already have Python3_EXECUTABLE handy
+    set (G_IR_SCANNER_CMD "${Python3_EXECUTABLE}" "${G_IR_SCANNER}")
+  else ()
+    set (G_IR_SCANNER_CMD "${G_IR_SCANNER}")
+  endif ()
+
+  # We need to account for the varying output directories
+  # when we build using Visual Studio projects
+  if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
+    set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>")
+  else ()
+    set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
+  endif ()
+
+  # Get the CFlags that we used to build HarfBuzz/HarfBuzz-GObject
+  set (hb_defines_cflags "")
+  foreach (hb_cflag ${hb_cflags})
+    list(APPEND hb_defines_cflags "-D${hb_cflag}")
+  endforeach (hb_cflag)
+
+  # Get the other dependent libraries we used to build HarfBuzz/HarfBuzz-GObject
+  set (extra_libs "")
+  foreach (extra_lib ${THIRD_PARTY_LIBS})
+    # We don't want the .lib extension here...
+    string(REPLACE ".lib" "" extra_lib_stripped "${extra_lib}")
+    list(APPEND extra_libs "--extra-library=${extra_lib_stripped}")
+  endforeach ()
+
+  set (introspected_sources)
+  foreach (f
+    ${project_headers}
+    ${project_sources}
+    ${hb_gobject_gen_sources}
+    ${hb_gobject_gen_headers}
+    ${hb_gobject_sources}
+    ${hb_gobject_headers}
+  )
+    if (WIN32)
+      # Nasty issue: We need to make drive letters lower case,
+      # otherwise g-ir-scanner won't like it and give us a bunch
+      # of invalid items and unresolved types...
+      STRING(SUBSTRING "${f}" 0 1 drive)
+      STRING(SUBSTRING "${f}" 1 -1 path)
+      if (drive MATCHES "[A-Z]")
+        STRING(TOLOWER ${drive} drive_lower)
+        list(APPEND introspected_sources "${drive_lower}${path}")
+      else ()
+        list(APPEND introspected_sources "${f}")
+      endif ()
+    else ()
+      list(APPEND introspected_sources "${f}")
+    endif ()
+  endforeach ()
+
+  file(REMOVE ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list)
+  foreach (s ${introspected_sources})
+    file(APPEND ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list "${s}\n")
+  endforeach ()
+
+  # Finally, build the introspection files...
+  add_custom_command(
+    TARGET harfbuzz-gobject
+    POST_BUILD
+    COMMAND ${G_IR_SCANNER_CMD}
+      --warn-all --no-libtool --verbose
+      --namespace=HarfBuzz
+      --nsversion=0.0
+      --symbol-prefix=hb
+      --symbol-prefix=hb_gobject
+      --identifier-prefix=hb_
+      --include GObject-2.0
+      --pkg-export=harfbuzz-gobject
+      --c-include=hb-gobject.h
+      --cflags-begin
+      -I${PROJECT_SOURCE_DIR}/src
+      -I${PROJECT_BINARY_DIR}/src
+      ${hb_includedir_cflags}
+      ${hb_defines_cflags}
+      -DHB_NO_SINGLE_HEADER_ERROR
+      -DHB_HAVE_GOBJECT
+      -DHB_EXTERN=
+      --cflags-end
+      --library=harfbuzz-gobject
+      --library=harfbuzz
+      -L${hb_libpath}
+      ${extra_libs}
+      --filelist ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list
+      -o ${hb_libpath}/HarfBuzz-0.0.gir
+    DEPENDS harfbuzz-gobject harfbuzz ${CMAKE_CURRENT_BINARY_DIR}/src/hb_gir_list
+  )
+
+  add_custom_command(
+    TARGET harfbuzz-gobject
+    POST_BUILD
+    COMMAND "${G_IR_COMPILER}"
+      --verbose --debug
+      --includedir ${CMAKE_CURRENT_BINARY_DIR}
+      ${hb_libpath}/HarfBuzz-0.0.gir
+      -o ${hb_libpath}/HarfBuzz-0.0.typelib
+    DEPENDS ${hb_libpath}/HarfBuzz-0.0.gir harfbuzz-gobject
+  )
+endif ()
+
+
+## Additional framework build configs
+if (BUILD_FRAMEWORK)
+  set (CMAKE_MACOSX_RPATH ON)
+  set_target_properties(harfbuzz PROPERTIES
+    FRAMEWORK TRUE
+    PUBLIC_HEADER "${project_headers}"
+    XCODE_ATTRIBUTE_INSTALL_PATH "@rpath"
+  )
+  set (MACOSX_FRAMEWORK_IDENTIFIER "harfbuzz")
+  set (MACOSX_FRAMEWORK_SHORT_VERSION_STRING "${HB_VERSION}")
+  set (MACOSX_FRAMEWORK_BUNDLE_VERSION "${HB_VERSION}")
+endif ()
+
+
+## Additional harfbuzz build artifacts
+if (HB_BUILD_UTILS)
+  add_definitions("-DPACKAGE_NAME=\"HarfBuzz\"")
+  add_definitions("-DPACKAGE_VERSION=\"${HB_VERSION}\"")
+
+  if (HB_HAVE_CAIRO)
+    add_executable(hb-view
+        ${PROJECT_SOURCE_DIR}/util/ansi-print.hh
+        ${PROJECT_SOURCE_DIR}/util/face-options.hh
+        ${PROJECT_SOURCE_DIR}/util/font-options.hh
+        ${PROJECT_SOURCE_DIR}/util/hb-view.cc
+        ${PROJECT_SOURCE_DIR}/util/helper-cairo-ansi.hh
+        ${PROJECT_SOURCE_DIR}/util/helper-cairo-ft.hh
+        ${PROJECT_SOURCE_DIR}/util/helper-cairo.hh
+        ${PROJECT_SOURCE_DIR}/util/main-font-text.hh
+        ${PROJECT_SOURCE_DIR}/util/options.hh
+        ${PROJECT_SOURCE_DIR}/util/output-options.hh
+        ${PROJECT_SOURCE_DIR}/util/shape-consumer.hh
+        ${PROJECT_SOURCE_DIR}/util/shape-options.hh
+        ${PROJECT_SOURCE_DIR}/util/text-options.hh
+        ${PROJECT_SOURCE_DIR}/util/view-cairo.hh
+        ${PROJECT_SOURCE_DIR}/util/view-options.hh
+    )
+    target_link_libraries(hb-view harfbuzz-cairo harfbuzz ${CAIRO_LIBRARIESNAMES})
+  endif()
+
+  add_executable(hb-shape
+        ${PROJECT_SOURCE_DIR}/util/batch.hh
+        ${PROJECT_SOURCE_DIR}/util/face-options.hh
+        ${PROJECT_SOURCE_DIR}/util/font-options.hh
+        ${PROJECT_SOURCE_DIR}/util/hb-shape.cc
+        ${PROJECT_SOURCE_DIR}/util/main-font-text.hh
+        ${PROJECT_SOURCE_DIR}/util/options.hh
+        ${PROJECT_SOURCE_DIR}/util/output-options.hh
+        ${PROJECT_SOURCE_DIR}/util/shape-consumer.hh
+        ${PROJECT_SOURCE_DIR}/util/shape-format.hh
+        ${PROJECT_SOURCE_DIR}/util/shape-options.hh
+        ${PROJECT_SOURCE_DIR}/util/shape-output.hh
+        ${PROJECT_SOURCE_DIR}/util/text-options.hh
+  )
+  target_link_libraries(hb-shape harfbuzz)
+
+  add_executable(hb-subset
+        ${PROJECT_SOURCE_DIR}/util/batch.hh
+        ${PROJECT_SOURCE_DIR}/util/face-options.hh
+        ${PROJECT_SOURCE_DIR}/util/hb-subset.cc
+        ${PROJECT_SOURCE_DIR}/util/main-font-text.hh
+        ${PROJECT_SOURCE_DIR}/util/options.hh
+        ${PROJECT_SOURCE_DIR}/util/output-options.hh
+        ${PROJECT_SOURCE_DIR}/util/text-options.hh
+        ${PROJECT_SOURCE_DIR}/util/helper-subset.hh
+  )
+  target_link_libraries(hb-subset harfbuzz harfbuzz-subset)
+
+  add_executable(hb-ot-shape-closure
+        ${PROJECT_SOURCE_DIR}/util/face-options.hh
+        ${PROJECT_SOURCE_DIR}/util/font-options.hh
+        ${PROJECT_SOURCE_DIR}/util/hb-ot-shape-closure.cc
+        ${PROJECT_SOURCE_DIR}/util/main-font-text.hh
+        ${PROJECT_SOURCE_DIR}/util/options.hh
+        ${PROJECT_SOURCE_DIR}/util/text-options.hh
+  )
+  target_link_libraries(hb-ot-shape-closure harfbuzz)
+
+  if (HB_HAVE_GOBJECT)
+    add_executable(hb-info
+        ${PROJECT_SOURCE_DIR}/util/batch.hh
+        ${PROJECT_SOURCE_DIR}/util/face-options.hh
+        ${PROJECT_SOURCE_DIR}/util/font-options.hh
+        ${PROJECT_SOURCE_DIR}/util/hb-info.cc
+        ${PROJECT_SOURCE_DIR}/util/options.hh
+    )
+    target_link_libraries(hb-info harfbuzz-gobject harfbuzz)
+  endif()
+endif ()
+
+
+## Install
+include (GNUInstallDirs)
+
+if (NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
+  install(FILES ${project_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz)
+  if (HB_HAVE_GOBJECT)
+    install(FILES ${hb_gobject_headers} ${hb_gobject_gen_headers} DESTINATION ${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz)
+  endif ()
+endif ()
+
+# get these variables in the required format
+list(REMOVE_DUPLICATES PC_REQUIRES_PRIV)
+string(REPLACE ";" ", " PC_REQUIRES_PRIV "${PC_REQUIRES_PRIV}")
+list(REMOVE_DUPLICATES PC_LIBS_PRIV)
+string(REPLACE ";" " " PC_LIBS_PRIV "${PC_LIBS_PRIV}")
+
+# Macro to write pkg-config .pc configuration files
+macro ( make_pkgconfig_pc_file name )
+  file(READ "${PROJECT_SOURCE_DIR}/src/${name}.pc.in" FSTR)
+
+  string(REPLACE "%prefix%" "${CMAKE_INSTALL_PREFIX}" FSTR ${FSTR})
+  string(REPLACE "%exec_prefix%" "\${prefix}" FSTR ${FSTR})
+
+  if (IS_ABSOLUTE "${CMAKE_INSTALL_INCLUDEDIR}")
+    string(REPLACE "%includedir%" "${CMAKE_INSTALL_INCLUDEDIR}" FSTR ${FSTR})
+  else ()
+    string(REPLACE "%includedir%" "\${prefix}/${CMAKE_INSTALL_INCLUDEDIR}" FSTR ${FSTR})
+  endif ()
+
+  if (IS_ABSOLUTE "${CMAKE_INSTALL_LIBDIR}")
+    string(REPLACE "%libdir%" "${CMAKE_INSTALL_LIBDIR}" FSTR ${FSTR})
+  else ()
+    string(REPLACE "%libdir%" "\${prefix}/${CMAKE_INSTALL_LIBDIR}" FSTR ${FSTR})
+  endif ()
+
+  string(REPLACE "%VERSION%" "${HB_VERSION}" FSTR ${FSTR})
+  string(REPLACE "%requires_private%" "${PC_REQUIRES_PRIV}" FSTR ${FSTR})
+  string(REPLACE "%libs_private%" "${PC_LIBS_PRIV}" FSTR ${FSTR})
+
+  file(WRITE "${PROJECT_BINARY_DIR}/${name}.pc" ${FSTR})
+
+  install(
+    FILES "${PROJECT_BINARY_DIR}/${name}.pc"
+    DESTINATION "${CMAKE_INSTALL_LIBDIR}/pkgconfig"
+    COMPONENT pkgconfig
+  )
+endmacro ( make_pkgconfig_pc_file )
+
+# Generate hb-features.h with the features we enabled
+macro (make_hb_features_h)
+  file(READ "${PROJECT_SOURCE_DIR}/src/hb-features.h.in" feature_h_in)
+  foreach(arg cairo coretext directwrite freetype gdi glib gobject graphite icu uniscribe wasm)
+    string(TOUPPER ${arg} feature_caps)
+    set(feature_instring "#mesondefine HB_HAS_${feature_caps}")
+    if (HB_HAVE_${feature_caps})
+      set(feature_outstring "#define HB_HAS_${feature_caps} 1")
+    else ()
+      set(feature_outstring "/* #undef HB_HAS_${feature_caps} */")
+    endif()
+    string(REPLACE ${feature_instring} ${feature_outstring} feature_h_in ${feature_h_in})
+  endforeach()
+  file(WRITE "${PROJECT_BINARY_DIR}/src/hb-features.h" ${feature_h_in})
+  if (NOT SKIP_INSTALL_HEADERS AND NOT SKIP_INSTALL_ALL)
+    install(
+      FILES "${PROJECT_BINARY_DIR}/src/hb-features.h"
+      DESTINATION "${CMAKE_INSTALL_INCLUDEDIR}/harfbuzz"
+    )
+  endif()
+endmacro (make_hb_features_h)
+
+if (NOT SKIP_INSTALL_LIBRARIES AND NOT SKIP_INSTALL_ALL)
+  install(TARGETS harfbuzz
+    EXPORT harfbuzzConfig
+    ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    FRAMEWORK DESTINATION Library/Frameworks
+  )
+  make_pkgconfig_pc_file("harfbuzz")
+  install(EXPORT harfbuzzConfig
+      NAMESPACE harfbuzz::
+      DESTINATION ${CMAKE_INSTALL_LIBDIR}/cmake/harfbuzz
+  )
+  if (HB_HAVE_ICU)
+    install(TARGETS harfbuzz-icu
+      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+      FRAMEWORK DESTINATION Library/Frameworks
+    )
+    make_pkgconfig_pc_file("harfbuzz-icu")
+  endif ()
+  if (HB_HAVE_CAIRO)
+    install(TARGETS harfbuzz-cairo
+      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+      FRAMEWORK DESTINATION Library/Frameworks
+    )
+    make_pkgconfig_pc_file("harfbuzz-cairo")
+  endif ()
+  if (HB_BUILD_SUBSET)
+    install(TARGETS harfbuzz-subset
+      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+    )
+    make_pkgconfig_pc_file("harfbuzz-subset")
+  endif ()
+  if (HB_BUILD_UTILS)
+    if (WIN32 AND BUILD_SHARED_LIBS)
+      install(TARGETS harfbuzz-subset
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+      )
+    endif ()
+    if (HB_HAVE_CAIRO)
+      install(TARGETS hb-view
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+      )
+    endif()
+    install(TARGETS hb-subset
+      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    )
+
+    install(TARGETS hb-shape
+      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    )
+
+    if (HB_HAVE_GOBJECT)
+      install(TARGETS hb-info
+        RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+      )
+    endif()
+
+    install(TARGETS hb-ot-shape-closure
+      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    )
+  endif ()
+  if (HB_HAVE_GOBJECT)
+    install(TARGETS harfbuzz-gobject
+      ARCHIVE DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      LIBRARY DESTINATION ${CMAKE_INSTALL_LIBDIR}
+      RUNTIME DESTINATION ${CMAKE_INSTALL_BINDIR}
+    )
+    make_pkgconfig_pc_file("harfbuzz-gobject")
+    if (HB_HAVE_INTROSPECTION)
+      if ("${CMAKE_GENERATOR}" MATCHES "Visual Studio*")
+        set (hb_libpath "${CMAKE_CURRENT_BINARY_DIR}/$<CONFIG>")
+      else ()
+        set (hb_libpath "$<TARGET_FILE_DIR:harfbuzz-gobject>")
+      endif ()
+
+      install(FILES "${hb_libpath}/HarfBuzz-0.0.gir"
+        DESTINATION ${CMAKE_INSTALL_DATAROOTDIR}/gir-1.0
+      )
+
+      install(FILES "${hb_libpath}/HarfBuzz-0.0.typelib"
+        DESTINATION ${CMAKE_INSTALL_LIBDIR}/girepository-1.0
+      )
+    endif ()
+  endif ()
+  make_hb_features_h()
+endif ()

+ 162 - 0
hbfreetypefont.mod/harfbuzz/CONFIG.md

@@ -0,0 +1,162 @@
+# Configuring HarfBuzz
+
+Most of the time you will not need any custom configuration.  The configuration
+options provided by `meson` should be enough.  In particular, if you just want
+HarfBuzz library plus hb-shape / hb-view utilities, make sure FreeType and Cairo
+are available and found during configuration.
+
+If you are building for distribution, you should more carefully consider whether
+you need Glib, ICU, Graphite2, as well as CoreText / Uniscribe / DWrite.  Make
+sure the relevant ones are enabled.
+
+If you are building for custom environment (embedded, downloadable app, etc)
+where you mostly just want to call `hb_shape()` and the binary size of the
+resulting library is very important to you, the rest of this file guides you
+through your options to disable features you may not need, in exchange for
+binary size savings.
+
+## Compiler Options
+
+Make sure you build with your compiler's "optimize for size" option.  On `gcc`
+this is `-Os`, and can be enabled by passing `CXXFLAGS=-Os`.  On clang there
+is an even more extreme flag, `-Oz`.  Meson also provides `--buildtype=minsize`
+for more convenience.
+
+HarfBuzz heavily uses inline functions and the optimize-size flag can make the
+library smaller by 20% or more.  Moreover, sometimes, based on the target CPU,
+the optimize-size builds perform *faster* as well, thanks to lower code
+footprint and caching effects.  So, definitely try that even if size is not
+extremely tight but you have a huge application.  For example, Chrome does
+that.  Note that this configuration also automatically enables certain internal
+optimizations.  Search for `HB_OPTIMIZE_SIZE` for details, if you are using
+other compilers, or continue reading.
+
+Another compiler option to consider is "link-time optimization", also known as
+'lto'.  To enable that, feel free to use `-Db_lto=true` of meson.
+This, also, can have a huge impact on the final size, 20% or more.
+
+Finally, if you are making a static library build or otherwise linking the
+library into your app, make sure your linker removes unused functions.  This
+can be tricky and differ from environment to environment, but you definitely
+want to make sure this happens.  Otherwise, every unused public function will
+be adding unneeded bytes to your binary.  The following pointers might come
+handy:
+
+ * https://lwn.net/Articles/741494/ (all of the four-part series)
+ * https://elinux.org/images/2/2d/ELC2010-gc-sections_Denys_Vlasenko.pdf
+
+Combining the above three build options should already shrink your library a lot.
+The rest of this file shows you ways to shrink the library even further at the
+expense of removing functionality (that may not be needed).  The remaining
+options are all enabled by defining pre-processor macros, which can be done
+via `CXXFLAGS` or `CPPFLAGS` similarly.
+
+
+## Unicode-functions
+
+Access to Unicode data can be configured at compile time as well as run-time.
+By default, HarfBuzz ships with its own compact subset of properties from
+Unicode Character Database that it needs.  This is a highly-optimized
+implementation that depending on compile settings (optimize-size or not)
+takes around ~40kb or ~60kb.  Using this implementation (default) is highly
+recommended, as HarfBuzz always ships with data from latest version of Unicode.
+This implementation can be disabled by defining `HB_NO_UCD`.
+
+For example, if you are enabling ICU as a built-in option, or GLib, those
+can provide Unicode data as well, so defining `HB_NO_UCD` might save you
+space without reducing functionality (to the extent that the Unicode version
+of those implementations is recent.)
+
+If, however, you provide your own Unicode data to HarfBuzz at run-time by
+calling `hb_buffer_set_unicode_funcs` on every buffer you create, and you do
+not rely on `hb_unicode_funcs_get_default()` results, you can disable the
+internal implementation by defining both `HB_NO_UCD` and `HB_NO_UNICODE_FUNCS`.
+The latter is needed to guard against accidentally building a library without
+any default Unicode implementations.
+
+
+## Font-functions
+
+Access to certain font functionalities can also be configured at run-time.  By
+default, HarfBuzz uses an efficient internal implementation of OpenType
+functionality for this.  This internal implementation is called `hb-ot-font`.
+All newly-created `hb_font_t` objects by default use `hb-ot-font`.  Using this
+is highly recommended, and is what fonts use by default when they are created.
+
+Most embedded uses will probably use HarfBuzz with FreeType using `hb-ft.h`.
+In that case, or if you otherwise provide those functions by calling
+`hb_font_set_funcs()` on every font you create, you can disable `hb-ot-font`
+without loss of functionality by defining `HB_NO_OT_FONT`.
+
+
+## Shapers
+
+Most HarfBuzz clients use it for the main shaper, called "ot".  However, it
+is legitimate to want to compile HarfBuzz with only another backend, eg.
+CoreText, for example for an iOS app.  For that, you want `HB_NO_OT_SHAPE`.
+If you are going down that route, check if you want `HB_NO_OT`.
+
+This is very rarely what you need.  Make sure you understand exactly what you
+are doing.
+
+Defining `HB_NO_FALLBACK_SHAPE` however is pretty harmless.  That removes the
+(unused) "fallback" shaper.  This is defined by the `HB_TINY` profile already
+(more below).
+
+
+## Thread-safety
+
+By default HarfBuzz builds as a thread-safe library.  The exception is that
+the `HB_TINY` predefined configuration (more below) disables thread-safety.
+
+If you do *not* need thread-safety in the library (eg. you always call into
+HarfBuzz from the same thread), you can disable thread-safety by defining
+`HB_NO_MT`.  As noted already, this is enabled by `HB_TINY`.
+
+
+## Pre-defined configurations
+
+The [`hb-config.hh`](src/hb-config.hh) internal header supports three
+pre-defined configurations as well grouping of various configuration options.
+The pre-defined configurations are:
+
+  * `HB_MINI`: Disables shaping of AAT as well as legacy fonts.  Ie. it produces
+    a capable OpenType shaper only.
+
+  * `HB_LEAN`: Disables various non-shaping functionality in the library, as well
+    as esoteric or rarely-used shaping features.  See the definition for details.
+
+  * `HB_TINY`: Enables both `HB_MINI` and `HB_LEAN` configurations, as well as
+    disabling thread-safety and debugging, and use even more size-optimized data
+    tables.
+
+To setup the build with these options use something like:
+```
+$ meson setup build -Dcpp_args=-DHB_MINI -Dc_args=-DHB_MINI
+```
+
+## Tailoring configuration
+
+Most of the time, one of the pre-defined configuration is exactly what one needs.
+Sometimes, however, the pre-defined configuration cuts out features that might
+be desired in the library.  Unfortunately there is no quick way to undo those
+configurations from the command-line.
+
+However, configuration can still be overridden from a file.  To do that, add your
+override instructions (mostly `undef` instructions) to a header file and define
+the macro `HB_CONFIG_OVERRIDE_H` to the string containing to that header file's
+name.  HarfBuzz will then include that file at the appropriate place during
+configuration.
+
+Up until HarfBuzz 3.1.2, the configuration override header file's name was
+fixed and called `config-override.h`, and was activated by defining the macro
+`HAVE_CONFIG_OVERRIDE_H`.  That still works.
+
+
+## Notes
+
+Note that the config option `HB_NO_CFF`, which is enabled by `HB_LEAN` and
+`HB_TINY` does *not* mean that the resulting library won't work with CFF fonts.
+The library can shape valid CFF fonts just fine, with or without this option.
+This option disables (among other things) the code to calculate glyph extents
+for CFF fonts or draw them, which many clients might not need.

+ 42 - 0
hbfreetypefont.mod/harfbuzz/COPYING

@@ -0,0 +1,42 @@
+HarfBuzz is licensed under the so-called "Old MIT" license.  Details follow.
+For parts of HarfBuzz that are licensed under different licenses see individual
+files names COPYING in subdirectories where applicable.
+
+Copyright © 2010-2022  Google, Inc.
+Copyright © 2015-2020  Ebrahim Byagowi
+Copyright © 2019,2020  Facebook, Inc.
+Copyright © 2012,2015  Mozilla Foundation
+Copyright © 2011  Codethink Limited
+Copyright © 2008,2010  Nokia Corporation and/or its subsidiary(-ies)
+Copyright © 2009  Keith Stribley
+Copyright © 2011  Martin Hosken and SIL International
+Copyright © 2007  Chris Wilson
+Copyright © 2005,2006,2020,2021,2022,2023  Behdad Esfahbod
+Copyright © 2004,2007,2008,2009,2010,2013,2021,2022,2023  Red Hat, Inc.
+Copyright © 1998-2005  David Turner and Werner Lemberg
+Copyright © 2016  Igalia S.L.
+Copyright © 2022  Matthias Clasen
+Copyright © 2018,2021  Khaled Hosny
+Copyright © 2018,2019,2020  Adobe, Inc
+Copyright © 2013-2015  Alexei Podtelezhnikov
+
+For full copyright notices consult the individual files in the package.
+
+
+Permission is hereby granted, without written agreement and without
+license or royalty fees, to use, copy, modify, and distribute this
+software and its documentation for any purpose, provided that the
+above copyright notice and the following two paragraphs appear in
+all copies of this software.
+
+IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+DAMAGE.
+
+THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.

+ 3468 - 0
hbfreetypefont.mod/harfbuzz/NEWS

@@ -0,0 +1,3468 @@
+Overview of changes leading to 9.0.0
+Thursday, Jun 27, 2024
+====================================
+- HarfBuzz now the supports the proposed new OpenType “VARC” table. This
+  replaces the previously supported “Variable Composites” experimental feature.
+  “VARC” support is still experimental and it is not enabled unless HarfBuzz is
+  built with experimental APIs enabled:
+  https://github.com/harfbuzz/boring-expansion-spec/blob/main/VARC.md
+- Autotools build system have been dropped. Meson is the only supported build
+  system in HarfBuzz going forward.
+- Speed up “AAT” shaping for short words by up to 4%.
+- Ignore unknown “CFF” operators.
+- “hb_subset_input_keep_everything()” now keeps also non-unicode “name” table
+  records.
+- Update the IANA and OpenType language tag registries.
+- Support composite glyphs with very large number of points in hb-draw API.
+- Various build fixes.
+
+
+Overview of changes leading to 8.5.0
+Monday, May 13, 2024
+====================================
+- API for partial instancing is now stable and have been promoted out of
+  experimental APIs.
+- Support instancing “BASE” table.
+- Speedup AAT shaping by 13–30%.
+- Various build fixes.
+- Various subsetter and instancer fixes.
+
+- New API
++HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS
++hb_subset_input_get_axis_range()
++hb_subset_input_pin_axis_location()
+
+Overview of changes leading to 8.4.0
+Saturday, March 29, 2024
+====================================
+- Add /bigobj to MSVC compiler flags in meson build, to fix building hb-subset.cc
+- Specify minimum versions of various dependencies in meson and autotools build.
+- When subsetting, place variation store at the end of “GDEF” table  to fix
+  shaping issues with some versions of Adobe InDesign.
+- Various build fixes.
+
+- New API:
++hb_buffer_set_random_state()
++hb_buffer_get_random_state()
+
+Overview of changes leading to 8.3.1
+Saturday, March 16, 2024
+====================================
+- hb_blob_create_from_file_or_fail() on Windows will now try to interpret the
+  file name as UTF-8 first, and as system code page if it is not valid UTF-8.
+- Fix hb_style_get_value() in fonts with “STAT” table.
+- Properly handle negative offsets in CFF table.
+- Update IANA Language Subtag Registry to 2024-03-07.
+- Subsetter now supports subsetting “BASE” table.
+- Subsetter will update “hhea” font metrics in sync with “OS/2” ones.
+- “--variations” option of “hb-subset” now supports leaving out values that
+  should be unchanged, e.g. “wght=:500:” will change the default and keep max
+  and min unchanged. It also supports “*=drop” to to pin all axes to default
+  location.
+- Fix hb_ot_math_get_glyph_kerning() to match updated “MATH” table spec.
+- Support legacy MacRoman encoding in “cmap” table.
+- Various build fixes.
+- Various subsetting and instancing fixes.
+
+- New API:
+hb_subset_input_pin_all_axes_to_default()
+
+Overview of changes leading to 8.3.0
+Saturday, November 11, 2023
+====================================
+- Improve memory barrier to fix potential segfaults.
+- Various build fixes.
+- Various subsetting and instancing fixes.
+- Rename “hb-subset” option “--instance” to “--variations” to match the other
+  tools. Old option is kept as an alias.
+
+- New API:
+HB_AAT_LAYOUT_FEATURE_TYPE_CURSIVE_CONNECTION
+
+- Deprecated API:
+HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION
+
+Overview of changes leading to 8.2.2
+Wednesday, October 18, 2023
+“From the river to the sea, Palestine will be free”
+====================================
+- Fix regression from 8.1.0 in shaping fonts with duplicate feature tags.
+- Fix regression from 8.2.0 in parsing CSS-style feature strings.
+- Variable fonts instanciation now handles more tables.
+- Various CMake build improvements.
+- various fixes to build without errors with gcc 4.9.2.
+
+
+Overview of changes leading to 8.2.1
+Monday, September 18, 2023
+====================================
+- Unicode 15.1 support.
+
+
+Overview of changes leading to 8.2.0
+Friday, September 8, 2023
+====================================
+- Various build and fuzzing fixes
+- Improvements to COLRv1 painting.
+
+- New API:
++hb_paint_color_glyph_func_t
++hb_paint_funcs_set_color_glyph_func
++hb_paint_color_glyph
+
+
+Overview of changes leading to 8.1.1
+Wednesday, August 2, 2023
+====================================
+- Fix shaping of contextual rules at the end of string, introduced in 8.1.0
+- Fix stack-overflow in repacker with malicious fonts.
+- 30% speed up loading Noto Duployan font.
+
+
+Overview of changes leading to 8.1.0
+Tuesday, August 1, 2023
+====================================
+- Fix long-standing build issue with the AIX compiler and older Apple clang.
+
+- Revert optimization that could cause timeout during subsetting with malicious fonts.
+
+- More optimization work:
+  - 45% speed up in shaping Noto Duployan font.
+  - 10% speed up in subsetting Noto Duployan font.
+  - Another 8% speed up in shaping Gulzar.
+  - 5% speed up in loading Roboto.
+
+- New API:
++hb_ot_layout_collect_features_map()
+
+
+Overview of changes leading to 8.0.1
+Wednesday, July 12, 2023
+====================================
+- Build fix on 32-bit ARM.
+
+- More speed optimizations:
+  - 60% speed up in retain-gid (used for IFT) subsetting of SourceHanSans-VF.
+  - 16% speed up in retain-gid (used for IFT) subsetting of NotoSansCJKkr.
+  - 38% speed up in subsetting (beyond-64k) mega-merged Noto.
+
+
+Overview of changes leading to 8.0.0
+Sunday, July 9, 2023
+====================================
+- New, experimental, WebAssembly (WASM) shaper, that provides greater
+  flexibility over OpenType/AAT/Graphite shaping, using WebAssembly embedded
+  inside the font file. Currently WASM shaper is disabled by default and needs
+  to be enabled at build time. For details, see:
+
+    https://github.com/harfbuzz/harfbuzz/blob/main/docs/wasm-shaper.md
+
+  For example fonts making use of the WASM shaper, see:
+
+    https://github.com/harfbuzz/harfbuzz-wasm-examples
+
+- Improvements to Experimental features introduced in earlier releases:
+  - Support for subsetting beyond-64k and VarComposites fonts.
+  - Support for instancing variable fonts with cubic “glyf” table.
+
+- Many big speed optimizations:
+  - Up to 89% speedup loading variable fonts for shaping.
+  - Up to 88% speedup in small subsets of large (eg. CJK) fonts (both TTF and
+    OTF), essential for Incremental Font Transfer (IFT).
+  - Over 50% speedup in loading Roboto font for shaping.
+  - Up to 40% speed up in loading (sanitizing) complex fonts.
+  - 30% speed up in shaping Gulzar font.
+  - Over 25% speedup in glyph loading Roboto font.
+  - 10% speed up loading glyph shapes in VarComposite Hangul font.
+  - hb-hashmap optimizations & hashing improvements.
+
+- New macro HB_ALWAYS_INLINE. HarfBuzz now inlines functions more aggressively,
+  which results in some speedup at the expense of bigger code size. To disable
+  this feature define the macro to just inline.
+
+- New API:
++HB_CODEPOINT_INVALID
++hb_ot_layout_get_baseline2()
++hb_ot_layout_get_baseline_with_fallback2()
++hb_ot_layout_get_font_extents()
++hb_ot_layout_get_font_extents2()
++hb_subset_input_set_axis_range()
+
+
+Overview of changes leading to 7.3.0
+Tuesday, May 9, 2023
+====================================
+- Speedup applying glyph variation in VarComposites fonts (over 40% speedup).
+  (Behdad Esfahbod)
+- Speedup instancing some fonts (over 20% speedup in instancing RobotoFlex).
+  (Behdad Esfahbod)
+- Speedup shaping some fonts (over 30% speedup in shaping Roboto).
+  (Behdad Esfahbod)
+- Support subsetting VarComposites and beyond-64k fonts. (Behdad Esfahbod)
+- New configuration macro HB_MINIMIZE_MEMORY_USAGE to favor optimizing memory
+  usage over speed. (Behdad Esfahbod)
+- Supporting setting the mapping between old and new glyph indices during
+  subsetting. (Garret Rieger)
+- Various fixes and improvements.
+  (Behdad Esfahbod, Denis Rochette, Garret Rieger, Han Seung Min, Qunxin Liu)
+
+- New API:
++hb_subset_input_old_to_new_glyph_mapping()
+
+
+Overview of changes leading to 7.2.0
+Thursday, April 27, 2023
+====================================
+- Add Tifinagh to the list of scripts that can natively be either right-to-left
+  or left-to-right, to improve handling of its glyph positioning.
+  (Simon Cozens)
+- Return also single substitution from hb_ot_layout_lookup_get_glyph_alternates()
+  (Behdad Esfahbod)
+- Fix 4.2.0 regression in applying across syllables in syllabic scripts.
+  (Behdad Esfahbod)
+- Add flag to avoid glyph substitution closure during subsetting, and the
+  corresponding “--no-layout-closure” option to “hb-subset” command line tool.
+  (Garret Rieger)
+- Support instancing COLRv1 table. (Qunxin Liu)
+- Don’t drop used user-defined name table entries during subsetting.
+  (Qunxin Liu)
+- Optimize handling of “gvar” table. (Behdad Esfahbod)
+- Various subsetter bug fixes and improvements. (Garret Rieger, Qunxin Liu)
+- Various documentation improvements. (Behdad Esfahbod, Josef Friedrich)
+
+- New API:
++HB_SUBSET_FLAGS_NO_LAYOUT_CLOSURE
++HB_UNICODE_COMBINING_CLASS_CCC132
+
+- Deprecated API:
++HB_UNICODE_COMBINING_CLASS_CCC133
+
+
+Overview of changes leading to 7.1.0
+Friday, March 3, 2023
+====================================
+- New experimental hb_shape_justify() API that uses font variations to expand
+  or shrink the text to a given advance. (Behdad Esfahbod)
+- Various build and bug fixes. (Behdad Esfahbod, Garret Rieger, Qunxin Liu)
+
+- New API:
++hb_font_set_variation()
+
+
+Overview of changes leading to 7.0.1
+Monday, February 20, 2023
+====================================
+- Various build and bug fixes.
+
+
+Overview of changes leading to 7.0.0
+Saturday, February 11, 2023
+====================================
+- New hb-paint API that is designed mainly to paint “COLRv1” glyphs, but can be
+  also used as a unified API to paint any of the glyph representations
+  supported by HarfBuzz (B/W outlines, color layers, or color bitmaps).
+  (Behdad Esfahbod, Matthias Clasen)
+- New hb-cairo API for integrating with cairo graphics library. This is provided
+  as a separate harfbuzz-cairo library. (Behdad Esfahbod, Matthias Clasen)
+- Support for instancing “CFF2” table. (Behdad Esfahbod)
+- Support font emboldening. (Behdad Esfahbod)
+- Support feature ranges with AAT shaping. (Behdad Esfahbod)
+- Experimental support to cubic curves in “glyf” table, see
+  https://github.com/harfbuzz/boring-expansion-spec/blob/main/glyf1-cubicOutlines.md
+  for spec. (Behdad Esfahbod)
+- Various subsetter improvements. (Garret Rieger, Qunxin Liu, Behdad Esfahbod)
+- Various documentation improvements.
+  (Behdad Esfahbod, Matthias Clasen, Khaled Hosny)
+- Significantly reduced memory use during shaping. (Behdad Esfahbod)
+- Greatly reduced memory use during subsetting “CFF” table. (Behdad Esfahbod)
+- New command line utility, hb-info, for querying various font information.
+  (Behdad Esfahbod, Matthias Clasen)
+- New hb-shape/hb-view options: --glyphs, --color-palette, --font-bold,
+  --font-grade, and --named-instance. (Behdad Esfahbod)
+- Miscellaneous fixes and improvements.
+  (Amir Masoud Abdol, Andres Salomon, Behdad Esfahbod, Chun-wei Fan,
+  Garret Rieger, Jens Kutilek, Khaled Hosny, Konstantin Käfer, Matthias Clasen,
+  Nirbheek Chauhan, Pedro J. Estébanez, Qunxin Liu, Sergei Trofimovich)
+
+- New API:
++HB_FONT_NO_VAR_NAMED_INSTANCE
++HB_PAINT_IMAGE_FORMAT_BGRA
++HB_PAINT_IMAGE_FORMAT_PNG
++HB_PAINT_IMAGE_FORMAT_SVG
++hb_cairo_font_face_create_for_face
++hb_cairo_font_face_create_for_font
++hb_cairo_font_face_get_face
++hb_cairo_font_face_get_font
++hb_cairo_font_face_get_scale_factor
++hb_cairo_font_face_set_font_init_func
++hb_cairo_font_face_set_scale_factor
++hb_cairo_font_init_func_t
++hb_cairo_glyphs_from_buffer
++hb_cairo_scaled_font_get_font
++hb_color_line_get_color_stops
++hb_color_line_get_color_stops_func_t
++hb_color_line_get_extend
++hb_color_line_get_extend_func_t
++hb_color_line_t
++hb_color_stop_t
++hb_draw_funcs_get_empty
++hb_draw_funcs_get_user_data
++hb_draw_funcs_set_user_data
++hb_face_collect_nominal_glyph_mapping
++hb_font_draw_glyph
++hb_font_draw_glyph_func_t
++hb_font_funcs_set_draw_glyph_func
++hb_font_funcs_set_paint_glyph_func
++hb_font_get_synthetic_bold
++hb_font_get_var_named_instance
++hb_font_paint_glyph
++hb_font_paint_glyph_func_t
++hb_font_set_synthetic_bold
++hb_map_keys
++hb_map_next
++hb_map_update
++hb_map_values
++hb_ot_color_glyph_has_paint
++hb_ot_color_has_paint
++hb_ot_layout_script_select_language2
++hb_ot_name_id_predefined_t
++hb_paint_color
++hb_paint_color_func_t
++hb_paint_composite_mode_t
++hb_paint_custom_palette_color
++hb_paint_custom_palette_color_func_t
++hb_paint_extend_t
++hb_paint_funcs_create
++hb_paint_funcs_destroy
++hb_paint_funcs_get_empty
++hb_paint_funcs_get_user_data
++hb_paint_funcs_is_immutable
++hb_paint_funcs_make_immutable
++hb_paint_funcs_reference
++hb_paint_funcs_set_color_func
++hb_paint_funcs_set_custom_palette_color_func
++hb_paint_funcs_set_image_func
++hb_paint_funcs_set_linear_gradient_func
++hb_paint_funcs_set_pop_clip_func
++hb_paint_funcs_set_pop_group_func
++hb_paint_funcs_set_pop_transform_func
++hb_paint_funcs_set_push_clip_glyph_func
++hb_paint_funcs_set_push_clip_rectangle_func
++hb_paint_funcs_set_push_group_func
++hb_paint_funcs_set_push_transform_func
++hb_paint_funcs_set_radial_gradient_func
++hb_paint_funcs_set_sweep_gradient_func
++hb_paint_funcs_set_user_data
++hb_paint_funcs_t
++hb_paint_image
++hb_paint_image_func_t
++hb_paint_linear_gradient
++hb_paint_linear_gradient_func_t
++hb_paint_pop_clip
++hb_paint_pop_clip_func_t
++hb_paint_pop_group
++hb_paint_pop_group_func_t
++hb_paint_pop_transform
++hb_paint_pop_transform_func_t
++hb_paint_push_clip_glyph
++hb_paint_push_clip_glyph_func_t
++hb_paint_push_clip_rectangle
++hb_paint_push_clip_rectangle_func_t
++hb_paint_push_group
++hb_paint_push_group_func_t
++hb_paint_push_transform
++hb_paint_push_transform_func_t
++hb_paint_radial_gradient
++hb_paint_radial_gradient_func_t
++hb_paint_sweep_gradient
++hb_paint_sweep_gradient_func_t
++hb_set_is_inverted
++hb_subset_input_keep_everything
+
+- Deprecated API:
++hb_font_funcs_set_glyph_shape_func
++hb_font_get_glyph_shape_func_t
++hb_font_get_glyph_shape
+
+
+Overview of changes leading to 6.0.0
+Friday, December 16, 2022
+====================================
+- A new API have been added to pre-process the face and speed up future
+  subsetting operations on that face. Provides up to a 95% reduction in
+  subsetting times when the same face is subset more than once.
+
+  For more details and benchmarks, see:
+  https://github.com/harfbuzz/harfbuzz/blob/main/docs/subset-preprocessing.md
+
+  (Garret Rieger, Behdad Esfahbod)
+
+- Shaping have been speedup by skipping entire lookups when the buffer contents
+  don't intersect with the lookup. Shows up to a 10% speedup in shaping some
+  fonts. (Behdad Esfahbod)
+
+- A new experimental feature, “Variable Composites” (enabled by passing
+  -Dexperimental_api=true to meson), is also featured in this release.
+  This technology enables drastic compression of fonts in the Chinese,
+  Japanese, Korean, and other writing systems, by reusing the OpenType Font
+  Variations technology for encoding “smart components” into the font.
+
+  The specification for these  extensions to the font format can be found in:
+  https://github.com/harfbuzz/boring-expansion-spec/blob/glyf1/glyf1.md
+
+  A test variable-font with ~7160 Hangul syllables derived from the
+  NotoSerifKR-VF font has been built, with existing OpenType technology, as
+  well as with the new Variable Composites (VarComposites) technology. The
+  VarComposites font is over 90% smaller than the OpenType version of the font!
+  Both fonts can be obtained from the “smarties” repository:
+  https://github.com/behdad/smarties/tree/3.0/fonts/hangul/serif
+
+  When building HarfBuzz with experimental features enabled, you can test
+  the “smarties” font with a sample character like this:
+
+  $ hb-view butchered-hangul-serif-smarties-variable.ttf -u AE01 --variations=wght=700
+
+  (Behdad Esfahbod)
+
+- The HarfBuzz subsetter can now drop axes by pinning them to specific values
+  (also referred to as instancing). There are a couple of restrictions
+  currently:
+
+  - Only works with TrueType (“glyf”) based fonts. “CFF2” fonts are not yet
+    supported.
+  - Only supports the case where all axes in a font are pinned.
+
+  (Garret Rieger, Qunxin Liu)
+
+- Miscellaneous fixes and improvements.
+
+  (Behdad Esfahbod, Christoph Reiter, David Corbett, Eli Schwartz, Garret
+   Rieger, Joel Auterson, Jordan Petridis, Khaled Hosny, Lorenz Wildberg,
+   Marco Rebhan, Martin Storsjö, Matthias Clasen, Qunxin Liu, Satadru Pramanik)
+
+
+- New API
++hb_subset_input_pin_axis_location()
++hb_subset_input_pin_axis_to_default()
++hb_subset_preprocess()
+
+
+Overview of changes leading to 5.3.1
+Wednesday, October 19, 2022
+====================================
+- Subsetter repacker fixes. (Garret Rieger)
+- Adjust Grapheme clusters for Katakana voiced sound marks. (Behdad Esfahbod)
+- New “hb-subset” option “--preprocess-face”. (Garret Rieger)
+
+
+Overview of changes leading to 5.3.0
+Saturday, October 8, 2022
+"Women, Life, Freedom" #MahsaAmini
+====================================
+- Don’t add glyphs from dropped MATH or COLR tables to the subset glyphs.
+  (Khaled Hosny)
+- Map “rlig” to appropriate AAT feature selectors. (Jonathan Kew)
+- Update USE data files to latest version. (David Corbett)
+- Check “CBDT” extents first before outline tables, to help with fonts that
+  also include an empty “glyf” table. (Khaled Hosny)
+- More work towards variable font instancing in the subsetter. (Qunxin Liu)
+- Subsetter repacker improvements. (Garret Rieger)
+- New API:
++hb_ot_layout_lookup_get_optical_bound()
++hb_face_builder_sort_tables()
+
+
+Overview of changes leading to 5.2.0
+Saturday, September 17, 2022
+====================================
+- Fix regressions in hb-ft font functions for FT_Face’s with transformation
+  matrix. (Behdad Esfahbod)
+- The experimental hb-repacker API now supports splitting several GPOS subtable
+  types when needed. (Garret Rieger)
+- The HarfBuzz extensions to OpenType font format are now opt-in behind
+  build-time flags. (Behdad Esfahbod)
+- The experimental hb-subset variable fonts instantiation API can now
+  instantiate more font tables and arbitrary axis locations. (Qunxin Liu)
+- Unicode 15 support. (David Corbett)
+- Various documentation improvements. (Behdad Esfahbod, Matthias Clasen)
+- The hb-view command line tool now detects WezTerm inline images support.
+  (Wez Furlong)
+- Fix FreeType and ICU dependency lookup with meson. (Xavier Claessens)
+
+- New API:
++HB_SCRIPT_KAWI
++HB_SCRIPT_NAG_MUNDARI
+
+
+Overview of changes leading to 5.1.0
+Sunday, July 31, 2022
+====================================
+- More extensive buffer tracing messages. (Behdad Esfahbod)
+- Fix hb-ft regression in bitmap fonts rendering. (Behdad Esfahbod)
+- Support extension promotion of lookups in hb-subset-repacker. (Garret Rieger)
+- A new HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL for scripts that use elongation
+  (e.g. Arabic) to signify where it is safe to insert tatweel glyph without
+  interrupting shaping. (Behdad Esfahbod)
+- Add “--safe-to-insert-tatweel” to “hb-shape” tool. (Behdad Esfahbod)
+
+- New API
++HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL
++HB_BUFFER_FLAG_PRODUCE_SAFE_TO_INSERT_TATWEEL
+
+
+Overview of changes leading to 5.0.1
+Saturday, July 23, 2022
+====================================
+- Fix version 2 “avar” table with hb-ft. (Behdad Esfahbod)
+
+
+Overview of changes leading to 5.0.0
+Saturday, July 23, 2022
+====================================
+- Support fonts with more than 65535 glyphs in “GDEF”, “GSUB”, and “GPOS”
+  tables. This is part of https://github.com/be-fonts/boring-expansion-spec to
+  extend OpenType in a backward-compatible way.
+  (Behdad Esfahbod, Garret Rieger)
+- Complete support for more than 65535 glyphs in “glyf” table that started in
+  4.0.0 release. Part of boring-expansion-spec. (Behdad Esfahbod)
+- Support version 2 of “avar” table. Part of boring-expansion-spec.
+  (Behdad Esfahbod)
+- Fix mark attachment on multiple substitutions in some cases.
+  (Behdad Esfahbod)
+- Fix application of “calt”, “rclt”, and “ccmp” features to better match
+  Uniscribe behaviour with some Arabic fonts. (Behdad Esfahbod)
+- Improvement to interaction between multiple cursive attachments.
+  (Behdad Esfahbod)
+- Improve multiple mark interactions in Hebrew. (Behdad Esfahbod)
+- Implement language-specific forms in AAT shaping. (Behdad Esfahbod)
+- Fix variation of “VORG” table. (Behdad Esfahbod)
+- Support for specific script tags to be retained in the subsetter, and add
+  “--layout-scripts” option to “hb-subset” tool. (Garret Rieger)
+- Accept space as delimiter for --features/--variations in command line tools.
+- Improve subsetting of “COLR” table. (Qunxin Liu)
+- Improved fuzzing coverage for ot-math API. (Frédéric Wang)
+- Fix “kern” table version 2 (AAT) sanitization on 32-bit systems.
+  (Behdad Esfahbod)
+- Allow negative glyph advances from “graphite2” shaper. (Stephan Bergmann)
+- Implement loading (color) bitmap fonts with hb-ft. (Behdad Esfahbod)
+- Fix regression in hb-ft when changing font size. (Behdad Esfahbod)
+- Fix build on GCC < 7. (Kleis Auke Wolthuizen)
+- Dynamically load dwrite.dll on windows if “directwrite” shaper is enabled.
+  (Luca Bacci)
+- Provide a single-file harfbuzz-subset.cc file for easier alternate building
+  of hb-subset library, similar to harfbuzz.cc. (Khaled Hosny)
+
+- New API
++HB_SUBSET_SETS_LAYOUT_SCRIPT_TAG
++hb_language_matches()
+
+
+Overview of changes leading to 4.4.1
+Wednesday, June 29, 2022
+====================================
+- Fix test failure with some compilers.
+- Fix Telugu and Kannada kerning regression.
+
+
+Overview of changes leading to 4.4.0
+Monday, June 27, 2022
+====================================
+- Caching of variable fonts shaping, in particular when using HarfBuzz’s own
+  font loading functions (ot). Bringing performance of variable shaping in par
+  with non-variable fonts shaping. (Behdad Esfahbod)
+- Caching of format 2 “Contextual Substitution” and “Chained Contexts
+  Substitution” lookups. Resulting in up to 20% speedup of lookup-heavy fonts
+  like Gulzar or Noto Nastaliq Urdu. (Behdad Esfahbod)
+- Improved ANSI output from hb-view. (Behdad Esfahbod)
+- Support for shaping legacy, pre-OpenType Windows 3.1-era, Arabic fonts that
+  relied on a fixed PUA encoding. (Khaled Hosny, Behdad Esfahbod)
+- Sinhala script is now shaped by the USE shaper instead of “indic” one.
+  (Behdad Esfahbod, David Corbett)
+- Thai shaper improvements. (David Corbett)
+- hb-ot-name API supports approximate BCP-47 language matching, for example
+  asking for “en_US” in a font that has only “en” names will return them.
+  (Behdad Esfahbod)
+- Optimized TrueType glyph shape loading. (Behdad Esfahbod)
+- Fix subsetting of HarfBuzz faces created via hb_face_create_for_tables().
+  (Garret Rieger)
+- Add 32 bit var store support to the subsetter. (Garret Rieger)
+
+- New API
++HB_BUFFER_FLAG_DEFINED
++HB_BUFFER_SERIALIZE_FLAG_DEFINED
++hb_font_changed()
++hb_font_get_serial()
++hb_ft_hb_font_changed()
++hb_set_hash()
++hb_map_copy()
++hb_map_hash()
+
+
+Overview of changes leading to 4.3.0
+Friday, May 20, 2022
+====================================
+- Major speed up in loading and subsetting fonts, especially in
+  handling CFF table. Subsetting some fonts is now 3 times faster.
+  (Behdad Esfahbod, Garret Rieger)
+- Speed up blending CFF2 table. (Behdad Esfahbod)
+- Speed up hb_ot_tags_from_language(). (Behdad Esfahbod, David Corbett)
+- Fix USE classification of U+10A38 to fix multiple marks on single Kharoshthi
+  base. (David Corbett)
+- Fix parsing of empty CFF Index. (Behdad Esfahbod)
+- Fix subsetting CPAL table with partial palette overlaps. (Garret Rieger)
+
+- New API
++hb_map_is_equal() (Behdad Esfahbod)
+
+
+Overview of changes leading to 4.2.1
+Sunday, April 24, 2022
+====================================
+- Make sure hb_blob_create_from_file_or_fail() always returns nullptr in case
+  of failure and not empty blob sometimes. (Khaled Hosny)
+- Add --passthrough-tables option to hb-subset. (Cosimo Lupo)
+- Reinstate a pause after basic features in Khmer shaper, fixing a regression
+  introduced in previous release. (Behdad Esfahbod)
+- Better handling of Regional_Indicator when shaped with RTL-native scripts,
+  reverting earlier fix that caused regressions in AAT shaping. (Behdad Esfahbod)
+
+
+Overview of changes leading to 4.2.0
+Wednesday, March 30, 2022
+====================================
+- Source code reorganization, splitting large hb-ot-layout files into smaller,
+  per-subtable ones under OT/Layout/*. Code for more tables will follow suit in
+  later releases. (Garret Rieger, Behdad Esfahbod)
+- Revert Indic shaper change in previous release that broke some fonts and
+  instead make per-syllable restriction of “GSUB” application limited to
+  script-specific Indic features, while applying them and discretionary
+  features in one go. (Behdad Esfahbod)
+- Fix decoding of private in gvar table. (Behdad Esfahbod)
+- Fix handling of contextual lookups that delete too many glyphs. (Behdad Esfahbod)
+- Make “morx” deleted glyphs don’t block “GPOS” application. (Behdad Esfahbod)
+- Various build fixes. (Chun-wei Fan, Khaled Hosny)
+
+- New API
++hb_set_next_many() (Andrew John)
+
+
+Overview of changes leading to 4.1.0
+Wednesday, March 23, 2022
+====================================
+- Various OSS-Fuzz fixes. (Behdad Esfahbod)
+- Make fallback vertical-origin match FreeType’s. (Behdad Esfahbod)
+- Treat visible viramas like dependent vowels in USE shaper. (David Corbett)
+- Apply presentation forms features and discretionary features in one go in
+  Indic shaper, which seems to match Uniscribe and CoreText behaviour.
+  (Behdad Esfahbod, David Corbett)
+- Various bug fixes.
+
+- New API
++hb_set_add_sorted_array() (Andrew John)
+
+
+Overview of changes leading to 4.0.1
+Friday, March 11, 2022
+====================================
+- Update OpenType to AAT mappings for “hist” and “vrtr” features.
+  (Florian Pircher)
+- Update IANA Language Subtag Registry to 2022-03-02. (David Corbett)
+- Update USE shaper to allow any non-numeric tail in a symbol cluster, and
+  remove obsolete data overrides. (David Corbett)
+- Fix handling of baseline variations to return correctly scaled values.
+  (Matthias Clasen)
+- A new experimental hb_subset_repack_or_fail() to repack an array of objects,
+  eliminating offset overflows. The API is not available unless HarfBuzz is
+  built with experimental APIs enabled. (Qunxin Liu)
+
+- New experimental API
++hb_link_t
++hb_object_t
++hb_subset_repack_or_fail()
+
+
+Overview of changes leading to 4.0.0
+Tuesday, March 1, 2022
+====================================
+- New public API to create subset plan and gather information on things like
+  glyph mappings in the final subset. The plan can then be passed on to perform
+  the subsetting operation. (Garret Rieger)
+- Draw API for extracting glyph shapes have been extended and finalized and is
+  no longer an experimental API. The draw API supports glyf, CFF and CFF2
+  glyph outlines tables, and applies variation settings set on the font as well
+  as synthetic slant. The new public API is not backward compatible with the
+  previous, non-public, experimental API. (Behdad Esfahbod)
+- The hb-view tool will use HarfBuzz draw API to render the glyphs instead of
+  cairo-ft when compiled with Cairo 1.17.5 or newer, setting HB_DRAW
+  environment variable to 1 or 0 will force using or not use the draw API,
+  respectively. (Behdad Esfahbod)
+- The hb-shape and hb-view tools now default to using HarfBuzz’s own font
+  loading functions (ot) instead of FreeType ones (ft). They also have a new
+  option, --font-slant, to apply synthetic slant to the font. (Behdad Esfahbod)
+- HarfBuzz now supports more than 65535 (the OpenType limit) glyph shapes and
+  metrics. See https://github.com/be-fonts/boring-expansion-spec/issues/6 and
+  https://github.com/be-fonts/boring-expansion-spec/issues/7 for details.
+  (Behdad Esfahbod)
+- New API to get the dominant horizontal baseline tag for a given script.
+  (Behdad Esfahbod)
+- New API to get the baseline positions from the font, and synthesize missing
+  ones. As well as new API to get font metrics and synthesize missing ones.
+  (Matthias Clasen)
+- Improvements to finding dependencies on Windows when building with Visual
+  Studio. (Chun-wei Fan)
+- New buffer flag, HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT, that must be set
+  during shaping for HB_GLYPH_FLAG_UNSAFE_TO_CONCAT flag to be reliably
+  produced. This is to limit the performance hit of producing this flag to when
+  it is actually needed. (Behdad Esfahbod)
+- Documentation improvements. (Matthias Clasen)
+
+- New API
+ - General:
+   +HB_BUFFER_FLAG_PRODUCE_UNSAFE_TO_CONCAT
+   +hb_var_num_t
+
+ - Draw:
+   +hb_draw_funcs_t
+   +hb_draw_funcs_create()
+   +hb_draw_funcs_reference()
+   +hb_draw_funcs_destroy()
+   +hb_draw_funcs_is_immutable()
+   +hb_draw_funcs_make_immutable()
+   +hb_draw_move_to_func_t
+   +hb_draw_funcs_set_move_to_func()
+   +hb_draw_line_to_func_t
+   +hb_draw_funcs_set_line_to_func()
+   +hb_draw_quadratic_to_func_t
+   +hb_draw_funcs_set_quadratic_to_func()
+   +hb_draw_cubic_to_func_t
+   +hb_draw_funcs_set_cubic_to_func()
+   +hb_draw_close_path_func_t
+   +hb_draw_funcs_set_close_path_func()
+   +hb_draw_state_t
+   +HB_DRAW_STATE_DEFAULT
+   +hb_draw_move_to()
+   +hb_draw_line_to()
+   +hb_draw_quadratic_to()
+   +hb_draw_cubic_to()
+   +hb_draw_close_path()
+   +hb_font_get_glyph_shape_func_t
+   +hb_font_funcs_set_glyph_shape_func()
+   +hb_font_get_glyph_shape()
+
+ - OpenType layout
+   +HB_OT_LAYOUT_BASELINE_TAG_IDEO_FACE_CENTRAL
+   +HB_OT_LAYOUT_BASELINE_TAG_IDEO_EMBOX_CENTRAL
+   +hb_ot_layout_get_horizontal_baseline_tag_for_script()
+   +hb_ot_layout_get_baseline_with_fallback()
+
+ - Metrics:
+   +hb_ot_metrics_get_position_with_fallback()
+
+ - Subset:
+   +hb_subset_plan_t
+   +hb_subset_plan_create_or_fail()
+   +hb_subset_plan_reference()
+   +hb_subset_plan_destroy()
+   +hb_subset_plan_set_user_data()
+   +hb_subset_plan_get_user_data()
+   +hb_subset_plan_execute_or_fail()
+   +hb_subset_plan_unicode_to_old_glyph_mapping()
+   +hb_subset_plan_new_to_old_glyph_mapping()
+   +hb_subset_plan_old_to_new_glyph_mapping()
+
+
+Overview of changes leading to 3.4.0
+Sunday, February 13, 2022
+====================================
+- Perform sanity checks on shaping results is now part of “harfbuzz” library
+  and can be enabled by setting the buffer flag HB_BUFFER_FLAG_VERIFY.
+  (Behdad Esfahbod)
+- Arabic Mark Transient Reordering Algorithm have been updated to revision 6.
+  (Khaled Hosny)
+- ISO 15924 code for mathematical notation, ‘Zmth’, now maps to the OpenType
+  ‘math’ tag. (Alexis King)
+- It is now possible to get at once all math kerning values for a given glyph
+  at a given corner. (Alexis King)
+- Fix locale_t portability issues on systems the typedef’s it to a void
+  pointer. (Behdad Esfahbod)
+
+- New API:
++HB_BUFFER_FLAG_VERIFY
++HB_OT_TAG_MATH_SCRIPT
++HB_SCRIPT_MATH
++hb_ot_math_kern_entry_t
++hb_ot_math_get_glyph_kernings()
+
+- Deprecated API
++HB_OT_MATH_SCRIPT
+
+
+Overview of changes leading to 3.3.2
+Sunday, February 6, 2022
+====================================
+- Revert splitting of pair positioning values introduced in 3.3.0 as it proved
+  problematic. (Behdad Esfahbod)
+
+
+Overview of changes leading to 3.3.1
+Monday, January 31, 2022
+====================================
+- Fix heap-use-after-free in harfbuzz-subset introduced in previous release.
+  (Garret Rieger)
+
+
+Overview of changes leading to 3.3.0
+Monday, January 31, 2022
+====================================
+- Improved documentation. (Matthias Clasen)
+- Internal code cleanup, using C++ standard library more. (Behdad Esfahbod)
+- The low 16-bits of face index will be used by hb_face_create() to select a
+  face inside a font collection file format, while the high 16-bits will be
+  used by hb_font_create() to load the named instance. (Behdad Esfahbod)
+- Glyph positions and other font metrics now apply synthetic slant set by
+  hb_font_set_synthetic_slant(), for improved positioning for synthetically
+  slanted fonts. (Behdad Esfahbod)
+- Fixed unintentional locale dependency in hb_variation_to_string() for decimal
+  point representation. (Matthias Clasen)
+- When applying pair positioning (kerning) the positioning value is split
+  between the two sides of the pair for improved cursor positioning between
+  such pairs. (Behdad Esfahbod)
+- Introduced new HB_GLYPH_FLAG_UNSAFE_TO_CONCAT, to be used in conjunction
+  with HB_GLYPH_FLAG_UNSAFE_TO_BREAK for optimizing re-shaping during line
+  breaking. Check the documentation for further details. (Behdad Esfahbod)
+- Improved handling of macrolanguages when mapping BCP 47 codes to OpenType
+  tags. (David Corbett)
+
+- New API:
++HB_GLYPH_FLAG_UNSAFE_TO_CONCAT
++hb_segment_properties_overlay()
++hb_buffer_create_similar()
++hb_font_set_synthetic_slant()
++hb_font_get_synthetic_slant()
++hb_font_get_var_coords_design()
+
+
+Overview of changes leading to 3.2.0
+Friday, November 26, 2021
+====================================
+“harfbuzz” library improvements:
+- Fixed shaping of Apple Color Emoji flags in right-to-left context. (Behdad Esfahbod)
+- Fixed positioning of CFF fonts in HB_TINY profile. (Behdad Esfahbod)
+- OpenType 1.9 language tags update. (David Corbett)
+- Add HB_NO_VERTICAL config option.
+- Add HB_CONFIG_OVERRIDE_H for easier configuration. (Behdad Esfahbod)
+
+“harfbuzz-subset” library improvements:
+- Improved packing of cmap, loca, and Ligature tables. (Garret Rieger)
+- Significantly improved overflow-resolution strategy in the repacker. (Garret Rieger)
+
+
+Overview of changes leading to 3.1.2
+Friday, November 26, 2021
+====================================
+- hb-shape / hb-view: revert treating text on the commandline as single
+  paragraph (was introduced in 3.0.0); add new --single-par to do that.
+  (Behdad Esfahbod)
+- Subsetter bug fixes. (Garret Rieger, Qunxin Liu, Behdad Esfahbod)
+
+
+Overview of changes leading to 3.1.1
+Wednesday, November 8, 2021
+====================================
+- Work around GCC cast-align error/warning on some platforms. (Behdad Esfahbod)
+- Documentation improvements. (Matthias Clasen)
+
+
+Overview of changes leading to 3.1.0
+Wednesday, November 3, 2021
+====================================
+- Better offset-overflow handling in the subsetter library. (Garret Rieger)
+- Improved Unicode 14 properties in the USE shaper, and various other USE
+  shaper fixes. (David Corbett)
+- MATH and COLR v1 tables subsetting support, and various other subsetter fixes.
+  (Qunxin Liu)
+- Support for Pwo Karen / Ason Chin medial la. (Simon Cozens)
+- Apply GPOS positioning when substituting with morx table, if kerx is missing.
+  (Behdad Esfahbod)
+- Apply calt and clig features across syllable boundaries in Indic shaper.
+  (Behdad Esfahbod)
+- meson option for enabling Graphite 2 has been renamed to graphite2.
+- Build and documentation fixes.
+
+- New API:
++hb_buffer_set_not_found_glyph()
++hb_buffer_get_not_found_glyph()
+
+
+Overview of changes leading to 3.0.0
+Friday, September 17, 2021
+====================================
+- Unicode 14.0 support (David Corbett).
+- The hb-subset API and the harfbuzz-subset library's ABI are now declared
+  stable. The harfbuzz-subset library would not have been possible without the
+  work of Garret Rieger and Qunxin Liu from Google Fonts, and the earlier work
+  of Michiharu Ariza from Adobe.
+- The hb-style API is now stable and no longer experimental.
+
+- New API:
++hb_style_tag_t
++hb_style_get_value()
++hb_subset_input_t
++hb_subset_flags_t
++hb_subset_sets_t
++hb_subset_input_create_or_fail()
++hb_subset_input_reference()
++hb_subset_input_destroy()
++hb_subset_input_set_user_data()
++hb_subset_input_get_user_data()
++hb_subset_input_unicode_set()
++hb_subset_input_glyph_set()
++hb_subset_input_set()
++hb_subset_input_get_flags()
++hb_subset_input_set_flags()
++hb_subset_or_fail()
+
+- Removed old unstable harfbuzz-subset API:
+-hb_subset_input_nameid_set()
+-hb_subset_input_namelangid_set()
+-hb_subset_input_layout_features_set()
+-hb_subset_input_no_subset_tables_set()
+-hb_subset_input_drop_tables_set()
+-hb_subset_input_set_drop_hints()
+-hb_subset_input_get_drop_hints()
+-hb_subset_input_set_desubroutinize()
+-hb_subset_input_get_desubroutinize()
+-hb_subset_input_set_retain_gids()
+-hb_subset_input_get_retain_gids()
+-hb_subset_input_set_name_legacy()
+-hb_subset_input_get_name_legacy()
+-hb_subset_input_set_overlaps_flag()
+-hb_subset_input_get_overlaps_flag()
+-hb_subset_input_set_notdef_outline()
+-hb_subset_input_get_notdef_outline()
+-hb_subset_input_set_no_prune_unicode_ranges()
+-hb_subset_input_get_no_prune_unicode_ranges()
+-hb_subset()
+
+
+Overview of changes leading to 2.9.1
+Tuesday, September 7, 2021
+====================================
+- Final subset API is in place and if no issues are discovered, it will be the
+  stable subset API of HarfBuzz 3.0.0. Old API is kept to ease transition, but
+  will be removed in 3.0.0.
+- Various fuzzer-found bug fixes.
+- hb_buffer_append() now handles the pre- and post-context which previously
+  were left unchanged in the destination buffer.
+- hb-view / hb-shape now accept following new arguments:
+  o --unicodes-before/after: takes a list of hex numbers that represent Unicode
+    codepoints.
+- Undeprecated API:
+  hb_set_invert()
+
+
+Overview of changes leading to 2.9.0
+Wednesday, August 18, 2021
+History Repeats Itself (Afghanistan)
+====================================
+- Subsetter API is being stabilized, with the first stable API to happen in
+  3.0.0 release (https://github.com/harfbuzz/harfbuzz/issues/3078).
+- Support multiple variation axes with same tag, aka HOI.
+- The “coretext” testing shaper now passes font variations to CoreText.
+- hb-shape/hb-view does not break line at new lines unless text is read from
+  file.
+- hb-view and hb-subset has a --batch now, similar to hb-shape.
+- The --batch mode now uses ; as argument separator instead of : used previously.
+- The --batch in hb-shape does not expect 0th argument anymore. That is, the
+  lines read are interpreted as argv[1:], instead of argv[0:].
+- The --batch option has been undocumented. We are ready to document it; send
+  feedback if you find it useful.
+- hb-subset got arguments revamps. Added much-requested --gids-file, --glyphs,
+  --glyphs-file, --unicodes-file, supporting ranges in --unicodes.
+- Various bug fixes.
+
+
+Overview of changes leading to 2.8.2
+Tuesday, July 8, 2021
+====================================
+- Shaping LTR digits for RTL scripts now makes the native direction of the
+  digits LTR, applying shaping and positioning rules on the same glyph order as
+  Uniscribe. (Jonathan Kew, Khaled Hosny).
+- Subsetting COLR v1 and CPAL tables is now supported. (Garret Rieger, Qunxin Liu)
+- Various fixes and improvements to the subsetter. (Garret Rieger, Qunxin Liu, Behdad)
+- When applying morx table, mark glyph widths should not be zeroed. (Jonathan Kew)
+- GPOS is preferred over kerx, if GSUB was applied. (Behdad)
+- Regional_Indicator pairs are grouped together when clustering. (Behdad)
+- New API:
++hb_blob_create_or_fail()
++hb_blob_create_from_file_or_fail()
++hb_set_copy()
+
+
+Overview of changes leading to 2.8.1
+Tuesday, May 4, 2021
+====================================
+- Subsetter now fully supports GSUB/GPOS/GDEF tables (including variations); as
+  such, layout tables are retained by subsetter by default. (Garret Rieger, Qunxin Liu)
+- Build scripts no longer check for FontConfig as HarfBuzz does not use it.
+- hb-view supports iTerm2 and kitty inline image protocols (Khaled Hosny),
+  it can also use Chafa for terminal graphics if available (Hans Petter Jansson).
+
+Overview of changes leading to 2.8.0
+Tuesday, March 16, 2021
+====================================
+- Shape joining scripts other than Arabic/Syriac using the Universal Shaping Engine.
+  Previously these were shaped using the generalized Arabic shaper. (David Corbett)
+- Fix regression in shaping of U+0B55 ORIYA SIGN OVERLINE. (David Corbett)
+- Update language tags. (David Corbett)
+- Variations: reduce error: do not round each interpolated delta. (Just van Rossum)
+- Documentation improvements. (Khaled Hosny, Nathan Willis)
+- Subsetter improvements: subsets most, if not all, lookup types now. (Garret Rieger, Qunxin Liu)
+- Fuzzer-found fixes and other improvements when memory failures happen. (Behdad)
+- Removed most atomic implementations now that we have C++11 atomic impl. (Behdad)
+- General codebase upkeep; using more C++11 features: constexpr constructors, etc. (Behdad)
+
+
+Overview of changes leading to 2.7.4
+Sunday, December 27, 2020
+====================================
+- Fix missing --enable-introspection configure option from previous release
+  tarball.
+- Documentation updates.
+
+
+Overview of changes leading to 2.7.3
+Wednesday, December 23, 2020
+====================================
+- Update USE shaper to 2020-08-13 specification, and other improvements.
+- Don’t disable liga feature in myanmar shaper, to match Uniscribe.
+- Improvements to language and script tags handling.
+- Update language system tag registry to OpenType 1.8.4
+- Support for serializing and deserializing Unicode buffers. Serialized buffers
+  are now delimited with `<>` or `[]` based on whether it is a Unicode or
+  glyphs buffer.
+- Increase buffer work limits to handle fonts with many complex lookups.
+- Handle more shaping operations in trace output.
+- Memory access fixes.
+- More OOM fixes.
+- Improved documentation.
+- Build system improvements.
+- New API:
++hb_buffer_has_positions()
++hb_buffer_serialize()
++hb_buffer_serialize_unicode()
++hb_buffer_deserialize_unicode()
+
+
+Overview of changes leading to 2.7.2
+Saturday, August 29, 2020
+====================================
+- Fix a regression in the previous release that caused a crash with Kaithi.
+- More OOM fixes.
+
+
+Overview of changes leading to 2.7.1
+Thursday, August 13, 2020
+====================================
+- ot-funcs now handles variable empty glyphs better when hvar/vvar isn't present.
+- Reverted a GDEF processing regression.
+- A couple of fixes to handle OOM better.
+
+
+Overview of changes leading to 2.7.0
+Saturday, July 25, 2020
+====================================
+- Use an implementation for round that always rounds up, some minor fluctuations
+  are expected on var font specially when hb-ot callback is used.
+- Fix an AAT's `kerx` issue on broken rendering of Devanagari Sangam MN.
+- Remove AAT's `lcar` table support from _get_ligature_carets API, not even much
+  use on macOS installed fonts (only two files).  GDEF support is the recommended
+  one and expected to work properly after issues fixed two releases ago.
+- Minor memory fixes to handle OOM better specially in hb-ft.
+- Minor .so files versioning scheme change and remove stable/unstable scheme
+  differences, was never used in practice (always default to stable scheme).
+- We are now suggesting careful packaging of the library using meson,
+  https://github.com/harfbuzz/harfbuzz/wiki/Notes-on-migration-to-meson
+  for more information.
+- Distribution package URL is changed, either use GitHub generated tarballs,
+  `https://github.com/harfbuzz/harfbuzz/archive/$pkgver.tar.gz`
+  or, even more preferably use commit hash of the release and git checkouts like,
+  `git+https://github.com/harfbuzz/harfbuzz#commit=$commit`
+
+
+Overview of changes leading to 2.6.8
+Monday, June 22, 2020
+====================================
+- New API to fetch glyph alternates from GSUB table.
+- hb-coretext build fix for macOS < 10.10.
+- Meson build fixes, cmake port removal is postponed but please prepare for
+  it and give us feedback.
+  Autotools is still our main build system however please consider
+  experimenting with meson also for packaging the library.
+- New API:
++hb_ot_layout_lookup_get_glyph_alternates()
+
+
+Overview of changes leading to 2.6.7
+Wednesday, June 3, 2020
+====================================
+- Update to Unicode 13.0.0.
+- Fix hb_ot_layout_get_ligature_carets for fonts without lcar table, it was
+  completely broken for all the other fonts since 2.1.2.
+- As a part of our migration to meson, this release will be the last one
+  to provide cmake port files but autotools still is our main build system.
+  There is a possibility that the next version or the after be released
+  using meson.
+
+
+Overview of changes leading to 2.6.6
+Tuesday, May 12, 2020
+====================================
+- A fix in AAT kerning for Geeza Pro.
+- Better support for resource fork fonts on macOS.
+
+
+Overview of changes leading to 2.6.5
+Friday, April 17, 2020
+====================================
+- Add experimental meson build system.  Autotools is still the primary
+  and supported build system.
+- AAT is now always preferred for horizontal scripts when both AAT and OT
+  layout tables exist at the same time.
+- Subsetter improvements.
+- New API:
++hb_ft_font_lock_face()
++hb_ft_font_unlock_face()
+
+
+Overview of changes leading to 2.6.4
+Monday, October 29, 2019
+====================================
+- Small bug fix.
+- Build fixes.
+
+
+Overview of changes leading to 2.6.3
+Monday, October 28, 2019
+====================================
+- Misc small fixes, mostly to build-related issues.
+- New API:
++hb_font_get_nominal_glyphs()
+
+
+Overview of changes leading to 2.6.2
+Monday, September 30, 2019
+====================================
+- Misc small fixes, mostly to build-related issues.
+
+
+Overview of changes leading to 2.6.1
+Thursday, August 22, 2019
+====================================
+- Fix regression with hb_font_create_sub_font scaling introduced in 2.6.0.
+- Change interpretation of font PTEM size / CoreText font size handling.
+  See https://github.com/harfbuzz/harfbuzz/pull/1484
+- hb-ot-font: Prefer symbol cmap subtable if present.
+- Apply 'dist'/'abvm'/'blwm' features to all scripts.
+- Drop experimental DirectWrite API.
+
+
+Overview of changes leading to 2.6.0
+Tuesday, August 13, 2019
+====================================
+- New OpenType metrics, baseline, and metadata table access APIs.
+- New API to set font variations to a named-instance.
+- New hb-gdi.h header and API for creating hb_face_t from HFONT.
+- Amalgam: Provide a single-file harfbuzz.cc file for easier alternate building.
+- More size-reduction configurable options, enabled by HB_TINY.
+- New API:
++hb_font_set_var_named_instance()
++hb_gdi_face_create()
++hb_ot_layout_baseline_tag_t
++hb_ot_layout_get_baseline()
++hb_ot_meta_tag_t
++hb_ot_meta_get_entry_tags()
++hb_ot_meta_reference_entry()
++hb_ot_metrics_tag_t
++hb_ot_metrics_get_position()
++hb_ot_metrics_get_variation()
++hb_ot_metrics_get_x_variation()
++hb_ot_metrics_get_y_variation()
+
+
+Overview of changes leading to 2.5.3
+Wednesday, June 26, 2019
+====================================
+- Fix UCD script data for Unicode 10+ scripts.  This was broken since 2.5.0.
+- More optimizations for HB_TINY.
+
+
+Overview of changes leading to 2.5.2
+Thursday, June 20, 2019
+====================================
+- More hb-config.hh facilities to shrink library size, namely when built as
+  HB_TINY.
+- New documentation of custom configurations in CONFIG.md.
+- Fix build on gcc 4.8.  That's supported again.
+- Universal Shaping Engine improvements thanks to David Corbett.
+- API Changes: Undeprecate some horizontal-kerning API and re-enable in hb-ft,
+  such that Type1 fonts will continue kerning.
+
+
+Overview of changes leading to 2.5.1
+Friday, May 31, 2019
+====================================
+- Fix build with various versions of Visual Studio.
+- Improved documentation, thanks to Nathan Willis.
+- Bugfix in subsetting glyf table.
+- Improved scripts for cross-compiling for Windows using mingw.
+- Rename HB_MATH_GLYPH_PART_FLAG_EXTENDER to HB_OT_MATH_GLYPH_PART_FLAG_EXTENDER.
+  A deprecated macro is added for backwards-compatibility.
+
+
+Overview of changes leading to 2.5.0
+Friday, May 24, 2019
+====================================
+- This release does not include much functional changes, but includes major internal
+  code-base changes.  We now require C++11.  Support for gcc 4.8 and earlier has been
+  dropped.
+- New hb-config.hh facility for compiling smaller library for embedded and web usecases.
+- New Unicode Character Database implementation that is half the size of previously-used
+  UCDN.
+- Subsetter improvements.
+- Improved documentation, thanks to Nathan Willis.
+- Misc shaping fixes.
+
+
+Overview of changes leading to 2.4.0
+Monday, March 25, 2019
+====================================
+- Unicode 12.
+- Misc fixes.
+- Subsetter improvements.
+- New API:
+HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE
+hb_directwrite_face_create()
+
+
+Overview of changes leading to 2.3.1
+Wednesday, January 30, 2019
+====================================
+- AAT bug fixes.
+- Misc internal housekeeping cleanup.
+
+
+Overview of changes leading to 2.3.0
+Thursday, December 20, 2018
+====================================
+- Fix regression on big-endian architectures.  Ouch!
+- Misc bug and build fixes.
+- Fix subsetting of simple GSUB/GDEF.
+- Merge CFF / CFF2 support contributed by Adobe.  This mostly involves
+  the subsetter, but also get_glyph_extents on CFF fonts.
+
+New API in hb-aat.h:
++hb_aat_layout_has_substitution()
++hb_aat_layout_has_positioning()
++hb_aat_layout_has_tracking()
+
+
+Overview of changes leading to 2.2.0
+Thursday, November 29, 2018
+====================================
+- Misc shaping bug fixes.
+- Add font variations named-instance API.
+- Deprecate font variations axis enumeration API and add replacement.
+- AAT shaping improvements:
+  o Fixed 'kern' table Format 2 implementation.
+  o Implement 'feat' table API for feature detection.
+  o Blacklist 'GSUB' table of fonts from 'MUTF' foundry that also have 'morx'.
+
+New API:
++hb_aat_layout_feature_type_t
++hb_aat_layout_feature_selector_t
++hb_aat_layout_get_feature_types()
++hb_aat_layout_feature_type_get_name_id
++hb_aat_layout_feature_selector_info_t
++HB_AAT_LAYOUT_NO_SELECTOR_INDEX
++hb_aat_layout_feature_type_get_selector_infos()
++hb_ot_var_axis_flags_t
++hb_ot_var_axis_info_t
++hb_ot_var_get_axis_infos()
++hb_ot_var_find_axis_info()
++hb_ot_var_get_named_instance_count()
++hb_ot_var_named_instance_get_subfamily_name_id()
++hb_ot_var_named_instance_get_postscript_name_id()
++hb_ot_var_named_instance_get_design_coords()
+
+Deprecated API:
++HB_OT_VAR_NO_AXIS_INDEX
++hb_ot_var_axis_t
++hb_ot_var_get_axes()
++hb_ot_var_find_axis()
+
+
+Overview of changes leading to 2.1.3
+Friday, November 16, 2018
+====================================
+- Fix AAT 'mort' shaping, which was broken in 2.1.2
+
+
+Overview of changes leading to 2.1.2
+Friday, November 16, 2018
+====================================
+- Various internal changes.
+- AAT shaping improvements:
+  o Implement kern table Format 1 state-machine-based kerning.
+  o Implement cross-stream kerning (cursive positioning, etc).
+  o Ignore emptyish GSUB tables (zero scripts) if morx present.
+  o Don't apply GPOS if morx is being applied.  Matches Apple.
+
+
+-Overview of changes leading to 2.1.1
+Monday, November 5, 2018
+====================================
+- AAT improvements:
+  o Implement 'mort' table.
+  o Implement 'kern' subtables Format 1 and Format 3.
+
+
+Overview of changes leading to 2.1.0
+Tuesday, October 30, 2018
+====================================
+- AAT shaping improvements:
+  o Allow user controlling AAT features, for whole buffer only currently.
+  o Several 'morx' fixes.
+  o Implement tuple-kerns in 'kerx'; Fixes kerning with Apple default
+    San Francisco fonts.
+- Support for color fonts:
+  o COLR/CPAL API to fetch color layers.
+  o SVG table to fetch SVG documents.
+  o CBDT/sbix API to fetch PNG images.
+- New 'name' table API.
+- hb-ot-font now uses 'VORG' table to correctly position CFF glyphs
+  in vertical layout.
+- Various fuzzer-found bug fixes.
+
+Changed API:
+
+A type and a macro added in 2.0.0 were renamed:
+
+hb_name_id_t -> hb_ot_name_id_t
+HB_NAME_ID_INVALID -> HB_OT_NAME_ID_INVALID
+
+New API:
+
++hb_color_t
++HB_COLOR
++hb_color_get_alpha()
++hb_color_get_red()
++hb_color_get_green()
++hb_color_get_blue()
++hb_ot_color_has_palettes()
++hb_ot_color_palette_get_count()
++hb_ot_color_palette_get_name_id()
++hb_ot_color_palette_color_get_name_id()
++hb_ot_color_palette_flags_t
++hb_ot_color_palette_get_flags()
++hb_ot_color_palette_get_colors()
++hb_ot_color_has_layers()
++hb_ot_color_layer_t
++hb_ot_color_glyph_get_layers()
++hb_ot_color_has_svg()
++hb_ot_color_glyph_reference_svg()
++hb_ot_color_has_png()
++hb_ot_color_glyph_reference_png()
+
++hb_ot_name_id_t
++HB_OT_NAME_ID_INVALID
++HB_OT_NAME_ID_COPYRIGHT
++HB_OT_NAME_ID_FONT_FAMILY
++HB_OT_NAME_ID_FONT_SUBFAMILY
++HB_OT_NAME_ID_UNIQUE_ID
++HB_OT_NAME_ID_FULL_NAME
++HB_OT_NAME_ID_VERSION_STRING
++HB_OT_NAME_ID_POSTSCRIPT_NAME
++HB_OT_NAME_ID_TRADEMARK
++HB_OT_NAME_ID_MANUFACTURER
++HB_OT_NAME_ID_DESIGNER
++HB_OT_NAME_ID_DESCRIPTION
++HB_OT_NAME_ID_VENDOR_URL
++HB_OT_NAME_ID_DESIGNER_URL
++HB_OT_NAME_ID_LICENSE
++HB_OT_NAME_ID_LICENSE_URL
++HB_OT_NAME_ID_TYPOGRAPHIC_FAMILY
++HB_OT_NAME_ID_TYPOGRAPHIC_SUBFAMILY
++HB_OT_NAME_ID_MAC_FULL_NAME
++HB_OT_NAME_ID_SAMPLE_TEXT
++HB_OT_NAME_ID_CID_FINDFONT_NAME
++HB_OT_NAME_ID_WWS_FAMILY
++HB_OT_NAME_ID_WWS_SUBFAMILY
++HB_OT_NAME_ID_LIGHT_BACKGROUND
++HB_OT_NAME_ID_DARK_BACKGROUND
++HB_OT_NAME_ID_VARIATIONS_PS_PREFIX
++hb_ot_name_entry_t
++hb_ot_name_list_names()
++hb_ot_name_get_utf8()
++hb_ot_name_get_utf16()
++hb_ot_name_get_utf32()
+
+
+Overview of changes leading to 2.0.2
+Saturday, October 20, 2018
+====================================
+- Fix two minor memory access issues in AAT tables.
+
+
+Overview of changes leading to 2.0.1
+Friday, October 19, 2018
+====================================
+- Fix hb-version.h reported release version that went wrong (1.8.0)
+  with previous release.
+- Fix extrapolation in 'trak' table.
+- Fix hb-font infinite-recursion issue with some font funcs and
+  subclassed fonts.
+- Implement variation-kerning format in kerx table, although without
+  variation.
+- Fix return value of hb_map_is_empty().
+
+
+Overview of changes leading to 2.0.0
+Thursday, October 18, 2018
+====================================
+- Added AAT shaping support (morx/kerx/trak).
+  Automatically used if GSUB/GPOS are not available respectively.
+  Set HB_OPTIONS=aat env var to have morx/kerx preferred over
+  GSUB/GPOS.
+- Apply TrueType kern table internally, instead of relying on
+  hb_font_t callbacks.
+- Khmer shaper significantly rewritten to better match Uniscribe.
+- Indic3 tags ('dev3', etc) are passed to USE shaper.
+- .dfont Mac font containers implemented.
+- Script- and language-mapping revamped to better use BCP 47.
+- Misc USE and Indic fixes.
+- Misc everything fixes.
+- Too many things to list.  Biggest release since 0.9.1, with
+  over 500 commits in just over 5 weeks!  Didn't intend it to
+  be a big release.  Just happened to become.
+- hb-ft now locks underlying FT_Face during use.
+
+API changes:
+
+- Newly-created hb_font_t's now have our internal "hb-ot-font"
+  callbacks set on them, so they should work out of the box
+  without any callbacks set.  If callbacks are set, everything
+  is back to what it was before, the fallback callbacks are
+  null.  If you to get the internal implementation modified,
+  sub_font it.
+
+- New hb_font_funcs_set_nominal_glyphs_func() allows speeding
+  up character to glyph mapping.
+
+New API:
++HB_FEATURE_GLOBAL_START
++HB_FEATURE_GLOBAL_END
++hb_buffer_set_invisible_glyph()
++hb_buffer_get_invisible_glyph()
++hb_font_funcs_set_nominal_glyphs_func()
++hb_ot_layout_table_select_script()
++hb_ot_layout_script_select_language()
++hb_ot_layout_feature_get_name_ids()
++hb_ot_layout_feature_get_characters()
++hb_name_id_t
++HB_NAME_ID_INVALID
++HB_OT_MAX_TAGS_PER_SCRIPT
++hb_ot_tags_from_script_and_language()
++hb_ot_tags_to_script_and_language()
+
+Deprecated API:
+-hb_font_funcs_set_glyph_func()
+-hb_unicode_eastasian_width_func_t
+-hb_unicode_funcs_set_eastasian_width_func()
+-hb_unicode_eastasian_width()
+-hb_unicode_decompose_compatibility_func_t
+-HB_UNICODE_MAX_DECOMPOSITION_LEN
+-hb_unicode_funcs_set_decompose_compatibility_func()
+-hb_unicode_decompose_compatibility()
+-hb_font_funcs_set_glyph_h_kerning_func()
+-hb_font_funcs_set_glyph_v_kerning_func()
+-hb_font_get_glyph_h_kerning()
+-hb_font_get_glyph_v_kerning()
+-hb_font_get_glyph_kerning_for_direction()
+-hb_ot_layout_table_choose_script()
+-hb_ot_layout_script_find_language()
+-hb_ot_tags_from_script()
+-hb_ot_tag_from_language()
+
+
+Overview of changes leading to 1.9.0
+Monday, September 10, 2018
+====================================
+- Added 'cmap' API to hb_face_t.
+- Face-builder API.
+- hb-ot-font re-creation should be much leaner now, as the
+  font tables it uses are cached on hb_face_t now.
+- Internal source header file name changes:
+  hb-*-private.hh is renamed to hb-*.hh.
+
+New API:
++HB_UNICODE_MAX
++hb_face_collect_unicodes()
++hb_face_collect_variation_selectors()
++hb_face_collect_variation_unicodes()
++hb_face_builder_create()
++hb_face_builder_add_table()
+
+
+Overview of changes leading to 1.8.8
+Tuesday, August 14, 2018
+====================================
+- Fix hb-icu crash on architectures where compare_exchange_weak() can
+  fail falsely.  This bug was introduced in 1.8.4.
+  https://bugs.chromium.org/p/chromium/issues/detail?id=873568
+- More internal refactoring of atomic operations and singletons.
+- API changes:
+  The following functions do NOT reference their return value before
+  returning:
+  * hb_unicode_funcs_get_default()
+  * hb_glib_get_unicode_funcs()
+  * hb_icu_get_unicode_funcs()
+  This is consistent with their naming ("get", instead of "reference")
+  as well as how they are used in the wild (ie. no one calls destroy()
+  on their return value.)
+
+
+Overview of changes leading to 1.8.7
+Wednesday, August 8, 2018
+====================================
+- Fix assertion failure with GDEF-blacklisted fonts.
+
+
+Overview of changes leading to 1.8.6
+Tuesday, August 7, 2018
+====================================
+- Internal code shuffling.
+- New API to speed up getting advance widths for implementations
+  that have heavy overhead in get_h_advance callback:
++hb_font_funcs_set_glyph_h_advances_func
++hb_font_funcs_set_glyph_v_advances_func
++hb_font_get_glyph_advances_for_direction
++hb_font_get_glyph_h_advances
++hb_font_get_glyph_h_advances_func_t
++hb_font_get_glyph_v_advances
++hb_font_get_glyph_v_advances_func_t
+
+
+Overview of changes leading to 1.8.5
+Wednesday, August 1, 2018
+====================================
+- Major Khmer shaper improvements to better match Microsoft.
+- Indic bug fixes.
+- Internal improvements to atomic operations.
+
+
+Overview of changes leading to 1.8.4
+Tuesday, July 17, 2018
+====================================
+- Fix build on non-C++11.
+- Use C++-style GCC atomics and C++11 atomics.
+
+
+Overview of changes leading to 1.8.3
+Wednesday, July 11, 2018
+====================================
+- A couple of Indic / USE bug fixes.
+- Disable vectorization, as it was causing unaligned access bus error on
+  certain 32bit architectures.
+
+
+Overview of changes leading to 1.8.2
+Tuesday, July 3, 2018
+====================================
+- Fix infinite loop in Khmer shaper.
+- Improve hb_blob_create_from_file() for streams.
+
+
+Overview of changes leading to 1.8.1
+Tuesday, June 12, 2018
+====================================
+- Fix hb-version.h file generation; last two releases went out with wrong ones.
+- Add correctness bug in hb_set_t operations, introduced in 1.7.7.
+- Remove HB_SUBSET_BUILTIN build option.  Not necessary.
+
+
+Overview of changes leading to 1.8.0
+Tuesday, June 5, 2018
+====================================
+- Update to Unicode 11.0.0.
+
+
+Overview of changes leading to 1.7.7
+Tuesday, June 5, 2018
+====================================
+- Lots of internal changes, but not yet exposed externally.
+- All HarfBuzz objects are significantly smaller in size now.
+- Sinhala: Position repha on top of post-consonant, not base.
+  This better matches Windows 10 behavior, which was changed
+  from previous Windows versions.
+- New build options:
+  o New cpp macro HB_NO_ATEXIT
+  o New cpp macro HB_SUBSET_BUILTIN
+- Significant libharfbuzz-subset changes. API subject to change.
+- New API in libharfbuzz:
+
++hb_blob_create_from_file()
++hb_face_count()
+
+A hashmap implementation:
++hb-map.h
++HB_MAP_VALUE_INVALID
++hb_map_t
++hb_map_create()
++hb_map_get_empty()
++hb_map_reference()
++hb_map_destroy()
++hb_map_set_user_data()
++hb_map_get_user_data()
++hb_map_allocation_successful()
++hb_map_clear()
++hb_map_is_empty()
++hb_map_get_population()
++hb_map_set()
++hb_map_get()
++hb_map_del()
++hb_map_has()
+
+
+Overview of changes leading to 1.7.6
+Wednesday, March 7, 2018
+====================================
+
+- Fix to hb_set_t binary operations. Ouch.
+- New experimental harfbuzz-subset library. All of hb-subset.h
+  is experimental right now and API WILL change.
+
+- New API:
+hb_blob_copy_writable_or_fail()
+HB_OT_TAG_BASE
+hb_set_previous()
+hb_set_previous_range()
+
+
+Overview of changes leading to 1.7.5
+Tuesday, January 30, 2018
+====================================
+
+- Separate Khmer shaper from Indic.
+- First stab at AAT morx. Not hooked up.
+- Misc bug fixes.
+
+
+Overview of changes leading to 1.7.4
+Wednesday, December 20, 2017
+====================================
+
+- Fix collect_glyphs() regression caused by hb_set_t changes.
+
+
+Overview of changes leading to 1.7.3
+Monday, December 18, 2017
+====================================
+
+- hb_set_t performance tuning and optimizations.
+- Speed up collect_glyphs() and reject garbage data.
+- In hb_coretext_font_create() set font point-size (ptem).
+- Misc fixes.
+
+
+Overview of changes leading to 1.7.2
+Monday, December 4, 2017
+====================================
+
+- Optimize hb_set_add_range().
+- Misc fixes.
+- New API:
+hb_coretext_font_create()
+
+
+Overview of changes leading to 1.7.1
+Tuesday, November 14, 2017
+====================================
+
+- Fix atexit object destruction regression.
+- Fix minor integer-overflow.
+
+
+Overview of changes leading to 1.7.0
+Monday, November 13, 2017
+====================================
+
+- Minor Indic fixes.
+- Implement kerning and glyph names in hb-ot-font.
+- Various DSO optimization re .data and .bss sizes.
+- Make C++11 optional; build fixes.
+- Mark all other backends "unsafe-to-break".
+- Graphite fix.
+
+
+Overview of changes leading to 1.6.3
+Thursday, October 26th, 2017
+====================================
+
+- Fix hb_set_t some more.  Should be solid now.
+- Implement get_glyph_name() for hb-ot-font.
+- Misc fixes.
+
+
+Overview of changes leading to 1.6.2
+Monday, October 23nd, 2017
+====================================
+
+- Yesterday's release had a bad crasher; don't use it.  That's what
+  happens when one works on Sunday...
+  https://github.com/harfbuzz/harfbuzz/issues/578
+- Build fixes for FreeBSD and Chrome Android.
+
+
+Overview of changes leading to 1.6.1
+Sunday, October 22nd, 2017
+====================================
+
+- Don't skip over COMBINING GRAPHEME JOINER when ligating, etc.
+  To be refined: https://github.com/harfbuzz/harfbuzz/issues/554
+- Faster hb_set_t implementation.
+- Don't use deprecated ICU API.
+- Fix undefined-behavior in Myanmar shaper, introduced in 1.6.0
+- Deprecated API:
+  hb_set_invert()
+
+
+Overview of changes leading to 1.6.0
+Friday, October the 13th, 2017
+====================================
+
+- Update to Unicode 10.
+
+- Various Indic and Universal Shaping Engine fixes as a result of
+  HarfBuzz Hackfest with Jonathan Kew at Web Engines Hackfest at
+  the Igalia offices in A Coruña, Spain.  Thanks Igalia for having
+  us!
+
+- Implement Unicode Arabic Mark Ordering Algorithm UTR#53.
+
+- Implement optical sizing / tracking in CoreText backend, using
+  new API hb_font_set_ptem().
+
+- Allow notifying hb_font_t that underlying FT_Face changed sizing,
+  using new API hb_ft_font_changed().
+
+- More Graphite backend RTL fixes.
+
+- Fix caching of variable font shaping plans.
+
+- hb-view / hb-shape now accept following new arguments:
+
+  o --unicodes: takes a list of hex numbers that represent Unicode
+    codepoints.
+
+New API:
++hb_face_get_table_tags()
++hb_font_set_ptem()
++hb_font_get_ptem()
++hb_ft_font_changed()
+
+
+Overview of changes leading to 1.5.1
+Tuesday, September 5, 2017
+====================================
+
+- Fix "unsafe-to-break" in fallback shaping and other corner cases.
+  All our tests pass with --verify now, meaning unsafe-to-break API
+  works as expected.
+- Add --unicodes to hb-view / hb-shape.
+- [indic] Treat Consonant_With_Stacker as consonant.  This will need
+  further tweaking.
+- hb_buffer_diff() tweaks.
+
+
+Overview of changes leading to 1.5.0
+Wednesday, August 23, 2017
+====================================
+
+- Misc new API, for appending a buffer to another, and for comparing
+  contents of two buffers for types of differences.
+
+- New "unsafe-to-break" API.  Can be used to speed up reshaping
+  in line-breaking situations.  Essentially, after shaping, it returns
+  positions in the input string (some of the cluster boundaries) that
+  are "safe to break" in that if the text is segmented at that position
+  and two sides reshaped and concatenated, the shaping result is
+  exactly the same as shaping the text in one piece.
+
+  hb-view and hb-shape and hb-shape now take --verify, which verifies
+  the above property.
+
+  Some corner cases of the implementation are still not quite working.
+  Those will be fixed in subsequent releases.
+
+- New API:
+
+hb_buffer_append()
+
+hb_glyph_flags_t
+HB_GLYPH_FLAG_UNSAFE_TO_BREAK
+HB_GLYPH_FLAG_DEFINED
+hb_glyph_info_get_glyph_flags()
+
+HB_BUFFER_SERIALIZE_FLAG_GLYPH_FLAGS
+
+hb_buffer_diff_flags_t
+HB_BUFFER_DIFF_FLAG_EQUAL
+HB_BUFFER_DIFF_FLAG_CONTENT_TYPE_MISMATCH
+HB_BUFFER_DIFF_FLAG_LENGTH_MISMATCH
+HB_BUFFER_DIFF_FLAG_NOTDEF_PRESENT
+HB_BUFFER_DIFF_FLAG_DOTTED_CIRCLE_PRESENT
+HB_BUFFER_DIFF_FLAG_CODEPOINT_MISMATCH
+HB_BUFFER_DIFF_FLAG_CLUSTER_MISMATCH
+HB_BUFFER_DIFF_FLAG_GLYPH_FLAGS_MISMATCH
+HB_BUFFER_DIFF_FLAG_POSITION_MISMATCH
+hb_buffer_diff
+
+
+Overview of changes leading to 1.4.8
+Tuesday, August 8, 2017
+====================================
+
+- Major fix to avar table handling.
+- Rename hb-shape --show-message to --trace.
+- Build fixes.
+
+
+Overview of changes leading to 1.4.7
+Tuesday, July 18, 2017
+====================================
+
+- Multiple Indic, Tibetan, and Cham fixes.
+- CoreText: Allow disabling kerning.
+- Adjust Arabic feature order again.
+- Misc build fixes.
+
+
+Overview of changes leading to 1.4.6
+Sunday, April 23, 2017
+====================================
+
+- Graphite2: Fix RTL positioning issue.
+- Backlist GDEF of more versions of Padauk and Tahoma.
+- New, experimental, cmake alternative build system.
+
+
+Overview of changes leading to 1.4.5
+Friday, March 10, 2017
+====================================
+
+- Revert "Fix Context lookup application when moving back after a glyph..."
+  This introduced memory access problems.  To be fixed properly soon.
+
+
+Overview of changes leading to 1.4.4
+Sunday, March 5, 2017
+====================================
+
+- Fix Context lookup application when moving back after a glyph deletion.
+- Fix buffer-overrun in Bengali.
+
+
+Overview of changes leading to 1.4.3
+Saturday, February 25, 2017
+====================================
+
+- Route Adlam script to Arabic shaper.
+- Misc fixes.
+- New API:
+  hb_font_set_face()
+- Deprecate API:
+  hb_graphite2_font_get_gr_font()
+
+
+Overview of changes leading to 1.4.2
+Monday, January 23, 2017
+====================================
+
+- Implement OpenType Font Variation tables avar/fvar/HVAR/VVAR.
+- hb-shape and hb-view now accept --variations.
+- New API:
+
+hb_variation_t
+hb_variation_from_string()
+hb_variation_to_string()
+
+hb_font_set_variations()
+hb_font_set_var_coords_design()
+hb_font_get_var_coords_normalized()
+
+hb-ot-var.h:
+hb_ot_var_axis_t
+hb_ot_var_has_data()
+hb_ot_var_get_axis_count()
+hb_ot_var_get_axes()
+hb_ot_var_find_axis()
+hb_ot_var_normalize_variations()
+hb_ot_var_normalize_coords()
+
+- MVAR to be implemented later.  Access to named instances to be
+  implemented later as well.
+
+- Misc fixes.
+
+
+Overview of changes leading to 1.4.1
+Thursday, January 5, 2017
+====================================
+
+- Always build and use UCDN for Unicode data by default.
+  Reduces dependence on version of Unicode data in glib,
+  specially in the Windows bundles we are shipping, which
+  have very old glib.
+
+
+Overview of changes leading to 1.4.0
+Thursday, January 5, 2017
+====================================
+
+- Merged "OpenType GX" branch which adds core of support for
+  OpenType 1.8 Font Variations.  To that extent, the relevant
+  new API is:
+
+New API:
+hb_font_set_var_coords_normalized()
+
+  with supporting API:
+
+New API:
+HB_OT_LAYOUT_NO_VARIATIONS_INDEX
+hb_ot_layout_table_find_feature_variations()
+hb_ot_layout_feature_with_variations_get_lookups()
+hb_shape_plan_create2()
+hb_shape_plan_create_cached2()
+
+  Currently variations in GSUB/GPOS/GDEF are fully supported,
+  and no other tables are supported.  In particular, fvar/avar
+  are NOT supported, hence the hb_font_set_var_coords_normalized()
+  taking normalized coordinates.  API to take design coordinates
+  will be added in the future.
+
+  HVAR/VVAR/MVAR support will also be added to hb-ot-font in the
+  future.
+
+- Fix regression in GDEF glyph class processing.
+- Add decompositions for Chakma, Limbu, and Balinese in USE shaper.
+- Misc fixes.
+
+
+Overview of changes leading to 1.3.4
+Monday, December 5, 2016
+====================================
+
+- Fix vertical glyph origin in hb-ot-font.
+- Implement CBDT/CBLC color font glyph extents in hb-ot-font.
+
+
+Overview of changes leading to 1.3.3
+Wednesday, September 28, 2016
+====================================
+
+- Implement parsing of OpenType MATH table.
+New API:
+HB_OT_TAG_MATH
+HB_OT_MATH_SCRIPT
+hb_ot_math_constant_t
+hb_ot_math_kern_t
+hb_ot_math_glyph_variant_t
+hb_ot_math_glyph_part_flags_t
+hb_ot_math_glyph_part_t
+hb_ot_math_has_data
+hb_ot_math_get_constant
+hb_ot_math_get_glyph_italics_correction
+hb_ot_math_get_glyph_top_accent_attachment
+hb_ot_math_get_glyph_kerning
+hb_ot_math_is_glyph_extended_shape
+hb_ot_math_get_glyph_variants
+hb_ot_math_get_min_connector_overlap
+hb_ot_math_get_glyph_assembly
+
+
+Overview of changes leading to 1.3.2
+Wednesday, September 27, 2016
+====================================
+
+- Fix build of hb-coretext on older OS X versions.
+
+
+Overview of changes leading to 1.3.1
+Wednesday, September 7, 2016
+====================================
+
+- Blacklist bad GDEF of more fonts (Padauk).
+- More CoreText backend crash fixes with OS X 10.9.5.
+- Misc fixes.
+
+
+Overview of changes leading to 1.3.0
+Thursday, July 21, 2016
+====================================
+
+- Update to Unicode 9.0.0
+- Move Javanese from Indic shaper to Universal Shaping Engine.
+- Allow MultipleSubst to delete a glyph (matching Windows engine).
+- Update Universal Shaping Engine to latest draft from Microsoft.
+- DirectWrite backend improvements.  Note: this backend is for testing ONLY.
+- CoreText backend improvements with unreachable fonts.
+- Implement symbol fonts (cmap 3.0.0) in hb-ft and hb-ot-font.
+- Blacklist bad GDEF of more fonts (Tahoma & others).
+- Misc fixes.
+
+
+Overview of changes leading to 1.2.7
+Monday, May 2, 2016
+====================================
+
+- Blacklist another version of Times New Roman (Bold) Italic from Windows 7.
+- Fix Mongolian Free Variation Selectors shaping with certain fonts.
+- Fix Tibetan shorthand contractions shaping.
+- Improved list of language tag mappings.
+- Unbreak build on Windows CE.
+- Make 'glyf' table loading lazy in hb-ot-font.
+
+
+Overview of changes leading to 1.2.6
+Friday, April 8, 2016
+====================================
+
+- Blacklist GDEF table of another set of Times New Roman (Bold) Italic.
+- DirectWrite backend improvements.  Note: DirectWrite backend is
+  exclusively for our internal testing and should NOT be used in any
+  production system whatsoever.
+
+
+Overview of changes leading to 1.2.5
+Monday, April 4, 2016
+====================================
+
+- Fix GDEF mark-filtering-set, which was broken in 1.2.3.
+
+
+Overview of changes leading to 1.2.4
+Thursday, March 17, 2016
+====================================
+
+- Synthesize GDEF glyph class for any glyph that does not have one in GDEF.
+  I really hope we don't discover broken fonts that shape badly with this
+  change.
+- Misc build and other minor fixes.
+- API changes:
+  - Added HB_NDEBUG.  It's fine for production systems to define this to
+    disable high-overhead debugging checks.  However, I also reduced the
+    overhead of those checks, so it's a non-issue right now.  You can
+    forget it.  Just not defining anything at all is fine.
+
+
+Overview of changes leading to 1.2.3
+Thursday, February 25, 2016
+====================================
+
+- Blacklist GDEF table of certain versions of Times New Roman (Bold) Italic,
+  due to bug in glyph class of ASCII double-quote character.  This should
+  address "regression" introduced in 1.2.0 when we switched mark zeroing
+  in most shapers from BY_UNICODE_LATE to BY_GDEF_LATE.
+  This fourth release in a week should finally stabilize things...
+
+- hb-ot-font's get_glyph() implementation saw some optimizations.  Though,
+  might be really hard to measure in real-world situations.
+
+- Also, two rather small API changes:
+
+We now disable some time-consuming internal bookkeeping if built with NDEBUG
+defined.  This is a first time that we use NDEBUG to disable debug code.  If
+there exist production systems that do NOT want to enable NDEBUG, please let
+me know and I'll add HB_NDEBUG.
+
+Added get_nominal_glyph() and get_variation_glyph() instead of get_glyph()
+
+New API:
+- hb_font_get_nominal_glyph_func_t
+- hb_font_get_variation_glyph_func_t
+- hb_font_funcs_set_nominal_glyph_func()
+- hb_font_funcs_set_variation_glyph_func()
+- hb_font_get_nominal_glyph()
+- hb_font_get_variation_glyph()
+
+Deprecated API:
+- hb_font_get_glyph_func_t
+- hb_font_funcs_set_glyph_func()
+
+Clients that implement their own font-funcs are encouraged to replace
+their get_glyph() implementation with a get_nominal_glyph() and
+get_variation_glyph() pair.  The variation version can assume that
+variation_selector argument is not zero.  Old (deprecated) functions
+will continue working indefinitely using internal gymnastics; it is
+just more efficient to use the new functions.
+
+
+Overview of changes leading to 1.2.2
+Wednesday, February 24, 2016
+====================================
+
+- Fix regression with mark positioning with fonts that have
+  non-zero mark advances.  This was introduced in 1.2.0 while
+  trying to make mark and cursive attachments to work together.
+  I have partially reverted that, so this version is much more
+  like what we had before.  All clients who updated to 1.2.0
+  should update to this version.
+
+
+Overview of changes leading to 1.2.1
+Tuesday, February 23, 2016
+====================================
+
+- CoreText: Fix bug with wrong scale if font scale was changed later.
+  https://github.com/libass/libass/issues/212
+- CoreText: Drastically speed up font initialization.
+- CoreText: Fix tiny leak.
+- Group ZWJ/ZWNJ with previous syllable under cluster-level=0.
+  https://github.com/harfbuzz/harfbuzz/issues/217
+- Add test/shaping/README.md about how to add tests to the suite.
+
+
+Overview of changes leading to 1.2.0
+Friday, February 19, 2016
+====================================
+
+- Fix various issues (hangs mostly) in case of memory allocation failure.
+- Change mark zeroing types of most shapers from BY_UNICODE_LATE to
+  BY_GDEF_LATE.  This seems to be what Uniscribe does.
+- Change mark zeroing of USE shaper from NONE to BY_GDEF_EARLY.  That's
+  what Windows does.
+- Allow GPOS cursive connection on marks, and fix the interaction with
+  mark attachment.  This work resulted in some changes to how mark
+  attachments work.  See:
+  https://github.com/harfbuzz/harfbuzz/issues/211
+  https://github.com/harfbuzz/harfbuzz/commit/86c68c7a2c971efe8e35b1f1bd99401dc8b688d2
+- Graphite2 shaper: improved negative advance handling (eg. Nastaliq).
+- Add nmake-based build system for Windows.
+- Minor speedup.
+- Misc. improvements.
+
+
+Overview of changes leading to 1.1.3
+Monday, January 11, 2016
+====================================
+
+- Ported Indic shaper to Unicode 8.0 data.
+- Universal Shaping Engine fixes.
+- Speed up CoreText shaper when font fallback happens in CoreText.
+- Documentation improvements, thanks to Khaled Hosny.
+- Very rough directwrite shaper for testing, thanks to Ebrahim Byagowi.
+- Misc bug fixes.
+- New API:
+
+  * Font extents:
+      hb_font_extents_t
+      hb_font_get_font_extents_func_t
+      hb_font_get_font_h_extents_func_t
+      hb_font_get_font_v_extents_func_t
+      hb_font_funcs_set_font_h_extents_func
+      hb_font_funcs_set_font_v_extents_func
+      hb_font_get_h_extents
+      hb_font_get_v_extents
+      hb_font_get_extents_for_direction
+
+  * Buffer message (aka debug):
+      hb_buffer_message_func_t
+      hb_buffer_set_message_func()
+    Actual message protocol to be fleshed out later.
+
+
+Overview of changes leading to 1.1.2
+Wednesday, November 26, 2015
+====================================
+
+- Fix badly-broken fallback shaper that affected terminology.
+  https://github.com/harfbuzz/harfbuzz/issues/187
+- Fix y_scaling in Graphite shaper.
+- API changes:
+  * An unset glyph_h_origin() function in font-funcs now (sensibly)
+    implies horizontal origin at 0,0.  Ie, the nil callback returns
+    true instead of false.  As such, implementations that have a
+    glyph_h_origin() that simply returns true, can remove that function
+    with HarfBuzz >= 1.1.2.  This results in a tiny speedup.
+
+
+Overview of changes leading to 1.1.1
+Wednesday, November 24, 2015
+====================================
+
+- Build fixes, specially for hb-coretext.
+
+
+Overview of changes leading to 1.1.0
+Wednesday, November 18, 2015
+====================================
+
+- Implement 'stch' stretch feature for Syriac Abbreviation Mark.
+  https://github.com/harfbuzz/harfbuzz/issues/141
+- Disable use of decompose_compatibility() callback.
+- Implement "shaping" of various Unicode space characters, even
+  if the font does not support them.
+  https://github.com/harfbuzz/harfbuzz/issues/153
+- If font does not support U+2011 NO-BREAK HYPHEN, fallback to
+  U+2010 HYPHEN.
+- Changes resulting from libFuzzer continuous fuzzing:
+  * Reject font tables that need more than 8 edits,
+  * Bound buffer growth during shaping to 32x,
+  * Fix assertions and other issues at OOM / buffer max-growth.
+- Misc fixes and optimizations.
+- API changes:
+  * All fonts created with hb_font_create() now inherit from
+    (ie. have parent) hb_font_get_empty().
+
+
+Overview of changes leading to 1.0.6
+Thursday, October 15, 2015
+====================================
+
+- Reduce max nesting level in OT lookups from 8 to 6.
+  Should not affect any real font as far as I know.
+- Fix memory access issue in ot-font.
+- Revert default load-flags of fonts created using hb_ft_font_create()
+  back to FT_LOAD_DEFAULT|FT_LOAD_NO_HINTING.  This was changed in
+  last release (1.0.5), but caused major issues, so revert.
+  https://github.com/harfbuzz/harfbuzz/issues/143
+
+
+Overview of changes leading to 1.0.5
+Tuesday, October 13, 2015
+====================================
+
+- Fix multiple memory access bugs discovered using libFuzzer.
+  https://github.com/harfbuzz/harfbuzz/issues/139
+  Everyone should upgrade to this version as soon as possible.
+  We now have continuous fuzzing set up, to avoid issues like
+  these creeping in again.
+- Misc fixes.
+
+- New API:
+  * hb_font_set_parent().
+  * hb_ft_font_[sg]et_load_flags()
+    The default flags for fonts created using hb_ft_font_create()
+    has changed to default to FT_LOAD_DEFAULT now.  Previously it
+    was defaulting to FT_LOAD_DFEAULT|FT_LOAD_NO_HINTING.
+
+- API changes:
+  * Fonts now default to units-per-EM as their scale, instead of 0.
+  * hb_font_create_sub_font() does NOT make parent font immutable
+    anymore.  hb_font_make_immutable() does.
+
+
+Overview of changes leading to 1.0.4
+Wednesday, September 30, 2015
+====================================
+
+- Fix minor out-of-bounds read error.
+
+
+Overview of changes leading to 1.0.3
+Tuesday, September 1, 2015
+====================================
+
+- Start of user documentation, from Simon Cozens!
+- Implement glyph_extents() for TrueType fonts in hb-ot-font.
+- Improve GPOS cursive attachments with conflicting lookups.
+- More fixes for cluster-level = 1.
+- Uniscribe positioning fix.
+
+
+Overview of changes leading to 1.0.2
+Wednesday, August 19, 2015
+====================================
+
+- Fix shaping with cluster-level > 0.
+- Fix Uniscribe backend font-size scaling.
+- Declare dependencies in harfbuzz.pc.
+  FreeType is not declared though, to avoid bugs in pkg-config
+  0.26 with recursive dependencies.
+- Slightly improved debug infrastructure.  More to come later.
+- Misc build fixes.
+
+
+Overview of changes leading to 1.0.1
+Monday, July 27, 2015
+====================================
+
+- Fix out-of-bounds access in USE shaper.
+
+
+Overview of changes leading to 1.0.0
+Sunday, July 26, 2015
+====================================
+
+- Implement Universal Shaping Engine:
+  https://www.microsoft.com/typography/OpenTypeDev/USE/intro.htm
+  http://blogs.windows.com/bloggingwindows/2015/02/23/windows-shapes-the-worlds-languages/
+- Bump version to 1.0.0.  The soname was NOT bumped.
+
+
+Overview of changes leading to 0.9.42
+Thursday, July 26, 2015
+=====================================
+
+- New API to allow for retrieving finer-grained cluster
+  mappings if the client desires to handle them.  Default
+  behavior is unchanged.
+- Fix cluster merging when removing default-ignorables.
+- Update to Unicode 8.0
+- hb-graphite2 fixes.
+- Misc fixes.
+- Removed HB_NO_MERGE_CLUSTERS hack.
+- New API:
+  hb_buffer_cluster_level_t enum
+  hb_buffer_get_cluster_level()
+  hb_buffer_set_cluster_level()
+  hb-shape / hb-view --cluster-level
+
+
+Overview of changes leading to 0.9.41
+Thursday, June 18, 2015
+=====================================
+
+- Fix hb-coretext with trailing whitespace in right-to-left.
+- New API: hb_buffer_reverse_range().
+- Allow implementing atomic ops in config.h.
+- Fix hb_language_t in language bindings.
+- Misc fixes.
+
+
+Overview of changes leading to 0.9.40
+Friday, March 20, 2015
+=====================================
+
+- Another hb-coretext crasher fix.  Ouch!
+- Happy Norouz!
+
+
+Overview of changes leading to 0.9.39
+Wednesday, March 4, 2015
+=====================================
+
+- Critical hb-coretext fixes.
+- Optimizations and refactoring; no functional change
+  expected.
+- Misc build fixes.
+
+
+Overview of changes leading to 0.9.38
+Friday, January 23, 2015
+=====================================
+
+- Fix minor out-of-bounds access in Indic shaper.
+- Change New Tai Lue shaping engine from South-East Asian to default,
+  reflecting change in Unicode encoding model.
+- Add hb-shape --font-size.  Can take up to two numbers for separate
+  x / y size.
+- Fix CoreText and FreeType scale issues with negative scales.
+- Reject blobs larger than 2GB.  This might break some icu-le-hb clients
+  that need security fixes.  See:
+  http://www.icu-project.org/trac/ticket/11450
+- Avoid accessing font tables during face destruction, in casce rogue
+  clients released face data already.
+- Fix up gobject-introspection a bit.  Python bindings kinda working.
+  See README.python.
+- Misc fixes.
+- API additions:
+  hb_ft_face_create_referenced()
+  hb_ft_font_create_referenced()
+
+
+Overview of changes leading to 0.9.37
+Wednesday, December 17, 2014
+=====================================
+
+- Fix out-of-bounds access in Context lookup format 3.
+- Indic: Allow ZWJ/ZWNJ before syllable modifiers.
+
+
+Overview of changes leading to 0.9.36
+Thursday, November 20, 2014
+=====================================
+
+- First time that three months went by without a release since
+  0.9.2 was released on August 10, 2012!
+- Fix performance bug in hb_ot_collect_glyphs():
+  https://bugzilla.mozilla.org/show_bug.cgi?id=1090869
+- Add basic vertical-text support to hb-ot-font.
+- Misc build fixes.
+
+
+Overview of changes leading to 0.9.35
+Saturday, August 13, 2014
+=====================================
+
+- Fix major shape-plan caching bug when more than one shaper were
+  provided to hb_shape_full() (as exercised by XeTeX).
+  http://www.mail-archive.com/[email protected]/msg1246370.html
+- Fix Arabic fallback shaping regression.  This was broken in 0.9.32.
+- Major hb-coretext fixes.  That backend is complete now, including
+  respecing buffer direction and language, down to vertical writing.
+- Build fixes for Windows CE.  Should build fine now.
+- Misc fixes:
+  Use atexit() only if it's safe to call from shared library
+  https://bugs.freedesktop.org/show_bug.cgi?id=82246
+  Mandaic had errors in its Unicode Joining_Type
+  https://bugs.freedesktop.org/show_bug.cgi?id=82306
+- API changes:
+
+  * hb_buffer_clear_contents() does not reset buffer flags now.
+
+    After 763e5466c0a03a7c27020e1e2598e488612529a7, one doesn't
+    need to set flags for different pieces of text.  The flags now
+    are something the client sets up once, depending on how it
+    actually uses the buffer.  As such, don't clear it in
+    clear_contents().
+
+    I don't expect any changes to be needed to any existing client.
+
+
+Overview of changes leading to 0.9.34
+Saturday, August 2, 2014
+=====================================
+
+- hb_feature_from_string() now accepts CSS font-feature-settings format.
+- As a result, hb-shape / hb-view --features also accept CSS-style strings.
+  Eg, "'liga' off" is accepted now.
+- Add old-spec Myanmar shaper:
+  https://bugs.freedesktop.org/show_bug.cgi?id=81775
+- Don't apply 'calt' in Hangul shaper.
+- Fix mark advance zeroing for Hebrew shaper:
+  https://bugs.freedesktop.org/show_bug.cgi?id=76767
+- Implement Windows-1256 custom Arabic shaping.  Only built on Windows,
+  and requires help from get_glyph().  Used by Firefox.
+  https://bugzilla.mozilla.org/show_bug.cgi?id=1045139
+- Disable 'liga' in vertical text.
+- Build fixes.
+- API changes:
+
+  * Make HB_BUFFER_FLAG_BOT/EOT easier to use.
+
+    Previously, we expected users to provide BOT/EOT flags when the
+    text *segment* was at paragraph boundaries.  This meant that for
+    clients that provide full paragraph to HarfBuzz (eg. Pango), they
+    had code like this:
+
+      hb_buffer_set_flags (hb_buffer,
+                           (item_offset == 0 ? HB_BUFFER_FLAG_BOT : 0) |
+                           (item_offset + item_length == paragraph_length ?
+                            HB_BUFFER_FLAG_EOT : 0));
+
+      hb_buffer_add_utf8 (hb_buffer,
+                          paragraph_text, paragraph_length,
+                          item_offset, item_length);
+
+    After this change such clients can simply say:
+
+      hb_buffer_set_flags (hb_buffer,
+                           HB_BUFFER_FLAG_BOT | HB_BUFFER_FLAG_EOT);
+
+      hb_buffer_add_utf8 (hb_buffer,
+                          paragraph_text, paragraph_length,
+                          item_offset, item_length);
+
+    Ie, HarfBuzz itself checks whether the segment is at the beginning/end
+    of the paragraph.  Clients that only pass item-at-a-time to HarfBuzz
+    continue not setting any flags whatsoever.
+
+    Another way to put it is: if there's pre-context text in the buffer,
+    HarfBuzz ignores the BOT flag.  If there's post-context, it ignores
+    EOT flag.
+
+
+Overview of changes leading to 0.9.33
+Tuesday, July 22, 2014
+=====================================
+
+- Turn off ARabic 'cswh' feature that was accidentally turned on.
+- Add HB_TAG_MAX_SIGNED.
+- Make hb_face_make_immutable() really make face immutable!
+- Windows build fixes.
+
+
+Overview of changes leading to 0.9.32
+Thursday, July 17, 2014
+=====================================
+
+- Apply Arabic shaping features in spec order exactly.
+- Another fix for Mongolian free variation selectors.
+- For non-Arabic scripts in Arabic shaper apply 'rlig' and 'calt'
+  together.
+- Minor adjustment to U+FFFD logic.
+- Fix hb-coretext build.
+
+
+Overview of changes leading to 0.9.31
+Wednesday, July 16, 2014
+=====================================
+
+- Only accept valid UTF-8/16/32; we missed many cases before.
+- Better shaping of invalid UTF-8/16/32.  Falls back to
+  U+FFFD REPLACEMENT CHARACTER now.
+- With all changes in this release, the buffer will contain fully
+  valid Unicode after hb_buffer_add_utf8/16/32 no matter how
+  broken the input is.  This can be overridden though.  See below.
+- Fix Mongolian Variation Selectors for fonts without GDEF.
+- Fix minor invalid buffer access.
+- Accept zh-Hant and zh-Hans language tags.  hb_ot_tag_to_language()
+  now uses these instead of private tags.
+- Build fixes.
+- New API:
+  * hb_buffer_add_codepoints().  This does what hb_buffer_add_utf32()
+    used to do, ie. no validity check on the input at all.  add_utf32
+    now replaces invalid Unicode codepoints with the replacement
+    character (see below).
+  * hb_buffer_set_replacement_codepoint()
+  * hb_buffer_get_replacement_codepoint()
+    Previously, in hb_buffer_add_utf8 and hb_buffer_add_utf16, when
+    we detected broken input, we replaced that with (hb_codepoint_t)-1.
+    This has changed to use U+FFFD now, but can be changed using these
+    new API.
+
+
+Overview of changes leading to 0.9.30
+Wednesday, July 9, 2014
+=====================================
+
+- Update to Unicode 7.0.0:
+  * New scripts Manichaean and Psalter Pahlavi are shaped using
+    Arabic shaper.
+  * All the other new scripts to through the generic shaper for
+    now.
+- Minor Indic improvements.
+- Fix graphite2 backend cluster mapping [crasher!]
+- API changes:
+  * New HB_SCRIPT_* values for Unicode 7.0 scripts.
+  * New function hb_ot_layout_language_get_required_feature().
+- Build fixes.
+
+
+Overview of changes leading to 0.9.29
+Thursday, May 29, 2014
+=====================================
+
+- Implement cmap in hb-ot-font.h.  No variation-selectors yet.
+- Myanmar: Allow MedialYa+Asat.
+- Various Indic fixes:
+  * Support most characters in Extended Devanagary and Vedic
+    Unicode blocks.
+  * Allow digits and a some punctuation as consonant placeholders.
+- Build fixes.
+
+
+Overview of changes leading to 0.9.28
+Monday, April 28, 2014
+=====================================
+
+- Unbreak old-spec Indic shaping. (bug 76705)
+- Fix shaping of U+17DD and U+0FC6.
+- Add HB_NO_MERGE_CLUSTERS build option.  NOT to be enabled by default
+  for shipping libraries.  It's an option for further experimentation
+  right now.  When we are sure how to do it properly, we will add
+  public run-time API for the functionality.
+- Build fixes.
+
+
+Overview of changes leading to 0.9.27
+Tuesday, March 18, 2014
+=====================================
+
+- Don't use "register" storage class specifier
+- Wrap definition of free_langs() with HAVE_ATEXIT
+- Add coretext_aat shaper and hb_coretext_face_create() constructor
+- If HAVE_ICU_BUILTIN is defined, use hb-icu Unicode callbacks
+- Add Myanmar test case from OpenType Myanmar spec
+- Only do fallback Hebrew composition if no GPOS 'mark' available
+- Allow bootstrapping without gtk-doc
+- Use AM_MISSING_PROG for ragel and git
+- Typo in ucdn's Makefile.am
+- Improve MemoryBarrier() implementation
+
+
+Overview of changes leading to 0.9.26
+Thursday, January 30, 2014
+=====================================
+
+- Misc fixes.
+- Fix application of 'rtlm' feature.
+- Automatically apply frac/numr/dnom around U+2044 FRACTION SLASH.
+- New header: hb-ot-shape.h
+- Uniscribe: fix scratch-buffer accounting.
+- Reorder Tai Tham SAKOT to after tone-marks.
+- Add Hangul shaper.
+- New files:
+  hb-ot-shape-complex-hangul.cc
+  hb-ot-shape-complex-hebrew.cc
+  hb-ot-shape-complex-tibetan.cc
+- Disable 'cswh' feature in Arabic shaper.
+- Coretext: better handle surrogate pairs.
+- Add HB_TAG_MAX and _HB_SCRIPT_MAX_VALUE.
+
+
+Overview of changes leading to 0.9.25
+Wednesday, December 4, 2013
+=====================================
+
+- Myanmar shaper improvements.
+- Avoid font fallback in CoreText backend.
+- Additional OpenType language tag mappiongs.
+- More aggressive shape-plan caching.
+- Build with / require automake 1.13.
+- Build with libtool 2.4.2.418 alpha to support ppc64le.
+
+
+Overview of changes leading to 0.9.24
+Tuesday, November 13, 2013
+=====================================
+
+- Misc compiler warning fixes with clang.
+- No functional changes.
+
+
+Overview of changes leading to 0.9.23
+Monday, October 28, 2013
+=====================================
+
+- "Udupi HarfBuzz Hackfest", Paris, October 14..18 2013.
+- Fix (Chain)Context recursion with non-monotone lookup positions.
+- Misc Indic bug fixes.
+- New Javanese / Buginese shaping, similar to Windows 8.1.
+
+
+Overview of changes leading to 0.9.22
+Thursday, October 3, 2013
+=====================================
+
+- Fix use-after-end-of-scope in hb_language_from_string().
+- Fix hiding of default_ignorables if font doesn't have space glyph.
+- Protect against out-of-range lookup indices.
+
+- API Changes:
+
+  * Added hb_ot_layout_table_get_lookup_count()
+
+
+Overview of changes leading to 0.9.21
+Monday, September 16, 2013
+=====================================
+
+- Rename gobject-introspection library name from harfbuzz to HarfBuzz.
+- Remove (long disabled) hb-old and hb-icu-le test shapers.
+- Misc gtk-doc and gobject-introspection annotations.
+- Misc fixes.
+- API changes:
+
+  * Add HB_SET_VALUE_INVALID
+
+Overview of changes leading to 0.9.20
+Thursday, August 29, 2013
+=====================================
+
+General:
+- Misc substitute_closure() fixes.
+- Build fixes.
+
+Documentation:
+- gtk-doc boilerplate integrated.  Docs are built now, but
+  contain no contents.  By next release hopefully we have
+  some content in.  Enable using --enable-gtk-doc.
+
+GObject and Introspection:
+- Added harfbuzz-gobject library (hb-gobject.h) that has type
+  bindings for all HarfBuzz objects and enums.  Enable using
+  --with-gobject.
+- Added gobject-introspection boilerplate.  Nothing useful
+  right now.  Work in progress.  Gets enabled automatically if
+  --with-gobject is used.  Override with --disable-introspection.
+
+OpenType shaper:
+- Apply 'mark' in Myanmar shaper.
+- Don't apply 'dlig' by default.
+
+Uniscribe shaper:
+- Support user features.
+- Fix loading of fonts that are also installed on the system.
+- Fix shaping of Arabic Presentation Forms.
+- Fix build with wide chars.
+
+CoreText shaper:
+- Support user features.
+
+Source changes:
+- hb_face_t code moved to hb-face.h / hb-face.cc.
+- Added hb-deprecated.h.
+
+API changes:
+- Added HB_DISABLE_DEPRECATED.
+- Deprecated HB_SCRIPT_CANADIAN_ABORIGINAL; replaced by
+  HB_SCRIPT_CANADIAN_SYLLABICS.
+- Deprecated HB_BUFFER_FLAGS_DEFAULT; replaced by
+  HB_BUFFER_FLAG_DEFAULT.
+- Deprecated HB_BUFFER_SERIALIZE_FLAGS_DEFAULT; replaced by
+  HB_BUFFER_SERIALIZE_FLAG_DEFAULT.
+
+
+Overview of changes leading to 0.9.19
+Tuesday, July 16, 2013
+=====================================
+
+- Build fixes.
+- Better handling of multiple variation selectors in a row.
+- Pass on variation selector to GSUB if not consumed by cmap.
+- Fix undefined memory access.
+- Add Javanese config to Indic shaper.
+- Misc bug fixes.
+
+Overview of changes leading to 0.9.18
+Tuesday, May 28, 2013
+=====================================
+
+New build system:
+
+- All unneeded code is all disabled by default,
+
+- Uniscribe and CoreText shapers can be enabled with their --with options,
+
+- icu_le and old shapers cannot be enabled for now,
+
+- glib, freetype, and cairo will be detected automatically.
+  They can be force on/off'ed with their --with options,
+
+- icu and graphite2 are default off, can be enabled with their --with
+  options,
+
+Moreover, ICU support is now build into a separate library:
+libharfbuzz-icu.so, and a new harfbuzz-icu.pc is shipped for it.
+Distros can enable ICU now without every application on earth
+getting linked to via libharfbuzz.so.
+
+For distros I recommend that they make sure they are building --with-glib
+--with-freetype --with-cairo, --with-icu, and optionally --with-graphite2;
+And package harfbuzz and harfbuzz-icu separately.
+
+
+Overview of changes leading to 0.9.17
+Monday, May 20, 2013
+=====================================
+
+- Build fixes.
+- Fix bug in hb_set_get_min().
+- Fix regression with Arabic mark positioning / width-zeroing.
+
+Overview of changes leading to 0.9.16
+Friday, April 19, 2013
+=====================================
+
+- Major speedup in OpenType lookup processing.  With the Amiri
+  Arabic font, this release is over 3x faster than previous
+  release.  All scripts / languages should see this speedup.
+
+- New --num-iterations option for hb-shape / hb-view; useful for
+  profiling.
+
+Overview of changes leading to 0.9.15
+Friday, April 05, 2013
+=====================================
+
+- Build fixes.
+- Fix crasher in graphite2 shaper.
+- Fix Arabic mark width zeroing regression.
+- Don't compose Hangul jamo into Unicode syllables.
+
+
+Overview of changes leading to 0.9.14
+Thursday, March 21, 2013
+=====================================
+
+- Build fixes.
+- Fix time-consuming sanitize with malicious fonts.
+- Implement hb_buffer_deserialize_glyphs() for both json and text.
+- Do not ignore Hangul filler characters.
+- Indic fixes:
+  * Fix Malayalam pre-base reordering interaction with post-forms.
+  * Further adjust ZWJ handling.  Should fix known regressions from
+    0.9.13.
+
+
+Overview of changes leading to 0.9.13
+Thursday, February 25, 2013
+=====================================
+
+- Build fixes.
+- Ngapi HarfBuzz Hackfest in London (February 2013):
+  * Fixed all known Indic bugs,
+  * New Win8-style Myanmar shaper,
+  * New South-East Asian shaper for Tai Tham, Cham, and New Tai Lue,
+  * Smartly ignore Default_Ignorable characters (joiners, etc) wheb
+    matching GSUB/GPOS lookups,
+  * Fix 'Phags-Pa U+A872 shaping,
+  * Fix partial disabling of default-on features,
+  * Allow disabling of TrueType kerning.
+- Fix possible crasher with broken fonts with overlapping tables.
+- Removed generated files from git again.  So, one needs ragel to
+  bootstrap from the git tree.
+
+API changes:
+- hb_shape() and related APIs now abort if buffer direction is
+  HB_DIRECTION_INVALID.  Previously, hb_shape() was calling
+  hb_buffer_guess_segment_properties() on the buffer before
+  shaping.  The heuristics in that function are fragile.  If the
+  user really wants the old behvaior, they can call that function
+  right before calling hb_shape() to get the old behavior.
+- hb_blob_create_sub_blob() always creates sub-blob with
+  HB_MEMORY_MODE_READONLY.  See comments for the reason.
+
+
+Overview of changes leading to 0.9.12
+Thursday, January 18, 2013
+=====================================
+
+- Build fixes for Sun compiler.
+- Minor bug fix.
+
+Overview of changes leading to 0.9.11
+Thursday, January 10, 2013
+=====================================
+
+- Build fixes.
+- Fix GPOS mark attachment with null Anchor offsets.
+- [Indic] Fix old-spec reordering of viramas if sequence ends in one.
+- Fix multi-threaded shaper data creation crash.
+- Add atomic ops for Solaris.
+
+API changes:
+- Rename hb_buffer_clear() to hb_buffer_clear_contents().
+
+
+Overview of changes leading to 0.9.10
+Thursday, January 3, 2013
+=====================================
+
+- [Indic] Fixed rendering of Malayalam dot-reph
+- Updated OT language tags.
+- Updated graphite2 backend.
+- Improved hb_ot_layout_get_size_params() logic.
+- Improve hb-shape/hb-view help output.
+- Fixed hb-set.h implementation to not crash.
+- Fixed various issues with hb_ot_layout_collect_lookups().
+- Various build fixes.
+
+New API:
+
+hb_graphite2_face_get_gr_face()
+hb_graphite2_font_get_gr_font()
+hb_coretext_face_get_cg_font()
+
+Modified API:
+
+hb_ot_layout_get_size_params()
+
+
+Overview of changes leading to 0.9.9
+Wednesday, December 5, 2012
+====================================
+
+- Fix build on Windows.
+- Minor improvements.
+
+
+Overview of changes leading to 0.9.8
+Tuesday, December 4, 2012
+====================================
+
+
+- Actually implement hb_shape_plan_get_shaper ().
+- Make UCDB data tables const.
+- Lots of internal refactoring in OTLayout tables.
+- Flesh out hb_ot_layout_lookup_collect_glyphs().
+
+New API:
+
+hb_ot_layout_collect_lookups()
+hb_ot_layout_get_size_params()
+
+
+Overview of changes leading to 0.9.7
+Sunday, November 21, 2012
+====================================
+
+
+HarfBuzz "All-You-Can-Eat-Sushi" (aka Vancouver) Hackfest and follow-on fixes.
+
+- Fix Arabic contextual joining using pre-context text.
+- Fix Sinhala "split matra" mess.
+- Fix Khmer shaping with broken fonts.
+- Implement Thai "PUA" shaping for old fonts.
+- Do NOT route Kharoshthi script through the Indic shaper.
+- Disable fallback positioning for Indic and Thai shapers.
+- Misc fixes.
+
+
+hb-shape / hb-view changes:
+
+- Add --text-before and --text-after
+- Add --bot / --eot / --preserve-default-ignorables
+- hb-shape --output-format=json
+
+
+New API:
+
+hb_buffer_clear()
+
+hb_buffer_flags_t
+
+HB_BUFFER_FLAGS_DEFAULT
+HB_BUFFER_FLAG_BOT
+HB_BUFFER_FLAG_EOT
+HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES
+
+hb_buffer_set_flags()
+hb_buffer_get_flags()
+
+HB_BUFFER_SERIALIZE_FLAGS
+hb_buffer_serialize_glyphs()
+hb_buffer_deserialize_glyphs()
+hb_buffer_serialize_list_formats()
+
+hb_set_add_range()
+hb_set_del_range()
+hb_set_get_population()
+hb_set_next_range()
+
+hb_face_[sg]et_glyph_count()
+
+hb_segment_properties_t
+HB_SEGMENT_PROPERTIES_DEFAULT
+hb_segment_properties_equal()
+hb_segment_properties_hash()
+
+hb_buffer_set_segment_properties()
+hb_buffer_get_segment_properties()
+
+hb_ot_layout_glyph_class_t
+hb_ot_layout_get_glyph_class()
+hb_ot_layout_get_glyphs_in_class()
+
+hb_shape_plan_t
+hb_shape_plan_create()
+hb_shape_plan_create_cached()
+hb_shape_plan_get_empty()
+hb_shape_plan_reference()
+hb_shape_plan_destroy()
+hb_shape_plan_set_user_data()
+hb_shape_plan_get_user_data()
+hb_shape_plan_execute()
+hb_shape_plan_get_shaper()
+
+hb_ot_shape_plan_collect_lookups()
+
+
+API changes:
+
+- Remove "mask" parameter from hb_buffer_add().
+- Rename hb_ot_layout_would_substitute_lookup() and hb_ot_layout_substitute_closure_lookup().
+- hb-set.h API const correction.
+- Renamed hb_set_min/max() to hb_set_get_min/max().
+- Rename hb_ot_layout_feature_get_lookup_indexes() to hb_ot_layout_feature_get_lookups().
+- Rename hb_buffer_guess_properties() to hb_buffer_guess_segment_properties().
+
+
+
+Overview of changes leading to 0.9.6
+Sunday, November 13, 2012
+====================================
+
+- Don't clear pre-context text if no new context is provided.
+- Fix ReverseChainingSubstLookup, which was totally borked.
+- Adjust output format of hb-shape a bit.
+- Include config.h.in in-tree.  Makes it easier for alternate build systems.
+- Fix hb_buffer_set_length(buffer, 0) invalid memory allocation.
+- Use ICU LayoutEngine's C API instead of C++.  Avoids much headache.
+- Drop glyphs for all of Unicode Default_Ignorable characters.
+- Misc build fixes.
+
+Arabic shaper:
+- Enable 'dlig' and 'mset' features in Arabic shaper.
+- Implement 'Phags-pa shaping, improve Mongolian.
+
+Indic shaper:
+- Decompose Sinhala split matras the way old HarfBuzz / Pango did.
+- Initial support for Consonant Medials.
+- Start adding new-style Myanmar shaping.
+- Make reph and 'pref' logic introspect the font.
+- Route Meetei-Mayek through the Indic shaper.
+- Don't apply 'liga' in Indic shaper.
+- Improve Malayalam pre-base reordering Ra interaction with Chillus.
+
+
+
+Overview of changes leading to 0.9.5
+Sunday, October 14, 2012
+====================================
+
+- Synthetic-GSUB Arabic fallback shaping.
+
+- Misc Indic improvements.
+
+- Add build system support for pthread.
+
+- Imported UCDN for in-tree Unicode callbacks implementation.
+
+- Context-aware Arabic joining.
+
+- Misc other fixes.
+
+- New API:
+
+  hb_feature_to/from-string()
+  hb_buffer_[sg]et_content_type()
+
+
+
+Overview of changes leading to 0.9.4
+Tuesday, Sep 03, 2012
+====================================
+
+- Indic improvements with old-spec Malayalam.
+
+- Better fallback glyph positioning, specially with Thai / Lao marks.
+
+- Implement dotted-circle insertion.
+
+- Better Arabic fallback shaping / ligation.
+
+- Added ICU LayoutEngine backend for testing.  Call it by the 'icu_le' name.
+
+- Misc fixes.
+
+
+
+Overview of changes leading to 0.9.3
+Friday, Aug 18, 2012
+====================================
+
+- Fixed fallback mark positioning for left-to-right text.
+
+- Improve mark positioning for the remaining combining classes.
+
+- Unbreak Thai and fallback Arabic shaping.
+
+- Port Arabic shaper to shape-plan caching.
+
+- Use new ICU normalizer functions.
+
+
+
+Overview of changes leading to 0.9.2
+Friday, Aug 10, 2012
+====================================
+
+- Over a thousand commits!  This is the first major release of HarfBuzz.
+
+- HarfBuzz is feature-complete now!  It should be in par, or better, than
+  both Pango's shapers and old HarfBuzz / Qt shapers.
+
+- New Indic shaper, supporting main Indic scripts, Sinhala, and Khmer.
+
+- Improved Arabic shaper, with fallback Arabic shaping, supporting Arabic,
+  Sinhala, N'ko, Mongolian, and Mandaic.
+
+- New Thai / Lao shaper.
+
+- Tibetan / Hangul support in the generic shaper.
+
+- Synthetic GDEF support for fonts without a GDEF table.
+
+- Fallback mark positioning for fonts without a GPOS table.
+
+- Unicode normalization shaping heuristic during glyph mapping.
+
+- New experimental Graphite2 backend.
+
+- New Uniscribe backend (primarily for testing).
+
+- New CoreText backend (primarily for testing).
+
+- Major optimization and speedup.
+
+- Test suites and testing infrastructure (work in progress).
+
+- Greatly improved hb-view cmdline tool.
+
+- hb-shape cmdline tool.
+
+- Unicode 6.1 support.
+
+Summary of API changes:
+
+o Changed API:
+
+  - Users are expected to only include main header files now (ie. hb.h,
+    hb-glib.h, hb-ft.h, ...)
+
+  - All struct tag names had their initial underscore removed.
+    Ie. "struct _hb_buffer_t" is "struct hb_buffer_t" now.
+
+  - All set_user_data() functions now take a "replace" boolean parameter.
+
+  - hb_buffer_create() takes zero arguments now.
+    Use hb_buffer_pre_allocate() to pre-allocate.
+
+  - hb_buffer_add_utf*() now accept -1 for length parameters,
+    meaning "nul-terminated".
+
+  - hb_direction_t enum values changed.
+
+  - All *_from_string() APIs now take a length parameter to allow for
+    non-nul-terminated strings. A -1 length means "nul-terminated".
+
+  - Typedef for hb_language_t changed.
+
+  - hb_get_table_func_t renamed to hb_reference_table_func_t.
+
+  - hb_ot_layout_table_choose_script()
+
+  - Various renames in hb-unicode.h.
+
+o New API:
+
+  - hb_buffer_guess_properties()
+    Automatically called by hb_shape().
+
+  - hb_buffer_normalize_glyphs()
+
+  - hb_tag_from_string()
+
+  - hb-coretext.h
+
+  - hb-uniscribe.h
+
+  - hb_face_reference_blob()
+  - hb_face_[sg]et_index()
+  - hb_face_set_upem()
+
+  - hb_font_get_glyph_name_func_t
+    hb_font_get_glyph_from_name_func_t
+    hb_font_funcs_set_glyph_name_func()
+    hb_font_funcs_set_glyph_from_name_func()
+    hb_font_get_glyph_name()
+    hb_font_get_glyph_from_name()
+    hb_font_glyph_to_string()
+    hb_font_glyph_from_string()
+
+  - hb_font_set_funcs_data()
+
+  - hb_ft_font_set_funcs()
+  - hb_ft_font_get_face()
+
+  - hb-gobject.h (work in progress)
+
+  - hb_ot_shape_glyphs_closure()
+    hb_ot_layout_substitute_closure_lookup()
+
+  - hb-set.h
+
+  - hb_shape_full()
+
+  - hb_unicode_combining_class_t
+
+  - hb_unicode_compose_func_t
+    hb_unicode_decompose_func_t
+    hb_unicode_decompose_compatibility_func_t
+    hb_unicode_funcs_set_compose_func()
+    hb_unicode_funcs_set_decompose_func()
+    hb_unicode_funcs_set_decompose_compatibility_func()
+    hb_unicode_compose()
+    hb_unicode_decompose()
+    hb_unicode_decompose_compatibility()
+
+o Removed API:
+
+  - hb_ft_get_font_funcs()
+
+  - hb_ot_layout_substitute_start()
+    hb_ot_layout_substitute_lookup()
+    hb_ot_layout_substitute_finish()
+    hb_ot_layout_position_start()
+    hb_ot_layout_position_lookup()
+    hb_ot_layout_position_finish()
+
+
+
+Overview of changes leading to 0.6.0
+Friday, May 27, 2011
+====================================
+
+- Vertical text support in GPOS
+- Almost all API entries have unit tests now, under test/
+- All thread-safety issues are fixed
+
+Summary of API changes follows.
+
+
+* Simple Types API:
+
+  o New API:
+    HB_LANGUAGE_INVALID
+    hb_language_get_default()
+    hb_direction_to_string()
+    hb_direction_from_string()
+    hb_script_get_horizontal_direction()
+    HB_UNTAG()
+
+  o Renamed API:
+    hb_category_t renamed to hb_unicode_general_category_t
+
+  o Changed API:
+    hb_language_t is a typed pointers now
+
+  o Removed API:
+    HB_TAG_STR()
+
+
+* Use ISO 15924 tags for hb_script_t:
+
+  o New API:
+    hb_script_from_iso15924_tag()
+    hb_script_to_iso15924_tag()
+    hb_script_from_string()
+
+  o Changed API:
+    HB_SCRIPT_* enum members changed value.
+
+
+* Buffer API streamlined:
+
+  o New API:
+    hb_buffer_reset()
+    hb_buffer_set_length()
+    hb_buffer_allocation_successful()
+
+  o Renamed API:
+    hb_buffer_ensure() renamed to hb_buffer_pre_allocate()
+    hb_buffer_add_glyph() renamed to hb_buffer_add()
+
+  o Removed API:
+    hb_buffer_clear()
+    hb_buffer_clear_positions()
+
+  o Changed API:
+    hb_buffer_get_glyph_infos() takes an out length parameter now
+    hb_buffer_get_glyph_positions() takes an out length parameter now
+
+
+* Blob API streamlined:
+
+  o New API:
+    hb_blob_get_data()
+    hb_blob_get_data_writable()
+
+  o Renamed API:
+    hb_blob_create_empty() renamed to hb_blob_get_empty()
+
+  o Removed API:
+    hb_blob_lock()
+    hb_blob_unlock()
+    hb_blob_is_writable()
+    hb_blob_try_writable()
+
+  o Changed API:
+    hb_blob_create() takes user_data before destroy now
+
+
+* Unicode functions API:
+
+  o Unicode function vectors can subclass other unicode function vectors now.
+    Unimplemented callbacks in the subclass automatically chainup to the parent.
+
+  o All hb_unicode_funcs_t callbacks take a user_data now.  Their setters
+    take a user_data and its respective destroy callback.
+
+  o New API:
+    hb_unicode_funcs_get_empty()
+    hb_unicode_funcs_get_default()
+    hb_unicode_funcs_get_parent()
+
+  o Changed API:
+    hb_unicode_funcs_create() now takes a parent_funcs.
+
+  o Removed func getter functions:
+    hb_unicode_funcs_get_mirroring_func()
+    hb_unicode_funcs_get_general_category_func()
+    hb_unicode_funcs_get_script_func()
+    hb_unicode_funcs_get_combining_class_func()
+    hb_unicode_funcs_get_eastasian_width_func()
+
+
+* Face API:
+
+  o Renamed API:
+    hb_face_get_table() renamed to hb_face_reference_table()
+    hb_face_create_for_data() renamed to hb_face_create()
+
+  o Changed API:
+    hb_face_create_for_tables() takes user_data before destroy now
+    hb_face_reference_table() returns empty blob instead of NULL
+    hb_get_table_func_t accepts the face as first parameter now
+
+* Font API:
+
+  o Fonts can subclass other fonts now.  Unimplemented callbacks in the
+    subclass automatically chainup to the parent.  When chaining up,
+    scale is adjusted if the parent font has a different scale.
+
+  o All hb_font_funcs_t callbacks take a user_data now.  Their setters
+    take a user_data and its respective destroy callback.
+
+  o New API:
+    hb_font_get_parent()
+    hb_font_funcs_get_empty()
+    hb_font_create_sub_font()
+
+  o Removed API:
+    hb_font_funcs_copy()
+    hb_font_unset_funcs()
+
+  o Removed func getter functions:
+    hb_font_funcs_get_glyph_func()
+    hb_font_funcs_get_glyph_advance_func()
+    hb_font_funcs_get_glyph_extents_func()
+    hb_font_funcs_get_contour_point_func()
+    hb_font_funcs_get_kerning_func()
+
+  o Changed API:
+    hb_font_create() takes a face and references it now
+    hb_font_set_funcs() takes user_data before destroy now
+    hb_font_set_scale() accepts signed integers now
+    hb_font_get_contour_point_func_t now takes glyph first, then point_index
+    hb_font_get_glyph_func_t returns a success boolean now
+
+
+* Changed object model:
+
+  o All object types have a _get_empty() now:
+    hb_blob_get_empty()
+    hb_buffer_get_empty()
+    hb_face_get_empty()
+    hb_font_get_empty()
+    hb_font_funcs_get_empty()
+    hb_unicode_funcs_get_empty()
+
+  o Added _set_user_data() and _get_user_data() for all object types:
+    hb_blob_get_user_data()
+    hb_blob_set_user_data()
+    hb_buffer_get_user_data()
+    hb_buffer_set_user_data()
+    hb_face_get_user_data()
+    hb_face_set_user_data()
+    hb_font_funcs_get_user_data()
+    hb_font_funcs_set_user_data()
+    hb_font_get_user_data()
+    hb_font_set_user_data()
+    hb_unicode_funcs_get_user_data()
+    hb_unicode_funcs_set_user_data()
+
+  o Removed the _get_reference_count() from all object types:
+    hb_blob_get_reference_count()
+    hb_buffer_get_reference_count()
+    hb_face_get_reference_count()
+    hb_font_funcs_get_reference_count()
+    hb_font_get_reference_count()
+    hb_unicode_funcs_get_reference_count()
+
+  o Added _make_immutable() and _is_immutable() for all object types except for buffer:
+    hb_blob_make_immutable()
+    hb_blob_is_immutable()
+    hb_face_make_immutable()
+    hb_face_is_immutable()
+
+
+* Changed API for vertical text support
+
+  o The following callbacks where removed:
+    hb_font_get_glyph_advance_func_t
+    hb_font_get_kerning_func_t
+
+  o The following new callbacks added instead:
+    hb_font_get_glyph_h_advance_func_t
+    hb_font_get_glyph_v_advance_func_t
+    hb_font_get_glyph_h_origin_func_t
+    hb_font_get_glyph_v_origin_func_t
+    hb_font_get_glyph_h_kerning_func_t
+    hb_font_get_glyph_v_kerning_func_t
+
+  o The following API removed as such:
+    hb_font_funcs_set_glyph_advance_func()
+    hb_font_funcs_set_kerning_func()
+    hb_font_get_glyph_advance()
+    hb_font_get_kerning()
+
+  o New API added instead:
+    hb_font_funcs_set_glyph_h_advance_func()
+    hb_font_funcs_set_glyph_v_advance_func()
+    hb_font_funcs_set_glyph_h_origin_func()
+    hb_font_funcs_set_glyph_v_origin_func()
+    hb_font_funcs_set_glyph_h_kerning_func()
+    hb_font_funcs_set_glyph_v_kerning_func()
+    hb_font_get_glyph_h_advance()
+    hb_font_get_glyph_v_advance()
+    hb_font_get_glyph_h_origin()
+    hb_font_get_glyph_v_origin()
+    hb_font_get_glyph_h_kerning()
+    hb_font_get_glyph_v_kerning()
+
+  o The following higher-leve API added for convenience:
+    hb_font_get_glyph_advance_for_direction()
+    hb_font_get_glyph_origin_for_direction()
+    hb_font_add_glyph_origin_for_direction()
+    hb_font_subtract_glyph_origin_for_direction()
+    hb_font_get_glyph_kerning_for_direction()
+    hb_font_get_glyph_extents_for_origin()
+    hb_font_get_glyph_contour_point_for_origin()
+
+
+* OpenType Layout API:
+
+  o New API:
+    hb_ot_layout_position_start()
+    hb_ot_layout_substitute_start()
+    hb_ot_layout_substitute_finish()
+
+
+* Glue code:
+
+  o New API:
+    hb_glib_script_to_script()
+    hb_glib_script_from_script()
+    hb_icu_script_to_script()
+    hb_icu_script_from_script()
+
+
+* Version API added:
+
+  o New API:
+    HB_VERSION_MAJOR
+    HB_VERSION_MINOR
+    HB_VERSION_MICRO
+    HB_VERSION_STRING
+    HB_VERSION_CHECK()
+    hb_version()
+    hb_version_string()
+    hb_version_check()
+
+

+ 1 - 0
hbfreetypefont.mod/harfbuzz/README

@@ -0,0 +1 @@
+README.md

+ 104 - 0
hbfreetypefont.mod/harfbuzz/README.md

@@ -0,0 +1,104 @@
+[![Linux CI Status](https://github.com/harfbuzz/harfbuzz/workflows/linux-ci/badge.svg)](https://github.com/harfbuzz/harfbuzz/workflows/linux-ci/badge.svg)
+[![CircleCI Build Status](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main.svg?style=svg)](https://circleci.com/gh/harfbuzz/harfbuzz/tree/main)
+[![OSS-Fuzz Status](https://oss-fuzz-build-logs.storage.googleapis.com/badges/harfbuzz.svg)](https://oss-fuzz-build-logs.storage.googleapis.com/index.html)
+[![Coverity Scan Build Status](https://scan.coverity.com/projects/15166/badge.svg)](https://scan.coverity.com/projects/harfbuzz)
+[![Codacy Badge](https://app.codacy.com/project/badge/Grade/89c872f5ce1c42af802602bfcd15d90a)](https://app.codacy.com/gh/harfbuzz/harfbuzz/dashboard?utm_source=gh&utm_medium=referral&utm_content=&utm_campaign=Badge_grade)
+[![Codecov Code Coverage](https://codecov.io/gh/harfbuzz/harfbuzz/branch/main/graph/badge.svg)](https://codecov.io/gh/harfbuzz/harfbuzz)
+[![Packaging status](https://repology.org/badge/tiny-repos/harfbuzz.svg)](https://repology.org/project/harfbuzz/versions)
+[![OpenSSF Scorecard](https://api.securityscorecards.dev/projects/github.com/harfbuzz/harfbuzz/badge)](https://securityscorecards.dev/viewer/?uri=github.com/harfbuzz/harfbuzz)
+
+
+# HarfBuzz
+
+HarfBuzz is a text shaping engine. It primarily supports [OpenType][1], but also
+[Apple Advanced Typography][2]. HarfBuzz is used in Android, Chrome,
+ChromeOS, Firefox, GNOME, GTK+, KDE, Qt, LibreOffice, OpenJDK, XeTeX,
+PlayStation, Microsoft Edge, Adobe Photoshop, Illustrator, InDesign,
+Godot Engine, and other places.
+
+[![xkcd-derived image](xkcd.png)](https://xkcd.com/2347/)
+
+For bug reports, mailing list, and other information please visit:
+
+  http://harfbuzz.org/
+
+For license information, see [COPYING](COPYING).
+
+## Documentation
+
+For user manual as well as API documentation, check: https://harfbuzz.github.io
+
+## Download
+
+For tarball releases of HarfBuzz, look [here][3]. At the same place you
+will also find Win32/Win64 binary bundles that include `libharfbuzz` DLL,
+`hb-view.exe`, `hb-shape.exe`, and all dependencies.
+
+The canonical source tree is available on [github][4].
+
+The API that comes with `hb.h` will not change incompatibly. Other, peripheral,
+headers are more likely to go through minor modifications, but again, we do our
+best to never change API in an incompatible way. We will never break the ABI.
+
+If you are not sure whether Pango or HarfBuzz is right for you, read [Pango vs
+HarfBuzz][5].
+
+## Development
+
+For build information, see [BUILD.md](BUILD.md).
+
+For custom configurations, see [CONFIG.md](CONFIG.md).
+
+For testing and profiling, see [TESTING.md](TESTING.md).
+
+To get a better idea of where HarfBuzz stands in the text rendering stack you
+may want to read [State of Text Rendering][6], though, that document is many
+years old. Here are a few presentation slides about HarfBuzz at the
+Internationalization and Unicode Conference over the years:
+
+*   November 2014, [Unicode, OpenType, and HarfBuzz: Closing the Circle][7],
+*   October 2012, [HarfBuzz, The Free and Open Text Shaping Engine][8],
+*   October 2009, [HarfBuzz: the Free and Open Shaping Engine][9].
+
+Both development and user support discussion around HarfBuzz happens on the
+[github][4].
+
+To report bugs or submit patches please use [github][4] issues and
+pull-requests.
+
+For a comparison of old vs new HarfBuzz memory consumption see [this][10].
+
+<!--See past and upcoming [HarfBuzz Hackfests](https://freedesktop.org/wiki/Software/HarfBuzz/Hackfests/)!-->
+
+## Name
+
+HarfBuzz (حرف‌باز) is the literal Persian translation of “[OpenType][1]”,
+transliterated using the Latin script. It also means "talkative" or
+"glib" (also a nod to the GNOME project where HarfBuzz originates from).
+
+> Background: Originally there was this font format called TrueType. People and
+> companies started calling their type engines all things ending in Type:
+> FreeType, CoolType, ClearType, etc. And then came OpenType, which is the
+> successor of TrueType. So, for my OpenType implementation, I decided to stick
+> with the concept but use the Persian translation. Which is fitting given that
+> Persian is written in the Arabic script, and OpenType is an extension of
+> TrueType that adds support for complex script rendering, and HarfBuzz is an
+> implementation of OpenType complex text shaping.
+
+<details>
+  <summary>Packaging status of HarfBuzz</summary>
+
+[![Packaging status](https://repology.org/badge/vertical-allrepos/harfbuzz.svg?header=harfbuzz)](https://repology.org/project/harfbuzz/versions)
+
+</details>
+
+[1]: https://docs.microsoft.com/en-us/typography/opentype/spec/
+[2]: https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6AATIntro.html
+[3]: https://github.com/harfbuzz/harfbuzz/releases
+[4]: https://github.com/harfbuzz/harfbuzz
+[5]: http://mces.blogspot.com/2009/11/pango-vs-harfbuzz.html
+[6]: http://behdad.org/text/
+[7]: https://goo.gl/FSIQuC
+[8]: https://goo.gl/2wSRu
+[9]: http://behdad.org/download/Presentations/slippy/harfbuzz_slides.pdf
+[10]: https://goo.gl/woyty

+ 35 - 0
hbfreetypefont.mod/harfbuzz/README.python.md

@@ -0,0 +1,35 @@
+To enable HarfBuzz bindings for Python among other languages, make sure
+you have latest version of gobject-introspection available.  On Ubuntu,
+you can install that this way:
+
+```bash
+sudo apt-get install libgirepository1.0-dev
+```
+
+And then run `meson setup` and make sure that `Introspection` is reported
+enabled in output.
+
+If you are building with Visual Studio, it is recommended that Visual Studio
+2019 or later is used for this build, for the best build experience.
+
+Compile and install.
+
+Make sure you have the installation lib dir in `LD_LIBRARY_PATH` (or the
+installation DLL dir in `PATH` for Windows systems), as needed
+for the linker to find the library.
+
+Then make sure you also have `GI_TYPELIB_PATH` pointing to the resulting
+`$prefix/lib/girepository-*` directory.
+
+Make sure you have pygobject installed.  Then check that the following
+import works in your Python interpreter:
+
+```python
+from gi.repository import HarfBuzz
+```
+
+If it does, you are ready to call HarfBuzz from Python!  Congratulations.
+See [`src/sample.py`](src/sample.py).
+
+The Python API will change.  Let us know on the mailing list if you are
+using it, and send lots of feedback.

+ 37 - 0
hbfreetypefont.mod/harfbuzz/RELEASING.md

@@ -0,0 +1,37 @@
+# HarfBuzz release walk-through checklist:
+
+- [ ] Open gitk and review changes since last release.
+
+	- [ ] Print all public API changes:
+        `git diff $(git describe | sed 's/-.*//').. src/*.h`
+
+    - [ ]  Document them in NEWS.
+        All API and API semantic changes should be clearly marked as API additions, API changes, or API deletions.
+
+    - [ ] Document deprecations.
+        Ensure all new API / deprecations are in listed correctly in docs/harfbuzz-sections.txt.
+        If release added new API, add entry for new API index at the end of docs/harfbuzz-docs.xml.
+
+     If there's a backward-incompatible API change (including deletions for API used anywhere), that's a release blocker.
+     Do NOT release.
+
+- [ ] Based on severity of changes, decide whether it's a minor or micro release number bump.
+
+- [ ] Search for 'XSince: REPLACEME' on the repository and replace it with the chosen version for the release, e.g. 'Since: 1.4.7'.
+
+- [ ] Make sure you have correct date and new version at the top of NEWS file.
+
+- [ ] Bump version in line 3 of meson.build.
+
+- [ ] Do a `meson test -Cbuild` so it both checks the tests and updates hb-version.h (use `git diff` to see if is really updated).
+
+- [ ] Commit NEWS, meson.build, and src/hb-version.h, as well as any REPLACEME changes you made.
+        The commit message is simply the release number, e. g. "1.4.7"
+
+- [ ] Do a `meson dist -Cbuild` that runs the tests against the latest committed changes.
+   If doesn't pass, something fishy is going on, reset the repo and start over.
+
+- [ ] Tag the release and sign it: e.g. `git tag -s 1.4.7 -m 1.4.7`.
+	  Enter your GPG password.
+
+- [ ] Push the commit and tag out: `git push --follow-tags`.

+ 20 - 0
hbfreetypefont.mod/harfbuzz/SECURITY.md

@@ -0,0 +1,20 @@
+# Security Policy
+
+If you have discovered a security vulnerability in this project, please report it
+privately. **Do not disclose it as a public issue.** This gives me time to work with you
+to fix the issue before public exposure, reducing the chance that the exploit will be
+used before a patch is released.
+
+You may submit the report in the following ways:
+
+- send an email to [email protected] and [email protected]; and/or
+- send me a [private vulnerability report](https://github.com/harfbuzz/harfbuzz/security/advisories/new)
+
+Please provide the following information in your report:
+
+- A description of the vulnerability and its impact
+- How to reproduce the issue
+
+This project is mostly maintained by two developers, working on a reasonable effort
+basis. As such, we ask that you give us 90 days to work on a fix before public
+disclosure.

+ 47 - 0
hbfreetypefont.mod/harfbuzz/TESTING.md

@@ -0,0 +1,47 @@
+## Build and Test
+
+```shell
+meson build
+ninja -Cbuild
+meson test -Cbuild
+```
+
+### Debug with GDB
+
+```shell
+meson test -Cbuild --gdb testname
+```
+
+## Build and Run
+
+Depending on what area you are working in change or add `HB_DEBUG_<whatever>`.
+Values defined in `hb-debug.hh`.
+
+```shell
+CPPFLAGS='-DHB_DEBUG_SUBSET=100' meson setup build --reconfigure
+meson test -C build
+```
+
+### Run tests with asan
+
+```shell
+meson setup build -Db_sanitize=address --reconfigure
+meson compile -C build
+meson test -C build
+```
+
+### Enable Debug Logging
+
+```shell
+CPPFLAGS=-DHB_DEBUG_SUBSET=100 meson build --reconfigure
+ninja -C build
+```
+
+## Test with the Fuzzer
+
+FOr fuzzing, see `test/fuzzing/README.md`.
+
+## Profiling
+
+For profiling, see `perf/README.md`.
+

+ 7 - 0
hbfreetypefont.mod/harfbuzz/THANKS

@@ -0,0 +1,7 @@
+Bradley Grainger
+Kenichi Ishibashi
+Ivan Kuckir <https://photopea.com/>
+Ryan Lortie
+Jeff Muizelaar
+suzuki toshiya
+Philip Withnall

BIN
hbfreetypefont.mod/harfbuzz/docs/HarfBuzz.png


Fichier diff supprimé car celui-ci est trop grand
+ 2 - 0
hbfreetypefont.mod/harfbuzz/docs/HarfBuzz.svg


+ 259 - 0
hbfreetypefont.mod/harfbuzz/docs/features.dot

@@ -0,0 +1,259 @@
+digraph {
+  graph [outputorder=edgefirst];
+	node [shape="record", fontname="Noto Sans Mono SemiBold", fontsize=15];
+	edge [fontname="Verdana", fontsize=12,labeldistance=7.5 ];
+	fontname="Verdana";
+  ranksep=0.02; nodesep=0.5;
+
+subgraph {
+	ranksep="0.02 equally";
+	preprocessing[style=filled,fillcolor="lightgreen",fontname="Verdana",label="Glyph pre-processing"];
+	orthographic[style=filled,fillcolor="lightblue",fontname="Verdana",label="Orthographic Unit Shaping"];
+	reordering[style=filled, fillcolor="lightcoral",fontname="Verdana",label="Reordering group (USE)"];
+	topographic[style=filled,fillcolor="lightgoldenrod",fontname="Verdana",label="Topographical Features‡"];
+	typographic[style=filled,fillcolor="lightpink",fontname="Verdana",label="Typographic Presentation"];
+	positioning[style=filled,fillcolor="lightsalmon",fontname="Verdana",label="Positioning"];
+	preprocessing->reordering->orthographic->topographic->typographic->positioning;
+}
+
+	decision1 [shape="diamond", label="Script\ndirection?",fontname="Verdana"];
+	rvrn->decision1;
+
+	ltrfeatures [label="{ltra|ltrm}", fillcolor="lightgreen",style="filled"];
+	{
+	rtlfeatures [label="{rtla|rtlm¹}", fillcolor="lightgreen",style="filled"];
+	}
+	{
+		rank=same;
+		fracfeatures [label="frac²|numr³|dnom⁴", fillcolor="lightpink",style="filled"];
+		fracnotes [fontname="Verdana",shape=plaintext,label=<<table border="0" cellborder="0" cellspacing="0">
+			<tr><td align="left">¹ rtlm is scoped to characters with a Unicode mirroring property</td></tr>
+			<tr><td align="left">² frac is scoped to numr + the slash + dnom</td></tr>
+			<tr><td align="left">³ numr is scoped to all decimal numbers before a U+2044 FRACTION SLASH.</td></tr>
+			<tr><td align="left">⁴ dnom is scoped to all decimal numbers after a U+2044 FRACTION SLASH.</td></tr>
+	</table>
+		>];
+
+	}
+	rand [fillcolor="lightpink",style="filled"];
+
+	decision1 -> ltrfeatures [label="Left-to-right"];
+	decision1 -> rtlfeatures [label="Right-to-left"];
+
+	decision1 -> fracfeatures [label="Other"];
+
+	ltrfeatures -> fracfeatures;
+	rtlfeatures -> fracfeatures;
+	fracfeatures->rand;
+
+	decision2 [shape="diamond", label="Script?",fontname="Verdana"];
+
+{rank=same; HARF [label="{Harf|HARF}"]; notes;}
+	rand -> trak -> HARF -> decision2;
+
+	commonfeatures [shape=none,label=<<table border="0" cellspacing="0">
+                    <tr>
+                    	<td border="1" bgcolor="lightsalmon">abvm</td>
+                    	<td border="1" bgcolor="lightsalmon">blwm</td>
+                    	<td border="1" bgcolor="lightgreen">ccmp</td>
+                    	<td border="1" bgcolor="lightgreen">locl</td>
+                    	<td border="1" bgcolor="lightsalmon">mark</td>
+                    	<td border="1" bgcolor="lightsalmon">mkmk</td>
+                    	<td border="1" bgcolor="lightpink">rlig</td>
+                    </tr>
+                </table>>
+    ];
+
+	decision3 [shape="diamond", label="Script\ndirection?",fontname="Verdana"];
+
+	BUZZ  [label="{Buzz|BUZZ}"];
+	BUZZ -> commonfeatures -> decision3;
+
+	horizontalfeatures [
+	shape=none,label=<<table border="0" cellspacing="0">
+                    <tr><td border="1" bgcolor="lightpink">calt <font face="Verdana">(not Hangul)</font></td></tr>
+                    <tr><td border="1" bgcolor="lightpink">clig <font face="Verdana">(not Khmer)</font></td></tr>
+                    <tr><td border="1" bgcolor="lightsalmon">curs</td></tr>
+                    <tr><td border="1" bgcolor="lightsalmon">dist</td></tr>
+                    <tr><td border="1" bgcolor="lightsalmon">kern</td></tr>
+                    <tr><td border="1" bgcolor="lightpink">liga <font face="Verdana">(not Khmer)</font></td></tr>
+                    <tr><td border="1" bgcolor="lightpink">rclt</td></tr>
+                </table>>
+                ];
+	vert [label="vert",style=filled,fillcolor="lightpink"];
+
+	decision3 -> horizontalfeatures [label="Horizontal"];
+	decision3 -> vert [label="Vertical"];
+
+	discretionary [label="User-selected\ndiscretionary\nfeatures",fontname="Verdana"];
+
+	horizontalfeatures -> discretionary;
+	vert -> discretionary;
+
+	decision2->stch;
+
+	BUZZ;
+
+subgraph shapers {
+	subgraph cluster_arabic {
+		bgcolor="lightyellow"
+		label="Arabic, Syriac";
+	stch [ style="filled", fillcolor="lightgreen",label="stch"];
+	ccmplocl [ style="filled", label="ccmp|locl", fillcolor="lightgreen"];
+	arabicfeatures [label="isol|fina|fin2|fin3|medi|med2|init", style="filled", fillcolor="lightgoldenrod"];
+	arabicfeatures2 [label="rclt|calt", style="filled",fillcolor="lightpink"];
+rlig[style="filled",fillcolor="lightpink"];
+mset [fillcolor="lightpink",style="filled"]
+	stch->ccmplocl->arabicfeatures->rlig->arabicfeatures2->mset;
+	}
+	mset->BUZZ:n;
+
+	subgraph cluster_hangul {
+		bgcolor="lightyellow"
+		label="Hangul";
+		hangulfeatures [label="ljmo|vjmo|tjmo", style="filled",fillcolor="lightgoldenrod"]
+	}
+	  hangulfeatures->BUZZ:n;
+
+	subgraph cluster_indic {
+		label="Indic";
+		bgcolor="lightyellow"
+		// Preprocessing
+		loclccmpindic [label="locl†|ccmp†",style=filled,fillcolor="lightgreen"];
+		node[style=filled,fillcolor="lightgreen"];
+		nukt [label="nukt†"];
+		akhn [label="akhn†"];
+		loclccmpindic->indic_reorder_1->nukt->akhn;
+		indic_reorder_1[label="Initial reordering", fontname="Verdana",fillcolor="lightgrey",shape=ellipse,style=filled]
+
+		// Orthographic
+		node[style=filled,fillcolor="lightblue"]
+		rphf [label="rphf⁵"];
+		rkpf [label="rkpf†"];
+		pref [label="pref⁶"];
+		blwf [label="blwf⁷"];
+		abvf [label="abvf⁸"];
+		half [label="half⁹"];
+		pstf [label="pstf⁸"];
+		vatu [label="vatu†"];
+		cjct [label="cjct†"];
+		akhn ->rphf -> rkpf -> pref -> blwf -> abvf -> half -> pstf -> vatu -> cjct;
+		// Typographic presentation
+		indic_typographic[style=filled,fillcolor="lightpink",label="init|pres|abvs|blws|psts|haln"]
+		indic_reorder_2[label="Final reordering",fillcolor="lightgrey",fontname="Verdana", shape=ellipse,style=filled]
+		cjct->indic_reorder_2->indic_typographic;
+
+	notes2 [fontname="Verdana",shape=plaintext,style="",label=<<table border="0" cellborder="0" cellspacing="0">
+<tr><td align="right">⁵ rphf is scoped to pre-base ra+halant sequences</td></tr>
+<tr><td align="right">⁶ pref is scoped to the two glyphs after the base; outputs are reordered</td></tr>
+<tr><td align="right">⁷ blwf is usually scoped to the whole syllable, except in Telugu and Kannada where it is post-base</td></tr>
+<tr><td align="right">⁸ abvf and pstf are scoped to post-base</td></tr>
+<tr><td align="right">⁹ half is scoped to pre-base</td></tr>
+</table>
+>];
+		indic_typographic -> notes2 [style=invis];
+	}
+
+
+	subgraph cluster_khmer {
+		label="Khmer";
+		bgcolor="lightyellow"
+
+		khmerbasic [style=filled,fillcolor="lightgreen",label="locl†|ccmp†|pref†|bwlf†|abvf†|pstf†|cfar†"]
+		khmerother [style=filled,fillcolor="lightpink",label="pres|abvs|blws|psts"]
+		khmerbasic -> khmerother -> khmerclig;
+				khmerclig [label="clig",style=filled,fillcolor="lightpink"];
+	}
+
+	subgraph cluster_myanmar {
+		label="Myanmar";
+		bgcolor="lightyellow"
+		loclccmpmyanmar [label="locl†|ccmp†",style=filled,fillcolor="lightgreen"];
+		rphfmymr [label="rphf†",style=filled,fillcolor="lightblue"]
+		prefmymr [label="pref†",style=filled,fillcolor="lightblue"]
+		blwfmymr [label="blwf†",style=filled,fillcolor="lightblue"]
+		pstfmymr [label="pstf†",style=filled,fillcolor="lightblue"]
+		myanmarother [label="pres|abvs|blws|psts",style=filled,fillcolor="lightpink"];
+		reorder_myanmar[label="Reordering", shape=ellipse,style=filled,fontname="Verdana"]
+		loclccmpmyanmar -> reorder_myanmar-> rphfmymr -> prefmymr -> blwfmymr -> pstfmymr -> myanmarother;
+	}
+
+	subgraph cluster_use {
+		label="Universal Shaping Engine"
+		bgcolor="lightyellow"
+		use_preprocessing [style=filled, label="locl†|ccmp†|nukt†|akhn†", fillcolor="lightgreen"];
+		// Reoredering
+		rphfuse [label="rphf¹⁰", style=filled, fillcolor="lightcoral"];
+		prefuse [label="pref¹¹", style=filled, fillcolor="lightcoral"];
+		// Orthographic
+		orthographicuse [label="rkrf†|abvf†|blwf†|half†|pstf†|vatu†|cjct†", style="filled", fillcolor="lightblue"];
+		topographicaluse [label="isol|init|medi|fina", style="filled", fillcolor="lightgoldenrod"];
+		typographicaluse [label="abvs|blws|haln|pres|psts", style="filled", fillcolor="lightpink"];
+		reorder_use[label="Reordering", shape=ellipse,style=filled,fontname="Verdana"]
+		use_preprocessing -> rphfuse -> prefuse->orthographicuse ->reorder_use -> topographicaluse -> typographicaluse;
+			notes3 [fontname="Verdana",shape=plaintext,label=<<table border="0" cellborder="0" cellspacing="0">
+		<tr><td align="left">¹⁰ Outputs are reordered as category R</td></tr>
+		<tr><td align="left">¹¹ Outputs are reordered to before base</td></tr>
+		</table>
+		>];
+		typographicaluse -> notes3 [style=invis];
+	}
+
+}
+
+	indic_typographic->BUZZ:n;
+	typographicaluse->BUZZ:n;
+	khmerclig -> BUZZ:n;
+	myanmarother -> BUZZ:n;
+
+
+	decision2->hangulfeatures;
+	decision2->loclccmpindic;
+	decision2->khmerbasic;
+	decision2->loclccmpmyanmar;
+	decision2->use_preprocessing;
+	decision2->BUZZ [label="  Hebrew, Thai,\n  Lao, other"];
+
+notes [fontname="Verdana",shape=box,label=<<table border="0" cellborder="0" cellspacing="0">
+	<tr><td align="left">
+<b>Indic</b> scripts are: Bengali, Devanagari,
+ Gujarati, Gurmukhi, Kannada,
+ Malayalam, Oriya, Tamil,
+ Telugu
+</td></tr>
+
+	<tr><td align="left">
+<b>USE</b> scripts are:
+ Adlam, Ahom, Balinese, Batak, Bhaiksuki, Brahmi, Buginese,
+ Buhid, Chakma, Cham, Chorasmian, Dives Akuru, Dogra, Duployan,
+</td></tr>
+	<tr><td align="left">
+Egyptian hieroglyphs, Elymaic, Grantha, Gunjala Ggondi, Hanifi Rohingya,
+ Hanunoo, Javanese, Kaithi, Kayah li, Kharoshthi, Khojki,
+</td></tr>
+	<tr><td align="left">
+Khudawadi, Lepcha, Limbu, Mahajani, Makasar, Mandaic, Manichaean,
+ Marchen, Masaram Gondi, Medefaidrin, Meetei Mayek, Miao, Modi,
+</td></tr>
+	<tr><td align="left">
+Mongolian, Multani, Nandinagari, Newa, Nko, Nyiakeng Puachue Hmong,
+ Old Sogdian, Pahawh Hmong, Phags Pa, Psalter Pahlavi, Rejang,
+</td></tr>
+	<tr><td align="left">
+Saurashtra, Sharada, Siddham, Sinhala, Sogdian, Soyombo, Sundanese,
+ Syloti Nagri, Tagalog, Tagbanwa, Tai Le, Tai Tham, Tai Viet,
+</td></tr>
+	<tr><td align="left">
+Takri, Tibetan, Tifinagh, Tirhuta, Wancho, Zanabazar square,
+</td></tr>
+
+</table>>]
+
+
+	footnote[fontname="Verdana",label=<<table border="0" cellborder="0" cellspacing="0">
+		<tr><td align="left">† Feature is scoped to each syllable</td></tr>
+		<tr><td align="left">‡ All topographic features are scoped based on topographic position</td></tr>
+		</table>>];
+	notes3->footnote[style=invis];
+
+}

+ 226 - 0
hbfreetypefont.mod/harfbuzz/docs/harfbuzz-docs.xml

@@ -0,0 +1,226 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<book id="index">
+  <bookinfo>
+    <title>HarfBuzz Manual</title>
+    <abstract>
+      <title>HarfBuzz</title>
+      <graphic fileref="HarfBuzz.png" format="PNG" align="center"/>
+      <para>
+        HarfBuzz is a text shaping library. Using the HarfBuzz library allows
+	programs to convert a sequence of Unicode input into
+	properly formatted and positioned glyph output&mdash;for any writing
+	system and language.
+      </para>
+
+      <para>
+	The canonical source-code tree is available at
+        <ulink url="https://github.com/harfbuzz/harfbuzz">github.com/harfbuzz/harfbuzz</ulink>.
+	See <xref linkend="download" endterm="download.title"/> for
+	release tarballs.
+      </para>
+    </abstract>
+  </bookinfo>
+
+  <part id="user-manual">
+    <title>User's manual</title>
+      <xi:include href="usermanual-what-is-harfbuzz.xml"/>
+      <xi:include href="usermanual-install-harfbuzz.xml"/>
+      <xi:include href="usermanual-getting-started.xml"/>
+      <xi:include href="usermanual-shaping-concepts.xml"/>
+      <xi:include href="usermanual-object-model.xml"/>
+      <xi:include href="usermanual-buffers-language-script-and-direction.xml"/>
+      <xi:include href="usermanual-fonts-and-faces.xml"/>
+      <xi:include href="usermanual-opentype-features.xml"/>
+      <xi:include href="usermanual-clusters.xml"/>
+      <xi:include href="usermanual-utilities.xml"/>
+      <xi:include href="usermanual-integration.xml"/>
+  </part>
+
+  <part id="reference-manual">
+    <partinfo>
+      <releaseinfo>
+        This document is for HarfBuzz &version;.
+        <!--The latest version of this documentation can be found on-line at
+        <ulink role="online-location" url="http://[SERVER]/libharfbuzz/index.html">http://[SERVER]/libharfbuzz/</ulink>.-->
+      </releaseinfo>
+    </partinfo>
+
+    <title>Reference manual</title>
+      <chapter id="core-api">
+        <title>Core API</title>
+        <xi:include href="xml/hb-blob.xml"/>
+        <xi:include href="xml/hb-buffer.xml"/>
+        <xi:include href="xml/hb-common.xml"/>
+        <xi:include href="xml/hb-features.xml"/>
+        <xi:include href="xml/hb-draw.xml"/>
+        <xi:include href="xml/hb-paint.xml"/>
+        <xi:include href="xml/hb-deprecated.xml"/>
+        <xi:include href="xml/hb-face.xml"/>
+        <xi:include href="xml/hb-font.xml"/>
+        <xi:include href="xml/hb-map.xml"/>
+        <xi:include href="xml/hb-set.xml"/>
+        <xi:include href="xml/hb-shape-plan.xml"/>
+        <xi:include href="xml/hb-shape.xml"/>
+        <xi:include href="xml/hb-unicode.xml"/>
+        <xi:include href="xml/hb-version.xml"/>
+      </chapter>
+
+      <chapter id="opentype-api">
+        <title>OpenType API</title>
+        <xi:include href="xml/hb-ot-color.xml"/>
+        <xi:include href="xml/hb-ot-font.xml"/>
+        <xi:include href="xml/hb-ot-layout.xml"/>
+        <xi:include href="xml/hb-ot-math.xml"/>
+        <xi:include href="xml/hb-ot-meta.xml"/>
+        <xi:include href="xml/hb-ot-metrics.xml"/>
+        <xi:include href="xml/hb-ot-name.xml"/>
+        <xi:include href="xml/hb-ot-shape.xml"/>
+        <xi:include href="xml/hb-ot-var.xml"/>
+      </chapter>
+
+      <chapter id="apple-advanced-typography-api">
+        <title>Apple Advanced Typography API</title>
+        <xi:include href="xml/hb-aat-layout.xml"/>
+      </chapter>
+
+      <chapter id="integration-api">
+        <title>Integration API</title>
+        <xi:include href="xml/hb-coretext.xml"/>
+        <xi:include href="xml/hb-ft.xml"/>
+        <xi:include href="xml/hb-glib.xml"/>
+        <xi:include href="xml/hb-graphite2.xml"/>
+        <xi:include href="xml/hb-icu.xml"/>
+        <xi:include href="xml/hb-uniscribe.xml"/>
+        <xi:include href="xml/hb-gdi.xml"/>
+        <xi:include href="xml/hb-directwrite.xml"/>
+        <xi:include href="xml/hb-cairo.xml"/>
+      </chapter>
+
+      <chapter id="style-api">
+        <title>Style API</title>
+        <xi:include href="xml/hb-style.xml"/>
+      </chapter>
+
+      <chapter id="subset-api">
+        <title>Subset API</title>
+        <xi:include href="xml/hb-subset.xml"/>
+      </chapter>
+
+
+      <!--chapter id="object-tree">
+        <title>Object Hierarchy</title>
+         <xi:include href="xml/tree_index.sgml"/>
+      </chapter-->
+
+      <index id="api-index-full"><title>API Index</title><xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include></index>
+      <index id="deprecated-api-index"><title>Index of deprecated API</title><xi:include href="xml/api-index-deprecated.xml"><xi:fallback /></xi:include></index>
+
+      <index id="api-index-8-5-0"><title>Index of new symbols in 8.5.0</title><xi:include href="xml/api-index-8.5.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-8-4-0"><title>Index of new symbols in 8.4.0</title><xi:include href="xml/api-index-8.4.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-8-3-1"><title>Index of new symbols in 8.3.1</title><xi:include href="xml/api-index-8.3.1.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-8-2-0"><title>Index of new symbols in 8.2.0</title><xi:include href="xml/api-index-8.2.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-8-1-0"><title>Index of new symbols in 8.1.0</title><xi:include href="xml/api-index-8.1.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-8-0-0"><title>Index of new symbols in 8.0.0</title><xi:include href="xml/api-index-8.0.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-7-3-0"><title>Index of new symbols in 7.3.0</title><xi:include href="xml/api-index-7.3.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-7-1-0"><title>Index of new symbols in 7.1.0</title><xi:include href="xml/api-index-7.1.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-7-0-0"><title>Index of new symbols in 7.0.0</title><xi:include href="xml/api-index-7.0.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-6-0-0"><title>Index of new symbols in 6.0.0</title><xi:include href="xml/api-index-6.0.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-5-3-0"><title>Index of new symbols in 5.3.0</title><xi:include href="xml/api-index-5.3.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-5-0-0"><title>Index of new symbols in 5.0.0</title><xi:include href="xml/api-index-5.0.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-4-4-0"><title>Index of new symbols in 4.4.0</title><xi:include href="xml/api-index-4.4.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-4-3-0"><title>Index of new symbols in 4.3.0</title><xi:include href="xml/api-index-4.3.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-4-2-0"><title>Index of new symbols in 4.2.0</title><xi:include href="xml/api-index-4.2.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-4-1-0"><title>Index of new symbols in 4.1.0</title><xi:include href="xml/api-index-4.1.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-4-0-0"><title>Index of new symbols in 4.0.0</title><xi:include href="xml/api-index-4.0.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-3-4-0"><title>Index of new symbols in 3.4.0</title><xi:include href="xml/api-index-3.4.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-3-3-0"><title>Index of new symbols in 3.3.0</title><xi:include href="xml/api-index-3.3.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-3-1-0"><title>Index of new symbols in 3.1.0</title><xi:include href="xml/api-index-3.1.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-3-0-0"><title>Index of new symbols in 3.0.0</title><xi:include href="xml/api-index-3.0.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-9-1"><title>Index of new symbols in 2.9.1</title><xi:include href="xml/api-index-2.9.1.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-9-0"><title>Index of new symbols in 2.9.0</title><xi:include href="xml/api-index-2.9.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-8-2"><title>Index of new symbols in 2.8.2</title><xi:include href="xml/api-index-2.8.2.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-7-3"><title>Index of new symbols in 2.7.3</title><xi:include href="xml/api-index-2.7.3.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-6-8"><title>Index of new symbols in 2.6.8</title><xi:include href="xml/api-index-2.6.8.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-6-5"><title>Index of new symbols in 2.6.5</title><xi:include href="xml/api-index-2.6.5.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-6-3"><title>Index of new symbols in 2.6.3</title><xi:include href="xml/api-index-2.6.3.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-6-0"><title>Index of new symbols in 2.6.0</title><xi:include href="xml/api-index-2.6.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-5-0"><title>Index of new symbols in 2.5.0</title><xi:include href="xml/api-index-2.5.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-4-0"><title>Index of new symbols in 2.4.0</title><xi:include href="xml/api-index-2.4.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-3-0"><title>Index of new symbols in 2.3.0</title><xi:include href="xml/api-index-2.3.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-2-0"><title>Index of new symbols in 2.2.0</title><xi:include href="xml/api-index-2.2.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-1-0"><title>Index of new symbols in 2.1.0</title><xi:include href="xml/api-index-2.1.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-2-0-0"><title>Index of new symbols in 2.0.0</title><xi:include href="xml/api-index-2.0.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-9-0"><title>Index of new symbols in 1.9.0</title><xi:include href="xml/api-index-1.9.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-8-6"><title>Index of new symbols in 1.8.6</title><xi:include href="xml/api-index-1.8.6.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-8-5"><title>Index of new symbols in 1.8.5</title><xi:include href="xml/api-index-1.8.5.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-8-1"><title>Index of new symbols in 1.8.1</title><xi:include href="xml/api-index-1.8.1.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-8-0"><title>Index of new symbols in 1.8.0</title><xi:include href="xml/api-index-1.8.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-7-7"><title>Index of new symbols in 1.7.7</title><xi:include href="xml/api-index-1.7.7.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-7-2"><title>Index of new symbols in 1.7.2</title><xi:include href="xml/api-index-1.7.2.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-6-0"><title>Index of new symbols in 1.6.0</title><xi:include href="xml/api-index-1.6.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-5-0"><title>Index of new symbols in 1.5.0</title><xi:include href="xml/api-index-1.5.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-4-3"><title>Index of new symbols in 1.4.3</title><xi:include href="xml/api-index-1.4.3.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-4-2"><title>Index of new symbols in 1.4.2</title><xi:include href="xml/api-index-1.4.2.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-4-0"><title>Index of new symbols in 1.4.0</title><xi:include href="xml/api-index-1.4.0.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-3-3"><title>Index of new symbols in 1.3.3</title><xi:include href="xml/api-index-1.3.3.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-2-3"><title>Index of new symbols in 1.2.3</title><xi:include href="xml/api-index-1.2.3.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-1-3"><title>Index of new symbols in 1.1.3</title><xi:include href="xml/api-index-1.1.3.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-1-2"><title>Index of new symbols in 1.1.2</title><xi:include href="xml/api-index-1.1.2.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-1-0-5"><title>Index of new symbols in 1.0.5</title><xi:include href="xml/api-index-1.0.5.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-42"><title>Index of new symbols in 0.9.42</title><xi:include href="xml/api-index-0.9.42.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-41"><title>Index of new symbols in 0.9.41</title><xi:include href="xml/api-index-0.9.41.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-39"><title>Index of new symbols in 0.9.39</title><xi:include href="xml/api-index-0.9.39.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-38"><title>Index of new symbols in 0.9.38</title><xi:include href="xml/api-index-0.9.38.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-33"><title>Index of new symbols in 0.9.33</title><xi:include href="xml/api-index-0.9.33.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-31"><title>Index of new symbols in 0.9.31</title><xi:include href="xml/api-index-0.9.31.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-30"><title>Index of new symbols in 0.9.30</title><xi:include href="xml/api-index-0.9.30.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-28"><title>Index of new symbols in 0.9.28</title><xi:include href="xml/api-index-0.9.28.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-26"><title>Index of new symbols in 0.9.26</title><xi:include href="xml/api-index-0.9.26.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-22"><title>Index of new symbols in 0.9.22</title><xi:include href="xml/api-index-0.9.22.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-21"><title>Index of new symbols in 0.9.21</title><xi:include href="xml/api-index-0.9.21.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-20"><title>Index of new symbols in 0.9.20</title><xi:include href="xml/api-index-0.9.20.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-11"><title>Index of new symbols in 0.9.11</title><xi:include href="xml/api-index-0.9.11.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-10"><title>Index of new symbols in 0.9.10</title><xi:include href="xml/api-index-0.9.10.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-8"><title>Index of new symbols in 0.9.8</title><xi:include href="xml/api-index-0.9.8.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-7"><title>Index of new symbols in 0.9.7</title><xi:include href="xml/api-index-0.9.7.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-5"><title>Index of new symbols in 0.9.5</title><xi:include href="xml/api-index-0.9.5.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-9-2"><title>Index of new symbols in 0.9.2</title><xi:include href="xml/api-index-0.9.2.xml"><xi:fallback /></xi:include></index>
+      <index id="api-index-0-6-0"><title>Index of new symbols in 0.6.0</title><xi:include href="xml/api-index-0.6.0.xml"><xi:fallback /></xi:include></index>
+
+      <xi:include href="xml/annotation-glossary.xml"><xi:fallback /></xi:include>
+  </part>
+
+  <note>
+    <para>
+      The current HarfBuzz codebase is stable
+      and under active maintenance. This is what is used in latest
+      versions of Firefox, GNOME, ChromeOS, Chrome, LibreOffice,
+      XeTeX, Android, and KDE, among other places.
+    </para>
+    <para>
+      Prior to 2012, the original HarfBuzz codebase (which, these days, is
+      referred to as <emphasis>harfbuzz-old</emphasis>) was derived from code
+      in <ulink url="http://freetype.org/">FreeType</ulink>,
+      <ulink url="http://pango.org/">Pango</ulink>, and
+      <ulink url="http://qt-project.org/">Qt</ulink>.
+      It is <emphasis>not</emphasis> actively developed or  maintained, and is
+      extremely buggy. All users of harfbuzz-old are encouraged to switch over
+      to the new HarfBuzz as soon as possible.
+    </para>
+    <para>
+      To make this distinction clearer in discussions, the current HarfBuzz
+      codebase is sometimes referred to as <emphasis>harfbuzz-ng</emphasis>.
+    </para>
+    <para>
+      For reference purposes, the harfbuzz-old source tree is archived
+      <ulink url="http://cgit.freedesktop.org/harfbuzz.old/">here</ulink>.
+      There are no release tarballs of harfbuzz-old whatsoever.
+    </para>
+  </note>
+
+</book>

+ 0 - 0
hbfreetypefont.mod/harfbuzz/docs/harfbuzz-overrides.txt


+ 928 - 0
hbfreetypefont.mod/harfbuzz/docs/harfbuzz-sections.txt

@@ -0,0 +1,928 @@
+<SECTION>
+<FILE>hb-aat-layout</FILE>
+HB_AAT_LAYOUT_NO_SELECTOR_INDEX
+hb_aat_layout_feature_type_t
+hb_aat_layout_feature_selector_t
+hb_aat_layout_feature_selector_info_t
+hb_aat_layout_feature_type_get_name_id
+hb_aat_layout_feature_type_get_selector_infos
+hb_aat_layout_get_feature_types
+hb_aat_layout_has_positioning
+hb_aat_layout_has_substitution
+hb_aat_layout_has_tracking
+</SECTION>
+
+<SECTION>
+<FILE>hb-blob</FILE>
+hb_blob_create
+hb_blob_create_or_fail
+hb_blob_create_from_file
+hb_blob_create_from_file_or_fail
+hb_blob_create_sub_blob
+hb_blob_copy_writable_or_fail
+hb_blob_get_empty
+hb_blob_reference
+hb_blob_destroy
+hb_blob_set_user_data
+hb_blob_get_user_data
+hb_blob_make_immutable
+hb_blob_is_immutable
+hb_blob_get_data
+hb_blob_get_data_writable
+hb_blob_get_length
+hb_blob_t
+hb_memory_mode_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-buffer</FILE>
+hb_buffer_create
+hb_buffer_allocation_successful
+hb_buffer_create_similar
+hb_buffer_get_empty
+hb_buffer_reference
+hb_buffer_destroy
+hb_buffer_set_user_data
+hb_buffer_get_user_data
+hb_buffer_reset
+hb_buffer_clear_contents
+hb_buffer_pre_allocate
+hb_buffer_add
+hb_buffer_add_codepoints
+hb_buffer_add_utf32
+hb_buffer_add_utf16
+hb_buffer_add_utf8
+hb_buffer_add_latin1
+hb_buffer_append
+hb_buffer_set_content_type
+hb_buffer_get_content_type
+hb_buffer_set_direction
+hb_buffer_get_direction
+hb_buffer_set_script
+hb_buffer_get_script
+hb_buffer_set_language
+hb_buffer_get_language
+hb_buffer_set_flags
+hb_buffer_get_flags
+hb_buffer_set_cluster_level
+hb_buffer_get_cluster_level
+hb_buffer_set_length
+hb_buffer_get_length
+hb_buffer_set_segment_properties
+hb_buffer_get_segment_properties
+hb_buffer_guess_segment_properties
+hb_buffer_set_unicode_funcs
+hb_buffer_get_unicode_funcs
+hb_buffer_get_glyph_infos
+hb_glyph_info_get_glyph_flags
+hb_buffer_get_glyph_positions
+hb_buffer_has_positions
+hb_buffer_set_invisible_glyph
+hb_buffer_get_invisible_glyph
+hb_buffer_set_not_found_glyph
+hb_buffer_get_not_found_glyph
+hb_buffer_set_replacement_codepoint
+hb_buffer_get_replacement_codepoint
+hb_buffer_set_random_state
+hb_buffer_get_random_state
+hb_buffer_normalize_glyphs
+hb_buffer_reverse
+hb_buffer_reverse_range
+hb_buffer_reverse_clusters
+hb_buffer_serialize
+hb_buffer_serialize_glyphs
+hb_buffer_deserialize_glyphs
+hb_buffer_serialize_unicode
+hb_buffer_deserialize_unicode
+hb_buffer_serialize_format_from_string
+hb_buffer_serialize_format_to_string
+hb_buffer_serialize_list_formats
+hb_segment_properties_equal
+hb_segment_properties_hash
+hb_segment_properties_overlay
+hb_buffer_diff
+hb_buffer_message_func_t
+hb_buffer_set_message_func
+HB_SEGMENT_PROPERTIES_DEFAULT
+HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT
+hb_buffer_t
+hb_glyph_info_t
+hb_glyph_flags_t
+hb_glyph_position_t
+hb_buffer_content_type_t
+hb_buffer_flags_t
+hb_buffer_cluster_level_t
+hb_segment_properties_t
+hb_buffer_serialize_format_t
+hb_buffer_serialize_flags_t
+hb_buffer_diff_flags_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-common</FILE>
+HB_TAG
+HB_UNTAG
+hb_tag_from_string
+hb_tag_to_string
+hb_direction_from_string
+hb_direction_to_string
+HB_DIRECTION_REVERSE
+HB_DIRECTION_IS_BACKWARD
+HB_DIRECTION_IS_FORWARD
+HB_DIRECTION_IS_HORIZONTAL
+HB_DIRECTION_IS_VALID
+HB_DIRECTION_IS_VERTICAL
+hb_script_from_iso15924_tag
+hb_script_to_iso15924_tag
+hb_script_from_string
+hb_script_get_horizontal_direction
+hb_language_from_string
+hb_language_to_string
+hb_language_get_default
+hb_language_matches
+hb_feature_from_string
+hb_feature_to_string
+hb_variation_from_string
+hb_variation_to_string
+hb_bool_t
+hb_codepoint_t
+HB_CODEPOINT_INVALID
+hb_destroy_func_t
+hb_direction_t
+hb_language_t
+hb_feature_t
+hb_variation_t
+hb_mask_t
+hb_position_t
+hb_tag_t
+hb_script_t
+hb_user_data_key_t
+HB_TAG_NONE
+HB_TAG_MAX
+HB_TAG_MAX_SIGNED
+HB_LANGUAGE_INVALID
+HB_FEATURE_GLOBAL_END
+HB_FEATURE_GLOBAL_START
+<SUBSECTION Private>
+HB_BEGIN_DECLS
+HB_END_DECLS
+hb_var_int_t
+hb_var_num_t
+int16_t
+int32_t
+int64_t
+int8_t
+uint16_t
+uint32_t
+uint64_t
+uint8_t
+HB_EXTERN
+HB_DEPRECATED
+HB_DEPRECATED_FOR
+<SUBSECTION Private>
+HB_H_IN
+HB_OT_H_IN
+HB_AAT_H_IN
+</SECTION>
+
+<SECTION>
+<FILE>hb-features</FILE>
+HB_HAS_CAIRO
+HB_HAS_CORETEXT
+HB_HAS_DIRECTWRITE
+HB_HAS_FREETYPE
+HB_HAS_GDI
+HB_HAS_GLIB
+HB_HAS_GOBJECT
+HB_HAS_GRAPHITE
+HB_HAS_ICU
+HB_HAS_UNISCRIBE
+HB_HAS_WASM
+</SECTION>
+
+<SECTION>
+<FILE>hb-draw</FILE>
+hb_draw_funcs_create
+hb_draw_funcs_get_empty
+hb_draw_funcs_reference
+hb_draw_funcs_destroy
+hb_draw_funcs_set_user_data
+hb_draw_funcs_get_user_data
+hb_draw_funcs_make_immutable
+hb_draw_funcs_is_immutable
+hb_draw_move_to_func_t
+hb_draw_funcs_set_move_to_func
+hb_draw_line_to_func_t
+hb_draw_funcs_set_line_to_func
+hb_draw_quadratic_to_func_t
+hb_draw_funcs_set_quadratic_to_func
+hb_draw_cubic_to_func_t
+hb_draw_funcs_set_cubic_to_func
+hb_draw_close_path_func_t
+hb_draw_funcs_set_close_path_func
+hb_draw_move_to
+hb_draw_line_to
+hb_draw_quadratic_to
+hb_draw_cubic_to
+hb_draw_close_path
+HB_DRAW_STATE_DEFAULT
+hb_draw_funcs_t
+hb_draw_state_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-paint</FILE>
+hb_paint_funcs_t
+hb_paint_funcs_create
+hb_paint_funcs_get_empty
+hb_paint_funcs_reference
+hb_paint_funcs_destroy
+hb_paint_funcs_set_user_data
+hb_paint_funcs_get_user_data
+hb_paint_funcs_make_immutable
+hb_paint_funcs_is_immutable
+
+hb_paint_push_transform_func_t
+hb_paint_funcs_set_push_transform_func
+hb_paint_pop_transform_func_t
+hb_paint_funcs_set_pop_transform_func
+hb_paint_color_glyph_func_t
+hb_paint_funcs_set_color_glyph_func
+hb_paint_push_clip_glyph_func_t
+hb_paint_funcs_set_push_clip_glyph_func
+hb_paint_push_clip_rectangle_func_t
+hb_paint_funcs_set_push_clip_rectangle_func
+hb_paint_pop_clip_func_t
+hb_paint_funcs_set_pop_clip_func
+hb_paint_color_func_t
+hb_paint_funcs_set_color_func
+HB_PAINT_IMAGE_FORMAT_PNG
+HB_PAINT_IMAGE_FORMAT_SVG
+HB_PAINT_IMAGE_FORMAT_BGRA
+hb_paint_image_func_t
+hb_paint_funcs_set_image_func
+hb_color_line_t
+hb_color_stop_t
+hb_color_line_get_color_stops_func_t
+hb_color_line_get_color_stops
+hb_paint_extend_t
+hb_color_line_get_extend_func_t
+hb_color_line_get_extend
+hb_paint_linear_gradient_func_t
+hb_paint_funcs_set_linear_gradient_func
+hb_paint_radial_gradient_func_t
+hb_paint_funcs_set_radial_gradient_func
+hb_paint_sweep_gradient_func_t
+hb_paint_funcs_set_sweep_gradient_func
+hb_paint_composite_mode_t
+hb_paint_push_group_func_t
+hb_paint_funcs_set_push_group_func
+hb_paint_pop_group_func_t
+hb_paint_funcs_set_pop_group_func
+hb_paint_custom_palette_color_func_t
+hb_paint_funcs_set_custom_palette_color_func
+
+hb_paint_push_transform
+hb_paint_pop_transform
+hb_paint_color_glyph
+hb_paint_push_clip_glyph
+hb_paint_push_clip_rectangle
+hb_paint_pop_clip
+hb_paint_color
+hb_paint_image
+hb_paint_linear_gradient
+hb_paint_radial_gradient
+hb_paint_sweep_gradient
+hb_paint_push_group
+hb_paint_pop_group
+hb_paint_custom_palette_color
+</SECTION>
+
+<SECTION>
+<FILE>hb-deprecated</FILE>
+HB_BUFFER_FLAGS_DEFAULT
+HB_BUFFER_SERIALIZE_FLAGS_DEFAULT
+HB_SCRIPT_CANADIAN_ABORIGINAL
+hb_font_funcs_set_glyph_func
+hb_font_get_glyph_func_t
+HB_MATH_GLYPH_PART_FLAG_EXTENDER
+HB_OT_MATH_SCRIPT
+hb_ot_layout_table_choose_script
+hb_ot_layout_table_find_script
+hb_ot_tag_from_language
+hb_ot_tags_from_script
+HB_OT_VAR_NO_AXIS_INDEX
+hb_ot_var_axis_t
+hb_ot_var_find_axis
+hb_ot_var_get_axes
+hb_unicode_eastasian_width_func_t
+hb_unicode_eastasian_width
+hb_unicode_funcs_set_eastasian_width_func
+HB_UNICODE_MAX_DECOMPOSITION_LEN
+hb_unicode_decompose_compatibility_func_t
+hb_unicode_decompose_compatibility
+hb_unicode_funcs_set_decompose_compatibility_func
+HB_UNICODE_COMBINING_CLASS_CCC133
+hb_font_funcs_set_glyph_v_kerning_func
+hb_font_get_glyph_shape
+hb_font_get_glyph_shape_func_t
+hb_font_funcs_set_glyph_shape_func
+hb_font_get_glyph_v_kerning
+hb_font_get_glyph_v_kerning_func_t
+HB_AAT_LAYOUT_FEATURE_TYPE_CURISVE_CONNECTION
+</SECTION>
+
+<SECTION>
+<FILE>hb-coretext</FILE>
+HB_CORETEXT_TAG_KERX
+HB_CORETEXT_TAG_MORT
+HB_CORETEXT_TAG_MORX
+hb_coretext_face_create
+hb_coretext_font_create
+hb_coretext_face_get_cg_font
+hb_coretext_font_get_ct_font
+</SECTION>
+
+<SECTION>
+<FILE>hb-directwrite</FILE>
+hb_directwrite_face_create
+hb_directwrite_face_get_font_face
+</SECTION>
+
+<SECTION>
+<FILE>hb-face</FILE>
+hb_face_count
+hb_face_t
+hb_face_create
+hb_face_create_for_tables
+hb_face_get_empty
+hb_face_reference
+hb_face_destroy
+hb_face_set_user_data
+hb_face_get_user_data
+hb_face_make_immutable
+hb_face_is_immutable
+hb_face_get_table_tags
+hb_face_set_glyph_count
+hb_face_get_glyph_count
+hb_face_set_index
+hb_face_get_index
+hb_face_set_upem
+hb_face_get_upem
+hb_face_reference_blob
+hb_face_reference_table
+hb_face_collect_unicodes
+hb_face_collect_nominal_glyph_mapping
+hb_face_collect_variation_selectors
+hb_face_collect_variation_unicodes
+hb_face_builder_create
+hb_face_builder_add_table
+hb_face_builder_sort_tables
+</SECTION>
+
+<SECTION>
+<FILE>hb-font</FILE>
+hb_font_add_glyph_origin_for_direction
+hb_font_create
+hb_font_create_sub_font
+hb_font_get_empty
+hb_font_reference
+hb_font_destroy
+hb_font_set_user_data
+hb_font_get_user_data
+hb_font_make_immutable
+hb_font_is_immutable
+hb_font_set_face
+hb_font_get_face
+hb_font_get_glyph
+hb_font_get_glyph_advance_for_direction
+hb_font_get_glyph_advances_for_direction
+hb_font_get_glyph_contour_point
+hb_font_get_glyph_contour_point_for_origin
+hb_font_get_glyph_extents
+hb_font_get_glyph_extents_for_origin
+hb_font_get_glyph_from_name
+hb_font_get_glyph_h_advance
+hb_font_get_glyph_v_advance
+hb_font_get_glyph_h_advances
+hb_font_get_glyph_v_advances
+hb_font_get_glyph_h_kerning
+hb_font_get_glyph_kerning_for_direction
+hb_font_get_glyph_h_origin
+hb_font_get_glyph_v_origin
+hb_font_get_glyph_origin_for_direction
+hb_font_get_glyph_name
+hb_font_draw_glyph
+hb_font_paint_glyph
+hb_font_get_nominal_glyph
+hb_font_get_nominal_glyphs
+hb_font_get_variation_glyph
+hb_font_set_parent
+hb_font_get_parent
+hb_font_set_ppem
+hb_font_get_ppem
+hb_font_set_ptem
+hb_font_get_ptem
+hb_font_set_scale
+hb_font_get_scale
+hb_font_get_synthetic_bold
+hb_font_set_synthetic_bold
+hb_font_set_synthetic_slant
+hb_font_get_synthetic_slant
+hb_font_set_variations
+hb_font_set_variation
+HB_FONT_NO_VAR_NAMED_INSTANCE
+hb_font_set_var_named_instance
+hb_font_get_var_named_instance
+hb_font_set_var_coords_design
+hb_font_get_var_coords_design
+hb_font_set_var_coords_normalized
+hb_font_get_var_coords_normalized
+hb_font_glyph_from_string
+hb_font_glyph_to_string
+hb_font_get_serial
+hb_font_changed
+hb_font_set_funcs
+hb_font_set_funcs_data
+hb_font_subtract_glyph_origin_for_direction
+hb_font_funcs_create
+hb_font_funcs_get_empty
+hb_font_funcs_reference
+hb_font_funcs_destroy
+hb_font_funcs_set_user_data
+hb_font_funcs_get_user_data
+hb_font_funcs_make_immutable
+hb_font_funcs_is_immutable
+hb_font_get_glyph_contour_point_func_t
+hb_font_funcs_set_glyph_contour_point_func
+hb_font_get_glyph_extents_func_t
+hb_font_funcs_set_glyph_extents_func
+hb_font_get_glyph_from_name_func_t
+hb_font_funcs_set_glyph_from_name_func
+hb_font_get_glyph_advance_func_t
+hb_font_get_glyph_h_advance_func_t
+hb_font_funcs_set_glyph_h_advance_func
+hb_font_get_glyph_v_advance_func_t
+hb_font_funcs_set_glyph_v_advance_func
+hb_font_get_glyph_advances_func_t
+hb_font_get_glyph_h_advances_func_t
+hb_font_funcs_set_glyph_h_advances_func
+hb_font_get_glyph_v_advances_func_t
+hb_font_funcs_set_glyph_v_advances_func
+hb_font_get_glyph_kerning_func_t
+hb_font_get_glyph_h_kerning_func_t
+hb_font_funcs_set_glyph_h_kerning_func
+hb_font_get_glyph_origin_func_t
+hb_font_get_glyph_h_origin_func_t
+hb_font_funcs_set_glyph_h_origin_func
+hb_font_get_glyph_v_origin_func_t
+hb_font_funcs_set_glyph_v_origin_func
+hb_font_get_glyph_name_func_t
+hb_font_funcs_set_glyph_name_func
+hb_font_draw_glyph_func_t
+hb_font_funcs_set_draw_glyph_func
+hb_font_paint_glyph_func_t
+hb_font_funcs_set_paint_glyph_func
+hb_font_get_nominal_glyph_func_t
+hb_font_funcs_set_nominal_glyph_func
+hb_font_get_nominal_glyphs_func_t
+hb_font_funcs_set_nominal_glyphs_func
+hb_font_get_variation_glyph_func_t
+hb_font_funcs_set_variation_glyph_func
+hb_font_funcs_t
+hb_font_t
+hb_reference_table_func_t
+hb_font_get_font_extents_func_t
+hb_font_get_font_h_extents_func_t
+hb_font_funcs_set_font_h_extents_func
+hb_font_get_font_v_extents_func_t
+hb_font_funcs_set_font_v_extents_func
+hb_font_get_h_extents
+hb_font_get_v_extents
+hb_font_get_extents_for_direction
+hb_font_extents_t
+hb_glyph_extents_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-ft</FILE>
+hb_ft_face_create
+hb_ft_face_create_cached
+hb_ft_face_create_referenced
+hb_ft_font_create
+hb_ft_font_create_referenced
+hb_ft_font_changed
+hb_ft_font_get_face
+hb_ft_font_lock_face
+hb_ft_font_unlock_face
+hb_ft_font_set_load_flags
+hb_ft_font_get_load_flags
+hb_ft_font_set_funcs
+hb_ft_hb_font_changed
+</SECTION>
+
+<SECTION>
+<FILE>hb-gdi</FILE>
+hb_gdi_face_create
+</SECTION>
+
+<SECTION>
+<FILE>hb-glib</FILE>
+hb_glib_get_unicode_funcs
+hb_glib_script_from_script
+hb_glib_script_to_script
+hb_glib_blob_create
+</SECTION>
+
+<SECTION>
+<FILE>hb-graphite2</FILE>
+HB_GRAPHITE2_TAG_SILF
+hb_graphite2_face_get_gr_face
+hb_graphite2_font_get_gr_font
+</SECTION>
+
+<SECTION>
+<FILE>hb-icu</FILE>
+hb_icu_get_unicode_funcs
+hb_icu_script_from_script
+hb_icu_script_to_script
+</SECTION>
+
+<SECTION>
+<FILE>hb-map</FILE>
+hb_map_create
+hb_map_allocation_successful
+hb_map_copy
+hb_map_clear
+hb_map_get_empty
+hb_map_reference
+hb_map_destroy
+hb_map_set_user_data
+hb_map_get_user_data
+hb_map_set
+hb_map_get
+hb_map_del
+hb_map_has
+hb_map_get_population
+hb_map_is_empty
+hb_map_is_equal
+hb_map_hash
+hb_map_update
+hb_map_next
+hb_map_keys
+hb_map_values
+HB_MAP_VALUE_INVALID
+hb_map_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-ot-color</FILE>
+HB_COLOR
+hb_color_get_alpha
+hb_color_get_blue
+hb_color_get_green
+hb_color_get_red
+hb_ot_color_has_layers
+hb_ot_color_glyph_get_layers
+hb_ot_color_has_palettes
+hb_ot_color_palette_get_count
+hb_ot_color_palette_get_colors
+hb_ot_color_palette_get_flags
+hb_ot_color_palette_get_name_id
+hb_ot_color_palette_color_get_name_id
+hb_ot_color_has_paint
+hb_ot_color_glyph_has_paint
+hb_ot_color_has_png
+hb_ot_color_glyph_reference_png
+hb_ot_color_has_svg
+hb_ot_color_glyph_reference_svg
+hb_color_t
+hb_ot_color_layer_t
+hb_ot_color_palette_flags_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-ot-font</FILE>
+hb_ot_font_set_funcs
+</SECTION>
+
+<SECTION>
+<FILE>hb-ot-name</FILE>
+hb_ot_name_list_names
+hb_ot_name_get_utf16
+hb_ot_name_get_utf32
+hb_ot_name_get_utf8
+hb_ot_name_id_t
+hb_ot_name_id_predefined_t
+hb_ot_name_entry_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-ot-layout</FILE>
+hb_ot_tag_to_language
+hb_ot_tag_to_script
+hb_ot_tags_from_script_and_language
+hb_ot_tags_to_script_and_language
+hb_ot_layout_collect_lookups
+hb_ot_layout_collect_features
+hb_ot_layout_collect_features_map
+hb_ot_layout_feature_get_characters
+hb_ot_layout_feature_get_lookups
+hb_ot_layout_feature_get_name_ids
+hb_ot_layout_feature_with_variations_get_lookups
+hb_ot_layout_get_attach_points
+hb_ot_layout_get_font_extents
+hb_ot_layout_get_font_extents2
+hb_ot_layout_get_horizontal_baseline_tag_for_script
+hb_ot_layout_get_baseline
+hb_ot_layout_get_baseline2
+hb_ot_layout_get_baseline_with_fallback
+hb_ot_layout_get_baseline_with_fallback2
+hb_ot_layout_get_glyph_class
+hb_ot_layout_get_glyphs_in_class
+hb_ot_layout_get_ligature_carets
+hb_ot_layout_get_size_params
+hb_ot_layout_has_glyph_classes
+hb_ot_layout_has_positioning
+hb_ot_layout_has_substitution
+hb_ot_layout_language_find_feature
+hb_ot_layout_language_get_feature_indexes
+hb_ot_layout_language_get_feature_tags
+hb_ot_layout_language_get_required_feature
+hb_ot_layout_lookup_collect_glyphs
+hb_ot_layout_lookup_get_glyph_alternates
+hb_ot_layout_lookup_get_optical_bound
+hb_ot_layout_lookup_substitute_closure
+hb_ot_layout_lookups_substitute_closure
+hb_ot_layout_lookup_would_substitute
+hb_ot_layout_script_find_language
+hb_ot_layout_script_get_language_tags
+hb_ot_layout_script_select_language
+hb_ot_layout_script_select_language2
+hb_ot_layout_table_find_feature_variations
+hb_ot_layout_table_get_feature_tags
+hb_ot_layout_table_get_script_tags
+hb_ot_layout_table_get_lookup_count
+hb_ot_layout_table_select_script
+hb_ot_shape_plan_collect_lookups
+hb_ot_layout_language_get_required_feature_index
+HB_OT_MAX_TAGS_PER_LANGUAGE
+HB_OT_MAX_TAGS_PER_SCRIPT
+HB_OT_TAG_DEFAULT_LANGUAGE
+HB_OT_TAG_DEFAULT_SCRIPT
+HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX
+HB_OT_LAYOUT_NO_FEATURE_INDEX
+HB_OT_LAYOUT_NO_SCRIPT_INDEX
+HB_OT_LAYOUT_NO_VARIATIONS_INDEX
+HB_OT_TAG_BASE
+HB_OT_TAG_GDEF
+HB_OT_TAG_GPOS
+HB_OT_TAG_GSUB
+HB_OT_TAG_JSTF
+hb_ot_layout_baseline_tag_t
+hb_ot_layout_glyph_class_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-ot-math</FILE>
+hb_ot_math_has_data
+hb_ot_math_get_constant
+hb_ot_math_get_glyph_italics_correction
+hb_ot_math_get_glyph_top_accent_attachment
+hb_ot_math_get_glyph_kerning
+hb_ot_math_get_glyph_kernings
+hb_ot_math_is_glyph_extended_shape
+hb_ot_math_get_glyph_variants
+hb_ot_math_get_min_connector_overlap
+hb_ot_math_get_glyph_assembly
+HB_OT_TAG_MATH
+HB_OT_TAG_MATH_SCRIPT
+hb_ot_math_constant_t
+hb_ot_math_kern_t
+hb_ot_math_kern_entry_t
+hb_ot_math_glyph_variant_t
+hb_ot_math_glyph_part_flags_t
+hb_ot_math_glyph_part_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-ot-meta</FILE>
+hb_ot_meta_get_entry_tags
+hb_ot_meta_reference_entry
+hb_ot_meta_tag_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-ot-metrics</FILE>
+hb_ot_metrics_get_position
+hb_ot_metrics_get_position_with_fallback
+hb_ot_metrics_get_variation
+hb_ot_metrics_get_x_variation
+hb_ot_metrics_get_y_variation
+hb_ot_metrics_tag_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-ot-shape</FILE>
+hb_ot_shape_glyphs_closure
+</SECTION>
+
+<SECTION>
+<FILE>hb-ot-var</FILE>
+hb_ot_var_has_data
+hb_ot_var_find_axis_info
+hb_ot_var_get_axis_count
+hb_ot_var_get_axis_infos
+hb_ot_var_get_named_instance_count
+hb_ot_var_named_instance_get_subfamily_name_id
+hb_ot_var_named_instance_get_postscript_name_id
+hb_ot_var_named_instance_get_design_coords
+hb_ot_var_normalize_variations
+hb_ot_var_normalize_coords
+HB_OT_TAG_VAR_AXIS_ITALIC
+HB_OT_TAG_VAR_AXIS_OPTICAL_SIZE
+HB_OT_TAG_VAR_AXIS_SLANT
+HB_OT_TAG_VAR_AXIS_WEIGHT
+HB_OT_TAG_VAR_AXIS_WIDTH
+hb_ot_var_axis_flags_t
+hb_ot_var_axis_info_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-set</FILE>
+hb_set_create
+hb_set_allocation_successful
+hb_set_copy
+hb_set_get_empty
+hb_set_reference
+hb_set_destroy
+hb_set_set_user_data
+hb_set_get_user_data
+hb_set_clear
+hb_set_set
+hb_set_has
+hb_set_add
+hb_set_add_range
+hb_set_add_sorted_array
+hb_set_del
+hb_set_del_range
+hb_set_get_max
+hb_set_get_min
+hb_set_get_population
+hb_set_is_empty
+hb_set_hash
+hb_set_subtract
+hb_set_intersect
+hb_set_union
+hb_set_symmetric_difference
+hb_set_invert
+hb_set_is_inverted
+hb_set_is_equal
+hb_set_is_subset
+hb_set_next
+hb_set_next_range
+hb_set_next_many
+hb_set_previous
+hb_set_previous_range
+HB_SET_VALUE_INVALID
+hb_set_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-shape</FILE>
+hb_shape
+hb_shape_full
+hb_shape_justify
+hb_shape_list_shapers
+</SECTION>
+
+<SECTION>
+<FILE>hb-shape-plan</FILE>
+hb_shape_plan_create
+hb_shape_plan_create_cached
+hb_shape_plan_create2
+hb_shape_plan_create_cached2
+hb_shape_plan_get_empty
+hb_shape_plan_reference
+hb_shape_plan_destroy
+hb_shape_plan_set_user_data
+hb_shape_plan_get_user_data
+hb_shape_plan_execute
+hb_shape_plan_get_shaper
+hb_shape_plan_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-unicode</FILE>
+hb_unicode_general_category
+hb_unicode_combining_class
+hb_unicode_mirroring
+hb_unicode_script
+hb_unicode_compose
+hb_unicode_decompose
+hb_unicode_funcs_create
+hb_unicode_funcs_get_empty
+hb_unicode_funcs_reference
+hb_unicode_funcs_destroy
+hb_unicode_funcs_set_user_data
+hb_unicode_funcs_get_user_data
+hb_unicode_funcs_make_immutable
+hb_unicode_funcs_is_immutable
+hb_unicode_funcs_get_default
+hb_unicode_funcs_get_parent
+hb_unicode_general_category_func_t
+hb_unicode_funcs_set_general_category_func
+hb_unicode_combining_class_func_t
+hb_unicode_funcs_set_combining_class_func
+hb_unicode_mirroring_func_t
+hb_unicode_funcs_set_mirroring_func
+hb_unicode_script_func_t
+hb_unicode_funcs_set_script_func
+hb_unicode_compose_func_t
+hb_unicode_funcs_set_compose_func
+hb_unicode_decompose_func_t
+hb_unicode_funcs_set_decompose_func
+HB_UNICODE_MAX
+hb_unicode_combining_class_t
+hb_unicode_general_category_t
+hb_unicode_funcs_t
+</SECTION>
+
+<SECTION>
+<FILE>hb-uniscribe</FILE>
+hb_uniscribe_font_get_hfont
+hb_uniscribe_font_get_logfontw
+</SECTION>
+
+<SECTION>
+<FILE>hb-version</FILE>
+HB_VERSION_ATLEAST
+hb_version
+hb_version_atleast
+hb_version_string
+HB_VERSION_MAJOR
+HB_VERSION_MICRO
+HB_VERSION_MINOR
+HB_VERSION_STRING
+</SECTION>
+
+<SECTION>
+<FILE>hb-style</FILE>
+hb_style_tag_t
+hb_style_get_value
+</SECTION>
+
+<SECTION>
+<FILE>hb-subset</FILE>
+hb_subset_input_create_or_fail
+hb_subset_input_reference
+hb_subset_input_destroy
+hb_subset_input_set_user_data
+hb_subset_input_get_user_data
+hb_subset_input_keep_everything
+hb_subset_input_set_flags
+hb_subset_input_get_flags
+hb_subset_input_unicode_set
+hb_subset_input_glyph_set
+hb_subset_input_set
+hb_subset_input_old_to_new_glyph_mapping
+hb_subset_input_pin_all_axes_to_default
+hb_subset_input_pin_axis_location
+hb_subset_input_pin_axis_to_default
+hb_subset_input_get_axis_range
+hb_subset_input_set_axis_range
+hb_subset_or_fail
+hb_subset_plan_create_or_fail
+hb_subset_plan_reference
+hb_subset_plan_destroy
+hb_subset_plan_set_user_data
+hb_subset_plan_get_user_data
+hb_subset_plan_execute_or_fail
+hb_subset_plan_unicode_to_old_glyph_mapping
+hb_subset_plan_new_to_old_glyph_mapping
+hb_subset_plan_old_to_new_glyph_mapping
+hb_subset_preprocess
+hb_subset_flags_t
+hb_subset_input_t
+hb_subset_sets_t
+hb_subset_plan_t
+<SUBSECTION Private>
+hb_link_t
+hb_object_t
+hb_subset_repack_or_fail
+hb_subset_input_override_name_table
+</SECTION>
+
+<SECTION>
+<FILE>hb-cairo</FILE>
+hb_cairo_font_face_create_for_font
+hb_cairo_font_face_get_font
+hb_cairo_font_face_create_for_face
+hb_cairo_font_face_get_face
+hb_cairo_font_init_func_t
+hb_cairo_font_face_set_font_init_func
+hb_cairo_scaled_font_get_font
+hb_cairo_font_face_set_scale_factor
+hb_cairo_font_face_get_scale_factor
+hb_cairo_glyphs_from_buffer
+</SECTION>

+ 65 - 0
hbfreetypefont.mod/harfbuzz/docs/meson.build

@@ -0,0 +1,65 @@
+if not find_program('gtkdoc-scan', required: get_option('docs')).found()
+  message('Not building documentation as gtk-doc was not found')
+  subdir_done()
+endif
+
+conf.set('HAVE_GTK_DOC', 1)
+
+gnome = import('gnome')
+
+docconf = configuration_data()
+docconf.set('HB_VERSION', meson.project_version())
+
+version_xml = configure_file(input: 'version.xml.in',
+  output: 'version.xml',
+  configuration: docconf)
+
+content_files = [
+  'usermanual-what-is-harfbuzz.xml',
+  'usermanual-install-harfbuzz.xml',
+  'usermanual-getting-started.xml',
+  'usermanual-glyph-information.xml',
+  'usermanual-shaping-concepts.xml',
+  'usermanual-object-model.xml',
+  'usermanual-buffers-language-script-and-direction.xml',
+  'usermanual-fonts-and-faces.xml',
+  'usermanual-opentype-features.xml',
+  'usermanual-clusters.xml',
+  'usermanual-utilities.xml',
+  'usermanual-integration.xml',
+  version_xml,
+]
+
+html_images = [
+  'HarfBuzz.png',
+  'HarfBuzz.svg',
+]
+
+ignore_headers = [
+  'hb-features.h',
+  'hb-gobject.h',
+  'hb-gobject-enums.h',
+  'hb-gobject-enums-tmp.h',
+  'hb-gobject-structs.h',
+  'hb-wasm-api.h',
+]
+
+gnome.gtkdoc('harfbuzz',
+  main_sgml: 'harfbuzz-docs.xml',
+  src_dir: [meson.current_source_dir() / '..' / 'src',
+            meson.current_build_dir() / '..' / 'src',
+           ],
+  scan_args: ['--deprecated-guards=HB_DISABLE_DEPRECATED',
+              '--ignore-decorators=HB_EXTERN|HB_DEPRECATED|HB_DEPRECATED_FOR()',
+             ],
+  mkdb_args: ['--source-suffixes=h,cc',
+              '--xml-mode',
+              '--output-format=xml',
+             ],
+  content_files: content_files,
+  html_assets: html_images,
+  ignore_headers: ignore_headers,
+  dependencies: [libharfbuzz_dep],
+  install: true,
+  check: get_option('doc_tests'),
+)

+ 294 - 0
hbfreetypefont.mod/harfbuzz/docs/repacker.md

@@ -0,0 +1,294 @@
+# Introduction
+
+Several tables in the opentype format are formed internally by a graph of subtables. Parent node's
+reference their children through the use of positive offsets, which are typically 16 bits wide.
+Since offsets are always positive this forms a directed acyclic graph. For storage in the font file
+the graph must be given a topological ordering and then the subtables packed in serial according to
+that ordering. Since 16 bit offsets have a maximum value of 65,535 if the distance between a parent
+subtable and a child is more then 65,535 bytes then it's not possible for the offset to encode that
+edge.
+
+For many fonts with complex layout rules (such as Arabic) it's not unusual for the tables containing
+layout rules ([GSUB/GPOS](https://docs.microsoft.com/en-us/typography/opentype/spec/gsub)) to be
+larger than 65kb. As a result these types of fonts are susceptible to offset overflows when
+serializing to the binary font format.
+
+Offset overflows can happen for a variety of reasons and require different strategies to resolve:
+*  Simple overflows can often be resolved with a different topological ordering.
+*  If a subtable has many parents this can result in the link from furthest parent(s)
+   being at risk for overflows. In these cases it's possible to duplicate the shared subtable which
+   allows it to be placed closer to it's parent.
+*  If subtables exist which are themselves larger than 65kb it's not possible for any offsets to point
+   past them. In these cases the subtable can usually be split into two smaller subtables to allow
+   for more flexibility in the ordering.
+*  In GSUB/GPOS overflows from Lookup subtables can be resolved by changing the Lookup to an extension
+   lookup which uses a 32 bit offset instead of 16 bit offset.
+
+In general there isn't a simple solution to produce an optimal topological ordering for a given graph.
+Finding an ordering which doesn't overflow is a NP hard problem. Existing solutions use heuristics
+which attempt a combination of the above strategies to attempt to find a non-overflowing configuration.
+
+The harfbuzz subsetting library
+[includes a repacking algorithm](https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-repacker.hh)
+which is used to resolve offset overflows that are present in the subsetted tables it produces. This
+document provides a deep dive into how the harfbuzz repacking algorithm works.
+
+Other implementations exist, such as in
+[fontTools](https://github.com/fonttools/fonttools/blob/7af43123d49c188fcef4e540fa94796b3b44e858/Lib/fontTools/ttLib/tables/otBase.py#L72), however these are not covered in this document.
+
+# Foundations
+
+There's four key pieces to the harfbuzz approach:
+
+*  Subtable Graph: a table's internal structure is abstracted out into a lightweight graph
+   representation where each subtable is a node and each offset forms an edge. The nodes only need
+   to know how many bytes the corresponding subtable occupies. This lightweight representation can
+   be easily modified to test new ordering's and strategies as the repacking algorithm iterates.
+
+*  [Topological sorting algorithm](https://en.wikipedia.org/wiki/Topological_sorting): an algorithm
+   which given a graph gives a linear sorting of the nodes such that all offsets will be positive.
+
+*  Overflow check: given a graph and a topological sorting it checks if there will be any overflows
+   in any of the offsets. If there are overflows it returns a list of (parent, child) tuples that
+   will overflow. Since the graph has information on the size of each subtable it's straightforward
+   to calculate the final position of each subtable and then check if any offsets to it will
+   overflow.
+
+*  Content Aware Preprocessing: if the overflow resolver is aware of the format of the underlying
+   tables (eg. GSUB, GPOS) then in some cases preprocessing can be done to increase the chance of
+   successfully packing the graph. For example for GSUB and GPOS we can preprocess the graph and
+   promote lookups to extension lookups (upgrades a 16 bit offset to 32 bits) or split large lookup
+   subtables into two or more pieces.
+
+*  Offset resolution strategies: given a particular occurrence of an overflow these strategies
+   modify the graph to attempt to resolve the overflow.
+
+# High Level Algorithm
+
+```
+def repack(graph):
+  graph.topological_sort()
+
+  if (graph.will_overflow())
+    preprocess(graph)
+    assign_spaces(graph)
+    graph.topological_sort()
+
+  while (overflows = graph.will_overflow()):
+    for overflow in overflows:
+      apply_offset_resolution_strategy (overflow, graph)
+    graph.topological_sort()
+```
+
+The actual code for this processing loop can be found in the function hb_resolve_overflows () of
+[hb-repacker.hh](https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-repacker.hh).
+
+# Topological Sorting Algorithms
+
+The harfbuzz repacker uses two different algorithms for topological sorting:
+*  [Kahn's Algorithm](https://en.wikipedia.org/wiki/Topological_sorting#Kahn's_algorithm)
+*  Sorting by shortest distance
+
+Kahn's algorithm is approximately twice as fast as the shortest distance sort so that is attempted
+first (only on the first topological sort). If it fails to eliminate overflows then shortest distance
+sort will be used for all subsequent topological sorting operations.
+
+## Shortest Distance Sort
+
+This algorithm orders the nodes based on total distance to each node. Nodes with a shorter distance
+are ordered first.
+
+The "weight" of an edge is the sum of the size of the sub-table being pointed to plus 2^16 for a 16 bit
+offset and 2^32 for a 32 bit offset.
+
+The distance of a node is the sum of all weights along the shortest path from the root to that node
+plus a priority modifier (used to change where nodes are placed by moving increasing or
+decreasing the effective distance). Ties between nodes with the same distance are broken based
+on the order of the offset in the sub table bytes.
+
+The shortest distance to each node is determined using
+[Djikstra's algorithm](https://en.wikipedia.org/wiki/Dijkstra%27s_algorithm). Then the topological
+ordering is produce by applying a modified version of Kahn's algorithm that uses a priority queue
+based on the shortest distance to each node.
+
+## Optimizing the Sorting
+
+The topological sorting operation is the core of the repacker and is run on each iteration so it needs
+to be as fast as possible. There's a few things that are done to speed up subsequent sorting
+operations:
+
+*  The number of incoming edges to each node is cached. This is required by the Kahn's algorithm
+   portion of both sorts. Where possible when the graph is modified we manually update the cached
+   edge counts of affected nodes.
+
+*  The distance to each node is cached. Where possible when the graph is modified we manually update
+   the cached distances of any affected nodes.
+
+Caching these values allows the repacker to avoid recalculating them for the full graph on each
+iteration.
+
+The other important factor to speed is a fast priority queue which is a core datastructure to
+the topological sorting algorithm. Currently a basic heap based queue is used. Heap based queue's
+don't support fast priority decreases, but that can be worked around by just adding redundant entries
+to the priority queue and filtering the older ones out when poppping off entries. This is based
+on the recommendations in
+[a study of the practical performance of priority queues in Dijkstra's algorithm](https://www3.cs.stonybrook.edu/~rezaul/papers/TR-07-54.pdf)
+
+## Special Handling of 32 bit Offsets
+
+If a graph contains multiple 32 bit offsets then the shortest distance sorting will be likely be
+suboptimal. For example consider the case where a graph contains two 32 bit offsets that each point
+to a subgraph which are not connected to each other. The shortest distance sort will interleave the
+subtables of the two subgraphs, potentially resulting in overflows. Since each of these subgraphs are
+independent of each other, and 32 bit offsets can point extremely long distances a better strategy is
+to pack the first subgraph in it's entirety and then have the second subgraph packed after with the 32
+bit offset pointing over the first subgraph. For example given the graph:
+
+
+```
+a--- b -- d -- f
+ \
+  \_ c -- e -- g
+```
+
+Where the links from a to b and a to c are 32 bit offsets, the shortest distance sort would be:
+
+```
+a, b, c, d, e, f, g
+
+```
+
+If nodes d and e have a combined size greater than 65kb then the offset from d to f will overflow.
+A better ordering is:
+
+```
+a, b, d, f, c, e, g
+```
+
+The ability for 32 bit offsets to point long distances is utilized to jump over the subgraph of
+b which gives the remaining 16 bit offsets a better chance of not overflowing.
+
+The above is an ideal situation where the subgraphs are disconnected from each other, in practice
+this is often not this case. So this idea can be generalized as follows:
+
+If there is a subgraph that is only reachable from one or more 32 bit offsets, then:
+*  That subgraph can be treated as an independent unit and all nodes of the subgraph packed in isolation
+   from the rest of the graph.
+*  In a table that occupies less than 4gb of space (in practice all fonts), that packed independent
+   subgraph can be placed anywhere after the parent nodes without overflowing the 32 bit offsets from
+   the parent nodes.
+
+The sorting algorithm incorporates this via a "space" modifier that can be applied to nodes in the
+graph. By default all nodes are treated as being in space zero. If a node is given a non-zero space, n,
+then the computed distance to the node will be modified by adding `n * 2^32`. This will cause that
+node and it's descendants to be packed between all nodes in space n-1 and space n+1. Resulting in a
+topological sort like:
+
+```
+| space 0 subtables | space 1 subtables | .... | space n subtables |
+```
+
+The assign_spaces() step in the high level algorithm is responsible for identifying independent
+subgraphs and assigning unique spaces to each one. More information on the space assignment can be
+found in the next section.
+
+# Graph Preprocessing
+
+For certain table types we can preprocess and modify the graph structure to reduce the occurences
+of overflows. Currently the repacker implements preprocessing only for GPOS and GSUB tables.
+
+## GSUB/GPOS Table Splitting
+
+The GSUB/GPOS preprocessor scans each lookup subtable and determines if the subtable's children are
+so large that no overflow resolution is possible (for example a single subtable that exceeds 65kb
+cannot be pointed over). When such cases are detected table splitting is invoked:
+
+* The subtable is first analyzed to determine the smallest number of split points that will allow
+  for successful offset overflow resolution.
+
+* Then the subtable in the graph representation is modified to actually perform the split at the
+  previously computed split points. At a high level splits are done by inserting new subtables
+  which contain a subset of the data of the original subtable and then shrinking the original subtable.
+
+Table splitting must be aware of the underlying format of each subtable type and thus needs custom
+code for each subtable type. Currently subtable splitting is only supported for GPOS subtable types.
+
+## GSUB/GPOS Extension Lookup Promotion
+
+In GSUB/GPOS tables lookups can be regular lookups which use 16 bit offsets to the children subtables
+or extension lookups which use 32 bit offsets to the children subtables. If the sub graph of all
+regular lookups is too large then it can be difficult to find an overflow free configuration. This
+can be remedied by promoting one or more regular lookups to extension lookups.
+
+During preprocessing the graph is scanned to determine the size of the subgraph of regular lookups.
+If the graph is found to be too big then the analysis finds a set of lookups to promote to reduce
+the subgraph size. Lastly the graph is modified to convert those lookups to extension lookups.
+
+# Offset Resolution Strategies
+
+## Space Assignment
+
+The goal of space assignment is to find connected subgraphs that are only reachable via 32 bit offsets
+and then assign each such subgraph to a unique non-zero space. The algorithm is roughly:
+
+1.  Collect the set, `S`, of nodes that are children of 32 bit offsets.
+
+2.  Do a directed traversal from each node in `S` and collect all encountered nodes into set `T`.
+    Mark all nodes in the graph that are not in `T` as being in space 0.
+
+3.  Set `next_space = 1`.
+
+4.  While set `S` is not empty:
+
+    a.  Pick a node `n` in set `S` then perform an undirected graph traversal and find the set `Q` of
+        nodes that are reachable from `n`.
+
+    b.  During traversal if a node, `m`, has a edge to a node in space 0 then `m` must be duplicated
+        to disconnect it from space 0.
+
+    d.  Remove all nodes in `Q` from `S` and assign all nodes in `Q` to `next_space`.
+
+
+    c.  Increment `next_space` by one.
+
+
+## Manual Iterative Resolutions
+
+For each overflow in each iteration the algorithm will attempt to apply offset overflow resolution
+strategies to eliminate the overflow. The type of strategy applied is dependent on the characteristics
+of the overflowing link:
+
+*  If the overflowing offset is inside a space other than space 0 and the subgraph space has more
+   than one 32 bit offset pointing into the subgraph then subdivide the space by moving subgraph
+   from one of the 32 bit offsets into a new space via the duplication of shared nodes.
+
+*  If the overflowing offset is pointing to a subtable with more than one incoming edge: duplicate
+   the node so that the overflowing offset is pointing at it's own copy of that node.
+
+*  Otherwise, attempt to move the child subtable closer to it's parent. This is accomplished by
+   raising the priority of all children of the parent. Next time the topological sort is run the
+   children will be ordered closer to the parent.
+
+# Test Cases
+
+The harfbuzz repacker has tests defined using generic graphs: https://github.com/harfbuzz/harfbuzz/blob/main/src/test-repacker.cc
+
+# Future Improvements
+
+Currently for GPOS tables the repacker implementation is sufficient to handle both subsetting and the
+general case of font compilation repacking. However for GSUB the repacker is only sufficient for
+subsetting related overflows. To enable general case repacking of GSUB, support for splitting of
+GSUB subtables will need to be added. Other table types such as COLRv1 shouldn't require table
+splitting due to the wide use of 24 bit offsets throughout the table.
+
+Beyond subtable splitting there are a couple of "nice to have" improvements, but these are not required
+to support the general case:
+
+*  Extension demotion: currently extension promotion is supported but in some cases if the non-extension
+   subgraph is underfilled then packed size can be reduced by demoting extension lookups back to regular
+   lookups.
+
+*  Currently only children nodes are moved to resolve offsets. However, in many cases moving a parent
+   node closer to it's children will have less impact on the size of other offsets. Thus the algorithm
+   should use a heuristic (based on parent and child subtable sizes) to decide if the children's
+   priority should be increased or the parent's priority decreased.

+ 178 - 0
hbfreetypefont.mod/harfbuzz/docs/serializer.md

@@ -0,0 +1,178 @@
+# Introduction
+
+In hb-subset serialization is the process of writing the subsetted font
+tables out to actual bytes in the final format. All serialization works
+through an object called the serialize context
+([hb_serialize_context_t](https://github.com/harfbuzz/harfbuzz/blob/main/src/hb-serialize.hh)).
+
+Internally the serialize context holds a fixed size memory buffer. For simple
+tables the final bytes are written into the buffer sequentially to produce
+the final serialized bytes.
+
+## Simple Tables
+
+Simple tables are tables that do not use offset graphs.
+
+To write a struct into the serialization context, first you call an
+allocation method on the context which requests a writable array of bytes of
+a fixed size. If the requested array will not exceed the bounds of the fixed
+buffer the serializer will return a pointer to the next unwritten portion
+of the buffer. Then the struct is cast onto the returned pointer and values
+are written to the structs fields.
+
+Internally the serialization context ends up looking like:
+
+```
++-------+-------+-----+-------+--------------+
+| Obj 1 | Obj 2 | ... | Obj N | Unused Space |
++-------+-------+-----+-------+--------------+
+```
+
+Here Obj N, is the object currently being written.
+
+## Complex Tables
+
+Complex tables are made up of graphs of objects, where offset's are used
+to form the edges of the graphs. Each object is a continuous slice of bytes
+that contains zero or more offsets pointing to more objects.
+
+In this case the serialization buffer has a different layout:
+
+```
+|- in progress objects -|              |--- packed objects --|
++-----------+-----------+--------------+-------+-----+-------+
+|  Obj n+2  |  Obj n+1  | Unused Space | Obj n | ... | Obj 0 |
++-----------+-----------+--------------+-------+-----+-------+
+|----------------------->              <---------------------|
+```
+
+The buffer holds two stacks:
+
+1. In progress objects are held in a stack starting from the start of buffer
+   that grows towards the end of the buffer.
+
+2. Packed objects are held in a stack that starts at the end of the buffer
+   and grows towards the start of the buffer.
+
+Once the object on the top of the in progress stack is finished being written
+its bytes are popped from the in progress stack and copied to the top of
+the packed objects stack. In the example above, finalizing Obj n+1
+would result in the following state:
+
+```
++---------+--------------+---------+-------+-----+-------+
+| Obj n+2 | Unused Space | Obj n+1 | Obj n | ... | Obj 0 |
++---------+--------------+---------+-------+-----+-------+
+```
+
+Each packed object is associated with an ID, it's zero based position in the packed
+objects stack. In this example Obj 0, would have an ID of 0.
+
+During serialization offsets that link from one object to another are stored
+using object ids. The serialize context maintains a list of links between
+objects. Each link records the parent object id, the child object id, the position
+of the offset field within the parent object, and the width of the offset.
+
+Links are always added to the current in progress object and you can only link too
+objects that have been packed and thus have an ID.
+
+### Object De-duplication
+
+An important optimization in packing offset graphs is de-duplicating equivalent objects. If you
+have two or more parent objects that point to child objects that are equivalent then you only need
+to encode the child once and can have the parents point to the same child. This can significantly
+reduce the final size of a serialized graph.
+
+During packing of an inprogress object the serialization context checks if any existing packed
+objects are equivalent to the object being packed. Here equivalence means the object has the
+exact same bytes and all of it's links are equivalent. If an equivalent object is found the
+in progress object is discarded and not copied to the packed object stack. The object id of
+the equivalent object is instead returned. Thus parent objects will then link to the existing
+equivalent object.
+
+To find equivalent objects the serialization context maintains a hashmap from object to the canonical
+object id.
+
+### Link Resolution
+
+Once all objects have been packed the next step is to assign actual values to all of the offset
+fields. Prior to this point all links in the graph have been recorded using object id's. For each
+link the resolver computes the offset between the parent and child and writes the offset into
+the serialization buffer at the appropriate location.
+
+### Offset Overflow Resolution
+
+If during link resolution the resolver finds that an offsets value would exceed what can be encoded
+in that offset field link resolution is aborted and the offset overflow resolver is invoked.
+That process is documented [here](reapcker.md).
+
+
+### Example of Complex Serialization
+
+
+If we wanted to serialize the following graph:
+
+```
+a--b--d
+ \   /
+   c
+```
+
+Serializer would be called like this:
+
+```c++
+hb_serialize_context_t ctx;
+
+struct root {
+  char name;
+  Offset16To<child> child_1;
+  Offset16To<child> child_2;
+}
+
+struct child {
+  char name;
+  Offset16To<char> leaf;
+}
+
+// Object A.
+ctx->push();
+root* a = ctx->start_embed<root> ();
+ctx->extend_min (a);
+a->name = 'a';
+
+// Object B.
+ctx->push();
+child* b = ctx->start_embed<child> ();
+ctx->extend_min (b);
+b->name = 'b';
+
+// Object D.
+ctx->push();
+*ctx->allocate_size<char> (1) = 'd';
+unsigned d_id = ctx->pop_pack ();
+
+ctx->add_link (b->leaf, d_id);
+unsigned b_id = ctx->pop_pack ();
+
+// Object C
+ctx->push();
+child* c = ctx->start_embed<child> ();
+ctx->extend_min (c);
+c->name = 'c';
+
+// Object D.
+ctx->push();
+*ctx->allocate_size<char> (1) = 'd';
+d_id = ctx->pop_pack (); // Serializer will automatically de-dup this with the previous 'd'
+
+ctx->add_link (c->leaf, d_id);
+unsigned c_id = ctx->pop_pack ();
+
+// Object A's links:
+ctx->add_link (a->child_1, b_id);
+ctx->add_link (a->child_2, c_id);
+ctx->pop_pack ();
+
+ctx->end_serialize ();
+
+```

+ 228 - 0
hbfreetypefont.mod/harfbuzz/docs/subset-preprocessing.md

@@ -0,0 +1,228 @@
+# Introduction
+
+Subset preprocessing is a mechanism which can significantly speed up font subsetting operations.
+It works by prepopulating datastructures from the source font which can be used in later subsetting
+operations to more quickly produce the subset. Preprocessing is useful in cases where multiple subsets
+will be cut from the same source font.
+
+# Usage
+
+```c++
+hb_face_t* preprocessed = hb_subset_preprocess (source_face);
+
+...
+
+hb_face_t* subset = hb_subset_or_fail (preprocessed, subset_input);
+```
+
+# Additional Details
+
+*  A subset produced from a preprocessed face should be identical to a subset produced from only the
+   original face. The preprocessor does not change the functionality of the subsetter, just speeds
+   things up.
+
+*  The preprocessing operation may take longer than the time it takes to produce a subset from the
+   source font. Thus the main performance gains are made when a preprocessed face is reused for
+   multiple subsetting operations.
+
+*  Currently the largest performance gains are seen when using a preprocessed face for CFF subsetting.
+
+*  The preprocessed face may contain references to the memory backing the source face. If this memory
+   is fully owned by a harfbuzz hb_blob_t* then it will automatically be kept alive for the lifetime
+   of the preprocessed face. However, if this memory is not fully owned by a harfbuzz hb_blob_t* then
+   it is necessary to ensure that the memory is kept alive for the lifetime of the preprocessed face.
+
+
+# Performance Improvements
+
+Here is the performance difference of producing a subset with a preprocessed face vs producing
+a subset with the source face:
+
+Benchmark | Delta Time (%)
+----------|-----------------
+BM_subset/subset_glyphs/Roboto-Regular.ttf/10_median|-56%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/64_median|-33%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/512_median|-28%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/1000_median|-11%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/nohinting/10_median|-56%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/nohinting/64_median|-33%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/nohinting/512_median|-21%
+BM_subset/subset_glyphs/Roboto-Regular.ttf/nohinting/1000_median|-9%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/10_median|-67%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/64_median|-48%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/512_median|-21%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/4096_median|-9%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/nohinting/10_median|-66%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/nohinting/64_median|-50%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/nohinting/512_median|-8%
+BM_subset/subset_glyphs/Amiri-Regular.ttf/nohinting/4096_median|-9%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/10_median|-85%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/64_median|-71%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/512_median|-3%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/1400_median|4%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/nohinting/10_median|-84%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/nohinting/64_median|-72%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/nohinting/512_median|0%
+BM_subset/subset_glyphs/NotoNastaliqUrdu-Regular.ttf/nohinting/1400_median|0%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/10_median|-30%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/64_median|-24%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/512_median|-3%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/1000_median|-3%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/nohinting/10_median|-30%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/nohinting/64_median|-24%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/nohinting/512_median|-3%
+BM_subset/subset_glyphs/NotoSansDevanagari-Regular.ttf/nohinting/1000_median|-5%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/10_median|-96%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/64_median|-90%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/512_median|-74%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/4096_median|-25%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/10000_median|-23%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/10_median|-95%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/64_median|-90%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/512_median|-73%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/4096_median|-24%
+BM_subset/subset_glyphs/Mplus1p-Regular.ttf/nohinting/10000_median|-11%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/10_median|-84%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/64_median|-77%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/512_median|-70%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/4096_median|-80%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/10000_median|-86%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/10_median|-84%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/64_median|-78%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/512_median|-71%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/4096_median|-86%
+BM_subset/subset_glyphs/SourceHanSans-Regular_subset.otf/nohinting/10000_median|-88%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/10_median|-59%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/64_median|-55%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/512_median|-67%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/2000_median|-68%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/nohinting/10_median|-60%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/nohinting/64_median|-58%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/nohinting/512_median|-72%
+BM_subset/subset_glyphs/SourceSansPro-Regular.otf/nohinting/2000_median|-71%
+BM_subset/subset_glyphs/AdobeVFPrototype.otf/10_median|-70%
+BM_subset/subset_glyphs/AdobeVFPrototype.otf/64_median|-64%
+BM_subset/subset_glyphs/AdobeVFPrototype.otf/300_median|-73%
+BM_subset/subset_glyphs/AdobeVFPrototype.otf/nohinting/10_median|-71%
+BM_subset/subset_glyphs/AdobeVFPrototype.otf/nohinting/64_median|-68%
+BM_subset/subset_glyphs/AdobeVFPrototype.otf/nohinting/300_median|-72%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/10_median|-90%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/64_median|-82%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/512_median|-31%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/4096_median|-9%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/6000_median|-22%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/10_median|-88%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/64_median|-83%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/512_median|-31%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/4096_median|-16%
+BM_subset/subset_glyphs/MPLUS1-Variable.ttf/nohinting/6000_median|-18%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/10_median|-44%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/64_median|-18%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/512_median|-2%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/900_median|-6%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/nohinting/10_median|-45%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/nohinting/64_median|-17%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/nohinting/512_median|-15%
+BM_subset/subset_glyphs/RobotoFlex-Variable.ttf/nohinting/900_median|-3%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/10_median|-20%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/64_median|-16%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/512_median|-12%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/1000_median|-10%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/10_median|-24%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/64_median|-14%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/512_median|-15%
+BM_subset/subset_codepoints/Roboto-Regular.ttf/nohinting/1000_median|-9%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/10_median|-51%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/64_median|-37%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/512_median|-12%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/4096_median|-1%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/10_median|-49%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/64_median|-35%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/512_median|-6%
+BM_subset/subset_codepoints/Amiri-Regular.ttf/nohinting/4096_median|-1%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/10_median|-82%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/64_median|-9%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/512_median|0%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/1400_median|0%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/10_median|-82%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/64_median|-13%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/512_median|-3%
+BM_subset/subset_codepoints/NotoNastaliqUrdu-Regular.ttf/nohinting/1400_median|2%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/10_median|-40%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/64_median|-26%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/512_median|-5%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/1000_median|3%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/10_median|-43%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/64_median|-24%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/512_median|-2%
+BM_subset/subset_codepoints/NotoSansDevanagari-Regular.ttf/nohinting/1000_median|2%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/10_median|-83%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/64_median|-67%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/512_median|-39%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/4096_median|-20%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/10000_median|-25%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/10_median|-83%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/64_median|-65%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/512_median|-42%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/4096_median|-34%
+BM_subset/subset_codepoints/Mplus1p-Regular.ttf/nohinting/10000_median|-21%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/10_median|-69%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/64_median|-69%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/512_median|-70%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/4096_median|-84%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/10000_median|-83%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/10_median|-71%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/64_median|-68%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/512_median|-70%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/4096_median|-86%
+BM_subset/subset_codepoints/SourceHanSans-Regular_subset.otf/nohinting/10000_median|-88%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/10_median|-45%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/64_median|-48%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/512_median|-57%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/2000_median|-66%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/10_median|-43%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/64_median|-50%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/512_median|-63%
+BM_subset/subset_codepoints/SourceSansPro-Regular.otf/nohinting/2000_median|-72%
+BM_subset/subset_codepoints/AdobeVFPrototype.otf/10_median|-69%
+BM_subset/subset_codepoints/AdobeVFPrototype.otf/64_median|-66%
+BM_subset/subset_codepoints/AdobeVFPrototype.otf/300_median|-74%
+BM_subset/subset_codepoints/AdobeVFPrototype.otf/nohinting/10_median|-70%
+BM_subset/subset_codepoints/AdobeVFPrototype.otf/nohinting/64_median|-71%
+BM_subset/subset_codepoints/AdobeVFPrototype.otf/nohinting/300_median|-75%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/10_median|-66%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/64_median|-46%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/512_median|-15%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/4096_median|-5%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/6000_median|-16%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/10_median|-66%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/64_median|-45%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/512_median|-14%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/4096_median|-11%
+BM_subset/subset_codepoints/MPLUS1-Variable.ttf/nohinting/6000_median|-27%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/10_median|-38%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/64_median|-9%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/512_median|-3%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/900_median|-16%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/10_median|-39%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/64_median|-12%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/512_median|-4%
+BM_subset/subset_codepoints/RobotoFlex-Variable.ttf/nohinting/900_median|-2%
+BM_subset/instance/MPLUS1-Variable.ttf/10_median|-68%
+BM_subset/instance/MPLUS1-Variable.ttf/64_median|-45%
+BM_subset/instance/MPLUS1-Variable.ttf/512_median|-18%
+BM_subset/instance/MPLUS1-Variable.ttf/4096_median|-2%
+BM_subset/instance/MPLUS1-Variable.ttf/6000_median|4%
+BM_subset/instance/MPLUS1-Variable.ttf/nohinting/10_median|-69%
+BM_subset/instance/MPLUS1-Variable.ttf/nohinting/64_median|-46%
+BM_subset/instance/MPLUS1-Variable.ttf/nohinting/512_median|-11%
+BM_subset/instance/MPLUS1-Variable.ttf/nohinting/4096_median|4%
+BM_subset/instance/MPLUS1-Variable.ttf/nohinting/6000_median|-5%
+BM_subset/instance/RobotoFlex-Variable.ttf/10_median|-34%
+BM_subset/instance/RobotoFlex-Variable.ttf/64_median|-12%
+BM_subset/instance/RobotoFlex-Variable.ttf/512_median|6%
+BM_subset/instance/RobotoFlex-Variable.ttf/900_median|-6%
+BM_subset/instance/RobotoFlex-Variable.ttf/nohinting/10_median|-33%
+BM_subset/instance/RobotoFlex-Variable.ttf/nohinting/64_median|-11%
+BM_subset/instance/RobotoFlex-Variable.ttf/nohinting/512_median|3%
+BM_subset/instance/RobotoFlex-Variable.ttf/nohinting/900_median|0%

+ 412 - 0
hbfreetypefont.mod/harfbuzz/docs/usermanual-buffers-language-script-and-direction.xml

@@ -0,0 +1,412 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="buffers-language-script-and-direction">
+  <title>Buffers, language, script and direction</title>
+  <para>
+    The input to the HarfBuzz shaper is a series of Unicode characters, stored in a
+    buffer. In this chapter, we'll look at how to set up a buffer with
+    the text that we want and how to customize the properties of the
+    buffer. We'll also look at a piece of lower-level machinery that
+    you will need to understand before proceeding: the functions that
+    HarfBuzz uses to retrieve Unicode information.
+  </para>
+  <para>
+    After shaping is complete, HarfBuzz puts its output back
+    into the buffer. But getting that output requires setting up a
+    face and a font first, so we will look at that in the next chapter
+    instead of here.
+  </para>
+  <section id="creating-and-destroying-buffers">
+    <title>Creating and destroying buffers</title>
+    <para>
+      As we saw in our <emphasis>Getting Started</emphasis> example, a
+      buffer is created and 
+      initialized with <function>hb_buffer_create()</function>. This
+      produces a new, empty buffer object, instantiated with some
+      default values and ready to accept your Unicode strings.
+    </para>
+    <para>
+      HarfBuzz manages the memory of objects (such as buffers) that it
+      creates, so you don't have to. When you have finished working on 
+      a buffer, you can call <function>hb_buffer_destroy()</function>:
+    </para>
+    <programlisting language="C">
+      hb_buffer_t *buf = hb_buffer_create();
+      ...
+      hb_buffer_destroy(buf);
+    </programlisting>
+    <para>
+      This will destroy the object and free its associated memory -
+      unless some other part of the program holds a reference to this
+      buffer. If you acquire a HarfBuzz buffer from another subsystem
+      and want to ensure that it is not garbage collected by someone
+      else destroying it, you should increase its reference count:
+    </para>
+    <programlisting language="C">
+      void somefunc(hb_buffer_t *buf) {
+      buf = hb_buffer_reference(buf);
+      ...
+    </programlisting>
+    <para>
+      And then decrease it once you're done with it:
+    </para>
+    <programlisting language="C">
+      hb_buffer_destroy(buf);
+      }
+    </programlisting>
+    <para>
+      While we are on the subject of reference-counting buffers, it is
+      worth noting that an individual buffer can only meaningfully be
+      used by one thread at a time.
+    </para>
+    <para>
+      To throw away all the data in your buffer and start from scratch,
+      call <function>hb_buffer_reset(buf)</function>. If you want to
+      throw away the string in the buffer but keep the options, you can
+      instead call <function>hb_buffer_clear_contents(buf)</function>.
+    </para>
+  </section>
+  
+  <section id="adding-text-to-the-buffer">
+    <title>Adding text to the buffer</title>
+    <para>
+      Now we have a brand new HarfBuzz buffer. Let's start filling it
+      with text! From HarfBuzz's perspective, a buffer is just a stream
+      of Unicode code points, but your input string is probably in one of
+      the standard Unicode character encodings (UTF-8, UTF-16, or
+      UTF-32). HarfBuzz provides convenience functions that accept
+      each of these encodings:
+      <function>hb_buffer_add_utf8()</function>,
+      <function>hb_buffer_add_utf16()</function>, and
+      <function>hb_buffer_add_utf32()</function>. Other than the
+      character encoding they accept, they function identically.
+    </para>
+    <para>
+      You can add UTF-8 text to a buffer by passing in the text array,
+      the array's length, an offset into the array for the first
+      character to add, and the length of the segment to add:
+    </para>
+    <programlisting language="C">
+    hb_buffer_add_utf8 (hb_buffer_t *buf,
+                    const char *text,
+                    int text_length,
+                    unsigned int item_offset,
+                    int item_length)
+    </programlisting>
+    <para>
+      So, in practice, you can say:
+    </para>
+    <programlisting language="C">
+      hb_buffer_add_utf8(buf, text, strlen(text), 0, strlen(text));
+    </programlisting>
+    <para>
+      This will append your new characters to
+      <parameter>buf</parameter>, not replace its existing
+      contents. Also, note that you can use <literal>-1</literal> in
+      place of the first instance of <function>strlen(text)</function>
+      if your text array is NULL-terminated. Similarly, you can also use
+      <literal>-1</literal> as the final argument want to add its full
+      contents.
+    </para>
+    <para>
+      Whatever start <parameter>item_offset</parameter> and
+      <parameter>item_length</parameter> you provide, HarfBuzz will also
+      attempt to grab the five characters <emphasis>before</emphasis>
+      the offset point and the five characters
+      <emphasis>after</emphasis> the designated end. These are the
+      before and after "context" segments, which are used internally
+      for HarfBuzz to make shaping decisions. They will not be part of
+      the final output, but they ensure that HarfBuzz's
+      script-specific shaping operations are correct. If there are
+      fewer than five characters available for the before or after
+      contexts, HarfBuzz will just grab what is there.
+    </para>
+    <para>
+      For longer text runs, such as full paragraphs, it might be
+      tempting to only add smaller sub-segments to a buffer and
+      shape them in piecemeal fashion. Generally, this is not a good
+      idea, however, because a lot of shaping decisions are
+      dependent on this context information. For example, in Arabic
+      and other connected scripts, HarfBuzz needs to know the code
+      points before and after each character in order to correctly
+      determine which glyph to return.
+    </para>
+    <para>
+      The safest approach is to add all of the text available (even
+      if your text contains a mix of scripts, directions, languages
+      and fonts), then use <parameter>item_offset</parameter> and
+      <parameter>item_length</parameter> to indicate which characters you
+      want shaped (which must all have the same script, direction,
+      language and font), so that HarfBuzz has access to any context.
+    </para>
+    <para>
+      You can also add Unicode code points directly with
+      <function>hb_buffer_add_codepoints()</function>. The arguments
+      to this function are the same as those for the UTF
+      encodings. But it is particularly important to note that
+      HarfBuzz does not do validity checking on the text that is added
+      to a buffer. Invalid code points will be replaced, but it is up
+      to you to do any deep-sanity checking necessary.
+    </para>
+    
+  </section>
+  
+  <section id="setting-buffer-properties">
+    <title>Setting buffer properties</title>
+    <para>
+      Buffers containing input characters still need several
+      properties set before HarfBuzz can shape their text correctly.
+    </para>
+    <para>
+      Initially, all buffers are set to the
+      <literal>HB_BUFFER_CONTENT_TYPE_INVALID</literal> content
+      type. After adding text, the buffer should be set to
+      <literal>HB_BUFFER_CONTENT_TYPE_UNICODE</literal> instead, which
+      indicates that it contains un-shaped input
+      characters. After shaping, the buffer will have the
+      <literal>HB_BUFFER_CONTENT_TYPE_GLYPHS</literal> content type.
+    </para>
+    <para>
+      <function>hb_buffer_add_utf8()</function> and the
+      other UTF functions set the content type of their buffer
+      automatically. But if you are reusing a buffer you may want to
+      check its state with
+      <function>hb_buffer_get_content_type(buffer)</function>. If
+      necessary you can set the content type with
+    </para>
+    <programlisting language="C">
+      hb_buffer_set_content_type(buf, HB_BUFFER_CONTENT_TYPE_UNICODE);
+    </programlisting>
+    <para>
+      to prepare for shaping.
+    </para>
+    <para>
+      Buffers also need to carry information about the script,
+      language, and text direction of their contents. You can set
+      these properties individually:
+    </para>
+    <programlisting language="C">
+      hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
+      hb_buffer_set_script(buf, HB_SCRIPT_LATIN);
+      hb_buffer_set_language(buf, hb_language_from_string("en", -1));
+    </programlisting>
+    <para>
+      However, since these properties are often repeated for
+      multiple text runs, you can also save them in a
+      <literal>hb_segment_properties_t</literal> for reuse:
+    </para>
+    <programlisting language="C">
+      hb_segment_properties_t *savedprops;
+      hb_buffer_get_segment_properties (buf, savedprops);
+      ...
+      hb_buffer_set_segment_properties (buf2, savedprops);
+    </programlisting>
+    <para>
+      HarfBuzz also provides getter functions to retrieve a buffer's
+      direction, script, and language properties individually.
+    </para>
+    <para>
+      HarfBuzz recognizes four text directions in
+      <type>hb_direction_t</type>: left-to-right
+      (<literal>HB_DIRECTION_LTR</literal>), right-to-left (<literal>HB_DIRECTION_RTL</literal>),
+      top-to-bottom (<literal>HB_DIRECTION_TTB</literal>), and
+      bottom-to-top (<literal>HB_DIRECTION_BTT</literal>).  For the
+      script property, HarfBuzz uses identifiers based on the
+      <ulink
+      url="https://unicode.org/iso15924/">ISO 15924
+      standard</ulink>. For languages, HarfBuzz uses tags based on the
+      <ulink url="https://tools.ietf.org/html/bcp47">IETF BCP 47</ulink> standard.
+    </para>
+    <para>
+      Helper functions are provided to convert character strings into
+      the necessary script and language tag types.
+    </para>
+    <para>
+      Two additional buffer properties to be aware of are the
+      "invisible glyph" and the replacement code point. The
+      replacement code point is inserted into buffer output in place of
+      any invalid code points encountered in the input. By default, it
+      is the Unicode <literal>REPLACEMENT CHARACTER</literal> code
+      point, <literal>U+FFFD</literal> "&#xFFFD;". You can change this with
+    </para>
+    <programlisting language="C">
+      hb_buffer_set_replacement_codepoint(buf, replacement);
+    </programlisting>
+    <para>
+      passing in the replacement Unicode code point as the
+      <parameter>replacement</parameter> parameter.
+    </para>
+    <para>
+      The invisible glyph is used to replace all output glyphs that
+      are invisible. By default, the standard space character
+      <literal>U+0020</literal> is used; you can replace this (for
+      example, when using a font that provides script-specific
+      spaces) with 
+    </para>
+    <programlisting language="C">
+      hb_buffer_set_invisible_glyph(buf, replacement_glyph);
+    </programlisting>
+    <para>
+      Do note that in the <parameter>replacement_glyph</parameter>
+      parameter, you must provide the glyph ID of the replacement you
+      wish to use, not the Unicode code point.
+    </para>
+    <para>
+      HarfBuzz supports a few additional flags you might want to set
+      on your buffer under certain circumstances. The
+      <literal>HB_BUFFER_FLAG_BOT</literal> and
+      <literal>HB_BUFFER_FLAG_EOT</literal> flags tell HarfBuzz
+      that the buffer represents the beginning or end (respectively)
+      of a text element (such as a paragraph or other block). Knowing
+      this allows HarfBuzz to apply certain contextual font features
+      when shaping, such as initial or final variants in connected
+      scripts.
+    </para>
+    <para>
+      <literal>HB_BUFFER_FLAG_PRESERVE_DEFAULT_IGNORABLES</literal>
+      tells HarfBuzz not to hide glyphs with the
+      <literal>Default_Ignorable</literal> property in Unicode. This 
+      property designates control characters and other non-printing
+      code points, such as joiners and variation selectors. Normally
+      HarfBuzz replaces them in the output buffer with zero-width
+      space glyphs (using the "invisible glyph" property discussed
+      above); setting this flag causes them to be printed, which can
+      be helpful for troubleshooting.
+    </para>
+    <para>
+      Conversely, setting the
+      <literal>HB_BUFFER_FLAG_REMOVE_DEFAULT_IGNORABLES</literal> flag
+      tells HarfBuzz to remove <literal>Default_Ignorable</literal>
+      glyphs from the output buffer entirely. Finally, setting the
+      <literal>HB_BUFFER_FLAG_DO_NOT_INSERT_DOTTED_CIRCLE</literal>
+      flag tells HarfBuzz not to insert the dotted-circle glyph
+      (<literal>U+25CC</literal>, "&#x25CC;"), which is normally
+      inserted into buffer output when broken character sequences are
+      encountered (such as combining marks that are not attached to a
+      base character).
+    </para>
+  </section>
+  
+  <section id="customizing-unicode-functions">
+    <title>Customizing Unicode functions</title>
+    <para>
+      HarfBuzz requires some simple functions for accessing
+      information from the Unicode Character Database (such as the
+      <literal>General_Category</literal> (gc) and
+      <literal>Script</literal> (sc) properties) that is useful
+      for shaping, as well as some useful operations like composing and
+      decomposing code points.
+    </para>
+    <para>
+      HarfBuzz includes its own internal, lightweight set of Unicode
+      functions. At build time, it is also possible to compile support
+      for some other options, such as the Unicode functions provided
+      by GLib or the International Components for Unicode (ICU)
+      library. Generally, this option is only of interest for client
+      programs that have specific integration requirements or that do
+      a significant amount of customization.
+    </para>
+    <para>
+      If your program has access to other Unicode functions, however,
+      such as through a system library or application framework, you
+      might prefer to use those instead of the built-in
+      options. HarfBuzz supports this by implementing its Unicode
+      functions as a set of virtual methods that you can replace —
+      without otherwise affecting HarfBuzz's functionality.
+    </para>
+    <para>
+      The Unicode functions are specified in a structure called
+      <literal>unicode_funcs</literal> which is attached to each
+      buffer. But even though <literal>unicode_funcs</literal> is
+      associated with a <type>hb_buffer_t</type>, the functions
+      themselves are called by other HarfBuzz APIs that access
+      buffers, so it would be unwise for you to hook different
+      functions into different buffers.
+    </para>
+    <para>
+      In addition, you can mark your <literal>unicode_funcs</literal>
+      as immutable by calling
+      <function>hb_unicode_funcs_make_immutable (ufuncs)</function>.
+      This is especially useful if your code is a
+      library or framework that will have its own client programs. By
+      marking your Unicode function choices as immutable, you prevent
+      your own client programs from changing the
+      <literal>unicode_funcs</literal> configuration and introducing
+      inconsistencies and errors downstream.
+    </para>
+    <para>
+      You can retrieve the Unicode-functions configuration for
+      your buffer by calling <function>hb_buffer_get_unicode_funcs()</function>:
+    </para>
+    <programlisting language="C">
+      hb_unicode_funcs_t *ufunctions;
+      ufunctions = hb_buffer_get_unicode_funcs(buf);
+    </programlisting>
+    <para>
+      The current version of <literal>unicode_funcs</literal> uses six functions:
+    </para>
+    <itemizedlist>
+      <listitem>
+	<para>
+	  <function>hb_unicode_combining_class_func_t</function>:
+	  returns the Canonical Combining Class of a code point.
+      	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  <function>hb_unicode_general_category_func_t</function>:
+	  returns the General Category (gc) of a code point.
+      	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  <function>hb_unicode_mirroring_func_t</function>: returns
+	  the Mirroring Glyph code point (for bi-directional
+	  replacement) of a code point.
+      	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  <function>hb_unicode_script_func_t</function>: returns the
+	  Script (sc) property of a code point.
+      	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  <function>hb_unicode_compose_func_t</function>: returns the
+	  canonical composition of a sequence of two code points.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  <function>hb_unicode_decompose_func_t</function>: returns
+	  the canonical decomposition of a code point.
+	</para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      Note, however, that future HarfBuzz releases may alter this set.
+    </para>
+    <para>
+      Each Unicode function has a corresponding setter, with which you
+      can assign a callback to your replacement function. For example,
+      to replace
+      <function>hb_unicode_general_category_func_t</function>, you can call
+    </para>
+    <programlisting language="C">
+      hb_unicode_funcs_set_general_category_func (*ufuncs, func, *user_data, destroy)	    
+    </programlisting>
+    <para>
+      Virtualizing this set of Unicode functions is primarily intended
+      to improve portability. There is no need for every client
+      program to make the effort to replace the default options, so if
+      you are unsure, do not feel any pressure to customize
+      <literal>unicode_funcs</literal>. 
+    </para>
+  </section>
+  
+</chapter>

+ 701 - 0
hbfreetypefont.mod/harfbuzz/docs/usermanual-clusters.xml

@@ -0,0 +1,701 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="clusters">
+  <title>Clusters</title>
+  <section id="clusters-and-shaping">
+    <title>Clusters and shaping</title>
+    <para>
+      In text shaping, a <emphasis>cluster</emphasis> is a sequence of
+      characters that needs to be treated as a single, indivisible
+      unit. A single letter or symbol can be a cluster of its
+      own. Other clusters correspond to longer subsequences of the
+      input code points &mdash; such as a ligature or conjunct form
+      &mdash; and require the shaper to ensure that the cluster is not
+      broken during the shaping process.
+    </para>
+    <para>
+      A cluster is distinct from a <emphasis>grapheme</emphasis>,
+      which is the smallest unit of meaning in a writing system or
+      script.
+    </para>
+    <para>
+      The definitions of the two terms are similar. However, clusters
+      are only relevant for script shaping and glyph layout. In
+      contrast, graphemes are a property of the underlying script, and
+      are of interest when client programs implement orthographic 
+      or linguistic functionality.
+    </para>
+    <para>
+      For example, two individual letters are often two separate
+      graphemes. When two letters form a ligature, however, they
+      combine into a single glyph. They are then part of the same
+      cluster and are treated as a unit by the shaping engine &mdash;
+      even though the two original, underlying letters remain separate
+      graphemes.
+    </para>
+    <para>
+      HarfBuzz is concerned with clusters, <emphasis>not</emphasis>
+      with graphemes &mdash; although client programs using HarfBuzz
+      may still care about graphemes for other reasons from time to time.
+    </para>
+    <para>
+      During the shaping process, there are several shaping operations
+      that may merge adjacent characters (for example, when two code
+      points form a ligature or a conjunct form and are replaced by a
+      single glyph) or split one character into several (for example,
+      when decomposing a code point through the
+      <literal>ccmp</literal> feature). Operations like these alter
+      clusters; HarfBuzz tracks the changes to ensure that no clusters
+      get lost or broken during shaping. 
+    </para>
+    <para>
+      HarfBuzz records cluster information independently from how
+      shaping operations affect the individual glyphs returned in an
+      output buffer. Consequently, a client program using HarfBuzz can
+      utilize the cluster information to implement features such as:
+    </para>
+    <itemizedlist>
+      <listitem>
+	<para>
+	  Correctly positioning the cursor within a shaped text run,
+	  even when characters have formed ligatures, composed or
+	  decomposed, reordered, or undergone other shaping operations.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Correctly highlighting a text selection that includes some,
+	  but not all, of the characters in a word. 
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Applying text attributes (such as color or underlining) to
+	  part, but not all, of a word.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Generating output document formats (such as PDF) with
+	  embedded text that can be fully extracted.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Determining the mapping between input characters and output
+	  glyphs, such as which glyphs are ligatures.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Performing line-breaking, justification, and other
+	  line-level or paragraph-level operations that must be done
+	  after shaping is complete, but which require examining
+	  character-level properties.
+	</para>
+      </listitem>
+    </itemizedlist>
+  </section>
+  <section id="working-with-harfbuzz-clusters">
+    <title>Working with HarfBuzz clusters</title>
+    <para>
+      When you add text to a HarfBuzz buffer, each code point must be
+      assigned a <emphasis>cluster value</emphasis>.
+    </para>
+    <para>
+      This cluster value is an arbitrary number; HarfBuzz uses it only
+      to distinguish between clusters. Many client programs will use
+      the index of each code point in the input text stream as the
+      cluster value. This is for the sake of convenience; the actual
+      value does not matter.
+    </para>
+    <para>
+      Some of the shaping operations performed by HarfBuzz &mdash;
+      such as reordering, composition, decomposition, and substitution
+      &mdash; may alter the cluster values of some characters. The
+      final cluster values in the buffer at the end of the shaping
+      process will indicate to client programs which subsequences of
+      glyphs represent a cluster and, therefore, must not be
+      separated.
+    </para>
+    <para>
+      In addition, client programs can query the final cluster values
+      to discern other potentially important information about the
+      glyphs in the output buffer (such as whether or not a ligature
+      was formed).
+    </para>
+    <para>
+      For example, if the initial sequence of cluster values was:
+    </para>
+    <programlisting>
+      0,1,2,3,4
+    </programlisting>
+    <para>
+      and the final sequence of cluster values is:
+    </para>
+    <programlisting>
+      0,0,3,3
+    </programlisting>
+    <para>
+      then there are two clusters in the output buffer: the first
+      cluster includes the first two glyphs, and the second cluster
+      includes the third and fourth glyphs. It is also evident that a
+      ligature or conjunct has been formed, because there are fewer
+      glyphs in the output buffer (four) than there were code points
+      in the input buffer (five).
+    </para>
+    <para>
+      Although client programs using HarfBuzz are free to assign
+      initial cluster values in any manner they choose to, HarfBuzz
+      does offer some useful guarantees if the cluster values are
+      assigned in a monotonic (either non-decreasing or non-increasing)
+      order.
+    </para>
+    <para>
+      For buffers in the left-to-right (LTR)
+      or top-to-bottom (TTB) text flow direction,
+      HarfBuzz will preserve the monotonic property: client programs
+      are guaranteed that monotonically increasing initial cluster
+      values will be returned as monotonically increasing final
+      cluster values.
+    </para>
+    <para>
+      For buffers in the right-to-left (RTL)
+      or bottom-to-top (BTT) text flow direction,
+      the directionality of the buffer itself is reversed for final
+      output as a matter of design. Therefore, HarfBuzz inverts the
+      monotonic property: client programs are guaranteed that
+      monotonically increasing initial cluster values will be
+      returned as monotonically <emphasis>decreasing</emphasis> final
+      cluster values.
+    </para>
+    <para>
+      Client programs can adjust how HarfBuzz handles clusters during
+      shaping by setting the
+      <literal>cluster_level</literal> of the
+      buffer. HarfBuzz offers three <emphasis>levels</emphasis> of
+      clustering support for this property:
+    </para>
+    <itemizedlist>
+      <listitem>
+	<para><emphasis>Level 0</emphasis> is the default.
+	</para>
+	<para>
+	  The distinguishing feature of level 0 behavior is that, at
+	  the beginning of processing the buffer, all code points that
+	  are categorized as <emphasis>marks</emphasis>,
+	  <emphasis>modifier symbols</emphasis>, or
+	  <emphasis>Emoji extended pictographic</emphasis> modifiers,
+	  as well as the <emphasis>Zero Width Joiner</emphasis> and
+	  <emphasis>Zero Width Non-Joiner</emphasis> code points, are
+	  assigned the cluster value of the closest preceding code
+	  point from <emphasis>different</emphasis> category.
+	</para>
+	<para>
+	  In essence, whenever a base character is followed by a mark
+	  character or a sequence of mark characters, those marks are
+	  reassigned to the same initial cluster value as the base
+	  character. This reassignment is referred to as
+	  "merging" the affected clusters. This behavior is based on
+	  the Grapheme Cluster Boundary specification in <ulink
+	  url="https://www.unicode.org/reports/tr29/#Regex_Definitions">Unicode
+	  Technical Report 29</ulink>.
+	</para>
+	<para>
+	  This cluster level is suitable for code that likes to use
+	  HarfBuzz cluster values as an approximation of the Unicode
+	  Grapheme Cluster Boundaries as well.
+	</para>
+	<para>
+	  Client programs can specify level 0 behavior for a buffer by
+	  setting its <literal>cluster_level</literal> to
+	  <literal>HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES</literal>. 
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  <emphasis>Level 1</emphasis> tweaks the old behavior
+	  slightly to produce better results. Therefore, level 1
+	  clustering is recommended for code that is not required to
+	  implement backward compatibility with the old HarfBuzz.
+	</para>
+	<para>
+	  <emphasis>Level 1</emphasis> differs from level 0 by not merging the
+	  clusters of marks and other modifier code points with the
+	  preceding "base" code point's cluster. By preserving the
+	  separate cluster values of these marks and modifier code
+	  points, script shapers can perform additional operations
+	  that might lead to improved results (for example, coloring
+	  mark glyphs differently than their base).
+	</para>
+	<para>
+	  Client programs can specify level 1 behavior for a buffer by
+	  setting its <literal>cluster_level</literal> to
+	  <literal>HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS</literal>. 
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  <emphasis>Level 2</emphasis> differs significantly in how it
+	  treats cluster values. In level 2, HarfBuzz never merges
+	  clusters.
+	</para>
+	<para>
+	  This difference can be seen most clearly when HarfBuzz processes
+	  ligature substitutions and glyph decompositions. In level 0
+	  and level 1, ligatures and glyph decomposition both involve
+	  merging clusters; in level 2, neither of these operations
+	  triggers a merge.
+	</para>
+	<para>
+	  Client programs can specify level 2 behavior for a buffer by
+	  setting its <literal>cluster_level</literal> to
+	  <literal>HB_BUFFER_CLUSTER_LEVEL_CHARACTERS</literal>. 
+	</para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      As mentioned earlier, client programs using HarfBuzz often
+      assign initial cluster values in a buffer by reusing the indices
+      of the code points in the input text. This gives a sequence of
+      cluster values that is monotonically increasing (for example,
+      0,1,2,3,4).
+    </para>
+    <para>
+      It is not <emphasis>required</emphasis> that the cluster values
+      in a buffer be monotonically increasing. However, if the initial
+      cluster values in a buffer are monotonic and the buffer is
+      configured to use cluster level 0 or 1, then HarfBuzz
+      guarantees that the final cluster values in the shaped buffer
+      will also be monotonic. No such guarantee is made for cluster
+      level 2.
+    </para>
+    <para>
+      In levels 0 and 1, HarfBuzz implements the following conceptual
+      model for cluster values:
+    </para>
+    <itemizedlist spacing="compact">
+      <listitem>
+	<para>
+          If the sequence of input cluster values is monotonic, the
+	  sequence of cluster values will remain monotonic.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+          Each cluster value represents a single cluster.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+          Each cluster contains one or more glyphs and one or more
+          characters.
+	</para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      In practice, this model offers several benefits. Assuming that
+      the initial cluster values were monotonically increasing
+      and distinct before shaping began, then, in the final output:
+    </para>
+    <itemizedlist spacing="compact">
+      <listitem>
+	<para>
+	  All adjacent glyphs having the same final cluster
+	  value belong to the same cluster.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+          Each character belongs to the cluster that has the highest
+	  cluster value <emphasis>not larger than</emphasis> its
+	  initial cluster value.
+	</para>
+      </listitem>
+    </itemizedlist>
+  </section>
+
+  <section id="a-clustering-example-for-levels-0-and-1">
+    <title>A clustering example for levels 0 and 1</title>
+    <para>
+      The basic shaping operations affect clusters in a predictable
+      manner when using level 0 or level 1: 
+    </para>
+    <itemizedlist>
+      <listitem>
+	<para>
+	  When two or more clusters <emphasis>merge</emphasis>, the
+	  resulting merged cluster takes as its cluster value the
+	  <emphasis>minimum</emphasis> of the incoming cluster values.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  When a cluster <emphasis>decomposes</emphasis>, all of the
+	  resulting child clusters inherit as their cluster value the
+	  cluster value of the parent cluster.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  When a character is <emphasis>reordered</emphasis>, the
+	  reordered character and all clusters that the character
+	  moves past as part of the reordering are merged into one cluster.
+	</para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      The functionality, guarantees, and benefits of level 0 and level
+      1 behavior can be seen with some examples. First, let us examine
+      what happens with cluster values when shaping involves cluster
+      merging with ligatures and decomposition.
+    </para>
+
+    <para>
+      Let's say we start with the following character sequence (top row) and
+      initial cluster values (bottom row):
+    </para>
+    <programlisting>
+      A,B,C,D,E
+      0,1,2,3,4
+    </programlisting>
+    <para>
+      During shaping, HarfBuzz maps these characters to glyphs from
+      the font. For simplicity, let us assume that each character maps
+      to the corresponding, identical-looking glyph:
+    </para>
+    <programlisting>
+      A,B,C,D,E
+      0,1,2,3,4
+    </programlisting>
+    <para>
+      Now if, for example, <literal>B</literal> and <literal>C</literal>
+      form a ligature, then the clusters to which they belong
+      &quot;merge&quot;. This merged cluster takes for its cluster
+      value the minimum of all the cluster values of the clusters that
+      went in to the ligature. In this case, we get:
+    </para>
+    <programlisting>
+      A,BC,D,E
+      0,1 ,3,4
+    </programlisting>
+    <para>
+      because 1 is the minimum of the set {1,2}, which were the
+      cluster values of <literal>B</literal> and
+      <literal>C</literal>. 
+    </para>
+    <para>
+      Next, let us say that the <literal>BC</literal> ligature glyph
+      decomposes into three components, and <literal>D</literal> also
+      decomposes into two components. Whenever a cluster decomposes,
+      its components each inherit the cluster value of their parent: 
+    </para>
+    <programlisting>
+      A,BC0,BC1,BC2,D0,D1,E
+      0,1  ,1  ,1  ,3 ,3 ,4
+    </programlisting>
+    <para>
+      Next, if <literal>BC2</literal> and <literal>D0</literal> form a
+      ligature, then their clusters (cluster values 1 and 3) merge into
+      <literal>min(1,3) = 1</literal>:
+    </para>
+    <programlisting>
+      A,BC0,BC1,BC2D0,D1,E
+      0,1  ,1  ,1    ,1 ,4
+    </programlisting>
+    <para>
+      Note that the entirety of cluster 3 merges into cluster 1, not
+      just the <literal>D0</literal> glyph. This reflects the fact
+      that the cluster <emphasis>must</emphasis> be treated as an
+      indivisible unit.
+    </para>
+    <para>
+      At this point, cluster 1 means: the character sequence
+      <literal>BCD</literal> is represented by glyphs
+      <literal>BC0,BC1,BC2D0,D1</literal> and cannot be broken down any
+      further.
+    </para>
+  </section>
+  <section id="reordering-in-levels-0-and-1">
+    <title>Reordering in levels 0 and 1</title>
+    <para>
+      Another common operation in some shapers is glyph
+      reordering. In order to maintain a monotonic cluster sequence
+      when glyph reordering takes place, HarfBuzz merges the clusters
+      of everything in the reordering sequence.
+    </para>
+    <para>
+      For example, let us again start with the character sequence (top
+      row) and initial cluster values (bottom row):
+    </para>
+    <programlisting>
+      A,B,C,D,E
+      0,1,2,3,4
+    </programlisting>
+    <para>
+      If <literal>D</literal> is reordered to the position immediately
+      before <literal>B</literal>, then HarfBuzz merges the
+      <literal>B</literal>, <literal>C</literal>, and
+      <literal>D</literal> clusters &mdash; all the clusters between
+      the final position of the reordered glyph and its original
+      position. This means that we get:
+    </para>
+    <programlisting>
+      A,D,B,C,E
+      0,1,1,1,4
+    </programlisting>
+    <para>
+      as the final cluster sequence.
+    </para>
+    <para>
+      Merging this many clusters is not ideal, but it is the only
+      sensible way for HarfBuzz to maintain the guarantee that the
+      sequence of cluster values remains monotonic and to retain the
+      true relationship between glyphs and characters.
+    </para>
+  </section>
+  <section id="the-distinction-between-levels-0-and-1">
+    <title>The distinction between levels 0 and 1</title>
+    <para>
+      The preceding examples demonstrate the main effects of using
+      cluster levels 0 and 1. The only difference between the two
+      levels is this: in level 0, at the very beginning of the shaping
+      process, HarfBuzz merges the cluster of each base character
+      with the clusters of all Unicode marks (combining or not) and
+      modifiers that follow it.
+    </para>
+    <para>
+      For example, let us start with the following character sequence
+      (top row) and accompanying initial cluster values (bottom row):
+    </para>
+    <programlisting>
+      A,acute,B
+      0,1    ,2
+    </programlisting>
+    <para>
+      The <literal>acute</literal> is a Unicode mark. If HarfBuzz is
+      using cluster level 0 on this sequence, then the
+      <literal>A</literal> and <literal>acute</literal> clusters will
+      merge, and the result will become:
+    </para>
+    <programlisting>
+      A,acute,B
+      0,0    ,2
+    </programlisting>
+    <para>
+      This merger is performed before any other script-shaping
+      steps.
+    </para>
+    <para>
+      This initial cluster merging is the default behavior of the
+      Windows shaping engine, and the old HarfBuzz codebase copied
+      that behavior to maintain compatibility. Consequently, it has
+      remained the default behavior in the new HarfBuzz codebase.
+    </para>
+    <para>
+      But this initial cluster-merging behavior makes it impossible
+      for client programs to implement some features (such as to
+      color diacritic marks differently from their base
+      characters). That is why, in level 1, HarfBuzz does not perform
+      the initial merging step.
+    </para>
+    <para>
+      For client programs that rely on HarfBuzz cluster values to
+      perform cursor positioning, level 0 is more convenient. But
+      relying on cluster boundaries for cursor positioning is wrong: cursor
+      positions should be determined based on Unicode grapheme
+      boundaries, not on shaping-cluster boundaries. As such, using
+      level 1 clustering behavior is recommended. 
+    </para>
+    <para>
+      One final facet of levels 0 and 1 is worth noting. HarfBuzz
+      currently does not allow any
+      <emphasis>multiple-substitution</emphasis> GSUB lookups to 
+      replace a glyph with zero glyphs (in other words, to delete a
+      glyph).
+    </para>
+    <para>
+      But, in some other situations, glyphs can be deleted. In
+      those cases, if the glyph being deleted is the last glyph of its
+      cluster, HarfBuzz makes sure to merge the deleted glyph's
+      cluster with a neighboring cluster.
+    </para>
+    <para>
+      This is done primarily to make sure that the starting cluster of the
+      text always has the cluster index pointing to the start of the text
+      for the run; more than one client program currently relies on this
+      guarantee.
+    </para>
+    <para>
+      Incidentally, Apple's CoreText does something different to
+      maintain the same promise: it inserts a glyph with id 65535 at
+      the beginning of the glyph string if the glyph corresponding to
+      the first character in the run was deleted. HarfBuzz might do
+      something similar in the future.
+    </para>
+  </section>
+  <section id="level-2">
+    <title>Level 2</title>
+    <para>
+      HarfBuzz's level 2 cluster behavior uses a significantly
+      different model than that of level 0 and level 1.
+    </para>
+    <para>
+      The level 2 behavior is easy to describe, but it may be
+      difficult to understand in practical terms. In brief, level 2 
+      performs no merging of clusters whatsoever.
+    </para>
+    <para>
+      This means that there is no initial base-and-mark merging step
+      (as is done in level 0), and it means that reordering moves and
+      ligature substitutions do not trigger a cluster merge.
+    </para>
+    <para>
+      Only one shaping operation directly affects clusters when using
+      level 2:
+    </para>
+    <itemizedlist>
+      <listitem>
+	<para>
+	  When a cluster <emphasis>decomposes</emphasis>, all of the
+	  resulting child clusters inherit as their cluster value the
+	  cluster value of the parent cluster.
+	</para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      When glyphs do form a ligature (or when some other feature
+      substitutes multiple glyphs with one glyph) the cluster value
+      of the first glyph is retained as the cluster value for the
+      resulting ligature.
+    </para>
+    <para>
+      This occurrence sounds similar to a cluster merge, but it is
+      different. In particular, no subsequent characters &mdash;
+      including marks and modifiers &mdash; are affected. They retain
+      their previous cluster values. 
+    </para>
+    <para>
+      Level 2 cluster behavior is ultimately less complex than level 0
+      or level 1, but there are several cases for which processing
+      cluster values produced at level 2 may be tricky. 
+    </para>
+    <section id="ligatures-with-combining-marks-in-level-2">
+      <title>Ligatures with combining marks in level 2</title>
+      <para>
+	The first example of how HarfBuzz's level 2 cluster behavior
+	can be tricky is when the text to be shaped includes combining
+	marks attached to ligatures.
+      </para>
+      <para>
+	Let us start with an input sequence with the following
+	characters (top row) and initial cluster values (bottom row):
+      </para>
+      <programlisting>
+	A,acute,B,breve,C,circumflex
+	0,1    ,2,3    ,4,5
+      </programlisting>
+      <para>
+	If the sequence <literal>A,B,C</literal> forms a ligature,
+	then these are the cluster values HarfBuzz will return under
+	the various cluster levels:
+      </para>
+      <para>
+	Level 0:
+      </para>
+      <programlisting>
+	ABC,acute,breve,circumflex
+	0  ,0    ,0    ,0
+      </programlisting>
+      <para>
+	Level 1:
+      </para>
+      <programlisting>
+	ABC,acute,breve,circumflex
+	0  ,0    ,0    ,5
+      </programlisting>
+      <para>
+	Level 2:
+      </para>
+      <programlisting>
+	ABC,acute,breve,circumflex
+	0  ,1    ,3    ,5
+      </programlisting>
+      <para>
+	Making sense of the level 2 result is the hardest for a client
+	program, because there is nothing in the cluster values that
+	indicates that <literal>B</literal> and <literal>C</literal>
+	formed a ligature with <literal>A</literal>.
+      </para>
+      <para>
+	In contrast, the "merged" cluster values of the mark glyphs
+	that are seen in the level 0 and level 1 output are evidence
+	that a ligature substitution took place. 
+      </para>
+    </section>
+    <section id="reordering-in-level-2">
+      <title>Reordering in level 2</title>
+      <para>
+	Another example of how HarfBuzz's level 2 cluster behavior
+	can be tricky is when glyphs reorder. Consider an input sequence
+	with the following characters (top row) and initial cluster
+	values (bottom row):
+      </para>
+      <programlisting>
+	A,B,C,D,E
+	0,1,2,3,4
+      </programlisting>
+      <para>
+	Now imagine <literal>D</literal> moves before
+	<literal>B</literal> in a reordering operation. The cluster
+	values will then be:
+      </para>
+      <programlisting>
+	A,D,B,C,E
+	0,3,1,2,4
+      </programlisting>
+      <para>
+	Next, if <literal>D</literal> forms a ligature with
+	<literal>B</literal>, the output is:
+      </para>
+      <programlisting>
+	A,DB,C,E
+	0,3 ,2,4
+      </programlisting>
+      <para>
+	However, in a different scenario, in which the shaping rules
+	of the script instead caused <literal>A</literal> and
+	<literal>B</literal> to form a ligature
+	<emphasis>before</emphasis> the <literal>D</literal> reordered, the
+	result would be:
+      </para>
+      <programlisting>
+	AB,D,C,E
+	0 ,3,2,4   
+      </programlisting>
+      <para>
+	There is no way for a client program to differentiate between
+	these two scenarios based on the cluster values
+	alone. Consequently, client programs that use level 2 might
+	need to undertake additional work in order to manage cursor
+	positioning, text attributes, or other desired features.
+      </para>
+    </section>
+    <section id="other-considerations-in-level-2">
+      <title>Other considerations in level 2</title>
+      <para>
+	There may be other problems encountered with ligatures under
+	level 2, such as if the direction of the text is forced to
+	the opposite of its natural direction (for example, Arabic text
+	that is forced into left-to-right directionality). But,
+	generally speaking, these other scenarios are minor corner
+	cases that are too obscure for most client programs to need to
+	worry about.
+      </para>
+    </section>
+  </section>
+</chapter>

+ 518 - 0
hbfreetypefont.mod/harfbuzz/docs/usermanual-fonts-and-faces.xml

@@ -0,0 +1,518 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="fonts-and-faces">
+  <title>Fonts, faces, and output</title>
+    <para>
+      In the previous chapter, we saw how to set up a buffer and fill
+      it with text as Unicode code points. In order to shape this
+      buffer text with HarfBuzz, you will need also need a font
+      object.
+    </para>
+    <para>
+      HarfBuzz provides abstractions to help you cache and reuse the
+      heavier parts of working with binary fonts, so we will look at
+      how to do that. We will also look at how to work with the
+      FreeType font-rendering library and at how you can customize
+      HarfBuzz to work with other libraries.
+    </para>
+    <para>
+      Finally, we will look at how to work with OpenType variable
+      fonts, the latest update to the OpenType font format, and at
+      some other recent additions to OpenType.
+    </para>
+
+  <section id="fonts-and-faces-objects">
+    <title>Font and face objects</title>
+    <para>
+      The outcome of shaping a run of text depends on the contents of
+      a specific font file (such as the substitutions and positioning
+      moves in the 'GSUB' and 'GPOS' tables), so HarfBuzz makes
+      accessing those internals fast.
+    </para>
+    <para>
+      An <type>hb_face_t</type> represents a <emphasis>face</emphasis>
+      in HarfBuzz. This data type is a wrapper around an
+      <type>hb_blob_t</type> blob that holds the contents of a binary
+      font file. Since HarfBuzz supports TrueType Collections and
+      OpenType Collections (each of which can include multiple
+      typefaces), a HarfBuzz face also requires an index number
+      specifying which typeface in the file you want to use. Most of
+      the font files you will encounter in the wild include just a
+      single face, however, so most of the time you would pass in
+      <literal>0</literal> as the index when you create a face:
+    </para>
+    <programlisting language="C">
+      hb_blob_t* blob = hb_blob_create_from_file(file);
+      ...
+      hb_face_t* face = hb_face_create(blob, 0);
+    </programlisting>
+    <para>
+      On its own, a face object is not quite ready to use for
+      shaping. The typeface must be set to a specific point size in
+      order for some details (such as hinting) to work. In addition,
+      if the font file in question is an OpenType Variable Font, then
+      you may need to specify one or more variation-axis settings (or a
+      named instance) in order to get the output you need.
+    </para>
+    <para>
+      In HarfBuzz, you do this by creating a <emphasis>font</emphasis>
+      object from your face.
+    </para>
+    <para>
+      Font objects also have the advantage of being considerably
+      lighter-weight than face objects (remember that a face contains
+      the contents of a binary font file mapped into memory). As a
+      result, you can cache and reuse a font object, but you could
+      also create a new one for each additional size you needed.
+      Creating new fonts incurs some additional overhead, of course,
+      but whether or not it is excessive is your call in the end. In
+      contrast, face objects are substantially larger, and you really
+      should cache them and reuse them whenever possible.
+    </para>
+    <para>
+      You can create a font object from a face object:
+    </para>
+    <programlisting language="C">
+      hb_font_t* hb_font = hb_font_create(hb_face);
+    </programlisting>
+    <para>
+      After creating a font, there are a few properties you should
+      set. Many fonts enable and disable hints based on the size it
+      is used at, so setting this is important for font
+      objects. <function>hb_font_set_ppem(font, x_ppem,
+      y_ppem)</function> sets the pixels-per-EM value of the font. You
+      can also set the point size of the font with
+      <function>hb_font_set_ptem(font, ptem)</function>. HarfBuzz uses the
+      industry standard 72 points per inch.
+    </para>
+    <para>
+      HarfBuzz lets you specify the degree subpixel precision you want
+      through a scaling factor. You can set horizontal and
+      vertical scaling factors on the
+      font by calling <function>hb_font_set_scale(font, x_scale,
+      y_scale)</function>. 
+    </para>
+    <para>
+      There may be times when you are handed a font object and need to
+      access the face object that it comes from. For that, you can call
+    </para>
+    <programlisting language="C">
+      hb_face = hb_font_get_face(hb_font);
+    </programlisting>
+    <para>
+      You can also create a font object from an existing font object
+      using the <function>hb_font_create_sub_font()</function>
+      function. This creates a child font object that is initiated
+      with the same attributes as its parent; it can be used to
+      quickly set up a new font for the purpose of overriding a specific
+      font-functions method.
+    </para>
+    <para>
+      All face objects and font objects are lifecycle-managed by
+      HarfBuzz. After creating a face, you increase its reference
+      count with <function>hb_face_reference(face)</function> and
+      decrease it with
+      <function>hb_face_destroy(face)</function>. Likewise, you
+      increase the reference count on a font with
+      <function>hb_font_reference(font)</function> and decrease it
+      with <function>hb_font_destroy(font)</function>.
+    </para>
+    <para>
+      You can also attach user data to face objects and font objects.
+    </para>
+  </section>
+
+ <section id="fonts-and-faces-custom-functions">
+    <title>Customizing font functions</title>
+    <para>
+      During shaping, HarfBuzz frequently needs to query font objects
+      to get at the contents and parameters of the glyphs in a font
+      file. It includes a built-in set of functions that is tailored
+      to working with OpenType fonts. However, as was the case with
+      Unicode functions in the buffers chapter, HarfBuzz also wants to
+      make it easy for you to assign a substitute set of font
+      functions if you are developing a program to work with a library
+      or platform that provides its own font functions. 
+    </para>
+    <para>
+      Therefore, the HarfBuzz API defines a set of virtual
+      methods for accessing font-object properties, and you can
+      replace the defaults with your own selections without
+      interfering with the shaping process. Each font object in
+      HarfBuzz includes a structure called
+      <literal>font_funcs</literal> that serves as a vtable for the
+      font object. The virtual methods in
+      <literal>font_funcs</literal> are:
+    </para>
+    <itemizedlist>
+      <listitem>
+    <para>
+      <function>hb_font_get_font_h_extents_func_t</function>: returns
+      the extents of the font for horizontal text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_font_v_extents_func_t</function>: returns
+      the extents of the font for vertical text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_nominal_glyph_func_t</function>: returns
+      the font's nominal glyph for a given code point.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_variation_glyph_func_t</function>: returns
+      the font's glyph for a given code point when it is followed by a
+      given Variation Selector.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_nominal_glyphs_func_t</function>: returns
+      the font's nominal glyphs for a series of code points.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_advance_func_t</function>: returns
+      the advance for a glyph.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_h_advance_func_t</function>: returns
+      the advance for a glyph for horizontal text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_v_advance_func_t</function>:returns
+      the advance for a glyph for vertical text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_advances_func_t</function>: returns
+      the advances for a series of glyphs.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_h_advances_func_t</function>: returns
+      the advances for a series of glyphs for horizontal text .
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_v_advances_func_t</function>: returns
+      the advances for a series of glyphs for vertical text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_origin_func_t</function>: returns
+      the origin coordinates of a glyph.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_h_origin_func_t</function>: returns
+      the origin coordinates of a glyph for horizontal text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_v_origin_func_t</function>: returns
+      the origin coordinates of a glyph for vertical text.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_extents_func_t</function>: returns
+      the extents for a glyph.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_contour_point_func_t</function>:
+      returns the coordinates of a specific contour point from a glyph.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_name_func_t</function>: returns the
+      name of a glyph (from its glyph index).
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_get_glyph_from_name_func_t</function>: returns
+      the glyph index that corresponds to a given glyph name.
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_draw_glyph_func_t</function>: gets the outlines
+      of a glyph (by calling #hb_draw_funcs_t callbacks).
+    </para>
+      </listitem>
+      <listitem>
+    <para>
+      <function>hb_font_paint_glyph_func_t</function>: paints a glyph
+      (by calling #hb_paint_funcs_t callbacks).
+    </para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      You can create new font-functions by calling
+      <function>hb_font_funcs_create()</function>:
+    </para>
+    <programlisting language="C">
+      hb_font_funcs_t *ffunctions = hb_font_funcs_create ();
+      hb_font_set_funcs (font, ffunctions, font_data, destroy);
+    </programlisting>
+    <para>
+      The individual methods can each be set with their own setter
+      function, such as
+      <function>hb_font_funcs_set_nominal_glyph_func(ffunctions,
+      func, user_data, destroy)</function>.
+    </para>
+    <para>
+      Font-functions structures can be reused for multiple font
+      objects, and can be reference counted with
+      <function>hb_font_funcs_reference()</function> and
+      <function>hb_font_funcs_destroy()</function>. Just like other
+      objects in HarfBuzz, you can set user-data for each
+      font-functions structure and assign a destroy callback for
+      it.
+    </para>
+    <para>
+      You can also mark a font-functions structure as immutable,
+      with <function>hb_font_funcs_make_immutable()</function>. This
+      is especially useful if your code is a library or framework that
+      will have its own client programs. By marking your
+      font-functions structures as immutable, you prevent your client
+      programs from changing the configuration and introducing
+      inconsistencies and errors downstream.
+    </para>
+    <para>
+      To override only some functions while using the default implementation
+      for the others, you will need to create a sub-font. By default, the
+      sub-font uses the font functions of its parent except for the functions
+      that were explicitly set. The following code will override only the
+      <function>hb_font_get_nominal_glyph_func_t</function> for the sub-font:
+    </para>
+    <programlisting language="C">
+      hb_font_t *subfont = hb_font_create_sub_font (font)
+      hb_font_funcs_t *ffunctions = hb_font_funcs_create ();
+      hb_font_funcs_set_nominal_glyph_func (ffunctions, func, user_data, destroy);
+      hb_font_set_funcs (subfont, ffunctions, font_data, destroy);
+      hb_font_funcs_destroy (ffunctions);
+    </programlisting>
+  </section>
+
+  <section id="fonts-and-faces-native-opentype">
+    <title>Font objects and HarfBuzz's native OpenType implementation</title>
+    <para>
+      By default, whenever HarfBuzz creates a font object, it will
+      configure the font to use a built-in set of font functions that
+      supports contemporary OpenType font internals. If you want to
+      work with OpenType or TrueType fonts, you should be able to use
+      these functions without difficulty.
+    </para>
+    <para>
+      Many of the methods in the font-functions structure deal with
+      the fundamental properties of glyphs that are required for
+      shaping text: extents (the maximums and minimums on each axis),
+      origins (the <literal>(0,0)</literal> coordinate point which
+      glyphs are drawn in reference to), and advances (the amount that
+      the cursor needs to be moved after drawing each glyph, including
+      any empty space for the glyph's side bearings).
+    </para>
+    <para>
+      As you can see in the list of functions, there are separate "horizontal"
+      and "vertical" variants depending on whether the text is set in
+      the horizontal or vertical direction. For some scripts, fonts
+      that are designed to support text set horizontally or vertically (for
+      example, in Japanese) may include metrics for both text
+      directions. When fonts don't include this information, HarfBuzz
+      does its best to transform what the font provides.
+    </para>
+    <para>
+      In addition to the direction-specific functions, HarfBuzz
+      provides some higher-level functions for fetching information
+      like extents and advances for a glyph. If you call
+    </para>
+    <programlisting language="C">
+      hb_font_get_glyph_advance_for_direction(font, direction, extents);
+    </programlisting>
+    <para>
+      then you can provide any <type>hb_direction_t</type> as the
+      <parameter>direction</parameter> parameter, and HarfBuzz will
+      use the correct function variant for the text direction. There
+      are similar higher-level versions of the functions for fetching
+      extents, origin coordinates, and contour-point
+      coordinates. There are also addition and subtraction functions
+      for moving points with respect to the origin.
+    </para>
+    <para>
+      There are also methods for fetching the glyph ID that
+      corresponds to a Unicode code point (possibly when followed by a
+      variation-selector code point), fetching the glyph name from the
+      font, and fetching the glyph ID that corresponds to a glyph name
+      you already have.
+    </para>
+    <para>
+      HarfBuzz also provides functions for converting between glyph
+      names and string
+      variables. <function>hb_font_glyph_to_string(font, glyph, s,
+      size)</function> retrieves the name for the glyph ID
+      <parameter>glyph</parameter> from the font object. It generates a
+      generic name of the form <literal>gidDDD</literal> (where DDD is
+      the glyph index) if there is no name for the glyph in the
+      font. The <function>hb_font_glyph_from_string(font, s, len,
+      glyph)</function> takes an input string <parameter>s</parameter>
+      and looks for a glyph with that name in the font, returning its
+      glyph ID in the <parameter>glyph</parameter>
+      output parameter. It automatically parses
+      <literal>gidDDD</literal> and <literal>uniUUUU</literal> strings.
+    </para>
+  </section>
+
+  <section id="fonts-and-faces-variable">
+    <title>Working with OpenType Variable Fonts</title>
+    <para>
+      If you are working with OpenType Variable Fonts, there are a few
+      additional functions you should use to specify the
+      variation-axis settings of your font object. Without doing so,
+      your variable font's font object can still be used, but only at
+      the default setting for every axis (which, of course, is
+      sometimes what you want, but does not cover general usage).
+    </para>
+    <para>
+      HarfBuzz manages variation settings in the
+      <type>hb_variation_t</type> data type, which holds a <property>tag</property> for the
+      variation-axis identifier tag and a <property>value</property> for its
+      setting. You can retrieve the list of variation axes in a font
+      binary from the face object (not from a font object, notably) by
+      calling <function>hb_ot_var_get_axis_count(face)</function> to
+      find the number of axes, then using
+      <function>hb_ot_var_get_axis_infos()</function> to collect the 
+      axis structures:
+    </para>
+    <programlisting language="C">
+      axes = hb_ot_var_get_axis_count(face);
+      ...
+      hb_ot_var_get_axis_infos(face, 0, axes, axes_array);
+    </programlisting>
+    <para>
+      For each axis returned in the array, you can can access the
+      identifier in its <property>tag</property>. HarfBuzz also has
+      tag definitions predefined for the five standard axes specified
+      in OpenType (<literal>ital</literal> for italic,
+      <literal>opsz</literal> for optical size,
+      <literal>slnt</literal> for slant, <literal>wdth</literal> for
+      width, and <literal>wght</literal> for weight). Each axis also
+      has a <property>min_value</property>, a
+      <property>default_value</property>, and a <property>max_value</property>.
+    </para>
+    <para>
+      To set your font object's variation settings, you call the
+      <function>hb_font_set_variations()</function> function with an
+      array of <type>hb_variation_t</type> variation settings. Let's
+      say our font has weight and width axes. We need to specify each
+      of the axes by tag and assign a value on the axis:
+    </para>
+    <programlisting language="C">
+      unsigned int variation_count = 2;
+      hb_variation_t variation_data[variation_count];
+      variation_data[0].tag = HB_OT_TAG_VAR_AXIS_WIDTH;
+      variation_data[1].tag = HB_OT_TAG_VAR_AXIS_WEIGHT;
+      variation_data[0].value = 80;
+      variation_data[1].value = 750;
+      ...
+      hb_font_set_variations(font, variation_data, variation_count);
+    </programlisting>
+    <para>
+      That should give us a slightly condensed font ("normal" on the
+      <literal>wdth</literal> axis is 100) at a noticeably bolder
+      weight ("regular" is 400 on the <literal>wght</literal> axis).
+    </para>
+    <para>
+      In practice, though, you should always check that the value you
+      want to set on the axis is within the
+      [<property>min_value</property>,<property>max_value</property>]
+      range actually implemented in the font's variation axis. After
+      all, a font might only provide lighter-than-regular weights, and
+      setting a heavier value on the <literal>wght</literal> axis will
+      not change that.
+    </para>
+    <para>
+      Once your variation settings are specified on your font object,
+      however, shaping with a variable font is just like shaping a
+      static font.
+    </para>
+    <para>
+      In addition to providing the variation axes themselves, fonts may also
+      pre-define certain variation coordinates as named instances. HarfBuzz
+      makes these coordinates (and their associated names) available via
+      <function>hb_ot_var_named_instance_get_design_coords()</function> and
+      <function>hb_ot_var_named_instance_get_subfamily_name_id()</function>.
+    </para>
+    <para>
+      Applications should treat named instances like multiple independent,
+      static fonts.
+    </para>
+  </section>
+
+  <section id="glyphs-and-rendering">
+    <title>Glyphs and rendering</title>
+
+    <para>
+      The main purpose of HarfBuzz is shaping, which creates a list of positioned
+      glyphs as output. The remaining task for text layout is to convert this list
+      into rendered output. While HarfBuzz does not handle rasterization of glyphs
+      per se, it does have APIs that provide access to the font data that is needed
+      to perform this task.
+    </para>
+    <para>
+      Traditionally, the shapes of glyphs in scalable fonts are provided as quadratic
+      or cubic Beziér curves defining outlines to be filled. To obtain the outlines
+      for a glyph, call <function>hb_font_draw_glyph()</function> and pass a
+      <type>hb_draw_funcs_t</type> struct. The callbacks in that struct will be called
+      for each segment of the outline. Note that this API provides access to outlines
+      as they are defined in the font, without applying hinting to fit the curves
+      to the pixel grid.
+    </para>
+    <para>
+      Fonts may provide pre-rendered images for glyphs instead of or in addition to
+      outlines. This is most common for fonts that contain colored glyphs, such as
+      Emoji. To access these images, use <function>hb_ot_color_reference_png()</function>
+      or <function>hb_ot_color_reference_svg()</function>.
+    </para>
+    <para>
+      Another way in which fonts provide colored glyphs is via paint graphs that
+      combine glyph outlines with gradients and allow for transformations and
+      compositing. In its simplest form, this can be presented as a series of
+      layers that are rendered on top of each other, each with its own color.
+      HarfBuzz has the <function>hb_ot_color_glyph_get_layers()</function> to
+      access glyph data in this form.
+    </para>
+    <para>
+      In the general case, you have to use <function>hb_font_paint_glyph()</function>
+      and pass a <type>hb_paint_funcs_t</type> struct with callbacks to obtain paint
+      graphs for glyphs that have them. The <function>hb_font_paint_glyph()</function>
+      API can handle outline and image glyphs as well, so it provides a unified API for
+      access to glyph rendering information.
+    </para>
+  </section>
+
+ </chapter>

+ 316 - 0
hbfreetypefont.mod/harfbuzz/docs/usermanual-getting-started.xml

@@ -0,0 +1,316 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="getting-started">
+  <title>Getting started with HarfBuzz</title>
+  <section id="an-overview-of-the-harfbuzz-shaping-api">
+    <title>An overview of the HarfBuzz shaping API</title>
+    <para>
+      The core of the HarfBuzz shaping API is the function
+      <function>hb_shape()</function>. This function takes a font, a
+      buffer containing a string of Unicode codepoints and
+      (optionally) a list of font features as its input. It replaces
+      the codepoints in the buffer with the corresponding glyphs from
+      the font, correctly ordered and positioned, and with any of the
+      optional font features applied.
+    </para>
+    <para>
+      In addition to holding the pre-shaping input (the Unicode
+      codepoints that comprise the input string) and the post-shaping
+      output (the glyphs and positions), a HarfBuzz buffer has several
+      properties that affect shaping. The most important are the
+      text-flow direction (e.g., left-to-right, right-to-left,
+      top-to-bottom, or bottom-to-top), the script tag, and the
+      language tag.
+    </para>
+
+    <para>
+      For input string buffers, flags are available to denote when the
+      buffer represents the beginning or end of a paragraph, to
+      indicate whether or not to visibly render Unicode <literal>Default
+      Ignorable</literal> codepoints, and to modify the cluster-merging
+      behavior for the buffer. For shaped output buffers, the
+      individual X and Y offsets and <literal>advances</literal>
+      (the logical dimensions) of each glyph are 
+      accessible. HarfBuzz also flags glyphs as
+      <literal>UNSAFE_TO_BREAK</literal> if breaking the string at
+      that glyph (e.g., in a line-breaking or hyphenation process)
+      would require re-shaping the text.
+    </para>
+    
+    <para>
+      HarfBuzz also provides methods to compare the contents of
+      buffers, join buffers, normalize buffer contents, and handle
+      invalid codepoints, as well as to determine the state of a
+      buffer (e.g., input codepoints or output glyphs). Buffer
+      lifecycles are managed and all buffers are reference-counted.
+    </para>
+
+    <para>
+      Although the default <function>hb_shape()</function> function is
+      sufficient for most use cases, a variant is also provided that
+      lets you specify which of HarfBuzz's shapers to use on a buffer. 
+    </para>
+
+    <para>
+      HarfBuzz can read TrueType fonts, TrueType collections, OpenType
+      fonts, and OpenType collections. Functions are provided to query
+      font objects about metrics, Unicode coverage, available tables and
+      features, and variation selectors. Individual glyphs can also be
+      queried for metrics, variations, and glyph names. OpenType
+      variable fonts are supported, and HarfBuzz allows you to set
+      variation-axis coordinates on font objects.
+    </para>
+    
+    <para>
+      HarfBuzz provides glue code to integrate with various other
+      libraries, including FreeType, GObject, and CoreText. Support
+      for integrating with Uniscribe and DirectWrite is experimental
+      at present.
+    </para>
+  </section>
+
+  <section id="terminology">
+    <title>Terminology</title>
+    <para>
+      
+    </para>
+      <variablelist>
+	<?dbfo list-presentation="blocks"?> 
+	<varlistentry>
+	  <term>script</term>
+	  <listitem>
+	    <para>
+	      In text shaping, a <emphasis>script</emphasis> is a
+	      writing system: a set of symbols, rules, and conventions
+	      that is used to represent a language or multiple
+	      languages.
+	    </para>
+	    <para>
+	      In general computing lingo, the word "script" can also
+	      be used to mean an executable program (usually one
+	      written in a human-readable programming language). For
+	      the sake of clarity, HarfBuzz documents will always use
+	      more specific terminology when referring to this
+	      meaning, such as "Python script" or "shell script." In
+	      all other instances, "script" refers to a writing system.
+	    </para>
+	    <para>
+	      For developers using HarfBuzz, it is important to note
+	      the distinction between a script and a language. Most
+	      scripts are used to write a variety of different
+	      languages, and many languages may be written in more
+	      than one script.
+	    </para>
+	  </listitem>
+	</varlistentry>
+	
+	<varlistentry>
+	  <term>shaper</term>
+	  <listitem>
+	    <para>
+	      In HarfBuzz, a <emphasis>shaper</emphasis> is a
+	      handler for a specific script-shaping model. HarfBuzz
+	      implements separate shapers for Indic, Arabic, Thai and
+	      Lao, Khmer, Myanmar, Tibetan, Hangul, Hebrew, the
+	      Universal Shaping Engine (USE), and a default shaper for
+	      scripts with no script-specific shaping model.
+	    </para>
+	  </listitem>
+	</varlistentry>
+	
+	<varlistentry>
+	  <term>cluster</term>
+	  <listitem>
+	    <para>
+	      In text shaping, a <emphasis>cluster</emphasis> is a
+	      sequence of codepoints that must be treated as an
+	      indivisible unit. Clusters can include code-point
+	      sequences that form a ligature or base-and-mark
+	      sequences. Tracking and preserving clusters is important
+	      when shaping operations might separate or reorder
+	      code points.
+	    </para>
+	    <para>
+	      HarfBuzz provides three cluster
+	      <emphasis>levels</emphasis> that implement different
+	      approaches to the problem of preserving clusters during
+	      shaping operations.
+	    </para>
+	  </listitem>
+	</varlistentry>
+	
+	<varlistentry>
+	  <term>grapheme</term>
+	  <listitem>
+	    <para>
+	      In linguistics, a <emphasis>grapheme</emphasis> is one
+	      of the indivisible units that make up a writing system or
+	      script. Often, graphemes are individual symbols (letters,
+	      numbers, punctuation marks, logograms, etc.) but,
+	      depending on the writing system, a particular grapheme
+	      might correspond to a sequence of several Unicode code
+	      points.
+	    </para>
+	    <para>
+	      In practice, HarfBuzz and other text-shaping engines
+	      are not generally concerned with graphemes. However, it
+	      is important for developers using HarfBuzz to recognize
+	      that there is a difference between graphemes and shaping
+	      clusters (see above). The two concepts may overlap
+	      frequently, but there is no guarantee that they will be
+	      identical.
+	    </para>
+	  </listitem>
+	</varlistentry>
+	
+	<varlistentry>
+	  <term>syllable</term>
+	  <listitem>
+	    <para>
+	      In linguistics, a <emphasis>syllable</emphasis> is an 
+	      a sequence of sounds that makes up a building block of a
+	      particular language. Every language has its own set of
+	      rules describing what constitutes a valid syllable.
+	    </para>
+	    <para>
+	      For text-shaping purposes, the various definitions of
+	      "syllable" are important because script-specific shaping
+	      operations may be applied at the syllable level. For
+	      example, a reordering rule might specify that a vowel
+	      mark be reordered to the beginning of the syllable.
+	    </para>
+	    <para>
+	      Syllables will consist of one or more Unicode code
+	      points. The definition of a syllable for a particular
+	      writing system might correspond to how HarfBuzz
+	      identifies clusters (see above) for the same writing
+	      system. However, it is important for developers using
+	      HarfBuzz to recognize that there is a difference between
+	      syllables and shaping clusters. The two concepts may
+	      overlap frequently, but there is no guarantee that they
+	      will be identical.
+	    </para>
+	  </listitem>
+	</varlistentry>
+      </variablelist>
+    
+  </section>
+
+
+  <section id="a-simple-shaping-example">
+    <title>A simple shaping example</title>
+
+    <para>
+      Below is the simplest HarfBuzz shaping example possible.
+    </para>
+    <orderedlist numeration="arabic">
+      <listitem>
+	<para>
+          Create a buffer and put your text in it.
+	</para>
+      </listitem>
+    </orderedlist>
+    <programlisting language="C">
+      #include &lt;hb.h&gt;
+
+      hb_buffer_t *buf;
+      buf = hb_buffer_create();
+      hb_buffer_add_utf8(buf, text, -1, 0, -1);
+    </programlisting>
+    <orderedlist numeration="arabic">
+      <listitem override="2">
+	<para>
+          Set the script, language and direction of the buffer.
+	</para>
+      </listitem>
+    </orderedlist>
+    <programlisting language="C">
+      // If you know the direction, script, and language
+      hb_buffer_set_direction(buf, HB_DIRECTION_LTR);
+      hb_buffer_set_script(buf, HB_SCRIPT_LATIN);
+      hb_buffer_set_language(buf, hb_language_from_string("en", -1));
+
+      // If you don't know the direction, script, and language
+      hb_buffer_guess_segment_properties(buffer);
+    </programlisting>
+    <orderedlist numeration="arabic">
+      <listitem override="3">
+	<para>
+          Create a face and a font from a font file.
+	</para>
+      </listitem>
+    </orderedlist>
+    <programlisting language="C">
+      hb_blob_t *blob = hb_blob_create_from_file(filename); /* or hb_blob_create_from_file_or_fail() */
+      hb_face_t *face = hb_face_create(blob, 0);
+      hb_font_t *font = hb_font_create(face);
+    </programlisting>
+    <orderedlist numeration="arabic">
+      <listitem override="4">
+	<para>
+          Shape!
+	</para>
+      </listitem>
+    </orderedlist>
+    <programlisting>
+      hb_shape(font, buf, NULL, 0);
+    </programlisting>
+    <orderedlist numeration="arabic">
+      <listitem override="5">
+	<para>
+          Get the glyph and position information.
+	</para>
+      </listitem>
+    </orderedlist>
+    <programlisting language="C">
+      unsigned int glyph_count;
+      hb_glyph_info_t *glyph_info    = hb_buffer_get_glyph_infos(buf, &amp;glyph_count);
+      hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &amp;glyph_count);
+    </programlisting>
+    <orderedlist numeration="arabic">
+      <listitem override="6">
+	<para>
+          Iterate over each glyph.
+	</para>
+      </listitem>
+    </orderedlist>
+    <programlisting language="C">
+      hb_position_t cursor_x = 0;
+      hb_position_t cursor_y = 0;
+      for (unsigned int i = 0; i &lt; glyph_count; i++) {
+          hb_codepoint_t glyphid  = glyph_info[i].codepoint;
+          hb_position_t x_offset  = glyph_pos[i].x_offset;
+          hb_position_t y_offset  = glyph_pos[i].y_offset;
+          hb_position_t x_advance = glyph_pos[i].x_advance;
+          hb_position_t y_advance = glyph_pos[i].y_advance;
+       /* draw_glyph(glyphid, cursor_x + x_offset, cursor_y + y_offset); */
+          cursor_x += x_advance;
+          cursor_y += y_advance;
+      }
+    </programlisting>
+    <orderedlist numeration="arabic">
+      <listitem override="7">
+	<para>
+          Tidy up.
+	</para>
+      </listitem>
+    </orderedlist>
+    <programlisting language="C">
+      hb_buffer_destroy(buf);
+      hb_font_destroy(font);
+      hb_face_destroy(face);
+      hb_blob_destroy(blob);
+    </programlisting>
+    
+    <para>
+      This example shows enough to get us started using HarfBuzz. In
+      the sections that follow, we will use the remainder of
+      HarfBuzz's API to refine and extend the example and improve its
+      text-shaping capabilities.
+    </para>
+  </section>
+</chapter>

+ 14 - 0
hbfreetypefont.mod/harfbuzz/docs/usermanual-glyph-information.xml

@@ -0,0 +1,14 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<sect1 id="glyph-information">
+  <title>Glyph information</title>
+  <sect2 id="names-and-numbers">
+    <title>Names and numbers</title>
+    <para>
+    </para>
+  </sect2>
+</sect1>

+ 349 - 0
hbfreetypefont.mod/harfbuzz/docs/usermanual-install-harfbuzz.xml

@@ -0,0 +1,349 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="install-harfbuzz">
+  <title>Installing HarfBuzz</title>
+  
+  <section id="download">
+    <title id="download.title">Downloading HarfBuzz</title>
+    <para>
+      The HarfBuzz source code is hosted at <ulink
+      url="https://github.com/harfbuzz/harfbuzz">github.com/harfbuzz/harfbuzz</ulink>.
+    </para>
+    <para>
+      Tarball releases and Win32 binary bundles (which include the
+      libharfbuzz DLL, hb-view.exe, hb-shape.exe, and all
+      dependencies) of HarfBuzz can be downloaded from <ulink
+      url="https://github.com/harfbuzz/harfbuzz/releases">github.com/harfbuzz/harfbuzz/releases</ulink>.
+    </para>
+    <para>
+      Release notes are posted with each new release to provide an
+      overview of the changes. The project <ulink url="https://github.com/harfbuzz/harfbuzz/issues">tracks bug
+      reports and other issues</ulink> on GitHub. Discussion and
+      questions are welcome on <ulink
+      url="https://github.com/harfbuzz/harfbuzz/discussions">GitHub</ulink> as well.
+    </para>
+    <para>
+      The API included in the <filename
+      class='headerfile'>hb.h</filename> file will not change in a
+      compatibility-breaking way in any release. However, other,
+      peripheral headers are more likely to go through minor
+      modifications. We will do our best to never change APIs in an
+      incompatible way. We will <emphasis>never</emphasis> break the ABI. 
+    </para>
+  </section>
+  
+  <section id="building">
+    <title>Building HarfBuzz</title>
+
+    <section id="building.linux">
+      <title>Building on Linux</title>
+    <para>
+      <emphasis>(1)</emphasis> To build HarfBuzz on Linux, you must first install the
+      development packages for FreeType, Cairo, and GLib. The exact
+      commands required for this step will vary depending on
+      the Linux distribution you use.
+    </para>
+    <para>
+      For example, on an Ubuntu or Debian system, you would run:
+      <programlisting><command>sudo apt install</command> <package>gcc g++ libfreetype6-dev libglib2.0-dev libcairo2-dev</package></programlisting>
+      On Fedora, RHEL, CentOS, or other Red-Hat&ndash;based systems, you would run:
+      <programlisting><command>sudo yum install</command> <package>gcc gcc-c++ freetype-devel glib2-devel cairo-devel</package></programlisting>
+
+    </para>
+    
+    <para>
+      <emphasis>(2)</emphasis> The next step depends on whether you
+      are building from the source in a downloaded release tarball or
+      from the source directly from the git repository.
+    </para>
+    <para>
+      <emphasis>(2)(a)</emphasis> If you downloaded the HarfBuzz
+      source code in a tarball, you can now extract the source.
+    </para>
+    <para>
+      From a shell in the top-level directory of the extracted source
+      code, you can run <command>meson build</command> followed by
+      <command>meson compile -C build</command> as with any other standard package.
+    </para>
+    <para>
+      This should leave you with a shared
+      library in the <filename>src/</filename> directory, and a few
+      utility programs including <command>hb-view</command> and
+      <command>hb-shape</command> under the <filename>util/</filename>
+      directory.
+    </para>
+    <para>
+      <emphasis>(2)(b)</emphasis> If you are building from the source in the HarfBuzz git
+      repository, rather than installing from a downloaded tarball
+      release, then you must install two more auxiliary tools before you 
+      can build for the first time: <package>pkg-config</package>.
+    </para>
+    <para>
+      On Ubuntu or Debian, run:
+      <programlisting><command>sudo apt-get install</command> <package>meson pkg-config gtk-doc-tools</package></programlisting>
+      On Fedora, RHEL, CentOS, run:
+      <programlisting><command>sudo yum install</command> <package>meson pkgconfig gtk-doc</package></programlisting>
+      
+    </para>
+    <para>
+      With <package>pkg-config</package> installed, you can now run
+      <command>meson build</command> then
+      <command>meson compile -C build</command> to build HarfBuzz.
+    </para>
+    </section>
+
+    
+    <section id="building.windows">
+      <title>Building on Windows</title>
+
+      <para>
+        <ulink url="https://mesonbuild.com/Getting-meson.html">Install meson</ulink>
+        and run (from the console) <command>meson build</command> (by default
+        bundled dependencies are not built, <command>--wrap-mode=default</command>
+        overrides this), then <command>meson compile -C build</command> to
+	build HarfBuzz.
+      </para>
+    </section>
+
+    
+    <section id="building.macos">
+      <title>Building on macOS</title>
+
+      <para>
+	There are two ways to build HarfBuzz on Mac systems: MacPorts
+	and Homebrew. The process is similar to the process used on a
+	Linux system.
+      </para>
+      <para>
+	<emphasis>(1)</emphasis> You must first install the
+	development packages for FreeType, Cairo, and GLib. If you are
+	using MacPorts, you should run:
+      <programlisting><command>sudo port install</command> <package>freetype glib2 cairo</package></programlisting>
+      </para>
+      <para>
+	If you are using Homebrew, you should run:
+	<programlisting><command>brew install</command> <package>freetype glib cairo</package></programlisting>
+      </para>
+      <para>
+	<emphasis>(2)</emphasis> The next step depends on whether you are building from the
+	source in a downloaded release tarball or from the source directly
+	from the git repository.
+      </para>
+      <para>
+	<emphasis>(2)(a)</emphasis> If you are installing HarfBuzz
+	from a downloaded tarball release, extract the tarball and
+	open a Terminal in the extracted source-code directory. Run:
+	<programlisting><command>meson build</command></programlisting>
+	followed by:
+	<programlisting><command>meson compile -C build</command></programlisting>
+	to build HarfBuzz.
+      </para>
+      <para>
+	<emphasis>(2)(b)</emphasis> Alternatively, if you are building
+	HarfBuzz from the source in the HarfBuzz git repository, then
+	you must install several built-time dependencies before
+	proceeding.
+      </para>
+      <para>If you are
+	using MacPorts, you should run:
+      <programlisting><command>sudo port install</command> <package>meson pkgconfig gtk-doc</package></programlisting>
+      to install the build dependencies.
+      </para>
+      <para>If you are using Homebrew, you should run:
+	<programlisting><command>brew install</command> <package>meson pkgconfig gtk-doc</package></programlisting>
+      	Finally, you can run:
+	<programlisting><command>meson build</command></programlisting>
+      </para>
+      <para>
+	<emphasis>(3)</emphasis> You can now build HarfBuzz (on either
+	a MacPorts or a Homebrew system) by running:
+	<programlisting><command>meson build</command></programlisting>
+	followed by:
+	<programlisting><command>meson compile -C build</command></programlisting>
+      </para>
+      <para>
+	This should leave you with a shared
+	library in the <filename>src/</filename> directory, and a few
+	utility programs including <command>hb-view</command> and
+	<command>hb-shape</command> under the <filename>util/</filename>
+	directory.
+      </para>      
+	
+    </section>
+
+    <section id="configuration">
+      <title>Configuration options</title>
+
+      <para>
+	The instructions in the "Building HarfBuzz" section will build
+	the source code under its default configuration. If needed,
+	the following additional configuration options are available.
+      </para>
+
+      <variablelist>
+	<?dbfo list-presentation="blocks"?>	
+	<varlistentry>
+	  <term><command>-Dglib=enabled</command></term>
+	  <listitem>
+	    <para>
+	     Use <ulink url="https://developer.gnome.org/glib/">GLib</ulink>. <emphasis>(Default = auto)</emphasis>
+	    </para>
+	    <para>
+	      This option enables or disables usage of the GLib
+	      library.  The default setting is to check for the
+	      presence of GLib and, if it is found, build with
+	      GLib support. GLib is native to GNU/Linux systems but is
+	      available on other operating system as well.
+	    </para>
+	  </listitem>
+	</varlistentry>
+	
+	<varlistentry>
+	  <term><command>-Dgobject=enabled</command></term>
+	  <listitem>
+	    <para>
+	      Use <ulink url="https://developer.gnome.org/gobject/stable/">GObject</ulink>. <emphasis>(Default = no)</emphasis>
+	    </para>	   
+	    <para>
+	      This option enables or disables usage of the GObject
+	      library. The default setting is to check for the
+	      presence of GObject and, if it is found, build with
+	      GObject support. GObject is native to GNU/Linux systems but is
+	      available on other operating system as well.
+	    </para> 
+	  </listitem>
+	</varlistentry>
+	
+	<varlistentry>
+	  <term><command>-Dcairo=enabled</command></term>
+	  <listitem>
+	    <para>
+	      Use <ulink url="https://cairographics.org/">Cairo</ulink>. <emphasis>(Default = auto)</emphasis>
+	    </para>	   
+	    <para>
+	      This option enables or disables usage of the Cairo
+	      graphics-rendering library. The default setting is to
+	      check for the presence of Cairo and, if it is found,
+	      build with Cairo support.
+	    </para>
+	    <para>
+	      Note: Cairo is used only by the HarfBuzz
+	      command-line utilities, and not by the HarfBuzz library.
+	    </para>
+	  </listitem>
+	</varlistentry>
+	
+	<varlistentry>
+	  <term><command>-Dicu=enabled</command></term>
+	  <listitem>
+	    <para>
+	      Use the <ulink url="http://site.icu-project.org/home">ICU</ulink> library. <emphasis>(Default = auto)</emphasis>
+	    </para>
+	    <para>
+	      This option enables or disables usage of the
+	      <emphasis>International Components for
+	      Unicode</emphasis> (ICU) library, which provides access
+	      to Unicode Character Database (UCD) properties as well
+	      as normalization and conversion functions. The default
+	      setting is to check for the presence of ICU and, if it
+	      is found, build with ICU support.
+	    </para>
+	  </listitem>
+	</varlistentry>
+	
+	<varlistentry>
+	  <term><command>-Dgraphite=enabled</command></term>
+	  <listitem>
+	    <para>
+	      Use the <ulink url="http://graphite.sil.org/">Graphite2</ulink> library. <emphasis>(Default = no)</emphasis>
+	    </para>
+	    <para>
+	      This option enables or disables usage of the Graphite2
+	      library, which provides support for the Graphite shaping
+	      model. 
+	    </para>
+	  </listitem>
+	</varlistentry>
+	
+	<varlistentry>
+	  <term><command>-Dfreetype=enabled</command></term>
+	  <listitem>
+	    <para>
+	      Use the <ulink url="https://www.freetype.org/">FreeType</ulink> library. <emphasis>(Default = auto)</emphasis>
+	    </para>
+	    <para>
+	      This option enables or disables usage of the FreeType
+	      font-rendering library. The default setting is to check for the
+	      presence of FreeType and, if it is found, build with
+	      FreeType support.
+	    </para>
+	  </listitem>
+	</varlistentry>
+	
+	<varlistentry>
+	  <term><command>-Dgdi=enabled</command></term>
+	  <listitem>
+	    <para>
+	      Use the <ulink
+	      url="https://docs.microsoft.com/en-us/windows/desktop/intl/uniscribe">Uniscribe</ulink>
+	      library (experimental). <emphasis>(Default = no)</emphasis>
+	    </para>
+	    <para>
+	      This option enables or disables usage of the Uniscribe
+	      font-rendering library. Uniscribe is available on
+	      Windows systems. Uniscribe support is used only for
+	      testing purposes and does not need to be enabled for
+	      HarfBuzz to run on Windows systems.
+	    </para>
+	  </listitem>
+	</varlistentry>
+	
+	<varlistentry>
+	  <term><command>-Ddirectwrite=enabled</command></term>
+	  <listitem>
+	    <para>
+	      Use the <ulink url="https://docs.microsoft.com/en-us/windows/desktop/directwrite/direct-write-portal">DirectWrite</ulink> library (experimental). <emphasis>(Default = no)</emphasis>
+	    </para>
+	    <para>
+	      This option enables or disables usage of the DirectWrite
+	      font-rendering library. DirectWrite is available on
+	      Windows systems. DirectWrite support is used only for
+	      testing purposes and does not need to be enabled for
+	      HarfBuzz to run on Windows systems.
+	    </para>
+	  </listitem>
+	</varlistentry>
+	
+	<varlistentry>
+	  <term><command>-Dcoretext=enabled</command></term>
+	  <listitem>
+	    <para>
+	      Use the <ulink url="https://developer.apple.com/documentation/coretext">CoreText</ulink> library. <emphasis>(Default = no)</emphasis>
+	    </para>
+	    <para>
+	      This option enables or disables usage of the CoreText
+	      library. CoreText is available on macOS and iOS systems.
+	    </para>
+	  </listitem>
+	</varlistentry>	
+
+	<varlistentry>
+	  <term><command>-Ddocs=enabled</command></term>
+	  <listitem>
+	    <para>
+	      Use <ulink url="https://github.com/GNOME/gtk-doc">GTK-Doc</ulink>. <emphasis>(Default = no)</emphasis>
+	    </para>
+	    <para>
+	      This option enables the building of the documentation.
+	    </para>
+	  </listitem>
+	</varlistentry>
+      </variablelist>
+    </section>
+    
+  </section>
+</chapter>

+ 647 - 0
hbfreetypefont.mod/harfbuzz/docs/usermanual-integration.xml

@@ -0,0 +1,647 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="integration">
+  <title>Platform Integration Guide</title>
+  <para>
+    HarfBuzz was first developed for use with the GNOME and GTK
+    software stack commonly found in desktop Linux
+    distributions. Nevertheless, it can be used on other operating
+    systems and platforms, from iOS and macOS to Windows. It can also
+    be used with other application frameworks and components, such as
+    Android, Qt, or application-specific widget libraries.
+  </para>
+  <para>
+    This chapter will look at how HarfBuzz fits into a typical
+    text-rendering pipeline, and will discuss the APIs available to
+    integrate HarfBuzz with contemporary Linux, Mac, and Windows
+    software. It will also show how HarfBuzz integrates with popular
+    external libraries like FreeType and International Components for
+    Unicode (ICU) and describe the HarfBuzz language bindings for
+    Python.
+  </para>
+  <para>
+    On a GNOME system, HarfBuzz is designed to tie in with several
+    other common system libraries. The most common architecture uses
+    Pango at the layer directly "above" HarfBuzz; Pango is responsible
+    for text segmentation and for ensuring that each input
+    <type>hb_buffer_t</type> passed to HarfBuzz for shaping contains
+    Unicode code points that share the same segment properties
+    (namely, direction, language, and script, but also higher-level
+    properties like the active font, font style, and so on).
+  </para>
+  <para>
+    The layer directly "below" HarfBuzz is typically FreeType, which
+    is used to rasterize glyph outlines at the necessary optical size,
+    hinting settings, and pixel resolution. FreeType provides APIs for
+    accessing font and face information, so HarfBuzz includes
+    functions to create <type>hb_face_t</type> and
+    <type>hb_font_t</type> objects directly from FreeType
+    objects. HarfBuzz can use FreeType's built-in functions for
+    <structfield>font_funcs</structfield> vtable in an <type>hb_font_t</type>.
+  </para>
+  <para>
+    FreeType's output is bitmaps of the rasterized glyphs; on a
+    typical Linux system these will then be drawn by a graphics
+    library like Cairo, but those details are beyond HarfBuzz's
+    control. On the other hand, at the top end of the stack, Pango is
+    part of the larger GNOME framework, and HarfBuzz does include APIs
+    for working with key components of GNOME's higher-level libraries
+    &mdash; most notably GLib.
+  </para>
+  <para>
+    For other operating systems or application frameworks, the
+    critical integration points are where HarfBuzz gets font and face
+    information about the font used for shaping and where HarfBuzz
+    gets Unicode data about the input-buffer code points.
+  </para>
+  <para>
+    The font and face information is necessary for text shaping
+    because HarfBuzz needs to retrieve the glyph indices for
+    particular code points, and to know the extents and advances of
+    glyphs. Note that, in an OpenType variable font, both of those
+    types of information can change with different variation-axis
+    settings.
+  </para>
+  <para>
+    The Unicode information is necessary for shaping because the
+    properties of a code point (such as its General Category (gc),
+    Canonical Combining Class (ccc), and decomposition) can directly
+    impact the shaping moves that HarfBuzz performs.
+  </para>
+  
+  <section id="integration-glib">
+    <title>GNOME integration, GLib, and GObject</title>
+    <para>
+      As mentioned in the preceding section, HarfBuzz offers
+      integration APIs to help client programs using the
+      GNOME and GTK framework commonly found in desktop Linux
+      distributions. 
+    </para>
+    <para>
+      GLib is the main utility library for GNOME applications. It
+      provides basic data types and conversions, file abstractions,
+      string manipulation, and macros, as well as facilities like
+      memory allocation and the main event loop.
+    </para>
+    <para>
+      Where text shaping is concerned, GLib provides several utilities
+      that HarfBuzz can take advantage of, including a set of
+      Unicode-data functions and a data type for script
+      information. Both are useful when working with HarfBuzz
+      buffers. To make use of them, you will need to include the
+      <filename>hb-glib.h</filename> header file.
+    </para>
+    <para>
+      GLib's <ulink
+      url="https://developer.gnome.org/glib/stable/glib-Unicode-Manipulation.html">Unicode
+      manipulation API</ulink> includes all the functionality
+      necessary to retrieve Unicode data for the
+      <structfield>unicode_funcs</structfield> structure of a HarfBuzz
+      <type>hb_buffer_t</type>. 
+    </para>
+    <para>
+      The function <function>hb_glib_get_unicode_funcs()</function>
+      sets up a <type>hb_unicode_funcs_t</type> structure configured
+      with the GLib Unicode functions and returns a pointer to it.
+    </para>
+    <para>
+      You can attach this Unicode-functions structure to your buffer,
+      and it will be ready for use with GLib:
+    </para>
+    <programlisting language="C">
+      #include &lt;hb-glib.h&gt;
+      ...
+      hb_unicode_funcs_t *glibufunctions;
+      glibufunctions = hb_glib_get_unicode_funcs();
+      hb_buffer_set_unicode_funcs(buf, glibufunctions);
+    </programlisting>
+    <para>
+      For script information, GLib uses the
+      <type>GUnicodeScript</type> type. Like HarfBuzz's own
+      <type>hb_script_t</type>, this data type is an enumeration
+      of Unicode scripts, but text segments passed in from GLib code
+      will be tagged with a <type>GUnicodeScript</type>. Therefore,
+      when setting the script property on a <type>hb_buffer_t</type>,
+      you will need to convert between the <type>GUnicodeScript</type>
+      of the input provided by GLib and HarfBuzz's
+      <type>hb_script_t</type> type.
+    </para>
+    <para>
+      The <function>hb_glib_script_to_script()</function> function
+      takes an <type>GUnicodeScript</type> script identifier as its
+      sole argument and returns the corresponding <type>hb_script_t</type>.
+      The <function>hb_glib_script_from_script()</function> does the
+      reverse, taking an <type>hb_script_t</type> and returning the
+      <type>GUnicodeScript</type> identifier for GLib.
+    </para>
+    <para>
+      Finally, GLib also provides a reference-counted object type called <ulink
+      url="https://developer.gnome.org/glib/stable/glib-Byte-Arrays.html#GBytes"><type>GBytes</type></ulink>
+      that is used for accessing raw memory segments with the benefits
+      of GLib's lifecycle management. HarfBuzz provides a
+      <function>hb_glib_blob_create()</function> function that lets
+      you create an <type>hb_blob_t</type> directly from a
+      <type>GBytes</type> object. This function takes only the
+      <type>GBytes</type> object as its input; HarfBuzz registers the
+      GLib <function>destroy</function> callback automatically.
+    </para>
+    <para>
+      The GNOME platform also features an object system called
+      GObject. For HarfBuzz, the main advantage of GObject is a
+      feature called <ulink
+      url="https://gi.readthedocs.io/en/latest/">GObject
+      Introspection</ulink>. This is a middleware facility that can be
+      used to generate language bindings for C libraries. HarfBuzz uses it
+      to build its Python bindings, which we will look at in a separate section.
+    </para>
+  </section>
+  
+  <section id="integration-freetype">
+    <title>FreeType integration</title>
+    <para>
+      FreeType is the free-software font-rendering engine included in
+      desktop Linux distributions, Android, ChromeOS, iOS, and multiple Unix
+      operating systems, and used by cross-platform programs like
+      Chrome, Java, and GhostScript. Used together, HarfBuzz can
+      perform shaping on Unicode text segments, outputting the glyph
+      IDs that FreeType should rasterize from the active font as well
+      as the positions at which those glyphs should be drawn.
+    </para>
+    <para>
+      HarfBuzz provides integration points with FreeType at the
+      face-object and font-object level and for the font-functions
+      virtual-method structure of a font object. These functions
+      make it easy for clients that use FreeType for rasterization
+      or font-loading, to use HarfBuzz for shaping. To use the
+      FreeType-integration API, include the
+      <filename>hb-ft.h</filename> header.
+    </para>
+    <para>
+      In a typical client program, you will create your
+      <type>hb_face_t</type> face object and <type>hb_font_t</type>
+      font object from a FreeType <type>FT_Face</type>. HarfBuzz
+      provides a suite of functions for doing this.
+    </para>
+    <para>
+      In the most common case, you will want to use
+      <function>hb_ft_font_create_referenced()</function>, which
+      creates both an <type>hb_face_t</type> face object and
+      <type>hb_font_t</type> font object (linked to that face object),
+      and provides lifecycle management.
+    </para>
+    <para>
+      It is important to note,
+      though, that while HarfBuzz makes a distinction between its face and
+      font objects, FreeType's <type>FT_Face</type> does not. After
+      you create your <type>FT_Face</type>, you must set its size
+      parameter using <function>FT_Set_Char_Size()</function>, because
+      an <type>hb_font_t</type> is defined as an instance of an
+      <type>hb_face_t</type> with size specified.
+    </para>
+    <programlisting language="C">
+      #include &lt;hb-ft.h&gt;
+      ...
+      FT_New_Face(ft_library, font_path, index, &amp;face);
+      FT_Set_Char_Size(face, 0, 1000, 0, 0);
+      hb_font_t *font = hb_ft_font_create(face);
+    </programlisting>
+    <para>
+      <function>hb_ft_font_create_referenced()</function> is
+      the recommended function for creating an <type>hb_face_t</type> face
+      object. This function calls <function>FT_Reference_Face()</function>
+      before using the <type>FT_Face</type> and calls 
+      <function>FT_Done_Face()</function> when it is finished using the
+      <type>FT_Face</type>. Consequently, your client program does not need
+      to worry about destroying the <type>FT_Face</type> while HarfBuzz
+      is still using it.
+    </para>
+    <para>
+      Although <function>hb_ft_font_create_referenced()</function> is
+      the recommended function, there is another variant for client code
+      where special circumstances make it necessary. The simpler
+      version of the function is <function>hb_ft_font_create()</function>,
+      which takes an <type>FT_Face</type> and an optional destroy callback 
+      as its arguments. Because <function>hb_ft_font_create()</function> 
+      does not offer lifecycle management, however, your client code will
+      be responsible for tracking references to the <type>FT_Face</type>
+      objects and destroying them when they are no longer needed. If you
+      do not have a valid reason for doing this, use
+      <function>hb_ft_font_create_referenced()</function>. 
+    </para>
+    <para>
+      After you have created your font object from your
+      <type>FT_Face</type>, you can set or retrieve the
+      <structfield>load_flags</structfield> of the
+      <type>FT_Face</type> through the <type>hb_font_t</type>
+      object. HarfBuzz provides
+      <function>hb_ft_font_set_load_flags()</function> and
+      <function>hb_ft_font_get_load_flags()</function> for this
+      purpose. The ability to set the
+      <structfield>load_flags</structfield> through the font object
+      could be useful for enabling or disabling hinting, for example,
+      or to activate vertical layout.
+    </para>
+    <para>
+      HarfBuzz also provides a utility function called
+      <function>hb_ft_font_has_changed()</function> that you should
+      call whenever you have altered the properties of your underlying
+      <type>FT_Face</type>, as well as a
+      <function>hb_ft_get_face()</function> that you can call on an
+      <type>hb_font_t</type> font object to fetch its underlying <type>FT_Face</type>.
+    </para>
+    <para>
+      With an <type>hb_face_t</type> and <type>hb_font_t</type> both linked
+      to your <type>FT_Face</type>, you will typically also want to
+      use FreeType for the <structfield>font_funcs</structfield>
+      vtable of your <type>hb_font_t</type>. As a reminder, this
+      font-functions structure is the set of methods that HarfBuzz
+      will use to fetch important information from the font, such as
+      the advances and extents of individual glyphs. 
+    </para>
+    <para>
+      All you need to do is call
+    </para>
+    <programlisting language="C">
+      hb_ft_font_set_funcs(font);
+    </programlisting>
+    <para>
+      and HarfBuzz will use FreeType for the font-functions in
+      <literal>font</literal>. 
+    </para>
+    <para>
+      As we noted above, an <type>hb_font_t</type> is derived from an
+      <type>hb_face_t</type> with size (and, perhaps, other
+      parameters, such as variation-axis coordinates)
+      specified. Consequently, you can reuse an <type>hb_face_t</type>
+      with several <type>hb_font_t</type> objects, and HarfBuzz
+      provides functions to simplify this.
+    </para>
+    <para>
+      The <function>hb_ft_face_create_referenced()</function>
+      function creates just an <type>hb_face_t</type> from a FreeType
+      <type>FT_Face</type> and, as with
+      <function>hb_ft_font_create_referenced()</function> above,
+      provides lifecycle management for the <type>FT_Face</type>.
+    </para>
+    <para>
+      Similarly, there is an <function>hb_ft_face_create()</function>
+      function variant that does not provide the lifecycle-management
+      feature. As with the font-object case, if you use this version
+      of the function, it will be your client code's respsonsibility
+      to track usage of the <type>FT_Face</type> objects.
+    </para>
+    <para>
+      A third variant of this function is
+      <function>hb_ft_face_create_cached()</function>, which is the
+      same as <function>hb_ft_face_create()</function> except that it
+      also uses the <structfield>generic</structfield> field of the
+      <type>FT_Face</type> structure to save a pointer to the newly
+      created <type>hb_face_t</type>. Subsequently, function calls
+      that pass the same <type>FT_Face</type> will get the same
+      <type>hb_face_t</type> returned &mdash; and the
+      <type>hb_face_t</type> will be correctly reference
+      counted. Still, as with
+      <function>hb_ft_face_create()</function>, your client code must
+      track references to the <type>FT_Face</type> itself, and destroy
+      it when it is unneeded.
+    </para>
+  </section>
+
+  <section id="integration-cairo">
+    <title>Cairo integration</title>
+
+    <para>
+      Cairo is a 2D graphics library that is frequently used together
+      with GTK and Pango. Cairo supports rendering text using FreeType, or
+      by using callback-based 'user fonts'.
+    </para>
+    <para>
+      HarfBuzz provides integration points with cairo for fonts as well as
+      for buffers. To use the Cairo-integration API, link against libharfbuzz-cairo,
+      and include the <filename>hb-cairo.h</filename> header. For easy buildsystem
+      integration, HarfBuzz comes with a <filename>harfbuzz-cairo.pc</filename>
+      pkg-config file.
+    </para>
+    <para>
+      To create a <type>cairo_scaled_font_t</type> font from a HarfBuzz
+      <type>hb_font_t</type>, you can use <function>hb_cairo_font_face_create_for_font()</function>
+      or <function>hb_cairo_font_face_create_for_face()</function>. The former API
+      applies variations and synthetic slant from the <type>hb_font_t</type> when
+      rendering, the latter takes them from the <type>cairo_font_options_t</type>
+      that were passed when creating the <type>cairo_scaled_font_t</type>.
+    </para>
+    <para>
+      The Cairo fonts created in this way make use of Cairo's user-font facilities.
+      They can be used to render on any Cairo context, and provide full support for
+      font rendering features, including color. One current limitation of the
+      implementation is that it does not support hinting for glyph outlines.
+    </para>
+    <para>
+      When using color fonts with this API, the color palette index is taken from
+      the <type>cairo_font_options_t</type> (with new enough Cairo), and the foreground
+      color is extracted from the source of the Cairo context.
+    </para>
+    <para>
+      To render the results of shaping a piece of text, use
+      <function>hb_cairo_glyphs_from_buffer()</function> to obtain the glyphs in
+      a form that can be passed to <function>cairo_show_text_glyphs()</function> or
+      <function>cairo_show_glyphs()</function>.
+    </para>
+  </section>
+
+  <section id="integration-uniscribe">
+    <title>Uniscribe integration</title>
+    <para>
+      If your client program is running on Windows, HarfBuzz offers
+      an additional API that can help integrate with Microsoft's
+      Uniscribe engine and the Windows GDI.
+    </para>
+    <para>
+      Overall, the Uniscribe API covers a broader set of typographic
+      layout functions than HarfBuzz implements, but HarfBuzz's
+      shaping API can serve as a drop-in replacement for Uniscribe's shaping
+      functionality. In fact, one of HarfBuzz's design goals is to
+      accurately reproduce the same output for shaping a given text
+      segment that Uniscribe produces &mdash; even to the point of
+      duplicating known shaping bugs or deviations from the
+      specification &mdash; so you can be confident that your users'
+      documents with their existing fonts will not be affected adversely by
+      switching to HarfBuzz.
+    </para>
+    <para>
+      At a basic level, HarfBuzz's <function>hb_shape()</function>
+      function replaces both the <ulink url=""><function>ScriptShape()</function></ulink>
+      and <ulink
+      url="https://docs.microsoft.com/en-us/windows/desktop/api/Usp10/nf-usp10-scriptplace"><function>ScriptPlace()</function></ulink>
+      functions from Uniscribe. 
+    </para>
+    <para>
+      However, whereas <function>ScriptShape()</function> returns the
+      glyphs and clusters for a shaped sequence and
+      <function>ScriptPlace()</function> returns the advances and
+      offsets for those glyphs, <function>hb_shape()</function>
+      handles both. After <function>hb_shape()</function> shapes a
+      buffer, the output glyph IDs and cluster IDs are returned as
+      an array of <structname>hb_glyph_info_t</structname> structures, and the
+      glyph advances and offsets are returned as an array of
+      <structname>hb_glyph_position_t</structname> structures. 
+    </para>
+    <para>
+      Your client program only needs to ensure that it converts
+      correctly between HarfBuzz's low-level data types (such as
+      <type>hb_position_t</type>) and Windows's corresponding types
+      (such as <type>GOFFSET</type> and <type>ABC</type>). Be sure you
+      read the <xref linkend="buffers-language-script-and-direction"
+      /> 
+      chapter for a full explanation of how HarfBuzz input buffers are
+      used, and see <xref linkend="shaping-buffer-output" /> for the
+      details of what <function>hb_shape()</function> returns in the
+      output buffer when shaping is complete. 
+    </para>
+    <para>
+      Although <function>hb_shape()</function> itself is functionally
+      equivalent to Uniscribe's shaping routines, there are two
+      additional HarfBuzz functions you may want to use to integrate
+      the libraries in your code. Both are used to link HarfBuzz font
+      objects to the equivalent Windows structures.
+    </para>
+    <para>
+      The <function>hb_uniscribe_font_get_logfontw()</function>
+      function takes a <type>hb_font_t</type> font object and returns
+      a pointer to the <ulink
+      url="https://docs.microsoft.com/en-us/windows/desktop/api/wingdi/ns-wingdi-logfontw"><type>LOGFONTW</type></ulink>
+      "logical font" that corresponds to it. A <type>LOGFONTW</type>
+      structure holds font-wide attributes, including metrics, size,
+      and style information.
+    </para>
+<!--      
+     <para>
+       In Uniscribe's model, the <type>SCRIPT_CACHE</type> holds the
+       device context, including the logical font that the shaping
+       functions apply.
+       https://docs.microsoft.com/en-us/windows/desktop/Intl/script-cache
+    </para>
+-->
+    <para>
+      The <function>hb_uniscribe_font_get_hfont()</function> function
+      also takes a <type>hb_font_t</type> font object, but it returns
+      an <type>HFONT</type> &mdash; a handle to the underlying logical
+      font &mdash; instead.
+    </para>
+    <para>
+      <type>LOGFONTW</type>s and <type>HFONT</type>s are both needed
+      by other Uniscribe functions.
+    </para>
+    <para>
+      As a final note, you may notice a reference to an optional
+      <literal>uniscribe</literal> shaper back-end in the <xref
+      linkend="configuration" /> section of the HarfBuzz manual. This
+      option is not a Uniscribe-integration facility.
+    </para>
+    <para>
+      Instead, it is a internal code path used in the
+      <command>hb-shape</command> command-line utility, which hands
+      shaping functionality over to Uniscribe entirely, when run on a
+      Windows system. That allows testing HarfBuzz's native output
+      against the Uniscribe engine, for tracking compatibility and
+      debugging.
+    </para>
+    <para>
+      Because this back-end is only used when testing HarfBuzz
+      functionality, it is disabled by default when building the
+      HarfBuzz binaries.
+    </para>
+  </section>
+   
+  <section id="integration-coretext">
+    <title>Core Text integration</title>
+    <para>
+      If your client program is running on macOS or iOS, HarfBuzz offers
+      an additional API that can help integrate with Apple's
+      Core Text engine and the underlying Core Graphics
+      framework. HarfBuzz does not attempt to offer the same
+      drop-in-replacement functionality for Core Text that it strives
+      for with Uniscribe on Windows, but you can still use HarfBuzz
+      to perform text shaping in native macOS and iOS applications.
+    </para>
+    <para>
+      Note, though, that if your interest is just in using fonts that
+      contain Apple Advanced Typography (AAT) features, then you do
+      not need to add Core Text integration. HarfBuzz natively
+      supports AAT features and will shape AAT fonts (on any platform)
+      automatically, without requiring additional work on your
+      part. This includes support for AAT-specific TrueType tables
+      such as <literal>mort</literal>, <literal>morx</literal>, and
+      <literal>kerx</literal>, which AAT fonts use instead of
+      <literal>GSUB</literal> and <literal>GPOS</literal>.
+    </para>
+    <para>
+      On a macOS or iOS system, the primary integration points offered
+      by HarfBuzz are for face objects and font objects. 
+    </para>
+    <para>
+      The Apple APIs offer a pair of data structures that map well to
+      HarfBuzz's face and font objects. The Core Graphics API, which
+      is slightly lower-level than Core Text, provides
+      <ulink url="https://developer.apple.com/documentation/coregraphics/cgfontref"><type>CGFontRef</type></ulink>, which enables access to typeface
+      properties, but does not include size information. Core Text's
+      <ulink url="https://developer.apple.com/documentation/coretext/ctfont-q6r"><type>CTFontRef</type></ulink> is analogous to a HarfBuzz font object,
+      with all of the properties required to render text at a specific
+      size and configuration.
+      Consequently, a HarfBuzz <type>hb_font_t</type> font object can
+      be hooked up to a Core Text <type>CTFontRef</type>, and a HarfBuzz
+      <type>hb_face_t</type> face object can be hooked up to a
+      <type>CGFontRef</type>.
+    </para>
+    <para>
+      You can create a <type>hb_face_t</type> from a
+      <type>CGFontRef</type> by using the
+      <function>hb_coretext_face_create()</function>. Subsequently,
+      you can retrieve the <type>CGFontRef</type> from a
+      <type>hb_face_t</type> with <function>hb_coretext_face_get_cg_font()</function>.
+    </para>
+    <para>
+      Likewise, you create a <type>hb_font_t</type> from a
+      <type>CTFontRef</type> by calling
+      <function>hb_coretext_font_create()</function>, and you can
+      fetch the associated <type>CTFontRef</type> from a
+      <type>hb_font_t</type> font object with
+      <function>hb_coretext_face_get_ct_font()</function>. 
+    </para>
+    <para>
+      HarfBuzz also offers a <function>hb_font_set_ptem()</function>
+      that you an use to set the nominal point size on any
+      <type>hb_font_t</type> font object. Core Text uses this value to
+      implement optical scaling. 
+    </para>
+    <para>
+      When integrating your client code with Core Text, it is
+      important to recognize that Core Text <literal>points</literal>
+      are not typographic points (standardized at 72 per inch) as the
+      term is used elsewhere in OpenType. Instead, Core Text points
+      are CSS points, which are standardized at 96 per inch.
+    </para>
+    <para>
+      HarfBuzz's font functions take this distinction into account,
+      but it can be an easy detail to miss in cross-platform
+      code. 
+    </para>
+    <para>
+      As a final note, you may notice a reference to an optional
+      <literal>coretext</literal> shaper back-end in the <xref
+      linkend="configuration" /> section of the HarfBuzz manual. This
+      option is not a Core Text-integration facility.
+    </para>
+    <para>
+      Instead, it is a internal code path used in the
+      <command>hb-shape</command> command-line utility, which hands
+      shaping functionality over to Core Text entirely, when run on a
+      macOS system. That allows testing HarfBuzz's native output
+      against the Core Text engine, for tracking compatibility and debugging.
+    </para>
+    <para>
+      Because this back-end is only used when testing HarfBuzz
+      functionality, it is disabled by default when building the
+      HarfBuzz binaries.
+    </para>
+  </section>
+  
+  <section id="integration-icu">
+    <title>ICU integration</title>
+    <para>
+      Although HarfBuzz includes its own Unicode-data functions, it
+      also provides integration APIs for using the International
+      Components for Unicode (ICU) library as a source of Unicode data
+      on any supported platform.
+    </para>
+    <para>
+      The principal integration point with ICU is the
+      <type>hb_unicode_funcs_t</type> Unicode-functions structure
+      attached to a buffer. This structure holds the virtual methods
+      used for retrieving Unicode character properties, such as
+      General Category, Script, Combining Class, decomposition
+      mappings, and mirroring information.
+    </para>
+    <para>
+      To use ICU in your client program, you need to call
+      <function>hb_icu_get_unicode_funcs()</function>, which creates a
+      Unicode-functions structure populated with the ICU function for
+      each included method. Subsequently, you can attach the
+      Unicode-functions structure to your buffer:
+    </para>
+    <programlisting language="C">
+      hb_unicode_funcs_t *icufunctions;
+      icufunctions = hb_icu_get_unicode_funcs();
+      hb_buffer_set_unicode_funcs(buf, icufunctions);
+    </programlisting>
+    <para>
+      and ICU will be used for Unicode-data access.
+    </para>
+    <para>
+      HarfBuzz also supplies a pair of functions
+      (<function>hb_icu_script_from_script()</function> and
+      <function>hb_icu_script_to_script()</function>) for converting
+      between ICU's and HarfBuzz's internal enumerations of Unicode
+      scripts. The <function>hb_icu_script_from_script()</function>
+      function converts from a HarfBuzz <type>hb_script_t</type> to an
+      ICU <type>UScriptCode</type>. The
+      <function>hb_icu_script_to_script()</function> function does the
+      reverse: converting from a <type>UScriptCode</type> identifier
+      to a <type>hb_script_t</type>.
+    </para>
+    <para>
+      By default, HarfBuzz's ICU support is built as a separate shared
+      library (<filename class="libraryfile">libharfbuzz-icu.so</filename>)
+      when compiling HarfBuzz from source. This allows client programs
+      that do not need ICU to link against HarfBuzz without unnecessarily
+      adding ICU as a dependency. You can also build HarfBuzz with ICU
+      support built directly into the main HarfBuzz shared library
+      (<filename class="libraryfile">libharfbuzz.so</filename>),
+      by specifying the <literal>--with-icu=builtin</literal>
+      compile-time option.
+    </para>
+
+  </section>
+  
+  <section id="integration-python">
+    <title>Python bindings</title>
+    <para>
+      As noted in the <xref linkend="integration-glib" /> section,
+      HarfBuzz uses a feature called <ulink
+      url="https://wiki.gnome.org/Projects/GObjectIntrospection">GObject
+      Introspection</ulink> (GI) to provide bindings for Python.
+    </para>
+    <para>
+      At compile time, the GI scanner analyzes the HarfBuzz C source
+      and builds metadata objects connecting the language bindings to
+      the C library. Your Python code can then use the HarfBuzz binary
+      through its Python interface.
+    </para>
+    <para>
+      HarfBuzz's Python bindings support Python 2 and Python 3. To use
+      them, you will need to have the <literal>pygobject</literal>
+      package installed. Then you should import
+      <literal>HarfBuzz</literal> from
+      <literal>gi.repository</literal>: 
+    </para>
+    <programlisting language="Python">
+      from gi.repository import HarfBuzz
+    </programlisting>
+    <para>
+      and you can call HarfBuzz functions from Python. Sample code can
+      be found in the <filename>sample.py</filename> script in the
+      HarfBuzz <filename>src</filename> directory.
+    </para>
+    <para>
+      Do note, however, that the Python API is subject to change
+      without advance notice. GI allows the bindings to be
+      automatically updated, which is one of its advantages, but you
+      may need to update your Python code.
+    </para>
+  </section>
+  
+</chapter>

+ 266 - 0
hbfreetypefont.mod/harfbuzz/docs/usermanual-object-model.xml

@@ -0,0 +1,266 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="object-model">
+  <title>The HarfBuzz object model</title>
+  <section id="object-model-intro">
+    <title>An overview of data types in HarfBuzz</title>
+    <para>
+      HarfBuzz features two kinds of data types: non-opaque,
+      pass-by-value types and opaque, heap-allocated types.  This kind
+      of separation is common in C libraries that have to provide
+      API/ABI compatibility (almost) indefinitely.
+    </para>
+    <para>
+      <emphasis>Value types:</emphasis> The non-opaque, pass-by-value
+      types include integer types, enums, and small structs.  Exposing
+      a struct in the public API makes it impossible to expand the
+      struct in the future. As such, exposing structs is reserved for
+      cases where it’s extremely inefficient to do otherwise.
+    </para>
+    <para>
+      In HarfBuzz, several structs, like <literal>hb_glyph_info_t</literal> and
+      <literal>hb_glyph_position_t</literal>, fall into that efficiency-sensitive
+      category and are non-opaque.
+    </para>
+    <para>
+      For all non-opaque structs where future extensibility may be
+      necessary, reserved members are included to hold space for
+      possible future members.  As such, it’s important to provide
+      <function>equal()</function>, and <function>hash()</function>
+      methods for such structs, allowing users of the API do
+      effectively deal with the type without having to
+      adapt their code to future changes.
+    </para>
+    <para>
+      Important value types provided by HarfBuzz include the structs
+      for working with Unicode code points, glyphs, and tags for font
+      tables and features, as well as the enums for many Unicode and
+      OpenType properties.
+    </para>
+  </section>
+
+  <section id="object-model-object-types">
+    <title>Objects in HarfBuzz</title>
+    <para>
+      <emphasis>Object types:</emphasis> Opaque struct types are used
+      for what HarfBuzz loosely calls "objects."  This doesn’t have
+      much to do with the terminology from object-oriented programming
+      (OOP), although some of the concepts are similar.
+    </para>
+    <para>
+      In HarfBuzz, all object types provide certain
+      lifecycle-management APIs.  Objects are reference-counted, and
+      constructed with various <function>create()</function> methods, referenced via
+      <function>reference()</function> and dereferenced using
+      <function>destroy()</function>.
+    </para>
+    <para>
+      For example,
+      the <literal>hb_buffer_t</literal> object has
+      <function>hb_buffer_create()</function> as its constructor,
+      <function>hb_buffer_reference()</function> to reference, and
+      <function>hb_buffer_destroy()</function> to dereference.
+    </para>
+    <para>
+      After construction, each object's properties are accessible only
+      through the setter and getter functions described in the API
+      Reference manual.
+    </para>
+    <para>
+      Note that many object types can be marked as read-only or immutable,
+      facilitating their use in multi-threaded environments.
+    </para>
+    <para>
+      Key object types provided by HarfBuzz include:
+    </para>
+    <itemizedlist spacing="compact">
+      <listitem>
+	<para>
+	  <emphasis>blobs</emphasis>, which act as low-level wrappers around binary
+	  data. Blobs are typically used to hold the contents of a
+	  binary font file.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  <emphasis>faces</emphasis>, which represent typefaces from a
+	  font file, but without specific parameters (such as size) set.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  <emphasis>fonts</emphasis>, which represent instances of a
+	  face with all of their parameters specified.
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  <emphasis>buffers</emphasis>, which hold Unicode code points
+	  for characters (before shaping) and the shaped glyph output
+	  (after shaping).
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  <emphasis>shape plans</emphasis>, which store the settings
+	  that HarfBuzz will use when shaping a particular text
+	  segment. Shape plans are not generally used by client
+	  programs directly, but as we will see in a later chapter,
+	  they are still valuable to understand.
+	</para>
+      </listitem>
+    </itemizedlist>
+
+  </section>
+
+
+
+  <section id="object-model-lifecycle">
+    <title>Object lifecycle management</title>
+    <para>
+      Each object type in HarfBuzz provides a
+      <function>create()</function> method. Some object types provide
+      additional variants of <function>create()</function> to handle
+      special cases or to speed up common tasks; those variants are
+      documented in the API reference. For example,
+      <function>hb_blob_create_from_file()</function> constructs a new
+      blob directly from the contents of a file.
+    </para>
+    <para>
+      All objects are created with an initial reference count of
+      <literal>1</literal>. Client programs can increase the reference
+      count on an object by calling its
+      <function>reference()</function> method. Whenever a client
+      program is finished with an object, it should call its
+      corresponding <function>destroy()</function> method. The destroy
+      method will decrease the reference count on the object and,
+      whenever the reference count reaches zero, it will also destroy
+      the object and free all of the associated memory.
+    </para>
+    <para>
+      All of HarfBuzz's object-lifecycle-management APIs are
+      thread-safe (unless you compiled HarfBuzz from source with the
+      <literal>HB_NO_MT</literal> configuration flag), even when the
+      object as a whole is not thread-safe.
+      It is also permissible to <function>reference()</function> or to
+      <function>destroy()</function> the <literal>NULL</literal>
+      value.
+    </para>
+    <para>
+      Some objects are thread-safe after they have been constructed
+      and set up. The general pattern is to
+      <function>create()</function> the object, make a few
+      <function>set_*()</function> calls to set up the
+      object, and then use it without further modification.
+    </para>
+    <para>
+      To ensure that such an object is not modified, client programs
+      can explicitly mark an object as immutable. HarfBuzz provides
+      <function>make_immutable()</function> methods to mark an object
+      as immutable and <function>is_immutable()</function> methods to
+      test whether or not an object is immutable. Attempts to use
+      setter functions on immutable objects will fail silently; see the API
+      Reference manual for specifics.
+    </para>
+    <para>
+      Note also that there are no "make mutable" methods. If client
+      programs need to alter an object previously marked as immutable,
+      they will need to make a duplicate of the original.
+    </para>
+    <para>
+      Finally, object constructors (and, indeed, as much of the
+      shaping API as possible) will never return
+      <literal>NULL</literal>.  Instead, if there is an allocation
+      error, each constructor will return an “empty” object
+      singleton.
+    </para>
+    <para>
+      These empty-object singletons are inert and safe (although
+      typically useless) to pass around.  This design choice avoids
+      having to check for <literal>NULL</literal> pointers all
+      throughout the code.
+    </para>
+    <para>
+      In addition, this “empty” object singleton can also be accessed
+      using the <function>get_empty()</function> method of the object
+      type in question.
+    </para>
+  </section>
+
+
+  <section id="object-model-user-data">
+    <title>User data</title>
+    <para>
+      To better integrate with client programs, HarfBuzz's objects
+      offer a "user data" mechanism that can be used to attach
+      arbitrary data to the object.  User-data attachment can be
+      useful for tying the lifecycles of various pieces of data
+      together, or for creating language bindings.
+    </para>
+    <para>
+      Each object type has a <function>set_user_data()</function>
+      method and a <function>get_user_data()</function> method. The
+      <function>set_user_data()</function> methods take a client-provided
+      <literal>key</literal> and a pointer,
+      <literal>user_data</literal>, pointing to the data itself. Once
+      the key-data pair has been attached to the object, the
+      <function>get_user_data()</function> method can be called with
+      the key, returning the <function>user_data</function> pointer.
+    </para>
+    <para>
+      The <function>set_user_data()</function> methods also support an
+      optional <function>destroy</function> callback. Client programs
+      can set the <function>destroy</function> callback and receive
+      notification from HarfBuzz whenever the object is destructed.
+    </para>
+    <para>
+      Finally, each <function>set_user_data()</function> method allows
+      the client program to set a <literal>replace</literal> Boolean
+      indicating whether or not the function call should replace any
+      existing <literal>user_data</literal>
+      associated with the specified key.
+    </para>
+  </section>
+
+
+
+  <section id="object-model-blobs">
+    <title>Blobs</title>
+    <para>
+      While most of HarfBuzz's object types are specific to the
+      shaping process, <emphasis>blobs</emphasis> are somewhat
+      different.
+    </para>
+    <para>
+      Blobs are an abstraction designed to negotiate lifecycle and
+      permissions for raw pieces of data.  For example, when you load
+      the raw font data into memory and want to pass it to HarfBuzz,
+      you do so in a <literal>hb_blob_t</literal> wrapper.
+    </para>
+    <para>
+      This allows you to take advantage of HarfBuzz's
+      reference-counting and <function>destroy</function>
+      callbacks. If you allocated the memory for the data using
+      <function>malloc()</function>, you would create the blob using
+    </para>
+    <programlisting language="C">
+      hb_blob_create (data, length, HB_MEMORY_MODE_WRITABLE, data, free)
+    </programlisting>
+    <para>
+      That way, HarfBuzz will call <function>free()</function> on the
+      allocated memory whenever the blob drops its last reference and
+      is deconstructed.  Consequently, the user code can stop worrying
+      about freeing memory and let the reference-counting machinery
+      take care of that.
+    </para>
+    <para>
+      Most of the time, blobs are read-only, facilitating their use in
+      immutable objects.
+    </para>
+  </section>
+
+</chapter>

+ 336 - 0
hbfreetypefont.mod/harfbuzz/docs/usermanual-opentype-features.xml

@@ -0,0 +1,336 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="shaping-and-shape-plans">
+  <title>Shaping and shape plans</title>
+  <para>
+    Once you have your face and font objects configured as desired and
+    your input buffer is filled with the characters you need to shape,
+    all you need to do is call <function>hb_shape()</function>.
+  </para>
+  <para>
+    HarfBuzz will return the shaped version of the text in the same
+    buffer that you provided, but it will be in output mode. At that
+    point, you can iterate through the glyphs in the buffer, drawing
+    each one at the specified position or handing them off to the
+    appropriate graphics library.
+  </para>
+  <para>
+    For the most part, HarfBuzz's shaping step is straightforward from
+    the outside. But that doesn't mean there will never be cases where
+    you want to look under the hood and see what is happening on the
+    inside. HarfBuzz provides facilities for doing that, too.
+  </para>
+  
+  <section id="shaping-buffer-output">
+    <title>Shaping and buffer output</title>
+    <para>
+      The <function>hb_shape()</function> function call takes four arguments: the font
+      object to use, the buffer of characters to shape, an array of
+      user-specified features to apply, and the length of that feature
+      array. The feature array can be NULL, so for the sake of
+      simplicity we will start with that case.
+    </para>
+    <para>
+      Internally, HarfBuzz looks  at the tables of the font file to
+      determine where glyph classes, substitutions, and positioning
+      are defined, using that information to decide which
+      <emphasis>shaper</emphasis> to use (<literal>ot</literal> for
+      OpenType fonts, <literal>aat</literal> for Apple Advanced
+      Typography fonts, and so on). It also looks at the direction,
+      script, and language properties of the segment to figure out
+      which script-specific shaping model is needed (at least, in
+      shapers that support multiple options).      
+    </para>
+    <para>
+      If a font has a GDEF table, then that is used for
+      glyph classes; if not, HarfBuzz will fall back to Unicode
+      categorization by code point. If a font has an AAT <literal>morx</literal> table,
+      then it is used for substitutions; if not, but there is a GSUB
+      table, then the GSUB table is used. If the font has an AAT
+      <literal>kerx</literal> table, then it is used for positioning; if not, but
+      there is a GPOS table, then the GPOS table is used. If neither
+      table is found, but there is a <literal>kern</literal> table, then HarfBuzz will
+      use the <literal>kern</literal> table. If there is no <literal>kerx</literal>, no GPOS, and no
+      <literal>kern</literal>, HarfBuzz will fall back to positioning marks itself.
+    </para>
+    <para>
+      With a well-behaved OpenType font, you expect GDEF, GSUB, and
+      GPOS tables to all be applied. HarfBuzz implements the
+      script-specific shaping models in internal functions, rather
+      than in the public API.
+    </para>
+    <para>
+      The algorithms
+      used for shaping can be quite involved; HarfBuzz tries
+      to be compatible with the OpenType Layout specification
+      and, wherever there is any ambiguity, HarfBuzz attempts to replicate the
+      output of Microsoft's Uniscribe engine, to the extent that is feasible and desirable. See the <ulink
+      url="https://docs.microsoft.com/en-us/typography/script-development/standard">Microsoft
+      Typography pages</ulink> for more detail.
+    </para>
+    <para>
+      In general, though, all that you need to know is that
+      <function>hb_shape()</function> returns the results of shaping
+      in the same buffer that you provided. The buffer's content type
+      will now be set to
+      <literal>HB_BUFFER_CONTENT_TYPE_GLYPHS</literal>, indicating
+      that it contains shaped output, rather than input text. You can
+      now extract the glyph information and positioning arrays:
+    </para>
+    <programlisting language="C">
+      hb_glyph_info_t *glyph_info    = hb_buffer_get_glyph_infos(buf, &amp;glyph_count);
+      hb_glyph_position_t *glyph_pos = hb_buffer_get_glyph_positions(buf, &amp;glyph_count);
+    </programlisting>
+    <para>
+      The glyph information array holds a <type>hb_glyph_info_t</type>
+      for each output glyph, which has two fields:
+      <parameter>codepoint</parameter> and
+      <parameter>cluster</parameter>. Whereas, in the input buffer,
+      the <parameter>codepoint</parameter> field contained the Unicode
+      code point, it now contains the glyph ID of the corresponding
+      glyph in the font. The <parameter>cluster</parameter> field is
+      an integer that you can use to help identify when shaping has
+      reordered, split, or combined code points; we will say more
+      about that in the next chapter.
+    </para>
+    <para>
+      The glyph positions array holds a corresponding
+      <type>hb_glyph_position_t</type> for each output glyph,
+      containing four fields: <parameter>x_advance</parameter>,
+      <parameter>y_advance</parameter>,
+      <parameter>x_offset</parameter>, and
+      <parameter>y_offset</parameter>. The advances tell you how far
+      you need to move the drawing point after drawing this glyph,
+      depending on whether you are setting horizontal text (in which
+      case you will have x advances) or vertical text (for which you
+      will have y advances). The x and y offsets tell you where to
+      move to start drawing the glyph; usually you will have both and
+      x and a y offset, regardless of the text direction.
+    </para>
+    <para>
+      Most of the time, you will rely on a font-rendering library or
+      other graphics library to do the actual drawing of glyphs, so
+      you will need to iterate through the glyphs in the buffer and
+      pass the corresponding values off.
+    </para>
+  </section>
+  
+  <section id="shaping-opentype-features">
+    <title>OpenType features</title>
+    <para>
+      OpenType features enable fonts to include smart behavior,
+      implemented as "lookup" rules stored in the GSUB and GPOS
+      tables. The OpenType specification defines a long list of
+      standard features that fonts can use for these behaviors; each
+      feature has a four-character reserved name and a well-defined
+      semantic meaning.
+    </para>
+    <para>
+      Some OpenType features are defined for the purpose of supporting
+      script-specific shaping, and are automatically activated, but
+      only when a buffer's script property is set to a script that the
+      feature supports.
+    </para>
+    <para>
+      Other features are more generic and can apply to several (or
+      any) script, and shaping engines are expected to implement
+      them. By default, HarfBuzz activates several of these features
+      on every text run. They include <literal>abvm</literal>,
+      <literal>blwm</literal>, <literal>ccmp</literal>,
+      <literal>locl</literal>, <literal>mark</literal>,
+      <literal>mkmk</literal>, and <literal>rlig</literal>.
+    </para>
+    <para>
+      In addition, if the text direction is horizontal, HarfBuzz
+      also applies the <literal>calt</literal>,
+      <literal>clig</literal>, <literal>curs</literal>,
+      <literal>dist</literal>, <literal>kern</literal>,
+      <literal>liga</literal> and <literal>rclt</literal>, features.
+    </para>
+    <para>
+      Additionally, when HarfBuzz encounters a fraction slash
+      (<literal>U+2044</literal>), it looks backward and forward for decimal
+      digits (Unicode General Category = Nd), and enables features
+      <literal>numr</literal> on the sequence before the fraction slash,
+      <literal>dnom</literal> on the sequence after the fraction slash,
+      and <literal>frac</literal> on the whole sequence including the fraction
+      slash.
+    </para>
+    <para>
+      Some script-specific shaping models
+      (see <xref linkend="opentype-shaping-models" />) disable some of the
+      features listed above:
+    </para>
+    <itemizedlist>
+      <listitem>
+        <para>
+          Hangul: <literal>calt</literal>
+	</para>
+      </listitem>
+      <listitem>
+        <para>
+          Indic: <literal>liga</literal>
+	</para>
+      </listitem>
+      <listitem>
+        <para>
+          Khmer: <literal>liga</literal>
+	</para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      If the text direction is vertical, HarfBuzz applies
+      the <literal>vert</literal> feature by default.
+    </para>
+    <para>
+      Still other features are designed to be purely optional and left
+      up to the application or the end user to enable or disable as desired.
+    </para>
+    <para>
+      You can adjust the set of features that HarfBuzz applies to a
+      buffer by supplying an array of <type>hb_feature_t</type>
+      features as the third argument to
+      <function>hb_shape()</function>. For a simple case, let's just
+      enable the <literal>dlig</literal> feature, which turns on any
+      "discretionary" ligatures in the font:
+    </para>
+    <programlisting language="C">
+      hb_feature_t userfeatures[1];
+      userfeatures[0].tag = HB_TAG('d','l','i','g');
+      userfeatures[0].value = 1;
+      userfeatures[0].start = HB_FEATURE_GLOBAL_START;
+      userfeatures[0].end = HB_FEATURE_GLOBAL_END;
+    </programlisting>
+    <para>
+      <literal>HB_FEATURE_GLOBAL_END</literal> and
+      <literal>HB_FEATURE_GLOBAL_END</literal> are macros we can use
+      to indicate that the features will be applied to the entire
+      buffer. We could also have used a literal <literal>0</literal>
+      for the start and a <literal>-1</literal> to indicate the end of
+      the buffer (or have selected other start and end positions, if needed).
+    </para>
+    <para>
+      When we pass the <varname>userfeatures</varname> array to
+      <function>hb_shape()</function>, any discretionary ligature
+      substitutions from our font that match the text in our buffer
+      will get performed:
+    </para>
+    <programlisting language="C">
+      hb_shape(font, buf, userfeatures, num_features);
+    </programlisting>
+    <para>
+      Just like we enabled the <literal>dlig</literal> feature by
+      setting its <parameter>value</parameter> to
+      <literal>1</literal>, you would disable a feature by setting its
+      <parameter>value</parameter> to <literal>0</literal>. Some
+      features can take other <parameter>value</parameter> settings;
+      be sure you read the full specification of each feature tag to
+      understand what it does and how to control it.
+    </para>
+  </section>
+
+  <section id="shaping-shaper-selection">
+    <title>Shaper selection</title>
+    <para>
+      The basic version of <function>hb_shape()</function> determines
+      its shaping strategy based on examining the capabilities of the
+      font file. OpenType font tables cause HarfBuzz to try the
+      <literal>ot</literal> shaper, while AAT font tables cause HarfBuzz to try the
+      <literal>aat</literal> shaper. 
+    </para>
+    <para>
+      In the real world, however, a font might include some unusual
+      mix of tables, or one of the tables might simply be broken for
+      the script you need to shape. So, sometimes, you might not
+      want to rely on HarfBuzz's process for deciding what to do, and
+      just tell <function>hb_shape()</function> what you want it to try.
+    </para>
+    <para>
+      <function>hb_shape_full()</function> is an alternate shaping
+      function that lets you supply a list of shapers for HarfBuzz to
+      try, in order, when shaping your buffer. For example, if you
+      have determined that HarfBuzz's attempts to work around broken
+      tables gives you better results than the AAT shaper itself does,
+      you might move the AAT shaper to the end of your list of
+      preferences and call <function>hb_shape_full()</function>
+    </para>
+    <programlisting language="C">
+      char *shaperprefs[3] = {"ot", "default", "aat"};
+      ...
+      hb_shape_full(font, buf, userfeatures, num_features, shaperprefs);
+    </programlisting>
+    <para>
+      to get results you are happier with.
+    </para>
+    <para>
+      You may also want to call
+      <function>hb_shape_list_shapers()</function> to get a list of
+      the shapers that were built at compile time in your copy of HarfBuzz.
+    </para>
+  </section>
+  
+  <section id="shaping-plans-and-caching">
+    <title>Plans and caching</title>
+    <para>
+      Internally, HarfBuzz uses a structure called a shape plan to
+      track its decisions about how to shape the contents of a
+      buffer. The <function>hb_shape()</function> function builds up the shape plan by
+      examining segment properties and by inspecting the contents of
+      the font.
+    </para>
+    <para>
+      This process can involve some decision-making and
+      trade-offs — for example, HarfBuzz inspects the GSUB and GPOS
+      lookups for the script and language tags set on the segment
+      properties, but it falls back on the lookups under the
+      <literal>DFLT</literal> tag (and sometimes other common tags)
+      if there are actually no lookups for the tag requested.
+    </para>
+    <para>
+      HarfBuzz also includes some work-arounds for
+      handling well-known older font conventions that do not follow
+      OpenType or Unicode specifications, for buggy system fonts, and for
+      peculiarities of Microsoft Uniscribe. All of that means that a
+      shape plan, while not something that you should edit directly in
+      client code, still might be an object that you want to
+      inspect. Furthermore, if resources are tight, you might want to
+      cache the shape plan that HarfBuzz builds for your buffer and
+      font, so that you do not have to rebuild it for every shaping call.
+    </para>
+    <para>
+      You can create a cacheable shape plan with
+      <function>hb_shape_plan_create_cached(face, props,
+      user_features, num_user_features, shaper_list)</function>, where
+      <parameter>face</parameter> is a face object (not a font object,
+      notably), <parameter>props</parameter> is an
+      <type>hb_segment_properties_t</type>,
+      <parameter>user_features</parameter> is an array of
+      <type>hb_feature_t</type>s (with length
+      <parameter>num_user_features</parameter>), and
+      <parameter>shaper_list</parameter> is a list of shapers to try.
+    </para>
+    <para>
+      Shape plans are objects in HarfBuzz, so there are
+      reference-counting functions and user-data attachment functions
+      you can
+      use. <function>hb_shape_plan_reference(shape_plan)</function>
+      increases the reference count on a shape plan, while
+      <function>hb_shape_plan_destroy(shape_plan)</function> decreases
+      the reference count, destroying the shape plan when the last
+      reference is dropped.
+    </para>
+    <para>
+      You can attach user data to a shaper (with a key) using the
+      <function>hb_shape_plan_set_user_data(shape_plan,key,data,destroy,replace)</function>
+      function, optionally supplying a <function>destroy</function>
+      callback to use. You can then fetch the user data attached to a
+      shape plan with
+      <function>hb_shape_plan_get_user_data(shape_plan, key)</function>.
+    </para>
+  </section>
+  
+</chapter>

+ 368 - 0
hbfreetypefont.mod/harfbuzz/docs/usermanual-shaping-concepts.xml

@@ -0,0 +1,368 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="shaping-concepts">
+  <title>Shaping concepts</title>
+  <section id="text-shaping-concepts">
+    <title>Text shaping</title>
+    <para>
+      Text shaping is the process of transforming a sequence of Unicode
+      codepoints that represent individual characters (letters,
+      diacritics, tone marks, numbers, symbols, etc.) into the
+      orthographically and linguistically correct two-dimensional layout
+      of glyph shapes taken from a specified font.
+    </para>
+    <para>
+      For some writing systems (or <emphasis>scripts</emphasis>) and
+      languages, the process is simple, requiring the shaper to do
+      little more than advance the horizontal position forward by the
+      correct amount for each successive glyph.
+    </para>
+    <para>
+      But, for other scripts (often unceremoniously called <emphasis>complex scripts</emphasis>), any combination of
+      several shaping operations may be required, and the rules for how
+      and when they are applied vary from script to script. HarfBuzz and
+      other shaping engines implement these rules.
+    </para>
+    <para>
+      The exact rules and necessary operations for a particular script
+      constitute a shaping <emphasis>model</emphasis>. OpenType
+      specifies a set of shaping models that covers all of
+      Unicode. Other shaping models are available, however, including
+      Graphite and Apple Advanced Typography (AAT). 
+    </para>
+  </section>
+  
+  <section id="script-specific-shaping">
+    <title>Script-specific shaping</title>
+    <para>
+      In many scripts, transforming the input
+      sequence into the final layout often requires some combination of
+      operations&mdash;such as context-dependent substitutions,
+      context-dependent mark positioning, glyph-to-glyph joining,
+      glyph reordering, or glyph stacking.
+    </para>
+    <para>
+      In some scripts, the shaping rules require that a text
+      run be divided into syllables before the operations can be
+      applied. Other scripts may apply shaping operations over
+      entire words or over the entire text run, with no subdivision
+      required.
+    </para>
+    <para>
+      Other scripts, do not require these
+      operations. However, correctly shaping a text run in
+      any script may still involve Unicode normalization,
+      ligature substitutions, mark positioning, kerning, and applying
+      other font features.
+    </para>
+  </section>
+  
+  <section id="shaping-operations">
+    <title>Shaping operations</title>
+    <para>
+      Shaping a text run involves transforming the
+      input sequence of Unicode codepoints with some combination of
+      operations that is specified in the shaping model for the
+      script.
+    </para>
+    <para>
+      The specific conditions that trigger a given operation for a
+      text run varies from script to script, as do the order that the
+      operations are performed in and which codepoints are
+      affected. However, the same general set of shaping operations is
+      common to all of the script shaping models. 
+    </para>
+    
+    <itemizedlist>
+      <listitem>
+	<para>
+	  A <emphasis>reordering</emphasis> operation moves a glyph
+	  from its original ("logical") position in the sequence to
+	  some other ("visual") position.
+	</para>
+	<para>
+	  The shaping model for a given script might involve
+	  more than one reordering step.
+	</para>
+      </listitem>
+      
+      <listitem>
+	<para>
+	  A <emphasis>joining</emphasis> operation replaces a glyph
+	  with an alternate form that is designed to connect with one
+	  or more of the adjacent glyphs in the sequence.
+	</para>
+      </listitem>
+      
+      <listitem>
+	<para>
+	  A contextual <emphasis>substitution</emphasis> operation
+	  replaces either a single glyph or a subsequence of several
+	  glyphs with an alternate glyph. This substitution is
+	  performed when the original glyph or subsequence of glyphs
+	  occurs in a specified position with respect to the
+	  surrounding sequence. For example, one substitution might be
+	  performed only when the target glyph is the first glyph in
+	  the sequence, while another substitution is performed only
+	  when a different target glyph occurs immediately after a
+	  particular string pattern.
+	</para>
+	<para>
+	  The shaping model for a given script might involve
+	  multiple contextual-substitution operations, each applying
+	  to different target glyphs and patterns, and which are
+	  performed in separate steps.
+	</para>
+      </listitem>
+      
+      <listitem>
+	<para>
+	  A contextual <emphasis>positioning</emphasis> operation
+	  moves the horizontal and/or vertical position of a
+	  glyph. This positioning move is performed when the glyph
+	  occurs in a specified position with respect to the
+	  surrounding sequence.
+	</para>
+	<para>
+	  Many contextual positioning operations are used to place
+	  <emphasis>mark</emphasis> glyphs (such as diacritics, vowel
+	  signs, and tone markers) with respect to
+	  <emphasis>base</emphasis> glyphs. However, some
+	  scripts may use contextual positioning operations to
+	  correctly place base glyphs as well, such as
+	  when the script uses <emphasis>stacking</emphasis> characters.
+	</para>
+      </listitem>
+      
+    </itemizedlist>
+  </section>
+  
+  <section id="unicode-character-categories">
+    <title>Unicode character categories</title>
+    <para>
+      Shaping models are typically specified with respect to how
+      scripts are defined in the Unicode standard.
+    </para>
+    <para>
+      Every codepoint in the Unicode Character Database (UCD) is
+      assigned a <emphasis>Unicode General Category</emphasis> (UGC),
+      which provides the most fundamental information about the
+      codepoint: whether the codepoint represents a
+      <emphasis>Letter</emphasis>, a <emphasis>Mark</emphasis>, a
+      <emphasis>Number</emphasis>, <emphasis>Punctuation</emphasis>, a
+      <emphasis>Symbol</emphasis>, a <emphasis>Separator</emphasis>,
+      or something else (<emphasis>Other</emphasis>).
+    </para>
+    <para>
+      These UGC properties are "Major" categories. Each codepoint is
+      further assigned to a "minor" category within its Major
+      category, such as "Letter, uppercase" (<literal>Lu</literal>) or
+      "Letter, modifier" (<literal>Lm</literal>).
+    </para>
+    <para>
+      Shaping models are concerned primarily with Letter and Mark
+      codepoints. The minor categories of Mark codepoints are
+      particularly important for shaping. Marks can be nonspacing
+      (<literal>Mn</literal>), spacing combining
+      (<literal>Mc</literal>), or enclosing (<literal>Me</literal>).
+    </para>
+    <para>
+      In addition to the UGC property, codepoints in the Indic and
+      Southeast Asian scripts are also assigned
+      <emphasis>Unicode Indic Syllabic Category</emphasis> (UISC) and
+      <emphasis>Unicode Indic Positional Category</emphasis> (UIPC)
+      properties that provide more detailed information needed for
+      shaping.
+    </para>
+    <para>
+      The UISC property sub-categorizes Letters and Marks according to
+      common script-shaping behaviors. For example, UISC distinguishes
+      between consonant letters, vowel letters, and vowel marks. The
+      UIPC property sub-categorizes Mark codepoints by the relative visual
+      position that they occupy (above, below, right, left, or in
+      multiple positions).
+    </para>
+    <para>
+      Some scripts require that the text run be split into
+      syllables. What constitutes a valid syllable in these
+      scripts is specified in regular expressions, formed from the
+      Letter and Mark codepoints, that take the UISC and UIPC
+      properties into account.
+    </para>
+
+  </section>
+  
+  <section id="text-runs">
+    <title>Text runs</title>
+    <para>
+      Real-world text usually contains codepoints from a mixture of
+      different Unicode scripts (including punctuation, numbers, symbols,
+      white-space characters, and other codepoints that do not belong
+      to any script). Real-world text may also be marked up with
+      formatting that changes font properties (including the font,
+      font style, and font size).
+    </para>
+    <para>
+      For shaping purposes, all real-world text streams must be first
+      segmented into runs that have a uniform set of properties. 
+    </para>
+    <para>
+      In particular, shaping models always assume that every codepoint
+      in a text run has the same <emphasis>direction</emphasis>,
+      <emphasis>script</emphasis> tag, and
+      <emphasis>language</emphasis> tag.
+    </para>
+  </section>
+  
+  <section id="opentype-shaping-models">
+    <title>OpenType shaping models</title>
+    <para>
+      OpenType provides shaping models for the following scripts:
+    </para>
+
+    <itemizedlist>
+      <listitem>
+	<para>
+	  The <emphasis>default</emphasis> shaping model handles all
+	  scripts with no script-specific shaping model, and may also be used as a fallback for
+	  handling unrecognized scripts.
+	</para>
+      </listitem>
+
+      <listitem>
+	<para>
+	  The <emphasis>Indic</emphasis> shaping model handles the Indic
+	  scripts Bengali, Devanagari, Gujarati, Gurmukhi, Kannada,
+	  Malayalam, Oriya, Tamil, and Telugu.
+	</para>
+	<para>
+	  The Indic shaping model was revised significantly in
+	  2005. To denote the change, a new set of <emphasis>script
+	  tags</emphasis> was assigned for Bengali, Devanagari,
+	  Gujarati, Gurmukhi, Kannada, Malayalam, Oriya, Tamil, and
+	  Telugu. For the sake of clarity, the term "Indic2" is
+	  sometimes used to refer to the current, revised shaping
+	  model.
+	</para>
+      </listitem>
+
+      <listitem>
+	<para>
+	  The <emphasis>Arabic</emphasis> shaping model supports
+	  Arabic, Mongolian, N'Ko, Syriac, and several other connected
+	  or cursive scripts.
+	</para>
+      </listitem>
+
+      <listitem>
+	<para>
+	  The <emphasis>Thai/Lao</emphasis> shaping model supports
+	  the Thai and Lao scripts.
+	</para>
+      </listitem>
+
+      <listitem>
+	<para>
+	  The <emphasis>Khmer</emphasis> shaping model supports the
+	  Khmer script.
+	</para>
+      </listitem>
+
+      <listitem>
+	<para>
+	  The <emphasis>Myanmar</emphasis> shaping model supports the
+	  Myanmar (or Burmese) script.
+	</para>
+      </listitem>
+
+      <listitem>
+	<para>
+	  The <emphasis>Tibetan</emphasis> shaping model supports the
+	  Tibetan script.
+	</para>
+      </listitem>
+
+      <listitem>
+	<para>
+	  The <emphasis>Hangul</emphasis> shaping model supports the
+	  Hangul script.
+	</para>
+      </listitem>
+
+      <listitem>
+	<para>
+	  The <emphasis>Hebrew</emphasis> shaping model supports the
+	  Hebrew script.
+	</para>
+      </listitem>
+
+      <listitem>
+	<para>
+	  The <emphasis>Universal Shaping Engine</emphasis> (USE)
+	  shaping model supports scripts not covered by one of
+	  the above, script-specific shaping models, including
+	  Javanese, Balinese, Buginese, Batak, Chakma, Lepcha, Modi,
+	  Phags-pa, Tagalog, Siddham, Sundanese, Tai Le, Tai Tham, Tai
+	  Viet, and many others. 
+	</para>
+      </listitem>
+
+      <listitem>
+	<para>
+	  Text runs that do not fall under one of the above shaping
+	  models may still require processing by a shaping engine. Of
+	  particular note is <emphasis>Emoji</emphasis> shaping, which
+	  may involve variation-selector sequences and glyph
+	  substitution. Emoji shaping is handled by the default
+	  shaping model.
+	</para>
+      </listitem>
+
+    </itemizedlist>
+    
+  </section>
+  
+  <section id="graphite-shaping">
+    <title>Graphite shaping</title>
+    <para>
+      In contrast to OpenType shaping, Graphite shaping does not
+      specify a predefined set of shaping models or a set of supported
+      scripts.
+    </para>
+    <para>
+      Instead, each Graphite font contains a complete set of rules that
+      implement the required shaping model for the intended
+      script. These rules include finite-state machines to match
+      sequences of codepoints to the shaping operations to perform.
+    </para>
+    <para>
+      Graphite shaping can perform the same shaping operations used in
+      OpenType shaping, as well as other functions that have not been
+      defined for OpenType shaping.
+    </para>
+  </section>
+  
+  <section id="aat-shaping">
+    <title>AAT shaping</title>
+    <para>
+      In contrast to OpenType shaping, AAT shaping does not specify a 
+      predefined set of shaping models or a set of supported scripts.
+    </para>
+    <para>
+      Instead, each AAT font includes a complete set of rules that
+      implement the desired shaping model for the intended
+      script. These rules include finite-state machines to match glyph
+      sequences and the shaping operations to perform.
+    </para>
+    <para>
+      Notably, AAT shaping rules are expressed for glyphs in the font,
+      not for Unicode codepoints. AAT shaping can perform the same
+      shaping operations used in OpenType shaping, as well as other
+      functions that have not been defined for OpenType shaping.
+    </para>
+  </section>
+</chapter>

+ 218 - 0
hbfreetypefont.mod/harfbuzz/docs/usermanual-utilities.xml

@@ -0,0 +1,218 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="utilities">
+  <title>Utilities</title>
+  <para>
+    HarfBuzz includes several auxiliary components in addition to the
+    main APIs. These include a set of command-line tools, a set of
+    lower-level APIs for common data types that may be of interest to
+    client programs.
+  </para>
+  
+  <section id="utilities-command-line-tools">
+    <title>Command-line tools</title>
+    <para>
+      HarfBuzz include three command-line tools:
+      <command>hb-shape</command>, <command>hb-view</command>, and
+      <command>hb-subset</command>. They can be used to examine
+      HarfBuzz's functionality, debug font binaries, or explore the
+      various shaping models and features from a terminal.
+    </para>
+    
+    <section id="utilities-command-line-hbshape">
+      <title>hb-shape</title>
+      <para>
+	<emphasis><command>hb-shape</command></emphasis> allows you to run HarfBuzz's
+	<function>hb_shape()</function> function on an input string and
+	to examine the outcome, in human-readable form, as terminal
+	output. <command>hb-shape</command> does
+	<emphasis>not</emphasis> render the results of the shaping call
+	into rendered text (you can use <command>hb-view</command>, below, for
+	that). Instead, it prints out the final glyph indices and
+	positions, taking all shaping operations into account, as if the
+	input string were a HarfBuzz input buffer.
+      </para>
+      <para>
+	You can specify the font to be used for shaping and, with
+	command-line options, you can add various aspects of the
+	internal state to the output that is sent to the terminal. The
+	general format is
+      </para>
+      <programlisting>
+	<command>hb-shape</command> <optional>[OPTIONS]</optional>
+      <parameter>path/to/font/file.ttf</parameter>
+      <parameter>yourinputtext</parameter>
+      </programlisting>
+      <para>
+	The default output format is plain text (although JSON output
+	can be selected instead by specifying the option
+	<optional>--output-format=json</optional>). The default output
+	syntax reports each glyph name (or glyph index if there is no
+	name) followed by its cluster value, its horizontal and vertical
+	position displacement, and its horizontal and vertical advances.
+      </para>
+      <para>
+	Output options exist to skip any of these elements in the
+	output, and to include additional data, such as Unicode
+	code-point values, glyph extents, glyph flags, or interim
+	shaping results.
+      </para>
+      <para>
+	Output can also be redirected to a file, or input read from a
+	file. Additional options enable you to enable or disable
+	specific font features, to set variation-font axis values, to
+	alter the language, script, direction, and clustering settings
+	used, to enable sanity checks, or to change which shaping engine is used.
+      </para>
+      <para>
+	For a complete explanation of the options available, run
+      </para>
+      <programlisting>
+	<command>hb-shape</command> <parameter>--help</parameter>
+      </programlisting>  
+    </section>
+    
+    <section id="utilities-command-line-hbview">
+      <title>hb-view</title>
+      <para>
+	<emphasis><command>hb-view</command></emphasis> allows you to
+	see the shaped output of an input string in rendered
+	form. Like <command>hb-shape</command>,
+	<command>hb-view</command> takes a font file and a text string
+	as its arguments:
+      </para>
+      <programlisting>
+	<command>hb-view</command> <optional>[OPTIONS]</optional>
+	<parameter>path/to/font/file.ttf</parameter>
+	<parameter>yourinputtext</parameter>
+      </programlisting>
+      <para>
+	By default, <command>hb-view</command> renders the shaped
+	text in ASCII block-character images as terminal output. By
+	appending the
+	<command>--output-file=<optional>filename</optional></command>
+	switch, you can write the output to a PNG, SVG, or PDF file
+	(among other formats).
+      </para>
+      <para>
+	As with <command>hb-shape</command>, a lengthy set of options
+	is available, with which you can  enable or disable
+	specific font features, set variation-font axis values,
+	alter the language, script, direction, and clustering settings
+	used, enable sanity checks, or change which shaping engine is
+	used.
+      </para>
+      <para>
+	You can also set the foreground and background colors used for
+	the output, independently control the width of all four
+	margins, alter the line spacing, and annotate the output image
+	with 
+      </para>
+      <para>
+	In general, <command>hb-view</command> is a quick way to
+	verify that the output of HarfBuzz's shaping operation looks
+	correct for a given text-and-font combination, but you may
+	want to use <command>hb-shape</command> to figure out exactly
+	why something does not appear as expected.
+      </para>
+    </section>
+    
+    <section id="utilities-command-line-hbsubset">
+      <title>hb-subset</title>
+      <para>
+	<emphasis><command>hb-subset</command></emphasis> allows you
+	to generate a subset of a given font, with a limited set of
+	supported characters, features, and variation settings.
+      </para>
+      <para>
+	By default, you provide an input font and an input text string
+	as the arguments to <command>hb-subset</command>, and it will
+	generate a font that covers the input text exactly like the
+	input font does, but includes no other characters or features.
+      </para>
+      <programlisting>
+	<command>hb-subset</command> <optional>[OPTIONS]</optional>
+	<parameter>path/to/font/file.ttf</parameter>
+	<parameter>yourinputtext</parameter>
+      </programlisting>
+      <para>
+	For example, to create a subset of Noto Serif that just includes the
+	numerals and the lowercase Latin alphabet, you could run
+      </para>
+      <programlisting>
+	<command>hb-subset</command> <optional>[OPTIONS]</optional>
+	<parameter>NotoSerif-Regular.ttf</parameter>
+	<parameter>0123456789abcdefghijklmnopqrstuvwxyz</parameter>
+      </programlisting>
+      <para>
+	There are options available to remove hinting from the
+	subsetted font and to specify a list of variation-axis settings.
+      </para>
+    </section>
+    
+  </section>
+  
+  <section id="utilities-common-types-apis">
+    <title>Common data types and APIs</title>
+    <para>
+      HarfBuzz includes several APIs for working with general-purpose
+      data that you may find convenient to leverage in your own
+      software. They include set operations and integer-to-integer
+      mapping operations.
+    </para>
+    <para>
+      HarfBuzz uses set operations for internal bookkeeping, such as
+      when it collects all of the glyph IDs covered by a particular
+      font feature. You can also use the set API to build sets, add
+      and remove elements, test whether or not sets contain particular
+      elements, or compute the unions, intersections, or differences
+      between sets.
+    </para>
+    <para>
+      All set elements are integers (specifically,
+      <type>hb_codepoint_t</type> 32-bit unsigned ints), and there are
+      functions for fetching the minimum and maximum element from a
+      set. The set API also includes some functions that might not 
+      be part of a generic set facility, such as the ability to add a
+      contiguous range of integer elements to a set in bulk, and the
+      ability to fetch the next-smallest or next-largest element.
+    </para>
+    <para>
+      The HarfBuzz set API includes some conveniences as well. All
+      sets are lifecycle-managed, just like other HarfBuzz
+      objects. You increase the reference count on a set with
+      <function>hb_set_reference()</function> and decrease it with
+      <function>hb_set_destroy()</function>. You can also attach
+      user data to a set, just like you can to blobs, buffers, faces,
+      fonts, and other objects, and set destroy callbacks.
+    </para>
+    <para>
+      HarfBuzz also provides an API for keeping track of
+      integer-to-integer mappings. As with the set API, each integer is
+      stored as an unsigned 32-bit <type>hb_codepoint_t</type>
+      element. Maps, like other objects, are reference counted with
+      reference and destroy functions, and you can attach user data to
+      them. The mapping operations include adding and deleting
+      integer-to-integer key:value pairs to the map, testing for the
+      presence of a key, fetching the population of the map, and so on.
+    </para>
+    <para>
+      There are several other internal HarfBuzz facilities that are
+      exposed publicly and which you may want to take advantage of
+      while processing text. HarfBuzz uses a common
+      <type>hb_tag_t</type> for a variety of OpenType tag identifiers (for
+      scripts, languages, font features, table names, variation-axis
+      names, and more), and provides functions for converting strings
+      to tags and vice-versa. 
+    </para>
+    <para>
+      Finally, HarfBuzz also includes data type for Booleans, bit
+      masks, and other simple types.
+    </para>
+  </section>
+
+</chapter>

+ 441 - 0
hbfreetypefont.mod/harfbuzz/docs/usermanual-what-is-harfbuzz.xml

@@ -0,0 +1,441 @@
+<?xml version="1.0"?>
+<!DOCTYPE book PUBLIC "-//OASIS//DTD DocBook XML V4.3//EN"
+               "http://www.oasis-open.org/docbook/xml/4.3/docbookx.dtd" [
+  <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
+  <!ENTITY version SYSTEM "version.xml">
+]>
+<chapter id="what-is-harfbuzz">
+  <title>What is HarfBuzz?</title>
+  <para>
+    HarfBuzz is a <emphasis>text-shaping engine</emphasis>. If you
+    give HarfBuzz a font and a string containing a sequence of Unicode
+    codepoints, HarfBuzz selects and positions the corresponding
+    glyphs from the font, applying all of the necessary layout rules
+    and font features. HarfBuzz then returns the string to you in the
+    form that is correctly arranged for the language and writing
+    system. 
+  </para>
+  <para>
+    HarfBuzz can properly shape all of the world's major writing
+    systems. It runs on all major operating systems and software
+    platforms and it supports the major font formats in use
+    today.
+  </para>
+  <section id="what-is-text-shaping">
+    <title>What is text shaping?</title>
+    <para>
+      Text shaping is the process of translating a string of character
+      codes (such as Unicode codepoints) into a properly arranged
+      sequence of glyphs that can be rendered onto a screen or into
+      final output form for inclusion in a document.
+    </para>
+    <para>
+      The shaping process is dependent on the input string, the active
+      font, the script (or writing system) that the string is in, and
+      the language that the string is in.
+    </para>
+    <para>
+      Modern software systems generally only deal with strings in the
+      Unicode encoding scheme (although legacy systems and documents may
+      involve other encodings).
+    </para>
+    <para>
+      There are several font formats that a program might
+      encounter, each of which has a set of standard text-shaping
+      rules.
+    </para>
+    <para>The dominant format is <ulink
+      url="http://www.microsoft.com/typography/otspec/">OpenType</ulink>. The
+    OpenType specification defines a series of <ulink url="https://github.com/n8willis/opentype-shaping-documents">shaping models</ulink> for
+    various scripts from around the world. These shaping models depend on
+    the font incorporating certain features as
+    <emphasis>lookups</emphasis> in its <literal>GSUB</literal> 
+    and <literal>GPOS</literal> tables.
+    </para>
+    <para>
+      Alternatively, OpenType fonts can include shaping features for
+      the <ulink url="https://graphite.sil.org/">Graphite</ulink> shaping model.
+    </para>
+    <para>
+      TrueType fonts can also include OpenType shaping
+      features. Alternatively, TrueType fonts can also include <ulink url="https://developer.apple.com/fonts/TrueType-Reference-Manual/RM09/AppendixF.html">Apple
+      Advanced Typography</ulink> (AAT) tables to implement shaping
+      support. AAT fonts are generally only found on macOS and iOS systems.
+    </para>
+    <para>
+      Text strings will usually be tagged with a script and language
+      tag that provide the context needed to perform text shaping
+      correctly.  The necessary <ulink
+      url="https://docs.microsoft.com/en-us/typography/opentype/spec/scripttags">script</ulink> 
+      and <ulink
+      url="https://docs.microsoft.com/en-us/typography/opentype/spec/languagetags">language</ulink>
+      tags are defined by OpenType.
+    </para>
+  </section>
+  
+  <section id="why-do-i-need-a-shaping-engine">
+    <title>Why do I need a shaping engine?</title>
+    <para>
+      Text shaping is an integral part of preparing text for
+      display. Before a Unicode sequence can be rendered, the
+      codepoints in the sequence must be mapped to the corresponding
+      glyphs provided in the font, and those glyphs must be positioned
+      correctly relative to each other. For many of the scripts
+      supported in Unicode, these steps involve script-specific layout
+      rules, including complex joining, reordering, and positioning
+      behavior. Implementing these rules is the job of the shaping engine.
+    </para>
+    <para>
+      Text shaping is a fairly low-level operation. HarfBuzz is
+      used directly by text-handling libraries like <ulink
+      url="https://www.pango.org/">Pango</ulink>, as well as by the layout
+      engines in Firefox, LibreOffice, and Chromium. Unless you are
+      <emphasis>writing</emphasis> one of these layout engines
+      yourself, you will probably not need to use HarfBuzz: normally,
+      a layout engine, toolkit, or other library will turn text into
+      glyphs for you.
+    </para>
+    <para>
+      However, if you <emphasis>are</emphasis> writing a layout engine
+      or graphics library yourself, then you will need to perform text
+      shaping, and this is where HarfBuzz can help you.
+    </para>
+    <para>
+      Here are some specific scenarios where a text-shaping engine
+      like HarfBuzz helps you:
+    </para>
+    <itemizedlist>
+      <listitem>
+        <para>
+          OpenType fonts contain a set of glyphs (that is, shapes
+	  to represent the letters, numbers, punctuation marks, and
+	  all other symbols), which are indexed by a <literal>glyph ID</literal>.
+	</para>
+	<para>
+          A particular glyph ID within the font does not necessarily
+	  correlate to a predictable Unicode codepoint. For instance,
+	  some fonts have the letter &quot;a&quot; as glyph ID 1, but
+	  many others do not. In order to retrieve the right glyph
+	  from the font to display &quot;a&quot;, you need to consult
+	  the table inside the font (the <literal>cmap</literal>
+	  table) that maps Unicode codepoints to glyph IDs. In other
+	  words, <emphasis>text shaping turns codepoints into glyph
+	  IDs</emphasis>.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          Many OpenType fonts contain ligatures: combinations of
+          characters that are rendered as a single unit. For instance,
+	  it is common for the &quot;f, i&quot; letter
+	  sequence to appear in print as the single ligature glyph
+	  &quot;fi&quot;.
+	</para>
+	<para>
+	  Whether you should render an &quot;f, i&quot; sequence
+	  as <literal>fi</literal> or as &quot;fi&quot; does not
+          depend on the input text. Instead, it depends on the whether
+	  or not the font includes an &quot;fi&quot; glyph and on the
+	  level of ligature application you wish to perform. The font
+	  and the amount of ligature application used are under your
+	  control. In other words, <emphasis>text shaping involves
+	  querying the font's ligature tables and determining what
+	  substitutions should be made</emphasis>. 
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          While ligatures like &quot;fi&quot; are optional typographic
+          refinements, some languages <emphasis>require</emphasis> certain
+          substitutions to be made in order to display text correctly.
+        </para>
+	<para>
+	  For example, in Tamil, when the letter &quot;TTA&quot; (ட)
+	  letter is followed by the vowel sign &quot;U&quot; (ு), the pair
+	  must be replaced by the single glyph &quot;டு&quot;. The
+	  sequence of Unicode characters &quot;ட,ு&quot; needs to be
+	  substituted with a single &quot;டு&quot; glyph from the
+	  font.
+	</para>
+	<para>
+	  But &quot;டு&quot; does not have a Unicode codepoint. To
+	  find this glyph, you need to consult the table inside 
+	  the font (the <literal>GSUB</literal> table) that contains
+	  substitution information. In other words, <emphasis>text shaping 
+	  chooses the correct glyph for a sequence of characters
+	  provided</emphasis>.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          Similarly, each Arabic character has four different variants
+	  corresponding to the different positions it might appear in
+	  within a sequence. Inside a font, there will be separate
+	  glyphs for the initial, medial, final, and isolated forms of
+	  each letter, each at a different glyph ID.
+	</para>
+	<para>
+	  Unicode only assigns one codepoint per character, so a
+	  Unicode string will not tell you which glyph variant to use
+	  for each character. To decide, you need to analyze the whole
+	  string and determine the appropriate glyph for each character
+	  based on its position. In other words, <emphasis>text
+	  shaping chooses the correct form of the letter by its
+	  position and returns the correct glyph from the font</emphasis>.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          Other languages involve marks and accents that need to be
+          rendered in specific positions relative a base character. For
+          instance, the Moldovan language includes the Cyrillic letter
+          &quot;zhe&quot; (ж) with a breve accent, like so: &quot;ӂ&quot;.
+	</para>
+	<para>
+	  Some fonts will provide this character as a single
+	  zhe-with-breve glyph, but other fonts will not and, instead,
+	  will expect the rendering engine to form the character by 
+          superimposing the separate &quot;ж&quot; and &quot;˘&quot;
+	  glyphs.
+	</para>
+	<para>
+	  But exactly where you should draw the breve depends on the
+	  height and width of the preceding zhe glyph. To find the
+	  right position, you need to consult the table inside
+	  the font (the <literal>GPOS</literal> table) that contains
+	  positioning information.
+          In other words, <emphasis>text shaping tells you whether you
+	  have a precomposed glyph within your font or if you need to
+	  compose a glyph yourself out of combining marks&mdash;and,
+	  if so, where to position those marks.</emphasis>
+        </para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      If tasks like these are something that you need to do, then you
+      need a text shaping engine. You could use Uniscribe if you are
+      writing Windows software; you could use CoreText on macOS; or
+      you could use HarfBuzz.
+    </para>
+    <note>
+      <para>
+	In the rest of this manual, the text will assume that the reader
+	is that implementor of a text-layout engine.
+      </para>
+    </note>
+  </section>
+  
+
+  <section id="what-does-harfbuzz-do">
+    <title>What does HarfBuzz do?</title>
+    <para>
+      HarfBuzz provides text shaping through a cross-platform
+      C API that accepts sequences of Unicode codepoints as input. Currently,
+      the following OpenType shaping models are supported:
+    </para>
+    <itemizedlist>
+      <listitem>
+	<para>
+	  Indic (covering Devanagari, Bengali, Gujarati,
+	  Gurmukhi, Kannada, Malayalam, Oriya, Tamil, and Telugu)
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Arabic (covering Arabic, N'Ko, Syriac, and Mongolian)
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Thai and Lao
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Khmer
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Myanmar
+	</para>
+      </listitem>
+      
+      <listitem>
+	<para>
+	  Tibetan
+	</para>
+      </listitem>
+      
+      <listitem>
+	<para>
+	  Hangul
+	</para>
+      </listitem>
+      
+      <listitem>
+	<para>
+	  Hebrew
+	</para>
+      </listitem>      
+      <listitem>
+	<para>
+	  The Universal Shaping Engine or <emphasis>USE</emphasis>
+	  (covering complex scripts not covered by the above shaping
+	  models)
+	</para>
+      </listitem>      
+      <listitem>
+	<para>
+	  A default shaping model for non-complex scripts
+	  (covering Latin, Cyrillic, Greek, Armenian, Georgian, Tifinagh,
+	  and many others)
+	</para>
+      </listitem>
+      <listitem>
+	<para>
+	  Emoji (including emoji modifier sequences, flag sequences,
+	  and ZWJ sequences)
+	</para>
+      </listitem>
+    </itemizedlist>
+
+    <para>
+      In addition to OpenType shaping, HarfBuzz supports the latest
+      version of Graphite shaping (the "Graphite 2" model) and AAT
+      shaping.
+    </para>
+    
+    <para>
+      HarfBuzz can read and understand TrueType fonts (.ttf), TrueType
+      collections (.ttc), and OpenType fonts (.otf, including those
+      fonts that contain TrueType-style outlines and those that
+      contain PostScript CFF or CFF2 outlines).
+    </para>
+
+    <para>
+      HarfBuzz is designed and tested to run on top of the FreeType
+      font renderer. It can run on Linux, Android, Windows, macOS, and
+      iOS systems.
+    </para>
+    
+    <para>
+      In addition to its core shaping functionality, HarfBuzz provides
+      functions for accessing other font features, including optional
+      GSUB and GPOS OpenType features, as well as
+      all color-font formats (<literal>CBDT</literal>,
+      <literal>sbix</literal>, <literal>COLR/CPAL</literal>, and
+      <literal>SVG-OT</literal>) and OpenType variable fonts. HarfBuzz
+      also includes a font-subsetting feature. HarfBuzz can perform
+      some low-level math-shaping operations, although it does not
+      currently perform full shaping for mathematical typesetting.
+    </para>
+    
+    <para>
+      A suite of command-line utilities is also provided in the
+      source-code tree, designed to help users test and debug
+      HarfBuzz's features on real-world fonts and input.
+    </para>
+  </section>
+
+  <section id="what-harfbuzz-doesnt-do">
+    <title>What HarfBuzz doesn't do</title>
+    <para>
+      HarfBuzz will take a Unicode string, shape it, and give you the
+      information required to lay it out correctly on a single
+      horizontal (or vertical) line using the font provided. That is the
+      extent of HarfBuzz's responsibility.
+    </para>
+    <para>
+      It is important to note that if you are implementing a complete
+      text-layout engine you may have other responsibilities that
+      HarfBuzz will <emphasis>not</emphasis> help you with. For example:
+    </para>
+    <itemizedlist>
+      <listitem>
+        <para>
+          HarfBuzz won't help you with bidirectionality. If you want to
+          lay out text that includes a mix of Hebrew and English, you
+	  will need to ensure that each buffer provided to HarfBuzz
+	  has all of its characters in the same order and that the
+	  directionality of the buffer is set correctly. This may mean
+	  segmenting the text before it is placed into HarfBuzz buffers. In
+          other words, the user will hit the keys in the following
+          sequence:
+        </para>
+        <programlisting>
+	  A B C [space] ג ב א [space] D E F
+        </programlisting>
+        <para>
+          but will expect to see in the output:
+        </para>
+        <programlisting>
+	  ABC אבג DEF
+        </programlisting>
+        <para>
+          This reordering is called <emphasis>bidi processing</emphasis>
+          (&quot;bidi&quot; is short for bidirectional), and there's an
+          algorithm as an annex to the Unicode Standard which tells you how
+          to process a string of mixed directionality.
+          Before sending your string to HarfBuzz, you may need to apply the
+          bidi algorithm to it. Libraries such as <ulink
+	  url="http://icu-project.org/">ICU</ulink> and <ulink
+	  url="http://fribidi.org/">fribidi</ulink> can do this for you.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          HarfBuzz won't help you with text that contains different font
+          properties. For instance, if you have the string &quot;a
+          <emphasis>huge</emphasis> breakfast&quot;, and you expect
+          &quot;huge&quot; to be italic, then you will need to send three
+          strings to HarfBuzz: <literal>a</literal>, in your Roman font;
+          <literal>huge</literal> using your italic font; and
+          <literal>breakfast</literal> using your Roman font again.
+	</para>
+	<para>
+          Similarly, if you change the font, font size, script,
+	  language, or direction within your string, then you will
+	  need to shape each run independently and output them
+	  independently. HarfBuzz expects to shape a run of characters
+	  that all share the same properties.
+        </para>
+      </listitem>
+      <listitem>
+        <para>
+          HarfBuzz won't help you with line breaking, hyphenation, or
+          justification. As mentioned above, HarfBuzz lays out the string
+          along a <emphasis>single line</emphasis> of, notionally,
+          infinite length. If you want to find out where the potential
+          word, sentence and line break points are in your text, you
+          could use the ICU library's break iterator functions.
+        </para>
+        <para>
+          HarfBuzz can tell you how wide a shaped piece of text is, which is
+          useful input to a justification algorithm, but it knows nothing
+          about paragraphs, lines or line lengths. Nor will it adjust the
+          space between words to fit them proportionally into a line.
+        </para>
+      </listitem>
+    </itemizedlist>
+    <para>
+      As a layout-engine implementor, HarfBuzz will help you with the
+      interface between your text and your font, and that's something
+      that you'll need&mdash;what you then do with the glyphs that your font
+      returns is up to you. 
+    </para>
+  </section>
+    
+  <section id="why-is-it-called-harfbuzz">
+    <title>Why is it called HarfBuzz?</title>
+    <para>
+      HarfBuzz began its life as text-shaping code within the FreeType
+      project (and you will see references to the FreeType authors
+      within the source code copyright declarations), but was then
+      extracted out to its own project. This project is maintained by
+      Behdad Esfahbod, who named it HarfBuzz. Originally, it was a
+      shaping engine for OpenType fonts&mdash;&quot;HarfBuzz&quot; is
+      the Persian for &quot;open type&quot;.
+    </para>
+  </section>
+</chapter>

+ 1 - 0
hbfreetypefont.mod/harfbuzz/docs/version.xml.in

@@ -0,0 +1 @@
+@HB_VERSION@

+ 544 - 0
hbfreetypefont.mod/harfbuzz/docs/wasm-shaper.md

@@ -0,0 +1,544 @@
+# The web assembly shaper
+
+If the standard OpenType shaping engine doesn't give you enough flexibility, Harfbuzz allows you to write your own shaping engine in WebAssembly and embed it into your font! Any font which contains a `Wasm` table will be passed to the WebAssembly shaper.
+
+## What you can and can't do: the WASM shaper's role in shaping
+
+The Harfbuzz shaping engine, unlike its counterparts CoreText and DirectWrite, is only responsible for a small part of the text rendering process. Specifically, Harfbuzz is purely responsible for *shaping*; although Harfbuzz does have APIs for accessing glyph outlines, typically other libraries in the free software text rendering stack are responsible for text segmentation into runs, outline scaling and rasterizing, setting text on lines, and so on.
+
+Harfbuzz is therefore restricted to turning a buffer of codepoints for a segmented run of the same script, language, font, and variation settings, into glyphs and positioning them. This is also all that you can do with the WASM shaper; you can influence the process of mapping a string of characters into an array of glyphs, you can determine how those glyphs are positioned and their advance widths, but you cannot manipulate outlines, variations, line breaks, or affect text layout between texts of different font, variation, language, script or OpenType feature selection.
+
+## The WASM shaper interface
+
+The WASM code inside a font is expected to export a function called `shape` which takes five int32 arguments and returns an int32 status value. (Zero for failure, any other value for success.) Three of the five arguments are tokens which can be passed to the API functions exported to your WASM code by the host shaping engine:
+
+* A *shape plan* token, which can largely be ignored.
+* A *font* token.
+* A *buffer* token.
+* A *feature* array.
+* The number of features.
+
+The general goal of WASM shaping involves receiving and manipulating a *buffer contents* structure, which is an array of *infos* and *positions* (as defined below). Initially this buffer will represent an input string in Unicode codepoints. By the end of your `shape` function, it should represent a set of glyph IDs and their positions. (User-supplied WASM code will manipulate the buffer through *buffer tokens*; the `buffer_copy_contents` and `buffer_set_contents` API functions, defined below, use these tokens to exchange buffer information with the host shaping engine.)
+
+* The `buffer_contents_t` structure
+
+| type | field | description|
+| - | - | - |
+| uint32 | length | Number of items (characters or glyphs) in the buffer
+| glyph_info_t | infos | An array of `length` glyph infos |
+| glyph_position_t | positions | An array of `length` glyph positions |
+
+* The `glyph_info_t` structure
+
+| type | field | description|
+| - | - | - |
+| uint32 | codepoint | (On input) A Unicode codepoint. (On output) A glyph ID. |
+| uint32 | mask | Unused in WASM; can be user-defined |
+| uint32 | cluster | Index of start of this graphical cluster in input string |
+| uint32 | var1 | Reserved |
+| uint32 | var2 | Reserved |
+
+The `cluster` field is used to glyphs in the output glyph stream back to characters in the input Unicode sequence for hit testing, cursor positioning, etc. It must be set to a monotonically increasing value across the buffer.
+
+* The `glyph_position_t` structure
+
+| type | field | description|
+| - | - | - |
+| int32 | x_advance | X advance of the glyph |
+| int32 | y_advance | Y advance of the glyph |
+| int32 | x_offset | X offset of the glyph |
+| int32 | y_offset | Y offset of the glyph |
+| uint32 | var | Reserved |
+
+* The `feature_t` array
+
+To communicate user-selected OpenType features to the user-defined WASM shaper, the host shaping engine passes an array of feature structures:
+
+| type | field | description|
+| - | - | - |
+| uint32 | tag | Byte-encoded feature tag |
+| uint32 | value | Value: 0=off, 1=on, other values used for alternate selection |
+| uint32 | start | Index into the input string representing start of the active region for this feature selection (0=start of string) |
+| uint32 | end | Index into the input string representing end of the active region for this feature selection (-1=end of string) |
+
+## API functions available
+
+To assist the shaping code in mapping codepoints to glyphs, the WASM shaper exports the following functions. Note that these are the low level API functions; WASM authors may prefer to use higher-level abstractions around these functions, such as the `harfbuzz-wasm` Rust crate provided by Harfbuzz.
+
+### Sub-shaping
+
+* `shape_with`
+
+```C
+bool shape_with(
+    uint32 font_token,
+    uint32 buffer_token,
+    feature_t* features,
+    uint32 num_features,
+    char* shaper
+)
+```
+
+Run another shaping engine's shaping process on the given font and buffer. The only shaping engine guaranteed to be available is `ot`, the OpenType shaper, but others may also be available. This allows the WASM author to process a buffer "normally", before further manipulating it.
+
+### Buffer access
+
+* `buffer_copy_contents`
+
+```C
+bool buffer_copy_contents(
+    uint32 buffer_token,
+    buffer_contents_t* buffer_contents
+)
+```
+
+Retrieves the contents of the host shaping engine's buffer into the `buffer_contents` structure. This should typically be called at the beginning of shaping.
+
+* `buffer_set_contents`
+
+```C
+bool buffer_set_contents(
+    uint32 buffer_token,
+    buffer_contents_t* buffer_contents
+)
+```
+
+Copy the `buffer_contents` structure back into the host shaping engine's buffer. This should typically be called at the end of shaping.
+
+* `buffer_contents_free`
+
+```C
+bool buffer_contents_free(buffer_contents_t* buffer_contents)
+```
+
+Releases the memory taken up by the buffer contents structure.
+
+* `buffer_contents_realloc`
+
+```C
+bool buffer_contents_realloc(
+    buffer_contents_t* buffer_contents,
+    uint32 size
+)
+```
+
+Requests that the buffer contents structure be resized to the given size.
+
+* `buffer_get_direction`
+
+```C
+uint32 buffer_get_direction(uint32 buffer_token)
+```
+
+Returns the buffer's direction:
+
+* 0 = invalid
+* 4 = left to right
+* 5 = right to left
+* 6 = top to bottom
+* 7 = bottom to top
+
+* `buffer_get_script`
+
+```C
+uint32 buffer_get_script(uint32 buffer_token)
+```
+
+Returns the byte-encoded OpenType script tag of the buffer.
+
+* `buffer_reverse`
+
+```C
+void buffer_reverse(uint32 buffer_token)
+```
+
+Reverses the order of items in the buffer.
+
+* `buffer_reverse_clusters`
+
+```C
+void buffer_reverse_clusters(uint32 buffer_token)
+```
+
+Reverses the order of items in the buffer while keeping items of the same cluster together.
+
+## Font handling functions
+
+(In the following functions, a *font* is a specific instantiation of a *face* at a particular scale factor and variation position.)
+
+* `font_create`
+
+```C
+uint32 font_create(uint32 face_token)
+```
+
+Returns a new *font token* from the given *face token*.
+
+* `font_get_face`
+
+```C
+uint32 font_get_face(uint32 font_token)
+```
+
+Creates a new *face token* from the given *font token*.
+
+* `font_get_scale`
+
+```C
+void font_get_scale(
+    uint32 font_token,
+    int32* x_scale,
+    int32* y_scale
+)
+```
+
+Returns the scale of the current font.
+
+* `font_get_glyph`
+
+```C
+uint32 font_get_glyph(
+    uint32 font_token,
+    uint32 codepoint,
+    uint32 variation_selector
+)
+```
+
+Returns the nominal glyph ID for the given codepoint, using the `cmap` table of the font to map Unicode codepoint (and variation selector) to glyph ID.
+
+* `font_get_glyph_h_advance`/`font_get_glyph_v_advance`
+
+```C
+uint32 font_get_glyph_h_advance(uint32 font_token, uint32 glyph_id)
+uint32 font_get_glyph_v_advance(uint32 font_token, uint32 glyph_id)
+```
+
+Returns the default horizontal and vertical advance respectively for the given glyph ID the current scale and variations settings.
+
+* `font_get_glyph_extents`
+
+```C
+typedef struct
+{
+  uint32 x_bearing;
+  uint32 y_bearing;
+  uint32 width;
+  uint32 height;
+} glyph_extents_t;
+
+bool font_get_glyph_extents(
+    uint32 font_token,
+    uint32 glyph_id,
+    glyph_extents_t* extents
+)
+```
+
+Returns the glyph's extents for the given glyph ID at current scale and variation settings.
+
+* `font_glyph_to_string`
+
+```C
+void font_glyph_to_string(
+    uint32 font_token,
+    uint32 glyph_id,
+    char* string,
+    uint32 size
+)
+```
+
+Copies the name of the given glyph, or, if no name is available, a string of the form `gXXXX` into the given string.
+
+* `font_copy_glyph_outline`
+
+```C
+typedef struct
+{
+  float x;
+  float y;
+  uint32_t type;
+} glyph_outline_point_t;
+
+typedef struct
+{
+  uint32_t n_points;
+  glyph_outline_point_t* points;
+  uint32_t n_contours;
+  uint32_t* contours;
+} glyph_outline_t;
+
+bool font_copy_glyph_outline(
+    uint32 font_token,
+    uint32 glyph_id,
+    glyph_outline_t* outline
+);
+```
+
+Copies the outline of the given glyph ID, at current scale and variation settings, into the outline structure provided. The outline structure returns an array of points (specifying coordinates and whether the point is oncurve or offcurve) and an array of indexes into the points array representing the end of each contour, similar to the `glyf` table structure.
+
+* `font_copy_coords`/`font_set_coords`
+
+```C
+typedef struct
+{
+  uint32 length;
+  int32* coords;
+} coords_t;
+
+bool font_copy_coords(uint32 font_token, &coords_t coords);
+bool font_set_coords(uint32 font_token, &coords_t coords);
+```
+
+`font_copy_coords` copies the font's variation coordinates into the given structure; the resulting structure has `length` equal to the number of variation axes, with each member of the `coords` array being a F2DOT14 encoding of the normalized variation value.
+
+`font_set_coords` sets the font's variation coordinates. Because the WASM shaper is only responsible for shaping and positioning, not outline drawing, the user should *not* expect this to affect the rendered outlines; the function is only useful in very limited circumstances, such as when instantiating a second variable font and sub-shaping a buffer using this new font.
+
+## Face handling functions
+
+* `face_create`
+
+```C
+typedef struct
+{
+  uint32_t length;
+  char* data;
+} blob_t;
+
+uint32 font_get_face(blob_t* blob)
+```
+
+Creates a new *face token* from the given binary data.
+
+* `face_copy_table`
+
+```C
+void face_copy_table(uint32 face_token, uint32 tag, blob_t* blob)
+```
+
+Copies the binary data in the OpenType table referenced by `tag` into the supplied `blob` structure.
+
+* `face_get_upem`
+
+```C
+uint32 font_get_upem(uint32 face_token)
+```
+
+Returns the units-per-em of the font face.
+
+### Other functions
+
+* `blob_free`
+
+```C
+void blob_free(blob_t* blob)
+```
+
+Frees the memory allocated to a blob structure.
+
+* `glyph_outline_free`
+
+```C
+void glyph_outline_free(glyph_outline_t* glyph_outline)
+```
+
+Frees the memory allocated to a glyph outline structure.
+
+* `script_get_horizontal_direction`
+
+```C
+uint32 script_get_horizontal_direction(uint32 tag)
+```
+
+Returns the horizontal direction for the given ISO 15924 script tag. For return values, see `buffer_get_direction` above.
+
+* `debugprint` / `debugprint1` ... `debugprint4`
+
+```C
+void debugprint(char* str)
+void debugprint1(char* str, int32 arg1)
+void debugprint2(char* str, int32 arg1, int32 arg2)
+void debugprint3(char* str, int32 arg1, int32 arg2, int32 arg3)
+void debugprint4(
+    char* str,
+    int32 arg1,
+    int32 arg2,
+    int32 arg3,
+    int32 arg4
+)
+```
+
+Produces a debugging message in the host shaper's log output; the variants `debugprint1` ... `debugprint4` suffix the message with a comma-separated list of the integer arguments.
+
+## Enabling the WASM shaper when building Harfbuzz
+
+First, you will need the `wasm-micro-runtime` library installed on your computer. Download `wasm-micro-runtime` from [its GitHub repository](https://github.com/bytecodealliance/wasm-micro-runtime/tree/main); then follow [the instructions for building](https://github.com/bytecodealliance/wasm-micro-runtime/blob/main/product-mini/README.md), except run the cmake command from the repository root directory and add the `-DWAMR_BUILD_REF_TYPES=1` flag to the `cmake` line. (You may want to enable "fast JIT".) Then, install it.
+
+So, for example:
+
+```
+$ cmake -B build -DWAMR_BUILD_REF_TYPES=1 -DWAMR_BUILD_FAST_JIT=1
+$ cmake --build build --parallel
+$ sudo cmake --build build --target install
+```
+
+(If you don't want to install `wasm-micro-runtime` globally, you can copy `libiwasm.*` and `libvmlib.a` into a directory that your compiler can see when building Harfbuzz.)
+
+Once `wasm-micro-runtime` is installed, to enable the WASM shaper, you need to add the string `-Dwasm=enabled` to your meson build line. For example:
+
+```
+$ meson setup build -Dwasm=enabled
+...
+  Additional shapers
+    Graphite2                 : NO
+    WebAssembly (experimental): YES
+...
+$ meson compile -C build
+```
+
+## How to write a shaping engine in Rust
+
+You may write shaping engines in any language supported by WASM, by conforming to the API described above, but Rust is particularly easy, and we have one of those high-level interface wrappers which makes the process easier. Here are the steps to create an example shaping engine in Rust: (These examples can also be found in `src/wasm/sample/rust`)
+
+* First, install wasm-pack, which helps us to generate optimized WASM files. It writes some Javascript bridge code that we don't need, but it makes the build and deployment process much easier:
+
+```
+$ cargo install wasm-pack
+```
+
+* Now let's create a new library:
+
+```
+$ cargo new --lib hello-wasm
+```
+
+* We need the target to be a dynamic library, and we're going to use `bindgen` to export our Rust function to WASM, so let's put these lines in the `Cargo.toml`. The Harfbuzz sources contain a Rust crate which makes it easy to create the shaper, so we'll specify that as a dependency as well:
+
+```toml
+[lib]
+crate-type = ["cdylib"]
+[dependencies]
+wasm-bindgen = "0.2"
+harfbuzz-wasm = { path = "your-harfbuzz-source/src/wasm/rust/harfbuzz-wasm"}
+```
+
+*
+* And now we'll create our shaper code. In `src/lib.rs`:
+
+```rust
+use wasm_bindgen::prelude::*;
+
+#[wasm_bindgen]
+pub fn shape(_shape_plan:u32, font_ref: u32, buf_ref: u32, _features: u32, _num_features: u32) -> i32 {
+    1 // success!
+}
+```
+
+This exports a shaping function which takes four arguments, tokens representing the shaping plan, the font and the buffer, and returns a status value. We can pass these tokens back to Harfbuzz in order to use its native functions on the font and buffer objects. More on native functions later - let's get this shaper compiled and added into a font:
+
+* To compile the shaper, run `wasm-pack build --target nodejs`:
+
+```
+INFO]: 🎯  Checking for the Wasm target...
+[INFO]: 🌀  Compiling to Wasm...
+   Compiling hello-wasm v0.1.0 (...)
+    Finished release [optimized] target(s) in 0.20s
+[WARN]: ⚠️   origin crate has no README
+[INFO]: ⬇️  Installing wasm-bindgen...
+[INFO]: Optimizing wasm binaries with `wasm-opt`...
+[INFO]: Optional fields missing from Cargo.toml: 'description', 'repository', and 'license'. These are not necessary, but recommended
+[INFO]: ✨   Done in 0.40s
+```
+
+You'll find the output WASM file in `pkg/hello_wasm_bg.wasm`
+
+* Now we need to get it into a font.
+
+We provide a utility to do this called `addTable.py` in the `src/` directory:
+
+```
+% python3 ~/harfbuzz/src/addTable.py test.ttf test-wasm.ttf pkg/hello_wasm_bg.wasm
+```
+
+And now we can run it!
+
+```
+% hb-shape test-wasm.ttf abc --shapers=wasm
+[cent=0|sterling=1|fraction=2]
+```
+
+(The `--shapers=wasm` isn't necessary, as any font with a `Wasm` table will be sent to the WASM shaper if it's enabled, but it proves the point.)
+
+Congratulations! Our shaper did nothing, but in Rust! Now let's do something - it's time for the Hello World of WASM shaping.
+
+* To say hello world, we're going to have to use a native function.
+
+In debugging builds of Harfbuzz, we can print some output from the web assembly module to the host's standard output using the `debug` function. To make this easier, we've got the `harfbuzz-wasm` crate:
+
+```rust
+use harfbuzz_wasm::debug;
+
+#[wasm_bindgen]
+pub fn shape(_shape_plan:u32, _font_ref: u32, _buf_ref: u32, _features: u32, _num_features: u32) -> i32 {
+    debug("Hello from Rust!\n");
+    1
+}
+```
+
+With this compiled into a WASM module, and installed into our font again, finally our fonts can talk to us!
+
+```
+$ hb-shape test-wasm.ttf abc
+Hello from Rust!
+[cent=0|sterling=1|fraction=2]
+```
+
+Now let's start to do some actual, you know, *shaping*. The first thing a shaping engine normally does is (a) map the items in the buffer from Unicode codepoints into glyphs in the font, and (b) set the advance width of the buffer items to the default advance width for those glyphs. We're going to need to interrogate the font for this information, and write back to the buffer. Harfbuzz provides us with opaque pointers to the memory for the font and buffer, but we can turn those into useful Rust structures using the `harfbuzz-wasm` crate again:
+
+```rust
+use wasm_bindgen::prelude::*;
+use harfbuzz_wasm::{Font, GlyphBuffer};
+
+#[wasm_bindgen]
+pub fn shape(_shape_plan:u32, font_ref: u32, buf_ref: u32, _features: u32, _num_features: u32) -> i32 {
+    let font = Font::from_ref(font_ref);
+    let mut buffer = GlyphBuffer::from_ref(buf_ref);
+    for mut item in buffer.glyphs.iter_mut() {
+        // Map character to glyph
+        item.codepoint = font.get_glyph(item.codepoint, 0);
+        // Set advance width
+        item.x_advance = font.get_glyph_h_advance(item.codepoint);
+    }
+    1
+}
+```
+
+The `GlyphBuffer`, unlike in Harfbuzz, combines positioning and information in a single structure, to save you having to zip and unzip all the time. It also takes care of marshalling the buffer back to Harfbuzz-land; when a GlyphBuffer is dropped, it writes its contents back through the reference into Harfbuzz's address space. (If you want a different representation of buffer items, you can have one: `GlyphBuffer` is implemented as a `Buffer<Glyph>`, and if you make your own struct which implements the `BufferItem` trait, you can make a buffer out of that instead.)
+
+One easy way to write your own shapers is to make use of OpenType shaping for the majority of your shaping work, and then make changes to the pre-shaped buffer afterwards. You can do this using the `Font.shape_with` method. Run this on a buffer reference, and then construct your `GlyphBuffer` object afterwards:
+
+```rust
+use harfbuzz_wasm::{Font, GlyphBuffer};
+use tiny_rng::{Rand, Rng};
+use wasm_bindgen::prelude::*;
+
+#[wasm_bindgen]
+pub fn shape(_shape_plan:u32, font_ref: u32, buf_ref: u32, _features: u32, _num_features: u32) -> i32 {
+    let mut rng = Rng::from_seed(123456);
+
+    // Use the default OpenType shaper
+    let font = Font::from_ref(font_ref);
+    font.shape_with(buf_ref, "ot");
+
+    // Now we have a buffer with glyph ids, advance widths etc.
+    // already filled in.
+    let mut buffer = GlyphBuffer::from_ref(buf_ref);
+    for mut item in buffer.glyphs.iter_mut() {
+        // Randomize it!
+        item.x_offset = ((rng.rand_u32() as i32) >> 24) - 120;
+        item.y_offset = ((rng.rand_u32() as i32) >> 24) - 120;
+    }
+
+    1
+}
+```
+
+See the documentation for the `harfbuzz-wasm` crate for all the other

+ 24 - 0
hbfreetypefont.mod/harfbuzz/harfbuzz.doap

@@ -0,0 +1,24 @@
+<Project xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
+         xmlns:rdfs="http://www.w3.org/2000/01/rdf-schema#"
+         xmlns:foaf="http://xmlns.com/foaf/0.1/"
+         xmlns="http://usefulinc.com/ns/doap#">
+
+  <name xml:lang="en">harfbuzz</name>
+  <shortdesc xml:lang="en">Text shaping library</shortdesc>
+
+  <homepage
+  rdf:resource="https://github.com/harfbuzz/harfbuzz" />
+  <mailing-list
+  rdf:resource="https://github.com/harfbuzz/harfbuzz/discussions" />
+  <download-page
+  rdf:resource="https://github.com/harfbuzz/harfbuzz/releases" />
+  <bug-database
+  rdf:resource="https://github.com/harfbuzz/harfbuzz/issues" />
+
+  <maintainer>
+    <foaf:Person>
+      <foaf:name>Behdad Esfahbod</foaf:name>
+      <foaf:mbox rdf:resource="mailto:[email protected]" />
+    </foaf:Person>
+  </maintainer>
+</Project>

+ 511 - 0
hbfreetypefont.mod/harfbuzz/meson.build

@@ -0,0 +1,511 @@
+project('harfbuzz', 'c', 'cpp',
+  meson_version: '>= 0.55.0',
+  version: '9.0.0',
+  default_options: [
+    'cpp_eh=none',          # Just to support msvc, we are passing -fno-exceptions also anyway
+    # 'cpp_rtti=false',     # Do NOT enable, wraps inherit it and ICU needs RTTI
+    'cpp_std=c++11',
+    'wrap_mode=nofallback', # Use --wrap-mode=default to revert, https://github.com/harfbuzz/harfbuzz/pull/2548
+  ],
+)
+
+glib_min_version = '>= 2.30.0'
+cairo_min_version = '>= 1.10.0'
+chafa_min_version = '>= 1.6.0'
+icu_min_version = '>= 49.0'
+graphite2_min_version = '>= 1.2.0'
+
+freetype_min_version_actual = '>= 2.4.2'
+freetype_min_version = '>= 12.0.6'    # Corresponds to `freetype_min_version_actual`
+
+hb_version_arr = meson.project_version().split('.')
+hb_version_major = hb_version_arr[0].to_int()
+hb_version_minor = hb_version_arr[1].to_int()
+hb_version_micro = hb_version_arr[2].to_int()
+
+# libtool versioning
+hb_version_int = 60000 + hb_version_major*100 + hb_version_minor*10 + hb_version_micro
+hb_libtool_version_info = '@0@:0:@0@'.format(hb_version_int)
+
+pkgmod = import('pkgconfig')
+cpp = meson.get_compiler('cpp')
+null_dep = dependency('', required: false)
+
+# Only perform these checks if cpp_std is c++11 as setting -std directly
+# produces a warning from meson.
+if get_option('cpp_std') == 'c++11'
+  # Enforce C++14 requirement for MSVC STL
+  if cpp.get_id() == 'clang' and cpp.get_define('_MSC_FULL_VER') != ''
+    add_project_arguments('-std=c++14', language: 'cpp')
+  elif cpp.get_id() == 'clang-cl'
+    # Clang-cl produces a warning when using -std=c++14, but not when using /std:c++14
+    add_project_arguments('/std:c++14', language : 'cpp')
+  endif
+endif
+
+if cpp.get_argument_syntax() == 'msvc'
+  # Ignore several spurious warnings for things HarfBuzz does very commonly.
+  # If a warning is completely useless and spammy, use '/wdXXXX' to suppress it
+  # If a warning is harmless but hard to fix, use '/woXXXX' so it's shown once
+  # NOTE: Only add warnings here if you are sure they're spurious
+  msvc_args = [
+    '/wd4244', # lossy type conversion (e.g. double -> int)
+    '/bigobj', # hb-subset.cc -- compile error C1128: number of sections exceeded object file format limit
+    cpp.get_supported_arguments(['/utf-8']), # set the input encoding to utf-8
+  ]
+  add_project_arguments(msvc_args, language: ['c', 'cpp'])
+  # Disable SAFESEH with MSVC for libs that use external deps that are built with MinGW
+  # noseh_link_args = ['/SAFESEH:NO']
+endif
+
+add_project_link_arguments(cpp.get_supported_link_arguments([
+  '-Bsymbolic-functions'
+]), language: 'c')
+
+add_project_arguments(cpp.get_supported_arguments([
+  '-fno-exceptions',
+  '-fno-rtti',
+  '-fno-threadsafe-statics',
+  '-fvisibility-inlines-hidden',
+]), language: 'cpp')
+
+if host_machine.cpu_family() == 'arm' and cpp.alignment('struct { char c; }') != 1
+  if cpp.has_argument('-mstructure-size-boundary=8')
+    add_project_arguments('-mstructure-size-boundary=8', language: 'cpp')
+  endif
+endif
+
+if host_machine.system() == 'windows'
+  add_project_arguments(cpp.get_supported_arguments([
+    '-Wa,-mbig-obj'
+  ]), language : 'cpp')
+endif
+
+check_headers = [
+  ['unistd.h'],
+  ['sys/mman.h'],
+  ['stdbool.h'],
+  ['xlocale.h'],
+]
+
+check_funcs = [
+  ['atexit', {'prefix': '#include <stdlib.h>'}],
+  ['mprotect', {'prefix': '#include <sys/mman.h>'}],
+  ['sysconf', {'prefix': '#include <unistd.h>'}],
+  ['getpagesize', {'prefix': '#include <unistd.h>'}],
+  ['mmap', {'prefix': '#include <sys/mman.h>'}],
+  ['isatty', {'prefix': '#include <unistd.h>'}],
+  ['uselocale', {'prefix': '#include <locale.h>'}],
+  ['newlocale', {'prefix': '#include <locale.h>'}],
+  ['sincosf', {'prefix': '#define _GNU_SOURCE\n#include <math.h>'}],
+]
+
+m_dep = cpp.find_library('m', required: false)
+
+if meson.version().version_compare('>=0.60.0')
+  # Sadly, FreeType's versioning schemes are different between pkg-config and CMake
+  # pkg-config: freetype2, cmake: Freetype
+  freetype_dep = dependency('freetype2',
+                            version: freetype_min_version,
+                            method: 'pkg-config',
+                            required: false,
+                            allow_fallback: false)
+  if not freetype_dep.found()
+    freetype_dep = dependency('FreeType',
+                              version: freetype_min_version_actual,
+                              method: 'cmake',
+                              required: get_option('freetype'),
+                              default_options: ['harfbuzz=disabled'],
+                              allow_fallback: true)
+  endif
+else
+  # painful hack to handle multiple dependencies but also respect options
+  freetype_opt = get_option('freetype')
+  # we want to handle enabled manually after fallbacks, but also handle disabled normally
+  if freetype_opt.enabled()
+    freetype_opt = false
+  endif
+  # try pkg-config name
+  freetype_dep = dependency('freetype2', version: freetype_min_version, method: 'pkg-config', required: freetype_opt)
+  # when disabled, leave it not-found
+  if not freetype_dep.found() and not get_option('freetype').disabled()
+    # Try cmake name
+    freetype_dep = dependency('Freetype', version: freetype_min_version_actual, method: 'cmake', required: false)
+    # Subproject fallback, `allow_fallback: true` means the fallback will be
+    # tried even if the freetype option is set to `auto`.
+    if not freetype_dep.found()
+      freetype_dep = dependency('freetype2',
+                                version: freetype_min_version,
+                                method: 'pkg-config',
+                                required: get_option('freetype'),
+                                default_options: ['harfbuzz=disabled'],
+                                allow_fallback: true)
+    endif
+  endif
+endif
+
+glib_dep = dependency('glib-2.0', version: glib_min_version, required: get_option('glib'))
+gobject_dep = dependency('gobject-2.0', version: glib_min_version, required: get_option('gobject'))
+graphite2_dep = dependency('graphite2', version: graphite2_min_version, required: get_option('graphite2'))
+graphite_dep = dependency('graphite2', version: graphite2_min_version, required: get_option('graphite'))
+wasm_dep = cpp.find_library('iwasm', required: get_option('wasm'))
+# How to check whether iwasm was built, and hence requires, LLVM?
+#llvm_dep = cpp.find_library('LLVM-15', required: get_option('wasm'))
+
+if meson.version().version_compare('>=0.60.0')
+  # pkg-config: icu-uc, cmake: ICU but with components
+  icu_dep = dependency('icu-uc', 'ICU',
+                            version: icu_min_version,
+                            components: 'uc',
+                            required: get_option('icu'),
+                            allow_fallback: true)
+else
+  # painful hack to handle multiple dependencies but also respect options
+  icu_opt = get_option('icu')
+  # we want to handle enabled manually after fallbacks, but also handle disabled normally
+  if icu_opt.enabled()
+    icu_opt = false
+  endif
+  # try pkg-config name
+  icu_dep = dependency('icu-uc', version: icu_min_version, method: 'pkg-config', required: icu_opt)
+  # when disabled, leave it not-found
+  if not icu_dep.found() and not get_option('icu').disabled()
+    # Try cmake name
+    icu_dep = dependency('ICU', version: icu_min_version, method: 'cmake', components: 'uc', required: false)
+    # Try again with subproject fallback. `allow_fallback: true` means the
+    # fallback will be tried even if the icu option is set to `auto`, but
+    # we cannot pass this option until Meson 0.59.0, because no wrap file
+    # is checked into git.
+    if not icu_dep.found()
+      icu_dep = dependency('icu-uc',
+                           version: icu_min_version,
+                           method: 'pkg-config',
+                           required: get_option('icu'))
+    endif
+  endif
+endif
+
+if icu_dep.found() and icu_dep.version().version_compare('>=75.1') and (get_option('cpp_std') == 'c++11' or get_option('cpp_std') == 'c++14')
+  add_project_arguments('-std=c++17', language: 'cpp')
+endif
+
+if icu_dep.found() and icu_dep.type_name() == 'pkgconfig'
+  icu_defs = icu_dep.get_variable(pkgconfig: 'DEFS', default_value: '').split()
+  if icu_defs.length() > 0
+    add_project_arguments(icu_defs, language: ['c', 'cpp'])
+  endif
+endif
+
+cairo_dep = null_dep
+cairo_ft_dep = null_dep
+if not get_option('cairo').disabled()
+  cairo_dep = dependency('cairo', version: cairo_min_version, required: false)
+  cairo_ft_dep = dependency('cairo-ft', version: cairo_min_version, required: false)
+
+  if (not cairo_dep.found() and
+      cpp.get_argument_syntax() == 'msvc' and
+      cpp.has_header('cairo.h'))
+    cairo_dep = cpp.find_library('cairo', required: false)
+    if cairo_dep.found() and cpp.has_function('cairo_ft_font_face_create_for_ft_face',
+                                              prefix: '#include <cairo-ft.h>',
+                                              dependencies: cairo_dep)
+      cairo_ft_dep = cairo_dep
+    endif
+  endif
+
+  if not cairo_dep.found()
+    # Note that we don't have harfbuzz -> cairo -> freetype2 -> harfbuzz fallback
+    # dependency cycle here because we have configured freetype2 above with
+    # harfbuzz support disabled, so when cairo will lookup freetype2 dependency
+    # it will be forced to use that one.
+    cairo_dep = dependency('cairo', version: cairo_min_version, required: get_option('cairo'))
+    cairo_ft_required = get_option('cairo').enabled() and get_option('freetype').enabled()
+    cairo_ft_dep = dependency('cairo-ft', version: cairo_min_version, required: cairo_ft_required)
+  endif
+endif
+
+chafa_dep = dependency('chafa', version: chafa_min_version, required: get_option('chafa'))
+
+conf = configuration_data()
+incconfig = include_directories('.')
+
+add_project_arguments('-DHAVE_CONFIG_H', language: ['c', 'cpp'])
+
+warn_cflags = [
+  '-Wno-non-virtual-dtor',
+]
+
+cpp_args = cpp.get_supported_arguments(warn_cflags)
+
+if glib_dep.found()
+  conf.set('HAVE_GLIB', 1)
+endif
+
+if gobject_dep.found()
+  conf.set('HAVE_GOBJECT', 1)
+endif
+
+if cairo_dep.found()
+  conf.set('HAVE_CAIRO', 1)
+  check_cairo_funcs = [
+    ['cairo_user_font_face_set_render_color_glyph_func', {'deps': cairo_dep}],
+    ['cairo_font_options_get_custom_palette_color', {'deps': cairo_dep}],
+    ['cairo_user_scaled_font_get_foreground_source', {'deps': cairo_dep}],
+  ]
+
+  if cairo_dep.type_name() == 'internal'
+    foreach func: check_cairo_funcs
+      name = func[0]
+      conf.set('HAVE_@0@'.format(name.to_upper()), 1)
+    endforeach
+  else
+    check_funcs += check_cairo_funcs
+  endif
+endif
+
+if cairo_ft_dep.found()
+  conf.set('HAVE_CAIRO_FT', 1)
+endif
+
+if chafa_dep.found()
+  conf.set('HAVE_CHAFA', 1)
+endif
+
+if wasm_dep.found()
+  conf.set('HAVE_WASM', 1)
+  conf.set('HB_WASM_MODULE_DIR', '"'+get_option('prefix')+'/'+get_option('libdir')+'/harfbuzz/wasm"')
+endif
+
+if graphite2_dep.found() or graphite_dep.found()
+  conf.set('HAVE_GRAPHITE2', 1)
+endif
+
+if icu_dep.found()
+  conf.set('HAVE_ICU', 1)
+endif
+
+if get_option('icu_builtin')
+  conf.set('HAVE_ICU_BUILTIN', 1)
+endif
+
+if get_option('experimental_api')
+  conf.set('HB_EXPERIMENTAL_API', 1)
+endif
+
+if freetype_dep.found()
+  conf.set('HAVE_FREETYPE', 1)
+  check_freetype_funcs = [
+    ['FT_Get_Var_Blend_Coordinates', {'deps': freetype_dep}],
+    ['FT_Set_Var_Blend_Coordinates', {'deps': freetype_dep}],
+    ['FT_Done_MM_Var', {'deps': freetype_dep}],
+    ['FT_Get_Transform', {'deps': freetype_dep}],
+  ]
+
+  if freetype_dep.type_name() == 'internal'
+    foreach func: check_freetype_funcs
+      name = func[0]
+      conf.set('HAVE_@0@'.format(name.to_upper()), 1)
+    endforeach
+  else
+    check_funcs += check_freetype_funcs
+  endif
+endif
+
+gdi_uniscribe_deps = []
+# GDI (Uniscribe) (Windows)
+if host_machine.system() == 'windows' and not get_option('gdi').disabled()
+  if (get_option('directwrite').enabled() and
+      not (cpp.has_header('usp10.h') and cpp.has_header('windows.h')))
+    error('GDI/Uniscribe was enabled explicitly, but required headers are missing.')
+  endif
+
+  gdi_deps_found = true
+  foreach usplib : ['usp10', 'gdi32', 'rpcrt4']
+    dep = cpp.find_library(usplib, required: get_option('gdi'))
+    gdi_deps_found = gdi_deps_found and dep.found()
+    gdi_uniscribe_deps += dep
+  endforeach
+
+  if gdi_deps_found
+    conf.set('HAVE_UNISCRIBE', 1)
+    conf.set('HAVE_GDI', 1)
+  endif
+endif
+
+# DirectWrite (Windows)
+if host_machine.system() == 'windows' and not get_option('directwrite').disabled()
+  if get_option('directwrite').enabled() and not cpp.has_header('dwrite_1.h')
+    error('DirectWrite was enabled explicitly, but required header is missing.')
+  endif
+
+  conf.set('HAVE_DIRECTWRITE', 1)
+endif
+
+# CoreText (macOS)
+coretext_deps = []
+if host_machine.system() == 'darwin' and not get_option('coretext').disabled()
+  app_services_dep = dependency('appleframeworks', modules: ['ApplicationServices'], required: false)
+  if cpp.has_type('CTFontRef', prefix: '#include <ApplicationServices/ApplicationServices.h>', dependencies: app_services_dep)
+    coretext_deps += [app_services_dep]
+    conf.set('HAVE_CORETEXT', 1)
+  # On iOS CoreText and CoreGraphics are stand-alone frameworks
+  # Check for a different symbol to avoid getting cached result
+  else
+    coretext_dep = dependency('appleframeworks', modules: ['CoreText'], required: false)
+    coregraphics_dep = dependency('appleframeworks', modules: ['CoreGraphics'], required: false)
+    corefoundation_dep = dependency('appleframeworks', modules: ['CoreFoundation'], required: false)
+    if cpp.has_type('CTRunRef', prefix: '#include <CoreText/CoreText.h>', dependencies: [coretext_dep, coregraphics_dep, corefoundation_dep])
+      coretext_deps += [coretext_dep, coregraphics_dep, corefoundation_dep]
+      conf.set('HAVE_CORETEXT', 1)
+    elif get_option('coretext').enabled()
+      error('CoreText was enabled explicitly, but required headers or frameworks are missing.')
+    endif
+  endif
+endif
+
+# threads
+thread_dep = null_dep
+if host_machine.system() != 'windows'
+  thread_dep = dependency('threads', required: false)
+
+  if thread_dep.found()
+    conf.set('HAVE_PTHREAD', 1)
+  endif
+endif
+
+conf.set_quoted('PACKAGE_NAME', 'HarfBuzz')
+conf.set_quoted('PACKAGE_VERSION', meson.project_version())
+
+foreach check : check_headers
+  name = check[0]
+
+  if cpp.has_header(name)
+    conf.set('HAVE_@0@'.format(name.to_upper().underscorify()), 1)
+  endif
+endforeach
+
+harfbuzz_extra_deps = []
+foreach check : check_funcs
+  name = check[0]
+  opts = check.get(1, {})
+  link_withs = opts.get('link_with', [])
+  check_deps = opts.get('deps', [])
+  check_prefix = opts.get('prefix', '')
+  extra_deps = []
+  found = true
+
+  # First try without linking
+  found = cpp.has_function(name, prefix: check_prefix, dependencies: check_deps)
+
+  if not found and link_withs.length() > 0
+    found = true
+
+    foreach link_with : link_withs
+      dep = cpp.find_library(link_with, required: false)
+      if dep.found()
+        extra_deps += dep
+      else
+        found = false
+      endif
+    endforeach
+
+    if found
+      found = cpp.has_function(name, prefix: check_prefix, dependencies: check_deps + extra_deps)
+    endif
+  endif
+
+  if found
+    harfbuzz_extra_deps += extra_deps
+    conf.set('HAVE_@0@'.format(name.to_upper()), 1)
+  endif
+endforeach
+
+# CMake support (package install dir)
+
+# Equivalent to configure_package_config_file(INSTALL_DESTINATION ...), see
+# https://cmake.org/cmake/help/latest/module/CMakePackageConfigHelpers.html#command:configure_package_config_file.
+# In certain unusual packaging layouts such as Nixpkgs, the Harfbuzz package
+# is installed into two Nix store paths, "out" and "dev", where "out" contains
+# libraries only (i.e. lib/libharfbuzz.so) and "dev" contains development
+# files, i.e. include and lib/cmake. If CMake package files are installed to
+# "out", Nixpkgs will move them to "dev", which breaks assumptions about
+# our file paths. Since we need to figure out relative install paths here
+# to make a relocatable package, we do need to know the final path of our
+# CMake files to calculate the correct relative paths.
+# Of course, this still defaults to $libdir/cmake if unset, which works for
+# most packaging layouts.
+cmake_package_install_dir = get_option('cmakepackagedir')
+
+if cmake_package_install_dir == ''
+  cmake_package_install_dir = get_option('libdir') / 'cmake'
+endif
+
+subdir('src')
+
+if not get_option('utilities').disabled()
+  subdir('util')
+endif
+
+if not get_option('tests').disabled()
+  subdir('test')
+endif
+
+if not get_option('benchmark').disabled()
+  subdir('perf')
+endif
+
+if not get_option('docs').disabled()
+  subdir('docs')
+endif
+
+configure_file(output: 'config.h', configuration: conf)
+
+alias_target('lib', libharfbuzz)
+alias_target('libs', libharfbuzz, libharfbuzz_subset)
+
+build_summary = {
+  'Directories':
+    {'prefix': get_option('prefix'),
+     'bindir': get_option('bindir'),
+     'libdir': get_option('libdir'),
+     'includedir': get_option('includedir'),
+     'datadir': get_option('datadir'),
+     'cmakepackagedir': cmake_package_install_dir
+    },
+  'Unicode callbacks (you want at least one)':
+    {'Builtin': true,
+     'Glib': conf.get('HAVE_GLIB', 0) == 1,
+     'ICU': conf.get('HAVE_ICU', 0) == 1,
+    },
+  'Font callbacks (the more the merrier)':
+    {'Builtin' : true,
+     'FreeType': conf.get('HAVE_FREETYPE', 0) == 1,
+    },
+  'Dependencies used for command-line utilities':
+    {'Cairo': conf.get('HAVE_CAIRO', 0) == 1,
+     'Chafa': conf.get('HAVE_CHAFA', 0) == 1,
+    },
+  'Additional shapers':
+    {'Graphite2': conf.get('HAVE_GRAPHITE2', 0) == 1,
+     'WebAssembly (experimental)': conf.get('HAVE_WASM', 0) == 1,
+    },
+  'Platform shapers (not normally needed)':
+    {'CoreText': conf.get('HAVE_CORETEXT', 0) == 1,
+     'DirectWrite (experimental)': conf.get('HAVE_DIRECTWRITE', 0) == 1,
+     'GDI/Uniscribe': (conf.get('HAVE_GDI', 0) == 1) and (conf.get('HAVE_UNISCRIBE', 0) == 1),
+    },
+  'Other features':
+    {'Documentation': conf.get('HAVE_GTK_DOC', 0) == 1,
+     'GObject bindings': conf.get('HAVE_GOBJECT', 0) == 1,
+     'Cairo integration': conf.get('HAVE_CAIRO', 0) == 1,
+     'Introspection': conf.get('HAVE_INTROSPECTION', 0) == 1,
+     'Experimental APIs': conf.get('HB_EXPERIMENTAL_API', 0) == 1,
+    },
+  'Testing':
+    {'Tests': get_option('tests').enabled(),
+     'Benchmark': get_option('benchmark').enabled(),
+    },
+}
+foreach section_title, section : build_summary
+  summary(section, bool_yn: true, section: section_title)
+endforeach

+ 52 - 0
hbfreetypefont.mod/harfbuzz/meson_options.txt

@@ -0,0 +1,52 @@
+# HarfBuzz feature options
+option('glib', type: 'feature', value: 'auto',
+  description: 'Enable GLib unicode functions')
+option('gobject', type: 'feature', value: 'auto',
+  description: 'Enable GObject bindings')
+option('cairo', type: 'feature', value: 'auto',
+  description: 'Use Cairo graphics library')
+option('chafa', type: 'feature', value: 'auto',
+  description: 'Use Chafa terminal graphics library')
+option('icu', type: 'feature', value: 'auto',
+  description: 'Enable ICU library unicode functions')
+option('graphite', type: 'feature', value: 'disabled',
+  description: 'Deprecated use graphite2 option instead')
+option('graphite2', type: 'feature', value: 'disabled',
+  description: 'Enable Graphite2 complementary shaper')
+option('freetype', type: 'feature', value: 'auto',
+  description: 'Enable freetype interop helpers')
+option('gdi', type: 'feature', value: 'disabled',
+  description: 'Enable GDI helpers and Uniscribe shaper backend (Windows only)')
+option('directwrite', type: 'feature', value: 'disabled',
+  description: 'Enable DirectWrite shaper backend on Windows (experimental)')
+option('coretext', type: 'feature', value: 'disabled',
+  description: 'Enable CoreText shaper backend on macOS')
+option('wasm', type: 'feature', value: 'disabled',
+  description: 'Enable WebAssembly shaper backend (experimental)')
+
+# Common feature options
+option('tests', type: 'feature', value: 'enabled', yield: true,
+  description: 'Enable or disable unit tests')
+option('introspection', type: 'feature', value: 'auto', yield: true,
+  description: 'Generate gobject-introspection bindings (.gir/.typelib files)')
+option('docs', type: 'feature', value: 'auto', yield: true,
+  description: 'Generate documentation with gtk-doc')
+option('doc_tests', type: 'boolean', value: false,
+  description: 'Run gtkdoc-check tests')
+option('utilities', type: 'feature', value: 'enabled', yield: true,
+  description: 'Build harfbuzz utils')
+
+option('benchmark', type: 'feature', value: 'disabled',
+  description: 'Enable benchmark tests')
+option('icu_builtin', type: 'boolean', value: false,
+  description: 'Don\'t separate ICU support as harfbuzz-icu module')
+option('experimental_api', type: 'boolean', value: false,
+  description: 'Enable experimental APIs')
+option('ragel_subproject', type: 'boolean', value: false,
+  description: 'Build Ragel subproject if no suitable version is found')
+option('fuzzer_ldflags', type: 'string',
+  description: 'Extra LDFLAGS used during linking of fuzzing binaries')
+
+# Install directory options
+option('cmakepackagedir', type: 'string',
+  description: 'CMake package configuration install directory')

+ 54 - 0
hbfreetypefont.mod/harfbuzz/perf/README.md

@@ -0,0 +1,54 @@
+# Building and Running
+
+Benchmarks are implemented using [Google Benchmark](https://github.com/google/benchmark).
+
+To build the benchmarks in this directory you need to set the benchmark
+option while configuring the build with meson:
+
+```
+meson build -Dbenchmark=enabled --buildtype=release
+```
+or:
+```
+meson build -Dbenchmark=enabled --buildtype=debugoptimized
+```
+
+
+Then build a specific benchmark binaries with ninja:
+```
+ninja -Cbuild perf/benchmark-set
+```
+or just build the whole project:
+```
+ninja -Cbuild
+```
+
+Finally, to run one of the benchmarks:
+
+```
+./build/perf/benchmark-set
+```
+
+It's possible to filter the benchmarks being run and customize the output
+via flags to the benchmark binary. See the
+[Google Benchmark User Guide](https://github.com/google/benchmark/blob/main/docs/user_guide.md#user-guide) for more details.
+
+# Profiling
+
+Configure the build to include debug information for profiling:
+
+```
+CXXFLAGS="-fno-omit-frame-pointer" meson --reconfigure build -Dbenchmark=enabled --buildtype=debug
+ninja -Cbuild
+```
+
+Then run the benchmark with perf:
+
+```
+perf record -g build/perf/benchmark-subset --benchmark_filter="BM_subset_codepoints/subset_notocjk/100000" --benchmark_repetitions=5
+```
+You probably want to filter to a specific benchmark of interest and set the number of repititions high enough to get a good sampling of profile data.
+
+Finally view the profile with:
+
+perf report

+ 319 - 0
hbfreetypefont.mod/harfbuzz/perf/benchmark-font.cc

@@ -0,0 +1,319 @@
+#include "benchmark/benchmark.h"
+#include <cassert>
+#include <cstring>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "hb.h"
+#include "hb-ot.h"
+#ifdef HAVE_FREETYPE
+#include "hb-ft.h"
+#endif
+
+
+#define SUBSET_FONT_BASE_PATH "test/subset/data/fonts/"
+
+struct test_input_t
+{
+  bool is_variable;
+  const char *font_path;
+} default_tests[] =
+{
+  {false, SUBSET_FONT_BASE_PATH "Roboto-Regular.ttf"},
+  {true , SUBSET_FONT_BASE_PATH "RobotoFlex-Variable.ttf"},
+  {false, SUBSET_FONT_BASE_PATH "SourceSansPro-Regular.otf"},
+  {true , SUBSET_FONT_BASE_PATH "AdobeVFPrototype.otf"},
+  {true , SUBSET_FONT_BASE_PATH "SourceSerifVariable-Roman.ttf"},
+  {false, SUBSET_FONT_BASE_PATH "Comfortaa-Regular-new.ttf"},
+  {false, SUBSET_FONT_BASE_PATH "NotoNastaliqUrdu-Regular.ttf"},
+  {false, SUBSET_FONT_BASE_PATH "NotoSerifMyanmar-Regular.otf"},
+};
+
+static test_input_t *tests = default_tests;
+static unsigned num_tests = sizeof (default_tests) / sizeof (default_tests[0]);
+
+enum backend_t { HARFBUZZ, FREETYPE };
+
+enum operation_t
+{
+  nominal_glyphs,
+  glyph_h_advances,
+  glyph_extents,
+  draw_glyph,
+  paint_glyph,
+  load_face_and_shape,
+};
+
+static void
+_hb_move_to (hb_draw_funcs_t *, void *draw_data, hb_draw_state_t *, float x, float y, void *)
+{
+  float &i = * (float *) draw_data;
+  i += x + y;
+}
+
+static void
+_hb_line_to (hb_draw_funcs_t *, void *draw_data, hb_draw_state_t *, float x, float y, void *)
+{
+  float &i = * (float *) draw_data;
+  i += x + y;
+}
+
+static void
+_hb_quadratic_to (hb_draw_funcs_t *, void *draw_data, hb_draw_state_t *, float cx, float cy, float x, float y, void *)
+{
+  float &i = * (float *) draw_data;
+  i += cx + cy + x + y;
+}
+
+static void
+_hb_cubic_to (hb_draw_funcs_t *, void *draw_data, hb_draw_state_t *, float cx1, float cy1, float cx2, float cy2, float x, float y, void *)
+{
+  float &i = * (float *) draw_data;
+  i += cx1 + cy1 + cx2 + cy2 + x + y;
+}
+
+static void
+_hb_close_path (hb_draw_funcs_t *, void *draw_data, hb_draw_state_t *, void *)
+{
+  float &i = * (float *) draw_data;
+  i += 1.0;
+}
+
+static hb_draw_funcs_t *
+_draw_funcs_create (void)
+{
+  hb_draw_funcs_t *draw_funcs = hb_draw_funcs_create ();
+  hb_draw_funcs_set_move_to_func (draw_funcs, _hb_move_to, nullptr, nullptr);
+  hb_draw_funcs_set_line_to_func (draw_funcs, _hb_line_to, nullptr, nullptr);
+  hb_draw_funcs_set_quadratic_to_func (draw_funcs, _hb_quadratic_to, nullptr, nullptr);
+  hb_draw_funcs_set_cubic_to_func (draw_funcs, _hb_cubic_to, nullptr, nullptr);
+  hb_draw_funcs_set_close_path_func (draw_funcs, _hb_close_path, nullptr, nullptr);
+  return draw_funcs;
+}
+
+static void BM_Font (benchmark::State &state,
+		     bool is_var, backend_t backend, operation_t operation,
+		     const test_input_t &test_input)
+{
+  hb_font_t *font;
+  unsigned num_glyphs;
+  {
+    hb_blob_t *blob = hb_blob_create_from_file_or_fail (test_input.font_path);
+    assert (blob);
+    hb_face_t *face = hb_face_create (blob, 0);
+    hb_blob_destroy (blob);
+    num_glyphs = hb_face_get_glyph_count (face);
+    font = hb_font_create (face);
+    hb_face_destroy (face);
+  }
+
+  if (is_var)
+  {
+    hb_variation_t wght = {HB_TAG ('w','g','h','t'), 500};
+    hb_font_set_variations (font, &wght, 1);
+  }
+
+  switch (backend)
+  {
+    case HARFBUZZ:
+      hb_ot_font_set_funcs (font);
+      break;
+
+    case FREETYPE:
+#ifdef HAVE_FREETYPE
+      hb_ft_font_set_funcs (font);
+#endif
+      break;
+  }
+
+  switch (operation)
+  {
+    case nominal_glyphs:
+    {
+      hb_set_t *set = hb_set_create ();
+      hb_face_collect_unicodes (hb_font_get_face (font), set);
+      unsigned pop = hb_set_get_population (set);
+      hb_codepoint_t *unicodes = (hb_codepoint_t *) calloc (pop, sizeof (hb_codepoint_t));
+      hb_codepoint_t *glyphs = (hb_codepoint_t *) calloc (pop, sizeof (hb_codepoint_t));
+
+      hb_codepoint_t *p = unicodes;
+      for (hb_codepoint_t u = HB_SET_VALUE_INVALID;
+	   hb_set_next (set, &u);)
+        *p++ = u;
+      assert (p == unicodes + pop);
+
+      for (auto _ : state)
+	hb_font_get_nominal_glyphs (font,
+				    pop,
+				    unicodes, sizeof (*unicodes),
+				    glyphs, sizeof (*glyphs));
+
+      free (glyphs);
+      free (unicodes);
+      hb_set_destroy (set);
+      break;
+    }
+    case glyph_h_advances:
+    {
+      hb_codepoint_t *glyphs = (hb_codepoint_t *) calloc (num_glyphs, sizeof (hb_codepoint_t));
+      hb_position_t *advances = (hb_position_t *) calloc (num_glyphs, sizeof (hb_codepoint_t));
+
+      for (unsigned g = 0; g < num_glyphs; g++)
+        glyphs[g] = g;
+
+      for (auto _ : state)
+	hb_font_get_glyph_h_advances (font,
+				      num_glyphs,
+				      glyphs, sizeof (*glyphs),
+				      advances, sizeof (*advances));
+
+      free (advances);
+      free (glyphs);
+      break;
+    }
+    case glyph_extents:
+    {
+      hb_glyph_extents_t extents;
+      for (auto _ : state)
+	for (unsigned gid = 0; gid < num_glyphs; ++gid)
+	  hb_font_get_glyph_extents (font, gid, &extents);
+      break;
+    }
+    case draw_glyph:
+    {
+      hb_draw_funcs_t *draw_funcs = _draw_funcs_create ();
+      for (auto _ : state)
+      {
+	float i = 0;
+	for (unsigned gid = 0; gid < num_glyphs; ++gid)
+	  hb_font_draw_glyph (font, gid, draw_funcs, &i);
+      }
+      hb_draw_funcs_destroy (draw_funcs);
+      break;
+    }
+    case paint_glyph:
+    {
+      hb_paint_funcs_t *paint_funcs = hb_paint_funcs_create ();
+      for (auto _ : state)
+      {
+	for (unsigned gid = 0; gid < num_glyphs; ++gid)
+	  hb_font_paint_glyph (font, gid, paint_funcs, nullptr, 0, 0);
+      }
+      hb_paint_funcs_destroy (paint_funcs);
+      break;
+    }
+    case load_face_and_shape:
+    {
+      for (auto _ : state)
+      {
+	hb_blob_t *blob = hb_blob_create_from_file_or_fail (test_input.font_path);
+	assert (blob);
+	hb_face_t *face = hb_face_create (blob, 0);
+	hb_blob_destroy (blob);
+	hb_font_t *font = hb_font_create (face);
+	hb_face_destroy (face);
+
+	switch (backend)
+	{
+	  case HARFBUZZ:
+	    hb_ot_font_set_funcs (font);
+	    break;
+
+	  case FREETYPE:
+#ifdef HAVE_FREETYPE
+	    hb_ft_font_set_funcs (font);
+#endif
+	    break;
+	}
+
+	hb_buffer_t *buffer = hb_buffer_create ();
+	hb_buffer_add_utf8 (buffer, " ", -1, 0, -1);
+	hb_buffer_guess_segment_properties (buffer);
+
+	hb_shape (font, buffer, nullptr, 0);
+
+	hb_buffer_destroy (buffer);
+	hb_font_destroy (font);
+      }
+      break;
+    }
+  }
+
+
+  hb_font_destroy (font);
+}
+
+static void test_backend (backend_t backend,
+			  const char *backend_name,
+			  bool variable,
+			  operation_t op,
+			  const char *op_name,
+			  benchmark::TimeUnit time_unit,
+			  const test_input_t &test_input)
+{
+  char name[1024] = "BM_Font/";
+  strcat (name, op_name);
+  strcat (name, "/");
+  const char *p = strrchr (test_input.font_path, '/');
+  strcat (name, p ? p + 1 : test_input.font_path);
+  strcat (name, variable ? "/var" : "");
+  strcat (name, "/");
+  strcat (name, backend_name);
+
+  benchmark::RegisterBenchmark (name, BM_Font, variable, backend, op, test_input)
+   ->Unit(time_unit);
+}
+
+static void test_operation (operation_t op,
+			    const char *op_name,
+			    benchmark::TimeUnit time_unit)
+{
+  for (unsigned i = 0; i < num_tests; i++)
+  {
+    auto& test_input = tests[i];
+    for (int variable = 0; variable < int (test_input.is_variable) + 1; variable++)
+    {
+      bool is_var = (bool) variable;
+
+      test_backend (HARFBUZZ, "hb", is_var, op, op_name, time_unit, test_input);
+#ifdef HAVE_FREETYPE
+      test_backend (FREETYPE, "ft", is_var, op, op_name, time_unit, test_input);
+#endif
+    }
+  }
+}
+
+int main(int argc, char** argv)
+{
+  benchmark::Initialize(&argc, argv);
+
+  if (argc > 1)
+  {
+    num_tests = argc - 1;
+    tests = (test_input_t *) calloc (num_tests, sizeof (test_input_t));
+    for (unsigned i = 0; i < num_tests; i++)
+    {
+      tests[i].is_variable = true;
+      tests[i].font_path = argv[i + 1];
+    }
+  }
+
+#define TEST_OPERATION(op, time_unit) test_operation (op, #op, time_unit)
+
+  TEST_OPERATION (nominal_glyphs, benchmark::kMicrosecond);
+  TEST_OPERATION (glyph_h_advances, benchmark::kMicrosecond);
+  TEST_OPERATION (glyph_extents, benchmark::kMicrosecond);
+  TEST_OPERATION (draw_glyph, benchmark::kMicrosecond);
+  TEST_OPERATION (paint_glyph, benchmark::kMillisecond);
+  TEST_OPERATION (load_face_and_shape, benchmark::kMicrosecond);
+
+#undef TEST_OPERATION
+
+  benchmark::RunSpecifiedBenchmarks();
+  benchmark::Shutdown();
+
+  if (tests != default_tests)
+    free (tests);
+}

+ 110 - 0
hbfreetypefont.mod/harfbuzz/perf/benchmark-map.cc

@@ -0,0 +1,110 @@
+/*
+ * Benchmarks for hb_map_t operations.
+ */
+#include "benchmark/benchmark.h"
+
+#include <cassert>
+#include <cstdlib>
+#include "hb.h"
+
+void RandomMap(unsigned size, hb_map_t* out, hb_set_t* key_sample) {
+  hb_map_clear(out);
+
+  unsigned sample_denom = 1;
+  if (size > 10000)
+    sample_denom = size / 10000;
+
+  srand(size);
+  for (unsigned i = 0; i < size; i++) {
+    while (true) {
+      hb_codepoint_t next = rand();
+      if (hb_map_has (out, next)) continue;
+
+      hb_codepoint_t val = rand();
+      if (key_sample && val % sample_denom == 0)
+        hb_set_add (key_sample, next);
+      hb_map_set (out, next, val);
+      break;
+    }
+  }
+}
+
+/* Insert a single value into map of varying sizes. */
+static void BM_MapInsert(benchmark::State& state) {
+  unsigned map_size = state.range(0);
+
+  hb_map_t* original = hb_map_create ();
+  RandomMap(map_size, original, nullptr);
+  assert(hb_map_get_population(original) == map_size);
+
+  unsigned mask = 1;
+  while (mask < map_size)
+    mask <<= 1;
+  mask--;
+
+  auto needle = 0u;
+  for (auto _ : state) {
+    // TODO(garretrieger): create a copy of the original map.
+    //                     Needs a hb_map_copy(..) in public api.
+
+    hb_map_set (original, needle++ & mask, 1);
+  }
+
+  hb_map_destroy(original);
+}
+BENCHMARK(BM_MapInsert)
+    ->Range(1 << 4, 1 << 20);
+
+/* Single value lookup on map of various sizes where the key is not present. */
+static void BM_MapLookupMiss(benchmark::State& state) {
+  unsigned map_size = state.range(0);
+
+  hb_map_t* original = hb_map_create ();
+  RandomMap(map_size, original, nullptr);
+  assert(hb_map_get_population(original) == map_size);
+
+  auto needle = map_size / 2;
+
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(
+        hb_map_get (original, needle++));
+  }
+
+  hb_map_destroy(original);
+}
+BENCHMARK(BM_MapLookupMiss)
+    ->Range(1 << 4, 1 << 20); // Map size
+
+/* Single value lookup on map of various sizes. */
+static void BM_MapLookupHit(benchmark::State& state) {
+  unsigned map_size = state.range(0);
+
+  hb_map_t* original = hb_map_create ();
+  hb_set_t* key_set = hb_set_create ();
+  RandomMap(map_size, original, key_set);
+  assert(hb_map_get_population(original) == map_size);
+
+  unsigned num_keys = hb_set_get_population (key_set);
+  hb_codepoint_t* key_array =
+    (hb_codepoint_t*) calloc (num_keys, sizeof(hb_codepoint_t));
+  
+  hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+  unsigned i = 0;
+  while (hb_set_next (key_set, &cp))
+    key_array[i++] = cp;
+
+  i = 0;
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(
+        hb_map_get (original, key_array[i++ % num_keys]));
+  }
+
+  hb_set_destroy (key_set);
+  free (key_array);
+  hb_map_destroy(original);
+}
+BENCHMARK(BM_MapLookupHit)
+    ->Range(1 << 4, 1 << 20); // Map size
+
+
+BENCHMARK_MAIN();

+ 44 - 0
hbfreetypefont.mod/harfbuzz/perf/benchmark-ot.cc

@@ -0,0 +1,44 @@
+/*
+ * Benchmarks for hb_set_t operations.
+ */
+#include "benchmark/benchmark.h"
+
+#include "hb-ot.h"
+
+static void BM_hb_ot_tags_from_script_and_language (benchmark::State& state,
+						    hb_script_t script,
+						    const char *language_str) {
+
+  hb_language_t language = hb_language_from_string (language_str, -1);
+
+  for (auto _ : state)
+  {
+    hb_tag_t script_tags[HB_OT_MAX_TAGS_PER_SCRIPT];
+    unsigned script_count = HB_OT_MAX_TAGS_PER_SCRIPT;
+
+    hb_tag_t language_tags[HB_OT_MAX_TAGS_PER_LANGUAGE];
+    unsigned language_count = HB_OT_MAX_TAGS_PER_LANGUAGE;
+
+    hb_ot_tags_from_script_and_language (script,
+					 language,
+					 &script_count /* IN/OUT */,
+					 script_tags /* OUT */,
+					 &language_count /* IN/OUT */,
+					 language_tags /* OUT */);
+  }
+}
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON zh_abcd, HB_SCRIPT_COMMON, "zh_abcd");
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON zh_hans, HB_SCRIPT_COMMON, "zh_hans");
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON ab_abcd, HB_SCRIPT_COMMON, "ab_abcd");
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON ab_abc, HB_SCRIPT_COMMON, "ab_abc");
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON abcdef_XY, HB_SCRIPT_COMMON, "abcdef_XY");
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON abcd_XY, HB_SCRIPT_COMMON, "abcd_XY");
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON cxy_CN, HB_SCRIPT_COMMON, "cxy_CN");
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON exy_CN, HB_SCRIPT_COMMON, "exy_CN");
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON zh_CN, HB_SCRIPT_COMMON, "zh_CN");
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON en_US, HB_SCRIPT_COMMON, "en_US");
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, LATIN en_US, HB_SCRIPT_LATIN, "en_US");
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, COMMON none, HB_SCRIPT_LATIN, nullptr);
+BENCHMARK_CAPTURE (BM_hb_ot_tags_from_script_and_language, LATIN none, HB_SCRIPT_LATIN, nullptr);
+
+BENCHMARK_MAIN();

+ 151 - 0
hbfreetypefont.mod/harfbuzz/perf/benchmark-set.cc

@@ -0,0 +1,151 @@
+/*
+ * Benchmarks for hb_set_t operations.
+ */
+#include "benchmark/benchmark.h"
+
+#include <cassert>
+#include <cstdlib>
+#include "hb.h"
+
+void RandomSet(unsigned size, unsigned max_value, hb_set_t* out) {
+  hb_set_clear(out);
+
+  srand(size * max_value);
+  for (unsigned i = 0; i < size; i++) {
+    while (true) {
+      unsigned next = rand() % max_value;
+      if (hb_set_has (out, next)) continue;
+
+      hb_set_add(out, next);
+      break;
+    }
+  }
+}
+
+// TODO(garretrieger): benchmark union/subtract/intersection etc.
+
+/* Insert a 1000 values into set of varying sizes. */
+static void BM_SetInsert_1000(benchmark::State& state) {
+  unsigned set_size = state.range(0);
+  unsigned max_value = state.range(0) * state.range(1);
+
+  hb_set_t* original = hb_set_create ();
+  RandomSet(set_size, max_value, original);
+  assert(hb_set_get_population(original) == set_size);
+
+  for (auto _ : state) {
+    state.PauseTiming ();
+    hb_set_t* data = hb_set_copy(original);
+    state.ResumeTiming ();
+    for (int i = 0; i < 1000; i++) {
+      hb_set_add(data, i * 2654435761u % max_value);
+    }
+    hb_set_destroy(data);
+  }
+
+  hb_set_destroy(original);
+}
+BENCHMARK(BM_SetInsert_1000)
+    ->Unit(benchmark::kMicrosecond)
+    ->Ranges(
+        {{1 << 10, 1 << 16}, // Set Size
+         {2, 512}});          // Density
+
+/* Insert a 1000 values into set of varying sizes. */
+static void BM_SetOrderedInsert_1000(benchmark::State& state) {
+  unsigned set_size = state.range(0);
+  unsigned max_value = state.range(0) * state.range(1);
+
+  hb_set_t* original = hb_set_create ();
+  RandomSet(set_size, max_value, original);
+  assert(hb_set_get_population(original) == set_size);
+
+  for (auto _ : state) {
+    state.PauseTiming ();
+    hb_set_t* data = hb_set_copy(original);
+    state.ResumeTiming ();
+    for (int i = 0; i < 1000; i++) {
+      hb_set_add(data, i);
+    }
+    hb_set_destroy(data);
+  }
+
+  hb_set_destroy(original);
+}
+BENCHMARK(BM_SetOrderedInsert_1000)
+    ->Unit(benchmark::kMicrosecond)
+    ->Ranges(
+        {{1 << 10, 1 << 16}, // Set Size
+         {2, 512}});          // Density
+
+/* Single value lookup on sets of various sizes. */
+static void BM_SetLookup(benchmark::State& state, unsigned interval) {
+  unsigned set_size = state.range(0);
+  unsigned max_value = state.range(0) * state.range(1);
+
+  hb_set_t* original = hb_set_create ();
+  RandomSet(set_size, max_value, original);
+  assert(hb_set_get_population(original) == set_size);
+
+  auto needle = max_value / 2;
+  for (auto _ : state) {
+    benchmark::DoNotOptimize(
+        hb_set_has (original, (needle += interval) % max_value));
+  }
+
+  hb_set_destroy(original);
+}
+BENCHMARK_CAPTURE(BM_SetLookup, ordered, 3)
+    ->Ranges(
+        {{1 << 10, 1 << 16}, // Set Size
+         {2, 512}});          // Density
+BENCHMARK_CAPTURE(BM_SetLookup, random, 12345)
+    ->Ranges(
+        {{1 << 10, 1 << 16}, // Set Size
+         {2, 512}});          // Density
+
+/* Full iteration of sets of varying sizes. */
+static void BM_SetIteration(benchmark::State& state) {
+  unsigned set_size = state.range(0);
+  unsigned max_value = state.range(0) * state.range(1);
+
+  hb_set_t* original = hb_set_create ();
+  RandomSet(set_size, max_value, original);
+  assert(hb_set_get_population(original) == set_size);
+
+  hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+  for (auto _ : state) {
+    hb_set_next (original, &cp);
+  }
+
+  hb_set_destroy(original);
+}
+BENCHMARK(BM_SetIteration)
+    ->Ranges(
+        {{1 << 10, 1 << 16}, // Set Size
+         {2, 512}});          // Density
+
+/* Set copy. */
+static void BM_SetCopy(benchmark::State& state) {
+  unsigned set_size = state.range(0);
+  unsigned max_value = state.range(0) * state.range(1);
+
+  hb_set_t* original = hb_set_create ();
+  RandomSet(set_size, max_value, original);
+  assert(hb_set_get_population(original) == set_size);
+
+  for (auto _ : state) {
+    hb_set_t *s = hb_set_create ();
+    hb_set_set (s, original);
+    hb_set_destroy (s);
+  }
+
+  hb_set_destroy(original);
+}
+BENCHMARK(BM_SetCopy)
+    ->Unit(benchmark::kMicrosecond)
+    ->Ranges(
+        {{1 << 10, 1 << 16}, // Set Size
+         {2, 512}});          // Density
+
+BENCHMARK_MAIN();

+ 180 - 0
hbfreetypefont.mod/harfbuzz/perf/benchmark-shape.cc

@@ -0,0 +1,180 @@
+#include "benchmark/benchmark.h"
+#include <cstring>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <cassert>
+
+#include "hb.h"
+#include "hb-ot.h"
+#ifdef HAVE_FREETYPE
+#include "hb-ft.h"
+#endif
+
+#define SUBSET_FONT_BASE_PATH "test/subset/data/fonts/"
+
+struct test_input_t
+{
+  const char *font_path;
+  const char *text_path;
+  bool is_variable;
+} default_tests[] =
+{
+
+  {"perf/fonts/NotoNastaliqUrdu-Regular.ttf",
+   "perf/texts/fa-thelittleprince.txt",
+   false},
+
+  {"perf/fonts/NotoNastaliqUrdu-Regular.ttf",
+   "perf/texts/fa-words.txt",
+   false},
+
+  {"perf/fonts/Amiri-Regular.ttf",
+   "perf/texts/fa-thelittleprince.txt",
+   false},
+
+  {SUBSET_FONT_BASE_PATH "NotoSansDevanagari-Regular.ttf",
+   "perf/texts/hi-words.txt",
+   false},
+
+  {"perf/fonts/Roboto-Regular.ttf",
+   "perf/texts/en-thelittleprince.txt",
+   false},
+
+  {"perf/fonts/Roboto-Regular.ttf",
+   "perf/texts/en-words.txt",
+   false},
+
+  {SUBSET_FONT_BASE_PATH "SourceSerifVariable-Roman.ttf",
+   "perf/texts/en-thelittleprince.txt",
+   true},
+};
+
+static test_input_t *tests = default_tests;
+static unsigned num_tests = sizeof (default_tests) / sizeof (default_tests[0]);
+
+enum backend_t { HARFBUZZ, FREETYPE };
+
+static void BM_Shape (benchmark::State &state,
+		      bool is_var,
+		      backend_t backend,
+		      const test_input_t &input)
+{
+  hb_font_t *font;
+  {
+    hb_blob_t *blob = hb_blob_create_from_file_or_fail (input.font_path);
+    assert (blob);
+    hb_face_t *face = hb_face_create (blob, 0);
+    hb_blob_destroy (blob);
+    font = hb_font_create (face);
+    hb_face_destroy (face);
+  }
+
+  if (is_var)
+  {
+    hb_variation_t wght = {HB_TAG ('w','g','h','t'), 500};
+    hb_font_set_variations (font, &wght, 1);
+  }
+
+  switch (backend)
+  {
+    case HARFBUZZ:
+      hb_ot_font_set_funcs (font);
+      break;
+
+    case FREETYPE:
+#ifdef HAVE_FREETYPE
+      hb_ft_font_set_funcs (font);
+#endif
+      break;
+  }
+
+  hb_blob_t *text_blob = hb_blob_create_from_file_or_fail (input.text_path);
+  assert (text_blob);
+  unsigned orig_text_length;
+  const char *orig_text = hb_blob_get_data (text_blob, &orig_text_length);
+
+  hb_buffer_t *buf = hb_buffer_create ();
+  for (auto _ : state)
+  {
+    unsigned text_length = orig_text_length;
+    const char *text = orig_text;
+
+    const char *end;
+    while ((end = (const char *) memchr (text, '\n', text_length)))
+    {
+      hb_buffer_clear_contents (buf);
+      hb_buffer_add_utf8 (buf, text, text_length, 0, end - text);
+      hb_buffer_guess_segment_properties (buf);
+      hb_shape (font, buf, nullptr, 0);
+
+      unsigned skip = end - text + 1;
+      text_length -= skip;
+      text += skip;
+    }
+  }
+  hb_buffer_destroy (buf);
+
+  hb_blob_destroy (text_blob);
+  hb_font_destroy (font);
+}
+
+static void test_backend (backend_t backend,
+			  const char *backend_name,
+			  bool variable,
+			  const test_input_t &test_input)
+{
+  char name[1024] = "BM_Shape";
+  const char *p;
+  strcat (name, "/");
+  p = strrchr (test_input.font_path, '/');
+  strcat (name, p ? p + 1 : test_input.font_path);
+  strcat (name, "/");
+  p = strrchr (test_input.text_path, '/');
+  strcat (name, p ? p + 1 : test_input.text_path);
+  strcat (name, variable ? "/var" : "");
+  strcat (name, "/");
+  strcat (name, backend_name);
+
+  benchmark::RegisterBenchmark (name, BM_Shape, variable, backend, test_input)
+   ->Unit(benchmark::kMillisecond);
+}
+
+int main(int argc, char** argv)
+{
+  benchmark::Initialize(&argc, argv);
+
+  if (argc > 2)
+  {
+    num_tests = (argc - 1) / 2;
+    tests = (test_input_t *) calloc (num_tests, sizeof (test_input_t));
+    for (unsigned i = 0; i < num_tests; i++)
+    {
+      tests[i].is_variable = true;
+      tests[i].font_path = argv[1 + i * 2];
+      tests[i].text_path = argv[2 + i * 2];
+    }
+  }
+
+  for (unsigned i = 0; i < num_tests; i++)
+  {
+    auto& test_input = tests[i];
+    for (int variable = 0; variable < int (test_input.is_variable) + 1; variable++)
+    {
+      bool is_var = (bool) variable;
+
+      test_backend (HARFBUZZ, "hb", is_var, test_input);
+#ifdef HAVE_FREETYPE
+      test_backend (FREETYPE, "ft", is_var, test_input);
+#endif
+    }
+  }
+
+  benchmark::RunSpecifiedBenchmarks();
+  benchmark::Shutdown();
+
+  if (tests != default_tests)
+    free (tests);
+}

+ 287 - 0
hbfreetypefont.mod/harfbuzz/perf/benchmark-subset.cc

@@ -0,0 +1,287 @@
+#include "benchmark/benchmark.h"
+#include <cassert>
+#include <cstring>
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include "hb-subset.h"
+
+
+enum operation_t
+{
+  subset_glyphs,
+  subset_unicodes,
+  instance,
+};
+
+struct axis_location_t
+{
+  hb_tag_t axis_tag;
+  float axis_value;
+};
+
+static const axis_location_t
+_roboto_flex_instance_opts[] =
+{
+  {HB_TAG ('w', 'g', 'h', 't'), 600.f},
+  {HB_TAG ('w', 'd', 't', 'h'), 75.f},
+  {HB_TAG ('o', 'p', 's', 'z'), 90.f},
+  {HB_TAG ('G', 'R', 'A', 'D'), -100.f},
+  {HB_TAG ('s', 'l', 'n', 't'), -3.f},
+  {HB_TAG ('X', 'T', 'R', 'A'), 500.f},
+  {HB_TAG ('X', 'O', 'P', 'Q'), 150.f},
+  {HB_TAG ('Y', 'O', 'P', 'Q'), 100.f},
+  {HB_TAG ('Y', 'T', 'L', 'C'), 480.f},
+  {HB_TAG ('Y', 'T', 'U', 'C'), 600.f},
+  {HB_TAG ('Y', 'T', 'A', 'S'), 800.f},
+  {HB_TAG ('Y', 'T', 'D', 'E'), -50.f},
+  {HB_TAG ('Y', 'T', 'F', 'I'), 600.f},
+};
+
+static const axis_location_t
+_mplus_instance_opts[] =
+{
+  {HB_TAG ('w', 'g', 'h', 't'), 800.f},
+};
+
+static const axis_location_t
+_fraunces_partial_instance_opts[] =
+{
+  {HB_TAG ('S', 'O', 'F', 'T'), 75.0f},
+  {HB_TAG ('W', 'O', 'N', 'K'), 0.75f},
+};
+
+template <typename Type, unsigned int n>
+static inline unsigned int ARRAY_LEN (const Type (&)[n]) { return n; }
+
+#define SUBSET_FONT_BASE_PATH "test/subset/data/fonts/"
+
+struct test_input_t
+{
+  const char *font_path;
+  unsigned max_subset_size;
+  const axis_location_t *instance_opts;
+  unsigned num_instance_opts;
+} default_tests[] =
+{
+  {SUBSET_FONT_BASE_PATH "Roboto-Regular.ttf", 1000, nullptr, 0},
+  {SUBSET_FONT_BASE_PATH "Amiri-Regular.ttf", 4096, nullptr, 0},
+  {SUBSET_FONT_BASE_PATH "NotoNastaliqUrdu-Regular.ttf", 1400, nullptr, 0},
+  {SUBSET_FONT_BASE_PATH "NotoSansDevanagari-Regular.ttf", 1000, nullptr, 0},
+  {SUBSET_FONT_BASE_PATH "Mplus1p-Regular.ttf", 10000, nullptr, 0},
+  {SUBSET_FONT_BASE_PATH "SourceHanSans-Regular_subset.otf", 10000, nullptr, 0},
+  {SUBSET_FONT_BASE_PATH "SourceSansPro-Regular.otf", 2000, nullptr, 0},
+  {SUBSET_FONT_BASE_PATH "AdobeVFPrototype.otf", 300, nullptr, 0},
+  {SUBSET_FONT_BASE_PATH "MPLUS1-Variable.ttf", 6000, _mplus_instance_opts, ARRAY_LEN (_mplus_instance_opts)},
+  {SUBSET_FONT_BASE_PATH "RobotoFlex-Variable.ttf", 900, _roboto_flex_instance_opts, ARRAY_LEN (_roboto_flex_instance_opts)},
+  {SUBSET_FONT_BASE_PATH "Fraunces.ttf", 900, _fraunces_partial_instance_opts, ARRAY_LEN (_fraunces_partial_instance_opts)},
+#if 0
+  {"perf/fonts/NotoSansCJKsc-VF.ttf", 100000},
+#endif
+};
+
+static test_input_t *tests = default_tests;
+static unsigned num_tests = sizeof (default_tests) / sizeof (default_tests[0]);
+
+
+void AddCodepoints(const hb_set_t* codepoints_in_font,
+                   unsigned subset_size,
+                   hb_subset_input_t* input)
+{
+  auto *unicodes = hb_subset_input_unicode_set (input);
+  hb_codepoint_t cp = HB_SET_VALUE_INVALID;
+  for (unsigned i = 0; i < subset_size; i++) {
+    // TODO(garretrieger): pick randomly.
+    if (!hb_set_next (codepoints_in_font, &cp)) return;
+    hb_set_add (unicodes, cp);
+  }
+}
+
+void AddGlyphs(unsigned num_glyphs_in_font,
+               unsigned subset_size,
+               hb_subset_input_t* input)
+{
+  auto *glyphs = hb_subset_input_glyph_set (input);
+  for (unsigned i = 0; i < subset_size && i < num_glyphs_in_font; i++) {
+    if (i + 1 == subset_size &&
+        hb_subset_input_get_flags (input) & HB_SUBSET_FLAGS_RETAIN_GIDS)
+    {
+      hb_set_add (glyphs, num_glyphs_in_font - 1);
+      continue;
+    }
+    hb_set_add (glyphs, i);
+  }
+}
+
+// Preprocess face and populate the subset accelerator on it to speed up
+// the subsetting operations.
+static hb_face_t* preprocess_face(hb_face_t* face)
+{
+  hb_face_t* new_face = hb_subset_preprocess(face);
+  hb_face_destroy(face);
+  return new_face;
+}
+
+static hb_face_t *cached_face;
+
+static void
+free_cached_face (void)
+{
+  hb_face_destroy (cached_face);
+  cached_face = nullptr;
+}
+
+
+/* benchmark for subsetting a font */
+static void BM_subset (benchmark::State &state,
+                       operation_t operation,
+                       const test_input_t &test_input,
+                       bool retain_gids)
+{
+  unsigned subset_size = state.range(0);
+
+  hb_face_t *face = nullptr;
+
+  static const char *cached_font_path;
+
+  if (!cached_font_path || strcmp (cached_font_path, test_input.font_path))
+  {
+    hb_blob_t *blob = hb_blob_create_from_file_or_fail (test_input.font_path);
+    assert (blob);
+    face = hb_face_create (blob, 0);
+    hb_blob_destroy (blob);
+
+    face = preprocess_face (face);
+
+    if (cached_face)
+      hb_face_destroy (cached_face);
+
+    cached_face = hb_face_reference (face);
+    cached_font_path = test_input.font_path;
+  }
+  else
+    face = hb_face_reference (cached_face);
+
+  hb_subset_input_t* input = hb_subset_input_create_or_fail ();
+  assert (input);
+
+  if (retain_gids)
+    hb_subset_input_set_flags (input, HB_SUBSET_FLAGS_RETAIN_GIDS);
+
+  switch (operation)
+  {
+    case subset_unicodes:
+    {
+      hb_set_t* all_codepoints = hb_set_create ();
+      hb_face_collect_unicodes (face, all_codepoints);
+      AddCodepoints(all_codepoints, subset_size, input);
+      hb_set_destroy (all_codepoints);
+    }
+    break;
+
+    case subset_glyphs:
+    {
+      unsigned num_glyphs = hb_face_get_glyph_count (face);
+      AddGlyphs(num_glyphs, subset_size, input);
+    }
+    break;
+
+    case instance:
+    {
+      hb_set_t* all_codepoints = hb_set_create ();
+      hb_face_collect_unicodes (face, all_codepoints);
+      AddCodepoints(all_codepoints, subset_size, input);
+      hb_set_destroy (all_codepoints);
+
+      hb_subset_input_set_flags(input, hb_subset_input_get_flags(input) | HB_SUBSET_FLAGS_OPTIMIZE_IUP_DELTAS);
+
+      for (unsigned i = 0; i < test_input.num_instance_opts; i++)
+        hb_subset_input_pin_axis_location (input, face,
+                                           test_input.instance_opts[i].axis_tag,
+                                           test_input.instance_opts[i].axis_value);
+    }
+    break;
+  }
+
+  for (auto _ : state)
+  {
+    hb_face_t* subset = hb_subset_or_fail (face, input);
+    assert (subset);
+    hb_face_destroy (subset);
+  }
+
+  hb_subset_input_destroy (input);
+  hb_face_destroy (face);
+}
+
+static void test_subset (operation_t op,
+                         const char *op_name,
+                         bool retain_gids,
+                         benchmark::TimeUnit time_unit,
+                         const test_input_t &test_input)
+{
+  if (op == instance && test_input.instance_opts == nullptr)
+    return;
+
+  char name[1024] = "BM_subset/";
+  strcat (name, op_name);
+  strcat (name, "/");
+  const char *p = strrchr (test_input.font_path, '/');
+  strcat (name, p ? p + 1 : test_input.font_path);
+  if (retain_gids)
+    strcat (name, "/retaingids");
+
+  benchmark::RegisterBenchmark (name, BM_subset, op, test_input, retain_gids)
+      ->Range(10, test_input.max_subset_size)
+      ->Unit(time_unit);
+}
+
+static void test_operation (operation_t op,
+                            const char *op_name,
+                            const test_input_t *tests,
+                            unsigned num_tests,
+                            benchmark::TimeUnit time_unit)
+{
+  for (unsigned i = 0; i < num_tests; i++)
+  {
+    auto& test_input = tests[i];
+    test_subset (op, op_name, true, time_unit, test_input);
+    test_subset (op, op_name, false, time_unit, test_input);
+  }
+}
+
+int main(int argc, char** argv)
+{
+  benchmark::Initialize(&argc, argv);
+
+#ifndef HB_NO_ATEXIT
+  atexit (free_cached_face);
+#endif
+
+  if (argc > 1)
+  {
+    num_tests = (argc - 1) / 2;
+    tests = (test_input_t *) calloc (num_tests, sizeof (test_input_t));
+    for (unsigned i = 0; i < num_tests; i++)
+    {
+      tests[i].font_path = argv[1 + i * 2];
+      tests[i].max_subset_size = atoi (argv[2 + i * 2]);
+    }
+  }
+
+#define TEST_OPERATION(op, time_unit) test_operation (op, #op, tests, num_tests, time_unit)
+
+  TEST_OPERATION (subset_glyphs, benchmark::kMicrosecond);
+  TEST_OPERATION (subset_unicodes, benchmark::kMicrosecond);
+  TEST_OPERATION (instance, benchmark::kMicrosecond);
+
+#undef TEST_OPERATION
+
+  benchmark::RunSpecifiedBenchmarks();
+  benchmark::Shutdown();
+
+  if (tests != default_tests)
+    free (tests);
+}

BIN
hbfreetypefont.mod/harfbuzz/perf/fonts/Amiri-Regular.ttf


BIN
hbfreetypefont.mod/harfbuzz/perf/fonts/NotoNastaliqUrdu-Regular.ttf


BIN
hbfreetypefont.mod/harfbuzz/perf/fonts/Roboto-Regular.ttf


+ 62 - 0
hbfreetypefont.mod/harfbuzz/perf/meson.build

@@ -0,0 +1,62 @@
+google_benchmark = subproject('google-benchmark')
+google_benchmark_dep = google_benchmark.get_variable('google_benchmark_dep')
+
+benchmark('benchmark-font', executable('benchmark-font', 'benchmark-font.cc',
+  dependencies: [
+    google_benchmark_dep, freetype_dep,
+  ],
+  cpp_args: [],
+  include_directories: [incconfig, incsrc],
+  link_with: [libharfbuzz],
+  install: false,
+), workdir: meson.current_source_dir() / '..', timeout: 100)
+
+benchmark('benchmark-map', executable('benchmark-map', 'benchmark-map.cc',
+  dependencies: [
+    google_benchmark_dep,
+  ],
+  cpp_args: [],
+  include_directories: [incconfig, incsrc],
+  link_with: [libharfbuzz],
+  install: false,
+), workdir: meson.current_source_dir() / '..', timeout: 100)
+
+benchmark('benchmark-ot', executable('benchmark-ot', 'benchmark-ot.cc',
+  dependencies: [
+    google_benchmark_dep,
+  ],
+  cpp_args: [],
+  include_directories: [incconfig, incsrc],
+  link_with: [libharfbuzz],
+  install: false,
+), workdir: meson.current_source_dir() / '..', timeout: 100)
+
+benchmark('benchmark-set', executable('benchmark-set', 'benchmark-set.cc',
+  dependencies: [
+    google_benchmark_dep,
+  ],
+  cpp_args: [],
+  include_directories: [incconfig, incsrc],
+  link_with: [libharfbuzz],
+  install: false,
+), workdir: meson.current_source_dir() / '..', timeout: 100)
+
+benchmark('benchmark-shape', executable('benchmark-shape', 'benchmark-shape.cc',
+  dependencies: [
+    google_benchmark_dep, freetype_dep,
+  ],
+  cpp_args: [],
+  include_directories: [incconfig, incsrc],
+  link_with: [libharfbuzz],
+  install: false,
+), workdir: meson.current_source_dir() / '..', timeout: 100)
+
+benchmark('benchmark-subset', executable('benchmark-subset', 'benchmark-subset.cc',
+  dependencies: [
+    google_benchmark_dep,
+  ],
+  cpp_args: [],
+  include_directories: [incconfig, incsrc],
+  link_with: [libharfbuzz, libharfbuzz_subset],
+  install: false,
+), workdir: meson.current_source_dir() / '..', timeout: 100)

Fichier diff supprimé car celui-ci est trop grand
+ 6 - 0
hbfreetypefont.mod/harfbuzz/perf/texts/duployan.txt


+ 1893 - 0
hbfreetypefont.mod/harfbuzz/perf/texts/en-thelittleprince.txt

@@ -0,0 +1,1893 @@
+Downloaded from https://archive.org/details/TheLittlePrince-English
+
+THE LITTLE PRINCE
+
+
+
+Antoine De Saint-Exupery
+
+
+
+
+Antoine de Saint-Exupery, who was a French author, journalist and pilot wrote
+The Little Prince in 1943, one year before his death.
+
+The Little Prince appears to be a simple children’s tale,
+some would say that it is actually a profound and deeply moving tale,
+written in riddles and laced with philosophy and poetic metaphor.
+
+
+
+
+Once when I was six years old I saw a magnificent picture in a book, called True Stories from
+Nature, about the primeval forest. It was a picture of a boa constrictor in the act of swallowing an
+animal. Here is a copy of the drawing.
+
+In the book it said: “Boa constrictors swallow their prey whole, without chewing it. After that they
+are not able to move, and they sleep through the six months that they need for digestion.” I
+pondered deeply, then, over the adventures of the jungle. And after some work with a coloured
+pencil I succeeded in making my first drawing. My Drawing Number One. It looked like this:
+
+
+
+
+I showed my masterpiece to the grown-ups, and asked them whether the drawing frightened them.
+But they answered: “Frighten? Why should any one be frightened by a hat?” My drawing was not
+a picture of a hat. It was a picture of a boa constrictor digesting an elephant. But since the grown-
+ups were not able to understand it, I made another drawing: I drew the inside of the boa
+constrictor, so that the grown-ups could see it clearly. They always need to have things explained.
+
+
+
+My Drawing Number Two looked like this:
+
+
+
+
+The grown-ups’ response, this time, was to advise me to lay aside my drawings of boa
+constrictors, whether from the inside or the outside, and devote myself instead to geography,
+history, arithmetic and grammar. That is why, at the age of six, I gave up what might have been a
+magnificent career as a painter. I had been disheartened by the failure of my Drawing Number
+One and my Drawing Number Two. Grown-ups never understand anything by themselves, and it is
+tiresome for children to be always and forever explaining things to them.
+
+So then I chose another profession, and learned to pilot air-planes. I have flown a little over all
+parts of the world; and it is true that geography has been very useful to me. At a glance I can
+distinguish China from Arizona. If one gets lost in the night, such knowledge is valuable. In the
+course of this life I have had a great many encounters with a great many people who have been
+concerned with matters of consequence. I have lived a great deal among grown-ups. I have seen
+them intimately, close at hand. And that hasn’t much improved my opinion of them.
+
+Whenever I met one of them who seemed to me at all clear-sighted, I tried the experiment of
+showing him my Drawing Number One, which I have always kept. I would try to find out, so, if this
+was a person of true understanding. But, whoever it was, he, or she, would always say: “That is a
+hat.” Then I would never talk to that person about boa constrictors, or primeval forests, or stars. I
+would bring myself down to his level. I would talk to him about bridge, and golf, and politics, and
+neckties. And the grown-up would be greatly pleased to have met such a sensible man.
+
+So I lived my life alone, without anyone that I could really talk to, until I had an accident with my
+plane in the Desert of Sahara, six years ago. Something was broken in my engine. And as I had
+with me neither a mechanic nor any passengers, I set myself to attempt the difficult repairs all
+alone. It was a question of life or death for me: I had scarcely enough drinking water to last a
+week.
+
+The first night, then, I went to sleep on the sand, a thousand miles from any human habitation. I
+was more isolated than a shipwrecked sailor on a raft in the middle of the ocean. Thus you can
+imagine my amazement, at sunrise, when I was awakened by an odd little voice.
+
+
+
+
+It said: “If you please, draw me a sheep!”
+
+“What!”
+
+“Draw me a sheep!”
+
+I jumped to my feet, completely thunderstruck. I blinked my eyes hard. I looked carefully all
+around me. And I saw a most extraordinary small person, who stood there examining me with
+great seriousness. Here you may see the best portrait that, later, I was able to make of him. But
+my drawing is certainly very much less charming than its model.
+
+That, however, is not my fault. The grown-ups discouraged me in my painter’s career when I was
+six years old, and I never learned to draw anything, except boas from the outside and boas from
+the inside.
+
+Now I stared at this sudden apparition with my eyes fairly starting out of my head in
+astonishment. Remember, I had crashed in the desert a thousand miles from any inhabited region.
+And yet my little man seemed neither to be straying uncertainly among the sands, nor to be
+fainting from fatigue or hunger or thirst or fear. Nothing about him gave any suggestion of a child
+lost in the middle of the desert, a thousand miles from any human habitation.
+
+When at last I was able to speak, I said to him: “But, what are you doing here?” And in answer he
+repeated, very slowly, as if he were speaking of a matter of great consequence:
+
+“If you please, draw me a sheep...”
+
+When a mystery is too overpowering, one dare not disobey. Absurd as it might seem to me, a
+thousand miles from any human habitation and in danger of death, I took out of my pocket a sheet
+of paper and my fountain pen. But then I remembered how my studies had been concentrated on
+geography, history, arithmetic, and grammar, and I told the little chap (a little crossly, too) that I
+did not know how to draw. He answered me: “That doesn’t matter. Draw me a sheep...”
+
+
+
+
+But I had never drawn a sheep. So I drew for him one of the two pictures I had drawn so often. It
+was that of the boa constrictor from the outside. And I was astounded to hear the little fellow
+greet it with, “No, no, no! I do not want an elephant inside a boa constrictor. A boa constrictor is a
+very dangerous creature, and an elephant is very cumbersome. Where I live, everything is very
+small. What I need is a sheep. Draw me a sheep.
+
+
+
+
+So then I made a drawing. He looked at it carefully, then he said: “No. This sheep is already very
+sickly. Make me another.” So I made another drawing. My friend smiled gently and indulgently.
+“You see yourself,” he said, “that this is not a sheep. This is a ram. It has horns.
+
+
+
+
+So then I did my drawing over once more. But it was rejected too, just like the others. “This one is
+too old. I want a sheep that will live a long time.
+
+By this time my patience was exhausted, because I was in a hurry to start taking my engine apart.
+So I tossed off this drawing. And I threw out an explanation with it.
+
+“This is only his box. The sheep you asked for is inside.”
+
+
+
+
+I was very surprised to see a light break over the face of my young judge:
+
+“That is exactly the way I wanted it! Do you think that this sheep will have to have a great deal of
+grass?”
+
+“Why?”
+
+“Because where I live everything is very small...”
+
+“There will surely be enough grass for him,” I said.
+
+“It is a very small sheep that I have given you.”
+
+He bent his head over the drawing: “Not so small that, Look! He has gone to sleep...”
+
+And that is how I made the acquaintance of the little prince.
+
+It took me a long time to learn where he came from. The little prince, who asked me so many
+questions, never seemed to hear the ones I asked him. It was from words dropped by chance that,
+little by little, everything was revealed to me.
+
+The first time he saw my air-plane, for instance (I shall not draw my air-plane; that would be much
+too complicated for me), he asked me: “What is that object?”
+
+“That is not an object. It flies. It is an air-plane. It is my air-plane.” And I was proud to have him
+learn that I could fly. He cried out, then: “What! You dropped down from the sky?”
+
+
+
+“Yes,” I answered, modestly.
+
+
+
+“Oh! That is funny!” And the little prince broke into a lovely peal of laughter, which irritated me
+very much. I like my misfortunes to be taken seriously.
+
+Then he added: “So you, too, come from the sky! Which is your planet?” At that moment I caught
+a gleam of light in the impenetrable mystery of his presence; and I demanded, abruptly: “Do you
+come from another planet?” But he did not reply. He tossed his head gently, without taking his
+eyes from my plane: “It is true that on that you can’t have come from very far away...” And he
+sank into a reverie, which lasted a long time. Then, taking my sheep out of his pocket, he buried
+himself in the contemplation of his treasure.
+
+You can imagine how my curiosity was aroused by this half-confidence about the “other planets.” I
+made a great effort, therefore, to find out more on this subject.
+
+“My little man, where do you come from? What is this ‘where I live,’ of which you speak? Where
+do you want to take your sheep?”
+
+After a reflective silence he answered: “The thing that is so good about the box you have given
+me is that at night he can use it as his house.”
+
+“That is so. And if you are good I will give you a string, too, so that you can tie him during the day,
+and a post to tie him to.”
+
+But the little prince seemed shocked by this offer: “Tie him! What a queer idea!”
+
+“But if you don’t tie him,” I said, “he will wander off somewhere, and get lost.”
+
+My friend broke into another peal of laughter: “But where do you think he would go?”
+“Anywhere. Straight ahead of him.”
+
+Then the little prince said, earnestly: “That doesn’t matter. Where I live, everything is so small!”
+And, with perhaps a hint of sadness, he added: “Straight ahead of him, nobody can go very far...”
+
+
+
+
+I had thus learned a second fact of great importance: this was that the planet the little prince
+came from was scarcely any larger than a house! But that did not really surprise me much. I knew
+very well that in addition to the great planets, such as the Earth, Jupiter, Mars, Venus, to which
+we have given names, there are also hundreds of others, some of which are so small that one has
+a hard time seeing them through the telescope.
+
+
+
+When an astronomer discovers one of these he does not give it a name, but only a number. He
+might call it, for example, “Asteroid 325.”
+
+
+
+
+I have serious reason to believe that the planet from which the little prince came is the asteroid
+known as B-612. This asteroid has only once been seen through the telescope. That was by a
+Turkish astronomer, in 1909.
+
+On making his discovery, the astronomer had presented it to the International Astronomical
+Congress, in a great demonstration. But he was in Turkish costume, and so nobody would believe
+what he said. Grown-ups are like that...
+
+Fortunately, however, for the reputation of Asteroid B-612, a Turkish dictator made a law that his
+subjects, under pain of death, should change to European costume. So in 1920 the astronomer
+gave his demonstration all over again, dressed with impressive style and elegance. And this time
+everybody accepted his report.
+
+If I have told you these details about the asteroid, and made a note of its number for you, it is on
+account of the grown-ups and their ways. When you tell them that you have made a new friend,
+they never ask you any questions about essential matters. They never say to you, “What does his
+voice sound like? What games does he love best? Does he collect butterflies?” Instead, they
+demand: “How old is he? How many brothers has he? How much does he weigh? How much
+money does his father make?”
+
+Only from these figures do they think they have learned anything about him.
+
+If you were to say to the grown-ups: “I saw a beautiful house made of rosy brick, with geraniums
+in the windows and doves on the roof,” they would not be able to get any idea of that house at all.
+
+You would have to say to them: “I saw a house that cost $ 20,000.” Then they would exclaim: “Oh,
+what a pretty house that is!” Just so, you might say to them: “The proof that the little prince
+existed is that he was charming, that he laughed, and that he was looking for a sheep. If anybody
+wants a sheep, that is a proof that he exists.” And what good would it do to tell them that? They
+would shrug their shoulders, and treat you like a child. But if you said to them: “The planet he
+came from is Asteroid B-612,” then they would be convinced, and leave you in peace from their
+questions. They are like that. One must not hold it against them. Children should always show
+great forbearance toward grown-up people. But certainly, for us who understand life, figures are a
+matter of indifference.
+
+I should have liked to begin this story in the fashion of the fairy-tales. I should have like to say:
+“Once upon a time there was a little prince who lived on a planet that was scarcely any bigger
+
+
+
+than himself, and who had need of a sheep...”
+
+
+
+To those who understand life, that would have given a much greater air of truth to my story. Fori
+do not want any one to read my book carelessly. I have suffered too much grief in setting down
+these memories. Six years have already passed since my friend went away from me, with his
+sheep. If I try to describe him here, it is to make sure that I shall not forget him. To forget a friend
+is sad. Not every one has had a friend. And if I forget him, I may become like the grown-ups who
+are no longer interested in anything but figures... It is for that purpose, again, that I have bought a
+box of paints and some pencils.
+
+It is hard to take up drawing again at my age, when I have never made any pictures except those
+of the boa constrictor from the outside and the boa constrictor from the inside, since I was six. I
+shall certainly try to make my portraits as true to life as possible. But I am not at all sure of
+success. One drawing goes along all right, and another has no resemblance to its subject. I make
+some errors, too, in the little prince’s height: in one place he is too tall and in another too short.
+And I feel some doubts about the colour of his costume. So I fumble along as best I can, now good,
+now bad, and I hope generally fair-to- middling. In certain more important details I shall make
+mistakes, also. But that is something that will not be my fault. My friend never explained anything
+to me. He thought, perhaps, that I was like himself. But I, alas, do not know how to see sheep
+through the walls of boxes. Perhaps I am a little like the grown-ups. I have had to grow old.
+
+As each day passed I would learn, in our talk, something about the little prince’s planet, his
+departure from it, his journey. The information would come very slowly, as it might chance to fall
+from his thoughts. It was in this way that I heard, on the third day, about the catastrophe of the
+baobabs.
+
+This time, once more, I had the sheep to thank for it. For the little prince asked me abruptly, as if
+seized by a grave doubt,
+
+“It is true, isn’t it, that sheep eat little bushes?”
+
+“Yes, that is true.”
+
+“Ah! I am glad!”
+
+I did not understand why it was so important that sheep should eat little bushes. But the little
+prince added: “Then it follows that they also eat baobabs?” I pointed out to the little prince that
+baobabs were not little bushes, but, on the contrary, trees as big as castles; and that even if he
+took a whole herd of elephants away with him, the herd would not eat up one single baobab.
+
+The idea of the herd of elephants made the little prince laugh. “We would have to put them one on
+top of the other,” he said. But he made a wise comment:
+
+“Before they grow so big, the baobabs start out by being little.”
+
+“That is strictly correct,” I said. “But why do you want the sheep to eat the little baobabs?”
+
+He answered me at once, “Oh, come, come!”, as if he were speaking of something that was self-
+evident. And I was obliged to make a great mental effort to solve this problem, without any
+assistance.
+
+Indeed, as I learned, there were on the planet where the little prince lived, as on all planets, good
+
+
+
+
+
+plants and bad plants. In consequence, there were good seeds from good plants, and bad seeds
+from bad plants. But seeds are invisible. They sleep deep in the heart of the earth’s darkness,
+until some one among them is seized with the desire to awaken. Then this little seed will stretch
+itself and begin, timidly at first, to push a charming little sprig inoffensively upward toward the
+sun. If it is only a sprout of radish or the sprig of a rose-bush, one would let it grow wherever it
+might wish. But when it is a bad plant, one must destroy it as soon as possible, the very first
+instant that one recognises it.
+
+Now there were some terrible seeds on the planet that was the home of the little prince; and these
+were the seeds of the baobab. The soil of that planet was infested with them. A baobab is
+something you will never, never be able to get rid of if you attend to it too late. It spreads over the
+entire planet. It bores clear through it with its roots. And if the planet is too small, and the
+baobabs are too many, they split it in pieces...
+
+“It is a question of discipline,” the little prince said to me later on.
+
+“When you’ve finished your own toilet in the morning, then it is time to attend to the toilet of your
+planet, just so, with the greatest care. You must see to it that you pull up regularly all the baobabs,
+at the very first moment when they can be distinguished from the rosebushes, which they
+resemble so closely in their earliest youth. It is very tedious work,” the little prince added, “but
+very easy.” And one day he said to me: “You ought to make a beautiful drawing, so that the
+children where you live can see exactly how all this is. That would be very useful to them if they
+were to travel some day.
+
+
+
+
+Sometimes,” he added, “there is no harm in putting off a piece of work until another day. But
+when it is a matter of baobabs, that always means a catastrophe.
+
+I knew a planet that was inhabited by a lazy man. He neglected three little bushes... So, as the
+little prince described it to me, I have made a drawing of that planet. I do not much like to take
+the tone of a moralist. But the danger of the baobabs is so little understood, and such considerable
+risks would be run by anyone who might get lost on an asteroid, that for once I am breaking
+through my reserve. “Children,” I say plainly, “watch out for the baobabs!” My friends, like
+myself, have been skirting this danger for a long time, without ever knowing it; and so it is for
+them that I have worked so hard over this drawing.
+
+The lesson which I pass on by this means is worth all the trouble it has cost me. Perhaps you will
+ask me, “Why are there no other drawing in this book as magnificent and impressive as this
+drawing of the baobabs?” The reply is simple. I have tried. But with the others I have not been
+successful. When I made the drawing of the baobabs I was carried beyond myself by the inspiring
+force of urgent necessity.
+
+Oh, little prince! Bit by bit I came to understand the secrets of your sad little life... For a long time
+you had found your only entertainment in the quiet pleasure of looking at the sunset.
+
+I learned that new detail on the morning of the fourth day, when you said to me:
+
+“I am very fond of sunsets. Come, let us go look at a sunset now.”
+
+“But we must wait,” I said.
+
+“Wait? For what?”
+
+“For the sunset. We must wait until it is time.”
+
+At first you seemed to be very much surprised. And then you laughed to yourself. You said to me:
+“I am always thinking that I am at home!”
+
+Just so. Everybody knows that when it is noon in the United States the sun is setting over France.
+If you could fly to France in one minute, you could go straight into the sunset, right from noon.
+Unfortunately, France is too far away for that. But on your tiny planet, my little prince, all you
+need do is move your chair a few steps. You can see the day end and the twilight falling whenever
+you like...
+
+“One day,” you said to me, “I saw the sunset forty-four times!”
+
+And a little later you added: “You know, one loves the sunset, when one is so sad...” “Were you so
+sad, then?” I asked, “on the day of the forty-four sunsets?”
+
+But the little prince made no reply.
+
+On the fifth day, again, as always, it was thanks to the sheep, the secret of the little prince’s life
+was revealed to me.
+
+Abruptly, without anything to lead up to it, and as if the question had been born of long and silent
+meditation on his problem, he demanded: “A sheep; if it eats little bushes, does it eat flowers,
+too?”
+
+
+
+
+“A sheep,” I answered, “eats anything it finds in its reach.”
+
+
+
+“Even flowers that have thorns?”
+
+“Yes, even flowers that have thorns.”
+
+“Then the thorns, what use are they?” I did not know.
+
+At that moment I was very busy trying to unscrew a bolt that had got stuck in my engine. I was
+very much worried, for it was becoming clear to me that the breakdown of my plane was
+extremely serious. And I had so little drinking water left that I had to fear for the worst.
+
+“The thorns, what use are they?”
+
+The little prince never let go of a question, once he had asked it. As for me, I was upset over that
+bolt. And I answered with the first thing that came into my head: “The thorns are of no use at all.
+Flowers have thorns just for spite!”
+
+“Oh!” There was a moment of complete silence.
+
+Then the little prince flashed back at me, with a kind of resentfulness: “I don’t believe you!
+Flowers are weak creatures. They are naive. They reassure themselves as best they can. They
+believe that their thorns are terrible weapons...”
+
+I did not answer. At that instant I was saying to myself: “If this bolt still won’t turn, I am going to
+knock it out with the hammer.”
+
+Again the little prince disturbed my thoughts. “And you actually believe that the flowers...”
+
+“Oh, no!” I cried. “No, no no! I don’t believe anything. I answered you with the first thing that
+came into my head. Don’t you see, I am very busy with matters of consequence!”
+
+He stared at me, thunderstruck. “Matters of consequence!”
+
+He looked at me there, with my hammer in my hand, my fingers black with engine grease, bending
+down over an object which seemed to him extremely ugly...
+
+“You talk just like the grown-ups!” That made me a little ashamed. But he went on, relentlessly:
+“You mix everything up together... You confuse everything...”
+
+He was really very angry. He tossed his golden curls in the breeze.
+
+“I know a planet where there is a certain red-faced gentleman. He has never smelled a flower. He
+has never looked at a star. He has never loved any one. He has never done anything in his life but
+add up figures. And all day he says over and over, just like you: ‘I am busy with matters of
+consequence!’ And that makes him swell up with pride.
+
+“But he is not a man, he is a mushroom!”
+
+
+
+“A what?”
+
+
+
+“A mushroom!” The little prince was now white with rage. “The flowers have been growing thorns
+for millions of years. For millions of years the sheep have been eating them just the same. And is
+it not a matter of consequence to try to understand why the flowers go to so much trouble to grow
+
+
+
+
+' '
+
+I \
+
+
+
+
+thorns, which are never of any use to them? Is the warfare between the sheep and the flowers not
+important? Is this not of more consequence than a fat red-faced gentleman’s sums? And if I know,
+I, myself, one flower which is unique in the world, which grows nowhere but on my planet, but
+which one little sheep can destroy in a single bite some morning, without even noticing what he is
+doing, Oh! You think that is not important! His face turned from white to red as he continued: “If
+some one loves a flower, of which just one single blossom grows in all the millions and millions of
+stars, it is enough to make him happy just to look at the stars.
+
+He can say to himself, ‘Somewhere, my flower is there...’ But if the sheep eats the flower, in one
+moment all his stars will be darkened... And you think that is not important!”
+
+He could not say anything more. His words were choked by sobbing. The night had fallen. I had
+let my tools drop from my hands. Of what moment now was my hammer, my bolt, or thirst, or
+death? On one star, one planet, my planet, the Earth, there was a little prince to be comforted. I
+took him in my arms, and rocked him. I said to him: “The flower that you love is not in danger. I
+will draw you a muzzle for your sheep. I will draw you a railing to put around your flower. I will...”
+
+I did not know what to say to him. I felt awkward and blundering. I did not know how I could reach
+him, where I could overtake him and go on hand in hand with him once more.
+
+It is such a secret place, the land of tears.
+
+I soon learned to know this flower better. On the little prince’s planet the flowers had always been
+very simple. They had only one ring of petals; they took up no room at all; they were a trouble to
+nobody. One morning they would appear in the grass, and by night they would have faded
+peacefully away. But one day, from a seed blown from no one knew where, a new flower had come
+up; and the little prince had watched very closely over this small sprout which was not like any
+other small sprouts on his planet.
+
+It might, you see, have been a new kind of baobab. The shrub soon stopped growing, and began to
+get ready to produce a flower. The little prince, who was present at the first appearance of a huge
+bud, felt at once that some sort of miraculous apparition must emerge from it. But the flower was
+not satisfied to complete the preparations for her beauty in the shelter of her green chamber. She
+
+
+
+chose her colours with the greatest care. She adjusted her petals one by one. She did not wish to
+go out into the world all rumpled, like the field poppies. It was only in the full radiance of her
+beauty that she wished to appear. Oh, yes! She was a coquettish creature! And her mysterious
+adornment lasted for days and days. Then one morning, exactly at sunrise, she suddenly showed
+herself. And, after working with all this painstaking precision, she yawned and said: “Ah! I am
+scarcely awake. I beg that you will excuse me. My petals are still all disarranged...” But the little
+prince could not restrain his admiration:
+
+“Oh! How beautiful you are!”
+
+“Am I not?” the flower responded, sweetly. “And I was born at the same moment as the sun...”
+
+The little prince could guess easily enough that she was not any too modest, but how moving, and
+exciting she was!
+
+“I think it is time for breakfast,” she added an instant later. “If you would have the kindness to
+think of my needs” And the little prince, completely abashed, went to look for a sprinkling can of
+fresh water.
+
+So, he tended the flower. So, too, she began very quickly to torment him with her vanity, which
+was, if the truth be known, a little difficult to deal with.
+
+One day, for instance, when she was speaking of her four thorns, she said to the little prince: “Let
+the tigers come with their claws!”
+
+“There are no tigers on my planet,” the little prince objected. “And, anyway, tigers do not eat
+weeds.”
+
+“I am not a weed,” the flower replied, sweetly. “Please excuse me...” “I am not at all afraid of
+tigers,” she went on, “but I have a horror of drafts. I suppose you wouldn’t screen for me?"
+
+“A horror of drafts, that is bad luck, for a plant,” remarked the little prince, and added to himself,
+“This flower is a very complex creature...”
+
+“At night I want you to put me under a glass globe. It is very cold where you live. In the place I
+came from...” But she interrupted herself at that point. She had come in the form of a seed. She
+could not have known anything of any other worlds.
+
+Embarrassed over having let herself be caught on the verge of such an untruth, she coughed two
+or three times, in order to put the little prince in the wrong.
+
+“The screen?”
+
+“I was just going to look for it when you spoke to me...”
+
+Then she forced her cough a little more so that he should suffer from remorse just the same. So
+the little prince, in spite of all the good will that was inseparable from his love, had soon come to
+doubt her. He had taken seriously words which were without importance, and it made him very
+unhappy.
+
+“I ought not to have listened to her,” he confided to me one day.
+
+“One never ought to listen to the flowers. One should simply look at them and breathe their
+
+
+
+
+fragrance. Mine perfumed all my planet. But I did not know how to take pleasure in all her grace.
+This tale of claws, which disturbed me so much, should only have filled my heart with tenderness
+and pity.”
+
+And he continued his confidences: “The fact is that I did not know how to understand anything! I
+ought to have judged by deeds and not by words. She cast her fragrance and her radiance over
+me. I ought never to have run away from her... I ought to have guessed all the affection that lay
+behind her poor little stratagems. Flowers are so inconsistent! But I was too young to know how to
+love her...”
+
+I believe that for his escape he took advantage of the migration of a flock of wild birds. On the
+morning of his departure he put his planet in perfect order. He carefully cleaned out his active
+volcanoes. He possessed two active volcanoes; and they were very convenient for heating his
+breakfast in the morning. He also had one volcano that was extinct. But, as he said, “One never
+knows!” So he cleaned out the extinct volcano, too. If they are well cleaned out, volcanoes burn
+slowly and steadily, without any eruptions. Volcanic eruptions are like fires in a chimney.
+
+On our earth we are obviously much too small to clean out our volcanoes. That is why they bring
+no end of trouble upon us. The little prince also pulled up, with a certain sense of dejection, the
+last little shoots of the baobabs. He believed that he would never want to return. But on this last
+morning all these familiar tasks seemed very precious to him. And when he watered the flower for
+the last time, and prepared to place her under the shelter of her glass globe, he realised that he
+was very close to tears. “Goodbye,” he said to the flower. But she made no answer. “Goodbye,”
+he said again. The flower coughed. But it was not because she had a cold.
+
+“I have been silly,” she said to him, at last. “I ask your forgiveness. Try to be happy...” He was
+surprised by this absence of reproaches. He stood there all bewildered, the glass globe held
+arrested in mid-air. He did not understand this quiet sweetness.
+
+“Of course I love you,” the flower said to him. “It is my fault that you have not known it all the
+while. That is of no importance. But you, you have been just as foolish as I. Try to be happy... let
+the glass globe be. I don’t want it any more.”
+
+“But the wind...” “My cold is not so bad as all that... the cool night air will do me good. I am a
+flower.”
+
+“But the animals...” “Well, I must endure the presence of two or three caterpillars if I wish to
+become acquainted with the butterflies. It seems that they are very beautiful. And if not the
+butterflies and the caterpillars who will call upon me? You will be far away... as for the large
+animals, I am not at all afraid of any of them. I have my claws.”
+
+And, naively, she showed her four thorns.
+
+Then she added: “Don’t linger like this. You have decided to go away. Now go!”
+
+For she did not want him to see her crying. She was such a proud flower...
+
+
+
+He found himself in the neighbourhood of the asteroids 325, 326, 327, 328, 329, and 330. He
+began, therefore, by visiting them, in order to add to his knowledge. The first of them was
+inhabited by a king. Clad in royal purple and ermine, he was seated upon a throne, which was at
+
+
+
+
+the same time both simple and majestic.
+
+
+
+“Ah! Here is a subject,” exclaimed the king, when he saw the little prince coming. And the little
+prince asked himself: “How could he recognise me when he had never seen me before?”
+
+He did not know how the world is simplified for kings. To them, all men are subjects. “Approach,
+so that I may see you better,” said the king, who felt consumingly proud of being at last a king
+over somebody.
+
+The little prince looked everywhere to find a place to sit down; but the entire planet was crammed
+and obstructed by the king’s magnificent ermine robe. So he remained standing upright, and, since
+he was tired, he yawned.
+
+“It is contrary to etiquette to yawn in the presence of a king,” the monarch said to him. “I forbid
+you to do so.”
+
+“I can’t help it. I can’t stop myself,” replied the little prince, thoroughly embarrassed.
+
+“I have come on a long journey, and I have had no sleep...”
+
+“Ah, then,” the king said. “I order you to yawn. It is years since I have seen anyone yawning.
+Yawns, to me, are objects of curiosity. Come, now! Yawn again! It is an order.”
+
+“That frightens me... I cannot, any more...” murmured the little prince, now completely abashed.
+
+“Hum! Hum!” replied the king. “Then I... I order you sometimes to yawn and sometimes to” He
+sputtered a little, and seemed vexed. For what the king fundamentally insisted upon was that his
+authority should be respected. He tolerated no disobedience. He was an absolute monarch. But,
+because he was a very good man, he made his orders reasonable.
+
+“If I ordered a general,” he would say, by way of example, “if I ordered a general to change
+himself into a sea bird, and if the general did not obey me, that would not be the fault of the
+general. It would be my fault.”
+
+“May I sit down?” came now a timid inquiry from the little prince. “I order you to do so,” the king
+answered him, and majestically gathered in a fold of his ermine mantle. But the little prince was
+wondering... The planet was tiny. Over what could this king really rule?
+
+“Sire,” he said to him, “I beg that you will excuse my asking you a question”
+
+“I order you to ask me a question,” the king hastened to assure him. “Sire, over what do you
+rule?” “Over everything,” said the king, with magnificent simplicity.
+
+“Over everything?” The king made a gesture, which took in his planet, the other planets, and all
+the stars. “Over all that?” asked the little prince. “Over all that,” the king answered. For his rule
+was not only absolute: it was also universal. “And the stars obey you?” “Certainly they do,” the
+king said. “They obey instantly. I do not permit insubordination.”
+
+Such power was a thing for the little prince to marvel at. If he had been master of such complete
+authority, he would have been able to watch the sunset, not forty-four times in one day, but
+seventy-two, or even a hundred, or even two hundred times, with out ever having to move his
+chair. And because he felt a bit sad as he remembered his little planet, which he had forsaken, he
+plucked up his courage to ask the king a favour:
+
+
+
+
+
+“I should like to see a sunset... do me that kindness... Order the sun to set...”
+
+“If I ordered a general to fly from one flower to another like a butterfly, or to write a tragic
+drama, or to change himself into a sea bird, and if the general did not carry out the order that he
+had received, which one of us would be in the wrong?” the king demanded. “The general, or
+myself?”
+
+“You,” said the little prince firmly.
+
+“Exactly. One much require from each one the duty which each one can perform,” the king went
+on. “Accepted authority rests first of all on reason. If you ordered your people to go and throw
+themselves into the sea, they would rise up in revolution. I have the right to require obedience
+because my orders are reasonable.”
+
+“Then my sunset?” the little prince reminded him: for he never forgot a question once he had
+asked it.
+
+“You shall have your sunset. I shall command it. But, according to my science of government, I
+shall wait until conditions are favourable.”
+
+“When will that be?” inquired the little prince. “Hum! Hum!” replied the king; and before saying
+anything else he consulted a bulky almanac. “Hum! Hum! That will be about... about... that will be
+this evening about twenty minutes to eight. And you will see how well I am obeyed.”
+
+The little prince yawned. He was regretting his lost sunset. And then, too, he was already
+beginning to be a little bored. “I have nothing more to do here,” he said to the king. “So I shall set
+out on my way again.” “Do not go,” said the king, who was very proud of having a subject. “Do
+not go. I will make you a Minister!” “Minister of what?” “Minster of...of Justice!” “But there is
+nobody here to judge!” “We do not know that,” the king said to him. “I have not yet made a
+complete tour of my kingdom. I am very old. There is no room here for a carriage. And it tires me
+to walk.” “Oh, but I have looked already!” said the little prince, turning around to give one more
+glance to the other side of the planet.
+
+On that side, as on this, there was nobody at all... “Then you shall judge yourself,” the king
+answered, “that is the most difficult thing of all. It is much more difficult to j udge oneself than to
+j udge others. If you succeed in j udging yourself rightly, then you are indeed a man of true
+wisdom.”
+
+
+
+“Yes,” said the little prince, “but I can judge myself anywhere. I do not need to live on this planet.
+“Hum! Hum!” said the king. “I have good reason to believe that somewhere on my planet there is
+an old rat. I hear him at night. You can judge this old rat. From time to time you will condemn him
+to death. Thus his life will depend on your j ustice. But you will pardon him on each occasion; for
+he must be treated thriftily. He is the only one we have.”
+
+“I,” replied the little prince, “do not like to condemn anyone to death. And now I think I will go on
+my way.” “No,” said the king. But the little prince, having now completed his preparations for
+departure, had no wish to grieve the old monarch. “If Your Majesty wishes to be promptly
+obeyed,” he said, “he should be able to give me a reasonable order. He should be able, for
+example, to order me to be gone by the end of one minute. It seems to me that conditions are
+favourable...” As the king made no answer, the little prince hesitated a moment.
+
+Then, with a sigh, he took his leave. “I made you my Ambassador,” the king called out, hastily.
+
+He had a magnificent air of authority.
+
+“The grown-ups are very strange,” the little prince said to himself, as he continued on his journey.
+The second planet was inhabited by a conceited man.
+
+
+
+
+
+
+
+
+
+
+“Ah! Ah! I am about to receive a visit from an admirer!” he exclaimed from afar, when he first
+saw the little prince coming. For, to conceited men, all other men are admirers.
+
+“Good morning,” said the little prince. “That is a queer hat you are wearing.”
+
+“It is a hat for salutes,” the conceited man replied. “It is to raise in salute when people acclaim
+me. Unfortunately, nobody at all ever passes this way.”
+
+“Yes?” said the little prince, who did not understand what the conceited man was talking about.
+
+“Clap your hands, one against the other,” the conceited man now directed him. The little prince
+clapped his hands. The conceited man raised his hat in a modest salute. “This is more entertaining
+than the visit to the king,” the little prince said to himself. And he began again to clap his hands,
+one against the other. The conceited man against raised his hat in salute. After five minutes of
+
+
+
+this exercise the little prince grew tired of the game’s monotony. “And what should one do to
+make the hat come down?” he asked. But the conceited man did not hear him. Conceited people
+never hear anything but praise.
+
+“Do you really admire me very much?” he demanded of the little prince. “What does that mean,
+‘admire’?”
+
+“To admire means that you regard me as the handsomest, the best-dressed, the richest, and the
+most intelligent man on this planet.” “But you are the only man on your planet!” “Do me this
+kindness. Admire me just the same.”
+
+“I admire you,” said the little prince, shrugging his shoulders slightly, “but what is there in that to
+interest you so much?”
+
+And the little prince went away. “The grown-ups are certainly very odd,” he said to himself, as he
+continued on his journey.
+
+The next planet was inhabited by a tippler.
+
+
+
+
+This was a very short visit, but it plunged the little prince into deep dejection. “What are you
+doing there?” he said to the tippler, whom he found settled down in silence before a collection of
+empty bottles and also a collection of full bottles.
+
+“I am drinking,” replied the tippler, with a lugubrious air.
+
+“Why are you drinking?” demanded the little prince.
+
+“So that I may forget,” replied the tippler. “Forget what?” inquired the little prince, who already
+was sorry for him.
+
+“Forget that I am ashamed,” the tippler confessed, hanging his head.
+
+“Ashamed of what?” insisted the little prince, who wanted to help him.
+
+“Ashamed of drinking!” The tippler brought his speech to an end, and shut himself up in an
+impregnable silence.
+
+And the little prince went away, puzzled. “The grown-ups are certainly very, very odd,” he said to
+himself, as he continued on his journey.
+
+The fourth planet belonged to a businessman.
+
+This man was so much occupied that he did not even raise his head at the little prince’s arrival.
+
+
+
+“Good morning,” the little prince said to him. “Your cigarette has gone out.”
+
+
+
+“Three and two make five. Five and seven make twelve. Twelve and three make fifteen. Good
+morning. Fifteen and seven make twenty-two. Twenty-two and six make twenty-eight. I haven’t
+time to light it again. Twenty-six and five make thirty-one. Phew ! Then that makes five-hundred-
+and-one-million, six-hundred-twenty-two-thousand, seven-hundred-thirty-one.”
+
+“Five hundred million what?” asked the little prince. “Eh? Are you still there? Five-hundred-and-
+one million, I can’t stop... I have so much to do! I am concerned with matters of consequence. I
+don’t amuse myself with balderdash. Two and five make seven...”
+
+“Five-hundred-and-one million what?” repeated the little prince, who never in his life had let go of
+a question once he had asked it.
+
+The businessman raised his head. “During the fifty-four years that I have inhabited this planet, I
+have been disturbed only three times. The first time was twenty-two years ago, when some giddy
+goose fell from goodness knows where. He made the most frightful noise that resounded all over
+the place, and I made four mistakes in my addition. The second time, eleven years ago, I was
+disturbed by an attack of rheumatism. I don’t get enough exercise. I have no time for loafing. The
+third time, well, this is it! I was saying, then, five -hundred-and-one millions”
+
+“Millions of what?” The businessman suddenly realised that there was no hope of being left in
+peace until he answered this question.
+
+“Millions of those little objects,” he said, “which one sometimes sees in the sky.” “Flies?” “Oh,
+no. Little glittering objects.” “Bees?” “Oh, no. Little golden objects that set lazy men to idle
+dreaming. As for me, I am concerned with matters of consequence. There is no time for idle
+dreaming in my life.” “Ah! You mean the stars?” “Yes, that’s it. The stars.” “And what do you do
+with five-hundred millions of stars?” “Five-hundred-and-one million, six-hundred-twenty-two
+thousand, seven-hundred-thirty-one. I am concerned with matters of consequence: I am
+accurate.”
+
+“And what do you do with these stars?” “What do I do with them?” “Yes.” “Nothing. I own them.”
+“You own the stars?” “Yes.” “But I have already seen a king who...” “Kings do not own, they
+reign over. It is a very different matter.”
+
+“And what good does it do you to own the stars?” “It does me the good of making me rich.”
+
+“And what good does it do you to be rich?”
+
+“It makes it possible for me to buy more stars, if any are ever discovered.”
+
+“This man,” the little prince said to himself, “reasons a little like my poor tippler...” Nevertheless,
+he still had some more questions. “How is it possible for one to own the stars?” “To whom do they
+belong?” the businessman retorted, peevishly. “I don’t know. To nobody.” “Then they belong to
+me, because I was the first person to think of it.” “Is that all that is necessary?” “Certainly.
+
+When you find a diamond that belongs to nobody, it is yours. When you discover an island that
+belongs to nobody, it is yours. When you get an idea before any one else, you take out a patent on
+it: it is yours. So with me: I own the stars, because nobody else before me ever thought of owning
+them.”
+
+“Yes, that is true,” said the little prince. “And what do you do with them?”
+
+
+
+
+“I administer them,” replied the businessman. “I count them and recount them. It is difficult. But I
+am a man who is naturally interested in matters of consequence.”
+
+The little prince was still not satisfied. “If I owned a silk scarf,” he said, “I could put it around my
+neck and take it away with me. If I owned a flower, I could pluck that flower and take it away with
+me. But you cannot pluck the stars from heaven...”
+
+“No. But I can put them in the bank.” “Whatever does that mean?” “That means that I write the
+number of my stars on a little paper. And then I put this paper in a drawer and lock it with a key.”
+
+“And that is all?”
+
+“That is enough,” said the businessman.
+
+“It is entertaining,” thought the little prince. “It is rather poetic. But it is of no great
+consequence.” On matters of consequence, the little prince had ideas, which were very different
+from those of the grown-ups.
+
+“I myself own a flower,” he continued his conversation with the businessman, “which I water
+every day. I own three volcanoes, which I clean out every week (for I also clean out the one that is
+extinct; one never knows). It is of some use to my volcanoes, and it is of some use to my flower,
+that I own them. But you are of no use to the stars...”
+
+The businessman opened his mouth, but he found nothing to say in answer. And the little prince
+went away. “The grown-ups are certainly altogether extraordinary,” he said simply, talking to
+himself as he continued on his journey.
+
+The fifth planet was very strange. It was the smallest of all. There was just enough room on it for
+a street lamp and a lamplighter.
+
+
+
+
+The little prince was not able to reach any explanation of the use of a street lamp and a
+lamplighter, somewhere in the heavens, on a planet, which had no people, and not one house.
+
+But he said to himself, nevertheless: “It may well be that this man is absurd. But he is not so
+absurd as the king, the conceited man, the businessman, and the tippler. For at least his work has
+
+
+
+some meaning. When he lights his street lamp, it is as if he brought one more star to life, or one
+flower. When he puts out his lamp, he sends the flower, or the star, to sleep. That is a beautiful
+occupation. And since it is beautiful, it is truly useful.”
+
+When he arrived on the planet he respectfully saluted the lamplighter.
+
+“Good morning. Why have you just put out your lamp?”
+
+“Those are the orders,” replied the lamplighter. “Good morning.”
+
+“What are the orders?”
+
+“The orders are that I put out my lamp. Good evening.” And he lighted his lamp again. “But why
+have you just lighted it again?”
+
+“Those are the orders,” replied the lamplighter.
+
+“I do not understand,” said the little prince.
+
+“There is nothing to understand,” said the lamplighter. “Orders are orders. Good morning.” And
+he put out his lamp.
+
+Then he mopped his forehead with a handkerchief decorated with red squares.
+
+“I follow a terrible profession. In the old days it was reasonable. I put the lamp out in the morning,
+and in the evening I lighted it again. I had the rest of the day for relaxation and the rest of the
+night for sleep.”
+
+“And the orders have been changed since that time?”
+
+“The orders have not been changed,” said the lamplighter. “That is the tragedy! From year to
+year the planet has turned more rapidly and the orders have not been changed!”
+
+“Then what?” asked the little prince.
+
+“Then the planet now makes a complete turn every minute, and I no longer have a single second
+for repose. Once every minute I have to light my lamp and put it out!”
+
+“That is very funny! A day lasts only one minute, here where you live!”
+
+“It is not funny at all!” said the lamplighter. “While we have been talking together a month has
+gone by.”
+
+“A month?”
+
+
+
+“Yes, a month. Thirty minutes. Thirty days. Good evening.” And he lighted his lamp again. As the
+little prince watched him, he felt that he loved this lamplighter who was so faithful to his orders.
+He remembered the sunsets, which he himself had gone to seek, in other days, merely by pulling
+up his chair; and he wanted to help his friend.
+
+“You know,” he said, “I can tell you a way you can rest whenever you want to...”
+
+“I always want to rest,” said the lamplighter. For it is possible for a man to be faithful and lazy at
+the same time.
+
+
+
+
+The little prince went on with his explanation: “Your planet is so small that three strides will take
+you all the way around it. To be always in the sunshine, you need only walk along rather slowly.
+When you want to rest, you will walk and the day will last as long as you like.”
+
+“That doesn’t do me much good,” said the lamplighter. “The one thing I love in life is to sleep.”
+
+“Then you’re unlucky,” said the little prince.
+
+“I am unlucky,” said the lamplighter. “Good morning.” And he put out his lamp.
+
+“That man,” said the little prince to himself, as he continued farther on his journey, “that man
+would be scorned by all the others: by the king, by the conceited man, by the tippler, by the
+businessman. Nevertheless he is the only one of them all who does not seem to me ridiculous.
+Perhaps that is because he is thinking of something else besides himself.”
+
+He breathed a sigh of regret, and said to himself, again: “That man is the only one of them all
+whom I could have made my friend. But his planet is indeed too small. There is no room on it for
+two people...” What the little prince did not dare confess was that he was sorry most of all to leave
+this planet, because it was blest every day with 1440 sunsets!
+
+The sixth planet was ten times larger than the last one. It was inhabited by an old gentleman who
+wrote voluminous books.
+
+
+
+
+“Oh, look! Here is an explorer!” he exclaimed to himself when he saw the little prince coming.
+
+The little prince sat down on the table and panted a little. He had already travelled so much and
+so far!
+
+“Where do you come from?” the old gentleman said to him.
+
+“What is that big book?” said the little prince. “What are you doing?”
+
+“I am a geographer,” the old gentleman said to him.
+
+“What is a geographer?” asked the little prince. “A geographer is a scholar who knows the
+location of all the seas, rivers, towns, mountains, and deserts.”
+
+“That is very interesting,” said the little prince. “Here at last is a man who has a real profession!”
+And he cast a look around him at the planet of the geographer.
+
+
+
+It was the most magnificent and stately planet that he had ever seen.
+
+“Your planet is very beautiful,” he said. “Has it any oceans?”
+
+“I couldn’t tell you,” said the geographer.
+
+“Ah!” The little prince was disappointed. “Has it any mountains?”
+
+“I couldn’t tell you,” said the geographer.
+
+“And towns, and rivers, and deserts?”
+
+“I couldn’t tell you that, either.”
+
+“But you are a geographer!”
+
+“Exactly,” the geographer said. “But I am not an explorer. I haven’t a single explorer on my
+planet. It is not the geographer who goes out to count the towns, the rivers, the mountains, the
+seas, the oceans, and the deserts. The geographer is much too important to go loafing about. He
+does not leave his desk. But he receives the explorers in his study. He asks them questions, and
+he notes down what they recall of their travels. And if the recollections of any one among them
+seem interesting to him, the geographer orders an inquiry into that explorer’s moral character.”
+
+“Why is that?”
+
+“Because an explorer who told lies would bring disaster on the books of the geographer. So would
+an explorer who drank too much.”
+
+“Why is that?” asked the little prince.
+
+“Because intoxicated men see double. Then the geographer would note down two mountains in a
+place where there was only one.”
+
+“I know some one,” said the little prince, “who would make a bad explorer.”
+
+“That is possible. Then, when the moral character of the explorer is shown to be good, an inquiry
+is ordered into his discovery.”
+
+“One goes to see it?”
+
+“No. That would be too complicated. But one requires the explorer to furnish proofs. For example,
+if the discovery in question is that of a large mountain, one requires that large stones be brought
+back from it.” The geographer was suddenly stirred to excitement. “But you come from far away!
+You are an explorer! You shall describe your planet to me!” And, having opened his big register,
+the geographer sharpened his pencil. The recitals of explorers are put down first in pencil. One
+waits until the explorer has furnished proofs, before putting them down in ink. “Well?” said the
+geographer expectantly.
+
+“Oh, where I live,” said the little prince, “it is not very interesting. It is all so small. I have three
+volcanoes. Two volcanoes are active and the other is extinct. But one never knows.”
+
+“One never knows,” said the geographer.
+
+
+
+“I have also a flower.”
+
+
+
+
+“We do not record flowers,” said the geographer.
+
+“Why is that? The flower is the most beautiful thing on my planet!”
+
+“We do not record them,” said the geographer, “because they are ephemeral.”
+
+“What does that mean ‘ephemeral’?”
+
+“Geographies,” said the geographer, “are the books which, of all books, are most concerned with
+matters of consequence. They never become old-fashioned. It is very rarely that a mountain
+changes its position. It is very rarely that an ocean empties itself of its waters. We write of eternal
+things.”
+
+“But extinct volcanoes may come to life again,” the little prince interrupted.
+
+“What does that mean ‘ephemeral’?”
+
+“Whether volcanoes are extinct or alive, it comes to the same thing for us,” said the geographer.
+“The thing that matters to us is the mountain. It does not change.”
+
+“But what does that mean ‘ephemeral’?” repeated the little prince, who never in his life had let go
+of a question, once he had asked it.
+
+“It means, ‘which is in danger of speedy disappearance.’ “
+
+“Is my flower in danger of speedy disappearance?”
+
+“Certainly it is.”
+
+“My flower is ephemeral,” the little prince said to himself, “and she has only four thorns to
+defend herself against the world. And I have left her on my planet, all alone!”
+
+That was his first moment of regret. But he took courage once more. “What place would you
+advise me to visit now?” he asked. “The planet Earth,” replied the geographer. “It has a good
+reputation.” And the little prince went away, thinking of his flower.
+
+
+
+
+So then the seventh planet was the Earth.
+
+The Earth is not just an ordinary planet!
+
+One can count, there 111 kings (not forgetting, to be sure, the Negro kings among them), 7000
+geographers, 900,000 businessmen, 7,500,000 tipplers, 311,000,000 conceited men, that is to say,
+about 2,000,000,000 grown-ups.
+
+To give you an idea of the size of the Earth, I will tell you that before the invention of electricity it
+was necessary to maintain, over the whole of the six continents, a veritable army of 462,511
+lamplighters for the street lamps. Seen from a slight distance, that would make a splendid
+spectacle.
+
+The movements of this army would be regulated like those of the ballet in the opera. First would
+come the turn of the lamplighters of New Zealand and Australia. Having set their lamps alight,
+these would go off to sleep. Next, the lamplighters of China and Siberia would enter for their steps
+in the dance, and then they too would be waved back into the wings. After that would come the
+turn of the lamplighters of Russia and the Indies; then those of Africa and Europe, then those of
+South America; then those of North America. And never would they make a mistake in the order
+of their entry upon the stage. It would be magnificent.
+
+Only the man who was in charge of the single lamp at the North Pole, and his colleague who was
+responsible for the single lamp at the South Pole, only these two would live free from toil and
+care: they would be busy twice a year.
+
+When one wishes to play the wit, he sometimes wanders a little from the truth.
+
+I have not been altogether honest in what I have told you about the lamplighters. And I realise
+that I run the risk of giving a false idea of our planet to those who do not know it.
+
+Men occupy a very small place upon the Earth. If the two billion inhabitants who people its
+surface were all to stand upright and somewhat crowded together, as they do for some big public
+assembly, they could easily be put into one public square twenty miles long and twenty miles wide.
+All humanity could be piled up on a small Pacific islet.
+
+The grown-ups, to be sure, will not believe you when you tell them that. They imagine that they fill
+a great deal of space. They fancy themselves as important as the baobabs. You should advise
+them, then, to make their own calculations. They adore figures, and that will please them. But do
+not waste your time on this extra task. It is unnecessary. You have, I know, confidence in me.
+
+When the little prince arrived on the Earth, he was very much surprised not to see any people. He
+was beginning to be afraid he had come to the wrong planet, when a coil of gold, the colour of the
+moonlight, flashed across the sand.
+
+“Good evening,” said the little prince courteously.
+
+“Good evening,” said the snake.
+
+“What planet is this on which I have come down?” asked the little prince.
+
+“This is the Earth; this is Africa,” the snake answered.
+
+“Ah! Then there are no people on the Earth?”
+
+
+
+
+“This is the desert. There are no people in the desert. The Earth is large,” said the snake.
+
+The little prince sat down on a stone, and raised his eyes toward the sky.
+
+“I wonder,” he said, “whether the stars are set alight in heaven so that one day each one of us
+may find his own again... Look at my planet. It is right there above us. But how far away it is!”
+
+“It is beautiful,” the snake said. “What has brought you here?”
+
+“I have been having some trouble with a flower,” said the little prince. “Ah!” said the snake. And
+they were both silent.
+
+“Where are the men?” the little prince at last took up the conversation again. “It is a little lonely
+in the desert...”
+
+“It is also lonely among men,” the snake said. The little prince gazed at him for a long time.
+
+“You are a funny animal,” he said at last. “You are no thicker than a finger...”
+
+“But I am more powerful than the finger of a king,” said the snake.
+
+The little prince smiled. “You are not very powerful. You haven’t even any feet. You cannot even
+travel...”
+
+“I can carry you farther than any ship could take you,” said the snake. He twined himself around
+the little prince’s ankle, like a golden bracelet.
+
+“Whomever I touch, I send back to the earth from whence he came,” the snake spoke again. “But
+you are innocent and true, and you come from a star...”
+
+The little prince made no reply. “You move me to pity, you are so weak on this Earth made of
+granite,” the snake said. “I can help you, some day, if you grow too homesick for your own planet.
+I can...”
+
+“Oh! I understand you very well,” said the little prince. “But why do you always speak in
+riddles?”
+
+“I solve them all,” said the snake. And they were both silent.
+
+The little prince crossed the desert and met with only one flower.
+
+It was a flower with three petals, a flower of no account at all.
+
+“Good morning,” said the little prince.
+
+“Good morning,” said the flower.
+
+“Where are the men?” the little prince asked, politely. The flower had once seen a caravan
+passing.
+
+“Men?” she echoed. “I think there are six or seven of them in existence. I saw them, several
+years ago. But one never knows where to find them. The wind blows them away. They have no
+roots, and that makes their life very difficult.”
+
+
+
+“Goodbye,” said the little prince.
+
+
+
+
+“Goodbye,” said the flower.
+
+
+
+After that, the little prince climbed a high mountain. The only mountains he had ever known were
+the three volcanoes, which came up to his knees. And he used the extinct volcano as a footstool.
+
+“From a mountain as high as this one,” he said to himself, “I shall be able to see the whole planet
+at one glance, and all the people...” But he saw nothing, save peaks of rock that were sharpened
+like needles.
+
+
+
+
+“Good morning,” he said courteously.
+
+“Good morning...Good morning...Good morning,” answered the echo.
+
+“Who are you?” said the little prince.
+
+“Who are you...Who are you...Who are you?” answered the echo.
+
+“Be my friends. I am all alone,” he said.
+
+“I am all alone...all alone. ..all alone,” answered the echo.
+
+“What a queer planet!” he thought. “It is altogether dry, and altogether pointed, and altogether
+harsh and forbidding. And the people have no imagination. They repeat whatever one says to
+them... On my planet I had a flower; she always was the first to speak...”
+
+But it happened that after walking for a long time through sand, and rocks, and snow, the little
+prince at last came upon a road. And all roads lead to the abodes of men.
+
+“Good morning,” he said. He was standing before a garden, all a-bloom with roses.
+
+“Good morning,” said the roses.
+
+The little prince gazed at them. They all looked like his flower.
+
+“Who are you?” he demanded, thunderstruck.
+
+“We are roses,” the roses said. And he was overcome with sadness. His flower had told him that
+she was the only one of her kind in all the universe. And here were five thousand of them, all
+alike, in one single garden!
+
+“She would be very much annoyed,” he said to himself, “if she should see that... she would cough
+
+
+
+most dreadfully, and she would pretend that she was dying, to avoid being laughed at. And I
+should be obliged to pretend that I was nursing her back to life, for if I did not do that, to humble
+myself also, she would really allow herself to die...”
+
+Then he went on with his reflections: “I thought that I was rich, with a flower that was unique in all
+the world; and all I had was a common rose. A common rose, and three volcanoes that come up to
+my knees — and one of them perhaps extinct forever... that doesn’t make me a very great
+prince...” And he lay down in the grass and cried.
+
+It was then that the fox appeared.
+
+“Good morning,” said the fox.
+
+“Good morning,” the little prince responded politely, although when he turned around he saw
+nothing.
+
+“I am right here,” the voice said, “under the apple tree.” “
+
+Who are you?” asked the little prince, and added, “You are very pretty to look at.”
+
+“I am a fox,” said the fox.
+
+“Come and play with me,” proposed the little prince.
+
+“I am so unhappy.” “I cannot play with you,” the fox said. “I am not tamed.”
+
+“Ah! Please excuse me,” said the little prince. But, after some thought, he added: “What does
+that mean, ‘tame’?”
+
+
+
+
+“You do not live here,” said the fox. “What is it that you are looking for?”
+
+“I am looking for men,” said the little prince. “What does that mean, ‘tame’?”
+
+“Men,” said the fox. “They have guns, and they hunt. It is very disturbing. They also raise
+chickens. These are their only interests. Are you looking for chickens?”
+
+“No,” said the little prince. “I am looking for friends. What does that mean, ‘tame’?”
+
+“It is an act too often neglected,” said the fox. It means to establish ties.”
+
+
+
+“‘To establish ties’?”
+
+
+
+“Just that,” said the fox. “To me, you are still nothing more than a little boy who is just like a
+hundred thousand other little boys. And I have no need of you. And you, on your part, have no
+need of me. To you, I am nothing more than a fox like a hundred thousand other foxes. But if you
+tame me, then we shall need each other. To me, you will be unique in all the world. To you, I shall
+be unique in all the world...”
+
+“I am beginning to understand,” said the little prince. “There is a flower... I think that she has
+tamed me...”
+
+“It is possible,” said the fox. “On the Earth one sees all sorts of things.”
+
+“Oh, but this is not on the Earth!” said the little prince. The fox seemed perplexed, and very
+curious.
+
+“On another planet?”
+
+“Yes.”
+
+“Are there hunters on this planet?”
+
+“No.”
+
+“Ah, that is interesting! Are there chickens?”
+
+“No.”
+
+“Nothing is perfect,” sighed the fox. But he came back to his idea. “My life is very monotonous,”
+the fox said. “I hunt chickens; men hunt me. All the chickens are just alike, and all the men are
+just alike. And, in consequence, I am a little bored. But if you tame me, it will be as if the sun
+came to shine on my life. I shall know the sound of a step that will be different from all the others.
+Other steps send me hurrying back underneath the ground. Yours will call me, like music, out of
+my burrow. And then look: you see the grain-fields down yonder? I do not eat bread. Wheat is of
+no use to me. The wheat fields have nothing to say to me. And that is sad. But you have hair that
+is the colour of gold. Think how wonderful that will be when you have tamed me! The grain, which
+is also golden, will bring me back the thought of you. And I shall love to listen to the wind in the
+wheat...” The fox gazed at the little prince, for a long time. “Please, tame me!” he said.
+
+“I want to, very much,” the little prince replied. “But I have not much time. I have friends to
+discover, and a great many things to understand.”
+
+“One only understands the things that one tames,” said the fox. “Men have no more time to
+understand anything. They buy things all ready-made at the shops. But there is no shop anywhere
+where one can buy friendship, and so men have no friends any more. If you want a friend, tame
+me...”
+
+“What must I do, to tame you?” asked the little prince.
+
+“You must be very patient,” replied the fox. “First you will sit down at a little distance from me,
+like that, in the grass. I shall look at you out of the corner of my eye, and you will say nothing.
+Words are the source of misunderstandings. But you will sit a little closer to me, every day...”
+
+
+
+
+The next day the little prince came back.
+
+
+
+“It would have been better to come back at the same hour,” said the fox. “If, for example, you
+come at four o’clock in the afternoon, then at three o’clock I shall begin to be happy. I shall feel
+happier and happier as the hour advances. At four o’clock, I shall already be worrying and
+jumping about. I shall show you how happy I am! But if you come at just any time, I shall never
+know at what hour my heart is to be ready to greet you... One must observe the proper rites...”
+
+“What is a rite?” asked the little prince.
+
+“Those also are actions too often neglected,” said the fox. “They are what make one day
+different from other days, one hour from other hours. There is a rite, for example, among my
+hunters. Every Thursday they dance with the village girls. So Thursday is a wonderful day for me!
+I can take a walk as far as the vineyards. But if the hunters danced at just any time, every day
+would be like every other day, and I should never have any vacation at all.”
+
+So the little prince tamed the fox. And when the hour of his departure drew near...
+
+“Ah,” said the fox, “I shall cry.”
+
+“It is your own fault,” said the little prince. “I never wished you any sort of harm; but you wanted
+me to tame you...”
+
+“Yes, that is so,” said the fox.
+
+“But now you are going to cry!” said the little prince.
+
+“Yes, that is so,” said the fox.
+
+“Then it has done you no good at all!”
+
+“It has done me good,” said the fox, “because of the colour of the wheat fields.” And then he
+added: “Go and look again at the roses. You will understand now that yours is unique in all the
+world. Then come back to say goodbye to me, and I will make you a present of a secret.”
+
+The little prince went away, to look again at the roses. “You are not at all like my rose,” he said.
+“As yet you are nothing. No one has tamed you, and you have tamed no one. You are like my fox
+when I first knew him. He was only a fox like a hundred thousand other foxes. But I have made
+him my friend, and now he is unique in all the world.” And the roses were very much embarrassed.
+“You are beautiful, but you are empty,” he went on. “One could not die for you. To be sure, an
+ordinary passer-by would think that my rose looked just like you, the rose that belongs to me. But
+in herself alone she is more important than all the hundreds of you other roses: because it is she
+that I have watered; because it is she that I have put under the glass globe; because it is she that
+I have sheltered behind the screen; because it is for her that I have killed the caterpillars (except
+the two or three that we saved to become butterflies); because it is she that I have listened to,
+when she grumbled, or boasted, or even sometimes when she said nothing. Because she is my
+rose.
+
+And he went back to meet the fox. “Goodbye,” he said.
+
+“Goodbye,” said the fox. “And now here is my secret, a very simple secret: It is only with the
+heart that one can see rightly; what is essential is invisible to the eye.”
+
+
+
+
+“What is essential is invisible to the eye,” the little prince repeated, so that he would be sure to
+remember.
+
+“It is the time you have wasted for your rose that makes your rose so important.”
+
+“It is the time I have wasted for my rose...” said the little prince, so that he would be sure to
+remember.
+
+“Men have forgotten this truth,” said the fox. “But you must not forget it. You become
+responsible, forever, for what you have tamed. You are responsible for your rose...”
+
+“I am responsible for my rose,” the little prince repeated, so that he would be sure to remember.
+
+“Good morning,” said the little prince.
+
+“Good morning,” said the railway switchman.
+
+“What do you do here?” the little prince asked.
+
+“I sort out travellers, in bundles of a thousand,” said the switchman. “I send off the trains that
+carry them; now to the right, now to the left.” And a brilliantly lighted express train shook the
+switchman’s cabin as it rushed by with a roar like thunder.
+
+“They are in a great hurry,” said the little prince. “What are they looking for?”
+
+“Not even the locomotive engineer knows that,” said the switchman. And a second brilliantly
+lighted express thundered by, in the opposite direction.
+
+“Are they coming back already?” demanded the little prince. “These are not the same ones,” said
+the switchman. “It is an exchange.”
+
+“Were they not satisfied where they were?” asked the little prince.
+
+“No one is ever satisfied where he is,” said the switchman. And they heard the roaring thunder of
+a third brilliantly lighted express.
+
+“Are they pursuing the first travellers?” demanded the little prince.
+
+“They are pursuing nothing at all,” said the switchman. “They are asleep in there, or if they are
+not asleep they are yawning. Only the children are flattening their noses against the
+windowpanes.”
+
+“Only the children know what they are looking for,” said the little prince.
+
+“They waste their time over a rag doll and it becomes very important to them; and if anybody
+takes it away from them, they cry...” “They are lucky,” the switchman said.
+
+“Good morning,” said the little prince.
+
+“Good morning,” said the merchant.
+
+This was a merchant who sold pills that had been invented to quench thirst. You need only swallow
+one pill a week, and you would feel no need of anything to drink.
+
+
+
+
+“Why are you selling those?” asked the little prince.
+
+
+
+“Because they save a tremendous amount of time,” said the merchant. “Computations have been
+made by experts. With these pills, you save fifty-three minutes in every week.”
+
+“And what do I do with those fifty-three minutes?”
+
+“Anything you like...”
+
+“As for me,” said the little prince to himself, “if I had fifty-three minutes to spend as I liked, I
+should walk at my leisure toward a spring of fresh water.”
+
+It was now the eighth day since I had had my accident in the desert, and I had listened to the story
+of the merchant as I was drinking the last drop of my water supply.
+
+“Ah,” I said to the little prince, “these memories of yours are very charming; but I have not yet
+succeeded in repairing my plane; I have nothing more to drink; and I, too, should be very happy if
+I could walk at my leisure toward a spring of fresh water!”
+
+“My friend the fox...” the little prince said to me.
+
+“My dear little man, this is no longer a matter that has anything to do with the fox!”
+
+“Why not?”
+
+“Because I am about to die of thirst...”
+
+He did not follow my reasoning, and he answered me: “It is a good thing to have had a friend,
+even if one is about to die. I, for instance, am very glad to have had a fox as a friend...”
+
+“He has no way of guessing the danger,” I said to myself. “He has never been either hungry or
+thirsty. A little sunshine is all he needs...”
+
+But he looked at me steadily, and replied to my thought: “I am thirsty, too. Let us look for a
+well...” I made a gesture of weariness. It is absurd to look for a well, at random, in the immensity
+of the desert. But nevertheless we started walking.
+
+When we had trudged along for several hours, in silence, the darkness fell, and the stars began to
+come out. Thirst had made me a little feverish, and I looked at them as if I were in a dream. The
+little prince’s last words came reeling back into my memory: “Then you are thirsty, too?” I
+demanded. But he did not reply to my question. He merely said to me: “Water may also be good
+for the heart...”
+
+I did not understand this answer, but I said nothing. I knew very well that it was impossible to
+cross-examine him. He was tired. He sat down. I sat down beside him. And, after a little silence,
+he spoke again: “The stars are beautiful, because of a flower that cannot be seen.”
+
+I replied, “Yes, that is so.” And, without saying anything more, I looked across the ridges of sand
+that were stretched out before us in the moonlight.
+
+“The desert is beautiful,” the little prince added.
+
+And that was true. I have always loved the desert. One sits down on a desert sand dune, sees
+
+
+
+
+
+nothing, hears nothing. Yet through the silence something throbs, and gleams...
+
+“What makes the desert beautiful,” said the little prince, “is that somewhere it hides a well...”
+
+I was astonished by a sudden understanding of that mysterious radiation of the sands. When I was
+a little boy I lived in an old house, and legend told us that a treasure was buried there. To be sure,
+no one had ever known how to find it; perhaps no one had ever even looked for it. But it cast an
+enchantment over that house. My home was hiding a secret in the depths of its heart... “Yes,” I
+said to the little prince. “The house, the stars, the desert — what gives them their beauty is
+something that is invisible!”
+
+“I am glad,” he said, “that you agree with my fox.” As the little prince dropped off to sleep, I took
+him in my arms and set out walking once more. I felt deeply moved, and stirred. It seemed to me
+that I was carrying a very fragile treasure. It seemed to me, even, that there was nothing more
+fragile on all Earth. In the moonlight I looked at his pale forehead, his closed eyes, his locks of
+hair that trembled in the wind, and I said to myself:
+
+“What I see here is nothing but a shell. What is most important is invisible...”
+
+As his lips opened slightly with the suspicious of a half-smile, I said to myself, again: “What
+moves me so deeply, about this little prince who is sleeping here, is his loyalty to a flower — the
+image of a rose that shines through his whole being like the flame of a lamp, even when he is
+asleep...”
+
+And I felt him to be more fragile still. I felt the need of protecting him, as if he himself were a
+flame that might be extinguished by a little puff of wind... And, as I walked on so, I found the well,
+at daybreak.
+
+“Men,” said the little prince, “set out on their way in express trains, but they do not know what
+they are looking for. Then they rush about, and get excited, and turn round and round...” And he
+added: “It is not worth the trouble...”
+
+
+
+The well that we had come to was not like the wells of the Sahara. The wells of the Sahara are
+mere holes dug in the sand. This one was like a well in a village. But there was no village here,
+and I thought I must be dreaming...
+
+“It is strange,” I said to the little prince. “Everything is ready for use: the pulley, the bucket, the
+rope...” He laughed, touched the rope, and set the pulley to working. And the pulley moaned, like
+an old weathervane, which the wind has long since forgotten.
+
+“Do you hear?” said the little prince. “We have wakened the well, and it is singing...”
+
+I did not want him to tire himself with the rope.
+
+“Leave it to me,” I said. “It is too heavy for you.” I hoisted the bucket slowly to the edge of the
+well and set it there, happy, tired as I was, over my achievement. The song of the pulley was still
+in my ears, and I could see the sunlight shimmer in the still trembling water.
+
+“I am thirsty for this water,” said the little prince. “Give me some of it to drink...”
+
+And I understood what he had been looking for. I raised the bucket to his lips. He drank, his eyes
+closed. It was as sweet as some special festival treat. This water was indeed a different thing from
+ordinary nourishment. Its sweetness was born of the walk under the stars, the song of the pulley,
+the effort of my arms. It was good for the heart, like a present. When I was a little boy, the lights
+of the Christmas tree, the music of the Midnight Mass, the tenderness of smiling faces, used to
+make up, so, the radiance of the gifts I received.
+
+“The men where you live,” said the little prince, “raise five thousand roses in the same garden
+and they do not find in it what they are looking for.”
+
+“They do not find it,” I replied.
+
+“And yet what they are looking for could be found in one single rose, or in a little water.”
+
+“Yes, that is true,” I said.
+
+And the little prince added: “But the eyes are blind. One must look with the heart...”
+
+I had drunk the water. I breathed easily. At sunrise the sand is the colour of honey. And that
+honey colour was making me happy, too. What brought me, then, this sense of grief?
+
+“You must keep your promise,” said the little prince, softly, as he sat down beside me once more.
+“What promise?” “You know, a muzzle for my sheep... I am responsible for this flower...”
+
+I took my rough drafts of drawings out of my pocket. The little prince looked them over, and
+laughed as he said:
+
+“Your baobabs, they look a little like cabbages.”
+
+“Oh!” I had been so proud of my baobabs! “Your fox, his ears look a little like horns; and they are
+too long.” And he laughed again.
+
+“You are not fair, little prince,” I said. “I don’t know how to draw anything except boa constrictors
+from the outside and boa constrictors from the inside.”
+
+
+
+
+
+“Oh, that will be all right,” he said, “children understand.”
+
+So then I made a pencil sketch of a muzzle. And as I gave it to him my heart was torn.
+
+“You have plans that I do not know about,” I said. But he did not answer me. He said to me,
+instead: “You know, my descent to the earth... Tomorrow will be its anniversary.” Then, after a
+silence, he went on: “I came down very near here.” And he flushed.
+
+And once again, without understanding why, I had a queer sense of sorrow. One question,
+however, occurred to me: “Then it was not by chance that on the morning when I first met you — a
+week ago — you were strolling along like that, all alone, a thousand miles from any inhabited
+region? You were on the your way back to the place where you landed?”
+
+The little prince flushed again. And I added, with some hesitancy: “Perhaps it was because of the
+anniversary?” The little prince flushed once more. He never answered questions, but when one
+flushes does that not mean “Yes”?
+
+“Ah,” I said to him, “I am a little frightened...”
+
+But he interrupted me. “Now you must work. You must return to your engine. I will be waiting for
+you here. Come back tomorrow evening...”
+
+But I was not reassured. I remembered the fox. One runs the risk of weeping a little, if one lets
+himself be tamed...
+
+Beside the well there was the ruin of an old stone wall. When I came back from my work, the next
+evening, I saw from some distance away my little prince sitting on top of a wall, with his feet
+dangling. And I heard him say: “Then you don’t remember. This is not the exact spot.” Another
+voice must have answered him, for he replied to it: “Yes, yes! It is the right day, but this is not the
+place.”
+
+I continued my walk toward the wall. At no time did I see or hear anyone. The little prince,
+however, replied once again: “...Exactly. You will see where my track begins, in the sand. You have
+nothing to do but wait for me there. I shall be there tonight.”
+
+
+
+I was only twenty metres from the wall, and I still saw nothing. After a silence the little prince
+spoke again: “You have good poison? You are sure that it will not make me suffer too long?” I
+stopped in my tracks, my heart torn asunder; but still I did not understand. “Now go away,” said
+the little prince. “I want to get down from the wall.”
+
+I dropped my eyes, then, to the foot of the wall... and I leaped into the air. There before me, facing
+the little prince, was one of those yellow snakes that take just thirty seconds to bring your life to
+an end. Even as I was digging into my pocked to get out my revolver I made a running step back.
+But, at the noise I made, the snake let himself flow easily across the sand like the dying spray of
+a fountain, and, in no apparent hurry, disappeared, with a light metallic sound, among the stones. I
+reached the wall just in time to catch my little man in my arms; his face was white as snow.
+
+“What does this mean?” I demanded. “Why are you talking with snakes?”
+
+I had loosened the golden muffler that he always wore. I had moistened his temples, and had
+given him some water to drink. And now I did not dare ask him any more questions. He looked at
+me very gravely, and put his arms around my neck. I felt his heart beating like the heart of a
+dying bird, shot with someone’s rifle...
+
+“I am glad that you have found what was the matter with your engine,” he said. “Now you can go
+back home”
+
+“How do you know about that?” I was just coming to tell him that my work had been successful,
+beyond anything that I had dared to hope.
+
+He made no answer to my question, but he added: “I, too, am going back home today...” Then,
+sadly, “It is much farther... it is much more difficult...” I realised clearly that something
+extraordinary was happening. I was holding him close in my arms as if he were a little child; and
+yet it seemed to me that he was rushing headlong toward an abyss from which I could do nothing
+to restrain him... His look was very serious, like some one lost far away.
+
+“I have your sheep. And I have the sheep’s box. And I have the muzzle...”
+
+And he gave me a sad smile. I waited a long time. I could see that he was reviving little by little.
+
+“Dear little man,” I said to him, “you are afraid...” He was afraid, there was no doubt about that.
+But he laughed lightly.
+
+“I shall be much more afraid this evening...”
+
+Once again I felt myself frozen by the sense of something irreparable. And I knew that I could not
+bear the thought of never hearing that laughter any more. For me, it was like a spring of fresh
+water in the desert.
+
+“Little man,” I said, “I want to hear you laugh again.” But he said to me: “Tonight, it will be a
+year... my star, then, can be found right above the place where I came to the Earth, a year ago...”
+
+“Little man,” I said, “tell me that it is only a bad dream, this affair of the snake, and the meeting-
+place, and the star...” But he did not answer my plea.
+
+He said to me, instead: “The thing that is important is the thing that is not seen...” “Yes, I
+know...”
+
+
+
+
+“It is just as it is with the flower. If you love a flower that lives on a star, it is sweet to look at the
+sky at night. All the stars are a-bloom with flowers...”
+
+“Yes, I know...”
+
+“It is just as it is with the water. Because of the pulley, and the rope, what you gave me to drink
+was like music. You remember, how good it was.”
+
+“Yes, I know...”
+
+“And at night you will look up at the stars. Where I live everything is so small that I cannot show
+you where my star is to be found. It is better, like that. My star will just be one of the stars, for
+you. And so you will love to watch all the stars in the heavens... they will all be your friends. And,
+besides, I am going to make you a present...” He laughed again.
+
+“Ah, little prince, dear little prince! I love to hear that laughter!”
+
+“That is my present. Just that. It will be as it was when we drank the water...”
+
+“What are you trying to say?”
+
+“All men have the stars,” he answered, “but they are not the same things for different people. For
+some, who are travellers, the stars are guides. For others they are no more than little lights in the
+sky. For others, who are scholars, they are problems. For my businessman they were wealth. But
+all these stars are silent. You, you alone, will have the stars as no one else has them”
+
+“What are you trying to say?”
+
+“In one of the stars I shall be living. In one of them I shall be laughing. And so it will be as if all
+the stars were laughing, when you look at the sky at night... you, only you, will have stars that can
+laugh!”
+
+And he laughed again. “And when your sorrow is comforted (time soothes all sorrows) you will be
+content that you have known me. You will always be my friend. You will want to laugh with me. And
+you will sometimes open your window, so, for that pleasure... and your friends will be properly
+astonished to see you laughing as you look up at the sky! Then you will say to them, ‘Yes, the
+stars always make me laugh!’ And they will think you are crazy. It will be a very shabby trick that
+I shall have played on you...”
+
+And he laughed again. “It will be as if, in place of the stars, I had given you a great number of
+little bells that knew how to laugh...”
+
+And he laughed again. Then he quickly became serious: “Tonight, you know... do not come,” said
+the little prince.
+
+“I shall not leave you,” I said.
+
+“I shall look as if I were suffering. I shall look a little as if I were dying. It is like that. Do not
+come to see that. It is not worth the trouble...”
+
+“I shall not leave you.”
+
+
+
+But he was worried. “I tell you, it is also because of the snake. He must not bite you. Snakes, they
+
+
+
+
+are malicious creatures. This one might bite you just for fun...”
+
+
+
+“I shall not leave you.”
+
+But a thought came to reassure him: “It is true that they have no more poison for a second bite.”
+
+That night I did not see him set out on his way. He got away from me without making a sound.
+When I succeeded in catching up with him he was walking along with a quick and resolute step. He
+said to me merely: “Ah! You are there...” And he took me by the hand. But he was still worrying.
+“It was wrong of you to come. You will suffer. I shall look as if I were dead; and that will not be
+true...”
+
+I said nothing.
+
+“You understand... it is too far. I cannot carry this body with me. It is too heavy.”
+
+I said nothing.
+
+“But it will be like an old abandoned shell. There is nothing sad about old shells...”
+
+I said nothing. He was a little discouraged. But he made one more effort: “You know, it will be
+very nice. I, too, shall look at the stars. All the stars will be wells with a rusty pulley. All the stars
+will pour out fresh water for me to drink...”
+
+I said nothing.
+
+“That will be so amusing! You will have five hundred million little bells, and I shall have five
+hundred million springs of fresh water...” And he too said nothing more, because he was crying...
+
+“Here it is. Let me go on by myself.” And he sat down, because he was afraid. Then he said,
+again: “You know, my flower... I am responsible for her. And she is so weak! She has four thorns,
+of no use at all, to protect herself against all the world...”
+
+I too sat down, because I was not able to stand up any longer. “There now, that is all...”
+
+He still hesitated a little; then he got up. He took one step. I could not move. There was nothing
+but a flash of yellow close to his ankle. He remained motionless for an instant. He did not cry out.
+He fell as gently as a tree falls. There was not even any sound, because of the sand.
+
+And now six years have already gone by... I have never yet told this story.
+
+The companions who met me on my return were well content to see me alive. I was sad, but I told
+them: “I am tired.” Now my sorrow is comforted a little. That is to say, not entirely. But I know
+that he did go back to his planet, because I did not find his body at daybreak. It was not such a
+heavy body... and at night I love to listen to the stars. It is like five hundred million little bells...
+But there is one extraordinary thing... when I drew the muzzle for the little prince, I forgot to add
+the leather strap to it. He will never have been able to fasten it on his sheep.
+
+So now I keep wondering: what is happening on his planet? Perhaps the sheep has eaten the
+flower... At one time I say to myself: “Surely not! The little prince shuts his flower under her glass
+globe every night, and he watches over his sheep very carefully...” Then I am happy. And there is
+sweetness in the laughter of all the stars.
+
+
+
+
+But at another time I say to myself: “At some moment or other one is absent-minded, and that is
+enough! On some one evening he forgot the glass globe, or the sheep got out, without making any
+noise, in the night...” And then the little bells are changed to tears... Here, then, is a great
+mystery.
+
+For you who also love the little prince, and for me, nothing in the universe can be the same if
+somewhere, we do not know where, a sheep that we never saw has eaten a rose... Look up at the
+sky. Ask yourselves: is it yes or no?
+
+Has the sheep eaten the flower? And you will see how everything changes... And no grown-up will
+ever understand that this is a matter of so much importance! This is, to me, the loveliest and
+saddest landscape in the world. It is the same as that on the preceding page, but I have drawn it
+again to impress it on your memory. It is here that the little prince appeared on Earth, and
+disappeared. Look at it carefully so that you will be sure to recognise it in case you travel some
+day to the African desert. And, if you should come upon this spot, please do not hurry on. Wait for
+a time, exactly under the star. Then, if a little man appears who laughs, who has golden hair and
+who refuses to answer questions, you will know who he is. If this should happen, please comfort
+me. Send me word that he has come back.
+
+
+
+END

+ 12391 - 0
hbfreetypefont.mod/harfbuzz/perf/texts/en-words.txt

@@ -0,0 +1,12391 @@
+a
+A
+aa
+AA
+aaa
+AAA
+aaae
+AAAu
+AAB
+AAC
+aacute
+Aacute
+Aacutesmall
+AAD
+aae
+AAE
+aaf
+AAF
+aalt
+aao
+aarch
+Aari
+aat
+AAT
+aatFeatureType
+AAu
+ab
+AB
+Abaza
+abb
+ABBREV
+abc
+ABC
+abcde
+abcdefghijklmnopqrstuvwxyz
+ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz
+ABD
+ABE
+ABEu
+ABF
+ABFu
+abh
+ABI
+ability
+Abkhazian
+able
+Aboriginal
+ABORIGINAL
+abort
+about
+above
+Above
+ABOVE
+abq
+abs
+absolute
+absolutely
+absorb
+abstraction
+abstractions
+ABu
+abuse
+abv
+ABVF
+abvm
+abvs
+ABVS
+ABx
+ABxCD
+ABxD
+ac
+AC
+acb
+ACBu
+acc
+ACC
+accel
+Accelerate
+accelerator
+ACCELERATOR
+accels
+accent
+ACCENT
+accents
+accept
+acceptable
+accepted
+accepting
+accepts
+access
+Access
+accessed
+accessible
+accessing
+accessors
+accommodate
+Accommodate
+accompanying
+accomplish
+according
+According
+account
+accounting
+ACCu
+accumulate
+Accumulate
+accuracy
+accurate
+AccuT
+ACDu
+acf
+ach
+Achi
+achieve
+Acholi
+achung
+achVendID
+acircumflex
+Acircumflex
+Acircumflexsmall
+ack
+acm
+Acoli
+acom
+acq
+ACQ
+acquire
+ACQUIRE
+acr
+across
+act
+action
+Action
+ACTION
+actionable
+actionClass
+actionData
+actionLength
+actions
+Actions
+ActionSubrecord
+ActionSubrecordHeader
+actionType
+ActionType
+activated
+activates
+active
+acts
+actual
+Actual
+actualGlyphsCount
+actually
+ACu
+acute
+Acutesmall
+acw
+acx
+acy
+ad
+AD
+ada
+Adamawa
+Adangme
+Adap
+adapt
+Adapted
+Adaptors
+aData
+adb
+ADBu
+add
+Add
+addcnt
+added
+AddFontMemResourceEx
+addGlyph
+adding
+Adding
+addition
+Addition
+additional
+Additional
+additionalCount
+additions
+addr
+AddRef
+address
+addressof
+adds
+ADDu
+Adeni
+adequate
+adf
+adieresis
+Adieresis
+Adieresissmall
+Adilabad
+adjacent
+Adjacent
+adjust
+Adjust
+adjusted
+adjustment
+adjustments
+Adjusts
+ADL
+Adlam
+ADLAM
+adobe
+Adobe
+adopt
+Adopted
+adorned
+adp
+ADu
+adv
+advance
+Advance
+Advanced
+advanceMax
+advanceMeasurement
+advanceOffset
+advances
+ADVANCES
+Advancing
+advantage
+ADVISED
+advMap
+ady
+Adyghe
+ae
+AE
+aea
+aeaf
+aeb
+aec
+AEDu
+AEEu
+AEFu
+Aegean
+AEsmall
+AEu
+af
+AF
+afa
+afadd
+Afar
+AFAu
+afb
+AFBAu
+AFBu
+AFDKO
+AFEu
+AFF
+affect
+affected
+affecting
+affects
+affinity
+Afghanistan
+Africa
+Afrikaans
+after
+After
+AFTER
+afterGrowLimit
+afterShrinkLimit
+AFu
+AG
+again
+against
+Agaw
+Agfa
+agnostic
+agrave
+Agrave
+Agravesmall
+agree
+agreement
+ahead
+Aheri
+ahg
+Ahom
+AHOM
+aht
+Ahtena
+ai
+AI
+aii
+AIN
+aio
+Aiton
+aiw
+AIX
+ajp
+ak
+aka
+AKA
+Akan
+AKAT
+AKHN
+alaph
+ALAPH
+alas
+Alaska
+Alaskan
+Albania
+Albanian
+ALBANIAN
+Albay
+alef
+Alef
+ALEF
+Algeria
+Algerian
+algorithm
+Algorithm
+algorithmic
+algorithms
+Algorithms
+algs
+ALGS
+alias
+aliased
+aliases
+aliasing
+align
+aligned
+alignment
+alignof
+aligns
+alive
+all
+All
+ALL
+ALLAH
+AllDirections
+Allison
+alloc
+Alloc
+allocate
+Allocate
+ALLOCATE
+allocated
+allocates
+allocating
+allocation
+Allocation
+allocations
+Allocations
+allocator
+allow
+Allow
+allowed
+allowing
+allows
+almost
+aln
+alone
+along
+alpha
+Alpha
+alphabet
+Alphabet
+alphabetic
+Alphabetic
+alphabetical
+alphabetically
+Alphanumeric
+Alphanumerics
+already
+als
+Alsatian
+also
+Also
+alt
+ALT
+Altai
+alter
+alternate
+Alternate
+ALTERNATE
+alternates
+ALTERNATES
+alternateSet
+AlternateSet
+AlternateSubst
+AlternateSubstFormat
+alternative
+Alternatively
+ALTERNATIVES
+although
+Although
+alts
+always
+Always
+am
+AM
+ambiguity
+ambiguous
+Ambo
+Amend
+American
+Americanist
+amf
+Amharic
+among
+amongst
+amount
+Amoy
+amp
+ampersand
+ampersandsmall
+amw
+an
+An
+AN
+Ana
+analysis
+Analysis
+ANALYSIS
+analyze
+Analyze
+analyzer
+Analyzer
+analyzers
+Analyzes
+AnalyzeScript
+ANATOLIAN
+Ancash
+anchor
+Anchor
+anchorData
+anchored
+AnchorFormat
+AnchorMatrix
+anchorPoint
+anchors
+Ancient
+and
+And
+AND
+android
+Android
+ANDROID
+ang
+angle
+Angle
+ANGLE
+Anglo
+ankr
+ANKR
+ankrActionIndex
+ankrData
+annex
+annotate
+Annotated
+annotation
+ANNOTATION
+annotations
+another
+Another
+Ansi
+Antankarana
+Antillean
+any
+Any
+ANY
+anymore
+anything
+Anything
+anyway
+ap
+Apache
+apc
+apd
+Api
+API
+apis
+APIs
+apj
+apk
+apl
+apm
+APP
+Apparently
+appear
+appearance
+appearing
+append
+Append
+APPEND
+appended
+appending
+Appendix
+AppendixF
+Appends
+Appl
+APPL
+apple
+Apple
+APPLE
+AppleColorEmoji
+applicable
+Applicable
+APPLICABLE
+application
+applications
+Applications
+ApplicationServices
+applied
+applies
+apply
+Apply
+APPLY
+applying
+Applying
+approach
+approaches
+appropriate
+approxequal
+approximate
+appveyor
+April
+apt
+Apurímac
+apw
+AQ
+ar
+Arabia
+ARABIAN
+arabic
+Arabic
+ARABIC
+ArabicShaping
+Aragonese
+Arakanese
+Arakwal
+Aramaic
+ARAMAIC
+arb
+Arbëreshë
+arbitrarily
+arbitrary
+ARC
+Archaic
+architecturally
+archive
+archives
+are
+ARE
+area
+Area
+Arequipa
+arg
+ARG
+Argentina
+Argh
+args
+ARGS
+argStack
+argument
+arguments
+aring
+Aring
+Aringsmall
+ARISING
+arith
+arithmetic
+Ariza
+armcc
+Armenia
+Armenian
+ARMENIAN
+arn
+Aromanian
+around
+arounds
+Arpitan
+arq
+arr
+arranged
+array
+Array
+ARRAY
+ArrayOf
+ArrayOfM
+arrays
+arrayZ
+arrive
+Arrows
+ars
+Arsi
+articles
+Arvanitika
+ary
+arz
+as
+As
+AS
+Asat
+ascender
+ASCENDER
+ascenderOffset
+ascending
+ascent
+ASCENT
+ascii
+ASCII
+asciicircum
+asciitilde
+Asho
+Asian
+aSize
+asked
+Asking
+Asmall
+Asomtavruli
+aspect
+aspects
+aspx
+Assamese
+assembly
+assert
+ASSERT
+assertion
+ASSERTION
+assign
+Assign
+ASSIGN
+assignable
+assigned
+assigns
+assistance
+assisted
+associated
+associates
+associating
+Association
+assume
+Assume
+assumed
+Assumed
+assuming
+Assuming
+assumption
+Assumption
+Assyrian
+ast
+asterisk
+ASTERISK
+Asturian
+asuperior
+at
+At
+atexit
+ATEXIT
+aTextPosition
+ath
+Athapascan
+Athapaskan
+Atikamekw
+atilde
+Atilde
+Atildesmall
+atj
+Atlas
+atleast
+ATLEAST
+atomic
+Atomic
+ATOMIC
+Atomically
+atomics
+atsFont
+ATSFontGetFileReference
+ATSFontRef
+attach
+Attach
+ATTACH
+attached
+ATTACHED
+attaches
+attaching
+attachList
+AttachList
+attachment
+Attachment
+ATTACHMENT
+attachments
+attachPoint
+AttachPoint
+attempt
+attempted
+attempts
+Attempts
+attr
+ATTR
+attractive
+attrib
+attribute
+ATTRIBUTE
+attributed
+attributes
+Attributes
+attrs
+atv
+au
+Au
+AU
+audiences
+augmented
+Australia
+Austria
+Author
+AUTHOR
+authors
+auto
+AUTO
+autoconf
+autogen
+automake
+automatic
+Automatic
+automatically
+auxiliary
+Auxiliary
+auz
+av
+AV
+Avagraha
+AVAGRAHA
+avail
+Availability
+AvailabilityMacros
+available
+avar
+Avar
+AVAR
+Avaric
+AVESTAN
+avl
+avoid
+Avoid
+avoided
+avoiding
+avoids
+aw
+awa
+Awa
+Awadhi
+aware
+away
+awful
+ax
+Ax
+AxCD
+AxD
+axes
+axesZ
+axis
+Axis
+AXIS
+axisCount
+axisIndex
+axisNameID
+AxisRecord
+axisSize
+axisTag
+AxisValue
+axisValueCount
+AxisValueFormat
+AxisValueMap
+AxisValueRecord
+axisValues
+ay
+Ayacucho
+ayc
+ayh
+AYIN
+ayl
+Aymara
+ayn
+ayp
+ayr
+az
+azb
+Azerbaijan
+Azerbaijani
+Azeri
+azj
+b
+B
+ba
+BA
+Babalia
+Babine
+BABu
+Bacanese
+back
+backend
+backends
+background
+Background
+BACKGROUND
+backing
+backslash
+backtrack
+backtrackClassDef
+backtrackCount
+backtracking
+backward
+BACKWARD
+backwards
+Backwards
+bad
+Badaga
+badly
+BADLY
+bae
+BAEu
+BAFu
+Bagheli
+Baghelkhandi
+Bagirmi
+Bagri
+Baharna
+Bahrain
+bai
+bail
+Bakhtiari
+bal
+Balanta
+Balante
+Balinese
+BALINESE
+Balkan
+Balkar
+Balochi
+Balti
+Baltic
+Baluchi
+Bamanankan
+Bambara
+Bamileke
+BAMUM
+ban
+Banda
+Bandjalang
+Bangka
+Bangladesh
+Bangun
+Banjar
+Banna
+Baoulé
+bar
+Bara
+BARREE
+barrier
+Barrier
+bars
+Bas
+base
+Base
+BASE
+baseArray
+BaseArray
+BaseCoord
+BaseCoordFormat
+baseCoords
+baseCoverage
+BaseCoverage
+based
+Based
+BaseFontBlend
+baseFontName
+BaseFontName
+BaseGlyph
+BaseGlyphRecord
+baseGlyphsZ
+BaseLangSysRecord
+baseLangSysRecords
+BaseLangSysRecords
+baseLangSysTag
+baseline
+Baseline
+BASELINE
+baselines
+BaselineTableFormat
+baselinetags
+baselineTags
+bases
+baseScript
+BaseScript
+baseScriptList
+BaseScriptList
+BaseScriptRecord
+baseScriptRecords
+BaseScriptRecords
+baseScriptTag
+baseTagCount
+baseTagList
+BaseTagList
+baseValues
+BaseValues
+Bashkir
+basic
+Basic
+BASIC
+basically
+BASIS
+Basque
+BASSA
+Batak
+BATAK
+batch
+BAu
+Baulé
+Bavarian
+Bawm
+BB
+BBAu
+BBBu
+bbc
+bbee
+BBEu
+BBF
+BBu
+bbz
+bc
+BC
+bca
+BCA
+BCAu
+BCBu
+bcc
+BCCu
+bcd
+BCD
+BCDu
+BCEu
+bci
+bcl
+bcp
+BCP
+bcq
+bcr
+BCu
+bcursor
+bd
+BD
+bdadd
+bdfaab
+bdu
+BDu
+bdy
+be
+Be
+BE
+bea
+BEAM
+bearing
+bearings
+bearingX
+bearingY
+Beaver
+beb
+Bebele
+Bebil
+bec
+because
+Because
+become
+BECOME
+becomes
+bed
+Bedawi
+BEEH
+been
+BEEN
+BEEu
+before
+Before
+BEFORE
+beforeGrowLimit
+beforehand
+beforeShrinkLimit
+BeforeSub
+began
+begin
+BEGIN
+beginning
+Beginning
+BEH
+behave
+behaved
+behaving
+behavior
+behaviors
+behaviour
+Behdad
+BEHEH
+behind
+Bei
+being
+Being
+BEInt
+Belarus
+Belarusian
+Belarussian
+Belgium
+Belize
+belong
+belonging
+belongs
+below
+Below
+BELOW
+bem
+Bemba
+Bench
+bend
+benefits
+BENG
+Bengali
+BENGALI
+ber
+Berau
+Berber
+best
+Bet
+BET
+Beti
+bets
+Betsimisaraka
+better
+between
+BEu
+beyond
+bf
+BF
+bfaeafe
+BFAu
+bfb
+BFF
+bffc
+BFFu
+bfind
+BFIND
+bfq
+bft
+bfu
+BFu
+bfy
+bg
+bgc
+bgn
+bgp
+bgq
+bgr
+BGRAColor
+Bhaiksuki
+BHAIKSUKI
+Bhasha
+bhb
+bhi
+Bhilali
+Bhili
+bhk
+bho
+Bhojpuri
+bhr
+bi
+Bi
+bias
+biased
+biasedSubrs
+Bible
+Bicolano
+bidi
+bidirectional
+BiDirectional
+bidirectionality
+big
+Big
+BIG
+BigGlyphMetrics
+bik
+Bikol
+BILD
+Bilen
+Bilin
+billion
+bimap
+BIMAP
+bin
+binaries
+binary
+Binary
+BINARY
+bindings
+Bindu
+BINDU
+Bindus
+BinSearchArrayOf
+BinSearchHeader
+Bishnupriya
+Bislama
+bit
+Bit
+bitcount
+bitDepth
+bitfield
+bithacks
+Bithacks
+bitmap
+Bitmap
+BITMAP
+bitmaps
+BitmapSizeTable
+bits
+Bits
+BITS
+BitScanForward
+BitScanReverse
+bitset
+bitsize
+bitwise
+bjj
+bjn
+BJN
+bjq
+bjt
+bl
+BL
+bla
+black
+Black
+BLACK
+Blackfoot
+blackhole
+blacklist
+BLACKLIST
+blacklisted
+blacklisting
+Blas
+ble
+blend
+Blend
+BLEND
+blendcs
+blenddict
+blended
+blending
+BlendInterpEnv
+blends
+Blink
+blk
+bln
+blob
+BLOB
+blobs
+Blobs
+block
+Block
+BLOCK
+blocked
+Blocked
+blocks
+Blocks
+Bloom
+blow
+blown
+blue
+Blue
+BlueFuzz
+BlueScale
+BlueShift
+BlueValues
+blwf
+BLWF
+blwm
+blws
+BLWS
+bm
+bmg
+bmm
+bmp
+BMP
+bn
+bo
+Bodo
+body
+bok
+Bokmal
+Bokmål
+bold
+Bold
+BOLD
+bolder
+Bolivia
+Bolivian
+book
+Book
+bookbold
+bookkeeping
+bool
+BOOL
+Boolean
+Booleans
+BOOM
+Bopomofo
+BOPOMOFO
+Borana
+BORDERS
+Borgu
+Borrowed
+Bosnia
+Bosnian
+BOT
+both
+bother
+bottom
+Bottom
+BOTTOM
+bottomSide
+bound
+Bound
+boundaries
+boundary
+Boundary
+bounding
+bounds
+Bounds
+BOUNDS
+Bouyei
+box
+Box
+BOX
+boxed
+BOXED
+boxes
+bpy
+bqi
+br
+BR
+bra
+braceleft
+braceright
+braces
+Bracket
+BRACKET
+bracketleft
+bracketright
+Brahmi
+BRAHMI
+Brahui
+Braille
+BRAILLE
+Braj
+branches
+brand
+Brawer
+Brazil
+break
+BREAK
+breakfast
+breaking
+breakpoint
+BREAKPOINT
+breaks
+bretagne
+Breton
+breve
+Brevesmall
+brew
+brh
+brief
+broken
+Broken
+brokenbar
+Brunei
+Bruno
+bruteforce
+brx
+bs
+bsb
+bsearch
+bsk
+bsln
+BSLN
+Bsmall
+bsuperior
+bswap
+btb
+btj
+bto
+bts
+btt
+BTT
+bu
+Bu
+Bualkhaw
+Bubble
+bucket
+buf
+buff
+buffArray
+buffer
+Buffer
+BUFFER
+buffers
+Buffers
+BUFSIZ
+bug
+BUG
+buggy
+Buginese
+BUGINESE
+Bugis
+bugs
+bugzilla
+Buhi
+Buhid
+BUHID
+build
+builder
+Builder
+building
+Building
+builds
+built
+builtin
+BUILTIN
+builtins
+Bukit
+Bukusu
+Bulgaria
+Bulgarian
+bulk
+bullet
+Bulu
+bum
+Bumthangkha
+bundles
+burden
+Buriat
+Burmese
+Burushaski
+business
+but
+But
+BUT
+BV
+bve
+bvu
+bxk
+bxp
+bxr
+by
+By
+BY
+Byagowi
+Byelorussian
+byes
+byn
+byte
+Byte
+BYTE
+byteArray
+byteOffsetToIndex
+bytes
+Bytes
+BYTES
+bytesArray
+bytesX
+bytesZ
+byv
+Byzantine
+bzc
+c
+C
+ca
+Ca
+CA
+CABu
+caca
+cache
+Cache
+CACHE
+cacheable
+cached
+caches
+caching
+Caching
+cacute
+Cacute
+caf
+cairo
+Cairo
+cairographics
+Cajamarca
+Cajatambo
+Cajun
+cak
+calcOffSize
+CalcTableChecksum
+calculate
+Calculate
+calculated
+calculates
+calculation
+Calderón
+Calibry
+call
+Call
+callback
+Callback
+callbacks
+CALLBACKS
+called
+Called
+caller
+callers
+callgsubr
+calling
+calloc
+calls
+Calls
+callStack
+callsubr
+calt
+Cambodia
+Cameroon
+Campidanese
+can
+Can
+Canada
+Canadian
+CANADIAN
+Cañar
+CANCEL
+candidate
+candidates
+cannot
+Cannot
+canon
+canonical
+Canonical
+CANONICAL
+canonically
+cantarell
+Cantarell
+Cantillation
+CANTILLATION
+cap
+Cap
+CAP
+capabilities
+capable
+capital
+CAPS
+care
+careful
+carefully
+caret
+Caret
+CARET
+caretOffset
+carets
+caretSlopeDenominator
+caretSlopeNumerator
+caretSlopeRise
+caretSlopeRun
+CaretValue
+caretValueFormat
+CaretValueFormat
+caretValuePoint
+Carian
+CARIAN
+Caribbean
+caron
+Caronsmall
+Carpathian
+Carrier
+carry
+cas
+cascade
+cascading
+case
+CASE
+cases
+cast
+Cast
+casting
+casts
+Casts
+cat
+Cat
+CAT
+Catalan
+Catanduanes
+catch
+categories
+Categories
+CATEGORIES
+categorization
+categorize
+categorized
+categorizes
+category
+Category
+CATEGORY
+Cateories
+CAu
+CAUCASIAN
+cause
+caused
+causes
+causing
+cautious
+cb
+CB
+cbb
+CBCu
+cbdt
+CBDT
+CBEu
+CBFu
+cbk
+cbl
+cblc
+CBLC
+CBu
+cc
+Cc
+CC
+ccaron
+Ccaron
+CCAu
+CCBu
+ccc
+CCC
+ccccae
+cccf
+CCCu
+CCD
+CCDu
+ccedilla
+Ccedilla
+Ccedillasmall
+CCEu
+cChars
+ccmp
+cco
+ccq
+CCu
+cd
+CD
+CDATA
+cdd
+cdo
+CDu
+CDx
+CDxA
+CDxAB
+CDxBA
+ce
+CE
+ceb
+Cebuano
+CECu
+cedilla
+Cedillasmall
+CEDu
+CEEu
+ceil
+CEIL
+cent
+center
+Center
+centered
+CENTERED
+centinferior
+centoldstyle
+CentOS
+central
+Central
+centsuperior
+ceparams
+certain
+Certain
+CEu
+cf
+Cf
+CF
+cfar
+CFAR
+CFArrayAppendValue
+CFArrayCreate
+CFArrayCreateMutable
+CFArrayGetCount
+CFArrayGetValueAtIndex
+CFArrayRef
+CFAttributedStringCreateMutable
+CFAttributedStringRemoveAttribute
+CFAttributedStringReplaceString
+CFAttributedStringSetAttribute
+CFComparisonResult
+cfd
+CFData
+CFDataGetBytePtr
+CFDataGetLength
+CFDataRef
+CFDictionaryCreate
+CFDictionaryGetValue
+CFDictionaryRef
+CFDu
+CFEqual
+cff
+CFF
+cfff
+CFFIndex
+CFFIndexOf
+CFFTag
+CFFu
+CFIndex
+cfm
+CFMutableArrayRef
+CFMutableAttributedStringRef
+CFNumberCreate
+CFNumberRef
+CFRange
+CFRangeMake
+CFRelease
+CFRetain
+CFSTR
+CFStringCompare
+CFStringCreateWithCharactersNoCopy
+CFStringCreateWithCStringNoCopy
+CFStringGetCharacterAtIndex
+CFStringHasPrefix
+CFStringHasSuffix
+CFStringRef
+CFu
+CFURLCreateFromFSRef
+CFURLRef
+cg
+CGDataProviderCreateWithData
+CGDataProviderRef
+CGDataProviderRelease
+CGFloat
+CGFont
+CGFontCopyPostScriptName
+CGFontCopyTableForTag
+CGFontCreateWithDataProvider
+CGFontRef
+CGFontRelease
+CGFontRetain
+cgg
+CGGlyph
+cgi
+cgit
+CGJ
+cGlyphs
+CGPoint
+ch
+Chachapoyas
+Chadian
+Chaha
+chain
+Chain
+chainContext
+ChainContext
+ChainContextApplyLookupContext
+ChainContextClosureLookupContext
+ChainContextCollectGlyphsLookupContext
+ChainContextFormat
+ChainContextPos
+ChainContextSubst
+chainCount
+chaining
+Chaining
+ChainRule
+ChainRuleSet
+chains
+Chains
+ChainSubtable
+Chakma
+CHAKMA
+Chaldean
+Cham
+CHAM
+Chamorro
+chance
+chandas
+change
+Change
+changed
+changes
+Changes
+changing
+channel
+channels
+Chap
+chapter
+Chapter
+char
+Char
+CHAR
+character
+Character
+CHARACTER
+characterCode
+characterize
+characters
+Characters
+CHARACTERS
+characterVariants
+charmap
+Charmap
+charMirror
+CHARPROP
+chars
+charset
+Charset
+CHARSET
+CharsetID
+charsetInfo
+CharsetOffset
+charstreing
+charstring
+CharString
+charstrings
+charStrings
+CharStrings
+charStringsInfo
+charStringsOffset
+CharstringType
+charts
+chattawa
+CHATTAWA
+Chattisgarhi
+Chaungtha
+Chavacano
+cheaper
+Chechen
+check
+Check
+CHECK
+checked
+CHECKED
+checking
+Checking
+checks
+Checks
+checksum
+checkSum
+CheckSum
+checkSumAdjustment
+Cherokee
+CHEROKEE
+Chetco
+Chewa
+Cheyenne
+Chhattisgarhi
+Chichewa
+Chiga
+Chiki
+CHIKI
+Chilcotin
+child
+children
+Chile
+Chilean
+Chillus
+Chiltepec
+Chimborazo
+Chin
+China
+Chinantec
+Chinbon
+Chincha
+Chinese
+Chipewyan
+Chippewa
+Chiquián
+Chiricahua
+Chiripá
+Chittagonian
+chj
+chk
+CHL
+cho
+Choctaw
+choice
+choices
+choose
+Choose
+chooses
+choosing
+chop
+Chop
+chosen
+CHOSEONG
+chp
+chq
+chr
+chris
+Chris
+chromium
+Chromium
+Chuanqiandian
+Chukchi
+Chukot
+chunk
+ChunkLen
+chunks
+Church
+Chuukese
+Chuvash
+chy
+chz
+ci
+CI
+CID
+cidCount
+CIDCount
+CIDFontRevision
+CIDFontType
+CIDFontVersion
+CIN
+cInChars
+CIP
+circle
+CIRCLE
+circles
+circuit
+CIRCUIT
+circumflex
+Circumflexsmall
+circumstances
+circumvents
+citer
+CITI
+ciw
+cja
+CJCT
+CJK
+cjm
+cjy
+ck
+CK
+cka
+ckb
+ckt
+cl
+Clamp
+clang
+clarity
+Clasen
+class
+Class
+CLASS
+classArray
+classCount
+classDef
+ClassDef
+ClassDefFormat
+classes
+classFormat
+Classic
+Classical
+classifications
+classified
+classify
+classTable
+ClassTable
+ClassType
+ClassTypeNarrow
+ClassTypeWide
+classValue
+classValueArray
+clc
+cld
+cle
+clean
+Clean
+cleanest
+clear
+Clear
+cleared
+clearing
+clearly
+clears
+Clears
+ClearType
+ClearType™
+client
+Client
+clients
+Clients
+clig
+clipping
+CLIPPING
+clockwise
+close
+Close
+CLOSE
+CloseHandle
+closely
+closer
+closest
+CLOSEST
+closure
+Closure
+CLOSURE
+closures
+cluster
+Cluster
+CLUSTER
+clustering
+clusterMap
+clusters
+Clusters
+CLUSTERS
+clz
+clzl
+clzll
+CM
+CMAbv
+cmake
+cmap
+CMAP
+cmapsubtable
+CmapSubtable
+CmapSubtableFormat
+CmapSubtableLongGroup
+CmapSubtableLongSegmented
+CmapSubtableTrimmed
+cMaxGlyphs
+cMaxItems
+CMBlw
+cmn
+cmp
+cmpexch
+cmplexch
+cmpswap
+cmr
+cn
+Cn
+cnb
+cnh
+cnk
+cnl
+cnt
+cntrmask
+cnw
+co
+Co
+coa
+Cocos
+code
+Code
+CODE
+codebase
+coded
+codepath
+codepoint
+CODEPOINT
+codepoints
+codepont
+codes
+Codethink
+Coeng
+COENG
+coengs
+col
+Col
+collect
+Collect
+COLLECT
+collected
+collection
+Collection
+collections
+Collections
+collects
+Colombia
+colon
+COLON
+colonmonetary
+color
+Color
+COLOR
+colorIdx
+colorLabelsZ
+ColorRecord
+colorRecordIndicesZ
+colorRecordsZ
+colorRef
+colors
+colorType
+Colour
+colr
+COLR
+cols
+COLS
+columnCount
+columnIndexTable
+com
+Comaltepec
+combination
+combinations
+combine
+COMBINE
+combined
+combiner
+combiners
+combining
+Combining
+COMBINING
+come
+comes
+comfortably
+coming
+comma
+COMMA
+commainferior
+command
+Command
+commands
+commas
+commasuperior
+comment
+Commenting
+comments
+commit
+commitcomment
+commits
+common
+Common
+COMMON
+commonly
+Comorian
+comp
+compact
+Compact
+compar
+compare
+Compare
+compared
+compares
+comparing
+Comparing
+comparison
+compat
+compatibility
+Compatibility
+COMPATIBILITY
+compatible
+COMPATIBLE
+compensate
+compilable
+compile
+Compile
+compiled
+compiler
+Compiler
+compilers
+compiles
+COMPILES
+compiling
+complains
+complang
+Complement
+complete
+Complete
+completely
+complex
+Complex
+COMPLEX
+COMPLEXITY
+complicated
+component
+COMPONENT
+componentData
+ComponentGlyph
+components
+Components
+COMPONENTS
+ComponentsArray
+composable
+compose
+composed
+COMPOSED
+composePair
+composes
+Composes
+composing
+composite
+COMPOSITE
+CompositeGlyph
+CompositeGlyphChain
+composites
+composition
+Composition
+COMPOSITION
+COMPOUND
+compressed
+compressionMethod
+comprise
+comprising
+comps
+compute
+Compute
+Computes
+computing
+concepts
+Concepts
+conceptual
+Conceptually
+concern
+concerned
+Conchucos
+cond
+Cond
+condensed
+Condensed
+CONDENSED
+condition
+Condition
+conditional
+conditionalAddGlyphAction
+ConditionalAddGlyphAction
+conditionally
+ConditionFormat
+conditions
+Conditions
+ConditionSet
+config
+CONFIG
+configs
+configuration
+Configuration
+configurations
+configure
+configured
+conflicting
+confused
+confusing
+Congo
+conjunct
+connect
+CONNECT
+connected
+CONNECTED
+connecting
+connection
+CONNECTION
+connector
+CONNECTOR
+Cons
+CONS
+consecutive
+CONSEQUENTIAL
+Consequently
+consider
+Consider
+considerably
+consideration
+considerations
+considered
+consist
+consistent
+consists
+consonant
+Consonant
+CONSONANT
+consonants
+const
+CONST
+constant
+CONSTANT
+constants
+Constants
+constexpr
+constituent
+constitute
+constitutes
+constraints
+CONSTRAINTS
+construct
+constructed
+constructible
+construction
+constructor
+constructors
+Constructors
+constructs
+consult
+consumed
+contain
+contained
+container
+containers
+containing
+contains
+ContainsTextPosition
+contemporary
+content
+CONTENT
+contents
+context
+Context
+CONTEXT
+ContextApplyFuncs
+ContextApplyLookupContext
+ContextClosureFuncs
+ContextClosureLookupContext
+ContextCollectGlyphsFuncs
+ContextCollectGlyphsLookupContext
+ContextFormat
+ContextPos
+contexts
+ContextSubst
+contextual
+Contextual
+CONTEXTUAL
+ContextualSubtable
+contiguous
+continuation
+CONTINUATION
+continuations
+continue
+continues
+contour
+Contour
+contours
+contract
+CONTRACT
+contrary
+contrast
+contributing
+Contributor
+control
+Control
+CONTROL
+controlling
+controls
+convenience
+conveniences
+convenient
+conventions
+Conversely
+conversion
+Conversion
+Conversions
+convert
+Convert
+converted
+Converted
+converters
+convertible
+converting
+Converts
+convoluted
+coord
+coordinate
+Coordinate
+coordinates
+Coordinates
+COORDINATES
+coordinatesZ
+coordPoint
+coords
+coorinates
+cop
+copied
+Copied
+copies
+Copies
+Coptic
+COPTIC
+copy
+Copy
+COPY
+copyable
+copying
+copyright
+Copyright
+COPYRIGHT
+coq
+Coquille
+core
+CoreGraphics
+coretext
+CoreText
+CORETEXT
+corner
+CORNER
+corners
+Cornish
+Corongo
+correct
+correction
+correctionHeight
+correctly
+Correctly
+correctness
+correlate
+correspond
+corresponding
+corresponds
+corrupt
+Corsican
+cost
+Costa
+costs
+costy
+cotfRecords
+could
+Could
+count
+Count
+COUNT
+countChar
+counted
+counter
+counting
+Counting
+CountMask
+countries
+counts
+couple
+Courier
+course
+courtesy
+cover
+coverage
+Coverage
+COVERAGE
+coverageFormat
+CoverageFormat
+coverageZ
+covered
+COVERED
+covering
+covers
+cp
+CP
+cpa
+cpal
+CPAL
+CPALV
+cpe
+cpf
+cplusplus
+cpp
+cppreference
+CPR
+CPrf
+cpx
+cqd
+cqu
+cr
+CRAMPED
+cRanges
+crap
+Crap
+CRAP
+CrapHelper
+CrapOrNull
+CrapOrNullHelper
+CrapPool
+crash
+crashes
+crazy
+crbug
+create
+Create
+CREATE
+CreateCustomFontFileReference
+created
+CreateFile
+CREATEFILE
+CreateFileMapping
+CreateFileMappingFromApp
+CreateFileW
+CreateFontFace
+CreateFontIndirectW
+creates
+Creates
+CreateStreamFromKey
+CreateTextAnalyzer
+creating
+Creating
+creation
+creator
+Cree
+Creek
+Creole
+creoles
+Creoles
+crh
+Crimean
+Crioulo
+criteria
+CRITICAL
+crj
+crk
+crl
+crm
+Croatia
+Croatian
+cross
+Cross
+crossStream
+CrossStream
+crp
+crucial
+crx
+cs
+Cs
+CS
+csa
+csb
+csh
+Csmall
+cso
+csop
+CSOPSET
+CSR
+CSS
+CSType
+csw
+cswh
+csy
+ct
+ctc
+ctd
+cte
+CTFont
+CTFontCopyAttribute
+CTFontCopyGraphicsFont
+CTFontCopyName
+CTFontCopyPostScriptName
+CTFontCreateCopyWithAttributes
+CTFontCreateUIFontForLanguage
+ctfontcreatewithgraphicsfont
+CTFontCreateWithGraphicsFont
+CTFontDescriptorCreateWithAttributes
+CTFontDescriptorCreateWithNameAndSize
+CTFontDescriptorRef
+CTFontGetPlatformFont
+CTFontGetSize
+CTFontRef
+CTFontUIFontType
+ctg
+CTGetCoreTextVersion
+ctl
+CTLineGetGlyphRuns
+CTLineGetTrailingWhitespaceWidth
+CTLineRef
+ctlPoints
+ctor
+CTRunGetAttributes
+CTRunGetGlyphCount
+CTRunGetGlyphs
+CTRunGetGlyphsPtr
+CTRunGetPositions
+CTRunGetPositionsPtr
+CTRunGetStatus
+CTRunGetStringIndices
+CTRunGetStringIndicesPtr
+CTRunGetStringRange
+CTRunGetTypographicBounds
+CTRunRef
+CTRunStatus
+cts
+CTTypesetterCreateLine
+CTTypesetterCreateWithAttributedStringAndOptions
+CTTypesetterRef
+CTYPE
+ctz
+ctzl
+ctzll
+cu
+Cu
+cuc
+cuk
+cumulated
+Cumulative
+Cuneiform
+CUNEIFORM
+cur
+curEntry
+Curiously
+CURISVE
+CURLY
+curr
+curradv
+curradvx
+curradvy
+currAnchor
+currAnchorPoint
+currclus
+currControlPoint
+currency
+Currency
+CURRENCY
+current
+Current
+CurrentCategory
+currentIndex
+currentInsertBefore
+CurrentInsertBefore
+currentInsertCount
+CurrentInsertCount
+currentInsertIndex
+currentInsertList
+CurrentIsKashidaLike
+currently
+Currently
+currX
+currY
+curs
+cursive
+Cursive
+CURSIVE
+CursivePos
+CursivePosFormat
+cursor
+Cursor
+cursoring
+curve
+CURVE
+Cusco
+custom
+Custom
+customization
+customize
+customizing
+Customizing
+CustomRange
+cut
+CUT
+cutting
+cv
+cvn
+CVT
+cvXX
+cwd
+CWS
+cx
+cy
+CYGWIN
+Cypriot
+CYPRIOT
+Cyrillic
+CYRILLIC
+Czech
+czh
+czo
+czt
+d
+D
+da
+DA
+Daai
+DAD
+DAFu
+dagesh
+DAGESH
+dagger
+daggerdbl
+DAHAL
+Dai
+DAL
+DALATH
+DALET
+dam
+DAMAGE
+DAMAGES
+damma
+dammatan
+Dan
+dance
+dangerous
+Dangme
+Danish
+dao
+dap
+dar
+Dargwa
+Dari
+dark
+DARK
+Darkhat
+Darussalam
+Darwazi
+DASH
+data
+Data
+DATA
+dataArray
+dataArrayLen
+Database
+dataLen
+dataLength
+DataMap
+dataMaps
+dataOffset
+dataset
+dataSets
+dataSize
+dataSizeArray
+dataZ
+Date
+DAu
+David
+Daw
+dax
+day
+Dayi
+db
+DB
+DBAu
+DBBu
+DBCu
+DBEu
+DBF
+dbfo
+DBL
+DBu
+dc
+DC
+DCA
+DCAu
+DCBu
+DCFu
+dcroat
+DCu
+DCx
+DCxA
+DCxAB
+DCxBA
+dd
+DD
+DDA
+DDAHAL
+DDAL
+DDAu
+DDCu
+DDD
+DDDu
+dde
+DDEu
+ddf
+DDF
+DDFu
+DDu
+de
+DE
+deabc
+Dead
+DEAD
+deal
+deallocate
+Deallocate
+DEALLOCATE
+deallocation
+dealt
+DEAu
+Debian
+debug
+Debug
+DEBUG
+debugging
+Debugging
+dec
+decay
+decender
+decide
+Decide
+deciding
+DECIMAL
+decipoints
+decision
+decisions
+declaration
+declarations
+declare
+Declare
+DECLARE
+declared
+declaring
+decls
+DECLS
+declspec
+decltype
+declval
+decode
+DECODE
+decomp
+decompose
+Decompose
+DECOMPOSE
+decomposed
+DECOMPOSED
+decomposedglyphs
+decomposes
+decomposing
+decomposition
+DECOMPOSITION
+decompositionAction
+DecompositionAction
+decompositions
+decompressed
+deconstructed
+DECORATIVE
+DecorativeBorders
+decrease
+decreased
+decreases
+Decreases
+decreasing
+deduce
+deduced
+deduces
+deem
+deemed
+deep
+def
+DEF
+defaul
+default
+Default
+DEFAULT
+defaultBaseline
+defaultFlags
+defaultIndex
+DefaultJstfLangSys
+defaultLangSys
+DefaultLangSys
+defaultMinMax
+defaults
+defaultUVS
+DefaultUVS
+defaultValue
+defaultVertOriginY
+defaultWidthX
+define
+DEFINE
+defined
+Defined
+DEFINED
+defines
+Defines
+defining
+Defining
+definition
+Definition
+definitions
+Definitions
+DEFu
+Degexit
+degree
+DEGREE
+degrees
+Dehong
+DejaVu
+del
+delayed
+delete
+DELETE
+DeleteCriticalSection
+deleted
+DELETED
+DeleteObject
+deleting
+delimited
+DELIMITED
+delta
+Delta
+DELTA
+deltaFormat
+deltaGlyphID
+deltas
+DELTAS
+DeltaSetIndexMap
+DeltaValue
+deltaValueZ
+Democratic
+demonstrate
+den
+DENIED
+Denmark
+denom
+DENOM
+DENOMINATOR
+denote
+density
+depend
+dependant
+dependencies
+dependency
+dependent
+Dependent
+DEPENDENT
+depending
+depends
+deprecated
+Deprecated
+DEPRECATED
+depth
+deref
+dereference
+dereferenced
+dereferencing
+derived
+Derived
+DerivedCoreProperties
+desc
+descendent
+descender
+DESCENDER
+descending
+descent
+DESCENT
+describe
+described
+describes
+describing
+description
+Description
+DESCRIPTION
+descriptor
+descriptors
+Deseret
+DESERET
+deserialize
+DESERIALIZE
+design
+Design
+DESIGN
+designated
+designates
+designAxesOffset
+designAxisCount
+designAxisSize
+designed
+designer
+DESIGNER
+designSize
+desirable
+desired
+desktop
+dest
+destroy
+Destroy
+DESTROY
+destroyed
+destroying
+destroys
+Destroys
+destruct
+destructed
+destructible
+destruction
+desubroutinize
+detail
+detailed
+details
+detect
+detected
+determine
+Determine
+determined
+determines
+determining
+Determining
+DEu
+dev
+DEVA
+devanagari
+Devanagari
+DEVANAGARI
+devel
+develop
+developed
+developer
+developers
+developing
+development
+Deviate
+device
+Device
+DeviceHeader
+DeviceRecord
+devices
+deviceTable
+devnet
+df
+DF
+DFAu
+dfde
+DFDu
+dfe
+DFF
+DFFu
+dflt
+DFLT
+dfont
+DFont
+DFontTag
+DFu
+dgo
+dgr
+Dhangu
+dhd
+dhg
+Dhivehi
+Dhofari
+Dhundari
+Dhuwal
+Dhuwaya
+diacritic
+Diacritical
+diacritics
+DIACRITICS
+diagnostic
+DIAGNOSTIC
+DIAGONAL
+DIAMOND
+dib
+dict
+Dict
+DICT
+dictionary
+dicts
+dictsSize
+dictval
+DICTVAL
+did
+didn
+Didn
+didnt
+dieresis
+Dieresissmall
+diff
+DIFF
+differ
+difference
+differences
+different
+Different
+differentiate
+differently
+differing
+differs
+difficult
+difficulty
+digest
+DIGEST
+digests
+digit
+Digit
+DIGIT
+digital
+Digits
+dik
+dimensional
+dimensions
+Dimli
+din
+Dingbats
+DINGBATS
+Dinka
+dip
+DIPHTHONG
+diq
+dir
+DIR
+direct
+DIRECT
+direction
+Direction
+DIRECTION
+directional
+directionality
+directions
+directive
+directly
+directory
+directwrite
+DirectWrite
+DIRECTWRITE
+dirty
+disable
+Disable
+DISABLE
+disabled
+disableFlags
+disables
+disabling
+disallow
+disallows
+disambiguated
+Disc
+discard
+Discarding
+discards
+discern
+DISCLAIMS
+discover
+Discovered
+discretionary
+discussed
+Discussion
+dispatch
+Dispatch
+DISPATCH
+displacement
+display
+Display
+DISPLAY
+displaying
+dist
+distance
+Distance
+DISTANCE
+distances
+distinct
+distinction
+distinguish
+distinguishes
+distinguishing
+distribute
+distribution
+ditto
+div
+DIV
+Divehi
+divert
+divide
+DIVIDE
+divided
+divisible
+diw
+Djambarrpuyngu
+dje
+djr
+dks
+DLBAR
+dlig
+dll
+DLL
+dllexport
+dm
+dng
+dnj
+dnom
+do
+Do
+DO
+DOACHASHMEE
+doc
+Doc
+docbook
+DocBook
+docbookx
+docs
+DOCTYPE
+document
+Document
+documentation
+DOCUMENTATION
+documented
+documents
+Documents
+does
+Does
+doesn
+Doesn
+doesnt
+Dogra
+DOGRA
+Dogri
+Dogrib
+doi
+doing
+dollar
+dollarinferior
+dollaroldstyle
+dollarsuperior
+Domain
+dominant
+Dominican
+Domino
+don
+Don
+DON
+done
+Done
+DONE
+Dong
+dont
+DONT
+DontAdvance
+Dos
+DoS
+dot
+Dot
+DOT
+dotaccent
+Dotaccentsmall
+dotlessi
+dotsection
+dotted
+DOTTED
+dottedcircle
+DOTTEDCIRCLE
+Dotyali
+double
+DOUBLE
+down
+DOWN
+download
+downloaded
+Downloading
+downstream
+downward
+DPI
+DR
+dragons
+drain
+draw
+Draw
+drawing
+Drawing
+DRAWINGS
+drawn
+Drepper
+drh
+drive
+driver
+Driver
+drop
+Drop
+DROP
+dropped
+dropping
+drops
+drw
+ds
+dsb
+Dsmall
+dsohowto
+dst
+dsuperior
+dtd
+DTD
+dtor
+dty
+du
+Du
+dual
+Duano
+duct
+ductile
+ductileGlyphAction
+DuctileGlyphAction
+ductility
+due
+duj
+DUL
+dumb
+dumber
+Dumbest
+dummy
+Dummy
+Dungan
+dup
+dupe
+duplicate
+DUPLICATE
+duplicated
+Duplicated
+duplicates
+duplication
+DUPLOYAN
+dupped
+duration
+during
+During
+Dutch
+dv
+dw
+dwFeatures
+dwFileAttributes
+dwFileFlags
+DWORD
+dwrite
+DWrite
+DWRITE
+DWriteCreateFactory
+dwriteFactory
+DWriteFontFileLoader
+DWriteFontFileStream
+dwSecurityQosFlags
+dwSize
+dwu
+dwy
+dx
+Dx
+DxA
+DxAB
+DxBA
+dy
+DYEH
+dynamic
+dyu
+Dyula
+dz
+Dzongkha
+e
+E
+ea
+EA
+EAAu
+EABu
+each
+Each
+eachother
+EACu
+eacute
+Eacute
+Eacutesmall
+EADu
+eae
+EAEu
+EAFu
+eager
+earlier
+Earlier
+early
+EARLY
+easier
+East
+eastasian
+Eastern
+easy
+EAu
+eb
+EB
+EBAu
+EBBu
+EBCu
+ebdt
+EBDT
+EBDu
+EBEu
+EBFu
+Ebira
+eblc
+Ebrahim
+EBu
+ec
+EC
+ECAu
+ECBu
+ECCu
+ECD
+ecde
+ECDu
+ECE
+ECEu
+ecfb
+ECFu
+ecircumflex
+Ecircumflex
+Ecircumflexsmall
+ECu
+Ecuador
+ed
+ED
+eda
+EDAu
+EDBu
+EDCu
+EDDu
+EDEu
+EDFu
+edge
+edges
+edieresis
+Edieresis
+Edieresissmall
+edit
+edits
+EDITS
+Edo
+EDu
+ee
+EE
+EEAu
+EEBu
+EECu
+EEDu
+EEEEEELLLLLLLLuuuuuuuuGGGGGGGEEEEEEEE
+EEELLLGGGGEEEE
+EEEu
+EEFu
+EEu
+ef
+EF
+EFEu
+EFF
+effect
+effectively
+effects
+efficiency
+efficiently
+effort
+efi
+Efik
+EFu
+eg
+Eg
+egrave
+Egrave
+Egravesmall
+Egypt
+Egyptian
+EGYPTIAN
+eight
+EIGHT
+EIGHTEEN
+eightinferior
+eightoldstyle
+eightsuperior
+EINTR
+either
+Either
+EK
+ekk
+el
+El
+ELBASAN
+ELEM
+element
+ELEMENT
+elements
+Elements
+ELEVEN
+elidable
+ELIDABLE
+elidedFallbackNameID
+elie
+Elie
+elif
+ellipsis
+ELLIPSIS
+else
+Else
+elt
+ELT
+ELYMAIC
+em
+EM
+embed
+embedded
+EmbeddedPeakTuple
+embedding
+EMBEDDING
+emboldening
+EMBOX
+emdash
+emk
+emoji
+Emoji
+EMOJI
+emphasis
+empty
+Empty
+EMPTY
+ems
+en
+EN
+enable
+Enable
+enabled
+ENABLED
+enableFlags
+enables
+enabling
+enb
+enc
+Enclosed
+enclosing
+ENCLOSING
+encode
+ENCODE
+encoded
+Encoded
+encoder
+Encodes
+encoding
+Encoding
+ENCODING
+encodingID
+EncodingID
+encodingOffset
+EncodingOffset
+encodingrec
+EncodingRecIter
+encodingRecord
+EncodingRecord
+encodings
+encounter
+encountered
+end
+End
+END
+endash
+endchar
+endCharCode
+endcode
+endCode
+endConnectorLength
+endCoord
+endCount
+endcp
+ended
+endGlyphID
+endGlyphIndex
+endian
+Endian
+ENDIAN
+endif
+ending
+EndPtr
+endPtsOfContours
+ends
+endSize
+Enets
+enf
+enforce
+engine
+Engine
+engines
+English
+ENGRAVED
+enh
+ENHANCEMENTS
+enlarge
+Enlarge
+enough
+ensure
+Ensure
+ensures
+enter
+EnterCriticalSection
+entire
+entirely
+entirety
+ENTITY
+entries
+Entries
+entry
+Entry
+entryAnchor
+EntryAnchor
+EntryData
+EntryExit
+entryExitRecord
+EntryExitRecord
+entrySelector
+EntryT
+entryTable
+enum
+enumerate
+enumerated
+Enumerates
+enumeration
+enumerations
+enums
+env
+ENV
+environment
+eo
+eof
+EOT
+epsilon
+eq
+equal
+EQUAL
+equality
+equally
+equals
+Equatorial
+equivalent
+Eric
+err
+Err
+Erratic
+erratically
+erring
+errno
+ERRNO
+error
+Error
+ERROR
+errors
+errs
+Erzya
+es
+ESC
+escape
+escapes
+eScript
+Esfahbod
+esg
+esi
+esk
+Esmall
+esp
+especially
+Esperanto
+esque
+essence
+essentially
+Estero
+estimate
+estimated
+estimates
+Estonia
+Estonian
+Estrangela
+Estrangelo
+esu
+esuperior
+et
+etc
+eth
+Eth
+Ethiopia
+Ethiopic
+ETHIOPIC
+Ethsmall
+eto
+Eton
+eu
+Eu
+eval
+evaluate
+evaluating
+eve
+even
+Even
+EVEN
+Evenki
+event
+EVENT
+events
+eventual
+ever
+every
+Every
+everyone
+everything
+evidence
+evident
+evn
+Ewe
+ewo
+Ewondo
+exact
+exactly
+examine
+examines
+examining
+example
+examples
+exceed
+exceeds
+except
+Except
+exception
+exceptional
+exceptions
+excess
+excessive
+exch
+exchange
+exclam
+EXCLAMATION
+exclamdown
+exclamdownsmall
+exclamsmall
+excluded
+exclusion
+exclusive
+Exclusive
+exclusivity
+exe
+executable
+execute
+EXECUTE
+exhaust
+exist
+existence
+existent
+existing
+EXISTING
+exists
+exit
+exitAnchor
+ExitAnchor
+exp
+EXP
+expand
+expanded
+EXPANDED
+ExpansionFactor
+expect
+expected
+expects
+expensive
+experience
+experimental
+experimentally
+expert
+EXPERT
+ExpertCharset
+ExpertEncoding
+ExpertSubsetCharset
+explanation
+explicit
+EXPLICIT
+explicitLevel
+explicitly
+explore
+exponent
+EXPONENTS
+export
+EXPORT
+exported
+exports
+expose
+Expose
+exposed
+exposing
+Exposing
+expr
+EXPR
+express
+Express
+expressed
+expression
+expressions
+extend
+Extend
+extended
+Extended
+EXTENDED
+extendedShapeCoverage
+ExtendedTypes
+Extender
+EXTENDER
+ExtenderGlyph
+extenderGlyphs
+ExtenderGlyphs
+extensibility
+extension
+Extension
+extensionDisableGPOS
+extensionDisableGSUB
+extensionEnableGPOS
+extensionEnableGSUB
+ExtensionFormat
+extensionJstfMax
+extensionLookupType
+extensionOffset
+ExtensionOffset
+ExtensionPos
+extensions
+Extensions
+EXTENSIONS
+ExtensionSubst
+extensively
+extent
+Extent
+extents
+EXTENTS
+extern
+EXTERN
+external
+externally
+externs
+extlang
+extra
+Extra
+EXTRA
+extract
+extracted
+EXTRAS
+extreme
+extremely
+eye
+Eye
+eyelash
+eyo
+f
+F
+fa
+FA
+FAAu
+fabs
+FABu
+FAbv
+faca
+face
+Face
+FACE
+faceBlob
+Facebook
+faces
+FACESIZE
+facet
+faceType
+facilities
+facility
+fact
+factor
+FACTOR
+factors
+factory
+FACTORY
+factoryType
+FACu
+FADu
+FAEu
+FAFu
+fail
+Fail
+FAIL
+failed
+Failed
+FAILED
+failing
+FAILLING
+fails
+Fails
+failure
+FAILURE
+failures
+fairly
+Falam
+fall
+Fall
+fallback
+Fallback
+FALLBACK
+falling
+falls
+fallthrough
+FALLTHROUGH
+false
+FALSE
+family
+Family
+FAMILY
+FamilyBlues
+familyName
+FamilyName
+FamilyOtherBlues
+fan
+Fancy
+Fang
+Fanti
+faq
+far
+Faroe
+Faroese
+Farsi
+FARSI
+fashion
+fast
+faster
+fat
+fatha
+FATHA
+fathatan
+FAu
+faulty
+favor
+fb
+FB
+fba
+FBAu
+FBBu
+FBCu
+FBDu
+fbe
+FBFu
+fbl
+FBlw
+FBu
+fc
+FC
+FCAu
+fcc
+FCCu
+FCDu
+FCEu
+FCFu
+fclose
+fcntl
+FCu
+fd
+FD
+fda
+fdArray
+FDArray
+FDArrayInfo
+FDArrayOffset
+FDAu
+fdcount
+fdCount
+FDDu
+fde
+FDEFs
+FDEu
+FDF
+FDFu
+FDIndex
+fdmap
+fds
+fdsc
+FDSC
+fdselect
+fdSelect
+FDSelect
+FDSELECT
+FDSelectInfo
+FDSelectOffset
+FDu
+fe
+Fe
+FE
+feat
+FEAT
+FeatMinMaxRecord
+featMinMaxRecords
+FeatMinMaxRecords
+feats
+featUILableNameID
+featUITooltipTextNameID
+feature
+Feature
+FEATURE
+featureCount
+featureFlags
+featureIndex
+featureList
+FeatureList
+FeatureName
+featureNameCount
+featureParams
+FeatureParams
+FeatureParamsCharacterVariants
+FeatureParamsSize
+FeatureParamsStylisticSet
+featureRangeLengths
+features
+Features
+FEATURES
+featureSetting
+FeatureTableSubstitution
+FeatureTableSubstitutionRecord
+featureTableTag
+featureType
+featureval
+FeatureVariationRecord
+FeatureVariations
+featureVars
+featureZ
+FEAu
+Feb
+February
+FEBu
+FECu
+Fedora
+FEDu
+fee
+feed
+feel
+fees
+FEFF
+FEH
+fence
+feof
+ferror
+fetch
+Fetch
+fetched
+fetches
+Fetches
+fetching
+FetchNextRun
+FEu
+few
+fewer
+ff
+FF
+FFA
+FFAu
+ffbfea
+ffcdf
+FFCu
+FFEu
+FFF
+FFFD
+FFFF
+FFFFF
+FFFFFF
+FFFFFFF
+FFFFFFFFULL
+FFFFFu
+FFFFu
+FFFFULL
+FFFu
+ffi
+ffl
+ffm
+FFu
+FFULL
+ffuncs
+ffunctions
+fh
+fi
+fi
+fid
+field
+fields
+FIFTEEN
+figure
+FIGURE
+figuredash
+Fijian
+fil
+file
+File
+FILE
+filename
+fileOffset
+files
+fileSize
+fileType
+Filipino
+fill
+Fill
+filled
+FILLER
+filling
+Filling
+filter
+Filter
+filtered
+filtering
+filterMethod
+filterRangeMaxValue
+filterRangeMinValue
+filters
+FIN
+fina
+FINA
+final
+Final
+FINAL
+finalcode
+finalize
+finalizer
+Finalizer
+finally
+Finally
+finaLookup
+finaSubLookup
+find
+Find
+FINDFONT
+finding
+finds
+Finds
+fine
+fini
+finish
+Finish
+finished
+finite
+Finland
+Finnish
+Firefox
+first
+First
+FIRST
+firstAxis
+firstAxisSegmentMaps
+firstChain
+firstDeviceRecord
+firstGlyph
+firstGlyphIndex
+FirstGlyphs
+firstLayerIdx
+firstPairValueRecord
+firstParamUILabelNameID
+firstSubtable
+firstSubTable
+fit
+FITNESS
+fitting
+five
+FIVE
+fiveeighths
+fiveinferior
+fiveoldstyle
+fivesuperior
+fix
+Fix
+fixed
+Fixed
+FIXED
+fixedcs
+FixedType
+FixedVersion
+Fixes
+fixup
+Fixup
+fj
+fl
+flag
+Flag
+FLAG
+flags
+Flags
+FLAGS
+flat
+flatStr
+flatten
+Flatten
+FLATTENED
+flattener
+fLayoutRTL
+Flemish
+Fleurons
+FLEURONS
+flex
+flip
+flm
+float
+floating
+fLogicalOrder
+flooded
+floor
+florin
+flow
+Flowery
+FLT
+flush
+fly
+FM
+FMAbv
+FMBlw
+fMergeNeutralItems
+fmp
+FMPst
+fmt
+fNoGlyphIndex
+fo
+folded
+follow
+followed
+Followed
+following
+Following
+follows
+fon
+Fon
+fonipa
+fonnapa
+font
+Font
+FONT
+FontBBox
+fontconfig
+Fontconfig
+FontConfig
+FontDescriptor
+fontdict
+FontDict
+fontdicts
+fontDicts
+fontDictStr
+fontDirectionHint
+fontEmSize
+fontFace
+fontFile
+fontFileKey
+fontFileLoader
+fontFileReferenceKey
+fontFileReferenceKeySize
+fontFileStream
+FontInfo
+fontlab
+FontMatrix
+fontName
+FontName
+fontRevision
+fonts
+Fonts
+fontSzr
+fonttools
+fontTools
+FontTools
+foo
+fopen
+for
+For
+FOR
+forbid
+Force
+ForceBold
+forced
+foreach
+foreground
+Forest
+forget
+forgives
+fork
+Fork
+form
+Form
+FORM
+format
+Format
+FORMAT
+formatReserved
+formats
+Formats
+formatting
+formed
+former
+Former
+formerly
+forms
+Forms
+FORMS
+FORMULA
+forum
+forw
+forward
+FORWARD
+forwards
+found
+Found
+FOUND
+Foundation
+four
+Four
+FOUR
+fourinferior
+fouroldstyle
+foursuperior
+FOURTEEN
+fourth
+fOverrideDirection
+fp
+fprintf
+FPst
+fr
+frac
+FRACT
+fraction
+FRACTION
+fractional
+fractions
+FRACTIONS
+fragmentContext
+fragmentSize
+fragmentStart
+frame
+framework
+franc
+France
+frc
+fread
+Frédéric
+free
+Free
+FREE
+freed
+freedesktop
+Freedesktop
+freeing
+FreeLibrary
+freelocale
+freely
+freetype
+FreeType
+FREETYPE
+fref
+French
+frequent
+frequently
+fribidi
+friend
+Frisian
+Friulian
+from
+From
+FROM
+fromCoord
+FromGlyphs
+front
+frozen
+frp
+fRTL
+fscale
+Fsmall
+fsref
+FSRef
+fsSelection
+fstat
+fsType
+ft
+FT
+FTStringRange
+fu
+Fu
+fub
+fuc
+fue
+fuf
+fuh
+fui
+Fujian
+Fukien
+Fulah
+fulfilled
+Fulfulde
+full
+Full
+FULL
+fullAdvance
+fullName
+FullName
+fullset
+Fullwidth
+FULLWIDTH
+fully
+Fully
+fun
+func
+Func
+FUNC
+FUNCOBJ
+funcs
+Funcs
+FUNCS
+FUNCSIG
+function
+Function
+FUNCTION
+functionality
+functions
+Functions
+FuncType
+funcZ
+fundamental
+fundamentals
+FUnit
+FUnits
+fuq
+fur
+further
+Furthermore
+Futa
+future
+fuv
+Fuzhou
+fuzz
+fvar
+FVAR
+FVSes
+FWIDTH
+FWORD
+fy
+FYROM
+g
+G
+ga
+Ga
+gaa
+Gade
+Gaelic
+GAF
+gag
+Gagauz
+Gah
+Gahri
+Galice
+Galician
+Galla
+Gallurese
+gan
+Gan
+Ganda
+Ganja
+gap
+GAP
+gaps
+garbage
+Garhwali
+Garo
+Garret
+Garshuni
+gasp
+GASP
+GaspRange
+gaspRanges
+gather
+gaw
+gax
+gaz
+GB
+gbm
+GBoxedCopyFunc
+GBoxedFreeFunc
+gbreve
+Gbreve
+gbytes
+GBytes
+gc
+GC
+gcc
+GCC
+gce
+gchar
+gconstpointer
+gd
+gda
+gdef
+GDEF
+gdi
+GDI
+Ge
+Geez
+Gemination
+GEMINATION
+gen
+Gen
+GEN
+general
+General
+GENERAL
+generally
+Generally
+generate
+generated
+GenerateResults
+generates
+Generates
+Generating
+generic
+Generic
+GENERIC
+geok
+Geok
+Geometric
+Georgia
+Georgian
+GEORGIAN
+German
+germandbls
+Germany
+get
+Get
+GET
+GetCharVariantIndex
+getCombiningClass
+GetDC
+getenv
+GETENV
+GetFileSize
+GetFileSizeEx
+GetFontData
+GetGlyphPlacements
+getglyphs
+GetGlyphs
+getIntPropertyMaxValue
+getIntPropertyValue
+GetJustificationOpportunities
+getjustifiedglyphs
+GetJustifiedGlyphs
+GetLastWriteTime
+GetLocaleName
+GetModuleHandle
+getNFCInstance
+getNFDInstance
+GetNumberSubstitution
+getpagesize
+GETPAGESIZE
+GetParagraphReadingDirection
+GetProcAddress
+getRawDecomposition
+gets
+Gets
+getScript
+GetScriptProperties
+getShortName
+getter
+getters
+GetTextAtPosition
+GetTextBeforePosition
+getting
+Getting
+gez
+gfxShapedWord
+ggo
+GHAIN
+Gheg
+GHUNNA
+gid
+GID
+gidDDD
+gids
+gih
+Gikuyu
+gil
+Gilaki
+Gilbertese
+Gilyak
+GIMEL
+ginfo
+git
+Githabul
+github
+GitHub
+give
+Give
+given
+Given
+gives
+giving
+gju
+gkp
+gl
+Glagolitic
+GLAGOLITIC
+gld
+glib
+GLib
+GLIB
+glibc
+GLIBC
+glk
+global
+Global
+GLOBAL
+GlobalSubr
+globalsubrs
+globalSubrs
+globalSubrsInfo
+glue
+glyf
+GLYF
+glyid
+glyID
+glyph
+Glyph
+GLYPH
+glyphAdvances
+GlyphAnchors
+glyphArray
+glyphAssembly
+GlyphAssembly
+GlyphBitmapDataFormat
+glyphClassDef
+GlyphClasses
+glyphConstruction
+glyphCount
+glyphDataFormat
+glyphDataOffsets
+glyphFormat
+GlyphHeader
+glyphid
+glyphId
+glyphID
+GlyphID
+GLYPHID
+glyphIdArray
+glyphIdArrayLength
+GlyphIDs
+glyphIndex
+glyphIndices
+glyphMetrics
+glyphNameIndex
+glyphOffsets
+GLYPHPROP
+glyphProperties
+glyphs
+Glyphs
+GLYPHS
+glyphset
+GlyphVarData
+GM
+gmappedfile
+GMT
+gn
+gname
+gnn
+gno
+gnome
+gnu
+GNU
+GNUC
+gnw
+go
+goal
+GOAL
+goals
+Goan
+gobject
+GObject
+GOBJECT
+GOFFSET
+gog
+Gogo
+going
+gom
+gon
+Gondi
+GONDI
+gone
+good
+google
+Google
+Goronzy
+got
+Got
+Gothic
+GOTHIC
+goto
+gpos
+GPOS
+GPOSProxy
+gr
+grab
+graduated
+grained
+granted
+GRANTED
+Grantha
+GRANTHA
+granular
+granularly
+graph
+grapheme
+Grapheme
+GRAPHEME
+graphemes
+Graphemes
+GRAPHEMES
+graphic
+graphics
+Graphics
+graphicType
+graphite
+Graphite
+GRAPHITE
+grave
+Gravesmall
+greater
+greaterequal
+Greece
+Greek
+GREEK
+green
+Green
+Greenland
+Greenlandic
+greg
+grep
+grface
+Grid
+GRID
+Grigori
+grigorig
+group
+GROUP
+grouped
+Groupings
+grouprecord
+groups
+grow
+growFlags
+growing
+grows
+growth
+grt
+gru
+gsize
+Gsmall
+gsub
+GSUB
+gsubgpos
+GSUBGPOS
+GSUBProxy
+gsw
+gt
+gtk
+GTK
+gtype
+GType
+gu
+Guarani
+Guaraní
+guarantee
+guaranteed
+guarantees
+guards
+Guatemala
+guc
+GUEH
+guess
+guessing
+guf
+gug
+gui
+Guibei
+Guibian
+guillemotleft
+guillemotright
+guilsinglleft
+guilsinglright
+Guinea
+Guiyang
+Gujarati
+GUJARATI
+Gujari
+Guji
+GUJR
+guk
+Gulf
+Gumatj
+Gumuz
+gun
+GUnicodeScript
+GUnicodeType
+Gunjala
+GUNJALA
+Gupapuyngu
+Gurage
+Gurmukhi
+GURMUKHI
+GURU
+Gusii
+guz
+gv
+gvar
+GVAR
+gwi
+Gwich
+GX
+gxFontDescriptor
+gzip
+h
+H
+ha
+haa
+hack
+HACKMEM
+had
+Hadothi
+Hadrami
+hae
+HAFS
+HAH
+Haible
+HAIR
+Haitian
+Haji
+hak
+Hakha
+Hakka
+Halam
+halant
+Halant
+HALANT
+halants
+half
+Half
+HALF
+Halfwidth
+HALFWIDTH
+Halh
+HALN
+Hamer
+Hammer
+HAMZA
+HAMZAH
+Han
+HAN
+hand
+Hand
+handed
+handing
+handle
+Handle
+HANDLE
+handled
+handler
+handles
+handling
+hang
+hanging
+Hanging
+HANGING
+hangul
+Hangul
+HANGUL
+Hanifi
+HANIFI
+HANJA
+hans
+Hans
+hant
+Hant
+Hanunoo
+HANUNOO
+happen
+happened
+happening
+happens
+Happens
+happier
+happy
+har
+Harari
+Harauti
+hard
+harder
+hardest
+harfbuzz
+HarfBuzz
+HarffBuzz
+Haryanvi
+has
+Has
+HAS
+hash
+hashmap
+Hat
+hataf
+HATRAN
+HAU
+Hausa
+have
+Have
+HAVE
+having
+haw
+Hawaiian
+hAxis
+hay
+Haya
+haz
+Hazaragi
+hb
+HB
+HBASELINE
+HBFixed
+HBGlyphID16
+HBINT
+hbot
+hbotABCD
+hbsc
+hbshape
+hbsubset
+HBUCHAR
+HBUINT
+HBUSHORT
+hbview
+hdc
+HDC
+hdmx
+HDMX
+he
+HE
+hea
+head
+Head
+HEAD
+header
+Header
+HEADER
+headerfile
+headers
+Headers
+headerSize
+HeadlessArrayOf
+heap
+heavier
+heavily
+hebrew
+Hebrew
+HEBREW
+HEH
+height
+HEIGHT
+heightCount
+heights
+help
+helper
+Helper
+helpers
+helpful
+helps
+hence
+Hence
+here
+Here
+hereby
+Herero
+HEREUNDER
+Herzegovina
+HET
+heuristic
+Hexagram
+hflex
+hfont
+HFONT
+hh
+HH
+hhcurveto
+hhea
+HHEA
+hi
+hidden
+HIDDEN
+hide
+HIDE
+hiding
+HIEROGLYPHS
+high
+High
+HIGH
+higher
+highest
+Highland
+HIGHLEVEL
+highlight
+highlighting
+highly
+Hijazi
+hil
+Hiligaynon
+himalaya
+Himalaya
+Hindi
+Hindko
+hinstLib
+hint
+hinted
+hinting
+HINTING
+HintingDevice
+hintmask
+hints
+Hiragana
+HIRAGANA
+Hiri
+hiriq
+HIRIQ
+historical
+HISTORICAL
+history
+hit
+hji
+hk
+HK
+hlineto
+hlt
+hma
+hmc
+hmd
+hme
+hmetrics
+hmg
+hmh
+hmi
+hmj
+hml
+hmm
+hmn
+HMODULE
+Hmong
+HMONG
+hmoveto
+hmp
+hmq
+hms
+hmtx
+HMTX
+hmtxvmtx
+hmw
+hmy
+hmz
+HN
+hnd
+hne
+hnj
+hno
+ho
+Ho
+hoc
+hoi
+hoj
+HOJO
+Hokkien
+Hoklo
+holam
+HOLAM
+hold
+holder
+Holder
+HOLDER
+holding
+holds
+Holikachuk
+home
+Homebrew
+Honduras
+Hong
+Hongshuihe
+hood
+hook
+Hook
+hooks
+horiBearingX
+horiBearingY
+horiz
+HORIZ
+horizData
+horizGlyphCount
+horizGlyphCoverage
+horizontal
+Horizontal
+HORIZONTAL
+horizontally
+Horned
+Hosken
+Hosny
+hosted
+house
+House
+how
+however
+However
+HOWEVER
+HP
+hr
+HRESULT
+hrm
+hsb
+Hsmall
+hsn
+hstem
+hstemhm
+ht
+hTemplateFile
+html
+http
+https
+hu
+Huallaga
+Huamalíes
+Huánuco
+Huaylas
+Huaylla
+huge
+Huishui
+Huizhou
+huj
+human
+Humm
+Hungarian
+HUNGARIAN
+hungarumlaut
+Hungarumlautsmall
+Hungary
+hup
+Hupa
+hvar
+HVAR
+HVARTag
+HVARVVAR
+hvcurveto
+HVM
+hy
+hyphen
+HYPHEN
+hyphenation
+hypheninferior
+HYPHENS
+hyphensuperior
+hyw
+hz
+i
+I
+ia
+iacute
+Iacute
+Iacutesmall
+iba
+Iban
+ibb
+Ibibio
+IBMCPP
+ibmxl
+ibo
+ic
+Iceland
+Icelandic
+iCharPos
+iche
+icircumflex
+Icircumflex
+Icircumflexsmall
+icu
+ICU
+id
+ID
+ida
+Idakho
+idDelta
+idea
+ideal
+Ideally
+ideas
+IDEFs
+idempotent
+identical
+identically
+identification
+identified
+identifier
+identifiers
+identifies
+identify
+identifying
+identity
+IDEO
+Ideograms
+Ideographic
+IDEOGRAPHIC
+Ideographs
+IDEOGRAPHS
+idieresis
+Idieresis
+Idieresissmall
+Ido
+Idotaccent
+idRangeOffset
+ids
+IDs
+IDWriteFactory
+IDWriteFontFace
+IDWriteFontFile
+IDWriteFontFileLoader
+IDWriteFontFileStream
+IDWriteNumberSubstitution
+IDWriteTextAnalysisSink
+IDWriteTextAnalysisSource
+IDWriteTextAnalyzer
+idx
+ie
+Ie
+ietf
+IETF
+if
+If
+IF
+IFACEMETHOD
+IFACEMETHODIMP
+ifdef
+ifelse
+iff
+ifndef
+ig
+Igalia
+igb
+Igbo
+ignorable
+Ignorable
+IGNORABLE
+ignorables
+IGNORABLES
+ignore
+Ignore
+IGNORE
+IgnoreBaseGlyphs
+ignored
+Ignored
+IGNORED
+IgnoreFlags
+IgnoreLigatures
+IgnoreMarks
+ignoring
+igrave
+Igrave
+Igravesmall
+IHDR
+ii
+II
+iid
+IID
+ijc
+ijo
+Ijo
+ik
+ike
+ikt
+ill
+illegal
+ILLUMINATED
+illustrates
+ilo
+Ilokano
+Iloko
+image
+imageDataOffset
+imageFormat
+imageOffsetsZ
+images
+imagine
+Imbabura
+IMC
+immediately
+immutable
+IMPERIAL
+impl
+IMPL
+implement
+Implement
+IMPLEMENT
+implementation
+IMPLEMENTATION
+implementations
+Implementations
+implemented
+IMPLEMENTED
+implementing
+Implementing
+implementor
+implements
+Implements
+implicit
+IMPLICIT
+implied
+IMPLIED
+implies
+important
+Important
+impose
+impossible
+improve
+improved
+iMu
+in
+In
+IN
+inaccuracy
+Inari
+inc
+Inc
+inch
+INCIDENTAL
+Incidentally
+include
+Include
+included
+includes
+Includes
+including
+Including
+INCLUDING
+inclusion
+inclusive
+incoming
+incompatible
+incomplete
+inconsistencies
+incorporating
+incorrect
+incorrectly
+incorrectness
+increase
+Increase
+increased
+increases
+Increases
+increasing
+incrementally
+incurs
+IND
+indeed
+indefinitely
+indented
+independent
+Independent
+INDEPENDENT
+independently
+index
+Index
+INDEX
+IndexArray
+indexed
+Indexed
+indexes
+indexFormat
+indexing
+IndexMask
+IndexOf
+IndexSubtable
+IndexSubtableArray
+indexSubtableArrayOffset
+IndexSubtableFormat
+IndexSubtableHeader
+IndexSubtableRecord
+indexSubtablesZ
+indexTablesSize
+indexToLocFormat
+India
+indic
+Indic
+INDIC
+indicate
+indicated
+indicates
+Indicates
+indicating
+indication
+indices
+indicies
+IndicPositionalCategory
+IndicShapingInvalidCluster
+IndicSMatraCategory
+IndicSyllabicCategory
+IndicSyllableCategory
+INDIRECT
+indirection
+individual
+Individual
+individually
+indivisible
+Indonesia
+Indonesian
+inds
+industry
+IndV
+indx
+indy
+ineffective
+inefficient
+INEQUALITY
+inert
+INERT
+inf
+infer
+Infer
+INFERIORS
+inferred
+infinite
+infinitum
+infinity
+info
+INFO
+informaltable
+informatimago
+information
+Information
+infos
+infrequent
+ing
+Ingush
+inh
+INHERENT
+inherit
+Inherit
+INHERITED
+inherits
+inhibit
+init
+Init
+INIT
+initial
+Initial
+INITIAL
+Initialization
+initialize
+InitializeCriticalSection
+InitializeCriticalSectionEx
+initialized
+initializer
+INITIALIZER
+initializers
+initially
+Initially
+initialRandomSeed
+initiated
+initLookup
+initmediSubLookup
+initpos
+initSubLookup
+InitT
+ink
+inline
+inner
+innerIndex
+inout
+INOUT
+inplace
+input
+Input
+INPUT
+inputClassDef
+inputCount
+inputs
+inputX
+inputZ
+Inremental
+ins
+insane
+INSCRIPTIONAL
+insert
+Insert
+INSERT
+inserted
+insertion
+Insertion
+insertionAction
+insertions
+InsertionSubtable
+inserts
+inside
+Inside
+inspect
+inspecting
+inspects
+install
+Install
+installed
+installing
+Installing
+instance
+INSTANCE
+instanceCoords
+instanceCount
+InstanceRecord
+instances
+Instances
+instanceSize
+INSTANTIATE
+instantiated
+instead
+Instead
+instruct
+instruction
+instructionLength
+instructions
+Instructions
+INSTRUCTIONS
+INSUFFICIENT
+int
+Int
+INT
+integer
+Integer
+INTEGER
+integers
+integral
+integrate
+integrating
+integration
+Integration
+intel
+INTEL
+intended
+intentional
+intentionally
+Intentionally
+Inter
+interact
+InterCharacter
+interest
+interested
+interface
+interfaces
+interfering
+interim
+Interix
+interlaceMethod
+Interlingua
+Interlingue
+InterlockedCompareExchangePointer
+InterlockedExchange
+InterlockedExchangeAdd
+intermediate
+intermediateEndTuple
+IntermediateRegion
+intermediateStartTuple
+intermixed
+intern
+internal
+Internal
+INTERNAL
+internally
+Internally
+internals
+International
+INTERNATIONAL
+InternationalSymbols
+interp
+INTERP
+interpolate
+Interpolate
+interpolation
+interpret
+interpretation
+Interpretation
+interpreter
+interpreting
+INTERROBANG
+intersect
+intersections
+intersects
+INTERSECTS
+interviews
+intl
+into
+intOp
+intptr
+intrin
+intro
+introduced
+Introduced
+introducing
+Introduction
+ints
+IntType
+INTTYPE
+inttypes
+intuition
+Inuinnaqtun
+Inuktitut
+Inupiaq
+Inupiat
+Inupiatun
+invalid
+Invalid
+INVALID
+invert
+INVERTED
+inverts
+investigated
+investigation
+invisible
+Invisible
+INVISIBLE
+invocation
+invoke
+invoked
+invol
+involve
+involved
+involves
+io
+iOS
+iota
+IOTA
+ip
+IPA
+IPHONE
+Iran
+Iranian
+IranNastaliq
+Iraq
+Ireland
+Irish
+irrelevant
+is
+Is
+IS
+Isaac
+ISALNUM
+ISALPHA
+ISC
+isCombinedS
+isCombiningL
+isCombiningT
+isCombiningV
+isEmojiFont
+isFixedPitch
+ish
+isHangulTone
+isiXhosa
+isiZulu
+isL
+Islamic
+Islands
+Ismall
+isn
+iso
+ISO
+ISOAdobeCharset
+ISOL
+ISOLATE
+isolated
+ISOLATED
+Israel
+isRightToLeft
+ISSPACE
+issue
+issuecomment
+issues
+issuetracker
+isSupported
+isT
+Isukha
+isuperior
+isV
+it
+It
+ital
+Italian
+italic
+Italic
+ITALIC
+italicAngle
+ItalicAngle
+italics
+Italics
+italicsCorrection
+Italy
+item
+Item
+ITEM
+itemCount
+itemizedlist
+itemizer
+items
+Items
+ITEMS
+ItemSize
+iter
+Iter
+ITER
+iterable
+Iterable
+iterables
+iterate
+Iterate
+iterated
+iteration
+iterations
+iterator
+Iterator
+IteratorIn
+IteratorOut
+iterators
+iters
+its
+Its
+ITS
+itself
+iu
+IUnknown
+ivs
+iw
+Izon
+izzi
+j
+J
+ja
+jak
+Jakun
+jam
+Jamaica
+Jamaican
+Jambi
+jamo
+Jamo
+January
+Japan
+Japanese
+Jauja
+Javanese
+JAVANESE
+jax
+jbo
+jct
+JEEM
+JEH
+jg
+ji
+Jicarilla
+Jing
+Jinyu
+JIS
+JMO
+job
+join
+joiner
+Joiner
+JOINER
+joiners
+JOINERS
+joining
+Joining
+JOINING
+Jonathan
+Jordan
+jpg
+Jsmall
+json
+JSON
+jstf
+JSTF
+JstfLangSys
+JstfLangSysRecords
+JstfMax
+JstfModList
+JstfPriority
+JstfScript
+JstfScripts
+jt
+Jula
+JUNGSEONG
+Junín
+junk
+just
+Just
+JUST
+justClass
+JustClass
+justClassTable
+justification
+Justification
+JUSTIFICATION
+JustificationCategory
+justificationCharacter
+JustificationHeader
+justificationOpportunities
+justified
+justifiedGlyphAdvances
+justifiedGlyphOffsets
+justify
+JustifyGlyphAdvances
+JustWidthDeltaEntry
+jv
+jw
+jy
+k
+K
+ka
+kaa
+kab
+Kabardian
+Kabras
+Kabuverdianu
+Kabyle
+Kachchi
+Kachhi
+KAF
+Kaithi
+KAITHI
+Kalenjin
+Kalmyk
+Kalo
+Kalpak
+kam
+Kamba
+Kambaata
+kana
+KANA
+Kanaq
+Kanauji
+Kanbun
+Kangri
+Kangxi
+Kanji
+Kannada
+KANNADA
+Kanuri
+Kaqchikel
+kar
+Kara
+Karachay
+Karaim
+Karakalpak
+Karelian
+Karen
+kashida
+Kashida
+KashidaLike
+Kashmiri
+Kashubian
+Kaska
+kasra
+kasratan
+Katakana
+KATAKANA
+Katanga
+Kato
+kau
+Kaur
+Kayah
+KAYAH
+Kazakh
+Kazakhstan
+Kazim
+kb
+kbd
+kby
+kByte
+kca
+kCFAllocatorDefault
+kCFAllocatorNull
+kCFBooleanTrue
+kCFCompareEqualTo
+kCFNumberIntType
+kCFStringEncodingUTF
+kCFTypeArrayCallBacks
+kCFTypeDictionaryKeyCallBacks
+kCFTypeDictionaryValueCallBacks
+kCTFontAttributeName
+kCTFontCascadeListAttribute
+kCTFontEmphasizedSystemFontType
+kCTFontFeatureSelectorIdentifierKey
+kCTFontFeatureSettingsAttribute
+kCTFontFeatureTypeIdentifierKey
+kCTFontPostScriptNameKey
+kCTFontSystemFontType
+kCTFontUIFontEmphasizedSystem
+kCTFontUIFontSystem
+kCTFontURLAttribute
+kCTKernAttributeName
+kCTLanguageAttributeName
+kCTRunStatusNonMonotonic
+kCTRunStatusRightToLeft
+kCTTypesetterOptionForcedEmbeddingLevel
+kCTVersionNumber
+kCTVerticalFormsAttributeName
+kde
+kdr
+kdt
+kea
+Kebena
+Kedah
+keep
+Keep
+keeping
+KEHEH
+Keith
+Keiyo
+kek
+Kekchi
+Kentohe
+Kenya
+kept
+Kerinci
+kern
+KERN
+KernAAT
+KernAATSubTableHeader
+kernAction
+kernActionIndex
+KERNEL
+kernIndex
+kerning
+Kerning
+KERNING
+kerningv
+KernOT
+KernOTSubTableHeader
+KernPair
+kerns
+KernSubTable
+KernSubTableFormat
+KernSubTableHeader
+kernValue
+kernValueCount
+kernValueZ
+kerx
+KERX
+KerxSubTable
+KerxSubTableFormat
+KerxSubTableHeader
+KerxTable
+kerxTupleKern
+Kew
+kex
+key
+Key
+KEY
+keys
+kfa
+KFGQPC
+kfr
+kfx
+kfy
+kg
+kha
+KHAH
+Khakas
+Khakass
+Khaled
+Khamti
+Khanty
+Kharoshthi
+KHAROSHTHI
+Khasi
+Khayo
+khb
+Khengkha
+Khimi
+khk
+khmer
+Khmer
+KHMER
+KhmerUI
+Khojki
+KHOJKI
+Khorasani
+Khowar
+kht
+Khudawadi
+KHUDAWADI
+Khumi
+Khutsuri
+khw
+ki
+kick
+KIKAKUI
+Kikongo
+Kikuyu
+Kildin
+Killer
+KILLER
+Kimbundu
+kind
+kinda
+kinds
+Kingdom
+kinoho
+kINVALID
+Kinyarwanda
+Kiowa
+Kipsigis
+Kirghiz
+KIRGHIZ
+Kiribati
+Kirmanjki
+Kisa
+Kisi
+Kisii
+Kissi
+Kistane
+Kiswahili
+Kita
+Kituba
+kiu
+Kiwai
+kj
+kjd
+kjh
+kjp
+kjz
+kk
+kkz
+kl
+klass
+klasses
+kln
+km
+kMaxCallLimit
+kmb
+kmr
+kmw
+kmz
+kn
+knc
+KNDA
+kng
+knn
+know
+knowing
+Knowing
+knowledge
+known
+Known
+knows
+Knuth
+ko
+Ko
+Kodagu
+Kodava
+koi
+kok
+Kokni
+Kölsch
+Komi
+Komo
+Komso
+Kong
+Kongo
+Konkani
+Konso
+Konyanka
+Koongo
+Koorete
+Korea
+Korean
+Koryak
+kos
+Kosraean
+Kota
+koy
+Koyukon
+kpe
+Kpelle
+kpv
+kpy
+kqs
+kqy
+kr
+krc
+kri
+Krio
+krl
+krt
+kru
+Krymchak
+ks
+ksh
+kShort
+kSizeLimit
+Ksmall
+kss
+ksw
+ktb
+ktu
+ktw
+ku
+Kuanyama
+Kubu
+Kui
+Kukna
+Kullu
+Kulvi
+kum
+Kumaoni
+Kumyk
+Kumzari
+Kuna
+Kurdish
+Kurukh
+Kuskokwim
+Kutai
+kuu
+Kuwait
+Kuy
+kv
+kvb
+kvr
+kw
+KW
+kwy
+kxc
+kxd
+kxu
+ky
+Kyrgyz
+Kyrgyzstan
+kyu
+kZero
+l
+L
+la
+La
+Laari
+label
+LABEL
+labels
+lack
+lad
+Ladakhi
+Ladin
+Ladino
+Lahuli
+laid
+Lak
+Laki
+Lalana
+Lam
+LAM
+lamAlefLigaturesSubLookup
+Lambadi
+Lambani
+Lambayeque
+LAMED
+lamInitLigature
+lamLigatureSet
+Lampung
+lang
+langs
+langsys
+langSys
+LangSys
+LANGSYS
+LangSysRecords
+LangSysTag
+LangTag
+language
+Language
+LANGUAGE
+LanguageGroup
+languageID
+languages
+Languages
+LANGUAGES
+languagetags
+Lanka
+Lao
+LAO
+large
+Large
+LARGE
+larger
+largest
+Largest
+LArrayOf
+lash
+last
+Last
+LAST
+lastCode
+lastGlyphIndex
+LastResort
+lastWriteTime
+LATE
+later
+latest
+latg
+Latg
+Latgalian
+latin
+Latin
+LATIN
+latn
+latter
+Latvia
+Latvian
+Lauricocha
+Lawoi
+lay
+layer
+Layer
+layering
+LayerRecord
+layers
+layersZ
+layout
+Layout
+LAYOUT
+LayoutRTL
+lays
+Laz
+lazily
+lazy
+Lazy
+lb
+LBAR
+LBase
+LBASE
+lbe
+lbj
+lbl
+LC
+lcar
+LCAR
+lcarFormat
+lce
+lcf
+LCount
+LCOUNT
+ld
+ldi
+Le
+LE
+lead
+LEADER
+leading
+Leading
+LEADING
+leadingBearingX
+Lealao
+LEAN
+leans
+least
+leave
+Leave
+LeaveCriticalSection
+leaving
+Lebanon
+Leboa
+left
+Left
+LEFT
+leftC
+leftClass
+leftClassCount
+leftClassTable
+leftSide
+legacy
+Legacy
+LEGACY
+legally
+legit
+Lemberg
+len
+LEN
+LENG
+length
+Length
+LENGTH
+lengthed
+lengths
+lengthy
+lenient
+lenM
+lenP
+LENTICULAR
+LenType
+Leone
+Lepcha
+LEPCHA
+less
+lessequal
+let
+Let
+lets
+Lets
+letter
+Letter
+LETTER
+Letterlike
+letters
+Letters
+Levantine
+level
+Level
+LEVEL
+levels
+leverage
+lexicographic
+lez
+Lezghian
+Lezgi
+lf
+LF
+lfCharSet
+lfFaceName
+lfHeight
+lg
+lhs
+Lhs
+li
+Li
+LI
+LIABLE
+Lianshan
+libc
+libcairo
+Liberia
+libfreetype
+libglib
+libharfbuzz
+libkern
+Libon
+libraries
+Libraries
+library
+Library
+LibreOffice
+libs
+libstdc
+libtool
+Libya
+Libyan
+license
+LICENSE
+lidentity
+Liechtenstein
+lif
+life
+lifecycle
+lifecycles
+lig
+LIG
+liga
+ligAction
+LigActionFlags
+ligActionIndex
+LigActionLast
+LigActionOffset
+LigActionStore
+ligActionTable
+ligate
+ligated
+LIGATED
+ligating
+ligation
+ligature
+Ligature
+LIGATURE
+ligatureArray
+LigatureArray
+LigatureAttach
+ligatureCoverage
+LigatureCoverage
+ligatureData
+LigatureEntry
+LigatureEntryT
+LigatureGlyph
+ligatures
+Ligatures
+LIGATURES
+ligatureSet
+LigatureSet
+LigatureSetOffsets
+LigatureSetOffsetsArray
+LigatureSubst
+LigatureSubstFormat
+LigatureSubtable
+ligbase
+LIGBASE
+LigCaretClassEntry
+ligCaretList
+LigCaretList
+ligGlyph
+LigGlyph
+light
+Light
+LIGHT
+lighter
+lightweight
+ligs
+Ligurian
+lij
+like
+Like
+likely
+Likewise
+Lima
+Limbu
+LIMBU
+Limburgish
+limit
+Limit
+LIMIT
+limitation
+limited
+Limited
+LIMITED
+limiting
+limits
+lindex
+line
+LINE
+linear
+Linear
+LINEAR
+linearly
+Linebreak
+lineBreakpoints
+lineGap
+lines
+lineWidth
+Lingala
+lingo
+linguistic
+LINGUISTIC
+linguistically
+linguistics
+link
+linked
+linkedValue
+linking
+links
+linux
+Linux
+Lipan
+lis
+list
+List
+LIST
+listed
+listinfo
+listitem
+lists
+Lisu
+LISU
+literal
+Literary
+Lithuania
+Lithuanian
+little
+LITTLE
+Liujiang
+Liuqian
+liw
+ljmo
+LJMO
+ljp
+lkb
+lki
+lklug
+lko
+lks
+ll
+Ll
+lld
+LLLEEEEEEEGGGG
+LLONG
+LLVM
+lm
+Lm
+lmn
+lmo
+ln
+LNNOffsetTo
+lo
+Lo
+load
+Load
+LOAD
+loaded
+loader
+loaders
+loading
+LoadLibrary
+loc
+loca
+local
+locale
+Locale
+LOCALE
+localeName
+localized
+localsubr
+LocalSubr
+localsubrs
+localSubrs
+localSubrsInfos
+Locate
+located
+location
+Location
+locations
+lock
+lockable
+Lockable
+locl
+locName
+LOffsetArrayOf
+LOffsetLArrayOf
+LOffsetTo
+log
+LOG
+LOGFONT
+logfontw
+LOGFONTW
+logic
+logical
+Logical
+logicalnot
+LogicalOrder
+Logo
+logograms
+Logooli
+LOGOS
+Logudorese
+Lohar
+lohit
+Lohit
+Loja
+lojban
+Lojban
+lom
+Loma
+Lombard
+Lomwe
+Loncong
+lone
+Lonely
+long
+Long
+LONG
+LONGDATETIME
+longer
+longint
+longintdict
+LongMetric
+longMetricZ
+longword
+look
+Look
+lookahead
+lookaheadClassDef
+lookaheadCount
+lookaheadX
+looked
+looking
+Looking
+looks
+Looks
+lookup
+Lookup
+LOOKUP
+lookupCount
+lookupFlag
+LookupFlag
+LookupFlags
+LookupFormat
+lookupIndex
+lookupList
+LookupList
+lookupListIndex
+lookupOffset
+lookupOrderZ
+lookupRecord
+LookupRecord
+LookupRecords
+lookupRecordX
+lookups
+Lookups
+LOOKUPS
+LookupSegmentArray
+LookupSegmentSingle
+LookupSingle
+lookupTable
+lookupType
+LookupType
+lookupX
+loop
+Loop
+loops
+loose
+loosely
+Lortie
+lose
+LOSS
+lossless
+lost
+lot
+Lots
+low
+Low
+LOW
+lower
+Lower
+LOWER
+lowercase
+LOWERCASE
+lowercased
+lowerLimit
+lowest
+lowestRecPPEM
+Lowland
+LowPart
+lozenge
+lParameter
+lps
+lpSecurityAttributes
+LR
+lrc
+lri
+lrm
+lsb
+lsbMap
+lsearch
+lslash
+Lslash
+Lslashsmall
+lsm
+Lsmall
+lsuperior
+lt
+Lt
+ltag
+LTAG
+ltg
+lto
+ltr
+LTR
+lts
+lu
+Lu
+Lü
+lua
+Luba
+Lubu
+Lucian
+Lue
+LUE
+Lule
+Lulua
+luo
+Luo
+Luopohe
+Luri
+lus
+Lushai
+lux
+Luxembourg
+Luxembourgish
+luy
+Luyia
+luz
+lv
+LV
+lvalue
+lvalues
+lvs
+LVT
+lwg
+lwsync
+lx
+Lycian
+LYCIAN
+Lydian
+LYDIAN
+lzh
+lzz
+m
+M
+ma
+Maasina
+MAbv
+mac
+Mac
+MAC
+Macao
+Macedonia
+Macedonian
+machine
+MACHINE
+machinery
+MACHINERY
+machines
+Macintosh
+macos
+macOS
+MacPorts
+macro
+macrolanguage
+macroman
+MACROMAN
+macron
+Macronsmall
+macros
+Macros
+macStyle
+mad
+MADDA
+MADDAH
+made
+Madura
+Madurese
+mag
+Magahi
+magic
+magicNumber
+Mahafaly
+Mahajani
+MAHAJANI
+Mahjong
+mai
+MAI
+mailing
+mailman
+main
+Main
+MAIN
+mainly
+maintain
+maintained
+MAINTENANCE
+MAITAIKHU
+Maithili
+Majang
+major
+Major
+MAJOR
+mak
+Makasar
+MAKASAR
+make
+Make
+MAKE
+makeotf
+makeOTF
+MakeOTF
+makes
+Makes
+Makhuwa
+making
+Making
+Makonde
+MAKSURA
+Malagasy
+Malay
+Malayalam
+MALAYALAM
+Malaysia
+Maldives
+Maldivian
+Male
+Malinke
+malloc
+Malta
+Maltese
+Malvi
+mam
+Mam
+man
+Manado
+manage
+managed
+management
+manages
+Manchu
+Mandaic
+MANDAIC
+Mandar
+Mandarin
+Mandingo
+Mandinka
+Manga
+Manichaean
+MANICHAEAN
+manifest
+Manifest
+MANIFEST
+manifestData
+ManifestLookup
+Maninka
+Maninkakan
+Manipuri
+manner
+manpage
+Mansi
+manual
+Manual
+MANUAL
+manufacturer
+MANUFACTURER
+Manx
+many
+Many
+Maore
+Maori
+map
+Map
+MAP
+mapCount
+mapDataZ
+mapLen
+mapped
+mapper
+mapping
+Mapping
+mappings
+maps
+Maps
+Mapudungun
+MapViewOfFile
+MapViewOfFileFromApp
+Mara
+Marachi
+Marama
+Marathi
+MARBUTA
+March
+Marchen
+MARCHEN
+margins
+Margos
+Mari
+mark
+Mark
+MARK
+markAnchor
+markAnchorPoint
+markArray
+MarkArray
+markAttachClassDef
+MarkAttachmentType
+markBase
+MarkBase
+MarkBasePos
+MarkBasePosFormat
+MarkCategory
+markControlPoint
+markCoverage
+MarkCoverage
+marked
+markedInsertBefore
+MarkedInsertBefore
+markedInsertCount
+MarkedInsertCount
+markedInsertIndex
+markedInsertList
+MarkedIsKashidaLike
+markers
+markFilteringSet
+markFilteringSetX
+MarkFirst
+MarkGlyph
+MarkGlyphSets
+markGlyphSetsDef
+MarkGlyphSetsFormat
+markIndex
+marking
+MarkLast
+markLig
+MarkLig
+MarkLigPos
+MarkLigPosFormat
+markMark
+MarkMark
+MarkMarkPos
+MarkMarkPosFormat
+MarkRecord
+MarkRecords
+marks
+Marks
+MARKS
+Markweeta
+markX
+markY
+Marma
+Marshallese
+Martin
+Martín
+Marwari
+Masaram
+MASARAM
+Mashan
+Masikoro
+mask
+Mask
+MASK
+masks
+Masks
+master
+Master
+MASTERS
+match
+Match
+MATCH
+matched
+matcher
+matches
+matching
+material
+math
+Math
+MATH
+mathConstants
+MathConstants
+mathematical
+Mathematical
+MATHEMATICAL
+mathematics
+MathGlyphAssembly
+MathGlyphConstruction
+mathGlyphInfo
+MathGlyphInfo
+MathGlyphPartRecord
+mathGlyphVariantRecord
+MathGlyphVariantRecord
+MathGlyphVariantRecords
+mathItalicsCorrectionInfo
+MathItalicsCorrectionInfo
+mathKern
+MathKern
+mathKernCoverage
+mathKernInfo
+MathKernInfo
+MathKernInfoRecord
+mathKernInfoRecords
+MathKernInfoRecords
+MathSymbols
+mathTopAccentAttachment
+MathTopAccentAttachment
+MathValueRecord
+mathValueRecords
+MathValueRecords
+mathValueRecordsZ
+mathVariants
+MathVariants
+matra
+Matra
+MATRA
+matras
+Matras
+matrix
+Matrix
+matrixZ
+matter
+Matthias
+Mattole
+Matu
+max
+Max
+MAX
+maxBeforeBL
+maxComponentDepth
+maxComponentElements
+maxCompositeContours
+maxCompositePoints
+maxContours
+maxCoord
+MaxDebugDepth
+maxExtent
+maxFunctionDefs
+maxGlyphCount
+maximum
+Maximum
+maximumLimit
+maximums
+maxInstructionDefs
+maxMemType
+maxp
+MAXP
+maxPoints
+maxpV
+maxSizeOfInstructions
+maxStackElements
+maxStorage
+maxTwilightPoints
+maxVal
+maxValue
+maxWidth
+maxZones
+may
+May
+MAY
+Mayan
+maybe
+Maybe
+MAYBE
+Mayek
+MAYEK
+Mayo
+Mazanderani
+mb
+MB
+mbarrier
+Mbembe
+mBidiLevel
+MBlw
+mbo
+Mbo
+mbstowcs
+Mbundu
+Mbyá
+Mc
+mcm
+mct
+mCurrentRun
+md
+MD
+mdash
+mData
+mdf
+mdr
+mdy
+me
+Me
+mean
+MEAN
+meaning
+meaningfully
+meanings
+means
+Meanwhile
+measurable
+measure
+MEASURE
+measured
+measuring
+mechanical
+mechanism
+MED
+MEDEFAIDRIN
+medi
+MEDI
+medial
+Medial
+MEDIAL
+median
+medifinaLamAlefSubLookup
+mediLookup
+mediSubLookup
+Medium
+MEDIUM
+Medumba
+MEEM
+Meetei
+MEETEI
+Meh
+MEM
+memaccess
+member
+members
+Members
+memcmp
+memcpy
+memmove
+memoize
+memory
+Memory
+MEMORY
+MemoryBarrier
+memset
+men
+Mende
+MENDE
+Mengisa
+mentioned
+mentions
+menu
+meo
+mer
+MERCHANTABILITY
+merge
+Merge
+merged
+merger
+merges
+merging
+Merging
+MEROITIC
+Meru
+Merwari
+Mescalero
+Mesopotamian
+message
+MESSAGE
+messaging
+messed
+meta
+Meta
+META
+metadata
+Metadata
+metamorphosis
+Metamorphosis
+meteg
+method
+methods
+Methods
+metric
+METRIC
+metricDataFormat
+metrics
+Metrics
+METRICS
+Mewari
+Mewati
+Mexico
+mfa
+mfb
+mfe
+mFontFileStream
+mg
+mGlyphCount
+mGlyphStart
+mh
+MH
+mhr
+mhv
+mi
+Miao
+MIAO
+Michiharu
+micro
+MICRO
+microsoft
+Microsoft
+microsqoft
+MicroType
+mid
+middle
+Middle
+midnight
+might
+Might
+min
+Min
+MIN
+minAdvanceSB
+minAfterBL
+Minangkabau
+minConnectorOverlap
+minCoord
+mind
+mingw
+MinGW
+MINGW
+minHeight
+MINI
+minimal
+minimum
+Minimum
+minimumLimit
+minimums
+Minjangbal
+Minjungbal
+minLeadingBearing
+minlen
+minMax
+MinMax
+minMaxCoord
+minMemType
+Minnan
+minor
+MINOR
+minOriginSB
+minorVersion
+minstd
+minTrailingBearing
+minus
+MINUS
+minVal
+minValue
+minVersion
+Minz
+Mirandese
+Miraya
+mirror
+mirroring
+Mirroring
+misc
+Misc
+Miscellaneous
+MISMATCH
+mIsSideways
+missing
+MIT
+mix
+mixed
+mixin
+Mixin
+Mixing
+mixture
+Mizo
+mk
+mkmk
+mku
+mkw
+ml
+ML
+mLocaleName
+mlq
+MLYM
+mm
+MM
+mman
+MMAN
+mmap
+Mmap
+MMAP
+mmr
+mn
+Mn
+mnc
+mnemonics
+mni
+mnk
+mnp
+mns
+mnw
+mo
+mod
+MOD
+mode
+Mode
+MODE
+model
+models
+Modern
+modes
+Modi
+MODI
+modification
+Modification
+modifications
+MODIFICATIONS
+modified
+Modified
+MODIFIED
+modifiedClusterMap
+modifiedGlyphAdvances
+modifiedGlyphIndices
+modifiedGlyphOffsets
+modifier
+Modifier
+MODIFIER
+modifiers
+modify
+Modify
+modifying
+Modifying
+MODIFYING
+modulo
+moh
+Mohawk
+Moksha
+Moldavian
+Moldova
+Moldovan
+Moluccan
+Mon
+Monaco
+Mongolia
+mongolian
+Mongolian
+MONGOLIAN
+Mono
+monospaced
+MONOSPACED
+monotone
+MONOTONE
+monotonic
+monotonically
+monster
+Months
+Moose
+more
+More
+MORE
+MoreToolbox
+Morisyen
+Moroccan
+Morocco
+morphHeader
+mort
+MORT
+mortmorx
+morx
+MORX
+mos
+Mossi
+most
+Most
+mostly
+Motorola
+Motu
+move
+Move
+moved
+moves
+moveto
+moving
+Moving
+mozilla
+Mozilla
+mpe
+MPre
+mprotect
+MPROTECT
+MPst
+mqg
+mr
+MR
+mReadingDirection
+mrh
+mrj
+Mro
+MRO
+mRunHead
+ms
+MS
+msc
+MSC
+mScript
+msdn
+msg
+MSG
+msgidx
+msgstr
+msh
+msi
+mSize
+Msmall
+msuperior
+MSVC
+mt
+MT
+mText
+mTextLength
+mTextStart
+mtr
+mtx
+mu
+much
+mui
+MUJ
+mul
+MulFix
+Muller
+mult
+Multani
+MULTANI
+multi
+multiple
+Multiple
+MULTIPLE
+MultipleSubst
+MultipleSubstFormat
+multiplication
+multiplicative
+multiplied
+MULTIPLIED
+multiply
+MULTIPLY
+multiplying
+mults
+Mundari
+munmap
+mup
+muq
+mus
+Muscogee
+Musi
+Musical
+MUSICAL
+must
+Must
+MUST
+mutable
+mutex
+MUTEX
+mutually
+mvar
+MVAR
+mvb
+mve
+mvf
+MW
+Mwali
+mwk
+mwl
+mwr
+mww
+my
+MY
+myanmar
+Myanmar
+MYANMAR
+mym
+mymr
+myn
+myq
+myv
+mzn
+n
+N
+na
+NABATAEAN
+Nacional
+nag
+Naga
+Nagari
+Nagri
+NAGRI
+nags
+nah
+Nahuatl
+naive
+Najdi
+nalf
+nalfType
+name
+Name
+NAME
+named
+Named
+nameid
+nameID
+NameID
+nameids
+nameIndex
+NameIndex
+nameIndexOffset
+nameList
+namely
+Namely
+nameOffset
+NameRecord
+nameRecordZ
+names
+Names
+NAMES
+nameSIDs
+namespace
+Namespace
+NAMESPACE
+namesX
+namesZ
+nameTag
+Naming
+nan
+Nan
+Nanai
+Nandi
+Nandinagari
+NANDINAGARI
+nap
+Napo
+NARROW
+narrowing
+nasalization
+Naskapi
+native
+NativeFontResourceDWrite
+natural
+Nauru
+Nauruan
+navajo
+Navajo
+nb
+NC
+nClasses
+nCodes
+NCount
+NCOUNT
+nd
+Nd
+ndash
+Ndau
+ndc
+Ndebele
+NDEBUG
+Ndonga
+nds
+Ndzwani
+ne
+Neapolitan
+necessarily
+necessary
+need
+Need
+needed
+needing
+needs
+Needs
+neg
+NEG
+negation
+negative
+Negative
+NEGATIVE
+Negeri
+NEGLIGENCE
+negotiate
+neighboring
+neither
+nel
+Nenets
+Neo
+Nepal
+Nepali
+nesting
+NESTING
+net
+NetBSD
+Netherlands
+neuter
+neutrals
+never
+Never
+nevertheless
+new
+New
+NEW
+Newa
+NEWA
+Newari
+newBits
+newCount
+newer
+newlocale
+NEWLOCALE
+newly
+newRun
+newState
+next
+Next
+NEXT
+nextRun
+NFC
+NFD
+ng
+NG
+nga
+Ngawn
+Ngazidja
+Ngbaka
+ngl
+ngo
+NGOEH
+Ngoni
+nhd
+nibble
+Nibble
+nibbles
+Nicaragua
+nice
+Niger
+Nigeria
+Nigerian
+nikhahit
+Nikhahit
+NIKHAHIT
+nil
+NIL
+Nimadi
+nindex
+nine
+NINE
+nineinferior
+nineoldstyle
+ninesuperior
+NINETEEN
+niq
+Nirmala
+Nisi
+niu
+Niuean
+niv
+NJ
+Njua
+njz
+NKD
+nko
+NKo
+NKO
+Nkoo
+nl
+Nl
+NLCCHARACTERS
+nle
+nLeft
+nmemb
+nn
+NNOffsetTo
+no
+No
+NO
+nod
+node
+nodes
+noe
+noErr
+nog
+Nogai
+nominal
+NOMINAL
+nominalValue
+nominalWidthX
+non
+Non
+NON
+Nonaka
+NonAlphabetic
+nonbreakingspace
+noncontextual
+Noncontextual
+NoncontextualSubtable
+nonDefault
+nonDefaultUVS
+NonDefaultUVS
+none
+NONE
+nonexistent
+Nong
+nonliteral
+nonmarkingreturn
+nonmonotonic
+nonnull
+nonspacing
+NonStop
+nonzero
+NOON
+NOP
+noporpoise
+nor
+Nor
+NORESERVE
+Norfolk
+normal
+NORMAL
+normalization
+Normalization
+NORMALIZATION
+normalize
+NORMALIZE
+normalized
+normalizer
+normally
+Normally
+North
+NORTH
+Northeastern
+Northern
+Northwest
+Northwestern
+Norway
+Norwegian
+noStretchValue
+not
+Not
+NOT
+notable
+notably
+Notably
+Notation
+notdef
+NOTDEF
+NotDefault
+note
+Note
+NOTE
+noted
+notequal
+notes
+NOTES
+nothing
+Nothing
+notice
+Notice
+noticeably
+notification
+notified
+notifiers
+NOTIMPL
+noting
+notionally
+Noto
+NotoSerif
+nounihan
+nov
+novalidate
+NOVAR
+Novial
+now
+Now
+np
+npi
+nqo
+nr
+nRanges
+nSettings
+nSizes
+nsk
+NSLanguage
+Nsmall
+nso
+nSubrs
+nsuperior
+nSups
+ntilde
+Ntilde
+Ntildesmall
+nTracks
+Nüa
+Nuke
+NUKT
+nukta
+Nukta
+NUKTA
+nul
+NUL
+null
+Null
+NULL
+nullable
+NullHelper
+NullPool
+NullPriority
+nullptr
+num
+Num
+NUM
+numBaseGlyphs
+number
+Number
+NUMBER
+numberOfContours
+numberOfFaces
+numberOfIndexSubtables
+numberOfLongMetrics
+numbers
+Numbers
+NUMBERS
+numbersign
+numberSubstitution
+numBlends
+numColorRecords
+numColors
+numeral
+NUMERAL
+numerals
+Numerals
+numeration
+NUMERATOR
+numeric
+numerical
+Numerical
+numGlyphs
+numLayers
+numNamedParameters
+numOfHMetrics
+numPalettes
+numParameters
+numr
+numRecords
+numScriptCode
+numTables
+numValues
+NUN
+nUnits
+NUSHU
+Nuskhuri
+nv
+ny
+Nyala
+Nyamwezi
+Nyanja
+Nyankole
+nyd
+NYEH
+NYIAKENG
+Nyishi
+nym
+nyn
+Nynorsk
+Nyore
+nza
+o
+O
+oacute
+Oacute
+Oacutesmall
+oasis
+OASIS
+obj
+OBJ
+object
+Object
+OBJECT
+objects
+Objects
+objidx
+OBLIGATION
+oblique
+Oblique
+OBLIQUE
+obliqueing
+obscure
+Obsolete
+obsoleted
+ObsoleteTypes
+obtained
+obvious
+oc
+occasionally
+Occitan
+occupancy
+occupy
+occurrence
+occurrences
+occurring
+occurs
+ocircumflex
+Ocircumflex
+Ocircumflexsmall
+odd
+oddly
+Odia
+odieresis
+Odieresis
+Odieresissmall
+oe
+OE
+OEM
+OEsmall
+of
+Of
+OF
+off
+Off
+OFF
+offer
+offers
+offload
+offs
+OFFS
+offset
+Offset
+OFFSET
+OffsetArrayOf
+offsetArrayZ
+OffsetListOf
+offsetof
+offsets
+Offsets
+OffsetTable
+OffsetTables
+OffsetTo
+offsetToAxisValueOffsets
+offsetToIndex
+offsetToSubtable
+OffsetType
+offsetZ
+offSize
+ofs
+Ofs
+often
+Often
+og
+Ogham
+OGHAM
+ogonek
+Ogoneksmall
+ograve
+Ograve
+Ogravesmall
+Oh
+Oirat
+oj
+ojb
+ojc
+ojg
+Oji
+Ojibwa
+Ojibway
+Ojitlán
+ojs
+ojw
+ok
+Ok
+OK
+oki
+Okiek
+okm
+Ol
+OL
+old
+Old
+OLD
+older
+Older
+OLDER
+om
+Oman
+Omani
+Omega
+omitted
+on
+On
+ON
+once
+Once
+one
+One
+ONE
+OneByteIntFirst
+OneByteIntLast
+onedotenleader
+oneeighth
+onefitted
+onehalf
+oneinferior
+oneoldstyle
+onequarter
+ones
+onesuperior
+onethird
+only
+Only
+ONLY
+onto
+OOP
+op
+Op
+OP
+opaque
+Opaque
+opbd
+OPBD
+opbdFormat
+opcode
+OpCode
+opcodes
+opeator
+open
+Open
+OPEN
+OpenBSD
+opentype
+OpenType
+OPENTYPE
+OpenTypeFontFace
+OpenTypeFontFile
+OpenTypeTable
+operand
+operands
+operate
+operates
+operating
+operation
+operations
+Operations
+operator
+Operator
+OPERATOR
+operators
+Operators
+opportunities
+OPPORTUNITY
+opposite
+ops
+OPS
+opset
+OPSET
+opStart
+opstr
+OPSTR
+opsz
+opszr
+optical
+Optical
+OPTICAL
+OpticalBounds
+OpticalSize
+optimal
+optimally
+optimization
+optimizations
+optimize
+Optimize
+OPTIMIZE
+optimized
+opting
+option
+OPTION
+optional
+Optional
+OPTIONAL
+optionally
+options
+OPTIONS
+opts
+or
+Or
+OR
+oracle
+Orang
+orc
+order
+Order
+ORDER
+ordered
+orderedlist
+ordering
+ordfeminine
+ordinal
+ORDINALS
+ordmasculine
+org
+Organization
+oriented
+orig
+origin
+Origin
+original
+originally
+Originally
+originated
+origins
+origRun
+Oriya
+ORIYA
+Orma
+orn
+ORNAMENT
+ORNAMENTS
+Oromo
+ors
+orthogonal
+orthographic
+Orthographic
+orthographically
+ory
+ORYA
+os
+OS
+OSAGE
+OSAtomic
+OSAtomicAdd
+OSAtomicCompareAndSwap
+OSAtomicCompareAndSwapPtrBarrier
+oslash
+Oslash
+Oslashsmall
+Osmall
+Osmanya
+OSMANYA
+OSMemoryBarrier
+Ossetian
+OSStatus
+osuperior
+ot
+OT
+otf
+otFeatureTag
+OTFontFileVal
+OTHeader
+other
+Other
+OTHER
+OtherBlues
+others
+otherwise
+Otherwise
+OTHERWISE
+otilde
+Otilde
+Otildesmall
+otspec
+Ottawa
+OTTO
+otw
+Ouch
+OUCH
+ought
+our
+Our
+ourself
+ourselves
+out
+Out
+OUT
+outbuffer
+outcome
+outer
+Outer
+outerIndex
+outline
+Outline
+OUTLINE
+OUTLINED
+outlines
+OUTOFMEMORY
+outOfRange
+output
+Output
+OutputArray
+outside
+outward
+over
+OVERBAR
+overflow
+OVERFLOW
+Overflowed
+overflows
+Overflows
+overhead
+overlap
+OVERLAP
+OVERLAPPED
+overlapping
+OVERLAPPING
+OVERLAY
+overloaded
+overloading
+overridden
+override
+Override
+OVERRIDE
+overriden
+overrides
+Overrides
+overriding
+overstrike
+Overstruck
+OVERSTRUCK
+overview
+overwrite
+Owen
+own
+owned
+ownership
+Ozumacín
+p
+P
+pa
+Pa
+PA
+pABC
+Pacaraos
+pack
+package
+packages
+packed
+pad
+padauk
+Padauk
+padded
+padding
+PADMA
+pag
+page
+PAGE
+pages
+pagesize
+PAGESIZE
+Pahari
+PAHAWH
+Pahlavi
+PAHLAVI
+PaintType
+pair
+Pair
+Paired
+pairing
+PairPos
+PairPosFormat
+pairs
+Pairs
+pairSet
+PairSet
+PairValueRecord
+PairValueRecords
+pairwise
+Paite
+Pakistan
+Palantla
+Palauan
+Palaung
+Palestinian
+palette
+Palette
+PALETTE
+paletteFlagsZ
+paletteLabelsZ
+palettes
+Pali
+PALMYRENE
+Palpa
+pam
+Pampanga
+Pampangan
+Panama
+Panao
+Pangasinan
+pango
+Pango
+Panjabi
+panose
+Pao
+pap
+Papiamento
+Papiamentu
+para
+paragraph
+PARAGRAPH
+paragraphs
+Paraguay
+Paraguayan
+parallel
+param
+PARAM
+parameter
+parameters
+Parameters
+PARAMETERS
+params
+PARAMS
+paren
+parenleft
+parenleftinferior
+parenleftsuperior
+parenright
+parenrightinferior
+parenrightsuperior
+parent
+Parent
+parentheses
+PARENTHESIS
+parity
+parse
+parsed
+parser
+PARSER
+parses
+Parses
+parsing
+part
+Part
+PART
+partFlags
+PartFlags
+PARTHIAN
+partial
+Partial
+partialdiff
+PARTIALIZE
+partially
+PARTIALLY
+partically
+participate
+participates
+particular
+PARTICULAR
+particularly
+partRecords
+parts
+Parts
+PARTY
+Pascal
+Pasco
+Pashto
+pass
+Pass
+passed
+PASSED
+passes
+passing
+passthru
+past
+Pastaza
+paste
+PASTE
+patah
+path
+PATH
+Pattani
+pattern
+patterns
+Patterns
+pau
+PAU
+pause
+pauses
+pb
+pbt
+pbu
+Pc
+PC
+pcc
+pcd
+pce
+pcGlyphs
+pCharProps
+pchars
+pcItems
+pck
+pcTable
+pd
+Pd
+pdc
+pdefault
+pdf
+PDF
+pdfs
+pe
+Pe
+PE
+peak
+peakCoord
+peakTuple
+peculiarities
+peculiarity
+pedantic
+Pedi
+peek
+PEH
+PEHEH
+Pekal
+pel
+pend
+Pennsylvania
+people
+People
+per
+Per
+PER
+percent
+Percent
+PERCENT
+percentage
+percentScaleDown
+perfect
+perform
+Perform
+performAction
+PerformAction
+performance
+PERFORMANCE
+performed
+performing
+Performing
+performs
+Performs
+perhaps
+period
+PERIOD
+periodcentered
+periodinferior
+PERIODS
+periodsuperior
+peripheral
+Peripheral
+permanently
+PERMIC
+permissible
+permission
+Permission
+permissions
+permissive
+permitted
+permute
+Permyak
+perpendicular
+Persian
+PERSIAN
+persistent
+person
+perspective
+pertaining
+perthousand
+Peru
+pes
+PETITE
+Pf
+pg
+pga
+pglyph
+pGlyphProps
+pGoffset
+pgwide
+Phags
+PHAGS
+Phaistos
+Phake
+Phalaa
+phantom
+PHANTOM
+phantoms
+phase
+Phase
+phases
+Phases
+phi
+Philippines
+PHINTHU
+phk
+Phoenician
+PHOENICIAN
+PHONE
+Phonetic
+phrase
+PHRASE
+PHRU
+pi
+Pi
+PI
+piAdvance
+Picard
+PiCharacters
+pick
+picks
+pictographic
+Pictographic
+Pictures
+PICTURES
+Pidgin
+pidgins
+piece
+piecemeal
+pieces
+Piemontese
+pih
+pinfo
+pipes
+Pisin
+Pitcairn
+pItems
+pivot
+Pivot
+pivots
+pixel
+Pixel
+pixels
+pixelSize
+pj
+pk
+PK
+pkey
+pkg
+pkgconfig
+pko
+pl
+place
+Place
+placed
+placeholder
+Placeholder
+PLACEHOLDER
+placeholders
+placement
+PLACEMENT
+placements
+plain
+Plains
+plan
+Plan
+PLAN
+plane
+Plane
+planes
+planned
+planner
+planning
+plans
+Plans
+Plateau
+platform
+Platform
+platformID
+platforms
+ple
+please
+plen
+plevel
+pll
+plookups
+plp
+plt
+plus
+PLUS
+plusminus
+pms
+pnb
+png
+PNG
+PNGHeader
+po
+Po
+Pocomchi
+poh
+Pohnpeian
+point
+Point
+POINT
+pointed
+pointer
+Pointer
+pointers
+pointing
+points
+POINTS
+POISON
+Pökoot
+Poland
+Polish
+polyton
+polytonic
+Polytonic
+pon
+pool
+POOL
+pools
+poor
+pop
+popcount
+popcountl
+popcountll
+popped
+pops
+populate
+Populate
+population
+Poqomchi
+port
+Port
+portability
+portal
+Portugal
+Portuguese
+pos
+Pos
+POS
+positinoing
+position
+Position
+POSITION
+Positional
+positioned
+positioning
+Positioning
+positions
+POSITIONS
+positive
+Positive
+POSIX
+PosLookup
+PosLookupSubTable
+possibility
+POSSIBILITY
+possible
+Possible
+possibly
+post
+Post
+POST
+PosTable
+postcompensation
+PostcompensationActionChain
+posted
+postfix
+Postfixed
+POSTFIXED
+postponing
+postprocess
+postscript
+Postscript
+PostScript
+POSTSCRIPT
+postScriptNameIDX
+postV
+potential
+potentially
+potfRecords
+Pournader
+pOutGlyphProps
+pow
+power
+powers
+pp
+ppa
+ppc
+ppem
+PPEM
+ppemX
+ppemY
+PPI
+ppObject
+pPos
+pr
+practical
+practice
+pragma
+PRAGMA
+pragmas
+PRC
+pre
+Pre
+PRE
+precede
+precedence
+preceding
+Preceding
+PRECEDING
+precious
+precision
+precomposed
+Pred
+predef
+predefined
+Predicate
+predicates
+predictable
+pref
+PREF
+prefer
+Prefer
+preferable
+preference
+preferences
+preferred
+Preferred
+prefers
+prefix
+PREFIX
+prefixed
+Prefixed
+PREFIXED
+preloadAll
+prepare
+Prepare
+preparing
+preprocess
+preprocessor
+PREREQ
+pres
+PRES
+presence
+present
+PRESENT
+presentation
+Presentation
+preserve
+PRESERVE
+preserved
+preserving
+presForm
+presidential
+pressure
+PRETTY
+prev
+PREV
+prevent
+PREVENT
+prevented
+preventing
+prevents
+previous
+previously
+Previously
+Pri
+primarily
+primary
+prime
+primitives
+PRIMITIVES
+Principality
+print
+Print
+printed
+printer
+Printer
+printf
+PRINTF
+printing
+prints
+prior
+priorities
+prioritize
+priority
+Priority
+priv
+private
+Private
+PRIVATE
+PrivateDict
+privateDictInfo
+privateDictInfos
+privateDicts
+privateDictsOffset
+privateInfos
+PrivatePointNumbers
+privDictStr
+PRIVDICTVAL
+privInfo
+PRIVOPSET
+privSzr
+pro
+probable
+probably
+Probably
+Probing
+problem
+problems
+Procedure
+proceed
+proceeding
+process
+Process
+processed
+processes
+processing
+procs
+produce
+produced
+Produced
+produces
+product
+Profile
+PROFITS
+program
+programlisting
+programming
+programs
+Programs
+Proj
+project
+projection
+Projection
+promise
+promotion
+propagate
+Propagate
+proper
+properly
+properties
+PROPERTIES
+property
+PROPORTIONAL
+proportionally
+props
+PROPS
+PROT
+protected
+Protection
+prototypes
+provenc
+Provençal
+proves
+provide
+PROVIDE
+provided
+PROVIDED
+provider
+provides
+Provides
+Province
+proxy
+Proxy
+prs
+prune
+ps
+Ps
+PS
+psa
+Psalter
+PSALTER
+psc
+psControl
+pScriptTags
+pse
+pseudo
+Psmall
+psState
+pst
+pstf
+PSTF
+PString
+PSTS
+psva
+pt
+PT
+ptem
+pthread
+PTHREAD
+ptr
+PTR
+ptrdiff
+Pu
+pua
+PUA
+PUACHUE
+public
+Public
+PUBLIC
+publicly
+published
+Puerto
+Pulaar
+Pular
+pull
+Pull
+punctuation
+Punctuation
+PUNCTUATION
+Punjabi
+Puno
+pure
+Pure
+PURE
+purely
+purpose
+PURPOSE
+purposes
+push
+Push
+put
+Put
+puts
+pv
+pval
+pwcChars
+pwcInChars
+pwGlyphs
+pwLogClust
+pwo
+Pwo
+pwOutGlyphs
+px
+py
+Python
+q
+Q
+Qaai
+QAF
+qamats
+QAMATS
+Qatar
+Qiandong
+Qimant
+Qiubei
+QOF
+Qsmall
+qsort
+QSORT
+QType
+qu
+QUAD
+QuadPart
+qualifiers
+quantity
+QUARTER
+qub
+qubuts
+quc
+qud
+Quechua
+queried
+queries
+query
+querying
+QueryInterface
+question
+QUESTION
+questiondown
+questiondownsmall
+questions
+questionsmall
+quf
+qug
+quh
+Quichua
+quick
+quickly
+quicksort
+Quicksort
+Quiotepec
+quite
+quk
+qul
+quot
+quotation
+quotations
+quote
+quotedbl
+quotedblbase
+quotedblleft
+quotedblright
+quoteleft
+quoteright
+QUOTES
+quotesinglbase
+quotesingle
+Quotient
+Quoting
+qup
+qur
+qus
+qut
+quw
+qux
+quy
+quz
+qva
+qvc
+qve
+qvh
+qvi
+qvj
+qvl
+qvm
+qvn
+qvo
+qvp
+qvs
+qvw
+qvz
+qwa
+qwc
+qwh
+qws
+qxa
+qxc
+qxh
+qxl
+qxn
+qxo
+qxp
+qxr
+qxt
+qxu
+qxw
+r
+R
+ra
+Ra
+RA
+race
+races
+radical
+RADICAL
+radicalDegreeBottomRaisePercent
+Radicals
+rafe
+RAFE
+rag
+ragel
+Raise
+RAISE
+raises
+raj
+Rajasthani
+Rakhine
+ran
+rand
+random
+Random
+RANDOM
+randomize
+Randomly
+range
+Range
+RANGE
+rangeCount
+rangeEnd
+rangeGaspBehavior
+rangeMaxPPEM
+rangeMaxValue
+rangeMinValue
+rangeoffset
+rangeOffset
+rangeRecord
+RangeRecord
+ranges
+Ranges
+RANGES
+rangeShift
+RangeShift
+rangeStart
+Ranglong
+rar
+rare
+RARE
+Rarely
+Rarotongan
+rasterizer
+rate
+rather
+ratio
+raw
+rb
+rbb
+rbl
+RC
+rclt
+rcRangeChars
+RCU
+rcurveline
+RD
+RDONLY
+re
+Re
+reach
+reaches
+read
+Read
+READ
+readable
+reader
+ReadFileFragment
+READING
+readingDirection
+readjusting
+readonly
+READONLY
+ready
+real
+Real
+realistic
+reality
+realloc
+reallocate
+Reallocate
+reallocating
+really
+Really
+rearranged
+rearrangement
+Rearrangement
+REARRANGEMENT
+RearrangementSubtable
+reason
+reasons
+reassign
+reassigned
+reassignment
+reassignSIDs
+rebuild
+REBUS
+rec
+recalculated
+recategorize
+receive
+recent
+recently
+Recognition
+recognizable
+recognize
+recognized
+recognizes
+recom
+recommended
+recompose
+recomposed
+recomposing
+recomposition
+reconfiguration
+reconfigured
+reconfiguring
+record
+Record
+RECORD
+RecordArrayOf
+recording
+RecordList
+RecordListOf
+records
+Records
+Recover
+recovery
+recreate
+recurring
+recurse
+recursed
+Recursed
+recursing
+recursion
+recursive
+recursively
+Recursively
+red
+Red
+redefine
+redefined
+redirected
+redone
+Redu
+reduce
+redundant
+reenabling
+ref
+refcount
+refer
+reference
+Reference
+REFERENCE
+referenced
+referenceGlyph
+references
+referred
+referring
+refers
+REFIID
+refine
+refinements
+reflect
+reflecting
+reflects
+Reformed
+refs
+REGARD
+regardless
+Regex
+region
+Region
+regionCount
+regionIndices
+regions
+register
+Register
+REGISTER
+registered
+RegisterFontFileLoader
+registers
+registry
+Registry
+regular
+Regular
+REGULAR
+REH
+reinterpret
+rej
+Rejang
+REJANG
+reject
+Reject
+rejection
+rel
+REL
+related
+relation
+relationship
+relative
+relax
+relaxed
+RELAXED
+release
+Release
+RELEASE
+released
+releasedc
+ReleaseDC
+ReleaseFileFragment
+ReleaseFontTable
+releases
+relevant
+relicensed
+relies
+relocating
+rely
+Rely
+relying
+remain
+remainder
+remained
+remaining
+remains
+remap
+remapping
+remaps
+Remarks
+remember
+Remember
+remembered
+Removable
+removal
+remove
+Remove
+REMOVE
+removed
+RemoveFontMemResourceEx
+removing
+rename
+render
+rendered
+renderer
+rendering
+renders
+renum
+renumber
+Renumber
+renumbering
+renumbers
+reorder
+Reorder
+reordered
+REORDERED
+reordering
+Reordering
+reorders
+Reorders
+Repack
+repeat
+REPEAT
+repeated
+repeatedAddGlyphAction
+RepeatedAddGlyphAction
+repeating
+REPEATING
+reph
+Reph
+REPH
+repha
+Repha
+REPHA
+replace
+Replace
+replaced
+REPLACEME
+replacement
+REPLACEMENT
+replaces
+Replaces
+replacing
+replicate
+report
+Report
+reports
+Reports
+repositioned
+repositioning
+repository
+represent
+representation
+representations
+represented
+representing
+represents
+Represents
+reproduces
+Republic
+reqFeatureIndex
+request
+requested
+requests
+require
+Require
+required
+REQUIRED
+requirement
+requirements
+requires
+Requires
+requiring
+res
+resCountM
+research
+reserved
+Reserved
+RESERVED
+reservedESC
+ReservedESC
+reservedPad
+reset
+Reset
+Resets
+RESH
+reshaping
+reside
+resize
+resizing
+resolution
+resolutions
+resolve
+Resolved
+resolvedLevel
+resolver
+resolves
+resort
+Resort
+resource
+Resource
+ResourceForkHeader
+ResourceMap
+ResourceRecord
+resources
+resourcesZ
+ResourceTypeRecord
+respect
+respective
+respectively
+responsibilities
+responsibility
+responsible
+resreved
+rest
+RESTORE
+restrict
+restructuring
+result
+resulted
+resulting
+RESULTING
+results
+resume
+ret
+Ret
+RET
+retain
+Retain
+retained
+retains
+RETAINS
+retired
+retrieve
+retrieved
+retrieves
+Retrieves
+retry
+return
+Return
+RETURN
+returned
+Returned
+returning
+returns
+Returns
+reuse
+reused
+reusing
+reverse
+REVERSE
+reverseChainContextSingle
+ReverseChainSingle
+ReverseChainSingleSubst
+ReverseChainSingleSubstFormat
+reversed
+Reverses
+reversing
+revert
+revised
+rewind
+Rewind
+rewinding
+Rewinding
+Rewrite
+rfHeader
+RHA
+RHEL
+rhs
+Rhs
+ri
+ria
+Riang
+Rica
+Rico
+ridentity
+Rieger
+rif
+right
+Right
+RIGHT
+rightC
+rightClass
+rightClassCount
+rightClassTable
+rightSide
+RightToLeft
+Rinconada
+ring
+Ringsmall
+Ripuarian
+rise
+RISE
+RISH
+risking
+rit
+Ritarungo
+rki
+RKRF
+rkw
+rl
+rlig
+rligLookup
+rligMarksLookup
+rlinecurve
+rlineto
+rm
+RM
+rmc
+rmf
+rml
+rmn
+rmo
+rmoveto
+rmw
+rmy
+rmz
+rn
+rnl
+RNOON
+ro
+Ro
+RO
+road
+Robatic
+Roberts
+rock
+Rod
+Roderick
+Rohingya
+ROHINGYA
+role
+roll
+rom
+Roman
+ROMAN
+Romani
+Romania
+Romanian
+ROMANIZATION
+Romansh
+Romany
+room
+root
+rooted
+Roozbeh
+ros
+ROS
+rotate
+rotated
+Rotuman
+round
+ROUND
+ROUNDED
+roundf
+ROUNDF
+rounding
+rounds
+routine
+routines
+roux
+Roux
+row
+rowCount
+rowIndexTable
+rows
+rowWidth
+royalty
+RP
+rpc
+rphf
+RPHF
+rpRangeProperties
+RRA
+rrcurveto
+RREH
+RS
+rsb
+rsbMap
+Rsmall
+rsuperior
+Rsv
+rt
+rtl
+RTL
+rtlm
+rtm
+ru
+Ruanda
+RUBY
+Ruching
+rue
+rule
+Rule
+RULE
+rules
+Rules
+ruleSet
+RuleSet
+rulesets
+ruleSets
+Rumai
+run
+Run
+RUN
+Rundi
+runHead
+Runic
+RUNIC
+running
+runs
+runtime
+Runtime
+rup
+rupiah
+Russia
+Russian
+Rusyn
+rvalue
+rvalues
+Rvalues
+rw
+Rwanda
+rwr
+Ryan
+s
+S
+sa
+Saamia
+Sabah
+Sabaot
+Sad
+SAD
+Sadri
+safe
+safely
+safest
+sah
+Saharan
+said
+Saidi
+Saint
+Sakalava
+sake
+Sakha
+sakot
+SAKOT
+sal
+Salasaca
+salt
+Salvador
+sam
+Samaritan
+SAMARITAN
+Sambalpuri
+same
+Same
+SAME
+SAMEKH
+Sami
+Samoan
+Samogitian
+sample
+SAMPLE
+sampleTextNameId
+sampleTextNameID
+San
+Sanaani
+sandboxed
+sane
+Sango
+sanitization
+sanitizations
+sanitize
+Sanitize
+SANITIZE
+sanitized
+sanitizer
+sanitizing
+Sanitizing
+sanity
+Sankaran
+Sans
+Sanskrit
+Santa
+Santali
+Santiago
+santization
+SAR
+sara
+SARA
+Saraiki
+Sardinian
+Sarsi
+sas
+Sasak
+Sascha
+Sassarese
+sat
+Saterfriesisch
+Saterland
+Saudi
+Saurashtra
+SAURASHTRA
+save
+Save
+SAVE
+saved
+savedprops
+Saves
+saw
+Saxon
+say
+Sayisi
+says
+sb
+SBase
+SBASE
+SBitLineMetrics
+sbix
+SBIX
+SBIXGlyph
+SBIXStrike
+sbl
+SBL
+SBLHebrewUserManual
+sc
+Sc
+SC
+Scalable
+scalar
+Scalar
+scalars
+scale
+SCALE
+scaled
+SCALED
+scalef
+scaler
+scaling
+scan
+Scan
+sCapHeight
+scaron
+Scaron
+Scaronsmall
+scedilla
+Scedilla
+scenario
+scenarios
+SCHAR
+sched
+SCHED
+scheme
+Schouten
+science
+SCIENTIFIC
+sck
+scn
+sco
+sconsumed
+scope
+score
+Scots
+Scottish
+scount
+SCount
+SCOUNT
+scratch
+SCRATCH
+screen
+script
+Script
+SCRIPT
+scriptAnalysis
+scriptCode
+ScriptExtensions
+ScriptFreeCache
+ScriptItemize
+ScriptItemizeOpenType
+scriptList
+ScriptList
+ScriptPlace
+ScriptPlaceOpenType
+scriptProperties
+scripts
+Scripts
+SCRIPTS
+ScriptShape
+ScriptShapeOpenType
+ScriptTag
+scripttags
+scs
+scursor
+sd
+SD
+sDageshForms
+sdc
+sdh
+SDL
+sdn
+se
+seac
+search
+Search
+SEARCH
+searched
+searching
+searchRange
+Sebat
+sec
+second
+Second
+secondGlyph
+seconds
+sect
+section
+SECTION
+sections
+security
+sed
+see
+See
+seeing
+seek
+seem
+seems
+Seems
+seen
+SEEN
+seenCrossStream
+seequence
+sees
+seg
+segcount
+segCount
+segCountX
+segment
+Segment
+SEGMENT
+segmented
+segmenting
+SegmentMaps
+segments
+segol
+seh
+Seigo
+sek
+Sekani
+Sekota
+sel
+select
+Select
+selected
+selecting
+selection
+selections
+selectively
+SelectObject
+selector
+Selector
+SELECTOR
+selectors
+Selectors
+SELECTORs
+selectorToDisable
+selectorToEnable
+selects
+Seletar
+self
+Selkup
+semantic
+semantical
+SEMANTICS
+Sembilan
+semi
+SEMI
+Semibold
+semicolon
+SEMICOLON
+Sena
+send
+sending
+Senegal
+sense
+sensible
+sensitive
+SENSITIVE
+sensitivity
+sent
+sentence
+Senthang
+sentinel
+SENTINEL
+separate
+separated
+separately
+separation
+Separator
+SEPARATOR
+seq
+sequence
+Sequence
+sequenceIndex
+sequences
+SEQUENCES
+sequential
+sequentially
+Serbia
+Serbian
+Serer
+serial
+serialization
+serialize
+Serialize
+SERIALIZE
+serialized
+serializer
+SERIALIZER
+Serializes
+series
+Serif
+serve
+servers
+serves
+Sesotho
+set
+Set
+SET
+SetBidiLevel
+SetComponent
+SetCurrentRun
+SetLineBreakpoints
+setlocale
+SETLOCALE
+SetMark
+SetNumberSubstitution
+sets
+Sets
+SETS
+SetScriptAnalysis
+Setswana
+setter
+setters
+setting
+Setting
+SettingName
+settings
+settingTableZ
+setup
+Setup
+seven
+SEVEN
+seveneighths
+seveninferior
+sevenoldstyle
+sevensuperior
+SEVENTEEN
+several
+severely
+Severn
+sez
+sFamilyClass
+sfinae
+SFINAE
+sfm
+SFNSDisplay
+SFNSText
+sfnt
+Sfnt
+SFNT
+sfntVersion
+sg
+sga
+sgc
+sgi
+sgs
+sgw
+sh
+sha
+shadda
+Shadda
+SHADDA
+shaddaLigature
+shaddaLigatureSet
+shaddaLigaturesSubLookup
+Shadow
+SHADOW
+shall
+SHALL
+shallow
+Shan
+shape
+Shape
+SHAPE
+shaped
+shaper
+Shaper
+SHAPER
+shaperprefs
+shapers
+Shapers
+SHAPERS
+shapes
+Shapes
+SHAPES
+shaping
+Shaping
+SHAPING
+Sharada
+SHARADA
+share
+SHARE
+shared
+Shared
+SHARED
+SharedPointNumbers
+sharedTupleCount
+sharedTuples
+Shavian
+SHAVIAN
+SHEEN
+Sheeter
+Shekhawati
+shell
+SHELL
+sheva
+shi
+shift
+Shift
+SHIFT
+shifted
+Shifter
+SHIFTER
+shifting
+Shifting
+Shihhi
+shin
+SHIN
+ship
+shipped
+shn
+Shona
+short
+Short
+SHORT
+shortCount
+shortcut
+shortcuts
+shortest
+shortfall
+Shorthand
+SHORTHAND
+shortint
+shoudln
+should
+Should
+shouldn
+Shouldn
+show
+SHOW
+showing
+shows
+shrink
+Shrinkage
+shrinkageDisableGPOS
+shrinkageDisableGSUB
+shrinkageEnableGPOS
+shrinkageEnableGSUB
+shrinkageJstfMax
+shrinkFlags
+SHRT
+shu
+Shua
+shuffle
+Shurishkar
+shut
+Shut
+Shwe
+si
+Sibe
+SIBLING
+Sichuan
+Sicilian
+sid
+SID
+Sidamo
+Siddham
+SIDDHAM
+side
+sidebearing
+sides
+sidmap
+sids
+SIDs
+Sierra
+sign
+Sign
+signature
+signed
+Signed
+SIGNED
+signedness
+significance
+significant
+significantly
+signifying
+signs
+SIGNWRITING
+Sihuas
+Siksika
+sil
+SIL
+silently
+Silesian
+silf
+Silf
+SILF
+Silt
+Silte
+Simalungun
+similar
+Similar
+similarly
+Similarly
+SIMP
+simple
+Simple
+SIMPLE
+SimpleGlyph
+simpler
+simplest
+simplicity
+simplification
+simplified
+Simplified
+SIMPLIFIED
+simplifies
+Simplifies
+simplify
+simply
+SIMULATIONS
+sin
+SIN
+since
+Since
+Sindhi
+Singapore
+single
+Single
+SINGLE
+SinglePos
+SinglePosFormat
+SingleSubst
+SingleSubstFormat
+singleton
+singletons
+singular
+SINH
+sinhala
+Sinhala
+SINHALA
+Sinhalese
+sink
+Sink
+sinks
+Sinte
+SIOT
+Sit
+site
+sites
+situations
+six
+SIX
+sixinferior
+sixoldstyle
+sixsuperior
+sixteen
+SIXTEEN
+Siyin
+size
+Size
+SIZE
+sized
+SIZED
+sizeDeviceRecord
+sizeof
+sizes
+sizeTable
+sizeTables
+sizing
+sjd
+sjo
+sk
+Sk
+SKEWED
+skg
+skip
+Skip
+SKIP
+skippable
+skipped
+skipping
+Skipping
+skippy
+Skolt
+skr
+sl
+SL
+slant
+Slant
+SLANT
+slanted
+slash
+SLASH
+SLASHED
+Slave
+Slavey
+Slavonic
+slen
+slightly
+slim
+slnt
+slope
+slot
+slots
+Slovak
+Slovakia
+Slovenia
+Slovenian
+slower
+sm
+Sm
+SM
+sma
+SMAbv
+small
+Small
+SMALL
+smaller
+smallest
+Smallest
+SmallGlyphMetrics
+smart
+SMART
+SMBlw
+smj
+smn
+smoking
+sms
+SMVD
+sn
+snap
+snapshot
+sniff
+snk
+snprintf
+so
+So
+Sochiapam
+Sodo
+SOFT
+software
+Software
+SOFTWARE
+Soga
+Sogdian
+SOGDIAN
+Solaris
+SOLARIS
+solely
+solution
+Somali
+some
+Some
+Somebody
+somefunc
+somehow
+Somehow
+someone
+something
+sometime
+sometimes
+somewhat
+SOMPENG
+Songe
+Soninke
+soon
+sop
+SORA
+Sorbian
+sort
+Sort
+SORT
+sorted
+Sorted
+SORTED
+SortedArrayOf
+sortedness
+SortedUnsizedArrayOf
+sorting
+SORTING
+Sotho
+SOUND
+sounds
+source
+Source
+SOURCE
+sourceware
+South
+SOUTH
+Southeast
+Southeastern
+Southern
+Southwestern
+Soyombo
+SOYOMBO
+spac
+space
+Space
+SPACE
+spaced
+spaces
+Spaces
+spacing
+Spacing
+SPACING
+Spain
+Spanish
+spans
+speaking
+spec
+Spec
+special
+Special
+SPECIAL
+Specialization
+specializations
+Specializations
+Specialize
+specially
+Specials
+specific
+specifically
+SPECIFICALLY
+specification
+specifications
+specificed
+specifics
+specified
+specifies
+specify
+specifying
+specs
+speculative
+speed
+Speed
+speeds
+split
+Split
+SplitCurrentRun
+splitPoint
+splitPosition
+Spoon
+SPOT
+Spread
+spreadsheets
+Spring
+spv
+spy
+sq
+sqrt
+Square
+SQUARE
+SQUARED
+squeezing
+sr
+src
+Sri
+sro
+srr
+srs
+ss
+ssh
+Ssmall
+SSOT
+ssuperior
+ssxx
+ssXX
+st
+stable
+stack
+Stack
+STACK
+Stacker
+STACKER
+stacking
+stackoverflow
+stage
+stages
+STAGES
+stale
+standalone
+standard
+Standard
+StandardEncoding
+standardheaderfiles
+standards
+stands
+start
+Start
+START
+startCharCode
+startcode
+startCode
+startConnectorLength
+startCoord
+startCount
+started
+Started
+starter
+Starter
+startGlyph
+startGlyphID
+startGlyphIndex
+starting
+Starting
+StartOfText
+starts
+startSize
+startUnicodeValue
+stat
+STAT
+StatAxisRecord
+state
+State
+STATE
+stateArrayTable
+stateHeader
+statement
+states
+States
+STATES
+StateTable
+StateTableDriver
+stateTableOffset
+static
+Static
+STATIC
+status
+stay
+stays
+stch
+STCH
+std
+STD
+stdarg
+stddef
+stderr
+stdGlyph
+StdHW
+stdint
+stdio
+stdlib
+STDMETHODCALLTYPE
+STDMETHODIMP
+StdVW
+stem
+StemSnapH
+StemSnapV
+step
+STEP
+stepping
+steps
+sterling
+stHeader
+still
+Still
+stmt
+STMT
+stop
+Stop
+STOP
+stopped
+stops
+storage
+Storage
+store
+Store
+STORE
+stored
+Stored
+storing
+stq
+str
+STR
+straight
+Straight
+straightforward
+strategic
+strategy
+Strategy
+strbuf
+strchr
+strcmp
+strcpy
+strdup
+stream
+streams
+strerror
+stretch
+Stretch
+STRETCH
+stretchable
+stretched
+stretchGlyphAction
+StretchGlyphAction
+stretching
+Stribley
+Strict
+STRICT
+strictly
+stride
+strike
+strikeout
+STRIKEOUT
+strikes
+string
+String
+STRING
+stringIndex
+StringIndex
+stringIndexInfo
+stringOffset
+strings
+strlen
+strncmp
+strncpy
+stroke
+Strokes
+StrokeWidth
+strong
+strongly
+strstr
+strtod
+STRTOD
+strtol
+strtoul
+struct
+StructAfter
+StructAtOffset
+StructAtOffsetOrNull
+StructAtOffsetUnaligned
+structs
+STRUCTS
+structure
+Structure
+structures
+Studio
+stuff
+stupid
+stv
+style
+Style
+STYLE
+stylistic
+Stylistic
+STYLISTIC
+stylisticSet
+sTypoAscender
+sTypoDescender
+sTypoLineGap
+su
+sub
+SUB
+subarray
+subclass
+Subclass
+subclasses
+subdivided
+subdivision
+subfamily
+SUBFAMILY
+subfamilyID
+subfamilyNameID
+subFeatureFlags
+subfonts
+SubFormat
+subject
+subjoined
+Subjoined
+SUBJOINED
+subjoining
+sublookup
+SUBLOOKUP
+SubLookupOffsets
+SubLookupOffsetsArray
+submerged
+subpixel
+subr
+subrecord
+subroffset
+subroutine
+Subroutine
+subroutines
+subrs
+Subrs
+SUBRS
+subrsOffset
+subs
+subscript
+Subscript
+SUBSCRIPT
+subscripts
+Subscripts
+subsequence
+subsequences
+subsequent
+subset
+Subset
+SUBSET
+SubsetGlyph
+Subsets
+subsetted
+subsetter
+SUBSETTER
+subsetting
+subst
+SUBST
+substantially
+substGlyph
+substitued
+substitute
+Substitute
+SUBSTITUTE
+substituted
+SUBSTITUTED
+substitutes
+substituteX
+substitution
+Substitution
+SUBSTITUTION
+substitutions
+substitutionTables
+SubstLookup
+SubstLookupSubTable
+substr
+substring
+substThreshold
+subsystem
+subtable
+subTable
+Subtable
+SubTable
+subtableCount
+SubTableFlags
+subtableGlyphCoverageArray
+SubTableHeader
+subtables
+Subtables
+SubTables
+SUBTABLES
+SubtableType
+subtag
+SUBTAG
+subtags
+subtending
+subtract
+subtracting
+subtraction
+succeed
+succeeded
+SUCCEEDED
+Succeeding
+SUCCEEDING
+succeeds
+success
+successful
+successfully
+successive
+such
+SUCH
+sucks
+Sudanese
+sudo
+sufficient
+SUFFICIENT
+suggest
+suggested
+Suggested
+suggests
+suit
+suitable
+suite
+Suite
+suk
+Sukuma
+sukun
+SUKUN
+sum
+Sum
+summation
+Summer
+sun
+Sundanese
+SUNDANESE
+SUNPRO
+SUPER
+superimposing
+SUPERIORS
+superscript
+SUPERSCRIPT
+superscripts
+Superscripts
+supp
+suppData
+suppEncData
+SuppEncData
+SuppEncoding
+supplement
+Supplement
+Supplemental
+supplied
+supply
+supplying
+support
+Support
+SUPPORT
+supported
+Supported
+SUPPORTED
+supporting
+supports
+Supports
+supposed
+supposedly
+suppress
+supps
+suq
+sure
+Suri
+surprise
+surprises
+surrogate
+SURROGATE
+Surrogates
+surrounding
+survive
+survived
+survives
+sutable
+Sutu
+sv
+sva
+Svan
+svg
+SVG
+svgDoc
+svgDocEntries
+svgDocLength
+SVGDocumentIndexEntry
+SVR
+sw
+Swadaya
+Swahili
+Swampy
+swap
+Swap
+SWAP
+swaplp
+swapped
+swaps
+SWASH
+SWASHES
+Swati
+swb
+swc
+Sweden
+Swedish
+Sweep
+swh
+switch
+Switch
+switched
+switches
+Switzerland
+swv
+sxHeight
+sxu
+syc
+syl
+Sylheti
+Syllabary
+syllabic
+Syllabic
+SYLLABIC
+Syllabics
+SYLLABICS
+syllable
+Syllable
+SYLLABLE
+syllables
+Syllables
+Syloti
+SYLOTI
+SYM
+symbol
+Symbol
+SYMBOL
+symbolic
+symbols
+Symbols
+SYMBOLS
+symmetric
+sync
+synchronize
+syntatically
+syntax
+Syntax
+synthesize
+synthesizes
+synthesizing
+SyntheticBase
+syr
+Syrc
+syre
+Syre
+Syria
+syriac
+Syriac
+SYRIAC
+syrj
+Syrj
+syrn
+Syrn
+sys
+SYS
+sysconf
+SYSCONF
+system
+System
+SYSTEM
+systems
+sz
+szl
+t
+T
+ta
+Ta
+taa
+tab
+Tabasaran
+Tabassaran
+table
+Table
+TABLE
+tableCount
+tablelist
+TableRecord
+TableRecords
+tables
+Tables
+TABLES
+tableTag
+TableType
+Tachelhit
+Tachoni
+tag
+Tag
+TAG
+Tagalog
+TAGALOG
+Tagbanwa
+TAGBANWA
+tagFeature
+tagged
+Tagin
+Tagish
+tagLangSys
+tagRanges
+tags
+Tags
+TAGS
+tagScript
+TAH
+Tahaggart
+Tahitian
+Tahltan
+tahoma
+Tahoma
+tahomabd
+Tai
+TAI
+tail
+Tail
+tailored
+Taiwan
+Taiwanese
+Tajik
+Tajiki
+Tajikistan
+take
+Take
+taken
+takes
+taking
+Takri
+TAKRI
+TALL
+Tamahaq
+Tamajaq
+Tamajeq
+Tamashek
+Tamasheq
+Tamazight
+Tamil
+TAMIL
+TAML
+Tanacross
+Tanaina
+Tanana
+TANDEM
+Tandroy
+Tangshewi
+TANGUT
+Tanosy
+Tanzania
+taq
+tarball
+Tarball
+target
+TARGET
+TargetConditionals
+targs
+Tarifit
+tasks
+Tatar
+tator
+tau
+TAV
+Tawallammat
+Tawr
+Tày
+Tayart
+Taylor
+TB
+TBase
+TBASE
+tbl
+tbody
+TBR
+tcb
+tce
+TCHEH
+TCHEHEH
+TCodepoint
+TCount
+TCOUNT
+tcp
+tcy
+tcz
+tdd
+tdx
+te
+tec
+technetwork
+Technical
+technicalities
+Technically
+Tedim
+TEH
+TEHEH
+telecom
+tell
+tells
+TELU
+Telugu
+TELUGU
+tem
+Temne
+temp
+templ
+template
+Template
+templates
+temporarily
+temporary
+tempting
+Temuan
+TEN
+Tena
+Tenggarong
+Tepetotutla
+Tepinapa
+Terik
+term
+terminal
+Terminal
+terminate
+terminated
+terminates
+terminating
+termination
+Termination
+TerminationWordCount
+terminator
+terminology
+Terminology
+terms
+Tesaka
+test
+Test
+TEST
+tested
+testing
+Testing
+tests
+Tests
+tet
+TET
+Tetum
+text
+Text
+TEXT
+TextAnalysis
+textAnalyzer
+textLength
+textPosition
+textProperties
+TEXTRANGE
+textString
+textual
+tfn
+tg
+tgj
+tgroup
+tgx
+th
+TH
+tha
+Thaana
+THAANA
+Thado
+thai
+Thai
+THAI
+Thailand
+THAL
+Tham
+THAM
+than
+THAN
+THANTHAKHAT
+that
+That
+the
+The
+THE
+thead
+THEH
+their
+them
+themed
+themselves
+then
+Then
+theory
+thep
+there
+There
+therefore
+Therefore
+these
+These
+they
+They
+thickness
+THICKNESS
+THIN
+thing
+things
+Things
+thingy
+think
+third
+Third
+THIRD
+THIRTEEN
+this
+This
+THIS
+thiz
+THO
+thorn
+Thorn
+Thornsmall
+those
+though
+thread
+Thread
+threading
+threads
+threadsafe
+threadsafely
+three
+Three
+THREE
+threeeighths
+threeinferior
+threeoldstyle
+threequarters
+threequartersemdash
+threesuperior
+through
+throughout
+throw
+tht
+thus
+thv
+thz
+ti
+Tibetan
+TIBETAN
+Tidy
+tiff
+Tifinagh
+TIFINAGH
+tig
+tight
+Tigon
+Tigre
+Tigrinya
+tilde
+Tildesmall
+tile
+tiles
+Tiles
+time
+timeouts
+times
+Times
+timesbi
+timesi
+Timne
+tindex
+Tiny
+TINY
+Tirhuta
+TIRHUTA
+Tiriki
+title
+TITLECASE
+TITLING
+tiv
+Tiv
+tjmo
+TJMO
+tk
+tkg
+tl
+TL
+Tlacoatzintepec
+tlen
+tlist
+TLookup
+TLookupList
+TLR
+TM
+tmh
+tmp
+tmw
+tn
+tnf
+to
+To
+TO
+Toba
+Tobago
+TObject
+toCoord
+tod
+today
+Todo
+TODO
+toe
+together
+ToGlyphs
+toi
+tok
+Tok
+tol
+Tolowa
+TOLOWER
+Toma
+tombstone
+tombstones
+tone
+Tone
+TONE
+tones
+Tonga
+Tongan
+too
+took
+toolkit
+tools
+tooltip
+top
+Top
+TOP
+topAccentAttachment
+topAccentCoverage
+topdict
+topDict
+TopDict
+topDictIndex
+TopDictIndex
+topDictInfo
+topDictModSIDs
+topDictSize
+topDictStr
+toplevel
+topographical
+Topographical
+topologically
+topSide
+topSzr
+Torki
+TORTIOUS
+TORTOISE
+Tosk
+total
+Total
+totalDataSize
+totally
+touch
+TOUCH
+touches
+TOUPPER
+towards
+tpi
+tr
+TR
+trace
+Trace
+TRACE
+tracing
+track
+Track
+trackData
+TrackData
+tracking
+Tracking
+trackNameID
+tracks
+trackTable
+trackTableEntry
+TrackTableEntry
+TRAD
+trade
+trademark
+TRADEMARK
+trademarks
+Traditional
+TRADITIONAL
+trailed
+trailing
+trak
+TRAK
+trampoline
+trans
+TRANSCODING
+transcription
+transfer
+Transfer
+transform
+Transform
+transformation
+transformed
+transforming
+transient
+Transient
+transition
+transitioning
+transitive
+translatation
+translate
+translating
+translation
+TRANSLITERATION
+transparent
+traversal
+treat
+treated
+treatment
+treats
+tree
+trees
+TRI
+trick
+trickiest
+tricky
+Tricky
+tried
+tries
+Tries
+trigger
+triggered
+triggers
+trim
+trimmable
+trimmed
+Trimming
+Trinidad
+trivial
+Trivial
+trivially
+trouble
+troubleshooting
+tru
+true
+TRUE
+TrueTag
+TrueType
+TRUETYPE
+TrueTypeTag
+truly
+truncate
+truncated
+try
+Try
+TryGetFontTable
+trying
+Trying
+ts
+Ts
+TSA
+TSADI
+tsb
+tsere
+Tsetsaut
+Tshangla
+Tsimihety
+tsj
+Tsmall
+Tsonga
+Tsotso
+TSubTable
+tsuperior
+Tswana
+tt
+TTA
+ttb
+TTB
+ttc
+TTC
+ttcf
+ttcHeader
+TTCHeader
+TTCHeaderVersion
+ttcTag
+TTCTag
+TTEH
+TTEHEH
+ttf
+ttm
+ttq
+Tugen
+Tulu
+tum
+Tumari
+Tumbuka
+Tundra
+Tunisia
+Tunisian
+tuple
+Tuple
+tupleCount
+tupleIndex
+TupleIndexMask
+tuples
+tupleVarCount
+TupleVarCount
+TupleVarHeader
+tupleVarHeaders
+Tupple
+TuppleIndex
+Turkey
+Turkic
+TURKIC
+Turkish
+Turkmen
+Turkmenistan
+turn
+Turn
+Turner
+turning
+turns
+Turns
+Turoyo
+Tusi
+Tutchone
+Tututni
+tuu
+Tuvalu
+Tuvin
+Tuvinian
+tuy
+tvalue
+tvl
+tw
+tweaks
+TWELVE
+TWENTY
+Twi
+twice
+twilight
+two
+Two
+TWO
+TwoByteNegInt
+TwoBytePosInt
+twodotenleader
+twoinferior
+twooldstyle
+twosuperior
+twothirds
+tx
+txc
+txt
+txy
+ty
+tying
+Typ
+type
+Type
+TYPE
+typed
+typedef
+typedefs
+typeface
+typefaces
+typeList
+typename
+TypeName
+types
+Types
+TYPES
+typesetter
+typesetting
+typical
+typically
+typo
+TYPO
+typographic
+Typographic
+TYPOGRAPHIC
+typographical
+typography
+Typography
+typos
+tyv
+tyz
+tze
+tzm
+tzo
+Tzotzil
+u
+U
+uacute
+Uacute
+Uacutesmall
+UARRAY
+ub
+uBidiLevel
+ubl
+Ubuntu
+ubyte
+ubytes
+ucd
+UCD
+ucdn
+UCDN
+uchar
+UChar
+UCHAR
+ucircumflex
+Ucircumflex
+Ucircumflexsmall
+ucs
+udieresis
+Udieresis
+Udieresissmall
+udm
+Udmurt
+ue
+UE
+UEE
+UErrorCode
+ufuncs
+ufunctions
+UFWORD
+ug
+Ugaritic
+UGARITIC
+UGC
+Ugh
+ugly
+Ugly
+UGLY
+ugrave
+Ugrave
+Ugravesmall
+UHEADLESSARRAY
+UI
+UIDBase
+Uighur
+uiLabelNameId
+uiNameID
+uint
+UINT
+uintptr
+UIPC
+UISC
+uk
+Ukraine
+Ukrainian
+ULBAR
+ulCodePageRange
+ulink
+ULL
+ULLONG
+ULong
+ULONG
+Ulrich
+ultimately
+ULTRA
+ulUnicodeOS
+ulUnicodeRange
+umb
+Umbundu
+Umm
+un
+unassigned
+UNASSIGNED
+unbounded
+UNBOUNDED
+unchanged
+UNCLASSIFIED
+UnclassifiedGlyph
+unclear
+unconditionalAddGlyphAction
+UnconditionalAddGlyphAction
+unconditionally
+UNCONNECTED
+unconst
+und
+undef
+UNDEF
+undefined
+UNDEFINED
+under
+Under
+UNDERBAR
+underflow
+undergone
+underline
+Underline
+UNDERLINE
+underlinePosition
+UnderlinePosition
+underlineThickness
+UnderlineThickness
+underlining
+underlying
+underneath
+underscore
+UNDERSCORE
+understand
+understandable
+understood
+undertake
+Undetermined
+undo
+undocumented
+Undocumented
+unequal
+UNFITTED
+unforced
+unformed
+unfortunate
+unfortunately
+Unfortunately
+unhide
+uni
+unichar
+UniChar
+unicode
+Unicode
+UNICODE
+UnicodeData
+unicodes
+UNICODES
+unicodeValue
+UnicodeValueRange
+Unified
+uniform
+uninitialized
+union
+UNION
+Unión
+unions
+unique
+UNIQUE
+UniqueID
+uniscribe
+Uniscribe
+UNISCRIBE
+unistd
+UNISTD
+unit
+United
+units
+Units
+unitSize
+unitsPerEm
+uniUUUU
+Universal
+unix
+unknown
+Unknown
+UNKNOWN
+unless
+Unless
+unlike
+unlikely
+unlimited
+UnlimiteGap
+unloaded
+unlock
+Unmake
+unmap
+UnmapViewOfFile
+unmarked
+unnecessary
+unnormalize
+unoffset
+unorm
+UNormalizer
+unpack
+unpadded
+unpop
+unprocessed
+unr
+unrecognized
+unref
+unreferenced
+UnregisterFontFileLoader
+unsafe
+Unsafe
+UNSAFE
+UNSCALED
+unset
+unsigned
+Unsized
+UnsizedArrayOf
+UnsizedByteStr
+UnsizedOffsetArrayOf
+UnsizedOffsetListOf
+unsorted
+UNSUCCESSFUL
+unsupported
+UNSUPPORTED
+unsure
+UNTAG
+until
+untouched
+unused
+Unused
+UNUSED
+unusual
+unwanted
+unwise
+unzip
+uoffset
+up
+UP
+update
+updated
+UPDATES
+upem
+UPEM
+upon
+upper
+Upper
+UPPER
+uppercase
+UPPERCASE
+upperLimit
+upright
+UPROPS
+upward
+ur
+Urak
+Urdu
+urk
+url
+URL
+Uruguay
+us
+USABLE
+usage
+usBreakChar
+uscript
+USCRIPT
+UScriptCode
+usDefaultChar
+use
+Use
+USE
+used
+Used
+useful
+Useful
+useless
+UseMarkFilteringSet
+user
+User
+USER
+userfeatures
+users
+uses
+Uses
+usFirstCharIndex
+USHRT
+Usila
+using
+Using
+USING
+usLastCharIndex
+usLowerOpticalPointSize
+Usmall
+usMaxContext
+usp
+USP
+ustr
+ustring
+usually
+Usually
+usUpperOpticalPointSize
+usWeightClass
+usWidthClass
+usWinAscent
+usWinDescent
+utf
+UTF
+Uthmanic
+util
+utilities
+Utilities
+utility
+utilize
+UTS
+uu
+UU
+UUID
+UuidCreate
+uuidof
+UVCRDOypOtijlMDLNNyyLk
+uversion
+uvs
+UVS
+UVSMapping
+Uyghur
+uz
+Uzbek
+Uzbeki
+Uzbekistan
+uzn
+uzs
+v
+V
+va
+VA
+VAbv
+VAH
+Vai
+VAI
+Vakhi
+val
+Val
+VAL
+ValCount
+valFormat
+valid
+Valid
+VALID
+validate
+validated
+Validator
+validity
+Valle
+valuable
+value
+Value
+VALUE
+valueArrayZ
+valueCount
+valueFormat
+ValueFormat
+valueFormats
+valueIndex
+valueNameID
+ValueRecord
+valueRecordCount
+ValueRecords
+valueRecordSize
+values
+Values
+VALUES
+ValuesAreLong
+valueSize
+valuesZ
+valueTag
+ValueType
+var
+Var
+VAR
+vararg
+varation
+VarData
+varDataSize
+variable
+Variable
+variablelist
+variables
+variant
+Variant
+VARIANT
+variantGlyph
+variants
+Variants
+variation
+Variation
+VARIATION
+variationAxis
+VariationAxisRecord
+VariationDevice
+variations
+Variations
+VARIATIONS
+VariationSelectorRecord
+variationsTag
+VariationStore
+VariationValueRecord
+varidx
+varIdx
+varies
+variety
+varika
+variour
+various
+Various
+varlistentry
+varname
+varRecords
+VarRegionAxis
+VarRegionList
+vars
+varSelector
+VarSizedBinSearchArrayOf
+VarSizedBinSearchHeader
+varStore
+varStoreOffset
+vary
+vattu
+vatu
+Vatu
+VATU
+VAV
+vAxis
+VBAR
+VBase
+VBASE
+VBlw
+VCount
+VCOUNT
+vcpkg
+VD
+ve
+VE
+vec
+vector
+Vector
+VECTOR
+vectorization
+vectorized
+vedic
+Vedic
+VEH
+ven
+Venda
+VENDOR
+Venetian
+Venezuela
+VER
+Verb
+verbatim
+verify
+versa
+version
+Version
+VERSION
+versions
+versionZ
+vert
+VERT
+vertAdvance
+vertBearingX
+vertBearingY
+vertData
+vertGlyphCount
+vertGlyphCoverage
+vertical
+Vertical
+VERTICAL
+vertically
+VertOriginMetric
+vertOriginY
+vertYOrigins
+very
+vfprintf
+vhcurveto
+vhea
+vi
+VI
+via
+vice
+Viet
+VIET
+Vietnam
+Vietnamese
+view
+vindex
+vINVALID
+violation
+virama
+Virama
+VIRAMA
+viramas
+virtual
+Virtualizing
+vis
+Visarga
+VISARGA
+VISATTR
+visibility
+VISIBILITY
+visible
+visibly
+visit
+visited
+visitLangSys
+visitScript
+vista
+Vista
+visual
+Visual
+VISUAL
+vjmo
+VJMO
+vkk
+vkt
+Vlaams
+Vlax
+vlineto
+vls
+VM
+VMAbv
+VMBlw
+vmoveto
+VMPre
+VMPst
+vmtx
+vmw
+vo
+Vo
+VOICED
+VOICING
+void
+Void
+VOID
+VOL
+Volapük
+volatile
+volt
+vorg
+VORG
+vorgMap
+Võro
+vowel
+Vowel
+VOWEL
+vowels
+Vowels
+vp
+VPre
+VPst
+VRBAR
+vrinda
+vro
+Vs
+VS
+vsindex
+vsindexcs
+vsindexdict
+Vsmall
+vsnprintf
+vstem
+vstemhm
+vstore
+vstoreOffset
+vtable
+vv
+vvar
+VVAR
+VVARTag
+vvcurveto
+w
+W
+wa
+Wa
+Wagdi
+Wailaki
+walk
+Walk
+walks
+Wall
+Walloon
+Wanca
+WANCHO
+Wang
+Wanga
+want
+wanted
+wants
+war
+WARANG
+Waray
+warn
+warning
+Warning
+WARNING
+warnings
+Warnings
+WARRANTIES
+was
+Was
+WASLA
+wasn
+waste
+Watch
+watchout
+Watchout
+WAVY
+WAW
+way
+ways
+Wayuu
+wbm
+wbr
+Wbuiltin
+Wc
+Wcast
+WCE
+wchar
+WCHAR
+Wclass
+Wconversion
+wdcTable
+Wdelete
+Wdeprecated
+Wdisabled
+Wdouble
+wdRecord
+wdth
+we
+We
+WE
+weak
+weight
+Weight
+WEIGHT
+weights
+weird
+welcome
+well
+Welsh
+Wembedded
+went
+were
+Werner
+West
+Western
+Weverything
+Wextra
+Wformat
+wght
+what
+What
+WHAT
+whatever
+Whatever
+whatsoever
+WHATSOEVER
+when
+When
+whenever
+Whenever
+where
+whereas
+Whereas
+WheresData
+WheresFace
+wherever
+whether
+Whether
+WHETHER
+which
+Which
+while
+While
+white
+WHITE
+Whitelist
+whitespace
+Whitespace
+who
+whole
+whose
+why
+Why
+wide
+widely
+width
+Width
+WIDTH
+WidthDeltaCluster
+WidthDeltaPair
+widthMax
+widths
+widthsZ
+Wignored
+wiki
+wikipedia
+wild
+will
+Will
+willing
+willis
+wilson
+Wilson
+Wimplicit
+win
+Win
+WIN
+WINAPI
+windows
+Windows
+Winit
+Winjected
+WINNT
+Winter
+Wipe
+wish
+wishes
+with
+With
+WITH
+within
+Within
+without
+Without
+WJ
+wlc
+wle
+wlk
+Wlogical
+Wmaybe
+Wmissing
+Wnested
+wni
+wo
+Wolane
+Wold
+Wolof
+won
+Woods
+word
+Word
+WORD
+wording
+wordOffsetToIndex
+words
+WORDS
+work
+Work
+worked
+working
+Working
+works
+Works
+world
+worry
+worrying
+worth
+would
+Would
+WOULD
+wouldbn
+wouldn
+Wow
+Wpacked
+Wpointer
+Wpragmas
+wrap
+wrapper
+wrappers
+wrapping
+Wredundant
+Wreorder
+writable
+Writable
+WRITABLE
+write
+Write
+WRITE
+writer
+writing
+written
+Written
+wrong
+wrote
+wry
+Ws
+wsg
+Wshadow
+Wsign
+Wsmall
+Wstrict
+Wstring
+Wswitch
+Wtautological
+wtm
+Wtype
+Wu
+Wundef
+Wunknown
+Wunneeded
+Wunsafe
+Wunused
+wuu
+Wvla
+ww
+Wwrite
+WWS
+www
+x
+X
+xa
+xA
+xaa
+xAA
+xAAF
+xAB
+xabc
+xABC
+xABFFu
+xAC
+xAdvance
+xAdvDevice
+xAFF
+xal
+XALLOCATE
+Xamtanga
+xan
+xAu
+xAvgCharWidth
+xb
+xB
+xBA
+xBB
+xBFF
+xBytes
+xc
+xC
+xCD
+xCFF
+Xconstructor
+xCoordinate
+xCULL
+xD
+xDBFFu
+xDC
+xDE
+xDeviceTable
+xDFDFDFDF
+xDFDFDFDFu
+xDFF
+xDFFF
+xDFFFu
+xDFu
+xe
+xE
+xEFF
+xEFu
+xF
+xFAFF
+xFB
+xFBA
+xFBAAu
+xFBABu
+xFBACu
+xFBADu
+xFBAEu
+xFBAFu
+xFBB
+xFBD
+xFBDAu
+xFBDBu
+xFBDCu
+xFBDDu
+xFBDEu
+xFBDFu
+xFBE
+xFBFCu
+xFBFDu
+xFBFEu
+xFBFFu
+xFDFF
+xfe
+xFE
+xFEA
+xFEAAu
+xFEABu
+xFEACu
+xFEADu
+xFEAEu
+xFEAFu
+xFEB
+xFEBAu
+xFEBBu
+xFEBCu
+xFEBDu
+xFEBEu
+xFEBFu
+xFEC
+xFECAu
+xFECBu
+xFECCu
+xFECDu
+xFECEu
+xFECFu
+xFED
+xFEDAu
+xFEDBu
+xFEDCu
+xFEDDu
+xFEDEu
+xFEDFu
+xFEE
+xFEEAu
+xFEEBu
+xFEECu
+xFEEDu
+xFEEEu
+xFEEFu
+xFEF
+xFEFAu
+xFEFBu
+xFEFCu
+xFEFF
+xFEFFu
+xff
+xFF
+xFFEF
+xFFF
+xFFFC
+xFFFD
+xFFFDu
+xFFFE
+xFFFF
+xFFFFD
+xFFFFF
+xFFFFFF
+xFFFFFFFF
+xFFFFFFFFFFFFFull
+xFFFFFFFFu
+xFFFFu
+xFFu
+xFu
+Xgroup
+xh
+Xhb
+Xhosa
+xi
+Xian
+Xiang
+Xiangxi
+Xibe
+XInclude
+xjb
+xkf
+xlocale
+XLOCALE
+xMax
+xMin
+xml
+XML
+xmlns
+xmm
+xmv
+xmw
+xnr
+xOffset
+xog
+xor
+XP
+xpe
+xPlacement
+xPlaDevice
+xscale
+xsl
+Xsmall
+xst
+Xuan
+XUID
+xwo
+xx
+XXX
+XY
+y
+Y
+Ya
+yacute
+Yacute
+Yacutesmall
+yAdvance
+yAdvDevice
+Yakut
+Yanahuanca
+Yang
+Yangbye
+yao
+Yao
+yap
+Yapese
+Yarowilca
+Yauyos
+Yay
+yb
+ybd
+yBytes
+yCoordinate
+ydd
+yDeviceTable
+ydieresis
+Ydieresis
+Ydieresissmall
+YEH
+Yemen
+yen
+yes
+Yes
+YES
+yet
+Ygroup
+yi
+Yi
+YI
+Yiddish
+YIDDISH
+yield
+YIELD
+yields
+yih
+Yijing
+YING
+yMax
+yMin
+yml
+yo
+YO
+YOD
+yOffset
+Yongbei
+Yongnan
+Yoruba
+yos
+Yos
+Yosemite
+you
+You
+Youjiang
+your
+yourinputtext
+yourself
+yPlacement
+yPlaDevice
+yrk
+yscale
+Ysmall
+yStrikeoutPosition
+yStrikeoutSize
+ySubscriptXOffset
+ySubscriptXSize
+ySubscriptYOffset
+ySubscriptYSize
+ySuperscriptXOffset
+ySuperscriptXSize
+ySuperscriptYOffset
+ySuperscriptYSize
+YU
+yue
+Yue
+Yugoslav
+yum
+Yupik
+z
+Z
+za
+ZAH
+ZAIN
+Zambia
+Zamboanga
+Zanabazar
+ZANABAZAR
+Zande
+Zarma
+zawgyi
+Zawgyi
+ZAWGYI
+ZAYIN
+Zazaki
+zcaron
+Zcaron
+Zcaronsmall
+zch
+zdj
+zea
+Zealand
+Zealandic
+Zeeuws
+zeh
+zero
+Zero
+ZERO
+zeroed
+zeroinferior
+zeroing
+zeroint
+zerooldstyle
+zeros
+zerosuperior
+zgb
+zgh
+zgm
+zgn
+zh
+zhd
+zhe
+zhn
+Zhong
+Zhuang
+Zimbabwe
+zip
+zipped
+zk
+Zl
+zlj
+zlm
+zln
+zlq
+zmi
+zne
+zo
+zom
+zone
+Zotung
+Zou
+Zp
+zqe
+Zs
+zsm
+Zsmall
+zu
+Zulu
+zum
+Zuojiang
+zwj
+ZWJ
+zwnj
+ZWNJ
+zyb
+zyg
+zyj
+zyn
+Zyrian
+zza
+zzj

Fichier diff supprimé car celui-ci est trop grand
+ 133 - 0
hbfreetypefont.mod/harfbuzz/perf/texts/fa-thelittleprince.txt


+ 10000 - 0
hbfreetypefont.mod/harfbuzz/perf/texts/fa-words.txt

@@ -0,0 +1,10000 @@
+در
+به
+از
+ویکی‌پدیا
+که
+را
+این
+با
+است
+رده
+برای
+کاربر
+بحث
+تصویر
+میلادی
+ایران
+تاریخ
+نام
+پرونده
+آن
+یک
+ساعت
+صفحهٔ
+کنید
+پیوند
+مقاله
+صفحه
+شما
+اصلی
+عنوان
+یا
+تا
+سال
+هم
+من
+استفاده
+بر
+خود
+شده
+شد
+تغییرمسیر
+شهرستان
+کار
+راهنمای
+اگر
+تکثیر
+چه
+ویرایش
+حق
+مقاله‌های
+می
+فارسی
+نیست
+دیگر
+نوشتن
+پنج
+بود
+زبان
+سیارک
+امضا
+کمک
+شیوه‌نامه
+منابع
+ملی
+ثبت
+آثار
+پانویس
+۱۱
+میز
+خودآموز
+بخش
+دارد
+خرد
+انگلیسی
+او
+لطفاً
+نیز
+۱۵
+شماره
+پهنا
+بنیاد
+استان
+هر
+اثر
+می‌شود
+مورد
+کرد
+یادکرد
+امیدوارم
+راهنما
+کنیم
+خوش
+ویکی
+چیزی
+پس
+شهر
+پیش
+فهرست
+مرجع
+خط
+آمدید
+اطلاعات
+اینجا
+تاریخی
+زیر
+منبع
+جعبه
+جدید
+دوره
+بیشتر
+اینکه
+بهتر
+یکی
+شود
+دو
+سپتامبر
+راهنمایی
+پیوندهای
+حذف
+۲۰۰۰
+خوب
+نظر
+آزاد
+قرار
+خواهد
+تمرین
+باشد
+بله
+پیرامون
+سلام
+آموزش
+اصل
+۱۰
+نه
+صفحات
+۱۹
+۱۲
+۲۰۱۱،
+های
+پاس
+ولی
+توسط
+چگونه
+برگزیده
+بداریم
+فقط
+ویکی‌پروژه
+۲۰۰۱
+روی
+سریع
+اکتبر
+صورت
+دست
+قهوه‌خانه
+۱۴
+دانشگاه
+بنیادی
+اما
+بیاید
+ناشر
+داشتید،
+باید
+بروید
+الگو
+چهار
+اول
+مارس
+کتاب
+ایجاد
+بازدید
+توجه
+آنها
+پایه
+۲۰
+کشور
+ساختار
+سخ
+خوش‌آمدید
+مقالهٔ
+شده‌است
+سازمان
+فارسی‌نویسی
+بودن
+مرکزی
+باز
+آمریکا
+وب
+۱۶
+نویسنده
+کادر
+دسامبر
+صورتی
+۲۰۰۷
+۱۸
+۲۰۱۰،
+کند
+فنی
+تصمیم
+۱۳
+تهران
+وجود
+۱۷
+نشانی
+چطور
+چند
+کشف
+اوت
+دانشنامه‌ای
+فوتبال
+علمی
+۲۰۰۸،
+درج
+۲۰۰۲
+هستند
+بگیرید
+۲۱
+۲۰۱۱
+نوامبر
+مطالب
+آزمایش
+وی
+کاربران
+فیلم
+ها
+ماندن
+مقالات
+بپرسید
+حروف
+لذت
+جمعیت
+بحثم
+ببرید
+خوشتان
+مدک
+وابسته
+ویکی‌پدیانویس
+ویکی‌پدیانویسان
+۲۰۰۹،
+اسلام
+۲۲
+مسایل
+آوریل
+بنویسیم
+۱۹۹۹
+کاربری
+علامت
+واقع
+شوید
+اهمیت
+۲۳
+کلاس
+کردن
+ای
+آشنا
+باشید
+نگاهی
+کوچک
+نکنید
+وب‌گاه
+پروژه‌های
+کرده
+۲۸
+می‌توانید
+انتخاب
+مکنید
+بعد
+روز
+است،
+جستارهای
+شدن
+نوع
+نمونه‌های
+۲۴
+نفر
+دارید،
+بیندازید
+خودکار
+۲۰۰۶
+نوشته
+مطالعهٔ
+انبار
+عجله
+غفلت
+فهرست‌شده
+مشارکت
+اهل
+۲۵
+سوال
+محمد
+بوده
+۳۰
+بسیار
+بزرگ
+میراث
+میان
+زمان
+منابعی
+اثبات‌پذیری
+جلالی
+سیارک‌های
+دهستان
+مرکز
+انجام
+فوریه
+می‌کند
+۲۶
+نام‌های
+ما
+یعنی
+ایرانی
+ژوئن
+غیر
+پایان
+یونسکو
+حال
+پرحجم
+چپ
+می‌گویم
+داشته
+جمله
+پیام
+عمومی
+گردشگری
+قبل
+همین
+همچنین
+همان
+مالک
+سپاسگزارم
+سال‌های
+همه
+اندازه
+مربوط
+ویکی‌انبار
+قدر
+چون
+بیرون
+ویکی‌نویسی
+داده
+کسب
+دوم
+ویژه
+هیچ
+فرهنگ
+کسی
+بروید،
+تنها
+۲۰۰۳
+دارای
+ساخت
+افراد
+رتب
+تازه‌واردان،
+مه
+محلی
+بصب
+بین
+پتوپ
+مقاله‌ها
+نیازمند
+اسلامی
+۲۷
+بی
+مرگ
+علی
+۲۰۰۵
+متون
+مطلق
+سه
+می‌باشد
+نیاز
+شرکت
+۲۹
+۲۰۰۹
+باشگاه
+دلیل
+زندگی
+چاپ
+موجود
+۲۰۰۸
+نقل
+گروه
+۲۰۰۴
+انتهای
+دارند
+محتویات
+شاد
+موضوعات
+جستجوی
+۱۹۹۸
+مردم
+نشان
+موسیقی
+ویکی‌مدیا
+همراه
+ویکی‌گفتاورد
+تپه
+شورای
+دانشنامه
+ویکی‌واژه
+بدون
+مانند
+راه
+شهرهای
+فرهنگی
+سیاره
+ویکی‌نبشته
+ترجمه
+فراویکی
+حجم
+کنونی
+طبق
+ژانویهٔ
+بار
+اجرام
+روستای
+ویکی‌نَسک
+تغییر
+خوشامد
+سرعت
+۲۰۱۲،
+جنگ
+برابر
+محل
+سر
+سپس
+سیارک‌ها
+عربی
+بازیابی
+داشت
+بازی
+ماه
+می‌تواند
+رو
+کنید،
+ژانویه
+معرفی
+بنا
+مشترک
+چندین
+دوران
+ندارد
+جهان
+حقوق
+کنم
+بالا
+ضمن
+داد
+وبگاه
+البته
+آب
+قدیمی
+امکان
+جمهوری
+قسمت
+۰۹
+مفیدند
+پیدا
+وپ
+پروژه
+بن
+همکاری
+۰۸
+تغییرات
+كه
+منطقه
+معماری
+چم‌وخم
+معرفی‌شده
+کنند
+هزار
+عرض‌جغرافیایی
+طول‌جغرافیایی
+۰۷
+روی‌نقشه
+برخی
+آی‌پی
+آمار
+ویکی‌پدیای
+۲۰۱۰
+جای
+موضوع
+تمام
+گرفته
+شرقی
+فوریهٔ
+اخیر
+قمری
+متوسط
+دیگری
+غربی
+درگاه
+ربات
+راستی
+اولین
+۳۱
+باستانی
+امنیت
+چنین
+آلمان
+کم
+رسمی
+جهانی
+مطالعه
+بررسی
+ژوئیه
+فعالیت
+آغاز
+آذربایجان
+فکر
+اين
+الگوی
+تیم
+لطفا
+ژوئیهٔ
+صنایع
+درود
+نامه
+تلفن
+اقدام
+روستا
+ایشان
+می‌کنند
+فارس
+حتی
+تعداد
+دربارهٔ
+فعلی
+درست
+مدیران
+گفتگو
+حجت
+دستی
+ستاره
+بسیاری
+اند
+نقش
+کلیک
+بودند
+۰۶
+تولد
+کردم
+زادگان
+شاه
+متحده
+توضیح
+طول
+دوست
+ذکر
+رسیده
+مقاله‌ای
+قابل
+اضافه
+مسائل
+ایالات
+همهٔ
+اینترنتی
+نام‌گذاری
+سیاسی
+طور
+خیلی
+رضا
+روستاهای
+چپ‌چین
+تولید
+صفحه‌های
+برچسب
+خانه
+شکل
+دولت
+می‌توان
+شامل
+می‌نویسید
+یادتان
+موسسه
+جنوب
+نرود
+نشریه
+باشند
+۰۰
+آمد
+وارد
+فرانسه
+جوایز
+مجموعه
+قانون
+به‌عنوان
+متن
+۰۵
+جایزه
+خبری
+سید
+ویکی‌خبر
+گفته
+اساس
+سیاست‌های
+جنوبی
+سایت
+آری
+ممکن
+نمی
+بنویسید
+روسیه
+فیلم‌های
+مهٔ
+سوم
+تشکر
+جام
+۱۳۸۵
+حدود
+کامل
+عرض
+شمارهٔ
+قاجار
+ماني
+عکس
+اجازه
+تصحیح
+آرش
+علوم
+نظری
+جای‌های
+اشاره
+دانشنامهٔ
+گرفت
+کردند
+جان
+فرهنگی،
+مختلف
+بانی
+توضیحات
+ارتفاع
+موارد
+میلاد
+مثل
+مرمت
+ژورنال
+شعر
+محتوای
+بیش
+چرا
+شمال
+خواهر
+می‌کنم
+خم
+فصل
+شروع
+تشکیل
+چم
+سرشماری
+دهه
+مشکل
+ساخته
+زبان‌ها
+گونه‌های
+مدت
+مجموعه‌ای
+زیادی
+بهترین
+درباره
+موافق
+دیرینگی
+نتیجه
+هست
+آلبوم
+ادامه
+جهت
+خراسان
+شرح
+ایران‌شهر
+زیستی
+پیشرفته
+می‌دهد
+راهنماهای
+صفحه‌ی
+افغانستان
+هماهنگی
+قلعه
+اصفهان
+بالای
+جغرافیایی
+شخصی
+نسبت
+می‌شوند
+تصنيف
+مطرح
+عناوین
+بوده‌است
+۰۱
+۱۳۸۶
+زمین
+سازی
+حزب
+سی
+آن‌ها
+سرشناسی
+انقلاب
+مي
+واژه‌ها
+مهم
+سایر
+می‌آید،
+دکتر
+مساحت
+قطعنامه
+۰۴
+شدند
+مرد
+درگذشتگان
+پرونده‌های
+باعث
+نکاتی
+اعلام
+نامگذاری
+پروژه‌ای
+زبانه
+سیستم
+انتفاعی
+یادداشتی
+کتابچه
+پرسیدن
+۰۳
+چندرسانه‌ای
+قول‌ها
+هرکسی،
+ویکی‌گونه
+خوانندگانش
+کیلومتر
+سطح
+زمینه
+اهالی
+سؤال،
+حسین
+اصطلاح‌نامه
+موقت
+سندباد
+بود،
+تبدیل
+سبک
+بنویسیم؟
+روش
+میثم
+زمانی
+۱۳۸۷
+دسترسی
+کد
+انگلستان
+برنامه
+رنگ
+تحت
+هاروارد
+مدیر
+امیروبات
+جرم
+جلد
+وقتی
+گودال
+نگاره
+شمالی
+۰۲
+پاسخ
+آیا
+تر
+منتشر
+شوند
+انتشارات
+مخالف
+مسجد
+بایگانی
+هماهنگ‌کننده
+کپی
+متر
+مجلس
+۴۰
+دهید
+شاید
+آنجا
+گل
+کاربرهای
+ناسا
+دوستان
+جناب
+پیشنهاد
+ان
+دی
+یافت
+آسمانی
+۱۳۸۸
+هنوز
+نخستین
+مذهب
+نویسندگان
+زنده
+ایالت
+ماسه‌بازی
+احمد
+آنهاست
+کنار
+شبکه
+بازی‌های
+مشخص
+ژاپن
+نمود
+وقت
+کشورهای
+خواندن
+معروف
+اروپا
+اشتباه
+کرمان
+سن
+معرف
+پهلوی
+درجه
+سوی
+ام
+محیط
+بحثتان
+روزنامه
+گونه
+۱۹۹۷
+طرف
+کل
+داستان
+علت
+الگوهای
+آمریکایی
+تو
+آمده
+بین‌المللی
+داتک
+امیر
+انتشار
+قوانین
+شماره‌دار
+دادگان
+موفق
+رشته
+خاطر
+دارم
+خورشیدی
+حسن
+معنی
+زنان
+انتقال
+پی
+حکومت
+لازم
+به‌آفرید
+تپه‌های
+نام‌صفحه
+شابک
+زن
+قرن
+دهد
+عمل
+بازیگر
+تصاویر
+رئیس
+ممنون
+عزیز
+یاد
+گفت
+هفته
+دین
+رای
+وضعیت
+فرار
+درخواست
+سیاست
+سمت
+حالت
+پسر
+کوه
+پرچم
+طی
+ادبیات
+الله
+کلی
+کشف‌شده
+بازیابی‌شده
+غرب
+فرودگاه
+۱۳۹۰
+سپاس
+واژه
+توابع
+ابعاد
+کمربند
+دور
+مدرک
+مبدا
+مازندران
+کننده
+مدیریت
+دوستدار
+وجه
+مهدی
+نمایش
+هجری
+هنر
+ابتدا
+ده
+رسید
+اعضای
+انسان
+امام
+مثال
+دادن
+آخرین
+اسرائیل
+قول
+نمایید
+حضور
+رود
+خودتان
+زیاد
+جا
+توصیه
+مناطق
+عراق
+مطلب
+پرسش
+خان
+عضو
+حسام
+حداقل
+باستان
+ارائه
+۵۰
+مواد
+کمی
+خارج
+دما
+چین
+وزارت
+اوج
+خروج
+طبیعی
+پزشکی
+ستاره‌شناسی
+فراموش
+پایین
+کاری
+اکنون
+بعضی
+میانگین
+نشده
+هزاره
+نشر
+مهندسی
+شد،
+آباد
+خودم
+اسپانیا
+خاص
+دوران‌های
+۱۳۸۹
+جریان
+منظور
+طریق
+ترتیب
+بناهای
+بیان
+دارید
+روستایی
+سطحی
+شیخ
+نسخه
+حرکت
+بنده
+سده
+اجتماعی
+طراحی
+حرف
+خودروهای
+ویکی‌گزارش
+نو
+هند
+استاد
+به‌شما
+دوباره
+توان
+نظامی
+بلکه
+سری
+همسر
+هنری
+شیراز
+مفیدی
+جمع
+علم
+خانواده
+انتخابات
+آلمانی
+فاصله
+نیروی
+مرتبط
+نمونه
+پدیا
+فرمایید؛
+شناخته
+چگالی
+دیده
+معتبر
+مناسب
+قرآن
+میلیون
+واحد
+۴۵
+مهر
+تبریز
+هنگام
+گسترش
+طبقه‌بندی
+۱۹۹۶
+فلسفه
+کرمانشاه
+گردید
+گذشته
+دنیا
+زیرا
+قدرت
+مثلا
+ببینید
+لیگ
+دریافت
+انحراف
+نام‌رسمی
+می‌آید
+حمله
+گرانش
+توسعه
+افزایش
+چشم
+مکان
+عدد
+ابهام‌زدایی
+دانش
+موضوعی
+نزدیک
+شخص
+آنان
+دیگران
+بازیکنان
+آقای
+کاشف
+تلویزیونی
+زاده
+بسته
+جایی
+خدا
+حاضر
+شرق
+می‌شد
+حساب
+پدر
+داشتید
+نقض
+پیش‌شماره
+ایتالیا
+کاربرد
+سعی
+رفت
+برد
+‌بودن
+کاربردها
+تناوب
+۳۵
+معمولاً
+زبان‌های
+بهمن
+۳۲
+عباس
+حضیض
+پدیدآور
+انجمن
+فیزیک
+نگاه
+فعال
+نور
+نسخه‌ها
+ریاست
+هستم
+فلکی
+فرد
+مسیر
+اجازه‌نامه
+جامعه
+آلبدو
+مصر
+آنومالی
+کلمه
+نیم‌محور
+بریتانیا
+۱۹۹۵
+پر
+پاک
+۱۹۹۳
+بازیگران
+بخشی
+فرانسوی
+داخلی
+خبر
+سئوال
+محمود
+باشد،
+امروز
+کرده‌است
+ارتباط
+درصد
+تاریخچه
+ملل
+اصلاح
+معیارهای
+همچون
+طرح
+شده‌اند
+هدف
+عالی
+وقایع
+میدان
+محسوب
+حل
+باغ
+استان‌های
+خودش
+قطع
+ایران،
+۳۳
+۳۴
+اش
+دنبال
+شهری
+تعریف
+دانشکده
+انواع
+دار
+ورزشگاه
+نقشه
+کوتاه
+شمار
+مدرسه
+کمتر
+آرامگاه
+عصر
+عبارت
+بیست
+تن
+خرابکاری
+المپیک
+تیر
+می‌رود
+خیابان
+بازار
+نامزد
+میرزا
+داخل
+اندازه‌تصویر
+پایگاه
+رضوی
+سؤال
+۱۹۹۰
+الان
+گرامی
+نبود
+خوبی
+۳۷
+خارجی
+گیری
+آورد
+برچسب‌تصویر
+۴۸
+سیستان
+۱۹۹۴
+آزادی
+رشد
+نباید
+پرسشی
+۱۳۸۴
+حد
+۳۶
+ملیت
+رشدجمعیت
+تازه
+میانگین‌دما
+عدم
+نیروهای
+تراکم‌جمعیت
+سؤالی
+نام‌های‌قدیمی
+بنابراین
+ارتش
+شب
+داشتن
+علاوه
+ابن
+شمارروزهای‌یخبندان
+میانگین‌بارش‌سالانه
+پل
+تصویب
+میانه
+خرداد
+گیلان
+سنگ
+کنترل
+بهزاد
+کیفیت
+می‌‌نویسید
+۴۱
+درگذشت
+علیه
+گزارش
+شیعه
+خور
+۳۸
+جزیره
+ره‌آورد
+دسترس
+دستگاه
+نام‌محلی
+تگزاس
+جز
+همیشه
+۴۲
+اجرا
+کوشش
+پخش
+رد
+۴۶
+متحد
+اسفند
+وزیر
+خواننده
+بهبود
+اثبات
+سفید
+نظرخواهی
+شرایط
+جمله‌خوشامد
+ترکیه
+۴۴
+همدان
+قم
+۳۹
+می‌گیرد
+۴۳
+بلوچستان
+چیز
+دسته
+خوزستان
+گنو
+ترانه
+کدام
+خودرو
+۵۵
+۴۷
+باقی
+بندی
+۵۱
+بخوانید
+۱۹۹۲
+خواهند
+صد
+ناحیه
+۵۳
+کاهش
+۱۹۹۱
+میشود
+مذهبی
+۴۹
+ساختمان
+اولیه
+مقابل
+۵۲
+سبز
+وحید
+۵۷
+مشهور
+متوجه
+تهیه
+کافی
+آنچه
+ترک
+افزودن
+می‌شود،
+جدا
+۱۳۸۲
+چهارم
+تقسیم
+نژاد
+معنای
+کشاورزی
+صفوی
+براساس
+سیاه
+هایی
+آسیا
+تمامی
+تحقیق
+۱۹۶۰
+ساسانیان
+نوشتار
+رادیو
+۵۶
+۵۴
+اسم
+ارزش
+دهانه
+اقتصادی
+ابراهیم
+نخست
+فرزندان
+۵۹
+هاي
+شهرها
+دقیقه
+حالا
+دستور
+امور
+رابطه
+پارک
+جنبش
+دختر
+قالب
+بیماری
+نام‌های‌دیگر
+محوطه
+بازیکن
+کشته
+دارد،
+مشهد
+منتقل
+شهریور
+مرداد
+کیلومتری
+پرداخت
+۵۸
+تخصصی
+۲۰۱۲
+مرده
+دهیار
+صنعتی
+خدمت
+پشت
+فشار
+می‌کرد
+تلاش
+مدیاویکی
+تلویزیون
+میزان
+سال‌بنیاد
+قبلی
+انرژی
+بدست
+نظام
+حوزه
+پا
+بودم
+یزد
+هفت
+ازدواج
+است؟
+فضای
+نظریه
+اختلاف
+حمایت
+خواهم
+مجله
+رفته
+اجرای
+می‌گردد
+برتر
+متولد
+کره
+خاک
+برگزار
+سرزمین
+بدن
+کرده‌اید
+مسابقات
+اقتصاد
+ندارم
+بعدی
+قبول
+خلیج
+آخر
+کمیته
+فروردین
+مادر
+کارگردان
+می‌کنید
+سال‌ها
+کسانی
+مصرف
+جدول
+جشنواره
+آنرا
+دید
+فرزند
+عرب
+کاملا
+آمل
+پادشاه
+دیدگاه
+آذر
+اشکانیان
+سفر
+متفاوت
+وزن
+نیویورک
+داشتند
+بیشتری
+موزه
+یه
+می‌رسد
+خاصی
+دل
+دهستان‌های
+آنکه
+استقلال
+پنهان
+مجوز
+نوعی
+کردید
+لرستان
+جغرافیا
+ترکی
+محسن
+هوایی
+۱۹۸۱
+فروش
+مقام
+مقدار
+۱۶۱۵
+قزوین
+حالی
+عمر
+لزوم
+میل
+آبی
+دقت
+اصلا
+اطلاع
+رخ
+شکست
+اعمال
+اینترنت
+موتور
+دومین
+شهید
+تحقیقات
+تاسیس
+برخورد
+روم
+ماده
+محله
+لینک
+راست
+امروزه
+کرده‌اند
+بازگشت
+جواب
+پارس
+یونان
+رتبه
+شده،
+۱۳۸۱
+اساسی
+نقطه
+گردد
+موجب
+سخن
+تقویم
+نکته
+می‌دهند
+مستقل
+جامع
+اردیبهشت
+هستید
+سینما
+مدل
+کانادا
+گاه
+آورده
+حفظ
+ثابت
+احترام
+بوشهر
+مربع
+۱۹۸۸
+روابط
+سیمرغ
+درون
+زیرنویس
+کن
+نظرم
+ترکیب
+بهار
+بد
+پادشاهی
+دلار
+شیمی
+تعیین
+بابل
+نفت
+دولتی
+مدتی
+نظرات
+درستش
+کاتالوگ
+گاهشماری
+لحاظ
+ساده
+بخش‌های
+شوروی
+باب
+بی‌بی‌سی
+گرفتن
+دادم
+مثلاً
+گروه‌های
+ندارند
+کردستان
+حاصل
+شود،
+انسانی
+گرم
+روشن
+مسکن
+خون
+۱۳۸۰
+رسیدگی
+مفهوم
+خمینی
+گیاهان
+ساز
+آهنگ
+ترین
+هرمزگان
+۱۹۸۹
+صاحب
+کارهای
+اغلب
+عبدالله
+مشغول
+۱۰۰
+شناسی
+محمديان
+گفتم
+مختصات
+دهند
+یونانی
+رایانه‌ای
+یکم
+ستارگان
+کتاب‌های
+ایرانیان
+آوردن
+صنعت
+کند،
+صحبت
+فناوری
+نمی‌شود
+آینده
+واگردانی
+کتابخانه
+برجسته
+امر
+نقد
+مخصوص
+بزرگی
+آبان
+نتایج
+براي
+یافته
+لقب
+متاسفانه
+مالکیت
+مشاهده
+عرضه
+کارت
+گاهی
+شش
+دفاع
+مایکل
+اداره
+خبرگزاری
+دره
+مسئله
+صحیح
+ولایت
+گروهی
+رودخانه
+مقدس
+مراسم
+کشورها
+باد
+تاکنون
+خلاف
+علاقه
+ارومیه
+مرحله
+ورود
+۲۰۰۷،
+تکمیل
+موقعیت
+رویدادها
+تفاوت
+ایستگاه
+شیمیایی
+مگر
+ضد
+ژاپنی
+استاندارد
+دریای
+۱۹۸۰
+معاصر
+زندان
+غیرقابل
+عملیات
+دریایی
+خصوص
+برخوردار
+لندن
+شیوه
+آقا
+مشابه
+سخت
+خلاصه
+دفتر
+برنده
+سنت
+پاپ
+جلوگیری
+قدیم
+ورودی
+اسکار
+بطور
+چر
+بندر
+مرا
+راک
+نیشابور
+نیستند
+۱۵۱
+مشکلی
+آتش
+کشوری
+تابستانی
+امپراتوری
+بررسی‌های
+آن،
+اس
+میکنم
+پارسی
+تشخیص
+شاعر
+خدمات
+عهده
+نیمه
+مشکلات
+نیست،
+آشنایی
+بصورت
+تأسیس
+درمان
+ابزار
+آموزشی
+نوروز
+بروجرد
+تواند
+قتل
+تحصیل
+دیدم
+مدرس
+دانشگاه‌های
+جمهور
+محدود
+برج
+آبشار
+دانشجویان
+احتمال
+رفتار
+اعتماد
+اطراف
+هشدار
+همواره
+قطعنامه‌های
+محمدرضا
+پاریس
+ساله
+کالیفرنیا
+وسیله
+اصول
+درخت
+سالگی
+۱۹۷۷
+پیشه
+داریم
+شخصیت
+قصد
+نداشته
+می‌گوید
+جشن
+ویرایش‌های
+ادبی
+بهره
+سنتی
+فوق
+کنید؛
+تام
+بانک
+دهم
+استرالیا
+دقیق
+نامیده
+نفوس
+فراهم
+می‌توانند
+بدین
+اختیار
+چشمه
+دادند
+يا
+اردبیل
+پست
+خانوار
+قهرمانی
+منصور
+سرخ
+روسی
+۱۳۸۳
+شبیه
+بشر
+قرمز
+قطر
+سبب
+کشتی
+برده
+صدا
+یکسان
+شمسی
+مجدد
+اکثر
+جالب
+تک
+گلستان
+پنجم
+فراوان
+يك
+نرم‌افزار
+توهین
+اتحادیه
+عشق
+ظهیری
+گورستان
+بلژیک
+بکار
+رستم
+سرشناس
+‌ها
+هیئت
+علیا
+مقالاتی
+رباتیکی
+هنگامی
+لطف
+بختیاری
+روح
+ارجاع
+تقریبا
+۱۹۷۳
+سپاه
+‌های
+یکدیگر
+نموده
+رمان
+کرد،
+جنسی
+بزرگترین
+پیشرفت
+دعوت
+بقیه
+کلمات
+شهرت
+مرکزی،
+رایانه
+یمن
+تخت
+معادل
+صادق
+وسط
+خوانندگان
+تلفظ
+اتفاق
+امامزاده
+تحصیلات
+خانوادگی
+حقیقت
+خورشید
+نوری
+نقاط
+پایتخت
+بند
+گوگل
+مانده
+نزدیکی
+سعید
+امید
+نشود
+نر
+مسعود
+سلطان
+ادغام
+سفلی
+دریا
+لاتین
+اجماع
+خوانده
+سابق
+ریاضی
+درستی
+فضایی
+دلایل
+برندگان
+بعدها
+متعلق
+پیشین
+شدم
+هنرمند
+درس
+ذخیره
+کارگردانی
+نباشد
+دانقولا
+اون
+تابع
+مالی
+صدای
+بلند
+بارگذاری
+بخش‌ها
+اینگونه
+اواخر
+ریشه
+نشد
+کاخ
+ریز
+فرض
+قانونی
+برق
+جلوی
+کودکان
+نزد
+قاسم
+آهن
+زنجان
+نگارش
+شدت
+می‌گویند
+جایگزین
+جاده
+می‌کردند
+مفید
+زرشک
+لیست
+محور
+ویکیپدیا
+رایج
+مناسبت‌ها
+خلق
+مراکز
+ساری
+عامل
+نقاشی
+رسیدن
+کارشناسی
+۱۹۸۴
+زده
+رعایت
+انگلیس
+اطلاعاتی
+ورزشی
+مقایسه
+منبعی
+بازبینی
+حافظه
+حتما
+عربستان
+مستقیم
+گیرد
+الدین
+۱۹۸۲
+علیرضا
+تعدادی
+ورزش
+برادر
+گذاشته
+تهران،
+محصولات
+زندگینامه
+هوا
+۱۹۸۶
+۶۰
+کس
+پوشش
+حکم
+قهرمان
+خانه‌های
+حاج
+خواهش
+گردآفرید
+نوبل
+نرم
+رهبری
+خیر
+تجاری
+نوشت
+۱۹۸۵
+جوان
+واقعی
+نظیر
+سند
+سرانجام
+منجر
+اعداد
+فی
+واقعا
+نبرد
+مردان
+جغرافیای
+شدید
+روند
+ویرایشی
+دشت
+رده‌بندی
+پرحجم،
+گذاری
+افشار
+۱۹۷۸
+زدن
+سوئد
+خویش
+ماهی
+خالی
+درآمد
+آمریکای
+مسلمانان
+کجا
+می‌باشند
+طوری
+اید
+دکمهٔ
+احمدی
+درد
+۱۹۸۷
+شاعران
+گویا
+نداشت
+هـ
+سالهای
+ششم
+شیر
+دچار
+تاثیر
+زیست
+دینی
+سریال
+نماد
+راجع
+مطالعات
+مراجعه
+لحن
+خطر
+پرسپولیس
+حضرت
+مکتب
+دامنه
+بروید؛
+زیبا
+بافت
+مسلمان
+کامیار
+محافظت
+ناوبری
+نهایت
+کلیسای
+هشت
+تکرار
+پرورش
+توزیع
+معمولا
+وبلاگ
+طولانی
+تجربه
+ظاهر
+گسترده
+ممنوع
+پیروزی
+چهل
+گاز
+عکاسی
+کاملاً
+احساس
+همچنان
+تفسیر
+چک
+مترجم
+مشخصات
+اینها
+تایید
+۱۹۷۹
+توکیو
+ال
+سمنان
+۲۰۰
+رهبر
+بیت
+سومین
+خورده‌است
+پاکستان
+۹۰
+همانند
+فردی
+ملحق
+کامپیوتر
+سوریه
+پدرش
+اوایل
+پول
+سوره
+تقویم‌های
+آفریقا
+کتاب‌ها
+دنیای
+همانطور
+دودمان
+هدایت
+باره
+سلسله
+موسوی
+قضیه
+غیره
+صرف
+آید
+ايران
+پک
+طبقه
+حاکم
+داریوش
+گوناگون
+زهرا
+اسماعیل
+زمین‌لرزه
+اعتبار
+بعنوان
+مُروا
+توانست
+۱۳۷۹
+تدوین
+اهواز
+سبزوار
+جکسون
+نمایندگان
+مقاومت
+آی
+برداشت
+گشت
+قلم
+تنظیم
+نگاری
+هلند
+باور
+نهاد
+سینمای
+تمدن
+فرهنگستان
+کردی
+ویندوز
+سوئیس
+کانی
+نویسی
+ممتنع
+مانی
+پشتیبانی
+جو
+رده‌ها
+ساکن
+شهرک
+روزی
+صحنه
+اصطلاح
+تئاتر
+جستجو
+جلو
+فردا
+جیمز
+کی
+هرگز
+چیست؟
+حمل
+توصیف
+گیتار
+ری
+والدین
+۱۹۷۶
+حفاظت
+رشت
+سابقه
+کودک
+کنون
+فعالیت‌های
+عوض
+اعتراض
+نسل
+دریاچه
+مرز
+باشگاه‌های
+کهگیلویه
+میکند
+دادگاه
+تصویری
+خانم
+مخالفت
+نصب
+آل
+افرادی
+چاه
+نماینده
+نگه
+عملکرد
+جدیدی
+۱۹۷۰
+مهمترین
+آمده‌است
+محمدعلی
+بدهید
+اتحاد
+شرکت‌های
+موج
+رم
+کشیده
+تحلیل
+نظارت
+تابلوی
+شهرداری
+محصول
+متعدد
+نماید
+قوم
+مصطفی
+جزایر
+گرمی
+عقب
+صلح
+شعار
+ارسال
+جی
+نوشته‌های
+غلط
+۱۹۷۱
+سازنده
+نکرده
+مواردی
+جوانان
+حمام
+دورهٔ
+تبریک
+بگذارید
+دانشگاهی
+مس
+ماند
+خداوند
+مهاجرت
+ضبط
+ست
+احتمالا
+لبنان
+دوربین
+خودشان
+عبور
+ارشد
+بنام
+فرمان
+عبارتند
+مطابق
+خرم‌آباد
+بالاتر
+سد
+تقریباً
+اکبر
+دیدن
+موفقیت
+مدرن
+نگهداری
+۷۰
+عوامل
+پای
+جایگاه
+۸۰
+زادروز
+پرواز
+خلیفه
+هفتم
+ماشین
+هرچند
+هسته‌ای
+عناصر
+اسناد
+گنبد
+لا
+نهایی
+تدریس
+طلایی
+زابل
+چندان
+اروپایی
+ظاهری
+صفر
+اول،
+اشعار
+دبیرستان
+معلوم
+برنامه‌های
+نخواهد
+زد
+بیفزایید
+خصوصی
+وظیفه
+ادعا
+عزیزی
+عمده
+انتظار
+آن‌لاین
+قبلا
+مبارزه
+هستند،
+خسته
+فرصت
+رفتن
+مشارکت‌ها
+گرامی،
+سراسر
+۱۹۸۳
+پیروز
+گویش
+رفع
+جزو
+گفتاورد
+متال
+مکزیک
+۱۳۵۷
+امپراتور
+اطلس
+اسپانیایی
+پنجاه
+شاپا
+بیمارستان
+پیامبر
+بستک
+می‌کنیم
+اشکال
+تقسیمات
+الکتریکی
+درک
+سلطنت
+لباس
+دهنده
+نشست
+اعدام
+اقوام
+شاخه
+سلام،
+الگوریتم
+چپچین
+شان
+خواست
+مدال
+امارات
+جبهه
+باشم
+مطبوعات
+مستعار
+نیازی
+عادی
+چینی
+افتخار
+کهن
+نا
+مثبت
+شخصیت‌های
+خطوط
+ویلیام
+سلطنتی
+منطقی
+اطمینان
+جعفر
+سقوط
+روزهای
+گرفته‌است
+طبیعت
+باشیم
+رده‌های
+ترتیب‌پیش‌فرض
+شبه
+موافقم
+یهودیان
+تربیت
+دیوید
+معاون
+پرندگان
+ملت
+دیوان
+تی
+پلیس
+ملک
+نيز
+هنرمندان
+عین
+تماس
+حرفه‌ای
+آستانه
+بماند
+واکنش
+زحمت
+عمان
+حافظ
+نیم
+منفی
+آسیای
+تابستان
+جدی
+قابلیت
+ساختن
+آسیایی
+رجوع
+شهرستان‌های
+معین
+نیستم
+ناشی
+تهیه‌کننده
+داشته‌است
+دانشمندان
+صبح
+اعتقاد
+مبارک
+سورنا
+اساطیر
+اصلاً
+تذکر
+خطی
+کاربردی
+داشتم
+آدم
+کتابی
+مختلفی
+کاربرانی
+سرباز
+جذب
+متغیر
+وضع
+روزبه
+مجازی
+گذاشت
+بابت
+اعلانات
+مهمی
+فلان
+آماده
+مصاحبه
+باتجربه‌تر
+رقص
+کلاسیک
+گیاه
+سامانه
+مجبور
+نحوه
+نبوده
+نفوذ
+متری
+کانال
+حیات
+گفتمان
+جلسه
+ارادتمند
+درفش
+حومه
+تصور
+خاندان
+بهرام
+لحظه
+برزیل
+یهودی
+دهخدا
+ایتالیایی
+رسانه
+۱۹۷۵
+مسابقه
+خواستم
+کابل
+نی
+اوکراین
+موسی
+شما،
+بگیرد
+زرد
+هوای
+فلسطین
+اهداف
+است؛
+ولسوالی
+غار
+بنای
+نوشتارهای
+مربوطه
+اخبار
+بودند،
+مهم‌ترین
+سینمایی
+پیمان
+۸۸
+همزمان
+ها،
+احتمالاً
+آسمان
+شهرک‌های
+ابتدای
+ندهید
+بوجود
+آیدا
+جانوران
+سده‌های
+بازداشت
+هسته
+یادداشت
+ایلام
+نامی
+مجموع
+هنرهای
+می‌دانند
+ادعای
+سرویس
+بگویم
+ظهور
+هزینه
+کاویانی
+الگوها
+ضروری
+آرام
+حذفی
+اقیانوس
+یی
+امتیاز
+زمینی
+آدرس
+باشه
+امکانات
+بیشترین
+طراح
+نواحی
+مطالبی
+مقالات،
+بخاطر
+لی
+آفتاب
+بفرمایید
+دقیقا
+هشتم
+توانایی
+آیت‌الله
+مسیحیت
+تبلیغات
+محوطه‌های
+بارها
+ته
+سنچولی
+يک
+الف
+متصل
+ساسانی
+بویراحمد
+سروش
+نظرتان
+ربطی
+روایت
+بروز
+دیگه
+پژوهشی
+زبانی
+۱۳۷۸
+ثانیه
+برگزاری
+تبلیغ
+شاهنامه
+نزاکت
+قوی
+خواجه
+پوست
+پژوهش
+شروین
+سنی
+میباشد
+سرد
+بگویید
+شکایت
+بنی
+صدر
+مطلبی
+اسید
+کلید
+خسرو
+گذشت
+طلا
+شیرازی
+اي
+شناسایی
+تأثیر
+شیرین
+می‌کند،
+رأی
+فردوسی
+اگرچه
+چهارمین
+نمی‌کند
+زاپاس
+خشک
+جنگی
+برداری
+قادر
+بومی
+بنابر
+ديگر
+تقدیم
+حاشیه
+نگاره‌های
+۱۹۷۲
+اختصاص
+یونایتد
+بردن
+اندیشه
+حتماً
+بودجه
+داشت،
+افزوده
+۱۹۷۴
+بیرجند
+عضویت
+مستند
+بحثی
+الکترونیک
+امروزی
+بیرونی
+فتح
+معمول
+واژگان
+ادب
+نمی‌توان
+مرتضی
+اتصال
+مخالفان
+گویند
+ناقص
+سفارت
+۱۳۷۷
+المللی
+قسمتی
+چنان
+مدفن
+فضا
+گرچه
+ويکيپديا
+آمدن
+زیبایی
+نوشتم
+عهد
+رای‌گیری
+سرمایه
+نامعلوم
+ردیف
+تجارت
+نیک
+ایل
+یافتن
+اظهار
+گرد
+مایل
+اعراب
+قیمت
+چی
+مقدمه
+خرید
+عمق
+گمان
+هری
+معتقد
+داده‌است
+یوسف
+مردتنها
+بزرگ‌ترین
+فراوانی
+مرور
+جزء
+ناصر
+موشک
+رومانی
+دانست
+نادرست
+خود،
+فایل
+تلقی
+مشاهیر
+بوده‌اند
+آواز
+ضمنا
+بشود
+عثمانی
+مبنای
+قلب
+گوش
+جمعه
+آیت
+ویرایشات
+هاشمی
+دارند،
+استادان
+فرق
+همگی
+پرتغال
+ذهن
+پیر
+زیست‌شناسی
+پرنده
+بتواند
+ارمنستان
+اتریش
+اندکی
+آیین
+اتاق
+قطعه
+شناخت
+تغییری
+۱۹۶۸
+عبری
+معیار
+هفتاد
+روش‌های
+نکردن
+فاقد
+آیه
+دم
+عید
+مکانیک
+تک‌آهنگ
+نوبت
+دیوار
+گشتن
+درمانی
+مطمئن
+نصف‌النهار
+جنس
+تیره
+منظومه
+بایستی
+ریاضیات
+مهندس
+رییس
+بارگذار
+هواپیما
+میشه
+آرژانتین
+کلا
+کریم
+شاهد
+گر
+سنگی
+مسئول
+نشانه
+فیلمبرداری
+نوکیا
+جمشید
+تغییراتی
+کتب
+کرج
+استناد
+شریف
+ایرلند
+اف
+نسخهٔ
+چهره
+نوید
+کنگره
+منچستر
+رابرت
+نباشید
+پرویز
+مى
+نماز
+کمال
+گونه‌ای
+ژان
+دلیلی
+داری
+عالم
+اسب
+حمید
+قرارداد
+پیشینه
+قره
+خروجی
+کمونیست
+قاسمیان
+می‌گیرند
+شصت
+زمستان
+کلمبیا
+راهی
+محدوده
+نام‌ها
+میر
+لینوکس
+میلادی،
+بهداشت
+اگه
+سدهٔ
+۵۰۰
+بجای
+مغز
+پوستر
+حاوی
+لغت
+رسانی
+لوگو
+مسیح
+فرزاد
+فرمول
+مؤسسه
+مفصل
+پدید
+درام
+اردشیر
+آفریقای
+خرابکار
+تامین
+داره
+اتمی
+بزرگان
+محکوم
+نجات
+یادبودهای
+ریچارد
+رومی
+مدار
+تخریب
+بدانید
+درگیری
+بیستم
+افتاد
+محترم
+خودروها
+نوین
+مطابقت
+تاجیکستان
+نقش‌های
+افزار
+مراجع
+اتومبیل‌های
+عزیز،
+ضعیف
+امضاء
+بیگانه
+فرا
+اکثریت
+هرات
+می‌یابد
+پنجمین
+میکنند
+کنندگان
+فعلا
+۸۵
+نکات
+ارتباطات
+خواهید
+مجمع
+کنی
+یابد
+منطق
+دیدار
+دویست
+دوستانه
+آوری
+آلبوم‌های
+اتهام
+بینی
+مسیحی
+گری
+آنلاین
+ویژگی
+ادوارد
+امنیتی
+برایتان
+كرد
+دیگر،
+عام
+اصرار
+بودید
+تبلیغاتی
+حاجی
+هرچه
+۱۹۶۴
+انتقاد
+برسد
+شک
+توانید
+ویژگی‌های
+خوی
+۶۴
+زادگاه
+مساله
+فیزیکی
+هخامنشی
+غذایی
+نمی‌دانم
+سامسونگ
+گرفتند
+تاج
+موقع
+۱۹۶۹
+فاطمه
+سخنرانی
+سختی
+استدلال
+۱۳۷۶
+شهردار
+ار
+سلیمان
+متهم
+مذکور
+عملی
+چندی
+پدیای
+صادر
+منتظر
+ضرب
+تیم‌های
+تل
+حسینی
+گیر
+سراب
+تیرداد
+ویکی‌سازی
+تان
+مشروطه
+کوچکی
+مردمان
+ویکی‌پدیا،
+مجاز
+محاسبه
+بزنید
+جنگل
+مجموعه‌های
+واقعیت
+سان
+قومی
+صفحه‌ها
+قطب
+تالار
+خواب
+تاکید
+گاه‌شماری
+امین
+لذا
+آسیب
+هیات
+قد
+میلیارد
+کوچولو
+برقرار
+بالایی
+شیعیان
+قاضی
+برگرفته
+عنصر
+معانی
+ارتباطی
+شبکه‌های
+درود،
+۳۰۰
+مراحل
+لهستان
+معمولی
+نوار
+محس
+۸۹
+قبیل
+سیر
+دهیم
+شاخص
+عیسی
+ترور
+دمای
+تکامل
+کبیر
+درگیر
+سونی
+یاری
+۱۹۵۰
+آگاهی
+نیوز
+پیوست
+رچ
+خدای
+کودکی
+مرتب
+رژیم
+روبات
+ابتدایی
+میتوان
+هشتاد
+زادهٔ
+کشت
+بازسازی
+وسایل
+بتوان
+مجارستان
+پیاده
+میان‌ویکی
+فرمانده
+۸۷
+تهدید
+ویک
+محرم
+نهم
+احمدی‌نژاد
+۶۵
+خورد
+رسول
+تمیزکاری
+بندانگشتی
+گیاهی
+سیاست‌ها
+این‌که
+کلیه
+بهشت
+هندی
+مشکوک
+فکری
+عقیده
+اشغال
+نویس
+ستون
+خارجه
+۱۳۸۶،
+۸۶
+نمی‌گیرد
+کارخانه
+دانشجو
+پیوسته
+خاطرات
+پادشاهان
+۱۹۶۷
+غذا
+زرتشت
+سود
+خوشحال
+رساند
+آر
+فیلمی
+می‌پردازد
+تری
+لایه
+سپهرنوش
+ظاهرا
+مصدق
+کویت
+مال
+احداث
+کانون
+مد
+فرماندهی
+مرحوم
+مواجه
+۱۳۹۰،
+بايد
+افتاده
+دوم،
+گردیده
+کارل
+وگرنه
+ندارد،
+ترجمهٔ
+ساحل
+جم
+طرفی
+نگهدار
+شرط
+روان
+آبتین
+جوانبخت
+سازهای
+الکترونیکی
+پور
+نود
+جمعی
+راحتی
+حیوانات
+داروهای
+دستگیر
+بابک
+حداکثر
+دانش‌آموختگان
+حلقه
+راستای
+اراک
+نادر
+اثری
+زبانهای
+برندارید
+رشته‌های
+بستن
+برگردان
+آبشارها
+ریزی
+مراغه
+دروازه
+پذیرش
+نمایی
+مدیریتی
+منصفانه
+واژهٔ
+جانب
+متعددی
+رسد
+گوید
+شغل
+زاهدان
+نمای
+رواج
+واضح
+عده‌ای
+می‌مانند
+ایوان
+چوب
+نکند
+فلسفی
+معنا
+نمی‌تواند
+خورده
+سو
+باند
+ماهواره
+مرغ
+دشمن
+کوه‌های
+سرطان
+دبی
+پرداخته
+ایکس
+آشکار
+کاشان
+بغداد
+ببخشید
+ششمین
+منظورم
+جلب
+دیر
+مـهـران
+زند
+مناسبی
+خانگی
+تجزیه
+بالغ
+می‌داند
+علامه
+جولای
+برگ
+سیستم‌های
+سیستم‌عامل
+کاوه
+۷۵
+دراپر
+مدارس
+ظاهراً
+رنگی
+دهه‌ها
+چیست
+تظاهرات
+مربی
+سازمان‌های
+برپایه
+متشکرم
+دوازده
+ایراد
+گیتاشناسی
+می‌برد
+اسامی
+او،
+دارد؟
+بورکینافاسو
+تجهیزات
+شاهزاده
+دربار
+دانم
+زاویه
+قاره
+رهبران
+سرود
+ابهام
+۱۳۷۵
+ایمیل
+پیغام
+فرآیند
+دالبا
+پستی
+ظرفیت
+بشه
+سیتی
+هستیم
+پرتاب
+کمدی
+توی
+فجر
+این‌جا
+گرگان
+می‌دانم
+جواد
+شاتل
+خطاب
+الهی
+گرایش
+ملا
+دانشمند
+فیلتر
+نسبی
+شوم
+داستان‌های
+نمایشگاه
+تربت
+ممنونم
+آگوست
+پایدار
+مشارکت‌هایتان
+منطقه‌ای
+تنگ
+مقیاس
+شریک
+جزئی
+هویت
+بدهد
+نوشتهٔ
+بابا
+ادیان
+۱۹۶۵
+جورج
+هفتمین
+تصرف
+آهنگساز
+پاورقی
+دلیلتان
+حس
+کوچه
+رقابت
+نمایند
+رها
+مقامات
+منطقهٔ
+قلعه‌های
+فن
+مادرش
+متخصص
+تکنولوژی
+سالی
+کیفیتی
+زمین‌شناسی
+می‌دهم
+مک
+کشتار
+سنگین
+می‌نویسد
+نکردم
+ید
+پرو
+بدان
+باران
+دخالت
+درختان
+جوانی
+آنگاه
+حسب
+حرفه
+سندی
+چگونگی
+تبار
+توافق
+کتابهای
+اطلاق
+نامناسب
+مایکروسافت
+۱۹۶۶
+ارشاد
+فردوس
+صوتی
+روزگار
+نمودند
+سگ
+دارو
+خاورمیانه
+معلم
+گره
+ون
+سوخت
+مترو
+آموخت
+نشده‌است
+شماست
+هتل
+حدیث
+نداریم
+پیدایش
+۱۳۷۰
+میانی
+کنند،
+عقاید
+پیچیده
+قهوه
+فرشته
+نحوهٔ
+عجیب
+جداگانه
+هشتمین
+جزئیات
+همشهری
+مبنی
+کاتولیک
+اصفهانی
+حملات
+جاری
+پویان
+انگلیسی،
+برخلاف
+نيست
+اشخاص
+مجید
+سیمای
+کانی‌های
+تغذیه
+مربیگری
+برنامه‌نویسی
+‌پدیا
+فدراسیون
+اجرایی
+سیصد
+احمدآباد
+می‌خواهید
+جنگ‌های
+پیگیری
+حوادث
+اخیراً
+دیجیتال
+تکیه
+مریم
+الی
+۱۹۴۸
+كند
+عده
+اقدامات
+شعاع
+تخیلی
+ماه‌های
+۶۶
+آزمایشی
+شده‌است،
+واژه‌های
+دشتی
+موافقت
+قهرمانان
+جلال
+اچ‌دی
+الفبای
+نفس
+پایانی
+پانصد
+برایش
+ترجیح
+خواند
+سلول
+عصبی
+کوخرد
+آب‌انبار
+۶۲
+مفاهیم
+شنبه
+بالاخره
+دانسته
+هواپیمای
+نهمین
+ایالتی
+مو
+فارغ
+پلی
+دروغ
+اداری
+استقبال
+مسئولیت
+داده‌اند
+فدرال
+ترانه‌های
+نوازندگان
+چای
+دههٔ
+تراکم
+فهرست‌های
+مردی
+زمرہ
+گورستان‌های
+سوالات
+عباسی
+سردار
+محک
+ترکیبی
+رقم
+سعودی
+نرم‌افزارهای
+بازرگانی
+برلین
+نروژ
+مارتین
+فوت
+دیدنی
+کنفرانس
+فارسی،
+اهر
+نجف
+پذیرفته
+اینست
+ملکه
+سرخط
+كرده
+زنی
+قلمرو
+بخصوص
+امی
+بهائی
+نقاش
+کازرون
+تار
+گرفته،
+نظم
+۷۲
+خودداری
+شمس
+صفحه‌ای
+بیمار
+واقعه
+هادی
+۸۴
+خاتمی
+بارسلونا
+سرچشمه
+زنز
+برچسب‌های
+منتخب
+بحرین
+واشنگتن
+پاتر
+کرده‌ام
+شاهین
+زرین
+مارک
+توپ
+وقوع
+حدی
+آذری
+شاگردان
+معبد
+آرمان
+۱۹۶۲
+بیماری‌های
+بچه
+فعالان
+کوروش
+دارویی
+اوقات
+اوست
+می‌کنند،
+قضاوت
+ین
+دست‌اول
+فریدون
+تئوری
+نمی‌توانید
+دوستی
+حقیقی
+زندانی
+مقطع
+راستش
+۱۹۶۳
+شاپور
+۱۹۵۶
+آکادمی
+بازنویسی
+ارمنی
+۱۹۶۱
+مهران
+مردمی
+ندارید
+گذاشتن
+کوتاهی
+فقه
+تنکابن
+درجه‌بندی
+ژنرال
+مایع
+طرفداران
+مدارک
+بدلیل
+پیشنهادی
+باشند،
+ذرات
+دانشجویی
+نگارخانه
+نیت
+کیلوگرم
+سردشت
+ایده
+تسلیم
+برادران
+هزاران
+حادثه
+مرتضا
+خواستار
+نهضت
+نرسی
+آمیز
+استودیو
+قدمت
+مجموعهٔ
+مغناطیسی
+قطعات
+عمران
+توجهی
+فیلم‌ها
+كار
+۶۳
+رسم
+درب
+مبتنی
+امواج
+تمایل
+احزاب
+روحانی
+اردن
+۶۱
+عمارت
+می‌دانید
+گفتار
+دزفول
+داوری
+کا
+حقوقی
+زمستانی
+فولاد
+امریکا
+مزرعه
+بوده،
+رساله
+رامین
+جراحی
+محقق
+ابزارهای
+ویکی‌
+پزشک
+قبلاً
+ضلع
+سرور
+مجاهدین
+اخلاق
+گراف
+مانع
+مشارکت‌کنندگان
+قشلاق
+نوازنده
+پرده
+۱۹۵۳
+شیروان
+کاظم
+اریکسون
+طیف
+مسکو
+۱۹۳۰
+۶۸
+مقابله
+لوله
+علی‌آباد
+واقعاً
+معدنی
+طباطبایی
+شاهان
+تاريخ
+ودر
+ماهان
+یوشیمیتسو
+۱۹۴۵
+نمونه‌هایی
+البرز
+چهارمحال
+مالزی
+۱۹۵۸
+خودرویی
+بیاورید
+آبادی
+مخابرات
+می‌دهید
+رودبار
+جور
+یحیی
+كتاب
+وین
+می‌داد
+غلامرضا
+طایفه
+سطر
+خواهیم
+جانشین
+اقامت
+توده
+مشارکت‌های
+برود
+جویا
+می‌روند
+نتیجهٔ
+اختیاری
+اساتید
+آگاه
+ساوه
+قدس
+ناخالص
+چرخ
+پردازش
+خرم
+به‌
+کاربردهای
+فیلسوفان
+طب
+زمانه
+وحدت
+افغان
+منوچهر
+طرز
+بوسیله
+مدیری
+اخذ
+اصلاحات
+فرهاد
+۱۳۷۳
+بایرن
+تور
+۸۲
+بست
+راحت
+تقلید
+لهجه
+قرون
+افسانه
+۶۷
+منزل
+۰۰۰
+رکوردز
+تأثیرات
+افتتاح
+بزرگتر
+هندوستان
+نقره
+بهشتی
+پذیر
+عظیم
+سیم
+خواص
+اعتراضات
+سخنان
+رزیدنت
+مسجدهای
+هرگونه
+می‌آورد
+این‌ها
+دقیقاً
+بسکتبال
+صوت
+بوئین
+۱۲۰
+۱۵۰
+شور
+زودی
+توانند
+سربازان
+رویداد
+خب
+بنیان
+چلسی
+زیبای
+شورش
+خامنه‌ای
+برایم
+درخواستی
+روان‌شناسی
+جسم
+ممنوعیت
+اهورا
+چقدر
+ابوالحسن
+سالن
+صحت
+می‌خواهد
+۹۶۴
+نرخ
+اختلال
+رویدادهای
+خراب
+تونی
+دایره
+دبیر
+۸۱
+۱۳۶۸
+دانشگاه‌ها
+تقویت
+زلزله
+دهانه‌های
+کوهستانی
+محض
+۱۹۵۴
+نبودن
+بين
+کارکنان
+جملات
+خاکستری
+دادید
+فرایند
+دارا
+وفيات
+چهارصد
+خصوصیات
+چارلز
+گفتند
+ستاد
+۱۰۰۰
+پیتر
+انگلیسی‌زبان
+مجتمع
+وسعت
+می‌شدند
+۱۳۷۴
+نیروگاه
+گذار
+قوچان
+تحصیلی
+دهی
+میلان
+نمی‌کنم
+فرم
+پستانداران
+گردن
+۱۳۷۲
+۱۹۴۰
+جناح
+شوشتر
+پذیری
+لیبی
+اسلامی،
+بحث‌های
+سوء
+همسرش
+قفل
+اسکندر
+تحلیلی
+تحمل
+فعلاً
+۱۳۵۴
+میوه
+مصنوعی
+ارزیابی
+روزانه
+مدعی
+دانمارک
+فرستاده
+شناسه
+صبر
+شطرنج
+گفتید
+وسیع
+گام
+گوشت
+کرده،
+رصد
+کوهدشت
+اینطور
+نوجوانی
+ملت‌های
+محمدی
+۶۹
+لشکر
+بزرگراه
+۱۹۵۲
+پاینده
+۴۰۰
+جانبی
+ایول
+تجدید
+نیست؟
+حامد
+نشریات
+توماس
+مجازات
+قیام
+گپ
+سینا
+۷۸
+بس
+وظایف
+کوهستان
+اینجاست
+میدهد
+کارها
+سالها
+یادبود
+آبادان
+طبس
+خوردن
+روزه
+مسکونی
+اعظم
+دموکرات
+خشونت
+۸۳
+هوشنگ
+تخصص
+سیما
+منظر
+علمیه
+سالم
+پیکسل
+کمکی
+خواسته
+ایرج
+مدنی
+گفتن
+آذربایجانی
+ره
+اتمام
+آلاباما
+۱۹۲۰
+ابی
+بام
+فقیه
+کیلومترمربع
+عوارض
+۱۳۵۰
+ترس
+بازگردانی
+سعدی
+موثر
+کلیبر
+انقلابی
+وبسایت
+روانی
+موردی
+دختران
+روس
+بم
+پاک‌کن
+داشته‌اند
+یوتی‌سی
+صدها
+پانویس‌ها
+نفتی
+ورزقان
+کمبود
+نابود
+فرانک
+دان
+۷۶
+جرج
+جدایی
+کیهان
+نامش
+تبریزی
+کتیبه
+حکومتی
+قسمت‌های
+صرفا
+۷۱
+اندازی
+قدم
+منحصر
+عموم
+پهنای
+پدیده
+روغن
+رسانه‌های
+اطلاعات،
+سایت‌ها
+اکران
+سلامت
+بالاترین
+پیروی
+۱۹۵۱
+مصداق
+۷۳
+شکار
+مباحث
+پوویا
+فاصلهٔ
+فاز
+۷۷
+حالیکه
+شهریار
+۱۹۵۷
+درخشان
+آن‌جا
+تنهایی
+نکرد
+عدالت
+می‌نماید
+مقبره
+سانسور
+داده‌ها
+شاهرود
+تخمین
+نشست‌های
+۱۹۳۶
+جین
+روبرو
+پس‌زمینه
+نیرو
+اخلاقی
+داستانی
+سینه
+شاهنشاهی
+مولانا
+گاو
+استخوان
+گرگ
+دکتری
+اند،
+کشف‌های
+سنندج
+۷۴
+ساحلی
+برهان
+پیش‌نمایش
+کردم،
+دوره‌های
+۱۳۵۶
+آغازین
+سالانه
+بستگی
+تخم
+۹۹
+سیگنال
+ویکی‌پروژهٔ
+ناقض
+خودمان
+کرد؟
+ویرایشگران
+داوران
+برداشته
+۱۳۷۱
+یکمین
+ریزشگاه
+سوار
+سلاح
+شایسته
+سفیدپر
+غزه
+ترکیبات
+لاله
+اولی
+گذر
+جک
+ذیل
+دراز
+۹۵
+پان
+درصورت
+ایرانشهر
+عرصه
+پیروان
+پردازنده
+زایش
+مدینه
+انفجار
+کمپانی
+فرشتهٔ
+واحدهای
+حرارت
+بعداً
+۱۹۴۹
+همینطور
+استخراج
+ملاقات
+فرو
+پارامتر
+منتقدان
+آزمایشگاه
+نوشته‌شده
+اصطلاحات
+بتوانند
+مشتری
+متوقف
+اجباری
+مسلح
+سلجوقیان
+کندی
+اسکاتلند
+فیلسوف
+می‌سازد
+زود
+۷۹
+رجبی
+هفتصد
+تقی
+معدن
+مار
+فراز
+ایالت‌های
+ایمان
+ابراز
+ممسنی
+رادیویی
+سرکوب
+پیوندها
+۱۹۵۹
+توزیع‌کننده
+کشید
+بال
+۱۳۵۸
+۱۹۵۵
+شفاف
+کلام
+یکبار
+رصدخانه
+موسوم
+صلاح
+اخیرتان
+کالج
+واز
+شیکاگو
+جنبه
+۱۳۶۹
+عاشق
+کک
+خنثی
+امیرکبیر
+آنقدر
+زبان‌شناسی
+مشاور
+نمایشگر
+دا
+مِنْ
+آرزوی
+آئین
+می‌آیند
+شکلی
+۱۳۶۰
+سقف
+فرامرز
+بحث‌ها
+همت
+خیام
+تصادفی
+میتواند
+تجاوز
+روح‌الله
+روستاها
+هواپیمایی
+گلدن
+منظورتان
+کرمانی
+قله
+ضربه
+ساکنان
+اورشلیم
+مجدد،
+ویکی‌پ
+معتقدند
+۱۹۳۸
+محیطی
+جعفری
+خطا
+ویروس
+نگار
+سال‌ف
+ابراهیمی
+هشتصد
+نکنم
+ذوب
+رایت
+هاست
+متنی
+نان
+اضافی
+باله
+اصغر
+تایلند
+را،
+پیانو
+سکونت
+تالیف
+اختصاصی
+بهتری
+ترابری
+چو
+دیو
+زندگی‌نامه
+شیشه
+قلبی
+تحریک
+کیش
+ستاره‌ای
+اختراع
+برآورد
+سزار
+دهستانی
+مجسمه
+برطرف
+سپرده
+پارلمان
+رمز
+درسی
+سپاهان
+منصوب
+۱۹۴۱
+پروانه
+جمع‌بندی
+فعل
+کربن
+دژ
+تفکیک
+قفقاز
+همراهی
+عبدالحسین
+بسيار
+مواليد
+۲۵۰
+پیرو
+معاونت
+پیرانشهر
+۹۱
+معنوی
+کاروانسرای
+دفن
+سیزدهم
+ند
+اینقدر
+هخامنشیان
+دستگیری
+گل‌های
+می‌خواهم
+گیرند
+متفاوتی
+شیلی
+مراکش
+کنسرت
+بدهم
+تومان
+کهکشان
+اوضاع
+اندونزی
+چنانچه
+جایزهٔ
+بدهند
+کروبی
+سکه
+گرفته‌اند
+می‌شوم
+تضاد
+ملایر
+شیطان
+سهم
+اخطار
+حرم
+موافق،
+هیتلر
+واسطه
+ناظر
+نمودار
+بگوید
+تیمور
+قصر
+مکانی
+فرودگاه‌های
+۱۹۴۶
+جهاد
+مقداری
+داد،
+اندک
+دکترای
+فیلیپ
+۱۹۳۳
+کارگران
+آماری
+۹۸
+تست
+هستی
+میزبان
+تقاضای
+اوبلاست
+شیوه‌نامهٔ
+من،
+محتوا
+مربیان
+دیسک
+معتبری
+زدایی
+صعود
+حکمت
+مخفی
+زمینهٔ
+دهان
+گو
+رمضان
+ششصد
+هم‌اکنون
+شکسته
+‌است
+حرفی
+۹۶
+هواداران
+تبعید
+نشین
+توجیه
+مکه
+جاذبه‌های
+منافع
+بیفزایید،
+عرفان
+کشی
+آمریکایی‌های
+عقل
+وفات
+سیب
+پربارتر
+کنه
+تألیف
+بنیانگذار
+دموکراسی
+نهصد
+یادم
+سراسری
+تفکر
+لارستان
+برگزیدگی
+رباط
+لس
+حساس
+حبیب
+ویکی‌پدی
+فرود
+همکاران
+تشویق
+تحویل
+باقری
+داده‌های
+معرض
+گلوب
+کلیسا
+ویکی‌پد
+کف
+۱۳۶۷
+امضای
+بخواهیم
+خالد
+فلزی
+نظرخواهی‌ها
+آیات
+درگذشته
+شباهت
+هم‌چنین
+تعلق
+بگیرند
+گوناگونی
+نایب
+حساسیت
+کارگردانان
+مغول
+سازمانی
+دیا
+داغ
+خواهی
+فشرده
+ماجرای
+زندانیان
+تصاویری
+بیماران
+کهنه
+مکمل
+بخواهید
+رایگان
+رویه
+ماری
+فرمایید
+بلورین
+فورد
+درخواست‌های
+سازد
+پروتکل
+راس
+فرقه
+وفق
+نازی
+احتمالی
+طلب
+اقماری
+محدودیت
+همایون
+۱۱۰
+هیأت
+احسان
+ابرخس
+بخواهد
+له
+مهرداد
+می‌شوند،
+سکوت
+مهاجر
+صدور
+بازیگری
+آسان
+سراغ
+اولا
+محلول
+وان
+کوی
+الکساندر
+لیسانس
+خزر
+۹۲
+شکنجه
+امیررضا
+گرجستان
+بازرسی
+عکاس
+۱۳۶۲
+آسیاب
+گویی
+شود؟
+حیاط
+موجهی
+ارکستر
+ارباب
+نویسندهٔ
+یخ
+السلام
+نسب
+بوی
+۱۹۴۷
+نمي
+اعضا
+خانوادهٔ
+ویکیپدیای
+سحابی
+شاهی
+شیوهٔ
+زیارت
+تحقیقاتی
+فعالیتهای
+کاغذ
+تهرانی
+پروفسور
+بریتانیایی
+اخیرا
+ایرنا
+مادرید
+۱۳۵۵
+زمینه‌های
+ببینم
+۱۹۳۴
+می‌بینید،
+فیفا
+صالح
+متداول
+ربط
+سطوح
+ی‌پدیا
+خواهدشد
+بحران
+۱۹۳۹
+افکار
+پیراهن
+۱۹۳۲
+انتظامی
+بلافاصله
+ارایه
+کمیسیون
+راز
+محمدحسین
+آبیلا
+محبوب
+سایه
+جوامع
+داور
+۱۹۰۰
+زودتر
+ولز
+سوخته
+تأیید
+ابوالقاسم
+برادرش
+بمب
+امتحان
+آرتور
+فرستاد
+صص
+دانشجوی
+کارگر
+هوش
+اتفاقا
+غلامحسین
+قربانی
+می‌خورد
+احکام
+سرزمین‌های
+ضمناً
+فینال
+قبرستان
+ضعف
+نامهای
+گندم
+قواعد
+تند
+تایپ
+ماموریت
+موسیقی‌دانان
+گوشه
+دری
+مناسبت
+ارقام
+چاراویماق
+مبانی
+گذاشته‌اید
+ابر
+مدخل
+یو
+شناس
+اندازهٔ
+غالب
+قنات
+مبتلا
+ویکی‌فا
+نوزدهم
+مونیخ
+کابینه
+میرحسین
+باقر
+۱۹۳۵
+سامان
+هلندی
+موجودات
+فنلاند
+برعهده
+مدافع
+قطار
+تغییرات،
+فرمانروایی
+واگذار
+حکیم
+آهنگسازان
+شوند،
+تحول
+مرکب
+مقادیر
+اختیارات
+نوشتاری
+چندانی
+جان،
+هکتار
+رازی
+محله‌های
+آوردند
+صف
+مقاله،
+تدریج
+نیستید
+تسلط
+اسلام‌آباد
+آزمون
+ویرایشاتشان
+اصولا
+صفت
+۱۹۳۷
+می‌شد،
+سفیر
+تمرکز
+شهروند
+نمودن
+ویتنام
+نمایندگی
+گردش
+سران
+فر
+ایمنی
+خو
+مشارکت،
+پسرش
+می‌ماند
+متروی
+ختم
+علمای
+۱۳۶۴
+ران
+کودتای
+قهوه‌ای
+دایرة‌المعارف
+لنگه
+درونی
+سرا
+خاموش
+منصب
+ماد
+دومی
+کشور،
+سوادکوه
+خدایان
+بی‌طرف
+ماجرا
+دماوند
+بردسکن
+ویکی‌نویس
+ماهنامه
+یادگیری
+قابل‌
+هاشم
+همگان
+روانشناسی
+محمدآباد
+نگهبان
+آفرید
+گیرنده
+۱۳۵۲
+۱۳۸۹،
+ترکان
+هوی
+دندان
+خوش‌آمد
+گرفتم
+پایهٔ
+دانلود
+جفت
+فهم
+گوشزد
+متشکل
+رسمیت
+مقدماتی
+جویباری
+پيش
+کنیم،
+استانداردهای
+سرجعبه
+آنجایی
+خیریه
+بیش‌تر
+في
+دکمه
+ماندگار
+فیروزآباد
+بخار
+فیلیپین
+جلگه
+آرامش
+۹۳
+رونق
+پاسداران
+میتوانید
+کاووس
+۱۳۵۳
+۶۰۰
+مرو
+نیافتید،
+نداره
+نجفی
+الهام
+میکنید
+ناصرالدین
+قصه
+آمدند
+پراکنده
+خواهان
+روي
+مرودشت
+مسیحیان
+عبدالهی
+حسابی
+پاییز
+جانبدارانه
+کی‌پدیا
+حین
+پلی‌استیشن
+اعصاب
+می‌توانیم
+فرح
+نمک
+به‌طور
+۹۷
+۱۳۵۹
+گرافیک
+زمین‌لرزه‌های
+منتهی
+مستقر
+تقدیر
+۱۹۳۱
+می‌رفت
+افسانه‌ای
+برخط‌اند
+آبشارهای
+برخوردی
+عکسی
+خاور
+مورخ
+جمال
+باتجربه‌ترند
+به‌کار
+مطالبتان
+راه‌آهن
+نفع
+پاجعبه
+نسخه‌های
+بدی
+آکادمیک
+امتداد
+یوشیچی
+رضاشاه
+تأمین
+خواهشمندیم
+لو
+رئال
+خراسانی
+سردر
+آشپزی
+ایرانیکا
+شاگرد
+سرای
+یزدی
+نامزدهای
+وکیل
+نقشهٔ
+اکسیژن
+شفافیت
+یکی‌پدیا
+مقیم
+ویل
+یادآوری
+بلوری
+شعاعی
+قائم
+آلن
+استانبول
+بکنید
+عمیق
+تایمز
+سلماس
+بی‌طرفی
+بیل
+بویژه
+تک‌آهنگ‌های
+می‌باشد،
+جماهیر
+وحشی
+نمایشنامه
+روایات
+غنی
+کسروی
+بازتاب
+شاملو
+اروپای
+برنج
+بيشتر
+اخراج
+جمعیتی
+اخترسنجی
+شوش
+خوشنویسی
+تقاضا
+مکان‌های
+کریمی
+۱۹۲۹
+دفاعی
+برگشت
+کنید؟
+معمار
+خوش‌حال
+قوه
+۱۳۶۵
+اکسید
+لاهیجان
+آئیله
+عقاب
+پائین
+سوالی
+کنم،
+مان
+خواف
+انجیل
+محاکمه
+ور
+كنيد
+میخی
+مرزهای
+روشی
+بل
+آداب
+زرتشتی
+باشی
+جهرم
+آور
+شهادت
+رسیده‌است
+سادات
+زحمات
+بنویسم
+شریعتی
+بان
+مرتبه
+آثاری
+شه
+کابلی
+تویوهارا
+بیجار
+می‌زند
+نگران
+کر
+سیرجان
+اماکن
+ایلخانی
+ماست
+گزینه
+دوشنبه
+شواهد
+قاعده
+موازی
+شتاب
+۱۳۶۶
+حال،
+ویا
+می‌برند
+۱۹۲۴
+نت
+نجومی
+تعارض
+سادگی
+۱۳۰
+خلافت
+تأثیرپذیرفته
+طبری
+تعقیب
+کاشانی
+منع
+توضیحی
+دورود
+حبس
+بهایی
+محاسبات
+بگوییم
+تنوع
+معادله
+۱۳۵۱
+کوچکتر
+جوی
+دورنما
+شرایطی
+فرماندار
+هریوا
+پی‌گیری
+۱۹۲۸
+می‌نامند
+فومن
+الجزایر
+سیاست‌مداران
+۹۴
+مقدم
+طرفین
+چمن
+صفویه
+یر
+نابودی
+رفسنجانی
+معادن
+۱۳۴۷
+نیل
+سانتی
+دام
+نامه‌ای
+ات
+یافته‌است
+می‌دارد
+بقعه
+۸۰۰
+پرتو
+قید
+ظرف
+لری
+قدیمی‌ترین
+انسان‌ها
+برنامه‌ریزی
+وسطی
+مسلم
+چالوس
+پیشتر
+پوشیده
+فرزان
+میشوند
+منظم
+تلفن‌های
+خوشحالم
+تجمع
+رنج
+آباد،
+مختصر
+هماهنگ
+روشهای
+لفظ
+چوبی
+همين
+شادی
+وسیعی
+گور
+کردیم
+تندیس
+مواقع
+الیگودرز
+نسبتاً
+هٔ
+مخصوصا
+شی
+مشهورترین
+می‌خواستم
+انها
+نهنگ
+حرکات
+دنباله
+قانع
+۱۹۴۲
+داوود
+می‌کردم
+جاوا
+تعادل
+پزشکان
+نحوی
+مادی
+ردهٔ
+گذاشتم
+۱۳۶۳
+کمان
+بعدا
+شرمنده
+ویراستار
+ایام
+اسلواکی
+ناراحت
+متحرک
+تجربی
+خاصیت
+گیلانغرب
+کشتن
+مرزی
+پرچم‌ها
+ذهنی
+لر
+مساوی
+رستمی
+کرم
+ازبکستان
+رضایی
+احیا
+هنگ
+توانم
+شکر
+مند
+کمتری
+بردارید
+قبر
+فرعی
+ایم
+معارف
+پیوندی
+اطلاع‌رسانی
+بسازید
+کردند،
+کلیدی
+سيستم
+لغو
+بسیج
+سرنوشت
+شاخه‌های
+طرفدار
+سیاوش
+کشیدن
+پناه
+هشترود
+ورزشگاه‌های
+صفحه،
+عارف
+ابرکوه
+،خرد
+دراین
+بایر
+قلی
+دشوار
+بیزانس
+بهانه
+جالبی
+قبیله
+بیژن
+چنانکه
+می‌
+بیانیه
+آلفا
+کارگاه
+استوار
+کش
+پویا
+چیزهایی
+نمی‌کنند
+رهنمود
+وصل
+کریس
+پسوند
+مهاجم
+جامعه‌شناسی
+مجددا
+ایر
+احتیاج
+متأسفانه
+خودکشی
+۱۳۴۸
+مراتب
+یازدهم
+خام
+نوجوانان
+بدانم
+طنز
+چهره‌های
+شبانه
+دامغان
+مقصد
+وزیران
+لوح
+شهرام
+بده
+جلا
+دشتستان
+روزنامهٔ
+چهارشنبه
+دالاهو
+ضریب
+تکنیک
+سرخس
+ولي
+دکترا
+آنجلس
+خرس
+مجتبی
+نهاوند
+مسیه
+حسینیه
+كنند
+ملاک
+۳۶۰
+هندسه
+ابو
+کامپیوتری
+۱۳۴۵
+۱۰۱
+صندوق
+بلی
+آقایی
+قالی
+۱۹۲۵
+اشتغال
+اوستا
+خاش
+باتری
+قربان
+رمان‌های
+زير
+خالص
+زدم
+باشد؟
+توقف
+دوستانی
+اجتماع
+کوهی
+کلاه
+قائل
+فلز
+مطلوب
+گربه
+نگرانی
+زوج
+یار
+سرپل
+نوروزی
+۱۹۲۶
+الآن
+اختلالات
+بریتانیکا
+ايجاد
+آزار
+سا
+پروتئین
+بادی
+مجزا
+سانتیمتر
+اله
+پسران
+۱۳۴۶
+دروس
+کور
+مطلع
+نستعلیق
+خطرناک
+لوگوی
+دنده
+ویژه‌ای
+بهینه
+الکترون
+سقز
+عددی
+کاش
+جیرفت
+راسته
+بتوانم
+نسبتا
+یازده
+کمیل
+مانفی
+انتخابی
+نداشتن
+حرکتی
+کمترین
+مرورگر
+مقاله‌ی
+برنز
+انشای
+فراتر
+وسیلهٔ
+انزلی
+سوم،
+آشور
+اجزای
+روزنامه‌های
+نداشتند
+برتری
+توقیف
+گنجایش
+نویسندگی
+واشینگتن
+وَ
+عبد
+ماهیت
+ترکمن
+تابش
+برف
+اثرات
+نمایشی
+است‌
+حدس
+بین‌الملل
+۱۹۲۳
+راوی
+بامداد
+تنگه
+گذراند
+اتفاقی
+هالیوود
+گشته
+اسمیت
+باش
+آلی
+ترکمنستان
+سوسیالیستی
+مجلات
+۱۹۱۸
+بدنه
+قاهره
+خانهٔ
+بید
+ایرانی،
+۱۳۴۰
+پری
+اشتباهی
+نهاده
+وب‌سایت
+شهروندان
+همایش
+خوان
+نژادی
+عملیاتی
+افزود
+مخلوط
+رودسر
+الیزابت
+نمونه‌ای
+مغزی
+قضایی
+یان
+گالری
+بگو
+ملقب
+ایفا
+انیمیشن
+بخش‌هایی
+شکستگی
+سوپر
+کانی‌شناسی
+ویتامین
+می‌دادند
+پرجمعیت
+درسال
+۱۰۵
+ستاره‌های
+مدیا
+بندپی
+تردید
+كشور
+ماهیان
+پوزش
+انگار
+اسلام،
+ايشان
+سرپرستی
+تاکستان
+۱۹۲۷
+۱،
+پذیرفت
+نما
+مشتق
+باستان‌شناسی
+امامی
+اتم
+ندیدم
+نوشهر
+گزیدن
+۱۹۱۹
+حیوان
+بنظر
+کورش
+اواسط
+رفتند
+تبادل
+میلی
+استون
+دانستن
+آمریکا،
+حصار
+آینه
+گرایی
+قبایل
+کبیسه
+۱۹۴۳
+۱۹۱۲
+۱۹۱۷
+برقراری
+فيلم
+نداشتم
+سرده
+فعالیت‌ها
+بوستان
+خیال
+کارش
+کربلا
+کنم؟
+سیاست‌مدار
+معنایی
+آلودگی
+شماری
+کودتا
+پانزده
+المعارف
+کالبدشناسی
+عظیمی
+علائم
+کنسول
+نحو
+سوئدی
+گرفت،
+مازندرانی
+مثال،
+منسوب
+نشدم
+ویران
+درخشندگی
+بندرعباس
+ارگ
+سامانه‌های
+بیمه
+انجامید
+اردکان
+متمرکز
+سلولی
+مرسوم
+صادقی
+هيچ
+امثال
+ولتاژ
+مقررات
+رکورد
+بلخ
+نامزدی
+پردیس
+راه‌های
+‌ای
+مانده‌است
+هدیه
+خاکی
+کلاً
+كنم
+جویبار
+گرجی
+سنجش
+بو
+مثلث
+جمهوری‌های
+خاتمه
+رشتهٔ
+بوش
+حسین‌آباد
+۱۳۴۹
+جنگلی
+عزل
+مزار
+اختلافات
+زاکسن
+عشایر
+دشمنان
+کنگ
+یهودیت
+الگویی
+فرکانس
+تحریف
+پژوهش‌های
+شام
+لار
+می‌بینید
+مریخ
+علی‌اکبر
+عامه
+روزها
+زخمی
+عبارت‌اند
+ویکی‌های
+بری
+کارائیب
+رده‌فرد
+رحیم
+نگاشته
+القاب
+قاتل
+مکرر
+محمد،
+ابداع
+ویدئو
+اسطوره
+جامد
+ژنتیک
+مجاور
+سیاسی،
+رفسنجان
+بعید
+مرند
+روحانیون
+اریک
+قریب
+نثر
+تحریم
+موزیک
+برداشتن
+ارتفاعات
+اشکالی
+غذاهای
+شهاب
+بورس
+سال،
+نقشه‌های
+عروس
+نخل
+محلات
+آلبرت
+فا
+دشمنی
+۱۹۴۴
+يكي
+جایگزینی
+تفاصیل
+خدابنده
+اقلیت
+مشخصی
+محاصره
+زین
+افتخارات
+این،
+بي
+سواحل
+اندام
+فرماندهان
+دانند
+دوازدهم
+بجز
+آرا
+بهائیت
+۱۹۲۱
+کالا
+استقرار
+تلخ
+تکه
+جلوه
+امان
+نگونبانگونی
+فیلمنامه
+مترجمان
+کتاب،
+بستر
+تولیدی
+باغ‌های
+نباشند
+انصاری
+محمدتقی
+ان‌جی‌سی
+سلمان
+پهن
+گستره
+سودان
+پرهیز
+همون
+موسسات
+جاهای
+اشرف
+سواد
+مصوب
+دانه
+اينكه
+شعبه
+تشیع
+اپرا
+مجری
+موضع
+۱۴۰
+گلوله
+دارایی
+آوردم
+۱۸۰
+بلد
+سیروس
+گرمسار
+مهارت
+پیشاپیش
+ساختمانی
+باختر
+نامید
+ایفای
+باریک
+تعجب
+عقد
+فرمودید
+وطن
+گوی
+قبرس
+محبوبیت
+کوچ
+جدید،
+اخترشناسی
+کلمهٔ
+ایذه
+احوال
+پراکندگی
+ویرایش‌ها
+سانتا
+نپال
+چرخش
+فخرالدین
+دستگاه‌های
+پاراگراف
+می‌توانم
+پیکر
+بعد،
+جای‌ها
+یاران
+بیگ
+پنجره
+رامسر
+خواه
+انکار
+می‌کشد
+۱۹۲۲
+برعکس
+پاره
+اکشن
+لغات
+گردآوری
+سهراب
+نیز،
+عراقی
+پاسارگاد
+نوجوان
+مخفف
+هیچگاه
+کاندید
+بهروز
+بناب
+تهمت
+آفریقایی
+جسد
+پژوهشگران
+موسس
+بلاگ
+آبخواره
+مایه
+مجدداً
+لقب‌ها
+تلسکوپ
+استانی
+منتقد
+داراب
+دلخواه
+فرش
+بارگذاری‌شده
+صحرای
+نوک
+فارسي
+رسانه‌ها
+ماکو
+۱۳۶۱
+استفادهٔ
+دستیابی
+سرو
+بردار
+آلبوم‌ها
+مکعب
+تب
+می‌گرفت
+وی،
+قطعی
+اقبال
+پلاک
+برابری
+جوش
+التحصیل
+بردند
+شارل
+خشم
+سارا
+گناه
+حوصله
+بیافزایید
+اصیل
+خودمختار
+نمی‌دهد
+داند
+سراوان
+صور
+یعقوب
+شنیدن
+اشتراک
+دفع
+اد
+ه‍
+وستفالن
+بهائیان
+پناهگاه
+مسیرهای
+هست،
+مذاهب
+گران
+تابعیت
+یابی
+ولسوالی‌های
+اسرائیلی
+تاریکی
+تعطیل
+همکار
+زور
+خلیل
+شوخی
+سلول‌های
+تنش
+کرسی
+نصف
+می‌افتد
+بیات
+فضل
+نامشخص
+تعبیر
+۷۰۰
+شو
+سوسیالیسم
+اب
+پرچمک
+دموکراتیک
+تحولات
+بگیریم
+گسترده‌ای
+آریایی
+کیلو
+والی
+براون
+ناچار
+گنج
+بلندترین
+انگشت
+محتواهای
+۱۳۸۵،
+نه؟
+یهود
+وضوح
+بلوک
+بلور
+باکیفیت
+غير
+بدل
+نادیده
+لاریجان
+دلفین
+جاز
+حاکمان
+دوری
+آرای
+خاوری
+شناختی
+ماریا
+شیب
+نیوزیلند
+مشکین
+منتظری
+خریداری
+۱۱۵
+جانی
+به‌شمار
+تعلیم
+تأکید
+اندازه‌گیری
+یافتند
+مادری
+فون
+بادن
+کدهای
+بدنی
+لوئیس
+ادامهٔ
+مبلغ
+صلیب
+می‌بایست
+آریا
+۱۲۵
+بفرمائید
+قراردادی
+شر
+گفت‌وگو
+گرینویچ
+مولکولی
+نیو
+سايت
+۱۹۱۴
+جزیره‌های
+رسیدند
+فرمت
+قائم‌شهر
+تفرش
+نظریهٔ
+خواستید
+هافبک
+دائمی
+تنیس
+می‌دهد،
+ماتریس
+باخت
+سیا
+مغرب
+سل
+اسلحه
+ذهاب
+دهد،
+فرقی
+صرفاً
+وبلاگ‌ها
+نمیشود
+راضی
+آتن
+چراغ
+حالتی
+شلیک
+الیور
+اینکار
+برپا
+آهنگرکلا
+لویی
+نیما
+بجنورد
+نهادهای
+محروم
+نکا
+لب
+وحش
+اعتراضی
+ژن
+ويكي
+عثمان
+نیشابوری
+بلک
+کنندهٔ
+موتورهای
+رئیس‌جمهور
+حکایت
+حاکمیت
+نفره
+هرسین
+مالیات
+انجام‌دادنی‌ها
+خودت
+مناقشه
+کارهایی
+غذای
+نوردراین
+علل
+دیپلم
+دادگستری
+پیچ
+لیورپول
+سرپرست
+گلی
+تفت
+جنسیت
+امری
+صبا
+اسفراین
+ریخته
+برا
+ناپلئون
+دبستان
+ویدئویی
+خمیر
+انتخاباتی
+گفته‌است
+ورزشکاران
+عادت
+آرایه
+اعتراف
+استخدام
+آرامگاه‌های
+دوتایی
+ارنست
+عمدتا
+مجهز
+زدند
+۱۳۳۰
+۱۳۸
+۱۳۳۲
+آلبانی
+نشانه‌های
+باغین
+شعبان
+فارسی‌زبان
+نیمی
+سازگار
+زبانان
+پیست
+کارایی
+گرافیکی
+کوره
+اتیوپی
+ساوجبلاغ
+مشرق
+فِي
+سیزده
+۱۰۳
+مردم‌شناسی
+بلندی
+محمودآباد
+بتا
+۱۰۲
+مراد
+افتخاری
+سهام
+امیدان
+دلایلی
+غول
+۲،
+مازیار
+عمدتاً
+مملکت
+۱۳۴۲
+انگیزه
+فرنگی
+مینودشت
+بقایای
+ابوالفضل
+فاکس
+میگوید
+همچنين
+شعری
+لس‌آنجلس
+تائید
+تاریک
+تونس
+بستان‌آباد
+کارمندان
+اسحاق
+۱۶۰
+کارگری
+پتانسیل
+سحر
+۱۰۹
+نیازهای
+آرسنال
+افزون
+نظریات
+کوبا
+فهرستی
+آزادگان
+کارشناسان
+تزریق
+کاپیتان
+حدودی
+فیل
+والیبال
+ازای
+این‌گونه
+همانگونه
+نداده
+سردبیر
+تالش
+سام
+می‌گذرد
+آنتی
+مجلهٔ
+بازی‌ها
+رجال
+هم‌درازا
+دختری
+رفته‌است
+ابریشم
+فلوریدا
+بلغارستان
+مصری
+بلوار
+دليل
+راه‌اندازی
+۱۰۴
+شمشیر
+ندا
+صادرات
+دانیل
+هریس
+کله
+حوزهٔ
+نشسته
+بیاندازید
+۱۲۸
+وبه
+تازگی
+شورا
+سروده
+درمورد
+شدند،
+قطعا
+اراضی
+می‌گویید
+حامی
+خوراکی
+جایزه‌ها
+کویر
+مفهومی
+رودهای
+زمان،
+کمیاب
+مخاطب
+سوابق
+سلامتی
+علوی
+خواندم
+نهایتا
+هوشمند
+همیشگی
+همدیگر
+سازه
+ترویج
+مقر
+قشم
+تغيير
+دیروز
+مخالفم
+نجوم
+آرزو
+عموماً
+افقی
+گوشی‌های
+رباتیک
+کلاته
+لورنس
+وزیری
+پرداختند
+رجب
+جوزف
+سپری
+تایوان
+مقاله‌هایی
+بود؟
+بزند
+مرسی
+باختری
+صلاحیت
+نمی‌آید
+بهشهر
+جماعت
+خونی
+نوشته‌است
+ازنا
+مکانیکی
+فضاهای
+فرمانروایان
+رزمی
+همسایه
+همدانی
+۱۹۰۸
+۱۹۰۵
+هردو
+۱۱۴
+هرم
+شهرکرد
+۱۰۷
+آب‌های
+متقاعد
+شویم
+نبود،
+نویسان
+هم‌زمان
+شهر،
+صخره‌ای
+ارزشمند
+۱۳۲۰
+حذفش
+سامی
+ثانویه
+دن
+احساسات
+بوئینگ
+نام،
+شبکهٔ
+شمرده
+طوایف
+باری
+جبر
+اجازهٔ
+بزرگ،
+بهم
+۱۱۱
+جهان،
+مولوی
+تفریحی
+ماساچوست
+آنها،
+اجتماعی،
+طاق
+خوشامدید
+نیامده
+اچ
+ملاحظه
+کمبریج
+زی
+برش
+می‌گذارد
+شدگان
+بدو
+درحال
+چارچوب
+شده‌اند،
+قطبی
+لئون
+هیدروژن
+کاردانی
+درمیان
+نقاشان
+شنیده
+چنين
+آتشکده
+کوههای
+قروه
+هجوم
+سرهنگ
+عکس‌های
+تاجگذاری
+خرج
+۱۳۴۴
+جعلی
+آمیزش
+راهپیمایی
+سرشار
+فیروز
+دوک
+بهداشتی
+شکی
+ماهواره‌ای
+طاهره
+زیرصفحه
+تسخیر
+مخزن
+حیدر
+اتفاقات
+غزل
+زهج
+بولیوی
+کردها
+۱۹۰۱
+قند
+نخست‌وزیر
+بازهم
+عصب
+مهاباد
+پرس
+گازی
+ابزاری
+مبدل
+۱۳۵
+میشل
+مستقیما
+صدام
+محکم
+فلزات
+طنابداران
+پروژهٔ
+امّا
+صحرا
+۱۰۸
+جملهٔ
+شوهر
+هواپیماهای
+سعادت
+جعل
+صفحه‌کلید
+اوباما
+۱۹۰۶
+انب
+اپل
+مرخصی
+معیارها
+دانید
+دعا
+تلفات
+تضمین
+آرامی
+دائم
+شد؛
+چرخه
+شجره‌نامه
+آفرینش
+معادلات
+رسما
+مزبور
+بارش
+برکه
+نبی
+مصالح
+والتر
+سدیم
+بحثش
+پیشگیری
+پروین
+نشود،
+می‌گردند
+مسافر
+راین
+بتن
+خوشه
+طوسی
+جونز
+وابستگی
+اسیر
+خیابانی
+بت
+اینجانب
+ببینیم
+لیکن
+بگذاریم
+شراب
+انگیز
+برروی
+حاجی‌آباد
+پارسک
+اعزام
+اعطا
+فقر
+علي
+کارنامه
+حجاب
+اینک
+جمع‌آوری
+درهم
+خواهشمندم
+اینه
+گانه
+پارچه
+گردیده‌است
+مداوم
+آلوده
+حقایق
+جعبه‌دندهٔ
+بشری
+چهارده
+۱۳۰۰
+لیلا
+بدیهی
+مابین
+مثنوی
+ویدیویی
+محققان
+رابط
+تلمبه
+پرفروش‌ترین
+استیو
+ساختمان‌های
+وانتشار
+معترضان
+وحی
+برنامهٔ
+بگم
+عسل
+پرتغالی
+فصلنامه
+عجب
+رفتارهای
+وورتمبرگ
+امپراطوری
+برون
+شانزدهم
+مدل‌های
+آکسفورد
+فساد
+چیزها
+خبرنگار
+ذره
+کان
+کنیم؟
+دامداری
+هی
+عبدالکریم
+کوهرنگ
+آنتونیو
+ایرادی
+۱۱۶
+دریافتی
+هرمز
+آب،
+گـپ
+ویکی‌پدیایی‌ها
+۱۰۶
+غریب
+دلفان
+راسل
+۱۹۰۷
+گویم
+قزاقستان
+وحشت
+منشور
+انتقام
+مشروطیت
+کیفی
+بپردازد
+براى
+شركت
+تعصب
+ویلهلم
+خطای
+متقابل
+۲۰۱
+اشکانی
+می‌کرد،
+بروجردی
+طبقات
+طالبان
+سفارش
+فیلمهای
+آهنگ‌های
+کنستانتین
+پیوستن
+دیدگاه‌های
+چالش
+ستایش
+نقشی
+کهریز
+منطقه‌های
+خلبان
+تنگستان
+فروند
+حج
+خاتم
+۱۳۴۱
+گردند
+پایتون
+گفته‌اند
+دانسته‌اند
+دانشکدهٔ
+تکلیف
+بازرگان
+نتوانست
+بیوگرافی
+۱۵۰۰
+بنت
+مری
+نقص
+فانتزی
+پژوهشگر
+دویچه
+کنت
+قاجاریه
+دوام
+حیدریه
+جیمی
+پویانمایی
+قوای
+می‌آورند
+کامران
+متنوع
+استراتژی
+شمارش
+۱۹۰۴
+اعم
+داراي
+بهبهان
+الدوله
+تخلف
+فراری
+ایزد
+رأس
+انداخت
+چرداول
+پیش‌فرض
+رهنمودهای
+بافتا
+شناسان
+اردو
+آبیاری
+ترانه‌سرا
+روحی
+ادیب
+فلات
+ایست
+سلیقه
+ماجراهای
+باکو
+همارس
+تراکتورسازی
+گم
+رابطهٔ
+داشتند،
+رپ
+گز
+بگذارد
+۱۱۲
+مستندات
+زمین‌های
+سایت‌های
+مبحث
+مشکلاتی
+بوکان
+ابزارها
+جبران
+تقریبی
+زیان
+گلپایگان
+خوشنویسان
+۱۲۲
+بارز
+مَا
+بوک
+اشتباهات
+تانک
+می‌شده
+دهه‌های
+واژه‌نامه
+خشکی
+ایی
+اللَّهِ
+عفونت
+۱۲۳
+باده
+نام‌تصویر
+بیس
+كردن
+گچ
+زدهٔ
+طلای
+معکوس
+نبودند
+رضایت
+ثروت
+انار
+کشاورز
+کوانتومی
+اژدها
+سوراخ
+بیلبورد
+شاهین‌دژ
+بره
+اهدا
+زیرزمینی
+تکراری
+صربستان
+مراقبت
+تروریستی
+۱۹۱۱
+متمایز
+آملی
+برساند
+عن
+ابهر
+معتدل
+گفتگوی
+املش
+می‌بینم
+می‌آمد
+۱۹۱۳
+ناشناس
+وله
+جایش
+جنبش‌های
+توليد
+موزه‌های
+نمائید
+دهمین
+برند
+تاریخچهٔ
+می‌شده‌است
+پاسخی
+پشتی
+تشریح
+نمی‌شوند
+خویشاوندان
+انگشتدان
+دكتر
+ژانر
+فریاد
+اخلال
+تمشک
+سعد
+پارسا
+۹۰۰
+نامدار
+نظامیان
+قدری
+حمام‌های
+مستوفی
+گرما
+گرا
+یادگار
+عاشورا
+دفعه
+بیانی
+شنا
+استعفا
+رسانه‌ای
+انحلال
+بزرگداشت
+فایرفاکس
+بتوانید
+مؤلف
+حامیان
+ناحیهٔ
+مور
+۱۹۱۰
+حیاتی
+هرگاه
+آنا
+جاسوسی
+منتج
+جابجایی
+تولیدات
+هاى
+قدردانی
+۱۷۰
+راست۱
+لیلی
+عملاً
+میشد
+کشورهایی
+درجهٔ
+حامل
+ابوبکر
+خصوصا
+اختصار
+مجاورت
+پدیدآورنده
+آراء
+چپ۱
+گله
+یکپارچه
+عبارات
+جمینای
+جزیرهٔ
+اسرار
+خانواده‌های
+بلوز
+مونته‌نگرو
+بیابان
+به‌صورت
+دارید؟
+نقطهٔ
+ضرورت
+وي
+کارکرد
+هوانوردی
+محبت
+پارک‌های
+واژه‌ای
+امامزاده‌های
+هریک
+کوچکترین
+طاهر
+حوالی
+مطهری
+کنگاور
+شدهٔ
+شبکه‌ها
+شیوه‌های
+تیراندازی
+۱۱۸
+جست
+آژانس
+سایز
+بدن۱
+تکذیب
+نقدی
+متناسب
+دال
+بابی
+شانزده
+هرکدام
+ادعاهای
+العاده
+عنایت
+مزدیسنا
+انقراض
+مقدونیه
+۱۲۷
+ندیده
+رأی‌گیری
+دلو
+هندسی
+موبایل
+تورم
+رفتاری
+پیامدهای
+زید
+زادروزها
+حیدری
+بتوانیم
+فوری
+علایم
+نویسه
+غم
+خلال
+اریل
+کاشمر
+بز
+بردسیر
+۱۹۱۵
+حتا
+برخط
+خرمشهر
+همچین
+نفری
+سالگرد
+متخصصان
+شاهرخ
+صحن
+جنین
+جشن‌های
+یکشنبه
+تمیز
+ارامنه
+چپ۲
+جلسات
+مهمان
+کجای
+روال
+۱۳۴۳
+پینک
+سبک‌های
+هان
+بدن۲
+عمودی
+افسران
+شجریان
+نوسنگی
+الاسلام
+مساجد
+صاف
+مروارید
+جانور
+آنهایی
+راست۲
+اسکی
+ناشناخته
+اعتقادات
+یم
+انگور
+ويرايش
+گروههای
+ترانهٔ
+شد؟
+دقیقی
+استادیوم
+مختلف،
+عتیق
+توطئه
+بالا،
+مین
+همگانی
+تلفنی
+می‌دانست
+ود
+ميان
+تشکیلات
+روده
+مدیره
+ونزوئلا
+مخصوصاً
+مشتمل
+انتقادی
+تفنگ
+برایشان
+طالقان
+فرانسیس
+بازارهای
+پایین‌تر
+کاروان
+به‌جای
+الیاف
+خامنه
+خصوصاً
+ظهر
+سکس
+چهاردهم
+ایزو
+مسجدسلیمان
+الکل
+فلاندری
+محمدیان
+شکوه
+کرده‌اید،
+اسلامي
+سم
+کناره
+لوازم
+نمیدانم
+پیامی
+فارغ‌التحصیل
+باس
+کام
+بنویسد
+بازنشسته
+نصر
+کاشی
+شکارچی
+پست‌های
+ویلیامز
+دهکده
+اندر
+۱۵۴
+جهانگیر
+ملکان
+می‌توانست
+عبارتی
+مسئولان
+هلال
+مهندسان
+غارهای
+بیلی
+۱۹۱۶
+بنگلادش
+حملهٔ
+توانستند
+پارینه‌سنگی
+پولی
+خوشبختانه
+نموده‌است
+امینی
+نه،
+هما
+مشورت
+نامحدود
+آندره
+پلنگ
+مخدر
+مضمون
+برمی
+هم،
+لاس
+دهید،
+ویکتوریا
+موثق
+داود
+عذرخواهی
+یاهو
+رنگ‌های
+۱۱۷
+تناوبی
+نوشتید
+لااقل
+شتر
+مرکزیت
+امن
+ترسیم
+سیستم‌ها
+اتومبیل
+آفی
+جون
+خالق
+حرارتی
+رسوم
+موریس
+مارشال
+یورو
+بانو
+اولين
+منشورات
+غیبت
+نوشته‌اند
+قدرتمند
+شکم
+هایش
+انداز
+رویکرد
+علاقه‌مند
+خانواده‌ای
+دمشق
+دربند
+برو
+آرشیو
+۱۹۰۹
+رویش
+استخر
+آنالیز
+گچساران
+بکنم
+مولا
+متفرقه
+رحمت
+شاخ
+۱۳۱۰
+اتفاقاً
+اسمش
+سهامی
+دبلیو
+بخشهای
+سرتاسر
+ویکی‌ها
+خیالی
+نکنند
+تناسلی
+م‍انفی
+جديد
+۱۳۲۴
+کار،
+برندهٔ
+پیچیدگی
+گواهی
+زرتشتیان
+ناصری
+همانجا
+رغم
+گفتهٔ
+۱۱۳
+گرمسیری
+طلوع
+برترین
+درآورد
+به‌دست
+برقی
+سپاهیان
+ویژگی‌ها
+مر
+۱۲۴
+چهاردانگه
+جامعهٔ
+تحقق
+مجاری
+می‌گفتند
+فروپاشی
+چشمه‌های
+ساختاری
+مسافرت
+پیکان
+نرم‌افزاری
+جد
+روشنی
+معرفت
+تله
+می‌کنم،
+محرک
+مشتریان
+بیانگر
+سازمانهای
+چیزهای
+رقیب
+فرعون
+بیروت
+منعکس
+تابناک
+مشرف
+آورده‌است
+نمی‌توانم
+۱۱۹
+مولکول
+نعمت
+می‌رساند
+فرمانداری
+دستکاری
+۱۳۳۹
+مت
+اردبیلی
+مسدود
+بله،
+رانندگی
+۱۲۱
+سایپا
+استعداد
+پیامبران
+داماد
+واجب
+نسخ
+فاضل
+عرفانی
+بزرگ‌تر
+حق‌تکثیر
+شخصاً
+دگرگونی
+عكس
+انبوه
+آپولو
+فنون
+افلاطون
+حمزه
+میانجی‌گری
+نظرسنجی
+آنتونی
+اکوادور
+آن‌چه
+قذافی
+اسکن
+خاتون
+ناگهان
+گونه‌ها
+تونل
+به‌ویژه
+ناگهانی
+بدهیم
+دوشیزه
+آباده
+نمی‌توانند
+شلوغ
+ی،
+۱۳۳۵
+خلع
+فلوید
+ابومسلم
+بایت
+اعطای
+جاسک
+پوند
+پایداری
+تیتر
+واپسین
+استالین
+تعطیلات
+آستین
+مختلط
+تابلو
+خنده
+نویسه‌های
+ثمر
+۲۰۰۰،
+بازاریابی
+حسابداری
+تکلم
+رنگرزی
+نهبندان
+۱۳۳۶
+نیلوفر
+شرقی،
+بداند
+فسا
+آلیکانته
+دیلمی
+اجتناب
+نیر
+سطح‌بالای
+اينجا
+می‌زنند
+کیم
+لغتنامه
+عاشقانه
+فتحعلی
+اشیاء
+تعمیر
+فلانی
+استیون
+سازماندهی
+ویرجینیا
+راجر
+بگویند
+روزنامه‌نگاران
+هندو
+دیوانسالار
+ایستاده
+۱۳۳۷
+کرانه
+کلسیم
+هایدلبرگ
+کرواسی
+سرانه
+الملک
+سنگ‌های
+ژنتیکی
+نیکی
+هجرت
+مامور
+خنک
+نمایان
+بهرامی
+شبستر
+واسط
+آرایش
+مبهم
+بسی
+بریتانیای
+محدودهٔ
+بحث‍
+گاما
+ده‌ها
+نواختن
+فروشگاه
+خمین
+صنعاء،
+کنفدراسیون
+اموال
+هنرپیشه
+پارسیان
+متوسطه
+دامن
+۱۲۶
+لک
+شیشه‌ای
+ابراهیم،
+آمادگی
+هو
+زنجیره‌ای
+۱۳۲۸
+بازیهای
+سنقر
+بدر
+آورند
+مرجعیت
+آلت
+اسدآباد
+کارلوس
+سودمند
+نشانگر
+رسید،
+حوزه‌های
+دیار
+کنگو
+میهن
+کلانی
+۱۲۹
+افسر
+باکتری
+معماران
+۱۳۲
+سیدنی
+کفش
+ارادت
+می‌خواهند
+خر
+۳۵۰
+بدترین
+تاریخ،
+فلسطینی
+زاگرس
+بیاورد
+یانگ
+شخصا
+تشدید
+آدمی
+ماهی‌ها
+هیچکدام
+میناب
+بوسنی
+ایندیانا
+دنباله‌دار
+ملوان
+روزنامه‌نگار
+مؤثر
+دستورات
+رطوبت
+تعامل
+کلان
+عباس‌آباد
+کاملی
+احادیث
+مدرکی
+پاکسازی
+۱۳۷
+تفاوتی
+ورزشکار
+جنبه‌های
+غالباً
+بود؛
+چنگ
+مهاجران
+پله
+تراز
+آمد،
+وا
+کوثر
+وادی
+اتوبوس
+کاظمی
+خبرگان
+موس
+تکمیلی
+لهستانی
+درویش
+منم
+جعفرآباد
+نیا
+جاذبه
+گیلانی
+طلاق
+تروریسم
+به‌خاطر
+آيا
+گرفتار
+اشعه
+می‌پردازند
+شخصیتی
+آقایان
+رفتم
+جریمه
+مهره
+خاستگاه
+میان‌ویکی‌ها
+بالینی
+یزدگرد
+ببرد
+دوش
+چغازنبیل
+۳۰۰۰
+فوقانی
+۱۳۳۱
+گیلکی
+خط‌به‌خط
+کاترین
+بختیار
+کردید،
+گردان
+ادی
+طاها
+مدیترانه
+ارس
+حسن‌آباد
+پوشاک
+بابلسر
+رساندن
+کند؟
+بهش
+وست
+خوشامدگویی
+مهار
+میبد
+فلسفهٔ
+وند
+آش
+سیمین
+خوراک
+خوزه
+ساختند
+نياز
+عروسی
+میگردد
+جلفا
+بودیم
+بکند
+۱۳۸۸،
+روحانیان
+حماسه
+پایتخت‌های
+مبارزات
+احمد،
+ارث
+محمّد
+۱۳۳۳
+کوشک
+سنگ‌ها
+زشت
+دنا
+دستیار
+گرمایی
+ایشون
+نامهٔ
+تحمیل
+گوشی
+دوره‌ای
+ققنوس
+بدانند
+شن
+انداختن
+هفدهم
+غالبا
+اسدالله
+۱۳۴
+شدیدی
+ناپذیر
+۱۴۴
+گینه
+سرمربی
+نطنز
+کیبورد
+محفوظ
+آیند
+انفرادی
+آن‌که
+گمانم
+توانسته
+سال‌شهرشدن
+علم‌جو
+خرده
+درگز
+ایستگاه‌های
+بکشید
+پیش‌بینی
+حالات
+هرکس
+بزودی
+کایروس
+اوستایی
+صفات
+مارکسیست
+خشت
+جنب
+عذر
+ونیز
+آسانی
+کریستین
+صفویان
+اسدی
+۱۹۰۳
+تاخیر
+خیانت
+قوس
+قطره
+آثارش
+سیل
+اسکات
+مشاغل
+شم
+بخارا
+چاپی
+مکتوب
+دیدید
+انتها
+موزیکال
+كاربر
+منشأ
+سمی
+لَا
+پهلوان
+پوسته
+درختی
+مشابهی
+کنیا
+عاملی
+۱۳۹
+گویید
+۱۳۳
+تلاش‌های
+اهمیتی
+عازم
+اسمی
+پکن
+تصوف
+تکاب
+حاکی
+برت
+کنيد
+نوروزتان
+ببیند
+کبوتر
+سفرنامه
+۱۳۳۴
+تخلیه
+آق
+زنجیره
+انتقادات
+کوک
+همان‌طور
+غربی،
+جنجال
+فیزیولوژی
+سانتی‌متر
+بسط
+زخم
+۱۴۱
+ویکتور
+آران
+یك
+التهاب
+دسته‌بندی
+جنگنده
+ایفتا
+ژاک
+طاهری
+فیض
+بهتره
+ادعایی
+اسد
+بودنش
+پیک
+مسأله
+بانوان
+بنفش
+گشود
+باغی
+هیدوچ
+جسمی
+انگشتی
+یوهان
+لنز
+چراکه
+رهایی
+نگرفته
+مقصود
+جوراب۱
+آنهم
+قمی
+سکته
+کو
+سره
+زبانها
+برج‌های
+مکان‌ها
+نشدن
+چابهار
+پاراگوئه
+کتابها
+طولانی‌ترین
+اولویت
+مبارز
+استراحت
+مشت
+حرام
+فرمود
+نقلیه
+کمر
+پستان
+سرچ
+فعاليت
+ارتقاء
+شانس
+خودی
+فاتح
+مطالب،
+گوسفند
+میگویند
+غلام
+وصف
+دلم
+اظهارات
+انتگرال
+سوسیالیست
+گذارد
+ماموران
+بادام
+چال
+ساگه
+ایسنا
+معده
+ریشتر
+اعلان
+تک‌نفره
+بلو
+مناطقی
+شافعی
+می‌گفت
+می‌خواند
+ثانی
+هست؟
+منو
+لوث‌شدن
+جنایت
+برخاست
+بوده‌است،
+نمی‌باشد
+اشراف
+نداد
+مهربان
+الهیات
+همه‌ی
+زمين
+کینگ
+رول
+والتوزیع،
+مدرسهٔ
+ترافیک
+اتهامات
+وای
+بهنام
+شجاع
+سیار
+ترسناک
+ذات
+مختار
+عموما
+اینتر
+فرزندش
+داروشناسی
+ریسک
+۱۹۹
+نیجریه
+مظفر
+حشرات
+میدانید
+جبل
+آریزونا
+نارنجی
+کتابخانه‌های
+میدانم
+آرم
+بشمار
+اعتباری
+کره‌ای
+عکس‌ها
+پیکچرز
+تخته
+متمایل
+رفاه
+شهبازی
+میخائیل
+تطبیق
+نظریه‌های
+بلوغ
+عزیزم
+۱۳۹۱
+محاسباتی
+سنجی
+مکانیسم
+سریعتر
+آبشاری
+کالاهای
+اشک
+خانی
+سازگاری
+مارچ
+گرین
+قرص
+خوانندهٔ
+صفی
+نازک
+داروها
+۳،
+۱۳۶
+هماهنگ‌کنندهٔ
+لینکلن
+بانوی
+خودروی
+پل‌های
+۱۳۳۸
+دیوارهای
+ورامین
+۱۴۵
+اتخاذ
+کمیت
+دارم،
+مذاکرات
+حول
+برگزید
+کارشناس
+نامعتبر
+سفرهای
+رومیان
+ربات‌ها
+غیراینصورت
+انیمه
+به‌وسیله
+استعمال
+صریح
+سازه‌ها
+رامهرمز
+اندیس
+رازقنــدی
+تثبیت
+۱۰،
+تصوير
+گویش‌های
+کتک
+طالب
+حماس
+۱۳۲۹
+علیرغم
+۱۴۸
+حزبی
+استونی
+اوین
+غروب
+حریف
+استراتژیک
+شگفت
+مرگش
+جانسون
+پانزدهم
+موشک‌های
+گن‌آباد
+ارتقا
+باطل
+خورشیدی،
+آلفرد
+ساموئل
+بحرانی
+قندهار
+كردم
+ماکس
+گی
+میخواستم
+بچه‌های
+۱۳۲۵
+شرطی
+گشایش
+زندگي
+دایی
+یون
+فرانس
+تورات
+گزارشی
+۲۲۰
+فیلم،
+دهلی
+مسافران
+سنگر
+نخواهم
+موش
+ریشهٔ
+سخنگوی
+زنگ
+نینتندو
+دیوانه
+بمباران
+مسئولین
+استودیویی
+شدیدا
+تیلور
+۱۲۰۰
+قزوینی
+لاست
+مسلما
+ورق
+شهرزاد
+لطفی
+کلات
+بارداری
+دیواره
+باشگاهی
+شکستن
+تریلر
+ممتاز
+پرانتز
+یوتیوب
+بیهوده
+ابدی
+نباشد،
+کیوان
+طرح‌های
+بدم
+کاریکاتور
+بدتر
+داش
+می‌رسید
+میانجی
+بيش
+اختریان
+سربیشه
+روشنایی
+تبیان
+بکشد
+اراده
+چربی
+خرما
+سلطانی
+شيخ
+مقا
+مستخدم
+وب‌گاه‌ها،
+نشینی
+نرگس
+۱۷۵
+تویسرکان
+خاطره
+برکنار
+غیرقانونی
+ساواک
+نگاره‌ای
+سین
+شناسنامه
+بناها
+‌ها،
+غرق
+شعرهای
+مسلط
+سرش
+اه
+برکت
+جنگل‌های
+سلطه
+اقیانوسیه
+علما
+بنفشه
+یال
+هولوکاست
+دادستان
+حلی
+اجسام
+غواصی
+احاطه
+والا
+بیماریهای
+صدوق
+ریو
+دیویس
+ناهید
+دهها
+نتوانستم
+ایکس‌باکس
+ول
+منبع‌ها
+تاریخی،
+کثیر
+لیتوانی
+شده‌
+بپرسم
+قربانیان
+جانشینی
+سیریلیک
+بوستون
+یونانیان
+دوبار
+فرضیه
+امروز،
+دیده‌ام
+عزيز
+۱۴۲
+میگیرد
+شلوارک۱
+مِنَ
+ارسطو
+ومبلی
+بخواند
+۱۹۰
+صوفی
+صدق
+کارب
+گذاشتند
+هزینه‌های
+فردریک
+نوشته‌اید
+آو
+عمده‌ای
+م‍
+هیچگونه
+حسی
+اللَّهُ
+معدود
+مارکس
+سنگاپور
+رایانش
+عادل
+ریگان
+میرسد
+الگوریتم‌های
+ائتلاف
+فریدون‌کنار
+بازگا
+نگرش
+هرحال
+بدانیم
+کفایت
+فین
+۱۳۲۷
+باورهای
+بازگیر
+لردگان
+چرا؟
+تعویض
+سلجوقی
+جستار
+نخواهند
+می‌نمایند
+دهستان‌ها
+فرمانروای
+خودتون
+منتقدین
+کلاردشت
+اره
+لزومی
+مرتفع
+ویر
+سندرم
+نیاید
+آجر
+دانشکده‌های
+نمین
+مق
+تن‍
+اینچ
+فوتسال
+ساکنین
+‍ه‍
+فرانسه،
+صفحاتی
+۱۹۰۲
+طالقانی
+جعبهٔ
+غارت
+بزرگسالان
+لین
+۱۶۵
+قیاس
+افغانی
+نگذاشته‌اید
+ساید
+نادری
+امامان
+سنا
+سرگذشت
+رایش
+توجیهتان
+بروند
+سمفونی
+آهنگ‌ها
+توس
+تم
+پنسیلوانیا
+خرچنگ
+مغان
+سجاد
+پایینی
+تحریر
+لوث
+شانه
+طوفان
+اصولاً
+کبودرآهنگ
+تسمیه
+عامیانه
+بیشینه
+فضاپیمای
+بودایی
+۱۸۹۰
+اقلیم
+مثالی
+جشنواره‌های
+برایان
+میرود
+پین
+آم
+سرگرمی
+مزایای
+ریال
+رسماً
+ناحیه‌های
+تازه‌ای
+می‌دهیم
+هارد
+مقال
+فراهان
+دلیلش
+میلیمتر
+۱۸۰۰
+ماهنشان
+سالار
+جت
+مردگان
+فقیر
+۱۵۵
+راستا
+میکنیم
+جوری
+شلوارک۲
+پژوهشگاه
+نیستند،
+۱۴۶
+اینشتین
+یخچال
+روزمره
+ارم
+سنین
+تحسین
+سکه‌های
+۱۳۱
+فحاشی
+پاپ‌های
+عینی
+رسانده
+رز
+بودم،
+ارزشی
+ستان
+باراک
+اصلي
+الکتریک
+نامه‌های
+عطار
+علمي
+بخشید
+السلطنه
+يعني
+غلبه
+مستقیماً
+منش
+رستاق
+افراطی
+بگیرم
+سيد
+۱۴۷
+ندارند،
+الَّذِينَ
+نمونهٔ
+کریستال
+قایق
+نوادگان
+سالیانه
+می‌پذیرد
+احترامات
+شیری
+سیاهکل
+سرب
+نصرالله
+مانه
+گیم
+ببر
+آستان
+زیستگاه
+ای،
+داده‌ام
+لوئی
+شریعت
+آموز
+رتبهٔ
+کمک‌های
+نقدها
+حلقه‌ها
+ارتقای
+هال
+انسانها
+پشتو
+امیرحسین
+سین‌آباد
+رشید
+۱۴۳
+شیرینی
+مذاکره
+تعدیل
+کارمند
+اعضاء
+روانه
+بنر
+معروفترین
+خیابان‌های
+مشاوره
+اکثرا
+افت
+کنگان
+بگذارند
+دامنه‌های
+رحم
+بیدار
+تیپ
+تنفس
+افغانستان،
+میشیگان
+استعمار
+فرخ
+گذرگاه
+توالی
+تایم
+جمله‌ای
+ولادیمیر
+دستوری
+تساوی
+ساختارهای
+جانوری
+قسم
+۱۳۱۶
+هفده
+یقین
+صوفیان
+می‌نویسند
+رومرکز
+بک
+انگشته
+مولف
+نگفتم
+یورش
+ثبات
+بیایند
+بپرهیزید
+وبا
+اس‌جی‌اچ
+جن
+ورزش‌های
+لامرد
+سپیدان
+کبک
+عزت
+افشین
+کامرون
+فیلم‌شناسی
+پاول
+نکنیم
+درگیری‌های
+رخداد
+کیا
+عرف
+شازند
+یکصد
+استهبان
+می‌گیرد،
+نرسیده
+ویژهٔ
+ابتلا
+اینطوری
+گارد
+بزن
+مدتها
+وعده
+شرف
+پيدا
+نیدرزاکسن
+زواری‌جان
+اسدخانی
+هندواروپایی
+تصویرگر
+مختص
+استادی
+هیپ
+امشب
+احیای
+بنو
+امامت
+خونریزی
+سیگار
+کاسه
+غرض
+معتقدم
+ساختم
+صفح
+روایتی
+نمادهای
+متوالی
+خدایی
+نمود،
+عجم
+آبهای
+آمده‌اند
+نموده‌اید
+لاریجانی
+شیوع
+زمينه
+الا
+بیا
+آزمایشگاهی
+آنتن
+قرآنی
+بیستون
+فاجعه
+۱۵۸
+ریه
+انعکاس
+تقلب
+هجدهم
+طبرستان
+تناقض
+مدت‌ها
+علمی،
+تصنیف
+فروغ
+دایرةالمعارف
+آلمریا
+تاسیسات
+گونهٔ
+هیچکس
+ایدز
+آوا
+۱۴۹
+مديريت
+بیاد
+پایگاه‌های
+زیرصفحه‌های
+مقاوم
+گمشده
+نشدید
+نوزاد
+سیف
+دیفرانسیل
+موافقان
+بانه
+فونت
+صفا
+واتیکان
+اصالت
+کتابخانهٔ
+یگانه
+کیت
+ترجیحات
+کنوانسیون
+نانو
+۱۵۳
+آنزیم
+كردند
+تیمی
+۱۸۵
+هستید،
+حوض
+نویسنده،
+ورد
+حسنی
+پديا
+بویین
+مادها
+ناوگان
+بنگاه
+اردلان
+صومعه
+تورنتو
+کارولینای
+۵۰۰۰
+اشکالات
+مسائلی
+انداخته
+نماند
+دستمزد
+بخواهم
+سرقت
+میدانی
+ریتم
+خوبیدگی
+پوستی
+اندی
+الماس
+بزنم
+مقدونی
+هسن
+گروه‌ها
+بروجن
+تگ
+منشی
+ملکی
+تبعیض
+ببین
+افق
+خشن
+کورین
+دوی
+قوام
+ایلینوی
+بچه‌ها
+تکاملی
+دخترش
+برانگیز
+اصطلاحی
+مل
+یکان
+داراست
+عرب‌ها
+ناموفق
+کبد
+کوفی
+رودها
+پشته
+رسالت
+مرتکب
+معروف‌ترین
+نشوند
+نبودم
+بنیانگذاری
+لیبرال
+فرید
+حوضه
+ربع
+نوح
+سیاهه
+تای
+خستگی
+پدری
+برنامه‌ها
+فرستادن
+بیطرفی
+نواب
+نزول
+استیشن
+رادار
+پخش‌کننده
+سازند
+عضلات
+سعیدی
+کوین
+بنویسند
+برم
+بیایید
+حجازی
+شده؟
+تالیفات
+حسینعلی
+نیست؛
+مزاحم
+فروشی
+آموزان
+میکرد
+۲۴۰
+بحث،
+وارنر
+کوری
+واکنش‌های
+فستیوال
+قارچ
+لغت‌نامه
+تاجیک
+شرکتهای
+هروی
+ویژگیهای
+عکسهای
+چارلی
+باشيد
+داشتیم
+بومیان
+باقیمانده
+یافت،
+اشاره‌ای
+فصلی
+عبدی
+بزرگوار
+بیتی
+مُعجَم
+نازل
+امپراتوران
+مهمتر
+کانی‌ها
+۱۸۹۶
+محمدباقر
+شایع
+ادریس
+که‌
+دهندگان
+اعلامیه
+به‌نظر
+داروی
+لیک
+اتوماتیک
+مي‌شود
+فروغی
+برآورده
+بلا
+آدولف
+قشقایی
+تنفسی
+اردوگاه
+زنجانی
+تنه
+گزیده
+مریوان
+پورنو
+کامبوج
+تل‌های
+رمزنگاری
+دامپزشکی
+شاهنشاه
+قرقیزستان
+ارابه‌ران
+نمودم
+ضرر
+بازنگری
+دگرگون
+بررسي
+شده‌بود
+ناپدید
+متاسفم
+نسخه‌ای
+اشنویه
+پیاپی
+عبدالعزیز
+۱۶۸
+اسباب
+نسبیت
+کعبه
+مردم،
+ذوب‌آهن
+آنچنان
+ادرار
+رنسانس
+سوسیال
+دهخدا،
+تختی
+فاطمی
+ماشین‌های
+پاسکال
+مینا
+تابعی
+سایتی
+توانیم
+ترين
+توران
+ادارهٔ
+فهرست‌ها
+خوشی
+معینی
+یادآور
+مخالفین
+دود
+مدام
+انی
+تقاطع
+پتاسیم
+نساجی
+ارد
+اندیمشک
+داده،
+مخالفتی
+دونفره
+اندیشه‌های
+علیزاده
+آجری
+برسیم
+اقدامی
+فقهی
+اشکان
+همبستگی
+فرادیرینه‌سنگی
+گناوه
+کوفه
+۱۸۹۹
+اینصورت
+عبدالرحمن
+لبه
+بی‌پایان
+میدهند
+منشا
+مرحلهٔ
+بیطرف
+کردید؟
+مسخره
+مشخصه
+عضلانی
+اسارت
+عنوانی
+۱۵۲
+ندارم،
+برچسب‌ها
+اچ‌آی‌پی
+منصوری
+۲۱۰
+بینم
+مجنون
+تعاریف
+تعهد
+اقتباس
+جلیل
+می‌کنید؟
+رزن
+مسئلهٔ
+فرستنده
+گان
+قاب
+کمونیسم
+تناسب
+ندای
+توحید
+هواشناسی
+کرده‌اند،
+منتها
+روز،
+شوال
+لیزر
+پس‌از
+دزدان
+دارد؛
+جنگ‌افزار
+جایزه‌های
+واحدی
+تیموریان
+ذكر
+کنده
+ترش
+می‌خوانند
+ریش
+تمایز
+پیشبرد
+زندگانی
+دلتا
+پیش‌از
+نقده
+ایرلندی
+هنرستان
+قبال
+فرصتی
+دودویی
+عليه
+زیباترین
+شاعری
+سرما
+ایلی‌نوی
+شهبانو
+پنالتی
+بهاری
+افتد
+فیروزکوه
+فایده
+۱۶۳
+بروس
+نیسان
+نکردند
+نمیتوان
+۱۶۲
+روباه
+سقراط
+کشته‌شدگان
+اورانیوم
+عملا
+طراحان
+ماهیچه
+سرم
+اوهایو
+علاقمند
+نویسد
+الجزیره
+گذشته،
+مزارع
+گزینش
+جنگهای
+اطلاعی
+نوشته‌ها
+پارلمانی
+۱۱،
+جنابعالی
+اسفندیار
+امیدوار
+ک‌گ
+گازهای
+کبود
+زمین،
+تلگراف
+لئونیداس
+گرمای
+کتابخانه‌ها
+آشوری
+طعم
+راد
+زنانه
+عربی،
+جادو
+حمیدرضا
+جنگ،
+جابجا
+ماکیان
+بیابید
+شکاف
+گلزار
+متفقین
+متاخر
+سایتهای
+بایگانی‌ها
+بهره‌برداری
+جنایی
+کارون
+شهدای
+میامی
+پدیده‌های
+هستم،
+برکلی
+نایین
+ببینند
+استانداری
+۱۶۱
+پسری
+شوالیه
+کت
+شاخه‌ای
+مقاطع
+آنوقت
+اسکو
+۱۸۹۲
+نده
+رسانید
+۲۳۰
+تاسف
+هايي
+پلدختر
+تاجیکی
+جاجرم
+وضع‌کننده
+استر
+همنشین
+زحمتی
+کانادایی
+تبلیغات،
+زهک
+دولت‌های
+ترمودینامیک
+سوری
+خلفای
+درآن
+فراگیری
+ختنه
+امیرآباد
+تروث
+بوم
+زاد
+خنج
+بروم
+سومالی
+جیم
+دیجیتالی
+عفو
+سوشی
+اصفهان،
+بلاندی
+کوچک‌تر
+گمنام
+سکوی
+نزاع
+احتیاط
+گردید،
+بزنند
+علنی
+ویلا
+۱۳۲۶
+الهه
+هدر
+ظلم
+ناو
+می‌کردند،
+الحکمة،
+یاقوت
+حتي
+شرکت‌ها
+تعلیق
+خواستند
+کاروان‌سرا
+نکتهٔ
+رشته‌ای
+باهم
+بپردازند
+درجات
+وجودی
+بودا
+نیوتن
+منطبق
+نصرت
+ال‌جی
+سومی
+فلش
+۱۳۸۵جمعیت
+فریم
+دوما
+ساقه
+اسماعیلی
+دینامیک
+المقحفی،
+المُدُن
+فیلم‌هایی
+فیزیکدان
+محضر
+آخوند
+فراهانی
+صید
+بسا
+الیَمَنِیَة
+بنایی
+۱۷۳
+می‌گوییم
+درآمده
+مورخان
+یونیکس
+جاها
+وام
+کوتوله
+۱۷۶
+ژرفای
+موجودی
+مرادی
+بدنیا
+پمپ
+پرستاری
+می‌شوید
+مناره
+انقلاب،
+برجستهٔ
+جذاب
+نوشتارها
+نمیشه
+مایک
+امیری
+چناران
+ــ
+گردو
+تفویض
+دخیل
+۱۵۹
+بنیادین
+بدیع
+سالیان
+مواضع
+وَالقَبائِل
+۱۶۹
+می‌بیند
+درگذشتهٔ
+داشته،
+قنطورس
+۱۸۹۸
+تصمیم‌گیری
+مشمول
+رودان
+فراگیر
+آمده،
+نفهمیدم
+۱۸۸۹
+شده‌اید
+نفی
+افسردگی
+می‌دانستند
+آلات
+قوت
+دانه‌های
+محمدحسن
+عزيزی
+جامی
+نجم
+طرحی
+گاندی
+جنوبی،
+بصره
+اروگوئه
+شرکت‌ها،
+پورت
+خجسته
+زمانیکه
+ریشه‌های
+فمینیسم
+گاردین
+بایست
+وار
+دیوان‌سالار
+فوتبالیست
+۱۶۷
+آلمان،
+شعله
+آناتولی
+على
+شمالی،
+سیمون
+ظروف
+رستوران
+دایر
+می‌گذارند
+تفاهم
+آناتومی
+گذراندن
+شكل
+مرگ‌ها
+آهنگسازی
+لیتر
+دزدی
+فرموده
+معصوم
+اطاعت
+تارنمای
+فارس،
+پلان
+هانس
+فریدریش
+ملی،
+روحانیت
+اوّل
+نتيجه
+وادار
+صورت،
+۱۳۰۴
+ترتیبی
+مبارکه
+بنیان‌گذار
+۱۷۹
+ژوزف
+اردستان
+افزودم
+مطبوعاتی
+ارز
+جنجالی
+نوازندگی
+سوزان
+دارن
+افتادن
+هایشان
+تحقیقی
+سهند
+سپاسگذارم
+فیزیوتراپی
+محافظ
+ماشینی
+ربر
+یدالله
+میمون
+سیاستهای
+نگارهٔ
+چه؟
+صراحت
+رسته
+تجویز
+توفیق
+مغولستان
+کین
+وال
+ساکورا
+پیشروی
+متوفی
+تازی
+دیلم
+پل‌دختر
+می‌خواست
+صدیق
+نمی‌بینم
+ایلات
+درحالی
+غلات
+نوه
+هاله
+سیستمهای
+کتیبه‌های
+سیال
+منبر
+بیک
+۱۳۱۴
+۱۳۱۸
+حسين
+۱۷۱
+درشت
+سوق
+برنامه‌ای
+گهواره
+دست‌آوردهای
+تعبیه
+رادیوی
+ساسان
+درامز
+۱۲۹۹
+تجسمی
+سیمان
+گنجی
+کشش
+اسلوونی
+ویلسون
+داماش
+إِنَّ
+کارتوگرافی
+کاشت
+دستان
+لید
+نوازندهٔ
+نمی‌شد
+قران
+ایدئولوژی
+کامپکت
+ناغان
+قرائت
+کاراکتر
+خانه‌ها
+شفاهی
+فله‌ای
+شهرسازی
+اعتصاب
+۱۸۱
+ویدیو
+شايد
+ویرایشگر
+پردازد
+داده‌اید
+حاد
+اجتهاد
+مرطوب
+کلماتی
+مهریز
+حلال
+بیافزایید،
+۱۵۷
+همجنس‌گرایان
+لینکی
+تطابق
+باورند
+دالاس
+إِلَّا
+اصولی
+کپی‌رایت
+الفبا
+کیهانی
+تاب
+شرعی
+محتوی
+هانری
+می‌دهند،
+یوگسلاوی
+بگذارم
+تداوم
+گریز
+نشده‌اند
+شناخته‌شده
+انعطاف
+اندک،
+دعوا
+کری
+تبیین
+احساسی
+ساعات
+معاصر،
+پیشوند
+طبع
+میاندوآب
+اخترفیزیک
+مطمئنا
+پرسید
+انگل
+برکناری
+رولینگ
+حفاری
+زیارتگاه
+منتسب
+پیام‌های
+گسسته
+طريق
+باخ
+۱۳۲۳
+کلیساهای
+معصومه
+شهروز
+متناوب
+۱۸۹۵
+پن
+ابراهيم
+۱۳۱۳
+بطوریکه
+رابین
+آموخته
+میدان‌های
+تاریخ‌نگاران
+بکر
+میش
+پخته
+قلمداد
+رویا
+باشید،
+سیستانی
+قومیت
+جرمی
+لوس
+آفرین
+تلف
+خوارزمی
+محتوایی
+سول
+دبط
+جُستارهای
+می‌نمود
+روزنامه‌ها
+یت
+دگر
+بانکی
+سدان
+متغیرهای
+یابند
+بکارگیری
+انتاریو
+کوسه
+۱۶۴
+بلخی
+بیم
+خلخال
+حائری
+۱۸۹۳
+آورده‌اند
+نقطه‌ای
+علمجو
+استیل
+سلولهای
+گوگرد
+میتوانند
+گوارش
+سبزی
+۱۶۰۰
+جوراب۲
+زیرین
+ميشود
+پنبه
+آورد،
+حرفهای
+لنگرود
+فریمان
+سلاح‌های
+میانگین‌جریان
+غبار
+مردانه
+مؤسسهٔ
+اسراییل
+تک‌نواز
+۱۶۶
+لکی
+خبرنگاران
+پالایشگاه
+مصلحت
+۱۷۷
+مجروح
+پرستش
+دوگانه
+مدفون
+ولیعهد
+سرزمینی
+آق‌قلا
+اساسا
+بهر
+ملي
+كنار
+روستاي
+کلاس‌های
+سفره
+نرمال
+وری
+کیف
+۱۸۸۰
+۱۹۸
+زدید
+زراعت
+رهنمودها
+توضيح
+۱۷۲
+۱۹۲
+پدیدار
+وایت
+بمانند
+لرد
+دستم
+ایسلند
+لیقوان
+نیافتم
+باتشکر
+تئودور
+عبادت
+تبديل
+نکردید
+مسلحانه
+دیزنی
+رانش
+فرهنگ‌های
+مخاطبان
+دول
+کتابت
+سلیم
+ایرانی‌تبار
+غلظت
+شونده
+۱۲،
+اوراق
+سامانی
+اقتصادی،
+۲۵۰۰
+شخصیت‌ها
+فحش
+سربازی
+هشداردهنده
+ندرت
+۳۲۰
+می‌شه
+۱۸۹۷
+فروهر
+صلی
+سیوند
+انجمن‌های
+بعلاوه
+ترشح
+فرج
+جاي
+بخیر
+محراب
+کارتان
+هجده
+قریه
+ربیع‌الاول
+ضخامت
+بارندگی
+بح
+نسیم
+زهره
+جادویی
+تالاب
+جنون
+بروی
+۱۳،
+فیلد
+کریسمس
+میزبانی
+می‌کنید،
+آپلود
+برگزیدگان
+یش
+خانواده‌اش
+کریستوفر
+بیننده
+توکلی
+می‌سازند
+لنگ
+تداخل
+مقدمات
+۱۸۹۴
+الوند
+مع
+گناباد
+مزدا
+رکن
+عیلام
+ترقی
+منکر
+معامله
+اینچنین
+کول
+سازمان‌ها
+مأموریت
+موعود
+دولت‌آباد
+بلبل
+طولی
+می‌رسند
+اجاق‌کندی
+ديگري
+ندارد؟
+براین
+مصور
+اعتقادی
+فرخزاد
+درباره‌ی
+خداآفرین
+گفتاری
+خوانی
+پارامترهای
+تهاجم
+آیوی
+توضیحاتی
+بشرویه
+۹۷۸
+کیست
+نداشت،
+شهروندی
+برخي
+۱۵۶
+سمرقند
+نوا
+كمك
+لامپ
+عماد
+رام
+اينکه
+ضمیمه
+بنابراین،
+تصویربرداری
+سیبری
+یوفا
+کلر
+گوجه
+حیف
+سواری
+۱۳۱۲
+طارم
+۲۶۰
+اباد
+عنوان‌های
+مركز
+مقوله
+گوستاو
+مرعشی
+بحر
+تون
+انصار
+جداسازی
+تصفیه
+سازندگان
+ببنید
+محافل
+نقره‌ای
+تیرماه
+پیاز
+سرسبز
+انه
+چشمان
+تایباد
+اشیا
+طرد
+گوهر
+نکن
+هرزگوین
+اقلید
+خاص،
+ثالث
+علی‌رضا
+آنگونه
+مستمر
+عضوی
+هامبورگ
+پورتال
+تویوتا
+رامیان
+هخامنش
+اردل
+قاطع
+گنجینه
+روشنفکران
+تصادف
+۱۹۷
+جزیی
+مؤسس
+روبروی
+آلاسکا
+خوشه‌مهر
+آرد
+صالحی
+سونامی
+کشیش
+پروس
+انحصاری
+کاسته
+دوستانش
+گاوران
+دلالت
+۱۸۴
+اصحاب
+جزیره‌ها
+مهدوی
+آبیک
+افزايش
+مزیت
+جوابی
+صغیر
+منحنی
+رمین
+سانتیگراد
+دبیرکل
+غریب‌دوست
+بنزین
+اپیزود
+استانهای
+بهاءالله
+سپید
+کمونیستی
+سوگند
+شهباز
+اکتشاف
+استحکام
+مفاد
+بسازد
+اسکناس
+۱۴۰۰
+مبدأ
+بخورد
+مناظر
+زا
+پرستی
+تمبکا
+محرمانه
+سکنه
+زیتون
+رومانیایی
+جسارت
+عمومی،
+دات
+آهنی
+بینید
+مخابراتی
+نظرش
+مولداوی
+العظمی
+ولف
+ممکنه
+راننده
+اولاً
+وَمَا
+وسیله‌ای
+موی
+بادلو
+چرب
+مسافت
+مکس
+۱۷۸
+پودر
+عوام
+که،
+پنجم،
+گرگوری
+میسر
+مفصلی
+استبداد
+حیدرآباد
+آلیس
+فیروزه
+ریخت
+اینان
+کروی
+وقف
+شعارهای
+۱۹۶
+سملقان
+فروخته
+۱۷۴
+نبوده‌است
+دیکتاتوری
+میدهم
+ظریف
+معتبرترین
+سیاسر
+ایرادات
+اجماعی
+۱۹۳
+منحل
+زاید
+میخواهم
+صاحبان
+مهلت
+می‌پرداخت
+ماهه
+جری
+بازرس
+وَلَا
+گلشن
+برهنه
+نوشته‌ام
+می‌شود؟
+صخره
+عمو
+ابد
+بیداری
+۱۸۸۸
+۲۷۰
+بعلت
+پنیر
+حاتمی
+خانقاه
+رس
+شکسپیر
+معذرت
+پايان
+ساختگی
+آموختن
+فقدان
+پاسخگویی
+زانو
+كوه
+لزوما
+قمر
+شهریاری
+بيان
+واین
+صورتیکه
+بدنبال
+پاره‌ای
+ارمغان
+می‌شود؛
+شغلی
+دیگ
+عنبرآباد
+امریکایی
+پیشرو
+تجربیات
+علوم،
+پیری‌کندی
+ازجمله
+به‌نام
+صومای
+۳۳۰
+۲۶،
+اسطوره‌های
+منفجره
+دستتان
+رشته‌کوه
+۱۹۵
+برن
+بلده
+شیعی
+رحیمی
+رجایی
+کجور
+۱۵،
+تاون
+آموزگار
+آستارا
+هیل
+ترانه‌ها
+یوری
+کلاله
+محو
+خوانندگی
+زار
+عیب
+افسانه‌های
+پخت
+نامبرده
+پنجشنبه
+سور
+نروژی
+تکنیک‌های
+دریاچه‌های
+مالدیو
+سوسن
+کیسه
+کاوش
+دابودشت
+کردن،
+زندگان
+مقدمه‌ای
+موزهٔ
+۱۸۸
+برپایی
+داگلاس
+فضل‌الله
+زینب
+اللَّهَ
+صحرایی
+کرت
+اذیت
+نمی‌رسد
+آتشفشان
+۱۳۲۱
+بلاروس
+انگ
+ارگان
+بسامد
+نشوید
+بزرگای
+کلارک
+۲۱،
+بشدت
+نقوش
+خوشنویس
+الفبایی
+نخ
+رفیق
+ناراحتی
+رسی
+بخواهند
+طرفداری
+دردسر
+۴۵۰
+۱۸۳
+ایرباس
+پرت
+فرآیندهای
+گردشگران
+مخرب
+میگم
+کارتون
+نوژن
+سفری
+صندلی
+می‌کرده
+نزنید
+ج۱
+میخواهید
+گنگ
+می‌ریزد
+پشتکوه
+ویکی‌پدیاست
+دلاری
+ویکیفا
+خيلي
+بازگشایی
+چشمگیری
+نیتروژن
+بافی
+لانه
+بدید
+آشتیانی
+باشد؛
+محققین
+۲۴،
+یوتا
+طرفه
+توسعهٔ
+کشتی‌های
+۲۰۶
+جاستین
+شوشتری
+اسمیت‌سونیان
+طوطی
+عباسیان
+رده‌ای
+زرند
+می‌رود،
+ابتکار
+دهلران
+بستان
+برجای
+۳۸۰
+رمانتیک
+ترجمه‌های
+کاربرها
+بندری
+پرداختن
+منهتن
+پاتریک
+طناب
+چهارم،
+نتواند
+بور
+دانسته‌های
+روحیه
+میلاد،
+برزنجیر
+مرجان
+دهند،
+شهرستان‌ها
+سپرد
+داران
+استوارت
+دوچرخه
+طراحي
+۱۱۰۰
+خانه‌ای
+نوآوری
+نامنظم
+کامپیوترهای
+دیوانسالاری
+وفادار
+هرودوت
+امسال
+استثنا
+فرانکفورت
+مجالس
+خدمتتان
+کتابداری
+لاین
+پوران
+آنالوگ
+برادوست
+۲۰۸
+شادباش
+می‌شناسند
+بولکیمده
+می‌نویسم
+چالدران
+کهنوج
+تطبیقی
+۱۶،
+دیدگاهی
+منحرف
+شنوایی
+تیز
+تیغ
+موشکی
+پرشیانا
+امیل
+ایزدان
+سه‌گانه
+پنجه
+۱۸۹۱
+۱۳۲۲
+دين
+قبله
+جهنم
+خدماتی
+ببرند
+مأمور
+نیستیم
+کلمه‌ای
+اعتیاد
+فرانکلین
+معجزه
+ذهنم
+بازماندگان
+مصوبه
+کلینتون
+برسند
+معاهده
+نمیکنم
+چندگانه
+شهرستانی
+لاک
+موضوعاتی
+خوسف
+اسک
+خروس
+لتونی
+وات
+کرد؛
+رودکی
+خدمتم
+تاری
+مجلسی
+فهمید
+هفتگی
+کروز
+برگرداننده
+قیصر
+معروفی
+فكر
+نو،
+فضانورد
+فتح‌آباد
+هورمون
+الفاظ
+آمازون
+بیاوریم
+دستهٔ
+می‌کردید
+بینایی
+پافشاری
+بردم
+دیپلماتیک
+سنگینی
+نمره
+غیرآزاد
+فریب
+پذیرد
+حیطه
+اصلی،
+تربیتی
+محال
+ارجمند
+می‌یابند
+فلج
+اربر
+اینجا،
+آوای
+دودانگه
+چاه‌بهار
+همزه
+۲۳۸
+تمبر
+انوشیروان
+متن‌های
+پشتوانه
+عجب‌شیر
+قسمت‌ها
+آشوب
+بدرود
+نظرشان
+ه‌های
+روزتان
+استفان
+گیتاریست
+نشده،
+دینار
+چاره
+تیموری
+زهی
+مغولی
+۲۵۶
+هیوستون
+الموت
+۱۸۷۹
+راگبی
+لوکزامبورگ
+حیث
+عاج
+سخت‌افزار
+رمانی
+نگهبانی
+پتروشیمی
+چادر
+صلیبی
+کنکور
+کانسار
+بلوچ
+زاهدی
+هستید؟
+دوبله
+طیفی
+نشریه‌های
+زنبور
+حزب‌الله
+اخوان
+اجزاء
+ژنو
+دعای
+مزمن
+سخنی
+نهایتاً
+اندرو
+میشوم
+۱۸،
+دارمشترانگ
+می‌دارند
+سه‌شنبه
+حفره
+زرندیه
+ذخایر
+۱۳۱۹
+زنجیر
+سبکی
+قیمتی
+جنیفر
+۲۰،
+تعمید
+آبگرم
+حکمرانی
+پلاستیک
+بی‌نزاکتی
+تماشاگر
+لایحه
+بازه
+تحکیم
+موضعی
+جویی
+محافظة
+شاه،
+ما،
+۳۰،
+آمبرلا
+کلرادو
+هیجانی
+مجتهد
+گیاه‌شناسی
+اضطراب
+جنگ‌افزارهای
+۱۹،
+ادوار
+مسیری
+چمران
+پایه‌های
+گیتاشناسی،
+نمی‌کنید
+گیل
+متین
+آدلر
+۱۷،
+بعدش
+باکس
+یاس
+حکمیت
+کیلوبایت
+بریده
+هموار
+معقول
+کروم
+۱۸۸۶
+غزنوی
+نوش
+بازنشستگی
+گوینده
+یک‌نمونه
+هنر،
+میاد
+عظمت
+جهش
+جانبداری
+شبكه
+آسا
+استاندار
+۲۰۹
+فرانسیسکو
+بریتنی
+محدودیت‌های
+بشکه
+بنگرید
+تاثیرات
+آسفالت
+گیج
+کاروان‌سراهای
+فراموشی
+گلدار
+ترتیب،
+يافت
+همینجا
+بدخشان
+۲۵،
+تمدید
+زيادي
+هستش
+رضا۱۶۱۵
+بودی
+مهرماه
+اسکندریه
+لزوماً
+سیستمی
+هارون
+نگفته
+می‌دانیم
+سایوز
+آن‌را
+نوزده
+بمبئی
+فان
+میدانند
+۱۸۷
+دانستند
+اجاره
+فورت
+مراقب
+نفرت
+نوی
+۲۰۴
+تدریجی
+تهی
+نورآباد
+گزاره
+کلامی
+نتیجه‌ای
+پانک
+هاكل
+عفونی
+بسر
+پیشگامان
+بلاغ
+زئوس
+بريفين
+گزارش‌های
+نمایندهٔ
+سیالات
+۱۸۲
+فارسان
+جلدی
+فلک
+تحقیر
+فهمیدم
+ناتو
+سایرین
+شناور
+انستیتو
+نیکو
+مارکسیسم
+تبعیت
+تفریح
+زبان،
+گلوگاه
+بقیهٔ
+کمپین
+احراز
+بودن،
+محکومیت
+کماکان
+بستری
+تروریست
+سرواژهٔ
+دانمارکی
+آمستردام
+همی
+داوید
+کافیست
+دنی
+رون
+۶۰۰۰
+لابد
+کانتری
+سس
+کسری
+می‌فرمایید
+سیاستمدار
+حریم
+معنویت
+عسکری
+بخشیدن
+محصور
+مدافعان
+گرایش‌های
+واگن
+حجر
+سرداران
+مشهود
+یافتم
+تنسی
+نهر
+دارالفنون
+نمايش
+بسياري
+سابقهٔ
+یتیم
+توپولوژی
+۱۴،
+نگارشی
+جمعيت
+تنبیه
+کیو
+سقط
+شریفی
+کما
+میکروبیولوژی
+دیابت
+تاتنهام
+منقرض
+تاتی
+محمددین
+انگليسي
+فارسی‌سازی
+زمینهای
+شهدا
+۰۸،
+متکی
+کوه‌ها
+دزد
+کنایه
+مشایخ
+ارزان
+ماسه
+هرمان
+تنظیمات
+اونجا
+خار
+هیلاری
+چنار
+خزانه
+شکاری
+عجایب
+رنو
+قراردادن
+جابر
+سروستان
+مستطیل
+مجموعه‌ها
+بهمیی
+یکسال
+سرخرگ
+نادرشاه
+لیاقت
+دوستار
+وارده
+کاستیا
+لرزه
+اى
+بجا
+نم
+مغولان
+امارت
+کشاورزان
+طبی
+کجاست؟
+نبح
+نمایم
+للطباعة
+بکنند
+داستان‌ها
+آمیخته
+تاريخي
+اندازه‌ای
+پیکار
+مستعمره
+کوهپایه
+تصدیق
+۱۳۱۵
+فیلترینگ
+۰۹،
+آدینه
+توبه
+بصری
+بکنیم
+هوتک
+فیلم‌نامه
+پشتون
+زمره
+حبیبی
+اسکندری
+نیایش
+هائی
+رقابت‌های
+داوطلب
+ازش
+بنظرم
+دلیجان
+رضی
+مصاحب
+پرون
+بازگو
+آگهی
+قولی
+سیسیل
+انگلیسی‌ها
+مکاتب
+حبیب‌الله
+سانسکریت
+توکل‌آباد
+نموده‌اند
+حیوانی
+پروژه‌ها
+گیتی
+فالتز
+سنگسار
+بخت
+میلانی
+مارکوس
+نید
+شدیم
+۲۲۴
+مش
+فصول
+کتابش
+می‌خواهیم
+مشی
+آنی
+مادهٔ
+میکردند
+یکا
+طلبان
+عهدنامه
+الملل
+ارکان
+کاربریتان
+جلال‌الدین
+ایرونی
+یونس
+آبراهام
+فرشتگان
+فارسی‌زبانان
+۲۰۳
+۳۵،
+ناتمام
+موظف
+ایت
+می‌زنم
+ییلاق
+منی
+كم
+گریه
+بسازیم
+سیبک
+انجا
+موفق‌ترین
+۱۳۰۷
+ثروتمند
+گریخت
+زمان‌دار
+تروا
+ژرمنی
+برنارد
+تشكر
+ژنریک
+راهبردی
+گره‌های
+پارسی‌گوی
+بندهای
+مبادله
+اسفندیاری
+سرتیپ
+خوارزم
+کلاغ
+ياد
+ايراني
+نجف‌آباد
+سولفات
+كامل
+ناظری
+شهرستانهای
+أَنْ
+میگ
+پادگان
+مرتضوی
+زياد
+کلود
+مقاصد
+بهارستان
+دیکتاتور
+باستان،
+۳۱،
+اسکای
+الکلی
+میباشند
+پارتی
+بیاورند
+لایه‌های
+پرتقال
+آمیزی
+۴۰،
+۱۸۶
+رستاخیز
+خرگوش
+فیبر
+لیبرالیسم
+مخترع
+تعمیم
+برمی‌گردد
+تل‌آویو
+خورش
+مولد
+ستم
+باغات
+نژادهای
+ضربات
+آنست
+ارواح
+جوار
+اپرای
+تحتانی
+آنتوان
+زحمتش
+۱۸۸۲
+بازگشتی
+رفت،
+۱۸۹
+هوگو
+گیلاس
+۲۰۵
+دستاوردهای
+قضائیه
+۴۰۰۰
+مستقلی
+رعنا
+بخوان
+۵۶،
+سوزی
+تلاشی
+هرکسی
+میلی‌متر
+هفته‌نامه
+برومند
+کباب
+سرمایه‌گذاری
+پلاتین
+دنیس
+وگاس
+قرآن،
+نصرت‌آباد
+۲۲۵
+۱۹۱
+بافق
+ژاله
+آبریز
+صدد
+املاک
+مقاله‌
+بوانات
+پژو
+زمان‌ها
+کامیاران
+پگاه
+۲۰۲
+حرف‌های
+ترغیب
+حک
+مسطح
+دی‌وی‌دی
+جانبه
+سفیران
+غدد
+هستند؟
+مدرسه‌های
+۵۲،
+منبع‌دار
+چاله
+نائین
+مدير
+عکاسان
+آب‌خورده
+فیات
+خبرنامه
+مشهدی
+استرالیایی
+سیامک
+بگیر
+شایان
+درسته
+نامند
+ویرایشهای
+گل‌ها
+مایا
+گروه،
+آتشفشانی
+کرده‌است،
+نیمهٔ
+آزادشهر
+رانده
+علاقه‌ای
+ثریا
+متشکر
+ولت
+فرزانه
+صورت‌های
+دانشگاههای
+وز
+ویدئوی
+جنازه
+برتون
+جلوه‌های
+تغییرمسیرهای
+بیانیه‌ای
+دون
+نبوی
+یک‌بار
+رک
+حزب‌های
+مدارهای
+میگویم
+كنيم
+معلق
+تماشاگران
+نش
+نصیر
+۱۹۴
+رضاخان
+گردد،
+کنسول‌های
+قسمتهای
+شورشیان
+دقیق‌تر
+مداخله
+علاءالدین
+استنباط
+مصرفی
+باردار
+اهورامزدا
+ادبيات
+باهنر
+مقرر
+عزاداری
+كلمه
+خونین
+محدودی
+نمی‌دارد
+ذوق
+پرسش‌های
+بریم
+قشر
+۳۸،
+صالح‌آباد
+محسنی
+تخلص
+شکل‌های
+شوی
+رنگ‌ها
+توربین
+مگابایت
+فسفات
+واجد
+اهانت
+محفل
+برحسب
+گیگا
+گيرد
+۱۸۷۰
+صنفی
+تن‌تن
+برگردانده
+دایناسور
+لای
+می‌بینیم
+۰۴،
+فرمائید
+سیارات
+۵۱،
+تص
+سرودهای
+معترض
+ممكن
+متا
+می‌شویم
+ثلاث
+گفته‌های
+بی‌طرفانه
+هاپ
+نهان
+ادارات
+عجیبی
+جنایات
+دستورالعمل
+پارا
+نهادند
+ام،
+فتنه
+فواصل
+۱۸۵۰
+توریستی
+مرمر
+دیتابیس
+۴۲،
+کلیات
+۱۸۸۳
+لنین
+بلكه
+کاتوزیان
+میسیسیپی
+معاویه
+یوونتوس
+کشاورزی،
+هوافضا
+كوخرد
+فاریاب
+محيط
+نکنید،
+میترا
+رنگین
+آلپ
+آلومینیوم
+ملودی
+سیاستمداران
+گمر
+اسکان
+مختصری
+قشون
+جوادی
+رباتی
+۲۱۱
+جایز
+۲۷،
+محمودی
+كاربران
+یافته‌اند
+بگذریم
+محوری
+زمان‌های
+۲۲،
+انصراف
+میلا
+ساير
+۲۱۴
+تصریح
+۳۶،
+۲۸،
+آلباسته
+وظیفهٔ
+آذرشهر
+خدمه
+بارانی
+فیزیک‌دانان
+۱۸۸۴
+تماشای
+۱۳۱۱
+نويسنده
+علامرودشت
+افزاری
+گلشیری
+عملیات‌های
+داس
+ناخواسته
+هوتن
+واسه
+ثانیا
+لینه
+سنج
+اروپا،
+ایلیا
+بازمانده
+بشریت
+شناسی،
+۱۷۰۰
+کالیفرنیا،
+نکرده‌ام
+سیلیکات
+آزاده
+کامنت
+یونیکد
+آمدم
+احضار
+توده‌ای
+فرایندهای
+بیماری‌ها
+آخه
+تبلور
+۰۷،
+۲۰۷
+مونوبوک
+تصمیمات
+اختراعات
+جشنوارهٔ
+مشاهدات
+ریزشگاه‌ها
+۲۹،
+فیلادلفیا
+یزید
+سکولار
+خشایارشا
+سنتور
+محافظه
+کاپ
+نادرستی
+علی،
+محیط‌های
+منفرد
+اهتمام
+القاعده
+علاقهٔ
+لرزش
+عصبانی
+پسند
+لیل
+۲۲۶
+جدای
+جواهر
+ژولیوسی
+کوچک،
+شمیرانات
+بخوانند
+ربیع‌الثانی
+۵۰،
+۲۳۵
+توپخانه
+نیکلاس
+ویستا
+فردیناند
+۲۸۰
+تشییع
+نمیکند
+موسیقی،
+نیرومند
+۱۸۷۸
+غفاری
+بفتا
+هویدا
+صدیقی
+سلیمانی
+سياسي
+شهرضا
+جوانرود
+انتشاراتی
+شخصه
+۵۵،
+آسیاب‌های
+خوب،
+راههای
+والنشر
+حماسی
+عکسها
+۲۱۲
+۱۸۸۵
+تعریفی
+قاسمی
+مصادف
+مفرغ
+گشتاور
+۱۸۷۵
+شکل‌گیری
+طهماسب
+موجودیت
+ستاره‌ها
+آوردید
+سازه‌های
+۲۱۷
+ببریم
+ارسنجان
+بیدگل
+مگه
+عبادی
+فایل‌های
+۱۸۷۶
+تبریز،
+رهنما
+سپر
+قاره‌ای
+وو
+جعبه‌ای
+دانش‌نامه
+اجتماعي
+هیجان
+کارتر
+نرسید
+۳۳،
+کارم
+نمی‌شود،
+نسل‌کشی
+نمونه،
+صمد
+دریک
+میله
+پلاسما
+زاغ‌ده
+داروین
+۴۴،
+ویس
+قاچاق
+املای
+نامیدن
+گنجانده
+شادگان
+نی‌بید
+۲۲۲
+تسهیل
+هلن
+ناپدیدشدن
+خط‌ها
+ابلاغ
+شمع
+بازی،
+فندقاع
+جوهر
+پترزبورگ
+هخ
+سکو
+۴۱،
+یاسر
+۵۷،
+مستلزم
+آلبومی
+کلک
+ضخیم
+پاشا
+۲۳،
+۱۸۸۱
+دی‌ان‌ای
+حساب‌های
+غلامعلی
+خواندند
+معلمان
+همیلتون
+مداری
+مست
+تصویرها
+اندیشهٔ
+شدیداً
+دیواندره
+کنن
+بشوند
+نیامد
+مانگا
+۱۳۱۷
+چسب
+شجاعت
+مشتاق
+ایرا
+دانا
+بریتیش
+ویکی‌پدیاها
+مهم‌تر
+روبرت
+کافه
+ئی
+ارضی
+دست‌کم
+دندان‌پزشکی
+مهرآباد
+كننده
+رضوانشهر
+پراگ
+پال
+فرسایش
+درگاه‌ها
+راور
+میکروسکوپ
+فشارهای
+آرزومندم
+مصاحبه‌ای
+ویولن
+دریافت‌کنندگان
+نجیب
+سئول

+ 10000 - 0
hbfreetypefont.mod/harfbuzz/perf/texts/hi-words.txt

@@ -0,0 +1,10000 @@
+के
+में
+की
+है
+का
+और
+से
+को
+है।
+एक
+पर
+श्रेणी
+वार्ता
+भारत
+हैं
+भी
+यह
+शीर्षक
+पूर्व
+लिए
+गाँव
+ईसा
+उत्तराखण्ड
+किया
+ने
+इस
+संवत
+कि
+हिन्दी
+जो
+।
+जाता
+गया
+या
+जिले
+वर्ष
+जिला
+नहीं
+कर
+साँचा
+ही
+हैं।
+करने
+हो
+रूप
+था
+साथ
+द्वारा
+जन्म
+तहसील
+फ़िल्म
+होता
+तथा
+बाद
+विकिपीडिया
+आधार
+अन्य
+प्राचीन
+कुछ
+सदस्य
+अपने
+इसके
+प्रदेश
+तो
+एवं
+तक
+चित्र
+बाहरी
+राज्य
+जा
+प्रकार
+सरकार
+नाम
+दिया
+होती
+स्वागत
+कई
+वह
+बिहार
+करते
+सप्तर्षि
+जैसे
+थे
+समय
+अनुसार
+आदि
+वे
+सकते
+अधिक
+वाले
+किसी
+आधिकारिक
+सकता
+कड़ियाँ
+भारतीय
+उत्तर
+मण्डल
+हुए
+न
+जाती
+प्रखण्ड
+हुआ
+क्षेत्र
+लेख
+द
+बनी
+होने
+उसके
+करता
+इन
+अंग्रेज़ी
+संदर्भ
+थी
+था।
+शक
+कारण
+भाषा
+बहुत
+स्थित
+पहले
+उनके
+प्रसिद्ध
+सहायता
+जब
+दो
+अपनी
+कोई
+सबसे
+अलावा
+स्थान
+होते
+कम
+विश्व
+लिये
+ये
+जाने
+बारे
+लेकिन
+प्रयोग
+उन्होंने
+राष्ट्रीय
+वर्षों
+कहा
+पृष्ठ
+गए
+रहा
+आप
+देखें
+व
+एक्स्प्रेस
+तरह
+मे
+करना
+शामिल
+सभी
+प्रमुख
+आंध्र
+इसी
+अमेरिका
+प्राप्त
+करें
+अन्तर्गत
+इसे
+माना
+सितंबर
+उस
+५७
+इसका
+जानकारी
+नगर
+मुख्य
+हुई
+शिक्षा
+उन्हें
+संस्कृत
+कलियुग
+बीच
+गई
+विक्रमी
+रहे
+उपयोग
+मार्च
+पोर्टल
+काम
+वेबसाइट
+जनवरी
+कुमाऊँ
+उसे
+शहर
+जाते
+उनकी
+लोग
+जिसमें
+देश
+दी
+संघ
+थे।
+भाग
+लोगों
+जीवन
+१
+कार्य
+जी
+फिल्म
+विशेष
+बार
+ओर
+२
+इतिहास
+कभी
+दोनों
+अब
+निर्माण
+२००९
+पुरस्कार
+वाली
+शब्द
+पताका
+अधिकांश
+चिह्न
+विकास
+धर्म
+केवल
+लिया
+ए
+दक्षिण
+पुराने
+जुलाई
+यहाँ
+नया
+स्टेशन
+फिर
+लगभग
+संयुक्त
+अलग
+आन्ध्रप्रदेश
+गढ़वाल
+स्थल
+दिल्ली
+ई
+आरम्भ
+अपना
+जून
+विस्तृत
+यदि
+प्रान्त
+इसकी
+सूत्र
+शुरु
+मंदिर
+जालपृष्ठ
+जिसे
+घटनाएँ
+कृषि
+दौरान
+करती
+निधन
+दिन
+संगीत
+यहां
+तीन
+क्योंकि
+इसमें
+साहित्य
+ऑफ़
+मूल
+भूगोल
+॥
+पास
+पटना
+नए
+हालांकि
+सिंह
+प्रदर्शित
+प्रतिरूप
+अप्रैल
+बात
+विषय
+टेनिस
+२०१०
+प्रतियोगिता
+प्रचलित
+कहते
+विज्ञान
+विभिन्न
+अगस्त
+ऑफ
+पद्धति
+छत्तीसगढ़
+सन्
+जाना
+शुरू
+बना
+समूह
+अनेक
+थी।
+ता
+प्रामाणिक
+मध्य
+रही
+सूची
+संख्या
+व्यक्ति
+ऐसा
+गणना
+प्रति
+आज
+तब
+उनका
+क
+इलाहाबाद
+ऐसे
+मैं
+काल
+हम
+युद्ध
+गया।
+वाला
+श्री
+आदर्श
+स्थिति
+सी
+सकती
+दिसंबर
+प्रदान
+विक्रम
+विश्वविद्यालय
+रेलवे
+बड़े
+सामूहिक
+किया।
+किए
+राज्यक्षेत्र
+यातायात
+उन
+चार
+उपरोक्त
+दर्शाता
+बन
+अर्थ
+अलीगढ़
+दूसरे
+तौर
+गयी
+५८
+अन्तर
+उत्तरा
+राजा
+प्रभा
+क्या
+घटित
+मानकर
+विभाग
+कैलेंडर
+देने
+बनाने
+खेल
+प्रथम
+हिंदी
+इन्हें
+एकल
+उसकी
+एंड
+मसीह
+अथवा
+अमेरिकी
+जहां
+उदाहरण
+कलाकार
+निकाले
+आवश्यक
+७८
+महत्वपूर्ण
+पुरुष
+मई
+नदी
+जिसके
+प्रभाव
+आम
+जूलियन
+योगदान
+किये
+अधारित
+ले
+अधार
+इस्तेमाल
+सेवा
+३०७६
+जिसका
+३१०२
+पंचाग
+६६७६
+चर्चा
+भोजपुरी
+कैसे
+उर्दु
+कलेण्डर
+करके
+चाहिए
+स
+कला
+उपलब्ध
+जनसांख्यिकी
+साल
+काफी
+फर्रुखाबाद
+आगरा
+कंपनी
+३
+उच्च
+अक्तूबर
+आ
+मेरा
+स्तर
+नवंबर
+नीचे
+देता
+अध्ययन
+जारी
+कोड
+पहली
+प्रणाली
+अगर
+ओपन
+ध्यान
+उसका
+नामक
+बड़ी
+जल
+नैनीताल
+अक्सर
+अंग्रेजी
+सरकारी
+वर्तमान
+रंग
+जिससे
+मेल
+पुलिस
+रखा
+प्रत्येक
+हर
+बनाया
+ट्रेन
+सामान्य
+दुनिया
+भूमिका
+लिंक
+दे
+जबकि
+सन्देश
+शरीर
+पता
+भागलपुर
+विचार
+जहाँ
+लगा
+लेकर
+बड़ा
+वर्ग
+आगे
+छोटे
+तथ्य
+समाज
+पानी
+इससे
+उसने
+देशों
+महिला
+इसलिए
+देना
+पर्यटन
+एस
+परिणाम
+अल्मोड़ा
+सब
+स्थापना
+बाह्य
+स्थापित
+पौड़ी
+दल
+माध्यम
+आधारित
+पश्चिम
+प्रदर्शन
+सर्वश्रेष्ठ
+चीन
+शक्ति
+बाहर
+बी
+ऊपर
+बेगूसराय
+उत्पन्न
+हेतु
+डी
+आशीष
+अतिरिक्त
+समान
+वीं
+हिन्दू
+गये
+परिवर्तन
+आधुनिक
+लिखा
+कुमार
+देखा
+अंत
+मार्ग
+मानव
+रेल
+अक्टूबर
+आपको
+घर
+प्रश्न
+दूर
+कन्नौज
+भटनागर
+सामाजिक
+प्रकाशित
+अभिनेता
+देते
+कुल
+अभी
+जिस
+होना
+आई
+४
+पूरी
+संबंधित
+रहता
+ज्ञान
+ब्रिटिश
+कृपया
+हस्ताक्षर
+व्यक्तिगत
+बिना
+नई
+रोग
+१०
+दशक
+अधिकार
+परिवार
+शैली
+लेखक
+संस्करण
+जिनमें
+सेना
+संबंधी
+औरंगाबाद
+प्रक्रिया
+यात्रा
+२००८
+नये
+आवश्यकता
+ऐसी
+स्वयं
+होगा
+संबंध
+चिकित्सा
+मात्रा
+परियोजना
+प्रबंधक
+१५
+विकसित
+संदेशों
+होकर
+प्रकाश
+पहाड़ी
+पहला
+आकार
+सुधार
+जगह
+पन्ना
+सही
+मैथिली
+तैयार
+नवम्बर
+पिता
+मुक्त
+क्षेत्रों
+रचना
+१२
+२००७
+पूरा
+पी
+संस्थान
+५
+लोक
+१३
+चरित्र
+तुलना
+हुआ।
+लाल
+उत्पादन
+जनसंख्या
+रहते
+उसी
+इनके
+ा
+१४
+संदेश
+ज्यादा
+शताब्दी
+मृत्यु
+साधारण
+पाकिस्तान
+मास्टर्स
+दूसरी
+पुस्तक
+भगवान
+इनमें
+पूर्ण
+लाभ
+टीम
+बैंक
+अवधि
+भिन्न
+खिलाड़ी
+ली
+सदस्यों
+आने
+प्रयोक्ता
+कार्यक्रम
+सीमा
+समर्थन
+संस्कृति
+े
+अंतिम
+स्कूल
+बने
+विकि
+टी
+अ
+पाया
+नही
+र
+सदी
+फरवरी
+मुझे
+सन
+परिचय
+लेने
+मेरे
+पार्टी
+उत्तरी
+लिखने
+१८
+दिसम्बर
+राम
+भर
+विशिष्ट
+मी
+क्षमता
+प्रयास
+सहित
+पश्चिमी
+सिद्धांत
+दर्शन
+सभा
+किंतु
+वर्णन
+विधि
+श्रृंखला
+बजे
+संगठन
+गीत
+एम
+बेबल
+राजधानी
+प्रभावित
+पौडी
+ठीक
+सुझाव
+गति
+प्रबंधन
+व्यापार
+सामग्री
+ना
+एन
+दृष्टि
+दिया।
+पद
+ब्रजभाषा
+म
+सूचना
+शोध
+नामांकन
+अवधी
+लोकप्रिय
+आन्ध्र
+हाथ
+रहने
+विस्तार
+ऑस्ट्रेलिया
+वृद्धि
+फ़रवरी
+११
+जैसा
+आर
+कहानी
+व्यवस्था
+क्रिकेट
+बागेश्वर
+पृथ्वी
+चमोली
+गांव
+युग
+यौगिक
+कहीं
+पूर्वी
+२०
+सुरक्षा
+मुखपृष्ठ
+स्पष्ट
+१६
+मिलता
+देवी
+यही
+बुंदेली
+सामने
+प्रवेश
+यूरोप
+रखने
+दिए
+जॉन
+जिन्हें
+दूसरा
+पूरे
+स्थानीय
+आते
+नियंत्रण
+चीनी
+दिखाई
+प्रकाशन
+ऊर्जा
+प्राकृतिक
+की।
+जैन
+लगता
+बनाए
+अमरीकी
+कवि
+व्यापक
+दर
+वजह
+वहाँ
+परीक्षण
+लंदन
+प
+ी
+बदल
+जाए
+अदिलाबादु
+शासक
+खोज
+द्वितीय
+बस्तर
+मदद
+योजना
+ब्रिटेन
+प्रस्तुत
+जे
+धार्मिक
+आर्थिक
+सहायक
+लेखन
+शुरुआत
+मिल
+डॉ
+प्रौद्योगिकी
+शासन
+स्रोत
+रायगढ़
+वैज्ञानिक
+कमी
+आपके
+मिनट
+पत्र
+निर्वाचन
+रक्त
+ऑफिस
+गूगल
+संग्रह
+उद्योग
+राष्ट्र
+एशिया
+सांस्कृतिक
+पदार्थ
+इनका
+आपका
+मुंबई
+हिस्सा
+दृष्टिकोण
+उद्देश्य
+वी
+ह
+दूरी
+आता
+अनुवाद
+वो
+पीछे
+भूषण
+क्रिया
+स्वास्थ्य
+पैदा
+केंद्र
+२०११
+अच्छे
+पद्म
+शब्दों
+ऐतिहासिक
+गैर
+पिथोरागढ
+छोटी
+६
+सार्वजनिक
+कपूर
+प्रेम
+मुंगेर
+रहती
+चैनल
+समस्या
+कनाडा
+अंतर्गत
+देवनागरी
+राष्ट्रपति
+जिसने
+बैंड
+साम्राज्य
+कॉलेज
+मगही
+प्रयुक्त
+पुत्र
+अनुसंधान
+पहचान
+निर्मित
+किमी
+बंद
+प्रतिशत
+लगे
+अंतर्राष्ट्रीय
+ताकि
+भूमि
+मानक
+इंग्लैंड
+सके
+प्रारंभिक
+सन्दर्भ
+थीं
+अंगिका
+दिशा
+जर्मनी
+१९
+संकेत
+बच्चों
+द्वीप
+समाचार
+अफ्रीका
+घोषणा
+रह
+बंगाल
+भाषाओं
+घंटे
+हाल
+राजस्थान
+वहां
+आया
+उपन्यास
+कानून
+दिनों
+अभिनेत्री
+खिलाफ
+सदर
+अनुमति
+हवाई
+टीवी
+समाप्त
+मीडिया
+उपचार
+हमारे
+जनता
+नियम
+संक्षेप
+मन
+मिलियन
+चौपाल
+उपकरण
+राज
+भीतर
+चेन्नई
+२८
+कृष्ण
+क्लिक
+३०
+कविता
+कथा
+सूर्य
+प्रेस
+वीडियो
+स्वतंत्रता
+वन
+राजनीतिक
+आमतौर
+देती
+दृश्य
+न्यू
+योग्य
+लागू
+मिला
+बताया
+मैच
+जिसकी
+सा
+मीटर
+नेटवर्क
+रोचक
+भोजन
+हूँ
+मौजूद
+धीरे
+१७
+संभव
+माता
+नृत्य
+७
+महत्व
+परन्तु
+आशा
+डॉलर
+शायद
+आयोजित
+सम्मान
+युगल
+कांग्रेस
+सफल
+उर्दू
+उनमें
+वापस
+चाहिए।
+दें
+मनुष्य
+लाख
+महान
+निजी
+उल्लेख
+जैसी
+इनकी
+व्यवहार
+पन्ने
+नीति
+जाति
+एल
+पोस्टर
+विशाल
+बल्कि
+संचालित
+देखने
+विवाह
+अच्छा
+ख़ान
+२६
+इ
+कृष्णा
+वंश
+जापान
+केन्द्र
+मेरी
+तमिल
+देख
+विजेता
+वेब
+शिव
+सिर्फ
+न्यूयॉर्क
+भाई
+यूरोपीय
+राजीव
+प्रयोगस्थल
+उत्पाद
+मंच
+पांच
+०५
+पंजाब
+०४
+राजमार्ग
+मॉडल
+कंप्यूटर
+स्वीकार
+अंतर
+कार्बनिक
+सक्रिय
+परंतु
+लखीसराय
+किलोमीटर
+यमकेश्वर
+चला
+आलेख
+पड़ता
+उसमें
+ज्ञानसन्दूक
+आपने
+हमें
+मान
+इंजन
+तहत
+पत्रिका
+अवस्था
+९
+चम्पावत
+ं
+सहयोग
+मौलिक
+मामले
+अच्छी
+तिथि
+आरंभ
+स्वतंत्र
+बल
+बाजार
+८
+प्रारंभ
+मूल्य
+सरल
+वास्तव
+यू
+उससे
+तुम
+मैंने
+पुनः
+सागर
+पक्ष
+०६
+छोड़
+खाना
+अनुभव
+टू
+तरफ
+बस
+विजय
+महाराष्ट्र
+समुद्र
+उचित
+रेडियो
+चल
+हटाने
+खुद
+समीक्षाएँ
+जीव
+तेल
+दिल
+उम्र
+जर्मन
+ग्रंथ
+रूस
+संपर्क
+बौक्स
+रखें
+गंगा
+एल्बम
+राय
+पाठ
+हासिल
+निश्चित
+सीमित
+सात
+प्रांत
+गई।
+नेपाल
+दक्षिणी
+काव्य
+निर्णय
+छोटा
+२५
+डिजाइन
+रात
+हों
+लगाया
+वास्तविक
+पूछे
+ज्ञात
+प्रकृति
+कार
+गए।
+निर्वाचित
+तरीके
+त
+ज
+चुनाव
+किन्तु
+बढ़
+२१
+हो।
+जीत
+विपरीत
+दस
+वर्मन
+औसत
+इंडिया
+सम्मानित
+२२
+नाटक
+अधिनियम
+वस्तु
+संरचना
+मत
+सर्वाधिक
+लेखों
+विश्वास
+मास
+संकिपा
+वायु
+शीघ्र
+घटना
+निम्न
+विरोध
+सप्ताह
+स्वरूप
+प्रवेशद्वार
+सितम्बर
+गुरु
+सॉफ्टवेयर
+निर्धारित
+विद्युत
+रक्षा
+पूर्णिमा
+पड़ा
+बावजूद
+बेहतर
+वर्ल्ड
+चुका
+भारी
+मगध
+समुदाय
+क्यों
+ऑस्ट्रेलियाई
+जनगणना
+लीग
+अंक
+मिलती
+भागों
+बाल
+भेज
+कप
+कोरिया
+कर्नाटक
+मात्र
+हुई।
+अत्यंत
+तत्व
+महाभारत
+ओ
+अरब
+पूजा
+निर्माता
+रोमन
+विदेशी
+अल
+पर्वत
+पिछले
+इनसे
+पार्क
+स्थानों
+जिन
+धारा
+चुके
+मिली
+जाकर
+बदलने
+स्वामी
+सम्मेलन
+२३
+बनाये
+अल्मोडा
+शो
+जंक्शन
+मन्दिर
+गलत
+सफलता
+लिपि
+पाए
+योग
+निर्भर
+सिस्टम
+प्रसाद
+गांधी
+प्रचार
+फ्रांस
+वर्मा
+जिन्होंने
+रहें
+बौद्ध
+बच्चे
+आंदोलन
+एच
+तंत्र
+मोबाइल
+कोशिश
+अध्यक्ष
+गैस
+प्यार
+सारे
+ल
+लक्ष्य
+अवश्य
+लेते
+आसपास
+चरण
+पर्याप्त
+आयु
+शर्मा
+कार्बन
+सुरक्षित
+कोलकाता
+शीर्ष
+२७
+मै
+समिति
+धन
+विवरण
+सुविधा
+खान
+आती
+जिनके
+यद्यपि
+मामलों
+प्रशिक्षण
+सिटी
+कैंसर
+पात्र
+इतना
+रिपोर्ट
+नेतृत्व
+महिलाओं
+फल
+महीने
+सड़क
+देव
+मान्यता
+क्लब
+अनंतपुर
+क्रम
+य
+बजाय
+साँचे
+उप
+२४
+विश्लेषण
+आनन्द
+यूनानी
+चाहते
+राज्यों
+फाइनल
+अवार्ड
+जुड़े
+अत्यधिक
+तकनीक
+अज्ञात
+निकट
+सेंट
+चलता
+रेखा
+निर्देशक
+इंडियन
+मानते
+देवता
+जांच
+हे
+पत्नी
+इंटरनेट
+केरल
+जोखिम
+रिकॉर्ड
+बदलाव
+डिग्री
+प्रतीक
+जाएगा
+अतः
+पालन
+खंड
+विष्णु
+भौतिक
+जिनका
+अकादमी
+होगा।
+गुण
+वित्तीय
+क्षेत्रफल
+कर्नूलु
+करें।
+भाव
+तापमान
+०७
+अनुमान
+डे
+अमरीका
+रासायनिक
+च
+ग
+अभिनय
+पत्थर
+खाता
+किस
+गणराज्य
+टेस्ट
+चोर
+इत्यादि
+शुद्ध
+होगी
+भिकियासैण
+संघर्ष
+अंतरराष्ट्रीय
+लगातार
+माँ
+उल्लेखनीय
+रखते
+लक्षण
+जेम्स
+ग्रह
+प्राय
+वही
+औद्योगिक
+संक्षिप्त
+२००६
+विमान
+टिप्पणी
+नागरिक
+ध्वनि
+याद
+संचार
+बराबर
+प्रधान
+अमेरिकन
+पारंपरिक
+युक्त
+अत
+पुरी
+प्रतिक्रिया
+शाह
+चक्र
+अवसर
+हमेशा
+शारीरिक
+हंडिया
+आबादी
+तट
+लाइन
+विकल्प
+अंग
+लोकसभा
+खाद्य
+पर्यावरण
+संसार
+विवाद
+बनने
+करीब
+व्यक्तियों
+०
+वैदिक
+बिक्री
+ब
+निम्नलिखित
+कोशिका
+पार
+परमाणु
+भवन
+समझ
+नष्ट
+स्वर
+दुर्ग
+जितना
+प्रकट
+फॉर
+विमानक्षेत्र
+रख
+रुप
+शहरों
+तकनीकी
+लखनऊ
+मुद्रा
+हिस्से
+झील
+आयोजन
+इकाई
+मील
+समस्त
+संरक्षण
+अंदर
+संस्था
+परंपरा
+सतह
+कार्यों
+विद्यालय
+संसद
+अभियान
+सिद्ध
+मुख्यालय
+प्रस्ताव
+सीधे
+सर्वोच्च
+डालकर
+वाहन
+गुजरात
+उपयुक्त
+राशि
+बोली
+सक्षम
+अधिकतर
+नेशनल
+प्राथमिक
+मौत
+इसने
+गणित
+अली
+व्यवसाय
+हवा
+मिट्टी
+अगले
+फिल्मों
+चले
+डेविड
+मिलते
+बनाई
+महल
+आक्रमण
+रे
+राजनीति
+मंत्री
+गंभीर
+शाखा
+अम्ल
+हटा
+तटस्थ
+भविष्य
+ईश्वर
+आए
+वि
+दावा
+प्रसारण
+जीवित
+कड़ी
+रखें।
+लिमिटेड
+अन्दर
+क्रांति
+लिखे
+मैदान
+धातु
+एफ
+सम्बन्ध
+विलियम
+हृदय
+संभावना
+वातावरण
+न्यायालय
+लगाने
+सैन्य
+परिवहन
+परिषद
+चारों
+पवित्र
+योगदानकर्ताओ
+गुणवत्ता
+खगड़िया
+शेष
+करे
+ला
+युवा
+नियमित
+ऑन
+सर
+पसंद
+दबाव
+ईरान
+लागत
+०९
+०८
+२९
+अधिकारी
+उनसे
+कहना
+बोर्ड
+ग्रहण
+अशोक
+स्टार
+जान
+दिखाया
+ग्राम
+स्पेन
+नीतियाँ
+सभ्य
+०००
+समारोह
+संविधान
+इटली
+आठ
+संग्रहालय
+तर्क
+दूतावास
+पाने
+लिया।
+पाँच
+थलीसैंण
+लगी
+जन
+ताप
+परिणामस्वरूप
+लॉग
+लिखी
+रॉक
+कार्ड
+प्रेरित
+आगंतुकों
+फूल
+तेलगू
+लेता
+मिले
+रोगी
+आक्षेप
+जरूरत
+गठन
+व्यक्त
+भुगतान
+मौसम
+मीडियाविकि
+अन्तर्राष्ट्रीय
+पदार्थों
+पूर्वाग्रह
+रहे।
+शादी
+पुरा
+विषयों
+बिलियन
+ढंग
+आदेश
+लंबे
+काउंटी
+धन्यवाद
+मुस्लिम
+विरोधी
+वेल्स
+लिखें।
+पुरानी
+कांडा
+रानी
+विभाजित
+मिलकर
+तारा
+वैसे
+ईसाई
+पू
+शिकार
+ज्ञानसंदूक
+नेता
+शास्त्र
+कौन
+राजवंश
+ब्लैक
+अस्तित्व
+धारी
+प्र
+०३
+तेजी
+रायपुर
+संवाद
+किनारे
+टाइम्स
+भार
+सिर
+उत्तरप्रदेश
+छह
+आलोचना
+दिये
+गुप्त
+गेम
+नियंत्रित
+पुराण
+उद्यान
+डालें।
+हिंदू
+डीवीडी
+परीक्षा
+वालों
+घरेलू
+वस्तुओं
+व्याख्या
+पौराणिक
+अर्थात
+फूलपुर
+करोड़
+दिवस
+लघु
+जिसमे
+पिथौरागढ
+विज्ञापन
+पेश
+चर्च
+घोषित
+कंपनियों
+पशु
+पाएँ
+दर्द
+चलते
+समाधान
+माइकल
+सामना
+पूछें
+लड़ाई
+जोड़ें।
+संपादित
+जनरल
+विविध
+मिश्र
+आग
+भावना
+टिल्ड
+कैलंडर
+हत्या
+ग्रेगोरी
+प्रशासन
+रिलीज़
+खास
+मध्यम
+ज्यादातर
+अरबी
+रानीखेत
+देखते
+पाई
+आसानी
+अंश
+कश्मीर
+नवागंतुकों
+प्रभावी
+लिख
+किताब
+जीन
+इंडियाना
+चूंकि
+सत्य
+गंगोलीहाट
+नामांकित
+कोशिकाओं
+कार्यालय
+छात्र
+मस्तिष्क
+डेटा
+अनुनाद
+मंडल
+चुकी
+नारायण
+कर्म
+संपूर्ण
+प्रतिनिधित्व
+पहुंचती
+तेज
+अपेक्षा
+जाएगा।
+व्यंजन
+आत्मा
+वैश्विक
+मांग
+सेट
+इन्होंने
+सम्पूर्ण
+बदलें
+लग
+एशियाई
+रोड
+ऑनलाइन
+इस्लाम
+दास
+संत
+पक्षी
+बीबीसी
+व्यावसायिक
+सीज़न
+फुट
+जानते
+संक्रमण
+विचारों
+चाहता
+मतलब
+विरुद्ध
+रसायन
+निवेश
+वर्षा
+प्रमंडल
+संस्कार
+केन्द्रीय
+अंतरिक्ष
+ध्वज
+विशेषता
+बाकी
+थीं।
+यूनिवर्सिटी
+शंकर
+दैनिक
+आचार्य
+सं
+अनुरोध
+गायक
+मानसिक
+जमा
+हाउस
+मंत्रालय
+पहुंच
+जॉर्ज
+उपस्थित
+मार
+प्रधानमंत्री
+अंततः
+घनत्व
+थराली
+दूध
+सेवाओं
+वर्णित
+नियमों
+यूनाइटेड
+साथी
+विभाजन
+आपकी
+चौबटाखाल
+सम्मिलित
+प्रवाह
+गोल
+हुए।
+बिलासपुर
+कह
+जलवायु
+ब्राह्मण
+समर्पित
+निवास
+फोन
+प्रमाण
+पैमाने
+बिजली
+रोहित
+शांति
+अति
+उत्पत्ति
+तीसरे
+आनंद
+हमारी
+एकमात्र
+नुकसान
+मिलने
+पे
+सौ
+घटनाओं
+मां
+प्रायः
+भौतिकी
+कठिन
+माने
+घाटी
+अधीन
+स्थिर
+लेना
+उपयोगी
+रखना
+छूटती
+द्वार
+वेद
+चैम्पियनशिप
+बिंदु
+जुड़ा
+कल्पना
+आये
+संपादन
+तारे
+दें।
+परिभाषित
+उ
+सिद्धार्थ
+जापानी
+ऊंचाई
+भौगोलिक
+समुद्री
+आदमी
+उपकरणों
+स्त्री
+वाक्य
+निर्देश
+मशीन
+०२
+सत्र
+फुटबॉल
+घाट
+उपग्रह
+पंथ
+बहुधा
+हाइड्रोजन
+लंबी
+श
+सुंदर
+दौर
+रखता
+फ़ाइल
+मोहन
+देकर
+काला
+नंबर
+उपस्थिति
+दवा
+जीवनी
+आंतरिक
+परिवर्तित
+ज्ञानकोष
+वहीं
+आय
+समझा
+निगम
+वृक्ष
+पॉल
+बुद्ध
+बाज़ार
+मराठी
+रूसी
+जय
+ग्रैंड
+संचालन
+तत्वों
+व्यक्तित्व
+कीया
+३१
+कारणों
+बनाना
+अपराध
+फिल्में
+चक
+व्यास
+चाहे
+छोड़कर
+नमस्कार
+टेलीविजन
+डा
+वितरण
+एक्स
+पुराना
+रामायण
+बेरीनाग
+ग्रामीण
+सेंटर
+लाइसेंस
+मित्र
+छात्रों
+अध्याय
+शेयर
+अभाव
+मानना
+विद्वानों
+जनजातियां
+वैकल्पिक
+तुर्की
+जैव
+पश्चात
+नहीं।
+डिजिटल
+तारीख़
+समीक्षा
+हजार
+प्रिय
+इतनी
+अर्जुन
+शराब
+स्मृति
+जीता
+उच्चारण
+श्रीलंका
+बीजापुर
+निकल
+स्वीडन
+सत्ता
+संपत्ति
+गर्म
+बीमारी
+अर्थात्
+५०
+सम्राट
+व्रत
+मिश्रण
+वार्षिक
+प्रत्यक्ष
+अंकित
+रॉबर्ट
+समूहों
+आपूर्ति
+इंजीनियरिंग
+कैलिफोर्निया
+उनको
+गेंद
+इच्छा
+रन
+ऋषि
+समस्याओं
+आन्दोलन
+अपेक्षाकृत
+रोम
+चाहिये
+चलने
+गतिविधियों
+गाने
+विम्बलडन
+हैरी
+एण्ड
+इंच
+सेवाएं
+वेस्ट
+वें
+जाये
+पहुँच
+हूं
+श्रेष्ठ
+रहा।
+हार
+अस्पताल
+निरंतर
+नियुक्त
+तारों
+ख
+केंद्रीय
+वर्तनी
+धारण
+दान
+वाराणसी
+स्टूडियो
+रोगियों
+कुकर्म
+साधन
+जटिल
+अक्षर
+देंगे
+स्कोर
+उत्पादों
+प्रोटीन
+अनिवार्य
+२००१
+कायमगंज
+सौर
+सरगुजा
+साबित
+ऊँचाई
+लीला
+सैनिक
+स्टेडियम
+रायगढ
+पर्व
+जयपुर
+व्याकरण
+रावत
+इसलिये
+करेगा
+तीव्र
+प्रकाशक
+कृतियाँ
+प्रसार
+नोबेल
+सभ्यता
+परिसर
+अफ़्रीका
+राजनैतिक
+इलाज
+साहित्यिक
+सतपुली
+लिखित
+फ्रेंच
+देखे
+ऋण
+अकबर
+सोवियत
+हमला
+प्रोग्राम
+मिस्र
+डाला
+छत्तीसगढ
+आयोग
+पुरुषों
+रस
+सुनिश्चित
+पेरिस
+साहित्यकार
+परिभाषा
+डाटा
+अर्थव्यवस्था
+महाराज
+ओम
+सह
+पेज
+जिनकी
+वर्ण
+दर्ज
+भारती
+तभी
+तय
+एसोसिएशन
+अनुपात
+झारखंड
+जोड़ा
+पुन
+छत्तीसगढ़ी
+यानि
+लकड़ी
+त्वचा
+अधिकतम
+कोरबा
+देखकर
+डाल
+पुरालेख
+कोइल
+बढ़ती
+सफेद
+प्रतीत
+कानूनी
+चयन
+बनता
+हाथों
+जल्दी
+चार्ल्स
+ग्रन्थ
+रोक
+कारक
+खाने
+अभ्यास
+कैरियर
+वर्गीकरण
+सर्वेक्षण
+नारायणपुर
+मिश्रित
+ें
+तमिलनाडु
+प्राप्ति
+आकर्षित
+भेजा
+बनाकर
+संग्राम
+किले
+अड्डा
+कहलाता
+महसूस
+मार्क
+माल
+वजन
+फ़्रेंच
+ठोस
+उपयोगकर्ता
+चम्पा
+सलाह
+भेद
+काफ़ी
+लोगो
+खाते
+निर्देशन
+स्वर्ण
+बनाते
+नोकिया
+मूर्ति
+हद
+रोकने
+समाप्ति
+अकाउंट
+कार्यक्रमों
+ग्रीक
+संधि
+लंबाई
+निवासी
+दौरे
+चाहें
+क्षेत्रीय
+स्थायी
+किंग
+न्याय
+मोटर
+संभवतः
+बनाता
+पेड़
+तल
+पति
+वां
+कराया
+शुरूआत
+प्रारूप
+काले
+कांकेर
+रखे
+पौधों
+खेलों
+००
+काशी
+मस्जिद
+हरा
+आकर्षण
+नयी
+रखी
+मजबूत
+कडप
+आजकल
+टंकण
+साक्षात्कार
+तीसरी
+खेती
+महासागर
+लाया
+जोड़
+सामान्यतः
+सम्बंधित
+सुन्दर
+रचित
+जांजगीर
+पृष्ठों
+दीवार
+उन्होने
+विद्या
+लाने
+पड़ती
+संयोजन
+तीसरा
+पड़
+रोगों
+संसाधन
+भाषाएँ
+मानचित्र
+जमीन
+देहरादून
+मुगल
+कोर्ट
+कवर्धा
+धमतरी
+जशपुर
+पौधे
+कदम
+आकर
+बढ़ा
+अधिकारियों
+आरोप
+मिलाकर
+बढ़ाने
+प्रशासनिक
+हमले
+टाइम
+प्रेरणा
+उड़ान
+शक्तिशाली
+पीपी
+महासमुन्द
+विधानसभा
+फीट
+प्रगति
+स्नातक
+सूक्ष्म
+जवाब
+कम्प्यूटर
+अप
+छवि
+फ़िल्मों
+भ
+शुल्क
+विभूतियाँ
+कलाकारों
+संकट
+संभावित
+दिशानिर्देश
+जोर
+विधान
+आहार
+गोठ
+उपाधि
+राजनांदगांव
+जम्मू
+सतनाम
+कर्णप्रयाग
+थोड़ा
+बाबा
+साइट
+तथापि
+दन्तेवाड़ा
+यानी
+अमर
+मार्टिन
+तुरंत
+जिले।
+लाइव
+पुनःप्राप्त
+निर्धारण
+तत्कालीन
+कक्षा
+सारी
+प्रजातियों
+गये।
+करो
+मूल्यांकन
+द्वाराहाट
+राजशाही
+घई
+होगी।
+गैरसैण
+हॉल
+बिल
+ऐ
+रूपों
+मंगल
+जानी
+चित्रण
+नीतियां
+शिक्षण
+अवधारणा
+चेक
+किला
+तीनों
+मारे
+इमारत
+आवासीय
+किंगडम
+राजीवमास
+चुना
+आँकड़े
+फलस्वरूप
+करेंगे
+ज्योतिष
+यंत्र
+ग्राहक
+चित्रों
+नौ
+सल्ट
+उम्मीदवार
+कोश्याँकुटोली
+बीज
+उत्कृष्ट
+०१
+कम्पनी
+महात्मा
+खर्च
+केंद्रित
+सिन्हा
+हाई
+प्रबंधकों
+मुश्किल
+नर
+गाँधी
+बनाएं
+करनी
+हूँ।
+स्टेट
+प्
+दार्शनिक
+निकाल
+मनोरंजन
+पुस्तकालय
+सोचते
+जेल
+हिमालय
+पा
+जहाज
+तरल
+यूनिकोड
+सैन
+हास्य
+पैर
+दि
+दी।
+खराब
+ख़ुदा
+कृति
+पुष्टि
+हल्द्वानी
+असम
+अर्थशास्त्र
+सेवन
+ग्रंथों
+कड़ियां
+बदले
+पुस्तकों
+हेनरी
+रिचर्ड
+परम
+सके।
+पृ
+रहना
+हल
+सर्वप्रथम
+सामान
+काली
+चेतावनी
+मनोविज्ञान
+बॉक्स
+छोड़ने
+संगठनों
+तारामंडल
+हैदराबाद
+छिबरामऊ
+मुख्यतः
+टैग
+४०
+यहूदी
+विद्रोह
+दर्शकों
+ग्रुप
+जोशी
+डीडीहाट
+सेन
+गरुङ
+कीमत
+पीटर
+कृत्रिम
+विपणन
+प्राण
+आस
+बुनियादी
+वीर
+जल्द
+ऊपरी
+टिप्पणियाँ
+नज़र
+पहुंचा
+लेखकों
+ईंधन
+गुणों
+२००४
+स्ट्रीट
+बचपन
+लैटिन
+मलयालम
+हिमाचल
+सरस्वती
+स्वामित्व
+जंगल
+भनोली
+भक्ति
+श्रीकृष्ण
+नवीन
+मैन
+पीढ़ी
+शहरी
+लव
+अररिया
+अनुबंध
+विश्वभर
+स्मारक
+पुर्णीमा
+देवताओं
+पढ़ें
+प्रसारित
+परिस्थितियों
+रास्ते
+टाटा
+वा
+तरीका
+विषाणु
+अनुप्रयोग
+ईरानी
+यात्री
+संशोधन
+क्रमांक
+पंडित
+ते
+माह
+मुक्ति
+गहराई
+सुबह
+यहीं
+नाथ
+संबद्ध
+उत्तम
+प्रजाति
+मापन
+गद्य
+टीका
+वित्त
+विख्यात
+अवतार
+उपनिषद
+दीया
+मुहम्मद
+राजाओं
+फैसला
+परंपरागत
+जर्नल
+व्यापारिक
+होंगे
+एयर
+चौखुटिया
+मथुरा
+लगते
+उसको
+तनाव
+सिंगापुर
+उत्सव
+पुणे
+अभिव्यक्ति
+बढ़ावा
+इसको
+बच्चन
+द्रव
+अनुरूप
+एट
+मेट्रो
+उत्सर्जन
+एलबम
+हरियाणा
+चलती
+वाणिज्यिक
+डॉक्टर
+चली
+मानी
+लगा।
+लॉस
+सैनिकों
+सवाल
+२००५
+आरंभिक
+निदान
+अतरौली
+कराने
+मालिक
+देर
+तीर्थ
+विदेश
+यथा
+प्रबंध
+संपादक
+जैविक
+दोस्त
+मि
+अनुकूल
+संस्थापक
+इंटरनेशनल
+स्लैम
+सकारात्मक
+टाइप
+पुस्तकें
+रा
+मियामी
+लगे।
+ड
+घटक
+निदेशक
+इतने
+प्रतिनिधि
+मितुल
+अंग्रेजों
+दोनो
+बांग्लादेश
+वनस्पति
+बढ़ने
+बंदरगाह
+आसान
+सटीक
+मनाया
+भू
+समकालीन
+पाठक
+दोष
+औपचारिक
+डिस्क
+बेटी
+संदर्भित
+निभाई
+राव
+सूरज
+मगर
+चलचित्र
+मछली
+देखी
+जगत
+ज़्यादा
+सर्वर
+लम्बाई
+ग्रेट
+कर्मचारियों
+पंजाबी
+अगला
+शाही
+दर्जा
+चिकित्सक
+विकार
+फैला
+शुक्ल
+प्रजनन
+हां
+सदा
+अग्रणी
+नायक
+गृह
+धन्यवाद।
+जालस्थल
+आवाज
+बनाम
+कपकोट
+संघीय
+बिग
+गलती
+विविधता
+नो
+लगती
+पेट
+रिलीज
+विद्वान
+अन्तिम
+कॉपीराइट
+नमक
+अधिकारों
+प्रणालियों
+युकेश
+आर्ट
+रॉयल
+बालक
+पश्चात्
+हटाया
+पर्यटक
+आर्य
+प्रीमियर
+शब्दावली
+परत
+सिद्धांतों
+हमारा
+अकार्बनिक
+चोट
+कौशल
+प्रारम्भ
+विकेट
+गुना
+ब्रह्म
+आयरलैंड
+पेशेवर
+इस्पात
+ठाकुर
+अग्नि
+कोश
+रुचि
+उपनाम
+दत्त
+उम्मीद
+पशुओं
+श्रेय
+मुम्बई
+निकाला
+सिख
+पदक
+कवियों
+इसीलिए
+मार्शल
+बॉलीवुड
+खन्ना
+प्रवृत्ति
+यौन
+रचनाओं
+उड़ीसा
+तेलुगू
+आश्रम
+अस्पष्ट
+माइक्रोसॉफ्ट
+महत्त्वपूर्ण
+चयनित
+शास्त्रीय
+कर्मचारी
+जैक
+खो
+विशेषकर
+शब्दकोष
+स्क्रीन
+प्रतिमा
+बर्फ
+फारसी
+महाराजा
+ब्लू
+शून्य
+जरूरी
+आनेवालों
+दौरा
+प्रतिभा
+सच
+मौजूदा
+क्षति
+स्थलों
+खून
+फ़िल्में
+प्रशंसा
+होटल
+सेल
+सालों
+थ
+दुर्गा
+हाँ
+स्मिथ
+बुक
+नोट
+रचयिता
+शिखर
+नेहरू
+ब्रांड
+सुख
+समझने
+मुंह
+महाविद्यालय
+ईस्ट
+शृंखला
+बचाने
+आध्यात्मिक
+पुल
+त्याग
+आविष्कार
+हजारों
+कहता
+जाय
+प्रक्रियाओं
+विलय
+दूसरों
+जाए।
+२०००
+वापसी
+आकाश
+थॉमस
+इलेक्ट्रॉनिक
+कडियाँ
+संगीतकार
+परस्पर
+मुख्यमंत्री
+उपभोक्ता
+प्राणी
+होनी
+आउट
+स्व
+उपनिषदों
+वक्त
+कक्ष
+यांत्रिक
+आंशिक
+बांग्ला
+संकोच
+शनि
+ट
+हिन्द
+पट्टी
+लंबा
+कन्या
+जीवों
+नैतिक
+किशोर
+फ्रांसीसी
+वस्त्र
+शिकागो
+नदियों
+संस्थाओं
+ो
+गतिविधि
+कठोर
+सोने
+कंपनियां
+बेटे
+प्रतिरोध
+दवाओं
+न्यूनतम
+खैर
+गरीब
+मेला
+निकटतम
+स्थानांतरित
+लौट
+विटामिन
+जोड़ने
+ब्रायन
+यादव
+सहारा
+अफ्रीकी
+सिनेमा
+रचनात्मक
+नामों
+यज्ञ
+स्थितियों
+तृतीय
+हुये
+रिंग
+पोषण
+कहने
+उपाय
+विशेषज्ञ
+चार्ट
+क्लासिक
+मानवीय
+कार्रवाई
+एक्सप्रेस
+निर्देशित
+सम्बन्धित
+ग्राहकों
+चलाने
+अड्डे
+चेतना
+देखभाल
+रंगों
+विकी
+कल
+संबंधों
+सम्पर्क
+निष्कर्ष
+तंत्रिका
+वैज्ञानिकों
+टॉम
+प्रयत्न
+२००३
+पाठ्यक्रम
+चिंता
+३५
+श्रम
+बहन
+काल्पनिक
+डब्ल्यू
+कपड़े
+डबल्यू
+जातियों
+खाड़ी
+गीता
+हाथी
+डिज़ाइन
+एकीकृत
+कन्नड़
+खतरा
+प्रस्तावित
+खरीद
+अन्त
+कार्यरत
+ग्रीन
+विकिरण
+असफल
+हानि
+लोहाघाट
+कानपुर
+खिलाड़ियों
+छ
+सूचित
+अयोध्या
+स्टॉक
+चन्द्र
+गवर्नर
+लिंक्स
+फ़ारसी
+खनिज
+मंदिरों
+गिरावट
+पोखरी
+सारा
+आवाज़
+वायरस
+विलियम्स
+राधा
+सेंट्रल
+सहमत
+बातें
+रामनगर
+लिंग
+श्वेत
+लक्षणों
+दर्शनीय
+बाराकोट
+ऐंड
+सन्‌
+रास्ता
+वसा
+शती
+बदला
+उन्नत
+हिन्दुस्तान
+३६
+पृष्ठभूमि
+हार्ट
+सहज
+गिटार
+इतालवी
+पर्यटकों
+हरे
+खुले
+वर
+व्युत्पन्न
+जाँच
+धारणा
+मुख
+होली
+खड़े
+प्रतिष्ठित
+पड़ा।
+बचने
+निवासियों
+बरो
+लेती
+पीठ
+पाकिस्तानी
+रामचरितमानस
+आपस
+समझौते
+महीनों
+कर्ण
+हिस्ट्री
+सो
+पोस्ट
+पंक्ति
+बहु
+संशोधित
+कोलंबिया
+बचाव
+रिकॉर्डिंग
+थोड़ी
+चुने
+चौधरी
+अंकों
+शाम
+बातचीत
+ओलम्पिक
+गर्मी
+फ्लोरिडा
+गोली
+लाइफ
+लम्बी
+बम
+चावल
+बातों
+वर्गों
+आवास
+मिशन
+सफ़ेद
+४५
+दशा
+अपलोड
+मेडिकल
+जानने
+कार्यकारी
+सकतें
+समीप
+संयंत्र
+नि
+आवेदन
+मांस
+गहरा
+तरीकों
+छः
+कल्याण
+लगने
+हुसैन
+औ
+संजय
+जंगली
+केन
+सुपर
+सबूत
+साफ
+क्रमश
+लॉर्ड
+समझौता
+नाडु
+अदालत
+आगमन
+प्रथा
+डालने
+औषधि
+करवाया
+जिम्मेदार
+यान
+पन्नों
+महावीर
+सकें
+परम्परा
+मेक्सिको
+गोल्डन
+गईं
+टन
+एकदिवसीय
+आदि।
+ऑल
+१००
+प्रदूषण
+अणु
+चोपड़ा
+भा
+संरक्षित
+प्रभावशाली
+पुचः
+जुड़ी
+प्रोत्साहित
+तल्ला
+साधना
+न्यूटन
+लोकप्रियता
+भरा
+प्रार्थना
+बंगाली
+द्रव्यमान
+व्यावहारिक
+ट्रैक
+सावधान
+बैठक
+तुम्हारे
+पॉटर
+रथ
+प्रोग्रामिंग
+कही
+कमल
+मशहूर
+नजर
+धरती
+स्वाभाविक
+चेहरे
+सकता।
+शिशु
+कोण
+पॉप
+मन्त्र
+५१
+निवेदन
+अकेले
+आवृत्ति
+३२
+उठा
+कवर
+गरम
+शैक्षिक
+वास्तुकला
+पाते
+खूबसूरत
+एसिड
+होता।
+जायेगा
+पड़े
+सीजन
+नीला
+योग्यता
+वैध
+ग्लोबल
+पथ
+बीमा
+हिस्सों
+माप
+मैने
+बारह
+उल्लंघन
+जानवरों
+प्रवासी
+साहब
+एजेंसी
+हिट
+सुविधाओं
+सोच
+रवि
+गीतों
+पेन
+गुजराती
+अगली
+दर्शाया
+पतन
+चित्रित
+आकृति
+मैसूर
+बुद्धि
+मंत्र
+मनुष्यों
+पत्रकार
+पेय
+विद्यमान
+मादा
+बोलने
+मना
+बेस
+सहयोगी
+हराया
+समीकरण
+लिखते
+फसल
+संहिता
+लें
+तिलक
+प्रोफेसर
+सीधा
+आकर्षक
+संज्ञा
+मोटे
+वार
+खगोलीय
+क्रमशः
+समर्थक
+स्नान
+नकारात्मक
+नक्षत्र
+पहुंचने
+चित्रकार
+दुर्लभ
+सिद्धान्त
+भाँति
+छाया
+पूंजी
+आलोचक
+अपनाया
+बेहद
+खड़ा
+सका
+उदय
+भूल
+यमुना
+क्रेडिट
+साउथ
+नैदानिक
+हिल
+में।
+फ
+नील
+प्रयोगशाला
+५२
+शासकों
+मा
+हिसाब
+इन्हीं
+रॉय
+गाय
+घायल
+ऋतु
+तार
+लम्बे
+३८
+संपन्न
+क्रिस
+कृत
+उतना
+नामकरण
+स्वाद
+मनोवैज्ञानिक
+भय
+नौसेना
+हावड़ा
+४८
+श्याम
+कार्यवाही
+हस्तक्षेप
+दंड
+दुबई
+किस्म
+अभियांत्रिकी
+फ़िल्मफ़ेयर
+मोहम्मद
+उर्जा
+पारित
+गोरखपुर
+अस्थायी
+स्तंभ
+मुसलमानों
+असामान्य
+कैथोलिक
+वर्गीकृत
+पाप
+मनीष
+श्रेणियों
+भरे
+४६
+पढ़ने
+बिल्कुल
+खुला
+उद्यम
+मूलतः
+जोड़ी
+युनाइटेड
+दरबार
+मद्रास
+निकालने
+विरासत
+संगम
+निहित
+गिर
+कथन
+दाब
+आवश्यकताओं
+कहानियों
+ऑक्सफोर्ड
+आफ
+उन्हीं
+आधा
+मर
+सोसाइटी
+ब्लॉग
+मल्ला
+कालाढूगी
+आकलन
+अत्यन्त
+पकड़
+चाहिये।
+भरी
+भाषण
+आधे
+रत्न
+टूर
+नाना
+संस्थानों
+कालेज
+शल्य
+।।
+नौकरी
+जुड़ने
+गा
+मास्टर
+किरदार
+कुशल
+पक्षियों
+अधिग्रहण
+मजबूर
+खड़ी
+बताते
+अनिल
+महाद्वीप
+हथियार
+कलकत्ता
+प्लास्टिक
+पायलट
+स्वस्थ
+जिनसे
+रचनाएँ
+शिवाजी
+परिक्रमा
+२००२
+भोपाल
+पटकथा
+खत्म
+ड्राइव
+रूपांतरण
+भक्त
+४२
+अन्यथा
+उच्चतम
+बढ़ता
+असर
+रेड
+घरों
+व्हाइट
+आना
+खाली
+जॉनी
+राहुल
+कमजोर
+ब्राज़ील
+श्रीमती
+चाय
+रखकर
+ॐ
+एपिसोड
+मुसलमान
+जाया
+एडवर्ड
+पारी
+बांध
+विस्फोट
+उर्फ
+गुरू
+डच
+प्रमाणित
+समग्र
+मतदान
+कण
+पाटी
+प्रोटोकॉल
+विकिपीडीया
+हिंसा
+आजादी
+तस्वीर
+४७
+चुनौती
+क्रांतिकारी
+शेर
+न्यूजीलैंड
+ऑक्सीजन
+बनते
+निगरानी
+व्यवस्थित
+सर्विस
+आखिरी
+चिन्ह
+समृद्ध
+प्रयासों
+रेस
+पाता
+खतरे
+उन्हे
+पटेल
+बादशाह
+गर्भ
+हमने
+चरम
+मुखर्जी
+चलकर
+पाउंड
+जातक
+टिप्पणीसूची
+न्यायाधीश
+५५
+अनुच्छेद
+शास्त्री
+हि
+५३
+पेशकश
+बिट
+गणेश
+जीवाणु
+संकलन
+पीड़ित
+ख़ास
+बेस्ट
+निकलने
+लोहे
+ऑव
+स्वर्ग
+सोसायटी
+बेल
+भट्ट
+बढ़ते
+दुर्घटना
+त्यौहार
+संगणक
+विनोद
+हालाँकि
+न्यूज़
+गहरी
+पब्लिक
+४३
+तीव्रता
+पेटेंट
+तिब्बत
+पीने
+इस्लामी
+भीड़
+बहादुर
+ड्रामा
+सुल्तान
+हटाए
+अन्तरविकि
+साक्षरता
+विक्टोरिया
+सिनसिनाटी
+मठ
+प्रतिदिन
+सम्बन्धी
+निबंध
+बनाती
+नव
+विषय।
+तेलुगु
+वीकीपीडीया
+ऊतक
+असली
+संसाधनों
+जानवर
+डाक
+बाग
+डर
+स्रोतों
+प्रतिबंध
+सोमेश्वर
+कब्जा
+रहित
+अवशेष
+वरिष्ठ
+बेल्जियम
+देशी
+जीतने
+रणनीति
+हें
+ताल
+द्रव्य
+खेला
+राजस्व
+रीति
+गयी।
+सजा
+उपयोगकर्ताओं
+बोस
+आलोक
+आत्म
+फ़्रांस
+किसान
+गणितीय
+ज्वालामुखी
+अंगों
+ों
+बनती
+४९
+कायम
+खिताब
+तुलसी
+लक्ष्मी
+समानता
+वयस्क
+शिष्य
+संतुलन
+अचानक
+नदियाँ
+नीतियों
+नागरिकों
+जाल
+नामित
+नेताओं
+पात्रों
+सिविल
+कप्तान
+दुश्मन
+चमक
+अर्जित
+मौखिक
+स्वभाव
+आनुवंशिक
+कितने
+भागीदारी
+चोरी
+रोशन
+आलोचकों
+बोल
+गहरे
+गेट
+स्तरीय
+बता
+बहस
+जावा
+खासकर
+पड़ने
+दौड़
+३७
+निर्माताओं
+विशेषताओं
+माई
+काट
+५६
+सृष्टि
+फाउंडेशन
+संप्रदाय
+उपर
+प्रखंड
+एटा
+प्रकरण
+अक्षय
+स्कॉटलैंड
+राजकुमार
+इंग्लिश
+आइपी
+ध्रुव
+मैक
+अनुमानित
+मधुमेह
+गौतम
+चरणों
+कहे
+ि
+महादेवी
+निम्नांकित
+कथित
+परिणामों
+लिखना
+गाड़ी
+कॉम
+लड़की
+उद्धृत
+ब्लॉक
+३९
+टेलीविज़न
+एकता
+खेलने
+कारों
+सांसद
+चौथे
+सहमति
+बचा
+गाइड
+भले
+हा
+कां
+रिसर्च
+ज़मीन
+आयुर्वेद
+बॉब
+मुद्दों
+सोडियम
+तरंग
+चालक
+बाघ
+साइंस
+ग्लोब
+सकल
+मिलान
+बताता
+जिलों
+जिम
+पत्रिकाओं
+लगाना
+वाशिंगटन
+बैंकिंग
+प्राणियों
+ै
+ईमेल
+३३
+निर्दिष्ट
+पोर्ट
+पुर्तगाली
+चीज़
+बाबू
+अखिल
+उदयपुर
+चोटी
+शक्तियों
+मापदंड
+ण
+घातक
+माध्यमिक
+मारा
+जरिए
+इकाइयों
+५४
+लेजर
+विधियों
+खण्ड
+देखना
+कान
+प्रस्तुति
+३४
+अक्षांश
+कइ
+मानकों
+गुफा
+रखती
+सुरक्षीत
+होम
+करियर
+कारकों
+पत्रकारिता
+पृष्ठ।
+प्रचलन
+अनुक्रम
+इगलास
+जूनियर
+विनिमय
+अनुवादक
+विद्यार्थी
+निर्यात
+शब्दार्थ
+केन्द्रित
+सम्पादन
+बोध
+ब्रह्मा
+फ़ोन
+चाल
+ध
+अंडे
+हनुमान
+ज़
+बास्केटबॉल
+समापन
+राग
+छोर
+साहिब
+शांत
+यॉर्क
+अद्भुत
+राष्ट्रों
+सदन
+प्रसंग
+मोशन
+तकनीकों
+परामर्श
+पैसे
+एवम
+पं
+पृथक
+सरदार
+माया
+मारने
+लेबल
+टु
+निचले
+अतिथि
+महादेव
+परियोजनाओं
+दर्शक
+विकिपीडियन
+जगदीश
+विकिपरियोजना
+मुख्यत
+सीमाओं
+मुकाबले
+प्रताप
+यौगिकों
+बजट
+५९
+अहमद
+चलाया
+अहमदाबाद
+अनुपम
+पूर्ति
+पिक्चर
+स्कूलों
+अंग्रेज
+स्वीकृति
+बसा
+धरोहर
+आंकड़े
+बैटरी
+फूलों
+बेटा
+गर्मियों
+प्रबन्धक
+जोड़े
+महाकाव्य
+जन्मे
+गानों
+वनों
+लेन
+बाह
+एकत्रित
+नेपाली
+अमीर
+नीदरलैंड
+कहानियाँ
+मेयर
+ऑपरेशन
+एक्शन
+श्रेणियाँ
+४१
+चुंबकीय
+मृत
+मुद्दे
+हित
+तोड़
+करे।
+बर्मा
+कहलगाँव
+कहाँ
+बैंकों
+मेले
+ग्रहों
+परे
+ब्रज
+ऑस्टिन
+सूचीबद्ध
+जरिये
+दूरभाष
+कितना
+प्रभावों
+वध
+वर्णमाला
+कितनी
+सचिव
+पवन
+मैक्स
+पिछला
+सौंदर्य
+लो
+खबर
+वाह्य
+प्रचालन
+री
+प्रभाकर
+पहल
+प्रभाग
+अनुसरण
+पहलू
+धूम्रपान
+रिकार्ड
+प्रशांत
+अक्षरों
+कथानक
+पारिवारिक
+लाहौर
+भाषाओँ
+यात्रियों
+घास
+जनपद
+विचारधारा
+बिलकुल
+सीता
+प्रतिष्ठा
+निशान
+टॉप
+अवैध
+दूरसंचार
+लौह
+अतीत
+छत
+इंक
+पूर्णिया
+कोर
+एलन
+उद्योगों
+निष्क्रिय
+क्यूबा
+वेग
+स्टील
+टाउन
+यूनान
+साफ़
+अलंकार
+विफल
+कुत्ते
+सम
+करना।
+मलेशिया
+तैयारी
+भव्य
+ार
+पुत्री
+इमामगंज
+वकील
+४४
+संकेतों
+मूल्यों
+बाई
+भ्रम
+पाल
+ब्याज
+गहन
+अंतराल
+चौथी
+प्रतिस्पर्धा
+निश्चय
+कारोबार
+बच
+कोटि
+साझा
+खुल
+लन्दन
+सार
+राज्यपाल
+पराजित
+स्नातकोत्तर
+रात्रि
+शानदार
+हॉलीवुड
+नाटकों
+पीला
+ब्राजील
+ऊंची
+पाये
+जोशीमठ
+सदस्यता
+पैरों
+हॉट
+आँख
+शिक्षक
+घिरा
+फ़ाइलों
+कथाओं
+बिगाड़
+रुपये
+तू
+संदेह
+लेखा
+क्रिसमस
+भूकंप
+बुरी
+हवेली
+बीकानेर
+जोधपुर
+कहलाते
+करनेवाले
+दशकों
+प्रदेशों
+कमरे
+वुल्फ़
+जितनी
+खतरनाक
+गुगल
+मामला
+रक्तचाप
+डा०
+रविवार
+लीये
+स्थापत्य
+वाहनों
+छूट
+हों।
+प्रो
+जातीय
+फंड
+चौक
+सिक्किम
+मिस्टर
+टूर्नामेंट
+रहमान
+जड़
+बनवाया
+इलाके
+गठबंधन
+किरण
+गोपाल
+कागज
+शुभ
+मिस
+एयरलाइंस
+लाखों
+तत्काल
+अवार्ड्स
+मौका
+गोल्ड
+व्यापारी
+हरी
+सलाहकार
+मनु
+फ़र्रूख़ाबाद
+अपवाद
+मूवी
+जोन्स
+फ्रॉम
+शिकारी
+ऑडियो
+महेश
+गौरव
+ऊँचा
+कब
+सतत
+पहाड़
+अनिरुद्ध
+अध्ययनों
+इंदिरा
+उपर्युक्त
+एकत्र
+महर्षि
+भर्ती
+सोचा
+गुरुआ
+शुरुआती
+अभियान्त्रिकी
+जनवादी
+पड़ी
+आंख
+फ़्राँस
+गोवा
+जैंती
+ट्रस्ट
+सर्जरी
+संयोग
+गिरफ्तार
+रामपुर
+समाजवादी
+सृजन
+बपतिस्मा
+कोष
+आराम
+मैचों
+बसे
+पैदल
+तलाश
+थियेटर
+शुष्क
+विश्वयुद्ध
+प्रतिद्वंदी
+परिवर्तनों
+एकदम
+भ्रूण
+मासिक
+द्वीपसमूह
+माला
+फैल
+नरेन्द्र
+स्टोन
+उठाया
+सारणी
+प्रारम्भिक
+बेतालघाट
+बीस
+त्रुटि
+संगठित
+क्लास
+एड
+आयरिश
+हू
+ललिता
+आग्रह
+संतान
+प्रबल
+नहर
+डॉन
+प्रवाहित
+स्पेनिश
+बनावट
+भाषाएं
+करा
+प्रोत्साहन
+भ्रष्टाचार
+उष्णकटिबंधीय
+गाना
+उपरांत
+पोलैंड
+बनायी
+आएगा।
+पादरी
+फैशन
+बजाए
+टूट
+सोनी
+गले
+मलेरिया
+बंगलौर
+पढ़ाई
+क्रिस्टल
+चौड़ाई
+जोकि
+व्यय
+मिला।
+विवेक
+अब्दुल
+परिवारों
+बाधा
+भूत
+रंगीन
+राजेश
+नींव
+हाइड्रोकार्बन
+पीले
+राकेश
+बुलाया
+इंस्पेक्टर
+परिचित
+वेतन
+इलेक्ट्रिक
+तरी
+खोला
+पदों
+मेन
+स्तरों
+रोजगार
+डोमेन
+मानता
+सेकंड
+६०
+ईसवी
+सिरे
+नाइट
+गभाना
+यथार्थ
+लि
+कीट
+भावनाओं
+नरेश
+करार
+जानता
+कार्यकाल
+सिडनी
+रमेश
+परिमाण
+भरत
+कार्ल
+खोल
+म्यूज़िक
+पठार
+शाखाओं
+गुप्ता
+कार्लो
+तिरवा
+वर्षीय
+चक्रवर्ती
+दिव्य
+चंद्र
+पावर
+विथ
+पूरक
+मुफ्त
+ग्रस्त
+रोज़
+समुदायों
+शैक्षणिक
+नीले
+भिन्नता
+फ़
+देन
+जाएँ
+अनेकों
+काउंसिल
+प्रतिद्वंद्वी
+माइक
+चालू
+सम्भव
+क्रियाओं
+शहीद
+विश्वविद्यालयों
+चौथा
+सदैव
+सुधीर
+नागपुर
+दु
+नवाब
+स्पर्श
+कोट
+दलों
+लगाए
+इतिहासकार
+ओवर
+फ़तेहाबाद
+ऑस्ट्रिया
+हार्ड
+मुकदमा
+स्टीव
+चीज
+पायी
+बादल
+आकाशगंगा
+आवरण
+भेजने
+सुनील
+कुश्ती
+ईसापूर्व
+२००
+मुनि
+स्
+बृहस्पति
+प्रयोगों
+बयान
+खाँ
+शब्दकोश
+स्वचालित
+सिम्बल
+पसंदीदा
+उत्तराधिकारी
+संसदीय
+गायन
+क्षमा
+आतंकवाद
+पत्रों
+हरिद्वार
+लगाकर
+अतएव
+गार्डन
+बैठे
+मदन
+चौहान
+चन्द्रमा
+उठाने
+जायें
+अर्ध
+तारीख
+डाउनलोड
+अनु
+ओलंपिक
+श्रंखला
+दिखाने
+अमिताभ
+मौर्य
+मुताबिक
+प्रपात
+फोटो
+लक्ष्मण
+मालूम
+देगा
+अपील
+लेंस
+स्पेस
+बिन्दु
+द्वीपों
+स्विट्ज़रलैंड
+अर्जेंटीना
+पूछा
+वोट
+अकाल
+शत्रु
+कबीर
+आचरण
+सफलतापूर्वक
+एक्सचेंज
+उत्तराखंड
+शिकायत
+शंकराचार्य
+धारावाहिक
+दृश्यों
+१९९०
+तूफान
+सड़कों
+अपेक्षित
+बाढ़
+प्रोजेक्ट
+पहुँचने
+हूं।
+ग्रांड
+उन्नति
+कच्चे
+स्वीकृत
+बहती
+व्यायाम
+प्रयोजन
+एरिक
+ऑटो
+इंटरसिटी
+सरलता
+उपनगरीय
+अनाज
+धातुओं
+संकल्प
+तेरे
+धूप
+वंशज
+परिपथ
+घोड़े
+मोक्ष
+तालाब
+असमर्थ
+श्रद्धा
+विनाश
+सापेक्ष
+अद्वितीय
+सराय
+सुरेश
+जनजाति
+ट्यूब
+रहकर
+कैम्ब्रिज
+श्वसन
+सुविधाएं
+सूत्रों
+बंध
+जंगलों
+नेत्र
+डीएनए
+बिलबोर्ड
+आदिवासी
+दिखने
+गाया
+आर्थर
+नैशनल
+सिक्के
+वायुयान
+समक्ष
+समतल
+पिछली
+छोड़े।
+विधा
+सीखने
+कालीन
+बौद्धिक
+विधेयक
+सक्सेना
+खा
+यूनियन
+परमात्मा
+संस्करणों
+योद्धा
+पैटर्न
+स्त्रियों
+कर्तव्य
+जातियाँ
+वंशावली
+कमाई
+पैसा
+वसंत
+कहलाती
+एंजिल्स
+अपोलो
+सिंहासन
+इनपुट
+बस्ती
+दीवारों
+प्राधिकरण
+संभवत
+भालू
+केबल
+पुष्प
+सिंचाई
+मानने
+कॉल
+क्रॉस
+अभिगम
+उपलब्धि
+राजनीतिज्ञ
+नोट्स
+बे
+मेजर
+ग्वालियर
+प्रजातियां
+लॉ
+प्रसन्न
+यूएस
+रहेगा
+बुरा
+रोल
+नली
+उक्त
+राजकीय
+हल्के
+हंगरी
+पैलेस
+बनकर
+फेर
+पुरे
+घड़ी
+कविताओं
+स्वरुप
+सेनानी
+अवयव
+अनुप्रयोगों
+कृतियों
+ध्रुवीय
+विल
+इंडोनेशिया
+बहुमत
+टिकट
+कठिनाई
+शासनकाल
+कार्यान्वयन
+दायित्व
+जर्सी
+वितरित
+मूर
+टर्मिनस
+सुन
+जाएगी
+फोर्ड
+दीपक
+चित्रकला
+गरीबी
+सेमी
+तात्पर्य
+संलग्न
+आश्चर्य
+मेहरा
+१९९८
+भंडार
+परिषद्
+लाइब्रेरी
+बंधन
+इण्डिया
+कोयला
+महमूद
+सुना
+नंदीग्राम
+संतोष
+यूके
+जागरण
+बदलकर
+नींद
+बचे
+किसानों
+खुशी
+स्पोर्ट्स
+बलों
+भंग
+कहानियां
+सफाई
+रहस्य
+कणों
+किशन
+वृत्त
+अरुण
+मानस
+प्रेमी
+हमलों
+जीते
+नमूने
+त्वरित
+नम्बर
+शरण
+आतंकवादी
+रंगमंच
+टुकड़े
+निकलता
+ठंडा
+खेत
+गेम्स
+राजेन्द्र
+तालिका
+तटीय
+दिनेश
+भंडारण
+निकला
+मध्यकालीन
+५००
+पान
+चक्कर
+ब्राउन
+वाणी
+असाधारण
+यकृत
+बोलते
+रोटी
+झूठ
+पौधा
+वेदों
+संक्रमित
+जितने
+खूब
+नाभिकीय
+ज्यामिति
+रेटिंग
+जिम्मेदारी
+प्रेमचंद
+एजेंट
+निरीक्षण
+लुईस
+नित्य
+मेमोरी
+उतनी
+उसपर
+पड़ोसी
+तुम्हें
+वचन
+लोकतंत्र
+पार्श्व
+संवेदनशील
+उत्पादित
+सीरीज
+कॉर्पोरेट
+सूचकांक
+चैनलों
+अनंत
+नीतिया
+रिकॉर्ड्स
+ज़रूरत
+भावी
+होल
+विवादास्पद
+पिनकोड
+सरकारों
+पहलुओं
+जादू
+तपस्या
+विहार
+मोटी
+रुपए
+अपितु
+व्यंग्य
+सीधी
+सिर्फ़
+गुवाहाटी
+बेच
+नाटकीय
+शोर
+पुराणों
+मरीज
+वाजपेयी
+तिवारी
+रही।
+ब्रेक
+फैले
+विन्यास
+भाप
+थोड़े
+सर्वोत्तम
+शशि
+पार्वती
+रचनाकाल
+अदा
+गयीं
+पुर्णिया
+बॉन्ड
+बिन
+मोंटे
+नाक
+दीक्षित
+जिनमे
+अवलोकन
+नस्ल
+डेनमार्क
+वरुण
+विभक्त
+सैकड़ों
+अनुभूति
+पंजीकृत
+मतभेद
+कॉमेडी
+कलात्मक
+निकाय
+तरफ़
+आणि
+साथियों
+गुलाब
+झिल्ली
+सोना
+संश्लेषण
+इलाकों
+पण्डित
+आया।
+रेसिंग
+खपत
+टेलीफोन
+पड़ते
+दिलीप
+ई०
+एकादशी
+प्रतिबंधित
+फलों
+साइड
+उपासना
+खोटे
+प्रिक्स
+एचआईवी
+आमंत्रित
+फार्म
+इसपर
+रेंज
+१९९९
+प्रयाग
+मंगोल
+शासित
+रद्द
+अजय
+भाजपा
+आईएसबीएन
+सुमित
+एवम्
+रजिस्टर
+विकीस्रोत
+इंदौर
+बोइंग
+अमृतसर
+मकान
+पारिस्थितिकी
+मैड्रिड
+समन्वय
+अन्ना
+लोहा
+कम्युनिस्ट
+गण
+अवसरों
+ब्यूरो
+चूँकि
+खुली
+तन्त्र
+राजपूत
+समझते
+बिहारी
+वैष्णव
+चैंपियनशिप
+प्रतिकूल
+सिंड्रोम
+बंबई
+अमृतपुर
+ख्याति
+पुर्तगाल
+क्यूँ
+घ
+नारी
+अनुभाग
+मैरी
+गर्भाशय
+सर्व
+पूर्ववर्ती
+चतुर्थ
+इमारतों
+रेजिस्ट्रेशन
+प्रभु
+अस्वीकार
+साक्ष्य
+वॉ
+बढ़कर
+इनकार
+सांस
+प्रतिवर्ष
+भाषी
+बढा
+मूत्र
+अरारिया
+निकलती
+क्रिटिक्स
+धारक
+उपयोगिता
+त्योहार
+समेत
+प्रतिरक्षा
+बटन
+समर्थ
+दा
+नगरी
+तेज़
+भूतपूर्व
+देखता
+दमन
+अनुचित
+श्रीवास्तव
+हट
+प्रशंसकों
+भंडा
+तथ्यों
+दस्तावेज
+ऑपरेटिंग
+कोशिकाएं
+वाणिज्य
+पोषक
+धीमी
+वियतनाम
+स्कॉट
+रहीं
+घाव
+प्रावधान
+१९९२
+बैक
+श्रीराम
+मुकाबला
+स्टेट्स
+पादप
+गणतंत्र
+योजनाओं
+रोजर
+हार्मोन
+उत्पादक
+टेक्सास
+बेहतरीन
+फ़्रांसिसी
+राजस्थानी
+लगाते
+बीटा
+मान्य
+उद्धरण
+एज
+उद्घाटन
+पूर्वोत्तर
+हार्डी
+यहा
+शैलियों
+ऋग्वेद
+तमाम
+बेन
+सुभाष
+प्रशिक्षित
+दुबारा
+भीतरी
+प्रिंस
+हड्डी
+मल्ली
+बेचने
+महत्त्व
+आक्रामक
+कार्यकर्ता
+कटौती
+सोमवार
+गिर्द
+शुरूआती
+तिहाई
+खरीदने
+इट
+बिजनेस
+असंभव
+डिज़्नी
+जानकी
+ली।
+तें
+बने।
+खेले
+दादा
+पृथ्वीराज
+सांख्यिकी
+हुईं
+केविन
+बनारस
+रोशनी
+आरती
+पीछा
+स्थानांतरण
+रिश्ते
+बर्तन
+परिस्थिति
+बोले
+राष्ट्रीयता
+बलि
+इंजीनियर
+प्रमेय
+बुक्स
+उनपर
+छंद
+गुंजन
+टॉवर
+शाब्दिक
+स्वप्न
+सुधारने
+यूरो
+अवध
+तत्त्व
+निधि
+ललित
+भांति
+विमानों
+जलप्रपात
+चाहती
+आंकड़ों
+तेज़ी
+मैनेजमेंट
+मैट्रिक्स
+राजभाषा
+आयाम
+गुड
+पाली
+सनहौला
+पारस्परिक
+जंग
+पिक्चर्स
+इनको
+आस्था
+गुलाबी
+आजाद
+टेक
+ऊंचा
+एतमादपुर
+ब्लोक
+प्रतिनिधियों
+स्टेशनों
+हालत
+१९९१
+अटलांटिक
+ऊँचे
+वेबसाईट
+पत्ते
+आलू
+इन्द्र
+परिकल्पना
+सुनने
+गुलशन
+हज़ार
+कम्प्यूटिंग
+नियुक्ति
+पहुँचा
+विशेषताएं
+आयात
+खुदरा
+लैंड
+मग
+महा
+फ़िर
+अनुयायी
+काफलीगैर
+डाउन
+ओबामा
+कैद
+सूजन
+उपदेश
+विवेचन
+मोटा
+नारंगी
+धर्मों
+कुमारी
+बंदी
+ख़त्म
+अल्प
+कोटा
+चीजों
+पहाड़ियों
+८०
+सर्किट
+स्रोतहीन
+दुकान
+हंस
+सैद्धांतिक
+किरन
+देखें।
+तलवार
+सबके
+ब्रदर्स
+दोषी
+टेलर
+बॉल
+कटाई
+वाद
+पक्षों
+फ्रैंक
+नगरों
+वाहक
+विश्वसनीय
+समस्याएं
+पत्थरों
+कार्टून
+जि
+बीसवीं
+तिब्बती
+गो
+भेंट
+जगहों
+निष्पादन
+विक्रेता
+खगोल
+रोज
+कसम
+स्मरण
+क्रोध
+कॉमिक्स
+सूर्यवंशी
+पोप
+भेजे
+्य
+किरौली
+सख्त
+ग्रीष्मकालीन
+विल्सन
+सुदूर
+ढांचे
+जगन्नाथ
+ड्राइवर
+गांवों
+कश्मीरी
+स्वीडिश
+वशिष्ठ
+पीड़ा
+कहकर
+नैतिकता
+वस्तुत
+औषधीय
+मैट
+ज्योति
+नगला
+महापौर
+गठित
+प्रदाता
+श्
+आर्ट्स
+हटाना
+ऊष्मा
+सकने
+मरने
+ग्रीस
+मिश्रा
+हमसे
+आपसे
+क्वीन
+गिनती
+शिल्प
+मनोनीत
+एकड़
+रोकथाम
+हितों
+आशू
+अधिकृत
+इर्द
+सांता
+खुदाई
+स्टीफन
+विश्वकोश
+लायक
+विश्वनाथ
+गीतकार
+मुमताज़
+रूचि
+इराक
+लम्बा
+ग़ैर
+वॉशिंगटन
+आपसी
+भूमिगत
+भरपूर
+रावण
+वन्य
+सौरभ
+जुड़
+विद्युत्
+अद्यतन
+जीएसएम
+मैकमोहन
+सेतु
+दूरदर्शन
+संवैधानिक
+जीवाश्म
+डबल
+हानिकारक
+दर्पण
+पूजन
+विलयन
+िया
+लता
+उपहार
+क़ानून
+थिएटर
+परिचालन
+एकीकरण
+प्लेट
+हार्डवेयर
+समावेश
+संचिका
+अपशिष्ट
+मनमोहन
+फाइबर
+भारतीयों
+दुसरे
+आंखों
+संस्कृतियों
+यंग
+सदियों
+मत्स्य
+युक्ति
+फ्रांसिस्को
+बर्लिन
+लौटने
+मेहता
+क्षण
+पाश्चात्य
+गामा
+कैमरा
+ताजमहल
+सर्च
+बना।
+तल्ली
+साधनों
+पहचाना
+राजा।
+मेरठ
+जिसको
+मधु
+रिश्ता
+धूल
+गायब
+मोर
+सीरीज़
+इति
+सें
+सामुदायिक
+अनुदान
+ड्रम
+बडा
+कालिदास
+ब्रूस
+क्षय
+मातृवंश
+ट्रिपल
+प्रगतिशील
+गोस्वामी
+शनिवार
+हल्का
+हिन्दुओं
+फैली
+विष
+गर्भावस्था
+विस्तारित
+मिमी
+बा
+डेल्टा
+आँखों
+दीर्घ
+गंतव्य
+गणितज्ञ
+बिली
+बल्लेबाज
+क्लोराइड
+बालों
+मैनचेस्टर
+यु
+निर्णायक
+इंगित
+मयुर
+साप्ताहिक
+वैशाली
+पूर्णतया
+बच्चा
+अक्ष
+भविष्यवाणी
+भ्रमण
+हांगकांग
+ब्लेक
+रेस्तरां
+कृपा
+परेशान
+विकासशील
+मांसपेशियों
+गोविन्द
+प्राकृत
+कथाएँ
+गुलाम
+व्यस्त
+मार्गदर्शन
+कोंच
+कट
+प्रतिस्थापित
+वैभव
+पहने
+पाठकों
+बातकरें
+डॉग
+विकिमीडिया
+बेदी
+पोशाक
+चंद्रमा
+छिद्र
+इमारतें
+माउंट
+सिफारिश
+होगन
+उज्जैन
+समर्थित
+ब्रह्माण्ड
+रसूल
+श्लोक
+राहत
+आखिर
+एम्
+दाल
+पकड़ने
+मुँह
+उत्साह
+गर्दन
+तुलनात्मक
+काटने
+पाक
+महारानी
+ग्रंथि
+जरुर
+यूरोपियन
+आत्महत्या
+शर्त
+चुम्बकीय
+सम्प्रदाय
+नवीनतम
+हीरो
+मशीनों
+जयंती
+मिथुन
+उद्देश्यों
+सामयिक
+अकेला
+परिवेश
+मोड
+लवण
+चिली
+रखरखाव
+बोलचाल
+अभिलेख
+चाँद
+लें।
+सेनाओं
+अखबार
+दिखा
+रूपरेखा
+भास्कर
+समाधि
+विंडोज
+बनाया।
+भयंकर
+अमृत
+अरुणा
+ऊंचे
+खेर
+दोबारा
+बाध्य
+लगी।
+नागर
+उपन्यासों
+हीन्दी
+नाट्य
+जनक
+नमूना
+टीमों
+आउटपुट
+जोस
+कोरियाई
+मरम्मत
+डाक्टर
+सूरा
+कष्ट
+परीक्षणों
+बाएं
+भरने
+वेन
+केस
+महिलाएं
+लुप्त
+फ्रेम
+द्विवेदी
+असरानी
+शोषण
+नियमितता
+इंसान
+पद्य
+वायुमंडल
+पोल
+विलुप्त
+अपूर्ण
+बेचा
+लिनक्स
+कडी
+सतीश
+बहरहाल
+आयी
+हिन्दु
+मल
+बताने
+श्रीनगर
+लड़ने
+टोक्यो
+ऊँची
+पर्ल
+पितृवंश
+नी
+दीर्घा
+धार
+मंदी
+फ्री
+घंटा
+दोपहर
+इंस्टिट्यूट
+गुर्दे
+एचटीएमएल
+रजत
+अवकाश
+सीबीएस
+पाना
+होती।
+फेसबुक
+भगवानपुर
+पतली
+सीट
+मोड़
+मक्का
+स्पेक्ट्रम
+संरचनाओं
+इसमे
+बुध
+ब्लूज़
+अवसाद
+अफगानिस्तान
+पंजीकरण
+जरुरत
+अवरोध
+ब्राउज़र
+टाइगर
+विनिर्माण
+जालघर
+विज्ञापनों
+बॉट
+ग्यारह
+मुजफ्फरपुर
+गिनी
+परी
+मिलेगा
+कस्बे
+भाषाई
+बारी
+माँग
+गैलरी
+मिलन
+शुक्र
+आर्मेनिया
+इंस्टीट्यूट
+आत्मकथा
+सदस्योंको
+प्रतिपादन
+टर्मिनल
+रहेगा।
+पेड़ों
+मिली।
+कमीशन
+योनि
+फसलों
+गतिशील
+भी।
+संचरण
+प्रभुत्व
+उपक्रम
+समुचित
+दक्षता
+द्रविड़
+बन्द
+दिखता
+मध्यप्रदेश
+सारांश
+भीम
+अस्तित्वहीन
+हथियारों
+खुराक
+प्रकारों
+तेरा
+ताकत
+भगवान्
+लेक
+समकक्ष
+देशांतर
+ै।
+जोसेफ
+आज़ाद
+सामान्यत
+उपभोग
+भीष्म
+ऊतकों
+खिलाफ़
+लोकमान्य
+अन
+राजू
+अस्थि
+दरवाजे
+राजनेता
+आघात
+उपमहाद्वीप
+प्रख्यात
+टोनी
+टुल्सका
+विफलता
+स्टोरी
+बैठ
+बनना
+स्वतः
+भाषाविज्ञान
+दृढ़
+अर्थात्‌
+शी
+पचास
+प्रसिद्धि
+अपराधी
+डाली
+हरि
+डकोटा
+कोहली
+प्लेयर
+आश्रय
+नाग
+बिस्मिल
+छात्रवृति
+मिनेसोटा
+लाए
+सकें।
+चुनावों
+ब्रिज
+चिंतन
+बिगाड
+विमर्श
+पहुंचे
+होंगे।
+वैसा
+भूख
+दिखें
+नॉर्थ
+अवस्थित
+घेरे
+स्ट्रोक
+सर्बिया
+असल
+हिन्दुस्तानी
+घन
+वीज़ा
+महोत्सव
+घटकों
+बढ़ी
+करवा
+सुनकर
+रावल
+घट
+प्रायद्वीप
+स्वाधीनता
+विशेषज्ञों
+प्रबंधकोने
+कैलिन्डर
+धनरूआ
+डेली
+किलो
+जाट
+अधिकारिक
+माहौल
+सीटें
+पुरातत्व
+पीपल
+लीटर
+अनुकूलन
+गेंदबाज़ी
+शीह
+वायुसेना
+सूर्यगढा
+उन्होनें
+सिंध
+इधर
+टैंक
+पंच
+भूमध्य
+अफ़्रीकी
+डांस
+बलिया
+एड्स
+जनन
+जंतु
+समझना
+ग्रन्थों
+सैम
+गुरुत्वाकर्षण
+कोमल
+जायेंगे
+थाईलैंड
+टेलिविज़न
+दायर
+ज़िले
+त्रिपाठी
+प्राचीनतम
+विदेशों
+करी
+पढ़ा
+पर्वतीय
+नाइट्रोजन
+परशुराम
+स्वतन्त्रता
+चार्ज
+मेहनत
+फिलिप
+पेट्रोलियम
+नदियां
+पिंड
+उत्तरार्ध
+लेनदेन
+दीर्घकालिक
+आयतन
+मूलभूत
+टनकपुर
+डाटाबेस
+औरत
+नकल
+डि
+चैंपियन
+मोती
+होनेवाले
+दिमाग
+टेक्स्ट
+जीवनचरित
+मणिपुर
+फील्ड
+प्रक्षेपण
+निकले
+खड़गपुर
+करन
+९१
+प्रदर्शनी
+अनुष्ठान
+वक्र
+संबोधित
+शिविर
+वास्तविकता
+गोआ
+मेटल
+भगत
+सवार
+मजदूर
+शतक
+मानवता
+वॉन
+बढ़ाया
+दानव
+सदृश
+१९८९
+विभागों
+कमाल
+बचत
+मिर्च
+कॉफी
+बडे
+कीं
+फर्स्ट
+स्तन
+कोने
+संसारके
+१९७२
+डुमरिया
+क्
+आवागमन
+१९८०
+होम्स
+संकलित
+पत्तियों
+सूखे
+मुलाकात
+लास
+सनातन
+सामग्रियों
+कुत्तों
+रोबोट
+खैरागढ़
+कर्नल
+राखी
+आधारभूत
+पालीगंज
+स्पेशल
+संजीव
+अग्रवाल
+आस्ट्रेलिया
+आधी
+सूरत
+संक्रामक
+मुझसे
+मुग़ल
+वोल्टेज
+अणुओं
+ज़रा
+सील
+खनन
+समानांतर
+बोला
+ग्रे
+ष
+भागवत
+रंजीत
+मीनार
+पूर्णागिरी
+बीरबल
+गायत्री
+जबलपुर
+उजागर
+सशस्त्र
+कोच
+प्रश्नों
+बुंदेलखंड
+बडी
+बदलते
+पुर
+जीवविज्ञान
+राह
+प्रशंसक
+पर्यावरणीय
+लड़कियों
+स्टोर
+संगत
+प्रोफ़ेसर
+एलिस
+हिंद
+पूल
+भि
+९०
+भावनात्मक
+प्राथमिकता
+वाष्प
+ओल्ड
+आज्ञा
+औजार
+गैसों
+व्हिस्की
+रोका
+कहती
+जहाजों
+सशक्त
+दिवसीय
+उतार
+शान्ति
+वृक्षों
+प्रचुर
+प्रसव
+७०
+संरचनात्मक
+फीचर
+फॉक्स
+देरी
+पुरूष
+कीबोर्ड
+लाइट
+शिलालेख
+सपना
+व्युत्पत्ति
+कद
+सजीव
+लोकतांत्रिक
+स्राव
+विन्डोज़
+शॉट
+चिह्नित
+उधार
+जेट
+चे
+युधिष्ठिर
+माधव
+आसन
+संख्याओं
+शेख
+घूमने
+आक्सीजन
+राइट
+नियत
+इतिहासकारों
+एनरॉन
+रु
+पारम्परिक
+व्
+सर्वथा
+वाद्य
+आपदा
+दरभंगा
+जात
+१९७१
+लाभदायक
+म्यूजिक
+दावे
+वोल्डेमॉर्ट
+भारतवर्ष
+जोकर
+राणा
+कादर
+गढ़
+कनालीछीना
+मुकेश
+जाएं
+क्लार्क
+बॉबी
+सम्पन्न
+भूरे
+शोधकर्ताओं
+पूर्ववत
+अहिंसा
+बीमार
+जूते
+फाइल
+नारियल
+अमरीश
+अवतरण
+छेद
+शर्करा
+सेनापति
+एक्सेस
+वस्तुएं
+वादक
+दांत
+योगी
+चोल
+परिष्कृत
+श्रमिक
+नामांकरण
+सबको
+जिसपर
+इलेक्ट्रॉन
+महिमा
+क्षैतिज
+उत्तरदायी
+शूटिंग
+कारखाने
+आरक्षण
+आरेख
+किए।
+रो
+यों
+घटनाएं
+बाइबिल
+दम
+वार्ड
+ज़रूरी
+औचित्य
+एव
+१९७०
+तीस
+यूनिट
+खेलते
+डेटाबेस
+मामूली
+सफर
+अध्यक्षता
+आदर
+कॉर्पोरेशन
+चैतन्य
+िक
+निरपेक्ष
+निकोलस
+आसमान
+विश्राम
+वर्जीनिया
+अभिनीत
+आन
+संरक्षक
+दाता
+तेरी
+जॉनसन
+अल्कोहल
+दिस
+दर्शाते
+अन्वेषण
+लगाई
+जीने
+टीबी
+३००
+उदाहरणार्थ
+करण
+चंडीगढ़
+शरद
+कास्त्रो
+सहकारी
+छुट्टी
+स्थिरता
+जोड़ता
+कैल्शियम
+वुड्स
+ित
+सपने
+इत्यादि।
+प्रजा
+सेक्स
+शुक्रवार
+सर्दियों
+चीजें
+नाव
+फर्म
+हॉकी
+कहां
+विमानक्षेत्रों
+१९४७
+चढ़ाई
+परवर्ती
+क्षत्रिय
+ब्राह्मणों
+कराता
+नौबतपुर
+आयन
+आइ
+प्रवर्तन
+लिटिल
+स्वत
+नासा
+तंग
+रक्षक
+ग्रोवर
+शिवपुरी
+सीडी
+गौर
+बतौर
+कल्प
+साधु
+इकाइयाँ
+पढ़
+दीक्षा
+घंटों
+करेगी
+उदहारण
+लीवर
+सती
+बियर
+हार्वर्ड
+सहारे
+दक्ष
+१९९६
+अभिषेक
+तुम्हारी
+रेगिस्तान
+अभयारण्य
+चाचा
+प्रशासकीय
+टावर
+अनुकरण
+जें
+ऊन
+फायर
+जैसलमेर
+कविताएँ
+विक्रमादित्य
+लड़के
+न्यायिक
+आपराधिक
+निंदा
+सेठ
+गत
+दुर्योधन
+गगनचुम्बी
+हीरा
+१९९५
+वैन
+मिशेल
+मालुम
+जिमी
+रिपब्लिकन
+चटर्जी
+पेपर
+बोस्टन
+व्यापारियों
+शान
+सुप्रसिद्ध
+सचिन
+हु
+राजकुमारी
+निवारण
+विकृत
+त्रिपुरा
+लेबनान
+परेशानी
+१९९७
+देवलथल
+प्रत्यय
+मरीजों
+स्‍थान
+फतेहपुर
+ह्रदय
+अध्यापन
+लीड्स
+औरंगजेब
+वस्तुएँ
+निवेशकों
+सरोवर
+एंडी
+दिनांक
+कंट्री
+लीप
+गंध
+श्रेणियां
+आरक्षित
+मारुति
+प्रशासक
+ज़िन्दगी
+जन्मस्थान
+वॉल
+भाइयों
+सहकुंड
+शेयरों
+कवरेज
+धाम
+कर्ता
+वाल्मीकि
+संग
+सेल्सियस
+सलीम
+सूक्ष्मदर्शी
+यांत्रिकी
+इलाका
+रियल
+पंकज
+विशेषताएँ
+मकबरा
+प्रहार
+अजमेर
+अभिगमन
+केशव
+मयूर
+धनी
+ऑक्साइड
+अरुणाचल
+उपलब्धता
+नजदीकी
+इंजीनियरी
+डीन
+उपनिषद्
+जरूर
+प्रखण्ड।
+ब्रह्मांड
+शीत
+पहाड़ों
+एक्ट
+विण्डोज़
+छठी
+कश्यप
+वार्नर
+उ०व०
+बुश
+१९६०
+सन्त
+पारसी
+खोजने
+कुंजी
+रोमानिया
+इकट्ठा
+लय
+शस्त्र
+फलन
+तुलसीदास
+आदित्य
+जगदीशपुर
+नीम
+इयर
+सामान्यतया
+चार्ली
+जानेवाले
+एजेंसियों
+पाटिल
+सिगरेट
+बरकरार
+पाठ्य
+साहनी
+जोड़कर
+शैल
+पाचन
+लेट
+से।
+अनावश्यक
+गतिविधियाँ
+विषयक
+शर्तों
+असंख्य
+याहू
+विक्रय
+राष्ट्रमंडल
+ऑस्ट्रेलियन
+बलिदान
+उपेक्षा
+पाती
+गौरी
+संचित
+मार्केट
+सिकंदर
+सीरिया
+अभिक्रिया
+टक्कर
+दहन
+हैमिल्टन
+घोष
+समाजशास्त्र
+भाग्य
+चट्टानों
+साझेदारी
+पठन
+उत्तेजित
+अवशोषण
+चिकित्सकीय
+अपमान
+ओजोन
+स्तूप
+वयस्कों
+ट्यूमर
+रॉ
+इंटरफेस
+टेबल
+संज्ञानात्मक
+सच्चे
+कपड़ा
+वक़्त
+ऐल्बम
+मित्रों
+बीहता
+उदाहरणों
+ऑस्कर
+पृथक्
+घी
+अं
+सुई
+झलक
+विराम
+फोर्ट
+पुरस्कारों
+इज़
+एनबीसी
+रखा।
+सत्येन्द्र
+वर्णक्रम
+चांदी
+वेगास
+नें
+वषीश्ठ
+श्र
+बगैर
+पुनर्निर्माण
+आदान
+हिटलर
+क्षतिग्रस्त
+ज्यों
+प्रसंस्करण
+सुरंग
+शाकाहारी
+धनुष
+वैचारिक
+मधुर
+गायिका
+प्रोफाइल
+प्रतिरोधी
+उपज
+संवर्धन
+चेहरा
+बाँध
+कोर्स
+स्पेनी
+परिप्रेक्ष्य
+प्रतापगढ़
+महानगर
+सुनाई
+गद्दी
+वास्तु
+निर्देशांक
+आँखें
+व्यतीत
+उन्नीसवीं
+गिरने
+भावों
+सांख्यिकीय
+आशय
+भगवती
+साधारणतया
+भोज
+मुराद
+रवी
+प्लेस
+परंपराओं
+हिप
+डार्क
+चुन
+साजन
+परिदृश्य
+रज़ा
+ताइवान
+सवारी
+देखिये
+त्रिकोण
+कपड़ों
+पद्धतियों
+अपनाने
+स्त्रोत
+खिज़िरसराय
+समर
+जड़ी
+वेदव्यास
+१९६५
+चलन
+जिव्
+सौंप
+औपनिवेशिक
+चिकित्सीय
+ट्रेड
+स्वच्छ
+बुरे
+डैनियल
+मंगलवार
+पूर्वज
+उष्मा
+चिकित्सकों
+रूपांतरित
+जंतुओं
+नारद
+पैकेज
+नागरी
+पल
+बहुविकल्पी
+तथाकथित
+कार्यक्षेत्र
+पंख
+अवॉर्ड
+मसौढी
+तम्बाकू
+लहर
+बीमारियों
+निरूपण
+साइकिल
+थीम
+क्रान्तिकारी
+इंग्लैण्ड
+सर्वत्र
+जॉर्जिया
+शेट्टी
+छाप
+मलिक
+हैमबर्ग
+स्वदेशी
+सूचक
+१९६२
+धारचुला
+चर्चिल
+रिलायंस
+ईस
+ती
+संकर
+विजुअल
+उदार
+उद्गम
+पंचमी
+मंजूरी
+अनन्त
+प्रायोजित
+नेट
+मालवा
+लाई
+बगल
+धर्मेन्द्र
+नाश
+फीफा
+नगरपालिका
+टेप
+खुर्द
+मार्गों
+धमकी
+शिवलिंग
+प्रासंगिक
+धरहरा
+मारिया
+विवादित
+मेक्सिकन
+१९८६
+उपायों
+दरअसल
+सम्पादक
+वृत्तचित्र
+सिंगल
+लुई
+विद्यार्थियों
+मुद्दा
+फैसले
+आए।
+अलगाव
+मिशिगन
+धान
+भयानक
+पिट
+दिखाए
+ान
+चाप
+पहनने
+विशेषज्ञता
+पैट्रिक
+इनमे
+चर
+कुत्ता
+निर्वाण
+दण्ड
+नागरिकता
+दुकानों
+वर्चुअल
+लंका
+शॉन
+ब्लड
+जैक्सन
+जलीय
+अमास
+कड़ियों
+अनुसूचित
+रेत
+गारंटी
+दिशाओं
+स्टैनफोर्ड
+मूलत
+डेनियल
+परि
+सेवक
+अमृता
+शताब्दियों
+जायेगी
+दिलचस्पी
+नाईट
+मॉडलों
+हान
+स्वायत्त
+ज्वर
+जवाहरलाल
+आगामी
+कूद
+बुधवार
+राक्षस
+आयेगा।
+इंटर
+वांछित
+धमनी
+सुलभ
+बाण
+वाई
+पुरातात्विक
+गौड़
+सामवेद
+नाभिक
+अध्यापक
+समाजवाद
+उद्भव
+डैनी
+चक्रवात
+फैलाव
+एंटीबायोटिक
+चर्चित
+जितेन्द्र
+उपनिवेश
+लास्ट
+१९७५
+डाई
+गुणा
+सूट
+इलेक्ट्रॉनिक्स
+स्क्वायर
+डाले
+दुःख
+कुंड
+सांचे
+चंपारण
+प्रवास
+दुख
+अधिवेशन
+भरोसा
+तप
+महामारी
+सेब
+जेरी
+हसन
+ऑर्डर
+घोड़ा
+पासवर्ड
+खारिज
+ख़ुद
+इन्होने
+डेविस
+सरन
+प्लाज्मा
+खुलासा
+स्कॉटिश
+टोरंटो
+बेकर
+प्रतीक्षा
+कराते
+क्षमताओं
+पांडे
+हॉप
+कांच
+मणि
+ऐतरेय
+णी
+न्यूज
+संतुलित
+सीला
+विरूद्ध
+द्वितीयक
+ट्रक
+भेदभाव
+निराला
+नजदीक
+भाष्य
+आयेगा
+सहन
+उस्ताद
+नॉर्वे
+बैठा
+संस्कारों
+घने
+गोपनीयता
+स्तम्भ
+वैमानिक
+पंत
+भक्तों
+सम्भावना
+श्वास
+ओवेन
+जगत्
+फायदा
+तस्वीरें
+रुक
+निषेध
+नेटवर्किंग
+आयरन
+मॉडलिंग
+१९८४
+चंद
+शिमला
+कोल
+मनोज
+बैल
+झा
+केन्द्रों
+केप
+एकाधिक
+कुरुक्षेत्र
+डिएगो
+कराना
+फिल्मी
+ठहराया
+जिल्ला
+अमीरात
+ज़िला
+प्रतिस्थापन
+मूर्तियों
+कूट
+साहस
+बेबी
+हाइब्रिड
+पेशी
+तिरुपति
+सोलह
+इयान
+डिक्शनरी
+ताज
+बहुमूल्य
+सुगंधित
+पैनल
+वाटर
+नकली
+टैक्सी
+अस्त्र
+बुखार
+जानना
+उत्परिवर्तन
+निमित्त
+द्वारका
+फिलिप्स
+कांगो
+आइलैंड
+दाढ़ीकेश
+आक्साइड
+मिल्वौकी
+पर्वतों
+१९८५
+ढाल
+ईस्टर
+वर्षो
+उधर
+बिल्डिंग
+ज़ोर
+निर्भरता
+सिन्धु
+अनौपचारिक
+यम
+योर
+नवजात
+नियंत्रक
+अनुभवों
+विज्ञानी
+लगाये
+वर्णों
+स्वतन्त्र
+अलौकिक
+हीं
+बदलता
+डालते
+चौड़ी
+आशीर्वाद
+गोद
+उपाध्याय
+जिनको
+स्टर्लिंग
+क्यू
+सिपाही
+मासने
+अनुभवी
+अपभ्रंश
+सलमान
+दर्जे
+आईसीसी
+मेँ
+किलोग्राम
+इंजनों
+खुश
+किंग्स
+व्यर्थ
+प्राप्तकर्ता
+सल्तनत
+उत
+सीख
+१०००
+अवयवों
+जिक्र
+दीप
+ज्ञानपीठ
+कोयले
+्र
+संदिग्ध
+नम
+परमाणुओं
+मछलियों
+मार्टिना
+स्कैन
+मादक
+अधिवर्ष
+महान्
+लेखांकन
+आजीवन
+बेला
+बाली
+दाहिने
+उठ
+भूरा
+कोस्ट
+यंत्रों
+दलित
+पर्याय
+प्रस्थान
+रेखाओं
+ईस्वी
+पालतू
+गिरा
+बरौनी
+१९९४
+प्लग
+दोहरी
+एडम्स
+अजीत
+सावधानी
+थ्री
+आशंका
+सिल्वर
+न्यूयार्क
+रोमांस
+डॉट
+कॉपी
+बाप
+ईंट
+गर्भवती
+लाला
+घूर्णन
+जया
+यशवंतपुर
+पागल
+जागरूकता
+कंठ
+आईटी
+पत्तों
+समर्थकों
+टूल
+राउंड
+अन्‍य
+ग्रिड
+दंत
+हिंसक
+तार्किक
+विशुद्ध
+बैठने
+मुद्रण
+सकती।
+पहुंचाने
+कंधे
+परिश्रम
+खोलने
+वृत्तांत
+सिस्टम्स
+धरातल
+सांचा
+संवेदनशीलता
+जिंदगी
+पूर्णतः
+पुरस्कृत
+सराहना
+अन्न
+मीठा
+संतों
+डीसी
+एंड्रयू
+़
+बृहदारण्यक
+टुकड़ों
+रिजर्व
+खंडन
+उपभोक्ताओं
+टिम
+नागार्जुन
+श्रवण
+प्रविष्टियों
+कीटों
+रेसलिंग
+मैदानों
+अभिनव
+एनिमेटेड
+दीन
+बारिश
+मॉल
+डेथ
+क्रान्ति
+छोड़ा
+पुण्य
+प्रतियोगिताओं
+देह
+माइक्रोफोन
+मनाने
+किम
+हेल्थ
+अभिव्यक्त
+दस्तावेजों
+बेरी
+अपहरण
+टोपी
+बाजारों
+संग्रहित
+देखो
+बहने
+भली
+चतुर्वेदी
+विघटन
+रियासत
+भवनों
+जायेगा।
+छठे
+अपर्याप्त
+वस्तुतः
+कार्बोहाइड्रेट
+इंजेक्शन
+नायर
+विद्रोही
+बैटमैन
+गोल्फ
+प्रतिज्ञा
+जरा
+पीस
+बदलती
+खरीदा
+इंटरनैशनल
+झुकाव
+लाना
+उत्थान
+सुसज्जित
+अर्चना
+ओं
+लोड
+कमांडर
+१९८२
+विद्यालयों
+व्याप्त
+आतंक
+अनियमित
+विंग
+चंद्रशेखर
+जाहिर
+त्र
+काटकर
+गिल
+इवान
+एंटी
+जाता।
+प्रदीप
+वकालत
+परजीवी
+प्रणालियां
+अहम
+केले
+चन्द्रगुप्त
+इक्विटी
+दोस्तों
+विद्यापीठ
+समर्पण
+जिल
+तोड़ने
+फिलाडेल्फिया
+पंचायत
+चिड़ियाघर
+नर्मदा
+विनियमन
+परम्परागत
+लॉजिक
+बधाई
+टेक्नोलॉजी
+थाई
+मापने
+सोशल
+७५
+फॉण्ट
+चित्रकूट
+प्राइवेट
+मराठा
+तुम्हारा
+जमशेदपुर
+१९६१
+सावली
+भूमिकाओं
+चयापचय
+अभिन्न
+किन
+खंडों
+एलिजाबेथ
+ग्रहणाधिकार
+ताजा
+निक
+उदा
+प्रयोजनों
+पश्चात्‌
+लेखो
+गन
+नमस्ते
+जोनाथन
+गोविंद
+ऑटोमोबाइल
+गोलाकार
+गंभीरता
+फिनलैंड
+प्रबन्धन
+पूर्णविराम
+एलेक्स
+मनोहर
+सौदा
+स्टाइल
+२०१२
+पीट
+सामरिक
+रेड्डी
+दया
+प्रा
+वॉल्ट
+वादा
+दरों
+उपन्यासकार
+तरंगों
+स्पैनिश
+बरेली
+दोस्ती
+विकारों
+पंक्तियों
+दिखायी
+ड्रैगन
+चाँदी
+यश
+विकृति
+बेसिक
+कामयाब
+हल्की
+अंडा
+वास
+आर्मी
+कार्तिक
+श्रे
+ब्रह्मचारी
+अर्द्ध
+ग्रेड
+फिल्मांकन
+पूर्वानुमान
+साइटों
+मैत्री
+इज
+कलाओं
+मुद्रित
+मिलर
+सुंदरता
+युवाओं
+विंबलडन
+मीले
+पाणिनि
+सहारनपुर
+पिशाच
+केंडीबार
+मृ
+डिवीजन
+निकलकर
+निभाया
+मनी
+वक्ता
+सिग्नल
+कैलाश
+वाक्यांश
+तुर्क
+विशेषण
+निशाना
+अग्रसर
+रैंक
+१९५०
+खाद
+ङ
+सीटों
+कनेक्शन
+पेट्रोल
+तु
+ग्राफ
+रण
+कंट्रोल
+रत
+जुड़वां
+पूर्वक
+बर्बरता
+पेरू
+एहसास
+व्याख्यान
+गिल्ड
+न्यूज़ीलैंड
+कमान
+पुत्रों
+फ्रांसिस
+पुजारी
+भरतपुर
+कुवैत
+मापा
+खाई
+थकान
+रिक्त
+अनुमोदन
+लेडी
+बाएँ
+शोथ
+अभिप्राय
+युवक
+स्टेम
+नीलम
+पीरपैंती
+प्रतियां
+बहाव
+बहार
+उत्
+अरविन्द
+आराधना
+मंगोलिया
+ध्वन्यात्मक
+फ़ेडरर
+एयरपोर्ट
+बाबर
+टेरियर
+क्रमिक
+विषम
+१९९३
+चालित
+स्थाई
+शीतल
+सज़ा
+अनुपस्थिति
+बफ़ेलो
+होस्ट
+क्लान
+जाएंगे
+ऊर्ध्वाधर
+द्रौपदी
+सूप
+रुपया
+१९४८
+मीना
+शेक्सपियर
+बेकार
+टैगोर
+किताबें
+प्रविष्ट
+सौंपा
+चा
+हिंदुओं
+ऑब्जेक्ट
+अवशोषित
+सातवीं
+पिन
+अयस्क
+हाइकु
+संस्थाएं
+निकासी
+भीषण
+सल्फेट
+बीघा
+निपटने
+नाते
+बाला
+रिक
+समलैंगिक
+आपातकालीन
+उष्ण
+ईस्टवुड
+रचनाएं
+बरसात
+अमित
+यजुर्वेद
+प्रशा
+संपदा
+व्यंजनों
+रॉकेट
+चट्टान
+जार्ज
+यहूदियों
+विजयनगर
+अल्फा
+उत्तेजना
+प्रायोगिक
+अर्थों
+गेज
+दस्तावेज़
+मानकीकरण
+१९७७
+पैक
+टेरी
+उल्लिखित
+काच
+परास्त
+स्वीकार्य
+रचनाकार
+अलंकृत
+शपथ
+अंगूर
+अग्रिम
+वंचित
+कपास
+पाण्डवों
+दानापुर
+घोर
+कामना
+बह
+धोखा
+नं
+प्रतियोगी
+१९६७
+ज़्यादातर
+जला
+अनुशासन
+मसाला
+अंडरटेकर
+दूरस्थ
+सेठी
+उसमे
+दिलाने
+मुक्केबाजी
+संस्कृतनिष्ठ
+ग्रा
+कोकेन
+जेरिको
+ठंडे
+प्रोडक्शन
+गर्ल
+विराट
+गेंदबाजी
+पैन
+जज
+कराची
+महानगरीय
+स्टाफ
+मजदूरों
+एनीमेशन
+शाखाएँ
+वाइन
+१९५६
+एंव
+वीर्य
+सकते।
+तलाई
+परिपक्व
+डेल
+अवस्थाओं
+सर्प
+उन्मुख
+भूभाग
+युद्धों
+रूढ़िवादी
+नाथनगर
+नामके
+लॉस्ट
+कॉट
+नियामक
+वहन
+कलम
+सम्राट्
+परिपूर्ण
+इश्क
+ड्रीम
+कब्र
+मोम
+अल्बर्ट
+दूरबीन
+उदर
+कानूनों
+जवान
+इन्हे
+सौदे
+गान
+दामोदर
+बेलारूस
+श्रेण
+दिख
+दही
+विजयी
+घोल
+चालीस
+मध्ययुगीन
+पेंगुइन
+समायोजित
+मिनी
+पीसी
+फ़्रांसीसी
+सीईओ
+भजन
+आदत
+लिखकर
+१९६८
+परमेश्वर
+एरिया
+कमर
+रेशम
+मिसाइल
+जेन
+मोटर्स
+उग्र
+शैव
+डालता
+यूनिवर्सल
+पिनांग
+फ्लैश
+विजेताओं
+१९८८
+स्वरों
+बैंगनी
+स्विच
+फेफड़ों
+सच्चाई
+चरित
+निकटवर्ती
+इंद्र
+निवेशक
+सिकंदराबाद
+पूंछ
+समाहित
+चित्त
+फिट
+खुसरो
+सार्वभौमिक
+खाया
+स्थानिक
+चिट्ठा
+लग्गा
+समझे
+उपसर्ग
+भोग
+साइन
+क्रीम
+पाकर
+बोलियों
+सका।
+१९७३
+सिद्धि
+गुलज़ार
+आलोचनात्मक
+मिलाया
+शोभा
+ऐनी
+दायरे
+गईं।
+जाएगी।
+वाल्व
+वैली
+रामचंद्र
+संध्या
+क्रय
+सम्बद्ध
+जमाने
+सहस्रनामन
+ध्वस्त
+किरणों
+कै
+आएगा
+एस्टन
+सोचना
+अनुयायियों
+जवाहर
+मॅट
+निभाने
+का।
+क्रोएशिया
+कीर्ति
+कल्चर
+चालु
+ईथेन
+इरादा
+न्यास
+वृंदावन
+हिम
+गेट्स
+ज़ी
+वृद्धी
+परीचय
+डेबिट
+कार्निवल
+सकी
+नालंदा
+यो
+परेश
+कालांतर
+मुखिया
+डेड
+डब्लू
+सांख्य
+फ्रैंकफर्ट
+अजीब
+वृत्ति
+एफ़
+अबतक
+रूट
+हिस्सेदारी
+आवेश
+रू
+अंतरण
+वॉकर
+भवानी
+पत्ती
+धवन
+लाभकारी
+मैगज़ीन
+ओपेरा
+निकलते
+परिधि
+विलक्षण
+बताती
+शिक्षित
+१९५४
+विद
+लेफ्टिनेंट
+उल्लेखनीयता
+जोली
+रतन
+डालर
+उड़िया
+अनुपालन
+क्रिस्टोफर
+केदारनाथ
+डायोड
+तराई
+गुरारू
+प्रतिपादित
+धुरी
+प्रतिबिंबित
+अंग्रेज़
+स्टेज
+खलनायक
+सुप्रीम
+राष्ट्रवादी
+स्विस
+कैथरीन
+अपोल्लोन
+हिल्स
+प्रवर्तक
+रबर
+जोड़ों
+बॉम्बे
+विवादों
+वेस्टर्न
+मध्यवर्ती
+मालिश
+दीवाना
+गुरुवार
+दर्शाती
+गतिविधियां
+मुख्यधारा
+ऋषियों
+खिलाडी
+औसतन
+फ्रेडरिक
+पंचम
+सूखी
+चौड़ा
+विधियाँ
+१९८७
+बेंजामिन
+गली
+हफ्ते
+डीप
+नलिका
+पिंक
+आईपी
+साउंडट्रैक
+दिनकर
+एमटीवी
+अंकन
+क्रूज़
+कैफीन
+बल्लेबाजी
+देसाई
+ऑप्टिकल
+विद्वान्
+हेड
+लेंगे।
+शिवा
+बॉण्ड
+कुशलता
+क्वांटम
+अनिश्चित
+कन्नड
+विचित्र
+रग्बी
+रिव्यू
+प्रपत्र
+निष्पक्षता
+आर्कटिक
+समस्याएँ
+प्रयोगात्मक
+जुडना
+वाल
+ज़िम्बाब्वे
+तलाक
+व्योम
+बिक्रम
+अमीनो
+प्रतिस्पर्धी
+श्रीश
+विश्वव्यापी
+ग्राउंड
+पॉवर
+्ड
+बहुतायत
+मौसमी
+उतर
+तैनात
+चित्रकारी
+इंटरफ़ेस
+खगोलशास्त्र
+गुहा
+अपराधों
+पाउडर
+नॉन
+टिप्पणियां
+डू
+राजन
+मेघालय
+समृद्धि
+सीमेंट
+कथाकार
+गौराडीह
+कतिपय
+डगलस
+असमिया
+आदिम
+हज़ारों
+मीर
+हड़ताल
+ज्ञानसे
+पोर्टलैंड
+्रेणी
+संकाय
+दर्शाने
+अल्लाह
+बिल्ली
+श्रमिकों
+अल्पसंख्यक
+मेजबानी
+चाइना
+ह्रास
+फ़ाइलें
+गल्फ
+राख
+औषधियों
+१८५७
+आश्चर्यजनक
+हाउ
+खेतों
+विनंत्ती
+बढ़े
+ग्रीवा
+ऋषिकेश
+पुनपुन
+जटिलता
+राज्‍य
+लक्ष्यों
+डमी
+किताबों
+जोश
+लड़कों
+कॉमिक
+कैमरून
+पूर
+हमे
+१९८१
+स्पर्धा
+दिखाता
+कार्यकर्ताओं
+वरदान
+कराई
+अनुकूलित
+आचार
+गार्ड
+सुर
+मोर्चा
+१९७४
+प्रदत्त
+प्रेत
+डेवलपमेंट
+कार्यात्मक
+बालू
+पहचानने
+आश्रित
+रॉबिन
+आकस्मिक
+कस्बा
+मालिकों
+उपाध्यक्ष
+सिलिकॉन
+करेगा।
+दूत
+संग्रहण
+ड्रग
+गिरजाघर
+मोहब्बत
+घूम
+चैन
+आर्यों
+महासचिव
+फिलहाल
+मेजबान
+बसने
+१९८३
+पोत
+एप्पल
+रेणी
+मल्होत्रा
+चैप्लिन
+जीवाणुओं
+१९७६
+छाती
+ट्विटर
+सिकन्दर
+बोझ
+बैठकर
+ऐसें
+विस्फोटक
+अद्वैत
+जीवनकाल
+विचलन
+कैपिटल
+नाटककार
+उपवास
+बसें
+बांटा
+मदर
+डेस्कटॉप
+उन्मूलन
+देनी
+इच्छुक
+नेटस्केप
+बैरी
+ढाका
+ति
+तह
+एचटीएम
+खुफिया
+कामों
+आतंरिक
+सोनिया
+स्वम्
+ईमान
+सार्थक
+मेडिसिन
+काण्ड
+कॉमन्स
+अफ़ग़ानिस्तान
+शिशुओं
+शतरंज
+१२४
+गाजियाबाद
+सर्दी
+स्क्रिप्ट
+बैकअप
+छद्म
+केली
+मकर
+साधक
+मूर्तियां
+शिया
+सूरी
+छाल
+अब्राहम
+फूड
+ञ
+पालि
+मीमांसा
+मीरा
+मान्यताओं
+कैसा
+विनय
+जाय।
+लेम्बोर्गिनी
+इज़रायल
+जीनोम
+मैक्सिको
+एलिज़ाबेथ
+नॉट
+कंक्रीट
+बाधित
+यूनिक्स
+पाण्डव
+स्तनधारी
+सिवाय
+शारदा
+सत्याग्रह
+पूर्णत
+कठ
+बताई
+लीड
+उत्सर्जित
+सुधारों
+एंडरसन
+उत्कर्षराज
+कमला
+मैनेजर
+डीजल
+डेक
+शेखर
+साईट
+संयम
+बढ़ाकर
+तैत्तिरीय
+चमत्कार
+कवच
+तिल
+सप्रू
+४००
+सिंधु
+सब्जी
+पाइप
+मैथ्यू
+लेग
+वादी
+काय
+नेचर
+कागज़
+मंजिल
+बेल्ट
+प्रोफ़ाइल
+गाथा
+सीमांत
+कीमतों
+अंतर्निहित
+मुद्राओं
+जग
+ममता
+स्टीवन
+शास्त्रों
+फोरम
+लिए।
+विचारक
+प्रबंधकोंने
+हिंदुस्तान
+सिखों
+महत्ता
+गोदावरी
+खुदाबंदपुर
+दुबे
+सबका
+फिक्शन
+व्यवसायिक
+मरे
+चमड़े
+कालोनी
+सितारों
+दुरउपयोग
+आयुक्त
+नसीरुद्दीन
+दाँत
+सुलतानगंज
+राष्ट्रिय
+फतुहा
+संग्रामपुर
+सोर्स
+करेंगे।
+सहयोगियों
+क्लैप्टन
+बीजगणित
+प्रांतों
+आभासी
+दीवान
+मानो
+गौण
+लगाता
+डेनिस
+सुदृढ़
+एडम
+आभास
+सदस्योंके
+उठता
+ल्योन
+बंगला
+टुन
+लिट्टे
+नक्काशी
+बिंदुओं
+हेपेटाइटिस
+वामन
+जिलाधिकारी
+्व
+आठवीं
+फी
+जिन्ना
+क्वार्टर
+अनवर
+विंडोज़
+देखरेख
+ऑयल
+समजकर
+साहित्यकारों
+बालकाण्ड
+कौटिल्य
+जामनगर
+अंचल
+बिकने
+ज्ञानकोषकी
+अंगूठी
+खींच
+एफबीआई
+पेस्ट
+विडियो
+मिलना
+लाइनों
+भूटान
+ट्रेडमार्क
+तने
+बापकी
+अत्याचार
+मॉरिसन
+मलय
+उतने
+एंटीबॉडी
+मिठाई
+१९७९
+कोलेस्ट्रॉल
+ेणी
+संतुष्ट
+बेगम
+समझता
+पोलिश
+फ़ुटबॉल
+मीटाकर
+तारापुर
+धनबाद
+एयरलाइन
+लाकर
+अप्रत्यक्ष
+इंकार
+लौटे
+मानसून
+रॉबर्ट्स
+फोर्स
+चलाते
+प्रिंट
+ठ
+यूनेस्को
+धुन
+स्टॉप
+हर्ष
+ऊ
+सावित्री
+सलाम
+फेडरल
+जनित
+कु
+अन्तरिक्ष
+विक्टर
+इथियोपिया
+दुरुपयोग
+भारद्वाज
+नमः
+दांते
+शव
+सचमुच
+मुनिता
+चौथाई
+सालाना
+कब्जे
+ओड़िशा
+अंतत
+संगमरमर
+पारिस्थितिक
+आरम्भिक
+राघव
+मैसाचुसेट्स
+वीकीपीडीयांके
+पुनर्जागरण
+मिलक्त
+बमबारी
+अस्थिर
+प्रतीकों
+उच्चतर
+पतले
+अधिकांशतः
+चरित्रों
+सौन्दर्य
+पुरातन
+डिज्नी
+ड्यूक
+कार्यालयों
+कमज़ोर
+मेट
+शेफ़ील्ड
+आरएनए
+उत्प्रेरक
+सेक्शन
+संभोग
+बास
+वापिस
+राष्ट्रभाषा
+सस्ते
+मैदानी
+लग्न
+भोजपुर
+कुण्ड
+सघन
+फ़ॉर
+१९६४
+संस्मरण
+फॉर्म
+वैद्युत
+पाम
+परदे
+अचल
+ग़लती
+मंद
+बरियारपुर
+शुद्धता
+परवेज़
+बॉय
+जीभ
+रोलिंग
+बदलना
+स्टब
+भुवनेश्वर
+कोइ
+हस्तांतरण
+मुकदमे
+फैलने
+पैरिस
+प्रत्यारोपण
+अफ़्ग़ानिस्तान
+दयाल
+कवक
+मेमोरियल
+एयरबस
+इंटेल
+फिल्मफेयर
+बरोबर
+पहुँचे
+सावरकर
+कुरान
+माली
+दिखाते
+किनारों
+निचली
+कराती
+किस्मों
+रहेंगे
+रीढ़
+खजुराहो
+शियर्र
+घात
+स्वयंसेवक
+मेगावाट
+झरने
+बाढ
+ग्रीष्म
+हराकर
+ठंडी
+गेहूं
+ओबेरॉय
+फ्रेंकलिन
+केंद्रों
+शुक्राणु
+रूपये
+इकाइयां
+हटाकर
+प्रचारक
+रैंकिंग
+नीली
+क्लाउड
+निजामुद्दीन
+फर्क
+ग्लास
+उपजाऊ
+गैरी
+घुटने
+सत्यजित
+न्यून
+कमजोरी
+जोएल
+हरीश
+जन्मदिन
+क्योकि
+शिवराज
+ख़़ुदा
+सिक्कों
+पंचांग
+मिथिला
+१९३०
+पेशे
+राष्‍ट्रीय
+पहना
+कॅरियर
+प्रतिष्ठान
+मालदीव
+कलाम
+गेहूँ
+हुयी
+दुष्ट
+रांची
+टुकड़ा
+डाकू
+प्रक्रियाएं
+सहाय
+फ्रंट
+निकास
+लहसुन
+हेलन
+डाइऑक्साइड
+श्रद्धांजलि
+चिप
+रोमांटिक
+बॉडी
+शोक
+सितारा
+लेनी
+आयुर्विज्ञान
+फेम
+हरित
+हीमोग्लोबिन
+ब्रायंट
+गोला
+मानद
+कब्ज़ा
+व्यू
+प्रदर्शनों
+डेमोक्रेटिक
+फेंक
+आंत
+समुच्चय
+मातृभाषा
+महाराणा
+रिटर्न
+१९५७
+छपाई
+उपग्रहों
+गोले
+जीवंत
+रियो
+ैं
+दृढ़ता
+धीमा
+गज
+यादृच्छिक
+विपक्ष
+विमानन
+कथाएं
+चेष्टा
+गतिशीलता
+लालकुआँ
+१५०
+दिलचस्प
+बैक्टीरिया
+पवार
+ढांचा
+पंप
+नूतन
+आमन्त्रित
+पुस्तिका
+चौदह
+फोर
+सऊदी
+सरसों
+कैलिफ़ोर्निया
+नेल्सन
+रकम
+६५
+कहा।
+नायिका
+आभार
+अनजाने
+एस्टर
+एलेन
+प्रेरक
+जरुरी
+वाइल्ड
+विशेषाधिकार
+नरसिंह
+ब्रदर
+अधिकता
+बर्मी
+धाराओं
+सिंघल
+समीक्षकों
+राजदूत
+समारोहों
+ढेर
+सूखा
+अर्जेन्टीना
+प्लेटो
+१९६३
+१९६६
+स्थलाकृति
+इरादे
+कर्मों
+जानेवाली
+क्षीण
+मरुस्थल
+प्रांतीय
+स्काई
+ऍ
+विशिष्टता
+एमी
+अरबों
+इंसुलिन
+युवावस्था
+कैमरे
+नमूनों
+जावेद
+नक्शे
+सु
+१९६९
+संकुचन
+किय
+समीक्षाएं
+स्पिन
+हवाला
+कारावास
+शिक्षकों
+नाहीं
+सर्जन
+दाने
+उठाते
+वरन्
+६००
+उठाना
+भट्टाचार्य
+्ता
+डोनाल्ड
+संतृप्त
+हड्डियों
+मिलाने
+करनेवाला
+निकोबार
+दे।
+सॉसेज
+चेतन
+त्रिवेंद्रम
+ऐन
+करीबी
+मासको
+पहेली
+देशभर
+इमेज
+मोटाई
+सिगार
+ऑक्सीकरण
+मैनुअल
+सूअर
+चलना
+पड़े।
+पर।
+पराजय
+मंगेशकर
+नर्तकी
+यज्ञोपवीत
+देखिए
+द्योतक
+आतां
+मीठे
+भागने
+रूपी
+परिणत
+श्रृंगार
+शक्तिपीठ
+कुरु
+बीजिंग
+मुगलों
+घटा
+सच्चा
+वान
+पैकेट
+चौथान
+मॉर्गन
+सिवा
+इन्टरनेट
+वैधानिक
+मास्को
+भेड़
+रोहिणी
+मैरीलैंड
+भेजी
+मिर्ज़ा
+परिशिष्ट
+निर्माणाधीन
+असे
+रॉन
+डायरी
+द्
+संदूक
+नक्शा
+विराजमान
+विकल्पों
+प्रधानता
+लिपियों
+काउण्टी
+याचिका
+वरीयता
+विजू
+त्रुटियों
+निर्देशिका
+चूर्ण
+समूचे
+प्लस
+टाइपिंग
+लिखें
+दोहरे
+प्रथाओं
+निर्मल
+रस्सी
+बेखम
+ण्ड
+बजाया
+मुलायम
+हमीरपुर
+बंधक
+प्रतिरक्षी
+आपरेशन
+निसान
+नरम
+वॉल्यूम
+ख्याल
+क्रैमलिन
+इट्स
+थ्योरी
+शेयरधारकों
+सुमीत
+अंदरूनी
+लवी
+माधुरी
+खातों
+गाड़ियों
+सजावट
+निपटान
+खोलकर
+जन्मा
+पीएच
+अभिनेताओं
+चावला
+प्रेमिका
+स्विट्जरलैंड
+ब्राउजर
+मोदी
+शेरशाह
+नमी
+चालुक्य
+सूफी
+उचाई
+कोलम्बिया
+सू
+उठाकर
+ग़ज़ल
+क्षरण
+ग़लत
+खरीदारी
+दुल्हन
+शम्मी
+निष्ठा
+प्रविष्टि
+साम्यवादी
+रहेगी
+अनोखा
+स्तुति
+उपलब्धियों
+परियोजनाएं
+गद्यकार
+स्विफ्ट
+इंडीज
+लौकिक
+कोशों
+प्रिया
+शिष्यों
+निकली
+बाँटने
+टकराव
+मौजूदगी
+निरन्तर
+आकाशवाणी
+उल
+चीफ
+सुविधाजनक
+यादगार
+समाचारपत्र
+म्युज़िक
+सूचनाओं
+जमालपुर
+रोकता
+लक्षित
+दौलत
+स्पेंसर
+लालू
+पिच
+आसवन
+ज्वार
+पाषाण
+संयोजित
+अरे
+ईथरनेट
+मय
+आखिरकार
+एथेंस
+लड़का
+धूम
+निर्देशों
+आहे
+प्रयोगकर्ता
+झीलों
+ज्वाला
+नागालैंड
+आपत्ति
+कांस्य
+ख़राब
+करनेवाली
+विगत
+ार्ता
+फेडरेशन
+वैसी
+युनुस
+वस्त्रों
+श्रद्धालु
+अदृश्य
+सामर्थ्य
+६३
+हार्दिक
+मानदंड
+बौना
+सुनवाई
+शॉपिंग
+बराबरी
+सि
+पलायन
+लाइसेंसिंग
+अञ्चल
+जगदीप
+गोत्र
+देहांत
+कार्टर
+प्रतिबन्ध
+शैतान
+फांसी
+रीड
+बोतल
+गोविन्दा
+सामंजस्य
+फर्श
+फिल
+यूएसए
+गाते
+उपक्षेत्र
+एंग्लो
+तुमने
+बुगु
+निर्वाह
+बताए
+दूरदर्शी
+धोखाधड़ी
+संचालक
+तकरीबन
+आमिर
+स्टारबक्स
+जड़ें
+रूम
+टेल
+घोड़ों
+नरसंहार
+प्रीति
+अश्लील
+कलश
+कैलगरी
+८५
+घूमते
+प्रवक्ता
+वूल्वरिन
+अप्रत्याशित
+आंकड़ा
+ग्रीनहाउस
+फेस्टिवल
+अनूदित
+सर्वे
+चेन
+छवियों
+अधिकाधिक
+मिटा
+पिरामिड
+अग्र
+चाणक्य
+प्रक्षेपास्त्र
+१९७८
+विक
+टंडन
+मैनहटन
+कैच
+मौन
+टमाटर
+सांद्रता
+इस्तीफा
+करवाने
+समीक्षक
+फारस
+वज़न
+प्रवृत्तियों
+लुइस
+उत्तीर्ण
+राँची
+वनस्पतियों
+अल्फ़ा
+रीडर
+गेंदबाज
+नकद
+क्रिश्चियन
+राजेंद्र
+ऐल्कोहॉल
+कच्चा
+असोसिएशन
+लैंग्वेज
+मसाले
+ज़रूर
+मंडी
+सुमन
+सनी
+कर्मियों
+साइबेरिया
+कंपन
+आवर्त
+रुधिर
+गढ़ी
+चिकन
+स्नेह
+दत्ता
+धर्मग्रन्थ
+जौनपुर
+मुरादाबाद
+पर्वतमाला
+लौटा
+लाये
+गोपी
+दाएं
+पुनर्जीवित
+आगम
+प्रतिक्रियाओं
+हीरे
+तीर
+भ्रष्ट
+गर्भाधान
+परेड
+टेलीग्राफ
+ऐक्शन
+वीरता
+आर्क
+इफ़्तेख़ार
+टार्ज़न
+प्रतिलिपि
+डेढ़
+सम्पत्ति
+गर्व
+मदुगु
+माघ
+मूर्तियाँ
+छन्द
+कठिनाइयों
+अभियानों
+तया
+चांद
+कौषीतकि
+वास्तुकार
+पडता
+मज़बूत
+कार्यान्वित
+क्लाइंट
+पूरब
+साइमन
+क्षतिपूर्ति
+माध्यमों
+स्केल
+उत्तरदायित्व
+पतला
+पीटर्सबर्ग
+नौका
+पटल
+समझाने
+मिसौरी
+आण्विक
+एस्पिरिन
+म०ब०
+जोन
+कुक
+बाईं
+ध्येय
+ब्लेड
+कृत्य
+गार्सिया
+तीर्थंकर
+सम्मुख
+चाहीये
+मार्केटिंग
+रोमांचक
+सहानुभूति
+वायरलेस
+घृणा
+महाद्वीपीय
+उर्मिला
+बसंत
+दवाएं
+पकाने
+नन्दा
+अलवर
+निराशा
+छिपा
+तपेदिक
+आदिवासियों
+अनुवादित
+सातवें
+सिक्का
+संवत्
+सावन
+कार्पोरेशन
+उर्वरक
+राही
+ओलिवर
+पांचवें
+झीलें
+डेविल
+खां
+अन्तरराष्ट्रीय
+ब्राह्मी
+कांड
+जू
+गाँवों
+भैरव
+वीकली
+टुडे
+बेसिन
+बाघों
+निरूपित
+शाप
+मन्त्री
+कुंडली
+अथ
+राष्ट्रगान
+आणविक
+दांतों
+वैश्वीकरण
+कहें
+शैवाल
+सिलसिला
+कैरी
+१९५५
+काबुल
+मोटरसाइकिल
+विवश
+फ़ूड
+अरोड़ा
+गिरोह
+पते
+झरना
+अनुमोदित
+मांडूक्य
+कडियां
+मजाक
+जरी
+विकीपीडिया
+होत
+जमैका
+स्पष्टीकरण
+पाद
+जरूरतों
+एम्पायर
+हस्त
+संहिताओं
+लड्डू
+मध्यकाल
+वीकी
+देवगन
+चित्रआकार
+विदिशा
+कॉफ़ी
+सेंचुरी
+होते।
+मित्रता
+कठोरता
+वज़ीर
+रूपक
+अश्वेत
+राज्यसभा
+आभूषण
+चैम्पियन
+उपरान्त
+लार्ड
+नोबल
+प्रविष्टियां
+बस्तियों
+िए
+नानक
+बर्ड
+पड़ेगा
+लिंकन
+बहाल
+९६
+बंदूक
+रेट
+अयोध्याकाण्ड
+महाप्रभु
+ग्राहम
+नल
+डार्विन
+ग्रेटर
+कारखानों
+वाट
+सोचने
+हिम्मत
+बढाने
+लेबर
+गिना
+पूर्वजों
+बेचे
+हरिवंश
+श्वेताश्वतर
+माइक्रो
+सीनेट
+पु
+दिए।
+नकदी
+ब्रॉडबैंड
+फ्रेमवर्क
+दाग
+ँ
+ग्लूकोज
+आश्वासन
+दरगाह
+बीवी
+किस्में
+अभिकल्पना
+इन्दिरा
+रामकृष्ण
+शेन
+वार्
+पॉइंट
+झांसी
+चेल्सी
+वाइस
+महानतम
+विश्वसनीयता
+चूना
+डिस्प्ले
+प्रकोप
+सदाबहार
+लोहिया
+मीनाक्षी
+र्ता
+हावर्ड
+इस्लामिक
+कौशिक
+भुजा
+पहलवान
+जादुई
+अर्थशास्त्री
+मनमौजी
+शायर
+डिजाइनर
+समयावधि
+सपनों
+मर्यादा
+रेकी
+दरवाजा
+उत्त
+बारूद
+हे।
+कुर्सी
+जन्मजात
+लूट
+नियोजित
+नियोजन
+तेरह
+हिंगू
+मैडोना
+्म
+सोमनाथ
+पीपुल्स
+मुद्रास्फीति
+बजाने
+काँच
+तैराकी
+साबुन
+अभ्यारण्य
+बढ़ाते
+तन
+उ०प०
+महासभा
+अहंकार
+मांसपेशी
+निर्वात
+खतरों
+जाओ
+हैपलोग्रुप
+हैवीवेट
+आरोपों
+सितारे
+विनियमित
+सब्जियों
+शीतकालीन
+पार्टियों
+शिला
+रसवात्सल्य
+पश्च
+चॅक
+लड़ाकू
+तुझे
+रॉस
+क्लोरीन
+विषाक्तता
+मानों
+वाक्यों
+प्रतियों
+उल्टी
+हैरिस
+निकालना
+अक्षम
+सिंधी
+विशेषत
+आस्ट्रिया
+अवगत
+साधारणत
+मार्क्स
+चीता
+व्यवसायों
+डालना
+क्षितिज
+पालिका
+उल्टा
+कारखाना
+सैयद
+कमेटी
+भला
+फेयर
+फ्लू
+रामभद्राचार्य
+स्प्रिंगस्टीन
+पिस्टन
+संदर्भों
+जनसँख्या
+आनुवांशिक
+उषा
+ज़रिए
+सीमाएं
+घर्षण
+प्रौद्योगिकियों
+दिखती
+मतों
+लत
+बैले
+एक्यूपंक्चर
+फोटोग्राफर
+क्रिकेटर
+अनीता
+इण्डिक
+आधिपत्य
+सतही
+गुफाओं
+प्रतीकात्मक
+नशीली
+शुक्ला
+शेंगेन
+फास्ट
+बुल्गारिया
+महंगे
+सनम
+नज़रिया
+हेलो
+माथुर
+सेवाएँ
+रिपब्लिक
+सेंसर
+सर्कल
+बिज़नेस
+सेकेंड
+असत्यापित
+कैनेडी
+दुर्भाग्य
+विनायक
+कारगर
+प्रस्तावना
+अरस्तू
+बताये
+गृहयुद्ध
+तर
+शीट
+गिरफ्तारी
+वार्मिंग
+इसीलिये
+महासागरीय
+खनिजों
+पेरी
+जटिलताओं
+जीती
+लॉरेंस
+पूर्
+साठ
+सूडान
+एबीसी
+संस्थाएँ
+सिएटल
+आख्यान
+बोल्ट
+खानों
+यीशु
+परिलक्षित
+अभिमन्यु
+दैत्य
+पॉलिन
+निकाली
+राष्ट्रवाद
+खोजा
+साक्षी
+पारदर्शी
+७२
+जाएँगे।
+फुलवारीशरीफ़
+वैवाहिक
+जुलती
+सेंटीमीटर
+ईश
+नाभि
+रेशे
+संकीर्ण
+नेताजी
+टीके
+एड्रेस
+विश्‍व
+चार्टर
+बीना
+मधुबनी
+पियानो
+हेक्टेयर
+मंगलौर
+फलत
+सीने
+संभाल
+अलास्का
+स्पाइवेयर
+सुलोचना
+नीलगिरी
+तैसें
+उभरा
+राजकोट
+मिलीग्राम
+फाइलें
+हिब्रू
+बैग
+आटा
+होतीं
+शंख
+मजबूती
+सीना
+उनमे
+आज़मी
+अभिलेखों
+रोचेस्टर
+पुष्ट
+दाहिनी
+क़रीब
+कार्लोस
+जादूगर
+मैनें
+अवरुद्ध
+झ
+सस्ता
+लैंस
+टैक्स
+बैड
+इशारा
+पढ़ना
+विलायक
+ज्यामितीय
+एनी
+पत्तियाँ
+बहामास
+पढ़े
+कारें
+प्ले
+चश्मे
+प्रतिकृति
+झंडा
+उभरते
+स्टेनली
+डेव
+बेनोइट
+वीवरण
+निकालकर
+तदनुसार
+बुल
+अवशेषों
+कच्छ
+बताना
+एंटरटेनमेंट
+राज्यमंत्री
+मायने
+परख
+बराक
+मिले।
+ढाई
+प्रतिफल
+क्रियाएँ
+स्थूल
+बसु
+आकलनकर्ता
+गुट
+अथर्ववेद
+संस
+केट
+टीमें
+सैंडविच
+लेखिका
+कैबिनेट
+जुर्माना
+मारी
+मिटाने
+परवरदिगार
+अंदाज़
+मूल्यवान
+लिखता
+संचय
+साउंड
+युवराज
+विकिक्वेट
+स्कूली
+नशे
+प्रयोक्ताओं
+पापों
+पित्त
+बहल
+विकलांग
+डूब
+किंगफिशर
+कार्यक्षमता
+टेड
+वगैरह
+डाउनटाउन
+अपूर्व
+कलन
+थाली
+साढ़े
+पीली
+कृष्णन
+९९
+प्रोसेसर
+एमआईटी
+तंतु
+राजेन्द्रनाथ
+छीन
+स्टैंड
+मुरलीधरन
+कंप्यूटिंग
+सॉफ़्टवेयर
+चुप
+एसी
+प्रोटोटाइप
+चुनने
+राजी
+अंडर
+सुविधाएँ
+शरत
+हरेक
+मु
+विमानसेवा
+पड़ी।
+मूर्तिकला
+जुडी
+संविदा
+बाय
+बढ़ाता
+रुख
+लोकगीत
+समायोजन
+अमेरिकियों
+कैन
+जीप
+नक़ल
+तेथ
+श्रृंखलाओं
+ज़माने
+मशीनी
+एक्सरे
+आह्वान
+अलाउद्दीन
+प्रत्याशी
+बिन्दू
+रहस्यमय
+रेखाएँ
+पिया
+पत्रकारों
+प्रतिभूति
+उमर
+स्वच्छता
+घनश्याम
+विषाक्त
+दबाने
+अध
+जोड़ते
+वायुमंडलीय
+ठंड
+बर्फ़
+फीसदी
+लेआउट
+दरिया
+क्लबों
+छत्रपति
+असुरक्षित
+नागरकोविल
+कार्यो
+सौभाग्य
+परवाह
+महंगा
+युगांडा
+नवाचार
+रामचन्द्र
+जुलता
+निष्कासन
+गर्भगृह
+वेदांत
+निराश
+शोधकर्ता
+पड़ोस
+मौके
+असफलता
+गय
+जयसिंह
+हैदर
+संगीतकारों
+दीपावली
+मूसा
+समाजों
+मानवाधिकार
+जोड़ना
+ट्रम्प
+एंजाइम
+गांधीजी
+चुनी
+१९३१
+डिवाइस
+समझाया
+हजरत
+प्रमोद
+कुशीनगर
+बर्मन
+गोलार्ध
+मोह
+पढ़ते
+गवाह
+मर्सिडीज
+आमन्त्रण
+कतर
+एकाधिकार
+टायसन
+ऑपरेटर
+बलराम
+होंगी
+आये।
+नानी
+अलीगंज
+जहा
+विद्युतीय
+जड़ों
+अपराधियों
+द्वि
+जौ
+बंदर
+बढ़िया
+रेसलमेनिया
+इलेक्ट्रान
+फिलीपींस
+प्राप्‍त
+क्यूंकि
+विकलांगता
+जिल्हा
+सींग
+बछवारा
+हावी
+गाए
+एकेडमी
+वाइरस
+सवालों
+फोटोग्राफी
+हाइड्रोकार्बनों
+कोबेन
+स्वर्गीय
+यार
+कोशिकीय
+बखरी
+उतरने
+गैलापागोस
+विलास
+हंगल
+आज़ादी
+अंशों
+सिलेंडर
+केन्या
+अप्रयुक्त
+धर्मनिरपेक्ष
+प्रबंधको
+ताजिकिस्तान
+पुनर्गठन
+स्टडी
+समा
+ीर्षक
+दोषों
+आईएसओ
+कोला
+रेलमार्ग
+जहाज़
+बहाने
+थोक
+जानबूझकर
+बेकेट
+कमाने
+खाल
+छावनी
+डबल्स
+पहनते
+आल
+मनोरंजक
+फ्रैंकलिन
+भ्रमित
+सुज़ुकी
+वॉर्स
+वर्जित
+अनशन
+वुड
+अपवाह
+श्राफ
+एवेन्यू
+नाप
+पर्पल
+हुक्म
+भूगोलवेत्ता
+दबा
+उभर
+शंघाई
+पैकेजिंग
+नॉटिंघम
+वर्
+भूमिकाएं
+जनमत
+सीखा
+हलसी
+ग्रैमी
+सकेगा
+वार्त
+१९४०
+डैन
+कलंकीत
+कारन
+नहरें
+पडा
+२५०
+दर्रा
+ओड़िया
+कांफ्रेंस
+तिमाही
+फिल्टर
+ग्राफिक्स
+लाइक
+रोज़ेज़
+केक
+आंदोलनों
+ऑ
+७६
+गाँठ
+सेन्ट्रल
+करों
+पोजीशन
+ट्रांस
+अस्पतालों
+प्रचारित
+सपोर्ट
+समितियों
+एस्टेट
+संकुचित
+दिखते
+जलन
+उत्तराधिकार
+प्राध्यापक
+सूक्ष्मजैविकी
+मिर्जापुर
+रैखिक
+नैनोट्यूब
+वीजा
+गुजरती
+मालाबार
+निगमों
+पोरबंदर
+ट्वेंटी
+नवरातिलोवा
+्त
+७७
+जासूस
+अभूतपूर्व
+नवागन्तुकों
+वर्मनने
+मिसाल
+गरीबों
+फूट
+फ्रेंड्स
+फोकस
+शत
+तैसा
+गे
+एनिमेशन
+मेवाड़
+स्ट्रीम
+१९५८
+प्रमुखता
+पेशियों
+ऋ
+जलाशय
+चलाता
+क्ष
+हेमामालिनी
+बैंगलोर
+सुनते
+लैंगिक
+सुदर्शन
+रमन
+नाइट्राइट
+टिहरी
+कैदी
+कस्टम
+खरा
+चिप्स
+अनगिनत
+महाकवि
+आवश्यकताएं
+कमिश्नर
+रचा
+श्रेणीबद्ध
+रवाना
+बूटी
+वाँ
+खिलौना
+गर्ल्स
+कमांड
+चलाना
+संसद्
+तस्वीरों
+प्रतियोगिताएं
+शाखाएं
+निरूपा
+पावन
+रसायनों
+औषध
+वीणा
+साजिश
+बुजुर्ग
+एनालॉग
+मकबरे
+परीक्षित
+धोनी
+नबम्बर
+प्रबंधित
+सैल्मन
+आकारों
+सवाई
+माईस्पेस
+किण्वन
+आईबीएम
+प्लांट
+गुजर
+शर्ट
+ल०व०
+विकिसम्मेलन
+पंद्रहवीं
+मातृ
+ीय
+भिक्षु
+फ़ोटो
+अपडेट
+दोहरा
+क्रेन
+बाइबल
+पहुँचाने
+दाएँ
+निःशुल्क
+नाइट्रेट
+एरनाकुलम
+पहुंची
+सक्रियता
+लियोन
+मंडली
+लोकपाल
+निकायों
+आधुनिकता
+वसूली
+नारा
+राना
+गॉर्डन
+दांव
+चन्द्रशेखर
+हार्बर
+सलाद
+मंत्रिमंडल
+रसेल
+तब्दील
+आशिक
+विधायक
+बची
+१९४९
+जैकी
+पनीर
+वेशभूषा
+वेल्श
+पसन्द
+चुपके
+चि
+अतरी
+परतों
+मधुबाला
+सांप
+पहुंचता
+रोकना
+पकड़े
+१९२०
+पीतल
+नास्तिक
+नासिर
+किस्मत
+लाइनें
+प्रतिबिंब
+माफी
+मार्क्सवादी
+एथिलीन
+कोशीश
+जगद्गुरु
+जीना
+वाह
+प्रेसीडेंसी
+सीनियर
+पूर्णता
+फिजी
+अत्र
+होनेवाली
+बिड़ला
+रिवाज
+उपनगर
+ईथर
+बद्रीनाथ
+शीर
+ु
+रेखाचित्र
+महेन्द्र
+त्तराखण्ड
+सूत
+सीढ़ी
+भट्ठी
+भण्डार
+व्यवसायी
+सेवानिवृत्त
+गुणांक
+जामा
+शेखावत
+८००
+क्रूर
+घिरे
+फलक
+अम्बेडकर
+लगन
+बिन्दुओं
+मुकुट
+वेस्टमिंस्टर
+इमाम
+बर्नार्ड
+मृदा
+बायें
+शासकीय
+ख़िताब
+षड्यंत्र
+रेखीय
+स्पीयर्स
+जीमेल
+डिस्ट्रिक्ट
+अल्बानिया
+राशियों
+लीन
+गवाही
+जस्टिस
+स्पेलिंग
+बाँटा
+कुश
+मकसद
+अटल
+मेटा
+सर्पिल
+रास
+पंखों
+संवेदना
+हलचल
+संकल्पना
+३०००
+मक्खन
+जॉर्डन
+मिथ्या
+समीकरणों
+फेफड़े
+पैतृक
+प्लैटिनम
+एंथोनी
+वीनस
+बदली
+७००
+पीढ़ियों
+सूरीनाम
+स्ट्रॉस
+क्रियाशील
+विक्रेताओं
+मोल
+लड़ते
+रहो
+वक्तव्य
+उत्पादकता
+मॉनिटर
+पुरोहित
+मालवीय
+समझी
+रूपांतर
+पनामा
+प्रतिरोधक
+समस्तीपुर
+वेधशाला
+पीड़ितों
+देवदास
+अवधारणाओं
+फर्ग्यूसन
+ग्लेन
+चौड़े
+फाँसी
+आंत्र
+त्रि
+फेरारी
+पदार्थो
+शंकु
+दादी
+पुनरावर्तन
+विवरणों
+हलके
+दरार
+मीन
+गिरीश
+चुनें
+निभाता
+१९४५
+स्पीड
+यथार्थवादी
+तोप
+किट
+चिन
+पुकार
+मॉडर्न
+कड़े
+कावेरी
+आई।
+तूफ़ान
+द्योल
+पिकनिक
+बायर
+गिटारवादक
+एकांकी
+लगाव
+सस्ती
+खुदा
+बढ़ाना
+संयंत्रों
+निष्पक्ष
+अरविंद
+पकड़ा
+गिने
+शहद
+मिथक
+मून
+दीया।
+डेविडसन
+ग्राफिक
+प्रियस
+अनिष्पक्ष
+कराटे
+सुनहरा
+सचिवालय
+फ़ॉर्मैटिंग
+वाल्टर
+स्तंभों
+आटे
+स्मार्ट
+मेक
+घाटियों
+मेसन
+अनोखी
+सदाशिव
+प्रतिजन
+रुझान
+प्रवीण
+कपिल
+विधवा
+रुकावट
+टर्नर
+त्रिभुज
+मंत्रियों
+तत्पश्चात
+चूहे
+म्हणे
+कॉलेजों
+उत्कीर्ण
+र्षक
+घेर
+नेपोलियन
+सुलझाने
+विभिन्‍न
+आइस
+भित्ति
+गला
+वैधता
+लुकास
+उड़
+स्टैंडर्ड
+खिलौने
+युगों
+लिवरपूल
+लिप्यन्तरण
+खड़ीबोली
+पर्दे
+शत्रुघन
+अग्निहोत्री
+वर्चस्व
+बहिष्कार
+एडवेंचर
+यूटोपिया
+ऐसीटिलीन
+विचरण
+कल्पित
+मुख्‍य
+अपनाई
+गंधक
+ेश
+किशोरावस्था
+लेज़र
+कैम्प
+टाई
+तुरन्त
+अर्धचालक
+मॉरीशस
+साँस
+संगठनात्मक
+बहुवचन
+तले
+कभार
+पुकारा
+चाँदनी
+१९५९
+जिनपर
+नागराज
+मोनिका
+्तराखण्ड
+६४
+सुखद
+आवारा
+पानदारक
+एशियन
+चैत्र
+कैश
+हथेली
+नैनो
+झूठा
+विस्थापन
+प्रमाणीकरण
+इसराइल
+आठवें
+सागरीय
+प्रजापति
+किसने
+सभ्यताओं
+अर्ल
+स्वराज
+१९३६
+चन्द
+बसाया
+महानदी
+वर्ड
+रिसाव
+चम्मच
+प्रशिक्षक
+रघुनाथ
+एमिनेम
+सुधा
+पंद्रह
+काटा
+चादर
+जैम
+निकटता
+उमा
+भयभीत
+फ़ॉर्मूला
+शाहजहाँ
+इंजीनियरों
+वर्दी
+ूर्व
+आनुवंशिकी
+घेरा
+हाथियों
+रैली
+संलयन
+आवर्ती
+क्रियान्वित
+दशहरा
+वृद्ध
+विरोधियों
+बोवी
+भूविज्ञान
+पो
+होय
+ऋणात्मक
+लाते
+अण्डा
+सम्बंध
+बोट
+इटावा
+साहसिक
+आपातकाल
+टायर
+साइप्रस
+चूहों
+विधियां
+षक
+जोड़ती
+त्रिज्या
+मनाते
+बांड
+प्रतिबद्धता
+आइसलैंड
+उत्तेजक
+पैमाना
+बांद्रा
+गर्भपात
+पब्लिशिंग
+अन्यत्र
+बम्बई
+महीन
+पूंजीवाद
+क्रियान्वयन
+संगीतमय
+दैट
+दाखिला
+आवश्यकतानुसार
+मेनन
+स्प्रिंग
+ख़िलाफ़
+शक्तियां
+अंतरजाल
+यूक्रेन
+अस
+वर्जिन
+मानती
+सद्भावना
+आंद्रे
+वल्लभ
+इजरायल
+अध्यायों
+मजदूरी
+उत्तरोत्तर
+प्रभात
+श्रोताओं
+हलन्त
+हीरोज़
+कुँवर
+अलेक्जेंडर
+कराया।
+वोल्टता
+एवार्ड
+गोल्डेन
+पनडुब्बी
+स्टेरॉयड
+सचदेव
+ट्रू
+सिरों
+मारकर
+माउंटबेटन
+बार्नस्टार
+कोका
+मन्दिरों
+फ़िल्मी
+धाराएं
+सांप्रदायिक
+आत्मसमर्पण
+समांतर
+प्रीमियम
+विनोबा
+बहुराष्ट्रीय
+डैविल
+धागे
+दसवीं
+बार्कलेज
+बिरला
+प्रतिमान
+कक्षाओं
+हैना
+अमूर्त
+मंज़िल
+निरंतरता
+निपुण
+ढोल
+१९४२
+मनोरोग
+डेप
+यूनीवर्स
+डाला।
+क्षार
+शूट
+बेसबॉल
+बीएमडब्लू
+शौकिया
+प्रागैतिहासिक
+ारत
+मुझ
+गुफाएं
+वर्क
+अनन्य
+सुरुचि
+छा
+बग
+कर्क
+उठे
+हक
+प्रशस्ति
+कलाई
+जयप्रकाश
+महीना
+चिंतित
+दूषित
+नियोक्ता
+स्वदेश
+यत्र
+पूछताछ
+विस्थापित
+खोजों
+लाभान्वित
+कांट
+पहचाने
+बॉर्न
+प्रवृति
+रेजिमेंट
+थिंक
+ऐश
+स्थगित
+सीटी
+विशेषतः
+बुराई
+रुद्रप्रयाग
+सुषमा
+८४
+बनी।
+जनजातियों
+रेख
+अन्याय
+संवाददाता
+कच्ची
+बोलियाँ
+एडी
+पेंटिंग
+जिन्हे
+रति
+स्टार्च
+अबू
+पहुंचते
+अम्लीय
+सैर
+बीबी
+इंटरटेनमेंट
+वानस्पतिक
+बेशक
+श्लोकों
+आपात
+नन्द
+मेज
+तृतीयक
+टॉड
+प्रसिद्द
+रांगेय
+कैप्टन
+बीन
+चाह
+बनीं
+पोटेंशिअल
+असित
+सीरम
+कैदियों
+चुनरी
+ज्येष्ठ
+अगासी
+जस्ता
+थेरेपी
+मैथुन
+लोकल
+सूर
+यात्राओं
+गेंदों
+चढ़
+गाजीपुर
+भागीदार
+राहु
+सजाया
+उत्पीड़न
+ओमान
+बायीं
+तुर्कमेनिस्तान
+फेस
+धड़
+वन्यजीव
+चीज़ों
+अनमोल
+निभाते
+जैसें
+मुंशी
+सुपरमैन
+बहारी
+विकिस्रोत
+दुग्ध
+लगीं
+गुड्डी
+माउस
+आग़ा
+गोरखा
+कसौटी
+अल्फ्रेड
+पूज्य
+वोक्सवैगन
+ख़
+तना
+ट्रैफिक
+खंडित
+मो
+्षक
+नायडू
+शबाना
+आतंकवादियों
+जाली
+लिविंग
+पुनरावृत्ति
+एक्सप्लोरर
+फ़ोर्स
+श्रोता
+राजनयिक
+तुल्य
+डेज़
+फ्रेड
+परोसा
+ची
+फोर्ब्स
+कण्ठ
+बर
+कीन
+प्रतिभागियों
+सुरेन्द्र
+फाइलों
+निद्रा
+बंगलोर
+संभावनाओं
+बॉस्टन
+हार्ले
+प्रोसेसिंग
+नासिक
+वाइड
+एनर्जी
+पकवान
+दारा
+कम्पनियों
+थोडा
+नवादा
+सप्त
+शाहरुख़
+तांबे
+नग्न
+अंजाम
+तुग़लक़
+बचाया
+बैनर्जी
+बादलों
+संप्रेषण
+लैरी
+९८
+डायमंड
+शुभारंभ
+अपार
+देगा।
+खिड़की
+जश्न
+मैनपुरी
+विधाओं
+६६
+भ्रामक
+तंत्रों
+सीरिज़
+लहरों
+पुस्तकालयों
+विनाशकारी
+जैज़
+खतना
+बस्तियां
+उत्कर्ष
+कोशिकाएँ
+नेहरु
+मेड
+लिखा।
+धनात्मक
+चॉकलेट
+मनोरमा
+१९५२
+बार्सिलोना
+लावा
+फैजाबाद
+वाटर्स
+प्रात
+बढ
+विद्युत्‌
+मसलन
+मसूरी
+अचार
+सटीकता
+कीर्तिमान
+ब्रिगेड
+प्रकाशीय
+कं
+उत्साहित
+नौकर
+वारिस
+नामदेव
+हेमंत
+ईंटों
+इंटेलिजेंस
+सपाट
+गोबर
+पर्सनल
+कार्यप्रणाली
+असीम
+कॉलम
+झाँसी
+प्रबन्ध
+करिश्मा
+मिसिसिपी
+ब्रेकिंग
+निभा
+खाती
+दावों
+वोल्ट
+आप्रवासी
+धड़कन
+बिताया
+प्रशस्त
+बीटल
+महलों
+निलंबित
+एबरडीन
+लूथर
+बारबरा
+खण्डों
+यूज़र
+बर्बाद
+उन्नयन
+वेल्लोर
+राजबब्बर
+समन्वित
+लोप
+हल्दी
+बुद्धिमान
+किराए
+८८
+अनुसन्धान
+जेड
+बादाम
+पासपोर्ट
+खुलता
+माकपा
+प्रमाणन
+वृन्दावन
+सड़कें
+बम्बोर
+पोषित
+सिन्दूर
+अमोनिया
+श्रुति
+उठाए
+तकनीकें
+पदवी
+ऑर
+गड़बड़ी
+आमाशय
+नरक
+मुहैया
+गुजरने
+संग्रहीत
+जेसन
+सीक्रेट
+असिमोव
+कन्याकुमारी
+र्व
+झारखण्ड
+उत्तराख
+परिपक्वता
+८१
+कौरव
+ज्ञानकोश
+रंगोली
+गान्धी
+ध्वनियों
+कनाडाई
+छिपे
+म्हणोनि
+प्रणालियाँ
+विखंडन
+गुम्बद
+किक
+बख़्तियारपुर
+वश
+नैस्टर
+शा
+बर्गर
+फ़ल
+हुवा
+बिक
+अटलांटा
+रोधी
+बचना
+घा
+लुटेरे
+मेगाडेथ
+बीजों
+वियना
+चिन्तन
+अय्यर
+सोम
+चिन्हित
+रेफरी
+सहिष्णुता
+छोड़ना
+मसले
+उद्यमी
+जुलते
+स्लोवाकिया
+साख
+गोकुल
+दरबारी
+बढ़ाई
+देखा।
+खूबसूरती
+पैसेंजर
+फ्लाइट
+हवाओं
+पीढी
+नौगांव
+आगंतुक
+लिली
+उत्तरकाशी
+गुरुत्व
+सिखाया
+पियरे
+शीर्
+सिक्स
+डब्ल्यूडब्ल्यूएफ
+प्री
+दशमलव
+तेतिहा
+क़ानूनी
+धृतराष्ट्र
+हाजीपुर
+आर्यभट्ट
+प्रायोजक
+सन्दूक
+सांसारिक
+फलित
+नामका
+भट्टी
+पांव
+त्
+सम्पादित
+शोधन
+विश्‍वविद्यालय
+कंस
+पम्प
+चलाई
+करतीं
+ईपू
+मिज़ोरम
+हीन्दीवीकीपीडीयाके
+दायें
+अयोग्य
+मृग
+आनेवाले
+लीबिया
+लेसनर
+तुमको
+मेहमान
+मेलबोर्न
+स्‍थापना
+थर्ड
+इमेजिंग
+सम्मेलनों
+अमज़द
+लगेगा
+बेड़े
+इब्राहिम
+पक्का
+पलट
+मानदंडों
+त्रिनिदाद
+साम्राज्यवाद
+परीक्षक
+पड़ाव
+पहाडी
+जुड़ना
+विलोपन
+सिलसिले
+खींचने
+चलाए
+जानकर
+बेली
+विचारकों
+पितामह
+नॉर्मन
+डिपार्टमेंट
+स्वादिष्ट
+सुगंध
+पेस
+समता
+गोंडा
+लेस
+फैलाने
+सैनी
+पिज़्ज़ा
+रामधारी
+तांत्रिक
+साध्य
+जन्मभूमि
+संभालने
+आकृतियों
+अख्तर
+हेल
+तवी
+पांडवों
+मीलकर
+उत्खनन
+स्वैच्छिक
+दिल्‍ली
+श्रीलंकाई
+दोहराया
+मुखर
+टोयोटा
+रिपोर्टिंग
+निषिद्ध
+गंगोत्री
+डिक
+परमार
+बार्न
+फ़ैल
+इण्डोनेशिया
+अकादमिक
+ड्राफ्ट
+भूकम्प
+दिखलाई
+धर्मशास्त्र
+किये।
+क्राई
+बकरी
+पाया।
+न्यूर्क
+जौहर
+कामयाबी
+फौज
+सुव्यवस्थित
+डॉक्टरों
+बढ़त
+क्योटो
+दर्जन
+जुटाने
+कलर
+हिन
+ग्
+प्रेरण
+एथलेटिक्स
+कपाल
+जस्टिन
+पश्तो
+कुंभ
+थाइलैंड
+बांस
+ँव
+कनेक्टिकट
+जोरदार
+बेरोजगारी
+सुल्तानपुर
+बिस्तर
+खींचा
+प्रौढ़
+एल्बमों
+कड़ा
+मानकीकृत
+सामंत
+वृहत
+परबत्ता
+दुल्हिनबाजार
+सोल
+चना
+भोसले
+सप्ताहांत
+विशालकाय
+धोने
+भस्म
+रहनेवाले
+टेघरा
+अमीन
+फ़्रान्सीसी
+शल्यक्रिया
+ग्रांट
+१९२१
+सांकेतिक
+फार
+मदिरा
+पोर्शे
+परिधान
+यूरेनियम
+जिन्होने
+बलात्कार
+परीक्षाओं
+उत्तराखण
+ट्रेक
+जन्में
+पि
+पवित्रता
+इंतजार
+लाता
+वादन
+महत्‍वपूर्ण
+ब्
+अल्जीरिया
+सीखना
+नगण्य
+खत्री
+चतुर्भुज
+बाक़ी
+१९००
+टेन
+करोड़ों
+स्क्रीनिंग
+टूटने
+प्रजातियाँ
+आन्तरिक
+कहो
+अपघटन
+देशो
+ब्रेट
+पहुँचे।
+परिस्थितियां
+म्
+पुनर्निर्देशित
+नतीजा
+साइबर
+पैदावार
+स्याही
+नंदा
+सैटेलाइट
+न्यूट्रॉन
+रोनाल्ड
+देवेन
+चमकदार
+जिगर
+योजनाएं
+प्लेग
+अध्यात्म
+विदेशियों
+सच्ची
+चट्टोपाध्याय
+दार्शनिकों
+परिसंपत्ति
+ओक
+जाये।
+इलाक़े
+तुमसे
+बिखरे
+व्यवहारिक
+तराखण्ड
+मऊ
+प्लूटो
+दुखी
+ताम्र
+इल्म
+फैलता
+समतुल्य
+किरणें
+पेव्ड
+हुमायूँ
+सईद
+भाभी
+अंडमान
+चूक
+रणधीर
+इब्न
+बो
+बॉस
+उपराष्ट्रपति
+वू
+स्पीकर
+च्वाइस
+स्टुअर्ट
+प्रदाताओं
+कार्गो
+डेन्जोंगपा
+महज
+सीतापुर
+लगान
+पेंटल
+अनुसूची
+हस्तियों
+बहू
+कुलीन
+किनारा
+कुलकर्णी
+धनराशि
+छुटकारा
+बगीचे
+शिरा
+देखती
+हीन
+मद
+बीट
+वर्धित
+संभाला
+नीच
+बेंज
+जम
+जप
+गियर
+एफएम
+आरोपित
+सोन
+ठाकरे
+स्टीवर्ट
+पाण्डेय
+आयकर
+स्वार्थ
+जन्मतिथि
+विज्ञप्ति
+न्
+रीज़न
+म्हणौनि
+वत
+रणनीतिक
+शु
+अत्याधिक
+खालसा
+प्रान्तों
+कैलोरी
+१२०
+विनिर्देश
+अमावस्या
+गोलियों
+जिन्दगी
+अशुद्ध
+स्मिता
+वार्तालाप
+दाखिल
+काउबॉय
+एक्टर्स
+टेनेसी
+पराबैंगनी
+घूमती
+खुलने
+हिरण
+संचारित
+लैला
+लाभप्रद
+प्वाइंट
+नर्तक
+जासूसी
+मानवों
+शाहपुर
+गुड़िया
+अनुग्रह
+९५
+विश्लेषक
+जहांगीर
+ही।
+त्रिशूल
+मनीश
+स्पैरो
+कोंकणी
+सेक्टर
+रिवर
+यथासंभव
+साम्यवाद
+हडसन
+सेव
+चैंपियंस
+बसों
+किपलिंग
+लड़
+विकिपिडिया
+घनिष्ठ
+दीवारें
+टॉक
+क्रमपरिवर्तन
+म्यूजियम
+प्लान
+केसरी
+फैमिली
+लातिन
+आर्द्रता
+घाना
+अस्मिता
+बट
+छड़ी
+कात्यायन
+पुनर्जन्म
+ग्लूकोज़
+अज्ञेय
+फिटनेस
+प्रतिभाशाली
+कलाकृतियों
+हीलियम
+दोहा
+अंधेरे
+तापीय
+मल्टी
+टीकू
+आर्किटेक्चर
+किन्हीं
+सत्यापन
+बलूचिस्तान
+लारा
+फिशर
+रिहा
+देवा
+गॉड
+सुनाया
+वेश
+सबौर
+प्रशान्त
+चिंताओं
+तंजानिया
+जाएँ।
+संयोजी
+साँचों
+पूछ
+श्राद्ध
+मात
+टैंगो
+अमरनाथ
+जानकार
+कृषक
+पेले
+गुणसूत्र
+पहियों
+जिज्ञासा
+टिप्पणियों
+कहलाने
+मोनोक्रोम
+हीरालाल
+बारीक
+देंगे।
+चित
+छोड़ते
+क़ुरान
+यमन
+आदर्शों
+अपन
+संघटन
+विषयवस्तु
+आमदनी
+स्क्वैश
+दर्शनों
+सूरदास
+मातृभूमि
+फेंकने
+१९५३
+दोस्ताना
+लैण्ड
+योजन
+लॉर्ड्स
+अभि
+यूएफओ
+विध्वंस
+भूपति
+नदाल
+प्रतिभूतियों
+ट्री
+टॉमी
+संप्रदायों
+६२
+वैयक्तिक
+भेजता
+मल्टीमीडिया
+आयामी
+गुड़
+ट्रॉफी
+आविष्कारक
+हुईं।
+लॉयड
+चिह्नों
+बिशप
+साँप
+हेवी
+पर्यवेक्षण
+ाद
+चिन्ता
+आलम
+चौबीस
+तलसानिया
+ताड़
+दायित्वों
+गलतियाँ
+रिएक्टर
+चंद्रगुप्त
+सप्तम
+नाइजीरिया
+स्थ
+गुदा
+त्यों
+मिटटी
+कर्ज़
+बॉन
+६७
+तात्कालिक
+गार्डनर
+अनूठा
+ओड़िआ
+रीटा
+विश्लेषणात्मक
+देवरिया
+नेवर
+्दी
+चिकनी
+डेटिंग
+पोर्टेबल
+उगाया
+बालकों
+स्पोर्ट
+१९५१
+द्रोण
+आवंटित
+गांगुली
+नार्वे
+यन्त्र
+देशपांडे
+८२
+प्याज
+एसएमएस
+तूं
+संहार
+अलौली
+शकीरा
+छू
+देवकी
+गोल्डबर्ग
+मशीनें
+कर्ज
+चढ़ने
+हिमानी
+बतलाया
+बंगलुरु
+पढाई
+नेम
+फ़ैसला
+प्रीतम
+हिरासत
+मुबारक
+खा०प०
+डिप्लोमा
+कॉनकॉर्ड
+समझकर
+संदर्म
+एलर्जी
+नितांत
+उठने
+मेरिल
+गोपनीय
+सुगम
+क़ी
+ाखण्ड
+युग्म
+बढ़ना
+अबाउट
+वहा
+चला।
+वतन
+बाधाओं
+हुबली
+हीट
+फुल
+अनुपस्थित
+येल
+भावुक
+पित्ताशय
+टिन
+लड़ा
+रॉकी
+नोल्स
+वमन
+मारना
+ब्लाक
+बहोत
+कूपर
+करो।
+प्रमाणपत्र
+यूट्यूब
+सम्मलेन
+रनवे
+पूँजी
+मंडप
+पोटेशियम
+उत्तरांचल
+ठेठ
+ओडिशा
+पल्लव
+इन्दौर
+तर्ज़
+ः
+अनूप
+आओ
+कुख्यात
+बांसुरी
+अनुपयुक्त
+मगरमच्छ
+स्पा
+सेबी
+चाहा
+धमनियों
+बारें
+अश्व
+हस्तिनापुर
+ईसाइयों
+आइपॉड
+१०१
+इराकी
+रयान
+ाल
+हिमनद
+अमरावती
+गिरी
+पूछने
+प्रेषित
+घटाने
+डिस्कवरी
+पथरी
+रायबरेली
+नायनमार
+बढती
+मिलेगी
+किशोरों
+साड़ी
+शिवजी
+पुनर्वास
+सहरसा
+कैरोलिना
+आरण्यक
+असुर
+लौंग
+समाविष्ट
+ज़ोन
+फकीर
+बियोवुल्फ़
+राइस
+थेफ्ट
+लू
+ल०
+अज़ाब
+वेबदुनिया
+ल्यूकेमिया
+मार्गरेट
+संन्यास
+रनों
+सुनहरे
+सबने
+विरल
+पॉलिसी
+रश
+कैमरों
+एंजेल्स
+प्राणायाम
+सेलिब्रिटी
+कण्डारस्यूं
+शाश्वत
+जुलूस
+विश
+जेफ
+मतानुसार
+उत्पात
+मामा
+७३
+रहीं।
+क्लिंटन
+विकिया
+आइवी
+लिस्ट
+आबू
+गोमती
+पुरुषोत्तम
+उत्तराखण्
+हेराल्ड
+दांता
+पद्मश्री
+शर्तें
+कटिहार
+स्विंग
+उत्तरार्द्ध
+सिंगल्स
+केदार
+रघु
+वासना
+पहुँचकर
+न्यूकैसल
+मांगी
+अमल
+सल्फर
+छोड
+अंजना
+कंप्यूटरों
+ढ
+विलिस
+सीकर
+जुड़ता
+प्रसन्नता
+प्लेटफॉर्म
+गिरि
+उछाल
+करीना
+जहर
+मासके
+सम्पदा
+चौदहवीं
+ढाईज्यूली
+साओ
+कोचीन
+श्रावण
+अर्पित
+मासूम
+टीन
+स्पार्क
+कट्टर
+चढ़ा
+ट्रिब्यून
+होंडा
+कीये
+एंटोनियो
+लैस
+किससे
+एकजुट
+पतंग
+१९२७
+टीकाकरण
+मूक
+असरगंज
+सतहों
+नाल
+आयताकार
+चढ़ाव
+कार्यशील
+दक्षिणपूर्व
+माथे
+मर्फी
+गुजरता
+सफ़र
+स्लोवेनिया
+रिले
+कॉमन
+जमाव
+कुलभूषण
+्स
+क्रोम
+उजाला
+मूत्राशय
+इस्राइल
+नाड़ी
+ंवत
+परगना
+लैंडिंग
+रेलगाड़ी
+कलाँ
+उद्धार
+ज़रिये
+शॉर्ट
+टिक
+डिज़नी
+फिल्माया
+मरते
+निष्कर्षों
+उलट
+भीमसेन
+चक्रों
+मात्राओं
+प्रणाम
+सिम्बियन
+संस्थागत
+बिताने
+आंग्ल
+बिजनौर
+फायदे
+खेड़ा
+कार्यभार

+ 21 - 0
hbfreetypefont.mod/harfbuzz/replace-enum-strings.cmake

@@ -0,0 +1,21 @@
+# CMake script to replace items
+# in sources generated by glib-mkenums
+
+FILE(READ ${ENUM_INPUT_SRC} enum_in)
+
+STRING(REPLACE
+  "_t_get_type"
+  "_get_type"
+  enum_out_tmp
+  "${enum_in}"
+  )
+
+STRING(REPLACE
+  "_T ("
+  " ("
+  enum_out
+  "${enum_out_tmp}"
+  )
+
+FILE(WRITE ${ENUM_OUTPUT_SRC} "${enum_out}")
+FILE(REMOVE ${ENUM_INPUT_SRC})

+ 250 - 0
hbfreetypefont.mod/harfbuzz/src/ArabicPUASimplified.txt

@@ -0,0 +1,250 @@
+#
+#    Name:     Legacy Simplified Arabic encoding
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the PUA code (in hex as 0xXXXX)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in PUA order
+#
+0xF100	0x063B	# ARABIC LETTER KEHEH WITH TWO DOTS ABOVE
+0xF100	0x063C	# ARABIC LETTER KEHEH WITH THREE DOTS BELOW
+0xF100	0x063D	# ARABIC LETTER FARSI YEH WITH INVERTED V
+0xF100	0x063E	# ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE
+0xF100	0x063F	# ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
+0xF100	0x0653	# ARABIC MADDAH ABOVE
+0xF100	0x0654	# ARABIC HAMZA ABOVE
+0xF100	0x0655	# ARABIC HAMZA BELOW
+0xF100	0x0656	# ARABIC SUBSCRIPT ALEF
+0xF100	0x0657	# ARABIC INVERTED DAMMA
+0xF100	0x0658	# ARABIC MARK NOON GHUNNA
+0xF100	0x0659	# ARABIC ZWARAKAY
+0xF100	0x065A	# ARABIC VOWEL SIGN SMALL V ABOVE
+0xF100	0x065B	# ARABIC VOWEL SIGN INVERTED SMALL V ABOVE
+0xF100	0x065C	# ARABIC VOWEL SIGN DOT BELOW
+0xF100	0x065D	# ARABIC REVERSED DAMMA
+0xF100	0x065E	# ARABIC FATHA WITH TWO DOTS
+0xF10C	0x200C	# ZERO WIDTH NON-JOINER
+0xF10D	0x200D	# ZERO WIDTH JOINER
+0xF10E	0x200E	# LEFT-TO-RIGHT MARK
+0xF10F	0x200F	# RIGHT-TO-LEFT MARK
+0xF120	0x0020	# SPACE
+0xF121	0x0021	# EXCLAMATION MARK
+0xF122	0x0022	# QUOTATION MARK
+0xF123	0x00AB	# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xF124	0x00BB	# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xF125	0x0025	# PERCENT SIGN
+0xF126	0x00D7	# MULTIPLICATION SIGN
+0xF127	0x00F7	# DIVISION SIGN
+0xF128	0x0028	# LEFT PARENTHESIS
+0xF129	0x0029	# RIGHT PARENTHESIS
+0xF12A	0x002A	# ASTERISK
+0xF12B	0x002B	# PLUS SIGN
+0xF12C	0x060C	# ARABIC COMMA
+0xF12D	0x002D	# HYPHEN-MINUS
+0xF12E	0x002E	# FULL STOP
+0xF12F	0x002F	# SOLIDUS
+0xF130	0x0660	# ARABIC-INDIC DIGIT ZERO
+0xF131	0x0661	# ARABIC-INDIC DIGIT ONE
+0xF132	0x0662	# ARABIC-INDIC DIGIT TWO
+0xF133	0x0663	# ARABIC-INDIC DIGIT THREE
+0xF134	0x0664	# ARABIC-INDIC DIGIT FOUR
+0xF135	0x0665	# ARABIC-INDIC DIGIT FIVE
+0xF136	0x0666	# ARABIC-INDIC DIGIT SIX
+0xF137	0x0667	# ARABIC-INDIC DIGIT SEVEN
+0xF138	0x0668	# ARABIC-INDIC DIGIT EIGHT
+0xF139	0x0669	# ARABIC-INDIC DIGIT NINE
+0xF13A	0x003A	# COLON
+0xF13B	0x003B	# SEMICOLON
+0xF13B	0x061B	# ARABIC SEMICOLON
+0xF13C	0x2018	# LEFT SINGLE QUOTATION MARK
+0xF13D	0x003D	# EQUALS SIGN
+0xF13E	0x2019	# RIGHT SINGLE QUOTATION MARK
+0xF13F	0x003F	# QUESTION MARK
+0xF13F	0x061F	# ARABIC QUESTION MARK
+0xF141	0x0627	# ARABIC LETTER ALEF
+0xF141	0xFE8D	# ARABIC LETTER ALEF ISOLATED FORM
+0xF142	0xFE8E	# ARABIC LETTER ALEF FINAL FORM
+0xF143	0x0623	# ARABIC LETTER ALEF WITH HAMZA ABOVE
+0xF143	0xFE83	# ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM
+0xF144	0xFE84	# ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM
+0xF145	0x0622	# ARABIC LETTER ALEF WITH MADDA ABOVE
+0xF145	0xFE81	# ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM
+0xF146	0xFE82	# ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM
+0xF147	0x0625	# ARABIC LETTER ALEF WITH HAMZA BELOW
+0xF147	0xFE87	# ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM
+0xF148	0xFE88	# ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM
+0xF149	0xFE91	# ARABIC LETTER BEH INITIAL FORM
+0xF149	0xFE92	# ARABIC LETTER BEH MEDIAL FORM
+0xF14A	0x0628	# ARABIC LETTER BEH
+0xF14A	0xFE8F	# ARABIC LETTER BEH ISOLATED FORM
+0xF14A	0xFE90	# ARABIC LETTER BEH FINAL FORM
+0xF14B	0xFE97	# ARABIC LETTER TEH INITIAL FORM
+0xF14B	0xFE98	# ARABIC LETTER TEH MEDIAL FORM
+0xF14C	0x062A	# ARABIC LETTER TEH
+0xF14C	0xFE95	# ARABIC LETTER TEH ISOLATED FORM
+0xF14C	0xFE96	# ARABIC LETTER TEH FINAL FORM
+0xF14D	0xFE9B	# ARABIC LETTER THEH INITIAL FORM
+0xF14D	0xFE9C	# ARABIC LETTER THEH MEDIAL FORM
+0xF14E	0x062B	# ARABIC LETTER THEH
+0xF14E	0xFE99	# ARABIC LETTER THEH ISOLATED FORM
+0xF14E	0xFE9A	# ARABIC LETTER THEH FINAL FORM
+0xF14F	0xFE9F	# ARABIC LETTER JEEM INITIAL FORM
+0xF14F	0xFEA0	# ARABIC LETTER JEEM MEDIAL FORM
+0xF150	0xFE9E	# ARABIC LETTER JEEM FINAL FORM
+0xF151	0x062C	# ARABIC LETTER JEEM
+0xF151	0xFE9D	# ARABIC LETTER JEEM ISOLATED FORM
+0xF152	0xFEA3	# ARABIC LETTER HAH INITIAL FORM
+0xF152	0xFEA4	# ARABIC LETTER HAH MEDIAL FORM
+0xF153	0xFEA2	# ARABIC LETTER HAH FINAL FORM
+0xF154	0x062D	# ARABIC LETTER HAH
+0xF154	0xFEA1	# ARABIC LETTER HAH ISOLATED FORM
+0xF155	0xFEA7	# ARABIC LETTER KHAH INITIAL FORM
+0xF155	0xFEA8	# ARABIC LETTER KHAH MEDIAL FORM
+0xF156	0xFEA6	# ARABIC LETTER KHAH FINAL FORM
+0xF157	0x062E	# ARABIC LETTER KHAH
+0xF157	0xFEA5	# ARABIC LETTER KHAH ISOLATED FORM
+0xF158	0x062F	# ARABIC LETTER DAL
+0xF158	0xFEA9	# ARABIC LETTER DAL ISOLATED FORM
+0xF158	0xFEAA	# ARABIC LETTER DAL FINAL FORM
+0xF159	0x0630	# ARABIC LETTER THAL
+0xF159	0xFEAB	# ARABIC LETTER THAL ISOLATED FORM
+0xF159	0xFEAC	# ARABIC LETTER THAL FINAL FORM
+0xF15A	0x0631	# ARABIC LETTER REH
+0xF15A	0xFEAD	# ARABIC LETTER REH ISOLATED FORM
+0xF15A	0xFEAE	# ARABIC LETTER REH FINAL FORM
+0xF15B	0x005B	# LEFT SQUARE BRACKET
+0xF15C	0x005C	# REVERSE SOLIDUS
+0xF15D	0x005D	# RIGHT SQUARE BRACKET
+0xF15E	0x002C	# COMMA
+0xF15E	0x066B	# ARABIC DECIMAL SEPARATOR
+0xF15E	0x066C	# ARABIC THOUSANDS SEPARATOR
+0xF15F	0x0640	# ARABIC TATWEEL
+0xF160	0x0632	# ARABIC LETTER ZAIN
+0xF160	0xFEAF	# ARABIC LETTER ZAIN ISOLATED FORM
+0xF160	0xFEB0	# ARABIC LETTER ZAIN FINAL FORM
+0xF161	0xFEB3	# ARABIC LETTER SEEN INITIAL FORM
+0xF161	0xFEB4	# ARABIC LETTER SEEN MEDIAL FORM
+0xF162	0x0633	# ARABIC LETTER SEEN
+0xF162	0xFEB1	# ARABIC LETTER SEEN ISOLATED FORM
+0xF162	0xFEB2	# ARABIC LETTER SEEN FINAL FORM
+0xF163	0xFEB7	# ARABIC LETTER SHEEN INITIAL FORM
+0xF163	0xFEB8	# ARABIC LETTER SHEEN MEDIAL FORM
+0xF164	0x0634	# ARABIC LETTER SHEEN
+0xF164	0xFEB5	# ARABIC LETTER SHEEN ISOLATED FORM
+0xF164	0xFEB6	# ARABIC LETTER SHEEN FINAL FORM
+0xF165	0xFEBB	# ARABIC LETTER SAD INITIAL FORM
+0xF165	0xFEBC	# ARABIC LETTER SAD MEDIAL FORM
+0xF166	0x0635	# ARABIC LETTER SAD
+0xF166	0xFEB9	# ARABIC LETTER SAD ISOLATED FORM
+0xF166	0xFEBA	# ARABIC LETTER SAD FINAL FORM
+0xF167	0xFEBF	# ARABIC LETTER DAD INITIAL FORM
+0xF167	0xFEC0	# ARABIC LETTER DAD MEDIAL FORM
+0xF168	0x0636	# ARABIC LETTER DAD
+0xF168	0xFEBD	# ARABIC LETTER DAD ISOLATED FORM
+0xF168	0xFEBE	# ARABIC LETTER DAD FINAL FORM
+0xF169	0x0637	# ARABIC LETTER TAH
+0xF169	0xFEC1	# ARABIC LETTER TAH ISOLATED FORM
+0xF169	0xFEC2	# ARABIC LETTER TAH FINAL FORM
+0xF169	0xFEC3	# ARABIC LETTER TAH INITIAL FORM
+0xF169	0xFEC4	# ARABIC LETTER TAH MEDIAL FORM
+0xF16A	0x0638	# ARABIC LETTER ZAH
+0xF16A	0xFEC5	# ARABIC LETTER ZAH ISOLATED FORM
+0xF16A	0xFEC6	# ARABIC LETTER ZAH FINAL FORM
+0xF16A	0xFEC7	# ARABIC LETTER ZAH INITIAL FORM
+0xF16A	0xFEC8	# ARABIC LETTER ZAH MEDIAL FORM
+0xF16B	0xFECB	# ARABIC LETTER AIN INITIAL FORM
+0xF16C	0xFECC	# ARABIC LETTER AIN MEDIAL FORM
+0xF16D	0xFECA	# ARABIC LETTER AIN FINAL FORM
+0xF16E	0x0639	# ARABIC LETTER AIN
+0xF16E	0xFEC9	# ARABIC LETTER AIN ISOLATED FORM
+0xF16F	0xFECF	# ARABIC LETTER GHAIN INITIAL FORM
+0xF170	0xFED0	# ARABIC LETTER GHAIN MEDIAL FORM
+0xF171	0xFECE	# ARABIC LETTER GHAIN FINAL FORM
+0xF172	0x063A	# ARABIC LETTER GHAIN
+0xF172	0xFECD	# ARABIC LETTER GHAIN ISOLATED FORM
+0xF173	0xFED3	# ARABIC LETTER FEH INITIAL FORM
+0xF174	0xFED4	# ARABIC LETTER FEH MEDIAL FORM
+0xF175	0x0641	# ARABIC LETTER FEH
+0xF175	0xFED1	# ARABIC LETTER FEH ISOLATED FORM
+0xF175	0xFED2	# ARABIC LETTER FEH FINAL FORM
+0xF176	0xFED7	# ARABIC LETTER QAF INITIAL FORM
+0xF177	0xFED8	# ARABIC LETTER QAF MEDIAL FORM
+0xF178	0x0642	# ARABIC LETTER QAF
+0xF178	0xFED5	# ARABIC LETTER QAF ISOLATED FORM
+0xF178	0xFED6	# ARABIC LETTER QAF FINAL FORM
+0xF179	0xFEDB	# ARABIC LETTER KAF INITIAL FORM
+0xF179	0xFEDC	# ARABIC LETTER KAF MEDIAL FORM
+0xF17A	0x0643	# ARABIC LETTER KAF
+0xF17A	0xFED9	# ARABIC LETTER KAF ISOLATED FORM
+0xF17A	0xFEDA	# ARABIC LETTER KAF FINAL FORM
+0xF17B	0xFEDF	# ARABIC LETTER LAM INITIAL FORM
+0xF17B	0xFEE0	# ARABIC LETTER LAM MEDIAL FORM
+0xF17C	0x0644	# ARABIC LETTER LAM
+0xF17C	0xFEDD	# ARABIC LETTER LAM ISOLATED FORM
+0xF17C	0xFEDE	# ARABIC LETTER LAM FINAL FORM
+0xF17D	0xFEE3	# ARABIC LETTER MEEM INITIAL FORM
+0xF17D	0xFEE4	# ARABIC LETTER MEEM MEDIAL FORM
+0xF17E	0x0645	# ARABIC LETTER MEEM
+0xF17E	0xFEE1	# ARABIC LETTER MEEM ISOLATED FORM
+0xF17E	0xFEE2	# ARABIC LETTER MEEM FINAL FORM
+0xF17F	0xFEE7	# ARABIC LETTER NOON INITIAL FORM
+0xF17F	0xFEE8	# ARABIC LETTER NOON MEDIAL FORM
+0xF1A1	0xFEEB	# ARABIC LETTER HEH INITIAL FORM
+0xF1A2	0xFEEC	# ARABIC LETTER HEH MEDIAL FORM
+0xF1A3	0xFEEA	# ARABIC LETTER HEH FINAL FORM
+0xF1A4	0x0647	# ARABIC LETTER HEH
+0xF1A4	0xFEE9	# ARABIC LETTER HEH ISOLATED FORM
+0xF1A5	0x0648	# ARABIC LETTER WAW
+0xF1A5	0xFEED	# ARABIC LETTER WAW ISOLATED FORM
+0xF1A5	0xFEEE	# ARABIC LETTER WAW FINAL FORM
+0xF1A6	0xFEF3	# ARABIC LETTER YEH INITIAL FORM
+0xF1A6	0xFEF4	# ARABIC LETTER YEH MEDIAL FORM
+0xF1A7	0xFEF2	# ARABIC LETTER YEH FINAL FORM
+0xF1A8	0x064A	# ARABIC LETTER YEH
+0xF1A8	0xFEF1	# ARABIC LETTER YEH ISOLATED FORM
+0xF1A9	0x0629	# ARABIC LETTER TEH MARBUTA
+0xF1A9	0xFE93	# ARABIC LETTER TEH MARBUTA ISOLATED FORM
+0xF1AA	0xFE94	# ARABIC LETTER TEH MARBUTA FINAL FORM
+0xF1AB	0xFEF0	# ARABIC LETTER ALEF MAKSURA FINAL FORM
+0xF1AC	0x0649	# ARABIC LETTER ALEF MAKSURA
+0xF1AC	0xFEEF	# ARABIC LETTER ALEF MAKSURA ISOLATED FORM
+0xF1AD	0x0621	# ARABIC LETTER HAMZA
+0xF1AE	0xFE8B	# ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
+0xF1AE	0xFE8C	# ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM
+0xF1AF	0xFE8A	# ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM
+0xF1B0	0x0030	# DIGIT ZERO
+0xF1B1	0x0031	# DIGIT ONE
+0xF1B2	0x0032	# DIGIT TWO
+0xF1B3	0x0033	# DIGIT THREE
+0xF1B4	0x0034	# DIGIT FOUR
+0xF1B5	0x0035	# DIGIT FIVE
+0xF1B6	0x0036	# DIGIT SIX
+0xF1B7	0x0037	# DIGIT SEVEN
+0xF1B8	0x0038	# DIGIT EIGHT
+0xF1B9	0x0039	# DIGIT NINE
+0xF1BA	0x0626	# ARABIC LETTER YEH WITH HAMZA ABOVE
+0xF1BA	0xFE89	# ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM
+0xF1BB	0x0624	# ARABIC LETTER WAW WITH HAMZA ABOVE
+0xF1BB	0xFE85	# ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
+0xF1BB	0xFE86	# ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM
+0xF1BC	0xFEFC	# ARABIC LIGATURE LAM WITH ALEF FINAL FORM
+0xF1BD	0xFEFB	# ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
+0xF1BE	0xFEF7	# ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
+0xF1BF	0xFEF8	# ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
+0xF1C0	0xFEF5	# ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
+0xF1C1	0xFEF6	# ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
+0xF1C2	0xFEF9	# ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM
+0xF1C3	0xFEFA	# ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM
+0xF1C4	0x064E	# ARABIC FATHA
+0xF1C5	0x064F	# ARABIC DAMMA
+0xF1C6	0x0652	# ARABIC SUKUN
+0xF1C7	0x064B	# ARABIC FATHATAN
+0xF1C8	0x064C	# ARABIC DAMMATAN
+0xF1C9	0x0651	# ARABIC SHADDA
+0xF1CA	0x0650	# ARABIC KASRA
+0xF1CB	0x064D	# ARABIC KASRATAN
+0xF1E1	0x0646	# ARABIC LETTER NOON
+0xF1E1	0xFEE5	# ARABIC LETTER NOON ISOLATED FORM
+0xF1E1	0xFEE6	# ARABIC LETTER NOON FINAL FORM

+ 295 - 0
hbfreetypefont.mod/harfbuzz/src/ArabicPUATraditional.txt

@@ -0,0 +1,295 @@
+#
+#    Name:    Legacy Traditional Arabic encoding
+#
+#    Format: Three tab-separated columns
+#        Column #1 is the PUA code (in hex as 0xXXXX)
+#        Column #2 is the Unicode (in hex as 0xXXXX)
+#        Column #3 is the Unicode name (follows a comment sign, '#')
+#
+#    The entries are in PUA order
+#
+0xF200	0x063B	# ARABIC LETTER KEHEH WITH TWO DOTS ABOVE
+0xF200	0x063C	# ARABIC LETTER KEHEH WITH THREE DOTS BELOW
+0xF200	0x063D	# ARABIC LETTER FARSI YEH WITH INVERTED V
+0xF200	0x063E	# ARABIC LETTER FARSI YEH WITH TWO DOTS ABOVE
+0xF200	0x063F	# ARABIC LETTER FARSI YEH WITH THREE DOTS ABOVE
+0xF200	0x0653	# ARABIC MADDAH ABOVE
+0xF200	0x0654	# ARABIC HAMZA ABOVE
+0xF200	0x0655	# ARABIC HAMZA BELOW
+0xF200	0x0656	# ARABIC SUBSCRIPT ALEF
+0xF200	0x0657	# ARABIC INVERTED DAMMA
+0xF200	0x0658	# ARABIC MARK NOON GHUNNA
+0xF200	0x0659	# ARABIC ZWARAKAY
+0xF200	0x065A	# ARABIC VOWEL SIGN SMALL V ABOVE
+0xF200	0x065B	# ARABIC VOWEL SIGN INVERTED SMALL V ABOVE
+0xF200	0x065C	# ARABIC VOWEL SIGN DOT BELOW
+0xF200	0x065D	# ARABIC REVERSED DAMMA
+0xF200	0x065E	# ARABIC FATHA WITH TWO DOTS
+0xF202	0xFC08	# ARABIC LIGATURE BEH WITH MEEM ISOLATED FORM
+0xF203	0xFC0E	# ARABIC LIGATURE TEH WITH MEEM ISOLATED FORM
+0xF204	0xFC12	# ARABIC LIGATURE THEH WITH MEEM ISOLATED FORM
+0xF205	0xFC42	# ARABIC LIGATURE LAM WITH MEEM ISOLATED FORM
+0xF206	0xFC4E	# ARABIC LIGATURE NOON WITH MEEM ISOLATED FORM
+0xF20C	0x200C	# ZERO WIDTH NON-JOINER
+0xF20D	0x200D	# ZERO WIDTH JOINER
+0xF20E	0x200E	# LEFT-TO-RIGHT MARK
+0xF20F	0x200F	# RIGHT-TO-LEFT MARK
+0xF210	0xFD88	# ARABIC LIGATURE LAM WITH MEEM WITH HAH INITIAL FORM
+0xF212	0xFC3F	# ARABIC LIGATURE LAM WITH JEEM ISOLATED FORM
+0xF213	0xFC40	# ARABIC LIGATURE LAM WITH HAH ISOLATED FORM
+0xF214	0xFC41	# ARABIC LIGATURE LAM WITH KHAH ISOLATED FORM
+0xF215	0xFC6A	# ARABIC LIGATURE BEH WITH REH FINAL FORM
+0xF216	0xFC70	# ARABIC LIGATURE TEH WITH REH FINAL FORM
+0xF217	0xFC91	# ARABIC LIGATURE YEH WITH REH FINAL FORM
+0xF218	0xFCB0	# ARABIC LIGATURE SEEN WITH MEEM INITIAL FORM
+0xF219	0xFD30	# ARABIC LIGATURE SHEEN WITH MEEM INITIAL FORM
+0xF21A	0xFCCD	# ARABIC LIGATURE LAM WITH HEH INITIAL FORM
+0xF21C	0xFC44	# ARABIC LIGATURE LAM WITH YEH ISOLATED FORM
+0xF21D	0xFC0A	# ARABIC LIGATURE BEH WITH YEH ISOLATED FORM
+0xF21E	0xFC10	# ARABIC LIGATURE TEH WITH YEH ISOLATED FORM
+0xF21F	0xFC50	# ARABIC LIGATURE NOON WITH YEH ISOLATED FORM
+0xF220	0x0020	# SPACE
+0xF221	0x0021	# EXCLAMATION MARK
+0xF222	0x0022	# QUOTATION MARK
+0xF223	0x00AB	# LEFT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xF224	0x00BB	# RIGHT-POINTING DOUBLE ANGLE QUOTATION MARK
+0xF225	0x0025	# PERCENT SIGN
+0xF226	0x00D7	# MULTIPLICATION SIGN
+0xF227	0x00F7	# DIVISION SIGN
+0xF228	0x0028	# LEFT PARENTHESIS
+0xF229	0x0029	# RIGHT PARENTHESIS
+0xF22A	0x002A	# ASTERISK
+0xF22B	0x002B	# PLUS SIGN
+0xF22C	0x060C	# ARABIC COMMA
+0xF22D	0x002D	# HYPHEN-MINUS
+0xF22E	0x002E	# FULL STOP
+0xF22F	0x002F	# SOLIDUS
+0xF230	0x0660	# ARABIC-INDIC DIGIT ZERO
+0xF231	0x0661	# ARABIC-INDIC DIGIT ONE
+0xF232	0x0662	# ARABIC-INDIC DIGIT TWO
+0xF233	0x0663	# ARABIC-INDIC DIGIT THREE
+0xF234	0x0664	# ARABIC-INDIC DIGIT FOUR
+0xF235	0x0665	# ARABIC-INDIC DIGIT FIVE
+0xF236	0x0666	# ARABIC-INDIC DIGIT SIX
+0xF237	0x0667	# ARABIC-INDIC DIGIT SEVEN
+0xF238	0x0668	# ARABIC-INDIC DIGIT EIGHT
+0xF239	0x0669	# ARABIC-INDIC DIGIT NINE
+0xF23A	0x003A	# COLON
+0xF23B	0x003B	# SEMICOLON
+0xF23B	0x061B	# ARABIC SEMICOLON
+0xF23C	0x201C	# LEFT DOUBLE QUOTATION MARK
+0xF23D	0x003D	# EQUALS SIGN
+0xF23E	0x201D	# RIGHT DOUBLE QUOTATION MARK
+0xF23F	0x003F	# QUESTION MARK
+0xF23F	0x061F	# ARABIC QUESTION MARK
+0xF241	0x0627	# ARABIC LETTER ALEF
+0xF241	0xFE8D	# ARABIC LETTER ALEF ISOLATED FORM
+0xF242	0xFE8E	# ARABIC LETTER ALEF FINAL FORM
+0xF243	0x0623	# ARABIC LETTER ALEF WITH HAMZA ABOVE
+0xF243	0xFE83	# ARABIC LETTER ALEF WITH HAMZA ABOVE ISOLATED FORM
+0xF244	0xFE84	# ARABIC LETTER ALEF WITH HAMZA ABOVE FINAL FORM
+0xF245	0x0622	# ARABIC LETTER ALEF WITH MADDA ABOVE
+0xF245	0xFE81	# ARABIC LETTER ALEF WITH MADDA ABOVE ISOLATED FORM
+0xF246	0xFE82	# ARABIC LETTER ALEF WITH MADDA ABOVE FINAL FORM
+0xF247	0x0625	# ARABIC LETTER ALEF WITH HAMZA BELOW
+0xF247	0xFE87	# ARABIC LETTER ALEF WITH HAMZA BELOW ISOLATED FORM
+0xF248	0xFE88	# ARABIC LETTER ALEF WITH HAMZA BELOW FINAL FORM
+0xF249	0xFE91	# ARABIC LETTER BEH INITIAL FORM
+0xF24A	0xFE92	# ARABIC LETTER BEH MEDIAL FORM
+0xF24B	0xFE90	# ARABIC LETTER BEH FINAL FORM
+0xF24C	0x0628	# ARABIC LETTER BEH
+0xF24C	0xFE8F	# ARABIC LETTER BEH ISOLATED FORM
+0xF24D	0xFE97	# ARABIC LETTER TEH INITIAL FORM
+0xF24E	0xFE98	# ARABIC LETTER TEH MEDIAL FORM
+0xF24F	0xFE96	# ARABIC LETTER TEH FINAL FORM
+0xF250	0x062A	# ARABIC LETTER TEH
+0xF250	0xFE95	# ARABIC LETTER TEH ISOLATED FORM
+0xF251	0xFE9B	# ARABIC LETTER THEH INITIAL FORM
+0xF252	0xFE9C	# ARABIC LETTER THEH MEDIAL FORM
+0xF253	0xFE9A	# ARABIC LETTER THEH FINAL FORM
+0xF254	0x062B	# ARABIC LETTER THEH
+0xF254	0xFE99	# ARABIC LETTER THEH ISOLATED FORM
+0xF255	0xFE9F	# ARABIC LETTER JEEM INITIAL FORM
+0xF256	0xFEA0	# ARABIC LETTER JEEM MEDIAL FORM
+0xF257	0xFE9E	# ARABIC LETTER JEEM FINAL FORM
+0xF258	0x062C	# ARABIC LETTER JEEM
+0xF258	0xFE9D	# ARABIC LETTER JEEM ISOLATED FORM
+0xF259	0xFEA3	# ARABIC LETTER HAH INITIAL FORM
+0xF25A	0xFEA4	# ARABIC LETTER HAH MEDIAL FORM
+0xF25B	0x005B	# LEFT SQUARE BRACKET
+0xF25C	0xFEA2	# ARABIC LETTER HAH FINAL FORM
+0xF25D	0x005D	# RIGHT SQUARE BRACKET
+0xF25E	0x002C	# COMMA
+0xF25E	0x066B	# ARABIC DECIMAL SEPARATOR
+0xF25E	0x066C	# ARABIC THOUSANDS SEPARATOR
+0xF25F	0x0640	# ARABIC TATWEEL
+0xF260	0x062D	# ARABIC LETTER HAH
+0xF260	0xFEA1	# ARABIC LETTER HAH ISOLATED FORM
+0xF261	0xFEA7	# ARABIC LETTER KHAH INITIAL FORM
+0xF262	0xFEA8	# ARABIC LETTER KHAH MEDIAL FORM
+0xF263	0xFEA6	# ARABIC LETTER KHAH FINAL FORM
+0xF264	0x062E	# ARABIC LETTER KHAH
+0xF264	0xFEA5	# ARABIC LETTER KHAH ISOLATED FORM
+0xF265	0x062F	# ARABIC LETTER DAL
+0xF265	0xFEA9	# ARABIC LETTER DAL ISOLATED FORM
+0xF266	0xFEAA	# ARABIC LETTER DAL FINAL FORM
+0xF267	0x0630	# ARABIC LETTER THAL
+0xF267	0xFEAB	# ARABIC LETTER THAL ISOLATED FORM
+0xF268	0xFEAC	# ARABIC LETTER THAL FINAL FORM
+0xF269	0x0631	# ARABIC LETTER REH
+0xF269	0xFEAD	# ARABIC LETTER REH ISOLATED FORM
+0xF26A	0xFEAE	# ARABIC LETTER REH FINAL FORM
+0xF26B	0x0632	# ARABIC LETTER ZAIN
+0xF26B	0xFEAF	# ARABIC LETTER ZAIN ISOLATED FORM
+0xF26C	0xFEB0	# ARABIC LETTER ZAIN FINAL FORM
+0xF26D	0xFEB3	# ARABIC LETTER SEEN INITIAL FORM
+0xF26E	0xFEB4	# ARABIC LETTER SEEN MEDIAL FORM
+0xF26F	0xFEB2	# ARABIC LETTER SEEN FINAL FORM
+0xF270	0x0633	# ARABIC LETTER SEEN
+0xF270	0xFEB1	# ARABIC LETTER SEEN ISOLATED FORM
+0xF271	0xFEB7	# ARABIC LETTER SHEEN INITIAL FORM
+0xF272	0xFEB8	# ARABIC LETTER SHEEN MEDIAL FORM
+0xF273	0xFEB6	# ARABIC LETTER SHEEN FINAL FORM
+0xF274	0x0634	# ARABIC LETTER SHEEN
+0xF274	0xFEB5	# ARABIC LETTER SHEEN ISOLATED FORM
+0xF275	0xFEBB	# ARABIC LETTER SAD INITIAL FORM
+0xF276	0xFEBC	# ARABIC LETTER SAD MEDIAL FORM
+0xF277	0xFEBA	# ARABIC LETTER SAD FINAL FORM
+0xF278	0x0635	# ARABIC LETTER SAD
+0xF278	0xFEB9	# ARABIC LETTER SAD ISOLATED FORM
+0xF279	0xFEBF	# ARABIC LETTER DAD INITIAL FORM
+0xF27A	0xFEC0	# ARABIC LETTER DAD MEDIAL FORM
+0xF27B	0xFD3E	# ORNATE LEFT PARENTHESIS
+0xF27C	0xFEBE	# ARABIC LETTER DAD FINAL FORM
+0xF27D	0xFD3F	# ORNATE RIGHT PARENTHESIS
+0xF27E	0x0636	# ARABIC LETTER DAD
+0xF27E	0xFEBD	# ARABIC LETTER DAD ISOLATED FORM
+0xF27F	0xFEC3	# ARABIC LETTER TAH INITIAL FORM
+0xF280	0xFC9C	# ARABIC LIGATURE BEH WITH JEEM INITIAL FORM
+0xF281	0xFC9D	# ARABIC LIGATURE BEH WITH HAH INITIAL FORM
+0xF282	0xFC9E	# ARABIC LIGATURE BEH WITH KHAH INITIAL FORM
+0xF283	0xFCA1	# ARABIC LIGATURE TEH WITH JEEM INITIAL FORM
+0xF284	0xFCA2	# ARABIC LIGATURE TEH WITH HAH INITIAL FORM
+0xF285	0xFCA3	# ARABIC LIGATURE TEH WITH KHAH INITIAL FORM
+0xF286	0xFCC9	# ARABIC LIGATURE LAM WITH JEEM INITIAL FORM
+0xF287	0xFCCA	# ARABIC LIGATURE LAM WITH HAH INITIAL FORM
+0xF288	0xFCCB	# ARABIC LIGATURE LAM WITH KHAH INITIAL FORM
+0xF289	0xFCCE	# ARABIC LIGATURE MEEM WITH JEEM INITIAL FORM
+0xF28A	0xFCCF	# ARABIC LIGATURE MEEM WITH HAH INITIAL FORM
+0xF28B	0xFCD0	# ARABIC LIGATURE MEEM WITH KHAH INITIAL FORM
+0xF28D	0xFCD2	# ARABIC LIGATURE NOON WITH JEEM INITIAL FORM
+0xF28E	0xFCD3	# ARABIC LIGATURE NOON WITH HAH INITIAL FORM
+0xF28F	0xFCDA	# ARABIC LIGATURE YEH WITH JEEM INITIAL FORM
+0xF290	0xFCDB	# ARABIC LIGATURE YEH WITH HAH INITIAL FORM
+0xF291	0xFCDC	# ARABIC LIGATURE YEH WITH KHAH INITIAL FORM
+0xF292	0xFC6D	# ARABIC LIGATURE BEH WITH NOON FINAL FORM
+0xF293	0xFC73	# ARABIC LIGATURE TEH WITH NOON FINAL FORM
+0xF294	0xFC94	# ARABIC LIGATURE YEH WITH NOON FINAL FORM
+0xF295	0xFC86	# ARABIC LIGATURE LAM WITH ALEF MAKSURA FINAL FORM
+0xF296	0xFC9F	# ARABIC LIGATURE BEH WITH MEEM INITIAL FORM
+0xF297	0xFCA4	# ARABIC LIGATURE TEH WITH MEEM INITIAL FORM
+0xF298	0xFCD5	# ARABIC LIGATURE NOON WITH MEEM INITIAL FORM
+0xF299	0xFCDD	# ARABIC LIGATURE YEH WITH MEEM INITIAL FORM
+0xF29A	0xFCA8	# ARABIC LIGATURE JEEM WITH MEEM INITIAL FORM
+0xF29B	0xFCAA	# ARABIC LIGATURE HAH WITH MEEM INITIAL FORM
+0xF29C	0xFCAC	# ARABIC LIGATURE KHAH WITH MEEM INITIAL FORM
+0xF29D	0xFCCC	# ARABIC LIGATURE LAM WITH MEEM INITIAL FORM
+0xF29E	0xFCD1	# ARABIC LIGATURE MEEM WITH MEEM INITIAL FORM
+0xF29F	0xFC32	# ARABIC LIGATURE FEH WITH YEH ISOLATED FORM
+0xF2A1	0xFEC2	# ARABIC LETTER TAH FINAL FORM
+0xF2A2	0x0637	# ARABIC LETTER TAH
+0xF2A2	0xFEC1	# ARABIC LETTER TAH ISOLATED FORM
+0xF2A3	0x0638	# ARABIC LETTER ZAH
+0xF2A3	0xFEC7	# ARABIC LETTER ZAH INITIAL FORM
+0xF2A4	0xFEC8	# ARABIC LETTER ZAH MEDIAL FORM
+0xF2A5	0xFEC6	# ARABIC LETTER ZAH FINAL FORM
+0xF2A6	0xFEC5	# ARABIC LETTER ZAH ISOLATED FORM
+0xF2A7	0xFECB	# ARABIC LETTER AIN INITIAL FORM
+0xF2A8	0xFECC	# ARABIC LETTER AIN MEDIAL FORM
+0xF2A9	0xFECA	# ARABIC LETTER AIN FINAL FORM
+0xF2AA	0x0639	# ARABIC LETTER AIN
+0xF2AA	0xFEC9	# ARABIC LETTER AIN ISOLATED FORM
+0xF2AB	0xFECF	# ARABIC LETTER GHAIN INITIAL FORM
+0xF2AC	0xFED0	# ARABIC LETTER GHAIN MEDIAL FORM
+0xF2AD	0xFECE	# ARABIC LETTER GHAIN FINAL FORM
+0xF2AE	0x063A	# ARABIC LETTER GHAIN
+0xF2AE	0xFECD	# ARABIC LETTER GHAIN ISOLATED FORM
+0xF2AF	0xFED3	# ARABIC LETTER FEH INITIAL FORM
+0xF2B0	0xFED4	# ARABIC LETTER FEH MEDIAL FORM
+0xF2B1	0xFED2	# ARABIC LETTER FEH FINAL FORM
+0xF2B2	0x0641	# ARABIC LETTER FEH
+0xF2B2	0xFED1	# ARABIC LETTER FEH ISOLATED FORM
+0xF2B3	0xFED7	# ARABIC LETTER QAF INITIAL FORM
+0xF2B4	0xFED8	# ARABIC LETTER QAF MEDIAL FORM
+0xF2B5	0xFED6	# ARABIC LETTER QAF FINAL FORM
+0xF2B6	0x0642	# ARABIC LETTER QAF
+0xF2B6	0xFED5	# ARABIC LETTER QAF ISOLATED FORM
+0xF2B7	0xFEDB	# ARABIC LETTER KAF INITIAL FORM
+0xF2B8	0xFEDC	# ARABIC LETTER KAF MEDIAL FORM
+0xF2B9	0xFEDA	# ARABIC LETTER KAF FINAL FORM
+0xF2BA	0x0643	# ARABIC LETTER KAF
+0xF2BA	0xFED9	# ARABIC LETTER KAF ISOLATED FORM
+0xF2BB	0xFEDF	# ARABIC LETTER LAM INITIAL FORM
+0xF2BC	0xFEE0	# ARABIC LETTER LAM MEDIAL FORM
+0xF2BD	0xFEDE	# ARABIC LETTER LAM FINAL FORM
+0xF2BE	0x0644	# ARABIC LETTER LAM
+0xF2BE	0xFEDD	# ARABIC LETTER LAM ISOLATED FORM
+0xF2BF	0xFEE3	# ARABIC LETTER MEEM INITIAL FORM
+0xF2C0	0xFEE4	# ARABIC LETTER MEEM MEDIAL FORM
+0xF2C1	0xFEE2	# ARABIC LETTER MEEM FINAL FORM
+0xF2C2	0x0645	# ARABIC LETTER MEEM
+0xF2C2	0xFEE1	# ARABIC LETTER MEEM ISOLATED FORM
+0xF2C3	0xFEE7	# ARABIC LETTER NOON INITIAL FORM
+0xF2C4	0xFEE8	# ARABIC LETTER NOON MEDIAL FORM
+0xF2C5	0xFEE6	# ARABIC LETTER NOON FINAL FORM
+0xF2C6	0x0646	# ARABIC LETTER NOON
+0xF2C6	0xFEE5	# ARABIC LETTER NOON ISOLATED FORM
+0xF2C7	0xFEEB	# ARABIC LETTER HEH INITIAL FORM
+0xF2C8	0xFEEC	# ARABIC LETTER HEH MEDIAL FORM
+0xF2C9	0xFEEA	# ARABIC LETTER HEH FINAL FORM
+0xF2CA	0x0647	# ARABIC LETTER HEH
+0xF2CA	0xFEE9	# ARABIC LETTER HEH ISOLATED FORM
+0xF2CB	0x0648	# ARABIC LETTER WAW
+0xF2CB	0xFEED	# ARABIC LETTER WAW ISOLATED FORM
+0xF2CC	0xFEEE	# ARABIC LETTER WAW FINAL FORM
+0xF2CD	0xFEF3	# ARABIC LETTER YEH INITIAL FORM
+0xF2CE	0xFEF4	# ARABIC LETTER YEH MEDIAL FORM
+0xF2CF	0xFEF2	# ARABIC LETTER YEH FINAL FORM
+0xF2D0	0x064A	# ARABIC LETTER YEH
+0xF2D0	0xFEF1	# ARABIC LETTER YEH ISOLATED FORM
+0xF2D1	0x0629	# ARABIC LETTER TEH MARBUTA
+0xF2D1	0xFE93	# ARABIC LETTER TEH MARBUTA ISOLATED FORM
+0xF2D2	0xFE94	# ARABIC LETTER TEH MARBUTA FINAL FORM
+0xF2D3	0xFEF0	# ARABIC LETTER ALEF MAKSURA FINAL FORM
+0xF2D4	0x0649	# ARABIC LETTER ALEF MAKSURA
+0xF2D4	0xFEEF	# ARABIC LETTER ALEF MAKSURA ISOLATED FORM
+0xF2D5	0x0621	# ARABIC LETTER HAMZA
+0xF2D6	0xFE8B	# ARABIC LETTER YEH WITH HAMZA ABOVE INITIAL FORM
+0xF2D7	0xFE8C	# ARABIC LETTER YEH WITH HAMZA ABOVE MEDIAL FORM
+0xF2D8	0xFE8A	# ARABIC LETTER YEH WITH HAMZA ABOVE FINAL FORM
+0xF2D9	0x0626	# ARABIC LETTER YEH WITH HAMZA ABOVE
+0xF2D9	0xFE89	# ARABIC LETTER YEH WITH HAMZA ABOVE ISOLATED FORM
+0xF2DA	0x0624	# ARABIC LETTER WAW WITH HAMZA ABOVE
+0xF2DA	0xFE85	# ARABIC LETTER WAW WITH HAMZA ABOVE ISOLATED FORM
+0xF2DB	0xFE86	# ARABIC LETTER WAW WITH HAMZA ABOVE FINAL FORM
+0xF2DC	0xFEFB	# ARABIC LIGATURE LAM WITH ALEF ISOLATED FORM
+0xF2DD	0xFEFC	# ARABIC LIGATURE LAM WITH ALEF FINAL FORM
+0xF2DE	0xFEF7	# ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE ISOLATED FORM
+0xF2DF	0xFEF8	# ARABIC LIGATURE LAM WITH ALEF WITH HAMZA ABOVE FINAL FORM
+0xF2E0	0xFEF5	# ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE ISOLATED FORM
+0xF2E1	0xFEF6	# ARABIC LIGATURE LAM WITH ALEF WITH MADDA ABOVE FINAL FORM
+0xF2E2	0xFEF9	# ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW ISOLATED FORM
+0xF2E3	0xFEFA	# ARABIC LIGATURE LAM WITH ALEF WITH HAMZA BELOW FINAL FORM
+0xF2E4	0x064E	# ARABIC FATHA
+0xF2E5	0x064F	# ARABIC DAMMA
+0xF2E6	0x0652	# ARABIC SUKUN
+0xF2E7	0x064B	# ARABIC FATHATAN
+0xF2E8	0x064C	# ARABIC DAMMATAN
+0xF2E9	0x0651	# ARABIC SHADDA
+0xF2EA	0x0650	# ARABIC KASRA
+0xF2EB	0x064D	# ARABIC KASRATAN
+0xF2EC	0xFC60	# ARABIC LIGATURE SHADDA WITH FATHA ISOLATED FORM
+0xF2ED	0xFC61	# ARABIC LIGATURE SHADDA WITH DAMMA ISOLATED FORM
+0xF2EF	0xFC5E	# ARABIC LIGATURE SHADDA WITH DAMMATAN ISOLATED FORM
+0xF2F0	0xFC62	# ARABIC LIGATURE SHADDA WITH KASRA ISOLATED FORM
+0xF2F1	0xFEC4	# ARABIC LETTER TAH MEDIAL FORM

+ 1031 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Color/CBDT/CBDT.hh

@@ -0,0 +1,1031 @@
+/*
+ * Copyright © 2016  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Seigo Nonaka, Calder Kitagawa
+ */
+
+#ifndef OT_COLOR_CBDT_CBDT_HH
+#define OT_COLOR_CBDT_CBDT_HH
+
+#include "../../../hb-open-type.hh"
+#include "../../../hb-paint.hh"
+
+/*
+ * CBLC -- Color Bitmap Location
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/cblc
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/eblc
+ * CBDT -- Color Bitmap Data
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/cbdt
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/ebdt
+ */
+#define HB_OT_TAG_CBLC HB_TAG('C','B','L','C')
+#define HB_OT_TAG_CBDT HB_TAG('C','B','D','T')
+
+
+namespace OT {
+
+struct cblc_bitmap_size_subset_context_t
+{
+  const char *cbdt;
+  unsigned int cbdt_length;
+  hb_vector_t<char> *cbdt_prime;
+  unsigned int size;		/* INOUT
+				 *  Input: old size of IndexSubtable
+				 *  Output: new size of IndexSubtable
+				 */
+  unsigned int num_tables;	/* INOUT
+				 *  Input: old number of subtables.
+				 *  Output: new number of subtables.
+				 */
+  hb_codepoint_t start_glyph;	/* OUT */
+  hb_codepoint_t end_glyph;	/* OUT */
+};
+
+static inline bool
+_copy_data_to_cbdt (hb_vector_t<char> *cbdt_prime,
+		    const void        *data,
+		    unsigned           length)
+{
+  unsigned int new_len = cbdt_prime->length + length;
+  if (unlikely (!cbdt_prime->alloc (new_len))) return false;
+  hb_memcpy (cbdt_prime->arrayZ + cbdt_prime->length, data, length);
+  cbdt_prime->length = new_len;
+  return true;
+}
+
+struct SmallGlyphMetrics
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  void get_extents (hb_font_t *font, hb_glyph_extents_t *extents, bool scale) const
+  {
+    extents->x_bearing = bearingX;
+    extents->y_bearing = bearingY;
+    extents->width = width;
+    extents->height = -static_cast<int> (height);
+
+    if (scale)
+      font->scale_glyph_extents (extents);
+  }
+
+  HBUINT8	height;
+  HBUINT8	width;
+  HBINT8	bearingX;
+  HBINT8	bearingY;
+  HBUINT8	advance;
+  public:
+  DEFINE_SIZE_STATIC (5);
+};
+
+struct BigGlyphMetrics : SmallGlyphMetrics
+{
+  HBINT8	vertBearingX;
+  HBINT8	vertBearingY;
+  HBUINT8	vertAdvance;
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct SBitLineMetrics
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  HBINT8	ascender;
+  HBINT8	decender;
+  HBUINT8	widthMax;
+  HBINT8	caretSlopeNumerator;
+  HBINT8	caretSlopeDenominator;
+  HBINT8	caretOffset;
+  HBINT8	minOriginSB;
+  HBINT8	minAdvanceSB;
+  HBINT8	maxBeforeBL;
+  HBINT8	minAfterBL;
+  HBINT8	padding1;
+  HBINT8	padding2;
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+
+/*
+ * Index Subtables.
+ */
+
+struct IndexSubtableHeader
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  HBUINT16	indexFormat;
+  HBUINT16	imageFormat;
+  HBUINT32	imageDataOffset;
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+template <typename OffsetType>
+struct IndexSubtableFormat1Or3
+{
+  bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  offsetArrayZ.sanitize (c, glyph_count + 1));
+  }
+
+  bool get_image_data (unsigned int idx,
+		       unsigned int *offset,
+		       unsigned int *length) const
+  {
+    if (unlikely (offsetArrayZ[idx + 1] <= offsetArrayZ[idx]))
+      return false;
+
+    *offset = header.imageDataOffset + offsetArrayZ[idx];
+    *length = offsetArrayZ[idx + 1] - offsetArrayZ[idx];
+    return true;
+  }
+
+  bool add_offset (hb_serialize_context_t *c,
+		   unsigned int offset,
+		   unsigned int *size /* OUT (accumulated) */)
+  {
+    TRACE_SERIALIZE (this);
+    Offset<OffsetType> embedded_offset;
+    embedded_offset = offset;
+    *size += sizeof (OffsetType);
+    auto *o = c->embed (embedded_offset);
+    return_trace ((bool) o);
+  }
+
+  IndexSubtableHeader	header;
+  UnsizedArrayOf<Offset<OffsetType>>
+			offsetArrayZ;
+  public:
+  DEFINE_SIZE_ARRAY (8, offsetArrayZ);
+};
+
+struct IndexSubtableFormat1 : IndexSubtableFormat1Or3<HBUINT32> {};
+struct IndexSubtableFormat3 : IndexSubtableFormat1Or3<HBUINT16> {};
+
+struct IndexSubtable
+{
+  bool sanitize (hb_sanitize_context_t *c, unsigned int glyph_count) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.header.sanitize (c)) return_trace (false);
+    hb_barrier ();
+    switch (u.header.indexFormat)
+    {
+    case 1: return_trace (u.format1.sanitize (c, glyph_count));
+    case 3: return_trace (u.format3.sanitize (c, glyph_count));
+    default:return_trace (true);
+    }
+  }
+
+  bool
+  finish_subtable (hb_serialize_context_t *c,
+		   unsigned int cbdt_prime_len,
+		   unsigned int num_glyphs,
+		   unsigned int *size /* OUT (accumulated) */)
+  {
+    TRACE_SERIALIZE (this);
+
+    unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset;
+    switch (u.header.indexFormat)
+    {
+    case 1: return_trace (u.format1.add_offset (c, local_offset, size));
+    case 3: {
+      if (!u.format3.add_offset (c, local_offset, size))
+	return_trace (false);
+      if (!(num_glyphs & 0x01))  // Pad to 32-bit alignment if needed.
+	return_trace (u.format3.add_offset (c, 0, size));
+      return_trace (true);
+    }
+    // TODO: implement 2, 4, 5.
+    case 2: case 4:  // No-op.
+    case 5:  // Pad to 32-bit aligned.
+    default: return_trace (false);
+    }
+  }
+
+  bool
+  fill_missing_glyphs (hb_serialize_context_t *c,
+		       unsigned int cbdt_prime_len,
+		       unsigned int num_missing,
+		       unsigned int *size /* OUT (accumulated) */,
+		       unsigned int *num_glyphs /* OUT (accumulated) */)
+  {
+    TRACE_SERIALIZE (this);
+
+    unsigned int local_offset = cbdt_prime_len - u.header.imageDataOffset;
+    switch (u.header.indexFormat)
+    {
+    case 1: {
+      for (unsigned int i = 0; i < num_missing; i++)
+      {
+	if (unlikely (!u.format1.add_offset (c, local_offset, size)))
+	  return_trace (false);
+	*num_glyphs += 1;
+      }
+      return_trace (true);
+    }
+    case 3: {
+      for (unsigned int i = 0; i < num_missing; i++)
+      {
+	if (unlikely (!u.format3.add_offset (c, local_offset, size)))
+	  return_trace (false);
+	*num_glyphs += 1;
+      }
+      return_trace (true);
+    }
+    // TODO: implement 2, 4, 5.
+    case 2:  // Add empty space in cbdt_prime?.
+    case 4: case 5:  // No-op as sparse is supported.
+    default: return_trace (false);
+    }
+  }
+
+  bool
+  copy_glyph_at_idx (hb_serialize_context_t *c, unsigned int idx,
+		     const char *cbdt, unsigned int cbdt_length,
+		     hb_vector_t<char> *cbdt_prime /* INOUT */,
+		     IndexSubtable *subtable_prime /* INOUT */,
+		     unsigned int *size /* OUT (accumulated) */) const
+  {
+    TRACE_SERIALIZE (this);
+
+    unsigned int offset, length, format;
+    if (unlikely (!get_image_data (idx, &offset, &length, &format))) return_trace (false);
+    if (unlikely (offset > cbdt_length || cbdt_length - offset < length)) return_trace (false);
+
+    auto *header_prime = subtable_prime->get_header ();
+    unsigned int new_local_offset = cbdt_prime->length - (unsigned int) header_prime->imageDataOffset;
+    if (unlikely (!_copy_data_to_cbdt (cbdt_prime, cbdt + offset, length))) return_trace (false);
+
+    return_trace (subtable_prime->add_offset (c, new_local_offset, size));
+  }
+
+  bool
+  add_offset (hb_serialize_context_t *c, unsigned int local_offset,
+	      unsigned int *size /* OUT (accumulated) */)
+  {
+    TRACE_SERIALIZE (this);
+    switch (u.header.indexFormat)
+    {
+    case 1: return_trace (u.format1.add_offset (c, local_offset, size));
+    case 3: return_trace (u.format3.add_offset (c, local_offset, size));
+    // TODO: Implement tables 2, 4, 5
+    case 2:  // Should be a no-op.
+    case 4: case 5:  // Handle sparse cases.
+    default: return_trace (false);
+    }
+  }
+
+  bool get_extents (hb_glyph_extents_t *extents HB_UNUSED, bool scale HB_UNUSED) const
+  {
+    switch (u.header.indexFormat)
+    {
+    case 2: case 5: /* TODO */
+    case 1: case 3: case 4: /* Variable-metrics formats do not have metrics here. */
+    default:return (false);
+    }
+  }
+
+  bool
+  get_image_data (unsigned int idx, unsigned int *offset,
+		  unsigned int *length, unsigned int *format) const
+  {
+    *format = u.header.imageFormat;
+    switch (u.header.indexFormat)
+    {
+    case 1: return u.format1.get_image_data (idx, offset, length);
+    case 3: return u.format3.get_image_data (idx, offset, length);
+    default: return false;
+    }
+  }
+
+  const IndexSubtableHeader* get_header () const { return &u.header; }
+
+  void populate_header (unsigned index_format,
+			unsigned image_format,
+			unsigned int image_data_offset,
+			unsigned int *size)
+  {
+    u.header.indexFormat = index_format;
+    u.header.imageFormat = image_format;
+    u.header.imageDataOffset = image_data_offset;
+    switch (u.header.indexFormat)
+    {
+    case 1: *size += IndexSubtableFormat1::min_size; break;
+    case 3: *size += IndexSubtableFormat3::min_size; break;
+    }
+  }
+
+  protected:
+  union {
+  IndexSubtableHeader	header;
+  IndexSubtableFormat1	format1;
+  IndexSubtableFormat3	format3;
+  /* TODO: Format 2, 4, 5. */
+  } u;
+  public:
+  DEFINE_SIZE_UNION (8, header);
+};
+
+struct IndexSubtableRecord
+{
+  /* XXX Remove this and fix by not inserting it into vector. */
+  IndexSubtableRecord& operator = (const IndexSubtableRecord &o)
+  {
+    firstGlyphIndex = o.firstGlyphIndex;
+    lastGlyphIndex = o.lastGlyphIndex;
+    offsetToSubtable = (unsigned) o.offsetToSubtable;
+    assert (offsetToSubtable.is_null ());
+    return *this;
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  hb_barrier () &&
+		  firstGlyphIndex <= lastGlyphIndex &&
+		  offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1));
+  }
+
+  const IndexSubtable* get_subtable (const void *base) const
+  {
+    return &(base+offsetToSubtable);
+  }
+
+  bool add_new_subtable (hb_subset_context_t* c,
+			 cblc_bitmap_size_subset_context_t *bitmap_size_context,
+			 IndexSubtableRecord *record,
+			 const hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> *lookup, /* IN */
+			 const void *base,
+			 unsigned int *start /* INOUT */) const
+  {
+    TRACE_SERIALIZE (this);
+
+    auto *subtable = c->serializer->start_embed<IndexSubtable> ();
+    if (unlikely (!c->serializer->extend_min (subtable))) return_trace (false);
+
+    auto *old_subtable = get_subtable (base);
+    auto *old_header = old_subtable->get_header ();
+
+    subtable->populate_header (old_header->indexFormat,
+			       old_header->imageFormat,
+			       bitmap_size_context->cbdt_prime->length,
+			       &bitmap_size_context->size);
+
+    unsigned int num_glyphs = 0;
+    bool early_exit = false;
+    for (unsigned int i = *start; i < lookup->length; i++)
+    {
+      hb_codepoint_t new_gid = (*lookup)[i].first;
+      const IndexSubtableRecord *next_record = (*lookup)[i].second;
+      const IndexSubtable *next_subtable = next_record->get_subtable (base);
+      auto *next_header = next_subtable->get_header ();
+      if (next_header != old_header)
+      {
+	*start = i;
+	early_exit = true;
+	break;
+      }
+      unsigned int num_missing = record->add_glyph_for_subset (new_gid);
+      if (unlikely (!subtable->fill_missing_glyphs (c->serializer,
+						    bitmap_size_context->cbdt_prime->length,
+						    num_missing,
+						    &bitmap_size_context->size,
+						    &num_glyphs)))
+	return_trace (false);
+
+      hb_codepoint_t old_gid = 0;
+      c->plan->old_gid_for_new_gid (new_gid, &old_gid);
+      if (old_gid < next_record->firstGlyphIndex)
+	return_trace (false);
+
+      unsigned int old_idx = (unsigned int) old_gid - next_record->firstGlyphIndex;
+      if (unlikely (!next_subtable->copy_glyph_at_idx (c->serializer,
+						       old_idx,
+						       bitmap_size_context->cbdt,
+						       bitmap_size_context->cbdt_length,
+						       bitmap_size_context->cbdt_prime,
+						       subtable,
+						       &bitmap_size_context->size)))
+	return_trace (false);
+      num_glyphs += 1;
+    }
+    if (!early_exit)
+      *start = lookup->length;
+    if (unlikely (!subtable->finish_subtable (c->serializer,
+					      bitmap_size_context->cbdt_prime->length,
+					      num_glyphs,
+					      &bitmap_size_context->size)))
+      return_trace (false);
+    return_trace (true);
+  }
+
+  bool add_new_record (hb_subset_context_t *c,
+		       cblc_bitmap_size_subset_context_t *bitmap_size_context,
+		       const hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> *lookup, /* IN */
+		       const void *base,
+		       unsigned int *start, /* INOUT */
+		       hb_vector_t<IndexSubtableRecord>* records /* INOUT */) const
+  {
+    TRACE_SERIALIZE (this);
+    auto snap = c->serializer->snapshot ();
+    unsigned int old_size = bitmap_size_context->size;
+    unsigned int old_cbdt_prime_length = bitmap_size_context->cbdt_prime->length;
+
+    // Set to invalid state to indicate filling glyphs is not yet started.
+    if (unlikely (!c->serializer->check_success (records->resize (records->length + 1))))
+      return_trace (false);
+
+    records->tail ().firstGlyphIndex = 1;
+    records->tail ().lastGlyphIndex = 0;
+    bitmap_size_context->size += IndexSubtableRecord::min_size;
+
+    c->serializer->push ();
+
+    if (unlikely (!add_new_subtable (c, bitmap_size_context, &(records->tail ()), lookup, base, start)))
+    {
+      c->serializer->pop_discard ();
+      c->serializer->revert (snap);
+      bitmap_size_context->cbdt_prime->shrink (old_cbdt_prime_length);
+      bitmap_size_context->size = old_size;
+      records->resize (records->length - 1);
+      return_trace (false);
+    }
+
+    bitmap_size_context->num_tables += 1;
+    return_trace (true);
+  }
+
+  unsigned int add_glyph_for_subset (hb_codepoint_t gid)
+  {
+    if (firstGlyphIndex > lastGlyphIndex)
+    {
+      firstGlyphIndex = gid;
+      lastGlyphIndex = gid;
+      return 0;
+    }
+    // TODO maybe assert? this shouldn't occur.
+    if (lastGlyphIndex > gid)
+      return 0;
+    unsigned int num_missing = (unsigned int) (gid - lastGlyphIndex - 1);
+    lastGlyphIndex = gid;
+    return num_missing;
+  }
+
+  bool get_extents (hb_glyph_extents_t *extents, const void *base, bool scale) const
+  { return (base+offsetToSubtable).get_extents (extents, scale); }
+
+  bool get_image_data (unsigned int  gid,
+		       const void   *base,
+		       unsigned int *offset,
+		       unsigned int *length,
+		       unsigned int *format) const
+  {
+    if (gid < firstGlyphIndex || gid > lastGlyphIndex) return false;
+    return (base+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
+						   offset, length, format);
+  }
+
+  HBGlyphID16			firstGlyphIndex;
+  HBGlyphID16			lastGlyphIndex;
+  Offset32To<IndexSubtable>	offsetToSubtable;
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct IndexSubtableArray
+{
+  friend struct CBDT;
+
+  bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (indexSubtablesZ.sanitize (c, count, this));
+  }
+
+  void
+  build_lookup (hb_subset_context_t *c, cblc_bitmap_size_subset_context_t *bitmap_size_context,
+		hb_vector_t<hb_pair_t<hb_codepoint_t,
+		const IndexSubtableRecord*>> *lookup /* OUT */) const
+  {
+    bool start_glyph_is_set = false;
+    unsigned num_glyphs = c->plan->num_output_glyphs ();
+    for (hb_codepoint_t new_gid = 0; new_gid < num_glyphs; new_gid++)
+    {
+      hb_codepoint_t old_gid;
+      if (unlikely (!c->plan->old_gid_for_new_gid (new_gid, &old_gid))) continue;
+
+      const IndexSubtableRecord* record = find_table (old_gid, bitmap_size_context->num_tables);
+      if (unlikely (!record)) continue;
+
+      // Don't add gaps to the lookup. The best way to determine if a glyph is a
+      // gap is that it has no image data.
+      unsigned int offset, length, format;
+      if (unlikely (!record->get_image_data (old_gid, this, &offset, &length, &format))) continue;
+
+      lookup->push (hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*> (new_gid, record));
+
+      if (!start_glyph_is_set)
+      {
+	bitmap_size_context->start_glyph = new_gid;
+	start_glyph_is_set = true;
+      }
+
+      bitmap_size_context->end_glyph = new_gid;
+    }
+  }
+
+  bool
+  subset (hb_subset_context_t *c,
+	  cblc_bitmap_size_subset_context_t *bitmap_size_context) const
+  {
+    TRACE_SUBSET (this);
+
+    hb_vector_t<hb_pair_t<hb_codepoint_t, const IndexSubtableRecord*>> lookup;
+    build_lookup (c, bitmap_size_context, &lookup);
+    if (unlikely (!c->serializer->propagate_error (lookup)))
+      return false;
+
+    bitmap_size_context->size = 0;
+    bitmap_size_context->num_tables = 0;
+    hb_vector_t<IndexSubtableRecord> records;
+    for (unsigned int start = 0; start < lookup.length;)
+    {
+      if (unlikely (!lookup[start].second->add_new_record (c, bitmap_size_context, &lookup, this, &start, &records)))
+      {
+	// Discard any leftover pushes to the serializer from successful records.
+	for (unsigned int i = 0; i < records.length; i++)
+	  c->serializer->pop_discard ();
+	return_trace (false);
+      }
+    }
+
+    /* Workaround to ensure offset ordering is from least to greatest when
+     * resolving links. */
+    hb_vector_t<hb_serialize_context_t::objidx_t> objidxs;
+    for (unsigned int i = 0; i < records.length; i++)
+      objidxs.push (c->serializer->pop_pack ());
+    for (unsigned int i = 0; i < records.length; i++)
+    {
+      IndexSubtableRecord* record = c->serializer->embed (records[i]);
+      if (unlikely (!record)) return_trace (false);
+      c->serializer->add_link (record->offsetToSubtable, objidxs[records.length - 1 - i]);
+    }
+    return_trace (true);
+  }
+
+  public:
+  const IndexSubtableRecord* find_table (hb_codepoint_t glyph, unsigned int numTables) const
+  {
+    for (unsigned int i = 0; i < numTables; ++i)
+    {
+      unsigned int firstGlyphIndex = indexSubtablesZ[i].firstGlyphIndex;
+      unsigned int lastGlyphIndex = indexSubtablesZ[i].lastGlyphIndex;
+      if (firstGlyphIndex <= glyph && glyph <= lastGlyphIndex)
+	return &indexSubtablesZ[i];
+    }
+    return nullptr;
+  }
+
+  protected:
+  UnsizedArrayOf<IndexSubtableRecord>	indexSubtablesZ;
+};
+
+struct BitmapSizeTable
+{
+  friend struct CBLC;
+  friend struct CBDT;
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  hb_barrier () &&
+		  indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) &&
+		  horizontal.sanitize (c) &&
+		  vertical.sanitize (c));
+  }
+
+  const IndexSubtableRecord *
+  find_table (hb_codepoint_t glyph, const void *base, const void **out_base) const
+  {
+    *out_base = &(base+indexSubtableArrayOffset);
+    return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables);
+  }
+
+  bool
+  subset (hb_subset_context_t *c, const void *base,
+	  const char *cbdt, unsigned int cbdt_length,
+	  hb_vector_t<char> *cbdt_prime /* INOUT */) const
+  {
+    TRACE_SUBSET (this);
+    auto *out_table = c->serializer->embed (this);
+    if (unlikely (!out_table)) return_trace (false);
+
+    cblc_bitmap_size_subset_context_t bitmap_size_context;
+    bitmap_size_context.cbdt = cbdt;
+    bitmap_size_context.cbdt_length = cbdt_length;
+    bitmap_size_context.cbdt_prime = cbdt_prime;
+    bitmap_size_context.size = indexTablesSize;
+    bitmap_size_context.num_tables = numberOfIndexSubtables;
+    bitmap_size_context.start_glyph = 1;
+    bitmap_size_context.end_glyph = 0;
+
+    if (!out_table->indexSubtableArrayOffset.serialize_subset (c,
+							       indexSubtableArrayOffset,
+							       base,
+							       &bitmap_size_context))
+      return_trace (false);
+    if (!bitmap_size_context.size ||
+	!bitmap_size_context.num_tables ||
+	bitmap_size_context.start_glyph > bitmap_size_context.end_glyph)
+      return_trace (false);
+
+    out_table->indexTablesSize = bitmap_size_context.size;
+    out_table->numberOfIndexSubtables = bitmap_size_context.num_tables;
+    out_table->startGlyphIndex = bitmap_size_context.start_glyph;
+    out_table->endGlyphIndex = bitmap_size_context.end_glyph;
+    return_trace (true);
+  }
+
+  protected:
+  NNOffset32To<IndexSubtableArray>
+			indexSubtableArrayOffset;
+  HBUINT32		indexTablesSize;
+  HBUINT32		numberOfIndexSubtables;
+  HBUINT32		colorRef;
+  SBitLineMetrics	horizontal;
+  SBitLineMetrics	vertical;
+  HBGlyphID16		startGlyphIndex;
+  HBGlyphID16		endGlyphIndex;
+  HBUINT8		ppemX;
+  HBUINT8		ppemY;
+  HBUINT8		bitDepth;
+  HBINT8		flags;
+  public:
+  DEFINE_SIZE_STATIC (48);
+};
+
+
+/*
+ * Glyph Bitmap Data Formats.
+ */
+
+struct GlyphBitmapDataFormat17
+{
+  SmallGlyphMetrics	glyphMetrics;
+  Array32Of<HBUINT8>	data;
+  public:
+  DEFINE_SIZE_ARRAY (9, data);
+};
+
+struct GlyphBitmapDataFormat18
+{
+  BigGlyphMetrics	glyphMetrics;
+  Array32Of<HBUINT8>	data;
+  public:
+  DEFINE_SIZE_ARRAY (12, data);
+};
+
+struct GlyphBitmapDataFormat19
+{
+  Array32Of<HBUINT8>	data;
+  public:
+  DEFINE_SIZE_ARRAY (4, data);
+};
+
+struct CBLC
+{
+  friend struct CBDT;
+
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_CBLC;
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  hb_barrier () &&
+		  likely (version.major == 2 || version.major == 3) &&
+		  hb_barrier () &&
+		  sizeTables.sanitize (c, this));
+  }
+
+  static bool
+  sink_cbdt (hb_subset_context_t *c, hb_vector_t<char>* cbdt_prime)
+  {
+    hb_blob_t *cbdt_prime_blob = hb_blob_create (cbdt_prime->arrayZ,
+						 cbdt_prime->length,
+						 HB_MEMORY_MODE_WRITABLE,
+						 cbdt_prime->arrayZ,
+						 hb_free);
+    cbdt_prime->init ();  // Leak arrayZ to the blob.
+    bool ret = c->plan->add_table (HB_OT_TAG_CBDT, cbdt_prime_blob);
+    hb_blob_destroy (cbdt_prime_blob);
+    return ret;
+  }
+
+  bool
+  subset_size_table (hb_subset_context_t *c, const BitmapSizeTable& table,
+		     const char *cbdt /* IN */, unsigned int cbdt_length,
+		     CBLC *cblc_prime /* INOUT */, hb_vector_t<char> *cbdt_prime /* INOUT */) const
+  {
+    TRACE_SUBSET (this);
+    cblc_prime->sizeTables.len++;
+
+    auto snap = c->serializer->snapshot ();
+    auto cbdt_prime_len = cbdt_prime->length;
+
+    if (!table.subset (c, this, cbdt, cbdt_length, cbdt_prime))
+    {
+      cblc_prime->sizeTables.len--;
+      c->serializer->revert (snap);
+      cbdt_prime->shrink (cbdt_prime_len);
+      return_trace (false);
+    }
+    return_trace (true);
+  }
+
+  // Implemented in cc file as it depends on definition of CBDT.
+  HB_INTERNAL bool subset (hb_subset_context_t *c) const;
+
+  protected:
+  const BitmapSizeTable &choose_strike (hb_font_t *font) const
+  {
+    unsigned count = sizeTables.len;
+    if (unlikely (!count))
+      return Null (BitmapSizeTable);
+
+    unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
+    if (!requested_ppem)
+      requested_ppem = 1<<30; /* Choose largest strike. */
+    unsigned int best_i = 0;
+    unsigned int best_ppem = hb_max (sizeTables[0].ppemX, sizeTables[0].ppemY);
+
+    for (unsigned int i = 1; i < count; i++)
+    {
+      unsigned int ppem = hb_max (sizeTables[i].ppemX, sizeTables[i].ppemY);
+      if ((requested_ppem <= ppem && ppem < best_ppem) ||
+	  (requested_ppem > best_ppem && ppem > best_ppem))
+      {
+	best_i = i;
+	best_ppem = ppem;
+      }
+    }
+
+    return sizeTables[best_i];
+  }
+
+  protected:
+  FixedVersion<>		version;
+  Array32Of<BitmapSizeTable>	sizeTables;
+  public:
+  DEFINE_SIZE_ARRAY (8, sizeTables);
+};
+
+struct CBDT
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_CBDT;
+
+  struct accelerator_t
+  {
+    accelerator_t (hb_face_t *face)
+    {
+      this->cblc = hb_sanitize_context_t ().reference_table<CBLC> (face);
+      this->cbdt = hb_sanitize_context_t ().reference_table<CBDT> (face);
+
+      upem = hb_face_get_upem (face);
+    }
+    ~accelerator_t ()
+    {
+      this->cblc.destroy ();
+      this->cbdt.destroy ();
+    }
+
+    bool
+    get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents, bool scale = true) const
+    {
+      const void *base;
+      const BitmapSizeTable &strike = this->cblc->choose_strike (font);
+      const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base);
+      if (!subtable_record || !strike.ppemX || !strike.ppemY)
+	return false;
+
+      if (subtable_record->get_extents (extents, base, scale))
+	return true;
+
+      unsigned int image_offset = 0, image_length = 0, image_format = 0;
+      if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format))
+	return false;
+
+      unsigned int cbdt_len = cbdt.get_length ();
+      if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
+	return false;
+
+      switch (image_format)
+      {
+      case 17: {
+	if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
+	  return false;
+	auto &glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
+	glyphFormat17.glyphMetrics.get_extents (font, extents, scale);
+	break;
+      }
+      case 18: {
+	if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
+	  return false;
+	auto &glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
+	glyphFormat18.glyphMetrics.get_extents (font, extents, scale);
+	break;
+      }
+      default: return false; /* TODO: Support other image formats. */
+      }
+
+      /* Convert to font units. */
+      if (scale)
+      {
+	float x_scale = upem / (float) strike.ppemX;
+	float y_scale = upem / (float) strike.ppemY;
+	extents->x_bearing = roundf (extents->x_bearing * x_scale);
+	extents->y_bearing = roundf (extents->y_bearing * y_scale);
+	extents->width = roundf (extents->width * x_scale);
+	extents->height = roundf (extents->height * y_scale);
+      }
+
+      return true;
+    }
+
+    hb_blob_t*
+    reference_png (hb_font_t *font, hb_codepoint_t glyph) const
+    {
+      const void *base;
+      const BitmapSizeTable &strike = this->cblc->choose_strike (font);
+      const IndexSubtableRecord *subtable_record = strike.find_table (glyph, cblc, &base);
+      if (!subtable_record || !strike.ppemX || !strike.ppemY)
+	return hb_blob_get_empty ();
+
+      unsigned int image_offset = 0, image_length = 0, image_format = 0;
+      if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format))
+	return hb_blob_get_empty ();
+
+      unsigned int cbdt_len = cbdt.get_length ();
+      if (unlikely (image_offset > cbdt_len || cbdt_len - image_offset < image_length))
+	return hb_blob_get_empty ();
+
+      switch (image_format)
+      {
+      case 17:
+      {
+	if (unlikely (image_length < GlyphBitmapDataFormat17::min_size))
+	  return hb_blob_get_empty ();
+	auto &glyphFormat17 = StructAtOffset<GlyphBitmapDataFormat17> (this->cbdt, image_offset);
+	return hb_blob_create_sub_blob (cbdt.get_blob (),
+					image_offset + GlyphBitmapDataFormat17::min_size,
+					glyphFormat17.data.len);
+      }
+      case 18:
+      {
+	if (unlikely (image_length < GlyphBitmapDataFormat18::min_size))
+	  return hb_blob_get_empty ();
+	auto &glyphFormat18 = StructAtOffset<GlyphBitmapDataFormat18> (this->cbdt, image_offset);
+	return hb_blob_create_sub_blob (cbdt.get_blob (),
+					image_offset + GlyphBitmapDataFormat18::min_size,
+					glyphFormat18.data.len);
+      }
+      case 19:
+      {
+	if (unlikely (image_length < GlyphBitmapDataFormat19::min_size))
+	  return hb_blob_get_empty ();
+	auto &glyphFormat19 = StructAtOffset<GlyphBitmapDataFormat19> (this->cbdt, image_offset);
+	return hb_blob_create_sub_blob (cbdt.get_blob (),
+					image_offset + GlyphBitmapDataFormat19::min_size,
+					glyphFormat19.data.len);
+      }
+      default: return hb_blob_get_empty (); /* TODO: Support other image formats. */
+      }
+    }
+
+    bool has_data () const { return cbdt.get_length (); }
+
+    bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
+    {
+      hb_glyph_extents_t extents;
+      hb_glyph_extents_t pixel_extents;
+      hb_blob_t *blob = reference_png (font, glyph);
+
+      if (unlikely (blob == hb_blob_get_empty ()))
+        return false;
+
+      if (unlikely (!hb_font_get_glyph_extents (font, glyph, &extents)))
+        return false;
+
+      if (unlikely (!get_extents (font, glyph, &pixel_extents, false)))
+        return false;
+
+      bool ret = funcs->image (data,
+			       blob,
+			       pixel_extents.width, -pixel_extents.height,
+			       HB_PAINT_IMAGE_FORMAT_PNG,
+			       font->slant_xy,
+			       &extents);
+
+      hb_blob_destroy (blob);
+      return ret;
+    }
+
+    private:
+    hb_blob_ptr_t<CBLC> cblc;
+    hb_blob_ptr_t<CBDT> cbdt;
+
+    unsigned int upem;
+  };
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  hb_barrier () &&
+		  likely (version.major == 2 || version.major == 3));
+  }
+
+  protected:
+  FixedVersion<>		version;
+  UnsizedArrayOf<HBUINT8>	dataZ;
+  public:
+  DEFINE_SIZE_ARRAY (4, dataZ);
+};
+
+inline bool
+CBLC::subset (hb_subset_context_t *c) const
+{
+  TRACE_SUBSET (this);
+
+  // Use a vector as a secondary buffer as the tables need to be built in parallel.
+  hb_vector_t<char> cbdt_prime;
+
+  auto *cblc_prime = c->serializer->start_embed<CBLC> ();
+  if (unlikely (!c->serializer->extend_min (cblc_prime))) return_trace (false);
+  cblc_prime->version = version;
+
+  hb_blob_t* cbdt_blob = hb_sanitize_context_t ().reference_table<CBDT> (c->plan->source);
+  unsigned int cbdt_length;
+  CBDT* cbdt = (CBDT *) hb_blob_get_data (cbdt_blob, &cbdt_length);
+  if (unlikely (cbdt_length < CBDT::min_size))
+  {
+    hb_blob_destroy (cbdt_blob);
+    return_trace (false);
+  }
+  _copy_data_to_cbdt (&cbdt_prime, cbdt, CBDT::min_size);
+
+  for (const BitmapSizeTable& table : + sizeTables.iter ())
+    subset_size_table (c, table, (const char *) cbdt, cbdt_length, cblc_prime, &cbdt_prime);
+
+  hb_blob_destroy (cbdt_blob);
+
+  return_trace (CBLC::sink_cbdt (c, &cbdt_prime));
+}
+
+struct CBDT_accelerator_t : CBDT::accelerator_t {
+  CBDT_accelerator_t (hb_face_t *face) : CBDT::accelerator_t (face) {}
+};
+
+
+} /* namespace OT */
+
+#endif /* OT_COLOR_CBDT_CBDT_HH */

+ 2745 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Color/COLR/COLR.hh

@@ -0,0 +1,2745 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ * Copyright © 2020  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Calder Kitagawa
+ */
+
+#ifndef OT_COLOR_COLR_COLR_HH
+#define OT_COLOR_COLR_COLR_HH
+
+#include "../../../hb.hh"
+#include "../../../hb-open-type.hh"
+#include "../../../hb-ot-var-common.hh"
+#include "../../../hb-paint.hh"
+#include "../../../hb-paint-extents.hh"
+
+/*
+ * COLR -- Color
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/colr
+ */
+#define HB_OT_TAG_COLR HB_TAG('C','O','L','R')
+
+namespace OT {
+struct hb_paint_context_t;
+}
+
+namespace OT {
+
+struct COLR;
+
+struct Paint;
+
+struct hb_paint_context_t :
+       hb_dispatch_context_t<hb_paint_context_t>
+{
+  const char *get_name () { return "PAINT"; }
+  template <typename T>
+  return_t dispatch (const T &obj) { obj.paint_glyph (this); return hb_empty_t (); }
+  static return_t default_return_value () { return hb_empty_t (); }
+
+  const COLR* get_colr_table () const
+  { return reinterpret_cast<const COLR *> (base); }
+
+public:
+  const void *base;
+  hb_paint_funcs_t *funcs;
+  void *data;
+  hb_font_t *font;
+  unsigned int palette_index;
+  hb_color_t foreground;
+  ItemVarStoreInstancer &instancer;
+  hb_map_t current_glyphs;
+  hb_map_t current_layers;
+  int depth_left = HB_MAX_NESTING_LEVEL;
+  int edge_count = HB_MAX_GRAPH_EDGE_COUNT;
+
+  hb_paint_context_t (const void *base_,
+		      hb_paint_funcs_t *funcs_,
+		      void *data_,
+                      hb_font_t *font_,
+                      unsigned int palette_,
+                      hb_color_t foreground_,
+		      ItemVarStoreInstancer &instancer_) :
+    base (base_),
+    funcs (funcs_),
+    data (data_),
+    font (font_),
+    palette_index (palette_),
+    foreground (foreground_),
+    instancer (instancer_)
+  { }
+
+  hb_color_t get_color (unsigned int color_index, float alpha, hb_bool_t *is_foreground)
+  {
+    hb_color_t color = foreground;
+
+    *is_foreground = true;
+
+    if (color_index != 0xffff)
+    {
+      if (!funcs->custom_palette_color (data, color_index, &color))
+      {
+	unsigned int clen = 1;
+	hb_face_t *face = hb_font_get_face (font);
+
+	hb_ot_color_palette_get_colors (face, palette_index, color_index, &clen, &color);
+      }
+
+      *is_foreground = false;
+    }
+
+    return HB_COLOR (hb_color_get_blue (color),
+                     hb_color_get_green (color),
+                     hb_color_get_red (color),
+                     hb_color_get_alpha (color) * alpha);
+  }
+
+  inline void recurse (const Paint &paint);
+};
+
+struct hb_colrv1_closure_context_t :
+       hb_dispatch_context_t<hb_colrv1_closure_context_t>
+{
+  template <typename T>
+  return_t dispatch (const T &obj)
+  {
+    if (unlikely (nesting_level_left == 0))
+      return hb_empty_t ();
+
+    if (paint_visited (&obj))
+      return hb_empty_t ();
+
+    nesting_level_left--;
+    obj.closurev1 (this);
+    nesting_level_left++;
+    return hb_empty_t ();
+  }
+  static return_t default_return_value () { return hb_empty_t (); }
+
+  bool paint_visited (const void *paint)
+  {
+    hb_codepoint_t delta = (hb_codepoint_t) ((uintptr_t) paint - (uintptr_t) base);
+    if (visited_paint.in_error() || visited_paint.has (delta))
+      return true;
+
+    visited_paint.add (delta);
+    return false;
+  }
+
+  const COLR* get_colr_table () const
+  { return reinterpret_cast<const COLR *> (base); }
+
+  void add_glyph (unsigned glyph_id)
+  { glyphs->add (glyph_id); }
+
+  void add_layer_indices (unsigned first_layer_index, unsigned num_of_layers)
+  { layer_indices->add_range (first_layer_index, first_layer_index + num_of_layers - 1); }
+
+  void add_palette_index (unsigned palette_index)
+  { palette_indices->add (palette_index); }
+
+  void add_var_idxes (unsigned first_var_idx, unsigned num_idxes)
+  {
+    if (!num_idxes || first_var_idx == VarIdx::NO_VARIATION) return;
+    variation_indices->add_range (first_var_idx, first_var_idx + num_idxes - 1);
+  }
+
+  public:
+  const void *base;
+  hb_set_t visited_paint;
+  hb_set_t *glyphs;
+  hb_set_t *layer_indices;
+  hb_set_t *palette_indices;
+  hb_set_t *variation_indices;
+  unsigned num_var_idxes;
+  unsigned nesting_level_left;
+
+  hb_colrv1_closure_context_t (const void *base_,
+                               hb_set_t *glyphs_,
+                               hb_set_t *layer_indices_,
+                               hb_set_t *palette_indices_,
+                               hb_set_t *variation_indices_,
+                               unsigned num_var_idxes_ = 1,
+                               unsigned nesting_level_left_ = HB_MAX_NESTING_LEVEL) :
+                          base (base_),
+                          glyphs (glyphs_),
+                          layer_indices (layer_indices_),
+                          palette_indices (palette_indices_),
+                          variation_indices (variation_indices_),
+                          num_var_idxes (num_var_idxes_),
+                          nesting_level_left (nesting_level_left_)
+  {}
+};
+
+struct LayerRecord
+{
+  operator hb_ot_color_layer_t () const { return {glyphId, colorIdx}; }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  public:
+  HBGlyphID16	glyphId;	/* Glyph ID of layer glyph */
+  Index		colorIdx;	/* Index value to use with a
+				 * selected color palette.
+				 * An index value of 0xFFFF
+				 * is a special case indicating
+				 * that the text foreground
+				 * color (defined by a
+				 * higher-level client) should
+				 * be used and shall not be
+				 * treated as actual index
+				 * into CPAL ColorRecord array. */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct BaseGlyphRecord
+{
+  int cmp (hb_codepoint_t g) const
+  { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  public:
+  HBGlyphID16	glyphId;	/* Glyph ID of reference glyph */
+  HBUINT16	firstLayerIdx;	/* Index (from beginning of
+				 * the Layer Records) to the
+				 * layer record. There will be
+				 * numLayers consecutive entries
+				 * for this base glyph. */
+  HBUINT16	numLayers;	/* Number of color layers
+				 * associated with this glyph */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+template <typename T>
+struct Variable
+{
+  static constexpr bool is_variable = true;
+
+  Variable<T>* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (this));
+  }
+
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  {
+    c->num_var_idxes = 0;
+    // update c->num_var_idxes during value closure
+    value.closurev1 (c);
+    c->add_var_idxes (varIdxBase, c->num_var_idxes);
+  }
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer) const
+  {
+    TRACE_SUBSET (this);
+    if (!value.subset (c, instancer, varIdxBase)) return_trace (false);
+    if (c->plan->all_axes_pinned)
+      return_trace (true);
+
+    VarIdx new_varidx;
+    new_varidx = varIdxBase;
+    if (varIdxBase != VarIdx::NO_VARIATION)
+    {
+      hb_pair_t<unsigned, int> *new_varidx_delta;
+      if (!c->plan->colrv1_variation_idx_delta_map.has (varIdxBase, &new_varidx_delta))
+        return_trace (false);
+
+      new_varidx = hb_first (*new_varidx_delta);
+    }
+
+    return_trace (c->serializer->embed (new_varidx));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && value.sanitize (c));
+  }
+
+  void paint_glyph (hb_paint_context_t *c) const
+  {
+    TRACE_PAINT (this);
+    value.paint_glyph (c, varIdxBase);
+  }
+
+  void get_color_stop (hb_paint_context_t *c,
+                       hb_color_stop_t *stop,
+		       const ItemVarStoreInstancer &instancer) const
+  {
+    value.get_color_stop (c, stop, varIdxBase, instancer);
+  }
+
+  hb_paint_extend_t get_extend () const
+  {
+    return value.get_extend ();
+  }
+
+  protected:
+  T      value;
+  public:
+  VarIdx varIdxBase;
+  public:
+  DEFINE_SIZE_MIN (VarIdx::static_size + T::min_size);
+};
+
+template <typename T>
+struct NoVariable
+{
+  static constexpr bool is_variable = false;
+
+  static constexpr uint32_t varIdxBase = VarIdx::NO_VARIATION;
+
+  NoVariable<T>* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed (this));
+  }
+
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { value.closurev1 (c); }
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer) const
+  {
+    TRACE_SUBSET (this);
+    return_trace (value.subset (c, instancer, varIdxBase));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && value.sanitize (c));
+  }
+
+  void paint_glyph (hb_paint_context_t *c) const
+  {
+    TRACE_PAINT (this);
+    value.paint_glyph (c, varIdxBase);
+  }
+
+  void get_color_stop (hb_paint_context_t *c,
+                       hb_color_stop_t *stop,
+		       const ItemVarStoreInstancer &instancer) const
+  {
+    value.get_color_stop (c, stop, VarIdx::NO_VARIATION, instancer);
+  }
+
+  hb_paint_extend_t get_extend () const
+  {
+    return value.get_extend ();
+  }
+
+  T      value;
+  public:
+  DEFINE_SIZE_MIN (T::min_size);
+};
+
+// Color structures
+
+struct ColorStop
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  {
+    c->add_palette_index (paletteIndex);
+    c->num_var_idxes = 2;
+  }
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->stopOffset.set_float (stopOffset.to_float(instancer (varIdxBase, 0)));
+      out->alpha.set_float (alpha.to_float (instancer (varIdxBase, 1)));
+    }
+
+    return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex),
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  void get_color_stop (hb_paint_context_t *c,
+                       hb_color_stop_t *out,
+		       uint32_t varIdx,
+		       const ItemVarStoreInstancer &instancer) const
+  {
+    out->offset = stopOffset.to_float(instancer (varIdx, 0));
+    out->color = c->get_color (paletteIndex,
+                               alpha.to_float (instancer (varIdx, 1)),
+                               &out->is_foreground);
+  }
+
+  F2DOT14	stopOffset;
+  HBUINT16	paletteIndex;
+  F2DOT14	alpha;
+  public:
+  DEFINE_SIZE_STATIC (2 + 2 * F2DOT14::static_size);
+};
+
+struct Extend : HBUINT8
+{
+  enum {
+    EXTEND_PAD     = 0,
+    EXTEND_REPEAT  = 1,
+    EXTEND_REFLECT = 2,
+  };
+  public:
+  DEFINE_SIZE_STATIC (1);
+};
+
+template <template<typename> class Var>
+struct ColorLine
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  {
+    for (const auto &stop : stops.iter ())
+      stop.closurev1 (c);
+  }
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    if (!c->serializer->check_assign (out->extend, extend, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
+    if (!c->serializer->check_assign (out->stops.len, stops.len, HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)) return_trace (false);
+
+    for (const auto& stop : stops.iter ())
+    {
+      if (!stop.subset (c, instancer)) return_trace (false);
+    }
+    return_trace (true);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  stops.sanitize (c));
+  }
+
+  /* get up to count stops from start */
+  unsigned int
+  get_color_stops (hb_paint_context_t *c,
+                   unsigned int start,
+		   unsigned int *count,
+		   hb_color_stop_t *color_stops,
+		   const ItemVarStoreInstancer &instancer) const
+  {
+    unsigned int len = stops.len;
+
+    if (count && color_stops)
+    {
+      unsigned int i;
+      for (i = 0; i < *count && start + i < len; i++)
+        stops[start + i].get_color_stop (c, &color_stops[i], instancer);
+      *count = i;
+    }
+
+    return len;
+  }
+
+  HB_INTERNAL static unsigned int static_get_color_stops (hb_color_line_t *color_line,
+							  void *color_line_data,
+							  unsigned int start,
+							  unsigned int *count,
+							  hb_color_stop_t *color_stops,
+							  void *user_data)
+  {
+    const ColorLine *thiz = (const ColorLine *) color_line_data;
+    hb_paint_context_t *c = (hb_paint_context_t *) user_data;
+    return thiz->get_color_stops (c, start, count, color_stops, c->instancer);
+  }
+
+  hb_paint_extend_t get_extend () const
+  {
+    return (hb_paint_extend_t) (unsigned int) extend;
+  }
+
+  HB_INTERNAL static hb_paint_extend_t static_get_extend (hb_color_line_t *color_line,
+							  void *color_line_data,
+							  void *user_data)
+  {
+    const ColorLine *thiz = (const ColorLine *) color_line_data;
+    return thiz->get_extend ();
+  }
+
+  Extend	extend;
+  Array16Of<Var<ColorStop>>	stops;
+  public:
+  DEFINE_SIZE_ARRAY_SIZED (3, stops);
+};
+
+// Composition modes
+
+// Compositing modes are taken from https://www.w3.org/TR/compositing-1/
+// NOTE: a brief audit of major implementations suggests most support most
+// or all of the specified modes.
+struct CompositeMode : HBUINT8
+{
+  enum {
+    // Porter-Duff modes
+    // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators
+    COMPOSITE_CLEAR          =  0,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_clear
+    COMPOSITE_SRC            =  1,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_src
+    COMPOSITE_DEST           =  2,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dst
+    COMPOSITE_SRC_OVER       =  3,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcover
+    COMPOSITE_DEST_OVER      =  4,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstover
+    COMPOSITE_SRC_IN         =  5,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcin
+    COMPOSITE_DEST_IN        =  6,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstin
+    COMPOSITE_SRC_OUT        =  7,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcout
+    COMPOSITE_DEST_OUT       =  8,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstout
+    COMPOSITE_SRC_ATOP       =  9,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_srcatop
+    COMPOSITE_DEST_ATOP      = 10,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_dstatop
+    COMPOSITE_XOR            = 11,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_xor
+    COMPOSITE_PLUS           = 12,  // https://www.w3.org/TR/compositing-1/#porterduffcompositingoperators_plus
+
+    // Blend modes
+    // https://www.w3.org/TR/compositing-1/#blending
+    COMPOSITE_SCREEN         = 13,  // https://www.w3.org/TR/compositing-1/#blendingscreen
+    COMPOSITE_OVERLAY        = 14,  // https://www.w3.org/TR/compositing-1/#blendingoverlay
+    COMPOSITE_DARKEN         = 15,  // https://www.w3.org/TR/compositing-1/#blendingdarken
+    COMPOSITE_LIGHTEN        = 16,  // https://www.w3.org/TR/compositing-1/#blendinglighten
+    COMPOSITE_COLOR_DODGE    = 17,  // https://www.w3.org/TR/compositing-1/#blendingcolordodge
+    COMPOSITE_COLOR_BURN     = 18,  // https://www.w3.org/TR/compositing-1/#blendingcolorburn
+    COMPOSITE_HARD_LIGHT     = 19,  // https://www.w3.org/TR/compositing-1/#blendinghardlight
+    COMPOSITE_SOFT_LIGHT     = 20,  // https://www.w3.org/TR/compositing-1/#blendingsoftlight
+    COMPOSITE_DIFFERENCE     = 21,  // https://www.w3.org/TR/compositing-1/#blendingdifference
+    COMPOSITE_EXCLUSION      = 22,  // https://www.w3.org/TR/compositing-1/#blendingexclusion
+    COMPOSITE_MULTIPLY       = 23,  // https://www.w3.org/TR/compositing-1/#blendingmultiply
+
+    // Modes that, uniquely, do not operate on components
+    // https://www.w3.org/TR/compositing-1/#blendingnonseparable
+    COMPOSITE_HSL_HUE        = 24,  // https://www.w3.org/TR/compositing-1/#blendinghue
+    COMPOSITE_HSL_SATURATION = 25,  // https://www.w3.org/TR/compositing-1/#blendingsaturation
+    COMPOSITE_HSL_COLOR      = 26,  // https://www.w3.org/TR/compositing-1/#blendingcolor
+    COMPOSITE_HSL_LUMINOSITY = 27,  // https://www.w3.org/TR/compositing-1/#blendingluminosity
+  };
+  public:
+  DEFINE_SIZE_STATIC (1);
+};
+
+struct Affine2x3
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { c->num_var_idxes = 6; }
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->xx.set_float (xx.to_float(instancer (varIdxBase, 0)));
+      out->yx.set_float (yx.to_float(instancer (varIdxBase, 1)));
+      out->xy.set_float (xy.to_float(instancer (varIdxBase, 2)));
+      out->yy.set_float (yy.to_float(instancer (varIdxBase, 3)));
+      out->dx.set_float (dx.to_float(instancer (varIdxBase, 4)));
+      out->dy.set_float (dy.to_float(instancer (varIdxBase, 5)));
+    }
+    return_trace (true);
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    c->funcs->push_transform (c->data,
+			      xx.to_float (c->instancer (varIdxBase, 0)),
+			      yx.to_float (c->instancer (varIdxBase, 1)),
+                              xy.to_float (c->instancer (varIdxBase, 2)),
+			      yy.to_float (c->instancer (varIdxBase, 3)),
+                              dx.to_float (c->instancer (varIdxBase, 4)),
+			      dy.to_float (c->instancer (varIdxBase, 5)));
+  }
+
+  F16DOT16 xx;
+  F16DOT16 yx;
+  F16DOT16 xy;
+  F16DOT16 yy;
+  F16DOT16 dx;
+  F16DOT16 dy;
+  public:
+  DEFINE_SIZE_STATIC (6 * F16DOT16::static_size);
+};
+
+struct PaintColrLayers
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer HB_UNUSED) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (c->serializer->check_assign (out->firstLayerIndex, c->plan->colrv1_layers.get (firstLayerIndex),
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+
+    return_trace (true);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  inline void paint_glyph (hb_paint_context_t *c) const;
+
+  HBUINT8	format; /* format = 1 */
+  HBUINT8	numLayers;
+  HBUINT32	firstLayerIndex;  /* index into COLRv1::layerList */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct PaintSolid
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  {
+    c->add_palette_index (paletteIndex);
+    c->num_var_idxes = 1;
+  }
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+      out->alpha.set_float (alpha.to_float (instancer (varIdxBase, 0)));
+
+    if (format == 3 && c->plan->all_axes_pinned)
+        out->format = 2;
+
+    return_trace (c->serializer->check_assign (out->paletteIndex, c->plan->colr_palettes.get (paletteIndex),
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    hb_bool_t is_foreground;
+    hb_color_t color;
+
+    color = c->get_color (paletteIndex,
+                          alpha.to_float (c->instancer (varIdxBase, 0)),
+                          &is_foreground);
+    c->funcs->color (c->data, is_foreground, color);
+  }
+
+  HBUINT8	format; /* format = 2(noVar) or 3(Var)*/
+  HBUINT16	paletteIndex;
+  F2DOT14	alpha;
+  public:
+  DEFINE_SIZE_STATIC (3 + F2DOT14::static_size);
+};
+
+template <template<typename> class Var>
+struct PaintLinearGradient
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  {
+    (this+colorLine).closurev1 (c);
+    c->num_var_idxes = 6;
+  }
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->x0 = x0 + (int) roundf (instancer (varIdxBase, 0));
+      out->y0 = y0 + (int) roundf (instancer (varIdxBase, 1));
+      out->x1 = x1 + (int) roundf (instancer (varIdxBase, 2));
+      out->y1 = y1 + (int) roundf (instancer (varIdxBase, 3));
+      out->x2 = x2 + (int) roundf (instancer (varIdxBase, 4));
+      out->y2 = y2 + (int) roundf (instancer (varIdxBase, 5));
+    }
+
+    if (format == 5 && c->plan->all_axes_pinned)
+        out->format = 4;
+
+    return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    hb_color_line_t cl = {
+      (void *) &(this+colorLine),
+      (this+colorLine).static_get_color_stops, c,
+      (this+colorLine).static_get_extend, nullptr
+    };
+
+    c->funcs->linear_gradient (c->data, &cl,
+			       x0 + c->instancer (varIdxBase, 0),
+			       y0 + c->instancer (varIdxBase, 1),
+			       x1 + c->instancer (varIdxBase, 2),
+			       y1 + c->instancer (varIdxBase, 3),
+			       x2 + c->instancer (varIdxBase, 4),
+			       y2 + c->instancer (varIdxBase, 5));
+  }
+
+  HBUINT8			format; /* format = 4(noVar) or 5 (Var) */
+  Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintLinearGradient
+                                            * table) to ColorLine subtable. */
+  FWORD			x0;
+  FWORD			y0;
+  FWORD			x1;
+  FWORD			y1;
+  FWORD			x2;
+  FWORD			y2;
+  public:
+  DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size);
+};
+
+template <template<typename> class Var>
+struct PaintRadialGradient
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  {
+    (this+colorLine).closurev1 (c);
+    c->num_var_idxes = 6;
+  }
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->x0 = x0 + (int) roundf (instancer (varIdxBase, 0));
+      out->y0 = y0 + (int) roundf (instancer (varIdxBase, 1));
+      out->radius0 = radius0 + (unsigned) roundf (instancer (varIdxBase, 2));
+      out->x1 = x1 + (int) roundf (instancer (varIdxBase, 3));
+      out->y1 = y1 + (int) roundf (instancer (varIdxBase, 4));
+      out->radius1 = radius1 + (unsigned) roundf (instancer (varIdxBase, 5));
+    }
+
+    if (format == 7 && c->plan->all_axes_pinned)
+        out->format = 6;
+
+    return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    hb_color_line_t cl = {
+      (void *) &(this+colorLine),
+      (this+colorLine).static_get_color_stops, c,
+      (this+colorLine).static_get_extend, nullptr
+    };
+
+    c->funcs->radial_gradient (c->data, &cl,
+			       x0 + c->instancer (varIdxBase, 0),
+			       y0 + c->instancer (varIdxBase, 1),
+			       radius0 + c->instancer (varIdxBase, 2),
+			       x1 + c->instancer (varIdxBase, 3),
+			       y1 + c->instancer (varIdxBase, 4),
+			       radius1 + c->instancer (varIdxBase, 5));
+  }
+
+  HBUINT8			format; /* format = 6(noVar) or 7 (Var) */
+  Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintRadialGradient
+                                            * table) to ColorLine subtable. */
+  FWORD			x0;
+  FWORD			y0;
+  UFWORD		radius0;
+  FWORD			x1;
+  FWORD			y1;
+  UFWORD		radius1;
+  public:
+  DEFINE_SIZE_STATIC (4 + 6 * FWORD::static_size);
+};
+
+template <template<typename> class Var>
+struct PaintSweepGradient
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  {
+    (this+colorLine).closurev1 (c);
+    c->num_var_idxes = 4;
+  }
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 0));
+      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 1));
+      out->startAngle.set_float (startAngle.to_float (instancer (varIdxBase, 2)));
+      out->endAngle.set_float (endAngle.to_float (instancer (varIdxBase, 3)));
+    }
+
+    if (format == 9 && c->plan->all_axes_pinned)
+        out->format = 8;
+
+    return_trace (out->colorLine.serialize_subset (c, colorLine, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && colorLine.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    hb_color_line_t cl = {
+      (void *) &(this+colorLine),
+      (this+colorLine).static_get_color_stops, c,
+      (this+colorLine).static_get_extend, nullptr
+    };
+
+    c->funcs->sweep_gradient (c->data, &cl,
+			      centerX + c->instancer (varIdxBase, 0),
+			      centerY + c->instancer (varIdxBase, 1),
+                              (startAngle.to_float (c->instancer (varIdxBase, 2)) + 1) * HB_PI,
+                              (endAngle.to_float   (c->instancer (varIdxBase, 3)) + 1) * HB_PI);
+  }
+
+  HBUINT8			format; /* format = 8(noVar) or 9 (Var) */
+  Offset24To<ColorLine<Var>>	colorLine; /* Offset (from beginning of PaintSweepGradient
+                                            * table) to ColorLine subtable. */
+  FWORD			centerX;
+  FWORD			centerY;
+  F2DOT14		startAngle;
+  F2DOT14		endAngle;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size + 2 * F2DOT14::static_size);
+};
+
+// Paint a non-COLR glyph, filled as indicated by paint.
+struct PaintGlyph
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (! c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid),
+                                       HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return_trace (false);
+
+    return_trace (out->paint.serialize_subset (c, paint, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && paint.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c) const
+  {
+    TRACE_PAINT (this);
+    c->funcs->push_inverse_root_transform (c->data, c->font);
+    c->funcs->push_clip_glyph (c->data, gid, c->font);
+    c->funcs->push_root_transform (c->data, c->font);
+    c->recurse (this+paint);
+    c->funcs->pop_transform (c->data);
+    c->funcs->pop_clip (c->data);
+    c->funcs->pop_transform (c->data);
+  }
+
+  HBUINT8		format; /* format = 10 */
+  Offset24To<Paint>	paint;  /* Offset (from beginning of PaintGlyph table) to Paint subtable. */
+  HBUINT16		gid;
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct PaintColrGlyph
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer HB_UNUSED) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (c->serializer->check_assign (out->gid, c->plan->glyph_map->get (gid),
+                                               HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  inline void paint_glyph (hb_paint_context_t *c) const;
+
+  HBUINT8	format; /* format = 11 */
+  HBUINT16	gid;
+  public:
+  DEFINE_SIZE_STATIC (3);
+};
+
+template <template<typename> class Var>
+struct PaintTransform
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    if (!out->transform.serialize_subset (c, transform, this, instancer)) return_trace (false);
+    if (format == 13 && c->plan->all_axes_pinned)
+      out->format = 12;
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  src.sanitize (c, this) &&
+                  transform.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c) const
+  {
+    TRACE_PAINT (this);
+    (this+transform).paint_glyph (c);
+    c->recurse (this+src);
+    c->funcs->pop_transform (c->data);
+  }
+
+  HBUINT8			format; /* format = 12(noVar) or 13 (Var) */
+  Offset24To<Paint>		src; /* Offset (from beginning of PaintTransform table) to Paint subtable. */
+  Offset24To<Var<Affine2x3>>	transform;
+  public:
+  DEFINE_SIZE_STATIC (7);
+};
+
+struct PaintTranslate
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->dx = dx + (int) roundf (instancer (varIdxBase, 0));
+      out->dy = dy + (int) roundf (instancer (varIdxBase, 1));
+    }
+
+    if (format == 15 && c->plan->all_axes_pinned)
+        out->format = 14;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    float ddx = dx + c->instancer (varIdxBase, 0);
+    float ddy = dy + c->instancer (varIdxBase, 1);
+
+    bool p1 = c->funcs->push_translate (c->data, ddx, ddy);
+    c->recurse (this+src);
+    if (p1) c->funcs->pop_transform (c->data);
+  }
+
+  HBUINT8		format; /* format = 14(noVar) or 15 (Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintTranslate table) to Paint subtable. */
+  FWORD		dx;
+  FWORD		dy;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * FWORD::static_size);
+};
+
+struct PaintScale
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
+      out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
+    }
+
+    if (format == 17 && c->plan->all_axes_pinned)
+        out->format = 16;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
+    float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
+
+    bool p1 = c->funcs->push_scale (c->data, sx, sy);
+    c->recurse (this+src);
+    if (p1) c->funcs->pop_transform (c->data);
+  }
+
+  HBUINT8		format; /* format = 16 (noVar) or 17(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScale table) to Paint subtable. */
+  F2DOT14		scaleX;
+  F2DOT14		scaleY;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size);
+};
+
+struct PaintScaleAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->scaleX.set_float (scaleX.to_float (instancer (varIdxBase, 0)));
+      out->scaleY.set_float (scaleY.to_float (instancer (varIdxBase, 1)));
+      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
+      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
+    }
+
+    if (format == 19 && c->plan->all_axes_pinned)
+        out->format = 18;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    float sx = scaleX.to_float (c->instancer (varIdxBase, 0));
+    float sy = scaleY.to_float (c->instancer (varIdxBase, 1));
+    float tCenterX = centerX + c->instancer (varIdxBase, 2);
+    float tCenterY = centerY + c->instancer (varIdxBase, 3);
+
+    bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
+    bool p2 = c->funcs->push_scale (c->data, sx, sy);
+    bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
+    c->recurse (this+src);
+    if (p3) c->funcs->pop_transform (c->data);
+    if (p2) c->funcs->pop_transform (c->data);
+    if (p1) c->funcs->pop_transform (c->data);
+  }
+
+  HBUINT8		format; /* format = 18 (noVar) or 19(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleAroundCenter table) to Paint subtable. */
+  F2DOT14	scaleX;
+  F2DOT14	scaleY;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
+struct PaintScaleUniform
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+      out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
+
+    if (format == 21 && c->plan->all_axes_pinned)
+        out->format = 20;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    float s = scale.to_float (c->instancer (varIdxBase, 0));
+
+    bool p1 = c->funcs->push_scale (c->data, s, s);
+    c->recurse (this+src);
+    if (p1) c->funcs->pop_transform (c->data);
+  }
+
+  HBUINT8		format; /* format = 20 (noVar) or 21(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleUniform table) to Paint subtable. */
+  F2DOT14		scale;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size);
+};
+
+struct PaintScaleUniformAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->scale.set_float (scale.to_float (instancer (varIdxBase, 0)));
+      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
+      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
+    }
+
+    if (format == 23 && c->plan->all_axes_pinned)
+        out->format = 22;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    float s = scale.to_float (c->instancer (varIdxBase, 0));
+    float tCenterX = centerX + c->instancer (varIdxBase, 1);
+    float tCenterY = centerY + c->instancer (varIdxBase, 2);
+
+    bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
+    bool p2 = c->funcs->push_scale (c->data, s, s);
+    bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
+    c->recurse (this+src);
+    if (p3) c->funcs->pop_transform (c->data);
+    if (p2) c->funcs->pop_transform (c->data);
+    if (p1) c->funcs->pop_transform (c->data);
+  }
+
+  HBUINT8		format; /* format = 22 (noVar) or 23(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintScaleUniformAroundCenter table) to Paint subtable. */
+  F2DOT14	scale;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
+struct PaintRotate
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+      out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
+
+    if (format == 25 && c->plan->all_axes_pinned)
+      out->format = 24;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    float a = angle.to_float (c->instancer (varIdxBase, 0));
+
+    bool p1 = c->funcs->push_rotate (c->data, a);
+    c->recurse (this+src);
+    if (p1) c->funcs->pop_transform (c->data);
+  }
+
+  HBUINT8		format; /* format = 24 (noVar) or 25(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintRotate table) to Paint subtable. */
+  F2DOT14		angle;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size);
+};
+
+struct PaintRotateAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->angle.set_float (angle.to_float (instancer (varIdxBase, 0)));
+      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 1));
+      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 2));
+    }
+
+    if (format ==27 && c->plan->all_axes_pinned)
+        out->format = 26;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    float a = angle.to_float (c->instancer (varIdxBase, 0));
+    float tCenterX = centerX + c->instancer (varIdxBase, 1);
+    float tCenterY = centerY + c->instancer (varIdxBase, 2);
+
+    bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
+    bool p2 = c->funcs->push_rotate (c->data, a);
+    bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
+    c->recurse (this+src);
+    if (p3) c->funcs->pop_transform (c->data);
+    if (p2) c->funcs->pop_transform (c->data);
+    if (p1) c->funcs->pop_transform (c->data);
+  }
+
+  HBUINT8		format; /* format = 26 (noVar) or 27(Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintRotateAroundCenter table) to Paint subtable. */
+  F2DOT14	angle;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
+struct PaintSkew
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
+      out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
+    }
+
+    if (format == 29 && c->plan->all_axes_pinned)
+        out->format = 28;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
+    float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
+
+    bool p1 = c->funcs->push_skew (c->data, sx, sy);
+    c->recurse (this+src);
+    if (p1) c->funcs->pop_transform (c->data);
+  }
+
+  HBUINT8		format; /* format = 28(noVar) or 29 (Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintSkew table) to Paint subtable. */
+  F2DOT14		xSkewAngle;
+  F2DOT14		ySkewAngle;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size);
+};
+
+struct PaintSkewAroundCenter
+{
+  HB_INTERNAL void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->xSkewAngle.set_float (xSkewAngle.to_float (instancer (varIdxBase, 0)));
+      out->ySkewAngle.set_float (ySkewAngle.to_float (instancer (varIdxBase, 1)));
+      out->centerX = centerX + (int) roundf (instancer (varIdxBase, 2));
+      out->centerY = centerY + (int) roundf (instancer (varIdxBase, 3));
+    }
+
+    if (format == 31 && c->plan->all_axes_pinned)
+        out->format = 30;
+
+    return_trace (out->src.serialize_subset (c, src, this, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && src.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c, uint32_t varIdxBase) const
+  {
+    TRACE_PAINT (this);
+    float sx = xSkewAngle.to_float(c->instancer (varIdxBase, 0));
+    float sy = ySkewAngle.to_float(c->instancer (varIdxBase, 1));
+    float tCenterX = centerX + c->instancer (varIdxBase, 2);
+    float tCenterY = centerY + c->instancer (varIdxBase, 3);
+
+    bool p1 = c->funcs->push_translate (c->data, +tCenterX, +tCenterY);
+    bool p2 = c->funcs->push_skew (c->data, sx, sy);
+    bool p3 = c->funcs->push_translate (c->data, -tCenterX, -tCenterY);
+    c->recurse (this+src);
+    if (p3) c->funcs->pop_transform (c->data);
+    if (p2) c->funcs->pop_transform (c->data);
+    if (p1) c->funcs->pop_transform (c->data);
+  }
+
+  HBUINT8		format; /* format = 30(noVar) or 31 (Var) */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintSkewAroundCenter table) to Paint subtable. */
+  F2DOT14	xSkewAngle;
+  F2DOT14	ySkewAngle;
+  FWORD		centerX;
+  FWORD		centerY;
+  public:
+  DEFINE_SIZE_STATIC (4 + 2 * F2DOT14::static_size + 2 * FWORD::static_size);
+};
+
+struct PaintComposite
+{
+  void closurev1 (hb_colrv1_closure_context_t* c) const;
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    bool ret = false;
+    ret |= out->src.serialize_subset (c, src, this, instancer);
+    ret |= out->backdrop.serialize_subset (c, backdrop, this, instancer);
+    return_trace (ret);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  c->check_ops (this->min_size) && // PainComposite can get exponential
+                  src.sanitize (c, this) &&
+                  backdrop.sanitize (c, this));
+  }
+
+  void paint_glyph (hb_paint_context_t *c) const
+  {
+    TRACE_PAINT (this);
+    c->recurse (this+backdrop);
+    c->funcs->push_group (c->data);
+    c->recurse (this+src);
+    c->funcs->pop_group (c->data, (hb_paint_composite_mode_t) (int) mode);
+  }
+
+  HBUINT8		format; /* format = 32 */
+  Offset24To<Paint>	src; /* Offset (from beginning of PaintComposite table) to source Paint subtable. */
+  CompositeMode		mode;   /* If mode is unrecognized use COMPOSITE_CLEAR */
+  Offset24To<Paint>	backdrop; /* Offset (from beginning of PaintComposite table) to backdrop Paint subtable. */
+  public:
+  DEFINE_SIZE_STATIC (8);
+};
+
+struct ClipBoxData
+{
+  int xMin, yMin, xMax, yMax;
+};
+
+struct ClipBoxFormat1
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  void get_clip_box (ClipBoxData &clip_box, const ItemVarStoreInstancer &instancer HB_UNUSED) const
+  {
+    clip_box.xMin = xMin;
+    clip_box.yMin = yMin;
+    clip_box.xMax = xMax;
+    clip_box.yMax = yMax;
+  }
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer,
+               uint32_t varIdxBase) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    if (instancer && !c->plan->pinned_at_default && varIdxBase != VarIdx::NO_VARIATION)
+    {
+      out->xMin = xMin + (int) roundf (instancer (varIdxBase, 0));
+      out->yMin = yMin + (int) roundf (instancer (varIdxBase, 1));
+      out->xMax = xMax + (int) roundf (instancer (varIdxBase, 2));
+      out->yMax = yMax + (int) roundf (instancer (varIdxBase, 3));
+    }
+
+    if (format == 2 && c->plan->all_axes_pinned)
+        out->format = 1;
+
+    return_trace (true);
+  }
+
+  public:
+  HBUINT8	format; /* format = 1(noVar) or 2(Var)*/
+  FWORD		xMin;
+  FWORD		yMin;
+  FWORD		xMax;
+  FWORD		yMax;
+  public:
+  DEFINE_SIZE_STATIC (1 + 4 * FWORD::static_size);
+};
+
+struct ClipBoxFormat2 : Variable<ClipBoxFormat1>
+{
+  void get_clip_box (ClipBoxData &clip_box, const ItemVarStoreInstancer &instancer) const
+  {
+    value.get_clip_box(clip_box, instancer);
+    if (instancer)
+    {
+      clip_box.xMin += roundf (instancer (varIdxBase, 0));
+      clip_box.yMin += roundf (instancer (varIdxBase, 1));
+      clip_box.xMax += roundf (instancer (varIdxBase, 2));
+      clip_box.yMax += roundf (instancer (varIdxBase, 3));
+    }
+  }
+
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  { c->variation_indices->add_range (varIdxBase, varIdxBase + 3); }
+};
+
+struct ClipBox
+{
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer) const
+  {
+    TRACE_SUBSET (this);
+    switch (u.format) {
+    case 1: return_trace (u.format1.subset (c, instancer, VarIdx::NO_VARIATION));
+    case 2: return_trace (u.format2.subset (c, instancer));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  void closurev1 (hb_colrv1_closure_context_t* c) const
+  {
+    switch (u.format) {
+    case 2: u.format2.closurev1 (c);
+    default:return;
+    }
+  }
+
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
+    TRACE_DISPATCH (this, u.format);
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  bool get_extents (hb_glyph_extents_t *extents,
+                    const ItemVarStoreInstancer &instancer) const
+  {
+    ClipBoxData clip_box;
+    switch (u.format) {
+    case 1:
+      u.format1.get_clip_box (clip_box, instancer);
+      break;
+    case 2:
+      u.format2.get_clip_box (clip_box, instancer);
+      break;
+    default:
+      return false;
+    }
+
+    extents->x_bearing = clip_box.xMin;
+    extents->y_bearing = clip_box.yMax;
+    extents->width = clip_box.xMax - clip_box.xMin;
+    extents->height = clip_box.yMin - clip_box.yMax;
+    return true;
+  }
+
+  protected:
+  union {
+  HBUINT8		format;         /* Format identifier */
+  ClipBoxFormat1	format1;
+  ClipBoxFormat2	format2;
+  } u;
+};
+
+struct ClipRecord
+{
+  int cmp (hb_codepoint_t g) const
+  { return g < startGlyphID ? -1 : g <= endGlyphID ? 0 : +1; }
+
+  void closurev1 (hb_colrv1_closure_context_t* c, const void *base) const
+  {
+    if (!c->glyphs->intersects (startGlyphID, endGlyphID)) return;
+    (base+clipBox).closurev1 (c);
+  }
+
+  bool subset (hb_subset_context_t *c,
+               const void *base,
+               const ItemVarStoreInstancer &instancer) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (*this);
+    if (unlikely (!out)) return_trace (false);
+
+    return_trace (out->clipBox.serialize_subset (c, clipBox, base, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && clipBox.sanitize (c, base));
+  }
+
+  bool get_extents (hb_glyph_extents_t *extents,
+		    const void *base,
+		    const ItemVarStoreInstancer &instancer) const
+  {
+    return (base+clipBox).get_extents (extents, instancer);
+  }
+
+  public:
+  HBUINT16		startGlyphID;  // first gid clip applies to
+  HBUINT16		endGlyphID;    // last gid clip applies to, inclusive
+  Offset24To<ClipBox>	clipBox;   // Box or VarBox
+  public:
+  DEFINE_SIZE_STATIC (7);
+};
+DECLARE_NULL_NAMESPACE_BYTES (OT, ClipRecord);
+
+struct ClipList
+{
+  unsigned serialize_clip_records (hb_subset_context_t *c,
+                                   const ItemVarStoreInstancer &instancer,
+                                   const hb_set_t& gids,
+                                   const hb_map_t& gid_offset_map) const
+  {
+    TRACE_SERIALIZE (this);
+    if (gids.is_empty () ||
+        gid_offset_map.get_population () != gids.get_population ())
+      return_trace (0);
+
+    unsigned count  = 0;
+
+    hb_codepoint_t start_gid= gids.get_min ();
+    hb_codepoint_t prev_gid = start_gid;
+
+    unsigned offset = gid_offset_map.get (start_gid);
+    unsigned prev_offset = offset;
+    for (const hb_codepoint_t _ : gids.iter ())
+    {
+      if (_ == start_gid) continue;
+
+      offset = gid_offset_map.get (_);
+      if (_ == prev_gid + 1 &&  offset == prev_offset)
+      {
+        prev_gid = _;
+        continue;
+      }
+
+      ClipRecord record;
+      record.startGlyphID = start_gid;
+      record.endGlyphID = prev_gid;
+      record.clipBox = prev_offset;
+
+      if (!record.subset (c, this, instancer)) return_trace (0);
+      count++;
+
+      start_gid = _;
+      prev_gid = _;
+      prev_offset = offset;
+    }
+
+    //last one
+    {
+      ClipRecord record;
+      record.startGlyphID = start_gid;
+      record.endGlyphID = prev_gid;
+      record.clipBox = prev_offset;
+      if (!record.subset (c, this, instancer)) return_trace (0);
+      count++;
+    }
+    return_trace (count);
+  }
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    if (!c->serializer->check_assign (out->format, format, HB_SERIALIZE_ERROR_INT_OVERFLOW)) return_trace (false);
+
+    const hb_set_t& glyphset = c->plan->_glyphset_colred;
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    hb_map_t new_gid_offset_map;
+    hb_set_t new_gids;
+    for (const ClipRecord& record : clips.iter ())
+    {
+      unsigned start_gid = record.startGlyphID;
+      unsigned end_gid = record.endGlyphID;
+      for (unsigned gid = start_gid; gid <= end_gid; gid++)
+      {
+        if (!glyphset.has (gid) || !glyph_map.has (gid)) continue;
+        unsigned new_gid = glyph_map.get (gid);
+        new_gid_offset_map.set (new_gid, record.clipBox);
+        new_gids.add (new_gid);
+      }
+    }
+
+    unsigned count = serialize_clip_records (c, instancer, new_gids, new_gid_offset_map);
+    if (!count) return_trace (false);
+    return_trace (c->serializer->check_assign (out->clips.len, count, HB_SERIALIZE_ERROR_INT_OVERFLOW));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    // TODO Make a formatted struct!
+    return_trace (c->check_struct (this) && clips.sanitize (c, this));
+  }
+
+  bool
+  get_extents (hb_codepoint_t gid,
+	       hb_glyph_extents_t *extents,
+	       const ItemVarStoreInstancer &instancer) const
+  {
+    auto *rec = clips.as_array ().bsearch (gid);
+    if (rec)
+    {
+      rec->get_extents (extents, this, instancer);
+      return true;
+    }
+    return false;
+  }
+
+  HBUINT8			format;  // Set to 1.
+  SortedArray32Of<ClipRecord>	clips;  // Clip records, sorted by startGlyphID
+  public:
+  DEFINE_SIZE_ARRAY_SIZED (5, clips);
+};
+
+struct Paint
+{
+
+  template <typename ...Ts>
+  bool sanitize (hb_sanitize_context_t *c, Ts&&... ds) const
+  {
+    TRACE_SANITIZE (this);
+
+    if (unlikely (!c->check_start_recursion (HB_MAX_NESTING_LEVEL)))
+      return_trace (c->no_dispatch_return_value ());
+
+    return_trace (c->end_recursion (this->dispatch (c, std::forward<Ts> (ds)...)));
+  }
+
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
+    TRACE_DISPATCH (this, u.format);
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.paintformat1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.paintformat2, std::forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.paintformat3, std::forward<Ts> (ds)...));
+    case 4: return_trace (c->dispatch (u.paintformat4, std::forward<Ts> (ds)...));
+    case 5: return_trace (c->dispatch (u.paintformat5, std::forward<Ts> (ds)...));
+    case 6: return_trace (c->dispatch (u.paintformat6, std::forward<Ts> (ds)...));
+    case 7: return_trace (c->dispatch (u.paintformat7, std::forward<Ts> (ds)...));
+    case 8: return_trace (c->dispatch (u.paintformat8, std::forward<Ts> (ds)...));
+    case 9: return_trace (c->dispatch (u.paintformat9, std::forward<Ts> (ds)...));
+    case 10: return_trace (c->dispatch (u.paintformat10, std::forward<Ts> (ds)...));
+    case 11: return_trace (c->dispatch (u.paintformat11, std::forward<Ts> (ds)...));
+    case 12: return_trace (c->dispatch (u.paintformat12, std::forward<Ts> (ds)...));
+    case 13: return_trace (c->dispatch (u.paintformat13, std::forward<Ts> (ds)...));
+    case 14: return_trace (c->dispatch (u.paintformat14, std::forward<Ts> (ds)...));
+    case 15: return_trace (c->dispatch (u.paintformat15, std::forward<Ts> (ds)...));
+    case 16: return_trace (c->dispatch (u.paintformat16, std::forward<Ts> (ds)...));
+    case 17: return_trace (c->dispatch (u.paintformat17, std::forward<Ts> (ds)...));
+    case 18: return_trace (c->dispatch (u.paintformat18, std::forward<Ts> (ds)...));
+    case 19: return_trace (c->dispatch (u.paintformat19, std::forward<Ts> (ds)...));
+    case 20: return_trace (c->dispatch (u.paintformat20, std::forward<Ts> (ds)...));
+    case 21: return_trace (c->dispatch (u.paintformat21, std::forward<Ts> (ds)...));
+    case 22: return_trace (c->dispatch (u.paintformat22, std::forward<Ts> (ds)...));
+    case 23: return_trace (c->dispatch (u.paintformat23, std::forward<Ts> (ds)...));
+    case 24: return_trace (c->dispatch (u.paintformat24, std::forward<Ts> (ds)...));
+    case 25: return_trace (c->dispatch (u.paintformat25, std::forward<Ts> (ds)...));
+    case 26: return_trace (c->dispatch (u.paintformat26, std::forward<Ts> (ds)...));
+    case 27: return_trace (c->dispatch (u.paintformat27, std::forward<Ts> (ds)...));
+    case 28: return_trace (c->dispatch (u.paintformat28, std::forward<Ts> (ds)...));
+    case 29: return_trace (c->dispatch (u.paintformat29, std::forward<Ts> (ds)...));
+    case 30: return_trace (c->dispatch (u.paintformat30, std::forward<Ts> (ds)...));
+    case 31: return_trace (c->dispatch (u.paintformat31, std::forward<Ts> (ds)...));
+    case 32: return_trace (c->dispatch (u.paintformat32, std::forward<Ts> (ds)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  protected:
+  union {
+  HBUINT8					format;
+  PaintColrLayers				paintformat1;
+  NoVariable<PaintSolid>			paintformat2;
+  Variable<PaintSolid>				paintformat3;
+  NoVariable<PaintLinearGradient<NoVariable>>	paintformat4;
+  Variable<PaintLinearGradient<Variable>>	paintformat5;
+  NoVariable<PaintRadialGradient<NoVariable>>	paintformat6;
+  Variable<PaintRadialGradient<Variable>>	paintformat7;
+  NoVariable<PaintSweepGradient<NoVariable>>	paintformat8;
+  Variable<PaintSweepGradient<Variable>>	paintformat9;
+  PaintGlyph					paintformat10;
+  PaintColrGlyph				paintformat11;
+  PaintTransform<NoVariable>			paintformat12;
+  PaintTransform<Variable>			paintformat13;
+  NoVariable<PaintTranslate>			paintformat14;
+  Variable<PaintTranslate>			paintformat15;
+  NoVariable<PaintScale>			paintformat16;
+  Variable<PaintScale>				paintformat17;
+  NoVariable<PaintScaleAroundCenter>		paintformat18;
+  Variable<PaintScaleAroundCenter>		paintformat19;
+  NoVariable<PaintScaleUniform>			paintformat20;
+  Variable<PaintScaleUniform>			paintformat21;
+  NoVariable<PaintScaleUniformAroundCenter>	paintformat22;
+  Variable<PaintScaleUniformAroundCenter>	paintformat23;
+  NoVariable<PaintRotate>			paintformat24;
+  Variable<PaintRotate>				paintformat25;
+  NoVariable<PaintRotateAroundCenter>		paintformat26;
+  Variable<PaintRotateAroundCenter>		paintformat27;
+  NoVariable<PaintSkew>				paintformat28;
+  Variable<PaintSkew>				paintformat29;
+  NoVariable<PaintSkewAroundCenter>		paintformat30;
+  Variable<PaintSkewAroundCenter>		paintformat31;
+  PaintComposite				paintformat32;
+  } u;
+  public:
+  DEFINE_SIZE_MIN (2);
+};
+
+struct BaseGlyphPaintRecord
+{
+  int cmp (hb_codepoint_t g) const
+  { return g < glyphId ? -1 : g > glyphId ? 1 : 0; }
+
+  bool serialize (hb_serialize_context_t *s, const hb_map_t* glyph_map,
+                  const void* src_base, hb_subset_context_t *c,
+                  const ItemVarStoreInstancer &instancer) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = s->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    if (!s->check_assign (out->glyphId, glyph_map->get (glyphId),
+                          HB_SERIALIZE_ERROR_INT_OVERFLOW))
+      return_trace (false);
+
+    return_trace (out->paint.serialize_subset (c, paint, src_base, instancer));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) && paint.sanitize (c, base)));
+  }
+
+  public:
+  HBGlyphID16		glyphId;    /* Glyph ID of reference glyph */
+  Offset32To<Paint>	paint;      /* Offset (from beginning of BaseGlyphPaintRecord array) to Paint,
+                                     * Typically PaintColrLayers */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct BaseGlyphList : SortedArray32Of<BaseGlyphPaintRecord>
+{
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
+    const hb_set_t* glyphset = &c->plan->_glyphset_colred;
+
+    for (const auto& _ : as_array ())
+    {
+      unsigned gid = _.glyphId;
+      if (!glyphset->has (gid)) continue;
+
+      if (_.serialize (c->serializer, c->plan->glyph_map, this, c, instancer)) out->len++;
+      else return_trace (false);
+    }
+
+    return_trace (out->len != 0);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (SortedArray32Of<BaseGlyphPaintRecord>::sanitize (c, this));
+  }
+};
+
+struct LayerList : Array32OfOffset32To<Paint>
+{
+  const Paint& get_paint (unsigned i) const
+  { return this+(*this)[i]; }
+
+  bool subset (hb_subset_context_t *c,
+               const ItemVarStoreInstancer &instancer) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
+
+    bool ret = false;
+    for (const auto& _ : + hb_enumerate (*this)
+                         | hb_filter (c->plan->colrv1_layers, hb_first))
+
+    {
+      auto *o = out->serialize_append (c->serializer);
+      if (unlikely (!o)) return_trace (false);
+      ret |= o->serialize_subset (c, _.second, this, instancer);
+    }
+    return_trace (ret);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (Array32OfOffset32To<Paint>::sanitize (c, this));
+  }
+};
+
+struct delta_set_index_map_subset_plan_t
+{
+  unsigned get_inner_bit_count () const { return inner_bit_count; }
+  unsigned get_width ()           const { return ((outer_bit_count + inner_bit_count + 7) / 8); }
+  hb_array_t<const uint32_t> get_output_map () const { return output_map.as_array (); }
+
+  delta_set_index_map_subset_plan_t (const hb_map_t &new_deltaset_idx_varidx_map)
+  {
+    map_count = 0;
+    outer_bit_count = 0;
+    inner_bit_count = 1;
+    output_map.init ();
+
+    /* search backwards */
+    unsigned count = new_deltaset_idx_varidx_map.get_population ();
+    if (!count) return;
+
+    unsigned last_idx = (unsigned)-1;
+    unsigned last_varidx = (unsigned)-1;
+
+    for (unsigned i = count; i; i--)
+    {
+      unsigned delta_set_idx = i - 1;
+      unsigned var_idx = new_deltaset_idx_varidx_map.get (delta_set_idx);
+      if (i == count)
+      {
+        last_idx = delta_set_idx;
+        last_varidx = var_idx;
+        continue;
+      }
+      if (var_idx != last_varidx)
+        break;
+      last_idx = delta_set_idx;
+    }
+
+    map_count = last_idx + 1;
+  }
+
+  bool remap (const hb_map_t &new_deltaset_idx_varidx_map)
+  {
+    /* recalculate bit_count */
+    outer_bit_count = 1;
+    inner_bit_count = 1;
+
+    if (unlikely (!output_map.resize (map_count, false))) return false;
+
+    for (unsigned idx = 0; idx < map_count; idx++)
+    {
+      uint32_t *var_idx;
+      if (!new_deltaset_idx_varidx_map.has (idx, &var_idx)) return false;
+      output_map.arrayZ[idx] = *var_idx;
+
+      unsigned outer = (*var_idx) >> 16;
+      unsigned bit_count = (outer == 0) ? 1 : hb_bit_storage (outer);
+      outer_bit_count = hb_max (bit_count, outer_bit_count);
+      
+      unsigned inner = (*var_idx) & 0xFFFF;
+      bit_count = (inner == 0) ? 1 : hb_bit_storage (inner);
+      inner_bit_count = hb_max (bit_count, inner_bit_count);
+    }
+    return true;
+  }
+
+  private:
+  unsigned map_count;
+  unsigned outer_bit_count;
+  unsigned inner_bit_count;
+  hb_vector_t<uint32_t> output_map;
+};
+
+struct COLR
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_COLR;
+
+  bool has_v0_data () const { return numBaseGlyphs; }
+  bool has_v1_data () const
+  {
+    if (version != 1)
+      return false;
+    hb_barrier ();
+
+    return (this+baseGlyphList).len > 0;
+  }
+
+  unsigned int get_glyph_layers (hb_codepoint_t       glyph,
+				 unsigned int         start_offset,
+				 unsigned int        *count, /* IN/OUT.  May be NULL. */
+				 hb_ot_color_layer_t *layers /* OUT.     May be NULL. */) const
+  {
+    const BaseGlyphRecord &record = (this+baseGlyphsZ).bsearch (numBaseGlyphs, glyph);
+
+    hb_array_t<const LayerRecord> all_layers = (this+layersZ).as_array (numLayers);
+    hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
+								       record.numLayers);
+    if (count)
+    {
+      + glyph_layers.sub_array (start_offset, count)
+      | hb_sink (hb_array (layers, *count))
+      ;
+    }
+    return glyph_layers.length;
+  }
+
+  struct accelerator_t
+  {
+    accelerator_t (hb_face_t *face)
+    { colr = hb_sanitize_context_t ().reference_table<COLR> (face); }
+    ~accelerator_t () { this->colr.destroy (); }
+
+    bool is_valid () { return colr.get_blob ()->length; }
+
+    void closure_glyphs (hb_codepoint_t glyph,
+			 hb_set_t *related_ids /* OUT */) const
+    { colr->closure_glyphs (glyph, related_ids); }
+
+    void closure_V0palette_indices (const hb_set_t *glyphs,
+				    hb_set_t *palettes /* OUT */) const
+    { colr->closure_V0palette_indices (glyphs, palettes); }
+
+    void closure_forV1 (hb_set_t *glyphset,
+                        hb_set_t *layer_indices,
+                        hb_set_t *palette_indices,
+                        hb_set_t *variation_indices,
+                        hb_set_t *delta_set_indices) const
+    { colr->closure_forV1 (glyphset, layer_indices, palette_indices, variation_indices, delta_set_indices); }
+
+    bool has_var_store () const
+    { return colr->has_var_store (); }
+
+    const ItemVariationStore &get_var_store () const
+    { return colr->get_var_store (); }
+
+    bool has_delta_set_index_map () const
+    { return colr->has_delta_set_index_map (); }
+
+    const DeltaSetIndexMap &get_delta_set_index_map () const
+    { return colr->get_delta_set_index_map (); }
+
+    private:
+    hb_blob_ptr_t<COLR> colr;
+  };
+
+  void closure_glyphs (hb_codepoint_t glyph,
+		       hb_set_t *related_ids /* OUT */) const
+  {
+    const BaseGlyphRecord *record = get_base_glyph_record (glyph);
+    if (!record) return;
+
+    auto glyph_layers = (this+layersZ).as_array (numLayers).sub_array (record->firstLayerIdx,
+								       record->numLayers);
+    if (!glyph_layers.length) return;
+    related_ids->add_array (&glyph_layers[0].glyphId, glyph_layers.length, LayerRecord::min_size);
+  }
+
+  void closure_V0palette_indices (const hb_set_t *glyphs,
+				  hb_set_t *palettes /* OUT */) const
+  {
+    if (!numBaseGlyphs || !numLayers) return;
+    hb_array_t<const BaseGlyphRecord> baseGlyphs = (this+baseGlyphsZ).as_array (numBaseGlyphs);
+    hb_array_t<const LayerRecord> all_layers = (this+layersZ).as_array (numLayers);
+
+    for (const BaseGlyphRecord record : baseGlyphs)
+    {
+      if (!glyphs->has (record.glyphId)) continue;
+      hb_array_t<const LayerRecord> glyph_layers = all_layers.sub_array (record.firstLayerIdx,
+                                                                   record.numLayers);
+      for (const LayerRecord layer : glyph_layers)
+        palettes->add (layer.colorIdx);
+    }
+  }
+
+  void closure_forV1 (hb_set_t *glyphset,
+                      hb_set_t *layer_indices,
+                      hb_set_t *palette_indices,
+                      hb_set_t *variation_indices,
+                      hb_set_t *delta_set_indices) const
+  {
+    if (version != 1) return;
+    hb_barrier ();
+
+    hb_set_t visited_glyphs;
+
+    hb_colrv1_closure_context_t c (this, &visited_glyphs, layer_indices, palette_indices, variation_indices);
+    const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList;
+
+    for (const BaseGlyphPaintRecord &baseglyph_paintrecord: baseglyph_paintrecords.iter ())
+    {
+      unsigned gid = baseglyph_paintrecord.glyphId;
+      if (!glyphset->has (gid)) continue;
+
+      const Paint &paint = &baseglyph_paintrecords+baseglyph_paintrecord.paint;
+      paint.dispatch (&c);
+    }
+    hb_set_union (glyphset, &visited_glyphs);
+
+    const ClipList &cliplist = this+clipList;
+    c.glyphs = glyphset;
+    for (const ClipRecord &clip_record : cliplist.clips.iter())
+      clip_record.closurev1 (&c, &cliplist);
+
+    // if a DeltaSetIndexMap is included, collected variation indices are
+    // actually delta set indices, we need to map them into variation indices
+    if (has_delta_set_index_map ())
+    {
+      const DeltaSetIndexMap &var_idx_map = this+varIdxMap;
+      delta_set_indices->set (*variation_indices);
+      variation_indices->clear ();
+      for (unsigned delta_set_idx : *delta_set_indices)
+        variation_indices->add (var_idx_map.map (delta_set_idx));
+    }
+  }
+
+  const LayerList& get_layerList () const
+  { return (this+layerList); }
+
+  const BaseGlyphList& get_baseglyphList () const
+  { return (this+baseGlyphList); }
+
+  bool has_var_store () const
+  { return version >= 1 && varStore != 0; }
+
+  bool has_delta_set_index_map () const
+  { return version >= 1 && varIdxMap != 0; }
+
+  const DeltaSetIndexMap &get_delta_set_index_map () const
+  { return (version == 0 || varIdxMap == 0) ? Null (DeltaSetIndexMap) : this+varIdxMap; }
+
+  const ItemVariationStore &get_var_store () const
+  { return (version == 0 || varStore == 0) ? Null (ItemVariationStore) : this+varStore; }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  hb_barrier () &&
+                  (this+baseGlyphsZ).sanitize (c, numBaseGlyphs) &&
+                  (this+layersZ).sanitize (c, numLayers) &&
+                  (version == 0 ||
+		   (hb_barrier () &&
+		    version == 1 &&
+		    baseGlyphList.sanitize (c, this) &&
+		    layerList.sanitize (c, this) &&
+		    clipList.sanitize (c, this) &&
+		    varIdxMap.sanitize (c, this) &&
+		    varStore.sanitize (c, this))));
+  }
+
+  template<typename BaseIterator, typename LayerIterator,
+	   hb_requires (hb_is_iterator (BaseIterator)),
+	   hb_requires (hb_is_iterator (LayerIterator))>
+  bool serialize_V0 (hb_serialize_context_t *c,
+		     unsigned version,
+		     BaseIterator base_it,
+		     LayerIterator layer_it)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (base_it.len () != layer_it.len ()))
+      return_trace (false);
+
+    this->version = version;
+    numLayers = 0;
+    numBaseGlyphs = base_it.len ();
+    if (numBaseGlyphs == 0)
+    {
+      baseGlyphsZ = 0;
+      layersZ = 0;
+      return_trace (true);
+    }
+
+    c->push ();
+    for (const hb_item_type<BaseIterator> _ : + base_it.iter ())
+    {
+      auto* record = c->embed (_);
+      if (unlikely (!record)) return_trace (false);
+      record->firstLayerIdx = numLayers;
+      numLayers += record->numLayers;
+    }
+    c->add_link (baseGlyphsZ, c->pop_pack ());
+
+    c->push ();
+    for (const hb_item_type<LayerIterator>& _ : + layer_it.iter ())
+      _.as_array ().copy (c);
+
+    c->add_link (layersZ, c->pop_pack ());
+
+    return_trace (true);
+  }
+
+  const BaseGlyphRecord* get_base_glyph_record (hb_codepoint_t gid) const
+  {
+    const BaseGlyphRecord* record = &(this+baseGlyphsZ).bsearch (numBaseGlyphs, (unsigned int) gid);
+    if (record == &Null (BaseGlyphRecord) ||
+        (record && (hb_codepoint_t) record->glyphId != gid))
+      record = nullptr;
+    return record;
+  }
+
+  const BaseGlyphPaintRecord* get_base_glyph_paintrecord (hb_codepoint_t gid) const
+  {
+    const BaseGlyphPaintRecord* record = &(this+baseGlyphList).bsearch ((unsigned) gid);
+    if ((record && (hb_codepoint_t) record->glyphId != gid))
+      record = nullptr;
+    return record;
+  }
+
+  bool downgrade_to_V0 (const hb_set_t &glyphset) const
+  {
+    //no more COLRv1 glyphs, downgrade to version 0
+    for (const BaseGlyphPaintRecord& _ : get_baseglyphList ())
+      if (glyphset.has (_.glyphId))
+        return false;
+
+    return true;
+  }
+
+  bool subset_varstore (hb_subset_context_t *c,
+                        COLR* out /* OUT */) const
+  {
+    TRACE_SUBSET (this);
+    if (!varStore || c->plan->all_axes_pinned ||
+        !c->plan->colrv1_variation_idx_delta_map)
+      return_trace (true);
+
+    const ItemVariationStore& var_store = this+varStore;
+    if (c->plan->normalized_coords)
+    {
+      item_variations_t item_vars;
+      /* turn off varstore optimization when varIdxMap is null, so we maintain
+       * original var_idx sequence */
+      bool optimize = (varIdxMap != 0) ? true : false;
+      if (!item_vars.instantiate (var_store, c->plan,
+                                  optimize, /* optimization */
+                                  optimize, /* use_no_variation_idx = false */
+                                  c->plan->colrv1_varstore_inner_maps.as_array ()))
+        return_trace (false);
+
+      if (!out->varStore.serialize_serialize (c->serializer,
+                                              item_vars.has_long_word (),
+                                              c->plan->axis_tags,
+                                              item_vars.get_region_list (),
+                                              item_vars.get_vardata_encodings ()))
+        return_trace (false);
+
+      /* if varstore is optimized, update colrv1_new_deltaset_idx_varidx_map in
+       * subset plan */
+      if (optimize)
+      {
+        const hb_map_t &varidx_map = item_vars.get_varidx_map ();
+        for (auto _ : c->plan->colrv1_new_deltaset_idx_varidx_map.iter_ref ())
+        {
+          uint32_t varidx = _.second;
+          uint32_t *new_varidx;
+          if (varidx_map.has (varidx, &new_varidx))
+            _.second = *new_varidx;
+          else
+            _.second = VarIdx::NO_VARIATION;
+        }
+      }
+    }
+    else
+    {
+      if (unlikely (!out->varStore.serialize_serialize (c->serializer,
+                                                        &var_store,
+                                                        c->plan->colrv1_varstore_inner_maps.as_array ())))
+        return_trace (false);
+    }
+
+    return_trace (true);
+  }
+
+  bool subset_delta_set_index_map (hb_subset_context_t *c,
+                                   COLR* out /* OUT */) const
+  {
+    TRACE_SUBSET (this);
+    if (!varIdxMap || c->plan->all_axes_pinned ||
+        !c->plan->colrv1_new_deltaset_idx_varidx_map)
+      return_trace (true);
+
+    const hb_map_t &deltaset_idx_varidx_map = c->plan->colrv1_new_deltaset_idx_varidx_map;
+    delta_set_index_map_subset_plan_t index_map_plan (deltaset_idx_varidx_map);
+
+    if (unlikely (!index_map_plan.remap (deltaset_idx_varidx_map)))
+      return_trace (false);
+
+    return_trace (out->varIdxMap.serialize_serialize (c->serializer, index_map_plan));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_map_t &reverse_glyph_map = *c->plan->reverse_glyph_map;
+    const hb_set_t& glyphset = c->plan->_glyphset_colred;
+
+    auto base_it =
+    + hb_range (c->plan->num_output_glyphs ())
+    | hb_filter ([&](hb_codepoint_t new_gid)
+		 {
+		    hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
+		    if (glyphset.has (old_gid)) return true;
+		    return false;
+		 })
+    | hb_map_retains_sorting ([&](hb_codepoint_t new_gid)
+			      {
+				hb_codepoint_t old_gid = reverse_glyph_map.get (new_gid);
+
+				const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid);
+				if (unlikely (!old_record))
+				  return hb_pair_t<bool, BaseGlyphRecord> (false, Null (BaseGlyphRecord));
+				BaseGlyphRecord new_record = {};
+				new_record.glyphId = new_gid;
+				new_record.numLayers = old_record->numLayers;
+				return hb_pair_t<bool, BaseGlyphRecord> (true, new_record);
+			      })
+    | hb_filter (hb_first)
+    | hb_map_retains_sorting (hb_second)
+    ;
+
+    auto layer_it =
+    + hb_range (c->plan->num_output_glyphs ())
+    | hb_map (reverse_glyph_map)
+    | hb_filter (glyphset)
+    | hb_map_retains_sorting ([&](hb_codepoint_t old_gid)
+			      {
+				const BaseGlyphRecord* old_record = get_base_glyph_record (old_gid);
+				hb_vector_t<LayerRecord> out_layers;
+
+				if (unlikely (!old_record ||
+					      old_record->firstLayerIdx >= numLayers ||
+					      old_record->firstLayerIdx + old_record->numLayers > numLayers))
+				  return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers);
+
+				auto layers = (this+layersZ).as_array (numLayers).sub_array (old_record->firstLayerIdx,
+											     old_record->numLayers);
+				out_layers.resize (layers.length);
+				for (unsigned int i = 0; i < layers.length; i++) {
+				  out_layers[i] = layers[i];
+				  hb_codepoint_t new_gid = 0;
+				  if (unlikely (!c->plan->new_gid_for_old_gid (out_layers[i].glyphId, &new_gid)))
+				    return hb_pair_t<bool, hb_vector_t<LayerRecord>> (false, out_layers);
+				  out_layers[i].glyphId = new_gid;
+				  out_layers[i].colorIdx = c->plan->colr_palettes.get (layers[i].colorIdx);
+				}
+
+				return hb_pair_t<bool, hb_vector_t<LayerRecord>> (true, out_layers);
+			      })
+    | hb_filter (hb_first)
+    | hb_map_retains_sorting (hb_second)
+    ;
+
+    if (version == 0 && (!base_it || !layer_it))
+      return_trace (false);
+
+    auto *colr_prime = c->serializer->start_embed<COLR> ();
+    if (unlikely (!c->serializer->extend_min (colr_prime)))  return_trace (false);
+
+    if (version == 0 || downgrade_to_V0 (glyphset))
+    return_trace (colr_prime->serialize_V0 (c->serializer, 0, base_it, layer_it));
+
+    //start version 1
+    if (!c->serializer->allocate_size<void> (5 * HBUINT32::static_size)) return_trace (false);
+    if (!colr_prime->serialize_V0 (c->serializer, version, base_it, layer_it)) return_trace (false);
+
+    /* subset ItemVariationStore first, cause varidx_map needs to be updated
+     * after instancing */
+    if (!subset_varstore (c, colr_prime)) return_trace (false);
+
+    ItemVarStoreInstancer instancer (varStore ? &(this+varStore) : nullptr,
+	                         varIdxMap ? &(this+varIdxMap) : nullptr,
+	                         c->plan->normalized_coords.as_array ());
+
+    if (!colr_prime->baseGlyphList.serialize_subset (c, baseGlyphList, this, instancer))
+      return_trace (false);
+
+    colr_prime->layerList.serialize_subset (c, layerList, this, instancer);
+    colr_prime->clipList.serialize_subset (c, clipList, this, instancer);
+
+    return_trace (subset_delta_set_index_map (c, colr_prime));
+  }
+
+  const Paint *get_base_glyph_paint (hb_codepoint_t glyph) const
+  {
+    const BaseGlyphList &baseglyph_paintrecords = this+baseGlyphList;
+    const BaseGlyphPaintRecord* record = get_base_glyph_paintrecord (glyph);
+    if (record)
+    {
+      const Paint &paint = &baseglyph_paintrecords+record->paint;
+      return &paint;
+    }
+    else
+      return nullptr;
+  }
+
+#ifndef HB_NO_PAINT
+  bool
+  get_extents (hb_font_t *font, hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
+  {
+    if (version != 1)
+      return false;
+
+    ItemVarStoreInstancer instancer (&(this+varStore),
+				 &(this+varIdxMap),
+				 hb_array (font->coords, font->num_coords));
+
+    if (get_clip (glyph, extents, instancer))
+    {
+      font->scale_glyph_extents (extents);
+      return true;
+    }
+
+    auto *extents_funcs = hb_paint_extents_get_funcs ();
+    hb_paint_extents_context_t extents_data;
+    bool ret = paint_glyph (font, glyph, extents_funcs, &extents_data, 0, HB_COLOR(0,0,0,0));
+
+    hb_extents_t e = extents_data.get_extents ();
+    if (e.is_void ())
+    {
+      extents->x_bearing = 0;
+      extents->y_bearing = 0;
+      extents->width = 0;
+      extents->height = 0;
+    }
+    else
+    {
+      extents->x_bearing = e.xmin;
+      extents->y_bearing = e.ymax;
+      extents->width = e.xmax - e.xmin;
+      extents->height = e.ymin - e.ymax;
+    }
+
+    return ret;
+  }
+#endif
+
+  bool
+  has_paint_for_glyph (hb_codepoint_t glyph) const
+  {
+    if (version == 1)
+    {
+      hb_barrier ();
+
+      const Paint *paint = get_base_glyph_paint (glyph);
+
+      return paint != nullptr;
+    }
+
+    return false;
+  }
+
+  bool get_clip (hb_codepoint_t glyph,
+		 hb_glyph_extents_t *extents,
+		 const ItemVarStoreInstancer instancer) const
+  {
+    return (this+clipList).get_extents (glyph,
+					extents,
+					instancer);
+  }
+
+#ifndef HB_NO_PAINT
+  bool
+  paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data, unsigned int palette_index, hb_color_t foreground, bool clip = true) const
+  {
+    ItemVarStoreInstancer instancer (&(this+varStore),
+	                         &(this+varIdxMap),
+	                         hb_array (font->coords, font->num_coords));
+    hb_paint_context_t c (this, funcs, data, font, palette_index, foreground, instancer);
+    c.current_glyphs.add (glyph);
+
+    if (version == 1)
+    {
+      hb_barrier ();
+
+      const Paint *paint = get_base_glyph_paint (glyph);
+      if (paint)
+      {
+        // COLRv1 glyph
+
+	bool is_bounded = true;
+	if (clip)
+	{
+	  hb_glyph_extents_t extents;
+	  if (get_clip (glyph, &extents, instancer))
+	  {
+	    font->scale_glyph_extents (&extents);
+	    c.funcs->push_clip_rectangle (c.data,
+					  extents.x_bearing,
+					  extents.y_bearing + extents.height,
+					  extents.x_bearing + extents.width,
+					  extents.y_bearing);
+	  }
+	  else
+	  {
+	    auto *extents_funcs = hb_paint_extents_get_funcs ();
+	    hb_paint_extents_context_t extents_data;
+
+	    paint_glyph (font, glyph,
+			 extents_funcs, &extents_data,
+			 palette_index, foreground,
+			 false);
+
+	    hb_extents_t extents = extents_data.get_extents ();
+	    is_bounded = extents_data.is_bounded ();
+
+	    c.funcs->push_clip_rectangle (c.data,
+					  extents.xmin,
+					  extents.ymin,
+					  extents.xmax,
+					  extents.ymax);
+	  }
+	}
+
+	c.funcs->push_root_transform (c.data, font);
+
+	if (is_bounded)
+	  c.recurse (*paint);
+
+	c.funcs->pop_transform (c.data);
+
+	if (clip)
+	  c.funcs->pop_clip (c.data);
+
+        return true;
+      }
+    }
+
+    const BaseGlyphRecord *record = get_base_glyph_record (glyph);
+    if (record && ((hb_codepoint_t) record->glyphId == glyph))
+    {
+      // COLRv0 glyph
+      for (const auto &r : (this+layersZ).as_array (numLayers)
+			   .sub_array (record->firstLayerIdx, record->numLayers))
+      {
+        hb_bool_t is_foreground;
+        hb_color_t color = c.get_color (r.colorIdx, 1., &is_foreground);
+        c.funcs->push_clip_glyph (c.data, r.glyphId, c.font);
+        c.funcs->color (c.data, is_foreground, color);
+        c.funcs->pop_clip (c.data);
+      }
+
+      return true;
+    }
+
+    return false;
+  }
+#endif
+
+  protected:
+  HBUINT16	version;	/* Table version number (starts at 0). */
+  HBUINT16	numBaseGlyphs;	/* Number of Base Glyph Records. */
+  NNOffset32To<SortedUnsizedArrayOf<BaseGlyphRecord>>
+		baseGlyphsZ;	/* Offset to Base Glyph records. */
+  NNOffset32To<UnsizedArrayOf<LayerRecord>>
+		layersZ;	/* Offset to Layer Records. */
+  HBUINT16	numLayers;	/* Number of Layer Records. */
+  // Version-1 additions
+  Offset32To<BaseGlyphList>		baseGlyphList;
+  Offset32To<LayerList>			layerList;
+  Offset32To<ClipList>			clipList;   // Offset to ClipList table (may be NULL)
+  Offset32To<DeltaSetIndexMap>		varIdxMap;  // Offset to DeltaSetIndexMap table (may be NULL)
+  Offset32To<ItemVariationStore>	varStore;
+  public:
+  DEFINE_SIZE_MIN (14);
+};
+
+struct COLR_accelerator_t : COLR::accelerator_t {
+  COLR_accelerator_t (hb_face_t *face) : COLR::accelerator_t (face) {}
+};
+
+void
+hb_paint_context_t::recurse (const Paint &paint)
+{
+  if (unlikely (depth_left <= 0 || edge_count <= 0)) return;
+  depth_left--;
+  edge_count--;
+  paint.dispatch (this);
+  depth_left++;
+}
+
+void PaintColrLayers::paint_glyph (hb_paint_context_t *c) const
+{
+  TRACE_PAINT (this);
+  const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
+  for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
+  {
+    if (unlikely (c->current_layers.has (i)))
+      continue;
+
+    c->current_layers.add (i);
+
+    const Paint &paint = paint_offset_lists.get_paint (i);
+    c->funcs->push_group (c->data);
+    c->recurse (paint);
+    c->funcs->pop_group (c->data, HB_PAINT_COMPOSITE_MODE_SRC_OVER);
+
+    c->current_layers.del (i);
+  }
+}
+
+void PaintColrGlyph::paint_glyph (hb_paint_context_t *c) const
+{
+  TRACE_PAINT (this);
+
+  if (unlikely (c->current_glyphs.has (gid)))
+    return;
+
+  c->current_glyphs.add (gid);
+
+  c->funcs->push_inverse_root_transform (c->data, c->font);
+  if (c->funcs->color_glyph (c->data, gid, c->font))
+  {
+    c->funcs->pop_transform (c->data);
+    c->current_glyphs.del (gid);
+    return;
+  }
+  c->funcs->pop_transform (c->data);
+
+  const COLR *colr_table = c->get_colr_table ();
+  const Paint *paint = colr_table->get_base_glyph_paint (gid);
+
+  hb_glyph_extents_t extents = {0};
+  bool has_clip_box = colr_table->get_clip (gid, &extents, c->instancer);
+
+  if (has_clip_box)
+    c->funcs->push_clip_rectangle (c->data,
+				   extents.x_bearing,
+				   extents.y_bearing + extents.height,
+				   extents.x_bearing + extents.width,
+				   extents.y_bearing);
+
+  if (paint)
+    c->recurse (*paint);
+
+  if (has_clip_box)
+    c->funcs->pop_clip (c->data);
+
+  c->current_glyphs.del (gid);
+}
+
+} /* namespace OT */
+
+#endif /* OT_COLOR_COLR_COLR_HH */

+ 137 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Color/COLR/colrv1-closure.hh

@@ -0,0 +1,137 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ * Copyright © 2020  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ */
+
+#ifndef OT_COLOR_COLR_COLRV1_CLOSURE_HH
+#define OT_COLOR_COLR_COLRV1_CLOSURE_HH
+
+#include "../../../hb-open-type.hh"
+#include "COLR.hh"
+
+/*
+ * COLR -- Color
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/colr
+ */
+namespace OT {
+
+HB_INTERNAL void PaintColrLayers::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  c->add_layer_indices (firstLayerIndex, numLayers);
+  const LayerList &paint_offset_lists = c->get_colr_table ()->get_layerList ();
+  for (unsigned i = firstLayerIndex; i < firstLayerIndex + numLayers; i++)
+  {
+    const Paint &paint = std::addressof (paint_offset_lists) + paint_offset_lists[i];
+    paint.dispatch (c);
+  }
+}
+
+HB_INTERNAL void PaintGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  c->add_glyph (gid);
+  (this+paint).dispatch (c);
+}
+
+HB_INTERNAL void PaintColrGlyph::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  const COLR *colr_table = c->get_colr_table ();
+  const BaseGlyphPaintRecord* baseglyph_paintrecord = colr_table->get_base_glyph_paintrecord (gid);
+  if (!baseglyph_paintrecord) return;
+  c->add_glyph (gid);
+
+  const BaseGlyphList &baseglyph_list = colr_table->get_baseglyphList ();
+  (&baseglyph_list+baseglyph_paintrecord->paint).dispatch (c);
+}
+
+template <template<typename> class Var>
+HB_INTERNAL void PaintTransform<Var>::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  (this+src).dispatch (c);
+  (this+transform).closurev1 (c);
+}
+
+HB_INTERNAL void PaintTranslate::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  (this+src).dispatch (c);
+  c->num_var_idxes = 2;
+}
+
+HB_INTERNAL void PaintScale::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  (this+src).dispatch (c);
+  c->num_var_idxes = 2;
+}
+
+HB_INTERNAL void PaintScaleAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  (this+src).dispatch (c);
+  c->num_var_idxes = 4;
+}
+
+HB_INTERNAL void PaintScaleUniform::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  (this+src).dispatch (c);
+  c->num_var_idxes = 1;
+}
+
+HB_INTERNAL void PaintScaleUniformAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  (this+src).dispatch (c);
+  c->num_var_idxes = 3;
+}
+
+HB_INTERNAL void PaintRotate::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  (this+src).dispatch (c);
+  c->num_var_idxes = 1;
+}
+
+HB_INTERNAL void PaintRotateAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  (this+src).dispatch (c);
+  c->num_var_idxes = 3;
+}
+
+HB_INTERNAL void PaintSkew::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  (this+src).dispatch (c);
+  c->num_var_idxes = 2;
+}
+
+HB_INTERNAL void PaintSkewAroundCenter::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  (this+src).dispatch (c);
+  c->num_var_idxes = 4;
+}
+
+HB_INTERNAL void PaintComposite::closurev1 (hb_colrv1_closure_context_t* c) const
+{
+  (this+src).dispatch (c);
+  (this+backdrop).dispatch (c);
+}
+
+} /* namespace OT */
+
+
+#endif /* OT_COLOR_COLR_COLRV1_CLOSURE_HH */

+ 358 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Color/CPAL/CPAL.hh

@@ -0,0 +1,358 @@
+/*
+ * Copyright © 2016  Google, Inc.
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Sascha Brawer
+ */
+
+#ifndef OT_COLOR_CPAL_CPAL_HH
+#define OT_COLOR_CPAL_CPAL_HH
+
+#include "../../../hb-open-type.hh"
+#include "../../../hb-ot-color.h"
+#include "../../../hb-ot-name.h"
+
+
+/*
+ * CPAL -- Color Palette
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/cpal
+ */
+#define HB_OT_TAG_CPAL HB_TAG('C','P','A','L')
+
+namespace OT {
+
+
+struct CPALV1Tail
+{
+  friend struct CPAL;
+
+  private:
+  hb_ot_color_palette_flags_t get_palette_flags (const void *base,
+						 unsigned int palette_index,
+						 unsigned int palette_count) const
+  {
+    if (!paletteFlagsZ) return HB_OT_COLOR_PALETTE_FLAG_DEFAULT;
+    return (hb_ot_color_palette_flags_t) (uint32_t)
+	   (base+paletteFlagsZ).as_array (palette_count)[palette_index];
+  }
+
+  hb_ot_name_id_t get_palette_name_id (const void *base,
+				       unsigned int palette_index,
+				       unsigned int palette_count) const
+  {
+    if (!paletteLabelsZ) return HB_OT_NAME_ID_INVALID;
+    return (base+paletteLabelsZ).as_array (palette_count)[palette_index];
+  }
+
+  hb_ot_name_id_t get_color_name_id (const void *base,
+				     unsigned int color_index,
+				     unsigned int color_count) const
+  {
+    if (!colorLabelsZ) return HB_OT_NAME_ID_INVALID;
+    return (base+colorLabelsZ).as_array (color_count)[color_index];
+  }
+
+  public:
+  void collect_name_ids (const void *base,
+                         unsigned palette_count,
+                         unsigned color_count,
+                         const hb_map_t *color_index_map,
+                         hb_set_t *nameids_to_retain /* OUT */) const
+  {
+    if (paletteLabelsZ)
+    {
+      + (base+paletteLabelsZ).as_array (palette_count)
+      | hb_sink (nameids_to_retain)
+      ;
+    }
+
+    if (colorLabelsZ)
+    {
+      const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count);
+      for (unsigned i = 0; i < color_count; i++)
+      {
+        if (!color_index_map->has (i)) continue;
+        nameids_to_retain->add (colorLabels[i]);
+      }
+    }
+  }
+
+  bool serialize (hb_serialize_context_t *c,
+                  unsigned palette_count,
+                  unsigned color_count,
+                  const void *base,
+                  const hb_map_t *color_index_map) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->allocate_size<CPALV1Tail> (static_size);
+    if (unlikely (!out)) return_trace (false);
+
+    out->paletteFlagsZ = 0;
+    if (paletteFlagsZ)
+      out->paletteFlagsZ.serialize_copy (c, paletteFlagsZ, base, 0, hb_serialize_context_t::Head, palette_count);
+
+    out->paletteLabelsZ = 0;
+    if (paletteLabelsZ)
+      out->paletteLabelsZ.serialize_copy (c, paletteLabelsZ, base, 0, hb_serialize_context_t::Head, palette_count);
+
+    const hb_array_t<const NameID> colorLabels = (base+colorLabelsZ).as_array (color_count);
+    if (colorLabelsZ)
+    {
+      c->push ();
+      for (unsigned i = 0; i < color_count; i++)
+      {
+        if (!color_index_map->has (i)) continue;
+        if (!c->copy<NameID> (colorLabels[i]))
+        {
+          c->pop_discard ();
+          return_trace (false);
+        }
+      }
+      c->add_link (out->colorLabelsZ, c->pop_pack ());
+    }
+    return_trace (true);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c,
+		 const void *base,
+		 unsigned int palette_count,
+		 unsigned int color_count) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  (!paletteFlagsZ  || (base+paletteFlagsZ).sanitize (c, palette_count)) &&
+		  (!paletteLabelsZ || (base+paletteLabelsZ).sanitize (c, palette_count)) &&
+		  (!colorLabelsZ   || (base+colorLabelsZ).sanitize (c, color_count)));
+  }
+
+  protected:
+  // TODO(garretrieger): these offsets can hold nulls so we should not be using non-null offsets
+  //                     here. Currently they are needed since UnsizedArrayOf doesn't define null_size
+  NNOffset32To<UnsizedArrayOf<HBUINT32>>
+		paletteFlagsZ;		/* Offset from the beginning of CPAL table to
+					 * the Palette Type Array. Set to 0 if no array
+					 * is provided. */
+  NNOffset32To<UnsizedArrayOf<NameID>>
+		paletteLabelsZ;		/* Offset from the beginning of CPAL table to
+					 * the palette labels array. Set to 0 if no
+					 * array is provided. */
+  NNOffset32To<UnsizedArrayOf<NameID>>
+		colorLabelsZ;		/* Offset from the beginning of CPAL table to
+					 * the color labels array. Set to 0
+					 * if no array is provided. */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+typedef HBUINT32 BGRAColor;
+
+struct CPAL
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_CPAL;
+
+  bool has_data () const { return numPalettes; }
+
+  unsigned int get_size () const
+  { return min_size + numPalettes * sizeof (colorRecordIndicesZ[0]); }
+
+  unsigned int get_palette_count () const { return numPalettes; }
+  unsigned int   get_color_count () const { return numColors; }
+
+  hb_ot_color_palette_flags_t get_palette_flags (unsigned int palette_index) const
+  { return v1 ().get_palette_flags (this, palette_index, numPalettes); }
+
+  hb_ot_name_id_t get_palette_name_id (unsigned int palette_index) const
+  { return v1 ().get_palette_name_id (this, palette_index, numPalettes); }
+
+  hb_ot_name_id_t get_color_name_id (unsigned int color_index) const
+  { return v1 ().get_color_name_id (this, color_index, numColors); }
+
+  unsigned int get_palette_colors (unsigned int  palette_index,
+				   unsigned int  start_offset,
+				   unsigned int *color_count, /* IN/OUT.  May be NULL. */
+				   hb_color_t   *colors       /* OUT.     May be NULL. */) const
+  {
+    if (unlikely (palette_index >= numPalettes))
+    {
+      if (color_count) *color_count = 0;
+      return 0;
+    }
+    unsigned int start_index = colorRecordIndicesZ[palette_index];
+    hb_array_t<const BGRAColor> all_colors ((this+colorRecordsZ).arrayZ, numColorRecords);
+    hb_array_t<const BGRAColor> palette_colors = all_colors.sub_array (start_index,
+								       numColors);
+    if (color_count)
+    {
+      + palette_colors.sub_array (start_offset, color_count)
+      | hb_sink (hb_array (colors, *color_count))
+      ;
+    }
+    return numColors;
+  }
+
+  void collect_name_ids (const hb_map_t *color_index_map,
+                         hb_set_t *nameids_to_retain /* OUT */) const
+  {
+    if (version == 1)
+    {
+      hb_barrier ();
+      v1 ().collect_name_ids (this, numPalettes, numColors, color_index_map, nameids_to_retain);
+    }
+  }
+
+  private:
+  const CPALV1Tail& v1 () const
+  {
+    if (version == 0) return Null (CPALV1Tail);
+    hb_barrier ();
+    return StructAfter<CPALV1Tail> (*this);
+  }
+
+  public:
+  bool serialize (hb_serialize_context_t *c,
+                  const hb_array_t<const HBUINT16> &color_record_indices,
+                  const hb_array_t<const BGRAColor> &color_records,
+                  const hb_vector_t<unsigned>& first_color_index_for_layer,
+                  const hb_map_t& first_color_to_layer_index,
+                  const hb_set_t &retained_color_indices) const
+  {
+    TRACE_SERIALIZE (this);
+
+    // TODO(grieger): limit total final size.
+
+    for (const auto idx : color_record_indices)
+    {
+      hb_codepoint_t layer_index = first_color_to_layer_index[idx];
+
+      HBUINT16 new_idx;
+      new_idx = layer_index * retained_color_indices.get_population ();
+      if (!c->copy<HBUINT16> (new_idx)) return_trace (false);
+    }
+
+    c->push ();
+    for (unsigned first_color_index : first_color_index_for_layer)
+    {
+      for (hb_codepoint_t color_index : retained_color_indices)
+      {
+        if (!c->copy<BGRAColor> (color_records[first_color_index + color_index]))
+        {
+          c->pop_discard ();
+          return_trace (false);
+        }
+      }
+    }
+
+    c->add_link (colorRecordsZ, c->pop_pack ());
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    if (!numPalettes) return_trace (false);
+
+    const hb_map_t *color_index_map = &c->plan->colr_palettes;
+    if (color_index_map->is_empty ()) return_trace (false);
+
+    hb_set_t retained_color_indices;
+    for (const auto _ : color_index_map->keys ())
+    {
+      if (_ == 0xFFFF) continue;
+      retained_color_indices.add (_);
+    }
+    if (retained_color_indices.is_empty ()) return_trace (false);
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+
+    out->version = version;
+    out->numColors = retained_color_indices.get_population ();
+    out->numPalettes = numPalettes;
+
+    hb_vector_t<unsigned> first_color_index_for_layer;
+    hb_map_t first_color_to_layer_index;
+
+    const hb_array_t<const HBUINT16> colorRecordIndices = colorRecordIndicesZ.as_array (numPalettes);
+    for (const auto first_color_record_idx : colorRecordIndices)
+    {
+      if (first_color_to_layer_index.has (first_color_record_idx)) continue;
+
+      first_color_index_for_layer.push (first_color_record_idx);
+      first_color_to_layer_index.set (first_color_record_idx,
+                                      first_color_index_for_layer.length - 1);
+    }
+
+    out->numColorRecords = first_color_index_for_layer.length
+                           * retained_color_indices.get_population ();
+
+    const hb_array_t<const BGRAColor> color_records = (this+colorRecordsZ).as_array (numColorRecords);
+    if (!out->serialize (c->serializer,
+                         colorRecordIndices,
+                         color_records,
+                         first_color_index_for_layer,
+                         first_color_to_layer_index,
+                         retained_color_indices))
+      return_trace (false);
+
+    if (version == 1)
+    {
+      hb_barrier ();
+      return_trace (v1 ().serialize (c->serializer, numPalettes, numColors, this, color_index_map));
+    }
+
+    return_trace (true);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  hb_barrier () &&
+		  (this+colorRecordsZ).sanitize (c, numColorRecords) &&
+		  colorRecordIndicesZ.sanitize (c, numPalettes) &&
+		  (version == 0 || v1 ().sanitize (c, this, numPalettes, numColors)));
+  }
+
+  protected:
+  HBUINT16	version;		/* Table version number */
+  /* Version 0 */
+  HBUINT16	numColors;		/* Number of colors in each palette. */
+  HBUINT16	numPalettes;		/* Number of palettes in the table. */
+  HBUINT16	numColorRecords;	/* Total number of color records, combined for
+					 * all palettes. */
+  NNOffset32To<UnsizedArrayOf<BGRAColor>>
+		colorRecordsZ;		/* Offset from the beginning of CPAL table to
+					 * the first ColorRecord. */
+  UnsizedArrayOf<HBUINT16>
+		colorRecordIndicesZ;	/* Index of each palette’s first color record in
+					 * the combined color record array. */
+/*CPALV1Tail	v1;*/
+  public:
+  DEFINE_SIZE_ARRAY (12, colorRecordIndicesZ);
+};
+
+} /* namespace OT */
+
+
+#endif /* OT_COLOR_CPAL_CPAL_HH */

+ 448 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Color/sbix/sbix.hh

@@ -0,0 +1,448 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ * Copyright © 2020  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Google Author(s): Calder Kitagawa
+ */
+
+#ifndef OT_COLOR_SBIX_SBIX_HH
+#define OT_COLOR_SBIX_SBIX_HH
+
+#include "../../../hb-open-type.hh"
+#include "../../../hb-paint.hh"
+
+/*
+ * sbix -- Standard Bitmap Graphics
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/sbix
+ * https://developer.apple.com/fonts/TrueType-Reference-Manual/RM06/Chap6sbix.html
+ */
+#define HB_OT_TAG_sbix HB_TAG('s','b','i','x')
+
+
+namespace OT {
+
+
+struct SBIXGlyph
+{
+  SBIXGlyph* copy (hb_serialize_context_t *c, unsigned int data_length) const
+  {
+    TRACE_SERIALIZE (this);
+    SBIXGlyph* new_glyph = c->start_embed<SBIXGlyph> ();
+    if (unlikely (!c->extend_min (new_glyph))) return_trace (nullptr);
+
+    new_glyph->xOffset = xOffset;
+    new_glyph->yOffset = yOffset;
+    new_glyph->graphicType = graphicType;
+    data.copy (c, data_length);
+    return_trace (new_glyph);
+  }
+
+  HBINT16	xOffset;	/* The horizontal (x-axis) offset from the left
+				 * edge of the graphic to the glyph’s origin.
+				 * That is, the x-coordinate of the point on the
+				 * baseline at the left edge of the glyph. */
+  HBINT16	yOffset;	/* The vertical (y-axis) offset from the bottom
+				 * edge of the graphic to the glyph’s origin.
+				 * That is, the y-coordinate of the point on the
+				 * baseline at the left edge of the glyph. */
+  Tag		graphicType;	/* Indicates the format of the embedded graphic
+				 * data: one of 'jpg ', 'png ' or 'tiff', or the
+				 * special format 'dupe'. */
+  UnsizedArrayOf<HBUINT8>
+		data;		/* The actual embedded graphic data. The total
+				 * length is inferred from sequential entries in
+				 * the glyphDataOffsets array and the fixed size
+				 * (8 bytes) of the preceding fields. */
+  public:
+  DEFINE_SIZE_ARRAY (8, data);
+};
+
+struct SBIXStrike
+{
+  static unsigned int get_size (unsigned num_glyphs)
+  { return min_size + num_glyphs * HBUINT32::static_size; }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  imageOffsetsZ.sanitize_shallow (c, c->get_num_glyphs () + 1));
+  }
+
+  hb_blob_t *get_glyph_blob (unsigned int  glyph_id,
+			     hb_blob_t    *sbix_blob,
+			     hb_tag_t      file_type,
+			     int          *x_offset,
+			     int          *y_offset,
+			     unsigned int  num_glyphs,
+			     unsigned int *strike_ppem) const
+  {
+    if (unlikely (!ppem)) return hb_blob_get_empty (); /* To get Null() object out of the way. */
+
+    unsigned int retry_count = 8;
+    unsigned int sbix_len = sbix_blob->length;
+    unsigned int strike_offset = (const char *) this - (const char *) sbix_blob->data;
+    assert (strike_offset < sbix_len);
+
+  retry:
+    if (unlikely (glyph_id >= num_glyphs ||
+		  imageOffsetsZ[glyph_id + 1] <= imageOffsetsZ[glyph_id] ||
+		  imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] <= SBIXGlyph::min_size ||
+		  (unsigned int) imageOffsetsZ[glyph_id + 1] > sbix_len - strike_offset))
+      return hb_blob_get_empty ();
+
+    unsigned int glyph_offset = strike_offset + (unsigned int) imageOffsetsZ[glyph_id] + SBIXGlyph::min_size;
+    unsigned int glyph_length = imageOffsetsZ[glyph_id + 1] - imageOffsetsZ[glyph_id] - SBIXGlyph::min_size;
+
+    const SBIXGlyph *glyph = &(this+imageOffsetsZ[glyph_id]);
+
+    if (glyph->graphicType == HB_TAG ('d','u','p','e'))
+    {
+      if (glyph_length >= 2)
+      {
+	glyph_id = *((HBUINT16 *) &glyph->data);
+	if (retry_count--)
+	  goto retry;
+      }
+      return hb_blob_get_empty ();
+    }
+
+    if (unlikely (file_type != glyph->graphicType))
+      return hb_blob_get_empty ();
+
+    if (strike_ppem) *strike_ppem = ppem;
+    if (x_offset) *x_offset = glyph->xOffset;
+    if (y_offset) *y_offset = glyph->yOffset;
+    return hb_blob_create_sub_blob (sbix_blob, glyph_offset, glyph_length);
+  }
+
+  bool subset (hb_subset_context_t *c, unsigned int available_len) const
+  {
+    TRACE_SUBSET (this);
+    unsigned int num_output_glyphs = c->plan->num_output_glyphs ();
+
+    auto* out = c->serializer->start_embed<SBIXStrike> ();
+    auto snap = c->serializer->snapshot ();
+    if (unlikely (!c->serializer->extend (out, num_output_glyphs + 1))) return_trace (false);
+    out->ppem = ppem;
+    out->resolution = resolution;
+    HBUINT32 head;
+    head = get_size (num_output_glyphs + 1);
+
+    bool has_glyphs = false;
+    for (unsigned new_gid = 0; new_gid < num_output_glyphs; new_gid++)
+    {
+      hb_codepoint_t old_gid;
+      if (!c->plan->old_gid_for_new_gid (new_gid, &old_gid) ||
+	  unlikely (imageOffsetsZ[old_gid].is_null () ||
+		    imageOffsetsZ[old_gid + 1].is_null () ||
+		    imageOffsetsZ[old_gid + 1] <= imageOffsetsZ[old_gid] ||
+		    imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid] <= SBIXGlyph::min_size) ||
+		    (unsigned int) imageOffsetsZ[old_gid + 1] > available_len)
+      {
+	out->imageOffsetsZ[new_gid] = head;
+	continue;
+      }
+      has_glyphs = true;
+      unsigned int delta = imageOffsetsZ[old_gid + 1] - imageOffsetsZ[old_gid];
+      unsigned int glyph_data_length = delta - SBIXGlyph::min_size;
+      if (!(this+imageOffsetsZ[old_gid]).copy (c->serializer, glyph_data_length))
+	return_trace (false);
+      out->imageOffsetsZ[new_gid] = head;
+      head += delta;
+    }
+    if (has_glyphs)
+      out->imageOffsetsZ[num_output_glyphs] = head;
+    else
+      c->serializer->revert (snap);
+    return_trace (has_glyphs);
+  }
+
+  public:
+  HBUINT16	ppem;		/* The PPEM size for which this strike was designed. */
+  HBUINT16	resolution;	/* The device pixel density (in PPI) for which this
+				 * strike was designed. (E.g., 96 PPI, 192 PPI.) */
+  protected:
+  UnsizedArrayOf<Offset32To<SBIXGlyph>>
+		imageOffsetsZ;	/* Offset from the beginning of the strike data header
+				 * to bitmap data for an individual glyph ID. */
+  public:
+  DEFINE_SIZE_ARRAY (4, imageOffsetsZ);
+};
+
+struct sbix
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_sbix;
+
+  bool has_data () const { return version; }
+
+  const SBIXStrike &get_strike (unsigned int i) const { return this+strikes[i]; }
+
+  struct accelerator_t
+  {
+    accelerator_t (hb_face_t *face)
+    {
+      table = hb_sanitize_context_t ().reference_table<sbix> (face);
+      num_glyphs = face->get_num_glyphs ();
+    }
+    ~accelerator_t () { table.destroy (); }
+
+    bool has_data () const { return table->has_data (); }
+
+    bool get_extents (hb_font_t          *font,
+		      hb_codepoint_t      glyph,
+		      hb_glyph_extents_t *extents,
+		      bool                scale = true) const
+    {
+      /* We only support PNG right now, and following function checks type. */
+      return get_png_extents (font, glyph, extents, scale);
+    }
+
+    hb_blob_t *reference_png (hb_font_t      *font,
+			      hb_codepoint_t  glyph_id,
+			      int            *x_offset,
+			      int            *y_offset,
+			      unsigned int   *available_ppem) const
+    {
+      return choose_strike (font).get_glyph_blob (glyph_id, table.get_blob (),
+						  HB_TAG ('p','n','g',' '),
+						  x_offset, y_offset,
+						  num_glyphs, available_ppem);
+    }
+
+    bool paint_glyph (hb_font_t *font, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
+    {
+      if (!has_data ())
+        return false;
+
+      int x_offset = 0, y_offset = 0;
+      unsigned int strike_ppem = 0;
+      hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem);
+      hb_glyph_extents_t extents;
+      hb_glyph_extents_t pixel_extents;
+
+      if (blob == hb_blob_get_empty ())
+        return false;
+
+      if (!hb_font_get_glyph_extents (font, glyph, &extents))
+        return false;
+
+      if (unlikely (!get_extents (font, glyph, &pixel_extents, false)))
+        return false;
+
+      bool ret = funcs->image (data,
+			       blob,
+			       pixel_extents.width, -pixel_extents.height,
+			       HB_PAINT_IMAGE_FORMAT_PNG,
+			       font->slant_xy,
+			       &extents);
+
+      hb_blob_destroy (blob);
+      return ret;
+    }
+
+    private:
+
+    const SBIXStrike &choose_strike (hb_font_t *font) const
+    {
+      unsigned count = table->strikes.len;
+      if (unlikely (!count))
+	return Null (SBIXStrike);
+
+      unsigned int requested_ppem = hb_max (font->x_ppem, font->y_ppem);
+      if (!requested_ppem)
+	requested_ppem = 1<<30; /* Choose largest strike. */
+      /* TODO Add DPI sensitivity as well? */
+      unsigned int best_i = 0;
+      unsigned int best_ppem = table->get_strike (0).ppem;
+
+      for (unsigned int i = 1; i < count; i++)
+      {
+	unsigned int ppem = (table->get_strike (i)).ppem;
+	if ((requested_ppem <= ppem && ppem < best_ppem) ||
+	    (requested_ppem > best_ppem && ppem > best_ppem))
+	{
+	  best_i = i;
+	  best_ppem = ppem;
+	}
+      }
+
+      return table->get_strike (best_i);
+    }
+
+    struct PNGHeader
+    {
+      HBUINT8	signature[8];
+      struct
+      {
+	struct
+	{
+	  HBUINT32	length;
+	  Tag		type;
+	}		header;
+	HBUINT32	width;
+	HBUINT32	height;
+	HBUINT8		bitDepth;
+	HBUINT8		colorType;
+	HBUINT8		compressionMethod;
+	HBUINT8		filterMethod;
+	HBUINT8		interlaceMethod;
+      } IHDR;
+
+      public:
+      DEFINE_SIZE_STATIC (29);
+    };
+
+    bool get_png_extents (hb_font_t          *font,
+			  hb_codepoint_t      glyph,
+			  hb_glyph_extents_t *extents,
+			  bool                scale = true) const
+    {
+      /* Following code is safe to call even without data.
+       * But faster to short-circuit. */
+      if (!has_data ())
+	return false;
+
+      int x_offset = 0, y_offset = 0;
+      unsigned int strike_ppem = 0;
+      hb_blob_t *blob = reference_png (font, glyph, &x_offset, &y_offset, &strike_ppem);
+
+      const PNGHeader &png = *blob->as<PNGHeader>();
+
+      if (png.IHDR.height >= 65536 || png.IHDR.width >= 65536)
+      {
+	hb_blob_destroy (blob);
+	return false;
+      }
+
+      extents->x_bearing = x_offset;
+      extents->y_bearing = png.IHDR.height + y_offset;
+      extents->width     = png.IHDR.width;
+      extents->height    = -1 * png.IHDR.height;
+
+      /* Convert to font units. */
+      if (strike_ppem && scale)
+      {
+	float scale = font->face->get_upem () / (float) strike_ppem;
+	extents->x_bearing = roundf (extents->x_bearing * scale);
+	extents->y_bearing = roundf (extents->y_bearing * scale);
+	extents->width = roundf (extents->width * scale);
+	extents->height = roundf (extents->height * scale);
+      }
+
+      if (scale)
+	font->scale_glyph_extents (extents);
+
+      hb_blob_destroy (blob);
+
+      return strike_ppem;
+    }
+
+    private:
+    hb_blob_ptr_t<sbix> table;
+
+    unsigned int num_glyphs;
+  };
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+			  hb_barrier () &&
+			  version >= 1 &&
+			  strikes.sanitize (c, this)));
+  }
+
+  bool
+  add_strike (hb_subset_context_t *c, unsigned i) const
+  {
+    if (strikes[i].is_null () || c->source_blob->length < (unsigned) strikes[i])
+      return false;
+
+    return (this+strikes[i]).subset (c, c->source_blob->length - (unsigned) strikes[i]);
+  }
+
+  bool serialize_strike_offsets (hb_subset_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+
+    auto *out = c->serializer->start_embed<Array32OfOffset32To<SBIXStrike>> ();
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    hb_vector_t<Offset32To<SBIXStrike>*> new_strikes;
+    hb_vector_t<hb_serialize_context_t::objidx_t> objidxs;
+    for (int i = strikes.len - 1; i >= 0; --i)
+    {
+      auto* o = out->serialize_append (c->serializer);
+      if (unlikely (!o)) return_trace (false);
+      *o = 0;
+      auto snap = c->serializer->snapshot ();
+      c->serializer->push ();
+      bool ret = add_strike (c, i);
+      if (!ret)
+      {
+	c->serializer->pop_discard ();
+	out->pop ();
+	c->serializer->revert (snap);
+      }
+      else
+      {
+	objidxs.push (c->serializer->pop_pack ());
+	new_strikes.push (o);
+      }
+    }
+    for (unsigned int i = 0; i < new_strikes.length; ++i)
+      c->serializer->add_link (*new_strikes[i], objidxs[new_strikes.length - 1 - i]);
+
+    return_trace (true);
+  }
+
+  bool subset (hb_subset_context_t* c) const
+  {
+    TRACE_SUBSET (this);
+
+    if (unlikely (!c->serializer->embed (this->version))) return_trace (false);
+    if (unlikely (!c->serializer->embed (this->flags))) return_trace (false);
+
+    return_trace (serialize_strike_offsets (c));
+  }
+
+  protected:
+  HBUINT16	version;	/* Table version number — set to 1 */
+  HBUINT16	flags;		/* Bit 0: Set to 1. Bit 1: Draw outlines.
+				 * Bits 2 to 15: reserved (set to 0). */
+  Array32OfOffset32To<SBIXStrike>
+		strikes;	/* Offsets from the beginning of the 'sbix'
+				 * table to data for each individual bitmap strike. */
+  public:
+  DEFINE_SIZE_ARRAY (8, strikes);
+};
+
+struct sbix_accelerator_t : sbix::accelerator_t {
+  sbix_accelerator_t (hb_face_t *face) : sbix::accelerator_t (face) {}
+};
+
+
+} /* namespace OT */
+
+#endif /* OT_COLOR_SBIX_SBIX_HH */

+ 152 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Color/svg/svg.hh

@@ -0,0 +1,152 @@
+/*
+ * Copyright © 2018  Ebrahim Byagowi
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ */
+
+#ifndef OT_COLOR_SVG_SVG_HH
+#define OT_COLOR_SVG_SVG_HH
+
+#include "../../../hb-open-type.hh"
+#include "../../../hb-blob.hh"
+#include "../../../hb-paint.hh"
+
+/*
+ * SVG -- SVG (Scalable Vector Graphics)
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/svg
+ */
+
+#define HB_OT_TAG_SVG HB_TAG('S','V','G',' ')
+
+
+namespace OT {
+
+
+struct SVGDocumentIndexEntry
+{
+  int cmp (hb_codepoint_t g) const
+  { return g < startGlyphID ? -1 : g > endGlyphID ? 1 : 0; }
+
+  hb_blob_t *reference_blob (hb_blob_t *svg_blob, unsigned int index_offset) const
+  {
+    return hb_blob_create_sub_blob (svg_blob,
+				    index_offset + (unsigned int) svgDoc,
+				    svgDocLength);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+		  hb_barrier () &&
+		  svgDoc.sanitize (c, base, svgDocLength));
+  }
+
+  protected:
+  HBUINT16	startGlyphID;	/* The first glyph ID in the range described by
+				 * this index entry. */
+  HBUINT16	endGlyphID;	/* The last glyph ID in the range described by
+				 * this index entry. Must be >= startGlyphID. */
+  NNOffset32To<UnsizedArrayOf<HBUINT8>>
+		svgDoc;		/* Offset from the beginning of the SVG Document Index
+				 * to an SVG document. Must be non-zero. */
+  HBUINT32	svgDocLength;	/* Length of the SVG document.
+				 * Must be non-zero. */
+  public:
+  DEFINE_SIZE_STATIC (12);
+};
+
+struct SVG
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_SVG;
+
+  bool has_data () const { return svgDocEntries; }
+
+  struct accelerator_t
+  {
+    accelerator_t (hb_face_t *face)
+    { table = hb_sanitize_context_t ().reference_table<SVG> (face); }
+    ~accelerator_t () { table.destroy (); }
+
+    hb_blob_t *reference_blob_for_glyph (hb_codepoint_t glyph_id) const
+    {
+      return table->get_glyph_entry (glyph_id).reference_blob (table.get_blob (),
+							       table->svgDocEntries);
+    }
+
+    bool has_data () const { return table->has_data (); }
+
+    bool paint_glyph (hb_font_t *font HB_UNUSED, hb_codepoint_t glyph, hb_paint_funcs_t *funcs, void *data) const
+    {
+      if (!has_data ())
+        return false;
+
+      hb_blob_t *blob = reference_blob_for_glyph (glyph);
+
+      if (blob == hb_blob_get_empty ())
+        return false;
+
+      funcs->image (data,
+		    blob,
+		    0, 0,
+		    HB_PAINT_IMAGE_FORMAT_SVG,
+		    font->slant_xy,
+		    nullptr);
+
+      hb_blob_destroy (blob);
+      return true;
+    }
+
+    private:
+    hb_blob_ptr_t<SVG> table;
+    public:
+    DEFINE_SIZE_STATIC (sizeof (hb_blob_ptr_t<SVG>));
+  };
+
+  const SVGDocumentIndexEntry &get_glyph_entry (hb_codepoint_t glyph_id) const
+  { return (this+svgDocEntries).bsearch (glyph_id); }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (likely (c->check_struct (this) &&
+			  (this+svgDocEntries).sanitize_shallow (c)));
+  }
+
+  protected:
+  HBUINT16	version;	/* Table version (starting at 0). */
+  Offset32To<SortedArray16Of<SVGDocumentIndexEntry>>
+		svgDocEntries;	/* Offset (relative to the start of the SVG table) to the
+				 * SVG Documents Index. Must be non-zero. */
+				/* Array of SVG Document Index Entries. */
+  HBUINT32	reserved;	/* Set to 0. */
+  public:
+  DEFINE_SIZE_STATIC (10);
+};
+
+struct SVG_accelerator_t : SVG::accelerator_t {
+  SVG_accelerator_t (hb_face_t *face) : SVG::accelerator_t (face) {}
+};
+
+} /* namespace OT */
+
+
+#endif /* OT_COLOR_SVG_SVG_HH */

+ 352 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/Common/Coverage.hh

@@ -0,0 +1,352 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2010,2012  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Garret Rieger
+ */
+
+#ifndef OT_LAYOUT_COMMON_COVERAGE_HH
+#define OT_LAYOUT_COMMON_COVERAGE_HH
+
+#include "../types.hh"
+#include "CoverageFormat1.hh"
+#include "CoverageFormat2.hh"
+
+namespace OT {
+namespace Layout {
+namespace Common {
+
+template<typename Iterator>
+static inline void Coverage_serialize (hb_serialize_context_t *c,
+                                       Iterator it);
+
+struct Coverage
+{
+
+  protected:
+  union {
+  HBUINT16                      format;         /* Format identifier */
+  CoverageFormat1_3<SmallTypes> format1;
+  CoverageFormat2_4<SmallTypes> format2;
+#ifndef HB_NO_BEYOND_64K
+  CoverageFormat1_3<MediumTypes>format3;
+  CoverageFormat2_4<MediumTypes>format4;
+#endif
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+
+#ifndef HB_OPTIMIZE_SIZE
+  HB_ALWAYS_INLINE
+#endif
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.format.sanitize (c)) return_trace (false);
+    hb_barrier ();
+    switch (u.format)
+    {
+    case 1: return_trace (u.format1.sanitize (c));
+    case 2: return_trace (u.format2.sanitize (c));
+#ifndef HB_NO_BEYOND_64K
+    case 3: return_trace (u.format3.sanitize (c));
+    case 4: return_trace (u.format4.sanitize (c));
+#endif
+    default:return_trace (true);
+    }
+  }
+
+  /* Has interface. */
+  unsigned operator [] (hb_codepoint_t k) const { return get (k); }
+  bool has (hb_codepoint_t k) const { return (*this)[k] != NOT_COVERED; }
+  /* Predicate. */
+  bool operator () (hb_codepoint_t k) const { return has (k); }
+
+  unsigned int get (hb_codepoint_t k) const { return get_coverage (k); }
+  unsigned int get_coverage (hb_codepoint_t glyph_id) const
+  {
+    switch (u.format) {
+    case 1: return u.format1.get_coverage (glyph_id);
+    case 2: return u.format2.get_coverage (glyph_id);
+#ifndef HB_NO_BEYOND_64K
+    case 3: return u.format3.get_coverage (glyph_id);
+    case 4: return u.format4.get_coverage (glyph_id);
+#endif
+    default:return NOT_COVERED;
+    }
+  }
+
+  unsigned get_population () const
+  {
+    switch (u.format) {
+    case 1: return u.format1.get_population ();
+    case 2: return u.format2.get_population ();
+#ifndef HB_NO_BEYOND_64K
+    case 3: return u.format3.get_population ();
+    case 4: return u.format4.get_population ();
+#endif
+    default:return NOT_COVERED;
+    }
+  }
+
+  template <typename Iterator,
+      hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c, Iterator glyphs)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+
+    unsigned count = hb_len (glyphs);
+    unsigned num_ranges = 0;
+    hb_codepoint_t last = (hb_codepoint_t) -2;
+    hb_codepoint_t max = 0;
+    bool unsorted = false;
+    for (auto g: glyphs)
+    {
+      if (last != (hb_codepoint_t) -2 && g < last)
+	unsorted = true;
+      if (last + 1 != g)
+	num_ranges++;
+      last = g;
+      if (g > max) max = g;
+    }
+    u.format = !unsorted && count <= num_ranges * 3 ? 1 : 2;
+
+#ifndef HB_NO_BEYOND_64K
+    if (max > 0xFFFFu)
+      u.format += 2;
+    if (unlikely (max > 0xFFFFFFu))
+#else
+    if (unlikely (max > 0xFFFFu))
+#endif
+    {
+      c->check_success (false, HB_SERIALIZE_ERROR_INT_OVERFLOW);
+      return_trace (false);
+    }
+
+    switch (u.format)
+    {
+    case 1: return_trace (u.format1.serialize (c, glyphs));
+    case 2: return_trace (u.format2.serialize (c, glyphs));
+#ifndef HB_NO_BEYOND_64K
+    case 3: return_trace (u.format3.serialize (c, glyphs));
+    case 4: return_trace (u.format4.serialize (c, glyphs));
+#endif
+    default:return_trace (false);
+    }
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto it =
+    + iter ()
+    | hb_take (c->plan->source->get_num_glyphs ())
+    | hb_map_retains_sorting (c->plan->glyph_map_gsub)
+    | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; })
+    ;
+
+    // Cache the iterator result as it will be iterated multiple times
+    // by the serialize code below.
+    hb_sorted_vector_t<hb_codepoint_t> glyphs (it);
+    Coverage_serialize (c->serializer, glyphs.iter ());
+    return_trace (bool (glyphs));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  {
+    switch (u.format)
+    {
+    case 1: return u.format1.intersects (glyphs);
+    case 2: return u.format2.intersects (glyphs);
+#ifndef HB_NO_BEYOND_64K
+    case 3: return u.format3.intersects (glyphs);
+    case 4: return u.format4.intersects (glyphs);
+#endif
+    default:return false;
+    }
+  }
+  bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
+  {
+    switch (u.format)
+    {
+    case 1: return u.format1.intersects_coverage (glyphs, index);
+    case 2: return u.format2.intersects_coverage (glyphs, index);
+#ifndef HB_NO_BEYOND_64K
+    case 3: return u.format3.intersects_coverage (glyphs, index);
+    case 4: return u.format4.intersects_coverage (glyphs, index);
+#endif
+    default:return false;
+    }
+  }
+
+  /* Might return false if array looks unsorted.
+   * Used for faster rejection of corrupt data. */
+  template <typename set_t>
+  bool collect_coverage (set_t *glyphs) const
+  {
+    switch (u.format)
+    {
+    case 1: return u.format1.collect_coverage (glyphs);
+    case 2: return u.format2.collect_coverage (glyphs);
+#ifndef HB_NO_BEYOND_64K
+    case 3: return u.format3.collect_coverage (glyphs);
+    case 4: return u.format4.collect_coverage (glyphs);
+#endif
+    default:return false;
+    }
+  }
+
+  template <typename IterableOut,
+	    hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
+  void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const
+  {
+    switch (u.format)
+    {
+    case 1: return u.format1.intersect_set (glyphs, intersect_glyphs);
+    case 2: return u.format2.intersect_set (glyphs, intersect_glyphs);
+#ifndef HB_NO_BEYOND_64K
+    case 3: return u.format3.intersect_set (glyphs, intersect_glyphs);
+    case 4: return u.format4.intersect_set (glyphs, intersect_glyphs);
+#endif
+    default:return ;
+    }
+  }
+
+  struct iter_t : hb_iter_with_fallback_t<iter_t, hb_codepoint_t>
+  {
+    static constexpr bool is_sorted_iterator = true;
+    iter_t (const Coverage &c_ = Null (Coverage))
+    {
+      hb_memset (this, 0, sizeof (*this));
+      format = c_.u.format;
+      switch (format)
+      {
+      case 1: u.format1.init (c_.u.format1); return;
+      case 2: u.format2.init (c_.u.format2); return;
+#ifndef HB_NO_BEYOND_64K
+      case 3: u.format3.init (c_.u.format3); return;
+      case 4: u.format4.init (c_.u.format4); return;
+#endif
+      default:                               return;
+      }
+    }
+    bool __more__ () const
+    {
+      switch (format)
+      {
+      case 1: return u.format1.__more__ ();
+      case 2: return u.format2.__more__ ();
+#ifndef HB_NO_BEYOND_64K
+      case 3: return u.format3.__more__ ();
+      case 4: return u.format4.__more__ ();
+#endif
+      default:return false;
+      }
+    }
+    void __next__ ()
+    {
+      switch (format)
+      {
+      case 1: u.format1.__next__ (); break;
+      case 2: u.format2.__next__ (); break;
+#ifndef HB_NO_BEYOND_64K
+      case 3: u.format3.__next__ (); break;
+      case 4: u.format4.__next__ (); break;
+#endif
+      default:                   break;
+      }
+    }
+    typedef hb_codepoint_t __item_t__;
+    __item_t__ __item__ () const { return get_glyph (); }
+
+    hb_codepoint_t get_glyph () const
+    {
+      switch (format)
+      {
+      case 1: return u.format1.get_glyph ();
+      case 2: return u.format2.get_glyph ();
+#ifndef HB_NO_BEYOND_64K
+      case 3: return u.format3.get_glyph ();
+      case 4: return u.format4.get_glyph ();
+#endif
+      default:return 0;
+      }
+    }
+    bool operator != (const iter_t& o) const
+    {
+      if (unlikely (format != o.format)) return true;
+      switch (format)
+      {
+      case 1: return u.format1 != o.u.format1;
+      case 2: return u.format2 != o.u.format2;
+#ifndef HB_NO_BEYOND_64K
+      case 3: return u.format3 != o.u.format3;
+      case 4: return u.format4 != o.u.format4;
+#endif
+      default:return false;
+      }
+    }
+    iter_t __end__ () const
+    {
+      iter_t it = {};
+      it.format = format;
+      switch (format)
+      {
+      case 1: it.u.format1 = u.format1.__end__ (); break;
+      case 2: it.u.format2 = u.format2.__end__ (); break;
+#ifndef HB_NO_BEYOND_64K
+      case 3: it.u.format3 = u.format3.__end__ (); break;
+      case 4: it.u.format4 = u.format4.__end__ (); break;
+#endif
+      default: break;
+      }
+      return it;
+    }
+
+    private:
+    unsigned int format;
+    union {
+#ifndef HB_NO_BEYOND_64K
+    CoverageFormat2_4<MediumTypes>::iter_t      format4; /* Put this one first since it's larger; helps shut up compiler. */
+    CoverageFormat1_3<MediumTypes>::iter_t      format3;
+#endif
+    CoverageFormat2_4<SmallTypes>::iter_t       format2; /* Put this one first since it's larger; helps shut up compiler. */
+    CoverageFormat1_3<SmallTypes>::iter_t       format1;
+    } u;
+  };
+  iter_t iter () const { return iter_t (*this); }
+};
+
+template<typename Iterator>
+static inline void
+Coverage_serialize (hb_serialize_context_t *c,
+                    Iterator it)
+{ c->start_embed<Coverage> ()->serialize (c, it); }
+
+}
+}
+}
+
+#endif  // #ifndef OT_LAYOUT_COMMON_COVERAGE_HH

+ 133 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/Common/CoverageFormat1.hh

@@ -0,0 +1,133 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2010,2012  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Garret Rieger
+ */
+
+
+#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH
+#define OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH
+
+namespace OT {
+namespace Layout {
+namespace Common {
+
+#define NOT_COVERED             ((unsigned int) -1)
+
+template <typename Types>
+struct CoverageFormat1_3
+{
+  friend struct Coverage;
+
+  protected:
+  HBUINT16      coverageFormat; /* Format identifier--format = 1 */
+  SortedArray16Of<typename Types::HBGlyphID>
+                glyphArray;     /* Array of GlyphIDs--in numerical order */
+  public:
+  DEFINE_SIZE_ARRAY (4, glyphArray);
+
+  private:
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (glyphArray.sanitize (c));
+  }
+
+  unsigned int get_coverage (hb_codepoint_t glyph_id) const
+  {
+    unsigned int i;
+    glyphArray.bfind (glyph_id, &i, HB_NOT_FOUND_STORE, NOT_COVERED);
+    return i;
+  }
+
+  unsigned get_population () const
+  {
+    return glyphArray.len;
+  }
+
+  template <typename Iterator,
+      hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c, Iterator glyphs)
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (glyphArray.serialize (c, glyphs));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  {
+    if (glyphArray.len > glyphs->get_population () * hb_bit_storage ((unsigned) glyphArray.len) / 2)
+    {
+      for (auto g : *glyphs)
+        if (get_coverage (g) != NOT_COVERED)
+	  return true;
+      return false;
+    }
+
+    for (const auto& g : glyphArray.as_array ())
+      if (glyphs->has (g))
+        return true;
+    return false;
+  }
+  bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
+  { return glyphs->has (glyphArray[index]); }
+
+  template <typename IterableOut,
+	    hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
+  void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const
+  {
+    unsigned count = glyphArray.len;
+    for (unsigned i = 0; i < count; i++)
+      if (glyphs.has (glyphArray[i]))
+        intersect_glyphs << glyphArray[i];
+  }
+
+  template <typename set_t>
+  bool collect_coverage (set_t *glyphs) const
+  { return glyphs->add_sorted_array (glyphArray.as_array ()); }
+
+  public:
+  /* Older compilers need this to be public. */
+  struct iter_t
+  {
+    void init (const struct CoverageFormat1_3 &c_) { c = &c_; i = 0; }
+    bool __more__ () const { return i < c->glyphArray.len; }
+    void __next__ () { i++; }
+    hb_codepoint_t get_glyph () const { return c->glyphArray[i]; }
+    bool operator != (const iter_t& o) const
+    { return i != o.i; }
+    iter_t __end__ () const { iter_t it; it.init (*c); it.i = c->glyphArray.len; return it; }
+
+    private:
+    const struct CoverageFormat1_3 *c;
+    unsigned int i;
+  };
+  private:
+};
+
+}
+}
+}
+
+#endif  // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT1_HH

+ 239 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/Common/CoverageFormat2.hh

@@ -0,0 +1,239 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2010,2012  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Garret Rieger
+ */
+
+#ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH
+#define OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH
+
+#include "RangeRecord.hh"
+
+namespace OT {
+namespace Layout {
+namespace Common {
+
+template <typename Types>
+struct CoverageFormat2_4
+{
+  friend struct Coverage;
+
+  protected:
+  HBUINT16      coverageFormat; /* Format identifier--format = 2 */
+  SortedArray16Of<RangeRecord<Types>>
+                rangeRecord;    /* Array of glyph ranges--ordered by
+                                 * Start GlyphID. rangeCount entries
+                                 * long */
+  public:
+  DEFINE_SIZE_ARRAY (4, rangeRecord);
+
+  private:
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (rangeRecord.sanitize (c));
+  }
+
+  unsigned int get_coverage (hb_codepoint_t glyph_id) const
+  {
+    const RangeRecord<Types> &range = rangeRecord.bsearch (glyph_id);
+    return likely (range.first <= range.last)
+         ? (unsigned int) range.value + (glyph_id - range.first)
+         : NOT_COVERED;
+  }
+
+  unsigned get_population () const
+  {
+    typename Types::large_int ret = 0;
+    for (const auto &r : rangeRecord)
+      ret += r.get_population ();
+    return ret > UINT_MAX ? UINT_MAX : (unsigned) ret;
+  }
+
+  template <typename Iterator,
+      hb_requires (hb_is_sorted_source_of (Iterator, hb_codepoint_t))>
+  bool serialize (hb_serialize_context_t *c, Iterator glyphs)
+  {
+    TRACE_SERIALIZE (this);
+    if (unlikely (!c->extend_min (this))) return_trace (false);
+
+    unsigned num_ranges = 0;
+    hb_codepoint_t last = (hb_codepoint_t) -2;
+    for (auto g: glyphs)
+    {
+      if (last + 1 != g)
+        num_ranges++;
+      last = g;
+    }
+
+    if (unlikely (!rangeRecord.serialize (c, num_ranges))) return_trace (false);
+    if (!num_ranges) return_trace (true);
+
+    unsigned count = 0;
+    unsigned range = (unsigned) -1;
+    last = (hb_codepoint_t) -2;
+    unsigned unsorted = false;
+    for (auto g: glyphs)
+    {
+      if (last + 1 != g)
+      {
+	if (unlikely (last != (hb_codepoint_t) -2 && last + 1 > g))
+	  unsorted = true;
+
+        range++;
+        rangeRecord.arrayZ[range].first = g;
+        rangeRecord.arrayZ[range].value = count;
+      }
+      rangeRecord.arrayZ[range].last = g;
+      last = g;
+      count++;
+    }
+
+    if (unlikely (unsorted))
+      rangeRecord.as_array ().qsort (RangeRecord<Types>::cmp_range);
+
+    return_trace (true);
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  {
+    if (rangeRecord.len > glyphs->get_population () * hb_bit_storage ((unsigned) rangeRecord.len) / 2)
+    {
+      for (auto g : *glyphs)
+        if (get_coverage (g) != NOT_COVERED)
+	  return true;
+      return false;
+    }
+
+    return hb_any (+ hb_iter (rangeRecord)
+                   | hb_map ([glyphs] (const RangeRecord<Types> &range) { return range.intersects (*glyphs); }));
+  }
+  bool intersects_coverage (const hb_set_t *glyphs, unsigned int index) const
+  {
+    auto *range = rangeRecord.as_array ().bsearch (index);
+    if (range)
+      return range->intersects (*glyphs);
+    return false;
+  }
+
+  template <typename IterableOut,
+	    hb_requires (hb_is_sink_of (IterableOut, hb_codepoint_t))>
+  void intersect_set (const hb_set_t &glyphs, IterableOut&& intersect_glyphs) const
+  {
+    /* Break out of loop for overlapping, broken, tables,
+     * to avoid fuzzer timouts. */
+    hb_codepoint_t last = 0;
+    for (const auto& range : rangeRecord)
+    {
+      if (unlikely (range.first < last))
+        break;
+      last = range.last;
+      for (hb_codepoint_t g = range.first - 1;
+	   glyphs.next (&g) && g <= last;)
+	intersect_glyphs << g;
+    }
+  }
+
+  template <typename set_t>
+  bool collect_coverage (set_t *glyphs) const
+  {
+    for (const auto& range: rangeRecord)
+      if (unlikely (!range.collect_coverage (glyphs)))
+        return false;
+    return true;
+  }
+
+  public:
+  /* Older compilers need this to be public. */
+  struct iter_t
+  {
+    void init (const CoverageFormat2_4 &c_)
+    {
+      c = &c_;
+      coverage = 0;
+      i = 0;
+      j = c->rangeRecord.len ? c->rangeRecord[0].first : 0;
+      if (unlikely (c->rangeRecord[0].first > c->rangeRecord[0].last))
+      {
+        /* Broken table. Skip. */
+        i = c->rangeRecord.len;
+        j = 0;
+      }
+    }
+    bool __more__ () const { return i < c->rangeRecord.len; }
+    void __next__ ()
+    {
+      if (j >= c->rangeRecord[i].last)
+      {
+        i++;
+        if (__more__ ())
+        {
+          unsigned int old = coverage;
+          j = c->rangeRecord.arrayZ[i].first;
+          coverage = c->rangeRecord.arrayZ[i].value;
+          if (unlikely (coverage != old + 1))
+          {
+            /* Broken table. Skip. Important to avoid DoS.
+             * Also, our callers depend on coverage being
+             * consecutive and monotonically increasing,
+             * ie. iota(). */
+           i = c->rangeRecord.len;
+           j = 0;
+           return;
+          }
+        }
+        else
+          j = 0;
+        return;
+      }
+      coverage++;
+      j++;
+    }
+    hb_codepoint_t get_glyph () const { return j; }
+    bool operator != (const iter_t& o) const
+    { return i != o.i || j != o.j; }
+    iter_t __end__ () const
+    {
+      iter_t it;
+      it.init (*c);
+      it.i = c->rangeRecord.len;
+      it.j = 0;
+      return it;
+    }
+
+    private:
+    const struct CoverageFormat2_4 *c;
+    unsigned int i, coverage;
+    hb_codepoint_t j;
+  };
+  private:
+};
+
+}
+}
+}
+
+#endif  // #ifndef OT_LAYOUT_COMMON_COVERAGEFORMAT2_HH

+ 97 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/Common/RangeRecord.hh

@@ -0,0 +1,97 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2010,2012  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod, Garret Rieger
+ */
+
+#ifndef OT_LAYOUT_COMMON_RANGERECORD_HH
+#define OT_LAYOUT_COMMON_RANGERECORD_HH
+
+namespace OT {
+namespace Layout {
+namespace Common {
+
+template <typename Types>
+struct RangeRecord
+{
+  typename Types::HBGlyphID     first;          /* First GlyphID in the range */
+  typename Types::HBGlyphID     last;           /* Last GlyphID in the range */
+  HBUINT16                      value;          /* Value */
+
+  DEFINE_SIZE_STATIC (2 + 2 * Types::size);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  int cmp (hb_codepoint_t g) const
+  { return g < first ? -1 : g <= last ? 0 : +1; }
+
+  HB_INTERNAL static int cmp_range (const void *pa, const void *pb) {
+    const RangeRecord *a = (const RangeRecord *) pa;
+    const RangeRecord *b = (const RangeRecord *) pb;
+    if (a->first < b->first) return -1;
+    if (a->first > b->first) return +1;
+    if (a->last < b->last) return -1;
+    if (a->last > b->last) return +1;
+    if (a->value < b->value) return -1;
+    if (a->value > b->value) return +1;
+    return 0;
+  }
+
+  unsigned get_population () const
+  {
+    if (unlikely (last < first)) return 0;
+    return (last - first + 1);
+  }
+
+  bool intersects (const hb_set_t &glyphs) const
+  { return glyphs.intersects (first, last); }
+
+  template <typename set_t>
+  bool collect_coverage (set_t *glyphs) const
+  { return glyphs->add_range (first, last); }
+};
+
+}
+}
+}
+
+// TODO(garretrieger): This was previously implemented using
+//    DECLARE_NULL_NAMESPACE_BYTES_TEMPLATE1 (OT, RangeRecord, 9);
+//    but that only works when there is only a single namespace level.
+//    The macro should probably be fixed so it can work in this situation.
+extern HB_INTERNAL const unsigned char _hb_Null_OT_RangeRecord[9];
+template <typename Spec>
+struct Null<OT::Layout::Common::RangeRecord<Spec>> {
+  static OT::Layout::Common::RangeRecord<Spec> const & get_null () {
+    return *reinterpret_cast<const OT::Layout::Common::RangeRecord<Spec> *> (_hb_Null_OT_RangeRecord);
+  }
+};
+
+
+#endif  // #ifndef OT_LAYOUT_COMMON_RANGERECORD_HH

+ 1044 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GDEF/GDEF.hh

@@ -0,0 +1,1044 @@
+/*
+ * Copyright © 2007,2008,2009  Red Hat, Inc.
+ * Copyright © 2010,2011,2012  Google, Inc.
+ *
+ *  This is part of HarfBuzz, a text shaping library.
+ *
+ * Permission is hereby granted, without written agreement and without
+ * license or royalty fees, to use, copy, modify, and distribute this
+ * software and its documentation for any purpose, provided that the
+ * above copyright notice and the following two paragraphs appear in
+ * all copies of this software.
+ *
+ * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
+ * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
+ * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
+ * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
+ * DAMAGE.
+ *
+ * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
+ * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
+ * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
+ * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
+ * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
+ *
+ * Red Hat Author(s): Behdad Esfahbod
+ * Google Author(s): Behdad Esfahbod
+ */
+
+#ifndef OT_LAYOUT_GDEF_GDEF_HH
+#define OT_LAYOUT_GDEF_GDEF_HH
+
+#include "../../../hb-ot-var-common.hh"
+
+#include "../../../hb-font.hh"
+#include "../../../hb-cache.hh"
+
+
+namespace OT {
+
+
+/*
+ * Attachment List Table
+ */
+
+/* Array of contour point indices--in increasing numerical order */
+struct AttachPoint : Array16Of<HBUINT16>
+{
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    return_trace (out->serialize (c->serializer, + iter ()));
+  }
+};
+
+struct AttachList
+{
+  unsigned int get_attach_points (hb_codepoint_t glyph_id,
+				  unsigned int start_offset,
+				  unsigned int *point_count /* IN/OUT */,
+				  unsigned int *point_array /* OUT */) const
+  {
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (index == NOT_COVERED)
+    {
+      if (point_count)
+	*point_count = 0;
+      return 0;
+    }
+
+    const AttachPoint &points = this+attachPoint[index];
+
+    if (point_count)
+    {
+      + points.as_array ().sub_array (start_offset, point_count)
+      | hb_sink (hb_array (point_array, *point_count))
+      ;
+    }
+
+    return points.len;
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + hb_zip (this+coverage, attachPoint)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (subset_offset_array (c, out->attachPoint, this), hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+    out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
+    return_trace (bool (new_coverage));
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && attachPoint.sanitize (c, this));
+  }
+
+  protected:
+  Offset16To<Coverage>
+		coverage;		/* Offset to Coverage table -- from
+					 * beginning of AttachList table */
+  Array16OfOffset16To<AttachPoint>
+		attachPoint;		/* Array of AttachPoint tables
+					 * in Coverage Index order */
+  public:
+  DEFINE_SIZE_ARRAY (4, attachPoint);
+};
+
+/*
+ * Ligature Caret Table
+ */
+
+struct CaretValueFormat1
+{
+  friend struct CaretValue;
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (true);
+  }
+
+  private:
+  hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction) const
+  {
+    return HB_DIRECTION_IS_HORIZONTAL (direction) ? font->em_scale_x (coordinate) : font->em_scale_y (coordinate);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  HBUINT16	caretValueFormat;	/* Format identifier--format = 1 */
+  FWORD		coordinate;		/* X or Y value, in design units */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct CaretValueFormat2
+{
+  friend struct CaretValue;
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+    return_trace (true);
+  }
+
+  private:
+  hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
+  {
+    hb_position_t x, y;
+    font->get_glyph_contour_point_for_origin (glyph_id, caretValuePoint, direction, &x, &y);
+    return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  protected:
+  HBUINT16	caretValueFormat;	/* Format identifier--format = 2 */
+  HBUINT16	caretValuePoint;	/* Contour point index on glyph */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+struct CaretValueFormat3
+{
+  friend struct CaretValue;
+
+  hb_position_t get_caret_value (hb_font_t *font, hb_direction_t direction,
+				 const ItemVariationStore &var_store) const
+  {
+    return HB_DIRECTION_IS_HORIZONTAL (direction) ?
+	   font->em_scale_x (coordinate) + (this+deviceTable).get_x_delta (font, var_store) :
+	   font->em_scale_y (coordinate) + (this+deviceTable).get_y_delta (font, var_store);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (!c->serializer->embed (caretValueFormat)) return_trace (false);
+    if (!c->serializer->embed (coordinate)) return_trace (false);
+
+    unsigned varidx = (this+deviceTable).get_variation_index ();
+    hb_pair_t<unsigned, int> *new_varidx_delta;
+    if (!c->plan->layout_variation_idx_delta_map.has (varidx, &new_varidx_delta))
+      return_trace (false);
+
+    uint32_t new_varidx = hb_first (*new_varidx_delta);
+    int delta = hb_second (*new_varidx_delta);
+    if (delta != 0)
+    {
+      if (!c->serializer->check_assign (out->coordinate, coordinate + delta, HB_SERIALIZE_ERROR_INT_OVERFLOW))
+        return_trace (false);
+    }
+
+    if (new_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
+      return_trace (c->serializer->check_assign (out->caretValueFormat, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
+
+    if (!c->serializer->embed (deviceTable))
+      return_trace (false);
+
+    return_trace (out->deviceTable.serialize_copy (c->serializer, deviceTable, this, c->serializer->to_bias (out),
+						   hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map));
+  }
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  { (this+deviceTable).collect_variation_indices (c); }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
+  }
+
+  protected:
+  HBUINT16	caretValueFormat;	/* Format identifier--format = 3 */
+  FWORD		coordinate;		/* X or Y value, in design units */
+  Offset16To<Device>
+		deviceTable;		/* Offset to Device table for X or Y
+					 * value--from beginning of CaretValue
+					 * table */
+  public:
+  DEFINE_SIZE_STATIC (6);
+};
+
+struct CaretValue
+{
+  hb_position_t get_caret_value (hb_font_t *font,
+				 hb_direction_t direction,
+				 hb_codepoint_t glyph_id,
+				 const ItemVariationStore &var_store) const
+  {
+    switch (u.format) {
+    case 1: return u.format1.get_caret_value (font, direction);
+    case 2: return u.format2.get_caret_value (font, direction, glyph_id);
+    case 3: return u.format3.get_caret_value (font, direction, var_store);
+    default:return 0;
+    }
+  }
+
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
+    TRACE_DISPATCH (this, u.format);
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+    case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    switch (u.format) {
+    case 1:
+    case 2:
+      return;
+    case 3:
+      u.format3.collect_variation_indices (c);
+      return;
+    default: return;
+    }
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.format.sanitize (c)) return_trace (false);
+    hb_barrier ();
+    switch (u.format) {
+    case 1: return_trace (u.format1.sanitize (c));
+    case 2: return_trace (u.format2.sanitize (c));
+    case 3: return_trace (u.format3.sanitize (c));
+    default:return_trace (true);
+    }
+  }
+
+  protected:
+  union {
+  HBUINT16		format;		/* Format identifier */
+  CaretValueFormat1	format1;
+  CaretValueFormat2	format2;
+  CaretValueFormat3	format3;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+};
+
+struct LigGlyph
+{
+  unsigned get_lig_carets (hb_font_t            *font,
+			   hb_direction_t        direction,
+			   hb_codepoint_t        glyph_id,
+			   const ItemVariationStore &var_store,
+			   unsigned              start_offset,
+			   unsigned             *caret_count /* IN/OUT */,
+			   hb_position_t        *caret_array /* OUT */) const
+  {
+    if (caret_count)
+    {
+      + carets.as_array ().sub_array (start_offset, caret_count)
+      | hb_map (hb_add (this))
+      | hb_map ([&] (const CaretValue &value) { return value.get_caret_value (font, direction, glyph_id, var_store); })
+      | hb_sink (hb_array (caret_array, *caret_count))
+      ;
+    }
+
+    return carets.len;
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    + hb_iter (carets)
+    | hb_apply (subset_offset_array (c, out->carets, this))
+    ;
+
+    return_trace (bool (out->carets));
+  }
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    for (const Offset16To<CaretValue>& offset : carets.iter ())
+      (this+offset).collect_variation_indices (c);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (carets.sanitize (c, this));
+  }
+
+  protected:
+  Array16OfOffset16To<CaretValue>
+		carets;			/* Offset array of CaretValue tables
+					 * --from beginning of LigGlyph table
+					 * --in increasing coordinate order */
+  public:
+  DEFINE_SIZE_ARRAY (2, carets);
+};
+
+struct LigCaretList
+{
+  unsigned int get_lig_carets (hb_font_t *font,
+			       hb_direction_t direction,
+			       hb_codepoint_t glyph_id,
+			       const ItemVariationStore &var_store,
+			       unsigned int start_offset,
+			       unsigned int *caret_count /* IN/OUT */,
+			       hb_position_t *caret_array /* OUT */) const
+  {
+    unsigned int index = (this+coverage).get_coverage (glyph_id);
+    if (index == NOT_COVERED)
+    {
+      if (caret_count)
+	*caret_count = 0;
+      return 0;
+    }
+    const LigGlyph &lig_glyph = this+ligGlyph[index];
+    return lig_glyph.get_lig_carets (font, direction, glyph_id, var_store, start_offset, caret_count, caret_array);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + hb_zip (this+coverage, ligGlyph)
+    | hb_filter (glyphset, hb_first)
+    | hb_filter (subset_offset_array (c, out->ligGlyph, this), hb_second)
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+    out->coverage.serialize_serialize (c->serializer, new_coverage.iter ());
+    return_trace (bool (new_coverage));
+  }
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    + hb_zip (this+coverage, ligGlyph)
+    | hb_filter (c->glyph_set, hb_first)
+    | hb_map (hb_second)
+    | hb_map (hb_add (this))
+    | hb_apply ([c] (const LigGlyph& _) { _.collect_variation_indices (c); })
+    ;
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this) && ligGlyph.sanitize (c, this));
+  }
+
+  protected:
+  Offset16To<Coverage>
+		coverage;		/* Offset to Coverage table--from
+					 * beginning of LigCaretList table */
+  Array16OfOffset16To<LigGlyph>
+		ligGlyph;		/* Array of LigGlyph tables
+					 * in Coverage Index order */
+  public:
+  DEFINE_SIZE_ARRAY (4, ligGlyph);
+};
+
+
+struct MarkGlyphSetsFormat1
+{
+  bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+  { return (this+coverage[set_index]).get_coverage (glyph_id) != NOT_COVERED; }
+
+  void collect_used_mark_sets (const hb_set_t& glyph_set,
+                               hb_set_t& used_mark_sets /* OUT */) const
+  {
+    unsigned i = 0;
+    for (const auto &offset : coverage)
+     {
+       const auto &cov = this+offset;
+       if (cov.intersects (&glyph_set))
+         used_mark_sets.add (i);
+
+       i++;
+     }
+  }
+
+  template <typename set_t>
+  void collect_coverage (hb_vector_t<set_t> &sets) const
+  {
+     for (const auto &offset : coverage)
+     {
+       const auto &cov = this+offset;
+       cov.collect_coverage (sets.push ());
+     }
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->format = format;
+
+    bool ret = true;
+    for (const Offset32To<Coverage>& offset : coverage.iter ())
+    {
+      auto snap = c->serializer->snapshot ();
+      auto *o = out->coverage.serialize_append (c->serializer);
+      if (unlikely (!o))
+      {
+	ret = false;
+	break;
+      }
+
+      //skip empty coverage
+      c->serializer->push ();
+      bool res = false;
+      if (offset) res = c->dispatch (this+offset);
+      if (!res)
+      {
+        c->serializer->pop_discard ();
+        c->serializer->revert (snap);
+        (out->coverage.len)--;
+        continue;
+      }
+      c->serializer->add_link (*o, c->serializer->pop_pack ());
+    }
+
+    return_trace (ret && out->coverage.len);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (coverage.sanitize (c, this));
+  }
+
+  protected:
+  HBUINT16	format;			/* Format identifier--format = 1 */
+  Array16Of<Offset32To<Coverage>>
+		coverage;		/* Array of long offsets to mark set
+					 * coverage tables */
+  public:
+  DEFINE_SIZE_ARRAY (4, coverage);
+};
+
+struct MarkGlyphSets
+{
+  bool covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+  {
+    switch (u.format) {
+    case 1: return u.format1.covers (set_index, glyph_id);
+    default:return false;
+    }
+  }
+
+  template <typename set_t>
+  void collect_coverage (hb_vector_t<set_t> &sets) const
+  {
+    switch (u.format) {
+    case 1: u.format1.collect_coverage (sets); return;
+    default:return;
+    }
+  }
+
+  void collect_used_mark_sets (const hb_set_t& glyph_set,
+                               hb_set_t& used_mark_sets /* OUT */) const
+  {
+    switch (u.format) {
+    case 1: u.format1.collect_used_mark_sets (glyph_set, used_mark_sets); return;
+    default:return;
+    }
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    switch (u.format) {
+    case 1: return_trace (u.format1.subset (c));
+    default:return_trace (false);
+    }
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.format.sanitize (c)) return_trace (false);
+    hb_barrier ();
+    switch (u.format) {
+    case 1: return_trace (u.format1.sanitize (c));
+    default:return_trace (true);
+    }
+  }
+
+  protected:
+  union {
+  HBUINT16		format;		/* Format identifier */
+  MarkGlyphSetsFormat1	format1;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+};
+
+
+/*
+ * GDEF -- Glyph Definition
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/gdef
+ */
+
+
+template <typename Types>
+struct GDEFVersion1_2
+{
+  friend struct GDEF;
+
+  protected:
+  FixedVersion<>version;		/* Version of the GDEF table--currently
+					 * 0x00010003u */
+  typename Types::template OffsetTo<ClassDef>
+		glyphClassDef;		/* Offset to class definition table
+					 * for glyph type--from beginning of
+					 * GDEF header (may be Null) */
+  typename Types::template OffsetTo<AttachList>
+		attachList;		/* Offset to list of glyphs with
+					 * attachment points--from beginning
+					 * of GDEF header (may be Null) */
+  typename Types::template OffsetTo<LigCaretList>
+		ligCaretList;		/* Offset to list of positioning points
+					 * for ligature carets--from beginning
+					 * of GDEF header (may be Null) */
+  typename Types::template OffsetTo<ClassDef>
+		markAttachClassDef;	/* Offset to class definition table for
+					 * mark attachment type--from beginning
+					 * of GDEF header (may be Null) */
+  typename Types::template OffsetTo<MarkGlyphSets>
+		markGlyphSetsDef;	/* Offset to the table of mark set
+					 * definitions--from beginning of GDEF
+					 * header (may be NULL).  Introduced
+					 * in version 0x00010002. */
+  Offset32To<ItemVariationStore>
+		varStore;		/* Offset to the table of Item Variation
+					 * Store--from beginning of GDEF
+					 * header (may be NULL).  Introduced
+					 * in version 0x00010003. */
+  public:
+  DEFINE_SIZE_MIN (4 + 4 * Types::size);
+
+  unsigned int get_size () const
+  {
+    return min_size +
+	   (version.to_int () >= 0x00010002u ? markGlyphSetsDef.static_size : 0) +
+	   (version.to_int () >= 0x00010003u ? varStore.static_size : 0);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (version.sanitize (c) &&
+		  glyphClassDef.sanitize (c, this) &&
+		  attachList.sanitize (c, this) &&
+		  ligCaretList.sanitize (c, this) &&
+		  markAttachClassDef.sanitize (c, this) &&
+		  hb_barrier () &&
+		  (version.to_int () < 0x00010002u || markGlyphSetsDef.sanitize (c, this)) &&
+		  (version.to_int () < 0x00010003u || varStore.sanitize (c, this)));
+  }
+
+  static void remap_varidx_after_instantiation (const hb_map_t& varidx_map,
+                                                hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>>& layout_variation_idx_delta_map /* IN/OUT */)
+  {
+    /* varidx_map is empty which means varstore is empty after instantiation,
+     * no variations, map all varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX.
+     * varidx_map doesn't have original varidx, indicating delta row is all
+     * zeros, map varidx to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */
+    for (auto _ : layout_variation_idx_delta_map.iter_ref ())
+    {
+      /* old_varidx->(varidx, delta) mapping generated for subsetting, then this
+       * varidx is used as key of varidx_map during instantiation */
+      uint32_t varidx = _.second.first;
+      uint32_t *new_varidx;
+      if (varidx_map.has (varidx, &new_varidx))
+        _.second.first = *new_varidx;
+      else
+        _.second.first = HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
+    }
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    // Push var store first (if it's needed) so that it's last in the
+    // serialization order. Some font consumers assume that varstore runs to
+    // the end of the GDEF table.
+    // See: https://github.com/harfbuzz/harfbuzz/issues/4636
+    auto snapshot_version0 = c->serializer->snapshot ();
+    if (unlikely (version.to_int () >= 0x00010002u && !c->serializer->embed (markGlyphSetsDef)))
+      return_trace (false);
+
+    bool subset_varstore = false;
+    unsigned varstore_index = (unsigned) -1;
+    auto snapshot_version2 = c->serializer->snapshot ();
+    if (version.to_int () >= 0x00010003u)
+    {
+      if (unlikely (!c->serializer->embed (varStore))) return_trace (false);
+      if (c->plan->all_axes_pinned)
+        out->varStore = 0;
+      else if (c->plan->normalized_coords)
+      {
+        if (varStore)
+        {
+          item_variations_t item_vars;
+          if (item_vars.instantiate (this+varStore, c->plan, true, true,
+                                     c->plan->gdef_varstore_inner_maps.as_array ())) {
+            subset_varstore = out->varStore.serialize_serialize (c->serializer,
+                                                                 item_vars.has_long_word (),
+                                                                 c->plan->axis_tags,
+                                                                 item_vars.get_region_list (),
+                                                                 item_vars.get_vardata_encodings ());
+            varstore_index = c->serializer->last_added_child_index();
+          }
+          remap_varidx_after_instantiation (item_vars.get_varidx_map (),
+                                            c->plan->layout_variation_idx_delta_map);
+        }
+      }
+      else
+      {
+        subset_varstore = out->varStore.serialize_subset (c, varStore, this, c->plan->gdef_varstore_inner_maps.as_array ());
+        varstore_index = c->serializer->last_added_child_index();
+      }
+    }
+
+    out->version.major = version.major;
+    out->version.minor = version.minor;
+
+    if (!subset_varstore && version.to_int () >= 0x00010002u) {
+      c->serializer->revert (snapshot_version2);
+    }
+
+    bool subset_markglyphsetsdef = false;
+    if (version.to_int () >= 0x00010002u)
+    {
+      subset_markglyphsetsdef = out->markGlyphSetsDef.serialize_subset (c, markGlyphSetsDef, this);
+    }
+
+    if (subset_varstore)
+    {
+      out->version.minor = 3;
+      c->plan->has_gdef_varstore = true;
+    } else if (subset_markglyphsetsdef) {
+      out->version.minor = 2;      
+    } else  {
+      out->version.minor = 0;
+      c->serializer->revert (snapshot_version0);
+    }
+
+    bool subset_glyphclassdef = out->glyphClassDef.serialize_subset (c, glyphClassDef, this, nullptr, false, true);
+    bool subset_attachlist = out->attachList.serialize_subset (c, attachList, this);
+    bool subset_markattachclassdef = out->markAttachClassDef.serialize_subset (c, markAttachClassDef, this, nullptr, false, true);
+    bool subset_ligcaretlist = out->ligCaretList.serialize_subset (c, ligCaretList, this);
+
+    if (subset_varstore && varstore_index != (unsigned) -1) {
+      c->serializer->repack_last(varstore_index);
+    }
+
+    return_trace (subset_glyphclassdef || subset_attachlist ||
+		  subset_ligcaretlist || subset_markattachclassdef ||
+		  (out->version.to_int () >= 0x00010002u && subset_markglyphsetsdef) ||
+		  (out->version.to_int () >= 0x00010003u && subset_varstore));
+  }
+};
+
+struct GDEF
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_GDEF;
+
+  enum GlyphClasses {
+    UnclassifiedGlyph	= 0,
+    BaseGlyph		= 1,
+    LigatureGlyph	= 2,
+    MarkGlyph		= 3,
+    ComponentGlyph	= 4
+  };
+
+  unsigned int get_size () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version1.get_size ();
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.get_size ();
+#endif
+    default: return u.version.static_size;
+    }
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!u.version.sanitize (c))) return_trace (false);
+    hb_barrier ();
+    switch (u.version.major) {
+    case 1: return_trace (u.version1.sanitize (c));
+#ifndef HB_NO_BEYOND_64K
+    case 2: return_trace (u.version2.sanitize (c));
+#endif
+    default: return_trace (true);
+    }
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    switch (u.version.major) {
+    case 1: return u.version1.subset (c);
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.subset (c);
+#endif
+    default: return false;
+    }
+  }
+
+  bool has_glyph_classes () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version1.glyphClassDef != 0;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.glyphClassDef != 0;
+#endif
+    default: return false;
+    }
+  }
+  const ClassDef &get_glyph_class_def () const
+  {
+    switch (u.version.major) {
+    case 1: return this+u.version1.glyphClassDef;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return this+u.version2.glyphClassDef;
+#endif
+    default: return Null(ClassDef);
+    }
+  }
+  bool has_attach_list () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version1.attachList != 0;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.attachList != 0;
+#endif
+    default: return false;
+    }
+  }
+  const AttachList &get_attach_list () const
+  {
+    switch (u.version.major) {
+    case 1: return this+u.version1.attachList;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return this+u.version2.attachList;
+#endif
+    default: return Null(AttachList);
+    }
+  }
+  bool has_lig_carets () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version1.ligCaretList != 0;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.ligCaretList != 0;
+#endif
+    default: return false;
+    }
+  }
+  const LigCaretList &get_lig_caret_list () const
+  {
+    switch (u.version.major) {
+    case 1: return this+u.version1.ligCaretList;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return this+u.version2.ligCaretList;
+#endif
+    default: return Null(LigCaretList);
+    }
+  }
+  bool has_mark_attachment_types () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version1.markAttachClassDef != 0;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.markAttachClassDef != 0;
+#endif
+    default: return false;
+    }
+  }
+  const ClassDef &get_mark_attach_class_def () const
+  {
+    switch (u.version.major) {
+    case 1: return this+u.version1.markAttachClassDef;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return this+u.version2.markAttachClassDef;
+#endif
+    default: return Null(ClassDef);
+    }
+  }
+  bool has_mark_glyph_sets () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version.to_int () >= 0x00010002u && u.version1.markGlyphSetsDef != 0;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.markGlyphSetsDef != 0;
+#endif
+    default: return false;
+    }
+  }
+  const MarkGlyphSets &get_mark_glyph_sets () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version.to_int () >= 0x00010002u ? this+u.version1.markGlyphSetsDef : Null(MarkGlyphSets);
+#ifndef HB_NO_BEYOND_64K
+    case 2: return this+u.version2.markGlyphSetsDef;
+#endif
+    default: return Null(MarkGlyphSets);
+    }
+  }
+  bool has_var_store () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version.to_int () >= 0x00010003u && u.version1.varStore != 0;
+#ifndef HB_NO_BEYOND_64K
+    case 2: return u.version2.varStore != 0;
+#endif
+    default: return false;
+    }
+  }
+  const ItemVariationStore &get_var_store () const
+  {
+    switch (u.version.major) {
+    case 1: return u.version.to_int () >= 0x00010003u ? this+u.version1.varStore : Null(ItemVariationStore);
+#ifndef HB_NO_BEYOND_64K
+    case 2: return this+u.version2.varStore;
+#endif
+    default: return Null(ItemVariationStore);
+    }
+  }
+
+
+  bool has_data () const { return u.version.to_int (); }
+  unsigned int get_glyph_class (hb_codepoint_t glyph) const
+  { return get_glyph_class_def ().get_class (glyph); }
+  void get_glyphs_in_class (unsigned int klass, hb_set_t *glyphs) const
+  { get_glyph_class_def ().collect_class (glyphs, klass); }
+
+  unsigned int get_mark_attachment_type (hb_codepoint_t glyph) const
+  { return get_mark_attach_class_def ().get_class (glyph); }
+
+  unsigned int get_attach_points (hb_codepoint_t glyph_id,
+				  unsigned int start_offset,
+				  unsigned int *point_count /* IN/OUT */,
+				  unsigned int *point_array /* OUT */) const
+  { return get_attach_list ().get_attach_points (glyph_id, start_offset, point_count, point_array); }
+
+  unsigned int get_lig_carets (hb_font_t *font,
+			       hb_direction_t direction,
+			       hb_codepoint_t glyph_id,
+			       unsigned int start_offset,
+			       unsigned int *caret_count /* IN/OUT */,
+			       hb_position_t *caret_array /* OUT */) const
+  { return get_lig_caret_list ().get_lig_carets (font,
+						 direction, glyph_id, get_var_store(),
+						 start_offset, caret_count, caret_array); }
+
+  bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+  { return get_mark_glyph_sets ().covers (set_index, glyph_id); }
+
+  /* glyph_props is a 16-bit integer where the lower 8-bit have bits representing
+   * glyph class and other bits, and high 8-bit the mark attachment type (if any).
+   * Not to be confused with lookup_props which is very similar. */
+  unsigned int get_glyph_props (hb_codepoint_t glyph) const
+  {
+    unsigned int klass = get_glyph_class (glyph);
+
+    static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH == (unsigned int) LookupFlag::IgnoreBaseGlyphs), "");
+    static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE == (unsigned int) LookupFlag::IgnoreLigatures), "");
+    static_assert (((unsigned int) HB_OT_LAYOUT_GLYPH_PROPS_MARK == (unsigned int) LookupFlag::IgnoreMarks), "");
+
+    switch (klass) {
+    default:			return HB_OT_LAYOUT_GLYPH_CLASS_UNCLASSIFIED;
+    case BaseGlyph:		return HB_OT_LAYOUT_GLYPH_PROPS_BASE_GLYPH;
+    case LigatureGlyph:		return HB_OT_LAYOUT_GLYPH_PROPS_LIGATURE;
+    case MarkGlyph:
+	  klass = get_mark_attachment_type (glyph);
+	  return HB_OT_LAYOUT_GLYPH_PROPS_MARK | (klass << 8);
+    }
+  }
+
+  HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
+				   hb_face_t *face) const;
+
+  struct accelerator_t
+  {
+    accelerator_t (hb_face_t *face)
+    {
+      table = hb_sanitize_context_t ().reference_table<GDEF> (face);
+      if (unlikely (table->is_blocklisted (table.get_blob (), face)))
+      {
+	hb_blob_destroy (table.get_blob ());
+	table = hb_blob_get_empty ();
+      }
+
+#ifndef HB_NO_GDEF_CACHE
+      table->get_mark_glyph_sets ().collect_coverage (mark_glyph_set_digests);
+#endif
+    }
+    ~accelerator_t () { table.destroy (); }
+
+    unsigned int get_glyph_props (hb_codepoint_t glyph) const
+    {
+      unsigned v;
+
+#ifndef HB_NO_GDEF_CACHE
+      if (glyph_props_cache.get (glyph, &v))
+        return v;
+#endif
+
+      v = table->get_glyph_props (glyph);
+
+#ifndef HB_NO_GDEF_CACHE
+      if (likely (table.get_blob ())) // Don't try setting if we are the null instance!
+	glyph_props_cache.set (glyph, v);
+#endif
+
+      return v;
+
+    }
+
+    bool mark_set_covers (unsigned int set_index, hb_codepoint_t glyph_id) const
+    {
+      return
+#ifndef HB_NO_GDEF_CACHE
+	     mark_glyph_set_digests[set_index].may_have (glyph_id) &&
+#endif
+	     table->mark_set_covers (set_index, glyph_id);
+    }
+
+    hb_blob_ptr_t<GDEF> table;
+#ifndef HB_NO_GDEF_CACHE
+    hb_vector_t<hb_set_digest_t> mark_glyph_set_digests;
+    mutable hb_cache_t<21, 3, 8> glyph_props_cache;
+#endif
+  };
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  { get_lig_caret_list ().collect_variation_indices (c); }
+
+  protected:
+  union {
+  FixedVersion<>		version;	/* Version identifier */
+  GDEFVersion1_2<SmallTypes>	version1;
+#ifndef HB_NO_BEYOND_64K
+  GDEFVersion1_2<MediumTypes>	version2;
+#endif
+  } u;
+  public:
+  DEFINE_SIZE_MIN (4);
+};
+
+struct GDEF_accelerator_t : GDEF::accelerator_t {
+  GDEF_accelerator_t (hb_face_t *face) : GDEF::accelerator_t (face) {}
+};
+
+} /* namespace OT */
+
+
+#endif /* OT_LAYOUT_GDEF_GDEF_HH */

+ 84 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/Anchor.hh

@@ -0,0 +1,84 @@
+#ifndef OT_LAYOUT_GPOS_ANCHOR_HH
+#define OT_LAYOUT_GPOS_ANCHOR_HH
+
+#include "AnchorFormat1.hh"
+#include "AnchorFormat2.hh"
+#include "AnchorFormat3.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct Anchor
+{
+  protected:
+  union {
+  HBUINT16              format;         /* Format identifier */
+  AnchorFormat1         format1;
+  AnchorFormat2         format2;
+  AnchorFormat3         format3;
+  } u;
+  public:
+  DEFINE_SIZE_UNION (2, format);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (!u.format.sanitize (c)) return_trace (false);
+    hb_barrier ();
+    switch (u.format) {
+    case 1: return_trace (u.format1.sanitize (c));
+    case 2: return_trace (u.format2.sanitize (c));
+    case 3: return_trace (u.format3.sanitize (c));
+    default:return_trace (true);
+    }
+  }
+
+  void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
+                   float *x, float *y) const
+  {
+    *x = *y = 0;
+    switch (u.format) {
+    case 1: u.format1.get_anchor (c, glyph_id, x, y); return;
+    case 2: u.format2.get_anchor (c, glyph_id, x, y); return;
+    case 3: u.format3.get_anchor (c, glyph_id, x, y); return;
+    default:                                          return;
+    }
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    switch (u.format) {
+    case 1: return_trace (bool (reinterpret_cast<Anchor *> (u.format1.copy (c->serializer))));
+    case 2:
+      if (c->plan->flags & HB_SUBSET_FLAGS_NO_HINTING)
+      {
+        // AnchorFormat 2 just containins extra hinting information, so
+        // if hints are being dropped convert to format 1.
+        return_trace (bool (reinterpret_cast<Anchor *> (u.format1.copy (c->serializer))));
+      }
+      return_trace (bool (reinterpret_cast<Anchor *> (u.format2.copy (c->serializer))));
+    case 3: return_trace (u.format3.subset (c));
+    default:return_trace (false);
+    }
+  }
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    switch (u.format) {
+    case 1: case 2:
+      return;
+    case 3:
+      u.format3.collect_variation_indices (c);
+      return;
+    default: return;
+    }
+  }
+};
+
+}
+}
+}
+
+#endif  // OT_LAYOUT_GPOS_ANCHOR_HH

+ 46 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/AnchorFormat1.hh

@@ -0,0 +1,46 @@
+#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT1_HH
+#define OT_LAYOUT_GPOS_ANCHORFORMAT1_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct AnchorFormat1
+{
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 1 */
+  FWORD         xCoordinate;            /* Horizontal value--in design units */
+  FWORD         yCoordinate;            /* Vertical value--in design units */
+  public:
+  DEFINE_SIZE_STATIC (6);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
+                   float *x, float *y) const
+  {
+    hb_font_t *font = c->font;
+    *x = font->em_fscale_x (xCoordinate);
+    *y = font->em_fscale_y (yCoordinate);
+  }
+
+  AnchorFormat1* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    AnchorFormat1* out = c->embed<AnchorFormat1> (this);
+    if (!out) return_trace (out);
+    out->format = 1;
+    return_trace (out);
+  }
+};
+
+
+}
+}
+}
+
+#endif  // OT_LAYOUT_GPOS_ANCHORFORMAT1_HH

+ 58 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/AnchorFormat2.hh

@@ -0,0 +1,58 @@
+#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT2_HH
+#define OT_LAYOUT_GPOS_ANCHORFORMAT2_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct AnchorFormat2
+{
+
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 2 */
+  FWORD         xCoordinate;            /* Horizontal value--in design units */
+  FWORD         yCoordinate;            /* Vertical value--in design units */
+  HBUINT16      anchorPoint;            /* Index to glyph contour point */
+  public:
+  DEFINE_SIZE_STATIC (8);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this));
+  }
+
+  void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id,
+                   float *x, float *y) const
+  {
+    hb_font_t *font = c->font;
+
+#ifdef HB_NO_HINTING
+    *x = font->em_fscale_x (xCoordinate);
+    *y = font->em_fscale_y (yCoordinate);
+    return;
+#endif
+
+    unsigned int x_ppem = font->x_ppem;
+    unsigned int y_ppem = font->y_ppem;
+    hb_position_t cx = 0, cy = 0;
+    bool ret;
+
+    ret = (x_ppem || y_ppem) &&
+          font->get_glyph_contour_point_for_origin (glyph_id, anchorPoint, HB_DIRECTION_LTR, &cx, &cy);
+    *x = ret && x_ppem ? cx : font->em_fscale_x (xCoordinate);
+    *y = ret && y_ppem ? cy : font->em_fscale_y (yCoordinate);
+  }
+
+  AnchorFormat2* copy (hb_serialize_context_t *c) const
+  {
+    TRACE_SERIALIZE (this);
+    return_trace (c->embed<AnchorFormat2> (this));
+  }
+};
+
+}
+}
+}
+
+#endif  // OT_LAYOUT_GPOS_ANCHORFORMAT2_HH

+ 120 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/AnchorFormat3.hh

@@ -0,0 +1,120 @@
+#ifndef OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
+#define OT_LAYOUT_GPOS_ANCHORFORMAT3_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct AnchorFormat3
+{
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 3 */
+  FWORD         xCoordinate;            /* Horizontal value--in design units */
+  FWORD         yCoordinate;            /* Vertical value--in design units */
+  Offset16To<Device>
+                xDeviceTable;           /* Offset to Device table for X
+                                         * coordinate-- from beginning of
+                                         * Anchor table (may be NULL) */
+  Offset16To<Device>
+                yDeviceTable;           /* Offset to Device table for Y
+                                         * coordinate-- from beginning of
+                                         * Anchor table (may be NULL) */
+  public:
+  DEFINE_SIZE_STATIC (10);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!c->check_struct (this))) return_trace (false);
+
+    return_trace (xDeviceTable.sanitize (c, this) && yDeviceTable.sanitize (c, this));
+  }
+
+  void get_anchor (hb_ot_apply_context_t *c, hb_codepoint_t glyph_id HB_UNUSED,
+                   float *x, float *y) const
+  {
+    hb_font_t *font = c->font;
+    *x = font->em_fscale_x (xCoordinate);
+    *y = font->em_fscale_y (yCoordinate);
+
+    if ((font->x_ppem || font->num_coords) && xDeviceTable.sanitize (&c->sanitizer, this))
+    {
+      hb_barrier ();
+      *x += (this+xDeviceTable).get_x_delta (font, c->var_store, c->var_store_cache);
+    }
+    if ((font->y_ppem || font->num_coords) && yDeviceTable.sanitize (&c->sanitizer, this))
+    {
+      hb_barrier ();
+      *y += (this+yDeviceTable).get_y_delta (font, c->var_store, c->var_store_cache);
+    }
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->embed (format))) return_trace (false);
+    if (unlikely (!c->serializer->embed (xCoordinate))) return_trace (false);
+    if (unlikely (!c->serializer->embed (yCoordinate))) return_trace (false);
+
+    unsigned x_varidx = xDeviceTable ? (this+xDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
+    if (x_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
+    {
+      hb_pair_t<unsigned, int> *new_varidx_delta;
+      if (!c->plan->layout_variation_idx_delta_map.has (x_varidx, &new_varidx_delta))
+        return_trace (false);
+     
+      x_varidx = hb_first (*new_varidx_delta);
+      int delta = hb_second (*new_varidx_delta);
+      if (delta != 0)
+      {
+        if (!c->serializer->check_assign (out->xCoordinate, xCoordinate + delta,
+                                          HB_SERIALIZE_ERROR_INT_OVERFLOW))
+          return_trace (false);
+      }
+    }
+
+    unsigned y_varidx = yDeviceTable ? (this+yDeviceTable).get_variation_index () : HB_OT_LAYOUT_NO_VARIATIONS_INDEX;
+    if (y_varidx != HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
+    {
+      hb_pair_t<unsigned, int> *new_varidx_delta;
+      if (!c->plan->layout_variation_idx_delta_map.has (y_varidx, &new_varidx_delta))
+        return_trace (false);
+
+      y_varidx = hb_first (*new_varidx_delta);
+      int delta = hb_second (*new_varidx_delta);
+      if (delta != 0)
+      {
+        if (!c->serializer->check_assign (out->yCoordinate, yCoordinate + delta,
+                                          HB_SERIALIZE_ERROR_INT_OVERFLOW))
+          return_trace (false);
+      }
+    }
+
+    /* in case that all axes are pinned or no variations after instantiation,
+     * both var_idxes will be mapped to HB_OT_LAYOUT_NO_VARIATIONS_INDEX */
+    if (x_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX &&
+        y_varidx == HB_OT_LAYOUT_NO_VARIATIONS_INDEX)
+      return_trace (c->serializer->check_assign (out->format, 1, HB_SERIALIZE_ERROR_INT_OVERFLOW));
+
+    if (!c->serializer->embed (xDeviceTable)) return_trace (false);
+    if (!c->serializer->embed (yDeviceTable)) return_trace (false);
+
+    out->xDeviceTable.serialize_copy (c->serializer, xDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map);
+    out->yDeviceTable.serialize_copy (c->serializer, yDeviceTable, this, 0, hb_serialize_context_t::Head, &c->plan->layout_variation_idx_delta_map);
+    return_trace (out);
+  }
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    (this+xDeviceTable).collect_variation_indices (c);
+    (this+yDeviceTable).collect_variation_indices (c);
+  }
+};
+
+
+}
+}
+}
+
+#endif  // OT_LAYOUT_GPOS_ANCHORFORMAT3_HH

+ 87 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/AnchorMatrix.hh

@@ -0,0 +1,87 @@
+#ifndef OT_LAYOUT_GPOS_ANCHORMATRIX_HH
+#define OT_LAYOUT_GPOS_ANCHORMATRIX_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct AnchorMatrix
+{
+  HBUINT16      rows;                   /* Number of rows */
+  UnsizedArrayOf<Offset16To<Anchor, AnchorMatrix>>
+                matrixZ;                /* Matrix of offsets to Anchor tables--
+                                         * from beginning of AnchorMatrix table */
+  public:
+  DEFINE_SIZE_ARRAY (2, matrixZ);
+
+  bool sanitize (hb_sanitize_context_t *c, unsigned int cols) const
+  {
+    TRACE_SANITIZE (this);
+    if (!c->check_struct (this)) return_trace (false);
+    hb_barrier ();
+    if (unlikely (hb_unsigned_mul_overflows (rows, cols))) return_trace (false);
+    unsigned int count = rows * cols;
+    if (!c->check_array (matrixZ.arrayZ, count)) return_trace (false);
+
+    if (c->lazy_some_gpos)
+      return_trace (true);
+
+    hb_barrier ();
+    for (unsigned int i = 0; i < count; i++)
+      if (!matrixZ[i].sanitize (c, this)) return_trace (false);
+    return_trace (true);
+  }
+
+  const Anchor& get_anchor (hb_ot_apply_context_t *c,
+			    unsigned int row, unsigned int col,
+			    unsigned int cols, bool *found) const
+  {
+    *found = false;
+    if (unlikely (row >= rows || col >= cols)) return Null (Anchor);
+    auto &offset = matrixZ[row * cols + col];
+    if (unlikely (!offset.sanitize (&c->sanitizer, this))) return Null (Anchor);
+    hb_barrier ();
+    *found = !offset.is_null ();
+    return this+offset;
+  }
+
+  template <typename Iterator,
+            hb_requires (hb_is_iterator (Iterator))>
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+                                  Iterator index_iter) const
+  {
+    for (unsigned i : index_iter)
+      (this+matrixZ[i]).collect_variation_indices (c);
+  }
+
+  template <typename Iterator,
+      hb_requires (hb_is_iterator (Iterator))>
+  bool subset (hb_subset_context_t *c,
+               unsigned             num_rows,
+               Iterator             index_iter) const
+  {
+    TRACE_SUBSET (this);
+
+    auto *out = c->serializer->start_embed (this);
+
+    if (!index_iter) return_trace (false);
+    if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
+
+    out->rows = num_rows;
+    for (const unsigned i : index_iter)
+    {
+      auto *offset = c->serializer->embed (matrixZ[i]);
+      if (!offset) return_trace (false);
+      offset->serialize_subset (c, matrixZ[i], this);
+    }
+
+    return_trace (true);
+  }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_ANCHORMATRIX_HH */

+ 14 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/ChainContextPos.hh

@@ -0,0 +1,14 @@
+#ifndef OT_LAYOUT_GPOS_CHAINCONTEXTPOS_HH
+#define OT_LAYOUT_GPOS_CHAINCONTEXTPOS_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct ChainContextPos : ChainContext {};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_CHAINCONTEXTPOS_HH */

+ 33 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/Common.hh

@@ -0,0 +1,33 @@
+#ifndef OT_LAYOUT_GPOS_COMMON_HH
+#define OT_LAYOUT_GPOS_COMMON_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+enum attach_type_t {
+  ATTACH_TYPE_NONE      = 0X00,
+
+  /* Each attachment should be either a mark or a cursive; can't be both. */
+  ATTACH_TYPE_MARK      = 0X01,
+  ATTACH_TYPE_CURSIVE   = 0X02,
+};
+
+/* buffer **position** var allocations */
+#define attach_chain() var.i16[0] /* glyph to which this attaches to, relative to current glyphs; negative for going back, positive for forward. */
+#define attach_type() var.u8[2] /* attachment type */
+/* Note! if attach_chain() is zero, the value of attach_type() is irrelevant. */
+
+template<typename Iterator, typename SrcLookup>
+static void SinglePos_serialize (hb_serialize_context_t *c,
+                                 const SrcLookup *src,
+                                 Iterator it,
+                                 const hb_hashmap_t<unsigned, hb_pair_t<unsigned, int>> *layout_variation_idx_delta_map,
+                                 unsigned new_format);
+
+
+}
+}
+}
+
+#endif  // OT_LAYOUT_GPOS_COMMON_HH

+ 14 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/ContextPos.hh

@@ -0,0 +1,14 @@
+#ifndef OT_LAYOUT_GPOS_CONTEXTPOS_HH
+#define OT_LAYOUT_GPOS_CONTEXTPOS_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct ContextPos : Context {};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_CONTEXTPOS_HH */

+ 35 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/CursivePos.hh

@@ -0,0 +1,35 @@
+#ifndef OT_LAYOUT_GPOS_CURSIVEPOS_HH
+#define OT_LAYOUT_GPOS_CURSIVEPOS_HH
+
+#include "CursivePosFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct CursivePos
+{
+  protected:
+  union {
+  HBUINT16              format;         /* Format identifier */
+  CursivePosFormat1     format1;
+  } u;
+
+  public:
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
+    TRACE_DISPATCH (this, u.format);
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    default:return_trace (c->default_return_value ());
+    }
+  }
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_CURSIVEPOS_HH */

+ 311 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/CursivePosFormat1.hh

@@ -0,0 +1,311 @@
+#ifndef OT_LAYOUT_GPOS_CURSIVEPOSFORMAT1_HH
+#define OT_LAYOUT_GPOS_CURSIVEPOSFORMAT1_HH
+
+#include "Anchor.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct EntryExitRecord
+{
+  friend struct CursivePosFormat1;
+
+  bool sanitize (hb_sanitize_context_t *c, const struct CursivePosFormat1 *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (entryAnchor.sanitize (c, base) && exitAnchor.sanitize (c, base));
+  }
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+                                  const struct CursivePosFormat1 *src_base) const
+  {
+    (src_base+entryAnchor).collect_variation_indices (c);
+    (src_base+exitAnchor).collect_variation_indices (c);
+  }
+
+  bool subset (hb_subset_context_t *c,
+	       const struct CursivePosFormat1 *src_base) const
+  {
+    TRACE_SERIALIZE (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    bool ret = false;
+    ret |= out->entryAnchor.serialize_subset (c, entryAnchor, src_base);
+    ret |= out->exitAnchor.serialize_subset (c, exitAnchor, src_base);
+    return_trace (ret);
+  }
+
+  protected:
+  Offset16To<Anchor, struct CursivePosFormat1>
+                entryAnchor;            /* Offset to EntryAnchor table--from
+                                         * beginning of CursivePos
+                                         * subtable--may be NULL */
+  Offset16To<Anchor, struct CursivePosFormat1>
+                exitAnchor;             /* Offset to ExitAnchor table--from
+                                         * beginning of CursivePos
+                                         * subtable--may be NULL */
+  public:
+  DEFINE_SIZE_STATIC (4);
+};
+
+static void
+reverse_cursive_minor_offset (hb_glyph_position_t *pos, unsigned int i, hb_direction_t direction, unsigned int new_parent) {
+  int chain = pos[i].attach_chain(), type = pos[i].attach_type();
+  if (likely (!chain || 0 == (type & ATTACH_TYPE_CURSIVE)))
+    return;
+
+  pos[i].attach_chain() = 0;
+
+  unsigned int j = (int) i + chain;
+
+  /* Stop if we see new parent in the chain. */
+  if (j == new_parent)
+    return;
+
+  reverse_cursive_minor_offset (pos, j, direction, new_parent);
+
+  if (HB_DIRECTION_IS_HORIZONTAL (direction))
+    pos[j].y_offset = -pos[i].y_offset;
+  else
+    pos[j].x_offset = -pos[i].x_offset;
+
+  pos[j].attach_chain() = -chain;
+  pos[j].attach_type() = type;
+}
+
+
+struct CursivePosFormat1
+{
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 1 */
+  Offset16To<Coverage>
+                coverage;               /* Offset to Coverage table--from
+                                         * beginning of subtable */
+  Array16Of<EntryExitRecord>
+                entryExitRecord;        /* Array of EntryExit records--in
+                                         * Coverage Index order */
+  public:
+  DEFINE_SIZE_ARRAY (6, entryExitRecord);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    if (unlikely (!coverage.sanitize (c, this)))
+      return_trace (false);
+
+    if (c->lazy_some_gpos)
+      return_trace (entryExitRecord.sanitize_shallow (c));
+    else
+      return_trace (entryExitRecord.sanitize (c, this));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  { return (this+coverage).intersects (glyphs); }
+
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    + hb_zip (this+coverage, entryExitRecord)
+    | hb_filter (c->glyph_set, hb_first)
+    | hb_map (hb_second)
+    | hb_apply ([&] (const EntryExitRecord& record) { record.collect_variation_indices (c, this); })
+    ;
+  }
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  { if (unlikely (!(this+coverage).collect_coverage (c->input))) return; }
+
+  const Coverage &get_coverage () const { return this+coverage; }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
+
+    const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage  (buffer->cur().codepoint)];
+    if (!this_record.entryAnchor ||
+	unlikely (!this_record.entryAnchor.sanitize (&c->sanitizer, this))) return_trace (false);
+    hb_barrier ();
+
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    skippy_iter.reset_fast (buffer->idx);
+    unsigned unsafe_from;
+    if (unlikely (!skippy_iter.prev (&unsafe_from)))
+    {
+      buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
+      return_trace (false);
+    }
+
+    const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage  (buffer->info[skippy_iter.idx].codepoint)];
+    if (!prev_record.exitAnchor ||
+	unlikely (!prev_record.exitAnchor.sanitize (&c->sanitizer, this)))
+    {
+      buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+      return_trace (false);
+    }
+    hb_barrier ();
+
+    unsigned int i = skippy_iter.idx;
+    unsigned int j = buffer->idx;
+
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "cursive attaching glyph at %u to glyph at %u",
+			  i, j);
+    }
+
+    buffer->unsafe_to_break (i, j + 1);
+    float entry_x, entry_y, exit_x, exit_y;
+    (this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
+    (this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
+
+    hb_glyph_position_t *pos = buffer->pos;
+
+    hb_position_t d;
+    /* Main-direction adjustment */
+    switch (c->direction) {
+      case HB_DIRECTION_LTR:
+        pos[i].x_advance  = roundf (exit_x) + pos[i].x_offset;
+
+        d = roundf (entry_x) + pos[j].x_offset;
+        pos[j].x_advance -= d;
+        pos[j].x_offset  -= d;
+        break;
+      case HB_DIRECTION_RTL:
+        d = roundf (exit_x) + pos[i].x_offset;
+        pos[i].x_advance -= d;
+        pos[i].x_offset  -= d;
+
+        pos[j].x_advance  = roundf (entry_x) + pos[j].x_offset;
+        break;
+      case HB_DIRECTION_TTB:
+        pos[i].y_advance  = roundf (exit_y) + pos[i].y_offset;
+
+        d = roundf (entry_y) + pos[j].y_offset;
+        pos[j].y_advance -= d;
+        pos[j].y_offset  -= d;
+        break;
+      case HB_DIRECTION_BTT:
+        d = roundf (exit_y) + pos[i].y_offset;
+        pos[i].y_advance -= d;
+        pos[i].y_offset  -= d;
+
+        pos[j].y_advance  = roundf (entry_y);
+        break;
+      case HB_DIRECTION_INVALID:
+      default:
+        break;
+    }
+
+    /* Cross-direction adjustment */
+
+    /* We attach child to parent (think graph theory and rooted trees whereas
+     * the root stays on baseline and each node aligns itself against its
+     * parent.
+     *
+     * Optimize things for the case of RightToLeft, as that's most common in
+     * Arabic. */
+    unsigned int child  = i;
+    unsigned int parent = j;
+    hb_position_t x_offset = roundf (entry_x - exit_x);
+    hb_position_t y_offset = roundf (entry_y - exit_y);
+    if  (!(c->lookup_props & LookupFlag::RightToLeft))
+    {
+      unsigned int k = child;
+      child = parent;
+      parent = k;
+      x_offset = -x_offset;
+      y_offset = -y_offset;
+    }
+
+    /* If child was already connected to someone else, walk through its old
+     * chain and reverse the link direction, such that the whole tree of its
+     * previous connection now attaches to new parent.  Watch out for case
+     * where new parent is on the path from old chain...
+     */
+    reverse_cursive_minor_offset (pos, child, c->direction, parent);
+
+    pos[child].attach_type() = ATTACH_TYPE_CURSIVE;
+    pos[child].attach_chain() = (int) parent - (int) child;
+    buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
+    if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
+      pos[child].y_offset = y_offset;
+    else
+      pos[child].x_offset = x_offset;
+
+    /* If parent was attached to child, separate them.
+     * https://github.com/harfbuzz/harfbuzz/issues/2469
+     */
+    if (unlikely (pos[parent].attach_chain() == -pos[child].attach_chain()))
+    {
+      pos[parent].attach_chain() = 0;
+      if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
+	pos[parent].y_offset = 0;
+      else
+	pos[parent].x_offset = 0;
+    }
+
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "cursive attached glyph at %u to glyph at %u",
+			  i, j);
+    }
+
+    buffer->idx++;
+    return_trace (true);
+  }
+
+  template <typename Iterator,
+            hb_requires (hb_is_iterator (Iterator))>
+  void serialize (hb_subset_context_t *c,
+                  Iterator it,
+                  const struct CursivePosFormat1 *src_base)
+  {
+    if (unlikely (!c->serializer->extend_min ((*this)))) return;
+    this->format = 1;
+    this->entryExitRecord.len = it.len ();
+
+    for (const EntryExitRecord& entry_record : + it
+                                               | hb_map (hb_second))
+      entry_record.subset (c, src_base);
+
+    auto glyphs =
+    + it
+    | hb_map_retains_sorting (hb_first)
+    ;
+
+    coverage.serialize_serialize (c->serializer, glyphs);
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+
+    auto it =
+    + hb_zip (this+coverage, entryExitRecord)
+    | hb_filter (glyphset, hb_first)
+    | hb_map_retains_sorting ([&] (hb_pair_t<hb_codepoint_t, const EntryExitRecord&> p) -> hb_pair_t<hb_codepoint_t, const EntryExitRecord&>
+                              { return hb_pair (glyph_map[p.first], p.second);})
+    ;
+
+    bool ret = bool (it);
+    out->serialize (c, it, this);
+    return_trace (ret);
+  }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_CURSIVEPOSFORMAT1_HH */

+ 17 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/ExtensionPos.hh

@@ -0,0 +1,17 @@
+#ifndef OT_LAYOUT_GPOS_EXTENSIONPOS_HH
+#define OT_LAYOUT_GPOS_EXTENSIONPOS_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct ExtensionPos : Extension<ExtensionPos>
+{
+  typedef struct PosLookupSubTable SubTable;
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_EXTENSIONPOS_HH */

+ 171 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/GPOS.hh

@@ -0,0 +1,171 @@
+#ifndef OT_LAYOUT_GPOS_GPOS_HH
+#define OT_LAYOUT_GPOS_GPOS_HH
+
+#include "../../../hb-ot-layout-common.hh"
+#include "../../../hb-ot-layout-gsubgpos.hh"
+#include "Common.hh"
+#include "PosLookup.hh"
+
+namespace OT {
+
+using Layout::GPOS_impl::PosLookup;
+
+namespace Layout {
+
+static void
+propagate_attachment_offsets (hb_glyph_position_t *pos,
+                              unsigned int len,
+                              unsigned int i,
+                              hb_direction_t direction,
+                              unsigned nesting_level = HB_MAX_NESTING_LEVEL);
+
+/*
+ * GPOS -- Glyph Positioning
+ * https://docs.microsoft.com/en-us/typography/opentype/spec/gpos
+ */
+
+struct GPOS : GSUBGPOS
+{
+  static constexpr hb_tag_t tableTag = HB_OT_TAG_GPOS;
+
+  using Lookup = PosLookup;
+
+  const PosLookup& get_lookup (unsigned int i) const
+  { return static_cast<const PosLookup &> (GSUBGPOS::get_lookup (i)); }
+
+  static inline void position_start (hb_font_t *font, hb_buffer_t *buffer);
+  static inline void position_finish_advances (hb_font_t *font, hb_buffer_t *buffer);
+  static inline void position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer);
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    hb_subset_layout_context_t l (c, tableTag);
+    return GSUBGPOS::subset<PosLookup> (&l);
+  }
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (GSUBGPOS::sanitize<PosLookup> (c));
+  }
+
+  HB_INTERNAL bool is_blocklisted (hb_blob_t *blob,
+                                   hb_face_t *face) const;
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    for (unsigned i = 0; i < GSUBGPOS::get_lookup_count (); i++)
+    {
+      if (!c->gpos_lookups->has (i)) continue;
+      const PosLookup &l = get_lookup (i);
+      l.dispatch (c);
+    }
+  }
+
+  void closure_lookups (hb_face_t      *face,
+                        const hb_set_t *glyphs,
+                        hb_set_t       *lookup_indexes /* IN/OUT */) const
+  { GSUBGPOS::closure_lookups<PosLookup> (face, glyphs, lookup_indexes); }
+
+  typedef GSUBGPOS::accelerator_t<GPOS> accelerator_t;
+};
+
+
+static void
+propagate_attachment_offsets (hb_glyph_position_t *pos,
+                              unsigned int len,
+                              unsigned int i,
+                              hb_direction_t direction,
+                              unsigned nesting_level)
+{
+  /* Adjusts offsets of attached glyphs (both cursive and mark) to accumulate
+   * offset of glyph they are attached to. */
+  int chain = pos[i].attach_chain(), type = pos[i].attach_type();
+  if (likely (!chain))
+    return;
+
+  pos[i].attach_chain() = 0;
+
+  unsigned int j = (int) i + chain;
+
+  if (unlikely (j >= len))
+    return;
+
+  if (unlikely (!nesting_level))
+    return;
+
+  propagate_attachment_offsets (pos, len, j, direction, nesting_level - 1);
+
+  assert (!!(type & GPOS_impl::ATTACH_TYPE_MARK) ^ !!(type & GPOS_impl::ATTACH_TYPE_CURSIVE));
+
+  if (type & GPOS_impl::ATTACH_TYPE_CURSIVE)
+  {
+    if (HB_DIRECTION_IS_HORIZONTAL (direction))
+      pos[i].y_offset += pos[j].y_offset;
+    else
+      pos[i].x_offset += pos[j].x_offset;
+  }
+  else /*if (type & GPOS_impl::ATTACH_TYPE_MARK)*/
+  {
+    pos[i].x_offset += pos[j].x_offset;
+    pos[i].y_offset += pos[j].y_offset;
+
+    assert (j < i);
+    if (HB_DIRECTION_IS_FORWARD (direction))
+      for (unsigned int k = j; k < i; k++) {
+        pos[i].x_offset -= pos[k].x_advance;
+        pos[i].y_offset -= pos[k].y_advance;
+      }
+    else
+      for (unsigned int k = j + 1; k < i + 1; k++) {
+        pos[i].x_offset += pos[k].x_advance;
+        pos[i].y_offset += pos[k].y_advance;
+      }
+  }
+}
+
+void
+GPOS::position_start (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer)
+{
+  unsigned int count = buffer->len;
+  for (unsigned int i = 0; i < count; i++)
+    buffer->pos[i].attach_chain() = buffer->pos[i].attach_type() = 0;
+}
+
+void
+GPOS::position_finish_advances (hb_font_t *font HB_UNUSED, hb_buffer_t *buffer HB_UNUSED)
+{
+  //_hb_buffer_assert_gsubgpos_vars (buffer);
+}
+
+void
+GPOS::position_finish_offsets (hb_font_t *font, hb_buffer_t *buffer)
+{
+  _hb_buffer_assert_gsubgpos_vars (buffer);
+
+  unsigned int len;
+  hb_glyph_position_t *pos = hb_buffer_get_glyph_positions (buffer, &len);
+  hb_direction_t direction = buffer->props.direction;
+
+  /* Handle attachments */
+  if (buffer->scratch_flags & HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT)
+    for (unsigned i = 0; i < len; i++)
+      propagate_attachment_offsets (pos, len, i, direction);
+
+  if (unlikely (font->slant))
+  {
+    for (unsigned i = 0; i < len; i++)
+      if (unlikely (pos[i].y_offset))
+        pos[i].x_offset += roundf (font->slant_xy * pos[i].y_offset);
+  }
+}
+
+}
+
+struct GPOS_accelerator_t : Layout::GPOS::accelerator_t {
+  GPOS_accelerator_t (hb_face_t *face) : Layout::GPOS::accelerator_t (face) {}
+};
+
+}
+
+#endif  /* OT_LAYOUT_GPOS_GPOS_HH */

+ 57 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/LigatureArray.hh

@@ -0,0 +1,57 @@
+#ifndef OT_LAYOUT_GPOS_LIGATUREARRAY_HH
+#define OT_LAYOUT_GPOS_LIGATUREARRAY_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+
+typedef AnchorMatrix LigatureAttach;    /* component-major--
+                                         * in order of writing direction--,
+                                         * mark-minor--
+                                         * ordered by class--zero-based. */
+
+/* Array of LigatureAttach tables ordered by LigatureCoverage Index */
+struct LigatureArray : List16OfOffset16To<LigatureAttach>
+{
+  template <typename Iterator,
+            hb_requires (hb_is_iterator (Iterator))>
+  bool subset (hb_subset_context_t *c,
+               Iterator             coverage,
+               unsigned             class_count,
+               const hb_map_t      *klass_mapping) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+
+    auto *out = c->serializer->start_embed (this);
+    if (unlikely (!c->serializer->extend_min (out)))  return_trace (false);
+
+    bool ret = false;
+    for (const auto _ : + hb_zip (coverage, *this)
+                  | hb_filter (glyphset, hb_first))
+    {
+      auto *matrix = out->serialize_append (c->serializer);
+      if (unlikely (!matrix)) return_trace (false);
+
+      const LigatureAttach& src = (this + _.second);
+      auto indexes =
+          + hb_range (src.rows * class_count)
+          | hb_filter ([=] (unsigned index) { return klass_mapping->has (index % class_count); })
+          ;
+      ret |= matrix->serialize_subset (c,
+				       _.second,
+				       this,
+				       src.rows,
+				       indexes);
+    }
+    return_trace (ret);
+  }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_LIGATUREARRAY_HH */

+ 128 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkArray.hh

@@ -0,0 +1,128 @@
+#ifndef OT_LAYOUT_GPOS_MARKARRAY_HH
+#define OT_LAYOUT_GPOS_MARKARRAY_HH
+
+#include "AnchorMatrix.hh"
+#include "MarkRecord.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct MarkArray : Array16Of<MarkRecord>        /* Array of MarkRecords--in Coverage order */
+{
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (Array16Of<MarkRecord>::sanitize (c, this));
+  }
+
+  bool apply (hb_ot_apply_context_t *c,
+              unsigned int mark_index, unsigned int glyph_index,
+              const AnchorMatrix &anchors, unsigned int class_count,
+              unsigned int glyph_pos) const
+  {
+    TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
+    const MarkRecord &record = Array16Of<MarkRecord>::operator[](mark_index);
+    unsigned int mark_class = record.klass;
+
+    const Anchor& mark_anchor = this + record.markAnchor;
+    bool found;
+    const Anchor& glyph_anchor = anchors.get_anchor (c, glyph_index, mark_class, class_count, &found);
+    /* If this subtable doesn't have an anchor for this base and this class,
+     * return false such that the subsequent subtables have a chance at it. */
+    if (unlikely (!found)) return_trace (false);
+
+    float mark_x, mark_y, base_x, base_y;
+
+    buffer->unsafe_to_break (glyph_pos, buffer->idx + 1);
+    mark_anchor.get_anchor (c, buffer->cur().codepoint, &mark_x, &mark_y);
+    glyph_anchor.get_anchor (c, buffer->info[glyph_pos].codepoint, &base_x, &base_y);
+
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "attaching mark glyph at %u to glyph at %u",
+			  c->buffer->idx, glyph_pos);
+    }
+
+    hb_glyph_position_t &o = buffer->cur_pos();
+    o.x_offset = roundf (base_x - mark_x);
+    o.y_offset = roundf (base_y - mark_y);
+    o.attach_type() = ATTACH_TYPE_MARK;
+    o.attach_chain() = (int) glyph_pos - (int) buffer->idx;
+    buffer->scratch_flags |= HB_BUFFER_SCRATCH_FLAG_HAS_GPOS_ATTACHMENT;
+
+    if (HB_BUFFER_MESSAGE_MORE && c->buffer->messaging ())
+    {
+      c->buffer->message (c->font,
+			  "attached mark glyph at %u to glyph at %u",
+			  c->buffer->idx, glyph_pos);
+    }
+
+    buffer->idx++;
+    return_trace (true);
+  }
+
+  template <typename Iterator,
+      hb_requires (hb_is_iterator (Iterator))>
+  bool subset (hb_subset_context_t *c,
+               Iterator             coverage,
+               const hb_map_t      *klass_mapping) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+
+    auto* out = c->serializer->start_embed (this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+
+    auto mark_iter =
+    + hb_zip (coverage, this->iter ())
+    | hb_filter (glyphset, hb_first)
+    | hb_map (hb_second)
+    ;
+
+    bool ret = false;
+    unsigned new_length = 0;
+    for (const auto& mark_record : mark_iter) {
+      ret |= mark_record.subset (c, this, klass_mapping);
+      new_length++;
+    }
+
+    if (unlikely (!c->serializer->check_assign (out->len, new_length,
+                                                HB_SERIALIZE_ERROR_ARRAY_OVERFLOW)))
+      return_trace (false);
+
+    return_trace (ret);
+  }
+};
+
+HB_INTERNAL inline
+void Markclass_closure_and_remap_indexes (const Coverage  &mark_coverage,
+                                          const MarkArray &mark_array,
+                                          const hb_set_t  &glyphset,
+                                          hb_map_t*        klass_mapping /* INOUT */)
+{
+  hb_set_t orig_classes;
+
+  + hb_zip (mark_coverage, mark_array)
+  | hb_filter (glyphset, hb_first)
+  | hb_map (hb_second)
+  | hb_map (&MarkRecord::get_class)
+  | hb_sink (orig_classes)
+  ;
+
+  unsigned idx = 0;
+  for (auto klass : orig_classes.iter ())
+  {
+    if (klass_mapping->has (klass)) continue;
+    klass_mapping->set (klass, idx);
+    idx++;
+  }
+}
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKARRAY_HH */

+ 41 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkBasePos.hh

@@ -0,0 +1,41 @@
+#ifndef OT_LAYOUT_GPOS_MARKBASEPOS_HH
+#define OT_LAYOUT_GPOS_MARKBASEPOS_HH
+
+#include "MarkBasePosFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct MarkBasePos
+{
+  protected:
+  union {
+  HBUINT16				format;         /* Format identifier */
+  MarkBasePosFormat1_2<SmallTypes>	format1;
+#ifndef HB_NO_BEYOND_64K
+  MarkBasePosFormat1_2<MediumTypes>	format2;
+#endif
+  } u;
+
+  public:
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
+    TRACE_DISPATCH (this, u.format);
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BEYOND_64K
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#endif
+    default:return_trace (c->default_return_value ());
+    }
+  }
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKBASEPOS_HH */

+ 243 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkBasePosFormat1.hh

@@ -0,0 +1,243 @@
+#ifndef OT_LAYOUT_GPOS_MARKBASEPOSFORMAT1_HH
+#define OT_LAYOUT_GPOS_MARKBASEPOSFORMAT1_HH
+
+#include "MarkArray.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+typedef AnchorMatrix BaseArray;         /* base-major--
+                                         * in order of BaseCoverage Index--,
+                                         * mark-minor--
+                                         * ordered by class--zero-based. */
+
+template <typename Types>
+struct MarkBasePosFormat1_2
+{
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 1 */
+  typename Types::template OffsetTo<Coverage>
+                markCoverage;           /* Offset to MarkCoverage table--from
+                                         * beginning of MarkBasePos subtable */
+  typename Types::template OffsetTo<Coverage>
+                baseCoverage;           /* Offset to BaseCoverage table--from
+                                         * beginning of MarkBasePos subtable */
+  HBUINT16      classCount;             /* Number of classes defined for marks */
+  typename Types::template OffsetTo<MarkArray>
+                markArray;              /* Offset to MarkArray table--from
+                                         * beginning of MarkBasePos subtable */
+  typename Types::template OffsetTo<BaseArray>
+                baseArray;              /* Offset to BaseArray table--from
+                                         * beginning of MarkBasePos subtable */
+
+  public:
+  DEFINE_SIZE_STATIC (4 + 4 * Types::size);
+
+    bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  markCoverage.sanitize (c, this) &&
+                  baseCoverage.sanitize (c, this) &&
+                  markArray.sanitize (c, this) &&
+                  baseArray.sanitize (c, this, (unsigned int) classCount));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  {
+    return (this+markCoverage).intersects (glyphs) &&
+           (this+baseCoverage).intersects (glyphs);
+  }
+
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    + hb_zip (this+markCoverage, this+markArray)
+    | hb_filter (c->glyph_set, hb_first)
+    | hb_map (hb_second)
+    | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+markArray)); })
+    ;
+
+    hb_map_t klass_mapping;
+    Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, *c->glyph_set, &klass_mapping);
+
+    unsigned basecount = (this+baseArray).rows;
+    auto base_iter =
+    + hb_zip (this+baseCoverage, hb_range (basecount))
+    | hb_filter (c->glyph_set, hb_first)
+    | hb_map (hb_second)
+    ;
+
+    hb_sorted_vector_t<unsigned> base_indexes;
+    for (const unsigned row : base_iter)
+    {
+      + hb_range ((unsigned) classCount)
+      | hb_filter (klass_mapping)
+      | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+      | hb_sink (base_indexes)
+      ;
+    }
+    (this+baseArray).collect_variation_indices (c, base_indexes.iter ());
+  }
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return;
+    if (unlikely (!(this+baseCoverage).collect_coverage (c->input))) return;
+  }
+
+  const Coverage &get_coverage () const { return this+markCoverage; }
+
+  static inline bool accept (hb_buffer_t *buffer, unsigned idx)
+  {
+    /* 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 */
+    return !_hb_glyph_info_multiplied (&buffer->info[idx]) ||
+	   0 == _hb_glyph_info_get_lig_comp (&buffer->info[idx]) ||
+	   (idx == 0 ||
+	    _hb_glyph_info_is_mark (&buffer->info[idx - 1]) ||
+	    !_hb_glyph_info_multiplied (&buffer->info[idx - 1]) ||
+	    _hb_glyph_info_get_lig_id (&buffer->info[idx]) !=
+	    _hb_glyph_info_get_lig_id (&buffer->info[idx - 1]) ||
+	    _hb_glyph_info_get_lig_comp (&buffer->info[idx]) !=
+	    _hb_glyph_info_get_lig_comp (&buffer->info[idx - 1]) + 1
+	    );
+  }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
+    unsigned int mark_index = (this+markCoverage).get_coverage  (buffer->cur().codepoint);
+    if (likely (mark_index == NOT_COVERED)) return_trace (false);
+
+    /* Now we search backwards for a non-mark glyph.
+     * We don't use skippy_iter.prev() to avoid O(n^2) behavior. */
+
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
+
+    if (c->last_base_until > buffer->idx)
+    {
+      c->last_base_until = 0;
+      c->last_base = -1;
+    }
+    unsigned j;
+    for (j = buffer->idx; j > c->last_base_until; j--)
+    {
+      auto match = skippy_iter.match (buffer->info[j - 1]);
+      if (match == skippy_iter.MATCH)
+      {
+        // https://github.com/harfbuzz/harfbuzz/issues/4124
+	if (!accept (buffer, j - 1) &&
+	    NOT_COVERED == (this+baseCoverage).get_coverage  (buffer->info[j - 1].codepoint))
+	  match = skippy_iter.SKIP;
+      }
+      if (match == skippy_iter.MATCH)
+      {
+	c->last_base = (signed) j - 1;
+	break;
+      }
+    }
+    c->last_base_until = buffer->idx;
+    if (c->last_base == -1)
+    {
+      buffer->unsafe_to_concat_from_outbuffer (0, buffer->idx + 1);
+      return_trace (false);
+    }
+
+    unsigned idx = (unsigned) c->last_base;
+
+    /* Checking that matched glyph is actually a base glyph by GDEF is too strong; disabled */
+    //if (!_hb_glyph_info_is_base_glyph (&buffer->info[idx])) { return_trace (false); }
+
+    unsigned int base_index = (this+baseCoverage).get_coverage  (buffer->info[idx].codepoint);
+    if (base_index == NOT_COVERED)
+    {
+      buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
+      return_trace (false);
+    }
+
+    return_trace ((this+markArray).apply (c, mark_index, base_index, this+baseArray, classCount, idx));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->format = format;
+
+    hb_map_t klass_mapping;
+    Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
+
+    if (!klass_mapping.get_population ()) return_trace (false);
+    out->classCount = klass_mapping.get_population ();
+
+    auto mark_iter =
+    + hb_zip (this+markCoverage, this+markArray)
+    | hb_filter (glyphset, hb_first)
+    ;
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + mark_iter
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    if (!out->markCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
+      return_trace (false);
+
+    if (unlikely (!out->markArray.serialize_subset (c, markArray, this,
+						    (this+markCoverage).iter (),
+						    &klass_mapping)))
+      return_trace (false);
+
+    unsigned basecount = (this+baseArray).rows;
+    auto base_iter =
+    + hb_zip (this+baseCoverage, hb_range (basecount))
+    | hb_filter (glyphset, hb_first)
+    ;
+
+    new_coverage.reset ();
+    + base_iter
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    if (!out->baseCoverage.serialize_serialize (c->serializer, new_coverage.iter ()))
+      return_trace (false);
+
+    hb_sorted_vector_t<unsigned> base_indexes;
+    for (const unsigned row : + base_iter
+                              | hb_map (hb_second))
+    {
+      + hb_range ((unsigned) classCount)
+      | hb_filter (klass_mapping)
+      | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+      | hb_sink (base_indexes)
+      ;
+    }
+
+    return_trace (out->baseArray.serialize_subset (c, baseArray, this,
+						   base_iter.len (),
+						   base_indexes.iter ()));
+  }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKBASEPOSFORMAT1_HH */

+ 41 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkLigPos.hh

@@ -0,0 +1,41 @@
+#ifndef OT_LAYOUT_GPOS_MARKLIGPOS_HH
+#define OT_LAYOUT_GPOS_MARKLIGPOS_HH
+
+#include "MarkLigPosFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct MarkLigPos
+{
+  protected:
+  union {
+  HBUINT16				format;         /* Format identifier */
+  MarkLigPosFormat1_2<SmallTypes>	format1;
+#ifndef HB_NO_BEYOND_64K
+  MarkLigPosFormat1_2<MediumTypes>	format2;
+#endif
+  } u;
+
+  public:
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
+    TRACE_DISPATCH (this, u.format);
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BEYOND_64K
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#endif
+    default:return_trace (c->default_return_value ());
+    }
+  }
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKLIGPOS_HH */

+ 224 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkLigPosFormat1.hh

@@ -0,0 +1,224 @@
+#ifndef OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH
+#define OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH
+
+#include "LigatureArray.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+
+template <typename Types>
+struct MarkLigPosFormat1_2
+{
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 1 */
+  typename Types::template OffsetTo<Coverage>
+                markCoverage;           /* Offset to Mark Coverage table--from
+                                         * beginning of MarkLigPos subtable */
+  typename Types::template OffsetTo<Coverage>
+                ligatureCoverage;       /* Offset to Ligature Coverage
+                                         * table--from beginning of MarkLigPos
+                                         * subtable */
+  HBUINT16      classCount;             /* Number of defined mark classes */
+  typename Types::template OffsetTo<MarkArray>
+                markArray;              /* Offset to MarkArray table--from
+                                         * beginning of MarkLigPos subtable */
+  typename Types::template OffsetTo<LigatureArray>
+                ligatureArray;          /* Offset to LigatureArray table--from
+                                         * beginning of MarkLigPos subtable */
+  public:
+  DEFINE_SIZE_STATIC (4 + 4 * Types::size);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  markCoverage.sanitize (c, this) &&
+                  ligatureCoverage.sanitize (c, this) &&
+                  markArray.sanitize (c, this) &&
+                  ligatureArray.sanitize (c, this, (unsigned int) classCount));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  {
+    return (this+markCoverage).intersects (glyphs) &&
+           (this+ligatureCoverage).intersects (glyphs);
+  }
+
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    + hb_zip (this+markCoverage, this+markArray)
+    | hb_filter (c->glyph_set, hb_first)
+    | hb_map (hb_second)
+    | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+markArray)); })
+    ;
+
+    hb_map_t klass_mapping;
+    Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, *c->glyph_set, &klass_mapping);
+
+    unsigned ligcount = (this+ligatureArray).len;
+    auto lig_iter =
+    + hb_zip (this+ligatureCoverage, hb_range (ligcount))
+    | hb_filter (c->glyph_set, hb_first)
+    | hb_map (hb_second)
+    ;
+
+    const LigatureArray& lig_array = this+ligatureArray;
+    for (const unsigned i : lig_iter)
+    {
+      hb_sorted_vector_t<unsigned> lig_indexes;
+      unsigned row_count = lig_array[i].rows;
+      for (unsigned row : + hb_range (row_count))
+      {
+        + hb_range ((unsigned) classCount)
+        | hb_filter (klass_mapping)
+        | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+        | hb_sink (lig_indexes)
+        ;
+      }
+
+      lig_array[i].collect_variation_indices (c, lig_indexes.iter ());
+    }
+  }
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    if (unlikely (!(this+markCoverage).collect_coverage (c->input))) return;
+    if (unlikely (!(this+ligatureCoverage).collect_coverage (c->input))) return;
+  }
+
+  const Coverage &get_coverage () const { return this+markCoverage; }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
+    unsigned int mark_index = (this+markCoverage).get_coverage  (buffer->cur().codepoint);
+    if (likely (mark_index == NOT_COVERED)) return_trace (false);
+
+    /* Now we search backwards for a non-mark glyph */
+
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    skippy_iter.set_lookup_props (LookupFlag::IgnoreMarks);
+
+    if (c->last_base_until > buffer->idx)
+    {
+      c->last_base_until = 0;
+      c->last_base = -1;
+    }
+    unsigned j;
+    for (j = buffer->idx; j > c->last_base_until; j--)
+    {
+      auto match = skippy_iter.match (buffer->info[j - 1]);
+      if (match == skippy_iter.MATCH)
+      {
+	c->last_base = (signed) j - 1;
+	break;
+      }
+    }
+    c->last_base_until = buffer->idx;
+    if (c->last_base == -1)
+    {
+      buffer->unsafe_to_concat_from_outbuffer (0, buffer->idx + 1);
+      return_trace (false);
+    }
+
+    unsigned idx = (unsigned) c->last_base;
+
+    /* Checking that matched glyph is actually a ligature by GDEF is too strong; disabled */
+    //if (!_hb_glyph_info_is_ligature (&buffer->info[idx])) { return_trace (false); }
+
+    unsigned int lig_index = (this+ligatureCoverage).get_coverage  (buffer->info[idx].codepoint);
+    if (lig_index == NOT_COVERED)
+    {
+      buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
+      return_trace (false);
+    }
+
+    const LigatureArray& lig_array = this+ligatureArray;
+    const LigatureAttach& lig_attach = lig_array[lig_index];
+
+    /* Find component to attach to */
+    unsigned int comp_count = lig_attach.rows;
+    if (unlikely (!comp_count))
+    {
+      buffer->unsafe_to_concat_from_outbuffer (idx, buffer->idx + 1);
+      return_trace (false);
+    }
+
+    /* We must now check whether the ligature ID of the current mark glyph
+     * 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
+     * glyph to the last component of the ligature. */
+    unsigned int comp_index;
+    unsigned int lig_id = _hb_glyph_info_get_lig_id (&buffer->info[idx]);
+    unsigned int mark_id = _hb_glyph_info_get_lig_id (&buffer->cur());
+    unsigned int mark_comp = _hb_glyph_info_get_lig_comp (&buffer->cur());
+    if (lig_id && lig_id == mark_id && mark_comp > 0)
+      comp_index = hb_min (comp_count, _hb_glyph_info_get_lig_comp (&buffer->cur())) - 1;
+    else
+      comp_index = comp_count - 1;
+
+    return_trace ((this+markArray).apply (c, mark_index, comp_index, lig_attach, classCount, idx));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = c->plan->glyph_map_gsub;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->format = format;
+
+    hb_map_t klass_mapping;
+    Markclass_closure_and_remap_indexes (this+markCoverage, this+markArray, glyphset, &klass_mapping);
+
+    if (!klass_mapping.get_population ()) return_trace (false);
+    out->classCount = klass_mapping.get_population ();
+
+    auto mark_iter =
+    + hb_zip (this+markCoverage, this+markArray)
+    | hb_filter (glyphset, hb_first)
+    ;
+
+    auto new_mark_coverage =
+    + mark_iter
+    | hb_map_retains_sorting (hb_first)
+    | hb_map_retains_sorting (glyph_map)
+    ;
+
+    if (!out->markCoverage.serialize_serialize (c->serializer, new_mark_coverage))
+      return_trace (false);
+
+    if (unlikely (!out->markArray.serialize_subset (c, markArray, this,
+						    (this+markCoverage).iter (),
+						    &klass_mapping)))
+      return_trace (false);
+
+    auto new_ligature_coverage =
+    + hb_iter (this + ligatureCoverage)
+    | hb_take ((this + ligatureArray).len)
+    | hb_map_retains_sorting (glyph_map)
+    | hb_filter ([] (hb_codepoint_t glyph) { return glyph != HB_MAP_VALUE_INVALID; })
+    ;
+
+    if (!out->ligatureCoverage.serialize_serialize (c->serializer, new_ligature_coverage))
+      return_trace (false);
+
+    return_trace (out->ligatureArray.serialize_subset (c, ligatureArray, this,
+						       hb_iter (this+ligatureCoverage),
+						       classCount, &klass_mapping));
+  }
+
+};
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKLIGPOSFORMAT1_HH */

+ 42 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkMarkPos.hh

@@ -0,0 +1,42 @@
+#ifndef OT_LAYOUT_GPOS_MARKMARKPOS_HH
+#define OT_LAYOUT_GPOS_MARKMARKPOS_HH
+
+#include "MarkMarkPosFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct MarkMarkPos
+{
+  protected:
+  union {
+  HBUINT16				format;         /* Format identifier */
+  MarkMarkPosFormat1_2<SmallTypes>	format1;
+#ifndef HB_NO_BEYOND_64K
+  MarkMarkPosFormat1_2<MediumTypes>	format2;
+#endif
+  } u;
+
+  public:
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
+    TRACE_DISPATCH (this, u.format);
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BEYOND_64K
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#endif
+    default:return_trace (c->default_return_value ());
+    }
+  }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKMARKPOS_HH */

+ 231 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkMarkPosFormat1.hh

@@ -0,0 +1,231 @@
+#ifndef OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH
+#define OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH
+
+#include "MarkMarkPosFormat1.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+typedef AnchorMatrix Mark2Array;        /* mark2-major--
+                                         * in order of Mark2Coverage Index--,
+                                         * mark1-minor--
+                                         * ordered by class--zero-based. */
+
+template <typename Types>
+struct MarkMarkPosFormat1_2
+{
+  protected:
+  HBUINT16      format;                 /* Format identifier--format = 1 */
+  typename Types::template OffsetTo<Coverage>
+                mark1Coverage;          /* Offset to Combining Mark1 Coverage
+                                         * table--from beginning of MarkMarkPos
+                                         * subtable */
+  typename Types::template OffsetTo<Coverage>
+                mark2Coverage;          /* Offset to Combining Mark2 Coverage
+                                         * table--from beginning of MarkMarkPos
+                                         * subtable */
+  HBUINT16      classCount;             /* Number of defined mark classes */
+  typename Types::template OffsetTo<MarkArray>
+                mark1Array;             /* Offset to Mark1Array table--from
+                                         * beginning of MarkMarkPos subtable */
+  typename Types::template OffsetTo<Mark2Array>
+                mark2Array;             /* Offset to Mark2Array table--from
+                                         * beginning of MarkMarkPos subtable */
+  public:
+  DEFINE_SIZE_STATIC (4 + 4 * Types::size);
+
+  bool sanitize (hb_sanitize_context_t *c) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) &&
+                  mark1Coverage.sanitize (c, this) &&
+                  mark2Coverage.sanitize (c, this) &&
+                  mark1Array.sanitize (c, this) &&
+		  hb_barrier () &&
+                  mark2Array.sanitize (c, this, (unsigned int) classCount));
+  }
+
+  bool intersects (const hb_set_t *glyphs) const
+  {
+    return (this+mark1Coverage).intersects (glyphs) &&
+           (this+mark2Coverage).intersects (glyphs);
+  }
+
+  void closure_lookups (hb_closure_lookups_context_t *c) const {}
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c) const
+  {
+    + hb_zip (this+mark1Coverage, this+mark1Array)
+    | hb_filter (c->glyph_set, hb_first)
+    | hb_map (hb_second)
+    | hb_apply ([&] (const MarkRecord& record) { record.collect_variation_indices (c, &(this+mark1Array)); })
+    ;
+
+    hb_map_t klass_mapping;
+    Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, *c->glyph_set, &klass_mapping);
+
+    unsigned mark2_count = (this+mark2Array).rows;
+    auto mark2_iter =
+    + hb_zip (this+mark2Coverage, hb_range (mark2_count))
+    | hb_filter (c->glyph_set, hb_first)
+    | hb_map (hb_second)
+    ;
+
+    hb_sorted_vector_t<unsigned> mark2_indexes;
+    for (const unsigned row : mark2_iter)
+    {
+      + hb_range ((unsigned) classCount)
+      | hb_filter (klass_mapping)
+      | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+      | hb_sink (mark2_indexes)
+      ;
+    }
+    (this+mark2Array).collect_variation_indices (c, mark2_indexes.iter ());
+  }
+
+  void collect_glyphs (hb_collect_glyphs_context_t *c) const
+  {
+    if (unlikely (!(this+mark1Coverage).collect_coverage (c->input))) return;
+    if (unlikely (!(this+mark2Coverage).collect_coverage (c->input))) return;
+  }
+
+  const Coverage &get_coverage () const { return this+mark1Coverage; }
+
+  bool apply (hb_ot_apply_context_t *c) const
+  {
+    TRACE_APPLY (this);
+    hb_buffer_t *buffer = c->buffer;
+    unsigned int mark1_index = (this+mark1Coverage).get_coverage  (buffer->cur().codepoint);
+    if (likely (mark1_index == NOT_COVERED)) return_trace (false);
+
+    /* now we search backwards for a suitable mark glyph until a non-mark glyph */
+    hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
+    skippy_iter.reset_fast (buffer->idx);
+    skippy_iter.set_lookup_props (c->lookup_props & ~(uint32_t)LookupFlag::IgnoreFlags);
+    unsigned unsafe_from;
+    if (unlikely (!skippy_iter.prev (&unsafe_from)))
+    {
+      buffer->unsafe_to_concat_from_outbuffer (unsafe_from, buffer->idx + 1);
+      return_trace (false);
+    }
+
+    if (likely (!_hb_glyph_info_is_mark (&buffer->info[skippy_iter.idx])))
+    {
+      buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+      return_trace (false);
+    }
+
+    unsigned int j = skippy_iter.idx;
+
+    unsigned int id1 = _hb_glyph_info_get_lig_id (&buffer->cur());
+    unsigned int id2 = _hb_glyph_info_get_lig_id (&buffer->info[j]);
+    unsigned int comp1 = _hb_glyph_info_get_lig_comp (&buffer->cur());
+    unsigned int comp2 = _hb_glyph_info_get_lig_comp (&buffer->info[j]);
+
+    if (likely (id1 == id2))
+    {
+      if (id1 == 0) /* Marks belonging to the same base. */
+        goto good;
+      else if (comp1 == comp2) /* Marks belonging to the same ligature component. */
+        goto good;
+    }
+    else
+    {
+      /* If ligature ids don't match, it may be the case that one of the marks
+       * itself is a ligature.  In which case match. */
+      if ((id1 > 0 && !comp1) || (id2 > 0 && !comp2))
+        goto good;
+    }
+
+    /* Didn't match. */
+    buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+    return_trace (false);
+
+    good:
+    unsigned int mark2_index = (this+mark2Coverage).get_coverage  (buffer->info[j].codepoint);
+    if (mark2_index == NOT_COVERED)
+    {
+      buffer->unsafe_to_concat_from_outbuffer (skippy_iter.idx, buffer->idx + 1);
+      return_trace (false);
+    }
+
+    return_trace ((this+mark1Array).apply (c, mark1_index, mark2_index, this+mark2Array, classCount, j));
+  }
+
+  bool subset (hb_subset_context_t *c) const
+  {
+    TRACE_SUBSET (this);
+    const hb_set_t &glyphset = *c->plan->glyphset_gsub ();
+    const hb_map_t &glyph_map = *c->plan->glyph_map;
+
+    auto *out = c->serializer->start_embed (*this);
+    if (unlikely (!c->serializer->extend_min (out))) return_trace (false);
+    out->format = format;
+
+    hb_map_t klass_mapping;
+    Markclass_closure_and_remap_indexes (this+mark1Coverage, this+mark1Array, glyphset, &klass_mapping);
+
+    if (!klass_mapping.get_population ()) return_trace (false);
+    out->classCount = klass_mapping.get_population ();
+
+    auto mark1_iter =
+    + hb_zip (this+mark1Coverage, this+mark1Array)
+    | hb_filter (glyphset, hb_first)
+    ;
+
+    hb_sorted_vector_t<hb_codepoint_t> new_coverage;
+    + mark1_iter
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    if (!out->mark1Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
+      return_trace (false);
+
+    if (unlikely (!out->mark1Array.serialize_subset (c, mark1Array, this,
+						     (this+mark1Coverage).iter (),
+						     &klass_mapping)))
+      return_trace (false);
+
+    unsigned mark2count = (this+mark2Array).rows;
+    auto mark2_iter =
+    + hb_zip (this+mark2Coverage, hb_range (mark2count))
+    | hb_filter (glyphset, hb_first)
+    ;
+
+    new_coverage.reset ();
+    + mark2_iter
+    | hb_map (hb_first)
+    | hb_map (glyph_map)
+    | hb_sink (new_coverage)
+    ;
+
+    if (!out->mark2Coverage.serialize_serialize (c->serializer, new_coverage.iter ()))
+      return_trace (false);
+
+    hb_sorted_vector_t<unsigned> mark2_indexes;
+    for (const unsigned row : + mark2_iter
+                              | hb_map (hb_second))
+    {
+      + hb_range ((unsigned) classCount)
+      | hb_filter (klass_mapping)
+      | hb_map ([&] (const unsigned col) { return row * (unsigned) classCount + col; })
+      | hb_sink (mark2_indexes)
+      ;
+    }
+
+    return_trace (out->mark2Array.serialize_subset (c, mark2Array, this,
+						    mark2_iter.len (),
+						    mark2_indexes.iter ()));
+
+  }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKMARKPOSFORMAT1_HH */

+ 51 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/MarkRecord.hh

@@ -0,0 +1,51 @@
+#ifndef OT_LAYOUT_GPOS_MARKRECORD_HH
+#define OT_LAYOUT_GPOS_MARKRECORD_HH
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct MarkRecord
+{
+  friend struct MarkArray;
+
+  public:
+  HBUINT16      klass;                  /* Class defined for this mark */
+  Offset16To<Anchor>
+                markAnchor;             /* Offset to Anchor table--from
+                                         * beginning of MarkArray table */
+  public:
+  DEFINE_SIZE_STATIC (4);
+
+  unsigned get_class () const { return (unsigned) klass; }
+  bool sanitize (hb_sanitize_context_t *c, const void *base) const
+  {
+    TRACE_SANITIZE (this);
+    return_trace (c->check_struct (this) && markAnchor.sanitize (c, base));
+  }
+
+  bool subset (hb_subset_context_t    *c,
+	       const void             *src_base,
+	       const hb_map_t         *klass_mapping) const
+  {
+    TRACE_SUBSET (this);
+    auto *out = c->serializer->embed (this);
+    if (unlikely (!out)) return_trace (false);
+
+    out->klass = klass_mapping->get (klass);
+    return_trace (out->markAnchor.serialize_subset (c, markAnchor, src_base));
+  }
+
+  void collect_variation_indices (hb_collect_variation_indices_context_t *c,
+                                  const void *src_base) const
+  {
+    (src_base+markAnchor).collect_variation_indices (c);
+  }
+};
+
+
+}
+}
+}
+
+#endif /* OT_LAYOUT_GPOS_MARKRECORD_HH */

+ 46 - 0
hbfreetypefont.mod/harfbuzz/src/OT/Layout/GPOS/PairPos.hh

@@ -0,0 +1,46 @@
+#ifndef OT_LAYOUT_GPOS_PAIRPOS_HH
+#define OT_LAYOUT_GPOS_PAIRPOS_HH
+
+#include "PairPosFormat1.hh"
+#include "PairPosFormat2.hh"
+
+namespace OT {
+namespace Layout {
+namespace GPOS_impl {
+
+struct PairPos
+{
+  protected:
+  union {
+  HBUINT16			format;         /* Format identifier */
+  PairPosFormat1_3<SmallTypes>	format1;
+  PairPosFormat2_4<SmallTypes>	format2;
+#ifndef HB_NO_BEYOND_64K
+  PairPosFormat1_3<MediumTypes>	format3;
+  PairPosFormat2_4<MediumTypes>	format4;
+#endif
+  } u;
+
+  public:
+  template <typename context_t, typename ...Ts>
+  typename context_t::return_t dispatch (context_t *c, Ts&&... ds) const
+  {
+    if (unlikely (!c->may_dispatch (this, &u.format))) return c->no_dispatch_return_value ();
+    TRACE_DISPATCH (this, u.format);
+    switch (u.format) {
+    case 1: return_trace (c->dispatch (u.format1, std::forward<Ts> (ds)...));
+    case 2: return_trace (c->dispatch (u.format2, std::forward<Ts> (ds)...));
+#ifndef HB_NO_BEYOND_64K
+    case 3: return_trace (c->dispatch (u.format3, std::forward<Ts> (ds)...));
+    case 4: return_trace (c->dispatch (u.format4, std::forward<Ts> (ds)...));
+#endif
+    default:return_trace (c->default_return_value ());
+    }
+  }
+};
+
+}
+}
+}
+
+#endif  // OT_LAYOUT_GPOS_PAIRPOS_HH

Certains fichiers n'ont pas été affichés car il y a eu trop de fichiers modifiés dans ce diff