📄 cplayer.java
字号:
}
}
fusion.alpha = 100;
}
// Multiply Mode
// C = (A*aa*(1-ab) + B*ab*(1-aa) + A*B*aa*ab) / (aa + ab - aa*ab)
public void fusionWithMultiplyFullAlpha(CPLayer fusion, CPRect rc) {
CPRect rect = new CPRect(0, 0, width, height);
rect.clip(rc);
for (int j = rect.top; j < rect.bottom; j++) {
int off = rect.left + j * width;
for (int i = rect.left; i < rect.right; i++, off++) {
int color1 = data[off];
int alpha1 = (color1 >>> 24) * alpha / 100;
int color2 = fusion.data[off];
int alpha2 = (color2 >>> 24) * fusion.alpha / 100;
int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
if (newAlpha > 0) {
int alpha12 = alpha1 * alpha2 / 255;
int alpha1n2 = alpha1 * (alpha2 ^ 0xff) / 255;
int alphan12 = (alpha1 ^ 0xff) * alpha2 / 255;
fusion.data[off] = newAlpha << 24
| (((color1 >>> 16 & 0xff) * alpha1n2) + ((color2 >>> 16 & 0xff) * alphan12) + (color1 >>> 16 & 0xff)
* (color2 >>> 16 & 0xff) * alpha12 / 255)
/ newAlpha << 16
| (((color1 >>> 8 & 0xff) * alpha1n2) + ((color2 >>> 8 & 0xff) * alphan12) + (color1 >>> 8 & 0xff)
* (color2 >>> 8 & 0xff) * alpha12 / 255)
/ newAlpha << 8
| (((color1 & 0xff) * alpha1n2) + ((color2 & 0xff) * alphan12) + (color1 & 0xff)
* (color2 & 0xff) * alpha12 / 255) / newAlpha;
}
}
}
fusion.alpha = 100;
}
// Linear Dodge (Add) Mode
// C = (aa * A + ab * B) / (aa + ab - aa*ab)
public void fusionWithAddFullAlpha(CPLayer fusion, CPRect rc) {
CPRect rect = new CPRect(0, 0, width, height);
rect.clip(rc);
for (int j = rect.top; j < rect.bottom; j++) {
int off = rect.left + j * width;
for (int i = rect.left; i < rect.right; i++, off++) {
int color1 = data[off];
int alpha1 = (color1 >>> 24) * alpha / 100;
int color2 = fusion.data[off];
int alpha2 = (color2 >>> 24) * fusion.alpha / 100;
int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
if (newAlpha > 0) {
/*
* // this version seems slower than the Math.min one int r = (alpha2 * (color2 >>> 16 & 0xff) +
* alpha1 * (color1 >>> 16 & 0xff)) / newAlpha; r |= ((~((r & 0xffffff00) - 1) >> 16) | r) & 0xff;
* int g = (alpha2 * (color2 >>> 8 & 0xff) + alpha1 * (color1 >>> 8 & 0xff)) / newAlpha; g |= ((~((g &
* 0xffffff00) - 1) >> 16) | g) & 0xff; int b = (alpha2 * (color2 & 0xff) + alpha1 * (color1 &
* 0xff)) / newAlpha; b |= ((~((b & 0xffffff00) - 1) >> 16) | b) & 0xff;
*/
int r = Math.min(255, (alpha2 * (color2 >>> 16 & 0xff) + alpha1 * (color1 >>> 16 & 0xff))
/ newAlpha);
int g = Math.min(255, (alpha2 * (color2 >>> 8 & 0xff) + alpha1 * (color1 >>> 8 & 0xff)) / newAlpha);
int b = Math.min(255, (alpha2 * (color2 & 0xff) + alpha1 * (color1 & 0xff)) / newAlpha);
fusion.data[off] = newAlpha << 24 | r << 16 | g << 8 | b;
}
}
}
fusion.alpha = 100;
}
// Linear Burn (Sub) Mode
// C = (aa * A + ab * B - aa*ab ) / (aa + ab - aa*ab)
public void fusionWithSubtractFullAlpha(CPLayer fusion, CPRect rc) {
CPRect rect = new CPRect(0, 0, width, height);
rect.clip(rc);
for (int j = rect.top; j < rect.bottom; j++) {
int off = rect.left + j * width;
for (int i = rect.left; i < rect.right; i++, off++) {
int color1 = data[off];
int alpha1 = (color1 >>> 24) * alpha / 100;
int color2 = fusion.data[off];
int alpha2 = (color2 >>> 24) * fusion.alpha / 100;
int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
if (newAlpha > 0) {
int alpha12 = alpha1 * alpha2;
int r = (alpha2 * (color2 >>> 16 & 0xff) + alpha1 * (color1 >>> 16 & 0xff) - alpha12) / newAlpha;
r = r & (~r >>> 24); // binary magic to clamp negative values to zero without using a condition
int g = (alpha2 * (color2 >>> 8 & 0xff) + alpha1 * (color1 >>> 8 & 0xff) - alpha12) / newAlpha;
g = g & (~g >>> 24);
int b = (alpha2 * (color2 & 0xff) + alpha1 * (color1 & 0xff) - alpha12) / newAlpha;
b = b & (~b >>> 24);
fusion.data[off] = newAlpha << 24 | r << 16 | g << 8 | b;
}
}
}
fusion.alpha = 100;
}
// Screen Mode
// same as Multiply except all color channels are inverted and the result too
// C = 1 - (((1-A)*aa*(1-ab) + (1-B)*ab*(1-aa) + (1-A)*(1-B)*aa*ab) / (aa + ab - aa*ab))
public void fusionWithScreenFullAlpha(CPLayer fusion, CPRect rc) {
CPRect rect = new CPRect(0, 0, width, height);
rect.clip(rc);
for (int j = rect.top; j < rect.bottom; j++) {
int off = rect.left + j * width;
for (int i = rect.left; i < rect.right; i++, off++) {
int color1 = data[off];
int alpha1 = (color1 >>> 24) * alpha / 100;
int color2 = fusion.data[off];
int alpha2 = (color2 >>> 24) * fusion.alpha / 100;
int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
if (newAlpha > 0) {
int alpha12 = alpha1 * alpha2 / 255;
int alpha1n2 = alpha1 * (alpha2 ^ 0xff) / 255;
int alphan12 = (alpha1 ^ 0xff) * alpha2 / 255;
color1 ^= 0xffffff;
color2 ^= 0xffffff;
fusion.data[off] = newAlpha << 24
| (0xffffff ^ ((((color1 >>> 16 & 0xff) * alpha1n2) + ((color2 >>> 16 & 0xff) * alphan12) + (color1 >>> 16 & 0xff)
* (color2 >>> 16 & 0xff) * alpha12 / 255)
/ newAlpha << 16
| (((color1 >>> 8 & 0xff) * alpha1n2) + ((color2 >>> 8 & 0xff) * alphan12) + (color1 >>> 8 & 0xff)
* (color2 >>> 8 & 0xff) * alpha12 / 255)
/ newAlpha << 8 | (((color1 & 0xff) * alpha1n2)
+ ((color2 & 0xff) * alphan12) + (color1 & 0xff) * (color2 & 0xff) * alpha12 / 255)
/ newAlpha));
}
}
}
fusion.alpha = 100;
}
// Lighten Mode
// if B >= A: C = A*d + B*(1-d) and d = aa * (1-ab) / (aa + ab - aa*ab)
// if A > B: C = B*d + A*(1-d) and d = ab * (1-aa) / (aa + ab - aa*ab)
public void fusionWithLightenFullAlpha(CPLayer fusion, CPRect rc) {
CPRect rect = new CPRect(0, 0, width, height);
rect.clip(rc);
for (int j = rect.top; j < rect.bottom; j++) {
int off = rect.left + j * width;
for (int i = rect.left; i < rect.right; i++, off++) {
int color1 = data[off];
int alpha1 = (color1 >>> 24) * alpha / 100;
int color2 = fusion.data[off];
int alpha2 = (color2 >>> 24) * fusion.alpha / 100;
int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
if (newAlpha > 0) {
// This alpha is used when color1 > color2
int alpha12 = alpha2 * (alpha1 ^ 0xff) / newAlpha;
int invAlpha12 = alpha12 ^ 0xff;
// This alpha is used when color2 > color1
int alpha21 = alpha1 * (alpha2 ^ 0xff) / newAlpha;
int invAlpha21 = alpha21 ^ 0xff;
int color = newAlpha << 24;
int c1, c2;
c1 = (color1 >>> 16 & 0xff);
c2 = (color2 >>> 16 & 0xff);
color |= ((c2 >= c1) ? (c1 * alpha21 + c2 * invAlpha21) : (c2 * alpha12 + c1 * invAlpha12)) / 255 << 16;
c1 = (color1 >>> 8 & 0xff);
c2 = (color2 >>> 8 & 0xff);
color |= ((c2 >= c1) ? (c1 * alpha21 + c2 * invAlpha21) : (c2 * alpha12 + c1 * invAlpha12)) / 255 << 8;
c1 = color1 & 0xff;
c2 = color2 & 0xff;
color |= ((c2 >= c1) ? (c1 * alpha21 + c2 * invAlpha21) : (c2 * alpha12 + c1 * invAlpha12)) / 255;
fusion.data[off] = color;
}
}
}
fusion.alpha = 100;
}
// Darken Mode
// if B >= A: C = B*d + A*(1-d) and d = ab * (1-aa) / (aa + ab - aa*ab)
// if A > B: C = A*d + B*(1-d) and d = aa * (1-ab) / (aa + ab - aa*ab)
public void fusionWithDarkenFullAlpha(CPLayer fusion, CPRect rc) {
CPRect rect = new CPRect(0, 0, width, height);
rect.clip(rc);
for (int j = rect.top; j < rect.bottom; j++) {
int off = rect.left + j * width;
for (int i = rect.left; i < rect.right; i++, off++) {
int color1 = data[off];
int alpha1 = (color1 >>> 24) * alpha / 100;
int color2 = fusion.data[off];
int alpha2 = (color2 >>> 24) * fusion.alpha / 100;
int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
if (newAlpha > 0) {
// This alpha is used when color1 > color2
int alpha12 = alpha1 * (alpha2 ^ 0xff) / newAlpha;
int invAlpha12 = alpha12 ^ 0xff;
// This alpha is used when color2 > color1
int alpha21 = alpha2 * (alpha1 ^ 0xff) / newAlpha;
int invAlpha21 = alpha21 ^ 0xff;
int color = newAlpha << 24;
int c1, c2;
c1 = (color1 >>> 16 & 0xff);
c2 = (color2 >>> 16 & 0xff);
color |= ((c2 >= c1) ? (c2 * alpha21 + c1 * invAlpha21) : (c1 * alpha12 + c2 * invAlpha12)) / 255 << 16;
c1 = (color1 >>> 8 & 0xff);
c2 = (color2 >>> 8 & 0xff);
color |= ((c2 >= c1) ? (c2 * alpha21 + c1 * invAlpha21) : (c1 * alpha12 + c2 * invAlpha12)) / 255 << 8;
c1 = color1 & 0xff;
c2 = color2 & 0xff;
color |= ((c2 >= c1) ? (c2 * alpha21 + c1 * invAlpha21) : (c1 * alpha12 + c2 * invAlpha12)) / 255;
fusion.data[off] = color;
}
}
}
fusion.alpha = 100;
}
// Dodge Mode
//
// C = (aa*(1-ab)*A + (1-aa)*ab*B + aa*ab*B/(1-A)) / (aa + ab - aa*ab)
public void fusionWithDodgeFullAlpha(CPLayer fusion, CPRect rc) {
CPRect rect = new CPRect(0, 0, width, height);
rect.clip(rc);
for (int j = rect.top; j < rect.bottom; j++) {
int off = rect.left + j * width;
for (int i = rect.left; i < rect.right; i++, off++) {
int color1 = data[off];
int alpha1 = (color1 >>> 24) * alpha / 100;
if (alpha1 == 0) {
continue;
}
int color2 = fusion.data[off];
int alpha2 = (color2 >>> 24) * fusion.alpha / 100;
int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
if (newAlpha > 0) {
int alpha12 = alpha1 * alpha2 / 255;
int alpha1n2 = alpha1 * (alpha2 ^ 0xff) / 255;
int alphan12 = (alpha1 ^ 0xff) * alpha2 / 255;
int invColor1 = color1 ^ 0xffffffff;
fusion.data[off] = newAlpha << 24
| (((color1 >>> 16 & 0xff) * alpha1n2) + ((color2 >>> 16 & 0xff) * alphan12) + alpha12
* (((invColor1 >>> 16 & 0xff) == 0) ? 255 : Math.min(255, 255
* (color2 >>> 16 & 0xff) / (invColor1 >>> 16 & 0xff))))
/ newAlpha << 16
| (((color1 >>> 8 & 0xff) * alpha1n2) + ((color2 >>> 8 & 0xff) * alphan12) + alpha12
* (((invColor1 >>> 8 & 0xff) == 0) ? 255 : Math.min(255, 255
* (color2 >>> 8 & 0xff) / (invColor1 >>> 8 & 0xff))))
/ newAlpha << 8
| (((color1 & 0xff) * alpha1n2) + ((color2 & 0xff) * alphan12) + alpha12
* (((invColor1 & 0xff) == 0) ? 255 : Math.min(255, 255 * (color2 & 0xff)
/ (invColor1 & 0xff)))) / newAlpha;
}
}
}
fusion.alpha = 100;
}
// Burn Mode
//
// C = (aa*(1-ab)*A + (1-aa)*ab*B + aa*ab*(1-(1-B)/A)) / (aa + ab - aa*ab)
public void fusionWithBurnFullAlpha(CPLayer fusion, CPRect rc) {
CPRect rect = new CPRect(0, 0, width, height);
rect.clip(rc);
for (int j = rect.top; j < rect.bottom; j++) {
int off = rect.left + j * width;
for (int i = rect.left; i < rect.right; i++, off++) {
int color1 = data[off];
int alpha1 = (color1 >>> 24) * alpha / 100;
if (alpha1 == 0) {
continue;
}
int color2 = fusion.data[off];
int alpha2 = (color2 >>> 24) * fusion.alpha / 100;
int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
if (newAlpha > 0) {
int alpha12 = alpha1 * alpha2 / 255;
int alpha1n2 = alpha1 * (alpha2 ^ 0xff) / 255;
int alphan12 = (alpha1 ^ 0xff) * alpha2 / 255;
int invColor2 = color2 ^ 0xffffffff;
fusion.data[off] = newAlpha << 24
| (((color1 >>> 16 & 0xff) * alpha1n2) + ((color2 >>> 16 & 0xff) * alphan12) + alpha12
* (((color1 >>> 16 & 0xff) == 0) ? 0 : Math.min(255, 255
* (invColor2 >>> 16 & 0xff) / (color1 >>> 16 & 0xff)) ^ 0xff))
/ newAlpha << 16
| (((color1 >>> 8 & 0xff) * alpha1n2) + ((color2 >>> 8 & 0xff) * alphan12) + alpha12
* (((color1 >>> 8 & 0xff) == 0) ? 0 : Math.min(255, 255 * (invColor2 >>> 8 & 0xff)
/ (color1 >>> 8 & 0xff)) ^ 0xff))
/ newAlpha << 8
| (((color1 & 0xff) * alpha1n2) + ((color2 & 0xff) * alphan12) + alpha12
* (((color1 & 0xff) == 0) ? 0 : Math.min(255, 255 * (invColor2 & 0xff)
/ (color1 & 0xff)) ^ 0xff)) / newAlpha;
}
}
}
fusion.alpha = 100;
}
// Overlay Mode
// If B <= 0.5 C = (A*aa*(1-ab) + B*ab*(1-aa) + aa*ab*(2*A*B) / (aa + ab - aa*ab)
// If B > 0.5 C = (A*aa*(1-ab) + B*ab*(1-aa) + aa*ab*(1 - 2*(1-A)*(1-B)) / (aa + ab - aa*ab)
public void fusionWithOverlayFullAlpha(CPLayer fusion, CPRect rc) {
CPRect rect = new CPRect(0, 0, width, height);
rect.clip(rc);
for (int j = rect.top; j < rect.bottom; j++) {
int off = rect.left + j * width;
for (int i = rect.left; i < rect.right; i++, off++) {
int color1 = data[off];
int alpha1 = (color1 >>> 24) * alpha / 100;
if (alpha1 == 0) {
continue;
}
int color2 = fusion.data[off];
int alpha2 = (color2 >>> 24) * fusion.alpha / 100;
int newAlpha = alpha1 + alpha2 - alpha1 * alpha2 / 255;
if (newAlpha > 0) {
int alpha12 = alpha1 * alpha2 / 255;
int alpha1n2 = alpha1 * (alpha2 ^ 0xff) / 255;
int alphan12 = (alpha1 ^ 0xff) * alpha2 / 255;
int color = newAlpha << 24;
int c1, c2;
c1 = (color1 >>> 16 & 0xff);
c2 = (color2 >>> 16 & 0xff);
color |= (alpha1n2 * c1 + alphan12 * c2 + ((c2 <= 127) ? (alpha12 * 2 * c1 * c2 / 255)
: (alpha12 * ((2 * (c1 ^ 0xff) * (c2 ^ 0xff) / 255) ^ 0xff))))
/ newAlpha << 16;
c1 = (color1 >>> 8 & 0xff);
c2 = (color2 >>> 8 & 0xff);
color |= (alpha1n2 * c1 + alphan12 * c2 + ((c2 <= 127) ? (alpha12 * 2 * c1 * c2 / 255)
: (alpha12 * ((2 * (c1 ^ 0xff) * (c2 ^ 0xff) / 255) ^ 0xff))))
/ newAlpha << 8;
c1 = color1 & 0xff;
c2 = color2 & 0xff;
color |= (alpha1n2 * c1 + alphan12 * c2 + ((c2 <= 127) ? (alpha12 * 2 * c1 * c2 / 255)
: (alpha12 * ((2 * (c1 ^ 0xff) * (c2 ^ 0xff) / 255) ^ 0xff))))
/ newAlpha;
fusion.data[off] = color;
}
}
}
fusion.alpha = 100;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -