| OLD | NEW |
| (Empty) |
| 1 #include <stdint.h> | |
| 2 | |
| 3 #include <ft2build.h> | |
| 4 #include FT_FREETYPE_H | |
| 5 #include FT_TRUETYPE_TABLES_H | |
| 6 | |
| 7 #if 0 | |
| 8 #include <freetype/freetype.h> | |
| 9 #include <freetype/tttables.h> | |
| 10 #endif | |
| 11 | |
| 12 #include <harfbuzz-shaper.h> | |
| 13 #include "harfbuzz-unicode.h" | |
| 14 | |
| 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; | |
| 23 | |
| 24 size_t i = 0, j = 0; | |
| 25 while (i < len) { | |
| 26 const uint32_t cp = utf16_to_code_point(chars, len, &i); | |
| 27 glyphs[j++] = FT_Get_Char_Index(face, cp); | |
| 28 } | |
| 29 | |
| 30 *numGlyphs = j; | |
| 31 | |
| 32 return 1; | |
| 33 } | |
| 34 | |
| 35 static void | |
| 36 hb_freetype_advances_get(HB_Font font, const HB_Glyph *glyphs, hb_uint32 len, | |
| 37 HB_Fixed *advances, int flags) { | |
| 38 FT_Face face = (FT_Face) font->userData; | |
| 39 | |
| 40 hb_uint32 i; | |
| 41 for (i = 0; i < len; ++i) { | |
| 42 const FT_Error error = FT_Load_Glyph(face, glyphs[i], FT_LOAD_DEFAULT); | |
| 43 if (error) { | |
| 44 advances[i] = 0; | |
| 45 continue; | |
| 46 } | |
| 47 | |
| 48 advances[i] = face->glyph->advance.x; | |
| 49 } | |
| 50 } | |
| 51 | |
| 52 static HB_Bool | |
| 53 hb_freetype_can_render(HB_Font font, const HB_UChar16 *chars, hb_uint32 len) { | |
| 54 FT_Face face = (FT_Face)font->userData; | |
| 55 | |
| 56 size_t i = 0; | |
| 57 while (i < len) { | |
| 58 const uint32_t cp = utf16_to_code_point(chars, len, &i); | |
| 59 if (FT_Get_Char_Index(face, cp) == 0) | |
| 60 return 0; | |
| 61 } | |
| 62 | |
| 63 return 1; | |
| 64 } | |
| 65 | |
| 66 static HB_Error | |
| 67 hb_freetype_outline_point_get(HB_Font font, HB_Glyph glyph, int flags, | |
| 68 hb_uint32 point, HB_Fixed *xpos, HB_Fixed *ypos, | |
| 69 hb_uint32 *n_points) { | |
| 70 HB_Error error = HB_Err_Ok; | |
| 71 FT_Face face = (FT_Face) font->userData; | |
| 72 | |
| 73 int load_flags = (flags & HB_ShaperFlag_UseDesignMetrics) ? FT_LOAD_NO_HINTING
: FT_LOAD_DEFAULT; | |
| 74 | |
| 75 if ((error = (HB_Error) FT_Load_Glyph(face, glyph, load_flags))) | |
| 76 return error; | |
| 77 | |
| 78 if (face->glyph->format != ft_glyph_format_outline) | |
| 79 return (HB_Error)HB_Err_Invalid_SubTable; | |
| 80 | |
| 81 *n_points = face->glyph->outline.n_points; | |
| 82 if (!(*n_points)) | |
| 83 return HB_Err_Ok; | |
| 84 | |
| 85 if (point > *n_points) | |
| 86 return (HB_Error)HB_Err_Invalid_SubTable; | |
| 87 | |
| 88 *xpos = face->glyph->outline.points[point].x; | |
| 89 *ypos = face->glyph->outline.points[point].y; | |
| 90 | |
| 91 return HB_Err_Ok; | |
| 92 } | |
| 93 | |
| 94 static void | |
| 95 hb_freetype_glyph_metrics_get(HB_Font font, HB_Glyph glyph, | |
| 96 HB_GlyphMetrics *metrics) { | |
| 97 FT_Face face = (FT_Face) font->userData; | |
| 98 | |
| 99 const FT_Error error = FT_Load_Glyph(face, glyph, FT_LOAD_DEFAULT); | |
| 100 if (error) { | |
| 101 metrics->x = metrics->y = metrics->width = metrics->height = 0; | |
| 102 metrics->xOffset = metrics->yOffset = 0; | |
| 103 return; | |
| 104 } | |
| 105 | |
| 106 const FT_Glyph_Metrics *ftmetrics = &face->glyph->metrics; | |
| 107 metrics->width = ftmetrics->width; | |
| 108 metrics->height = ftmetrics->height; | |
| 109 metrics->x = ftmetrics->horiAdvance; | |
| 110 metrics->y = 0; // unclear what this is | |
| 111 metrics->xOffset = ftmetrics->horiBearingX; | |
| 112 metrics->yOffset = ftmetrics->horiBearingY; | |
| 113 } | |
| 114 | |
| 115 static HB_Fixed | |
| 116 hb_freetype_font_metric_get(HB_Font font, HB_FontMetric metric) { | |
| 117 FT_Face face = (FT_Face) font->userData; | |
| 118 | |
| 119 switch (metric) { | |
| 120 case HB_FontAscent: | |
| 121 // Note that we aren't scanning the VDMX table which we probably would in | |
| 122 // an ideal world. | |
| 123 return face->ascender; | |
| 124 default: | |
| 125 return 0; | |
| 126 } | |
| 127 } | |
| 128 | |
| 129 const HB_FontClass hb_freetype_class = { | |
| 130 hb_freetype_string_to_glyphs, | |
| 131 hb_freetype_advances_get, | |
| 132 hb_freetype_can_render, | |
| 133 hb_freetype_outline_point_get, | |
| 134 hb_freetype_glyph_metrics_get, | |
| 135 hb_freetype_font_metric_get, | |
| 136 }; | |
| 137 | |
| 138 HB_Error | |
| 139 hb_freetype_table_sfnt_get(void *voidface, const HB_Tag tag, HB_Byte *buffer, HB
_UInt *len) { | |
| 140 FT_Face face = (FT_Face) voidface; | |
| 141 FT_ULong ftlen = *len; | |
| 142 | |
| 143 if (!FT_IS_SFNT(face)) | |
| 144 return HB_Err_Invalid_Argument; | |
| 145 | |
| 146 const FT_Error error = FT_Load_Sfnt_Table(face, tag, 0, buffer, &ftlen); | |
| 147 *len = ftlen; | |
| 148 return (HB_Error) error; | |
| 149 } | |
| OLD | NEW |