/**
* Copyright 2010 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.html;
import com.google.gwt.canvas.dom.client.Context2d;
import com.google.gwt.core.client.JsArrayNumber;
import forplay.core.Asserts;
import forplay.core.Path;
class HtmlPath implements Path {
private static final int CMD_ARC = 3;
private static final int CMD_CLOSE = 4;
private static final int CMD_LINE = 1;
private static final int CMD_MOVE = 0;
private static final int CMD_QUAD = 2;
private JsArrayNumber list = JsArrayNumber.createArray().cast();
@Override
public void arcTo(float radius, float x, float y) {
list.push(CMD_ARC);
list.push(radius);
list.push(x);
list.push(y);
}
@Override
public void close() {
list.push(CMD_CLOSE);
}
@Override
public void lineTo(float x, float y) {
list.push(CMD_LINE);
list.push(x);
list.push(y);
}
@Override
public void moveTo(float x, float y) {
list.push(CMD_MOVE);
list.push(x);
list.push(y);
}
@Override
public void quadraticCurveTo(float cpx, float cpy, float x, float y) {
list.push(CMD_QUAD);
list.push(cpx);
list.push(cpy);
list.push(x);
list.push(y);
}
@Override
public void reset() {
list.setLength(0);
}
void replay(Context2d ctx) {
ctx.beginPath();
int len = list.length(), i = 0;
double x = 0, y = 0;
while (i < len) {
switch ((int) list.get(i++)) {
case CMD_MOVE: {
x = list.get(i++);
y = list.get(i++);
ctx.moveTo(x, y);
break;
}
case CMD_LINE: {
x = list.get(i++);
y = list.get(i++);
ctx.lineTo(x, y);
break;
}
case CMD_QUAD: {
double cpx = list.get(i++);
double cpy = list.get(i++);
x = list.get(i++);
y = list.get(i++);
ctx.quadraticCurveTo(cpx, cpy, x, y);
break;
}
case CMD_ARC: {
double curX = x, curY = 0;
double radius = list.get(i++);
x = list.get(i++);
y = list.get(i++);
ctx.arcTo(curX, curY, x, y, radius);
break;
}
case CMD_CLOSE: {
ctx.closePath();
break;
}
default:
throw new AssertionError("Corrupt command list");
}
}
}
float[] getVertices() {
int len = list.length();
Asserts.check(len % 2 == 0);
float[] vertices = new float[len];
for (int v = 0; v < len;) {
int cmd = (int) list.get(v);
if (v == vertices.length -2) {
Asserts.check(cmd == CMD_CLOSE);
} else {
Asserts.check(cmd == CMD_MOVE);
}
vertices[v] = (float) list.get(v + 1);
vertices[v+1] = (float) list.get(v + 2);
}
return vertices;
}
void replay(Path path) {
path.reset();
int len = list.length(), i = 0;
float x = 0, y = 0;
while (i < len) {
switch ((int) list.get(i++)) {
case CMD_MOVE: {
x = (float) list.get(i++);
y = (float) list.get(i++);
path.moveTo(x, y);
break;
}
case CMD_LINE: {
x = (float) list.get(i++);
y = (float) list.get(i++);
path.lineTo(x, y);
break;
}
case CMD_QUAD: {
float cpx = (float) list.get(i++);
float cpy = (float) list.get(i++);
x = (float) list.get(i++);
y = (float) list.get(i++);
path.quadraticCurveTo(cpx, cpy, x, y);
break;
}
case CMD_ARC: {
float radius = (float) list.get(i++);
x = (float) list.get(i++);
y = (float) list.get(i++);
path.arcTo(x, y, radius);
break;
}
case CMD_CLOSE: {
path.close();
break;
}
default:
throw new AssertionError("Corrupt command list");
}
}
}
}