< prev index next >
src/java.desktop/share/native/libfontmanager/harfbuzz/hb-ot-glyf-table.hh
Print this page
*** 25,39 ****
*/
#ifndef HB_OT_GLYF_TABLE_HH
#define HB_OT_GLYF_TABLE_HH
! #include "hb-open-type-private.hh"
#include "hb-ot-head-table.hh"
#include "hb-subset-glyf.hh"
- #include "hb-subset-plan.hh"
- #include "hb-subset-private.hh"
namespace OT {
/*
--- 25,37 ----
*/
#ifndef HB_OT_GLYF_TABLE_HH
#define HB_OT_GLYF_TABLE_HH
! #include "hb-open-type.hh"
#include "hb-ot-head-table.hh"
#include "hb-subset-glyf.hh"
namespace OT {
/*
*** 45,65 ****
struct loca
{
friend struct glyf;
! static const hb_tag_t tableTag = HB_OT_TAG_loca;
! inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
return_trace (true);
}
protected:
! HBUINT8 dataZ[VAR]; /* Location data. */
! DEFINE_SIZE_ARRAY (0, dataZ);
};
/*
* glyf -- TrueType Glyph Data
--- 43,66 ----
struct loca
{
friend struct glyf;
! static constexpr hb_tag_t tableTag = HB_OT_TAG_loca;
! bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
{
TRACE_SANITIZE (this);
return_trace (true);
}
protected:
! UnsizedArrayOf<HBUINT8> dataZ; /* Location data. */
! public:
! DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
! * check the size externally, allow Null() object of it by
! * defining it MIN() instead. */
};
/*
* glyf -- TrueType Glyph Data
*** 68,88 ****
#define HB_OT_TAG_glyf HB_TAG('g','l','y','f')
struct glyf
{
! static const hb_tag_t tableTag = HB_OT_TAG_glyf;
! inline bool sanitize (hb_sanitize_context_t *c) const
{
TRACE_SANITIZE (this);
/* We don't check for anything specific here. The users of the
* struct do all the hard work... */
return_trace (true);
}
! inline bool subset (hb_subset_plan_t *plan) const
{
hb_blob_t *glyf_prime = nullptr;
hb_blob_t *loca_prime = nullptr;
bool success = true;
--- 69,89 ----
#define HB_OT_TAG_glyf HB_TAG('g','l','y','f')
struct glyf
{
! static constexpr hb_tag_t tableTag = HB_OT_TAG_glyf;
! bool sanitize (hb_sanitize_context_t *c HB_UNUSED) const
{
TRACE_SANITIZE (this);
/* We don't check for anything specific here. The users of the
* struct do all the hard work... */
return_trace (true);
}
! bool subset (hb_subset_plan_t *plan) const
{
hb_blob_t *glyf_prime = nullptr;
hb_blob_t *loca_prime = nullptr;
bool success = true;
*** 101,118 ****
}
static bool
_add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
{
! hb_blob_t *head_blob = OT::Sanitizer<OT::head>().sanitize (hb_face_reference_table (plan->source, HB_OT_TAG_head));
hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
hb_blob_destroy (head_blob);
if (unlikely (!head_prime_blob))
return false;
! OT::head *head_prime = (OT::head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
head_prime->indexToLocFormat.set (use_short_loca ? 0 : 1);
bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);
hb_blob_destroy (head_prime_blob);
return success;
--- 102,119 ----
}
static bool
_add_head_and_set_loca_version (hb_subset_plan_t *plan, bool use_short_loca)
{
! hb_blob_t *head_blob = hb_sanitize_context_t ().reference_table<head> (plan->source);
hb_blob_t *head_prime_blob = hb_blob_copy_writable_or_fail (head_blob);
hb_blob_destroy (head_blob);
if (unlikely (!head_prime_blob))
return false;
! head *head_prime = (head *) hb_blob_get_data_writable (head_prime_blob, nullptr);
head_prime->indexToLocFormat.set (use_short_loca ? 0 : 1);
bool success = plan->add_table (HB_OT_TAG_head, head_prime_blob);
hb_blob_destroy (head_prime_blob);
return success;
*** 148,189 ****
SCALED_COMPONENT_OFFSET = 0x0800,
UNSCALED_COMPONENT_OFFSET = 0x1000
};
HBUINT16 flags;
! HBUINT16 glyphIndex;
! inline unsigned int get_size (void) const
{
unsigned int size = min_size;
- if (flags & ARG_1_AND_2_ARE_WORDS) {
// arg1 and 2 are int16
! size += 4;
! } else {
// arg1 and 2 are int8
! size += 2;
! }
! if (flags & WE_HAVE_A_SCALE) {
// One x 16 bit (scale)
! size += 2;
! } else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) {
// Two x 16 bit (xscale, yscale)
! size += 4;
! } else if (flags & WE_HAVE_A_TWO_BY_TWO) {
// Four x 16 bit (xscale, scale01, scale10, yscale)
! size += 8;
! }
return size;
}
struct Iterator
{
const char *glyph_start;
const char *glyph_end;
const CompositeGlyphHeader *current;
! inline bool move_to_next ()
{
if (current->flags & CompositeGlyphHeader::MORE_COMPONENTS)
{
const CompositeGlyphHeader *possible =
&StructAfter<CompositeGlyphHeader, CompositeGlyphHeader> (*current);
--- 149,185 ----
SCALED_COMPONENT_OFFSET = 0x0800,
UNSCALED_COMPONENT_OFFSET = 0x1000
};
HBUINT16 flags;
! GlyphID glyphIndex;
! unsigned int get_size () const
{
unsigned int size = min_size;
// arg1 and 2 are int16
! if (flags & ARG_1_AND_2_ARE_WORDS) size += 4;
// arg1 and 2 are int8
! else size += 2;
!
// One x 16 bit (scale)
! if (flags & WE_HAVE_A_SCALE) size += 2;
// Two x 16 bit (xscale, yscale)
! else if (flags & WE_HAVE_AN_X_AND_Y_SCALE) size += 4;
// Four x 16 bit (xscale, scale01, scale10, yscale)
! else if (flags & WE_HAVE_A_TWO_BY_TWO) size += 8;
!
return size;
}
struct Iterator
{
const char *glyph_start;
const char *glyph_end;
const CompositeGlyphHeader *current;
! bool move_to_next ()
{
if (current->flags & CompositeGlyphHeader::MORE_COMPONENTS)
{
const CompositeGlyphHeader *possible =
&StructAfter<CompositeGlyphHeader, CompositeGlyphHeader> (*current);
*** 193,211 ****
return true;
}
return false;
}
! inline bool in_range (const CompositeGlyphHeader *composite) const
{
return (const char *) composite >= glyph_start
&& ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end
! && ((const char *) composite + composite->get_size()) <= glyph_end;
}
};
! static inline bool get_iterator (const char * glyph_data,
unsigned int length,
CompositeGlyphHeader::Iterator *iterator /* OUT */)
{
if (length < GlyphHeader::static_size)
return false; /* Empty glyph; zero extents. */
--- 189,207 ----
return true;
}
return false;
}
! bool in_range (const CompositeGlyphHeader *composite) const
{
return (const char *) composite >= glyph_start
&& ((const char *) composite + CompositeGlyphHeader::min_size) <= glyph_end
! && ((const char *) composite + composite->get_size ()) <= glyph_end;
}
};
! static bool get_iterator (const char * glyph_data,
unsigned int length,
CompositeGlyphHeader::Iterator *iterator /* OUT */)
{
if (length < GlyphHeader::static_size)
return false; /* Empty glyph; zero extents. */
*** 230,303 ****
DEFINE_SIZE_MIN (4);
};
struct accelerator_t
{
! inline void init (hb_face_t *face)
{
memset (this, 0, sizeof (accelerator_t));
! hb_blob_t *head_blob = Sanitizer<head>().sanitize (face->reference_table (HB_OT_TAG_head));
! const head *head_table = head_blob->as<head> ();
! if (head_table == &Null(head) || (unsigned int) head_table->indexToLocFormat > 1 || head_table->glyphDataFormat != 0)
! {
! /* head table is not present, or in an unknown format. Leave num_glyphs=0, that takes care of disabling us. */
! hb_blob_destroy (head_blob);
return;
! }
! short_offset = 0 == head_table->indexToLocFormat;
! hb_blob_destroy (head_blob);
! loca_blob = Sanitizer<loca>().sanitize (face->reference_table (HB_OT_TAG_loca));
! loca_table = loca_blob->as<loca> ();
! glyf_blob = Sanitizer<glyf>().sanitize (face->reference_table (HB_OT_TAG_glyf));
! glyf_table = glyf_blob->as<glyf> ();
! num_glyphs = MAX (1u, hb_blob_get_length (loca_blob) / (short_offset ? 2 : 4)) - 1;
! glyf_len = hb_blob_get_length (glyf_blob);
}
! inline void fini (void)
{
! hb_blob_destroy (loca_blob);
! hb_blob_destroy (glyf_blob);
}
/*
* Returns true if the referenced glyph is a valid glyph and a composite glyph.
* If true is returned a pointer to the composite glyph will be written into
* composite.
*/
! inline bool get_composite (hb_codepoint_t glyph,
CompositeGlyphHeader::Iterator *composite /* OUT */) const
{
! if (this->glyf_table == &Null(glyf) || !num_glyphs)
return false;
unsigned int 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,
end_offset - start_offset,
composite);
}
enum simple_glyph_flag_t {
FLAG_X_SHORT = 0x02,
FLAG_Y_SHORT = 0x04,
FLAG_REPEAT = 0x08,
FLAG_X_SAME = 0x10,
! FLAG_Y_SAME = 0x20
};
/* based on FontTools _g_l_y_f.py::trim */
! inline bool remove_padding(unsigned int start_offset,
unsigned int *end_offset) const
{
! if (*end_offset - start_offset < GlyphHeader::static_size)
! return true;
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;
--- 226,293 ----
DEFINE_SIZE_MIN (4);
};
struct accelerator_t
{
! void init (hb_face_t *face)
{
memset (this, 0, sizeof (accelerator_t));
! const OT::head &head = *face->table.head;
! if (head.indexToLocFormat > 1 || head.glyphDataFormat != 0)
! /* Unknown format. Leave num_glyphs=0, that takes care of disabling us. */
return;
! short_offset = 0 == head.indexToLocFormat;
! loca_table = hb_sanitize_context_t ().reference_table<loca> (face);
! glyf_table = hb_sanitize_context_t ().reference_table<glyf> (face);
! num_glyphs = MAX (1u, loca_table.get_length () / (short_offset ? 2 : 4)) - 1;
}
! void fini ()
{
! loca_table.destroy ();
! glyf_table.destroy ();
}
/*
* Returns true if the referenced glyph is a valid glyph and a composite glyph.
* If true is returned a pointer to the composite glyph will be written into
* composite.
*/
! bool get_composite (hb_codepoint_t glyph,
CompositeGlyphHeader::Iterator *composite /* OUT */) const
{
! if (unlikely (!num_glyphs))
return false;
unsigned int 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,
end_offset - start_offset,
composite);
}
enum simple_glyph_flag_t {
+ FLAG_ON_CURVE = 0x01,
FLAG_X_SHORT = 0x02,
FLAG_Y_SHORT = 0x04,
FLAG_REPEAT = 0x08,
FLAG_X_SAME = 0x10,
! FLAG_Y_SAME = 0x20,
! FLAG_RESERVED1 = 0x40,
! FLAG_RESERVED2 = 0x80
};
/* based on FontTools _g_l_y_f.py::trim */
! bool remove_padding (unsigned int start_offset,
unsigned int *end_offset) const
{
! if (*end_offset - start_offset < GlyphHeader::static_size) return true;
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;
*** 310,321 ****
{
/* 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;
--- 300,311 ----
{
/* 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;
*** 337,355 ****
glyph++;
}
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;
--- 327,341 ----
glyph++;
}
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;
*** 366,403 ****
*end_offset -= glyph_end - glyph;
}
return true;
}
! inline bool get_offsets (hb_codepoint_t glyph,
unsigned int *start_offset /* OUT */,
unsigned int *end_offset /* OUT */) const
{
if (unlikely (glyph >= num_glyphs))
return false;
if (short_offset)
{
! const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ;
*start_offset = 2 * offsets[glyph];
*end_offset = 2 * offsets[glyph + 1];
}
else
{
! const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ;
*start_offset = offsets[glyph];
*end_offset = offsets[glyph + 1];
}
! if (*start_offset > *end_offset || *end_offset > glyf_len)
return false;
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)
--- 352,389 ----
*end_offset -= glyph_end - glyph;
}
return true;
}
! bool get_offsets (hb_codepoint_t glyph,
unsigned int *start_offset /* OUT */,
unsigned int *end_offset /* OUT */) const
{
if (unlikely (glyph >= num_glyphs))
return false;
if (short_offset)
{
! const HBUINT16 *offsets = (const HBUINT16 *) loca_table->dataZ.arrayZ;
*start_offset = 2 * offsets[glyph];
*end_offset = 2 * offsets[glyph + 1];
}
else
{
! const HBUINT32 *offsets = (const HBUINT32 *) loca_table->dataZ.arrayZ;
*start_offset = offsets[glyph];
*end_offset = offsets[glyph + 1];
}
! if (*start_offset > *end_offset || *end_offset > glyf_table.get_length ())
return false;
return true;
}
! 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)
*** 415,428 ****
(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 = ((char *) last - (char *) glyf_table->dataZ) + last->get_size();
else
*instruction_start = end_offset;
*instruction_end = end_offset;
if (unlikely (*instruction_start > *instruction_end))
{
--- 401,414 ----
(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 = ((char *) last - (char *) glyf_table->dataZ.arrayZ) + last->get_size ();
else
*instruction_start = end_offset;
*instruction_end = end_offset;
if (unlikely (*instruction_start > *instruction_end))
{
*** 452,463 ****
*instruction_end = end;
}
return true;
}
! inline bool get_extents (hb_codepoint_t glyph,
! hb_glyph_extents_t *extents) const
{
unsigned int start_offset, end_offset;
if (!get_offsets (glyph, &start_offset, &end_offset))
return false;
--- 438,448 ----
*instruction_end = end;
}
return true;
}
! bool get_extents (hb_codepoint_t glyph, hb_glyph_extents_t *extents) const
{
unsigned int start_offset, end_offset;
if (!get_offsets (glyph, &start_offset, &end_offset))
return false;
*** 475,496 ****
}
private:
bool short_offset;
unsigned int num_glyphs;
! const loca *loca_table;
! const glyf *glyf_table;
! hb_blob_t *loca_blob;
! hb_blob_t *glyf_blob;
! unsigned int glyf_len;
};
protected:
! HBUINT8 dataZ[VAR]; /* Glyphs data. */
!
! DEFINE_SIZE_ARRAY (0, dataZ);
};
} /* namespace OT */
#endif /* HB_OT_GLYF_TABLE_HH */
--- 460,482 ----
}
private:
bool short_offset;
unsigned int num_glyphs;
! hb_blob_ptr_t<loca> loca_table;
! hb_blob_ptr_t<glyf> glyf_table;
};
protected:
! UnsizedArrayOf<HBUINT8> dataZ; /* Glyphs data. */
! public:
! DEFINE_SIZE_MIN (0); /* In reality, this is UNBOUNDED() type; but since we always
! * check the size externally, allow Null() object of it by
! * defining it MIN() instead. */
};
+ struct glyf_accelerator_t : glyf::accelerator_t {};
+
} /* namespace OT */
#endif /* HB_OT_GLYF_TABLE_HH */
< prev index next >