gosu 0.14.0 → 0.14.3.pre1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gosu/Graphics.hpp +4 -1
- data/Gosu/Version.hpp +1 -1
- data/Gosu/Window.hpp +1 -1
- data/rdoc/gosu.rb +4 -2
- data/src/Audio.cpp +36 -38
- data/src/Bitmap.cpp +167 -153
- data/src/DirectoriesWin.cpp +68 -68
- data/src/Graphics.cpp +3 -2
- data/src/InputUIKit.cpp +2 -1
- data/src/MarkupParser.cpp +5 -4
- data/src/OffScreenTarget.cpp +2 -2
- data/src/OffScreenTarget.hpp +1 -1
- data/src/Resolution.cpp +3 -2
- data/src/RubyGosu.cxx +36 -6
- data/src/SndFile.hpp +8 -9
- data/src/TextBuilder.cpp +3 -3
- data/src/TrueTypeFont.cpp +6 -4
- data/src/TrueTypeFont.hpp +15 -20
- data/src/TrueTypeFontUnix.cpp +15 -7
- data/src/TrueTypeFontWin.cpp +8 -3
- data/src/Utility.cpp +2 -1
- data/src/WinMain.cpp +64 -64
- data/src/WinUtility.cpp +1 -1
- data/src/Window.cpp +8 -0
- data/src/stb_image.h +7 -4
- data/src/stb_image_write.h +34 -25
- data/src/stb_truetype.h +272 -8
- data/src/stb_vorbis.c +31 -32
- metadata +4 -4
data/src/DirectoriesWin.cpp
CHANGED
@@ -1,69 +1,69 @@
|
|
1
|
-
#include <Gosu/Platform.hpp>
|
2
|
-
#if defined(GOSU_IS_WIN)
|
3
|
-
|
4
|
-
#include "WinUtility.hpp"
|
5
|
-
#include <Gosu/Directories.hpp>
|
6
|
-
#include <Gosu/Utility.hpp>
|
7
|
-
#include <cwchar>
|
8
|
-
#include <stdexcept>
|
1
|
+
#include <Gosu/Platform.hpp>
|
2
|
+
#if defined(GOSU_IS_WIN)
|
3
|
+
|
4
|
+
#include "WinUtility.hpp"
|
5
|
+
#include <Gosu/Directories.hpp>
|
6
|
+
#include <Gosu/Utility.hpp>
|
7
|
+
#include <cwchar>
|
8
|
+
#include <stdexcept>
|
9
9
|
#include <shlobj.h>
|
10
|
-
using namespace std;
|
11
|
-
|
12
|
-
static string special_folder_path(int csidl)
|
13
|
-
{
|
14
|
-
WCHAR buf[MAX_PATH + 2];
|
15
|
-
if (FAILED(SHGetFolderPathW(nullptr, csidl | CSIDL_FLAG_CREATE, nullptr, 0, buf))) {
|
16
|
-
throw runtime_error("Error getting special folder path");
|
17
|
-
}
|
18
|
-
size_t len = wcslen(buf);
|
19
|
-
if (buf[len - 1] != L'\\') {
|
20
|
-
buf[len] = L'\\';
|
21
|
-
buf[len + 1] = 0;
|
22
|
-
}
|
23
|
-
return Gosu::utf16_to_utf8(buf);
|
24
|
-
}
|
25
|
-
|
26
|
-
static string exe_filename()
|
27
|
-
{
|
28
|
-
static string result;
|
29
|
-
if (result.empty()) {
|
30
|
-
WCHAR buffer[MAX_PATH * 2];
|
31
|
-
Gosu::winapi_check(GetModuleFileNameW(nullptr, buffer, MAX_PATH * 2),
|
32
|
-
"getting the module filename");
|
33
|
-
result = Gosu::utf16_to_utf8(buffer);
|
34
|
-
}
|
35
|
-
return result;
|
36
|
-
}
|
37
|
-
|
38
|
-
void Gosu::use_resource_directory()
|
39
|
-
{
|
40
|
-
SetCurrentDirectory(utf8_to_utf16(resource_prefix()).c_str());
|
41
|
-
}
|
42
|
-
|
43
|
-
string Gosu::resource_prefix()
|
44
|
-
{
|
45
|
-
static string result;
|
46
|
-
if (result.empty()) {
|
47
|
-
result = exe_filename();
|
48
|
-
auto last_delim = result.find_last_of("\\/");
|
49
|
-
result.resize(last_delim == string::npos ? 0 : last_delim + 1);
|
50
|
-
}
|
51
|
-
return result;
|
52
|
-
}
|
53
|
-
|
54
|
-
string Gosu::shared_resource_prefix()
|
55
|
-
{
|
56
|
-
return resource_prefix();
|
57
|
-
}
|
58
|
-
|
59
|
-
string Gosu::user_settings_prefix()
|
60
|
-
{
|
61
|
-
return special_folder_path(CSIDL_APPDATA);
|
62
|
-
}
|
63
|
-
|
64
|
-
string Gosu::user_documents_prefix()
|
65
|
-
{
|
66
|
-
return special_folder_path(CSIDL_PERSONAL);
|
67
|
-
}
|
68
|
-
|
69
|
-
#endif
|
10
|
+
using namespace std;
|
11
|
+
|
12
|
+
static string special_folder_path(int csidl)
|
13
|
+
{
|
14
|
+
WCHAR buf[MAX_PATH + 2];
|
15
|
+
if (FAILED(SHGetFolderPathW(nullptr, csidl | CSIDL_FLAG_CREATE, nullptr, 0, buf))) {
|
16
|
+
throw runtime_error("Error getting special folder path");
|
17
|
+
}
|
18
|
+
size_t len = wcslen(buf);
|
19
|
+
if (buf[len - 1] != L'\\') {
|
20
|
+
buf[len] = L'\\';
|
21
|
+
buf[len + 1] = 0;
|
22
|
+
}
|
23
|
+
return Gosu::utf16_to_utf8(buf);
|
24
|
+
}
|
25
|
+
|
26
|
+
static string exe_filename()
|
27
|
+
{
|
28
|
+
static string result;
|
29
|
+
if (result.empty()) {
|
30
|
+
WCHAR buffer[MAX_PATH * 2];
|
31
|
+
Gosu::winapi_check(GetModuleFileNameW(nullptr, buffer, MAX_PATH * 2),
|
32
|
+
"getting the module filename");
|
33
|
+
result = Gosu::utf16_to_utf8(buffer);
|
34
|
+
}
|
35
|
+
return result;
|
36
|
+
}
|
37
|
+
|
38
|
+
void Gosu::use_resource_directory()
|
39
|
+
{
|
40
|
+
SetCurrentDirectory(utf8_to_utf16(resource_prefix()).c_str());
|
41
|
+
}
|
42
|
+
|
43
|
+
string Gosu::resource_prefix()
|
44
|
+
{
|
45
|
+
static string result;
|
46
|
+
if (result.empty()) {
|
47
|
+
result = exe_filename();
|
48
|
+
auto last_delim = result.find_last_of("\\/");
|
49
|
+
result.resize(last_delim == string::npos ? 0 : last_delim + 1);
|
50
|
+
}
|
51
|
+
return result;
|
52
|
+
}
|
53
|
+
|
54
|
+
string Gosu::shared_resource_prefix()
|
55
|
+
{
|
56
|
+
return resource_prefix();
|
57
|
+
}
|
58
|
+
|
59
|
+
string Gosu::user_settings_prefix()
|
60
|
+
{
|
61
|
+
return special_folder_path(CSIDL_APPDATA);
|
62
|
+
}
|
63
|
+
|
64
|
+
string Gosu::user_documents_prefix()
|
65
|
+
{
|
66
|
+
return special_folder_path(CSIDL_PERSONAL);
|
67
|
+
}
|
68
|
+
|
69
|
+
#endif
|
data/src/Graphics.cpp
CHANGED
@@ -265,7 +265,8 @@ void Gosu::Graphics::clip_to(double x, double y, double width, double height,
|
|
265
265
|
current_queue().end_clipping();
|
266
266
|
}
|
267
267
|
|
268
|
-
Gosu::Image Gosu::Graphics::render(int width, int height, const function<void ()>& f
|
268
|
+
Gosu::Image Gosu::Graphics::render(int width, int height, const function<void ()>& f,
|
269
|
+
unsigned image_flags)
|
269
270
|
{
|
270
271
|
ensure_current_context();
|
271
272
|
|
@@ -285,7 +286,7 @@ Gosu::Image Gosu::Graphics::render(int width, int height, const function<void ()
|
|
285
286
|
#endif
|
286
287
|
|
287
288
|
// This is the actual render-to-texture step.
|
288
|
-
Image result = OffScreenTarget(width, height).render([&] {
|
289
|
+
Image result = OffScreenTarget(width, height, image_flags).render([&] {
|
289
290
|
glClearColor(0, 0, 0, 0);
|
290
291
|
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
291
292
|
queues.emplace_back(QM_RENDER_TO_TEXTURE);
|
data/src/InputUIKit.cpp
CHANGED
@@ -171,7 +171,8 @@ void Gosu::Input::set_text_input(TextInput* text_input)
|
|
171
171
|
if (text_input) {
|
172
172
|
pimpl->text_input = text_input;
|
173
173
|
[pimpl->view becomeFirstResponder];
|
174
|
-
}
|
174
|
+
}
|
175
|
+
else {
|
175
176
|
[pimpl->view resignFirstResponder];
|
176
177
|
pimpl->text_input = nullptr;
|
177
178
|
}
|
data/src/MarkupParser.cpp
CHANGED
@@ -139,7 +139,7 @@ bool Gosu::MarkupParser::parse_escape_entity()
|
|
139
139
|
|
140
140
|
void Gosu::MarkupParser::add_current_substring()
|
141
141
|
{
|
142
|
-
if (!
|
142
|
+
if (!substring.empty()) {
|
143
143
|
add_composed_substring(utf8_to_composed_utc4(substring));
|
144
144
|
substring.clear();
|
145
145
|
}
|
@@ -152,7 +152,7 @@ void Gosu::MarkupParser::add_composed_substring(u32string&& substring)
|
|
152
152
|
fstr.flags = flags();
|
153
153
|
fstr.color = c.back();
|
154
154
|
|
155
|
-
if (!
|
155
|
+
if (!substrings.empty() && substrings.back().can_be_merged_with(fstr)) {
|
156
156
|
substrings.back().text.append(move(fstr.text));
|
157
157
|
}
|
158
158
|
else {
|
@@ -162,7 +162,7 @@ void Gosu::MarkupParser::add_composed_substring(u32string&& substring)
|
|
162
162
|
|
163
163
|
void Gosu::MarkupParser::flush_to_consumer()
|
164
164
|
{
|
165
|
-
if (!
|
165
|
+
if (!substrings.empty()) {
|
166
166
|
consumer(move(substrings));
|
167
167
|
substrings.clear();
|
168
168
|
}
|
@@ -221,7 +221,8 @@ void Gosu::MarkupParser::parse(const std::string& markup_string)
|
|
221
221
|
add_current_substring();
|
222
222
|
flush_to_consumer();
|
223
223
|
word_state = ADDING_WHITESPACE;
|
224
|
-
}
|
224
|
+
}
|
225
|
+
else if (!whitespace_except_newline && word_state == ADDING_WHITESPACE) {
|
225
226
|
// We are in word-parsing mode, and this is was the start of a word.
|
226
227
|
add_current_substring();
|
227
228
|
flush_to_consumer();
|
data/src/OffScreenTarget.cpp
CHANGED
@@ -28,7 +28,7 @@ using namespace std;
|
|
28
28
|
GL_DEPTH_COMPONENT
|
29
29
|
#endif
|
30
30
|
|
31
|
-
Gosu::OffScreenTarget::OffScreenTarget(int width, int height)
|
31
|
+
Gosu::OffScreenTarget::OffScreenTarget(int width, int height, unsigned image_flags)
|
32
32
|
{
|
33
33
|
#ifndef GOSU_IS_IPHONE
|
34
34
|
if (!SDL_GL_ExtensionSupported("GL_EXT_framebuffer_object")) {
|
@@ -37,7 +37,7 @@ Gosu::OffScreenTarget::OffScreenTarget(int width, int height)
|
|
37
37
|
#endif
|
38
38
|
|
39
39
|
// Create a new texture that will be our rendering target.
|
40
|
-
texture = make_shared<Texture>(width, height,
|
40
|
+
texture = make_shared<Texture>(width, height, image_flags & IF_RETRO);
|
41
41
|
// Mark the full texture as blocked for our TexChunk.
|
42
42
|
texture->block(0, 0, width, height);
|
43
43
|
|
data/src/OffScreenTarget.hpp
CHANGED
@@ -16,7 +16,7 @@ namespace Gosu
|
|
16
16
|
OffScreenTarget& operator=(OffScreenTarget&& other) = delete;
|
17
17
|
|
18
18
|
public:
|
19
|
-
OffScreenTarget(int width, int height);
|
19
|
+
OffScreenTarget(int width, int height, unsigned image_flags);
|
20
20
|
~OffScreenTarget();
|
21
21
|
Gosu::Image render(const std::function<void ()>& f);
|
22
22
|
};
|
data/src/Resolution.cpp
CHANGED
@@ -34,7 +34,7 @@ unsigned Gosu::screen_height(Window* window)
|
|
34
34
|
static NSSize max_window_size(Gosu::Window* window)
|
35
35
|
{
|
36
36
|
// Keep in sync with SDL_cocoawindow.m.
|
37
|
-
auto style =
|
37
|
+
auto style = NSTitledWindowMask|NSClosableWindowMask|NSMiniaturizableWindowMask;
|
38
38
|
|
39
39
|
auto index = window ? SDL_GetWindowDisplayIndex(Gosu::shared_window()) : 0;
|
40
40
|
auto screen_frame = NSScreen.screens[index].visibleFrame;
|
@@ -63,7 +63,8 @@ static SIZE max_window_size(Gosu::Window* window)
|
|
63
63
|
if (window == nullptr) {
|
64
64
|
// Easy case: Return the work area of the primary monitor.
|
65
65
|
SystemParametersInfo(SPI_GETWORKAREA, 0, &work_area, 0);
|
66
|
-
}
|
66
|
+
}
|
67
|
+
else {
|
67
68
|
// Return the work area of the monitor the window is on.
|
68
69
|
SDL_SysWMinfo wm_info;
|
69
70
|
SDL_VERSION(&wm_info.version);
|
data/src/RubyGosu.cxx
CHANGED
@@ -2408,8 +2408,34 @@ namespace Gosu
|
|
2408
2408
|
return new Gosu::Image(Gosu::Graphics::record(width, height, [] { rb_yield(Qnil); }));
|
2409
2409
|
}
|
2410
2410
|
|
2411
|
-
Gosu::Image* render(int width, int height) {
|
2412
|
-
|
2411
|
+
Gosu::Image* render(int width, int height, VALUE options = 0) {
|
2412
|
+
unsigned image_flags = 0;
|
2413
|
+
|
2414
|
+
if (options) {
|
2415
|
+
Check_Type(options, T_HASH);
|
2416
|
+
|
2417
|
+
VALUE keys = rb_funcall(options, rb_intern("keys"), 0, NULL);
|
2418
|
+
int keys_size = NUM2INT(rb_funcall(keys, rb_intern("size"), 0, NULL));
|
2419
|
+
|
2420
|
+
for (int i = 0; i < keys_size; ++i) {
|
2421
|
+
VALUE key = rb_ary_entry(keys, i);
|
2422
|
+
const char* key_string = Gosu::cstr_from_symbol(key);
|
2423
|
+
|
2424
|
+
VALUE value = rb_hash_aref(options, key);
|
2425
|
+
if (!strcmp(key_string, "retro")) {
|
2426
|
+
if (RTEST(value)) image_flags |= Gosu::IF_RETRO;
|
2427
|
+
}
|
2428
|
+
else {
|
2429
|
+
static bool issued_warning = false;
|
2430
|
+
if (!issued_warning) {
|
2431
|
+
issued_warning = true;
|
2432
|
+
rb_warn("Unknown keyword argument: :%s", key_string);
|
2433
|
+
}
|
2434
|
+
}
|
2435
|
+
}
|
2436
|
+
}
|
2437
|
+
|
2438
|
+
return new Gosu::Image(Gosu::Graphics::render(width, height, [] { rb_yield(Qnil); }, image_flags));
|
2413
2439
|
}
|
2414
2440
|
|
2415
2441
|
// This method cannot be called "transform" because then it would be an ambiguous overload of
|
@@ -10890,6 +10916,7 @@ SWIGINTERN VALUE
|
|
10890
10916
|
_wrap_render(int argc, VALUE *argv, VALUE self) {
|
10891
10917
|
int arg1 ;
|
10892
10918
|
int arg2 ;
|
10919
|
+
VALUE arg3 = (VALUE) 0 ;
|
10893
10920
|
int val1 ;
|
10894
10921
|
int ecode1 = 0 ;
|
10895
10922
|
int val2 ;
|
@@ -10897,7 +10924,7 @@ _wrap_render(int argc, VALUE *argv, VALUE self) {
|
|
10897
10924
|
Gosu::Image *result = 0 ;
|
10898
10925
|
VALUE vresult = Qnil;
|
10899
10926
|
|
10900
|
-
if ((argc < 2) || (argc >
|
10927
|
+
if ((argc < 2) || (argc > 3)) {
|
10901
10928
|
rb_raise(rb_eArgError, "wrong # of arguments(%d for 2)",argc); SWIG_fail;
|
10902
10929
|
}
|
10903
10930
|
ecode1 = SWIG_AsVal_int(argv[0], &val1);
|
@@ -10910,15 +10937,18 @@ _wrap_render(int argc, VALUE *argv, VALUE self) {
|
|
10910
10937
|
SWIG_exception_fail(SWIG_ArgError(ecode2), Ruby_Format_TypeError( "", "int","Gosu::render", 2, argv[1] ));
|
10911
10938
|
}
|
10912
10939
|
arg2 = static_cast< int >(val2);
|
10940
|
+
if (argc > 2) {
|
10941
|
+
arg3 = argv[2];
|
10942
|
+
}
|
10913
10943
|
{
|
10914
10944
|
try {
|
10915
|
-
result = (Gosu::Image *)Gosu::render(arg1,arg2);
|
10945
|
+
result = (Gosu::Image *)Gosu::render(arg1,arg2,arg3);
|
10916
10946
|
}
|
10917
10947
|
catch (const std::exception& e) {
|
10918
10948
|
SWIG_exception(SWIG_RuntimeError, e.what());
|
10919
10949
|
}
|
10920
10950
|
}
|
10921
|
-
vresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Gosu__Image,
|
10951
|
+
vresult = SWIG_NewPointerObj(SWIG_as_voidptr(result), SWIGTYPE_p_Gosu__Image, SWIG_POINTER_OWN | 0 );
|
10922
10952
|
return vresult;
|
10923
10953
|
fail:
|
10924
10954
|
return Qnil;
|
@@ -11671,7 +11701,7 @@ SWIGEXPORT void Init_gosu(void) {
|
|
11671
11701
|
rb_define_const(mGosu, "LICENSES", SWIG_From_std_string(static_cast< std::string >(Gosu::LICENSES)));
|
11672
11702
|
rb_define_const(mGosu, "MAJOR_VERSION", SWIG_From_int(static_cast< int >(0)));
|
11673
11703
|
rb_define_const(mGosu, "MINOR_VERSION", SWIG_From_int(static_cast< int >(14)));
|
11674
|
-
rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(
|
11704
|
+
rb_define_const(mGosu, "POINT_VERSION", SWIG_From_int(static_cast< int >(3)));
|
11675
11705
|
rb_define_module_function(mGosu, "milliseconds", VALUEFUNC(_wrap_milliseconds), -1);
|
11676
11706
|
rb_define_module_function(mGosu, "random", VALUEFUNC(_wrap_random), -1);
|
11677
11707
|
rb_define_module_function(mGosu, "degrees_to_radians", VALUEFUNC(_wrap_degrees_to_radians), -1);
|
data/src/SndFile.hpp
CHANGED
@@ -19,9 +19,8 @@ namespace Gosu
|
|
19
19
|
Reader reader;
|
20
20
|
Buffer buffer;
|
21
21
|
|
22
|
-
//
|
23
|
-
|
24
|
-
#ifdef GOSU_IS_WIN
|
22
|
+
// /DELAYLOAD doesn't work with libsndfile.dll (is this still true?); manually lazy-load it.
|
23
|
+
#ifdef GOSU_IS_WIN
|
25
24
|
static HMODULE dll()
|
26
25
|
{
|
27
26
|
static HMODULE dll = LoadLibrary(L"libsndfile.dll");
|
@@ -29,7 +28,7 @@ namespace Gosu
|
|
29
28
|
return dll;
|
30
29
|
}
|
31
30
|
|
32
|
-
|
31
|
+
#define CREATE_STUB(NAME, RETURN, PARAMS, NAMES) \
|
33
32
|
static RETURN NAME PARAMS \
|
34
33
|
{ \
|
35
34
|
typedef RETURN (__cdecl *NAME##_ptr) PARAMS; \
|
@@ -54,8 +53,8 @@ namespace Gosu
|
|
54
53
|
CREATE_STUB(sf_strerror, const char*,
|
55
54
|
(SNDFILE* sndfile),
|
56
55
|
(sndfile))
|
57
|
-
|
58
|
-
|
56
|
+
#undef CREATE_STUB
|
57
|
+
#endif
|
59
58
|
|
60
59
|
static sf_count_t get_filelen(SndFile* self)
|
61
60
|
{
|
@@ -126,12 +125,12 @@ namespace Gosu
|
|
126
125
|
info.format = 0;
|
127
126
|
// TODO: Not sure if this is still necessary.
|
128
127
|
// Can libsndfile open UTF-8 filenames on Windows?
|
129
|
-
|
128
|
+
#ifdef GOSU_IS_WIN
|
130
129
|
load_file(buffer, filename);
|
131
130
|
file = sf_open_virtual(io_interface(), SFM_READ, &info, this);
|
132
|
-
|
131
|
+
#else
|
133
132
|
file = sf_open(filename.c_str(), SFM_READ, &info);
|
134
|
-
|
133
|
+
#endif
|
135
134
|
if (!file) {
|
136
135
|
throw std::runtime_error(sf_strerror(nullptr));
|
137
136
|
}
|
data/src/TextBuilder.cpp
CHANGED
@@ -7,7 +7,7 @@ using namespace std;
|
|
7
7
|
|
8
8
|
Gosu::WordInfo::WordInfo(const string& font_name, double font_height, vector<FormattedString> parts)
|
9
9
|
{
|
10
|
-
assert (!
|
10
|
+
assert (!parts.empty());
|
11
11
|
|
12
12
|
auto* properties = utf8proc_get_property(parts.front().text.front());
|
13
13
|
|
@@ -21,7 +21,7 @@ Gosu::WordInfo::WordInfo(const string& font_name, double font_height, vector<For
|
|
21
21
|
|
22
22
|
width = 0;
|
23
23
|
for (const auto& part : parts) {
|
24
|
-
assert (is_end_of_line || !
|
24
|
+
assert (is_end_of_line || !part.text.empty());
|
25
25
|
|
26
26
|
width += text_width(part.text, font_name, font_height, part.flags);
|
27
27
|
}
|
@@ -42,7 +42,7 @@ void Gosu::TextBuilder::flush_current_line(EndOfLineReason reason)
|
|
42
42
|
if (current_line.back().is_whitespace) current_line.pop_back();
|
43
43
|
|
44
44
|
// Shouldn't happen because the first word on a line should never be whitespace.
|
45
|
-
assert (!
|
45
|
+
assert (!current_line.empty());
|
46
46
|
|
47
47
|
double words_width = 0, whitespace_width = 0;
|
48
48
|
for (const auto& word : current_line) {
|
data/src/TrueTypeFont.cpp
CHANGED
@@ -199,12 +199,13 @@ double Gosu::TrueTypeFont::draw_text(const u32string &text, double height,
|
|
199
199
|
return pimpl->draw_text(text, true, height, bitmap, x, y, c);
|
200
200
|
}
|
201
201
|
|
202
|
-
bool Gosu::TrueTypeFont::
|
202
|
+
bool Gosu::TrueTypeFont::matches(const unsigned char* ttf_data,
|
203
|
+
const string& font_name, unsigned font_flags)
|
203
204
|
{
|
204
|
-
// Gosu
|
205
|
+
// Gosu::FontFlags uses the same values as the STBTT_ macros, except for this one.
|
205
206
|
int flags = (font_flags == 0 ? STBTT_MACSTYLE_NONE : font_flags);
|
206
207
|
|
207
|
-
return stbtt_FindMatchingFont(ttf_data, font_name.c_str(),
|
208
|
+
return stbtt_FindMatchingFont(ttf_data, font_name.c_str(), flags) >= 0 ||
|
208
209
|
stbtt_FindMatchingFont(ttf_data, font_name.c_str(), STBTT_MACSTYLE_DONTCARE) >= 0;
|
209
210
|
}
|
210
211
|
|
@@ -248,7 +249,8 @@ Gosu::TrueTypeFont& Gosu::font_by_name(const string& font_name, unsigned font_fl
|
|
248
249
|
if (font_name.find_first_of("./\\") != string::npos) {
|
249
250
|
// A filename? Load it and add it to the stack.
|
250
251
|
ttf_stack.push_back(ttf_data_from_file(font_name));
|
251
|
-
}
|
252
|
+
}
|
253
|
+
else if (font_name != default_font_name()) {
|
252
254
|
// A font name? Add it to the stack, both with font_flags and without.
|
253
255
|
ttf_stack.push_back(ttf_data_by_name(font_name, 0));
|
254
256
|
ttf_stack.push_back(ttf_data_by_name(font_name, font_flags));
|
data/src/TrueTypeFont.hpp
CHANGED
@@ -25,8 +25,8 @@ namespace Gosu
|
|
25
25
|
Bitmap* bitmap, double x, double y, Color c);
|
26
26
|
|
27
27
|
//! Returns true if the supplied buffer seems to be a font of the given name.
|
28
|
-
static bool
|
29
|
-
|
28
|
+
static bool matches(const unsigned char* ttf_data,
|
29
|
+
const std::string& font_name, unsigned font_flags);
|
30
30
|
};
|
31
31
|
|
32
32
|
TrueTypeFont& font_by_name(const std::string& font_name, unsigned font_flags);
|
@@ -36,6 +36,19 @@ namespace Gosu
|
|
36
36
|
//! In case of failure, this method must not return nullptr, but raise an exception.
|
37
37
|
//! Note that this method does not accept any font flags, and so it will always load the first
|
38
38
|
//! font in a TTC font collection.
|
39
|
+
//!
|
40
|
+
//! This function does not yet support Gosu::FontFlags, and consequently, custom TTF fonts do
|
41
|
+
//! not support markup or bold/italic text right now.
|
42
|
+
//!
|
43
|
+
//! Options for the future:
|
44
|
+
//! 1. Use stbtt_FindMatchingFont. This will only work for TTC font collections, and we will
|
45
|
+
//! have to patch stb_truetype to look for fonts only based on `int flags`, while ignoring
|
46
|
+
//! the name of fonts inside a bundle (who wants to deal with strings, anyway).
|
47
|
+
//! 2. Maybe Gosu should accept filename patterns like "LibreBaskerville-*.ttf" as the font
|
48
|
+
//! name and then replace the * with "Regular", "Bold", "Italic" etc.?
|
49
|
+
//! 3. As a last resort, Gosu could implement faux bold and faux italics. I think faux
|
50
|
+
//! underlines are a must anyway, since no font provides a dedicated TTF file for that.
|
51
|
+
//! These options are not mutually exclusive.
|
39
52
|
const unsigned char* ttf_data_from_file(const std::string& filename);
|
40
53
|
|
41
54
|
//! This method loads a TODO
|
@@ -46,22 +59,4 @@ namespace Gosu
|
|
46
59
|
//! This method has a different implementation on each platform.
|
47
60
|
//! In case of failure, this method must not return nullptr, but raise an exception.
|
48
61
|
const unsigned char* ttf_fallback_data();
|
49
|
-
|
50
|
-
// TODO still true? ↓
|
51
|
-
// These functions do not yet support Gosu::FontFlags. This is fine for system fonts like Arial,
|
52
|
-
// where the callers of these methods will typically load the correct file (e.g. ArialBold.ttf).
|
53
|
-
// However, games which ship with their own font files (which is a good idea) can't use bold or
|
54
|
-
// italic text using <b> or <i> markup because there is no way to associate one TTF file as the
|
55
|
-
// "bold variant" of another.
|
56
|
-
//
|
57
|
-
// Options for the future:
|
58
|
-
// 1. Use stbtt_FindMatchingFont. This will only work for TTC font collections, and we will
|
59
|
-
// have to patch stb_truetype to look for fonts only based on `int flags`, while ignoring
|
60
|
-
// the name of fonts inside a bundle (who wants to deal with strings, anyway).
|
61
|
-
// 2. Maybe Gosu should accept filename patterns like "LibreBaskerville-*.ttf" as the font
|
62
|
-
// name and then replace the * with "Regular", "Bold", "Italic" etc.?
|
63
|
-
// 3. As a last resort, Gosu could implement faux bold and faux italics. I think faux
|
64
|
-
// underlines are a must anyway, since no font provides a dedicated TTF file for that.
|
65
|
-
// These options are not mutually exclusive.
|
66
|
-
|
67
62
|
}
|