diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/de/mud/terminal/VDUBuffer.java | 16 | ||||
| -rw-r--r-- | src/de/mud/terminal/vt320.java | 67 | ||||
| -rw-r--r-- | src/org/connectbot/TerminalView.java | 10 | ||||
| -rw-r--r-- | src/org/connectbot/service/Relay.java | 12 | ||||
| -rw-r--r-- | src/org/connectbot/service/TerminalBridge.java | 28 | 
5 files changed, 107 insertions, 26 deletions
diff --git a/src/de/mud/terminal/VDUBuffer.java b/src/de/mud/terminal/VDUBuffer.java index 0f5fda6..93e3ccf 100644 --- a/src/de/mud/terminal/VDUBuffer.java +++ b/src/de/mud/terminal/VDUBuffer.java @@ -65,6 +65,20 @@ public class VDUBuffer {    /** Scroll down when inserting a line. */    public final static boolean SCROLL_DOWN = true; +  /*  Attributes bit-field usage: +   * +   *  8421 8421 8421 8421 8421 8421 8421 8421 +   *  |||| |||| |||| |||| |||| |||| |||| |||`- Bold +   *  |||| |||| |||| |||| |||| |||| |||| ||`-- Underline +   *  |||| |||| |||| |||| |||| |||| |||| |`--- Invert +   *  |||| |||| |||| |||| |||| |||| |||| `---- Low +   *  |||| |||| |||| |||| |||| |||| |||`------ Invisible +   *  |||| |||| |||| |||| ||`+-++++-+++------- Foreground Color +   *  |||| |||| |`++-++++-++------------------ Background Color +   *  |||| |||| `----------------------------- Fullwidth character +   *  `+++-++++------------------------------- Reserved for future use +   */ +    /** Make character normal. */    public final static int NORMAL = 0x00;    /** Make character bold. */ @@ -77,6 +91,8 @@ public class VDUBuffer {    public final static int LOW = 0x08;    /** Invisible character. */    public final static int INVISIBLE = 0x10; +  /** Unicode full-width character (CJK, et al.) */ +  public final static int FULLWIDTH = 0x8000000;    /** how much to left shift the foreground color */    public final static int COLOR_FG_SHIFT = 5; diff --git a/src/de/mud/terminal/vt320.java b/src/de/mud/terminal/vt320.java index f628cd4..729b6de 100644 --- a/src/de/mud/terminal/vt320.java +++ b/src/de/mud/terminal/vt320.java @@ -72,10 +72,10 @@ public abstract class vt320 extends VDUBuffer implements VDUInput {     * Convenience function for putString(char[], int, int)     */    public void putString(String s) { -	int len = s.length(); -	char[] tmp = new char[len]; -	s.getChars(0, len, tmp, 0); -	putString(tmp, 0, len); +    int len = s.length(); +    char[] tmp = new char[len]; +    s.getChars(0, len, tmp, 0); +    putString(tmp, null, 0, len);    }    /** @@ -85,36 +85,40 @@ public abstract class vt320 extends VDUBuffer implements VDUInput {     * @param start place to start in array     * @param len number of characters to process     */ -  public void putString(char[] s, int start, int len) { +  public void putString(char[] s, boolean[] fullwidths, int start, int len) {      if (len > 0) {        //markLine(R, 1);        int lastChar = -1;        char c; +      boolean isWide = false;        for (int i = 0; i < len; i++) {          c = s[start + i];          // Shortcut for my favorite ASCII          if (c <= 0x7F) {            if (lastChar != -1) -            putChar((char) lastChar, false); +            putChar((char) lastChar, isWide, false);            lastChar = c; +          isWide = false;          } else if (!Character.isLowSurrogate(c) && !Character.isHighSurrogate(c)) {            if (Character.getType(c) == Character.NON_SPACING_MARK) {              if (lastChar != -1) {                char nc = Precomposer.precompose((char) lastChar, c); -              putChar(nc, false); +              putChar(nc, isWide, false);                lastChar = -1;              }            } else { -          if (lastChar != -1) -              putChar((char) lastChar, false); +            if (lastChar != -1) +              putChar((char) lastChar, isWide, false);              lastChar = c; +            if (fullwidths != null) +                isWide = fullwidths[i];            }          }        }        if (lastChar != -1) -        putChar((char) lastChar, false); +        putChar((char) lastChar, isWide, false);        setCursorPosition(C, R);        redraw(); @@ -138,6 +142,9 @@ public void setScreenSize(int c, int r, boolean broadcast) {      //int oldcols = width;      if (debug>2) { +      if (debugStr == null) +        debugStr = new StringBuilder(); +        debugStr.append("setscreensize (")          .append(c)          .append(',') @@ -167,14 +174,15 @@ public void setScreenSize(int c, int r, boolean broadcast) {     */    public vt320(int width, int height) {      super(width, height); + +    debugStr = new StringBuilder(); +      setVMS(false);      setIBMCharset(false);      setTerminalID("vt320");      setBufferSize(100);      //setBorder(2, false); -    debugStr = new StringBuilder(); -      gx = new char[4];      reset(); @@ -548,8 +556,9 @@ public void setScreenSize(int c, int r, boolean broadcast) {      write(s); +    // TODO check if character is wide      if (doecho) -      putChar((char)s, false); +      putChar((char)s, false, false);      return true;    } @@ -1497,7 +1506,7 @@ public void setScreenSize(int c, int r, boolean broadcast) {      if (R > maxr) R = maxr;    } -  private void putChar(char c, boolean doshowcursor) { +  private void putChar(char c, boolean isWide, boolean doshowcursor) {      int rows = this.height; //statusline      int columns = this.width;      // byte msg[]; @@ -1754,9 +1763,25 @@ public void setScreenSize(int c, int r, boolean broadcast) {                /*if(true || (statusmode == 0)) { */                if (insertmode == 1) { -                insertChar(C, R, c, attributes); +                if (isWide) { +                  if (C >= columns - 1) { +                    C = 0; +                    R++; +                  } +                  insertChar(C++, R, c, attributes | FULLWIDTH); +                  insertChar(C, R, ' ', attributes | FULLWIDTH); +                } else +                  insertChar(C, R, c, attributes);                } else { -                putChar(C, R, c, attributes); +                if (isWide) { +                  if (C >= columns - 1) { +                    C = 0; +                    R++; +                  } +                  putChar(C++, R, c, attributes | FULLWIDTH); +                  putChar(C, R, ' ', attributes | FULLWIDTH); +                } else +                  putChar(C, R, c, attributes);                }                /*                  } else { @@ -2525,9 +2550,10 @@ public void setScreenSize(int c, int r, boolean broadcast) {              }            case 'C':              if (DCEvars[0] == 0) +              DCEvars[0] = 1; +            while (DCEvars[0]-- > 0) {                C++; -            else -              C += DCEvars[0]; +            }              if (C >= columns)                C = columns - 1;              if (debug > 1) @@ -2544,9 +2570,10 @@ public void setScreenSize(int c, int r, boolean broadcast) {              break;            case 'D':              if (DCEvars[0] == 0) +              DCEvars[0] = 1; +            while (DCEvars[0]-- > 0) {                C--; -            else -              C -= DCEvars[0]; +            }              if (C < 0) C = 0;              if (debug > 1)                debug("ESC [ " + DCEvars[0] + " D"); diff --git a/src/org/connectbot/TerminalView.java b/src/org/connectbot/TerminalView.java index de74f7e..5eb7e24 100644 --- a/src/org/connectbot/TerminalView.java +++ b/src/org/connectbot/TerminalView.java @@ -36,6 +36,7 @@ import android.view.inputmethod.BaseInputConnection;  import android.view.inputmethod.EditorInfo;  import android.view.inputmethod.InputConnection;  import android.widget.Toast; +import de.mud.terminal.VDUBuffer;  /**   * User interface {@link View} for showing a TerminalBridge in an @@ -148,6 +149,11 @@ public class TerminalView extends View implements FontSizeChangedListener {  			// also draw cursor if visible  			if(bridge.buffer.isCursorVisible()) { +				int currentAttribute = bridge.buffer.getAttributes( +						bridge.buffer.getCursorColumn(), +						bridge.buffer.getCursorRow()); +				boolean onWideCharacter = (currentAttribute & VDUBuffer.FULLWIDTH) != 0; +  				int x = bridge.buffer.getCursorColumn() * bridge.charWidth;  				int y = (bridge.buffer.getCursorRow()  						+ bridge.buffer.screenBase - bridge.buffer.windowBase) @@ -157,7 +163,9 @@ public class TerminalView extends View implements FontSizeChangedListener {  				canvas.save();  				canvas.translate(x, y); -				canvas.clipRect(0, 0, bridge.charWidth, bridge.charHeight); +				canvas.clipRect(0, 0, +						bridge.charWidth * (onWideCharacter ? 2 : 1), +						bridge.charHeight);  				canvas.drawPaint(cursorPaint);  				// Make sure we scale our decorations to the correct size. diff --git a/src/org/connectbot/service/Relay.java b/src/org/connectbot/service/Relay.java index 746a915..22b8299 100644 --- a/src/org/connectbot/service/Relay.java +++ b/src/org/connectbot/service/Relay.java @@ -92,6 +92,9 @@ public class Relay implements Runnable {  		byteBuffer = ByteBuffer.allocate(BUFFER_SIZE);  		charBuffer = CharBuffer.allocate(BUFFER_SIZE); +		float[] widths = new float[BUFFER_SIZE]; +		boolean[] fullwidths = new boolean[BUFFER_SIZE]; +  		byteArray = byteBuffer.array();  		charArray = charBuffer.array(); @@ -101,9 +104,11 @@ public class Relay implements Runnable {  		byteBuffer.limit(0);  		int bytesToRead;  		int offset; +		int charWidth;  		try {  			while (true) { +				charWidth = bridge.charWidth;  				bytesToRead = byteBuffer.capacity() - byteBuffer.limit();  				offset = byteBuffer.arrayOffset() + byteBuffer.limit();  				bytesRead = transport.read(byteArray, offset, bytesToRead); @@ -122,7 +127,12 @@ public class Relay implements Runnable {  						byteBuffer.position(0);  					} -					buffer.putString(charArray, 0, charBuffer.position()); +					offset = charBuffer.position(); +					bridge.defaultPaint.getTextWidths(charArray, 0, offset, widths); +					for (int i = 0; i < offset; i++) +						fullwidths[i] = (int)widths[i] != charWidth; + +					buffer.putString(charArray, fullwidths, 0, charBuffer.position());  					charBuffer.clear();  					bridge.redraw();  				} diff --git a/src/org/connectbot/service/TerminalBridge.java b/src/org/connectbot/service/TerminalBridge.java index 500a821..5cb9613 100644 --- a/src/org/connectbot/service/TerminalBridge.java +++ b/src/org/connectbot/service/TerminalBridge.java @@ -80,7 +80,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {  	private AbsTransport transport; -	private final Paint defaultPaint; +	final Paint defaultPaint;  	private Relay relay; @@ -1037,6 +1037,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {  		int fg, bg;  		synchronized (buffer) {  			boolean entireDirty = buffer.update[0] || fullRedraw; +			boolean isWideCharacter = false;  			// walk through all lines in the buffer  			for(int l = 0; l < buffer.height; l++) { @@ -1080,9 +1081,16 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {  					// set underlined attributes if requested  					defaultPaint.setUnderlineText((currAttr & VDUBuffer.UNDERLINE) != 0); -					// determine the amount of continuous characters with the same settings and print them all at once -					while(c + addr < buffer.width && buffer.charAttributes[buffer.windowBase + l][c + addr] == currAttr) { +					isWideCharacter = (currAttr & VDUBuffer.FULLWIDTH) != 0; + +					if (isWideCharacter)  						addr++; +					else { +						// determine the amount of continuous characters with the same settings and print them all at once +						while(c + addr < buffer.width +								&& buffer.charAttributes[buffer.windowBase + l][c + addr] == currAttr) { +							addr++; +						}  					}  					// Save the current clip region @@ -1090,7 +1098,17 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {  					// clear this dirty area with background color  					defaultPaint.setColor(bg); -					canvas.clipRect(c * charWidth, l * charHeight, (c + addr) * charWidth, (l + 1) * charHeight); +					if (isWideCharacter) { +						canvas.clipRect(c * charWidth, +								l * charHeight, +								(c + 2) * charWidth, +								(l + 1) * charHeight); +					} else { +						canvas.clipRect(c * charWidth, +								l * charHeight, +								(c + addr) * charWidth, +								(l + 1) * charHeight); +					}  					canvas.drawPaint(defaultPaint);  					// write the text string starting at 'c' for 'addr' number of characters @@ -1105,6 +1123,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener {  					// advance to the next text block with different characteristics  					c += addr - 1; +					if (isWideCharacter) +						c++;  				}  			}  | 
