Compare commits
2 Commits
1a81df39eb
...
100c123bb9
Author | SHA1 | Date | |
---|---|---|---|
100c123bb9 | |||
d9bd54c90a |
@ -336,7 +336,7 @@ class GDIPlusGlyphRenderer(Win32GlyphRenderer):
|
||||
pass
|
||||
|
||||
def _create_bitmap(self, width, height):
|
||||
self._data = (ctypes.c_byte * (4 * width * height))()
|
||||
self._data = (BYTE * (4 * width * height))()
|
||||
self._bitmap = ctypes.c_void_p()
|
||||
self._format = PixelFormat32bppARGB
|
||||
gdiplus.GdipCreateBitmapFromScan0(width, height, width * 4,
|
||||
@ -532,6 +532,12 @@ class GDIPlusFont(Win32Font):
|
||||
self._name = name
|
||||
|
||||
family = ctypes.c_void_p()
|
||||
|
||||
# GDI will add @ in front of a localized font for some Asian languages. However, GDI will also not find it
|
||||
# based on that name (???). Here we remove it before checking font collections.
|
||||
if name[0] == "@":
|
||||
name = name[1:]
|
||||
|
||||
name = ctypes.c_wchar_p(name)
|
||||
|
||||
# Look in private collection first:
|
||||
@ -540,6 +546,9 @@ class GDIPlusFont(Win32Font):
|
||||
|
||||
# Then in system collection:
|
||||
if not family:
|
||||
if _debug_font:
|
||||
print(f"Warning: Font '{name}' was not found. Defaulting to: {self._default_name}")
|
||||
|
||||
gdiplus.GdipCreateFontFamilyFromName(name, None, ctypes.byref(family))
|
||||
|
||||
# Nothing found, use default font.
|
||||
|
@ -244,7 +244,7 @@ class Win32ARBContext(_BaseWin32Context):
|
||||
if self.config.forward_compatible:
|
||||
flags |= wglext_arb.WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB
|
||||
if self.config.debug:
|
||||
flags |= wglext_arb.WGL_DEBUG_BIT_ARB
|
||||
flags |= wglext_arb.WGL_CONTEXT_DEBUG_BIT_ARB
|
||||
if flags:
|
||||
attribs.extend([wglext_arb.WGL_CONTEXT_FLAGS_ARB, flags])
|
||||
attribs.append(0)
|
||||
|
@ -601,7 +601,7 @@ class WICEncoder(ImageEncoder):
|
||||
|
||||
frame.SetPixelFormat(byref(default_format))
|
||||
|
||||
data = (c_byte * size).from_buffer(bytearray(image_data))
|
||||
data = (BYTE * size).from_buffer(bytearray(image_data))
|
||||
|
||||
frame.WritePixels(image.height, pitch, size, data)
|
||||
|
||||
|
@ -113,8 +113,8 @@ ERROR_SUCCESS = 0
|
||||
class XINPUT_GAMEPAD(Structure):
|
||||
_fields_ = [
|
||||
('wButtons', WORD),
|
||||
('bLeftTrigger', UBYTE),
|
||||
('bRightTrigger', UBYTE),
|
||||
('bLeftTrigger', BYTE),
|
||||
('bRightTrigger', BYTE),
|
||||
('sThumbLX', SHORT),
|
||||
('sThumbLY', SHORT),
|
||||
('sThumbRX', SHORT),
|
||||
|
@ -1,4 +1,5 @@
|
||||
import ctypes
|
||||
import sys
|
||||
|
||||
from ctypes import *
|
||||
from ctypes.wintypes import *
|
||||
@ -45,7 +46,6 @@ def POINTER_(obj):
|
||||
|
||||
c_void_p = POINTER_(c_void)
|
||||
INT = c_int
|
||||
UBYTE = c_ubyte
|
||||
LPVOID = c_void_p
|
||||
HCURSOR = HANDLE
|
||||
LRESULT = LPARAM
|
||||
@ -62,6 +62,11 @@ HDROP = HANDLE
|
||||
LPTSTR = LPWSTR
|
||||
LPSTREAM = c_void_p
|
||||
|
||||
# Fixed in python 3.12. Is c_byte on other versions.
|
||||
# Ensure it's the same across all versions.
|
||||
if sys.version_info < (3, 12):
|
||||
BYTE = c_ubyte
|
||||
|
||||
LF_FACESIZE = 32
|
||||
CCHDEVICENAME = 32
|
||||
CCHFORMNAME = 32
|
||||
@ -572,6 +577,7 @@ class IStream(com.pIUnknown):
|
||||
com.STDMETHOD()),
|
||||
]
|
||||
|
||||
|
||||
class DEV_BROADCAST_HDR(Structure):
|
||||
_fields_ = (
|
||||
('dbch_size', DWORD),
|
||||
@ -579,6 +585,7 @@ class DEV_BROADCAST_HDR(Structure):
|
||||
('dbch_reserved', DWORD),
|
||||
)
|
||||
|
||||
|
||||
class DEV_BROADCAST_DEVICEINTERFACE(Structure):
|
||||
_fields_ = (
|
||||
('dbcc_size', DWORD),
|
||||
|
@ -5,12 +5,11 @@ such as Rectangles, Circles, and Lines. These shapes are made
|
||||
internally from OpenGL primitives, and provide excellent performance
|
||||
when drawn as part of a :py:class:`~pyglet.graphics.Batch`.
|
||||
Convenience methods are provided for positioning, changing color
|
||||
and opacity, and rotation (where applicable). To create more
|
||||
complex shapes than what is provided here, the lower level
|
||||
graphics API is more appropriate.
|
||||
You can also use the ``in`` operator to check whether a point is
|
||||
inside a shape.
|
||||
See the :ref:`guide_graphics` for more details.
|
||||
and opacity, and rotation (where applicable).
|
||||
The Python ``in`` operator to check whether a point is inside a shape.
|
||||
|
||||
To create more complex shapes than what is provided here, the lower level
|
||||
graphics API is more appropriate. See the :ref:`guide_graphics` for more details.
|
||||
|
||||
A simple example of drawing shapes::
|
||||
|
||||
@ -1466,6 +1465,122 @@ class BorderedRectangle(ShapeBase):
|
||||
self._update_color()
|
||||
|
||||
|
||||
class Box(ShapeBase):
|
||||
def __init__(self, x, y, width, height, thickness=1, color=(255, 255, 255, 255), batch=None, group=None):
|
||||
"""Create an unfilled rectangular shape, with optional thickness.
|
||||
|
||||
The box's anchor point defaults to the (x, y) coordinates,
|
||||
which are at the bottom left.
|
||||
Changing the thickness of the box will extend the walls inward;
|
||||
the outward dimesions will not be affected.
|
||||
|
||||
:Parameters:
|
||||
`x` : float
|
||||
The X coordinate of the box.
|
||||
`y` : float
|
||||
The Y coordinate of the box.
|
||||
`width` : float
|
||||
The width of the box.
|
||||
`height` : float
|
||||
The height of the box.
|
||||
`thickness` : float
|
||||
The thickness of the lines that make up the box.
|
||||
`color` : (int, int, int, int)
|
||||
The RGB or RGBA color of the box, specified as a tuple
|
||||
of 3 or 4 ints in the range of 0-255. RGB colors will
|
||||
be treated as having an opacity of 255.
|
||||
`batch` : `~pyglet.graphics.Batch`
|
||||
Optional batch to add the box to.
|
||||
`group` : `~pyglet.graphics.Group`
|
||||
Optional parent group of the box.
|
||||
"""
|
||||
self._x = x
|
||||
self._y = y
|
||||
self._width = width
|
||||
self._height = height
|
||||
self._thickness = thickness
|
||||
|
||||
self._num_verts = 8
|
||||
|
||||
r, g, b, *a = color
|
||||
self._rgba = r, g, b, a[0] if a else 255
|
||||
|
||||
program = get_default_shader()
|
||||
self._batch = batch or Batch()
|
||||
self._group = self.group_class(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, program, group)
|
||||
|
||||
self._create_vertex_list()
|
||||
self._update_vertices()
|
||||
|
||||
def __contains__(self, point):
|
||||
assert len(point) == 2
|
||||
point = _rotate_point((self._x, self._y), point, math.radians(self._rotation))
|
||||
x, y = self._x - self._anchor_x, self._y - self._anchor_y
|
||||
return x < point[0] < x + self._width and y < point[1] < y + self._height
|
||||
|
||||
def _create_vertex_list(self):
|
||||
# 3 6
|
||||
# 2 7
|
||||
# 1 4
|
||||
# 0 5
|
||||
indices = [0, 1, 2, 0, 2, 3, 0, 5, 4, 0, 4, 1, 4, 5, 6, 4, 6, 7, 2, 7, 6, 2, 6, 3]
|
||||
self._vertex_list = self._group.program.vertex_list_indexed(
|
||||
self._num_verts, self._draw_mode, indices, self._batch, self._group,
|
||||
colors=('Bn', self._rgba * self._num_verts),
|
||||
translation=('f', (self._x, self._y) * self._num_verts))
|
||||
|
||||
def _update_color(self):
|
||||
self._vertex_list.colors[:] = self._rgba * self._num_verts
|
||||
|
||||
def _update_vertices(self):
|
||||
if not self._visible:
|
||||
self._vertex_list.position[:] = (0, 0) * self._num_verts
|
||||
else:
|
||||
|
||||
t = self._thickness
|
||||
left = -self._anchor_x
|
||||
bottom = -self._anchor_y
|
||||
right = left + self._width
|
||||
top = bottom + self._height
|
||||
|
||||
x1 = left
|
||||
x2 = left + t
|
||||
x3 = right - t
|
||||
x4 = right
|
||||
y1 = bottom
|
||||
y2 = bottom + t
|
||||
y3 = top - t
|
||||
y4 = top
|
||||
# 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7
|
||||
self._vertex_list.position[:] = x1, y1, x2, y2, x2, y3, x1, y4, x3, y2, x4, y1, x4, y4, x3, y3
|
||||
|
||||
@property
|
||||
def width(self):
|
||||
"""The width of the Box.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self._width
|
||||
|
||||
@width.setter
|
||||
def width(self, value):
|
||||
self._width = value
|
||||
self._update_vertices()
|
||||
|
||||
@property
|
||||
def height(self):
|
||||
"""The height of the Box.
|
||||
|
||||
:type: float
|
||||
"""
|
||||
return self._height
|
||||
|
||||
@height.setter
|
||||
def height(self, value):
|
||||
self._height = value
|
||||
self._update_vertices()
|
||||
|
||||
|
||||
class Triangle(ShapeBase):
|
||||
def __init__(self, x, y, x2, y2, x3, y3, color=(255, 255, 255, 255),
|
||||
batch=None, group=None):
|
||||
@ -1776,4 +1891,5 @@ class Polygon(ShapeBase):
|
||||
self._vertex_list.position[:] = tuple(value for coordinate in triangles for value in coordinate)
|
||||
|
||||
|
||||
__all__ = 'Arc', 'BezierCurve', 'Circle', 'Ellipse', 'Line', 'Rectangle', 'BorderedRectangle', 'Triangle', 'Star', 'Polygon', 'Sector'
|
||||
__all__ = ('Arc', 'Box', 'BezierCurve', 'Circle', 'Ellipse', 'Line', 'Rectangle',
|
||||
'BorderedRectangle', 'Triangle', 'Star', 'Polygon', 'Sector', 'ShapeBase')
|
||||
|
Loading…
Reference in New Issue
Block a user