1 18 package org.apache.batik.ext.awt; 19 20 import java.awt.Color ; 21 import java.awt.PaintContext ; 22 import java.awt.Rectangle ; 23 import java.awt.RenderingHints ; 24 import java.awt.color.ColorSpace ; 25 import java.awt.geom.AffineTransform ; 26 import java.awt.geom.NoninvertibleTransformException ; 27 import java.awt.geom.Rectangle2D ; 28 import java.awt.image.ColorModel ; 29 import java.awt.image.DataBuffer ; 30 import java.awt.image.DataBufferInt ; 31 import java.awt.image.DirectColorModel ; 32 import java.awt.image.Raster ; 33 import java.awt.image.SinglePixelPackedSampleModel ; 34 import java.awt.image.WritableRaster ; 35 import java.lang.ref.WeakReference ; 36 37 import org.apache.batik.ext.awt.image.GraphicsUtil; 38 39 49 abstract class MultipleGradientPaintContext implements PaintContext { 50 51 protected final static boolean DEBUG = false; 52 53 56 protected ColorModel dataModel; 57 62 protected ColorModel model; 63 64 65 private static ColorModel lrgbmodel_NA = new DirectColorModel 66 (ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), 67 24, 0xff0000, 0xFF00, 0xFF, 0x0, 68 false, DataBuffer.TYPE_INT); 69 70 private static ColorModel srgbmodel_NA = new DirectColorModel 71 (ColorSpace.getInstance(ColorSpace.CS_sRGB), 72 24, 0xff0000, 0xFF00, 0xFF, 0x0, 73 false, DataBuffer.TYPE_INT); 74 75 76 private static ColorModel lrgbmodel_A = new DirectColorModel 77 (ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB), 78 32, 0xff0000, 0xFF00, 0xFF, 0xFF000000, 79 false, DataBuffer.TYPE_INT); 80 81 private static ColorModel srgbmodel_A = new DirectColorModel 82 (ColorSpace.getInstance(ColorSpace.CS_sRGB), 83 32, 0xff0000, 0xFF00, 0xFF, 0xFF000000, 84 false, DataBuffer.TYPE_INT); 85 86 87 protected static ColorModel cachedModel; 88 89 90 protected static WeakReference cached; 91 92 93 protected WritableRaster saved; 94 95 96 protected MultipleGradientPaint.CycleMethodEnum cycleMethod; 97 98 99 protected MultipleGradientPaint.ColorSpaceEnum colorSpace; 100 101 102 protected float a00, a01, a10, a11, a02, a12; 103 104 110 protected boolean isSimpleLookup = true; 111 112 116 protected boolean hasDiscontinuity = false; 117 118 120 protected int fastGradientArraySize; 121 122 127 protected int[] gradient; 128 129 132 protected int[][] gradients; 133 134 138 protected int gradientAverage; 139 140 142 protected int gradientUnderflow; 143 144 146 protected int gradientOverflow; 147 148 149 protected int gradientsLength; 150 151 152 protected float[] normalizedIntervals; 153 154 155 protected float[] fractions; 156 157 158 private int transparencyTest; 159 160 161 private static final int SRGBtoLinearRGB[] = new int[256]; 162 private static final int LinearRGBtoSRGB[] = new int[256]; 163 164 static{ 166 for (int k = 0; k < 256; k++) { 167 SRGBtoLinearRGB[k] = convertSRGBtoLinearRGB(k); 168 LinearRGBtoSRGB[k] = convertLinearRGBtoSRGB(k); 169 } 170 } 171 172 175 protected static final int GRADIENT_SIZE = 256; 176 protected static final int GRADIENT_SIZE_INDEX = GRADIENT_SIZE -1; 177 178 183 private static final int MAX_GRADIENT_ARRAY_SIZE = 5000; 184 185 191 public MultipleGradientPaintContext(ColorModel cm, 192 Rectangle deviceBounds, 193 Rectangle2D userBounds, 194 AffineTransform t, 195 RenderingHints hints, 196 float[] fractions, 197 Color [] colors, 198 MultipleGradientPaint.CycleMethodEnum 199 cycleMethod, 200 MultipleGradientPaint.ColorSpaceEnum 201 colorSpace) 202 throws NoninvertibleTransformException 203 { 204 209 boolean fixFirst = false; 210 boolean fixLast = false; 211 int len = fractions.length; 212 213 if (fractions[0] != 0f) { 215 fixFirst = true; 216 len++; 217 } 218 219 if (fractions[fractions.length - 1] != 1f) { 221 fixLast = true; 222 len++; 223 } 224 225 for (int i=0; i<fractions.length-1; i++) 226 if (fractions[i] == fractions[i+1]) 227 len--; 228 229 this.fractions = new float[len]; 230 Color [] loColors = new Color [len-1]; 231 Color [] hiColors = new Color [len-1]; 232 normalizedIntervals = new float[len-1]; 233 234 gradientUnderflow = colors[0].getRGB(); 235 gradientOverflow = colors[colors.length-1].getRGB(); 236 237 int idx = 0; 238 if (fixFirst) { 239 this.fractions[0] = 0; 240 loColors[0] = colors[0]; 241 hiColors[0] = colors[0]; 242 normalizedIntervals[0] = fractions[0]; 243 idx++; 244 } 245 246 for (int i=0; i<fractions.length-1; i++) { 247 if (fractions[i] == fractions[i+1]) { 248 if (!colors[i].equals(colors[i+1])) { 250 hasDiscontinuity = true; 251 } 252 continue; 253 } 254 this.fractions[idx] = fractions[i]; 255 loColors[idx] = colors[i]; 256 hiColors[idx] = colors[i+1]; 257 normalizedIntervals[idx] = fractions[i+1]-fractions[i]; 258 idx++; 259 } 260 261 this.fractions[idx] = fractions[fractions.length-1]; 262 263 if (fixLast) { 264 loColors[idx] = hiColors[idx] = colors[colors.length-1]; 265 normalizedIntervals[idx] = 1-fractions[fractions.length-1]; 266 idx++; 267 this.fractions[idx] = 1; 268 } 269 270 AffineTransform tInv = t.createInverse(); 273 274 double m[] = new double[6]; 275 tInv.getMatrix(m); 276 a00 = (float)m[0]; 277 a10 = (float)m[1]; 278 a01 = (float)m[2]; 279 a11 = (float)m[3]; 280 a02 = (float)m[4]; 281 a12 = (float)m[5]; 282 283 this.cycleMethod = cycleMethod; 285 this.colorSpace = colorSpace; 286 287 if (cm.getColorSpace() == lrgbmodel_A.getColorSpace()) 289 dataModel = lrgbmodel_A; 290 else if (cm.getColorSpace() == srgbmodel_A.getColorSpace()) 291 dataModel = srgbmodel_A; 292 else 293 throw new IllegalArgumentException 294 ("Unsupported ColorSpace for interpolation"); 295 296 calculateGradientFractions(loColors, hiColors); 297 298 model = GraphicsUtil.coerceColorModel(dataModel, 299 cm.isAlphaPremultiplied()); 300 } 301 302 303 307 protected final void calculateGradientFractions 308 (Color []loColors, Color []hiColors) { 309 310 if (colorSpace == LinearGradientPaint.LINEAR_RGB) { 313 for (int i = 0; i < loColors.length; i++) { 314 loColors[i] = 315 new Color (SRGBtoLinearRGB[loColors[i].getRed()], 316 SRGBtoLinearRGB[loColors[i].getGreen()], 317 SRGBtoLinearRGB[loColors[i].getBlue()], 318 loColors[i].getAlpha()); 319 320 hiColors[i] = 321 new Color (SRGBtoLinearRGB[hiColors[i].getRed()], 322 SRGBtoLinearRGB[hiColors[i].getGreen()], 323 SRGBtoLinearRGB[hiColors[i].getBlue()], 324 hiColors[i].getAlpha()); 325 } 326 } 327 328 transparencyTest = 0xff000000; 330 if (cycleMethod == MultipleGradientPaint.NO_CYCLE) { 331 transparencyTest &= gradientUnderflow; 334 transparencyTest &= gradientOverflow; 335 } 336 337 gradients = new int[fractions.length - 1][]; 339 gradientsLength = gradients.length; 340 341 int n = normalizedIntervals.length; 343 344 float Imin = 1; 345 346 for(int i = 0; i < n; i++) { 347 Imin = (Imin > normalizedIntervals[i]) ? 348 normalizedIntervals[i] : Imin; 349 } 350 351 int estimatedSize = 0; 357 358 if (Imin == 0) { 359 estimatedSize = Integer.MAX_VALUE; 360 hasDiscontinuity = true; 361 } else { 362 for (int i = 0; i < normalizedIntervals.length; i++) { 363 estimatedSize += (normalizedIntervals[i]/Imin) * GRADIENT_SIZE; 364 } 365 } 366 367 368 if (estimatedSize > MAX_GRADIENT_ARRAY_SIZE) { 369 calculateMultipleArrayGradient(loColors, hiColors); 371 if ((cycleMethod == MultipleGradientPaint.REPEAT) && 372 (gradients[0][0] != 373 gradients[gradients.length-1][GRADIENT_SIZE_INDEX])) 374 hasDiscontinuity = true; 375 } else { 376 calculateSingleArrayGradient(loColors, hiColors, Imin); 378 if ((cycleMethod == MultipleGradientPaint.REPEAT) && 379 (gradient[0] != gradient[fastGradientArraySize])) 380 hasDiscontinuity = true; 381 } 382 383 if((transparencyTest >>> 24) == 0xff) { 385 if (dataModel.getColorSpace() == lrgbmodel_NA.getColorSpace()) 386 dataModel = lrgbmodel_NA; 387 else if (dataModel.getColorSpace() == srgbmodel_NA.getColorSpace()) 388 dataModel = srgbmodel_NA; 389 model = dataModel; 390 } 391 } 392 393 394 418 private void calculateSingleArrayGradient 419 (Color [] loColors, Color [] hiColors, float Imin) { 420 421 isSimpleLookup = true; 423 424 int rgb1; int rgb2; 426 427 int gradientsTot = 1; 429 int aveA = 0x008000; 431 int aveR = 0x008000; 432 int aveG = 0x008000; 433 int aveB = 0x008000; 434 435 for(int i=0; i < gradients.length; i++){ 437 438 int nGradients = (int)((normalizedIntervals[i]/Imin)*255f); 441 gradientsTot += nGradients; 442 gradients[i] = new int[nGradients]; 443 444 rgb1 = loColors[i].getRGB(); 446 rgb2 = hiColors[i].getRGB(); 447 448 interpolate(rgb1, rgb2, gradients[i]); 450 451 int argb = gradients[i][GRADIENT_SIZE/2]; 453 float norm = normalizedIntervals[i]; 454 aveA += (int)(((argb>> 8)&0xFF0000)*norm); 455 aveR += (int)(((argb )&0xFF0000)*norm); 456 aveG += (int)(((argb<< 8)&0xFF0000)*norm); 457 aveB += (int)(((argb<<16)&0xFF0000)*norm); 458 459 transparencyTest &= rgb1; 461 transparencyTest &= rgb2; 462 } 463 464 gradientAverage = (((aveA & 0xFF0000)<< 8) | 465 ((aveR & 0xFF0000) ) | 466 ((aveG & 0xFF0000)>> 8) | 467 ((aveB & 0xFF0000)>>16)); 468 469 gradient = new int[gradientsTot]; 471 int curOffset = 0; 472 for(int i = 0; i < gradients.length; i++){ 473 System.arraycopy(gradients[i], 0, gradient, 474 curOffset, gradients[i].length); 475 curOffset += gradients[i].length; 476 } 477 gradient[gradient.length-1] = hiColors[hiColors.length-1].getRGB(); 478 479 if (colorSpace == LinearGradientPaint.LINEAR_RGB) { 482 if (dataModel.getColorSpace() == 483 ColorSpace.getInstance(ColorSpace.CS_sRGB)) { 484 for (int i = 0; i < gradient.length; i++) { 485 gradient[i] = 486 convertEntireColorLinearRGBtoSRGB(gradient[i]); 487 } 488 gradientAverage = 489 convertEntireColorLinearRGBtoSRGB(gradientAverage); 490 } 491 } else { 492 if (dataModel.getColorSpace() == 493 ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB)) { 494 for (int i = 0; i < gradient.length; i++) { 495 gradient[i] = 496 convertEntireColorSRGBtoLinearRGB(gradient[i]); 497 } 498 gradientAverage = 499 convertEntireColorSRGBtoLinearRGB(gradientAverage); 500 } 501 } 502 503 fastGradientArraySize = gradient.length - 1; 504 } 505 506 507 526 private void calculateMultipleArrayGradient 527 (Color [] loColors, Color [] hiColors) { 528 529 isSimpleLookup = false; 531 532 int rgb1; int rgb2; 534 535 int aveA = 0x008000; 537 int aveR = 0x008000; 538 int aveG = 0x008000; 539 int aveB = 0x008000; 540 541 for(int i=0; i < gradients.length; i++){ 543 544 if (normalizedIntervals[i] == 0) 546 continue; 547 548 gradients[i] = new int[GRADIENT_SIZE]; 550 551 rgb1 = loColors[i].getRGB(); 553 rgb2 = hiColors[i].getRGB(); 554 555 interpolate(rgb1, rgb2, gradients[i]); 557 558 int argb = gradients[i][GRADIENT_SIZE/2]; 560 float norm = normalizedIntervals[i]; 561 aveA += (int)(((argb>> 8)&0xFF0000)*norm); 562 aveR += (int)(((argb )&0xFF0000)*norm); 563 aveG += (int)(((argb<< 8)&0xFF0000)*norm); 564 aveB += (int)(((argb<<16)&0xFF0000)*norm); 565 566 transparencyTest &= rgb1; 568 transparencyTest &= rgb2; 569 } 570 571 gradientAverage = (((aveA & 0xFF0000)<< 8) | 572 ((aveR & 0xFF0000) ) | 573 ((aveG & 0xFF0000)>> 8) | 574 ((aveB & 0xFF0000)>>16)); 575 576 if (colorSpace == LinearGradientPaint.LINEAR_RGB) { 579 if (dataModel.getColorSpace() == 580 ColorSpace.getInstance(ColorSpace.CS_sRGB)) { 581 for (int j = 0; j < gradients.length; j++) { 582 for (int i = 0; i < gradients[j].length; i++) { 583 gradients[j][i] = 584 convertEntireColorLinearRGBtoSRGB(gradients[j][i]); 585 } 586 } 587 gradientAverage = 588 convertEntireColorLinearRGBtoSRGB(gradientAverage); 589 } 590 } else { 591 if (dataModel.getColorSpace() == 592 ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB)) { 593 for (int j = 0; j < gradients.length; j++) { 594 for (int i = 0; i < gradients[j].length; i++) { 595 gradients[j][i] = 596 convertEntireColorSRGBtoLinearRGB(gradients[j][i]); 597 } 598 } 599 gradientAverage = 600 convertEntireColorSRGBtoLinearRGB(gradientAverage); 601 } 602 } 603 } 604 605 613 private void interpolate(int rgb1, int rgb2, int[] output) { 614 615 int a1, r1, g1, b1, da, dr, dg, db; 617 float stepSize = 1/(float)output.length; 619 620 a1 = (rgb1 >> 24) & 0xff; 622 r1 = (rgb1 >> 16) & 0xff; 623 g1 = (rgb1 >> 8) & 0xff; 624 b1 = (rgb1 ) & 0xff; 625 da = ((rgb2 >> 24) & 0xff) - a1; 627 dr = ((rgb2 >> 16) & 0xff) - r1; 628 dg = ((rgb2 >> 8) & 0xff) - g1; 629 db = ((rgb2 ) & 0xff) - b1; 630 631 for (int i = 0; i < output.length; i++) { 635 output[i] = 636 (((int) ((a1 + i * da * stepSize) + .5) << 24)) | 637 (((int) ((r1 + i * dr * stepSize) + .5) << 16)) | 638 (((int) ((g1 + i * dg * stepSize) + .5) << 8)) | 639 (((int) ((b1 + i * db * stepSize) + .5) )); 640 } 641 } 642 643 644 648 private int convertEntireColorLinearRGBtoSRGB(int rgb) { 649 650 int a1, r1, g1, b1; 652 a1 = (rgb >> 24) & 0xff; 654 r1 = (rgb >> 16) & 0xff; 655 g1 = (rgb >> 8) & 0xff; 656 b1 = rgb & 0xff; 657 658 r1 = LinearRGBtoSRGB[r1]; 660 g1 = LinearRGBtoSRGB[g1]; 661 b1 = LinearRGBtoSRGB[b1]; 662 663 return ((a1 << 24) | 665 (r1 << 16) | 666 (g1 << 8) | 667 b1); 668 } 669 670 674 private int convertEntireColorSRGBtoLinearRGB(int rgb) { 675 676 int a1, r1, g1, b1; 678 a1 = (rgb >> 24) & 0xff; 680 r1 = (rgb >> 16) & 0xff; 681 g1 = (rgb >> 8) & 0xff; 682 b1 = rgb & 0xff; 683 684 r1 = SRGBtoLinearRGB[r1]; 686 g1 = SRGBtoLinearRGB[g1]; 687 b1 = SRGBtoLinearRGB[b1]; 688 689 return ((a1 << 24) | 691 (r1 << 16) | 692 (g1 << 8) | 693 b1); 694 } 695 696 697 708 protected final int indexIntoGradientsArrays(float position) { 709 710 712 if (cycleMethod == MultipleGradientPaint.NO_CYCLE) { 713 714 if (position >= 1) { return gradientOverflow; 716 } 717 718 else if (position <= 0) { return gradientUnderflow; 720 } 721 } 722 723 else if (cycleMethod == MultipleGradientPaint.REPEAT) { 724 position = position - (int)position; 727 728 730 if (position < 0) { 731 position = position + 1; } 733 734 int w=0, c1=0, c2=0; 735 if (isSimpleLookup) { 736 position *= gradient.length; 737 int idx1 = (int)(position); 738 if (idx1+1 < gradient.length) 739 return gradient[idx1]; 740 741 w = (int)((position-idx1)*(1<<16)); 742 c1 = gradient[idx1]; 743 c2 = gradient[0]; 744 } else { 745 for (int i = 0; i < gradientsLength; i++) { 747 748 if (position < fractions[i+1]) { 750 float delta = position - fractions[i]; 751 752 delta = ((delta / normalizedIntervals[i]) * GRADIENT_SIZE); 753 int index = (int)delta; 755 if ((index+1<gradients[i].length) || 756 (i+1 < gradientsLength)) 757 return gradients[i][index]; 758 759 w = (int)((delta-index)*(1<<16)); 760 c1 = gradients[i][index]; 761 c2 = gradients[0][0]; 762 break; 763 } 764 } 765 } 766 767 return 768 (((( ( (c1>> 8) &0xFF0000)+ 769 ((((c2>>>24) )-((c1>>>24) ))*w))&0xFF0000)<< 8) | 770 771 ((( ( (c1 ) &0xFF0000)+ 772 ((((c2>> 16)&0xFF)-((c1>> 16)&0xFF))*w))&0xFF0000) ) | 773 774 ((( ( (c1<< 8) &0xFF0000)+ 775 ((((c2>> 8)&0xFF)-((c1>> 8)&0xFF))*w))&0xFF0000)>> 8) | 776 777 ((( ( (c1<< 16) &0xFF0000)+ 778 ((((c2 )&0xFF)-((c1 )&0xFF))*w))&0xFF0000)>>16)); 779 780 } 786 787 else { 789 if (position < 0) { 790 position = -position; } 792 793 int part = (int)position; 795 position = position - part; 797 if ((part & 0x00000001) == 1) { position = 1 - position; } 800 } 801 802 804 if (isSimpleLookup) { return gradient[(int)(position * fastGradientArraySize)]; 806 } 807 808 else { 810 for (int i = 0; i < gradientsLength; i++) { 812 813 if (position < fractions[i+1]) { 815 float delta = position - fractions[i]; 816 817 int index = (int)((delta / normalizedIntervals[i]) 819 * (GRADIENT_SIZE_INDEX)); 820 821 return gradients[i][index]; 822 } 823 } 824 825 } 826 827 return gradientOverflow; 828 } 829 830 831 843 protected final int indexGradientAntiAlias(float position, float sz) { 844 if (cycleMethod == MultipleGradientPaint.NO_CYCLE) { 846 if (DEBUG) System.out.println("NO_CYCLE"); 847 float p1 = position-(sz/2); 848 float p2 = position+(sz/2); 849 850 if (p1 >= 1) 851 return gradientOverflow; 852 853 if (p2 <= 0) 854 return gradientUnderflow; 855 856 int interior; 857 float top_weight=0, bottom_weight=0, frac; 858 if (p2 >= 1) { 859 top_weight = (p2-1)/sz; 860 if (p1 <= 0) { 861 bottom_weight = -p1/sz; 862 frac=1; 863 interior = gradientAverage; 864 } else { 865 frac=1-p1; 866 interior = getAntiAlias(p1, true, 1, false, 1-p1, 1); 867 } 868 } else if (p1 <= 0) { 869 bottom_weight = -p1/sz; 870 frac = p2; 871 interior = getAntiAlias(0, true, p2, false, p2, 1); 872 } else 873 return getAntiAlias(p1, true, p2, false, sz, 1); 874 875 int norm = (int)((1<<16)*frac/sz); 876 int pA = (((interior>>>20)&0xFF0)*norm)>>16; 877 int pR = (((interior>> 12)&0xFF0)*norm)>>16; 878 int pG = (((interior>> 4)&0xFF0)*norm)>>16; 879 int pB = (((interior<< 4)&0xFF0)*norm)>>16; 880 881 if (bottom_weight != 0) { 882 int bPix = gradientUnderflow; 883 norm = (int)((1<<16)*bottom_weight); 885 pA += (((bPix>>>20) & 0xFF0)*norm)>>16; 886 pR += (((bPix>> 12) & 0xFF0)*norm)>>16; 887 pG += (((bPix>> 4) & 0xFF0)*norm)>>16; 888 pB += (((bPix<< 4) & 0xFF0)*norm)>>16; 889 } 890 891 if (top_weight != 0) { 892 int tPix = gradientOverflow; 893 894 norm = (int)((1<<16)*top_weight); 895 pA += (((tPix>>>20) & 0xFF0)*norm)>>16; 896 pR += (((tPix>> 12) & 0xFF0)*norm)>>16; 897 pG += (((tPix>> 4) & 0xFF0)*norm)>>16; 898 pB += (((tPix<< 4) & 0xFF0)*norm)>>16; 899 } 900 901 return (((pA&0xFF0)<<20) | 902 ((pR&0xFF0)<<12) | 903 ((pG&0xFF0)<< 4) | 904 ((pB&0xFF0)>> 4)); 905 } 906 907 int intSz = (int)sz; 910 911 float weight = 1f; 912 if (intSz != 0) { 913 sz -= intSz; 917 weight = sz/(intSz+sz); 918 if (weight < 0.1) 919 return gradientAverage; 923 } 924 925 if (sz > 0.99) 927 return gradientAverage; 928 929 float p1 = position-(sz/2); 931 float p2 = position+(sz/2); 932 if (DEBUG) System.out.println("P1: " + p1 + " P2: " + p2); 933 934 boolean p1_up=true; 937 boolean p2_up=false; 938 939 if (cycleMethod == MultipleGradientPaint.REPEAT) { 940 if (DEBUG) System.out.println("REPEAT"); 941 942 p1=p1-(int)p1; 944 p2=p2-(int)p2; 945 946 if (p1 <0) p1 += 1; 948 if (p2 <0) p2 += 1; 949 } 950 951 else { if (DEBUG) System.out.println("REFLECT"); 953 954 if (p2 < 0) { 957 p1 = -p1; p1_up = !p1_up; 958 p2 = -p2; p2_up = !p2_up; 959 } else if (p1 < 0) { 960 p1 = -p1; p1_up = !p1_up; 961 } 962 963 int part1, part2; 964 part1 = (int)p1; p1 = p1 - part1; 967 part2 = (int)p2; p2 = p2 - part2; 970 if ((part1 & 0x01) == 1) { 973 p1 = 1-p1; 974 p1_up = !p1_up; 975 } 976 977 if ((part2 & 0x01) == 1) { 978 p2 = 1-p2; 979 p2_up = !p2_up; 980 } 981 982 if ((p1 > p2) && !p1_up && p2_up) { 985 float t = p1; 986 p1 = p2; 987 p2 = t; 988 p1_up = true; 989 p2_up = false; 990 } 991 } 992 993 return getAntiAlias(p1, p1_up, p2, p2_up, sz, weight); 994 } 995 996 997 private final int getAntiAlias(float p1, boolean p1_up, 998 float p2, boolean p2_up, 999 float sz, float weight) { 1000 1001 int ach=0, rch=0, gch=0, bch=0; 1003 if (isSimpleLookup) { 1004 p1 *= fastGradientArraySize; 1005 p2 *= fastGradientArraySize; 1006 1007 int idx1 = (int)p1; 1008 int idx2 = (int)p2; 1009 1010 int i, pix; 1011 1012 if (p1_up && !p2_up && (idx1 <= idx2)) { 1013 1014 if (idx1 == idx2) 1015 return gradient[idx1]; 1016 1017 for (i=idx1+1; i<idx2; i++) { 1019 pix = gradient[i]; 1020 ach += ((pix>>>20)&0xFF0); 1021 rch += ((pix>>>12)&0xFF0); 1022 gch += ((pix>>> 4)&0xFF0); 1023 bch += ((pix<< 4)&0xFF0); 1024 } 1025 } else { 1026 if (p1_up) { 1029 for (i=idx1+1; i<fastGradientArraySize; i++) { 1030 pix = gradient[i]; 1031 ach += ((pix>>>20)&0xFF0); 1032 rch += ((pix>>>12)&0xFF0); 1033 gch += ((pix>>> 4)&0xFF0); 1034 bch += ((pix<< 4)&0xFF0); 1035 } 1036 } else { 1037 for (i=0; i<idx1; i++) { 1038 pix = gradient[i]; 1039 ach += ((pix>>>20)&0xFF0); 1040 rch += ((pix>>>12)&0xFF0); 1041 gch += ((pix>>> 4)&0xFF0); 1042 bch += ((pix<< 4)&0xFF0); 1043 } 1044 } 1045 1046 if (p2_up) { 1047 for (i=idx2+1; i<fastGradientArraySize; i++) { 1048 pix = gradient[i]; 1049 ach += ((pix>>>20)&0xFF0); 1050 rch += ((pix>>>12)&0xFF0); 1051 gch += ((pix>>> 4)&0xFF0); 1052 bch += ((pix<< 4)&0xFF0); 1053 } 1054 } else { 1055 for (i=0; i<idx2; i++) { 1056 pix = gradient[i]; 1057 ach += ((pix>>>20)&0xFF0); 1058 rch += ((pix>>>12)&0xFF0); 1059 gch += ((pix>>> 4)&0xFF0); 1060 bch += ((pix<< 4)&0xFF0); 1061 } 1062 } 1063 } 1064 1065 int norm, isz; 1066 1067 isz = (int)((1<<16)/(sz*fastGradientArraySize)); 1069 ach = (ach*isz)>>16; 1070 rch = (rch*isz)>>16; 1071 gch = (gch*isz)>>16; 1072 bch = (bch*isz)>>16; 1073 1074 if (p1_up) norm = (int)((1-(p1-idx1))*isz); 1076 else norm = (int)( (p1-idx1) *isz); 1077 pix = gradient[idx1]; 1078 ach += (((pix>>>20)&0xFF0) *norm)>>16; 1079 rch += (((pix>>>12)&0xFF0) *norm)>>16; 1080 gch += (((pix>>> 4)&0xFF0) *norm)>>16; 1081 bch += (((pix<< 4)&0xFF0) *norm)>>16; 1082 1083 if (p2_up) norm = (int)((1-(p2-idx2))*isz); 1084 else norm = (int)( (p2-idx2) *isz); 1085 pix = gradient[idx2]; 1086 ach += (((pix>>>20)&0xFF0) *norm)>>16; 1087 rch += (((pix>>>12)&0xFF0) *norm)>>16; 1088 gch += (((pix>>> 4)&0xFF0) *norm)>>16; 1089 bch += (((pix<< 4)&0xFF0) *norm)>>16; 1090 1091 ach = (ach+0x08)>>4; 1093 rch = (rch+0x08)>>4; 1094 gch = (gch+0x08)>>4; 1095 bch = (bch+0x08)>>4; 1096 1097 } else { 1098 int idx1=0, idx2=0; 1099 int i1=-1, i2=-1; 1100 float f1=0, f2=0; 1101 for (int i = 0; i < gradientsLength; i++) { 1103 if ((p1 < fractions[i+1]) && (i1 == -1)) { 1104 i1 = i; 1106 f1 = p1 - fractions[i]; 1107 1108 f1 = ((f1/normalizedIntervals[i]) 1109 *GRADIENT_SIZE_INDEX); 1110 idx1 = (int)f1; 1112 if (i2 != -1) break; 1113 } 1114 if ((p2 < fractions[i+1]) && (i2 == -1)) { 1115 i2 = i; 1117 f2 = p2 - fractions[i]; 1118 1119 f2 = ((f2/normalizedIntervals[i]) 1120 *GRADIENT_SIZE_INDEX); 1121 idx2 = (int)f2; 1123 if (i1 != -1) break; 1124 } 1125 } 1126 1127 if (i1 == -1) { 1128 i1 = gradients.length - 1; 1129 f1 = idx1 = GRADIENT_SIZE_INDEX; 1130 } 1131 1132 if (i2 == -1) { 1133 i2 = gradients.length - 1; 1134 f2 = idx2 = GRADIENT_SIZE_INDEX; 1135 } 1136 1137 if (DEBUG) System.out.println("I1: " + i1 + " Idx1: " + idx1 + 1138 " I2: " + i2 + " Idx2: " + idx2); 1139 1140 if ((i1 == i2) && (idx1 <= idx2) && p1_up && !p2_up) 1143 return gradients[i1][(idx1+idx2+1)>>1]; 1144 1145 1147 int pix, norm; 1148 int base = (int)((1<<16)/sz); 1149 if ((i1 < i2) && p1_up && !p2_up) { 1150 norm = (int)((base 1151 *normalizedIntervals[i1] 1152 *(GRADIENT_SIZE_INDEX-f1)) 1153 /GRADIENT_SIZE_INDEX); 1154 pix = gradients[i1][(idx1+GRADIENT_SIZE)>>1]; 1155 ach += (((pix>>>20)&0xFF0) *norm)>>16; 1156 rch += (((pix>>>12)&0xFF0) *norm)>>16; 1157 gch += (((pix>>> 4)&0xFF0) *norm)>>16; 1158 bch += (((pix<< 4)&0xFF0) *norm)>>16; 1159 1160 for (int i=i1+1; i<i2; i++) { 1161 norm = (int)(base*normalizedIntervals[i]); 1162 pix = gradients[i][GRADIENT_SIZE>>1]; 1163 1164 ach += (((pix>>>20)&0xFF0) *norm)>>16; 1165 rch += (((pix>>>12)&0xFF0) *norm)>>16; 1166 gch += (((pix>>> 4)&0xFF0) *norm)>>16; 1167 bch += (((pix<< 4)&0xFF0) *norm)>>16; 1168 } 1169 1170 norm = (int)((base*normalizedIntervals[i2]*f2) 1171 /GRADIENT_SIZE_INDEX); 1172 pix = gradients[i2][(idx2+1)>>1]; 1173 ach += (((pix>>>20)&0xFF0) *norm)>>16; 1174 rch += (((pix>>>12)&0xFF0) *norm)>>16; 1175 gch += (((pix>>> 4)&0xFF0) *norm)>>16; 1176 bch += (((pix<< 4)&0xFF0) *norm)>>16; 1177 } else { 1178 if (p1_up) { 1179 norm = (int)((base 1180 *normalizedIntervals[i1] 1181 *(GRADIENT_SIZE_INDEX-f1)) 1182 /GRADIENT_SIZE_INDEX); 1183 pix = gradients[i1][(idx1+GRADIENT_SIZE)>>1]; 1184 } else { 1185 norm = (int)((base*normalizedIntervals[i1]*f1) 1186 /GRADIENT_SIZE_INDEX); 1187 pix = gradients[i1][(idx1+1)>>1]; 1188 } 1189 ach += (((pix>>>20)&0xFF0) *norm)>>16; 1190 rch += (((pix>>>12)&0xFF0) *norm)>>16; 1191 gch += (((pix>>> 4)&0xFF0) *norm)>>16; 1192 bch += (((pix<< 4)&0xFF0) *norm)>>16; 1193 1194 if (p2_up) { 1195 norm = (int)((base 1196 *normalizedIntervals[i2] 1197 *(GRADIENT_SIZE_INDEX-f2)) 1198 /GRADIENT_SIZE_INDEX); 1199 pix = gradients[i2][(idx2+GRADIENT_SIZE)>>1]; 1200 } else { 1201 norm = (int)((base*normalizedIntervals[i2]*f2) 1202 /GRADIENT_SIZE_INDEX); 1203 pix = gradients[i2][(idx2+1)>>1]; 1204 } 1205 ach += (((pix>>>20)&0xFF0) *norm)>>16; 1206 rch += (((pix>>>12)&0xFF0) *norm)>>16; 1207 gch += (((pix>>> 4)&0xFF0) *norm)>>16; 1208 bch += (((pix<< 4)&0xFF0) *norm)>>16; 1209 1210 if (p1_up) { 1211 for (int i=i1+1; i<gradientsLength; i++) { 1212 norm = (int)(base*normalizedIntervals[i]); 1213 pix = gradients[i][GRADIENT_SIZE>>1]; 1214 1215 ach += (((pix>>>20)&0xFF0) *norm)>>16; 1216 rch += (((pix>>>12)&0xFF0) *norm)>>16; 1217 gch += (((pix>>> 4)&0xFF0) *norm)>>16; 1218 bch += (((pix<< 4)&0xFF0) *norm)>>16; 1219 } 1220 } else { 1221 for (int i=0; i<i1; i++) { 1222 norm = (int)(base*normalizedIntervals[i]); 1223 pix = gradients[i][GRADIENT_SIZE>>1]; 1224 1225 ach += (((pix>>>20)&0xFF0) *norm)>>16; 1226 rch += (((pix>>>12)&0xFF0) *norm)>>16; 1227 gch += (((pix>>> 4)&0xFF0) *norm)>>16; 1228 bch += (((pix<< 4)&0xFF0) *norm)>>16; 1229 } 1230 } 1231 1232 if (p2_up) { 1233 for (int i=i2+1; i<gradientsLength; i++) { 1234 norm = (int)(base*normalizedIntervals[i]); 1235 pix = gradients[i][GRADIENT_SIZE>>1]; 1236 1237 ach += (((pix>>>20)&0xFF0) *norm)>>16; 1238 rch += (((pix>>>12)&0xFF0) *norm)>>16; 1239 gch += (((pix>>> 4)&0xFF0) *norm)>>16; 1240 bch += (((pix<< 4)&0xFF0) *norm)>>16; 1241 } 1242 } else { 1243 for (int i=0; i<i2; i++) { 1244 norm = (int)(base*normalizedIntervals[i]); 1245 pix = gradients[i][GRADIENT_SIZE>>1]; 1246 1247 ach += (((pix>>>20)&0xFF0) *norm)>>16; 1248 rch += (((pix>>>12)&0xFF0) *norm)>>16; 1249 gch += (((pix>>> 4)&0xFF0) *norm)>>16; 1250 bch += (((pix<< 4)&0xFF0) *norm)>>16; 1251 } 1252 } 1253 1254 } 1255 ach = (ach+0x08)>>4; 1256 rch = (rch+0x08)>>4; 1257 gch = (gch+0x08)>>4; 1258 bch = (bch+0x08)>>4; 1259 if (DEBUG) System.out.println("Pix: [" + ach + ", " + rch + 1260 ", " + gch + ", " + bch + "]"); 1261 } 1262 1263 if (weight != 1) { 1264 int aveW = (int)((1<<16)*(1-weight)); 1266 int aveA = ((gradientAverage>>>24) & 0xFF)*aveW; 1267 int aveR = ((gradientAverage>> 16) & 0xFF)*aveW; 1268 int aveG = ((gradientAverage>> 8) & 0xFF)*aveW; 1269 int aveB = ((gradientAverage ) & 0xFF)*aveW; 1270 1271 int iw = (int)(weight*(1<<16)); 1272 ach = ((ach*iw)+aveA)>>16; 1273 rch = ((rch*iw)+aveR)>>16; 1274 gch = ((gch*iw)+aveG)>>16; 1275 bch = ((bch*iw)+aveB)>>16; 1276 } 1277 1278 return ((ach<<24) | (rch<<16) | (gch<<8) | bch); 1279 } 1280 1281 1282 1285 private static int convertSRGBtoLinearRGB(int color) { 1286 1287 float input, output; 1288 1289 input = color/255.0f; 1290 if (input <= 0.04045f) { 1291 output = input/12.92f; 1292 } 1293 else { 1294 output = (float) Math.pow((input + 0.055) / 1.055, 2.4); 1295 } 1296 int o = Math.round(output * 255.0f); 1297 1298 return o; 1299 } 1300 1301 1304 private static int convertLinearRGBtoSRGB(int color) { 1305 1306 float input, output; 1307 1308 input = color/255.0f; 1309 1310 if (input <= 0.0031308) { 1311 output = input * 12.92f; 1312 } 1313 else { 1314 output = (1.055f * 1315 ((float) Math.pow(input, (1.0 / 2.4)))) - 0.055f; 1316 } 1317 1318 int o = Math.round(output * 255.0f); 1319 1320 return o; 1321 } 1322 1323 1324 1325 public final Raster getRaster(int x, int y, int w, int h) { 1326 if (w == 0 || h == 0) { 1327 return null; 1328 } 1329 1330 WritableRaster raster = saved; 1335 if (raster == null || raster.getWidth() < w || raster.getHeight() < h) 1336 { 1337 raster = getCachedRaster(dataModel, w, h); 1338 saved = raster; 1339 } 1340 1341 DataBufferInt rasterDB = (DataBufferInt )raster.getDataBuffer(); 1348 int[] pixels = rasterDB.getBankData()[0]; 1349 int off = rasterDB.getOffset(); 1350 int scanlineStride = ((SinglePixelPackedSampleModel ) 1351 raster.getSampleModel()).getScanlineStride(); 1352 int adjust = scanlineStride - w; 1353 1354 fillRaster(pixels, off, adjust, x, y, w, h); 1356 GraphicsUtil.coerceData(raster, dataModel, 1357 model.isAlphaPremultiplied()); 1358 1359 1360 return raster; 1361 } 1362 1363 1364 protected abstract void fillRaster(int pixels[], int off, int adjust, 1365 int x, int y, int w, int h); 1366 1367 1368 1372 protected final 1373 static synchronized WritableRaster getCachedRaster 1374 (ColorModel cm, int w, int h) { 1375 if (cm == cachedModel) { 1376 if (cached != null) { 1377 WritableRaster ras = (WritableRaster ) cached.get(); 1378 if (ras != null && 1379 ras.getWidth() >= w && 1380 ras.getHeight() >= h) 1381 { 1382 cached = null; 1383 return ras; 1384 } 1385 } 1386 } 1387 if (w<32) w=32; 1389 if (h<32) h=32; 1390 return cm.createCompatibleWritableRaster(w, h); 1391 } 1392 1393 1397 protected final 1398 static synchronized void putCachedRaster(ColorModel cm, 1399 WritableRaster ras) { 1400 if (cached != null) { 1401 WritableRaster cras = (WritableRaster ) cached.get(); 1402 if (cras != null) { 1403 int cw = cras.getWidth(); 1404 int ch = cras.getHeight(); 1405 int iw = ras.getWidth(); 1406 int ih = ras.getHeight(); 1407 if (cw >= iw && ch >= ih) { 1408 return; 1409 } 1410 if (cw * ch >= iw * ih) { 1411 return; 1412 } 1413 } 1414 } 1415 cachedModel = cm; 1416 cached = new WeakReference (ras); 1417 } 1418 1419 1422 public final void dispose() { 1423 if (saved != null) { 1424 putCachedRaster(model, saved); 1425 saved = null; 1426 } 1427 } 1428 1429 1432 public final ColorModel getColorModel() { 1433 return model; 1434 } 1435} 1436 1437 | Popular Tags |