diff --git a/es-core/src/resources/TextureData.cpp b/es-core/src/resources/TextureData.cpp index ba5d9d442..d6c1ef24f 100644 --- a/es-core/src/resources/TextureData.cpp +++ b/es-core/src/resources/TextureData.cpp @@ -26,6 +26,7 @@ TextureData::TextureData( : mTile(tile), mTextureID(0), mDataRGBA({}), + mScaleSVG(1.0f), mScalable(false), mWidth(0), mHeight(0), @@ -59,7 +60,7 @@ bool TextureData::initSVGFromMemory(const std::string& fileData) NSVGimage* svgImage = nsvgParse(const_cast(fileData.c_str()), "px", DPI); if (!svgImage) { - LOG(LogError) << "Error parsing SVG image."; + LOG(LogError) << "Couldn't parse SVG image"; return false; } @@ -69,8 +70,9 @@ bool TextureData::initSVGFromMemory(const std::string& fileData) mSourceWidth = svgImage->width; mSourceHeight = svgImage->height; } - mWidth = static_cast(std::round(mSourceWidth)); - mHeight = static_cast(std::round(mSourceHeight)); + + mWidth = static_cast(std::round(mSourceWidth * mScaleSVG)); + mHeight = static_cast(std::round(mSourceHeight * mScaleSVG)); if (mWidth == 0) { // Auto scale width to keep aspect ratio. diff --git a/es-core/src/resources/TextureData.h b/es-core/src/resources/TextureData.h index 1f181de89..ffcd6301d 100644 --- a/es-core/src/resources/TextureData.h +++ b/es-core/src/resources/TextureData.h @@ -54,6 +54,9 @@ 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; } + bool tiled() { return mTile; } private: @@ -66,6 +69,7 @@ private: size_t mHeight; float mSourceWidth; float mSourceHeight; + float mScaleSVG; bool mScalable; bool mReloadable; }; diff --git a/es-core/src/resources/TextureDataManager.cpp b/es-core/src/resources/TextureDataManager.cpp index 9c874c7b7..cee2d7b92 100644 --- a/es-core/src/resources/TextureDataManager.cpp +++ b/es-core/src/resources/TextureDataManager.cpp @@ -17,7 +17,7 @@ TextureDataManager::TextureDataManager() { unsigned char data[5 * 5 * 4]; mBlank = std::shared_ptr(new TextureData(false)); - for (int i = 0; i < (5 * 5); ++i) { + for (int i = 0; i < (5 * 5); i++) { data[i*4] = (i % 2) * 255; data[i*4+1] = (i % 2) * 255; data[i*4+2] = (i % 2) * 255; @@ -130,7 +130,7 @@ void TextureDataManager::load(std::shared_ptr tex, bool block) size_t max_texture = settingVRAM * 1024 * 1024; - for (auto it = mTextures.crbegin(); it != mTextures.crend(); ++it) { + for (auto it = mTextures.crbegin(); it != mTextures.crend(); it++) { if (size < max_texture) break; //size -= (*it)->getVRAMUsage(); diff --git a/es-core/src/resources/TextureResource.cpp b/es-core/src/resources/TextureResource.cpp index b68f84f7b..ed4bf1893 100644 --- a/es-core/src/resources/TextureResource.cpp +++ b/es-core/src/resources/TextureResource.cpp @@ -19,7 +19,8 @@ std::set TextureResource::sAllTextures; TextureResource::TextureResource( const std::string& path, bool tile, - bool dynamic) + bool dynamic, + float scaleSVG) : mTextureData(nullptr), mForceLoad(false) { @@ -31,6 +32,8 @@ TextureResource::TextureResource( if (dynamic) { data = sTextureDataManager.add(this, tile); data->initFromPath(path); + if (scaleSVG != 1.0f) + data->setScaleSVGDuringLoad(scaleSVG); // Force the texture manager to load it using a blocking load. sTextureDataManager.load(data, true); } @@ -38,6 +41,8 @@ TextureResource::TextureResource( mTextureData = std::shared_ptr(new TextureData(tile)); data = mTextureData; data->initFromPath(path); + if (scaleSVG != 1.0f) + data->setScaleSVGDuringLoad(scaleSVG); // Load it so we can read the width/height. data->load(); } @@ -124,14 +129,18 @@ bool TextureResource::bind() } } -std::shared_ptr TextureResource::get(const std::string& path, bool tile, - bool forceLoad, bool dynamic) +std::shared_ptr TextureResource::get( + const std::string& path, + bool tile, + bool forceLoad, + bool dynamic, + float scaleSVG) { std::shared_ptr& rm = ResourceManager::getInstance(); const std::string canonicalPath = Utils::FileSystem::getCanonicalPath(path); if (canonicalPath.empty()) { - std::shared_ptr tex(new TextureResource("", tile, false)); + std::shared_ptr tex(new TextureResource("", tile, false, scaleSVG)); // Make sure we get properly deinitialized even though we do nothing on reinitialization. rm->addReloadable(tex); return tex; @@ -147,7 +156,7 @@ std::shared_ptr TextureResource::get(const std::string& path, b // Need to create it. std::shared_ptr tex; - tex = std::shared_ptr(new TextureResource(key.first, tile, dynamic)); + tex = std::shared_ptr(new TextureResource(key.first, tile, dynamic, scaleSVG)); std::shared_ptr 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 e0f297b2c..5de8624a9 100644 --- a/es-core/src/resources/TextureResource.h +++ b/es-core/src/resources/TextureResource.h @@ -25,13 +25,20 @@ class TextureData; class TextureResource : public IReloadable { public: - static std::shared_ptr get(const std::string& path, bool tile = false, - bool forceLoad = false, bool dynamic = true); + static std::shared_ptr get( + const std::string& path, + bool tile = false, + bool forceLoad = false, + bool dynamic = true, + float scaleSVG = 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); - // For scalable source images in textures we want to set the resolution to rasterize at. + // 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. void rasterizeAt(size_t width, size_t height); Vector2f getSourceImageSize() const; @@ -49,7 +56,7 @@ public: static size_t getTotalTextureSize(); protected: - TextureResource(const std::string& path, bool tile, bool dynamic); + TextureResource(const std::string& path, bool tile, bool dynamic, float scaleSVG); virtual void unload(std::shared_ptr& rm); virtual void reload(std::shared_ptr& rm);