diff --git a/sources/Color/ColorAPI.uc b/sources/Color/ColorAPI.uc index 5087e9f..77d7c8d 100644 --- a/sources/Color/ColorAPI.uc +++ b/sources/Color/ColorAPI.uc @@ -38,7 +38,11 @@ enum ColorDisplayType // 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 + CLRDISPLAY_RGBA_TAG, + // Stripped RGB format; for pink: 255,192,203 + CLRDISPLAY_RGB_STRIPPED, + // Stripped RGBA format; for opaque pink: 255,192,203,255 + CLRDISPLAY_RGBA_STRIPPED }; // Some useful predefined color values. @@ -737,7 +741,7 @@ private final function string ComponentToHex(byte component) } /** - * Displays given color as a string in a given style + * Displays given color as a `string` in a given style * (hex color representation by default). * * @param colorToConvert Color to display as a `string`. @@ -773,15 +777,28 @@ public final function string ToStringType( $ "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) $ ")"; + else if (displayType == CLRDISPLAY_RGBA_TAG) + { + return "rgba(r=" $ string(colorToConvert.r) $ "," + $ "g=" $ string(colorToConvert.g) $ "," + $ "b=" $ string(colorToConvert.b) $ "," + $ "a=" $ string(colorToConvert.a) $ ")"; + } + else if (displayType == CLRDISPLAY_RGB_STRIPPED) + { + return string(colorToConvert.r) $ "," + $ string(colorToConvert.g) $ "," + $ string(colorToConvert.b); + } + //else if (displayType == CLRDISPLAY_RGBA_STRIPPED) + return string(colorToConvert.r) $ "," + $ string(colorToConvert.g) $ "," + $ string(colorToConvert.b) $ "," + $ string(colorToConvert.a); } /** - * Displays given color as a string in RGB or RGBA format, depending on + * 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` @@ -796,7 +813,38 @@ public final function string ToString(Color colorToConvert) return ToStringType(colorToConvert, CLRDISPLAY_RGB); } -// Parses color in `CLRDISPLAY_RGB` and `CLRDISPLAY_RGB_TAG` representations. +/** + * Displays given color as a `Text` in a given style + * (hex color representation by default). + * + * @param colorToConvert Color to display as a `Text`. + * @param displayType `enum` value, describing how should color + * be displayed. + * @return `Text` representation of a given color in a given style. + * Guaranteed to not be `none`. + */ +public final function Text ToTextType( + Color colorToConvert, + optional ColorDisplayType displayType) +{ + return _.text.FromString(ToStringType(colorToConvert, displayType)); +} + +/** + * Displays given color as a `Text` in RGB or RGBA format, depending on + * whether color is opaque. + * + * @param colorToConvert Color to display as a `Text` in `CLRDISPLAY_RGB` + * style if `colorToConvert.a == 255` and `CLRDISPLAY_RGBA` otherwise. + * @return `Text` representation of a given color in a given style. + */ +public final function Text ToText(Color colorToConvert) +{ + return _.text.FromString(ToString(colorToConvert)); +} + +// Parses color in `CLRDISPLAY_RGB`, `CLRDISPLAY_RGB_TAG` and +// `CLRDISPLAY_RGB_STRIPPED` representations. private final function Color ParseRGB(Parser parser) { local int redComponent; @@ -819,10 +867,18 @@ private final function Color ParseRGB(Parser parser) .MatchS("b=", SCASE_INSENSITIVE) .MInteger(blueComponent).MatchS(")"); } + if (!parser.Ok()) + { + parser.RestoreState(initialParserState) + .MInteger(redComponent).MatchS(",") + .MInteger(greenComponent).MatchS(",") + .MInteger(blueComponent); + } return RGB(redComponent, greenComponent, blueComponent); } -// Parses color in `CLRDISPLAY_RGBA` and `CLRDISPLAY_RGBA_TAG` representations. +// Parses color in `CLRDISPLAY_RGBA`, `CLRDISPLAY_RGBA_TAG` +// and `CLRDISPLAY_RGBA_STRIPPED` representations. private final function Color ParseRGBA(Parser parser) { local int redComponent; @@ -849,6 +905,14 @@ private final function Color ParseRGBA(Parser parser) .MatchS("a=", SCASE_INSENSITIVE) .MInteger(alphaComponent).MatchS(")"); } + if (!parser.Ok()) + { + parser.RestoreState(initialParserState) + .MInteger(redComponent).MatchS(",") + .MInteger(greenComponent).MatchS(",") + .MInteger(blueComponent).MatchS(",") + .MInteger(alphaComponent); + } return RGBA(redComponent, greenComponent, blueComponent, alphaComponent); } @@ -901,11 +965,13 @@ public final function bool ParseWith(Parser parser, out Color resultingColor) parser.RestoreState(initialParserState); } colorAlias.FreeSelf(); - resultingColor = ParseRGB(colorParser); + // `CLRDISPLAY_RGBA_STRIPPED` format can be parsed as an incomplete + // `CLRDISPLAY_RGB_STRIPPED`, so we need to try parsing RGBA first + resultingColor = ParseRGBA(colorParser); if (!colorParser.Ok()) { colorParser.RestoreState(initialParserState); - resultingColor = ParseRGBA(colorParser); + resultingColor = ParseRGB(colorParser); } if (!colorParser.Ok()) { diff --git a/sources/Color/Tests/TEST_ColorAPI.uc b/sources/Color/Tests/TEST_ColorAPI.uc index d39df04..de342c9 100644 --- a/sources/Color/Tests/TEST_ColorAPI.uc +++ b/sources/Color/Tests/TEST_ColorAPI.uc @@ -184,6 +184,7 @@ protected static function Test_ToString() { Context("Testing `ColorAPI`'s `ToString()` function."); SubTest_ToStringType(); + SubTest_ToStringTypeStripped(); SubTest_ToString(); } @@ -225,6 +226,30 @@ protected static function SubTest_ToStringType() ~= "rgba(r=0,g=255,b=255,a=0)"); } +protected static function SubTest_ToStringTypeStripped() +{ + local Color normalColor, borderValueColor; + normalColor = __().color.RGBA(24, 232, 187, 34); + borderValueColor = __().color.RGBA(0, 255, 255, 0); + Issue("`ToStringType()` improperly works with `CLRDISPLAY_RGB_STRIPPED`" + @ "option."); + TEST_ExpectTrue( + __().color.ToStringType(normalColor, CLRDISPLAY_RGB_STRIPPED) + ~= "24,232,187"); + TEST_ExpectTrue( + __().color.ToStringType(borderValueColor, CLRDISPLAY_RGB_STRIPPED) + ~= "0,255,255"); + + Issue("`ToStringType()` improperly works with `CLRDISPLAY_RGBA_STRIPPED`" + @ "option."); + TEST_ExpectTrue( + __().color.ToStringType(normalColor, CLRDISPLAY_RGBA_STRIPPED) + ~= "24,232,187,34"); + TEST_ExpectTrue( + __().color.ToStringType(borderValueColor, CLRDISPLAY_RGBA_STRIPPED) + ~= "0,255,255,0"); +} + protected static function SubTest_ToString() { local Color opaqueColor, transparentColor; @@ -286,6 +311,9 @@ protected static function Test_Parse() SubTest_ParseWithParser(); SubTest_ParseStringPlain(); SubTest_ParseText(); + SubTest_ParseWithParserStripped(); + SubTest_ParseStringPlainStripped(); + SubTest_ParseTextStripped(); } protected static function SubTest_ParseWithParser() @@ -392,6 +420,53 @@ protected static function SubTest_ParseText() resultColor)); } +protected static function SubTest_ParseWithParserStripped() +{ + local Color expectedColor, resultColor; + expectedColor = __().color.RGBA(154, 255, 0, 187); + Issue("`ParseWith()` cannot parse stripped rgb colors."); + TEST_ExpectTrue(__().color.ParseWith( + __().text.ParseString("154,255,0"), + resultColor)); + TEST_ExpectTrue(__().color.AreEqual(resultColor, expectedColor)); + + Issue("`ParseWith()` cannot parse stripped rgba colors."); + TEST_ExpectTrue(__().color.ParseWith( + __().text.ParseString("154,255,0,187"), + resultColor)); + TEST_ExpectTrue(__().color.AreEqualWithAlpha(resultColor, expectedColor)); +} + +protected static function SubTest_ParseStringPlainStripped() +{ + local Color expectedColor, resultColor; + expectedColor = __().color.RGBA(154, 255, 0, 187); + Issue("`ParseString()` cannot parse stripped rgb colors."); + TEST_ExpectTrue(__().color.ParseString("154,255,0", resultColor)); + TEST_ExpectTrue(__().color.AreEqual(resultColor, expectedColor)); + + Issue("`ParseString()` cannot parse stripped rgba colors."); + TEST_ExpectTrue(__().color.ParseString("154,255,0,187", resultColor)); + TEST_ExpectTrue(__().color.AreEqualWithAlpha(resultColor, expectedColor)); +} + +protected static function SubTest_ParseTextStripped() +{ + local Color expectedColor, resultColor; + expectedColor = __().color.RGBA(154, 255, 0, 187); + Issue("`Parse()` cannot parse stripped rgb colors."); + TEST_ExpectTrue(__().color.Parse( + __().text.FromString("154,255,0"), + resultColor)); + TEST_ExpectTrue(__().color.AreEqual(resultColor, expectedColor)); + + Issue("`Parse()` cannot parse stripped rgba colors."); + TEST_ExpectTrue(__().color.Parse( + __().text.FromString("154,255,0,187"), + resultColor)); + TEST_ExpectTrue(__().color.AreEqualWithAlpha(resultColor, expectedColor)); +} + defaultproperties { caseName = "ColorAPI"