1 /*
2 * Copyright (c) 2006, 2014, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
101 * direct access by subclasses.
102 */
103 protected int[] gradient;
104
105 /**
106 * Array of gradient arrays, one array for each interval. Used by
107 * calculateMultipleArrayGradient().
108 */
109 private int[][] gradients;
110
111 /** Normalized intervals array. */
112 private float[] normalizedIntervals;
113
114 /** Fractions array. */
115 private float[] fractions;
116
117 /** Used to determine if gradient colors are all opaque. */
118 private int transparencyTest;
119
120 /** Color space conversion lookup tables. */
121 private static final int SRGBtoLinearRGB[] = new int[256];
122 private static final int LinearRGBtoSRGB[] = new int[256];
123
124 static {
125 // build the tables
126 for (int k = 0; k < 256; k++) {
127 SRGBtoLinearRGB[k] = convertSRGBtoLinearRGB(k);
128 LinearRGBtoSRGB[k] = convertLinearRGBtoSRGB(k);
129 }
130 }
131
132 /**
133 * Constant number of max colors between any 2 arbitrary colors.
134 * Used for creating and indexing gradients arrays.
135 */
136 protected static final int GRADIENT_SIZE = 256;
137 protected static final int GRADIENT_SIZE_INDEX = GRADIENT_SIZE -1;
138
139 /**
140 * Maximum length of the fast single-array. If the estimated array size
141 * is greater than this, switch over to the slow lookup method.
142 * No particular reason for choosing this number, but it seems to provide
170 throw new NullPointerException("Transform cannot be null");
171 }
172
173 if (hints == null) {
174 throw new NullPointerException("RenderingHints cannot be null");
175 }
176
177 // The inverse transform is needed to go from device to user space.
178 // Get all the components of the inverse transform matrix.
179 AffineTransform tInv;
180 try {
181 // the following assumes that the caller has copied the incoming
182 // transform and is not concerned about it being modified
183 t.invert();
184 tInv = t;
185 } catch (NoninvertibleTransformException e) {
186 // just use identity transform in this case; better to show
187 // (incorrect) results than to throw an exception and/or no-op
188 tInv = new AffineTransform();
189 }
190 double m[] = new double[6];
191 tInv.getMatrix(m);
192 a00 = (float)m[0];
193 a10 = (float)m[1];
194 a01 = (float)m[2];
195 a11 = (float)m[3];
196 a02 = (float)m[4];
197 a12 = (float)m[5];
198
199 // copy some flags
200 this.cycleMethod = cycleMethod;
201 this.colorSpace = colorSpace;
202
203 // we can avoid copying this array since we do not modify its values
204 this.fractions = fractions;
205
206 // note that only one of these values can ever be non-null (we either
207 // store the fast gradient array or the slow one, but never both
208 // at the same time)
209 int[] gradient =
210 (mgp.gradient != null) ? mgp.gradient.get() : null;
634
635 // Access raster internal int array. Because we use a DirectColorModel,
636 // we know the DataBuffer is of type DataBufferInt and the SampleModel
637 // is SinglePixelPackedSampleModel.
638 // Adjust for initial offset in DataBuffer and also for the scanline
639 // stride.
640 // These calls make the DataBuffer non-acceleratable, but the
641 // Raster is never Stable long enough to accelerate anyway...
642 DataBufferInt rasterDB = (DataBufferInt)raster.getDataBuffer();
643 int[] pixels = rasterDB.getData(0);
644 int off = rasterDB.getOffset();
645 int scanlineStride = ((SinglePixelPackedSampleModel)
646 raster.getSampleModel()).getScanlineStride();
647 int adjust = scanlineStride - w;
648
649 fillRaster(pixels, off, adjust, x, y, w, h); // delegate to subclass
650
651 return raster;
652 }
653
654 protected abstract void fillRaster(int pixels[], int off, int adjust,
655 int x, int y, int w, int h);
656
657
658 /**
659 * Took this cacheRaster code from GradientPaint. It appears to recycle
660 * rasters for use by any other instance, as long as they are sufficiently
661 * large.
662 */
663 private static synchronized Raster getCachedRaster(ColorModel cm,
664 int w, int h)
665 {
666 if (cm == cachedModel) {
667 if (cached != null) {
668 Raster ras = cached.get();
669 if (ras != null &&
670 ras.getWidth() >= w &&
671 ras.getHeight() >= h)
672 {
673 cached = null;
674 return ras;
|
1 /*
2 * Copyright (c) 2006, 2018, Oracle and/or its affiliates. All rights reserved.
3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4 *
5 * This code is free software; you can redistribute it and/or modify it
6 * under the terms of the GNU General Public License version 2 only, as
7 * published by the Free Software Foundation. Oracle designates this
8 * particular file as subject to the "Classpath" exception as provided
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
101 * direct access by subclasses.
102 */
103 protected int[] gradient;
104
105 /**
106 * Array of gradient arrays, one array for each interval. Used by
107 * calculateMultipleArrayGradient().
108 */
109 private int[][] gradients;
110
111 /** Normalized intervals array. */
112 private float[] normalizedIntervals;
113
114 /** Fractions array. */
115 private float[] fractions;
116
117 /** Used to determine if gradient colors are all opaque. */
118 private int transparencyTest;
119
120 /** Color space conversion lookup tables. */
121 private static final int[] SRGBtoLinearRGB = new int[256];
122 private static final int[] LinearRGBtoSRGB = new int[256];
123
124 static {
125 // build the tables
126 for (int k = 0; k < 256; k++) {
127 SRGBtoLinearRGB[k] = convertSRGBtoLinearRGB(k);
128 LinearRGBtoSRGB[k] = convertLinearRGBtoSRGB(k);
129 }
130 }
131
132 /**
133 * Constant number of max colors between any 2 arbitrary colors.
134 * Used for creating and indexing gradients arrays.
135 */
136 protected static final int GRADIENT_SIZE = 256;
137 protected static final int GRADIENT_SIZE_INDEX = GRADIENT_SIZE -1;
138
139 /**
140 * Maximum length of the fast single-array. If the estimated array size
141 * is greater than this, switch over to the slow lookup method.
142 * No particular reason for choosing this number, but it seems to provide
170 throw new NullPointerException("Transform cannot be null");
171 }
172
173 if (hints == null) {
174 throw new NullPointerException("RenderingHints cannot be null");
175 }
176
177 // The inverse transform is needed to go from device to user space.
178 // Get all the components of the inverse transform matrix.
179 AffineTransform tInv;
180 try {
181 // the following assumes that the caller has copied the incoming
182 // transform and is not concerned about it being modified
183 t.invert();
184 tInv = t;
185 } catch (NoninvertibleTransformException e) {
186 // just use identity transform in this case; better to show
187 // (incorrect) results than to throw an exception and/or no-op
188 tInv = new AffineTransform();
189 }
190 double[] m = new double[6];
191 tInv.getMatrix(m);
192 a00 = (float)m[0];
193 a10 = (float)m[1];
194 a01 = (float)m[2];
195 a11 = (float)m[3];
196 a02 = (float)m[4];
197 a12 = (float)m[5];
198
199 // copy some flags
200 this.cycleMethod = cycleMethod;
201 this.colorSpace = colorSpace;
202
203 // we can avoid copying this array since we do not modify its values
204 this.fractions = fractions;
205
206 // note that only one of these values can ever be non-null (we either
207 // store the fast gradient array or the slow one, but never both
208 // at the same time)
209 int[] gradient =
210 (mgp.gradient != null) ? mgp.gradient.get() : null;
634
635 // Access raster internal int array. Because we use a DirectColorModel,
636 // we know the DataBuffer is of type DataBufferInt and the SampleModel
637 // is SinglePixelPackedSampleModel.
638 // Adjust for initial offset in DataBuffer and also for the scanline
639 // stride.
640 // These calls make the DataBuffer non-acceleratable, but the
641 // Raster is never Stable long enough to accelerate anyway...
642 DataBufferInt rasterDB = (DataBufferInt)raster.getDataBuffer();
643 int[] pixels = rasterDB.getData(0);
644 int off = rasterDB.getOffset();
645 int scanlineStride = ((SinglePixelPackedSampleModel)
646 raster.getSampleModel()).getScanlineStride();
647 int adjust = scanlineStride - w;
648
649 fillRaster(pixels, off, adjust, x, y, w, h); // delegate to subclass
650
651 return raster;
652 }
653
654 protected abstract void fillRaster(int[] pixels, int off, int adjust,
655 int x, int y, int w, int h);
656
657
658 /**
659 * Took this cacheRaster code from GradientPaint. It appears to recycle
660 * rasters for use by any other instance, as long as they are sufficiently
661 * large.
662 */
663 private static synchronized Raster getCachedRaster(ColorModel cm,
664 int w, int h)
665 {
666 if (cm == cachedModel) {
667 if (cached != null) {
668 Raster ras = cached.get();
669 if (ras != null &&
670 ras.getWidth() >= w &&
671 ras.getHeight() >= h)
672 {
673 cached = null;
674 return ras;
|