src/Makefile.sources | 2 src/hb-blob-private.hh | 1 src/hb-blob.cc | 29 +- src/hb-buffer-private.hh | 4 src/hb-buffer.cc | 44 +-- src/hb-dsalgs.hh | 340 +++-------------------------- src/hb-face-private.hh | 6 src/hb-face.cc | 5 src/hb-font-private.hh | 10 src/hb-font.cc | 66 ++--- src/hb-machinery-private.hh | 6 src/hb-null.hh | 106 +++++++++ src/hb-object-private.hh | 108 ++++++++- src/hb-open-type-private.hh | 3 src/hb-ot-glyf-table.hh | 6 src/hb-ot-head-table.hh | 4 src/hb-ot-layout-base-table.hh | 225 ++++++++----------- src/hb-ot-layout-common-private.hh | 5 src/hb-ot-layout-gdef-table.hh | 1 src/hb-ot-layout-gsubgpos-private.hh | 1 src/hb-ot-layout-private.hh | 4 src/hb-ot-layout.cc | 6 src/hb-ot-math-table.hh | 2 src/hb-ot-math.cc | 2 src/hb-ot-shape-complex-arabic-fallback.hh | 12 - src/hb-ot-var-fvar-table.hh | 2 src/hb-ot-var.cc | 2 src/hb-private.hh | 123 ---------- src/hb-shape-plan-private.hh | 1 src/hb-shape-plan.cc | 50 ++-- src/hb-static.cc | 10 src/hb-subset.cc | 2 src/hb-unicode-private.hh | 7 src/hb-unicode.cc | 5 src/hb-vector-private.hh | 238 ++++++++++++++++++++ src/main.cc | 2 36 files changed, 763 insertions(+), 677 deletions(-)
New commits: commit b912fbea17c50e229977345012227810ed7641e9 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 6 06:30:12 2018 -0700 Remove most uses of direct comparison to Null objects diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh index ce6ee1e2..bcf89e46 100644 --- a/src/hb-ot-glyf-table.hh +++ b/src/hb-ot-glyf-table.hh @@ -238,9 +238,9 @@ struct glyf hb_blob_t *head_blob = hb_sanitize_context_t().reference_table<head> (face); const head *head_table = head_blob->as<head> (); - if (head_table == &Null(head) || (unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) + if (head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0) { - /* head table is not present, or in an unknown format. Leave num_glyphs=0, that takes care of disabling us. */ + /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */ hb_blob_destroy (head_blob); return; } @@ -270,7 +270,7 @@ struct glyf inline bool get_composite (hb_codepoint_t glyph, CompositeGlyphHeader::Iterator *composite /* OUT */) const { - if (this->glyf_table == &Null(glyf) || !num_glyphs) + if (unlikely (!num_glyphs)) return false; unsigned int start_offset, end_offset; diff --git a/src/hb-ot-head-table.hh b/src/hb-ot-head-table.hh index 965e30a0..fded120b 100644 --- a/src/hb-ot-head-table.hh +++ b/src/hb-ot-head-table.hh @@ -141,8 +141,8 @@ struct head * -1: Only strongly right to left; * -2: Like -1 but also contains neutrals. */ public: - HBINT16 indexToLocFormat; /* 0 for short offsets, 1 for long. */ - HBINT16 glyphDataFormat; /* 0 for current format. */ + HBUINT16 indexToLocFormat; /* 0 for short offsets, 1 for long. */ + HBUINT16 glyphDataFormat; /* 0 for current format. */ DEFINE_SIZE_STATIC (54); }; diff --git a/src/hb-ot-layout-gdef-table.hh b/src/hb-ot-layout-gdef-table.hh index 60a8d3ad..d2b41a8e 100644 --- a/src/hb-ot-layout-gdef-table.hh +++ b/src/hb-ot-layout-gdef-table.hh @@ -349,6 +349,7 @@ struct GDEF ComponentGlyph = 4 }; + inline bool has_data (void) const { return version.to_int () != 0; } inline bool has_glyph_classes (void) const { return glyphClassDef != 0; } inline unsigned int get_glyph_class (hb_codepoint_t glyph) const { return (this+glyphClassDef).get_class (glyph); } diff --git a/src/hb-ot-layout-gsubgpos-private.hh b/src/hb-ot-layout-gsubgpos-private.hh index f3566ab1..40a2fc4c 100644 --- a/src/hb-ot-layout-gsubgpos-private.hh +++ b/src/hb-ot-layout-gsubgpos-private.hh @@ -2320,6 +2320,7 @@ struct Extension struct GSUBGPOS { + inline bool has_data (void) const { return version.to_int () != 0; } inline unsigned int get_script_count (void) const { return (this+scriptList).len; } inline const Tag& get_script_tag (unsigned int i) const diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc index bfde063d..09ff0e6c 100644 --- a/src/hb-ot-layout.cc +++ b/src/hb-ot-layout.cc @@ -904,7 +904,7 @@ hb_ot_layout_feature_with_variations_get_lookups (hb_face_t *face, hb_bool_t hb_ot_layout_has_substitution (hb_face_t *face) { - return &_get_gsub (face) != &Null(OT::GSUB); + return _get_gsub (face).has_data (); } /** @@ -1006,7 +1006,7 @@ hb_ot_layout_lookups_substitute_closure (hb_face_t *face, hb_bool_t hb_ot_layout_has_positioning (hb_face_t *face) { - return &_get_gpos (face) != &Null(OT::GPOS); + return _get_gpos (face).has_data (); } void @@ -1341,5 +1341,5 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c, // hb_bool_t // hb_ot_base_has_data (hb_face_t *face) // { -// return &_get_base (face) != &Null(OT::BASE); +// return _get_base (face).has_data (); // } diff --git a/src/hb-ot-math-table.hh b/src/hb-ot-math-table.hh index 5fef2d28..2dd71458 100644 --- a/src/hb-ot-math-table.hh +++ b/src/hb-ot-math-table.hh @@ -686,6 +686,8 @@ struct MATH { static const hb_tag_t tableTag = HB_OT_TAG_MATH; + inline bool has_data (void) const { return version.to_int () != 0; } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/src/hb-ot-math.cc b/src/hb-ot-math.cc index e7cb4652..66ce207a 100644 --- a/src/hb-ot-math.cc +++ b/src/hb-ot-math.cc @@ -55,7 +55,7 @@ _get_math (hb_face_t *face) hb_bool_t hb_ot_math_has_data (hb_face_t *face) { - return &_get_math (face) != &Null(OT::MATH); + return _get_math (face).has_data (); } /** diff --git a/src/hb-ot-shape-complex-arabic-fallback.hh b/src/hb-ot-shape-complex-arabic-fallback.hh index 2803febb..a55511aa 100644 --- a/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/src/hb-ot-shape-complex-arabic-fallback.hh @@ -313,6 +313,7 @@ arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan, if (arabic_fallback_plan_init_win1256 (fallback_plan, plan, font)) return fallback_plan; + assert (fallback_plan->num_lookups == 0); free (fallback_plan); return const_cast<arabic_fallback_plan_t *> (&Null(arabic_fallback_plan_t)); } @@ -320,7 +321,7 @@ arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan, static void arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan) { - if (!fallback_plan || fallback_plan == &Null(arabic_fallback_plan_t)) + if (!fallback_plan || fallback_plan->num_lookups == 0) return; for (unsigned int i = 0; i < fallback_plan->num_lookups; i++) diff --git a/src/hb-ot-var-fvar-table.hh b/src/hb-ot-var-fvar-table.hh index 82d29968..101476ed 100644 --- a/src/hb-ot-var-fvar-table.hh +++ b/src/hb-ot-var-fvar-table.hh @@ -87,6 +87,8 @@ struct fvar { static const hb_tag_t tableTag = HB_OT_TAG_fvar; + inline bool has_data (void) const { return version.to_int () != 0; } + inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); diff --git a/src/hb-ot-var.cc b/src/hb-ot-var.cc index 366860d5..6081ddfc 100644 --- a/src/hb-ot-var.cc +++ b/src/hb-ot-var.cc @@ -65,7 +65,7 @@ _get_avar (hb_face_t *face) hb_bool_t hb_ot_var_has_data (hb_face_t *face) { - return &_get_fvar (face) != &Null(OT::fvar); + return _get_fvar (face).has_data (); } /** diff --git a/src/hb-subset.cc b/src/hb-subset.cc index 9e8e2aff..411c6b86 100644 --- a/src/hb-subset.cc +++ b/src/hb-subset.cc @@ -83,7 +83,7 @@ _subset (hb_subset_plan_t *plan) hb_tag_t tag = TableType::tableTag; hb_bool_t result = false; - if (table != &Null(TableType)) + if (source_blob->data) { result = table->subset(plan); } else { diff --git a/src/main.cc b/src/main.cc index c6e05fc3..98a1320b 100644 --- a/src/main.cc +++ b/src/main.cc @@ -53,7 +53,7 @@ main (int argc, char **argv) hb_blob_t *font_blob = hb_sanitize_context_t().sanitize_blob<OpenTypeFontFile> (blob); const OpenTypeFontFile* sanitized = font_blob->as<OpenTypeFontFile> (); - if (sanitized == &Null(OpenTypeFontFile)) + if (!font_blob->data) { printf ("Sanitization of the file wasn't successful. Exit"); return 1; commit 3506672ce9d8685ce4e113716b0d06adbc7981b7 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 6 06:17:48 2018 -0700 Port _nil objects to Null() machinery Finally, unified! diff --git a/src/hb-blob-private.hh b/src/hb-blob-private.hh index 93fbc2d5..49ad68ec 100644 --- a/src/hb-blob-private.hh +++ b/src/hb-blob-private.hh @@ -76,6 +76,7 @@ struct hb_blob_t void *user_data; hb_destroy_func_t destroy; }; +DECLARE_NULL_INSTANCE (hb_blob_t); #endif /* HB_BLOB_PRIVATE_HH */ diff --git a/src/hb-blob.cc b/src/hb-blob.cc index 5bab1abb..25c3e05a 100644 --- a/src/hb-blob.cc +++ b/src/hb-blob.cc @@ -45,6 +45,20 @@ #include <stdlib.h> +DEFINE_NULL_INSTANCE (hb_blob_t) = +{ + HB_OBJECT_HEADER_STATIC, + + true, /* immutable */ + + nullptr, /* data */ + 0, /* length */ + HB_MEMORY_MODE_READONLY, /* mode */ + + nullptr, /* user_data */ + nullptr /* destroy */ +}; + /** * hb_blob_create: (skip) * @data: Pointer to blob data. @@ -182,20 +196,7 @@ hb_blob_copy_writable_or_fail (hb_blob_t *blob) hb_blob_t * hb_blob_get_empty (void) { - static const hb_blob_t _hb_blob_nil = { - HB_OBJECT_HEADER_STATIC, - - true, /* immutable */ - - nullptr, /* data */ - 0, /* length */ - HB_MEMORY_MODE_READONLY, /* mode */ - - nullptr, /* user_data */ - nullptr /* destroy */ - }; - - return const_cast<hb_blob_t *> (&_hb_blob_nil); + return const_cast<hb_blob_t *> (&Null(hb_blob_t)); } /** diff --git a/src/hb-buffer-private.hh b/src/hb-buffer-private.hh index f4581407..a6c4b696 100644 --- a/src/hb-buffer-private.hh +++ b/src/hb-buffer-private.hh @@ -83,7 +83,8 @@ HB_MARK_AS_FLAG_T (hb_buffer_scratch_flags_t); * hb_buffer_t */ -struct hb_buffer_t { +struct hb_buffer_t +{ hb_object_header_t header; ASSERT_POD (); @@ -352,6 +353,7 @@ struct hb_buffer_t { info[i].mask &= ~HB_GLYPH_FLAG_UNSAFE_TO_BREAK; } }; +DECLARE_NULL_INSTANCE (hb_buffer_t); /* Loop over clusters. Duplicated in foreach_syllable(). */ diff --git a/src/hb-buffer.cc b/src/hb-buffer.cc index d04e1e80..e79b45ae 100644 --- a/src/hb-buffer.cc +++ b/src/hb-buffer.cc @@ -701,6 +701,28 @@ hb_buffer_t::guess_segment_properties (void) /* Public API */ +DEFINE_NULL_INSTANCE (hb_buffer_t) = +{ + HB_OBJECT_HEADER_STATIC, + + const_cast<hb_unicode_funcs_t *> (&_hb_Null_hb_unicode_funcs_t), + HB_BUFFER_FLAG_DEFAULT, + HB_BUFFER_CLUSTER_LEVEL_DEFAULT, + HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, + HB_BUFFER_SCRATCH_FLAG_DEFAULT, + HB_BUFFER_MAX_LEN_DEFAULT, + HB_BUFFER_MAX_OPS_DEFAULT, + + HB_BUFFER_CONTENT_TYPE_INVALID, + HB_SEGMENT_PROPERTIES_DEFAULT, + false, /* successful */ + true, /* have_output */ + true /* have_positions */ + + /* Zero is good enough for everything else. */ +}; + + /** * hb_buffer_create: (Xconstructor) * @@ -743,27 +765,7 @@ hb_buffer_create (void) hb_buffer_t * hb_buffer_get_empty (void) { - static const hb_buffer_t _hb_buffer_nil = { - HB_OBJECT_HEADER_STATIC, - - const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil), - HB_BUFFER_FLAG_DEFAULT, - HB_BUFFER_CLUSTER_LEVEL_DEFAULT, - HB_BUFFER_REPLACEMENT_CODEPOINT_DEFAULT, - HB_BUFFER_SCRATCH_FLAG_DEFAULT, - HB_BUFFER_MAX_LEN_DEFAULT, - HB_BUFFER_MAX_OPS_DEFAULT, - - HB_BUFFER_CONTENT_TYPE_INVALID, - HB_SEGMENT_PROPERTIES_DEFAULT, - false, /* successful */ - true, /* have_output */ - true /* have_positions */ - - /* Zero is good enough for everything else. */ - }; - - return const_cast<hb_buffer_t *> (&_hb_buffer_nil); + return const_cast<hb_buffer_t *> (&Null(hb_buffer_t)); } /** diff --git a/src/hb-face-private.hh b/src/hb-face-private.hh index 73a68461..a4b2cd36 100644 --- a/src/hb-face-private.hh +++ b/src/hb-face-private.hh @@ -39,7 +39,8 @@ * hb_face_t */ -struct hb_face_t { +struct hb_face_t +{ hb_object_header_t header; ASSERT_POD (); @@ -94,8 +95,7 @@ struct hb_face_t { HB_INTERNAL void load_upem (void) const; HB_INTERNAL void load_num_glyphs (void) const; }; - -extern HB_INTERNAL const hb_face_t _hb_face_nil; +DECLARE_NULL_INSTANCE (hb_face_t); #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, face); diff --git a/src/hb-face.cc b/src/hb-face.cc index 9d17c4a5..e1492756 100644 --- a/src/hb-face.cc +++ b/src/hb-face.cc @@ -63,7 +63,8 @@ hb_face_count (hb_blob_t *blob) * hb_face_t */ -const hb_face_t _hb_face_nil = { +DEFINE_NULL_INSTANCE (hb_face_t) = +{ HB_OBJECT_HEADER_STATIC, true, /* immutable */ @@ -215,7 +216,7 @@ hb_face_create (hb_blob_t *blob, hb_face_t * hb_face_get_empty (void) { - return const_cast<hb_face_t *> (&_hb_face_nil); + return const_cast<hb_face_t *> (&Null(hb_face_t)); } diff --git a/src/hb-font-private.hh b/src/hb-font-private.hh index 9f657db6..4950e0bb 100644 --- a/src/hb-font-private.hh +++ b/src/hb-font-private.hh @@ -35,7 +35,6 @@ #include "hb-shaper-private.hh" - /* * hb_font_funcs_t */ @@ -57,7 +56,8 @@ HB_FONT_FUNC_IMPLEMENT (glyph_from_name) \ /* ^--- Add new callbacks here */ -struct hb_font_funcs_t { +struct hb_font_funcs_t +{ hb_object_header_t header; ASSERT_POD (); @@ -89,14 +89,15 @@ struct hb_font_funcs_t { ]) (void); } get; }; - +DECLARE_NULL_INSTANCE (hb_font_funcs_t); /* * hb_font_t */ -struct hb_font_t { +struct hb_font_t +{ hb_object_header_t header; ASSERT_POD (); @@ -553,6 +554,7 @@ struct hb_font_t { return (float) v * scale / face->get_upem (); } }; +DECLARE_NULL_INSTANCE (hb_font_t); #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS #define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_PROTOTYPE(shaper, font); diff --git a/src/hb-font.cc b/src/hb-font.cc index 4d62b9e9..7d8de6d0 100644 --- a/src/hb-font.cc +++ b/src/hb-font.cc @@ -341,7 +341,8 @@ hb_font_get_glyph_from_name_parent (hb_font_t *font, return font->parent->get_glyph_from_name (name, len, glyph); } -static const hb_font_funcs_t _hb_font_funcs_nil = { +DEFINE_NULL_INSTANCE (hb_font_funcs_t) = +{ HB_OBJECT_HEADER_STATIC, true, /* immutable */ @@ -364,6 +365,7 @@ static const hb_font_funcs_t _hb_font_funcs_nil = { } } }; + static const hb_font_funcs_t _hb_font_funcs_parent = { HB_OBJECT_HEADER_STATIC, @@ -1100,6 +1102,37 @@ hb_font_glyph_from_string (hb_font_t *font, * hb_font_t */ +DEFINE_NULL_INSTANCE (hb_font_t) = +{ + HB_OBJECT_HEADER_STATIC, + + true, /* immutable */ + + nullptr, /* parent */ + const_cast<hb_face_t *> (&_hb_Null_hb_face_t), + + 1000, /* x_scale */ + 1000, /* y_scale */ + + 0, /* x_ppem */ + 0, /* y_ppem */ + 0, /* ptem */ + + 0, /* num_coords */ + nullptr, /* coords */ + + const_cast<hb_font_funcs_t *> (&_hb_Null_hb_font_funcs_t), /* klass */ + nullptr, /* user_data */ + nullptr, /* destroy */ + + { +#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT + } +}; + + /** * hb_font_create: (Xconstructor) * @face: a face. @@ -1187,36 +1220,7 @@ hb_font_create_sub_font (hb_font_t *parent) hb_font_t * hb_font_get_empty (void) { - static const hb_font_t _hb_font_nil = { - HB_OBJECT_HEADER_STATIC, - - true, /* immutable */ - - nullptr, /* parent */ - const_cast<hb_face_t *> (&_hb_face_nil), - - 1000, /* x_scale */ - 1000, /* y_scale */ - - 0, /* x_ppem */ - 0, /* y_ppem */ - 0, /* ptem */ - - 0, /* num_coords */ - nullptr, /* coords */ - - const_cast<hb_font_funcs_t *> (&_hb_font_funcs_nil), /* klass */ - nullptr, /* user_data */ - nullptr, /* destroy */ - - { -#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT - } - }; - - return const_cast<hb_font_t *> (&_hb_font_nil); + return const_cast<hb_font_t *> (&Null(hb_font_t)); } /** diff --git a/src/hb-null.hh b/src/hb-null.hh index 5ab3289e..91efee64 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -59,10 +59,19 @@ template <> \ } \ namespace Namespace { \ static_assert (true, "Just so we take semicolon after.") - #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size] +/* Specializaitons for arbitrary-content Null objects expressed as struct initializer. */ +#define DECLARE_NULL_INSTANCE(Type) \ +extern HB_INTERNAL const Type _hb_Null_##Type; \ +template <> \ +/*static*/ inline const Type& Null<Type> (void) { \ + return _hb_Null_##Type; \ +} \ +static_assert (true, "Just so we take semicolon after.") +#define DEFINE_NULL_INSTANCE(Type) \ +const Type _hb_Null_##Type /* Global writable pool. Enlarge as necessary. */ diff --git a/src/hb-ot-shape-complex-arabic-fallback.hh b/src/hb-ot-shape-complex-arabic-fallback.hh index 40c5015c..2803febb 100644 --- a/src/hb-ot-shape-complex-arabic-fallback.hh +++ b/src/hb-ot-shape-complex-arabic-fallback.hh @@ -205,8 +205,6 @@ struct arabic_fallback_plan_t hb_ot_layout_lookup_accelerator_t accel_array[ARABIC_FALLBACK_MAX_LOOKUPS]; }; -static const arabic_fallback_plan_t arabic_fallback_plan_nil = {}; - #if (defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_WIN1256) #define HB_WITH_WIN1256 #endif @@ -215,7 +213,8 @@ static const arabic_fallback_plan_t arabic_fallback_plan_nil = {}; #include "hb-ot-shape-complex-arabic-win1256.hh" #endif -struct ManifestLookup { +struct ManifestLookup +{ OT::Tag tag; OT::OffsetTo<OT::SubstLookup> lookupOffset; }; @@ -299,7 +298,7 @@ arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan, { arabic_fallback_plan_t *fallback_plan = (arabic_fallback_plan_t *) calloc (1, sizeof (arabic_fallback_plan_t)); if (unlikely (!fallback_plan)) - return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil); + return const_cast<arabic_fallback_plan_t *> (&Null(arabic_fallback_plan_t)); fallback_plan->num_lookups = 0; fallback_plan->free_lookups = false; @@ -315,13 +314,13 @@ arabic_fallback_plan_create (const hb_ot_shape_plan_t *plan, return fallback_plan; free (fallback_plan); - return const_cast<arabic_fallback_plan_t *> (&arabic_fallback_plan_nil); + return const_cast<arabic_fallback_plan_t *> (&Null(arabic_fallback_plan_t)); } static void arabic_fallback_plan_destroy (arabic_fallback_plan_t *fallback_plan) { - if (!fallback_plan || fallback_plan == &arabic_fallback_plan_nil) + if (!fallback_plan || fallback_plan == &Null(arabic_fallback_plan_t)) return; for (unsigned int i = 0; i < fallback_plan->num_lookups; i++) diff --git a/src/hb-shape-plan-private.hh b/src/hb-shape-plan-private.hh index c2c4987e..7d020ff1 100644 --- a/src/hb-shape-plan-private.hh +++ b/src/hb-shape-plan-private.hh @@ -51,6 +51,7 @@ struct hb_shape_plan_t struct hb_shaper_data_t shaper_data; }; +DECLARE_NULL_INSTANCE (hb_shape_plan_t); #define HB_SHAPER_DATA_CREATE_FUNC_EXTRA_ARGS \ , const hb_feature_t *user_features \ diff --git a/src/hb-shape-plan.cc b/src/hb-shape-plan.cc index 37ff1a6e..cc1834c4 100644 --- a/src/hb-shape-plan.cc +++ b/src/hb-shape-plan.cc @@ -88,6 +88,31 @@ hb_shape_plan_plan (hb_shape_plan_t *shape_plan, * hb_shape_plan_t */ +DEFINE_NULL_INSTANCE (hb_shape_plan_t) = +{ + HB_OBJECT_HEADER_STATIC, + + true, /* default_shaper_list */ + nullptr, /* face */ + HB_SEGMENT_PROPERTIES_DEFAULT, /* props */ + + nullptr, /* shaper_func */ + nullptr, /* shaper_name */ + + nullptr, /* user_features */ + 0, /* num_user_featurs */ + + nullptr, /* coords */ + 0, /* num_coords */ + + { +#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, +#include "hb-shaper-list.hh" +#undef HB_SHAPER_IMPLEMENT + } +}; + + /** * hb_shape_plan_create: (Xconstructor) * @face: @@ -188,30 +213,7 @@ hb_shape_plan_create2 (hb_face_t *face, hb_shape_plan_t * hb_shape_plan_get_empty (void) { - static const hb_shape_plan_t _hb_shape_plan_nil = { - HB_OBJECT_HEADER_STATIC, - - true, /* default_shaper_list */ - nullptr, /* face */ - HB_SEGMENT_PROPERTIES_DEFAULT, /* props */ - - nullptr, /* shaper_func */ - nullptr, /* shaper_name */ - - nullptr, /* user_features */ - 0, /* num_user_featurs */ - - nullptr, /* coords */ - 0, /* num_coords */ - - { -#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID, -#include "hb-shaper-list.hh" -#undef HB_SHAPER_IMPLEMENT - } - }; - - return const_cast<hb_shape_plan_t *> (&_hb_shape_plan_nil); + return const_cast<hb_shape_plan_t *> (&Null(hb_shape_plan_t)); } /** diff --git a/src/hb-unicode-private.hh b/src/hb-unicode-private.hh index b2c203d2..fb16ba43 100644 --- a/src/hb-unicode-private.hh +++ b/src/hb-unicode-private.hh @@ -60,7 +60,8 @@ extern HB_INTERNAL const uint8_t _hb_modified_combining_class[256]; HB_UNICODE_FUNC_IMPLEMENT (hb_script_t, script) \ /* ^--- Add new simple callbacks here */ -struct hb_unicode_funcs_t { +struct hb_unicode_funcs_t +{ hb_object_header_t header; ASSERT_POD (); @@ -263,9 +264,7 @@ HB_UNICODE_FUNCS_IMPLEMENT_CALLBACKS_SIMPLE #undef HB_UNICODE_FUNC_IMPLEMENT } destroy; }; - - -extern HB_INTERNAL const hb_unicode_funcs_t _hb_unicode_funcs_nil; +DECLARE_NULL_INSTANCE (hb_unicode_funcs_t); /* Modified combining marks */ diff --git a/src/hb-unicode.cc b/src/hb-unicode.cc index 2d16c2e3..8cb41723 100644 --- a/src/hb-unicode.cc +++ b/src/hb-unicode.cc @@ -185,7 +185,8 @@ hb_unicode_funcs_create (hb_unicode_funcs_t *parent) } -const hb_unicode_funcs_t _hb_unicode_funcs_nil = { +DEFINE_NULL_INSTANCE (hb_unicode_funcs_t) = +{ HB_OBJECT_HEADER_STATIC, nullptr, /* parent */ @@ -209,7 +210,7 @@ const hb_unicode_funcs_t _hb_unicode_funcs_nil = { hb_unicode_funcs_t * hb_unicode_funcs_get_empty (void) { - return const_cast<hb_unicode_funcs_t *> (&_hb_unicode_funcs_nil); + return const_cast<hb_unicode_funcs_t *> (&Null(hb_unicode_funcs_t)); } /** commit 1abd427acfb7229b8607646bdde59f29306b86e1 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 6 05:53:35 2018 -0700 [BASE] Rename horzi/vert to h/v diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh index 70b954b8..96da07fb 100644 --- a/src/hb-ot-layout-base-table.hh +++ b/src/hb-ot-layout-base-table.hh @@ -525,78 +525,78 @@ struct BASE { static const hb_tag_t tableTag = HB_OT_TAG_BASE; - inline bool has_vert_axis(void) { return vertAxis != 0; } + inline bool has_v_axis(void) { return vAxis != 0; } - inline bool has_horiz_axis(void) { return horizAxis != 0; } + inline bool has_h_axis(void) { return hAxis != 0; } - inline unsigned int get_horiz_base_tag_index (Tag baselineTag) const + inline unsigned int get_h_base_tag_index (Tag baselineTag) const { - return (this+horizAxis).get_base_tag_index(baselineTag); + return (this+hAxis).get_base_tag_index(baselineTag); } - inline unsigned int get_horiz_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const + inline unsigned int get_h_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const { - return (this+horizAxis).get_default_base_tag_index_for_script_index(baseScriptIndex); + return (this+hAxis).get_default_base_tag_index_for_script_index(baseScriptIndex); } - inline int get_horiz_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const + inline int get_h_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const { - return (this+horizAxis).get_base_coord(baseScriptIndex, baselineTagIndex); + return (this+hAxis).get_base_coord(baseScriptIndex, baselineTagIndex); } - inline unsigned int get_vert_base_tag_index(Tag baselineTag) const + inline unsigned int get_v_base_tag_index(Tag baselineTag) const { - return (this+vertAxis).get_base_tag_index(baselineTag); + return (this+vAxis).get_base_tag_index(baselineTag); } - inline unsigned int get_vert_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const + inline unsigned int get_v_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const { - return (this+vertAxis).get_default_base_tag_index_for_script_index(baseScriptIndex); + return (this+vAxis).get_default_base_tag_index_for_script_index(baseScriptIndex); } - inline int get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const + inline int get_v_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const { - return (this+vertAxis).get_base_coord(baseScriptIndex, baselineTagIndex); + return (this+vAxis).get_base_coord(baseScriptIndex, baselineTagIndex); } - inline unsigned int get_horiz_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const + inline unsigned int get_h_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const { - return (this+horizAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag); + return (this+hAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag); } - inline unsigned int get_horiz_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const + inline unsigned int get_h_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const { - return (this+horizAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag); + return (this+hAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag); } - inline int get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + inline int get_h_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const { - return (this+horizAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + return (this+hAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); } - inline int get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + inline int get_h_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const { - return (this+horizAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + return (this+hAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); } - inline unsigned int get_vert_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const + inline unsigned int get_v_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const { - return (this+vertAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag); + return (this+vAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag); } - inline unsigned int get_vert_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const + inline unsigned int get_v_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const { - return (this+vertAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag); + return (this+vAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag); } - inline int get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + inline int get_v_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const { - return (this+vertAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + return (this+vAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); } - inline int get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const + inline int get_v_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const { - return (this+vertAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); + return (this+vAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); } inline bool sanitize (hb_sanitize_context_t *c) const @@ -604,15 +604,15 @@ struct BASE TRACE_SANITIZE (this); return_trace (c->check_struct (this) && likely (version.major == 1) && - horizAxis.sanitize (c, this) && - vertAxis.sanitize (c, this) && + hAxis.sanitize (c, this) && + vAxis.sanitize (c, this) && (version.to_int () < 0x00010001u || varStore.sanitize (c, this))); } protected: FixedVersion<> version; - OffsetTo<Axis> horizAxis; - OffsetTo<Axis> vertAxis; + OffsetTo<Axis> hAxis; + OffsetTo<Axis> vAxis; LOffsetTo<VariationStore> varStore; /* Offset to the table of Item Variation * Store--from beginning of BASE commit da48aca1be89efbb8b3ca4471f542aa54aff17c4 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 6 05:52:12 2018 -0700 [BASE] Misc fixes The code was badly broken. In better shape now, but still, needs a full review before ever working. diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh index 33dce890..70b954b8 100644 --- a/src/hb-ot-layout-base-table.hh +++ b/src/hb-ot-layout-base-table.hh @@ -33,13 +33,16 @@ namespace OT { -#define NOT_INDEXED ((unsigned int) -1) - /* * BASE -- Baseline * https://docs.microsoft.com/en-us/typography/opentype/spec/base */ + +/* XXX Review this. */ +#define NOT_INDEXED ((unsigned int) -1) + + struct BaseCoordFormat1 { inline int get_coord (void) const { return coordinate; } @@ -52,7 +55,7 @@ struct BaseCoordFormat1 protected: HBUINT16 format; /* Format identifier--format = 1 */ - HBINT16 coordinate; /* X or Y value, in design units */ + FWORD coordinate; /* X or Y value, in design units */ public: DEFINE_SIZE_STATIC (4); }; @@ -73,7 +76,7 @@ struct BaseCoordFormat2 protected: HBUINT16 format; /* Format identifier--format = 2 */ - HBINT16 coordinate; /* X or Y value, in design units */ + FWORD coordinate; /* X or Y value, in design units */ GlyphID referenceGlyph; /* Glyph ID of control glyph */ HBUINT16 coordPoint; /* Index of contour point on the * reference glyph */ @@ -97,7 +100,7 @@ struct BaseCoordFormat3 protected: HBUINT16 format; /* Format identifier--format = 3 */ - HBINT16 coordinate; /* X or Y value, in design units */ + FWORD coordinate; /* X or Y value, in design units */ OffsetTo<Device> deviceTable; /* Offset to Device table for X or * Y value, from beginning of * BaseCoord table (may be NULL). */ @@ -109,6 +112,7 @@ struct BaseCoord { inline int get_coord (void) const { + /* XXX wire up direction and font. */ switch (u.format) { case 1: return u.format1.get_coord (); case 2: return u.format2.get_coord (); @@ -142,14 +146,10 @@ struct BaseCoord struct FeatMinMaxRecord { - inline int get_min_value (void) const - { return (this+minCoord).get_coord(); } - - inline int get_max_value (void) const - { return (this+maxCoord).get_coord(); } + inline int get_min_value (void) const { return (this+minCoord).get_coord(); } + inline int get_max_value (void) const { return (this+maxCoord).get_coord(); } - inline const Tag &get_tag () const - { return tag; } + inline const Tag& get_tag () const { return tag; } inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { @@ -181,7 +181,7 @@ struct MinMax unsigned int count = featMinMaxRecords.len; for (unsigned int i = 0; i < count; i++) { - Tag tag = featMinMaxRecords[i].get_tag(); + Tag tag = featMinMaxRecords[i].get_tag (); int cmp = tag.cmp(featureTableTag); if (cmp == 0) return i; if (cmp > 0) return NOT_INDEXED; @@ -233,13 +233,13 @@ struct BaseLangSysRecord { return baseLangSysTag; } inline unsigned int get_feature_tag_index (Tag featureTableTag) const - { return (this+minMax).get_feature_tag_index(featureTableTag); } + { return (this+minMax).get_feature_tag_index( featureTableTag); } inline int get_min_value (unsigned int featureTableTagIndex) const - { return (this+minMax).get_min_value(featureTableTagIndex); } + { return (this+minMax).get_min_value( featureTableTagIndex); } inline int get_max_value (unsigned int featureTableTagIndex) const - { return (this+minMax).get_max_value(featureTableTagIndex); } + { return (this+minMax).get_max_value (featureTableTagIndex); } inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { @@ -263,34 +263,34 @@ struct BaseValues inline int get_base_coord (unsigned int baselineTagIndex) const { - return (this+baseCoords[baselineTagIndex]).get_coord(); + return (this+baseCoords[baselineTagIndex]).get_coord (); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - defaultIndex <= baseCoordCount && - baseCoords.sanitize (c, this)); + baseCoords.sanitize (c, this)); } protected: Index defaultIndex; - HBUINT16 baseCoordCount; OffsetArrayOf<BaseCoord> baseCoords; public: - DEFINE_SIZE_ARRAY (6, baseCoords); - + DEFINE_SIZE_ARRAY (4, baseCoords); }; struct BaseScript { inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const { + /* XXX bsearch */ Tag tag; int cmp; - for (unsigned int i = 0; i < baseLangSysCount; i++) { - tag = baseLangSysRecords[i].get_tag(); + unsigned int count = baseLangSysRecords.len; + for (unsigned int i = 0; i < count; i++) + { + tag = baseLangSysRecords[i].get_tag (); // taking advantage of alphabetical order cmp = tag.cmp(baseLangSysTag); if (cmp == 0) return i; @@ -301,51 +301,50 @@ struct BaseScript { inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const { - if (baseLangSysIndex == NOT_INDEXED) { + if (baseLangSysIndex == NOT_INDEXED) + { if (unlikely(defaultMinMax)) return NOT_INDEXED; - return (this+defaultMinMax).get_feature_tag_index(featureTableTag); + return (this+defaultMinMax).get_feature_tag_index (featureTableTag); } - if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NOT_INDEXED; - return baseLangSysRecords[baseLangSysIndex].get_feature_tag_index(featureTableTag); + return baseLangSysRecords[baseLangSysIndex].get_feature_tag_index (featureTableTag); } inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const { if (baseLangSysIndex == NOT_INDEXED) - return (this+defaultMinMax).get_min_value(featureTableTagIndex); - return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex); + return (this+defaultMinMax).get_min_value (featureTableTagIndex); + return baseLangSysRecords[baseLangSysIndex].get_max_value (featureTableTagIndex); } inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const { if (baseLangSysIndex == NOT_INDEXED) - return (this+defaultMinMax).get_min_value(featureTableTagIndex); - return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex); + return (this+defaultMinMax).get_min_value (featureTableTagIndex); + return baseLangSysRecords[baseLangSysIndex].get_max_value (featureTableTagIndex); } inline unsigned int get_default_base_tag_index (void) const - { return (this+baseValues).get_default_base_tag_index(); } + { return (this+baseValues).get_default_base_tag_index (); } inline int get_base_coord (unsigned int baselineTagIndex) const - { return (this+baseValues).get_base_coord(baselineTagIndex); } + { return (this+baseValues).get_base_coord (baselineTagIndex); } inline bool sanitize (hb_sanitize_context_t *c) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - baseValues.sanitize (c, this) && - defaultMinMax.sanitize (c, this) && - baseLangSysRecords.sanitize (c, this)); + baseValues.sanitize (c, this) && + defaultMinMax.sanitize (c, this) && + baseLangSysRecords.sanitize (c, this)); } protected: - OffsetTo<BaseValues> baseValues; - OffsetTo<MinMax> defaultMinMax; - HBUINT16 baseLangSysCount; - ArrayOf<BaseLangSysRecord> baseLangSysRecords; + OffsetTo<BaseValues> baseValues; + OffsetTo<MinMax> defaultMinMax; + ArrayOf<BaseLangSysRecord> baseLangSysRecords; public: - DEFINE_SIZE_ARRAY (8, baseLangSysRecords); + DEFINE_SIZE_ARRAY (6, baseLangSysRecords); }; @@ -355,29 +354,28 @@ struct BaseScriptRecord { { return baseScriptTag; } inline unsigned int get_default_base_tag_index(void) const - { return (this+baseScript).get_default_base_tag_index(); } + { return (this+baseScript).get_default_base_tag_index (); } inline int get_base_coord(unsigned int baselineTagIndex) const - { return (this+baseScript).get_base_coord(baselineTagIndex); } + { return (this+baseScript).get_base_coord (baselineTagIndex); } inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const - { return (this+baseScript).get_lang_tag_index(baseLangSysTag); } + { return (this+baseScript).get_lang_tag_index (baseLangSysTag); } inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const - { return (this+baseScript).get_feature_tag_index(baseLangSysIndex, featureTableTag); } + { return (this+baseScript).get_feature_tag_index (baseLangSysIndex, featureTableTag); } inline int get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { return (this+baseScript).get_max_value(baseLangSysIndex, featureTableTagIndex); } + { return (this+baseScript).get_max_value (baseLangSysIndex, featureTableTagIndex); } inline int get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const - { return (this+baseScript).get_min_value(baseLangSysIndex, featureTableTagIndex); } + { return (this+baseScript).get_min_value (baseLangSysIndex, featureTableTagIndex); } inline bool sanitize (hb_sanitize_context_t *c, const void *base) const { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - baseScript != Null(OffsetTo<BaseScript>) && - baseScript.sanitize (c, base)); + baseScript.sanitize (c, base)); } protected: @@ -392,7 +390,9 @@ struct BaseScriptList { inline unsigned int get_base_script_index (Tag baseScriptTag) const { - for (unsigned int i = 0; i < baseScriptCount; i++) + /* XXX bsearch? */ + unsigned int count = baseScriptRecords.len; + for (unsigned int i = 0; i < count; i++) if (baseScriptRecords[i].get_tag() == baseScriptTag) return i; return NOT_INDEXED; @@ -400,7 +400,6 @@ struct BaseScriptList { inline unsigned int get_default_base_tag_index (unsigned int baseScriptIndex) const { - if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED; return baseScriptRecords[baseScriptIndex].get_default_base_tag_index(); } @@ -411,13 +410,11 @@ struct BaseScriptList { inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const { - if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED; return baseScriptRecords[baseScriptIndex].get_lang_tag_index(baseLangSysTag); } inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const { - if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED; return baseScriptRecords[baseScriptIndex].get_feature_tag_index(baseLangSysIndex, featureTableTag); } @@ -435,24 +432,23 @@ struct BaseScriptList { { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - baseScriptRecords.sanitize (c, this)); + baseScriptRecords.sanitize (c, this)); } protected: - HBUINT16 baseScriptCount; - ArrayOf<BaseScriptRecord> baseScriptRecords; + ArrayOf<BaseScriptRecord> baseScriptRecords; public: - DEFINE_SIZE_ARRAY (4, baseScriptRecords); - + DEFINE_SIZE_ARRAY (2, baseScriptRecords); }; struct BaseTagList { - - inline unsigned int get_tag_index(Tag baselineTag) const + inline unsigned int get_tag_index (Tag baselineTag) const { - for (unsigned int i = 0; i < baseTagCount; i++) + /* TODO bsearch? */ + unsigned int count = baselineTags.len; + for (unsigned int i = 0; i < count; i++) if (baselineTags[i] == baselineTag) return i; return NOT_INDEXED; @@ -465,42 +461,37 @@ struct BaseTagList } protected: - HBUINT16 baseTagCount; SortedArrayOf<Tag> baselineTags; public: - DEFINE_SIZE_ARRAY (4, baselineTags); + DEFINE_SIZE_ARRAY (2, baselineTags); }; struct Axis { - inline unsigned int get_base_tag_index(Tag baselineTag) const + inline unsigned int get_base_tag_index (Tag baselineTag) const { - if (unlikely(baseTagList == Null(OffsetTo<BaseTagList>))) return NOT_INDEXED; return (this+baseTagList).get_tag_index(baselineTag); } inline unsigned int get_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const { - if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED; return (this+baseScriptList).get_default_base_tag_index(baseScriptIndex); } - inline int get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const + inline int get_base_coord (unsigned int baseScriptIndex, unsigned int baselineTagIndex) const { return (this+baseScriptList).get_base_coord(baseScriptIndex, baselineTagIndex); } inline unsigned int get_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const { - if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED; return (this+baseScriptList).get_lang_tag_index(baseScriptIndex, baseLangSysTag); } inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const { - if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NOT_INDEXED; return (this+baseScriptList).get_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag); } @@ -518,13 +509,13 @@ struct Axis { TRACE_SANITIZE (this); return_trace (c->check_struct (this) && - baseTagList.sanitize (c, this) && - baseScriptList.sanitize (c, this)); + baseTagList.sanitize (c, this) && + baseScriptList.sanitize (c, this)); } protected: - OffsetTo<BaseTagList> baseTagList; - OffsetTo<BaseScriptList> baseScriptList; + OffsetTo<BaseTagList> baseTagList; + OffsetTo<BaseScriptList> baseScriptList; public: DEFINE_SIZE_STATIC (4); @@ -534,23 +525,17 @@ struct BASE { static const hb_tag_t tableTag = HB_OT_TAG_BASE; - inline bool has_vert_axis(void) - { return vertAxis != Null(OffsetTo<Axis>); } + inline bool has_vert_axis(void) { return vertAxis != 0; } - inline bool has_horiz_axis(void) - { return horizAxis != Null(OffsetTo<Axis>); } + inline bool has_horiz_axis(void) { return horizAxis != 0; } - // horizontal axis base coords: - - inline unsigned int get_horiz_base_tag_index(Tag baselineTag) const + inline unsigned int get_horiz_base_tag_index (Tag baselineTag) const { - if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; return (this+horizAxis).get_base_tag_index(baselineTag); } inline unsigned int get_horiz_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const { - if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; return (this+horizAxis).get_default_base_tag_index_for_script_index(baseScriptIndex); } @@ -559,17 +544,13 @@ struct BASE return (this+horizAxis).get_base_coord(baseScriptIndex, baselineTagIndex); } - // vertical axis base coords: - inline unsigned int get_vert_base_tag_index(Tag baselineTag) const { - if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; return (this+vertAxis).get_base_tag_index(baselineTag); } inline unsigned int get_vert_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const { - if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; return (this+vertAxis).get_default_base_tag_index_for_script_index(baseScriptIndex); } @@ -578,17 +559,13 @@ struct BASE return (this+vertAxis).get_base_coord(baseScriptIndex, baselineTagIndex); } - // horizontal axis min/max coords: - inline unsigned int get_horiz_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const { - if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; return (this+horizAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag); } inline unsigned int get_horiz_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const { - if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; return (this+horizAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag); } @@ -602,17 +579,13 @@ struct BASE return (this+horizAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex); } - // vertical axis min/max coords: - inline unsigned int get_vert_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const { - if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; return (this+vertAxis).get_lang_tag_index (baseScriptIndex, baseLangSysTag); } inline unsigned int get_vert_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const { - if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NOT_INDEXED; return (this+vertAxis).get_feature_tag_index (baseScriptIndex, baseLangSysIndex, featureTableTag); } commit f9cfa5cb0e70203279e74fb6adb0cd4570238ff8 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 6 05:29:15 2018 -0700 Change null-pool specialization to min_size again diff --git a/src/hb-null.hh b/src/hb-null.hh index ca7492eb..5ab3289e 100644 --- a/src/hb-null.hh +++ b/src/hb-null.hh @@ -49,19 +49,19 @@ static inline Type const & Null (void) { } #define Null(Type) Null<Type>() -/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */ +/* Specializaitons for arbitrary-content Null objects expressed in bytes. */ #define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \ } /* Close namespace. */ \ -extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[sizeof (Namespace::Type)]; \ +extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size]; \ template <> \ /*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \ return *reinterpret_cast<const Namespace::Type *> (_hb_Null_##Namespace##_##Type); \ } \ namespace Namespace { \ -static_assert (Namespace::Type::min_size <= sizeof (Type), "Null pool too small. Enlarge."); \ +static_assert (true, "Just so we take semicolon after.") #define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ -const unsigned char _hb_Null_##Namespace##_##Type[sizeof (Namespace::Type)] +const unsigned char _hb_Null_##Namespace##_##Type[Namespace::Type::min_size] /* Global writable pool. Enlarge as necessary. */ commit 25147ff8086ab65995fe046cfdf8007604de6962 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 6 05:01:52 2018 -0700 Move Null system to hb-null.hh diff --git a/src/Makefile.sources b/src/Makefile.sources index 0a383dfc..b981b0e2 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -19,6 +19,7 @@ HB_BASE_sources = \ hb-map.cc \ hb-machinery-private.hh \ hb-mutex-private.hh \ + hb-null.hh \ hb-object-private.hh \ hb-open-file-private.hh \ hb-open-type-private.hh \ diff --git a/src/hb-null.hh b/src/hb-null.hh new file mode 100644 index 00000000..ca7492eb --- /dev/null +++ b/src/hb-null.hh @@ -0,0 +1,97 @@ +/* + * 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_NULL_HH +#define HB_NULL_HH + +#include "hb-private.hh" + + +/* + * Static pools + */ + +/* Global nul-content Null pool. Enlarge as necessary. */ + +#define HB_NULL_POOL_SIZE 264 + +extern HB_INTERNAL +hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; + +/* Generic nul-content Null objects. */ +template <typename Type> +static inline Type const & Null (void) { + static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + return *reinterpret_cast<Type const *> (_hb_NullPool); +} +#define Null(Type) Null<Type>() + +/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */ +#define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \ +} /* Close namespace. */ \ +extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[sizeof (Namespace::Type)]; \ +template <> \ +/*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \ + return *reinterpret_cast<const Namespace::Type *> (_hb_Null_##Namespace##_##Type); \ +} \ +namespace Namespace { \ +static_assert (Namespace::Type::min_size <= sizeof (Type), "Null pool too small. Enlarge."); \ + +#define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ +const unsigned char _hb_Null_##Namespace##_##Type[sizeof (Namespace::Type)] + + +/* Global writable pool. Enlarge as necessary. */ + +/* To be fully correct, CrapPool must be thread_local. However, we do not rely on CrapPool + * for correct operation. It only exist to catch and divert program logic bugs instead of + * causing bad memory access. So, races there are not actually introducing incorrectness + * in the code. Has ~12kb binary size overhead to have it, also clang build fails with it. */ +extern HB_INTERNAL +/*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; + +/* CRAP pool: Common Region for Access Protection. */ +template <typename Type> +static inline Type& Crap (void) { + static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); + Type *obj = reinterpret_cast<Type *> (_hb_CrapPool); + *obj = Null(Type); + return *obj; +} +#define Crap(Type) Crap<Type>() + +template <typename Type> +struct CrapOrNull { + static inline Type & get (void) { return Crap(Type); } +}; +template <typename Type> +struct CrapOrNull<const Type> { + static inline Type const & get (void) { return Null(Type); } +}; +#define CrapOrNull(Type) CrapOrNull<Type>::get () + + +#endif /* HB_NULL_HH */ diff --git a/src/hb-private.hh b/src/hb-private.hh index 5d12fb05..1bc996ed 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -368,70 +368,6 @@ typedef uint64_t hb_vector_size_impl_t; #endif -/* - * Static pools - */ - -/* Global nul-content Null pool. Enlarge as necessary. */ - -#define HB_NULL_POOL_SIZE 264 - -extern HB_INTERNAL -hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; - -/* Generic nul-content Null objects. */ -template <typename Type> -static inline Type const & Null (void) { - static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); - return *reinterpret_cast<Type const *> (_hb_NullPool); -} -#define Null(Type) Null<Type>() - -/* Specializaiton for arbitrary-content arbitrary-sized Null objects. */ -#define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \ -} /* Close namespace. */ \ -extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[sizeof (Namespace::Type)]; \ -template <> \ -/*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \ - return *reinterpret_cast<const Namespace::Type *> (_hb_Null_##Namespace##_##Type); \ -} \ -namespace Namespace { \ -static_assert (Namespace::Type::min_size <= sizeof (Type), "Null pool too small. Enlarge."); \ - -#define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ -const unsigned char _hb_Null_##Namespace##_##Type[sizeof (Namespace::Type)] - - -/* Global writable pool. Enlarge as necessary. */ - -/* To be fully correct, CrapPool must be thread_local. However, we do not rely on CrapPool - * for correct operation. It only exist to catch and divert program logic bugs instead of - * causing bad memory access. So, races there are not actually introducing incorrectness - * in the code. Has ~12kb binary size overhead to have it, also clang build fails with it. */ -extern HB_INTERNAL -/*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)]; - -/* CRAP pool: Common Region for Access Protection. */ -template <typename Type> -static inline Type& Crap (void) { - static_assert (sizeof (Type) <= HB_NULL_POOL_SIZE, "Increase HB_NULL_POOL_SIZE."); - Type *obj = reinterpret_cast<Type *> (_hb_CrapPool); - *obj = Null(Type); - return *obj; -} -#define Crap(Type) Crap<Type>() - -template <typename Type> -struct CrapOrNull { - static inline Type & get (void) { return Crap(Type); } -}; -template <typename Type> -struct CrapOrNull<const Type> { - static inline Type const & get (void) { return Null(Type); } -}; -#define CrapOrNull(Type) CrapOrNull<Type>::get () - - /* HB_NDEBUG disables some sanity checks that are very safe to disable and * should be disabled in production systems. If NDEBUG is defined, enable * HB_NDEBUG; but if it's desirable that normal assert()s (which are very @@ -525,6 +461,7 @@ _hb_memalign(void **memptr, size_t alignment, size_t size) #include "hb-debug.hh" #include "hb-dsalgs.hh" #include "hb-mutex-private.hh" +#include "hb-null.hh" #include "hb-object-private.hh" #endif /* HB_PRIVATE_HH */ commit f800368df33e7ec15c3e77bdb9f4b464899322d3 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 6 04:58:34 2018 -0700 Remove unused macros diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index 66a35df0..47255488 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -42,7 +42,6 @@ * Lockable set */ -#define HB_LOCKABLE_SET_INIT {HB_VECTOR_INIT} template <typename item_t, typename lock_t> struct hb_lockable_set_t { diff --git a/src/hb-vector-private.hh b/src/hb-vector-private.hh index 157fbd51..1ef20d43 100644 --- a/src/hb-vector-private.hh +++ b/src/hb-vector-private.hh @@ -31,7 +31,6 @@ #include "hb-private.hh" -#define HB_VECTOR_INIT {0, 0, false, nullptr} template <typename Type, unsigned int StaticSize=8> struct hb_vector_t { commit 19e0091299f06856002c702792b448b06da637a8 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 6 04:54:31 2018 -0700 Minor diff --git a/src/hb-private.hh b/src/hb-private.hh index 35881607..5d12fb05 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -285,13 +285,12 @@ static int errno = 0; /* Use something better? */ #define HB_STMT_START do #define HB_STMT_END while (0) +/* Static-assert as expression. */ template <unsigned int cond> class hb_assert_constant_t; template <> class hb_assert_constant_t<1> {}; - #define ASSERT_STATIC_EXPR_ZERO(_cond) (0 * (unsigned int) sizeof (hb_assert_constant_t<_cond>)) /* Lets assert int types. Saves trouble down the road. */ - static_assert ((sizeof (int8_t) == 1), ""); static_assert ((sizeof (uint8_t) == 1), ""); static_assert ((sizeof (int16_t) == 2), ""); @@ -300,7 +299,6 @@ static_assert ((sizeof (int32_t) == 4), ""); static_assert ((sizeof (uint32_t) == 4), ""); static_assert ((sizeof (int64_t) == 8), ""); static_assert ((sizeof (uint64_t) == 8), ""); - static_assert ((sizeof (hb_codepoint_t) == 4), ""); static_assert ((sizeof (hb_position_t) == 4), ""); static_assert ((sizeof (hb_mask_t) == 4), ""); commit 37be774af921812018f723521b90f2ab54f661c5 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 6 04:51:38 2018 -0700 Minor diff --git a/src/hb-private.hh b/src/hb-private.hh index 98a21188..35881607 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -86,7 +86,7 @@ extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size); /* * Compiler attributes - * */ + */ #if __cplusplus < 201103L @@ -98,7 +98,6 @@ extern "C" int hb_memalign_impl(void **memptr, size_t alignment, size_t size); #define constexpr const #endif -// Static assertions #ifndef static_assert #define static_assert(e, msg) \ HB_UNUSED typedef int HB_PASTE(static_assertion_failed_at_line_, __LINE__) [(e) ? 1 : -1] @@ -124,7 +123,7 @@ struct _hb_alignof }; #ifndef alignof #define alignof(x) (_hb_alignof<x>::value) -#endif // alignof +#endif #endif // __cplusplus < 201103L commit e1acff806b469e58f568bf5ad6ba578207821e87 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 6 04:42:46 2018 -0700 Move hb_vector_t to hb-vector-private.hh diff --git a/src/Makefile.sources b/src/Makefile.sources index 80b8e261..0a383dfc 100644 --- a/src/Makefile.sources +++ b/src/Makefile.sources @@ -52,6 +52,7 @@ HB_BASE_sources = \ hb-string-array.hh \ hb-unicode-private.hh \ hb-unicode.cc \ + hb-vector-private.hh \ hb-utf-private.hh \ hb-warning.cc \ $(NULL) diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index 36395db2..8cbe6584 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -488,303 +488,6 @@ hb_codepoint_parse (const char *s, unsigned int len, int base, hb_codepoint_t *o } -#define HB_VECTOR_INIT {0, 0, false, nullptr} -template <typename Type, unsigned int StaticSize=8> -struct hb_vector_t -{ - unsigned int len; - unsigned int allocated; /* == 0 means allocation failed. */ - Type *arrayZ; - Type static_array[StaticSize]; - - void init (void) - { - len = 0; - allocated = ARRAY_LENGTH (static_array); - arrayZ = static_array; - } - - inline Type& operator [] (unsigned int i) - { - if (unlikely (i >= len)) - return Crap (Type); - return arrayZ[i]; - } - inline const Type& operator [] (unsigned int i) const - { - if (unlikely (i >= len)) - return Null(Type); - return arrayZ[i]; - } - - inline Type *push (void) - { - if (unlikely (!resize (len + 1))) - return &Crap(Type); - return &arrayZ[len - 1]; - } - inline Type *push (const Type& v) - { - Type *p = push (); - *p = v; - return p; - } - - /* Allocate for size but don't adjust len. */ - inline bool alloc (unsigned int size) - { - if (unlikely (!allocated)) - return false; - - if (likely (size <= allocated)) - return true; - - /* Reallocate */ - - unsigned int new_allocated = allocated; - while (size >= new_allocated) - new_allocated += (new_allocated >> 1) + 8; - - Type *new_array = nullptr; - - if (arrayZ == static_array) - { - new_array = (Type *) calloc (new_allocated, sizeof (Type)); - if (new_array) - memcpy (new_array, arrayZ, 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)); - } - - if (unlikely (!new_array)) - { - allocated = 0; - return false; - } - - arrayZ = new_array; - allocated = new_allocated; - - return true; - } - - inline bool resize (int size_) - { - unsigned int size = size_ < 0 ? 0u : (unsigned int) size_; - if (!alloc (size)) - return false; - - if (size > len) - memset (arrayZ + len, 0, (size - len) * sizeof (*arrayZ)); - - len = size; - return true; - } - - inline void pop (void) - { - if (!len) return; - len--; - } - - 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--; - } - - inline void shrink (int size_) - { - unsigned int size = size_ < 0 ? 0u : (unsigned int) size_; - if (size < len) - len = size; - } - - template <typename T> - inline Type *find (T v) { - for (unsigned int i = 0; i < len; i++) - if (arrayZ[i] == v) - return &arrayZ[i]; - return nullptr; - } - template <typename T> - inline const Type *find (T v) const { - for (unsigned int i = 0; i < len; i++) - if (arrayZ[i] == v) - return &arrayZ[i]; - return nullptr; - } - - inline void qsort (int (*cmp)(const void*, const void*)) - { - ::qsort (arrayZ, len, sizeof (Type), cmp); - } - - inline void qsort (void) - { - ::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); - } - - template <typename T> - inline Type *lsearch (const T &x) - { - for (unsigned int i = 0; i < len; i++) - if (0 == this->arrayZ[i].cmp (&x)) - return &arrayZ[i]; - return nullptr; - } - - template <typename T> - inline Type *bsearch (const T &x) - { - unsigned int i; - 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; - } - template <typename T> - inline bool bfind (const T &x, unsigned int *i) const - { - int min = 0, max = (int) this->len - 1; - while (min <= max) - { - int mid = (min + max) / 2; - int c = this->arrayZ[mid].cmp (&x); - if (c < 0) - max = mid - 1; - else if (c > 0) - min = mid + 1; - else - { - *i = mid; - return true; - } - } - if (max < 0 || (max < (int) this->len && this->arrayZ[max].cmp (&x) > 0)) - max++; - *i = max; - return false; - } - - inline void fini (void) - { - if (arrayZ != static_array) - free (arrayZ); - arrayZ = nullptr; - allocated = len = 0; - } -}; - - -#define HB_LOCKABLE_SET_INIT {HB_VECTOR_INIT} -template <typename item_t, typename lock_t> -struct hb_lockable_set_t -{ - hb_vector_t <item_t, 1> items; - - inline void init (void) { items.init (); } - - template <typename T> - inline item_t *replace_or_insert (T v, lock_t &l, bool replace) - { - l.lock (); - item_t *item = items.find (v); - if (item) { - if (replace) { - item_t old = *item; - *item = v; - l.unlock (); - old.fini (); - } - else { - item = nullptr; - l.unlock (); - } - } else { - item = items.push (v); - l.unlock (); - } - return item; - } - - template <typename T> - inline void remove (T v, lock_t &l) - { - l.lock (); - item_t *item = items.find (v); - if (item) { - item_t old = *item; - *item = items[items.len - 1]; - items.pop (); - l.unlock (); - old.fini (); - } else { - l.unlock (); - } - } - - template <typename T> - inline bool find (T v, item_t *i, lock_t &l) - { - l.lock (); - item_t *item = items.find (v); - if (item) - *i = *item; - l.unlock (); - return !!item; - } - - template <typename T> - inline item_t *find_or_insert (T v, lock_t &l) - { - l.lock (); - item_t *item = items.find (v); - if (!item) { - item = items.push (v); - } - l.unlock (); - return item; - } - - inline void fini (lock_t &l) - { - if (!items.len) { - /* No need for locking. */ - items.fini (); - return; - } - l.lock (); - while (items.len) { - item_t old = items[items.len - 1]; - items.pop (); - l.unlock (); - old.fini (); - l.lock (); - } - items.fini (); - l.unlock (); - } - -}; - - template <typename Type> struct hb_auto_t : Type { diff --git a/src/hb-object-private.hh b/src/hb-object-private.hh index 36d27a89..66a35df0 100644 --- a/src/hb-object-private.hh +++ b/src/hb-object-private.hh @@ -35,9 +35,108 @@ #include "hb-private.hh" #include "hb-atomic-private.hh" #include "hb-mutex-private.hh" +#include "hb-vector-private.hh" -/* reference_count */ +/* + * Lockable set + */ + +#define HB_LOCKABLE_SET_INIT {HB_VECTOR_INIT} +template <typename item_t, typename lock_t> +struct hb_lockable_set_t +{ + hb_vector_t <item_t, 1> items; + + inline void init (void) { items.init (); } + + template <typename T> + inline item_t *replace_or_insert (T v, lock_t &l, bool replace) + { + l.lock (); + item_t *item = items.find (v); + if (item) { + if (replace) { + item_t old = *item; + *item = v; + l.unlock (); + old.fini (); + } + else { + item = nullptr; + l.unlock (); + } + } else { + item = items.push (v); + l.unlock (); + } + return item; + } + + template <typename T> + inline void remove (T v, lock_t &l) + { + l.lock (); + item_t *item = items.find (v); + if (item) { + item_t old = *item; + *item = items[items.len - 1]; + items.pop (); + l.unlock (); + old.fini (); + } else { + l.unlock (); + } + } + + template <typename T> + inline bool find (T v, item_t *i, lock_t &l) + { + l.lock (); + item_t *item = items.find (v); + if (item) + *i = *item; + l.unlock (); + return !!item; + } + + template <typename T> + inline item_t *find_or_insert (T v, lock_t &l) + { + l.lock (); + item_t *item = items.find (v); + if (!item) { + item = items.push (v); + } + l.unlock (); + return item; + } + + inline void fini (lock_t &l) + { + if (!items.len) { + /* No need for locking. */ + items.fini (); + return; + } + l.lock (); + while (items.len) { + item_t old = items[items.len - 1]; + items.pop (); + l.unlock (); + old.fini (); + l.lock (); + } + items.fini (); + l.unlock (); + } + +}; + + +/* + * Reference-count. + */ #define HB_REFERENCE_COUNT_INERT_VALUE 0 #define HB_REFERENCE_COUNT_POISON_VALUE -0x0000DEAD @@ -89,7 +188,9 @@ struct hb_user_data_array_t }; -/* object_header */ +/* + * Object header + */ struct hb_object_header_t { @@ -103,7 +204,9 @@ struct hb_object_header_t }; -/* object */ +/* + * Object + */ template <typename Type> static inline void hb_object_trace (const Type *obj, const char *function) diff --git a/src/hb-vector-private.hh b/src/hb-vector-private.hh new file mode 100644 index 00000000..157fbd51 --- /dev/null +++ b/src/hb-vector-private.hh @@ -0,0 +1,239 @@ +/* + * Copyright © 2017,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. + * + * Red Hat Author(s): Behdad Esfahbod + * Google Author(s): Behdad Esfahbod + */ + +#ifndef HB_VECTOR_PRIVATE_HH +#define HB_VECTOR_PRIVATE_HH + +#include "hb-private.hh" + + +#define HB_VECTOR_INIT {0, 0, false, nullptr} +template <typename Type, unsigned int StaticSize=8> +struct hb_vector_t +{ + unsigned int len; + unsigned int allocated; /* == 0 means allocation failed. */ + Type *arrayZ; + Type static_array[StaticSize]; + + void init (void) + { + len = 0; + allocated = ARRAY_LENGTH (static_array); + arrayZ = static_array; + } + + inline Type& operator [] (unsigned int i) + { + if (unlikely (i >= len)) + return Crap (Type); + return arrayZ[i]; + } + inline const Type& operator [] (unsigned int i) const + { + if (unlikely (i >= len)) + return Null(Type); + return arrayZ[i]; + } + + inline Type *push (void) + { + if (unlikely (!resize (len + 1))) + return &Crap(Type); + return &arrayZ[len - 1]; + } + inline Type *push (const Type& v) + { + Type *p = push (); + *p = v; + return p; + } + + /* Allocate for size but don't adjust len. */ + inline bool alloc (unsigned int size) + { + if (unlikely (!allocated)) + return false; + + if (likely (size <= allocated)) + return true; + + /* Reallocate */ + + unsigned int new_allocated = allocated; + while (size >= new_allocated) + new_allocated += (new_allocated >> 1) + 8; + + Type *new_array = nullptr; + + if (arrayZ == static_array) + { + new_array = (Type *) calloc (new_allocated, sizeof (Type)); + if (new_array) + memcpy (new_array, arrayZ, 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)); + } + + if (unlikely (!new_array)) + { + allocated = 0; + return false; + } + + arrayZ = new_array; + allocated = new_allocated; + + return true; + } + + inline bool resize (int size_) + { + unsigned int size = size_ < 0 ? 0u : (unsigned int) size_; + if (!alloc (size)) + return false; + + if (size > len) + memset (arrayZ + len, 0, (size - len) * sizeof (*arrayZ)); + + len = size; + return true; + } + + inline void pop (void) + { + if (!len) return; + len--; + } + + 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--; + } + + inline void shrink (int size_) + { + unsigned int size = size_ < 0 ? 0u : (unsigned int) size_; + if (size < len) + len = size; + } + + template <typename T> + inline Type *find (T v) { + for (unsigned int i = 0; i < len; i++) + if (arrayZ[i] == v) + return &arrayZ[i]; + return nullptr; + } + template <typename T> + inline const Type *find (T v) const { + for (unsigned int i = 0; i < len; i++) + if (arrayZ[i] == v) + return &arrayZ[i]; + return nullptr; + } + + inline void qsort (int (*cmp)(const void*, const void*)) + { + ::qsort (arrayZ, len, sizeof (Type), cmp); + } + + inline void qsort (void) + { + ::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); + } + + template <typename T> + inline Type *lsearch (const T &x) + { + for (unsigned int i = 0; i < len; i++) + if (0 == this->arrayZ[i].cmp (&x)) + return &arrayZ[i]; + return nullptr; + } + + template <typename T> + inline Type *bsearch (const T &x) + { + unsigned int i; + 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; + } + template <typename T> + inline bool bfind (const T &x, unsigned int *i) const + { + int min = 0, max = (int) this->len - 1; + while (min <= max) + { + int mid = (min + max) / 2; + int c = this->arrayZ[mid].cmp (&x); + if (c < 0) + max = mid - 1; + else if (c > 0) + min = mid + 1; + else + { + *i = mid; + return true; + } + } + if (max < 0 || (max < (int) this->len && this->arrayZ[max].cmp (&x) > 0)) + max++; + *i = max; + return false; + } + + inline void fini (void) + { + if (arrayZ != static_array) + free (arrayZ); + arrayZ = nullptr; + allocated = len = 0; + } +}; + + +#endif /* HB_VECTOR_PRIVATE_HH */ commit be336dadc07460a53de51be32dd5d1f218b398b6 Author: Behdad Esfahbod <[email protected]> Date: Mon Aug 6 04:32:51 2018 -0700 Move some more code around diff --git a/src/hb-dsalgs.hh b/src/hb-dsalgs.hh index fc7d1f0a..36395db2 100644 --- a/src/hb-dsalgs.hh +++ b/src/hb-dsalgs.hh @@ -232,6 +232,18 @@ hb_ctz (T v) * Tiny stuff. */ +/* ASCII tag/character handling */ +static inline bool ISALPHA (unsigned char c) +{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } +static inline bool ISALNUM (unsigned char c) +{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); } +static inline bool ISSPACE (unsigned char c) +{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; } +static inline unsigned char TOUPPER (unsigned char c) +{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; } +static inline unsigned char TOLOWER (unsigned char c) +{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; } + #undef MIN template <typename Type> static inline Type MIN (const Type &a, const Type &b) { return a < b ? a : b; } @@ -262,6 +274,37 @@ hb_ceil_to_4 (unsigned int v) return ((v - 1) | 3) + 1; } +template <typename T> class hb_assert_unsigned_t; +template <> class hb_assert_unsigned_t<unsigned char> {}; +template <> class hb_assert_unsigned_t<unsigned short> {}; +template <> class hb_assert_unsigned_t<unsigned int> {}; +template <> class hb_assert_unsigned_t<unsigned long> {}; + +template <typename T> static inline bool +hb_in_range (T u, T lo, T hi) +{ + /* The sizeof() is here to force template instantiation. + * I'm sure there are better ways to do this but can't think of + * one right now. Declaring a variable won't work as HB_UNUSED + * is unusable on some platforms and unused types are less likely + * to generate a warning than unused variables. */ + static_assert ((sizeof (hb_assert_unsigned_t<T>) >= 0), ""); + + /* The casts below are important as if T is smaller than int, + * the subtract results will become a signed int! */ + return (T)(u - lo) <= (T)(hi - lo); +} +template <typename T> static inline bool +hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2) +{ + return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2); +} +template <typename T> static inline bool +hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) +{ + return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3); +} + /* * Sort and search. diff --git a/src/hb-private.hh b/src/hb-private.hh index d912fe33..98a21188 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -435,20 +435,6 @@ struct CrapOrNull<const Type> { #define CrapOrNull(Type) CrapOrNull<Type>::get () -/* ASCII tag/character handling */ - -static inline bool ISALPHA (unsigned char c) -{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'); } -static inline bool ISALNUM (unsigned char c) -{ return (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || (c >= '0' && c <= '9'); } -static inline bool ISSPACE (unsigned char c) -{ return c == ' ' || c =='\f'|| c =='\n'|| c =='\r'|| c =='\t'|| c =='\v'; } -static inline unsigned char TOUPPER (unsigned char c) -{ return (c >= 'a' && c <= 'z') ? c - 'a' + 'A' : c; } -static inline unsigned char TOLOWER (unsigned char c) -{ return (c >= 'A' && c <= 'Z') ? c - 'A' + 'a' : c; } - - /* HB_NDEBUG disables some sanity checks that are very safe to disable and * should be disabled in production systems. If NDEBUG is defined, enable * HB_NDEBUG; but if it's desirable that normal assert()s (which are very @@ -459,41 +445,7 @@ static inline unsigned char TOLOWER (unsigned char c) #endif -/* Misc */ - -template <typename T> class hb_assert_unsigned_t; -template <> class hb_assert_unsigned_t<unsigned char> {}; -template <> class hb_assert_unsigned_t<unsigned short> {}; -template <> class hb_assert_unsigned_t<unsigned int> {}; -template <> class hb_assert_unsigned_t<unsigned long> {}; - -template <typename T> static inline bool -hb_in_range (T u, T lo, T hi) -{ - /* The sizeof() is here to force template instantiation. - * I'm sure there are better ways to do this but can't think of - * one right now. Declaring a variable won't work as HB_UNUSED - * is unusable on some platforms and unused types are less likely - * to generate a warning than unused variables. */ - static_assert ((sizeof (hb_assert_unsigned_t<T>) >= 0), ""); - - /* The casts below are important as if T is smaller than int, - * the subtract results will become a signed int! */ - return (T)(u - lo) <= (T)(hi - lo); -} - -template <typename T> static inline bool -hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2) -{ - return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2); -} - -template <typename T> static inline bool -hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) -{ - return hb_in_range (u, lo1, hi1) || hb_in_range (u, lo2, hi2) || hb_in_range (u, lo3, hi3); -} - +/* Flags */ /* Enable bitwise ops on enums marked as flags_t */ /* To my surprise, looks like the function resolver is happy to silently cast @@ -517,7 +469,6 @@ hb_in_ranges (T u, T lo1, T hi1, T lo2, T hi2, T lo3, T hi3) static inline T& operator ^= (T& l, T r) { l = l ^ r; return l; } \ } - /* Useful for set-operations on small enums. * For example, for testing "x ∈ {x1, x2, x3}" use: * (FLAG_UNSAFE(x) & (FLAG(x1) | FLAG(x2) | FLAG(x3))) commit 92806ee055c8efb68fcbe9e1750ce2532a1f8ab3 Author: Behdad Esfahbod <[email protected]> Date: Sun Aug 5 21:41:52 2018 -0700 Move null data definitions to hb-static.cc Also remove " " null data for Tag. Just use zeroes. diff --git a/src/hb-open-type-private.hh b/src/hb-open-type-private.hh index bae2eed8..5580565f 100644 --- a/src/hb-open-type-private.hh +++ b/src/hb-open-type-private.hh @@ -140,7 +140,6 @@ struct Tag : HBUINT32 public: DEFINE_SIZE_STATIC (4); }; -DEFINE_NULL_DATA (OT, Tag, " "); /* Glyph index number, same as uint16 (length = 16 bits) */ typedef HBUINT16 GlyphID; @@ -152,7 +151,7 @@ typedef HBUINT16 NameID; struct Index : HBUINT16 { static const unsigned int NOT_FOUND_INDEX = 0xFFFFu; }; -DEFINE_NULL_DATA (OT, Index, "\xff\xff"); +DECLARE_NULL_NAMESPACE_BYTES (OT, Index); /* Offset, Null offset = 0 */ template <typename Type> diff --git a/src/hb-ot-layout-common-private.hh b/src/hb-ot-layout-common-private.hh index 2da6e315..89d5eae4 100644 --- a/src/hb-ot-layout-common-private.hh +++ b/src/hb-ot-layout-common-private.hh @@ -173,7 +173,7 @@ struct RangeRecord public: DEFINE_SIZE_STATIC (6); }; -DEFINE_NULL_DATA (OT, RangeRecord, "\000\001"); +DECLARE_NULL_NAMESPACE_BYTES (OT, RangeRecord); struct IndexArray : ArrayOf<Index> @@ -240,8 +240,7 @@ struct LangSys public: DEFINE_SIZE_ARRAY (6, featureIndex); }; -DEFINE_NULL_DATA (OT, LangSys, "\0\0\xFF\xFF"); - +DECLARE_NULL_NAMESPACE_BYTES (OT, LangSys); struct Script { diff --git a/src/hb-private.hh b/src/hb-private.hh index 32e1edff..d912fe33 100644 --- a/src/hb-private.hh +++ b/src/hb-private.hh @@ -391,16 +391,18 @@ static inline Type const & Null (void) { #define Null(Type) Null<Type>() /* Specializaiton for arbitrary-content arbitrary-sized Null objects. */ -#define DEFINE_NULL_DATA(Namespace, Type, data) \ +#define DECLARE_NULL_NAMESPACE_BYTES(Namespace, Type) \ } /* Close namespace. */ \ -static const char _Null##Type[sizeof (Namespace::Type) + 1] = data; /* +1 is for nul-termination in data */ \ +extern HB_INTERNAL const unsigned char _hb_Null_##Namespace##_##Type[sizeof (Namespace::Type)]; \ template <> \ /*static*/ inline const Namespace::Type& Null<Namespace::Type> (void) { \ - return *reinterpret_cast<const Namespace::Type *> (_Null##Type); \ + return *reinterpret_cast<const Namespace::Type *> (_hb_Null_##Namespace##_##Type); \ } \ namespace Namespace { \ -/* The following line really exists such that we end in a place needing semicolon */ \ -static_assert (Namespace::Type::min_size + 1 <= sizeof (_Null##Type), "Null pool too small. Enlarge.") +static_assert (Namespace::Type::min_size <= sizeof (Type), "Null pool too small. Enlarge."); \ + +#define DEFINE_NULL_NAMESPACE_BYTES(Namespace, Type) \ +const unsigned char _hb_Null_##Namespace##_##Type[sizeof (Namespace::Type)] /* Global writable pool. Enlarge as necessary. */ diff --git a/src/hb-static.cc b/src/hb-static.cc index bd0943f5..ddecbba1 100644 --- a/src/hb-static.cc +++ b/src/hb-static.cc @@ -25,8 +25,11 @@ */ #include "hb-private.hh" -#include "hb-face-private.hh" + #include "hb-open-type-private.hh" +#include "hb-ot-layout-common-private.hh" + +#include "hb-face-private.hh" #include "hb-ot-head-table.hh" #include "hb-ot-maxp-table.hh" @@ -35,6 +38,11 @@ hb_vector_size_impl_t const _hb_NullPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {}; /*thread_local*/ hb_vector_size_impl_t _hb_CrapPool[(HB_NULL_POOL_SIZE + sizeof (hb_vector_size_impl_t) - 1) / sizeof (hb_vector_size_impl_t)] = {}; +DEFINE_NULL_NAMESPACE_BYTES (OT, Index) = {0xFF,0xFF}; +DEFINE_NULL_NAMESPACE_BYTES (OT, LangSys) = {0x00,0x00, 0xFF,0xFF, 0x00,0x00}; +DEFINE_NULL_NAMESPACE_BYTES (OT, RangeRecord) = {0x00,0x01, 0x00,0x00, 0x00, 0x00}; + + void hb_face_t::load_num_glyphs (void) const { commit 1b4d5a2402302e90867c178b6b2ad07541091a74 Author: Behdad Esfahbod <[email protected]> Date: Fri Aug 3 19:55:09 2018 -0700 Minor diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh index b03b8252..2a74135c 100644 --- a/src/hb-ot-layout-private.hh +++ b/src/hb-ot-layout-private.hh @@ -193,10 +193,10 @@ struct hb_ot_layout_t HB_INTERNAL void fini (void); #define HB_OT_LAYOUT_TABLE_ORDER(Namespace, Type) \ - HB_PASTE (TABLE_ORDER_, HB_PASTE (Namespace, HB_PASTE (_, Type))) + HB_PASTE (ORDER_, HB_PASTE (Namespace, HB_PASTE (_, Type))) enum order_t { - TABLE_ORDER_ZERO, + ORDER_ZERO, #define HB_OT_LAYOUT_TABLE(Namespace, Type) \ HB_OT_LAYOUT_TABLE_ORDER (Namespace, Type), HB_OT_LAYOUT_TABLES commit 7df7963b46223f47e89a5a38c597c874aaa93141 Author: Behdad Esfahbod <[email protected]> Date: Fri Aug 3 19:54:33 2018 -0700 Make lazy loader deal with OOM diff --git a/src/hb-machinery-private.hh b/src/hb-machinery-private.hh index 0d2dbc3c..119625c4 100644 --- a/src/hb-machinery-private.hh +++ b/src/hb-machinery-private.hh @@ -623,7 +623,11 @@ struct hb_lazy_loader_t if (unlikely (!p)) { hb_face_t *face = *(((hb_face_t **) this) - WheresFace); - p = thiz ()->create (face); + if (likely (!p)) + p = thiz ()->create (face); + if (unlikely (!p)) + p = thiz ()->create (nullptr); /* Produce nil object. */ + assert (p); if (unlikely (!hb_atomic_ptr_cmpexch (const_cast<Stored **>(&this->instance), nullptr, p))) { thiz ()->destroy (p); _______________________________________________ HarfBuzz mailing list [email protected] https://lists.freedesktop.org/mailman/listinfo/harfbuzz
