DR -> DR SDK #16
@ -3,7 +3,6 @@ from .base import Display, Screen, ScreenMode, Canvas
|
|||||||
from pyglet.libs.win32 import _user32
|
from pyglet.libs.win32 import _user32
|
||||||
from pyglet.libs.win32.constants import *
|
from pyglet.libs.win32.constants import *
|
||||||
from pyglet.libs.win32.types import *
|
from pyglet.libs.win32.types import *
|
||||||
from pyglet.libs.win32.context_managers import device_context
|
|
||||||
|
|
||||||
|
|
||||||
class Win32Display(Display):
|
class Win32Display(Display):
|
||||||
@ -31,13 +30,13 @@ class Win32Screen(Screen):
|
|||||||
self._handle = handle
|
self._handle = handle
|
||||||
|
|
||||||
def get_matching_configs(self, template):
|
def get_matching_configs(self, template):
|
||||||
with device_context(None) as hdc:
|
hdc = _user32.GetDC(0)
|
||||||
canvas = Win32Canvas(self.display, 0, hdc)
|
canvas = Win32Canvas(self.display, 0, hdc)
|
||||||
configs = template.match(canvas)
|
configs = template.match(canvas)
|
||||||
# XXX deprecate config's being screen-specific
|
# XXX deprecate config's being screen-specific
|
||||||
for config in configs:
|
for config in configs:
|
||||||
config.screen = self
|
config.screen = self
|
||||||
|
_user32.ReleaseDC(0, hdc)
|
||||||
return configs
|
return configs
|
||||||
|
|
||||||
def get_device_name(self):
|
def get_device_name(self):
|
||||||
|
@ -9,7 +9,6 @@ from pyglet.font import base
|
|||||||
from pyglet.font import win32query
|
from pyglet.font import win32query
|
||||||
import pyglet.image
|
import pyglet.image
|
||||||
from pyglet.libs.win32.constants import *
|
from pyglet.libs.win32.constants import *
|
||||||
from pyglet.libs.win32.context_managers import device_context
|
|
||||||
from pyglet.libs.win32.types import *
|
from pyglet.libs.win32.types import *
|
||||||
from pyglet.libs.win32 import _gdi32 as gdi32, _user32 as user32
|
from pyglet.libs.win32 import _gdi32 as gdi32, _user32 as user32
|
||||||
from pyglet.libs.win32 import _kernel32 as kernel32
|
from pyglet.libs.win32 import _kernel32 as kernel32
|
||||||
@ -196,13 +195,14 @@ class Win32Font(base.Font):
|
|||||||
self.hfont = gdi32.CreateFontIndirectW(byref(self.logfont))
|
self.hfont = gdi32.CreateFontIndirectW(byref(self.logfont))
|
||||||
|
|
||||||
# Create a dummy DC for coordinate mapping
|
# Create a dummy DC for coordinate mapping
|
||||||
with device_context(None) as dc:
|
dc = user32.GetDC(0)
|
||||||
metrics = TEXTMETRIC()
|
metrics = TEXTMETRIC()
|
||||||
gdi32.SelectObject(dc, self.hfont)
|
gdi32.SelectObject(dc, self.hfont)
|
||||||
gdi32.GetTextMetricsA(dc, byref(metrics))
|
gdi32.GetTextMetricsA(dc, byref(metrics))
|
||||||
self.ascent = metrics.tmAscent
|
self.ascent = metrics.tmAscent
|
||||||
self.descent = -metrics.tmDescent
|
self.descent = -metrics.tmDescent
|
||||||
self.max_glyph_width = metrics.tmMaxCharWidth
|
self.max_glyph_width = metrics.tmMaxCharWidth
|
||||||
|
user32.ReleaseDC(0, dc)
|
||||||
|
|
||||||
def __del__(self):
|
def __del__(self):
|
||||||
gdi32.DeleteObject(self.hfont)
|
gdi32.DeleteObject(self.hfont)
|
||||||
@ -210,22 +210,22 @@ class Win32Font(base.Font):
|
|||||||
@staticmethod
|
@staticmethod
|
||||||
def get_logfont(name, size, bold, italic, dpi):
|
def get_logfont(name, size, bold, italic, dpi):
|
||||||
# Create a dummy DC for coordinate mapping
|
# Create a dummy DC for coordinate mapping
|
||||||
with device_context(None) as dc:
|
dc = user32.GetDC(0)
|
||||||
if dpi is None:
|
if dpi is None:
|
||||||
dpi = 96
|
dpi = 96
|
||||||
logpixelsy = dpi
|
logpixelsy = dpi
|
||||||
|
|
||||||
logfont = LOGFONTW()
|
|
||||||
# Conversion of point size to device pixels
|
|
||||||
logfont.lfHeight = int(-size * logpixelsy // 72)
|
|
||||||
if bold:
|
|
||||||
logfont.lfWeight = FW_BOLD
|
|
||||||
else:
|
|
||||||
logfont.lfWeight = FW_NORMAL
|
|
||||||
logfont.lfItalic = italic
|
|
||||||
logfont.lfFaceName = name
|
|
||||||
logfont.lfQuality = ANTIALIASED_QUALITY
|
|
||||||
|
|
||||||
|
logfont = LOGFONTW()
|
||||||
|
# Conversion of point size to device pixels
|
||||||
|
logfont.lfHeight = int(-size * logpixelsy // 72)
|
||||||
|
if bold:
|
||||||
|
logfont.lfWeight = FW_BOLD
|
||||||
|
else:
|
||||||
|
logfont.lfWeight = FW_NORMAL
|
||||||
|
logfont.lfItalic = italic
|
||||||
|
logfont.lfFaceName = name
|
||||||
|
logfont.lfQuality = ANTIALIASED_QUALITY
|
||||||
|
user32.ReleaseDC(0, dc)
|
||||||
return logfont
|
return logfont
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
|
@ -71,7 +71,6 @@ appropriate typeface name and create the font using CreateFont or
|
|||||||
CreateFontIndirect.
|
CreateFontIndirect.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
from pyglet.libs.win32.context_managers import device_context
|
|
||||||
|
|
||||||
DEBUG = False
|
DEBUG = False
|
||||||
|
|
||||||
@ -386,33 +385,36 @@ def query(charset=DEFAULT_CHARSET):
|
|||||||
global FONTDB
|
global FONTDB
|
||||||
|
|
||||||
# 1. Get device context of the entire screen
|
# 1. Get device context of the entire screen
|
||||||
with device_context(None) as hdc:
|
hdc = user32.GetDC(None)
|
||||||
|
|
||||||
# 2. Call EnumFontFamiliesExA (ANSI version)
|
# 2. Call EnumFontFamiliesExA (ANSI version)
|
||||||
|
|
||||||
# 2a. Call with empty font name to query all available fonts
|
# 2a. Call with empty font name to query all available fonts
|
||||||
# (or fonts for the specified charset)
|
# (or fonts for the specified charset)
|
||||||
#
|
#
|
||||||
# NOTES:
|
# NOTES:
|
||||||
#
|
#
|
||||||
# * there are fonts that don't support ANSI charset
|
# * there are fonts that don't support ANSI charset
|
||||||
# * for DEFAULT_CHARSET font is passed to callback function as
|
# * for DEFAULT_CHARSET font is passed to callback function as
|
||||||
# many times as charsets it supports
|
# many times as charsets it supports
|
||||||
|
|
||||||
# [ ] font name should be less than 32 symbols with terminating \0
|
# [ ] font name should be less than 32 symbols with terminating \0
|
||||||
# [ ] check double purpose - enumerate all available font names
|
# [ ] check double purpose - enumerate all available font names
|
||||||
# - enumerate all available charsets for a single font
|
# - enumerate all available charsets for a single font
|
||||||
# - other params?
|
# - other params?
|
||||||
|
|
||||||
logfont = LOGFONTW(0, 0, 0, 0, 0, 0, 0, 0, charset, 0, 0, 0, 0, '')
|
logfont = LOGFONTW(0, 0, 0, 0, 0, 0, 0, 0, charset, 0, 0, 0, 0, '')
|
||||||
FONTDB = [] # clear cached FONTDB for enum_font_names callback
|
FONTDB = [] # clear cached FONTDB for enum_font_names callback
|
||||||
res = gdi32.EnumFontFamiliesExW(
|
res = gdi32.EnumFontFamiliesExW(
|
||||||
hdc, # handle to device context
|
hdc, # handle to device context
|
||||||
ctypes.byref(logfont),
|
ctypes.byref(logfont),
|
||||||
enum_font_names, # pointer to callback function
|
enum_font_names, # pointer to callback function
|
||||||
0, # lParam - application-supplied data
|
0, # lParam - application-supplied data
|
||||||
0) # dwFlags - reserved = 0
|
0) # dwFlags - reserved = 0
|
||||||
# res here is the last value returned by callback function
|
# res here is the last value returned by callback function
|
||||||
|
|
||||||
|
# 3. Release DC
|
||||||
|
user32.ReleaseDC(None, hdc)
|
||||||
|
|
||||||
return FONTDB
|
return FONTDB
|
||||||
|
|
||||||
|
@ -1,57 +0,0 @@
|
|||||||
"""
|
|
||||||
Win32 resources as handy context managers.
|
|
||||||
|
|
||||||
These are intended to help keep loader code clean & stable at the price
|
|
||||||
of a tiny bit of execution speed. Performance-critical code should avoid
|
|
||||||
using these helpers in favor of direct win32 API calls.
|
|
||||||
|
|
||||||
Before::
|
|
||||||
|
|
||||||
def loader_function(arg):
|
|
||||||
context_handle = user32.GetResource(None)
|
|
||||||
|
|
||||||
result = calculation(arg)
|
|
||||||
|
|
||||||
# Easily forgotten!
|
|
||||||
user32.ReleaseResource(context_handle)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
After::
|
|
||||||
|
|
||||||
def loader_function(arg):
|
|
||||||
|
|
||||||
with resource_context() as context_handle:
|
|
||||||
result = calculation(arg)
|
|
||||||
|
|
||||||
return result
|
|
||||||
|
|
||||||
"""
|
|
||||||
from contextlib import contextmanager
|
|
||||||
from typing import Optional, Generator
|
|
||||||
from ctypes.wintypes import HANDLE
|
|
||||||
from ctypes import WinError
|
|
||||||
from pyglet.libs.win32 import _user32 as user32
|
|
||||||
|
|
||||||
|
|
||||||
@contextmanager
|
|
||||||
def device_context(window_handle: Optional[int] = None) -> Generator[HANDLE, None, None]:
|
|
||||||
"""
|
|
||||||
A Windows device context wrapped as a context manager.
|
|
||||||
|
|
||||||
Args:
|
|
||||||
window_handle: A specific window handle to use, if any.
|
|
||||||
Raises:
|
|
||||||
WinError: Raises if a device context cannot be acquired or released
|
|
||||||
Yields:
|
|
||||||
HANDLE: the managed drawing context handle to auto-close.
|
|
||||||
|
|
||||||
"""
|
|
||||||
if not (_dc := user32.GetDC(window_handle)):
|
|
||||||
raise WinError()
|
|
||||||
|
|
||||||
try:
|
|
||||||
yield _dc
|
|
||||||
finally:
|
|
||||||
if not user32.ReleaseDC(None, _dc):
|
|
||||||
raise WinError()
|
|
Loading…
Reference in New Issue
Block a user