import java.util.*; import java.awt.*; public class DemoApplet extends BufferedApplet { int W = 0, H; Font font = new Font("Courier", Font.BOLD, 20); Font smallFont = new Font("Courier", Font.BOLD, 14); int shiftState = 0; boolean control = false; Color c0 = new Color(0,192,0); Color c1 = new Color(255,192,0); Color c2 = new Color(255,0,0); AlphaDraw z = new AlphaDraw(); Graphics g; TextEditor text = new TextEditor(); int px, py, pr; public void render(Graphics g) { this.g = g; if (W == 0) { W = bounds().width; H = bounds().height; text.setBounds(W, H); text.enterText("Now is the time\n"); text.enterText("for all good men\n"); text.enterText("to come to the aid\n"); text.enterText("of their party.\n"); px = 11*W/16; py = 11*H/16; pr = W/4; } g.setColor(Color.white); g.fillRect(0,0,W,H); drawPattern(g, px, py, pr); if (pattern != null) drawPattern(g); drawSquiggle(xy, n, false); g.setFont(font); text.render(g); } void drawSquiggle(int xy[], int n, boolean isArrow) { if (n > 2) { g.setColor(Color.black); double Dx = xy[2]-xy[0], Dy = xy[3]-xy[1]; for (int i = 0 ; i < n-2 ; i += 2) { g.drawLine(xy[i],xy[i+1],xy[i+2],xy[i+3]); if (isArrow) { Dx = .5 * Dx + .5 * (xy[i+2] - xy[i ]); Dy = .5 * Dy + .5 * (xy[i+3] - xy[i+1]); if (i == n-4) { double R = Math.sqrt(Dx*Dx + Dy*Dy); int dx = (int)(8 * Dx / R); int dy = (int)(8 * Dy / R); g.drawLine(xy[i]+dy, xy[i+1]-dx, xy[i+2], xy[i+3]); g.drawLine(xy[i]-dy, xy[i+1]+dx, xy[i+2], xy[i+3]); } } } } } int xy[] = new int[1000]; int n = 0; boolean isSelecting = false; int xDown, yDown; public boolean mouseDown(Event e, int x, int y) { n = 0; if (text.isOverText(x,y)) { isSelecting = true; xDown = x; yDown = y; text.select(xDown, yDown, x, y); } else { isSelecting = false; xy[n++] = x; xy[n++] = y; } pattern = null; damage = true; return true; } public boolean mouseDrag(Event e, int x, int y) { if (isSelecting) { text.select(xDown, yDown, x, y); } else { xy[n++] = x; xy[n++] = y; } damage = true; return true; } public boolean mouseUp(Event e, int x, int y) { int c = 0; if (isSelecting) { if (! text.hasSelection()) text.placeCursor(xDown,yDown); isSelecting = false; n = 0; damage = true; return true; } xy[n++] = x; xy[n++] = y; if (n >= 6) { c = z.recognize(xy, n); if (control) c = c - ('a'-1); control = false; } switch (c) { case -1: // DO NOTHING break; case 0: // TOGGLE NUMERIC KEYPAD z.toggleNumeric(); break; case AlphaDraw.SHIFT: // SHIFT shiftState = (shiftState + 1) % 3; break; case AlphaDraw.CNTRL: // CONTROL control = true; break; case 'C' - '@': // CONTROL C text.copy(); break; case 'V' - '@': // CONTROL V text.paste(); break; case 'X' - '@': // CONTROL X text.cut(); break; case AlphaDraw.SEND: // SEND System.out.println("SEND"); break; case AlphaDraw.END: // END System.out.println("END"); break; default: if (c == '\b' && text.hasSelection()) text.cut(); else enterTextChar(c); break; } n = 0; damage = true; return true; } void enterTextChar(int c) { text.enterText("" + (char)(shiftState != 0 ? z.shift(c) : c)); if (shiftState == 1) shiftState = 0; damage = true; } public boolean keyUp(Event e, int key) { switch (key) { case 'N'-'@': // CONTROL-N z.toggleHasNumbers(); damage = true; break; default: simulateTextChar(key); break; } return true; } double[] pattern = null; void simulateTextChar(int c) { pattern = z.getPattern("" + (char)c); System.out.println("pattern = " + pattern); enterTextChar(c); } Random R = new Random(); int pxy[] = new int[1000]; void drawPattern(Graphics g) { int n = pattern.length / 2; double x = 0, y = 0; for (int i = 0 ; i < n ; i++) { pxy[2*i ] = (int)(px - pr/4 + pr/2 * pattern[i ] + x); pxy[2*i+1] = (int)(py - pr/4 + pr/2 * pattern[i+n] + y); x += .02 * (R.nextInt() % 100); y += .02 * (R.nextInt() % 100); } drawSquiggle(pxy, 2 * n, true); } Color patternTextColor = new Color(128,160,255); Color patternLineColor = new Color(160,200,255); void drawPattern(Graphics g, int x, int y, int r) { int J[] = { 1,0,-1, 1,0,-1, 1,-1}; int K[] = { 0,0, 0, 1,1, 1, 2, 2}; double p[] = { 0,8,-1.5,8 , 0,6, 0,8 , 0,8, 1.5,8 , 0,8,-1.5,6.5, 0,8, 0,6.5, 0,8, 1.5,6.5, -1,7,-1,5.5, 1,7,1,5.5, }; for (int i = 0 ; i < 8 ; i++) { double theta = Math.PI * (5 - i) / 4; double cos = r * Math.cos(theta), sin = r * Math.sin(theta); int x0 = 0, y0 = 0; for (int m = 0 ; m < p.length ; m += 2) { int x1 = x + (int)( cos * p[m] + sin * p[m+1]) / 8; int y1 = y + (int)(-sin * p[m] + cos * p[m+1]) / 8; if (m % 4 == 2) { if (K[m/4] < 2) { g.setColor(patternLineColor); g.drawLine(x0,y0, x1,y1); g.setColor(patternTextColor); } else g.setColor(patternLineColor); int c = z.map(i, J[m/4], K[m/4]); if (c == '?') continue; if (shiftState != 0) c = z.shift(c); String s = "" + (char)c; Font f = smallFont; switch (c) { case AlphaDraw.SHIFT: switch (shiftState) { case 0: s = "CAP"; break; case 1: s = "SL"; break; case 2: s = "SD"; break; } break; case 'C'-'@': s = "COPY";break; case 'V'-'@': s = "PASTE";break; case 'X'-'@': s = "CUT";break; case 27 : s = "ESC";break; case ' ' : s = "SP"; break; case '\b' : s = "BS"; break; case '\t' : s = "TAB";break; case '\n' : s = "NL"; break; case 1004 : s = "UA"; break; case 1005 : s = "DA"; break; case 1006 : s = "LA"; break; case 1007 : s = "RA"; break; case AlphaDraw.SEND : s = "SND";break; case AlphaDraw.END : s = "END";break; case AlphaDraw.CNTRL: s = "CTL";break; default: f = font; break; } g.setFont(f); g.drawString(s, x1 - text.stringWidth(g,s)/2, y1+5); } x0 = x1; y0 = y1; } } } }