Skip to content

Commit be12523

Browse files
committed
rewrote and fixed Text.splitRawText, fixed TextInput navigation and handling
1 parent bade354 commit be12523

File tree

2 files changed

+66
-83
lines changed

2 files changed

+66
-83
lines changed

h2d/Text.hx

Lines changed: 47 additions & 62 deletions
Original file line numberDiff line numberDiff line change
@@ -114,6 +114,7 @@ class Text extends Drawable {
114114

115115
var glyphs : TileGroup;
116116
var needsRebuild : Bool;
117+
var trimTrailingSpaces : Bool = true;
117118
var currentText : String;
118119
var textChanged : Bool;
119120

@@ -324,79 +325,63 @@ class Text extends Drawable {
324325
return text;
325326
else
326327
maxWidth = Math.POSITIVE_INFINITY;
328+
} else {
329+
maxWidth -= afterData;
327330
}
328331
if ( font == null ) font = this.font;
329-
var lines = [], restPos = 0;
332+
var lines = [];
330333
var x = leftMargin;
331-
var wLastSep = 0.;
332-
for( i in 0...text.length ) {
334+
var lastPos = 0;
335+
var lastBreak = -1;
336+
var lastBreakX = 0.;
337+
338+
inline function flushLine(pos) {
339+
lines.push(text.substr(lastPos,pos-lastPos));
340+
lastPos = pos;
341+
if( sizes != null ) sizes.push(x);
342+
x = 0;
343+
prevChar = -1;
344+
lastBreak = -1;
345+
leftMargin = 0;
346+
}
347+
348+
var i = -1;
349+
var maxLen = text.length;
350+
while( ++i < maxLen ) {
333351
var cc = StringTools.fastCodeAt(text, i);
352+
if( cc == '\n'.code ) {
353+
flushLine(i);
354+
lastPos++;
355+
continue;
356+
}
357+
var startX = x;
358+
if( lastPos < i ) x += letterSpacing;
334359
var e = font.getChar(cc);
335-
var newline = cc == '\n'.code;
336360
var esize = e.width + e.getKerningOffset(prevChar);
337-
var isComplement = (i < text.length - 1 && font.charset.isComplementChar(StringTools.fastCodeAt(text, i + 1)));
338-
if( font.charset.isBreakChar(cc) && !isComplement ) {
339-
if( lines.length == 0 && leftMargin > 0 && x > maxWidth ) {
340-
lines.push("");
341-
if ( sizes != null ) sizes.push(leftMargin);
342-
x -= leftMargin;
343-
}
344-
var size = x + esize + letterSpacing; /* TODO : no letter spacing */
345-
var k = i + 1, max = text.length;
346-
var prevChar = cc;
347-
var breakFound = false;
348-
while( size <= maxWidth && k < max ) {
349-
var cc = StringTools.fastCodeAt(text, k++);
350-
if( lineBreak && (font.charset.isSpace(cc) || cc == '\n'.code ) ) {
351-
breakFound = true;
352-
break;
361+
x += esize;
362+
prevChar = cc;
363+
if( lineBreak ) {
364+
if( x > maxWidth && lastBreak >= 0 && (!trimTrailingSpaces || !font.charset.isSpace(cc) || startX > maxWidth) ) {
365+
i = lastBreak;
366+
x = lastBreakX;
367+
flushLine(i + 1);
368+
} else if( font.charset.isBreakChar(cc) && (i+1 == maxLen || !font.charset.isComplementChar(StringTools.fastCodeAt(text, i + 1))) ) {
369+
if( leftMargin > 0 && x > maxWidth ) {
370+
lines.push("");
371+
if ( sizes != null ) sizes.push(leftMargin);
372+
x -= leftMargin;
353373
}
354-
var e = font.getChar(cc);
355-
size += e.width + letterSpacing + e.getKerningOffset(prevChar);
356-
prevChar = cc;
357-
if ( font.charset.isBreakChar(cc) ) {
358-
if ( k >= text.length )
359-
break;
360-
var nc = StringTools.fastCodeAt(text, k);
361-
if ( !font.charset.isComplementChar(nc) ) break;
374+
if( x > maxWidth && (!trimTrailingSpaces || !font.charset.isSpace(cc)) ) {
375+
lastBreak = i - 1;
376+
lastBreakX = startX;
377+
} else {
378+
lastBreak = i;
379+
lastBreakX = x;
362380
}
363381
}
364-
if( lineBreak && (size > maxWidth || (!breakFound && size + afterData > maxWidth)) ) {
365-
newline = true;
366-
if( font.charset.isSpace(cc) ){
367-
lines.push(text.substr(restPos, i - restPos));
368-
e = null;
369-
}else{
370-
lines.push(text.substr(restPos, i + 1 - restPos));
371-
}
372-
restPos = i + 1;
373-
}
374-
else wLastSep = size;
375-
}
376-
else if( (x + esize + letterSpacing) - wLastSep > maxWidth && lineBreak ) {
377-
newline = true;
378-
lines.push(text.substr(restPos, i - restPos));
379-
restPos = font.charset.isSpace(cc) ? i + 1 : i;
380-
}
381-
if( e != null && cc != '\n'.code )
382-
x += esize + letterSpacing;
383-
if( newline ) {
384-
if ( sizes != null ) sizes.push(x);
385-
x = 0;
386-
wLastSep = 0.;
387-
prevChar = -1;
388-
} else
389-
prevChar = cc;
390-
}
391-
if( restPos < text.length ) {
392-
if( lines.length == 0 && leftMargin > 0 && x + afterData - letterSpacing > maxWidth ) {
393-
lines.push("");
394-
if ( sizes != null ) sizes.push(leftMargin);
395-
x -= leftMargin;
396382
}
397-
lines.push(text.substr(restPos, text.length - restPos));
398-
if ( sizes != null ) sizes.push(x);
399383
}
384+
if( x > leftMargin ) flushLine(text.length);
400385
return lines.join("\n");
401386
}
402387

h2d/TextInput.hx

Lines changed: 19 additions & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,6 @@ class TextInput extends Text {
7171
var cursorBlink = 0.;
7272
var constraintHeight = -1.;
7373
var scrollX = 0.;
74-
var selectionPos : Float;
75-
var selectionSize : Float;
7674
var undo : Array<TextHistoryElement> = [];
7775
var redo : Array<TextHistoryElement> = [];
7876
var lastChange = 0.;
@@ -88,6 +86,7 @@ class TextInput extends Text {
8886
**/
8987
public function new(font, ?parent) {
9088
super(font, parent);
89+
trimTrailingSpaces = false;
9190
interactive = new h2d.Interactive(0, 0);
9291
interactive.cursor = TextInput;
9392
interactive.onPush = function(e:hxd.Event) {
@@ -121,7 +120,6 @@ class TextInput extends Text {
121120
selectionRange = { start : index, length : startIndex - index };
122121
else
123122
selectionRange = { start : startIndex, length : index - startIndex };
124-
selectionSize = 0;
125123
cursorIndex = index;
126124
onCursorChange();
127125
if( e.kind == ERelease || getScene() != scene )
@@ -155,7 +153,6 @@ class TextInput extends Text {
155153
if( t - lastClick < 0.3 && getTextLength() != 0 ) {
156154
var start = getWordStart();
157155
selectionRange = { start : getWordStart(), length : getWordEnd() - start };
158-
selectionSize = 0;
159156
cursorIndex = selectionRange.start + selectionRange.length;
160157
}
161158
lastClick = t;
@@ -239,7 +236,7 @@ class TextInput extends Text {
239236
beforeChange();
240237
if( selectionRange == null )
241238
selectionRange = { start : cursorIndex, length : K.isDown(K.CTRL) ? getWordEnd() - cursorIndex : 1 };
242-
cutSelection();
239+
cutSelection(false);
243240
onChange();
244241
}
245242
case K.BACKSPACE:
@@ -249,7 +246,7 @@ class TextInput extends Text {
249246
var newIndex = K.isDown(K.CTRL) ? getWordStart() : cursorIndex - 1;
250247
selectionRange = { start : newIndex , length : cursorIndex - newIndex };
251248
}
252-
cutSelection();
249+
cutSelection(true);
253250
onChange();
254251
}
255252
case K.ESCAPE:
@@ -282,7 +279,6 @@ class TextInput extends Text {
282279
if (text != "") {
283280
cursorIndex = getTextLength();
284281
selectionRange = {start: 0, length: cursorIndex};
285-
selectionSize = 0;
286282
onCursorChange();
287283
}
288284
return;
@@ -335,7 +331,6 @@ class TextInput extends Text {
335331
selectionRange.start += selectionRange.length;
336332
selectionRange.length = -selectionRange.length;
337333
}
338-
selectionSize = 0;
339334
onCursorChange();
340335

341336
} else if( oldText != text || cursorIndex != oldIndex )
@@ -354,10 +349,9 @@ class TextInput extends Text {
354349
var pos = 0;
355350
for( line in lines ) {
356351
for( p in splitRawText(line).split("\n") ) {
357-
if( cursor < p.length )
352+
if( cursor <= p.length )
358353
return pos + cursor;
359354
pos += p.length;
360-
if( font.charset.isSpace(StringTools.fastCodeAt(text,pos)) ) pos++;
361355
cursor -= p.length + 1;
362356
}
363357
pos++;
@@ -374,10 +368,9 @@ class TextInput extends Text {
374368
var spos = 0;
375369
for( line in lines ) {
376370
for( p in splitRawText(line).split("\n") ) {
377-
if( (pos - spos) < p.length )
371+
if( (pos - spos) <= p.length )
378372
return (pos - spos) + cursor;
379373
spos += p.length;
380-
if( font.charset.isSpace(StringTools.fastCodeAt(text,spos)) ) spos++;
381374
cursor += p.length + 1;
382375
}
383376
spos++;
@@ -406,15 +399,20 @@ class TextInput extends Text {
406399
cutSelection();
407400
var pos = getTextPos(cursorIndex);
408401
text = text.substr(0, pos) + t + text.substr(pos);
409-
cursorIndex += t.length;
402+
pos += t.length;
403+
cursorIndex = getCursorPos(pos);
410404
onChange();
411405
}
412406

413-
function cutSelection() {
407+
function cutSelection( ?back ) {
414408
if(selectionRange == null) return false;
415-
cursorIndex = selectionRange.start;
416-
var end = cursorIndex + selectionRange.length;
417-
text = text.substr(0, getTextPos(cursorIndex)) + text.substr(getTextPos(end));
409+
var pos = getTextPos(selectionRange.start);
410+
var end = getTextPos(selectionRange.start + selectionRange.length);
411+
if( pos == end && back != null ) {
412+
if( back ) pos-- else end++;
413+
}
414+
text = text.substr(0, pos) + text.substr(end);
415+
cursorIndex = getCursorPos(pos);
418416
selectionRange = null;
419417
return true;
420418
}
@@ -778,17 +776,17 @@ class TextInput extends Text {
778776

779777
var selEnd = line.length;
780778

781-
if(selectionRange.start > lineOffset + line.length || selectionRange.start + selectionRange.length < lineOffset) {
779+
if(selectionRange.start >= lineOffset + line.length || selectionRange.start + selectionRange.length < lineOffset) {
782780
lineOffset += line.length;
783781
continue;
784782
}
785783

786784
var selStart = Math.floor(Math.max(0, selectionRange.start - lineOffset));
787785
var selEnd = Math.floor(Math.min(line.length - selStart, selectionRange.length + selectionRange.start - lineOffset - selStart));
788786

789-
selectionPos = calcTextWidth(line.substr(0, selStart));
790-
selectionSize = calcTextWidth(line.substr(selStart, selEnd));
791-
if( selectionRange.start + selectionRange.length == cursorIndex ) selectionSize += cursorTile.width; // last pixel
787+
var selectionPos = calcTextWidth(line.substr(0, selStart));
788+
var selectionSize = calcTextWidth(line.substr(selStart, selEnd));
789+
if( selectionRange.start + selectionRange.length == cursorIndex || selectionSize == 0 ) selectionSize += cursorTile.width; // last pixel
792790

793791
selectionTile.dx += selectionPos;
794792
selectionTile.dy += i * font.lineHeight;

0 commit comments

Comments
 (0)