using Annulus; using Azimuth; using Blacklight.Core; using Glass.Blacklight; using Prism; namespace Glass.Testbed.TestCases.Text { /// /// Labels tinted by a rainbow texture, so each glyph takes its color from where it sits rather than one color for /// the whole text. /// public class RainbowTextTestCase : TestCase { // A power of two, since D3D9 hardware with only conditional non-power-of-two support can't repeat other sizes. private const int PixelsPerCycle = 512; private const int PixelsPerSecond = 128; private const string Paragraph = "Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod " + "tempor incididunt ut labore et dolore magna aliqua."; private readonly World world; public RainbowTextTestCase(World world) { this.world = world; } /// /// Returns a one pixel tall strip running once through the rainbow, for a tint texture to repeat across the /// screen. /// private BlacklightGlassTexture RainbowStrip() { var rgba = new byte[PixelsPerCycle * DecodedImage.BytesPerPixel]; for (int x = 0; x < PixelsPerCycle; ++x) { Color color = new Hsv((double)x / PixelsPerCycle, 1, 1).ToColor(); int offset = x * DecodedImage.BytesPerPixel; rgba[offset] = color.Red; rgba[offset + 1] = color.Green; rgba[offset + 2] = color.Blue; rgba[offset + 3] = 255; } var image = new DecodedImage(rgba, new System.Drawing.Size(PixelsPerCycle, 1)); return new BlacklightGlassTexture { Texture = world.window.CreateTexture(image) }; } /// /// Returns a label whose rainbow slides along, sized to the text and still at the origin. /// private static Label SlidingLabel(TextMaterialStyle style, string text, Constraints constraints) { var label = new Label(new ScrollingTintText(style, text, PixelsPerSecond, PixelsPerCycle)); label.Bounds = Rect.FromPositionAndSize(Vector.Zero, label.PreferredSize(constraints)); return label; } protected override void Populate() { AddCaption("Tinted by a rainbow texture sliding across the screen, so color follows position"); var rainbow = new TextMaterialStyle { Font = Fonts.Philosopher64, TintColor = Colors.White, TintTexture = RainbowStrip(), Multiline = false, }; var title = SlidingLabel(rainbow, "Rainbow text", Constraints.Unbounded); title.Bounds = title.Bounds.WithPosition(ContentAggregator.NewRow(title.Bounds.Height).TopLeft); Add(title); AddCaption("Wrapped, so the colors line up down the lines too"); var paragraph = SlidingLabel(rainbow with { Font = Fonts.Philosopher32, Multiline = true }, Paragraph, Constraints.Loose(new Vector(PixelsPerCycle, Scalar.PositiveInfinity))); paragraph.Bounds = paragraph.Bounds.WithPosition(ContentAggregator.NewRow(paragraph.Bounds.Height).TopLeft); Add(paragraph); AddCaption("Pinned to the screen (left) or carried with the label (right), so only the right one starts " + "from the same color at its left edge"); var screenSpace = rainbow with { Font = Fonts.Philosopher32 }; var modelSpace = screenSpace with { TintSpace = Glass.TintSpace.Model }; Rect pair = ContentAggregator.NewRow(48); Label[] pairLabels = { SlidingLabel(screenSpace, "Screen space", Constraints.Unbounded), SlidingLabel(modelSpace, "Model space", Constraints.Unbounded), }; foreach (Label label in pairLabels) { label.Bounds = label.Bounds.WithPosition(pair.NewCol(label.Bounds.Width, margin: 40).TopLeft); Add(label); } } } }