/**
*
* Copyright 2014
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not
* use this file except in compliance with the License. You may obtain a copy of
* the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
* WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
* License for the specific language governing permissions and limitations under
* the License.
*
* @project loon
* @author cping
* @email:javachenpeng@yahoo.com
* @version 0.4.1
*/
package loon.canvas;
import loon.LTexture;
public class LShadow {
private int size;
private float alpha;
private LColor color;
private LTexture texture;
public LShadow(String file, LColor c) {
this(Image.createImage(file), 5, 0.5f, c);
}
public LShadow(String file, int size, float a, LColor c) {
this(Image.createImage(file), size, a, c);
}
public LShadow(String file) {
this(Image.createImage(file), 5, 0.5f, LColor.black);
}
public LShadow(LTexture tex) {
this(tex.getImage(), 5, 0.5f, LColor.black);
}
public LShadow(Image image) {
this(image, 5, 0.5f, LColor.black);
}
/**
* 引入指定图像,并以此生成阴影.
*
* @param image
* 图像
* @param size
* 模糊程度(越高则图像越模糊)
* @param a
* 透明度
* @param c
* 希望阴影化区域显示的颜色
*/
public LShadow(Image image, int size, float a, LColor c) {
this.size = size;
this.alpha = 0.5f;
this.color = c;
Image tmp = this.makeShadow(image);
this.texture = tmp.texture();
if (tmp != null) {
tmp.close();
tmp = null;
}
}
private Image makeShadow(final Image image) {
int dstWidth = image.getWidth();
int dstHeight = image.getHeight();
int left = (size - 1) >> 1;
int right = size - left;
int xStart = left;
int xStop = dstWidth - right;
int yStart = left;
int yStop = dstHeight - right;
int shadowRgb = color.getRGB() & 0x00FFFFFF;
int[] aHistory = new int[size];
int historyIdx = 0;
int aSum;
int[] dataBuffer = image.getPixels();
int lastPixelOffset = right * dstWidth;
float sumDivider = alpha / size;
for (int y = 0, bufferOffset = 0; y < dstHeight; y++, bufferOffset = y
* dstWidth) {
aSum = 0;
historyIdx = 0;
for (int x = 0; x < size; x++, bufferOffset++) {
int a = dataBuffer[bufferOffset] >>> 24;
aHistory[x] = a;
aSum += a;
}
bufferOffset -= right;
for (int x = xStart; x < xStop; x++, bufferOffset++) {
int a = (int) (aSum * sumDivider);
dataBuffer[bufferOffset] = a << 24 | shadowRgb;
aSum -= aHistory[historyIdx];
a = dataBuffer[bufferOffset + right] >>> 24;
aHistory[historyIdx] = a;
aSum += a;
if (++historyIdx >= size) {
historyIdx -= size;
}
}
}
for (int x = 0, bufferOffset = 0; x < dstWidth; x++, bufferOffset = x) {
aSum = 0;
historyIdx = 0;
for (int y = 0; y < size; y++, bufferOffset += dstWidth) {
int a = dataBuffer[bufferOffset] >>> 24;
aHistory[y] = a;
aSum += a;
}
bufferOffset -= lastPixelOffset;
for (int y = yStart; y < yStop; y++, bufferOffset += dstWidth) {
int a = (int) (aSum * sumDivider);
dataBuffer[bufferOffset] = a << 24 | shadowRgb;
aSum -= aHistory[historyIdx];
a = dataBuffer[bufferOffset + lastPixelOffset] >>> 24;
aHistory[historyIdx] = a;
aSum += a;
if (++historyIdx >= size) {
historyIdx -= size;
}
}
}
Image dst = Image.createImage(image.getWidth(), image.getHeight());
dst.setPixels(dataBuffer, image.getWidth(), image.getHeight());
dataBuffer = null;
return dst;
}
public int getSize() {
return size;
}
public float getAlpha() {
return alpha;
}
public LColor getColor() {
return color;
}
public LTexture getTexture() {
return texture;
}
}