|
19 | 19 | #define GENERATE_H_INCLUDED
|
20 | 20 |
|
21 | 21 | #include "mesh.h"
|
| 22 | +#include "image.h" |
22 | 23 | #include <utility>
|
23 | 24 | #include <functional>
|
24 | 25 | #include <tuple>
|
25 | 26 | #include <vector>
|
| 27 | +#include <cwchar> |
| 28 | +#include <string> |
| 29 | +#include <cmath> |
26 | 30 |
|
27 | 31 | using namespace std;
|
28 | 32 |
|
@@ -172,6 +176,121 @@ namespace Generate
|
172 | 176 | }
|
173 | 177 | return std::move(retval);
|
174 | 178 | }
|
| 179 | + |
| 180 | + struct TextProperties final |
| 181 | + { |
| 182 | + float tabWidth = 8; |
| 183 | + }; |
| 184 | + |
| 185 | + class Text final |
| 186 | + { |
| 187 | + Text() = delete; |
| 188 | + Text(const Text &) = delete; |
| 189 | + void operator =(const Text &) = delete; |
| 190 | + static void renderChar(Mesh &dest, float x, float y, unsigned ch, ColorF c, const std::shared_ptr<Texture> &fontTexture) |
| 191 | + { |
| 192 | + TextureDescriptor td = getTextFontCharacterTextureDescriptor(ch, fontTexture); |
| 193 | + dest.append(quadrilateral(td, |
| 194 | + VectorF(0 + x, 0 + y, 0), c, |
| 195 | + VectorF(1 + x, 0 + y, 0), c, |
| 196 | + VectorF(1 + x, 1 + y, 0), c, |
| 197 | + VectorF(0 + x, 1 + y, 0), c |
| 198 | + )); |
| 199 | + } |
| 200 | + static void renderEngine(Mesh *dest, float &x, float &y, float &w, float &h, std::wstring str, ColorF c, const TextProperties &tp, const std::shared_ptr<Texture> &fontTexture = nullptr) |
| 201 | + { |
| 202 | + float wholeHeight = 0; |
| 203 | + if(dest) |
| 204 | + renderEngine(nullptr, x, y, w, wholeHeight, str, c, tp); |
| 205 | + x = 0; |
| 206 | + y = 0; |
| 207 | + w = 0; |
| 208 | + h = 0; |
| 209 | + for(auto ch : str) |
| 210 | + { |
| 211 | + switch(ch) |
| 212 | + { |
| 213 | + case '\r': |
| 214 | + x = 0; |
| 215 | + break; |
| 216 | + case '\n': |
| 217 | + x = 0; |
| 218 | + y += 1; |
| 219 | + break; |
| 220 | + case '\t': |
| 221 | + { |
| 222 | + float tabWidth = tp.tabWidth; |
| 223 | + if(!std::isfinite(tabWidth) || tabWidth < 1e-4) |
| 224 | + tabWidth = 1; |
| 225 | + if(tabWidth > 1e6) |
| 226 | + tabWidth = 1e6; |
| 227 | + x /= tabWidth; |
| 228 | + x += 1e-4; |
| 229 | + x = std::floor(x); |
| 230 | + x += 1; |
| 231 | + x *= tabWidth; |
| 232 | + break; |
| 233 | + } |
| 234 | + case '\b': |
| 235 | + x -= 1; |
| 236 | + if(x < 0) |
| 237 | + x = 0; |
| 238 | + break; |
| 239 | + case '\0': |
| 240 | + case ' ': |
| 241 | + x += 1; |
| 242 | + break; |
| 243 | + default: |
| 244 | + if(dest) |
| 245 | + renderChar(*dest, x, wholeHeight - y - 1, ch, c, fontTexture); |
| 246 | + x += 1; |
| 247 | + break; |
| 248 | + } |
| 249 | + if(y >= h) |
| 250 | + h = y + 1; |
| 251 | + if(x > w) |
| 252 | + w = x; |
| 253 | + } |
| 254 | + y = h - y - 1; |
| 255 | + } |
| 256 | + public: |
| 257 | + static float width(std::wstring str, const TextProperties &tp = TextProperties()) |
| 258 | + { |
| 259 | + float x, y, w, h; |
| 260 | + renderEngine(nullptr, x, y, w, h, str, ColorF(), tp); |
| 261 | + return w; |
| 262 | + } |
| 263 | + static float height(std::wstring str, const TextProperties &tp = TextProperties()) |
| 264 | + { |
| 265 | + float x, y, w, h; |
| 266 | + renderEngine(nullptr, x, y, w, h, str, ColorF(), tp); |
| 267 | + return h; |
| 268 | + } |
| 269 | + static float x(std::wstring str, const TextProperties &tp = TextProperties()) |
| 270 | + { |
| 271 | + float x, y, w, h; |
| 272 | + renderEngine(nullptr, x, y, w, h, str, ColorF(), tp); |
| 273 | + return x; |
| 274 | + } |
| 275 | + static float y(std::wstring str, const TextProperties &tp = TextProperties()) |
| 276 | + { |
| 277 | + float x, y, w, h; |
| 278 | + renderEngine(nullptr, x, y, w, h, str, ColorF(), tp); |
| 279 | + return y; |
| 280 | + } |
| 281 | + static Mesh &mesh(Mesh &dest, std::wstring str, std::shared_ptr<Texture> fontTexture = nullptr, ColorF c = GrayscaleF(1), const TextProperties &tp = TextProperties()) |
| 282 | + { |
| 283 | + float x, y, w, h; |
| 284 | + renderEngine(&dest, x, y, w, h, str, c, tp, fontTexture); |
| 285 | + return dest; |
| 286 | + } |
| 287 | + static Mesh mesh(std::wstring str, std::shared_ptr<Texture> fontTexture = nullptr, ColorF c = GrayscaleF(1), const TextProperties &tp = TextProperties()) |
| 288 | + { |
| 289 | + Mesh dest; |
| 290 | + mesh(dest, str, fontTexture, c, tp); |
| 291 | + return std::move(dest); |
| 292 | + } |
| 293 | + }; |
175 | 294 | }
|
176 | 295 |
|
177 | 296 | #endif // GENERATE_H_INCLUDED
|
0 commit comments