From 0bfc98fe26c616e73cf0a05c75570e77acfeb163 Mon Sep 17 00:00:00 2001 From: Vincent Robinson Date: Sun, 3 Jul 2022 05:52:26 -0700 Subject: [PATCH] Backport (II): "FormSpec: 9-slice images, animated_images, and fgimg_middle (#12453)" * FormSpec: 9-slice images and animated_images * Add fgimg_middle; clean up code * Address issues, add tests * Fix stupid error; bump formspec version * Re-add image[] elements without a size --- doc/lua_api.txt | 6 +++-- src/gui/guiFormSpecMenu.cpp | 42 ++++++++++++++++++++++++++--------- src/network/networkprotocol.h | 2 +- 3 files changed, 36 insertions(+), 14 deletions(-) diff --git a/doc/lua_api.txt b/doc/lua_api.txt index b5ddbf015..d7208e950 100644 --- a/doc/lua_api.txt +++ b/doc/lua_api.txt @@ -2288,7 +2288,8 @@ Elements * Show an image. * `middle` (optional): Makes the image render in 9-sliced mode and defines the middle rect. - Requires formspec version >= 4. See `background9[]` documentation for more information. + * Requires formspec version >= 4. + * See `background9[]` documentation for more information. ### `animated_image[,;,;;;;;;]` @@ -2300,7 +2301,8 @@ Elements * `frame duration`: Milliseconds between each frame. `0` means the frames don't advance. * `frame start` (optional): The index of the frame to start on. Default `1`. * `middle` (optional): Makes the image render in 9-sliced mode and defines the middle rect. - Requires formspec version >= 4. See `background9[]` documentation for more information. + * Requires formspec version >= 4. + * See `background9[]` documentation for more information. ### `model[,;,;;;;;;;]` diff --git a/src/gui/guiFormSpecMenu.cpp b/src/gui/guiFormSpecMenu.cpp index da7478c68..1dbd2970e 100644 --- a/src/gui/guiFormSpecMenu.cpp +++ b/src/gui/guiFormSpecMenu.cpp @@ -802,31 +802,51 @@ void GUIFormSpecMenu::parseImage(parserData* data, const std::string &element) { std::vector parts = split(element,';'); - if (parts.size() == 3 || parts.size() == 4 || + if ((parts.size() >= 2 && parts.size() <= 4) || (parts.size() > 4 && m_formspec_version > FORMSPEC_API_VERSION)) { - std::vector v_pos = split(parts[0],','); - std::vector v_geom = split(parts[1],','); - std::string name = unescape_string(parts[2]); + size_t offset = parts.size() >= 3; + + std::vector v_pos = split(parts[0],','); MY_CHECKPOS("image", 0); - MY_CHECKGEOM("image", 1); + + std::vector v_geom; + if (parts.size() >= 3) { + v_geom = split(parts[1],','); + MY_CHECKGEOM("image", 1); + } + + std::string name = unescape_string(parts[1 + offset]); + video::ITexture *texture = m_tsrc->getTexture(name); v2s32 pos; v2s32 geom; + if (parts.size() < 3) { + if (texture != nullptr) { + core::dimension2du dim = texture->getOriginalSize(); + geom.X = dim.Width; + geom.Y = dim.Height; + } else { + geom = v2s32(0); + } + } + if (data->real_coordinates) { pos = getRealCoordinateBasePos(v_pos); - geom = getRealCoordinateGeometry(v_geom); + if (parts.size() >= 3) + geom = getRealCoordinateGeometry(v_geom); } else { pos = getElementBasePos(&v_pos); - geom.X = stof(v_geom[0]) * (float)imgsize.X; - geom.Y = stof(v_geom[1]) * (float)imgsize.Y; + if (parts.size() >= 3) { + geom.X = stof(v_geom[0]) * (float)imgsize.X; + geom.Y = stof(v_geom[1]) * (float)imgsize.Y; + } } if (!data->explicit_size) - warningstream << "Invalid use of image without a size[] element" - << std::endl; + warningstream << "Invalid use of image without a size[] element" << std::endl; FieldSpec spec( name, @@ -845,7 +865,7 @@ void GUIFormSpecMenu::parseImage(parserData* data, const std::string &element) GUIAnimatedImage *e = new GUIAnimatedImage(Environment, data->current_parent, spec.fid, rect); - e->setTexture(m_tsrc->getTexture(name)); + e->setTexture(texture); e->setMiddleRect(middle); auto style = getDefaultStyleForElement("image", spec.fname); diff --git a/src/network/networkprotocol.h b/src/network/networkprotocol.h index 14eba0e9e..4cb21a5db 100644 --- a/src/network/networkprotocol.h +++ b/src/network/networkprotocol.h @@ -227,7 +227,7 @@ with this program; if not, write to the Free Software Foundation, Inc., #define PASSWORD_SIZE 28 // Maximum password length. Allows for // base64-encoded SHA-1 (27+\0). -// See also: Formspec Version History in doc/lua_api.txt +// See also formspec [Version History] in doc/lua_api.txt #define FORMSPEC_API_VERSION 4 #define TEXTURENAME_ALLOWED_CHARS "abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789_.-"