From d850474b0a82ee00d094990d9bd3392ae8cd9575 Mon Sep 17 00:00:00 2001 From: Allan Wang Date: Mon, 24 Dec 2018 22:00:41 -0500 Subject: Simplify color utils and fix tests, resolves #156 --- .../kotlin/ca/allanwang/kau/ui/views/CutoutView.kt | 2 +- .../ca/allanwang/kau/utils/UtilsAndroidTest.kt | 50 ++++++++++++++++++++++ .../kotlin/ca/allanwang/kau/xml/FaqTest.kt | 28 +++--------- .../kotlin/ca/allanwang/kau/utils/ColorUtils.kt | 31 +++++++------- .../kotlin/ca/allanwang/kau/utils/UtilsTest.kt | 18 ++++++++ 5 files changed, 91 insertions(+), 38 deletions(-) create mode 100644 core/src/androidTest/kotlin/ca/allanwang/kau/utils/UtilsAndroidTest.kt diff --git a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt index 6da65a3..474d40a 100644 --- a/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt +++ b/core-ui/src/main/kotlin/ca/allanwang/kau/ui/views/CutoutView.kt @@ -90,7 +90,7 @@ class CutoutView @JvmOverloads constructor( if (attrs != null) { val a = context.obtainStyledAttributes(attrs, R.styleable.CutoutView, 0, 0) if (a.hasValue(R.styleable.CutoutView_font)) - paint.typeface = context.getFont(a.getString(R.styleable.CutoutView_font)) + paint.typeface = context.getFont(a.getString(R.styleable.CutoutView_font)!!) foregroundColor = a.getColor(R.styleable.CutoutView_foregroundColor, foregroundColor) text = a.getString(R.styleable.CutoutView_android_text) ?: text minHeight = a.getDimension(R.styleable.CutoutView_android_minHeight, minHeight) diff --git a/core/src/androidTest/kotlin/ca/allanwang/kau/utils/UtilsAndroidTest.kt b/core/src/androidTest/kotlin/ca/allanwang/kau/utils/UtilsAndroidTest.kt new file mode 100644 index 0000000..665e0b2 --- /dev/null +++ b/core/src/androidTest/kotlin/ca/allanwang/kau/utils/UtilsAndroidTest.kt @@ -0,0 +1,50 @@ +/* + * Copyright 2018 Allan Wang + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package ca.allanwang.kau.utils + +import android.graphics.Color +import androidx.test.ext.junit.runners.AndroidJUnit4 +import org.junit.Test +import org.junit.runner.RunWith +import kotlin.test.assertEquals + +/** + * Created by Allan Wang on 2018-12-24. + * + * Misc test code that are dependent on android + */ +@RunWith(AndroidJUnit4::class) +class UtilsAndroidTest { + + @Test + fun colorBlend() { + assertEquals(0x22446688, 0x11335577.blendWith(0x33557799, 0.5f), "Failed to blend with 50% ratio") + assertEquals(0x11335577, 0x11335577.blendWith(0x33557799, 0.0f), "Failed to blend with 0% ratio") + assertEquals(0x33557799, 0x22446688.blendWith(0x33557799, 1.0f), "Failed to blend with 100% ratio") + } + + @Test + fun lighten() { + assertEquals(Color.WHITE, Color.WHITE.lighten(0.35f), "Should not be able to further lighten white") + assertEquals(0xFFEEAAEA.toInt(), 0xFFDD55D5.toInt().lighten(0.5f), "Failed to lighten color by 50%") + } + + @Test + fun darken() { + assertEquals(Color.BLACK, Color.BLACK.darken(0.35f), "Should not be able to further darken black") + assertEquals(0xFF224424.toInt(), 0xFF448848.toInt().darken(0.5f), "Failed to darken color by 50%") + } +} diff --git a/core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt b/core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt index 2d02dbc..7ec2a41 100644 --- a/core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt +++ b/core/src/androidTest/kotlin/ca/allanwang/kau/xml/FaqTest.kt @@ -36,27 +36,11 @@ class FaqTest { @Test fun simpleTest() { - context.kauParseFaq(R.xml.test_faq) { data -> - assertEquals(2, data.size, "FAQ size is incorrect") - assertEquals("1. This is a question", data.first().question.toString(), "First question does not match") - assertEquals("This is an answer", data.first().answer.toString(), "First answer does not match") - assertEquals( - "2. This is another question", - data.last().question.toString(), - "Second question does not match" - ) - assertEquals("This is another answer", data.last().answer.toString(), "Second answer does not match") - } - } - - @Test - fun withoutNumbering() { - context.kauParseFaq(R.xml.test_faq, false) { data -> - assertEquals(2, data.size, "FAQ size is incorrect") - assertEquals("This is a question", data.first().question.toString(), "First question does not match") - assertEquals("This is an answer", data.first().answer.toString(), "First answer does not match") - assertEquals("This is another question", data.last().question.toString(), "Second question does not match") - assertEquals("This is another answer", data.last().answer.toString(), "Second answer does not match") - } + val data = context.kauParseFaq(R.xml.test_faq, false) + assertEquals(2, data.size, "FAQ size is incorrect") + assertEquals("This is a question", data.first().question.toString(), "First question does not match") + assertEquals("This is an answer", data.first().answer.toString(), "First answer does not match") + assertEquals("This is another question", data.last().question.toString(), "Second question does not match") + assertEquals("This is another answer", data.last().answer.toString(), "Second answer does not match") } } diff --git a/core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt b/core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt index 9e1832f..bbb8953 100644 --- a/core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt +++ b/core/src/main/kotlin/ca/allanwang/kau/utils/ColorUtils.kt @@ -118,25 +118,28 @@ fun Int.blendWith(@ColorInt color: Int, @FloatRange(from = 0.0, to = 1.0) ratio: } @ColorInt -fun Int.withAlpha(@IntRange(from = 0L, to = 255L) alpha: Int): Int = - Color.argb(alpha, Color.red(this), Color.green(this), Color.blue(this)) +fun Int.withAlpha(@IntRange(from = 0, to = 0xFF) alpha: Int): Int = + this and 0x00FFFFFF or (alpha shl 24) @ColorInt -fun Int.withMinAlpha(@IntRange(from = 0L, to = 255L) alpha: Int): Int = - Color.argb(Math.max(alpha, Color.alpha(this)), Color.red(this), Color.green(this), Color.blue(this)) +fun Int.withMinAlpha(@IntRange(from = 0, to = 0xFF) alpha: Int): Int = + withAlpha(Math.max(alpha, this ushr 24)) @ColorInt -fun Int.lighten(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int { +private inline fun Int.colorFactor(rgbFactor: (Int) -> Float): Int { val (red, green, blue) = intArrayOf(Color.red(this), Color.green(this), Color.blue(this)) - .map { (it * (1f - factor) + 255f * factor).toInt() } + .map { rgbFactor(it).toInt() } return Color.argb(Color.alpha(this), red, green, blue) } @ColorInt -fun Int.darken(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int { - val (red, green, blue) = intArrayOf(Color.red(this), Color.green(this), Color.blue(this)) - .map { (it * (1f - factor)).toInt() } - return Color.argb(Color.alpha(this), red, green, blue) +fun Int.lighten(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int = colorFactor { + (it * (1f - factor) + 255f * factor) +} + +@ColorInt +fun Int.darken(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int = colorFactor { + it * (1f - factor) } @ColorInt @@ -147,13 +150,11 @@ fun Int.colorToBackground(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f fun Int.colorToForeground(@FloatRange(from = 0.0, to = 1.0) factor: Float = 0.1f): Int = if (isColorDark) lighten(factor) else darken(factor) -@Throws(IllegalArgumentException::class) fun String.toColor(): Int { - val toParse: String - if (startsWith("#") && length == 4) - toParse = "#${this[1]}${this[1]}${this[2]}${this[2]}${this[3]}${this[3]}" + val toParse: String = if (startsWith("#") && length == 4) + "#${this[1]}${this[1]}${this[2]}${this[2]}${this[3]}${this[3]}" else - toParse = this + this return Color.parseColor(toParse) } diff --git a/core/src/test/kotlin/ca/allanwang/kau/utils/UtilsTest.kt b/core/src/test/kotlin/ca/allanwang/kau/utils/UtilsTest.kt index 1cce9ae..b9c200a 100644 --- a/core/src/test/kotlin/ca/allanwang/kau/utils/UtilsTest.kt +++ b/core/src/test/kotlin/ca/allanwang/kau/utils/UtilsTest.kt @@ -31,6 +31,24 @@ class UtilsTest { assertEquals("#ffffff", Color.WHITE.toHexString(withAlpha = false, withHexPrefix = true).toLowerCase()) } + @Test + fun colorWithAlpha() { + val origColor = 0xFF123456.toInt() + assertEquals(0x00123456, origColor.withAlpha(0), "Failed to convert with alpha 0") + assertEquals(0x50123456, origColor.withAlpha(80), "Failed to convert with alpha 80") + assertEquals(0xFF123456.toInt(), origColor.withAlpha(255), "Failed to convert with alpha 255") + assertEquals(0xFF123456.toInt(), origColor.withAlpha(0xFF), "Failed to convert with alpha 0xFF") + assertEquals(Color.TRANSPARENT, Color.BLACK.withAlpha(0), "Failed to convert black to transparent") + } + + @Test + fun colorWithMinAlpha() { + val origColor = 0x80123456.toInt() + assertEquals(origColor, origColor.withMinAlpha(0), "Failed to convert with min alpha 0") + assertEquals(0xFA123456.toInt(), origColor.withMinAlpha(0xFA), "Failed to convert with min alpha 0xFA") + assertEquals(Color.BLUE, Color.BLUE.withMinAlpha(89), "Failed to convert blue with min alpha 89") + } + @Test fun rounding() { assertEquals("1.23", 1.23456f.round(2)) -- cgit v1.2.3