mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2024-11-22 06:05: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 {
|
||||
// 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
|
||||
// ratios), it can cause cutoff when the aspect ratio breaks.
|
||||
// So we always make sure the resultant height is an integer to make sure cutoff doesn't
|
||||
// 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.
|
||||
// ratios), it can cause cutoff when the aspect ratio breaks. So we always make sure to
|
||||
// round accordingly to avoid such issues.
|
||||
if (mTargetIsMax) {
|
||||
mSize = textureSize;
|
||||
|
||||
|
@ -77,13 +74,11 @@ void ImageComponent::resize()
|
|||
// This will be mTargetSize.x. We can't exceed it, nor be lower than it.
|
||||
mSize.x *= resizeScale.x;
|
||||
// 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 {
|
||||
// This will be mTargetSize.y(). We can't exceed it.
|
||||
mSize.y = floorf(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.y *= resizeScale.y;
|
||||
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);
|
||||
crop(cropPercent, 0.0f, cropPercent, 0.0f);
|
||||
}
|
||||
// For SVG rasterization, always calculate width from rounded height (see comment
|
||||
// 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.y = std::max(mSize.y, mTargetSize.y);
|
||||
mSize.x = std::max((mSize.y / textureSize.y) * textureSize.x, mTargetSize.x);
|
||||
}
|
||||
else {
|
||||
|
@ -117,23 +110,24 @@ void ImageComponent::resize()
|
|||
mSize = mTargetSize == glm::vec2{} ? textureSize : mTargetSize;
|
||||
|
||||
// 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) {
|
||||
mSize.y = floorf(mTargetSize.y);
|
||||
mSize.y = mTargetSize.y;
|
||||
mSize.x = (mSize.y / textureSize.y) * textureSize.x;
|
||||
}
|
||||
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 = ceilf(mSize.x);
|
||||
mSize.y = ceilf(mSize.y);
|
||||
// Make sure sub-pixel values are not rounded to zero.
|
||||
if (mSize.x < 1.0f)
|
||||
mSize.x = ceilf(mSize.x);
|
||||
if (mSize.y < 1.0f)
|
||||
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();
|
||||
}
|
||||
|
|
|
@ -73,8 +73,8 @@ bool TextureData::initSVGFromMemory(const std::string& fileData)
|
|||
mSourceHeight = svgImage->height;
|
||||
}
|
||||
|
||||
mWidth = static_cast<size_t>(floorf(floorf(mSourceWidth) * mScaleDuringLoad));
|
||||
mHeight = static_cast<size_t>(floorf(floorf(mSourceHeight) * mScaleDuringLoad));
|
||||
mWidth = static_cast<int>(std::round(mSourceWidth * mScaleDuringLoad));
|
||||
mHeight = static_cast<int>(std::round(mSourceHeight * mScaleDuringLoad));
|
||||
|
||||
if (mWidth == 0) {
|
||||
// Auto scale width to keep aspect ratio.
|
||||
|
@ -92,9 +92,8 @@ bool TextureData::initSVGFromMemory(const std::string& fileData)
|
|||
|
||||
NSVGrasterizer* rast = nsvgCreateRasterizer();
|
||||
|
||||
nsvgRasterize(rast, svgImage, 0, 0, mHeight / svgImage->height, tempVector.data(),
|
||||
static_cast<int>(mWidth), static_cast<int>(mHeight),
|
||||
static_cast<int>(mWidth) * 4);
|
||||
nsvgRasterize(rast, svgImage, 0, 0, mHeight / svgImage->height, tempVector.data(), mWidth,
|
||||
mHeight, mWidth * 4);
|
||||
|
||||
// This is important in order to avoid memory leaks.
|
||||
nsvgDeleteRasterizer(rast);
|
||||
|
|
|
@ -72,8 +72,8 @@ private:
|
|||
std::string mPath;
|
||||
unsigned int mTextureID;
|
||||
std::vector<unsigned char> mDataRGBA;
|
||||
size_t mWidth;
|
||||
size_t mHeight;
|
||||
int mWidth;
|
||||
int mHeight;
|
||||
float mSourceWidth;
|
||||
float mSourceHeight;
|
||||
float mScaleDuringLoad;
|
||||
|
|
|
@ -194,7 +194,7 @@ std::shared_ptr<TextureResource> TextureResource::get(const std::string& path,
|
|||
return tex;
|
||||
}
|
||||
|
||||
void TextureResource::rasterizeAt(size_t width, size_t height)
|
||||
void TextureResource::rasterizeAt(float width, float height)
|
||||
{
|
||||
if (mTextureData != nullptr) {
|
||||
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
|
||||
// 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).
|
||||
void rasterizeAt(size_t width, size_t height);
|
||||
void rasterizeAt(float width, float height);
|
||||
glm::vec2 getSourceImageSize() const { return mSourceSize; }
|
||||
|
||||
virtual ~TextureResource();
|
||||
|
|
Loading…
Reference in a new issue