diff options
Diffstat (limited to 'awt/java/awt/GradientPaintContext.java')
-rw-r--r-- | awt/java/awt/GradientPaintContext.java | 204 |
1 files changed, 204 insertions, 0 deletions
diff --git a/awt/java/awt/GradientPaintContext.java b/awt/java/awt/GradientPaintContext.java new file mode 100644 index 0000000..74575f5 --- /dev/null +++ b/awt/java/awt/GradientPaintContext.java @@ -0,0 +1,204 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You 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. + */ +/** + * @author Denis M. Kishenko + * @version $Revision$ + */ +package java.awt; + +import java.awt.geom.AffineTransform; +import java.awt.geom.Point2D; +import java.awt.image.ColorModel; +import java.awt.image.DataBufferInt; +import java.awt.image.Raster; +import java.awt.image.WritableRaster; + +class GradientPaintContext implements PaintContext { + + /** + * The size of noncyclic part of color lookup table + */ + static int LOOKUP_SIZE = 256; + + /** + * The index mask to lookup color in the table + */ + static int LOOKUP_MASK = 0x1FF; + + /** + * The min value equivalent to zero. If absolute value less then ZERO it considered as zero. + */ + static double ZERO = 1E-10; + + /** + * The ColorModel user defined for PaintContext + */ + ColorModel cm; + + /** + * The indicator of cycle filling. + */ + boolean cyclic; + + /** + * The integer color value of the start point + */ + int c1; + + /** + * The integer color value of the end point + */ + int c2; + + /** + * The lookup gradient color table + */ + int[] table; + + /** + * The tempopary pre-calculated value to evalutae color index + */ + int dx; + + /** + * The tempopary pre-calculated value to evalutae color index + */ + int dy; + + /** + * The tempopary pre-calculated value to evalutae color index + */ + int delta; + + /** + * Constructs a new GradientPaintcontext + * @param cm - not used + * @param t - the fill transformation + * @param point1 - the start fill point + * @param color1 - color of the start point + * @param point2 - the end fill point + * @param color2 - color of the end point + * @param cyclic - the indicator of cycle filling + */ + GradientPaintContext(ColorModel cm, AffineTransform t, Point2D point1, Color color1, Point2D point2, Color color2, boolean cyclic) { + this.cyclic = cyclic; + this.cm = ColorModel.getRGBdefault(); + + c1 = color1.getRGB(); + c2 = color2.getRGB(); + + double px = point2.getX() - point1.getX(); + double py = point2.getY() - point1.getY(); + + Point2D p = t.transform(point1, null); + Point2D bx = new Point2D.Double(px, py); + Point2D by = new Point2D.Double(py, -px); + + t.deltaTransform(bx, bx); + t.deltaTransform(by, by); + + double vec = bx.getX() * by.getY() - bx.getY() * by.getX(); + + if (Math.abs(vec) < ZERO) { + dx = dy = delta = 0; + table = new int[1]; + table[0] = c1; + } else { + double mult = LOOKUP_SIZE * 256 / vec; + dx = (int)(by.getX() * mult); + dy = (int)(by.getY() * mult); + delta = (int)((p.getX() * by.getY() - p.getY() * by.getX()) * mult); + createTable(); + } + } + + /** + * Create color index lookup table. Calculate 256 step trasformation from + * the start point color to the end point color. Colors multiplied by 256 to do integer calculations. + */ + void createTable() { + double ca = (c1 >> 24) & 0xFF; + double cr = (c1 >> 16) & 0xFF; + double cg = (c1 >> 8) & 0xFF; + double cb = c1 & 0xFF; + + double k = 1.0 / LOOKUP_SIZE; + double da = (((c2 >> 24) & 0xFF) - ca) * k; + double dr = (((c2 >> 16) & 0xFF) - cr) * k; + double dg = (((c2 >> 8) & 0xFF) - cg) * k; + double db = ((c2 & 0xFF) - cb) * k; + + table = new int[cyclic ? LOOKUP_SIZE + LOOKUP_SIZE : LOOKUP_SIZE]; + for(int i = 0; i < LOOKUP_SIZE; i++) { + table[i] = + (int)ca << 24 | + (int)cr << 16 | + (int)cg << 8 | + (int)cb; + ca += da; + cr += dr; + cg += dg; + cb += db; + } + if (cyclic) { + for(int i = 0; i < LOOKUP_SIZE; i++) { + table[LOOKUP_SIZE + LOOKUP_SIZE - 1 - i] = table[i]; + } + } + } + + public ColorModel getColorModel() { + return cm; + } + + public void dispose() { + } + + public Raster getRaster(int x, int y, int w, int h) { + WritableRaster rast = cm.createCompatibleWritableRaster(w, h); + + int[] buf = ((DataBufferInt)rast.getDataBuffer()).getData(); + + int c = x * dy - y * dx - delta; + int cx = dy; + int cy = - w * dy - dx; + int k = 0; + + if (cyclic) { + for(int j = 0; j < h; j++) { + for(int i = 0; i < w; i++) { + buf[k++] = table[(c >> 8) & LOOKUP_MASK]; + c += cx; + } + c += cy; + } + } else { + for(int j = 0; j < h; j++) { + for(int i = 0; i < w; i++) { + int index = c >> 8; + buf[k++] = index < 0 ? c1 : index >= LOOKUP_SIZE ? c2 : table[index]; + c += cx; + } + c += cy; + } + } + + return rast; + } + +} + |