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