/**
* Copyright 2008 - 2015 The Loon Game Engine 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.
*
* @project loon
* @author cping
* @email:javachenpeng@yahoo.com
* @version 0.5
*/
package loon.android;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.WeakHashMap;
import loon.Graphics;
import loon.canvas.Canvas;
import loon.font.Font;
import loon.font.TextFormat;
import loon.font.TextLayout;
import loon.font.TextWrap;
import loon.geom.Dimension;
import loon.utils.Scale;
import android.graphics.Bitmap;
import android.graphics.Paint;
import android.graphics.Typeface;
import android.util.Pair;
public class AndroidGraphics extends Graphics {
public interface Refreshable {
void onSurfaceLost();
void onSurfaceCreated();
}
private final AndroidGame game;
private Map<Refreshable, Void> refreshables = Collections
.synchronizedMap(new WeakHashMap<Refreshable, Void>());
private final Map<Pair<String, Font.Style>, Typeface> fonts = new HashMap<Pair<String, Font.Style>, Typeface>();
private final Map<Pair<String, Font.Style>, String[]> ligatureHacks = new HashMap<Pair<String, Font.Style>, String[]>();
private Dimension screenSize = new Dimension();
private ScaleFunc canvasScaleFunc = new ScaleFunc() {
public Scale computeScale(float width, float height, Scale gfxScale) {
return gfxScale;
}
};
final Bitmap.Config preferredBitmapConfig;
public AndroidGraphics(AndroidGame game, Bitmap.Config bitmapConfig) {
super(game, new AndroidGL20(), game.setting.scaling() ? Scale.ONE
: new Scale(game.activity.scaleFactor()));
this.game = game;
this.preferredBitmapConfig = bitmapConfig;
}
void onSizeChanged(int viewWidth, int viewHeight) {
screenSize.width = viewWidth / scale.factor;
screenSize.height = viewHeight / scale.factor;
game.log().info(
"Updating size " + viewWidth + "x" + viewHeight + " / "
+ scale.factor + " -> " + screenSize);
viewportChanged(scale, viewWidth, viewHeight);
}
public void registerFont(String path, String name, Font.Style style,
String... ligatureGlyphs) {
try {
registerFont(game.assets().getTypeface(path), name, style,
ligatureGlyphs);
} catch (Exception e) {
game.reportError("Failed to load font [name=" + name + ", path="
+ path + "]", e);
}
}
public void registerFont(Typeface face, String name, Font.Style style,
String... ligatureGlyphs) {
Pair<String, Font.Style> key = Pair.create(name, style);
fonts.put(key, face);
ligatureHacks.put(key, ligatureGlyphs);
}
public void setCanvasFilterBitmaps(boolean filterBitmaps) {
if (filterBitmaps) {
AndroidCanvasState.PAINT_FLAGS |= Paint.FILTER_BITMAP_FLAG;
} else {
AndroidCanvasState.PAINT_FLAGS &= ~Paint.FILTER_BITMAP_FLAG;
}
}
public interface ScaleFunc {
Scale computeScale(float width, float height, Scale gfxScale);
}
public void setCanvasScaleFunc(ScaleFunc scaleFunc) {
if (scaleFunc == null) {
throw new NullPointerException("Scale func have not null");
}
canvasScaleFunc = scaleFunc;
}
@Override
public Dimension screenSize() {
return screenSize;
}
@Override
public Canvas createCanvas(float width, float height) {
Scale scale = canvasScaleFunc.computeScale(width, height, this.scale);
return createCanvasImpl(scale, scale.scaledCeil(width),
scale.scaledCeil(height));
}
@Override
public TextLayout layoutText(String text, TextFormat format) {
return AndroidTextLayout.layoutText(this, text, format);
}
@Override
public TextLayout[] layoutText(String text, TextFormat format, TextWrap wrap) {
return AndroidTextLayout.layoutText(this, text, format, wrap);
}
@Override
protected Canvas createCanvasImpl(Scale scale, int pixelWidth,
int pixelHeight) {
Bitmap bitmap = Bitmap.createBitmap(pixelWidth, pixelHeight,
preferredBitmapConfig);
return new AndroidCanvas(this, new AndroidImage(this, scale, bitmap,
"<canvas>"));
}
AndroidFont resolveFont(Font font) {
if (font == null) {
return AndroidFont.DEFAULT;
}
Pair<String, Font.Style> key = Pair.create(font.name, font.style);
Typeface face = fonts.get(key);
if (face == null) {
fonts.put(key, face = AndroidFont.create(font));
}
return new AndroidFont(face, font.size, ligatureHacks.get(key));
}
void onSurfaceCreated() {
for (Refreshable ref : refreshables.keySet()) {
ref.onSurfaceCreated();
}
}
void onSurfaceLost() {
for (Refreshable ref : refreshables.keySet()) {
ref.onSurfaceLost();
}
}
void addRefreshable(Refreshable ref) {
assert ref != null;
refreshables.put(ref, null);
}
void removeRefreshable(Refreshable ref) {
assert ref != null;
refreshables.remove(ref);
}
}