gosu 0.10.2.pre1 → 0.10.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|