abstractsurface.java

来自「纯java操作系统jnode,安装简单和操作简单的个人使用的Java操作系统」· Java 代码 · 共 376 行

JAVA
376
字号
/*
 * $Id: AbstractSurface.java,v 1.4 2004/01/04 15:40:02 epr Exp $
 */
package org.jnode.driver.video.util;

import java.awt.Color;
import java.awt.Rectangle;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.GeneralPath;
import java.awt.geom.PathIterator;
import java.awt.geom.RectangularShape;

import org.jnode.driver.video.Surface;

/**
 * Abstract and generic implementation of a Surface.
 * 
 * @author epr
 */
public abstract class AbstractSurface implements Surface {

	protected int width;
	protected int height;

	public AbstractSurface(int width, int height) {
		this.width = width;
		this.height = height;
	}

	/**
	 * @see org.jnode.driver.video.Surface#close()
	 */
	public void close() {
		// Nothing to do here
	}

	/**
	 * @see org.jnode.driver.video.Surface#draw(Shape, Shape, AffineTransform, Color, int)
	 */
	public void draw(Shape shape, Shape clip, AffineTransform tx, Color color, int mode) {
		draw(shape, clip, tx, convertColor(color), mode);
	}

	/**
	 * Fill the given shape with the given color
	 * 
	 * @param shape
	 *            The shape to fill
	 * @param clip
	 *            The clipping area, can be null
	 * @param trans
	 *            The transformation to be applied to shape & clip.
	 * @param color
	 * @param mode
	 */
	public void fill(Shape shape, Shape clip, AffineTransform trans, Color color, int mode) {
		final int c = convertColor(color);

		final double tx;
		final double ty;

		final Shape txShape;
		final Shape txClip;
		if (trans == null) {
			tx = 0.0;
			ty = 0.0;
			txShape = shape;
			txClip = clip;
		} else if (trans.getType() == AffineTransform.TYPE_IDENTITY) {
			tx = 0.0;
			ty = 0.0;
			txShape = shape;
			txClip = clip;
		} else if (trans.getType() == AffineTransform.TYPE_TRANSLATION) {
			tx = trans.getTranslateX();
			ty = trans.getTranslateY();
			txShape = shape;
			txClip = clip;
		} else {
			tx = 0.0;
			ty = 0.0;
			final GeneralPath gp = new GeneralPath();
			gp.append(shape.getPathIterator(trans), false);
			txShape = gp;
			if (clip != null) {
				final GeneralPath gpClip = new GeneralPath();
				gp.append(clip.getPathIterator(trans), false);
				txClip = gpClip;
			} else {
				txClip = null;
			}
		}

		Rectangle bounds = txShape.getBounds();
		if (txShape instanceof RectangularShape) {
			if (txClip != null) {
				bounds = bounds.createIntersection(txClip.getBounds2D()).getBounds();
				System.out.println("Clipped bounds " + bounds);
			}
			if ((bounds.width > 0) && (bounds.height > 0)) {
				bounds.translate((int) tx, (int) ty);
				fillRect(bounds.x, bounds.y, bounds.width, bounds.height, c, mode);
			}
		} else {
			//log.debug("Fill " + shape + ", bounds " + bounds);
			for (int row = 0; row < bounds.height; row++) {
				final int y = (int) (ty + bounds.y + row);
				for (int col = 0; col < bounds.width; col++) {
					final int x = (int) (tx + bounds.x + col);
					if (txShape.contains(x, y) && ((txClip == null) || txClip.contains(x, y))) {
						drawPixel(x, y, c, mode);
					}
				}
			}
		}
	}

	/**
	 * Fill a rectangle with the given color.
	 * 
	 * @param x
	 * @param y
	 * @param w
	 * @param h
	 * @param color
	 * @param mode
	 */
	protected void fillRect(int x, int y, int w, int h, int color, int mode) {
		for (int row = 0; row < h; row++) {
			drawLine(x, y + row, x + w, y + row, color, mode);
		}
	}

	/**
	 * Set a pixel at the given location
	 * 
	 * @param x
	 * @param y
	 * @param color
	 * @param mode
	 */
	protected abstract void drawPixel(int x, int y, int color, int mode);

	/**
	 * Draw a line between (x1,y1) and (x2,y2)
	 * 
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 * @param color
	 * @param mode
	 */
	protected void drawLine(int x1, int y1, int x2, int y2, int color, int mode) {
		final int incx, incy;
		int countx, county;

		//log.debug("AS.drawLine " + x1 + "," + y1 + "," + x2 + ","+ y2);

		final int sizex = Math.abs(x2 - x1);
		final int sizey = Math.abs(y2 - y1);
		if (x1 > x2) {
			incx = -1;
		} else {
			incx = 1;
		}
		if (y1 > y2) {
			incy = -1;
		} else {
			incy = 1;
		}
		countx = x1;
		county = y1;

		drawPixel(x1, y1, color, mode);
		if (sizex >= sizey) {
			int y = sizex >> 1;
			final int loops = sizex - 1;
			for (int i = 0; i < loops; i++) {
				y += sizey;
				if (y >= sizex) {
					y -= sizex;
					county += incy;
				}
				countx += incx;
				drawPixel(countx, county, color, mode);
			}
		} else {
			int x = sizey >> 1;
			final int loops = sizey - 1;
			for (int i = 0; i < loops; i++) {
				x += sizex;
				if (x >= sizey) {
					x -= sizey;
					countx += incx;
				}
				county += incy;
				drawPixel(countx, county, color, mode);
			}
		}
	}

	/**
	 * Draw a bezier curve
	 * 
	 * @param x0
	 * @param y0
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 * @param x3
	 * @param y3
	 * @param color
	 * @param mode
	 */
	protected void drawCurve(double x0, double y0, double x1, double y1, double x2, double y2, double x3, double y3, int color, int mode) {
		final double[] points = new double[42];
		Curves.calculateCubicCurve(x0, y0, x1, y1, x2, y2, x3, y3, points);
		for (int i = 0; i < points.length - 2; i += 2) {
			drawLine((int) points[i], (int) points[i + 1], (int) points[i + 2], (int) points[i + 3], color, mode);
		}
	}

	/**
	 * Draw a quadratic parametric curve
	 * 
	 * @param x0
	 * @param y0
	 * @param x1
	 * @param y1
	 * @param x2
	 * @param y2
	 * @param color
	 * @param mode
	 */
	protected void drawQuadCurve(double x0, double y0, double x1, double y1, double x2, double y2, int color, int mode) {
		final double[] points = new double[42];
		Curves.calculateQuadCurve(x0, y0, x1, y1, x2, y2, points);
		for (int i = 0; i < points.length - 2; i += 2) {
			drawLine((int) points[i], (int) points[i + 1], (int) points[i + 2], (int) points[i + 3], color, mode);
		}
	}

	/**
	 * Draw the given shape
	 * 
	 * @param shape
	 * @param clip
	 * @param color
	 * @param mode
	 */
	protected final void draw(Shape shape, Shape clip, AffineTransform trans, int color, int mode) {

		//log.debug("Draw " + shape + ", " + trans);

		final double[] coords = new double[6];
		double moveX = 0;
		double moveY = 0;
		double curX = 0;
		double curY = 0;

		final double tx;
		final double ty;

		if (clip != null) {
			// Very rough for now, but let's see
			if (!clip.contains(shape.getBounds2D())) {
				// TODO fix clipping
				//return;
			}
		}

		final PathIterator i;
		if (trans == null) {
			tx = 0.0;
			ty = 0.0;
			i = shape.getPathIterator(null);
		} else if (trans.getType() == AffineTransform.TYPE_IDENTITY) {
			tx = 0.0;
			ty = 0.0;
			i = shape.getPathIterator(null);
		} else if (trans.getType() == AffineTransform.TYPE_TRANSLATION) {
			tx = trans.getTranslateX();
			ty = trans.getTranslateY();
			i = shape.getPathIterator(null);
		} else {
			tx = 0.0;
			ty = 0.0;
			i = shape.getPathIterator(trans);
		}

		//log.debug("Draw");

		while (!i.isDone()) {
			final int type = i.currentSegment(coords);
			int x;
			int y;
			//log.debug("Segment type " + type);
			switch (type) {
				case PathIterator.SEG_MOVETO :
					curX = moveX = coords[0];
					curY = moveY = coords[1];
					break;
				case PathIterator.SEG_LINETO :
					x = (int) coords[0];
					y = (int) coords[1];
					drawLine((int) (curX + tx), (int) (curY + ty), (int) (x + tx), (int) (y + ty), color, mode);
					curX = x;
					curY = y;
					break;
				case PathIterator.SEG_CLOSE :
					drawLine((int) (moveX + tx), (int) (moveY + ty), (int) (curX + tx), (int) (curY + ty), color, mode);
					break;
				case PathIterator.SEG_CUBICTO :
					//log.debug("CUBICTO ");
					drawCurve(curX + tx, curY + ty, coords[0] + tx, coords[1] + ty, coords[2] + tx, coords[3] + ty, coords[4] + tx, coords[5] + ty, color, mode);
					curX = (int) coords[4];
					curY = (int) coords[5];
					break;
				case PathIterator.SEG_QUADTO :
					drawQuadCurve(curX + tx, curY + ty, coords[0] + tx, coords[1] + ty, coords[2] + tx, coords[3] + ty, color, mode);
					curX = (int) coords[2];
					curY = (int) coords[3];
					break;
			}
			i.next();
		}
		//log.debug("Draw done");
	}

	/**
	 * Convert the given color to an int representation
	 * 
	 * @param color
	 */
	protected abstract int convertColor(Color color);

	protected void setSize(int width, int height) {
		this.width = width;
		this.height = height;
	}

	/**
	 * @return The height of this surface
	 */
	protected final int getHeight() {
		return this.height;
	}

	/**
	 * @return The width of this surface
	 */
	protected final int getWidth() {
		return this.width;
	}

	protected final Rectangle getBounds(Shape shape, AffineTransform trans) {
		if (trans == null) {
			return shape.getBounds();
		} else if (trans.getType() == AffineTransform.TYPE_IDENTITY) {
			return shape.getBounds();
		} else if (trans.getType() == AffineTransform.TYPE_TRANSLATION) {
			Rectangle b = shape.getBounds();
			b.x += trans.getTranslateX();
			b.y += trans.getTranslateY();
			return b;
		} else {
			final GeneralPath gp = new GeneralPath();
			gp.append(shape.getPathIterator(trans), false);
			return gp.getBounds();
		}
	}
}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?