bug 941470 - update harfbuzz to latest upstream commit (205bf834...), to pick up plan-caching for user features and misc fixes. r=jdaggett

This commit is contained in:
Jonathan Kew 2013-12-04 07:07:44 +00:00
parent be1c082725
commit 607557da7d
19 changed files with 659 additions and 323 deletions

View File

@ -78,7 +78,7 @@ typedef int32_t hb_atomic_int_t;
#if (MAC_OS_X_VERSION_MIN_REQUIRED > MAC_OS_X_VERSION_10_4 || __IPHONE_VERSION_MIN_REQUIRED >= 20100)
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwapPtrBarrier ((void *) (O), (void *) (N), (void **) (P))
#else
#if __ppc64__ || __x86_64__
#if __ppc64__ || __x86_64__ || __arm64__
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap64Barrier ((int64_t) (O), (int64_t) (N), (int64_t*) (P))
#else
#define hb_atomic_ptr_cmpexch(P,O,N) OSAtomicCompareAndSwap32Barrier ((int32_t) (O), (int32_t) (N), (int32_t*) (P))

View File

@ -181,12 +181,13 @@ struct hb_buffer_t {
HB_INTERNAL bool enlarge (unsigned int size);
inline bool ensure (unsigned int size)
{ return likely (size < allocated) ? true : enlarge (size); }
{ return likely (!size || size < allocated) ? true : enlarge (size); }
HB_INTERNAL bool make_room_for (unsigned int num_in, unsigned int num_out);
HB_INTERNAL bool shift_forward (unsigned int count);
HB_INTERNAL void *get_scratch_buffer (unsigned int *size);
typedef long scratch_buffer_t;
HB_INTERNAL scratch_buffer_t *get_scratch_buffer (unsigned int *size);
inline void clear_context (unsigned int side) { context_len[side] = 0; }
};

View File

@ -152,7 +152,7 @@ hb_buffer_t::shift_forward (unsigned int count)
return true;
}
void *
hb_buffer_t::scratch_buffer_t *
hb_buffer_t::get_scratch_buffer (unsigned int *size)
{
have_output = false;
@ -161,8 +161,9 @@ hb_buffer_t::get_scratch_buffer (unsigned int *size)
out_len = 0;
out_info = info;
*size = allocated * sizeof (pos[0]);
return pos;
assert ((uintptr_t) pos % sizeof (scratch_buffer_t) == 0);
*size = allocated * sizeof (pos[0]) / sizeof (scratch_buffer_t);
return (scratch_buffer_t *) (void *) pos;
}
@ -1149,7 +1150,10 @@ hb_buffer_set_length (hb_buffer_t *buffer,
buffer->len = length;
if (!length)
{
buffer->content_type = HB_BUFFER_CONTENT_TYPE_INVALID;
buffer->clear_context (0);
}
buffer->clear_context (1);
return true;

View File

@ -394,6 +394,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
unsigned int num_features)
{
hb_face_t *face = font->face;
hb_coretext_shaper_face_data_t *face_data = HB_SHAPER_DATA_GET (face);
hb_coretext_shaper_font_data_t *font_data = HB_SHAPER_DATA_GET (font);
/*
@ -553,11 +554,21 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
} HB_STMT_END;
unsigned int scratch_size;
char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
#define ALLOCATE_ARRAY(Type, name, len) \
Type *name = (Type *) scratch; \
{ \
unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
assert (_consumed <= scratch_size); \
scratch += _consumed; \
scratch_size -= _consumed; \
}
#define utf16_index() var1.u32
UniChar *pchars = (UniChar *) scratch;
ALLOCATE_ARRAY (UniChar, pchars, buffer->len * 2);
unsigned int chars_len = 0;
for (unsigned int i = 0; i < buffer->len; i++) {
hb_codepoint_t c = buffer->info[i].codepoint;
@ -586,7 +597,7 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
if (num_features)
{
unsigned int *log_clusters = (unsigned int *) (pchars + chars_len);
ALLOCATE_ARRAY (unsigned int, log_clusters, chars_len);
/* Need log_clusters to assign features. */
chars_len = 0;
@ -638,26 +649,60 @@ _hb_coretext_shape (hb_shape_plan_t *shape_plan,
const CFRange range_all = CFRangeMake (0, 0);
for (unsigned int i = 0; i < num_runs; i++) {
for (unsigned int i = 0; i < num_runs; i++)
{
CTRunRef run = (CTRunRef) CFArrayGetValueAtIndex (glyph_runs, i);
/* CoreText does automatic font fallback (AKA "cascading") for characters
* not supported by the requested font, and provides no way to turn it off,
* so we detect if the returned run uses a font other than the requested
* one and fill in the buffer with .notdef glyphs instead of random glyph
* indices from a different font.
*/
CFDictionaryRef attributes = CTRunGetAttributes (run);
CTFontRef run_ct_font = static_cast<CTFontRef>(CFDictionaryGetValue (attributes, kCTFontAttributeName));
CGFontRef run_cg_font = CTFontCopyGraphicsFont (run_ct_font, 0);
if (!CFEqual (run_cg_font, face_data->cg_font))
{
CFRelease (run_cg_font);
CFRange range = CTRunGetStringRange (run);
buffer->ensure (buffer->len + range.length);
if (buffer->in_error)
FAIL ("Buffer resize failed");
hb_glyph_info_t *info = buffer->info + buffer->len;
buffer->len += range.length;
for (CFIndex j = 0; j < range.length; j++)
{
CGGlyph notdef = 0;
double advance = CTFontGetAdvancesForGlyphs (font_data->ct_font, kCTFontHorizontalOrientation, &notdef, NULL, 1);
info->codepoint = notdef;
/* TODO We have to fixup clusters later. See vis_clusters in
* hb-uniscribe.cc for example. */
info->cluster = range.location + j;
info->mask = advance;
info->var1.u32 = 0;
info->var2.u32 = 0;
info++;
}
continue;
}
CFRelease (run_cg_font);
unsigned int num_glyphs = CTRunGetGlyphCount (run);
if (num_glyphs == 0)
continue;
buffer->ensure (buffer->len + num_glyphs);
/* Testing indicates that CTRunGetGlyphsPtr (almost?) always succeeds,
* and so copying data to our own buffer with CTRunGetGlyphs will be
* extremely rare. */
scratch = buffer->get_scratch_buffer (&scratch_size);
unsigned int scratch_size;
char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
#define ALLOCATE_ARRAY(Type, name, len) \
Type *name = (Type *) scratch; \
scratch += (len) * sizeof ((name)[0]); \
scratch_size -= (len) * sizeof ((name)[0]);
/* Testing indicates that CTRunGetGlyphsPtr, etc (almost?) always
* succeed, and so copying data to our own buffer will be rare. */
const CGGlyph* glyphs = CTRunGetGlyphsPtr (run);
if (!glyphs) {

View File

@ -95,6 +95,16 @@ _hb_fallback_shape (hb_shape_plan_t *shape_plan HB_UNUSED,
const hb_feature_t *features HB_UNUSED,
unsigned int num_features HB_UNUSED)
{
/* TODO
*
* - Apply fallback kern.
* - Handle Variation Selectors?
* - Apply normalization?
*
* This will make the fallback shaper into a dumb "TrueType"
* shaper which many people unfortunately still request.
*/
hb_codepoint_t space;
font->get_glyph (' ', 0, &space);

View File

@ -118,12 +118,12 @@ struct hb_font_t {
/* Convert from parent-font user-space to our user-space */
inline hb_position_t parent_scale_x_distance (hb_position_t v) {
if (unlikely (parent && parent->x_scale != x_scale))
return v * (int64_t) this->x_scale / this->parent->x_scale;
return (hb_position_t) (v * (int64_t) this->x_scale / this->parent->x_scale);
return v;
}
inline hb_position_t parent_scale_y_distance (hb_position_t v) {
if (unlikely (parent && parent->y_scale != y_scale))
return v * (int64_t) this->y_scale / this->parent->y_scale;
return (hb_position_t) (v * (int64_t) this->y_scale / this->parent->y_scale);
return v;
}
inline hb_position_t parent_scale_x_position (hb_position_t v) {
@ -397,7 +397,7 @@ struct hb_font_t {
}
private:
inline hb_position_t em_scale (int16_t v, int scale) { return v * (int64_t) scale / face->get_upem (); }
inline hb_position_t em_scale (int16_t v, int scale) { return (hb_position_t) (v * (int64_t) scale / face->get_upem ()); }
};
#define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS

View File

@ -418,8 +418,8 @@ hb_ft_font_create (FT_Face ft_face,
_hb_ft_get_font_funcs (),
ft_face, (hb_destroy_func_t) _do_nothing);
hb_font_set_scale (font,
((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16,
((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16);
(int) (((uint64_t) ft_face->size->metrics.x_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16),
(int) (((uint64_t) ft_face->size->metrics.y_scale * (uint64_t) ft_face->units_per_EM + (1<<15)) >> 16));
hb_font_set_ppem (font,
ft_face->size->metrics.x_ppem,
ft_face->size->metrics.y_ppem);

View File

@ -243,14 +243,9 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
float curradvx = 0., curradvy = 0.;
unsigned int scratch_size;
char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
#define ALLOCATE_ARRAY(Type, name, len) \
Type *name = (Type *) scratch; \
scratch += (len) * sizeof ((name)[0]); \
scratch_size -= (len) * sizeof ((name)[0]);
ALLOCATE_ARRAY (uint32_t, chars, buffer->len);
uint32_t *chars = (uint32_t *) scratch;
for (unsigned int i = 0; i < buffer->len; ++i)
chars[i] = buffer->info[i].codepoint;
@ -276,9 +271,9 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
return false;
}
scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
while ((sizeof (hb_graphite2_cluster_t) * buffer->len +
sizeof (hb_codepoint_t) * glyph_count) > scratch_size)
scratch = buffer->get_scratch_buffer (&scratch_size);
while ((DIV_CEIL (sizeof (hb_graphite2_cluster_t) * buffer->len, sizeof (*scratch)) +
DIV_CEIL (sizeof (hb_codepoint_t) * glyph_count, sizeof (*scratch))) > scratch_size)
{
buffer->ensure (buffer->allocated * 2);
if (unlikely (buffer->in_error)) {
@ -286,12 +281,23 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
gr_seg_destroy (seg);
return false;
}
scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
scratch = buffer->get_scratch_buffer (&scratch_size);
}
#define ALLOCATE_ARRAY(Type, name, len) \
Type *name = (Type *) scratch; \
{ \
unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
assert (_consumed <= scratch_size); \
scratch += _consumed; \
scratch_size -= _consumed; \
}
ALLOCATE_ARRAY (hb_graphite2_cluster_t, clusters, buffer->len);
ALLOCATE_ARRAY (hb_codepoint_t, gids, glyph_count);
#undef ALLOCATE_ARRAY
memset (clusters, 0, sizeof (clusters[0]) * buffer->len);
hb_codepoint_t *pg = gids;

View File

@ -377,7 +377,7 @@ struct FeatureParamsStylisticSet
return TRACE_RETURN (c->check_struct (this));
}
USHORT minorVersion; /* (set to 0): This corresponds to a “minor”
USHORT version; /* (set to 0): This corresponds to a “minor”
* version number. Additional data may be
* added to the end of this Feature Parameters
* table in the future. */
@ -400,6 +400,7 @@ struct FeatureParamsStylisticSet
DEFINE_SIZE_STATIC (4);
};
/* http://www.microsoft.com/typography/otspec/features_ae.htm#cv01-cv99 */
struct FeatureParamsCharacterVariants
{
inline bool sanitize (hb_sanitize_context_t *c) {
@ -1112,7 +1113,7 @@ struct Device
if (!pixels) return 0;
return pixels * (int64_t) scale / ppem;
return (int) (pixels * (int64_t) scale / ppem);
}

View File

@ -34,196 +34,197 @@
#line 36 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
static const unsigned char _myanmar_syllable_machine_trans_keys[] = {
1u, 30u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
1u, 31u, 3u, 30u, 5u, 29u, 5u, 8u, 5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 1u, 16u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 5u, 29u, 5u, 8u,
5u, 29u, 3u, 25u, 5u, 25u, 5u, 25u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 30u, 3u, 29u, 1u, 30u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u,
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 0
3u, 29u, 3u, 29u, 3u, 29u, 3u, 29u, 8u, 8u, 0
};
static const char _myanmar_syllable_machine_key_spans[] = {
30, 28, 25, 4, 25, 23, 21, 21,
31, 28, 25, 4, 25, 23, 21, 21,
27, 27, 27, 27, 16, 27, 27, 27,
27, 27, 27, 27, 27, 27, 25, 4,
25, 23, 21, 21, 27, 27, 27, 27,
28, 27, 30, 27, 27, 27, 27, 27,
27, 27, 27, 27
27, 27, 27, 27, 1
};
static const short _myanmar_syllable_machine_index_offsets[] = {
0, 31, 60, 86, 91, 117, 141, 163,
185, 213, 241, 269, 297, 314, 342, 370,
398, 426, 454, 482, 510, 538, 566, 592,
597, 623, 647, 669, 691, 719, 747, 775,
803, 832, 860, 891, 919, 947, 975, 1003,
1031, 1059, 1087, 1115
0, 32, 61, 87, 92, 118, 142, 164,
186, 214, 242, 270, 298, 315, 343, 371,
399, 427, 455, 483, 511, 539, 567, 593,
598, 624, 648, 670, 692, 720, 748, 776,
804, 833, 861, 892, 920, 948, 976, 1004,
1032, 1060, 1088, 1116, 1144
};
static const char _myanmar_syllable_machine_indicies[] = {
1, 1, 2, 3, 4, 4, 0, 5,
0, 6, 0, 1, 0, 0, 0, 7,
0, 8, 1, 0, 9, 10, 11, 12,
13, 14, 15, 16, 17, 18, 0, 20,
21, 22, 22, 19, 23, 19, 24, 19,
19, 19, 19, 19, 19, 19, 25, 19,
19, 26, 27, 28, 29, 30, 31, 32,
33, 34, 35, 19, 22, 22, 19, 23,
19, 19, 19, 19, 19, 19, 19, 19,
19, 36, 19, 19, 19, 19, 19, 19,
30, 19, 19, 19, 34, 19, 22, 22,
19, 23, 19, 22, 22, 19, 23, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 30,
19, 19, 19, 34, 19, 37, 19, 22,
22, 19, 23, 19, 30, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 30, 19, 22, 22, 19,
23, 19, 19, 19, 19, 19, 19, 19,
19, 19, 38, 19, 19, 19, 19, 19,
19, 30, 19, 22, 22, 19, 23, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 30,
19, 20, 19, 22, 22, 19, 23, 19,
24, 19, 19, 19, 19, 19, 19, 19,
39, 19, 19, 39, 19, 19, 19, 30,
40, 19, 19, 34, 19, 20, 19, 22,
22, 19, 23, 19, 24, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 30, 19, 19, 19, 34,
19, 20, 19, 22, 22, 19, 23, 19,
24, 19, 19, 19, 19, 19, 19, 19,
39, 19, 19, 19, 19, 19, 19, 30,
40, 19, 19, 34, 19, 20, 19, 22,
22, 19, 23, 19, 24, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 30, 40, 19, 19, 34,
19, 1, 1, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
1, 19, 20, 19, 22, 22, 19, 23,
19, 24, 19, 19, 19, 19, 19, 19,
19, 25, 19, 19, 26, 27, 28, 29,
30, 31, 32, 33, 34, 19, 20, 19,
22, 22, 19, 23, 19, 24, 19, 19,
19, 19, 19, 19, 19, 33, 19, 19,
19, 19, 19, 19, 30, 31, 32, 33,
34, 19, 20, 19, 22, 22, 19, 23,
19, 24, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
30, 31, 32, 33, 34, 19, 20, 19,
22, 22, 19, 23, 19, 24, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 30, 31, 32, 19,
34, 19, 20, 19, 22, 22, 19, 23,
19, 24, 19, 19, 19, 19, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
30, 19, 32, 19, 34, 19, 20, 19,
22, 22, 19, 23, 19, 24, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
26, 19, 28, 19, 30, 31, 32, 33,
34, 19, 20, 19, 22, 22, 19, 23,
19, 24, 19, 19, 19, 19, 19, 19,
19, 33, 19, 19, 26, 19, 19, 19,
30, 31, 32, 33, 34, 19, 20, 19,
22, 22, 19, 23, 19, 24, 19, 19,
19, 19, 19, 19, 19, 19, 19, 19,
26, 27, 28, 19, 30, 31, 32, 33,
34, 19, 20, 21, 22, 22, 19, 23,
19, 24, 19, 19, 19, 19, 19, 19,
19, 25, 19, 19, 26, 27, 28, 29,
30, 31, 32, 33, 34, 19, 3, 3,
41, 5, 41, 41, 41, 41, 41, 41,
41, 41, 41, 42, 41, 41, 41, 41,
41, 41, 13, 41, 41, 41, 17, 41,
3, 3, 41, 5, 41, 3, 3, 41,
5, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 13, 41, 41, 41, 17, 41, 43,
41, 3, 3, 41, 5, 41, 13, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 13, 41, 3,
3, 41, 5, 41, 41, 41, 41, 41,
41, 41, 41, 41, 44, 41, 41, 41,
41, 41, 41, 13, 41, 3, 3, 41,
5, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 13, 41, 2, 41, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 45, 41, 41, 45, 41, 41,
41, 13, 46, 41, 41, 17, 41, 2,
41, 3, 3, 41, 5, 41, 6, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 13, 41, 41,
41, 17, 41, 2, 41, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 45, 41, 41, 41, 41, 41,
41, 13, 46, 41, 41, 17, 41, 2,
41, 3, 3, 41, 5, 41, 6, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 13, 46, 41,
41, 17, 41, 20, 21, 22, 22, 19,
23, 19, 24, 19, 19, 19, 19, 19,
19, 19, 47, 19, 19, 26, 27, 28,
29, 30, 31, 32, 33, 34, 35, 19,
20, 48, 22, 22, 19, 23, 19, 24,
19, 19, 19, 19, 19, 19, 19, 25,
19, 19, 26, 27, 28, 29, 30, 31,
32, 33, 34, 19, 1, 1, 2, 3,
3, 3, 41, 5, 41, 6, 41, 1,
41, 41, 41, 1, 41, 8, 1, 41,
9, 10, 11, 12, 13, 14, 15, 16,
17, 18, 41, 2, 41, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 8, 41, 41, 9, 10, 11,
12, 13, 14, 15, 16, 17, 41, 2,
41, 3, 3, 41, 5, 41, 6, 41,
41, 41, 41, 41, 41, 41, 16, 41,
41, 41, 41, 41, 41, 13, 14, 15,
16, 17, 41, 2, 41, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 13, 14, 15, 16, 17, 41, 2,
41, 3, 3, 41, 5, 41, 6, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 13, 14, 15,
41, 17, 41, 2, 41, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 13, 41, 15, 41, 17, 41, 2,
41, 3, 3, 41, 5, 41, 6, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 9, 41, 11, 41, 13, 14, 15,
16, 17, 41, 2, 41, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 16, 41, 41, 9, 41, 41,
41, 13, 14, 15, 16, 17, 41, 2,
41, 3, 3, 41, 5, 41, 6, 41,
41, 41, 41, 41, 41, 41, 41, 41,
41, 9, 10, 11, 41, 13, 14, 15,
16, 17, 41, 2, 3, 3, 3, 41,
5, 41, 6, 41, 41, 41, 41, 41,
41, 41, 8, 41, 41, 9, 10, 11,
12, 13, 14, 15, 16, 17, 41, 0
13, 14, 15, 16, 17, 18, 19, 0,
21, 22, 23, 23, 20, 24, 20, 25,
20, 20, 20, 20, 20, 20, 20, 26,
20, 20, 27, 28, 29, 30, 31, 32,
33, 34, 35, 36, 20, 23, 23, 20,
24, 20, 20, 20, 20, 20, 20, 20,
20, 20, 37, 20, 20, 20, 20, 20,
20, 31, 20, 20, 20, 35, 20, 23,
23, 20, 24, 20, 23, 23, 20, 24,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
31, 20, 20, 20, 35, 20, 38, 20,
23, 23, 20, 24, 20, 31, 20, 20,
20, 20, 20, 20, 20, 39, 20, 20,
20, 20, 20, 20, 31, 20, 23, 23,
20, 24, 20, 20, 20, 20, 20, 20,
20, 20, 20, 39, 20, 20, 20, 20,
20, 20, 31, 20, 23, 23, 20, 24,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
31, 20, 21, 20, 23, 23, 20, 24,
20, 25, 20, 20, 20, 20, 20, 20,
20, 40, 20, 20, 40, 20, 20, 20,
31, 41, 20, 20, 35, 20, 21, 20,
23, 23, 20, 24, 20, 25, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 31, 20, 20, 20,
35, 20, 21, 20, 23, 23, 20, 24,
20, 25, 20, 20, 20, 20, 20, 20,
20, 40, 20, 20, 20, 20, 20, 20,
31, 41, 20, 20, 35, 20, 21, 20,
23, 23, 20, 24, 20, 25, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 31, 41, 20, 20,
35, 20, 1, 1, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 1, 20, 21, 20, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 26, 20, 20, 27, 28, 29,
30, 31, 32, 33, 34, 35, 20, 21,
20, 23, 23, 20, 24, 20, 25, 20,
20, 20, 20, 20, 20, 20, 34, 20,
20, 20, 20, 20, 20, 31, 32, 33,
34, 35, 20, 21, 20, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 31, 32, 33, 34, 35, 20, 21,
20, 23, 23, 20, 24, 20, 25, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 31, 32, 33,
20, 35, 20, 21, 20, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 31, 20, 33, 20, 35, 20, 21,
20, 23, 23, 20, 24, 20, 25, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 27, 20, 29, 20, 31, 32, 33,
34, 35, 20, 21, 20, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 34, 20, 20, 27, 20, 20,
20, 31, 32, 33, 34, 35, 20, 21,
20, 23, 23, 20, 24, 20, 25, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 27, 28, 29, 20, 31, 32, 33,
34, 35, 20, 21, 22, 23, 23, 20,
24, 20, 25, 20, 20, 20, 20, 20,
20, 20, 26, 20, 20, 27, 28, 29,
30, 31, 32, 33, 34, 35, 20, 3,
3, 42, 5, 42, 42, 42, 42, 42,
42, 42, 42, 42, 43, 42, 42, 42,
42, 42, 42, 13, 42, 42, 42, 17,
42, 3, 3, 42, 5, 42, 3, 3,
42, 5, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 13, 42, 42, 42, 17, 42,
44, 42, 3, 3, 42, 5, 42, 13,
42, 42, 42, 42, 42, 42, 42, 45,
42, 42, 42, 42, 42, 42, 13, 42,
3, 3, 42, 5, 42, 42, 42, 42,
42, 42, 42, 42, 42, 45, 42, 42,
42, 42, 42, 42, 13, 42, 3, 3,
42, 5, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 13, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 46, 42, 42, 46, 42,
42, 42, 13, 47, 42, 42, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 13, 42,
42, 42, 17, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 46, 42, 42, 42, 42,
42, 42, 13, 47, 42, 42, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 13, 47,
42, 42, 17, 42, 21, 22, 23, 23,
20, 24, 20, 25, 20, 20, 20, 20,
20, 20, 20, 48, 20, 20, 27, 28,
29, 30, 31, 32, 33, 34, 35, 36,
20, 21, 49, 23, 23, 20, 24, 20,
25, 20, 20, 20, 20, 20, 20, 20,
26, 20, 20, 27, 28, 29, 30, 31,
32, 33, 34, 35, 20, 1, 1, 2,
3, 3, 3, 42, 5, 42, 6, 42,
1, 42, 42, 42, 1, 42, 8, 1,
42, 9, 10, 11, 12, 13, 14, 15,
16, 17, 18, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 8, 42, 42, 9, 10,
11, 12, 13, 14, 15, 16, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 16,
42, 42, 42, 42, 42, 42, 13, 14,
15, 16, 17, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 13, 14, 15, 16, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 13, 14,
15, 42, 17, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 13, 42, 15, 42, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 9, 42, 11, 42, 13, 14,
15, 16, 17, 42, 2, 42, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 16, 42, 42, 9, 42,
42, 42, 13, 14, 15, 16, 17, 42,
2, 42, 3, 3, 42, 5, 42, 6,
42, 42, 42, 42, 42, 42, 42, 42,
42, 42, 9, 10, 11, 42, 13, 14,
15, 16, 17, 42, 2, 3, 3, 3,
42, 5, 42, 6, 42, 42, 42, 42,
42, 42, 42, 8, 42, 42, 9, 10,
11, 12, 13, 14, 15, 16, 17, 42,
51, 50, 0
};
static const char _myanmar_syllable_machine_trans_targs[] = {
0, 1, 22, 0, 0, 23, 29, 32,
35, 36, 40, 41, 42, 25, 38, 39,
37, 28, 43, 0, 2, 12, 0, 3,
9, 13, 14, 18, 19, 20, 5, 16,
17, 15, 8, 21, 4, 6, 7, 10,
11, 0, 24, 26, 27, 30, 31, 33,
34
37, 28, 43, 44, 0, 2, 12, 0,
3, 9, 13, 14, 18, 19, 20, 5,
16, 17, 15, 8, 21, 4, 6, 7,
10, 11, 0, 24, 26, 27, 30, 31,
33, 34, 0, 0
};
static const char _myanmar_syllable_machine_trans_actions[] = {
3, 0, 0, 4, 5, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 6, 0, 0, 7, 0,
0, 0, 0, 0, 6, 0, 0, 7,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 8, 0, 0, 0, 0, 0, 0,
0
0, 0, 8, 0, 0, 0, 0, 0,
0, 0, 9, 10
};
static const char _myanmar_syllable_machine_to_state_actions[] = {
@ -232,7 +233,7 @@ static const char _myanmar_syllable_machine_to_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
0, 0, 0, 0, 0
};
static const char _myanmar_syllable_machine_from_state_actions[] = {
@ -241,16 +242,16 @@ static const char _myanmar_syllable_machine_from_state_actions[] = {
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0, 0
0, 0, 0, 0, 0
};
static const short _myanmar_syllable_machine_eof_trans[] = {
0, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 20, 20,
20, 20, 20, 20, 20, 20, 42, 42,
42, 42, 42, 42, 42, 42, 42, 42,
20, 20, 42, 42, 42, 42, 42, 42,
42, 42, 42, 42
0, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 21, 21,
21, 21, 21, 21, 21, 21, 43, 43,
43, 43, 43, 43, 43, 43, 43, 43,
21, 21, 43, 43, 43, 43, 43, 43,
43, 43, 43, 43, 51
};
static const int myanmar_syllable_machine_start = 0;
@ -264,7 +265,7 @@ static const int myanmar_syllable_machine_en_main = 0;
#line 90 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
#line 93 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
#define found_syllable(syllable_type) \
@ -284,7 +285,7 @@ find_syllables (hb_buffer_t *buffer)
int cs;
hb_glyph_info_t *info = buffer->info;
#line 288 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
#line 289 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
{
cs = myanmar_syllable_machine_start;
ts = 0;
@ -292,7 +293,7 @@ find_syllables (hb_buffer_t *buffer)
act = 0;
}
#line 111 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
#line 114 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
p = 0;
@ -301,7 +302,7 @@ find_syllables (hb_buffer_t *buffer)
unsigned int last = 0;
unsigned int syllable_serial = 1;
#line 305 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
#line 306 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
{
int _slen;
int _trans;
@ -315,7 +316,7 @@ _resume:
#line 1 "NONE"
{ts = p;}
break;
#line 319 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
#line 320 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
}
_keys = _myanmar_syllable_machine_trans_keys + (cs<<1);
@ -334,30 +335,38 @@ _eof_trans:
switch ( _myanmar_syllable_machine_trans_actions[_trans] ) {
case 7:
#line 83 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (consonant_syllable); }}
break;
case 5:
#line 84 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 4:
#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 3:
#line 86 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 10:
#line 87 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (punctuation_cluster); }}
break;
case 4:
#line 88 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (broken_cluster); }}
break;
case 3:
#line 89 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
{te = p+1;{ found_syllable (non_myanmar_cluster); }}
break;
case 6:
#line 83 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (consonant_syllable); }}
break;
case 8:
#line 85 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
#line 88 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (broken_cluster); }}
break;
#line 361 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
case 9:
#line 89 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
{te = p;p--;{ found_syllable (non_myanmar_cluster); }}
break;
#line 370 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
}
_again:
@ -366,7 +375,7 @@ _again:
#line 1 "NONE"
{ts = 0;}
break;
#line 370 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
#line 379 "hb-ot-shape-complex-myanmar-machine.hh.tmp"
}
if ( ++p != pe )
@ -382,7 +391,7 @@ _again:
}
#line 120 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
#line 123 "../../src/hb-ot-shape-complex-myanmar-machine.rl"
}

View File

@ -61,6 +61,7 @@ VS = 30;
ZWJ = 6;
ZWNJ = 5;
Ra = 16;
P = 31;
j = ZWJ|ZWNJ; # Joiners
k = (Ra As H); # Kinzi
@ -70,18 +71,20 @@ c = C|Ra; # is_consonant
medial_group = MY? MR? ((MW MH? | MH) As?)?;
main_vowel_group = VPre* VAbv* VBlw* A* (DB As?)?;
post_vowel_group = VPst MH? As* VAbv* A* (DB As?)?;
pwo_tone_group = PT A* (DB As?)?;
pwo_tone_group = PT A* DB? As?;
complex_syllable_tail = As* medial_group main_vowel_group post_vowel_group* pwo_tone_group* V* j?;
syllable_tail = (H | complex_syllable_tail);
consonant_syllable = k? (c|IV|D|GB).VS? (H (c|IV).VS?)* syllable_tail;
punctuation_cluster = P V;
broken_cluster = k? VS? syllable_tail;
other = any;
main := |*
consonant_syllable => { found_syllable (consonant_syllable); };
j => { found_syllable (non_myanmar_cluster); };
punctuation_cluster => { found_syllable (punctuation_cluster); };
broken_cluster => { found_syllable (broken_cluster); };
other => { found_syllable (non_myanmar_cluster); };
*|;

View File

@ -119,6 +119,7 @@ override_features_myanmar (hb_ot_shape_planner_t *plan)
enum syllable_type_t {
consonant_syllable,
punctuation_cluster,
broken_cluster,
non_myanmar_cluster,
};
@ -143,7 +144,8 @@ enum myanmar_category_t {
OT_VBlw = 27,
OT_VPre = 28,
OT_VPst = 29,
OT_VS = 30 /* Variation selectors */
OT_VS = 30, /* Variation selectors */
OT_P = 31 /* Punctuation */
};
@ -186,6 +188,10 @@ set_myanmar_properties (hb_glyph_info_t &info)
switch (u)
{
case 0x104E:
cat = (indic_category_t) OT_C; /* The spec says C, IndicSyllableCategory doesn't have. */
break;
case 0x002D: case 0x00A0: case 0x00D7: case 0x2012:
case 0x2013: case 0x2014: case 0x2015: case 0x2022:
case 0x25CC: case 0x25FB: case 0x25FC: case 0x25FD:
@ -243,6 +249,10 @@ set_myanmar_properties (hb_glyph_info_t &info)
case 0x108F: case 0x109A: case 0x109B: case 0x109C:
cat = (indic_category_t) OT_SM;
break;
case 0x104A: case 0x104B:
cat = (indic_category_t) OT_P;
break;
}
if (cat == OT_M)
@ -405,6 +415,16 @@ initial_reordering_broken_cluster (const hb_ot_shape_plan_t *plan,
initial_reordering_consonant_syllable (plan, face, buffer, start, end);
}
static void
initial_reordering_punctuation_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_face_t *face HB_UNUSED,
hb_buffer_t *buffer HB_UNUSED,
unsigned int start HB_UNUSED, unsigned int end HB_UNUSED)
{
/* Nothing to do right now. If we ever switch to using the output
* buffer in the reordering process, we'd need to next_glyph() here. */
}
static void
initial_reordering_non_myanmar_cluster (const hb_ot_shape_plan_t *plan HB_UNUSED,
hb_face_t *face HB_UNUSED,
@ -425,6 +445,7 @@ initial_reordering_syllable (const hb_ot_shape_plan_t *plan,
syllable_type_t syllable_type = (syllable_type_t) (buffer->info[start].syllable() & 0x0F);
switch (syllable_type) {
case consonant_syllable: initial_reordering_consonant_syllable (plan, face, buffer, start, end); return;
case punctuation_cluster: initial_reordering_punctuation_cluster (plan, face, buffer, start, end); return;
case broken_cluster: initial_reordering_broken_cluster (plan, face, buffer, start, end); return;
case non_myanmar_cluster: initial_reordering_non_myanmar_cluster (plan, face, buffer, start, end); return;
}

View File

@ -66,7 +66,7 @@ struct hb_ot_shape_planner_t
hb_ot_map_builder_t map;
hb_ot_shape_planner_t (const hb_shape_plan_t *master_plan) :
face (master_plan->face),
face (master_plan->face_unsafe),
props (master_plan->props),
shaper (NULL),
map (face, &props) {}

View File

@ -167,9 +167,12 @@ typedef struct {
*
* Generated by intersecting the OpenType language tag list from
* Draft OpenType 1.5 spec, with with the ISO 639-3 codes from
* 2008/08/04, matching on name, and finally adjusted manually.
* 2008-08-04, matching on name, and finally adjusted manually.
*
* Updated on 2012/12/07 with more research into remaining codes.
* Updated on 2012-12-07 with more research into remaining codes.
*
* Updated on 2013-11-23 based on usage in SIL and Microsoft fonts,
* the new proposal from Microsoft, and latest ISO 639-3 names.
*
* Some items still missing. Those are commented out at the end.
* Keep sorted for bsearch.
@ -179,57 +182,90 @@ static const LangTag ot_languages[] = {
{"aa", HB_TAG('A','F','R',' ')}, /* Afar */
{"ab", HB_TAG('A','B','K',' ')}, /* Abkhazian */
{"abq", HB_TAG('A','B','A',' ')}, /* Abaza */
{"ach", HB_TAG('A','C','H',' ')}, /* Acoli */
{"ada", HB_TAG('D','N','G',' ')}, /* Dangme */
{"ady", HB_TAG('A','D','Y',' ')}, /* Adyghe */
{"af", HB_TAG('A','F','K',' ')}, /* Afrikaans */
{"aii", HB_TAG('S','W','A',' ')}, /* Swadaya Aramaic */
{"aio", HB_TAG('A','I','O',' ')}, /* Aiton */
{"aiw", HB_TAG('A','R','I',' ')}, /* Aari */
{"ak", HB_TAG('T','W','I',' ')}, /* Akan [macrolanguage] */
{"alt", HB_TAG('A','L','T',' ')}, /* [Southern] Altai */
{"am", HB_TAG('A','M','H',' ')}, /* Amharic */
{"amf", HB_TAG('H','B','N',' ')}, /* Hammer-Banna */
{"ar", HB_TAG('A','R','A',' ')}, /* Arabic */
{"an", HB_TAG('A','R','G',' ')}, /* Aragonese */
{"ang", HB_TAG('A','N','G',' ')}, /* Old English (ca. 450-1100) */
{"ar", HB_TAG('A','R','A',' ')}, /* Arabic [macrolanguage] */
{"arb", HB_TAG('A','R','A',' ')}, /* Standard Arabic */
{"arn", HB_TAG('M','A','P',' ')}, /* Mapudungun */
{"ary", HB_TAG('M','O','R',' ')}, /* Moroccan Arabic */
{"as", HB_TAG('A','S','M',' ')}, /* Assamese */
{"ast", HB_TAG('A','S','T',' ')}, /* Asturian/Asturleonese/Bable/Leonese */
{"ath", HB_TAG('A','T','H',' ')}, /* Athapaskan [family] */
{"atv", HB_TAG('A','L','T',' ')}, /* [Northern] Altai */
{"av", HB_TAG('A','V','R',' ')}, /* Avaric */
{"awa", HB_TAG('A','W','A',' ')}, /* Awadhi */
{"ay", HB_TAG('A','Y','M',' ')}, /* Aymara */
{"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani */
{"ay", HB_TAG('A','Y','M',' ')}, /* Aymara [macrolanguage] */
{"az", HB_TAG('A','Z','E',' ')}, /* Azerbaijani [macrolanguage] */
{"azb", HB_TAG('A','Z','B',' ')}, /* South Azerbaijani */
{"azj", HB_TAG('A','Z','E',' ')}, /* North Azerbaijani */
{"ba", HB_TAG('B','S','H',' ')}, /* Bashkir */
{"bai", HB_TAG('B','M','L',' ')}, /* Bamileke [family] */
{"bal", HB_TAG('B','L','I',' ')}, /* Baluchi */
{"bci", HB_TAG('B','A','U',' ')}, /* Baule */
{"bal", HB_TAG('B','L','I',' ')}, /* Baluchi [macrolangauge] */
{"ban", HB_TAG('B','A','N',' ')}, /* Balinese */
{"bar", HB_TAG('B','A','R',' ')}, /* Bavarian */
{"bbc", HB_TAG('B','B','C',' ')}, /* Batak Toba */
{"bci", HB_TAG('B','A','U',' ')}, /* Baoulé */
{"bcl", HB_TAG('B','I','K',' ')}, /* Central Bikol */
{"bcq", HB_TAG('B','C','H',' ')}, /* Bench */
{"be", HB_TAG('B','E','L',' ')}, /* Belarussian */
{"be", HB_TAG('B','E','L',' ')}, /* Belarusian */
{"bem", HB_TAG('B','E','M',' ')}, /* Bemba (Zambia) */
{"ber", HB_TAG('B','E','R',' ')}, /* Berber [family] */
{"bfq", HB_TAG('B','A','D',' ')}, /* Badaga */
{"bft", HB_TAG('B','L','T',' ')}, /* Balti */
{"bfy", HB_TAG('B','A','G',' ')}, /* Baghelkhandi */
{"bg", HB_TAG('B','G','R',' ')}, /* Bulgarian */
{"bgc", HB_TAG('B','G','C',' ')}, /* Haryanvi */
{"bgq", HB_TAG('B','G','Q',' ')}, /* Bagri */
{"bhb", HB_TAG('B','H','I',' ')}, /* Bhili */
{"bhk", HB_TAG('B','I','K',' ')}, /* Albay Bicolano (retired code) */
{"bho", HB_TAG('B','H','O',' ')}, /* Bhojpuri */
{"bik", HB_TAG('B','I','K',' ')}, /* Bikol */
{"bi", HB_TAG('B','I','S',' ')}, /* Bislama */
{"bik", HB_TAG('B','I','K',' ')}, /* Bikol [macrolanguage] */
{"bin", HB_TAG('E','D','O',' ')}, /* Bini */
{"bjj", HB_TAG('B','J','J',' ')}, /* Kanauji */
{"bjt", HB_TAG('B','L','N',' ')}, /* Balanta-Ganja */
{"bla", HB_TAG('B','K','F',' ')}, /* Blackfoot */
{"ble", HB_TAG('B','L','N',' ')}, /* Balanta-Kentohe */
{"blk", HB_TAG('B','L','K',' ')}, /* Pa'O/Pa'o Karen */
{"bln", HB_TAG('B','I','K',' ')}, /* Southern Catanduanes Bikol */
{"bm", HB_TAG('B','M','B',' ')}, /* Bambara */
{"bn", HB_TAG('B','E','N',' ')}, /* Bengali */
{"bo", HB_TAG('T','I','B',' ')}, /* Tibetan */
{"bpy", HB_TAG('B','P','Y',' ')}, /* Bishnupriya */
{"bqi", HB_TAG('L','R','C',' ')}, /* Bakhtiari */
{"br", HB_TAG('B','R','E',' ')}, /* Breton */
{"bra", HB_TAG('B','R','I',' ')}, /* Braj Bhasha */
{"brh", HB_TAG('B','R','H',' ')}, /* Brahui */
{"brx", HB_TAG('B','R','X',' ')}, /* Bodo (India) */
{"bs", HB_TAG('B','O','S',' ')}, /* Bosnian */
{"btb", HB_TAG('B','T','I',' ')}, /* Beti (Cameroon) */
{"bto", HB_TAG('B','I','K',' ')}, /* Rinconada Bikol */
{"bts", HB_TAG('B','T','S',' ')}, /* Batak Simalungun */
{"bug", HB_TAG('B','U','G',' ')}, /* Buginese */
{"bxr", HB_TAG('R','B','U',' ')}, /* Russian Buriat */
{"byn", HB_TAG('B','I','L',' ')}, /* Bilen */
{"ca", HB_TAG('C','A','T',' ')}, /* Catalan */
{"cbk", HB_TAG('C','B','K',' ')}, /* Chavacano */
{"ce", HB_TAG('C','H','E',' ')}, /* Chechen */
{"ceb", HB_TAG('C','E','B',' ')}, /* Cebuano */
{"cgg", HB_TAG('C','G','G',' ')}, /* Chiga */
{"ch", HB_TAG('C','H','A',' ')}, /* Chamorro */
{"cho", HB_TAG('C','H','O',' ')}, /* Choctaw */
{"chp", HB_TAG('C','H','P',' ')}, /* Chipewyan */
{"chr", HB_TAG('C','H','R',' ')}, /* Cherokee */
{"chy", HB_TAG('C','H','Y',' ')}, /* Cheyenne */
{"ckb", HB_TAG('K','U','R',' ')}, /* Central Kurdish (Sorani) */
{"ckt", HB_TAG('C','H','K',' ')}, /* Chukchi */
{"cop", HB_TAG('C','O','P',' ')}, /* Coptic */
{"cr", HB_TAG('C','R','E',' ')}, /* Cree */
@ -239,6 +275,9 @@ static const LangTag ot_languages[] = {
{"crm", HB_TAG('M','C','R',' ')}, /* Moose Cree */
{"crx", HB_TAG('C','R','R',' ')}, /* Carrier */
{"cs", HB_TAG('C','S','Y',' ')}, /* Czech */
{"csb", HB_TAG('C','S','B',' ')}, /* Kashubian */
{"ctg", HB_TAG('C','T','G',' ')}, /* Chittagonian */
{"cts", HB_TAG('B','I','K',' ')}, /* Northern Catanduanes Bikol */
{"cu", HB_TAG('C','S','L',' ')}, /* Church Slavic */
{"cv", HB_TAG('C','H','U',' ')}, /* Chuvash */
{"cwd", HB_TAG('D','C','R',' ')}, /* Woods Cree */
@ -247,34 +286,42 @@ static const LangTag ot_languages[] = {
{"dap", HB_TAG('N','I','S',' ')}, /* Nisi (India) */
{"dar", HB_TAG('D','A','R',' ')}, /* Dargwa */
{"de", HB_TAG('D','E','U',' ')}, /* German */
{"din", HB_TAG('D','N','K',' ')}, /* Dinka */
{"dje", HB_TAG('D','J','R',' ')}, /* Djerma */
{"dgo", HB_TAG('D','G','O',' ')}, /* Dogri */
{"dhd", HB_TAG('M','A','W',' ')}, /* Dhundari */
{"din", HB_TAG('D','N','K',' ')}, /* Dinka [macrolanguage] */
{"diq", HB_TAG('D','I','Q',' ')}, /* Dimli */
{"dje", HB_TAG('D','J','R',' ')}, /* Zarma */
{"dng", HB_TAG('D','U','N',' ')}, /* Dungan */
{"doi", HB_TAG('D','G','R',' ')}, /* Dogri */
{"doi", HB_TAG('D','G','R',' ')}, /* Dogri [macrolanguage] */
{"dsb", HB_TAG('L','S','B',' ')}, /* Lower Sorbian */
{"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi */
{"dv", HB_TAG('D','I','V',' ')}, /* Dhivehi/Divehi/Maldivian */
{"dyu", HB_TAG('J','U','L',' ')}, /* Jula */
{"dz", HB_TAG('D','Z','N',' ')}, /* Dzongkha */
{"ee", HB_TAG('E','W','E',' ')}, /* Ewe */
{"efi", HB_TAG('E','F','I',' ')}, /* Efik */
{"ekk", HB_TAG('E','T','I',' ')}, /* Standard Estonian */
{"el", HB_TAG('E','L','L',' ')}, /* Modern Greek (1453-) */
{"emk", HB_TAG('M','N','K',' ')}, /* Eastern Maninkakan */
{"en", HB_TAG('E','N','G',' ')}, /* English */
{"eo", HB_TAG('N','T','O',' ')}, /* Esperanto */
{"eot", HB_TAG('B','T','I',' ')}, /* Beti (Côte d'Ivoire) */
{"es", HB_TAG('E','S','P',' ')}, /* Spanish */
{"et", HB_TAG('E','T','I',' ')}, /* Estonian */
{"et", HB_TAG('E','T','I',' ')}, /* Estonian [macrolanguage] */
{"eu", HB_TAG('E','U','Q',' ')}, /* Basque */
{"eve", HB_TAG('E','V','N',' ')}, /* Even */
{"evn", HB_TAG('E','V','K',' ')}, /* Evenki */
{"fa", HB_TAG('F','A','R',' ')}, /* Persian */
{"ff", HB_TAG('F','U','L',' ')}, /* Fulah */
{"fa", HB_TAG('F','A','R',' ')}, /* Persian [macrolanguage] */
{"ff", HB_TAG('F','U','L',' ')}, /* Fulah [macrolanguage] */
{"fi", HB_TAG('F','I','N',' ')}, /* Finnish */
{"fil", HB_TAG('P','I','L',' ')}, /* Filipino */
{"fj", HB_TAG('F','J','I',' ')}, /* Fijian */
{"fo", HB_TAG('F','O','S',' ')}, /* Faroese */
{"fon", HB_TAG('F','O','N',' ')}, /* Fon */
{"fr", HB_TAG('F','R','A',' ')}, /* French */
{"frc", HB_TAG('F','R','C',' ')}, /* Cajun French */
{"frp", HB_TAG('F','R','P',' ')}, /* Arpitan/Francoprovençal */
{"fur", HB_TAG('F','R','L',' ')}, /* Friulian */
{"fuv", HB_TAG('F','U','V',' ')}, /* Nigerian Fulfulde */
{"fy", HB_TAG('F','R','I',' ')}, /* Western Frisian */
{"ga", HB_TAG('I','R','I',' ')}, /* Irish */
{"gaa", HB_TAG('G','A','D',' ')}, /* Ga */
@ -282,113 +329,167 @@ static const LangTag ot_languages[] = {
{"gbm", HB_TAG('G','A','W',' ')}, /* Garhwali */
{"gd", HB_TAG('G','A','E',' ')}, /* Scottish Gaelic */
{"gez", HB_TAG('G','E','Z',' ')}, /* Ge'ez */
{"ggo", HB_TAG('G','O','N',' ')}, /* Southern Gondi */
{"gl", HB_TAG('G','A','L',' ')}, /* Galician */
{"gld", HB_TAG('N','A','N',' ')}, /* Nanai */
{"gn", HB_TAG('G','U','A',' ')}, /* Guarani */
{"gon", HB_TAG('G','O','N',' ')}, /* Gondi */
{"glk", HB_TAG('G','L','K',' ')}, /* Gilaki */
{"gn", HB_TAG('G','U','A',' ')}, /* Guarani [macrolanguage] */
{"gno", HB_TAG('G','O','N',' ')}, /* Northern Gondi */
{"gog", HB_TAG('G','O','G',' ')}, /* Gogo */
{"gon", HB_TAG('G','O','N',' ')}, /* Gondi [macrolanguage] */
{"grt", HB_TAG('G','R','O',' ')}, /* Garo */
{"gru", HB_TAG('S','O','G',' ')}, /* Sodo Gurage */
{"gu", HB_TAG('G','U','J',' ')}, /* Gujarati */
{"guc", HB_TAG('G','U','C',' ')}, /* Wayuu */
{"guk", HB_TAG('G','M','Z',' ')}, /* Gumuz */
{"gv", HB_TAG('M','N','X',' ')}, /* Manx Gaelic */
/*{"guk", HB_TAG('G','U','K',' ')},*/ /* Gumuz (in SIL fonts) */
{"guz", HB_TAG('G','U','Z',' ')}, /* Ekegusii/Gusii */
{"gv", HB_TAG('M','N','X',' ')}, /* Manx */
{"ha", HB_TAG('H','A','U',' ')}, /* Hausa */
{"har", HB_TAG('H','R','I',' ')}, /* Harari */
{"haw", HB_TAG('H','A','W',' ')}, /* Hawaiin */
{"haw", HB_TAG('H','A','W',' ')}, /* Hawaiian */
{"hay", HB_TAG('H','A','Y',' ')}, /* Haya */
{"haz", HB_TAG('H','A','Z',' ')}, /* Hazaragi */
{"he", HB_TAG('I','W','R',' ')}, /* Hebrew */
{"hz", HB_TAG('H','E','R',' ')}, /* Herero */
{"hi", HB_TAG('H','I','N',' ')}, /* Hindi */
{"hil", HB_TAG('H','I','L',' ')}, /* Hiligaynon */
{"hnd", HB_TAG('H','N','D',' ')}, /* [Southern] Hindko */
{"hne", HB_TAG('C','H','H',' ')}, /* Chattisgarhi */
{"hno", HB_TAG('H','N','D',' ')}, /* [Northern] Hindko */
{"ho", HB_TAG('H','M','O',' ')}, /* Hiri Motu */
{"hoc", HB_TAG('H','O',' ',' ')}, /* Ho */
{"hoj", HB_TAG('H','A','R',' ')}, /* Harauti */
{"hr", HB_TAG('H','R','V',' ')}, /* Croatian */
{"hsb", HB_TAG('U','S','B',' ')}, /* Upper Sorbian */
{"ht", HB_TAG('H','A','I',' ')}, /* Haitian */
{"ht", HB_TAG('H','A','I',' ')}, /* Haitian/Haitian Creole */
{"hu", HB_TAG('H','U','N',' ')}, /* Hungarian */
{"hy", HB_TAG('H','Y','E',' ')}, /* Armenian */
{"hz", HB_TAG('H','E','R',' ')}, /* Herero */
{"ia", HB_TAG('I','N','A',' ')}, /* Interlingua (International Auxiliary Language Association) */
{"ibb", HB_TAG('I','B','B',' ')}, /* Ibibio */
{"id", HB_TAG('I','N','D',' ')}, /* Indonesian */
{"ie", HB_TAG('I','L','E',' ')}, /* Interlingue/Occidental */
{"ig", HB_TAG('I','B','O',' ')}, /* Igbo */
{"igb", HB_TAG('E','B','I',' ')}, /* Ebira */
{"ijc", HB_TAG('I','J','O',' ')}, /* Izon */
{"ijo", HB_TAG('I','J','O',' ')}, /* Ijo [family] */
{"ik", HB_TAG('I','P','K',' ')}, /* Inupiaq [macrolanguage] */
{"ilo", HB_TAG('I','L','O',' ')}, /* Ilokano */
{"inh", HB_TAG('I','N','G',' ')}, /* Ingush */
{"io", HB_TAG('I','D','O',' ')}, /* Ido */
{"is", HB_TAG('I','S','L',' ')}, /* Icelandic */
{"it", HB_TAG('I','T','A',' ')}, /* Italian */
{"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut */
{"iu", HB_TAG('I','N','U',' ')}, /* Inuktitut [macrolanguage] */
{"ja", HB_TAG('J','A','N',' ')}, /* Japanese */
{"jam", HB_TAG('J','A','M',' ')}, /* Jamaican Creole English */
{"jbo", HB_TAG('J','B','O',' ')}, /* Lojban */
{"jv", HB_TAG('J','A','V',' ')}, /* Javanese */
{"ka", HB_TAG('K','A','T',' ')}, /* Georgian */
{"kaa", HB_TAG('K','R','K',' ')}, /* Karakalpak */
{"kab", HB_TAG('K','A','B',' ')}, /* Kabyle */
{"kam", HB_TAG('K','M','B',' ')}, /* Kamba (Kenya) */
{"kar", HB_TAG('K','R','N',' ')}, /* Karen [family] */
{"kbd", HB_TAG('K','A','B',' ')}, /* Kabardian */
{"kde", HB_TAG('K','D','E',' ')}, /* Makonde */
{"kdr", HB_TAG('K','R','M',' ')}, /* Karaim */
{"kdt", HB_TAG('K','U','Y',' ')}, /* Kuy */
{"kex", HB_TAG('K','K','N',' ')}, /* Kokni */
{"kfr", HB_TAG('K','A','C',' ')}, /* Kachchi */
{"kfy", HB_TAG('K','M','N',' ')}, /* Kumaoni */
{"kg", HB_TAG('K','O','N',' ')}, /* Kongo [macrolanguage] */
{"kha", HB_TAG('K','S','I',' ')}, /* Khasi */
{"khb", HB_TAG('X','B','D',' ')}, /* Tai Lue */
{"khb", HB_TAG('X','B','D',' ')}, /* Lü */
{"kht", HB_TAG('K','H','N',' ')}, /* Khamti (Microsoft fonts) */
/*{"kht", HB_TAG('K','H','T',' ')},*/ /* Khamti (OpenType spec and SIL fonts) */
{"khw", HB_TAG('K','H','W',' ')}, /* Khowar */
{"ki", HB_TAG('K','I','K',' ')}, /* Kikuyu */
{"ki", HB_TAG('K','I','K',' ')}, /* Gikuyu/Kikuyu */
{"kj", HB_TAG('K','U','A',' ')}, /* Kuanyama/Kwanyama */
{"kjh", HB_TAG('K','H','A',' ')}, /* Khakass */
{"kjp", HB_TAG('K','J','P',' ')}, /* Pwo Eastern Karen */
{"kk", HB_TAG('K','A','Z',' ')}, /* Kazakh */
{"kl", HB_TAG('G','R','N',' ')}, /* Kalaallisut */
{"kln", HB_TAG('K','A','L',' ')}, /* Kalenjin */
{"km", HB_TAG('K','H','M',' ')}, /* Central Khmer */
{"kmb", HB_TAG('M','B','N',' ')}, /* [North] Mbundu */
{"kmb", HB_TAG('M','B','N',' ')}, /* Kimbundu */
{"kmw", HB_TAG('K','M','O',' ')}, /* Komo (Democratic Republic of Congo) */
{"kn", HB_TAG('K','A','N',' ')}, /* Kannada */
{"knn", HB_TAG('K','O','K',' ')}, /* Konkani */
{"ko", HB_TAG('K','O','R',' ')}, /* Korean */
{"koi", HB_TAG('K','O','P',' ')}, /* Komi-Permyak */
{"kok", HB_TAG('K','O','K',' ')}, /* Konkani */
{"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle */
{"kok", HB_TAG('K','O','K',' ')}, /* Konkani [macrolanguage] */
{"kpe", HB_TAG('K','P','L',' ')}, /* Kpelle [macrolanguage] */
{"kpv", HB_TAG('K','O','Z',' ')}, /* Komi-Zyrian */
{"kpy", HB_TAG('K','Y','K',' ')}, /* Koryak */
{"kqy", HB_TAG('K','R','T',' ')}, /* Koorete */
{"kr", HB_TAG('K','N','R',' ')}, /* Kanuri */
{"kr", HB_TAG('K','N','R',' ')}, /* Kanuri [macrolanguage] */
{"kri", HB_TAG('K','R','I',' ')}, /* Krio */
{"krl", HB_TAG('K','R','L',' ')}, /* Karelian */
{"kru", HB_TAG('K','U','U',' ')}, /* Kurukh */
{"ks", HB_TAG('K','S','H',' ')}, /* Kashmiri */
{"ku", HB_TAG('K','U','R',' ')}, /* Kurdish */
{"ksh", HB_TAG('K','S','H',' ')}, /* Kölsch */
/*{"ksw", HB_TAG('K','R','N',' ')},*/ /* S'gaw Karen (Microsoft fonts?) */
{"ksw", HB_TAG('K','S','W',' ')}, /* S'gaw Karen (OpenType spec and SIL fonts) */
{"ku", HB_TAG('K','U','R',' ')}, /* Kurdish [macrolanguage] */
{"kum", HB_TAG('K','U','M',' ')}, /* Kumyk */
{"kv", HB_TAG('K','O','M',' ')}, /* Komi [macrolanguage] */
{"kvd", HB_TAG('K','U','I',' ')}, /* Kui (Indonesia) */
{"kw", HB_TAG('C','O','R',' ')}, /* Cornish */
{"kxc", HB_TAG('K','M','S',' ')}, /* Komso */
{"kxu", HB_TAG('K','U','I',' ')}, /* Kui (India) */
{"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz */
{"ky", HB_TAG('K','I','R',' ')}, /* Kirghiz/Kyrgyz */
{"kyu", HB_TAG('K','Y','U',' ')}, /* Western Kayah */
{"la", HB_TAG('L','A','T',' ')}, /* Latin */
{"lad", HB_TAG('J','U','D',' ')}, /* Ladino */
{"lb", HB_TAG('L','T','Z',' ')}, /* Luxembourgish */
{"lbe", HB_TAG('L','A','K',' ')}, /* Lak */
{"lbj", HB_TAG('L','D','K',' ')}, /* Ladakhi */
{"lez", HB_TAG('L','E','Z',' ')}, /* Lezgi */
{"lg", HB_TAG('L','U','G',' ')}, /* Luganda */
{"lg", HB_TAG('L','U','G',' ')}, /* Ganda */
{"li", HB_TAG('L','I','M',' ')}, /* Limburgan/Limburger/Limburgish */
{"lif", HB_TAG('L','M','B',' ')}, /* Limbu */
{"lij", HB_TAG('L','I','J',' ')}, /* Ligurian */
{"lis", HB_TAG('L','I','S',' ')}, /* Lisu */
{"ljp", HB_TAG('L','J','P',' ')}, /* Lampung Api */
{"lki", HB_TAG('L','K','I',' ')}, /* Laki */
{"lld", HB_TAG('L','A','D',' ')}, /* Ladin */
{"lmn", HB_TAG('L','A','M',' ')}, /* Lambani */
{"lmo", HB_TAG('L','M','O',' ')}, /* Lombard */
{"ln", HB_TAG('L','I','N',' ')}, /* Lingala */
{"lo", HB_TAG('L','A','O',' ')}, /* Lao */
{"lrc", HB_TAG('L','R','C',' ')}, /* Northern Luri */
{"lt", HB_TAG('L','T','H',' ')}, /* Lithuanian */
{"lu", HB_TAG('L','U','B',' ')}, /* Luba-Katanga */
{"lua", HB_TAG('L','U','B',' ')}, /* Luba-Kasai */
{"luo", HB_TAG('L','U','O',' ')}, /* Luo (Kenya and Tanzania) */
{"lus", HB_TAG('M','I','Z',' ')}, /* Mizo */
{"luy", HB_TAG('L','U','H',' ')}, /* Luhya [macrolanguage] */
{"luy", HB_TAG('L','U','H',' ')}, /* Luyia/Oluluyia [macrolanguage] */
{"luz", HB_TAG('L','R','C',' ')}, /* Southern Luri */
{"lv", HB_TAG('L','V','I',' ')}, /* Latvian */
{"lzz", HB_TAG('L','A','Z',' ')}, /* Laz */
{"mad", HB_TAG('M','A','D',' ')}, /* Madurese */
{"mag", HB_TAG('M','A','G',' ')}, /* Magahi */
{"mai", HB_TAG('M','T','H',' ')}, /* Maithili */
{"mak", HB_TAG('M','K','R',' ')}, /* Makasar */
{"man", HB_TAG('M','N','K',' ')}, /* Manding/Mandingo [macrolanguage] */
{"mdc", HB_TAG('M','L','E',' ')}, /* Male (Papua New Guinea) */
{"mdf", HB_TAG('M','O','K',' ')}, /* Moksha */
{"mdr", HB_TAG('M','D','R',' ')}, /* Mandar */
{"mdy", HB_TAG('M','L','E',' ')}, /* Male (Ethiopia) */
{"men", HB_TAG('M','D','E',' ')}, /* Mende (Sierra Leone) */
{"mg", HB_TAG('M','L','G',' ')}, /* Malagasy */
{"mer", HB_TAG('M','E','R',' ')}, /* Meru */
{"mfe", HB_TAG('M','F','E',' ')}, /* Morisyen */
{"mg", HB_TAG('M','L','G',' ')}, /* Malagasy [macrolanguage] */
{"mh", HB_TAG('M','A','H',' ')}, /* Marshallese */
{"mhr", HB_TAG('L','M','A',' ')}, /* Low Mari */
{"mi", HB_TAG('M','R','I',' ')}, /* Maori */
{"min", HB_TAG('M','I','N',' ')}, /* Minangkabau */
{"mk", HB_TAG('M','K','D',' ')}, /* Macedonian */
{"mku", HB_TAG('M','N','K',' ')}, /* Konyanka Maninka */
{"mkw", HB_TAG('M','K','W',' ')}, /* Kituba (Congo) */
{"ml", HB_TAG('M','L','R',' ')}, /* Malayalam */
{"mn", HB_TAG('M','N','G',' ')}, /* Mongolian */
{"mlq", HB_TAG('M','N','K',' ')}, /* Western Maninkakan */
{"mn", HB_TAG('M','N','G',' ')}, /* Mongolian [macrolanguage] */
{"mnc", HB_TAG('M','C','H',' ')}, /* Manchu */
{"mni", HB_TAG('M','N','I',' ')}, /* Manipuri */
{"mnk", HB_TAG('M','N','D',' ')}, /* Mandinka */
@ -396,72 +497,119 @@ static const LangTag ot_languages[] = {
{"mnw", HB_TAG('M','O','N',' ')}, /* Mon */
{"mo", HB_TAG('M','O','L',' ')}, /* Moldavian */
{"moh", HB_TAG('M','O','H',' ')}, /* Mohawk */
{"mos", HB_TAG('M','O','S',' ')}, /* Mossi */
{"mpe", HB_TAG('M','A','J',' ')}, /* Majang */
{"mr", HB_TAG('M','A','R',' ')}, /* Marathi */
{"mrj", HB_TAG('H','M','A',' ')}, /* High Mari */
{"ms", HB_TAG('M','L','Y',' ')}, /* Malay */
{"ms", HB_TAG('M','L','Y',' ')}, /* Malay [macrolanguage] */
{"msc", HB_TAG('M','N','K',' ')}, /* Sankaran Maninka */
{"mt", HB_TAG('M','T','S',' ')}, /* Maltese */
{"mwr", HB_TAG('M','A','W',' ')}, /* Marwari */
{"mtr", HB_TAG('M','A','W',' ')}, /* Mewari */
{"mus", HB_TAG('M','U','S',' ')}, /* Creek */
{"mve", HB_TAG('M','A','W',' ')}, /* Marwari (Pakistan) */
{"mwk", HB_TAG('M','N','K',' ')}, /* Kita Maninkakan */
{"mwl", HB_TAG('M','W','L',' ')}, /* Mirandese */
{"mwr", HB_TAG('M','A','W',' ')}, /* Marwari [macrolanguage] */
{"mww", HB_TAG('M','W','W',' ')}, /* Hmong Daw */
{"my", HB_TAG('B','R','M',' ')}, /* Burmese */
{"mym", HB_TAG('M','E','N',' ')}, /* Me'en */
{"myq", HB_TAG('M','N','K',' ')}, /* Forest Maninka (retired code) */
{"myv", HB_TAG('E','R','Z',' ')}, /* Erzya */
{"mzn", HB_TAG('M','Z','N',' ')}, /* Mazanderani */
{"na", HB_TAG('N','A','U',' ')}, /* Nauru */
{"nag", HB_TAG('N','A','G',' ')}, /* Naga-Assamese */
{"nah", HB_TAG('N','A','H',' ')}, /* Nahuatl [family] */
{"nap", HB_TAG('N','A','P',' ')}, /* Neapolitan */
{"nb", HB_TAG('N','O','R',' ')}, /* Norwegian Bokmål */
{"nco", HB_TAG('S','I','B',' ')}, /* Sibe */
{"nd", HB_TAG('N','D','B',' ')}, /* [North] Ndebele */
{"ndc", HB_TAG('N','D','C',' ')}, /* Ndau */
{"nds", HB_TAG('N','D','S',' ')}, /* Low German/Low Saxon */
{"ne", HB_TAG('N','E','P',' ')}, /* Nepali */
{"new", HB_TAG('N','E','W',' ')}, /* Newari */
{"ng", HB_TAG('N','D','G',' ')}, /* Ndonga */
{"nga", HB_TAG('N','G','A',' ')}, /* Ngabaka */
{"ngl", HB_TAG('L','M','W',' ')}, /* Lomwe */
{"niu", HB_TAG('N','I','U',' ')}, /* Niuean */
{"niv", HB_TAG('G','I','L',' ')}, /* Gilyak */
{"nl", HB_TAG('N','L','D',' ')}, /* Dutch */
{"nn", HB_TAG('N','Y','N',' ')}, /* Norwegian Nynorsk */
{"no", HB_TAG('N','O','R',' ')}, /* Norwegian (deprecated) */
{"nod", HB_TAG('N','T','A',' ')}, /* Northern Tai */
{"no", HB_TAG('N','O','R',' ')}, /* Norwegian [macrolanguage] */
{"nod", HB_TAG('N','T','A',' ')}, /* Northern Thai */
{"noe", HB_TAG('N','O','E',' ')}, /* Nimadi */
{"nog", HB_TAG('N','O','G',' ')}, /* Nogai */
{"nov", HB_TAG('N','O','V',' ')}, /* Novial */
{"nqo", HB_TAG('N','K','O',' ')}, /* N'Ko */
{"nr", HB_TAG('N','D','B',' ')}, /* [South] Ndebele */
{"nsk", HB_TAG('N','A','S',' ')}, /* Naskapi */
{"nso", HB_TAG('S','O','T',' ')}, /* [Northern] Sotho */
{"ny", HB_TAG('C','H','I',' ')}, /* Nyanja */
{"nyn", HB_TAG('N','K','L',' ')}, /* Nkole */
{"ny", HB_TAG('C','H','I',' ')}, /* Chewa/Chichwa/Nyanja */
{"nym", HB_TAG('N','Y','M',' ')}, /* Nyamwezi */
{"nyn", HB_TAG('N','K','L',' ')}, /* Nyankole */
{"oc", HB_TAG('O','C','I',' ')}, /* Occitan (post 1500) */
{"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa */
{"oj", HB_TAG('O','J','B',' ')}, /* Ojibwa [macrolanguage] */
{"ojs", HB_TAG('O','C','R',' ')}, /* Oji-Cree */
{"om", HB_TAG('O','R','O',' ')}, /* Oromo */
{"om", HB_TAG('O','R','O',' ')}, /* Oromo [macrolanguage] */
{"or", HB_TAG('O','R','I',' ')}, /* Oriya */
{"os", HB_TAG('O','S','S',' ')}, /* Ossetian */
{"pa", HB_TAG('P','A','N',' ')}, /* Panjabi */
{"pag", HB_TAG('P','A','G',' ')}, /* Pangasinan */
{"pam", HB_TAG('P','A','M',' ')}, /* Kapampangan/Pampanga */
{"pap", HB_TAG('P','A','P',' ')}, /* Papiamento */
{"pcc", HB_TAG('P','C','C',' ')}, /* Bouyei */
{"pcd", HB_TAG('P','C','D',' ')}, /* Picard */
{"pce", HB_TAG('P','L','G',' ')}, /* [Ruching] Palaung */
{"pdc", HB_TAG('P','D','C',' ')}, /* Pennsylvania German */
{"pes", HB_TAG('F','A','R',' ')}, /* Iranian Persian */
{"phk", HB_TAG('P','H','K',' ')}, /* Phake */
{"pi", HB_TAG('P','A','L',' ')}, /* Pali */
{"pih", HB_TAG('P','I','H',' ')}, /* Pitcairn-Norfolk */
{"pl", HB_TAG('P','L','K',' ')}, /* Polish */
{"pll", HB_TAG('P','L','G',' ')}, /* [Shwe] Palaung */
{"plp", HB_TAG('P','A','P',' ')}, /* Palpa */
{"prs", HB_TAG('D','R','I',' ')}, /* Dari */
{"ps", HB_TAG('P','A','S',' ')}, /* Pushto */
{"pms", HB_TAG('P','M','S',' ')}, /* Piemontese */
{"pnb", HB_TAG('P','N','B',' ')}, /* Western Panjabi */
{"prs", HB_TAG('D','R','I',' ')}, /* Afghan Persian/Dari */
{"ps", HB_TAG('P','A','S',' ')}, /* Pashto/Pushto [macrolanguage] */
{"pt", HB_TAG('P','T','G',' ')}, /* Portuguese */
{"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani */
{"rbb", HB_TAG('P','L','G',' ')}, /* [Rumai] Palaung */
{"pwo", HB_TAG('P','W','O',' ')}, /* Pwo Western Karen */
{"qu", HB_TAG('Q','U','Z',' ')}, /* Quechua [macrolanguage] */
{"quc", HB_TAG('Q','U','C',' ')}, /* K'iche'/Quiché */
{"quz", HB_TAG('Q','U','Z',' ')}, /* Cusco Quechua */
{"raj", HB_TAG('R','A','J',' ')}, /* Rajasthani [macrolanguage] */
{"rbb", HB_TAG('P','L','G',' ')}, /* Rumai Palaung */
{"rej", HB_TAG('R','E','J',' ')}, /* Rejang */
{"ria", HB_TAG('R','I','A',' ')}, /* Riang (India) */
{"ril", HB_TAG('R','I','A',' ')}, /* Riang (Myanmar) */
{"rki", HB_TAG('A','R','K',' ')}, /* Arakanese */
{"rm", HB_TAG('R','M','S',' ')}, /* Rhaeto-Romanic */
{"rki", HB_TAG('A','R','K',' ')}, /* Rakhine */
{"rm", HB_TAG('R','M','S',' ')}, /* Romansh */
{"rmy", HB_TAG('R','M','Y',' ')}, /* Vlax Romani */
{"rn", HB_TAG('R','U','N',' ')}, /* Rundi */
{"ro", HB_TAG('R','O','M',' ')}, /* Romanian */
{"rom", HB_TAG('R','O','Y',' ')}, /* Romany */
{"rom", HB_TAG('R','O','Y',' ')}, /* Romany [macrolanguage] */
{"ru", HB_TAG('R','U','S',' ')}, /* Russian */
{"rue", HB_TAG('R','S','Y',' ')}, /* Rusyn */
{"rw", HB_TAG('R','U','A',' ')}, /* Ruanda */
{"rup", HB_TAG('R','U','P',' ')}, /* Aromanian/Arumanian/Macedo-Romanian */
{"rw", HB_TAG('R','U','A',' ')}, /* Kinyarwanda */
{"rwr", HB_TAG('M','A','W',' ')}, /* Marwari (India) */
{"sa", HB_TAG('S','A','N',' ')}, /* Sanskrit */
{"sah", HB_TAG('Y','A','K',' ')}, /* Yakut */
{"sas", HB_TAG('S','A','S',' ')}, /* Sasak */
{"sat", HB_TAG('S','A','T',' ')}, /* Santali */
{"sck", HB_TAG('S','A','D',' ')}, /* Sadri */
{"sc", HB_TAG('S','R','D',' ')}, /* Sardinian [macrolanguage] */
{"scn", HB_TAG('S','C','N',' ')}, /* Sicilian */
{"sco", HB_TAG('S','C','O',' ')}, /* Scots */
{"scs", HB_TAG('S','L','A',' ')}, /* [North] Slavey */
{"sd", HB_TAG('S','N','D',' ')}, /* Sindhi */
{"se", HB_TAG('N','S','M',' ')}, /* Northern Sami */
{"seh", HB_TAG('S','N','A',' ')}, /* Sena */
{"sel", HB_TAG('S','E','L',' ')}, /* Selkup */
{"sg", HB_TAG('S','G','O',' ')}, /* Sango */
{"sga", HB_TAG('S','G','A',' ')}, /* Old Irish (to 900) */
{"sgs", HB_TAG('S','G','S',' ')}, /* Samogitian */
{"sgw", HB_TAG('C','H','G',' ')}, /* Sebat Bet Gurage */
/*{"sgw", HB_TAG('S','G','W',' ')},*/ /* Sebat Bet Gurage (in SIL fonts) */
{"shn", HB_TAG('S','H','N',' ')}, /* Shan */
{"si", HB_TAG('S','N','H',' ')}, /* Sinhala */
{"sid", HB_TAG('S','I','D',' ')}, /* Sidamo */
@ -474,60 +622,98 @@ static const LangTag ot_languages[] = {
{"smj", HB_TAG('L','S','M',' ')}, /* Lule Sami */
{"smn", HB_TAG('I','S','M',' ')}, /* Inari Sami */
{"sms", HB_TAG('S','K','S',' ')}, /* Skolt Sami */
{"sn", HB_TAG('S','N','A',' ')}, /* Shona */
{"snk", HB_TAG('S','N','K',' ')}, /* Soninke */
{"so", HB_TAG('S','M','L',' ')}, /* Somali */
{"sq", HB_TAG('S','Q','I',' ')}, /* Albanian */
{"sop", HB_TAG('S','O','P',' ')}, /* Songe */
{"sq", HB_TAG('S','Q','I',' ')}, /* Albanian [macrolanguage] */
{"sr", HB_TAG('S','R','B',' ')}, /* Serbian */
{"srr", HB_TAG('S','R','R',' ')}, /* Serer */
{"ss", HB_TAG('S','W','Z',' ')}, /* Swazi */
{"ss", HB_TAG('S','W','Z',' ')}, /* Swati */
{"st", HB_TAG('S','O','T',' ')}, /* [Southern] Sotho */
{"stq", HB_TAG('S','T','Q',' ')}, /* Saterfriesisch */
{"stv", HB_TAG('S','I','G',' ')}, /* Silt'e */
{"su", HB_TAG('S','U','N',' ')}, /* Sundanese */
{"suk", HB_TAG('S','U','K',' ')}, /* Sukama */
{"suq", HB_TAG('S','U','R',' ')}, /* Suri */
{"sv", HB_TAG('S','V','E',' ')}, /* Swedish */
{"sva", HB_TAG('S','V','A',' ')}, /* Svan */
{"sw", HB_TAG('S','W','K',' ')}, /* Swahili */
{"sw", HB_TAG('S','W','K',' ')}, /* Swahili [macrolanguage] */
{"swb", HB_TAG('C','M','R',' ')}, /* Comorian */
{"syr", HB_TAG('S','Y','R',' ')}, /* Syriac */
{"swh", HB_TAG('S','W','K',' ')}, /* Kiswahili/Swahili */
{"swv", HB_TAG('M','A','W',' ')}, /* Shekhawati */
{"sxu", HB_TAG('S','X','U',' ')}, /* Upper Saxon */
{"syl", HB_TAG('S','Y','L',' ')}, /* Sylheti */
{"syr", HB_TAG('S','Y','R',' ')}, /* Syriac [macrolanguage] */
{"szl", HB_TAG('S','Z','L',' ')}, /* Silesian */
{"ta", HB_TAG('T','A','M',' ')}, /* Tamil */
{"tab", HB_TAG('T','A','B',' ')}, /* Tabasaran */
{"tcy", HB_TAG('T','U','L',' ')}, /* Tulu */
{"tdd", HB_TAG('T','D','D',' ')}, /* Tai Nüa */
{"te", HB_TAG('T','E','L',' ')}, /* Telugu */
{"tem", HB_TAG('T','M','N',' ')}, /* Temne */
{"tet", HB_TAG('T','E','T',' ')}, /* Tetum */
{"tg", HB_TAG('T','A','J',' ')}, /* Tajik */
{"th", HB_TAG('T','H','A',' ')}, /* Thai */
{"ti", HB_TAG('T','G','Y',' ')}, /* Tigrinya */
{"tig", HB_TAG('T','G','R',' ')}, /* Tigre */
{"tiv", HB_TAG('T','I','V',' ')}, /* Tiv */
{"tk", HB_TAG('T','K','M',' ')}, /* Turkmen */
{"tl", HB_TAG('T','G','L',' ')}, /* Tagalog */
{"tmh", HB_TAG('t','m','h',' ')}, /* Tamashek [macrolanguage] */
{"tn", HB_TAG('T','N','A',' ')}, /* Tswana */
{"to", HB_TAG('T','G','N',' ')}, /* Tonga (Tonga Islands) */
{"tpi", HB_TAG('T','P','I',' ')}, /* Tok Pisin */
{"tr", HB_TAG('T','R','K',' ')}, /* Turkish */
{"tru", HB_TAG('T','U','A',' ')}, /* Turoyo Aramaic */
{"ts", HB_TAG('T','S','G',' ')}, /* Tsonga */
{"tt", HB_TAG('T','A','T',' ')}, /* Tatar */
{"tum", HB_TAG('T','U','M',' ')}, /* Tumbuka */
{"tw", HB_TAG('T','W','I',' ')}, /* Twi */
{"ty", HB_TAG('T','H','T',' ')}, /* Tahitian */
{"tyv", HB_TAG('T','U','V',' ')}, /* Tuvin */
{"tyz", HB_TAG('T','Y','Z',' ')}, /* Tày */
{"tzm", HB_TAG('T','Z','M',' ')}, /* Central Atlas Tamazight */
{"udm", HB_TAG('U','D','M',' ')}, /* Udmurt */
{"ug", HB_TAG('U','Y','G',' ')}, /* Uighur */
{"uk", HB_TAG('U','K','R',' ')}, /* Ukrainian */
{"umb", HB_TAG('M','B','N',' ')}, /* [South] Mbundu */
{"umb", HB_TAG('U','M','B',' ')}, /* Umbundu */
{"unr", HB_TAG('M','U','N',' ')}, /* Mundari */
{"ur", HB_TAG('U','R','D',' ')}, /* Urdu */
{"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek */
{"uz", HB_TAG('U','Z','B',' ')}, /* Uzbek [macrolanguage] */
{"uzn", HB_TAG('U','Z','B',' ')}, /* Northern Uzbek */
{"uzs", HB_TAG('U','Z','B',' ')}, /* Southern Uzbek */
{"ve", HB_TAG('V','E','N',' ')}, /* Venda */
{"vec", HB_TAG('V','E','C',' ')}, /* Venetian */
{"vls", HB_TAG('F','L','E',' ')}, /* Vlaams */
{"vi", HB_TAG('V','I','T',' ')}, /* Vietnamese */
{"vmw", HB_TAG('M','A','K',' ')}, /* Makua */
{"vmw", HB_TAG('M','A','K',' ')}, /* Makhuwa */
{"vo", HB_TAG('V','O','L',' ')}, /* Volapük */
{"vro", HB_TAG('V','R','O',' ')}, /* Võro */
{"wa", HB_TAG('W','L','N',' ')}, /* Walloon */
{"war", HB_TAG('W','A','R',' ')}, /* Waray (Philippines) */
{"wbm", HB_TAG('W','A',' ',' ')}, /* Wa */
{"wbr", HB_TAG('W','A','G',' ')}, /* Wagdi */
{"wle", HB_TAG('S','I','G',' ')}, /* Wolane */
{"wry", HB_TAG('M','A','W',' ')}, /* Merwari */
{"wtm", HB_TAG('W','T','M',' ')}, /* Mewati */
{"wo", HB_TAG('W','L','F',' ')}, /* Wolof */
{"xal", HB_TAG('K','L','M',' ')}, /* Kalmyk */
{"xh", HB_TAG('X','H','S',' ')}, /* Xhosa */
{"xog", HB_TAG('X','O','G',' ')}, /* Soga */
{"xom", HB_TAG('K','M','O',' ')}, /* Komo (Sudan) */
{"xsl", HB_TAG('S','S','L',' ')}, /* South Slavey */
{"yi", HB_TAG('J','I','I',' ')}, /* Yiddish */
{"xst", HB_TAG('S','I','G',' ')}, /* Silt'e (retired code) */
{"xwo", HB_TAG('T','O','D',' ')}, /* Written Oirat (Todo) */
{"yao", HB_TAG('Y','A','O',' ')}, /* Yao */
{"yi", HB_TAG('J','I','I',' ')}, /* Yiddish [macrolanguage] */
{"yo", HB_TAG('Y','B','A',' ')}, /* Yoruba */
{"yso", HB_TAG('N','I','S',' ')}, /* Nisi (China) */
{"za", HB_TAG('Z','H','A',' ')}, /* Chuang/Zhuang [macrolanguage] */
{"zea", HB_TAG('Z','E','A',' ')}, /* Zeeuws */
{"zne", HB_TAG('Z','N','D',' ')}, /* Zande */
{"zu", HB_TAG('Z','U','L',' ')} /* Zulu */
{"zu", HB_TAG('Z','U','L',' ')}, /* Zulu */
{"zum", HB_TAG('L','R','C',' ')} /* Kumzari */
/* The corresponding languages IDs for the following IDs are unclear,
* overlap, or are architecturally weird. Needs more research. */
@ -536,13 +722,13 @@ static const LangTag ot_languages[] = {
/*{"gsw?/gsw-FR?", HB_TAG('A','L','S',' ')},*/ /* Alsatian */
/*{"krc", HB_TAG('B','A','L',' ')},*/ /* Balkar */
/*{"??", HB_TAG('B','C','R',' ')},*/ /* Bible Cree */
/*{"sgw?", HB_TAG('C','H','G',' ')},*/ /* Chaha Gurage */
/*{"zh?", HB_TAG('C','H','N',' ')},*/ /* Chinese (seen in Microsoft fonts) */
/*{"acf/gcf?", HB_TAG('F','A','N',' ')},*/ /* French Antillean */
/*{"vls/nl-be", HB_TAG('F','L','E',' ')},*/ /* Flemish */
/*{"enf?/yrk?", HB_TAG('F','N','E',' ')},*/ /* Forest Nenets */
/*{"fuf?", HB_TAG('F','T','A',' ')},*/ /* Futa */
/*{"ar-Syrc?", HB_TAG('G','A','R',' ')},*/ /* Garshuni */
/*{"cfm/rnl?", HB_TAG('H','A','L',' ')},*/ /* Halam */
/*{"fonipa", HB_TAG('I','P','P','H')},*/ /* Phonetic transcription—IPA conventions */
/*{"ga-Latg?/Latg?", HB_TAG('I','R','T',' ')},*/ /* Irish Traditional */
/*{"krc", HB_TAG('K','A','R',' ')},*/ /* Karachay */
/*{"alw?/ktb?", HB_TAG('K','E','B',' ')},*/ /* Kebena */
@ -559,8 +745,6 @@ static const LangTag ot_languages[] = {
/*{"??", HB_TAG('L','C','R',' ')},*/ /* L-Cree */
/*{"??", HB_TAG('M','A','L',' ')},*/ /* Malayalam Traditional */
/*{"mnk?/mlq?/...", HB_TAG('M','L','N',' ')},*/ /* Malinke */
/*{"man?/myq?/mku?/msc?/...", HB_TAG('M','N','K',' ')},*/ /* Maninka */
/*{"??", HB_TAG('M','O','R',' ')},*/ /* Moroccan */
/*{"??", HB_TAG('N','C','R',' ')},*/ /* N-Cree */
/*{"??", HB_TAG('N','H','C',' ')},*/ /* Norway House Cree */
/*{"jpa?/sam?", HB_TAG('P','A','A',' ')},*/ /* Palestinian Aramaic */
@ -569,14 +753,12 @@ static const LangTag ot_languages[] = {
/*{"??", HB_TAG('R','C','R',' ')},*/ /* R-Cree */
/*{"chp?", HB_TAG('S','A','Y',' ')},*/ /* Sayisi */
/*{"xan?", HB_TAG('S','E','K',' ')},*/ /* Sekota */
/*{"stv/wle?/xst?", HB_TAG('S','I','G',' ')},*/ /* Silte Gurage */
/*{"ngo?", HB_TAG('S','X','T',' ')},*/ /* Sutu */
/*{"??", HB_TAG('T','C','R',' ')},*/ /* TH-Cree */
/*{"tnz?/tog?/toi?", HB_TAG('T','N','G',' ')},*/ /* Tonga */
/*{"enh?/yrk?", HB_TAG('T','N','E',' ')},*/ /* Tundra Nenets */
/*{"??", HB_TAG('T','O','D',' ')},*/ /* Todo */
/*{"??", HB_TAG('W','C','R',' ')},*/ /* West-Cree */
/*{"??", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */
/*{"cre?", HB_TAG('Y','C','R',' ')},*/ /* Y-Cree */
/*{"??", HB_TAG('Y','I','C',' ')},*/ /* Yi Classic */
/*{"ii?/Yiii?", HB_TAG('Y','I','M',' ')},*/ /* Yi Modern */
/*{"??", HB_TAG('Z','H','P',' ')},*/ /* Chinese Phonetic */

View File

@ -79,6 +79,9 @@ static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; }
template <typename Type>
static inline Type MAX (const Type &a, const Type &b) { return a > b ? a : b; }
static inline unsigned int DIV_CEIL (const unsigned int a, unsigned int b)
{ return (a + (b - 1)) / b; }
#undef ARRAY_LENGTH
template <typename Type, unsigned int n>

View File

@ -39,12 +39,15 @@ struct hb_shape_plan_t
ASSERT_POD ();
hb_bool_t default_shaper_list;
hb_face_t *face;
hb_face_t *face_unsafe; /* We don't carry a reference to face. */
hb_segment_properties_t props;
hb_shape_func_t *shaper_func;
const char *shaper_name;
hb_feature_t *user_features;
unsigned int num_user_features;
struct hb_shaper_data_t shaper_data;
};

View File

@ -46,7 +46,7 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan,
#define HB_SHAPER_PLAN(shaper) \
HB_STMT_START { \
if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face)) { \
if (hb_##shaper##_shaper_face_data_ensure (shape_plan->face_unsafe)) { \
HB_SHAPER_DATA (shaper, shape_plan) = \
HB_SHAPER_DATA_CREATE_FUNC (shaper, shape_plan) (shape_plan, user_features, num_user_features); \
shape_plan->shaper_func = _hb_##shaper##_shape; \
@ -107,18 +107,27 @@ hb_shape_plan_create (hb_face_t *face,
assert (props->direction != HB_DIRECTION_INVALID);
hb_shape_plan_t *shape_plan;
hb_feature_t *features = NULL;
if (unlikely (!face))
face = hb_face_get_empty ();
if (unlikely (!props || hb_object_is_inert (face)))
return hb_shape_plan_get_empty ();
if (!(shape_plan = hb_object_create<hb_shape_plan_t> ()))
if (num_user_features && !(features = (hb_feature_t *) malloc (num_user_features * sizeof (hb_feature_t))))
return hb_shape_plan_get_empty ();
if (!(shape_plan = hb_object_create<hb_shape_plan_t> ())) {
free (features);
return hb_shape_plan_get_empty ();
}
hb_face_make_immutable (face);
shape_plan->default_shaper_list = shaper_list == NULL;
shape_plan->face = hb_face_reference (face);
shape_plan->face_unsafe = face;
shape_plan->props = *props;
shape_plan->num_user_features = num_user_features;
shape_plan->user_features = features;
if (num_user_features)
memcpy (features, user_features, num_user_features * sizeof (hb_feature_t));
hb_shape_plan_plan (shape_plan, user_features, num_user_features, shaper_list);
@ -147,6 +156,9 @@ hb_shape_plan_get_empty (void)
NULL, /* shaper_func */
NULL, /* shaper_name */
NULL, /* user_features */
0, /* num_user_featurs */
{
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
#include "hb-shaper-list.hh"
@ -190,7 +202,7 @@ hb_shape_plan_destroy (hb_shape_plan_t *shape_plan)
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
hb_face_destroy (shape_plan->face);
free (shape_plan->user_features);
free (shape_plan);
}
@ -264,7 +276,7 @@ hb_shape_plan_execute (hb_shape_plan_t *shape_plan,
hb_object_is_inert (buffer)))
return false;
assert (shape_plan->face == font->face);
assert (shape_plan->face_unsafe == font->face);
assert (hb_segment_properties_equal (&shape_plan->props, &buffer->props));
#define HB_SHAPER_EXECUTE(shaper) \
@ -301,23 +313,55 @@ hb_shape_plan_hash (const hb_shape_plan_t *shape_plan)
}
#endif
/* TODO no user-feature caching for now. */
/* User-feature caching is currently somewhat dumb:
* it only finds matches where the feature array is identical,
* not cases where the feature lists would be compatible for plan purposes
* but have different ranges, for example.
*/
struct hb_shape_plan_proposal_t
{
const hb_segment_properties_t props;
const char * const *shaper_list;
const hb_feature_t *user_features;
unsigned int num_user_features;
hb_shape_func_t *shaper_func;
};
static inline hb_bool_t
hb_shape_plan_user_features_match (const hb_shape_plan_t *shape_plan,
const hb_shape_plan_proposal_t *proposal)
{
if (proposal->num_user_features != shape_plan->num_user_features) return false;
for (unsigned int i = 0, n = proposal->num_user_features; i < n; i++)
if (proposal->user_features[i].tag != shape_plan->user_features[i].tag ||
proposal->user_features[i].value != shape_plan->user_features[i].value ||
proposal->user_features[i].start != shape_plan->user_features[i].start ||
proposal->user_features[i].end != shape_plan->user_features[i].end) return false;
return true;
}
static hb_bool_t
hb_shape_plan_matches (const hb_shape_plan_t *shape_plan,
const hb_shape_plan_proposal_t *proposal)
{
return hb_segment_properties_equal (&shape_plan->props, &proposal->props) &&
hb_shape_plan_user_features_match (shape_plan, proposal) &&
((shape_plan->default_shaper_list && proposal->shaper_list == NULL) ||
(shape_plan->shaper_func == proposal->shaper_func));
}
static inline hb_bool_t
hb_non_global_user_features_present (const hb_feature_t *user_features,
unsigned int num_user_features)
{
while (num_user_features)
if (user_features->start != 0 || user_features->end != (unsigned int) -1)
return true;
else
num_user_features--, user_features++;
return false;
}
/**
* hb_shape_plan_create_cached:
* @face:
@ -339,12 +383,11 @@ hb_shape_plan_create_cached (hb_face_t *face,
unsigned int num_user_features,
const char * const *shaper_list)
{
if (num_user_features)
return hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
hb_shape_plan_proposal_t proposal = {
*props,
shaper_list,
user_features,
num_user_features,
NULL
};
@ -382,6 +425,11 @@ retry:
hb_shape_plan_t *shape_plan = hb_shape_plan_create (face, props, user_features, num_user_features, shaper_list);
/* Don't add the plan to the cache if there were user features with non-global ranges */
if (hb_non_global_user_features_present (user_features, num_user_features))
return shape_plan;
hb_face_t::plan_node_t *node = (hb_face_t::plan_node_t *) calloc (1, sizeof (hb_face_t::plan_node_t));
if (unlikely (!node))
return shape_plan;
@ -395,9 +443,6 @@ retry:
goto retry;
}
/* Release our reference on face. */
hb_face_destroy (face);
return hb_shape_plan_reference (shape_plan);
}

View File

@ -729,18 +729,21 @@ _hb_uniscribe_shape (hb_shape_plan_t *shape_plan,
retry:
unsigned int scratch_size;
char *scratch = (char *) buffer->get_scratch_buffer (&scratch_size);
/* Allocate char buffers; they all fit */
hb_buffer_t::scratch_buffer_t *scratch = buffer->get_scratch_buffer (&scratch_size);
#define ALLOCATE_ARRAY(Type, name, len) \
Type *name = (Type *) scratch; \
scratch += (len) * sizeof ((name)[0]); \
scratch_size -= (len) * sizeof ((name)[0]);
{ \
unsigned int _consumed = DIV_CEIL ((len) * sizeof (Type), sizeof (*scratch)); \
assert (_consumed <= scratch_size); \
scratch += _consumed; \
scratch_size -= _consumed; \
}
#define utf16_index() var1.u32
WCHAR *pchars = (WCHAR *) scratch;
ALLOCATE_ARRAY (WCHAR, pchars, buffer->len * 2);
unsigned int chars_len = 0;
for (unsigned int i = 0; i < buffer->len; i++)
{
@ -756,7 +759,6 @@ retry:
}
}
ALLOCATE_ARRAY (WCHAR, wchars, chars_len);
ALLOCATE_ARRAY (WORD, log_clusters, chars_len);
ALLOCATE_ARRAY (SCRIPT_CHARPROP, char_props, chars_len);
@ -774,12 +776,13 @@ retry:
}
}
/* On Windows, we don't care about alignment...*/
unsigned int glyphs_size = scratch_size / (sizeof (WORD) +
sizeof (SCRIPT_GLYPHPROP) +
sizeof (int) +
sizeof (GOFFSET) +
sizeof (uint32_t));
/* All the following types are sized in multiples of sizeof(int). */
unsigned int glyphs_size = scratch_size / ((sizeof (WORD) +
sizeof (SCRIPT_GLYPHPROP) +
sizeof (int) +
sizeof (GOFFSET) +
sizeof (uint32_t))
/ sizeof (int));
ALLOCATE_ARRAY (WORD, glyphs, glyphs_size);
ALLOCATE_ARRAY (SCRIPT_GLYPHPROP, glyph_props, glyphs_size);
@ -812,7 +815,7 @@ retry:
bidi_state.uBidiLevel = HB_DIRECTION_IS_FORWARD (buffer->props.direction) ? 0 : 1;
bidi_state.fOverrideDirection = 1;
hr = funcs->ScriptItemizeOpenType (wchars,
hr = funcs->ScriptItemizeOpenType (pchars,
chars_len,
MAX_ITEMS,
&bidi_control,
@ -887,7 +890,7 @@ retry:
range_char_counts.array,
range_properties.array,
range_properties.len,
wchars + chars_offset,
pchars + chars_offset,
item_chars_len,
glyphs_size - glyphs_offset,
/* out */
@ -929,7 +932,7 @@ retry:
range_char_counts.array,
range_properties.array,
range_properties.len,
wchars + chars_offset,
pchars + chars_offset,
log_clusters + chars_offset,
char_props + chars_offset,
item_chars_len,

View File

@ -38,9 +38,9 @@ HB_BEGIN_DECLS
#define HB_VERSION_MAJOR 0
#define HB_VERSION_MINOR 9
#define HB_VERSION_MICRO 23
#define HB_VERSION_MICRO 24
#define HB_VERSION_STRING "0.9.23"
#define HB_VERSION_STRING "0.9.24"
#define HB_VERSION_CHECK(major,minor,micro) \
((major)*10000+(minor)*100+(micro) >= \