Commit 1e7ced2c authored by Aloshi's avatar Aloshi

Two fixes with SVG rasterizing:

1. Original width/height were being returned as integers, even though they can be floats (see SVGResource::getImageSize()).  Function also renamed to be more descriptive (renamed to getSourceImageSize()).
2. Now we always round height and scale width from the rounded height when doing scaling, since SVG rasterization scale is determined from height. This seems to fix some 1px cutoff I was seeing, but I'm not sure if it still works for images with extreme aspect ratios that are taller rather than wider.
parent d2c7de38
......@@ -37,12 +37,20 @@ void ImageComponent::resize()
if(!mTexture)
return;
const Eigen::Vector2f textureSize((float)getTextureSize().x(), (float)getTextureSize().y());
SVGResource* svg = dynamic_cast<SVGResource*>(mTexture.get());
const Eigen::Vector2f textureSize = svg ? svg->getSourceImageSize() : Eigen::Vector2f((float)mTexture->getSize().x(), (float)mTexture->getSize().y());
if(mTexture->isTiled())
{
mSize = mTargetSize;
}else{
// SVG rasterization is determined by height (see SVGResource.cpp), 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)
// this is probably not the best way, so if you're familiar with this problem and have a better solution, please make a pull request!
if(mTargetIsMax)
{
mSize = textureSize;
......@@ -58,27 +66,32 @@ void ImageComponent::resize()
mSize[1] *= resizeScale.y();
}
// for SVG rasterization, always calculate width from rounded height (see comment above)
mSize[1] = round(mSize[1]);
mSize[0] = (mSize[1] / textureSize.y()) * textureSize.x();
}else{
// if both components are set, we just stretch
// if no components are set, we don't resize at all
mSize = mTargetSize.isZero() ? 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[0] = (mTargetSize.y() / textureSize.y()) * textureSize.x();
mSize[1] = mTargetSize.y();
mSize[1] = round(mTargetSize.y());
mSize[0] = (mSize.y() / textureSize.y()) * textureSize.x();
}else if(mTargetSize.x() && !mTargetSize.y())
{
mSize[0] = mTargetSize.x();
mSize[1] = (mTargetSize.x() / textureSize.x()) * textureSize.y();
mSize[1] = round((mTargetSize.x() / textureSize.x()) * textureSize.y());
mSize[0] = (mSize.y() / textureSize.y()) * textureSize.x();
}
}
}
SVGResource* svg = dynamic_cast<SVGResource*>(mTexture.get());
if(svg)
{
// mSize.y() should already be rounded
svg->rasterizeAt((int)round(mSize.x()), (int)round(mSize.y()));
}
......
......@@ -69,6 +69,10 @@ void SVGResource::rasterizeAt(size_t width, size_t height)
mLastHeight = height;
}
LOG(LogInfo) << "Rasterizing \"" << mPath << "\"...";
LOG(LogInfo) << " Original width: " << mSVGImage->width << ", original height: " << mSVGImage->height;
LOG(LogInfo) << " width: " << width << ", height: " << height << ", scale: " << height / mSVGImage->height;
unsigned char* imagePx = (unsigned char*)malloc(width * height * 4);
NSVGrasterizer* rast = nsvgCreateRasterizer();
......@@ -92,12 +96,12 @@ void SVGResource::rasterizeAt(size_t width, size_t height)
free(imagePx);
}
Eigen::Vector2i SVGResource::getImageSize() const
Eigen::Vector2f SVGResource::getSourceImageSize() const
{
if(mSVGImage)
return Eigen::Vector2i((int)round(mSVGImage->width), (int)round(mSVGImage->height));
return Eigen::Vector2f(mSVGImage->width, mSVGImage->height);
return Eigen::Vector2i::Zero();
return Eigen::Vector2f::Zero();
}
void SVGResource::deinitSVG()
......
......@@ -14,7 +14,7 @@ public:
virtual void initFromMemory(const char* image, size_t length) override;
void rasterizeAt(size_t width, size_t height);
Eigen::Vector2i getImageSize() const;
Eigen::Vector2f getSourceImageSize() const;
protected:
friend TextureResource;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment