diff --git a/docs/changelog.txt b/docs/changelog.txt index 9ad9dd18dd..da852776ff 100644 --- a/docs/changelog.txt +++ b/docs/changelog.txt @@ -61,6 +61,7 @@ Template for new versions: ## Fixes - a safety check was added to ``Screen::doSetTile_char`` fur out of bound pen color values - ``TextArea`` widget corrected to use ``COLOR_BLACK`` instead of ``COLOR_RESET`` as default background color +- ``Screen::Pen``: COLOR_RESET from Lua is changed to grey (fg) or black (bg); color values are masked to 4 bits to keep them in the expected range ## Misc Improvements diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index 6a08756156..c8f6277225 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -22,6 +22,7 @@ must not be misrepresented as being the original software. distribution. */ +#include "ColorText.h" #include "Core.h" #include "Error.h" #include "Internal.h" @@ -232,14 +233,30 @@ static bool get_bool_field(lua_State *L, bool *pf, int idx, const char *name, bo return !nil; } +static int8_t mask_pen_color(int8_t color, int8_t default_color) { + if (color == COLOR_RESET) + color = default_color; + return color & 15; +} + +static bool get_color_field(lua_State *L, int8_t *pf, int idx, const char *name, int defval) +{ + bool nonnil = get_int_field(L, pf, idx, name, defval); // defval for nil + *pf = mask_pen_color(*pf, defval); // defval for COLOR_RESET + return nonnil; +} + +static constexpr int8_t DEFAULT_FG = COLOR_GREY; +static constexpr int8_t DEFAULT_BG = COLOR_BLACK; + static void decode_pen(lua_State *L, Pen &pen, int idx) { idx = lua_absindex(L, idx); get_char_field(L, &pen.ch, idx, "ch", 0); - get_int_field(L, &pen.fg, idx, "fg", 7); - get_int_field(L, &pen.bg, idx, "bg", 0); + get_color_field(L, &pen.fg, idx, "fg", DEFAULT_FG); + get_color_field(L, &pen.bg, idx, "bg", DEFAULT_BG); lua_getfield(L, idx, "bold"); if (lua_isnil(L, -1)) @@ -252,8 +269,8 @@ static void decode_pen(lua_State *L, Pen &pen, int idx) get_int_or_closure_field(L, &pen.tile, idx, "tile", 0); - bool tcolor = get_int_field(L, &pen.tile_fg, idx, "tile_fg", 7); - tcolor = get_int_field(L, &pen.tile_bg, idx, "tile_bg", 0) || tcolor; + bool tcolor = get_color_field(L, &pen.tile_fg, idx, "tile_fg", DEFAULT_FG); + tcolor = get_color_field(L, &pen.tile_bg, idx, "tile_bg", DEFAULT_BG) || tcolor; if (tcolor) pen.tile_mode = Pen::TileColor; @@ -672,7 +689,7 @@ void Lua::CheckPen(lua_State *L, Screen::Pen *pen, int index, bool allow_nil, bo } else if (allow_color && lua_isnumber(L, index)) { - *pen = Pen(0, lua_tointeger(L, index)&15, 0); + *pen = Pen(0, mask_pen_color(lua_tointeger(L, index), DEFAULT_FG), 0); } else { @@ -698,8 +715,8 @@ static int adjust_pen(lua_State *L, bool no_copy) iidx = -1; - pen.fg = luaL_optint(L, 2, pen.fg) & 15; - pen.bg = luaL_optint(L, 3, pen.bg); + pen.fg = mask_pen_color(luaL_optint(L, 2, pen.fg), DEFAULT_FG); + pen.bg = mask_pen_color(luaL_optint(L, 3, pen.bg), DEFAULT_BG); if (!lua_isnil(L, 4)) pen.bold = lua_toboolean(L, 4); @@ -864,7 +881,7 @@ static int dfhack_pen_newindex(lua_State *L) lua_pushinteger(L, (unsigned char)pen.ch); break; case 1: - pen.fg = luaL_checkint(L, 3) & 15; + pen.fg = mask_pen_color(luaL_checkint(L, 3), DEFAULT_FG); lua_pushinteger(L, pen.fg); break; case 2: @@ -872,7 +889,7 @@ static int dfhack_pen_newindex(lua_State *L) lua_pushboolean(L, pen.bold); break; case 3: - pen.bg = luaL_checkint(L, 3) & 15; + pen.bg = mask_pen_color(luaL_checkint(L, 3), DEFAULT_BG); lua_pushinteger(L, pen.bg); break; case 4: @@ -891,14 +908,14 @@ static int dfhack_pen_newindex(lua_State *L) lua_pushboolean(L, pen.tile_mode == Pen::CharColor); break; case 6: - if (pen.tile_mode != Pen::TileColor) { wipe_tc = true; pen.tile_bg = 0; } - pen.tile_fg = luaL_checkint(L, 3) & 15; + if (pen.tile_mode != Pen::TileColor) { wipe_tc = true; pen.tile_bg = DEFAULT_BG; } + pen.tile_fg = mask_pen_color(luaL_checkint(L, 3), DEFAULT_FG); pen.tile_mode = Pen::TileColor; lua_pushinteger(L, pen.tile_fg); break; case 7: - if (pen.tile_mode != Pen::TileColor) { wipe_tc = true; pen.tile_fg = 7; } - pen.tile_bg = luaL_checkint(L, 3) & 15; + if (pen.tile_mode != Pen::TileColor) { wipe_tc = true; pen.tile_fg = DEFAULT_FG; } + pen.tile_bg = mask_pen_color(luaL_checkint(L, 3), DEFAULT_BG); pen.tile_mode = Pen::TileColor; lua_pushinteger(L, pen.tile_bg); break; diff --git a/library/include/modules/Screen.h b/library/include/modules/Screen.h index 173cda6aa8..86c619c2b5 100644 --- a/library/include/modules/Screen.h +++ b/library/include/modules/Screen.h @@ -94,26 +94,26 @@ namespace DFHack // NOTE: LuaApi.cpp assumes this struct is plain data and has empty destructor Pen(char ch = 0, int8_t fg = 7, int8_t bg = 0, int tile = 0, bool color_tile = false) - : ch(ch), fg(fg&7), bg(bg), bold(!!(fg&8)), + : ch(ch), fg(fg&7), bg(bg&15), bold(!!(fg&8)), tile(tile), tile_mode(color_tile ? CharColor : AsIs), tile_fg(0), tile_bg(0) {} Pen(char ch, int8_t fg, int8_t bg, bool bold, int tile = 0, bool color_tile = false) - : ch(ch), fg(fg), bg(bg), bold(bold), + : ch(ch), fg(fg&15), bg(bg&15), bold(bold), tile(tile), tile_mode(color_tile ? CharColor : AsIs), tile_fg(0), tile_bg(0) {} Pen(char ch, int8_t fg, int8_t bg, int tile, int8_t tile_fg, int8_t tile_bg) - : ch(ch), fg(fg&7), bg(bg), bold(!!(fg&8)), - tile(tile), tile_mode(TileColor), tile_fg(tile_fg), tile_bg(tile_bg) + : ch(ch), fg(fg&7), bg(bg&15), bold(!!(fg&8)), + tile(tile), tile_mode(TileColor), tile_fg(tile_fg&15), tile_bg(tile_bg&15) {} Pen(char ch, int8_t fg, int8_t bg, bool bold, int tile, int8_t tile_fg, int8_t tile_bg) - : ch(ch), fg(fg), bg(bg), bold(bold), - tile(tile), tile_mode(TileColor), tile_fg(tile_fg), tile_bg(tile_bg) + : ch(ch), fg(fg&15), bg(bg&15), bold(bold), + tile(tile), tile_mode(TileColor), tile_fg(tile_fg&15), tile_bg(tile_bg&15) {} void adjust(int8_t nfg) { fg = nfg&7; bold = !!(nfg&8); } - void adjust(int8_t nfg, bool nbold) { fg = nfg; bold = nbold; } - void adjust(int8_t nfg, int8_t nbg) { adjust(nfg); bg = nbg; } - void adjust(int8_t nfg, bool nbold, int8_t nbg) { adjust(nfg, nbold); bg = nbg; } + void adjust(int8_t nfg, bool nbold) { fg = nfg&15; bold = nbold; } + void adjust(int8_t nfg, int8_t nbg) { adjust(nfg); bg = nbg&15; } + void adjust(int8_t nfg, bool nbold, int8_t nbg) { adjust(nfg, nbold); bg = nbg&15; } Pen color(int8_t nfg) const { Pen cp(*this); cp.adjust(nfg); return cp; } Pen color(int8_t nfg, bool nbold) const { Pen cp(*this); cp.adjust(nfg, nbold); return cp; } diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index c5451ce806..05be06ee9e 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -480,9 +480,9 @@ bool Screen::drawBorder(const std::string &title) if (!gps) return false; auto dim = getWindowSize(); - Pen border('\xDB', 8); - Pen text(0, 0, 7); - Pen signature(0, 0, 8); + Pen border('\xDB', COLOR_DARKGREY); + Pen text(0, COLOR_BLACK, COLOR_GREY); + Pen signature(0, COLOR_BLACK, COLOR_DARKGREY); for (int x = 0; x < dim.x; x++) { @@ -516,8 +516,8 @@ bool Screen::invalidate() return true; } -const Pen Screen::Painter::default_pen(0,COLOR_GREY,0); -const Pen Screen::Painter::default_key_pen(0,COLOR_LIGHTGREEN,0); +const Pen Screen::Painter::default_pen(0, COLOR_GREY, COLOR_BLACK); +const Pen Screen::Painter::default_key_pen(0, COLOR_LIGHTGREEN, COLOR_BLACK); void Screen::Painter::do_paint_string(const std::string &str, const Pen &pen, bool map) { diff --git a/test/library/pen.lua b/test/library/pen.lua new file mode 100644 index 0000000000..c37cf55118 --- /dev/null +++ b/test/library/pen.lua @@ -0,0 +1,455 @@ +config.target = 'core' + +-- nil "base" pen + +function test.make_base_nil() + local pen = dfhack.pen.make(nil) + expect.nil_(pen) +end + +function test.make_base_empty() + local pen = dfhack.pen.make{} + expect.eq(pen.fg, COLOR_GREY) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) +end + +function test.make_base_nil_fg() + local pen = dfhack.pen.make(nil, COLOR_RED) + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + + pen = dfhack.pen.make(nil, COLOR_LIGHTRED) + expect.eq(pen.fg, COLOR_RED) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) +end + +function test.make_base_fg_nil_bg() + local pen = dfhack.pen.make(nil, nil, COLOR_BLUE) + expect.eq(pen.fg, COLOR_GREY) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) +end + +function test.make_base_fg_bg_nil_bold() + local pen = dfhack.pen.make(nil, nil, nil, true) + expect.eq(pen.fg, COLOR_GREY) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + + pen = dfhack.pen.make(nil, nil, nil, false) + expect.eq(pen.fg, COLOR_GREY) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) +end + +-- color number "base" pen + +function test.make_base_color() + local pen = dfhack.pen.make(COLOR_RED) + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + + pen = dfhack.pen.make(COLOR_LIGHTRED) + expect.eq(pen.fg, COLOR_RED) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) +end + +function test.make_base_color_fg() + local pen = dfhack.pen.make(COLOR_RED, COLOR_GREEN) + expect.eq(pen.fg, COLOR_GREEN) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + + pen = dfhack.pen.make(COLOR_RED, COLOR_LIGHTGREEN) + expect.eq(pen.fg, COLOR_GREEN) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) +end + +function test.make_base_color_fg_bg() + local pen = dfhack.pen.make(COLOR_RED, COLOR_GREEN, COLOR_BLUE) + expect.eq(pen.fg, COLOR_GREEN) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + + pen = dfhack.pen.make(COLOR_RED, COLOR_LIGHTGREEN, COLOR_BLUE) + expect.eq(pen.fg, COLOR_GREEN) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) +end + +function test.make_base_color_fg_bg_bold() + local pen = dfhack.pen.make(COLOR_RED, COLOR_GREEN, COLOR_BLUE, true) + expect.eq(pen.fg, COLOR_GREEN) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + + -- maybe a bit unexpected? bold=true does not mask off "light" bit in fg + pen = dfhack.pen.make(COLOR_RED, COLOR_LIGHTGREEN, COLOR_BLUE, true) + expect.eq(pen.fg, COLOR_LIGHTGREEN) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) +end + +function test.make_base_color_fg_bg_nonbold() + local pen = dfhack.pen.make(COLOR_RED, COLOR_GREEN, COLOR_BLUE, false) + expect.eq(pen.fg, COLOR_GREEN) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + + -- maybe a bit unexpected? bold=false does not mask off "light" bit in fg + pen = dfhack.pen.make(COLOR_RED, COLOR_LIGHTGREEN, COLOR_BLUE, false) + expect.eq(pen.fg, COLOR_LIGHTGREEN) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) +end + +-- table "base" pen + +function test.make_base_table_fg() + local pen = dfhack.pen.make{ fg = COLOR_RED } + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + expect.false_(pen.tile_color) + + pen = dfhack.pen.make{ fg = COLOR_LIGHTRED } + expect.eq(pen.fg, COLOR_RED) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + expect.false_(pen.tile_color) + + pen = dfhack.pen.make{ fg = COLOR_LIGHTRED, tile_color = true } + expect.eq(pen.fg, COLOR_RED) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + expect.true_(pen.tile_color) +end + +function test.make_base_table_bg() + local pen = dfhack.pen.make{ bg = COLOR_BLUE } + expect.eq(pen.fg, COLOR_GREY) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + expect.false_(pen.tile_color) + + pen = dfhack.pen.make{ bg = COLOR_LIGHTBLUE, tile_color = true } + expect.eq(pen.fg, COLOR_GREY) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_LIGHTBLUE) + expect.true_(pen.tile_color) +end + +function test.make_base_table_fg_bold() + local pen = dfhack.pen.make{ fg = COLOR_RED, bold = true } + expect.eq(pen.fg, COLOR_RED) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + + -- maybe a bit unexpected? bold=true does not mask off "light" bit in fg + pen = dfhack.pen.make{ fg = COLOR_LIGHTRED, bold = true } + expect.eq(pen.fg, COLOR_LIGHTRED) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) +end + +function test.make_base_table_fg_nonbold() + local pen = dfhack.pen.make{ fg = COLOR_RED, bold = false } + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + + -- maybe a bit unexpected? bold=false does not mask off "light" bit in fg + pen = dfhack.pen.make{ fg = COLOR_LIGHTRED, bold = false } + expect.eq(pen.fg, COLOR_LIGHTRED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) +end + +-- first pen is ignored if second is a table or a Pen + +function test.make_base_table_pen() + local pen = dfhack.pen.make({ fg = COLOR_LIGHTRED, bg = COLOR_BLUE }, { fg = COLOR_GREEN, bg = COLOR_BROWN }) + expect.eq(pen.fg, COLOR_GREEN) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BROWN) + + local pen2 = dfhack.pen.make{ fg = COLOR_GREEN, bg = COLOR_BROWN } + pen = dfhack.pen.make({ fg = COLOR_LIGHTRED, bg = COLOR_BLUE }, pen2) + expect.eq(pen.fg, COLOR_GREEN) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BROWN) +end + +function test.make_base_pen_pen() + local base = dfhack.pen.make{ fg = COLOR_RED, bg = COLOR_BLUE } + local pen_table = { fg = COLOR_LIGHTGREEN, bg = COLOR_BROWN } + local pen = dfhack.pen.make(base, pen_table) + -- base is unchanged + expect.eq(base.fg, COLOR_RED) + expect.false_(base.bold) + expect.eq(base.bg, COLOR_BLUE) + -- pen has new values + expect.eq(pen.fg, COLOR_GREEN) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BROWN) + + pen = dfhack.pen.make(base, dfhack.pen.make(pen_table)) + expect.eq(pen.fg, COLOR_GREEN) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BROWN) +end + +-- tile_fg, tile_bg + +function test.make_base_table_tile_fg() + local pen = dfhack.pen.make{ tile_fg = COLOR_RED } + expect.eq(pen.tile_fg, COLOR_RED) + expect.eq(pen.tile_bg, COLOR_BLACK) + expect.nil_(pen.tile_color) +end + +function test.make_base_table_tile_bg() + local pen = dfhack.pen.make{ tile_bg = COLOR_BLUE } + expect.eq(pen.tile_fg, COLOR_GREY) + expect.eq(pen.tile_bg, COLOR_BLUE) + expect.nil_(pen.tile_color) +end + +-- assign fields + +function test.assign_fg() + local pen = dfhack.pen.make{ fg = COLOR_RED, bg = COLOR_BLUE } + pen.fg = COLOR_GREEN + expect.eq(pen.fg, COLOR_GREEN) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + + -- assigning a "light" fg does not change bold + pen = dfhack.pen.make{ fg = COLOR_RED, bg = COLOR_BLUE } + pen.fg = COLOR_LIGHTGREEN + expect.eq(pen.fg, COLOR_LIGHTGREEN) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) +end + +function test.assign_bg() + local pen = dfhack.pen.make{ fg = COLOR_RED, bg = COLOR_BLUE } + pen.bg = COLOR_GREEN + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_GREEN) +end + +function test.assign_bold() + local pen = dfhack.pen.make{ fg = COLOR_RED, bg = COLOR_BLUE } + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + pen.bold = true + expect.eq(pen.fg, COLOR_RED) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + + pen = dfhack.pen.make{ fg = COLOR_LIGHTRED, bg = COLOR_BLUE } + expect.eq(pen.fg, COLOR_RED) + expect.true_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + pen.bold = false + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) +end + +function test.assign_tile_fg() + local pen = dfhack.pen.make{ fg = COLOR_RED, bg = COLOR_BLUE, tile_color = true } + pen.tile_fg = COLOR_GREEN + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + expect.eq(pen.tile_fg, COLOR_GREEN) + expect.eq(pen.tile_bg, COLOR_BLACK) + expect.nil_(pen.tile_color) + + pen = dfhack.pen.make{ tile_fg = COLOR_RED, tile_bg = COLOR_BLUE, tile_color = true } + pen.tile_fg = COLOR_GREEN + expect.eq(pen.fg, COLOR_GREY) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + expect.eq(pen.tile_fg, COLOR_GREEN) + expect.eq(pen.tile_bg, COLOR_BLUE) + expect.nil_(pen.tile_color) +end + +function test.assign_tile_bg() + local pen = dfhack.pen.make{ fg = COLOR_RED, bg = COLOR_BLUE, tile_color = true } + pen.tile_bg = COLOR_GREEN + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + expect.eq(pen.tile_fg, COLOR_GREY) + expect.eq(pen.tile_bg, COLOR_GREEN) + expect.nil_(pen.tile_color) + + pen = dfhack.pen.make{ tile_fg = COLOR_RED, tile_bg = COLOR_BLUE, tile_color = true } + pen.tile_bg = COLOR_GREEN + expect.eq(pen.fg, COLOR_GREY) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + expect.eq(pen.tile_fg, COLOR_RED) + expect.eq(pen.tile_bg, COLOR_GREEN) + expect.nil_(pen.tile_color) +end + +function test.assign_tile_color() + local tile = { tile_fg = COLOR_RED, tile_bg = COLOR_BLUE } + local pen = dfhack.pen.make(tile) + expect.eq(pen.fg, COLOR_GREY) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + expect.eq(pen.tile_fg, COLOR_RED) + expect.eq(pen.tile_bg, COLOR_BLUE) + expect.nil_(pen.tile_color) + + pen.tile_color = true + expect.eq(pen.fg, COLOR_GREY) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + expect.nil_(pen.tile_fg) + expect.nil_(pen.tile_bg) + expect.true_(pen.tile_color) + + + pen = dfhack.pen.make(tile) + pen.tile_color = false + expect.eq(pen.fg, COLOR_GREY) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLACK) + expect.nil_(pen.tile_fg) + expect.nil_(pen.tile_bg) + expect.false_(pen.tile_color) + + + pen = dfhack.pen.make({ fg = COLOR_RED, bg = COLOR_BLUE, tile_color = true }) + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + expect.nil_(pen.tile_fg) + expect.nil_(pen.tile_bg) + expect.true_(pen.tile_color) + + pen.tile_color = false + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + expect.nil_(pen.tile_fg) + expect.nil_(pen.tile_bg) + expect.false_(pen.tile_color) + + + pen = dfhack.pen.make({ fg = COLOR_RED, bg = COLOR_BLUE, tile_color = false }) + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + expect.nil_(pen.tile_fg) + expect.nil_(pen.tile_bg) + expect.false_(pen.tile_color) + + pen.tile_color = true + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + expect.nil_(pen.tile_fg) + expect.nil_(pen.tile_bg) + expect.true_(pen.tile_color) + + + -- a bit odd w.r.t usual Lua semantics: assigning nil to tile_color works like false + pen = dfhack.pen.make({ fg = COLOR_RED, bg = COLOR_BLUE, tile_color = true }) + pen.tile_color = nil + expect.eq(pen.fg, COLOR_RED) + expect.false_(pen.bold) + expect.eq(pen.bg, COLOR_BLUE) + expect.nil_(pen.tile_fg) + expect.nil_(pen.tile_bg) + expect.false_(pen.tile_color) +end + +-- COLOR_RESET should translate to "default" colors + +function test.make_base_reset() + local pen = dfhack.pen.make(COLOR_RESET) + expect.eq(pen.fg, COLOR_GREY) + expect.eq(pen.bg, COLOR_BLACK) +end + +function test.make_pen_reset() + local base = dfhack.pen.make{ fg = COLOR_RED, bg = COLOR_BLUE } + local pen = dfhack.pen.make(base, COLOR_RESET) + expect.eq(pen.fg, COLOR_GREY) + expect.eq(pen.bg, COLOR_BLUE) +end + +function test.make_bg_reset() + local base = dfhack.pen.make{ fg = COLOR_RED, bg = COLOR_BLUE } + local pen = dfhack.pen.make(base, nil, COLOR_RESET) + expect.eq(pen.fg, COLOR_RED) + expect.eq(pen.bg, COLOR_BLACK) +end + +function test.make_pen_table_fg_reset() + local pen = dfhack.pen.make{ fg = COLOR_RESET } + expect.eq(pen.fg, COLOR_GREY) + expect.eq(pen.bg, COLOR_BLACK) +end + +function test.make_pen_table_bg_reset() + local pen = dfhack.pen.make{ bg = COLOR_RESET } + expect.eq(pen.fg, COLOR_GREY) + expect.eq(pen.bg, COLOR_BLACK) +end + +function test.assign_fg_reset() + local pen = dfhack.pen.make{ fg = COLOR_RED, bg = COLOR_BLUE } + pen.fg = COLOR_RESET + expect.eq(pen.fg, COLOR_GREY) + expect.eq(pen.bg, COLOR_BLUE) +end + +function test.assign_bg_reset() + local pen = dfhack.pen.make{ fg = COLOR_RED, bg = COLOR_BLUE } + pen.bg = COLOR_RESET + expect.eq(pen.fg, COLOR_RED) + expect.eq(pen.bg, COLOR_BLACK) +end + +function test.make_pen_table_tile_fg_reset() + local pen = dfhack.pen.make{ tile_fg = COLOR_RESET } + expect.eq(pen.tile_fg, COLOR_GREY) + expect.eq(pen.tile_bg, COLOR_BLACK) +end + +function test.make_pen_table_tile_bg_reset() + local pen = dfhack.pen.make{ tile_bg = COLOR_RESET } + expect.eq(pen.tile_fg, COLOR_GREY) + expect.eq(pen.tile_bg, COLOR_BLACK) +end + +function test.assign_tile_fg_reset() + local pen = dfhack.pen.make{ tile_fg = COLOR_RED, tile_bg = COLOR_BLUE } + pen.tile_fg = COLOR_RESET + expect.eq(pen.tile_fg, COLOR_GREY) + expect.eq(pen.tile_bg, COLOR_BLUE) +end + +function test.assign_tile_bg_reset() + local pen = dfhack.pen.make{ tile_fg = COLOR_RED, tile_bg = COLOR_BLUE } + pen.tile_bg = COLOR_RESET + expect.eq(pen.tile_fg, COLOR_RED) + expect.eq(pen.tile_bg, COLOR_BLACK) +end