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.
- checksums.yaml +4 -4
- data/COPYING +2 -1
- data/dependencies/SDL/include/SDL_atomic.h +2 -3
- data/dependencies/SDL/include/SDL_audio.h +7 -7
- data/dependencies/SDL/include/SDL_blendmode.h +1 -1
- data/dependencies/SDL/include/SDL_endian.h +3 -3
- data/dependencies/SDL/include/SDL_gamecontroller.h +4 -4
- data/dependencies/SDL/include/SDL_hints.h +72 -28
- data/dependencies/SDL/include/SDL_joystick.h +8 -5
- data/dependencies/SDL/include/SDL_keycode.h +1 -1
- data/dependencies/SDL/include/SDL_main.h +7 -0
- data/dependencies/SDL/include/SDL_mouse.h +6 -7
- data/dependencies/SDL/include/SDL_mutex.h +79 -5
- data/dependencies/SDL/include/SDL_opengl_glext.h +5 -1
- data/dependencies/SDL/include/SDL_power.h +7 -8
- data/dependencies/SDL/include/SDL_render.h +5 -0
- data/dependencies/SDL/include/SDL_revision.h +2 -2
- data/dependencies/SDL/include/SDL_sensor.h +1 -1
- data/dependencies/SDL/include/SDL_stdinc.h +19 -11
- data/dependencies/SDL/include/SDL_thread.h +2 -2
- data/dependencies/SDL/include/SDL_version.h +2 -2
- data/dependencies/SDL/include/SDL_video.h +30 -2
- data/dependencies/SDL/include/begin_code.h +7 -7
- data/dependencies/SDL/include/close_code.h +2 -2
- data/dependencies/SDL/lib/x64/libSDL2.dll.a +0 -0
- data/dependencies/SDL/lib/x86/libSDL2.dll.a +0 -0
- data/dependencies/SDL_sound/SDL_sound.h +1 -1
- data/dependencies/SDL_sound/dr_flac.h +48 -23
- data/dependencies/SDL_sound/dr_mp3.h +34 -14
- data/dependencies/SDL_sound/stb_vorbis.h +3 -2
- data/dependencies/mojoAL/mojoal.c +1 -1
- data/ext/{gosu → gosu-ffi}/extconf.rb +34 -33
- data/ext/gosu-ffi/gosu-ffi.def +464 -0
- data/ffi/Gosu.cpp +307 -0
- data/ffi/Gosu.h +84 -0
- data/ffi/Gosu_Channel.cpp +62 -0
- data/ffi/Gosu_Channel.h +17 -0
- data/ffi/Gosu_Color.cpp +132 -0
- data/ffi/Gosu_Color.h +31 -0
- data/ffi/Gosu_Constants.cpp +334 -0
- data/ffi/Gosu_FFI.h +34 -0
- data/ffi/Gosu_FFI_internal.h +161 -0
- data/ffi/Gosu_Font.cpp +92 -0
- data/ffi/Gosu_Font.h +32 -0
- data/ffi/Gosu_Image.cpp +206 -0
- data/ffi/Gosu_Image.h +60 -0
- data/ffi/Gosu_Sample.cpp +29 -0
- data/ffi/Gosu_Sample.h +14 -0
- data/ffi/Gosu_Song.cpp +69 -0
- data/ffi/Gosu_Song.h +18 -0
- data/ffi/Gosu_TextInput.cpp +94 -0
- data/ffi/Gosu_TextInput.h +25 -0
- data/ffi/Gosu_Window.cpp +314 -0
- data/ffi/Gosu_Window.h +78 -0
- data/include/Gosu/Audio.hpp +6 -11
- data/include/Gosu/Bitmap.hpp +38 -53
- data/include/Gosu/Buffer.hpp +54 -0
- data/include/Gosu/Color.hpp +27 -35
- data/include/Gosu/Directories.hpp +25 -28
- data/include/Gosu/Drawable.hpp +58 -0
- data/include/Gosu/Font.hpp +6 -5
- data/include/Gosu/Fwd.hpp +4 -6
- data/include/Gosu/Gosu.hpp +5 -5
- data/include/Gosu/Graphics.hpp +51 -61
- data/include/Gosu/GraphicsBase.hpp +1 -11
- data/include/Gosu/Image.hpp +11 -14
- data/include/Gosu/Math.hpp +50 -72
- data/include/Gosu/Transform.hpp +32 -0
- data/include/Gosu/Utility.hpp +51 -1
- data/include/Gosu/Version.hpp +3 -3
- data/include/Gosu/Window.hpp +15 -9
- data/lib/SDL2.dll +0 -0
- data/lib/gosu/channel.rb +49 -0
- data/lib/gosu/color.rb +150 -0
- data/lib/gosu/compat.rb +29 -8
- data/lib/gosu/constants.rb +386 -0
- data/lib/gosu/ffi.rb +258 -0
- data/lib/gosu/font.rb +56 -0
- data/lib/gosu/gl_tex_info.rb +33 -0
- data/lib/gosu/gosu.rb +210 -0
- data/lib/gosu/image.rb +141 -0
- data/lib/gosu/numeric.rb +17 -0
- data/lib/gosu/preview.rb +6 -6
- data/lib/gosu/sample.rb +24 -0
- data/lib/gosu/song.rb +56 -0
- data/lib/gosu/text_input.rb +69 -0
- data/lib/gosu/window.rb +228 -0
- data/lib/gosu.rb +29 -8
- data/lib64/SDL2.dll +0 -0
- data/rdoc/gosu.rb +0 -2
- data/src/Audio.cpp +12 -12
- data/src/AudioFile.hpp +5 -4
- data/src/AudioFileAudioToolbox.cpp +8 -8
- data/src/AudioFileSDLSound.cpp +7 -10
- data/src/BinPacker.cpp +187 -0
- data/src/BinPacker.hpp +55 -0
- data/src/Bitmap.cpp +166 -144
- data/src/BitmapIO.cpp +60 -86
- data/src/Buffer.cpp +159 -0
- data/src/Color.cpp +75 -80
- data/src/Directories.cpp +47 -0
- data/src/DirectoriesUIKit.cpp +50 -0
- data/src/DrawOp.hpp +9 -4
- data/src/DrawOpQueue.hpp +2 -2
- data/src/Drawable.cpp +95 -0
- data/src/EmptyDrawable.hpp +38 -0
- data/src/FPS.cpp +31 -0
- data/src/Font.cpp +104 -74
- data/src/GosuGLView.cpp +14 -6
- data/src/GosuViewController.cpp +2 -10
- data/src/Graphics.cpp +60 -126
- data/src/GraphicsImpl.hpp +17 -47
- data/src/Image.cpp +41 -35
- data/src/Input.cpp +7 -8
- data/src/Macro.cpp +6 -6
- data/src/Macro.hpp +4 -4
- data/src/MarkupParser.cpp +5 -5
- data/src/Math.cpp +35 -22
- data/src/OffScreenTarget.cpp +53 -49
- data/src/OffScreenTarget.hpp +13 -11
- data/src/OpenGLContext.cpp +117 -0
- data/src/OpenGLContext.hpp +41 -0
- data/src/RenderState.hpp +21 -19
- data/src/Resolution.cpp +23 -21
- data/src/TexChunk.cpp +35 -80
- data/src/TexChunk.hpp +44 -35
- data/src/Text.cpp +1 -1
- data/src/TextBuilder.cpp +35 -21
- data/src/TextBuilder.hpp +6 -9
- data/src/Texture.cpp +62 -80
- data/src/Texture.hpp +25 -23
- data/src/TiledDrawable.cpp +150 -0
- data/src/TiledDrawable.hpp +47 -0
- data/src/TimingApple.cpp +1 -1
- data/src/Transform.cpp +45 -50
- data/src/TransformStack.hpp +16 -16
- data/src/TrueTypeFont.cpp +59 -51
- data/src/TrueTypeFont.hpp +6 -7
- data/src/TrueTypeFontApple.cpp +28 -19
- data/src/TrueTypeFontUnix.cpp +27 -23
- data/src/TrueTypeFontWin.cpp +30 -30
- data/src/Utility.cpp +84 -21
- data/src/UtilityWin.cpp +45 -0
- data/src/Window.cpp +92 -142
- data/src/WindowUIKit.cpp +14 -14
- metadata +72 -31
- data/include/Gosu/IO.hpp +0 -254
- data/include/Gosu/ImageData.hpp +0 -53
- data/include/Gosu/Inspection.hpp +0 -7
- data/lib/gosu/patches.rb +0 -66
- data/lib/gosu/run.rb +0 -20
- data/lib/gosu/swig_patches.rb +0 -110
- data/src/BlockAllocator.cpp +0 -131
- data/src/BlockAllocator.hpp +0 -32
- data/src/DirectoriesApple.cpp +0 -69
- data/src/DirectoriesUnix.cpp +0 -46
- data/src/DirectoriesWin.cpp +0 -65
- data/src/EmptyImageData.hpp +0 -52
- data/src/FileUnix.cpp +0 -99
- data/src/FileWin.cpp +0 -88
- data/src/IO.cpp +0 -60
- data/src/Iconv.hpp +0 -51
- data/src/Inspection.cpp +0 -27
- data/src/LargeImageData.cpp +0 -215
- data/src/LargeImageData.hpp +0 -39
- data/src/Log.hpp +0 -19
- data/src/RubyGosu.cxx +0 -13100
- data/src/RubyGosu.h +0 -49
- data/src/WinUtility.cpp +0 -61
- 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(
|
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] =
|
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 //
|
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(
|
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(
|
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(
|
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(
|
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(
|
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
|
-
|
155
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
53
|
+
schedule_draw_op(op);
|
82
54
|
}
|
83
55
|
|
84
|
-
std::unique_ptr<Gosu::
|
56
|
+
std::unique_ptr<Gosu::Drawable> Gosu::TexChunk::subimage(const Rect& rect) const
|
85
57
|
{
|
86
|
-
|
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(
|
68
|
+
return m_texture->to_bitmap(m_rect);
|
92
69
|
}
|
93
70
|
|
94
|
-
void Gosu::TexChunk::insert(const Bitmap&
|
71
|
+
void Gosu::TexChunk::insert(const Bitmap& bitmap, int x, int y)
|
95
72
|
{
|
96
73
|
Bitmap clipped_bitmap;
|
97
|
-
const 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 (
|
103
|
-
|
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
|
-
|
109
|
-
|
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(
|
132
|
-
clipped_bitmap.insert(
|
133
|
-
|
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
|
-
|
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/
|
5
|
-
#include
|
4
|
+
#include <Gosu/Drawable.hpp>
|
5
|
+
#include <Gosu/Utility.hpp>
|
6
|
+
#include <cstdint>
|
6
7
|
#include <memory>
|
7
|
-
#include <stdexcept>
|
8
8
|
|
9
|
-
|
9
|
+
namespace Gosu
|
10
10
|
{
|
11
|
-
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
|
24
|
-
|
25
|
-
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
|
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
|
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
|
-
|
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)
|
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)
|
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)
|
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::
|
108
|
+
void Gosu::TextBuilder::reallocate(int lines)
|
95
109
|
{
|
96
|
-
|
97
|
-
|
98
|
-
|
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
|
104
|
-
|
105
|
-
|
106
|
-
|
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
|
-
|
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
|
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
|