History

My first initial commit with all of mine experimental changes.

Dmitry Kabak (userdima committed 13 years ago

Commit d37b88d1 parent 3f5b46618352 files · +2598093 −-8690Browse files

Showing the changes to java/pkg/java/awt/TexturePaintContext.java (1 of 18352 files). Show all

Unified · Split

java/pkg/java/awt/TexturePaintContext.java+827−0
@@ -0,0 +1,827 @@
1/*
2 * Copyright (c) 1997, 2007, 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
23 * questions.
24 */
25
26package java.awt;
27
28import java.awt.image.BufferedImage;
29import java.awt.image.Raster;
30import java.awt.image.WritableRaster;
31import java.awt.image.ColorModel;
32import java.awt.image.DirectColorModel;
33import java.awt.image.IndexColorModel;
34import java.awt.geom.AffineTransform;
35import java.awt.geom.NoninvertibleTransformException;
36import java.lang.ref.WeakReference;
37import sun.awt.image.SunWritableRaster;
38import sun.awt.image.IntegerInterleavedRaster;
39import sun.awt.image.ByteInterleavedRaster;
40
41abstract class TexturePaintContext implements PaintContext {
42 public static ColorModel xrgbmodel =
43 new DirectColorModel(24, 0xff0000, 0xff00, 0xff);
44 public static ColorModel argbmodel = ColorModel.getRGBdefault();
45
46 ColorModel colorModel;
47 int bWidth;
48 int bHeight;
49 int maxWidth;
50
51 WritableRaster outRas;
52
53 double xOrg;
54 double yOrg;
55 double incXAcross;
56 double incYAcross;
57 double incXDown;
58 double incYDown;
59
60 int colincx;
61 int colincy;
62 int colincxerr;
63 int colincyerr;
64 int rowincx;
65 int rowincy;
66 int rowincxerr;
67 int rowincyerr;
68
69 public static PaintContext getContext(BufferedImage bufImg,
70 AffineTransform xform,
71 RenderingHints hints,
72 Rectangle devBounds) {
73 WritableRaster raster = bufImg.getRaster();
74 ColorModel cm = bufImg.getColorModel();
75 int maxw = devBounds.width;
76 Object val = hints.get(hints.KEY_INTERPOLATION);
77 boolean filter =
78 (val == null
79 ? (hints.get(hints.KEY_RENDERING) == hints.VALUE_RENDER_QUALITY)
80 : (val != hints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR));
81 if (raster instanceof IntegerInterleavedRaster &&
82 (!filter || isFilterableDCM(cm)))
83 {
84 IntegerInterleavedRaster iir = (IntegerInterleavedRaster) raster;
85 if (iir.getNumDataElements() == 1 && iir.getPixelStride() == 1) {
86 return new Int(iir, cm, xform, maxw, filter);
87 }
88 } else if (raster instanceof ByteInterleavedRaster) {
89 ByteInterleavedRaster bir = (ByteInterleavedRaster) raster;
90 if (bir.getNumDataElements() == 1 && bir.getPixelStride() == 1) {
91 if (filter) {
92 if (isFilterableICM(cm)) {
93 return new ByteFilter(bir, cm, xform, maxw);
94 }
95 } else {
96 return new Byte(bir, cm, xform, maxw);
97 }
98 }
99 }
100 return new Any(raster, cm, xform, maxw, filter);
101 }
102
103 public static boolean isFilterableICM(ColorModel cm) {
104 if (cm instanceof IndexColorModel) {
105 IndexColorModel icm = (IndexColorModel) cm;
106 if (icm.getMapSize() <= 256) {
107 return true;
108 }
109 }
110 return false;
111 }
112
113 public static boolean isFilterableDCM(ColorModel cm) {
114 if (cm instanceof DirectColorModel) {
115 DirectColorModel dcm = (DirectColorModel) cm;
116 return (isMaskOK(dcm.getAlphaMask(), true) &&
117 isMaskOK(dcm.getRedMask(), false) &&
118 isMaskOK(dcm.getGreenMask(), false) &&
119 isMaskOK(dcm.getBlueMask(), false));
120 }
121 return false;
122 }
123
124 public static boolean isMaskOK(int mask, boolean canbezero) {
125 if (canbezero && mask == 0) {
126 return true;
127 }
128 return (mask == 0xff ||
129 mask == 0xff00 ||
130 mask == 0xff0000 ||
131 mask == 0xff000000);
132 }
133
134 public static ColorModel getInternedColorModel(ColorModel cm) {
135 if (xrgbmodel == cm || xrgbmodel.equals(cm)) {
136 return xrgbmodel;
137 }
138 if (argbmodel == cm || argbmodel.equals(cm)) {
139 return argbmodel;
140 }
141 return cm;
142 }
143
144 TexturePaintContext(ColorModel cm, AffineTransform xform,
145 int bWidth, int bHeight, int maxw) {
146 this.colorModel = getInternedColorModel(cm);
147 this.bWidth = bWidth;
148 this.bHeight = bHeight;
149 this.maxWidth = maxw;
150
151 try {
152 xform = xform.createInverse();
153 } catch (NoninvertibleTransformException e) {
154 xform.setToScale(0, 0);
155 }
156 this.incXAcross = mod(xform.getScaleX(), bWidth);
157 this.incYAcross = mod(xform.getShearY(), bHeight);
158 this.incXDown = mod(xform.getShearX(), bWidth);
159 this.incYDown = mod(xform.getScaleY(), bHeight);
160 this.xOrg = xform.getTranslateX();
161 this.yOrg = xform.getTranslateY();
162 this.colincx = (int) incXAcross;
163 this.colincy = (int) incYAcross;
164 this.colincxerr = fractAsInt(incXAcross);
165 this.colincyerr = fractAsInt(incYAcross);
166 this.rowincx = (int) incXDown;
167 this.rowincy = (int) incYDown;
168 this.rowincxerr = fractAsInt(incXDown);
169 this.rowincyerr = fractAsInt(incYDown);
170
171 }
172
173 static int fractAsInt(double d) {
174 return (int) ((d % 1.0) * Integer.MAX_VALUE);
175 }
176
177 static double mod(double num, double den) {
178 num = num % den;
179 if (num < 0) {
180 num += den;
181 if (num >= den) {
182 // For very small negative numerators, the answer might
183 // be such a tiny bit less than den that the difference
184 // is smaller than the mantissa of a double allows and
185 // the result would then be rounded to den. If that is
186 // the case then we map that number to 0 as the nearest
187 // modulus representation.
188 num = 0;
189 }
190 }
191 return num;
192 }
193
194 /**
195 * Release the resources allocated for the operation.
196 */
197 public void dispose() {
198 dropRaster(colorModel, outRas);
199 }
200
201 /**
202 * Return the ColorModel of the output.
203 */
204 public ColorModel getColorModel() {
205 return colorModel;
206 }
207
208 /**
209 * Return a Raster containing the colors generated for the graphics
210 * operation.
211 * @param x,y,w,h The area in device space for which colors are
212 * generated.
213 */
214 public Raster getRaster(int x, int y, int w, int h) {
215 if (outRas == null ||
216 outRas.getWidth() < w ||
217 outRas.getHeight() < h)
218 {
219 // If h==1, we will probably get lots of "scanline" rects
220 outRas = makeRaster((h == 1 ? Math.max(w, maxWidth) : w), h);
221 }
222 double X = mod(xOrg + x * incXAcross + y * incXDown, bWidth);
223 double Y = mod(yOrg + x * incYAcross + y * incYDown, bHeight);
224
225 setRaster((int) X, (int) Y, fractAsInt(X), fractAsInt(Y),
226 w, h, bWidth, bHeight,
227 colincx, colincxerr,
228 colincy, colincyerr,
229 rowincx, rowincxerr,
230 rowincy, rowincyerr);
231
232 SunWritableRaster.markDirty(outRas);
233
234 return outRas;
235 }
236
237 private static WeakReference xrgbRasRef;
238 private static WeakReference argbRasRef;
239
240 synchronized static WritableRaster makeRaster(ColorModel cm,
241 Raster srcRas,
242 int w, int h)
243 {
244 if (xrgbmodel == cm) {
245 if (xrgbRasRef != null) {
246 WritableRaster wr = (WritableRaster) xrgbRasRef.get();
247 if (wr != null && wr.getWidth() >= w && wr.getHeight() >= h) {
248 xrgbRasRef = null;
249 return wr;
250 }
251 }
252 // If we are going to cache this Raster, make it non-tiny
253 if (w <= 32 && h <= 32) {
254 w = h = 32;
255 }
256 } else if (argbmodel == cm) {
257 if (argbRasRef != null) {
258 WritableRaster wr = (WritableRaster) argbRasRef.get();
259 if (wr != null && wr.getWidth() >= w && wr.getHeight() >= h) {
260 argbRasRef = null;
261 return wr;
262 }
263 }
264 // If we are going to cache this Raster, make it non-tiny
265 if (w <= 32 && h <= 32) {
266 w = h = 32;
267 }
268 }
269 if (srcRas != null) {
270 return srcRas.createCompatibleWritableRaster(w, h);
271 } else {
272 return cm.createCompatibleWritableRaster(w, h);
273 }
274 }
275
276 synchronized static void dropRaster(ColorModel cm, Raster outRas) {
277 if (outRas == null) {
278 return;
279 }
280 if (xrgbmodel == cm) {
281 xrgbRasRef = new WeakReference(outRas);
282 } else if (argbmodel == cm) {
283 argbRasRef = new WeakReference(outRas);
284 }
285 }
286
287 private static WeakReference byteRasRef;
288
289 synchronized static WritableRaster makeByteRaster(Raster srcRas,
290 int w, int h)
291 {
292 if (byteRasRef != null) {
293 WritableRaster wr = (WritableRaster) byteRasRef.get();
294 if (wr != null && wr.getWidth() >= w && wr.getHeight() >= h) {
295 byteRasRef = null;
296 return wr;
297 }
298 }
299 // If we are going to cache this Raster, make it non-tiny
300 if (w <= 32 && h <= 32) {
301 w = h = 32;
302 }
303 return srcRas.createCompatibleWritableRaster(w, h);
304 }
305
306 synchronized static void dropByteRaster(Raster outRas) {
307 if (outRas == null) {
308 return;
309 }
310 byteRasRef = new WeakReference(outRas);
311 }
312
313 public abstract WritableRaster makeRaster(int w, int h);
314 public abstract void setRaster(int x, int y, int xerr, int yerr,
315 int w, int h, int bWidth, int bHeight,
316 int colincx, int colincxerr,
317 int colincy, int colincyerr,
318 int rowincx, int rowincxerr,
319 int rowincy, int rowincyerr);
320
321 /*
322 * Blends the four ARGB values in the rgbs array using the factors
323 * described by xmul and ymul in the following ratio:
324 *
325 * rgbs[0] * (1-xmul) * (1-ymul) +
326 * rgbs[1] * ( xmul) * (1-ymul) +
327 * rgbs[2] * (1-xmul) * ( ymul) +
328 * rgbs[3] * ( xmul) * ( ymul)
329 *
330 * xmul and ymul are integer values in the half-open range [0, 2^31)
331 * where 0 == 0.0 and 2^31 == 1.0.
332 *
333 * Note that since the range is half-open, the values are always
334 * logically less than 1.0. This makes sense because while choosing
335 * pixels to blend, when the error values reach 1.0 we move to the
336 * next pixel and reset them to 0.0.
337 */
338 public static int blend(int rgbs[], int xmul, int ymul) {
339 // xmul/ymul are 31 bits wide, (0 => 2^31-1)
340 // shift them to 12 bits wide, (0 => 2^12-1)
341 xmul = (xmul >>> 19);
342 ymul = (ymul >>> 19);
343 int accumA, accumR, accumG, accumB;
344 accumA = accumR = accumG = accumB = 0;
345 for (int i = 0; i < 4; i++) {
346 int rgb = rgbs[i];
347 // The complement of the [xy]mul values (1-[xy]mul) can result
348 // in new values in the range (1 => 2^12). Thus for any given
349 // loop iteration, the values could be anywhere in (0 => 2^12).
350 xmul = (1<<12) - xmul;
351 if ((i & 1) == 0) {
352 ymul = (1<<12) - ymul;
353 }
354 // xmul and ymul are each 12 bits (0 => 2^12)
355 // factor is thus 24 bits (0 => 2^24)
356 int factor = xmul * ymul;
357 if (factor != 0) {
358 // accum variables will accumulate 32 bits
359 // bytes extracted from rgb fit in 8 bits (0 => 255)
360 // byte * factor thus fits in 32 bits (0 => 255 * 2^24)
361 accumA += (((rgb >>> 24) ) * factor);
362 accumR += (((rgb >>> 16) & 0xff) * factor);
363 accumG += (((rgb >>> 8) & 0xff) * factor);
364 accumB += (((rgb ) & 0xff) * factor);
365 }
366 }
367 return ((((accumA + (1<<23)) >>> 24) << 24) |
368 (((accumR + (1<<23)) >>> 24) << 16) |
369 (((accumG + (1<<23)) >>> 24) << 8) |
370 (((accumB + (1<<23)) >>> 24) ));
371 }
372
373 static class Int extends TexturePaintContext {
374 IntegerInterleavedRaster srcRas;
375 int inData[];
376 int inOff;
377 int inSpan;
378 int outData[];
379 int outOff;
380 int outSpan;
381 boolean filter;
382
383 public Int(IntegerInterleavedRaster srcRas, ColorModel cm,
384 AffineTransform xform, int maxw, boolean filter)
385 {
386 super(cm, xform, srcRas.getWidth(), srcRas.getHeight(), maxw);
387 this.srcRas = srcRas;
388 this.inData = srcRas.getDataStorage();
389 this.inSpan = srcRas.getScanlineStride();
390 this.inOff = srcRas.getDataOffset(0);
391 this.filter = filter;
392 }
393
394 public WritableRaster makeRaster(int w, int h) {
395 WritableRaster ras = makeRaster(colorModel, srcRas, w, h);
396 IntegerInterleavedRaster iiRas = (IntegerInterleavedRaster) ras;
397 outData = iiRas.getDataStorage();
398 outSpan = iiRas.getScanlineStride();
399 outOff = iiRas.getDataOffset(0);
400 return ras;
401 }
402
403 public void setRaster(int x, int y, int xerr, int yerr,
404 int w, int h, int bWidth, int bHeight,
405 int colincx, int colincxerr,
406 int colincy, int colincyerr,
407 int rowincx, int rowincxerr,
408 int rowincy, int rowincyerr) {
409 int[] inData = this.inData;
410 int[] outData = this.outData;
411 int out = outOff;
412 int inSpan = this.inSpan;
413 int inOff = this.inOff;
414 int outSpan = this.outSpan;
415 boolean filter = this.filter;
416 boolean normalx = (colincx == 1 && colincxerr == 0 &&
417 colincy == 0 && colincyerr == 0) && !filter;
418 int rowx = x;
419 int rowy = y;
420 int rowxerr = xerr;
421 int rowyerr = yerr;
422 if (normalx) {
423 outSpan -= w;
424 }
425 int rgbs[] = filter ? new int[4] : null;
426 for (int j = 0; j < h; j++) {
427 if (normalx) {
428 int in = inOff + rowy * inSpan + bWidth;
429 x = bWidth - rowx;
430 out += w;
431 if (bWidth >= 32) {
432 int i = w;
433 while (i > 0) {
434 int copyw = (i < x) ? i : x;
435 System.arraycopy(inData, in - x,
436 outData, out - i,
437 copyw);
438 i -= copyw;
439 if ((x -= copyw) == 0) {
440 x = bWidth;
441 }
442 }
443 } else {
444 for (int i = w; i > 0; i--) {
445 outData[out - i] = inData[in - x];
446 if (--x == 0) {
447 x = bWidth;
448 }
449 }
450 }
451 } else {
452 x = rowx;
453 y = rowy;
454 xerr = rowxerr;
455 yerr = rowyerr;
456 for (int i = 0; i < w; i++) {
457 if (filter) {
458 int nextx, nexty;
459 if ((nextx = x + 1) >= bWidth) {
460 nextx = 0;
461 }
462 if ((nexty = y + 1) >= bHeight) {
463 nexty = 0;
464 }
465 rgbs[0] = inData[inOff + y * inSpan + x];
466 rgbs[1] = inData[inOff + y * inSpan + nextx];
467 rgbs[2] = inData[inOff + nexty * inSpan + x];
468 rgbs[3] = inData[inOff + nexty * inSpan + nextx];
469 outData[out + i] =
470 TexturePaintContext.blend(rgbs, xerr, yerr);
471 } else {
472 outData[out + i] = inData[inOff + y * inSpan + x];
473 }
474 if ((xerr += colincxerr) < 0) {
475 xerr &= Integer.MAX_VALUE;
476 x++;
477 }
478 if ((x += colincx) >= bWidth) {
479 x -= bWidth;
480 }
481 if ((yerr += colincyerr) < 0) {
482 yerr &= Integer.MAX_VALUE;
483 y++;
484 }
485 if ((y += colincy) >= bHeight) {
486 y -= bHeight;
487 }
488 }
489 }
490 if ((rowxerr += rowincxerr) < 0) {
491 rowxerr &= Integer.MAX_VALUE;
492 rowx++;
493 }
494 if ((rowx += rowincx) >= bWidth) {
495 rowx -= bWidth;
496 }
497 if ((rowyerr += rowincyerr) < 0) {
498 rowyerr &= Integer.MAX_VALUE;
499 rowy++;
500 }
501 if ((rowy += rowincy) >= bHeight) {
502 rowy -= bHeight;
503 }
504 out += outSpan;
505 }
506 }
507 }
508
509 static class Byte extends TexturePaintContext {
510 ByteInterleavedRaster srcRas;
511 byte inData[];
512 int inOff;
513 int inSpan;
514 byte outData[];
515 int outOff;
516 int outSpan;
517
518 public Byte(ByteInterleavedRaster srcRas, ColorModel cm,
519 AffineTransform xform, int maxw)
520 {
521 super(cm, xform, srcRas.getWidth(), srcRas.getHeight(), maxw);
522 this.srcRas = srcRas;
523 this.inData = srcRas.getDataStorage();
524 this.inSpan = srcRas.getScanlineStride();
525 this.inOff = srcRas.getDataOffset(0);
526 }
527
528 public WritableRaster makeRaster(int w, int h) {
529 WritableRaster ras = makeByteRaster(srcRas, w, h);
530 ByteInterleavedRaster biRas = (ByteInterleavedRaster) ras;
531 outData = biRas.getDataStorage();
532 outSpan = biRas.getScanlineStride();
533 outOff = biRas.getDataOffset(0);
534 return ras;
535 }
536
537 public void dispose() {
538 dropByteRaster(outRas);
539 }
540
541 public void setRaster(int x, int y, int xerr, int yerr,
542 int w, int h, int bWidth, int bHeight,
543 int colincx, int colincxerr,
544 int colincy, int colincyerr,
545 int rowincx, int rowincxerr,
546 int rowincy, int rowincyerr) {
547 byte[] inData = this.inData;
548 byte[] outData = this.outData;
549 int out = outOff;
550 int inSpan = this.inSpan;
551 int inOff = this.inOff;
552 int outSpan = this.outSpan;
553 boolean normalx = (colincx == 1 && colincxerr == 0 &&
554 colincy == 0 && colincyerr == 0);
555 int rowx = x;
556 int rowy = y;
557 int rowxerr = xerr;
558 int rowyerr = yerr;
559 if (normalx) {
560 outSpan -= w;
561 }
562 for (int j = 0; j < h; j++) {
563 if (normalx) {
564 int in = inOff + rowy * inSpan + bWidth;
565 x = bWidth - rowx;
566 out += w;
567 if (bWidth >= 32) {
568 int i = w;
569 while (i > 0) {
570 int copyw = (i < x) ? i : x;
571 System.arraycopy(inData, in - x,
572 outData, out - i,
573 copyw);
574 i -= copyw;
575 if ((x -= copyw) == 0) {
576 x = bWidth;
577 }
578 }
579 } else {
580 for (int i = w; i > 0; i--) {
581 outData[out - i] = inData[in - x];
582 if (--x == 0) {
583 x = bWidth;
584 }
585 }
586 }
587 } else {
588 x = rowx;
589 y = rowy;
590 xerr = rowxerr;
591 yerr = rowyerr;
592 for (int i = 0; i < w; i++) {
593 outData[out + i] = inData[inOff + y * inSpan + x];
594 if ((xerr += colincxerr) < 0) {
595 xerr &= Integer.MAX_VALUE;
596 x++;
597 }
598 if ((x += colincx) >= bWidth) {
599 x -= bWidth;
600 }
601 if ((yerr += colincyerr) < 0) {
602 yerr &= Integer.MAX_VALUE;
603 y++;
604 }
605 if ((y += colincy) >= bHeight) {
606 y -= bHeight;
607 }
608 }
609 }
610 if ((rowxerr += rowincxerr) < 0) {
611 rowxerr &= Integer.MAX_VALUE;
612 rowx++;
613 }
614 if ((rowx += rowincx) >= bWidth) {
615 rowx -= bWidth;
616 }
617 if ((rowyerr += rowincyerr) < 0) {
618 rowyerr &= Integer.MAX_VALUE;
619 rowy++;
620 }
621 if ((rowy += rowincy) >= bHeight) {
622 rowy -= bHeight;
623 }
624 out += outSpan;
625 }
626 }
627 }
628
629 static class ByteFilter extends TexturePaintContext {
630 ByteInterleavedRaster srcRas;
631 int inPalette[];
632 byte inData[];
633 int inOff;
634 int inSpan;
635 int outData[];
636 int outOff;
637 int outSpan;
638
639 public ByteFilter(ByteInterleavedRaster srcRas, ColorModel cm,
640 AffineTransform xform, int maxw)
641 {
642 super((cm.getTransparency() == Transparency.OPAQUE
643 ? xrgbmodel : argbmodel),
644 xform, srcRas.getWidth(), srcRas.getHeight(), maxw);
645 this.inPalette = new int[256];
646 ((IndexColorModel) cm).getRGBs(this.inPalette);
647 this.srcRas = srcRas;
648 this.inData = srcRas.getDataStorage();
649 this.inSpan = srcRas.getScanlineStride();
650 this.inOff = srcRas.getDataOffset(0);
651 }
652
653 public WritableRaster makeRaster(int w, int h) {
654 // Note that we do not pass srcRas to makeRaster since it
655 // is a Byte Raster and this colorModel needs an Int Raster
656 WritableRaster ras = makeRaster(colorModel, null, w, h);
657 IntegerInterleavedRaster iiRas = (IntegerInterleavedRaster) ras;
658 outData = iiRas.getDataStorage();
659 outSpan = iiRas.getScanlineStride();
660 outOff = iiRas.getDataOffset(0);
661 return ras;
662 }
663
664 public void setRaster(int x, int y, int xerr, int yerr,
665 int w, int h, int bWidth, int bHeight,
666 int colincx, int colincxerr,
667 int colincy, int colincyerr,
668 int rowincx, int rowincxerr,
669 int rowincy, int rowincyerr) {
670 byte[] inData = this.inData;
671 int[] outData = this.outData;
672 int out = outOff;
673 int inSpan = this.inSpan;
674 int inOff = this.inOff;
675 int outSpan = this.outSpan;
676 int rowx = x;
677 int rowy = y;
678 int rowxerr = xerr;
679 int rowyerr = yerr;
680 int rgbs[] = new int[4];
681 for (int j = 0; j < h; j++) {
682 x = rowx;
683 y = rowy;
684 xerr = rowxerr;
685 yerr = rowyerr;
686 for (int i = 0; i < w; i++) {
687 int nextx, nexty;
688 if ((nextx = x + 1) >= bWidth) {
689 nextx = 0;
690 }
691 if ((nexty = y + 1) >= bHeight) {
692 nexty = 0;
693 }
694 rgbs[0] = inPalette[0xff & inData[inOff + x +
695 inSpan * y]];
696 rgbs[1] = inPalette[0xff & inData[inOff + nextx +
697 inSpan * y]];
698 rgbs[2] = inPalette[0xff & inData[inOff + x +
699 inSpan * nexty]];
700 rgbs[3] = inPalette[0xff & inData[inOff + nextx +
701 inSpan * nexty]];
702 outData[out + i] =
703 TexturePaintContext.blend(rgbs, xerr, yerr);
704 if ((xerr += colincxerr) < 0) {
705 xerr &= Integer.MAX_VALUE;
706 x++;
707 }
708 if ((x += colincx) >= bWidth) {
709 x -= bWidth;
710 }
711 if ((yerr += colincyerr) < 0) {
712 yerr &= Integer.MAX_VALUE;
713 y++;
714 }
715 if ((y += colincy) >= bHeight) {
716 y -= bHeight;
717 }
718 }
719 if ((rowxerr += rowincxerr) < 0) {
720 rowxerr &= Integer.MAX_VALUE;
721 rowx++;
722 }
723 if ((rowx += rowincx) >= bWidth) {
724 rowx -= bWidth;
725 }
726 if ((rowyerr += rowincyerr) < 0) {
727 rowyerr &= Integer.MAX_VALUE;
728 rowy++;
729 }
730 if ((rowy += rowincy) >= bHeight) {
731 rowy -= bHeight;
732 }
733 out += outSpan;
734 }
735 }
736 }
737
738 static class Any extends TexturePaintContext {
739 WritableRaster srcRas;
740 boolean filter;
741
742 public Any(WritableRaster srcRas, ColorModel cm,
743 AffineTransform xform, int maxw, boolean filter)
744 {
745 super(cm, xform, srcRas.getWidth(), srcRas.getHeight(), maxw);
746 this.srcRas = srcRas;
747 this.filter = filter;
748 }
749
750 public WritableRaster makeRaster(int w, int h) {
751 return makeRaster(colorModel, srcRas, w, h);
752 }
753
754 public void setRaster(int x, int y, int xerr, int yerr,
755 int w, int h, int bWidth, int bHeight,
756 int colincx, int colincxerr,
757 int colincy, int colincyerr,
758 int rowincx, int rowincxerr,
759 int rowincy, int rowincyerr) {
760 Object data = null;
761 int rowx = x;
762 int rowy = y;
763 int rowxerr = xerr;
764 int rowyerr = yerr;
765 WritableRaster srcRas = this.srcRas;
766 WritableRaster outRas = this.outRas;
767 int rgbs[] = filter ? new int[4] : null;
768 for (int j = 0; j < h; j++) {
769 x = rowx;
770 y = rowy;
771 xerr = rowxerr;
772 yerr = rowyerr;
773 for (int i = 0; i < w; i++) {
774 data = srcRas.getDataElements(x, y, data);
775 if (filter) {
776 int nextx, nexty;
777 if ((nextx = x + 1) >= bWidth) {
778 nextx = 0;
779 }
780 if ((nexty = y + 1) >= bHeight) {
781 nexty = 0;
782 }
783 rgbs[0] = colorModel.getRGB(data);
784 data = srcRas.getDataElements(nextx, y, data);
785 rgbs[1] = colorModel.getRGB(data);
786 data = srcRas.getDataElements(x, nexty, data);
787 rgbs[2] = colorModel.getRGB(data);
788 data = srcRas.getDataElements(nextx, nexty, data);
789 rgbs[3] = colorModel.getRGB(data);
790 int rgb =
791 TexturePaintContext.blend(rgbs, xerr, yerr);
792 data = colorModel.getDataElements(rgb, data);
793 }
794 outRas.setDataElements(i, j, data);
795 if ((xerr += colincxerr) < 0) {
796 xerr &= Integer.MAX_VALUE;
797 x++;
798 }
799 if ((x += colincx) >= bWidth) {
800 x -= bWidth;
801 }
802 if ((yerr += colincyerr) < 0) {
803 yerr &= Integer.MAX_VALUE;
804 y++;
805 }
806 if ((y += colincy) >= bHeight) {
807 y -= bHeight;
808 }
809 }
810 if ((rowxerr += rowincxerr) < 0) {
811 rowxerr &= Integer.MAX_VALUE;
812 rowx++;
813 }
814 if ((rowx += rowincx) >= bWidth) {
815 rowx -= bWidth;
816 }
817 if ((rowyerr += rowincyerr) < 0) {
818 rowyerr &= Integer.MAX_VALUE;
819 rowy++;
820 }
821 if ((rowy += rowincy) >= bHeight) {
822 rowy -= bHeight;
823 }
824 }
825 }
826 }
827}