-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathShadowRenderer.java
More file actions
125 lines (116 loc) · 4.38 KB
/
Copy pathShadowRenderer.java
File metadata and controls
125 lines (116 loc) · 4.38 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
package Charts;
import java.awt.Color;
import java.awt.image.BufferedImage;
public class ShadowRenderer {
private int size = 5;
private float opacity = 0.5f;
private Color color = Color.BLACK;
public ShadowRenderer() {
this(5, 0.5f, Color.BLACK);
}
public ShadowRenderer(final int size, final float opacity, final Color color) {
this.size = size;
this.opacity = opacity;
this.color = color;
}
public Color getColor() {
return color;
}
public float getOpacity() {
return opacity;
}
public int getSize() {
return size;
}
public BufferedImage createShadow(final BufferedImage image) {
int shadowSize = size * 2;
int srcWidth = image.getWidth();
int srcHeight = image.getHeight();
int dstWidth = srcWidth + shadowSize;
int dstHeight = srcHeight + shadowSize;
int left = size;
int right = shadowSize - left;
int yStop = dstHeight - right;
int shadowRgb = color.getRGB() & 0x00FFFFFF;
int[] aHistory = new int[shadowSize];
int historyIdx;
int aSum;
BufferedImage dst = new BufferedImage(dstWidth, dstHeight, BufferedImage.TYPE_INT_ARGB);
int[] dstBuffer = new int[dstWidth * dstHeight];
int[] srcBuffer = new int[srcWidth * srcHeight];
GraphicsUtilities.getPixels(image, 0, 0, srcWidth, srcHeight, srcBuffer);
int lastPixelOffset = right * dstWidth;
float hSumDivider = 1.0f / shadowSize;
float vSumDivider = opacity / shadowSize;
int[] hSumLookup = new int[256 * shadowSize];
for (int i = 0; i < hSumLookup.length; i++) {
hSumLookup[i] = (int) (i * hSumDivider);
}
int[] vSumLookup = new int[256 * shadowSize];
for (int i = 0; i < vSumLookup.length; i++) {
vSumLookup[i] = (int) (i * vSumDivider);
}
int srcOffset;
for (int srcY = 0, dstOffset = left * dstWidth; srcY < srcHeight; srcY++) {
for (historyIdx = 0; historyIdx < shadowSize;) {
aHistory[historyIdx++] = 0;
}
aSum = 0;
historyIdx = 0;
srcOffset = srcY * srcWidth;
for (int srcX = 0; srcX < srcWidth; srcX++) {
int a = hSumLookup[aSum];
dstBuffer[dstOffset++] = a << 24;
aSum -= aHistory[historyIdx];
a = srcBuffer[srcOffset + srcX] >>> 24;
aHistory[historyIdx] = a;
aSum += a;
if (++historyIdx >= shadowSize) {
historyIdx -= shadowSize;
}
}
for (int i = 0; i < shadowSize; i++) {
int a = hSumLookup[aSum];
dstBuffer[dstOffset++] = a << 24;
aSum -= aHistory[historyIdx];
if (++historyIdx >= shadowSize) {
historyIdx -= shadowSize;
}
}
}
for (int x = 0, bufferOffset = 0; x < dstWidth; x++, bufferOffset = x) {
aSum = 0;
for (historyIdx = 0; historyIdx < left;) {
aHistory[historyIdx++] = 0;
}
for (int y = 0; y < right; y++, bufferOffset += dstWidth) {
int a = dstBuffer[bufferOffset] >>> 24;
aHistory[historyIdx++] = a;
aSum += a;
}
bufferOffset = x;
historyIdx = 0;
for (int y = 0; y < yStop; y++, bufferOffset += dstWidth) {
int a = vSumLookup[aSum];
dstBuffer[bufferOffset] = a << 24 | shadowRgb;
aSum -= aHistory[historyIdx];
a = dstBuffer[bufferOffset + lastPixelOffset] >>> 24;
aHistory[historyIdx] = a;
aSum += a;
if (++historyIdx >= shadowSize) {
historyIdx -= shadowSize;
}
}
for (int y = yStop; y < dstHeight; y++, bufferOffset += dstWidth) {
int a = vSumLookup[aSum];
dstBuffer[bufferOffset] = a << 24 | shadowRgb;
aSum -= aHistory[historyIdx];
if (++historyIdx >= shadowSize) {
historyIdx -= shadowSize;
}
}
}
GraphicsUtilities.setPixels(dst, 0, 0, dstWidth, dstHeight, dstBuffer);
return dst;
}
}