+ int addedLength = outputText.length();
+ int currentLength = output.getCharCount();
+ int insertPos = currentLength;
+ int newLength = insertPos + addedLength;
+
+ if (limitConsoleOutput && newLength > highWatermark) {
+ // Test for corner case: buffer overflows and more text is incoming than fits low watermark
+ if (addedLength > lowWatermark) {
+ // Prune the new input text first if it is too large to fit in the buffer even on its own to be < lowWatermark
+ int removedCharacters = addedLength - lowWatermark;
+
+ outputText = outputText.substring(removedCharacters);
+ addedLength = outputText.length();
+ newLength = insertPos + addedLength;
+
+ // Prune new incoming style ranges also
+ int firstStyleRangeToCopy = 0;
+ for (int i = 0; i < styleRangeArray.length; ++i, ++firstStyleRangeToCopy) {
+ StyleRange sr = styleRangeArray[i];
+ if ((sr.start + sr.length) > removedCharacters) {
+ if (sr.start < removedCharacters)
+ sr.start = removedCharacters;
+ break;
+ }
+ }
+ styleRangeArray = Arrays.copyOfRange(styleRangeArray, firstStyleRangeToCopy, styleRangeArray.length);
+ for (StyleRange sr : styleRangeArray)
+ sr.start -= removedCharacters;
+ }
+
+ int minimallyRemoveFromBegin = Math.min(currentLength, newLength - lowWatermark);
+
+ // Find the next line change to prune the text until then
+ StyledTextContent content = output.getContent();
+ int lineCount = content.getLineCount();
+ int lastRemovedLine = content.getLineAtOffset(minimallyRemoveFromBegin);
+ int removeUntilOffset = lastRemovedLine >= (lineCount-1)
+ ? currentLength
+ : content.getOffsetAtLine(lastRemovedLine + 1);
+
+ insertPos -= removeUntilOffset;
+
+ outputModiLock = true;
+ output.replaceTextRange(0, removeUntilOffset, "");
+ output.replaceTextRange(insertPos, 0, outputText);
+ outputModiLock = false;
+ } else {
+ // Buffer does not need to be pruned, just append at end
+ outputModiLock = true;
+ output.replaceTextRange(insertPos, 0, outputText);
+ outputModiLock = false;
+ }