Skip to content

Commit

Permalink
Make alpha channel non optional
Browse files Browse the repository at this point in the history
  • Loading branch information
taig committed Nov 27, 2019
1 parent e66871b commit e7af90f
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 32 deletions.
43 changes: 21 additions & 22 deletions core/src/main/scala/io/taig/color/Color.scala
Expand Up @@ -4,7 +4,7 @@ final case class Color(
red: Channel,
green: Channel,
blue: Channel,
alpha: Option[Channel]
alpha: Channel
) {

/** Set the alpha channel to its min value */
Expand All @@ -13,38 +13,37 @@ final case class Color(
/** Set the alpha channel to its min value */
def opaque: Color = alpha(Channel.MaxValue)

def alpha(value: Channel): Color = copy(alpha = Some(value))
def alpha(value: Channel): Color = copy(alpha = value)

/** Remove the alpha channel information */
def dropAlpha: Color = copy(alpha = None)
def isOpaque: Boolean = alpha == Channel.MaxValue
def isTransparent: Boolean = alpha == Channel.MinValue

/** Print the color as a hex string */
def toHex: String = alpha match {
case Some(alpha) =>
def toHex: String =
if (isOpaque) f"#${red.value}%02x${green.value}%02x${blue.value}%02x"
else
f"#${red.value}%02x${green.value}%02x${blue.value}%02x${alpha.value}%02x"
case None =>
f"#${red.value}%02x${green.value}%02x${blue.value}%02x"
}

/** Print the color a rgb or rgba string */
def toRgb: String = toRgbX(color => String.valueOf(color.value))
def toRgbScaled: String = toRgbX(color => String.valueOf(color.scaled))
def toRgb_% : String = toRgbX(color => String.valueOf(color.%))

private def toRgbX(render: Channel => String): String = alpha match {
case Some(alpha) =>
private def toRgbX(render: Channel => String): String =
if (isOpaque)
"rgb(" + render(red) + ", " +
render(green) + ", " +
render(blue) + ")"
else
"rgba(" + render(red) + ", " +
render(green) + ", " +
render(blue) + ", " +
render(alpha) + ")"
case None =>
"rgb(" + render(red) + ", " +
render(green) + ", " +
render(blue) + ")"
}
}

object Color {
def opaque(red: Channel, green: Channel, blue: Channel): Color =
Color(red, green, blue, Channel.MaxValue)

/** Convert a (hexadecimal) number to a `Color`
*
Expand Down Expand Up @@ -76,24 +75,24 @@ object Color {
val red = channel(((value & 0xFFF) >> 8) * 17)
val green = channel(((value & 0xFF) >> 4) * 17)
val blue = channel((value & 0xF) * 17)
Right(Color(red, green, blue, None))
Right(opaque(red, green, blue))
} else if (digits == 4) {
val red = channel(((value & 0xFFFF) >> 12) * 17)
val green = channel(((value & 0xFFF) >> 8) * 17)
val blue = channel(((value & 0xFF) >> 4) * 17)
val alpha = channel((value & 0xF) * 17)
Right(Color(red, green, blue, Some(alpha)))
Right(Color(red, green, blue, alpha))
} else if (digits == 6) {
val red = channel((value & 0xFFFFFF) >> 16)
val green = channel((value & 0xFFFF) >> 8)
val blue = channel(value & 0xFF)
Right(Color(red, green, blue, None))
Right(opaque(red, green, blue))
} else if (digits == 8) {
val red = channel((value & 0xFFFFFFFF) >> 24)
val green = channel((value & 0xFFFFFF) >> 16)
val blue = channel((value & 0xFFFF) >> 8)
val alpha = channel(value & 0xFF)
Right(Color(red, green, blue, Some(alpha)))
Right(Color(red, green, blue, alpha))
} else {
val message = "Color value can only have 6 (rgba), 8 (rgba), 3 (rgb " +
"shorthand) or 4 (rgba shorthand) digits"
Expand All @@ -118,8 +117,8 @@ object Color {
parseHex(value).getOrElse(throw new IllegalArgumentException)

val Black: Color =
Color(Channel.MinValue, Channel.MinValue, Channel.MinValue, None)
opaque(Channel.MinValue, Channel.MinValue, Channel.MinValue)

val White: Color =
Color(Channel.MaxValue, Channel.MaxValue, Channel.MaxValue, None)
opaque(Channel.MaxValue, Channel.MaxValue, Channel.MaxValue)
}
20 changes: 10 additions & 10 deletions core/src/test/scala/io/taig/color/ColorTest.scala
Expand Up @@ -32,7 +32,7 @@ object ColorTest extends IOAutoTestApp {
},
test("#0FF") {
fromRight(Color.parseHex("#0FF")) assert
isEqual(Color(MinValue, MaxValue, MaxValue, None))
isEqual(Color.opaque(MinValue, MaxValue, MaxValue))
},
test("#FFFF") {
fromRight(Color.parseHex("#FFFF")) assert
Expand All @@ -50,7 +50,7 @@ object ColorTest extends IOAutoTestApp {
},
test("#ff0000") {
fromRight(Color.parseHex("#ff0000")) assert
isEqual(Color(MaxValue, MinValue, MinValue, None))
isEqual(Color.opaque(MaxValue, MinValue, MinValue))
},
test("#FFFFFFFF") {
fromRight(Color.parseHex("#FFFFFFFF")) assert
Expand All @@ -74,29 +74,29 @@ object ColorTest extends IOAutoTestApp {
test("#FFFFFF") {
isEqual("#ffffff")(Color.White.toHex)
},
test("#FFFFFFFF") {
isEqual("#ffffffff")(Color.White.opaque.toHex)
test("#FFFFFF00") {
isEqual("#ffffff00")(Color.White.transparent.toHex)
},
test("#000000") {
isEqual("#000000")(Color.Black.toHex)
},
test("#000000FF") {
isEqual("#000000ff")(Color.Black.opaque.toHex)
test("#00000000") {
isEqual("#00000000")(Color.Black.transparent.toHex)
}
)

test("toRgb")(
test("#FFFFFF") {
isEqual("rgb(255, 255, 255)")(Color.White.toRgb)
},
test("#FFFFFFFF") {
isEqual("rgba(255, 255, 255, 255)")(Color.White.opaque.toRgb)
test("#FFFFFF00") {
isEqual("rgba(255, 255, 255, 0)")(Color.White.transparent.toRgb)
},
test("#000000") {
isEqual("rgb(0, 0, 0)")(Color.Black.toRgb)
},
test("#000000FF") {
isEqual("rgba(0, 0, 0, 255)")(Color.Black.opaque.toRgb)
test("#00000000") {
isEqual("rgba(0, 0, 0, 0)")(Color.Black.transparent.toRgb)
}
)
}

0 comments on commit e7af90f

Please sign in to comment.