public override void Apply(IComponent component) { if (BackgroundColor.A != 0) { component.RemoveDrawInstructions(d => d.Tag == "bgColor"); var bgColorInstruction = new DrawInstruction( "bgColor", Helper.Content.Textures.WhitePixel, new Rectangle(0, 0, component.Bounds.Width, component.Bounds.Height), null, BackgroundColor, 0f, Vector2.Zero, SpriteEffects.None, 1f); component.AddDrawInstructions(bgColorInstruction); } if (BackgroundImage?.Invoke(component) is Texture2D bgImage) { component.RemoveDrawInstructions(d => d.Tag == "bgImage"); BackgroundBounds = new Rectangle(0, 0, bgImage.Width, bgImage.Height); Rectangle drawBounds = BackgroundBounds.Value; float fitToHeight = (float)component.Bounds.Height / (float)BackgroundBounds.Value.Height; float fitToWidth = (float)component.Bounds.Width / (float)BackgroundBounds.Value.Width; int tileWidth = (int)Math.Ceiling(component.Bounds.Width / (float)drawBounds.Width); int tileHeight = (int)Math.Ceiling(component.Bounds.Height / (float)drawBounds.Height); switch (FillStyle) { case BackgroundFill.Stretch: { drawBounds = new Rectangle(0, 0, component.Bounds.Width, component.Bounds.Height); break; } case BackgroundFill.Contain: { float scale = Math.Min(Math.Min(fitToHeight, fitToWidth), BackgroundMaxScale); int w = (int)(BackgroundBounds.Value.Width * scale); int h = (int)(BackgroundBounds.Value.Height * scale); drawBounds = new Rectangle((component.Bounds.Width - w) / 2, (component.Bounds.Height - h) / 2, w, h); break; } case BackgroundFill.Cover: { float scale = Math.Max(fitToHeight, fitToWidth); drawBounds = new Rectangle(0, 0, (int)(BackgroundBounds.Value.Width * scale), (int)(BackgroundBounds.Value.Height * scale)); break; } case BackgroundFill.TileMap: { drawBounds = new Rectangle(0, 0, drawBounds.Width / 3, drawBounds.Height / 3); break; } case BackgroundFill.Original: case BackgroundFill.Pattern: default: break; } switch (FillStyle) { case BackgroundFill.Stretch: case BackgroundFill.Cover: case BackgroundFill.Contain: case BackgroundFill.Original: { var bgImageInstruction = new DrawInstruction( "bgImage", bgImage, drawBounds, BackgroundSourceRectangle, Color.White * BackgroundOpacity, 0f, Vector2.Zero, SpriteEffects.None, 1f); component.AddDrawInstructions(bgImageInstruction); break; } case BackgroundFill.TileMap: { if (!BackgroundSourceRectangle.HasValue) { BackgroundSourceRectangle = BackgroundBounds; } for (int x = 0; x < tileWidth; x++) { for (int y = 0; y < tileHeight; y++) { int dx = x == 0 ? 0 : x == tileWidth - 1 ? 2 : 1; int dy = y == 0 ? 0 : y == tileHeight - 1 ? 2 : 1; var sWidth = BackgroundSourceRectangle.Value.Width / 3; var sHeight = BackgroundSourceRectangle.Value.Height / 3; var sX = BackgroundSourceRectangle.Value.X; var sY = BackgroundSourceRectangle.Value.Y; var sRect = new Rectangle(sX + (sWidth * dx), sY + (sHeight * dy), sWidth, sHeight); var bgImageInstruction = new DrawInstruction( "bgImage", bgImage, new Rectangle(x * BackgroundBounds.Value.Width, y * BackgroundBounds.Value.Height, BackgroundBounds.Value.Width, BackgroundBounds.Value.Height), sRect, Color.White * BackgroundOpacity, 0f, Vector2.Zero, SpriteEffects.None, 1f); component.AddDrawInstructions(bgImageInstruction); } } break; } case BackgroundFill.Pattern: { for (int x = 0; x < tileWidth; x++) { for (int y = 0; y < tileHeight; y++) { var bgImageInstruction = new DrawInstruction( "bgImage", bgImage, new Rectangle(drawBounds.Width * x, drawBounds.Height * y, drawBounds.Width, drawBounds.Height), BackgroundSourceRectangle, Color.White * BackgroundOpacity, 0f, Vector2.Zero, SpriteEffects.None, 1f); component.AddDrawInstructions(bgImageInstruction); } } break; } } } if (Image?.Invoke(component) is Texture2D image) { var imageInstruction = new DrawInstruction( "image", image, new Rectangle(0, 0, component.Bounds.Width, component.Bounds.Height), new Rectangle(0, 0, image.Width, image.Height), Color.White, 0f, Vector2.Zero, SpriteEffects.None, 1f); component.AddDrawInstructions(imageInstruction); } base.Apply(component); }