pyglet 2.1.3__py3-none-any.whl → 2.1.4__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (61) hide show
  1. pyglet/__init__.py +21 -9
  2. pyglet/__init__.pyi +3 -1
  3. pyglet/app/cocoa.py +6 -3
  4. pyglet/display/win32.py +14 -15
  5. pyglet/display/xlib_vidmoderestore.py +1 -1
  6. pyglet/extlibs/earcut.py +2 -2
  7. pyglet/font/__init__.py +3 -3
  8. pyglet/font/base.py +118 -51
  9. pyglet/font/dwrite/__init__.py +1381 -0
  10. pyglet/font/dwrite/d2d1_lib.py +637 -0
  11. pyglet/font/dwrite/d2d1_types_lib.py +60 -0
  12. pyglet/font/dwrite/dwrite_lib.py +1577 -0
  13. pyglet/font/fontconfig.py +79 -16
  14. pyglet/font/freetype.py +252 -77
  15. pyglet/font/freetype_lib.py +234 -125
  16. pyglet/font/harfbuzz/__init__.py +275 -0
  17. pyglet/font/harfbuzz/harfbuzz_lib.py +212 -0
  18. pyglet/font/quartz.py +432 -112
  19. pyglet/font/user.py +18 -11
  20. pyglet/font/win32.py +9 -1
  21. pyglet/gl/wgl.py +94 -87
  22. pyglet/gl/wglext_arb.py +472 -218
  23. pyglet/gl/wglext_nv.py +410 -188
  24. pyglet/gui/widgets.py +6 -1
  25. pyglet/image/codecs/bmp.py +3 -5
  26. pyglet/image/codecs/gdiplus.py +28 -9
  27. pyglet/image/codecs/wic.py +198 -489
  28. pyglet/image/codecs/wincodec_lib.py +413 -0
  29. pyglet/input/base.py +3 -2
  30. pyglet/input/macos/darwin_hid.py +28 -2
  31. pyglet/input/win32/directinput.py +2 -1
  32. pyglet/input/win32/xinput.py +10 -9
  33. pyglet/lib.py +14 -2
  34. pyglet/libs/darwin/cocoapy/cocoalibs.py +74 -3
  35. pyglet/libs/darwin/coreaudio.py +0 -2
  36. pyglet/libs/win32/__init__.py +4 -2
  37. pyglet/libs/win32/com.py +65 -12
  38. pyglet/libs/win32/constants.py +1 -0
  39. pyglet/libs/win32/dinput.py +1 -9
  40. pyglet/libs/win32/types.py +72 -8
  41. pyglet/media/codecs/coreaudio.py +1 -0
  42. pyglet/media/codecs/wmf.py +93 -72
  43. pyglet/media/devices/win32.py +5 -4
  44. pyglet/media/drivers/directsound/lib_dsound.py +4 -4
  45. pyglet/media/drivers/xaudio2/interface.py +21 -17
  46. pyglet/media/drivers/xaudio2/lib_xaudio2.py +42 -25
  47. pyglet/shapes.py +1 -1
  48. pyglet/text/document.py +7 -53
  49. pyglet/text/formats/attributed.py +3 -1
  50. pyglet/text/formats/plaintext.py +1 -1
  51. pyglet/text/formats/structured.py +1 -1
  52. pyglet/text/layout/base.py +76 -68
  53. pyglet/text/layout/incremental.py +38 -8
  54. pyglet/text/layout/scrolling.py +1 -1
  55. pyglet/text/runlist.py +2 -114
  56. pyglet/window/win32/__init__.py +1 -3
  57. {pyglet-2.1.3.dist-info → pyglet-2.1.4.dist-info}/METADATA +1 -1
  58. {pyglet-2.1.3.dist-info → pyglet-2.1.4.dist-info}/RECORD +60 -54
  59. pyglet/font/directwrite.py +0 -2798
  60. {pyglet-2.1.3.dist-info → pyglet-2.1.4.dist-info}/LICENSE +0 -0
  61. {pyglet-2.1.3.dist-info → pyglet-2.1.4.dist-info}/WHEEL +0 -0
@@ -0,0 +1,275 @@
1
+ from __future__ import annotations
2
+
3
+ from collections import defaultdict
4
+ from typing import TYPE_CHECKING
5
+ from ctypes import c_void_p, c_uint16, c_uint32, string_at, create_string_buffer, py_object, cast, POINTER
6
+ import sys
7
+
8
+ from pyglet.font.base import GlyphPosition
9
+
10
+ if TYPE_CHECKING:
11
+ from pyglet.font.freetype import FreeTypeFont
12
+ from pyglet.font.dwrite import Win32DirectWriteFont
13
+ from pyglet.font.quartz import QuartzFont
14
+ from pyglet.font.base import Font, Glyph
15
+
16
+ from .harfbuzz_lib import hb_lib
17
+ _available = False
18
+
19
+ if hb_lib:
20
+ _available = True
21
+
22
+ from .harfbuzz_lib import HB_MEMORY_MODE_READONLY, HB_DIRECTION_LTR
23
+
24
+
25
+ def harfbuzz_available() -> bool:
26
+ """Return if the Harfbuzz library is available to use."""
27
+ return _available
28
+
29
+
30
+ _hb_cache: dict[tuple[str, str, bool, str | bool], _HarfbuzzResources] = {}
31
+
32
+
33
+ def _add_utf16_buffer(text: str, buffer: c_void_p) -> None:
34
+ txt_utf16 = text.encode("utf-16-le") # HarfBuzz expects little-endian UTF-16
35
+ length = len(txt_utf16) // 2
36
+ txt_array = (c_uint16 * length).from_buffer_copy(txt_utf16)
37
+ hb_lib.hb_buffer_add_utf16(buffer, txt_array, length, 0, length)
38
+
39
+ def _add_utf32_buffer(text: str, buffer: c_void_p) -> None:
40
+ txt_utf32 = text.encode("utf-32-le")
41
+ char_ct = (len(txt_utf32) // 4)
42
+ txt_array = (c_uint32 * char_ct).from_buffer_copy(txt_utf32)
43
+ hb_lib.hb_buffer_add_utf32(buffer, txt_array,char_ct, 0, char_ct)
44
+
45
+
46
+ # Set which unicode python is using for the strings.
47
+ if sys.maxunicode == 0x10FFFF: # UTF-32
48
+ set_buffer_string = _add_utf32_buffer
49
+ elif sys.maxunicode == 0xFFFF: # UTF-16
50
+ set_buffer_string = _add_utf16_buffer
51
+
52
+ def get_resource_from_ct_font(font: QuartzFont):
53
+ """Get a harfbuzz resource object from a CoreText (Mac) font."""
54
+ key = (font.name, font.weight, font.italic, font.stretch)
55
+ if key in _hb_cache:
56
+ return _hb_cache[key]
57
+
58
+ resource = _HarfbuzzResources()
59
+ hb_face = font._get_hb_face()
60
+ resource.load_from_tabled_face(hb_face)
61
+ _hb_cache[key] = resource
62
+ return resource
63
+
64
+
65
+ def get_resource_from_dw_font(font: Win32DirectWriteFont) -> _HarfbuzzResources:
66
+ """Get a harfbuzz resource object from a DirectWrite (Windows) font."""
67
+ key = (font.name, font.weight, font.italic, font.stretch)
68
+ if key in _hb_cache:
69
+ return _hb_cache[key]
70
+
71
+ data = font.get_font_data()
72
+ if data:
73
+ resource = _HarfbuzzResources()
74
+ resource.load_from_memory(data)
75
+ _hb_cache[key] = resource
76
+ return resource
77
+
78
+ raise Exception("Font data could not be read.")
79
+
80
+ def get_resource_from_ft_font(font: FreeTypeFont) -> _HarfbuzzResources:
81
+ """Get a harfbuzz resource object from a FreeType (Linux) font."""
82
+ key = (font.name, font.weight, font.italic, font.stretch)
83
+ if key in _hb_cache:
84
+ return _hb_cache[key]
85
+
86
+ stream = font.face.ft_face.contents.stream.contents
87
+ data = string_at(stream.base, stream.size)
88
+ resource = _HarfbuzzResources()
89
+ resource.load_from_memory(data)
90
+ _hb_cache[key] = resource
91
+ return resource
92
+
93
+
94
+ def get_resource_from_path(font_path: str):
95
+ with open(font_path, "rb") as f:
96
+ data = f.read()
97
+
98
+ resource = _HarfbuzzResources()
99
+ resource.load_from_memory(data)
100
+ return resource
101
+
102
+ def _get_fallback_glyph_shape(font: Font, text: str) -> tuple[list[Glyph], list[GlyphPosition]]:
103
+ glyphs = []
104
+ offsets = []
105
+ pystr_len = len(text)
106
+ for fallback in font.fallbacks:
107
+ glyph_info = fallback.hb_resource.shape_text(text, fallback.pixel_size)
108
+
109
+ indices = [glyph_data["codepoint"] for glyph_data in glyph_info]
110
+ fallback.render_glyph_indices(indices)
111
+
112
+ for glyph_data in glyph_info:
113
+ glyph = fallback.glyphs[glyph_data["codepoint"]]
114
+ glyphs.append(glyph)
115
+ offset = GlyphPosition(glyph_data["x_advance"]-glyph.advance, glyph_data["y_advance"],
116
+ glyph_data["x_offset"], glyph_data["y_offset"])
117
+ offsets.append(offset)
118
+
119
+ diff = pystr_len - len(glyphs)
120
+ if diff > 0:
121
+ for i in range(diff):
122
+ glyphs.append(font._zero_glyph)
123
+ offsets.append(GlyphPosition(0, 0, 0, 0))
124
+
125
+ return glyphs, offsets
126
+
127
+ def get_harfbuzz_shaped_glyphs(font: Font, text: str) -> tuple[list[Glyph], list[GlyphPosition]]:
128
+ glyph_info = font.hb_resource.shape_text(text, font.pixel_size)
129
+ clusters = [glyph_data["cluster"] for glyph_data in glyph_info]
130
+ cluster_map = defaultdict(list)
131
+
132
+ # Find any clusters that have empty indices.
133
+ empty_clusters = {}
134
+ indices = []
135
+ for glyph_data in glyph_info:
136
+ # If any clusters have no codepoint, determine the size to pass to fallback.
137
+ cluster_num = glyph_data["cluster"]
138
+ glyph_index = glyph_data["codepoint"]
139
+ if glyph_index == 0 and cluster_num not in empty_clusters:
140
+ empty_clusters[cluster_num] = clusters.count(cluster_num)
141
+
142
+ if cluster_num not in cluster_map:
143
+ cluster_map[cluster_num] = []
144
+
145
+ cluster_map[cluster_num].append(glyph_data)
146
+ indices.append(glyph_index)
147
+
148
+ font.render_glyph_indices(indices)
149
+
150
+ # If a cluster is missing and had 0 indices.
151
+ missing_glyphs = {}
152
+ for cluster_id, cluster_ct in empty_clusters.items():
153
+ missing_text = text[cluster_id:cluster_id + cluster_ct]
154
+ if missing_text not in font.glyphs:
155
+ if missing_text == '\n':
156
+ fb_glyph_info = ([font._zero_glyph], [GlyphPosition(0, 0, 0, 0)])
157
+ else:
158
+ # Get glyphs from fallback, since we need the fallback to actually render it.
159
+ fb_glyph_info = _get_fallback_glyph_shape(font, missing_text)
160
+ font.glyphs[missing_text] = fb_glyph_info # Cache by string to prevent future fallback paths.
161
+ missing_glyphs[cluster_id] = font.glyphs[missing_text]
162
+
163
+ glyphs = []
164
+ offsets = []
165
+ for i in range(len(text)):
166
+ cluster_glyph_info = cluster_map[i]
167
+
168
+ # Cluster has data, check if it's part of the missing glyphs.
169
+ if i in missing_glyphs:
170
+ _glyphs, _offsets = missing_glyphs[i]
171
+ glyphs.extend(_glyphs)
172
+ offsets.extend(_offsets)
173
+
174
+ # If this cluster is missing, add some zero glyphs until count matches.
175
+ elif len(cluster_glyph_info) == 0:
176
+ while len(glyphs) - 1 < i:
177
+ glyphs.append(font._zero_glyph)
178
+ offsets.append(GlyphPosition(0, 0, 0, 0))
179
+ else:
180
+ for glyph_info in cluster_glyph_info:
181
+ glyph = font.glyphs[glyph_info["codepoint"]]
182
+ glyphs.append(glyph)
183
+
184
+ offsets.append(
185
+ GlyphPosition(glyph_info["x_advance"] - glyph.advance, glyph_info["y_advance"],
186
+ glyph_info["x_offset"], glyph_info["y_offset"])
187
+ )
188
+
189
+ return glyphs, offsets
190
+
191
+
192
+ class _HarfbuzzResources:
193
+ def __init__(self) -> None:
194
+ self.blob = None
195
+ self.face = None
196
+ self.font = None
197
+
198
+ def load_from_tabled_face(self, hb_face: c_void_p) -> None:
199
+ self.blob = None
200
+ self.face = hb_face
201
+ self.font = hb_lib.hb_font_create(self.face)
202
+
203
+ def load_from_memory(self, data: bytes) -> None:
204
+ data_len = len(data)
205
+ data_buf = create_string_buffer(data, data_len)
206
+ self.blob = hb_lib.hb_blob_create(data_buf, data_len, HB_MEMORY_MODE_READONLY, None, None)
207
+ self.face = hb_lib.hb_face_create(self.blob, 0)
208
+ self.font = hb_lib.hb_font_create(self.face)
209
+
210
+ def shape_text(self, text: str, pixel_size: int, direction: int=HB_DIRECTION_LTR):
211
+ """Shapes the given string using the provided hb_font.
212
+ Returns a list of dictionaries for each glyph containing:
213
+ - codepoint: the glyph index
214
+ - cluster: the index into the original string
215
+ - x_advance, y_advance: the advances (including kerning adjustments)
216
+ - x_offset, y_offset: the offsets (shaped adjustments)
217
+ """
218
+ # Create a new buffer.
219
+ buf = hb_lib.hb_buffer_create()
220
+
221
+ # hb_lib.hb_buffer_set_cluster_level(buf, HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS)
222
+ set_buffer_string(text, buf)
223
+
224
+ scale = int(pixel_size * 64)
225
+ hb_lib.hb_font_set_scale(self.font, scale, scale)
226
+
227
+ hb_lib.hb_buffer_guess_segment_properties(buf)
228
+
229
+ # Set text direction (LTR, RTL, etc.).
230
+ hb_lib.hb_buffer_set_direction(buf, direction)
231
+
232
+ # Perform shaping.
233
+ hb_lib.hb_shape(self.font, buf, None, 0)
234
+
235
+ # Retrieve the number of glyphs.
236
+ length = hb_lib.hb_buffer_get_length(buf)
237
+
238
+ # Get pointers to the glyph info and position arrays.
239
+ infos = hb_lib.hb_buffer_get_glyph_infos(buf, None)
240
+ positions = hb_lib.hb_buffer_get_glyph_positions(buf, None)
241
+
242
+ # Collect glyph metrics.
243
+ glyphs = []
244
+ for i in range(length):
245
+ info = infos[i]
246
+ pos = positions[i]
247
+ glyphs.append({
248
+ "codepoint": info.codepoint,
249
+ "cluster": info.cluster,
250
+ "x_advance": pos.x_advance / 64.0,
251
+ "y_advance": pos.y_advance / 64.0,
252
+ "x_offset": pos.x_offset / 64.0,
253
+ "y_offset": pos.y_offset / 64.0,
254
+ })
255
+
256
+ # Clean up the buffer.
257
+ hb_lib.hb_buffer_destroy(buf)
258
+
259
+ return glyphs
260
+
261
+ def __del__(self):
262
+ self.destroy()
263
+
264
+ def destroy(self):
265
+ if self.font:
266
+ hb_lib.hb_font_destroy(self.font)
267
+ self.font = None
268
+
269
+ if self.face:
270
+ hb_lib.hb_face_destroy(self.face)
271
+ self.face = None
272
+
273
+ if self.blob:
274
+ hb_lib.hb_blob_destroy(self.blob)
275
+ self.blob = None
@@ -0,0 +1,212 @@
1
+ from __future__ import annotations
2
+
3
+ import contextlib
4
+ from ctypes import (
5
+ CFUNCTYPE,
6
+ POINTER,
7
+ Structure,
8
+ Union,
9
+ c_char_p,
10
+ c_int,
11
+ c_int8,
12
+ c_int16,
13
+ c_int32,
14
+ c_size_t,
15
+ c_uint,
16
+ c_uint8,
17
+ c_uint16,
18
+ c_uint32,
19
+ c_void_p,
20
+ )
21
+
22
+ import pyglet
23
+
24
+ # Harfbuzz DLL depends on libglib and libintl (for Windows)
25
+ hb_lib = None
26
+ with contextlib.suppress(ImportError):
27
+ hb_lib = pyglet.lib.load_library("harfbuzz", win32='libharfbuzz-0.dll', darwin='libharfbuzz.0.dylib')
28
+
29
+
30
+ HB_MEMORY_MODE_READONLY = 0 # for read-only font data
31
+
32
+ HB_DIRECTION_INVALID = 0
33
+ HB_DIRECTION_LTR = 4
34
+ HB_DIRECTION_RTL = 5
35
+ HB_DIRECTION_TTB = 6
36
+ HB_DIRECTION_BTT = 7
37
+
38
+ HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES = 0
39
+ HB_BUFFER_CLUSTER_LEVEL_MONOTONE_CHARACTERS = 1
40
+ HB_BUFFER_CLUSTER_LEVEL_CHARACTERS = 2
41
+ HB_BUFFER_CLUSTER_LEVEL_DEFAULT = HB_BUFFER_CLUSTER_LEVEL_MONOTONE_GRAPHEMES
42
+
43
+ HB_GLYPH_FLAG_UNSAFE_TO_BREAK = 0x00000001
44
+ HB_GLYPH_FLAG_UNSAFE_TO_CONCAT = 0x00000002
45
+ HB_GLYPH_FLAG_SAFE_TO_INSERT_TATWEEL = 0x00000004
46
+
47
+ HB_GLYPH_FLAG_DEFINED = 0x00000007 # OR of all defined flags
48
+
49
+ hb_buffer_cluster_level_t = c_uint
50
+
51
+
52
+ class hb_var_int_t(Union):
53
+ _fields_ = [
54
+ ("u32", c_uint32),
55
+ ("i32", c_int32),
56
+ ("u16", c_uint16 * 2),
57
+ ("i16", c_int16 * 2),
58
+ ("u8", c_uint8 * 4),
59
+ ("i8", c_int8 * 4),
60
+ ]
61
+
62
+
63
+ hb_codepoint_t = c_uint32
64
+ hb_mask_t = c_uint32
65
+
66
+
67
+ class hb_glyph_info_t(Structure):
68
+ _fields_ = [
69
+ ("codepoint", hb_codepoint_t), # glyph index
70
+ ("mask", hb_mask_t),
71
+ ("cluster", c_uint32), # index in the original text
72
+ ("var1", hb_var_int_t),
73
+ ("var2", hb_var_int_t)
74
+ ]
75
+
76
+ def __repr__(self) -> str:
77
+ return f"hb_glyph_info_t(codepoint={self.codepoint}, cluster={self.cluster}, flag={self.mask & HB_GLYPH_FLAG_DEFINED})"
78
+
79
+
80
+ hb_position_t = c_int32
81
+
82
+
83
+ # The glyph position structure contains advances and offsets.
84
+ class hb_glyph_position_t(Structure):
85
+ _fields_ = [
86
+ ("x_advance", hb_position_t), # includes kerning
87
+ ("y_advance", hb_position_t),
88
+ ("x_offset", hb_position_t), # adjustments to the glyph's drawing position
89
+ ("y_offset", hb_position_t),
90
+ ('var', hb_var_int_t), # Private, do not use, but must be included for proper reading.
91
+ ]
92
+
93
+
94
+ if hb_lib:
95
+ hb_lib.hb_blob_create.argtypes = [
96
+ c_char_p, # pointer to the font data const char *data
97
+ c_size_t, # length of the data
98
+ c_uint, # memory mode (e.g., HB_MEMORY_MODE_READONLY) hb_memory_mode_t
99
+ c_void_p, # user data (None here) void *user_data
100
+ c_void_p # destroy callback (None here) hb_destroy_func_t
101
+ ]
102
+ hb_lib.hb_blob_create.restype = c_void_p
103
+
104
+ hb_blob_t = c_void_p
105
+ hb_lib.hb_face_create.argtypes = [
106
+ c_void_p, # hb_blob_t *blob
107
+ c_uint # font index in the blob (usually 0) index
108
+ ]
109
+ hb_lib.hb_face_create.restype = c_void_p
110
+
111
+ hb_reference_table_func_t = CFUNCTYPE(c_void_p, c_void_p, c_uint32, c_void_p)
112
+ hb_destroy_func_t = CFUNCTYPE(None, c_void_p)
113
+
114
+ hb_lib.hb_face_create_for_tables.argtypes = [
115
+ hb_reference_table_func_t, # table func
116
+ c_void_p, # user data ptr
117
+ hb_destroy_func_t # free memory function
118
+ ]
119
+ hb_lib.hb_face_create_for_tables.restype = c_void_p
120
+
121
+ hb_lib.hb_font_create.argtypes = [c_void_p] # hb_face_t *face
122
+ hb_lib.hb_font_create.restype = c_void_p
123
+
124
+ hb_lib.hb_face_get_upem.argtypes = [c_void_p] # hb_face_t *face
125
+ hb_lib.hb_face_get_upem.restype = c_uint
126
+
127
+ hb_lib.hb_font_set_scale.argtypes = [
128
+ c_void_p, # b_font_t *font
129
+ c_int, # x_scale
130
+ c_int # y_scale
131
+ ]
132
+ hb_lib.hb_font_set_scale.restype = None
133
+
134
+ hb_lib.hb_buffer_create.argtypes = []
135
+ hb_lib.hb_buffer_create.restype = c_void_p
136
+
137
+ hb_lib.hb_buffer_add_utf8.argtypes = [
138
+ c_void_p, # b_buffer_t *buffer
139
+ c_char_p, # UTF-8 text const char *text
140
+ c_int, # text length (number of bytes)
141
+ c_uint, # item offset (usually 0)
142
+ c_int # item length (often the same as text_length)
143
+ ]
144
+ hb_lib.hb_buffer_add_utf8.restype = None
145
+
146
+ hb_lib.hb_buffer_set_cluster_level.argtypes = [c_void_p, hb_buffer_cluster_level_t]
147
+ hb_lib.hb_buffer_set_cluster_level.restype = None
148
+
149
+ hb_lib.hb_buffer_add_utf16.argtypes = [
150
+ c_void_p, # hb_buffer_t *buffer
151
+ POINTER(c_uint16), # UTF-16 text onst char *text
152
+ c_int, # text length (number of bytes)
153
+ c_uint, # item offset (usually 0)
154
+ c_int # item length (often the same as text_length)
155
+ ]
156
+ hb_lib.hb_buffer_add_utf16.restype = None
157
+
158
+ hb_lib.hb_buffer_add_utf32.argtypes = [
159
+ c_void_p, # hb_buffer_t *buffer
160
+ POINTER(c_uint32), # UTF-32 text const char *text
161
+ c_int, # text length (number of bytes)
162
+ c_uint, # item offset (usually 0)
163
+ c_int # item length (often the same as text_length)
164
+ ]
165
+ hb_lib.hb_buffer_add_utf32.restype = None
166
+
167
+ hb_lib.hb_buffer_set_direction.argtypes = [
168
+ c_void_p, # hb_buffer_t *buffer
169
+ c_int # direction (e.g., HB_DIRECTION_LTR) hb_direction_t
170
+ ]
171
+ hb_lib.hb_buffer_set_direction.restype = None
172
+
173
+ hb_lib.hb_shape.argtypes = [
174
+ c_void_p, # hb_font_t *font
175
+ c_void_p, # hb_buffer_t *buffer
176
+ c_void_p, # hb_feature_t *features (None if not used)
177
+ c_uint # number of features (0 if features is None)
178
+ ]
179
+ hb_lib.hb_shape.restype = None
180
+
181
+ hb_lib.hb_buffer_guess_segment_properties.argtypes = [c_void_p]
182
+ hb_lib.hb_buffer_guess_segment_properties.restype = None
183
+
184
+ hb_lib.hb_buffer_get_length.argtypes = [c_void_p] # hb_buffer_t *buffer
185
+ hb_lib.hb_buffer_get_length.restype = c_uint
186
+
187
+ hb_lib.hb_buffer_get_glyph_infos.argtypes = [
188
+ c_void_p, # hb_buffer_t *buffer,
189
+ POINTER(c_uint) # pointer for length (can be None)
190
+ ]
191
+ hb_lib.hb_buffer_get_glyph_infos.restype = POINTER(hb_glyph_info_t)
192
+
193
+ hb_lib.hb_buffer_get_glyph_positions.argtypes = [
194
+ c_void_p, # hb_buffer_t *buffer
195
+ POINTER(c_uint) # pointer for length (can be None)
196
+ ]
197
+ hb_lib.hb_buffer_get_glyph_positions.restype = POINTER(hb_glyph_position_t)
198
+
199
+ hb_lib.hb_blob_destroy.argtypes = [c_void_p] # b_blob_t *blob)
200
+ hb_lib.hb_blob_destroy.restype = None
201
+
202
+ hb_lib.hb_face_destroy.argtypes = [c_void_p] # hb_face_t *face
203
+ hb_lib.hb_face_destroy.restype = None
204
+
205
+ hb_lib.hb_font_destroy.argtypes = [c_void_p] # hb_font_t *font
206
+ hb_lib.hb_font_destroy.restype = None
207
+
208
+ hb_lib.hb_buffer_destroy.argtypes = [c_void_p] # hb_buffer_t *buffer
209
+ hb_lib.hb_buffer_destroy.restype = None
210
+
211
+ hb_lib.hb_buffer_normalize_glyphs.argtypes = [c_void_p]
212
+ hb_lib.hb_buffer_normalize_glyphs.restype = None