gosu 0.10.2.pre1 → 0.10.2
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.
- checksums.yaml +4 -4
- data/Gosu/Version.hpp +1 -1
- data/ext/gosu/extconf.rb +0 -1
- data/ext/gosu/gosu_wrap.cxx +20 -59
- data/rdoc/gosu.rb +12 -0
- data/src/Text/Text.cpp +4 -4
- data/src/Text/TextApple.mm +19 -26
- data/src/Text/TextWin.cpp +3 -7
- metadata +4 -5
- data/src/Text/TextMac.cpp +0 -253
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 6a7232fe12b9c8879a9cfa88e30f9ce0cf61916c
|
4
|
+
data.tar.gz: 02b5c36e500dcd641fc70ee65d6d316dc16f3dba
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: ac51f4a214b0077dd7817ef0e5e741a1618019b3c7e552a0dc80cd3ae1897ea626d3be2e180b4a76b0603dc7fe5f057a57203d50550bde76e61a8f820bd50fe3
|
7
|
+
data.tar.gz: 09520284f76e8efad4dec94ffa584768f0c3c11882c845db9139dc6a7baa02ba4687efd463d43a86f253d44b92a81de61b8e2068b22b9c3f170bc673d63eed6e
|
data/Gosu/Version.hpp
CHANGED
data/ext/gosu/extconf.rb
CHANGED
data/ext/gosu/gosu_wrap.cxx
CHANGED
@@ -8,6 +8,10 @@
|
|
8
8
|
* interface file instead.
|
9
9
|
* ----------------------------------------------------------------------------- */
|
10
10
|
|
11
|
+
// This file was afterwards patched using the following instructions:
|
12
|
+
// http://sourceforge.net/tracker/index.php?func=detail&aid=2034216&group_id=1645&atid=101645
|
13
|
+
// (Many thanks to Kevin Burge for that.)
|
14
|
+
|
11
15
|
#define SWIGRUBY
|
12
16
|
#define SWIG_DIRECTORS
|
13
17
|
|
@@ -870,6 +874,7 @@ SWIG_UnpackDataName(const char *c, void *ptr, size_t sz, const char *name) {
|
|
870
874
|
|
871
875
|
|
872
876
|
#include <ruby.h>
|
877
|
+
#include <map>
|
873
878
|
|
874
879
|
/* Ruby 1.9.1 has a "memoisation optimisation" when compiling with GCC which
|
875
880
|
* breaks using rb_intern as an lvalue, as SWIG does. We work around this
|
@@ -1210,7 +1215,7 @@ extern "C" {
|
|
1210
1215
|
/* Global Ruby hash table to store Trackings from C/C++
|
1211
1216
|
structs to Ruby Objects.
|
1212
1217
|
*/
|
1213
|
-
static VALUE swig_ruby_trackings
|
1218
|
+
static std::map<void*, VALUE> swig_ruby_trackings;
|
1214
1219
|
|
1215
1220
|
/* Global variable that stores a reference to the ruby
|
1216
1221
|
hash table delete function. */
|
@@ -1227,34 +1232,18 @@ SWIGRUNTIME void SWIG_RubyInitializeTrackings(void) {
|
|
1227
1232
|
This is done to allow multiple DSOs to share the same
|
1228
1233
|
tracking table.
|
1229
1234
|
*/
|
1230
|
-
ID trackings_id = rb_intern( "@__trackings__" );
|
1231
1235
|
VALUE verbose = rb_gv_get("VERBOSE");
|
1232
1236
|
rb_gv_set("VERBOSE", Qfalse);
|
1233
|
-
swig_ruby_trackings = rb_ivar_get( _mSWIG, trackings_id );
|
1234
1237
|
rb_gv_set("VERBOSE", verbose);
|
1235
1238
|
|
1236
1239
|
/* No, it hasn't. Create one ourselves */
|
1237
|
-
|
1238
|
-
{
|
1239
|
-
swig_ruby_trackings = rb_hash_new();
|
1240
|
-
rb_ivar_set( _mSWIG, trackings_id, swig_ruby_trackings );
|
1241
|
-
}
|
1240
|
+
swig_ruby_trackings.clear();
|
1242
1241
|
|
1243
1242
|
/* Now store a reference to the hash table delete function
|
1244
1243
|
so that we only have to look it up once.*/
|
1245
1244
|
swig_ruby_hash_delete = rb_intern("delete");
|
1246
1245
|
}
|
1247
1246
|
|
1248
|
-
/* Get a Ruby number to reference a pointer */
|
1249
|
-
SWIGRUNTIME VALUE SWIG_RubyPtrToReference(void* ptr) {
|
1250
|
-
/* We cast the pointer to an unsigned long
|
1251
|
-
and then store a reference to it using
|
1252
|
-
a Ruby number object. */
|
1253
|
-
|
1254
|
-
/* Convert the pointer to a Ruby number */
|
1255
|
-
return SWIG2NUM(ptr);
|
1256
|
-
}
|
1257
|
-
|
1258
1247
|
/* Get a Ruby number to reference an object */
|
1259
1248
|
SWIGRUNTIME VALUE SWIG_RubyObjectToReference(VALUE object) {
|
1260
1249
|
/* We cast the object to an unsigned long
|
@@ -1276,39 +1265,16 @@ SWIGRUNTIME VALUE SWIG_RubyReferenceToObject(VALUE reference) {
|
|
1276
1265
|
|
1277
1266
|
/* Add a Tracking from a C/C++ struct to a Ruby object */
|
1278
1267
|
SWIGRUNTIME void SWIG_RubyAddTracking(void* ptr, VALUE object) {
|
1279
|
-
/* In a Ruby hash table we store the pointer and
|
1280
|
-
the associated Ruby object. The trick here is
|
1281
|
-
that we cannot store the Ruby object directly - if
|
1282
|
-
we do then it cannot be garbage collected. So
|
1283
|
-
instead we typecast it as a unsigned long and
|
1284
|
-
convert it to a Ruby number object.*/
|
1285
|
-
|
1286
|
-
/* Get a reference to the pointer as a Ruby number */
|
1287
|
-
VALUE key = SWIG_RubyPtrToReference(ptr);
|
1288
|
-
|
1289
|
-
/* Get a reference to the Ruby object as a Ruby number */
|
1290
|
-
VALUE value = SWIG_RubyObjectToReference(object);
|
1291
|
-
|
1292
1268
|
/* Store the mapping to the global hash table. */
|
1293
|
-
|
1269
|
+
swig_ruby_trackings[ptr] = object;
|
1294
1270
|
}
|
1295
1271
|
|
1296
1272
|
/* Get the Ruby object that owns the specified C/C++ struct */
|
1297
1273
|
SWIGRUNTIME VALUE SWIG_RubyInstanceFor(void* ptr) {
|
1298
|
-
|
1299
|
-
VALUE key = SWIG_RubyPtrToReference(ptr);
|
1300
|
-
|
1301
|
-
/* Now lookup the value stored in the global hash table */
|
1302
|
-
VALUE value = rb_hash_aref(swig_ruby_trackings, key);
|
1303
|
-
|
1304
|
-
if (value == Qnil) {
|
1305
|
-
/* No object exists - return nil. */
|
1274
|
+
if (swig_ruby_trackings.count(ptr) == 0)
|
1306
1275
|
return Qnil;
|
1307
|
-
|
1308
|
-
|
1309
|
-
/* Convert this value to Ruby object */
|
1310
|
-
return SWIG_RubyReferenceToObject(value);
|
1311
|
-
}
|
1276
|
+
else
|
1277
|
+
return swig_ruby_trackings[ptr];
|
1312
1278
|
}
|
1313
1279
|
|
1314
1280
|
/* Remove a Tracking from a C/C++ struct to a Ruby object. It
|
@@ -1316,12 +1282,7 @@ SWIGRUNTIME VALUE SWIG_RubyInstanceFor(void* ptr) {
|
|
1316
1282
|
since the same memory address may be reused later to create
|
1317
1283
|
a new object. */
|
1318
1284
|
SWIGRUNTIME void SWIG_RubyRemoveTracking(void* ptr) {
|
1319
|
-
|
1320
|
-
VALUE key = SWIG_RubyPtrToReference(ptr);
|
1321
|
-
|
1322
|
-
/* Delete the object from the hash table by calling Ruby's
|
1323
|
-
do this we need to call the Hash.delete method.*/
|
1324
|
-
rb_funcall(swig_ruby_trackings, swig_ruby_hash_delete, 1, key);
|
1285
|
+
swig_ruby_trackings.erase(ptr);
|
1325
1286
|
}
|
1326
1287
|
|
1327
1288
|
/* This is a helper method that unlinks a Ruby object from its
|
@@ -3119,14 +3080,14 @@ bool SwigDirector_Window::tick() {
|
|
3119
3080
|
void SwigDirector_Window::update() {
|
3120
3081
|
VALUE result;
|
3121
3082
|
|
3122
|
-
result = rb_funcall(swig_get_self(), rb_intern("
|
3083
|
+
result = rb_funcall(swig_get_self(), rb_intern("protected_update"), 0, NULL);
|
3123
3084
|
}
|
3124
3085
|
|
3125
3086
|
|
3126
3087
|
void SwigDirector_Window::draw() {
|
3127
3088
|
VALUE result;
|
3128
3089
|
|
3129
|
-
result = rb_funcall(swig_get_self(), rb_intern("
|
3090
|
+
result = rb_funcall(swig_get_self(), rb_intern("protected_draw_2"), 0, NULL);
|
3130
3091
|
}
|
3131
3092
|
|
3132
3093
|
|
@@ -3134,7 +3095,7 @@ bool SwigDirector_Window::needsRedraw() const {
|
|
3134
3095
|
bool c_result ;
|
3135
3096
|
VALUE result;
|
3136
3097
|
|
3137
|
-
result = rb_funcall(swig_get_self(), rb_intern("
|
3098
|
+
result = rb_funcall(swig_get_self(), rb_intern("protected_needs_redraw?"), 0, NULL);
|
3138
3099
|
bool swig_val;
|
3139
3100
|
int swig_res = SWIG_AsVal_bool(result, &swig_val);
|
3140
3101
|
if (!SWIG_IsOK(swig_res)) {
|
@@ -3149,7 +3110,7 @@ bool SwigDirector_Window::needsCursor() const {
|
|
3149
3110
|
bool c_result ;
|
3150
3111
|
VALUE result;
|
3151
3112
|
|
3152
|
-
result = rb_funcall(swig_get_self(), rb_intern("
|
3113
|
+
result = rb_funcall(swig_get_self(), rb_intern("protected_needs_cursor?"), 0, NULL);
|
3153
3114
|
bool swig_val;
|
3154
3115
|
int swig_res = SWIG_AsVal_bool(result, &swig_val);
|
3155
3116
|
if (!SWIG_IsOK(swig_res)) {
|
@@ -3163,7 +3124,7 @@ bool SwigDirector_Window::needsCursor() const {
|
|
3163
3124
|
void SwigDirector_Window::loseFocus() {
|
3164
3125
|
VALUE result;
|
3165
3126
|
|
3166
|
-
result = rb_funcall(swig_get_self(), rb_intern("
|
3127
|
+
result = rb_funcall(swig_get_self(), rb_intern("protected_lose_focus"), 0, NULL);
|
3167
3128
|
}
|
3168
3129
|
|
3169
3130
|
|
@@ -3184,7 +3145,7 @@ void SwigDirector_Window::buttonDown(Gosu::Button arg0) {
|
|
3184
3145
|
else
|
3185
3146
|
obj0 = LONG2NUM((&arg0)->id());
|
3186
3147
|
}
|
3187
|
-
result = rb_funcall(swig_get_self(), rb_intern("
|
3148
|
+
result = rb_funcall(swig_get_self(), rb_intern("protected_button_down"), 1,obj0);
|
3188
3149
|
}
|
3189
3150
|
|
3190
3151
|
|
@@ -3198,7 +3159,7 @@ void SwigDirector_Window::buttonUp(Gosu::Button arg0) {
|
|
3198
3159
|
else
|
3199
3160
|
obj0 = LONG2NUM((&arg0)->id());
|
3200
3161
|
}
|
3201
|
-
result = rb_funcall(swig_get_self(), rb_intern("
|
3162
|
+
result = rb_funcall(swig_get_self(), rb_intern("protected_button_up"), 1,obj0);
|
3202
3163
|
}
|
3203
3164
|
|
3204
3165
|
|
@@ -11209,7 +11170,7 @@ SWIGEXPORT void Init_gosu(void) {
|
|
11209
11170
|
rb_define_const(mGosu, "MAJOR_VERSION", SWIG_From_int(static_cast< int >(0)));
|
11210
11171
|
rb_define_const(mGosu, "MINOR_VERSION", SWIG_From_int(static_cast< int >(10)));
|
11211
11172
|
rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(2)));
|
11212
|
-
rb_define_const(mGosu, "VERSION", SWIG_FromCharPtr("0.10.2
|
11173
|
+
rb_define_const(mGosu, "VERSION", SWIG_FromCharPtr("0.10.2"));
|
11213
11174
|
rb_define_const(mGosu, "GOSU_COPYRIGHT_NOTICE", SWIG_FromCharPtr("This software uses the following third-party libraries:\n\nGosu, http://www.libgosu.org, MIT License, http://opensource.org/licenses/MIT\nSDL 2, http://www.libsdl.org, MIT License, http://opensource.org/licenses/MIT\nlibsndfile, http://www.mega-nerd.com/libsndfile, GNU LGPL 3, http://www.gnu.org/copyleft/lesser.html\nOpenAL Soft, http://kcat.strangesoft.net/openal.html, GNU LGPL 2, http://www.gnu.org/licenses/old-licenses/lgpl-2.0.html\n"));
|
11214
11175
|
rb_define_module_function(mGosu, "milliseconds", VALUEFUNC(_wrap_milliseconds), -1);
|
11215
11176
|
rb_define_module_function(mGosu, "random", VALUEFUNC(_wrap_random), -1);
|
data/rdoc/gosu.rb
CHANGED
@@ -742,6 +742,18 @@ module Gosu
|
|
742
742
|
#
|
743
743
|
# @return [void]
|
744
744
|
def show; end
|
745
|
+
|
746
|
+
##
|
747
|
+
# EXPERIMENTAL - MAY DISAPPEAR WITHOUT WARNING:
|
748
|
+
# Performs a single step in the main loop. This can be useful for integrating Gosu with other
|
749
|
+
# libraries that have their own main loop, e.g. Ruby/Tk.
|
750
|
+
#
|
751
|
+
# See: https://www.libgosu.org/cgi-bin/mwf/topic_show.pl?tid=1218
|
752
|
+
#
|
753
|
+
# If you find a good way to use this, please post it on the forum. Thank you!
|
754
|
+
#
|
755
|
+
# @return [true, false] whether the Window should still be shown after this tick
|
756
|
+
def tick; end
|
745
757
|
|
746
758
|
##
|
747
759
|
# Tells the window to end the current run loop as soon as possible. Calling this method will not prevent execution of lines after it.
|
data/src/Text/Text.cpp
CHANGED
@@ -67,7 +67,7 @@ namespace Gosu
|
|
67
67
|
allocatedLines += 10;
|
68
68
|
bmp.resize(bmp.width(),
|
69
69
|
fontHeight * allocatedLines + lineSpacing * (allocatedLines - 1),
|
70
|
-
|
70
|
+
0x00ffffff);
|
71
71
|
}
|
72
72
|
}
|
73
73
|
|
@@ -183,7 +183,7 @@ namespace Gosu
|
|
183
183
|
{
|
184
184
|
Bitmap result = bmp;
|
185
185
|
result.resize(result.width(),
|
186
|
-
fontHeight * usedLines + lineSpacing * (usedLines - 1));
|
186
|
+
fontHeight * usedLines + lineSpacing * (usedLines - 1), 0x00ffffff);
|
187
187
|
return result;
|
188
188
|
}
|
189
189
|
|
@@ -347,7 +347,7 @@ Gosu::Bitmap Gosu::createText(const wstring& text,
|
|
347
347
|
{
|
348
348
|
Gosu::Bitmap entity = entityBitmap(part.entityAt(0));
|
349
349
|
multiplyBitmapAlpha(entity, part.colorAt(0).alpha());
|
350
|
-
bmp.resize(max(bmp.width(), x + entity.width()), bmp.height());
|
350
|
+
bmp.resize(max(bmp.width(), x + entity.width()), bmp.height(), 0x00ffffff);
|
351
351
|
bmp.insert(entity, x, i * fontHeight);
|
352
352
|
x += entity.width();
|
353
353
|
continue;
|
@@ -357,7 +357,7 @@ Gosu::Bitmap Gosu::createText(const wstring& text,
|
|
357
357
|
wstring unformattedText = part.unformat();
|
358
358
|
unsigned partWidth =
|
359
359
|
textWidth(unformattedText, fontName, fontHeight, part.flagsAt(0));
|
360
|
-
bmp.resize(max(bmp.width(), x + partWidth), bmp.height());
|
360
|
+
bmp.resize(max(bmp.width(), x + partWidth), bmp.height(), 0x00ffffff);
|
361
361
|
drawText(bmp, unformattedText, x, i * fontHeight, part.colorAt(0),
|
362
362
|
fontName, fontHeight, part.flagsAt(0));
|
363
363
|
x += partWidth;
|
data/src/Text/TextApple.mm
CHANGED
@@ -1,7 +1,5 @@
|
|
1
1
|
#import <Gosu/Platform.hpp>
|
2
2
|
|
3
|
-
#if defined(GOSU_IS_IPHONE) || defined(__LP64__)
|
4
|
-
|
5
3
|
#include <Gosu/Text.hpp>
|
6
4
|
#include <Gosu/Bitmap.hpp>
|
7
5
|
#include <Gosu/Utility.hpp>
|
@@ -29,6 +27,8 @@ namespace
|
|
29
27
|
// like any system font. Otherwise, just returns the family name.
|
30
28
|
std::wstring normalizeFont(const std::wstring& fontName)
|
31
29
|
{
|
30
|
+
// On iOS, we have no support for loading font files yet. However if you register your fonts
|
31
|
+
// via your app's Info.plist, you should be able to reference them by their name.
|
32
32
|
#ifdef GOSU_IS_IPHONE
|
33
33
|
return fontName;
|
34
34
|
#else
|
@@ -48,8 +48,7 @@ namespace
|
|
48
48
|
fontName.length() * sizeof(wchar_t),
|
49
49
|
kCFStringEncodingUTF32LE, NO));
|
50
50
|
CFRef<CFURLRef> url(
|
51
|
-
CFURLCreateWithFileSystemPath(NULL, urlString.obj(),
|
52
|
-
kCFURLPOSIXPathStyle, YES));
|
51
|
+
CFURLCreateWithFileSystemPath(NULL, urlString.obj(), kCFURLPOSIXPathStyle, YES));
|
53
52
|
if (!url.get())
|
54
53
|
return familyOfFiles[fontName] = Gosu::defaultFontName();
|
55
54
|
|
@@ -57,17 +56,15 @@ namespace
|
|
57
56
|
CTFontManagerCreateFontDescriptorsFromURL(url.obj()));
|
58
57
|
|
59
58
|
if (array.get() == NULL || CFArrayGetCount(array.obj()) < 1 ||
|
60
|
-
!CTFontManagerRegisterFontsForURL(url.obj(),
|
61
|
-
kCTFontManagerScopeProcess, NULL))
|
59
|
+
!CTFontManagerRegisterFontsForURL(url.obj(), kCTFontManagerScopeProcess, NULL))
|
62
60
|
return familyOfFiles[fontName] = Gosu::defaultFontName();
|
63
61
|
|
64
62
|
CTFontDescriptorRef ref =
|
65
63
|
(CTFontDescriptorRef)CFArrayGetValueAtIndex(array.get(), 0);
|
66
64
|
CFRef<CFStringRef> fontNameStr(
|
67
65
|
(CFStringRef)CTFontDescriptorCopyAttribute(ref, kCTFontFamilyNameAttribute));
|
68
|
-
|
69
|
-
const char* utf8FontName =
|
70
|
-
[(NSString*)fontNameStr.obj() cStringUsingEncoding: NSUTF8StringEncoding];
|
66
|
+
|
67
|
+
const char* utf8FontName = [(NSString*)fontNameStr.obj() UTF8String];
|
71
68
|
return familyOfFiles[fontName] = Gosu::utf8ToWstring(utf8FontName);
|
72
69
|
#endif
|
73
70
|
}
|
@@ -81,9 +78,9 @@ namespace
|
|
81
78
|
OSXFont* result = usedFonts[make_pair(fontName, make_pair(fontFlags, height))];
|
82
79
|
if (!result)
|
83
80
|
{
|
84
|
-
ObjCRef<NSString> name([[NSString alloc] initWithUTF8String:
|
81
|
+
ObjCRef<NSString> name([[NSString alloc] initWithUTF8String:Gosu::wstringToUTF8(fontName).c_str()]);
|
85
82
|
#ifdef GOSU_IS_IPHONE
|
86
|
-
result = [OSXFont fontWithName:
|
83
|
+
result = [OSXFont fontWithName:name.obj() size:height];
|
87
84
|
#else
|
88
85
|
NSFontDescriptor* desc = [[NSFontDescriptor fontDescriptorWithFontAttributes:nil] fontDescriptorWithFamily:name.obj()];
|
89
86
|
result = [[NSFont fontWithDescriptor:desc size:height] retain];
|
@@ -103,8 +100,6 @@ namespace
|
|
103
100
|
|
104
101
|
wstring Gosu::defaultFontName()
|
105
102
|
{
|
106
|
-
// OF COURSE Helvetica is better - but the dots above my capital umlauts get
|
107
|
-
// eaten when I use it with Gosu. Until this is fixed, keep Arial. (TODO)
|
108
103
|
return L"Arial";
|
109
104
|
}
|
110
105
|
|
@@ -121,7 +116,7 @@ namespace
|
|
121
116
|
if (fontFlags & Gosu::ffUnderline)
|
122
117
|
{
|
123
118
|
Gosu::ObjCRef<NSNumber> underline([[NSNumber alloc] initWithInt:NSUnderlineStyleSingle]);
|
124
|
-
[dict setValue:
|
119
|
+
[dict setValue:underline.obj() forKey:NSUnderlineStyleAttributeName];
|
125
120
|
}
|
126
121
|
return dict;
|
127
122
|
}
|
@@ -138,12 +133,12 @@ unsigned Gosu::textWidth(const wstring& text,
|
|
138
133
|
|
139
134
|
// This will, of course, compute a too large size; fontHeight is in pixels,
|
140
135
|
// the method expects point.
|
141
|
-
ObjCRef<NSString> string([[NSString alloc] initWithUTF8String:
|
136
|
+
ObjCRef<NSString> string([[NSString alloc] initWithUTF8String:wstringToUTF8(text).c_str()]);
|
142
137
|
#ifndef GOSU_IS_IPHONE
|
143
138
|
ObjCRef<NSDictionary> attributes(attributeDictionary(font, fontFlags));
|
144
|
-
NSSize size = [string.obj() sizeWithAttributes:
|
139
|
+
NSSize size = [string.obj() sizeWithAttributes:attributes.get()];
|
145
140
|
#else
|
146
|
-
CGSize size = [string.obj() sizeWithFont:
|
141
|
+
CGSize size = [string.obj() sizeWithFont:font];
|
147
142
|
#endif
|
148
143
|
|
149
144
|
// Now adjust the scaling...
|
@@ -158,20 +153,20 @@ void Gosu::drawText(Bitmap& bitmap, const wstring& text, int x, int y,
|
|
158
153
|
throw std::invalid_argument("the argument to drawText cannot contain line breaks");
|
159
154
|
|
160
155
|
OSXFont* font = getFont(fontName, fontFlags, fontHeight);
|
161
|
-
ObjCRef<NSString> string([[NSString alloc] initWithUTF8String:
|
156
|
+
ObjCRef<NSString> string([[NSString alloc] initWithUTF8String:wstringToUTF8(text).c_str()]);
|
162
157
|
|
163
|
-
//
|
158
|
+
// Note that fontHeight is in pixels, the method expects points, so we have to scale this down.
|
164
159
|
#ifndef GOSU_IS_IPHONE
|
165
160
|
ObjCRef<NSDictionary> attributes(attributeDictionary(font, fontFlags));
|
166
|
-
NSSize size = [string.obj() sizeWithAttributes:
|
161
|
+
NSSize size = [string.obj() sizeWithAttributes:attributes.get()];
|
167
162
|
#else
|
168
|
-
CGSize size = [string.obj() sizeWithFont:
|
163
|
+
CGSize size = [string.obj() sizeWithFont:font];
|
169
164
|
#endif
|
170
165
|
|
171
166
|
unsigned width = static_cast<unsigned>(round(size.width / size.height * fontHeight));
|
172
167
|
|
173
168
|
// Get the width and height of the image
|
174
|
-
Bitmap bmp(width, fontHeight);
|
169
|
+
Bitmap bmp(width, fontHeight, 0x00ffffff);
|
175
170
|
|
176
171
|
// Use a temporary context to draw the CGImage to the buffer.
|
177
172
|
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
|
@@ -194,7 +189,7 @@ void Gosu::drawText(Bitmap& bitmap, const wstring& text, int x, int y,
|
|
194
189
|
CGContextTranslateCTM(context, 0, fontHeight);
|
195
190
|
CGContextScaleCTM(context, 1, -1);
|
196
191
|
UIGraphicsPushContext(context);
|
197
|
-
|
192
|
+
[string.obj() drawAtPoint:CGPointZero withFont:font];
|
198
193
|
UIGraphicsPopContext();
|
199
194
|
#else
|
200
195
|
NSPoint NSPointZero = { 0, 0 };
|
@@ -203,7 +198,7 @@ void Gosu::drawText(Bitmap& bitmap, const wstring& text, int x, int y,
|
|
203
198
|
[NSGraphicsContext saveGraphicsState];
|
204
199
|
[NSGraphicsContext setCurrentContext:
|
205
200
|
[NSGraphicsContext graphicsContextWithGraphicsPort:(void *)context flipped:false]];
|
206
|
-
[string.obj() drawAtPoint:
|
201
|
+
[string.obj() drawAtPoint:NSPointZero withAttributes:attributes.get()];
|
207
202
|
[NSGraphicsContext restoreGraphicsState];
|
208
203
|
#endif
|
209
204
|
CGContextRelease(context);
|
@@ -220,5 +215,3 @@ void Gosu::drawText(Bitmap& bitmap, const wstring& text, int x, int y,
|
|
220
215
|
bitmap.setPixel(x + relX, y + relY, c);
|
221
216
|
}
|
222
217
|
}
|
223
|
-
|
224
|
-
#endif
|
data/src/Text/TextWin.cpp
CHANGED
@@ -79,11 +79,6 @@ namespace Gosu
|
|
79
79
|
return bitmap;
|
80
80
|
}
|
81
81
|
|
82
|
-
/*char* data() const
|
83
|
-
{
|
84
|
-
return pixels;
|
85
|
-
}*/
|
86
|
-
|
87
82
|
void selectFont(std::wstring fontName, unsigned fontHeight,
|
88
83
|
unsigned fontFlags) const
|
89
84
|
{
|
@@ -123,8 +118,9 @@ namespace Gosu
|
|
123
118
|
CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
|
124
119
|
DEFAULT_PITCH | FF_DONTCARE };
|
125
120
|
|
126
|
-
//
|
127
|
-
|
121
|
+
// Don't rely on wcsncpy being in std::...
|
122
|
+
using namepace std;
|
123
|
+
wcsncpy(logfont.lfFaceName, fontName.c_str(), LF_FACESIZE);
|
128
124
|
logfont.lfFaceName[LF_FACESIZE - 1] = 0;
|
129
125
|
|
130
126
|
font = loadedFonts[key] = Win::check(::CreateFontIndirect(&logfont),
|
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.10.2
|
4
|
+
version: 0.10.2
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Julian Raschke
|
8
8
|
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2015-
|
11
|
+
date: 2015-09-13 00:00:00.000000000 Z
|
12
12
|
dependencies: []
|
13
13
|
description: |2
|
14
14
|
2D game development library.
|
@@ -85,7 +85,6 @@ files:
|
|
85
85
|
- src/Math.cpp
|
86
86
|
- src/Text/Font.cpp
|
87
87
|
- src/Text/Text.cpp
|
88
|
-
- src/Text/TextMac.cpp
|
89
88
|
- src/Text/TextTTFWin.cpp
|
90
89
|
- src/Text/TextUnix.cpp
|
91
90
|
- src/Text/TextWin.cpp
|
@@ -155,9 +154,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
|
|
155
154
|
version: 1.8.2
|
156
155
|
required_rubygems_version: !ruby/object:Gem::Requirement
|
157
156
|
requirements:
|
158
|
-
- - '
|
157
|
+
- - '>='
|
159
158
|
- !ruby/object:Gem::Version
|
160
|
-
version:
|
159
|
+
version: '0'
|
161
160
|
requirements: []
|
162
161
|
rubyforge_project:
|
163
162
|
rubygems_version: 2.0.14
|
data/src/Text/TextMac.cpp
DELETED
@@ -1,253 +0,0 @@
|
|
1
|
-
#include <Gosu/Platform.hpp>
|
2
|
-
|
3
|
-
#if !defined(GOSU_IS_IPHONE) && !defined(__LP64__)
|
4
|
-
|
5
|
-
#include <Gosu/Bitmap.hpp>
|
6
|
-
#include <Gosu/Text.hpp>
|
7
|
-
#include <Gosu/TR1.hpp>
|
8
|
-
#include <Gosu/Math.hpp>
|
9
|
-
#include <Gosu/Utility.hpp>
|
10
|
-
#include <Gosu/IO.hpp>
|
11
|
-
#include "../AppleUtility.hpp"
|
12
|
-
#include <cmath>
|
13
|
-
#include <stdexcept>
|
14
|
-
#include <map>
|
15
|
-
#include <vector>
|
16
|
-
#include <ApplicationServices/ApplicationServices.h>
|
17
|
-
|
18
|
-
std::wstring Gosu::defaultFontName()
|
19
|
-
{
|
20
|
-
// OF COURSE Helvetica is better - but the dots above my capital umlauts get
|
21
|
-
// eaten when I use it with Gosu. Until this is fixed, keep Arial. (TODO)
|
22
|
-
return L"Arial";
|
23
|
-
}
|
24
|
-
|
25
|
-
namespace Gosu
|
26
|
-
{
|
27
|
-
std::vector<unsigned short> wstringToUniChars(const std::wstring& ws);
|
28
|
-
}
|
29
|
-
|
30
|
-
namespace
|
31
|
-
{
|
32
|
-
class MacBitmap
|
33
|
-
{
|
34
|
-
std::tr1::uint32_t* buf;
|
35
|
-
unsigned width, height;
|
36
|
-
CGContextRef ctx;
|
37
|
-
|
38
|
-
MacBitmap(const MacBitmap&);
|
39
|
-
MacBitmap& operator=(const MacBitmap&);
|
40
|
-
|
41
|
-
public:
|
42
|
-
MacBitmap(std::tr1::uint32_t* buf, unsigned width, unsigned height)
|
43
|
-
: buf(buf), width(width), height(height)
|
44
|
-
{
|
45
|
-
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName(kCGColorSpaceGenericRGB);
|
46
|
-
ctx = CGBitmapContextCreate (buf, width, height, 8, width * 4, colorSpace,
|
47
|
-
kCGImageAlphaPremultipliedLast);
|
48
|
-
|
49
|
-
CGColorSpaceRelease( colorSpace );
|
50
|
-
}
|
51
|
-
|
52
|
-
~MacBitmap()
|
53
|
-
{
|
54
|
-
CGContextRelease(ctx);
|
55
|
-
}
|
56
|
-
|
57
|
-
CGContextRef context() const
|
58
|
-
{
|
59
|
-
return ctx;
|
60
|
-
}
|
61
|
-
};
|
62
|
-
|
63
|
-
struct CachedFontInfo
|
64
|
-
{
|
65
|
-
ATSUFontID fontId;
|
66
|
-
double heightAt1Pt;
|
67
|
-
double descentAt1Pt;
|
68
|
-
};
|
69
|
-
CachedFontInfo& getFont(const std::wstring& fontName)
|
70
|
-
{
|
71
|
-
static std::map<std::wstring, CachedFontInfo> fonts;
|
72
|
-
|
73
|
-
if (fonts.count(fontName))
|
74
|
-
return fonts[fontName];
|
75
|
-
|
76
|
-
// Get reference to font, loaded from the system or a file.
|
77
|
-
ATSFontRef atsRef;
|
78
|
-
if (fontName.find(L"/") == std::wstring::npos)
|
79
|
-
{
|
80
|
-
// System font
|
81
|
-
CFStringRef cfName = CFStringCreateWithCString(NULL, Gosu::narrow(fontName).c_str(), kCFStringEncodingASCII);
|
82
|
-
atsRef = ATSFontFindFromName(cfName, kATSOptionFlagsDefault);
|
83
|
-
if (!atsRef)
|
84
|
-
throw std::runtime_error("Cannot find font " + Gosu::narrow(fontName));
|
85
|
-
CFRelease(cfName);
|
86
|
-
}
|
87
|
-
else
|
88
|
-
{
|
89
|
-
// Filename to font
|
90
|
-
Gosu::Buffer buf;
|
91
|
-
Gosu::loadFile(buf, fontName);
|
92
|
-
|
93
|
-
ATSFontContainerRef container;
|
94
|
-
CHECK_OS( ATSFontActivateFromMemory(buf.data(), buf.size(),
|
95
|
-
kATSFontContextLocal, kATSFontFormatUnspecified,
|
96
|
-
NULL, kATSOptionFlagsDefault, &container) );
|
97
|
-
|
98
|
-
ATSFontRef fontRefs[1024];
|
99
|
-
ItemCount fontCount;
|
100
|
-
CHECK_OS( ATSFontFindFromContainer(container, kATSOptionFlagsDefault,
|
101
|
-
1024, fontRefs, &fontCount) );
|
102
|
-
if (fontCount == 0)
|
103
|
-
throw std::runtime_error("No font found in " + Gosu::narrow(fontName));
|
104
|
-
|
105
|
-
atsRef = fontRefs[0];
|
106
|
-
}
|
107
|
-
|
108
|
-
// Calculate metrics (for space allocations) and create CachedFontInfo entry.
|
109
|
-
CachedFontInfo newFont;
|
110
|
-
newFont.fontId = (ATSUFontID)atsRef;
|
111
|
-
|
112
|
-
ATSFontMetrics metrics;
|
113
|
-
CHECK_OS(ATSFontGetHorizontalMetrics(newFont.fontId, kATSOptionFlagsDefault, &metrics));
|
114
|
-
newFont.heightAt1Pt = metrics.ascent - metrics.descent;
|
115
|
-
newFont.descentAt1Pt = -metrics.descent;
|
116
|
-
fonts[fontName] = newFont;
|
117
|
-
return fonts[fontName];
|
118
|
-
}
|
119
|
-
|
120
|
-
class ATSULayoutAndStyle
|
121
|
-
{
|
122
|
-
ATSUStyle style;
|
123
|
-
ATSUTextLayout layout;
|
124
|
-
std::vector<UniChar> utf16; // More like UCS-2-INTERNAL.
|
125
|
-
|
126
|
-
template<typename T>
|
127
|
-
void setAttribute(ATSUAttributeTag tag, T value)
|
128
|
-
{
|
129
|
-
ByteCount size = sizeof value;
|
130
|
-
ATSUAttributeValuePtr ptr = &value;
|
131
|
-
CHECK_OS( ATSUSetAttributes(style, 1, &tag, &size, &ptr) );
|
132
|
-
}
|
133
|
-
|
134
|
-
template<typename T>
|
135
|
-
void setLayoutControl(ATSUAttributeTag tag, T value)
|
136
|
-
{
|
137
|
-
ByteCount size = sizeof value;
|
138
|
-
ATSUAttributeValuePtr ptr = &value;
|
139
|
-
CHECK_OS( ATSUSetLayoutControls(layout, 1, &tag, &size, &ptr) );
|
140
|
-
}
|
141
|
-
|
142
|
-
public:
|
143
|
-
ATSULayoutAndStyle(const std::wstring& text, const std::wstring& fontName, unsigned fontHeightPx, unsigned fontFlags)
|
144
|
-
{
|
145
|
-
utf16 = Gosu::wstringToUniChars(text);
|
146
|
-
|
147
|
-
CHECK_OS( ATSUCreateStyle(&style) );
|
148
|
-
|
149
|
-
CachedFontInfo& font = getFont(fontName);
|
150
|
-
|
151
|
-
setAttribute<ATSUFontID>(kATSUFontTag, font.fontId);
|
152
|
-
|
153
|
-
setAttribute<Fixed>(kATSUSizeTag, X2Fix(fontHeightPx / font.heightAt1Pt));
|
154
|
-
if (fontFlags & Gosu::ffBold)
|
155
|
-
setAttribute<Boolean>(kATSUQDBoldfaceTag, TRUE);
|
156
|
-
if (fontFlags & Gosu::ffItalic)
|
157
|
-
setAttribute<Boolean>(kATSUQDItalicTag, TRUE);
|
158
|
-
if (fontFlags & Gosu::ffUnderline)
|
159
|
-
setAttribute<Boolean>(kATSUQDUnderlineTag, TRUE);
|
160
|
-
|
161
|
-
UniCharCount runLength = utf16.size();
|
162
|
-
CHECK_OS( ATSUCreateTextLayoutWithTextPtr(&utf16[0], kATSUFromTextBeginning,
|
163
|
-
kATSUToTextEnd, utf16.size(), 1, &runLength, &style, &layout) );
|
164
|
-
}
|
165
|
-
|
166
|
-
~ATSULayoutAndStyle()
|
167
|
-
{
|
168
|
-
CHECK_OS( ATSUDisposeStyle(style) );
|
169
|
-
CHECK_OS( ATSUDisposeTextLayout(layout) );
|
170
|
-
}
|
171
|
-
|
172
|
-
Rect textExtents() const
|
173
|
-
{
|
174
|
-
Rect rect;
|
175
|
-
CHECK_OS( ATSUSetTransientFontMatching(layout, TRUE) );
|
176
|
-
CHECK_OS( ATSUMeasureTextImage(layout, kATSUFromTextBeginning,
|
177
|
-
kATSUToTextEnd, X2Fix(0), X2Fix(0), &rect) );
|
178
|
-
return rect;
|
179
|
-
}
|
180
|
-
|
181
|
-
void drawToContext(Fixed x, Fixed y, CGContextRef context)
|
182
|
-
{
|
183
|
-
// Always draw in black - recoloring to white happens in drawText itself.
|
184
|
-
// Reason: Text drawn using fallback fonts seems to always be black anyway :(
|
185
|
-
|
186
|
-
RGBColor color = { 0, 0, 0 };
|
187
|
-
setAttribute<RGBColor>(kATSUColorTag, color);
|
188
|
-
setLayoutControl<CGContextRef>(kATSUCGContextTag, context);
|
189
|
-
CHECK_OS( ATSUSetTransientFontMatching(layout, TRUE) );
|
190
|
-
CHECK_OS( ATSUDrawText(layout, kATSUFromTextBeginning, kATSUToTextEnd, x, y) );
|
191
|
-
}
|
192
|
-
};
|
193
|
-
}
|
194
|
-
|
195
|
-
unsigned Gosu::textWidth(const std::wstring& text,
|
196
|
-
const std::wstring& fontName, unsigned fontHeight, unsigned fontFlags)
|
197
|
-
{
|
198
|
-
if (text.find_first_of(L"\r\n") != std::wstring::npos)
|
199
|
-
throw std::invalid_argument("the argument to textWidth cannot contain line breaks");
|
200
|
-
|
201
|
-
// TODO: Why 1?
|
202
|
-
if (text.empty())
|
203
|
-
return 1;
|
204
|
-
|
205
|
-
// TODO: special case :(
|
206
|
-
// TODO: Why? I guess it was empty otherwise?
|
207
|
-
if (text == L" ")
|
208
|
-
return fontHeight / 3;
|
209
|
-
|
210
|
-
ATSULayoutAndStyle atlas(text, fontName, fontHeight, fontFlags);
|
211
|
-
Rect rect = atlas.textExtents();
|
212
|
-
return rect.right + 1 - rect.left + 1; // add one pixel on OS X
|
213
|
-
}
|
214
|
-
|
215
|
-
void Gosu::drawText(Bitmap& bitmap, const std::wstring& text, int x, int y,
|
216
|
-
Color c, const std::wstring& fontName, unsigned fontHeight,
|
217
|
-
unsigned fontFlags)
|
218
|
-
{
|
219
|
-
if (text.find_first_of(L"\r\n") != std::wstring::npos)
|
220
|
-
throw std::invalid_argument("the argument to drawText cannot contain line breaks");
|
221
|
-
|
222
|
-
if (text.empty())
|
223
|
-
return;
|
224
|
-
|
225
|
-
CachedFontInfo& font = getFont(fontName);
|
226
|
-
|
227
|
-
ATSULayoutAndStyle atlas(text, fontName, fontHeight, fontFlags);
|
228
|
-
Rect rect = atlas.textExtents();
|
229
|
-
int width = rect.right + 1 - rect.left + 1; // add one pixel on OS X
|
230
|
-
std::vector<std::tr1::uint32_t> buf(width * fontHeight);
|
231
|
-
{
|
232
|
-
MacBitmap helper(&buf[0], width, fontHeight);
|
233
|
-
atlas.drawToContext(X2Fix(-rect.left), X2Fix(fontHeight / font.heightAt1Pt * font.descentAt1Pt),
|
234
|
-
helper.context());
|
235
|
-
}
|
236
|
-
|
237
|
-
int effectiveWidth = Gosu::clamp<int>(width, 0, bitmap.width() - x);
|
238
|
-
int effectiveHeight = Gosu::clamp<int>(fontHeight, 0, bitmap.height() - y);
|
239
|
-
|
240
|
-
for (int relY = 0; relY < effectiveHeight; ++relY)
|
241
|
-
for (int relX = 0; relX < effectiveWidth; ++relX)
|
242
|
-
{
|
243
|
-
#ifdef __BIG_ENDIAN__
|
244
|
-
Color::Channel alpha = buf[relY * width + relX];
|
245
|
-
#else
|
246
|
-
Color::Channel alpha = Color(buf[relY * width + relX]).alpha();
|
247
|
-
#endif
|
248
|
-
if (alpha != 0)
|
249
|
-
bitmap.setPixel(x + relX, y + relY, multiply(c, Color(alpha, 0xff, 0xff, 0xff)));
|
250
|
-
}
|
251
|
-
}
|
252
|
-
|
253
|
-
#endif
|