mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-03-06 14:27:43 +00:00
Added support for scaling SVG graphics files directly when loading them.
This commit is contained in:
parent
2995a0c7c5
commit
1148f941a9
|
@ -26,6 +26,7 @@ TextureData::TextureData(
|
||||||
: mTile(tile),
|
: mTile(tile),
|
||||||
mTextureID(0),
|
mTextureID(0),
|
||||||
mDataRGBA({}),
|
mDataRGBA({}),
|
||||||
|
mScaleSVG(1.0f),
|
||||||
mScalable(false),
|
mScalable(false),
|
||||||
mWidth(0),
|
mWidth(0),
|
||||||
mHeight(0),
|
mHeight(0),
|
||||||
|
@ -59,7 +60,7 @@ bool TextureData::initSVGFromMemory(const std::string& fileData)
|
||||||
NSVGimage* svgImage = nsvgParse(const_cast<char*>(fileData.c_str()), "px", DPI);
|
NSVGimage* svgImage = nsvgParse(const_cast<char*>(fileData.c_str()), "px", DPI);
|
||||||
|
|
||||||
if (!svgImage) {
|
if (!svgImage) {
|
||||||
LOG(LogError) << "Error parsing SVG image.";
|
LOG(LogError) << "Couldn't parse SVG image";
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -69,8 +70,9 @@ bool TextureData::initSVGFromMemory(const std::string& fileData)
|
||||||
mSourceWidth = svgImage->width;
|
mSourceWidth = svgImage->width;
|
||||||
mSourceHeight = svgImage->height;
|
mSourceHeight = svgImage->height;
|
||||||
}
|
}
|
||||||
mWidth = static_cast<size_t>(std::round(mSourceWidth));
|
|
||||||
mHeight = static_cast<size_t>(std::round(mSourceHeight));
|
mWidth = static_cast<size_t>(std::round(mSourceWidth * mScaleSVG));
|
||||||
|
mHeight = static_cast<size_t>(std::round(mSourceHeight * mScaleSVG));
|
||||||
|
|
||||||
if (mWidth == 0) {
|
if (mWidth == 0) {
|
||||||
// Auto scale width to keep aspect ratio.
|
// Auto scale width to keep aspect ratio.
|
||||||
|
|
|
@ -54,6 +54,9 @@ public:
|
||||||
float sourceHeight();
|
float sourceHeight();
|
||||||
void setSourceSize(float width, float height);
|
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; }
|
bool tiled() { return mTile; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
@ -66,6 +69,7 @@ private:
|
||||||
size_t mHeight;
|
size_t mHeight;
|
||||||
float mSourceWidth;
|
float mSourceWidth;
|
||||||
float mSourceHeight;
|
float mSourceHeight;
|
||||||
|
float mScaleSVG;
|
||||||
bool mScalable;
|
bool mScalable;
|
||||||
bool mReloadable;
|
bool mReloadable;
|
||||||
};
|
};
|
||||||
|
|
|
@ -17,7 +17,7 @@ TextureDataManager::TextureDataManager()
|
||||||
{
|
{
|
||||||
unsigned char data[5 * 5 * 4];
|
unsigned char data[5 * 5 * 4];
|
||||||
mBlank = std::shared_ptr<TextureData>(new TextureData(false));
|
mBlank = std::shared_ptr<TextureData>(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] = (i % 2) * 255;
|
||||||
data[i*4+1] = (i % 2) * 255;
|
data[i*4+1] = (i % 2) * 255;
|
||||||
data[i*4+2] = (i % 2) * 255;
|
data[i*4+2] = (i % 2) * 255;
|
||||||
|
@ -130,7 +130,7 @@ void TextureDataManager::load(std::shared_ptr<TextureData> tex, bool block)
|
||||||
|
|
||||||
size_t max_texture = settingVRAM * 1024 * 1024;
|
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)
|
if (size < max_texture)
|
||||||
break;
|
break;
|
||||||
//size -= (*it)->getVRAMUsage();
|
//size -= (*it)->getVRAMUsage();
|
||||||
|
|
|
@ -19,7 +19,8 @@ std::set<TextureResource*> TextureResource::sAllTextures;
|
||||||
TextureResource::TextureResource(
|
TextureResource::TextureResource(
|
||||||
const std::string& path,
|
const std::string& path,
|
||||||
bool tile,
|
bool tile,
|
||||||
bool dynamic)
|
bool dynamic,
|
||||||
|
float scaleSVG)
|
||||||
: mTextureData(nullptr),
|
: mTextureData(nullptr),
|
||||||
mForceLoad(false)
|
mForceLoad(false)
|
||||||
{
|
{
|
||||||
|
@ -31,6 +32,8 @@ TextureResource::TextureResource(
|
||||||
if (dynamic) {
|
if (dynamic) {
|
||||||
data = sTextureDataManager.add(this, tile);
|
data = sTextureDataManager.add(this, tile);
|
||||||
data->initFromPath(path);
|
data->initFromPath(path);
|
||||||
|
if (scaleSVG != 1.0f)
|
||||||
|
data->setScaleSVGDuringLoad(scaleSVG);
|
||||||
// Force the texture manager to load it using a blocking load.
|
// Force the texture manager to load it using a blocking load.
|
||||||
sTextureDataManager.load(data, true);
|
sTextureDataManager.load(data, true);
|
||||||
}
|
}
|
||||||
|
@ -38,6 +41,8 @@ TextureResource::TextureResource(
|
||||||
mTextureData = std::shared_ptr<TextureData>(new TextureData(tile));
|
mTextureData = std::shared_ptr<TextureData>(new TextureData(tile));
|
||||||
data = mTextureData;
|
data = mTextureData;
|
||||||
data->initFromPath(path);
|
data->initFromPath(path);
|
||||||
|
if (scaleSVG != 1.0f)
|
||||||
|
data->setScaleSVGDuringLoad(scaleSVG);
|
||||||
// Load it so we can read the width/height.
|
// Load it so we can read the width/height.
|
||||||
data->load();
|
data->load();
|
||||||
}
|
}
|
||||||
|
@ -124,14 +129,18 @@ bool TextureResource::bind()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
std::shared_ptr<TextureResource> TextureResource::get(const std::string& path, bool tile,
|
std::shared_ptr<TextureResource> TextureResource::get(
|
||||||
bool forceLoad, bool dynamic)
|
const std::string& path,
|
||||||
|
bool tile,
|
||||||
|
bool forceLoad,
|
||||||
|
bool dynamic,
|
||||||
|
float scaleSVG)
|
||||||
{
|
{
|
||||||
std::shared_ptr<ResourceManager>& rm = ResourceManager::getInstance();
|
std::shared_ptr<ResourceManager>& rm = ResourceManager::getInstance();
|
||||||
|
|
||||||
const std::string canonicalPath = Utils::FileSystem::getCanonicalPath(path);
|
const std::string canonicalPath = Utils::FileSystem::getCanonicalPath(path);
|
||||||
if (canonicalPath.empty()) {
|
if (canonicalPath.empty()) {
|
||||||
std::shared_ptr<TextureResource> tex(new TextureResource("", tile, false));
|
std::shared_ptr<TextureResource> tex(new TextureResource("", tile, false, scaleSVG));
|
||||||
// Make sure we get properly deinitialized even though we do nothing on reinitialization.
|
// Make sure we get properly deinitialized even though we do nothing on reinitialization.
|
||||||
rm->addReloadable(tex);
|
rm->addReloadable(tex);
|
||||||
return tex;
|
return tex;
|
||||||
|
@ -147,7 +156,7 @@ std::shared_ptr<TextureResource> TextureResource::get(const std::string& path, b
|
||||||
|
|
||||||
// Need to create it.
|
// Need to create it.
|
||||||
std::shared_ptr<TextureResource> tex;
|
std::shared_ptr<TextureResource> tex;
|
||||||
tex = std::shared_ptr<TextureResource>(new TextureResource(key.first, tile, dynamic));
|
tex = std::shared_ptr<TextureResource>(new TextureResource(key.first, tile, dynamic, scaleSVG));
|
||||||
std::shared_ptr<TextureData> data = sTextureDataManager.get(tex.get());
|
std::shared_ptr<TextureData> data = sTextureDataManager.get(tex.get());
|
||||||
|
|
||||||
// Is it an SVG?
|
// Is it an SVG?
|
||||||
|
|
|
@ -25,13 +25,20 @@ class TextureData;
|
||||||
class TextureResource : public IReloadable
|
class TextureResource : public IReloadable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
static std::shared_ptr<TextureResource> get(const std::string& path, bool tile = false,
|
static std::shared_ptr<TextureResource> get(
|
||||||
bool forceLoad = false, bool dynamic = true);
|
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);
|
void initFromPixels(const unsigned char* dataRGBA, size_t width, size_t height);
|
||||||
virtual void initFromMemory(const char* data, size_t length);
|
virtual void initFromMemory(const char* data, size_t length);
|
||||||
static void manualUnload(std::string path, bool tile);
|
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);
|
void rasterizeAt(size_t width, size_t height);
|
||||||
Vector2f getSourceImageSize() const;
|
Vector2f getSourceImageSize() const;
|
||||||
|
|
||||||
|
@ -49,7 +56,7 @@ public:
|
||||||
static size_t getTotalTextureSize();
|
static size_t getTotalTextureSize();
|
||||||
|
|
||||||
protected:
|
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<ResourceManager>& rm);
|
virtual void unload(std::shared_ptr<ResourceManager>& rm);
|
||||||
virtual void reload(std::shared_ptr<ResourceManager>& rm);
|
virtual void reload(std::shared_ptr<ResourceManager>& rm);
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue