Finish FT glue. Rough and untested

This commit is contained in:
Behdad Esfahbod 2009-11-04 15:48:32 -05:00
parent f8be443aec
commit 3b59306b85
3 changed files with 62 additions and 54 deletions

View File

@ -41,7 +41,7 @@
static hb_codepoint_t static hb_codepoint_t
hb_font_get_glyph_nil (hb_font_t *font, hb_face_t *face, const void *user_data, hb_font_get_glyph_nil (hb_font_t *font, hb_face_t *face, const void *user_data,
hb_codepoint_t unicode, hb_codepoint_t variant_selector) hb_codepoint_t unicode, hb_codepoint_t variation_selector)
{ return unicode; } { return unicode; }
static hb_bool_t static hb_bool_t

View File

@ -103,7 +103,7 @@ typedef struct _hb_glyph_metrics_t
} hb_glyph_metrics_t; } hb_glyph_metrics_t;
typedef hb_codepoint_t (*hb_font_get_glyph_func_t) (hb_font_t *font, hb_face_t *face, const void *user_data, typedef hb_codepoint_t (*hb_font_get_glyph_func_t) (hb_font_t *font, hb_face_t *face, const void *user_data,
hb_codepoint_t unicode, hb_codepoint_t variant_selector); hb_codepoint_t unicode, hb_codepoint_t variation_selector);
typedef hb_bool_t (*hb_font_get_contour_point_func_t) (hb_font_t *font, hb_face_t *face, const void *user_data, typedef hb_bool_t (*hb_font_get_contour_point_func_t) (hb_font_t *font, hb_face_t *face, const void *user_data,
unsigned int point_index, unsigned int point_index,
hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y); hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y);

View File

@ -33,86 +33,93 @@
#include FT_TRUETYPE_TABLES_H #include FT_TRUETYPE_TABLES_H
#if 0 static hb_codepoint_t
extern hb_codepoint_t hb_GetGlyph(hb_font_t *font, hb_face_t *face, const void *user_data, hb_ft_get_glyph (hb_font_t *font, hb_face_t *face, const void *user_data,
hb_codepoint_t unicode, hb_codepoint_t variant_selector) hb_codepoint_t unicode, hb_codepoint_t variation_selector)
{ {
FT_Face fcFace = (FT_Face)user_data; FT_Face ft_face = (FT_Face) user_data;
return FT_Get_Char_Index(fcFace, unicode);
if (HB_UNLIKELY (variation_selector)) {
hb_codepoint_t glyph = FT_Face_GetCharVariantIndex (ft_face, unicode, variation_selector);
if (glyph)
return glyph;
}
return FT_Get_Char_Index (ft_face, unicode);
} }
extern hb_bool_t hb_GetContourPoint(hb_font_t *font, hb_face_t *face, const void *user_data, static hb_bool_t
hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y) hb_ft_get_contour_point (hb_font_t *font, hb_face_t *face, const void *user_data,
unsigned int point_index,
hb_codepoint_t glyph, hb_position_t *x, hb_position_t *y)
{ {
unsigned int point = 0; /* TODO this should be in API */ FT_Face ft_face = (FT_Face) user_data;
int load_flags = FT_LOAD_DEFAULT; int load_flags = FT_LOAD_DEFAULT;
FT_Face fcFace = (FT_Face)user_data; /* TODO: load_flags, embolden, etc */
if (FT_Load_Glyph(fcFace, glyph, load_flags))
return 0;
if (fcFace->glyph->format != ft_glyph_format_outline) if (HB_UNLIKELY (FT_Load_Glyph (ft_face, glyph, load_flags)))
return 0; return FALSE;
unsigned int nPoints = fcFace->glyph->outline.n_points; if (HB_UNLIKELY (ft_face->glyph->format != FT_GLYPH_FORMAT_OUTLINE))
if (!(nPoints)) return FALSE;
return 0;
if (point > nPoints) if (HB_UNLIKELY (point_index >= (unsigned int) ft_face->glyph->outline.n_points))
return 0; return FALSE;
*x = fcFace->glyph->outline.points[point].x; *x = ft_face->glyph->outline.points[point_index].x;
*y = fcFace->glyph->outline.points[point].y; *y = ft_face->glyph->outline.points[point_index].y;
return 1; return TRUE;
} }
extern void hb_GetGlyphMetrics(hb_font_t *font, hb_face_t *face, const void *user_data, static void
hb_codepoint_t glyph, hb_glyph_metrics_t *metrics) hb_ft_get_glyph_metrics (hb_font_t *font, hb_face_t *face, const void *user_data,
hb_codepoint_t glyph, hb_glyph_metrics_t *metrics)
{ {
int load_flags = FT_LOAD_DEFAULT; FT_Face ft_face = (FT_Face) user_data;
FT_Face fcFace = (FT_Face)user_data; int load_flags = FT_LOAD_DEFAULT;
metrics->x = metrics->y = 0; /* TODO: load_flags, embolden, etc */
metrics->x_offset = metrics->y_offset = 0;
if (FT_Load_Glyph(fcFace, glyph, load_flags)) metrics->x_pos = metrics->y_pos = 0;
{ metrics->x_advance = metrics->y_advance = 0;
metrics->width = metrics->height = 0; metrics->width = metrics->height = 0;
} if (HB_LIKELY (!FT_Load_Glyph (ft_face, glyph, load_flags)))
else {
{ /* TODO: A few negations should be in order here, not sure. */
metrics->width = fcFace->glyph->metrics.width; metrics->x_pos = ft_face->glyph->metrics.horiBearingX;
metrics->height = fcFace->glyph->metrics.height; metrics->y_pos = ft_face->glyph->metrics.horiBearingY;
metrics->x_offset = fcFace->glyph->advance.x; metrics->width = ft_face->glyph->metrics.width;
metrics->y_offset = fcFace->glyph->advance.y; metrics->height = ft_face->glyph->metrics.height;
} metrics->x_advance = ft_face->glyph->advance.x;
metrics->y_advance = ft_face->glyph->advance.y;
}
} }
extern hb_position_t hb_GetKerning(hb_font_t *font, hb_face_t *face, const void *user_data, static hb_position_t
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph) hb_ft_get_kerning (hb_font_t *font, hb_face_t *face, const void *user_data,
hb_codepoint_t first_glyph, hb_codepoint_t second_glyph)
{ {
FT_Face fcFace = (FT_Face)user_data; FT_Face ft_face = (FT_Face) user_data;
FT_Vector aKerning; FT_Vector kerning;
if (FT_Get_Kerning(fcFace, first_glyph, second_glyph, FT_KERNING_DEFAULT,
&aKerning)) /* TODO: Kern type? */
{ if (FT_Get_Kerning (ft_face, first_glyph, second_glyph, FT_KERNING_DEFAULT, &kerning))
return 0; return 0;
}
return aKerning.x; return kerning.x;
} }
#endif
static hb_font_funcs_t ft_ffuncs = { static hb_font_funcs_t ft_ffuncs = {
HB_REFERENCE_COUNT_INVALID, /* ref_count */ HB_REFERENCE_COUNT_INVALID, /* ref_count */
TRUE, /* immutable */ TRUE, /* immutable */
#if 0
hb_ft_get_glyph, hb_ft_get_glyph,
hb_ft_get_contour_point, hb_ft_get_contour_point,
hb_ft_get_glyph_metrics, hb_ft_get_glyph_metrics,
hb_ft_get_kerning hb_ft_get_kerning
#endif
}; };
hb_font_funcs_t * hb_font_funcs_t *
@ -134,6 +141,7 @@ _get_table (hb_tag_t tag, void *user_data)
if (error) if (error)
return hb_blob_create_empty (); return hb_blob_create_empty ();
/* TODO Use FT_Memory? */
buffer = malloc (length); buffer = malloc (length);
if (buffer == NULL) if (buffer == NULL)
return hb_blob_create_empty (); return hb_blob_create_empty ();