sources/coloredline.cpp

changeset 46
19be47c9bab7
child 47
35b968619b0c
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/sources/coloredline.cpp	Mon Dec 15 21:59:24 2014 +0200
@@ -0,0 +1,151 @@
+/*
+	Copyright 2014 Teemu Piippo
+	All rights reserved.
+
+	Redistribution and use in source and binary forms, with or without
+	modification, are permitted provided that the following conditions
+	are met:
+
+	1. Redistributions of source code must retain the above copyright
+	   notice, this list of conditions and the following disclaimer.
+	2. Redistributions in binary form must reproduce the above copyright
+	   notice, this list of conditions and the following disclaimer in the
+	   documentation and/or other materials provided with the distribution.
+	3. Neither the name of the copyright holder nor the names of its
+	   contributors may be used to endorse or promote products derived from
+	   this software without specific prior written permission.
+
+	THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+	"AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+	TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+	PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER
+	OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+	EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+	PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
+	PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
+	LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
+	NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
+	SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+*/
+
+#include "coloredline.h"
+
+static const struct { Color color; bool bold; } g_colorCodes['v' - 'a' + 1] =
+{
+	{ RED,     true  }, // a - brick
+	{ YELLOW,  true  }, // b - tan
+	{ WHITE,   false }, // c - gray
+	{ GREEN,   true  }, // d - light green
+	{ YELLOW,  false }, // e - brown
+	{ YELLOW,  true  }, // f - gold yellow
+	{ RED,     true  }, // g - bright red
+	{ BLUE,    false }, // h - dark blue
+	{ YELLOW,  false }, // i - orange
+	{ WHITE,   true  }, // j - white
+	{ YELLOW,  true  }, // k - fire yellow
+	{ DEFAULT, false }, // l - untranslated
+	{ BLACK,   false }, // m - black
+	{ BLUE,    true  }, // n - light blue
+	{ YELLOW,  true  }, // o - cream
+	{ GREEN,   true  }, // p - olive green
+	{ GREEN,   false }, // q - dark green
+	{ RED,     false }, // r - dark red
+	{ YELLOW,  false }, // s - dark brown
+	{ MAGENTA, false }, // t - purple
+	{ BLACK,   true  }, // u - dark gray
+	{ CYAN,    true  }, // v - cyan
+};
+
+// -------------------------------------------------------------------------------------------------
+//
+METHOD
+ColoredLine::finalize() -> void
+{
+	if (m_activeColor != DEFAULT)
+		this->set_color (m_activeColor, false);
+
+	if (m_boldActive)
+		m_data << RLINE_OFF_BOLD;
+
+	m_final = true;
+}
+
+// -------------------------------------------------------------------------------------------------
+//
+METHOD
+ColoredLine::add_char (char ch) -> void
+{
+	if (m_final)
+		return; // Don't touch finalized lines.
+
+	if (ch == '\x1C' and m_colorCodeStage == 0)
+	{
+		m_colorCodeStage = 1;
+		return;
+	}
+
+	if (m_colorCodeStage == 1)
+	{
+		if (m_activeColor != DEFAULT)
+			this->set_color (m_activeColor, false);
+
+		if (m_boldActive)
+			m_data << RLINE_OFF_BOLD;
+
+		if (ch >= 'a' and ch <= 'v' and ch != 'l')
+		{
+			auto colorInfo = g_colorCodes[ch - 'a'];
+			m_activeColor = colorInfo.color;
+			m_boldActive = colorInfo.bold;
+			assert (m_activeColor < 8);
+			this->set_color (m_activeColor, true);
+
+			if (m_boldActive)
+				m_data << RLINE_ON_BOLD;
+		}
+
+		m_colorCodeStage = 0;
+		return;
+	}
+
+	if (isprint (ch))
+	{
+		m_string += ch;
+		m_data << int (ch);
+		++m_length;
+	}
+}
+
+// -------------------------------------------------------------------------------------------------
+//
+METHOD
+ColoredLine::set_color (Color a, bool on) -> void
+{
+	switch (a)
+	{
+	case BLACK:   m_data << (on ? RLINE_ON_BLACK   : RLINE_OFF_BLACK); break;
+	case RED:     m_data << (on ? RLINE_ON_RED     : RLINE_OFF_RED); break;
+	case GREEN:   m_data << (on ? RLINE_ON_GREEN   : RLINE_OFF_GREEN); break;
+	case YELLOW:  m_data << (on ? RLINE_ON_YELLOW  : RLINE_OFF_YELLOW); break;
+	case BLUE:    m_data << (on ? RLINE_ON_BLUE    : RLINE_OFF_BLUE); break;
+	case MAGENTA: m_data << (on ? RLINE_ON_MAGENTA : RLINE_OFF_MAGENTA); break;
+	case CYAN:    m_data << (on ? RLINE_ON_CYAN    : RLINE_OFF_CYAN); break;
+	case WHITE:   m_data << (on ? RLINE_ON_WHITE   : RLINE_OFF_WHITE); break;
+	case NUM_COLORS:
+	case DEFAULT: assert (false); break;
+	}
+}
+
+// -------------------------------------------------------------------------------------------------
+// How many rows does this line take up?
+//
+METHOD
+ColoredLine::rows (int cols) const -> int
+{
+	int rows = length() / cols;
+
+	if (length() % cols != 0)
+		rows++;
+
+	return max (rows, 1);
+}

mercurial