toni@1129: /** toni@1302: * Back 2 Browser Bytecode Translator toni@1302: * Copyright (C) 2012 Jaroslav Tulach toni@1129: * toni@1302: * This program is free software: you can redistribute it and/or modify toni@1302: * it under the terms of the GNU General Public License as published by toni@1302: * the Free Software Foundation, version 2 of the License. toni@1129: * toni@1302: * This program is distributed in the hope that it will be useful, toni@1302: * but WITHOUT ANY WARRANTY; without even the implied warranty of toni@1302: * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the toni@1302: * GNU General Public License for more details. toni@1129: * toni@1302: * You should have received a copy of the GNU General Public License toni@1302: * along with this program. Look for COPYING file in the top folder. toni@1302: * If not, see http://opensource.org/licenses/GPL-2.0. toni@1129: */ toni@1129: package net.java.html.canvas; toni@1129: toni@1150: import java.util.HashMap; toni@1150: import java.util.Objects; toni@1150: toni@1129: /** toni@1154: * Style for Stroke and Fill of GraphicsContext. Styles are created using toni@1154: * GraphicsContexts factory methods. If the Implementation supports it, native toni@1154: * Styles will be cached for performance reasons. This happens the first time toni@1154: * the Style is actually used. toni@1129: * toni@1129: * @author antonepple toni@1129: */ toni@1132: public class Style { toni@1132: toni@1154: Object cached; toni@1141: private int cacheHash; toni@1141: toni@1132: Style() { toni@1132: } toni@1141: toni@1141: void cache(Object toCache) { toni@1141: cacheHash = hashCode(); toni@1141: this.cached = toCache; toni@1141: } toni@1141: toni@1141: private boolean isCached() { toni@1141: return cacheHash == hashCode(); toni@1141: } toni@1141: toni@1141: Object getCached() { toni@1141: return isCached() ? cached : null; toni@1141: } toni@1150: toni@1150: public static final class Pattern extends Style { toni@1150: toni@1150: private Image imageResource; toni@1150: private String repeat; toni@1150: toni@1270: public Pattern(Image imageResource, String repeat) { toni@1150: this.imageResource = imageResource; toni@1150: this.repeat = repeat; toni@1150: } toni@1150: toni@1150: public Image getImageResource() { toni@1150: return imageResource; toni@1150: } toni@1150: toni@1150: public void setImageResource(Image imageResource) { toni@1150: this.imageResource = imageResource; toni@1150: } toni@1150: toni@1150: public String getRepeat() { toni@1150: return repeat; toni@1150: } toni@1150: toni@1150: public void setRepeat(String repeat) { toni@1150: this.repeat = repeat; toni@1150: } toni@1150: } toni@1150: toni@1150: public static final class Color extends Style { toni@1150: toni@1150: private String web; toni@1150: toni@1150: /** toni@1150: * Creates an RGB color specified with an HTML or CSS attribute string. toni@1150: * toni@1150: * @param webColor Colordefined as toni@1150: */ toni@1265: public Color(String webColor) { toni@1157: this.web = webColor; toni@1150: } toni@1150: toni@1150: public String getAsString() { toni@1150: return web; toni@1150: } toni@1150: } toni@1150: toni@1150: public static class LinearGradient extends Style { toni@1150: toni@1150: private HashMap stops; toni@1150: private double x0, y0, x1, y1; toni@1150: toni@1150: LinearGradient(double x0, double y0, double x1, double y1) { toni@1150: this.x0 = x0; toni@1150: this.y0 = y0; toni@1150: this.x1 = x1; toni@1150: this.y1 = y1; toni@1150: } toni@1150: toni@1150: void addColorStop(double position, String color) { toni@1150: if (stops == null) { toni@1150: stops = new HashMap<>(); toni@1150: } toni@1150: stops.put(position, color); toni@1150: } toni@1150: toni@1150: public HashMap getStops() { toni@1150: return stops; toni@1150: } toni@1150: toni@1150: public void setStops(HashMap stops) { toni@1150: this.stops = stops; toni@1150: } toni@1150: toni@1150: public double getX0() { toni@1150: return x0; toni@1150: } toni@1150: toni@1150: public void setX0(double x0) { toni@1150: this.x0 = x0; toni@1150: } toni@1150: toni@1150: public double getY0() { toni@1150: return y0; toni@1150: } toni@1150: toni@1150: public void setY0(double y0) { toni@1150: this.y0 = y0; toni@1150: } toni@1150: toni@1150: public double getX1() { toni@1150: return x1; toni@1150: } toni@1150: toni@1150: public void setX1(double x1) { toni@1150: this.x1 = x1; toni@1150: } toni@1150: toni@1150: public double getY1() { toni@1150: return y1; toni@1150: } toni@1150: toni@1150: public void setY1(double y1) { toni@1150: this.y1 = y1; toni@1150: } toni@1150: toni@1150: @Override toni@1150: public int hashCode() { toni@1150: int hash = 7; toni@1150: hash = 29 * hash + Objects.hashCode(this.stops); toni@1150: hash = 29 * hash + (int) (Double.doubleToLongBits(this.x0) ^ (Double.doubleToLongBits(this.x0) >>> 32)); toni@1150: hash = 29 * hash + (int) (Double.doubleToLongBits(this.y0) ^ (Double.doubleToLongBits(this.y0) >>> 32)); toni@1150: hash = 29 * hash + (int) (Double.doubleToLongBits(this.x1) ^ (Double.doubleToLongBits(this.x1) >>> 32)); toni@1150: hash = 29 * hash + (int) (Double.doubleToLongBits(this.y1) ^ (Double.doubleToLongBits(this.y1) >>> 32)); toni@1150: return hash; toni@1150: } toni@1150: toni@1150: @Override toni@1150: public boolean equals(Object obj) { toni@1150: if (obj == null) { toni@1150: return false; toni@1150: } toni@1150: if (getClass() != obj.getClass()) { toni@1150: return false; toni@1150: } toni@1150: final LinearGradient other = (LinearGradient) obj; toni@1150: if (!Objects.equals(this.stops, other.stops)) { toni@1150: return false; toni@1150: } toni@1150: if (Double.doubleToLongBits(this.x0) != Double.doubleToLongBits(other.x0)) { toni@1150: return false; toni@1150: } toni@1150: if (Double.doubleToLongBits(this.y0) != Double.doubleToLongBits(other.y0)) { toni@1150: return false; toni@1150: } toni@1150: if (Double.doubleToLongBits(this.x1) != Double.doubleToLongBits(other.x1)) { toni@1150: return false; toni@1150: } toni@1150: if (Double.doubleToLongBits(this.y1) != Double.doubleToLongBits(other.y1)) { toni@1150: return false; toni@1150: } toni@1150: return true; toni@1150: } toni@1150: } toni@1150: toni@1150: public static final class RadialGradient extends LinearGradient { toni@1150: toni@1150: private double r0, r1; toni@1150: toni@1150: RadialGradient(double x0, double y0, double r0, double x1, double y1, double r1) { toni@1150: super(x0, y0, x1, y1); toni@1150: this.r0 = r0; toni@1150: this.r1 = r1; toni@1150: } toni@1150: toni@1150: public double getR0() { toni@1150: return r0; toni@1150: } toni@1150: toni@1150: public void setR0(double r0) { toni@1150: this.r0 = r0; toni@1150: } toni@1150: toni@1150: public double getR1() { toni@1150: return r1; toni@1150: } toni@1150: toni@1150: public void setR1(double r1) { toni@1150: this.r1 = r1; toni@1150: } toni@1150: toni@1150: @Override toni@1150: public int hashCode() { toni@1150: int hash = super.hashCode(); toni@1150: hash = 17 * hash + (int) (Double.doubleToLongBits(this.r0) ^ (Double.doubleToLongBits(this.r0) >>> 32)); toni@1150: hash = 17 * hash + (int) (Double.doubleToLongBits(this.r1) ^ (Double.doubleToLongBits(this.r1) >>> 32)); toni@1150: toni@1150: return hash; toni@1150: } toni@1150: toni@1150: @Override toni@1150: public boolean equals(Object obj) { toni@1150: if (obj == null) { toni@1150: return false; toni@1150: } toni@1150: if (getClass() != obj.getClass()) { toni@1150: return false; toni@1150: } toni@1150: if (!super.equals(obj)) { toni@1150: return false; toni@1150: } toni@1150: final RadialGradient other = (RadialGradient) obj; toni@1150: if (Double.doubleToLongBits(this.r0) != Double.doubleToLongBits(other.r0)) { toni@1150: return false; toni@1150: } toni@1150: if (Double.doubleToLongBits(this.r1) != Double.doubleToLongBits(other.r1)) { toni@1150: return false; toni@1150: } toni@1154: if ((this.getCached() == null) != (other.getCached() == null)) { toni@1154: return false; toni@1154: } toni@1150: return true; toni@1150: } toni@1150: } toni@1129: }