[API] Add support for vertical text

Design not final yet, and in fact I'm going to change it immediately,
but this is an standalone change for itself.
This commit is contained in:
Behdad Esfahbod 2011-05-16 18:15:37 -04:00
parent 80dce8b7c8
commit 744970af4d
12 changed files with 683 additions and 329 deletions

View File

@ -48,28 +48,33 @@ struct _hb_font_funcs_t {
/* Don't access these directly. Call hb_font_get_*() instead. */
#define HB_FONT_FUNCS_IMPLEMENT_CALLBACKS \
HB_FONT_FUNC_IMPLEMENT (glyph) \
HB_FONT_FUNC_IMPLEMENT (glyph_h_advance) \
HB_FONT_FUNC_IMPLEMENT (glyph_v_advance) \
HB_FONT_FUNC_IMPLEMENT (glyph_v_origin) \
HB_FONT_FUNC_IMPLEMENT (h_kerning) \
HB_FONT_FUNC_IMPLEMENT (v_kerning) \
HB_FONT_FUNC_IMPLEMENT (glyph_extents) \
HB_FONT_FUNC_IMPLEMENT (contour_point)
struct {
hb_font_get_contour_point_func_t contour_point;
hb_font_get_glyph_advance_func_t glyph_advance;
hb_font_get_glyph_extents_func_t glyph_extents;
hb_font_get_glyph_func_t glyph;
hb_font_get_kerning_func_t kerning;
#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_func_t name;
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
} get;
struct {
void *contour_point;
void *glyph_advance;
void *glyph_extents;
void *glyph;
void *kerning;
#define HB_FONT_FUNC_IMPLEMENT(name) void *name;
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
} user_data;
struct {
hb_destroy_func_t contour_point;
hb_destroy_func_t glyph_advance;
hb_destroy_func_t glyph_extents;
hb_destroy_func_t glyph;
hb_destroy_func_t kerning;
#define HB_FONT_FUNC_IMPLEMENT(name) hb_destroy_func_t name;
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
} destroy;
};

View File

@ -41,64 +41,6 @@ HB_BEGIN_DECLS
* hb_font_funcs_t
*/
static hb_bool_t
hb_font_get_contour_point_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_codepoint_t glyph,
unsigned int point_index,
hb_position_t *x,
hb_position_t *y,
void *user_data HB_UNUSED)
{
if (font->parent) {
hb_bool_t ret;
ret = hb_font_get_contour_point (font->parent,
glyph, point_index,
x, y);
font->parent_scale_position (x, y);
return ret;
}
*x = *y = 0;
return false;
}
static void
hb_font_get_glyph_advance_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_codepoint_t glyph,
hb_position_t *x_advance,
hb_position_t *y_advance,
void *user_data HB_UNUSED)
{
if (font->parent) {
hb_font_get_glyph_advance (font->parent, glyph, x_advance, y_advance);
font->parent_scale_distance (x_advance, y_advance);
return;
}
*x_advance = *y_advance = 0;
}
static void
hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
void *user_data HB_UNUSED)
{
if (font->parent) {
hb_font_get_glyph_extents (font->parent, glyph, extents);
font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
font->parent_scale_distance (&extents->width, &extents->height);
return;
}
extents->x_bearing = extents->y_bearing = 0;
extents->width = extents->height = 0;
}
static hb_bool_t
hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
@ -114,22 +56,152 @@ hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
return FALSE;
}
static void
hb_font_get_kerning_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_codepoint_t left_glyph,
hb_codepoint_t right_glyph,
hb_position_t *x_kern,
hb_position_t *y_kern,
void *user_data HB_UNUSED)
static hb_bool_t
hb_font_get_glyph_h_advance_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_codepoint_t glyph,
hb_position_t *x_advance,
hb_position_t *y_advance,
void *user_data HB_UNUSED)
{
if (font->parent) {
hb_font_get_kerning (font->parent, left_glyph, right_glyph, x_kern, y_kern);
hb_bool_t ret = hb_font_get_glyph_h_advance (font->parent,
glyph,
x_advance, y_advance);
font->parent_scale_distance (x_advance, y_advance);
return ret;
}
*x_advance = *y_advance = 0;
return FALSE;
}
static hb_bool_t
hb_font_get_glyph_v_advance_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_codepoint_t glyph,
hb_position_t *x_advance,
hb_position_t *y_advance,
void *user_data HB_UNUSED)
{
if (font->parent) {
hb_bool_t ret = hb_font_get_glyph_v_advance (font->parent,
glyph,
x_advance, y_advance);
font->parent_scale_distance (x_advance, y_advance);
return ret;
}
*x_advance = *y_advance = 0;
return FALSE;
}
static hb_bool_t
hb_font_get_glyph_v_origin_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_codepoint_t glyph,
hb_position_t *x_origin,
hb_position_t *y_origin,
void *user_data HB_UNUSED)
{
if (font->parent) {
hb_bool_t ret = hb_font_get_glyph_v_origin (font->parent,
glyph,
x_origin, y_origin);
font->parent_scale_distance (x_origin, y_origin);
return ret;
}
*x_origin = *y_origin = 0;
return FALSE;
}
static hb_bool_t
hb_font_get_h_kerning_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_codepoint_t left_glyph,
hb_codepoint_t right_glyph,
hb_position_t *x_kern,
hb_position_t *y_kern,
void *user_data HB_UNUSED)
{
if (font->parent) {
hb_bool_t ret = hb_font_get_h_kerning (font->parent,
left_glyph, right_glyph,
x_kern, y_kern);
font->parent_scale_distance (x_kern, y_kern);
return;
return ret;
}
*x_kern = *y_kern = 0;
return FALSE;
}
static hb_bool_t
hb_font_get_v_kerning_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_codepoint_t top_glyph,
hb_codepoint_t bottom_glyph,
hb_position_t *x_kern,
hb_position_t *y_kern,
void *user_data HB_UNUSED)
{
if (font->parent) {
hb_bool_t ret = hb_font_get_v_kerning (font->parent,
top_glyph, bottom_glyph,
x_kern, y_kern);
font->parent_scale_distance (x_kern, y_kern);
return ret;
}
*x_kern = *y_kern = 0;
return FALSE;
}
static hb_bool_t
hb_font_get_glyph_extents_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_codepoint_t glyph,
hb_bool_t *vertical,
hb_glyph_extents_t *extents,
void *user_data HB_UNUSED)
{
if (font->parent) {
hb_bool_t ret = hb_font_get_glyph_extents (font->parent,
glyph,
vertical,
extents);
font->parent_scale_position (&extents->x_bearing, &extents->y_bearing);
font->parent_scale_distance (&extents->width, &extents->height);
return ret;
}
extents->x_bearing = extents->y_bearing = 0;
extents->width = extents->height = 0;
return FALSE;
}
static hb_bool_t
hb_font_get_contour_point_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_codepoint_t glyph,
unsigned int point_index,
hb_bool_t *vertical,
hb_position_t *x,
hb_position_t *y,
void *user_data HB_UNUSED)
{
if (font->parent) {
hb_bool_t ret = hb_font_get_contour_point (font->parent,
glyph, point_index,
vertical,
x, y);
font->parent_scale_position (x, y);
return ret;
}
*x = *y = 0;
return FALSE;
}
@ -139,11 +211,9 @@ static hb_font_funcs_t _hb_font_funcs_nil = {
TRUE, /* immutable */
{
hb_font_get_contour_point_nil,
hb_font_get_glyph_advance_nil,
hb_font_get_glyph_extents_nil,
hb_font_get_glyph_nil,
hb_font_get_kerning_nil
#define HB_FONT_FUNC_IMPLEMENT(name) hb_font_get_##name##_nil,
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
}
};
@ -178,13 +248,9 @@ hb_font_funcs_destroy (hb_font_funcs_t *ffuncs)
{
if (!hb_object_destroy (ffuncs)) return;
#define DESTROY(name) if (ffuncs->destroy.name) ffuncs->destroy.name (ffuncs->user_data.name)
DESTROY (contour_point);
DESTROY (glyph_advance);
DESTROY (glyph_extents);
DESTROY (glyph);
DESTROY (kerning);
#undef DESTROY
#define HB_FONT_FUNC_IMPLEMENT(name) if (ffuncs->destroy.name) ffuncs->destroy.name (ffuncs->user_data.name);
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
free (ffuncs);
}
@ -222,7 +288,7 @@ hb_font_funcs_is_immutable (hb_font_funcs_t *ffuncs)
}
#define IMPLEMENT(name) \
#define HB_FONT_FUNC_IMPLEMENT(name) \
\
void \
hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
@ -247,47 +313,9 @@ hb_font_funcs_set_##name##_func (hb_font_funcs_t *ffuncs, \
} \
}
IMPLEMENT (contour_point);
IMPLEMENT (glyph_advance);
IMPLEMENT (glyph_extents);
IMPLEMENT (glyph);
IMPLEMENT (kerning);
HB_FONT_FUNCS_IMPLEMENT_CALLBACKS
#undef HB_FONT_FUNC_IMPLEMENT
#undef IMPLEMENT
hb_bool_t
hb_font_get_contour_point (hb_font_t *font,
hb_codepoint_t glyph, unsigned int point_index,
hb_position_t *x, hb_position_t *y)
{
*x = 0; *y = 0;
return font->klass->get.contour_point (font, font->user_data,
glyph, point_index,
x, y,
font->klass->user_data.contour_point);
}
void
hb_font_get_glyph_advance (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance)
{
*x_advance = *y_advance = 0;
return font->klass->get.glyph_advance (font, font->user_data,
glyph, x_advance, y_advance,
font->klass->user_data.glyph_advance);
}
void
hb_font_get_glyph_extents (hb_font_t *font,
hb_codepoint_t glyph, hb_glyph_extents_t *extents)
{
memset (extents, 0, sizeof (*extents));
return font->klass->get.glyph_extents (font, font->user_data,
glyph, extents,
font->klass->user_data.glyph_extents);
}
hb_bool_t
hb_font_get_glyph (hb_font_t *font,
@ -300,16 +328,165 @@ hb_font_get_glyph (hb_font_t *font,
font->klass->user_data.glyph);
}
void
hb_font_get_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
hb_position_t *x_kern, hb_position_t *y_kern)
hb_bool_t
hb_font_get_glyph_h_advance (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance)
{
*x_advance = *y_advance = 0;
return font->klass->get.glyph_h_advance (font, font->user_data,
glyph, x_advance, y_advance,
font->klass->user_data.glyph_h_advance);
}
hb_bool_t
hb_font_get_glyph_v_advance (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance)
{
*x_advance = *y_advance = 0;
return font->klass->get.glyph_v_advance (font, font->user_data,
glyph, x_advance, y_advance,
font->klass->user_data.glyph_v_advance);
}
hb_bool_t
hb_font_get_glyph_v_origin (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x_origin, hb_position_t *y_origin)
{
*x_origin = *y_origin = 0;
return font->klass->get.glyph_v_origin (font, font->user_data,
glyph, x_origin, y_origin,
font->klass->user_data.glyph_v_origin);
}
hb_bool_t
hb_font_get_h_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
hb_position_t *x_kern, hb_position_t *y_kern)
{
*x_kern = *y_kern = 0;
return font->klass->get.kerning (font, font->user_data,
left_glyph, right_glyph,
x_kern, y_kern,
font->klass->user_data.kerning);
return font->klass->get.h_kerning (font, font->user_data,
left_glyph, right_glyph,
x_kern, y_kern,
font->klass->user_data.h_kerning);
}
hb_bool_t
hb_font_get_v_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
hb_position_t *x_kern, hb_position_t *y_kern)
{
*x_kern = *y_kern = 0;
return font->klass->get.v_kerning (font, font->user_data,
left_glyph, right_glyph,
x_kern, y_kern,
font->klass->user_data.v_kerning);
}
hb_bool_t
hb_font_get_glyph_extents (hb_font_t *font,
hb_codepoint_t glyph,
hb_bool_t *vertical,
hb_glyph_extents_t *extents)
{
memset (extents, 0, sizeof (*extents));
return font->klass->get.glyph_extents (font, font->user_data,
glyph,
vertical,
extents,
font->klass->user_data.glyph_extents);
}
hb_bool_t
hb_font_get_contour_point (hb_font_t *font,
hb_codepoint_t glyph, unsigned int point_index,
hb_bool_t *vertical,
hb_position_t *x, hb_position_t *y)
{
*x = *y = 0;
return font->klass->get.contour_point (font, font->user_data,
glyph, point_index,
vertical,
x, y,
font->klass->user_data.contour_point);
}
/* A bit higher-level, and with fallback */
void
hb_font_get_glyph_advance_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
hb_direction_t direction,
hb_position_t *x_advance, hb_position_t *y_advance)
{
if (HB_DIRECTION_IS_VERTICAL (direction)) {
hb_bool_t ret = hb_font_get_glyph_v_advance (font, glyph, x_advance, y_advance);
if (!ret) {
/* TODO Simulate using h_advance and font_extents */
}
} else {
hb_font_get_glyph_h_advance (font, glyph, x_advance, y_advance);
}
}
void
hb_font_get_kerning_for_direction (hb_font_t *font,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
hb_direction_t direction,
hb_position_t *x_kern, hb_position_t *y_kern)
{
switch (direction) {
case HB_DIRECTION_LTR:
case HB_DIRECTION_RTL:
hb_font_get_h_kerning (font, first_glyph, second_glyph, x_kern, y_kern);
break;
case HB_DIRECTION_TTB:
case HB_DIRECTION_BTT:
hb_font_get_v_kerning (font, first_glyph, second_glyph, x_kern, y_kern);
break;
case HB_DIRECTION_INVALID:
default:
break;
}
}
void
hb_font_get_glyph_extents_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
hb_direction_t direction,
hb_glyph_extents_t *extents)
{
hb_bool_t vertical = HB_DIRECTION_IS_VERTICAL (direction);
hb_bool_t ret = hb_font_get_glyph_extents (font, glyph, &vertical, extents);
if (ret) {
if (vertical != HB_DIRECTION_IS_VERTICAL (direction)) {
/* XXX Adjust origin */
}
} else {
/* TODO Simulate using get_h_advance and font_extents? */
}
}
hb_bool_t
hb_font_get_contour_point_for_direction (hb_font_t *font,
hb_codepoint_t glyph, unsigned int point_index,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y)
{
hb_bool_t vertical = HB_DIRECTION_IS_VERTICAL (direction);
hb_bool_t ret = hb_font_get_contour_point (font, glyph, point_index, &vertical, x, y);
if (ret && vertical != HB_DIRECTION_IS_VERTICAL (direction)) {
/* XXX Adjust origin */
}
return ret;
}

View File

@ -134,42 +134,47 @@ typedef struct _hb_glyph_extents_t
} hb_glyph_extents_t;
typedef hb_bool_t (*hb_font_get_contour_point_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph, unsigned int point_index,
hb_position_t *x, hb_position_t *y,
void *user_data);
typedef void (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance,
void *user_data);
typedef void (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
void *user_data);
/* func types */
typedef hb_bool_t (*hb_font_get_glyph_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
void *user_data);
typedef void (*hb_font_get_kerning_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
hb_position_t *x_kern, hb_position_t *y_kern,
void *user_data);
void
hb_font_funcs_set_contour_point_func (hb_font_funcs_t *ffuncs,
hb_font_get_contour_point_func_t contour_point_func,
void *user_data, hb_destroy_func_t destroy);
typedef hb_bool_t (*hb_font_get_glyph_advance_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance,
void *user_data);
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_h_advance_func_t;
typedef hb_font_get_glyph_advance_func_t hb_font_get_glyph_v_advance_func_t;
void
hb_font_funcs_set_glyph_advance_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_advance_func_t glyph_advance_func,
void *user_data, hb_destroy_func_t destroy);
typedef hb_bool_t (*hb_font_get_glyph_v_origin_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_position_t *x_origin, hb_position_t *y_origin,
void *user_data);
void
hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_extents_func_t glyph_extents_func,
void *user_data, hb_destroy_func_t destroy);
typedef hb_bool_t (*hb_font_get_kerning_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
hb_position_t *x_kern, hb_position_t *y_kern,
void *user_data);
typedef hb_font_get_kerning_func_t hb_font_get_h_kerning_func_t;
typedef hb_font_get_kerning_func_t hb_font_get_v_kerning_func_t;
typedef hb_bool_t (*hb_font_get_glyph_extents_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_bool_t *vertical,
hb_glyph_extents_t *extents,
void *user_data);
typedef hb_bool_t (*hb_font_get_contour_point_func_t) (hb_font_t *font, void *font_data,
hb_codepoint_t glyph, unsigned int point_index,
hb_bool_t *vertical,
hb_position_t *x, hb_position_t *y,
void *user_data);
/* func setters */
void
hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
@ -177,35 +182,106 @@ hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
void *user_data, hb_destroy_func_t destroy);
void
hb_font_funcs_set_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_kerning_func_t kerning_func,
void *user_data, hb_destroy_func_t destroy);
hb_bool_t
hb_font_get_contour_point (hb_font_t *font,
hb_codepoint_t glyph, unsigned int point_index,
hb_position_t *x, hb_position_t *y);
hb_font_funcs_set_glyph_h_advance_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_h_advance_func_t glyph_advance_func,
void *user_data, hb_destroy_func_t destroy);
void
hb_font_funcs_set_glyph_v_advance_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_advance_func_t glyph_advance_func,
void *user_data, hb_destroy_func_t destroy);
void
hb_font_get_glyph_advance (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance);
hb_font_funcs_set_glyph_v_origin_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_v_origin_func_t glyph_advance_func,
void *user_data, hb_destroy_func_t destroy);
void
hb_font_get_glyph_extents (hb_font_t *font,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents);
hb_font_funcs_set_h_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_h_kerning_func_t kerning_func,
void *user_data, hb_destroy_func_t destroy);
void
hb_font_funcs_set_v_kerning_func (hb_font_funcs_t *ffuncs,
hb_font_get_v_kerning_func_t kerning_func,
void *user_data, hb_destroy_func_t destroy);
void
hb_font_funcs_set_glyph_extents_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_extents_func_t glyph_extents_func,
void *user_data, hb_destroy_func_t destroy);
void
hb_font_funcs_set_contour_point_func (hb_font_funcs_t *ffuncs,
hb_font_get_contour_point_func_t contour_point_func,
void *user_data, hb_destroy_func_t destroy);
/* func dispatch */
hb_bool_t
hb_font_get_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph);
hb_bool_t
hb_font_get_glyph_h_advance (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance);
hb_bool_t
hb_font_get_glyph_v_advance (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance);
hb_bool_t
hb_font_get_glyph_v_origin (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x_kern, hb_position_t *y_kern);
hb_bool_t
hb_font_get_h_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
hb_position_t *x_kern, hb_position_t *y_kern);
hb_bool_t
hb_font_get_v_kerning (hb_font_t *font,
hb_codepoint_t top_glyph, hb_codepoint_t bottom_glyph,
hb_position_t *x_kern, hb_position_t *y_kern);
hb_bool_t
hb_font_get_glyph_extents (hb_font_t *font,
hb_codepoint_t glyph,
hb_bool_t *vertical,
hb_glyph_extents_t *extents);
hb_bool_t
hb_font_get_contour_point (hb_font_t *font,
hb_codepoint_t glyph, unsigned int point_index,
hb_bool_t *vertical,
hb_position_t *x, hb_position_t *y);
/* high-level funcs, with fallback */
void
hb_font_get_kerning (hb_font_t *font,
hb_codepoint_t left_glyph, hb_codepoint_t right_glyph,
hb_position_t *x_kern, hb_position_t *y_kern);
hb_font_get_glyph_advance_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
hb_direction_t direction,
hb_position_t *x_advance, hb_position_t *y_advance);
void
hb_font_get_kerning_for_direction (hb_font_t *font,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph,
hb_direction_t direction,
hb_position_t *x_kern, hb_position_t *y_kern);
void
hb_font_get_glyph_extents_for_direction (hb_font_t *font,
hb_codepoint_t glyph,
hb_direction_t direction,
hb_glyph_extents_t *extents);
hb_bool_t
hb_font_get_contour_point_for_direction (hb_font_t *font,
hb_codepoint_t glyph, unsigned int point_index,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y);
/*

View File

@ -36,76 +36,24 @@
HB_BEGIN_DECLS
static hb_bool_t
hb_ft_get_contour_point (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t glyph,
unsigned int point_index,
hb_position_t *x,
hb_position_t *y,
void *user_data HB_UNUSED)
{
FT_Face ft_face = (FT_Face) font_data;
int load_flags = FT_LOAD_DEFAULT;
/* TODO:
*
* In general, this file does a fine job of what it's supposed to do.
* There are, however, things that need more work:
*
* - We don't handle any load_flags. That definitely has API implications. :(
* I believe hb_ft_font_create() should take load_flags input.
*
* - We don't handle / allow for emboldening / obliqueing.
*
* - In the future, we should add constructors to create fonts in font space.
*
* - I believe transforms are not correctly implemented. FreeType does not
* provide any API to get to the transform/delta set on the face. :(
*
* - Always use FT_LOAD_IGNORE_GLOBAL_ADVANCE_WIDTH?
*/
/* TODO: load_flags, embolden, etc */
if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
return FALSE;
if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
return FALSE;
if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
return FALSE;
*x = ft_face->glyph->outline.points[point_index].x;
*y = ft_face->glyph->outline.points[point_index].y;
return TRUE;
}
static void
hb_ft_get_glyph_advance (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t glyph,
hb_position_t *x_advance,
hb_position_t *y_advance,
void *user_data HB_UNUSED)
{
FT_Face ft_face = (FT_Face) font_data;
int load_flags = FT_LOAD_DEFAULT;
/* TODO: load_flags, embolden, etc */
if (likely (!FT_Load_Glyph (ft_face, glyph, load_flags)))
{
*x_advance = ft_face->glyph->advance.x;
*y_advance = ft_face->glyph->advance.y;
}
}
static void
hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t glyph,
hb_glyph_extents_t *extents,
void *user_data HB_UNUSED)
{
FT_Face ft_face = (FT_Face) font_data;
int load_flags = FT_LOAD_DEFAULT;
/* TODO: load_flags, embolden, etc */
if (likely (!FT_Load_Glyph (ft_face, glyph, load_flags)))
{
/* XXX: A few negations should be in order here, not sure. */
extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
extents->width = ft_face->glyph->metrics.width;
extents->height = ft_face->glyph->metrics.height;
}
}
static hb_bool_t
hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
@ -130,23 +78,144 @@ hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
return *glyph != 0;
}
static void
hb_ft_get_kerning (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t left_glyph,
hb_codepoint_t right_glyph,
hb_position_t *x_kern,
hb_position_t *y_kern,
void *user_data HB_UNUSED)
static hb_bool_t
hb_ft_get_glyph_h_advance (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t glyph,
hb_position_t *x_advance,
hb_position_t *y_advance,
void *user_data HB_UNUSED)
{
FT_Face ft_face = (FT_Face) font_data;
int load_flags = FT_LOAD_DEFAULT;
if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
return FALSE;
*x_advance = ft_face->glyph->metrics.horiAdvance;
return TRUE;
}
static hb_bool_t
hb_ft_get_glyph_v_advance (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t glyph,
hb_position_t *x_advance,
hb_position_t *y_advance,
void *user_data HB_UNUSED)
{
FT_Face ft_face = (FT_Face) font_data;
int load_flags = FT_LOAD_DEFAULT;
if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
return FALSE;
*y_advance = -ft_face->glyph->metrics.vertAdvance;
return TRUE;
}
static hb_bool_t
hb_ft_get_glyph_v_origin (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t glyph,
hb_position_t *x_origin,
hb_position_t *y_origin,
void *user_data HB_UNUSED)
{
FT_Face ft_face = (FT_Face) font_data;
int load_flags = FT_LOAD_DEFAULT;
if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
return FALSE;
*y_origin = ft_face->glyph->metrics.vertAdvance;
return TRUE;
}
static hb_bool_t
hb_ft_get_h_kerning (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t left_glyph,
hb_codepoint_t right_glyph,
hb_position_t *x_kern,
hb_position_t *y_kern,
void *user_data HB_UNUSED)
{
FT_Face ft_face = (FT_Face) font_data;
FT_Vector kerning;
if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerning))
return;
return FALSE;
*x_kern = kerning.x;
*y_kern = kerning.y;
return TRUE;
}
static hb_bool_t
hb_ft_get_v_kerning (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t top_glyph,
hb_codepoint_t bottom_glyph,
hb_position_t *x_kern,
hb_position_t *y_kern,
void *user_data HB_UNUSED)
{
/* FreeType API doesn't support vertical kerning */
return FALSE;
}
static hb_bool_t
hb_ft_get_glyph_extents (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t glyph,
hb_bool_t *vertical,
hb_glyph_extents_t *extents,
void *user_data HB_UNUSED)
{
FT_Face ft_face = (FT_Face) font_data;
int load_flags = FT_LOAD_DEFAULT;
/* TODO: load_flags, embolden, etc, shape/transform */
if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
return FALSE;
/* XXX: A few negations should be in order here, not sure. */
extents->x_bearing = ft_face->glyph->metrics.horiBearingX;
extents->y_bearing = ft_face->glyph->metrics.horiBearingY;
extents->width = ft_face->glyph->metrics.width;
extents->height = ft_face->glyph->metrics.height;
return TRUE;
}
static hb_bool_t
hb_ft_get_contour_point (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t glyph,
unsigned int point_index,
hb_bool_t *vertical,
hb_position_t *x,
hb_position_t *y,
void *user_data HB_UNUSED)
{
FT_Face ft_face = (FT_Face) font_data;
int load_flags = FT_LOAD_DEFAULT;
if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
return FALSE;
if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
return FALSE;
if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
return FALSE;
*x = ft_face->glyph->outline.points[point_index].x;
*y = ft_face->glyph->outline.points[point_index].y;
*vertical = FALSE; /* We always return position in horizontal coordinates */
return TRUE;
}
static hb_font_funcs_t ft_ffuncs = {
@ -155,11 +224,14 @@ static hb_font_funcs_t ft_ffuncs = {
TRUE, /* immutable */
{
hb_ft_get_contour_point,
hb_ft_get_glyph_advance,
hb_ft_get_glyph_extents,
hb_ft_get_glyph,
hb_ft_get_kerning
hb_ft_get_glyph_h_advance,
hb_ft_get_glyph_v_advance,
hb_ft_get_glyph_v_origin,
hb_ft_get_h_kerning,
hb_ft_get_v_kerning,
hb_ft_get_glyph_extents,
hb_ft_get_contour_point,
}
};
@ -210,7 +282,10 @@ hb_ft_face_create (FT_Face ft_face,
blob = hb_blob_create ((const char *) ft_face->stream->base,
(unsigned int) ft_face->stream->size,
/* TODO: Check FT_FACE_FLAG_EXTERNAL_STREAM? */
/* TODO: We assume that it's mmap()'ed, but FreeType code
* suggests that there are cases we reach here but font is
* not mmapped. For example, when mmap() fails. No idea
* how to deal with it better here. */
HB_MEMORY_MODE_READONLY_MAY_MAKE_WRITABLE,
ft_face, destroy);
face = hb_face_create (blob, ft_face->face_index);

View File

@ -121,7 +121,7 @@ struct CaretValueFormat2
inline int get_caret_value (hb_font_t *font, hb_direction_t direction, hb_codepoint_t glyph_id) const
{
hb_position_t x, y;
if (hb_font_get_contour_point (font, glyph_id, caretValuePoint, &x, &y))
if (hb_font_get_contour_point_for_direction (font, glyph_id, caretValuePoint, direction, &x, &y))
return HB_DIRECTION_IS_HORIZONTAL (direction) ? x : y;
else
return 0;

View File

@ -210,6 +210,7 @@ struct AnchorFormat1
private:
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
hb_direction_t direction HB_UNUSED,
hb_position_t *x, hb_position_t *y) const
{
*x = font->em_scale_x (xCoordinate);
@ -235,6 +236,7 @@ struct AnchorFormat2
private:
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y) const
{
unsigned int x_ppem = font->x_ppem;
@ -243,7 +245,7 @@ struct AnchorFormat2
hb_bool_t ret = false;
if (x_ppem || y_ppem)
ret = hb_font_get_contour_point (font, glyph_id, anchorPoint, &cx, &cy);
ret = hb_font_get_contour_point_for_direction (font, glyph_id, anchorPoint, direction, &cx, &cy);
*x = x_ppem && ret ? cx : font->em_scale_x (xCoordinate);
*y = y_ppem && ret ? cy : font->em_scale_y (yCoordinate);
}
@ -268,6 +270,7 @@ struct AnchorFormat3
private:
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id HB_UNUSED,
hb_direction_t direction HB_UNUSED,
hb_position_t *x, hb_position_t *y) const
{
*x = font->em_scale_x (xCoordinate);
@ -306,14 +309,15 @@ struct AnchorFormat3
struct Anchor
{
inline void get_anchor (hb_font_t *font, hb_codepoint_t glyph_id,
hb_direction_t direction,
hb_position_t *x, hb_position_t *y) const
{
*x = *y = 0;
switch (u.format) {
case 1: u.format1.get_anchor (font, glyph_id, x, y); return;
case 2: u.format2.get_anchor (font, glyph_id, x, y); return;
case 3: u.format3.get_anchor (font, glyph_id, x, y); return;
default: return;
case 1: u.format1.get_anchor (font, glyph_id, direction, x, y); return;
case 2: u.format2.get_anchor (font, glyph_id, direction, x, y); return;
case 3: u.format3.get_anchor (font, glyph_id, direction, x, y); return;
default: return;
}
}
@ -403,8 +407,8 @@ struct MarkArray : ArrayOf<MarkRecord> /* Array of MarkRecords--in Coverage orde
hb_position_t mark_x, mark_y, base_x, base_y;
mark_anchor.get_anchor (c->font, c->buffer->info[c->buffer->i].codepoint, &mark_x, &mark_y);
glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, &base_x, &base_y);
mark_anchor.get_anchor (c->font, c->buffer->info[c->buffer->i].codepoint, c->direction, &mark_x, &mark_y);
glyph_anchor.get_anchor (c->font, c->buffer->info[glyph_pos].codepoint, c->direction, &base_x, &base_y);
hb_glyph_position_t &o = c->buffer->pos[c->buffer->i];
o.x_offset = base_x - mark_x;
@ -859,23 +863,21 @@ struct CursivePosFormat1
unsigned int i = c->buffer->i;
hb_position_t entry_x, entry_y, exit_x, exit_y;
(this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, &exit_x, &exit_y);
(this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codepoint, &entry_x, &entry_y);
hb_direction_t direction = c->buffer->props.direction;
(this+this_record.exitAnchor).get_anchor (c->font, c->buffer->info[i].codepoint, c->direction, &exit_x, &exit_y);
(this+next_record.entryAnchor).get_anchor (c->font, c->buffer->info[j].codepoint, c->direction, &entry_x, &entry_y);
/* Align the exit anchor of the left/top glyph with the entry anchor of the right/bottom glyph
* by adjusting advance of the left/top glyph. */
if (HB_DIRECTION_IS_BACKWARD (direction))
if (HB_DIRECTION_IS_BACKWARD (c->direction))
{
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
c->buffer->pos[j].x_advance = c->buffer->pos[j].x_offset + entry_x - exit_x;
else
c->buffer->pos[j].y_advance = c->buffer->pos[j].y_offset + entry_y - exit_y;
}
else
{
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
c->buffer->pos[i].x_advance = c->buffer->pos[i].x_offset + exit_x - entry_x;
else
c->buffer->pos[i].y_advance = c->buffer->pos[i].y_offset + exit_y - entry_y;
@ -884,7 +886,7 @@ struct CursivePosFormat1
if (c->lookup_props & LookupFlag::RightToLeft)
{
c->buffer->pos[i].cursive_chain() = j - i;
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
c->buffer->pos[i].y_offset = entry_y - exit_y;
else
c->buffer->pos[i].x_offset = entry_x - exit_x;
@ -892,7 +894,7 @@ struct CursivePosFormat1
else
{
c->buffer->pos[j].cursive_chain() = i - j;
if (likely (HB_DIRECTION_IS_HORIZONTAL (direction)))
if (likely (HB_DIRECTION_IS_HORIZONTAL (c->direction)))
c->buffer->pos[j].y_offset = exit_y - entry_y;
else
c->buffer->pos[j].x_offset = exit_x - entry_x;
@ -1414,6 +1416,7 @@ struct PosLookup : Lookup
c->font = font;
c->face = font->face;
c->buffer = buffer;
c->direction = buffer->props.direction;
c->lookup_mask = lookup_mask;
c->context_length = context_length;
c->nesting_level_left = nesting_level_left;

View File

@ -773,6 +773,7 @@ struct SubstLookup : Lookup
c->face = face;
c->buffer = buffer;
c->direction = buffer->props.direction;
c->lookup_mask = lookup_mask;
c->context_length = context_length;
c->nesting_level_left = nesting_level_left;

View File

@ -56,6 +56,7 @@ struct hb_apply_context_t
hb_font_t *font;
hb_face_t *face;
hb_buffer_t *buffer;
hb_direction_t direction;
hb_mask_t lookup_mask;
unsigned int context_length;
unsigned int nesting_level_left;

View File

@ -169,7 +169,7 @@ hb_ensure_native_direction (hb_ot_shape_context_t *c)
{
hb_direction_t direction = c->buffer->props.direction;
/* TODO vertical */
/* XXX vertical */
if (HB_DIRECTION_IS_HORIZONTAL (direction) &&
direction != hb_script_get_horizontal_direction (c->buffer->props.script))
{
@ -258,9 +258,10 @@ hb_position_default (hb_ot_shape_context_t *c)
unsigned int count = c->buffer->len;
for (unsigned int i = 0; i < count; i++) {
hb_font_get_glyph_advance (c->font, c->buffer->info[i].codepoint,
&c->buffer->pos[i].x_advance,
&c->buffer->pos[i].y_advance);
hb_font_get_glyph_advance_for_direction (c->font, c->buffer->info[i].codepoint,
c->buffer->props.direction,
&c->buffer->pos[i].x_advance,
&c->buffer->pos[i].y_advance);
}
}
@ -277,7 +278,10 @@ hb_truetype_kern (hb_ot_shape_context_t *c)
unsigned int count = c->buffer->len;
for (unsigned int i = 1; i < count; i++) {
hb_position_t x_kern, y_kern, kern1, kern2;
hb_font_get_kerning (c->font, c->buffer->info[i - 1].codepoint, c->buffer->info[i].codepoint, &x_kern, &y_kern);
hb_font_get_kerning_for_direction (c->font,
c->buffer->info[i - 1].codepoint, c->buffer->info[i].codepoint,
c->buffer->props.direction,
&x_kern, &y_kern);
kern1 = x_kern >> 1;
kern2 = x_kern - kern1;

View File

@ -686,7 +686,7 @@ hb_ot_tag_to_language (hb_tag_t tag)
}
}
/* Else return a custom language in the form of "x-hbotXXXX" */
/* Else return a custom language in the form of "x-hbotABCD" */
{
unsigned char buf[11] = "x-hbot";
buf[6] = tag >> 24;

View File

@ -117,18 +117,18 @@ _test_font_nil_funcs (hb_font_t *font)
hb_glyph_extents_t extents;
x = y = 13;
g_assert (!hb_font_get_contour_point (font, 17, 2, &x, &y));
g_assert (!hb_font_get_contour_point (font, 17, 2, HB_DIRECTION_LTR, &x, &y));
g_assert_cmpint (x, ==, 0);
g_assert_cmpint (y, ==, 0);
x = y = 13;
hb_font_get_glyph_advance (font, 17, &x, &y);
hb_font_get_glyph_h_advance (font, 17, &x, &y);
g_assert_cmpint (x, ==, 0);
g_assert_cmpint (y, ==, 0);
extents.x_bearing = extents.y_bearing = 13;
extents.width = extents.height = 15;
hb_font_get_glyph_extents (font, 17, &extents);
hb_font_get_glyph_extents (font, 17, HB_DIRECTION_LTR, &extents);
g_assert_cmpint (extents.x_bearing, ==, 0);
g_assert_cmpint (extents.y_bearing, ==, 0);
g_assert_cmpint (extents.width, ==, 0);
@ -139,7 +139,7 @@ _test_font_nil_funcs (hb_font_t *font)
g_assert_cmpint (glyph, ==, 0);
x = y = 13;
hb_font_get_kerning (font, 17, 19, &x, &y);
hb_font_get_h_kerning (font, 17, 19, &x, &y);
g_assert_cmpint (x, ==, 0);
g_assert_cmpint (y, ==, 0);
}
@ -158,6 +158,7 @@ _test_fontfuncs_nil (hb_font_funcs_t *ffuncs)
hb_blob_destroy (blob);
g_assert (!hb_face_is_immutable (face));
font = hb_font_create (face);
g_assert (font);
g_assert (hb_face_is_immutable (face));
hb_face_destroy (face);
@ -168,6 +169,7 @@ _test_fontfuncs_nil (hb_font_funcs_t *ffuncs)
_test_font_nil_funcs (font);
subfont = hb_font_create_sub_font (font);
g_assert (subfont);
g_assert_cmpint (freed, ==, 0);
hb_font_destroy (font);
@ -203,9 +205,12 @@ test_fontfuncs_nil (void)
static hb_bool_t
contour_point_func1 (hb_font_t *font, void *font_data,
hb_codepoint_t glyph, unsigned int point_index,
hb_bool_t *vertical,
hb_position_t *x, hb_position_t *y,
void *user_data)
{
*vertical = FALSE;
if (glyph == 1) {
*x = 2;
*y = 3;
@ -223,6 +228,7 @@ contour_point_func1 (hb_font_t *font, void *font_data,
static hb_bool_t
contour_point_func2 (hb_font_t *font, void *font_data,
hb_codepoint_t glyph, unsigned int point_index,
hb_bool_t *vertical,
hb_position_t *x, hb_position_t *y,
void *user_data)
{
@ -233,19 +239,22 @@ contour_point_func2 (hb_font_t *font, void *font_data,
}
return hb_font_get_contour_point (hb_font_get_parent (font),
glyph, point_index, x, y);
glyph, point_index, vertical, x, y);
}
static void
glyph_advance_func1 (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance,
void *user_data)
static hb_bool_t
glyph_h_advance_func1 (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance,
void *user_data)
{
if (glyph == 1) {
*x_advance = 8;
*y_advance = 9;
return TRUE;
}
return FALSE;
}
static void
@ -274,24 +283,24 @@ test_fontfuncs_subclassing (void)
/* setup font1 */
ffuncs1 = hb_font_funcs_create ();
hb_font_funcs_set_contour_point_func (ffuncs1, contour_point_func1, NULL, NULL);
hb_font_funcs_set_glyph_advance_func (ffuncs1, glyph_advance_func1, NULL, NULL);
hb_font_funcs_set_glyph_h_advance_func (ffuncs1, glyph_h_advance_func1, NULL, NULL);
hb_font_set_funcs (font1, ffuncs1, NULL, NULL);
hb_font_funcs_destroy (ffuncs1);
x = y = 1;
g_assert (hb_font_get_contour_point (font1, 1, 2, &x, &y));
g_assert (hb_font_get_contour_point_for_direction (font1, 1, 2, HB_DIRECTION_LTR, &x, &y));
g_assert_cmpint (x, ==, 2);
g_assert_cmpint (y, ==, 3);
g_assert (hb_font_get_contour_point (font1, 2, 5, &x, &y));
g_assert (hb_font_get_contour_point_for_direction (font1, 2, 5, HB_DIRECTION_LTR, &x, &y));
g_assert_cmpint (x, ==, 4);
g_assert_cmpint (y, ==, 5);
g_assert (!hb_font_get_contour_point (font1, 3, 7, &x, &y));
g_assert (!hb_font_get_contour_point_for_direction (font1, 3, 7, HB_DIRECTION_RTL, &x, &y));
g_assert_cmpint (x, ==, 0);
g_assert_cmpint (y, ==, 0);
hb_font_get_glyph_advance (font1, 1, &x, &y);
hb_font_get_glyph_h_advance (font1, 1, &x, &y);
g_assert_cmpint (x, ==, 8);
g_assert_cmpint (y, ==, 9);
hb_font_get_glyph_advance (font1, 2, &x, &y);
hb_font_get_glyph_h_advance (font1, 2, &x, &y);
g_assert_cmpint (x, ==, 0);
g_assert_cmpint (y, ==, 0);
@ -307,19 +316,19 @@ test_fontfuncs_subclassing (void)
hb_font_funcs_destroy (ffuncs2);
x = y = 1;
g_assert (hb_font_get_contour_point (font2, 1, 2, &x, &y));
g_assert (hb_font_get_contour_point_for_direction (font2, 1, 2, HB_DIRECTION_LTR, &x, &y));
g_assert_cmpint (x, ==, 6);
g_assert_cmpint (y, ==, 7);
g_assert (hb_font_get_contour_point (font2, 2, 5, &x, &y));
g_assert (hb_font_get_contour_point_for_direction (font2, 2, 5, HB_DIRECTION_RTL, &x, &y));
g_assert_cmpint (x, ==, 4);
g_assert_cmpint (y, ==, 5);
g_assert (!hb_font_get_contour_point (font2, 3, 7, &x, &y));
g_assert (!hb_font_get_contour_point_for_direction (font2, 3, 7, HB_DIRECTION_LTR, &x, &y));
g_assert_cmpint (x, ==, 0);
g_assert_cmpint (y, ==, 0);
hb_font_get_glyph_advance (font2, 1, &x, &y);
hb_font_get_glyph_h_advance (font2, 1, &x, &y);
g_assert_cmpint (x, ==, 8);
g_assert_cmpint (y, ==, 9);
hb_font_get_glyph_advance (font2, 2, &x, &y);
hb_font_get_glyph_h_advance (font2, 2, &x, &y);
g_assert_cmpint (x, ==, 0);
g_assert_cmpint (y, ==, 0);
@ -332,19 +341,19 @@ test_fontfuncs_subclassing (void)
hb_font_set_scale (font3, 20, 30);
x = y = 1;
g_assert (hb_font_get_contour_point (font3, 1, 2, &x, &y));
g_assert (hb_font_get_contour_point_for_direction (font3, 1, 2, HB_DIRECTION_RTL, &x, &y));
g_assert_cmpint (x, ==, 6*2);
g_assert_cmpint (y, ==, 7*3);
g_assert (hb_font_get_contour_point (font3, 2, 5, &x, &y));
g_assert (hb_font_get_contour_point_for_direction (font3, 2, 5, HB_DIRECTION_LTR, &x, &y));
g_assert_cmpint (x, ==, 4*2);
g_assert_cmpint (y, ==, 5*3);
g_assert (!hb_font_get_contour_point (font3, 3, 7, &x, &y));
g_assert (!hb_font_get_contour_point_for_direction (font3, 3, 7, HB_DIRECTION_LTR, &x, &y));
g_assert_cmpint (x, ==, 0*2);
g_assert_cmpint (y, ==, 0*3);
hb_font_get_glyph_advance (font3, 1, &x, &y);
hb_font_get_glyph_h_advance (font3, 1, &x, &y);
g_assert_cmpint (x, ==, 8*2);
g_assert_cmpint (y, ==, 9*3);
hb_font_get_glyph_advance (font3, 2, &x, &y);
hb_font_get_glyph_h_advance (font3, 2, &x, &y);
g_assert_cmpint (x, ==, 0*2);
g_assert_cmpint (y, ==, 0*3);

View File

@ -37,17 +37,18 @@
static const char test_data[] = "test\0data";
static void
static hb_bool_t
glyph_advance_func (hb_font_t *font, void *font_data,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance,
void *user_data)
{
switch (glyph) {
case 1: *x_advance = 10; return;
case 2: *x_advance = 6; return;
case 3: *x_advance = 5; return;
case 1: *x_advance = 10; return TRUE;
case 2: *x_advance = 6; return TRUE;
case 3: *x_advance = 5; return TRUE;
}
return FALSE;
}
static hb_bool_t
@ -65,7 +66,7 @@ glyph_func (hb_font_t *font, void *font_data,
return FALSE;
}
static void
static hb_bool_t
kerning_func (hb_font_t *font, void *font_data,
hb_codepoint_t left, hb_codepoint_t right,
hb_position_t *x_kern, hb_position_t *y_kern,
@ -73,7 +74,9 @@ kerning_func (hb_font_t *font, void *font_data,
{
if (left == 1 && right == 2) {
*x_kern = -2;
return TRUE;
}
return FALSE;
}
static const char TesT[] = "TesT";
@ -98,9 +101,9 @@ test_shape (void)
hb_font_set_scale (font, 10, 10);
ffuncs = hb_font_funcs_create ();
hb_font_funcs_set_glyph_advance_func (ffuncs, glyph_advance_func, NULL, NULL);
hb_font_funcs_set_glyph_h_advance_func (ffuncs, glyph_advance_func, NULL, NULL);
hb_font_funcs_set_glyph_func (ffuncs, glyph_func, NULL, NULL);
hb_font_funcs_set_kerning_func (ffuncs, kerning_func, NULL, NULL);
hb_font_funcs_set_h_kerning_func (ffuncs, kerning_func, NULL, NULL);
hb_font_set_funcs (font, ffuncs, NULL, NULL);
hb_font_funcs_destroy (ffuncs);