../3rdparty/harfbuzz/src/harfbuzz-hangul.c

Source codeSwitch to Preprocessed file
LineSource CodeCoverage
1/* -
2 * Copyright (C) 2013 Digia Plc and/or its subsidiary(-ies) -
3 * -
4 * This is part of HarfBuzz, an OpenType Layout engine library. -
5 * -
6 * Permission is hereby granted, without written agreement and without -
7 * license or royalty fees, to use, copy, modify, and distribute this -
8 * software and its documentation for any purpose, provided that the -
9 * above copyright notice and the following two paragraphs appear in -
10 * all copies of this software. -
11 * -
12 * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR -
13 * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES -
14 * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN -
15 * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -
16 * DAMAGE. -
17 * -
18 * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, -
19 * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND -
20 * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS -
21 * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO -
22 * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. -
23 */ -
24 -
25#include "harfbuzz-shaper.h" -
26#include "harfbuzz-shaper-private.h" -
27 -
28#include <assert.h> -
29 -
30/* -
31// Hangul is a syllable based script. Unicode reserves a large range -
32// for precomposed hangul, where syllables are already precomposed to -
33// their final glyph shape. In addition, a so called jamo range is -
34// defined, that can be used to express old Hangul. Modern hangul -
35// syllables can also be expressed as jamo, and should be composed -
36// into syllables. The operation is rather simple and mathematical. -
37 -
38// Every hangul jamo is classified as being either a Leading consonant -
39// (L), and intermediat Vowel (V) or a trailing consonant (T). Modern -
40// hangul syllables (the ones in the precomposed area can be of type -
41// LV or LVT. -
42// -
43// Syllable breaks do _not_ occur between: -
44// -
45// L L, V or precomposed -
46// V, LV V, T -
47// LVT, T T -
48// -
49// A standard syllable is of the form L+V+T*. The above rules allow -
50// nonstandard syllables L*V*T*. To transform them into standard -
51// syllables fill characters L_f and V_f can be inserted. -
52*/ -
53 -
54enum { -
55 Hangul_SBase = 0xac00, -
56 Hangul_LBase = 0x1100, -
57 Hangul_VBase = 0x1161, -
58 Hangul_TBase = 0x11a7, -
59 Hangul_SCount = 11172, -
60 Hangul_LCount = 19, -
61 Hangul_VCount = 21, -
62 Hangul_TCount = 28, -
63 Hangul_NCount = 21*28 -
64}; -
65 -
66#define hangul_isPrecomposed(uc) \ -
67 (uc >= Hangul_SBase && uc < Hangul_SBase + Hangul_SCount) -
68 -
69#define hangul_isLV(uc) \ -
70 ((uc - Hangul_SBase) % Hangul_TCount == 0) -
71 -
72typedef enum { -
73 L, -
74 V, -
75 T, -
76 LV, -
77 LVT, -
78 X -
79} HangulType; -
80 -
81static HangulType hangul_type(unsigned short uc) { -
82 if (uc > Hangul_SBase && uc < Hangul_SBase + Hangul_SCount)
evaluated: uc > Hangul_SBase
TRUEFALSE
yes
Evaluation Count:28
yes
Evaluation Count:8
partially evaluated: uc < Hangul_SBase + Hangul_SCount
TRUEFALSE
yes
Evaluation Count:28
no
Evaluation Count:0
0-28
83 return hangul_isLV(uc) ? LV : LVT;
executed: return ((uc - Hangul_SBase) % Hangul_TCount == 0) ? LV : LVT;
Execution Count:28
28
84 if (uc < Hangul_LBase || uc > 0x11ff)
partially evaluated: uc < Hangul_LBase
TRUEFALSE
yes
Evaluation Count:8
no
Evaluation Count:0
never evaluated: uc > 0x11ff
0-8
85 return X;
executed: return X;
Execution Count:8
8
86 if (uc < Hangul_VBase)
never evaluated: uc < Hangul_VBase
0
87 return L;
never executed: return L;
0
88 if (uc < Hangul_TBase)
never evaluated: uc < Hangul_TBase
0
89 return V;
never executed: return V;
0
90 return T;
never executed: return T;
0
91} -
92 -
93static int hangul_nextSyllableBoundary(const HB_UChar16 *s, int start, int end) -
94{ -
95 const HB_UChar16 *uc = s + start;
executed (the execution status of this line is deduced): const HB_UChar16 *uc = s + start;
-
96 -
97 HangulType state = hangul_type(*uc);
executed (the execution status of this line is deduced): HangulType state = hangul_type(*uc);
-
98 int pos = 1;
executed (the execution status of this line is deduced): int pos = 1;
-
99 -
100 while (pos < end - start) {
evaluated: pos < end - start
TRUEFALSE
yes
Evaluation Count:16
yes
Evaluation Count:4
4-16
101 HangulType newState = hangul_type(uc[pos]);
executed (the execution status of this line is deduced): HangulType newState = hangul_type(uc[pos]);
-
102 switch(newState) { -
103 case X: -
104 goto finish;
executed: goto finish;
Execution Count:4
4
105 case L: -
106 case V: -
107 case T: -
108 if (state > newState)
never evaluated: state > newState
0
109 goto finish;
never executed: goto finish;
0
110 state = newState;
never executed (the execution status of this line is deduced): state = newState;
-
111 break;
never executed: break;
0
112 case LV: -
113 if (state > L)
partially evaluated: state > L
TRUEFALSE
yes
Evaluation Count:8
no
Evaluation Count:0
0-8
114 goto finish;
executed: goto finish;
Execution Count:8
8
115 state = V;
never executed (the execution status of this line is deduced): state = V;
-
116 break;
never executed: break;
0
117 case LVT: -
118 if (state > L)
partially evaluated: state > L
TRUEFALSE
yes
Evaluation Count:4
no
Evaluation Count:0
0-4
119 goto finish;
executed: goto finish;
Execution Count:4
4
120 state = T;
never executed (the execution status of this line is deduced): state = T;
-
121 }
never executed: }
0
122 ++pos;
never executed (the execution status of this line is deduced): ++pos;
-
123 }
never executed: }
0
124 -
125 finish: -
126 return start+pos;
executed: return start+pos;
Execution Count:20
20
127} -
128 -
129#ifndef NO_OPENTYPE -
130static const HB_OpenTypeFeature hangul_features [] = { -
131 { HB_MAKE_TAG('c', 'c', 'm', 'p'), CcmpProperty }, -
132 { HB_MAKE_TAG('l', 'j', 'm', 'o'), CcmpProperty }, -
133 { HB_MAKE_TAG('v', 'j', 'm', 'o'), CcmpProperty }, -
134 { HB_MAKE_TAG('t', 'j', 'm', 'o'), CcmpProperty }, -
135 { 0, 0 } -
136}; -
137#endif -
138 -
139static HB_Bool hangul_shape_syllable(HB_ShaperItem *item, HB_Bool openType) -
140{ -
141 const HB_UChar16 *ch = item->string + item->item.pos;
executed (the execution status of this line is deduced): const HB_UChar16 *ch = item->string + item->item.pos;
-
142 int len = item->item.length;
executed (the execution status of this line is deduced): int len = item->item.length;
-
143#ifndef NO_OPENTYPE -
144 const int availableGlyphs = item->num_glyphs;
executed (the execution status of this line is deduced): const int availableGlyphs = item->num_glyphs;
-
145#endif -
146 -
147 int i;
executed (the execution status of this line is deduced): int i;
-
148 HB_UChar16 composed = 0;
executed (the execution status of this line is deduced): HB_UChar16 composed = 0;
-
149 /* see if we can compose the syllable into a modern hangul */ -
150 if (item->item.length == 2) {
partially evaluated: item->item.length == 2
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:20
0-20
151 int LIndex = ch[0] - Hangul_LBase;
never executed (the execution status of this line is deduced): int LIndex = ch[0] - Hangul_LBase;
-
152 int VIndex = ch[1] - Hangul_VBase;
never executed (the execution status of this line is deduced): int VIndex = ch[1] - Hangul_VBase;
-
153 if (LIndex >= 0 && LIndex < Hangul_LCount &&
never evaluated: LIndex >= 0
never evaluated: LIndex < Hangul_LCount
0
154 VIndex >= 0 && VIndex < Hangul_VCount)
never evaluated: VIndex >= 0
never evaluated: VIndex < Hangul_VCount
0
155 composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + Hangul_SBase;
never executed: composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + Hangul_SBase;
0
156 } else if (item->item.length == 3) {
never executed: }
partially evaluated: item->item.length == 3
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:20
0-20
157 int LIndex = ch[0] - Hangul_LBase;
never executed (the execution status of this line is deduced): int LIndex = ch[0] - Hangul_LBase;
-
158 int VIndex = ch[1] - Hangul_VBase;
never executed (the execution status of this line is deduced): int VIndex = ch[1] - Hangul_VBase;
-
159 int TIndex = ch[2] - Hangul_TBase;
never executed (the execution status of this line is deduced): int TIndex = ch[2] - Hangul_TBase;
-
160 if (LIndex >= 0 && LIndex < Hangul_LCount &&
never evaluated: LIndex >= 0
never evaluated: LIndex < Hangul_LCount
0
161 VIndex >= 0 && VIndex < Hangul_VCount &&
never evaluated: VIndex >= 0
never evaluated: VIndex < Hangul_VCount
0
162 TIndex >= 0 && TIndex < Hangul_TCount)
never evaluated: TIndex >= 0
never evaluated: TIndex < Hangul_TCount
0
163 composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + TIndex + Hangul_SBase;
never executed: composed = (LIndex * Hangul_VCount + VIndex) * Hangul_TCount + TIndex + Hangul_SBase;
0
164 }
never executed: }
0
165 -
166 -
167 -
168 /* if we have a modern hangul use the composed form */ -
169 if (composed) {
partially evaluated: composed
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:20
0-20
170 ch = &composed;
never executed (the execution status of this line is deduced): ch = &composed;
-
171 len = 1;
never executed (the execution status of this line is deduced): len = 1;
-
172 }
never executed: }
0
173 -
174 if (!item->font->klass->convertStringToGlyphIndices(item->font,
partially evaluated: !item->font->klass->convertStringToGlyphIndices(item->font, ch, len, item->glyphs, &item->num_glyphs, item->item.bidiLevel % 2)
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:20
0-20
175 ch, len,
partially evaluated: !item->font->klass->convertStringToGlyphIndices(item->font, ch, len, item->glyphs, &item->num_glyphs, item->item.bidiLevel % 2)
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:20
0-20
176 item->glyphs, &item->num_glyphs,
partially evaluated: !item->font->klass->convertStringToGlyphIndices(item->font, ch, len, item->glyphs, &item->num_glyphs, item->item.bidiLevel % 2)
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:20
0-20
177 item->item.bidiLevel % 2))
partially evaluated: !item->font->klass->convertStringToGlyphIndices(item->font, ch, len, item->glyphs, &item->num_glyphs, item->item.bidiLevel % 2)
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:20
0-20
178 return FALSE;
never executed: return 0;
0
179 for (i = 0; i < len; i++) {
evaluated: i < len
TRUEFALSE
yes
Evaluation Count:20
yes
Evaluation Count:20
20
180 item->attributes[i].mark = FALSE;
executed (the execution status of this line is deduced): item->attributes[i].mark = 0;
-
181 item->attributes[i].clusterStart = FALSE;
executed (the execution status of this line is deduced): item->attributes[i].clusterStart = 0;
-
182 item->attributes[i].justification = 0;
executed (the execution status of this line is deduced): item->attributes[i].justification = 0;
-
183 item->attributes[i].zeroWidth = FALSE;
executed (the execution status of this line is deduced): item->attributes[i].zeroWidth = 0;
-
184 /*IDEBUG(" %d: %4x", i, ch[i].unicode()); */ -
185 }
executed: }
Execution Count:20
20
186 -
187#ifndef NO_OPENTYPE -
188 if (!composed && openType) {
partially evaluated: !composed
TRUEFALSE
yes
Evaluation Count:20
no
Evaluation Count:0
partially evaluated: openType
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:20
0-20
189 HB_Bool positioned;
never executed (the execution status of this line is deduced): HB_Bool positioned;
-
190 -
191 HB_STACKARRAY(unsigned short, logClusters, len);
never executed: logClusters = (unsigned short *)malloc((len) * sizeof(unsigned short));
never evaluated: (len) >= 512
0
192 for (i = 0; i < len; ++i)
never evaluated: i < len
0
193 logClusters[i] = i;
never executed: logClusters[i] = i;
0
194 item->log_clusters = logClusters;
never executed (the execution status of this line is deduced): item->log_clusters = logClusters;
-
195 -
196 HB_OpenTypeShape(item, /*properties*/0);
never executed (the execution status of this line is deduced): HB_OpenTypeShape(item, 0);
-
197 -
198 positioned = HB_OpenTypePosition(item, availableGlyphs, /*doLogClusters*/FALSE);
never executed (the execution status of this line is deduced): positioned = HB_OpenTypePosition(item, availableGlyphs, 0);
-
199 -
200 HB_FREE_STACKARRAY(logClusters);
never executed: free(logClusters);
never evaluated: stacklogClusters != logClusters
0
201 -
202 if (!positioned)
never evaluated: !positioned
0
203 return FALSE;
never executed: return 0;
0
204 } else {
never executed: }
0
205 HB_HeuristicPosition(item);
executed (the execution status of this line is deduced): HB_HeuristicPosition(item);
-
206 }
executed: }
Execution Count:20
20
207#endif -
208 -
209 item->attributes[0].clusterStart = TRUE;
executed (the execution status of this line is deduced): item->attributes[0].clusterStart = (!0);
-
210 return TRUE;
executed: return (!0);
Execution Count:20
20
211} -
212 -
213HB_Bool HB_HangulShape(HB_ShaperItem *item) -
214{ -
215 const HB_UChar16 *uc = item->string + item->item.pos;
executed (the execution status of this line is deduced): const HB_UChar16 *uc = item->string + item->item.pos;
-
216 HB_Bool allPrecomposed = TRUE;
executed (the execution status of this line is deduced): HB_Bool allPrecomposed = (!0);
-
217 int i;
executed (the execution status of this line is deduced): int i;
-
218 -
219 assert(item->item.script == HB_Script_Hangul);
executed (the execution status of this line is deduced): ((item->item.script == HB_Script_Hangul) ? static_cast<void> (0) : __assert_fail ("item->item.script == HB_Script_Hangul", "../3rdparty/harfbuzz/src/harfbuzz-hangul.c", 219, __PRETTY_FUNCTION__));
-
220 -
221 for (i = 0; i < (int)item->item.length; ++i) {
evaluated: i < (int)item->item.length
TRUEFALSE
yes
Evaluation Count:96
yes
Evaluation Count:28
28-96
222 if (!hangul_isPrecomposed(uc[i])) {
evaluated: uc[i] >= Hangul_SBase
TRUEFALSE
yes
Evaluation Count:92
yes
Evaluation Count:4
partially evaluated: uc[i] < Hangul_SBase + Hangul_SCount
TRUEFALSE
yes
Evaluation Count:92
no
Evaluation Count:0
0-92
223 allPrecomposed = FALSE;
executed (the execution status of this line is deduced): allPrecomposed = 0;
-
224 break;
executed: break;
Execution Count:4
4
225 } -
226 }
executed: }
Execution Count:92
92
227 -
228 if (!allPrecomposed) {
evaluated: !allPrecomposed
TRUEFALSE
yes
Evaluation Count:4
yes
Evaluation Count:28
4-28
229 HB_Bool openType = FALSE;
executed (the execution status of this line is deduced): HB_Bool openType = 0;
-
230 unsigned short *logClusters = item->log_clusters;
executed (the execution status of this line is deduced): unsigned short *logClusters = item->log_clusters;
-
231 HB_ShaperItem syllable;
executed (the execution status of this line is deduced): HB_ShaperItem syllable;
-
232 int first_glyph = 0;
executed (the execution status of this line is deduced): int first_glyph = 0;
-
233 int sstart = item->item.pos;
executed (the execution status of this line is deduced): int sstart = item->item.pos;
-
234 int end = sstart + item->item.length;
executed (the execution status of this line is deduced): int end = sstart + item->item.length;
-
235 -
236#ifndef NO_OPENTYPE -
237 openType = HB_SelectScript(item, hangul_features);
executed (the execution status of this line is deduced): openType = HB_SelectScript(item, hangul_features);
-
238#endif -
239 syllable = *item;
executed (the execution status of this line is deduced): syllable = *item;
-
240 -
241 while (sstart < end) {
evaluated: sstart < end
TRUEFALSE
yes
Evaluation Count:20
yes
Evaluation Count:4
4-20
242 int send = hangul_nextSyllableBoundary(item->string, sstart, end);
executed (the execution status of this line is deduced): int send = hangul_nextSyllableBoundary(item->string, sstart, end);
-
243 -
244 syllable.item.pos = sstart;
executed (the execution status of this line is deduced): syllable.item.pos = sstart;
-
245 syllable.item.length = send-sstart;
executed (the execution status of this line is deduced): syllable.item.length = send-sstart;
-
246 syllable.glyphs = item->glyphs + first_glyph;
executed (the execution status of this line is deduced): syllable.glyphs = item->glyphs + first_glyph;
-
247 syllable.attributes = item->attributes + first_glyph;
executed (the execution status of this line is deduced): syllable.attributes = item->attributes + first_glyph;
-
248 syllable.offsets = item->offsets + first_glyph;
executed (the execution status of this line is deduced): syllable.offsets = item->offsets + first_glyph;
-
249 syllable.advances = item->advances + first_glyph;
executed (the execution status of this line is deduced): syllable.advances = item->advances + first_glyph;
-
250 syllable.num_glyphs = item->num_glyphs - first_glyph;
executed (the execution status of this line is deduced): syllable.num_glyphs = item->num_glyphs - first_glyph;
-
251 if (!hangul_shape_syllable(&syllable, openType)) {
partially evaluated: !hangul_shape_syllable(&syllable, openType)
TRUEFALSE
no
Evaluation Count:0
yes
Evaluation Count:20
0-20
252 item->num_glyphs += syllable.num_glyphs;
never executed (the execution status of this line is deduced): item->num_glyphs += syllable.num_glyphs;
-
253 return FALSE;
never executed: return 0;
0
254 } -
255 /* fix logcluster array */ -
256 for (i = sstart; i < send; ++i)
evaluated: i < send
TRUEFALSE
yes
Evaluation Count:20
yes
Evaluation Count:20
20
257 logClusters[i-item->item.pos] = first_glyph;
executed: logClusters[i-item->item.pos] = first_glyph;
Execution Count:20
20
258 sstart = send;
executed (the execution status of this line is deduced): sstart = send;
-
259 first_glyph += syllable.num_glyphs;
executed (the execution status of this line is deduced): first_glyph += syllable.num_glyphs;
-
260 }
executed: }
Execution Count:20
20
261 item->num_glyphs = first_glyph;
executed (the execution status of this line is deduced): item->num_glyphs = first_glyph;
-
262 return TRUE;
executed: return (!0);
Execution Count:4
4
263 } -
264 -
265 return HB_BasicShape(item);
executed: return HB_BasicShape(item);
Execution Count:28
28
266} -
267 -
268 -
269 -
Source codeSwitch to Preprocessed file

Generated by Squish Coco Non-Commercial