// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System; using System.Collections.Generic; using osu.Framework.Graphics.Colour; using osu.Framework.Graphics.OpenGL.Vertices; using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.Textures; using osuTK; using osuTK.Graphics; namespace osu.Framework.Graphics.Sprites { public partial class SpriteText { internal class SpriteTextDrawNode : TexturedShaderDrawNode { protected new SpriteText Source => (SpriteText)base.Source; private bool shadow; private ColourInfo shadowColour; private Vector2 shadowOffset; private readonly List parts = new List(); public SpriteTextDrawNode(SpriteText source) : base(source) { } public override void ApplyState() { base.ApplyState(); parts.Clear(); parts.AddRange(Source.screenSpaceCharacters); shadow = Source.Shadow; if (shadow) { shadowColour = Source.ShadowColour; shadowOffset = Source.premultipliedShadowOffset; } } public override void Draw(Action vertexAction) { base.Draw(vertexAction); Shader.Bind(); var avgColour = (Color4)DrawColourInfo.Colour.AverageColour; float shadowAlpha = MathF.Pow(Math.Max(Math.Max(avgColour.R, avgColour.G), avgColour.B), 2); //adjust shadow alpha based on highest component intensity to avoid muddy display of darker text. //squared result for quadratic fall-off seems to give the best result. var finalShadowColour = DrawColourInfo.Colour; finalShadowColour.ApplyChild(shadowColour.MultiplyAlpha(shadowAlpha)); for (int i = 0; i < parts.Count; i++) { if (shadow) { var shadowQuad = parts[i].DrawQuad; DrawQuad(parts[i].Texture, new Quad( shadowQuad.TopLeft + shadowOffset, shadowQuad.TopRight + shadowOffset, shadowQuad.BottomLeft + shadowOffset, shadowQuad.BottomRight + shadowOffset), finalShadowColour, vertexAction: vertexAction, inflationPercentage: parts[i].InflationPercentage); } DrawQuad(parts[i].Texture, parts[i].DrawQuad, DrawColourInfo.Colour, vertexAction: vertexAction, inflationPercentage: parts[i].InflationPercentage); } Shader.Unbind(); } } /// /// A character of a provided with screen space draw coordinates. /// internal struct ScreenSpaceCharacterPart { /// /// The screen-space quad for the character to be drawn in. /// public Quad DrawQuad; /// /// Extra padding for the character's texture. /// public Vector2 InflationPercentage; /// /// The texture to draw the character with. /// public Texture Texture; } } }