summaryrefslogtreecommitdiffstats
path: root/crawl-ref/source/format.cc
diff options
context:
space:
mode:
authorharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2007-02-17 13:35:54 +0000
committerharanp <haranp@c06c8d41-db1a-0410-9941-cceddc491573>2007-02-17 13:35:54 +0000
commite9b1a504be1d94eab7a724ba5935aaf48fe9e4cb (patch)
tree3a07055dc98ba0f06bfc9e685e105a45085a7107 /crawl-ref/source/format.cc
parent702a81e3830d34745837cd116d5c3bcf6e4755bc (diff)
downloadcrawl-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.cc291
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;
+ }
+}