diff options
author | haranp <haranp@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-02-17 13:35:54 +0000 |
---|---|---|
committer | haranp <haranp@c06c8d41-db1a-0410-9941-cceddc491573> | 2007-02-17 13:35:54 +0000 |
commit | e9b1a504be1d94eab7a724ba5935aaf48fe9e4cb (patch) | |
tree | 3a07055dc98ba0f06bfc9e685e105a45085a7107 /crawl-ref/source/format.cc | |
parent | 702a81e3830d34745837cd116d5c3bcf6e4755bc (diff) | |
download | crawl-ref-e9b1a504be1d94eab7a724ba5935aaf48fe9e4cb.tar.gz crawl-ref-e9b1a504be1d94eab7a724ba5935aaf48fe9e4cb.zip |
Moved formatted_string into its own file, separate from the rest of Menu.
git-svn-id: https://crawl-ref.svn.sourceforge.net/svnroot/crawl-ref/trunk@954 c06c8d41-db1a-0410-9941-cceddc491573
Diffstat (limited to 'crawl-ref/source/format.cc')
-rw-r--r-- | crawl-ref/source/format.cc | 291 |
1 files changed, 291 insertions, 0 deletions
diff --git a/crawl-ref/source/format.cc b/crawl-ref/source/format.cc new file mode 100644 index 0000000000..3de867c8ee --- /dev/null +++ b/crawl-ref/source/format.cc @@ -0,0 +1,291 @@ +#include "AppHdr.h" + +#include "initfile.h" +#include "format.h" +#include "view.h" + +formatted_string::formatted_string(int init_colour) + : ops() +{ + if (init_colour) + textcolor(init_colour); +} + +formatted_string::formatted_string(const std::string &s, int init_colour) + : ops() +{ + if (init_colour) + textcolor(init_colour); + cprintf(s); +} + +int formatted_string::get_colour(const std::string &tag) +{ + if (tag == "h") + return (YELLOW); + + if (tag == "w") + return (WHITE); + + const int colour = str_to_colour(tag); + return (colour != -1? colour : LIGHTGREY); +} + +formatted_string formatted_string::parse_string( + const std::string &s, + bool eol_ends_format, + bool (*process)(const std::string &tag)) +{ + // FIXME This is a lame mess, just good enough for the task on hand + // (keyboard help). + formatted_string fs; + std::string::size_type tag = std::string::npos; + std::string::size_type length = s.length(); + + std::string currs; + int curr_colour = LIGHTGREY; + bool masked = false; + + for (tag = 0; tag < length; ++tag) + { + bool invert_colour = false; + std::string::size_type endpos = std::string::npos; + + if (s[tag] != '<' || tag >= length - 2) + { + if (!masked) + currs += s[tag]; + continue; + } + + // Is this a << escape? + if (s[tag + 1] == '<') + { + if (!masked) + currs += s[tag]; + tag++; + continue; + } + + endpos = s.find('>', tag + 1); + // No closing >? + if (endpos == std::string::npos) + { + if (!masked) + currs += s[tag]; + continue; + } + + std::string tagtext = s.substr(tag + 1, endpos - tag - 1); + if (tagtext.empty() || tagtext == "/") + { + if (!masked) + currs += s[tag]; + continue; + } + + if (tagtext[0] == '/') + { + invert_colour = true; + tagtext = tagtext.substr(1); + tag++; + } + + if (tagtext[0] == '?') + { + if (tagtext.length() == 1) + masked = false; + else if (process && !process(tagtext.substr(1))) + masked = true; + + tag += tagtext.length() + 1; + continue; + } + + const int new_colour = invert_colour? LIGHTGREY : get_colour(tagtext); + if (new_colour != curr_colour) + { + fs.cprintf(currs); + currs.clear(); + fs.textcolor( curr_colour = new_colour ); + } + tag += tagtext.length() + 1; + } + if (currs.length()) + fs.cprintf(currs); + + if (eol_ends_format && curr_colour != LIGHTGREY) + fs.textcolor(LIGHTGREY); + + return (fs); +} + +formatted_string::operator std::string() const +{ + std::string s; + for (unsigned i = 0, size = ops.size(); i < size; ++i) + { + if (ops[i] == FSOP_TEXT) + s += ops[i].text; + } + return (s); +} + +const formatted_string & +formatted_string::operator += (const formatted_string &other) +{ + ops.insert(ops.end(), other.ops.begin(), other.ops.end()); + return (*this); +} + +std::string::size_type formatted_string::length() const +{ + // Just add up the individual string lengths. + std::string::size_type len = 0; + for (unsigned i = 0, size = ops.size(); i < size; ++i) + if (ops[i] == FSOP_TEXT) + len += ops[i].text.length(); + return (len); +} + +inline void cap(int &i, int max) +{ + if (i < 0 && -i <= max) + i += max; + if (i >= max) + i = max - 1; + if (i < 0) + i = 0; +} + +std::string formatted_string::tostring(int s, int e) const +{ + std::string st; + + int size = ops.size(); + cap(s, size); + cap(e, size); + + for (int i = s; i <= e && i < size; ++i) + { + if (ops[i] == FSOP_TEXT) + st += ops[i].text; + } + return st; +} + +void formatted_string::display(int s, int e) const +{ + int size = ops.size(); + if (!size) + return; + + cap(s, size); + cap(e, size); + + for (int i = s; i <= e && i < size; ++i) + ops[i].display(); +} + +void formatted_string::gotoxy(int x, int y) +{ + ops.push_back( fs_op(x, y) ); +} + +void formatted_string::movexy(int x, int y) +{ + ops.push_back( fs_op(x, y, true) ); +} + +int formatted_string::find_last_colour() const +{ + if (!ops.empty()) + { + for (int i = ops.size() - 1; i >= 0; --i) + { + if (ops[i].type == FSOP_COLOUR) + return (ops[i].x); + } + } + return (LIGHTGREY); +} + +void formatted_string::add_glyph(const item_def *item) +{ + const int last_col = find_last_colour(); + unsigned short ch, col; + get_item_glyph(item, &ch, &col); + this->textcolor(col); + this->cprintf("%c", ch); + this->textcolor(last_col); +} + +void formatted_string::add_glyph(const monsters *mons) +{ + const int last_col = find_last_colour(); + unsigned short ch, col; + get_mons_glyph(mons, &ch, &col); + this->textcolor(col); + this->cprintf("%c", ch); + this->textcolor(last_col); +} + +void formatted_string::textcolor(int color) +{ + if (!ops.empty() && ops[ ops.size() - 1 ].type == FSOP_COLOUR) + ops.erase( ops.end() - 1 ); + + ops.push_back(color); +} + +void formatted_string::clear() +{ + ops.clear(); +} + +void formatted_string::cprintf(const char *s, ...) +{ + char buf[1000]; + va_list args; + va_start(args, s); + vsnprintf(buf, sizeof buf, s, args); + va_end(args); + + cprintf(std::string(buf)); +} + +void formatted_string::cprintf(const std::string &s) +{ + ops.push_back(s); +} + +void formatted_string::fs_op::display() const +{ + switch (type) + { + case FSOP_CURSOR: + { + int cx = x, cy = y; + if (relative) + { + cx += wherex(); + cy += wherey(); + } + else + { + if (cx == -1) + cx = wherex(); + if (cy == -1) + cy = wherey(); + } + ::gotoxy(cx, cy); + break; + } + case FSOP_COLOUR: + ::textattr(x); + break; + case FSOP_TEXT: + ::cprintf("%s", text.c_str()); + break; + } +} |