gosu 1.4.6 → 2.0.0.pre6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (170) hide show
  1. checksums.yaml +4 -4
  2. data/COPYING +2 -1
  3. data/dependencies/SDL/include/SDL_atomic.h +2 -3
  4. data/dependencies/SDL/include/SDL_audio.h +7 -7
  5. data/dependencies/SDL/include/SDL_blendmode.h +1 -1
  6. data/dependencies/SDL/include/SDL_endian.h +3 -3
  7. data/dependencies/SDL/include/SDL_gamecontroller.h +4 -4
  8. data/dependencies/SDL/include/SDL_hints.h +72 -28
  9. data/dependencies/SDL/include/SDL_joystick.h +8 -5
  10. data/dependencies/SDL/include/SDL_keycode.h +1 -1
  11. data/dependencies/SDL/include/SDL_main.h +7 -0
  12. data/dependencies/SDL/include/SDL_mouse.h +6 -7
  13. data/dependencies/SDL/include/SDL_mutex.h +79 -5
  14. data/dependencies/SDL/include/SDL_opengl_glext.h +5 -1
  15. data/dependencies/SDL/include/SDL_power.h +7 -8
  16. data/dependencies/SDL/include/SDL_render.h +5 -0
  17. data/dependencies/SDL/include/SDL_revision.h +2 -2
  18. data/dependencies/SDL/include/SDL_sensor.h +1 -1
  19. data/dependencies/SDL/include/SDL_stdinc.h +19 -11
  20. data/dependencies/SDL/include/SDL_thread.h +2 -2
  21. data/dependencies/SDL/include/SDL_version.h +2 -2
  22. data/dependencies/SDL/include/SDL_video.h +30 -2
  23. data/dependencies/SDL/include/begin_code.h +7 -7
  24. data/dependencies/SDL/include/close_code.h +2 -2
  25. data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
  26. data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
  27. data/dependencies/SDL_sound/SDL_sound.h +1 -1
  28. data/dependencies/SDL_sound/dr_flac.h +48 -23
  29. data/dependencies/SDL_sound/dr_mp3.h +34 -14
  30. data/dependencies/SDL_sound/stb_vorbis.h +3 -2
  31. data/dependencies/mojoAL/mojoal.c +1 -1
  32. data/ext/{gosu → gosu-ffi}/extconf.rb +34 -33
  33. data/ext/gosu-ffi/gosu-ffi.def +464 -0
  34. data/ffi/Gosu.cpp +307 -0
  35. data/ffi/Gosu.h +84 -0
  36. data/ffi/Gosu_Channel.cpp +62 -0
  37. data/ffi/Gosu_Channel.h +17 -0
  38. data/ffi/Gosu_Color.cpp +132 -0
  39. data/ffi/Gosu_Color.h +31 -0
  40. data/ffi/Gosu_Constants.cpp +334 -0
  41. data/ffi/Gosu_FFI.h +34 -0
  42. data/ffi/Gosu_FFI_internal.h +161 -0
  43. data/ffi/Gosu_Font.cpp +92 -0
  44. data/ffi/Gosu_Font.h +32 -0
  45. data/ffi/Gosu_Image.cpp +206 -0
  46. data/ffi/Gosu_Image.h +60 -0
  47. data/ffi/Gosu_Sample.cpp +29 -0
  48. data/ffi/Gosu_Sample.h +14 -0
  49. data/ffi/Gosu_Song.cpp +69 -0
  50. data/ffi/Gosu_Song.h +18 -0
  51. data/ffi/Gosu_TextInput.cpp +94 -0
  52. data/ffi/Gosu_TextInput.h +25 -0
  53. data/ffi/Gosu_Window.cpp +314 -0
  54. data/ffi/Gosu_Window.h +78 -0
  55. data/include/Gosu/Audio.hpp +6 -11
  56. data/include/Gosu/Bitmap.hpp +38 -53
  57. data/include/Gosu/Buffer.hpp +54 -0
  58. data/include/Gosu/Color.hpp +27 -35
  59. data/include/Gosu/Directories.hpp +25 -28
  60. data/include/Gosu/Drawable.hpp +58 -0
  61. data/include/Gosu/Font.hpp +6 -5
  62. data/include/Gosu/Fwd.hpp +4 -6
  63. data/include/Gosu/Gosu.hpp +5 -5
  64. data/include/Gosu/Graphics.hpp +51 -61
  65. data/include/Gosu/GraphicsBase.hpp +1 -11
  66. data/include/Gosu/Image.hpp +11 -14
  67. data/include/Gosu/Math.hpp +50 -72
  68. data/include/Gosu/Transform.hpp +32 -0
  69. data/include/Gosu/Utility.hpp +51 -1
  70. data/include/Gosu/Version.hpp +3 -3
  71. data/include/Gosu/Window.hpp +15 -9
  72. data/lib/SDL2.dll +0 -0
  73. data/lib/gosu/channel.rb +49 -0
  74. data/lib/gosu/color.rb +150 -0
  75. data/lib/gosu/compat.rb +29 -8
  76. data/lib/gosu/constants.rb +386 -0
  77. data/lib/gosu/ffi.rb +258 -0
  78. data/lib/gosu/font.rb +56 -0
  79. data/lib/gosu/gl_tex_info.rb +33 -0
  80. data/lib/gosu/gosu.rb +210 -0
  81. data/lib/gosu/image.rb +141 -0
  82. data/lib/gosu/numeric.rb +17 -0
  83. data/lib/gosu/preview.rb +6 -6
  84. data/lib/gosu/sample.rb +24 -0
  85. data/lib/gosu/song.rb +56 -0
  86. data/lib/gosu/text_input.rb +69 -0
  87. data/lib/gosu/window.rb +228 -0
  88. data/lib/gosu.rb +29 -8
  89. data/lib64/SDL2.dll +0 -0
  90. data/rdoc/gosu.rb +0 -2
  91. data/src/Audio.cpp +12 -12
  92. data/src/AudioFile.hpp +5 -4
  93. data/src/AudioFileAudioToolbox.cpp +8 -8
  94. data/src/AudioFileSDLSound.cpp +7 -10
  95. data/src/BinPacker.cpp +187 -0
  96. data/src/BinPacker.hpp +55 -0
  97. data/src/Bitmap.cpp +166 -144
  98. data/src/BitmapIO.cpp +60 -86
  99. data/src/Buffer.cpp +159 -0
  100. data/src/Color.cpp +75 -80
  101. data/src/Directories.cpp +47 -0
  102. data/src/DirectoriesUIKit.cpp +50 -0
  103. data/src/DrawOp.hpp +9 -4
  104. data/src/DrawOpQueue.hpp +2 -2
  105. data/src/Drawable.cpp +95 -0
  106. data/src/EmptyDrawable.hpp +38 -0
  107. data/src/FPS.cpp +31 -0
  108. data/src/Font.cpp +104 -74
  109. data/src/GosuGLView.cpp +14 -6
  110. data/src/GosuViewController.cpp +2 -10
  111. data/src/Graphics.cpp +60 -126
  112. data/src/GraphicsImpl.hpp +17 -47
  113. data/src/Image.cpp +41 -35
  114. data/src/Input.cpp +7 -8
  115. data/src/Macro.cpp +6 -6
  116. data/src/Macro.hpp +4 -4
  117. data/src/MarkupParser.cpp +5 -5
  118. data/src/Math.cpp +35 -22
  119. data/src/OffScreenTarget.cpp +53 -49
  120. data/src/OffScreenTarget.hpp +13 -11
  121. data/src/OpenGLContext.cpp +117 -0
  122. data/src/OpenGLContext.hpp +41 -0
  123. data/src/RenderState.hpp +21 -19
  124. data/src/Resolution.cpp +23 -21
  125. data/src/TexChunk.cpp +35 -80
  126. data/src/TexChunk.hpp +44 -35
  127. data/src/Text.cpp +1 -1
  128. data/src/TextBuilder.cpp +35 -21
  129. data/src/TextBuilder.hpp +6 -9
  130. data/src/Texture.cpp +62 -80
  131. data/src/Texture.hpp +25 -23
  132. data/src/TiledDrawable.cpp +150 -0
  133. data/src/TiledDrawable.hpp +47 -0
  134. data/src/TimingApple.cpp +1 -1
  135. data/src/Transform.cpp +45 -50
  136. data/src/TransformStack.hpp +16 -16
  137. data/src/TrueTypeFont.cpp +59 -51
  138. data/src/TrueTypeFont.hpp +6 -7
  139. data/src/TrueTypeFontApple.cpp +28 -19
  140. data/src/TrueTypeFontUnix.cpp +27 -23
  141. data/src/TrueTypeFontWin.cpp +30 -30
  142. data/src/Utility.cpp +84 -21
  143. data/src/UtilityWin.cpp +45 -0
  144. data/src/Window.cpp +92 -142
  145. data/src/WindowUIKit.cpp +14 -14
  146. metadata +72 -31
  147. data/include/Gosu/IO.hpp +0 -254
  148. data/include/Gosu/ImageData.hpp +0 -53
  149. data/include/Gosu/Inspection.hpp +0 -7
  150. data/lib/gosu/patches.rb +0 -66
  151. data/lib/gosu/run.rb +0 -20
  152. data/lib/gosu/swig_patches.rb +0 -110
  153. data/src/BlockAllocator.cpp +0 -131
  154. data/src/BlockAllocator.hpp +0 -32
  155. data/src/DirectoriesApple.cpp +0 -69
  156. data/src/DirectoriesUnix.cpp +0 -46
  157. data/src/DirectoriesWin.cpp +0 -65
  158. data/src/EmptyImageData.hpp +0 -52
  159. data/src/FileUnix.cpp +0 -99
  160. data/src/FileWin.cpp +0 -88
  161. data/src/IO.cpp +0 -60
  162. data/src/Iconv.hpp +0 -51
  163. data/src/Inspection.cpp +0 -27
  164. data/src/LargeImageData.cpp +0 -215
  165. data/src/LargeImageData.hpp +0 -39
  166. data/src/Log.hpp +0 -19
  167. data/src/RubyGosu.cxx +0 -13100
  168. data/src/RubyGosu.h +0 -49
  169. data/src/WinUtility.cpp +0 -61
  170. data/src/WinUtility.hpp +0 -27
data/src/RenderState.hpp CHANGED
@@ -1,6 +1,8 @@
1
1
  #pragma once
2
2
 
3
+ #include <Gosu/Transform.hpp>
3
4
  #include "GraphicsImpl.hpp"
5
+ #include "OpenGLContext.hpp"
4
6
  #include "Texture.hpp"
5
7
 
6
8
  // Properties that potentially need to be changed between each draw operation.
@@ -11,13 +13,13 @@ struct Gosu::RenderState
11
13
  const Transform* transform;
12
14
  ClipRect clip_rect;
13
15
  BlendMode mode;
14
-
16
+
15
17
  RenderState()
16
18
  : transform(0), mode(BM_DEFAULT)
17
19
  {
18
20
  clip_rect.width = NO_CLIPPING;
19
21
  }
20
-
22
+
21
23
  bool operator==(const RenderState& rhs) const
22
24
  {
23
25
  return texture == rhs.texture &&
@@ -25,7 +27,7 @@ struct Gosu::RenderState
25
27
  clip_rect == rhs.clip_rect &&
26
28
  mode == rhs.mode;
27
29
  }
28
-
30
+
29
31
  void apply_texture() const
30
32
  {
31
33
  if (texture) {
@@ -36,7 +38,7 @@ struct Gosu::RenderState
36
38
  glDisable(GL_TEXTURE_2D);
37
39
  }
38
40
  }
39
-
41
+
40
42
  void apply_alpha_mode() const
41
43
  {
42
44
  if (mode == BM_ADD) {
@@ -49,7 +51,7 @@ struct Gosu::RenderState
49
51
  glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
50
52
  }
51
53
  }
52
-
54
+
53
55
  void apply_clip_rect() const
54
56
  {
55
57
  if (clip_rect.width == NO_CLIPPING) {
@@ -60,7 +62,7 @@ struct Gosu::RenderState
60
62
  glScissor(clip_rect.x, clip_rect.y, clip_rect.width, clip_rect.height);
61
63
  }
62
64
  }
63
-
65
+
64
66
  // Only used by Macro so far
65
67
  #ifndef GOSU_IS_OPENGLES
66
68
  void apply() const
@@ -79,24 +81,24 @@ class Gosu::RenderStateManager : private Gosu::RenderState
79
81
  // Not copyable
80
82
  RenderStateManager(const RenderStateManager&);
81
83
  RenderStateManager& operator=(const RenderStateManager&);
82
-
84
+
83
85
  void apply_transform() const
84
86
  {
85
87
  glMatrixMode(GL_MODELVIEW);
86
88
  glLoadIdentity();
87
-
89
+
88
90
  #ifndef GOSU_IS_OPENGLES
89
- glMultMatrixd(&(*transform)[0]);
91
+ glMultMatrixd(transform->matrix.data());
90
92
  #else
91
93
  // TODO: Ouch, should always use floats!
92
94
  GLfloat matrix[16];
93
95
  for (int i = 0; i < 16; ++i) {
94
- matrix[i] = (*transform)[i];
96
+ matrix[i] = transform->matrix[i];
95
97
  }
96
98
  glMultMatrixf(matrix);
97
99
  #endif
98
100
  }
99
-
101
+
100
102
  public:
101
103
  RenderStateManager()
102
104
  {
@@ -105,7 +107,7 @@ public:
105
107
  glMatrixMode(GL_MODELVIEW);
106
108
  glPushMatrix();
107
109
  }
108
-
110
+
109
111
  ~RenderStateManager()
110
112
  {
111
113
  ClipRect no_clipping;
@@ -116,7 +118,7 @@ public:
116
118
  glMatrixMode(GL_MODELVIEW);
117
119
  glPopMatrix();
118
120
  }
119
-
121
+
120
122
  void set_render_state(const RenderState& rs)
121
123
  {
122
124
  set_texture(rs.texture);
@@ -124,7 +126,7 @@ public:
124
126
  set_clip_rect(rs.clip_rect);
125
127
  set_alpha_mode(rs.mode);
126
128
  }
127
-
129
+
128
130
  void set_texture(std::shared_ptr<Texture> new_texture)
129
131
  {
130
132
  if (new_texture == texture) return;
@@ -141,11 +143,11 @@ public:
141
143
  }
142
144
  texture = new_texture;
143
145
  }
144
-
146
+
145
147
  void set_transform(const Transform* new_transform)
146
148
  {
147
149
  if (new_transform == transform) return;
148
-
150
+
149
151
  transform = new_transform;
150
152
  apply_transform();
151
153
  }
@@ -173,15 +175,15 @@ public:
173
175
  }
174
176
  }
175
177
  }
176
-
178
+
177
179
  void set_alpha_mode(BlendMode new_mode)
178
180
  {
179
181
  if (new_mode == mode) return;
180
-
182
+
181
183
  mode = new_mode;
182
184
  apply_alpha_mode();
183
185
  }
184
-
186
+
185
187
  // The cached values may have been messed with. Reset them again.
186
188
  void enforce_after_untrusted_gL() const
187
189
  {
data/src/Resolution.cpp CHANGED
@@ -1,30 +1,30 @@
1
1
  #include <Gosu/Platform.hpp>
2
- #ifndef GOSU_IS_IPHONE // iPhone definitions live in WindowUIKit.cpp
2
+ #ifndef GOSU_IS_IPHONE // Definitions for iOS live in WindowUIKit.cpp
3
3
 
4
4
  #include <Gosu/Window.hpp>
5
5
  #include "GraphicsImpl.hpp"
6
6
  #include <SDL.h>
7
7
 
8
- static SDL_DisplayMode display_mode(Gosu::Window* window)
8
+ static SDL_DisplayMode display_mode(const Gosu::Window* window)
9
9
  {
10
- static struct VideoSubsystem
10
+ static const struct VideoSubsystem : Gosu::Noncopyable
11
11
  {
12
12
  VideoSubsystem() { SDL_InitSubSystem(SDL_INIT_VIDEO); };
13
13
  ~VideoSubsystem() { SDL_QuitSubSystem(SDL_INIT_VIDEO); };
14
14
  } subsystem;
15
15
 
16
- int index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
16
+ int index = window ? SDL_GetWindowDisplayIndex(window->sdl_window()) : 0;
17
17
  SDL_DisplayMode result;
18
18
  SDL_GetDesktopDisplayMode(index, &result);
19
19
  return result;
20
20
  }
21
21
 
22
- int Gosu::screen_width(Window* window)
22
+ int Gosu::screen_width(const Window* window)
23
23
  {
24
24
  return display_mode(window).w;
25
25
  }
26
26
 
27
- int Gosu::screen_height(Window* window)
27
+ int Gosu::screen_height(const Window* window)
28
28
  {
29
29
  return display_mode(window).h;
30
30
  }
@@ -32,7 +32,7 @@ int Gosu::screen_height(Window* window)
32
32
  #ifdef GOSU_IS_MAC
33
33
  #import <AppKit/AppKit.h>
34
34
 
35
- static SDL_Rect max_window_size(Gosu::Window* window)
35
+ static SDL_Rect max_window_size(const Gosu::Window* window)
36
36
  {
37
37
  // The extra size that a window needs depends on its style.
38
38
  // This logic must be kept in sync with SDL_cocoawindow.m to be 100% accurate.
@@ -48,7 +48,7 @@ static SDL_Rect max_window_size(Gosu::Window* window)
48
48
  style |= NSWindowStyleMaskResizable;
49
49
  }
50
50
 
51
- auto index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
51
+ auto index = window ? SDL_GetWindowDisplayIndex(window->sdl_window()) : 0;
52
52
  NSRect screen_frame = NSScreen.screens[index].visibleFrame;
53
53
  NSRect content_rect = [NSWindow contentRectForFrameRect:screen_frame styleMask:style];
54
54
 
@@ -68,26 +68,26 @@ static SDL_Rect max_window_size(Gosu::Window* window)
68
68
  #include <windows.h>
69
69
  #pragma comment(lib, "Dwmapi.lib")
70
70
 
71
- static SDL_Rect max_window_size(Gosu::Window* window)
71
+ static SDL_Rect max_window_size(const Gosu::Window* window)
72
72
  {
73
73
  // Replicate SDL's WIN_GetWindowBordersSize implementation (https://github.com/libsdl-org/SDL/blob/9f71a809e9bd6fbb5fa401a45c1537fc26abc1b4/src/video/windows/SDL_windowswindow.c#L514-L554)
74
74
  // until it's patched to ignore the window drop shadow (window border is 1px but with drop shadow it's reported as 8px)
75
75
  // REF: https://github.com/libsdl-org/SDL/issues/3835
76
76
 
77
- static struct VideoSubsystem
77
+ static const struct VideoSubsystem : Gosu::Noncopyable
78
78
  {
79
79
  VideoSubsystem() { SDL_InitSubSystem(SDL_INIT_VIDEO); };
80
80
  ~VideoSubsystem() { SDL_QuitSubSystem(SDL_INIT_VIDEO); };
81
81
  } subsystem;
82
82
 
83
- int index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
83
+ int index = window ? SDL_GetWindowDisplayIndex(window->sdl_window()) : 0;
84
84
  SDL_Rect rect;
85
85
  SDL_GetDisplayUsableBounds(index, &rect);
86
86
 
87
87
  if (window) {
88
88
  SDL_SysWMinfo info;
89
89
  SDL_VERSION(&info.version);
90
- SDL_GetWindowWMInfo(Gosu::shared_window(), &info);
90
+ SDL_GetWindowWMInfo(window->sdl_window(), &info);
91
91
  HWND hwnd = info.info.win.window;
92
92
 
93
93
  RECT rcClient, rcWindow;
@@ -137,33 +137,35 @@ static SDL_Rect max_window_size(Gosu::Window* window)
137
137
  #endif
138
138
 
139
139
  #ifdef GOSU_IS_X
140
- static SDL_Rect max_window_size(Gosu::Window* window)
140
+ static SDL_Rect max_window_size(const Gosu::Window* window)
141
141
  {
142
- static struct VideoSubsystem
142
+ static const struct VideoSubsystem : Gosu::Noncopyable
143
143
  {
144
144
  VideoSubsystem() { SDL_InitSubSystem(SDL_INIT_VIDEO); };
145
145
  ~VideoSubsystem() { SDL_QuitSubSystem(SDL_INIT_VIDEO); };
146
146
  } subsystem;
147
147
 
148
- int index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
148
+ int index = window ? SDL_GetWindowDisplayIndex(window->sdl_window()) : 0;
149
149
  SDL_Rect rect;
150
- int top, left, bottom, right;
151
150
  SDL_GetDisplayUsableBounds(index, &rect);
152
- SDL_GetWindowBordersSize(Gosu::shared_window(), &top, &left, &bottom, &right);
153
151
 
154
- rect.w -= left + right;
155
- rect.h -= top + bottom;
152
+ if (window) {
153
+ int top, left, bottom, right;
154
+ SDL_GetWindowBordersSize(window->sdl_window(), &top, &left, &bottom, &right);
155
+ rect.w -= left + right;
156
+ rect.h -= top + bottom;
157
+ }
156
158
 
157
159
  return rect;
158
160
  }
159
161
  #endif
160
162
 
161
- int Gosu::available_width(Window* window)
163
+ int Gosu::available_width(const Window* window)
162
164
  {
163
165
  return max_window_size(window).w;
164
166
  }
165
167
 
166
- int Gosu::available_height(Window* window)
168
+ int Gosu::available_height(const Window* window)
167
169
  {
168
170
  return max_window_size(window).h;
169
171
  }
data/src/TexChunk.cpp CHANGED
@@ -5,50 +5,20 @@
5
5
  #include "Texture.hpp"
6
6
  #include <stdexcept>
7
7
 
8
- void Gosu::TexChunk::set_tex_info()
8
+ Gosu::TexChunk::TexChunk(const std::shared_ptr<Texture>& texture, const Rect& rect,
9
+ const std::shared_ptr<const Rect>& rect_handle)
10
+ : m_texture(texture),
11
+ m_rect(rect),
12
+ m_info { .tex_name = texture->tex_name(),
13
+ .left = 1.0 * m_rect.x / texture->width(),
14
+ .right = 1.0 * m_rect.right() / texture->width(),
15
+ .top = 1.0 * m_rect.y / texture->height(),
16
+ .bottom = 1.0 * m_rect.bottom() / texture->height() },
17
+ m_rect_handle(rect_handle)
9
18
  {
10
- double width = m_texture->width(), height = m_texture->height();
11
-
12
- m_info.tex_name = m_texture->tex_name();
13
- m_info.left = m_x / width;
14
- m_info.top = m_y / height;
15
- m_info.right = (m_x + m_w) / width;
16
- m_info.bottom = (m_y + m_h) / height;
17
- }
18
-
19
- Gosu::TexChunk::TexChunk(std::shared_ptr<Texture> texture, int x, int y, int w, int h, int padding)
20
- : m_texture{move(texture)},
21
- m_x{x},
22
- m_y{y},
23
- m_w{w},
24
- m_h{h},
25
- m_padding{padding}
26
- {
27
- set_tex_info();
28
- }
29
-
30
- Gosu::TexChunk::TexChunk(const TexChunk& parent, int x, int y, int w, int h)
31
- : m_texture{parent.m_texture},
32
- m_x{parent.m_x + x},
33
- m_y{parent.m_y + y},
34
- m_w{w},
35
- m_h{h},
36
- m_padding{0}
37
- {
38
- if (x < 0 || y < 0 || x + w > parent.m_w || y + h > parent.m_h) {
39
- throw std::invalid_argument{"subimage bounds exceed those of its parent"};
19
+ if (!Rect::covering(*texture).contains(rect)) {
20
+ throw std::invalid_argument("Gosu::TexChunk exceeds its Gosu::Texture");
40
21
  }
41
- if (w <= 0 || h <= 0) {
42
- throw std::invalid_argument{"cannot create empty image"};
43
- }
44
-
45
- set_tex_info();
46
- m_texture->block(m_x, m_y, m_w, m_h);
47
- }
48
-
49
- Gosu::TexChunk::~TexChunk()
50
- {
51
- m_texture->free(m_x - m_padding, m_y - m_padding, m_w + 2 * m_padding, m_h + 2 * m_padding);
52
22
  }
53
23
 
54
24
  void Gosu::TexChunk::draw(double x1, double y1, Color c1, double x2, double y2, Color c2, //
@@ -59,6 +29,8 @@ void Gosu::TexChunk::draw(double x1, double y1, Color c1, double x2, double y2,
59
29
  op.render_state.texture = m_texture;
60
30
  op.render_state.mode = mode;
61
31
 
32
+ op.rect_handle = m_rect_handle;
33
+
62
34
  normalize_coordinates(x1, y1, x2, y2, x3, y3, c3, x4, y4, c4);
63
35
 
64
36
  op.vertices_or_block_index = 4;
@@ -78,62 +50,45 @@ void Gosu::TexChunk::draw(double x1, double y1, Color c1, double x2, double y2,
78
50
  op.bottom = m_info.bottom;
79
51
 
80
52
  op.z = z;
81
- Graphics::schedule_draw_op(op);
53
+ schedule_draw_op(op);
82
54
  }
83
55
 
84
- std::unique_ptr<Gosu::ImageData> Gosu::TexChunk::subimage(int x, int y, int width, int height) const
56
+ std::unique_ptr<Gosu::Drawable> Gosu::TexChunk::subimage(const Rect& rect) const
85
57
  {
86
- return std::unique_ptr<Gosu::ImageData>(new TexChunk(*this, x, y, width, height));
58
+ // Note: m_rect is relative to m_texture, but rect should be relative to m_rect.
59
+ if (!Rect::covering(*this).contains(rect)) {
60
+ throw std::invalid_argument("Gosu::TexChunk::subimage cannot exceed parent size");
61
+ }
62
+ const Rect nested_rect { m_rect.x + rect.x, m_rect.y + rect.y, rect.width, rect.height };
63
+ return std::make_unique<TexChunk>(m_texture, nested_rect, m_rect_handle);
87
64
  }
88
65
 
89
66
  Gosu::Bitmap Gosu::TexChunk::to_bitmap() const
90
67
  {
91
- return m_texture->to_bitmap(m_x, m_y, m_w, m_h);
68
+ return m_texture->to_bitmap(m_rect);
92
69
  }
93
70
 
94
- void Gosu::TexChunk::insert(const Bitmap& original_bitmap, int x, int y)
71
+ void Gosu::TexChunk::insert(const Bitmap& bitmap, int x, int y)
95
72
  {
96
73
  Bitmap clipped_bitmap;
97
- const Bitmap* bitmap = &original_bitmap;
74
+ const Bitmap* source = &bitmap;
98
75
 
76
+ Rect target_rect { x, y, bitmap.width(), bitmap.height() };
77
+ int offset_x = 0, offset_y = 0;
99
78
  // If inserting the bitmap at the given position exceeds the boundaries of the space allocated
100
79
  // for this image on the texture, we need to clip the bitmap and insert the clipped version
101
80
  // instead.
102
- if (x < 0 || y < 0 || x + original_bitmap.width() > m_w || y + original_bitmap.height() > m_h) {
103
- // How many pixels to remove at the top and left sides.
104
- int clip_left = 0, clip_top = 0;
105
- // How large the clipped version needs to be.
106
- int clipped_width = original_bitmap.width(), clipped_height = original_bitmap.height();
81
+ if (!Rect::covering(*this).contains(target_rect)) {
82
+ target_rect.clip_to(Rect::covering(*this), &offset_x, &offset_y);
107
83
 
108
- // Clip away pixels on the left side, if necessary.
109
- if (x < 0) {
110
- clip_left = -x;
111
- clipped_width -= -x;
112
- x = 0;
84
+ if (target_rect.empty()) {
85
+ return;
113
86
  }
114
- // Clip away pixels at the top, if necessary.
115
- if (y < 0) {
116
- clip_top = -y;
117
- clipped_height -= -y;
118
- y = 0;
119
- }
120
- // Clip away pixels on the right side, if necessary.
121
- if (x + clipped_width > m_w) {
122
- clipped_width = (m_w - x);
123
- }
124
- // Clip away pixels on the bottom, if necessary.
125
- if (y + clipped_height > m_h) {
126
- clipped_height = (m_h - y);
127
- }
128
-
129
- if (clipped_width <= 0 || clipped_height <= 0) return;
130
87
 
131
- clipped_bitmap.resize(clipped_width, clipped_height);
132
- clipped_bitmap.insert(-clip_left, -clip_top, original_bitmap);
133
- bitmap = &clipped_bitmap;
88
+ clipped_bitmap.resize(target_rect.width, target_rect.height);
89
+ clipped_bitmap.insert(bitmap, -offset_x, -offset_y);
90
+ source = &clipped_bitmap;
134
91
  }
135
92
 
136
- glBindTexture(GL_TEXTURE_2D, tex_name());
137
- glTexSubImage2D(GL_TEXTURE_2D, 0, m_x + x, m_y + y, bitmap->width(), bitmap->height(),
138
- Color::GL_FORMAT, GL_UNSIGNED_BYTE, bitmap->data());
93
+ m_texture->insert(*source, m_rect.x + x + offset_x, m_rect.y + y + offset_y);
139
94
  }
data/src/TexChunk.hpp CHANGED
@@ -1,41 +1,50 @@
1
1
  #pragma once
2
2
 
3
3
  #include <Gosu/Fwd.hpp>
4
- #include <Gosu/ImageData.hpp>
5
- #include "GraphicsImpl.hpp"
4
+ #include <Gosu/Drawable.hpp>
5
+ #include <Gosu/Utility.hpp>
6
+ #include <cstdint>
6
7
  #include <memory>
7
- #include <stdexcept>
8
8
 
9
- class Gosu::TexChunk : public Gosu::ImageData
9
+ namespace Gosu
10
10
  {
11
- std::shared_ptr<Texture> m_texture;
12
- int m_x, m_y, m_w, m_h, m_padding;
13
-
14
- GLTexInfo m_info;
15
-
16
- void set_tex_info();
17
-
18
- public:
19
- TexChunk(std::shared_ptr<Texture> texture, int x, int y, int w, int h, int padding);
20
- TexChunk(const TexChunk& parent, int x, int y, int w, int h);
21
- ~TexChunk() override;
22
-
23
- int width() const override { return m_w; }
24
- int height() const override { return m_h; }
25
-
26
- GLuint tex_name() const { return m_info.tex_name; }
27
-
28
- void draw(double x1, double y1, Color c1, //
29
- double x2, double y2, Color c2, //
30
- double x3, double y3, Color c3, //
31
- double x4, double y4, Color c4, //
32
- ZPos z, BlendMode mode) const override;
33
-
34
- const GLTexInfo* gl_tex_info() const override { return &m_info; }
35
-
36
- std::unique_ptr<ImageData> subimage(int x, int y, int width, int height) const override;
37
-
38
- Gosu::Bitmap to_bitmap() const override;
39
-
40
- void insert(const Bitmap& bitmap, int x, int y) override;
41
- };
11
+ class Texture;
12
+
13
+ /// The most common Drawable implementation which uses a portion of, or a full, OpenGL texture
14
+ /// to store image data.
15
+ class TexChunk : public Drawable
16
+ {
17
+ const std::shared_ptr<Texture> m_texture;
18
+ const Rect m_rect;
19
+ const GLTexInfo m_info;
20
+ const std::shared_ptr<const Rect> m_rect_handle;
21
+
22
+ public:
23
+ /// @param texture The texture on which the image data resides.
24
+ /// @param rect The portion of the texture that will be represented by this TexChunk.
25
+ /// This excludes any padding pixels.
26
+ /// @param rect_handle A shared_ptr that references the full rectangle that was allocated
27
+ /// for this TexChunk, including padding. When this TexChunk and all
28
+ /// of its subimages have been deleted, this rectangle will be reclaimed
29
+ /// for use by other image data.
30
+ TexChunk(const std::shared_ptr<Texture>& texture, const Rect& rect,
31
+ const std::shared_ptr<const Rect>& rect_handle);
32
+
33
+ int width() const override { return m_rect.width; }
34
+ int height() const override { return m_rect.height; }
35
+
36
+ void draw(double x1, double y1, Color c1, //
37
+ double x2, double y2, Color c2, //
38
+ double x3, double y3, Color c3, //
39
+ double x4, double y4, Color c4, //
40
+ ZPos z, BlendMode mode) const override;
41
+
42
+ const GLTexInfo* gl_tex_info() const override { return &m_info; }
43
+
44
+ std::unique_ptr<Drawable> subimage(const Rect& rect) const override;
45
+
46
+ Bitmap to_bitmap() const override;
47
+
48
+ void insert(const Bitmap& bitmap, int x, int y) override;
49
+ };
50
+ }
data/src/Text.cpp CHANGED
@@ -52,7 +52,7 @@ Gosu::Bitmap Gosu::layout_markup(const std::string& markup, const std::string& f
52
52
  // Feed all formatted substrings to the TextBuilder, which will construct the result.
53
53
  // Split the input string into words, because this method implements word-wrapping.
54
54
  MarkupParser parser{font_flags, true, [&text_builder](std::vector<FormattedString> word) {
55
- text_builder.feed_word(move(word));
55
+ text_builder.feed_word(std::move(word));
56
56
  }};
57
57
  parser.parse(markup);
58
58
 
data/src/TextBuilder.cpp CHANGED
@@ -8,16 +8,20 @@ Gosu::WordInfo::WordInfo(const std::string& font_name, double font_height,
8
8
  std::vector<FormattedString> parts)
9
9
  {
10
10
  assert(!parts.empty());
11
+ assert(!parts[0].text.empty());
11
12
 
12
- const auto* properties = utf8proc_get_property(parts.front().text.front());
13
+ const auto first_character = static_cast<utf8proc_int32_t>(parts.front().text.front());
14
+ const auto* properties = utf8proc_get_property(first_character);
13
15
 
14
16
  // Also check the BiDi class to filter out non-breaking spaces.
15
- is_whitespace = properties->category == UTF8PROC_CATEGORY_ZS &&
16
- properties->bidi_class == UTF8PROC_BIDI_CLASS_WS;
17
+ is_whitespace = properties->category == UTF8PROC_CATEGORY_ZS
18
+ && properties->bidi_class == UTF8PROC_BIDI_CLASS_WS;
17
19
 
18
20
  is_end_of_line = parts.back().text.back() == '\n';
19
21
  // Remove the trailing backspace character to avoid errors from Gosu::text_width().
20
- if (is_end_of_line) parts.back().text.pop_back();
22
+ if (is_end_of_line) {
23
+ parts.back().text.pop_back();
24
+ }
21
25
 
22
26
  width = 0;
23
27
  for (const auto& part : parts) {
@@ -26,20 +30,31 @@ Gosu::WordInfo::WordInfo(const std::string& font_name, double font_height,
26
30
  width += text_width(part.text, font_name, font_height, part.flags);
27
31
  }
28
32
 
29
- this->parts = move(parts);
33
+ this->parts = std::move(parts);
30
34
  }
31
35
 
36
+ enum Gosu::TextBuilder::EndOfLineReason : int
37
+ {
38
+ LINE_TOO_LONG,
39
+ END_OF_PARAGRAPH,
40
+ END_OF_TEXT
41
+ };
42
+
32
43
  void Gosu::TextBuilder::flush_current_line(EndOfLineReason reason)
33
44
  {
34
45
  if (m_current_line.empty()) {
35
- if (reason == END_OF_PARAGRAPH) allocate_next_line();
46
+ if (reason == END_OF_PARAGRAPH) {
47
+ allocate_next_line();
48
+ }
36
49
  return;
37
50
  }
38
51
 
39
52
  allocate_next_line();
40
53
 
41
54
  // Remove trailing whitespace so that justifying the text across the line works.
42
- if (m_current_line.back().is_whitespace) m_current_line.pop_back();
55
+ if (m_current_line.back().is_whitespace) {
56
+ m_current_line.pop_back();
57
+ }
43
58
 
44
59
  // Shouldn't happen because the first word on a line should never be whitespace.
45
60
  assert(!m_current_line.empty());
@@ -84,26 +99,26 @@ void Gosu::TextBuilder::flush_current_line(EndOfLineReason reason)
84
99
  void Gosu::TextBuilder::allocate_next_line()
85
100
  {
86
101
  if (m_used_lines == m_allocated_lines) {
87
- m_allocated_lines += 10;
88
- resize_to_allocated_lines();
102
+ reallocate(m_allocated_lines += 10);
89
103
  }
90
104
 
91
105
  ++m_used_lines;
92
106
  }
93
107
 
94
- void Gosu::TextBuilder::resize_to_allocated_lines()
108
+ void Gosu::TextBuilder::reallocate(int lines)
95
109
  {
96
- double new_height =
97
- m_font_height * m_allocated_lines + m_line_spacing * std::max(0, m_allocated_lines - 1);
98
- m_result.resize(m_result.width(), ceil(new_height));
110
+ m_allocated_lines = lines;
111
+ double new_height
112
+ = m_font_height * m_allocated_lines + m_line_spacing * std::max(0, m_allocated_lines - 1);
113
+ m_result.resize(m_result.width(), std::ceil(new_height));
99
114
  }
100
115
 
101
116
  Gosu::TextBuilder::TextBuilder(const std::string& font_name, int font_height, int line_spacing,
102
117
  int width, Alignment align)
103
- : m_font_name{font_name},
104
- m_font_height{font_height * 1.0},
105
- m_line_spacing{line_spacing * 1.0},
106
- m_align{align}
118
+ : m_font_name(font_name),
119
+ m_font_height(font_height * 1.0),
120
+ m_line_spacing(line_spacing * 1.0),
121
+ m_align(align)
107
122
  {
108
123
  // This class uses result.width() to remember its destination width, so store it in there.
109
124
  m_result.resize(width, 0);
@@ -114,14 +129,13 @@ Gosu::Bitmap Gosu::TextBuilder::move_into_bitmap() &&
114
129
  flush_current_line(END_OF_TEXT);
115
130
 
116
131
  // Shrink to fit the currently used height.
117
- m_allocated_lines = m_used_lines;
118
- resize_to_allocated_lines();
132
+ reallocate(m_used_lines);
119
133
  return std::move(m_result);
120
134
  }
121
135
 
122
- void Gosu::TextBuilder::feed_word(std::vector<FormattedString>&& word)
136
+ void Gosu::TextBuilder::feed_word(std::vector<FormattedString> word)
123
137
  {
124
- WordInfo new_word(m_font_name, m_font_height, word);
138
+ WordInfo new_word(m_font_name, m_font_height, std::move(word));
125
139
 
126
140
  if (m_current_line_width + new_word.width > m_result.width()) {
127
141
  // Can't fit it on the same line as before, so flush the last line before adding the word to