diff --git a/Docs/Luadoc/LuaDocumentation.xml b/Docs/Luadoc/LuaDocumentation.xml
index 34ba687243..4457774e76 100644
--- a/Docs/Luadoc/LuaDocumentation.xml
+++ b/Docs/Luadoc/LuaDocumentation.xml
@@ -4236,7 +4236,7 @@ save yourself some time, copy this for undocumented things:
[02 Sprite.lua] Call RageTexture:rate( fRate ) on the texture.
- Scale the Sprite to width fWidth and height fHeight clipping if the dimensions do not match.
+ Scale the Sprite to width fWidth and height fHeight clipping dimension that would stick out.
Set the Sprite's state to iNewState.
diff --git a/src/Sprite.cpp b/src/Sprite.cpp
index c3af0d668e..389c7568f4 100644
--- a/src/Sprite.cpp
+++ b/src/Sprite.cpp
@@ -30,6 +30,8 @@ Sprite::Sprite()
m_fRememberedClipWidth = -1;
m_fRememberedClipHeight = -1;
+ m_fRememberedCropWidth = -1;
+ m_fRememberedCropHeight = -1;
m_fTexCoordVelocityX = 0;
m_fTexCoordVelocityY = 0;
@@ -56,6 +58,8 @@ Sprite::Sprite( const Sprite &cpy ):
memcpy( m_CustomPosCoords, cpy.m_CustomPosCoords, sizeof(m_CustomPosCoords) );
CPY( m_fRememberedClipWidth );
CPY( m_fRememberedClipHeight );
+ CPY( m_fRememberedCropWidth );
+ CPY( m_fRememberedCropHeight );
CPY( m_fTexCoordVelocityX );
CPY( m_fTexCoordVelocityY );
#undef CPY
@@ -295,6 +299,11 @@ void Sprite::SetTexture( RageTexture *pTexture )
if( m_fRememberedClipWidth != -1 && m_fRememberedClipHeight != -1 )
ScaleToClipped( m_fRememberedClipWidth, m_fRememberedClipHeight );
+ if( m_fRememberedCropWidth != -1 && m_fRememberedCropHeight != -1 )
+ {
+ CropTo(m_fRememberedCropWidth, m_fRememberedCropHeight);
+ }
+
// Load default states if we haven't before.
if( m_States.empty() )
LoadStatesFromTexture();
@@ -871,125 +880,97 @@ void Sprite::SetTexCoordVelocity(float fVelX, float fVelY)
m_fTexCoordVelocityY = fVelY;
}
-void Sprite::ScaleToClipped( float fWidth, float fHeight )
+void Sprite::ScaleToClipped( float width, float height )
{
- m_fRememberedClipWidth = fWidth;
- m_fRememberedClipHeight = fHeight;
+ m_fRememberedClipWidth = width;
+ m_fRememberedClipHeight = height;
if( !m_pTexture )
- return;
-
- float fScaleFudgePercent = 0.15f; // scale up to this amount in one dimension to avoid clipping.
-
- // save the original X and Y. We're going to restore them later.
- float fOriginalX = GetX();
- float fOriginalY = GetY();
-
- if( fWidth != -1 && fHeight != -1 )
{
- // this is probably a background graphic or something not intended to be a CroppedSprite
- Sprite::StopUsingCustomCoords();
-
- // first find the correct zoom
- Sprite::ScaleToCover( RectF(0, 0, fWidth, fHeight) );
- // find which dimension is larger
- bool bXDimNeedsToBeCropped = GetZoomedWidth() > fWidth+0.01;
-
- if( bXDimNeedsToBeCropped ) // crop X
- {
- float fPercentageToCutOff = (this->GetZoomedWidth() - fWidth) / this->GetZoomedWidth();
- fPercentageToCutOff = max( fPercentageToCutOff-fScaleFudgePercent, 0 );
- float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
-
- // generate a rectangle with new texture coordinates
- RectF fCustomImageRect(
- fPercentageToCutOffEachSide,
- 0,
- 1 - fPercentageToCutOffEachSide,
- 1 );
- SetCustomImageRect( fCustomImageRect );
- }
- else // crop Y
- {
- float fPercentageToCutOff = (this->GetZoomedHeight() - fHeight) / this->GetZoomedHeight();
- fPercentageToCutOff = max( fPercentageToCutOff-fScaleFudgePercent, 0 );
- float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
-
- // generate a rectangle with new texture coordinates
- RectF fCustomImageRect(
- 0,
- fPercentageToCutOffEachSide,
- 1,
- 1 - fPercentageToCutOffEachSide );
- SetCustomImageRect( fCustomImageRect );
- }
- m_size = RageVector2( fWidth, fHeight );
- SetZoom( 1 );
+ return;
+ }
+ // -1 means do nothing because it's the default value and means no
+ // remembered dimensions.
+ if(width == -1 || height == -1)
+ {
+ return;
+ }
+ // The previous implementation used a custom image rect and ended with a
+ // zoom of 1, didn't actually clip unless the dest was larger, and didn't
+ // reverse itself correctly, so it couldn't be used on an image that
+ // changed. It also included a fudge factor which apparently existed
+ // solely to make the function only work when scaling up.
+ // Also, ScaleToClipped and CropTo were both setting RememberedClip, so
+ // after SetTexture, what was a CropTo operation was turned into a
+ // ScaleToClipped operation.
+ // This is much a much simpler implementation without the problems.
+ // The only caveat to this implementation is that GetWidth doesn't factor
+ // in cropping, so someone using GetWidth to put an outline around the
+ // sprite afterwards will end up with the wrong size. -Kyz
+ SetCropTop(0);
+ SetCropBottom(0);
+ SetCropLeft(0);
+ SetCropRight(0);
+ float uzw= GetUnzoomedWidth();
+ float uzh= GetUnzoomedHeight();
+ float xz= width / uzw;
+ float yz= height / uzh;
+ if(xz > yz)
+ {
+ SetZoom(xz);
+ float clip_amount= (1 - (height / (uzh * xz))) / 2;
+ SetCropTop(clip_amount);
+ SetCropBottom(clip_amount);
+ }
+ else
+ {
+ SetZoom(yz);
+ float clip_amount= (1 - (width / (uzw * yz))) / 2;
+ SetCropLeft(clip_amount);
+ SetCropRight(clip_amount);
}
-
- // restore original XY
- SetXY( fOriginalX, fOriginalY );
}
-// magic hurr
-// This code should either be removed or refactored in the future -aj
-void Sprite::CropTo( float fWidth, float fHeight )
+void Sprite::CropTo( float width, float height )
{
- m_fRememberedClipWidth = fWidth;
- m_fRememberedClipHeight = fHeight;
-
+ m_fRememberedCropWidth= width;
+ m_fRememberedCropHeight= height;
if( !m_pTexture )
- return;
-
- // save the original X&Y. We're going to restore them later.
- float fOriginalX = GetX();
- float fOriginalY = GetY();
-
- if( fWidth != -1 && fHeight != -1 )
{
- // this is probably a background graphic or something not intended to be a CroppedSprite
- Sprite::StopUsingCustomCoords();
-
- // first find the correct zoom
- Sprite::ScaleToCover( RectF(0, 0, fWidth, fHeight) );
- // find which dimension is larger
- bool bXDimNeedsToBeCropped = GetZoomedWidth() > fWidth+0.01;
-
- if( bXDimNeedsToBeCropped ) // crop X
- {
- float fPercentageToCutOff = (this->GetZoomedWidth() - fWidth) / this->GetZoomedWidth();
- float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
-
- // generate a rectangle with new texture coordinates
- RectF fCustomImageRect(
- fPercentageToCutOffEachSide,
- 0,
- 1 - fPercentageToCutOffEachSide,
- 1 );
- SetCustomImageRect( fCustomImageRect );
- }
- else // crop Y
- {
- float fPercentageToCutOff = (this->GetZoomedHeight() - fHeight) / this->GetZoomedHeight();
- float fPercentageToCutOffEachSide = fPercentageToCutOff / 2;
-
- // generate a rectangle with new texture coordinates
- RectF fCustomImageRect(
- 0,
- fPercentageToCutOffEachSide,
- 1,
- 1 - fPercentageToCutOffEachSide );
- SetCustomImageRect( fCustomImageRect );
- }
- m_size = RageVector2( fWidth, fHeight );
- SetZoom( 1 );
+ return;
}
-
- // restore original XY
- SetXY( fOriginalX, fOriginalY );
+ // -1 means do nothing because it's the default value and means no
+ // remembered dimensions.
+ if(width == -1 || height == -1)
+ {
+ return;
+ }
+ // The previous implementation was identical to ScaleToClipped's previous
+ // implementation (including the not working correctly part), but without
+ // the fudge factor. Why was a function named "CropTo" changing the scale
+ // of the sprite? That just seems strange and counterintuitive to me, so
+ // this implementation doesn't change the scale at all.
+ // Again, this has the caveat that GetWidth doesn't factor in cropping. -Kyz
+ float zw= GetZoomedWidth();
+ float zh= GetZoomedHeight();
+ float xf= width / zw;
+ float yf= height / zh;
+ float xc= (1 - xf) / 2;
+ float yc= (1 - yf) / 2;
+ if(xf > 1)
+ {
+ xc= 0;
+ }
+ if(yf > 1)
+ {
+ yc= 0;
+ }
+ SetCropLeft(xc);
+ SetCropRight(xc);
+ SetCropTop(yc);
+ SetCropBottom(yc);
}
-// end magic
void Sprite::StretchTexCoords( float fX, float fY )
{
diff --git a/src/Sprite.h b/src/Sprite.h
index 0697fc8aec..435a85742a 100644
--- a/src/Sprite.h
+++ b/src/Sprite.h
@@ -67,10 +67,10 @@ public:
* @brief Scale the Sprite while maintaining the aspect ratio.
*
* It has to fit within and become clipped to the given parameters.
- * @param fWidth the new width.
- * @param fHeight the new height. */
- void ScaleToClipped( float fWidth, float fHeight );
- void CropTo( float fWidth, float fHeight );
+ * @param width the new width.
+ * @param height the new height. */
+ void ScaleToClipped( float width, float height );
+ void CropTo( float width, float height );
// Commands
virtual void PushSelf( lua_State *L );
@@ -124,6 +124,7 @@ private:
// Remembered clipped dimensions are applied on Load().
// -1 means no remembered dimensions;
float m_fRememberedClipWidth, m_fRememberedClipHeight;
+ float m_fRememberedCropWidth, m_fRememberedCropHeight;
float m_fTexCoordVelocityX;
float m_fTexCoordVelocityY;