From 02d4cf2221062dedb08adb2e03c1a456008e210e Mon Sep 17 00:00:00 2001 From: shenjack <3695888@qq.com> Date: Mon, 29 Aug 2022 13:21:35 +0800 Subject: [PATCH] update pyglet --- libs/pyglet/sprite.py | 35 ++++++++++++---- libs/pyglet/text/__init__.py | 23 +++++++--- libs/pyglet/text/layout.py | 81 ++++++++++++++++++++++++++++++------ 3 files changed, 112 insertions(+), 27 deletions(-) diff --git a/libs/pyglet/sprite.py b/libs/pyglet/sprite.py index 2c365bf..7e388d4 100644 --- a/libs/pyglet/sprite.py +++ b/libs/pyglet/sprite.py @@ -651,24 +651,41 @@ class Sprite(event.EventDispatcher): `scale_y` : float Vertical scaling factor. """ - if x: + + translations_outdated = False + + # only bother updating if the translation actually changed + if x is not None: self._x = x - if y: + translations_outdated = True + if y is not None: self._y = y - if z: + translations_outdated = True + if z is not None: self._z = z - if x or y or z: + translations_outdated = True + + if translations_outdated: self._vertex_list.translate[:] = (self._x, self._y, self._z) * 4 - if rotation: + + if rotation is not None and rotation != self._rotation: self._rotation = rotation self._vertex_list.rotation[:] = (rotation,) * 4 - if scale: + + scales_outdated = False + + # only bother updating if the scale actually changed + if scale is not None: self._scale = scale - if scale_x: + scales_outdated = True + if scale_x is not None: self._scale_x = scale_x - if scale_y: + scales_outdated = True + if scale_y is not None: self._scale_y = scale_y - if scale or scale_x or scale_y: + scales_outdated = True + + if scales_outdated: self._vertex_list.scale[:] = (self._scale * self._scale_x, self._scale * self._scale_y) * 4 @property diff --git a/libs/pyglet/text/__init__.py b/libs/pyglet/text/__init__.py index 8271a02..18bfe34 100644 --- a/libs/pyglet/text/__init__.py +++ b/libs/pyglet/text/__init__.py @@ -236,7 +236,7 @@ class DocumentLabel(layout.TextLayout): def __init__(self, document=None, x=0, y=0, width=None, height=None, anchor_x='left', anchor_y='baseline', - multiline=False, dpi=None, batch=None, group=None): + multiline=False, dpi=None, batch=None, group=None, rotation=0): """Create a label for a given document. :Parameters: @@ -265,11 +265,16 @@ class DocumentLabel(layout.TextLayout): Optional graphics batch to add the label to. `group` : `~pyglet.graphics.Group` Optional graphics group to use. + `rotation`: float + The amount to rotate the label in degrees. A positive amount + will be a clockwise rotation, negative values will result in + counter-clockwise rotation. """ super().__init__(document, width, height, multiline, dpi, batch, group) self._x = x self._y = y + self._rotation = rotation self._anchor_x = anchor_x self._anchor_y = anchor_y self._update() @@ -413,7 +418,7 @@ class Label(DocumentLabel): x=0, y=0, width=None, height=None, anchor_x='left', anchor_y='baseline', align='left', - multiline=False, dpi=None, batch=None, group=None): + multiline=False, dpi=None, batch=None, group=None, rotation=0): """Create a plain text label. :Parameters: @@ -459,10 +464,14 @@ class Label(DocumentLabel): Optional graphics batch to add the label to. `group` : `~pyglet.graphics.Group` Optional graphics group to use. + `rotation`: float + The amount to rotate the label in degrees. A positive amount + will be a clockwise rotation, negative values will result in + counter-clockwise rotation. """ doc = decode_text(text) - super().__init__(doc, x, y, width, height, anchor_x, anchor_y, multiline, dpi, batch, group) + super().__init__(doc, x, y, width, height, anchor_x, anchor_y, multiline, dpi, batch, group, rotation) self.document.set_style(0, len(self.document.text), { 'font_name': font_name, @@ -485,7 +494,7 @@ class HTMLLabel(DocumentLabel): def __init__(self, text='', location=None, x=0, y=0, width=None, height=None, anchor_x='left', anchor_y='baseline', - multiline=False, dpi=None, batch=None, group=None): + multiline=False, dpi=None, batch=None, group=None, rotation=0): """Create a label with an HTML string. :Parameters: @@ -517,12 +526,16 @@ class HTMLLabel(DocumentLabel): Optional graphics batch to add the label to. `group` : `~pyglet.graphics.Group` Optional graphics group to use. + `rotation`: float + The amount to rotate the label in degrees. A positive amount + will be a clockwise rotation, negative values will result in + counter-clockwise rotation. """ self._text = text self._location = location doc = decode_html(text, location) - super().__init__(doc, x, y, width, height, anchor_x, anchor_y, multiline, dpi, batch, group) + super().__init__(doc, x, y, width, height, anchor_x, anchor_y, multiline, dpi, batch, group, rotation) @property def text(self): diff --git a/libs/pyglet/text/layout.py b/libs/pyglet/text/layout.py index b2c4e43..de9a64b 100644 --- a/libs/pyglet/text/layout.py +++ b/libs/pyglet/text/layout.py @@ -285,7 +285,7 @@ class _AbstractBox: self.advance = advance self.length = length - def place(self, layout, i, x, y, context): + def place(self, layout, i, x, y, rotation, anchor_x, anchor_y, context): raise NotImplementedError('abstract') def delete(self, layout): @@ -322,7 +322,7 @@ class _GlyphBox(_AbstractBox): self.glyphs = glyphs self.advance = advance - def place(self, layout, i, x, y, context): + def place(self, layout, i, x, y, rotation, anchor_x, anchor_y, context): assert self.glyphs program = get_default_layout_shader() @@ -369,7 +369,9 @@ class _GlyphBox(_AbstractBox): vertex_list = program.vertex_list_indexed(n_glyphs * 4, GL_TRIANGLES, indices, layout.batch, group, position=('f', vertices), colors=('Bn', colors), - tex_coords=('f', tex_coords)) + tex_coords=('f', tex_coords), + rotation=('f', ((rotation,) * 4) * n_glyphs), + anchor=('f', ((anchor_x, anchor_y) * 4) * n_glyphs)) context.add_list(vertex_list) @@ -419,7 +421,9 @@ class _GlyphBox(_AbstractBox): background_list = decoration_program.vertex_list_indexed(bg_count * 4, GL_TRIANGLES, background_indices, layout.batch, layout.background_decoration_group, position=('f', background_vertices), - colors=('Bn', background_colors)) + colors=('Bn', background_colors), + rotation=('f', (rotation,) * 4), + anchor=('f', (anchor_x, anchor_y) * 4)) context.add_list(background_list) if underline_vertices: @@ -427,7 +431,9 @@ class _GlyphBox(_AbstractBox): underline_list = decoration_program.vertex_list(len(underline_vertices) // 2, GL_LINES, layout.batch, layout.foreground_decoration_group, position=('f',underline_vertices), - colors=('Bn', underline_colors)) + colors=('Bn', underline_colors), + rotation=('f', (rotation,) * 4), + anchor=('f', (anchor_x, anchor_y) * 4)) context.add_list(underline_list) def delete(self, layout): @@ -465,7 +471,7 @@ class _InlineElementBox(_AbstractBox): self.element = element self.placed = False - def place(self, layout, i, x, y, context): + def place(self, layout, i, x, y, rotation, anchor_x, anchor_y, context): self.element.place(layout, x, y) self.placed = True context.add_box(self) @@ -537,6 +543,8 @@ layout_vertex_source = """#version 330 core in vec4 colors; in vec3 tex_coords; in vec2 translation; + in vec2 anchor; + in float rotation; out vec4 text_colors; out vec2 texture_coords; @@ -548,9 +556,22 @@ layout_vertex_source = """#version 330 core mat4 view; } window; + mat4 m_rotation = mat4(1.0); + mat4 m_anchor = mat4(1.0); + mat4 m_neganchor = mat4(1.0); + void main() { - gl_Position = window.projection * window.view * vec4(position + translation, 0.0, 1.0); + m_anchor[3][0] = anchor.x; + m_anchor[3][1] = anchor.y; + m_neganchor[3][0] = -anchor.x; + m_neganchor[3][1] = -anchor.y; + m_rotation[0][0] = cos(-radians(rotation)); + m_rotation[0][1] = sin(-radians(rotation)); + m_rotation[1][0] = -sin(-radians(rotation)); + m_rotation[1][1] = cos(-radians(rotation)); + + gl_Position = window.projection * window.view * m_anchor * m_rotation * m_neganchor * vec4(position + translation, 0.0, 1.0); vert_position = vec4(position + translation, 0.0, 1.0); text_colors = colors; @@ -585,6 +606,8 @@ decoration_vertex_source = """#version 330 core in vec2 position; in vec4 colors; in vec2 translation; + in vec2 anchor; + in float rotation; out vec4 vert_colors; out vec4 vert_position; @@ -595,9 +618,22 @@ decoration_vertex_source = """#version 330 core mat4 view; } window; + mat4 m_rotation = mat4(1.0); + mat4 m_anchor = mat4(1.0); + mat4 m_neganchor = mat4(1.0); + void main() { - gl_Position = window.projection * window.view * vec4(position + translation, 0.0, 1.0); + m_anchor[3][0] = anchor.x; + m_anchor[3][1] = anchor.y; + m_neganchor[3][0] = -anchor.x; + m_neganchor[3][1] = -anchor.y; + m_rotation[0][0] = cos(-radians(rotation)); + m_rotation[0][1] = sin(-radians(rotation)); + m_rotation[1][0] = -sin(-radians(rotation)); + m_rotation[1][1] = cos(-radians(rotation)); + + gl_Position = window.projection * window.view * m_anchor * m_rotation * m_neganchor * vec4(position + translation, 0.0, 1.0); vert_position = vec4(position + translation, 0.0, 1.0); vert_colors = colors; @@ -789,6 +825,7 @@ class ScrollableTextDecorationGroup(graphics.Group): def __hash__(self): return id(self) + class IncrementalTextDecorationGroup(ScrollableTextDecorationGroup): # Subclass so that the scissor_area isn't shared with the # ScrollableTextDecorationGroup. We use a class variable here so @@ -839,6 +876,7 @@ class TextLayout: _x = 0 _y = 0 + _rotation = 0 _width = None _height = None _anchor_x = 'left' @@ -1023,6 +1061,22 @@ class TextLayout: vertex_list.position[:] = vertices self._y = y + @property + def rotation(self): + """Rotation of the layout. + + :type: float + """ + return self._rotation + + @rotation.setter + def rotation(self, rotation): + self._set_rotation(rotation) + + def _set_rotation(self, rotation): + self._rotation = rotation + self._update() + @property def position(self): """The (X, Y) coordinates of the layout, as a tuple. @@ -1774,7 +1828,7 @@ class TextLayout: def _create_vertex_lists(self, x, y, i, boxes, context): for box in boxes: - box.place(self, i, x, y, context) + box.place(self, i, x, y, self._rotation, self._x, self._y, context) x += box.advance i += box.length @@ -2058,10 +2112,6 @@ class IncrementalTextLayout(TextLayout, EventDispatcher): self._update_visible_lines() self._update_vertex_lists() - # Reclamp view_y in case content height has changed and reset top of content. - # self.view_y = self._translate_y - # self._update_translation() - if trigger_update_event: self.dispatch_event('on_layout_update') @@ -2348,6 +2398,11 @@ class IncrementalTextLayout(TextLayout, EventDispatcher): self._wrap_lines_invariant() self._update() + def _set_rotation(self, rotation): + self._rotation = rotation + self.invalid_flow.invalidate(0, len(self.document.text)) + self._update() + # Offset of content within viewport def _update_translation(self):