Add [colorize modifier 1711/head
authorBlockMen <nmuelll@web.de>
Fri, 3 Oct 2014 04:11:21 +0000 (06:11 +0200)
committerBlockMen <nmuelll@web.de>
Sun, 5 Oct 2014 14:49:52 +0000 (16:49 +0200)
doc/lua_api.txt
src/guiFormSpecMenu.cpp
src/guiFormSpecMenu.h
src/guiTable.cpp
src/tile.cpp
src/util/string.cpp
src/util/string.h

index 4db0dc40f0b289f22534b47308a995d0ade89705..131a63fa55f480b2ddf1df398367bbeb91aa4911 100644 (file)
@@ -262,6 +262,10 @@ Advanced texture modifiers:
     Apply a mask to the base image.
     The mask is applied using binary AND.
 
+  [colorize:<color>
+    Colorize the textures with given color
+    <color> as ColorString
+
 Sounds
 -------
 Only OGG Vorbis files are supported.
@@ -985,16 +989,16 @@ list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]
 ^ Show an inventory list
 
 listcolors[<slot_bg_normal>;<slot_bg_hover>]
-^ Sets background color of slots in HEX-Color format
+^ Sets background color of slots as ColorString
 ^ Sets background color of slots on mouse hovering
 
 listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>]
-^ Sets background color of slots in HEX-Color format
+^ Sets background color of slots as ColorString
 ^ Sets background color of slots on mouse hovering
 ^ Sets color of slots border
 
 listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>;<tooltip_bgcolor>;<tooltip_fontcolor>]
-^ Sets background color of slots in HEX-Color format
+^ Sets background color of slots as ColorString
 ^ Sets background color of slots on mouse hovering
 ^ Sets color of slots border
 ^ Sets default background color of tooltips
@@ -1002,8 +1006,8 @@ listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>;<tooltip_bgcolor>;<too
 
 tooltip[<gui_element_name>;<tooltip_text>;<bgcolor>,<fontcolor>]
 ^ Adds tooltip for an element
-^ <bgcolor> tooltip background color in HEX-Color format (optional)
-^ <fontcolor> tooltip font color in HEX-Color format (optional)
+^ <bgcolor> tooltip background color as ColorString (optional)
+^ <fontcolor> tooltip font color as ColorString (optional)
 
 
 image[<X>,<Y>;<W>,<H>;<texture name>]
@@ -1015,7 +1019,7 @@ item_image[<X>,<Y>;<W>,<H>;<item name>]
 ^ Position and size units are inventory slots
 
 bgcolor[<color>;<fullscreen>]
-^ Sets background color of formspec in HEX-Color format
+^ Sets background color of formspec as ColorString
 ^ If true the background color is drawn fullscreen (does not effect the size of the formspec)
 
 background[<X>,<Y>;<W>,<H>;<texture name>]
@@ -1136,7 +1140,7 @@ box[<X>,<Y>;<W>,<H>;<color>]
 ^ simple colored semitransparent box
 ^ x and y position the box relative to the top left of the menu
 ^ w and h are the size of box
-^ color in HEX-Color format
+^ color as ColorString
 
 dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]
 ^ show a dropdown field
@@ -1182,15 +1186,15 @@ table[<X>,<Y>;<W>,<H>;<name>;<cell 1>,<cell 2>,...,<cell n>;<selected idx>]
 tableoptions[<opt 1>;<opt 2>;...]
 ^ sets options for table[]:
 ^ color=#RRGGBB
-^^ default text color (HEX-Color), defaults to #FFFFFF
+^^ default text color (ColorString), defaults to #FFFFFF
 ^ background=#RRGGBB
-^^ table background color (HEX-Color), defaults to #000000
+^^ table background color (ColorString), defaults to #000000
 ^ border=<true/false>
 ^^ should the table be drawn with a border? (default true)
 ^ highlight=#RRGGBB
-^^ highlight background color (HEX-Color), defaults to #466432
+^^ highlight background color (ColorString), defaults to #466432
 ^ highlight_text=#RRGGBB
-^^ highlight text color (HEX-Color), defaults to #FFFFFF
+^^ highlight text color (ColorString), defaults to #FFFFFF
 ^ opendepth=<value>
 ^^ all subtrees up to depth < value are open (default value = 0)
 ^^ only useful when there is a column of type "tree"
@@ -1200,7 +1204,7 @@ tablecolumns[<type 1>,<opt 1a>,<opt 1b>,...;<type 2>,<opt 2a>,<opt 2b>;...]
 ^ types: text, image, color, indent, tree
 ^^ text:   show cell contents as text
 ^^ image:  cell contents are an image index, use column options to define images
-^^ color:  cell contents are a HEX-Color and define color of following cell
+^^ color:  cell contents are a ColorString and define color of following cell
 ^^ indent: cell contents are a number and define indentation of following cell
 ^^ tree:   same as indent, but user can open and close subtrees (treeview-like)
 ^ column options:
@@ -1231,8 +1235,8 @@ Inventory location:
 - "nodemeta:<X>,<Y>,<Z>": Any node metadata
 - "detached:<name>": A detached inventory
 
-HEX-Color
----------
+ColorString
+-----------
 #RGB
 ^ defines a color in hexadecimal format
 #RGBA
index f50fd15e59013e012ef69cf7bb28fd2df959ce6e..2439de7fad4c675ec38385c219ad9c7ce3187721 100644 (file)
@@ -50,6 +50,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "main.h"
 #include "settings.h"
 #include "client.h"
+#include "util/string.h" // for parseColorString()
 
 #define MY_CHECKPOS(a,b)                                                                                                       \
        if (v_pos.size() != 2) {                                                                                                \
@@ -1575,7 +1576,7 @@ void GUIFormSpecMenu::parseBox(parserData* data,std::string element)
 
                video::SColor tmp_color;
 
-               if (parseColor(parts[2], tmp_color, false)) {
+               if (parseColorString(parts[2], tmp_color, false)) {
                        BoxDrawSpec spec(pos, geom, tmp_color);
 
                        m_boxes.push_back(spec);
@@ -1595,7 +1596,7 @@ void GUIFormSpecMenu::parseBackgroundColor(parserData* data,std::string element)
        if (((parts.size() == 1) || (parts.size() == 2)) ||
                ((parts.size() > 2) && (m_formspec_version > FORMSPEC_API_VERSION)))
        {
-               parseColor(parts[0],m_bgcolor,false);
+               parseColorString(parts[0],m_bgcolor,false);
 
                if (parts.size() == 2) {
                        std::string fullscreen = parts[1];
@@ -1613,20 +1614,20 @@ void GUIFormSpecMenu::parseListColors(parserData* data,std::string element)
        if (((parts.size() == 2) || (parts.size() == 3) || (parts.size() == 5)) ||
                ((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION)))
        {
-               parseColor(parts[0], m_slotbg_n, false);
-               parseColor(parts[1], m_slotbg_h, false);
+               parseColorString(parts[0], m_slotbg_n, false);
+               parseColorString(parts[1], m_slotbg_h, false);
 
                if (parts.size() >= 3) {
-                       if (parseColor(parts[2], m_slotbordercolor, false)) {
+                       if (parseColorString(parts[2], m_slotbordercolor, false)) {
                                m_slotborder = true;
                        }
                }
                if (parts.size() == 5) {
                        video::SColor tmp_color;
 
-                       if (parseColor(parts[3], tmp_color, false))
+                       if (parseColorString(parts[3], tmp_color, false))
                                m_default_tooltip_bgcolor = tmp_color;
-                       if (parseColor(parts[4], tmp_color, false))
+                       if (parseColorString(parts[4], tmp_color, false))
                                m_default_tooltip_color = tmp_color;
                }
                return;
@@ -1644,7 +1645,7 @@ void GUIFormSpecMenu::parseTooltip(parserData* data, std::string element)
        } else if (parts.size() == 4) {
                std::string name = parts[0];
                video::SColor tmp_color1, tmp_color2;
-               if ( parseColor(parts[2], tmp_color1, false) && parseColor(parts[3], tmp_color2, false) ) {
+               if ( parseColorString(parts[2], tmp_color1, false) && parseColorString(parts[3], tmp_color2, false) ) {
                        m_tooltips[narrow_to_wide(name.c_str())] = TooltipSpec (parts[1], tmp_color1, tmp_color2);
                        return;
                }
@@ -3388,67 +3389,3 @@ std::wstring GUIFormSpecMenu::getLabelByID(s32 id)
        }
        return L"";
 }
-
-bool GUIFormSpecMenu::parseColor(const std::string &value, video::SColor &color,
-               bool quiet)
-{
-       const char *hexpattern = NULL;
-       if (value[0] == '#') {
-               if (value.size() == 9)
-                       hexpattern = "#RRGGBBAA";
-               else if (value.size() == 7)
-                       hexpattern = "#RRGGBB";
-               else if (value.size() == 5)
-                       hexpattern = "#RGBA";
-               else if (value.size() == 4)
-                       hexpattern = "#RGB";
-       }
-
-       if (hexpattern) {
-               assert(strlen(hexpattern) == value.size());
-               video::SColor outcolor(255, 255, 255, 255);
-               for (size_t pos = 0; pos < value.size(); ++pos) {
-                       // '#' in the pattern means skip that character
-                       if (hexpattern[pos] == '#')
-                               continue;
-
-                       // Else assume hexpattern[pos] is one of 'R' 'G' 'B' 'A'
-                       // Read one or two digits, depending on hexpattern
-                       unsigned char c1, c2;
-                       if (hexpattern[pos+1] == hexpattern[pos]) {
-                               // Two digits, e.g. hexpattern == "#RRGGBB"
-                               if (!hex_digit_decode(value[pos], c1) ||
-                                   !hex_digit_decode(value[pos+1], c2))
-                                       goto fail;
-                               ++pos;
-                       }
-                       else {
-                               // One digit, e.g. hexpattern == "#RGB"
-                               if (!hex_digit_decode(value[pos], c1))
-                                       goto fail;
-                               c2 = c1;
-                       }
-                       u32 colorpart = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
-
-                       // Update outcolor with newly read color part
-                       if (hexpattern[pos] == 'R')
-                               outcolor.setRed(colorpart);
-                       else if (hexpattern[pos] == 'G')
-                               outcolor.setGreen(colorpart);
-                       else if (hexpattern[pos] == 'B')
-                               outcolor.setBlue(colorpart);
-                       else if (hexpattern[pos] == 'A')
-                               outcolor.setAlpha(colorpart);
-               }
-
-               color = outcolor;
-               return true;
-       }
-
-       // Optionally, named colors could be implemented here
-
-fail:
-       if (!quiet)
-               errorstream<<"Invalid color: \""<<value<<"\""<<std::endl;
-       return false;
-}
index 2ffa05308af5d88974351ef67884fa05161f6d24..40be59b4660419532155fdcda50fc451358fe792 100644 (file)
@@ -274,9 +274,6 @@ public:
 
        GUITable* getTable(std::wstring tablename);
 
-       static bool parseColor(const std::string &value,
-                       video::SColor &color, bool quiet);
-
 #ifdef __ANDROID__
        bool getAndroidUIInput();
 #endif
index 1543497ab3c5bcb7433b11c71e8b1af22ea151f9..845c90122c51675f7d06383b6c3af6f743c7aca6 100644 (file)
@@ -32,7 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "gettime.h"
 #include "util/string.h"
 #include "util/numeric.h"
-#include "guiFormSpecMenu.h" // for parseColor()
+#include "util/string.h" // for parseColorString()
 #include "main.h"
 #include "settings.h" // for settings
 #include "porting.h" // for dpi
@@ -164,7 +164,7 @@ void GUITable::setTextList(const std::vector<std::string> &content,
                        cell->content_index = allocString(s.substr(2));
                }
                else if (s[0] == '#' && s.size() >= 7 &&
-                               GUIFormSpecMenu::parseColor(
+                               parseColorString(
                                        s.substr(0,7), cell->color, false)) {
                        // single # for color
                        cell->color_defined = true;
@@ -211,15 +211,15 @@ void GUITable::setTable(const TableOptions &options,
                const std::string &name = options[k].name;
                const std::string &value = options[k].value;
                if (name == "color")
-                       GUIFormSpecMenu::parseColor(value, m_color, false);
+                       parseColorString(value, m_color, false);
                else if (name == "background")
-                       GUIFormSpecMenu::parseColor(value, m_background, false);
+                       parseColorString(value, m_background, false);
                else if (name == "border")
                        m_border = is_yes(value);
                else if (name == "highlight")
-                       GUIFormSpecMenu::parseColor(value, m_highlight, false);
+                       parseColorString(value, m_highlight, false);
                else if (name == "highlight_text")
-                       GUIFormSpecMenu::parseColor(value, m_highlight_text, false);
+                       parseColorString(value, m_highlight_text, false);
                else if (name == "opendepth")
                        opendepth = stoi(value);
                else
@@ -416,7 +416,7 @@ void GUITable::setTable(const TableOptions &options,
                else if (columntype == COLUMN_TYPE_COLOR) {
                        for (s32 i = 0; i < rowcount; ++i) {
                                video::SColor cellcolor(255, 255, 255, 255);
-                               if (GUIFormSpecMenu::parseColor(content[i * colcount + j], cellcolor, true))
+                               if (parseColorString(content[i * colcount + j], cellcolor, true))
                                        rows[i].colors.push_back(std::make_pair(cellcolor, j+span));
                        }
                }
index ebef77fb9cbe148010b2688a3ff98a04c5023e38..fa2f4c84e56c519c7dca694437fa81176a053ef9 100644 (file)
@@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "log.h"
 #include "gamedef.h"
 #include "strfnd.h"
+#include "util/string.h" // for parseColorString()
 
 #ifdef __ANDROID__
 #include <GLES/gl.h>
@@ -1588,10 +1589,46 @@ bool TextureSource::generateImagePart(std::string part_of_name,
                                                << filename << "\".";
                        }
                }
+               /*
+                       [colorize:color
+                       Overlays image with given color
+                       color = color as ColorString
+               */
+               else if (part_of_name.substr(0,10) == "[colorize:") {
+                       Strfnd sf(part_of_name);
+                       sf.next(":");
+                       std::string color_str = sf.next(":");
+
+                       if (baseimg == NULL) {
+                               errorstream << "generateImagePart(): baseimg != NULL "
+                                               << "for part_of_name=\"" << part_of_name
+                                               << "\", cancelling." << std::endl;
+                               return false;
+                       }
+
+                       video::SColor color;
+                       if (!parseColorString(color_str, color, false))
+                               return false;
+                       
+                       core::dimension2d<u32> dim = baseimg->getDimension();
+                       video::IImage *img = driver->createImage(video::ECF_A8R8G8B8, dim);
+
+                       if (!img) {
+                               errorstream << "generateImagePart(): Could not create image "
+                                               << "for part_of_name=\"" << part_of_name
+                                               << "\", cancelling." << std::endl;
+                               return false;
+                       }
+
+                       img->fill(video::SColor(color));
+                       // Overlay the colored image
+                       blit_with_alpha_overlay(img, baseimg, v2s32(0,0), v2s32(0,0), dim);
+                       img->drop();
+               }
                else
                {
-                       errorstream<<"generateImagePart(): Invalid "
-                                       " modification: \""<<part_of_name<<"\""<<std::endl;
+                       errorstream << "generateImagePart(): Invalid "
+                                       " modification: \"" << part_of_name << "\"" << std::endl;
                }
        }
 
index 5ba97afd515ecb03656418f1cb651c6440766d2d..57545aa20a710cc5db4547c30c3fc244ff60ca75 100644 (file)
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #include "string.h"
 #include "pointer.h"
 #include "numeric.h"
+#include "log.h"
 
 #include <sstream>
 #include <iomanip>
@@ -303,3 +304,65 @@ u64 read_seed(const char *str)
                
        return num;
 }
+
+bool parseColorString(const std::string &value, video::SColor &color, bool quiet)
+{
+       const char *hexpattern = NULL;
+       video::SColor outcolor(255, 255, 255, 255);
+
+       if (value[0] == '#') {
+               if (value.size() == 9)
+                       hexpattern = "#RRGGBBAA";
+               else if (value.size() == 7)
+                       hexpattern = "#RRGGBB";
+               else if (value.size() == 5)
+                       hexpattern = "#RGBA";
+               else if (value.size() == 4)
+                       hexpattern = "#RGB";
+       }
+
+       if (!hexpattern)
+               goto fail;
+
+       assert(strlen(hexpattern) == value.size());
+       for (size_t pos = 0; pos < value.size(); ++pos) {
+               // '#' in the pattern means skip that character
+               if (hexpattern[pos] == '#')
+                       continue;
+
+               // Else assume hexpattern[pos] is one of 'R' 'G' 'B' 'A'
+               // Read one or two digits, depending on hexpattern
+               unsigned char c1, c2;
+               if (hexpattern[pos+1] == hexpattern[pos]) {
+                       // Two digits, e.g. hexpattern == "#RRGGBB"
+                       if (!hex_digit_decode(value[pos], c1) ||
+                                  !hex_digit_decode(value[pos+1], c2))
+                               goto fail;
+                       ++pos;
+               } else {
+                       // One digit, e.g. hexpattern == "#RGB"
+                       if (!hex_digit_decode(value[pos], c1))
+                               goto fail;
+                       c2 = c1;
+               }
+               u32 colorpart = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
+
+               // Update outcolor with newly read color part
+               if (hexpattern[pos] == 'R')
+                       outcolor.setRed(colorpart);
+               else if (hexpattern[pos] == 'G')
+                       outcolor.setGreen(colorpart);
+               else if (hexpattern[pos] == 'B')
+                       outcolor.setBlue(colorpart);
+               else if (hexpattern[pos] == 'A')
+                       outcolor.setAlpha(colorpart);
+       }
+
+       color = outcolor;
+       return true;
+
+fail:
+       if (!quiet)
+               errorstream << "Invalid color: \"" << value << "\"" << std::endl;
+       return false;
+}
index 54a5a458eaa5124ebfe7aaf1f6e03a1234235b00..e46fbf4e9b2a48e3682eee3a317927290079cc13 100644 (file)
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
 #ifndef UTIL_STRING_HEADER
 #define UTIL_STRING_HEADER
 
-#include "../irrlichttypes.h"
+#include "irrlichttypes_bloated.h"
 #include <stdlib.h>
 #include <string>
 #include <cstring>
@@ -349,6 +349,7 @@ std::string writeFlagString(u32 flags, const FlagDesc *flagdesc, u32 flagmask);
 size_t mystrlcpy(char *dst, const char *src, size_t size);
 char *mystrtok_r(char *s, const char *sep, char **lasts);
 u64 read_seed(const char *str);
+bool parseColorString(const std::string &value, video::SColor &color, bool quiet);
 
 #endif