Showing the changes to java/pkg/sun/java2d/loops/GeneralRenderer.java (1 of 18352 files). Show all
Unified · Split
| @@ -0,0 +1,1125 @@ | |||
| 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 | } | ||