Merge branch 'master' into cff-subset
This commit is contained in:
commit
fc0153a1d4
@ -155,6 +155,10 @@ HB_BUFFER_SERIALIZE_FLAGS_DEFAULT
|
||||
HB_SCRIPT_CANADIAN_ABORIGINAL
|
||||
hb_font_funcs_set_glyph_func
|
||||
hb_font_get_glyph_func_t
|
||||
hb_ot_layout_table_choose_script
|
||||
hb_ot_layout_table_find_script
|
||||
hb_ot_tag_from_language
|
||||
hb_ot_tags_from_script
|
||||
hb_set_invert
|
||||
hb_unicode_eastasian_width_func_t
|
||||
hb_unicode_eastasian_width
|
||||
@ -497,12 +501,12 @@ hb_ot_layout_lookups_substitute_closure
|
||||
hb_ot_layout_lookup_would_substitute
|
||||
hb_ot_layout_script_find_language
|
||||
hb_ot_layout_script_get_language_tags
|
||||
hb_ot_layout_table_choose_script
|
||||
hb_ot_layout_script_select_language
|
||||
hb_ot_layout_table_find_feature_variations
|
||||
hb_ot_layout_table_find_script
|
||||
hb_ot_layout_table_get_feature_tags
|
||||
hb_ot_layout_table_get_script_tags
|
||||
hb_ot_layout_table_get_lookup_count
|
||||
hb_ot_layout_table_select_script
|
||||
hb_ot_shape_plan_collect_lookups
|
||||
hb_ot_layout_language_get_required_feature_index
|
||||
<SUBSECTION Private>
|
||||
@ -550,12 +554,14 @@ hb_ot_math_get_glyph_assembly
|
||||
|
||||
<SECTION>
|
||||
<FILE>hb-ot-tag</FILE>
|
||||
HB_OT_MAX_TAGS_PER_LANGUAGE
|
||||
HB_OT_MAX_TAGS_PER_SCRIPT
|
||||
HB_OT_TAG_DEFAULT_LANGUAGE
|
||||
HB_OT_TAG_DEFAULT_SCRIPT
|
||||
hb_ot_tag_from_language
|
||||
hb_ot_tag_to_language
|
||||
hb_ot_tag_to_script
|
||||
hb_ot_tags_from_script
|
||||
hb_ot_tags_from_script_and_language
|
||||
hb_ot_tags_to_script_and_language
|
||||
</SECTION>
|
||||
|
||||
<SECTION>
|
||||
|
@ -291,11 +291,12 @@ GENERATORS = \
|
||||
gen-emoji-table.py \
|
||||
gen-indic-table.py \
|
||||
gen-os2-unicode-ranges.py \
|
||||
gen-tag-table.py \
|
||||
gen-use-table.py \
|
||||
$(NULL)
|
||||
EXTRA_DIST += $(GENERATORS)
|
||||
|
||||
unicode-tables: arabic-table indic-table use-table emoji-table
|
||||
unicode-tables: arabic-table indic-table tag-table use-table emoji-table
|
||||
|
||||
arabic-table: gen-arabic-table.py ArabicShaping.txt UnicodeData.txt Blocks.txt
|
||||
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-arabic-table.hh \
|
||||
@ -305,6 +306,10 @@ indic-table: gen-indic-table.py IndicSyllabicCategory.txt IndicPositionalCategor
|
||||
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-indic-table.cc \
|
||||
|| ($(RM) $(srcdir)/hb-ot-shape-complex-indic-table.cc; false)
|
||||
|
||||
tag-table: gen-tag-table.py languagetags language-subtag-registry
|
||||
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-tag-table.hh \
|
||||
|| ($(RM) $(srcdir)/hb-ot-tag-table.hh; false)
|
||||
|
||||
use-table: gen-use-table.py IndicSyllabicCategory.txt IndicPositionalCategory.txt UnicodeData.txt Blocks.txt
|
||||
$(AM_V_GEN) $(builddir)/$^ > $(srcdir)/hb-ot-shape-complex-use-table.cc \
|
||||
|| ($(RM) $(srcdir)/hb-ot-shape-complex-use-table.cc; false)
|
||||
@ -315,7 +320,7 @@ emoji-table: gen-emoji-table.py emoji-data.txt
|
||||
|
||||
built-sources: $(BUILT_SOURCES)
|
||||
|
||||
.PHONY: unicode-tables arabic-table indic-table use-table emoji-table built-sources
|
||||
.PHONY: unicode-tables arabic-table indic-table tag-table use-table emoji-table built-sources
|
||||
|
||||
RAGEL_GENERATED = \
|
||||
$(patsubst %,$(srcdir)/%,$(HB_BASE_RAGEL_GENERATED_sources)) \
|
||||
|
@ -43,6 +43,7 @@ HB_BASE_sources = \
|
||||
hb-ot-os2-unicode-ranges.hh \
|
||||
hb-ot-post-macroman.hh \
|
||||
hb-ot-post-table.hh \
|
||||
hb-ot-tag-table.hh \
|
||||
hb-ot-tag.cc \
|
||||
hb.hh \
|
||||
hb-set-digest.hh \
|
||||
|
1126
src/gen-tag-table.py
Executable file
1126
src/gen-tag-table.py
Executable file
File diff suppressed because it is too large
Load Diff
@ -164,7 +164,7 @@ struct LookupFormat4
|
||||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 2 */
|
||||
HBUINT16 format; /* Format identifier--format = 4 */
|
||||
VarSizedBinSearchArrayOf<LookupSegmentArray<T> >
|
||||
segments; /* The actual segments. These must already be sorted,
|
||||
* according to the first word in each one (the last
|
||||
@ -187,7 +187,7 @@ struct LookupSingle
|
||||
GlyphID glyph; /* Last GlyphID */
|
||||
T value; /* The lookup value (only one) */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4 + T::static_size);
|
||||
DEFINE_SIZE_STATIC (2 + T::static_size);
|
||||
};
|
||||
|
||||
template <typename T>
|
||||
@ -386,6 +386,8 @@ struct StateTable
|
||||
const HBUINT16 *states = (this+stateArrayTable).arrayZ;
|
||||
const Entry<Extra> *entries = (this+entryTable).arrayZ;
|
||||
|
||||
unsigned int num_classes = nClasses;
|
||||
|
||||
unsigned int num_states = 1;
|
||||
unsigned int num_entries = 0;
|
||||
|
||||
@ -393,13 +395,16 @@ struct StateTable
|
||||
unsigned int entry = 0;
|
||||
while (state < num_states)
|
||||
{
|
||||
if (unlikely (hb_unsigned_mul_overflows (num_classes, states[0].static_size)))
|
||||
return_trace (false);
|
||||
|
||||
if (unlikely (!c->check_array (states,
|
||||
num_states,
|
||||
states[0].static_size * nClasses)))
|
||||
num_classes * states[0].static_size)))
|
||||
return_trace (false);
|
||||
{ /* Sweep new states. */
|
||||
const HBUINT16 *stop = &states[num_states * nClasses];
|
||||
for (const HBUINT16 *p = &states[state * nClasses]; p < stop; p++)
|
||||
const HBUINT16 *stop = &states[num_states * num_classes];
|
||||
for (const HBUINT16 *p = &states[state * num_classes]; p < stop; p++)
|
||||
num_entries = MAX<unsigned int> (num_entries, *p + 1);
|
||||
state = num_states;
|
||||
}
|
||||
|
@ -996,7 +996,7 @@ hb_buffer_get_script (hb_buffer_t *buffer)
|
||||
* are orthogonal to the scripts, and though they are related, they are
|
||||
* different concepts and should not be confused with each other.
|
||||
*
|
||||
* Use hb_language_from_string() to convert from ISO 639 language codes to
|
||||
* Use hb_language_from_string() to convert from BCP 47 language tags to
|
||||
* #hb_language_t.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
|
@ -325,14 +325,14 @@ retry:
|
||||
/**
|
||||
* hb_language_from_string:
|
||||
* @str: (array length=len) (element-type uint8_t): a string representing
|
||||
* ISO 639 language code
|
||||
* a BCP 47 language tag
|
||||
* @len: length of the @str, or -1 if it is %NULL-terminated.
|
||||
*
|
||||
* Converts @str representing an ISO 639 language code to the corresponding
|
||||
* Converts @str representing a BCP 47 language tag to the corresponding
|
||||
* #hb_language_t.
|
||||
*
|
||||
* Return value: (transfer none):
|
||||
* The #hb_language_t corresponding to the ISO 639 language code.
|
||||
* The #hb_language_t corresponding to the BCP 47 language tag.
|
||||
*
|
||||
* Since: 0.9.2
|
||||
**/
|
||||
|
@ -211,6 +211,29 @@ hb_font_get_glyph_kerning_for_direction (hb_font_t *font,
|
||||
hb_direction_t direction,
|
||||
hb_position_t *x, hb_position_t *y);
|
||||
|
||||
/* Like hb_ot_layout_table_find_script, but takes zero-terminated array of scripts to test */
|
||||
HB_EXTERN HB_DEPRECATED hb_bool_t
|
||||
hb_ot_layout_table_choose_script (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
const hb_tag_t *script_tags,
|
||||
unsigned int *script_index,
|
||||
hb_tag_t *chosen_script);
|
||||
|
||||
HB_EXTERN HB_DEPRECATED hb_bool_t
|
||||
hb_ot_layout_script_find_language (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
hb_tag_t language_tag,
|
||||
unsigned int *language_index);
|
||||
|
||||
HB_EXTERN HB_DEPRECATED void
|
||||
hb_ot_tags_from_script (hb_script_t script,
|
||||
hb_tag_t *script_tag_1,
|
||||
hb_tag_t *script_tag_2);
|
||||
|
||||
HB_EXTERN HB_DEPRECATED hb_tag_t
|
||||
hb_ot_tag_from_language (hb_language_t language);
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
|
@ -33,6 +33,8 @@
|
||||
|
||||
#include <graphite2/Segment.h>
|
||||
|
||||
#include "hb-ot-tag.h"
|
||||
|
||||
|
||||
HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, face)
|
||||
HB_SHAPER_DATA_ENSURE_DEFINE(graphite2, font)
|
||||
@ -277,11 +279,16 @@ _hb_graphite2_shape (hb_shape_plan_t *shape_plan,
|
||||
|
||||
/* TODO ensure_native_direction. */
|
||||
|
||||
hb_tag_t script_tag[2];
|
||||
hb_ot_tags_from_script (hb_buffer_get_script (buffer), &script_tag[0], &script_tag[1]);
|
||||
hb_tag_t script_tag[HB_OT_MAX_TAGS_PER_SCRIPT];
|
||||
unsigned int count = HB_OT_MAX_TAGS_PER_SCRIPT;
|
||||
hb_ot_tags_from_script_and_language (hb_buffer_get_script (buffer),
|
||||
HB_LANGUAGE_INVALID,
|
||||
&count,
|
||||
script_tag,
|
||||
nullptr, nullptr);
|
||||
|
||||
seg = gr_make_seg (nullptr, grface,
|
||||
script_tag[1] == HB_TAG_NONE ? script_tag[0] : script_tag[1],
|
||||
count ? script_tag[count - 1] : HB_OT_TAG_DEFAULT_SCRIPT,
|
||||
feats,
|
||||
gr_utf32, chars, buffer->len,
|
||||
2 | (hb_buffer_get_direction (buffer) == HB_DIRECTION_RTL ? 1 : 0));
|
||||
|
@ -833,7 +833,7 @@ struct VarSizedBinSearchArrayOf
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
return_trace (header.sanitize (c) &&
|
||||
Type::static_size >= header.unitSize &&
|
||||
Type::static_size <= header.unitSize &&
|
||||
c->check_array (bytesZ.arrayZ, header.nUnits, header.unitSize));
|
||||
}
|
||||
|
||||
|
@ -973,22 +973,22 @@ struct CursivePosFormat1
|
||||
hb_buffer_t *buffer = c->buffer;
|
||||
|
||||
const EntryExitRecord &this_record = entryExitRecord[(this+coverage).get_coverage (buffer->cur().codepoint)];
|
||||
if (!this_record.exitAnchor) return_trace (false);
|
||||
if (!this_record.entryAnchor) return_trace (false);
|
||||
|
||||
hb_ot_apply_context_t::skipping_iterator_t &skippy_iter = c->iter_input;
|
||||
skippy_iter.reset (buffer->idx, 1);
|
||||
if (!skippy_iter.next ()) return_trace (false);
|
||||
if (!skippy_iter.prev ()) return_trace (false);
|
||||
|
||||
const EntryExitRecord &next_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)];
|
||||
if (!next_record.entryAnchor) return_trace (false);
|
||||
const EntryExitRecord &prev_record = entryExitRecord[(this+coverage).get_coverage (buffer->info[skippy_iter.idx].codepoint)];
|
||||
if (!prev_record.exitAnchor) return_trace (false);
|
||||
|
||||
unsigned int i = buffer->idx;
|
||||
unsigned int j = skippy_iter.idx;
|
||||
unsigned int i = skippy_iter.idx;
|
||||
unsigned int j = buffer->idx;
|
||||
|
||||
buffer->unsafe_to_break (i, j);
|
||||
float entry_x, entry_y, exit_x, exit_y;
|
||||
(this+this_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
|
||||
(this+next_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
|
||||
(this+prev_record.exitAnchor).get_anchor (c, buffer->info[i].codepoint, &exit_x, &exit_y);
|
||||
(this+this_record.entryAnchor).get_anchor (c, buffer->info[j].codepoint, &entry_x, &entry_y);
|
||||
|
||||
hb_glyph_position_t *pos = buffer->pos;
|
||||
|
||||
@ -1035,7 +1035,7 @@ struct CursivePosFormat1
|
||||
* parent.
|
||||
*
|
||||
* Optimize things for the case of RightToLeft, as that's most common in
|
||||
* Arabinc. */
|
||||
* Arabic. */
|
||||
unsigned int child = i;
|
||||
unsigned int parent = j;
|
||||
hb_position_t x_offset = entry_x - exit_x;
|
||||
@ -1064,7 +1064,7 @@ struct CursivePosFormat1
|
||||
else
|
||||
pos[child].x_offset = x_offset;
|
||||
|
||||
buffer->idx = j;
|
||||
buffer->idx++;
|
||||
return_trace (true);
|
||||
}
|
||||
|
||||
|
@ -367,18 +367,37 @@ hb_ot_layout_table_choose_script (hb_face_t *face,
|
||||
const hb_tag_t *script_tags,
|
||||
unsigned int *script_index,
|
||||
hb_tag_t *chosen_script)
|
||||
{
|
||||
const hb_tag_t *t;
|
||||
for (t = script_tags; *t; t++);
|
||||
return hb_ot_layout_table_select_script (face, table_tag, t - script_tags, script_tags, script_index, chosen_script);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_layout_table_select_script:
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_ot_layout_table_select_script (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_count,
|
||||
const hb_tag_t *script_tags,
|
||||
unsigned int *script_index /* OUT */,
|
||||
hb_tag_t *chosen_script /* OUT */)
|
||||
{
|
||||
static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_NO_SCRIPT_INDEX), "");
|
||||
const OT::GSUBGPOS &g = get_gsubgpos_table (face, table_tag);
|
||||
unsigned int i;
|
||||
|
||||
while (*script_tags)
|
||||
for (i = 0; i < script_count; i++)
|
||||
{
|
||||
if (g.find_script_index (*script_tags, script_index)) {
|
||||
if (g.find_script_index (script_tags[i], script_index))
|
||||
{
|
||||
if (chosen_script)
|
||||
*chosen_script = *script_tags;
|
||||
*chosen_script = script_tags[i];
|
||||
return true;
|
||||
}
|
||||
script_tags++;
|
||||
}
|
||||
|
||||
/* try finding 'DFLT' */
|
||||
@ -463,14 +482,34 @@ hb_ot_layout_script_find_language (hb_face_t *face,
|
||||
unsigned int script_index,
|
||||
hb_tag_t language_tag,
|
||||
unsigned int *language_index)
|
||||
{
|
||||
return hb_ot_layout_script_select_language (face, table_tag, script_index, 1, &language_tag, language_index);
|
||||
}
|
||||
|
||||
/**
|
||||
* hb_ot_layout_script_select_language:
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
hb_bool_t
|
||||
hb_ot_layout_script_select_language (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_count,
|
||||
const hb_tag_t *language_tags,
|
||||
unsigned int *language_index /* OUT */)
|
||||
{
|
||||
static_assert ((OT::Index::NOT_FOUND_INDEX == HB_OT_LAYOUT_DEFAULT_LANGUAGE_INDEX), "");
|
||||
const OT::Script &s = get_gsubgpos_table (face, table_tag).get_script (script_index);
|
||||
unsigned int i;
|
||||
|
||||
if (s.find_lang_sys_index (language_tag, language_index))
|
||||
return true;
|
||||
for (i = 0; i < language_count; i++)
|
||||
{
|
||||
if (s.find_lang_sys_index (language_tags[i], language_index))
|
||||
return true;
|
||||
}
|
||||
|
||||
/* try with 'dflt'; MS site has had typos and many fonts use it now :( */
|
||||
/* try finding 'dflt' */
|
||||
if (s.find_lang_sys_index (HB_OT_TAG_DEFAULT_LANGUAGE, language_index))
|
||||
return false;
|
||||
|
||||
@ -743,11 +782,12 @@ _hb_ot_layout_collect_features_languages (hb_face_t *face,
|
||||
for (; *languages; languages++)
|
||||
{
|
||||
unsigned int language_index;
|
||||
if (hb_ot_layout_script_find_language (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
*languages,
|
||||
&language_index))
|
||||
if (hb_ot_layout_script_select_language (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
1,
|
||||
languages,
|
||||
&language_index))
|
||||
_hb_ot_layout_collect_features_features (face,
|
||||
table_tag,
|
||||
script_index,
|
||||
|
@ -111,13 +111,13 @@ hb_ot_layout_table_find_script (hb_face_t *face,
|
||||
hb_tag_t script_tag,
|
||||
unsigned int *script_index);
|
||||
|
||||
/* Like find_script, but takes zero-terminated array of scripts to test */
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_table_choose_script (hb_face_t *face,
|
||||
hb_ot_layout_table_select_script (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_count,
|
||||
const hb_tag_t *script_tags,
|
||||
unsigned int *script_index,
|
||||
hb_tag_t *chosen_script);
|
||||
unsigned int *script_index /* OUT */,
|
||||
hb_tag_t *chosen_script /* OUT */);
|
||||
|
||||
HB_EXTERN unsigned int
|
||||
hb_ot_layout_table_get_feature_tags (hb_face_t *face,
|
||||
@ -135,11 +135,12 @@ hb_ot_layout_script_get_language_tags (hb_face_t *face,
|
||||
hb_tag_t *language_tags /* OUT */);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_script_find_language (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
hb_tag_t language_tag,
|
||||
unsigned int *language_index);
|
||||
hb_ot_layout_script_select_language (hb_face_t *face,
|
||||
hb_tag_t table_tag,
|
||||
unsigned int script_index,
|
||||
unsigned int language_count,
|
||||
const hb_tag_t *language_tags,
|
||||
unsigned int *language_index /* OUT */);
|
||||
|
||||
HB_EXTERN hb_bool_t
|
||||
hb_ot_layout_language_get_required_feature_index (hb_face_t *face,
|
||||
|
@ -54,16 +54,17 @@ hb_ot_map_builder_t::hb_ot_map_builder_t (hb_face_t *face_,
|
||||
/* Fetch script/language indices for GSUB/GPOS. We need these later to skip
|
||||
* features not available in either table and not waste precious bits for them. */
|
||||
|
||||
hb_tag_t script_tags[3] = {HB_TAG_NONE, HB_TAG_NONE, HB_TAG_NONE};
|
||||
hb_tag_t language_tag;
|
||||
unsigned int script_count = HB_OT_MAX_TAGS_PER_SCRIPT;
|
||||
unsigned int language_count = HB_OT_MAX_TAGS_PER_LANGUAGE;
|
||||
hb_tag_t script_tags[HB_OT_MAX_TAGS_PER_SCRIPT];
|
||||
hb_tag_t language_tags[HB_OT_MAX_TAGS_PER_LANGUAGE];
|
||||
|
||||
hb_ot_tags_from_script (props.script, &script_tags[0], &script_tags[1]);
|
||||
language_tag = hb_ot_tag_from_language (props.language);
|
||||
hb_ot_tags_from_script_and_language (props.script, props.language, &script_count, script_tags, &language_count, language_tags);
|
||||
|
||||
for (unsigned int table_index = 0; table_index < 2; table_index++) {
|
||||
hb_tag_t table_tag = table_tags[table_index];
|
||||
found_script[table_index] = (bool) hb_ot_layout_table_choose_script (face, table_tag, script_tags, &script_index[table_index], &chosen_script[table_index]);
|
||||
hb_ot_layout_script_find_language (face, table_tag, script_index[table_index], language_tag, &language_index[table_index]);
|
||||
found_script[table_index] = (bool) hb_ot_layout_table_select_script (face, table_tag, script_count, script_tags, &script_index[table_index], &chosen_script[table_index]);
|
||||
hb_ot_layout_script_select_language (face, table_tag, script_index[table_index], language_count, language_tags, &language_index[table_index]);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -611,6 +611,7 @@ modifier_combining_marks[] =
|
||||
0x06E3u, /* ARABIC SMALL LOW SEEN */
|
||||
0x06E7u, /* ARABIC SMALL HIGH YEH */
|
||||
0x06E8u, /* ARABIC SMALL HIGH NOON */
|
||||
0x08D3u, /* ARABIC SMALL LOW WAW */
|
||||
0x08F3u, /* ARABIC SMALL HIGH WAW */
|
||||
};
|
||||
|
||||
|
@ -375,6 +375,25 @@ final_reordering (const hb_ot_shape_plan_t *plan,
|
||||
}
|
||||
|
||||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
|
||||
{
|
||||
collect_features_myanmar,
|
||||
override_features_myanmar,
|
||||
nullptr, /* data_create */
|
||||
nullptr, /* data_destroy */
|
||||
nullptr, /* preprocess_text */
|
||||
nullptr, /* postprocess_glyphs */
|
||||
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
|
||||
nullptr, /* decompose */
|
||||
nullptr, /* compose */
|
||||
setup_masks_myanmar,
|
||||
HB_TAG_NONE, /* gpos_tag */
|
||||
nullptr, /* reorder_marks */
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
|
||||
false, /* fallback_position */
|
||||
};
|
||||
|
||||
|
||||
/* Uniscribe seems to have a shaper for 'mymr' that is like the
|
||||
* generic shaper, except that it zeros mark advances GDEF_LATE. */
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old =
|
||||
@ -395,20 +414,24 @@ const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_old =
|
||||
true, /* fallback_position */
|
||||
};
|
||||
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar =
|
||||
|
||||
/* Ugly Zawgyi encoding.
|
||||
* Disable all auto processing.
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/1162 */
|
||||
const hb_ot_complex_shaper_t _hb_ot_complex_shaper_myanmar_zawgyi =
|
||||
{
|
||||
collect_features_myanmar,
|
||||
override_features_myanmar,
|
||||
nullptr, /* collect_features */
|
||||
nullptr, /* override_features */
|
||||
nullptr, /* data_create */
|
||||
nullptr, /* data_destroy */
|
||||
nullptr, /* preprocess_text */
|
||||
nullptr, /* postprocess_glyphs */
|
||||
HB_OT_SHAPE_NORMALIZATION_MODE_COMPOSED_DIACRITICS_NO_SHORT_CIRCUIT,
|
||||
HB_OT_SHAPE_NORMALIZATION_MODE_NONE,
|
||||
nullptr, /* decompose */
|
||||
nullptr, /* compose */
|
||||
setup_masks_myanmar,
|
||||
nullptr, /* setup_masks */
|
||||
HB_TAG_NONE, /* gpos_tag */
|
||||
nullptr, /* reorder_marks */
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_BY_GDEF_EARLY,
|
||||
HB_OT_SHAPE_ZERO_WIDTH_MARKS_NONE,
|
||||
false, /* fallback_position */
|
||||
};
|
||||
|
@ -58,6 +58,7 @@ enum hb_ot_shape_zero_width_marks_type_t {
|
||||
HB_COMPLEX_SHAPER_IMPLEMENT (khmer) \
|
||||
HB_COMPLEX_SHAPER_IMPLEMENT (myanmar) \
|
||||
HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_old) \
|
||||
HB_COMPLEX_SHAPER_IMPLEMENT (myanmar_zawgyi) \
|
||||
HB_COMPLEX_SHAPER_IMPLEMENT (thai) \
|
||||
HB_COMPLEX_SHAPER_IMPLEMENT (use) \
|
||||
/* ^--- Add new shapers here */
|
||||
@ -254,11 +255,13 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
|
||||
/* If the designer designed the font for the 'DFLT' script,
|
||||
* (or we ended up arbitrarily pick 'latn'), use the default shaper.
|
||||
* Otherwise, use the specific shaper.
|
||||
* Note that for some simple scripts, there may not be *any*
|
||||
* GSUB/GPOS needed, so there may be no scripts found! */
|
||||
*
|
||||
* If it's indy3 tag, send to USE. */
|
||||
if (planner->map.chosen_script[0] == HB_TAG ('D','F','L','T') ||
|
||||
planner->map.chosen_script[0] == HB_TAG ('l','a','t','n'))
|
||||
return &_hb_ot_complex_shaper_default;
|
||||
else if ((planner->map.chosen_script[0] & 0x000000FF) == '3')
|
||||
return &_hb_ot_complex_shaper_use;
|
||||
else
|
||||
return &_hb_ot_complex_shaper_indic;
|
||||
|
||||
@ -372,6 +375,10 @@ hb_ot_shape_complex_categorize (const hb_ot_shape_planner_t *planner)
|
||||
return &_hb_ot_complex_shaper_default;
|
||||
else
|
||||
return &_hb_ot_complex_shaper_use;
|
||||
|
||||
/* https://github.com/harfbuzz/harfbuzz/issues/1162 */
|
||||
case HB_SCRIPT_MYANMAR_ZAWGYI:
|
||||
return &_hb_ot_complex_shaper_myanmar_zawgyi;
|
||||
}
|
||||
}
|
||||
|
||||
|
2064
src/hb-ot-tag-table.hh
Normal file
2064
src/hb-ot-tag-table.hh
Normal file
File diff suppressed because it is too large
Load Diff
1127
src/hb-ot-tag.cc
1127
src/hb-ot-tag.cc
File diff suppressed because it is too large
Load Diff
@ -39,20 +39,39 @@ HB_BEGIN_DECLS
|
||||
#define HB_OT_TAG_DEFAULT_SCRIPT HB_TAG ('D', 'F', 'L', 'T')
|
||||
#define HB_OT_TAG_DEFAULT_LANGUAGE HB_TAG ('d', 'f', 'l', 't')
|
||||
|
||||
/**
|
||||
* HB_OT_MAX_TAGS_PER_SCRIPT:
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
#define HB_OT_MAX_TAGS_PER_SCRIPT 3u
|
||||
/**
|
||||
* HB_OT_MAX_TAGS_PER_LANGUAGE:
|
||||
*
|
||||
* Since: REPLACEME
|
||||
**/
|
||||
#define HB_OT_MAX_TAGS_PER_LANGUAGE 3u
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_tags_from_script (hb_script_t script,
|
||||
hb_tag_t *script_tag_1,
|
||||
hb_tag_t *script_tag_2);
|
||||
hb_ot_tags_from_script_and_language (hb_script_t script,
|
||||
hb_language_t language,
|
||||
unsigned int *script_count /* IN/OUT */,
|
||||
hb_tag_t *script_tags /* OUT */,
|
||||
unsigned int *language_count /* IN/OUT */,
|
||||
hb_tag_t *language_tags /* OUT */);
|
||||
|
||||
HB_EXTERN hb_script_t
|
||||
hb_ot_tag_to_script (hb_tag_t tag);
|
||||
|
||||
HB_EXTERN hb_tag_t
|
||||
hb_ot_tag_from_language (hb_language_t language);
|
||||
|
||||
HB_EXTERN hb_language_t
|
||||
hb_ot_tag_to_language (hb_tag_t tag);
|
||||
|
||||
HB_EXTERN void
|
||||
hb_ot_tags_to_script_and_language (hb_tag_t script_tag,
|
||||
hb_tag_t language_tag,
|
||||
hb_script_t *script /* OUT */,
|
||||
hb_language_t *language /* OUT */);
|
||||
|
||||
|
||||
HB_END_DECLS
|
||||
|
||||
|
@ -44,7 +44,7 @@ HB_BEGIN_DECLS
|
||||
* HB_UNICODE_MAX
|
||||
*
|
||||
* Since: 1.9.0
|
||||
*/
|
||||
**/
|
||||
#define HB_UNICODE_MAX 0x10FFFFu
|
||||
|
||||
|
||||
|
@ -478,6 +478,14 @@ _hb_memalign(void **memptr, size_t alignment, size_t size)
|
||||
#endif
|
||||
|
||||
|
||||
/*
|
||||
* For lack of a better place, put Zawgyi script hack here.
|
||||
* https://github.com/harfbuzz/harfbuzz/issues/1162
|
||||
*/
|
||||
|
||||
#define HB_SCRIPT_MYANMAR_ZAWGYI ((hb_script_t) HB_TAG ('Q','a','a','g'))
|
||||
|
||||
|
||||
/* Headers we include for everyone. Keep sorted. They express dependency amongst
|
||||
* themselves, but no other file should include them.*/
|
||||
#include "hb-atomic.hh"
|
||||
|
@ -58,10 +58,8 @@ hb_subset_test_open_font (const char *font_path)
|
||||
|
||||
hb_blob_t *blob = hb_blob_create_from_file (path);
|
||||
if (hb_blob_get_length (blob) == 0)
|
||||
{
|
||||
printf ("The test font is not found.");
|
||||
exit (1);
|
||||
}
|
||||
g_error ("Font not found.");
|
||||
|
||||
hb_face_t *face = hb_face_create (blob, 0);
|
||||
hb_blob_destroy (blob);
|
||||
|
||||
|
@ -149,10 +149,7 @@ main (int argc, char **argv)
|
||||
|
||||
hb_blob_t *blob = hb_blob_create_from_file (path);
|
||||
if (hb_blob_get_length (blob) == 0)
|
||||
{
|
||||
printf ("The test font is not found.");
|
||||
return 1;
|
||||
}
|
||||
g_error ("Font not found.");
|
||||
|
||||
hb_face_t *face = hb_face_create (blob, 0);
|
||||
font = hb_font_create (face);
|
||||
|
@ -37,50 +37,86 @@ static void
|
||||
test_simple_tags (const char *s, hb_script_t script)
|
||||
{
|
||||
hb_script_t tag;
|
||||
hb_tag_t t1, t2;
|
||||
unsigned int count = 2;
|
||||
hb_tag_t t[2];
|
||||
|
||||
g_test_message ("Testing script %c%c%c%c: tag %s", HB_UNTAG (hb_script_to_iso15924_tag (script)), s);
|
||||
tag = hb_tag_from_string (s, -1);
|
||||
|
||||
hb_ot_tags_from_script (script, &t1, &t2);
|
||||
hb_ot_tags_from_script_and_language (script,
|
||||
HB_LANGUAGE_INVALID,
|
||||
&count, t, NULL, NULL);
|
||||
|
||||
g_assert_cmphex (t1, ==, tag);
|
||||
g_assert_cmphex (t2, ==, HB_OT_TAG_DEFAULT_SCRIPT);
|
||||
if (count)
|
||||
g_assert_cmphex (t[0], ==, tag);
|
||||
else
|
||||
g_assert_cmphex (HB_TAG_CHAR4 ("DFLT"), ==, tag);
|
||||
|
||||
g_assert_cmphex (hb_ot_tag_to_script (tag), ==, script);
|
||||
}
|
||||
|
||||
static void
|
||||
test_indic_tags (const char *s1, const char *s2, hb_script_t script)
|
||||
test_script_tags_from_language (const char *s, const char *lang_s, hb_script_t script)
|
||||
{
|
||||
hb_script_t tag1, tag2;
|
||||
hb_script_t t1, t2;
|
||||
hb_script_t tag;
|
||||
unsigned int count = 1;
|
||||
hb_script_t t;
|
||||
|
||||
g_test_message ("Testing script %c%c%c%c: new tag %s, old tag %s", HB_UNTAG (hb_script_to_iso15924_tag (script)), s1, s2);
|
||||
g_test_message ("Testing script %c%c%c%c: script tag %s, language tag %s", HB_UNTAG (hb_script_to_iso15924_tag (script)), s, lang_s);
|
||||
tag = hb_tag_from_string (s, -1);
|
||||
|
||||
hb_ot_tags_from_script_and_language (script, hb_language_from_string (lang_s, -1), &count, &t, NULL, NULL);
|
||||
|
||||
if (count != 0)
|
||||
{
|
||||
g_assert_cmpuint (count, ==, 1);
|
||||
g_assert_cmphex (t, ==, tag);
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
test_indic_tags (const char *s1, const char *s2, const char *s3, hb_script_t script)
|
||||
{
|
||||
hb_script_t tag1, tag2, tag3;
|
||||
hb_script_t t[3];
|
||||
unsigned int count = 3;
|
||||
|
||||
g_test_message ("Testing script %c%c%c%c: USE tag %s, new tag %s, old tag %s", HB_UNTAG (hb_script_to_iso15924_tag (script)), s1, s2, s3);
|
||||
tag1 = hb_tag_from_string (s1, -1);
|
||||
tag2 = hb_tag_from_string (s2, -1);
|
||||
tag3 = hb_tag_from_string (s3, -1);
|
||||
|
||||
hb_ot_tags_from_script (script, &t1, &t2);
|
||||
hb_ot_tags_from_script_and_language (script,
|
||||
HB_LANGUAGE_INVALID,
|
||||
&count, t, NULL, NULL);
|
||||
|
||||
g_assert_cmphex (t1, ==, tag1);
|
||||
g_assert_cmphex (t2, ==, tag2);
|
||||
g_assert_cmpuint (count, ==, 3);
|
||||
g_assert_cmphex (t[0], ==, tag1);
|
||||
g_assert_cmphex (t[1], ==, tag2);
|
||||
g_assert_cmphex (t[2], ==, tag3);
|
||||
|
||||
g_assert_cmphex (hb_ot_tag_to_script (tag1), ==, script);
|
||||
g_assert_cmphex (hb_ot_tag_to_script (tag2), ==, script);
|
||||
g_assert_cmphex (hb_ot_tag_to_script (tag3), ==, script);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ot_tag_script_degenerate (void)
|
||||
{
|
||||
hb_tag_t t1, t2;
|
||||
hb_script_t t[2];
|
||||
unsigned int count = 2;
|
||||
|
||||
g_assert_cmphex (HB_TAG_CHAR4 ("DFLT"), ==, HB_OT_TAG_DEFAULT_SCRIPT);
|
||||
|
||||
/* HIRAGANA and KATAKANA both map to 'kana' */
|
||||
test_simple_tags ("kana", HB_SCRIPT_KATAKANA);
|
||||
hb_ot_tags_from_script (HB_SCRIPT_HIRAGANA, &t1, &t2);
|
||||
g_assert_cmphex (t1, ==, HB_TAG_CHAR4 ("kana"));
|
||||
g_assert_cmphex (t2, ==, HB_OT_TAG_DEFAULT_SCRIPT);
|
||||
|
||||
hb_ot_tags_from_script_and_language (HB_SCRIPT_HIRAGANA,
|
||||
HB_LANGUAGE_INVALID,
|
||||
&count, t, NULL, NULL);
|
||||
|
||||
g_assert_cmpuint (count, ==, 1);
|
||||
g_assert_cmphex (t[0], ==, HB_TAG_CHAR4 ("kana"));
|
||||
|
||||
test_simple_tags ("DFLT", HB_SCRIPT_INVALID);
|
||||
|
||||
@ -120,19 +156,41 @@ test_ot_tag_script_simple (void)
|
||||
test_simple_tags ("mand", HB_SCRIPT_MANDAIC);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ot_tag_script_from_language (void)
|
||||
{
|
||||
test_script_tags_from_language (NULL, NULL, HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language (NULL, "en", HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language ("copt", "en", HB_SCRIPT_COPTIC);
|
||||
test_script_tags_from_language (NULL, "x-hbsc", HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language ("copt", "x-hbsc", HB_SCRIPT_COPTIC);
|
||||
test_script_tags_from_language ("abc ", "x-hbscabc", HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language ("deva", "x-hbscdeva", HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language ("dev2", "x-hbscdev2", HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language ("dev3", "x-hbscdev3", HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language ("copt", "x-hbotpap0-hbsccopt", HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language (NULL, "en-x-hbsc", HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language ("copt", "en-x-hbsc", HB_SCRIPT_COPTIC);
|
||||
test_script_tags_from_language ("abc ", "en-x-hbscabc", HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language ("deva", "en-x-hbscdeva", HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language ("dev2", "en-x-hbscdev2", HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language ("dev3", "en-x-hbscdev3", HB_SCRIPT_INVALID);
|
||||
test_script_tags_from_language ("copt", "en-x-hbotpap0-hbsccopt", HB_SCRIPT_INVALID);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ot_tag_script_indic (void)
|
||||
{
|
||||
test_indic_tags ("bng2", "beng", HB_SCRIPT_BENGALI);
|
||||
test_indic_tags ("dev2", "deva", HB_SCRIPT_DEVANAGARI);
|
||||
test_indic_tags ("gjr2", "gujr", HB_SCRIPT_GUJARATI);
|
||||
test_indic_tags ("gur2", "guru", HB_SCRIPT_GURMUKHI);
|
||||
test_indic_tags ("knd2", "knda", HB_SCRIPT_KANNADA);
|
||||
test_indic_tags ("mlm2", "mlym", HB_SCRIPT_MALAYALAM);
|
||||
test_indic_tags ("ory2", "orya", HB_SCRIPT_ORIYA);
|
||||
test_indic_tags ("tml2", "taml", HB_SCRIPT_TAMIL);
|
||||
test_indic_tags ("tel2", "telu", HB_SCRIPT_TELUGU);
|
||||
test_indic_tags ("mym2", "mymr", HB_SCRIPT_MYANMAR);
|
||||
test_indic_tags ("bng3", "bng2", "beng", HB_SCRIPT_BENGALI);
|
||||
test_indic_tags ("dev3", "dev2", "deva", HB_SCRIPT_DEVANAGARI);
|
||||
test_indic_tags ("gjr3", "gjr2", "gujr", HB_SCRIPT_GUJARATI);
|
||||
test_indic_tags ("gur3", "gur2", "guru", HB_SCRIPT_GURMUKHI);
|
||||
test_indic_tags ("knd3", "knd2", "knda", HB_SCRIPT_KANNADA);
|
||||
test_indic_tags ("mlm3", "mlm2", "mlym", HB_SCRIPT_MALAYALAM);
|
||||
test_indic_tags ("ory3", "ory2", "orya", HB_SCRIPT_ORIYA);
|
||||
test_indic_tags ("tml3", "tml2", "taml", HB_SCRIPT_TAMIL);
|
||||
test_indic_tags ("tel3", "tel2", "telu", HB_SCRIPT_TELUGU);
|
||||
test_indic_tags ("mym3", "mym2", "mymr", HB_SCRIPT_MYANMAR);
|
||||
}
|
||||
|
||||
|
||||
@ -147,7 +205,16 @@ test_language_two_way (const char *tag_s, const char *lang_s)
|
||||
|
||||
g_test_message ("Testing language %s <-> tag %s", lang_s, tag_s);
|
||||
|
||||
g_assert_cmphex (tag, ==, hb_ot_tag_from_language (lang));
|
||||
hb_tag_t tag2;
|
||||
unsigned int count = 1;
|
||||
hb_ot_tags_from_script_and_language (HB_SCRIPT_INVALID,
|
||||
lang,
|
||||
NULL, NULL, &count, &tag2);
|
||||
|
||||
if (count)
|
||||
g_assert_cmphex (tag, ==, tag2);
|
||||
else
|
||||
g_assert_cmphex (tag, ==, HB_TAG_CHAR4 ("dflt"));
|
||||
g_assert (lang == hb_ot_tag_to_language (tag));
|
||||
}
|
||||
|
||||
@ -159,7 +226,16 @@ test_tag_from_language (const char *tag_s, const char *lang_s)
|
||||
|
||||
g_test_message ("Testing language %s -> tag %s", lang_s, tag_s);
|
||||
|
||||
g_assert_cmphex (tag, ==, hb_ot_tag_from_language (lang));
|
||||
hb_tag_t tag2;
|
||||
unsigned int count = 1;
|
||||
hb_ot_tags_from_script_and_language (HB_SCRIPT_INVALID,
|
||||
lang,
|
||||
NULL, NULL, &count, &tag2);
|
||||
|
||||
if (count)
|
||||
g_assert_cmphex (tag, ==, tag2);
|
||||
else
|
||||
g_assert_cmphex (tag, ==, HB_TAG_CHAR4 ("dflt"));
|
||||
}
|
||||
|
||||
static void
|
||||
@ -173,6 +249,32 @@ test_tag_to_language (const char *tag_s, const char *lang_s)
|
||||
g_assert (lang == hb_ot_tag_to_language (tag));
|
||||
}
|
||||
|
||||
static void
|
||||
test_tags_to_script_and_language (const char *script_tag_s,
|
||||
const char *lang_tag_s,
|
||||
const char *script_s,
|
||||
const char *lang_s)
|
||||
{
|
||||
hb_script_t actual_script[1];
|
||||
hb_language_t actual_lang[1];
|
||||
hb_tag_t script_tag = hb_tag_from_string (script_tag_s, -1);
|
||||
hb_tag_t lang_tag = hb_tag_from_string (lang_tag_s, -1);
|
||||
hb_ot_tags_to_script_and_language (script_tag, lang_tag, actual_script, actual_lang);
|
||||
g_assert_cmphex (*actual_script, ==, hb_tag_from_string (script_s, -1));
|
||||
g_assert_cmpstr (hb_language_to_string (*actual_lang), ==, lang_s);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ot_tags_to_script_and_language (void)
|
||||
{
|
||||
test_tags_to_script_and_language ("DFLT", "ENG", "", "en-x-hbscdflt");
|
||||
test_tags_to_script_and_language ("latn", "ENG", "Latn", "en");
|
||||
test_tags_to_script_and_language ("deva", "MAR", "Deva", "mr-x-hbscdeva");
|
||||
test_tags_to_script_and_language ("dev2", "MAR", "Deva", "mr-x-hbscdev2");
|
||||
test_tags_to_script_and_language ("dev3", "MAR", "Deva", "mr");
|
||||
test_tags_to_script_and_language ("qaa", "QTZ0", "Qaaa", "x-hbotqtz0-hbscqaa");
|
||||
}
|
||||
|
||||
static void
|
||||
test_ot_tag_language (void)
|
||||
{
|
||||
@ -230,27 +332,27 @@ test_ot_tag_language (void)
|
||||
|
||||
test_language_two_way ("TUA", "tru"); /* Turoyo Aramaic */
|
||||
|
||||
test_language_two_way ("ZHH", "zh-hk"); /* Chinese (Hong Kong) */
|
||||
|
||||
test_tag_from_language ("ZHS", "zh"); /* Chinese */
|
||||
test_tag_from_language ("ZHS", "zh-cn"); /* Chinese (China) */
|
||||
test_tag_from_language ("ZHS", "zh-sg"); /* Chinese (Singapore) */
|
||||
test_tag_from_language ("ZHH", "zh-mo"); /* Chinese (Macao) */
|
||||
test_tag_from_language ("ZHH", "zh-hant-mo"); /* Chinese (Macao) */
|
||||
test_tag_from_language ("ZHH", "zh-hk"); /* Chinese (Hong Kong) */
|
||||
test_language_two_way ("ZHH", "zh-HK"); /* Chinese (Hong Kong) */
|
||||
test_tag_from_language ("ZHH", "zH-HanT-hK"); /* Chinese (Hong Kong) */
|
||||
test_tag_from_language ("ZHT", "zh-tw"); /* Chinese (Taiwan) */
|
||||
test_tag_from_language ("ZHS", "zh-Hans"); /* Chinese (Simplified) */
|
||||
test_tag_from_language ("ZHT", "zh-Hant"); /* Chinese (Traditional) */
|
||||
test_language_two_way ("ZHS", "zh-Hans"); /* Chinese (Simplified) */
|
||||
test_language_two_way ("ZHT", "zh-Hant"); /* Chinese (Traditional) */
|
||||
test_tag_from_language ("ZHS", "zh-xx"); /* Chinese (Other) */
|
||||
|
||||
test_tag_from_language ("ZHS", "zh-Hans-TW");
|
||||
|
||||
test_tag_from_language ("ZHH", "yue");
|
||||
test_tag_from_language ("ZHH", "yue-Hant");
|
||||
test_tag_from_language ("ZHS", "yue-Hans");
|
||||
|
||||
test_tag_from_language ("ZHS", "zh"); /* Chinese */
|
||||
test_tag_from_language ("ZHS", "zh-xx");
|
||||
|
||||
test_tag_to_language ("ZHS", "zh-Hans");
|
||||
test_tag_to_language ("ZHT", "zh-Hant");
|
||||
test_tag_to_language ("ZHP", "x-hbotzhp");
|
||||
|
||||
test_language_two_way ("ABC", "x-hbotabc");
|
||||
test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc-zxc");
|
||||
test_tag_from_language ("ABC", "asdf-asdf-wer-x-hbotabc");
|
||||
@ -262,39 +364,64 @@ test_ot_tag_language (void)
|
||||
test_tag_from_language ("XYZ", "xyz"); /* Unknown ISO 639-3 */
|
||||
test_tag_from_language ("XYZ", "xyz-qw"); /* Unknown ISO 639-3 */
|
||||
|
||||
/*
|
||||
* Invalid input. The precise answer does not matter, as long as it
|
||||
* does not crash or get into an infinite loop.
|
||||
*/
|
||||
test_tag_from_language ("IPPH", "-fonipa");
|
||||
|
||||
/*
|
||||
* Tags that contain "-fonipa" as a substring but which do not contain
|
||||
* the subtag "fonipa".
|
||||
*/
|
||||
test_tag_from_language ("ENG", "en-fonipax");
|
||||
test_tag_from_language ("ENG", "en-x-fonipa");
|
||||
test_tag_from_language ("ENG", "en-a-fonipa");
|
||||
test_tag_from_language ("ENG", "en-a-qwe-b-fonipa");
|
||||
|
||||
/* International Phonetic Alphabet */
|
||||
test_tag_from_language ("IPPH", "en-fonipa");
|
||||
test_tag_from_language ("IPPH", "en-fonipax-fonipa");
|
||||
test_tag_from_language ("IPPH", "rm-CH-fonipa-sursilv-x-foobar");
|
||||
test_tag_from_language ("IPPH", "und-fonipa");
|
||||
test_language_two_way ("IPPH", "und-fonipa");
|
||||
test_tag_from_language ("IPPH", "zh-fonipa");
|
||||
test_tag_to_language ("IPPH", "und-fonipa");
|
||||
|
||||
/* North American Phonetic Alphabet (Americanist Phonetic Notation) */
|
||||
test_tag_from_language ("APPH", "en-fonnapa");
|
||||
test_tag_from_language ("APPH", "chr-fonnapa");
|
||||
test_tag_from_language ("APPH", "und-fonnapa");
|
||||
test_tag_to_language ("APPH", "und-fonnapa");
|
||||
test_language_two_way ("APPH", "und-fonnapa");
|
||||
|
||||
/* Khutsuri Georgian */
|
||||
test_tag_from_language ("KGE", "ka-Geok");
|
||||
test_language_two_way ("KGE", "und-Geok");
|
||||
|
||||
/* Irish Traditional */
|
||||
test_language_two_way ("IRT", "ga-Latg");
|
||||
|
||||
/* Moldavian */
|
||||
test_language_two_way ("MOL", "ro-MD");
|
||||
|
||||
/* Polytonic Greek */
|
||||
test_language_two_way ("PGR", "el-polyton");
|
||||
test_tag_from_language ("PGR", "el-CY-polyton");
|
||||
|
||||
/* Estrangela Syriac */
|
||||
test_tag_from_language ("SYRE", "aii-Syre");
|
||||
test_tag_from_language ("SYRE", "de-Syre");
|
||||
test_tag_from_language ("SYRE", "syr-Syre");
|
||||
test_tag_from_language ("SYRE", "und-Syre");
|
||||
test_tag_to_language ("SYRE", "und-Syre");
|
||||
test_language_two_way ("SYRE", "und-Syre");
|
||||
|
||||
/* Western Syriac */
|
||||
test_tag_from_language ("SYRJ", "aii-Syrj");
|
||||
test_tag_from_language ("SYRJ", "de-Syrj");
|
||||
test_tag_from_language ("SYRJ", "syr-Syrj");
|
||||
test_tag_from_language ("SYRJ", "und-Syrj");
|
||||
test_tag_to_language ("SYRJ", "und-Syrj");
|
||||
test_language_two_way ("SYRJ", "und-Syrj");
|
||||
|
||||
/* Eastern Syriac */
|
||||
test_tag_from_language ("SYRN", "aii-Syrn");
|
||||
test_tag_from_language ("SYRN", "de-Syrn");
|
||||
test_tag_from_language ("SYRN", "syr-Syrn");
|
||||
test_tag_from_language ("SYRN", "und-Syrn");
|
||||
test_tag_to_language ("SYRN", "und-Syrn");
|
||||
test_language_two_way ("SYRN", "und-Syrn");
|
||||
|
||||
/* Test that x-hbot overrides the base language */
|
||||
test_tag_from_language ("ABC", "fa-x-hbotabc-zxc");
|
||||
@ -303,6 +430,77 @@ test_ot_tag_language (void)
|
||||
test_tag_from_language ("ABC", "zh-cn-x-hbotabc-zxc");
|
||||
test_tag_from_language ("ABC", "zh-xy-x-hbotabc-zxc");
|
||||
test_tag_from_language ("ABC", "xyz-xy-x-hbotabc-zxc");
|
||||
|
||||
/* Unnormalized BCP 47 tags */
|
||||
test_tag_from_language ("ARA", "ar-aao");
|
||||
test_tag_from_language ("JBO", "art-lojban");
|
||||
test_tag_from_language ("KOK", "kok-gom");
|
||||
test_tag_from_language ("LTZ", "i-lux");
|
||||
test_tag_from_language ("MNG", "drh");
|
||||
test_tag_from_language ("MOR", "ar-ary");
|
||||
test_tag_from_language ("MOR", "ar-ary-DZ");
|
||||
test_tag_from_language ("NOR", "no-bok");
|
||||
test_tag_from_language ("NYN", "no-nyn");
|
||||
test_tag_from_language ("ZHS", "i-hak");
|
||||
test_tag_from_language ("ZHS", "zh-guoyu");
|
||||
test_tag_from_language ("ZHS", "zh-min");
|
||||
test_tag_from_language ("ZHS", "zh-min-nan");
|
||||
test_tag_from_language ("ZHS", "zh-xiang");
|
||||
|
||||
/* A UN M.49 region code, not an extended language subtag */
|
||||
test_tag_from_language ("ARA", "ar-001");
|
||||
}
|
||||
|
||||
static void
|
||||
test_tags (hb_script_t script,
|
||||
const char *lang_s,
|
||||
unsigned int script_count,
|
||||
unsigned int language_count,
|
||||
unsigned int expected_script_count,
|
||||
unsigned int expected_language_count,
|
||||
...)
|
||||
{
|
||||
va_list expected_tags;
|
||||
unsigned int i;
|
||||
hb_tag_t *script_tags = malloc (script_count * sizeof (hb_tag_t));
|
||||
hb_tag_t *language_tags = malloc (language_count * sizeof (hb_tag_t));
|
||||
g_assert_nonnull (script_tags);
|
||||
g_assert_nonnull (language_tags);
|
||||
hb_language_t lang = hb_language_from_string (lang_s, -1);
|
||||
va_start (expected_tags, expected_language_count);
|
||||
|
||||
hb_ot_tags_from_script_and_language (script, lang, &script_count, script_tags, &language_count, language_tags);
|
||||
|
||||
g_assert_cmpuint (script_count, ==, expected_script_count);
|
||||
g_assert_cmpuint (language_count, ==, expected_language_count);
|
||||
|
||||
for (i = 0; i < script_count + language_count; i++)
|
||||
{
|
||||
hb_tag_t expected_tag = hb_tag_from_string (va_arg (expected_tags, const char *), -1);
|
||||
hb_tag_t actual_tag = i < script_count ? script_tags[i] : language_tags[i - script_count];
|
||||
g_assert_cmphex (actual_tag, ==, expected_tag);
|
||||
}
|
||||
|
||||
free (script_tags);
|
||||
free (language_tags);
|
||||
va_end (expected_tags);
|
||||
}
|
||||
|
||||
static void
|
||||
test_ot_tag_full (void)
|
||||
{
|
||||
test_tags (HB_SCRIPT_INVALID, "en", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 0, 1, "ENG");
|
||||
test_tags (HB_SCRIPT_INVALID, "en-x-hbscdflt", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 1, 1, "DFLT", "ENG");
|
||||
test_tags (HB_SCRIPT_LATIN, "en", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 1, 1, "latn", "ENG");
|
||||
test_tags (HB_SCRIPT_LATIN, "en", 0, 0, 0, 0);
|
||||
test_tags (HB_SCRIPT_INVALID, "und-fonnapa", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 0, 1, "APPH");
|
||||
test_tags (HB_SCRIPT_INVALID, "en-fonnapa", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 0, 1, "APPH");
|
||||
test_tags (HB_SCRIPT_INVALID, "x-hbot1234-hbsc5678", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 1, 1, "5678", "1234");
|
||||
test_tags (HB_SCRIPT_INVALID, "x-hbsc5678-hbot1234", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 1, 1, "5678", "1234");
|
||||
test_tags (HB_SCRIPT_MALAYALAM, "ml", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 3, 2, "mlm3", "mlm2", "mlym", "MAL", "MLR");
|
||||
test_tags (HB_SCRIPT_MALAYALAM, "ml", 1, 1, 1, 1, "mlm3", "MAL");
|
||||
test_tags (HB_SCRIPT_INVALID, "xyz", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 0, 1, "XYZ");
|
||||
test_tags (HB_SCRIPT_INVALID, "xy", HB_OT_MAX_TAGS_PER_SCRIPT, HB_OT_MAX_TAGS_PER_LANGUAGE, 0, 0);
|
||||
}
|
||||
|
||||
int
|
||||
@ -312,9 +510,14 @@ main (int argc, char **argv)
|
||||
|
||||
hb_test_add (test_ot_tag_script_degenerate);
|
||||
hb_test_add (test_ot_tag_script_simple);
|
||||
hb_test_add (test_ot_tag_script_from_language);
|
||||
hb_test_add (test_ot_tag_script_indic);
|
||||
|
||||
hb_test_add (test_ot_tags_to_script_and_language);
|
||||
|
||||
hb_test_add (test_ot_tag_language);
|
||||
|
||||
hb_test_add (test_ot_tag_full);
|
||||
|
||||
return hb_test_run();
|
||||
}
|
||||
|
@ -2,7 +2,6 @@ if (HB_CHECK)
|
||||
file (READ "${CMAKE_CURRENT_SOURCE_DIR}/Makefile.am" MAKEFILEAM)
|
||||
extract_make_variable (hb_shape_fuzzer_SOURCES ${MAKEFILEAM})
|
||||
extract_make_variable (hb_subset_fuzzer_SOURCES ${MAKEFILEAM})
|
||||
extract_make_variable (hb_subset_get_codepoints_fuzzer_SOURCES ${MAKEFILEAM})
|
||||
|
||||
# TODO: enable these two
|
||||
#extract_make_variable (FUZZING_CPPFLAGS ${MAKEFILEAM}) # extracting regex fail
|
||||
@ -16,17 +15,13 @@ if (HB_CHECK)
|
||||
add_executable (hb-subset-fuzzer ${hb_subset_fuzzer_SOURCES})
|
||||
target_link_libraries (hb-subset-fuzzer harfbuzz-subset)
|
||||
|
||||
add_executable (hb-subset-get-codepoints-fuzzer ${hb_subset_get_codepoints_fuzzer_SOURCES})
|
||||
target_link_libraries (hb-subset-get-codepoints-fuzzer harfbuzz-subset)
|
||||
|
||||
target_compile_definitions(hb-shape-fuzzer PUBLIC ${FUZZING_CPPFLAGS})
|
||||
target_compile_definitions(hb-subset-fuzzer PUBLIC ${FUZZING_CPPFLAGS})
|
||||
target_compile_definitions(hb-subset-get-codepoints-fuzzer PUBLIC ${FUZZING_CPPFLAGS})
|
||||
|
||||
add_test (NAME hb-shape-fuzzer
|
||||
COMMAND "${PYTHON_EXECUTABLE}" run-shape-fuzzer-tests.py $<TARGET_FILE:hb-shape-fuzzer>
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
add_test (NAME hb-subset-fuzzer
|
||||
COMMAND "${PYTHON_EXECUTABLE}" run-subset-fuzzer-tests.py $<TARGET_FILE:hb-subset-fuzzer> $<TARGET_FILE:hb-subset-get-codepoints-fuzzer>
|
||||
COMMAND "${PYTHON_EXECUTABLE}" run-subset-fuzzer-tests.py $<TARGET_FILE:hb-subset-fuzzer>
|
||||
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR})
|
||||
endif ()
|
||||
|
@ -23,7 +23,6 @@ EXTRA_DIST += \
|
||||
check_PROGRAMS = \
|
||||
hb-shape-fuzzer \
|
||||
hb-subset-fuzzer \
|
||||
hb-subset-get-codepoints-fuzzer \
|
||||
$(NULL)
|
||||
|
||||
AM_CPPFLAGS = \
|
||||
@ -65,21 +64,6 @@ hb_subset_fuzzer_DEPENDENCIES = \
|
||||
lib \
|
||||
$(NULL)
|
||||
|
||||
hb_subset_get_codepoints_fuzzer_SOURCES = \
|
||||
hb-fuzzer.hh \
|
||||
hb-subset-get-codepoints-fuzzer.cc \
|
||||
main.cc \
|
||||
$(NULL)
|
||||
hb_subset_get_codepoints_fuzzer_LDADD = \
|
||||
$(top_builddir)/src/libharfbuzz-subset-fuzzing.la \
|
||||
$(NULL)
|
||||
hb_subset_get_codepoints_fuzzer_CPPFLAGS = \
|
||||
$(AM_CPPFLAGS) \
|
||||
$(NULL)
|
||||
hb_subset_get_codepoints_fuzzer_DEPENDENCIES = \
|
||||
lib \
|
||||
$(NULL)
|
||||
|
||||
check:
|
||||
EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-shape-fuzzer-tests.py
|
||||
EXEEXT="$(EXEEXT)" srcdir="$(srcdir)" builddir="$(builddir)" $(srcdir)/run-subset-fuzzer-tests.py
|
||||
|
@ -50,6 +50,11 @@ extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
HB_MEMORY_MODE_READONLY, NULL, NULL);
|
||||
hb_face_t *face = hb_face_create (blob, 0);
|
||||
|
||||
/* Just test this API here quickly. */
|
||||
hb_set_t *output = hb_set_create();
|
||||
hb_face_collect_unicodes (face, output);
|
||||
hb_set_destroy (output);
|
||||
|
||||
const hb_codepoint_t text[] =
|
||||
{
|
||||
'A', 'B', 'C', 'D', 'E', 'X', 'Y', 'Z', '1', '2',
|
||||
|
@ -1,23 +0,0 @@
|
||||
#include "hb-fuzzer.hh"
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "hb-subset.h"
|
||||
|
||||
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size)
|
||||
{
|
||||
hb_blob_t *blob = hb_blob_create ((const char *)data, size,
|
||||
HB_MEMORY_MODE_READONLY, NULL, NULL);
|
||||
hb_face_t *face = hb_face_create (blob, 0);
|
||||
|
||||
hb_set_t *output = hb_set_create();
|
||||
hb_face_collect_unicodes (face, output);
|
||||
|
||||
hb_set_destroy (output);
|
||||
hb_face_destroy (face);
|
||||
hb_blob_destroy (blob);
|
||||
|
||||
return 0;
|
||||
}
|
@ -10,7 +10,7 @@ int main(int argc, char **argv) {
|
||||
const char *font_data = hb_blob_get_data (blob, &len);
|
||||
if (len == 0)
|
||||
{
|
||||
printf ("The test font is not found.");
|
||||
printf ("Font not found.\n");
|
||||
exit (1);
|
||||
}
|
||||
|
||||
|
@ -8,7 +8,6 @@ srcdir = os.environ.get ("srcdir", ".")
|
||||
EXEEXT = os.environ.get ("EXEEXT", "")
|
||||
top_builddir = os.environ.get ("top_builddir", ".")
|
||||
hb_subset_fuzzer = os.path.join (top_builddir, "hb-subset-fuzzer" + EXEEXT)
|
||||
hb_subset_get_codepoints_fuzzer = os.path.join (top_builddir, "hb-subset-get-codepoints-fuzzer" + EXEEXT)
|
||||
|
||||
if not os.path.exists (hb_subset_fuzzer):
|
||||
if len (sys.argv) < 2 or not os.path.exists (sys.argv[1]):
|
||||
@ -18,14 +17,6 @@ please provide it as the first argument to the tool""")
|
||||
|
||||
hb_subset_fuzzer = sys.argv[1]
|
||||
|
||||
if not os.path.exists (hb_subset_get_codepoints_fuzzer):
|
||||
if len (sys.argv) < 3 or not os.path.exists (sys.argv[2]):
|
||||
print ("""Failed to find hb-subset-get-codepoints-fuzzer binary automatically,
|
||||
please provide it as the second argument to the tool""")
|
||||
sys.exit (1)
|
||||
|
||||
hb_subset_get_codepoints_fuzzer = sys.argv[2]
|
||||
|
||||
print ('hb_subset_fuzzer:', hb_subset_fuzzer)
|
||||
fails = 0
|
||||
|
||||
@ -41,9 +32,6 @@ for file in os.listdir (parent_path):
|
||||
print ("failed for %s" % path)
|
||||
fails = fails + 1
|
||||
|
||||
print ("running subset get codepoints fuzzer against %s" % path)
|
||||
p = subprocess.Popen ([hb_subset_get_codepoints_fuzzer, path])
|
||||
|
||||
if p.wait () != 0:
|
||||
print ("failed for %s" % path)
|
||||
fails = fails + 1
|
||||
|
@ -37,6 +37,7 @@ TESTS = \
|
||||
tests/mark-filtering-sets.tests \
|
||||
tests/mongolian-variation-selector.tests \
|
||||
tests/myanmar-syllable.tests \
|
||||
tests/myanmar-zawgyi.tests \
|
||||
tests/none-directional.tests \
|
||||
tests/rand.tests \
|
||||
tests/spaces.tests \
|
||||
@ -46,6 +47,7 @@ TESTS = \
|
||||
tests/tibetan-contractions-2.tests \
|
||||
tests/tibetan-vowels.tests \
|
||||
tests/use.tests \
|
||||
tests/use-indic3.tests \
|
||||
tests/use-marchen.tests \
|
||||
tests/use-syllable.tests \
|
||||
tests/variations-rvrn.tests \
|
||||
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -2,3 +2,4 @@
|
||||
../fonts/298c9e1d955f10f6f72c6915c3c6ff9bf9695cec.ttf::U+0643,U+0645,U+0645,U+062B,U+0644:[gid8=4+738|gid5=3@441,1197+0|gid6=3@0,432+405|gid9=2@0,477+500|gid9=1@0,577+452|gid10=0@20,1177+207]
|
||||
#../fonts/706c5d7b625f207bc0d874c67237aad6f1e9cd6f.ttf::U+0B1F,U+0B4D,U+0B1A,U+0B4D,U+0B1A:[ttaorya=0+1307|casubscriptorya=0@-242,104+-231|casubscriptnarroworya=0@20,104+507]
|
||||
../fonts/07f054357ff8638bac3711b422a1e31180bba863.ttf:--font-funcs=ot --no-glyph-names:U+0606,U+06E1:[2=0@40,502+0|1=0+1000]
|
||||
../fonts/9fc3e6960b3520e5304033ef5fd540285f72f14d.ttf::U+16F0A,U+16F57,U+16F8F:[u16F0A=0+422|u16F57=0@0,209+338|u16F8F=0+0]
|
||||
|
@ -10,3 +10,4 @@
|
||||
../fonts/6991b13ce889466be6de3f66e891de2bc0f117ee.ttf:--language=zh-HK:U+004A:[gid6=0+1000]
|
||||
../fonts/6991b13ce889466be6de3f66e891de2bc0f117ee.ttf:--language=zh-mo:U+004A:[gid6=0+1000]
|
||||
../fonts/6991b13ce889466be6de3f66e891de2bc0f117ee.ttf:--language=zh-Hant-mo:U+004A:[gid6=0+1000]
|
||||
../fonts/d3129450fafe5e5c98cfc25a4e71809b1b4d2855.ttf:--language=dv --no-glyph-names:U+007C:[2=0+156]
|
||||
|
1
test/shaping/data/in-house/tests/myanmar-zawgyi.tests
Normal file
1
test/shaping/data/in-house/tests/myanmar-zawgyi.tests
Normal file
@ -0,0 +1 @@
|
||||
../fonts/ab14b4eb9d7a67e293f51d30d719add06c9d6e06.ttf:--script=Qaag:U+1000,U+103A,U+1004,U+1037,U+1039,U+1041:[Ka=0+2217|Ya-Semivowel=0+286|Nga=2+1247|Dot Below=2+0|Virama-Killer=2+0|One-Myanmar=5+1247]
|
1
test/shaping/data/in-house/tests/use-indic3.tests
Normal file
1
test/shaping/data/in-house/tests/use-indic3.tests
Normal file
@ -0,0 +1 @@
|
||||
../fonts/3c96e7a303c58475a8c750bf4289bbe73784f37d.ttf::U+0C95,U+0CCD,U+0CB0:[uni0C95=0+1176|uni0CB0_uni0CCD.blwf=0+275]
|
@ -3,8 +3,9 @@
|
||||
dir=`mktemp -d`
|
||||
|
||||
out=/dev/stdout
|
||||
if test "x${1:0:3}" == 'x-o='; then
|
||||
out=${1:3}
|
||||
if test "x$1" == 'x-o'; then
|
||||
shift
|
||||
out=$1
|
||||
shift
|
||||
fi
|
||||
hb_shape=$1
|
||||
|
Loading…
Reference in New Issue
Block a user