[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.
pull/1/head
Behdad Esfahbod 14 years ago
parent 80dce8b7c8
commit 744970af4d
  1. 35
      src/hb-font-private.hh
  2. 387
      src/hb-font.cc
  3. 164
      src/hb-font.h
  4. 227
      src/hb-ft.cc
  5. 2
      src/hb-ot-layout-gdef-private.hh
  6. 35
      src/hb-ot-layout-gpos-private.hh
  7. 1
      src/hb-ot-layout-gsub-private.hh
  8. 1
      src/hb-ot-layout-gsubgpos-private.hh
  9. 14
      src/hb-ot-shape.cc
  10. 2
      src/hb-ot-tag.cc
  11. 61
      test/test-font.c
  12. 17
      test/test-shape.c

@ -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;
};

@ -42,94 +42,166 @@ HB_BEGIN_DECLS
*/
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)
hb_font_get_glyph_nil (hb_font_t *font HB_UNUSED,
void *font_data HB_UNUSED,
hb_codepoint_t unicode,
hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED)
{
if (font->parent)
return hb_font_get_glyph (font->parent, unicode, variation_selector, glyph);
*glyph = 0;
return FALSE;
}
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_bool_t ret;
ret = hb_font_get_contour_point (font->parent,
glyph, point_index,
x, y);
font->parent_scale_position (x, y);
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 = *y = 0;
return false;
*x_advance = *y_advance = 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)
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_font_get_glyph_advance (font->parent, glyph, x_advance, y_advance);
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;
return ret;
}
*x_advance = *y_advance = 0;
return FALSE;
}
static void
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 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_font_get_glyph_extents (font->parent, glyph, extents);
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;
return ret;
}
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,
hb_codepoint_t unicode,
hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED)
{
if (font->parent)
return hb_font_get_glyph (font->parent, unicode, variation_selector, glyph);
*glyph = 0;
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_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_font_get_kerning (font->parent, left_glyph, right_glyph, x_kern, y_kern);
font->parent_scale_distance (x_kern, y_kern);
return;
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_kern = *y_kern = 0;
*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,69 +313,180 @@ 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_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph)
{
*glyph = 0;
return font->klass->get.glyph (font, font->user_data,
unicode, variation_selector, glyph,
font->klass->user_data.glyph);
}
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_get_glyph_h_advance (hb_font_t *font,
hb_codepoint_t glyph,
hb_position_t *x_advance, hb_position_t *y_advance)
{
*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);
*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);
}
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_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_advance (font, font->user_data,
glyph, x_advance, y_advance,
font->klass->user_data.glyph_advance);
return font->klass->get.glyph_v_advance (font, font->user_data,
glyph, x_advance, y_advance,
font->klass->user_data.glyph_v_advance);
}
void
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.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_glyph_extents_t *extents)
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, extents,
glyph,
vertical,
extents,
font->klass->user_data.glyph_extents);
}
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_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)
{
*glyph = 0;
return font->klass->get.glyph (font, font->user_data,
unicode, variation_selector, glyph,
font->klass->user_data.glyph);
*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_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)
{
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)
{
*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);
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;
}

@ -134,78 +134,154 @@ 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);
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;
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);
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_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);
hb_font_funcs_set_glyph_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_func_t glyph_func,
void *user_data, hb_destroy_func_t destroy);
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);
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_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_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_glyph_func (hb_font_funcs_t *ffuncs,
hb_font_get_glyph_func_t glyph_func,
void *user_data, hb_destroy_func_t destroy);
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);
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);
/* func dispatch */
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_get_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph);
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_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);
void
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_glyph (hb_font_t *font,
hb_codepoint_t unicode, hb_codepoint_t variation_selector,
hb_codepoint_t *glyph);
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_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 (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_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);
/*

@ -36,117 +36,186 @@
HB_BEGIN_DECLS
/* 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?
*/
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)
hb_ft_get_glyph (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t unicode,
hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED)
{
FT_Face ft_face = (FT_Face) font_data;
int load_flags = FT_LOAD_DEFAULT;
/* TODO: load_flags, embolden, etc */
#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX
if (unlikely (variation_selector)) {
*glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
if (*glyph)
return TRUE;
}
#endif
*glyph = FT_Get_Char_Index (ft_face, unicode);
return *glyph != 0;
}
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;
return FALSE;
if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
return FALSE;
*x_advance = ft_face->glyph->metrics.horiAdvance;
return TRUE;
}
if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
return FALSE;
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;
*x = ft_face->glyph->outline.points[point_index].x;
*y = ft_face->glyph->outline.points[point_index].y;
if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
return FALSE;
*y_advance = -ft_face->glyph->metrics.vertAdvance;
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)
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;
/* TODO: load_flags, embolden, etc */
if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
return FALSE;
if (likely (!FT_Load_Glyph (ft_face, glyph, load_flags)))
{
*x_advance = ft_face->glyph->advance.x;
*y_advance = ft_face->glyph->advance.y;
}
*y_origin = ft_face->glyph->metrics.vertAdvance;
return TRUE;
}
static void
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 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 */
/* TODO: load_flags, embolden, etc, shape/transform */
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;
}
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_glyph (hb_font_t *font HB_UNUSED,
void *font_data,
hb_codepoint_t unicode,
hb_codepoint_t variation_selector,
hb_codepoint_t *glyph,
void *user_data HB_UNUSED)
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;
#ifdef HAVE_FT_FACE_GETCHARVARIANTINDEX
if (unlikely (variation_selector)) {
*glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
if (*glyph)
return TRUE;
}
#endif
if (unlikely (FT_Load_Glyph (ft_face, glyph, load_flags)))
return FALSE;
*glyph = FT_Get_Char_Index (ft_face, unicode);
return *glyph != 0;
}
if (unlikely (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
return FALSE;
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)
{
FT_Face ft_face = (FT_Face) font_data;
FT_Vector kerning;
if (unlikely (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
return FALSE;
if (FT_Get_Kerning (ft_face, left_glyph, right_glyph, FT_KERNING_DEFAULT, &kerning))
return;
*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 */
*x_kern = kerning.x;
*y_kern = kerning.y;
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);

@ -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;

@ -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;

@ -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;

@ -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;

@ -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;

@ -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;

@ -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);

@ -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);

Loading…
Cancel
Save