/* * Copyright 2010, 2011, 2012 mapsforge.org * * This program is free software: you can redistribute it and/or modify it under the * terms of the GNU Lesser General Public License as published by the Free Software * Foundation, either version 3 of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, but WITHOUT ANY * WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A * PARTICULAR PURPOSE. See the GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License along with * this program. If not, see <http://www.gnu.org/licenses/>. */ package org.mapsforge.android.maps.mapgenerator.databaserenderer; import java.util.List; import org.mapsforge.core.model.Tile; import android.graphics.Bitmap; import android.graphics.Canvas; import android.graphics.Color; import android.graphics.Matrix; import android.graphics.Paint; import android.graphics.Path; import android.graphics.Typeface; /** * A CanvasRasterer uses a Canvas for drawing. * * @see <a href="http://developer.android.com/reference/android/graphics/Canvas.html">Canvas</a> */ class CanvasRasterer { private static final Paint PAINT_BITMAP_FILTER = new Paint(Paint.FILTER_BITMAP_FLAG); private static final Paint PAINT_TILE_COORDINATES = new Paint(Paint.ANTI_ALIAS_FLAG); private static final Paint PAINT_TILE_COORDINATES_STROKE = new Paint(Paint.ANTI_ALIAS_FLAG); private static final Paint PAINT_TILE_FRAME = new Paint(Paint.ANTI_ALIAS_FLAG); private static final float[] TILE_FRAME = new float[] { 0, 0, 0, Tile.TILE_SIZE, 0, Tile.TILE_SIZE, Tile.TILE_SIZE, Tile.TILE_SIZE, Tile.TILE_SIZE, Tile.TILE_SIZE, Tile.TILE_SIZE, 0 }; private static void configurePaints() { PAINT_TILE_COORDINATES.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD)); PAINT_TILE_COORDINATES.setTextSize(20); PAINT_TILE_COORDINATES_STROKE.setTypeface(Typeface.defaultFromStyle(Typeface.BOLD)); PAINT_TILE_COORDINATES_STROKE.setStyle(Paint.Style.STROKE); PAINT_TILE_COORDINATES_STROKE.setStrokeWidth(5); PAINT_TILE_COORDINATES_STROKE.setTextSize(20); PAINT_TILE_COORDINATES_STROKE.setColor(Color.WHITE); } private final Canvas canvas; private final Path path; private final Matrix symbolMatrix; CanvasRasterer() { this.canvas = new Canvas(); this.symbolMatrix = new Matrix(); this.path = new Path(); this.path.setFillType(Path.FillType.EVEN_ODD); configurePaints(); } private void drawTileCoordinate(String string, int offsetY) { this.canvas.drawText(string, 20, offsetY, PAINT_TILE_COORDINATES_STROKE); this.canvas.drawText(string, 20, offsetY, PAINT_TILE_COORDINATES); } void drawNodes(List<PointTextContainer> pointTextContainers) { for (int index = pointTextContainers.size() - 1; index >= 0; --index) { PointTextContainer pointTextContainer = pointTextContainers.get(index); if (pointTextContainer.paintBack != null) { this.canvas.drawText(pointTextContainer.text, pointTextContainer.x, pointTextContainer.y, pointTextContainer.paintBack); } this.canvas.drawText(pointTextContainer.text, pointTextContainer.x, pointTextContainer.y, pointTextContainer.paintFront); } } void drawSymbols(List<SymbolContainer> symbolContainers) { for (int index = symbolContainers.size() - 1; index >= 0; --index) { SymbolContainer symbolContainer = symbolContainers.get(index); if (symbolContainer.alignCenter) { int pivotX = symbolContainer.symbol.getWidth() >> 1; int pivotY = symbolContainer.symbol.getHeight() >> 1; this.symbolMatrix.setRotate(symbolContainer.rotation, pivotX, pivotY); this.symbolMatrix.postTranslate(symbolContainer.x - pivotX, symbolContainer.y - pivotY); } else { this.symbolMatrix.setRotate(symbolContainer.rotation); this.symbolMatrix.postTranslate(symbolContainer.x, symbolContainer.y); } this.canvas.drawBitmap(symbolContainer.symbol, this.symbolMatrix, PAINT_BITMAP_FILTER); } } void drawTileCoordinates(Tile tile) { drawTileCoordinate("X: " + tile.tileX, 30); drawTileCoordinate("Y: " + tile.tileY, 60); drawTileCoordinate("Z: " + tile.zoomLevel, 90); } void drawTileFrame() { this.canvas.drawLines(TILE_FRAME, PAINT_TILE_FRAME); } void drawWayNames(List<WayTextContainer> wayTextContainers) { for (int index = wayTextContainers.size() - 1; index >= 0; --index) { WayTextContainer wayTextContainer = wayTextContainers.get(index); this.path.rewind(); float[] textCoordinates = wayTextContainer.coordinates; this.path.moveTo(textCoordinates[0], textCoordinates[1]); for (int i = 2; i < textCoordinates.length; i += 2) { this.path.lineTo(textCoordinates[i], textCoordinates[i + 1]); } this.canvas.drawTextOnPath(wayTextContainer.text, this.path, 0, 3, wayTextContainer.paint); } } void drawWays(List<List<List<ShapePaintContainer>>> drawWays) { int levelsPerLayer = drawWays.get(0).size(); for (int layer = 0, layers = drawWays.size(); layer < layers; ++layer) { List<List<ShapePaintContainer>> shapePaintContainers = drawWays.get(layer); for (int level = 0; level < levelsPerLayer; ++level) { List<ShapePaintContainer> wayList = shapePaintContainers.get(level); for (int index = wayList.size() - 1; index >= 0; --index) { ShapePaintContainer shapePaintContainer = wayList.get(index); this.path.rewind(); switch (shapePaintContainer.shapeContainer.getShapeType()) { case CIRCLE: CircleContainer circleContainer = (CircleContainer) shapePaintContainer.shapeContainer; this.path.addCircle(circleContainer.x, circleContainer.y, circleContainer.radius, Path.Direction.CCW); break; case WAY: WayContainer wayContainer = (WayContainer) shapePaintContainer.shapeContainer; float[][] coordinates = wayContainer.coordinates; for (int j = 0; j < coordinates.length; ++j) { // make sure that the coordinates sequence is not empty if (coordinates[j].length > 2) { this.path.moveTo(coordinates[j][0], coordinates[j][1]); for (int i = 2; i < coordinates[j].length; i += 2) { this.path.lineTo(coordinates[j][i], coordinates[j][i + 1]); } } } break; } this.canvas.drawPath(this.path, shapePaintContainer.paint); } } } } void fill(int color) { this.canvas.drawColor(color); } void setCanvasBitmap(Bitmap bitmap) { this.canvas.setBitmap(bitmap); } }