(root)/
harfbuzz-8.3.0/
test/
api/
test-ot-collect-glyphs.c
       1  /*
       2   * Copyright © 2021  Khaled Hosny
       3   *
       4   *  This is part of HarfBuzz, a text shaping library.
       5   *
       6   * Permission is hereby granted, without written agreement and without
       7   * license or royalty fees, to use, copy, modify, and distribute this
       8   * software and its documentation for any purpose, provided that the
       9   * above copyright notice and the following two paragraphs appear in
      10   * all copies of this software.
      11   *
      12   * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR
      13   * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES
      14   * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN
      15   * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH
      16   * DAMAGE.
      17   *
      18   * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING,
      19   * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
      20   * FITNESS FOR A PARTICULAR PURPOSE.  THE SOFTWARE PROVIDED HEREUNDER IS
      21   * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
      22   * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
      23   */
      24  
      25  #include "hb-test.h"
      26  
      27  #include <hb.h>
      28  #include <hb-ot.h>
      29  
      30  #define BEGIN(tag, idx) \
      31    hb_ot_layout_lookup_collect_glyphs (face, tag, idx, before, input, after, output) \
      32  
      33  #define END() \
      34    hb_set_clear (before); \
      35    hb_set_clear (input); \
      36    hb_set_clear (after); \
      37    hb_set_clear (output)
      38  
      39  static void
      40  test_ot_layout_lookup_collect_glyphs_source_sans (void)
      41  {
      42    hb_face_t *face = hb_test_open_font_file ("fonts/SourceSansPro-Regular.otf");
      43  
      44    hb_set_t *before = hb_set_create();
      45    hb_set_t *input = hb_set_create();
      46    hb_set_t *after = hb_set_create();
      47    hb_set_t *output = hb_set_create();
      48    hb_codepoint_t g = HB_SET_VALUE_INVALID;
      49  
      50    /* SingleSubst */
      51    BEGIN(HB_OT_TAG_GSUB, 0);
      52    g_assert_cmpuint (0, ==, hb_set_get_population (before));
      53    g_assert_cmpuint (684, ==, hb_set_get_population (input));
      54    g = HB_SET_VALUE_INVALID;
      55    g_assert (hb_set_next (input, &g));
      56    g_assert_cmpuint (54, ==, g);
      57    g_assert_cmpuint (0, ==, hb_set_get_population (after));
      58    g_assert_cmpuint (372, ==, hb_set_get_population (output));
      59    g = HB_SET_VALUE_INVALID;
      60    g_assert (hb_set_next (output, &g));
      61    g_assert_cmpuint (574, ==, g);
      62    END();
      63  
      64    /* AlternateSubst */
      65    BEGIN(HB_OT_TAG_GSUB, 1);
      66    g_assert_cmpuint (0, ==, hb_set_get_population (before));
      67  
      68    g_assert_cmpuint (143, ==, hb_set_get_population (input));
      69    g = HB_SET_VALUE_INVALID;
      70    g_assert (hb_set_next (input, &g));
      71    g_assert_cmpuint (2, ==, g);
      72  
      73    g_assert_cmpuint (0, ==, hb_set_get_population (after));
      74  
      75    g_assert_cmpuint (319, ==, hb_set_get_population (output));
      76    g = HB_SET_VALUE_INVALID;
      77    g_assert (hb_set_next (output, &g));
      78    g_assert_cmpuint (519, ==, g);
      79    END();
      80  
      81    /* MultipleSubst */
      82    BEGIN(HB_OT_TAG_GSUB, 7);
      83    g_assert_cmpuint (0, ==, hb_set_get_population (before));
      84  
      85    g_assert_cmpuint (10, ==, hb_set_get_population (input));
      86    g = HB_SET_VALUE_INVALID;
      87    g_assert (hb_set_next (input, &g));
      88    g_assert_cmpuint (92, ==, g);
      89  
      90    g_assert_cmpuint (0, ==, hb_set_get_population (after));
      91  
      92    g_assert_cmpuint (9, ==, hb_set_get_population (output));
      93    g = HB_SET_VALUE_INVALID;
      94    g_assert (hb_set_next (output, &g));
      95    g_assert_cmpuint (6, ==, g);
      96    END();
      97  
      98    /* LigatureSubst */
      99    BEGIN(HB_OT_TAG_GSUB, 10);
     100    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     101  
     102    g_assert_cmpuint (14, ==, hb_set_get_population (input));
     103    g = HB_SET_VALUE_INVALID;
     104    g_assert (hb_set_next (input, &g));
     105    g_assert_cmpuint (1823, ==, g);
     106  
     107    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     108  
     109    g_assert_cmpuint (22, ==, hb_set_get_population (output));
     110    g = HB_SET_VALUE_INVALID;
     111    g_assert (hb_set_next (output, &g));
     112    g_assert_cmpuint (1897, ==, g);
     113    END();
     114  
     115    /* ChainContextSubstFormat3 */
     116    BEGIN(HB_OT_TAG_GSUB, 8);
     117    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     118  
     119    g_assert_cmpuint (10, ==, hb_set_get_population (input));
     120    g = HB_SET_VALUE_INVALID;
     121    g_assert (hb_set_next (input, &g));
     122    g_assert_cmpuint (92, ==, g);
     123  
     124    g_assert_cmpuint (2, ==, hb_set_get_population (after));
     125    g = HB_SET_VALUE_INVALID;
     126    g_assert (hb_set_next (after, &g));
     127    g_assert_cmpuint (1826, ==, g);
     128    g_assert (hb_set_next (after, &g));
     129    g_assert_cmpuint (1837, ==, g);
     130  
     131    g_assert_cmpuint (9, ==, hb_set_get_population (output));
     132    g = HB_SET_VALUE_INVALID;
     133    g_assert (hb_set_next (output, &g));
     134    g_assert_cmpuint (6, ==, g);
     135    END();
     136  
     137    /* ChainContextSubstFormat3 */
     138    BEGIN(HB_OT_TAG_GSUB, 13);
     139    g_assert_cmpuint (771, ==, hb_set_get_population (before));
     140    g = HB_SET_VALUE_INVALID;
     141    g_assert (hb_set_next (before, &g));
     142    g_assert_cmpuint (2, ==, g);
     143  
     144    g_assert_cmpuint (28, ==, hb_set_get_population (input));
     145    g = HB_SET_VALUE_INVALID;
     146    g_assert (hb_set_next (input, &g));
     147    g_assert_cmpuint (1823, ==, g);
     148  
     149    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     150  
     151    g_assert_cmpuint (48, ==, hb_set_get_population (output));
     152    g = HB_SET_VALUE_INVALID;
     153    g_assert (hb_set_next (output, &g));
     154    g_assert_cmpuint (325, ==, g);
     155    END();
     156  
     157    /* MarkBasePos */
     158    BEGIN(HB_OT_TAG_GPOS, 0);
     159    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     160  
     161    g_assert_cmpuint (179, ==, hb_set_get_population (input));
     162    g = HB_SET_VALUE_INVALID;
     163    g_assert (hb_set_next (input, &g));
     164    g_assert_cmpuint (28, ==, g);
     165  
     166    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     167    g_assert_cmpuint (0, ==, hb_set_get_population (output));
     168    END();
     169  
     170    /* MarkMarkPos */
     171    BEGIN(HB_OT_TAG_GPOS, 9);
     172    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     173  
     174    g_assert_cmpuint (48, ==, hb_set_get_population (input));
     175    g = HB_SET_VALUE_INVALID;
     176    g_assert (hb_set_next (input, &g));
     177    g_assert_cmpuint (1823, ==, g);
     178  
     179    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     180    g_assert_cmpuint (0, ==, hb_set_get_population (output));
     181    END();
     182  
     183    /* PairPos */
     184    BEGIN(HB_OT_TAG_GPOS, 10);
     185    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     186  
     187    g_assert_cmpuint (1426, ==, hb_set_get_population (input));
     188    g = HB_SET_VALUE_INVALID;
     189    g_assert (hb_set_next (input, &g));
     190    g_assert_cmpuint (2, ==, g);
     191  
     192    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     193    g_assert_cmpuint (0, ==, hb_set_get_population (output));
     194    END();
     195  
     196    hb_face_destroy (face);
     197    face = hb_test_open_font_file ("fonts/SourceHanSans-Regular.41,3041,4C2E.otf");
     198  
     199    /* SinglePosFormat2 */
     200    BEGIN(HB_OT_TAG_GPOS, 1);
     201    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     202  
     203    g_assert_cmpuint (1, ==, hb_set_get_population (input));
     204    g = HB_SET_VALUE_INVALID;
     205    g_assert (hb_set_next (input, &g));
     206    g_assert_cmpuint (4, ==, g);
     207  
     208    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     209    g_assert_cmpuint (0, ==, hb_set_get_population (output));
     210    END();
     211  
     212    hb_face_destroy (face);
     213    hb_set_destroy (before);
     214    hb_set_destroy (input);
     215    hb_set_destroy (after);
     216    hb_set_destroy (output);
     217  }
     218  
     219  static void
     220  test_ot_layout_lookup_collect_glyphs_noto_nastaliq (void)
     221  {
     222    hb_face_t *face = hb_test_open_font_file ("fonts/NotoNastaliqUrdu-Regular.ttf");
     223  
     224    hb_set_t *before = hb_set_create();
     225    hb_set_t *input = hb_set_create();
     226    hb_set_t *after = hb_set_create();
     227    hb_set_t *output = hb_set_create();
     228    hb_codepoint_t g = HB_SET_VALUE_INVALID;
     229  
     230    /* ExtensionSubst -> ContextSubstFormat1 */
     231    BEGIN(HB_OT_TAG_GSUB, 9);
     232    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     233  
     234    g_assert_cmpuint (3, ==, hb_set_get_population (input));
     235    g = HB_SET_VALUE_INVALID;
     236    g_assert (hb_set_next (input, &g));
     237    g_assert_cmpuint (228, ==, g);
     238    g_assert (hb_set_next (input, &g));
     239    g_assert_cmpuint (416, ==, g);
     240    g_assert (hb_set_next (input, &g));
     241    g_assert_cmpuint (441, ==, g);
     242  
     243    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     244  
     245    g_assert_cmpuint (3, ==, hb_set_get_population (output));
     246    g = HB_SET_VALUE_INVALID;
     247    g_assert (hb_set_next (output, &g));
     248    g_assert_cmpuint (267, ==, g);
     249    g_assert (hb_set_next (output, &g));
     250    g_assert_cmpuint (268, ==, g);
     251    g_assert (hb_set_next (output, &g));
     252    g_assert_cmpuint (279, ==, g);
     253    END();
     254  
     255    /* ExtensionSubst -> SingleSubst */
     256    BEGIN(HB_OT_TAG_GSUB, 10);
     257    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     258  
     259    g_assert_cmpuint (3, ==, hb_set_get_population (input));
     260    g = HB_SET_VALUE_INVALID;
     261    g_assert (hb_set_next (input, &g));
     262    g_assert_cmpuint (228, ==, g);
     263    g_assert (hb_set_next (input, &g));
     264    g_assert_cmpuint (416, ==, g);
     265    g_assert (hb_set_next (input, &g));
     266    g_assert_cmpuint (441, ==, g);
     267  
     268    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     269  
     270    g_assert_cmpuint (3, ==, hb_set_get_population (output));
     271    g = HB_SET_VALUE_INVALID;
     272    g_assert (hb_set_next (output, &g));
     273    g_assert_cmpuint (267, ==, g);
     274    g_assert (hb_set_next (output, &g));
     275    g_assert_cmpuint (268, ==, g);
     276    g_assert (hb_set_next (output, &g));
     277    g_assert_cmpuint (279, ==, g);
     278    END();
     279  
     280    /* ExtensionSubst -> ChainContextSubstFormat2 */
     281    BEGIN(HB_OT_TAG_GSUB, 16);
     282    g_assert_cmpuint (16, ==, hb_set_get_population (before));
     283    g = HB_SET_VALUE_INVALID;
     284    g_assert (hb_set_next (before, &g));
     285    g_assert_cmpuint (74, ==, g);
     286  
     287    g_assert_cmpuint (27, ==, hb_set_get_population (input));
     288    g = HB_SET_VALUE_INVALID;
     289    g_assert (hb_set_next (input, &g));
     290    g_assert_cmpuint (276, ==, g);
     291  
     292    g_assert_cmpuint (14, ==, hb_set_get_population (after));
     293    g = HB_SET_VALUE_INVALID;
     294    g_assert (hb_set_next (after, &g));
     295    g_assert_cmpuint (252, ==, g);
     296  
     297    g_assert_cmpuint (43, ==, hb_set_get_population (output));
     298    g = HB_SET_VALUE_INVALID;
     299    g_assert (hb_set_next (output, &g));
     300    g_assert_cmpuint (74, ==, g);
     301    END();
     302  
     303    /* ExtensionSubst -> ContextSubstFormat2 */
     304    BEGIN(HB_OT_TAG_GSUB, 39);
     305    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     306  
     307    g_assert_cmpuint (246, ==, hb_set_get_population (input));
     308    g = HB_SET_VALUE_INVALID;
     309    g_assert (hb_set_next (input, &g));
     310    g_assert_cmpuint (252, ==, g);
     311  
     312    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     313  
     314    g_assert_cmpuint (258, ==, hb_set_get_population (output));
     315    g = HB_SET_VALUE_INVALID;
     316    g_assert (hb_set_next (output, &g));
     317    g_assert_cmpuint (74, ==, g);
     318    END();
     319  
     320  
     321    /* CursivePos */
     322    BEGIN(HB_OT_TAG_GPOS, 0);
     323    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     324  
     325    g_assert_cmpuint (616, ==, hb_set_get_population (input));
     326    g = HB_SET_VALUE_INVALID;
     327    g_assert (hb_set_next (input, &g));
     328    g_assert_cmpuint (228, ==, g);
     329  
     330    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     331    g_assert_cmpuint (0, ==, hb_set_get_population (output));
     332    END();
     333  
     334    /* ExtensionSubst -> MarkLigPos */
     335    BEGIN(HB_OT_TAG_GPOS, 13);
     336    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     337  
     338    g_assert_cmpuint (46, ==, hb_set_get_population (input));
     339    g = HB_SET_VALUE_INVALID;
     340    g_assert (hb_set_next (input, &g));
     341    g_assert_cmpuint (1004, ==, g);
     342  
     343    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     344    g_assert_cmpuint (0, ==, hb_set_get_population (output));
     345    END();
     346  
     347    /* ExtensionSubst -> SinglePosFormat1 */
     348    BEGIN(HB_OT_TAG_GPOS, 17);
     349    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     350  
     351    g_assert_cmpuint (242, ==, hb_set_get_population (input));
     352    g = HB_SET_VALUE_INVALID;
     353    g_assert (hb_set_next (input, &g));
     354    g_assert_cmpuint (257, ==, g);
     355  
     356    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     357    g_assert_cmpuint (0, ==, hb_set_get_population (output));
     358    END();
     359  
     360    hb_face_destroy (face);
     361    hb_set_destroy (before);
     362    hb_set_destroy (input);
     363    hb_set_destroy (after);
     364    hb_set_destroy (output);
     365  }
     366  
     367  static void
     368  test_ot_layout_lookup_collect_glyphs_qahiri (void)
     369  {
     370    hb_face_t *face = hb_test_open_font_file ("fonts/Qahiri-Regular.ttf");
     371  
     372    hb_set_t *before = hb_set_create();
     373    hb_set_t *input = hb_set_create();
     374    hb_set_t *after = hb_set_create();
     375    hb_set_t *output = hb_set_create();
     376    hb_codepoint_t g = HB_SET_VALUE_INVALID;
     377  
     378    /* SingleSubstFormat1 */
     379    BEGIN(HB_OT_TAG_GSUB, 0);
     380    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     381  
     382    g_assert_cmpuint (4, ==, hb_set_get_population (input));
     383    g = HB_SET_VALUE_INVALID;
     384    g_assert (hb_set_next (input, &g));
     385    g_assert_cmpuint (52, ==, g);
     386    g_assert (hb_set_next (input, &g));
     387    g_assert_cmpuint (60, ==, g);
     388    g_assert (hb_set_next (input, &g));
     389    g_assert_cmpuint (62, ==, g);
     390    g_assert (hb_set_next (input, &g));
     391    g_assert_cmpuint (159, ==, g);
     392  
     393    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     394  
     395    g_assert_cmpuint (4, ==, hb_set_get_population (output));
     396    g = HB_SET_VALUE_INVALID;
     397    g_assert (hb_set_next (output, &g));
     398    g_assert_cmpuint (53, ==, g);
     399    g_assert (hb_set_next (output, &g));
     400    g_assert_cmpuint (61, ==, g);
     401    g_assert (hb_set_next (output, &g));
     402    g_assert_cmpuint (63, ==, g);
     403    g_assert (hb_set_next (output, &g));
     404    g_assert_cmpuint (160, ==, g);
     405    END();
     406  
     407    /* ChainContextSubstFormat1 */
     408    BEGIN(HB_OT_TAG_GSUB, 11);
     409    g_assert_cmpuint (1, ==, hb_set_get_population (before));
     410    g = HB_SET_VALUE_INVALID;
     411    g_assert (hb_set_next (before, &g));
     412    g_assert_cmpuint (39, ==, g);
     413  
     414    g_assert_cmpuint (2, ==, hb_set_get_population (input));
     415    g = HB_SET_VALUE_INVALID;
     416    g_assert (hb_set_next (input, &g));
     417    g_assert_cmpuint (154, ==, g);
     418    g_assert (hb_set_next (input, &g));
     419    g_assert_cmpuint (159, ==, g);
     420  
     421    g_assert_cmpuint (1, ==, hb_set_get_population (after));
     422    g = HB_SET_VALUE_INVALID;
     423    g_assert (hb_set_next (after, &g));
     424    g_assert_cmpuint (179, ==, g);
     425  
     426    g_assert_cmpuint (2, ==, hb_set_get_population (output));
     427    g = HB_SET_VALUE_INVALID;
     428    g_assert (hb_set_next (output, &g));
     429    g_assert_cmpuint (155, ==, g);
     430    g_assert (hb_set_next (output, &g));
     431    g_assert_cmpuint (162, ==, g);
     432    END();
     433  
     434    /* ContextSubstFormat3 */
     435    BEGIN(HB_OT_TAG_GSUB, 31);
     436    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     437  
     438    g_assert_cmpuint (4, ==, hb_set_get_population (input));
     439    g = HB_SET_VALUE_INVALID;
     440    g_assert (hb_set_next (input, &g));
     441    g_assert_cmpuint (53, ==, g);
     442  
     443    g_assert_cmpuint (0, ==, hb_set_get_population (after));
     444  
     445    g_assert_cmpuint (4, ==, hb_set_get_population (output));
     446    g = HB_SET_VALUE_INVALID;
     447    g_assert (hb_set_next (output, &g));
     448    g_assert_cmpuint (52, ==, g);
     449    g_assert (hb_set_next (output, &g));
     450    g_assert_cmpuint (60, ==, g);
     451    g_assert (hb_set_next (output, &g));
     452    g_assert_cmpuint (62, ==, g);
     453    g_assert (hb_set_next (output, &g));
     454    g_assert_cmpuint (159, ==, g);
     455    END();
     456  
     457    /* ReverseChainSingleSubst */
     458    BEGIN(HB_OT_TAG_GSUB, 32);
     459    g_assert_cmpuint (0, ==, hb_set_get_population (before));
     460  
     461    g_assert_cmpuint (42, ==, hb_set_get_population (input));
     462    g = HB_SET_VALUE_INVALID;
     463    g_assert (hb_set_next (input, &g));
     464    g_assert_cmpuint (47, ==, g);
     465  
     466    g_assert_cmpuint (46, ==, hb_set_get_population (after));
     467    g = HB_SET_VALUE_INVALID;
     468    g_assert (hb_set_next (after, &g));
     469    g_assert_cmpuint (61, ==, g);
     470  
     471    g_assert_cmpuint (42, ==, hb_set_get_population (output));
     472    g = HB_SET_VALUE_INVALID;
     473    g_assert (hb_set_next (output, &g));
     474    g_assert_cmpuint (463, ==, g);
     475    END();
     476  
     477    hb_face_destroy (face);
     478    hb_set_destroy (before);
     479    hb_set_destroy (input);
     480    hb_set_destroy (after);
     481    hb_set_destroy (output);
     482  }
     483  
     484  int
     485  main (int argc, char **argv)
     486  {
     487    hb_test_init (&argc, &argv);
     488    hb_test_add (test_ot_layout_lookup_collect_glyphs_source_sans);
     489    hb_test_add (test_ot_layout_lookup_collect_glyphs_noto_nastaliq);
     490    hb_test_add (test_ot_layout_lookup_collect_glyphs_qahiri);
     491    return hb_test_run ();
     492  }