1 /* 2 * Copyright (c) 1998, 2008, 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 26 /* 27 * @author Charlton Innovations, Inc. 28 */ 29 30 package sun.java2d.loops; 31 32 import java.awt.image.WritableRaster; 33 import java.awt.image.DataBuffer; 34 import java.awt.image.ColorModel; 35 import java.awt.geom.Path2D; 36 import java.awt.geom.PathIterator; 37 import java.awt.geom.AffineTransform; 38 import sun.java2d.pipe.Region; 39 import sun.java2d.pipe.SpanIterator; 40 import sun.java2d.SunGraphics2D; 41 import sun.java2d.SurfaceData; 42 import sun.java2d.loops.ProcessPath; 43 import sun.font.GlyphList; 44 45 /** 46 * GeneralRenderer collection 47 * Basically, a collection of components which permit basic 48 * rendering to occur on rasters of any format 49 */ 50 51 public final class GeneralRenderer { 52 public static void register() { 53 Class<?> owner = GeneralRenderer.class; 54 GraphicsPrimitive[] primitives = { 55 new GraphicsPrimitiveProxy(owner, "SetFillRectANY", 56 FillRect.methodSignature, 57 FillRect.primTypeID, 58 SurfaceType.AnyColor, 59 CompositeType.SrcNoEa, 60 SurfaceType.Any), 61 new GraphicsPrimitiveProxy(owner, "SetFillPathANY", 62 FillPath.methodSignature, 63 FillPath.primTypeID, 64 SurfaceType.AnyColor, 65 CompositeType.SrcNoEa, 66 SurfaceType.Any), 67 new GraphicsPrimitiveProxy(owner, "SetFillSpansANY", 68 FillSpans.methodSignature, 69 FillSpans.primTypeID, 70 SurfaceType.AnyColor, 71 CompositeType.SrcNoEa, 72 SurfaceType.Any), 73 new GraphicsPrimitiveProxy(owner, "SetDrawLineANY", 74 DrawLine.methodSignature, 75 DrawLine.primTypeID, 76 SurfaceType.AnyColor, 77 CompositeType.SrcNoEa, 78 SurfaceType.Any), 79 new GraphicsPrimitiveProxy(owner, "SetDrawPolygonsANY", 80 DrawPolygons.methodSignature, 81 DrawPolygons.primTypeID, 82 SurfaceType.AnyColor, 83 CompositeType.SrcNoEa, 84 SurfaceType.Any), 85 new GraphicsPrimitiveProxy(owner, "SetDrawPathANY", 86 DrawPath.methodSignature, 87 DrawPath.primTypeID, 88 SurfaceType.AnyColor, 89 CompositeType.SrcNoEa, 90 SurfaceType.Any), 91 new GraphicsPrimitiveProxy(owner, "SetDrawRectANY", 92 DrawRect.methodSignature, 93 DrawRect.primTypeID, 94 SurfaceType.AnyColor, 95 CompositeType.SrcNoEa, 96 SurfaceType.Any), 97 98 new GraphicsPrimitiveProxy(owner, "XorFillRectANY", 99 FillRect.methodSignature, 100 FillRect.primTypeID, 101 SurfaceType.AnyColor, 102 CompositeType.Xor, 103 SurfaceType.Any), 104 new GraphicsPrimitiveProxy(owner, "XorFillPathANY", 105 FillPath.methodSignature, 106 FillPath.primTypeID, 107 SurfaceType.AnyColor, 108 CompositeType.Xor, 109 SurfaceType.Any), 110 new GraphicsPrimitiveProxy(owner, "XorFillSpansANY", 111 FillSpans.methodSignature, 112 FillSpans.primTypeID, 113 SurfaceType.AnyColor, 114 CompositeType.Xor, 115 SurfaceType.Any), 116 new GraphicsPrimitiveProxy(owner, "XorDrawLineANY", 117 DrawLine.methodSignature, 118 DrawLine.primTypeID, 119 SurfaceType.AnyColor, 120 CompositeType.Xor, 121 SurfaceType.Any), 122 new GraphicsPrimitiveProxy(owner, "XorDrawPolygonsANY", 123 DrawPolygons.methodSignature, 124 DrawPolygons.primTypeID, 125 SurfaceType.AnyColor, 126 CompositeType.Xor, 127 SurfaceType.Any), 128 new GraphicsPrimitiveProxy(owner, "XorDrawPathANY", 129 DrawPath.methodSignature, 130 DrawPath.primTypeID, 131 SurfaceType.AnyColor, 132 CompositeType.Xor, 133 SurfaceType.Any), 134 new GraphicsPrimitiveProxy(owner, "XorDrawRectANY", 135 DrawRect.methodSignature, 136 DrawRect.primTypeID, 137 SurfaceType.AnyColor, 138 CompositeType.Xor, 139 SurfaceType.Any), 140 new GraphicsPrimitiveProxy(owner, "XorDrawGlyphListANY", 141 DrawGlyphList.methodSignature, 142 DrawGlyphList.primTypeID, 143 SurfaceType.AnyColor, 144 CompositeType.Xor, 145 SurfaceType.Any), 146 new GraphicsPrimitiveProxy(owner, "XorDrawGlyphListAAANY", 147 DrawGlyphListAA.methodSignature, 148 DrawGlyphListAA.primTypeID, 149 SurfaceType.AnyColor, 150 CompositeType.Xor, 151 SurfaceType.Any), 152 }; 153 GraphicsPrimitiveMgr.register(primitives); 154 } 155 156 static void doDrawPoly(SurfaceData sData, PixelWriter pw, 157 int xPoints[], int yPoints[], int off, int nPoints, 158 Region clip, int transx, int transy, boolean close) 159 { 160 int mx, my, x1, y1; 161 int[] tmp = null; 162 163 if (nPoints <= 0) { 164 return; 165 } 166 mx = x1 = xPoints[off] + transx; 167 my = y1 = yPoints[off] + transy; 168 while (--nPoints > 0) { 169 ++off; 170 int x2 = xPoints[off] + transx; 171 int y2 = yPoints[off] + transy; 172 tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip, 173 x1, y1, x2, y2); 174 x1 = x2; 175 y1 = y2; 176 } 177 if (close && (x1 != mx || y1 != my)) { 178 tmp = GeneralRenderer.doDrawLine(sData, pw, tmp, clip, 179 x1, y1, mx, my); 180 } 181 } 182 183 static void doSetRect(SurfaceData sData, PixelWriter pw, 184 int x1, int y1, int x2, int y2) { 185 WritableRaster dstRast = 186 (WritableRaster) sData.getRaster(x1, y1, x2-x1, y2-y1); 187 pw.setRaster(dstRast); 188 189 while (y1 < y2) { 190 for (int x = x1; x < x2; x++) { 191 pw.writePixel(x, y1); 192 } 193 y1++; 194 } 195 } 196 197 static int[] doDrawLine(SurfaceData sData, PixelWriter pw, int[] boundPts, 198 Region clip, 199 int origx1, int origy1, int origx2, int origy2) 200 { 201 if (boundPts == null) { 202 boundPts = new int[8]; 203 } 204 boundPts[0] = origx1; 205 boundPts[1] = origy1; 206 boundPts[2] = origx2; 207 boundPts[3] = origy2; 208 if (!adjustLine(boundPts, 209 clip.getLoX(), clip.getLoY(), 210 clip.getHiX(), clip.getHiY())) 211 { 212 return boundPts; 213 } 214 int x1 = boundPts[0]; 215 int y1 = boundPts[1]; 216 int x2 = boundPts[2]; 217 int y2 = boundPts[3]; 218 219 WritableRaster dstRast = (WritableRaster) 220 sData.getRaster(Math.min(x1, x2), Math.min(y1, y2), 221 Math.abs(x1 - x2) + 1, Math.abs(y1 - y2) + 1); 222 pw.setRaster(dstRast); 223 224 /* this could be made smaller, more elegant, more traditional. */ 225 if (x1 == x2) { 226 if (y1 > y2) { 227 do { 228 pw.writePixel(x1, y1); 229 y1--; 230 } while (y1 >= y2); 231 } else { 232 do { 233 pw.writePixel(x1, y1); 234 y1++; 235 } while (y1 <= y2); 236 } 237 } else if (y1 == y2) { 238 if (x1 > x2) { 239 do { 240 pw.writePixel(x1, y1); 241 x1--; 242 } while (x1 >= x2); 243 } else { 244 do { 245 pw.writePixel(x1, y1); 246 x1++; 247 } while (x1 <= x2); 248 } 249 } else { 250 int dx = boundPts[4]; 251 int dy = boundPts[5]; 252 int ax = boundPts[6]; 253 int ay = boundPts[7]; 254 int steps; 255 int bumpmajor; 256 int bumpminor; 257 int errminor; 258 int errmajor; 259 int error; 260 boolean xmajor; 261 262 if (ax >= ay) { 263 /* x is dominant */ 264 xmajor = true; 265 errmajor = ay * 2; 266 errminor = ax * 2; 267 bumpmajor = (dx < 0) ? -1 : 1; 268 bumpminor = (dy < 0) ? -1 : 1; 269 ax = -ax; /* For clipping adjustment below */ 270 steps = x2 - x1; 271 } else { 272 /* y is dominant */ 273 xmajor = false; 274 errmajor = ax * 2; 275 errminor = ay * 2; 276 bumpmajor = (dy < 0) ? -1 : 1; 277 bumpminor = (dx < 0) ? -1 : 1; 278 ay = -ay; /* For clipping adjustment below */ 279 steps = y2 - y1; 280 } 281 error = - (errminor / 2); 282 if (y1 != origy1) { 283 int ysteps = y1 - origy1; 284 if (ysteps < 0) { 285 ysteps = -ysteps; 286 } 287 error += ysteps * ax * 2; 288 } 289 if (x1 != origx1) { 290 int xsteps = x1 - origx1; 291 if (xsteps < 0) { 292 xsteps = -xsteps; 293 } 294 error += xsteps * ay * 2; 295 } 296 if (steps < 0) { 297 steps = -steps; 298 } 299 if (xmajor) { 300 do { 301 pw.writePixel(x1, y1); 302 x1 += bumpmajor; 303 error += errmajor; 304 if (error >= 0) { 305 y1 += bumpminor; 306 error -= errminor; 307 } 308 } while (--steps >= 0); 309 } else { 310 do { 311 pw.writePixel(x1, y1); 312 y1 += bumpmajor; 313 error += errmajor; 314 if (error >= 0) { 315 x1 += bumpminor; 316 error -= errminor; 317 } 318 } while (--steps >= 0); 319 } 320 } 321 return boundPts; 322 } 323 324 public static void doDrawRect(PixelWriter pw, 325 SunGraphics2D sg2d, SurfaceData sData, 326 int x, int y, int w, int h) 327 { 328 if (w < 0 || h < 0) { 329 return; 330 } 331 int x2 = Region.dimAdd(Region.dimAdd(x, w), 1); 332 int y2 = Region.dimAdd(Region.dimAdd(y, h), 1); 333 Region r = sg2d.getCompClip().getBoundsIntersectionXYXY(x, y, x2, y2); 334 if (r.isEmpty()) { 335 return; 336 } 337 int cx1 = r.getLoX(); 338 int cy1 = r.getLoY(); 339 int cx2 = r.getHiX(); 340 int cy2 = r.getHiY(); 341 342 if (w < 2 || h < 2) { 343 doSetRect(sData, pw, cx1, cy1, cx2, cy2); 344 return; 345 } 346 347 348 if (cy1 == y) { 349 doSetRect(sData, pw, cx1, cy1, cx2, cy1+1); 350 } 351 if (cx1 == x) { 352 doSetRect(sData, pw, cx1, cy1+1, cx1+1, cy2-1); 353 } 354 if (cx2 == x2) { 355 doSetRect(sData, pw, cx2-1, cy1+1, cx2, cy2-1); 356 } 357 if (cy2 == y2) { 358 doSetRect(sData, pw, cx1, cy2-1, cx2, cy2); 359 } 360 } 361 362 /* 363 * REMIND: For now this will field both AA and non-AA requests and 364 * use a simple threshold to choose pixels if the supplied grey 365 * bits are antialiased. We should really find a way to disable 366 * AA text at a higher level or to have the GlyphList be able to 367 * reset the glyphs to non-AA after construction. 368 */ 369 static void doDrawGlyphList(SurfaceData sData, PixelWriter pw, 370 GlyphList gl, Region clip) 371 { 372 int[] bounds = gl.getBounds(); 373 clip.clipBoxToBounds(bounds); 374 int cx1 = bounds[0]; 375 int cy1 = bounds[1]; 376 int cx2 = bounds[2]; 377 int cy2 = bounds[3]; 378 379 WritableRaster dstRast = 380 (WritableRaster) sData.getRaster(cx1, cy1, cx2 - cx1, cy2 - cy1); 381 pw.setRaster(dstRast); 382 383 int num = gl.getNumGlyphs(); 384 for (int i = 0; i < num; i++) { 385 gl.setGlyphIndex(i); 386 int metrics[] = gl.getMetrics(); 387 int gx1 = metrics[0]; 388 int gy1 = metrics[1]; 389 int w = metrics[2]; 390 int gx2 = gx1 + w; 391 int gy2 = gy1 + metrics[3]; 392 int off = 0; 393 if (gx1 < cx1) { 394 off = cx1 - gx1; 395 gx1 = cx1; 396 } 397 if (gy1 < cy1) { 398 off += (cy1 - gy1) * w; 399 gy1 = cy1; 400 } 401 if (gx2 > cx2) gx2 = cx2; 402 if (gy2 > cy2) gy2 = cy2; 403 if (gx2 > gx1 && gy2 > gy1) { 404 byte alpha[] = gl.getGrayBits(); 405 w -= (gx2 - gx1); 406 for (int y = gy1; y < gy2; y++) { 407 for (int x = gx1; x < gx2; x++) { 408 if (alpha[off++] < 0) { 409 pw.writePixel(x, y); 410 } 411 } 412 off += w; 413 } 414 } 415 } 416 } 417 418 static final int OUTCODE_TOP = 1; 419 static final int OUTCODE_BOTTOM = 2; 420 static final int OUTCODE_LEFT = 4; 421 static final int OUTCODE_RIGHT = 8; 422 423 static int outcode(int x, int y, int xmin, int ymin, int xmax, int ymax) { 424 int code; 425 if (y < ymin) { 426 code = OUTCODE_TOP; 427 } else if (y > ymax) { 428 code = OUTCODE_BOTTOM; 429 } else { 430 code = 0; 431 } 432 if (x < xmin) { 433 code |= OUTCODE_LEFT; 434 } else if (x > xmax) { 435 code |= OUTCODE_RIGHT; 436 } 437 return code; 438 } 439 440 public static boolean adjustLine(int [] boundPts, 441 int cxmin, int cymin, int cx2, int cy2) 442 { 443 int cxmax = cx2 - 1; 444 int cymax = cy2 - 1; 445 int x1 = boundPts[0]; 446 int y1 = boundPts[1]; 447 int x2 = boundPts[2]; 448 int y2 = boundPts[3]; 449 450 if ((cxmax < cxmin) || (cymax < cymin)) { 451 return false; 452 } 453 454 if (x1 == x2) { 455 if (x1 < cxmin || x1 > cxmax) { 456 return false; 457 } 458 if (y1 > y2) { 459 int t = y1; 460 y1 = y2; 461 y2 = t; 462 } 463 if (y1 < cymin) { 464 y1 = cymin; 465 } 466 if (y2 > cymax) { 467 y2 = cymax; 468 } 469 if (y1 > y2) { 470 return false; 471 } 472 boundPts[1] = y1; 473 boundPts[3] = y2; 474 } else if (y1 == y2) { 475 if (y1 < cymin || y1 > cymax) { 476 return false; 477 } 478 if (x1 > x2) { 479 int t = x1; 480 x1 = x2; 481 x2 = t; 482 } 483 if (x1 < cxmin) { 484 x1 = cxmin; 485 } 486 if (x2 > cxmax) { 487 x2 = cxmax; 488 } 489 if (x1 > x2) { 490 return false; 491 } 492 boundPts[0] = x1; 493 boundPts[2] = x2; 494 } else { 495 /* REMIND: This could overflow... */ 496 int outcode1, outcode2; 497 int dx = x2 - x1; 498 int dy = y2 - y1; 499 int ax = (dx < 0) ? -dx : dx; 500 int ay = (dy < 0) ? -dy : dy; 501 boolean xmajor = (ax >= ay); 502 503 outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax); 504 outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax); 505 while ((outcode1 | outcode2) != 0) { 506 int xsteps, ysteps; 507 if ((outcode1 & outcode2) != 0) { 508 return false; 509 } 510 if (outcode1 != 0) { 511 if (0 != (outcode1 & (OUTCODE_TOP | OUTCODE_BOTTOM))) { 512 if (0 != (outcode1 & OUTCODE_TOP)) { 513 y1 = cymin; 514 } else { 515 y1 = cymax; 516 } 517 ysteps = y1 - boundPts[1]; 518 if (ysteps < 0) { 519 ysteps = -ysteps; 520 } 521 xsteps = 2 * ysteps * ax + ay; 522 if (xmajor) { 523 xsteps += ay - ax - 1; 524 } 525 xsteps = xsteps / (2 * ay); 526 if (dx < 0) { 527 xsteps = -xsteps; 528 } 529 x1 = boundPts[0] + xsteps; 530 } else if (0 != 531 (outcode1 & (OUTCODE_LEFT | OUTCODE_RIGHT))) { 532 if (0 != (outcode1 & OUTCODE_LEFT)) { 533 x1 = cxmin; 534 } else { 535 x1 = cxmax; 536 } 537 xsteps = x1 - boundPts[0]; 538 if (xsteps < 0) { 539 xsteps = -xsteps; 540 } 541 ysteps = 2 * xsteps * ay + ax; 542 if (!xmajor) { 543 ysteps += ax - ay - 1; 544 } 545 ysteps = ysteps / (2 * ax); 546 if (dy < 0) { 547 ysteps = -ysteps; 548 } 549 y1 = boundPts[1] + ysteps; 550 } 551 outcode1 = outcode(x1, y1, cxmin, cymin, cxmax, cymax); 552 } else { 553 if (0 != (outcode2 & (OUTCODE_TOP | OUTCODE_BOTTOM))) { 554 if (0 != (outcode2 & OUTCODE_TOP)) { 555 y2 = cymin; 556 } else { 557 y2 = cymax; 558 } 559 ysteps = y2 - boundPts[3]; 560 if (ysteps < 0) { 561 ysteps = -ysteps; 562 } 563 xsteps = 2 * ysteps * ax + ay; 564 if (xmajor) { 565 xsteps += ay - ax; 566 } else { 567 xsteps -= 1; 568 } 569 xsteps = xsteps / (2 * ay); 570 if (dx > 0) { 571 xsteps = -xsteps; 572 } 573 x2 = boundPts[2] + xsteps; 574 } else if (0 != 575 (outcode2 & (OUTCODE_LEFT | OUTCODE_RIGHT))) { 576 if (0 != (outcode2 & OUTCODE_LEFT)) { 577 x2 = cxmin; 578 } else { 579 x2 = cxmax; 580 } 581 xsteps = x2 - boundPts[2]; 582 if (xsteps < 0) { 583 xsteps = -xsteps; 584 } 585 ysteps = 2 * xsteps * ay + ax; 586 if (xmajor) { 587 ysteps -= 1; 588 } else { 589 ysteps += ax - ay; 590 } 591 ysteps = ysteps / (2 * ax); 592 if (dy > 0) { 593 ysteps = -ysteps; 594 } 595 y2 = boundPts[3] + ysteps; 596 } 597 outcode2 = outcode(x2, y2, cxmin, cymin, cxmax, cymax); 598 } 599 } 600 boundPts[0] = x1; 601 boundPts[1] = y1; 602 boundPts[2] = x2; 603 boundPts[3] = y2; 604 boundPts[4] = dx; 605 boundPts[5] = dy; 606 boundPts[6] = ax; 607 boundPts[7] = ay; 608 } 609 return true; 610 } 611 612 static PixelWriter createSolidPixelWriter(SunGraphics2D sg2d, 613 SurfaceData sData) 614 { 615 ColorModel dstCM = sData.getColorModel(); 616 Object srcPixel = dstCM.getDataElements(sg2d.eargb, null); 617 618 return new SolidPixelWriter(srcPixel); 619 } 620 621 static PixelWriter createXorPixelWriter(SunGraphics2D sg2d, 622 SurfaceData sData) 623 { 624 ColorModel dstCM = sData.getColorModel(); 625 626 Object srcPixel = dstCM.getDataElements(sg2d.eargb, null); 627 628 XORComposite comp = (XORComposite)sg2d.getComposite(); 629 int xorrgb = comp.getXorColor().getRGB(); 630 Object xorPixel = dstCM.getDataElements(xorrgb, null); 631 632 switch (dstCM.getTransferType()) { 633 case DataBuffer.TYPE_BYTE: 634 return new XorPixelWriter.ByteData(srcPixel, xorPixel); 635 case DataBuffer.TYPE_SHORT: 636 case DataBuffer.TYPE_USHORT: 637 return new XorPixelWriter.ShortData(srcPixel, xorPixel); 638 case DataBuffer.TYPE_INT: 639 return new XorPixelWriter.IntData(srcPixel, xorPixel); 640 case DataBuffer.TYPE_FLOAT: 641 return new XorPixelWriter.FloatData(srcPixel, xorPixel); 642 case DataBuffer.TYPE_DOUBLE: 643 return new XorPixelWriter.DoubleData(srcPixel, xorPixel); 644 default: 645 throw new InternalError("Unsupported XOR pixel type"); 646 } 647 } 648 } 649 650 class SetFillRectANY extends FillRect { 651 SetFillRectANY() { 652 super(SurfaceType.AnyColor, 653 CompositeType.SrcNoEa, 654 SurfaceType.Any); 655 } 656 657 public void FillRect(SunGraphics2D sg2d, SurfaceData sData, 658 int x, int y, int w, int h) 659 { 660 PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); 661 662 Region r = sg2d.getCompClip().getBoundsIntersectionXYWH(x, y, w, h); 663 664 GeneralRenderer.doSetRect(sData, pw, 665 r.getLoX(), r.getLoY(), 666 r.getHiX(), r.getHiY()); 667 } 668 } 669 670 class PixelWriterDrawHandler extends ProcessPath.DrawHandler { 671 PixelWriter pw; 672 SurfaceData sData; 673 Region clip; 674 675 public PixelWriterDrawHandler(SurfaceData sData, PixelWriter pw, 676 Region clip, int strokeHint) { 677 super(clip.getLoX(), clip.getLoY(), 678 clip.getHiX(), clip.getHiY(), 679 strokeHint); 680 this.sData = sData; 681 this.pw = pw; 682 this.clip = clip; 683 } 684 685 public void drawLine(int x0, int y0, int x1, int y1) { 686 GeneralRenderer.doDrawLine(sData, pw, null, clip, 687 x0, y0, x1, y1); 688 } 689 690 public void drawPixel(int x0, int y0) { 691 GeneralRenderer.doSetRect(sData, pw, x0, y0, x0 + 1, y0 + 1); 692 } 693 694 public void drawScanline(int x0, int x1, int y0) { 695 GeneralRenderer.doSetRect(sData, pw, x0, y0, x1 + 1, y0 + 1); 696 } 697 } 698 699 class SetFillPathANY extends FillPath { 700 SetFillPathANY() { 701 super(SurfaceType.AnyColor, CompositeType.SrcNoEa, 702 SurfaceType.Any); 703 } 704 705 public void FillPath(SunGraphics2D sg2d, SurfaceData sData, 706 int transx, int transy, 707 Path2D.Float p2df) 708 { 709 PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); 710 ProcessPath.fillPath( 711 new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(), 712 sg2d.strokeHint), 713 p2df, transx, transy); 714 } 715 } 716 717 class SetFillSpansANY extends FillSpans { 718 SetFillSpansANY() { 719 super(SurfaceType.AnyColor, 720 CompositeType.SrcNoEa, 721 SurfaceType.Any); 722 } 723 724 public void FillSpans(SunGraphics2D sg2d, SurfaceData sData, 725 SpanIterator si) 726 { 727 PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); 728 729 int span[] = new int[4]; 730 while (si.nextSpan(span)) { 731 GeneralRenderer.doSetRect(sData, pw, 732 span[0], span[1], span[2], span[3]); 733 } 734 } 735 } 736 737 class SetDrawLineANY extends DrawLine { 738 SetDrawLineANY() { 739 super(SurfaceType.AnyColor, 740 CompositeType.SrcNoEa, 741 SurfaceType.Any); 742 } 743 744 public void DrawLine(SunGraphics2D sg2d, SurfaceData sData, 745 int x1, int y1, int x2, int y2) 746 { 747 PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); 748 749 if (y1 >= y2) { 750 GeneralRenderer.doDrawLine(sData, pw, null, 751 sg2d.getCompClip(), 752 x2, y2, x1, y1); 753 } else { 754 GeneralRenderer.doDrawLine(sData, pw, null, 755 sg2d.getCompClip(), 756 x1, y1, x2, y2); 757 } 758 } 759 } 760 761 class SetDrawPolygonsANY extends DrawPolygons { 762 SetDrawPolygonsANY() { 763 super(SurfaceType.AnyColor, 764 CompositeType.SrcNoEa, 765 SurfaceType.Any); 766 } 767 768 public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData, 769 int xPoints[], int yPoints[], 770 int nPoints[], int numPolys, 771 int transx, int transy, 772 boolean close) 773 { 774 PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); 775 776 int off = 0; 777 Region clip = sg2d.getCompClip(); 778 for (int i = 0; i < numPolys; i++) { 779 int numpts = nPoints[i]; 780 GeneralRenderer.doDrawPoly(sData, pw, 781 xPoints, yPoints, off, numpts, 782 clip, transx, transy, close); 783 off += numpts; 784 } 785 } 786 } 787 788 class SetDrawPathANY extends DrawPath { 789 SetDrawPathANY() { 790 super(SurfaceType.AnyColor, 791 CompositeType.SrcNoEa, 792 SurfaceType.Any); 793 } 794 795 public void DrawPath(SunGraphics2D sg2d, SurfaceData sData, 796 int transx, int transy, 797 Path2D.Float p2df) 798 { 799 PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); 800 ProcessPath.drawPath( 801 new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(), 802 sg2d.strokeHint), 803 p2df, transx, transy 804 ); 805 } 806 } 807 808 class SetDrawRectANY extends DrawRect { 809 SetDrawRectANY() { 810 super(SurfaceType.AnyColor, 811 CompositeType.SrcNoEa, 812 SurfaceType.Any); 813 } 814 815 public void DrawRect(SunGraphics2D sg2d, SurfaceData sData, 816 int x, int y, int w, int h) 817 { 818 PixelWriter pw = GeneralRenderer.createSolidPixelWriter(sg2d, sData); 819 820 GeneralRenderer.doDrawRect(pw, sg2d, sData, x, y, w, h); 821 } 822 } 823 824 class XorFillRectANY extends FillRect { 825 XorFillRectANY() { 826 super(SurfaceType.AnyColor, 827 CompositeType.Xor, 828 SurfaceType.Any); 829 } 830 831 public void FillRect(SunGraphics2D sg2d, SurfaceData sData, 832 int x, int y, int w, int h) 833 { 834 PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); 835 836 Region r = sg2d.getCompClip().getBoundsIntersectionXYWH(x, y, w, h); 837 838 GeneralRenderer.doSetRect(sData, pw, 839 r.getLoX(), r.getLoY(), 840 r.getHiX(), r.getHiY()); 841 } 842 } 843 844 class XorFillPathANY extends FillPath { 845 XorFillPathANY() { 846 super(SurfaceType.AnyColor, CompositeType.Xor, 847 SurfaceType.Any); 848 } 849 850 public void FillPath(SunGraphics2D sg2d, SurfaceData sData, 851 int transx, int transy, 852 Path2D.Float p2df) 853 { 854 PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); 855 ProcessPath.fillPath( 856 new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(), 857 sg2d.strokeHint), 858 p2df, transx, transy); 859 } 860 } 861 862 class XorFillSpansANY extends FillSpans { 863 XorFillSpansANY() { 864 super(SurfaceType.AnyColor, 865 CompositeType.Xor, 866 SurfaceType.Any); 867 } 868 869 public void FillSpans(SunGraphics2D sg2d, SurfaceData sData, 870 SpanIterator si) 871 { 872 PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); 873 874 int span[] = new int[4]; 875 while (si.nextSpan(span)) { 876 GeneralRenderer.doSetRect(sData, pw, 877 span[0], span[1], span[2], span[3]); 878 } 879 } 880 } 881 882 class XorDrawLineANY extends DrawLine { 883 XorDrawLineANY() { 884 super(SurfaceType.AnyColor, 885 CompositeType.Xor, 886 SurfaceType.Any); 887 } 888 889 public void DrawLine(SunGraphics2D sg2d, SurfaceData sData, 890 int x1, int y1, int x2, int y2) 891 { 892 PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); 893 894 if (y1 >= y2) { 895 GeneralRenderer.doDrawLine(sData, pw, null, 896 sg2d.getCompClip(), 897 x2, y2, x1, y1); 898 } else { 899 GeneralRenderer.doDrawLine(sData, pw, null, 900 sg2d.getCompClip(), 901 x1, y1, x2, y2); 902 } 903 } 904 } 905 906 class XorDrawPolygonsANY extends DrawPolygons { 907 XorDrawPolygonsANY() { 908 super(SurfaceType.AnyColor, 909 CompositeType.Xor, 910 SurfaceType.Any); 911 } 912 913 public void DrawPolygons(SunGraphics2D sg2d, SurfaceData sData, 914 int xPoints[], int yPoints[], 915 int nPoints[], int numPolys, 916 int transx, int transy, 917 boolean close) 918 { 919 PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); 920 921 int off = 0; 922 Region clip = sg2d.getCompClip(); 923 for (int i = 0; i < numPolys; i++) { 924 int numpts = nPoints[i]; 925 GeneralRenderer.doDrawPoly(sData, pw, 926 xPoints, yPoints, off, numpts, 927 clip, transx, transy, close); 928 off += numpts; 929 } 930 } 931 } 932 933 class XorDrawPathANY extends DrawPath { 934 XorDrawPathANY() { 935 super(SurfaceType.AnyColor, 936 CompositeType.Xor, 937 SurfaceType.Any); 938 } 939 940 public void DrawPath(SunGraphics2D sg2d, SurfaceData sData, 941 int transx, int transy, Path2D.Float p2df) 942 { 943 PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); 944 ProcessPath.drawPath( 945 new PixelWriterDrawHandler(sData, pw, sg2d.getCompClip(), 946 sg2d.strokeHint), 947 p2df, transx, transy 948 ); 949 } 950 } 951 952 class XorDrawRectANY extends DrawRect { 953 XorDrawRectANY() { 954 super(SurfaceType.AnyColor, 955 CompositeType.Xor, 956 SurfaceType.Any); 957 } 958 959 public void DrawRect(SunGraphics2D sg2d, SurfaceData sData, 960 int x, int y, int w, int h) 961 { 962 PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); 963 964 GeneralRenderer.doDrawRect(pw, sg2d, sData, x, y, w, h); 965 } 966 } 967 968 class XorDrawGlyphListANY extends DrawGlyphList { 969 XorDrawGlyphListANY() { 970 super(SurfaceType.AnyColor, 971 CompositeType.Xor, 972 SurfaceType.Any); 973 } 974 975 public void DrawGlyphList(SunGraphics2D sg2d, SurfaceData sData, 976 GlyphList gl) 977 { 978 PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); 979 GeneralRenderer.doDrawGlyphList(sData, pw, gl, sg2d.getCompClip()); 980 } 981 } 982 983 class XorDrawGlyphListAAANY extends DrawGlyphListAA { 984 XorDrawGlyphListAAANY() { 985 super(SurfaceType.AnyColor, 986 CompositeType.Xor, 987 SurfaceType.Any); 988 } 989 990 public void DrawGlyphListAA(SunGraphics2D sg2d, SurfaceData sData, 991 GlyphList gl) 992 { 993 PixelWriter pw = GeneralRenderer.createXorPixelWriter(sg2d, sData); 994 GeneralRenderer.doDrawGlyphList(sData, pw, gl, sg2d.getCompClip()); 995 } 996 } 997 998 abstract class PixelWriter { 999 protected WritableRaster dstRast; 1000 1001 public void setRaster(WritableRaster dstRast) { 1002 this.dstRast = dstRast; 1003 } 1004 1005 public abstract void writePixel(int x, int y); 1006 } 1007 1008 class SolidPixelWriter extends PixelWriter { 1009 protected Object srcData; 1010 1011 SolidPixelWriter(Object srcPixel) { 1012 this.srcData = srcPixel; 1013 } 1014 1015 public void writePixel(int x, int y) { 1016 dstRast.setDataElements(x, y, srcData); 1017 } 1018 } 1019 1020 abstract class XorPixelWriter extends PixelWriter { 1021 protected ColorModel dstCM; 1022 1023 public void writePixel(int x, int y) { 1024 Object dstPixel = dstRast.getDataElements(x, y, null); 1025 xorPixel(dstPixel); 1026 dstRast.setDataElements(x, y, dstPixel); 1027 } 1028 1029 protected abstract void xorPixel(Object pixData); 1030 1031 public static class ByteData extends XorPixelWriter { 1032 byte[] xorData; 1033 1034 ByteData(Object srcPixel, Object xorPixel) { 1035 this.xorData = (byte[]) srcPixel; 1036 xorPixel(xorPixel); 1037 this.xorData = (byte[]) xorPixel; 1038 } 1039 1040 protected void xorPixel(Object pixData) { 1041 byte[] dstData = (byte[]) pixData; 1042 for (int i = 0; i < dstData.length; i++) { 1043 dstData[i] ^= xorData[i]; 1044 } 1045 } 1046 } 1047 1048 public static class ShortData extends XorPixelWriter { 1049 short[] xorData; 1050 1051 ShortData(Object srcPixel, Object xorPixel) { 1052 this.xorData = (short[]) srcPixel; 1053 xorPixel(xorPixel); 1054 this.xorData = (short[]) xorPixel; 1055 } 1056 1057 protected void xorPixel(Object pixData) { 1058 short[] dstData = (short[]) pixData; 1059 for (int i = 0; i < dstData.length; i++) { 1060 dstData[i] ^= xorData[i]; 1061 } 1062 } 1063 } 1064 1065 public static class IntData extends XorPixelWriter { 1066 int[] xorData; 1067 1068 IntData(Object srcPixel, Object xorPixel) { 1069 this.xorData = (int[]) srcPixel; 1070 xorPixel(xorPixel); 1071 this.xorData = (int[]) xorPixel; 1072 } 1073 1074 protected void xorPixel(Object pixData) { 1075 int[] dstData = (int[]) pixData; 1076 for (int i = 0; i < dstData.length; i++) { 1077 dstData[i] ^= xorData[i]; 1078 } 1079 } 1080 } 1081 1082 public static class FloatData extends XorPixelWriter { 1083 int[] xorData; 1084 1085 FloatData(Object srcPixel, Object xorPixel) { 1086 float[] srcData = (float[]) srcPixel; 1087 float[] xorData = (float[]) xorPixel; 1088 this.xorData = new int[srcData.length]; 1089 for (int i = 0; i < srcData.length; i++) { 1090 this.xorData[i] = (Float.floatToIntBits(srcData[i]) ^ 1091 Float.floatToIntBits(xorData[i])); 1092 } 1093 } 1094 1095 protected void xorPixel(Object pixData) { 1096 float[] dstData = (float[]) pixData; 1097 for (int i = 0; i < dstData.length; i++) { 1098 int v = Float.floatToIntBits(dstData[i]) ^ xorData[i]; 1099 dstData[i] = Float.intBitsToFloat(v); 1100 } 1101 } 1102 } 1103 1104 public static class DoubleData extends XorPixelWriter { 1105 long[] xorData; 1106 1107 DoubleData(Object srcPixel, Object xorPixel) { 1108 double[] srcData = (double[]) srcPixel; 1109 double[] xorData = (double[]) xorPixel; 1110 this.xorData = new long[srcData.length]; 1111 for (int i = 0; i < srcData.length; i++) { 1112 this.xorData[i] = (Double.doubleToLongBits(srcData[i]) ^ 1113 Double.doubleToLongBits(xorData[i])); 1114 } 1115 } 1116 1117 protected void xorPixel(Object pixData) { 1118 double[] dstData = (double[]) pixData; 1119 for (int i = 0; i < dstData.length; i++) { 1120 long v = Double.doubleToLongBits(dstData[i]) ^ xorData[i]; 1121 dstData[i] = Double.longBitsToDouble(v); 1122 } 1123 } 1124 } 1125 }