gosu 0.14.0.pre2 → 0.14.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/Gosu/Bitmap.hpp +4 -0
- data/Gosu/Font.hpp +29 -34
- data/Gosu/Text.hpp +19 -8
- data/Gosu/Utility.hpp +0 -5
- data/Gosu/Version.hpp +2 -2
- data/Gosu/Window.hpp +23 -16
- data/lib/gosu/compat.rb +17 -4
- data/lib/gosu/patches.rb +16 -0
- data/rdoc/gosu.rb +33 -9
- data/src/Bitmap.cpp +20 -0
- data/src/DirectoriesWin.cpp +3 -3
- data/src/DrawOpQueue.hpp +2 -1
- data/src/FileWin.cpp +87 -87
- data/src/Font.cpp +51 -31
- data/src/Graphics.cpp +1 -1
- data/src/GraphicsImpl.hpp +19 -0
- data/src/Input.cpp +30 -12
- data/src/MarkupParser.cpp +11 -8
- data/src/MarkupParser.hpp +2 -2
- data/src/Resolution.cpp +81 -50
- data/src/RubyGosu.cxx +285 -480
- data/src/Text.cpp +77 -50
- data/src/TextBuilder.cpp +1 -1
- data/src/TimingUnix.cpp +1 -1
- data/src/TrueTypeFont.cpp +26 -27
- data/src/TrueTypeFont.hpp +2 -1
- data/src/TrueTypeFontUnix.cpp +1 -1
- data/src/TrueTypeFontWin.cpp +4 -4
- data/src/Utility.cpp +0 -54
- data/src/UtilityApple.cpp +0 -35
- data/src/WinUtility.cpp +60 -41
- data/src/WinUtility.hpp +5 -0
- data/src/Window.cpp +19 -7
- data/src/WindowUIKit.cpp +26 -30
- metadata +4 -5
- data/src/ResolutionApple.cpp +0 -25
data/src/DrawOpQueue.hpp
CHANGED
@@ -13,9 +13,10 @@
|
|
13
13
|
|
14
14
|
class Gosu::DrawOpQueue
|
15
15
|
{
|
16
|
+
const QueueMode queue_mode;
|
17
|
+
|
16
18
|
TransformStack transform_stack;
|
17
19
|
ClipRectStack clip_rect_stack;
|
18
|
-
QueueMode queue_mode = QM_RENDER_TO_SCREEN;
|
19
20
|
|
20
21
|
std::vector<DrawOp> ops;
|
21
22
|
std::vector<std::function<void ()>> gl_blocks;
|
data/src/FileWin.cpp
CHANGED
@@ -1,88 +1,88 @@
|
|
1
|
-
#include <Gosu/Platform.hpp>
|
2
|
-
#if defined(GOSU_IS_WIN)
|
3
|
-
|
4
|
-
#include "WinUtility.hpp"
|
5
|
-
#include <Gosu/IO.hpp>
|
6
|
-
#include <Gosu/Utility.hpp>
|
1
|
+
#include <Gosu/Platform.hpp>
|
2
|
+
#if defined(GOSU_IS_WIN)
|
3
|
+
|
4
|
+
#include "WinUtility.hpp"
|
5
|
+
#include <Gosu/IO.hpp>
|
6
|
+
#include <Gosu/Utility.hpp>
|
7
7
|
#include <windows.h>
|
8
|
-
using namespace std;
|
9
|
-
|
10
|
-
// TODO: Error checking
|
11
|
-
|
12
|
-
struct Gosu::File::Impl
|
13
|
-
{
|
14
|
-
HANDLE handle = INVALID_HANDLE_VALUE;
|
15
|
-
|
16
|
-
~Impl()
|
17
|
-
{
|
18
|
-
if (handle != INVALID_HANDLE_VALUE) {
|
19
|
-
CloseHandle(handle);
|
20
|
-
}
|
21
|
-
}
|
22
|
-
};
|
23
|
-
|
24
|
-
Gosu::File::File(const string& filename, FileMode mode)
|
25
|
-
: pimpl(new Impl)
|
26
|
-
{
|
27
|
-
DWORD access;
|
28
|
-
switch (mode) {
|
29
|
-
case FM_READ:
|
30
|
-
access = GENERIC_READ;
|
31
|
-
break;
|
32
|
-
case FM_REPLACE:
|
33
|
-
access = GENERIC_WRITE;
|
34
|
-
break;
|
35
|
-
case FM_ALTER:
|
36
|
-
access = GENERIC_READ | GENERIC_WRITE;
|
37
|
-
break;
|
38
|
-
}
|
39
|
-
DWORD share_mode = FILE_SHARE_READ;
|
40
|
-
DWORD creation_disp = (mode == FM_READ) ? OPEN_EXISTING : OPEN_ALWAYS;
|
41
|
-
|
42
|
-
wstring wfilename =
|
43
|
-
pimpl->handle = CreateFileW(wfilename.c_str(), access, share_mode, 0, creation_disp,
|
44
|
-
FILE_ATTRIBUTE_NORMAL, 0);
|
45
|
-
if (pimpl->handle == INVALID_HANDLE_VALUE) {
|
46
|
-
throw_last_winapi_error("opening " + filename);
|
47
|
-
}
|
48
|
-
if (mode == FM_REPLACE) {
|
49
|
-
resize(0);
|
50
|
-
}
|
51
|
-
}
|
52
|
-
|
53
|
-
Gosu::File::~File()
|
54
|
-
{
|
55
|
-
}
|
56
|
-
|
57
|
-
size_t Gosu::File::size() const
|
58
|
-
{
|
59
|
-
return GetFileSize(pimpl->handle, 0);
|
60
|
-
}
|
61
|
-
|
62
|
-
void Gosu::File::resize(size_t new_size)
|
63
|
-
{
|
64
|
-
if (SetFilePointer(pimpl->handle, new_size, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
|
65
|
-
throw_last_winapi_error("setting the file pointer");
|
66
|
-
}
|
67
|
-
winapi_check(SetEndOfFile(pimpl->handle), "resizing a file");
|
68
|
-
}
|
69
|
-
|
70
|
-
void Gosu::File::read(size_t offset, size_t length, void* dest_buffer) const
|
71
|
-
{
|
72
|
-
if (SetFilePointer(pimpl->handle, offset, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
|
73
|
-
throw_last_winapi_error("setting the file pointer");
|
74
|
-
}
|
75
|
-
DWORD dummy;
|
76
|
-
winapi_check(ReadFile(pimpl->handle, dest_buffer, length, &dummy, 0));
|
77
|
-
}
|
78
|
-
|
79
|
-
void Gosu::File::write(size_t offset, size_t length, const void* source_buffer)
|
80
|
-
{
|
81
|
-
if (SetFilePointer(pimpl->handle, offset, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
|
82
|
-
throw_last_winapi_error("setting the file pointer");
|
83
|
-
}
|
84
|
-
DWORD dummy;
|
85
|
-
winapi_check(WriteFile(pimpl->handle, source_buffer, length, &dummy, 0));
|
86
|
-
}
|
87
|
-
|
88
|
-
#endif
|
8
|
+
using namespace std;
|
9
|
+
|
10
|
+
// TODO: Error checking
|
11
|
+
|
12
|
+
struct Gosu::File::Impl
|
13
|
+
{
|
14
|
+
HANDLE handle = INVALID_HANDLE_VALUE;
|
15
|
+
|
16
|
+
~Impl()
|
17
|
+
{
|
18
|
+
if (handle != INVALID_HANDLE_VALUE) {
|
19
|
+
CloseHandle(handle);
|
20
|
+
}
|
21
|
+
}
|
22
|
+
};
|
23
|
+
|
24
|
+
Gosu::File::File(const string& filename, FileMode mode)
|
25
|
+
: pimpl(new Impl)
|
26
|
+
{
|
27
|
+
DWORD access;
|
28
|
+
switch (mode) {
|
29
|
+
case FM_READ:
|
30
|
+
access = GENERIC_READ;
|
31
|
+
break;
|
32
|
+
case FM_REPLACE:
|
33
|
+
access = GENERIC_WRITE;
|
34
|
+
break;
|
35
|
+
case FM_ALTER:
|
36
|
+
access = GENERIC_READ | GENERIC_WRITE;
|
37
|
+
break;
|
38
|
+
}
|
39
|
+
DWORD share_mode = FILE_SHARE_READ;
|
40
|
+
DWORD creation_disp = (mode == FM_READ) ? OPEN_EXISTING : OPEN_ALWAYS;
|
41
|
+
|
42
|
+
wstring wfilename = utf8_to_utf16(filename);
|
43
|
+
pimpl->handle = CreateFileW(wfilename.c_str(), access, share_mode, 0, creation_disp,
|
44
|
+
FILE_ATTRIBUTE_NORMAL, 0);
|
45
|
+
if (pimpl->handle == INVALID_HANDLE_VALUE) {
|
46
|
+
throw_last_winapi_error("opening " + filename);
|
47
|
+
}
|
48
|
+
if (mode == FM_REPLACE) {
|
49
|
+
resize(0);
|
50
|
+
}
|
51
|
+
}
|
52
|
+
|
53
|
+
Gosu::File::~File()
|
54
|
+
{
|
55
|
+
}
|
56
|
+
|
57
|
+
size_t Gosu::File::size() const
|
58
|
+
{
|
59
|
+
return GetFileSize(pimpl->handle, 0);
|
60
|
+
}
|
61
|
+
|
62
|
+
void Gosu::File::resize(size_t new_size)
|
63
|
+
{
|
64
|
+
if (SetFilePointer(pimpl->handle, new_size, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
|
65
|
+
throw_last_winapi_error("setting the file pointer");
|
66
|
+
}
|
67
|
+
winapi_check(SetEndOfFile(pimpl->handle), "resizing a file");
|
68
|
+
}
|
69
|
+
|
70
|
+
void Gosu::File::read(size_t offset, size_t length, void* dest_buffer) const
|
71
|
+
{
|
72
|
+
if (SetFilePointer(pimpl->handle, offset, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
|
73
|
+
throw_last_winapi_error("setting the file pointer");
|
74
|
+
}
|
75
|
+
DWORD dummy;
|
76
|
+
winapi_check(ReadFile(pimpl->handle, dest_buffer, length, &dummy, 0));
|
77
|
+
}
|
78
|
+
|
79
|
+
void Gosu::File::write(size_t offset, size_t length, const void* source_buffer)
|
80
|
+
{
|
81
|
+
if (SetFilePointer(pimpl->handle, offset, 0, FILE_BEGIN) == INVALID_SET_FILE_POINTER) {
|
82
|
+
throw_last_winapi_error("setting the file pointer");
|
83
|
+
}
|
84
|
+
DWORD dummy;
|
85
|
+
winapi_check(WriteFile(pimpl->handle, source_buffer, length, &dummy, 0));
|
86
|
+
}
|
87
|
+
|
88
|
+
#endif
|
data/src/Font.cpp
CHANGED
@@ -27,10 +27,10 @@ struct Gosu::Font::Impl
|
|
27
27
|
// Everything else is looked up through a map...
|
28
28
|
array<map<utf8proc_int32_t, Image>, FF_COMBINATIONS> other_glyphs;
|
29
29
|
|
30
|
-
|
30
|
+
Image& image(char32_t codepoint, unsigned font_flags)
|
31
31
|
{
|
32
32
|
Image* image;
|
33
|
-
if (codepoint < fast_glyphs.size()) {
|
33
|
+
if (codepoint < fast_glyphs[font_flags].size()) {
|
34
34
|
image = &fast_glyphs[font_flags][codepoint];
|
35
35
|
}
|
36
36
|
else {
|
@@ -43,13 +43,13 @@ struct Gosu::Font::Impl
|
|
43
43
|
|
44
44
|
u32string string(1, codepoint);
|
45
45
|
Bitmap bitmap(scaled_height, scaled_height);
|
46
|
-
auto required_width = ceil(draw_text(bitmap, 0, 0, Color::WHITE, string,
|
47
|
-
|
46
|
+
auto required_width = ceil(Gosu::draw_text(bitmap, 0, 0, Color::WHITE, string,
|
47
|
+
name, scaled_height, font_flags));
|
48
48
|
if (required_width > bitmap.width()) {
|
49
49
|
// If the character was wider than high, we need to render it again.
|
50
50
|
Bitmap(required_width, scaled_height).swap(bitmap);
|
51
|
-
draw_text(bitmap, 0, 0, Color::WHITE, string,
|
52
|
-
|
51
|
+
Gosu::draw_text(bitmap, 0, 0, Color::WHITE, string,
|
52
|
+
name, scaled_height, font_flags);
|
53
53
|
}
|
54
54
|
|
55
55
|
*image = Image(bitmap, 0, 0, required_width, scaled_height);
|
@@ -82,60 +82,79 @@ unsigned Gosu::Font::flags() const
|
|
82
82
|
return pimpl->base_flags;
|
83
83
|
}
|
84
84
|
|
85
|
-
double Gosu::Font::text_width(const string& text
|
85
|
+
double Gosu::Font::text_width(const string& text) const
|
86
86
|
{
|
87
|
-
|
87
|
+
return markup_width(escape_markup(text));
|
88
|
+
}
|
89
|
+
|
90
|
+
double Gosu::Font::markup_width(const string& markup) const
|
91
|
+
{
|
92
|
+
double width = 0;
|
88
93
|
|
89
94
|
// Split the text into lines (split_words = false) because Font doesn't implement word-wrapping.
|
90
|
-
MarkupParser(
|
91
|
-
|
95
|
+
MarkupParser parser(pimpl->base_flags, false, [&](vector<FormattedString>&& line) {
|
96
|
+
double line_width = 0;
|
92
97
|
for (auto& part : line) {
|
93
98
|
for (auto codepoint : part.text) {
|
94
|
-
|
99
|
+
auto& image = pimpl->image(codepoint, part.flags);
|
100
|
+
double image_scale = 1.0 * height() / image.height();
|
101
|
+
line_width += image_scale * image.width();
|
95
102
|
}
|
96
103
|
}
|
97
104
|
width = max(width, line_width);
|
98
|
-
})
|
105
|
+
});
|
106
|
+
parser.parse(markup);
|
99
107
|
|
100
|
-
return
|
108
|
+
return width;
|
109
|
+
}
|
110
|
+
|
111
|
+
void Gosu::Font::draw_text(const string& text, double x, double y, ZPos z,
|
112
|
+
double scale_x, double scale_y, Color c, AlphaMode mode) const
|
113
|
+
{
|
114
|
+
draw_markup(escape_markup(text), x, y, z, scale_x, scale_y, c, mode);
|
101
115
|
}
|
102
116
|
|
103
|
-
void Gosu::Font::
|
104
|
-
|
117
|
+
void Gosu::Font::draw_markup(const string& markup, double x, double y, ZPos z,
|
118
|
+
double scale_x, double scale_y, Color c, AlphaMode mode) const
|
105
119
|
{
|
106
120
|
double current_y = y;
|
107
121
|
|
108
122
|
// Split the text into lines (split_words = false) because Font doesn't implement word-wrapping.
|
109
|
-
MarkupParser(
|
123
|
+
MarkupParser parser(pimpl->base_flags, false, [&](vector<FormattedString>&& line) {
|
110
124
|
double current_x = x;
|
111
125
|
for (auto& part : line) {
|
112
126
|
for (auto codepoint : part.text) {
|
113
127
|
auto& image = pimpl->image(codepoint, part.flags);
|
128
|
+
double image_scale = 1.0 * height() / image.height();
|
114
129
|
image.draw(current_x, current_y, z,
|
115
|
-
|
116
|
-
c, mode);
|
117
|
-
current_x += scale_x * image.width()
|
130
|
+
image_scale * scale_x, image_scale * scale_y,
|
131
|
+
multiply(c, part.color), mode);
|
132
|
+
current_x += image_scale * scale_x * image.width();
|
118
133
|
}
|
119
134
|
}
|
120
135
|
current_y += scale_y * height();
|
121
|
-
})
|
136
|
+
});
|
137
|
+
parser.parse(markup);
|
122
138
|
}
|
123
139
|
|
124
|
-
void Gosu::Font::
|
125
|
-
|
140
|
+
void Gosu::Font::draw_text_rel(const string& text, double x, double y, ZPos z,
|
141
|
+
double rel_x, double rel_y, double scale_x, double scale_y,
|
142
|
+
Color c, AlphaMode mode) const
|
126
143
|
{
|
127
|
-
x -= text_width(text) * scale_x * rel_x;
|
128
|
-
y -= height() * scale_y * rel_y;
|
144
|
+
if (rel_x) x -= text_width(text) * scale_x * rel_x;
|
145
|
+
if (rel_y) y -= height() * scale_y * rel_y;
|
129
146
|
|
130
|
-
|
147
|
+
draw_text(text, x, y, z, scale_x, scale_y, c, mode);
|
131
148
|
}
|
132
149
|
|
133
|
-
void Gosu::Font::
|
134
|
-
|
150
|
+
void Gosu::Font::draw_markup_rel(const string& markup, double x, double y, ZPos z,
|
151
|
+
double rel_x, double rel_y, double scale_x, double scale_y,
|
152
|
+
Color c, AlphaMode mode) const
|
135
153
|
{
|
136
|
-
|
137
|
-
|
138
|
-
|
154
|
+
if (rel_x) x -= markup_width(markup) * scale_x * rel_x;
|
155
|
+
if (rel_y) y -= height() * scale_y * rel_y;
|
156
|
+
|
157
|
+
draw_markup(markup, x, y, z, scale_x, scale_y, c, mode);
|
139
158
|
}
|
140
159
|
|
141
160
|
void Gosu::Font::set_image(std::string codepoint, unsigned font_flags, const Gosu::Image& image)
|
@@ -147,7 +166,8 @@ void Gosu::Font::set_image(std::string codepoint, unsigned font_flags, const Gos
|
|
147
166
|
|
148
167
|
if (utc4[0] < pimpl->fast_glyphs[font_flags].size()) {
|
149
168
|
pimpl->fast_glyphs[font_flags][utc4[0]] = image;
|
150
|
-
}
|
169
|
+
}
|
170
|
+
else {
|
151
171
|
pimpl->other_glyphs[font_flags][utc4[0]] = image;
|
152
172
|
}
|
153
173
|
}
|
data/src/Graphics.cpp
CHANGED
@@ -288,7 +288,7 @@ Gosu::Image Gosu::Graphics::render(int width, int height, const function<void ()
|
|
288
288
|
Image result = OffScreenTarget(width, height).render([&] {
|
289
289
|
glClearColor(0, 0, 0, 0);
|
290
290
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
291
|
-
queues.emplace_back(
|
291
|
+
queues.emplace_back(QM_RENDER_TO_TEXTURE);
|
292
292
|
f();
|
293
293
|
queues.back().perform_draw_ops_and_code();
|
294
294
|
queues.pop_back();
|
data/src/GraphicsImpl.hpp
CHANGED
@@ -8,6 +8,7 @@
|
|
8
8
|
#include <OpenGLES/ES1/gl.h>
|
9
9
|
#include <OpenGLES/ES1/glext.h>
|
10
10
|
#else
|
11
|
+
#include <SDL.h>
|
11
12
|
#include <SDL_opengl.h>
|
12
13
|
#endif
|
13
14
|
|
@@ -102,5 +103,23 @@ namespace Gosu
|
|
102
103
|
inline int clip_rect_base_factor() { return 1; }
|
103
104
|
#endif
|
104
105
|
|
106
|
+
#ifndef GOSU_IS_IPHONE
|
107
|
+
SDL_Window* shared_window();
|
108
|
+
#endif
|
109
|
+
|
105
110
|
void ensure_current_context();
|
111
|
+
|
112
|
+
inline std::string escape_markup(const std::string& text) {
|
113
|
+
// Escape all markup and delegate to layout_markup.
|
114
|
+
auto markup = text;
|
115
|
+
for (std::string::size_type pos = 0; pos < markup.length(); ++pos) {
|
116
|
+
if (markup[pos] == '&') {
|
117
|
+
markup.replace(pos, 1, "&");
|
118
|
+
}
|
119
|
+
else if (markup[pos] == '<') {
|
120
|
+
markup.replace(pos, 1, "<");
|
121
|
+
}
|
122
|
+
}
|
123
|
+
return markup;
|
124
|
+
}
|
106
125
|
}
|
data/src/Input.cpp
CHANGED
@@ -4,13 +4,22 @@
|
|
4
4
|
#include <Gosu/Input.hpp>
|
5
5
|
#include <Gosu/TextInput.hpp>
|
6
6
|
#include <Gosu/Utility.hpp>
|
7
|
+
|
7
8
|
#include <SDL.h>
|
9
|
+
#include "utf8proc.h"
|
10
|
+
|
8
11
|
#include <cwctype>
|
9
12
|
#include <cstdlib>
|
10
13
|
#include <algorithm>
|
11
14
|
#include <array>
|
12
15
|
using namespace std;
|
13
16
|
|
17
|
+
// Workaround for broken SDL_GetGlobalMouseState, see below.
|
18
|
+
#ifdef GOSU_IS_MAC
|
19
|
+
#import <CoreGraphics/CoreGraphics.h>
|
20
|
+
#import <AppKit/AppKit.h>
|
21
|
+
#endif
|
22
|
+
|
14
23
|
static void require_sdl_video()
|
15
24
|
{
|
16
25
|
static bool initialized = false;
|
@@ -71,11 +80,17 @@ struct Gosu::Input::Impl
|
|
71
80
|
|
72
81
|
void update_mouse_position()
|
73
82
|
{
|
74
|
-
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
83
|
+
#if defined(GOSU_IS_MAC)
|
84
|
+
// Avoid SDL_GetGlobalMouseState on macOS until this bug is fixed:
|
85
|
+
// https://bugzilla.libsdl.org/show_bug.cgi?id=4255
|
86
|
+
int window_x, window_y;
|
87
|
+
SDL_GetWindowPosition(window, &window_x, &window_y);
|
88
|
+
auto mouse_position = NSEvent.mouseLocation;
|
89
|
+
mouse_x = mouse_position.x - window_x;
|
90
|
+
mouse_y = (CGDisplayPixelsHigh(kCGDirectMainDisplay) - mouse_position.y) - window_y;
|
91
|
+
#elif SDL_VERSION_ATLEAST(2, 0, 5)
|
92
|
+
// SDL_GetGlobalMouseState was added in SDL 2.0.4, but it only started using the same
|
93
|
+
// coordinate system as SDL_GetWindowPosition on X11 in 2.0.5.
|
79
94
|
int x, y, window_x, window_y;
|
80
95
|
SDL_GetWindowPosition(window, &window_x, &window_y);
|
81
96
|
SDL_GetGlobalMouseState(&x, &y);
|
@@ -325,14 +340,17 @@ string Gosu::Input::id_to_char(Button btn)
|
|
325
340
|
const char* name = SDL_GetKeyName(keycode);
|
326
341
|
if (name == nullptr) return "";
|
327
342
|
|
328
|
-
|
329
|
-
|
343
|
+
u32string codepoints = utf8_to_composed_utc4(name);
|
344
|
+
|
345
|
+
// Filter out names that are more than one logical character.
|
346
|
+
if (codepoints.length() != 1) return "";
|
330
347
|
|
331
|
-
//
|
332
|
-
|
333
|
-
//
|
334
|
-
|
335
|
-
|
348
|
+
// Always return lower case to be consistent with previous versions of Gosu.
|
349
|
+
codepoints[0] = utf8proc_tolower(codepoints[0]);
|
350
|
+
// Convert back to UTF-8.
|
351
|
+
utf8proc_uint8_t utf8_buffer[4];
|
352
|
+
auto len = utf8proc_encode_char(codepoints[0], utf8_buffer);
|
353
|
+
return string(reinterpret_cast<char*>(utf8_buffer), len);
|
336
354
|
}
|
337
355
|
|
338
356
|
Gosu::Button Gosu::Input::char_to_id(string ch)
|
data/src/MarkupParser.cpp
CHANGED
@@ -97,9 +97,9 @@ bool Gosu::MarkupParser::parse_markup()
|
|
97
97
|
|
98
98
|
if (hex_chars == 3) {
|
99
99
|
// Expand 0xrgb to 0xFFrrggbb:
|
100
|
-
auto r = argb >> 8 &
|
101
|
-
auto g = argb >> 4 &
|
102
|
-
auto b = argb >> 0 &
|
100
|
+
auto r = argb >> 8 & 0xf;
|
101
|
+
auto g = argb >> 4 & 0xf;
|
102
|
+
auto b = argb >> 0 & 0xf;
|
103
103
|
argb = 0xff000000 | r << 20 | r << 16 | g << 12 | g << 8 | b << 4 | b << 0;
|
104
104
|
}
|
105
105
|
else if (hex_chars == 6) {
|
@@ -139,7 +139,7 @@ bool Gosu::MarkupParser::parse_escape_entity()
|
|
139
139
|
|
140
140
|
void Gosu::MarkupParser::add_current_substring()
|
141
141
|
{
|
142
|
-
if (!substring.empty()) {
|
142
|
+
if (! substring.empty()) {
|
143
143
|
add_composed_substring(utf8_to_composed_utc4(substring));
|
144
144
|
substring.clear();
|
145
145
|
}
|
@@ -168,9 +168,9 @@ void Gosu::MarkupParser::flush_to_consumer()
|
|
168
168
|
}
|
169
169
|
}
|
170
170
|
|
171
|
-
Gosu::MarkupParser::MarkupParser(
|
171
|
+
Gosu::MarkupParser::MarkupParser(unsigned base_flags, bool split_words,
|
172
172
|
function<void (vector<FormattedString>)> consumer)
|
173
|
-
:
|
173
|
+
: consumer(move(consumer))
|
174
174
|
{
|
175
175
|
word_state = (split_words ? ADDING_WORD : IGNORE_WORDS);
|
176
176
|
|
@@ -179,9 +179,10 @@ Gosu::MarkupParser::MarkupParser(const char* markup, unsigned base_flags, bool s
|
|
179
179
|
u = (base_flags & FF_UNDERLINE) ? 1 : 0;
|
180
180
|
}
|
181
181
|
|
182
|
-
void Gosu::MarkupParser::parse()
|
182
|
+
void Gosu::MarkupParser::parse(const std::string& markup_string)
|
183
183
|
{
|
184
|
-
|
184
|
+
markup = markup_string.data();
|
185
|
+
const char* end_of_markup = markup_string.data() + markup_string.length();
|
185
186
|
|
186
187
|
while (markup < end_of_markup) {
|
187
188
|
if (*markup == '<' && parse_markup()) {
|
@@ -196,7 +197,9 @@ void Gosu::MarkupParser::parse()
|
|
196
197
|
if (*markup == '\n') {
|
197
198
|
// Explicitly add the trailing \n to the current substring so that the consumer can
|
198
199
|
// distinguish between line breaks and word breaks in split_words mode.
|
200
|
+
substring.append(1, '\n');
|
199
201
|
++markup;
|
202
|
+
|
200
203
|
add_current_substring();
|
201
204
|
flush_to_consumer();
|
202
205
|
// Avoid incrementing ++markup again.
|