This source file includes following definitions.
- hb_face_create_for_tables
- _hb_face_for_data_closure_create
- _hb_face_for_data_closure_destroy
- _hb_face_for_data_reference_table
- hb_face_create
- hb_face_get_empty
- hb_face_reference
- hb_face_destroy
- hb_face_set_user_data
- hb_face_get_user_data
- hb_face_make_immutable
- hb_face_is_immutable
- hb_face_reference_table
- hb_face_reference_blob
- hb_face_set_index
- hb_face_get_index
- hb_face_set_upem
- hb_face_get_upem
- load_upem
- hb_face_set_glyph_count
- hb_face_get_glyph_count
- load_num_glyphs
#include "hb-private.hh"
#include "hb-ot-layout-private.hh"
#include "hb-font-private.hh"
#include "hb-open-file-private.hh"
#include "hb-ot-head-table.hh"
#include "hb-ot-maxp-table.hh"
#include "hb-cache-private.hh"
#include <string.h>
const hb_face_t _hb_face_nil = {
HB_OBJECT_HEADER_STATIC,
true,
NULL,
NULL,
NULL,
0,
1000,
0,
{
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_INVALID,
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
},
NULL,
};
hb_face_t *
hb_face_create_for_tables (hb_reference_table_func_t reference_table_func,
void *user_data,
hb_destroy_func_t destroy)
{
hb_face_t *face;
if (!reference_table_func || !(face = hb_object_create<hb_face_t> ())) {
if (destroy)
destroy (user_data);
return hb_face_get_empty ();
}
face->reference_table_func = reference_table_func;
face->user_data = user_data;
face->destroy = destroy;
face->upem = 0;
face->num_glyphs = (unsigned int) -1;
return face;
}
typedef struct hb_face_for_data_closure_t {
hb_blob_t *blob;
unsigned int index;
} hb_face_for_data_closure_t;
static hb_face_for_data_closure_t *
_hb_face_for_data_closure_create (hb_blob_t *blob, unsigned int index)
{
hb_face_for_data_closure_t *closure;
closure = (hb_face_for_data_closure_t *) malloc (sizeof (hb_face_for_data_closure_t));
if (unlikely (!closure))
return NULL;
closure->blob = blob;
closure->index = index;
return closure;
}
static void
_hb_face_for_data_closure_destroy (hb_face_for_data_closure_t *closure)
{
hb_blob_destroy (closure->blob);
free (closure);
}
static hb_blob_t *
_hb_face_for_data_reference_table (hb_face_t *face HB_UNUSED, hb_tag_t tag, void *user_data)
{
hb_face_for_data_closure_t *data = (hb_face_for_data_closure_t *) user_data;
if (tag == HB_TAG_NONE)
return hb_blob_reference (data->blob);
const OT::OpenTypeFontFile &ot_file = *OT::Sanitizer<OT::OpenTypeFontFile>::lock_instance (data->blob);
const OT::OpenTypeFontFace &ot_face = ot_file.get_face (data->index);
const OT::OpenTypeTable &table = ot_face.get_table_by_tag (tag);
hb_blob_t *blob = hb_blob_create_sub_blob (data->blob, table.offset, table.length);
return blob;
}
hb_face_t *
hb_face_create (hb_blob_t *blob,
unsigned int index)
{
hb_face_t *face;
if (unlikely (!blob || !hb_blob_get_length (blob)))
return hb_face_get_empty ();
hb_face_for_data_closure_t *closure = _hb_face_for_data_closure_create (OT::Sanitizer<OT::OpenTypeFontFile>::sanitize (hb_blob_reference (blob)), index);
if (unlikely (!closure))
return hb_face_get_empty ();
face = hb_face_create_for_tables (_hb_face_for_data_reference_table,
closure,
(hb_destroy_func_t) _hb_face_for_data_closure_destroy);
hb_face_set_index (face, index);
return face;
}
hb_face_t *
hb_face_get_empty (void)
{
return const_cast<hb_face_t *> (&_hb_face_nil);
}
hb_face_t *
hb_face_reference (hb_face_t *face)
{
return hb_object_reference (face);
}
void
hb_face_destroy (hb_face_t *face)
{
if (!hb_object_destroy (face)) return;
for (hb_face_t::plan_node_t *node = face->shape_plans; node; )
{
hb_face_t::plan_node_t *next = node->next;
hb_shape_plan_destroy (node->shape_plan);
free (node);
node = next;
}
#define HB_SHAPER_IMPLEMENT(shaper) HB_SHAPER_DATA_DESTROY(shaper, face);
#include "hb-shaper-list.hh"
#undef HB_SHAPER_IMPLEMENT
if (face->destroy)
face->destroy (face->user_data);
free (face);
}
hb_bool_t
hb_face_set_user_data (hb_face_t *face,
hb_user_data_key_t *key,
void * data,
hb_destroy_func_t destroy,
hb_bool_t replace)
{
return hb_object_set_user_data (face, key, data, destroy, replace);
}
void *
hb_face_get_user_data (hb_face_t *face,
hb_user_data_key_t *key)
{
return hb_object_get_user_data (face, key);
}
void
hb_face_make_immutable (hb_face_t *face)
{
if (hb_object_is_inert (face))
return;
face->immutable = true;
}
hb_bool_t
hb_face_is_immutable (hb_face_t *face)
{
return face->immutable;
}
hb_blob_t *
hb_face_reference_table (hb_face_t *face,
hb_tag_t tag)
{
return face->reference_table (tag);
}
hb_blob_t *
hb_face_reference_blob (hb_face_t *face)
{
return face->reference_table (HB_TAG_NONE);
}
void
hb_face_set_index (hb_face_t *face,
unsigned int index)
{
if (hb_object_is_inert (face))
return;
face->index = index;
}
unsigned int
hb_face_get_index (hb_face_t *face)
{
return face->index;
}
void
hb_face_set_upem (hb_face_t *face,
unsigned int upem)
{
if (hb_object_is_inert (face))
return;
face->upem = upem;
}
unsigned int
hb_face_get_upem (hb_face_t *face)
{
return face->get_upem ();
}
void
hb_face_t::load_upem (void) const
{
hb_blob_t *head_blob = OT::Sanitizer<OT::head>::sanitize (reference_table (HB_OT_TAG_head));
const OT::head *head_table = OT::Sanitizer<OT::head>::lock_instance (head_blob);
upem = head_table->get_upem ();
hb_blob_destroy (head_blob);
}
void
hb_face_set_glyph_count (hb_face_t *face,
unsigned int glyph_count)
{
if (hb_object_is_inert (face))
return;
face->num_glyphs = glyph_count;
}
unsigned int
hb_face_get_glyph_count (hb_face_t *face)
{
return face->get_num_glyphs ();
}
void
hb_face_t::load_num_glyphs (void) const
{
hb_blob_t *maxp_blob = OT::Sanitizer<OT::maxp>::sanitize (reference_table (HB_OT_TAG_maxp));
const OT::maxp *maxp_table = OT::Sanitizer<OT::maxp>::lock_instance (maxp_blob);
num_glyphs = maxp_table->get_num_glyphs ();
hb_blob_destroy (maxp_blob);
}