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
         |