Merge branch 'master' into cff-subset

pull/1113/head
Michiharu Ariza 6 years ago
parent e7a045e4db
commit 55942ad5c1
  1. 10
      TODO
  2. 2
      configure.ac
  3. 4
      src/hb-aat-layout-common.hh
  4. 9
      src/hb-aat-layout-morx-table.hh
  5. 6
      src/hb-aat-layout.cc
  6. 2
      src/hb-aat-layout.hh
  7. 2
      src/hb-face.cc
  8. 2
      src/hb-machinery.hh
  9. 2
      src/hb-ot-cmap-table.hh
  10. 2
      src/hb-ot-post-table.hh
  11. 27
      src/hb-ot-shape.cc
  12. 5
      src/hb-ot-shape.hh
  13. 4
      src/hb-set.hh
  14. 2
      src/hb-subset.cc
  15. 100
      src/hb-vector.hh
  16. 35
      test/shaping/data/text-rendering-tests/DISABLED
  17. 18
      test/shaping/data/text-rendering-tests/Makefile.sources
  18. 18
      test/shaping/data/text-rendering-tests/extract-tests.py
  19. BIN
      test/shaping/data/text-rendering-tests/fonts/TestGSUBThree.ttf
  20. BIN
      test/shaping/data/text-rendering-tests/fonts/TestMORXThirtyfive.ttf
  21. BIN
      test/shaping/data/text-rendering-tests/fonts/TestMORXThirtyfour.ttf
  22. BIN
      test/shaping/data/text-rendering-tests/fonts/TestMORXThirtysix.ttf
  23. BIN
      test/shaping/data/text-rendering-tests/fonts/TestMORXThirtythree.ttf
  24. BIN
      test/shaping/data/text-rendering-tests/fonts/TestMORXTwentyfour.ttf
  25. 1
      test/shaping/data/text-rendering-tests/tests/GSUB-3.tests
  26. 1
      test/shaping/data/text-rendering-tests/tests/MORX-24.tests
  27. 8
      test/shaping/data/text-rendering-tests/tests/MORX-32.tests
  28. 3
      test/shaping/data/text-rendering-tests/tests/MORX-33.tests
  29. 1
      test/shaping/data/text-rendering-tests/tests/MORX-34.tests
  30. 2
      test/shaping/data/text-rendering-tests/tests/MORX-35.tests
  31. 1
      test/shaping/data/text-rendering-tests/tests/MORX-36.tests
  32. 19
      test/shaping/run-tests.py
  33. 2
      util/view-cairo.hh

10
TODO

@ -1,9 +1,3 @@
General fixes:
=============
- Implement 'rand' feature.
API issues:
===========
@ -19,12 +13,10 @@ API additions
- Add hb-cairo glue
- Add sanitize API (and a cached version, that saves result on blob user-data)
- Add sanitize API.
- BCP 47 language handling / API (language_matches?)
- Add hb_font_create_unscaled()?
- Add query / enumeration API for aalt-like features?
- Add segmentation API

@ -12,6 +12,7 @@ AC_CONFIG_HEADERS([config.h])
AM_INIT_AUTOMAKE([1.13.0 gnits tar-ustar dist-bzip2 no-dist-gzip -Wall no-define color-tests -Wno-portability])
AM_SILENT_RULES([yes])
AX_CODE_COVERAGE
AC_USE_SYSTEM_EXTENSIONS
# Initialize libtool
m4_ifdef([AM_PROG_AR], [AM_PROG_AR])
@ -19,7 +20,6 @@ LT_PREREQ([2.2])
LT_INIT([disable-static])
# Check for programs
AC_USE_SYSTEM_EXTENSIONS
AC_PROG_CC
AC_PROG_CC_C99
AM_PROG_CC_C_O

@ -546,8 +546,6 @@ struct StateTableDriver
template <typename context_t>
inline void drive (context_t *c)
{
hb_glyph_info_t *info = buffer->info;
if (!c->in_place)
buffer->clear_output ();
@ -556,7 +554,7 @@ struct StateTableDriver
for (buffer->idx = 0;;)
{
unsigned int klass = buffer->idx < buffer->len ?
machine.get_class (info[buffer->idx].codepoint, num_glyphs) :
machine.get_class (buffer->info[buffer->idx].codepoint, num_glyphs) :
(unsigned) StateTable<EntryData>::CLASS_END_OF_TEXT;
const Entry<EntryData> *entry = machine.get_entryZ (state, klass);
if (unlikely (!entry))

@ -592,6 +592,7 @@ struct InsertionSubtable
hb_aat_apply_context_t *c_) :
ret (false),
c (c_),
mark_set (false),
mark (0),
insertionAction (table+table->insertionAction) {}
@ -607,7 +608,7 @@ struct InsertionSubtable
hb_buffer_t *buffer = driver->buffer;
unsigned int flags = entry->flags;
if (entry->data.markedInsertIndex != 0xFFFF)
if (entry->data.markedInsertIndex != 0xFFFF && mark_set)
{
unsigned int count = (flags & MarkedInsertCount);
unsigned int start = entry->data.markedInsertIndex;
@ -668,7 +669,10 @@ struct InsertionSubtable
}
if (flags & SetMark)
{
mark_set = true;
mark = buffer->out_len;
}
return true;
}
@ -677,6 +681,7 @@ struct InsertionSubtable
bool ret;
private:
hb_aat_apply_context_t *c;
bool mark_set;
unsigned int mark;
const UnsizedArrayOf<GlyphID> &insertionAction;
};
@ -942,6 +947,8 @@ struct morx
{
static const hb_tag_t tableTag = HB_AAT_TAG_morx;
inline bool has_data (void) const { return version != 0; }
inline void apply (hb_aat_apply_context_t *c) const
{
if (unlikely (!c->buffer->successful)) return;

@ -55,6 +55,12 @@ _get_morx (hb_face_t *face, hb_blob_t **blob = nullptr)
return morx;
}
hb_bool_t
hb_aat_layout_has_substitution (hb_face_t *face)
{
return _get_morx (face).has_data ();
}
void
hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer)
{

@ -33,6 +33,8 @@
#include "hb-buffer.hh"
#include "hb-open-type.hh"
HB_INTERNAL hb_bool_t
hb_aat_layout_has_substitution (hb_face_t *face);
HB_INTERNAL void
hb_aat_layout_substitute (hb_font_t *font, hb_buffer_t *buffer);

@ -634,7 +634,7 @@ _hb_face_builder_data_reference_blob (hb_face_builder_data_t *data)
unsigned int face_length = table_count * 16 + 12;
for (unsigned int i = 0; i < table_count; i++)
face_length += hb_ceil_to_4 (hb_blob_get_length (data->tables.arrayZ[i].blob));
face_length += hb_ceil_to_4 (hb_blob_get_length (data->tables[i].blob));
char *buf = (char *) malloc (face_length);
if (unlikely (!buf))

@ -591,7 +591,7 @@ struct Supplier
}
inline Supplier (const hb_vector_t<Type> *v)
{
head = v->arrayZ;
head = v->arrayZ();
len = v->len;
stride = sizeof (Type);
}

@ -495,7 +495,7 @@ struct CmapSubtableLongSegmented
{
TRACE_SERIALIZE (this);
if (unlikely (!c->extend_min (*this))) return_trace (false);
Supplier<CmapSubtableLongGroup> supplier (group_data.arrayZ, group_data.len);
Supplier<CmapSubtableLongGroup> supplier (group_data.arrayZ(), group_data.len);
if (unlikely (!groups.serialize (c, supplier, group_data.len))) return_trace (false);
return true;
}

@ -242,7 +242,7 @@ struct post
if (index >= index_to_offset.len)
return hb_bytes_t ();
unsigned int offset = index_to_offset.arrayZ[index];
unsigned int offset = index_to_offset[index];
const uint8_t *data = pool + offset;
unsigned int name_length = *data;

@ -63,9 +63,14 @@ hb_ot_shape_planner_t::compile (hb_ot_shape_plan_t &plan,
plan.kerning_requested = !!plan.kern_mask;
plan.has_gpos_mark = !!plan.map.get_1_mask (HB_TAG ('m','a','r','k'));
plan.apply_morx = !hb_ot_layout_has_substitution (face) &&
hb_aat_layout_has_substitution (face);
bool disable_gpos = plan.shaper->gpos_tag &&
plan.shaper->gpos_tag != plan.map.chosen_script[1];
plan.fallback_positioning = disable_gpos || !hb_ot_layout_has_positioning (face);
plan.apply_gpos = !disable_gpos && hb_ot_layout_has_positioning (face);
plan.fallback_positioning = !plan.apply_gpos;
plan.fallback_glyph_classes = !hb_ot_layout_has_glyph_classes (face);
}
@ -127,9 +132,13 @@ hb_ot_shape_collect_features (hb_ot_shape_planner_t *planner,
/* Random! */
map->enable_feature (HB_TAG ('r','a','n','d'), F_RANDOM, HB_OT_MAP_MAX_VALUE);
map->enable_feature (HB_TAG('H','A','R','F'));
if (planner->shaper->collect_features)
planner->shaper->collect_features (planner);
map->enable_feature (HB_TAG('B','U','Z','Z'));
for (unsigned int i = 0; i < ARRAY_LENGTH (common_features); i++)
map->add_feature (common_features[i]);
@ -217,7 +226,13 @@ _hb_ot_shaper_shape_plan_data_create (hb_shape_plan_t *shape_plan,
hb_ot_shape_planner_t planner (shape_plan);
planner.shaper = hb_ot_shape_complex_categorize (&planner);
/* Ugly that we have to do this here...
* If we are going to apply morx, choose default shaper. */
if (!hb_ot_layout_has_substitution (planner.face) &&
hb_aat_layout_has_substitution (planner.face))
planner.shaper = &_hb_ot_complex_shaper_default;
else
planner.shaper = hb_ot_shape_complex_categorize (&planner);
hb_ot_shape_collect_features (&planner, &shape_plan->props,
user_features, num_user_features);
@ -661,10 +676,10 @@ hb_ot_substitute_complex (hb_ot_shape_context_t *c)
if (c->plan->fallback_glyph_classes)
hb_synthesize_glyph_classes (c);
c->plan->substitute (c->font, buffer);
if (0) /* XXX Call morx instead. */
if (unlikely (c->plan->apply_morx))
hb_aat_layout_substitute (c->font, c->buffer);
else
c->plan->substitute (c->font, buffer);
}
static inline void
@ -784,7 +799,7 @@ hb_ot_position_complex (hb_ot_shape_context_t *c)
break;
}
if (likely (!c->plan->fallback_positioning))
if (c->plan->apply_gpos)
c->plan->position (c->font, c->buffer);
switch (c->plan->shaper->zero_width_marks)

@ -49,6 +49,11 @@ struct hb_ot_shape_plan_t
bool fallback_positioning : 1;
bool fallback_glyph_classes : 1;
bool apply_morx : 1;
bool apply_gpos : 1;
inline void collect_lookups (hb_tag_t table_tag, hb_set_t *lookups) const
{
unsigned int table_index;

@ -368,8 +368,8 @@ struct hb_set_t
if (!resize (count))
return;
population = other->population;
memcpy (pages.arrayZ, other->pages.arrayZ, count * sizeof (pages.arrayZ[0]));
memcpy (page_map.arrayZ, other->page_map.arrayZ, count * sizeof (page_map.arrayZ[0]));
memcpy (pages.arrayZ(), other->pages.arrayZ(), count * sizeof (pages.arrayZ()[0]));
memcpy (page_map.arrayZ(), other->page_map.arrayZ(), count * sizeof (page_map.arrayZ()[0]));
}
inline bool is_equal (const hb_set_t *other) const

@ -80,7 +80,7 @@ _subset2 (hb_subset_plan_t *plan)
return false;
}
retry:
hb_serialize_context_t serializer (buf.arrayZ, buf_size);
hb_serialize_context_t serializer (buf.arrayZ(), buf_size);
hb_subset_context_t c (plan, &serializer);
result = table->subset (&c);
if (serializer.ran_out_of_room)

@ -35,35 +35,42 @@ template <typename Type, unsigned int StaticSize=8>
struct hb_vector_t
{
unsigned int len;
private:
unsigned int allocated; /* == 0 means allocation failed. */
Type *arrayZ;
Type *arrayZ_;
Type static_array[StaticSize];
public:
void init (void)
{
len = 0;
allocated = ARRAY_LENGTH (static_array);
arrayZ = static_array;
arrayZ_ = nullptr;
}
inline Type * arrayZ (void)
{ return arrayZ_ ? arrayZ_ : static_array; }
inline const Type * arrayZ (void) const
{ return arrayZ_ ? arrayZ_ : static_array; }
inline Type& operator [] (unsigned int i)
{
if (unlikely (i >= len))
return Crap (Type);
return arrayZ[i];
return arrayZ()[i];
}
inline const Type& operator [] (unsigned int i) const
{
if (unlikely (i >= len))
return Null(Type);
return arrayZ[i];
return arrayZ()[i];
}
inline Type *push (void)
{
if (unlikely (!resize (len + 1)))
return &Crap(Type);
return &arrayZ[len - 1];
return &arrayZ()[len - 1];
}
inline Type *push (const Type& v)
{
@ -91,17 +98,17 @@ struct hb_vector_t
Type *new_array = nullptr;
if (arrayZ == static_array)
if (!arrayZ_)
{
new_array = (Type *) calloc (new_allocated, sizeof (Type));
if (new_array)
memcpy (new_array, arrayZ, len * sizeof (Type));
memcpy (new_array, static_array, len * sizeof (Type));
}
else
{
bool overflows = (new_allocated < allocated) || hb_unsigned_mul_overflows (new_allocated, sizeof (Type));
if (likely (!overflows))
new_array = (Type *) realloc (arrayZ, new_allocated * sizeof (Type));
new_array = (Type *) realloc (arrayZ_, new_allocated * sizeof (Type));
}
if (unlikely (!new_array))
@ -110,7 +117,7 @@ struct hb_vector_t
return false;
}
arrayZ = new_array;
arrayZ_ = new_array;
allocated = new_allocated;
return true;
@ -123,7 +130,7 @@ struct hb_vector_t
return false;
if (size > len)
memset (arrayZ + len, 0, (size - len) * sizeof (*arrayZ));
memset (arrayZ() + len, 0, (size - len) * sizeof (*arrayZ()));
len = size;
return true;
@ -137,12 +144,13 @@ struct hb_vector_t
inline void remove (unsigned int i)
{
if (unlikely (i >= len))
return;
memmove (static_cast<void *> (&arrayZ[i]),
static_cast<void *> (&arrayZ[i + 1]),
(len - i - 1) * sizeof (Type));
len--;
if (unlikely (i >= len))
return;
Type *array = arrayZ();
memmove (static_cast<void *> (&array[i]),
static_cast<void *> (&array[i + 1]),
(len - i - 1) * sizeof (Type));
len--;
}
inline void shrink (int size_)
@ -153,41 +161,55 @@ struct hb_vector_t
}
template <typename T>
inline Type *find (T v) {
inline Type *find (T v)
{
Type *array = arrayZ();
for (unsigned int i = 0; i < len; i++)
if (arrayZ[i] == v)
return &arrayZ[i];
if (array[i] == v)
return &array[i];
return nullptr;
}
template <typename T>
inline const Type *find (T v) const {
inline const Type *find (T v) const
{
const Type *array = arrayZ();
for (unsigned int i = 0; i < len; i++)
if (arrayZ[i] == v)
return &arrayZ[i];
if (array[i] == v)
return &array[i];
return nullptr;
}
inline void qsort (int (*cmp)(const void*, const void*))
{
::qsort (arrayZ, len, sizeof (Type), cmp);
::qsort (arrayZ(), len, sizeof (Type), cmp);
}
inline void qsort (void)
{
::qsort (arrayZ, len, sizeof (Type), Type::cmp);
::qsort (arrayZ(), len, sizeof (Type), Type::cmp);
}
inline void qsort (unsigned int start, unsigned int end)
{
::qsort (arrayZ + start, end - start, sizeof (Type), Type::cmp);
::qsort (arrayZ() + start, end - start, sizeof (Type), Type::cmp);
}
template <typename T>
inline Type *lsearch (const T &x)
{
Type *array = arrayZ();
for (unsigned int i = 0; i < len; i++)
if (0 == this->arrayZ[i].cmp (&x))
return &arrayZ[i];
if (0 == array[i].cmp (&x))
return &array[i];
return nullptr;
}
template <typename T>
inline const Type *lsearch (const T &x) const
{
const Type *array = arrayZ();
for (unsigned int i = 0; i < len; i++)
if (0 == array[i].cmp (&x))
return &array[i];
return nullptr;
}
@ -195,22 +217,23 @@ struct hb_vector_t
inline Type *bsearch (const T &x)
{
unsigned int i;
return bfind (x, &i) ? &arrayZ[i] : nullptr;
return bfind (x, &i) ? &arrayZ()[i] : nullptr;
}
template <typename T>
inline const Type *bsearch (const T &x) const
{
unsigned int i;
return bfind (x, &i) ? &arrayZ[i] : nullptr;
return bfind (x, &i) ? &arrayZ()[i] : nullptr;
}
template <typename T>
inline bool bfind (const T &x, unsigned int *i) const
{
int min = 0, max = (int) this->len - 1;
const Type *array = this->arrayZ();
while (min <= max)
{
int mid = (min + max) / 2;
int c = this->arrayZ[mid].cmp (&x);
int c = array[mid].cmp (&x);
if (c < 0)
max = mid - 1;
else if (c > 0)
@ -221,17 +244,26 @@ struct hb_vector_t
return true;
}
}
if (max < 0 || (max < (int) this->len && this->arrayZ[max].cmp (&x) > 0))
if (max < 0 || (max < (int) this->len && array[max].cmp (&x) > 0))
max++;
*i = max;
return false;
}
inline void fini_deep (void)
{
Type *array = arrayZ();
unsigned int count = len;
for (unsigned int i = 0; i < count; i++)
array[i].fini ();
fini ();
}
inline void fini (void)
{
if (arrayZ != static_array)
free (arrayZ);
arrayZ = nullptr;
if (arrayZ_)
free (arrayZ_);
arrayZ_ = nullptr;
allocated = len = 0;
}
};

@ -1,38 +1,9 @@
# https://github.com/harfbuzz/harfbuzz/issues/1224
tests/MORX-35.tests
# Non-Unicode cmap
tests/CMAP-3.tests
# Not hooked up
tests/MORX-1.tests
tests/MORX-2.tests
tests/MORX-3.tests
tests/MORX-4.tests
tests/MORX-5.tests
tests/MORX-6.tests
tests/MORX-7.tests
tests/MORX-8.tests
tests/MORX-9.tests
tests/MORX-10.tests
tests/MORX-11.tests
tests/MORX-12.tests
tests/MORX-13.tests
tests/MORX-14.tests
tests/MORX-16.tests
tests/MORX-17.tests
tests/MORX-18.tests
tests/MORX-19.tests
tests/MORX-20.tests
tests/MORX-21.tests
tests/MORX-22.tests
tests/MORX-23.tests
tests/MORX-25.tests
tests/MORX-26.tests
tests/MORX-27.tests
tests/MORX-28.tests
tests/MORX-29.tests
tests/MORX-30.tests
tests/MORX-31.tests
tests/MORX-32.tests
# Rounding differences
tests/SHARAN-1.tests
tests/SHBALI-1.tests

@ -15,6 +15,7 @@ TESTS = \
tests/GPOS-5.tests \
tests/GSUB-1.tests \
tests/GSUB-2.tests \
tests/GSUB-3.tests \
tests/GVAR-1.tests \
tests/GVAR-2.tests \
tests/GVAR-3.tests \
@ -28,12 +29,6 @@ TESTS = \
tests/HVAR-2.tests \
tests/KERN-1.tests \
tests/KERN-2.tests \
tests/SHBALI-3.tests \
tests/SHKNDA-1.tests \
$(NULL)
DISBALED_TESTS = \
tests/CMAP-3.tests \
tests/MORX-10.tests \
tests/MORX-11.tests \
tests/MORX-12.tests \
@ -48,6 +43,7 @@ DISBALED_TESTS = \
tests/MORX-21.tests \
tests/MORX-22.tests \
tests/MORX-23.tests \
tests/MORX-24.tests \
tests/MORX-25.tests \
tests/MORX-26.tests \
tests/MORX-27.tests \
@ -57,6 +53,9 @@ DISBALED_TESTS = \
tests/MORX-30.tests \
tests/MORX-31.tests \
tests/MORX-32.tests \
tests/MORX-33.tests \
tests/MORX-34.tests \
tests/MORX-36.tests \
tests/MORX-3.tests \
tests/MORX-4.tests \
tests/MORX-5.tests \
@ -64,6 +63,13 @@ DISBALED_TESTS = \
tests/MORX-7.tests \
tests/MORX-8.tests \
tests/MORX-9.tests \
tests/SHBALI-3.tests \
tests/SHKNDA-1.tests \
$(NULL)
DISBALED_TESTS = \
tests/MORX-35.tests \
tests/CMAP-3.tests \
tests/SHARAN-1.tests \
tests/SHBALI-1.tests \
tests/SHBALI-2.tests \

@ -28,12 +28,13 @@ def glyphstr(glyphs):
html = ET.fromstring(sys.stdin.read())
found = False
for elt in html.findall(".//*[@class='expected'][@ft:id]", namespaces):
found = True
name = elt.get(ns('ft:id'))
text = elt.get(ns('ft:render'))
font = elt.get(ns('ft:font'))
vars = elt.get(ns('ft:var'), '').replace(':', '=').replace(';', ',')
variations = elt.get(ns('ft:var'), '').replace(':', '=').replace(';', ',')
glyphs = []
for use in elt.findall(".//use"):
x = int(use.get('x'))
@ -43,8 +44,19 @@ for elt in html.findall(".//*[@class='expected'][@ft:id]", namespaces):
glyphname = '.'.join(href[1:].split('/')[1].split('.')[1:])
glyphs.append((glyphname, x, y))
opts = '--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft'
if vars:
opts = opts + ' --variations=%s' % vars
if variations:
opts = opts + ' --variations=%s' % variations
print ("../fonts/%s:%s:%s:%s" % (font, opts, unistr(text), glyphstr(glyphs)))
for elt in html.findall(".//*[@class='should-not-crash'][@ft:id]", namespaces):
found = True
name = elt.get(ns('ft:id'))
text = elt.get(ns('ft:render'))
font = elt.get(ns('ft:font'))
variations = elt.get(ns('ft:var'), '').replace(':', '=').replace(';', ',')
opts = ''
if variations:
opts = '--variations=%s' % variations
print ("../fonts/%s:%s:%s:*" % (font, opts, unistr(text)))
sys.exit(0 if found else 1)

@ -0,0 +1 @@
../fonts/TestGSUBThree.ttf::U+006C,U+006F,U+006C:*

@ -0,0 +1 @@
../fonts/TestMORXTwentyfour.ttf::U+0041,U+0042,U+0043,U+0044,U+0045:*

@ -1,4 +1,4 @@
../fonts/TestMORXThirtytwo.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041:[I|N@830,0|S@1660,0|A@2490,0]
../fonts/TestMORXThirtytwo.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0059:[I|N@830,0|S@1660,0|X@2490,0|A@2854,0|Y@3684,0]
../fonts/TestMORXThirtytwo.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0042:[B|I@830,0|N@1660,0|S@2490,0]
../fonts/TestMORXThirtytwo.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0042,U+0059:[X|I@364,0|N@1194,0|S@2024,0|B@2854,0|Y@3684,0]
../fonts/TestMORXThirtytwo.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041:[A]
../fonts/TestMORXThirtytwo.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0059:[X|A@364,0|Y@1194,0]
../fonts/TestMORXThirtytwo.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0042:[B]
../fonts/TestMORXThirtytwo.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0042,U+0059:[X|B@364,0|Y@1194,0]

@ -0,0 +1,3 @@
../fonts/TestMORXThirtythree.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0068,U+0061:[h|a@618,0|h@1179,0|a@1797,0]
../fonts/TestMORXThirtythree.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0068,U+0061,U+0068,U+0061:[h|a@618,0|h@1179,0|a@1797,0|h@2358,0|a@2976,0|h@3537,0|a@4155,0]
../fonts/TestMORXThirtythree.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0061,U+0068:[a|h@561,0]

@ -0,0 +1 @@
../fonts/TestMORXThirtyfour.ttf::U+0068,U+0061:*

@ -0,0 +1,2 @@
../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0041:[A|B@639,0|C@1265,0]
../fonts/TestMORXThirtyfive.ttf:--font-size=1000 --ned --remove-default-ignorables --font-funcs=ft:U+0058,U+0041,U+0059:[X|A@586,0|B@1225,0|C@1851,0|E@2447,0|Y@3003,0]

@ -0,0 +1 @@
../fonts/TestMORXThirtysix.ttf::U+0041:*

@ -19,8 +19,6 @@ if not args or sys.argv[1].find('hb-shape') == -1 or not os.path.exists (sys.arg
sys.exit (1)
hb_shape, args = args[0], args[1:]
extra_options = "--verify"
fails = 0
reference = False
@ -48,6 +46,11 @@ for filename in args:
cwd = os.path.dirname(filename)
fontfile = os.path.normpath (os.path.join (cwd, fontfile))
extra_options = ["--shaper=ot"]
glyphs_expected = glyphs_expected.strip()
if glyphs_expected != '*':
extra_options.append("--verify")
if line.startswith ("#"):
if not reference:
print ("# %s %s --unicodes %s" % (hb_shape, fontfile, unicodes))
@ -55,19 +58,19 @@ for filename in args:
if not reference:
print ("%s %s %s %s --unicodes %s" %
(hb_shape, fontfile, extra_options, options, unicodes))
(hb_shape, fontfile, ' '.join(extra_options), options, unicodes))
glyphs1, returncode = cmd ([hb_shape, "--font-funcs=ft",
fontfile, extra_options, "--unicodes",
fontfile] + extra_options + ["--unicodes",
unicodes] + (options.split (' ') if options else []))
if returncode:
print ("hb-shape --font-funcs=ft failed.") # file=sys.stderr
print ("ERROR: hb-shape --font-funcs=ft failed.") # file=sys.stderr
fails = fails + 1
#continue
glyphs2, returncode = cmd ([hb_shape, "--font-funcs=ot",
fontfile, extra_options, "--unicodes",
fontfile] + extra_options + ["--unicodes",
unicodes] + (options.split (' ') if options else []))
if returncode:
@ -75,7 +78,7 @@ for filename in args:
fails = fails + 1
#continue
if glyphs1 != glyphs2:
if glyphs1 != glyphs2 and glyphs_expected != '*':
print ("FT funcs: " + glyphs1) # file=sys.stderr
print ("OT funcs: " + glyphs2) # file=sys.stderr
fails = fails + 1
@ -84,7 +87,7 @@ for filename in args:
print (":".join ([fontfile, options, unicodes, glyphs1]))
continue
if glyphs1.strip() != glyphs_expected.strip() and glyphs_expected.strip() != '*':
if glyphs1.strip() != glyphs_expected and glyphs_expected != '*':
print ("Actual: " + glyphs1) # file=sys.stderr
print ("Expected: " + glyphs_expected) # file=sys.stderr
fails = fails + 1

@ -46,7 +46,7 @@ struct view_cairo_t
void init (hb_buffer_t *buffer, const font_options_t *font_opts)
{
lines = g_array_new (false, false, sizeof (helper_cairo_line_t));
scale_bits = -font_opts->subpixel_bits;
scale_bits = - (int) font_opts->subpixel_bits;
}
void new_line (void)
{

Loading…
Cancel
Save