--- /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); +}