ruby2d 0.12.0 → 1.0.0
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/LICENSE.md +7 -0
- data/README.md +141 -0
- data/USAGE.md +2435 -0
- data/assets/Rakefile +637 -0
- data/assets/build_support/CMakeLists.txt +94 -0
- data/assets/build_support/mruby/build_config.rb +34 -0
- data/assets/build_support/mruby/build_config_wasm.rb +30 -0
- data/assets/build_support/sdl_test.c +174 -0
- data/assets/deps.yaml +16 -0
- data/assets/platform/include/SDL3/SDL.h +91 -0
- data/assets/platform/include/SDL3/SDL_assert.h +705 -0
- data/assets/platform/include/SDL3/SDL_asyncio.h +550 -0
- data/assets/platform/include/SDL3/SDL_atomic.h +692 -0
- data/assets/platform/include/SDL3/SDL_audio.h +2370 -0
- data/assets/platform/include/SDL3/SDL_begin_code.h +553 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_bits.h +47 -27
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_blendmode.h +59 -55
- data/assets/platform/include/SDL3/SDL_camera.h +535 -0
- data/assets/platform/include/SDL3/SDL_clipboard.h +331 -0
- data/assets/{include/SDL2/close_code.h → platform/include/SDL3/SDL_close_code.h} +9 -8
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_copying.h +3 -1
- data/assets/platform/include/SDL3/SDL_cpuinfo.h +374 -0
- data/assets/platform/include/SDL3/SDL_dialog.h +343 -0
- data/assets/platform/include/SDL3/SDL_dlopennote.h +234 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_egl.h +11 -8
- data/assets/platform/include/SDL3/SDL_endian.h +645 -0
- data/assets/platform/include/SDL3/SDL_error.h +226 -0
- data/assets/platform/include/SDL3/SDL_events.h +1645 -0
- data/assets/platform/include/SDL3/SDL_filesystem.h +537 -0
- data/assets/platform/include/SDL3/SDL_gamepad.h +1656 -0
- data/assets/platform/include/SDL3/SDL_gpu.h +4608 -0
- data/assets/platform/include/SDL3/SDL_guid.h +106 -0
- data/assets/platform/include/SDL3/SDL_haptic.h +1461 -0
- data/assets/platform/include/SDL3/SDL_hidapi.h +571 -0
- data/assets/platform/include/SDL3/SDL_hints.h +5001 -0
- data/assets/platform/include/SDL3/SDL_init.h +507 -0
- data/assets/platform/include/SDL3/SDL_intrin.h +410 -0
- data/assets/platform/include/SDL3/SDL_iostream.h +1379 -0
- data/assets/platform/include/SDL3/SDL_joystick.h +1385 -0
- data/assets/platform/include/SDL3/SDL_keyboard.h +608 -0
- data/assets/platform/include/SDL3/SDL_keycode.h +347 -0
- data/assets/platform/include/SDL3/SDL_loadso.h +145 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_locale.h +40 -24
- data/assets/platform/include/SDL3/SDL_log.h +541 -0
- data/assets/platform/include/SDL3/SDL_main.h +704 -0
- data/assets/platform/include/SDL3/SDL_main_impl.h +151 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_messagebox.h +85 -48
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_metal.h +29 -29
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_misc.h +13 -12
- data/assets/platform/include/SDL3/SDL_mouse.h +813 -0
- data/assets/platform/include/SDL3/SDL_mutex.h +1117 -0
- data/assets/platform/include/SDL3/SDL_oldnames.h +1339 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengl.h +1247 -278
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengl_glext.h +5 -1
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengles.h +6 -7
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengles2.h +10 -11
- data/assets/platform/include/SDL3/SDL_pen.h +198 -0
- data/assets/platform/include/SDL3/SDL_pixels.h +1441 -0
- data/assets/{include/SDL2/SDL_test_log.h → platform/include/SDL3/SDL_platform.h} +25 -26
- data/assets/platform/include/SDL3/SDL_platform_defines.h +497 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_power.h +40 -20
- data/assets/platform/include/SDL3/SDL_process.h +441 -0
- data/assets/platform/include/SDL3/SDL_properties.h +572 -0
- data/assets/platform/include/SDL3/SDL_rect.h +528 -0
- data/assets/platform/include/SDL3/SDL_render.h +3028 -0
- data/assets/platform/include/SDL3/SDL_revision.h +59 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_scancode.h +59 -68
- data/assets/platform/include/SDL3/SDL_sensor.h +321 -0
- data/assets/platform/include/SDL3/SDL_stdinc.h +6186 -0
- data/assets/platform/include/SDL3/SDL_storage.h +686 -0
- data/assets/platform/include/SDL3/SDL_surface.h +1769 -0
- data/assets/platform/include/SDL3/SDL_system.h +840 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test.h +16 -22
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_assert.h +27 -34
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_common.h +109 -52
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_compare.h +22 -14
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_crc32.h +27 -30
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_font.h +50 -49
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_fuzzer.h +64 -79
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_harness.h +47 -30
- data/assets/platform/include/SDL3/SDL_test_log.h +83 -0
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_md5.h +21 -28
- data/assets/{include/SDL2 → platform/include/SDL3}/SDL_test_memory.h +19 -16
- data/assets/platform/include/SDL3/SDL_thread.h +602 -0
- data/assets/platform/include/SDL3/SDL_time.h +249 -0
- data/assets/platform/include/SDL3/SDL_timer.h +454 -0
- data/assets/platform/include/SDL3/SDL_touch.h +184 -0
- data/assets/platform/include/SDL3/SDL_tray.h +544 -0
- data/assets/platform/include/SDL3/SDL_version.h +198 -0
- data/assets/platform/include/SDL3/SDL_video.h +3497 -0
- data/assets/platform/include/SDL3/SDL_vulkan.h +287 -0
- data/assets/platform/include/SDL3_image/SDL_image.h +3328 -0
- data/assets/platform/include/SDL3_mixer/SDL_mixer.h +3369 -0
- data/assets/platform/include/SDL3_ttf/SDL_textengine.h +181 -0
- data/assets/platform/include/SDL3_ttf/SDL_ttf.h +2833 -0
- data/assets/{include → platform/include}/mrbconf.h +42 -31
- data/assets/{include → platform/include}/mruby/array.h +3 -4
- data/assets/{include → platform/include}/mruby/boxing_nan.h +10 -0
- data/assets/platform/include/mruby/boxing_no.h +59 -0
- data/assets/{include → platform/include}/mruby/boxing_word.h +72 -26
- data/assets/platform/include/mruby/class.h +157 -0
- data/assets/{include → platform/include}/mruby/common.h +30 -1
- data/assets/{include → platform/include}/mruby/compile.h +52 -74
- data/assets/{include → platform/include}/mruby/data.h +2 -2
- data/assets/{include → platform/include}/mruby/debug.h +12 -5
- data/assets/{include → platform/include}/mruby/dump.h +7 -9
- data/assets/{include → platform/include}/mruby/endian.h +1 -1
- data/assets/platform/include/mruby/error.h +173 -0
- data/assets/platform/include/mruby/gc.h +79 -0
- data/assets/{include → platform/include}/mruby/hash.h +1 -7
- data/assets/platform/include/mruby/internal.h +282 -0
- data/assets/platform/include/mruby/irep.h +143 -0
- data/assets/{include → platform/include}/mruby/istruct.h +1 -1
- data/assets/platform/include/mruby/khash.h +455 -0
- data/assets/platform/include/mruby/mempool.h +19 -0
- data/assets/{include → platform/include}/mruby/numeric.h +7 -10
- data/assets/platform/include/mruby/object.h +51 -0
- data/assets/{include → platform/include}/mruby/opcode.h +5 -5
- data/assets/{include → platform/include}/mruby/ops.h +19 -6
- data/assets/platform/include/mruby/presym/id.h +1447 -0
- data/assets/{include → platform/include}/mruby/presym/scanning.h +10 -7
- data/assets/platform/include/mruby/presym/table.h +2893 -0
- data/assets/platform/include/mruby/presym.h +65 -0
- data/assets/platform/include/mruby/proc.h +184 -0
- data/assets/{include → platform/include}/mruby/range.h +0 -2
- data/assets/{include → platform/include}/mruby/string.h +33 -53
- data/assets/platform/include/mruby/throw.h +81 -0
- data/assets/{include → platform/include}/mruby/value.h +64 -29
- data/assets/{include → platform/include}/mruby/variable.h +6 -23
- data/assets/{include → platform/include}/mruby/version.h +7 -7
- data/assets/{include → platform/include}/mruby.h +238 -116
- data/assets/platform/macos-arm64/bin/mrbc +0 -0
- data/assets/platform/macos-arm64/lib/libSDL3.a +0 -0
- data/assets/platform/macos-arm64/lib/libSDL3_image.a +0 -0
- data/assets/platform/macos-arm64/lib/libSDL3_mixer.a +0 -0
- data/assets/platform/macos-arm64/lib/libSDL3_ttf.a +0 -0
- data/assets/platform/macos-arm64/lib/libmruby.a +0 -0
- data/assets/platform/wasm/lib/libFLAC.a +0 -0
- data/assets/platform/wasm/lib/libSDL3.a +0 -0
- data/assets/platform/wasm/lib/libSDL3_image.a +0 -0
- data/assets/platform/wasm/lib/libSDL3_mixer.a +0 -0
- data/assets/platform/wasm/lib/libSDL3_ttf.a +0 -0
- data/assets/platform/wasm/lib/libfreetype.a +0 -0
- data/assets/platform/wasm/lib/libharfbuzz.a +0 -0
- data/assets/platform/wasm/lib/libmruby.a +0 -0
- data/assets/platform/wasm/lib/libogg.a +0 -0
- data/assets/platform/wasm/lib/libplutosvg.a +0 -0
- data/assets/platform/wasm/lib/libplutovg.a +0 -0
- data/assets/platform/wasm/lib/libpng.a +0 -0
- data/assets/platform/wasm/lib/libpng16.a +0 -0
- data/assets/platform/wasm/lib/libvorbis.a +0 -0
- data/assets/platform/wasm/lib/libvorbisfile.a +0 -0
- data/assets/platform/wasm/lib/libzlibstatic.a +0 -0
- data/assets/platform/windows-arm64-mingw-ucrt/bin/mrbc.exe +0 -0
- data/assets/platform/windows-arm64-mingw-ucrt/lib/libSDL3.a +0 -0
- data/assets/platform/windows-arm64-mingw-ucrt/lib/libSDL3_image.a +0 -0
- data/assets/platform/windows-arm64-mingw-ucrt/lib/libSDL3_mixer.a +0 -0
- data/assets/platform/windows-arm64-mingw-ucrt/lib/libSDL3_ttf.a +0 -0
- data/assets/platform/windows-arm64-mingw-ucrt/lib/libmruby.a +0 -0
- data/assets/platform/windows-x86_64-mingw-ucrt/bin/mrbc.exe +0 -0
- data/assets/platform/windows-x86_64-mingw-ucrt/lib/libSDL3.a +0 -0
- data/assets/platform/windows-x86_64-mingw-ucrt/lib/libSDL3_image.a +0 -0
- data/assets/platform/windows-x86_64-mingw-ucrt/lib/libSDL3_mixer.a +0 -0
- data/assets/platform/windows-x86_64-mingw-ucrt/lib/libSDL3_ttf.a +0 -0
- data/assets/platform/windows-x86_64-mingw-ucrt/lib/libmruby.a +0 -0
- data/assets/resources/fonts/outfit/OFL.txt +93 -0
- data/assets/resources/fonts/outfit/outfit.ttf +0 -0
- data/assets/resources/fonts/roboto_mono/OFL.txt +91 -0
- data/assets/resources/fonts/roboto_mono/roboto_mono.ttf +0 -0
- data/assets/resources/icons/icon.icns +0 -0
- data/assets/resources/icons/icon.png +0 -0
- data/assets/resources/spritesheets/License.txt +28 -0
- data/assets/resources/spritesheets/spritesheet-backgrounds.png +0 -0
- data/assets/resources/spritesheets/spritesheet-backgrounds.xml +16 -0
- data/assets/resources/spritesheets/spritesheet-characters.png +0 -0
- data/assets/resources/spritesheets/spritesheet-characters.xml +47 -0
- data/assets/resources/spritesheets/spritesheet-enemies.png +0 -0
- data/assets/resources/spritesheets/spritesheet-enemies.xml +62 -0
- data/assets/resources/spritesheets/spritesheet-tiles.png +0 -0
- data/assets/resources/spritesheets/spritesheet-tiles.xml +316 -0
- data/assets/{wasm → resources/web}/template.html +1 -1
- data/assets/target.rb +131 -0
- data/bin/ruby2d +281 -82
- data/examples/astar.rb +269 -0
- data/examples/asteroids.rb +403 -0
- data/examples/bezier_editor.rb +96 -0
- data/examples/boids.rb +191 -0
- data/examples/bouncing_balls.rb +119 -0
- data/examples/breakout.rb +186 -0
- data/examples/constellations.rb +100 -0
- data/examples/dashboard.rb +133 -0
- data/examples/double_pendulum.rb +254 -0
- data/examples/falling_sand.rb +291 -0
- data/examples/fireworks.rb +110 -0
- data/examples/fluid_dynamics.rb +340 -0
- data/examples/fourier_epicycles.rb +142 -0
- data/examples/fractal_tree.rb +326 -0
- data/examples/game_of_life.rb +148 -0
- data/examples/gamepads.rb +333 -0
- data/examples/hill_driver.rb +613 -0
- data/examples/logo_animation.rb +251 -0
- data/examples/lorenz_attractor.rb +115 -0
- data/examples/mandelbrot.rb +207 -0
- data/examples/marching_squares.rb +200 -0
- data/examples/maze.rb +323 -0
- data/examples/nbody.rb +338 -0
- data/examples/outrun.rb +391 -0
- data/examples/pixel_paint.rb +313 -0
- data/examples/platformer.rb +335 -0
- data/examples/ray_casting_maze.rb +175 -0
- data/examples/shadow_casting.rb +151 -0
- data/examples/shape_recognizer.rb +908 -0
- data/examples/snake.rb +144 -0
- data/examples/sprite_sheets.rb +246 -0
- data/examples/swarm.rb +206 -0
- data/examples/tsp_annealing.rb +104 -0
- data/examples/ui_controls.rb +163 -0
- data/examples/wireframe_3d.rb +139 -0
- data/ext/ruby2d/audio.c +324 -0
- data/ext/ruby2d/canvas.c +1715 -494
- data/ext/ruby2d/ext.c +541 -0
- data/ext/ruby2d/extconf.rb +122 -145
- data/ext/ruby2d/font.c +566 -20
- data/ext/ruby2d/fps.c +92 -0
- data/ext/ruby2d/image.c +466 -41
- data/ext/ruby2d/ruby2d.c +374 -1890
- data/ext/ruby2d/ruby2d.h +840 -460
- data/ext/ruby2d/shapes.c +931 -101
- data/ext/ruby2d/text.c +586 -21
- data/ext/ruby2d/window.c +1693 -283
- data/lib/ruby2d/atlas_parser.rb +194 -0
- data/lib/ruby2d/audio.rb +73 -0
- data/lib/ruby2d/benchmark.rb +259 -0
- data/lib/ruby2d/bitmap_text.rb +155 -0
- data/lib/ruby2d/button.rb +402 -0
- data/lib/ruby2d/canvas.rb +703 -279
- data/lib/ruby2d/circle.rb +206 -29
- data/lib/ruby2d/cli/browser.rb +314 -0
- data/lib/ruby2d/cli/build.rb +471 -257
- data/lib/ruby2d/cli/colorize.rb +7 -5
- data/lib/ruby2d/cli/examples.rb +127 -0
- data/lib/ruby2d/cli/launch.rb +24 -39
- data/lib/ruby2d/cli/lib_files.rb +48 -0
- data/lib/ruby2d/cli/messages.rb +40 -0
- data/lib/ruby2d/cli/setup.rb +273 -0
- data/lib/ruby2d/cli/static_server.rb +160 -0
- data/lib/ruby2d/cli/usage.rb +255 -0
- data/lib/ruby2d/color.rb +191 -69
- data/lib/ruby2d/core.rb +37 -19
- data/lib/ruby2d/deps_help.rb +89 -0
- data/lib/ruby2d/dsl.rb +51 -12
- data/lib/ruby2d/ellipse.rb +228 -0
- data/lib/ruby2d/exceptions.rb +0 -2
- data/lib/ruby2d/font.rb +34 -74
- data/lib/ruby2d/gamepad.rb +323 -0
- data/lib/ruby2d/gem_paths.rb +19 -0
- data/lib/ruby2d/image.rb +155 -52
- data/lib/ruby2d/interactive.rb +103 -0
- data/lib/ruby2d/json_parser.rb +268 -0
- data/lib/ruby2d/line.rb +194 -85
- data/lib/ruby2d/mruby_compat.rb +12 -0
- data/lib/ruby2d/polygon.rb +297 -0
- data/lib/ruby2d/polyline.rb +368 -0
- data/lib/ruby2d/quad.rb +358 -94
- data/lib/ruby2d/rectangle.rb +77 -19
- data/lib/ruby2d/renderable.rb +411 -11
- data/lib/ruby2d/sprite.rb +471 -180
- data/lib/ruby2d/sprite_sheet.rb +64 -0
- data/lib/ruby2d/square.rb +29 -17
- data/lib/ruby2d/text.rb +196 -65
- data/lib/ruby2d/tileset.rb +139 -81
- data/lib/ruby2d/triangle.rb +324 -89
- data/lib/ruby2d/version.rb +1 -3
- data/lib/ruby2d/vertices.rb +62 -85
- data/lib/ruby2d/warnings.rb +29 -0
- data/lib/ruby2d/window/class_methods.rb +218 -0
- data/lib/ruby2d/window/gamepad_events.rb +141 -0
- data/lib/ruby2d/window/key_events.rb +74 -0
- data/lib/ruby2d/window/mouse_events.rb +171 -0
- data/lib/ruby2d/window/object_events.rb +168 -0
- data/lib/ruby2d/window.rb +632 -585
- data/lib/ruby2d.rb +14 -19
- metadata +275 -428
- data/assets/app.icns +0 -0
- data/assets/include/GLES2/gl2.h +0 -656
- data/assets/include/GLES2/gl2ext.h +0 -3949
- data/assets/include/GLES2/gl2ext_angle.h +0 -701
- data/assets/include/GLES2/gl2platform.h +0 -27
- data/assets/include/GLES3/gl3.h +0 -1192
- data/assets/include/GLES3/gl31.h +0 -1507
- data/assets/include/GLES3/gl32.h +0 -1808
- data/assets/include/GLES3/gl3platform.h +0 -27
- data/assets/include/KHR/khrplatform.h +0 -290
- data/assets/include/SDL2/SDL.h +0 -233
- data/assets/include/SDL2/SDL_assert.h +0 -326
- data/assets/include/SDL2/SDL_atomic.h +0 -415
- data/assets/include/SDL2/SDL_audio.h +0 -1500
- data/assets/include/SDL2/SDL_clipboard.h +0 -141
- data/assets/include/SDL2/SDL_config.h +0 -61
- data/assets/include/SDL2/SDL_config_android.h +0 -194
- data/assets/include/SDL2/SDL_config_emscripten.h +0 -218
- data/assets/include/SDL2/SDL_config_iphoneos.h +0 -217
- data/assets/include/SDL2/SDL_config_macosx.h +0 -277
- data/assets/include/SDL2/SDL_config_minimal.h +0 -95
- data/assets/include/SDL2/SDL_config_ngage.h +0 -89
- data/assets/include/SDL2/SDL_config_os2.h +0 -207
- data/assets/include/SDL2/SDL_config_pandora.h +0 -141
- data/assets/include/SDL2/SDL_config_windows.h +0 -331
- data/assets/include/SDL2/SDL_config_wingdk.h +0 -253
- data/assets/include/SDL2/SDL_config_winrt.h +0 -220
- data/assets/include/SDL2/SDL_config_xbox.h +0 -235
- data/assets/include/SDL2/SDL_cpuinfo.h +0 -594
- data/assets/include/SDL2/SDL_endian.h +0 -348
- data/assets/include/SDL2/SDL_error.h +0 -163
- data/assets/include/SDL2/SDL_events.h +0 -1166
- data/assets/include/SDL2/SDL_filesystem.h +0 -149
- data/assets/include/SDL2/SDL_gamecontroller.h +0 -1074
- data/assets/include/SDL2/SDL_gesture.h +0 -117
- data/assets/include/SDL2/SDL_guid.h +0 -100
- data/assets/include/SDL2/SDL_haptic.h +0 -1341
- data/assets/include/SDL2/SDL_hidapi.h +0 -451
- data/assets/include/SDL2/SDL_hints.h +0 -2569
- data/assets/include/SDL2/SDL_image.h +0 -2173
- data/assets/include/SDL2/SDL_joystick.h +0 -1066
- data/assets/include/SDL2/SDL_keyboard.h +0 -353
- data/assets/include/SDL2/SDL_keycode.h +0 -358
- data/assets/include/SDL2/SDL_loadso.h +0 -115
- data/assets/include/SDL2/SDL_log.h +0 -404
- data/assets/include/SDL2/SDL_main.h +0 -275
- data/assets/include/SDL2/SDL_mixer.h +0 -2784
- data/assets/include/SDL2/SDL_mouse.h +0 -465
- data/assets/include/SDL2/SDL_mutex.h +0 -471
- data/assets/include/SDL2/SDL_name.h +0 -33
- data/assets/include/SDL2/SDL_pixels.h +0 -644
- data/assets/include/SDL2/SDL_platform.h +0 -261
- data/assets/include/SDL2/SDL_quit.h +0 -58
- data/assets/include/SDL2/SDL_rect.h +0 -376
- data/assets/include/SDL2/SDL_render.h +0 -1919
- data/assets/include/SDL2/SDL_revision.h +0 -6
- data/assets/include/SDL2/SDL_rwops.h +0 -841
- data/assets/include/SDL2/SDL_sensor.h +0 -322
- data/assets/include/SDL2/SDL_shape.h +0 -155
- data/assets/include/SDL2/SDL_stdinc.h +0 -830
- data/assets/include/SDL2/SDL_surface.h +0 -997
- data/assets/include/SDL2/SDL_system.h +0 -623
- data/assets/include/SDL2/SDL_syswm.h +0 -386
- data/assets/include/SDL2/SDL_test_images.h +0 -78
- data/assets/include/SDL2/SDL_test_random.h +0 -115
- data/assets/include/SDL2/SDL_thread.h +0 -464
- data/assets/include/SDL2/SDL_timer.h +0 -222
- data/assets/include/SDL2/SDL_touch.h +0 -150
- data/assets/include/SDL2/SDL_ttf.h +0 -2316
- data/assets/include/SDL2/SDL_types.h +0 -29
- data/assets/include/SDL2/SDL_version.h +0 -204
- data/assets/include/SDL2/SDL_video.h +0 -2150
- data/assets/include/SDL2/SDL_vulkan.h +0 -215
- data/assets/include/SDL2/begin_code.h +0 -187
- data/assets/include/mruby/boxing_no.h +0 -58
- data/assets/include/mruby/class.h +0 -108
- data/assets/include/mruby/error.h +0 -147
- data/assets/include/mruby/gc.h +0 -94
- data/assets/include/mruby/irep.h +0 -147
- data/assets/include/mruby/khash.h +0 -284
- data/assets/include/mruby/object.h +0 -43
- data/assets/include/mruby/presym/disable.h +0 -70
- data/assets/include/mruby/presym/enable.h +0 -37
- data/assets/include/mruby/presym.h +0 -40
- data/assets/include/mruby/proc.h +0 -211
- data/assets/include/mruby/throw.h +0 -66
- data/assets/macos/universal/bin/mrbc +0 -0
- data/assets/macos/universal/lib/libFLAC.a +0 -0
- data/assets/macos/universal/lib/libSDL2.a +0 -0
- data/assets/macos/universal/lib/libSDL2_image.a +0 -0
- data/assets/macos/universal/lib/libSDL2_mixer.a +0 -0
- data/assets/macos/universal/lib/libSDL2_ttf.a +0 -0
- data/assets/macos/universal/lib/libavif.a +0 -0
- data/assets/macos/universal/lib/libbrotlicommon-static.a +0 -0
- data/assets/macos/universal/lib/libbrotlidec-static.a +0 -0
- data/assets/macos/universal/lib/libfreetype.a +0 -0
- data/assets/macos/universal/lib/libgraphite2.a +0 -0
- data/assets/macos/universal/lib/libharfbuzz.a +0 -0
- data/assets/macos/universal/lib/libhwy.a +0 -0
- data/assets/macos/universal/lib/libjpeg.a +0 -0
- data/assets/macos/universal/lib/libjxl.a +0 -0
- data/assets/macos/universal/lib/libmodplug.a +0 -0
- data/assets/macos/universal/lib/libmpg123.a +0 -0
- data/assets/macos/universal/lib/libmruby.a +0 -0
- data/assets/macos/universal/lib/libogg.a +0 -0
- data/assets/macos/universal/lib/libpng.a +0 -0
- data/assets/macos/universal/lib/libtiff.a +0 -0
- data/assets/macos/universal/lib/libvorbis.a +0 -0
- data/assets/macos/universal/lib/libvorbisfile.a +0 -0
- data/assets/macos/universal/lib/libwebp.a +0 -0
- data/assets/macos/universal/lib/libzstd.a +0 -0
- data/assets/test_media/README.md +0 -3
- data/assets/test_media/bitstream_vera/COPYRIGHT.txt +0 -124
- data/assets/test_media/bitstream_vera/vera.ttf +0 -0
- data/assets/test_media/boom.png +0 -0
- data/assets/test_media/coin.png +0 -0
- data/assets/test_media/colors.png +0 -0
- data/assets/test_media/controller.png +0 -0
- data/assets/test_media/dial.wav +0 -0
- data/assets/test_media/hero.png +0 -0
- data/assets/test_media/image.bmp +0 -0
- data/assets/test_media/image.jpg +0 -0
- data/assets/test_media/image.png +0 -0
- data/assets/test_media/music.flac +0 -0
- data/assets/test_media/music.mp3 +0 -0
- data/assets/test_media/music.ogg +0 -0
- data/assets/test_media/music.wav +0 -0
- data/assets/test_media/originals/boom.pxm +0 -0
- data/assets/test_media/originals/coin.pxm +0 -0
- data/assets/test_media/originals/controller.sketch +0 -0
- data/assets/test_media/originals/hero.pxm +0 -0
- data/assets/test_media/originals/image.pxm +0 -0
- data/assets/test_media/originals/music.caf +0 -0
- data/assets/test_media/originals/texture_atlas.pxm +0 -0
- data/assets/test_media/rondo_alla_turka.ogg +0 -0
- data/assets/test_media/sound.flac +0 -0
- data/assets/test_media/sound.mp3 +0 -0
- data/assets/test_media/sound.ogg +0 -0
- data/assets/test_media/sound.wav +0 -0
- data/assets/test_media/sprite_sheet.png +0 -0
- data/assets/test_media/texture_atlas.png +0 -0
- data/assets/wasm/libmruby.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/bin/mrbc.exe +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libFLAC.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libLerc.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_image.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_mixer.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libSDL2_ttf.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbrotlicommon.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbrotlidec.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libbz2.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libdeflate.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libfreetype.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libglew32.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libgraphite2.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libharfbuzz.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libhwy.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjbig.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjpeg.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libjxl.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/liblzma.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmodplug.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmpg123.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libmruby.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libogg.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libopus.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libopusfile.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libpng.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libsndfile.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libssp.a +0 -1
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libstdc++.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libtiff.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libvorbis.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libvorbisfile.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libwebp.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libz.a +0 -0
- data/assets/windows/mingw-w64-ucrt-x86_64/lib/libzstd.a +0 -0
- data/assets/windows/mingw-w64-x86_64/bin/mrbc.exe +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libFLAC.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libLerc.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libSDL2.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libSDL2_image.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libSDL2_mixer.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libSDL2_ttf.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libbrotlicommon.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libbrotlidec.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libbz2.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libdeflate.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libfreetype.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libglew32.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libgraphite2.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libharfbuzz.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libhwy.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libjbig.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libjpeg.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libjxl.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/liblzma.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libmodplug.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libmpg123.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libmruby.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libogg.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libopus.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libopusfile.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libpng.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libsndfile.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libssp.a +0 -1
- data/assets/windows/mingw-w64-x86_64/lib/libstdc++.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libtiff.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libvorbis.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libvorbisfile.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libwebp.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libz.a +0 -0
- data/assets/windows/mingw-w64-x86_64/lib/libzstd.a +0 -0
- data/assets/xcode/ios/Assets.xcassets/AppIcon.appiconset/Contents.json +0 -98
- data/assets/xcode/ios/Assets.xcassets/Contents.json +0 -6
- data/assets/xcode/ios/Base.lproj/LaunchScreen.storyboard +0 -27
- data/assets/xcode/ios/Info.plist +0 -43
- data/assets/xcode/ios/MRuby.framework/Headers/mrbconf.h +0 -143
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/array.h +0 -280
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/boxing_nan.h +0 -102
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/boxing_no.h +0 -56
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/boxing_word.h +0 -144
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/class.h +0 -97
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/common.h +0 -77
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/compile.h +0 -195
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/data.h +0 -75
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/debug.h +0 -67
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/dump.h +0 -196
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/error.h +0 -75
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/gc.h +0 -91
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/hash.h +0 -215
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/irep.h +0 -75
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/istruct.h +0 -47
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/khash.h +0 -274
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/numeric.h +0 -161
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/object.h +0 -44
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/opcode.h +0 -69
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/ops.h +0 -117
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/proc.h +0 -131
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/range.h +0 -49
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/re.h +0 -16
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/string.h +0 -444
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/throw.h +0 -55
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/value.h +0 -309
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/variable.h +0 -136
- data/assets/xcode/ios/MRuby.framework/Headers/mruby/version.h +0 -110
- data/assets/xcode/ios/MRuby.framework/Headers/mruby.h +0 -1282
- data/assets/xcode/ios/MRuby.framework/Info.plist +0 -20
- data/assets/xcode/ios/MRuby.framework/MRuby +0 -0
- data/assets/xcode/ios/MyApp.xcodeproj/project.pbxproj +0 -368
- data/assets/xcode/ios/MyApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- data/assets/xcode/ios/MyApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- data/assets/xcode/ios/MyApp.xcodeproj/project.xcworkspace/xcshareddata/MyApp.xcscmblueprint +0 -30
- data/assets/xcode/ios/main.c +0 -1
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Content.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Back.imagestacklayer/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Contents.json +0 -17
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Content.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Front.imagestacklayer/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Large.imagestack/Middle.imagestacklayer/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Content.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Back.imagestacklayer/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Contents.json +0 -17
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Content.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Front.imagestacklayer/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Content.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/App Icon - Small.imagestack/Middle.imagestacklayer/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Contents.json +0 -32
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image Wide.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/App Icon & Top Shelf Image.brandassets/Top Shelf Image.imageset/Contents.json +0 -16
- data/assets/xcode/tvos/Assets.xcassets/Contents.json +0 -6
- data/assets/xcode/tvos/Assets.xcassets/LaunchImage.launchimage/Contents.json +0 -22
- data/assets/xcode/tvos/Info.plist +0 -30
- data/assets/xcode/tvos/MRuby.framework/Headers/mrbconf.h +0 -143
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/array.h +0 -280
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/boxing_nan.h +0 -102
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/boxing_no.h +0 -56
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/boxing_word.h +0 -144
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/class.h +0 -97
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/common.h +0 -77
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/compile.h +0 -195
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/data.h +0 -75
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/debug.h +0 -67
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/dump.h +0 -196
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/error.h +0 -75
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/gc.h +0 -91
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/hash.h +0 -215
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/irep.h +0 -75
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/istruct.h +0 -47
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/khash.h +0 -274
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/numeric.h +0 -161
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/object.h +0 -44
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/opcode.h +0 -69
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/ops.h +0 -117
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/proc.h +0 -131
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/range.h +0 -49
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/re.h +0 -16
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/string.h +0 -444
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/throw.h +0 -55
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/value.h +0 -309
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/variable.h +0 -136
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby/version.h +0 -110
- data/assets/xcode/tvos/MRuby.framework/Headers/mruby.h +0 -1282
- data/assets/xcode/tvos/MRuby.framework/Info.plist +0 -20
- data/assets/xcode/tvos/MRuby.framework/MRuby +0 -0
- data/assets/xcode/tvos/MyApp.xcodeproj/project.pbxproj +0 -350
- data/assets/xcode/tvos/MyApp.xcodeproj/project.xcworkspace/contents.xcworkspacedata +0 -7
- data/assets/xcode/tvos/MyApp.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +0 -8
- data/assets/xcode/tvos/MyApp.xcodeproj/project.xcworkspace/xcshareddata/MyApp.xcscmblueprint +0 -30
- data/assets/xcode/tvos/main.c +0 -1
- data/ext/ruby2d/common.c +0 -185
- data/ext/ruby2d/controllers.c +0 -110
- data/ext/ruby2d/gl.c +0 -398
- data/ext/ruby2d/gl2.c +0 -86
- data/ext/ruby2d/gl3.c +0 -304
- data/ext/ruby2d/gles.c +0 -302
- data/ext/ruby2d/input.c +0 -48
- data/ext/ruby2d/music.c +0 -127
- data/ext/ruby2d/sound.c +0 -132
- data/lib/ruby2d/cli/console.rb +0 -65
- data/lib/ruby2d/cli/enable_console.rb +0 -7
- data/lib/ruby2d/cli/platform.rb +0 -17
- data/lib/ruby2d/music.rb +0 -77
- data/lib/ruby2d/pixel.rb +0 -18
- data/lib/ruby2d/pixmap.rb +0 -39
- data/lib/ruby2d/pixmap_atlas.rb +0 -56
- data/lib/ruby2d/sound.rb +0 -61
- data/lib/ruby2d/texture.rb +0 -38
- /data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengles2_gl2.h +0 -0
- /data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengles2_gl2ext.h +0 -0
- /data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengles2_gl2platform.h +0 -0
- /data/assets/{include/SDL2 → platform/include/SDL3}/SDL_opengles2_khrplatform.h +0 -0
- /data/assets/{include → platform/include}/mruby/re.h +0 -0
data/ext/ruby2d/text.c
CHANGED
|
@@ -2,34 +2,599 @@
|
|
|
2
2
|
|
|
3
3
|
#include "ruby2d.h"
|
|
4
4
|
|
|
5
|
+
R2D_DEFINE_DATA_TYPE(R2D_Text);
|
|
6
|
+
|
|
7
|
+
// Text-specific ivar IDs. Shared ivar IDs live in ext.c.
|
|
8
|
+
static R_ID id_font, id_size, id_style_flags;
|
|
9
|
+
|
|
5
10
|
|
|
6
11
|
/*
|
|
7
|
-
*
|
|
12
|
+
* Initialize
|
|
8
13
|
*/
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
14
|
+
void R2D_Text_Init() {
|
|
15
|
+
id_font = r_id("@font");
|
|
16
|
+
id_size = r_id("@size");
|
|
17
|
+
id_style_flags = r_id("@style_flags");
|
|
18
|
+
|
|
19
|
+
r_define_class_method(ruby2d_ext_module, "text_create", ruby2d_ext_text_create, r_args_variadic);
|
|
20
|
+
r_define_class_method(ruby2d_ext_module, "text_draw", ruby2d_ext_text_draw, r_args_variadic);
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
|
|
24
|
+
// Font Cache //////////////////////////////////////////////////////////////////
|
|
25
|
+
//
|
|
26
|
+
// Shares TTF_Font handles across R2D_Text objects with the same font path and
|
|
27
|
+
// size. Each entry is reference-counted; the font is only closed when the last
|
|
28
|
+
// reference is released AND the slot is needed for a new font.
|
|
29
|
+
|
|
30
|
+
#define R2D_FONT_CACHE_MAX 128
|
|
31
|
+
|
|
32
|
+
struct R2D_FontCacheEntry {
|
|
33
|
+
char *path;
|
|
34
|
+
int size;
|
|
35
|
+
int style; // TTF_FontStyleFlags (bold/italic/…) — part of the cache key
|
|
36
|
+
TTF_Font *font;
|
|
37
|
+
int ref_count;
|
|
38
|
+
bool standalone; // true => not in the cache array; freed when ref_count hits 0
|
|
39
|
+
};
|
|
40
|
+
|
|
41
|
+
static R2D_FontCacheEntry font_cache[R2D_FONT_CACHE_MAX];
|
|
42
|
+
static int font_cache_count = 0;
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
/*
|
|
46
|
+
* Look up or open a font, returning a cache entry with ref_count incremented.
|
|
47
|
+
* Returns NULL on failure (SDL error is set).
|
|
48
|
+
*/
|
|
49
|
+
static R2D_FontCacheEntry *R2D_FontCacheGet(const char *path, int size, int style) {
|
|
50
|
+
// Search for existing entry
|
|
51
|
+
for (int i = 0; i < font_cache_count; i++) {
|
|
52
|
+
if (font_cache[i].size == size && font_cache[i].style == style &&
|
|
53
|
+
strcmp(font_cache[i].path, path) == 0) {
|
|
54
|
+
font_cache[i].ref_count++;
|
|
55
|
+
return &font_cache[i];
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
// Not found — open a new font and apply its style. Style is part of the
|
|
60
|
+
// cache key, so each (path, size, style) owns its own TTF_Font and
|
|
61
|
+
// TTF_SetFontStyle never mutates a handle shared by differently-styled text.
|
|
62
|
+
TTF_Font *font = TTF_OpenFont(path, size);
|
|
63
|
+
if (!font) return NULL;
|
|
64
|
+
TTF_SetFontStyle(font, style);
|
|
12
65
|
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
if (
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
66
|
+
// Find a slot: append if room, otherwise evict an unreferenced entry
|
|
67
|
+
R2D_FontCacheEntry *slot = NULL;
|
|
68
|
+
if (font_cache_count < R2D_FONT_CACHE_MAX) {
|
|
69
|
+
slot = &font_cache[font_cache_count++];
|
|
70
|
+
} else {
|
|
71
|
+
for (int i = 0; i < font_cache_count; i++) {
|
|
72
|
+
if (font_cache[i].ref_count == 0) {
|
|
73
|
+
TTF_CloseFont(font_cache[i].font);
|
|
74
|
+
free(font_cache[i].path);
|
|
75
|
+
slot = &font_cache[i];
|
|
76
|
+
break;
|
|
77
|
+
}
|
|
78
|
+
}
|
|
19
79
|
}
|
|
20
80
|
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
81
|
+
if (!slot) {
|
|
82
|
+
// Cache is full and every entry is referenced by a live Text. The font is
|
|
83
|
+
// valid — fall back to a standalone, single-owner entry rather than
|
|
84
|
+
// hard-failing a legitimate font. It isn't shared (no array slot to find
|
|
85
|
+
// it), so its sole owner frees it via R2D_FontCacheRelease.
|
|
86
|
+
R2D_FontCacheEntry *standalone = malloc(sizeof(R2D_FontCacheEntry));
|
|
87
|
+
if (!standalone) {
|
|
88
|
+
TTF_CloseFont(font);
|
|
89
|
+
return NULL;
|
|
90
|
+
}
|
|
91
|
+
standalone->path = strdup(path);
|
|
92
|
+
standalone->size = size;
|
|
93
|
+
standalone->style = style;
|
|
94
|
+
standalone->font = font;
|
|
95
|
+
standalone->ref_count = 1;
|
|
96
|
+
standalone->standalone = true;
|
|
97
|
+
return standalone;
|
|
31
98
|
}
|
|
32
|
-
surface->pitch = len;
|
|
33
99
|
|
|
100
|
+
slot->path = strdup(path);
|
|
101
|
+
slot->size = size;
|
|
102
|
+
slot->style = style;
|
|
103
|
+
slot->font = font;
|
|
104
|
+
slot->ref_count = 1;
|
|
105
|
+
slot->standalone = false;
|
|
106
|
+
return slot;
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
/*
|
|
111
|
+
* Release a reference to a cached font. The entry stays in the cache (with
|
|
112
|
+
* ref_count 0) so it can be reused without reopening the file.
|
|
113
|
+
*/
|
|
114
|
+
static void R2D_FontCacheRelease(R2D_FontCacheEntry *entry) {
|
|
115
|
+
if (!entry) return;
|
|
116
|
+
if (entry->ref_count > 0) entry->ref_count--;
|
|
117
|
+
|
|
118
|
+
// Standalone (degraded) entries aren't in the cache array, so nothing can
|
|
119
|
+
// reuse them — close and free once the last reference is gone.
|
|
120
|
+
if (entry->standalone && entry->ref_count == 0) {
|
|
121
|
+
TTF_CloseFont(entry->font);
|
|
122
|
+
free(entry->path);
|
|
123
|
+
free(entry);
|
|
124
|
+
}
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
|
|
128
|
+
// Text Surface Cache //////////////////////////////////////////////////////////
|
|
129
|
+
//
|
|
130
|
+
// Shares rendered SDL_Surface* handles across R2D_Text objects with the same
|
|
131
|
+
// (font entry, string) pair, avoiding duplicate TTF_RenderText_Blended calls
|
|
132
|
+
// for identical labels. Each slot is reference-counted and also holds a
|
|
133
|
+
// reference on its font entry so the font cache cannot evict a font while any
|
|
134
|
+
// cached surface is keyed against it.
|
|
135
|
+
|
|
136
|
+
#define R2D_TEXT_SURFACE_CACHE_MAX 256
|
|
137
|
+
|
|
138
|
+
typedef struct {
|
|
139
|
+
R2D_FontCacheEntry *entry;
|
|
140
|
+
char *text;
|
|
141
|
+
size_t text_len; // byte length of `text`; keys compared by length + memcmp
|
|
142
|
+
SDL_Surface *surface;
|
|
143
|
+
int ref_count;
|
|
144
|
+
uint64_t last_used;
|
|
145
|
+
} R2D_TextSurfaceCacheEntry;
|
|
146
|
+
|
|
147
|
+
static R2D_TextSurfaceCacheEntry text_surface_cache[R2D_TEXT_SURFACE_CACHE_MAX];
|
|
148
|
+
static int text_surface_cache_count = 0;
|
|
149
|
+
static uint64_t text_surface_cache_tick = 0;
|
|
150
|
+
|
|
151
|
+
|
|
152
|
+
/*
|
|
153
|
+
* Duplicate a byte buffer of exactly `len` bytes, NUL-terminating the copy.
|
|
154
|
+
* Unlike strdup, this preserves embedded NULs so length-keyed text (which may
|
|
155
|
+
* contain them) round-trips intact. Returns NULL on allocation failure.
|
|
156
|
+
*/
|
|
157
|
+
static char *R2D_TextDup(const char *text, size_t len) {
|
|
158
|
+
char *copy = malloc(len + 1);
|
|
159
|
+
if (!copy) return NULL;
|
|
160
|
+
memcpy(copy, text, len);
|
|
161
|
+
copy[len] = '\0';
|
|
162
|
+
return copy;
|
|
163
|
+
}
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
/*
|
|
167
|
+
* Look up or rasterize a surface for (entry, msg) of msg_len bytes. The key is
|
|
168
|
+
* length-aware so embedded NULs and prefix-equal strings stay distinct.
|
|
169
|
+
*
|
|
170
|
+
* On success, returns a surface and sets *cached_out:
|
|
171
|
+
* - true => surface is shared and ref-counted in the cache; caller must
|
|
172
|
+
* release via R2D_TextSurfaceCacheRelease(entry, msg, msg_len).
|
|
173
|
+
* - false => cache was full with all entries live; caller owns the surface
|
|
174
|
+
* and must SDL_DestroySurface it directly.
|
|
175
|
+
*
|
|
176
|
+
* Returns NULL on rasterization failure (SDL error is set).
|
|
177
|
+
*/
|
|
178
|
+
static SDL_Surface *R2D_TextSurfaceCacheGet(
|
|
179
|
+
R2D_FontCacheEntry *entry, const char *msg, size_t msg_len, bool *cached_out) {
|
|
180
|
+
|
|
181
|
+
// Fast path: existing cached surface. The key is compared by byte length and
|
|
182
|
+
// memcmp (not strcmp) so content with embedded NULs — and prefix-equal strings
|
|
183
|
+
// of different lengths — are distinguished correctly.
|
|
184
|
+
for (int i = 0; i < text_surface_cache_count; i++) {
|
|
185
|
+
R2D_TextSurfaceCacheEntry *e = &text_surface_cache[i];
|
|
186
|
+
if (e->entry == entry && e->text_len == msg_len &&
|
|
187
|
+
memcmp(e->text, msg, msg_len) == 0) {
|
|
188
|
+
e->ref_count++;
|
|
189
|
+
e->last_used = ++text_surface_cache_tick;
|
|
190
|
+
*cached_out = true;
|
|
191
|
+
return e->surface;
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
|
|
195
|
+
// Pick a slot before rasterizing so we can fall back to degraded mode cleanly.
|
|
196
|
+
// For an LRU-evicted slot, defer freeing the victim's contents until the new
|
|
197
|
+
// surface rasterizes successfully — destroying it up front would leave the
|
|
198
|
+
// still-live slot pointing at freed memory if the rasterize fails (a UAF on
|
|
199
|
+
// the next lookup's memcmp, then a double-free on the next eviction).
|
|
200
|
+
R2D_TextSurfaceCacheEntry *slot = NULL;
|
|
201
|
+
bool is_new_slot = false;
|
|
202
|
+
if (text_surface_cache_count < R2D_TEXT_SURFACE_CACHE_MAX) {
|
|
203
|
+
slot = &text_surface_cache[text_surface_cache_count];
|
|
204
|
+
is_new_slot = true;
|
|
205
|
+
} else {
|
|
206
|
+
uint64_t lowest_tick = UINT64_MAX;
|
|
207
|
+
for (int i = 0; i < text_surface_cache_count; i++) {
|
|
208
|
+
R2D_TextSurfaceCacheEntry *e = &text_surface_cache[i];
|
|
209
|
+
if (e->ref_count == 0 && e->last_used < lowest_tick) {
|
|
210
|
+
lowest_tick = e->last_used;
|
|
211
|
+
slot = e;
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
}
|
|
215
|
+
|
|
216
|
+
SDL_Color color = { 255, 255, 255, 255 };
|
|
217
|
+
// Wrapped renderer with wrap width 0 lays out embedded "\n" as hard line
|
|
218
|
+
// breaks (the non-wrapped TTF_RenderText_Blended renders newlines as a
|
|
219
|
+
// single garbled line). Wrap width 0 means "only break on explicit \n".
|
|
220
|
+
// Pass the explicit byte length (not 0 = NUL-terminated) so content with an
|
|
221
|
+
// embedded NUL renders in full rather than truncating at the first NUL.
|
|
222
|
+
SDL_Surface *surface = TTF_RenderText_Blended_Wrapped(entry->font, msg, msg_len, color, 0);
|
|
223
|
+
if (!surface) return NULL;
|
|
224
|
+
|
|
225
|
+
#ifdef __EMSCRIPTEN__
|
|
226
|
+
// Normalize to RGBA32: the web build's persistent text texture is created
|
|
227
|
+
// RGBA32 (WebGL-native, like Canvas) and takes raw SDL_UpdateTexture
|
|
228
|
+
// uploads, so the surface must match byte-for-byte. TTF renders ARGB8888;
|
|
229
|
+
// converting once here costs far less than the rasterize itself, and cache
|
|
230
|
+
// hits skip both. Web-only: native keeps the ARGB surface because Metal
|
|
231
|
+
// prefers it — an RGBA32 surface forced a convert-back inside every
|
|
232
|
+
// CreateTextureFromSurface, measurably slowing the dynamic-text bench.
|
|
233
|
+
if (surface->format != SDL_PIXELFORMAT_RGBA32) {
|
|
234
|
+
SDL_Surface *converted = SDL_ConvertSurface(surface, SDL_PIXELFORMAT_RGBA32);
|
|
235
|
+
SDL_DestroySurface(surface);
|
|
236
|
+
if (!converted) return NULL;
|
|
237
|
+
surface = converted;
|
|
238
|
+
}
|
|
239
|
+
#endif
|
|
240
|
+
|
|
241
|
+
if (!slot) {
|
|
242
|
+
// Degraded: every cached entry is live. Rasterize ad-hoc, don't insert.
|
|
243
|
+
*cached_out = false;
|
|
244
|
+
return surface;
|
|
245
|
+
}
|
|
246
|
+
|
|
247
|
+
// Rasterize succeeded — now it's safe to evict the LRU victim's contents
|
|
248
|
+
// (reused slots only; a freshly appended slot has nothing to free).
|
|
249
|
+
if (!is_new_slot) {
|
|
250
|
+
SDL_DestroySurface(slot->surface);
|
|
251
|
+
free(slot->text);
|
|
252
|
+
R2D_FontCacheRelease(slot->entry);
|
|
253
|
+
}
|
|
254
|
+
|
|
255
|
+
// Hold our own ref on the font entry for the lifetime of this cache slot.
|
|
256
|
+
entry->ref_count++;
|
|
257
|
+
|
|
258
|
+
slot->entry = entry;
|
|
259
|
+
slot->text = R2D_TextDup(msg, msg_len);
|
|
260
|
+
slot->text_len = msg_len;
|
|
261
|
+
slot->surface = surface;
|
|
262
|
+
slot->ref_count = 1;
|
|
263
|
+
slot->last_used = ++text_surface_cache_tick;
|
|
264
|
+
if (is_new_slot) text_surface_cache_count++;
|
|
265
|
+
|
|
266
|
+
*cached_out = true;
|
|
34
267
|
return surface;
|
|
35
268
|
}
|
|
269
|
+
|
|
270
|
+
|
|
271
|
+
/*
|
|
272
|
+
* Release one R2D_Text's reference on a cached surface. The entry stays in
|
|
273
|
+
* the cache (with ref_count 0) so a future lookup can reuse it without
|
|
274
|
+
* re-rasterizing; eviction happens lazily on the next cache miss.
|
|
275
|
+
*/
|
|
276
|
+
static void R2D_TextSurfaceCacheRelease(
|
|
277
|
+
R2D_FontCacheEntry *entry, const char *text, size_t text_len) {
|
|
278
|
+
for (int i = 0; i < text_surface_cache_count; i++) {
|
|
279
|
+
R2D_TextSurfaceCacheEntry *e = &text_surface_cache[i];
|
|
280
|
+
if (e->entry == entry && e->text_len == text_len &&
|
|
281
|
+
memcmp(e->text, text, text_len) == 0) {
|
|
282
|
+
if (e->ref_count > 0) e->ref_count--;
|
|
283
|
+
return;
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
}
|
|
287
|
+
|
|
288
|
+
|
|
289
|
+
/*
|
|
290
|
+
* Release the surface/font references a Text currently holds, leaving the
|
|
291
|
+
* fields NULL. A no-op on a freshly allocated struct (all fields NULL).
|
|
292
|
+
* Shared by R2D_TextRasterize (before installing new resources) and
|
|
293
|
+
* R2D_Text_free (final teardown). The GPU texture is deliberately NOT
|
|
294
|
+
* released here: it persists across re-rasterizes as a grow-only allocation
|
|
295
|
+
* (text_draw uploads the new surface into it), and is destroyed only in
|
|
296
|
+
* R2D_Text_free.
|
|
297
|
+
*/
|
|
298
|
+
static void R2D_TextReleaseResources(R2D_Text *txt) {
|
|
299
|
+
if (txt->cached_text) {
|
|
300
|
+
R2D_TextSurfaceCacheRelease(txt->font_entry, txt->cached_text, txt->cached_text_len);
|
|
301
|
+
free(txt->cached_text);
|
|
302
|
+
txt->cached_text = NULL;
|
|
303
|
+
txt->cached_text_len = 0;
|
|
304
|
+
txt->surface = NULL; // owned by cache — don't destroy
|
|
305
|
+
} else if (txt->surface) {
|
|
306
|
+
SDL_DestroySurface(txt->surface);
|
|
307
|
+
txt->surface = NULL;
|
|
308
|
+
}
|
|
309
|
+
R2D_FontCacheRelease(txt->font_entry);
|
|
310
|
+
txt->font_entry = NULL;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
|
|
314
|
+
/*
|
|
315
|
+
* (Re)rasterize a Text's surface at the current asset scale and update its
|
|
316
|
+
* logical width/height, marking the persistent texture stale so text_draw
|
|
317
|
+
* re-uploads it.
|
|
318
|
+
*
|
|
319
|
+
* All fallible work (open font, render surface, copy the cache key) is done
|
|
320
|
+
* into local temporaries first; only once every step succeeds are the old
|
|
321
|
+
* resources released and the new ones installed. On any failure the existing
|
|
322
|
+
* txt->surface/font_entry/cached_text are left untouched (so a previously valid
|
|
323
|
+
* Text keeps drawing) and false is returned (SDL error is set).
|
|
324
|
+
*
|
|
325
|
+
* Called from text_create (initial build) and from text_draw when the asset
|
|
326
|
+
* scale has changed since the surface was built — e.g. a Text constructed
|
|
327
|
+
* before the window opened, when R2D_GetAssetScale() was still 1.0.
|
|
328
|
+
*/
|
|
329
|
+
static bool R2D_TextRasterize(R_VAL obj, R2D_Text *txt) {
|
|
330
|
+
const char *font = obj_str(obj, id_font);
|
|
331
|
+
const char *msg = obj_str(obj, id_content);
|
|
332
|
+
size_t msg_len = obj_str_len(obj, id_content);
|
|
333
|
+
int size = obj_int(obj, id_size);
|
|
334
|
+
int style = obj_int(obj, id_style_flags);
|
|
335
|
+
|
|
336
|
+
float scale = R2D_GetAssetScale();
|
|
337
|
+
int effective_size = (int)(size * scale);
|
|
338
|
+
|
|
339
|
+
// --- Build the new resources into locals (nothing on txt is touched yet) ---
|
|
340
|
+
R2D_FontCacheEntry *new_entry = R2D_FontCacheGet(font, effective_size, style);
|
|
341
|
+
if (!new_entry) return false;
|
|
342
|
+
|
|
343
|
+
// Empty content: report a zero-width box at the font's natural line height and
|
|
344
|
+
// skip rasterization entirely (no surface or texture). The draw paths key off
|
|
345
|
+
// txt->empty to treat this as "nothing to draw" rather than a failure. Width
|
|
346
|
+
// and height are derived from the new font, so it's safe to set them once the
|
|
347
|
+
// (only fallible) font open above has succeeded.
|
|
348
|
+
if (msg_len == 0) {
|
|
349
|
+
int new_height = (int)((float)TTF_GetFontHeight(new_entry->font) / scale);
|
|
350
|
+
|
|
351
|
+
R2D_TextReleaseResources(txt);
|
|
352
|
+
#ifndef __EMSCRIPTEN__
|
|
353
|
+
// Native: drop the texture here, during the update phase, exactly like
|
|
354
|
+
// the pre-persistent-texture code — destroying at draw time instead
|
|
355
|
+
// (mid-render, per text) breaks the renderer's command batching and
|
|
356
|
+
// measurably slowed the dynamic-text bench.
|
|
357
|
+
if (txt->texture) {
|
|
358
|
+
if (R2D_RendererAlive()) SDL_DestroyTexture(txt->texture);
|
|
359
|
+
txt->texture = NULL;
|
|
360
|
+
}
|
|
361
|
+
#endif
|
|
362
|
+
txt->font_entry = new_entry;
|
|
363
|
+
txt->surface = NULL;
|
|
364
|
+
txt->cached_text = NULL;
|
|
365
|
+
txt->cached_text_len = 0;
|
|
366
|
+
txt->empty = true;
|
|
367
|
+
txt->rendered_scale = scale;
|
|
368
|
+
obj_set_int(obj, id_width, 0);
|
|
369
|
+
obj_set_int(obj, id_height, new_height);
|
|
370
|
+
return true;
|
|
371
|
+
}
|
|
372
|
+
|
|
373
|
+
bool cached = false;
|
|
374
|
+
SDL_Surface *new_surface = R2D_TextSurfaceCacheGet(new_entry, msg, msg_len, &cached);
|
|
375
|
+
if (!new_surface) {
|
|
376
|
+
R2D_FontCacheRelease(new_entry);
|
|
377
|
+
return false;
|
|
378
|
+
}
|
|
379
|
+
|
|
380
|
+
char *new_cached_text = NULL;
|
|
381
|
+
if (cached) {
|
|
382
|
+
// Ownership of a cache-shared surface is tracked solely via cached_text. If
|
|
383
|
+
// the copy fails (OOM), keeping the surface would later SDL_DestroySurface a
|
|
384
|
+
// cache-owned handle (double-free), so release our refs and fail instead.
|
|
385
|
+
new_cached_text = R2D_TextDup(msg, msg_len);
|
|
386
|
+
if (!new_cached_text) {
|
|
387
|
+
R2D_TextSurfaceCacheRelease(new_entry, msg, msg_len);
|
|
388
|
+
R2D_FontCacheRelease(new_entry);
|
|
389
|
+
return false;
|
|
390
|
+
}
|
|
391
|
+
}
|
|
392
|
+
|
|
393
|
+
// --- All fallible steps succeeded: release the old, install the new --------
|
|
394
|
+
R2D_TextReleaseResources(txt);
|
|
395
|
+
#ifndef __EMSCRIPTEN__
|
|
396
|
+
// Native: destroy during the update phase, not at draw time — see the
|
|
397
|
+
// matching block in the empty-content path above.
|
|
398
|
+
if (txt->texture) {
|
|
399
|
+
if (R2D_RendererAlive()) SDL_DestroyTexture(txt->texture);
|
|
400
|
+
txt->texture = NULL;
|
|
401
|
+
}
|
|
402
|
+
#endif
|
|
403
|
+
txt->font_entry = new_entry;
|
|
404
|
+
txt->surface = new_surface;
|
|
405
|
+
txt->cached_text = new_cached_text;
|
|
406
|
+
txt->cached_text_len = new_cached_text ? msg_len : 0;
|
|
407
|
+
txt->texture_stale = true; // text_draw uploads the new surface
|
|
408
|
+
txt->empty = false;
|
|
409
|
+
txt->rendered_scale = scale;
|
|
410
|
+
|
|
411
|
+
/* The surface dimensions are in renderer pixels. To present sizes in
|
|
412
|
+
window/logical coordinates (so R2D_WindowToRendererCoordinatesRect()
|
|
413
|
+
scales them correctly on HiDPI displays), divide by the asset scale. */
|
|
414
|
+
int logical_w = (int) ((float)new_surface->w / scale);
|
|
415
|
+
int logical_h = (int) ((float)new_surface->h / scale);
|
|
416
|
+
obj_set_int(obj, id_width, logical_w);
|
|
417
|
+
obj_set_int(obj, id_height, logical_h);
|
|
418
|
+
|
|
419
|
+
return true;
|
|
420
|
+
}
|
|
421
|
+
|
|
422
|
+
|
|
423
|
+
/*
|
|
424
|
+
* Ruby2D::Text#ext_create
|
|
425
|
+
*/
|
|
426
|
+
R_VAL ruby2d_ext_text_create(RUBY2D_METHOD_ARGS_VARIADIC) {
|
|
427
|
+
RUBY2D_EXTRACT_VARIADIC;
|
|
428
|
+
if (argc != 1) r_raise("Ruby2D::Ext.text_create expects 1 arg (text), got %d", (int)argc);
|
|
429
|
+
R_VAL obj = argv[0];
|
|
430
|
+
// Ensure SDL subsystems are initialized (display_scale is set in R2D_Init)
|
|
431
|
+
if (!R2D_Init()) r_raise("Ruby2D: failed to initialize: %s", SDL_GetError());
|
|
432
|
+
|
|
433
|
+
// The font path's existence is validated Ruby-side in `normalize_font_path`
|
|
434
|
+
// before any `text_create` (construction and `font=` both route through it),
|
|
435
|
+
// so re-stating it here on every content=/size= reassignment would be a
|
|
436
|
+
// per-frame syscall for nothing (~one stat per Text per frame under a dynamic
|
|
437
|
+
// HUD). A font deleted at runtime between `font=` and a later create still
|
|
438
|
+
// fails cleanly below via `TTF_OpenFont` (the `font` name feeds that error).
|
|
439
|
+
const char *font = obj_str(obj, id_font);
|
|
440
|
+
|
|
441
|
+
// Reuse the existing struct if present (e.g. a content=/size= reassignment),
|
|
442
|
+
// otherwise allocate and initialize a fresh one. R2D_TextRasterize releases
|
|
443
|
+
// any old resources before building the new surface.
|
|
444
|
+
R2D_Text *txt = NULL;
|
|
445
|
+
bool is_new = false;
|
|
446
|
+
R_VAL existing = r_iv_get(obj, "@ext_text");
|
|
447
|
+
if (r_test(existing)) {
|
|
448
|
+
obj_struct(obj, id_ext_text, R2D_Text, txt);
|
|
449
|
+
}
|
|
450
|
+
if (!txt) {
|
|
451
|
+
txt = ALLOC(R2D_Text);
|
|
452
|
+
memset(txt, 0, sizeof(R2D_Text));
|
|
453
|
+
is_new = true;
|
|
454
|
+
}
|
|
455
|
+
|
|
456
|
+
if (!R2D_TextRasterize(obj, txt)) {
|
|
457
|
+
if (is_new) xfree(txt);
|
|
458
|
+
r_error("Failed to render text (font `%s`): %s", font, SDL_GetError());
|
|
459
|
+
return R_NIL;
|
|
460
|
+
}
|
|
461
|
+
|
|
462
|
+
// Only set the struct on the Ruby object if we allocated new
|
|
463
|
+
if (is_new) {
|
|
464
|
+
obj_set_struct(obj, id_ext_text, R2D_Text, txt);
|
|
465
|
+
}
|
|
466
|
+
|
|
467
|
+
return R_TRUE;
|
|
468
|
+
}
|
|
469
|
+
|
|
470
|
+
|
|
471
|
+
/*
|
|
472
|
+
* Ruby2D::Text#ext_draw
|
|
473
|
+
*/
|
|
474
|
+
R_VAL ruby2d_ext_text_draw(RUBY2D_METHOD_ARGS_VARIADIC) {
|
|
475
|
+
RUBY2D_EXTRACT_VARIADIC;
|
|
476
|
+
if (argc != 3) r_raise("Ruby2D::Ext.text_draw expects 3 args (text, rx, ry), got %d", (int)argc);
|
|
477
|
+
R_VAL obj = argv[0];
|
|
478
|
+
float crx = NUM2DBL(argv[1]);
|
|
479
|
+
float cry = NUM2DBL(argv[2]);
|
|
480
|
+
R2D_Text *txt;
|
|
481
|
+
obj_struct(obj, id_ext_text, R2D_Text, txt);
|
|
482
|
+
|
|
483
|
+
// Re-rasterize if the asset scale changed since the surface was built — e.g.
|
|
484
|
+
// the Text was created before the window opened (scale 1.0) and the window
|
|
485
|
+
// then opened on a HiDPI display without pixel_scale (scale = display_scale).
|
|
486
|
+
if (txt->rendered_scale != R2D_GetAssetScale()) {
|
|
487
|
+
if (!R2D_TextRasterize(obj, txt)) {
|
|
488
|
+
r_error("Failed to render text: %s", SDL_GetError());
|
|
489
|
+
return R_NIL;
|
|
490
|
+
}
|
|
491
|
+
}
|
|
492
|
+
|
|
493
|
+
if (txt->empty) return R_NIL; // empty content: nothing to draw
|
|
494
|
+
|
|
495
|
+
/* Refresh the GPU texture from the (re)rasterized surface. The strategy is
|
|
496
|
+
platform-split, and both arms were measured on the dynamic-text bench —
|
|
497
|
+
intuition points the wrong way on each side:
|
|
498
|
+
|
|
499
|
+
- Web (WebGL): a persistent grow-only texture updated in place. Fresh
|
|
500
|
+
glTexImage2D texture objects every frame churn the browser GPU
|
|
501
|
+
pipeline; switching to SDL_UpdateTexture cut the wasm render slice by
|
|
502
|
+
~60% (and SwiftShader understates the real-browser win).
|
|
503
|
+
- Native: destroy + SDL_CreateTextureFromSurface per change. Metal is
|
|
504
|
+
far faster at create-fresh than at updating a live texture — the
|
|
505
|
+
persistent path measured +75% frame cost (~18µs per SDL_UpdateTexture
|
|
506
|
+
across 360 texts/frame). */
|
|
507
|
+
if (txt->texture == NULL || txt->texture_stale) {
|
|
508
|
+
SDL_Surface *s = txt->surface;
|
|
509
|
+
#ifdef __EMSCRIPTEN__
|
|
510
|
+
if (txt->texture == NULL || s->w > txt->tex_w || s->h > txt->tex_h) {
|
|
511
|
+
int new_w = s->w > txt->tex_w ? s->w : txt->tex_w;
|
|
512
|
+
int new_h = s->h > txt->tex_h ? s->h : txt->tex_h;
|
|
513
|
+
if (txt->texture) SDL_DestroyTexture(txt->texture);
|
|
514
|
+
txt->texture = SDL_CreateTexture(R2D_GetRenderer(), SDL_PIXELFORMAT_RGBA32,
|
|
515
|
+
SDL_TEXTUREACCESS_STREAMING, new_w, new_h);
|
|
516
|
+
if (!txt->texture) {
|
|
517
|
+
txt->tex_w = 0;
|
|
518
|
+
txt->tex_h = 0;
|
|
519
|
+
r_raise("SDL_CreateTexture failed: %s", SDL_GetError());
|
|
520
|
+
return R_NIL;
|
|
521
|
+
}
|
|
522
|
+
SDL_SetTextureBlendMode(txt->texture, SDL_BLENDMODE_BLEND);
|
|
523
|
+
txt->tex_w = new_w;
|
|
524
|
+
txt->tex_h = new_h;
|
|
525
|
+
}
|
|
526
|
+
SDL_Rect upload_rect = { 0, 0, s->w, s->h };
|
|
527
|
+
R2D_CheckSDL(SDL_UpdateTexture(txt->texture, &upload_rect, s->pixels, s->pitch),
|
|
528
|
+
"SDL_UpdateTexture");
|
|
529
|
+
#else
|
|
530
|
+
// Rasterize already destroyed the old texture (update phase), so this is
|
|
531
|
+
// always a fresh create — the exact pre-persistent-texture flow.
|
|
532
|
+
if (txt->texture == NULL) {
|
|
533
|
+
txt->texture = SDL_CreateTextureFromSurface(R2D_GetRenderer(), s);
|
|
534
|
+
if (!txt->texture) {
|
|
535
|
+
r_raise("SDL_CreateTextureFromSurface failed: %s", SDL_GetError());
|
|
536
|
+
return R_NIL;
|
|
537
|
+
}
|
|
538
|
+
SDL_SetTextureBlendMode(txt->texture, SDL_BLENDMODE_BLEND);
|
|
539
|
+
}
|
|
540
|
+
#endif
|
|
541
|
+
txt->texture_stale = false;
|
|
542
|
+
// Keep surface alive for canvas blitting; R2D_Text_free handles cleanup
|
|
543
|
+
}
|
|
544
|
+
|
|
545
|
+
#ifdef __EMSCRIPTEN__
|
|
546
|
+
// The persistent texture's capacity can exceed the content — clip to it.
|
|
547
|
+
// Native textures are always content-sized, so NULL (whole texture) is
|
|
548
|
+
// equivalent and keeps that path identical to what was benchmarked.
|
|
549
|
+
SDL_FRect src_rect = { 0, 0, (float)txt->surface->w, (float)txt->surface->h };
|
|
550
|
+
const SDL_FRect *src = &src_rect;
|
|
551
|
+
#else
|
|
552
|
+
const SDL_FRect *src = NULL;
|
|
553
|
+
#endif
|
|
554
|
+
SDL_FRect dst_rect = {
|
|
555
|
+
obj_float(obj, id_x),
|
|
556
|
+
obj_float(obj, id_y),
|
|
557
|
+
obj_float(obj, id_width),
|
|
558
|
+
obj_float(obj, id_height)
|
|
559
|
+
};
|
|
560
|
+
|
|
561
|
+
R_VAL color_obj = r_ivar_get(obj, id_color);
|
|
562
|
+
SDL_SetTextureColorModFloat(txt->texture,
|
|
563
|
+
NUM2DBL(r_ivar_get(color_obj, id_r)),
|
|
564
|
+
NUM2DBL(r_ivar_get(color_obj, id_g)),
|
|
565
|
+
NUM2DBL(r_ivar_get(color_obj, id_b))
|
|
566
|
+
);
|
|
567
|
+
SDL_SetTextureAlphaModFloat(txt->texture, NUM2DBL(r_ivar_get(color_obj, id_a)));
|
|
568
|
+
|
|
569
|
+
SDL_FPoint center = {
|
|
570
|
+
crx - obj_float(obj, id_x),
|
|
571
|
+
cry - obj_float(obj, id_y)
|
|
572
|
+
};
|
|
573
|
+
|
|
574
|
+
R2D_CheckSDL(SDL_RenderTextureRotated(
|
|
575
|
+
R2D_GetRenderer(),
|
|
576
|
+
txt->texture,
|
|
577
|
+
src,
|
|
578
|
+
&dst_rect,
|
|
579
|
+
obj_float(obj, id_rotate),
|
|
580
|
+
¢er,
|
|
581
|
+
SDL_FLIP_NONE
|
|
582
|
+
), "SDL_RenderTextureRotated");
|
|
583
|
+
|
|
584
|
+
return R_TRUE;
|
|
585
|
+
}
|
|
586
|
+
|
|
587
|
+
|
|
588
|
+
/*
|
|
589
|
+
* Free the memory and resources associated with an R2D_Text object
|
|
590
|
+
*/
|
|
591
|
+
static void R2D_Text_free(void *p) {
|
|
592
|
+
if (!p) return;
|
|
593
|
+
R2D_Text *txt = (R2D_Text *)p;
|
|
594
|
+
R2D_TextReleaseResources(txt);
|
|
595
|
+
if (txt->texture) {
|
|
596
|
+
if (R2D_RendererAlive()) SDL_DestroyTexture(txt->texture);
|
|
597
|
+
txt->texture = NULL;
|
|
598
|
+
}
|
|
599
|
+
xfree(txt);
|
|
600
|
+
}
|