private static bool ForwardDraw( XSpriteBatch @this, XTexture2D?texture, XRectangle destinationRectangle, XColor color, XRectangle?sourceRectangle = null, float rotation = 0f, XVector2?origin = null, SpriteEffects effects = SpriteEffects.None, float layerDepth = 0f ) { if (!Config.IsEnabled) { return(true); } @this.Draw( texture: texture, destinationRectangle: destinationRectangle, sourceRectangle: sourceRectangle, color: color, rotation: rotation, origin: origin ?? XVector2.Zero, effects: effects, layerDepth: layerDepth ); return(false); }
// Takes the arguments, and checks to see if the texture is padded. If it is, it is forwarded to the correct draw call, avoiding // intervening mods altering the arguments first. internal static bool OnDrawFirst( this XSpriteBatch @this, ref XTexture2D?texture, ref XRectangle destination, ref XRectangle?source, XColor color, float rotation, ref XVector2 origin, ref SpriteEffects effects, float layerDepth, ref ManagedTexture2D?__state ) { if (texture is null) { return(false); } using var watchdogScoped = WatchDog.WatchDog.ScopedWorkingState; /* * if (destination.Width < 0 || destination.Height < 0) { * Debug.Trace("destination invert"); * } * if (source is XRectangle sourceRect && (sourceRect.Width < 0 || sourceRect.Height < 0)) { * Debug.Trace("source invert"); * } */ GetDrawParameters( texture: texture, source: source, bounds: out var sourceRectangle, scaleFactor: out var scaleFactor ); var referenceRectangle = sourceRectangle; Bounds destinationBounds = destination; var expectedScale2D = destinationBounds.ExtentF / sourceRectangle.ExtentF; var expectedScale = EstimateScale(expectedScale2D, scaleFactor); if (!texture.FetchScaledTexture( expectedScale: expectedScale, source: ref sourceRectangle, spriteInstance: out var spriteInstance, create: true )) { return(Continue); } spriteInstance.UpdateReferenceFrame(); if (referenceRectangle.X < 0) { destinationBounds.Left -= referenceRectangle.X; } if (referenceRectangle.Y < 0) { destinationBounds.Top -= referenceRectangle.Y; } var resampledTexture = spriteInstance.Texture !; if (!spriteInstance.Padding.IsZero) { // Convert the draw into the other draw style. This has to be done because the padding potentially has // subpixel accuracy when scaled to the destination rectangle. var originalSize = referenceRectangle.ExtentF; var destinationSize = destinationBounds.ExtentF; var newScale = destinationSize / originalSize; var newPosition = destinationBounds.OffsetF; if ((destinationBounds.Invert.X || destinationBounds.Invert.Y) && DrawState.CurrentRasterizerState.CullMode == CullMode.CullCounterClockwiseFace) { // Winding order is invalid return(Stop); } if (destinationBounds.Invert.X) { effects ^= SpriteEffects.FlipHorizontally; } if (destinationBounds.Invert.Y) { effects ^= SpriteEffects.FlipVertically; } // TODO handle culling here for inverted sprites? @this.Draw( texture: resampledTexture, position: newPosition, sourceRectangle: sourceRectangle, color: color, rotation: rotation, origin: origin, scale: newScale, effects: effects, layerDepth: layerDepth ); return(Stop); } __state = resampledTexture; return(Continue); }