/* * Copyright (c) 2010, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.java2d.xr; /** * Represents a single tile, used to store the rectangles covering the area * of the mask where the tile is located. * * @author Clemens Eisserer */ public class MaskTile { GrowableRectArray rects; DirtyRegion dirtyArea; public MaskTile() { rects = new GrowableRectArray(128); dirtyArea = new DirtyRegion(); } public void addRect(int x, int y, int width, int height) { int index = rects.getNextIndex(); rects.setX(index, x); rects.setY(index, y); rects.setWidth(index, width); rects.setHeight(index, height); } public void addLine(int x1, int y1, int x2, int y2) { /* * EXA is not able to accalerate diagonal lines, we try to "guide" it a * bit to avoid excessive migration See project documentation for an * detailed explanation */ DirtyRegion region = new DirtyRegion(); region.setDirtyLineRegion(x1, y1, x2, y2); int xDiff = region.x2 - region.x; int yDiff = region.y2 - region.y; if (xDiff == 0 || yDiff == 0) { addRect(region.x, region.y, region.x2 - region.x + 1, region.y2 - region.y + 1); } else if (xDiff == 1 && yDiff == 1) { addRect(x1, y1, 1, 1); addRect(x2, y2, 1, 1); } else { lineToRects(x1, y1, x2, y2); } } private void lineToRects(int xstart, int ystart, int xend, int yend) { int x, y, t, dx, dy, incx, incy, pdx, pdy, ddx, ddy, es, el, err; /* Entfernung in beiden Dimensionen berechnen */ dx = xend - xstart; dy = yend - ystart; /* Vorzeichen des Inkrements bestimmen */ incx = dx > 0 ? 1 : (dx < 0) ? -1 : 0; incy = dy > 0 ? 1 : (dy < 0) ? -1 : 0; if (dx < 0) dx = -dx; if (dy < 0) dy = -dy; /* feststellen, welche Entfernung groesser ist */ if (dx > dy) { /* x ist schnelle Richtung */ pdx = incx; pdy = 0; /* pd. ist Parallelschritt */ ddx = incx; ddy = incy; /* dd. ist Diagonalschritt */ es = dy; el = dx; /* Fehlerschritte schnell, langsam */ } else { /* y ist schnelle Richtung */ pdx = 0; pdy = incy; /* pd. ist Parallelschritt */ ddx = incx; ddy = incy; /* dd. ist Diagonalschritt */ es = dx; el = dy; /* Fehlerschritte schnell, langsam */ } /* Initialisierungen vor Schleifenbeginn */ x = xstart; y = ystart; err = el / 2; addRect(x, y, 1, 1); /* Pixel berechnen */ for (t = 0; t < el; ++t) /* t zaehlt die Pixel, el ist auch Anzahl */ { /* Aktualisierung Fehlerterm */ err -= es; if (err < 0) { /* Fehlerterm wieder positiv (>=0) machen */ err += el; /* Schritt in langsame Richtung, Diagonalschritt */ x += ddx; y += ddy; } else { /* Schritt in schnelle Richtung, Parallelschritt */ x += pdx; y += pdy; } addRect(x, y, 1, 1); // SetPixel(x,y); // System.out.println(x+":"+y); } } public void calculateDirtyAreas() { for (int i=0; i < rects.getSize(); i++) { int x = rects.getX(i); int y = rects.getY(i); dirtyArea.growDirtyRegion(x, y, x + rects.getWidth(i), y + rects.getHeight(i)); } } public void reset() { rects.clear(); dirtyArea.clear(); } public void translate(int x, int y) { if (rects.getSize() > 0) { dirtyArea.translate(x, y); } rects.translateRects(x, y); } public GrowableRectArray getRects() { return rects; } public DirtyRegion getDirtyArea() { return dirtyArea; } }