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.
@@ -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