-
Notifications
You must be signed in to change notification settings - Fork 6
/
NewNewGUITextView.cpp
161 lines (110 loc) · 3.86 KB
/
NewNewGUITextView.cpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
//
// NewTextView.cpp
// Deep
//
// Created by Nathan Daly on 1/4/13.
// Copyright (c) 2013 Lions Entertainment. All rights reserved.
//
#include "NewNewGUITextView.h"
#include "GameDisplay.h"
#include <iostream>
#include <map>
using std::string;
using std::map;
using std::make_pair;
namespace GUI {
//---------------
class LetterCache {
public:
static const GUIImage& get_image(const LetterData& data);
};
//---------------
const SDL_Color text_color_black_c = {0,0,0,0};
const SDL_Color clear_color_c = {0xFF, 0, 0xFF};
NewTextView::NewTextView(int w, int h, int size, SDL_Color color)
:View(w,h), prev('a', size, color)
{
draw_onto_self(GUIImage::create_filled(w, h, clear_color_c), DispPoint());
set_clear_color(clear_color_c);
}
void NewTextView::draw() {
DispPoint pos(0,0);
letter_ctr_t::iterator it;
for (it = text.begin(); it != text.end(); ++it) {
const GUIImage& image = LetterCache::get_image(*it);
draw_onto_self(image, pos);
pos.x += image.getw();
if (pos.x + image.getw() >= get_w()) {
pos.x = 0;
pos.y += image.geth();
}
}
}
static bool operator<(const SDL_Color& a, const SDL_Color& b) {
if (a.r < b.r) return true;
else if (a.r == b.r && a.b < b.b) return true;
else if (a.b == b.b && a.g < b.g) return true;
else return false;
}
bool LetterData::operator<(const LetterData& rhs) const {
if (c < rhs.c) return true;
else if (c == rhs.c && size < rhs.size) return true;
else if (size == rhs.size && color < rhs.color) return true;
else return false;
}
void NewTextView::set_letter_data(const LetterData& data,
size_t startIdx, size_t endIdx) {
prev = data;
if (endIdx == string::npos) endIdx = text.size();
letter_ctr_t::iterator it = text.begin();
for (size_t i = 0; i < startIdx; i++) ++it; // advance to correct position.
for (size_t i = startIdx; i < endIdx; ++i, ++it) {
it->size = data.size;
it->color = data.color;
}
}
void NewTextView::set_text(const std::string& text_){
text.clear();
add_text(text_, 0);
}
void NewTextView::add_text(const std::string& text_, int index){
if (index > (int)text.size()) {
throw Error("Cannot add text: Index is out of bounds.");
}
letter_ctr_t new_text;
for (size_t i = 0; i < text_.size(); ++i) {
new_text.push_back(LetterData(text_[i], prev.size, prev.color));
}
letter_ctr_t::iterator it = text.begin();
for (int i = 0; i < index; i++) ++it; // advance to correct position.
text.insert(it, new_text.begin(), new_text.end());
draw();
}
void NewTextView::append_text(const std::string& text_){
add_text(text_, text.size());
}
std::string NewTextView::get_text() const {
string result;
letter_ctr_t::const_iterator it;
for (it = text.begin(); it != text.end(); ++it) {
result.append(1, it->c);
}
return result;
}
const GUIImage& LetterCache::get_image(const LetterData& data) {
static map<LetterData, SDL_Surface*> letters;
static map<int, TTF_Font*> fonts;
if (fonts.count(data.size) == 0) {
fonts[data.size] = TTF_OpenFont("GUIFonts/arial.ttf", data.size);
}
TTF_Font *font = fonts[data.size];
if (letters.count(data) == 0) {
string ch(1, data.c);
SDL_Surface* text = TTF_RenderText_Solid(font, ch.c_str(),
data.color);
letters.insert(make_pair(data, text));
}
// todo As it is, TTF_RenderText creates Alpha'd images, but the GUIImage copy constructed images have a completely black background.
return (GUIImage&)letters[data]; // Avoid the copy constructor.
}
} // namespace GUI