[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:
parent
80dce8b7c8
commit
744970af4d
@ -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;
|
||||
};
|
||||
|
||||
|
435
src/hb-font.cc
435
src/hb-font.cc
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
168
src/hb-font.h
168
src/hb-font.h
@ -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);
|
||||
|
||||
|
||||
/*
|
||||
|
241
src/hb-ft.cc
241
src/hb-ft.cc
@ -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);
|
||||
|
@ -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…
Reference in New Issue
Block a user