Mailbox support for texture layers.
[chromium-blink-merge.git] / third_party / harfbuzz / contrib / harfbuzz-freetype.c
blobf6a1e1ab141cb19333329ef1ebace2553715b9bd
1 #include <stdint.h>
3 #include <ft2build.h>
4 #include FT_FREETYPE_H
5 #include FT_TRUETYPE_TABLES_H
7 #if 0
8 #include <freetype/freetype.h>
9 #include <freetype/tttables.h>
10 #endif
12 #include <harfbuzz-shaper.h>
13 #include "harfbuzz-unicode.h"
15 static HB_Bool
16 hb_freetype_string_to_glyphs(HB_Font font,
17 const HB_UChar16 *chars, hb_uint32 len,
18 HB_Glyph *glyphs, hb_uint32 *numGlyphs,
19 HB_Bool is_rtl) {
20 FT_Face face = (FT_Face) font->userData;
21 if (len > *numGlyphs)
22 return 0;
24 ssize_t i = 0;
25 hb_uint32 j = 0;
26 while (i < len) {
27 const uint32_t cp = utf16_to_code_point(chars, len, &i);
28 glyphs[j++] = FT_Get_Char_Index(face, cp);
31 *numGlyphs = j;
33 return 1;
36 static void
37 hb_freetype_advances_get(HB_Font font, const HB_Glyph *glyphs, hb_uint32 len,
38 HB_Fixed *advances, int flags) {
39 FT_Face face = (FT_Face) font->userData;
41 hb_uint32 i;
42 for (i = 0; i < len; ++i) {
43 const FT_Error error = FT_Load_Glyph(face, glyphs[i], FT_LOAD_DEFAULT);
44 if (error) {
45 advances[i] = 0;
46 continue;
49 advances[i] = face->glyph->advance.x;
53 static HB_Bool
54 hb_freetype_can_render(HB_Font font, const HB_UChar16 *chars, hb_uint32 len) {
55 FT_Face face = (FT_Face)font->userData;
57 ssize_t i = 0;
58 while (i < len) {
59 const uint32_t cp = utf16_to_code_point(chars, len, &i);
60 if (FT_Get_Char_Index(face, cp) == 0)
61 return 0;
64 return 1;
67 static HB_Error
68 hb_freetype_outline_point_get(HB_Font font, HB_Glyph glyph, int flags,
69 hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos,
70 hb_uint32 *n_points) {
71 HB_Error error = HB_Err_Ok;
72 FT_Face face = (FT_Face) font->userData;
74 int load_flags = (flags & HB_ShaperFlag_UseDesignMetrics) ? FT_LOAD_NO_HINTING : FT_LOAD_DEFAULT;
76 if ((error = (HB_Error) FT_Load_Glyph(face, glyph, load_flags)))
77 return error;
79 if (face->glyph->format != ft_glyph_format_outline)
80 return (HB_Error)HB_Err_Invalid_SubTable;
82 *n_points = face->glyph->outline.n_points;
83 if (!(*n_points))
84 return HB_Err_Ok;
86 if (point > *n_points)
87 return (HB_Error)HB_Err_Invalid_SubTable;
89 *xpos = face->glyph->outline.points[point].x;
90 *ypos = face->glyph->outline.points[point].y;
92 return HB_Err_Ok;
95 static void
96 hb_freetype_glyph_metrics_get(HB_Font font, HB_Glyph glyph,
97 HB_GlyphMetrics *metrics) {
98 FT_Face face = (FT_Face) font->userData;
100 const FT_Error error = FT_Load_Glyph(face, glyph, FT_LOAD_DEFAULT);
101 if (error) {
102 metrics->x = metrics->y = metrics->width = metrics->height = 0;
103 metrics->xOffset = metrics->yOffset = 0;
104 return;
107 const FT_Glyph_Metrics *ftmetrics = &face->glyph->metrics;
108 metrics->width = ftmetrics->width;
109 metrics->height = ftmetrics->height;
110 metrics->x = ftmetrics->horiAdvance;
111 metrics->y = 0; // unclear what this is
112 metrics->xOffset = ftmetrics->horiBearingX;
113 metrics->yOffset = ftmetrics->horiBearingY;
116 static HB_Fixed
117 hb_freetype_font_metric_get(HB_Font font, HB_FontMetric metric) {
118 FT_Face face = (FT_Face) font->userData;
120 switch (metric) {
121 case HB_FontAscent:
122 // Note that we aren't scanning the VDMX table which we probably would in
123 // an ideal world.
124 return face->ascender;
125 default:
126 return 0;
130 const HB_FontClass hb_freetype_class = {
131 hb_freetype_string_to_glyphs,
132 hb_freetype_advances_get,
133 hb_freetype_can_render,
134 hb_freetype_outline_point_get,
135 hb_freetype_glyph_metrics_get,
136 hb_freetype_font_metric_get,
139 HB_Error
140 hb_freetype_table_sfnt_get(void *voidface, const HB_Tag tag, HB_Byte *buffer, HB_UInt *len) {
141 FT_Face face = (FT_Face) voidface;
142 FT_ULong ftlen = *len;
144 if (!FT_IS_SFNT(face))
145 return HB_Err_Invalid_Argument;
147 const FT_Error error = FT_Load_Sfnt_Table(face, tag, 0, buffer, &ftlen);
148 *len = ftlen;
149 return (HB_Error) error;