simpleglyph.java

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

JAVA
205
字号
/*
 * $Id: SimpleGlyph.java,v 1.1 2003/11/25 11:51:38 epr Exp $
 */
package org.jnode.awt.font.truetype;

import java.awt.geom.GeneralPath;
import java.io.IOException;

public class SimpleGlyph extends Glyph {

	private static final int ON_CURVE = 0;
	private static final int X_SHORT = 1;
	private static final int Y_SHORT = 2;
	private static final int REPEAT_FLAG = 3;
	private static final int X_SAME = 4;
	private static final int Y_SAME = 5;
	private static final int X_POSITIVE = 4;
	private static final int Y_POSITIVE = 5;

	private int numberOfContours;
	private int[] endPtsOfContours;
	private int[] instructions;
	private int[] flags;
	private int[] xCoordinates, yCoordinates;
	private boolean[] onCurve;
	private GeneralPath shape;

	public SimpleGlyph(int numberOfContours) {
		this.numberOfContours = numberOfContours;
		this.endPtsOfContours = new int[numberOfContours];
	}

	public String getType() {
		return "Simple Glyph";
	}

	public void read(TTFInput ttf) throws IOException {
		// read the xMax,yMax,xMin,YMin
		super.read(ttf);

		// read Array of last points of each contour
		for (int i = 0; i < endPtsOfContours.length; i++) {
			endPtsOfContours[i] = ttf.readUShort();
		}
		// read the number of instructions and allocate memory for them
		instructions = new int[ttf.readUShort()];
		// read all the instructions
		for (int i = 0; i < instructions.length; i++) {
			instructions[i] = ttf.readByte();
		}

		int numberOfPoints = endPtsOfContours[endPtsOfContours.length - 1] + 1;
		// allocate memory for flags, xCoordinates[], yCoordinates[]
		flags = new int[numberOfPoints];
		xCoordinates = new int[numberOfPoints];
		yCoordinates = new int[numberOfPoints];
		onCurve = new boolean[numberOfPoints];
		// if should be repeted than return allways the last byte of
		// repeatCountTimes
		int repeatCount = 0;
		int repeatFlag = 0;
		// read the flags
		for (int i = 0; i < numberOfPoints; i++) {
			// if repeatCount was seted than return the same byte and 
			// decrementthe number of repeats
			if (repeatCount > 0) {
				flags[i] = repeatFlag;
				repeatCount--;
			} else {
				// read the flag
				flags[i] = ttf.readRawByte();
				// if repeat is seted than read how many times
				if (TTFInput.flagBit(flags[i], REPEAT_FLAG)) {
					repeatCount = ttf.readByte();
					repeatFlag = flags[i];
				}
			}
			TTFInput.checkZeroBit(flags[i], 6, "flags");
			TTFInput.checkZeroBit(flags[i], 7, "flags");
			onCurve[i] = TTFInput.flagBit(flags[i], ON_CURVE);
		}

		int last = 0;
		// read xCoordinates
		for (int i = 0; i < numberOfPoints; i++) {
			if (TTFInput.flagBit(flags[i], X_SHORT)) {
				if (TTFInput.flagBit(flags[i], X_POSITIVE)) {
					last = xCoordinates[i] = last + ttf.readByte();
				} else {
					last = xCoordinates[i] = last - ttf.readByte();
				}
			} else {
				if (TTFInput.flagBit(flags[i], X_SAME)) {
					last = xCoordinates[i] = last;
				} else {
					last = xCoordinates[i] = last + ttf.readShort();
				}
			}
		}

		last = 0;
		// read yCoordinates
		for (int i = 0; i < numberOfPoints; i++) {
			if (TTFInput.flagBit(flags[i], Y_SHORT)) {
				if (TTFInput.flagBit(flags[i], Y_POSITIVE)) {
					last = yCoordinates[i] = last + ttf.readByte();
				} else {
					last = yCoordinates[i] = last - ttf.readByte();
				}
			} else {
				if (TTFInput.flagBit(flags[i], Y_SAME)) {
					last = yCoordinates[i] = last;
				} else {
					last = yCoordinates[i] = last + ttf.readShort();
				}
			}
		}
	}

	public String toString() {
		String str = super.toString() + ", " + numberOfContours + " contours, endPts={";
		for (int i = 0; i < numberOfContours; i++)
			str += (i == 0 ? "" : ",") + endPtsOfContours[i];
		str += "}, " + instructions.length + " instructions";
		return str;
	}

	public String toDetailedString() {
		String str = toString() + "\n  instructions = {";
		for (int i = 0; i < instructions.length; i++) {
			str += Integer.toHexString(instructions[i]) + " ";
		}
		return str + "}";
	}

	public GeneralPath getShape() {
		if (shape != null) {
			return shape;
		}

		shape = new GeneralPath(GeneralPath.WIND_NON_ZERO);
		int p = 0;
		int x = 0;
		int y = 0;
		for (int i = 0; i < endPtsOfContours.length; i++) {
			boolean first = true;
			while (p <= endPtsOfContours[i]) {
				x = xCoordinates[p];
				y = yCoordinates[p];
				//System.out.print(p+": ("+x+","+y+")");
				if (first) {
					shape.moveTo(x, y);
					//System.out.println(" m");
					if (!onCurve[p])
						System.err.println("First point of contour not on curve!");
				} else if (onCurve[p]) {
					shape.lineTo(x, y);
					//System.out.println(" l");
				} else {
					int pIndex = 0;
					// when we are at the end of a contour
					if (p == endPtsOfContours[i])
						// look for the endpoint of the curve at the beginning
						if (i > 0)
							pIndex = endPtsOfContours[i - 1] + 1;
						else
							pIndex = 0;
					else
						pIndex = ++p; // else take the next point
					int x1 = xCoordinates[pIndex];
					int y1 = yCoordinates[pIndex];
					//System.out.print("("+x1+","+y1+")");
					if (onCurve[p]) {
						shape.quadTo(x, y, x1, y1);
						//System.out.println(" q");
					} else {
						if (p == endPtsOfContours[i])
							if (i > 0)
								pIndex = endPtsOfContours[i - 1] + 1;
							else
								pIndex = 0;
						else
							pIndex = ++p;
						int x2 = xCoordinates[pIndex];
						int y2 = yCoordinates[pIndex];
						//System.out.println("("+y2+","+y2+") c");
						shape.curveTo(x, y, x1, y1, x2, y2);

						// FIXME: Find out how to construct a cubic or quadratic 
						// Bezier curve from a Bezier spline with an arbitrary number
						// of off-curve points
						if (!onCurve[p])
							System.err.println("Three points in a row not on curve!");
					}
				}
				first = false;
				p++;
			}
			shape.closePath();
			//System.out.println(".");
		}
		return shape;
	}

}

⌨️ 快捷键说明

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