public TestType1CFont(InputStream is) throws IOException { super(); setPreferredSize(new Dimension(800, 800)); addKeyListener(this); BufferedInputStream bis = new BufferedInputStream(is); int count = 0; ArrayList<byte[]> al = new ArrayList<byte[]>(); byte b[] = new byte[32000]; int len; while ((len = bis.read(b, 0, b.length)) >= 0) { byte[] c = new byte[len]; System.arraycopy(b, 0, c, 0, len); al.add(c); count += len; b = new byte[32000]; } data = new byte[count]; len = 0; for (int i = 0; i < al.size(); i++) { byte from[] = al.get(i); System.arraycopy(from, 0, data, len, from.length); len += from.length; } pos = 0; // printData(); parse(); // TODO: free up (set to null) unused structures (data, subrs, stack) }
void enlargeArrays() { if (xp != null) { int[] xptemp = new int[maxPoints * 2]; int[] yptemp = new int[maxPoints * 2]; System.arraycopy(xp, 0, xptemp, 0, maxPoints); System.arraycopy(yp, 0, yptemp, 0, maxPoints); xp = xptemp; yp = yptemp; } if (xpf != null) { float[] xpftemp = new float[maxPoints * 2]; float[] ypftemp = new float[maxPoints * 2]; System.arraycopy(xpf, 0, xpftemp, 0, maxPoints); System.arraycopy(ypf, 0, ypftemp, 0, maxPoints); xpf = xpftemp; ypf = ypftemp; } int[] xp2temp = new int[maxPoints * 2]; int[] yp2temp = new int[maxPoints * 2]; System.arraycopy(xp2, 0, xp2temp, 0, maxPoints); System.arraycopy(yp2, 0, yp2temp, 0, maxPoints); xp2 = xp2temp; yp2 = yp2temp; if (IJ.debugMode) IJ.log("PolygonRoi: " + maxPoints + " points"); maxPoints *= 2; }
public void parseGlyph(Range r, GlyphData gp, FlPoint pt) { pos = r.getStart(); int i; float x1, y1, x2, y2, x3, y3, ybase; int hold; int stemhints = 0; gp.setAdvance(defaultWidthX); while (pos < r.getEnd()) { int cmd = readCommand(true); hold = 0; switch (cmd) { case 1: // hstem case 3: // vstem if ((stackptr & 1) == 1) { gp.setAdvance(nominalWidthX + stack[0]); } stackptr = 0; break; case 4: // vmoveto if (stackptr > 1) { // this is the first call, arg1 is width gp.setAdvance(nominalWidthX + stack[0]); stack[0] = stack[1]; } pt.y += stack[0]; if (pt.open) { gp.closePath(); } pt.open = false; gp.moveTo(pt.x, pt.y); stackptr = 0; break; case 5: // rlineto for (i = 0; i < stackptr; ) { pt.x += stack[i++]; pt.y += stack[i++]; gp.lineTo(pt.x, pt.y); } pt.open = true; stackptr = 0; break; case 6: // hlineto for (i = 0; i < stackptr; ) { if ((i & 1) == 0) { pt.x += stack[i++]; } else { pt.y += stack[i++]; } gp.lineTo(pt.x, pt.y); } pt.open = true; stackptr = 0; break; case 7: // vlineto for (i = 0; i < stackptr; ) { if ((i & 1) == 0) { pt.y += stack[i++]; } else { pt.x += stack[i++]; } gp.lineTo(pt.x, pt.y); } pt.open = true; stackptr = 0; break; case 8: // rrcurveto for (i = 0; i < stackptr; ) { x1 = pt.x + stack[i++]; y1 = pt.y + stack[i++]; x2 = x1 + stack[i++]; y2 = y1 + stack[i++]; pt.x = x2 + stack[i++]; pt.y = y2 + stack[i++]; gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); } pt.open = true; stackptr = 0; break; case 10: // callsubr hold = pos; i = (int) stack[--stackptr] + lsubrsoffset; Range lsubr = getIndexEntry(lsubrbase, i); parseGlyph(lsubr, gp, pt); pos = hold; break; case 11: // return return; case 14: // endchar if (stackptr == 5) { buildAccentChar(stack[1], stack[2], stack[3], stack[4], gp); } if (pt.open) { gp.closePath(); } pt.open = false; stackptr = 0; return; case 18: // hstemhm if ((stackptr & 1) == 1) { gp.setAdvance(nominalWidthX + stack[0]); } stemhints += stackptr / 2; stackptr = 0; break; case 19: // hintmask case 20: // cntrmask if ((stackptr & 1) == 1) { gp.setAdvance(nominalWidthX + stack[0]); } stemhints += stackptr / 2; System.out.println( "Added " + stackptr + " extra bits; skipping " + ((stemhints - 1) / 8 + 1) + " from " + stemhints); pos += (stemhints - 1) / 8 + 1; stackptr = 0; break; case 21: // rmoveto if (stackptr > 2) { gp.setAdvance(nominalWidthX + stack[0]); stack[0] = stack[1]; stack[1] = stack[2]; } pt.x += stack[0]; pt.y += stack[1]; if (pt.open) { gp.closePath(); } gp.moveTo(pt.x, pt.y); pt.open = false; stackptr = 0; break; case 22: // hmoveto if (stackptr > 1) { gp.setAdvance(nominalWidthX + stack[0]); stack[0] = stack[1]; } pt.x += stack[0]; if (pt.open) { gp.closePath(); } gp.moveTo(pt.x, pt.y); pt.open = false; stackptr = 0; break; case 23: // vstemhm if ((stackptr & 1) == 1) { gp.setAdvance(nominalWidthX + stack[0]); } stemhints += stackptr / 2; stackptr = 0; break; case 24: // rcurveline for (i = 0; i < stackptr - 2; ) { x1 = pt.x + stack[i++]; y1 = pt.y + stack[i++]; x2 = x1 + stack[i++]; y2 = y1 + stack[i++]; pt.x = x2 + stack[i++]; pt.y = y2 + stack[i++]; gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); } pt.x += stack[i++]; pt.y += stack[i++]; gp.lineTo(pt.x, pt.y); pt.open = true; stackptr = 0; break; case 25: // rlinecurve for (i = 0; i < stackptr - 6; ) { pt.x += stack[i++]; pt.y += stack[i++]; gp.lineTo(pt.x, pt.y); } x1 = pt.x + stack[i++]; y1 = pt.y + stack[i++]; x2 = x1 + stack[i++]; y2 = y1 + stack[i++]; pt.x = x2 + stack[i++]; pt.y = y2 + stack[i++]; gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); pt.open = true; stackptr = 0; break; case 26: // vvcurveto i = 0; if ((stackptr & 1) == 1) { // odd number of arguments pt.x += stack[i++]; } while (i < stackptr) { x1 = pt.x; y1 = pt.y + stack[i++]; x2 = x1 + stack[i++]; y2 = y1 + stack[i++]; pt.x = x2; pt.y = y2 + stack[i++]; gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); } pt.open = true; stackptr = 0; break; case 27: // hhcurveto i = 0; if ((stackptr & 1) == 1) { // odd number of arguments pt.y += stack[i++]; } while (i < stackptr) { x1 = pt.x + stack[i++]; y1 = pt.y; x2 = x1 + stack[i++]; y2 = y1 + stack[i++]; pt.x = x2 + stack[i++]; pt.y = y2; gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); } pt.open = true; stackptr = 0; break; case 29: // callgsubr hold = pos; i = (int) stack[--stackptr] + gsubrsoffset; Range gsubr = getIndexEntry(gsubrbase, i); parseGlyph(gsubr, gp, pt); pos = hold; break; case 30: // vhcurveto hold = 4; case 31: // hvcurveto for (i = 0; i < stackptr; ) { boolean hv = (((i + hold) & 4) == 0); x1 = pt.x + (hv ? stack[i++] : 0); y1 = pt.y + (hv ? 0 : stack[i++]); x2 = x1 + stack[i++]; y2 = y1 + stack[i++]; pt.x = x2 + (hv ? 0 : stack[i++]); pt.y = y2 + (hv ? stack[i++] : 0); if (i == stackptr - 1) { if (hv) { pt.x += stack[i++]; } else { pt.y += stack[i++]; } } gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); } pt.open = true; stackptr = 0; break; case 1003: // and x1 = stack[--stackptr]; y1 = stack[--stackptr]; stack[stackptr++] = ((x1 != 0) && (y1 != 0)) ? 1 : 0; break; case 1004: // or x1 = stack[--stackptr]; y1 = stack[--stackptr]; stack[stackptr++] = ((x1 != 0) || (y1 != 0)) ? 1 : 0; break; case 1005: // not x1 = stack[--stackptr]; stack[stackptr++] = (x1 == 0) ? 1 : 0; break; case 1009: // abs stack[stackptr - 1] = Math.abs(stack[stackptr - 1]); break; case 1010: // add x1 = stack[--stackptr]; y1 = stack[--stackptr]; stack[stackptr++] = x1 + y1; break; case 1011: // sub x1 = stack[--stackptr]; y1 = stack[--stackptr]; stack[stackptr++] = y1 - x1; break; case 1012: // div x1 = stack[--stackptr]; y1 = stack[--stackptr]; stack[stackptr++] = y1 / x1; break; case 1014: // neg stack[stackptr - 1] = -stack[stackptr - 1]; break; case 1015: // eq x1 = stack[--stackptr]; y1 = stack[--stackptr]; stack[stackptr++] = (x1 == y1) ? 1 : 0; break; case 1018: // drop stackptr--; break; case 1020: // put i = (int) stack[--stackptr]; x1 = stack[--stackptr]; temps[i] = x1; break; case 1021: // get i = (int) stack[--stackptr]; stack[stackptr++] = temps[i]; break; case 1022: // ifelse if (stack[stackptr - 2] > stack[stackptr - 1]) { stack[stackptr - 4] = stack[stackptr - 3]; } stackptr -= 3; break; case 1023: // random stack[stackptr++] = (float) Math.random(); break; case 1024: // mul x1 = stack[--stackptr]; y1 = stack[--stackptr]; stack[stackptr++] = y1 * x1; break; case 1026: // sqrt stack[stackptr - 1] = (float) Math.sqrt(stack[stackptr - 1]); break; case 1027: // dup x1 = stack[stackptr - 1]; stack[stackptr++] = x1; break; case 1028: // exch x1 = stack[stackptr - 1]; stack[stackptr - 1] = stack[stackptr - 2]; stack[stackptr - 2] = x1; break; case 1029: // index i = (int) stack[stackptr - 1]; if (i < 0) { i = 0; } stack[stackptr - 1] = stack[stackptr - 2 - i]; break; case 1030: // roll i = (int) stack[--stackptr]; int n = (int) stack[--stackptr]; // roll n number by i (+ = upward) if (i > 0) { i = i % n; } else { i = n - (-i % n); } // x x x x i y y y -> y y y x x x x i (where i=3) if (i > 0) { float roll[] = new float[n]; System.arraycopy(stack, stackptr - 1 - i, roll, 0, i); System.arraycopy(stack, stackptr - 1 - n, roll, i, n - i); System.arraycopy(roll, 0, stack, stackptr - 1 - n, n); } break; case 1034: // hflex x1 = pt.x + stack[0]; y1 = ybase = pt.y; x2 = x1 + stack[1]; y2 = y1 + stack[2]; pt.x = x2 + stack[3]; pt.y = y2; gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); x1 = pt.x + stack[4]; y1 = pt.y; x2 = x1 + stack[5]; y2 = ybase; pt.x = x2 + stack[6]; pt.y = y2; gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); pt.open = true; stackptr = 0; break; case 1035: // flex x1 = pt.x + stack[0]; y1 = pt.y + stack[1]; x2 = x1 + stack[2]; y2 = y1 + stack[3]; pt.x = x2 + stack[4]; pt.y = y2 + stack[5]; gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); x1 = pt.x + stack[6]; y1 = pt.y + stack[7]; x2 = x1 + stack[8]; y2 = y1 + stack[9]; pt.x = x2 + stack[10]; pt.y = y2 + stack[11]; gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); pt.open = true; stackptr = 0; break; case 1036: // hflex1 ybase = pt.y; x1 = pt.x + stack[0]; y1 = pt.y + stack[1]; x2 = x1 + stack[2]; y2 = y1 + stack[3]; pt.x = x2 + stack[4]; pt.y = y2; gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); x1 = pt.x + stack[5]; y1 = pt.y; x2 = x1 + stack[6]; y2 = y1 + stack[7]; pt.x = x2 + stack[8]; pt.y = ybase; gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); pt.open = true; stackptr = 0; break; case 1037: // flex1 ybase = pt.y; float xbase = pt.x; x1 = pt.x + stack[0]; y1 = pt.y + stack[1]; x2 = x1 + stack[2]; y2 = y1 + stack[3]; pt.x = x2 + stack[4]; pt.y = y2 + stack[5]; gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); x1 = pt.x + stack[6]; y1 = pt.y + stack[7]; x2 = x1 + stack[8]; y2 = y1 + stack[9]; if (Math.abs(x2 - xbase) > Math.abs(y2 - ybase)) { pt.x = x2 + stack[10]; pt.y = ybase; } else { pt.x = xbase; pt.y = y2 + stack[10]; } gp.curveTo(x1, y1, x2, y2, pt.x, pt.y); pt.open = true; stackptr = 0; break; default: System.out.println("ERROR! TYPE1C CHARSTRING CMD IS " + cmd); break; } } }
public void vertex(float x, float y) { curveVertexCount = 0; // float vertex[]; if (vertexCount == vertices.length) { float temp[][] = new float[vertexCount << 1][VERTEX_FIELD_COUNT]; System.arraycopy(vertices, 0, temp, 0, vertexCount); vertices = temp; // message(CHATTER, "allocating more vertices " + vertices.length); } // not everyone needs this, but just easier to store rather // than adding another moving part to the code... vertices[vertexCount][X] = x; vertices[vertexCount][Y] = y; vertexCount++; switch (shape) { case POINTS: point(x, y); break; case LINES: if ((vertexCount % 2) == 0) { line(vertices[vertexCount - 2][X], vertices[vertexCount - 2][Y], x, y); } break; case TRIANGLES: if ((vertexCount % 3) == 0) { triangle( vertices[vertexCount - 3][X], vertices[vertexCount - 3][Y], vertices[vertexCount - 2][X], vertices[vertexCount - 2][Y], x, y); } break; case TRIANGLE_STRIP: if (vertexCount >= 3) { triangle( vertices[vertexCount - 2][X], vertices[vertexCount - 2][Y], vertices[vertexCount - 1][X], vertices[vertexCount - 1][Y], vertices[vertexCount - 3][X], vertices[vertexCount - 3][Y]); } break; case TRIANGLE_FAN: if (vertexCount == 3) { triangle(vertices[0][X], vertices[0][Y], vertices[1][X], vertices[1][Y], x, y); } else if (vertexCount > 3) { gpath = new GeneralPath(); // when vertexCount > 3, draw an un-closed triangle // for indices 0 (center), previous, current gpath.moveTo(vertices[0][X], vertices[0][Y]); gpath.lineTo(vertices[vertexCount - 2][X], vertices[vertexCount - 2][Y]); gpath.lineTo(x, y); drawShape(gpath); } break; case QUADS: if ((vertexCount % 4) == 0) { quad( vertices[vertexCount - 4][X], vertices[vertexCount - 4][Y], vertices[vertexCount - 3][X], vertices[vertexCount - 3][Y], vertices[vertexCount - 2][X], vertices[vertexCount - 2][Y], x, y); } break; case QUAD_STRIP: // 0---2---4 // | | | // 1---3---5 if ((vertexCount >= 4) && ((vertexCount % 2) == 0)) { quad( vertices[vertexCount - 4][X], vertices[vertexCount - 4][Y], vertices[vertexCount - 2][X], vertices[vertexCount - 2][Y], x, y, vertices[vertexCount - 3][X], vertices[vertexCount - 3][Y]); } break; case POLYGON: if (gpath == null) { gpath = new GeneralPath(); gpath.moveTo(x, y); } else if (breakShape) { gpath.moveTo(x, y); breakShape = false; } else { gpath.lineTo(x, y); } break; } }