From 06e72b5d7dfe46917a342b031a0f61a63d1ecc6f Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 27 Mar 2024 10:06:39 +0100 Subject: [PATCH 1/8] text: Add docstring for `set_text_color()` Fixes #1621 --- panda/src/text/textNode.I | 8 ++++++-- panda/src/text/textProperties.I | 10 +++++++--- 2 files changed, 13 insertions(+), 5 deletions(-) diff --git a/panda/src/text/textNode.I b/panda/src/text/textNode.I index 1d02442451..6d54f95b54 100644 --- a/panda/src/text/textNode.I +++ b/panda/src/text/textNode.I @@ -804,7 +804,9 @@ clear_wordwrap() { } /** - * + * Sets the color of the text. Note that this will modulate the color of all + * components of the text, including the shadow and outline. If you wish to + * only set the foreground color, see DynamicTextFont::set_fg(). */ INLINE void TextNode:: set_text_color(const LColor &text_color) { @@ -814,7 +816,9 @@ set_text_color(const LColor &text_color) { } /** - * + * Sets the color of the text. Note that this will modulate the color of all + * components of the text, including the shadow and outline. If you wish to + * only set the foreground color, see DynamicTextFont::set_fg(). */ INLINE void TextNode:: set_text_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a) { diff --git a/panda/src/text/textProperties.I b/panda/src/text/textProperties.I index d56c354d46..c31cd883de 100644 --- a/panda/src/text/textProperties.I +++ b/panda/src/text/textProperties.I @@ -419,7 +419,9 @@ get_preserve_trailing_whitespace() const { } /** - * + * Sets the color of the text. Note that this will modulate the color of all + * components of the text, including the shadow and outline. If you wish to + * only set the foreground color, see DynamicTextFont::set_fg(). */ INLINE void TextProperties:: set_text_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a) { @@ -427,7 +429,9 @@ set_text_color(PN_stdfloat r, PN_stdfloat g, PN_stdfloat b, PN_stdfloat a) { } /** - * + * Sets the color of the text. Note that this will modulate the color of all + * components of the text, including the shadow and outline. If you wish to + * only set the foreground color, see DynamicTextFont::set_fg(). */ INLINE void TextProperties:: set_text_color(const LColor &text_color) { @@ -448,7 +452,7 @@ clear_text_color() { } /** - * + * Returns true if a text color was specified with set_text_color(). */ INLINE bool TextProperties:: has_text_color() const { From 8ea2301d16c15b7878393ea6006b4d00fcb78b1e Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 27 Mar 2024 10:22:54 +0100 Subject: [PATCH 2/8] pgui: Fix PGEntry::get_cursor_Y() It returned the Y position, which is always 0.0, instead of the Z position. Fixes #1633 --- panda/src/pgui/pgEntry.I | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/panda/src/pgui/pgEntry.I b/panda/src/pgui/pgEntry.I index e758a7ff8c..61262d87aa 100644 --- a/panda/src/pgui/pgEntry.I +++ b/panda/src/pgui/pgEntry.I @@ -134,7 +134,6 @@ get_cursor_position() const { /** * Returns the node position x of the cursor */ - INLINE PN_stdfloat PGEntry:: get_cursor_X() const { LightReMutexHolder holder(_lock); @@ -144,14 +143,12 @@ get_cursor_X() const { /** * Returns the node position y of the cursor */ - INLINE PN_stdfloat PGEntry:: get_cursor_Y() const { LightReMutexHolder holder(_lock); - return _cursor_def.get_y(); + return _cursor_def.get_z(); } - /** * Sets the maximum number of characters that may be typed into the entry. * This is a limit on the number of characters, as opposed to the width of the From 237d27dfd9094596ea5931d8791a05094a0cbd54 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 27 Mar 2024 10:58:35 +0100 Subject: [PATCH 3/8] text: Error instead of crash when glyph does not fit into page Fixes #1626 --- panda/src/text/dynamicTextFont.cxx | 34 +++++++++++++++++++++++------- 1 file changed, 26 insertions(+), 8 deletions(-) diff --git a/panda/src/text/dynamicTextFont.cxx b/panda/src/text/dynamicTextFont.cxx index 347841a92f..4d933619b5 100644 --- a/panda/src/text/dynamicTextFont.cxx +++ b/panda/src/text/dynamicTextFont.cxx @@ -621,6 +621,9 @@ make_glyph(int character, FT_Face face, int glyph_index) { render_distance_field(image, outline, bounds.xMin, bounds.yMin); glyph = slot_glyph(character, int_x_size, int_y_size, advance); + if (glyph == nullptr) { + return nullptr; + } if (!_needs_image_processing) { copy_pnmimage_to_texture(image, glyph); } else { @@ -633,6 +636,9 @@ make_glyph(int character, FT_Face face, int glyph_index) { // other processing before it goes to the texture, we can just copy it // directly into the texture. glyph = slot_glyph(character, bitmap.width, bitmap.rows, advance); + if (glyph == nullptr) { + return nullptr; + } copy_bitmap_to_texture(bitmap, glyph); } else { @@ -660,6 +666,9 @@ make_glyph(int character, FT_Face face, int glyph_index) { tex_x_size += outline * 2; tex_y_size += outline * 2; glyph = slot_glyph(character, int_x_size, int_y_size, advance); + if (glyph == nullptr) { + return nullptr; + } if (outline != 0) { // Pad the glyph image to make room for the outline. @@ -940,10 +949,7 @@ slot_glyph(int character, int x_size, int y_size, PN_stdfloat advance) { if (page->is_empty()) { // If we couldn't even put it on an empty page, we're screwed. - text_cat.error() - << "Glyph of size " << x_size << " by " << y_size - << " pixels won't fit on an empty page.\n"; - return nullptr; + goto does_not_fit; } pi = (pi + 1) % _pages.size(); @@ -954,15 +960,27 @@ slot_glyph(int character, int x_size, int y_size, PN_stdfloat advance) { if (garbage_collect() != 0) { // Yes, we just freed up some space. Try once more, recursively. return slot_glyph(character, x_size, y_size, advance); + } - } else { - // No good; all recorded glyphs are actually in use. We need to make a - // new page. + // No good; all recorded glyphs are actually in use. We need to make a new + // page. + { _preferred_page = _pages.size(); PT(DynamicTextPage) page = new DynamicTextPage(this, _preferred_page); _pages.push_back(page); - return page->slot_glyph(character, x_size, y_size, _texture_margin, advance); + + DynamicTextGlyph *glyph = page->slot_glyph(character, x_size, y_size, _texture_margin, advance); + if (glyph != nullptr) { + return glyph; + } } + +does_not_fit: + // If you get this error, increase text-page-size in Config.prc. + text_cat.error() + << "Glyph of size " << x_size << " by " << y_size + << " pixels won't fit on an empty page.\n"; + return nullptr; } /** From a50b9d83aaf5cbe9968497c0f7acbabe4e9fec92 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 27 Mar 2024 11:06:34 +0100 Subject: [PATCH 4/8] interval: Fix creating LerpFunctionInterval from partial Fixes #1623 --- direct/src/interval/LerpInterval.py | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/direct/src/interval/LerpInterval.py b/direct/src/interval/LerpInterval.py index 24435ae084..b65b3750ca 100644 --- a/direct/src/interval/LerpInterval.py +++ b/direct/src/interval/LerpInterval.py @@ -821,9 +821,13 @@ class LerpFunctionInterval(Interval.Interval): self.blendType = LerpBlendHelpers.getBlend(blendType) self.extraArgs = extraArgs # Generate unique name if necessary - if (name == None): + if name is None: + if hasattr(function, '__name__'): + name = function.__name__ + else: + name = '<' + function.__class__.__name__ + '>' name = ('LerpFunctionInterval-%s-%d' % - (function.__name__, + (name, LerpFunctionInterval.lerpFunctionIntervalNum)) LerpFunctionInterval.lerpFunctionIntervalNum += 1 else: From aa58b4ccf22a766217d6ddf2e96de1178a2f241a Mon Sep 17 00:00:00 2001 From: kamgha Date: Fri, 22 Mar 2024 16:09:27 +0100 Subject: [PATCH 5/8] palettizer: Fix magfilter on KW_mipmap Closes #1631 --- pandatool/src/palettizer/txaLine.cxx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pandatool/src/palettizer/txaLine.cxx b/pandatool/src/palettizer/txaLine.cxx index 41f9349c51..913ca456ab 100644 --- a/pandatool/src/palettizer/txaLine.cxx +++ b/pandatool/src/palettizer/txaLine.cxx @@ -492,7 +492,7 @@ match_texture(TextureImage *texture) const { case KW_mipmap: request._minfilter = EggTexture::FT_linear_mipmap_linear; - request._magfilter = EggTexture::FT_linear_mipmap_linear; + request._magfilter = EggTexture::FT_linear; break; case KW_anisotropic: From 1f41edd0a035f70b81692908a0d24524461de49c Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 27 Mar 2024 11:23:17 +0100 Subject: [PATCH 6/8] dist: Remove panda3d dependency for global dist hook Fixes #1624 --- direct/src/dist/_dist_hooks.py | 16 ++++++++++++++++ direct/src/dist/commands.py | 12 +----------- 2 files changed, 17 insertions(+), 11 deletions(-) create mode 100644 direct/src/dist/_dist_hooks.py diff --git a/direct/src/dist/_dist_hooks.py b/direct/src/dist/_dist_hooks.py new file mode 100644 index 0000000000..a611c35dbc --- /dev/null +++ b/direct/src/dist/_dist_hooks.py @@ -0,0 +1,16 @@ +# This module should not import Panda3D modules globally as it contains hooks +# that may be invoked by setuptools even when Panda3D is not used. If the +# Panda3D installation is broken, it should not affect other applications. + +__all__ = ('finalize_distribution_options', ) + + +def finalize_distribution_options(dist): + """Entry point for compatibility with setuptools>=61, see #1394.""" + + options = dist.get_option_dict('build_apps') + if options.get('gui_apps') or options.get('console_apps'): + # Make sure this is set to avoid auto-discovery taking place. + if getattr(dist.metadata, 'py_modules', None) is None and \ + getattr(dist.metadata, 'packages', None) is None: + dist.py_modules = [] diff --git a/direct/src/dist/commands.py b/direct/src/dist/commands.py index 9cc7ce455f..94ab191d0b 100644 --- a/direct/src/dist/commands.py +++ b/direct/src/dist/commands.py @@ -25,6 +25,7 @@ import distutils.log from . import FreezeTool from . import pefile from .icon import Icon +from ._dist_hooks import finalize_distribution_options import panda3d.core as p3d @@ -1765,14 +1766,3 @@ class bdist_apps(setuptools.Command): else: self.announce('\tUnknown installer: {}'.format(installer), distutils.log.ERROR) - - -def finalize_distribution_options(dist): - """Entry point for compatibility with setuptools>=61, see #1394.""" - - options = dist.get_option_dict('build_apps') - if options.get('gui_apps') or options.get('console_apps'): - # Make sure this is set to avoid auto-discovery taking place. - if getattr(dist.metadata, 'py_modules', None) is None and \ - getattr(dist.metadata, 'packages', None) is None: - dist.py_modules = [] From d44f9ae3dc2dd87abb8a920a0fadaa4b10be9459 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 27 Mar 2024 12:01:09 +0100 Subject: [PATCH 7/8] makepanda: Use new dist hooks location introduced by 1f41edd Fixes #1624 --- makepanda/makepanda.py | 2 +- makepanda/makewheel.py | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/makepanda/makepanda.py b/makepanda/makepanda.py index 83e56ec6f2..d9e157d79a 100755 --- a/makepanda/makepanda.py +++ b/makepanda/makepanda.py @@ -3285,7 +3285,7 @@ build_apps = direct.dist.commands:build_apps bdist_apps = direct.dist.commands:bdist_apps [setuptools.finalize_distribution_options] -build_apps = direct.dist.commands:finalize_distribution_options +build_apps = direct.dist._dist_hooks:finalize_distribution_options """ if not PkgSkip("DIRECT"): diff --git a/makepanda/makewheel.py b/makepanda/makewheel.py index 55a48f62cf..880fa277e6 100644 --- a/makepanda/makewheel.py +++ b/makepanda/makewheel.py @@ -768,7 +768,7 @@ __version__ = '{0}' entry_points += 'build_apps = direct.dist.commands:build_apps\n' entry_points += 'bdist_apps = direct.dist.commands:bdist_apps\n' entry_points += '[setuptools.finalize_distribution_options]\n' - entry_points += 'build_apps = direct.dist.commands:finalize_distribution_options\n' + entry_points += 'build_apps = direct.dist._dist_hooks:finalize_distribution_options\n' whl.write_file_data('panda3d_tools/__init__.py', PANDA3D_TOOLS_INIT.format(tools_init)) From 0e2a706ec81950b42b69a7596f8b93b998dcc7d2 Mon Sep 17 00:00:00 2001 From: rdb Date: Wed, 27 Mar 2024 12:02:12 +0100 Subject: [PATCH 8/8] audio: Fix changing sound time not working on macOS Fixes #1607 --- panda/src/audiotraits/openalAudioSound.cxx | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/panda/src/audiotraits/openalAudioSound.cxx b/panda/src/audiotraits/openalAudioSound.cxx index bb4b9f9ae4..155d6211fb 100644 --- a/panda/src/audiotraits/openalAudioSound.cxx +++ b/panda/src/audiotraits/openalAudioSound.cxx @@ -172,9 +172,20 @@ play() { if (_sd->_sample) { push_fresh_buffers(); + // The macOS implementation of alSourcePlay resets the offset, so we call + // it before and avoid calling restart_stalled_audio() afterwards (#1607) +#ifdef HAVE_OPENAL_FRAMEWORK + ALenum status; + alGetSourcei(_source, AL_SOURCE_STATE, &status); + if (status != AL_PLAYING) { + alSourcePlay(_source); + } +#endif alSourcef(_source, AL_SEC_OFFSET, _start_time); _stream_queued[0]._time_offset = _start_time; +#ifndef HAVE_OPENAL_FRAMEWORK restart_stalled_audio(); +#endif } else { audio_debug("Play: stream tell = " << _sd->_stream->tell() << " seeking " << _start_time); if (_sd->_stream->tell() != _start_time) {