/* * This file is part of lanterna (http://code.google.com/p/lanterna/). * * lanterna is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public License * along with this program. If not, see . * * Copyright (C) 2010-2015 Martin */ package com.googlecode.lanterna.terminal.swing; import com.googlecode.lanterna.TerminalTextUtils; import com.googlecode.lanterna.TextCharacter; import com.googlecode.lanterna.TerminalPosition; import com.googlecode.lanterna.TerminalSize; import java.util.ArrayList; import java.util.Iterator; import java.util.LinkedList; import java.util.List; import java.util.ListIterator; /** * Contains an entire text buffer used by Swing terminal * @author martin */ class TextBuffer { private final int backlog; private final LinkedList> lineBuffer; private final TextCharacter fillCharacter; TextBuffer(int backlog) { this.backlog = backlog; this.lineBuffer = new LinkedList>(); this.fillCharacter = TextCharacter.DEFAULT_CHARACTER; //Initialize the content to one line newLine(); } void clear() { lineBuffer.clear(); newLine(); } void newLine() { ArrayList line = new ArrayList(200); line.add(fillCharacter); lineBuffer.addFirst(line); } Iterable> getVisibleLines(final int visibleRows, final int scrollOffset) { final int length = Math.min(visibleRows, lineBuffer.size()); return new Iterable>() { @Override public Iterator> iterator() { return new Iterator>() { private final ListIterator> listIterator = lineBuffer.subList(scrollOffset, scrollOffset + length).listIterator(length); @Override public boolean hasNext() { return listIterator.hasPrevious(); } @Override public List next() { return listIterator.previous(); } @Override public void remove() { listIterator.remove(); } }; } }; } int getNumberOfLines() { return lineBuffer.size(); } void trimBacklog(int terminalHeight) { while(lineBuffer.size() - terminalHeight > backlog) { lineBuffer.removeLast(); } } void ensurePosition(TerminalSize terminalSize, TerminalPosition position) { getLine(terminalSize, position); } public TextCharacter getCharacter(TerminalSize terminalSize, TerminalPosition position) { return getLine(terminalSize, position).get(position.getColumn()); } void setCharacter(TerminalSize terminalSize, TerminalPosition currentPosition, TextCharacter terminalCharacter) { List line = getLine(terminalSize, currentPosition); //If we are replacing a CJK character with a non-CJK character, make the following character empty if(TerminalTextUtils.isCharCJK(line.get(currentPosition.getColumn()).getCharacter()) && !TerminalTextUtils.isCharCJK(terminalCharacter.getCharacter())) { line.set(currentPosition.getColumn() + 1, terminalCharacter.withCharacter(' ')); } //Set the character in the buffer line.set(currentPosition.getColumn(), terminalCharacter); //Pad CJK character with a trailing space if(TerminalTextUtils.isCharCJK(terminalCharacter.getCharacter()) && currentPosition.getColumn() + 1 < line.size()) { ensurePosition(terminalSize, currentPosition.withRelativeColumn(1)); line.set(currentPosition.getColumn() + 1, terminalCharacter.withCharacter(' ')); } //If there's a CJK character immediately to our left, reset it if(currentPosition.getColumn() > 0 && TerminalTextUtils.isCharCJK(line.get(currentPosition.getColumn() - 1).getCharacter())) { line.set(currentPosition.getColumn() - 1, line.get(currentPosition.getColumn() - 1).withCharacter(' ')); } } private List getLine(TerminalSize terminalSize, TerminalPosition position) { while(position.getRow() >= lineBuffer.size()) { newLine(); } int lineIndex = Math.min(terminalSize.getRows(), lineBuffer.size()) - 1 - position.getRow(); List line = lineBuffer.get(lineIndex); while(line.size() <= position.getColumn()) { line.add(fillCharacter); } return line; } }