Merge branch 'master' into cff-subset

This commit is contained in:
Michiharu Ariza 2018-10-15 14:03:23 -07:00
commit 9ade3e7bb8
12 changed files with 140 additions and 59 deletions

View File

@ -211,10 +211,29 @@ static void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem,
int main (int argc, char **argv) int main (int argc, char **argv)
{ {
if (argc != 2) { if (argc != 2) {
fprintf (stderr, "usage: %s font-file.ttf\n", argv[0]); fprintf (stderr, "usage: %s font-file.ttf\n"
"run it like `rm -rf out && mkdir out && %s font-file.ttf`\n",
argv[0], argv[0]);
exit (1); exit (1);
} }
FILE *font_name_file = fopen ("out/_font_name_file.txt", "r");
if (font_name_file != nullptr)
{
fprintf (stderr, "Purge or move ./out folder in order to run a new dump\n");
exit (1);
}
font_name_file = fopen ("out/_font_name_file.txt", "w");
if (font_name_file == nullptr)
{
fprintf (stderr, "./out is not accessible, create it please\n");
exit (1);
}
fwrite (argv[1], 1, strlen (argv[1]), font_name_file);
fclose (font_name_file);
hb_blob_t *blob = hb_blob_create_from_file (argv[1]); hb_blob_t *blob = hb_blob_create_from_file (argv[1]);
hb_face_t *face = hb_face_create (blob, 0); hb_face_t *face = hb_face_create (blob, 0);
hb_font_t *font = hb_font_create (face); hb_font_t *font = hb_font_create (face);

View File

@ -224,7 +224,8 @@ struct LookupFormat8
private: private:
inline const T* get_value (hb_codepoint_t glyph_id) const inline const T* get_value (hb_codepoint_t glyph_id) const
{ {
return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ? &valueArrayZ[glyph_id - firstGlyph] : nullptr; return firstGlyph <= glyph_id && glyph_id - firstGlyph < glyphCount ?
&valueArrayZ[glyph_id - firstGlyph] : nullptr;
} }
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
@ -234,7 +235,7 @@ struct LookupFormat8
} }
protected: protected:
HBUINT16 format; /* Format identifier--format = 6 */ HBUINT16 format; /* Format identifier--format = 8 */
GlyphID firstGlyph; /* First glyph index included in the trimmed array. */ GlyphID firstGlyph; /* First glyph index included in the trimmed array. */
HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
* glyph minus the value of firstGlyph plus 1). */ * glyph minus the value of firstGlyph plus 1). */
@ -506,8 +507,9 @@ struct StateTableDriver
if (!c->in_place) if (!c->in_place)
{ {
for (; buffer->idx < buffer->len;) for (; buffer->successful && buffer->idx < buffer->len;)
buffer->next_glyph (); buffer->next_glyph ();
if (likely (buffer->successful))
buffer->swap_buffers (); buffer->swap_buffers ();
} }
} }

View File

@ -172,7 +172,7 @@ struct KerxSubTableFormat1
* list. Discovered by testing. */ * list. Discovered by testing. */
unsigned int idx = stack[i]; unsigned int idx = stack[i];
int v = *actions++; int v = *actions++;
if (buffer->info[idx].mask & kern_mask) if (idx < buffer->len && buffer->info[idx].mask & kern_mask)
{ {
/* XXX Non-forward direction... */ /* XXX Non-forward direction... */
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction)) if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
@ -212,7 +212,9 @@ struct KerxSubTableFormat1
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (likely (machine.sanitize (c))); /* The rest of array sanitizations are done at run-time. */
return_trace (likely (c->check_struct (this) &&
machine.sanitize (c)));
} }
protected: protected:
@ -338,7 +340,7 @@ struct KerxSubTableFormat4
hb_buffer_t *buffer = driver->buffer; hb_buffer_t *buffer = driver->buffer;
unsigned int flags = entry->flags; unsigned int flags = entry->flags;
if (mark_set && entry->data.ankrActionIndex != 0xFFFF) if (mark_set && entry->data.ankrActionIndex != 0xFFFF && buffer->idx < buffer->len)
{ {
hb_glyph_position_t &o = buffer->cur_pos(); hb_glyph_position_t &o = buffer->cur_pos();
switch (action_type) switch (action_type)
@ -444,11 +446,9 @@ struct KerxSubTableFormat4
inline bool sanitize (hb_sanitize_context_t *c) const inline bool sanitize (hb_sanitize_context_t *c) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
/* The rest of array sanitizations are done at run-time. */ /* The rest of array sanitizations are done at run-time. */
return_trace (c->check_struct (this) && return_trace (likely (c->check_struct (this) &&
machine.sanitize (c) && machine.sanitize (c)));
flags.sanitize (c));
} }
protected: protected:

View File

@ -391,6 +391,12 @@ struct LigatureSubtable
unsigned int action_idx = entry->data.ligActionIndex; unsigned int action_idx = entry->data.ligActionIndex;
unsigned int action; unsigned int action;
unsigned int ligature_idx = 0; unsigned int ligature_idx = 0;
if (unlikely (!match_length))
return false;
buffer->merge_out_clusters (match_positions[0], buffer->out_len);
do do
{ {
if (unlikely (!match_length)) if (unlikely (!match_length))
@ -406,6 +412,8 @@ struct LigatureSubtable
if (uoffset & 0x20000000) if (uoffset & 0x20000000)
uoffset += 0xC0000000; uoffset += 0xC0000000;
int32_t offset = (int32_t) uoffset; int32_t offset = (int32_t) uoffset;
if (buffer->idx >= buffer->len)
return false; // TODO Work on previous instead?
unsigned int component_idx = buffer->cur().codepoint + offset; unsigned int component_idx = buffer->cur().codepoint + offset;
const HBUINT16 &componentData = component[component_idx]; const HBUINT16 &componentData = component[component_idx];
@ -428,7 +436,6 @@ struct LigatureSubtable
buffer->skip_glyph (); buffer->skip_glyph ();
end--; end--;
} }
/* TODO merge_clusters / unsafe_to_break */
action_idx++; action_idx++;
} }
@ -620,12 +627,12 @@ struct InsertionSubtable
unsigned int end = buffer->out_len; unsigned int end = buffer->out_len;
buffer->move_to (mark); buffer->move_to (mark);
if (!before) if (buffer->idx < buffer->len && !before)
buffer->copy_glyph (); buffer->copy_glyph ();
/* TODO We ignore KashidaLike setting. */ /* TODO We ignore KashidaLike setting. */
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
buffer->output_glyph (glyphs[i]); buffer->output_glyph (glyphs[i]);
if (!before) if (buffer->idx < buffer->len && !before)
buffer->skip_glyph (); buffer->skip_glyph ();
buffer->move_to (end + count); buffer->move_to (end + count);
@ -644,12 +651,12 @@ struct InsertionSubtable
unsigned int end = buffer->out_len; unsigned int end = buffer->out_len;
if (!before) if (buffer->idx < buffer->len && !before)
buffer->copy_glyph (); buffer->copy_glyph ();
/* TODO We ignore KashidaLike setting. */ /* TODO We ignore KashidaLike setting. */
for (unsigned int i = 0; i < count; i++) for (unsigned int i = 0; i < count; i++)
buffer->output_glyph (glyphs[i]); buffer->output_glyph (glyphs[i]);
if (!before) if (buffer->idx < buffer->len && !before)
buffer->skip_glyph (); buffer->skip_glyph ();
/* Humm. Not sure where to move to. There's this wording under /* Humm. Not sure where to move to. There's this wording under

View File

@ -507,8 +507,9 @@ struct hb_mapped_file_t
#if (defined(HAVE_MMAP) || defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_MMAP) #if (defined(HAVE_MMAP) || defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_MMAP)
static void static void
_hb_mapped_file_destroy (hb_mapped_file_t *file) _hb_mapped_file_destroy (void *file_)
{ {
hb_mapped_file_t *file = (hb_mapped_file_t *) file_;
#ifdef HAVE_MMAP #ifdef HAVE_MMAP
munmap (file->contents, file->length); munmap (file->contents, file->length);
#elif defined(_WIN32) || defined(__CYGWIN__) #elif defined(_WIN32) || defined(__CYGWIN__)

View File

@ -229,7 +229,10 @@ struct hb_buffer_t
{ {
if (unlikely (!make_room_for (0, 1))) return Crap(hb_glyph_info_t); if (unlikely (!make_room_for (0, 1))) return Crap(hb_glyph_info_t);
out_info[out_len] = info[idx]; if (unlikely (idx == len && !out_len))
return Crap(hb_glyph_info_t);
out_info[out_len] = idx < len ? info[idx] : out_info[out_len - 1];
out_info[out_len].codepoint = glyph_index; out_info[out_len].codepoint = glyph_index;
out_len++; out_len++;

View File

@ -128,7 +128,7 @@ struct IndexSubtableFormat1Or3
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && return_trace (c->check_struct (this) &&
c->check_array (offsetArrayZ.arrayZ, glyph_count + 1)); offsetArrayZ.sanitize (c, glyph_count + 1));
} }
bool get_image_data (unsigned int idx, bool get_image_data (unsigned int idx,
@ -206,7 +206,7 @@ struct IndexSubtableRecord
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && return_trace (c->check_struct (this) &&
firstGlyphIndex <= lastGlyphIndex && firstGlyphIndex <= lastGlyphIndex &&
offsetToSubtable.sanitize (c, this, lastGlyphIndex - firstGlyphIndex + 1)); offsetToSubtable.sanitize (c, base, lastGlyphIndex - firstGlyphIndex + 1));
} }
inline bool get_extents (hb_glyph_extents_t *extents) const inline bool get_extents (hb_glyph_extents_t *extents) const
@ -215,15 +215,13 @@ struct IndexSubtableRecord
} }
bool get_image_data (unsigned int gid, bool get_image_data (unsigned int gid,
const void *base,
unsigned int *offset, unsigned int *offset,
unsigned int *length, unsigned int *length,
unsigned int *format) const unsigned int *format) const
{ {
if (gid < firstGlyphIndex || gid > lastGlyphIndex) if (gid < firstGlyphIndex || gid > lastGlyphIndex) return false;
{ return (base+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
return false;
}
return (this+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
offset, length, format); offset, length, format);
} }
@ -241,12 +239,7 @@ struct IndexSubtableArray
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
{ {
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
if (unlikely (!c->check_array (indexSubtablesZ.arrayZ, count))) return_trace (indexSubtablesZ.sanitize (c, count, this));
return_trace (false);
for (unsigned int i = 0; i < count; i++)
if (unlikely (!indexSubtablesZ[i].sanitize (c, this)))
return_trace (false);
return_trace (true);
} }
public: public:
@ -276,13 +269,15 @@ struct BitmapSizeTable
TRACE_SANITIZE (this); TRACE_SANITIZE (this);
return_trace (c->check_struct (this) && return_trace (c->check_struct (this) &&
indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) && indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) &&
c->check_range (&(base+indexSubtableArrayOffset), indexTablesSize) &&
horizontal.sanitize (c) && horizontal.sanitize (c) &&
vertical.sanitize (c)); vertical.sanitize (c));
} }
const IndexSubtableRecord *find_table (hb_codepoint_t glyph, const void *base) const const IndexSubtableRecord *find_table (hb_codepoint_t glyph,
const void *base,
const void **out_base) const
{ {
*out_base = &(base+indexSubtableArrayOffset);
return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables); return (base+indexSubtableArrayOffset).find_table (glyph, numberOfIndexSubtables);
} }
@ -348,7 +343,8 @@ struct CBLC
protected: protected:
const IndexSubtableRecord *find_table (hb_codepoint_t glyph, const IndexSubtableRecord *find_table (hb_codepoint_t glyph,
unsigned int *x_ppem, unsigned int *y_ppem) const unsigned int *x_ppem, unsigned int *y_ppem,
const void **base) const
{ {
/* TODO: Make it possible to select strike. */ /* TODO: Make it possible to select strike. */
@ -361,7 +357,7 @@ struct CBLC
{ {
*x_ppem = sizeTables[i].ppemX; *x_ppem = sizeTables[i].ppemX;
*y_ppem = sizeTables[i].ppemY; *y_ppem = sizeTables[i].ppemY;
return sizeTables[i].find_table (glyph, this); return sizeTables[i].find_table (glyph, this, base);
} }
} }
@ -419,7 +415,8 @@ struct CBDT
if (!cblc) if (!cblc)
return false; // Not a color bitmap font. return false; // Not a color bitmap font.
const IndexSubtableRecord *subtable_record = this->cblc->find_table(glyph, &x_ppem, &y_ppem); const void *base;
const IndexSubtableRecord *subtable_record = this->cblc->find_table (glyph, &x_ppem, &y_ppem, &base);
if (!subtable_record || !x_ppem || !y_ppem) if (!subtable_record || !x_ppem || !y_ppem)
return false; return false;
@ -427,7 +424,7 @@ struct CBDT
return true; return true;
unsigned int image_offset = 0, image_length = 0, image_format = 0; unsigned int image_offset = 0, image_length = 0, image_format = 0;
if (!subtable_record->get_image_data (glyph, &image_offset, &image_length, &image_format)) if (!subtable_record->get_image_data (glyph, base, &image_offset, &image_length, &image_format))
return false; return false;
{ {
@ -478,7 +475,7 @@ struct CBDT
{ {
unsigned int image_offset = 0, image_length = 0, image_format = 0; unsigned int image_offset = 0, image_length = 0, image_format = 0;
if (!subtable_record.get_image_data (gid, if (!subtable_record.get_image_data (gid, &subtable_array,
&image_offset, &image_length, &image_format)) &image_offset, &image_length, &image_format))
continue; continue;

View File

@ -128,6 +128,35 @@ hb_ot_get_glyph_v_advances (hb_font_t* font, void* font_data,
} }
} }
static hb_bool_t
hb_ot_get_glyph_v_origin (hb_font_t *font,
void *font_data,
hb_codepoint_t glyph,
hb_position_t *x,
hb_position_t *y,
void *user_data HB_UNUSED)
{
const hb_ot_face_data_t *ot_face = (const hb_ot_face_data_t *) font_data;
*x = font->get_glyph_h_advance (glyph) / 2;
hb_glyph_extents_t extents = {0};
bool ret = ot_face->glyf->get_extents (glyph, &extents);
if (ret)
{
const OT::vmtx_accelerator_t &vmtx = *ot_face->vmtx.get ();
hb_position_t tsb = vmtx.get_side_bearing (glyph);
*y = font->em_scale_y (extents.y_bearing + tsb);
return true;
}
hb_font_extents_t font_extents;
font->get_h_extents_with_fallback (&font_extents);
*y = font_extents.ascender;
return true;
}
static hb_bool_t static hb_bool_t
hb_ot_get_glyph_extents (hb_font_t *font, hb_ot_get_glyph_extents (hb_font_t *font,
void *font_data, void *font_data,
@ -223,7 +252,7 @@ static struct hb_ot_font_funcs_lazy_loader_t : hb_font_funcs_lazy_loader_t<hb_ot
hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr); hb_font_funcs_set_glyph_h_advances_func (funcs, hb_ot_get_glyph_h_advances, nullptr, nullptr);
hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr); hb_font_funcs_set_glyph_v_advances_func (funcs, hb_ot_get_glyph_v_advances, nullptr, nullptr);
//hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr); //hb_font_funcs_set_glyph_h_origin_func (funcs, hb_ot_get_glyph_h_origin, nullptr, nullptr);
//hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr); hb_font_funcs_set_glyph_v_origin_func (funcs, hb_ot_get_glyph_v_origin, nullptr, nullptr);
hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr); hb_font_funcs_set_glyph_extents_func (funcs, hb_ot_get_glyph_extents, nullptr, nullptr);
//hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr); //hb_font_funcs_set_glyph_contour_point_func (funcs, hb_ot_get_glyph_contour_point, nullptr, nullptr);
hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr); hb_font_funcs_set_glyph_name_func (funcs, hb_ot_get_glyph_name, nullptr, nullptr);

View File

@ -48,7 +48,7 @@ namespace OT {
struct LongMetric struct LongMetric
{ {
UFWORD advance; /* Advance width/height. */ UFWORD advance; /* Advance width/height. */
FWORD lsb; /* Leading (left/top) side bearing. */ FWORD sb; /* Leading (left/top) side bearing. */
public: public:
DEFINE_SIZE_STATIC (4); DEFINE_SIZE_STATIC (4);
}; };
@ -134,8 +134,8 @@ struct hmtxvmtx
} }
else else
{ {
/* dest just lsb */ /* dest just sb */
*((FWORD *) dest_pos) = src_metric->lsb; *((FWORD *) dest_pos) = src_metric->sb;
} }
} }
else else
@ -147,18 +147,18 @@ struct hmtxvmtx
failed = true; failed = true;
break; break;
} }
FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances); FWORD src_sb = *(lsbs + gids[i] - _mtx.num_advances);
if (i < num_advances) if (i < num_advances)
{ {
/* dest needs a full LongMetric */ /* dest needs a full LongMetric */
LongMetric *metric = (LongMetric *)dest_pos; LongMetric *metric = (LongMetric *)dest_pos;
metric->advance = src_metric->advance; metric->advance = src_metric->advance;
metric->lsb = src_lsb; metric->sb = src_sb;
} }
else else
{ {
/* dest just needs an lsb */ /* dest just needs an sb */
*((FWORD *) dest_pos) = src_lsb; *((FWORD *) dest_pos) = src_sb;
} }
} }
dest_pos += (i < num_advances ? 4 : 2); dest_pos += (i < num_advances ? 4 : 2);
@ -249,6 +249,19 @@ struct hmtxvmtx
hb_blob_destroy (var_blob); hb_blob_destroy (var_blob);
} }
/* TODO Add variations version. */
inline unsigned int get_side_bearing (hb_codepoint_t glyph) const
{
if (glyph < num_advances)
return table->longMetricZ[glyph].sb;
if (unlikely (glyph > num_metrics))
return 0;
const FWORD *bearings = (const FWORD *) &table->longMetricZ[num_advances];
return bearings[glyph - num_advances];
}
inline unsigned int get_advance (hb_codepoint_t glyph) const inline unsigned int get_advance (hb_codepoint_t glyph) const
{ {
if (unlikely (glyph >= num_metrics)) if (unlikely (glyph >= num_metrics))

View File

@ -37,6 +37,7 @@ struct hb_kern_machine_t
{ {
hb_kern_machine_t (const Driver &driver_) : driver (driver_) {} hb_kern_machine_t (const Driver &driver_) : driver (driver_) {}
HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
inline void kern (hb_font_t *font, inline void kern (hb_font_t *font,
hb_buffer_t *buffer, hb_buffer_t *buffer,
hb_mask_t kern_mask) const hb_mask_t kern_mask) const

View File

@ -237,6 +237,15 @@ struct _hb_alignof
# define HB_FALLTHROUGH /* FALLTHROUGH */ # define HB_FALLTHROUGH /* FALLTHROUGH */
#endif #endif
#if defined(__clang__)
/* Disable certain sanitizer errors. */
/* https://github.com/harfbuzz/harfbuzz/issues/1247 */
#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW __attribute__((no_sanitize("signed-integer-overflow")))
#else
#define HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
#endif
#if defined(_WIN32) || defined(__CYGWIN__) #if defined(_WIN32) || defined(__CYGWIN__)
/* We need Windows Vista for both Uniscribe backend and for /* We need Windows Vista for both Uniscribe backend and for
* MemoryBarrier. We don't support compiling on Windows XP, * MemoryBarrier. We don't support compiling on Windows XP,

View File

@ -1,3 +1,3 @@
../fonts/191826b9643e3f124d865d617ae609db6a2ce203.ttf:--direction=t --font-funcs=ft:U+300C:[uni300C.vert=0@-512,-578+0,-1024] ../fonts/191826b9643e3f124d865d617ae609db6a2ce203.ttf:--direction=t --font-funcs=ft:U+300C:[uni300C.vert=0@-512,-578+0,-1024]
../fonts/f9b1dd4dcb515e757789a22cb4241107746fd3d0.ttf:--direction=t --font-funcs=ft:U+0041,U+0042:[gid1=0@-654,-2128+0,-2789|gid2=1@-665,-2125+0,-2789] ../fonts/f9b1dd4dcb515e757789a22cb4241107746fd3d0.ttf:--direction=t --font-funcs=ft:U+0041,U+0042:[gid1=0@-654,-2128+0,-2789|gid2=1@-665,-2125+0,-2789]
../fonts/f9b1dd4dcb515e757789a22cb4241107746fd3d0.ttf:--direction=t --font-funcs=ot:U+0041,U+0042:[gid1=0@-654,-2189+0,-2048|gid2=1@-665,-2189+0,-2048] ../fonts/f9b1dd4dcb515e757789a22cb4241107746fd3d0.ttf:--direction=t --font-funcs=ot:U+0041,U+0042:[gid1=0@-654,-1468+0,-2048|gid2=1@-665,-1462+0,-2048]