Moved html engine

This commit is contained in:
Andrea Cavalli 2018-07-22 23:40:51 +02:00
parent dd9fab3841
commit 20097e1fcb
5 changed files with 752 additions and 752 deletions

View File

@ -1,296 +1,296 @@
package org.warp.picalculator.gui.graphicengine.html; package org.warp.picalculator.gui.graphicengine.html;
import java.io.IOException; import java.io.IOException;
import java.util.concurrent.Semaphore; import java.util.concurrent.Semaphore;
import org.teavm.jso.JSBody; import org.teavm.jso.JSBody;
import org.teavm.jso.JSObject; import org.teavm.jso.JSObject;
import org.teavm.jso.browser.Window; import org.teavm.jso.browser.Window;
import org.teavm.jso.canvas.CanvasGradient; import org.teavm.jso.canvas.CanvasGradient;
import org.teavm.jso.canvas.CanvasRenderingContext2D; import org.teavm.jso.canvas.CanvasRenderingContext2D;
import org.teavm.jso.dom.events.Event; import org.teavm.jso.dom.events.Event;
import org.teavm.jso.dom.events.EventListener; import org.teavm.jso.dom.events.EventListener;
import org.teavm.jso.dom.events.EventTarget; import org.teavm.jso.dom.events.EventTarget;
import org.teavm.jso.dom.events.KeyboardEvent; import org.teavm.jso.dom.events.KeyboardEvent;
import org.teavm.jso.dom.html.HTMLButtonElement; import org.teavm.jso.dom.html.HTMLButtonElement;
import org.teavm.jso.dom.html.HTMLCanvasElement; import org.teavm.jso.dom.html.HTMLCanvasElement;
import org.teavm.jso.dom.html.HTMLDocument; import org.teavm.jso.dom.html.HTMLDocument;
import org.teavm.jso.dom.html.HTMLElement; import org.teavm.jso.dom.html.HTMLElement;
import org.teavm.jso.dom.html.HTMLInputElement; import org.teavm.jso.dom.html.HTMLInputElement;
import org.teavm.jso.dom.xml.NodeList; import org.teavm.jso.dom.xml.NodeList;
import org.teavm.jso.json.JSON; import org.teavm.jso.json.JSON;
import org.warp.picalculator.PlatformUtils; import org.warp.picalculator.PlatformUtils;
import org.warp.picalculator.Utils; import org.warp.picalculator.Utils;
import org.warp.picalculator.deps.DSemaphore; import org.warp.picalculator.deps.DSemaphore;
import org.warp.picalculator.deps.StorageUtils; import org.warp.picalculator.deps.StorageUtils;
import org.warp.picalculator.device.Keyboard; import org.warp.picalculator.device.Keyboard;
import org.warp.picalculator.gui.graphicengine.BinaryFont; import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.Renderer;
import org.warp.picalculator.gui.graphicengine.RenderingLoop; import org.warp.picalculator.gui.graphicengine.RenderingLoop;
import org.warp.picalculator.gui.graphicengine.Skin; import org.warp.picalculator.gui.graphicengine.Skin;
import org.warp.picalculator.gui.graphicengine.cpu.CPUFont; import org.warp.picalculator.gui.graphicengine.cpu.CPUFont;
import org.warp.picalculator.gui.graphicengine.cpu.CPUSkin; import org.warp.picalculator.gui.graphicengine.cpu.CPUSkin;
public class HtmlEngine implements GraphicEngine { public class HtmlEngine implements GraphicEngine {
private boolean initialized; private boolean initialized;
public DSemaphore exitSemaphore = new DSemaphore(0); public DSemaphore exitSemaphore = new DSemaphore(0);
private static final HTMLDocument document = Window.current().getDocument(); private static final HTMLDocument document = Window.current().getDocument();
private HTMLCanvasElement canvas; private HTMLCanvasElement canvas;
private CanvasRenderingContext2D g; private CanvasRenderingContext2D g;
private RenderingLoop renderingLoop; private RenderingLoop renderingLoop;
private HtmlRenderer renderer; private HtmlRenderer renderer;
private int width = -1, height = -1; private int width = -1, height = -1;
private final int frameTime = (int) (1000d/10d); private final int frameTime = (int) (1000d/10d);
@Override @Override
public int[] getSize() { public int[] getSize() {
return new int[] { getWidth(), getHeight() }; return new int[] { getWidth(), getHeight() };
} }
@Override @Override
public boolean isInitialized() { public boolean isInitialized() {
return initialized; return initialized;
} }
@Override @Override
public void setTitle(String title) { public void setTitle(String title) {
HtmlEngine.setHTMLTitle(title); HtmlEngine.setHTMLTitle(title);
} }
@JSBody(params = {"wndTitle"}, script = "document.title = wndTitle") @JSBody(params = {"wndTitle"}, script = "document.title = wndTitle")
private static native void setHTMLTitle(String wndTitle); private static native void setHTMLTitle(String wndTitle);
@Override @Override
public void setResizable(boolean r) {} public void setResizable(boolean r) {}
@Override @Override
public void setDisplayMode(int ww, int wh) { public void setDisplayMode(int ww, int wh) {
canvas.setWidth(ww); canvas.setWidth(ww);
width = ww; width = ww;
canvas.setHeight(wh); canvas.setHeight(wh);
height = wh; height = wh;
} }
private String previousValue=""; private String previousValue="";
@Override @Override
public void create(Runnable onInitialized) { public void create(Runnable onInitialized) {
canvas = (HTMLCanvasElement) document.createElement("canvas"); canvas = (HTMLCanvasElement) document.createElement("canvas");
g = (CanvasRenderingContext2D ) canvas.getContext("2d"); g = (CanvasRenderingContext2D ) canvas.getContext("2d");
HTMLInputElement keyInput = (HTMLInputElement) document.createElement("input"); HTMLInputElement keyInput = (HTMLInputElement) document.createElement("input");
keyInput.setType("text"); keyInput.setType("text");
keyInput.getStyle().setProperty("opacity", "0.1"); keyInput.getStyle().setProperty("opacity", "0.1");
setDisplayMode(480, 320); setDisplayMode(480, 320);
document.getElementById("container").appendChild(canvas); document.getElementById("container").appendChild(canvas);
document.getBody().appendChild(keyInput); document.getBody().appendChild(keyInput);
keyInput.setTabIndex(0); keyInput.setTabIndex(0);
keyInput.addEventListener("keydown", (KeyboardEvent evt) -> { keyInput.addEventListener("keydown", (KeyboardEvent evt) -> {
evt.preventDefault(); evt.preventDefault();
new Thread(() -> { new Thread(() -> {
previousValue = keyInput.getValue(); previousValue = keyInput.getValue();
Keyboard.debugKeyPressed(evt.getKeyCode()); Keyboard.debugKeyPressed(evt.getKeyCode());
System.out.println(evt.getKeyCode()); System.out.println(evt.getKeyCode());
System.out.println(""+(int) evt.getKey().charAt(0)); System.out.println(""+(int) evt.getKey().charAt(0));
}).start(); }).start();
}); });
keyInput.addEventListener("input", (Event evt) -> { keyInput.addEventListener("input", (Event evt) -> {
evt.preventDefault(); evt.preventDefault();
final String previousValue = this.previousValue; final String previousValue = this.previousValue;
final String newValue = keyInput.getValue(); final String newValue = keyInput.getValue();
final int prevLen = previousValue.length(); final int prevLen = previousValue.length();
final int newLen = newValue.length(); final int newLen = newValue.length();
new Thread(() -> { new Thread(() -> {
if (newLen == prevLen) { if (newLen == prevLen) {
} else if (newLen - prevLen == 1) { } else if (newLen - prevLen == 1) {
Keyboard.debugKeyPressed((int) newValue.toUpperCase().charAt(newLen-1)); Keyboard.debugKeyPressed((int) newValue.toUpperCase().charAt(newLen-1));
} else if (newLen - prevLen > 1) { } else if (newLen - prevLen > 1) {
for (int i = 0; i < newLen - prevLen; i++) { for (int i = 0; i < newLen - prevLen; i++) {
Keyboard.debugKeyPressed((int) newValue.toUpperCase().charAt(prevLen + i)); Keyboard.debugKeyPressed((int) newValue.toUpperCase().charAt(prevLen + i));
} }
} else if (newLen - prevLen < 1) { } else if (newLen - prevLen < 1) {
for (int i = 0; i < prevLen - newLen; i++) { for (int i = 0; i < prevLen - newLen; i++) {
Keyboard.debugKeyPressed(8); Keyboard.debugKeyPressed(8);
} }
} }
}).start(); }).start();
}); });
canvas.addEventListener("click", (Event evt) -> { canvas.addEventListener("click", (Event evt) -> {
keyInput.focus(); keyInput.focus();
}); });
document.addEventListener("DOMContentLoaded", (Event e) -> { document.addEventListener("DOMContentLoaded", (Event e) -> {
keyInput.focus(); keyInput.focus();
}); });
NodeList<? extends HTMLElement> buttons = document.getBody().getElementsByTagName("button"); NodeList<? extends HTMLElement> buttons = document.getBody().getElementsByTagName("button");
for (int i = 0; i < buttons.getLength(); i++) { for (int i = 0; i < buttons.getLength(); i++) {
if (buttons.item(i).hasAttribute("keycode")) { if (buttons.item(i).hasAttribute("keycode")) {
buttons.item(i).addEventListener("click", (Event evt) -> { buttons.item(i).addEventListener("click", (Event evt) -> {
evt.preventDefault(); evt.preventDefault();
EventTarget target = evt.getCurrentTarget(); EventTarget target = evt.getCurrentTarget();
HTMLButtonElement button = target.cast(); HTMLButtonElement button = target.cast();
new Thread(() -> { new Thread(() -> {
try { try {
if (button.hasAttribute("keycode") && button.getAttribute("keycode").contains(",")) { if (button.hasAttribute("keycode") && button.getAttribute("keycode").contains(",")) {
String code = button.getAttribute("keycode"); String code = button.getAttribute("keycode");
String[] coordinates = code.split(",", 2); String[] coordinates = code.split(",", 2);
boolean removeshift = Keyboard.shift && Integer.parseInt(coordinates[0]) != 0 && Integer.parseInt(coordinates[1]) != 0; boolean removeshift = Keyboard.shift && Integer.parseInt(coordinates[0]) != 0 && Integer.parseInt(coordinates[1]) != 0;
boolean removealpha = Keyboard.alpha && Integer.parseInt(coordinates[0]) != 0 && Integer.parseInt(coordinates[1]) != 1; boolean removealpha = Keyboard.alpha && Integer.parseInt(coordinates[0]) != 0 && Integer.parseInt(coordinates[1]) != 1;
Keyboard.keyPressedRaw(Integer.parseInt(coordinates[0]), Integer.parseInt(coordinates[1])); Keyboard.keyPressedRaw(Integer.parseInt(coordinates[0]), Integer.parseInt(coordinates[1]));
if (removeshift) { if (removeshift) {
Keyboard.keyPressedRaw(0,0); Keyboard.keyPressedRaw(0,0);
} }
if (removealpha) { if (removealpha) {
Keyboard.keyPressedRaw(0,1); Keyboard.keyPressedRaw(0,1);
} }
Thread.sleep(100); Thread.sleep(100);
Keyboard.keyReleasedRaw(Integer.parseInt(coordinates[0]), Integer.parseInt(coordinates[1])); Keyboard.keyReleasedRaw(Integer.parseInt(coordinates[0]), Integer.parseInt(coordinates[1]));
if (removeshift) { if (removeshift) {
Keyboard.keyReleasedRaw(0,0); Keyboard.keyReleasedRaw(0,0);
} }
if (removealpha) { if (removealpha) {
Keyboard.keyReleasedRaw(0,1); Keyboard.keyReleasedRaw(0,1);
} }
} else { } else {
if (Keyboard.alpha && !Keyboard.shift) { if (Keyboard.alpha && !Keyboard.shift) {
if (button.hasAttribute("keycodea")) { if (button.hasAttribute("keycodea")) {
Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycodea"))); Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycodea")));
} else { } else {
Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycode"))); Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycode")));
} }
} else if (!Keyboard.alpha && Keyboard.shift) { } else if (!Keyboard.alpha && Keyboard.shift) {
if (button.hasAttribute("keycodes")) { if (button.hasAttribute("keycodes")) {
Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycodes"))); Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycodes")));
} else { } else {
Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycode"))); Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycode")));
} }
} else if (Keyboard.alpha && Keyboard.shift) { } else if (Keyboard.alpha && Keyboard.shift) {
if (button.hasAttribute("keycodesa")) { if (button.hasAttribute("keycodesa")) {
Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycodesa"))); Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycodesa")));
} else { } else {
if (button.hasAttribute("keycodes")) { if (button.hasAttribute("keycodes")) {
Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycodes"))); Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycodes")));
} else { } else {
Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycode"))); Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycode")));
} }
} }
} else { } else {
Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycode"))); Keyboard.debugKeyPressed(Integer.parseInt(button.getAttribute("keycode")));
} }
} }
} catch (Exception ex) { } catch (Exception ex) {
ex.printStackTrace(); ex.printStackTrace();
} }
}).start(); }).start();
}); });
} }
} }
renderer = new HtmlRenderer(this, g); renderer = new HtmlRenderer(this, g);
initialized = true; initialized = true;
if (onInitialized != null) { if (onInitialized != null) {
onInitialized.run(); onInitialized.run();
} }
} }
@Override @Override
public boolean wasResized() { public boolean wasResized() {
return false; return false;
} }
@Override @Override
public int getWidth() { public int getWidth() {
if (width == -1) { if (width == -1) {
width = canvas.getWidth(); width = canvas.getWidth();
} }
return width; return width;
} }
@Override @Override
public int getHeight() { public int getHeight() {
if (height == -1) { if (height == -1) {
height = canvas.getHeight(); height = canvas.getHeight();
} }
return height; return height;
} }
@Override @Override
public void destroy() { public void destroy() {
document.getBody().removeChild(canvas); document.getBody().removeChild(canvas);
initialized = false; initialized = false;
exitSemaphore.release(); exitSemaphore.release();
} }
@Override @Override
public void start(RenderingLoop d) { public void start(RenderingLoop d) {
renderingLoop = d; renderingLoop = d;
final Thread th = new Thread(() -> { final Thread th = new Thread(() -> {
try { try {
double extratime = 0; double extratime = 0;
while (initialized) { while (initialized) {
final long start = System.currentTimeMillis(); final long start = System.currentTimeMillis();
repaint(); repaint();
final long end = System.currentTimeMillis(); final long end = System.currentTimeMillis();
final double delta = (end - start) / 1000d; final double delta = (end - start) / 1000d;
final int deltaInt = (int) Math.floor(delta); final int deltaInt = (int) Math.floor(delta);
final int extraTimeInt = (int) Math.floor(extratime); final int extraTimeInt = (int) Math.floor(extratime);
if (extraTimeInt + deltaInt < frameTime) { if (extraTimeInt + deltaInt < frameTime) {
Thread.sleep(frameTime - (extraTimeInt + deltaInt)); Thread.sleep(frameTime - (extraTimeInt + deltaInt));
extratime = 0; extratime = 0;
} else { } else {
extratime += delta - frameTime; extratime += delta - frameTime;
} }
} }
} catch (final InterruptedException e) { } catch (final InterruptedException e) {
e.printStackTrace(); e.printStackTrace();
} }
}); });
PlatformUtils.setThreadName(th, "Canvas rendering thread"); PlatformUtils.setThreadName(th, "Canvas rendering thread");
PlatformUtils.setDaemon(th); PlatformUtils.setDaemon(th);
th.start(); th.start();
} }
@Override @Override
public void repaint() { public void repaint() {
renderingLoop.refresh(); renderingLoop.refresh();
} }
@Override @Override
public HtmlRenderer getRenderer() { public HtmlRenderer getRenderer() {
return renderer; return renderer;
} }
@Override @Override
public HtmlFont loadFont(String fontName) throws IOException { public HtmlFont loadFont(String fontName) throws IOException {
return new HtmlFont(fontName); return new HtmlFont(fontName);
} }
@Override @Override
public HtmlFont loadFont(String path, String fontName) throws IOException { public HtmlFont loadFont(String path, String fontName) throws IOException {
return new HtmlFont(fontName); return new HtmlFont(fontName);
} }
@Override @Override
public HtmlSkin loadSkin(String file) throws IOException { public HtmlSkin loadSkin(String file) throws IOException {
return new HtmlSkin(file); return new HtmlSkin(file);
} }
@Override @Override
public void waitForExit() { public void waitForExit() {
try { try {
exitSemaphore.acquire(); exitSemaphore.acquire();
} catch (final InterruptedException e) {} } catch (final InterruptedException e) {}
} }
@Override @Override
public boolean isSupported() { public boolean isSupported() {
return PlatformUtils.isJavascript; return PlatformUtils.isJavascript;
} }
@Override @Override
public boolean doesRefreshPauses() { public boolean doesRefreshPauses() {
return true; return true;
} }
} }

View File

@ -1,68 +1,68 @@
package org.warp.picalculator.gui.graphicengine.html; package org.warp.picalculator.gui.graphicengine.html;
import java.io.IOException; import java.io.IOException;
import org.teavm.jso.browser.Window; import org.teavm.jso.browser.Window;
import org.teavm.jso.canvas.CanvasRenderingContext2D; import org.teavm.jso.canvas.CanvasRenderingContext2D;
import org.teavm.jso.dom.html.HTMLCanvasElement; import org.teavm.jso.dom.html.HTMLCanvasElement;
import org.teavm.jso.dom.html.HTMLDocument; import org.teavm.jso.dom.html.HTMLDocument;
import org.teavm.jso.dom.html.HTMLImageElement; import org.teavm.jso.dom.html.HTMLImageElement;
import org.teavm.jso.typedarrays.Uint8ClampedArray; import org.teavm.jso.typedarrays.Uint8ClampedArray;
import org.warp.picalculator.StaticVars; import org.warp.picalculator.StaticVars;
import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.cpu.CPUFont; import org.warp.picalculator.gui.graphicengine.cpu.CPUFont;
public class HtmlFont extends CPUFont { public class HtmlFont extends CPUFont {
public HTMLCanvasElement imgEl; public HTMLCanvasElement imgEl;
public CanvasRenderingContext2D imgElCtx; public CanvasRenderingContext2D imgElCtx;
public HtmlFont(String fontName) throws IOException { public HtmlFont(String fontName) throws IOException {
super(fontName); super(fontName);
HTMLDocument doc = Window.current().getDocument(); HTMLDocument doc = Window.current().getDocument();
imgEl = doc.createElement("canvas").cast(); imgEl = doc.createElement("canvas").cast();
imgEl.setClassName("hidden"); imgEl.setClassName("hidden");
doc.getBody().appendChild(imgEl); doc.getBody().appendChild(imgEl);
imgElCtx = imgEl.getContext("2d").cast(); imgElCtx = imgEl.getContext("2d").cast();
imgEl.setWidth(this.charW); imgEl.setWidth(this.charW);
imgEl.setHeight(this.charH * intervalsTotalSize); imgEl.setHeight(this.charH * intervalsTotalSize);
int screenPos = 0; int screenPos = 0;
int currentInt; int currentInt;
int currentIntBitPosition; int currentIntBitPosition;
int bitData; int bitData;
int j; int j;
imgElCtx.clearRect(0, 0, imgEl.getWidth(), imgEl.getHeight()); imgElCtx.clearRect(0, 0, imgEl.getWidth(), imgEl.getHeight());
imgElCtx.setFillStyle("#000"); imgElCtx.setFillStyle("#000");
int minBound = 0, maxBound = intervalsTotalSize-1; int minBound = 0, maxBound = intervalsTotalSize-1;
System.out.println("charIndex:"+0); System.out.println("charIndex:"+0);
System.out.println("minBound"+minBound); System.out.println("minBound"+minBound);
System.out.println("maxBound"+maxBound); System.out.println("maxBound"+maxBound);
for (int charIndex = minBound; charIndex < maxBound; charIndex++) { for (int charIndex = minBound; charIndex < maxBound; charIndex++) {
for (int dy = 0; dy < charH; dy++) { for (int dy = 0; dy < charH; dy++) {
for (int dx = 0; dx < charW; dx++) { for (int dx = 0; dx < charW; dx++) {
j = dx; j = dx;
final int bit = dx + dy * charW; final int bit = dx + dy * charW;
currentInt = (int) (Math.floor(bit) / (HtmlFont.intBits)); currentInt = (int) (Math.floor(bit) / (HtmlFont.intBits));
currentIntBitPosition = bit - (currentInt * HtmlFont.intBits); currentIntBitPosition = bit - (currentInt * HtmlFont.intBits);
final int charIdx = charIndex * charIntCount + currentInt; final int charIdx = charIndex * charIntCount + currentInt;
if (charIdx >= 0 && charIdx < chars32.length) { if (charIdx >= 0 && charIdx < chars32.length) {
bitData = (chars32[charIdx] >> currentIntBitPosition) & 1; bitData = (chars32[charIdx] >> currentIntBitPosition) & 1;
if (bitData == 1) { if (bitData == 1) {
imgElCtx.fillRect( dx, charIndex*charH+dy, 1, 1 ); imgElCtx.fillRect( dx, charIndex*charH+dy, 1, 1 );
} }
} }
} }
} }
} }
} }
@Override @Override
public void use(GraphicEngine d) { public void use(GraphicEngine d) {
if (d.getRenderer() instanceof HtmlRenderer) { if (d.getRenderer() instanceof HtmlRenderer) {
((HtmlRenderer) d.getRenderer()).f = this; ((HtmlRenderer) d.getRenderer()).f = this;
} }
} }
} }

View File

@ -1,292 +1,292 @@
package org.warp.picalculator.gui.graphicengine.html; package org.warp.picalculator.gui.graphicengine.html;
import org.teavm.jso.canvas.CanvasImageSource; import org.teavm.jso.canvas.CanvasImageSource;
import org.teavm.jso.canvas.CanvasRenderingContext2D; import org.teavm.jso.canvas.CanvasRenderingContext2D;
import org.teavm.jso.dom.html.HTMLImageElement; import org.teavm.jso.dom.html.HTMLImageElement;
import org.teavm.jso.typedarrays.Uint8ClampedArray; import org.teavm.jso.typedarrays.Uint8ClampedArray;
import org.warp.picalculator.StaticVars; import org.warp.picalculator.StaticVars;
import org.warp.picalculator.gui.graphicengine.Renderer; import org.warp.picalculator.gui.graphicengine.Renderer;
public class HtmlRenderer implements Renderer { public class HtmlRenderer implements Renderer {
private static final boolean ENABLE_SUPERSAMPLING = false; private static final boolean ENABLE_SUPERSAMPLING = false;
private static final boolean ENABLE_TRANSPARENCY = true; private static final boolean ENABLE_TRANSPARENCY = true;
private String currentColor = "#000000ff"; private String currentColor = "#000000ff";
private String clearColor = "#000000ff"; private String clearColor = "#000000ff";
HtmlFont f = null; HtmlFont f = null;
HtmlSkin currentSkin = null; HtmlSkin currentSkin = null;
private final CanvasRenderingContext2D g; private final CanvasRenderingContext2D g;
private final HtmlEngine e; private final HtmlEngine e;
public HtmlRenderer(HtmlEngine e, CanvasRenderingContext2D g) { public HtmlRenderer(HtmlEngine e, CanvasRenderingContext2D g) {
this.g = g; this.g = g;
this.e = e; this.e = e;
} }
private String toHex(int c) { private String toHex(int c) {
final int a = c >> 24 & 0xFF; final int a = c >> 24 & 0xFF;
final int r = c >> 16 & 0xFF; final int r = c >> 16 & 0xFF;
final int gg = c >> 8 & 0xFF; final int gg = c >> 8 & 0xFF;
final int b = c & 0xFF; final int b = c & 0xFF;
return String.format("#%02x%02x%02x%02x", r, gg, b, a); return String.format("#%02x%02x%02x%02x", r, gg, b, a);
} }
private String toHex8(int c) { private String toHex8(int c) {
final int r = c >> 16 & 0xFF; final int r = c >> 16 & 0xFF;
final int gg = c >> 8 & 0xFF; final int gg = c >> 8 & 0xFF;
final int b = c & 0xFF; final int b = c & 0xFF;
return String.format("#%02x%02x%02x", r, gg, b); return String.format("#%02x%02x%02x", r, gg, b);
} }
private String toHex(int r, int g, int b) { private String toHex(int r, int g, int b) {
return String.format("#%02x%02x%02x", r, g, b); return String.format("#%02x%02x%02x", r, g, b);
} }
private String toHex(int r, int g, int b, int a) { private String toHex(int r, int g, int b, int a) {
return String.format("#%02x%02x%02x%02x", r, g, b, a); return String.format("#%02x%02x%02x%02x", r, g, b, a);
} }
@Override @Override
public int glGetClearColor() { public int glGetClearColor() {
return hexToInt(clearColor); return hexToInt(clearColor);
} }
private int hexToInt(String hex) { private int hexToInt(String hex) {
switch (hex.length()) { switch (hex.length()) {
case 6: case 6:
return (0xFF << 24) | return (0xFF << 24) |
(Integer.valueOf(hex.substring(0, 2), 16) << 16) | (Integer.valueOf(hex.substring(0, 2), 16) << 16) |
(Integer.valueOf(hex.substring(2, 4), 16) << 8) | (Integer.valueOf(hex.substring(2, 4), 16) << 8) |
Integer.valueOf(hex.substring(4, 6), 16); Integer.valueOf(hex.substring(4, 6), 16);
case 6+1: case 6+1:
return (0xFF << 24) | return (0xFF << 24) |
(Integer.valueOf(hex.substring(0+1, 2+1), 16) << 16) | (Integer.valueOf(hex.substring(0+1, 2+1), 16) << 16) |
(Integer.valueOf(hex.substring(2+1, 4+1), 16) << 8) | (Integer.valueOf(hex.substring(2+1, 4+1), 16) << 8) |
Integer.valueOf(hex.substring(4+1, 6+1), 16); Integer.valueOf(hex.substring(4+1, 6+1), 16);
case 8: case 8:
return (Integer.valueOf(hex.substring(6, 8), 16) << 24) | return (Integer.valueOf(hex.substring(6, 8), 16) << 24) |
(Integer.valueOf(hex.substring(0, 2), 16) << 16) | (Integer.valueOf(hex.substring(0, 2), 16) << 16) |
(Integer.valueOf(hex.substring(2, 4), 16) << 8) | (Integer.valueOf(hex.substring(2, 4), 16) << 8) |
Integer.valueOf(hex.substring(4, 6), 16); Integer.valueOf(hex.substring(4, 6), 16);
case 8+1: case 8+1:
return (Integer.valueOf(hex.substring(6+1, 8+1), 16) << 24) | return (Integer.valueOf(hex.substring(6+1, 8+1), 16) << 24) |
(Integer.valueOf(hex.substring(0+1, 2+1), 16) << 16) | (Integer.valueOf(hex.substring(0+1, 2+1), 16) << 16) |
(Integer.valueOf(hex.substring(2+1, 4+1), 16) << 8) | (Integer.valueOf(hex.substring(2+1, 4+1), 16) << 8) |
Integer.valueOf(hex.substring(4+1, 6+1), 16); Integer.valueOf(hex.substring(4+1, 6+1), 16);
} }
return 0xFF000000; return 0xFF000000;
} }
@Override @Override
public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth, public void glFillRect(float x, float y, float width, float height, float uvX, float uvY, float uvWidth,
float uvHeight) { float uvHeight) {
if (currentSkin != null) { if (currentSkin != null) {
glDrawSkin((int) x, (int) y, (int) (x + width), (int) (y + height), (int) uvX, (int) uvY, (int) (uvWidth + uvX), (int) (uvHeight + uvY), true); glDrawSkin((int) x, (int) y, (int) (x + width), (int) (y + height), (int) uvX, (int) uvY, (int) (uvWidth + uvX), (int) (uvHeight + uvY), true);
} else { } else {
glFillColor(x, y, width, height); glFillColor(x, y, width, height);
} }
} }
@SuppressWarnings("unused") @SuppressWarnings("unused")
private void glDrawSkin(int x0, int y0, int x1, int y1, int s0, int t0, int s1, int t1, boolean transparent) { private void glDrawSkin(int x0, int y0, int x1, int y1, int s0, int t0, int s1, int t1, boolean transparent) {
final int[] size = e.getSize(); final int[] size = e.getSize();
x0 += StaticVars.screenPos[0]; x0 += StaticVars.screenPos[0];
y0 += StaticVars.screenPos[1]; y0 += StaticVars.screenPos[1];
final double incrementX = Math.abs((double) (x1 - x0) / (double) (s1 - s0)); final double incrementX = Math.abs((double) (x1 - x0) / (double) (s1 - s0));
final double incrementY = Math.abs((double) (y1 - y0) / (double) (t1 - t0)); final double incrementY = Math.abs((double) (y1 - y0) / (double) (t1 - t0));
final boolean flippedX = (x1 - x0) / (s1 - s0) < 0; final boolean flippedX = (x1 - x0) / (s1 - s0) < 0;
final boolean flippedY = (y1 - y0) / (t1 - t0) < 0; final boolean flippedY = (y1 - y0) / (t1 - t0) < 0;
int oldColor = 0; int oldColor = 0;
int newColor; int newColor;
final int onex = s0 <= s1 ? 1 : -1; final int onex = s0 <= s1 ? 1 : -1;
final int oney = t0 <= t1 ? 1 : -1; final int oney = t0 <= t1 ? 1 : -1;
int width = 0; int width = 0;
int height = 0; int height = 0;
if (onex == -1) { if (onex == -1) {
final int s00 = s0; final int s00 = s0;
s0 = s1; s0 = s1;
s1 = s00; s1 = s00;
width = s1 - s0; width = s1 - s0;
} }
if (oney == -1) { if (oney == -1) {
final int t00 = t0; final int t00 = t0;
t0 = t1; t0 = t1;
t1 = t00; t1 = t00;
height = t1 - t0; height = t1 - t0;
} }
if (x0 >= size[0] || y0 >= size[0]) { if (x0 >= size[0] || y0 >= size[0]) {
return; return;
} }
if (x0 + width >= size[0]) { if (x0 + width >= size[0]) {
s1 = size[0] - x0 + s0; s1 = size[0] - x0 + s0;
} }
if (y0 + height >= size[1]) { if (y0 + height >= size[1]) {
t1 = size[1] - y0 + t0; t1 = size[1] - y0 + t0;
} }
if (x0 < 0) { if (x0 < 0) {
if (onex == -1) { if (onex == -1) {
width += x0; width += x0;
s1 += x0 + 1; s1 += x0 + 1;
} else { } else {
s0 -= x0; s0 -= x0;
} }
x0 = 0; x0 = 0;
} }
if (y0 < 0) { if (y0 < 0) {
if (oney == -1) { if (oney == -1) {
height += y0; height += y0;
t1 += y0 + 1; t1 += y0 + 1;
} else { } else {
t0 -= y0; t0 -= y0;
} }
y0 = 0; y0 = 0;
} }
g.drawImage(currentSkin.getImgElement(), s0, t0, s1-s0, t1-t0, x0, y0, x1-x0, y1-y0); g.drawImage(currentSkin.getImgElement(), s0, t0, s1-s0, t1-t0, x0, y0, x1-x0, y1-y0);
} }
@Override @Override
public void glFillColor(float x, float y, float width, float height) { public void glFillColor(float x, float y, float width, float height) {
x += StaticVars.screenPos[0]; x += StaticVars.screenPos[0];
y += StaticVars.screenPos[1]; y += StaticVars.screenPos[1];
g.setFillStyle(currentColor); g.setFillStyle(currentColor);
g.fillRect( x, y, width, height ); g.fillRect( x, y, width, height );
} }
@Override @Override
public void glDrawStringRight(float x, float y, String text) { public void glDrawStringRight(float x, float y, String text) {
glDrawStringLeft(x - f.getStringWidth(text), y, text); glDrawStringLeft(x - f.getStringWidth(text), y, text);
} }
@Override @Override
public void glDrawStringLeft(float x, float y, String textString) { public void glDrawStringLeft(float x, float y, String textString) {
x += StaticVars.screenPos[0]; x += StaticVars.screenPos[0];
y += StaticVars.screenPos[1]; y += StaticVars.screenPos[1];
f.imgElCtx.setGlobalCompositeOperation("source-in"); f.imgElCtx.setGlobalCompositeOperation("source-in");
f.imgElCtx.setFillStyle(currentColor); f.imgElCtx.setFillStyle(currentColor);
f.imgElCtx.fillRect(0, 0, f.imgEl.getWidth(), f.imgEl.getHeight()); f.imgElCtx.fillRect(0, 0, f.imgEl.getWidth(), f.imgEl.getHeight());
final int[] text = f.getCharIndexes(textString); final int[] text = f.getCharIndexes(textString);
final int[] screenSize = e.getSize(); final int[] screenSize = e.getSize();
int cpos; int cpos;
final int l = text.length; final int l = text.length;
for (int i = 0; i < l; i++) { for (int i = 0; i < l; i++) {
cpos = (i * (f.charW)); cpos = (i * (f.charW));
final int charIndex = text[i]; final int charIndex = text[i];
g.drawImage(f.imgEl, 0, charIndex*f.charH, f.charW, f.charH, x+cpos, y, f.charW, f.charH); g.drawImage(f.imgEl, 0, charIndex*f.charH, f.charW, f.charH, x+cpos, y, f.charW, f.charH);
} }
} }
private int stackColors(int... color) { private int stackColors(int... color) {
double a = 0; double a = 0;
double r = 0; double r = 0;
double g = 0; double g = 0;
double b = 0; double b = 0;
for (final int newColor : color) { for (final int newColor : color) {
final double alpha = (newColor >> 24 & 0xFF) / 255d; final double alpha = (newColor >> 24 & 0xFF) / 255d;
a = a * (1d - alpha) + (newColor >> 24 & 0xFF) * alpha; a = a * (1d - alpha) + (newColor >> 24 & 0xFF) * alpha;
r = r * (1d - alpha) + (newColor >> 16 & 0xFF) * alpha; r = r * (1d - alpha) + (newColor >> 16 & 0xFF) * alpha;
g = g * (1d - alpha) + (newColor >> 8 & 0xFF) * alpha; g = g * (1d - alpha) + (newColor >> 8 & 0xFF) * alpha;
b = b * (1d - alpha) + (newColor & 0xFF) * alpha; b = b * (1d - alpha) + (newColor & 0xFF) * alpha;
} }
return ((int) a) << 24 | ((int) r) << 16 | ((int) g) << 8 | ((int) b); return ((int) a) << 24 | ((int) r) << 16 | ((int) g) << 8 | ((int) b);
} }
@Override @Override
public void glDrawStringCenter(float x, float y, String text) { public void glDrawStringCenter(float x, float y, String text) {
glDrawStringLeft(x - (f.getStringWidth(text) / 2), y, text); glDrawStringLeft(x - (f.getStringWidth(text) / 2), y, text);
} }
@Override @Override
public void glDrawLine(float x0, float y0, float x1, float y1) { public void glDrawLine(float x0, float y0, float x1, float y1) {
if (x1-x0 > 0 && y1-y0 > 0) { if (x1-x0 > 0 && y1-y0 > 0) {
g.beginPath(); g.beginPath();
g.moveTo(x0, y0); g.moveTo(x0, y0);
g.lineTo(x1, y1); g.lineTo(x1, y1);
g.stroke(); g.stroke();
} else { } else {
g.fillRect(x0, y0, (x1-x0)+1, (y1-y0)+1); g.fillRect(x0, y0, (x1-x0)+1, (y1-y0)+1);
} }
} }
@Override @Override
public void glDrawCharRight(int x, int y, char ch) { public void glDrawCharRight(int x, int y, char ch) {
glDrawStringRight(x, y, ch + ""); glDrawStringRight(x, y, ch + "");
} }
@Override @Override
public void glDrawCharLeft(int x, int y, char ch) { public void glDrawCharLeft(int x, int y, char ch) {
glDrawStringLeft(x, y, ch + ""); glDrawStringLeft(x, y, ch + "");
} }
@Override @Override
public void glDrawCharCenter(int x, int y, char ch) { public void glDrawCharCenter(int x, int y, char ch) {
glDrawStringCenter(x, y, ch + ""); glDrawStringCenter(x, y, ch + "");
} }
@Override @Override
public void glColor4i(int red, int green, int blue, int alpha) { public void glColor4i(int red, int green, int blue, int alpha) {
g.setFillStyle(currentColor = toHex(red, green, blue, alpha)); g.setFillStyle(currentColor = toHex(red, green, blue, alpha));
} }
@Override @Override
public void glColor4f(float red, float green, float blue, float alpha) { public void glColor4f(float red, float green, float blue, float alpha) {
glColor4i((int) (red * 255d), (int) (green * 255d), (int) (blue * 255d), (int) (alpha * 255d)); glColor4i((int) (red * 255d), (int) (green * 255d), (int) (blue * 255d), (int) (alpha * 255d));
} }
@Override @Override
public void glColor3i(int r, int gg, int b) { public void glColor3i(int r, int gg, int b) {
g.setFillStyle(currentColor = toHex(r, gg, b)); g.setFillStyle(currentColor = toHex(r, gg, b));
} }
@Override @Override
public void glColor3f(float red, float green, float blue) { public void glColor3f(float red, float green, float blue) {
glColor3i((int) (red * 255d), (int) (green * 255d), (int) (blue * 255d)); glColor3i((int) (red * 255d), (int) (green * 255d), (int) (blue * 255d));
} }
@Override @Override
public void glColor(int c) { public void glColor(int c) {
final int a = c >> 24 & 0xFF; final int a = c >> 24 & 0xFF;
final int r = c >> 16 & 0xFF; final int r = c >> 16 & 0xFF;
final int gg = c >> 8 & 0xFF; final int gg = c >> 8 & 0xFF;
final int b = c & 0xFF; final int b = c & 0xFF;
g.setFillStyle(currentColor = toHex(r, gg, b, a)); g.setFillStyle(currentColor = toHex(r, gg, b, a));
} }
@Override @Override
public void glClearSkin() { public void glClearSkin() {
currentSkin = null; currentSkin = null;
} }
@Override @Override
public void glClearColor4i(int red, int green, int blue, int alpha) { public void glClearColor4i(int red, int green, int blue, int alpha) {
clearColor = toHex(red, green, blue, alpha); clearColor = toHex(red, green, blue, alpha);
} }
@Override @Override
public void glClearColor4f(float red, float green, float blue, float alpha) { public void glClearColor4f(float red, float green, float blue, float alpha) {
clearColor = toHex((int)(red*255), clearColor = toHex((int)(red*255),
(int)(green*255), (int)(green*255),
(int)(blue*255), (int)(blue*255),
(int)(alpha*255)); (int)(alpha*255));
} }
@Override @Override
public void glClearColor(int c) { public void glClearColor(int c) {
final int r = c >> 16 & 0xFF; final int r = c >> 16 & 0xFF;
final int gg = c >> 8 & 0xFF; final int gg = c >> 8 & 0xFF;
final int b = c & 0xFF; final int b = c & 0xFF;
clearColor = toHex(r, gg, b); clearColor = toHex(r, gg, b);
} }
@Override @Override
public void glClear(int screenWidth, int screenHeight) { public void glClear(int screenWidth, int screenHeight) {
g.setFillStyle(clearColor); g.setFillStyle(clearColor);
g.fillRect(0, 0, screenWidth, screenHeight); g.fillRect(0, 0, screenWidth, screenHeight);
g.setFillStyle(currentColor); g.setFillStyle(currentColor);
} }
@Override @Override
public HtmlFont getCurrentFont() { public HtmlFont getCurrentFont() {
return f; return f;
} }
} }

View File

@ -1,86 +1,86 @@
package org.warp.picalculator.gui.graphicengine.html; package org.warp.picalculator.gui.graphicengine.html;
import java.io.IOException; import java.io.IOException;
import java.net.URISyntaxException; import java.net.URISyntaxException;
import org.teavm.jso.JSObject; import org.teavm.jso.JSObject;
import org.teavm.jso.browser.Window; import org.teavm.jso.browser.Window;
import org.teavm.jso.dom.html.HTMLDocument; import org.teavm.jso.dom.html.HTMLDocument;
import org.teavm.jso.dom.html.HTMLImageElement; import org.teavm.jso.dom.html.HTMLImageElement;
import org.warp.picalculator.deps.StorageUtils; import org.warp.picalculator.deps.StorageUtils;
import org.warp.picalculator.gui.graphicengine.GraphicEngine; import org.warp.picalculator.gui.graphicengine.GraphicEngine;
import org.warp.picalculator.gui.graphicengine.Skin; import org.warp.picalculator.gui.graphicengine.Skin;
import ar.com.hjg.pngj.PngReader; import ar.com.hjg.pngj.PngReader;
public class HtmlSkin implements Skin { public class HtmlSkin implements Skin {
private String url; private String url;
private int[] skinSize; private int[] skinSize;
private boolean initd; private boolean initd;
private HTMLImageElement imgEl; private HTMLImageElement imgEl;
public HtmlSkin(String file) throws IOException { public HtmlSkin(String file) throws IOException {
load(file); load(file);
} }
public void use(GraphicEngine d) { public void use(GraphicEngine d) {
if (d instanceof HtmlEngine) { if (d instanceof HtmlEngine) {
if (!initd) if (!initd)
initialize(d); initialize(d);
((HtmlEngine) d).getRenderer().currentSkin = this; ((HtmlEngine) d).getRenderer().currentSkin = this;
} }
} }
@Override @Override
public void load(String file) throws IOException { public void load(String file) throws IOException {
if (!file.startsWith("/")) if (!file.startsWith("/"))
file = "/"+file; file = "/"+file;
url = StorageUtils.basepath+file; url = StorageUtils.basepath+file;
try { try {
PngReader r = new PngReader(StorageUtils.getResourceStream(file)); PngReader r = new PngReader(StorageUtils.getResourceStream(file));
skinSize = new int[] { r.imgInfo.cols, r.imgInfo.rows }; skinSize = new int[] { r.imgInfo.cols, r.imgInfo.rows };
r.close(); r.close();
} catch (URISyntaxException e) { } catch (URISyntaxException e) {
IOException ex = new IOException(); IOException ex = new IOException();
ex.initCause(e); ex.initCause(e);
throw ex; throw ex;
} }
} }
@Override @Override
public void initialize(GraphicEngine d) { public void initialize(GraphicEngine d) {
HTMLDocument doc = Window.current().getDocument(); HTMLDocument doc = Window.current().getDocument();
imgEl = doc.createElement("img").cast(); imgEl = doc.createElement("img").cast();
imgEl.setSrc(url); imgEl.setSrc(url);
imgEl.setClassName("hidden"); imgEl.setClassName("hidden");
doc.getBody().appendChild(imgEl); doc.getBody().appendChild(imgEl);
initd = true; initd = true;
} }
@Override @Override
public boolean isInitialized() { public boolean isInitialized() {
return initd; return initd;
} }
@Override @Override
public int getSkinWidth() { public int getSkinWidth() {
return skinSize[0]; return skinSize[0];
} }
@Override @Override
public int getSkinHeight() { public int getSkinHeight() {
return skinSize[1]; return skinSize[1];
} }
public final String getUrl() { public final String getUrl() {
return url; return url;
} }
public final HTMLImageElement getImgElement() { public final HTMLImageElement getImgElement() {
return imgEl; return imgEl;
} }
} }

View File

@ -1,10 +1,10 @@
package org.warp.picalculator.gui.graphicengine.html; package org.warp.picalculator.gui.graphicengine.html;
import org.teavm.jso.JSProperty; import org.teavm.jso.JSProperty;
import org.teavm.jso.dom.events.Event; import org.teavm.jso.dom.events.Event;
public interface InputEvent extends Event { public interface InputEvent extends Event {
@JSProperty @JSProperty
String getValue(); String getValue();
} }