javaquery/canvas/src/main/java/net/java/html/canvas/Style.java
author Anton Epple <toni.epple@eppleton.de>
Thu, 26 Sep 2013 16:33:04 -0700
branchcanvas
changeset 1308 e8429fba8cce
parent 1302 e67363288df1
child 1446 619f507713a2
permissions -rw-r--r--
documentation
toni@1129
     1
/**
toni@1302
     2
 * Back 2 Browser Bytecode Translator
toni@1302
     3
 * Copyright (C) 2012 Jaroslav Tulach <jaroslav.tulach@apidesign.org>
toni@1129
     4
 *
toni@1302
     5
 * This program is free software: you can redistribute it and/or modify
toni@1302
     6
 * it under the terms of the GNU General Public License as published by
toni@1302
     7
 * the Free Software Foundation, version 2 of the License.
toni@1129
     8
 *
toni@1302
     9
 * This program is distributed in the hope that it will be useful,
toni@1302
    10
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
toni@1302
    11
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
toni@1302
    12
 * GNU General Public License for more details.
toni@1129
    13
 *
toni@1302
    14
 * You should have received a copy of the GNU General Public License
toni@1302
    15
 * along with this program. Look for COPYING file in the top folder.
toni@1302
    16
 * If not, see http://opensource.org/licenses/GPL-2.0.
toni@1129
    17
 */
toni@1129
    18
package net.java.html.canvas;
toni@1129
    19
toni@1308
    20
import java.util.Collection;
toni@1150
    21
import java.util.HashMap;
toni@1150
    22
import java.util.Objects;
toni@1150
    23
toni@1129
    24
/**
toni@1154
    25
 * Style for Stroke and Fill of GraphicsContext. Styles are created using
toni@1154
    26
 * GraphicsContexts factory methods. If the Implementation supports it, native
toni@1154
    27
 * Styles will be cached for performance reasons. This happens the first time
toni@1154
    28
 * the Style is actually used.
toni@1129
    29
 *
toni@1129
    30
 * @author antonepple
toni@1129
    31
 */
toni@1132
    32
public class Style {
toni@1132
    33
toni@1154
    34
    Object cached;
toni@1141
    35
    private int cacheHash;
toni@1141
    36
toni@1132
    37
    Style() {
toni@1132
    38
    }
toni@1141
    39
toni@1141
    40
    void cache(Object toCache) {
toni@1141
    41
        cacheHash = hashCode();
toni@1141
    42
        this.cached = toCache;
toni@1141
    43
    }
toni@1141
    44
toni@1141
    45
    private boolean isCached() {
toni@1141
    46
        return cacheHash == hashCode();
toni@1141
    47
    }
toni@1141
    48
toni@1141
    49
    Object getCached() {
toni@1141
    50
        return isCached() ? cached : null;
toni@1141
    51
    }
toni@1150
    52
toni@1308
    53
    /**
toni@1308
    54
     * A Fill Pattern using an Image Resource to create a fill style supporting 
toni@1308
    55
     * different repeat styles repeat, repeat-x, repeat-y, or no-repeat. 
toni@1308
    56
     * Default is repeat. 
toni@1308
    57
     */
toni@1150
    58
    public static final class Pattern extends Style {
toni@1150
    59
toni@1308
    60
        private final Image imageResource;
toni@1308
    61
        private final String repeat;
toni@1150
    62
toni@1308
    63
        /**
toni@1308
    64
         * 
toni@1308
    65
         * @param imageResource the base image of thsi pattern
toni@1308
    66
         * @param repeat the repeat pattern, possible values are repeat, repeat-x, repeat-y, or no-repeat.
toni@1308
    67
         */
toni@1270
    68
        public Pattern(Image imageResource, String repeat) {
toni@1150
    69
            this.imageResource = imageResource;
toni@1150
    70
            this.repeat = repeat;
toni@1150
    71
        }
toni@1150
    72
toni@1308
    73
        /**
toni@1308
    74
         * Get the base image of this pattern
toni@1308
    75
         * @return the base image of this pattern
toni@1308
    76
         */
toni@1150
    77
        public Image getImageResource() {
toni@1150
    78
            return imageResource;
toni@1150
    79
        }
toni@1150
    80
toni@1308
    81
        /**
toni@1308
    82
         * Get the repeat style for this pattern
toni@1308
    83
         * @return return the repeat style
toni@1308
    84
         */
toni@1150
    85
        public String getRepeat() {
toni@1150
    86
            return repeat;
toni@1150
    87
        }
toni@1150
    88
toni@1150
    89
    }
toni@1150
    90
toni@1150
    91
    public static final class Color extends Style {
toni@1150
    92
toni@1150
    93
        private String web;
toni@1150
    94
toni@1150
    95
        /**
toni@1150
    96
         * Creates an RGB color specified with an HTML or CSS attribute string.
toni@1150
    97
         *
toni@1308
    98
         * @param webColor Color defined as web color (e.g. #ff0000)
toni@1150
    99
         */
toni@1265
   100
        public Color(String webColor) {
toni@1157
   101
            this.web = webColor;
toni@1150
   102
        }
toni@1150
   103
toni@1308
   104
        /**
toni@1308
   105
         * 
toni@1308
   106
         * 
toni@1308
   107
         * @return the Color value as a Web Color (e.g. #ff0000)
toni@1308
   108
         */
toni@1150
   109
        public String getAsString() {
toni@1150
   110
            return web;
toni@1150
   111
        }
toni@1150
   112
    }
toni@1150
   113
toni@1308
   114
    /**
toni@1308
   115
     * A Linear Gradient. The GRadient has a direction defined by two coordinates
toni@1308
   116
     * and stops defining the Color at a specific position.
toni@1308
   117
     */
toni@1150
   118
    public static class LinearGradient extends Style {
toni@1150
   119
toni@1150
   120
        private HashMap<Double, String> stops;
toni@1150
   121
        private double x0, y0, x1, y1;
toni@1150
   122
toni@1308
   123
        /**
toni@1308
   124
         * 
toni@1308
   125
         * @param x0 the x coordinate of the start point for this gradient
toni@1308
   126
         * @param y0 the y coordinate of the start point for this gradient
toni@1308
   127
         * @param x1 the x coordinate of the end point for this gradient
toni@1308
   128
         * @param y1 the y coordinate of the end point for this gradient
toni@1308
   129
         */
toni@1150
   130
        LinearGradient(double x0, double y0, double x1, double y1) {
toni@1150
   131
            this.x0 = x0;
toni@1150
   132
            this.y0 = y0;
toni@1150
   133
            this.x1 = x1;
toni@1150
   134
            this.y1 = y1;
toni@1150
   135
        }
toni@1150
   136
toni@1308
   137
        /**
toni@1308
   138
         * Add a new Color stop. A color stop defines a fixed color at a position
toni@1308
   139
         * along the coordinates.
toni@1308
   140
         * @param position the position of this stop in percent [0.0-1.0]
toni@1308
   141
         * @param color A Color defined in web format (e.g. #ff0000) 
toni@1308
   142
         */
toni@1150
   143
        void addColorStop(double position, String color) {
toni@1150
   144
            if (stops == null) {
toni@1150
   145
                stops = new HashMap<>();
toni@1150
   146
            }
toni@1150
   147
            stops.put(position, color);
toni@1150
   148
        }
toni@1150
   149
toni@1308
   150
        /**
toni@1308
   151
         * Get the stops of this gradient. 
toni@1308
   152
         * @return the stops of this gradient
toni@1308
   153
         */
toni@1308
   154
        public HashMap<Double, String> getStops(){
toni@1308
   155
            return new HashMap<>(stops);
toni@1308
   156
        }
toni@1308
   157
        
toni@1308
   158
        /**
toni@1308
   159
         * Set the stops as Position/Color pairs 
toni@1308
   160
         * @param stops the stops for thsi Gradient
toni@1308
   161
         */
toni@1308
   162
        public void setStops(HashMap<Double, String> stops) {     
toni@1308
   163
            this.stops = new HashMap<>(stops);
toni@1150
   164
        }
toni@1150
   165
toni@1308
   166
        
toni@1150
   167
        public double getX0() {
toni@1150
   168
            return x0;
toni@1150
   169
        }
toni@1150
   170
toni@1150
   171
        public void setX0(double x0) {
toni@1150
   172
            this.x0 = x0;
toni@1150
   173
        }
toni@1150
   174
toni@1150
   175
        public double getY0() {
toni@1150
   176
            return y0;
toni@1150
   177
        }
toni@1150
   178
toni@1150
   179
        public void setY0(double y0) {
toni@1150
   180
            this.y0 = y0;
toni@1150
   181
        }
toni@1150
   182
toni@1150
   183
        public double getX1() {
toni@1150
   184
            return x1;
toni@1150
   185
        }
toni@1150
   186
toni@1150
   187
        public void setX1(double x1) {
toni@1150
   188
            this.x1 = x1;
toni@1150
   189
        }
toni@1150
   190
toni@1150
   191
        public double getY1() {
toni@1150
   192
            return y1;
toni@1150
   193
        }
toni@1150
   194
toni@1150
   195
        public void setY1(double y1) {
toni@1150
   196
            this.y1 = y1;
toni@1150
   197
        }
toni@1150
   198
toni@1150
   199
        @Override
toni@1150
   200
        public int hashCode() {
toni@1150
   201
            int hash = 7;
toni@1150
   202
            hash = 29 * hash + Objects.hashCode(this.stops);
toni@1150
   203
            hash = 29 * hash + (int) (Double.doubleToLongBits(this.x0) ^ (Double.doubleToLongBits(this.x0) >>> 32));
toni@1150
   204
            hash = 29 * hash + (int) (Double.doubleToLongBits(this.y0) ^ (Double.doubleToLongBits(this.y0) >>> 32));
toni@1150
   205
            hash = 29 * hash + (int) (Double.doubleToLongBits(this.x1) ^ (Double.doubleToLongBits(this.x1) >>> 32));
toni@1150
   206
            hash = 29 * hash + (int) (Double.doubleToLongBits(this.y1) ^ (Double.doubleToLongBits(this.y1) >>> 32));
toni@1150
   207
            return hash;
toni@1150
   208
        }
toni@1150
   209
toni@1150
   210
        @Override
toni@1150
   211
        public boolean equals(Object obj) {
toni@1150
   212
            if (obj == null) {
toni@1150
   213
                return false;
toni@1150
   214
            }
toni@1150
   215
            if (getClass() != obj.getClass()) {
toni@1150
   216
                return false;
toni@1150
   217
            }
toni@1150
   218
            final LinearGradient other = (LinearGradient) obj;
toni@1150
   219
            if (!Objects.equals(this.stops, other.stops)) {
toni@1150
   220
                return false;
toni@1150
   221
            }
toni@1150
   222
            if (Double.doubleToLongBits(this.x0) != Double.doubleToLongBits(other.x0)) {
toni@1150
   223
                return false;
toni@1150
   224
            }
toni@1150
   225
            if (Double.doubleToLongBits(this.y0) != Double.doubleToLongBits(other.y0)) {
toni@1150
   226
                return false;
toni@1150
   227
            }
toni@1150
   228
            if (Double.doubleToLongBits(this.x1) != Double.doubleToLongBits(other.x1)) {
toni@1150
   229
                return false;
toni@1150
   230
            }
toni@1150
   231
            if (Double.doubleToLongBits(this.y1) != Double.doubleToLongBits(other.y1)) {
toni@1150
   232
                return false;
toni@1150
   233
            }
toni@1150
   234
            return true;
toni@1150
   235
        }
toni@1150
   236
    }
toni@1150
   237
toni@1150
   238
    public static final class RadialGradient extends LinearGradient {
toni@1150
   239
toni@1150
   240
        private double r0, r1;
toni@1150
   241
toni@1150
   242
        RadialGradient(double x0, double y0, double r0, double x1, double y1, double r1) {
toni@1150
   243
            super(x0, y0, x1, y1);
toni@1150
   244
            this.r0 = r0;
toni@1150
   245
            this.r1 = r1;
toni@1150
   246
        }
toni@1150
   247
toni@1150
   248
        public double getR0() {
toni@1150
   249
            return r0;
toni@1150
   250
        }
toni@1150
   251
toni@1150
   252
        public void setR0(double r0) {
toni@1150
   253
            this.r0 = r0;
toni@1150
   254
        }
toni@1150
   255
toni@1150
   256
        public double getR1() {
toni@1150
   257
            return r1;
toni@1150
   258
        }
toni@1150
   259
toni@1150
   260
        public void setR1(double r1) {
toni@1150
   261
            this.r1 = r1;
toni@1150
   262
        }
toni@1150
   263
toni@1150
   264
        @Override
toni@1150
   265
        public int hashCode() {
toni@1150
   266
            int hash = super.hashCode();
toni@1150
   267
            hash = 17 * hash + (int) (Double.doubleToLongBits(this.r0) ^ (Double.doubleToLongBits(this.r0) >>> 32));
toni@1150
   268
            hash = 17 * hash + (int) (Double.doubleToLongBits(this.r1) ^ (Double.doubleToLongBits(this.r1) >>> 32));
toni@1150
   269
toni@1150
   270
            return hash;
toni@1150
   271
        }
toni@1150
   272
toni@1150
   273
        @Override
toni@1150
   274
        public boolean equals(Object obj) {
toni@1150
   275
            if (obj == null) {
toni@1150
   276
                return false;
toni@1150
   277
            }
toni@1150
   278
            if (getClass() != obj.getClass()) {
toni@1150
   279
                return false;
toni@1150
   280
            }
toni@1150
   281
            if (!super.equals(obj)) {
toni@1150
   282
                return false;
toni@1150
   283
            }
toni@1150
   284
            final RadialGradient other = (RadialGradient) obj;
toni@1150
   285
            if (Double.doubleToLongBits(this.r0) != Double.doubleToLongBits(other.r0)) {
toni@1150
   286
                return false;
toni@1150
   287
            }
toni@1150
   288
            if (Double.doubleToLongBits(this.r1) != Double.doubleToLongBits(other.r1)) {
toni@1150
   289
                return false;
toni@1150
   290
            }
toni@1154
   291
            if ((this.getCached() == null) != (other.getCached() == null)) {
toni@1154
   292
                return false;
toni@1154
   293
            }
toni@1150
   294
            return true;
toni@1150
   295
        }
toni@1150
   296
    }
toni@1129
   297
}