@@ -44,7 +44,7 @@ pub enum SliceScaleMode {
4444}
4545
4646impl TextureSlicer {
47- /// Computes the 4 corner slices
47+ /// Computes the 4 corner slices: top left, top right, bottom left, bottom right.
4848 #[ must_use]
4949 fn corner_slices ( & self , base_rect : Rect , render_size : Vec2 ) -> [ TextureSlice ; 4 ] {
5050 let coef = render_size / base_rect. size ( ) ;
@@ -116,7 +116,7 @@ impl TextureSlicer {
116116 render_size : Vec2 ,
117117 ) -> [ TextureSlice ; 2 ] {
118118 [
119- // left
119+ // Left
120120 TextureSlice {
121121 texture_rect : Rect {
122122 min : base_rect. min + vec2 ( 0.0 , self . border . top ) ,
@@ -127,24 +127,30 @@ impl TextureSlicer {
127127 } ,
128128 draw_size : vec2 (
129129 bl_corner. draw_size . x ,
130- render_size. y - bl_corner. draw_size . y - tl_corner. draw_size . y ,
130+ render_size. y - ( bl_corner. draw_size . y + tl_corner. draw_size . y ) ,
131131 ) ,
132- offset : vec2 ( -render_size. x + bl_corner. draw_size . x , 0.0 ) / 2.0 ,
132+ offset : vec2 (
133+ -render_size. x + bl_corner. draw_size . x ,
134+ bl_corner. draw_size . y - tl_corner. draw_size . y ,
135+ ) / 2.0 ,
133136 } ,
134- // right
137+ // Right
135138 TextureSlice {
136139 texture_rect : Rect {
137140 min : vec2 (
138141 base_rect. max . x - self . border . right ,
139- base_rect. min . y + self . border . bottom ,
142+ base_rect. min . y + self . border . top ,
140143 ) ,
141- max : vec2 ( base_rect. max . x , base_rect. max . y - self . border . top ) ,
144+ max : vec2 ( base_rect. max . x , base_rect. max . y - self . border . bottom ) ,
142145 } ,
143146 draw_size : vec2 (
144147 br_corner. draw_size . x ,
145148 render_size. y - ( br_corner. draw_size . y + tr_corner. draw_size . y ) ,
146149 ) ,
147- offset : vec2 ( render_size. x - br_corner. draw_size . x , 0.0 ) / 2.0 ,
150+ offset : vec2 (
151+ render_size. x - br_corner. draw_size . x ,
152+ br_corner. draw_size . y - tr_corner. draw_size . y ,
153+ ) / 2.0 ,
148154 } ,
149155 ]
150156 }
@@ -171,7 +177,10 @@ impl TextureSlicer {
171177 render_size. x - ( bl_corner. draw_size . x + br_corner. draw_size . x ) ,
172178 bl_corner. draw_size . y ,
173179 ) ,
174- offset : vec2 ( 0.0 , bl_corner. offset . y ) ,
180+ offset : vec2 (
181+ ( bl_corner. draw_size . x - br_corner. draw_size . x ) / 2.0 ,
182+ bl_corner. offset . y ,
183+ ) ,
175184 } ,
176185 // Top
177186 TextureSlice {
@@ -186,7 +195,10 @@ impl TextureSlicer {
186195 render_size. x - ( tl_corner. draw_size . x + tr_corner. draw_size . x ) ,
187196 tl_corner. draw_size . y ,
188197 ) ,
189- offset : vec2 ( 0.0 , tl_corner. offset . y ) ,
198+ offset : vec2 (
199+ ( tl_corner. draw_size . x - tr_corner. draw_size . x ) / 2.0 ,
200+ tl_corner. offset . y ,
201+ ) ,
190202 } ,
191203 ]
192204 }
@@ -220,22 +232,29 @@ impl TextureSlicer {
220232 } ] ;
221233 }
222234 let mut slices = Vec :: with_capacity ( 9 ) ;
223- // Corners
235+ // Corners are in this order: [TL, TR, BL, BR]
224236 let corners = self . corner_slices ( rect, render_size) ;
225- // Sides
237+ // Vertical Sides: [B, T]
226238 let vertical_sides = self . vertical_side_slices ( & corners, rect, render_size) ;
239+ // Horizontal Sides: [L, R]
227240 let horizontal_sides = self . horizontal_side_slices ( & corners, rect, render_size) ;
228241 // Center
229242 let center = TextureSlice {
230243 texture_rect : Rect {
231- min : rect. min + vec2 ( self . border . left , self . border . bottom ) ,
232- max : vec2 ( rect. max . x - self . border . right , rect. max . y - self . border . top ) ,
244+ min : rect. min + vec2 ( self . border . left , self . border . top ) ,
245+ max : vec2 (
246+ rect. max . x - self . border . right ,
247+ rect. max . y - self . border . bottom ,
248+ ) ,
233249 } ,
234250 draw_size : vec2 (
235251 render_size. x - ( corners[ 2 ] . draw_size . x + corners[ 3 ] . draw_size . x ) ,
236252 render_size. y - ( corners[ 2 ] . draw_size . y + corners[ 0 ] . draw_size . y ) ,
237253 ) ,
238- offset : Vec2 :: ZERO ,
254+ offset : Vec2 :: new (
255+ ( corners[ 0 ] . draw_size . x - corners[ 3 ] . draw_size . x ) / 2.0 ,
256+ ( corners[ 2 ] . draw_size . y - corners[ 0 ] . draw_size . y ) / 2.0 ,
257+ ) ,
239258 } ;
240259
241260 slices. extend ( corners) ;
@@ -279,3 +298,148 @@ impl Default for TextureSlicer {
279298 }
280299 }
281300}
301+
302+ #[ cfg( test) ]
303+ mod test {
304+ use super :: * ;
305+ #[ test]
306+ fn test_horizontal_sizes_uniform ( ) {
307+ let slicer = TextureSlicer {
308+ border : BorderRect {
309+ left : 10. ,
310+ right : 10. ,
311+ top : 10. ,
312+ bottom : 10. ,
313+ } ,
314+ center_scale_mode : SliceScaleMode :: Stretch ,
315+ sides_scale_mode : SliceScaleMode :: Stretch ,
316+ max_corner_scale : 1.0 ,
317+ } ;
318+ let base_rect = Rect {
319+ min : Vec2 :: ZERO ,
320+ max : Vec2 :: splat ( 50. ) ,
321+ } ;
322+ let render_rect = Vec2 :: splat ( 100. ) ;
323+ let slices = slicer. corner_slices ( base_rect, render_rect) ;
324+ assert_eq ! (
325+ slices[ 0 ] ,
326+ TextureSlice {
327+ texture_rect: Rect {
328+ min: Vec2 :: ZERO ,
329+ max: Vec2 :: splat( 10.0 )
330+ } ,
331+ draw_size: Vec2 :: new( 10.0 , 10.0 ) ,
332+ offset: Vec2 :: new( -45.0 , 45.0 ) ,
333+ }
334+ ) ;
335+ }
336+
337+ #[ test]
338+ fn test_horizontal_sizes_non_uniform_bigger ( ) {
339+ let slicer = TextureSlicer {
340+ border : BorderRect {
341+ left : 20. ,
342+ right : 10. ,
343+ top : 10. ,
344+ bottom : 10. ,
345+ } ,
346+ center_scale_mode : SliceScaleMode :: Stretch ,
347+ sides_scale_mode : SliceScaleMode :: Stretch ,
348+ max_corner_scale : 1.0 ,
349+ } ;
350+ let base_rect = Rect {
351+ min : Vec2 :: ZERO ,
352+ max : Vec2 :: splat ( 50. ) ,
353+ } ;
354+ let render_rect = Vec2 :: splat ( 100. ) ;
355+ let slices = slicer. corner_slices ( base_rect, render_rect) ;
356+ assert_eq ! (
357+ slices[ 0 ] ,
358+ TextureSlice {
359+ texture_rect: Rect {
360+ min: Vec2 :: ZERO ,
361+ max: Vec2 :: new( 20.0 , 10.0 )
362+ } ,
363+ draw_size: Vec2 :: new( 20.0 , 10.0 ) ,
364+ offset: Vec2 :: new( -40.0 , 45.0 ) ,
365+ }
366+ ) ;
367+ }
368+
369+ #[ test]
370+ fn test_horizontal_sizes_non_uniform_smaller ( ) {
371+ let slicer = TextureSlicer {
372+ border : BorderRect {
373+ left : 5. ,
374+ right : 10. ,
375+ top : 10. ,
376+ bottom : 10. ,
377+ } ,
378+ center_scale_mode : SliceScaleMode :: Stretch ,
379+ sides_scale_mode : SliceScaleMode :: Stretch ,
380+ max_corner_scale : 1.0 ,
381+ } ;
382+ let rect = Rect {
383+ min : Vec2 :: ZERO ,
384+ max : Vec2 :: splat ( 50. ) ,
385+ } ;
386+ let render_size = Vec2 :: splat ( 100. ) ;
387+ let corners = slicer. corner_slices ( rect, render_size) ;
388+
389+ let vertical_sides = slicer. vertical_side_slices ( & corners, rect, render_size) ;
390+ assert_eq ! (
391+ corners[ 0 ] ,
392+ TextureSlice {
393+ texture_rect: Rect {
394+ min: Vec2 :: ZERO ,
395+ max: Vec2 :: new( 5.0 , 10.0 )
396+ } ,
397+ draw_size: Vec2 :: new( 5.0 , 10.0 ) ,
398+ offset: Vec2 :: new( -47.5 , 45.0 ) ,
399+ }
400+ ) ;
401+ assert_eq ! (
402+ vertical_sides[ 1 ] , /* top */
403+ TextureSlice {
404+ texture_rect: Rect {
405+ min: Vec2 :: new( 5.0 , 0.0 ) ,
406+ max: Vec2 :: new( 40.0 , 10.0 )
407+ } ,
408+ draw_size: Vec2 :: new( 85.0 , 10.0 ) ,
409+ offset: Vec2 :: new( -2.5 , 45.0 ) ,
410+ }
411+ ) ;
412+ }
413+
414+ #[ test]
415+ fn test_horizontal_sizes_non_uniform_zero ( ) {
416+ let slicer = TextureSlicer {
417+ border : BorderRect {
418+ left : 0. ,
419+ right : 10. ,
420+ top : 10. ,
421+ bottom : 10. ,
422+ } ,
423+ center_scale_mode : SliceScaleMode :: Stretch ,
424+ sides_scale_mode : SliceScaleMode :: Stretch ,
425+ max_corner_scale : 1.0 ,
426+ } ;
427+ let base_rect = Rect {
428+ min : Vec2 :: ZERO ,
429+ max : Vec2 :: splat ( 50. ) ,
430+ } ;
431+ let render_rect = Vec2 :: splat ( 100. ) ;
432+ let slices = slicer. corner_slices ( base_rect, render_rect) ;
433+ assert_eq ! (
434+ slices[ 0 ] ,
435+ TextureSlice {
436+ texture_rect: Rect {
437+ min: Vec2 :: ZERO ,
438+ max: Vec2 :: new( 0.0 , 10.0 )
439+ } ,
440+ draw_size: Vec2 :: new( 0.0 , 10.0 ) ,
441+ offset: Vec2 :: new( -50.0 , 45.0 ) ,
442+ }
443+ ) ;
444+ }
445+ }
0 commit comments