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