From 26ff978b0ffc788385f74ada472e5b819615c0c0 Mon Sep 17 00:00:00 2001 From: agnostic-apollo Date: Tue, 14 Jun 2022 19:13:19 +0500 Subject: [PATCH] Changed: Use black or white cursor color based on terminal background instead of always white if colors.properties didn't have cursor color set Credit for algorithm link belong to @Jamie-Landeg-Jones Closes #2653 --- .../termux/terminal/TerminalColorScheme.java | 23 +++++++++++++++++++ .../com/termux/terminal/TerminalColors.java | 20 ++++++++++++++++ 2 files changed, 43 insertions(+) diff --git a/terminal-emulator/src/main/java/com/termux/terminal/TerminalColorScheme.java b/terminal-emulator/src/main/java/com/termux/terminal/TerminalColorScheme.java index e4fd4e9c..40887818 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/TerminalColorScheme.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/TerminalColorScheme.java @@ -71,6 +71,7 @@ public final class TerminalColorScheme { public void updateWith(Properties props) { reset(); + boolean cursorPropExists = false; for (Map.Entry entries : props.entrySet()) { String key = (String) entries.getKey(); String value = (String) entries.getValue(); @@ -82,6 +83,7 @@ public final class TerminalColorScheme { colorIndex = TextStyle.COLOR_INDEX_BACKGROUND; } else if (key.equals("cursor")) { colorIndex = TextStyle.COLOR_INDEX_CURSOR; + cursorPropExists = true; } else if (key.startsWith("color")) { try { colorIndex = Integer.parseInt(key.substring(5)); @@ -98,6 +100,27 @@ public final class TerminalColorScheme { mDefaultColors[colorIndex] = colorValue; } + + if (!cursorPropExists) + setCursorColorForBackground(); + } + + /** + * If the "cursor" color is not set by user, we need to decide on the appropriate color that will + * be visible on the current terminal background. White will not be visible on light backgrounds + * and black won't be visible on dark backgrounds. So we find the perceived brightness of the + * background color and if its below the threshold (too dark), we use white cursor and if its + * above (too bright), we use black cursor. + */ + public void setCursorColorForBackground() { + int backgroundColor = mDefaultColors[TextStyle.COLOR_INDEX_BACKGROUND]; + int brightness = TerminalColors.getPerceivedBrightnessOfColor(backgroundColor); + if (brightness > 0) { + if (brightness < 130) + mDefaultColors[TextStyle.COLOR_INDEX_CURSOR] = 0xffffffff; + else + mDefaultColors[TextStyle.COLOR_INDEX_CURSOR] = 0xff000000; + } } } diff --git a/terminal-emulator/src/main/java/com/termux/terminal/TerminalColors.java b/terminal-emulator/src/main/java/com/termux/terminal/TerminalColors.java index 6d8cfdb9..25135a2f 100644 --- a/terminal-emulator/src/main/java/com/termux/terminal/TerminalColors.java +++ b/terminal-emulator/src/main/java/com/termux/terminal/TerminalColors.java @@ -1,5 +1,7 @@ package com.termux.terminal; +import android.graphics.Color; + /** Current terminal colors (if different from default). */ public final class TerminalColors { @@ -73,4 +75,22 @@ public final class TerminalColors { if (c != 0) mCurrentColors[intoIndex] = c; } + /** + * Get the perceived brightness of the color based on its RGB components. + * + * https://www.nbdtech.com/Blog/archive/2008/04/27/Calculating-the-Perceived-Brightness-of-a-Color.aspx + * http://alienryderflex.com/hsp.html + * + * @param color The color code int. + * @return Returns value between 0-255. + */ + public static int getPerceivedBrightnessOfColor(int color) { + return (int) + Math.floor(Math.sqrt( + Math.pow(Color.red(color), 2) * 0.241 + + Math.pow(Color.green(color), 2) * 0.691 + + Math.pow(Color.blue(color), 2) * 0.068 + )); + } + }