summaryrefslogtreecommitdiffstats
path: root/awt/java/awt/GradientPaintContext.java
diff options
context:
space:
mode:
Diffstat (limited to 'awt/java/awt/GradientPaintContext.java')
-rw-r--r--awt/java/awt/GradientPaintContext.java204
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;
+ }
+
+}
+