1cdef extern from "stdlib.h": 2 ctypedef int size_t 3 void *malloc(size_t size) 4 void free(void* ptr) 5 6cdef extern from "ft2build.h" : 7 pass 8 9cdef extern from "freetype/freetype.h" : 10 ctypedef void *FT_Library 11 ctypedef void *FT_Face 12 ctypedef int FT_Error 13 14 FT_Error FT_Init_FreeType (FT_Library *alib) 15 FT_Error FT_Done_FreeType (FT_Library alib) 16 FT_Error FT_Done_Face (FT_Face alib) 17 FT_Error FT_New_Face( FT_Library library, char *path, unsigned long index, FT_Face *aface) 18 FT_Error FT_Set_Char_Size (FT_Face aFace, unsigned int size_x, unsigned int size_y, unsigned int res_x, unsigned int res_y) 19 20cdef extern from "hb-common.h" : 21 cdef enum hb_direction_t : 22 HB_DIRECTION_LTR 23 HB_DIRECTION_RTL 24 HB_DIRECTION_TTB 25 HB_DIRECTION_BTT 26 ctypedef unsigned long hb_codepoint_t 27 ctypedef long hb_position_t 28 ctypedef unsigned long hb_mask_t 29 ctypedef unsigned long hb_tag_t 30 hb_tag_t hb_tag_from_string (char *s) 31 ctypedef void (*hb_destroy_func_t) (void *user_data) 32 ctypedef void *hb_language_t 33 hb_language_t hb_language_from_string(char *str) 34 char * hb_language_to_string(hb_language_t language) 35 36cdef extern from "hb-unicode.h" : 37# there must be a better way of syncing this list with the true source 38 ctypedef enum hb_script_t : 39 HB_SCRIPT_COMMON = 0 40 41cdef extern from "hb-ot-tag.h" : 42 hb_script_t hb_ot_tag_to_script (hb_tag_t tag) 43 44cdef extern from "hb-buffer.h" : 45 ctypedef struct hb_buffer_t : 46 pass 47 48 ctypedef struct hb_glyph_info_t : 49 hb_codepoint_t codepoint 50 hb_mask_t mask 51 unsigned long cluster 52 53 ctypedef union hb_var_int_t: 54 unsigned long u32 55 56 ctypedef struct hb_glyph_position_t : 57 hb_position_t x_advance 58 hb_position_t y_advance 59 hb_position_t x_offset 60 hb_position_t y_offset 61 hb_var_int_t var 62 63 hb_buffer_t *hb_buffer_create(unsigned int size) 64 hb_buffer_t *hb_buffer_reference(hb_buffer_t *buffer) 65 unsigned int hb_buffer_get_reference_count(hb_buffer_t *buffer) 66 void hb_buffer_destroy(hb_buffer_t *buffer) 67 void hb_buffer_set_direction(hb_buffer_t *buffer, hb_direction_t direction) 68 hb_direction_t hb_buffer_get_direction(hb_buffer_t *buffer) 69 void hb_buffer_set_script(hb_buffer_t *buffer, hb_script_t script) 70 hb_script_t hb_buffer_get_script(hb_buffer_t *buffer) 71 void hb_buffer_set_language(hb_buffer_t *buffer, hb_language_t language) 72 hb_language_t hb_buffer_get_language(hb_buffer_t *buffer) 73 void hb_buffer_clear(hb_buffer_t *) 74 void hb_buffer_clear_positions(hb_buffer_t *buffer) 75 void hb_buffer_ensure(hb_buffer_t *buffer, unsigned int size) 76 void hb_buffer_reverse(hb_buffer_t *buffer) 77 void hb_buffer_reverse_clusters(hb_buffer_t *buffer) 78 void hb_buffer_add_glyph(hb_buffer_t *buffer, hb_codepoint_t codepoint, hb_mask_t mask, unsigned int cluster) 79 void hb_buffer_add_utf8(hb_buffer_t *buffer, char *text, unsigned int text_length, unsigned int item_offset, unsigned int item_length) 80 unsigned int hb_buffer_get_length(hb_buffer_t *buffer) 81 hb_glyph_info_t *hb_buffer_get_glyph_infos(hb_buffer_t *buffer, unsigned int *len) 82 hb_glyph_position_t *hb_buffer_get_glyph_positions(hb_buffer_t *buffer, unsigned int *len) 83 84cdef extern from "hb-blob.h" : 85 cdef struct hb_blob_t : 86 pass 87# do I need blob functions here? 88 89cdef extern from "hb-font.h" : 90 ctypedef struct hb_face_t : 91 pass 92 ctypedef struct hb_font_t : 93 pass 94 95 ctypedef hb_blob_t * (*hb_get_table_func_t) (hb_tag_t tag, void *user_data) 96 hb_face_t * hb_face_create_for_data(hb_blob_t *blob, unsigned int index) 97 hb_face_t * hb_face_create_for_tables(hb_get_table_func_t get_table, hb_destroy_func_t destroy, void *user_data) 98 hb_face_t * hb_face_reference(hb_face_t *face) 99 unsigned int hb_face_get_reference_count(hb_face_t *face) 100 void hb_face_destroy(hb_face_t *face) 101 void hb_font_destroy(hb_font_t *font) 102 hb_blob_t * hb_face_get_table(hb_face_t *face, hb_tag_t tag) 103 104 105cdef extern from "hb-shape.h" : 106 ctypedef struct hb_feature_t : 107 int tag 108 unsigned int value 109 unsigned int start 110 unsigned int end 111 112 void hb_shape (hb_font_t *font, hb_buffer_t *buffer, hb_feature_t *features, unsigned int num_features) 113 114cdef extern from "hb-ft.h" : 115 hb_face_t *hb_ft_face_create (FT_Face ft_face, hb_destroy_func_t destroy) 116 hb_font_t *hb_ft_font_create (FT_Face ft_face, hb_destroy_func_t destroy) 117 118class glyphinfo : 119 120 def __init__(self, gid, cluster, advance, offset, internal = 0) : 121 self.gid = gid 122 self.cluster = cluster 123 self.advance = advance 124 self.offset = offset 125 self.internal = internal 126 127 def __repr__(self) : 128 res = "{0:d}>{1:d}@({2:.2f},{3:.2f})+({4:.2f},{5:.2f})".format(self.gid, self.cluster, self.offset[0], self.offset[1], self.advance[0], self.advance[1]) 129 if self.internal : res += "/i=" + str(self.internal) 130 return res 131 132cdef class buffer : 133 cdef hb_buffer_t *buffer 134 135 def __init__(self, char *text, unsigned int length) : 136 """Note text must be a utf-8 string and length is number of chars""" 137 self.buffer = hb_buffer_create(length) 138 hb_buffer_add_utf8(self.buffer, text, length, 0, len(text)) 139 140 def set_scriptlang(self, char *script, char *lang) : 141 cdef hb_language_t language 142 cdef hb_script_t scriptnum 143 144 language = hb_language_from_string(lang) 145 scriptnum = hb_ot_tag_to_script(hb_tag_from_string(script)) 146 hb_buffer_set_script(self.buffer, scriptnum) 147 hb_buffer_set_language(self.buffer, language) 148 149 def get_info(self, scale = 1) : 150 cdef hb_glyph_info_t *infos 151 cdef hb_glyph_position_t *positions 152 cdef unsigned int num 153 cdef unsigned int i 154 res = [] 155 156 num = hb_buffer_get_length(self.buffer) 157 infos = hb_buffer_get_glyph_infos(self.buffer, &num) 158 positions = hb_buffer_get_glyph_positions(self.buffer, &num) 159 for 0 <= i < num : 160 temp = glyphinfo(infos[i].codepoint, infos[i].cluster, (positions[i].x_advance / scale, positions[i].y_advance / scale), (positions[i].x_offset / scale, positions[i].y_offset / scale), positions[i].var.u32) 161 res.append(temp) 162 return res 163 164 def get_settings(self) : 165 cdef hb_script_t script 166 cdef hb_language_t lang 167 168 script = hb_buffer_get_script(self.buffer) 169 lang = hb_buffer_get_language(self.buffer) 170 return {'script' : script, 'language' : hb_language_to_string(lang)} 171 172 def __del__(self) : 173 hb_buffer_destroy(self.buffer) 174 175cdef class ft : 176 cdef FT_Library engine 177 cdef FT_Face face 178 cdef hb_face_t *hbface 179 cdef hb_font_t *hbfont 180 181 def __init__(self, char *fname, size) : 182 cdef FT_Library engine 183 FT_Init_FreeType(&engine) 184 self.engine = engine 185 cdef FT_Face face 186 FT_New_Face(engine, fname, 0, &face) 187 FT_Set_Char_Size(face, size << 6, size << 6, 72, 72) 188 self.face = face 189 self.hbface = hb_ft_face_create(face, <void (*)(void *)>hb_face_destroy) 190 self.hbfont = hb_ft_font_create(face, <void (*)(void *)>hb_font_destroy) 191 192 def __del__(self) : 193 cdef FT_Library engine 194 engine = self.engine 195 cdef FT_Face face 196 face = self.face 197 FT_Done_Face(face) 198 FT_Done_FreeType(engine) 199 200 def shape(self, buffer aBuffer, features = {}) : 201 cdef hb_feature_t *feats 202 cdef hb_feature_t *aFeat 203 feats = <hb_feature_t *>malloc(sizeof(hb_feature_t) * len(features)) 204 aFeat = feats 205 for k,v in features.items() : 206 aFeat.tag = hb_tag_from_string (k) 207 aFeat.value = int(v) 208 aFeat.start = 0 209 aFeat.end = -1 210 aFeat += 1 211 hb_shape(self.hbfont, aBuffer.buffer, feats, len(features)) 212 213 214