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