mirror of
https://github.com/vcmi/vcmi.git
synced 2025-08-13 19:54:17 +02:00
2
Global.h
2
Global.h
@@ -122,6 +122,7 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
|
|||||||
#include <optional>
|
#include <optional>
|
||||||
#include <queue>
|
#include <queue>
|
||||||
#include <random>
|
#include <random>
|
||||||
|
#include <regex>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <sstream>
|
#include <sstream>
|
||||||
#include <string>
|
#include <string>
|
||||||
@@ -147,6 +148,7 @@ static_assert(sizeof(bool) == 1, "Bool needs to be 1 byte in size.");
|
|||||||
#define BOOST_ASIO_ENABLE_OLD_SERVICES
|
#define BOOST_ASIO_ENABLE_OLD_SERVICES
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#include <boost/algorithm/hex.hpp>
|
||||||
#include <boost/algorithm/string.hpp>
|
#include <boost/algorithm/string.hpp>
|
||||||
#include <boost/crc.hpp>
|
#include <boost/crc.hpp>
|
||||||
#include <boost/current_function.hpp>
|
#include <boost/current_function.hpp>
|
||||||
|
@@ -10,6 +10,7 @@
|
|||||||
|
|
||||||
#include "StdInc.h"
|
#include "StdInc.h"
|
||||||
#include "Colors.h"
|
#include "Colors.h"
|
||||||
|
#include "../../lib/JsonNode.h"
|
||||||
|
|
||||||
const ColorRGBA Colors::YELLOW = { 229, 215, 123, ColorRGBA::ALPHA_OPAQUE };
|
const ColorRGBA Colors::YELLOW = { 229, 215, 123, ColorRGBA::ALPHA_OPAQUE };
|
||||||
const ColorRGBA Colors::WHITE = { 255, 243, 222, ColorRGBA::ALPHA_OPAQUE };
|
const ColorRGBA Colors::WHITE = { 255, 243, 222, ColorRGBA::ALPHA_OPAQUE };
|
||||||
@@ -23,3 +24,29 @@ const ColorRGBA Colors::RED = {255, 0, 0, ColorRGBA::ALPHA_OPAQUE};
|
|||||||
const ColorRGBA Colors::PURPLE = {255, 75, 125, ColorRGBA::ALPHA_OPAQUE};
|
const ColorRGBA Colors::PURPLE = {255, 75, 125, ColorRGBA::ALPHA_OPAQUE};
|
||||||
const ColorRGBA Colors::BLACK = {0, 0, 0, ColorRGBA::ALPHA_OPAQUE};
|
const ColorRGBA Colors::BLACK = {0, 0, 0, ColorRGBA::ALPHA_OPAQUE};
|
||||||
const ColorRGBA Colors::TRANSPARENCY = {0, 0, 0, ColorRGBA::ALPHA_TRANSPARENT};
|
const ColorRGBA Colors::TRANSPARENCY = {0, 0, 0, ColorRGBA::ALPHA_TRANSPARENT};
|
||||||
|
|
||||||
|
std::optional<ColorRGBA> Colors::parseColor(std::string text)
|
||||||
|
{
|
||||||
|
std::smatch match;
|
||||||
|
std::regex expr("^#([0-9a-fA-F]{6})$");
|
||||||
|
ui8 rgb[3] = {0, 0, 0};
|
||||||
|
if(std::regex_search(text, match, expr))
|
||||||
|
{
|
||||||
|
std::string tmp = boost::algorithm::unhex(match[1].str());
|
||||||
|
std::copy(tmp.begin(), tmp.end(), rgb);
|
||||||
|
return ColorRGBA(rgb[0], rgb[1], rgb[2]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static const JsonNode config(JsonPath::builtin("CONFIG/textColors"));
|
||||||
|
auto colors = config["colors"].Struct();
|
||||||
|
for(auto & color : colors) {
|
||||||
|
if(boost::algorithm::to_lower_copy(color.first) == boost::algorithm::to_lower_copy(text))
|
||||||
|
{
|
||||||
|
std::string tmp = boost::algorithm::unhex(color.second.String());
|
||||||
|
std::copy(tmp.begin(), tmp.end(), rgb);
|
||||||
|
return ColorRGBA(rgb[0], rgb[1], rgb[2]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return std::nullopt;
|
||||||
|
}
|
@@ -49,4 +49,7 @@ public:
|
|||||||
static const ColorRGBA BLACK;
|
static const ColorRGBA BLACK;
|
||||||
|
|
||||||
static const ColorRGBA TRANSPARENCY;
|
static const ColorRGBA TRANSPARENCY;
|
||||||
|
|
||||||
|
/// parse color
|
||||||
|
static std::optional<ColorRGBA> parseColor(std::string text);
|
||||||
};
|
};
|
||||||
|
@@ -153,6 +153,17 @@ void CTextContainer::blitLine(Canvas & to, Rect destRect, std::string what)
|
|||||||
//We should count delimiters length from string to correct centering later.
|
//We should count delimiters length from string to correct centering later.
|
||||||
delimitersCount *= f->getStringWidth(delimeters)/2;
|
delimitersCount *= f->getStringWidth(delimeters)/2;
|
||||||
|
|
||||||
|
std::smatch match;
|
||||||
|
std::regex expr("\\{(.*?)\\|");
|
||||||
|
std::string::const_iterator searchStart( what.cbegin() );
|
||||||
|
while(std::regex_search(searchStart, what.cend(), match, expr))
|
||||||
|
{
|
||||||
|
std::string colorText = match[1].str();
|
||||||
|
if(auto c = Colors::parseColor(colorText))
|
||||||
|
delimitersCount += f->getStringWidth(colorText + "|");
|
||||||
|
searchStart = match.suffix().first;
|
||||||
|
}
|
||||||
|
|
||||||
// input is rect in which given text should be placed
|
// input is rect in which given text should be placed
|
||||||
// calculate proper position for top-left corner of the text
|
// calculate proper position for top-left corner of the text
|
||||||
if(alignment == ETextAlignment::TOPLEFT)
|
if(alignment == ETextAlignment::TOPLEFT)
|
||||||
@@ -189,8 +200,25 @@ void CTextContainer::blitLine(Canvas & to, Rect destRect, std::string what)
|
|||||||
{
|
{
|
||||||
std::string toPrint = what.substr(begin, end - begin);
|
std::string toPrint = what.substr(begin, end - begin);
|
||||||
|
|
||||||
if(currDelimeter % 2) // Enclosed in {} text - set to yellow
|
if(currDelimeter % 2) // Enclosed in {} text - set to yellow or defined color
|
||||||
to.drawText(where, font, Colors::YELLOW, ETextAlignment::TOPLEFT, toPrint);
|
{
|
||||||
|
std::smatch match;
|
||||||
|
std::regex expr("^(.*?)\\|");
|
||||||
|
if(std::regex_search(toPrint, match, expr))
|
||||||
|
{
|
||||||
|
std::string colorText = match[1].str();
|
||||||
|
|
||||||
|
if(auto color = Colors::parseColor(colorText))
|
||||||
|
{
|
||||||
|
toPrint = toPrint.substr(colorText.length() + 1, toPrint.length() - colorText.length());
|
||||||
|
to.drawText(where, font, *color, ETextAlignment::TOPLEFT, toPrint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
to.drawText(where, font, Colors::YELLOW, ETextAlignment::TOPLEFT, toPrint);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
to.drawText(where, font, Colors::YELLOW, ETextAlignment::TOPLEFT, toPrint);
|
||||||
|
}
|
||||||
else // Non-enclosed text, use default color
|
else // Non-enclosed text, use default color
|
||||||
to.drawText(where, font, color, ETextAlignment::TOPLEFT, toPrint);
|
to.drawText(where, font, color, ETextAlignment::TOPLEFT, toPrint);
|
||||||
|
|
||||||
|
@@ -131,6 +131,7 @@ std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineWi
|
|||||||
ui32 wordBreak = -1; //last position for line break (last space character)
|
ui32 wordBreak = -1; //last position for line break (last space character)
|
||||||
ui32 currPos = 0; //current position in text
|
ui32 currPos = 0; //current position in text
|
||||||
bool opened = false; //set to true when opening brace is found
|
bool opened = false; //set to true when opening brace is found
|
||||||
|
std::string color = ""; //color found
|
||||||
|
|
||||||
size_t symbolSize = 0; // width of character, in bytes
|
size_t symbolSize = 0; // width of character, in bytes
|
||||||
size_t glyphWidth = 0; // width of printable glyph, pixels
|
size_t glyphWidth = 0; // width of printable glyph, pixels
|
||||||
@@ -147,9 +148,27 @@ std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineWi
|
|||||||
|
|
||||||
/* We don't count braces in string length. */
|
/* We don't count braces in string length. */
|
||||||
if (text[currPos] == '{')
|
if (text[currPos] == '{')
|
||||||
|
{
|
||||||
opened=true;
|
opened=true;
|
||||||
|
|
||||||
|
std::smatch match;
|
||||||
|
std::regex expr("^\\{(.*?)\\|");
|
||||||
|
std::string tmp = text.substr(currPos);
|
||||||
|
if(std::regex_search(tmp, match, expr))
|
||||||
|
{
|
||||||
|
std::string colorText = match[1].str();
|
||||||
|
if(auto c = Colors::parseColor(colorText))
|
||||||
|
{
|
||||||
|
color = colorText + "|";
|
||||||
|
currPos += colorText.length() + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
else if (text[currPos]=='}')
|
else if (text[currPos]=='}')
|
||||||
|
{
|
||||||
opened=false;
|
opened=false;
|
||||||
|
color = "";
|
||||||
|
}
|
||||||
else
|
else
|
||||||
lineWidth += (ui32)glyphWidth;
|
lineWidth += (ui32)glyphWidth;
|
||||||
currPos += (ui32)symbolSize;
|
currPos += (ui32)symbolSize;
|
||||||
@@ -196,7 +215,7 @@ std::vector<std::string> CMessage::breakText( std::string text, size_t maxLineWi
|
|||||||
{
|
{
|
||||||
/* Add an opening brace for the next line. */
|
/* Add an opening brace for the next line. */
|
||||||
if (text.length() != 0)
|
if (text.length() != 0)
|
||||||
text.insert(0, "{");
|
text.insert(0, "{" + color);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@@ -16,6 +16,10 @@ struct SDL_Surface;
|
|||||||
class CInfoWindow;
|
class CInfoWindow;
|
||||||
class CComponent;
|
class CComponent;
|
||||||
|
|
||||||
|
VCMI_LIB_NAMESPACE_BEGIN
|
||||||
|
class ColorRGBA;
|
||||||
|
VCMI_LIB_NAMESPACE_END
|
||||||
|
|
||||||
|
|
||||||
/// Class which draws formatted text messages and generates chat windows
|
/// Class which draws formatted text messages and generates chat windows
|
||||||
class CMessage
|
class CMessage
|
||||||
|
171
config/textColors.json
Normal file
171
config/textColors.json
Normal file
@@ -0,0 +1,171 @@
|
|||||||
|
{
|
||||||
|
"colors": {
|
||||||
|
"r": "F80000",
|
||||||
|
"g": "00FC00",
|
||||||
|
"b": "0000F8",
|
||||||
|
"y": "F8FC00",
|
||||||
|
"o": "F88000",
|
||||||
|
"p": "F800F8",
|
||||||
|
"c": "00FCF8",
|
||||||
|
"k": "000000",
|
||||||
|
"w": "FFFFFF",
|
||||||
|
"Regular": "F8F0D8",
|
||||||
|
"Highlight": "E8D478",
|
||||||
|
"H3Red": "F80000",
|
||||||
|
"H3Cyan": "00FCF8",
|
||||||
|
"H3Green": "00FC00",
|
||||||
|
"H3Blue": "0000F8",
|
||||||
|
"H3Yellow": "F8FC00",
|
||||||
|
"H3Orange": "F88000",
|
||||||
|
"H3Purple": "F800F8",
|
||||||
|
"H3Pink": "C07888",
|
||||||
|
"Black": "000000",
|
||||||
|
"Navy": "000080",
|
||||||
|
"DarkBlue": "00008B",
|
||||||
|
"MediumBlue": "0000CD",
|
||||||
|
"Blue": "0000FF",
|
||||||
|
"DarkGreen": "006400",
|
||||||
|
"Green": "008000",
|
||||||
|
"Teal": "008080",
|
||||||
|
"DarkCyan": "008B8B",
|
||||||
|
"DeepSkyBlue": "00BFFF",
|
||||||
|
"DarkTurquoise": "00CED1",
|
||||||
|
"MediumSpringGreen": "00FA9A",
|
||||||
|
"Lime": "00FF00",
|
||||||
|
"SpringGreen": "00FF7F",
|
||||||
|
"Aqua": "00FFFF",
|
||||||
|
"Cyan": "00FFFF",
|
||||||
|
"MidnightBlue": "191970",
|
||||||
|
"DodgerBlue": "1E90FF",
|
||||||
|
"LightSeaGreen": "20B2AA",
|
||||||
|
"ForestGreen": "228B22",
|
||||||
|
"SeaGreen": "2E8B57",
|
||||||
|
"DarkSlateGray": "2F4F4F",
|
||||||
|
"DarkSlateGrey": "2F4F4F",
|
||||||
|
"LimeGreen": "32CD32",
|
||||||
|
"MediumSeaGreen": "3CB371",
|
||||||
|
"Turquoise": "40E0D0",
|
||||||
|
"RoyalBlue": "4169E1",
|
||||||
|
"SteelBlue": "4682B4",
|
||||||
|
"DarkSlateBlue": "483D8B",
|
||||||
|
"MediumTurquoise": "48D1CC",
|
||||||
|
"Indigo": "4B0082",
|
||||||
|
"DarkOliveGreen": "556B2F",
|
||||||
|
"CadetBlue": "5F9EA0",
|
||||||
|
"CornflowerBlue": "6495ED",
|
||||||
|
"RebeccaPurple": "663399",
|
||||||
|
"MediumAquaMarine": "66CDAA",
|
||||||
|
"DimGray": "696969",
|
||||||
|
"DimGrey": "696969",
|
||||||
|
"SlateBlue": "6A5ACD",
|
||||||
|
"OliveDrab": "6B8E23",
|
||||||
|
"SlateGray": "708090",
|
||||||
|
"SlateGrey": "708090",
|
||||||
|
"LightSlateGray": "778899",
|
||||||
|
"LightSlateGrey": "778899",
|
||||||
|
"MediumSlateBlue": "7B68EE",
|
||||||
|
"LawnGreen": "7CFC00",
|
||||||
|
"Chartreuse": "7FFF00",
|
||||||
|
"Aquamarine": "7FFFD4",
|
||||||
|
"Maroon": "800000",
|
||||||
|
"Purple": "800080",
|
||||||
|
"Olive": "808000",
|
||||||
|
"Gray": "808080",
|
||||||
|
"Grey": "808080",
|
||||||
|
"SkyBlue": "87CEEB",
|
||||||
|
"LightSkyBlue": "87CEFA",
|
||||||
|
"BlueViolet": "8A2BE2",
|
||||||
|
"DarkRed": "8B0000",
|
||||||
|
"DarkMagenta": "8B008B",
|
||||||
|
"SaddleBrown": "8B4513",
|
||||||
|
"DarkSeaGreen": "8FBC8F",
|
||||||
|
"LightGreen": "90EE90",
|
||||||
|
"MediumPurple": "9370DB",
|
||||||
|
"DarkViolet": "9400D3",
|
||||||
|
"PaleGreen": "98FB98",
|
||||||
|
"DarkOrchid": "9932CC",
|
||||||
|
"YellowGreen": "9ACD32",
|
||||||
|
"Sienna": "A0522D",
|
||||||
|
"Brown": "A52A2A",
|
||||||
|
"DarkGray": "A9A9A9",
|
||||||
|
"DarkGrey": "A9A9A9",
|
||||||
|
"LightBlue": "ADD8E6",
|
||||||
|
"GreenYellow": "ADFF2F",
|
||||||
|
"PaleTurquoise": "AFEEEE",
|
||||||
|
"LightSteelBlue": "B0C4DE",
|
||||||
|
"PowderBlue": "B0E0E6",
|
||||||
|
"FireBrick": "B22222",
|
||||||
|
"DarkGoldenRod": "B8860B",
|
||||||
|
"MediumOrchid": "BA55D3",
|
||||||
|
"RosyBrown": "BC8F8F",
|
||||||
|
"DarkKhaki": "BDB76B",
|
||||||
|
"Silver": "C0C0C0",
|
||||||
|
"MediumVioletRed": "C71585",
|
||||||
|
"IndianRed": "CD5C5C",
|
||||||
|
"Peru": "CD853F",
|
||||||
|
"Chocolate": "D2691E",
|
||||||
|
"Tan": "D2B48C",
|
||||||
|
"LightGray": "D3D3D3",
|
||||||
|
"LightGrey": "D3D3D3",
|
||||||
|
"Thistle": "D8BFD8",
|
||||||
|
"Orchid": "DA70D6",
|
||||||
|
"GoldenRod": "DAA520",
|
||||||
|
"PaleVioletRed": "DB7093",
|
||||||
|
"Crimson": "DC143C",
|
||||||
|
"Gainsboro": "DCDCDC",
|
||||||
|
"Plum": "DDA0DD",
|
||||||
|
"BurlyWood": "DEB887",
|
||||||
|
"LightCyan": "E0FFFF",
|
||||||
|
"Lavender": "E6E6FA",
|
||||||
|
"DarkSalmon": "E9967A",
|
||||||
|
"Violet": "EE82EE",
|
||||||
|
"PaleGoldenRod": "EEE8AA",
|
||||||
|
"LightCoral": "F08080",
|
||||||
|
"Khaki": "F0E68C",
|
||||||
|
"AliceBlue": "F0F8FF",
|
||||||
|
"HoneyDew": "F0FFF0",
|
||||||
|
"Azure": "F0FFFF",
|
||||||
|
"SandyBrown": "F4A460",
|
||||||
|
"Wheat": "F5DEB3",
|
||||||
|
"Beige": "F5F5DC",
|
||||||
|
"WhiteSmoke": "F5F5F5",
|
||||||
|
"MintCream": "F5FFFA",
|
||||||
|
"GhostWhite": "F8F8FF",
|
||||||
|
"Salmon": "FA8072",
|
||||||
|
"AntiqueWhite": "FAEBD7",
|
||||||
|
"Linen": "FAF0E6",
|
||||||
|
"LightGoldenRodYellow": "FAFAD2",
|
||||||
|
"OldLace": "FDF5E6",
|
||||||
|
"Red": "FF0000",
|
||||||
|
"Fuchsia": "FF00FF",
|
||||||
|
"Magenta": "FF00FF",
|
||||||
|
"DeepPink": "FF1493",
|
||||||
|
"OrangeRed": "FF4500",
|
||||||
|
"Tomato": "FF6347",
|
||||||
|
"HotPink": "FF69B4",
|
||||||
|
"Coral": "FF7F50",
|
||||||
|
"DarkOrange": "FF8C00",
|
||||||
|
"LightSalmon": "FFA07A",
|
||||||
|
"Orange": "FFA500",
|
||||||
|
"LightPink": "FFB6C1",
|
||||||
|
"Pink": "FFC0CB",
|
||||||
|
"Gold": "FFD700",
|
||||||
|
"PeachPuff": "FFDAB9",
|
||||||
|
"NavajoWhite": "FFDEAD",
|
||||||
|
"Moccasin": "FFE4B5",
|
||||||
|
"Bisque": "FFE4C4",
|
||||||
|
"MistyRose": "FFE4E1",
|
||||||
|
"BlanchedAlmond": "FFEBCD",
|
||||||
|
"PapayaWhip": "FFEFD5",
|
||||||
|
"LavenderBlush": "FFF0F5",
|
||||||
|
"SeaShell": "FFF5EE",
|
||||||
|
"Cornsilk": "FFF8DC",
|
||||||
|
"LemonChiffon": "FFFACD",
|
||||||
|
"FloralWhite": "FFFAF0",
|
||||||
|
"Snow": "FFFAFA",
|
||||||
|
"Yellow": "FFFF00",
|
||||||
|
"LightYellow": "FFFFE0",
|
||||||
|
"Ivory": "FFFFF0",
|
||||||
|
"White": "FFFFFF"
|
||||||
|
}
|
||||||
|
}
|
@@ -45,6 +45,31 @@ Some of H3 mechanics can't be straight considered as bug, but default VCMI behav
|
|||||||
|
|
||||||
Mouse click on castle icon in the town screen open quick recruitment window, where we can purhase in fast way units.
|
Mouse click on castle icon in the town screen open quick recruitment window, where we can purhase in fast way units.
|
||||||
|
|
||||||
|
## Color support
|
||||||
|
|
||||||
|
Additional color are supported for text fields (e.g. map description). Uses HTML color syntax (e.g. #abcdef) / HTML predefined colors (e.g. green).
|
||||||
|
|
||||||
|
##### Original Heroes III Support
|
||||||
|
|
||||||
|
`This is white`
|
||||||
|
|
||||||
|
<span style="color:white;background-color:black;">This is white</span>
|
||||||
|
|
||||||
|
`{This is yellow}`
|
||||||
|
|
||||||
|
<span style="color:yellow;background-color:black;">This is yellow</span>
|
||||||
|
|
||||||
|
##### New
|
||||||
|
|
||||||
|
`{#ff0000|This is red}`
|
||||||
|
|
||||||
|
<span style="color:red">This is red</span>
|
||||||
|
|
||||||
|
`{green|This is green}`
|
||||||
|
|
||||||
|
<span style="color:green">This is green</span>
|
||||||
|
|
||||||
|
|
||||||
# Manuals and guides
|
# Manuals and guides
|
||||||
|
|
||||||
- https://heroes.thelazy.net//index.php/Main_Page Wiki that aims to be a complete reference to Heroes of Might and Magic III.
|
- https://heroes.thelazy.net/index.php/Main_Page Wiki that aims to be a complete reference to Heroes of Might and Magic III.
|
||||||
|
Reference in New Issue
Block a user