/**
* Copyright 2011 The ForPlay Authors
*
* 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.
*/
package forplay.java;
import java.awt.TexturePaint;
import java.awt.geom.Rectangle2D;
import static forplay.core.ForPlay.graphics;
import forplay.core.Asserts;
import forplay.core.Image;
import forplay.core.ImageLayer;
class JavaImageLayer extends JavaLayer implements ImageLayer {
private float width, height;
private boolean widthSet, heightSet;
private float sx, sy, sw, sh;
private boolean sourceRectSet;
private boolean repeatX, repeatY;
private JavaImage image;
private JavaImage cachedImage;
private boolean dirty = true;
JavaImageLayer() {
super();
}
JavaImageLayer(JavaImage image) {
super();
this.image = image;
}
@Override
public void clearHeight() {
heightSet = false;
}
@Override
public void clearSourceRect() {
sourceRectSet = false;
}
@Override
public void clearWidth() {
widthSet = false;
}
@Override
public Image image() {
return image;
}
@Override
public void setHeight(float height) {
Asserts.checkArgument(height > 0, "Height must be > 0");
heightSet = true;
if (this.height != height) {
this.height = height;
dirty = true;
}
}
@Override
public void setImage(Image image) {
Asserts.checkArgument(image instanceof JavaImage);
this.image = (JavaImage) image;
dirty = true;
}
@Override
public void setRepeatX(boolean repeat) {
Asserts.checkArgument(!repeat || !sourceRectSet, "Cannot repeat when source rect is used");
if (repeatX != repeat) {
repeatX = repeat;
dirty = true;
}
}
@Override
public void setRepeatY(boolean repeat) {
Asserts.checkArgument(!repeat || !sourceRectSet, "Cannot repeat when source rect is used");
if (repeatY != repeat) {
repeatY = repeat;
dirty = true;
}
}
@Override
public void setSourceRect(float sx, float sy, float sw, float sh) {
Asserts.checkState(!repeatX && !repeatY, "Cannot use source rect when repeating x or y");
sourceRectSet = true;
this.sx = sx;
this.sy = sy;
this.sw = sw;
this.sh = sh;
}
@Override
public void setWidth(float width) {
Asserts.checkArgument(width > 0, "Width must be > 0");
widthSet = true;
if (this.width != width) {
this.width = width;
dirty = true;
}
}
@Override
public void setSize(float width, float height) {
Asserts.checkArgument(width > 0 && height > 0,
"Width and height must be > 0 (got %dx%d)", width, height);
widthSet = true;
if (this.width != width) {
this.width = width;
dirty = true;
}
heightSet = true;
if (this.height != height) {
this.height = height;
dirty = true;
}
}
@Override
void paint(JavaCanvas canvas) {
if (!visible()) return;
canvas.save();
transform(canvas);
canvas.setAlpha(canvas.alpha() * alpha);
float dw = widthSet ? width : image.width();
float dh = heightSet ? height : image.height();
if (repeatX || repeatY) {
if (dirty) {
// repaint repeated image onto cached image
cachedImage = (JavaImage) graphics().createImage((int) dw, (int) dh);
float anchorWidth = repeatX ? image.width() : dw;
float anchorHeight = repeatY ? image.height() : dh;
TexturePaint tpaint =
new TexturePaint(image.img, new Rectangle2D.Float(0, 0, anchorWidth, anchorHeight));
((JavaCanvas) cachedImage.canvas()).gfx.setPaint(tpaint);
((JavaCanvas) cachedImage.canvas()).gfx.fill(new Rectangle2D.Float(0, 0, dw, dh));
dirty = false;
}
canvas.drawImage(cachedImage, 0, 0);
} else if (sourceRectSet) {
canvas.drawImage(image, 0, 0, dw, dh, sx, sy, sw, sh);
} else {
canvas.drawImage(image, 0, 0);
}
canvas.restore();
}
@Override
public float width() {
Asserts.checkNotNull(image, "Image must not be null");
if (widthSet) {
return width;
} else {
return image.width();
}
}
@Override
public float height() {
Asserts.checkNotNull(image, "Image must not be null");
if (heightSet) {
return height;
} else {
return image.height();
}
}
@Override
public float scaledWidth() {
return transform().scaleX() * width();
}
@Override
public float scaledHeight() {
return transform().scaleY() * height();
}
}