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