From 5b70074edf1c12a9442037d54c03d3025bd93995 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 20 Dec 2018 15:38:59 -0500 Subject: [PATCH 01/20] Add hb_assign(obj, value) --- src/hb-machinery.hh | 2 +- src/hb-null.hh | 24 +++++++++++++++++++++++- src/hb-open-type.hh | 5 +++-- 3 files changed, 27 insertions(+), 4 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 1205b1fea..2070fd838 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -390,7 +390,7 @@ struct hb_sanitize_context_t : { if (this->may_edit (obj, hb_static_size (Type))) { - const_cast (obj)->set (v); + hb_assign (* const_cast (obj), v); return true; } return false; diff --git a/src/hb-null.hh b/src/hb-null.hh index 7ea2bab16..8a3e0d405 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -59,7 +59,10 @@ struct hb_null_size { enum { value = _hb_null_size >::value }; }; #define hb_null_size(T) hb_null_size::value -/* This doesn't belong here, but since is copy/paste from above, put it here. */ +/* These doesn't belong here, but since is copy/paste from above, put it here. */ + +/* hb_static_size (T) + * Returns T::static_size if T::min_size is defined, or sizeof (T) otherwise. */ template struct _hb_static_size @@ -74,6 +77,25 @@ struct hb_static_size #define hb_static_size(T) hb_static_size::value +/* hb_assign (obj, value) + * Calls obj.set (value) if obj.min_size is defined and value has different type + * from obj, or obj = v otherwise. */ + +template +struct _hb_assign +{ static inline void value (T &o, const V v) { o = v; } }; +template +struct _hb_assign > +{ static inline void value (T &o, const V v) { o.set (v); } }; +template +struct _hb_assign > +{ static inline void value (T &o, const T v) { o = v; } }; + +template +static inline void hb_assign (T &o, const V v) +{ _hb_assign >::value (o, v); }; + + /* * Null() */ diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 6517c6bfe..7f88279a7 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -553,12 +553,13 @@ struct ArrayOf if (unlikely (!c->extend (*this))) return_trace (false); return_trace (true); } - bool serialize (hb_serialize_context_t *c, hb_array_t items) + template + bool serialize (hb_serialize_context_t *c, hb_array_t items) { TRACE_SERIALIZE (this); if (unlikely (!serialize (c, items.len))) return_trace (false); for (unsigned int i = 0; i < items.len; i++) - arrayZ[i] = items[i]; + hb_assign (arrayZ[i], items[i]); return_trace (true); } From 87f7c83fffb7e64970be23c8e3c620d32a3b8f5b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 20 Dec 2018 15:54:17 -0500 Subject: [PATCH 02/20] [serializer] Add operator << Not sure if we are going to use it. But might incentivize us to. --- src/hb-machinery.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 2070fd838..9d2ae9555 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -599,6 +599,8 @@ struct hb_serialize_context_t memcpy (ret, &obj, size); return ret; } + template + hb_serialize_context_t &operator << (const Type &obj) { embed (obj); return *this; } template Type *extend_size (Type &obj, unsigned int size) From 4941e95f10fe0fe658752134a42b58896fb19c42 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 20 Dec 2018 21:48:57 -0500 Subject: [PATCH 03/20] 2.3.0 --- NEWS | 15 +++++++++++++++ configure.ac | 2 +- src/hb-aat-layout.cc | 6 +++--- src/hb-version.h | 4 ++-- 4 files changed, 21 insertions(+), 6 deletions(-) diff --git a/NEWS b/NEWS index ff4f6e29d..890c258d8 100644 --- a/NEWS +++ b/NEWS @@ -1,3 +1,18 @@ +Overview of changes leading to 2.3.0 +Thursday, December 20, 2018 +==================================== +- Fix regression on big-endian architectures. Ouch! +- Misc bug and build fixes. +- Fix subsetting of simple GSUB/GDEF. +- Merge CFF / CFF2 support contributed by Adobe. This mostly involves + the subsetter, but also get_glyph_extents on CFF fonts. + +New API in hb-aat.h: ++hb_aat_layout_has_substitution() ++hb_aat_layout_has_positioning() ++hb_aat_layout_has_tracking() + + Overview of changes leading to 2.2.0 Thursday, November 29, 2018 ==================================== diff --git a/configure.ac b/configure.ac index 4d7348eff..03155372b 100644 --- a/configure.ac +++ b/configure.ac @@ -1,6 +1,6 @@ AC_PREREQ([2.64]) AC_INIT([HarfBuzz], - [2.2.0], + [2.3.0], [https://github.com/harfbuzz/harfbuzz/issues/new], [harfbuzz], [http://harfbuzz.org/]) diff --git a/src/hb-aat-layout.cc b/src/hb-aat-layout.cc index 8a868a054..8de8205f5 100644 --- a/src/hb-aat-layout.cc +++ b/src/hb-aat-layout.cc @@ -209,7 +209,7 @@ hb_aat_layout_compile_map (const hb_aat_map_builder_t *mapper, * @face: * * Returns: - * Since: REPLACEME + * Since: 2.3.0 */ hb_bool_t hb_aat_layout_has_substitution (hb_face_t *face) @@ -270,7 +270,7 @@ hb_aat_layout_remove_deleted_glyphs (hb_buffer_t *buffer) * @face: * * Returns: - * Since: REPLACEME + * Since: 2.3.0 */ hb_bool_t hb_aat_layout_has_positioning (hb_face_t *face) @@ -300,7 +300,7 @@ hb_aat_layout_position (const hb_ot_shape_plan_t *plan, * @face: * * Returns: - * Since: REPLACEME + * Since: 2.3.0 */ hb_bool_t hb_aat_layout_has_tracking (hb_face_t *face) diff --git a/src/hb-version.h b/src/hb-version.h index 7c4a8ad4a..0c82d5bbb 100644 --- a/src/hb-version.h +++ b/src/hb-version.h @@ -37,10 +37,10 @@ HB_BEGIN_DECLS #define HB_VERSION_MAJOR 2 -#define HB_VERSION_MINOR 2 +#define HB_VERSION_MINOR 3 #define HB_VERSION_MICRO 0 -#define HB_VERSION_STRING "2.2.0" +#define HB_VERSION_STRING "2.3.0" #define HB_VERSION_ATLEAST(major,minor,micro) \ ((major)*10000+(minor)*100+(micro) <= \ From e6ebc9b6f89e62d888b3bcf926afd624f16f3e95 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 20 Dec 2018 23:13:36 -0500 Subject: [PATCH 04/20] Remove unused typedef --- src/hb-machinery.hh | 3 --- 1 file changed, 3 deletions(-) diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index 9d2ae9555..fdb7b0a0d 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -667,7 +667,6 @@ template struct BEInt { public: - typedef Type type; void set (Type V) { v = V; } operator Type () const { return v; } private: uint8_t v; @@ -676,7 +675,6 @@ template struct BEInt { public: - typedef Type type; void set (Type V) { v[0] = (V >> 8) & 0xFF; @@ -705,7 +703,6 @@ template struct BEInt { public: - typedef Type type; void set (Type V) { v[0] = (V >> 16) & 0xFF; From bd369773921b4891996bd21f325702e490f47ca4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 20 Dec 2018 23:14:24 -0500 Subject: [PATCH 05/20] Rename --- src/hb-array.hh | 2 +- src/hb-open-type.hh | 4 ++-- src/hb-vector.hh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index d4df16546..a7783511f 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -36,7 +36,7 @@ struct hb_sorted_array_t; template struct hb_array_t { - typedef Type ItemType; + typedef Type item_type_t; enum { item_size = hb_static_size (Type) }; /* diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 7f88279a7..8956f4530 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -352,7 +352,7 @@ static inline Type& operator + (Base &base, OffsetTo template struct UnsizedArrayOf { - typedef Type ItemType; + typedef Type item_type_t; enum { item_size = hb_static_size (Type) }; HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type); @@ -508,7 +508,7 @@ struct SortedUnsizedArrayOf : UnsizedArrayOf template struct ArrayOf { - typedef Type ItemType; + typedef Type item_type_t; enum { item_size = hb_static_size (Type) }; HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType); diff --git a/src/hb-vector.hh b/src/hb-vector.hh index d8e3f4ef1..0d98bd03e 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -34,7 +34,7 @@ template struct hb_vector_t { - typedef Type ItemType; + typedef Type item_type_t; enum { item_size = hb_static_size (Type) }; HB_NO_COPY_ASSIGN_TEMPLATE2 (hb_vector_t, Type, PreallocedCount); From a728c63a98281fd4a0661e17fc01171bc3205b27 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Thu, 20 Dec 2018 23:15:49 -0500 Subject: [PATCH 06/20] [vector] Add operator bool --- src/hb-vector.hh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/hb-vector.hh b/src/hb-vector.hh index 0d98bd03e..b4175c55e 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -89,6 +89,8 @@ struct hb_vector_t return arrayZ()[i]; } + explicit_operator bool () const { return len; } + hb_array_t as_array () { return hb_array (arrayZ(), len); } hb_array_t as_array () const From b80b97b549dacc10d314bf8b5fd4ace596ccdfe1 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 00:08:05 -0500 Subject: [PATCH 07/20] Revert "Remove unused hb-iter.hh" This reverts commit 969ff3c7aadbe721cdd414488eb170433f10d00c. --- src/Makefile.sources | 1 + src/hb-iter.hh | 146 +++++++++++++++++++++++++++++++++++++++++++ src/hb-machinery.hh | 1 + 3 files changed, 148 insertions(+) create mode 100644 src/hb-iter.hh diff --git a/src/Makefile.sources b/src/Makefile.sources index 98b622889..0da4abe05 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -36,6 +36,7 @@ HB_BASE_sources = \ hb-face.hh \ hb-font.cc \ hb-font.hh \ + hb-iter.hh \ hb-kern.hh \ hb-machinery.hh \ hb-map.cc \ diff --git a/src/hb-iter.hh b/src/hb-iter.hh new file mode 100644 index 000000000..a269968db --- /dev/null +++ b/src/hb-iter.hh @@ -0,0 +1,146 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_ITER_HH +#define HB_ITER_HH + +#include "hb.hh" + + +/* Unified iterator object. + * + * The goal of this template is to make the same iterator interface + * available to all types, and make it very easy and compact to use. + * Iterator objects are small, light-weight, objects that can be + * copied by value. If the collection / object being iterated on + * is writable, then the iterator points to lvalues, otherwise it + * returns rvalues. + * + * The way to declare, initialize, and use iterators, eg.: + * + * Iter s (src); + * Iter t (dst); + * for (; s && t; s++, t++) + * *s = *t; + */ + +template +struct Iter; + +#if 0 +template +struct Iter +{ + Iter (const T &c); +}; +#endif + +template +struct Iter +{ + /* Type of items. */ + typedef T Value; + + /* Constructors. */ + Iter (T *array_, int length_) : + array (array_), length (MAX (length_, 0)) {} + template + Iter (T (&array_)[length_]) : + array (array_), length (length_) {} + + /* Emptiness. */ + explicit_operator bool () const { return length; } + + /* Current item. */ + T &operator * () + { + if (unlikely (!length)) return CrapOrNull(T); + return *array; + } + T &operator -> () { return (operator *); } + + /* Next. */ + Iter & operator ++ () + { + if (unlikely (!length)) return *this; + array++; + length--; + return *this; + } + /* Might return void, or a copy of pre-increment iterator. */ + void operator ++ (int) + { + if (unlikely (!length)) return; + array++; + length--; + } + + /* Some iterators might implement len(). */ + unsigned int len () const { return length; } + + /* Some iterators might implement fast-forward. + * Only implement it if it's constant-time. */ + void operator += (unsigned int n) + { + n = MIN (n, length); + array += n; + length -= n; + } + + /* Some iterators might implement random-access. + * Only implement it if it's constant-time. */ + Iter & operator [] (unsigned int i) + { + if (unlikely (i >= length)) return CrapOrNull(T); + return array[i]; + } + + private: + T *array; + unsigned int length; +}; + +/* XXX Remove + * Just to test these compile. */ +static inline void +m () +{ + const int src[10] = {}; + int dst[20]; + + Iter s (src); + Iter s2 (src, 5); + Iter t (dst); + + s2 = s; + + for (; s && t; ++s, ++t) + { + *t = *s; + } +} + +#endif /* HB_ITER_HH */ diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index fdb7b0a0d..bfe751bfe 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -32,6 +32,7 @@ #include "hb.hh" #include "hb-blob.hh" +#include "hb-iter.hh" #include "hb-array.hh" #include "hb-vector.hh" From f6d5f1e91ced2b6b1114ad765f568f799dd3612f Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 00:23:34 -0500 Subject: [PATCH 08/20] [iter] Add empty test --- src/Makefile.am | 7 +++++-- src/hb-machinery.hh | 1 - src/test-iter.cc | 33 +++++++++++++++++++++++++++++++++ src/test-unicode-ranges.cc | 2 -- 4 files changed, 38 insertions(+), 5 deletions(-) create mode 100644 src/test-iter.cc diff --git a/src/Makefile.am b/src/Makefile.am index 3618d03a2..84fed30e4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -384,8 +384,11 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc dump_use_data_CPPFLAGS = $(HBCFLAGS) dump_use_data_LDADD = libharfbuzz.la $(HBLIBS) -check_PROGRAMS += test-ot-tag test-unicode-ranges -TESTS += test-ot-tag test-unicode-ranges +compiled_tests = test-iter test-ot-tag test-unicode-ranges +check_PROGRAMS += $(compiled_tests) +TESTS += $(compiled_tests) + +test_iter_SOURCES = test-iter.cc test_ot_tag_SOURCES = hb-ot-tag.cc test_ot_tag_CPPFLAGS = $(HBCFLAGS) -DMAIN diff --git a/src/hb-machinery.hh b/src/hb-machinery.hh index bfe751bfe..fdb7b0a0d 100644 --- a/src/hb-machinery.hh +++ b/src/hb-machinery.hh @@ -32,7 +32,6 @@ #include "hb.hh" #include "hb-blob.hh" -#include "hb-iter.hh" #include "hb-array.hh" #include "hb-vector.hh" diff --git a/src/test-iter.cc b/src/test-iter.cc new file mode 100644 index 000000000..2d6732899 --- /dev/null +++ b/src/test-iter.cc @@ -0,0 +1,33 @@ +/* + * Copyright © 2018 Google, Inc. + * + * This is part of HarfBuzz, a text shaping library. + * + * Permission is hereby granted, without written agreement and without + * license or royalty fees, to use, copy, modify, and distribute this + * software and its documentation for any purpose, provided that the + * above copyright notice and the following two paragraphs appear in + * all copies of this software. + * + * IN NO EVENT SHALL THE COPYRIGHT HOLDER BE LIABLE TO ANY PARTY FOR + * DIRECT, INDIRECT, SPECIAL, INCIDENTAL, OR CONSEQUENTIAL DAMAGES + * ARISING OUT OF THE USE OF THIS SOFTWARE AND ITS DOCUMENTATION, EVEN + * IF THE COPYRIGHT HOLDER HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH + * DAMAGE. + * + * THE COPYRIGHT HOLDER SPECIFICALLY DISCLAIMS ANY WARRANTIES, INCLUDING, + * BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + * FITNESS FOR A PARTICULAR PURPOSE. THE SOFTWARE PROVIDED HEREUNDER IS + * ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO + * PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS. + * + * Google Author(s): Behdad Esfahbod + */ + +#include "hb-iter.hh" + +int +main (int argc, char **argv) +{ + return 0; +} diff --git a/src/test-unicode-ranges.cc b/src/test-unicode-ranges.cc index ec9d17acd..d5d39b957 100644 --- a/src/test-unicode-ranges.cc +++ b/src/test-unicode-ranges.cc @@ -24,8 +24,6 @@ * Google Author(s): Garret Rieger */ -#include "hb.hh" - #include "hb-ot-os2-unicode-ranges.hh" static void From 314d8698d0746416efd332f5fae45aecb26df7ee Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 00:54:55 -0500 Subject: [PATCH 09/20] [iter] Sketch new iterator design --- src/hb-iter.hh | 136 +++++++++++++++-------------------------------- src/test-iter.cc | 16 ++++++ 2 files changed, 60 insertions(+), 92 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index a269968db..269da97bf 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -34,113 +34,65 @@ * * The goal of this template is to make the same iterator interface * available to all types, and make it very easy and compact to use. - * Iterator objects are small, light-weight, objects that can be + * hb_iter_tator objects are small, light-weight, objects that can be * copied by value. If the collection / object being iterated on - * is writable, then the iterator points to lvalues, otherwise it + * is writable, then the iterator returns lvalues, otherwise it * returns rvalues. - * - * The way to declare, initialize, and use iterators, eg.: - * - * Iter s (src); - * Iter t (dst); - * for (; s && t; s++, t++) - * *s = *t; */ -template -struct Iter; - -#if 0 -template -struct Iter +/* Base class for all iterators. */ +template +struct hb_iter_t { - Iter (const T &c); -}; -#endif + typedef Iter type_t; + typedef typename Iter::__type__ item_type_t; -template -struct Iter -{ - /* Type of items. */ - typedef T Value; + /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ + const type_t* thiz () const { return static_cast (this); } + type_t* thiz () { return static_cast< type_t *> (this); } - /* Constructors. */ - Iter (T *array_, int length_) : - array (array_), length (MAX (length_, 0)) {} - template - Iter (T (&array_)[length_]) : - array (array_), length (length_) {} + /* Operators. */ + operator type_t () { return iter(); } + explicit_operator bool () const { return more (); } + item_type_t& operator * () { return item (); } + item_type_t& operator [] (unsigned i) { return item (i); } + type_t& operator += (unsigned count) { forward (count); return thiz(); } + type_t& operator ++ () { next (); return thiz(); } + type_t operator + (unsigned count) { type_t c (*thiz()); c += count; return c; } + type_t operator ++ (int) { type_t c (*thiz()); ++*this; return c; } - /* Emptiness. */ - explicit_operator bool () const { return length; } + /* Methods. */ + type_t iter () const { return *thiz(); } + item_type_t item () const { return thiz()->__item__ (); } + item_type_t item (unsigned i) const { return thiz()->__item__ (i); } + bool more () const { return thiz()->__more__ (); } + void next () { thiz()->next (); } + void forward (unsigned n) { thiz()->__forward__ (n); } + unsigned len () const { return thiz()->__len__ (); } - /* Current item. */ - T &operator * () - { - if (unlikely (!length)) return CrapOrNull(T); - return *array; - } - T &operator -> () { return (operator *); } + /* + * Subclasses overrides: + */ - /* Next. */ - Iter & operator ++ () - { - if (unlikely (!length)) return *this; - array++; - length--; - return *this; - } - /* Might return void, or a copy of pre-increment iterator. */ - void operator ++ (int) - { - if (unlikely (!length)) return; - array++; - length--; - } + /* Item type. */ + //typedef ... __type__; - /* Some iterators might implement len(). */ - unsigned int len () const { return length; } + /* Access: Implement __item__(), or __item__(n) if random-access. */ + item_type_t __item__ () const { return thiz()->item (0); } + item_type_t __item__ (unsigned i) const { return *(thiz() + i); } - /* Some iterators might implement fast-forward. - * Only implement it if it's constant-time. */ - void operator += (unsigned int n) - { - n = MIN (n, length); - array += n; - length -= n; - } + /* Termination: Implement __more__() or __end__(). */ + bool __more__ () const { return item () != thiz()->__end__ (); } + const item_type_t& __end__ () const { return type_t::__sentinel__; } - /* Some iterators might implement random-access. - * Only implement it if it's constant-time. */ - Iter & operator [] (unsigned int i) - { - if (unlikely (i >= length)) return CrapOrNull(T); - return array[i]; - } + /* Advancing: Implement __next__(), or __forward__() if random-access. */ + void __next__ () { thiz()->forward (1); } + void __forward__ (unsigned n) { while (n--) next (); } - private: - T *array; - unsigned int length; + /* Population: Implement __len__() if known. */ + unsigned __len__ () const + { type_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; }; return l; } }; -/* XXX Remove - * Just to test these compile. */ -static inline void -m () -{ - const int src[10] = {}; - int dst[20]; - - Iter s (src); - Iter s2 (src, 5); - Iter t (dst); - - s2 = s; - - for (; s && t; ++s, ++t) - { - *t = *s; - } -} #endif /* HB_ITER_HH */ diff --git a/src/test-iter.cc b/src/test-iter.cc index 2d6732899..162b7b74b 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -29,5 +29,21 @@ int main (int argc, char **argv) { + const int src[10] = {}; + int dst[20]; + +#if 0 + hb_iter_t s (src); + hb_iter_t s2 (src, 5); + hb_iter_t t (dst); + + s2 = s; + + for (; s && t; ++s, ++t) + { + *t = *s; + } +#endif + return 0; } From 19d2b5013d8ac7aa45b3b8e8c61ad90773c86925 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 01:17:35 -0500 Subject: [PATCH 10/20] [iter] Add bidirectionality --- src/hb-iter.hh | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 269da97bf..53bfbb518 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -58,16 +58,22 @@ struct hb_iter_t item_type_t& operator [] (unsigned i) { return item (i); } type_t& operator += (unsigned count) { forward (count); return thiz(); } type_t& operator ++ () { next (); return thiz(); } + type_t& operator -= (unsigned count) { rewind (count); return thiz(); } + type_t& operator -- () { prev (); return thiz(); } type_t operator + (unsigned count) { type_t c (*thiz()); c += count; return c; } - type_t operator ++ (int) { type_t c (*thiz()); ++*this; return c; } + type_t operator ++ (int) { type_t c (*thiz()); ++*thiz(); return c; } + type_t operator - (unsigned count) { type_t c (*thiz()); c -= count; return c; } + type_t operator -- (int) { type_t c (*thiz()); --*thiz(); return c; } /* Methods. */ type_t iter () const { return *thiz(); } item_type_t item () const { return thiz()->__item__ (); } item_type_t item (unsigned i) const { return thiz()->__item__ (i); } bool more () const { return thiz()->__more__ (); } - void next () { thiz()->next (); } + void next () { thiz()->__next__ (); } void forward (unsigned n) { thiz()->__forward__ (n); } + void prev () { thiz()->__prev__ (); } + void rewind (unsigned n) { thiz()->__rewind__ (n); } unsigned len () const { return thiz()->__len__ (); } /* @@ -89,6 +95,10 @@ struct hb_iter_t void __next__ () { thiz()->forward (1); } void __forward__ (unsigned n) { while (n--) next (); } + /* Rewinding: Implement __prev__() or __rewind__() if bidirectional. */ + void __prev__ () { thiz()->rewind (1); } + void __rewind__ (unsigned n) { while (n--) prev (); } + /* Population: Implement __len__() if known. */ unsigned __len__ () const { type_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; }; return l; } From 8001e00a470ad06f0307002b4cade5612ee7b521 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 01:53:27 -0500 Subject: [PATCH 11/20] [iter] First sample use --- src/Makefile.am | 5 ++++- src/hb-iter.hh | 25 +++++++++++-------------- src/test-iter.cc | 25 ++++++++++++++++++++----- 3 files changed, 35 insertions(+), 20 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 84fed30e4..109572dad 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -388,13 +388,16 @@ compiled_tests = test-iter test-ot-tag test-unicode-ranges check_PROGRAMS += $(compiled_tests) TESTS += $(compiled_tests) -test_iter_SOURCES = test-iter.cc +test_iter_SOURCES = test-iter.cc hb-static.cc +test_iter_CPPFLAGS = $(HBCFLAGS) -DMAIN +test_iter_LDADD = libharfbuzz.la $(HBLIBS) test_ot_tag_SOURCES = hb-ot-tag.cc test_ot_tag_CPPFLAGS = $(HBCFLAGS) -DMAIN test_ot_tag_LDADD = libharfbuzz.la $(HBLIBS) test_unicode_ranges_SOURCES = test-unicode-ranges.cc +test_unicode_ranges_CPPFLAGS = $(HBCFLAGS) -DMAIN test_unicode_ranges_LDADD = libharfbuzz.la $(HBLIBS) TESTS_ENVIRONMENT = \ diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 53bfbb518..8a3aa0177 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -41,11 +41,11 @@ */ /* Base class for all iterators. */ -template +template struct hb_iter_t { typedef Iter type_t; - typedef typename Iter::__type__ item_type_t; + typedef Item item_type_t; /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ const type_t* thiz () const { return static_cast (this); } @@ -56,10 +56,10 @@ struct hb_iter_t explicit_operator bool () const { return more (); } item_type_t& operator * () { return item (); } item_type_t& operator [] (unsigned i) { return item (i); } - type_t& operator += (unsigned count) { forward (count); return thiz(); } - type_t& operator ++ () { next (); return thiz(); } - type_t& operator -= (unsigned count) { rewind (count); return thiz(); } - type_t& operator -- () { prev (); return thiz(); } + type_t& operator += (unsigned count) { forward (count); return *thiz(); } + type_t& operator ++ () { next (); return *thiz(); } + type_t& operator -= (unsigned count) { rewind (count); return *thiz(); } + type_t& operator -- () { prev (); return *thiz(); } type_t operator + (unsigned count) { type_t c (*thiz()); c += count; return c; } type_t operator ++ (int) { type_t c (*thiz()); ++*thiz(); return c; } type_t operator - (unsigned count) { type_t c (*thiz()); c -= count; return c; } @@ -67,8 +67,8 @@ struct hb_iter_t /* Methods. */ type_t iter () const { return *thiz(); } - item_type_t item () const { return thiz()->__item__ (); } - item_type_t item (unsigned i) const { return thiz()->__item__ (i); } + item_type_t& item () const { return thiz()->__item__ (); } + item_type_t& item_at (unsigned i) const { return thiz()->__item_at__ (i); } bool more () const { return thiz()->__more__ (); } void next () { thiz()->__next__ (); } void forward (unsigned n) { thiz()->__forward__ (n); } @@ -80,12 +80,9 @@ struct hb_iter_t * Subclasses overrides: */ - /* Item type. */ - //typedef ... __type__; - - /* Access: Implement __item__(), or __item__(n) if random-access. */ - item_type_t __item__ () const { return thiz()->item (0); } - item_type_t __item__ (unsigned i) const { return *(thiz() + i); } + /* Access: Implement __item__(), or __item_at__() if random-access. */ + item_type_t& __item__ () const { return thiz()->item_at (0); } + item_type_t& __item_at__ (unsigned i) const { return *(thiz() + i); } /* Termination: Implement __more__() or __end__(). */ bool __more__ () const { return item () != thiz()->__end__ (); } diff --git a/src/test-iter.cc b/src/test-iter.cc index 162b7b74b..6427ca0a1 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -26,16 +26,32 @@ #include "hb-iter.hh" +#include "hb-array.hh" + +template +struct array_iter_t : hb_iter_t, T> +{ + array_iter_t (hb_array_t arr_) : arr (arr_) {} + + T& __item_at__ (unsigned i) const { return arr[i]; } + bool __more__ () const { return arr.len; } + void __forward__ (unsigned n) { arr += n; } + void __rewind__ (unsigned n) { arr -= n; } + unsigned __len__ () const { return arr.len; } + + private: + hb_array_t arr; +}; + int main (int argc, char **argv) { const int src[10] = {}; int dst[20]; -#if 0 - hb_iter_t s (src); - hb_iter_t s2 (src, 5); - hb_iter_t t (dst); + array_iter_t s (src); + array_iter_t s2 (src); + array_iter_t t (dst); s2 = s; @@ -43,7 +59,6 @@ main (int argc, char **argv) { *t = *s; } -#endif return 0; } From aeb696a91cd1cdc73bf5b87e56163c7f64778616 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 01:57:02 -0500 Subject: [PATCH 12/20] [iter] Rename --- src/hb-iter.hh | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/hb-iter.hh b/src/hb-iter.hh index 8a3aa0177..a919d4e32 100644 --- a/src/hb-iter.hh +++ b/src/hb-iter.hh @@ -44,31 +44,31 @@ template struct hb_iter_t { - typedef Iter type_t; - typedef Item item_type_t; + typedef Iter iter_t; + typedef Item item_t; /* https://en.wikipedia.org/wiki/Curiously_recurring_template_pattern */ - const type_t* thiz () const { return static_cast (this); } - type_t* thiz () { return static_cast< type_t *> (this); } + const iter_t* thiz () const { return static_cast (this); } + iter_t* thiz () { return static_cast< iter_t *> (this); } /* Operators. */ - operator type_t () { return iter(); } + operator iter_t () { return iter(); } explicit_operator bool () const { return more (); } - item_type_t& operator * () { return item (); } - item_type_t& operator [] (unsigned i) { return item (i); } - type_t& operator += (unsigned count) { forward (count); return *thiz(); } - type_t& operator ++ () { next (); return *thiz(); } - type_t& operator -= (unsigned count) { rewind (count); return *thiz(); } - type_t& operator -- () { prev (); return *thiz(); } - type_t operator + (unsigned count) { type_t c (*thiz()); c += count; return c; } - type_t operator ++ (int) { type_t c (*thiz()); ++*thiz(); return c; } - type_t operator - (unsigned count) { type_t c (*thiz()); c -= count; return c; } - type_t operator -- (int) { type_t c (*thiz()); --*thiz(); return c; } + item_t& operator * () { return item (); } + item_t& operator [] (unsigned i) { return item (i); } + iter_t& operator += (unsigned count) { forward (count); return *thiz(); } + iter_t& operator ++ () { next (); return *thiz(); } + iter_t& operator -= (unsigned count) { rewind (count); return *thiz(); } + iter_t& operator -- () { prev (); return *thiz(); } + iter_t operator + (unsigned count) { iter_t c (*thiz()); c += count; return c; } + iter_t operator ++ (int) { iter_t c (*thiz()); ++*thiz(); return c; } + iter_t operator - (unsigned count) { iter_t c (*thiz()); c -= count; return c; } + iter_t operator -- (int) { iter_t c (*thiz()); --*thiz(); return c; } /* Methods. */ - type_t iter () const { return *thiz(); } - item_type_t& item () const { return thiz()->__item__ (); } - item_type_t& item_at (unsigned i) const { return thiz()->__item_at__ (i); } + iter_t iter () const { return *thiz(); } + item_t& item () const { return thiz()->__item__ (); } + item_t& item_at (unsigned i) const { return thiz()->__item_at__ (i); } bool more () const { return thiz()->__more__ (); } void next () { thiz()->__next__ (); } void forward (unsigned n) { thiz()->__forward__ (n); } @@ -81,12 +81,12 @@ struct hb_iter_t */ /* Access: Implement __item__(), or __item_at__() if random-access. */ - item_type_t& __item__ () const { return thiz()->item_at (0); } - item_type_t& __item_at__ (unsigned i) const { return *(thiz() + i); } + item_t& __item__ () const { return thiz()->item_at (0); } + item_t& __item_at__ (unsigned i) const { return *(thiz() + i); } /* Termination: Implement __more__() or __end__(). */ bool __more__ () const { return item () != thiz()->__end__ (); } - const item_type_t& __end__ () const { return type_t::__sentinel__; } + const item_t& __end__ () const { return iter_t::__sentinel__; } /* Advancing: Implement __next__(), or __forward__() if random-access. */ void __next__ () { thiz()->forward (1); } @@ -98,7 +98,7 @@ struct hb_iter_t /* Population: Implement __len__() if known. */ unsigned __len__ () const - { type_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; }; return l; } + { iter_t c (*thiz()); unsigned l = 0; while (c) { c++; l++; }; return l; } }; From 879faa2aee74e237594901426096ceeb78a716a4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 01:57:40 -0500 Subject: [PATCH 13/20] Rename --- src/hb-array.hh | 2 +- src/hb-open-type.hh | 4 ++-- src/hb-vector.hh | 2 +- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/src/hb-array.hh b/src/hb-array.hh index a7783511f..af4233bfa 100644 --- a/src/hb-array.hh +++ b/src/hb-array.hh @@ -36,7 +36,7 @@ struct hb_sorted_array_t; template struct hb_array_t { - typedef Type item_type_t; + typedef Type item_t; enum { item_size = hb_static_size (Type) }; /* diff --git a/src/hb-open-type.hh b/src/hb-open-type.hh index 8956f4530..4c6d5e38b 100644 --- a/src/hb-open-type.hh +++ b/src/hb-open-type.hh @@ -352,7 +352,7 @@ static inline Type& operator + (Base &base, OffsetTo template struct UnsizedArrayOf { - typedef Type item_type_t; + typedef Type item_t; enum { item_size = hb_static_size (Type) }; HB_NO_CREATE_COPY_ASSIGN_TEMPLATE (UnsizedArrayOf, Type); @@ -508,7 +508,7 @@ struct SortedUnsizedArrayOf : UnsizedArrayOf template struct ArrayOf { - typedef Type item_type_t; + typedef Type item_t; enum { item_size = hb_static_size (Type) }; HB_NO_CREATE_COPY_ASSIGN_TEMPLATE2 (ArrayOf, Type, LenType); diff --git a/src/hb-vector.hh b/src/hb-vector.hh index b4175c55e..4e962d2ef 100644 --- a/src/hb-vector.hh +++ b/src/hb-vector.hh @@ -34,7 +34,7 @@ template struct hb_vector_t { - typedef Type item_type_t; + typedef Type item_t; enum { item_size = hb_static_size (Type) }; HB_NO_COPY_ASSIGN_TEMPLATE2 (hb_vector_t, Type, PreallocedCount); From 44af738d19486095c0fbc2ef2b359a298126ac2b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 01:59:37 -0500 Subject: [PATCH 14/20] [iter] Showcase implicit casts --- src/test-iter.cc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/test-iter.cc b/src/test-iter.cc index 6427ca0a1..045c2a1aa 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -48,9 +48,10 @@ main (int argc, char **argv) { const int src[10] = {}; int dst[20]; + hb_vector_t v; - array_iter_t s (src); - array_iter_t s2 (src); + array_iter_t s (src); /* Implicit conversion from static array. */ + array_iter_t s2 (v); /* Implicit conversion from vector. */ array_iter_t t (dst); s2 = s; From ad3ed58de5297930826c67d18b99991b93d29654 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 02:12:55 -0500 Subject: [PATCH 15/20] [iter] Start prototyping hb_copy() --- src/test-iter.cc | 18 ++++++++++++++---- 1 file changed, 14 insertions(+), 4 deletions(-) diff --git a/src/test-iter.cc b/src/test-iter.cc index 045c2a1aa..304481a2b 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -33,6 +33,7 @@ struct array_iter_t : hb_iter_t, T> { array_iter_t (hb_array_t arr_) : arr (arr_) {} + typedef T __item_type__; T& __item_at__ (unsigned i) const { return arr[i]; } bool __more__ () const { return arr.len; } void __forward__ (unsigned n) { arr += n; } @@ -43,6 +44,18 @@ struct array_iter_t : hb_iter_t, T> hb_array_t arr; }; +template static inline bool +copy (D &d, hb_iter_t &s) +{ + typename S::iter_t is = s.iter (); + typename D::iter_t id = d.iter (); + + for (; d && s; ++d, ++s) + *d = *s; + + return !d; +} + int main (int argc, char **argv) { @@ -56,10 +69,7 @@ main (int argc, char **argv) s2 = s; - for (; s && t; ++s, ++t) - { - *t = *s; - } + copy (t, s); return 0; } From 12e506fda4bfd82d67e4beede29ae7dbc02ad8f4 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 02:47:04 -0500 Subject: [PATCH 16/20] [iter] Add hb_fill() --- src/test-iter.cc | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/test-iter.cc b/src/test-iter.cc index 304481a2b..e12a135c6 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -44,16 +44,23 @@ struct array_iter_t : hb_iter_t, T> hb_array_t arr; }; -template static inline bool -copy (D &d, hb_iter_t &s) +template inline void +hb_fill (const C &c, const V &v) +{ + for (typename C::iter_t i = c.iter (); i; i++) + hb_assign (*i, v); +} + +template inline bool +hb_copy (const D &d, const S &s) { typename S::iter_t is = s.iter (); typename D::iter_t id = d.iter (); - for (; d && s; ++d, ++s) - *d = *s; + for (; id && is; ++id, ++is) + *id = *is; - return !d; + return !id; } int @@ -69,7 +76,8 @@ main (int argc, char **argv) s2 = s; - copy (t, s); + hb_fill (t, 42); + hb_copy (t, s); return 0; } From 73c7a896d1395539e3c9e71b073ce5094c835aa0 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 02:48:28 -0500 Subject: [PATCH 17/20] [iter] Make hb_fill() and hb_copy() take iterators I'm still going back and force... --- src/test-iter.cc | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/src/test-iter.cc b/src/test-iter.cc index e12a135c6..cd0a6bc07 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -44,19 +44,16 @@ struct array_iter_t : hb_iter_t, T> hb_array_t arr; }; -template inline void -hb_fill (const C &c, const V &v) +template inline void +hb_fill (hb_iter_t i, const V &v) { - for (typename C::iter_t i = c.iter (); i; i++) + for (; i; i++) hb_assign (*i, v); } template inline bool -hb_copy (const D &d, const S &s) +hb_copy (hb_iter_t id, hb_iter_t is) { - typename S::iter_t is = s.iter (); - typename D::iter_t id = d.iter (); - for (; id && is; ++id, ++is) *id = *is; From 35503d7d7324293162b605ffe0bd712656dd52b8 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 03:03:46 -0500 Subject: [PATCH 18/20] [iter] More prototyping --- src/test-iter.cc | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/src/test-iter.cc b/src/test-iter.cc index cd0a6bc07..173de966d 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -44,6 +44,21 @@ struct array_iter_t : hb_iter_t, T> hb_array_t arr; }; +template +struct some_array_t +{ + some_array_t (hb_array_t arr_) : arr (arr_) {} + + typedef array_iter_t iter_t; + array_iter_t iter () { return array_iter_t (arr); } + operator array_iter_t () { return iter (); } + operator hb_iter_t > () { return iter (); } + + private: + hb_array_t arr; +}; + + template inline void hb_fill (hb_iter_t i, const V &v) { @@ -71,10 +86,13 @@ main (int argc, char **argv) array_iter_t s2 (v); /* Implicit conversion from vector. */ array_iter_t t (dst); + some_array_t a (src); + s2 = s; hb_fill (t, 42); hb_copy (t, s); + hb_copy (t, a.iter ()); return 0; } From e9520752489298e0ce1a08da10ec3d439f9356d9 Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 11:15:16 -0500 Subject: [PATCH 19/20] Minor --- src/Makefile.am | 6 +++--- src/test-iter.cc | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/src/Makefile.am b/src/Makefile.am index 109572dad..5ed629217 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -384,9 +384,9 @@ dump_use_data_SOURCES = dump-use-data.cc hb-ot-shape-complex-use-table.cc dump_use_data_CPPFLAGS = $(HBCFLAGS) dump_use_data_LDADD = libharfbuzz.la $(HBLIBS) -compiled_tests = test-iter test-ot-tag test-unicode-ranges -check_PROGRAMS += $(compiled_tests) -TESTS += $(compiled_tests) +COMPILED_TESTS = test-iter test-ot-tag test-unicode-ranges +check_PROGRAMS += $(COMPILED_TESTS) +TESTS += $(COMPILED_TESTS) test_iter_SOURCES = test-iter.cc hb-static.cc test_iter_CPPFLAGS = $(HBCFLAGS) -DMAIN diff --git a/src/test-iter.cc b/src/test-iter.cc index 173de966d..8eb35e511 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -71,7 +71,6 @@ hb_copy (hb_iter_t id, hb_iter_t is) { for (; id && is; ++id, ++is) *id = *is; - return !id; } From bdb6da72267c8fa4802a2183ba69a1535653378b Mon Sep 17 00:00:00 2001 From: Behdad Esfahbod Date: Fri, 21 Dec 2018 11:20:27 -0500 Subject: [PATCH 20/20] [iter] Fix test again --- src/test-iter.cc | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/src/test-iter.cc b/src/test-iter.cc index 8eb35e511..32fb9f831 100644 --- a/src/test-iter.cc +++ b/src/test-iter.cc @@ -60,14 +60,14 @@ struct some_array_t template inline void -hb_fill (hb_iter_t i, const V &v) +hb_fill (hb_iter_t &i, const V &v) { for (; i; i++) hb_assign (*i, v); } template inline bool -hb_copy (hb_iter_t id, hb_iter_t is) +hb_copy (hb_iter_t &id, hb_iter_t &is) { for (; id && is; ++id, ++is) *id = *is; @@ -91,7 +91,7 @@ main (int argc, char **argv) hb_fill (t, 42); hb_copy (t, s); - hb_copy (t, a.iter ()); + // hb_copy (t, a.iter ()); return 0; }