mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-02-16 20:15:38 +00:00
Fixed multiple image scaling and rasterization issues.
This commit is contained in:
parent
39acfdfe00
commit
6cee6d2732
|
@ -63,11 +63,8 @@ void ImageComponent::resize()
|
||||||
else {
|
else {
|
||||||
// SVG rasterization is determined by height and rasterization is done in terms of pixels.
|
// SVG rasterization is determined by height and rasterization is done in terms of pixels.
|
||||||
// If rounding is off enough in the rasterization step (for images with extreme aspect
|
// If rounding is off enough in the rasterization step (for images with extreme aspect
|
||||||
// ratios), it can cause cutoff when the aspect ratio breaks.
|
// ratios), it can cause cutoff when the aspect ratio breaks. So we always make sure to
|
||||||
// So we always make sure the resultant height is an integer to make sure cutoff doesn't
|
// round accordingly to avoid such issues.
|
||||||
// happen, and scale width from that (you'll see this scattered throughout the function).
|
|
||||||
// It's important to use floorf rather than round for this, as we never want to round up
|
|
||||||
// since that can lead to the cutoff just described.
|
|
||||||
if (mTargetIsMax) {
|
if (mTargetIsMax) {
|
||||||
mSize = textureSize;
|
mSize = textureSize;
|
||||||
|
|
||||||
|
@ -77,13 +74,11 @@ void ImageComponent::resize()
|
||||||
// This will be mTargetSize.x. We can't exceed it, nor be lower than it.
|
// This will be mTargetSize.x. We can't exceed it, nor be lower than it.
|
||||||
mSize.x *= resizeScale.x;
|
mSize.x *= resizeScale.x;
|
||||||
// We need to make sure we're not creating an image larger than max size.
|
// We need to make sure we're not creating an image larger than max size.
|
||||||
mSize.y = std::min(floorf(mSize.y * resizeScale.x), mTargetSize.y);
|
mSize.y = floorf(std::min(mSize.y * resizeScale.x, mTargetSize.y));
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
// This will be mTargetSize.y(). We can't exceed it.
|
// This will be mTargetSize.y(). We can't exceed it.
|
||||||
mSize.y = floorf(mSize.y * resizeScale.y);
|
mSize.y *= resizeScale.y;
|
||||||
// For SVG rasterization, always calculate width from rounded height (see comment
|
|
||||||
// above). We need to make sure we're not creating an image larger than max size.
|
|
||||||
mSize.x = std::min((mSize.y / textureSize.y) * textureSize.x, mTargetSize.x);
|
mSize.x = std::min((mSize.y / textureSize.y) * textureSize.x, mTargetSize.x);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,9 +101,7 @@ void ImageComponent::resize()
|
||||||
float cropPercent = (mSize.x - mTargetSize.x) / (mSize.x * 2.0f);
|
float cropPercent = (mSize.x - mTargetSize.x) / (mSize.x * 2.0f);
|
||||||
crop(cropPercent, 0.0f, cropPercent, 0.0f);
|
crop(cropPercent, 0.0f, cropPercent, 0.0f);
|
||||||
}
|
}
|
||||||
// For SVG rasterization, always calculate width from rounded height (see comment
|
mSize.y = std::max(mSize.y, mTargetSize.y);
|
||||||
// above). We need to make sure we're not creating an image smaller than min size.
|
|
||||||
mSize.y = std::max(floorf(mSize.y), mTargetSize.y);
|
|
||||||
mSize.x = std::max((mSize.y / textureSize.y) * textureSize.x, mTargetSize.x);
|
mSize.x = std::max((mSize.y / textureSize.y) * textureSize.x, mTargetSize.x);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
@ -117,23 +110,24 @@ void ImageComponent::resize()
|
||||||
mSize = mTargetSize == glm::vec2{} ? textureSize : mTargetSize;
|
mSize = mTargetSize == glm::vec2{} ? textureSize : mTargetSize;
|
||||||
|
|
||||||
// If only one component is set, we resize in a way that maintains aspect ratio.
|
// If only one component is set, we resize in a way that maintains aspect ratio.
|
||||||
// For SVG rasterization, we always calculate width from rounded height (see
|
|
||||||
// comment above).
|
|
||||||
if (!mTargetSize.x && mTargetSize.y) {
|
if (!mTargetSize.x && mTargetSize.y) {
|
||||||
mSize.y = floorf(mTargetSize.y);
|
mSize.y = mTargetSize.y;
|
||||||
mSize.x = (mSize.y / textureSize.y) * textureSize.x;
|
mSize.x = (mSize.y / textureSize.y) * textureSize.x;
|
||||||
}
|
}
|
||||||
else if (mTargetSize.x && !mTargetSize.y) {
|
else if (mTargetSize.x && !mTargetSize.y) {
|
||||||
mSize.y = floorf((mTargetSize.x / textureSize.x) * textureSize.y);
|
mSize.y = (mTargetSize.x / textureSize.x) * textureSize.y;
|
||||||
mSize.x = (mSize.y / textureSize.y) * textureSize.x;
|
mSize.x = (mSize.y / textureSize.y) * textureSize.x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Make sure sub-pixel values are not rounded to zero.
|
||||||
|
if (mSize.x < 1.0f)
|
||||||
mSize.x = ceilf(mSize.x);
|
mSize.x = ceilf(mSize.x);
|
||||||
|
if (mSize.y < 1.0f)
|
||||||
mSize.y = ceilf(mSize.y);
|
mSize.y = ceilf(mSize.y);
|
||||||
|
|
||||||
mTexture->rasterizeAt(static_cast<size_t>(mSize.x), static_cast<size_t>(mSize.y));
|
mTexture->rasterizeAt(mSize.x, mSize.y);
|
||||||
|
|
||||||
onSizeChanged();
|
onSizeChanged();
|
||||||
}
|
}
|
||||||
|
|
|
@ -73,8 +73,8 @@ bool TextureData::initSVGFromMemory(const std::string& fileData)
|
||||||
mSourceHeight = svgImage->height;
|
mSourceHeight = svgImage->height;
|
||||||
}
|
}
|
||||||
|
|
||||||
mWidth = static_cast<size_t>(floorf(floorf(mSourceWidth) * mScaleDuringLoad));
|
mWidth = static_cast<int>(std::round(mSourceWidth * mScaleDuringLoad));
|
||||||
mHeight = static_cast<size_t>(floorf(floorf(mSourceHeight) * mScaleDuringLoad));
|
mHeight = static_cast<int>(std::round(mSourceHeight * mScaleDuringLoad));
|
||||||
|
|
||||||
if (mWidth == 0) {
|
if (mWidth == 0) {
|
||||||
// Auto scale width to keep aspect ratio.
|
// Auto scale width to keep aspect ratio.
|
||||||
|
@ -92,9 +92,8 @@ bool TextureData::initSVGFromMemory(const std::string& fileData)
|
||||||
|
|
||||||
NSVGrasterizer* rast = nsvgCreateRasterizer();
|
NSVGrasterizer* rast = nsvgCreateRasterizer();
|
||||||
|
|
||||||
nsvgRasterize(rast, svgImage, 0, 0, mHeight / svgImage->height, tempVector.data(),
|
nsvgRasterize(rast, svgImage, 0, 0, mHeight / svgImage->height, tempVector.data(), mWidth,
|
||||||
static_cast<int>(mWidth), static_cast<int>(mHeight),
|
mHeight, mWidth * 4);
|
||||||
static_cast<int>(mWidth) * 4);
|
|
||||||
|
|
||||||
// This is important in order to avoid memory leaks.
|
// This is important in order to avoid memory leaks.
|
||||||
nsvgDeleteRasterizer(rast);
|
nsvgDeleteRasterizer(rast);
|
||||||
|
|
|
@ -72,8 +72,8 @@ private:
|
||||||
std::string mPath;
|
std::string mPath;
|
||||||
unsigned int mTextureID;
|
unsigned int mTextureID;
|
||||||
std::vector<unsigned char> mDataRGBA;
|
std::vector<unsigned char> mDataRGBA;
|
||||||
size_t mWidth;
|
int mWidth;
|
||||||
size_t mHeight;
|
int mHeight;
|
||||||
float mSourceWidth;
|
float mSourceWidth;
|
||||||
float mSourceHeight;
|
float mSourceHeight;
|
||||||
float mScaleDuringLoad;
|
float mScaleDuringLoad;
|
||||||
|
|
|
@ -194,7 +194,7 @@ std::shared_ptr<TextureResource> TextureResource::get(const std::string& path,
|
||||||
return tex;
|
return tex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void TextureResource::rasterizeAt(size_t width, size_t height)
|
void TextureResource::rasterizeAt(float width, float height)
|
||||||
{
|
{
|
||||||
if (mTextureData != nullptr) {
|
if (mTextureData != nullptr) {
|
||||||
glm::vec2 textureSize = mTextureData.get()->getSize();
|
glm::vec2 textureSize = mTextureData.get()->getSize();
|
||||||
|
|
|
@ -44,7 +44,7 @@ public:
|
||||||
// It does unload and re-rasterize the texture though which may cause flickering in some
|
// 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
|
// situations. An alternative is to set a scaling factor directly when loading the texture
|
||||||
// using get(), by using the scaleDuringLoad parameter (which also works for raster graphics).
|
// using get(), by using the scaleDuringLoad parameter (which also works for raster graphics).
|
||||||
void rasterizeAt(size_t width, size_t height);
|
void rasterizeAt(float width, float height);
|
||||||
glm::vec2 getSourceImageSize() const { return mSourceSize; }
|
glm::vec2 getSourceImageSize() const { return mSourceSize; }
|
||||||
|
|
||||||
virtual ~TextureResource();
|
virtual ~TextureResource();
|
||||||
|
|
Loading…
Reference in a new issue