------------------------------------------------
Found it: DrawingWindow.onKeyDown appends every key-down event to the label, including Shift, whose getUnicodeChar() returns 0 and gets inserted as \0 before capitals—explaining the \0T\0B\0C\0M pattern and why it's label-only, not a UTF-16 issue. Now checking the load path too.
Ran 1 shell command
Now the fix. I'll skip non-printing key events, and also remove existing NULs when a .tdr is loaded so sketches that are already affected get cleaned up.
● Update(src/com/topodroid/TDX/DrawingWindow.java)
Added 1 line, removed 2 lines
if ( mLabelPath != null ) {
int code_point = ev.getUnicodeChar();
// TDLog.v("key event unicode " + code_point );
- // TODO suppress invalid characters
if ( code == KeyEvent.KEYCODE_DEL ) {
mLabelPath.delTextChar( );
- } else {
+ } else if ( code_point > 0 && ! Character.isISOControl( code_point ) ) { // skip non-printing key
s (eg, SHIFT gives 0), and dead keys (COMBINING_ACCENT flag makes it negative)
mLabelPath.addTextChar( Character.toChars( code_point ) );
}
// mDrawingSurface.setBackgroundColor( 0 ); // this makes grey for all modes
● Update(src/com/topodroid/TDX/DrawingLabelPath.java)
Added 1 line, removed 1 line
scale = dis.readInt( );
if ( version > 401090 ) level = dis.readInt();
if ( version > 401160 ) scrap = dis.readInt();
- text = dis.readUTF();
+ text = dis.readUTF().replace( "\u0000", "" ); // drop NUL chars stored by older versions
options = dis.readUTF();
// TDLog.Log( TDLog.LOG_PLOT, "Label <" + text + " " + ccx + " " + ccy + " scale " + scale + " (" + op
tions + ")" );
Ran 1 shell command
I found the bug and fixed it. The UTF-16 explanation turned out to be wrong: TopoDroid is adding the NULs itself when you type a label directly on the sketch. I haven't compiled or tested the change on a device.
Cause: DrawingWindow.onKeyDown (src/com/topodroid/TDX/DrawingWindow.java:8921) appends every key-down event to the label being typed, with no filter (there was even a // TODO suppress invalid characters there). Pressing Shift is a key-down event of its own, and ev.getUnicodeChar() returns 0 for it. So Character.toChars(0) added a \0 before each capital letter. Typing "TBCM" with Shift gives exactly \0T\0B\0C\0M.
This is why only labels are affected: this typing path is used only by DrawingLabelPath. The .th2 writer and escapeQuotes just write out whatever text they're given.
The same unfiltered call also had a second, latent bug. Dead keys (accent keys) return a negative value with the COMBINING_ACCENT flag set, and Character.toChars() throws an IllegalArgumentException on that.
What I changed:
1. DrawingWindow.java: a key's character is now appended only if it is greater than 0 and is not a control character. This skips Shift, Ctrl and similar keys, and dead keys. Delete still works as before.
2. DrawingLabelPath.java:98: NUL characters are removed from label text when a .tdr sketch is loaded. Sketches saved by 6.5.22 and earlier then export clean .th2 files the next time they're saved.