Add ColorAPI
This commit is contained in:
parent
e3f3296c2d
commit
070211158e
812
sources/Core/Color/ColorAPI.uc
Normal file
812
sources/Core/Color/ColorAPI.uc
Normal file
@ -0,0 +1,812 @@
|
||||
/**
|
||||
* API that provides functions for working with color.
|
||||
* It has a wide range of pre-defined colors and some functions that
|
||||
* allow to quickly assemble color from rgb(a) values, parse it from
|
||||
* a `Text`/string or load it from an alias.
|
||||
* Copyright 2020 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class ColorAPI extends Singleton
|
||||
dependson(Parser)
|
||||
config(AcediaSystem);
|
||||
|
||||
/**
|
||||
* Enumeration for ways to represent `Color` as a `string`.
|
||||
*/
|
||||
enum ColorDisplayType
|
||||
{
|
||||
// Hex format; for pink: #ffc0cb
|
||||
CLRDISPLAY_HEX,
|
||||
// RGB format; for pink: rgb(255,192,203)
|
||||
CLRDISPLAY_RGB,
|
||||
// RGBA format; for opaque pink: rgb(255,192,203,255)
|
||||
CLRDISPLAY_RGBA,
|
||||
// RGB format with tags; for pink: rgb(r=255,g=192,b=203)
|
||||
CLRDISPLAY_RGB_TAG,
|
||||
// RGBA format with tags; for pink: rgb(r=255,g=192,b=203,a=255)
|
||||
CLRDISPLAY_RGBA_TAG
|
||||
};
|
||||
|
||||
// Some useful predefined color values.
|
||||
// They are marked as `config` to allow server admins to mess about with
|
||||
// colors if they want to.
|
||||
// Pink colors
|
||||
var public config const Color Pink;
|
||||
var public config const Color LightPink;
|
||||
var public config const Color HotPink;
|
||||
var public config const Color DeepPink;
|
||||
var public config const Color PaleVioletRed;
|
||||
var public config const Color MediumVioletRed;
|
||||
// Red colors
|
||||
var public config const Color LightSalmon;
|
||||
var public config const Color Salmon;
|
||||
var public config const Color DarkSalmon;
|
||||
var public config const Color LightCoral;
|
||||
var public config const Color IndianRed;
|
||||
var public config const Color Crimson;
|
||||
var public config const Color Firebrick;
|
||||
var public config const Color DarkRed;
|
||||
var public config const Color Red;
|
||||
// Orange colors
|
||||
var public config const Color OrangeRed;
|
||||
var public config const Color Tomato;
|
||||
var public config const Color Coral;
|
||||
var public config const Color DarkOrange;
|
||||
var public config const Color Orange;
|
||||
// Yellow colors
|
||||
var public config const Color Yellow;
|
||||
var public config const Color LightYellow;
|
||||
var public config const Color LemonChiffon;
|
||||
var public config const Color LightGoldenrodYellow;
|
||||
var public config const Color PapayaWhip;
|
||||
var public config const Color Moccasin;
|
||||
var public config const Color PeachPuff;
|
||||
var public config const Color PaleGoldenrod;
|
||||
var public config const Color Khaki;
|
||||
var public config const Color DarkKhaki;
|
||||
var public config const Color Gold;
|
||||
// Brown colors
|
||||
var public config const Color Cornsilk;
|
||||
var public config const Color BlanchedAlmond;
|
||||
var public config const Color Bisque;
|
||||
var public config const Color NavajoWhite;
|
||||
var public config const Color Wheat;
|
||||
var public config const Color Burlywood;
|
||||
var public config const Color TanColor; // `Tan()` already taken by a function
|
||||
var public config const Color RosyBrown;
|
||||
var public config const Color SandyBrown;
|
||||
var public config const Color Goldenrod;
|
||||
var public config const Color DarkGoldenrod;
|
||||
var public config const Color Peru;
|
||||
var public config const Color Chocolate;
|
||||
var public config const Color SaddleBrown;
|
||||
var public config const Color Sienna;
|
||||
var public config const Color Brown;
|
||||
var public config const Color Maroon;
|
||||
// Green colors
|
||||
var public config const Color DarkOliveGreen;
|
||||
var public config const Color Olive;
|
||||
var public config const Color OliveDrab;
|
||||
var public config const Color YellowGreen;
|
||||
var public config const Color LimeGreen;
|
||||
var public config const Color Lime;
|
||||
var public config const Color LawnGreen;
|
||||
var public config const Color Chartreuse;
|
||||
var public config const Color GreenYellow;
|
||||
var public config const Color SpringGreen;
|
||||
var public config const Color MediumSpringGreen;
|
||||
var public config const Color LightGreen;
|
||||
var public config const Color PaleGreen;
|
||||
var public config const Color DarkSeaGreen;
|
||||
var public config const Color MediumAquamarine;
|
||||
var public config const Color MediumSeaGreen;
|
||||
var public config const Color SeaGreen;
|
||||
var public config const Color ForestGreen;
|
||||
var public config const Color Green;
|
||||
var public config const Color DarkGreen;
|
||||
// Cyan colors
|
||||
var public config const Color Aqua;
|
||||
var public config const Color Cyan;
|
||||
var public config const Color LightCyan;
|
||||
var public config const Color PaleTurquoise;
|
||||
var public config const Color Aquamarine;
|
||||
var public config const Color Turquoise;
|
||||
var public config const Color MediumTurquoise;
|
||||
var public config const Color DarkTurquoise;
|
||||
var public config const Color LightSeaGreen;
|
||||
var public config const Color CadetBlue;
|
||||
var public config const Color DarkCyan;
|
||||
var public config const Color Teal;
|
||||
// Blue colors
|
||||
var public config const Color LightSteelBlue;
|
||||
var public config const Color PowderBlue;
|
||||
var public config const Color LightBlue;
|
||||
var public config const Color SkyBlue;
|
||||
var public config const Color LightSkyBlue;
|
||||
var public config const Color DeepSkyBlue;
|
||||
var public config const Color DodgerBlue;
|
||||
var public config const Color CornflowerBlue;
|
||||
var public config const Color SteelBlue;
|
||||
var public config const Color RoyalBlue;
|
||||
var public config const Color Blue;
|
||||
var public config const Color MediumBlue;
|
||||
var public config const Color DarkBlue;
|
||||
var public config const Color Navy;
|
||||
var public config const Color MidnightBlue;
|
||||
// Purple, violet, and magenta colors
|
||||
var public config const Color Lavender;
|
||||
var public config const Color Thistle;
|
||||
var public config const Color Plum;
|
||||
var public config const Color Violet;
|
||||
var public config const Color Orchid;
|
||||
var public config const Color Fuchsia;
|
||||
var public config const Color Magenta;
|
||||
var public config const Color MediumOrchid;
|
||||
var public config const Color MediumPurple;
|
||||
var public config const Color BlueViolet;
|
||||
var public config const Color DarkViolet;
|
||||
var public config const Color DarkOrchid;
|
||||
var public config const Color DarkMagenta;
|
||||
var public config const Color Purple;
|
||||
var public config const Color Indigo;
|
||||
var public config const Color DarkSlateBlue;
|
||||
var public config const Color SlateBlue;
|
||||
var public config const Color MediumSlateBlue;
|
||||
// White colors
|
||||
var public config const Color White;
|
||||
var public config const Color Snow;
|
||||
var public config const Color Honeydew;
|
||||
var public config const Color MintCream;
|
||||
var public config const Color Azure;
|
||||
var public config const Color AliceBlue;
|
||||
var public config const Color GhostWhite;
|
||||
var public config const Color WhiteSmoke;
|
||||
var public config const Color Seashell;
|
||||
var public config const Color Beige;
|
||||
var public config const Color OldLace;
|
||||
var public config const Color FloralWhite;
|
||||
var public config const Color Ivory;
|
||||
var public config const Color AntiqueWhite;
|
||||
var public config const Color Linen;
|
||||
var public config const Color LavenderBlush;
|
||||
var public config const Color MistyRose;
|
||||
// Gray and black colors
|
||||
var public config const Color Gainsboro;
|
||||
var public config const Color LightGray;
|
||||
var public config const Color Silver;
|
||||
var public config const Color DarkGray;
|
||||
var public config const Color Gray;
|
||||
var public config const Color DimGray;
|
||||
var public config const Color LightSlateGray;
|
||||
var public config const Color SlateGray;
|
||||
var public config const Color DarkSlateGray;
|
||||
var public config const Color Eigengrau;
|
||||
var public config const Color Black;
|
||||
|
||||
// Escape code point is used to change output's color and is used in
|
||||
// Unreal Engine's `string`s.
|
||||
var private const int CODEPOINT_ESCAPE;
|
||||
var private const int CODEPOINT_SMALL_A;
|
||||
|
||||
/**
|
||||
* Creates opaque color from (red, green, blue) triplet.
|
||||
*
|
||||
* @param red Red component, range from 0 to 255.
|
||||
* @param green Green component, range from 0 to 255.
|
||||
* @param blue Blue component, range from 0 to 255.
|
||||
* @return `Color` with specified red, green and blue component and
|
||||
* alpha component of `255`.
|
||||
*/
|
||||
public final function Color RGB(byte red, byte green, byte blue)
|
||||
{
|
||||
local Color result;
|
||||
result.r = red;
|
||||
result.g = green;
|
||||
result.b = blue;
|
||||
result.a = 255;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates color from (red, green, blue, alpha) quadruplet.
|
||||
*
|
||||
* @param red Red component, range from 0 to 255.
|
||||
* @param green Green component, range from 0 to 255.
|
||||
* @param blue Blue component, range from 0 to 255.
|
||||
* @param alpha Alpha component, range from 0 to 255.
|
||||
* @return `Color` with specified red, green, blue and alpha component.
|
||||
*/
|
||||
public final function Color RGBA(byte red, byte green, byte blue, byte alpha)
|
||||
{
|
||||
local Color result;
|
||||
result.r = red;
|
||||
result.g = green;
|
||||
result.b = blue;
|
||||
result.a = alpha;
|
||||
return result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two colors for exact equality of red, green and blue components.
|
||||
* Alpha component is ignored.
|
||||
*
|
||||
* @param color1 Color to compare
|
||||
* @param color2 Color to compare
|
||||
* @return `true` if colors' red, green and blue components are equal
|
||||
* and `false` otherwise.
|
||||
*/
|
||||
public final function bool AreEqual(Color color1, Color color2, optional bool fixColors)
|
||||
{
|
||||
if (fixColors) {
|
||||
color1 = FixColor(color1);
|
||||
color2 = FixColor(color2);
|
||||
}
|
||||
if (color1.r != color2.r) return false;
|
||||
if (color1.g != color2.g) return false;
|
||||
if (color1.b != color2.b) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Compares two colors for exact equality of red, green, blue
|
||||
* and alpha components.
|
||||
*
|
||||
* @param color1 Color to compare
|
||||
* @param color2 Color to compare
|
||||
* @return `true` if colors' red, green, blue and alpha components are equal
|
||||
* and `false` otherwise.
|
||||
*/
|
||||
public final function bool AreEqualWithAlpha(Color color1, Color color2, optional bool fixColors)
|
||||
{
|
||||
if (fixColors) {
|
||||
color1 = FixColor(color1);
|
||||
color2 = FixColor(color2);
|
||||
}
|
||||
if (color1.r != color2.r) return false;
|
||||
if (color1.g != color2.g) return false;
|
||||
if (color1.b != color2.b) return false;
|
||||
if (color1.a != color2.a) return false;
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Killing floor's standard methods of rendering colored `string`s
|
||||
* make use of inserting 4-byte sequence into them: first bytes denotes
|
||||
* the start of the sequence, 3 following bytes denote rgb color components.
|
||||
* Unfortunately these methods also have issues with rendering `string`s
|
||||
* if you specify certain values (`0` and `10`) of rgb color components.
|
||||
*
|
||||
* This function "fixes" components by replacing them with close and valid
|
||||
* color component values (adds `1` to the component).
|
||||
*/
|
||||
public final function byte FixColorComponent(byte colorComponent)
|
||||
{
|
||||
if (colorComponent == 0 || colorComponent == 10)
|
||||
{
|
||||
return colorComponent + 1;
|
||||
}
|
||||
return colorComponent;
|
||||
}
|
||||
|
||||
/**
|
||||
* Killing floor's standard methods of rendering colored `string`s
|
||||
* make use of inserting 4-byte sequence into them: first bytes denotes
|
||||
* the start of the sequence, 3 following bytes denote rgb color components.
|
||||
* Unfortunately these methods also have issues with rendering `string`s
|
||||
* if you specify certain values (`0` and `10`) as rgb color components.
|
||||
*
|
||||
* This function "fixes" given `Color`'s components by replacing them with
|
||||
* close and valid color values (using `FixColorComponent()` method),
|
||||
* resulting in a `Color` that looks almost the same, but is suitable to be
|
||||
* included into 4-byte color change sequence.
|
||||
*
|
||||
* Since alpha component is never used in color-change sequences,
|
||||
* it is never affected.
|
||||
*/
|
||||
public final function Color FixColor(Color colorToFix)
|
||||
{
|
||||
colorToFix.r = FixColorComponent(colorToFix.r);
|
||||
colorToFix.g = FixColorComponent(colorToFix.g);
|
||||
colorToFix.b = FixColorComponent(colorToFix.b);
|
||||
return colorToFix;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 4-gyte sequence for color change to a given color.
|
||||
*
|
||||
* To make returned tag work in most sequences, the value of given color is
|
||||
* auto "fixed" (see `FixColor()` for details).
|
||||
* There is an option to skip color fixing, but method will still change
|
||||
* `0` components to `1`, since they cannot otherwise be used in a tag at all.
|
||||
*
|
||||
* Also see `GetColorTagRGB()`.
|
||||
*
|
||||
* @param colorToUse Color to which tag must change the text.
|
||||
* It's alpha value (`colorToUse.a`) is discarded.
|
||||
* @param doNotFixComponents Minimizes changes to color components
|
||||
* (only allows to change `0` components to `1` before creating a tag).
|
||||
* @return `string` containing 4-byte sequence that will swap text's color to
|
||||
* a given one in standard Unreal Engine's UI.
|
||||
*/
|
||||
public final function string GetColorTag(
|
||||
Color colorToUse,
|
||||
optional bool doNotFixComponents)
|
||||
{
|
||||
if (!doNotFixComponents) {
|
||||
colorToUse = FixColor(colorToUse);
|
||||
}
|
||||
colorToUse.r = Max(1, colorToUse.r);
|
||||
colorToUse.g = Max(1, colorToUse.g);
|
||||
colorToUse.b = Max(1, colorToUse.b);
|
||||
return Chr(CODEPOINT_ESCAPE)
|
||||
$ Chr(colorToUse.r)
|
||||
$ Chr(colorToUse.g)
|
||||
$ Chr(colorToUse.b);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns 4-gyte sequence for color change to a given color.
|
||||
*
|
||||
* To make returned tag work in most sequences, the value of given color is
|
||||
* auto "fixed" (see `FixColor()` for details).
|
||||
* There is an option to skip color fixing, but method will still change
|
||||
* `0` components to `1`, since they cannot otherwise be used in a tag at all.
|
||||
*
|
||||
* Also see `GetColorTag()`.
|
||||
*
|
||||
* @param red Red component of color to which tag must
|
||||
* change the text.
|
||||
* @param green Green component of color to which tag must
|
||||
* change the text.
|
||||
* @param blue Blue component of color to which tag must
|
||||
* change the text.
|
||||
* @param doNotFixComponents Minimizes changes to color components
|
||||
* (only allows to change `0` components to `1` before creating a tag).
|
||||
* @return `string` containing 4-byte sequence that will swap text's color to
|
||||
* a given one in standard Unreal Engine's UI.
|
||||
*/
|
||||
public final function string GetColorTagRGB(
|
||||
int red,
|
||||
int green,
|
||||
int blue,
|
||||
optional bool doNotFixComponents)
|
||||
{
|
||||
if (!doNotFixComponents)
|
||||
{
|
||||
red = FixColorComponent(red);
|
||||
green = FixColorComponent(green);
|
||||
blue = FixColorComponent(blue);
|
||||
}
|
||||
red = Max(1, red);
|
||||
green = Max(1, green);
|
||||
blue = Max(1, blue);
|
||||
return Chr(CODEPOINT_ESCAPE) $ Chr(red) $ Chr(green) $ Chr(blue);
|
||||
}
|
||||
|
||||
// Helper function that converts `byte` with values between 0 and 15 into
|
||||
// a corresponding hex letter
|
||||
private final function string ByteToHexCharacter(byte component)
|
||||
{
|
||||
component = Clamp(component, 0, 15);
|
||||
if (component < 10) {
|
||||
return string(component);
|
||||
}
|
||||
return Chr(component - 10 + CODEPOINT_SMALL_A);
|
||||
}
|
||||
|
||||
// `byte` to `string` in hex
|
||||
private final function string ComponentToHex(byte component)
|
||||
{
|
||||
local byte high4Bits, low4Bits;
|
||||
low4Bits = component % 16;
|
||||
if (component >= 16) {
|
||||
high4Bits = (component - low4Bits) / 16;
|
||||
}
|
||||
else {
|
||||
high4Bits = 0;
|
||||
}
|
||||
return ByteToHexCharacter(high4Bits) $ ByteToHexCharacter(low4Bits);
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays given color as a string in a given style
|
||||
* (hex color representation by default).
|
||||
*
|
||||
* @param colorToConvert Color to display as a `string`.
|
||||
* @param displayType `enum` value, describing how should color
|
||||
* be displayed.
|
||||
* @return `string` representation of a given color in a given style.
|
||||
*/
|
||||
public final function string ToStringType(
|
||||
Color colorToConvert,
|
||||
optional ColorDisplayType displayType)
|
||||
{
|
||||
if (displayType == CLRDISPLAY_HEX) {
|
||||
return "#" $ ComponentToHex(colorToConvert.r)
|
||||
$ ComponentToHex(colorToConvert.g)
|
||||
$ ComponentToHex(colorToConvert.b);
|
||||
}
|
||||
else if (displayType == CLRDISPLAY_RGB)
|
||||
{
|
||||
return "rgb(" $ string(colorToConvert.r) $ ","
|
||||
$ string(colorToConvert.g) $ ","
|
||||
$ string(colorToConvert.b) $ ")";
|
||||
}
|
||||
else if (displayType == CLRDISPLAY_RGBA)
|
||||
{
|
||||
return "rgba(" $ string(colorToConvert.r) $ ","
|
||||
$ string(colorToConvert.g) $ ","
|
||||
$ string(colorToConvert.b) $ ","
|
||||
$ string(colorToConvert.a) $ ")";
|
||||
}
|
||||
else if (displayType == CLRDISPLAY_RGB_TAG)
|
||||
{
|
||||
return "rgb(r=" $ string(colorToConvert.r) $ ","
|
||||
$ "g=" $ string(colorToConvert.g) $ ","
|
||||
$ "b=" $ string(colorToConvert.b) $ ")";
|
||||
}
|
||||
//else if (displayType == CLRDISPLAY_RGBA_TAG)
|
||||
return "rgba(r=" $ string(colorToConvert.r) $ ","
|
||||
$ "g=" $ string(colorToConvert.g) $ ","
|
||||
$ "b=" $ string(colorToConvert.b) $ ","
|
||||
$ "a=" $ string(colorToConvert.a) $ ")";
|
||||
}
|
||||
|
||||
/**
|
||||
* Displays given color as a string in RGB or RGBA format, depending on
|
||||
* whether color is opaque.
|
||||
*
|
||||
* @param colorToConvert Color to display as a `string` in `CLRDISPLAY_RGB`
|
||||
* style if `colorToConvert.a == 255` and `CLRDISPLAY_RGBA` otherwise.
|
||||
* @return `string` representation of a given color in a given style.
|
||||
*/
|
||||
public final function string ToString(Color colorToConvert)
|
||||
{
|
||||
if (colorToConvert.a < 255) {
|
||||
return ToStringType(colorToConvert, CLRDISPLAY_RGBA);
|
||||
}
|
||||
return ToStringType(colorToConvert, CLRDISPLAY_RGB);
|
||||
}
|
||||
|
||||
// Parses color in `CLRDISPLAY_RGB` and `CLRDISPLAY_RGB_TAG` representations.
|
||||
private final function Color ParseRGB(Parser parser)
|
||||
{
|
||||
local int redComponent;
|
||||
local int greenComponent;
|
||||
local int blueComponent;
|
||||
local Parser.ParserState initialParserState;
|
||||
initialParserState = parser.GetCurrentState();
|
||||
parser.Match("rgb(", true)
|
||||
.MInteger(redComponent).Match(",")
|
||||
.MInteger(greenComponent).Match(",")
|
||||
.MInteger(blueComponent).Match(")");
|
||||
if (!parser.Ok())
|
||||
{
|
||||
parser.RestoreState(initialParserState).Match("rgb(", true)
|
||||
.Match("r=", true).MInteger(redComponent).Match(",")
|
||||
.Match("g=", true).MInteger(greenComponent).Match(",")
|
||||
.Match("b=", true).MInteger(blueComponent).Match(")");
|
||||
}
|
||||
return RGB(redComponent, greenComponent, blueComponent);
|
||||
}
|
||||
|
||||
// Parses color in `CLRDISPLAY_RGBA` and `CLRDISPLAY_RGBA_TAG` representations.
|
||||
private final function Color ParseRGBA(Parser parser)
|
||||
{
|
||||
local int redComponent;
|
||||
local int greenComponent;
|
||||
local int blueComponent;
|
||||
local int alphaComponent;
|
||||
local Parser.ParserState initialParserState;
|
||||
initialParserState = parser.GetCurrentState();
|
||||
parser.Match("rgba(", true)
|
||||
.MInteger(redComponent).Match(",")
|
||||
.MInteger(greenComponent).Match(",")
|
||||
.MInteger(blueComponent).Match(",")
|
||||
.MInteger(alphaComponent).Match(")");
|
||||
if (!parser.Ok())
|
||||
{
|
||||
parser.RestoreState(initialParserState).Match("rgba(", true)
|
||||
.Match("r=", true).MInteger(redComponent).Match(",")
|
||||
.Match("g=", true).MInteger(greenComponent).Match(",")
|
||||
.Match("b=", true).MInteger(blueComponent).Match(",")
|
||||
.Match("a=", true).MInteger(alphaComponent).Match(")");
|
||||
}
|
||||
return RGBA(redComponent, greenComponent, blueComponent, alphaComponent);
|
||||
}
|
||||
|
||||
// Parses color in `CLRDISPLAY_HEX` representation.
|
||||
private final function Color ParseHexColor(Parser parser)
|
||||
{
|
||||
local int redComponent;
|
||||
local int greenComponent;
|
||||
local int blueComponent;
|
||||
parser.Match("#")
|
||||
.MUnsignedInteger(redComponent, 16, 2)
|
||||
.MUnsignedInteger(greenComponent, 16, 2)
|
||||
.MUnsignedInteger(blueComponent, 16, 2);
|
||||
return RGB(redComponent, greenComponent, blueComponent);
|
||||
}
|
||||
|
||||
/**
|
||||
* Uses given parser to try and parse a color in any of the
|
||||
* `ColorDisplayType` representations.
|
||||
*
|
||||
* @param parser Parser that method would use to parse color from
|
||||
* wherever it left. It's confirmed state will not be changed.
|
||||
* Do not treat `parser` bein in a non-failed state as a confirmation of
|
||||
* successful parsing: color parsing might fail regardless.
|
||||
* Check return value for that.
|
||||
* @param resultingColor Parsed color will be written here if parsing is
|
||||
* successful, otherwise value is undefined.
|
||||
* If parsed color did not specify alpha component - 255 will be used.
|
||||
* @return `true` if parsing was successful and false otherwise.
|
||||
*/
|
||||
public final function bool ParseWith(Parser parser, out Color resultingColor)
|
||||
{
|
||||
local bool successfullyParsed;
|
||||
local string colorAlias;
|
||||
local Parser colorParser;
|
||||
local Parser.ParserState initialParserState;
|
||||
if (parser == none) return false;
|
||||
resultingColor.a = 0xff;
|
||||
colorParser = parser;
|
||||
initialParserState = parser.GetCurrentState();
|
||||
if (parser.Match("$").MUntil(colorAlias,, true).Ok())
|
||||
{
|
||||
colorParser = _.text.ParseString(_.alias.TryColor(colorAlias));
|
||||
initialParserState = colorParser.GetCurrentState();
|
||||
}
|
||||
else {
|
||||
parser.RestoreState(initialParserState);
|
||||
}
|
||||
resultingColor = ParseRGB(colorParser);
|
||||
if (!colorParser.Ok())
|
||||
{
|
||||
colorParser.RestoreState(initialParserState);
|
||||
resultingColor = ParseRGBA(colorParser);
|
||||
}
|
||||
if (!colorParser.Ok())
|
||||
{
|
||||
colorParser.RestoreState(initialParserState);
|
||||
resultingColor = ParseHexColor(colorParser);
|
||||
}
|
||||
successfullyParsed = colorParser.Ok();
|
||||
if (colorParser != parser) {
|
||||
_.memory.Free(colorParser);
|
||||
}
|
||||
return successfullyParsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a color in any of the `ColorDisplayType` representations from the
|
||||
* beginning of a given `string`.
|
||||
*
|
||||
* @param stringWithColor String, that contains color definition at
|
||||
* the beginning. Anything after color definition is not used.
|
||||
* @param resultingColor Parsed color will be written here if parsing is
|
||||
* successful, otherwise value is undefined.
|
||||
* If parsed color did not specify alpha component - 255 will be used.
|
||||
* @param stringType How to treat given `string`,
|
||||
* see `StringType` for more details.
|
||||
* @return `true` if parsing was successful and false otherwise.
|
||||
*/
|
||||
public final function bool ParseString(
|
||||
string stringWithColor,
|
||||
out Color resultingColor,
|
||||
optional Text.StringType stringType)
|
||||
{
|
||||
local bool successfullyParsed;
|
||||
local Parser colorParser;
|
||||
colorParser = _.text.ParseString(stringWithColor, stringType);
|
||||
successfullyParsed = ParseWith(colorParser, resultingColor);
|
||||
_.memory.Free(colorParser);
|
||||
return successfullyParsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a color in any of the `ColorDisplayType` representations from the
|
||||
* beginning of a given `Text`.
|
||||
*
|
||||
* @param textWithColor `Text`, that contains color definition at
|
||||
* the beginning. Anything after color definition is not used.
|
||||
* @param resultingColor Parsed color will be written here if parsing is
|
||||
* successful, otherwise value is undefined.
|
||||
* If parsed color did not specify alpha component - 255 will be used.
|
||||
* @return `true` if parsing was successful and false otherwise.
|
||||
*/
|
||||
public final function bool ParseText(
|
||||
Text textWithColor,
|
||||
out Color resultingColor)
|
||||
{
|
||||
local bool successfullyParsed;
|
||||
local Parser colorParser;
|
||||
colorParser = _.text.Parse(textWithColor);
|
||||
successfullyParsed = ParseWith(colorParser, resultingColor);
|
||||
_.memory.Free(colorParser);
|
||||
return successfullyParsed;
|
||||
}
|
||||
|
||||
/**
|
||||
* Parses a color in any of the `ColorDisplayType` representations from the
|
||||
* beginning of a given raw data.
|
||||
*
|
||||
* @param rawDataWithColor Raw data, that contains color definition at
|
||||
* the beginning. Anything after color definition is not used.
|
||||
* @param resultingColor Parsed color will be written here if parsing is
|
||||
* successful, otherwise value is undefined.
|
||||
* If parsed color did not specify alpha component - 255 will be used.
|
||||
* @return `true` if parsing was successful and false otherwise.
|
||||
*/
|
||||
public final function bool ParseRaw(
|
||||
array<Text.Character> rawDataWithColor,
|
||||
out Color resultingColor)
|
||||
{
|
||||
local bool successfullyParsed;
|
||||
local Parser colorParser;
|
||||
colorParser = _.text.ParseRaw(rawDataWithColor);
|
||||
successfullyParsed = ParseWith(colorParser, resultingColor);
|
||||
_.memory.Free(colorParser);
|
||||
return successfullyParsed;
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
Pink=(R=255,G=192,B=203,A=255)
|
||||
LightPink=(R=255,G=182,B=193,A=255)
|
||||
HotPink=(R=255,G=105,B=180,A=255)
|
||||
DeepPink=(R=255,G=20,B=147,A=255)
|
||||
PaleVioletRed=(R=219,G=112,B=147,A=255)
|
||||
MediumVioletRed=(R=199,G=21,B=133,A=255)
|
||||
LightSalmon=(R=255,G=160,B=122,A=255)
|
||||
Salmon=(R=250,G=128,B=114,A=255)
|
||||
DarkSalmon=(R=233,G=150,B=122,A=255)
|
||||
LightCoral=(R=240,G=128,B=128,A=255)
|
||||
IndianRed=(R=205,G=92,B=92,A=255)
|
||||
Crimson=(R=220,G=20,B=60,A=255)
|
||||
Firebrick=(R=178,G=34,B=34,A=255)
|
||||
DarkRed=(R=139,G=0,B=0,A=255)
|
||||
Red=(R=255,G=0,B=0,A=255)
|
||||
OrangeRed=(R=255,G=69,B=0,A=255)
|
||||
Tomato=(R=255,G=99,B=71,A=255)
|
||||
Coral=(R=255,G=127,B=80,A=255)
|
||||
DarkOrange=(R=255,G=140,B=0,A=255)
|
||||
Orange=(R=255,G=165,B=0,A=255)
|
||||
Yellow=(R=255,G=255,B=0,A=255)
|
||||
LightYellow=(R=255,G=255,B=224,A=255)
|
||||
LemonChiffon=(R=255,G=250,B=205,A=255)
|
||||
LightGoldenrodYellow=(R=250,G=250,B=210,A=255)
|
||||
PapayaWhip=(R=255,G=239,B=213,A=255)
|
||||
Moccasin=(R=255,G=228,B=181,A=255)
|
||||
PeachPuff=(R=255,G=218,B=185,A=255)
|
||||
PaleGoldenrod=(R=238,G=232,B=170,A=255)
|
||||
Khaki=(R=240,G=230,B=140,A=255)
|
||||
DarkKhaki=(R=189,G=183,B=107,A=255)
|
||||
Gold=(R=255,G=215,B=0,A=255)
|
||||
Cornsilk=(R=255,G=248,B=220,A=255)
|
||||
BlanchedAlmond=(R=255,G=235,B=205,A=255)
|
||||
Bisque=(R=255,G=228,B=196,A=255)
|
||||
NavajoWhite=(R=255,G=222,B=173,A=255)
|
||||
Wheat=(R=245,G=222,B=179,A=255)
|
||||
Burlywood=(R=222,G=184,B=135,A=255)
|
||||
TanColor=(R=210,G=180,B=140,A=255)
|
||||
RosyBrown=(R=188,G=143,B=143,A=255)
|
||||
SandyBrown=(R=244,G=164,B=96,A=255)
|
||||
Goldenrod=(R=218,G=165,B=32,A=255)
|
||||
DarkGoldenrod=(R=184,G=134,B=11,A=255)
|
||||
Peru=(R=205,G=133,B=63,A=255)
|
||||
Chocolate=(R=210,G=105,B=30,A=255)
|
||||
SaddleBrown=(R=139,G=69,B=19,A=255)
|
||||
Sienna=(R=160,G=82,B=45,A=255)
|
||||
Brown=(R=165,G=42,B=42,A=255)
|
||||
Maroon=(R=128,G=0,B=0,A=255)
|
||||
DarkOliveGreen=(R=85,G=107,B=47,A=255)
|
||||
Olive=(R=128,G=128,B=0,A=255)
|
||||
OliveDrab=(R=107,G=142,B=35,A=255)
|
||||
YellowGreen=(R=154,G=205,B=50,A=255)
|
||||
LimeGreen=(R=50,G=205,B=50,A=255)
|
||||
Lime=(R=0,G=255,B=0,A=255)
|
||||
LawnGreen=(R=124,G=252,B=0,A=255)
|
||||
Chartreuse=(R=127,G=255,B=0,A=255)
|
||||
GreenYellow=(R=173,G=255,B=47,A=255)
|
||||
SpringGreen=(R=0,G=255,B=127,A=255)
|
||||
MediumSpringGreen=(R=0,G=250,B=154,A=255)
|
||||
LightGreen=(R=144,G=238,B=144,A=255)
|
||||
PaleGreen=(R=152,G=251,B=152,A=255)
|
||||
DarkSeaGreen=(R=143,G=188,B=143,A=255)
|
||||
MediumAquamarine=(R=102,G=205,B=170,A=255)
|
||||
MediumSeaGreen=(R=60,G=179,B=113,A=255)
|
||||
SeaGreen=(R=46,G=139,B=87,A=255)
|
||||
ForestGreen=(R=34,G=139,B=34,A=255)
|
||||
Green=(R=0,G=128,B=0,A=255)
|
||||
DarkGreen=(R=0,G=100,B=0,A=255)
|
||||
Aqua=(R=0,G=255,B=255,A=255)
|
||||
Cyan=(R=0,G=255,B=255,A=255)
|
||||
LightCyan=(R=224,G=255,B=255,A=255)
|
||||
PaleTurquoise=(R=175,G=238,B=238,A=255)
|
||||
Aquamarine=(R=127,G=255,B=212,A=255)
|
||||
Turquoise=(R=64,G=224,B=208,A=255)
|
||||
MediumTurquoise=(R=72,G=209,B=204,A=255)
|
||||
DarkTurquoise=(R=0,G=206,B=209,A=255)
|
||||
LightSeaGreen=(R=32,G=178,B=170,A=255)
|
||||
CadetBlue=(R=95,G=158,B=160,A=255)
|
||||
DarkCyan=(R=0,G=139,B=139,A=255)
|
||||
Teal=(R=0,G=128,B=128,A=255)
|
||||
LightSteelBlue=(R=176,G=196,B=222,A=255)
|
||||
PowderBlue=(R=176,G=224,B=230,A=255)
|
||||
LightBlue=(R=173,G=216,B=230,A=255)
|
||||
SkyBlue=(R=135,G=206,B=235,A=255)
|
||||
LightSkyBlue=(R=135,G=206,B=250,A=255)
|
||||
DeepSkyBlue=(R=0,G=191,B=255,A=255)
|
||||
DodgerBlue=(R=30,G=144,B=255,A=255)
|
||||
CornflowerBlue=(R=100,G=149,B=237,A=255)
|
||||
SteelBlue=(R=70,G=130,B=180,A=255)
|
||||
RoyalBlue=(R=65,G=105,B=225,A=255)
|
||||
Blue=(R=0,G=0,B=255,A=255)
|
||||
MediumBlue=(R=0,G=0,B=205,A=255)
|
||||
DarkBlue=(R=0,G=0,B=139,A=255)
|
||||
Navy=(R=0,G=0,B=128,A=255)
|
||||
MidnightBlue=(R=25,G=25,B=112,A=255)
|
||||
Lavender=(R=230,G=230,B=250,A=255)
|
||||
Thistle=(R=216,G=191,B=216,A=255)
|
||||
Plum=(R=221,G=160,B=221,A=255)
|
||||
Violet=(R=238,G=130,B=238,A=255)
|
||||
Orchid=(R=218,G=112,B=214,A=255)
|
||||
Fuchsia=(R=255,G=0,B=255,A=255)
|
||||
Magenta=(R=255,G=0,B=255,A=255)
|
||||
MediumOrchid=(R=186,G=85,B=211,A=255)
|
||||
MediumPurple=(R=147,G=112,B=219,A=255)
|
||||
BlueViolet=(R=138,G=43,B=226,A=255)
|
||||
DarkViolet=(R=148,G=0,B=211,A=255)
|
||||
DarkOrchid=(R=153,G=50,B=204,A=255)
|
||||
DarkMagenta=(R=139,G=0,B=139,A=255)
|
||||
Purple=(R=128,G=0,B=128,A=255)
|
||||
Indigo=(R=75,G=0,B=130,A=255)
|
||||
DarkSlateBlue=(R=72,G=61,B=139,A=255)
|
||||
SlateBlue=(R=106,G=90,B=205,A=255)
|
||||
MediumSlateBlue=(R=123,G=104,B=238,A=255)
|
||||
White=(R=255,G=255,B=255,A=255)
|
||||
Snow=(R=255,G=250,B=250,A=255)
|
||||
Honeydew=(R=240,G=255,B=240,A=255)
|
||||
MintCream=(R=245,G=255,B=250,A=255)
|
||||
Azure=(R=240,G=255,B=255,A=255)
|
||||
AliceBlue=(R=240,G=248,B=255,A=255)
|
||||
GhostWhite=(R=248,G=248,B=255,A=255)
|
||||
WhiteSmoke=(R=245,G=245,B=245,A=255)
|
||||
Seashell=(R=255,G=245,B=238,A=255)
|
||||
Beige=(R=245,G=245,B=220,A=255)
|
||||
OldLace=(R=253,G=245,B=230,A=255)
|
||||
FloralWhite=(R=255,G=250,B=240,A=255)
|
||||
Ivory=(R=255,G=255,B=240,A=255)
|
||||
AntiqueWhite=(R=250,G=235,B=215,A=255)
|
||||
Linen=(R=250,G=240,B=230,A=255)
|
||||
LavenderBlush=(R=255,G=240,B=245,A=255)
|
||||
MistyRose=(R=255,G=228,B=225,A=255)
|
||||
Gainsboro=(R=220,G=220,B=220,A=255)
|
||||
LightGray=(R=211,G=211,B=211,A=255)
|
||||
Silver=(R=192,G=192,B=192,A=255)
|
||||
Gray=(R=169,G=169,B=169,A=255)
|
||||
DimGray=(R=128,G=128,B=128,A=255)
|
||||
DarkGray=(R=105,G=105,B=105,A=255)
|
||||
LightSlateGray=(R=119,G=136,B=153,A=255)
|
||||
SlateGray=(R=112,G=128,B=144,A=255)
|
||||
DarkSlateGray=(R=47,G=79,B=79,A=255)
|
||||
Eigengrau=(R=22,G=22,B=29,A=255)
|
||||
Black=(R=0,G=0,B=0,A=255)
|
||||
CODEPOINT_SMALL_A = 97
|
||||
CODEPOINT_ESCAPE = 27
|
||||
}
|
507
sources/Core/Color/Tests/TEST_ColorAPI.uc
Normal file
507
sources/Core/Color/Tests/TEST_ColorAPI.uc
Normal file
@ -0,0 +1,507 @@
|
||||
/**
|
||||
* Set of tests for Color API.
|
||||
* Copyright 2020 Anton Tarasenko
|
||||
*------------------------------------------------------------------------------
|
||||
* This file is part of Acedia.
|
||||
*
|
||||
* Acedia is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* Acedia is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with Acedia. If not, see <https://www.gnu.org/licenses/>.
|
||||
*/
|
||||
class TEST_ColorAPI extends TestCase
|
||||
abstract;
|
||||
|
||||
protected static function TESTS()
|
||||
{
|
||||
Test_ColorCreation();
|
||||
Test_EqualityCheck();
|
||||
Test_ColorFixing();
|
||||
Test_ToString();
|
||||
Test_Parse();
|
||||
Test_GetTag();
|
||||
}
|
||||
|
||||
protected static function Test_ColorCreation()
|
||||
{
|
||||
Context("Testing `ColorAPI`'s functions for creating color structures.");
|
||||
SubTest_ColorCreationRGB();
|
||||
SubTest_ColorCreationRGBA();
|
||||
}
|
||||
|
||||
protected static function SubTest_ColorCreationRGB()
|
||||
{
|
||||
local Color createdColor;
|
||||
Issue("`RGB() function does not set red, green and blue components"
|
||||
@ "correctly.");
|
||||
createdColor = _().color.RGB(145, 67, 237);
|
||||
TEST_ExpectTrue(createdColor.r == 145);
|
||||
TEST_ExpectTrue(createdColor.g == 67);
|
||||
TEST_ExpectTrue(createdColor.b == 237);
|
||||
|
||||
Issue("`RGB() function does not set alpha component to 255.");
|
||||
TEST_ExpectTrue(createdColor.a == 255);
|
||||
|
||||
Issue("`RGB() function does not set special values (border values"
|
||||
@ "`0`, `255` and value `10`, incorrect for coloring a `string`) for"
|
||||
@"red, green and blue components correctly.");
|
||||
createdColor = _().color.RGB(0, 10, 255);
|
||||
TEST_ExpectTrue(createdColor.r == 0);
|
||||
TEST_ExpectTrue(createdColor.g == 10);
|
||||
TEST_ExpectTrue(createdColor.b == 255);
|
||||
|
||||
Issue("`RGB() function does not set alpha value to 255.");
|
||||
TEST_ExpectTrue(createdColor.a == 255);
|
||||
}
|
||||
|
||||
protected static function SubTest_ColorCreationRGBA()
|
||||
{
|
||||
local Color createdColor;
|
||||
Issue("`RGBA() function does not set red, green, blue, alpha"
|
||||
@ "components correctly.");
|
||||
createdColor = _().color.RGBA(93, 245, 1, 67);
|
||||
TEST_ExpectTrue(createdColor.r == 93);
|
||||
TEST_ExpectTrue(createdColor.g == 245);
|
||||
TEST_ExpectTrue(createdColor.b == 1);
|
||||
TEST_ExpectTrue(createdColor.a == 67);
|
||||
|
||||
Issue("`RGBA() function does not set special values (border values"
|
||||
@ "`0`, `255` and value `10`, incorrect for coloring a `string`) for"
|
||||
@"red, green, blue components correctly.");
|
||||
createdColor = _().color.RGBA(0, 10, 10, 255);
|
||||
TEST_ExpectTrue(createdColor.r == 0);
|
||||
TEST_ExpectTrue(createdColor.g == 10);
|
||||
TEST_ExpectTrue(createdColor.b == 10);
|
||||
TEST_ExpectTrue(createdColor.a == 255);
|
||||
}
|
||||
|
||||
protected static function Test_EqualityCheck()
|
||||
{
|
||||
Context("Testing `ColorAPI`'s functions for color equality check.");
|
||||
SubTest_EqualityCheckNotFixed();
|
||||
SubTest_EqualityCheckFixed();
|
||||
}
|
||||
|
||||
protected static function SubTest_EqualityCheckNotFixed()
|
||||
{
|
||||
local Color color1, color2, color3;
|
||||
color1 = _().color.RGB(45, 10, 19);
|
||||
color2 = _().color.RGB(45, 11, 19);
|
||||
color3 = _().color.RGBA(45, 10, 19, 178);
|
||||
Issue("`AreEqual()` does not recognized equal colors as such.");
|
||||
TEST_ExpectTrue(_().color.AreEqual(color1, color1));
|
||||
|
||||
Issue("`AreEqual()` does not recognized colors that differ only in alpha"
|
||||
@ "channel as equal.");
|
||||
TEST_ExpectTrue(_().color.AreEqual(color1, color3));
|
||||
|
||||
Issue("`AreEqual()` does not recognized different colors as such.");
|
||||
TEST_ExpectFalse(_().color.AreEqual(color1, color2));
|
||||
|
||||
Issue("`AreEqualWithAlpha()` does not recognized equal colors as such.");
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(color1, color1));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(color3, color3));
|
||||
|
||||
Issue("`AreEqualWithAlpha()` does not recognized different colors"
|
||||
@ "as such.");
|
||||
TEST_ExpectFalse(_().color.AreEqualWithAlpha(color1, color2));
|
||||
TEST_ExpectFalse(_().color.AreEqualWithAlpha(color1, color3));
|
||||
}
|
||||
|
||||
protected static function SubTest_EqualityCheckFixed()
|
||||
{
|
||||
local Color color1, color2, color3;
|
||||
color1 = _().color.RGB(45, 10, 0);
|
||||
color2 = _().color.RGB(45, 239, 19);
|
||||
color3 = _().color.RGBA(45, 11, 1, 178);
|
||||
Issue("`AreEqual()` does not recognized equal colors as such (with color"
|
||||
@ "auto-fix).");
|
||||
TEST_ExpectTrue(_().color.AreEqual(color1, color1, true));
|
||||
|
||||
Issue("`AreEqual()` does not recognized colors that differ only in alpha"
|
||||
@ "channel as equal (with color auto-fix).");
|
||||
TEST_ExpectTrue(_().color.AreEqual(color1, color3, true));
|
||||
|
||||
Issue("`AreEqual()` does not recognized different colors as such"
|
||||
@ "(with color auto-fix).");
|
||||
TEST_ExpectFalse(_().color.AreEqual(color1, color2, true));
|
||||
|
||||
Issue("`AreEqualWithAlpha()` does not recognized equal colors as such"
|
||||
@ "(with color auto-fix).");
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(color1, color1, true));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(color3, color3, true));
|
||||
|
||||
Issue("`AreEqualWithAlpha()` does not recognized different colors as such"
|
||||
@ "(with color auto-fix).");
|
||||
TEST_ExpectFalse(_().color.AreEqualWithAlpha(color1, color2, true));
|
||||
TEST_ExpectFalse(_().color.AreEqualWithAlpha(color1, color3, true));
|
||||
}
|
||||
|
||||
protected static function Test_ColorFixing()
|
||||
{
|
||||
local Color validColor, brokenColor;
|
||||
validColor = _().color.RGB(23, 179, 244);
|
||||
brokenColor = _().color.RGB(10, 35, 0);
|
||||
Context("Testing `ColorAPI`'s functions for fixing color components for"
|
||||
@ "game's native render functions.");
|
||||
Issue("`FixColorComponent()` does not \"fix\" values it is expected to,"
|
||||
@ "the way it is expected to.");
|
||||
TEST_ExpectTrue(_().color.FixColorComponent(0) == 1);
|
||||
TEST_ExpectTrue(_().color.FixColorComponent(10) == 11);
|
||||
|
||||
Issue("`FixColorComponent()` changes values it should not.");
|
||||
TEST_ExpectTrue(_().color.FixColorComponent(9) == 9);
|
||||
TEST_ExpectTrue(_().color.FixColorComponent(255) == 255);
|
||||
TEST_ExpectTrue(_().color.FixColorComponent(87) == 87);
|
||||
|
||||
Issue("`FixColor()` changes colors it should not.");
|
||||
TEST_ExpectTrue(
|
||||
_().color.AreEqualWithAlpha(validColor,
|
||||
_().color.FixColor(validColor)));
|
||||
|
||||
Issue("`FixColor()` doesn't fix color it should fix in an expected way.");
|
||||
TEST_ExpectTrue(
|
||||
_().color.AreEqualWithAlpha(_().color.RGB(11, 35, 1),
|
||||
_().color.FixColor(brokenColor)));
|
||||
|
||||
Issue("`FixColor()` affects alpha channel.");
|
||||
TEST_ExpectTrue(_().color.FixColor(validColor).a == 255);
|
||||
validColor.a = 0;
|
||||
TEST_ExpectTrue(_().color.FixColor(validColor).a == 0);
|
||||
validColor.a = 10;
|
||||
TEST_ExpectTrue(_().color.FixColor(validColor).a == 10);
|
||||
}
|
||||
|
||||
protected static function Test_ToString()
|
||||
{
|
||||
Context("Testing `ColorAPI`'s `ToString()` function.");
|
||||
SubTest_ToStringType();
|
||||
SubTest_ToString();
|
||||
}
|
||||
|
||||
protected static function SubTest_ToStringType()
|
||||
{
|
||||
local Color normalColor, borderValueColor;
|
||||
normalColor = _().color.RGBA(24, 232, 187, 34);
|
||||
borderValueColor = _().color.RGBA(0, 255, 255, 0);
|
||||
Issue("`ToStringType()` improperly works with `CLRDISPLAY_HEX` option.");
|
||||
TEST_ExpectTrue(_().color.ToStringType(normalColor) ~= "#18e8bb");
|
||||
TEST_ExpectTrue(_().color.ToStringType(borderValueColor) ~= "#00ffff");
|
||||
|
||||
Issue("`ToStringType()` improperly works with `CLRDISPLAY_RGB` option.");
|
||||
TEST_ExpectTrue(_().color.ToStringType(normalColor, CLRDISPLAY_RGB)
|
||||
~= "rgb(24,232,187)");
|
||||
TEST_ExpectTrue(_().color.ToStringType(borderValueColor, CLRDISPLAY_RGB)
|
||||
~= "rgb(0,255,255)");
|
||||
|
||||
Issue("`ToStringType()` improperly works with `CLRDISPLAY_RGBA` option.");
|
||||
TEST_ExpectTrue(_().color.ToStringType(normalColor, CLRDISPLAY_RGBA)
|
||||
~= "rgba(24,232,187,34)");
|
||||
TEST_ExpectTrue(_().color.ToStringType(borderValueColor, CLRDISPLAY_RGBA)
|
||||
~= "rgba(0,255,255,0)");
|
||||
|
||||
Issue("`ToStringType()` improperly works with `CLRDISPLAY_RGB_TAG`"
|
||||
@ "option.");
|
||||
TEST_ExpectTrue(_().color.ToStringType(normalColor, CLRDISPLAY_RGB_TAG)
|
||||
~= "rgb(r=24,g=232,b=187)");
|
||||
TEST_ExpectTrue(_().color.ToStringType(borderValueColor, CLRDISPLAY_RGB_TAG)
|
||||
~= "rgb(r=0,g=255,b=255)");
|
||||
|
||||
Issue("`ToStringType()` improperly works with `CLRDISPLAY_RGBA_TAG`"
|
||||
@ "option.");
|
||||
TEST_ExpectTrue(_().color.ToStringType(normalColor, CLRDISPLAY_RGBA_TAG)
|
||||
~= "rgba(r=24,g=232,b=187,a=34)");
|
||||
TEST_ExpectTrue(
|
||||
_().color.ToStringType(borderValueColor, CLRDISPLAY_RGBA_TAG)
|
||||
~= "rgba(r=0,g=255,b=255,a=0)");
|
||||
}
|
||||
|
||||
protected static function SubTest_ToString()
|
||||
{
|
||||
local Color opaqueColor, transparentColor;
|
||||
opaqueColor = _().color.RGBA(143, 211, 43, 255);
|
||||
transparentColor = _().color.RGBA(234, 32, 145, 13);
|
||||
Issue("`ToString()` improperly converts color with opaque color.");
|
||||
TEST_ExpectTrue(_().color.ToString(opaqueColor) ~= "rgb(143,211,43)");
|
||||
Issue("`ToString()` improperly converts color with transparent color.");
|
||||
TEST_ExpectTrue(_().color.ToString(transparentColor)
|
||||
~= "rgba(234,32,145,13)");
|
||||
}
|
||||
|
||||
protected static function Test_GetTag()
|
||||
{
|
||||
Context("Testing `ColorAPI`'s functionality of creating 4-byte color"
|
||||
@ "change sequences.");
|
||||
SubTest_GetTagColor();
|
||||
SubTest_GetTagRGB();
|
||||
}
|
||||
|
||||
protected static function SubTest_GetTagColor()
|
||||
{
|
||||
local Color normalColor, borderColor;
|
||||
normalColor = _().color.RGB(143, 211, 43);
|
||||
borderColor = _().color.RGB(10, 0, 255);
|
||||
Issue("`GetColorTag()` does not properly convert colors.");
|
||||
TEST_ExpectTrue(_().color.GetColorTag(normalColor)
|
||||
== (Chr(27) $ Chr(143) $ Chr(211) $ Chr(43)));
|
||||
TEST_ExpectTrue(_().color.GetColorTag(borderColor)
|
||||
== (Chr(27) $ Chr(11) $ Chr(1) $ Chr(255)));
|
||||
|
||||
Issue("`GetColorTag()` does not properly convert colors when asked not to"
|
||||
@ "fix components.");
|
||||
TEST_ExpectTrue(_().color.GetColorTag(normalColor, true)
|
||||
== (Chr(27) $ Chr(143) $ Chr(211) $ Chr(43)));
|
||||
TEST_ExpectTrue(_().color.GetColorTag(borderColor, true)
|
||||
== (Chr(27) $ Chr(10) $ Chr(1) $ Chr(255)));
|
||||
}
|
||||
|
||||
protected static function SubTest_GetTagRGB()
|
||||
{
|
||||
Issue("`GetColorTagRGB()` does not properly convert colors.");
|
||||
TEST_ExpectTrue(_().color.GetColorTagRGB(143, 211, 43)
|
||||
== (Chr(27) $ Chr(143) $ Chr(211) $ Chr(43)));
|
||||
TEST_ExpectTrue(_().color.GetColorTagRGB(10, 0, 255)
|
||||
== (Chr(27) $ Chr(11) $ Chr(1) $ Chr(255)));
|
||||
|
||||
Issue("`GetColorTagRGB()` does not properly convert colors when asked"
|
||||
@ "not to fix components.");
|
||||
TEST_ExpectTrue(_().color.GetColorTagRGB(143, 211, 43, true)
|
||||
== (Chr(27) $ Chr(143) $ Chr(211) $ Chr(43)));
|
||||
TEST_ExpectTrue(_().color.GetColorTagRGB(10, 0, 255, true)
|
||||
== (Chr(27) $ Chr(10) $ Chr(1) $ Chr(255)));
|
||||
}
|
||||
|
||||
protected static function Test_Parse()
|
||||
{
|
||||
Context("Testing `ColorAPI`'s parsing functionality.");
|
||||
SubTest_ParseWithParser();
|
||||
SubTest_ParseStringPlain();
|
||||
SubTest_ParseStringColored();
|
||||
SubTest_ParseStringFormatted();
|
||||
SubTest_ParseText();
|
||||
SubTest_ParseRaw();
|
||||
}
|
||||
|
||||
protected static function SubTest_ParseWithParser()
|
||||
{
|
||||
local Color expectedColor, resultColor;
|
||||
expectedColor = _().color.RGBA(154, 255, 0, 187);
|
||||
Issue("`ParseWith()` cannot parse hex colors.");
|
||||
TEST_ExpectTrue(_().color.ParseWith(_().text.ParseString("#9aff00"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseWith()` cannot parse rgb colors.");
|
||||
TEST_ExpectTrue(_().color.ParseWith(_().text.ParseString("rgb(154,255,0)"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseWith()` cannot parse rgba colors.");
|
||||
TEST_ExpectTrue(_().color.ParseWith(
|
||||
_().text.ParseString("rgba(154,255,0,187)"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseWith()` cannot parse rgb colors with tags.");
|
||||
TEST_ExpectTrue(_().color.ParseWith(
|
||||
_().text.ParseString("rgb(r=154,g=255,b=0)"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseWith()` cannot parse rgba colors with tags.");
|
||||
TEST_ExpectTrue(_().color.ParseWith(
|
||||
_().text.ParseString("rgba(r=154,g=255,b=0,a=187)"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseWith()` reports success when parsing invalid color string.");
|
||||
TEST_ExpectFalse(_().color.ParseWith( _().text.ParseString("#9aff0g"),
|
||||
resultColor));
|
||||
}
|
||||
|
||||
protected static function SubTest_ParseStringPlain()
|
||||
{
|
||||
local Color expectedColor, resultColor;
|
||||
expectedColor = _().color.RGBA(154, 255, 0, 187);
|
||||
Issue("`ParseString()` cannot parse hex colors.");
|
||||
TEST_ExpectTrue(_().color.ParseString("#9aff00", resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString()` cannot parse rgb colors.");
|
||||
TEST_ExpectTrue(_().color.ParseString("rgb(154,255,0)", resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString()` cannot parse rgba colors.");
|
||||
TEST_ExpectTrue(_().color.ParseString("rgba(154,255,0,187)", resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString()` cannot parse rgb colors with tags.");
|
||||
TEST_ExpectTrue(_().color.ParseString("rgb(r=154,g=255,b=0)", resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString()` cannot parse rgba colors with tags.");
|
||||
TEST_ExpectTrue(_().color.ParseString( "rgba(r=154,g=255,b=0,a=187)",
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString()` reports success when parsing invalid color string.");
|
||||
TEST_ExpectFalse(_().color.ParseString("#9aff0g", resultColor));
|
||||
}
|
||||
|
||||
protected static function SubTest_ParseStringColored()
|
||||
{
|
||||
local Color expectedColor, resultColor;
|
||||
expectedColor = _().color.RGBA(154, 255, 0, 187);
|
||||
Issue("`ParseString(STRING_Colored)` cannot parse hex colors.");
|
||||
TEST_ExpectTrue(_().color.ParseString(
|
||||
"#9af" $ Chr(27) $ Chr(45) $ Chr(234) $ Chr(24) $ "f00",
|
||||
resultColor, STRING_Colored));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString(STRING_Colored)` cannot parse rgb colors.");
|
||||
TEST_ExpectTrue(_().color.ParseString(
|
||||
"rgb(154,2" $ Chr(27) $ Chr(23) $ Chr(32) $ Chr(53) $ "55,0)",
|
||||
resultColor, STRING_Colored));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString(STRING_Colored)` cannot parse rgba colors.");
|
||||
TEST_ExpectTrue(_().color.ParseString(
|
||||
"rgba(154,255,0,187" $ Chr(27) $ Chr(133) $ Chr(234) $ Chr(10) $ ")",
|
||||
resultColor, STRING_Colored));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString(STRING_Colored)` cannot parse rgb colors with tags.");
|
||||
TEST_ExpectTrue(_().color.ParseString(
|
||||
"rg" $ Chr(27) $ Chr(26) $ Chr(234) $ Chr(125) $ "b(r=154,g=255,b=0)",
|
||||
resultColor, STRING_Colored));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString(STRING_Colored)` cannot parse rgba colors with tags.");
|
||||
TEST_ExpectTrue(_().color.ParseString(
|
||||
"rgba(r=154,g=255,b" $ Chr(27) $ Chr(1) $ Chr(4) $ Chr(7) $ "=0,a=187)",
|
||||
resultColor, STRING_Colored));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(resultColor, expectedColor));
|
||||
}
|
||||
|
||||
protected static function SubTest_ParseStringFormatted()
|
||||
{
|
||||
local Color expectedColor, resultColor;
|
||||
expectedColor = _().color.RGBA(154, 255, 0, 187);
|
||||
Issue("`ParseString(STRING_Formatted)` cannot parse hex colors.");
|
||||
TEST_ExpectTrue(_().color.ParseString(
|
||||
"#9a{#4753d5 ff0}0",
|
||||
resultColor, STRING_Formatted));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString(STRING_Formatted)` cannot parse rgb colors.");
|
||||
TEST_ExpectTrue(_().color.ParseString(
|
||||
"rg{rgb(45,67,123) b(154,25}5,0)",
|
||||
resultColor, STRING_Formatted));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString(STRING_Formatted)` cannot parse rgba colors.");
|
||||
TEST_ExpectTrue(_().color.ParseString(
|
||||
"rgba(154,2{#34d1a7 }55,0,187)",
|
||||
resultColor, STRING_Formatted));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString(STRING_Formatted)` cannot parse rgb colors with tags.");
|
||||
TEST_ExpectTrue(_().color.ParseString(
|
||||
"rgb(r{#34d1a7 }=154,g=255,b=0)",
|
||||
resultColor, STRING_Formatted));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseString(STRING_Formatted)` cannot parse rgba colors with"
|
||||
@ "tags.");
|
||||
TEST_ExpectTrue(_().color.ParseString(
|
||||
"r{rgb(12,12,253) gba(r=154,g=255,b=0,a=187)}",
|
||||
resultColor, STRING_Formatted));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(resultColor, expectedColor));
|
||||
}
|
||||
|
||||
protected static function SubTest_ParseText()
|
||||
{
|
||||
local Color expectedColor, resultColor;
|
||||
expectedColor = _().color.RGBA(154, 255, 0, 187);
|
||||
Issue("`ParseText()` cannot parse hex colors.");
|
||||
TEST_ExpectTrue(_().color.ParseText(_().text.FromString("#9aff00"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseText()` cannot parse rgb colors.");
|
||||
TEST_ExpectTrue(_().color.ParseText(_().text.FromString("rgb(154,255,0)"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseText()` cannot parse rgba colors.");
|
||||
TEST_ExpectTrue(_().color.ParseText(
|
||||
_().text.FromString("rgba(154,255,0,187)"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseText()` cannot parse rgb colors with tags.");
|
||||
TEST_ExpectTrue(_().color.ParseText(
|
||||
_().text.FromString("rgb(r=154,g=255,b=0)"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseText()` cannot parse rgba colors with tags.");
|
||||
TEST_ExpectTrue(_().color.ParseText(
|
||||
_().text.FromString("rgba(r=154,g=255,b=0,a=187)"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseText()` reports success when parsing invalid color string.");
|
||||
TEST_ExpectFalse(_().color.ParseText( _().text.FromString("#9aff0g"),
|
||||
resultColor));
|
||||
}
|
||||
|
||||
protected static function SubTest_ParseRaw()
|
||||
{
|
||||
local Color expectedColor, resultColor;
|
||||
expectedColor = _().color.RGBA(154, 255, 0, 187);
|
||||
Issue("`ParseRaw()` cannot parse hex colors.");
|
||||
TEST_ExpectTrue(_().color.ParseRaw( _().text.StringToRaw("#9aff00"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseRaw()` cannot parse rgb colors.");
|
||||
TEST_ExpectTrue(_().color.ParseRaw( _().text.StringToRaw("rgb(154,255,0)"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseRaw()` cannot parse rgba colors.");
|
||||
TEST_ExpectTrue(_().color.ParseRaw(
|
||||
_().text.StringToRaw("rgba(154,255,0,187)"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseRaw()` cannot parse rgb colors with tags.");
|
||||
TEST_ExpectTrue(_().color.ParseRaw(
|
||||
_().text.StringToRaw("rgb(r=154,g=255,b=0)"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqual(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseRaw()` cannot parse rgba colors with tags.");
|
||||
TEST_ExpectTrue(_().color.ParseRaw(
|
||||
_().text.StringToRaw("rgba(r=154,g=255,b=0,a=187)"),
|
||||
resultColor));
|
||||
TEST_ExpectTrue(_().color.AreEqualWithAlpha(resultColor, expectedColor));
|
||||
|
||||
Issue("`ParseRaw()` reports success when parsing invalid color string.");
|
||||
TEST_ExpectFalse(_().color.ParseRaw(_().text.StringToRaw("#9aff0g"),
|
||||
resultColor));
|
||||
}
|
||||
|
||||
defaultproperties
|
||||
{
|
||||
caseName = "Colors"
|
||||
}
|
Reference in New Issue
Block a user