1f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod/* 2f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * Copyright © 2010,2012 Google, Inc. 3f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * 4f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * This is part of HarfBuzz, a text shaping library. 5f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * 6f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * Permission is hereby granted, without written agreement and without 7f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * license or royalty fees, to use, copy, modify, and distribute this 8f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * software and its documentation for any purpose, provided that the 9f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * above copyright notice and the following two paragraphs appear in 10f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * all copies of this software. 11f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * 12f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 13f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 14f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 15f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 16f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * DAMAGE. 17f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * 18f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 19f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 20f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 21f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 22f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 23f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * 24f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * Google Author(s): Behdad Esfahbod 25f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod */ 26f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod 27f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod#include "hb-ot-shape-complex-private.hh" 28f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod 29f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod 30f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbodstatic bool 31f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbodcompose_hebrew (const hb_ot_shape_normalize_context_t *c, 32f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod hb_codepoint_t a, 33f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod hb_codepoint_t b, 34f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod hb_codepoint_t *ab) 35f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod{ 36f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod /* Hebrew presentation-form shaping. 37f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * https://bugzilla.mozilla.org/show_bug.cgi?id=728866 387627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod * Hebrew presentation forms with dagesh, for characters U+05D0..05EA; 39f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * Note that some letters do not have a dagesh presForm encoded. 40f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod */ 417627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod static const hb_codepoint_t sDageshForms[0x05EAu - 0x05D0u + 1] = { 427627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB30u, /* ALEF */ 437627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB31u, /* BET */ 447627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB32u, /* GIMEL */ 457627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB33u, /* DALET */ 467627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB34u, /* HE */ 477627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB35u, /* VAV */ 487627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB36u, /* ZAYIN */ 497627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0x0000u, /* HET */ 507627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB38u, /* TET */ 517627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB39u, /* YOD */ 527627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB3Au, /* FINAL KAF */ 537627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB3Bu, /* KAF */ 547627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB3Cu, /* LAMED */ 557627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0x0000u, /* FINAL MEM */ 567627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB3Eu, /* MEM */ 577627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0x0000u, /* FINAL NUN */ 587627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB40u, /* NUN */ 597627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB41u, /* SAMEKH */ 607627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0x0000u, /* AYIN */ 617627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB43u, /* FINAL PE */ 627627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB44u, /* PE */ 637627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0x0000u, /* FINAL TSADI */ 647627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB46u, /* TSADI */ 657627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB47u, /* QOF */ 667627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB48u, /* RESH */ 677627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB49u, /* SHIN */ 687627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod 0xFB4Au /* TAV */ 69f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod }; 70f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod 71f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod bool found = c->unicode->compose (a, b, ab); 72f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod 73a82165248cddb720576464b8e59a986491d3f2e9Behdad Esfahbod if (!found && !c->plan->has_mark) 74f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod { 75f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod /* Special-case Hebrew presentation forms that are excluded from 76f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod * standard normalization, but wanted for old fonts. */ 77f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod switch (b) { 787627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod case 0x05B4u: /* HIRIQ */ 797627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if (a == 0x05D9u) { /* YOD */ 807627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB1Du; 81f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 82f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod } 83f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod break; 847627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod case 0x05B7u: /* patah */ 857627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if (a == 0x05F2u) { /* YIDDISH YOD YOD */ 867627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB1Fu; 87f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 887627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod } else if (a == 0x05D0u) { /* ALEF */ 897627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB2Eu; 90f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 91f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod } 92f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod break; 937627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod case 0x05B8u: /* QAMATS */ 947627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if (a == 0x05D0u) { /* ALEF */ 957627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB2Fu; 96f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 97f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod } 98f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod break; 997627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod case 0x05B9u: /* HOLAM */ 1007627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if (a == 0x05D5u) { /* VAV */ 1017627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB4Bu; 102f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 103f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod } 104f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod break; 1057627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod case 0x05BCu: /* DAGESH */ 1067627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if (a >= 0x05D0u && a <= 0x05EAu) { 1077627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = sDageshForms[a - 0x05D0u]; 108f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = (*ab != 0); 1097627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod } else if (a == 0xFB2Au) { /* SHIN WITH SHIN DOT */ 1107627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB2Cu; 111f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 1127627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod } else if (a == 0xFB2Bu) { /* SHIN WITH SIN DOT */ 1137627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB2Du; 114f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 115f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod } 116f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod break; 1177627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod case 0x05BFu: /* RAFE */ 118f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod switch (a) { 1197627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod case 0x05D1u: /* BET */ 1207627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB4Cu; 121f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 122f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod break; 1237627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod case 0x05DBu: /* KAF */ 1247627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB4Du; 125f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 126f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod break; 1277627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod case 0x05E4u: /* PE */ 1287627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB4Eu; 129f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 130f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod break; 131f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod } 132f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod break; 1337627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod case 0x05C1u: /* SHIN DOT */ 1347627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if (a == 0x05E9u) { /* SHIN */ 1357627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB2Au; 136f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 1377627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod } else if (a == 0xFB49u) { /* SHIN WITH DAGESH */ 1387627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB2Cu; 139f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 140f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod } 141f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod break; 1427627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod case 0x05C2u: /* SIN DOT */ 1437627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod if (a == 0x05E9u) { /* SHIN */ 1447627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB2Bu; 145f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 1467627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod } else if (a == 0xFB49u) { /* SHIN WITH DAGESH */ 1477627100f428ac0ec8509d961d368d2d25d8f0b6eBehdad Esfahbod *ab = 0xFB2Du; 148f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod found = true; 149f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod } 150f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod break; 151f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod } 152f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod } 153f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod 154f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod return found; 155f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod} 156f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod 157f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod 158f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbodconst hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew = 159f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod{ 160f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod "hebrew", 161f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod NULL, /* collect_features */ 162f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod NULL, /* override_features */ 163f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod NULL, /* data_create */ 164f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod NULL, /* data_destroy */ 165f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod NULL, /* preprocess_text */ 166f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, 167f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod NULL, /* decompose */ 168f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod compose_hebrew, 169f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod NULL, /* setup_masks */ 1709e834e29e0b657f0555df1ab9cea79ff7abcf08dBehdad Esfahbod HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, 171f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod true, /* fallback_position */ 172f14bb7de631b20e2868fb62e5311cd0d9e24bb49Behdad Esfahbod}; 173