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);
}
}
}
}