Alpha color support

This commit is contained in:
M66B 2021-07-05 16:55:31 +02:00
parent 576388ee16
commit de12fd9d08
4 changed files with 101 additions and 41 deletions

View File

@ -36,7 +36,6 @@ import android.content.pm.ResolveInfo;
import android.content.res.Configuration;
import android.content.res.Resources;
import android.content.res.TypedArray;
import android.graphics.Color;
import android.net.Uri;
import android.os.BatteryManager;
import android.os.Build;
@ -88,7 +87,6 @@ import androidx.browser.customtabs.CustomTabsServiceConnection;
import androidx.constraintlayout.widget.ConstraintLayout;
import androidx.core.content.ContextCompat;
import androidx.core.content.FileProvider;
import androidx.core.graphics.ColorUtils;
import androidx.fragment.app.FragmentActivity;
import androidx.lifecycle.Lifecycle;
import androidx.lifecycle.LifecycleObserver;
@ -1092,15 +1090,6 @@ public class Helper {
return (tv.string != null && !"light".contentEquals(tv.string));
}
static int adjustLuminance(int color, boolean dark, float min) {
float lum = (float) ColorUtils.calculateLuminance(color);
if (dark ? lum < min : lum > 1 - min)
return ColorUtils.blendARGB(color,
dark ? Color.WHITE : Color.BLACK,
dark ? min - lum : lum - (1 - min));
return color;
}
static void hideKeyboard(final View view) {
InputMethodManager imm =
(InputMethodManager) view.getContext().getSystemService(Activity.INPUT_METHOD_SERVICE);

View File

@ -399,12 +399,16 @@ public class HtmlEx {
}
if (style[j] instanceof ForegroundColorSpan) {
int color = ((ForegroundColorSpan) style[j]).getForegroundColor();
out.append(String.format("<span style=\"color:#%06X;\">", 0xFFFFFF & color));
//out.append(String.format("<span style=\"color:#%06X;\">", 0xFFFFFF & color));
out.append(String.format("<span style=\"color:%s;\">",
eu.faircode.email.HtmlHelper.encodeWebColor(color)));
}
if (style[j] instanceof BackgroundColorSpan) {
int color = ((BackgroundColorSpan) style[j]).getBackgroundColor();
out.append(String.format("<span style=\"background-color:#%06X;\">",
0xFFFFFF & color));
//out.append(String.format("<span style=\"background-color:#%06X;\">",
// 0xFFFFFF & color));
out.append(String.format("<span style=\"background-color:%s;\">",
eu.faircode.email.HtmlHelper.encodeWebColor(color)));
}
}

View File

@ -592,6 +592,10 @@ public class HtmlHelper {
Integer color = parseColor(value);
// fromHtml does not support transparency
//if (color != null)
// color = (0xFFFFFF & color);
if ("color".equals(key)) {
boolean bg = false;
Element e = element;
@ -601,6 +605,7 @@ public class HtmlHelper {
else
e = e.parent();
// Keep color as-is when background set
if (!bg) {
// Special case:
// external draft / dark background / dark font
@ -613,13 +618,31 @@ public class HtmlHelper {
if (color != null && view)
color = adjustColor(dark, textColorPrimary, color);
}
} else {
if (color != null)
element.attr("x-color", "true");
} else /* background */ {
if (color != null && !hasColor(color))
continue;
if (color != null) {
String hex = String.format("#%06X", (0xFFFFFF & color));
element.attr("x-background", hex);
if (color != null)
element.attr("x-background", "true");
if (dark) {
boolean fg = (parseColor(kv.get("color")) != null);
Element e = element;
while (e != null && !fg)
if (e.hasAttr("x-color"))
fg = true;
else
e = e.parent();
// Force foreground color
if (!fg)
sb.append("color")
.append(':')
.append(encodeWebColor(textColorPrimaryInverse))
.append(";");
}
}
@ -628,8 +651,7 @@ public class HtmlHelper {
continue;
}
// fromHtml does not support transparency
String c = String.format("#%06x", color);
String c = encodeWebColor(color);
sb.append(key).append(':').append(c).append(";");
if (Build.VERSION.SDK_INT < Build.VERSION_CODES.N)
element.attr(key, c);
@ -1514,7 +1536,10 @@ public class HtmlHelper {
}
}
private static Integer parseColor(@NonNull String value) {
private static Integer parseColor(String value) {
if (TextUtils.isEmpty(value))
return null;
// https://developer.mozilla.org/en-US/docs/Web/CSS/color_value
String c = value
.replace("null", "")
@ -1530,6 +1555,7 @@ public class HtmlHelper {
.replaceAll("#+", "#");
Integer color = null;
boolean hasAlpha = false;
try {
if (TextUtils.isEmpty(c))
return null;
@ -1538,8 +1564,10 @@ public class HtmlHelper {
String code = c.substring(1);
if (x11ColorMap.containsKey(code)) // workaround
color = x11ColorMap.get(code);
else
color = parseWebColor(code);
else {
color = parseWebColor(c);
hasAlpha = true;
}
}
} else if (c.startsWith("rgb") || c.startsWith("hsl")) {
int s = c.indexOf("(");
@ -1565,14 +1593,25 @@ public class HtmlHelper {
Float.parseFloat(component[0]),
Integer.parseInt(component[1]) / 100f,
Integer.parseInt(component[2]) / 100f});
if (color != null && component.length >= 4) {
int alpha = Math.round(Float.parseFloat(component[3]) * 255);
color = ColorUtils.setAlphaComponent(color, alpha);
hasAlpha = true;
}
}
} else if (x11ColorMap.containsKey(c))
color = x11ColorMap.get(c);
else
else {
color = parseWebColor(c);
hasAlpha = true;
}
if (color != null && !hasAlpha)
color = ColorUtils.setAlphaComponent(color, 255);
if (BuildConfig.DEBUG)
Log.i("Color " + c + "=" + (color == null ? null : Long.toHexString(color)));
Log.i("Color " + c + "=" + (color == null ? null : encodeWebColor(color)));
} catch (Throwable ex) {
Log.i("Color=" + c + ": " + ex);
@ -1581,28 +1620,55 @@ public class HtmlHelper {
return color;
}
private static int parseWebColor(String value) {
if (value.length() == 3 || value.length() == 6 || value.length() == 8) {
if (value.length() == 3)
value = "" +
value.charAt(0) + value.charAt(0) +
value.charAt(1) + value.charAt(1) +
value.charAt(2) + value.charAt(2);
return (int) Long.parseLong(value, 16);
} else
private static int parseWebColor(@NonNull String value) {
if (value.startsWith("#"))
value = value.substring(1);
if (value.length() == 3)
value = "FF" +
value.charAt(0) + value.charAt(0) +
value.charAt(1) + value.charAt(1) +
value.charAt(2) + value.charAt(2);
else if (value.length() == 6)
value = "FF" + value;
else if (value.length() == 8)
value = value.substring(6, 8) + value.substring(0, 6);
else
throw new IllegalArgumentException("Unknown color=" + value);
return (int) Long.parseLong(value, 16);
}
static String encodeWebColor(int color) {
int alpha = Color.alpha(color);
int rgb = 0xFFFFFF & color;
if (alpha == 0)
return String.format("#%06X", rgb);
else
return String.format("#%06X%02X", rgb, alpha);
}
private static Integer adjustColor(boolean dark, int textColorPrimary, Integer color) {
// Special case:
// shades of gray
int r = Color.red(color);
int g = Color.green(color);
int b = Color.blue(color);
if (r == g && r == b && (dark ? 255 - r : r) < GRAY_THRESHOLD)
float a = Color.alpha(color) / 255f;
if (r == g && r == b && (dark ? 255 - r : r) * a < GRAY_THRESHOLD)
color = textColorPrimary;
else
color = Helper.adjustLuminance(color, dark, MIN_LUMINANCE);
return (color & 0xFFFFFF);
return adjustLuminance(color, dark, MIN_LUMINANCE);
}
static int adjustLuminance(int color, boolean dark, float min) {
int c = ColorUtils.compositeColors(color, dark ? Color.BLACK : Color.WHITE);
float lum = (float) ColorUtils.calculateLuminance(c);
if (dark ? lum < min : lum > 1 - min)
color = ColorUtils.blendARGB(color,
dark ? Color.WHITE : Color.BLACK,
dark ? min - lum : lum - (1 - min));
return color;
}
private static boolean hasColor(int color) {
@ -2413,7 +2479,7 @@ public class HtmlHelper {
case "background-color":
if (!TextUtils.isEmpty(value))
try {
int color = Integer.parseInt(value.substring(1), 16) | 0xFF000000;
int color = parseWebColor(value);
CharacterStyle span;
if ("color".equals(key))
span = new ForegroundColorSpan(color);
@ -2775,6 +2841,7 @@ public class HtmlHelper {
static void clearAnnotations(Document d) {
d.select("*")
.removeAttr("x-background")
.removeAttr("x-color")
.removeAttr("x-block")
.removeAttr("x-inline")
.removeAttr("x-paragraph")

View File

@ -254,7 +254,7 @@ public class StyleHelper {
.setColorEditTextColor(editTextColor)
.wheelType(ColorPickerView.WHEEL_TYPE.FLOWER)
.density(6)
.lightnessSliderOnly()
//.lightnessSliderOnly()
.setPositiveButton(android.R.string.ok, new ColorPickerClickListener() {
@Override
public void onClick(DialogInterface dialog, int selectedColor, Integer[] allColors) {
@ -307,7 +307,7 @@ public class StyleHelper {
.setColorEditTextColor(editTextColor)
.wheelType(ColorPickerView.WHEEL_TYPE.FLOWER)
.density(6)
.lightnessSliderOnly()
//.lightnessSliderOnly()
.setPositiveButton(android.R.string.ok, new ColorPickerClickListener() {
@Override
public void onClick(DialogInterface dialog, int selectedColor, Integer[] allColors) {