Skip to content

Commit

Permalink
HSL colorspace (#2006)
Browse files Browse the repository at this point in the history
Co-authored-by: amylizzle <[email protected]>
  • Loading branch information
amylizzle and amylizzle authored Oct 3, 2024
1 parent 5eadbd3 commit dae5c6c
Show file tree
Hide file tree
Showing 4 changed files with 35 additions and 8 deletions.
12 changes: 12 additions & 0 deletions Content.Tests/DMProject/Tests/Builtins/rgb.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
/proc/RunTest()
ASSERT(rgb(255, 255, 255) =="#ffffff")
ASSERT(rgb(255, 0, 0) == "#ff0000" )
ASSERT(rgb(0, 0, 255) == "#0000ff")
ASSERT(rgb(18, 245, 230) == "#12f5e6")
ASSERT(rgb(18, 245, 230, 128) == "#12f5e680")
ASSERT(rgb(202, 96, 219, space=COLORSPACE_RGB) == "#ca60db")
ASSERT(rgb(291.70734, 56.164383, 85.882355, space=COLORSPACE_HSV) == "#ca60db")
ASSERT(rgb(291.70734, 63.07692, 61.764706, space=COLORSPACE_HSL) == "#ca60db" )

ASSERT(rgb(291.70734, 63.07692, 61.764706, 128, COLORSPACE_HSL) == "#ca60db80" )
//ASSERT(rgb(291.70734, 68.2215, 55.423534, space=COLORSPACE_HCY) == "#ca60db") // TODO Support HCY
3 changes: 3 additions & 0 deletions OpenDream.sln.DotSettings
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,9 @@
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=LHS/@EntryIndexedValue">LHS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RHS/@EntryIndexedValue">RHS</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=UI/@EntryIndexedValue">UI</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=RGB/@EntryIndexedValue">RGB</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HSV/@EntryIndexedValue">HSV</s:String>
<s:String x:Key="/Default/CodeStyle/Naming/CSharpNaming/Abbreviations/=HSL/@EntryIndexedValue">HSL</s:String>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpKeepExistingMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpPlaceEmbeddedOnSameLineMigration/@EntryIndexedValue">True</s:Boolean>
<s:Boolean x:Key="/Default/Environment/SettingsMigration/IsMigratorApplied/=JetBrains_002EReSharper_002EPsi_002ECSharp_002ECodeStyle_002ECSharpUseContinuousIndentInsideBracesMigration/@EntryIndexedValue">True</s:Boolean>
Expand Down
25 changes: 18 additions & 7 deletions OpenDreamRuntime/Procs/DMOpcodeHandlers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1929,7 +1929,7 @@ public static ProcStatus Rgb(DMProcState state) {
DreamValue color1 = default;
DreamValue color2 = default;
DreamValue color3 = default;
DreamValue a = default;
DreamValue a = DreamValue.Null;
ColorHelpers.ColorSpace space = ColorHelpers.ColorSpace.RGB;

if (arguments.Item1 != null) {
Expand Down Expand Up @@ -1974,6 +1974,9 @@ public static ProcStatus Rgb(DMProcState state) {
} else if (name.StartsWith("v", StringComparison.InvariantCultureIgnoreCase) && color3 == default) {
color3 = arg.Value;
space = ColorHelpers.ColorSpace.HSV;
} else if (name.StartsWith("l", StringComparison.InvariantCultureIgnoreCase) && color3 == default) {
color3 = arg.Value;
space = ColorHelpers.ColorSpace.HSL;
} else if (name.StartsWith("a", StringComparison.InvariantCultureIgnoreCase) && a == default)
a = arg.Value;
else if (name == "space" && space == default)
Expand All @@ -1994,10 +1997,10 @@ public static ProcStatus Rgb(DMProcState state) {
return ProcStatus.Continue;
}

int color1Value = (int)color1.UnsafeGetValueAsFloat();
int color2Value = (int)color2.UnsafeGetValueAsFloat();
int color3Value = (int)color3.UnsafeGetValueAsFloat();
byte aValue = (byte)Math.Clamp((int)a.UnsafeGetValueAsFloat(), 0, 255);
float color1Value = color1.UnsafeGetValueAsFloat();
float color2Value = color2.UnsafeGetValueAsFloat();
float color3Value = color3.UnsafeGetValueAsFloat();
byte aValue = a.IsNull ? (byte)255 : (byte)Math.Clamp((int)a.UnsafeGetValueAsFloat(), 0, 255);
Color color;

switch (space) {
Expand All @@ -2018,15 +2021,23 @@ public static ProcStatus Rgb(DMProcState state) {
color = Color.FromHsv((h, s, v, aValue / 255f));
break;
}
case ColorHelpers.ColorSpace.HSL: {
float h = Math.Clamp(color1Value, 0, 360) / 360f;
float s = Math.Clamp(color2Value, 0, 100) / 100f;
float l = Math.Clamp(color3Value, 0, 100) / 100f;

color = Color.FromHsl((h, s, l, aValue / 255f));
break;
}
default:
throw new Exception($"Unimplemented color space {space}");
}

// TODO: There is a difference between passing null and not passing a fourth arg at all
if (a.IsNull) {
state.Push(new DreamValue($"#{color.RByte:X2}{color.GByte:X2}{color.BByte:X2}"));
state.Push(new DreamValue($"#{color.RByte:X2}{color.GByte:X2}{color.BByte:X2}".ToLower()));
} else {
state.Push(new DreamValue($"#{color.RByte:X2}{color.GByte:X2}{color.BByte:X2}{color.AByte:X2}"));
state.Push(new DreamValue($"#{color.RByte:X2}{color.GByte:X2}{color.BByte:X2}{color.AByte:X2}".ToLower()));
}

return ProcStatus.Continue;
Expand Down
3 changes: 2 additions & 1 deletion OpenDreamShared/Dream/ColorHelpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ public static class ColorHelpers {

public enum ColorSpace {
RGB = 0,
HSV = 1
HSV = 1,
HSL = 2
}

public static bool TryParseColor(string color, out Color colorOut, string defaultAlpha = "ff") {
Expand Down

0 comments on commit dae5c6c

Please sign in to comment.