namespace Sandbox.UI; /// /// We share a lot of code between mask-image and background-image - so this handles all image rect calculations. /// internal static class ImageRect { public readonly record struct Result( Vector4 Rect, bool IsCover ); public record struct Input { public Texture Image; public Rect PanelRect; public Length? ImageSizeX; public Length? ImageSizeY; public Length? ImagePositionX; public Length? ImagePositionY; public float ScaleToScreen; public Length DefaultSize; } public static Result Calculate( Input input ) { var x = 0.0f; var y = 0.0f; var w = (float)input.Image.Width; var h = (float)input.Image.Height; var sizeX = input.ImageSizeX ?? input.DefaultSize; var aspect = h / w; if ( input.ImageSizeX.Value.Unit == LengthUnit.Undefined ) sizeX = input.DefaultSize; bool cover = false; if ( sizeX.Unit == LengthUnit.Cover ) { w = input.PanelRect.Width; h = w * aspect; if ( h < input.PanelRect.Height ) { h = input.PanelRect.Height; w = h / aspect; } cover = true; } else if ( sizeX.Unit == LengthUnit.Contain ) { w = input.PanelRect.Width; h = w * aspect; if ( h > input.PanelRect.Height ) { h = input.PanelRect.Height; w = h / aspect; } } else if ( sizeX.Unit == LengthUnit.Auto ) { // Already is I think } else if ( sizeX.Unit == LengthUnit.Pixels || sizeX.Unit == LengthUnit.Percentage ) { w = input.ImageSizeX?.GetPixels( input.PanelRect.Width ) ?? w; h = input.ImageSizeY?.GetPixels( input.PanelRect.Height ) ?? h; // scale to screen if ( input.ImageSizeX?.Unit == LengthUnit.Pixels ) w *= input.ScaleToScreen; if ( input.ImageSizeY?.Unit == LengthUnit.Pixels ) h *= input.ScaleToScreen; } x = input.ImagePositionX?.GetPixels( input.PanelRect.Width, w ) ?? x; y = input.ImagePositionY?.GetPixels( input.PanelRect.Height, h ) ?? y; var res = new Result( new Vector4( x, y, w, h ), cover ); return res; } }