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,1577 @@
1
+ from __future__ import annotations
2
+
3
+ import copy
4
+ import ctypes
5
+ import os
6
+ import platform
7
+ from _ctypes import _Pointer
8
+ from ctypes import (
9
+ HRESULT,
10
+ POINTER,
11
+ Structure,
12
+ byref,
13
+ c_uint32,
14
+ c_void_p,
15
+ c_wchar_p,
16
+ cast,
17
+ create_unicode_buffer,
18
+ pointer,
19
+ sizeof,
20
+ windll,
21
+ )
22
+ from ctypes.wintypes import BOOL, FLOAT, HDC, UINT, WCHAR
23
+ from typing import NoReturn
24
+
25
+ from pyglet.font.dwrite.d2d1_types_lib import (
26
+ D2D1_COLOR_F,
27
+ D2D1_POINT_2L,
28
+ D2D1_SIZE_U,
29
+ D2D_POINT_2F,
30
+ )
31
+ from pyglet.libs.win32 import INT16, INT32, LOGFONTW, UINT8, UINT16, UINT32, UINT64, c_void, com
32
+
33
+ try:
34
+ dwrite = "dwrite"
35
+
36
+ # System32 and SysWOW64 folders are opposite perception in Windows x64.
37
+ # System32 = x64 dll's | SysWOW64 = x86 dlls
38
+ # By default ctypes only seems to look in system32 regardless of Python architecture, which has x64 dlls.
39
+ if platform.architecture()[0] == "32bit" and platform.machine().endswith("64"): # Machine is x64, Python is x86.
40
+ dwrite = os.path.join(os.environ["WINDIR"], "SysWOW64", "dwrite.dll")
41
+
42
+ dwrite_lib = windll.LoadLibrary(dwrite)
43
+ except OSError:
44
+ # Doesn't exist? Should stop import of library.
45
+ msg = "DirectWrite Not Found"
46
+ raise ImportError(msg) # noqa: B904
47
+
48
+
49
+ def DWRITE_MAKE_OPENTYPE_TAG(a: str, b: str, c: str, d: str) -> int:
50
+ return ord(d) << 24 | ord(c) << 16 | ord(b) << 8 | ord(a)
51
+
52
+ DWRITE_NO_PALETTE_INDEX = 0xFFFF
53
+
54
+ DWRITE_FACTORY_TYPE = UINT
55
+ DWRITE_FACTORY_TYPE_SHARED = 0
56
+ DWRITE_FACTORY_TYPE_ISOLATED = 1
57
+
58
+ DWRITE_FONT_WEIGHT = UINT
59
+ DWRITE_FONT_WEIGHT_THIN = 100
60
+ DWRITE_FONT_WEIGHT_EXTRA_LIGHT = 200
61
+ DWRITE_FONT_WEIGHT_ULTRA_LIGHT = 200
62
+ DWRITE_FONT_WEIGHT_LIGHT = 300
63
+ DWRITE_FONT_WEIGHT_SEMI_LIGHT = 350
64
+ DWRITE_FONT_WEIGHT_NORMAL = 400
65
+ DWRITE_FONT_WEIGHT_REGULAR = 400
66
+ DWRITE_FONT_WEIGHT_MEDIUM = 500
67
+ DWRITE_FONT_WEIGHT_DEMI_BOLD = 600
68
+ DWRITE_FONT_WEIGHT_SEMI_BOLD = 600
69
+ DWRITE_FONT_WEIGHT_BOLD = 700
70
+ DWRITE_FONT_WEIGHT_EXTRA_BOLD = 800
71
+ DWRITE_FONT_WEIGHT_ULTRA_BOLD = 800
72
+ DWRITE_FONT_WEIGHT_BLACK = 900
73
+ DWRITE_FONT_WEIGHT_HEAVY = 900
74
+ DWRITE_FONT_WEIGHT_EXTRA_BLACK = 950
75
+
76
+
77
+ DWRITE_FONT_STRETCH = UINT
78
+ DWRITE_FONT_STRETCH_UNDEFINED = 0
79
+ DWRITE_FONT_STRETCH_ULTRA_CONDENSED = 1
80
+ DWRITE_FONT_STRETCH_EXTRA_CONDENSED = 2
81
+ DWRITE_FONT_STRETCH_CONDENSED = 3
82
+ DWRITE_FONT_STRETCH_SEMI_CONDENSED = 4
83
+ DWRITE_FONT_STRETCH_NORMAL = 5
84
+ DWRITE_FONT_STRETCH_MEDIUM = 5
85
+ DWRITE_FONT_STRETCH_SEMI_EXPANDED = 6
86
+ DWRITE_FONT_STRETCH_EXPANDED = 7
87
+ DWRITE_FONT_STRETCH_EXTRA_EXPANDED = 8
88
+
89
+ DWRITE_GLYPH_IMAGE_FORMATS = UINT
90
+ DWRITE_GLYPH_IMAGE_FORMATS_NONE = 0x00000000
91
+ DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE = 0x00000001
92
+ DWRITE_GLYPH_IMAGE_FORMATS_CFF = 0x00000002
93
+ DWRITE_GLYPH_IMAGE_FORMATS_COLR = 0x00000004
94
+ DWRITE_GLYPH_IMAGE_FORMATS_SVG = 0x00000008
95
+ DWRITE_GLYPH_IMAGE_FORMATS_PNG = 0x00000010
96
+ DWRITE_GLYPH_IMAGE_FORMATS_JPEG = 0x00000020
97
+ DWRITE_GLYPH_IMAGE_FORMATS_TIFF = 0x00000040
98
+ DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8 = 0x00000080
99
+ DWRITE_GLYPH_IMAGE_FORMATS_COLR_PAINT_TREE = 0x00000100
100
+
101
+ DWRITE_GLYPH_IMAGE_FORMATS_BITMAP = (DWRITE_GLYPH_IMAGE_FORMATS_PNG |
102
+ DWRITE_GLYPH_IMAGE_FORMATS_JPEG |
103
+ DWRITE_GLYPH_IMAGE_FORMATS_TIFF |
104
+ DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8)
105
+
106
+ DWRITE_MEASURING_MODE = UINT
107
+ DWRITE_MEASURING_MODE_NATURAL = 0
108
+ DWRITE_MEASURING_MODE_GDI_CLASSIC = 1
109
+ DWRITE_MEASURING_MODE_GDI_NATURAL = 2
110
+
111
+ DWRITE_GLYPH_IMAGE_FORMATS_ALL = DWRITE_GLYPH_IMAGE_FORMATS_TRUETYPE | \
112
+ DWRITE_GLYPH_IMAGE_FORMATS_CFF | \
113
+ DWRITE_GLYPH_IMAGE_FORMATS_COLR | \
114
+ DWRITE_GLYPH_IMAGE_FORMATS_SVG | \
115
+ DWRITE_GLYPH_IMAGE_FORMATS_PNG | \
116
+ DWRITE_GLYPH_IMAGE_FORMATS_JPEG | \
117
+ DWRITE_GLYPH_IMAGE_FORMATS_TIFF | \
118
+ DWRITE_GLYPH_IMAGE_FORMATS_PREMULTIPLIED_B8G8R8A8
119
+
120
+ DWRITE_FONT_STYLE = UINT
121
+ DWRITE_FONT_STYLE_NORMAL = 0
122
+ DWRITE_FONT_STYLE_OBLIQUE = 1
123
+ DWRITE_FONT_STYLE_ITALIC = 2
124
+
125
+
126
+ DWRITE_INFORMATIONAL_STRING_ID = UINT32
127
+ DWRITE_INFORMATIONAL_STRING_NONE = 0
128
+ DWRITE_INFORMATIONAL_STRING_COPYRIGHT_NOTICE = 1
129
+ DWRITE_INFORMATIONAL_STRING_VERSION_STRINGS = 2
130
+ DWRITE_INFORMATIONAL_STRING_TRADEMARK = 3
131
+ DWRITE_INFORMATIONAL_STRING_MANUFACTURER = 4
132
+ DWRITE_INFORMATIONAL_STRING_DESIGNER = 5
133
+ DWRITE_INFORMATIONAL_STRING_DESIGNER_URL = 6
134
+ DWRITE_INFORMATIONAL_STRING_DESCRIPTION = 7
135
+ DWRITE_INFORMATIONAL_STRING_FONT_VENDOR_URL = 8
136
+ DWRITE_INFORMATIONAL_STRING_LICENSE_DESCRIPTION = 9
137
+ DWRITE_INFORMATIONAL_STRING_LICENSE_INFO_URL = 10
138
+ DWRITE_INFORMATIONAL_STRING_WIN32_FAMILY_NAMES = 11
139
+ DWRITE_INFORMATIONAL_STRING_WIN32_SUBFAMILY_NAMES = 12
140
+ DWRITE_INFORMATIONAL_STRING_TYPOGRAPHIC_FAMILY_NAMES = 13
141
+ DWRITE_INFORMATIONAL_STRING_TYPOGRAPHIC_SUBFAMILY_NAMES = 14
142
+ DWRITE_INFORMATIONAL_STRING_SAMPLE_TEXT = 15
143
+ DWRITE_INFORMATIONAL_STRING_FULL_NAME = 16
144
+ DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_NAME = 17
145
+ DWRITE_INFORMATIONAL_STRING_POSTSCRIPT_CID_NAME = 18
146
+ DWRITE_INFORMATIONAL_STRING_WEIGHT_STRETCH_STYLE_FAMILY_NAME = 19
147
+ DWRITE_INFORMATIONAL_STRING_DESIGN_SCRIPT_LANGUAGE_TAG = 20
148
+ DWRITE_INFORMATIONAL_STRING_SUPPORTED_SCRIPT_LANGUAGE_TAG = 21
149
+ DWRITE_INFORMATIONAL_STRING_PREFERRED_FAMILY_NAMES = 22
150
+ DWRITE_INFORMATIONAL_STRING_PREFERRED_SUBFAMILY_NAMES = 23
151
+ DWRITE_INFORMATIONAL_STRING_WWS_FAMILY_NAME = 24
152
+
153
+
154
+ DWRITE_TEXT_ALIGNMENT = UINT
155
+ DWRITE_TEXT_ALIGNMENT_LEADING = 1
156
+ DWRITE_TEXT_ALIGNMENT_TRAILING = 2
157
+ DWRITE_TEXT_ALIGNMENT_CENTER = 3
158
+ DWRITE_TEXT_ALIGNMENT_JUSTIFIED = 4
159
+
160
+ DWRITE_FONT_FACE_TYPE = UINT
161
+ DWRITE_FONT_FACE_TYPE_CFF = 0
162
+ DWRITE_FONT_FACE_TYPE_TRUETYPE = 1
163
+ DWRITE_FONT_FACE_TYPE_OPENTYPE_COLLECTION = 2
164
+ DWRITE_FONT_FACE_TYPE_TYPE1 = 3
165
+ DWRITE_FONT_FACE_TYPE_VECTOR = 4
166
+ DWRITE_FONT_FACE_TYPE_BITMAP = 5
167
+ DWRITE_FONT_FACE_TYPE_UNKNOWN = 6
168
+ DWRITE_FONT_FACE_TYPE_RAW_CFF = 7
169
+ DWRITE_FONT_FACE_TYPE_TRUETYPE_COLLECTION = 8
170
+
171
+ def repr_func(self):
172
+ field_values = []
173
+ for field_value in self._fields_:
174
+ try:
175
+ name, typ, _ = field_value # bitfields
176
+ except ValueError:
177
+ name, typ = field_value
178
+
179
+ value = getattr(self, name)
180
+
181
+ # Check if the field is a POINTER to any ctypes structure
182
+ if isinstance(value, _Pointer):
183
+ value = repr(value.contents) if value else "NULL"
184
+
185
+ field_values.append(f"{name}={value}")
186
+
187
+ return f"{self.__class__.__name__}({', '.join(field_values)})"
188
+
189
+ DWRITE_COLOR_F = D2D1_COLOR_F
190
+
191
+ class DWRITE_TEXT_METRICS(Structure):
192
+ _fields_ = (
193
+ ("left", FLOAT),
194
+ ("top", FLOAT),
195
+ ("width", FLOAT),
196
+ ("widthIncludingTrailingWhitespace", FLOAT),
197
+ ("height", FLOAT),
198
+ ("layoutWidth", FLOAT),
199
+ ("layoutHeight", FLOAT),
200
+ ("maxBidiReorderingDepth", UINT32),
201
+ ("lineCount", UINT32),
202
+ )
203
+
204
+
205
+ class DWRITE_FONT_METRICS(Structure):
206
+ _fields_ = (
207
+ ("designUnitsPerEm", UINT16),
208
+ ("ascent", UINT16),
209
+ ("descent", UINT16),
210
+ ("lineGap", INT16),
211
+ ("capHeight", UINT16),
212
+ ("xHeight", UINT16),
213
+ ("underlinePosition", INT16),
214
+ ("underlineThickness", UINT16),
215
+ ("strikethroughPosition", INT16),
216
+ ("strikethroughThickness", UINT16),
217
+ )
218
+
219
+ class DWRITE_FONT_METRICS1(Structure):
220
+ _fields_ = (
221
+ ("designUnitsPerEm", UINT16),
222
+ ("ascent", UINT16),
223
+ ("descent", UINT16),
224
+ ("lineGap", INT16),
225
+ ("capHeight", UINT16),
226
+ ("xHeight", UINT16),
227
+ ("underlinePosition", INT16),
228
+ ("underlineThickness", UINT16),
229
+ ("strikethroughPosition", INT16),
230
+ ("strikethroughThickness", UINT16),
231
+ ("glyphBoxLeft", INT16), # New starting here.
232
+ ("glyphBoxTop", INT16),
233
+ ("glyphBoxRight", INT16),
234
+ ("glyphBoxBottom", INT16),
235
+ ("subscriptPositionX", INT16),
236
+ ("subscriptPositionY", INT16),
237
+ ("subscriptSizeX", INT16),
238
+ ("subscriptSizeY", INT16),
239
+ ("superscriptPositionX", INT16),
240
+ ("superscriptPositionY", INT16),
241
+ ("superscriptSizeX", INT16),
242
+ ("superscriptSizeY", INT16),
243
+ ("hasTypographicMetrics", BOOL),
244
+ )
245
+
246
+ class DWRITE_CARET_METRICS(Structure):
247
+ _fields_ = (
248
+ ("slopeRise", INT16),
249
+ ("slopeRun", INT16),
250
+ ("offset", INT16),
251
+ )
252
+
253
+ class DWRITE_GLYPH_METRICS(Structure):
254
+ _fields_ = (
255
+ ("leftSideBearing", INT32),
256
+ ("advanceWidth", UINT32),
257
+ ("rightSideBearing", INT32),
258
+ ("topSideBearing", INT32),
259
+ ("advanceHeight", UINT32),
260
+ ("bottomSideBearing", INT32),
261
+ ("verticalOriginY", INT32),
262
+ )
263
+
264
+ def __repr__(self):
265
+ return (f"DWRITE_GLYPH_METRICS(leftSideBearing={self.leftSideBearing}, advanceWidth={self.advanceWidth}, "
266
+ f"rightSideBearing={self.rightSideBearing}, topSideBearing={self.topSideBearing}, advanceHeight={self.advanceHeight}, "
267
+ f"bottomSideBearing={self.bottomSideBearing}, verticalOriginY={self.verticalOriginY})")
268
+
269
+
270
+ class DWRITE_GLYPH_OFFSET(Structure):
271
+ _fields_ = (
272
+ ("advanceOffset", FLOAT),
273
+ ("ascenderOffset", FLOAT),
274
+ )
275
+
276
+ def __repr__(self) -> str:
277
+ return f"DWRITE_GLYPH_OFFSET({self.advanceOffset}, {self.ascenderOffset})"
278
+
279
+
280
+ class DWRITE_CLUSTER_METRICS(Structure):
281
+ _fields_ = (
282
+ ("width", FLOAT),
283
+ ("length", UINT16),
284
+ ("canWrapLineAfter", UINT16, 1),
285
+ ("isWhitespace", UINT16, 1),
286
+ ("isNewline", UINT16, 1),
287
+ ("isSoftHyphen", UINT16, 1),
288
+ ("isRightToLeft", UINT16, 1),
289
+ ("padding", UINT16, 11),
290
+ )
291
+
292
+ DWRITE_CLUSTER_METRICS.__repr__ = repr_func
293
+
294
+ class IDWriteFontFileStream(com.IUnknown):
295
+ _methods_ = [
296
+ ("ReadFileFragment",
297
+ com.STDMETHOD(POINTER(c_void_p), UINT64, UINT64, POINTER(c_void_p))),
298
+ ("ReleaseFileFragment",
299
+ com.STDMETHOD(c_void_p)),
300
+ ("GetFileSize",
301
+ com.STDMETHOD(POINTER(UINT64))),
302
+ ("GetLastWriteTime",
303
+ com.STDMETHOD(POINTER(UINT64))),
304
+ ]
305
+
306
+
307
+ class IDWriteFontFileLoader_LI(com.IUnknown): # Local implementation use only.
308
+ _methods_ = [
309
+ ("CreateStreamFromKey",
310
+ com.STDMETHOD(c_void_p, UINT32, POINTER(POINTER(IDWriteFontFileStream)))),
311
+ ]
312
+
313
+
314
+ class IDWriteFontFileLoader(com.pIUnknown):
315
+ _methods_ = [
316
+ ("CreateStreamFromKey",
317
+ com.STDMETHOD(c_void_p, UINT32, POINTER(POINTER(IDWriteFontFileStream)))),
318
+ ]
319
+
320
+
321
+ class IDWriteLocalFontFileLoader(IDWriteFontFileLoader, com.pIUnknown):
322
+ _methods_ = [
323
+ ("GetFilePathLengthFromKey",
324
+ com.STDMETHOD(c_void_p, UINT32, POINTER(UINT32))),
325
+ ("GetFilePathFromKey",
326
+ com.STDMETHOD(c_void_p, UINT32, c_wchar_p, UINT32)),
327
+ ("GetLastWriteTimeFromKey",
328
+ com.STDMETHOD()),
329
+ ]
330
+
331
+
332
+ IID_IDWriteLocalFontFileLoader = com.GUID(0xb2d9f3ec, 0xc9fe, 0x4a11, 0xa2, 0xec, 0xd8, 0x62, 0x08, 0xf7, 0xc0, 0xa2)
333
+
334
+
335
+ class IDWriteLocalizedStrings(com.pIUnknown):
336
+ _methods_ = [
337
+ ("GetCount",
338
+ com.METHOD(UINT32)),
339
+ ("FindLocaleName",
340
+ com.STDMETHOD(c_wchar_p, POINTER(UINT32), POINTER(BOOL))),
341
+ ("GetLocaleNameLength",
342
+ com.STDMETHOD(UINT32, POINTER(UINT32))),
343
+ ("GetLocaleName",
344
+ com.STDMETHOD(UINT32, c_wchar_p, UINT32)),
345
+ ("GetStringLength",
346
+ com.STDMETHOD(UINT32, POINTER(UINT32))),
347
+ ("GetString",
348
+ com.STDMETHOD(UINT32, c_wchar_p, UINT32)),
349
+ ]
350
+
351
+ class IDWriteFontFile(com.pIUnknown):
352
+ _methods_ = [
353
+ ("GetReferenceKey",
354
+ com.STDMETHOD(POINTER(c_void_p), POINTER(UINT32))),
355
+ ("GetLoader",
356
+ com.STDMETHOD(POINTER(IDWriteFontFileLoader))),
357
+ ("Analyze",
358
+ com.STDMETHOD()),
359
+ ]
360
+
361
+
362
+ class IDWriteFontFace(com.pIUnknown):
363
+ _methods_ = [
364
+ ("GetType",
365
+ com.METHOD(DWRITE_FONT_FACE_TYPE)),
366
+ ("GetFiles",
367
+ com.STDMETHOD(POINTER(UINT32), POINTER(IDWriteFontFile))),
368
+ ("GetIndex",
369
+ com.METHOD(UINT32)),
370
+ ("GetSimulations",
371
+ com.STDMETHOD()),
372
+ ("IsSymbolFont",
373
+ com.METHOD(BOOL)),
374
+ ("GetMetrics",
375
+ com.METHOD(c_void, POINTER(DWRITE_FONT_METRICS))),
376
+ ("GetGlyphCount",
377
+ com.METHOD(UINT16)),
378
+ ("GetDesignGlyphMetrics",
379
+ com.STDMETHOD(POINTER(UINT16), UINT32, POINTER(DWRITE_GLYPH_METRICS), BOOL)),
380
+ ("GetGlyphIndices",
381
+ com.STDMETHOD(POINTER(UINT32), UINT32, POINTER(UINT16))),
382
+ ("TryGetFontTable",
383
+ com.STDMETHOD(UINT32, c_void_p, POINTER(UINT32), c_void_p, POINTER(BOOL))),
384
+ ("ReleaseFontTable",
385
+ com.METHOD(c_void)),
386
+ ("GetGlyphRunOutline",
387
+ com.STDMETHOD()),
388
+ ("GetRecommendedRenderingMode",
389
+ com.STDMETHOD()),
390
+ ("GetGdiCompatibleMetrics",
391
+ com.STDMETHOD()),
392
+ ("GetGdiCompatibleGlyphMetrics",
393
+ com.STDMETHOD()),
394
+ ]
395
+
396
+
397
+ IID_IDWriteFontFace1 = com.GUID(0xa71efdb4, 0x9fdb, 0x4838, 0xad, 0x90, 0xcf, 0xc3, 0xbe, 0x8c, 0x3d, 0xaf)
398
+
399
+
400
+ class IDWriteFontFace1(IDWriteFontFace):
401
+ _methods_ = [
402
+ ("GetMetrics1",
403
+ com.STDMETHOD(POINTER(DWRITE_FONT_METRICS1))),
404
+ ("GetGdiCompatibleMetrics1",
405
+ com.STDMETHOD()),
406
+ ("GetCaretMetrics",
407
+ com.STDMETHOD(POINTER(DWRITE_CARET_METRICS))),
408
+ ("GetUnicodeRanges",
409
+ com.STDMETHOD()),
410
+ ("IsMonospacedFont",
411
+ com.METHOD(BOOL)),
412
+ ("GetDesignGlyphAdvances",
413
+ com.METHOD(c_void, POINTER(DWRITE_FONT_METRICS))),
414
+ ("GetGdiCompatibleGlyphAdvances",
415
+ com.STDMETHOD()),
416
+ ("GetKerningPairAdjustments",
417
+ com.STDMETHOD(UINT32, POINTER(UINT16), POINTER(INT32))),
418
+ ("HasKerningPairs",
419
+ com.METHOD(BOOL)),
420
+ ("GetRecommendedRenderingMode1",
421
+ com.STDMETHOD()),
422
+ ("GetVerticalGlyphVariants",
423
+ com.STDMETHOD()),
424
+ ("HasVerticalGlyphVariants",
425
+ com.METHOD(BOOL)),
426
+ ]
427
+
428
+ IID_IDWriteFontFace2 = com.GUID(0xd8b768ff, 0x64bc, 0x4e66, 0x98,0x2b, 0xec,0x8e,0x87,0xf6,0x93,0xf7)
429
+
430
+ class IDWriteFontFace2(IDWriteFontFace1):
431
+ _methods_ = [
432
+ ("IsColorFont",
433
+ com.METHOD(BOOL)),
434
+ ("GetColorPaletteCount",
435
+ com.METHOD(UINT32)),
436
+ ("GetPaletteEntryCount",
437
+ com.METHOD(UINT32)),
438
+ ("GetPaletteEntries",
439
+ com.STDMETHOD()),
440
+ ("GetRecommendedRenderingMode2",
441
+ com.STDMETHOD()),
442
+ ]
443
+
444
+ IID_IDWriteFontFace3 = com.GUID(0xd37d7598, 0x09be, 0x4222, 0xa2,0x36, 0x20,0x81,0x34,0x1c,0xc1,0xf2)
445
+
446
+ class IDWriteFontFace3(IDWriteFontFace2):
447
+ _methods_ = [
448
+ ("GetFontFaceReference",
449
+ com.STDMETHOD()),
450
+ ("GetPanose",
451
+ com.STDMETHOD()),
452
+ ("GetWeight",
453
+ com.METHOD(DWRITE_FONT_WEIGHT)),
454
+ ("GetStretch",
455
+ com.METHOD(DWRITE_FONT_STRETCH)),
456
+ ("GetStyle",
457
+ com.METHOD(DWRITE_FONT_STYLE)),
458
+ ("GetFamilyNames",
459
+ com.STDMETHOD(POINTER(IDWriteLocalizedStrings))),
460
+ ("GetFaceNames",
461
+ com.STDMETHOD(POINTER(IDWriteLocalizedStrings))),
462
+ ("GetInformationalStrings",
463
+ com.STDMETHOD()),
464
+ ("HasCharacter",
465
+ com.METHOD(BOOL, UINT32)),
466
+ ("GetRecommendedRenderingMode3",
467
+ com.STDMETHOD()),
468
+ ("IsCharacterLocal",
469
+ com.STDMETHOD()),
470
+ ("IsGlyphLocal",
471
+ com.STDMETHOD()),
472
+ ("AreCharactersLocal",
473
+ com.STDMETHOD()),
474
+ ("AreGlyphsLocal",
475
+ com.STDMETHOD()),
476
+ ]
477
+
478
+
479
+ class DWRITE_GLYPH_IMAGE_DATA(Structure):
480
+ _fields_ = [
481
+ ("imageData", c_void_p),
482
+ ("imageDataSize", UINT32),
483
+ ("uniqueDataId", UINT32),
484
+ ("pixelsPerEm", UINT32),
485
+ ("pixelSize", D2D1_SIZE_U),
486
+ ("horizontalLeftOrigin", D2D1_POINT_2L),
487
+ ("horizontalRightOrigin", D2D1_POINT_2L),
488
+ ("verticalTopOrigin", D2D1_POINT_2L),
489
+ ("verticalBottomOrigin", D2D1_POINT_2L),
490
+ ]
491
+
492
+ IID_IDWriteFontFace4 = com.GUID(0x27f2a904, 0x4eb8, 0x441d, 0x96,0x78, 0x05,0x63,0xf5,0x3e,0x3e,0x2f)
493
+
494
+ class IDWriteFontFace4(IDWriteFontFace3):
495
+ _methods_ = [
496
+ ("GetGlyphImageFormats_",
497
+ com.STDMETHOD(UINT16, UINT32, UINT32, POINTER(DWRITE_GLYPH_IMAGE_FORMATS))),
498
+ ("GetGlyphImageFormats",
499
+ com.METHOD(DWRITE_GLYPH_IMAGE_FORMATS)),
500
+ ("GetGlyphImageData",
501
+ com.STDMETHOD(UINT16, UINT32, DWRITE_GLYPH_IMAGE_FORMATS, POINTER(DWRITE_GLYPH_IMAGE_DATA),
502
+ POINTER(c_void_p))),
503
+ ("ReleaseGlyphImageData",
504
+ com.METHOD(None, c_void_p))
505
+ ]
506
+
507
+
508
+ class DWRITE_GLYPH_RUN(Structure):
509
+ _fields_ = (
510
+ ("fontFace", IDWriteFontFace),
511
+ ("fontEmSize", FLOAT),
512
+ ("glyphCount", UINT32),
513
+ ("glyphIndices", POINTER(UINT16)),
514
+ ("glyphAdvances", POINTER(FLOAT)),
515
+ ("glyphOffsets", POINTER(DWRITE_GLYPH_OFFSET)),
516
+ ("isSideways", BOOL),
517
+ ("bidiLevel", UINT32),
518
+ )
519
+
520
+ def get_info(self):
521
+ print(f"DWRITE_GLYPH_RUN(face: {self.fontFace}, fontEmSize: {self.fontEmSize}, count: {self.glyphCount}")
522
+ for i in range(self.glyphCount):
523
+ print(f"glyph: {i}, indice: {self.glyphIndices[i]}, advance: {self.glyphAdvances[i]}, offset: {self.glyphOffsets[i]}")
524
+
525
+
526
+ DWRITE_SCRIPT_SHAPES = UINT
527
+ DWRITE_SCRIPT_SHAPES_DEFAULT = 0
528
+
529
+
530
+ class DWRITE_SCRIPT_ANALYSIS(Structure):
531
+ _fields_ = (
532
+ ("script", UINT16),
533
+ ("shapes", DWRITE_SCRIPT_SHAPES),
534
+ )
535
+
536
+
537
+ DWRITE_FONT_FEATURE_TAG = UINT
538
+
539
+
540
+ class DWRITE_FONT_FEATURE(Structure):
541
+ _fields_ = (
542
+ ("nameTag", DWRITE_FONT_FEATURE_TAG),
543
+ ("parameter", UINT32),
544
+ )
545
+
546
+
547
+ class DWRITE_TYPOGRAPHIC_FEATURES(Structure):
548
+ _fields_ = (
549
+ ("features", POINTER(DWRITE_FONT_FEATURE)),
550
+ ("featureCount", UINT32),
551
+ )
552
+
553
+
554
+ class DWRITE_SHAPING_TEXT_PROPERTIES(Structure):
555
+ _fields_ = (
556
+ ("isShapedAlone", UINT16, 1),
557
+ ("reserved1", UINT16, 1),
558
+ ("canBreakShapingAfter", UINT16, 1),
559
+ ("reserved", UINT16, 13),
560
+ )
561
+
562
+ def __repr__(self) -> str:
563
+ return f"DWRITE_SHAPING_TEXT_PROPERTIES({self.isShapedAlone}, {self.reserved1}, {self.canBreakShapingAfter})"
564
+
565
+
566
+ class DWRITE_SHAPING_GLYPH_PROPERTIES(Structure):
567
+ _fields_ = (
568
+ ("justification", UINT16, 4),
569
+ ("isClusterStart", UINT16, 1),
570
+ ("isDiacritic", UINT16, 1),
571
+ ("isZeroWidthSpace", UINT16, 1),
572
+ ("reserved", UINT16, 9),
573
+ )
574
+ DWRITE_SHAPING_GLYPH_PROPERTIES.__repr__ = repr_func
575
+
576
+ DWRITE_READING_DIRECTION = UINT
577
+ DWRITE_READING_DIRECTION_LEFT_TO_RIGHT = 0
578
+
579
+
580
+ class IDWriteTextAnalysisSource(com.IUnknown):
581
+ _methods_ = [
582
+ ("GetTextAtPosition",
583
+ com.STDMETHOD(UINT32, POINTER(c_wchar_p), POINTER(UINT32))),
584
+ ("GetTextBeforePosition",
585
+ com.STDMETHOD(UINT32, POINTER(c_wchar_p), POINTER(UINT32))),
586
+ ("GetParagraphReadingDirection",
587
+ com.METHOD(DWRITE_READING_DIRECTION)),
588
+ ("GetLocaleName",
589
+ com.STDMETHOD(UINT32, POINTER(UINT32), POINTER(c_wchar_p))),
590
+ ("GetNumberSubstitution",
591
+ com.STDMETHOD(UINT32, POINTER(UINT32), c_void_p)),
592
+ ]
593
+
594
+
595
+ class IDWriteTextAnalysisSink(com.IUnknown):
596
+ _methods_ = [
597
+ ("SetScriptAnalysis",
598
+ com.STDMETHOD(UINT32, UINT32, POINTER(DWRITE_SCRIPT_ANALYSIS))),
599
+ ("SetLineBreakpoints",
600
+ com.STDMETHOD(UINT32, UINT32, c_void_p)),
601
+ ("SetBidiLevel",
602
+ com.STDMETHOD(UINT32, UINT32, UINT8, UINT8)),
603
+ ("SetNumberSubstitution",
604
+ com.STDMETHOD(UINT32, UINT32, c_void_p)),
605
+ ]
606
+
607
+
608
+ class IDWriteTextAnalyzer(com.pIUnknown):
609
+ _methods_ = [
610
+ ("AnalyzeScript",
611
+ com.STDMETHOD(POINTER(IDWriteTextAnalysisSource), UINT32, UINT32, POINTER(IDWriteTextAnalysisSink))),
612
+ ("AnalyzeBidi",
613
+ com.STDMETHOD()),
614
+ ("AnalyzeNumberSubstitution",
615
+ com.STDMETHOD()),
616
+ ("AnalyzeLineBreakpoints",
617
+ com.STDMETHOD()),
618
+ ("GetGlyphs",
619
+ com.STDMETHOD(c_wchar_p, UINT32, IDWriteFontFace, BOOL, BOOL, POINTER(DWRITE_SCRIPT_ANALYSIS),
620
+ c_wchar_p, c_void_p, POINTER(POINTER(DWRITE_TYPOGRAPHIC_FEATURES)), POINTER(UINT32),
621
+ UINT32, UINT32, POINTER(UINT16), POINTER(DWRITE_SHAPING_TEXT_PROPERTIES),
622
+ POINTER(UINT16), POINTER(DWRITE_SHAPING_GLYPH_PROPERTIES), POINTER(UINT32))),
623
+ ("GetGlyphPlacements",
624
+ com.STDMETHOD(c_wchar_p, POINTER(UINT16), POINTER(DWRITE_SHAPING_TEXT_PROPERTIES), UINT32, POINTER(UINT16),
625
+ POINTER(DWRITE_SHAPING_GLYPH_PROPERTIES), UINT32, IDWriteFontFace, FLOAT, BOOL, BOOL,
626
+ POINTER(DWRITE_SCRIPT_ANALYSIS), c_wchar_p, POINTER(DWRITE_TYPOGRAPHIC_FEATURES),
627
+ POINTER(UINT32), UINT32, POINTER(FLOAT), POINTER(DWRITE_GLYPH_OFFSET))),
628
+ ("GetGdiCompatibleGlyphPlacements",
629
+ com.STDMETHOD()),
630
+ ]
631
+
632
+
633
+
634
+
635
+ class IDWriteFontList(com.pIUnknown):
636
+ _methods_ = [
637
+ ("GetFontCollection",
638
+ com.STDMETHOD()),
639
+ ("GetFontCount",
640
+ com.METHOD(UINT32)),
641
+ ("GetFont",
642
+ com.STDMETHOD(UINT32, c_void_p)), # IDWriteFont, use void because of forward ref.
643
+ ]
644
+
645
+
646
+ class IDWriteFontFamily(IDWriteFontList, com.pIUnknown):
647
+ _methods_ = [
648
+ ("GetFamilyNames",
649
+ com.STDMETHOD(POINTER(IDWriteLocalizedStrings))),
650
+ ("GetFirstMatchingFont",
651
+ com.STDMETHOD(DWRITE_FONT_WEIGHT, DWRITE_FONT_STRETCH, DWRITE_FONT_STYLE, c_void_p)),
652
+ ("GetMatchingFonts",
653
+ com.STDMETHOD()),
654
+ ]
655
+
656
+
657
+ class IDWriteFontFamily1(IDWriteFontFamily, IDWriteFontList, com.pIUnknown):
658
+ _methods_ = [
659
+ ("GetFontLocality",
660
+ com.STDMETHOD()),
661
+ ("GetFont1",
662
+ com.STDMETHOD()),
663
+ ("GetFontFaceReference",
664
+ com.STDMETHOD()),
665
+ ]
666
+
667
+
668
+ class IDWriteFont(com.pIUnknown):
669
+ _methods_ = [
670
+ ("GetFontFamily",
671
+ com.STDMETHOD(POINTER(IDWriteFontFamily))),
672
+ ("GetWeight",
673
+ com.METHOD(DWRITE_FONT_WEIGHT)),
674
+ ("GetStretch",
675
+ com.METHOD(DWRITE_FONT_STRETCH)),
676
+ ("GetStyle",
677
+ com.METHOD(DWRITE_FONT_STYLE)),
678
+ ("IsSymbolFont",
679
+ com.METHOD(BOOL)),
680
+ ("GetFaceNames",
681
+ com.STDMETHOD(POINTER(IDWriteLocalizedStrings))),
682
+ ("GetInformationalStrings",
683
+ com.STDMETHOD(DWRITE_INFORMATIONAL_STRING_ID, POINTER(IDWriteLocalizedStrings), POINTER(BOOL))),
684
+ ("GetSimulations",
685
+ com.STDMETHOD()),
686
+ ("GetMetrics",
687
+ com.STDMETHOD()),
688
+ ("HasCharacter",
689
+ com.STDMETHOD(UINT32, POINTER(BOOL))),
690
+ ("CreateFontFace",
691
+ com.STDMETHOD(POINTER(IDWriteFontFace))),
692
+ ]
693
+
694
+
695
+ class IDWriteFont1(IDWriteFont, com.pIUnknown):
696
+ _methods_ = [
697
+ ("GetMetrics1",
698
+ com.STDMETHOD()),
699
+ ("GetPanose",
700
+ com.STDMETHOD()),
701
+ ("GetUnicodeRanges",
702
+ com.STDMETHOD()),
703
+ ("IsMonospacedFont",
704
+ com.STDMETHOD()),
705
+ ]
706
+
707
+
708
+ class IDWriteFontCollection(com.pIUnknown):
709
+ _methods_ = [
710
+ ("GetFontFamilyCount",
711
+ com.METHOD(UINT32)),
712
+ ("GetFontFamily",
713
+ com.STDMETHOD(UINT32, POINTER(IDWriteFontFamily))),
714
+ ("FindFamilyName",
715
+ com.STDMETHOD(c_wchar_p, POINTER(UINT), POINTER(BOOL))),
716
+ ("GetFontFromFontFace",
717
+ com.STDMETHOD()),
718
+ ]
719
+
720
+
721
+ class IDWriteFontCollection1(IDWriteFontCollection, com.pIUnknown):
722
+ _methods_ = [
723
+ ("GetFontSet",
724
+ com.STDMETHOD()),
725
+ ("GetFontFamily1",
726
+ com.STDMETHOD(POINTER(IDWriteFontFamily1))),
727
+ ]
728
+
729
+
730
+ class IDWriteGdiInterop(com.pIUnknown):
731
+ _methods_ = [
732
+ ("CreateFontFromLOGFONT",
733
+ com.STDMETHOD(POINTER(LOGFONTW), POINTER(IDWriteFont))),
734
+ ("ConvertFontToLOGFONT",
735
+ com.STDMETHOD()),
736
+ ("ConvertFontFaceToLOGFONT",
737
+ com.STDMETHOD()),
738
+ ("CreateFontFaceFromHdc",
739
+ com.STDMETHOD(HDC, POINTER(IDWriteFontFace))),
740
+ ("CreateBitmapRenderTarget",
741
+ com.STDMETHOD()),
742
+ ]
743
+
744
+
745
+ class IDWriteTextFormat(com.pIUnknown):
746
+ _methods_ = [
747
+ ("SetTextAlignment",
748
+ com.STDMETHOD(DWRITE_TEXT_ALIGNMENT)),
749
+ ("SetParagraphAlignment",
750
+ com.STDMETHOD()),
751
+ ("SetWordWrapping",
752
+ com.STDMETHOD()),
753
+ ("SetReadingDirection",
754
+ com.STDMETHOD()),
755
+ ("SetFlowDirection",
756
+ com.STDMETHOD()),
757
+ ("SetIncrementalTabStop",
758
+ com.STDMETHOD()),
759
+ ("SetTrimming",
760
+ com.STDMETHOD()),
761
+ ("SetLineSpacing",
762
+ com.STDMETHOD()),
763
+ ("GetTextAlignment",
764
+ com.STDMETHOD()),
765
+ ("GetParagraphAlignment",
766
+ com.STDMETHOD()),
767
+ ("GetWordWrapping",
768
+ com.STDMETHOD()),
769
+ ("GetReadingDirection",
770
+ com.STDMETHOD()),
771
+ ("GetFlowDirection",
772
+ com.STDMETHOD()),
773
+ ("GetIncrementalTabStop",
774
+ com.STDMETHOD()),
775
+ ("GetTrimming",
776
+ com.STDMETHOD()),
777
+ ("GetLineSpacing",
778
+ com.STDMETHOD()),
779
+ ("GetFontCollection",
780
+ com.STDMETHOD()),
781
+ ("GetFontFamilyNameLength",
782
+ com.STDMETHOD(UINT32, POINTER(UINT32))),
783
+ ("GetFontFamilyName",
784
+ com.STDMETHOD(UINT32, c_wchar_p, UINT32)),
785
+ ("GetFontWeight",
786
+ com.STDMETHOD()),
787
+ ("GetFontStyle",
788
+ com.STDMETHOD()),
789
+ ("GetFontStretch",
790
+ com.STDMETHOD()),
791
+ ("GetFontSize",
792
+ com.STDMETHOD()),
793
+ ("GetLocaleNameLength",
794
+ com.STDMETHOD()),
795
+ ("GetLocaleName",
796
+ com.STDMETHOD()),
797
+ ]
798
+
799
+
800
+ class IDWriteTypography(com.pIUnknown):
801
+ _methods_ = [
802
+ ("AddFontFeature",
803
+ com.STDMETHOD(DWRITE_FONT_FEATURE)),
804
+ ("GetFontFeatureCount",
805
+ com.METHOD(UINT32)),
806
+ ("GetFontFeature",
807
+ com.STDMETHOD()),
808
+ ]
809
+
810
+
811
+ class DWRITE_TEXT_RANGE(Structure):
812
+ _fields_ = (
813
+ ("startPosition", UINT32),
814
+ ("length", UINT32),
815
+ )
816
+
817
+
818
+ class DWRITE_OVERHANG_METRICS(Structure):
819
+ _fields_ = (
820
+ ("left", FLOAT),
821
+ ("top", FLOAT),
822
+ ("right", FLOAT),
823
+ ("bottom", FLOAT),
824
+ )
825
+
826
+
827
+ class DWRITE_GLYPH_RUN_DESCRIPTION(Structure):
828
+ _fields_ = [
829
+ ('localeName', c_wchar_p),
830
+ ('text', c_wchar_p),
831
+ ('textLength', UINT32),
832
+ ('clusterMap', POINTER(UINT16)),
833
+ ('textPosition', UINT32)
834
+ ]
835
+
836
+ class DWRITE_COLOR_GLYPH_RUN(Structure):
837
+ _fields_ = [
838
+ ('glyphRun', DWRITE_GLYPH_RUN),
839
+ ('glyphRunDescription', POINTER(DWRITE_GLYPH_RUN_DESCRIPTION)),
840
+ ('baselineOriginX', FLOAT),
841
+ ('baselineOriginY', FLOAT),
842
+ ('runColor', DWRITE_COLOR_F),
843
+ ('paletteIndex', UINT16),
844
+ ]
845
+
846
+
847
+ DWRITE_COLOR_GLYPH_RUN1_Fields = [
848
+ ('glyphRun', DWRITE_GLYPH_RUN),
849
+ ('glyphRunDescription', POINTER(DWRITE_GLYPH_RUN_DESCRIPTION)),
850
+ ('baselineOriginX', FLOAT),
851
+ ('baselineOriginY', FLOAT),
852
+ ('runColor', DWRITE_COLOR_F),
853
+ ('paletteIndex', UINT16),
854
+ ("_pad", UINT32), # Padding only exists in 64 bit... only info found in header.
855
+ ('glyphImageFormat', DWRITE_GLYPH_IMAGE_FORMATS),
856
+ ('measuringMode', DWRITE_MEASURING_MODE)
857
+ ]
858
+
859
+ if platform.architecture()[0] == "32bit":
860
+ DWRITE_COLOR_GLYPH_RUN1_Fields.remove(("_pad", UINT32))
861
+
862
+
863
+ class DWRITE_COLOR_GLYPH_RUN1(Structure):
864
+ _fields_ = DWRITE_COLOR_GLYPH_RUN1_Fields
865
+
866
+ class DWRITE_MATRIX(Structure):
867
+ _fields_ = [
868
+ ("m11", FLOAT),
869
+ ("m12", FLOAT),
870
+ ("m21", FLOAT),
871
+ ("m22", FLOAT),
872
+ ("dx", FLOAT),
873
+ ("dy", FLOAT),
874
+ ]
875
+
876
+ class IDWritePixelSnapping(com.IUnknown):
877
+ _methods_ = [
878
+ ("IsPixelSnappingDisabled", com.STDMETHOD(c_void_p, POINTER(FLOAT))),
879
+ ("GetCurrentTransform", com.STDMETHOD(c_void_p, POINTER(DWRITE_MATRIX))),
880
+ ("GetPixelsPerDip", com.STDMETHOD(c_void_p, POINTER(FLOAT))),
881
+ ]
882
+
883
+ class IDWriteTextRenderer(IDWritePixelSnapping):
884
+ _methods_ = [
885
+ ("DrawGlyphRun",
886
+ com.STDMETHOD(c_void_p, FLOAT, FLOAT, DWRITE_MEASURING_MODE,
887
+ POINTER(DWRITE_GLYPH_RUN),
888
+ POINTER(DWRITE_GLYPH_RUN_DESCRIPTION), c_void_p)),
889
+ ("DrawUnderline",
890
+ com.STDMETHOD(c_void_p, FLOAT, FLOAT, c_void_p, c_void_p)
891
+ ),
892
+ ("DrawStrikethrough",
893
+ com.STDMETHOD(c_void_p, FLOAT, FLOAT, c_void_p, c_void_p)),
894
+ ("DrawInlineObject",
895
+ com.STDMETHOD(c_void_p, FLOAT, FLOAT, c_void_p, BOOL, BOOL, c_void_p)),
896
+ ]
897
+
898
+
899
+ class IDWriteTextLayout(IDWriteTextFormat):
900
+ _methods_ = [
901
+ ("SetMaxWidth",
902
+ com.STDMETHOD()),
903
+ ("SetMaxHeight",
904
+ com.STDMETHOD()),
905
+ ("SetFontCollection",
906
+ com.STDMETHOD()),
907
+ ("SetFontFamilyName",
908
+ com.STDMETHOD()),
909
+ ("SetFontWeight", # 30
910
+ com.STDMETHOD()),
911
+ ("SetFontStyle",
912
+ com.STDMETHOD()),
913
+ ("SetFontStretch",
914
+ com.STDMETHOD()),
915
+ ("SetFontSize",
916
+ com.STDMETHOD()),
917
+ ("SetUnderline",
918
+ com.STDMETHOD()),
919
+ ("SetStrikethrough",
920
+ com.STDMETHOD()),
921
+ ("SetDrawingEffect",
922
+ com.STDMETHOD()),
923
+ ("SetInlineObject",
924
+ com.STDMETHOD()),
925
+ ("SetTypography",
926
+ com.STDMETHOD(IDWriteTypography, DWRITE_TEXT_RANGE)),
927
+ ("SetLocaleName",
928
+ com.STDMETHOD()),
929
+ ("GetMaxWidth", # 40
930
+ com.METHOD(FLOAT)),
931
+ ("GetMaxHeight",
932
+ com.METHOD(FLOAT)),
933
+ ("GetFontCollection2",
934
+ com.STDMETHOD(UINT32, POINTER(IDWriteFontCollection), POINTER(DWRITE_TEXT_RANGE))),
935
+ ("GetFontFamilyNameLength2",
936
+ com.STDMETHOD(UINT32, POINTER(UINT32), c_void_p)),
937
+ ("GetFontFamilyName2",
938
+ com.STDMETHOD(UINT32, c_wchar_p, UINT32, POINTER(DWRITE_TEXT_RANGE))),
939
+ ("GetFontWeight2",
940
+ com.STDMETHOD(UINT32, POINTER(DWRITE_FONT_WEIGHT), POINTER(DWRITE_TEXT_RANGE))),
941
+ ("GetFontStyle2",
942
+ com.STDMETHOD()),
943
+ ("GetFontStretch2",
944
+ com.STDMETHOD()),
945
+ ("GetFontSize2",
946
+ com.STDMETHOD()),
947
+ ("GetUnderline",
948
+ com.STDMETHOD()),
949
+ ("GetStrikethrough",
950
+ com.STDMETHOD(UINT32, POINTER(BOOL), POINTER(DWRITE_TEXT_RANGE))),
951
+ ("GetDrawingEffect",
952
+ com.STDMETHOD()),
953
+ ("GetInlineObject",
954
+ com.STDMETHOD()),
955
+ ("GetTypography", # Always returns NULL without SetTypography being called.
956
+ com.STDMETHOD(UINT32, POINTER(IDWriteTypography), POINTER(DWRITE_TEXT_RANGE))),
957
+ ("GetLocaleNameLength1",
958
+ com.STDMETHOD()),
959
+ ("GetLocaleName1",
960
+ com.STDMETHOD()),
961
+ ("Draw",
962
+ com.STDMETHOD(c_void_p, POINTER(IDWriteTextRenderer), FLOAT, FLOAT)),
963
+ ("GetLineMetrics",
964
+ com.STDMETHOD()),
965
+ ("GetMetrics",
966
+ com.STDMETHOD(POINTER(DWRITE_TEXT_METRICS))),
967
+ ("GetOverhangMetrics",
968
+ com.STDMETHOD(POINTER(DWRITE_OVERHANG_METRICS))),
969
+ ("GetClusterMetrics",
970
+ com.STDMETHOD(POINTER(DWRITE_CLUSTER_METRICS), UINT32, POINTER(UINT32))),
971
+ ("DetermineMinWidth",
972
+ com.STDMETHOD(POINTER(FLOAT))),
973
+ ("HitTestPoint",
974
+ com.STDMETHOD()),
975
+ ("HitTestTextPosition",
976
+ com.STDMETHOD()),
977
+ ("HitTestTextRange",
978
+ com.STDMETHOD()),
979
+ ]
980
+
981
+
982
+ class IDWriteTextLayout1(IDWriteTextLayout, IDWriteTextFormat, com.pIUnknown):
983
+ _methods_ = [
984
+ ("SetPairKerning",
985
+ com.STDMETHOD()),
986
+ ("GetPairKerning",
987
+ com.STDMETHOD()),
988
+ ("SetCharacterSpacing",
989
+ com.STDMETHOD()),
990
+ ("GetCharacterSpacing",
991
+ com.STDMETHOD(UINT32, POINTER(FLOAT), POINTER(FLOAT), POINTER(FLOAT), POINTER(DWRITE_TEXT_RANGE))),
992
+ ]
993
+
994
+
995
+ class IDWriteFontFileEnumerator(com.IUnknown):
996
+ _methods_ = [
997
+ ("MoveNext",
998
+ com.STDMETHOD(POINTER(BOOL))),
999
+ ("GetCurrentFontFile",
1000
+ com.STDMETHOD(c_void_p)),
1001
+ ]
1002
+
1003
+
1004
+ class IDWriteFontCollectionLoader(com.IUnknown):
1005
+ _methods_ = [
1006
+ ("CreateEnumeratorFromKey",
1007
+ com.STDMETHOD(c_void_p, c_void_p, UINT32, POINTER(POINTER(IDWriteFontFileEnumerator)))),
1008
+ ]
1009
+
1010
+ # Windows 7
1011
+ IID_IDWriteFactory = com.GUID(0xb859ee5a, 0xd838, 0x4b5b, 0xa2, 0xe8, 0x1a, 0xdc, 0x7d, 0x93, 0xdb, 0x48)
1012
+
1013
+
1014
+ class IDWriteRenderingParams(com.pIUnknown):
1015
+ _methods_ = [
1016
+ ("GetGamma",
1017
+ com.METHOD(FLOAT)),
1018
+ ("GetEnhancedContrast",
1019
+ com.METHOD(FLOAT)),
1020
+ ("GetClearTypeLevel",
1021
+ com.METHOD(FLOAT)),
1022
+ ("GetPixelGeometry",
1023
+ com.METHOD(UINT)),
1024
+ ("GetRenderingMode",
1025
+ com.METHOD(UINT)),
1026
+ ]
1027
+
1028
+
1029
+ class IDWriteFactory(com.pIUnknown):
1030
+ _methods_ = [
1031
+ ("GetSystemFontCollection",
1032
+ com.STDMETHOD(POINTER(IDWriteFontCollection), BOOL)),
1033
+ ("CreateCustomFontCollection",
1034
+ com.STDMETHOD(POINTER(IDWriteFontCollectionLoader), c_void_p, UINT32, POINTER(IDWriteFontCollection))),
1035
+ ("RegisterFontCollectionLoader",
1036
+ com.STDMETHOD(POINTER(IDWriteFontCollectionLoader))),
1037
+ ("UnregisterFontCollectionLoader",
1038
+ com.STDMETHOD(POINTER(IDWriteFontCollectionLoader))),
1039
+ ("CreateFontFileReference",
1040
+ com.STDMETHOD(c_wchar_p, c_void_p, POINTER(IDWriteFontFile))),
1041
+ ("CreateCustomFontFileReference",
1042
+ com.STDMETHOD(c_void_p, UINT32, POINTER(IDWriteFontFileLoader_LI), POINTER(IDWriteFontFile))),
1043
+ ("CreateFontFace",
1044
+ com.STDMETHOD()),
1045
+ ("CreateRenderingParams",
1046
+ com.STDMETHOD(POINTER(IDWriteRenderingParams))),
1047
+ ("CreateMonitorRenderingParams",
1048
+ com.STDMETHOD()),
1049
+ ("CreateCustomRenderingParams",
1050
+ com.STDMETHOD(FLOAT, FLOAT, FLOAT, UINT, UINT, POINTER(IDWriteRenderingParams))),
1051
+ ("RegisterFontFileLoader",
1052
+ com.STDMETHOD(c_void_p)), # Ambigious as newer is a pIUnknown and legacy is IUnknown.
1053
+ ("UnregisterFontFileLoader",
1054
+ com.STDMETHOD(POINTER(IDWriteFontFileLoader_LI))),
1055
+ ("CreateTextFormat",
1056
+ com.STDMETHOD(c_wchar_p, IDWriteFontCollection, DWRITE_FONT_WEIGHT, DWRITE_FONT_STYLE, DWRITE_FONT_STRETCH,
1057
+ FLOAT, c_wchar_p, POINTER(IDWriteTextFormat))),
1058
+ ("CreateTypography",
1059
+ com.STDMETHOD(POINTER(IDWriteTypography))),
1060
+ ("GetGdiInterop",
1061
+ com.STDMETHOD(POINTER(IDWriteGdiInterop))),
1062
+ ("CreateTextLayout",
1063
+ com.STDMETHOD(c_wchar_p, UINT32, IDWriteTextFormat, FLOAT, FLOAT, POINTER(IDWriteTextLayout))),
1064
+ ("CreateGdiCompatibleTextLayout",
1065
+ com.STDMETHOD()),
1066
+ ("CreateEllipsisTrimmingSign",
1067
+ com.STDMETHOD()),
1068
+ ("CreateTextAnalyzer",
1069
+ com.STDMETHOD(POINTER(IDWriteTextAnalyzer))),
1070
+ ("CreateNumberSubstitution",
1071
+ com.STDMETHOD()),
1072
+ ("CreateGlyphRunAnalysis",
1073
+ com.STDMETHOD()),
1074
+ ]
1075
+
1076
+ # Windows 8
1077
+ IID_IDWriteFactory1 = com.GUID(0x30572f99, 0xdac6, 0x41db, 0xa1, 0x6e, 0x04, 0x86, 0x30, 0x7e, 0x60, 0x6a)
1078
+
1079
+
1080
+ class IDWriteFactory1(IDWriteFactory, com.pIUnknown):
1081
+ _methods_ = [
1082
+ ("GetEudcFontCollection",
1083
+ com.STDMETHOD()),
1084
+ ("CreateCustomRenderingParams1",
1085
+ com.STDMETHOD()),
1086
+ ]
1087
+
1088
+
1089
+ class DWRITE_UNICODE_RANGE(Structure):
1090
+ _fields_ = [
1091
+ ("first", UINT32),
1092
+ ("last", UINT32)
1093
+ ]
1094
+
1095
+
1096
+ class IDWriteFontFallback(com.pIUnknown):
1097
+ _methods_ = [
1098
+ ("MapCharacters",
1099
+ com.STDMETHOD(POINTER(IDWriteTextAnalysisSource), UINT32, UINT32, IDWriteFontCollection, c_wchar_p,
1100
+ DWRITE_FONT_WEIGHT, DWRITE_FONT_STYLE, DWRITE_FONT_STRETCH, POINTER(UINT32),
1101
+ POINTER(IDWriteFont),
1102
+ POINTER(FLOAT))),
1103
+ ]
1104
+
1105
+ class IDWriteFontFallbackBuilder(com.pIUnknown):
1106
+ _methods_ = [
1107
+ ("AddMapping",
1108
+ com.STDMETHOD(POINTER(DWRITE_UNICODE_RANGE), UINT32, POINTER(c_wchar_p), UINT32,
1109
+ IDWriteFontCollection,
1110
+ c_wchar_p, c_wchar_p, FLOAT)),
1111
+ ("AddMappings",
1112
+ com.STDMETHOD(IDWriteFontFallback)),
1113
+ ("CreateFontFallback",
1114
+ com.STDMETHOD(POINTER(IDWriteFontFallback))),
1115
+ ]
1116
+
1117
+
1118
+
1119
+ class IDWriteColorGlyphRunEnumerator(com.pIUnknown):
1120
+ _methods_ = [
1121
+ ("MoveNext",
1122
+ com.STDMETHOD(POINTER(BOOL))),
1123
+ ("GetCurrentRun",
1124
+ com.STDMETHOD(POINTER(POINTER(DWRITE_COLOR_GLYPH_RUN)))),
1125
+ ]
1126
+
1127
+
1128
+ class IDWriteFactory2(IDWriteFactory1, IDWriteFactory, com.pIUnknown):
1129
+ _methods_ = [
1130
+ ("GetSystemFontFallback",
1131
+ com.STDMETHOD(POINTER(IDWriteFontFallback))),
1132
+ ("CreateFontFallbackBuilder",
1133
+ com.STDMETHOD(POINTER(IDWriteFontFallbackBuilder))),
1134
+ ("TranslateColorGlyphRun",
1135
+ com.STDMETHOD(FLOAT, FLOAT, POINTER(DWRITE_GLYPH_RUN), c_void_p, DWRITE_MEASURING_MODE, c_void_p, UINT32,
1136
+ POINTER(IDWriteColorGlyphRunEnumerator))),
1137
+ ("CreateCustomRenderingParams2",
1138
+ com.STDMETHOD()),
1139
+ ("CreateGlyphRunAnalysis2",
1140
+ com.STDMETHOD()),
1141
+ ]
1142
+
1143
+ # Windows 8.1
1144
+ IID_IDWriteFactory2 = com.GUID(0x0439fc60, 0xca44, 0x4994, 0x8d, 0xee, 0x3a, 0x9a, 0xf7, 0xb7, 0x32, 0xec)
1145
+
1146
+
1147
+ class IDWriteFontSet(com.pIUnknown):
1148
+ _methods_ = [
1149
+ ("GetFontCount",
1150
+ com.STDMETHOD()),
1151
+ ("GetFontFaceReference",
1152
+ com.STDMETHOD()),
1153
+ ("FindFontFaceReference",
1154
+ com.STDMETHOD()),
1155
+ ("FindFontFace",
1156
+ com.STDMETHOD()),
1157
+ ("GetPropertyValues__",
1158
+ com.STDMETHOD()),
1159
+ ("GetPropertyValues_",
1160
+ com.STDMETHOD()),
1161
+ ("GetPropertyValues",
1162
+ com.STDMETHOD()),
1163
+ ("GetPropertyOccurrenceCount",
1164
+ com.STDMETHOD()),
1165
+ ("GetMatchingFonts_",
1166
+ com.STDMETHOD()),
1167
+ ("GetMatchingFonts",
1168
+ com.STDMETHOD()),
1169
+ ]
1170
+
1171
+
1172
+ class IDWriteFontSetBuilder(com.pIUnknown):
1173
+ _methods_ = [
1174
+ ("AddFontFaceReference_",
1175
+ com.STDMETHOD()),
1176
+ ("AddFontFaceReference",
1177
+ com.STDMETHOD()),
1178
+ ("AddFontSet",
1179
+ com.STDMETHOD()),
1180
+ ("CreateFontSet",
1181
+ com.STDMETHOD(POINTER(IDWriteFontSet))),
1182
+ ]
1183
+
1184
+
1185
+ class IDWriteFontSetBuilder1(IDWriteFontSetBuilder, com.pIUnknown):
1186
+ _methods_ = [
1187
+ ("AddFontFile",
1188
+ com.STDMETHOD(IDWriteFontFile)),
1189
+ ]
1190
+
1191
+
1192
+ class IDWriteFactory3(IDWriteFactory2, com.pIUnknown):
1193
+ _methods_ = [
1194
+ ("CreateGlyphRunAnalysis3",
1195
+ com.STDMETHOD()),
1196
+ ("CreateCustomRenderingParams3",
1197
+ com.STDMETHOD()),
1198
+ ("CreateFontFaceReference_",
1199
+ com.STDMETHOD()),
1200
+ ("CreateFontFaceReference",
1201
+ com.STDMETHOD()),
1202
+ ("GetSystemFontSet",
1203
+ com.STDMETHOD()),
1204
+ ("CreateFontSetBuilder",
1205
+ com.STDMETHOD(POINTER(IDWriteFontSetBuilder))),
1206
+ ("CreateFontCollectionFromFontSet",
1207
+ com.STDMETHOD(IDWriteFontSet, POINTER(IDWriteFontCollection1))),
1208
+ ("GetSystemFontCollection3",
1209
+ com.STDMETHOD()),
1210
+ ("GetFontDownloadQueue",
1211
+ com.STDMETHOD()),
1212
+ # ('GetSystemFontSet',
1213
+ # com.STDMETHOD()),
1214
+ ]
1215
+
1216
+
1217
+ class IDWriteColorGlyphRunEnumerator1(IDWriteColorGlyphRunEnumerator):
1218
+ _methods_ = [
1219
+ ("GetCurrentRun1",
1220
+ com.STDMETHOD(POINTER(POINTER(DWRITE_COLOR_GLYPH_RUN1)))),
1221
+ ]
1222
+
1223
+ IID_IDWriteColorGlyphRunEnumerator1 = com.GUID(0x7c5f86da, 0xc7a1, 0x4f05, 0xb8,0xe1, 0x55,0xa1,0x79,0xfe,0x5a,0x35)
1224
+
1225
+
1226
+ class IDWriteFactory4(IDWriteFactory3, com.pIUnknown):
1227
+ _methods_ = [
1228
+ ("TranslateColorGlyphRun4",
1229
+ com.STDMETHOD(D2D_POINT_2F, POINTER(DWRITE_GLYPH_RUN), c_void_p, DWRITE_GLYPH_IMAGE_FORMATS,
1230
+ DWRITE_MEASURING_MODE, c_void_p, UINT32, POINTER(IDWriteColorGlyphRunEnumerator1))),
1231
+ ("ComputeGlyphOrigins_",
1232
+ com.STDMETHOD()),
1233
+ ("ComputeGlyphOrigins",
1234
+ com.STDMETHOD()),
1235
+ ]
1236
+
1237
+
1238
+ class IDWriteInMemoryFontFileLoader(com.pIUnknown):
1239
+ _methods_ = [
1240
+ ("CreateStreamFromKey",
1241
+ com.STDMETHOD()),
1242
+ ("CreateInMemoryFontFileReference",
1243
+ com.STDMETHOD(IDWriteFactory, c_void_p, UINT, c_void_p, POINTER(IDWriteFontFile))),
1244
+ ("GetFileCount",
1245
+ com.STDMETHOD()),
1246
+ ]
1247
+
1248
+ # Windows 10 - Creators
1249
+ IID_IDWriteFactory5 = com.GUID(0x958DB99A, 0xBE2A, 0x4F09, 0xAF, 0x7D, 0x65, 0x18, 0x98, 0x03, 0xD1, 0xD3)
1250
+
1251
+
1252
+ class IDWriteFactory5(IDWriteFactory4, IDWriteFactory3, IDWriteFactory2, IDWriteFactory1, IDWriteFactory,
1253
+ com.pIUnknown):
1254
+ _methods_ = [
1255
+ ("CreateFontSetBuilder5",
1256
+ com.STDMETHOD(POINTER(IDWriteFontSetBuilder1))),
1257
+ ("CreateInMemoryFontFileLoader",
1258
+ com.STDMETHOD(POINTER(IDWriteInMemoryFontFileLoader))),
1259
+ ("CreateHttpFontFileLoader",
1260
+ com.STDMETHOD()),
1261
+ ("AnalyzeContainerType",
1262
+ com.STDMETHOD()),
1263
+ ("UnpackFontFile",
1264
+ com.STDMETHOD()),
1265
+ ]
1266
+
1267
+
1268
+ ID_IDWriteFactory6 = com.GUID(0xf3744d80, 0x21f7, 0x42eb, 0xb3,0x5d, 0x99,0x5b,0xc7,0x2f,0xc2,0x23)
1269
+
1270
+ class IDWriteFactory6(IDWriteFactory5, IDWriteFactory4, IDWriteFactory3, IDWriteFactory2, IDWriteFactory1, IDWriteFactory,
1271
+ com.pIUnknown):
1272
+ _methods_ = [
1273
+ ("CreateFontFaceReference6",
1274
+ com.STDMETHOD()),
1275
+ ("CreateFontResource",
1276
+ com.STDMETHOD()),
1277
+ ("GetSystemFontSet6",
1278
+ com.STDMETHOD()),
1279
+ ("GetSystemFontCollection6",
1280
+ com.STDMETHOD()),
1281
+ ("CreateFontCollectionFromFontSet6",
1282
+ com.STDMETHOD()),
1283
+ ("CreateFontSetBuilder6",
1284
+ com.STDMETHOD()),
1285
+ ("CreateTextFormat6",
1286
+ com.STDMETHOD()),
1287
+ ]
1288
+
1289
+
1290
+ class IDWriteFactory7(IDWriteFactory6, IDWriteFactory5, IDWriteFactory4, IDWriteFactory3, IDWriteFactory2,
1291
+ IDWriteFactory1, IDWriteFactory, com.pIUnknown):
1292
+ _methods_ = [
1293
+ ("GetSystemFontSet7",
1294
+ com.STDMETHOD()),
1295
+ ("GetSystemFontCollection7",
1296
+ com.STDMETHOD()),
1297
+ ]
1298
+
1299
+ IID_IDWriteFactory7 = com.GUID(0x35d0e0b3, 0x9076, 0x4d2e, 0xa0,0x16, 0xa9,0x1b,0x56,0x8a,0x06,0xb4)
1300
+
1301
+
1302
+ DWriteCreateFactory = dwrite_lib.DWriteCreateFactory
1303
+ DWriteCreateFactory.restype = HRESULT
1304
+ DWriteCreateFactory.argtypes = [DWRITE_FACTORY_TYPE, com.REFIID, POINTER(com.pIUnknown)]
1305
+
1306
+
1307
+ # ---- COM Interface implementations.
1308
+ class Run:
1309
+ def __init__(self) -> None:
1310
+ self.text_start = 0
1311
+ self.text_length = 0
1312
+ self.glyph_start = 0
1313
+ self.glyph_count = 0
1314
+ self.script = DWRITE_SCRIPT_ANALYSIS()
1315
+ self.bidi = 0
1316
+ self.isNumberSubstituted = False
1317
+ self.isSideways = False
1318
+
1319
+ self.next_run = None
1320
+
1321
+ def ContainsTextPosition(self, textPosition: int) -> bool:
1322
+ return textPosition >= self.text_start and textPosition < self.text_start + self.text_length
1323
+
1324
+
1325
+ class TextAnalysis(com.COMObject):
1326
+ _interfaces_ = [IDWriteTextAnalysisSource, IDWriteTextAnalysisSink]
1327
+
1328
+ def __init__(self) -> None:
1329
+ super().__init__()
1330
+ self._textstart = 0
1331
+ self._textlength = 0
1332
+ self._glyphstart = 0
1333
+ self._glyphcount = 0
1334
+ self._ptrs = []
1335
+
1336
+ self._script = None
1337
+ self._bidi = 0
1338
+ # self._sideways = False # noqa: ERA001
1339
+
1340
+ def GenerateResults(self, analyzer: IDWriteTextAnalyzer, text: c_wchar_p, text_length: int) -> None:
1341
+ self._text = text
1342
+ self._textstart = 0
1343
+ self._textlength = text_length
1344
+ self._glyphstart = 0
1345
+ self._glyphcount = 0
1346
+ self._ptrs.clear()
1347
+
1348
+ self._start_run = Run()
1349
+ self._start_run.text_length = text_length
1350
+
1351
+ self._current_run = self._start_run
1352
+
1353
+ analyzer.AnalyzeScript(self, 0, text_length, self)
1354
+
1355
+ def SetScriptAnalysis(self, textPosition: UINT32, textLength: UINT32,
1356
+ scriptAnalysis: POINTER(DWRITE_SCRIPT_ANALYSIS)) -> int:
1357
+ # textPosition - The index of the first character in the string that the result applies to
1358
+ # textLength - How many characters of the string from the index that the result applies to
1359
+ # scriptAnalysis - The analysis information for all glyphs starting at position for length.
1360
+ self.SetCurrentRun(textPosition)
1361
+ self.SplitCurrentRun(textPosition)
1362
+
1363
+ while textLength > 0:
1364
+ run, textLength = self.FetchNextRun(textLength)
1365
+
1366
+ run.script.script = scriptAnalysis[0].script
1367
+ run.script.shapes = scriptAnalysis[0].shapes
1368
+
1369
+ self._script = run.script
1370
+
1371
+ return 0
1372
+ # return 0x80004001
1373
+
1374
+ def GetTextBeforePosition(self, textPosition: UINT32, textString: POINTER(POINTER(WCHAR)),
1375
+ textLength: POINTER(UINT32)) -> NoReturn:
1376
+ msg = "Currently not implemented."
1377
+ raise Exception(msg)
1378
+
1379
+ def GetTextAtPosition(self, textPosition: UINT32, textString: c_wchar_p, textLength: POINTER(UINT32)) -> int:
1380
+ # This method will retrieve a substring of the text in this layout
1381
+ # to be used in an analysis step.
1382
+ # Arguments:
1383
+ # textPosition - The index of the first character of the text to retrieve.
1384
+ # textString - The pointer to the first character of text at the index requested.
1385
+ # textLength - The characters available at/after the textString pointer (string length).
1386
+
1387
+ if textPosition >= self._textlength:
1388
+ self._no_ptr = c_wchar_p(None)
1389
+ textString[0] = self._no_ptr
1390
+ textLength[0] = 0
1391
+ else:
1392
+ ptr = c_wchar_p(self._text[textPosition:])
1393
+ self._ptrs.append(ptr)
1394
+ textString[0] = ptr
1395
+ textLength[0] = self._textlength - textPosition
1396
+
1397
+ return 0
1398
+
1399
+ def GetParagraphReadingDirection(self) -> int:
1400
+ return 0
1401
+
1402
+ def GetLocaleName(self, textPosition: UINT32, textLength: POINTER(UINT32),
1403
+ localeName: POINTER(POINTER(WCHAR))) -> int:
1404
+ self.__local_name = c_wchar_p("") # TODO: Add more locales.
1405
+ localeName[0] = self.__local_name
1406
+ textLength[0] = self._textlength - textPosition
1407
+ return 0
1408
+
1409
+ def GetNumberSubstitution(self) -> int:
1410
+ return 0
1411
+
1412
+ def SetCurrentRun(self, textPosition: UINT32) -> None:
1413
+ if self._current_run and self._current_run.ContainsTextPosition(textPosition):
1414
+ return
1415
+
1416
+ def SplitCurrentRun(self, textPosition: UINT32) -> None:
1417
+ if not self._current_run:
1418
+ return
1419
+
1420
+ if textPosition <= self._current_run.text_start:
1421
+ # Already first start of the run.
1422
+ return
1423
+
1424
+ new_run = copy.copy(self._current_run)
1425
+
1426
+ new_run.next_run = self._current_run.next_run
1427
+ self._current_run.next_run = new_run
1428
+
1429
+ splitPoint = textPosition - self._current_run.text_start
1430
+ new_run.text_start += splitPoint
1431
+ new_run.text_length -= splitPoint
1432
+
1433
+ self._current_run.text_length = splitPoint
1434
+ self._current_run = new_run
1435
+
1436
+ def FetchNextRun(self, textLength: UINT32) -> tuple[Run, int]:
1437
+ original_run = self._current_run
1438
+
1439
+ if (textLength < self._current_run.text_length):
1440
+ self.SplitCurrentRun(self._current_run.text_start + textLength)
1441
+ else:
1442
+ self._current_run = self._current_run.next_run
1443
+
1444
+ textLength -= original_run.text_length
1445
+
1446
+ return original_run, textLength
1447
+
1448
+
1449
+ class MyFontFileStream(com.COMObject):
1450
+ _interfaces_ = [IDWriteFontFileStream]
1451
+
1452
+ def __init__(self, data: bytes) -> None:
1453
+ super().__init__()
1454
+ self._data = data
1455
+ self._size = len(data)
1456
+ self._ptrs = []
1457
+
1458
+ def ReadFileFragment(self, fragmentStart: POINTER(c_void_p), fileOffset: UINT64, fragmentSize: UINT64,
1459
+ fragmentContext: POINTER(c_void_p)) -> int:
1460
+ if fileOffset + fragmentSize > self._size:
1461
+ return 0x80004005 # E_FAIL
1462
+
1463
+ fragment = self._data[fileOffset:]
1464
+ buffer = (ctypes.c_ubyte * len(fragment)).from_buffer(bytearray(fragment))
1465
+ ptr = ctypes.cast(buffer, c_void_p)
1466
+
1467
+ self._ptrs.append(ptr)
1468
+ fragmentStart[0] = ptr
1469
+ fragmentContext[0] = None
1470
+ return 0
1471
+
1472
+ def ReleaseFileFragment(self, fragmentContext: c_void_p) -> int:
1473
+ return 0
1474
+
1475
+ def GetFileSize(self, fileSize: POINTER(UINT64)) -> int:
1476
+ fileSize[0] = self._size
1477
+ return 0
1478
+
1479
+ def GetLastWriteTime(self, lastWriteTime: POINTER(UINT64)) -> int:
1480
+ return com.E_NOTIMPL
1481
+
1482
+
1483
+ class LegacyFontFileLoader(com.COMObject):
1484
+ _interfaces_ = [IDWriteFontFileLoader_LI]
1485
+
1486
+ def __init__(self) -> None:
1487
+ super().__init__()
1488
+ self._streams = {}
1489
+
1490
+ def CreateStreamFromKey(self, fontfileReferenceKey: c_void_p, fontFileReferenceKeySize: UINT32,
1491
+ fontFileStream: POINTER(IDWriteFontFileStream)) -> int:
1492
+ convert_index = cast(fontfileReferenceKey, POINTER(c_uint32))
1493
+
1494
+ self._ptr = cast(self._streams[convert_index.contents.value].as_interface(IDWriteFontFileStream),
1495
+ POINTER(IDWriteFontFileStream))
1496
+ fontFileStream[0] = self._ptr
1497
+ return 0
1498
+
1499
+ def SetCurrentFont(self, index: int, data: bytes) -> int:
1500
+ self._streams[index] = MyFontFileStream(data)
1501
+
1502
+
1503
+ class MyEnumerator(com.COMObject):
1504
+ _interfaces_ = [IDWriteFontFileEnumerator]
1505
+
1506
+ def __init__(self, factory: c_void_p, loader: LegacyFontFileLoader) -> None:
1507
+ super().__init__()
1508
+ self.factory = ctypes.cast(factory, IDWriteFactory)
1509
+ self.key = "pyglet_dwrite"
1510
+ self.size = len(self.key)
1511
+ self.current_index = -1
1512
+
1513
+ self._keys = []
1514
+ self._font_data = []
1515
+ self._font_files = []
1516
+ self._current_file = None
1517
+
1518
+ self._font_key_ref = create_unicode_buffer("none")
1519
+ self._font_key_len = len(self._font_key_ref)
1520
+
1521
+ self._file_loader = loader
1522
+
1523
+ def AddFontData(self, fonts: list[str]) -> None:
1524
+ self._font_data = fonts
1525
+
1526
+ def MoveNext(self, hasCurrentFile: BOOL) -> None:
1527
+ self.current_index += 1
1528
+ if self.current_index != len(self._font_data):
1529
+ font_file = IDWriteFontFile()
1530
+
1531
+ self._file_loader.SetCurrentFont(self.current_index, self._font_data[self.current_index])
1532
+
1533
+ key = self.current_index
1534
+
1535
+ if self.current_index not in self._keys:
1536
+ buffer = pointer(c_uint32(key))
1537
+
1538
+ ptr = cast(buffer, c_void_p)
1539
+
1540
+ self._keys.append(ptr)
1541
+
1542
+ self.factory.CreateCustomFontFileReference(self._keys[self.current_index],
1543
+ sizeof(buffer),
1544
+ self._file_loader,
1545
+ byref(font_file))
1546
+
1547
+ self._font_files.append(font_file)
1548
+
1549
+ hasCurrentFile[0] = 1
1550
+ else:
1551
+ hasCurrentFile[0] = 0
1552
+ else:
1553
+ hasCurrentFile[0] = 0
1554
+
1555
+ def GetCurrentFontFile(self, fontFile: IDWriteFontFile) -> int:
1556
+ fontFile = cast(fontFile, POINTER(IDWriteFontFile))
1557
+ fontFile[0] = self._font_files[self.current_index]
1558
+ return 0
1559
+
1560
+
1561
+ class LegacyCollectionLoader(com.COMObject):
1562
+ _interfaces_ = [IDWriteFontCollectionLoader]
1563
+
1564
+ def __init__(self, factory: c_void_p, loader: LegacyFontFileLoader) -> None:
1565
+ super().__init__()
1566
+ self._enumerator = MyEnumerator(factory, loader)
1567
+
1568
+ def AddFontData(self, fonts) -> None:
1569
+ self._enumerator.AddFontData(fonts)
1570
+
1571
+ def CreateEnumeratorFromKey(self, factory: IDWriteFactory, key: c_void_p, key_size: UINT32,
1572
+ enumerator: MyEnumerator) -> int:
1573
+ self._ptr = cast(self._enumerator.as_interface(IDWriteFontFileEnumerator),
1574
+ POINTER(IDWriteFontFileEnumerator))
1575
+
1576
+ enumerator[0] = self._ptr
1577
+ return 0