Skip to content

Commit 28438bb

Browse files
committedOct 5, 2014
Add [colorize modifier
1 parent 173beee commit 28438bb

File tree

7 files changed

+138
-99
lines changed

7 files changed

+138
-99
lines changed
 

‎doc/lua_api.txt

+18-14
Original file line numberDiff line numberDiff line change
@@ -262,6 +262,10 @@ Advanced texture modifiers:
262262
Apply a mask to the base image.
263263
The mask is applied using binary AND.
264264

265+
[colorize:<color>
266+
Colorize the textures with given color
267+
<color> as ColorString
268+
265269
Sounds
266270
-------
267271
Only OGG Vorbis files are supported.
@@ -985,25 +989,25 @@ list[<inventory location>;<list name>;<X>,<Y>;<W>,<H>;<starting item index>]
985989
^ Show an inventory list
986990

987991
listcolors[<slot_bg_normal>;<slot_bg_hover>]
988-
^ Sets background color of slots in HEX-Color format
992+
^ Sets background color of slots as ColorString
989993
^ Sets background color of slots on mouse hovering
990994

991995
listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>]
992-
^ Sets background color of slots in HEX-Color format
996+
^ Sets background color of slots as ColorString
993997
^ Sets background color of slots on mouse hovering
994998
^ Sets color of slots border
995999

9961000
listcolors[<slot_bg_normal>;<slot_bg_hover>;<slot_border>;<tooltip_bgcolor>;<tooltip_fontcolor>]
997-
^ Sets background color of slots in HEX-Color format
1001+
^ Sets background color of slots as ColorString
9981002
^ Sets background color of slots on mouse hovering
9991003
^ Sets color of slots border
10001004
^ Sets default background color of tooltips
10011005
^ Sets default font color of tooltips
10021006

10031007
tooltip[<gui_element_name>;<tooltip_text>;<bgcolor>,<fontcolor>]
10041008
^ Adds tooltip for an element
1005-
^ <bgcolor> tooltip background color in HEX-Color format (optional)
1006-
^ <fontcolor> tooltip font color in HEX-Color format (optional)
1009+
^ <bgcolor> tooltip background color as ColorString (optional)
1010+
^ <fontcolor> tooltip font color as ColorString (optional)
10071011

10081012

10091013
image[<X>,<Y>;<W>,<H>;<texture name>]
@@ -1015,7 +1019,7 @@ item_image[<X>,<Y>;<W>,<H>;<item name>]
10151019
^ Position and size units are inventory slots
10161020

10171021
bgcolor[<color>;<fullscreen>]
1018-
^ Sets background color of formspec in HEX-Color format
1022+
^ Sets background color of formspec as ColorString
10191023
^ If true the background color is drawn fullscreen (does not effect the size of the formspec)
10201024

10211025
background[<X>,<Y>;<W>,<H>;<texture name>]
@@ -1136,7 +1140,7 @@ box[<X>,<Y>;<W>,<H>;<color>]
11361140
^ simple colored semitransparent box
11371141
^ x and y position the box relative to the top left of the menu
11381142
^ w and h are the size of box
1139-
^ color in HEX-Color format
1143+
^ color as ColorString
11401144

11411145
dropdown[<X>,<Y>;<W>;<name>;<item 1>,<item 2>, ...,<item n>;<selected idx>]
11421146
^ show a dropdown field
@@ -1182,15 +1186,15 @@ table[<X>,<Y>;<W>,<H>;<name>;<cell 1>,<cell 2>,...,<cell n>;<selected idx>]
11821186
tableoptions[<opt 1>;<opt 2>;...]
11831187
^ sets options for table[]:
11841188
^ color=#RRGGBB
1185-
^^ default text color (HEX-Color), defaults to #FFFFFF
1189+
^^ default text color (ColorString), defaults to #FFFFFF
11861190
^ background=#RRGGBB
1187-
^^ table background color (HEX-Color), defaults to #000000
1191+
^^ table background color (ColorString), defaults to #000000
11881192
^ border=<true/false>
11891193
^^ should the table be drawn with a border? (default true)
11901194
^ highlight=#RRGGBB
1191-
^^ highlight background color (HEX-Color), defaults to #466432
1195+
^^ highlight background color (ColorString), defaults to #466432
11921196
^ highlight_text=#RRGGBB
1193-
^^ highlight text color (HEX-Color), defaults to #FFFFFF
1197+
^^ highlight text color (ColorString), defaults to #FFFFFF
11941198
^ opendepth=<value>
11951199
^^ all subtrees up to depth < value are open (default value = 0)
11961200
^^ 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>;...]
12001204
^ types: text, image, color, indent, tree
12011205
^^ text: show cell contents as text
12021206
^^ image: cell contents are an image index, use column options to define images
1203-
^^ color: cell contents are a HEX-Color and define color of following cell
1207+
^^ color: cell contents are a ColorString and define color of following cell
12041208
^^ indent: cell contents are a number and define indentation of following cell
12051209
^^ tree: same as indent, but user can open and close subtrees (treeview-like)
12061210
^ column options:
@@ -1231,8 +1235,8 @@ Inventory location:
12311235
- "nodemeta:<X>,<Y>,<Z>": Any node metadata
12321236
- "detached:<name>": A detached inventory
12331237

1234-
HEX-Color
1235-
---------
1238+
ColorString
1239+
-----------
12361240
#RGB
12371241
^ defines a color in hexadecimal format
12381242
#RGBA

‎src/guiFormSpecMenu.cpp

+9-72
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
5050
#include "main.h"
5151
#include "settings.h"
5252
#include "client.h"
53+
#include "util/string.h" // for parseColorString()
5354

5455
#define MY_CHECKPOS(a,b) \
5556
if (v_pos.size() != 2) { \
@@ -1575,7 +1576,7 @@ void GUIFormSpecMenu::parseBox(parserData* data,std::string element)
15751576

15761577
video::SColor tmp_color;
15771578

1578-
if (parseColor(parts[2], tmp_color, false)) {
1579+
if (parseColorString(parts[2], tmp_color, false)) {
15791580
BoxDrawSpec spec(pos, geom, tmp_color);
15801581

15811582
m_boxes.push_back(spec);
@@ -1595,7 +1596,7 @@ void GUIFormSpecMenu::parseBackgroundColor(parserData* data,std::string element)
15951596
if (((parts.size() == 1) || (parts.size() == 2)) ||
15961597
((parts.size() > 2) && (m_formspec_version > FORMSPEC_API_VERSION)))
15971598
{
1598-
parseColor(parts[0],m_bgcolor,false);
1599+
parseColorString(parts[0],m_bgcolor,false);
15991600

16001601
if (parts.size() == 2) {
16011602
std::string fullscreen = parts[1];
@@ -1613,20 +1614,20 @@ void GUIFormSpecMenu::parseListColors(parserData* data,std::string element)
16131614
if (((parts.size() == 2) || (parts.size() == 3) || (parts.size() == 5)) ||
16141615
((parts.size() > 5) && (m_formspec_version > FORMSPEC_API_VERSION)))
16151616
{
1616-
parseColor(parts[0], m_slotbg_n, false);
1617-
parseColor(parts[1], m_slotbg_h, false);
1617+
parseColorString(parts[0], m_slotbg_n, false);
1618+
parseColorString(parts[1], m_slotbg_h, false);
16181619

16191620
if (parts.size() >= 3) {
1620-
if (parseColor(parts[2], m_slotbordercolor, false)) {
1621+
if (parseColorString(parts[2], m_slotbordercolor, false)) {
16211622
m_slotborder = true;
16221623
}
16231624
}
16241625
if (parts.size() == 5) {
16251626
video::SColor tmp_color;
16261627

1627-
if (parseColor(parts[3], tmp_color, false))
1628+
if (parseColorString(parts[3], tmp_color, false))
16281629
m_default_tooltip_bgcolor = tmp_color;
1629-
if (parseColor(parts[4], tmp_color, false))
1630+
if (parseColorString(parts[4], tmp_color, false))
16301631
m_default_tooltip_color = tmp_color;
16311632
}
16321633
return;
@@ -1644,7 +1645,7 @@ void GUIFormSpecMenu::parseTooltip(parserData* data, std::string element)
16441645
} else if (parts.size() == 4) {
16451646
std::string name = parts[0];
16461647
video::SColor tmp_color1, tmp_color2;
1647-
if ( parseColor(parts[2], tmp_color1, false) && parseColor(parts[3], tmp_color2, false) ) {
1648+
if ( parseColorString(parts[2], tmp_color1, false) && parseColorString(parts[3], tmp_color2, false) ) {
16481649
m_tooltips[narrow_to_wide(name.c_str())] = TooltipSpec (parts[1], tmp_color1, tmp_color2);
16491650
return;
16501651
}
@@ -3388,67 +3389,3 @@ std::wstring GUIFormSpecMenu::getLabelByID(s32 id)
33883389
}
33893390
return L"";
33903391
}
3391-
3392-
bool GUIFormSpecMenu::parseColor(const std::string &value, video::SColor &color,
3393-
bool quiet)
3394-
{
3395-
const char *hexpattern = NULL;
3396-
if (value[0] == '#') {
3397-
if (value.size() == 9)
3398-
hexpattern = "#RRGGBBAA";
3399-
else if (value.size() == 7)
3400-
hexpattern = "#RRGGBB";
3401-
else if (value.size() == 5)
3402-
hexpattern = "#RGBA";
3403-
else if (value.size() == 4)
3404-
hexpattern = "#RGB";
3405-
}
3406-
3407-
if (hexpattern) {
3408-
assert(strlen(hexpattern) == value.size());
3409-
video::SColor outcolor(255, 255, 255, 255);
3410-
for (size_t pos = 0; pos < value.size(); ++pos) {
3411-
// '#' in the pattern means skip that character
3412-
if (hexpattern[pos] == '#')
3413-
continue;
3414-
3415-
// Else assume hexpattern[pos] is one of 'R' 'G' 'B' 'A'
3416-
// Read one or two digits, depending on hexpattern
3417-
unsigned char c1, c2;
3418-
if (hexpattern[pos+1] == hexpattern[pos]) {
3419-
// Two digits, e.g. hexpattern == "#RRGGBB"
3420-
if (!hex_digit_decode(value[pos], c1) ||
3421-
!hex_digit_decode(value[pos+1], c2))
3422-
goto fail;
3423-
++pos;
3424-
}
3425-
else {
3426-
// One digit, e.g. hexpattern == "#RGB"
3427-
if (!hex_digit_decode(value[pos], c1))
3428-
goto fail;
3429-
c2 = c1;
3430-
}
3431-
u32 colorpart = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
3432-
3433-
// Update outcolor with newly read color part
3434-
if (hexpattern[pos] == 'R')
3435-
outcolor.setRed(colorpart);
3436-
else if (hexpattern[pos] == 'G')
3437-
outcolor.setGreen(colorpart);
3438-
else if (hexpattern[pos] == 'B')
3439-
outcolor.setBlue(colorpart);
3440-
else if (hexpattern[pos] == 'A')
3441-
outcolor.setAlpha(colorpart);
3442-
}
3443-
3444-
color = outcolor;
3445-
return true;
3446-
}
3447-
3448-
// Optionally, named colors could be implemented here
3449-
3450-
fail:
3451-
if (!quiet)
3452-
errorstream<<"Invalid color: \""<<value<<"\""<<std::endl;
3453-
return false;
3454-
}

‎src/guiFormSpecMenu.h

-3
Original file line numberDiff line numberDiff line change
@@ -274,9 +274,6 @@ class GUIFormSpecMenu : public GUIModalMenu
274274

275275
GUITable* getTable(std::wstring tablename);
276276

277-
static bool parseColor(const std::string &value,
278-
video::SColor &color, bool quiet);
279-
280277
#ifdef __ANDROID__
281278
bool getAndroidUIInput();
282279
#endif

‎src/guiTable.cpp

+7-7
Original file line numberDiff line numberDiff line change
@@ -32,7 +32,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3232
#include "gettime.h"
3333
#include "util/string.h"
3434
#include "util/numeric.h"
35-
#include "guiFormSpecMenu.h" // for parseColor()
35+
#include "util/string.h" // for parseColorString()
3636
#include "main.h"
3737
#include "settings.h" // for settings
3838
#include "porting.h" // for dpi
@@ -164,7 +164,7 @@ void GUITable::setTextList(const std::vector<std::string> &content,
164164
cell->content_index = allocString(s.substr(2));
165165
}
166166
else if (s[0] == '#' && s.size() >= 7 &&
167-
GUIFormSpecMenu::parseColor(
167+
parseColorString(
168168
s.substr(0,7), cell->color, false)) {
169169
// single # for color
170170
cell->color_defined = true;
@@ -211,15 +211,15 @@ void GUITable::setTable(const TableOptions &options,
211211
const std::string &name = options[k].name;
212212
const std::string &value = options[k].value;
213213
if (name == "color")
214-
GUIFormSpecMenu::parseColor(value, m_color, false);
214+
parseColorString(value, m_color, false);
215215
else if (name == "background")
216-
GUIFormSpecMenu::parseColor(value, m_background, false);
216+
parseColorString(value, m_background, false);
217217
else if (name == "border")
218218
m_border = is_yes(value);
219219
else if (name == "highlight")
220-
GUIFormSpecMenu::parseColor(value, m_highlight, false);
220+
parseColorString(value, m_highlight, false);
221221
else if (name == "highlight_text")
222-
GUIFormSpecMenu::parseColor(value, m_highlight_text, false);
222+
parseColorString(value, m_highlight_text, false);
223223
else if (name == "opendepth")
224224
opendepth = stoi(value);
225225
else
@@ -416,7 +416,7 @@ void GUITable::setTable(const TableOptions &options,
416416
else if (columntype == COLUMN_TYPE_COLOR) {
417417
for (s32 i = 0; i < rowcount; ++i) {
418418
video::SColor cellcolor(255, 255, 255, 255);
419-
if (GUIFormSpecMenu::parseColor(content[i * colcount + j], cellcolor, true))
419+
if (parseColorString(content[i * colcount + j], cellcolor, true))
420420
rows[i].colors.push_back(std::make_pair(cellcolor, j+span));
421421
}
422422
}

‎src/tile.cpp

+39-2
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
3333
#include "log.h"
3434
#include "gamedef.h"
3535
#include "strfnd.h"
36+
#include "util/string.h" // for parseColorString()
3637

3738
#ifdef __ANDROID__
3839
#include <GLES/gl.h>
@@ -1588,10 +1589,46 @@ bool TextureSource::generateImagePart(std::string part_of_name,
15881589
<< filename << "\".";
15891590
}
15901591
}
1592+
/*
1593+
[colorize:color
1594+
Overlays image with given color
1595+
color = color as ColorString
1596+
*/
1597+
else if (part_of_name.substr(0,10) == "[colorize:") {
1598+
Strfnd sf(part_of_name);
1599+
sf.next(":");
1600+
std::string color_str = sf.next(":");
1601+
1602+
if (baseimg == NULL) {
1603+
errorstream << "generateImagePart(): baseimg != NULL "
1604+
<< "for part_of_name=\"" << part_of_name
1605+
<< "\", cancelling." << std::endl;
1606+
return false;
1607+
}
1608+
1609+
video::SColor color;
1610+
if (!parseColorString(color_str, color, false))
1611+
return false;
1612+
1613+
core::dimension2d<u32> dim = baseimg->getDimension();
1614+
video::IImage *img = driver->createImage(video::ECF_A8R8G8B8, dim);
1615+
1616+
if (!img) {
1617+
errorstream << "generateImagePart(): Could not create image "
1618+
<< "for part_of_name=\"" << part_of_name
1619+
<< "\", cancelling." << std::endl;
1620+
return false;
1621+
}
1622+
1623+
img->fill(video::SColor(color));
1624+
// Overlay the colored image
1625+
blit_with_alpha_overlay(img, baseimg, v2s32(0,0), v2s32(0,0), dim);
1626+
img->drop();
1627+
}
15911628
else
15921629
{
1593-
errorstream<<"generateImagePart(): Invalid "
1594-
" modification: \""<<part_of_name<<"\""<<std::endl;
1630+
errorstream << "generateImagePart(): Invalid "
1631+
" modification: \"" << part_of_name << "\"" << std::endl;
15951632
}
15961633
}
15971634

‎src/util/string.cpp

+63
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2020
#include "string.h"
2121
#include "pointer.h"
2222
#include "numeric.h"
23+
#include "log.h"
2324

2425
#include <sstream>
2526
#include <iomanip>
@@ -303,3 +304,65 @@ u64 read_seed(const char *str)
303304

304305
return num;
305306
}
307+
308+
bool parseColorString(const std::string &value, video::SColor &color, bool quiet)
309+
{
310+
const char *hexpattern = NULL;
311+
video::SColor outcolor(255, 255, 255, 255);
312+
313+
if (value[0] == '#') {
314+
if (value.size() == 9)
315+
hexpattern = "#RRGGBBAA";
316+
else if (value.size() == 7)
317+
hexpattern = "#RRGGBB";
318+
else if (value.size() == 5)
319+
hexpattern = "#RGBA";
320+
else if (value.size() == 4)
321+
hexpattern = "#RGB";
322+
}
323+
324+
if (!hexpattern)
325+
goto fail;
326+
327+
assert(strlen(hexpattern) == value.size());
328+
for (size_t pos = 0; pos < value.size(); ++pos) {
329+
// '#' in the pattern means skip that character
330+
if (hexpattern[pos] == '#')
331+
continue;
332+
333+
// Else assume hexpattern[pos] is one of 'R' 'G' 'B' 'A'
334+
// Read one or two digits, depending on hexpattern
335+
unsigned char c1, c2;
336+
if (hexpattern[pos+1] == hexpattern[pos]) {
337+
// Two digits, e.g. hexpattern == "#RRGGBB"
338+
if (!hex_digit_decode(value[pos], c1) ||
339+
!hex_digit_decode(value[pos+1], c2))
340+
goto fail;
341+
++pos;
342+
} else {
343+
// One digit, e.g. hexpattern == "#RGB"
344+
if (!hex_digit_decode(value[pos], c1))
345+
goto fail;
346+
c2 = c1;
347+
}
348+
u32 colorpart = ((c1 & 0x0f) << 4) | (c2 & 0x0f);
349+
350+
// Update outcolor with newly read color part
351+
if (hexpattern[pos] == 'R')
352+
outcolor.setRed(colorpart);
353+
else if (hexpattern[pos] == 'G')
354+
outcolor.setGreen(colorpart);
355+
else if (hexpattern[pos] == 'B')
356+
outcolor.setBlue(colorpart);
357+
else if (hexpattern[pos] == 'A')
358+
outcolor.setAlpha(colorpart);
359+
}
360+
361+
color = outcolor;
362+
return true;
363+
364+
fail:
365+
if (!quiet)
366+
errorstream << "Invalid color: \"" << value << "\"" << std::endl;
367+
return false;
368+
}

‎src/util/string.h

+2-1
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ with this program; if not, write to the Free Software Foundation, Inc.,
2020
#ifndef UTIL_STRING_HEADER
2121
#define UTIL_STRING_HEADER
2222

23-
#include "../irrlichttypes.h"
23+
#include "irrlichttypes_bloated.h"
2424
#include <stdlib.h>
2525
#include <string>
2626
#include <cstring>
@@ -349,6 +349,7 @@ std::string writeFlagString(u32 flags, const FlagDesc *flagdesc, u32 flagmask);
349349
size_t mystrlcpy(char *dst, const char *src, size_t size);
350350
char *mystrtok_r(char *s, const char *sep, char **lasts);
351351
u64 read_seed(const char *str);
352+
bool parseColorString(const std::string &value, video::SColor &color, bool quiet);
352353

353354
#endif
354355

0 commit comments

Comments
 (0)
Please sign in to comment.