gosu 0.13.3 → 0.14.0.pre2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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