gosu 0.10.6 → 0.10.7
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/COPYING +1 -1
- data/Gosu/Gosu.hpp +1 -1
- data/Gosu/Version.hpp +3 -3
- data/README.md +4 -0
- data/ext/gosu/extconf.rb +8 -8
- data/ext/gosu/gosu_wrap.cxx +12 -7
- data/src/AppleUtility.hpp +19 -62
- data/src/Audio/Audio.cpp +31 -23
- data/src/Audio/AudioToolboxFile.hpp +19 -18
- data/src/Bitmap/BitmapIO.cpp +32 -17
- data/src/DirectoriesApple.mm +36 -41
- data/src/Input/Input.cpp +22 -6
- data/src/Input/InputUIKit.mm +37 -29
- data/src/Text/Font.cpp +1 -1
- data/src/Text/TextApple.mm +50 -41
- data/src/UIKit/GosuAppDelegate.mm +1 -1
- data/src/UIKit/GosuGLView.mm +0 -2
- data/src/UIKit/GosuViewController.mm +7 -10
- data/src/UtilityApple.mm +26 -19
- data/src/WindowUIKit.mm +22 -12
- data/src/stb_image.h +499 -253
- data/src/stb_image_write.h +98 -43
- data/src/stb_vorbis.c +188 -232
- metadata +4 -4
data/src/Bitmap/BitmapIO.cpp
CHANGED
@@ -9,6 +9,13 @@
|
|
9
9
|
#define STB_IMAGE_IMPLEMENTATION
|
10
10
|
#define STBI_NO_STDIO
|
11
11
|
#define STBI_NO_LINEAR
|
12
|
+
|
13
|
+
// Work around this bug:
|
14
|
+
// https://bugs.launchpad.net/ubuntu/+source/gcc-5/+bug/1568899
|
15
|
+
#ifdef GOSU_IS_X
|
16
|
+
#define STBI_NO_SIMD
|
17
|
+
#endif
|
18
|
+
|
12
19
|
#include "../stb_image.h"
|
13
20
|
|
14
21
|
namespace
|
@@ -106,32 +113,40 @@ void Gosu::saveImageFile(const Gosu::Bitmap& bitmap, const std::wstring& filenam
|
|
106
113
|
throw std::runtime_error("Could not save image data to file: " + utf8);
|
107
114
|
}
|
108
115
|
|
116
|
+
namespace
|
117
|
+
{
|
118
|
+
void stbiWriteToWriter(void *context, void *data, int size)
|
119
|
+
{
|
120
|
+
Gosu::Writer *writer = reinterpret_cast<Gosu::Writer*>(context);
|
121
|
+
writer->write(data, size);
|
122
|
+
}
|
123
|
+
}
|
124
|
+
|
109
125
|
void Gosu::saveImageFile(const Gosu::Bitmap& bitmap, Gosu::Writer writer,
|
110
126
|
const std::wstring& formatHint)
|
111
127
|
{
|
112
|
-
|
113
|
-
const_cast<unsigned char*>(reinterpret_cast<const unsigned char*>(bitmap.data()));
|
114
|
-
|
115
|
-
// TODO: Use the new *_to_func functions in stb_imagewrite.h instead:
|
116
|
-
// https://github.com/nothings/stb/blob/master/stb_image_write.h#L39
|
117
|
-
int length;
|
118
|
-
unsigned char* png =
|
119
|
-
stbi_write_png_to_mem(rgba, 0, bitmap.width(), bitmap.height(), 4, &length);
|
120
|
-
|
121
|
-
if (png == 0)
|
122
|
-
throw std::runtime_error("Could not save image data to memory");
|
128
|
+
int ok;
|
123
129
|
|
124
|
-
|
130
|
+
if (isExtension(formatHint.c_str(), L"bmp"))
|
125
131
|
{
|
126
|
-
|
132
|
+
ok = stbi_write_bmp_to_func(stbiWriteToWriter, &writer,
|
133
|
+
bitmap.width(), bitmap.height(), 4, bitmap.data());
|
127
134
|
}
|
128
|
-
|
135
|
+
else if (isExtension(formatHint.c_str(), L"tga"))
|
129
136
|
{
|
130
|
-
|
131
|
-
|
137
|
+
stbi_write_tga_with_rle = 0;
|
138
|
+
ok = stbi_write_tga_to_func(stbiWriteToWriter, &writer,
|
139
|
+
bitmap.width(), bitmap.height(), 4, bitmap.data());
|
140
|
+
}
|
141
|
+
else
|
142
|
+
{
|
143
|
+
ok = stbi_write_png_to_func(stbiWriteToWriter, &writer,
|
144
|
+
bitmap.width(), bitmap.height(), 4, bitmap.data(), 0);
|
132
145
|
}
|
133
146
|
|
134
|
-
|
147
|
+
if (ok == 0)
|
148
|
+
throw std::runtime_error("Could not save image data to memory (format hint = '" +
|
149
|
+
Gosu::wstringToUTF8(formatHint) + "'");
|
135
150
|
}
|
136
151
|
|
137
152
|
// Deprecated methods.
|
data/src/DirectoriesApple.mm
CHANGED
@@ -5,9 +5,9 @@
|
|
5
5
|
#import <unistd.h>
|
6
6
|
|
7
7
|
|
8
|
-
static std::wstring stringFromNSString(NSString*
|
8
|
+
static std::wstring stringFromNSString(NSString *string, const wchar_t *fallback)
|
9
9
|
{
|
10
|
-
return string ? Gosu::utf8ToWstring([string UTF8String]) :
|
10
|
+
return string ? Gosu::utf8ToWstring([string UTF8String]) : fallback;
|
11
11
|
}
|
12
12
|
|
13
13
|
void Gosu::useResourceDirectory()
|
@@ -17,60 +17,55 @@ void Gosu::useResourceDirectory()
|
|
17
17
|
|
18
18
|
std::wstring Gosu::userSettingsPrefix()
|
19
19
|
{
|
20
|
-
static std::wstring result
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
}
|
20
|
+
static std::wstring result = [] {
|
21
|
+
@autoreleasepool {
|
22
|
+
NSString *library =
|
23
|
+
NSSearchPathForDirectoriesInDomains(NSLibraryDirectory, NSUserDomainMask, YES)[0];
|
24
|
+
NSString *preferences = [library stringByAppendingPathComponent:@"Preferences"];
|
25
|
+
|
26
|
+
return stringFromNSString(preferences, L".") + L"/";
|
27
|
+
}
|
28
|
+
}();
|
30
29
|
return result;
|
31
30
|
}
|
32
31
|
|
33
32
|
std::wstring Gosu::userDocsPrefix()
|
34
33
|
{
|
35
|
-
static std::wstring result
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
}
|
34
|
+
static std::wstring result = [] {
|
35
|
+
@autoreleasepool {
|
36
|
+
NSString *documents =
|
37
|
+
NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES)[0];
|
38
|
+
|
39
|
+
return stringFromNSString(documents, L".") + L"/";
|
40
|
+
}
|
41
|
+
}();
|
44
42
|
return result;
|
45
43
|
}
|
46
44
|
|
47
45
|
std::wstring Gosu::resourcePrefix()
|
48
46
|
{
|
49
|
-
static std::wstring result
|
50
|
-
|
51
|
-
|
52
|
-
|
53
|
-
|
54
|
-
|
55
|
-
result = stringFromNSString(resourcePath, L".") + L"/";
|
56
|
-
}
|
47
|
+
static std::wstring result = [] {
|
48
|
+
@autoreleasepool {
|
49
|
+
NSString *resources = [NSBundle mainBundle].resourcePath;
|
50
|
+
return stringFromNSString(resources, L".") + L"/";
|
51
|
+
}
|
52
|
+
}();
|
57
53
|
return result;
|
58
54
|
}
|
59
55
|
|
60
56
|
std::wstring Gosu::sharedResourcePrefix()
|
61
57
|
{
|
62
|
-
|
58
|
+
#ifdef GOSU_IS_IPHONE
|
63
59
|
return resourcePrefix();
|
64
|
-
|
65
|
-
static std::wstring result
|
66
|
-
|
67
|
-
|
68
|
-
|
69
|
-
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
}
|
60
|
+
#else
|
61
|
+
static std::wstring result = [] {
|
62
|
+
@autoreleasepool {
|
63
|
+
NSString *bundlePath = [NSBundle mainBundle].bundlePath;
|
64
|
+
NSString *containingPath = [bundlePath stringByDeletingLastPathComponent];
|
65
|
+
|
66
|
+
return stringFromNSString(containingPath, L".");
|
67
|
+
}
|
68
|
+
}();
|
74
69
|
return result;
|
75
|
-
|
70
|
+
#endif
|
76
71
|
}
|
data/src/Input/Input.cpp
CHANGED
@@ -48,7 +48,11 @@ struct Gosu::Input::Impl
|
|
48
48
|
|
49
49
|
void updateMousePosition()
|
50
50
|
{
|
51
|
-
|
51
|
+
// Do not use GetGlobalMouseState on Linux for now to prevent this bug:
|
52
|
+
// https://github.com/gosu/gosu/issues/326
|
53
|
+
// Once SDL 2.0.5 has been released, we can use this function as a workaround:
|
54
|
+
// https://wiki.libsdl.org/SDL_GetWindowBordersSize
|
55
|
+
#if SDL_VERSION_ATLEAST(2, 0, 4) && !defined(GOSU_IS_X)
|
52
56
|
int x, y, windowX, windowY;
|
53
57
|
SDL_GetWindowPosition(window, &windowX, &windowY);
|
54
58
|
SDL_GetGlobalMouseState(&x, &y);
|
@@ -60,6 +64,22 @@ struct Gosu::Input::Impl
|
|
60
64
|
#endif
|
61
65
|
}
|
62
66
|
|
67
|
+
void setMousePosition(double x, double y)
|
68
|
+
{
|
69
|
+
SDL_WarpMouseInWindow(window,
|
70
|
+
(x - mouseOffsetX) / mouseFactorX, (y - mouseOffsetY) / mouseFactorY);
|
71
|
+
|
72
|
+
#if SDL_VERSION_ATLEAST(2, 0, 4) && !defined(GOSU_IS_X)
|
73
|
+
// On systems where we have a working GetGlobalMouseState, we can warp the mouse and
|
74
|
+
// retrieve its position directly afterwards.
|
75
|
+
updateMousePosition();
|
76
|
+
#else
|
77
|
+
// Otherwise, we have to assume that setting the position worked, because if we update the
|
78
|
+
// mouse position now, we'll get the previous position.
|
79
|
+
mouseX = x, mouseY = y;
|
80
|
+
#endif
|
81
|
+
}
|
82
|
+
|
63
83
|
void enqueueEvent(int id, bool down)
|
64
84
|
{
|
65
85
|
eventQueue.push_back(down ? id : ~id);
|
@@ -378,11 +398,7 @@ double Gosu::Input::mouseY() const
|
|
378
398
|
|
379
399
|
void Gosu::Input::setMousePosition(double x, double y)
|
380
400
|
{
|
381
|
-
|
382
|
-
(x - pimpl->mouseOffsetX) / pimpl->mouseFactorX,
|
383
|
-
(y - pimpl->mouseOffsetY) / pimpl->mouseFactorY);
|
384
|
-
|
385
|
-
pimpl->updateMousePosition();
|
401
|
+
pimpl->setMousePosition(x, y);
|
386
402
|
}
|
387
403
|
|
388
404
|
void Gosu::Input::setMouseFactors(double factorX, double factorY,
|
data/src/Input/InputUIKit.mm
CHANGED
@@ -14,29 +14,32 @@ unsigned Gosu::TextInput::selectionStart() const { return 0; }
|
|
14
14
|
|
15
15
|
struct Gosu::Input::Impl
|
16
16
|
{
|
17
|
-
UIView*
|
17
|
+
UIView *view;
|
18
18
|
float mouseX, mouseY;
|
19
19
|
float factorX, factorY;
|
20
20
|
float updateInterval;
|
21
21
|
|
22
|
-
|
23
|
-
std::
|
22
|
+
NSMutableSet *currentTouchesSet;
|
23
|
+
std::unique_ptr<Gosu::Touches> currentTouchesVector;
|
24
24
|
|
25
|
-
Touch translateTouch(UITouch*
|
25
|
+
Touch translateTouch(UITouch *uiTouch)
|
26
26
|
{
|
27
|
-
CGPoint point = [uiTouch locationInView:
|
28
|
-
|
29
|
-
|
30
|
-
|
27
|
+
CGPoint point = [uiTouch locationInView:view];
|
28
|
+
|
29
|
+
return (Touch) {
|
30
|
+
.id = (__bridge void *)uiTouch,
|
31
|
+
.x = (float) point.x * factorX,
|
32
|
+
.y = (float) point.y * factorY,
|
33
|
+
};
|
31
34
|
}
|
32
35
|
};
|
33
36
|
|
34
37
|
Gosu::Input::Input(void* view, float updateInterval)
|
35
38
|
: pimpl(new Impl)
|
36
39
|
{
|
37
|
-
pimpl->view = (UIView*)view;
|
40
|
+
pimpl->view = (__bridge UIView *)view;
|
38
41
|
pimpl->updateInterval = updateInterval;
|
39
|
-
pimpl->currentTouchesSet
|
42
|
+
pimpl->currentTouchesSet = [NSMutableSet new];
|
40
43
|
pimpl->mouseX = pimpl->mouseY = -1000;
|
41
44
|
setMouseFactors(1, 1);
|
42
45
|
}
|
@@ -45,27 +48,27 @@ Gosu::Input::~Input()
|
|
45
48
|
{
|
46
49
|
}
|
47
50
|
|
48
|
-
void Gosu::Input::feedTouchEvent(int type, void*
|
51
|
+
void Gosu::Input::feedTouchEvent(int type, void *touches)
|
49
52
|
{
|
50
|
-
NSSet *uiTouches = (NSSet *)touches;
|
53
|
+
NSSet *uiTouches = (__bridge NSSet *)touches;
|
51
54
|
|
52
55
|
pimpl->currentTouchesVector.reset();
|
53
56
|
|
54
57
|
std::tr1::function<void (Touch)>* callback = nullptr;
|
55
58
|
|
56
59
|
if (type == 0) {
|
57
|
-
[pimpl->currentTouchesSet
|
60
|
+
[pimpl->currentTouchesSet unionSet:uiTouches];
|
58
61
|
callback = &onTouchBegan;
|
59
62
|
}
|
60
63
|
else if (type == 1) {
|
61
64
|
callback = &onTouchMoved;
|
62
65
|
}
|
63
66
|
else if (type == 2) {
|
64
|
-
[pimpl->currentTouchesSet
|
67
|
+
[pimpl->currentTouchesSet minusSet:uiTouches];
|
65
68
|
callback = &onTouchEnded;
|
66
69
|
}
|
67
70
|
else if (type == 3) {
|
68
|
-
[pimpl->currentTouchesSet
|
71
|
+
[pimpl->currentTouchesSet minusSet:uiTouches];
|
69
72
|
callback = &onTouchCancelled;
|
70
73
|
}
|
71
74
|
|
@@ -115,11 +118,11 @@ void Gosu::Input::setMouseFactors(double factorX, double factorY, double offsetX
|
|
115
118
|
|
116
119
|
const Gosu::Touches& Gosu::Input::currentTouches() const
|
117
120
|
{
|
118
|
-
if (!pimpl->currentTouchesVector.get())
|
119
|
-
{
|
121
|
+
if (!pimpl->currentTouchesVector.get()) {
|
120
122
|
pimpl->currentTouchesVector.reset(new Gosu::Touches);
|
121
|
-
for (UITouch* uiTouch in pimpl->currentTouchesSet
|
123
|
+
for (UITouch* uiTouch in pimpl->currentTouchesSet) {
|
122
124
|
pimpl->currentTouchesVector->push_back(pimpl->translateTouch(uiTouch));
|
125
|
+
}
|
123
126
|
}
|
124
127
|
return *pimpl->currentTouchesVector;
|
125
128
|
}
|
@@ -144,30 +147,35 @@ void Gosu::Input::update()
|
|
144
147
|
// Check for dead touches and remove from vector if
|
145
148
|
// necessary
|
146
149
|
|
147
|
-
|
150
|
+
NSMutableSet *deadTouches = nil;
|
148
151
|
|
149
|
-
for (UITouch*
|
152
|
+
for (UITouch *touch in pimpl->currentTouchesSet)
|
150
153
|
{
|
151
154
|
UITouchPhase phase = [touch phase];
|
152
155
|
if (phase == UITouchPhaseBegan ||
|
153
|
-
|
154
|
-
|
156
|
+
phase == UITouchPhaseMoved ||
|
157
|
+
phase == UITouchPhaseStationary) {
|
155
158
|
continue;
|
159
|
+
}
|
156
160
|
|
157
161
|
// Something was deleted, we will need the set.
|
158
|
-
if (!deadTouches
|
159
|
-
deadTouches
|
160
|
-
|
162
|
+
if (!deadTouches) {
|
163
|
+
deadTouches = [NSMutableSet new];
|
164
|
+
}
|
165
|
+
[deadTouches addObject:touch];
|
161
166
|
}
|
162
167
|
|
163
168
|
// Has something been deleted?
|
164
|
-
if (deadTouches
|
169
|
+
if (deadTouches)
|
165
170
|
{
|
166
171
|
pimpl->currentTouchesVector.reset();
|
167
|
-
[pimpl->currentTouchesSet
|
168
|
-
|
169
|
-
|
172
|
+
[pimpl->currentTouchesSet minusSet: deadTouches];
|
173
|
+
|
174
|
+
if (onTouchEnded) {
|
175
|
+
for (UITouch *uiTouch in deadTouches) {
|
170
176
|
onTouchEnded(pimpl->translateTouch(uiTouch));
|
177
|
+
}
|
178
|
+
}
|
171
179
|
}
|
172
180
|
}
|
173
181
|
|
data/src/Text/Font.cpp
CHANGED
@@ -65,7 +65,7 @@ struct Gosu::Font::Impl
|
|
65
65
|
// charString.clear();
|
66
66
|
unsigned charWidth = Gosu::textWidth(charString, name, height, flags);
|
67
67
|
|
68
|
-
Bitmap bitmap(charWidth, height);
|
68
|
+
Bitmap bitmap(charWidth, height, 0x00ffffff);
|
69
69
|
drawText(bitmap, charString, 0, 0, Color::WHITE, name, height, flags);
|
70
70
|
info.image.reset(new Image(bitmap));
|
71
71
|
info.factor = 0.5;
|
data/src/Text/TextApple.mm
CHANGED
@@ -20,7 +20,6 @@ typedef NSFont OSXFont;
|
|
20
20
|
|
21
21
|
namespace
|
22
22
|
{
|
23
|
-
using Gosu::ObjCRef;
|
24
23
|
using Gosu::CFRef;
|
25
24
|
|
26
25
|
// If a font is a filename, loads the font and returns its family name that can be used
|
@@ -35,12 +34,14 @@ namespace
|
|
35
34
|
static map<wstring, wstring> familyOfFiles;
|
36
35
|
|
37
36
|
// Not a path name: It is already a family name
|
38
|
-
if (fontName.find(L"/") == std::wstring::npos)
|
37
|
+
if (fontName.find(L"/") == std::wstring::npos) {
|
39
38
|
return fontName;
|
39
|
+
}
|
40
40
|
|
41
41
|
// Already activated font & extracted family name
|
42
|
-
if (familyOfFiles.count(fontName) > 0)
|
42
|
+
if (familyOfFiles.count(fontName) > 0) {
|
43
43
|
return familyOfFiles[fontName];
|
44
|
+
}
|
44
45
|
|
45
46
|
CFRef<CFStringRef> urlString(
|
46
47
|
CFStringCreateWithBytes(NULL,
|
@@ -49,22 +50,24 @@ namespace
|
|
49
50
|
kCFStringEncodingUTF32LE, NO));
|
50
51
|
CFRef<CFURLRef> url(
|
51
52
|
CFURLCreateWithFileSystemPath(NULL, urlString.obj(), kCFURLPOSIXPathStyle, YES));
|
52
|
-
if (!url.get())
|
53
|
+
if (!url.get()) {
|
53
54
|
return familyOfFiles[fontName] = Gosu::defaultFontName();
|
54
|
-
|
55
|
+
}
|
56
|
+
|
55
57
|
CFRef<CFArrayRef> array(
|
56
58
|
CTFontManagerCreateFontDescriptorsFromURL(url.obj()));
|
57
59
|
|
58
60
|
if (array.get() == NULL || CFArrayGetCount(array.obj()) < 1 ||
|
59
|
-
|
61
|
+
!CTFontManagerRegisterFontsForURL(url.obj(), kCTFontManagerScopeProcess, NULL)) {
|
60
62
|
return familyOfFiles[fontName] = Gosu::defaultFontName();
|
63
|
+
}
|
61
64
|
|
62
65
|
CTFontDescriptorRef ref =
|
63
66
|
(CTFontDescriptorRef)CFArrayGetValueAtIndex(array.get(), 0);
|
64
67
|
CFRef<CFStringRef> fontNameStr(
|
65
68
|
(CFStringRef)CTFontDescriptorCopyAttribute(ref, kCTFontFamilyNameAttribute));
|
66
69
|
|
67
|
-
const char*
|
70
|
+
const char *utf8FontName = [(__bridge NSString *)fontNameStr.obj() UTF8String];
|
68
71
|
return familyOfFiles[fontName] = Gosu::utf8ToWstring(utf8FontName);
|
69
72
|
#endif
|
70
73
|
}
|
@@ -78,21 +81,25 @@ namespace
|
|
78
81
|
OSXFont* result = usedFonts[make_pair(fontName, make_pair(fontFlags, height))];
|
79
82
|
if (!result)
|
80
83
|
{
|
81
|
-
|
84
|
+
NSString *name = [NSString stringWithUTF8String:Gosu::wstringToUTF8(fontName).c_str()];
|
82
85
|
#ifdef GOSU_IS_IPHONE
|
83
|
-
result = [OSXFont fontWithName:name
|
86
|
+
result = [OSXFont fontWithName:name size:height];
|
84
87
|
#else
|
85
|
-
NSFontDescriptor* desc = [[NSFontDescriptor fontDescriptorWithFontAttributes:nil]
|
86
|
-
|
87
|
-
|
88
|
+
NSFontDescriptor* desc = [[NSFontDescriptor fontDescriptorWithFontAttributes:nil]
|
89
|
+
fontDescriptorWithFamily:name];
|
90
|
+
result = [NSFont fontWithDescriptor:desc size:height];
|
91
|
+
if (result && (fontFlags & Gosu::ffBold)) {
|
88
92
|
result = [[NSFontManager sharedFontManager] convertFont:result toHaveTrait:NSFontBoldTrait];
|
89
|
-
|
93
|
+
}
|
94
|
+
if (result && (fontFlags & Gosu::ffItalic)) {
|
90
95
|
result = [[NSFontManager sharedFontManager] convertFont:result toHaveTrait:NSFontItalicTrait];
|
96
|
+
}
|
91
97
|
#endif
|
92
|
-
if (!result && fontName != Gosu::defaultFontName())
|
98
|
+
if (!result && fontName != Gosu::defaultFontName()) {
|
93
99
|
result = getFont(Gosu::defaultFontName(), 0, height);
|
100
|
+
}
|
94
101
|
assert(result);
|
95
|
-
usedFonts[make_pair(fontName, make_pair(fontFlags, height))] =
|
102
|
+
usedFonts[make_pair(fontName, make_pair(fontFlags, height))] = result;
|
96
103
|
}
|
97
104
|
return result;
|
98
105
|
}
|
@@ -106,17 +113,16 @@ wstring Gosu::defaultFontName()
|
|
106
113
|
#ifndef GOSU_IS_IPHONE
|
107
114
|
namespace
|
108
115
|
{
|
109
|
-
NSDictionary*
|
116
|
+
NSDictionary *attributeDictionary(NSFont* font, unsigned fontFlags)
|
110
117
|
{
|
111
|
-
|
112
|
-
|
113
|
-
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
[dict setValue:underline.obj() forKey:NSUnderlineStyleAttributeName];
|
118
|
+
NSDictionary* dict = @{
|
119
|
+
NSFontAttributeName: font,
|
120
|
+
NSForegroundColorAttributeName: [NSColor whiteColor]
|
121
|
+
};
|
122
|
+
if (fontFlags & Gosu::ffUnderline) {
|
123
|
+
NSMutableDictionary *mutableDict = [dict mutableCopy];
|
124
|
+
mutableDict[NSUnderlineStyleAttributeName] = @(NSUnderlineStyleSingle);
|
125
|
+
dict = [mutableDict copy];
|
120
126
|
}
|
121
127
|
return dict;
|
122
128
|
}
|
@@ -126,19 +132,20 @@ namespace
|
|
126
132
|
unsigned Gosu::textWidth(const wstring& text,
|
127
133
|
const wstring& fontName, unsigned fontHeight, unsigned fontFlags)
|
128
134
|
{
|
129
|
-
if (text.find_first_of(L"\r\n") != wstring::npos)
|
135
|
+
if (text.find_first_of(L"\r\n") != wstring::npos) {
|
130
136
|
throw std::invalid_argument("the argument to textWidth cannot contain line breaks");
|
137
|
+
}
|
131
138
|
|
132
|
-
OSXFont*
|
139
|
+
OSXFont *font = getFont(fontName, fontFlags, fontHeight);
|
133
140
|
|
134
141
|
// This will, of course, compute a too large size; fontHeight is in pixels,
|
135
142
|
// the method expects point.
|
136
|
-
|
143
|
+
NSString *string = [NSString stringWithUTF8String:wstringToUTF8(text).c_str()];
|
137
144
|
#ifndef GOSU_IS_IPHONE
|
138
|
-
|
139
|
-
NSSize size = [string
|
145
|
+
NSDictionary *attributes = attributeDictionary(font, fontFlags);
|
146
|
+
NSSize size = [string sizeWithAttributes:attributes];
|
140
147
|
#else
|
141
|
-
CGSize size = [string
|
148
|
+
CGSize size = [string sizeWithFont:font];
|
142
149
|
#endif
|
143
150
|
|
144
151
|
// Now adjust the scaling...
|
@@ -149,18 +156,19 @@ void Gosu::drawText(Bitmap& bitmap, const wstring& text, int x, int y,
|
|
149
156
|
Color c, const wstring& fontName, unsigned fontHeight,
|
150
157
|
unsigned fontFlags)
|
151
158
|
{
|
152
|
-
if (text.find_first_of(L"\r\n") != wstring::npos)
|
159
|
+
if (text.find_first_of(L"\r\n") != wstring::npos) {
|
153
160
|
throw std::invalid_argument("the argument to drawText cannot contain line breaks");
|
161
|
+
}
|
154
162
|
|
155
|
-
OSXFont*
|
156
|
-
|
163
|
+
OSXFont *font = getFont(fontName, fontFlags, fontHeight);
|
164
|
+
NSString *string = [NSString stringWithUTF8String:wstringToUTF8(text).c_str()];
|
157
165
|
|
158
166
|
// Note that fontHeight is in pixels, the method expects points, so we have to scale this down.
|
159
167
|
#ifndef GOSU_IS_IPHONE
|
160
|
-
|
161
|
-
NSSize size = [string
|
168
|
+
NSDictionary *attributes = attributeDictionary(font, fontFlags);
|
169
|
+
NSSize size = [string sizeWithAttributes:attributes];
|
162
170
|
#else
|
163
|
-
CGSize size = [string
|
171
|
+
CGSize size = [string sizeWithFont:font];
|
164
172
|
#endif
|
165
173
|
|
166
174
|
unsigned width = static_cast<unsigned>(round(size.width / size.height * fontHeight));
|
@@ -189,16 +197,16 @@ void Gosu::drawText(Bitmap& bitmap, const wstring& text, int x, int y,
|
|
189
197
|
CGContextTranslateCTM(context, 0, fontHeight);
|
190
198
|
CGContextScaleCTM(context, 1, -1);
|
191
199
|
UIGraphicsPushContext(context);
|
192
|
-
[string
|
200
|
+
[string drawAtPoint:CGPointZero withFont:font];
|
193
201
|
UIGraphicsPopContext();
|
194
202
|
#else
|
195
203
|
NSPoint NSPointZero = { 0, 0 };
|
196
|
-
attributes
|
204
|
+
attributes = attributeDictionary(font, fontFlags);
|
197
205
|
|
198
206
|
[NSGraphicsContext saveGraphicsState];
|
199
207
|
[NSGraphicsContext setCurrentContext:
|
200
208
|
[NSGraphicsContext graphicsContextWithGraphicsPort:(void *)context flipped:false]];
|
201
|
-
[string
|
209
|
+
[string drawAtPoint:NSPointZero withAttributes:attributes];
|
202
210
|
[NSGraphicsContext restoreGraphicsState];
|
203
211
|
#endif
|
204
212
|
CGContextRelease(context);
|
@@ -211,7 +219,8 @@ void Gosu::drawText(Bitmap& bitmap, const wstring& text, int x, int y,
|
|
211
219
|
for (int relX = 0; relX < effectiveWidth; ++relX)
|
212
220
|
{
|
213
221
|
c.setAlpha(bmp.getPixel(relX, relY).alpha());
|
214
|
-
if (c.alpha())
|
222
|
+
if (c.alpha()) {
|
215
223
|
bitmap.setPixel(x + relX, y + relY, c);
|
224
|
+
}
|
216
225
|
}
|
217
226
|
}
|