@@ -126,11 +126,12 @@ int DynamicSprite_GetColorDepth(ScriptDynamicSprite *sds) {
126126 return depth;
127127}
128128
129- void DynamicSprite_Resize (ScriptDynamicSprite *sds, int width, int height) {
130- if ((width < 1 ) || (height < 1 ))
131- quit (" !DynamicSprite.Resize: width and height must be greater than zero" );
129+ void DynamicSprite_Resize (ScriptDynamicSprite *sds, int width, int height)
130+ {
132131 if (sds->slot == 0 )
133132 quit (" !DynamicSprite.Resize: sprite has been deleted" );
133+ if ((width < 1 ) || (height < 1 ))
134+ quit (" !DynamicSprite.Resize: width and height must be greater than zero" );
134135
135136 data_to_game_coords (&width, &height);
136137
@@ -147,11 +148,12 @@ void DynamicSprite_Resize(ScriptDynamicSprite *sds, int width, int height) {
147148 add_dynamic_sprite (sds->slot , std::move (new_pic), (game.SpriteInfos [sds->slot ].Flags & SPF_ALPHACHANNEL) != 0 );
148149}
149150
150- void DynamicSprite_Flip (ScriptDynamicSprite *sds, int direction) {
151- if ((direction < 1 ) || (direction > 3 ))
152- quit (" !DynamicSprite.Flip: invalid direction" );
151+ void DynamicSprite_Flip (ScriptDynamicSprite *sds, int direction)
152+ {
153153 if (sds->slot == 0 )
154154 quit (" !DynamicSprite.Flip: sprite has been deleted" );
155+ if ((direction < 1 ) || (direction > 3 ))
156+ quit (" !DynamicSprite.Flip: invalid direction" );
155157
156158 // resize the sprite to the requested size
157159 Bitmap *sprite = spriteset[sds->slot ];
@@ -164,7 +166,8 @@ void DynamicSprite_Flip(ScriptDynamicSprite *sds, int direction) {
164166 add_dynamic_sprite (sds->slot , std::move (new_pic), (game.SpriteInfos [sds->slot ].Flags & SPF_ALPHACHANNEL) != 0 );
165167}
166168
167- void DynamicSprite_CopyTransparencyMask (ScriptDynamicSprite *sds, int sourceSprite) {
169+ void DynamicSprite_CopyTransparencyMask (ScriptDynamicSprite *sds, int sourceSprite)
170+ {
168171 if (sds->slot == 0 )
169172 quit (" !DynamicSprite.CopyTransparencyMask: sprite has been deleted" );
170173
@@ -200,7 +203,7 @@ void DynamicSprite_ChangeCanvasSize(ScriptDynamicSprite *sds, int width, int hei
200203 if (sds->slot == 0 )
201204 quit (" !DynamicSprite.ChangeCanvasSize: sprite has been deleted" );
202205 if ((width < 1 ) || (height < 1 ))
203- quit (" !DynamicSprite.ChangeCanvasSize: new size is too small " );
206+ quit (" !DynamicSprite.ChangeCanvasSize: width and height must be greater than zero " );
204207
205208 data_to_game_coords (&x, &y);
206209 data_to_game_coords (&width, &height);
@@ -210,23 +213,31 @@ void DynamicSprite_ChangeCanvasSize(ScriptDynamicSprite *sds, int width, int hei
210213 return ; // same canvas size and no offset: no need to do anything
211214
212215 std::unique_ptr<Bitmap> new_pic (BitmapHelper::CreateTransparentBitmap (width, height, sprite->GetColorDepth ()));
213- // blit it into the enlarged image
214216 new_pic->Blit (sprite, 0 , 0 , x, y, sprite->GetWidth (), sprite->GetHeight ());
215217
218+ // replace the bitmap in the sprite set
216219 add_dynamic_sprite (sds->slot , std::move (new_pic), (game.SpriteInfos [sds->slot ].Flags & SPF_ALPHACHANNEL) != 0 );
217220}
218221
219- void DynamicSprite_Crop (ScriptDynamicSprite *sds, int x, int y, int width, int height) {
220- if ((width < 1 ) || (height < 1 ))
221- quit (" !DynamicSprite.Crop: co-ordinates do not make sense" );
222+ void DynamicSprite_Crop (ScriptDynamicSprite *sds, int x, int y, int width, int height)
223+ {
222224 if (sds->slot == 0 )
223225 quit (" !DynamicSprite.Crop: sprite has been deleted" );
226+ if ((width < 1 ) || (height < 1 ))
227+ quit (" !DynamicSprite.Crop: width and height must be greater than zero" );
224228
225229 data_to_game_coords (&x, &y);
226230 data_to_game_coords (&width, &height);
227231
228- if ((width > game.SpriteInfos [sds->slot ].Width ) || (height > game.SpriteInfos [sds->slot ].Height ))
229- quit (" !DynamicSprite.Crop: requested to crop an area larger than the source" );
232+ // Clamp the cropped size to the valid area of the original image
233+ if ((x < 0 ) || (y < 0 ) || (width > game.SpriteInfos [sds->slot ].Width - x) || (height > game.SpriteInfos [sds->slot ].Height - y))
234+ debug_script_warn (" DynamicSprite.Crop: requested to crop to an area outside of the source image: image is %dx%d, crop area %d,%d %dx%d" ,
235+ game.SpriteInfos [sds->slot ].Width , game.SpriteInfos [sds->slot ].Height , x, y, width, height);
236+ Math::ClampLength (x, width, 0 , game.SpriteInfos [sds->slot ].Width );
237+ Math::ClampLength (y, height, 0 , game.SpriteInfos [sds->slot ].Height );
238+
239+ if (width <= 0 || height <= 0 )
240+ return ; // cannot crop to zero size
230241
231242 Bitmap *sprite = spriteset[sds->slot ];
232243 if (sprite->GetWidth () == width && sprite->GetHeight () == height && x == 0 && y == 0 )
@@ -239,20 +250,25 @@ void DynamicSprite_Crop(ScriptDynamicSprite *sds, int x, int y, int width, int h
239250 add_dynamic_sprite (sds->slot , std::move (new_pic), (game.SpriteInfos [sds->slot ].Flags & SPF_ALPHACHANNEL) != 0 );
240251}
241252
242- void DynamicSprite_Rotate (ScriptDynamicSprite *sds, int angle, int width, int height) {
243- if ((angle < 1 ) || (angle > 359 ))
244- quit (" !DynamicSprite.Rotate: invalid angle (must be 1-359)" );
253+ void DynamicSprite_Rotate (ScriptDynamicSprite *sds, int angle, int width, int height)
254+ {
245255 if (sds->slot == 0 )
246256 quit (" !DynamicSprite.Rotate: sprite has been deleted" );
257+ if ((angle < 1 ) || (angle > 359 ))
258+ quit (" !DynamicSprite.Rotate: invalid angle (must be 1-359)" );
259+ if ((width != SCR_NO_VALUE) && (width < 1 ) || (height != SCR_NO_VALUE) && (height < 1 ))
260+ quit (" !DynamicSprite.Rotate: width and height must be greater than zero" );
247261
248262 const int src_width = game.SpriteInfos [sds->slot ].Width ;
249263 const int src_height = game.SpriteInfos [sds->slot ].Height ;
250- if ((width == SCR_NO_VALUE) || (height == SCR_NO_VALUE)) {
264+ if ((width == SCR_NO_VALUE) || (height == SCR_NO_VALUE))
265+ {
251266 Size rot_sz = RotateSize (Size (src_width, src_height), angle);
252267 width = rot_sz.Width ;
253268 height = rot_sz.Height ;
254269 }
255- else {
270+ else
271+ {
256272 data_to_game_coords (&width, &height);
257273 }
258274
0 commit comments