Merge branch 'master' into cff-subset
This commit is contained in:
commit
9ade3e7bb8
|
@ -211,10 +211,29 @@ static void dump_glyphs (cairo_font_face_t *cairo_face, unsigned int upem,
|
|||
int main (int argc, char **argv)
|
||||
{
|
||||
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);
|
||||
}
|
||||
|
||||
|
||||
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_face_t *face = hb_face_create (blob, 0);
|
||||
hb_font_t *font = hb_font_create (face);
|
||||
|
|
|
@ -224,7 +224,8 @@ struct LookupFormat8
|
|||
private:
|
||||
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
|
||||
|
@ -234,7 +235,7 @@ struct LookupFormat8
|
|||
}
|
||||
|
||||
protected:
|
||||
HBUINT16 format; /* Format identifier--format = 6 */
|
||||
HBUINT16 format; /* Format identifier--format = 8 */
|
||||
GlyphID firstGlyph; /* First glyph index included in the trimmed array. */
|
||||
HBUINT16 glyphCount; /* Total number of glyphs (equivalent to the last
|
||||
* glyph minus the value of firstGlyph plus 1). */
|
||||
|
@ -506,9 +507,10 @@ struct StateTableDriver
|
|||
|
||||
if (!c->in_place)
|
||||
{
|
||||
for (; buffer->idx < buffer->len;)
|
||||
buffer->next_glyph ();
|
||||
buffer->swap_buffers ();
|
||||
for (; buffer->successful && buffer->idx < buffer->len;)
|
||||
buffer->next_glyph ();
|
||||
if (likely (buffer->successful))
|
||||
buffer->swap_buffers ();
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -172,7 +172,7 @@ struct KerxSubTableFormat1
|
|||
* list. Discovered by testing. */
|
||||
unsigned int idx = stack[i];
|
||||
int v = *actions++;
|
||||
if (buffer->info[idx].mask & kern_mask)
|
||||
if (idx < buffer->len && buffer->info[idx].mask & kern_mask)
|
||||
{
|
||||
/* XXX Non-forward direction... */
|
||||
if (HB_DIRECTION_IS_HORIZONTAL (buffer->props.direction))
|
||||
|
@ -212,7 +212,9 @@ struct KerxSubTableFormat1
|
|||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
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:
|
||||
|
@ -338,7 +340,7 @@ struct KerxSubTableFormat4
|
|||
hb_buffer_t *buffer = driver->buffer;
|
||||
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();
|
||||
switch (action_type)
|
||||
|
@ -444,11 +446,9 @@ struct KerxSubTableFormat4
|
|||
inline bool sanitize (hb_sanitize_context_t *c) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
|
||||
/* The rest of array sanitizations are done at run-time. */
|
||||
return_trace (c->check_struct (this) &&
|
||||
machine.sanitize (c) &&
|
||||
flags.sanitize (c));
|
||||
return_trace (likely (c->check_struct (this) &&
|
||||
machine.sanitize (c)));
|
||||
}
|
||||
|
||||
protected:
|
||||
|
|
|
@ -391,6 +391,12 @@ struct LigatureSubtable
|
|||
unsigned int action_idx = entry->data.ligActionIndex;
|
||||
unsigned int action;
|
||||
unsigned int ligature_idx = 0;
|
||||
|
||||
if (unlikely (!match_length))
|
||||
return false;
|
||||
|
||||
buffer->merge_out_clusters (match_positions[0], buffer->out_len);
|
||||
|
||||
do
|
||||
{
|
||||
if (unlikely (!match_length))
|
||||
|
@ -406,6 +412,8 @@ struct LigatureSubtable
|
|||
if (uoffset & 0x20000000)
|
||||
uoffset += 0xC0000000;
|
||||
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;
|
||||
|
||||
const HBUINT16 &componentData = component[component_idx];
|
||||
|
@ -428,7 +436,6 @@ struct LigatureSubtable
|
|||
buffer->skip_glyph ();
|
||||
end--;
|
||||
}
|
||||
/* TODO merge_clusters / unsafe_to_break */
|
||||
|
||||
action_idx++;
|
||||
}
|
||||
|
@ -620,12 +627,12 @@ struct InsertionSubtable
|
|||
unsigned int end = buffer->out_len;
|
||||
buffer->move_to (mark);
|
||||
|
||||
if (!before)
|
||||
if (buffer->idx < buffer->len && !before)
|
||||
buffer->copy_glyph ();
|
||||
/* TODO We ignore KashidaLike setting. */
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
buffer->output_glyph (glyphs[i]);
|
||||
if (!before)
|
||||
if (buffer->idx < buffer->len && !before)
|
||||
buffer->skip_glyph ();
|
||||
|
||||
buffer->move_to (end + count);
|
||||
|
@ -644,12 +651,12 @@ struct InsertionSubtable
|
|||
|
||||
unsigned int end = buffer->out_len;
|
||||
|
||||
if (!before)
|
||||
if (buffer->idx < buffer->len && !before)
|
||||
buffer->copy_glyph ();
|
||||
/* TODO We ignore KashidaLike setting. */
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
buffer->output_glyph (glyphs[i]);
|
||||
if (!before)
|
||||
if (buffer->idx < buffer->len && !before)
|
||||
buffer->skip_glyph ();
|
||||
|
||||
/* Humm. Not sure where to move to. There's this wording under
|
||||
|
|
|
@ -507,8 +507,9 @@ struct hb_mapped_file_t
|
|||
|
||||
#if (defined(HAVE_MMAP) || defined(_WIN32) || defined(__CYGWIN__)) && !defined(HB_NO_MMAP)
|
||||
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
|
||||
munmap (file->contents, file->length);
|
||||
#elif defined(_WIN32) || defined(__CYGWIN__)
|
||||
|
|
|
@ -229,7 +229,10 @@ struct hb_buffer_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_len++;
|
||||
|
|
|
@ -128,7 +128,7 @@ struct IndexSubtableFormat1Or3
|
|||
{
|
||||
TRACE_SANITIZE (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,
|
||||
|
@ -206,7 +206,7 @@ struct IndexSubtableRecord
|
|||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
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
|
||||
|
@ -214,16 +214,14 @@ struct IndexSubtableRecord
|
|||
return (this+offsetToSubtable).get_extents (extents);
|
||||
}
|
||||
|
||||
bool get_image_data (unsigned int gid,
|
||||
bool get_image_data (unsigned int gid,
|
||||
const void *base,
|
||||
unsigned int *offset,
|
||||
unsigned int *length,
|
||||
unsigned int *format) const
|
||||
{
|
||||
if (gid < firstGlyphIndex || gid > lastGlyphIndex)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
return (this+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
|
||||
if (gid < firstGlyphIndex || gid > lastGlyphIndex) return false;
|
||||
return (base+offsetToSubtable).get_image_data (gid - firstGlyphIndex,
|
||||
offset, length, format);
|
||||
}
|
||||
|
||||
|
@ -241,12 +239,7 @@ struct IndexSubtableArray
|
|||
inline bool sanitize (hb_sanitize_context_t *c, unsigned int count) const
|
||||
{
|
||||
TRACE_SANITIZE (this);
|
||||
if (unlikely (!c->check_array (indexSubtablesZ.arrayZ, count)))
|
||||
return_trace (false);
|
||||
for (unsigned int i = 0; i < count; i++)
|
||||
if (unlikely (!indexSubtablesZ[i].sanitize (c, this)))
|
||||
return_trace (false);
|
||||
return_trace (true);
|
||||
return_trace (indexSubtablesZ.sanitize (c, count, this));
|
||||
}
|
||||
|
||||
public:
|
||||
|
@ -276,13 +269,15 @@ struct BitmapSizeTable
|
|||
TRACE_SANITIZE (this);
|
||||
return_trace (c->check_struct (this) &&
|
||||
indexSubtableArrayOffset.sanitize (c, base, numberOfIndexSubtables) &&
|
||||
c->check_range (&(base+indexSubtableArrayOffset), indexTablesSize) &&
|
||||
horizontal.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);
|
||||
}
|
||||
|
||||
|
@ -348,7 +343,8 @@ struct CBLC
|
|||
|
||||
protected:
|
||||
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. */
|
||||
|
||||
|
@ -361,7 +357,7 @@ struct CBLC
|
|||
{
|
||||
*x_ppem = sizeTables[i].ppemX;
|
||||
*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)
|
||||
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)
|
||||
return false;
|
||||
|
||||
|
@ -427,7 +424,7 @@ struct CBDT
|
|||
return true;
|
||||
|
||||
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;
|
||||
|
||||
{
|
||||
|
@ -478,7 +475,7 @@ struct CBDT
|
|||
{
|
||||
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))
|
||||
continue;
|
||||
|
||||
|
|
|
@ -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
|
||||
hb_ot_get_glyph_extents (hb_font_t *font,
|
||||
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_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_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_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);
|
||||
|
|
|
@ -48,7 +48,7 @@ namespace OT {
|
|||
struct LongMetric
|
||||
{
|
||||
UFWORD advance; /* Advance width/height. */
|
||||
FWORD lsb; /* Leading (left/top) side bearing. */
|
||||
FWORD sb; /* Leading (left/top) side bearing. */
|
||||
public:
|
||||
DEFINE_SIZE_STATIC (4);
|
||||
};
|
||||
|
@ -134,8 +134,8 @@ struct hmtxvmtx
|
|||
}
|
||||
else
|
||||
{
|
||||
/* dest just lsb */
|
||||
*((FWORD *) dest_pos) = src_metric->lsb;
|
||||
/* dest just sb */
|
||||
*((FWORD *) dest_pos) = src_metric->sb;
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -147,18 +147,18 @@ struct hmtxvmtx
|
|||
failed = true;
|
||||
break;
|
||||
}
|
||||
FWORD src_lsb = *(lsbs + gids[i] - _mtx.num_advances);
|
||||
FWORD src_sb = *(lsbs + gids[i] - _mtx.num_advances);
|
||||
if (i < num_advances)
|
||||
{
|
||||
/* dest needs a full LongMetric */
|
||||
LongMetric *metric = (LongMetric *)dest_pos;
|
||||
metric->advance = src_metric->advance;
|
||||
metric->lsb = src_lsb;
|
||||
metric->sb = src_sb;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* dest just needs an lsb */
|
||||
*((FWORD *) dest_pos) = src_lsb;
|
||||
/* dest just needs an sb */
|
||||
*((FWORD *) dest_pos) = src_sb;
|
||||
}
|
||||
}
|
||||
dest_pos += (i < num_advances ? 4 : 2);
|
||||
|
@ -249,17 +249,30 @@ struct hmtxvmtx
|
|||
hb_blob_destroy (var_blob);
|
||||
}
|
||||
|
||||
inline unsigned int get_advance (hb_codepoint_t glyph) const
|
||||
/* 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
|
||||
{
|
||||
if (unlikely (glyph >= num_metrics))
|
||||
{
|
||||
/* If num_metrics is zero, it means we don't have the metrics table
|
||||
* for this direction: return default advance. Otherwise, it means that the
|
||||
* glyph index is out of bound: return zero. */
|
||||
if (num_metrics)
|
||||
return 0;
|
||||
else
|
||||
return default_advance;
|
||||
/* If num_metrics is zero, it means we don't have the metrics table
|
||||
* for this direction: return default advance. Otherwise, it means that the
|
||||
* glyph index is out of bound: return zero. */
|
||||
if (num_metrics)
|
||||
return 0;
|
||||
else
|
||||
return default_advance;
|
||||
}
|
||||
|
||||
return table->longMetricZ[MIN (glyph, (uint32_t) num_advances - 1)].advance;
|
||||
|
@ -271,7 +284,7 @@ struct hmtxvmtx
|
|||
unsigned int advance = get_advance (glyph);
|
||||
if (likely(glyph < num_metrics))
|
||||
{
|
||||
advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
|
||||
advance += (font->num_coords ? var_table->get_advance_var (glyph, font->coords, font->num_coords) : 0); // TODO Optimize?!
|
||||
}
|
||||
return advance;
|
||||
}
|
||||
|
|
|
@ -37,6 +37,7 @@ struct hb_kern_machine_t
|
|||
{
|
||||
hb_kern_machine_t (const Driver &driver_) : driver (driver_) {}
|
||||
|
||||
HB_NO_SANITIZE_SIGNED_INTEGER_OVERFLOW
|
||||
inline void kern (hb_font_t *font,
|
||||
hb_buffer_t *buffer,
|
||||
hb_mask_t kern_mask) const
|
||||
|
|
|
@ -237,6 +237,15 @@ struct _hb_alignof
|
|||
# define HB_FALLTHROUGH /* FALLTHROUGH */
|
||||
#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__)
|
||||
/* We need Windows Vista for both Uniscribe backend and for
|
||||
* MemoryBarrier. We don't support compiling on Windows XP,
|
||||
|
|
|
@ -1,3 +1,3 @@
|
|||
../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=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]
|
||||
|
|
Loading…
Reference in New Issue