From 0bc707a828640ee4a624487ed12e74b324ca4e3a Mon Sep 17 00:00:00 2001
From: Leon Styhre <leon@leonstyhre.com>
Date: Fri, 15 Jan 2021 18:39:19 +0100
Subject: [PATCH] Added support for scaling textures during load for raster
 files.

---
 es-core/src/resources/TextureData.cpp     | 29 +++++++++++++++--------
 es-core/src/resources/TextureData.h       |  6 ++---
 es-core/src/resources/TextureResource.cpp | 17 ++++++-------
 es-core/src/resources/TextureResource.h   |  6 ++---
 4 files changed, 34 insertions(+), 24 deletions(-)

diff --git a/es-core/src/resources/TextureData.cpp b/es-core/src/resources/TextureData.cpp
index d6c1ef24f..ce5bb2eb0 100644
--- a/es-core/src/resources/TextureData.cpp
+++ b/es-core/src/resources/TextureData.cpp
@@ -26,7 +26,7 @@ TextureData::TextureData(
         : mTile(tile),
         mTextureID(0),
         mDataRGBA({}),
-        mScaleSVG(1.0f),
+        mScaleDuringLoad(1.0f),
         mScalable(false),
         mWidth(0),
         mHeight(0),
@@ -71,8 +71,8 @@ bool TextureData::initSVGFromMemory(const std::string& fileData)
         mSourceHeight = svgImage->height;
     }
 
-    mWidth = static_cast<size_t>(std::round(mSourceWidth * mScaleSVG));
-    mHeight = static_cast<size_t>(std::round(mSourceHeight * mScaleSVG));
+    mWidth = static_cast<size_t>(std::round(mSourceWidth * mScaleDuringLoad));
+    mHeight = static_cast<size_t>(std::round(mSourceHeight * mScaleDuringLoad));
 
     if (mWidth == 0) {
         // Auto scale width to keep aspect ratio.
@@ -107,7 +107,8 @@ bool TextureData::initSVGFromMemory(const std::string& fileData)
 
 bool TextureData::initImageFromMemory(const unsigned char* fileData, size_t length)
 {
-    size_t width, height;
+    size_t width;
+    size_t height;
 
     // If already initialized then don't process it again.
     {
@@ -141,7 +142,7 @@ bool TextureData::initFromRGBA(const unsigned char* dataRGBA, size_t width, size
         return true;
 
     mDataRGBA.reserve(width * height * 4);
-    mDataRGBA.insert(mDataRGBA.begin(), dataRGBA, dataRGBA+(width * height * 4));
+    mDataRGBA.insert(mDataRGBA.begin(), dataRGBA, dataRGBA + (width * height * 4));
 
     mWidth = width;
     mHeight = height;
@@ -193,9 +194,9 @@ bool TextureData::uploadAndBind()
             return false;
 
         // Upload texture.
-        mTextureID = Renderer::createTexture(Renderer::Texture::RGBA, true,
-                mTile, static_cast<const unsigned int>(mWidth),
-                static_cast<const unsigned int>(mHeight), mDataRGBA.data());
+        mTextureID = Renderer::createTexture(Renderer::Texture::RGBA, true, mTile,
+                static_cast<const unsigned int>(mWidth), static_cast<const unsigned int>(mHeight),
+                mDataRGBA.data());
     }
     return true;
 }
@@ -223,14 +224,22 @@ size_t TextureData::width()
 {
     if (mWidth == 0)
         load();
-    return mWidth;
+    // If it's an SVG image, the size was correctly set to the scaled-up values during the
+    // rasterization, so only multiply by the scale factor if it's a raster file.
+    if (!mScalable)
+        return mWidth * mScaleDuringLoad;
+    else
+        return mWidth;
 }
 
 size_t TextureData::height()
 {
     if (mHeight == 0)
         load();
-    return mHeight;
+    if (!mScalable)
+        return mHeight * mScaleDuringLoad;
+    else
+        return mHeight;
 }
 
 float TextureData::sourceWidth()
diff --git a/es-core/src/resources/TextureData.h b/es-core/src/resources/TextureData.h
index ffcd6301d..c1ffb404c 100644
--- a/es-core/src/resources/TextureData.h
+++ b/es-core/src/resources/TextureData.h
@@ -54,8 +54,8 @@ public:
     float sourceHeight();
     void setSourceSize(float width, float height);
 
-    // Define a factor for scaling the SVG graphics when loading it (1.0f = no scaling).
-    void setScaleSVGDuringLoad(float scale) { mScaleSVG = scale; }
+    // Define a factor for scaling the file when loading it (1.0f = no scaling).
+    void setScaleDuringLoad(float scale) { mScaleDuringLoad = scale; }
 
     bool tiled() { return mTile; }
 
@@ -69,7 +69,7 @@ private:
     size_t mHeight;
     float mSourceWidth;
     float mSourceHeight;
-    float mScaleSVG;
+    float mScaleDuringLoad;
     bool mScalable;
     bool mReloadable;
 };
diff --git a/es-core/src/resources/TextureResource.cpp b/es-core/src/resources/TextureResource.cpp
index ed4bf1893..e82a49310 100644
--- a/es-core/src/resources/TextureResource.cpp
+++ b/es-core/src/resources/TextureResource.cpp
@@ -20,7 +20,7 @@ TextureResource::TextureResource(
         const std::string& path,
         bool tile,
         bool dynamic,
-        float scaleSVG)
+        float scaleDuringLoad)
         : mTextureData(nullptr),
         mForceLoad(false)
 {
@@ -32,8 +32,8 @@ TextureResource::TextureResource(
         if (dynamic) {
             data = sTextureDataManager.add(this, tile);
             data->initFromPath(path);
-            if (scaleSVG != 1.0f)
-                data->setScaleSVGDuringLoad(scaleSVG);
+            if (scaleDuringLoad != 1.0f)
+                data->setScaleDuringLoad(scaleDuringLoad);
             // Force the texture manager to load it using a blocking load.
             sTextureDataManager.load(data, true);
         }
@@ -41,8 +41,8 @@ TextureResource::TextureResource(
             mTextureData = std::shared_ptr<TextureData>(new TextureData(tile));
             data = mTextureData;
             data->initFromPath(path);
-            if (scaleSVG != 1.0f)
-                data->setScaleSVGDuringLoad(scaleSVG);
+            if (scaleDuringLoad != 1.0f)
+                data->setScaleDuringLoad(scaleDuringLoad);
             // Load it so we can read the width/height.
             data->load();
         }
@@ -134,13 +134,13 @@ std::shared_ptr<TextureResource> TextureResource::get(
         bool tile,
         bool forceLoad,
         bool dynamic,
-        float scaleSVG)
+        float scaleDuringLoad)
 {
     std::shared_ptr<ResourceManager>& rm = ResourceManager::getInstance();
 
     const std::string canonicalPath = Utils::FileSystem::getCanonicalPath(path);
     if (canonicalPath.empty()) {
-        std::shared_ptr<TextureResource> tex(new TextureResource("", tile, false, scaleSVG));
+        std::shared_ptr<TextureResource> tex(new TextureResource("", tile, false, scaleDuringLoad));
         // Make sure we get properly deinitialized even though we do nothing on reinitialization.
         rm->addReloadable(tex);
         return tex;
@@ -156,7 +156,8 @@ std::shared_ptr<TextureResource> TextureResource::get(
 
     // Need to create it.
     std::shared_ptr<TextureResource> tex;
-    tex = std::shared_ptr<TextureResource>(new TextureResource(key.first, tile, dynamic, scaleSVG));
+    tex = std::shared_ptr<TextureResource>(
+            new TextureResource(key.first, tile, dynamic, scaleDuringLoad));
     std::shared_ptr<TextureData> data = sTextureDataManager.get(tex.get());
 
     // Is it an SVG?
diff --git a/es-core/src/resources/TextureResource.h b/es-core/src/resources/TextureResource.h
index 5de8624a9..a9fa3ee0b 100644
--- a/es-core/src/resources/TextureResource.h
+++ b/es-core/src/resources/TextureResource.h
@@ -30,7 +30,7 @@ public:
             bool tile = false,
             bool forceLoad = false,
             bool dynamic = true,
-            float scaleSVG = 1.0f);
+            float scaleDuringLoad = 1.0f);
     void initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height);
     virtual void initFromMemory(const char* data, size_t length);
     static void manualUnload(std::string path, bool tile);
@@ -38,7 +38,7 @@ public:
     // For SVG graphics this function effectively rescales the image to the defined size.
     // It does unload and re-rasterize the texture though which may cause flickering in some
     // situations. An alternative is to set a scaling factor directly when loading the texture
-    // using get(), by using the scaleSVG parameter.
+    // using get(), by using the scaleDuringLoad parameter (which also works for raster graphics).
     void rasterizeAt(size_t width, size_t height);
     Vector2f getSourceImageSize() const;
 
@@ -56,7 +56,7 @@ public:
     static size_t getTotalTextureSize();
 
 protected:
-    TextureResource(const std::string& path, bool tile, bool dynamic, float scaleSVG);
+    TextureResource(const std::string& path, bool tile, bool dynamic, float scaleDuringLoad);
     virtual void unload(std::shared_ptr<ResourceManager>& rm);
     virtual void reload(std::shared_ptr<ResourceManager>& rm);