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.
Files changed (80) hide show
  1. checksums.yaml +4 -4
  2. data/Gosu/Audio.hpp +15 -11
  3. data/Gosu/Font.hpp +24 -20
  4. data/Gosu/Fwd.hpp +1 -1
  5. data/Gosu/Graphics.hpp +8 -9
  6. data/Gosu/ImageData.hpp +1 -1
  7. data/Gosu/Input.hpp +1 -1
  8. data/Gosu/Math.hpp +0 -18
  9. data/Gosu/Text.hpp +22 -30
  10. data/Gosu/TextInput.hpp +13 -0
  11. data/Gosu/Utility.hpp +2 -0
  12. data/Gosu/Window.hpp +3 -3
  13. data/README.md +3 -4
  14. data/ext/gosu/extconf.rb +7 -9
  15. data/lib/gosu/swig_patches.rb +1 -4
  16. data/rdoc/gosu.rb +34 -9
  17. data/src/Audio.cpp +6 -6
  18. data/src/AudioImpl.cpp +2 -2
  19. data/src/Bitmap.cpp +1 -2
  20. data/src/BitmapIO.cpp +21 -2
  21. data/src/BlockAllocator.cpp +1 -1
  22. data/src/Channel.cpp +7 -1
  23. data/src/ClipRectStack.hpp +4 -1
  24. data/src/Color.cpp +2 -1
  25. data/src/DirectoriesWin.cpp +1 -1
  26. data/src/DrawOp.hpp +8 -4
  27. data/src/DrawOpQueue.hpp +13 -24
  28. data/src/FileUnix.cpp +3 -1
  29. data/src/Font.cpp +92 -96
  30. data/src/GosuGLView.cpp +59 -31
  31. data/src/GosuGLView.hpp +14 -0
  32. data/src/GosuViewController.cpp +21 -21
  33. data/src/{GosuViewController.h → GosuViewController.hpp} +2 -4
  34. data/src/Graphics.cpp +71 -38
  35. data/src/GraphicsImpl.hpp +12 -29
  36. data/src/Image.cpp +5 -7
  37. data/src/Input.cpp +7 -5
  38. data/src/InputUIKit.cpp +19 -37
  39. data/src/Macro.cpp +10 -2
  40. data/src/MarkupParser.cpp +241 -0
  41. data/src/MarkupParser.hpp +61 -0
  42. data/src/Math.cpp +1 -1
  43. data/src/OffScreenTarget.cpp +99 -0
  44. data/src/OffScreenTarget.hpp +23 -0
  45. data/src/OggFile.hpp +10 -0
  46. data/src/RenderState.hpp +0 -2
  47. data/src/Resolution.cpp +2 -2
  48. data/src/RubyGosu.cxx +457 -244
  49. data/src/TexChunk.cpp +8 -6
  50. data/src/Text.cpp +58 -345
  51. data/src/TextBuilder.cpp +138 -0
  52. data/src/TextBuilder.hpp +55 -0
  53. data/src/TextInput.cpp +27 -10
  54. data/src/Texture.cpp +22 -17
  55. data/src/Texture.hpp +19 -20
  56. data/src/TimingApple.cpp +5 -7
  57. data/src/TimingUnix.cpp +1 -4
  58. data/src/TimingWin.cpp +4 -1
  59. data/src/TrueTypeFont.cpp +282 -0
  60. data/src/TrueTypeFont.hpp +66 -0
  61. data/src/TrueTypeFontApple.cpp +65 -0
  62. data/src/TrueTypeFontUnix.cpp +91 -0
  63. data/src/TrueTypeFontWin.cpp +82 -0
  64. data/src/Utility.cpp +40 -0
  65. data/src/Window.cpp +7 -6
  66. data/src/WindowUIKit.cpp +9 -4
  67. data/src/stb_truetype.h +4589 -0
  68. data/src/utf8proc.c +755 -0
  69. data/src/utf8proc.h +699 -0
  70. data/src/utf8proc_data.h +14386 -0
  71. metadata +23 -16
  72. data/src/FormattedString.cpp +0 -237
  73. data/src/FormattedString.hpp +0 -47
  74. data/src/GosuAppDelegate.cpp +0 -30
  75. data/src/GosuAppDelegate.h +0 -8
  76. data/src/GosuGLView.h +0 -8
  77. data/src/TextApple.cpp +0 -212
  78. data/src/TextTTFWin.cpp +0 -197
  79. data/src/TextUnix.cpp +0 -280
  80. 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.13.3
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-03-08 00:00:00.000000000 Z
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.h
85
+ - src/GosuGLView.hpp
90
86
  - src/GosuViewController.cpp
91
- - src/GosuViewController.h
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/TextApple.cpp
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.8.2
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: '0'
168
+ version: 1.3.1
162
169
  requirements: []
163
170
  rubyforge_project:
164
- rubygems_version: 2.7.4
171
+ rubygems_version: 2.7.6
165
172
  signing_key:
166
173
  specification_version: 4
167
174
  summary: 2D game development library.
@@ -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"&lt;", 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"&gt;", 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"&amp;", 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
- }
@@ -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
-
@@ -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
@@ -1,8 +0,0 @@
1
- #import <UIKit/UIKit.h>
2
-
3
-
4
- @interface GosuAppDelegate : UIResponder <UIApplicationDelegate>
5
-
6
- @property (nonatomic, strong) UIWindow *window;
7
-
8
- @end
@@ -1,8 +0,0 @@
1
- #import <UIKit/UIKit.h>
2
-
3
-
4
- @interface GosuGLView : UIView
5
-
6
- - (void)redrawGL:(void (^)())code;
7
-
8
- @end
@@ -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