gosu 0.14.0 → 0.14.3.pre1

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.
@@ -21,11 +21,13 @@ const unsigned char* Gosu::ttf_data_by_name(const string& font_name, unsigned fo
21
21
 
22
22
  static FcConfig* config = FcInitLoadConfigAndFonts();
23
23
  if (config) {
24
+ // Find "outline fonts" (so no bitmap fonts).
24
25
  // Our search pattern does not include weight or slant so that we can compromise on these.
25
- FcPattern* pattern = FcPatternBuild(nullptr,
26
- FC_FAMILY, FcTypeString, font_name.c_str(),
27
- FC_OUTLINE, FcTypeBool, FcTrue, /* no bitmap fonts */
28
- nullptr);
26
+ FcPattern* pattern = FcPatternBuild(nullptr, FC_OUTLINE, FcTypeBool, FcTrue, nullptr);
27
+ // If a font name was given, add it to the pattern.
28
+ if (!font_name.empty()) {
29
+ FcPatternBuild(pattern, FC_FAMILY, FcTypeString, font_name.c_str(), nullptr);
30
+ }
29
31
  FcObjectSet* props = FcObjectSetBuild(FC_FILE, FC_WEIGHT, FC_SLANT, nullptr);
30
32
 
31
33
  if (FcFontSet* fonts = FcFontList(config, pattern, props)) {
@@ -44,12 +46,14 @@ const unsigned char* Gosu::ttf_data_by_name(const string& font_name, unsigned fo
44
46
  int diff = 0;
45
47
  if (font_flags & Gosu::FF_BOLD) {
46
48
  diff += abs(weight - 200);
47
- } else {
49
+ }
50
+ else {
48
51
  diff += abs(weight - 80);
49
52
  }
50
53
  if (font_flags & Gosu::FF_ITALIC) {
51
54
  diff += abs(slant - 100);
52
- } else {
55
+ }
56
+ else {
53
57
  diff += abs(slant - 0);
54
58
  }
55
59
 
@@ -80,12 +84,16 @@ const unsigned char* Gosu::ttf_fallback_data()
80
84
  static const unsigned char* unifont = ttf_data_by_name("Unifont", 0);
81
85
  if (unifont) return unifont;
82
86
 
87
+ // Otherwise, just use any font that font-config gives us.
88
+ static const unsigned char* any_font = ttf_data_by_name("", 0);
89
+ if (any_font) return any_font;
90
+
83
91
  return ttf_data_from_file("/usr/share/fonts/truetype/liberation/LiberationSans-Regular.ttf");
84
92
  }
85
93
 
86
94
  string Gosu::default_font_name()
87
95
  {
88
- return "Liberation";
96
+ return "Liberation Sans";
89
97
  }
90
98
 
91
99
  #endif
@@ -33,7 +33,7 @@ const unsigned char* Gosu::ttf_data_by_name(const string& font_name, unsigned fo
33
33
  (font_flags & Gosu::FF_UNDERLINE) ? TRUE : FALSE,
34
34
  FALSE /* no strikethrough */,
35
35
  ANSI_CHARSET, OUT_OUTLINE_PRECIS, CLIP_DEFAULT_PRECIS, ANTIALIASED_QUALITY,
36
- DEFAULT_PITCH | FF_DONTCARE
36
+ DEFAULT_PITCH
37
37
  };
38
38
 
39
39
  wstring wfont_name = utf8_to_utf16(font_name);
@@ -49,7 +49,7 @@ const unsigned char* Gosu::ttf_data_by_name(const string& font_name, unsigned fo
49
49
  buffer->resize(ttf_buffer_size);
50
50
  if (GetFontData(hdc, 0, 0, buffer->data(), buffer->size()) != GDI_ERROR) {
51
51
  auto data = static_cast<const unsigned char*>(buffer->data());
52
- if (TrueTypeFont::verify_font_name(data, font_name, font_flags)) {
52
+ if (font_name.empty() || TrueTypeFont::matches(data, font_name, font_flags)) {
53
53
  buffer_ptr = buffer;
54
54
  }
55
55
  }
@@ -69,8 +69,13 @@ const unsigned char* Gosu::ttf_fallback_data()
69
69
  static const unsigned char* arial_unicode = ttf_data_by_name("Arial Unicode MS", 0);
70
70
  if (arial_unicode) return arial_unicode;
71
71
 
72
+ // Otherwise, just try to find *any* font.
73
+ static const unsigned char* any_font = ttf_data_by_name("", 0);
74
+ if (any_font) return any_font;
75
+
72
76
  static const char* windir = getenv("WINDIR");
73
- if (windir) ttf_data_from_file(string(windir) + "/Fonts/arial.ttf");
77
+ if (windir) return ttf_data_from_file(string(windir) + "/Fonts/arial.ttf");
78
+
74
79
  return ttf_data_from_file("C:/Windows/Fonts/arial.ttf");
75
80
  }
76
81
 
data/src/Utility.cpp CHANGED
@@ -23,7 +23,8 @@ u32string Gosu::utf8_to_composed_utc4(const string& utf8)
23
23
  // Not looking good, skip this byte and retry.
24
24
  current_byte += 1;
25
25
  remaining_length -= 1;
26
- } else {
26
+ }
27
+ else {
27
28
  utc4.push_back(codepoint);
28
29
  current_byte += bytes_read;
29
30
  remaining_length -= bytes_read;
data/src/WinMain.cpp CHANGED
@@ -1,64 +1,64 @@
1
- #include <Gosu/Platform.hpp>
2
- #if defined(GOSU_IS_WIN)
3
-
4
- #include <exception>
5
- #include <string>
6
- #include <vector>
7
- #include <windows.h>
8
- using namespace std;
9
-
10
- vector<string> split_cmd_line()
11
- {
12
- vector<string> result;
13
-
14
- const char* cmd_line = ::GetCommandLineA();
15
-
16
- const char* arg_begin = nullptr;
17
- bool is_quoted_arg = false;
18
-
19
- while (*cmd_line) {
20
- if (*cmd_line == '"') {
21
- if (arg_begin == nullptr) {
22
- arg_begin = cmd_line + 1;
23
- is_quoted_arg = true;
24
- }
25
- else if (is_quoted_arg) {
26
- result.push_back(string(arg_begin, cmd_line));
27
- arg_begin = nullptr;
28
- }
29
- }
30
- else if (!isspace((unsigned char)*cmd_line) && arg_begin == nullptr) {
31
- arg_begin = cmd_line;
32
- is_quoted_arg = false;
33
- }
34
- else if (isspace((unsigned char)*cmd_line) && arg_begin != nullptr && !is_quoted_arg) {
35
- result.push_back(string(arg_begin, cmd_line + 1));
36
- arg_begin = nullptr;
37
- }
38
- ++cmd_line;
39
- }
40
-
41
- if (arg_begin != 0)
42
- result.push_back(arg_begin);
43
-
44
- return result;
45
- }
46
-
47
- int main(int argc, char* argv[]);
48
-
49
- int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
50
- {
51
- try {
52
- vector<string> arguments = split_cmd_line();
53
- vector<char*> argv(arguments.size());
54
- for (unsigned i = 0; i < argv.size(); ++i)
55
- argv[i] = const_cast<char*>(arguments[i].c_str());
56
- return main(argv.size(), &argv[0]);
57
- }
58
- catch (const exception& e) {
59
- ::MessageBoxA(0, e.what(), "Uncaught Exception", MB_OK | MB_ICONERROR);
60
- return EXIT_FAILURE;
61
- }
62
- }
63
-
64
- #endif
1
+ #include <Gosu/Platform.hpp>
2
+ #if defined(GOSU_IS_WIN)
3
+
4
+ #include <exception>
5
+ #include <string>
6
+ #include <vector>
7
+ #include <windows.h>
8
+ using namespace std;
9
+
10
+ vector<string> split_cmd_line()
11
+ {
12
+ vector<string> result;
13
+
14
+ const char* cmd_line = ::GetCommandLineA();
15
+
16
+ const char* arg_begin = nullptr;
17
+ bool is_quoted_arg = false;
18
+
19
+ while (*cmd_line) {
20
+ if (*cmd_line == '"') {
21
+ if (arg_begin == nullptr) {
22
+ arg_begin = cmd_line + 1;
23
+ is_quoted_arg = true;
24
+ }
25
+ else if (is_quoted_arg) {
26
+ result.push_back(string(arg_begin, cmd_line));
27
+ arg_begin = nullptr;
28
+ }
29
+ }
30
+ else if (!isspace((unsigned char)*cmd_line) && arg_begin == nullptr) {
31
+ arg_begin = cmd_line;
32
+ is_quoted_arg = false;
33
+ }
34
+ else if (isspace((unsigned char)*cmd_line) && arg_begin != nullptr && !is_quoted_arg) {
35
+ result.push_back(string(arg_begin, cmd_line + 1));
36
+ arg_begin = nullptr;
37
+ }
38
+ ++cmd_line;
39
+ }
40
+
41
+ if (arg_begin != 0) result.push_back(arg_begin);
42
+
43
+ return result;
44
+ }
45
+
46
+ int main(int argc, char* argv[]);
47
+
48
+ int WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, int)
49
+ {
50
+ try {
51
+ vector<string> arguments = split_cmd_line();
52
+ vector<char*> argv(arguments.size());
53
+ for (unsigned i = 0; i < argv.size(); ++i) {
54
+ argv[i] = const_cast<char*>(arguments[i].c_str());
55
+ }
56
+ return main(argv.size(), &argv[0]);
57
+ }
58
+ catch (const exception& e) {
59
+ ::MessageBoxA(0, e.what(), "Uncaught Exception", MB_OK | MB_ICONERROR);
60
+ return EXIT_FAILURE;
61
+ }
62
+ }
63
+
64
+ #endif
data/src/WinUtility.cpp CHANGED
@@ -30,7 +30,7 @@ void Gosu::throw_last_winapi_error(const string& action)
30
30
  {
31
31
  // Obtain error message from Windows.
32
32
  wchar_t* buffer;
33
-
33
+
34
34
  if (!FormatMessageW(FORMAT_MESSAGE_ALLOCATE_BUFFER |
35
35
  FORMAT_MESSAGE_FROM_SYSTEM |
36
36
  FORMAT_MESSAGE_IGNORE_INSERTS, nullptr, GetLastError(),
data/src/Window.cpp CHANGED
@@ -338,6 +338,14 @@ void Gosu::Window::button_down(Button button)
338
338
  !Input::down(KB_LEFT_META) && !Input::down(KB_RIGHT_META) &&
339
339
  !Input::down(KB_LEFT_SHIFT) && !Input::down(KB_RIGHT_SHIFT);
340
340
  #endif
341
+ // F11 is supported as a shortcut for fullscreen mode on all platforms.
342
+ if (!toggle_fullscreen && button == KB_F11 &&
343
+ !Input::down(KB_LEFT_ALT) && !Input::down(KB_RIGHT_ALT) &&
344
+ !Input::down(KB_LEFT_CONTROL) && !Input::down(KB_RIGHT_CONTROL) &&
345
+ !Input::down(KB_LEFT_META) && !Input::down(KB_RIGHT_META) &&
346
+ !Input::down(KB_LEFT_SHIFT) && !Input::down(KB_RIGHT_SHIFT)) {
347
+ toggle_fullscreen = true;
348
+ }
341
349
 
342
350
  if (toggle_fullscreen) {
343
351
  resize(width(), height(), !fullscreen());
data/src/stb_image.h CHANGED
@@ -1,4 +1,4 @@
1
- /* stb_image - v2.18 - public domain image loader - http://nothings.org/stb
1
+ /* stb_image - v2.19 - public domain image loader - http://nothings.org/stb
2
2
  no warranty implied; use at your own risk
3
3
 
4
4
  Do this:
@@ -48,6 +48,7 @@ LICENSE
48
48
 
49
49
  RECENT REVISION HISTORY:
50
50
 
51
+ 2.19 (2018-02-11) fix warning
51
52
  2.18 (2018-01-30) fix warnings
52
53
  2.17 (2018-01-29) bugfix, 1-bit BMP, 16-bitness query, fix warnings
53
54
  2.16 (2017-07-23) all functions have 16-bit variants; optimizations; bugfixes
@@ -6894,7 +6895,7 @@ static int stbi__psd_info(stbi__context *s, int *x, int *y, int *comp)
6894
6895
 
6895
6896
  static int stbi__psd_is16(stbi__context *s)
6896
6897
  {
6897
- int channelCount, dummy, depth;
6898
+ int channelCount, depth;
6898
6899
  if (stbi__get32be(s) != 0x38425053) {
6899
6900
  stbi__rewind( s );
6900
6901
  return 0;
@@ -6909,8 +6910,8 @@ static int stbi__psd_is16(stbi__context *s)
6909
6910
  stbi__rewind( s );
6910
6911
  return 0;
6911
6912
  }
6912
- dummy = stbi__get32be(s);
6913
- dummy = stbi__get32be(s);
6913
+ (void) stbi__get32be(s);
6914
+ (void) stbi__get32be(s);
6914
6915
  depth = stbi__get16be(s);
6915
6916
  if (depth != 16) {
6916
6917
  stbi__rewind( s );
@@ -7237,6 +7238,8 @@ STBIDEF int stbi_is_16_bit_from_callbacks(stbi_io_callbacks const *c, void *user
7237
7238
 
7238
7239
  /*
7239
7240
  revision history:
7241
+ 2.19 (2018-02-11) fix warning
7242
+ 2.18 (2018-01-30) fix warnings
7240
7243
  2.17 (2018-01-29) change sbti__shiftsigned to avoid clang -O2 bug
7241
7244
  1-bit BMP
7242
7245
  *_is_16_bit api
@@ -1,4 +1,4 @@
1
- /* stb_image_write - v1.08 - public domain - http://nothings.org/stb/stb_image_write.h
1
+ /* stb_image_write - v1.09 - public domain - http://nothings.org/stb/stb_image_write.h
2
2
  writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
3
3
  no warranty implied; use at your own risk
4
4
 
@@ -45,8 +45,8 @@ USAGE:
45
45
  int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
46
46
  int stbi_write_bmp(char const *filename, int w, int h, int comp, const void *data);
47
47
  int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
48
+ int stbi_write_jpg(char const *filename, int w, int h, int comp, const void *data, int quality);
48
49
  int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
49
- int stbi_write_jpg(char const *filename, int w, int h, int comp, const float *data, int quality);
50
50
 
51
51
  void stbi_flip_vertically_on_write(int flag); // flag is non-zero to flip data vertically
52
52
 
@@ -95,7 +95,7 @@ USAGE:
95
95
  at the end of the line.)
96
96
 
97
97
  PNG allows you to set the deflate compression level by setting the global
98
- variable 'stbi_write_png_level' (it defaults to 8).
98
+ variable 'stbi_write_png_compression_level' (it defaults to 8).
99
99
 
100
100
  HDR expects linear float data. Since the format is always 32-bit rgb(e)
101
101
  data, alpha (if provided) is discarded, and for monochrome data it is
@@ -133,7 +133,12 @@ CREDITS:
133
133
  github:poppolopoppo
134
134
  Patrick Boettcher
135
135
  github:xeekworx
136
-
136
+ Cap Petschulat
137
+ Simon Rodriguez
138
+ Ivan Tikhonov
139
+ github:ignotion
140
+ Adam Schackart
141
+
137
142
  LICENSE
138
143
 
139
144
  See end of file for license information.
@@ -143,19 +148,24 @@ LICENSE
143
148
  #ifndef INCLUDE_STB_IMAGE_WRITE_H
144
149
  #define INCLUDE_STB_IMAGE_WRITE_H
145
150
 
146
- #ifdef __cplusplus
147
- extern "C" {
148
- #endif
149
-
151
+ // if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline'
152
+ #ifndef STBIWDEF
150
153
  #ifdef STB_IMAGE_WRITE_STATIC
151
- #define STBIWDEF static
154
+ #define STBIWDEF static
152
155
  #else
153
- #define STBIWDEF extern
156
+ #ifdef __cplusplus
157
+ #define STBIWDEF extern "C"
158
+ #else
159
+ #define STBIWDEF extern
160
+ #endif
161
+ #endif
154
162
  #endif
155
163
 
156
- STBIWDEF int stbi_write_tga_with_rle;
157
- STBIWDEF int stbi_write_png_comperssion_level;
158
- STBIWDEF int stbi_write_force_png_filter;
164
+ #ifndef STB_IMAGE_WRITE_STATIC // C++ forbids static forward declarations
165
+ extern int stbi_write_tga_with_rle;
166
+ extern int stbi_write_png_compression_level;
167
+ extern int stbi_write_force_png_filter;
168
+ #endif
159
169
 
160
170
  #ifndef STBI_WRITE_NO_STDIO
161
171
  STBIWDEF int stbi_write_png(char const *filename, int w, int h, int comp, const void *data, int stride_in_bytes);
@@ -175,10 +185,6 @@ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x,
175
185
 
176
186
  STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
177
187
 
178
- #ifdef __cplusplus
179
- }
180
- #endif
181
-
182
188
  #endif//INCLUDE_STB_IMAGE_WRITE_H
183
189
 
184
190
  #ifdef STB_IMAGE_WRITE_IMPLEMENTATION
@@ -233,8 +239,8 @@ STBIWDEF void stbi_flip_vertically_on_write(int flip_boolean);
233
239
  #define STBIW_UCHAR(x) (unsigned char) ((x) & 0xff)
234
240
 
235
241
  #ifdef STB_IMAGE_WRITE_STATIC
236
- static stbi__flip_vertically_on_write=0;
237
- static int stbi_write_png_compression level = 8;
242
+ static int stbi__flip_vertically_on_write=0;
243
+ static int stbi_write_png_compression_level = 8;
238
244
  static int stbi_write_tga_with_rle = 1;
239
245
  static int stbi_write_force_png_filter = -1;
240
246
  #else
@@ -987,13 +993,14 @@ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int
987
993
  int i;
988
994
  int type = mymap[filter_type];
989
995
  unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y);
996
+ int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes;
990
997
  for (i = 0; i < n; ++i) {
991
998
  switch (type) {
992
999
  case 0: line_buffer[i] = z[i]; break;
993
1000
  case 1: line_buffer[i] = z[i]; break;
994
- case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
995
- case 3: line_buffer[i] = z[i] - (z[i-stride_bytes]>>1); break;
996
- case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-stride_bytes],0)); break;
1001
+ case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break;
1002
+ case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break;
1003
+ case 4: line_buffer[i] = (signed char) (z[i] - stbiw__paeth(0,z[i-signed_stride],0)); break;
997
1004
  case 5: line_buffer[i] = z[i]; break;
998
1005
  case 6: line_buffer[i] = z[i]; break;
999
1006
  }
@@ -1002,9 +1009,9 @@ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int
1002
1009
  switch (type) {
1003
1010
  case 0: line_buffer[i] = z[i]; break;
1004
1011
  case 1: line_buffer[i] = z[i] - z[i-n]; break;
1005
- case 2: line_buffer[i] = z[i] - z[i-stride_bytes]; break;
1006
- case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-stride_bytes])>>1); break;
1007
- case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-stride_bytes], z[i-stride_bytes-n]); break;
1012
+ case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break;
1013
+ case 3: line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break;
1014
+ case 4: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break;
1008
1015
  case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
1009
1016
  case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
1010
1017
  }
@@ -1476,6 +1483,8 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
1476
1483
  #endif // STB_IMAGE_WRITE_IMPLEMENTATION
1477
1484
 
1478
1485
  /* Revision history
1486
+ 1.09 (2018-02-11)
1487
+ fix typo in zlib quality API, improve STB_I_W_STATIC in C++
1479
1488
  1.08 (2018-01-29)
1480
1489
  add stbi__flip_vertically_on_write, external zlib, zlib quality, choose PNG filter
1481
1490
  1.07 (2017-07-24)
data/src/stb_truetype.h CHANGED
@@ -1,4 +1,4 @@
1
- // stb_truetype.h - v1.18 - public domain
1
+ // stb_truetype.h - v1.19 - public domain
2
2
  // authored from 2009-2016 by Sean Barrett / RAD Game Tools
3
3
  //
4
4
  // This library processes TrueType files:
@@ -22,12 +22,14 @@
22
22
  // Mikko Mononen: compound shape support, more cmap formats
23
23
  // Tor Andersson: kerning, subpixel rendering
24
24
  // Dougall Johnson: OpenType / Type 2 font handling
25
+ // Daniel Ribeiro Maciel: basic GPOS-based kerning
25
26
  //
26
27
  // Misc other:
27
28
  // Ryan Gordon
28
29
  // Simon Glass
29
30
  // github:IntellectualKitty
30
31
  // Imanol Celaya
32
+ // Daniel Ribeiro Maciel
31
33
  //
32
34
  // Bug/warning reports/fixes:
33
35
  // "Zer" on mollyrocket Fabian "ryg" Giesen
@@ -47,6 +49,7 @@
47
49
  //
48
50
  // VERSION HISTORY
49
51
  //
52
+ // 1.19 (2018-02-11) GPOS kerning, STBTT_fmod
50
53
  // 1.18 (2018-01-29) add missing function
51
54
  // 1.17 (2017-07-23) make more arguments const; doc fix
52
55
  // 1.16 (2017-07-12) SDF support
@@ -411,7 +414,8 @@ int main(int arg, char **argv)
411
414
  //// INTEGRATION WITH YOUR CODEBASE
412
415
  ////
413
416
  //// The following sections allow you to supply alternate definitions
414
- //// of C library functions used by stb_truetype.
417
+ //// of C library functions used by stb_truetype, e.g. if you don't
418
+ //// link with the C runtime library.
415
419
 
416
420
  #ifdef STB_TRUETYPE_IMPLEMENTATION
417
421
  // #define your own (u)stbtt_int8/16/32 before including to override this
@@ -427,7 +431,7 @@ int main(int arg, char **argv)
427
431
  typedef char stbtt__check_size32[sizeof(stbtt_int32)==4 ? 1 : -1];
428
432
  typedef char stbtt__check_size16[sizeof(stbtt_int16)==2 ? 1 : -1];
429
433
 
430
- // #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
434
+ // e.g. #define your own STBTT_ifloor/STBTT_iceil() to avoid math.h
431
435
  #ifndef STBTT_ifloor
432
436
  #include <math.h>
433
437
  #define STBTT_ifloor(x) ((int) floor(x))
@@ -440,6 +444,11 @@ int main(int arg, char **argv)
440
444
  #define STBTT_pow(x,y) pow(x,y)
441
445
  #endif
442
446
 
447
+ #ifndef STBTT_fmod
448
+ #include <math.h>
449
+ #define STBTT_fmod(x,y) fmod(x,y)
450
+ #endif
451
+
443
452
  #ifndef STBTT_cos
444
453
  #include <math.h>
445
454
  #define STBTT_cos(x) cos(x)
@@ -695,7 +704,7 @@ struct stbtt_fontinfo
695
704
 
696
705
  int numGlyphs; // number of glyphs, needed for range checking
697
706
 
698
- int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf
707
+ int loca,head,glyf,hhea,hmtx,kern,gpos; // table locations as offset from start of .ttf
699
708
  int index_map; // a cmap mapping for our chosen character encoding
700
709
  int indexToLocFormat; // format needed to map from glyph index to glyph
701
710
 
@@ -1338,6 +1347,7 @@ static int stbtt_InitFont_internal(stbtt_fontinfo *info, unsigned char *data, in
1338
1347
  info->hhea = stbtt__find_table(data, fontstart, "hhea"); // required
1339
1348
  info->hmtx = stbtt__find_table(data, fontstart, "hmtx"); // required
1340
1349
  info->kern = stbtt__find_table(data, fontstart, "kern"); // not required
1350
+ info->gpos = stbtt__find_table(data, fontstart, "GPOS"); // not required
1341
1351
 
1342
1352
  if (!cmap || !info->head || !info->hhea || !info->hmtx)
1343
1353
  return 0;
@@ -2256,7 +2266,7 @@ STBTT_DEF void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *info, int glyph_inde
2256
2266
  }
2257
2267
  }
2258
2268
 
2259
- STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
2269
+ static int stbtt__GetGlyphKernInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
2260
2270
  {
2261
2271
  stbtt_uint8 *data = info->data + info->kern;
2262
2272
  stbtt_uint32 needle, straw;
@@ -2286,9 +2296,260 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int glyph1,
2286
2296
  return 0;
2287
2297
  }
2288
2298
 
2299
+ static stbtt_int32 stbtt__GetCoverageIndex(stbtt_uint8 *coverageTable, int glyph)
2300
+ {
2301
+ stbtt_uint16 coverageFormat = ttUSHORT(coverageTable);
2302
+ switch(coverageFormat) {
2303
+ case 1: {
2304
+ stbtt_uint16 glyphCount = ttUSHORT(coverageTable + 2);
2305
+
2306
+ // Binary search.
2307
+ stbtt_int32 l=0, r=glyphCount-1, m;
2308
+ int straw, needle=glyph;
2309
+ while (l <= r) {
2310
+ stbtt_uint8 *glyphArray = coverageTable + 4;
2311
+ stbtt_uint16 glyphID;
2312
+ m = (l + r) >> 1;
2313
+ glyphID = ttUSHORT(glyphArray + 2 * m);
2314
+ straw = glyphID;
2315
+ if (needle < straw)
2316
+ r = m - 1;
2317
+ else if (needle > straw)
2318
+ l = m + 1;
2319
+ else {
2320
+ return m;
2321
+ }
2322
+ }
2323
+ } break;
2324
+
2325
+ case 2: {
2326
+ stbtt_uint16 rangeCount = ttUSHORT(coverageTable + 2);
2327
+ stbtt_uint8 *rangeArray = coverageTable + 4;
2328
+
2329
+ // Binary search.
2330
+ stbtt_int32 l=0, r=rangeCount-1, m;
2331
+ int strawStart, strawEnd, needle=glyph;
2332
+ while (l <= r) {
2333
+ stbtt_uint8 *rangeRecord;
2334
+ m = (l + r) >> 1;
2335
+ rangeRecord = rangeArray + 6 * m;
2336
+ strawStart = ttUSHORT(rangeRecord);
2337
+ strawEnd = ttUSHORT(rangeRecord + 2);
2338
+ if (needle < strawStart)
2339
+ r = m - 1;
2340
+ else if (needle > strawEnd)
2341
+ l = m + 1;
2342
+ else {
2343
+ stbtt_uint16 startCoverageIndex = ttUSHORT(rangeRecord + 4);
2344
+ return startCoverageIndex + glyph - strawStart;
2345
+ }
2346
+ }
2347
+ } break;
2348
+
2349
+ default: {
2350
+ // There are no other cases.
2351
+ STBTT_assert(0);
2352
+ } break;
2353
+ }
2354
+
2355
+ return -1;
2356
+ }
2357
+
2358
+ static stbtt_int32 stbtt__GetGlyphClass(stbtt_uint8 *classDefTable, int glyph)
2359
+ {
2360
+ stbtt_uint16 classDefFormat = ttUSHORT(classDefTable);
2361
+ switch(classDefFormat)
2362
+ {
2363
+ case 1: {
2364
+ stbtt_uint16 startGlyphID = ttUSHORT(classDefTable + 2);
2365
+ stbtt_uint16 glyphCount = ttUSHORT(classDefTable + 4);
2366
+ stbtt_uint8 *classDef1ValueArray = classDefTable + 6;
2367
+
2368
+ if (glyph >= startGlyphID && glyph < startGlyphID + glyphCount)
2369
+ return (stbtt_int32)ttUSHORT(classDef1ValueArray + 2 * (glyph - startGlyphID));
2370
+
2371
+ classDefTable = classDef1ValueArray + 2 * glyphCount;
2372
+ } break;
2373
+
2374
+ case 2: {
2375
+ stbtt_uint16 classRangeCount = ttUSHORT(classDefTable + 2);
2376
+ stbtt_uint8 *classRangeRecords = classDefTable + 4;
2377
+
2378
+ // Binary search.
2379
+ stbtt_int32 l=0, r=classRangeCount-1, m;
2380
+ int strawStart, strawEnd, needle=glyph;
2381
+ while (l <= r) {
2382
+ stbtt_uint8 *classRangeRecord;
2383
+ m = (l + r) >> 1;
2384
+ classRangeRecord = classRangeRecords + 6 * m;
2385
+ strawStart = ttUSHORT(classRangeRecord);
2386
+ strawEnd = ttUSHORT(classRangeRecord + 2);
2387
+ if (needle < strawStart)
2388
+ r = m - 1;
2389
+ else if (needle > strawEnd)
2390
+ l = m + 1;
2391
+ else
2392
+ return (stbtt_int32)ttUSHORT(classRangeRecord + 4);
2393
+ }
2394
+
2395
+ classDefTable = classRangeRecords + 6 * classRangeCount;
2396
+ } break;
2397
+
2398
+ default: {
2399
+ // There are no other cases.
2400
+ STBTT_assert(0);
2401
+ } break;
2402
+ }
2403
+
2404
+ return -1;
2405
+ }
2406
+
2407
+ // Define to STBTT_assert(x) if you want to break on unimplemented formats.
2408
+ #define STBTT_GPOS_TODO_assert(x)
2409
+
2410
+ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, int glyph1, int glyph2)
2411
+ {
2412
+ stbtt_uint16 lookupListOffset;
2413
+ stbtt_uint8 *lookupList;
2414
+ stbtt_uint16 lookupCount;
2415
+ stbtt_uint8 *data;
2416
+ stbtt_int32 i;
2417
+
2418
+ if (!info->gpos) return 0;
2419
+
2420
+ data = info->data + info->gpos;
2421
+
2422
+ if (ttUSHORT(data+0) != 1) return 0; // Major version 1
2423
+ if (ttUSHORT(data+2) != 0) return 0; // Minor version 0
2424
+
2425
+ lookupListOffset = ttUSHORT(data+8);
2426
+ lookupList = data + lookupListOffset;
2427
+ lookupCount = ttUSHORT(lookupList);
2428
+
2429
+ for (i=0; i<lookupCount; ++i) {
2430
+ stbtt_uint16 lookupOffset = ttUSHORT(lookupList + 2 + 2 * i);
2431
+ stbtt_uint8 *lookupTable = lookupList + lookupOffset;
2432
+
2433
+ stbtt_uint16 lookupType = ttUSHORT(lookupTable);
2434
+ stbtt_uint16 subTableCount = ttUSHORT(lookupTable + 4);
2435
+ stbtt_uint8 *subTableOffsets = lookupTable + 6;
2436
+ switch(lookupType) {
2437
+ case 2: { // Pair Adjustment Positioning Subtable
2438
+ stbtt_int32 sti;
2439
+ for (sti=0; sti<subTableCount; sti++) {
2440
+ stbtt_uint16 subtableOffset = ttUSHORT(subTableOffsets + 2 * sti);
2441
+ stbtt_uint8 *table = lookupTable + subtableOffset;
2442
+ stbtt_uint16 posFormat = ttUSHORT(table);
2443
+ stbtt_uint16 coverageOffset = ttUSHORT(table + 2);
2444
+ stbtt_int32 coverageIndex = stbtt__GetCoverageIndex(table + coverageOffset, glyph1);
2445
+ if (coverageIndex == -1) continue;
2446
+
2447
+ switch (posFormat) {
2448
+ case 1: {
2449
+ stbtt_int32 l, r, m;
2450
+ int straw, needle;
2451
+ stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
2452
+ stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
2453
+ stbtt_int32 valueRecordPairSizeInBytes = 2;
2454
+ stbtt_uint16 pairSetCount = ttUSHORT(table + 8);
2455
+ stbtt_uint16 pairPosOffset = ttUSHORT(table + 10 + 2 * coverageIndex);
2456
+ stbtt_uint8 *pairValueTable = table + pairPosOffset;
2457
+ stbtt_uint16 pairValueCount = ttUSHORT(pairValueTable);
2458
+ stbtt_uint8 *pairValueArray = pairValueTable + 2;
2459
+ // TODO: Support more formats.
2460
+ STBTT_GPOS_TODO_assert(valueFormat1 == 4);
2461
+ if (valueFormat1 != 4) return 0;
2462
+ STBTT_GPOS_TODO_assert(valueFormat2 == 0);
2463
+ if (valueFormat2 != 0) return 0;
2464
+
2465
+ STBTT_assert(coverageIndex < pairSetCount);
2466
+
2467
+ needle=glyph2;
2468
+ r=pairValueCount-1;
2469
+ l=0;
2470
+
2471
+ // Binary search.
2472
+ while (l <= r) {
2473
+ stbtt_uint16 secondGlyph;
2474
+ stbtt_uint8 *pairValue;
2475
+ m = (l + r) >> 1;
2476
+ pairValue = pairValueArray + (2 + valueRecordPairSizeInBytes) * m;
2477
+ secondGlyph = ttUSHORT(pairValue);
2478
+ straw = secondGlyph;
2479
+ if (needle < straw)
2480
+ r = m - 1;
2481
+ else if (needle > straw)
2482
+ l = m + 1;
2483
+ else {
2484
+ stbtt_int16 xAdvance = ttSHORT(pairValue + 2);
2485
+ return xAdvance;
2486
+ }
2487
+ }
2488
+ } break;
2489
+
2490
+ case 2: {
2491
+ stbtt_uint16 valueFormat1 = ttUSHORT(table + 4);
2492
+ stbtt_uint16 valueFormat2 = ttUSHORT(table + 6);
2493
+
2494
+ stbtt_uint16 classDef1Offset = ttUSHORT(table + 8);
2495
+ stbtt_uint16 classDef2Offset = ttUSHORT(table + 10);
2496
+ int glyph1class = stbtt__GetGlyphClass(table + classDef1Offset, glyph1);
2497
+ int glyph2class = stbtt__GetGlyphClass(table + classDef2Offset, glyph2);
2498
+
2499
+ stbtt_uint16 class1Count = ttUSHORT(table + 12);
2500
+ stbtt_uint16 class2Count = ttUSHORT(table + 14);
2501
+ STBTT_assert(glyph1class < class1Count);
2502
+ STBTT_assert(glyph2class < class2Count);
2503
+
2504
+ // TODO: Support more formats.
2505
+ STBTT_GPOS_TODO_assert(valueFormat1 == 4);
2506
+ if (valueFormat1 != 4) return 0;
2507
+ STBTT_GPOS_TODO_assert(valueFormat2 == 0);
2508
+ if (valueFormat2 != 0) return 0;
2509
+
2510
+ if (glyph1class >= 0 && glyph1class < class1Count && glyph2class >= 0 && glyph2class < class2Count) {
2511
+ stbtt_uint8 *class1Records = table + 16;
2512
+ stbtt_uint8 *class2Records = class1Records + 2 * (glyph1class * class2Count);
2513
+ stbtt_int16 xAdvance = ttSHORT(class2Records + 2 * glyph2class);
2514
+ return xAdvance;
2515
+ }
2516
+ } break;
2517
+
2518
+ default: {
2519
+ // There are no other cases.
2520
+ STBTT_assert(0);
2521
+ break;
2522
+ };
2523
+ }
2524
+ }
2525
+ break;
2526
+ };
2527
+
2528
+ default:
2529
+ // TODO: Implement other stuff.
2530
+ break;
2531
+ }
2532
+ }
2533
+
2534
+ return 0;
2535
+ }
2536
+
2537
+ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int g2)
2538
+ {
2539
+ int xAdvance = 0;
2540
+
2541
+ if (info->gpos)
2542
+ xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
2543
+
2544
+ if (info->kern)
2545
+ xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
2546
+
2547
+ return xAdvance;
2548
+ }
2549
+
2289
2550
  STBTT_DEF int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *info, int ch1, int ch2)
2290
2551
  {
2291
- if (!info->kern) // if no kerning table, don't waste time looking up both codepoint->glyphs
2552
+ if (!info->kern && !info->gpos) // if no kerning table, don't waste time looking up both codepoint->glyphs
2292
2553
  return 0;
2293
2554
  return stbtt_GetGlyphKernAdvance(info, stbtt_FindGlyphIndex(info,ch1), stbtt_FindGlyphIndex(info,ch2));
2294
2555
  }
@@ -3932,7 +4193,7 @@ static int stbtt__ray_intersect_bezier(float orig[2], float ray[2], float q0[2],
3932
4193
  float discr = b*b - a*c;
3933
4194
  if (discr > 0.0) {
3934
4195
  float rcpna = -1 / a;
3935
- float d = (float) sqrt(discr);
4196
+ float d = (float) STBTT_sqrt(discr);
3936
4197
  s0 = (b+d) * rcpna;
3937
4198
  s1 = (b-d) * rcpna;
3938
4199
  if (s0 >= 0.0 && s0 <= 1.0)
@@ -3994,7 +4255,7 @@ static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex
3994
4255
  orig[1] = y;
3995
4256
 
3996
4257
  // make sure y never passes through a vertex of the shape
3997
- y_frac = (float) fmod(y, 1.0f);
4258
+ y_frac = (float) STBTT_fmod(y, 1.0f);
3998
4259
  if (y_frac < 0.01f)
3999
4260
  y += 0.01f;
4000
4261
  else if (y_frac > 0.99f)
@@ -4494,6 +4755,9 @@ STBTT_DEF int stbtt_CompareUTF8toUTF16_bigendian(const char *s1, int len1, const
4494
4755
 
4495
4756
  // FULL VERSION HISTORY
4496
4757
  //
4758
+ // 1.19 (2018-02-11) OpenType GPOS kerning (horizontal only), STBTT_fmod
4759
+ // 1.18 (2018-01-29) add missing function
4760
+ // 1.17 (2017-07-23) make more arguments const; doc fix
4497
4761
  // 1.16 (2017-07-12) SDF support
4498
4762
  // 1.15 (2017-03-03) make more arguments const
4499
4763
  // 1.14 (2017-01-16) num-fonts-in-TTC function