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 <queue>
|
||||
#include <random>
|
||||
#include <regex>
|
||||
#include <set>
|
||||
#include <sstream>
|
||||
#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
|
||||
#endif
|
||||
|
||||
#include <boost/algorithm/hex.hpp>
|
||||
#include <boost/algorithm/string.hpp>
|
||||
#include <boost/crc.hpp>
|
||||
#include <boost/current_function.hpp>
|
||||
|
@@ -10,6 +10,7 @@
|
||||
|
||||
#include "StdInc.h"
|
||||
#include "Colors.h"
|
||||
#include "../../lib/JsonNode.h"
|
||||
|
||||
const ColorRGBA Colors::YELLOW = { 229, 215, 123, 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::BLACK = {0, 0, 0, ColorRGBA::ALPHA_OPAQUE};
|
||||
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 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.
|
||||
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
|
||||
// calculate proper position for top-left corner of the text
|
||||
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);
|
||||
|
||||
if(currDelimeter % 2) // Enclosed in {} text - set to yellow
|
||||
if(currDelimeter % 2) // Enclosed in {} text - set to yellow or defined color
|
||||
{
|
||||
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
|
||||
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 currPos = 0; //current position in text
|
||||
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 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. */
|
||||
if (text[currPos] == '{')
|
||||
{
|
||||
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]=='}')
|
||||
{
|
||||
opened=false;
|
||||
color = "";
|
||||
}
|
||||
else
|
||||
lineWidth += (ui32)glyphWidth;
|
||||
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. */
|
||||
if (text.length() != 0)
|
||||
text.insert(0, "{");
|
||||
text.insert(0, "{" + color);
|
||||
}
|
||||
}
|
||||
|
||||
|
@@ -16,6 +16,10 @@ struct SDL_Surface;
|
||||
class CInfoWindow;
|
||||
class CComponent;
|
||||
|
||||
VCMI_LIB_NAMESPACE_BEGIN
|
||||
class ColorRGBA;
|
||||
VCMI_LIB_NAMESPACE_END
|
||||
|
||||
|
||||
/// Class which draws formatted text messages and generates chat windows
|
||||
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.
|
||||
|
||||
## 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
|
||||
|
||||
- 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