1/* Canonical composition of Unicode characters. 2 Copyright (C) 2002, 2006, 2009-2010 Free Software Foundation, Inc. 3 Written by Bruno Haible <bruno@clisp.org>, 2009. 4 5 This program is free software: you can redistribute it and/or modify it 6 under the terms of the GNU Lesser General Public License as published 7 by the Free Software Foundation; either version 3 of the License, or 8 (at your option) any later version. 9 10 This program is distributed in the hope that it will be useful, 11 but WITHOUT ANY WARRANTY; without even the implied warranty of 12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 13 Lesser General Public License for more details. 14 15 You should have received a copy of the GNU Lesser General Public License 16 along with this program. If not, see <http://www.gnu.org/licenses/>. */ 17 18#include <config.h> 19 20/* Specification. */ 21#include "uninorm.h" 22 23#include <string.h> 24 25struct composition_rule { char codes[4]; unsigned short combined; }; 26 27#include "composition-table.h" 28 29ucs4_t 30uc_composition (ucs4_t uc1, ucs4_t uc2) 31{ 32 if (uc1 < 0x10000 && uc2 < 0x10000) 33 { 34 if (uc2 >= 0x1161 && uc2 < 0x1161 + 21 35 && uc1 >= 0x1100 && uc1 < 0x1100 + 19) 36 { 37 /* Hangul: Combine single letter L and single letter V to form 38 two-letter syllable LV. */ 39 return 0xAC00 + ((uc1 - 0x1100) * 21 + (uc2 - 0x1161)) * 28; 40 } 41 else if (uc2 > 0x11A7 && uc2 < 0x11A7 + 28 42 && uc1 >= 0xAC00 && uc1 < 0xD7A4 && ((uc1 - 0xAC00) % 28) == 0) 43 { 44 /* Hangul: Combine two-letter syllable LV with single-letter T 45 to form three-letter syllable LVT. */ 46 return uc1 + (uc2 - 0x11A7); 47 } 48 else 49 { 50#if 0 51 unsigned int uc = MUL1 * uc1 * MUL2 * uc2; 52 unsigned int index1 = uc >> composition_header_0; 53 if (index1 < composition_header_1) 54 { 55 int lookup1 = u_composition.level1[index1]; 56 if (lookup1 >= 0) 57 { 58 unsigned int index2 = (uc >> composition_header_2) & composition_header_3; 59 int lookup2 = u_composition.level2[lookup1 + index2]; 60 if (lookup2 >= 0) 61 { 62 unsigned int index3 = (uc & composition_header_4); 63 unsigned int lookup3 = u_composition.level3[lookup2 + index3]; 64 if ((lookup3 >> 16) == uc2) 65 return lookup3 & ((1U << 16) - 1); 66 } 67 } 68 } 69#else 70 char codes[4]; 71 const struct composition_rule *rule; 72 73 codes[0] = (uc1 >> 8) & 0xff; 74 codes[1] = uc1 & 0xff; 75 codes[2] = (uc2 >> 8) & 0xff; 76 codes[3] = uc2 & 0xff; 77 78 rule = gl_uninorm_compose_lookup (codes, 4); 79 if (rule != NULL) 80 return rule->combined; 81#endif 82 } 83 } 84 return 0; 85} 86