1 /*
2 Copyright (C) 2003 - 2018 by the Battle for Wesnoth Project https://www.wesnoth.org/
3
4 This program is free software; you can redistribute it and/or modify
5 it under the terms of the GNU General Public License as published by
6 the Free Software Foundation; either version 2 of the License, or
7 (at your option) any later version.
8 This program is distributed in the hope that it will be useful,
9 but WITHOUT ANY WARRANTY.
10
11 See the COPYING file for more details.
12 */
13
14 #include "serialization/string_utils.hpp"
15 #include "color.hpp"
16
17 #include <iomanip>
18 #include <sstream>
19
from_rgba_string(const std::string & c)20 color_t color_t::from_rgba_string(const std::string& c)
21 {
22 if(c.empty()) {
23 return null_color();
24 }
25
26 std::vector<std::string> fields = utils::split(c);
27
28 // Allow either 3 (automatic opaque alpha) or 4 (explicit alpha) fields
29 if(fields.size() != 3 && fields.size() != 4) {
30 throw std::invalid_argument("Wrong number of components for RGBA color");
31 }
32
33 return {
34 static_cast<uint8_t>(std::stoul(fields[0])),
35 static_cast<uint8_t>(std::stoul(fields[1])),
36 static_cast<uint8_t>(std::stoul(fields[2])),
37 static_cast<uint8_t>(fields.size() == 4 ? std::stoul(fields[3]) : ALPHA_OPAQUE)
38 };
39 }
40
from_rgb_string(const std::string & c)41 color_t color_t::from_rgb_string(const std::string& c)
42 {
43 if(c.empty()) {
44 return null_color();
45 }
46
47 std::vector<std::string> fields = utils::split(c);
48
49 if(fields.size() != 3) {
50 throw std::invalid_argument("Wrong number of components for RGB color");
51 }
52
53 return {
54 static_cast<uint8_t>(std::stoul(fields[0])),
55 static_cast<uint8_t>(std::stoul(fields[1])),
56 static_cast<uint8_t>(std::stoul(fields[2])),
57 static_cast<uint8_t>(ALPHA_OPAQUE)
58 };
59 }
60
from_hex_string(const std::string & c)61 color_t color_t::from_hex_string(const std::string& c)
62 {
63 if(c.length() != 6) {
64 throw std::invalid_argument("Color hex string should be exactly 6 digits");
65 }
66
67 unsigned long temp_c = std::strtol(c.c_str(), nullptr, 16);
68
69 return {
70 static_cast<uint8_t>((0x00FFFFFF & temp_c) >> 16),
71 static_cast<uint8_t>((0x00FFFFFF & temp_c) >> 8),
72 static_cast<uint8_t>((0x00FFFFFF & temp_c)),
73 ALPHA_OPAQUE
74 };
75 }
76
from_rgba_bytes(uint32_t c)77 color_t color_t::from_rgba_bytes(uint32_t c)
78 {
79 return {
80 static_cast<uint8_t>((RGBA_RED_MASK & c) >> RGBA_RED_BITSHIFT),
81 static_cast<uint8_t>((RGBA_GREEN_MASK & c) >> RGBA_GREEN_BITSHIFT),
82 static_cast<uint8_t>((RGBA_BLUE_MASK & c) >> RGBA_BLUE_BITSHIFT),
83 static_cast<uint8_t>((RGBA_ALPHA_MASK & c) >> RGBA_ALPHA_BITSHIFT),
84 };
85 }
86
from_argb_bytes(uint32_t c)87 color_t color_t::from_argb_bytes(uint32_t c)
88 {
89 return {
90 static_cast<uint8_t>((SDL_RED_MASK & c) >> SDL_RED_BITSHIFT),
91 static_cast<uint8_t>((SDL_GREEN_MASK & c) >> SDL_GREEN_BITSHIFT),
92 static_cast<uint8_t>((SDL_BLUE_MASK & c) >> SDL_BLUE_BITSHIFT),
93 static_cast<uint8_t>((SDL_ALPHA_MASK & c) >> SDL_ALPHA_BITSHIFT),
94 };
95 }
96
to_hex_string() const97 std::string color_t::to_hex_string() const
98 {
99 std::ostringstream h;
100
101 h << "#"
102 << std::hex << std::setfill('0')
103 << std::setw(2) << static_cast<int>(r)
104 << std::setw(2) << static_cast<int>(g)
105 << std::setw(2) << static_cast<int>(b);
106
107 return h.str();
108 }
109
to_rgba_string() const110 std::string color_t::to_rgba_string() const
111 {
112 std::ostringstream color;
113
114 color << static_cast<int>(r) << ','
115 << static_cast<int>(g) << ','
116 << static_cast<int>(b) << ','
117 << static_cast<int>(a);
118
119 return color.str();
120 }
121
to_rgb_string() const122 std::string color_t::to_rgb_string() const
123 {
124 std::ostringstream color;
125
126 color << static_cast<int>(r) << ','
127 << static_cast<int>(g) << ','
128 << static_cast<int>(b);
129
130 return color.str();
131 }
132