gosu 0.13.3 → 0.14.0.pre2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gosu/Audio.hpp +15 -11
- data/Gosu/Font.hpp +24 -20
- data/Gosu/Fwd.hpp +1 -1
- data/Gosu/Graphics.hpp +8 -9
- data/Gosu/ImageData.hpp +1 -1
- data/Gosu/Input.hpp +1 -1
- data/Gosu/Math.hpp +0 -18
- data/Gosu/Text.hpp +22 -30
- data/Gosu/TextInput.hpp +13 -0
- data/Gosu/Utility.hpp +2 -0
- data/Gosu/Window.hpp +3 -3
- data/README.md +3 -4
- data/ext/gosu/extconf.rb +7 -9
- data/lib/gosu/swig_patches.rb +1 -4
- data/rdoc/gosu.rb +34 -9
- data/src/Audio.cpp +6 -6
- data/src/AudioImpl.cpp +2 -2
- data/src/Bitmap.cpp +1 -2
- data/src/BitmapIO.cpp +21 -2
- data/src/BlockAllocator.cpp +1 -1
- data/src/Channel.cpp +7 -1
- data/src/ClipRectStack.hpp +4 -1
- data/src/Color.cpp +2 -1
- data/src/DirectoriesWin.cpp +1 -1
- data/src/DrawOp.hpp +8 -4
- data/src/DrawOpQueue.hpp +13 -24
- data/src/FileUnix.cpp +3 -1
- data/src/Font.cpp +92 -96
- data/src/GosuGLView.cpp +59 -31
- data/src/GosuGLView.hpp +14 -0
- data/src/GosuViewController.cpp +21 -21
- data/src/{GosuViewController.h → GosuViewController.hpp} +2 -4
- data/src/Graphics.cpp +71 -38
- data/src/GraphicsImpl.hpp +12 -29
- data/src/Image.cpp +5 -7
- data/src/Input.cpp +7 -5
- data/src/InputUIKit.cpp +19 -37
- data/src/Macro.cpp +10 -2
- data/src/MarkupParser.cpp +241 -0
- data/src/MarkupParser.hpp +61 -0
- data/src/Math.cpp +1 -1
- data/src/OffScreenTarget.cpp +99 -0
- data/src/OffScreenTarget.hpp +23 -0
- data/src/OggFile.hpp +10 -0
- data/src/RenderState.hpp +0 -2
- data/src/Resolution.cpp +2 -2
- data/src/RubyGosu.cxx +457 -244
- data/src/TexChunk.cpp +8 -6
- data/src/Text.cpp +58 -345
- data/src/TextBuilder.cpp +138 -0
- data/src/TextBuilder.hpp +55 -0
- data/src/TextInput.cpp +27 -10
- data/src/Texture.cpp +22 -17
- data/src/Texture.hpp +19 -20
- data/src/TimingApple.cpp +5 -7
- data/src/TimingUnix.cpp +1 -4
- data/src/TimingWin.cpp +4 -1
- data/src/TrueTypeFont.cpp +282 -0
- data/src/TrueTypeFont.hpp +66 -0
- data/src/TrueTypeFontApple.cpp +65 -0
- data/src/TrueTypeFontUnix.cpp +91 -0
- data/src/TrueTypeFontWin.cpp +82 -0
- data/src/Utility.cpp +40 -0
- data/src/Window.cpp +7 -6
- data/src/WindowUIKit.cpp +9 -4
- data/src/stb_truetype.h +4589 -0
- data/src/utf8proc.c +755 -0
- data/src/utf8proc.h +699 -0
- data/src/utf8proc_data.h +14386 -0
- metadata +23 -16
- data/src/FormattedString.cpp +0 -237
- data/src/FormattedString.hpp +0 -47
- data/src/GosuAppDelegate.cpp +0 -30
- data/src/GosuAppDelegate.h +0 -8
- data/src/GosuGLView.h +0 -8
- data/src/TextApple.cpp +0 -212
- data/src/TextTTFWin.cpp +0 -197
- data/src/TextUnix.cpp +0 -280
- data/src/TextWin.cpp +0 -191
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: gosu
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 0.14.0.pre2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julian Raschke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2018-
|
11
|
+
date: 2018-08-29 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
14
|
2D game development library.
|
@@ -81,14 +81,10 @@ files:
|
|
81
81
|
- src/FileUnix.cpp
|
82
82
|
- src/FileWin.cpp
|
83
83
|
- src/Font.cpp
|
84
|
-
- src/FormattedString.cpp
|
85
|
-
- src/FormattedString.hpp
|
86
|
-
- src/GosuAppDelegate.cpp
|
87
|
-
- src/GosuAppDelegate.h
|
88
84
|
- src/GosuGLView.cpp
|
89
|
-
- src/GosuGLView.
|
85
|
+
- src/GosuGLView.hpp
|
90
86
|
- src/GosuViewController.cpp
|
91
|
-
- src/GosuViewController.
|
87
|
+
- src/GosuViewController.hpp
|
92
88
|
- src/Graphics.cpp
|
93
89
|
- src/GraphicsImpl.hpp
|
94
90
|
- src/IO.cpp
|
@@ -102,7 +98,11 @@ files:
|
|
102
98
|
- src/MPEGFile.hpp
|
103
99
|
- src/Macro.cpp
|
104
100
|
- src/Macro.hpp
|
101
|
+
- src/MarkupParser.cpp
|
102
|
+
- src/MarkupParser.hpp
|
105
103
|
- src/Math.cpp
|
104
|
+
- src/OffScreenTarget.cpp
|
105
|
+
- src/OffScreenTarget.hpp
|
106
106
|
- src/OggFile.hpp
|
107
107
|
- src/RenderState.hpp
|
108
108
|
- src/Resolution.cpp
|
@@ -113,11 +113,9 @@ files:
|
|
113
113
|
- src/TexChunk.cpp
|
114
114
|
- src/TexChunk.hpp
|
115
115
|
- src/Text.cpp
|
116
|
-
- src/
|
116
|
+
- src/TextBuilder.cpp
|
117
|
+
- src/TextBuilder.hpp
|
117
118
|
- src/TextInput.cpp
|
118
|
-
- src/TextTTFWin.cpp
|
119
|
-
- src/TextUnix.cpp
|
120
|
-
- src/TextWin.cpp
|
121
119
|
- src/Texture.cpp
|
122
120
|
- src/Texture.hpp
|
123
121
|
- src/TimingApple.cpp
|
@@ -125,6 +123,11 @@ files:
|
|
125
123
|
- src/TimingWin.cpp
|
126
124
|
- src/Transform.cpp
|
127
125
|
- src/TransformStack.hpp
|
126
|
+
- src/TrueTypeFont.cpp
|
127
|
+
- src/TrueTypeFont.hpp
|
128
|
+
- src/TrueTypeFontApple.cpp
|
129
|
+
- src/TrueTypeFontUnix.cpp
|
130
|
+
- src/TrueTypeFontWin.cpp
|
128
131
|
- src/Utility.cpp
|
129
132
|
- src/UtilityApple.cpp
|
130
133
|
- src/UtilityWin.cpp
|
@@ -136,7 +139,11 @@ files:
|
|
136
139
|
- src/WindowUIKit.cpp
|
137
140
|
- src/stb_image.h
|
138
141
|
- src/stb_image_write.h
|
142
|
+
- src/stb_truetype.h
|
139
143
|
- src/stb_vorbis.c
|
144
|
+
- src/utf8proc.c
|
145
|
+
- src/utf8proc.h
|
146
|
+
- src/utf8proc_data.h
|
140
147
|
homepage: https://www.libgosu.org/
|
141
148
|
licenses:
|
142
149
|
- MIT
|
@@ -153,15 +160,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
153
160
|
requirements:
|
154
161
|
- - ">="
|
155
162
|
- !ruby/object:Gem::Version
|
156
|
-
version: 1.
|
163
|
+
version: 1.9.3
|
157
164
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
158
165
|
requirements:
|
159
|
-
- - "
|
166
|
+
- - ">"
|
160
167
|
- !ruby/object:Gem::Version
|
161
|
-
version:
|
168
|
+
version: 1.3.1
|
162
169
|
requirements: []
|
163
170
|
rubyforge_project:
|
164
|
-
rubygems_version: 2.7.
|
171
|
+
rubygems_version: 2.7.6
|
165
172
|
signing_key:
|
166
173
|
specification_version: 4
|
167
174
|
summary: 2D game development library.
|
data/src/FormattedString.cpp
DELETED
@@ -1,237 +0,0 @@
|
|
1
|
-
#include "FormattedString.hpp"
|
2
|
-
#include <Gosu/Utility.hpp>
|
3
|
-
#include <cwchar>
|
4
|
-
#include <cwctype>
|
5
|
-
using namespace std;
|
6
|
-
|
7
|
-
static unsigned flags(int b, int u, int i)
|
8
|
-
{
|
9
|
-
unsigned flags = 0;
|
10
|
-
if (b > 0) flags |= Gosu::FF_BOLD;
|
11
|
-
if (u > 0) flags |= Gosu::FF_UNDERLINE;
|
12
|
-
if (i > 0) flags |= Gosu::FF_ITALIC;
|
13
|
-
return flags;
|
14
|
-
}
|
15
|
-
|
16
|
-
bool Gosu::FormattedString::FormattedChar::same_style_as(const FormattedChar& other) const
|
17
|
-
{
|
18
|
-
return wc && other.wc && color == other.color && flags == other.flags;
|
19
|
-
}
|
20
|
-
|
21
|
-
Gosu::FormattedString::FormattedString()
|
22
|
-
{
|
23
|
-
}
|
24
|
-
|
25
|
-
Gosu::FormattedString::FormattedString(const wchar_t* html, unsigned base_flags)
|
26
|
-
{
|
27
|
-
// Remove \r characters if existent. Avoid a copy if we don't need one.
|
28
|
-
wstring unixified;
|
29
|
-
// We have to explicitly qualify wcschr to avoid an ambiguity on macOS.
|
30
|
-
if (std::wcschr(html, L'\r')) {
|
31
|
-
unixified.resize(wcslen(html));
|
32
|
-
unsigned pos = 0;
|
33
|
-
while (*html) {
|
34
|
-
if (*html != '\r') {
|
35
|
-
unixified[pos++] = *html;
|
36
|
-
}
|
37
|
-
++html;
|
38
|
-
}
|
39
|
-
unixified.resize(pos);
|
40
|
-
html = unixified.c_str();
|
41
|
-
}
|
42
|
-
|
43
|
-
size_t len = wcslen(html);
|
44
|
-
|
45
|
-
// Just skip all this if there are entities or formatting tags in the string.
|
46
|
-
if (wcscspn(html, L"<&") == len) {
|
47
|
-
simple_string = html;
|
48
|
-
simple_flags = base_flags;
|
49
|
-
return;
|
50
|
-
}
|
51
|
-
|
52
|
-
unsigned pos = 0;
|
53
|
-
int b = (base_flags & FF_BOLD) ? 1 : 0,
|
54
|
-
u = (base_flags & FF_UNDERLINE) ? 1 : 0,
|
55
|
-
i = (base_flags & FF_ITALIC) ? 1 : 0;
|
56
|
-
vector<Color> c;
|
57
|
-
c.push_back(0xffffffff);
|
58
|
-
while (pos < len) {
|
59
|
-
if (!wcsncmp(html + pos, L"<b>", 3)) {
|
60
|
-
b += 1;
|
61
|
-
pos += 3;
|
62
|
-
continue;
|
63
|
-
}
|
64
|
-
if (!wcsncmp(html + pos, L"</b>", 4)) {
|
65
|
-
b -= 1;
|
66
|
-
pos += 4;
|
67
|
-
continue;
|
68
|
-
}
|
69
|
-
if (!wcsncmp(html + pos, L"<u>", 3)) {
|
70
|
-
u += 1;
|
71
|
-
pos += 3;
|
72
|
-
continue;
|
73
|
-
}
|
74
|
-
if (!wcsncmp(html + pos, L"</u>", 4)) {
|
75
|
-
u -= 1;
|
76
|
-
pos += 4;
|
77
|
-
continue;
|
78
|
-
}
|
79
|
-
if (!wcsncmp(html + pos, L"<i>", 3)) {
|
80
|
-
i += 1;
|
81
|
-
pos += 3;
|
82
|
-
continue;
|
83
|
-
}
|
84
|
-
if (!wcsncmp(html + pos, L"</i>", 4)) {
|
85
|
-
i -= 1;
|
86
|
-
pos += 4;
|
87
|
-
continue;
|
88
|
-
}
|
89
|
-
if (!wcsncmp(html + pos, L"<c=", 3) && len >= pos + 10 && html[pos + 9] == L'>') {
|
90
|
-
unsigned rgb = static_cast<uint32_t>(wcstoul(html + pos + 3, 0, 16));
|
91
|
-
c.push_back(0xff000000 | rgb);
|
92
|
-
pos += 10;
|
93
|
-
continue;
|
94
|
-
}
|
95
|
-
if (!wcsncmp(html + pos, L"<c=", 3) && len >= pos + 12 && html[pos + 11] == L'>') {
|
96
|
-
unsigned argb = static_cast<uint32_t>(wcstoul(html + pos + 3, 0, 16));
|
97
|
-
c.push_back(argb);
|
98
|
-
pos += 12;
|
99
|
-
continue;
|
100
|
-
}
|
101
|
-
if (!wcsncmp(html + pos, L"</c>", 4)) {
|
102
|
-
if (c.size() > 1) {
|
103
|
-
c.pop_back();
|
104
|
-
}
|
105
|
-
pos += 4;
|
106
|
-
continue;
|
107
|
-
}
|
108
|
-
if (!wcsncmp(html + pos, L"<", 4)) {
|
109
|
-
FormattedChar fc = { L'<', c.back(), flags(b, u, i) };
|
110
|
-
characters.push_back(fc);
|
111
|
-
pos += 4;
|
112
|
-
continue;
|
113
|
-
}
|
114
|
-
if (!wcsncmp(html + pos, L">", 4)) {
|
115
|
-
FormattedChar fc = { L'>', c.back(), flags(b, u, i) };
|
116
|
-
characters.push_back(fc);
|
117
|
-
pos += 4;
|
118
|
-
continue;
|
119
|
-
}
|
120
|
-
if (!wcsncmp(html + pos, L"&", 5)) {
|
121
|
-
FormattedChar fc = { L'&', c.back(), flags(b, u, i) };
|
122
|
-
characters.push_back(fc);
|
123
|
-
pos += 5;
|
124
|
-
continue;
|
125
|
-
}
|
126
|
-
if (html[pos] == L'&' && html[pos + 1]) {
|
127
|
-
int end_of_entity = pos + 1;
|
128
|
-
while (html[end_of_entity] != L';') {
|
129
|
-
if (!iswalnum(static_cast<wint_t>(html[end_of_entity]))) {
|
130
|
-
goto normal_character;
|
131
|
-
}
|
132
|
-
end_of_entity += 1;
|
133
|
-
if (end_of_entity >= len) {
|
134
|
-
goto normal_character;
|
135
|
-
}
|
136
|
-
}
|
137
|
-
wstring entity(html + pos + 1, html + end_of_entity);
|
138
|
-
FormattedChar fc = { 0, c.back(), 0, wstring_to_utf8(entity) };
|
139
|
-
if (!is_entity(fc.entity)) {
|
140
|
-
goto normal_character;
|
141
|
-
}
|
142
|
-
characters.push_back(fc);
|
143
|
-
pos = end_of_entity + 1;
|
144
|
-
continue;
|
145
|
-
}
|
146
|
-
|
147
|
-
normal_character:
|
148
|
-
FormattedChar fc = { html[pos], c.back(), flags(b, u, i) };
|
149
|
-
characters.push_back(fc);
|
150
|
-
pos += 1;
|
151
|
-
}
|
152
|
-
}
|
153
|
-
|
154
|
-
wstring Gosu::FormattedString::unformat() const
|
155
|
-
{
|
156
|
-
if (characters.empty()) return simple_string;
|
157
|
-
|
158
|
-
wstring result(characters.size(), 0);
|
159
|
-
for (int i = 0; i < characters.size(); ++i) {
|
160
|
-
result[i] = characters[i].wc;
|
161
|
-
}
|
162
|
-
return result;
|
163
|
-
}
|
164
|
-
|
165
|
-
const char* Gosu::FormattedString::entity_at(unsigned index) const
|
166
|
-
{
|
167
|
-
if (characters.empty()) return nullptr;
|
168
|
-
if (characters[index].wc != 0) return nullptr;
|
169
|
-
if (characters[index].entity.empty()) return nullptr;
|
170
|
-
|
171
|
-
return characters[index].entity.c_str();
|
172
|
-
}
|
173
|
-
|
174
|
-
wchar_t Gosu::FormattedString::char_at(unsigned index) const
|
175
|
-
{
|
176
|
-
return characters.empty() ? simple_string[index] : characters[index].wc;
|
177
|
-
}
|
178
|
-
|
179
|
-
unsigned Gosu::FormattedString::flags_at(unsigned index) const
|
180
|
-
{
|
181
|
-
return characters.empty() ? simple_flags : characters[index].flags;
|
182
|
-
}
|
183
|
-
|
184
|
-
Gosu::Color Gosu::FormattedString::color_at(unsigned index) const
|
185
|
-
{
|
186
|
-
return characters.empty() ? Color::WHITE : characters[index].color;
|
187
|
-
}
|
188
|
-
|
189
|
-
size_t Gosu::FormattedString::length() const
|
190
|
-
{
|
191
|
-
return characters.empty() ? simple_string.length() : characters.size();
|
192
|
-
}
|
193
|
-
|
194
|
-
Gosu::FormattedString Gosu::FormattedString::range(size_t begin, size_t end) const
|
195
|
-
{
|
196
|
-
FormattedString result;
|
197
|
-
if (characters.empty()) {
|
198
|
-
result.simple_string.assign(simple_string.begin() + begin,
|
199
|
-
simple_string.begin() + end);
|
200
|
-
result.simple_flags = simple_flags;
|
201
|
-
}
|
202
|
-
else {
|
203
|
-
result.characters.assign(characters.begin() + begin,
|
204
|
-
characters.begin() + end);
|
205
|
-
}
|
206
|
-
return result;
|
207
|
-
}
|
208
|
-
|
209
|
-
vector<Gosu::FormattedString> Gosu::FormattedString::split_lines() const
|
210
|
-
{
|
211
|
-
vector<FormattedString> result;
|
212
|
-
unsigned begin = 0;
|
213
|
-
for (unsigned cur = 0; cur < length(); ++cur) {
|
214
|
-
if (char_at(cur) == L'\n') {
|
215
|
-
result.push_back(range(begin, cur));
|
216
|
-
begin = cur + 1;
|
217
|
-
}
|
218
|
-
}
|
219
|
-
result.push_back(range(begin, length()));
|
220
|
-
return result;
|
221
|
-
}
|
222
|
-
|
223
|
-
vector<Gosu::FormattedString> Gosu::FormattedString::split_parts() const
|
224
|
-
{
|
225
|
-
if (characters.empty()) return vector<FormattedString>(1, *this);
|
226
|
-
|
227
|
-
vector<FormattedString> result;
|
228
|
-
unsigned begin = 0;
|
229
|
-
for (unsigned cur = 1; cur < length(); ++cur) {
|
230
|
-
if (!characters[begin].same_style_as(characters[cur])) {
|
231
|
-
result.push_back(range(begin, cur));
|
232
|
-
begin = cur;
|
233
|
-
}
|
234
|
-
}
|
235
|
-
result.push_back(range(begin, length()));
|
236
|
-
return result;
|
237
|
-
}
|
data/src/FormattedString.hpp
DELETED
@@ -1,47 +0,0 @@
|
|
1
|
-
#pragma once
|
2
|
-
|
3
|
-
#include "GraphicsImpl.hpp"
|
4
|
-
#include <Gosu/Color.hpp>
|
5
|
-
#include <Gosu/GraphicsBase.hpp>
|
6
|
-
#include <vector>
|
7
|
-
|
8
|
-
namespace Gosu
|
9
|
-
{
|
10
|
-
class FormattedString
|
11
|
-
{
|
12
|
-
struct FormattedChar
|
13
|
-
{
|
14
|
-
wchar_t wc;
|
15
|
-
Color color;
|
16
|
-
unsigned flags;
|
17
|
-
std::string entity;
|
18
|
-
|
19
|
-
bool same_style_as(const FormattedChar& other) const;
|
20
|
-
};
|
21
|
-
|
22
|
-
// If characters.empty(), use these for the whole string.
|
23
|
-
std::wstring simple_string;
|
24
|
-
unsigned simple_flags;
|
25
|
-
// If not characters.empty(), ignore above fields and use this.
|
26
|
-
std::vector<FormattedChar> characters;
|
27
|
-
|
28
|
-
public:
|
29
|
-
FormattedString();
|
30
|
-
FormattedString(const wchar_t* html, unsigned base_flags);
|
31
|
-
|
32
|
-
std::wstring unformat() const;
|
33
|
-
|
34
|
-
const char* entity_at(unsigned index) const;
|
35
|
-
wchar_t char_at(unsigned index) const;
|
36
|
-
unsigned flags_at(unsigned index) const;
|
37
|
-
Color color_at(unsigned index) const;
|
38
|
-
|
39
|
-
std::size_t length() const;
|
40
|
-
|
41
|
-
FormattedString range(std::size_t begin, std::size_t end) const;
|
42
|
-
|
43
|
-
std::vector<FormattedString> split_lines() const;
|
44
|
-
std::vector<FormattedString> split_parts() const;
|
45
|
-
};
|
46
|
-
}
|
47
|
-
|
data/src/GosuAppDelegate.cpp
DELETED
@@ -1,30 +0,0 @@
|
|
1
|
-
#include <Gosu/Platform.hpp>
|
2
|
-
#if defined(GOSU_IS_IPHONE)
|
3
|
-
|
4
|
-
#import "GosuAppDelegate.h"
|
5
|
-
#import <Gosu/Gosu.hpp>
|
6
|
-
|
7
|
-
Gosu::Window& window_instance();
|
8
|
-
|
9
|
-
@implementation GosuAppDelegate
|
10
|
-
|
11
|
-
- (BOOL)application:(UIApplication*)application
|
12
|
-
didFinishLaunchingWithOptions:(NSDictionary*)launchOptions
|
13
|
-
{
|
14
|
-
self.window = (__bridge UIWindow*) window_instance().UIWindow();
|
15
|
-
[self.window makeKeyAndVisible];
|
16
|
-
|
17
|
-
return YES;
|
18
|
-
}
|
19
|
-
|
20
|
-
@end
|
21
|
-
|
22
|
-
int main(int argc, char* argv[])
|
23
|
-
{
|
24
|
-
@autoreleasepool {
|
25
|
-
Gosu::use_resource_directory();
|
26
|
-
return UIApplicationMain(argc, argv, nil, NSStringFromClass([GosuAppDelegate class]));
|
27
|
-
}
|
28
|
-
}
|
29
|
-
|
30
|
-
#endif
|
data/src/GosuAppDelegate.h
DELETED
data/src/GosuGLView.h
DELETED
data/src/TextApple.cpp
DELETED
@@ -1,212 +0,0 @@
|
|
1
|
-
#include <Gosu/Platform.hpp>
|
2
|
-
#if defined(GOSU_IS_MAC)
|
3
|
-
|
4
|
-
#include <Gosu/Text.hpp>
|
5
|
-
#include <Gosu/Bitmap.hpp>
|
6
|
-
#include <Gosu/Math.hpp>
|
7
|
-
#include <Gosu/Utility.hpp>
|
8
|
-
#include <cmath>
|
9
|
-
#include <map>
|
10
|
-
|
11
|
-
#if defined(GOSU_IS_IPHONE)
|
12
|
-
#import <CoreGraphics/CoreGraphics.h>
|
13
|
-
#import <UIKit/UIKit.h>
|
14
|
-
typedef UIFont AppleFont;
|
15
|
-
#else
|
16
|
-
#import <AppKit/AppKit.h>
|
17
|
-
typedef NSFont AppleFont;
|
18
|
-
#endif
|
19
|
-
|
20
|
-
using namespace std;
|
21
|
-
|
22
|
-
// If a font is a filename, loads the font and returns its family name that can be used
|
23
|
-
// like any system font. Otherwise, just returns the family name.
|
24
|
-
static string normalize_font(const string& font_name)
|
25
|
-
{
|
26
|
-
#ifdef GOSU_IS_IPHONE
|
27
|
-
// On iOS, we have no support for loading font files yet. However, if you register your fonts
|
28
|
-
// via your app's Info.plist, you should be able to reference them by name.
|
29
|
-
return font_name;
|
30
|
-
#else
|
31
|
-
static map<string, string> family_of_files;
|
32
|
-
|
33
|
-
// Not a path name: It is already a family name.
|
34
|
-
if (font_name.find("/") == font_name.npos) {
|
35
|
-
return font_name;
|
36
|
-
}
|
37
|
-
|
38
|
-
// Already activated font & extracted family name.
|
39
|
-
if (family_of_files.count(font_name) > 0) {
|
40
|
-
return family_of_files[font_name];
|
41
|
-
}
|
42
|
-
|
43
|
-
NSURL* url = [NSURL fileURLWithPath:[NSString stringWithUTF8String:font_name.c_str()]
|
44
|
-
isDirectory:NO];
|
45
|
-
if (url == nullptr) {
|
46
|
-
return family_of_files[font_name] = Gosu::default_font_name();
|
47
|
-
}
|
48
|
-
CFURLRef url_ref = (__bridge CFURLRef) url;
|
49
|
-
|
50
|
-
NSArray* descriptors = CFBridgingRelease(CTFontManagerCreateFontDescriptorsFromURL(url_ref));
|
51
|
-
if (descriptors.count < 1 ||
|
52
|
-
!CTFontManagerRegisterFontsForURL(url_ref, kCTFontManagerScopeProcess, nullptr)) {
|
53
|
-
return family_of_files[font_name] = Gosu::default_font_name();
|
54
|
-
}
|
55
|
-
|
56
|
-
CTFontDescriptorRef ref = (__bridge CTFontDescriptorRef) descriptors[0];
|
57
|
-
CFTypeRef family_name_ref = CTFontDescriptorCopyAttribute(ref, kCTFontFamilyNameAttribute);
|
58
|
-
NSString* family_name = CFBridgingRelease(family_name_ref);
|
59
|
-
return family_of_files[font_name] = family_name.UTF8String ?: "";
|
60
|
-
#endif
|
61
|
-
}
|
62
|
-
|
63
|
-
static AppleFont* get_font(string font_name, unsigned font_flags, double height)
|
64
|
-
{
|
65
|
-
font_name = normalize_font(font_name);
|
66
|
-
|
67
|
-
static map<pair<string, pair<unsigned, double>>, AppleFont*> used_fonts;
|
68
|
-
|
69
|
-
auto key = make_pair(font_name, make_pair(font_flags, height));
|
70
|
-
|
71
|
-
AppleFont* result = used_fonts[key];
|
72
|
-
if (!result) {
|
73
|
-
NSString* name = [NSString stringWithUTF8String:font_name.c_str()];
|
74
|
-
#ifdef GOSU_IS_IPHONE
|
75
|
-
result = [AppleFont fontWithName:name size:height];
|
76
|
-
#else
|
77
|
-
NSFontDescriptor* desc =
|
78
|
-
[[NSFontDescriptor fontDescriptorWithFontAttributes:nil] fontDescriptorWithFamily:name];
|
79
|
-
result = [NSFont fontWithDescriptor:desc size:height];
|
80
|
-
if (result && (font_flags & Gosu::FF_BOLD)) {
|
81
|
-
result =
|
82
|
-
[[NSFontManager sharedFontManager] convertFont:result toHaveTrait:NSFontBoldTrait];
|
83
|
-
}
|
84
|
-
if (result && (font_flags & Gosu::FF_ITALIC)) {
|
85
|
-
result = [[NSFontManager sharedFontManager] convertFont:result
|
86
|
-
toHaveTrait:NSFontItalicTrait];
|
87
|
-
}
|
88
|
-
#endif
|
89
|
-
if (result == nullptr) {
|
90
|
-
if (font_name != Gosu::default_font_name()) {
|
91
|
-
result = get_font(Gosu::default_font_name(), 0, height);
|
92
|
-
}
|
93
|
-
else {
|
94
|
-
throw runtime_error("Cannot load default font");
|
95
|
-
}
|
96
|
-
}
|
97
|
-
used_fonts[key] = result;
|
98
|
-
}
|
99
|
-
return result;
|
100
|
-
}
|
101
|
-
|
102
|
-
string Gosu::default_font_name()
|
103
|
-
{
|
104
|
-
return "Arial";
|
105
|
-
}
|
106
|
-
|
107
|
-
#ifndef GOSU_IS_IPHONE
|
108
|
-
static NSDictionary* attribute_dictionary(NSFont* font, unsigned font_flags)
|
109
|
-
{
|
110
|
-
auto underline_style =
|
111
|
-
(font_flags & Gosu::FF_UNDERLINE) ? NSUnderlineStyleSingle : NSUnderlineStyleNone;
|
112
|
-
return @{
|
113
|
-
NSFontAttributeName: font,
|
114
|
-
NSForegroundColorAttributeName: [NSColor whiteColor],
|
115
|
-
NSUnderlineStyleAttributeName: @(underline_style)
|
116
|
-
};
|
117
|
-
}
|
118
|
-
#endif
|
119
|
-
|
120
|
-
unsigned Gosu::text_width(const string& text, const string& font_name,
|
121
|
-
unsigned font_height, unsigned font_flags)
|
122
|
-
{
|
123
|
-
if (text.find_first_of("\r\n") != text.npos) {
|
124
|
-
throw invalid_argument("text_width cannot handle line breaks");
|
125
|
-
}
|
126
|
-
|
127
|
-
AppleFont* font = get_font(font_name, font_flags, font_height);
|
128
|
-
|
129
|
-
// This will, of course, compute a too large size; font_height is in pixels,
|
130
|
-
// the method expects point.
|
131
|
-
NSString* string = [NSString stringWithUTF8String:text.c_str()];
|
132
|
-
#ifndef GOSU_IS_IPHONE
|
133
|
-
NSDictionary* attributes = attribute_dictionary(font, font_flags);
|
134
|
-
NSSize size = [string sizeWithAttributes:attributes];
|
135
|
-
#else
|
136
|
-
CGSize size = [string sizeWithFont:font];
|
137
|
-
#endif
|
138
|
-
|
139
|
-
// Now adjust the scaling...
|
140
|
-
return ceil(size.width / size.height * font_height);
|
141
|
-
}
|
142
|
-
|
143
|
-
void Gosu::draw_text(Bitmap& bitmap, const string& text, int x, int y, Color c,
|
144
|
-
const string& font_name, unsigned font_height, unsigned font_flags)
|
145
|
-
{
|
146
|
-
if (text.find_first_of("\r\n") != text.npos) {
|
147
|
-
throw invalid_argument("the argument to draw_text cannot contain line breaks");
|
148
|
-
}
|
149
|
-
|
150
|
-
AppleFont* font = get_font(font_name, font_flags, font_height);
|
151
|
-
NSString* string = [NSString stringWithUTF8String:text.c_str()];
|
152
|
-
|
153
|
-
#ifndef GOSU_IS_IPHONE
|
154
|
-
NSDictionary* attributes = attribute_dictionary(font, font_flags);
|
155
|
-
NSSize size = [string sizeWithAttributes:attributes];
|
156
|
-
#else
|
157
|
-
CGSize size = [string sizeWithFont:font];
|
158
|
-
#endif
|
159
|
-
|
160
|
-
unsigned width = static_cast<unsigned>(round(size.width / size.height * font_height));
|
161
|
-
|
162
|
-
// Get the width and height of the image
|
163
|
-
Bitmap bmp(width, font_height, 0x00ffffff);
|
164
|
-
|
165
|
-
// Use a temporary context to draw the CGImage to the buffer.
|
166
|
-
CGColorSpaceRef color_space = CGColorSpaceCreateDeviceRGB();
|
167
|
-
CGContextRef context = CGBitmapContextCreate(bmp.data(), bmp.width(), bmp.height(), 8,
|
168
|
-
bmp.width() * 4, color_space, kCGImageAlphaPremultipliedLast);
|
169
|
-
CGColorSpaceRelease(color_space);
|
170
|
-
#ifdef GOSU_IS_IPHONE
|
171
|
-
CGFloat color[] = { 1.f, 1.f, 1.f, 0.f };
|
172
|
-
CGContextSetStrokeColor(context, color);
|
173
|
-
CGContextSetFillColor(context, color);
|
174
|
-
#endif
|
175
|
-
|
176
|
-
// Use new font with proper size this time.
|
177
|
-
font = get_font(font_name, font_flags, font_height * font_height / size.height);
|
178
|
-
|
179
|
-
#ifdef GOSU_IS_IPHONE
|
180
|
-
CGContextTranslateCTM(context, 0, font_height);
|
181
|
-
CGContextScaleCTM(context, 1, -1);
|
182
|
-
UIGraphicsPushContext(context);
|
183
|
-
[string drawAtPoint:CGPointZero withFont:font];
|
184
|
-
UIGraphicsPopContext();
|
185
|
-
#else
|
186
|
-
NSPoint NSPointZero = { 0, 0 };
|
187
|
-
attributes = attribute_dictionary(font, font_flags);
|
188
|
-
|
189
|
-
[NSGraphicsContext saveGraphicsState];
|
190
|
-
[NSGraphicsContext
|
191
|
-
setCurrentContext:[NSGraphicsContext graphicsContextWithGraphicsPort:(void*)context
|
192
|
-
flipped:false]];
|
193
|
-
[string drawAtPoint:NSPointZero withAttributes:attributes];
|
194
|
-
[NSGraphicsContext restoreGraphicsState];
|
195
|
-
#endif
|
196
|
-
CGContextRelease(context);
|
197
|
-
|
198
|
-
int effective_width = Gosu::clamp<int>(width, 0, bitmap.width() - x);
|
199
|
-
int effective_height = Gosu::clamp<int>(font_height, 0, bitmap.height() - y);
|
200
|
-
|
201
|
-
// Now copy the set pixels back.
|
202
|
-
for (int rel_y = 0; rel_y < effective_height; ++rel_y) {
|
203
|
-
for (int rel_x = 0; rel_x < effective_width; ++rel_x) {
|
204
|
-
c.set_alpha(bmp.get_pixel(rel_x, rel_y).alpha());
|
205
|
-
if (c.alpha()) {
|
206
|
-
bitmap.set_pixel(x + rel_x, y + rel_y, c);
|
207
|
-
}
|
208
|
-
}
|
209
|
-
}
|
210
|
-
}
|
211
|
-
|
212
|
-
#endif
|