143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod/* 243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * Copyright © 2010,2012 Google, Inc. 343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * 443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * This is part of HarfBuzz, a text shaping library. 543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * 643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * Permission is hereby granted, without written agreement and without 743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * software and its documentation for any purpose, provided that the 943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 1043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * all copies of this software. 1143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * 1243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 1343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 1443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 1543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 1643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * DAMAGE. 1743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * 1843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 1943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 2043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 2143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 2243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 2343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * 2443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod * Google Author(s): Behdad Esfahbod 2543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod */ 2643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 2743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod#include "hb-ot-shape-complex-private.hh" 2843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 2943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 3043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod/* TODO Add kana, and other small shapers here */ 3143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 3243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 3343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod/* The default shaper *only* adds additional per-script features.*/ 3443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 3543f04a7456419153cb03e610a825056a47824780Behdad Esfahbodstatic const hb_tag_t hangul_features[] = 3643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod{ 3743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod HB_TAG('l','j','m','o'), 3843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod HB_TAG('v','j','m','o'), 3943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod HB_TAG('t','j','m','o'), 4043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod HB_TAG_NONE 4143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod}; 4243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 4343f04a7456419153cb03e610a825056a47824780Behdad Esfahbodstatic const hb_tag_t tibetan_features[] = 4443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod{ 4543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod HB_TAG('a','b','v','s'), 4643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod HB_TAG('b','l','w','s'), 4743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod HB_TAG('a','b','v','m'), 4843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod HB_TAG('b','l','w','m'), 4943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod HB_TAG_NONE 5043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod}; 5143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 5243f04a7456419153cb03e610a825056a47824780Behdad Esfahbodstatic void 5343f04a7456419153cb03e610a825056a47824780Behdad Esfahbodcollect_features_default (hb_ot_shape_planner_t *plan) 5443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod{ 5543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod const hb_tag_t *script_features = NULL; 5643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 5743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod switch ((hb_tag_t) plan->props.script) 5843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod { 5943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod /* Unicode-1.1 additions */ 6043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod case HB_SCRIPT_HANGUL: 6143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod script_features = hangul_features; 6243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 6343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 6443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod /* Unicode-2.0 additions */ 6543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod case HB_SCRIPT_TIBETAN: 6643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod script_features = tibetan_features; 6743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 6843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod } 6943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 7043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod for (; script_features && *script_features; script_features++) 71e7ffcfafb1108801ac504f18f820e497226bf07fBehdad Esfahbod plan->map.add_global_bool_feature (*script_features); 7243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod} 7343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 7443f04a7456419153cb03e610a825056a47824780Behdad Esfahbodstatic hb_ot_shape_normalization_mode_t 7543f04a7456419153cb03e610a825056a47824780Behdad Esfahbodnormalization_preference_default (const hb_segment_properties_t *props) 7643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod{ 7743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod switch ((hb_tag_t) props->script) 7843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod { 7943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod /* Unicode-1.1 additions */ 8043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod case HB_SCRIPT_HANGUL: 8143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_FULL; 8243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod } 8343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod return HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS; 8443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod} 8543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 86eba312c8d1b2bbe8cb9b6414e843e78d2c521aa4Behdad Esfahbodstatic bool 87eba312c8d1b2bbe8cb9b6414e843e78d2c521aa4Behdad Esfahbodcompose_default (const hb_ot_shape_normalize_context_t *c, 8843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod hb_codepoint_t a, 8943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod hb_codepoint_t b, 9043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod hb_codepoint_t *ab) 9143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod{ 9243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod /* Hebrew presentation-form shaping. 937d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod * https://bugzilla.mozilla.org/show_bug.cgi?id=728866 947d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod * Hebrew presentation forms with dagesh, for characters 0x05D0..0x05EA; 957d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod * Note that some letters do not have a dagesh presForm encoded. 967d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod */ 9743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod static const hb_codepoint_t sDageshForms[0x05EA - 0x05D0 + 1] = { 987d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB30, /* ALEF */ 997d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB31, /* BET */ 1007d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB32, /* GIMEL */ 1017d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB33, /* DALET */ 1027d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB34, /* HE */ 1037d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB35, /* VAV */ 1047d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB36, /* ZAYIN */ 1057d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0x0000, /* HET */ 1067d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB38, /* TET */ 1077d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB39, /* YOD */ 1087d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB3A, /* FINAL KAF */ 1097d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB3B, /* KAF */ 1107d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB3C, /* LAMED */ 1117d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0x0000, /* FINAL MEM */ 1127d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB3E, /* MEM */ 1137d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0x0000, /* FINAL NUN */ 1147d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB40, /* NUN */ 1157d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB41, /* SAMEKH */ 1167d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0x0000, /* AYIN */ 1177d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB43, /* FINAL PE */ 1187d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB44, /* PE */ 1197d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0x0000, /* FINAL TSADI */ 1207d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB46, /* TSADI */ 1217d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB47, /* QOF */ 1227d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB48, /* RESH */ 1237d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB49, /* SHIN */ 1247d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod 0xFB4A /* TAV */ 12543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod }; 12643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 127eba312c8d1b2bbe8cb9b6414e843e78d2c521aa4Behdad Esfahbod bool found = c->unicode->compose (a, b, ab); 12843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 12943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod if (!found && (b & ~0x7F) == 0x0580) { 1307d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod /* Special-case Hebrew presentation forms that are excluded from 1317d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod * standard normalization, but wanted for old fonts. */ 13243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod switch (b) { 1337d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod case 0x05B4: /* HIRIQ */ 1347d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod if (a == 0x05D9) { /* YOD */ 13543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB1D; 13643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 13743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod } 13843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 1397d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod case 0x05B7: /* patah */ 1407d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod if (a == 0x05F2) { /* YIDDISH YOD YOD */ 14143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB1F; 14243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 1437d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod } else if (a == 0x05D0) { /* ALEF */ 14443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB2E; 14543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 14643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod } 14743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 1487d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod case 0x05B8: /* QAMATS */ 1497d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod if (a == 0x05D0) { /* ALEF */ 15043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB2F; 15143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 15243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod } 15343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 1547d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod case 0x05B9: /* HOLAM */ 1557d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod if (a == 0x05D5) { /* VAV */ 15643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB4B; 15743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 15843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod } 15943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 1607d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod case 0x05BC: /* DAGESH */ 16143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod if (a >= 0x05D0 && a <= 0x05EA) { 16243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = sDageshForms[a - 0x05D0]; 16343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = (*ab != 0); 1647d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod } else if (a == 0xFB2A) { /* SHIN WITH SHIN DOT */ 16543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB2C; 16643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 1677d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod } else if (a == 0xFB2B) { /* SHIN WITH SIN DOT */ 16843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB2D; 16943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 17043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod } 17143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 1727d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod case 0x05BF: /* RAFE */ 17343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod switch (a) { 1747d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod case 0x05D1: /* BET */ 17543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB4C; 17643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 17743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 1787d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod case 0x05DB: /* KAF */ 17943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB4D; 18043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 18143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 1827d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod case 0x05E4: /* PE */ 18343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB4E; 18443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 18543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 18643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod } 18743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 1887d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod case 0x05C1: /* SHIN DOT */ 1897d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod if (a == 0x05E9) { /* SHIN */ 19043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB2A; 19143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 1927d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod } else if (a == 0xFB49) { /* SHIN WITH DAGESH */ 19343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB2C; 19443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 19543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod } 19643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 1977d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod case 0x05C2: /* SIN DOT */ 1987d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod if (a == 0x05E9) { /* SHIN */ 19943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB2B; 20043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 2017d52e6601f0e695690cd168a288466746cf25300Behdad Esfahbod } else if (a == 0xFB49) { /* SHIN WITH DAGESH */ 20243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod *ab = 0xFB2D; 20343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod found = true; 20443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod } 20543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod break; 20643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod } 20743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod } 20843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 20943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod return found; 21043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod} 21143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod 21243f04a7456419153cb03e610a825056a47824780Behdad Esfahbodconst hb_ot_complex_shaper_t _hb_ot_complex_shaper_default = 21343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod{ 21443f04a7456419153cb03e610a825056a47824780Behdad Esfahbod "default", 21543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod collect_features_default, 21643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod NULL, /* override_features */ 21743f04a7456419153cb03e610a825056a47824780Behdad Esfahbod NULL, /* data_create */ 21843f04a7456419153cb03e610a825056a47824780Behdad Esfahbod NULL, /* data_destroy */ 21943f04a7456419153cb03e610a825056a47824780Behdad Esfahbod NULL, /* preprocess_text */ 22043f04a7456419153cb03e610a825056a47824780Behdad Esfahbod normalization_preference_default, 22143f04a7456419153cb03e610a825056a47824780Behdad Esfahbod NULL, /* decompose */ 22243f04a7456419153cb03e610a825056a47824780Behdad Esfahbod compose_default, 22343f04a7456419153cb03e610a825056a47824780Behdad Esfahbod NULL, /* setup_masks */ 224568000274c8edb5f41bc4f876ce21fcc8bdaeed8Behdad Esfahbod HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_UNICODE, 22543f04a7456419153cb03e610a825056a47824780Behdad Esfahbod true, /* fallback_position */ 22643f04a7456419153cb03e610a825056a47824780Behdad Esfahbod}; 227