[HarfBuzz] harfbuzz: Branch 'master' - 28 commits
Behdad Esfahbod
behdad at kemper.freedesktop.org
Tue Feb 27 18:50:41 UTC 2018
src/Makefile.sources | 2
src/hb-ot-base.h | 56 +
src/hb-ot-glyf-table.hh | 131 ++++
src/hb-ot-layout-base-table.hh | 799 +++++++++++++++++++++++++++
src/hb-ot-layout-private.hh | 2
src/hb-ot-layout.cc | 35 +
src/hb-ot-layout.h | 1
src/hb-ot.h | 1
src/hb-subset-glyf.cc | 89 ++-
src/hb-subset-input.cc | 16
src/hb-subset-plan.cc | 4
src/hb-subset-plan.hh | 2
src/hb-subset-private.hh | 1
src/hb-subset.cc | 18
src/hb-subset.h | 2
test/api/fonts/Roboto-Regular.ac.nohints.ttf |binary
test/api/hb-subset-test.h | 16
test/api/test-subset-cmap.c | 4
test/api/test-subset-glyf.c | 51 +
test/api/test-subset-hdmx.c | 4
test/api/test-subset-hmtx.c | 10
test/api/test-subset-os2.c | 2
util/hb-subset.cc | 6
util/options.cc | 15
util/options.hh | 14
25 files changed, 1231 insertions(+), 50 deletions(-)
New commits:
commit f110c0c8866c853c0d5a930564a2b69231a33322
Merge: 4a1d51ef 0ad8c663
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date: Tue Feb 27 11:41:12 2018 +0330
Merge pull request #838 from harfbuzz/BASE
BASE table
diff --cc src/hb-ot-layout.cc
index 3273ecce,e02ff115..42802e2b
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@@ -62,12 -63,10 +63,13 @@@ _hb_ot_layout_create (hb_face_t *face
layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
layout->math.init (face);
+ layout->base.init (face);
layout->fvar.init (face);
layout->avar.init (face);
+ layout->ankr.init (face);
+ layout->kerx.init (face);
layout->morx.init (face);
+ layout->trak.init (face);
{
/*
@@@ -215,12 -214,10 +217,13 @@@ _hb_ot_layout_destroy (hb_ot_layout_t *
hb_blob_destroy (layout->gpos_blob);
layout->math.fini ();
+ layout->base.fini ();
layout->fvar.fini ();
layout->avar.fini ();
+ layout->ankr.fini ();
+ layout->kerx.fini ();
layout->morx.fini ();
+ layout->trak.fini ();
free (layout);
}
commit 0ad8c663e0b4602e2a413e77a8158bf8a46755d5
Author: Ebrahim Byagowi <ebrahim at gnu.org>
Date: Mon Feb 26 12:45:08 2018 +0330
Remove public API of the branch
diff --git a/src/hb-ot-base.h b/src/hb-ot-base.h
index 9d82d228..0437c168 100644
--- a/src/hb-ot-base.h
+++ b/src/hb-ot-base.h
@@ -48,8 +48,8 @@ HB_BEGIN_DECLS
/* Methods */
-HB_EXTERN hb_bool_t
-hb_ot_base_has_data (hb_face_t *face);
+// HB_EXTERN hb_bool_t
+// hb_ot_base_has_data (hb_face_t *face);
HB_END_DECLS
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index 169a13f3..3c3d3ade 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -23,8 +23,8 @@
*
*/
-#ifndef HB_OT_BASE_TABLE_HH
-#define HB_OT_BASE_TABLE_HH
+#ifndef HB_OT_LAYOUT_BASE_TABLE_HH
+#define HB_OT_LAYOUT_BASE_TABLE_HH
#include "hb-open-type-private.hh"
#include "hb-ot-layout-common-private.hh"
@@ -312,7 +312,7 @@ struct BaseScript {
return (this+defaultMinMax).get_min_value(featureTableTagIndex);
}
if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NO_COORD;
- return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex);
+ return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex);
}
inline HBINT16 get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
@@ -401,7 +401,7 @@ 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();
}
@@ -449,7 +449,7 @@ struct BaseScriptList {
public:
DEFINE_SIZE_ARRAY (4, baseScriptRecords);
-
+
};
struct BaseTagList
@@ -487,7 +487,7 @@ struct Axis
}
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);
}
@@ -546,7 +546,7 @@ struct BASEFormat1_1
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
horizAxis.sanitize (c, this) &&
- vertAxis.sanitize (c, this) &&
+ vertAxis.sanitize (c, this) &&
itemVarStore.sanitize (c, this));
}
@@ -578,7 +578,7 @@ struct BASEFormat1_0
}
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);
}
@@ -598,7 +598,7 @@ struct BASEFormat1_0
}
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);
}
@@ -796,4 +796,4 @@ struct BASE
} /* namespace OT */
-#endif /* HB_OT_BASE_TABLE_HH */
+#endif /* HB_OT_LAYOUT_BASE_TABLE_HH */
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 3a133212..e02ff115 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -222,13 +222,13 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
free (layout);
}
-static inline const OT::BASE&
-_get_base (hb_face_t *face)
-{
- if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::BASE);
- hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
- return *(layout->base.get ());
-}
+// static inline const OT::BASE&
+// _get_base (hb_face_t *face)
+// {
+// if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::BASE);
+// hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
+// return *(layout->base.get ());
+// }
static inline const OT::GDEF&
_get_gdef (hb_face_t *face)
@@ -1283,21 +1283,19 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
* OT::BASE
*/
-#if 0
-/**
- * hb_ot_base_has_data:
- * @face: #hb_face_t to test
- *
- * This function allows to verify the presence of an OpenType BASE table on the
- * face.
- *
- * Return value: true if face has a BASE table, false otherwise
- *
- * Since: XXX
- **/
-hb_bool_t
-hb_ot_base_has_data (hb_face_t *face)
-{
- return &_get_base (face) != &OT::Null(OT::BASE);
-}
-#endif
+// /**
+// * hb_ot_base_has_data:
+// * @face: #hb_face_t to test
+// *
+// * This function allows to verify the presence of an OpenType BASE table on the
+// * face.
+// *
+// * Return value: true if face has a BASE table, false otherwise
+// *
+// * Since: XXX
+// **/
+// hb_bool_t
+// hb_ot_base_has_data (hb_face_t *face)
+// {
+// return &_get_base (face) != &OT::Null(OT::BASE);
+// }
commit 4a1d51ef15a423706406f784a146078073147885
Merge: d0caf7e5 903771b6
Author: rsheeter <rsheeter at google.com>
Date: Mon Feb 26 20:23:41 2018 -0800
Merge pull request #818 from googlefonts/drophints
[subset] Drop hints
commit 903771b6c7689b9eee9a11bac128c42f39833b2e
Author: Rod Sheeter <rsheeter at google.com>
Date: Mon Feb 26 19:50:06 2018 -0800
[subset] clearer name for trim() and better comment about composite handling, per review feedback
diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh
index 3d030977..441d4b9e 100644
--- a/src/hb-ot-glyf-table.hh
+++ b/src/hb-ot-glyf-table.hh
@@ -276,8 +276,8 @@ struct glyf
}
/* based on FontTools _g_l_y_f.py::trim */
- inline bool trim(unsigned int start_offset,
- unsigned int *end_offset) const
+ inline bool remove_padding(unsigned int start_offset,
+ unsigned int *end_offset) const
{
static const int FLAG_X_SHORT = 0x02;
static const int FLAG_Y_SHORT = 0x04;
@@ -294,7 +294,9 @@ struct glyf
int16_t num_contours = (int16_t) glyph_header.numberOfContours;
if (num_contours < 0)
- return true; /* no trimming for composites just yet */
+ /* Trimming for composites not implemented.
+ * If removing hints it falls out of that. */
+ return true;
else if (num_contours > 0)
{
unsigned int glyph_len = *end_offset - start_offset;
diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc
index a97e1b76..696a74de 100644
--- a/src/hb-subset-glyf.cc
+++ b/src/hb-subset-glyf.cc
@@ -43,12 +43,14 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
for (unsigned int i = 0; i < glyph_ids.len; i++)
{
hb_codepoint_t next_glyph = glyph_ids[i];
- *(instruction_ranges->push()) = 0;
- *(instruction_ranges->push()) = 0;
+ unsigned int *instruction_start = instruction_ranges->push();
+ unsigned int *instruction_end = instruction_ranges->push();
+ *instruction_start = 0;
+ *instruction_end = 0;
unsigned int start_offset, end_offset;
if (unlikely (!(glyf.get_offsets(next_glyph, &start_offset, &end_offset)
- && glyf.trim(start_offset, &end_offset))))
+ && glyf.remove_padding(start_offset, &end_offset))))
{
DEBUG_MSG(SUBSET, nullptr, "Invalid gid %d", next_glyph);
continue;
@@ -56,20 +58,17 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
if (end_offset - start_offset < OT::glyf::GlyphHeader::static_size)
continue; /* 0-length glyph */
- unsigned int instruction_start = 0, instruction_end = 0;
if (drop_hints)
{
if (unlikely (!glyf.get_instruction_offsets(start_offset, end_offset,
- &instruction_start, &instruction_end)))
+ instruction_start, instruction_end)))
{
DEBUG_MSG(SUBSET, nullptr, "Unable to get instruction offsets for %d", next_glyph);
return false;
}
- instruction_ranges->array[i * 2] = instruction_start;
- instruction_ranges->array[i * 2 + 1] = instruction_end;
}
- total += end_offset - start_offset - (instruction_end - instruction_start);
+ total += end_offset - start_offset - (*instruction_end - *instruction_start);
/* round2 so short loca will work */
total += total % 2;
}
@@ -156,7 +155,7 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
{
unsigned int start_offset, end_offset;
if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset)
- && glyf.trim(start_offset, &end_offset))))
+ && glyf.remove_padding(start_offset, &end_offset))))
end_offset = start_offset = 0;
unsigned int instruction_start = instruction_ranges[i * 2];
unsigned int instruction_end = instruction_ranges[i * 2 + 1];
commit 551fa2d200a06d00d054f2c8e7aad1cb4d25249b
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sun Feb 25 16:32:17 2018 -0800
[BASE] Minor
diff --git a/src/Makefile.sources b/src/Makefile.sources
index cecd6447..49685008 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -87,7 +87,6 @@ HB_OT_sources = \
hb-aat-layout-kerx-table.hh \
hb-aat-layout-trak-table.hh \
hb-aat-layout-private.hh \
- hb-ot-base.cc \
hb-ot-font.cc \
hb-ot-layout.cc \
hb-ot-layout-base-table.hh \
diff --git a/src/hb-ot-base.cc b/src/hb-ot-base.cc
deleted file mode 100644
index 27e0b208..00000000
--- a/src/hb-ot-base.cc
+++ /dev/null
@@ -1,58 +0,0 @@
-/*
- * Copyright © 2017 Elie Roux<elie.roux at telecom-bretagne.eu>
- *
- * 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.
- *
- */
-
-#include "hb-open-type-private.hh"
-
-#include "hb-ot-layout-private.hh"
-#include "hb-ot-layout-base-table.hh"
-
-static inline const OT::BASE&
-_get_base (hb_face_t *face)
-{
- if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::BASE);
- hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
- return *(layout->base.get ());
-}
-
-/*
- * OT::BASE
- */
-
-/**
- * hb_ot_base_has_data:
- * @face: #hb_face_t to test
- *
- * This function allows to verify the presence of an OpenType BASE table on the
- * face.
- *
- * Return value: true if face has a BASE table, false otherwise
- *
- * Since: XXX
- **/
-hb_bool_t
-hb_ot_base_has_data (hb_face_t *face)
-{
- return &_get_base (face) != &OT::Null(OT::BASE);
-}
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index 78018604..169a13f3 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -221,40 +221,39 @@ struct MinMax {
};
-struct BaseLangSysRecord {
-
+struct BaseLangSysRecord
+{
inline Tag get_tag(void) const
{ return baseLangSysTag; }
inline unsigned int get_feature_tag_index (Tag featureTableTag) const
- { (this+minMax).get_feature_tag_index(featureTableTag); }
+ { return (this+minMax).get_feature_tag_index(featureTableTag); }
inline HBINT16 get_min_value (unsigned int featureTableTagIndex) const
- { (this+minMax).get_min_value(featureTableTagIndex); }
+ { return (this+minMax).get_min_value(featureTableTagIndex); }
inline HBINT16 get_max_value (unsigned int featureTableTagIndex) const
- { (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
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
- minMax != Null(OffsetTo<MinMax>) &&
- minMax.sanitize (c, base));
+ minMax != Null(OffsetTo<MinMax>) &&
+ minMax.sanitize (c, base));
}
protected:
- Tag baseLangSysTag;
- OffsetTo<MinMax> minMax; // not supposed to be NULL
-
+ Tag baseLangSysTag;
+ OffsetTo<MinMax> minMax;
public:
- DEFINE_SIZE_STATIC (6);
+ DEFINE_SIZE_STATIC (6);
};
-struct BaseValues {
-
- inline const unsigned int get_default_base_tag_index (void) const
+struct BaseValues
+{
+ inline unsigned int get_default_base_tag_index (void) const
{ return defaultIndex; }
inline HBINT16 get_base_coord (unsigned int baselineTagIndex) const
@@ -272,10 +271,9 @@ struct BaseValues {
}
protected:
- Index defaultIndex;
- HBUINT16 baseCoordCount;
- OffsetArrayOf<BaseCoord> baseCoords;
-
+ Index defaultIndex;
+ HBUINT16 baseCoordCount;
+ OffsetArrayOf<BaseCoord> baseCoords;
public:
DEFINE_SIZE_ARRAY (6, baseCoords);
@@ -711,26 +709,66 @@ struct BASE
inline unsigned int get_horiz_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
{ return u.format1_0.get_horiz_lang_tag_index(baseScriptIndex, baseLangSysTag); }
- inline unsigned int get_horiz_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
- { return u.format1_0.get_horiz_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag); }
+ inline unsigned int get_horiz_feature_tag_index (unsigned int baseScriptIndex,
+ unsigned int baseLangSysIndex,
+ Tag featureTableTag) const
+ {
+ return u.format1_0.get_horiz_feature_tag_index (baseScriptIndex,
+ baseLangSysIndex,
+ featureTableTag);
+ }
- inline HBINT16 get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
- { return u.format1_0.get_horiz_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
+ inline HBINT16 get_horiz_max_value (unsigned int baseScriptIndex,
+ unsigned int baseLangSysIndex,
+ unsigned int featureTableTagIndex) const
+ {
+ return u.format1_0.get_horiz_max_value (baseScriptIndex,
+ baseLangSysIndex,
+ featureTableTagIndex);
+ }
- inline HBINT16 get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
- { return u.format1_0.get_horiz_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
+ inline HBINT16 get_horiz_min_value (unsigned int baseScriptIndex,
+ unsigned int baseLangSysIndex,
+ unsigned int featureTableTagIndex) const
+ {
+ return u.format1_0.get_horiz_min_value (baseScriptIndex,
+ baseLangSysIndex,
+ featureTableTagIndex);
+ }
- inline unsigned int get_vert_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
- { return u.format1_0.get_vert_lang_tag_index(baseScriptIndex, baseLangSysTag); }
+ inline unsigned int get_vert_lang_tag_index (unsigned int baseScriptIndex,
+ Tag baseLangSysTag) const
+ {
+ return u.format1_0.get_vert_lang_tag_index (baseScriptIndex,
+ baseLangSysTag);
+ }
- inline unsigned int get_vert_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
- { return u.format1_0.get_vert_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag); }
+ inline unsigned int get_vert_feature_tag_index (unsigned int baseScriptIndex,
+ unsigned int baseLangSysIndex,
+ Tag featureTableTag) const
+ {
+ return u.format1_0.get_vert_feature_tag_index (baseScriptIndex,
+ baseLangSysIndex,
+ featureTableTag);
+ }
- inline HBINT16 get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
- { return u.format1_0.get_vert_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
+ inline HBINT16 get_vert_max_value (unsigned int baseScriptIndex,
+ unsigned int baseLangSysIndex,
+ unsigned int featureTableTagIndex) const
+ {
+ return u.format1_0.get_vert_max_value (baseScriptIndex,
+ baseLangSysIndex,
+ featureTableTagIndex);
+ }
- inline HBINT16 get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
- { return u.format1_0.get_vert_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
+ inline HBINT16 get_vert_min_value (unsigned int baseScriptIndex,
+ unsigned int baseLangSysIndex,
+ unsigned int featureTableTagIndex) const
+ {
+ return u.format1_0.get_vert_min_value (baseScriptIndex,
+ baseLangSysIndex,
+ featureTableTagIndex);
+ }
inline bool sanitize (hb_sanitize_context_t *c) const
{
@@ -750,7 +788,6 @@ struct BASE
BASEFormat1_0 format1_0;
BASEFormat1_1 format1_1;
} u;
-
public:
DEFINE_SIZE_UNION (4, version);
};
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 68eb125d..3a133212 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -222,6 +222,14 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
free (layout);
}
+static inline const OT::BASE&
+_get_base (hb_face_t *face)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::BASE);
+ hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
+ return *(layout->base.get ());
+}
+
static inline const OT::GDEF&
_get_gdef (hb_face_t *face)
{
@@ -1267,3 +1275,29 @@ hb_ot_layout_substitute_lookup (OT::hb_ot_apply_context_t *c,
{
apply_string<GSUBProxy> (c, lookup, accel);
}
+
+
+
+
+/*
+ * OT::BASE
+ */
+
+#if 0
+/**
+ * hb_ot_base_has_data:
+ * @face: #hb_face_t to test
+ *
+ * This function allows to verify the presence of an OpenType BASE table on the
+ * face.
+ *
+ * Return value: true if face has a BASE table, false otherwise
+ *
+ * Since: XXX
+ **/
+hb_bool_t
+hb_ot_base_has_data (hb_face_t *face)
+{
+ return &_get_base (face) != &OT::Null(OT::BASE);
+}
+#endif
diff --git a/src/hb-ot-layout.h b/src/hb-ot-layout.h
index 9861f0fc..077644c5 100644
--- a/src/hb-ot-layout.h
+++ b/src/hb-ot-layout.h
@@ -38,6 +38,7 @@
HB_BEGIN_DECLS
+#define HB_OT_TAG_BASE HB_TAG('B','A','S','E')
#define HB_OT_TAG_GDEF HB_TAG('G','D','E','F')
#define HB_OT_TAG_GSUB HB_TAG('G','S','U','B')
#define HB_OT_TAG_GPOS HB_TAG('G','P','O','S')
commit 05699fd996ed9c0e5dde8918388ac188e58df1a7
Merge: 83af6c23 3ebcd5a3
Author: Behdad Esfahbod <behdad at behdad.org>
Date: Sat Feb 24 12:01:54 2018 -0800
Merge remote-tracking branch 'eroux/add-base'
diff --cc src/Makefile.sources
index 2bb56b4f,db730565..cecd6447
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@@ -76,19 -65,13 +76,21 @@@ HB_NODIST_headers =
hb-version.h \
$(NULL)
-HB_FALLBACK_sources = hb-fallback-shape.cc
+HB_FALLBACK_sources = \
+ hb-fallback-shape.cc \
+ $(NULL)
HB_OT_sources = \
+ hb-aat-layout.cc \
+ hb-aat-layout-common-private.hh \
+ hb-aat-layout-morx-table.hh \
+ hb-aat-layout-kerx-table.hh \
+ hb-aat-layout-trak-table.hh \
+ hb-aat-layout-private.hh \
+ hb-ot-base.cc \
hb-ot-font.cc \
hb-ot-layout.cc \
+ hb-ot-layout-base-table.hh \
hb-ot-layout-common-private.hh \
hb-ot-layout-gdef-table.hh \
hb-ot-layout-gpos-table.hh \
diff --cc src/hb-ot-layout-base-table.hh
index 00000000,0d1e197e..78018604
mode 000000,100644..100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@@ -1,0 -1,762 +1,762 @@@
+ /*
+ * Copyright © 2016 Elie Roux <elie.roux at telecom-bretagne.eu>
+ *
+ * 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.
+ *
+ */
+
+ #ifndef HB_OT_BASE_TABLE_HH
+ #define HB_OT_BASE_TABLE_HH
+
+ #include "hb-open-type-private.hh"
+ #include "hb-ot-layout-common-private.hh"
+ #include "hb-ot-base.h"
+
+ namespace OT {
+
-#define NO_COORD Null(SHORT)//SHORT((short int) -32767)
++#define NO_COORD Null(HBINT16)//HBINT16((short int) -32767)
+
+ #define NOT_INDEXED ((unsigned int) -1)
+
+ /*
+ * BASE -- The BASE Table
+ */
+
+ struct BaseCoordFormat1 {
+
- inline SHORT get_coord (void) const
++ inline HBINT16 get_coord (void) const
+ { return coordinate; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ protected:
- USHORT baseCoordFormat;
- SHORT coordinate;
++ HBUINT16 baseCoordFormat;
++ HBINT16 coordinate;
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+ };
+
+ struct BaseCoordFormat2 {
+
- inline SHORT get_coord (void) const
++ inline HBINT16 get_coord (void) const
+ { return coordinate; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ protected:
- USHORT baseCoordFormat;
- SHORT coordinate;
- USHORT referenceGlyph;
- USHORT baseCoordPoint;
++ HBUINT16 baseCoordFormat;
++ HBINT16 coordinate;
++ HBUINT16 referenceGlyph;
++ HBUINT16 baseCoordPoint;
+
+ public:
+ DEFINE_SIZE_STATIC (8);
+ };
+
+ struct BaseCoordFormat3 {
+
- inline SHORT get_coord (void) const
++ inline HBINT16 get_coord (void) const
+ { return coordinate; }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
+ }
+
+ protected:
- USHORT baseCoordFormat;
- SHORT coordinate;
++ HBUINT16 baseCoordFormat;
++ HBINT16 coordinate;
+ OffsetTo<Device> deviceTable;
+
+ public:
+ DEFINE_SIZE_STATIC (6);
+ };
+
+ struct BaseCoord {
+
- inline SHORT get_coord (void) const
++ inline HBINT16 get_coord (void) const
+ { return u.format1.get_coord(); }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.baseCoordFormat.sanitize (c)) return_trace (false);
+ switch (u.baseCoordFormat) {
+ case 1: return_trace (u.format1.sanitize (c));
+ case 2: return_trace (u.format2.sanitize (c));
+ case 3: return_trace (u.format3.sanitize (c));
+ default:return_trace (false);
+ }
+ }
+
+ protected:
+ union {
- USHORT baseCoordFormat;
++ HBUINT16 baseCoordFormat;
+ BaseCoordFormat1 format1;
+ BaseCoordFormat2 format2;
+ BaseCoordFormat3 format3;
+ } u;
+
+ public:
+ DEFINE_SIZE_MIN (4);
+ };
+
+ struct FeatMinMaxRecord {
+
- inline SHORT get_min_value (void) const
++ inline HBINT16 get_min_value (void) const
+ {
+ if (minCoord == Null(OffsetTo<BaseCoord>)) return NO_COORD;
+ return (this+minCoord).get_coord();
+ }
+
- inline SHORT get_max_value (void) const
++ inline HBINT16 get_max_value (void) const
+ {
+ if (minCoord == Null(OffsetTo<BaseCoord>)) return NO_COORD;
+ return (this+maxCoord).get_coord();
+ }
+
+ inline Tag get_tag () const
+ { return featureTableTag; }
+
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ minCoord.sanitize (c, base) &&
+ maxCoord.sanitize (c, base));
+ }
+
+ protected:
+ Tag featureTableTag;
+ OffsetTo<BaseCoord> minCoord;
+ OffsetTo<BaseCoord> maxCoord;
+
+ public:
+ DEFINE_SIZE_STATIC (8);
+
+ };
+
+ struct MinMax {
+
+ inline unsigned int get_feature_tag_index (Tag featureTableTag) const
+ {
+ Tag tag;
+ int cmp;
+ // taking advantage of alphabetical order
+ for (unsigned int i = 0; i < featMinMaxCount; i++) {
+ tag = featMinMaxRecords[i].get_tag();
+ cmp = tag.cmp(featureTableTag);
+ if (cmp == 0) return i;
+ if (cmp > 0) return NOT_INDEXED;
+ }
+ return NOT_INDEXED;
+ }
+
- inline SHORT get_min_value (unsigned int featureTableTagIndex) const
++ inline HBINT16 get_min_value (unsigned int featureTableTagIndex) const
+ {
+ if (featureTableTagIndex == NOT_INDEXED) {
+ if (minCoord == Null(OffsetTo<BaseCoord>)) return NO_COORD;
+ return (this+minCoord).get_coord();
+ }
+ if (unlikely(featureTableTagIndex >= featMinMaxCount)) return NO_COORD;
+ return featMinMaxRecords[featureTableTagIndex].get_min_value();
+ }
+
- inline SHORT get_max_value (unsigned int featureTableTagIndex) const
++ inline HBINT16 get_max_value (unsigned int featureTableTagIndex) const
+ {
+ if (featureTableTagIndex == NOT_INDEXED) {
+ if (minCoord == Null(OffsetTo<BaseCoord>)) return NO_COORD;
+ return (this+maxCoord).get_coord();
+ }
+ if (unlikely(featureTableTagIndex >= featMinMaxCount)) return NO_COORD;
+ return featMinMaxRecords[featureTableTagIndex].get_max_value();
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ minCoord.sanitize (c, this) &&
+ maxCoord.sanitize (c, this) &&
+ featMinMaxRecords.sanitize (c, this));
+ // TODO: test alphabetical order?
+ }
+
+ protected:
+ OffsetTo<BaseCoord> minCoord;
+ OffsetTo<BaseCoord> maxCoord;
- USHORT featMinMaxCount;
++ HBUINT16 featMinMaxCount;
+ ArrayOf<FeatMinMaxRecord> featMinMaxRecords;
+
+ public:
+ DEFINE_SIZE_ARRAY (8, featMinMaxRecords);
+
+ };
+
+ struct BaseLangSysRecord {
+
+ inline Tag get_tag(void) const
+ { return baseLangSysTag; }
+
+ inline unsigned int get_feature_tag_index (Tag featureTableTag) const
+ { (this+minMax).get_feature_tag_index(featureTableTag); }
+
- inline SHORT get_min_value (unsigned int featureTableTagIndex) const
++ inline HBINT16 get_min_value (unsigned int featureTableTagIndex) const
+ { (this+minMax).get_min_value(featureTableTagIndex); }
+
- inline SHORT get_max_value (unsigned int featureTableTagIndex) const
++ inline HBINT16 get_max_value (unsigned int featureTableTagIndex) const
+ { (this+minMax).get_max_value(featureTableTagIndex); }
+
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ minMax != Null(OffsetTo<MinMax>) &&
+ minMax.sanitize (c, base));
+ }
+
+ protected:
+ Tag baseLangSysTag;
+ OffsetTo<MinMax> minMax; // not supposed to be NULL
+
+ public:
+ DEFINE_SIZE_STATIC (6);
+
+ };
+
+ struct BaseValues {
+
+ inline const unsigned int get_default_base_tag_index (void) const
+ { return defaultIndex; }
+
- inline SHORT get_base_coord (unsigned int baselineTagIndex) const
++ inline HBINT16 get_base_coord (unsigned int baselineTagIndex) const
+ {
+ if (unlikely(baselineTagIndex >= baseCoordCount)) return NO_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));
+ }
+
+ protected:
+ Index defaultIndex;
- USHORT baseCoordCount;
++ HBUINT16 baseCoordCount;
+ OffsetArrayOf<BaseCoord> baseCoords;
+
+ public:
+ DEFINE_SIZE_ARRAY (6, baseCoords);
+
+ };
+
+ struct BaseScript {
+
+ inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const
+ {
+ Tag tag;
+ int cmp;
+ for (unsigned int i = 0; i < baseLangSysCount; i++) {
+ tag = baseLangSysRecords[i].get_tag();
+ // taking advantage of alphabetical order
+ cmp = tag.cmp(baseLangSysTag);
+ if (cmp == 0) return i;
+ if (cmp > 0) return NOT_INDEXED;
+ }
+ return NOT_INDEXED;
+ }
+
+ inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const
+ {
+ if (baseLangSysIndex == NOT_INDEXED) {
+ if (unlikely(defaultMinMax)) return NOT_INDEXED;
+ return (this+defaultMinMax).get_feature_tag_index(featureTableTag);
+ }
+ if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NOT_INDEXED;
+ return baseLangSysRecords[baseLangSysIndex].get_feature_tag_index(featureTableTag);
+ }
+
- inline SHORT get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (baseLangSysIndex == NOT_INDEXED) {
+ if (unlikely(defaultMinMax == Null(OffsetTo<MinMax>))) return NO_COORD;
+ return (this+defaultMinMax).get_min_value(featureTableTagIndex);
+ }
+ if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NO_COORD;
+ return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex);
+ }
+
- inline SHORT get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (baseLangSysIndex == NOT_INDEXED) {
+ if (unlikely(defaultMinMax == Null(OffsetTo<MinMax>))) return NO_COORD;
+ return (this+defaultMinMax).get_min_value(featureTableTagIndex);
+ }
+ if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NO_COORD;
+ 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(); }
+
- inline SHORT get_base_coord (unsigned int baselineTagIndex) const
++ inline HBINT16 get_base_coord (unsigned int baselineTagIndex) const
+ { 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));
+ }
+
+ protected:
+ OffsetTo<BaseValues> baseValues;
+ OffsetTo<MinMax> defaultMinMax;
- USHORT baseLangSysCount;
++ HBUINT16 baseLangSysCount;
+ ArrayOf<BaseLangSysRecord> baseLangSysRecords;
+
+ public:
+ DEFINE_SIZE_ARRAY (8, baseLangSysRecords);
+ };
+
+
+ struct BaseScriptRecord {
+
+ inline bool get_tag (void) const
+ { return baseScriptTag; }
+
+ inline unsigned int get_default_base_tag_index(void) const
+ { return (this+baseScript).get_default_base_tag_index(); }
+
- inline SHORT get_base_coord(unsigned int baselineTagIndex) const
++ inline HBINT16 get_base_coord(unsigned int baselineTagIndex) const
+ { 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); }
+
+ inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const
+ { return (this+baseScript).get_feature_tag_index(baseLangSysIndex, featureTableTag); }
+
- inline SHORT get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ { return (this+baseScript).get_max_value(baseLangSysIndex, featureTableTagIndex); }
+
- inline SHORT get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ { 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));
+ }
+
+ protected:
+ Tag baseScriptTag;
+ OffsetTo<BaseScript> baseScript;
+
+ public:
+ DEFINE_SIZE_STATIC (6);
+ };
+
+ struct BaseScriptList {
+
+ inline unsigned int get_base_script_index (Tag baseScriptTag) const
+ {
+ for (unsigned int i = 0; i < baseScriptCount; i++)
+ if (baseScriptRecords[i].get_tag() == baseScriptTag)
+ return i;
+ return NOT_INDEXED;
+ }
+
+ 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();
+ }
+
- inline SHORT get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
++ inline HBINT16 get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+ {
+ if (unlikely(baseScriptIndex >= baseScriptCount)) return NO_COORD;
+ return baseScriptRecords[baseScriptIndex].get_base_coord(baselineTagIndex);
+ }
+
+ 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);
+ }
+
- inline SHORT get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(baseScriptIndex >= baseScriptCount)) return NO_COORD;
+ return baseScriptRecords[baseScriptIndex].get_max_value(baseLangSysIndex, featureTableTagIndex);
+ }
+
- inline SHORT get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(baseScriptIndex >= baseScriptCount)) return NO_COORD;
+ return baseScriptRecords[baseScriptIndex].get_min_value(baseLangSysIndex, featureTableTagIndex);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ baseScriptRecords.sanitize (c, this));
+ }
+
+ protected:
- USHORT baseScriptCount;
++ HBUINT16 baseScriptCount;
+ ArrayOf<BaseScriptRecord> baseScriptRecords;
+
+ public:
+ DEFINE_SIZE_ARRAY (4, baseScriptRecords);
+
+ };
+
+ struct BaseTagList
+ {
+
+ inline unsigned int get_tag_index(Tag baselineTag) const
+ {
+ for (unsigned int i = 0; i < baseTagCount; i++)
+ if (baselineTags[i] == baselineTag)
+ return i;
+ return NOT_INDEXED;
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
+ protected:
- USHORT baseTagCount;
++ HBUINT16 baseTagCount;
+ SortedArrayOf<Tag> baselineTags;
+
+ public:
+ DEFINE_SIZE_ARRAY (4, baselineTags);
+ };
+
+ struct Axis
+ {
+
+ 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 SHORT get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
++ inline HBINT16 get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+ {
+ if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NO_COORD;
+ 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);
+ }
+
- inline SHORT get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NO_COORD;
+ return (this+baseScriptList).get_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+ }
+
- inline SHORT get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NO_COORD;
+ return (this+baseScriptList).get_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ baseTagList.sanitize (c, this) &&
+ baseScriptList.sanitize (c, this));
+ }
+
+ protected:
+ OffsetTo<BaseTagList> baseTagList;
+ OffsetTo<BaseScriptList> baseScriptList;
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+ };
+
+ struct BASEFormat1_1
+ {
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ horizAxis.sanitize (c, this) &&
+ vertAxis.sanitize (c, this) &&
+ itemVarStore.sanitize (c, this));
+ }
+
+ protected:
+ FixedVersion<> version;
+ OffsetTo<Axis> horizAxis;
+ OffsetTo<Axis> vertAxis;
+ LOffsetTo<VariationStore> itemVarStore;
+
+ public:
+ DEFINE_SIZE_STATIC (12);
+ };
+
+ struct BASEFormat1_0
+ {
+
+ inline bool has_vert_axis(void)
+ { return vertAxis != Null(OffsetTo<Axis>); }
+
+ inline bool has_horiz_axis(void)
+ { return horizAxis != Null(OffsetTo<Axis>); }
+
+ // horizontal axis base coords:
+
+ 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);
+ }
+
- inline SHORT get_horiz_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
++ inline HBINT16 get_horiz_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+ {
+ if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NO_COORD;
+ 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);
+ }
+
- inline SHORT get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
++ inline HBINT16 get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+ {
+ if (vertAxis == Null(OffsetTo<Axis>)) return NO_COORD;
+ 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);
+ }
+
- inline SHORT get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NO_COORD;
+ return (this+horizAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+ }
+
- inline SHORT get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NO_COORD;
+ 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);
+ }
+
- inline SHORT get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NO_COORD;
+ return (this+vertAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+ }
+
- inline SHORT get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NO_COORD;
+ return (this+vertAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+ }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ horizAxis.sanitize (c, this) &&
+ vertAxis.sanitize (c, this));
+ }
+
+ protected:
+ FixedVersion<> version;
+ OffsetTo<Axis> horizAxis;
+ OffsetTo<Axis> vertAxis;
+
+ public:
+ DEFINE_SIZE_STATIC (8);
+ };
+
+ struct BASE
+ {
+ static const hb_tag_t tableTag = HB_OT_TAG_BASE;
+
+ inline bool has_vert_axis(void)
+ { return u.format1_0.has_vert_axis(); }
+
+ inline bool has_horiz_axis(void)
+ { return u.format1_0.has_horiz_axis(); }
+
+ inline unsigned int get_horiz_base_tag_index(Tag baselineTag) const
+ { return u.format1_0.get_horiz_base_tag_index(baselineTag); }
+
+ inline unsigned int get_horiz_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
+ { return u.format1_0.get_horiz_default_base_tag_index_for_script_index(baseScriptIndex); }
+
- inline SHORT get_horiz_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
++ inline HBINT16 get_horiz_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+ { return u.format1_0.get_horiz_base_coord(baseScriptIndex, baselineTagIndex); }
+
+ inline unsigned int get_vert_base_tag_index(Tag baselineTag) const
+ { return u.format1_0.get_vert_base_tag_index(baselineTag); }
+
+ inline unsigned int get_vert_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
+ { return u.format1_0.get_vert_default_base_tag_index_for_script_index(baseScriptIndex); }
+
- inline SHORT get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
++ inline HBINT16 get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+ { return u.format1_0.get_vert_base_coord(baseScriptIndex, baselineTagIndex); }
+
+ inline unsigned int get_horiz_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
+ { return u.format1_0.get_horiz_lang_tag_index(baseScriptIndex, baseLangSysTag); }
+
+ inline unsigned int get_horiz_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
+ { return u.format1_0.get_horiz_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag); }
+
- inline SHORT get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ { return u.format1_0.get_horiz_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
+
- inline SHORT get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ { return u.format1_0.get_horiz_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
+
+ inline unsigned int get_vert_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
+ { return u.format1_0.get_vert_lang_tag_index(baseScriptIndex, baseLangSysTag); }
+
+ inline unsigned int get_vert_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
+ { return u.format1_0.get_vert_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag); }
+
- inline SHORT get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ { return u.format1_0.get_vert_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
+
- inline SHORT get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
++ inline HBINT16 get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ { return u.format1_0.get_vert_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.version.sanitize (c)) return_trace (false);
+ if (!likely(u.version.major == 1)) return_trace (false);
+ switch (u.version.minor) {
+ case 0: return_trace (u.format1_0.sanitize (c));
+ case 1: return_trace (u.format1_1.sanitize (c));
+ default:return_trace (false);
+ }
+ }
+
+ protected:
+ union {
+ FixedVersion<> version; /* Version of the BASE table: 1.0 or 1.1 */
+ BASEFormat1_0 format1_0;
+ BASEFormat1_1 format1_1;
+ } u;
+
+ public:
+ DEFINE_SIZE_UNION (4, version);
+ };
+
+
+ } /* namespace OT */
+
+
+ #endif /* HB_OT_BASE_TABLE_HH */
diff --cc src/hb-ot-layout.cc
index 4cf6c722,d393f5ca..68eb125d
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@@ -62,9 -57,9 +63,10 @@@ _hb_ot_layout_create (hb_face_t *face
layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
layout->math.init (face);
+ layout->base.init (face);
layout->fvar.init (face);
layout->avar.init (face);
+ layout->morx.init (face);
{
/*
@@@ -212,9 -186,9 +214,10 @@@ _hb_ot_layout_destroy (hb_ot_layout_t *
hb_blob_destroy (layout->gpos_blob);
layout->math.fini ();
+ layout->base.fini ();
layout->fvar.fini ();
layout->avar.fini ();
+ layout->morx.fini ();
free (layout);
}
commit 5267520e078ed413df78f3a6781fd5370b6da63a
Author: Rod Sheeter <rsheeter at google.com>
Date: Fri Feb 23 18:36:22 2018 -0800
[subset] update hdmx test to create input explicitly
diff --git a/test/api/test-subset-hdmx.c b/test/api/test-subset-hdmx.c
index 291eb793..5211dbc4 100644
--- a/test/api/test-subset-hdmx.c
+++ b/test/api/test-subset-hdmx.c
@@ -41,7 +41,7 @@ test_subset_hdmx_simple_subset (void)
hb_set_t *codepoints = hb_set_create ();
hb_set_add (codepoints, 'a');
hb_set_add (codepoints, 'c');
- hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints);
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('h','d','m','x'));
@@ -60,7 +60,7 @@ test_subset_hdmx_noop (void)
hb_set_add (codepoints, 'a');
hb_set_add (codepoints, 'b');
hb_set_add (codepoints, 'c');
- hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints);
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('h','d','m','x'));
commit 2e3ee489f8374227fa94a8d8684e839e643888ea
Author: Rod Sheeter <rsheeter at google.com>
Date: Fri Feb 23 18:18:54 2018 -0800
[subset] format tweak, doc string
diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc
index 69aa9d61..c4003dd3 100644
--- a/src/hb-subset-input.cc
+++ b/src/hb-subset-input.cc
@@ -53,9 +53,9 @@ hb_subset_input_create_or_fail (void)
* hb_subset_input_reference: (skip)
* @subset_input: a subset_input.
*
- *
*
- * Return value:
+ *
+ * Return value:
*
* Since: 1.8.0
**/
@@ -106,8 +106,14 @@ hb_subset_input_glyph_set (hb_subset_input_t *subset_input)
return subset_input->glyphs;
}
+/**
+ * hb_subset_input_drop_hints:
+ * @subset_input: a subset_input.
+ *
+ * Since: 1.8.0
+ **/
HB_EXTERN hb_bool_t *
-hb_subset_input_drop_hints(hb_subset_input_t *subset_input)
+hb_subset_input_drop_hints (hb_subset_input_t *subset_input)
{
return &subset_input->drop_hints;
}
diff --git a/src/hb-subset.h b/src/hb-subset.h
index 1af7cba5..55ce25b0 100644
--- a/src/hb-subset.h
+++ b/src/hb-subset.h
@@ -69,7 +69,7 @@ HB_EXTERN hb_set_t *
hb_subset_input_glyph_set (hb_subset_input_t *subset_input);
HB_EXTERN hb_bool_t *
-hb_subset_input_drop_hints(hb_subset_input_t *subset_input);
+hb_subset_input_drop_hints (hb_subset_input_t *subset_input);
/* hb_subset() */
commit d78393b5547135b8db0356b0ec14d5ed0d334768
Merge: 1454d82a 83af6c23
Author: Rod Sheeter <rsheeter at google.com>
Date: Fri Feb 23 17:53:26 2018 -0800
Merge branch 'master' of https://github.com/harfbuzz/harfbuzz into drophints
diff --cc src/hb-subset.cc
index c708e193,12cdb1d2..cba05176
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@@ -229,9 -238,11 +238,12 @@@ _subset_table (hb_subset_plan_t *plan
case HB_OT_TAG_glyf:
result = _subset<const OT::glyf> (plan);
break;
+ case HB_OT_TAG_hdmx:
+ result = _subset<const OT::hdmx> (plan);
+ break;
case HB_OT_TAG_head:
- // SKIP head, it's handled by glyf
+ // TODO that won't work well if there is no glyf
+ DEBUG_MSG(SUBSET, nullptr, "skip head, handled by glyf");
result = true;
break;
case HB_OT_TAG_hhea:
commit 1454d82a9d3d9a47901b3d92ff7f2c05c596c0d5
Author: Rod Sheeter <rsheeter at google.com>
Date: Fri Feb 23 17:49:23 2018 -0800
[subset] keep glyph trim separate of more general get_offset
diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh
index c92f63f4..3d030977 100644
--- a/src/hb-ot-glyf-table.hh
+++ b/src/hb-ot-glyf-table.hh
@@ -267,7 +267,7 @@ struct glyf
CompositeGlyphHeader::Iterator *composite /* OUT */) const
{
unsigned int start_offset, end_offset;
- if (!get_offsets (glyph, /* trim */ false, &start_offset, &end_offset))
+ if (!get_offsets (glyph, &start_offset, &end_offset))
return false; /* glyph not found */
return CompositeGlyphHeader::get_iterator ((const char*) this->glyf_table + start_offset,
@@ -276,8 +276,8 @@ struct glyf
}
/* based on FontTools _g_l_y_f.py::trim */
- inline bool trim_glyph(unsigned int start_offset,
- unsigned int *end_offset) const
+ inline bool trim(unsigned int start_offset,
+ unsigned int *end_offset) const
{
static const int FLAG_X_SHORT = 0x02;
static const int FLAG_Y_SHORT = 0x04;
@@ -359,7 +359,6 @@ struct glyf
}
inline bool get_offsets (hb_codepoint_t glyph,
- bool trim,
unsigned int *start_offset /* OUT */,
unsigned int *end_offset /* OUT */) const
{
@@ -383,9 +382,6 @@ struct glyf
if (*start_offset > *end_offset || *end_offset > glyf_len)
return false;
- if (trim)
- return trim_glyph(*start_offset, end_offset);
-
return true;
}
@@ -438,7 +434,7 @@ struct glyf
hb_glyph_extents_t *extents) const
{
unsigned int start_offset, end_offset;
- if (!get_offsets (glyph, /* trim */ false, &start_offset, &end_offset))
+ if (!get_offsets (glyph, &start_offset, &end_offset))
return false;
if (end_offset - start_offset < GlyphHeader::static_size)
diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc
index ce7c99fe..654566af 100644
--- a/src/hb-subset-glyf.cc
+++ b/src/hb-subset-glyf.cc
@@ -47,7 +47,8 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
*(instruction_ranges->push()) = 0;
unsigned int start_offset, end_offset;
- if (unlikely (!glyf.get_offsets(next_glyph, /* trim */ true, &start_offset, &end_offset)))
+ if (unlikely (!(glyf.get_offsets(next_glyph, &start_offset, &end_offset)
+ && glyf.trim(start_offset, &end_offset))))
{
DEBUG_MSG(SUBSET, nullptr, "Invalid gid %d", next_glyph);
continue;
@@ -154,7 +155,8 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
for (unsigned int i = 0; i < glyph_ids.len; i++)
{
unsigned int start_offset, end_offset;
- if (unlikely (!glyf.get_offsets (glyph_ids[i], /* trim */ true, &start_offset, &end_offset)))
+ if (unlikely (!(glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset)
+ && glyf.trim(start_offset, &end_offset))))
end_offset = start_offset = 0;
unsigned int instruction_start = instruction_ranges[i * 2];
unsigned int instruction_end = instruction_ranges[i * 2 + 1];
commit 0ac8c0c1e6a6c076ce33b16baa173ff8763ac04e
Author: Rod Sheeter <rsheeter at google.com>
Date: Fri Feb 23 17:43:00 2018 -0800
[subset] zero glyf and loca memory before writing so pads are clean. Test just the part of maxp we care about
diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh
index 4b938017..c92f63f4 100644
--- a/src/hb-ot-glyf-table.hh
+++ b/src/hb-ot-glyf-table.hh
@@ -286,7 +286,7 @@ struct glyf
static const int FLAG_Y_SAME = 0x20;
if (*end_offset - start_offset < GlyphHeader::static_size)
- return false;
+ return true;
const char *glyph = ((const char *) glyf_table) + start_offset;
const char * const glyph_end = glyph + (*end_offset - start_offset);
@@ -313,7 +313,7 @@ struct glyf
while (glyph < glyph_end)
{
uint8_t flag = (uint8_t) *glyph;
- glyph++; i++;
+ glyph++;
unsigned int repeat = 1;
if (flag & FLAG_REPEAT)
@@ -324,7 +324,7 @@ struct glyf
return false;
}
repeat = ((uint8_t) *glyph) + 1;
- glyph++; i++;
+ glyph++;
}
unsigned int xBytes, yBytes;
diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc
index 052af3f4..ce7c99fe 100644
--- a/src/hb-subset-glyf.cc
+++ b/src/hb-subset-glyf.cc
@@ -230,8 +230,8 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf,
return false;
}
- char *glyf_prime_data = (char *) malloc (glyf_prime_size);
- char *loca_prime_data = (char *) malloc (loca_prime_size);
+ char *glyf_prime_data = (char *) calloc (1, glyf_prime_size);
+ char *loca_prime_data = (char *) calloc (1, loca_prime_size);
if (unlikely (!_write_glyf_and_loca_prime (plan, glyf, glyf_data,
*use_short_loca,
instruction_ranges,
diff --git a/test/api/test-subset-glyf.c b/test/api/test-subset-glyf.c
index 2f266d07..f5fdf32d 100644
--- a/test/api/test-subset-glyf.c
+++ b/test/api/test-subset-glyf.c
@@ -31,6 +31,18 @@
/* Unit tests for hb-subset-glyf.h */
+static void check_maxp_num_glyphs (hb_face_t *face, uint16_t expected_num_glyphs)
+{
+ hb_blob_t *maxp_blob = hb_face_reference_table (face, HB_TAG ('m','a','x', 'p'));
+
+ unsigned int maxp_len;
+ uint8_t *raw_maxp = (uint8_t *) hb_blob_get_data(maxp_blob, &maxp_len);
+ uint16_t num_glyphs = (raw_maxp[4] << 8) + raw_maxp[5];
+ g_assert_cmpuint(expected_num_glyphs, ==, num_glyphs);
+
+ hb_blob_destroy (maxp_blob);
+}
+
static void
test_subset_glyf (void)
{
@@ -45,7 +57,7 @@ test_subset_glyf (void)
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
- hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('m','a','x', 'p'));
+ check_maxp_num_glyphs(face_abc_subset, 3);
hb_face_destroy (face_abc_subset);
hb_face_destroy (face_abc);
@@ -65,7 +77,7 @@ test_subset_glyf_with_components (void)
hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('g','l','y','f'));
hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('l','o','c', 'a'));
- hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('m','a','x', 'p'));
+ check_maxp_num_glyphs(face_generated_subset, 4);
hb_face_destroy (face_generated_subset);
hb_face_destroy (face_subset);
@@ -86,6 +98,7 @@ test_subset_glyf_noop (void)
hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('g','l','y','f'));
hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('l','o','c', 'a'));
+ check_maxp_num_glyphs(face_abc_subset, 4);
hb_face_destroy (face_abc_subset);
hb_face_destroy (face_abc);
@@ -107,7 +120,7 @@ test_subset_glyf_strip_hints (void)
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
- hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('m','a','x', 'p'));
+ check_maxp_num_glyphs(face_abc_subset, 3);
hb_face_destroy (face_abc_subset);
hb_face_destroy (face_abc);
commit 9bd6d25254d9bfc612004982dba286a3751d1d29
Author: Rod Sheeter <rsheeter at google.com>
Date: Fri Feb 23 13:05:58 2018 -0800
[subset] clone trim logic from fonttools glyf handling
diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh
index 667dfb52..4b938017 100644
--- a/src/hb-ot-glyf-table.hh
+++ b/src/hb-ot-glyf-table.hh
@@ -267,7 +267,7 @@ struct glyf
CompositeGlyphHeader::Iterator *composite /* OUT */) const
{
unsigned int start_offset, end_offset;
- if (!get_offsets (glyph, &start_offset, &end_offset))
+ if (!get_offsets (glyph, /* trim */ false, &start_offset, &end_offset))
return false; /* glyph not found */
return CompositeGlyphHeader::get_iterator ((const char*) this->glyf_table + start_offset,
@@ -275,7 +275,91 @@ struct glyf
composite);
}
+ /* based on FontTools _g_l_y_f.py::trim */
+ inline bool trim_glyph(unsigned int start_offset,
+ unsigned int *end_offset) const
+ {
+ static const int FLAG_X_SHORT = 0x02;
+ static const int FLAG_Y_SHORT = 0x04;
+ static const int FLAG_REPEAT = 0x08;
+ static const int FLAG_X_SAME = 0x10;
+ static const int FLAG_Y_SAME = 0x20;
+
+ if (*end_offset - start_offset < GlyphHeader::static_size)
+ return false;
+
+ const char *glyph = ((const char *) glyf_table) + start_offset;
+ const char * const glyph_end = glyph + (*end_offset - start_offset);
+ const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyph, 0);
+ int16_t num_contours = (int16_t) glyph_header.numberOfContours;
+
+ if (num_contours < 0)
+ return true; /* no trimming for composites just yet */
+ else if (num_contours > 0)
+ {
+ unsigned int glyph_len = *end_offset - start_offset;
+ /* simple glyph w/contours, possibly trimmable */
+ glyph += GlyphHeader::static_size + 2 * num_contours;
+
+ if (unlikely (glyph + 2 >= glyph_end)) return false;
+ uint16_t nCoordinates = (uint16_t) StructAtOffset<HBUINT16>(glyph - 2, 0) + 1;
+ uint16_t nInstructions = (uint16_t) StructAtOffset<HBUINT16>(glyph, 0);
+
+ glyph += 2 + nInstructions;
+ if (unlikely (glyph + 2 >= glyph_end)) return false;
+
+ unsigned int coordBytes = 0;
+ unsigned int coordsWithFlags = 0;
+ while (glyph < glyph_end)
+ {
+ uint8_t flag = (uint8_t) *glyph;
+ glyph++; i++;
+
+ unsigned int repeat = 1;
+ if (flag & FLAG_REPEAT)
+ {
+ if (glyph >= glyph_end)
+ {
+ DEBUG_MSG(SUBSET, nullptr, "Bad flag");
+ return false;
+ }
+ repeat = ((uint8_t) *glyph) + 1;
+ glyph++; i++;
+ }
+
+ unsigned int xBytes, yBytes;
+ xBytes = yBytes = 0;
+ if (flag & FLAG_X_SHORT)
+ xBytes = 1;
+ else if ((flag & FLAG_X_SAME) == 0)
+ xBytes = 2;
+
+ if (flag & FLAG_Y_SHORT)
+ yBytes = 1;
+ else if ((flag & FLAG_Y_SAME) == 0)
+ yBytes = 2;
+
+ coordBytes += (xBytes + yBytes) * repeat;
+ coordsWithFlags += repeat;
+ if (coordsWithFlags >= nCoordinates)
+ break;
+ }
+
+ if (coordsWithFlags != nCoordinates)
+ {
+ DEBUG_MSG(SUBSET, nullptr, "Expect %d coords to have flags, got flags for %d", nCoordinates, coordsWithFlags);
+ return false;
+ }
+ glyph += coordBytes;
+
+ if (glyph < glyph_end)
+ *end_offset -= glyph_end - glyph;
+ }
+ return true;
+ }
+
inline bool get_offsets (hb_codepoint_t glyph,
+ bool trim,
unsigned int *start_offset /* OUT */,
unsigned int *end_offset /* OUT */) const
{
@@ -291,6 +375,7 @@ struct glyf
else
{
const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataX;
+
*start_offset = offsets[glyph];
*end_offset = offsets[glyph + 1];
}
@@ -298,6 +383,9 @@ struct glyf
if (*start_offset > *end_offset || *end_offset > glyf_len)
return false;
+ if (trim)
+ return trim_glyph(*start_offset, end_offset);
+
return true;
}
@@ -350,7 +438,7 @@ struct glyf
hb_glyph_extents_t *extents) const
{
unsigned int start_offset, end_offset;
- if (!get_offsets (glyph, &start_offset, &end_offset))
+ if (!get_offsets (glyph, /* trim */ false, &start_offset, &end_offset))
return false;
if (end_offset - start_offset < GlyphHeader::static_size)
diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc
index 867810fb..052af3f4 100644
--- a/src/hb-subset-glyf.cc
+++ b/src/hb-subset-glyf.cc
@@ -43,12 +43,18 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
for (unsigned int i = 0; i < glyph_ids.len; i++)
{
hb_codepoint_t next_glyph = glyph_ids[i];
+ *(instruction_ranges->push()) = 0;
+ *(instruction_ranges->push()) = 0;
+
unsigned int start_offset, end_offset;
- if (unlikely (!glyf.get_offsets(next_glyph, &start_offset, &end_offset)))
+ if (unlikely (!glyf.get_offsets(next_glyph, /* trim */ true, &start_offset, &end_offset)))
{
DEBUG_MSG(SUBSET, nullptr, "Invalid gid %d", next_glyph);
continue;
}
+ if (end_offset - start_offset < OT::glyf::GlyphHeader::static_size)
+ continue; /* 0-length glyph */
+
unsigned int instruction_start = 0, instruction_end = 0;
if (drop_hints)
{
@@ -58,12 +64,13 @@ _calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
DEBUG_MSG(SUBSET, nullptr, "Unable to get instruction offsets for %d", next_glyph);
return false;
}
+ instruction_ranges->array[i * 2] = instruction_start;
+ instruction_ranges->array[i * 2 + 1] = instruction_end;
}
- *(instruction_ranges->push()) = instruction_start;
- *(instruction_ranges->push()) = instruction_end;
total += end_offset - start_offset - (instruction_end - instruction_start);
- fprintf(stderr, " %d ends at %d (was %d to %d, remove %d)\n", next_glyph, total, start_offset, end_offset, instruction_end - instruction_start);
+ /* round2 so short loca will work */
+ total += total % 2;
}
*glyf_size = total;
@@ -147,12 +154,13 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
for (unsigned int i = 0; i < glyph_ids.len; i++)
{
unsigned int start_offset, end_offset;
- if (unlikely (!glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset)))
+ if (unlikely (!glyf.get_offsets (glyph_ids[i], /* trim */ true, &start_offset, &end_offset)))
end_offset = start_offset = 0;
unsigned int instruction_start = instruction_ranges[i * 2];
unsigned int instruction_end = instruction_ranges[i * 2 + 1];
int length = end_offset - start_offset - (instruction_end - instruction_start);
+ length += length % 2;
if (glyf_prime_data_next + length > glyf_prime_data + glyf_prime_size)
{
@@ -164,21 +172,17 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
}
if (instruction_start == instruction_end)
- {
- fprintf(stderr, "i=%d copy %d bytes from %d to %ld\n", i, length, start_offset, glyf_prime_data_next - glyf_prime_data);
memcpy (glyf_prime_data_next, glyf_data + start_offset, length);
- }
else
{
- fprintf(stderr, "i=%d copy %d bytes from %d to %ld\n", i, instruction_start - start_offset, start_offset, glyf_prime_data_next - glyf_prime_data);
- fprintf(stderr, "i=%d copy %d bytes from %d to %ld\n", i, end_offset - instruction_end, instruction_end, glyf_prime_data_next + instruction_start - start_offset - glyf_prime_data);
memcpy (glyf_prime_data_next, glyf_data + start_offset, instruction_start - start_offset);
memcpy (glyf_prime_data_next + instruction_start - start_offset, glyf_data + instruction_end, end_offset - instruction_end);
/* if the instructions end at the end this was a composite glyph */
if (instruction_end == end_offset)
; // TODO(rsheeter) remove WE_HAVE_INSTRUCTIONS from last flags
else
- ; // TODO(rsheeter) zero instructionLength
+ /* zero instruction length, which is just before instruction_start */
+ memset (glyf_prime_data_next + instruction_start - start_offset - 2, 0, 2);
}
success = success && _write_loca_entry (i,
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index 0f653ff3..8dfa660d 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -79,6 +79,9 @@ hb_subset_plan_add_table (hb_subset_plan_t *plan,
hb_tag_t tag,
hb_blob_t *contents)
{
+ hb_blob_t *source_blob = plan->source->reference_table (tag);
+ DEBUG_MSG(SUBSET, nullptr, "add table %c%c%c%c, dest %d bytes, source %d bytes", HB_UNTAG(tag), hb_blob_get_length (contents), hb_blob_get_length (source_blob));
+ hb_blob_destroy (source_blob);
return hb_subset_face_add_table(plan->dest, tag, contents);
}
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index b46b07fc..c708e193 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -230,11 +230,12 @@ _subset_table (hb_subset_plan_t *plan,
result = _subset<const OT::glyf> (plan);
break;
case HB_OT_TAG_head:
- // SKIP head, it's handled by glyf
+ // TODO that won't work well if there is no glyf
+ DEBUG_MSG(SUBSET, nullptr, "skip head, handled by glyf");
result = true;
break;
case HB_OT_TAG_hhea:
- // SKIP hhea, it's handled by hmtx
+ DEBUG_MSG(SUBSET, nullptr, "skip hhea handled by hmtx");
return true;
case HB_OT_TAG_hmtx:
result = _subset<const OT::hmtx> (plan);
@@ -243,7 +244,7 @@ _subset_table (hb_subset_plan_t *plan,
result = _subset<const OT::maxp> (plan);
break;
case HB_OT_TAG_loca:
- // SKIP loca, it's handle by glyf
+ DEBUG_MSG(SUBSET, nullptr, "skip loca handled by glyf");
return true;
case HB_OT_TAG_cmap:
result = _subset<const OT::cmap> (plan);
@@ -254,16 +255,12 @@ _subset_table (hb_subset_plan_t *plan,
default:
hb_blob_t *source_table = hb_face_reference_table(plan->source, tag);
if (likely(source_table))
- {
result = hb_subset_plan_add_table(plan, tag, source_table);
- }
else
- {
result = false;
- }
+ DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG(tag), result ? "ok" : "FAILED");
break;
}
- DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG(tag), result ? "ok" : "FAILED");
return result;
}
diff --git a/test/api/fonts/Roboto-Regular.ac.nohints.ttf b/test/api/fonts/Roboto-Regular.ac.nohints.ttf
index b7cdffed..b7339178 100644
Binary files a/test/api/fonts/Roboto-Regular.ac.nohints.ttf and b/test/api/fonts/Roboto-Regular.ac.nohints.ttf differ
diff --git a/test/api/hb-subset-test.h b/test/api/hb-subset-test.h
index 8f7fe393..8e579a6c 100644
--- a/test/api/hb-subset-test.h
+++ b/test/api/hb-subset-test.h
@@ -122,6 +122,7 @@ hb_subset_test_check (hb_face_t *expected,
hb_face_t *actual,
hb_tag_t table)
{
+ fprintf(stderr, "compare %c%c%c%c\n", HB_UNTAG(table));
hb_blob_t *expected_blob = hb_face_reference_table (expected, table);
hb_blob_t *actual_blob = hb_face_reference_table (actual, table);
hb_test_assert_blobs_equal (expected_blob, actual_blob);
diff --git a/test/api/test-subset-glyf.c b/test/api/test-subset-glyf.c
index a4b4295f..2f266d07 100644
--- a/test/api/test-subset-glyf.c
+++ b/test/api/test-subset-glyf.c
@@ -105,8 +105,8 @@ test_subset_glyf_strip_hints (void)
hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, input);
hb_set_destroy (codepoints);
- hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
+ hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('m','a','x', 'p'));
hb_face_destroy (face_abc_subset);
@@ -123,10 +123,10 @@ main (int argc, char **argv)
{
hb_test_init (&argc, &argv);
- hb_test_add (test_subset_glyf);
- hb_test_add (test_subset_glyf_with_components);
hb_test_add (test_subset_glyf_noop);
+ hb_test_add (test_subset_glyf);
hb_test_add (test_subset_glyf_strip_hints);
+ hb_test_add (test_subset_glyf_with_components);
return hb_test_run();
}
commit 4f07437dfebd3dc5923f40154c6f1b7e1dce1bd4
Author: Rod Sheeter <rsheeter at google.com>
Date: Wed Feb 21 22:23:05 2018 -0800
[subset] sketch out dropping in-glyf instructions. Sometimes yields differnet size glyphs than fonttools, possibly due to padding not being corrected
diff --git a/src/hb-ot-glyf-table.hh b/src/hb-ot-glyf-table.hh
index 50a71115..667dfb52 100644
--- a/src/hb-ot-glyf-table.hh
+++ b/src/hb-ot-glyf-table.hh
@@ -301,6 +301,51 @@ struct glyf
return true;
}
+ inline bool get_instruction_offsets(unsigned int start_offset,
+ unsigned int end_offset,
+ unsigned int *instruction_start /* OUT */,
+ unsigned int *instruction_end /* OUT */) const
+ {
+ if (end_offset - start_offset < GlyphHeader::static_size)
+ {
+ *instruction_start = 0;
+ *instruction_end = 0;
+ return true; /* Empty glyph; no instructions. */
+ }
+ const GlyphHeader &glyph_header = StructAtOffset<GlyphHeader> (glyf_table, start_offset);
+ int16_t num_contours = (int16_t) glyph_header.numberOfContours;
+ if (num_contours < 0)
+ {
+ CompositeGlyphHeader::Iterator *composite_it;
+ if (unlikely (!CompositeGlyphHeader::get_iterator (
+ (const char*) this->glyf_table + start_offset,
+ end_offset - start_offset, composite_it))) return false;
+ const CompositeGlyphHeader *last;
+ do {
+ last = composite_it->current;
+ } while (composite_it->move_to_next());
+
+ if ( (uint16_t) last->flags & CompositeGlyphHeader::WE_HAVE_INSTRUCTIONS)
+ *instruction_start = start_offset + ((char *) last - (char *) glyf_table->dataX) + last->get_size();
+ else
+ *instruction_start = end_offset;
+ *instruction_end = end_offset;
+ if (unlikely (*instruction_start > *instruction_end))
+ {
+ DEBUG_MSG(SUBSET, nullptr, "Invalid instruction offset, %d is outside [%d, %d]", *instruction_start, start_offset, end_offset);
+ return false;
+ }
+ }
+ else
+ {
+ unsigned int instruction_length_offset = start_offset + GlyphHeader::static_size + 2 * num_contours;
+ const HBUINT16 &instruction_length = StructAtOffset<HBUINT16> (glyf_table, instruction_length_offset);
+ *instruction_start = instruction_length_offset + 2;
+ *instruction_end = *instruction_start + (uint16_t) instruction_length;
+ }
+ return true;
+ }
+
inline bool get_extents (hb_codepoint_t glyph,
hb_glyph_extents_t *extents) const
{
diff --git a/src/hb-subset-glyf.cc b/src/hb-subset-glyf.cc
index d57b4115..867810fb 100644
--- a/src/hb-subset-glyf.cc
+++ b/src/hb-subset-glyf.cc
@@ -21,7 +21,7 @@
* ON AN "AS IS" BASIS, AND THE COPYRIGHT HOLDER HAS NO OBLIGATION TO
* PROVIDE MAINTENANCE, SUPPORT, UPDATES, ENHANCEMENTS, OR MODIFICATIONS.
*
- * Google Author(s): Garret Rieger
+ * Google Author(s): Garret Rieger, Roderick Sheeter
*/
#include "hb-open-type-private.hh"
@@ -33,26 +33,42 @@
static bool
_calculate_glyf_and_loca_prime_size (const OT::glyf::accelerator_t &glyf,
hb_prealloced_array_t<hb_codepoint_t> &glyph_ids,
- bool *use_short_loca, /* OUT */
- unsigned int *glyf_size, /* OUT */
- unsigned int *loca_size /* OUT */)
+ hb_bool_t drop_hints,
+ bool *use_short_loca /* OUT */,
+ unsigned int *glyf_size /* OUT */,
+ unsigned int *loca_size /* OUT */,
+ hb_prealloced_array_t<unsigned int> *instruction_ranges /* OUT */)
{
unsigned int total = 0;
- unsigned int count = 0;
for (unsigned int i = 0; i < glyph_ids.len; i++)
{
hb_codepoint_t next_glyph = glyph_ids[i];
unsigned int start_offset, end_offset;
- if (unlikely (!glyf.get_offsets (next_glyph, &start_offset, &end_offset)))
- end_offset = start_offset = 0;
+ if (unlikely (!glyf.get_offsets(next_glyph, &start_offset, &end_offset)))
+ {
+ DEBUG_MSG(SUBSET, nullptr, "Invalid gid %d", next_glyph);
+ continue;
+ }
+ unsigned int instruction_start = 0, instruction_end = 0;
+ if (drop_hints)
+ {
+ if (unlikely (!glyf.get_instruction_offsets(start_offset, end_offset,
+ &instruction_start, &instruction_end)))
+ {
+ DEBUG_MSG(SUBSET, nullptr, "Unable to get instruction offsets for %d", next_glyph);
+ return false;
+ }
+ }
+ *(instruction_ranges->push()) = instruction_start;
+ *(instruction_ranges->push()) = instruction_end;
- total += end_offset - start_offset;
- count++;
+ total += end_offset - start_offset - (instruction_end - instruction_start);
+ fprintf(stderr, " %d ends at %d (was %d to %d, remove %d)\n", next_glyph, total, start_offset, end_offset, instruction_end - instruction_start);
}
*glyf_size = total;
*use_short_loca = (total <= 131070);
- *loca_size = (count + 1)
+ *loca_size = (glyph_ids.len + 1)
* (*use_short_loca ? sizeof(OT::HBUINT16) : sizeof(OT::HBUINT32));
DEBUG_MSG(SUBSET, nullptr, "preparing to subset glyf: final size %d, loca size %d, using %s loca",
@@ -118,6 +134,7 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
const OT::glyf::accelerator_t &glyf,
const char *glyf_data,
bool use_short_loca,
+ hb_prealloced_array_t<unsigned int> &instruction_ranges,
unsigned int glyf_prime_size,
char *glyf_prime_data /* OUT */,
unsigned int loca_prime_size,
@@ -132,25 +149,44 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
unsigned int start_offset, end_offset;
if (unlikely (!glyf.get_offsets (glyph_ids[i], &start_offset, &end_offset)))
end_offset = start_offset = 0;
+ unsigned int instruction_start = instruction_ranges[i * 2];
+ unsigned int instruction_end = instruction_ranges[i * 2 + 1];
- int length = end_offset - start_offset;
+ int length = end_offset - start_offset - (instruction_end - instruction_start);
if (glyf_prime_data_next + length > glyf_prime_data + glyf_prime_size)
{
DEBUG_MSG (SUBSET,
nullptr,
- "WARNING: Attempted to write an out of bounds glyph entry for gid %d",
- i);
+ "WARNING: Attempted to write an out of bounds glyph entry for gid %d (length %d)",
+ i, length);
return false;
}
- memcpy (glyf_prime_data_next, glyf_data + start_offset, length);
+
+ if (instruction_start == instruction_end)
+ {
+ fprintf(stderr, "i=%d copy %d bytes from %d to %ld\n", i, length, start_offset, glyf_prime_data_next - glyf_prime_data);
+ memcpy (glyf_prime_data_next, glyf_data + start_offset, length);
+ }
+ else
+ {
+ fprintf(stderr, "i=%d copy %d bytes from %d to %ld\n", i, instruction_start - start_offset, start_offset, glyf_prime_data_next - glyf_prime_data);
+ fprintf(stderr, "i=%d copy %d bytes from %d to %ld\n", i, end_offset - instruction_end, instruction_end, glyf_prime_data_next + instruction_start - start_offset - glyf_prime_data);
+ memcpy (glyf_prime_data_next, glyf_data + start_offset, instruction_start - start_offset);
+ memcpy (glyf_prime_data_next + instruction_start - start_offset, glyf_data + instruction_end, end_offset - instruction_end);
+ /* if the instructions end at the end this was a composite glyph */
+ if (instruction_end == end_offset)
+ ; // TODO(rsheeter) remove WE_HAVE_INSTRUCTIONS from last flags
+ else
+ ; // TODO(rsheeter) zero instructionLength
+ }
success = success && _write_loca_entry (i,
glyf_prime_data_next - glyf_prime_data,
use_short_loca,
loca_prime_data,
loca_prime_size);
- _update_components (plan, glyf_prime_data_next, end_offset - start_offset);
+ _update_components (plan, glyf_prime_data_next, length);
glyf_prime_data_next += length;
}
@@ -166,7 +202,7 @@ _write_glyf_and_loca_prime (hb_subset_plan_t *plan,
static bool
_hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf,
const char *glyf_data,
- hb_subset_plan_t *plan,
+ hb_subset_plan_t *plan,
bool *use_short_loca,
hb_blob_t **glyf_prime /* OUT */,
hb_blob_t **loca_prime /* OUT */)
@@ -176,12 +212,17 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf,
unsigned int glyf_prime_size;
unsigned int loca_prime_size;
+ hb_prealloced_array_t<unsigned int> instruction_ranges;
+ instruction_ranges.init();
if (unlikely (!_calculate_glyf_and_loca_prime_size (glyf,
glyphs_to_retain,
+ plan->drop_hints,
use_short_loca,
&glyf_prime_size,
- &loca_prime_size))) {
+ &loca_prime_size,
+ &instruction_ranges))) {
+ instruction_ranges.finish();
return false;
}
@@ -189,12 +230,15 @@ _hb_subset_glyf_and_loca (const OT::glyf::accelerator_t &glyf,
char *loca_prime_data = (char *) malloc (loca_prime_size);
if (unlikely (!_write_glyf_and_loca_prime (plan, glyf, glyf_data,
*use_short_loca,
+ instruction_ranges,
glyf_prime_size, glyf_prime_data,
loca_prime_size, loca_prime_data))) {
free (glyf_prime_data);
free (loca_prime_data);
+ instruction_ranges.finish();
return false;
}
+ instruction_ranges.finish();
*glyf_prime = hb_blob_create (glyf_prime_data,
glyf_prime_size,
diff --git a/src/hb-subset-input.cc b/src/hb-subset-input.cc
index d41cff60..69aa9d61 100644
--- a/src/hb-subset-input.cc
+++ b/src/hb-subset-input.cc
@@ -105,3 +105,9 @@ hb_subset_input_glyph_set (hb_subset_input_t *subset_input)
{
return subset_input->glyphs;
}
+
+HB_EXTERN hb_bool_t *
+hb_subset_input_drop_hints(hb_subset_input_t *subset_input)
+{
+ return &subset_input->drop_hints;
+}
diff --git a/src/hb-subset.h b/src/hb-subset.h
index de7759b2..1af7cba5 100644
--- a/src/hb-subset.h
+++ b/src/hb-subset.h
@@ -68,6 +68,8 @@ hb_subset_input_unicode_set (hb_subset_input_t *subset_input);
HB_EXTERN hb_set_t *
hb_subset_input_glyph_set (hb_subset_input_t *subset_input);
+HB_EXTERN hb_bool_t *
+hb_subset_input_drop_hints(hb_subset_input_t *subset_input);
/* hb_subset() */
diff --git a/test/api/fonts/Roboto-Regular.ac.nohints.ttf b/test/api/fonts/Roboto-Regular.ac.nohints.ttf
new file mode 100644
index 00000000..b7cdffed
Binary files /dev/null and b/test/api/fonts/Roboto-Regular.ac.nohints.ttf differ
diff --git a/test/api/hb-subset-test.h b/test/api/hb-subset-test.h
index 12f7868a..8f7fe393 100644
--- a/test/api/hb-subset-test.h
+++ b/test/api/hb-subset-test.h
@@ -95,17 +95,20 @@ hb_subset_test_open_font (const char *font_path)
return NULL; /* Shut up, compiler! */
}
-static inline hb_face_t *
-hb_subset_test_create_subset (hb_face_t *source,
- const hb_set_t *codepoints)
+static inline hb_subset_input_t *
+hb_subset_test_create_input(const hb_set_t *codepoints)
{
- hb_subset_profile_t *profile = hb_subset_profile_create();
hb_subset_input_t *input = hb_subset_input_create_or_fail ();
-
hb_set_t * input_codepoints = hb_subset_input_unicode_set (input);
-
hb_set_union (input_codepoints, codepoints);
+ return input;
+}
+static inline hb_face_t *
+hb_subset_test_create_subset (hb_face_t *source,
+ hb_subset_input_t *input)
+{
+ hb_subset_profile_t *profile = hb_subset_profile_create();
hb_face_t *subset = hb_subset (source, profile, input);
g_assert (subset);
diff --git a/test/api/test-subset-cmap.c b/test/api/test-subset-cmap.c
index 8798475f..07715791 100644
--- a/test/api/test-subset-cmap.c
+++ b/test/api/test-subset-cmap.c
@@ -40,7 +40,7 @@ test_subset_cmap (void)
hb_set_t *codepoints = hb_set_create ();
hb_set_add (codepoints, 97);
hb_set_add (codepoints, 99);
- hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints);
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('c','m','a','p'));
@@ -59,7 +59,7 @@ test_subset_cmap_noop (void)
hb_set_add (codepoints, 97);
hb_set_add (codepoints, 98);
hb_set_add (codepoints, 99);
- hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints);
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('c','m','a','p'));
diff --git a/test/api/test-subset-glyf.c b/test/api/test-subset-glyf.c
index 96e37bbc..a4b4295f 100644
--- a/test/api/test-subset-glyf.c
+++ b/test/api/test-subset-glyf.c
@@ -40,7 +40,7 @@ test_subset_glyf (void)
hb_set_t *codepoints = hb_set_create();
hb_set_add (codepoints, 97);
hb_set_add (codepoints, 99);
- hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints);
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
@@ -60,7 +60,7 @@ test_subset_glyf_with_components (void)
hb_set_t *codepoints = hb_set_create();
hb_set_add (codepoints, 0x1fc);
- hb_face_t *face_generated_subset = hb_subset_test_create_subset (face_components, codepoints);
+ hb_face_t *face_generated_subset = hb_subset_test_create_subset (face_components, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
hb_subset_test_check (face_subset, face_generated_subset, HB_TAG ('g','l','y','f'));
@@ -81,7 +81,7 @@ test_subset_glyf_noop (void)
hb_set_add (codepoints, 97);
hb_set_add (codepoints, 98);
hb_set_add (codepoints, 99);
- hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints);
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
hb_subset_test_check (face_abc, face_abc_subset, HB_TAG ('g','l','y','f'));
@@ -91,6 +91,31 @@ test_subset_glyf_noop (void)
hb_face_destroy (face_abc);
}
+static void
+test_subset_glyf_strip_hints (void)
+{
+ hb_face_t *face_abc = hb_subset_test_open_font ("fonts/Roboto-Regular.abc.ttf");
+ hb_face_t *face_ac = hb_subset_test_open_font ("fonts/Roboto-Regular.ac.nohints.ttf");
+
+ hb_set_t *codepoints = hb_set_create();
+ hb_set_add (codepoints, 'a');
+ hb_set_add (codepoints, 'c');
+ hb_subset_input_t *input = hb_subset_test_create_input (codepoints);
+ *hb_subset_input_drop_hints(input) = true;
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, input);
+ hb_set_destroy (codepoints);
+
+ hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('g','l','y','f'));
+ hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('l','o','c', 'a'));
+ hb_subset_test_check (face_ac, face_abc_subset, HB_TAG ('m','a','x', 'p'));
+
+ hb_face_destroy (face_abc_subset);
+ hb_face_destroy (face_abc);
+ hb_face_destroy (face_ac);
+}
+
+// TODO(rsheeter): test strip hints from composite
+
// TODO(grieger): test for long loca generation.
int
@@ -101,6 +126,7 @@ main (int argc, char **argv)
hb_test_add (test_subset_glyf);
hb_test_add (test_subset_glyf_with_components);
hb_test_add (test_subset_glyf_noop);
+ hb_test_add (test_subset_glyf_strip_hints);
return hb_test_run();
}
diff --git a/test/api/test-subset-hmtx.c b/test/api/test-subset-hmtx.c
index 36d7d9e8..2b764526 100644
--- a/test/api/test-subset-hmtx.c
+++ b/test/api/test-subset-hmtx.c
@@ -55,7 +55,7 @@ test_subset_hmtx_simple_subset (void)
hb_set_t *codepoints = hb_set_create ();
hb_set_add (codepoints, 'a');
hb_set_add (codepoints, 'c');
- hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints);
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
check_num_hmetrics(face_abc_subset, 3); /* nothing has same width */
@@ -76,7 +76,7 @@ test_subset_hmtx_monospace (void)
hb_set_t *codepoints = hb_set_create ();
hb_set_add (codepoints, 'a');
hb_set_add (codepoints, 'c');
- hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints);
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
check_num_hmetrics(face_abc_subset, 1); /* everything has same width */
@@ -97,7 +97,7 @@ test_subset_hmtx_keep_num_metrics (void)
hb_set_t *codepoints = hb_set_create ();
hb_set_add (codepoints, 'a');
hb_set_add (codepoints, 'c');
- hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints);
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
check_num_hmetrics(face_abc_subset, 3); /* c is wider */
@@ -117,7 +117,7 @@ test_subset_hmtx_decrease_num_metrics (void)
hb_set_t *codepoints = hb_set_create ();
hb_set_add (codepoints, 'a');
hb_set_add (codepoints, 'b');
- hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints);
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
check_num_hmetrics(face_abc_subset, 1); /* everything left has same width */
@@ -137,7 +137,7 @@ test_subset_hmtx_noop (void)
hb_set_add (codepoints, 'a');
hb_set_add (codepoints, 'b');
hb_set_add (codepoints, 'c');
- hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints);
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
check_num_hmetrics(face_abc_subset, 4); /* nothing has same width */
diff --git a/test/api/test-subset-os2.c b/test/api/test-subset-os2.c
index e2b96f92..e9db9bed 100644
--- a/test/api/test-subset-os2.c
+++ b/test/api/test-subset-os2.c
@@ -37,7 +37,7 @@ test_subset_os2 (void)
hb_set_t *codepoints = hb_set_create();
hb_set_add (codepoints, 98);
- hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, codepoints);
+ hb_face_t *face_abc_subset = hb_subset_test_create_subset (face_abc, hb_subset_test_create_input (codepoints));
hb_set_destroy (codepoints);
hb_subset_test_check (face_b, face_abc_subset, HB_TAG ('O','S','/','2'));
commit 74e0c13a4a55848e797242c02c8f067e587ea603
Author: Rod Sheeter <rsheeter at google.com>
Date: Wed Feb 21 11:19:18 2018 -0800
[subset] drop hint tables if so flagged. Still need to dump glyf instructions.
diff --git a/src/hb-subset-plan.cc b/src/hb-subset-plan.cc
index b9e299ad..0f653ff3 100644
--- a/src/hb-subset-plan.cc
+++ b/src/hb-subset-plan.cc
@@ -191,6 +191,7 @@ hb_subset_plan_create (hb_face_t *face,
plan->gids_to_retain_sorted.init();
plan->source = hb_face_reference (face);
plan->dest = hb_subset_face_create ();
+ plan->drop_hints = input->drop_hints;
_populate_codepoints (input->unicodes, plan->codepoints);
_populate_gids_to_retain (face,
diff --git a/src/hb-subset-plan.hh b/src/hb-subset-plan.hh
index a7415285..d1b66b44 100644
--- a/src/hb-subset-plan.hh
+++ b/src/hb-subset-plan.hh
@@ -37,6 +37,8 @@ struct hb_subset_plan_t {
hb_object_header_t header;
ASSERT_POD ();
+ hb_bool_t drop_hints;
+
// TODO(Q1) actual map, drop this crap
// Look at me ma, I'm a poor mans map codepoint : new gid
// codepoints is sorted and aligned with gids_to_retain.
diff --git a/src/hb-subset-private.hh b/src/hb-subset-private.hh
index 55ac6f12..5fa72527 100644
--- a/src/hb-subset-private.hh
+++ b/src/hb-subset-private.hh
@@ -43,7 +43,7 @@ struct hb_subset_input_t {
hb_set_t *unicodes;
hb_set_t *glyphs;
- hb_bool_t retain_hints;
+ hb_bool_t drop_hints;
/* TODO
*
* features
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index a4794f18..b46b07fc 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -268,9 +268,16 @@ _subset_table (hb_subset_plan_t *plan,
}
static bool
-_should_drop_table(hb_tag_t tag)
+_should_drop_table(hb_subset_plan_t *plan, hb_tag_t tag)
{
switch (tag) {
+ case HB_TAG ('c', 'v', 'a', 'r'): /* hint table, fallthrough */
+ case HB_TAG ('c', 'v', 't', ' '): /* hint table, fallthrough */
+ case HB_TAG ('f', 'p', 'g', 'm'): /* hint table, fallthrough */
+ case HB_TAG ('p', 'r', 'e', 'p'): /* hint table, fallthrough */
+ case HB_TAG ('h', 'd', 'm', 'x'): /* hint table, fallthrough */
+ case HB_TAG ('V', 'D', 'M', 'X'): /* hint table, fallthrough */
+ return plan->drop_hints;
case HB_TAG ('G', 'D', 'E', 'F'): /* temporary */
case HB_TAG ('G', 'P', 'O', 'S'): /* temporary */
case HB_TAG ('G', 'S', 'U', 'B'): /* temporary */
@@ -307,7 +314,7 @@ hb_subset (hb_face_t *source,
for (unsigned int i = 0; i < count; i++)
{
hb_tag_t tag = table_tags[i];
- if (_should_drop_table(tag))
+ if (_should_drop_table(plan, tag))
{
DEBUG_MSG(SUBSET, nullptr, "drop %c%c%c%c", HB_UNTAG(tag));
continue;
diff --git a/util/hb-subset.cc b/util/hb-subset.cc
index 3db62598..20617554 100644
--- a/util/hb-subset.cc
+++ b/util/hb-subset.cc
@@ -90,7 +90,7 @@ struct subset_consumer_t
void finish (const font_options_t *font_opts)
{
- input->retain_hints = subset_options.hinting;
+ input->drop_hints = subset_options.drop_hints;
hb_subset_profile_t *subset_profile = hb_subset_profile_create();
hb_face_t *face = hb_font_get_face (font);
diff --git a/util/options.cc b/util/options.cc
index aa8a6a96..7571fe84 100644
--- a/util/options.cc
+++ b/util/options.cc
@@ -992,7 +992,7 @@ subset_options_t::add_options (option_parser_t *parser)
{
GOptionEntry entries[] =
{
- {"hinting", 0, 0, G_OPTION_ARG_NONE, &this->hinting, "Whether to retain or drop hints", nullptr},
+ {"no-hinting", 0, 0, G_OPTION_ARG_NONE, &this->drop_hints, "Whether to drop hints", nullptr},
{nullptr}
};
parser->add_group (entries,
diff --git a/util/options.hh b/util/options.hh
index 80d32d90..cce0eb16 100644
--- a/util/options.hh
+++ b/util/options.hh
@@ -653,14 +653,14 @@ struct subset_options_t : option_group_t
{
subset_options_t (option_parser_t *parser)
{
- hinting = true;
+ drop_hints = false;
add_options (parser);
}
void add_options (option_parser_t *parser);
- hb_bool_t hinting;
+ hb_bool_t drop_hints;
};
/* fallback implementation for scalbn()/scalbnf() for pre-2013 MSVC */
commit 0bd100e144885ed8144cf23e7e106014858a1724
Author: Rod Sheeter <rsheeter at google.com>
Date: Wed Feb 21 10:34:00 2018 -0800
[subset] add --hinting flag
diff --git a/src/hb-subset-private.hh b/src/hb-subset-private.hh
index cf784d72..55ac6f12 100644
--- a/src/hb-subset-private.hh
+++ b/src/hb-subset-private.hh
@@ -43,6 +43,7 @@ struct hb_subset_input_t {
hb_set_t *unicodes;
hb_set_t *glyphs;
+ hb_bool_t retain_hints;
/* TODO
*
* features
diff --git a/util/hb-subset.cc b/util/hb-subset.cc
index ea657aff..3db62598 100644
--- a/util/hb-subset.cc
+++ b/util/hb-subset.cc
@@ -29,6 +29,7 @@
#include "main-font-text.hh"
#include "hb-subset.h"
+#include "hb-subset-private.hh"
/*
* Command line interface to the harfbuzz font subsetter.
@@ -37,7 +38,7 @@
struct subset_consumer_t
{
subset_consumer_t (option_parser_t *parser)
- : failed (false), options (parser), font (nullptr), input (nullptr) {}
+ : failed (false), options (parser), subset_options (parser), font (nullptr), input (nullptr) {}
void init (hb_buffer_t *buffer_,
const font_options_t *font_opts)
@@ -89,6 +90,8 @@ struct subset_consumer_t
void finish (const font_options_t *font_opts)
{
+ input->retain_hints = subset_options.hinting;
+
hb_subset_profile_t *subset_profile = hb_subset_profile_create();
hb_face_t *face = hb_font_get_face (font);
@@ -111,6 +114,7 @@ struct subset_consumer_t
private:
output_options_t options;
+ subset_options_t subset_options;
hb_font_t *font;
hb_subset_input_t *input;
};
diff --git a/util/options.cc b/util/options.cc
index 6d8064b9..aa8a6a96 100644
--- a/util/options.cc
+++ b/util/options.cc
@@ -986,3 +986,18 @@ format_options_t::serialize_buffer_of_glyphs (hb_buffer_t *buffer,
serialize_glyphs (buffer, font, output_format, format_flags, gs);
g_string_append_c (gs, '\n');
}
+
+void
+subset_options_t::add_options (option_parser_t *parser)
+{
+ GOptionEntry entries[] =
+ {
+ {"hinting", 0, 0, G_OPTION_ARG_NONE, &this->hinting, "Whether to retain or drop hints", nullptr},
+ {nullptr}
+ };
+ parser->add_group (entries,
+ "subset",
+ "Subset options:",
+ "Options subsetting",
+ this);
+}
diff --git a/util/options.hh b/util/options.hh
index 411165bf..80d32d90 100644
--- a/util/options.hh
+++ b/util/options.hh
@@ -649,6 +649,20 @@ struct format_options_t : option_group_t
hb_bool_t trace;
};
+struct subset_options_t : option_group_t
+{
+ subset_options_t (option_parser_t *parser)
+ {
+ hinting = true;
+
+ add_options (parser);
+ }
+
+ void add_options (option_parser_t *parser);
+
+ hb_bool_t hinting;
+};
+
/* fallback implementation for scalbn()/scalbnf() for pre-2013 MSVC */
#if defined (_MSC_VER) && (_MSC_VER < 1800)
commit 7ecca8c0a83a6c71154fcc80887a4f895c0c5a23
Author: Rod Sheeter <rsheeter at google.com>
Date: Wed Feb 21 09:42:46 2018 -0800
[subset] keep the result of _subset
diff --git a/src/hb-subset.cc b/src/hb-subset.cc
index 418e481f..a4794f18 100644
--- a/src/hb-subset.cc
+++ b/src/hb-subset.cc
@@ -264,7 +264,7 @@ _subset_table (hb_subset_plan_t *plan,
break;
}
DEBUG_MSG(SUBSET, nullptr, "subset %c%c%c%c %s", HB_UNTAG(tag), result ? "ok" : "FAILED");
- return true;
+ return result;
}
static bool
commit 3ebcd5a381e2de27a0cfb5af3359331f0b7e7108
Author: Elie Roux <elie.roux at telecom-bretagne.eu>
Date: Sun Mar 5 16:26:01 2017 +0100
first working version!
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index 3511810a..d393f5ca 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -57,6 +57,7 @@ _hb_ot_layout_create (hb_face_t *face)
layout->gpos = OT::Sanitizer<OT::GPOS>::lock_instance (layout->gpos_blob);
layout->math.init (face);
+ layout->base.init (face);
layout->fvar.init (face);
layout->avar.init (face);
@@ -185,6 +186,7 @@ _hb_ot_layout_destroy (hb_ot_layout_t *layout)
hb_blob_destroy (layout->gpos_blob);
layout->math.fini ();
+ layout->base.fini ();
layout->fvar.fini ();
layout->avar.fini ();
diff --git a/src/hb-ot.h b/src/hb-ot.h
index 2120a3ef..272208e3 100644
--- a/src/hb-ot.h
+++ b/src/hb-ot.h
@@ -33,6 +33,7 @@
#include "hb-ot-font.h"
#include "hb-ot-layout.h"
#include "hb-ot-math.h"
+#include "hb-ot-base.h"
#include "hb-ot-tag.h"
#include "hb-ot-shape.h"
#include "hb-ot-var.h"
commit e65aaaa00a3b5ac811b5c73b5186cd7d65731f7b
Author: Elie Roux <elie.roux at telecom-bretagne.eu>
Date: Sun Mar 5 14:53:39 2017 +0100
BASE: start api
diff --git a/src/Makefile.sources b/src/Makefile.sources
index 0f83f6eb..db730565 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -68,6 +68,7 @@ HB_NODIST_headers = \
HB_FALLBACK_sources = hb-fallback-shape.cc
HB_OT_sources = \
+ hb-ot-base.cc \
hb-ot-font.cc \
hb-ot-layout.cc \
hb-ot-layout-base-table.hh \
@@ -121,6 +122,7 @@ HB_OT_headers = \
hb-ot-font.h \
hb-ot-layout.h \
hb-ot-math.h \
+ hb-ot-base.h \
hb-ot-shape.h \
hb-ot-tag.h \
hb-ot-var.h \
diff --git a/src/hb-ot-base.cc b/src/hb-ot-base.cc
new file mode 100644
index 00000000..27e0b208
--- /dev/null
+++ b/src/hb-ot-base.cc
@@ -0,0 +1,58 @@
+/*
+ * Copyright © 2017 Elie Roux<elie.roux at telecom-bretagne.eu>
+ *
+ * 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.
+ *
+ */
+
+#include "hb-open-type-private.hh"
+
+#include "hb-ot-layout-private.hh"
+#include "hb-ot-layout-base-table.hh"
+
+static inline const OT::BASE&
+_get_base (hb_face_t *face)
+{
+ if (unlikely (!hb_ot_shaper_face_data_ensure (face))) return OT::Null(OT::BASE);
+ hb_ot_layout_t * layout = hb_ot_layout_from_face (face);
+ return *(layout->base.get ());
+}
+
+/*
+ * OT::BASE
+ */
+
+/**
+ * hb_ot_base_has_data:
+ * @face: #hb_face_t to test
+ *
+ * This function allows to verify the presence of an OpenType BASE table on the
+ * face.
+ *
+ * Return value: true if face has a BASE table, false otherwise
+ *
+ * Since: XXX
+ **/
+hb_bool_t
+hb_ot_base_has_data (hb_face_t *face)
+{
+ return &_get_base (face) != &OT::Null(OT::BASE);
+}
diff --git a/src/hb-ot-base.h b/src/hb-ot-base.h
new file mode 100644
index 00000000..9d82d228
--- /dev/null
+++ b/src/hb-ot-base.h
@@ -0,0 +1,56 @@
+/*
+ * Copyright © 2017 Elie Roux<elie.roux at telecom-bretagne.eu>
+ *
+ * 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.
+ *
+ */
+
+#ifndef HB_OT_H_IN
+#error "Include <hb-ot.h> instead."
+#endif
+
+#ifndef HB_OT_BASE_H
+#define HB_OT_BASE_H
+
+#include "hb.h"
+
+HB_BEGIN_DECLS
+
+#define HB_OT_TAG_BASE HB_TAG('B','A','S','E')
+
+// https://www.microsoft.com/typography/otspec/baselinetags.htm
+
+#define HB_OT_TAG_BASE_HANG HB_TAG('h','a','n','g')
+#define HB_OT_TAG_BASE_ICFB HB_TAG('i','c','f','b')
+#define HB_OT_TAG_BASE_ICFT HB_TAG('i','c','f','t')
+#define HB_OT_TAG_BASE_IDEO HB_TAG('i','d','e','o')
+#define HB_OT_TAG_BASE_IDTB HB_TAG('i','d','t','b')
+#define HB_OT_TAG_BASE_MATH HB_TAG('m','a','t','h')
+#define HB_OT_TAG_BASE_ROMN HB_TAG('r','o','m','n')
+
+/* Methods */
+
+HB_EXTERN hb_bool_t
+hb_ot_base_has_data (hb_face_t *face);
+
+HB_END_DECLS
+
+#endif /* HB_OT_BASE_H */
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index c60ce6de..0d1e197e 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -28,18 +28,7 @@
#include "hb-open-type-private.hh"
#include "hb-ot-layout-common-private.hh"
-
-#define HB_OT_TAG_BASE HB_TAG('B','A','S','E')
-
-// https://www.microsoft.com/typography/otspec/baselinetags.htm
-
-#define HB_OT_TAG_BASE_HANG HB_TAG('h','a','n','g')
-#define HB_OT_TAG_BASE_ICFB HB_TAG('i','c','f','b')
-#define HB_OT_TAG_BASE_ICFT HB_TAG('i','c','f','t')
-#define HB_OT_TAG_BASE_IDEO HB_TAG('i','d','e','o')
-#define HB_OT_TAG_BASE_IDTB HB_TAG('i','d','t','b')
-#define HB_OT_TAG_BASE_MATH HB_TAG('m','a','t','h')
-#define HB_OT_TAG_BASE_ROMN HB_TAG('r','o','m','n')
+#include "hb-ot-base.h"
namespace OT {
@@ -743,7 +732,7 @@ struct BASE
inline SHORT get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
{ return u.format1_0.get_vert_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
- inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
if (!u.version.sanitize (c)) return_trace (false);
commit f72726c52b104a71ebf5b39fa1e3eb9febd446fc
Author: Elie Roux <elie.roux at telecom-bretagne.eu>
Date: Sun Feb 26 15:08:43 2017 +0100
BASE: add function in main BASE object
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index 9be403e5..c60ce6de 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -719,6 +719,30 @@ struct BASE
inline SHORT get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
{ return u.format1_0.get_vert_base_coord(baseScriptIndex, baselineTagIndex); }
+ inline unsigned int get_horiz_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
+ { return u.format1_0.get_horiz_lang_tag_index(baseScriptIndex, baseLangSysTag); }
+
+ inline unsigned int get_horiz_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
+ { return u.format1_0.get_horiz_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag); }
+
+ inline SHORT get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ { return u.format1_0.get_horiz_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
+
+ inline SHORT get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ { return u.format1_0.get_horiz_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
+
+ inline unsigned int get_vert_lang_tag_index (unsigned int baseScriptIndex, Tag baseLangSysTag) const
+ { return u.format1_0.get_vert_lang_tag_index(baseScriptIndex, baseLangSysTag); }
+
+ inline unsigned int get_vert_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
+ { return u.format1_0.get_vert_feature_tag_index(baseScriptIndex, baseLangSysIndex, featureTableTag); }
+
+ inline SHORT get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ { return u.format1_0.get_vert_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
+
+ inline SHORT get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ { return u.format1_0.get_vert_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex); }
+
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
commit 3963315f1b2eae2504bc683760245c827cd1ef16
Author: Elie Roux <elie.roux at telecom-bretagne.eu>
Date: Sun Feb 26 15:07:53 2017 +0100
BASE: first complete version
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index c4d9ad14..9be403e5 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -43,7 +43,9 @@
namespace OT {
-#define NO_COORD -32767
+#define NO_COORD Null(SHORT)//SHORT((short int) -32767)
+
+#define NOT_INDEXED ((unsigned int) -1)
/*
* BASE -- The BASE Table
@@ -51,7 +53,7 @@ namespace OT {
struct BaseCoordFormat1 {
- inline SHORT get_coord () const
+ inline SHORT get_coord (void) const
{ return coordinate; }
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -70,7 +72,7 @@ struct BaseCoordFormat1 {
struct BaseCoordFormat2 {
- inline SHORT get_coord () const
+ inline SHORT get_coord (void) const
{ return coordinate; }
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -91,7 +93,7 @@ struct BaseCoordFormat2 {
struct BaseCoordFormat3 {
- inline SHORT get_coord (void ) const
+ inline SHORT get_coord (void) const
{ return coordinate; }
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -111,17 +113,8 @@ struct BaseCoordFormat3 {
struct BaseCoord {
- inline hb_position_t get_value (hb_font_t *font, hb_direction_t dir) const
- {
- SHORT coord;
- switch (u.baseCoordFormat) {
- case 1: coord = u.format1.get_coord();
- case 2: coord = u.format2.get_coord();
- case 3: coord = u.format3.get_coord();
- default: return 0;
- }
- return font->em_scale (coord, dir);
- }
+ inline SHORT get_coord (void) const
+ { return u.format1.get_coord(); }
inline bool sanitize (hb_sanitize_context_t *c) const
{
@@ -131,7 +124,7 @@ struct BaseCoord {
case 1: return_trace (u.format1.sanitize (c));
case 2: return_trace (u.format2.sanitize (c));
case 3: return_trace (u.format3.sanitize (c));
- default:return_trace (true);
+ default:return_trace (false);
}
}
@@ -149,16 +142,16 @@ struct BaseCoord {
struct FeatMinMaxRecord {
- inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir) const
- {
- if (unlikely(minCoord == Null(OffsetTo<BaseCoord>))) return NO_COORD;
- return (this+minCoord).get_value(font, dir);
+ inline SHORT get_min_value (void) const
+ {
+ if (minCoord == Null(OffsetTo<BaseCoord>)) return NO_COORD;
+ return (this+minCoord).get_coord();
}
- inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir) const
- {
- if (unlikely(maxCoord == Null(OffsetTo<BaseCoord>))) return NO_COORD;
- return (this+maxCoord).get_value(font, dir);
+ inline SHORT get_max_value (void) const
+ {
+ if (minCoord == Null(OffsetTo<BaseCoord>)) return NO_COORD;
+ return (this+maxCoord).get_coord();
}
inline Tag get_tag () const
@@ -184,41 +177,39 @@ struct FeatMinMaxRecord {
struct MinMax {
- inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir) const
- {
- if (unlikely(minCoord == Null(OffsetTo<BaseCoord>))) return NO_COORD;
- return (this+minCoord).get_value(font, dir);
- }
-
- inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir) const
- {
- if (unlikely(maxCoord == Null(OffsetTo<BaseCoord>))) return NO_COORD;
- return (this+maxCoord).get_value(font, dir);
+ inline unsigned int get_feature_tag_index (Tag featureTableTag) const
+ {
+ Tag tag;
+ int cmp;
+ // taking advantage of alphabetical order
+ for (unsigned int i = 0; i < featMinMaxCount; i++) {
+ tag = featMinMaxRecords[i].get_tag();
+ cmp = tag.cmp(featureTableTag);
+ if (cmp == 0) return i;
+ if (cmp > 0) return NOT_INDEXED;
+ }
+ return NOT_INDEXED;
}
- inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir, Tag featureTableTag) const
+ inline SHORT get_min_value (unsigned int featureTableTagIndex) const
{
- for (unsigned int i = 0; i < featMinMaxCount; i++)
- {
- if (featMinMaxRecords[i].get_tag() == featureTableTag)
- return featMinMaxRecords[i].get_min_value(font, dir);
- // we could take advantage of alphabetical order by comparing Tags, not currently possible
- //if (featMinMaxRecords[i].get_tag() > featureTableTag)
- // break;
+ if (featureTableTagIndex == NOT_INDEXED) {
+ if (minCoord == Null(OffsetTo<BaseCoord>)) return NO_COORD;
+ return (this+minCoord).get_coord();
}
- return get_min_value (font, dir);
+ if (unlikely(featureTableTagIndex >= featMinMaxCount)) return NO_COORD;
+ return featMinMaxRecords[featureTableTagIndex].get_min_value();
}
- inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir, Tag featureTableTag) const
+ inline SHORT get_max_value (unsigned int featureTableTagIndex) const
{
- for (unsigned int i = 0; i < featMinMaxCount; i++)
- {
- if (featMinMaxRecords[i].get_tag() == featureTableTag)
- return featMinMaxRecords[i].get_max_value(font, dir);
- // we could use alphabetical order to break here
+ if (featureTableTagIndex == NOT_INDEXED) {
+ if (minCoord == Null(OffsetTo<BaseCoord>)) return NO_COORD;
+ return (this+maxCoord).get_coord();
}
- return get_min_value (font, dir);
- }
+ if (unlikely(featureTableTagIndex >= featMinMaxCount)) return NO_COORD;
+ return featMinMaxRecords[featureTableTagIndex].get_max_value();
+ }
inline bool sanitize (hb_sanitize_context_t *c) const
{
@@ -234,7 +225,7 @@ struct MinMax {
OffsetTo<BaseCoord> minCoord;
OffsetTo<BaseCoord> maxCoord;
USHORT featMinMaxCount;
- ArrayOf<FeatMinMaxRecord> featMinMaxRecords; /* All FeatMinMaxRecords are listed alphabetically */
+ ArrayOf<FeatMinMaxRecord> featMinMaxRecords;
public:
DEFINE_SIZE_ARRAY (8, featMinMaxRecords);
@@ -246,17 +237,14 @@ struct BaseLangSysRecord {
inline Tag get_tag(void) const
{ return baseLangSysTag; }
- inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir) const
- { return (this+minMax).get_min_value(font, dir); }
-
- inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir) const
- { return (this+minMax).get_max_value(font, dir); }
+ inline unsigned int get_feature_tag_index (Tag featureTableTag) const
+ { (this+minMax).get_feature_tag_index(featureTableTag); }
- inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir, Tag featureTableTag) const
- { return (this+minMax).get_min_value(font, dir, featureTableTag); }
+ inline SHORT get_min_value (unsigned int featureTableTagIndex) const
+ { (this+minMax).get_min_value(featureTableTagIndex); }
- inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir, Tag featureTableTag) const
- { return (this+minMax).get_max_value(font, dir, featureTableTag); }
+ inline SHORT get_max_value (unsigned int featureTableTagIndex) const
+ { (this+minMax).get_max_value(featureTableTagIndex); }
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
@@ -277,15 +265,25 @@ struct BaseLangSysRecord {
struct BaseValues {
+ inline const unsigned int get_default_base_tag_index (void) const
+ { return defaultIndex; }
+
+ inline SHORT get_base_coord (unsigned int baselineTagIndex) const
+ {
+ if (unlikely(baselineTagIndex >= baseCoordCount)) return NO_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));
}
protected:
- USHORT defaultIndex;
+ Index defaultIndex;
USHORT baseCoordCount;
OffsetArrayOf<BaseCoord> baseCoords;
@@ -296,62 +294,56 @@ struct BaseValues {
struct BaseScript {
- inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir) const
+ inline unsigned int get_lang_tag_index (Tag baseLangSysTag) const
{
- if (unlikely(defaultMinMax == Null(OffsetTo<MinMax>))) return NO_COORD;
- return (this+defaultMinMax).get_min_value(font, dir);
- }
-
- inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir) const
- {
- if (unlikely(defaultMinMax == Null(OffsetTo<MinMax>))) return NO_COORD;
- return (this+defaultMinMax).get_max_value(font, dir);
- }
-
- inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir, Tag baseLangSysTag) const
- {
- for (unsigned int i = 0; i < baseLangSysCount; i++)
- {
- if (baseLangSysRecords[i].get_tag() == baseLangSysTag)
- return baseLangSysRecords[i].get_min_value(font, dir);
- // we could use alphabetical order to break here
+ Tag tag;
+ int cmp;
+ for (unsigned int i = 0; i < baseLangSysCount; i++) {
+ tag = baseLangSysRecords[i].get_tag();
+ // taking advantage of alphabetical order
+ cmp = tag.cmp(baseLangSysTag);
+ if (cmp == 0) return i;
+ if (cmp > 0) return NOT_INDEXED;
}
- return get_min_value (font, dir);
+ return NOT_INDEXED;
}
- inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir, Tag baseLangSysTag) const
+ inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const
{
- for (unsigned int i = 0; i < baseLangSysCount; i++)
- {
- if (baseLangSysRecords[i].get_tag() == baseLangSysTag)
- return baseLangSysRecords[i].get_max_value(font, dir);
- // we could use alphabetical order to break here
+ if (baseLangSysIndex == NOT_INDEXED) {
+ if (unlikely(defaultMinMax)) return NOT_INDEXED;
+ return (this+defaultMinMax).get_feature_tag_index(featureTableTag);
}
- return get_max_value (font, dir);
+ if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NOT_INDEXED;
+ return baseLangSysRecords[baseLangSysIndex].get_feature_tag_index(featureTableTag);
}
- inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir, Tag baseLangSysTag, Tag featureTableTag) const
+ inline SHORT get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
{
- for (unsigned int i = 0; i < baseLangSysCount; i++)
- {
- if (baseLangSysRecords[i].get_tag() == baseLangSysTag)
- return baseLangSysRecords[i].get_min_value(font, dir, featureTableTag);
- // we could use alphabetical order to break here
+ if (baseLangSysIndex == NOT_INDEXED) {
+ if (unlikely(defaultMinMax == Null(OffsetTo<MinMax>))) return NO_COORD;
+ return (this+defaultMinMax).get_min_value(featureTableTagIndex);
}
- return get_min_value (font, dir);
+ if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NO_COORD;
+ return baseLangSysRecords[baseLangSysIndex].get_max_value(featureTableTagIndex);
}
- inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir, Tag baseLangSysTag, Tag featureTableTag) const
+ inline SHORT get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
{
- for (unsigned int i = 0; i < baseLangSysCount; i++)
- {
- if (baseLangSysRecords[i].get_tag() == baseLangSysTag)
- return baseLangSysRecords[i].get_max_value(font, dir);
- // we could use alphabetical order to break here
+ if (baseLangSysIndex == NOT_INDEXED) {
+ if (unlikely(defaultMinMax == Null(OffsetTo<MinMax>))) return NO_COORD;
+ return (this+defaultMinMax).get_min_value(featureTableTagIndex);
}
- return get_max_value (font, dir);
+ if (unlikely(baseLangSysIndex >= baseLangSysCount)) return NO_COORD;
+ 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(); }
+
+ inline SHORT get_base_coord (unsigned int baselineTagIndex) const
+ { return (this+baseValues).get_base_coord(baselineTagIndex); }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -374,20 +366,32 @@ struct BaseScript {
struct BaseScriptRecord {
- inline const BaseScript *get_baseScript (void) const
- {
- return &(this+baseScript);
- }
-
inline bool get_tag (void) const
- {
- return baseScriptTag;
- }
+ { return baseScriptTag; }
+
+ inline unsigned int get_default_base_tag_index(void) const
+ { return (this+baseScript).get_default_base_tag_index(); }
+
+ inline SHORT get_base_coord(unsigned int baselineTagIndex) const
+ { 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); }
+
+ inline unsigned int get_feature_tag_index (unsigned int baseLangSysIndex, Tag featureTableTag) const
+ { return (this+baseScript).get_feature_tag_index(baseLangSysIndex, featureTableTag); }
+
+ inline SHORT get_max_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ { return (this+baseScript).get_max_value(baseLangSysIndex, featureTableTagIndex); }
+
+ inline SHORT get_min_value (unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ { 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));
}
@@ -401,20 +405,48 @@ struct BaseScriptRecord {
struct BaseScriptList {
- inline const BaseScript *get_baseScript_from_tag (Tag baseScriptTag) const
+ inline unsigned int get_base_script_index (Tag baseScriptTag) const
{
for (unsigned int i = 0; i < baseScriptCount; i++)
if (baseScriptRecords[i].get_tag() == baseScriptTag)
- return baseScriptRecords[i].get_baseScript();
- // we could use alphabetical order to break here
- return NULL;
+ return i;
+ return NOT_INDEXED;
+ }
+
+ 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();
+ }
+
+ inline SHORT get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+ {
+ if (unlikely(baseScriptIndex >= baseScriptCount)) return NO_COORD;
+ return baseScriptRecords[baseScriptIndex].get_base_coord(baselineTagIndex);
+ }
+
+ 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 hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir, Tag baseScriptTag) const
+ inline unsigned int get_feature_tag_index (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, Tag featureTableTag) const
{
- const BaseScript *baseScript = get_baseScript_from_tag (baseScriptTag);
- if (baseScript == NULL) return NO_COORD;
- return baseScript->get_min_value(font, dir);
+ if (unlikely(baseScriptIndex >= baseScriptCount)) return NOT_INDEXED;
+ return baseScriptRecords[baseScriptIndex].get_feature_tag_index(baseLangSysIndex, featureTableTag);
+ }
+
+ inline SHORT get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(baseScriptIndex >= baseScriptCount)) return NO_COORD;
+ return baseScriptRecords[baseScriptIndex].get_max_value(baseLangSysIndex, featureTableTagIndex);
+ }
+
+ inline SHORT get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(baseScriptIndex >= baseScriptCount)) return NO_COORD;
+ return baseScriptRecords[baseScriptIndex].get_min_value(baseLangSysIndex, featureTableTagIndex);
}
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -436,12 +468,12 @@ struct BaseScriptList {
struct BaseTagList
{
- inline bool hasTag(Tag tag) const
+ inline unsigned int get_tag_index(Tag baselineTag) const
{
for (unsigned int i = 0; i < baseTagCount; i++)
- if (baselineTags[i] == tag)
- return true;
- return false;
+ if (baselineTags[i] == baselineTag)
+ return i;
+ return NOT_INDEXED;
}
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -452,7 +484,7 @@ struct BaseTagList
protected:
USHORT baseTagCount;
- ArrayOf<Tag> baselineTags; // must be in alphabetical order
+ SortedArrayOf<Tag> baselineTags;
public:
DEFINE_SIZE_ARRAY (4, baselineTags);
@@ -461,10 +493,46 @@ struct BaseTagList
struct Axis
{
- inline bool hasTag(Tag tag) 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 SHORT get_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
{
- if (unlikely(baseTagList == Null(OffsetTo<BaseTagList>))) return false;
- return (this+baseTagList).hasTag(tag);
+ if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NO_COORD;
+ 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);
+ }
+
+ inline SHORT get_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NO_COORD;
+ return (this+baseScriptList).get_max_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+ }
+
+ inline SHORT get_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(baseScriptList == Null(OffsetTo<BaseScriptList>))) return NO_COORD;
+ return (this+baseScriptList).get_min_value(baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
}
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -508,6 +576,104 @@ struct BASEFormat1_1
struct BASEFormat1_0
{
+ inline bool has_vert_axis(void)
+ { return vertAxis != Null(OffsetTo<Axis>); }
+
+ inline bool has_horiz_axis(void)
+ { return horizAxis != Null(OffsetTo<Axis>); }
+
+ // horizontal axis base coords:
+
+ 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);
+ }
+
+ inline SHORT get_horiz_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+ {
+ if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NO_COORD;
+ 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);
+ }
+
+ inline SHORT get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+ {
+ if (vertAxis == Null(OffsetTo<Axis>)) return NO_COORD;
+ 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);
+ }
+
+ inline SHORT get_horiz_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NO_COORD;
+ return (this+horizAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+ }
+
+ inline SHORT get_horiz_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(horizAxis == Null(OffsetTo<Axis>))) return NO_COORD;
+ 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);
+ }
+
+ inline SHORT get_vert_max_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NO_COORD;
+ return (this+vertAxis).get_max_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+ }
+
+ inline SHORT get_vert_min_value (unsigned int baseScriptIndex, unsigned int baseLangSysIndex, unsigned int featureTableTagIndex) const
+ {
+ if (unlikely(vertAxis == Null(OffsetTo<Axis>))) return NO_COORD;
+ return (this+vertAxis).get_min_value (baseScriptIndex, baseLangSysIndex, featureTableTagIndex);
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -529,6 +695,30 @@ struct BASE
{
static const hb_tag_t tableTag = HB_OT_TAG_BASE;
+ inline bool has_vert_axis(void)
+ { return u.format1_0.has_vert_axis(); }
+
+ inline bool has_horiz_axis(void)
+ { return u.format1_0.has_horiz_axis(); }
+
+ inline unsigned int get_horiz_base_tag_index(Tag baselineTag) const
+ { return u.format1_0.get_horiz_base_tag_index(baselineTag); }
+
+ inline unsigned int get_horiz_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
+ { return u.format1_0.get_horiz_default_base_tag_index_for_script_index(baseScriptIndex); }
+
+ inline SHORT get_horiz_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+ { return u.format1_0.get_horiz_base_coord(baseScriptIndex, baselineTagIndex); }
+
+ inline unsigned int get_vert_base_tag_index(Tag baselineTag) const
+ { return u.format1_0.get_vert_base_tag_index(baselineTag); }
+
+ inline unsigned int get_vert_default_base_tag_index_for_script_index (unsigned int baseScriptIndex) const
+ { return u.format1_0.get_vert_default_base_tag_index_for_script_index(baseScriptIndex); }
+
+ inline SHORT get_vert_base_coord(unsigned int baseScriptIndex, unsigned int baselineTagIndex) const
+ { return u.format1_0.get_vert_base_coord(baseScriptIndex, baselineTagIndex); }
+
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
@@ -537,7 +727,7 @@ struct BASE
switch (u.version.minor) {
case 0: return_trace (u.format1_0.sanitize (c));
case 1: return_trace (u.format1_1.sanitize (c));
- default:return_trace (true);
+ default:return_trace (false);
}
}
commit d34e35b47457e757781b1769a1fbaf107ec6e32f
Author: Elie Roux <elie.roux at telecom-bretagne.eu>
Date: Sat Feb 25 20:41:05 2017 +0100
BASE: WIP: more access functions
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index 75b3f2e8..c4d9ad14 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -43,12 +43,17 @@
namespace OT {
+#define NO_COORD -32767
+
/*
* BASE -- The BASE Table
*/
struct BaseCoordFormat1 {
+ inline SHORT get_coord () const
+ { return coordinate; }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -65,6 +70,9 @@ struct BaseCoordFormat1 {
struct BaseCoordFormat2 {
+ inline SHORT get_coord () const
+ { return coordinate; }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -83,6 +91,9 @@ struct BaseCoordFormat2 {
struct BaseCoordFormat3 {
+ inline SHORT get_coord (void ) const
+ { return coordinate; }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -100,6 +111,18 @@ struct BaseCoordFormat3 {
struct BaseCoord {
+ inline hb_position_t get_value (hb_font_t *font, hb_direction_t dir) const
+ {
+ SHORT coord;
+ switch (u.baseCoordFormat) {
+ case 1: coord = u.format1.get_coord();
+ case 2: coord = u.format2.get_coord();
+ case 3: coord = u.format3.get_coord();
+ default: return 0;
+ }
+ return font->em_scale (coord, dir);
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -126,6 +149,21 @@ struct BaseCoord {
struct FeatMinMaxRecord {
+ inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir) const
+ {
+ if (unlikely(minCoord == Null(OffsetTo<BaseCoord>))) return NO_COORD;
+ return (this+minCoord).get_value(font, dir);
+ }
+
+ inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir) const
+ {
+ if (unlikely(maxCoord == Null(OffsetTo<BaseCoord>))) return NO_COORD;
+ return (this+maxCoord).get_value(font, dir);
+ }
+
+ inline Tag get_tag () const
+ { return featureTableTag; }
+
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
@@ -146,6 +184,42 @@ struct FeatMinMaxRecord {
struct MinMax {
+ inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir) const
+ {
+ if (unlikely(minCoord == Null(OffsetTo<BaseCoord>))) return NO_COORD;
+ return (this+minCoord).get_value(font, dir);
+ }
+
+ inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir) const
+ {
+ if (unlikely(maxCoord == Null(OffsetTo<BaseCoord>))) return NO_COORD;
+ return (this+maxCoord).get_value(font, dir);
+ }
+
+ inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir, Tag featureTableTag) const
+ {
+ for (unsigned int i = 0; i < featMinMaxCount; i++)
+ {
+ if (featMinMaxRecords[i].get_tag() == featureTableTag)
+ return featMinMaxRecords[i].get_min_value(font, dir);
+ // we could take advantage of alphabetical order by comparing Tags, not currently possible
+ //if (featMinMaxRecords[i].get_tag() > featureTableTag)
+ // break;
+ }
+ return get_min_value (font, dir);
+ }
+
+ inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir, Tag featureTableTag) const
+ {
+ for (unsigned int i = 0; i < featMinMaxCount; i++)
+ {
+ if (featMinMaxRecords[i].get_tag() == featureTableTag)
+ return featMinMaxRecords[i].get_max_value(font, dir);
+ // we could use alphabetical order to break here
+ }
+ return get_min_value (font, dir);
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -153,13 +227,14 @@ struct MinMax {
minCoord.sanitize (c, this) &&
maxCoord.sanitize (c, this) &&
featMinMaxRecords.sanitize (c, this));
+ // TODO: test alphabetical order?
}
protected:
OffsetTo<BaseCoord> minCoord;
OffsetTo<BaseCoord> maxCoord;
USHORT featMinMaxCount;
- ArrayOf<FeatMinMaxRecord> featMinMaxRecords;
+ ArrayOf<FeatMinMaxRecord> featMinMaxRecords; /* All FeatMinMaxRecords are listed alphabetically */
public:
DEFINE_SIZE_ARRAY (8, featMinMaxRecords);
@@ -168,16 +243,32 @@ struct MinMax {
struct BaseLangSysRecord {
+ inline Tag get_tag(void) const
+ { return baseLangSysTag; }
+
+ inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir) const
+ { return (this+minMax).get_min_value(font, dir); }
+
+ inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir) const
+ { return (this+minMax).get_max_value(font, dir); }
+
+ inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir, Tag featureTableTag) const
+ { return (this+minMax).get_min_value(font, dir, featureTableTag); }
+
+ inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir, Tag featureTableTag) const
+ { return (this+minMax).get_max_value(font, dir, featureTableTag); }
+
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
+ minMax != Null(OffsetTo<MinMax>) &&
minMax.sanitize (c, base));
}
protected:
Tag baseLangSysTag;
- OffsetTo<MinMax> minMax;
+ OffsetTo<MinMax> minMax; // not supposed to be NULL
public:
DEFINE_SIZE_STATIC (6);
@@ -205,6 +296,62 @@ struct BaseValues {
struct BaseScript {
+ inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir) const
+ {
+ if (unlikely(defaultMinMax == Null(OffsetTo<MinMax>))) return NO_COORD;
+ return (this+defaultMinMax).get_min_value(font, dir);
+ }
+
+ inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir) const
+ {
+ if (unlikely(defaultMinMax == Null(OffsetTo<MinMax>))) return NO_COORD;
+ return (this+defaultMinMax).get_max_value(font, dir);
+ }
+
+ inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir, Tag baseLangSysTag) const
+ {
+ for (unsigned int i = 0; i < baseLangSysCount; i++)
+ {
+ if (baseLangSysRecords[i].get_tag() == baseLangSysTag)
+ return baseLangSysRecords[i].get_min_value(font, dir);
+ // we could use alphabetical order to break here
+ }
+ return get_min_value (font, dir);
+ }
+
+ inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir, Tag baseLangSysTag) const
+ {
+ for (unsigned int i = 0; i < baseLangSysCount; i++)
+ {
+ if (baseLangSysRecords[i].get_tag() == baseLangSysTag)
+ return baseLangSysRecords[i].get_max_value(font, dir);
+ // we could use alphabetical order to break here
+ }
+ return get_max_value (font, dir);
+ }
+
+ inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir, Tag baseLangSysTag, Tag featureTableTag) const
+ {
+ for (unsigned int i = 0; i < baseLangSysCount; i++)
+ {
+ if (baseLangSysRecords[i].get_tag() == baseLangSysTag)
+ return baseLangSysRecords[i].get_min_value(font, dir, featureTableTag);
+ // we could use alphabetical order to break here
+ }
+ return get_min_value (font, dir);
+ }
+
+ inline hb_position_t get_max_value (hb_font_t *font, hb_direction_t dir, Tag baseLangSysTag, Tag featureTableTag) const
+ {
+ for (unsigned int i = 0; i < baseLangSysCount; i++)
+ {
+ if (baseLangSysRecords[i].get_tag() == baseLangSysTag)
+ return baseLangSysRecords[i].get_max_value(font, dir);
+ // we could use alphabetical order to break here
+ }
+ return get_max_value (font, dir);
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -227,6 +374,16 @@ struct BaseScript {
struct BaseScriptRecord {
+ inline const BaseScript *get_baseScript (void) const
+ {
+ return &(this+baseScript);
+ }
+
+ inline bool get_tag (void) const
+ {
+ return baseScriptTag;
+ }
+
inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
@@ -244,6 +401,22 @@ struct BaseScriptRecord {
struct BaseScriptList {
+ inline const BaseScript *get_baseScript_from_tag (Tag baseScriptTag) const
+ {
+ for (unsigned int i = 0; i < baseScriptCount; i++)
+ if (baseScriptRecords[i].get_tag() == baseScriptTag)
+ return baseScriptRecords[i].get_baseScript();
+ // we could use alphabetical order to break here
+ return NULL;
+ }
+
+ inline hb_position_t get_min_value (hb_font_t *font, hb_direction_t dir, Tag baseScriptTag) const
+ {
+ const BaseScript *baseScript = get_baseScript_from_tag (baseScriptTag);
+ if (baseScript == NULL) return NO_COORD;
+ return baseScript->get_min_value(font, dir);
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -260,35 +433,26 @@ struct BaseScriptList {
};
-struct BaselineTag {
+struct BaseTagList
+{
- inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ inline bool hasTag(Tag tag) const
{
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this));
+ for (unsigned int i = 0; i < baseTagCount; i++)
+ if (baselineTags[i] == tag)
+ return true;
+ return false;
}
- protected:
- Tag tag;
-
- public:
- DEFINE_SIZE_STATIC (4);
-
-};
-
-struct BaseTagList
-{
-
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- baselineTags.sanitize (c, this));
+ return_trace (c->check_struct (this));
}
protected:
- USHORT baseTagCount;
- ArrayOf<BaselineTag> baselineTags;
+ USHORT baseTagCount;
+ ArrayOf<Tag> baselineTags; // must be in alphabetical order
public:
DEFINE_SIZE_ARRAY (4, baselineTags);
@@ -297,6 +461,12 @@ struct BaseTagList
struct Axis
{
+ inline bool hasTag(Tag tag) const
+ {
+ if (unlikely(baseTagList == Null(OffsetTo<BaseTagList>))) return false;
+ return (this+baseTagList).hasTag(tag);
+ }
+
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
commit bd15567ed6a3667e6f8332b7374aece6a6f2361b
Author: Elie Roux <elie.roux at telecom-bretagne.eu>
Date: Sat Feb 25 17:08:01 2017 +0100
BASE: align member's names
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index f811c4ab..75b3f2e8 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -57,7 +57,7 @@ struct BaseCoordFormat1 {
protected:
USHORT baseCoordFormat;
- SHORT coordinate;
+ SHORT coordinate;
public:
DEFINE_SIZE_STATIC (4);
@@ -73,7 +73,7 @@ struct BaseCoordFormat2 {
protected:
USHORT baseCoordFormat;
- SHORT coordinate;
+ SHORT coordinate;
USHORT referenceGlyph;
USHORT baseCoordPoint;
@@ -90,9 +90,9 @@ struct BaseCoordFormat3 {
}
protected:
- USHORT baseCoordFormat;
- SHORT coordinate;
- OffsetTo<Device> deviceTable;
+ USHORT baseCoordFormat;
+ SHORT coordinate;
+ OffsetTo<Device> deviceTable;
public:
DEFINE_SIZE_STATIC (6);
@@ -114,7 +114,7 @@ struct BaseCoord {
protected:
union {
- USHORT baseCoordFormat;
+ USHORT baseCoordFormat;
BaseCoordFormat1 format1;
BaseCoordFormat2 format2;
BaseCoordFormat3 format3;
@@ -135,7 +135,7 @@ struct FeatMinMaxRecord {
}
protected:
- Tag featureTableTag;
+ Tag featureTableTag;
OffsetTo<BaseCoord> minCoord;
OffsetTo<BaseCoord> maxCoord;
@@ -156,9 +156,9 @@ struct MinMax {
}
protected:
- OffsetTo<BaseCoord> minCoord;
- OffsetTo<BaseCoord> maxCoord;
- USHORT featMinMaxCount;
+ OffsetTo<BaseCoord> minCoord;
+ OffsetTo<BaseCoord> maxCoord;
+ USHORT featMinMaxCount;
ArrayOf<FeatMinMaxRecord> featMinMaxRecords;
public:
@@ -176,8 +176,8 @@ struct BaseLangSysRecord {
}
protected:
- Tag baseLangSysTag;
- OffsetTo<MinMax> minMax;
+ Tag baseLangSysTag;
+ OffsetTo<MinMax> minMax;
public:
DEFINE_SIZE_STATIC (6);
@@ -194,9 +194,9 @@ struct BaseValues {
}
protected:
- USHORT defaultIndex;
- USHORT baseCoordCount;
- OffsetArrayOf<BaseCoord> baseCoords;
+ USHORT defaultIndex;
+ USHORT baseCoordCount;
+ OffsetArrayOf<BaseCoord> baseCoords;
public:
DEFINE_SIZE_ARRAY (6, baseCoords);
@@ -215,10 +215,10 @@ struct BaseScript {
}
protected:
- OffsetTo<BaseValues> baseValues;
- OffsetTo<MinMax> defaultMinMax;
- USHORT baseLangSysCount;
- ArrayOf<BaseLangSysRecord> baseLangSysRecords;
+ OffsetTo<BaseValues> baseValues;
+ OffsetTo<MinMax> defaultMinMax;
+ USHORT baseLangSysCount;
+ ArrayOf<BaseLangSysRecord> baseLangSysRecords;
public:
DEFINE_SIZE_ARRAY (8, baseLangSysRecords);
@@ -235,8 +235,8 @@ struct BaseScriptRecord {
}
protected:
- Tag baseScriptTag;
- OffsetTo<BaseScript> baseScript;
+ Tag baseScriptTag;
+ OffsetTo<BaseScript> baseScript;
public:
DEFINE_SIZE_STATIC (6);
@@ -252,7 +252,7 @@ struct BaseScriptList {
}
protected:
- USHORT baseScriptCount;
+ USHORT baseScriptCount;
ArrayOf<BaseScriptRecord> baseScriptRecords;
public:
@@ -287,8 +287,8 @@ struct BaseTagList
}
protected:
- USHORT baseTagCount;
- ArrayOf<BaselineTag> baselineTags;
+ USHORT baseTagCount;
+ ArrayOf<BaselineTag> baselineTags;
public:
DEFINE_SIZE_ARRAY (4, baselineTags);
@@ -306,8 +306,8 @@ struct Axis
}
protected:
- OffsetTo<BaseTagList> baseTagList;
- OffsetTo<BaseScriptList> baseScriptList;
+ OffsetTo<BaseTagList> baseTagList;
+ OffsetTo<BaseScriptList> baseScriptList;
public:
DEFINE_SIZE_STATIC (4);
@@ -326,9 +326,9 @@ struct BASEFormat1_1
}
protected:
- FixedVersion<>version;
- OffsetTo<Axis> horizAxis;
- OffsetTo<Axis> vertAxis;
+ FixedVersion<> version;
+ OffsetTo<Axis> horizAxis;
+ OffsetTo<Axis> vertAxis;
LOffsetTo<VariationStore> itemVarStore;
public:
@@ -347,9 +347,9 @@ struct BASEFormat1_0
}
protected:
- FixedVersion<>version;
- OffsetTo<Axis> horizAxis;
- OffsetTo<Axis> vertAxis;
+ FixedVersion<> version;
+ OffsetTo<Axis> horizAxis;
+ OffsetTo<Axis> vertAxis;
public:
DEFINE_SIZE_STATIC (8);
@@ -373,9 +373,9 @@ struct BASE
protected:
union {
- FixedVersion<>version; /* Version of the BASE table: 1.0 or 1.1 */
- BASEFormat1_0 format1_0;
- BASEFormat1_1 format1_1;
+ FixedVersion<> version; /* Version of the BASE table: 1.0 or 1.1 */
+ BASEFormat1_0 format1_0;
+ BASEFormat1_1 format1_1;
} u;
public:
commit 499b4bef2a5b6d49374ab4977509d1fbf7bd6038
Author: Elie Roux <elie.roux at telecom-bretagne.eu>
Date: Sat Feb 25 16:48:22 2017 +0100
BASE: more consistent naming (with spec and Harfbuzz code base)
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index 059c8f71..f811c4ab 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -144,7 +144,7 @@ struct FeatMinMaxRecord {
};
-struct MinMaxTable {
+struct MinMax {
inline bool sanitize (hb_sanitize_context_t *c) const
{
@@ -152,17 +152,17 @@ struct MinMaxTable {
return_trace (c->check_struct (this) &&
minCoord.sanitize (c, this) &&
maxCoord.sanitize (c, this) &&
- featMinMaxRecordTable.sanitize (c, this));
+ featMinMaxRecords.sanitize (c, this));
}
protected:
OffsetTo<BaseCoord> minCoord;
OffsetTo<BaseCoord> maxCoord;
USHORT featMinMaxCount;
- ArrayOf<FeatMinMaxRecord> featMinMaxRecordTable;
+ ArrayOf<FeatMinMaxRecord> featMinMaxRecords;
public:
- DEFINE_SIZE_ARRAY (8, featMinMaxRecordTable);
+ DEFINE_SIZE_ARRAY (8, featMinMaxRecords);
};
@@ -177,33 +177,33 @@ struct BaseLangSysRecord {
protected:
Tag baseLangSysTag;
- OffsetTo<MinMaxTable> minMax;
+ OffsetTo<MinMax> minMax;
public:
DEFINE_SIZE_STATIC (6);
};
-struct BaseValuesTable {
+struct BaseValues {
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
- baseCoordTable.sanitize (c, this));
+ baseCoords.sanitize (c, this));
}
protected:
USHORT defaultIndex;
USHORT baseCoordCount;
- OffsetArrayOf<BaseCoord> baseCoordTable;
+ OffsetArrayOf<BaseCoord> baseCoords;
public:
- DEFINE_SIZE_ARRAY (6, baseCoordTable);
+ DEFINE_SIZE_ARRAY (6, baseCoords);
};
-struct BaseScriptTable {
+struct BaseScript {
inline bool sanitize (hb_sanitize_context_t *c) const
{
@@ -211,17 +211,17 @@ struct BaseScriptTable {
return_trace (c->check_struct (this) &&
baseValues.sanitize (c, this) &&
defaultMinMax.sanitize (c, this) &&
- baseLangSysRecordTable.sanitize (c, this));
+ baseLangSysRecords.sanitize (c, this));
}
protected:
- OffsetTo<BaseValuesTable> baseValues;
- OffsetTo<MinMaxTable> defaultMinMax;
+ OffsetTo<BaseValues> baseValues;
+ OffsetTo<MinMax> defaultMinMax;
USHORT baseLangSysCount;
- ArrayOf<BaseLangSysRecord> baseLangSysRecordTable;
+ ArrayOf<BaseLangSysRecord> baseLangSysRecords;
public:
- DEFINE_SIZE_ARRAY (8, baseLangSysRecordTable);
+ DEFINE_SIZE_ARRAY (8, baseLangSysRecords);
};
@@ -236,7 +236,7 @@ struct BaseScriptRecord {
protected:
Tag baseScriptTag;
- OffsetTo<BaseScriptTable> baseScript;
+ OffsetTo<BaseScript> baseScript;
public:
DEFINE_SIZE_STATIC (6);
@@ -248,15 +248,15 @@ struct BaseScriptList {
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
- baseScriptRecordTable.sanitize (c, this));
+ baseScriptRecords.sanitize (c, this));
}
protected:
USHORT baseScriptCount;
- ArrayOf<BaseScriptRecord> baseScriptRecordTable;
+ ArrayOf<BaseScriptRecord> baseScriptRecords;
public:
- DEFINE_SIZE_ARRAY (4, baseScriptRecordTable);
+ DEFINE_SIZE_ARRAY (4, baseScriptRecords);
};
@@ -283,15 +283,15 @@ struct BaseTagList
{
TRACE_SANITIZE (this);
return_trace (c->check_struct (this) &&
- baseTagListTable.sanitize (c, this));
+ baselineTags.sanitize (c, this));
}
protected:
USHORT baseTagCount;
- ArrayOf<BaselineTag> baseTagListTable;
+ ArrayOf<BaselineTag> baselineTags;
public:
- DEFINE_SIZE_ARRAY (4, baseTagListTable);
+ DEFINE_SIZE_ARRAY (4, baselineTags);
};
struct Axis
commit a0bdd546c584eb7c7ea3ca7e19a178723e6fe77f
Author: Elie Roux <elie.roux at telecom-bretagne.eu>
Date: Sat Feb 25 16:34:58 2017 +0100
factorize horiz+vertAxis
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index 691b9db1..059c8f71 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -100,7 +100,6 @@ struct BaseCoordFormat3 {
struct BaseCoord {
-
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
@@ -295,7 +294,7 @@ struct BaseTagList
DEFINE_SIZE_ARRAY (4, baseTagListTable);
};
-struct VertAxis
+struct Axis
{
inline bool sanitize (hb_sanitize_context_t *c) const
@@ -314,26 +313,6 @@ struct VertAxis
DEFINE_SIZE_STATIC (4);
};
-struct HorizAxis
-{
-
- inline bool sanitize (hb_sanitize_context_t *c) const
- {
- TRACE_SANITIZE (this);
- return_trace (c->check_struct (this) &&
- baseTagList.sanitize (c, this) &&
- baseScriptList.sanitize (c, this));
- }
-
- protected:
- OffsetTo<HorizAxis> baseTagList;
- OffsetTo<VertAxis> baseScriptList;
-
- public:
- DEFINE_SIZE_STATIC (4);
-};
-
-
struct BASEFormat1_1
{
@@ -348,8 +327,8 @@ struct BASEFormat1_1
protected:
FixedVersion<>version;
- OffsetTo<HorizAxis> horizAxis;
- OffsetTo<VertAxis> vertAxis;
+ OffsetTo<Axis> horizAxis;
+ OffsetTo<Axis> vertAxis;
LOffsetTo<VariationStore> itemVarStore;
public:
@@ -369,8 +348,8 @@ struct BASEFormat1_0
protected:
FixedVersion<>version;
- OffsetTo<HorizAxis> horizAxis;
- OffsetTo<VertAxis> vertAxis;
+ OffsetTo<Axis> horizAxis;
+ OffsetTo<Axis> vertAxis;
public:
DEFINE_SIZE_STATIC (8);
commit 1d30c6d935535743c73b2d18abcc6ae86a1cfc5b
Author: Elie Roux <elie.roux at telecom-bretagne.eu>
Date: Sat Feb 25 16:19:35 2017 +0100
BASE: sanitize
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index b3c0927b..691b9db1 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -48,6 +48,13 @@ namespace OT {
*/
struct BaseCoordFormat1 {
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
protected:
USHORT baseCoordFormat;
SHORT coordinate;
@@ -57,6 +64,13 @@ struct BaseCoordFormat1 {
};
struct BaseCoordFormat2 {
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
protected:
USHORT baseCoordFormat;
SHORT coordinate;
@@ -68,6 +82,13 @@ struct BaseCoordFormat2 {
};
struct BaseCoordFormat3 {
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) && deviceTable.sanitize (c, this));
+ }
+
protected:
USHORT baseCoordFormat;
SHORT coordinate;
@@ -78,6 +99,20 @@ struct BaseCoordFormat3 {
};
struct BaseCoord {
+
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ if (!u.baseCoordFormat.sanitize (c)) return_trace (false);
+ switch (u.baseCoordFormat) {
+ case 1: return_trace (u.format1.sanitize (c));
+ case 2: return_trace (u.format2.sanitize (c));
+ case 3: return_trace (u.format3.sanitize (c));
+ default:return_trace (true);
+ }
+ }
+
protected:
union {
USHORT baseCoordFormat;
@@ -91,6 +126,15 @@ struct BaseCoord {
};
struct FeatMinMaxRecord {
+
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ minCoord.sanitize (c, base) &&
+ maxCoord.sanitize (c, base));
+ }
+
protected:
Tag featureTableTag;
OffsetTo<BaseCoord> minCoord;
@@ -102,6 +146,16 @@ struct FeatMinMaxRecord {
};
struct MinMaxTable {
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ minCoord.sanitize (c, this) &&
+ maxCoord.sanitize (c, this) &&
+ featMinMaxRecordTable.sanitize (c, this));
+ }
+
protected:
OffsetTo<BaseCoord> minCoord;
OffsetTo<BaseCoord> maxCoord;
@@ -114,6 +168,14 @@ struct MinMaxTable {
};
struct BaseLangSysRecord {
+
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ minMax.sanitize (c, base));
+ }
+
protected:
Tag baseLangSysTag;
OffsetTo<MinMaxTable> minMax;
@@ -124,6 +186,14 @@ struct BaseLangSysRecord {
};
struct BaseValuesTable {
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ baseCoordTable.sanitize (c, this));
+ }
+
protected:
USHORT defaultIndex;
USHORT baseCoordCount;
@@ -135,6 +205,16 @@ struct BaseValuesTable {
};
struct BaseScriptTable {
+
+ 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) &&
+ baseLangSysRecordTable.sanitize (c, this));
+ }
+
protected:
OffsetTo<BaseValuesTable> baseValues;
OffsetTo<MinMaxTable> defaultMinMax;
@@ -148,6 +228,13 @@ struct BaseScriptTable {
struct BaseScriptRecord {
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ baseScript.sanitize (c, base));
+ }
+
protected:
Tag baseScriptTag;
OffsetTo<BaseScriptTable> baseScript;
@@ -158,6 +245,13 @@ struct BaseScriptRecord {
struct BaseScriptList {
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ baseScriptRecordTable.sanitize (c, this));
+ }
+
protected:
USHORT baseScriptCount;
ArrayOf<BaseScriptRecord> baseScriptRecordTable;
@@ -169,6 +263,12 @@ struct BaseScriptList {
struct BaselineTag {
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this));
+ }
+
protected:
Tag tag;
@@ -180,6 +280,13 @@ struct BaselineTag {
struct BaseTagList
{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ baseTagListTable.sanitize (c, this));
+ }
+
protected:
USHORT baseTagCount;
ArrayOf<BaselineTag> baseTagListTable;
@@ -191,6 +298,14 @@ struct BaseTagList
struct VertAxis
{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ baseTagList.sanitize (c, this) &&
+ baseScriptList.sanitize (c, this));
+ }
+
protected:
OffsetTo<BaseTagList> baseTagList;
OffsetTo<BaseScriptList> baseScriptList;
@@ -202,6 +317,14 @@ struct VertAxis
struct HorizAxis
{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ baseTagList.sanitize (c, this) &&
+ baseScriptList.sanitize (c, this));
+ }
+
protected:
OffsetTo<HorizAxis> baseTagList;
OffsetTo<VertAxis> baseScriptList;
@@ -214,6 +337,15 @@ struct HorizAxis
struct BASEFormat1_1
{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ horizAxis.sanitize (c, this) &&
+ vertAxis.sanitize (c, this) &&
+ itemVarStore.sanitize (c, this));
+ }
+
protected:
FixedVersion<>version;
OffsetTo<HorizAxis> horizAxis;
@@ -227,6 +359,14 @@ struct BASEFormat1_1
struct BASEFormat1_0
{
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (c->check_struct (this) &&
+ horizAxis.sanitize (c, this) &&
+ vertAxis.sanitize (c, this));
+ }
+
protected:
FixedVersion<>version;
OffsetTo<HorizAxis> horizAxis;
@@ -240,11 +380,16 @@ struct BASE
{
static const hb_tag_t tableTag = HB_OT_TAG_BASE;
- inline bool sanitize (hb_sanitize_context_t *c) const
+ inline bool sanitize (hb_sanitize_context_t *c, const void *base) const
{
TRACE_SANITIZE (this);
- return_trace (u.version.sanitize (c) &&
- likely (u.version.major == 1));
+ if (!u.version.sanitize (c)) return_trace (false);
+ if (!likely(u.version.major == 1)) return_trace (false);
+ switch (u.version.minor) {
+ case 0: return_trace (u.format1_0.sanitize (c));
+ case 1: return_trace (u.format1_1.sanitize (c));
+ default:return_trace (true);
+ }
}
protected:
commit f131f00b1779b44633223915e17cbce358ad063a
Author: Elie Roux <elie.roux at telecom-bretagne.eu>
Date: Sun Feb 19 10:12:22 2017 +0100
compile, move into hb-ot-layout.cc
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index acbda8de..009db20a 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -30,7 +30,6 @@
#include "hb-font-private.hh"
-#include "hb-ot-layout-base-table.hh"
#include "hb-ot-cmap-table.hh"
#include "hb-ot-cbdt-table.hh"
#include "hb-ot-glyf-table.hh"
diff --git a/src/hb-ot-layout-base-table.hh b/src/hb-ot-layout-base-table.hh
index 8ad01fe3..b3c0927b 100644
--- a/src/hb-ot-layout-base-table.hh
+++ b/src/hb-ot-layout-base-table.hh
@@ -109,7 +109,7 @@ struct MinMaxTable {
ArrayOf<FeatMinMaxRecord> featMinMaxRecordTable;
public:
- DEFINE_SIZE_ARRAY (6, featMinMaxRecordTable);
+ DEFINE_SIZE_ARRAY (8, featMinMaxRecordTable);
};
@@ -127,10 +127,10 @@ struct BaseValuesTable {
protected:
USHORT defaultIndex;
USHORT baseCoordCount;
- ArrayOf<BaseCoord> baseCoordTable;
+ OffsetArrayOf<BaseCoord> baseCoordTable;
public:
- DEFINE_SIZE_ARRAY (4, baseCoordTable);
+ DEFINE_SIZE_ARRAY (6, baseCoordTable);
};
@@ -142,7 +142,7 @@ struct BaseScriptTable {
ArrayOf<BaseLangSysRecord> baseLangSysRecordTable;
public:
- DEFINE_SIZE_ARRAY (6, baseLangSysRecordTable);
+ DEFINE_SIZE_ARRAY (8, baseLangSysRecordTable);
};
@@ -153,7 +153,7 @@ struct BaseScriptRecord {
OffsetTo<BaseScriptTable> baseScript;
public:
- DEFINE_SIZE_STATIC (4);
+ DEFINE_SIZE_STATIC (6);
};
struct BaseScriptList {
@@ -163,7 +163,7 @@ struct BaseScriptList {
ArrayOf<BaseScriptRecord> baseScriptRecordTable;
public:
- DEFINE_SIZE_ARRAY (2, baseScriptRecordTable);
+ DEFINE_SIZE_ARRAY (4, baseScriptRecordTable);
};
@@ -182,10 +182,10 @@ struct BaseTagList
protected:
USHORT baseTagCount;
- ArrayOf<BaselineTag> BaseTagListTable;
+ ArrayOf<BaselineTag> baseTagListTable;
public:
- DEFINE_SIZE_STATIC (4);
+ DEFINE_SIZE_ARRAY (4, baseTagListTable);
};
struct VertAxis
@@ -210,6 +210,32 @@ struct HorizAxis
DEFINE_SIZE_STATIC (4);
};
+
+struct BASEFormat1_1
+{
+
+ protected:
+ FixedVersion<>version;
+ OffsetTo<HorizAxis> horizAxis;
+ OffsetTo<VertAxis> vertAxis;
+ LOffsetTo<VariationStore> itemVarStore;
+
+ public:
+ DEFINE_SIZE_STATIC (12);
+};
+
+struct BASEFormat1_0
+{
+
+ protected:
+ FixedVersion<>version;
+ OffsetTo<HorizAxis> horizAxis;
+ OffsetTo<VertAxis> vertAxis;
+
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
struct BASE
{
static const hb_tag_t tableTag = HB_OT_TAG_BASE;
@@ -217,18 +243,19 @@ struct BASE
inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
- return_trace (version.sanitize (c) &&
- likely (version.major == 1));
+ return_trace (u.version.sanitize (c) &&
+ likely (u.version.major == 1));
}
protected:
- FixedVersion<>version; /* Version of the BASE table: 1.0 or 1.1 */
- OffsetTo<HorizAxis> horizAxis;
- OffsetTo<VertAxis> vertAxis;
- //LOffsetTo<ItemVarStore> itemVarStore;
+ union {
+ FixedVersion<>version; /* Version of the BASE table: 1.0 or 1.1 */
+ BASEFormat1_0 format1_0;
+ BASEFormat1_1 format1_1;
+ } u;
public:
- DEFINE_SIZE_MIN (6);
+ DEFINE_SIZE_UNION (4, version);
};
diff --git a/src/hb-ot-layout.cc b/src/hb-ot-layout.cc
index a1682a5f..3511810a 100644
--- a/src/hb-ot-layout.cc
+++ b/src/hb-ot-layout.cc
@@ -31,6 +31,7 @@
#include "hb-open-type-private.hh"
#include "hb-ot-layout-private.hh"
+#include "hb-ot-layout-base-table.hh"
#include "hb-ot-layout-gdef-table.hh"
#include "hb-ot-layout-gsub-table.hh"
#include "hb-ot-layout-gpos-table.hh"
commit d0b97353e930d9b258f42f1cc1ac1a75306b76a8
Author: Elie Roux <elie.roux at telecom-bretagne.eu>
Date: Sun Feb 19 08:48:22 2017 +0100
hb-ot-base-table.hh -> hb-ot-layout-base-table.hh
per https://github.com/behdad/harfbuzz/issues/418#issuecomment-280873811
diff --git a/src/Makefile.sources b/src/Makefile.sources
index 20ce77b8..0f83f6eb 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -68,9 +68,9 @@ HB_NODIST_headers = \
HB_FALLBACK_sources = hb-fallback-shape.cc
HB_OT_sources = \
- hb-ot-base-table.hh \
hb-ot-font.cc \
hb-ot-layout.cc \
+ hb-ot-layout-base-table.hh \
hb-ot-layout-common-private.hh \
hb-ot-layout-gdef-table.hh \
hb-ot-layout-gpos-table.hh \
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 9abdc675..acbda8de 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -30,7 +30,7 @@
#include "hb-font-private.hh"
-#include "hb-ot-base-table.hh"
+#include "hb-ot-layout-base-table.hh"
#include "hb-ot-cmap-table.hh"
#include "hb-ot-cbdt-table.hh"
#include "hb-ot-glyf-table.hh"
diff --git a/src/hb-ot-base-table.hh b/src/hb-ot-layout-base-table.hh
similarity index 100%
rename from src/hb-ot-base-table.hh
rename to src/hb-ot-layout-base-table.hh
commit f748e11645a3361f94d6fb10ce59febbaa5ba8ca
Author: Elie Roux <elie.roux at telecom-bretagne.eu>
Date: Sat Feb 18 19:54:33 2017 +0100
bootstraping structure
diff --git a/src/Makefile.sources b/src/Makefile.sources
index 6363cf93..20ce77b8 100644
--- a/src/Makefile.sources
+++ b/src/Makefile.sources
@@ -68,6 +68,7 @@ HB_NODIST_headers = \
HB_FALLBACK_sources = hb-fallback-shape.cc
HB_OT_sources = \
+ hb-ot-base-table.hh \
hb-ot-font.cc \
hb-ot-layout.cc \
hb-ot-layout-common-private.hh \
diff --git a/src/hb-ot-base-table.hh b/src/hb-ot-base-table.hh
new file mode 100644
index 00000000..8ad01fe3
--- /dev/null
+++ b/src/hb-ot-base-table.hh
@@ -0,0 +1,238 @@
+/*
+ * Copyright © 2016 Elie Roux <elie.roux at telecom-bretagne.eu>
+ *
+ * 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.
+ *
+ */
+
+#ifndef HB_OT_BASE_TABLE_HH
+#define HB_OT_BASE_TABLE_HH
+
+#include "hb-open-type-private.hh"
+#include "hb-ot-layout-common-private.hh"
+
+#define HB_OT_TAG_BASE HB_TAG('B','A','S','E')
+
+// https://www.microsoft.com/typography/otspec/baselinetags.htm
+
+#define HB_OT_TAG_BASE_HANG HB_TAG('h','a','n','g')
+#define HB_OT_TAG_BASE_ICFB HB_TAG('i','c','f','b')
+#define HB_OT_TAG_BASE_ICFT HB_TAG('i','c','f','t')
+#define HB_OT_TAG_BASE_IDEO HB_TAG('i','d','e','o')
+#define HB_OT_TAG_BASE_IDTB HB_TAG('i','d','t','b')
+#define HB_OT_TAG_BASE_MATH HB_TAG('m','a','t','h')
+#define HB_OT_TAG_BASE_ROMN HB_TAG('r','o','m','n')
+
+namespace OT {
+
+/*
+ * BASE -- The BASE Table
+ */
+
+struct BaseCoordFormat1 {
+ protected:
+ USHORT baseCoordFormat;
+ SHORT coordinate;
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct BaseCoordFormat2 {
+ protected:
+ USHORT baseCoordFormat;
+ SHORT coordinate;
+ USHORT referenceGlyph;
+ USHORT baseCoordPoint;
+
+ public:
+ DEFINE_SIZE_STATIC (8);
+};
+
+struct BaseCoordFormat3 {
+ protected:
+ USHORT baseCoordFormat;
+ SHORT coordinate;
+ OffsetTo<Device> deviceTable;
+
+ public:
+ DEFINE_SIZE_STATIC (6);
+};
+
+struct BaseCoord {
+ protected:
+ union {
+ USHORT baseCoordFormat;
+ BaseCoordFormat1 format1;
+ BaseCoordFormat2 format2;
+ BaseCoordFormat3 format3;
+ } u;
+
+ public:
+ DEFINE_SIZE_MIN (4);
+};
+
+struct FeatMinMaxRecord {
+ protected:
+ Tag featureTableTag;
+ OffsetTo<BaseCoord> minCoord;
+ OffsetTo<BaseCoord> maxCoord;
+
+ public:
+ DEFINE_SIZE_STATIC (8);
+
+};
+
+struct MinMaxTable {
+ protected:
+ OffsetTo<BaseCoord> minCoord;
+ OffsetTo<BaseCoord> maxCoord;
+ USHORT featMinMaxCount;
+ ArrayOf<FeatMinMaxRecord> featMinMaxRecordTable;
+
+ public:
+ DEFINE_SIZE_ARRAY (6, featMinMaxRecordTable);
+
+};
+
+struct BaseLangSysRecord {
+ protected:
+ Tag baseLangSysTag;
+ OffsetTo<MinMaxTable> minMax;
+
+ public:
+ DEFINE_SIZE_STATIC (6);
+
+};
+
+struct BaseValuesTable {
+ protected:
+ USHORT defaultIndex;
+ USHORT baseCoordCount;
+ ArrayOf<BaseCoord> baseCoordTable;
+
+ public:
+ DEFINE_SIZE_ARRAY (4, baseCoordTable);
+
+};
+
+struct BaseScriptTable {
+ protected:
+ OffsetTo<BaseValuesTable> baseValues;
+ OffsetTo<MinMaxTable> defaultMinMax;
+ USHORT baseLangSysCount;
+ ArrayOf<BaseLangSysRecord> baseLangSysRecordTable;
+
+ public:
+ DEFINE_SIZE_ARRAY (6, baseLangSysRecordTable);
+};
+
+
+struct BaseScriptRecord {
+
+ protected:
+ Tag baseScriptTag;
+ OffsetTo<BaseScriptTable> baseScript;
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct BaseScriptList {
+
+ protected:
+ USHORT baseScriptCount;
+ ArrayOf<BaseScriptRecord> baseScriptRecordTable;
+
+ public:
+ DEFINE_SIZE_ARRAY (2, baseScriptRecordTable);
+
+};
+
+struct BaselineTag {
+
+ protected:
+ Tag tag;
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+
+};
+
+struct BaseTagList
+{
+
+ protected:
+ USHORT baseTagCount;
+ ArrayOf<BaselineTag> BaseTagListTable;
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct VertAxis
+{
+
+ protected:
+ OffsetTo<BaseTagList> baseTagList;
+ OffsetTo<BaseScriptList> baseScriptList;
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct HorizAxis
+{
+
+ protected:
+ OffsetTo<HorizAxis> baseTagList;
+ OffsetTo<VertAxis> baseScriptList;
+
+ public:
+ DEFINE_SIZE_STATIC (4);
+};
+
+struct BASE
+{
+ static const hb_tag_t tableTag = HB_OT_TAG_BASE;
+
+ inline bool sanitize (hb_sanitize_context_t *c) const
+ {
+ TRACE_SANITIZE (this);
+ return_trace (version.sanitize (c) &&
+ likely (version.major == 1));
+ }
+
+ protected:
+ FixedVersion<>version; /* Version of the BASE table: 1.0 or 1.1 */
+ OffsetTo<HorizAxis> horizAxis;
+ OffsetTo<VertAxis> vertAxis;
+ //LOffsetTo<ItemVarStore> itemVarStore;
+
+ public:
+ DEFINE_SIZE_MIN (6);
+};
+
+
+} /* namespace OT */
+
+
+#endif /* HB_OT_BASE_TABLE_HH */
diff --git a/src/hb-ot-font.cc b/src/hb-ot-font.cc
index 009db20a..9abdc675 100644
--- a/src/hb-ot-font.cc
+++ b/src/hb-ot-font.cc
@@ -30,6 +30,7 @@
#include "hb-font-private.hh"
+#include "hb-ot-base-table.hh"
#include "hb-ot-cmap-table.hh"
#include "hb-ot-cbdt-table.hh"
#include "hb-ot-glyf-table.hh"
diff --git a/src/hb-ot-layout-private.hh b/src/hb-ot-layout-private.hh
index 071a439d..ee8e1373 100644
--- a/src/hb-ot-layout-private.hh
+++ b/src/hb-ot-layout-private.hh
@@ -122,6 +122,7 @@ hb_ot_layout_position_finish_offsets (hb_font_t *font,
*/
namespace OT {
+ struct BASE;
struct GDEF;
struct GSUB;
struct GPOS;
@@ -162,6 +163,7 @@ struct hb_ot_layout_t
const struct OT::GPOS *gpos;
/* TODO Move the following out of this struct. */
+ OT::hb_lazy_table_loader_t<struct OT::BASE> base;
OT::hb_lazy_table_loader_t<struct OT::MATH> math;
OT::hb_lazy_table_loader_t<struct OT::fvar> fvar;
OT::hb_lazy_table_loader_t<struct OT::avar> avar;
More information about the HarfBuzz
mailing list