278 lines
6.7 KiB
Java
278 lines
6.7 KiB
Java
/*
|
|
* Copyright 2012 Hannes Janetzek
|
|
*
|
|
* 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.oscim.renderer.layer;
|
|
|
|
import static org.oscim.renderer.GLRenderer.COORD_SCALE;
|
|
import static org.oscim.renderer.layer.TextureItem.TEXTURE_HEIGHT;
|
|
import static org.oscim.renderer.layer.TextureItem.TEXTURE_WIDTH;
|
|
|
|
|
|
import android.graphics.Canvas;
|
|
public final class TextLayer extends TextureLayer {
|
|
|
|
//private static String TAG = TextureLayer.class.getName();
|
|
|
|
private final static int LBIT_MASK = 0xfffffffe;
|
|
|
|
private static int mFontPadX = 1;
|
|
//private static int mFontPadY = 1;
|
|
|
|
public TextItem labels;
|
|
private final Canvas mCanvas;
|
|
|
|
public TextItem getLabels() {
|
|
return labels;
|
|
}
|
|
|
|
public TextLayer() {
|
|
type = Layer.SYMBOL;
|
|
//mCanvas = Graphics.res.getCanvas();
|
|
mCanvas = new Canvas();
|
|
fixed = true;
|
|
}
|
|
|
|
public void addText(TextItem item) {
|
|
TextItem it = labels;
|
|
|
|
for (; it != null; it = it.next) {
|
|
|
|
if (item.text == it.text) {
|
|
while (it.next != null
|
|
// break if next item uses different text style
|
|
&& item.text == it.next.text
|
|
// check same string instance
|
|
&& item.string != it.string
|
|
// check same string
|
|
&& !item.string.equals(it.string))
|
|
it = it.next;
|
|
|
|
// unify duplicate string :)
|
|
// Note: this is required for 'packing test' in prepare to work!
|
|
if (item.string != it.string && item.string.equals(it.string))
|
|
item.string = it.string;
|
|
|
|
// insert after text of same type and/or before same string
|
|
item.next = it.next;
|
|
it.next = item;
|
|
return;
|
|
}
|
|
}
|
|
|
|
item.next = labels;
|
|
labels = item;
|
|
}
|
|
|
|
@Override
|
|
public boolean prepare() {
|
|
|
|
short numIndices = 0;
|
|
short offsetIndices = 0;
|
|
|
|
VertexItem vi = vertexItems = VertexItem.pool.get();
|
|
int pos = vi.used; // 0
|
|
short buf[] = vi.vertices;
|
|
|
|
verticesCnt = 0;
|
|
|
|
int advanceY = 0;
|
|
float x = 0;
|
|
float y = 0;
|
|
float yy;
|
|
|
|
TextureItem to = TextureItem.pool.get();
|
|
textures = to;
|
|
mCanvas.setBitmap(to.bitmap);
|
|
|
|
for (TextItem it = labels; it != null;) {
|
|
|
|
float width = it.width + 2 * mFontPadX;
|
|
float height = (int) (it.text.fontHeight) + 0.5f;
|
|
|
|
if (height > advanceY)
|
|
advanceY = (int) height;
|
|
|
|
if (x + width > TEXTURE_WIDTH) {
|
|
x = 0;
|
|
y += advanceY;
|
|
advanceY = (int) (height + 0.5f);
|
|
|
|
if (y + height > TEXTURE_HEIGHT) {
|
|
to.offset = offsetIndices;
|
|
to.vertices = (short) (numIndices - offsetIndices);
|
|
offsetIndices = numIndices;
|
|
|
|
to.next = TextureItem.pool.get();
|
|
to = to.next;
|
|
|
|
mCanvas.setBitmap(to.bitmap);
|
|
|
|
x = 0;
|
|
y = 0;
|
|
advanceY = (int) height;
|
|
}
|
|
}
|
|
|
|
//yy = y + (height - 1) - it.text.fontDescent - mFontPadY;
|
|
yy = y + height - it.text.fontDescent; // - mFontPadY;
|
|
|
|
if (it.text.stroke != null)
|
|
mCanvas.drawText(it.string, x + it.width / 2, yy, it.text.stroke);
|
|
|
|
mCanvas.drawText(it.string, x + it.width / 2, yy, it.text.paint);
|
|
|
|
// FIXME !!!
|
|
if (width > TEXTURE_WIDTH)
|
|
width = TEXTURE_WIDTH;
|
|
|
|
float hw = width / 2.0f;
|
|
float hh = height / 2.0f;
|
|
|
|
float hh2 = hh;
|
|
//if (!it.text.caption) {
|
|
// // displace by baseline
|
|
// float desc = 0; //(hh - (height - it.text.fontDescent) / 2);
|
|
//
|
|
// //float desc = it.text.fontDescent / 2;
|
|
// hh2 = hh + desc;
|
|
// hh = hh - desc;
|
|
//}
|
|
|
|
// texture coordinates
|
|
short u1 = (short) (COORD_SCALE * x);
|
|
short v1 = (short) (COORD_SCALE * y);
|
|
short u2 = (short) (COORD_SCALE * (x + width));
|
|
short v2 = (short) (COORD_SCALE * (y + height));
|
|
|
|
while (it != null) {
|
|
|
|
short x1, x2, x3, x4, y1, y3, y2, y4;
|
|
|
|
if (it.text.caption) {
|
|
//if (it.origin == 0) {
|
|
x1 = x3 = (short) (COORD_SCALE * -hw);
|
|
x2 = x4 = (short) (COORD_SCALE * hw);
|
|
y1 = y2 = (short) (COORD_SCALE * hh);
|
|
y3 = y4 = (short) (COORD_SCALE * -hh);
|
|
//} else {
|
|
// x1 = x3 = (short) (SCALE * 0);
|
|
// x2 = x4 = (short) (SCALE * width);
|
|
// y1 = y2 = (short) (SCALE * 0);
|
|
// y3 = y4 = (short) (SCALE * -height);
|
|
//}
|
|
} else {
|
|
float vx = it.x1 - it.x2;
|
|
float vy = it.y1 - it.y2;
|
|
float a = (float) Math.sqrt(vx * vx + vy * vy);
|
|
vx = vx / a;
|
|
vy = vy / a;
|
|
|
|
float ux = -vy * hh;
|
|
float uy = vx * hh;
|
|
|
|
float ux2 = -vy * hh2;
|
|
float uy2 = vx * hh2;
|
|
|
|
vx *= hw;
|
|
vy *= hw;
|
|
|
|
// top-left
|
|
x1 = (short) (COORD_SCALE * (vx - ux));
|
|
y1 = (short) (COORD_SCALE * (vy - uy));
|
|
// top-right
|
|
x2 = (short) (COORD_SCALE * (-vx - ux));
|
|
y2 = (short) (COORD_SCALE * (-vy - uy));
|
|
// bot-right
|
|
x4 = (short) (COORD_SCALE * (-vx + ux2));
|
|
y4 = (short) (COORD_SCALE * (-vy + uy2));
|
|
// bot-left
|
|
x3 = (short) (COORD_SCALE * (vx + ux2));
|
|
y3 = (short) (COORD_SCALE * (vy + uy2));
|
|
}
|
|
|
|
// add vertices
|
|
int tmp = (int) (COORD_SCALE * it.x) & LBIT_MASK;
|
|
short tx = (short) (tmp | (it.text.caption ? 1 : 0));
|
|
short ty = (short) (COORD_SCALE * it.y);
|
|
|
|
if (pos == VertexItem.SIZE) {
|
|
vi.used = VertexItem.SIZE;
|
|
vi = vi.next = VertexItem.pool.get();
|
|
buf = vi.vertices;
|
|
pos = 0;
|
|
}
|
|
|
|
// top-left
|
|
buf[pos++] = tx;
|
|
buf[pos++] = ty;
|
|
buf[pos++] = x1;
|
|
buf[pos++] = y1;
|
|
buf[pos++] = u1;
|
|
buf[pos++] = v2;
|
|
// bot-left
|
|
buf[pos++] = tx;
|
|
buf[pos++] = ty;
|
|
buf[pos++] = x3;
|
|
buf[pos++] = y3;
|
|
buf[pos++] = u1;
|
|
buf[pos++] = v1;
|
|
// top-right
|
|
buf[pos++] = tx;
|
|
buf[pos++] = ty;
|
|
buf[pos++] = x2;
|
|
buf[pos++] = y2;
|
|
buf[pos++] = u2;
|
|
buf[pos++] = v2;
|
|
// bot-right
|
|
buf[pos++] = tx;
|
|
buf[pos++] = ty;
|
|
buf[pos++] = x4;
|
|
buf[pos++] = y4;
|
|
buf[pos++] = u2;
|
|
buf[pos++] = v1;
|
|
|
|
// six indices to draw the four vertices
|
|
numIndices += TextureRenderer.INDICES_PER_SPRITE;
|
|
verticesCnt += 4;
|
|
|
|
if (it.next == null || (it.next.text != it.text) || (it.next.string != it.string)) {
|
|
it = it.next;
|
|
break;
|
|
}
|
|
it = it.next;
|
|
|
|
}
|
|
x += width;
|
|
}
|
|
|
|
vi.used = pos;
|
|
|
|
to.offset = offsetIndices;
|
|
to.vertices = (short) (numIndices - offsetIndices);
|
|
|
|
return true;
|
|
}
|
|
|
|
@Override
|
|
protected void clear() {
|
|
TextureItem.pool.releaseAll(textures);
|
|
TextItem.pool.releaseAll(labels);
|
|
VertexItem.pool.releaseAll(vertexItems);
|
|
textures = null;
|
|
labels = null;
|
|
vertexItems = null;
|
|
verticesCnt = 0;
|
|
}
|
|
}
|