/// <summary> /// Tries to increase a component of the 16-bit color by the given value, /// starting from the green component with the highest value range. /// </summary> /// <param name="color">The 16-bit color to increase.</param> /// <param name="value">The value of how much to attempt to increase a component.</param> /// <returns>True if any of the components could be increased by the given value, /// false otherwise.</returns> private static bool TryIncrease(ref Color565 color, int value) { const int maxValue6Bit = 63; const int maxValue5Bit = 31; if (color.G + value > 0 && color.G + value <= maxValue6Bit) { color = Color565.FromRgb(color.R, color.G + value, color.B); return(true); } if (color.R + value > 0 && color.R + value <= maxValue5Bit) { color = Color565.FromRgb(color.R + value, color.G, color.B); return(true); } if (color.B + value > 0 && color.B + value <= maxValue5Bit) { color = Color565.FromRgb(color.R, color.G, color.B + value); return(true); } return(false); }
public void DrawString(int x, int y, string s, Color565 foreground, Color565 background, Font font) { var currentX = x; char[] chars = s.ToCharArray(); foreach (char c in chars) { var character = font.GetFontData(c); if (c == '\n') //line feed { y += character.Height; } else if (c == '\r') //carriage return { currentX = x; } else { if (currentX + character.Width > Width) { currentX = x; //start over at the left and go to a new line. y += character.Height; } DrawChar(currentX, y, foreground, background, character); currentX += character.Width + character.Space; } } }
/// <summary> /// Instantiates a <see cref="BC1BlockData"/> from compressed BC1 block data. /// </summary> /// <param name="bytes">The data of a BC1 compressed block.</param> public static BC1BlockData FromBytes(byte[] bytes) { Debug.Assert(bytes.Length == BlockFormat.BC1ByteSize, "Mismatching number of bytes for format."); byte c0Low = bytes[0]; byte c0Hi = bytes[1]; byte c1Low = bytes[2]; byte c1Hi = bytes[3]; byte[] indexes = new byte[4]; indexes[0] = bytes[4]; indexes[1] = bytes[5]; indexes[2] = bytes[6]; indexes[3] = bytes[7]; var block = new BC1BlockData(); block.Color0 = Color565.FromValue((ushort)((c0Hi << 8) | c0Low)); block.Color1 = Color565.FromValue((ushort)((c1Hi << 8) | c1Low)); for (int p = 0, row = 0; p < BlockFormat.TexelCount; p += BlockFormat.Dimension, ++row) { block.ColorIndexes[p] = indexes[row] & 0x03; block.ColorIndexes[p + 1] = (indexes[row] >> 2) & 0x03; block.ColorIndexes[p + 2] = (indexes[row] >> 4) & 0x03; block.ColorIndexes[p + 3] = (indexes[row] >> 6) & 0x03; } return(block); }
public void FillScreen(Color565 color) { lock (this) { DrawRect(0, Width - 1, 0, Height - 1, color); } }
/// <summary> /// Converts the 32-bit color into a 16-bit R5:G6:B5 color by shifting the bits right for /// each color component. /// </summary> public static Color565 To16Bit(Color color) { int r = color.R >> 3; int g = color.G >> 2; int b = color.B >> 3; return(Color565.FromRgb(r, g, b)); }
public void ConstructFrom32BitIntegers() { var color = Color565.FromRgb(10, 51, 23); Assert.AreEqual(10, color.R); Assert.AreEqual(51, color.G); Assert.AreEqual(23, color.B); }
/// <summary> /// Blends the two colors by taking the average of each color component. /// </summary> public static Color565 Blend(Color565 a, Color565 b) { var c = BlendComponents( new[] { a.R, a.G, a.B }, new[] { b.R, b.G, b.B }); return(Color565.FromRgb(c[0], c[1], c[2])); }
public void SetPixel(int x, int y, Color565 color) { lock (this) { SetWindow(x, x, y, y); SendData((ushort)color); } }
/// <summary> /// https://social.msdn.microsoft.com/Forums/vstudio/en-US/5dd48231-22d4-47c4-a52c-c0c7d6fe8f52/creating-color-interpolation-by-using-a-class?forum=csharpgeneral /// </summary> public static Color565 LerpTwoThirds(Color565 a, Color565 b) { var c = LerpComponents( new[] { a.R, a.G, a.B }, new[] { b.R, b.G, b.B }); return(FromRgb(c[0], c[1], c[2])); }
/// <summary> /// https://stackoverflow.com/questions/3722307/is-there-an-easy-way-to-blend-two-system-drawing-color-values /// </summary> public static Color565 Blend(Color565 color0, Color565 color1) { var c = BlendComponents( new[] { color0.R, color0.G, color0.B }, new[] { color1.R, color1.G, color1.B }); return(FromRgb(c[0], c[1], c[2])); }
public void DrawPixel(UInt16 x, UInt16 y, Color565 color) { lock (this) { SetWindow(x, x, y, y); SendData((ushort)color); } }
public void ConstructFromBytes() { var color = Color565.FromRgb((byte)10, (byte)51, (byte)23); Assert.AreEqual(10, color.R); Assert.AreEqual(51, color.G); Assert.AreEqual(23, color.B); }
public void ConstructFrom16BitUnsignedInteger() { var color = Color565.FromValue(22135); Assert.AreEqual(10, color.R); Assert.AreEqual(51, color.G); Assert.AreEqual(23, color.B); Assert.AreEqual(22135, color.Value); }
/// <summary> /// Creates a BC1 color table from two 16-bit reference colors for 1-bit alpha mode. /// The table contains four 16-bit colors where the third color is a blend between the /// two reference colors and the last color is full black #0000. /// </summary> /// <param name="color0">The first reference color.</param> /// <param name="color1">The second reference color.</param> public static Color565[] CreateFor1BitAlpha(Color565 color0, Color565 color1) { var colors = new Color565[4]; colors[0] = color0; colors[1] = color1; colors[2] = ColorUtility.Blend(color0, color1); colors[3] = Color565.Black; return(colors); }
public void Lerp16BitColors() { var a = Color565.FromRgb(10, 60, 20); var b = Color565.FromRgb(30, 60, 15); var expected = Color565.FromRgb(23, 60, 17); var result = ColorUtility.LerpTwoThirds(a, b); Assert.AreEqual(expected, result); }
public void Blend16BitColors() { var a = Color565.FromRgb(30, 60, 20); var b = Color565.FromRgb(20, 60, 25); var expected = Color565.FromRgb(25, 60, 23); var result = ColorUtility.Blend(a, b); Assert.AreEqual(expected, result); }
/// <summary> /// Creates a BC1 color table from two 16-bit reference colors. The table contains /// four 16-bit colors where the third and fourth colors are linear interpolations /// between the two reference colors. /// </summary> /// <param name="color0">The first reference color.</param> /// <param name="color1">The second reference color.</param> public static Color565[] Create(Color565 color0, Color565 color1) { var colors = new Color565[4]; colors[0] = color0; colors[1] = color1; colors[2] = ColorUtility.LerpTwoThirds(color1, color0); colors[3] = ColorUtility.LerpTwoThirds(color0, color1); return(colors); }
/// <summary> /// Tries to differentiate the two colors by one integer value. Does nothing if the /// integer values of the two colors are different. /// </summary> /// <param name="min">The color which is decreased by one, if increasing /// <code>max</code> fails.</param> /// <param name="max">The color which is increased by one.</param> public static void TryDifferentiateByOne(ref Color565 min, ref Color565 max) { if (min.Value == max.Value) { if (!TryIncrease(ref max, 1)) { TryIncrease(ref min, -1); } } }
public static Color565[] To16Bit(Color[] colors) { var colors16 = new Color565[colors.Length]; for (int i = 0; i < colors.Length; ++i) { colors16[i] = ColorUtility.To16Bit(colors[i]); } return(colors16); }
public void DifferentiationDoesNothingWhenColorsAreDifferent() { var minOriginal = Color565.FromRgb(15, 31, 21); var maxOriginal = Color565.FromRgb(13, 24, 14); var min = minOriginal; var max = maxOriginal; ColorUtility.TryDifferentiateByOne(ref min, ref max); Assert.AreEqual(minOriginal, min); Assert.AreEqual(maxOriginal, max); }
public void DifferentiationIncreasesMaxColorByOneWhenMaxCanBeIncreased() { var minOriginal = Color565.FromRgb(15, 43, 9); var maxOriginal = Color565.FromRgb(15, 43, 9); var min = minOriginal; var max = maxOriginal; ColorUtility.TryDifferentiateByOne(ref min, ref max); Assert.AreEqual(minOriginal, min); Assert.AreEqual(Color565.FromRgb(15, 44, 9), max); }
public void ConstructionClampsComponentsForBytes() { var expected = Color565.FromRgb((byte)31, (byte)63, (byte)31); var color1 = Color565.FromRgb((byte)255, (byte)255, (byte)255); var color2 = Color565.FromRgb((byte)150, (byte)230, (byte)130); Assert.AreEqual(expected, color1); Assert.AreEqual(expected, color2); Assert.AreEqual(MaxValue16Bit, color1.Value); Assert.AreEqual(MaxValue16Bit, color2.Value); }
public void DifferentiationDecreasesMinColorByOneWhenMaxCannotBeIncreased() { var minOriginal = Color565.FromRgb(31, 63, 31); var maxOriginal = Color565.FromRgb(31, 63, 31); var min = minOriginal; var max = maxOriginal; ColorUtility.TryDifferentiateByOne(ref min, ref max); Assert.AreEqual(Color565.FromRgb(31, 62, 31), min); Assert.AreEqual(maxOriginal, max); }
public void DrawCircle(UInt16 x0, UInt16 y0, UInt16 radius, Color565 color) { for (int y = -radius; y <= radius; y++) { for (int x = -radius; x <= radius; x++) { if (x * x + y * y <= radius * radius) { DrawPixel((UInt16)(x + x0), (UInt16)(y + y0), color); } } } }
/// <summary> /// Instantiates a <see cref="BC2BlockData"/> from compressed BC2 block data. /// </summary> /// <param name="bytes">The data of a BC2 compressed block.</param> public static BC2BlockData FromBytes(byte[] bytes) { Debug.Assert(bytes.Length == BlockFormat.BC2ByteSize, "Mismatching number of bytes for format."); byte[,] alphas = new byte[4, 2]; alphas[0, 0] = bytes[0]; alphas[0, 1] = bytes[1]; alphas[1, 0] = bytes[2]; alphas[1, 1] = bytes[3]; alphas[2, 0] = bytes[4]; alphas[2, 1] = bytes[5]; alphas[3, 0] = bytes[6]; alphas[3, 1] = bytes[7]; byte c0Low = bytes[8]; byte c0Hi = bytes[9]; byte c1Low = bytes[10]; byte c1Hi = bytes[11]; byte[] indexes = new byte[4]; indexes[0] = bytes[12]; indexes[1] = bytes[13]; indexes[2] = bytes[14]; indexes[3] = bytes[15]; var block = new BC2BlockData(); block.Color0 = Color565.FromValue((ushort)((c0Hi << 8) | c0Low)); block.Color1 = Color565.FromValue((ushort)((c1Hi << 8) | c1Low)); for (int p = 0, row = 0; p < BlockFormat.TexelCount; p += BlockFormat.Dimension, ++row) { int a = p; int b = p + 1; int c = p + 2; int d = p + 3; block.ColorIndexes[a] = indexes[row] & 0x03; block.ColorIndexes[b] = (indexes[row] >> 2) & 0x03; block.ColorIndexes[c] = (indexes[row] >> 4) & 0x03; block.ColorIndexes[d] = (indexes[row] >> 6) & 0x03; block.ColorAlphas[a] = (byte)(alphas[row, 1] & 0x0F); block.ColorAlphas[b] = (byte)((alphas[row, 1] & 0xF0) >> 4); block.ColorAlphas[c] = (byte)(alphas[row, 0] & 0x0F); block.ColorAlphas[d] = (byte)((alphas[row, 0] & 0xF0) >> 4); } return(block); }
public void CalculateDistanceBetween16BitColors() { var a = Color565.FromRgb(10, 16, 9); var b = Color565.FromRgb(20, 63, 31); var expected = Math.Sqrt((10 - 20) * (10 - 20) + (16 - 63) * (16 - 63) + (9 - 31) * (9 - 31)); var result = ColorUtility.Distance(a, b); const double delta = 0.0001d; Assert.AreEqual(expected, result, delta); }
public void Convert32BitColorTo16Bit() { var color1 = Color.FromArgb(74, 207, 231); var expected1 = Color565.FromRgb(9, 51, 28); var color2 = Color.FromArgb(0, 255, 255); var expected2 = Color565.FromRgb(0, 63, 31); var result1 = ColorUtility.To16Bit(color1); var result2 = ColorUtility.To16Bit(color2); Assert.AreEqual(expected1, result1); Assert.AreEqual(expected2, result2); }
public void FormatIsR5G6B5() { var color = Color565.FromRgb(10, 51, 23); // 10 = _0 1010 -> R5 // 51 = 11 0011 -> G6 // 23 = _1 0111 -> B5 // R5 G6 B5 // 0101 0|110 011|1 0111 16-bit layout const int expected = 22135; var value = color.Value; Assert.AreEqual(expected, value); }
public void ConstructionClampsComponentsFor32BitIntegers() { var expected = Color565.FromRgb(31, 63, 31); var color1 = Color565.FromRgb(3455, 23145, 55132); var color2 = Color565.FromRgb(255, 255, 255); var color3 = Color565.FromRgb(150, 230, 130); Assert.AreEqual(expected, color1); Assert.AreEqual(expected, color2); Assert.AreEqual(expected, color3); Assert.AreEqual(MaxValue16Bit, color1.Value); Assert.AreEqual(MaxValue16Bit, color2.Value); Assert.AreEqual(MaxValue16Bit, color3.Value); }
/// <summary> /// Converts the 16-bit color into a 32-bit /// https://stackoverflow.com/questions/14419875/color-conversion-from-16-to-32-and-vice-versa /// </summary> public static Color To32Bit(Color565 color) { int r = color.R << 3; r |= (r & 0xE0) >> 5; int g = color.G << 2; g |= (g & 0xC0) >> 6; int b = color.B << 3; b |= (b & 0xE0) >> 5; return(Color.FromArgb(r, g, b)); }