[ot-font] Add metrics_accel_t
This commit is contained in:
parent
d41b809e9d
commit
be1cca2702
|
@ -35,18 +35,55 @@
|
||||||
#include "hb-ot-hmtx-table.hh"
|
#include "hb-ot-hmtx-table.hh"
|
||||||
|
|
||||||
|
|
||||||
|
struct metrics_accel_t
|
||||||
|
{
|
||||||
|
unsigned int num_metrics;
|
||||||
|
unsigned int num_advances;
|
||||||
|
const OT::_mtx *table;
|
||||||
|
hb_blob_t *blob;
|
||||||
|
|
||||||
|
inline void init (hb_font_t *font, hb_tag_t _hea_tag, hb_tag_t _mtx_tag)
|
||||||
|
{
|
||||||
|
this->num_metrics = font->face->get_num_glyphs ();
|
||||||
|
|
||||||
|
hb_blob_t *_hea_blob = OT::Sanitizer<OT::_hea>::sanitize (font->face->reference_table (_hea_tag));
|
||||||
|
const OT::_hea *_hea = OT::Sanitizer<OT::_hea>::lock_instance (_hea_blob);
|
||||||
|
this->num_advances = _hea->numberOfLongMetrics;
|
||||||
|
hb_blob_destroy (_hea_blob);
|
||||||
|
|
||||||
|
this->blob = OT::Sanitizer<OT::_mtx>::sanitize (font->face->reference_table (_mtx_tag));
|
||||||
|
if (unlikely (!this->num_advances ||
|
||||||
|
2 * (this->num_advances + this->num_metrics) < hb_blob_get_length (this->blob)))
|
||||||
|
{
|
||||||
|
hb_blob_destroy (this->blob);
|
||||||
|
this->blob = hb_blob_get_empty ();
|
||||||
|
}
|
||||||
|
this->table = OT::Sanitizer<OT::_mtx>::lock_instance (this->blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void fini (void)
|
||||||
|
{
|
||||||
|
hb_blob_destroy (this->blob);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline unsigned int get_advance (hb_codepoint_t glyph) const
|
||||||
|
{
|
||||||
|
if (unlikely (glyph >= this->num_metrics))
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
if (glyph >= this->num_advances)
|
||||||
|
glyph = this->num_advances - 1;
|
||||||
|
|
||||||
|
return this->table->longMetric[glyph].advance;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
struct hb_ot_font_t
|
struct hb_ot_font_t
|
||||||
{
|
{
|
||||||
unsigned int num_glyphs;
|
unsigned int num_glyphs;
|
||||||
|
|
||||||
unsigned int num_hmetrics;
|
metrics_accel_t h_metrics;
|
||||||
const OT::hmtx *hmtx;
|
metrics_accel_t v_metrics;
|
||||||
hb_blob_t *hmtx_blob;
|
|
||||||
|
|
||||||
unsigned int num_vmetrics;
|
|
||||||
const OT::vmtx *vmtx;
|
|
||||||
hb_blob_t *vmtx_blob;
|
|
||||||
|
|
||||||
const OT::CmapSubtable *cmap;
|
const OT::CmapSubtable *cmap;
|
||||||
const OT::CmapSubtable *cmap_uvs;
|
const OT::CmapSubtable *cmap_uvs;
|
||||||
|
@ -64,41 +101,9 @@ _hb_ot_font_create (hb_font_t *font)
|
||||||
|
|
||||||
ot_font->num_glyphs = font->face->get_num_glyphs ();
|
ot_font->num_glyphs = font->face->get_num_glyphs ();
|
||||||
|
|
||||||
/* Setup horizontal metrics. */
|
ot_font->h_metrics.init (font, HB_OT_TAG_hhea, HB_OT_TAG_hmtx);
|
||||||
{
|
/* TODO Can we do this lazily? */
|
||||||
hb_blob_t *hhea_blob = OT::Sanitizer<OT::hhea>::sanitize (font->face->reference_table (HB_OT_TAG_hhea));
|
ot_font->v_metrics.init (font, HB_OT_TAG_vhea, HB_OT_TAG_vmtx);
|
||||||
const OT::hhea *hhea = OT::Sanitizer<OT::hhea>::lock_instance (hhea_blob);
|
|
||||||
ot_font->num_hmetrics = hhea->numberOfMetrics;
|
|
||||||
hb_blob_destroy (hhea_blob);
|
|
||||||
|
|
||||||
ot_font->hmtx_blob = OT::Sanitizer<OT::hmtx>::sanitize (font->face->reference_table (HB_OT_TAG_hmtx));
|
|
||||||
if (unlikely (!ot_font->num_hmetrics ||
|
|
||||||
2 * (ot_font->num_hmetrics + ot_font->num_glyphs) < hb_blob_get_length (ot_font->hmtx_blob)))
|
|
||||||
{
|
|
||||||
hb_blob_destroy (ot_font->hmtx_blob);
|
|
||||||
free (ot_font);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ot_font->hmtx = OT::Sanitizer<OT::hmtx>::lock_instance (ot_font->hmtx_blob);
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Setup vertical metrics. */
|
|
||||||
{
|
|
||||||
hb_blob_t *vhea_blob = OT::Sanitizer<OT::vhea>::sanitize (font->face->reference_table (HB_OT_TAG_vhea));
|
|
||||||
const OT::vhea *vhea = OT::Sanitizer<OT::vhea>::lock_instance (vhea_blob);
|
|
||||||
ot_font->num_vmetrics = vhea->numberOfMetrics;
|
|
||||||
hb_blob_destroy (vhea_blob);
|
|
||||||
|
|
||||||
ot_font->vmtx_blob = OT::Sanitizer<OT::vmtx>::sanitize (font->face->reference_table (HB_TAG('v','m','t','x')));
|
|
||||||
if (unlikely (!ot_font->num_vmetrics ||
|
|
||||||
2 * (ot_font->num_vmetrics + ot_font->num_glyphs) < hb_blob_get_length (ot_font->vmtx_blob)))
|
|
||||||
{
|
|
||||||
hb_blob_destroy (ot_font->vmtx_blob);
|
|
||||||
free (ot_font);
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
ot_font->vmtx = OT::Sanitizer<OT::vmtx>::lock_instance (ot_font->vmtx_blob);
|
|
||||||
}
|
|
||||||
|
|
||||||
ot_font->cmap_blob = OT::Sanitizer<OT::cmap>::sanitize (font->face->reference_table (HB_OT_TAG_cmap));
|
ot_font->cmap_blob = OT::Sanitizer<OT::cmap>::sanitize (font->face->reference_table (HB_OT_TAG_cmap));
|
||||||
const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (ot_font->cmap_blob);
|
const OT::cmap *cmap = OT::Sanitizer<OT::cmap>::lock_instance (ot_font->cmap_blob);
|
||||||
|
@ -133,8 +138,8 @@ static void
|
||||||
_hb_ot_font_destroy (hb_ot_font_t *ot_font)
|
_hb_ot_font_destroy (hb_ot_font_t *ot_font)
|
||||||
{
|
{
|
||||||
hb_blob_destroy (ot_font->cmap_blob);
|
hb_blob_destroy (ot_font->cmap_blob);
|
||||||
hb_blob_destroy (ot_font->hmtx_blob);
|
ot_font->h_metrics.fini ();
|
||||||
hb_blob_destroy (ot_font->vmtx_blob);
|
ot_font->v_metrics.fini ();
|
||||||
|
|
||||||
free (ot_font);
|
free (ot_font);
|
||||||
}
|
}
|
||||||
|
@ -173,14 +178,7 @@ hb_ot_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||||
|
return font->em_scale_x (ot_font->h_metrics.get_advance (glyph));
|
||||||
if (unlikely (glyph >= ot_font->num_glyphs))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (glyph >= ot_font->num_hmetrics)
|
|
||||||
glyph = ot_font->num_hmetrics - 1;
|
|
||||||
|
|
||||||
return font->em_scale_x (ot_font->hmtx->longHorMetric[glyph].advance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_position_t
|
static hb_position_t
|
||||||
|
@ -190,14 +188,7 @@ hb_ot_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
|
||||||
void *user_data HB_UNUSED)
|
void *user_data HB_UNUSED)
|
||||||
{
|
{
|
||||||
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
const hb_ot_font_t *ot_font = (const hb_ot_font_t *) font_data;
|
||||||
|
return font->em_scale_y (-ot_font->v_metrics.get_advance (glyph));
|
||||||
if (unlikely (glyph >= ot_font->num_glyphs))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (glyph >= ot_font->num_vmetrics)
|
|
||||||
glyph = ot_font->num_vmetrics - 1;
|
|
||||||
|
|
||||||
return font->em_scale_y (-ot_font->vmtx->longHorMetric[glyph].advance);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static hb_bool_t
|
static hb_bool_t
|
||||||
|
|
|
@ -80,7 +80,7 @@ struct _hea
|
||||||
SHORT reserved3; /* Set to 0. */
|
SHORT reserved3; /* Set to 0. */
|
||||||
SHORT reserved4; /* Set to 0. */
|
SHORT reserved4; /* Set to 0. */
|
||||||
SHORT metricDataFormat; /* 0 for current format. */
|
SHORT metricDataFormat; /* 0 for current format. */
|
||||||
USHORT numberOfMetrics; /* Number of LongMetric entries in metric
|
USHORT numberOfLongMetrics; /* Number of LongMetric entries in metric
|
||||||
* table. */
|
* table. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_STATIC (36);
|
DEFINE_SIZE_STATIC (36);
|
||||||
|
|
|
@ -63,7 +63,7 @@ struct _mtx
|
||||||
}
|
}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
LongMetric longHorMetric[VAR]; /* Paired advance width and leading
|
LongMetric longMetric[VAR]; /* Paired advance width and leading
|
||||||
* bearing values for each glyph. The
|
* bearing values for each glyph. The
|
||||||
* value numOfHMetrics comes from
|
* value numOfHMetrics comes from
|
||||||
* the 'hhea' table. If the font is
|
* the 'hhea' table. If the font is
|
||||||
|
@ -85,7 +85,7 @@ struct _mtx
|
||||||
* font to vary the side bearing
|
* font to vary the side bearing
|
||||||
* values for each glyph. */
|
* values for each glyph. */
|
||||||
public:
|
public:
|
||||||
DEFINE_SIZE_ARRAY2 (0, longHorMetric, leadingBearingX);
|
DEFINE_SIZE_ARRAY2 (0, longMetric, leadingBearingX);
|
||||||
};
|
};
|
||||||
|
|
||||||
struct hmtx : _mtx {
|
struct hmtx : _mtx {
|
||||||
|
|
Loading…
Reference in New Issue