X-Git-Url: http://git.nikiroo.be/?p=jvcard.git;a=blobdiff_plain;f=src%2Fcom%2Fgooglecode%2Flanterna%2Fterminal%2FTerminalTextGraphics.java;fp=src%2Fcom%2Fgooglecode%2Flanterna%2Fterminal%2FTerminalTextGraphics.java;h=0000000000000000000000000000000000000000;hp=f51906d35b70ea98c9742dd199cd48feb526e863;hb=f06c81000632cfb5f525ca458f719338f55f9f66;hpb=a73a906356c971b080c36368e71a15d87e8b8d31 diff --git a/src/com/googlecode/lanterna/terminal/TerminalTextGraphics.java b/src/com/googlecode/lanterna/terminal/TerminalTextGraphics.java deleted file mode 100644 index f51906d..0000000 --- a/src/com/googlecode/lanterna/terminal/TerminalTextGraphics.java +++ /dev/null @@ -1,213 +0,0 @@ -/* - * 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; - -import com.googlecode.lanterna.SGR; -import com.googlecode.lanterna.TerminalPosition; -import com.googlecode.lanterna.TerminalSize; -import com.googlecode.lanterna.graphics.AbstractTextGraphics; -import com.googlecode.lanterna.TextCharacter; -import com.googlecode.lanterna.graphics.TextGraphics; - -import java.io.IOException; -import java.util.HashMap; -import java.util.Map; -import java.util.concurrent.atomic.AtomicInteger; - -/** - * This is the terminal's implementation of TextGraphics. Upon creation it takes a snapshot for the terminal's size, so - * that it won't require to do an expensive lookup on every call to {@code getSize()}, but this also means that it can - * go stale quickly if the terminal is resized. You should try to use the object quickly and then let it be GC:ed. It - * will not pick up on terminal resize! Also, the state of the Terminal after an operation performed by this - * TextGraphics implementation is undefined and you should probably re-initialize colors and modifiers. - *

- * Any write operation that results in an IOException will be wrapped by a RuntimeException since the TextGraphics - * interface doesn't allow throwing IOException - */ -class TerminalTextGraphics extends AbstractTextGraphics { - - private final Terminal terminal; - private final TerminalSize terminalSize; - - private final Map writeHistory; - - private AtomicInteger manageCallStackSize; - private TextCharacter lastCharacter; - private TerminalPosition lastPosition; - - TerminalTextGraphics(Terminal terminal) throws IOException { - this.terminal = terminal; - this.terminalSize = terminal.getTerminalSize(); - this.manageCallStackSize = new AtomicInteger(0); - this.writeHistory = new HashMap(); - this.lastCharacter = null; - this.lastPosition = null; - } - - @Override - public TextGraphics setCharacter(int columnIndex, int rowIndex, TextCharacter textCharacter) { - return setCharacter(new TerminalPosition(columnIndex, rowIndex), textCharacter); - } - - @Override - public synchronized TextGraphics setCharacter(TerminalPosition position, TextCharacter textCharacter) { - try { - if(manageCallStackSize.get() > 0) { - if(lastCharacter == null || !lastCharacter.equals(textCharacter)) { - applyGraphicState(textCharacter); - lastCharacter = textCharacter; - } - if(lastPosition == null || !lastPosition.equals(position)) { - terminal.setCursorPosition(position.getColumn(), position.getRow()); - lastPosition = position; - } - } - else { - terminal.setCursorPosition(position.getColumn(), position.getRow()); - applyGraphicState(textCharacter); - } - terminal.putCharacter(textCharacter.getCharacter()); - if(manageCallStackSize.get() > 0) { - lastPosition = position.withRelativeColumn(1); - } - writeHistory.put(position, textCharacter); - } - catch(IOException e) { - throw new RuntimeException(e); - } - return this; - } - - @Override - public TextCharacter getCharacter(int column, int row) { - return getCharacter(new TerminalPosition(column, row)); - } - - @Override - public synchronized TextCharacter getCharacter(TerminalPosition position) { - return writeHistory.get(position); - } - - private void applyGraphicState(TextCharacter textCharacter) throws IOException { - terminal.resetColorAndSGR(); - terminal.setForegroundColor(textCharacter.getForegroundColor()); - terminal.setBackgroundColor(textCharacter.getBackgroundColor()); - for(SGR sgr: textCharacter.getModifiers()) { - terminal.enableSGR(sgr); - } - } - - @Override - public TerminalSize getSize() { - return terminalSize; - } - - @Override - public synchronized TextGraphics drawLine(TerminalPosition fromPoint, TerminalPosition toPoint, char character) { - try { - enterAtomic(); - super.drawLine(fromPoint, toPoint, character); - return this; - } - finally { - leaveAtomic(); - } - } - - @Override - public synchronized TextGraphics drawTriangle(TerminalPosition p1, TerminalPosition p2, TerminalPosition p3, char character) { - try { - enterAtomic(); - super.drawTriangle(p1, p2, p3, character); - return this; - } - finally { - leaveAtomic(); - } - } - - @Override - public synchronized TextGraphics fillTriangle(TerminalPosition p1, TerminalPosition p2, TerminalPosition p3, char character) { - try { - enterAtomic(); - super.fillTriangle(p1, p2, p3, character); - return this; - } - finally { - leaveAtomic(); - } - } - - @Override - public synchronized TextGraphics fillRectangle(TerminalPosition topLeft, TerminalSize size, char character) { - try { - enterAtomic(); - super.fillRectangle(topLeft, size, character); - return this; - } - finally { - leaveAtomic(); - } - } - - @Override - public synchronized TextGraphics drawRectangle(TerminalPosition topLeft, TerminalSize size, char character) { - try { - enterAtomic(); - super.drawRectangle(topLeft, size, character); - return this; - } - finally { - leaveAtomic(); - } - } - - @Override - public synchronized TextGraphics putString(int column, int row, String string) { - try { - enterAtomic(); - return super.putString(column, row, string); - } - finally { - leaveAtomic(); - } - } - - /** - * It's tricky with this implementation because we can't rely on any state in between two calls to setCharacter - * since the caller might modify the terminal's state outside of this writer. However, many calls inside - * TextGraphics will indeed make multiple calls in setCharacter where we know that the state won't change (actually, - * we can't be 100% sure since the caller might create a separate thread and maliciously write directly to the - * terminal while call one of the draw/fill/put methods in here). We could just set the state before writing every - * single character but that would be inefficient. Rather, we keep a counter of if we are inside an 'atomic' - * (meaning we know multiple calls to setCharacter will have the same state). Some drawing methods call other - * drawing methods internally for their implementation so that's why this is implemented with an integer value - * instead of a boolean; when the counter reaches zero we remove the memory of what state the terminal is in. - */ - private void enterAtomic() { - manageCallStackSize.incrementAndGet(); - } - - private void leaveAtomic() { - if(manageCallStackSize.decrementAndGet() == 0) { - lastPosition = null; - lastCharacter = null; - } - } -}