1 /* 2 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 3 * 4 * This code is free software; you can redistribute it and/or modify it 5 * under the terms of the GNU General Public License version 2 only, as 6 * published by the Free Software Foundation. Oracle designates this 7 * particular file as subject to the "Classpath" exception as provided 8 * by Oracle in the LICENSE file that accompanied this code. 9 * 10 * This code is distributed in the hope that it will be useful, but WITHOUT 11 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 12 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 13 * version 2 for more details (a copy is included in the LICENSE file that 14 * accompanied this code). 15 * 16 * You should have received a copy of the GNU General Public License version 17 * 2 along with this work; if not, write to the Free Software Foundation, 18 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 19 * 20 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 21 * or visit www.oracle.com if you need additional information or have any 22 * questions. 23 */ 24 25 // This file is available under and governed by the GNU General Public 26 // License version 2 only, as published by the Free Software Foundation. 27 // However, the following notice accompanied the original version of this 28 // file: 29 // 30 /* 31 * Copyright © 2010,2012 Google, Inc. 32 * 33 * This is part of HarfBuzz, a text shaping library. 34 * 35 * Permission is hereby granted, without written agreement and without 36 * license or royalty fees, to use, copy, modify, and distribute this 37 * software and its documentation for any purpose, provided that the 38 * above copyright notice and the following two paragraphs appear in 39 * all copies of this software. 40 * 41 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR 42 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES 43 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN 44 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH 45 * DAMAGE. 46 * 47 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, 48 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND 49 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS 50 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO 51 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. 52 * 53 * Google Author(s): Behdad Esfahbod 54 */ 55 56 #include "hb-ot-shape-complex-private.hh" 57 58 59 static bool 60 compose_hebrew (const hb_ot_shape_normalize_context_t *c, 61 hb_codepoint_t a, 62 hb_codepoint_t b, 63 hb_codepoint_t *ab) 64 { 65 /* Hebrew presentation-form shaping. 66 * https://bugzilla.mozilla.org/show_bug.cgi?id=728866 67 * Hebrew presentation forms with dagesh, for characters U+05D0..05EA; 68 * Note that some letters do not have a dagesh presForm encoded. 69 */ 70 static const hb_codepoint_t sDageshForms[0x05EAu - 0x05D0u + 1] = { 71 0xFB30u, /* ALEF */ 72 0xFB31u, /* BET */ 73 0xFB32u, /* GIMEL */ 74 0xFB33u, /* DALET */ 75 0xFB34u, /* HE */ 76 0xFB35u, /* VAV */ 77 0xFB36u, /* ZAYIN */ 78 0x0000u, /* HET */ 79 0xFB38u, /* TET */ 80 0xFB39u, /* YOD */ 81 0xFB3Au, /* FINAL KAF */ 82 0xFB3Bu, /* KAF */ 83 0xFB3Cu, /* LAMED */ 84 0x0000u, /* FINAL MEM */ 85 0xFB3Eu, /* MEM */ 86 0x0000u, /* FINAL NUN */ 87 0xFB40u, /* NUN */ 88 0xFB41u, /* SAMEKH */ 89 0x0000u, /* AYIN */ 90 0xFB43u, /* FINAL PE */ 91 0xFB44u, /* PE */ 92 0x0000u, /* FINAL TSADI */ 93 0xFB46u, /* TSADI */ 94 0xFB47u, /* QOF */ 95 0xFB48u, /* RESH */ 96 0xFB49u, /* SHIN */ 97 0xFB4Au /* TAV */ 98 }; 99 100 bool found = c->unicode->compose (a, b, ab); 101 102 if (!found && !c->plan->has_mark) 103 { 104 /* Special-case Hebrew presentation forms that are excluded from 105 * standard normalization, but wanted for old fonts. */ 106 switch (b) { 107 case 0x05B4u: /* HIRIQ */ 108 if (a == 0x05D9u) { /* YOD */ 109 *ab = 0xFB1Du; 110 found = true; 111 } 112 break; 113 case 0x05B7u: /* patah */ 114 if (a == 0x05F2u) { /* YIDDISH YOD YOD */ 115 *ab = 0xFB1Fu; 116 found = true; 117 } else if (a == 0x05D0u) { /* ALEF */ 118 *ab = 0xFB2Eu; 119 found = true; 120 } 121 break; 122 case 0x05B8u: /* QAMATS */ 123 if (a == 0x05D0u) { /* ALEF */ 124 *ab = 0xFB2Fu; 125 found = true; 126 } 127 break; 128 case 0x05B9u: /* HOLAM */ 129 if (a == 0x05D5u) { /* VAV */ 130 *ab = 0xFB4Bu; 131 found = true; 132 } 133 break; 134 case 0x05BCu: /* DAGESH */ 135 if (a >= 0x05D0u && a <= 0x05EAu) { 136 *ab = sDageshForms[a - 0x05D0u]; 137 found = (*ab != 0); 138 } else if (a == 0xFB2Au) { /* SHIN WITH SHIN DOT */ 139 *ab = 0xFB2Cu; 140 found = true; 141 } else if (a == 0xFB2Bu) { /* SHIN WITH SIN DOT */ 142 *ab = 0xFB2Du; 143 found = true; 144 } 145 break; 146 case 0x05BFu: /* RAFE */ 147 switch (a) { 148 case 0x05D1u: /* BET */ 149 *ab = 0xFB4Cu; 150 found = true; 151 break; 152 case 0x05DBu: /* KAF */ 153 *ab = 0xFB4Du; 154 found = true; 155 break; 156 case 0x05E4u: /* PE */ 157 *ab = 0xFB4Eu; 158 found = true; 159 break; 160 } 161 break; 162 case 0x05C1u: /* SHIN DOT */ 163 if (a == 0x05E9u) { /* SHIN */ 164 *ab = 0xFB2Au; 165 found = true; 166 } else if (a == 0xFB49u) { /* SHIN WITH DAGESH */ 167 *ab = 0xFB2Cu; 168 found = true; 169 } 170 break; 171 case 0x05C2u: /* SIN DOT */ 172 if (a == 0x05E9u) { /* SHIN */ 173 *ab = 0xFB2Bu; 174 found = true; 175 } else if (a == 0xFB49u) { /* SHIN WITH DAGESH */ 176 *ab = 0xFB2Du; 177 found = true; 178 } 179 break; 180 } 181 } 182 183 return found; 184 } 185 186 187 const hb_ot_complex_shaper_t _hb_ot_complex_shaper_hebrew = 188 { 189 "hebrew", 190 NULL, /* collect_features */ 191 NULL, /* override_features */ 192 NULL, /* data_create */ 193 NULL, /* data_destroy */ 194 NULL, /* preprocess_text */ 195 HB_OT_SHAPE_NORMALIZATION_MODE_DEFAULT, 196 NULL, /* decompose */ 197 compose_hebrew, 198 NULL, /* setup_masks */ 199 HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_LATE, 200 true, /* fallback_position */ 201 };