123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)/* 223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * Copyright © 2010,2012 Google, Inc. 323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * 423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * This is part of HarfBuzz, a text shaping library. 523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * 623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * Permission is hereby granted, without written agreement and without 723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * license or royalty fees, to use, copy, modify, and distribute this 823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * software and its documentation for any purpose, provided that the 923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * above copyright notice and the following two paragraphs appear in 1023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * all copies of this software. 1123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * 1223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 1323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 1423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 1523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 1623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * DAMAGE. 1723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * 1823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 1923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 2023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 2123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 2223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 2323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * 2423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * Google Author(s): Behdad Esfahbod 2523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) */ 2623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)#include "hb-ot-shape-complex-private.hh" 2823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 2923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 3023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)static bool 3123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)compose_hebrew (const hb_ot_shape_normalize_context_t *c, 3223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) hb_codepoint_t a, 3323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) hb_codepoint_t b, 3423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) hb_codepoint_t *ab) 3523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles){ 3623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) /* Hebrew presentation-form shaping. 3723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * https://bugzilla.mozilla.org/show_bug.cgi?id=728866 385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) * Hebrew presentation forms with dagesh, for characters U+05D0..05EA; 3923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * Note that some letters do not have a dagesh presForm encoded. 4023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) */ 415f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) static const hb_codepoint_t sDageshForms[0x05EAu - 0x05D0u + 1] = { 425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB30u, /* ALEF */ 435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB31u, /* BET */ 445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB32u, /* GIMEL */ 455f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB33u, /* DALET */ 465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB34u, /* HE */ 475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB35u, /* VAV */ 485f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB36u, /* ZAYIN */ 495f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0x0000u, /* HET */ 505f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB38u, /* TET */ 515f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB39u, /* YOD */ 525f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB3Au, /* FINAL KAF */ 535f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB3Bu, /* KAF */ 545f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB3Cu, /* LAMED */ 555f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0x0000u, /* FINAL MEM */ 565f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB3Eu, /* MEM */ 575f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0x0000u, /* FINAL NUN */ 585f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB40u, /* NUN */ 595f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB41u, /* SAMEKH */ 605f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0x0000u, /* AYIN */ 615f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB43u, /* FINAL PE */ 625f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB44u, /* PE */ 635f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0x0000u, /* FINAL TSADI */ 645f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB46u, /* TSADI */ 655f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB47u, /* QOF */ 665f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB48u, /* RESH */ 675f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB49u, /* SHIN */ 685f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) 0xFB4Au /* TAV */ 6923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) }; 7023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 7123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) bool found = c->unicode->compose (a, b, ab); 7223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 7323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) if (!found && !c->plan->has_mark) 7423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) { 7523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) /* Special-case Hebrew presentation forms that are excluded from 7623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) * standard normalization, but wanted for old fonts. */ 7723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) switch (b) { 785f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 0x05B4u: /* HIRIQ */ 795f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (a == 0x05D9u) { /* YOD */ 805f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB1Du; 8123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 8223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 8323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 845f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 0x05B7u: /* patah */ 855f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (a == 0x05F2u) { /* YIDDISH YOD YOD */ 865f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB1Fu; 8723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 885f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (a == 0x05D0u) { /* ALEF */ 895f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB2Eu; 9023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 9123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 9223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 935f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 0x05B8u: /* QAMATS */ 945f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (a == 0x05D0u) { /* ALEF */ 955f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB2Fu; 9623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 9723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 9823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 995f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 0x05B9u: /* HOLAM */ 1005f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (a == 0x05D5u) { /* VAV */ 1015f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB4Bu; 10223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 10323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 10423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 1055f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 0x05BCu: /* DAGESH */ 1065f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (a >= 0x05D0u && a <= 0x05EAu) { 1075f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = sDageshForms[a - 0x05D0u]; 10823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = (*ab != 0); 1095f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (a == 0xFB2Au) { /* SHIN WITH SHIN DOT */ 1105f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB2Cu; 11123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 1125f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (a == 0xFB2Bu) { /* SHIN WITH SIN DOT */ 1135f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB2Du; 11423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 11523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 11623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 1175f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 0x05BFu: /* RAFE */ 11823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) switch (a) { 1195f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 0x05D1u: /* BET */ 1205f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB4Cu; 12123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 12223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 1235f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 0x05DBu: /* KAF */ 1245f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB4Du; 12523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 12623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 1275f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 0x05E4u: /* PE */ 1285f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB4Eu; 12923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 13023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 13123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 13223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 1335f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 0x05C1u: /* SHIN DOT */ 1345f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (a == 0x05E9u) { /* SHIN */ 1355f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB2Au; 13623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 1375f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (a == 0xFB49u) { /* SHIN WITH DAGESH */ 1385f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB2Cu; 13923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 14023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 14123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 1425f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) case 0x05C2u: /* SIN DOT */ 1435f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) if (a == 0x05E9u) { /* SHIN */ 1445f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB2Bu; 14523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 1465f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) } else if (a == 0xFB49u) { /* SHIN WITH DAGESH */ 1475f1c94371a64b3196d4be9466099bb892df9b88eTorne (Richard Coles) *ab = 0xFB2Du; 14823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) found = true; 14923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 15023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) break; 15123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 15223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) } 15323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 15423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) return found; 15523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)} 15623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 15723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) 15823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew = 15923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles){ 16023730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) "hebrew", 16123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NULL, /* collect_features */ 16223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NULL, /* override_features */ 16323730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NULL, /* data_create */ 16423730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NULL, /* data_destroy */ 16523730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NULL, /* preprocess_text */ 16623730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, 16723730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NULL, /* decompose */ 16823730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) compose_hebrew, 16923730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) NULL, /* setup_masks */ 17003b57e008b61dfcb1fbad3aea950ae0e001748b0Torne (Richard Coles) HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, 17123730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles) true, /* fallback_position */ 17223730a6e56a168d1879203e4b3819bb36e3d8f1fTorne (Richard Coles)}; 173