您最多选择25个主题
主题必须以中文或者字母或数字开头,可以包含连字符 (-),并且长度不得超过35个字符
346 行
9.6 KiB
346 行
9.6 KiB
using System;
|
|
using Unity.UIWidgets.painting;
|
|
using UnityEngine;
|
|
|
|
namespace Unity.UIWidgets.ui {
|
|
public class Color : IEquatable<Color> {
|
|
public Color(long value) {
|
|
this.value = value & 0xFFFFFFFF;
|
|
}
|
|
|
|
public static readonly Color clear = new Color(0x00000000);
|
|
|
|
public static readonly Color black = new Color(0xFF000000);
|
|
|
|
public static readonly Color white = new Color(0xFFFFFFFF);
|
|
|
|
public static Color fromARGB(int a, int r, int g, int b) {
|
|
return new Color(
|
|
(((a & 0xff) << 24) |
|
|
((r & 0xff) << 16) |
|
|
((g & 0xff) << 8) |
|
|
((b & 0xff) << 0)) & 0xFFFFFFFF);
|
|
}
|
|
|
|
public static Color fromRGBO(int r, int g, int b, double opacity) {
|
|
return new Color(
|
|
((((int) (opacity * 0xff) & 0xff) << 24) |
|
|
((r & 0xff) << 16) |
|
|
((g & 0xff) << 8) |
|
|
((b & 0xff) << 0)) & 0xFFFFFFFF);
|
|
}
|
|
|
|
public readonly long value;
|
|
|
|
public int alpha {
|
|
get { return (int) ((0xff000000 & this.value) >> 24); }
|
|
}
|
|
|
|
public double opacity {
|
|
get { return this.alpha / 255.0; }
|
|
}
|
|
|
|
public int red {
|
|
get { return (int) ((0x00ff0000 & this.value) >> 16); }
|
|
}
|
|
|
|
public int green {
|
|
get { return (int) ((0x0000ff00 & this.value) >> 8); }
|
|
}
|
|
|
|
public int blue {
|
|
get { return (int) ((0x000000ff & this.value) >> 0); }
|
|
}
|
|
|
|
public Color withAlpha(int a) {
|
|
return fromARGB(a, this.red, this.green, this.blue);
|
|
}
|
|
|
|
public Color withOpacity(double opacity) {
|
|
return this.withAlpha((int) (opacity * 255));
|
|
}
|
|
|
|
public Color withRed(int r) {
|
|
return fromARGB(this.alpha, r, this.green, this.blue);
|
|
}
|
|
|
|
public Color withGreen(int g) {
|
|
return fromARGB(this.alpha, this.red, g, this.blue);
|
|
}
|
|
|
|
public Color withBlue(int b) {
|
|
return fromARGB(this.alpha, this.red, this.green, b);
|
|
}
|
|
|
|
public static Color lerp(Color a, Color b, double t) {
|
|
if (a == null && b == null) {
|
|
return null;
|
|
}
|
|
|
|
if (a == null) {
|
|
return b._scaleAlpha(t);
|
|
}
|
|
|
|
if (b == null) {
|
|
return a._scaleAlpha(1.0 - t);
|
|
}
|
|
|
|
return fromARGB(
|
|
((int) MathUtils.lerpDouble(a.alpha, b.alpha, t)).clamp(0, 255),
|
|
((int) MathUtils.lerpDouble(a.red, b.red, t)).clamp(0, 255),
|
|
((int) MathUtils.lerpDouble(a.green, b.green, t)).clamp(0, 255),
|
|
((int) MathUtils.lerpDouble(a.blue, b.blue, t)).clamp(0, 255)
|
|
);
|
|
}
|
|
|
|
public bool Equals(Color other) {
|
|
if (ReferenceEquals(null, other)) {
|
|
return false;
|
|
}
|
|
if (ReferenceEquals(this, other)) {
|
|
return true;
|
|
}
|
|
return this.value == other.value;
|
|
}
|
|
|
|
public override bool Equals(object obj) {
|
|
if (ReferenceEquals(null, obj)) {
|
|
return false;
|
|
}
|
|
if (ReferenceEquals(this, obj)) {
|
|
return true;
|
|
}
|
|
if (obj.GetType() != this.GetType()) {
|
|
return false;
|
|
}
|
|
return this.Equals((Color) obj);
|
|
}
|
|
|
|
public override int GetHashCode() {
|
|
return this.value.GetHashCode();
|
|
}
|
|
|
|
public static bool operator ==(Color a, Color b) {
|
|
return ReferenceEquals(a, null) ? ReferenceEquals(b, null) : a.Equals(b);
|
|
}
|
|
|
|
public static bool operator !=(Color a, Color b) {
|
|
return !(a == b);
|
|
}
|
|
|
|
public override string ToString() {
|
|
return $"Color(0x{this.value:X8})";
|
|
}
|
|
}
|
|
|
|
public enum Clip {
|
|
none,
|
|
hardEdge,
|
|
antiAlias,
|
|
antiAliasWithSaveLayer,
|
|
}
|
|
|
|
public enum PaintingStyle {
|
|
fill,
|
|
stroke,
|
|
}
|
|
|
|
public enum StrokeCap {
|
|
butt,
|
|
round,
|
|
square,
|
|
}
|
|
|
|
public enum StrokeJoin {
|
|
miter,
|
|
round,
|
|
bevel,
|
|
}
|
|
|
|
public class ColorFilter {
|
|
public Color color;
|
|
public BlendMode blendMode;
|
|
}
|
|
|
|
public enum TileMode {
|
|
// todo: implement repeated, mirror.
|
|
clamp,
|
|
repeated,
|
|
mirror
|
|
}
|
|
|
|
public abstract class PaintShader {
|
|
}
|
|
|
|
public class Gradient : PaintShader {
|
|
internal float[] invXform;
|
|
internal float[] extent;
|
|
internal float radius;
|
|
internal float feather;
|
|
internal Color innerColor;
|
|
internal Color outerColor;
|
|
|
|
public static Gradient linear(
|
|
Offset from, Offset to,
|
|
Color color0, Color color1, TileMode tileMode = TileMode.clamp) {
|
|
const float large = 1e5f;
|
|
|
|
var dir = to - from;
|
|
var dx = (float) dir.dx;
|
|
var dy = (float) dir.dy;
|
|
var d = (float) dir.distance;
|
|
if (d > 0.0001f) {
|
|
dx /= d;
|
|
dy /= d;
|
|
} else {
|
|
dx = 0;
|
|
dy = 1;
|
|
}
|
|
|
|
var xform = new[] {dy, -dx, dx, dy, (float) from.dx - dx * large, (float) from.dy - dy * large};
|
|
var invXform = new float[6];
|
|
XformUtils.transformInverse(invXform, xform);
|
|
|
|
return new Gradient {
|
|
invXform = invXform,
|
|
extent = new[] {large, large + d * 0.5f},
|
|
radius = 0.0f,
|
|
feather = Mathf.Max(1.0f, d),
|
|
innerColor = color0,
|
|
outerColor = color1
|
|
};
|
|
}
|
|
|
|
public static Gradient radial(
|
|
Offset center, double radius0, double radius1,
|
|
Color color0, Color color1, TileMode tileMode = TileMode.clamp) {
|
|
float r = (float) (radius0 + radius1) * 0.5f;
|
|
float f = (float) (radius1 - radius0);
|
|
|
|
var xform = new[] {1, 0, 0, 1, (float) center.dx, (float) center.dy};
|
|
var invXform = new float[6];
|
|
XformUtils.transformInverse(invXform, xform);
|
|
|
|
return new Gradient {
|
|
invXform = invXform,
|
|
extent = new[] {r, r},
|
|
radius = r,
|
|
feather = Mathf.Max(1.0f, f),
|
|
innerColor = color0,
|
|
outerColor = color1
|
|
};
|
|
}
|
|
|
|
public static Gradient box(
|
|
Rect rect, double radius, double feather,
|
|
Color color0, Color color1, TileMode tileMode = TileMode.clamp) {
|
|
var ext0 = (float) rect.width * 0.5f;
|
|
var ext1 = (float) rect.height * 0.5f;
|
|
|
|
var xform = new[] {1, 0, 0, 1, (float) rect.left + ext0, (float) rect.top + ext1};
|
|
var invXform = new float[6];
|
|
XformUtils.transformInverse(invXform, xform);
|
|
|
|
return new Gradient {
|
|
invXform = invXform,
|
|
extent = new[] {ext0, ext1},
|
|
radius = (float) radius,
|
|
feather = Mathf.Max(1.0f, (float) feather),
|
|
innerColor = color0,
|
|
outerColor = color1
|
|
};
|
|
}
|
|
}
|
|
|
|
public class Paint {
|
|
static readonly Color _kColorDefault = new Color(0xFFFFFFFF);
|
|
|
|
public Color color = _kColorDefault;
|
|
|
|
public BlendMode blendMode = BlendMode.srcOver;
|
|
|
|
public PaintingStyle style = PaintingStyle.fill;
|
|
|
|
public double strokeWidth = 0;
|
|
|
|
public StrokeCap strokeCap = StrokeCap.butt;
|
|
|
|
public StrokeJoin strokeJoin = StrokeJoin.miter;
|
|
|
|
public double strokeMiterLimit = 4.0;
|
|
|
|
public FilterMode filterMode = FilterMode.Point;
|
|
|
|
public ColorFilter colorFilter = null;
|
|
|
|
public PaintShader shader = null;
|
|
|
|
public double blurSigma;
|
|
|
|
public bool invertColors;
|
|
}
|
|
|
|
public static class Conversions {
|
|
public static UnityEngine.Color toColor(this Color color) {
|
|
return new UnityEngine.Color(
|
|
color.red / 255f, color.green / 255f, color.blue / 255f, color.alpha / 255f);
|
|
}
|
|
|
|
public static Color32 toColor32(this Color color) {
|
|
return new Color32(
|
|
(byte) color.red, (byte) color.green, (byte) color.blue, (byte) color.alpha);
|
|
}
|
|
|
|
public static Vector2 toVector(this Offset offset) {
|
|
return new Vector2((float) offset.dx, (float) offset.dy);
|
|
}
|
|
|
|
public static UnityEngine.Rect toRect(this Rect rect) {
|
|
return new UnityEngine.Rect((float) rect.left, (float) rect.top, (float) rect.width, (float) rect.height);
|
|
}
|
|
|
|
public static float alignToPixel(this float v, float devicePixelRatio) {
|
|
return Mathf.Round(v * devicePixelRatio) / devicePixelRatio;
|
|
}
|
|
|
|
internal static Color _scaleAlpha(this Color a, double factor) {
|
|
return a.withAlpha((a.alpha * factor).round().clamp(0, 255));
|
|
}
|
|
}
|
|
|
|
public enum BlendMode {
|
|
clear,
|
|
src,
|
|
dst,
|
|
srcOver,
|
|
dstOver,
|
|
srcIn,
|
|
dstIn,
|
|
srcOut,
|
|
dstOut,
|
|
srcATop,
|
|
dstATop,
|
|
xor,
|
|
plus,
|
|
|
|
// REF: https://www.w3.org/TR/compositing-1/#blendingseparable
|
|
modulate,
|
|
screen,
|
|
overlay,
|
|
darken,
|
|
lighten,
|
|
colorDodge,
|
|
colorBurn,
|
|
hardLight,
|
|
softLight,
|
|
difference,
|
|
exclusion,
|
|
multiply,
|
|
|
|
// REF: https://www.w3.org/TR/compositing-1/#blendingnonseparable
|
|
hue,
|
|
saturation,
|
|
color,
|
|
luminosity,
|
|
}
|
|
}
|