package com.mutu.mapapi.views.overlay;
import com.mutu.mapapi.ResourceProxy;
import com.mutu.mapapi.views.MapView;
import com.mutu.mapapi.views.safecanvas.ISafeCanvas;
import com.mutu.mapapi.views.safecanvas.SafeTranslatedCanvas;
import android.content.Context;
import android.graphics.Canvas;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.os.Build;
/**
* An overlay class that uses the safe drawing canvas to draw itself and can be zoomed in to high
* levels without drawing issues.
*
* @see {@link ISafeCanvas}
*/
public abstract class SafeDrawOverlay extends Overlay {
private static final SafeTranslatedCanvas sSafeCanvas = new SafeTranslatedCanvas();
private static final Matrix sMatrix = new Matrix();
private boolean mUseSafeCanvas = true;
protected abstract void drawSafe(final ISafeCanvas c, final MapView osmv, final boolean shadow);
public SafeDrawOverlay(Context ctx) {
super(ctx);
}
public SafeDrawOverlay(ResourceProxy pResourceProxy) {
super(pResourceProxy);
}
@Override
protected void draw(final Canvas c, final MapView osmv, final boolean shadow) {
sSafeCanvas.setCanvas(c);
if (this.isUsingSafeCanvas()) {
// Find the screen offset
Rect screenRect = osmv.getProjection().getScreenRect();
sSafeCanvas.xOffset = -screenRect.left;
sSafeCanvas.yOffset = -screenRect.top;
// Save the canvas state
c.save();
if (osmv.getMapOrientation() != 0) {
// Un-rotate the maps so we can rotate them accurately using the safe canvas
c.rotate(-osmv.getMapOrientation(), screenRect.exactCenterX(),
screenRect.exactCenterY());
}
// Since the translate calls still take a float, there can be rounding errors
// Let's calculate the error, and adjust for it.
final int floatErrorX = screenRect.left - (int) (float) screenRect.left;
final int floatErrorY = screenRect.top - (int) (float) screenRect.top;
// Translate the coordinates
if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.HONEYCOMB) {
final float scaleX = osmv.getScaleX();
final float scaleY = osmv.getScaleY();
c.translate(screenRect.left * scaleX, screenRect.top * scaleY);
c.translate(floatErrorX, floatErrorY);
} else {
c.getMatrix(sMatrix);
sMatrix.preTranslate(screenRect.left, screenRect.top);
sMatrix.preTranslate(floatErrorX, floatErrorY);
c.setMatrix(sMatrix);
}
if (osmv.getMapOrientation() != 0) {
// Safely re-rotate the maps
sSafeCanvas.rotate(osmv.getMapOrientation(), (double) screenRect.exactCenterX(),
(double) screenRect.exactCenterY());
}
} else {
sSafeCanvas.xOffset = 0;
sSafeCanvas.yOffset = 0;
}
this.drawSafe(sSafeCanvas, osmv, shadow);
if (this.isUsingSafeCanvas()) {
c.restore();
}
}
public boolean isUsingSafeCanvas() {
return mUseSafeCanvas;
}
public void setUseSafeCanvas(boolean useSafeCanvas) {
mUseSafeCanvas = useSafeCanvas;
}
}