Fri, 16 Jan 2015 18:13:44 +0100
Integrate suggestion from review to improve consistency with existing code.
michael@0 | 1 | /* |
michael@0 | 2 | * Copyright © 2010,2012 Google, Inc. |
michael@0 | 3 | * |
michael@0 | 4 | * This is part of HarfBuzz, a text shaping library. |
michael@0 | 5 | * |
michael@0 | 6 | * Permission is hereby granted, without written agreement and without |
michael@0 | 7 | * license or royalty fees, to use, copy, modify, and distribute this |
michael@0 | 8 | * software and its documentation for any purpose, provided that the |
michael@0 | 9 | * above copyright notice and the following two paragraphs appear in |
michael@0 | 10 | * all copies of this software. |
michael@0 | 11 | * |
michael@0 | 12 | * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR |
michael@0 | 13 | * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES |
michael@0 | 14 | * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN |
michael@0 | 15 | * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH |
michael@0 | 16 | * DAMAGE. |
michael@0 | 17 | * |
michael@0 | 18 | * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, |
michael@0 | 19 | * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
michael@0 | 20 | * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS |
michael@0 | 21 | * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO |
michael@0 | 22 | * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. |
michael@0 | 23 | * |
michael@0 | 24 | * Google Author(s): Behdad Esfahbod |
michael@0 | 25 | */ |
michael@0 | 26 | |
michael@0 | 27 | #include "hb-ot-shape-complex-private.hh" |
michael@0 | 28 | |
michael@0 | 29 | |
michael@0 | 30 | static bool |
michael@0 | 31 | compose_hebrew (const hb_ot_shape_normalize_context_t *c, |
michael@0 | 32 | hb_codepoint_t a, |
michael@0 | 33 | hb_codepoint_t b, |
michael@0 | 34 | hb_codepoint_t *ab) |
michael@0 | 35 | { |
michael@0 | 36 | /* Hebrew presentation-form shaping. |
michael@0 | 37 | * https://bugzilla.mozilla.org/show_bug.cgi?id=728866 |
michael@0 | 38 | * Hebrew presentation forms with dagesh, for characters 0x05D0..0x05EA; |
michael@0 | 39 | * Note that some letters do not have a dagesh presForm encoded. |
michael@0 | 40 | */ |
michael@0 | 41 | static const hb_codepoint_t sDageshForms[0x05EA - 0x05D0 + 1] = { |
michael@0 | 42 | 0xFB30, /* ALEF */ |
michael@0 | 43 | 0xFB31, /* BET */ |
michael@0 | 44 | 0xFB32, /* GIMEL */ |
michael@0 | 45 | 0xFB33, /* DALET */ |
michael@0 | 46 | 0xFB34, /* HE */ |
michael@0 | 47 | 0xFB35, /* VAV */ |
michael@0 | 48 | 0xFB36, /* ZAYIN */ |
michael@0 | 49 | 0x0000, /* HET */ |
michael@0 | 50 | 0xFB38, /* TET */ |
michael@0 | 51 | 0xFB39, /* YOD */ |
michael@0 | 52 | 0xFB3A, /* FINAL KAF */ |
michael@0 | 53 | 0xFB3B, /* KAF */ |
michael@0 | 54 | 0xFB3C, /* LAMED */ |
michael@0 | 55 | 0x0000, /* FINAL MEM */ |
michael@0 | 56 | 0xFB3E, /* MEM */ |
michael@0 | 57 | 0x0000, /* FINAL NUN */ |
michael@0 | 58 | 0xFB40, /* NUN */ |
michael@0 | 59 | 0xFB41, /* SAMEKH */ |
michael@0 | 60 | 0x0000, /* AYIN */ |
michael@0 | 61 | 0xFB43, /* FINAL PE */ |
michael@0 | 62 | 0xFB44, /* PE */ |
michael@0 | 63 | 0x0000, /* FINAL TSADI */ |
michael@0 | 64 | 0xFB46, /* TSADI */ |
michael@0 | 65 | 0xFB47, /* QOF */ |
michael@0 | 66 | 0xFB48, /* RESH */ |
michael@0 | 67 | 0xFB49, /* SHIN */ |
michael@0 | 68 | 0xFB4A /* TAV */ |
michael@0 | 69 | }; |
michael@0 | 70 | |
michael@0 | 71 | bool found = c->unicode->compose (a, b, ab); |
michael@0 | 72 | |
michael@0 | 73 | if (!found) |
michael@0 | 74 | { |
michael@0 | 75 | /* Special-case Hebrew presentation forms that are excluded from |
michael@0 | 76 | * standard normalization, but wanted for old fonts. */ |
michael@0 | 77 | switch (b) { |
michael@0 | 78 | case 0x05B4: /* HIRIQ */ |
michael@0 | 79 | if (a == 0x05D9) { /* YOD */ |
michael@0 | 80 | *ab = 0xFB1D; |
michael@0 | 81 | found = true; |
michael@0 | 82 | } |
michael@0 | 83 | break; |
michael@0 | 84 | case 0x05B7: /* patah */ |
michael@0 | 85 | if (a == 0x05F2) { /* YIDDISH YOD YOD */ |
michael@0 | 86 | *ab = 0xFB1F; |
michael@0 | 87 | found = true; |
michael@0 | 88 | } else if (a == 0x05D0) { /* ALEF */ |
michael@0 | 89 | *ab = 0xFB2E; |
michael@0 | 90 | found = true; |
michael@0 | 91 | } |
michael@0 | 92 | break; |
michael@0 | 93 | case 0x05B8: /* QAMATS */ |
michael@0 | 94 | if (a == 0x05D0) { /* ALEF */ |
michael@0 | 95 | *ab = 0xFB2F; |
michael@0 | 96 | found = true; |
michael@0 | 97 | } |
michael@0 | 98 | break; |
michael@0 | 99 | case 0x05B9: /* HOLAM */ |
michael@0 | 100 | if (a == 0x05D5) { /* VAV */ |
michael@0 | 101 | *ab = 0xFB4B; |
michael@0 | 102 | found = true; |
michael@0 | 103 | } |
michael@0 | 104 | break; |
michael@0 | 105 | case 0x05BC: /* DAGESH */ |
michael@0 | 106 | if (a >= 0x05D0 && a <= 0x05EA) { |
michael@0 | 107 | *ab = sDageshForms[a - 0x05D0]; |
michael@0 | 108 | found = (*ab != 0); |
michael@0 | 109 | } else if (a == 0xFB2A) { /* SHIN WITH SHIN DOT */ |
michael@0 | 110 | *ab = 0xFB2C; |
michael@0 | 111 | found = true; |
michael@0 | 112 | } else if (a == 0xFB2B) { /* SHIN WITH SIN DOT */ |
michael@0 | 113 | *ab = 0xFB2D; |
michael@0 | 114 | found = true; |
michael@0 | 115 | } |
michael@0 | 116 | break; |
michael@0 | 117 | case 0x05BF: /* RAFE */ |
michael@0 | 118 | switch (a) { |
michael@0 | 119 | case 0x05D1: /* BET */ |
michael@0 | 120 | *ab = 0xFB4C; |
michael@0 | 121 | found = true; |
michael@0 | 122 | break; |
michael@0 | 123 | case 0x05DB: /* KAF */ |
michael@0 | 124 | *ab = 0xFB4D; |
michael@0 | 125 | found = true; |
michael@0 | 126 | break; |
michael@0 | 127 | case 0x05E4: /* PE */ |
michael@0 | 128 | *ab = 0xFB4E; |
michael@0 | 129 | found = true; |
michael@0 | 130 | break; |
michael@0 | 131 | } |
michael@0 | 132 | break; |
michael@0 | 133 | case 0x05C1: /* SHIN DOT */ |
michael@0 | 134 | if (a == 0x05E9) { /* SHIN */ |
michael@0 | 135 | *ab = 0xFB2A; |
michael@0 | 136 | found = true; |
michael@0 | 137 | } else if (a == 0xFB49) { /* SHIN WITH DAGESH */ |
michael@0 | 138 | *ab = 0xFB2C; |
michael@0 | 139 | found = true; |
michael@0 | 140 | } |
michael@0 | 141 | break; |
michael@0 | 142 | case 0x05C2: /* SIN DOT */ |
michael@0 | 143 | if (a == 0x05E9) { /* SHIN */ |
michael@0 | 144 | *ab = 0xFB2B; |
michael@0 | 145 | found = true; |
michael@0 | 146 | } else if (a == 0xFB49) { /* SHIN WITH DAGESH */ |
michael@0 | 147 | *ab = 0xFB2D; |
michael@0 | 148 | found = true; |
michael@0 | 149 | } |
michael@0 | 150 | break; |
michael@0 | 151 | } |
michael@0 | 152 | } |
michael@0 | 153 | |
michael@0 | 154 | return found; |
michael@0 | 155 | } |
michael@0 | 156 | |
michael@0 | 157 | |
michael@0 | 158 | const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew = |
michael@0 | 159 | { |
michael@0 | 160 | "hebrew", |
michael@0 | 161 | NULL, /* collect_features */ |
michael@0 | 162 | NULL, /* override_features */ |
michael@0 | 163 | NULL, /* data_create */ |
michael@0 | 164 | NULL, /* data_destroy */ |
michael@0 | 165 | NULL, /* preprocess_text */ |
michael@0 | 166 | HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, |
michael@0 | 167 | NULL, /* decompose */ |
michael@0 | 168 | compose_hebrew, |
michael@0 | 169 | NULL, /* setup_masks */ |
michael@0 | 170 | HB_OT_SHAPE_ZERO_WIDTH_MARKS_DEFAULT, |
michael@0 | 171 | true, /* fallback_position */ |
michael@0 | 172 | }; |