gosu 0.14.5 → 0.15.2

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.
Files changed (51) hide show
  1. checksums.yaml +4 -4
  2. data/.yardopts +1 -0
  3. data/COPYING +1 -1
  4. data/Gosu/Channel.h +25 -0
  5. data/Gosu/Color.h +38 -0
  6. data/Gosu/Font.h +36 -0
  7. data/Gosu/Gosu.h +79 -0
  8. data/Gosu/Image.h +54 -0
  9. data/Gosu/Sample.h +19 -0
  10. data/Gosu/Song.h +24 -0
  11. data/Gosu/TextInput.h +30 -0
  12. data/Gosu/Version.hpp +2 -2
  13. data/Gosu/Window.h +61 -0
  14. data/Gosu/Window.hpp +3 -2
  15. data/README.md +1 -1
  16. data/ext/gosu/extconf.rb +3 -0
  17. data/lib/gosu/compat.rb +12 -7
  18. data/lib/gosu/patches.rb +8 -2
  19. data/lib/gosu/swig_patches.rb +20 -9
  20. data/rdoc/gosu.rb +28 -7
  21. data/src/ChannelWrapper.cpp +50 -0
  22. data/src/ColorWrapper.cpp +126 -0
  23. data/src/Constants.cpp +287 -0
  24. data/src/Font.cpp +1 -0
  25. data/src/FontWrapper.cpp +74 -0
  26. data/src/GosuWrapper.cpp +232 -0
  27. data/src/Graphics.cpp +4 -1
  28. data/src/GraphicsImpl.hpp +0 -1
  29. data/src/ImageWrapper.cpp +168 -0
  30. data/src/LargeImageData.cpp +1 -0
  31. data/src/MarkupParser.cpp +11 -3
  32. data/src/RubyGosu.cxx +185 -121
  33. data/src/RubyGosu.h +2 -2
  34. data/src/SampleWrapper.cpp +30 -0
  35. data/src/SongWrapper.cpp +52 -0
  36. data/src/TexChunk.cpp +29 -19
  37. data/src/Text.cpp +2 -0
  38. data/src/TextBuilder.cpp +3 -3
  39. data/src/TextInputWrapper.cpp +101 -0
  40. data/src/TrueTypeFont.cpp +1 -0
  41. data/src/Window.cpp +62 -28
  42. data/src/WindowUIKit.cpp +8 -4
  43. data/src/WindowWrapper.cpp +289 -0
  44. data/src/stb_image.h +153 -56
  45. data/src/stb_image_write.h +111 -60
  46. data/src/stb_truetype.h +74 -39
  47. data/src/stb_vorbis.c +55 -15
  48. data/src/utf8proc.c +47 -29
  49. data/src/utf8proc.h +46 -24
  50. data/src/utf8proc_data.h +10043 -9609
  51. metadata +23 -4
@@ -1,4 +1,4 @@
1
- /* stb_image_write - v1.09 - public domain - http://nothings.org/stb/stb_image_write.h
1
+ /* stb_image_write - v1.13 - public domain - http://nothings.org/stb
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
 
@@ -10,15 +10,9 @@
10
10
 
11
11
  Will probably not work correctly with strict-aliasing optimizations.
12
12
 
13
- If using a modern Microsoft Compiler, non-safe versions of CRT calls may cause
14
- compilation warnings or even errors. To avoid this, also before #including,
15
-
16
- #define STBI_MSC_SECURE_CRT
17
-
18
13
  ABOUT:
19
14
 
20
- This header file is a library for writing images to C stdio. It could be
21
- adapted to write to memory or a general streaming interface; let me know.
15
+ This header file is a library for writing images to C stdio or a callback.
22
16
 
23
17
  The PNG output is not optimal; it is 20-50% larger than the file
24
18
  written by a decent optimizing implementation; though providing a custom
@@ -38,6 +32,14 @@ BUILDING:
38
32
  The returned data will be freed with STBIW_FREE() (free() by default),
39
33
  so it must be heap allocated with STBIW_MALLOC() (malloc() by default),
40
34
 
35
+ UNICODE:
36
+
37
+ If compiling for Windows and you wish to use Unicode filenames, compile
38
+ with
39
+ #define STBIW_WINDOWS_UTF8
40
+ and pass utf8-encoded filenames. Call stbiw_convert_wchar_to_utf8 to convert
41
+ Windows wchar_t filenames to utf8.
42
+
41
43
  USAGE:
42
44
 
43
45
  There are five functions, one for each image file format:
@@ -148,6 +150,8 @@ LICENSE
148
150
  #ifndef INCLUDE_STB_IMAGE_WRITE_H
149
151
  #define INCLUDE_STB_IMAGE_WRITE_H
150
152
 
153
+ #include <stdlib.h>
154
+
151
155
  // if STB_IMAGE_WRITE_STATIC causes problems, try defining STBIWDEF to 'inline' or 'static inline'
152
156
  #ifndef STBIWDEF
153
157
  #ifdef STB_IMAGE_WRITE_STATIC
@@ -173,6 +177,10 @@ STBIWDEF int stbi_write_bmp(char const *filename, int w, int h, int comp, const
173
177
  STBIWDEF int stbi_write_tga(char const *filename, int w, int h, int comp, const void *data);
174
178
  STBIWDEF int stbi_write_hdr(char const *filename, int w, int h, int comp, const float *data);
175
179
  STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality);
180
+
181
+ #ifdef STBI_WINDOWS_UTF8
182
+ STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input);
183
+ #endif
176
184
  #endif
177
185
 
178
186
  typedef void stbi_write_func(void *context, void *data, int size);
@@ -275,15 +283,52 @@ static void stbi__stdio_write(void *context, void *data, int size)
275
283
  fwrite(data,1,size,(FILE*) context);
276
284
  }
277
285
 
278
- static int stbi__start_write_file(stbi__write_context *s, const char *filename)
286
+ #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
287
+ #ifdef __cplusplus
288
+ #define STBIW_EXTERN extern "C"
289
+ #else
290
+ #define STBIW_EXTERN extern
291
+ #endif
292
+ STBIW_EXTERN __declspec(dllimport) int __stdcall MultiByteToWideChar(unsigned int cp, unsigned long flags, const char *str, int cbmb, wchar_t *widestr, int cchwide);
293
+ STBIW_EXTERN __declspec(dllimport) int __stdcall WideCharToMultiByte(unsigned int cp, unsigned long flags, const wchar_t *widestr, int cchwide, char *str, int cbmb, const char *defchar, int *used_default);
294
+
295
+ STBIWDEF int stbiw_convert_wchar_to_utf8(char *buffer, size_t bufferlen, const wchar_t* input)
296
+ {
297
+ return WideCharToMultiByte(65001 /* UTF8 */, 0, input, -1, buffer, (int) bufferlen, NULL, NULL);
298
+ }
299
+ #endif
300
+
301
+ static FILE *stbiw__fopen(char const *filename, char const *mode)
279
302
  {
280
303
  FILE *f;
281
- #ifdef STBI_MSC_SECURE_CRT
282
- if (fopen_s(&f, filename, "wb"))
283
- f = NULL;
304
+ #if defined(_MSC_VER) && defined(STBI_WINDOWS_UTF8)
305
+ wchar_t wMode[64];
306
+ wchar_t wFilename[1024];
307
+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, filename, -1, wFilename, sizeof(wFilename)))
308
+ return 0;
309
+
310
+ if (0 == MultiByteToWideChar(65001 /* UTF8 */, 0, mode, -1, wMode, sizeof(wMode)))
311
+ return 0;
312
+
313
+ #if _MSC_VER >= 1400
314
+ if (0 != _wfopen_s(&f, wFilename, wMode))
315
+ f = 0;
316
+ #else
317
+ f = _wfopen(wFilename, wMode);
318
+ #endif
319
+
320
+ #elif defined(_MSC_VER) && _MSC_VER >= 1400
321
+ if (0 != fopen_s(&f, filename, mode))
322
+ f=0;
284
323
  #else
285
- f = fopen(filename, "wb");
324
+ f = fopen(filename, mode);
286
325
  #endif
326
+ return f;
327
+ }
328
+
329
+ static int stbi__start_write_file(stbi__write_context *s, const char *filename)
330
+ {
331
+ FILE *f = stbiw__fopen(filename, "wb");
287
332
  stbi__start_write_callbacks(s, stbi__stdio_write, (void *) f);
288
333
  return f != NULL;
289
334
  }
@@ -343,7 +388,7 @@ static void stbiw__putc(stbi__write_context *s, unsigned char c)
343
388
  static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
344
389
  {
345
390
  unsigned char arr[3];
346
- arr[0] = a, arr[1] = b, arr[2] = c;
391
+ arr[0] = a; arr[1] = b; arr[2] = c;
347
392
  s->func(s->context, arr, 3);
348
393
  }
349
394
 
@@ -391,10 +436,11 @@ static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, i
391
436
  if (stbi__flip_vertically_on_write)
392
437
  vdir *= -1;
393
438
 
394
- if (vdir < 0)
395
- j_end = -1, j = y-1;
396
- else
397
- j_end = y, j = 0;
439
+ if (vdir < 0) {
440
+ j_end = -1; j = y-1;
441
+ } else {
442
+ j_end = y; j = 0;
443
+ }
398
444
 
399
445
  for (; j != j_end; j += vdir) {
400
446
  for (i=0; i < x; ++i) {
@@ -552,7 +598,7 @@ STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const
552
598
 
553
599
  #define stbiw__max(a, b) ((a) > (b) ? (a) : (b))
554
600
 
555
- void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
601
+ static void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
556
602
  {
557
603
  int exponent;
558
604
  float maxcomp = stbiw__max(linear[0], stbiw__max(linear[1], linear[2]));
@@ -569,7 +615,7 @@ void stbiw__linear_to_rgbe(unsigned char *rgbe, float *linear)
569
615
  }
570
616
  }
571
617
 
572
- void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
618
+ static void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char databyte)
573
619
  {
574
620
  unsigned char lengthbyte = STBIW_UCHAR(length+128);
575
621
  STBIW_ASSERT(length+128 <= 255);
@@ -577,7 +623,7 @@ void stbiw__write_run_data(stbi__write_context *s, int length, unsigned char dat
577
623
  s->func(s->context, &databyte, 1);
578
624
  }
579
625
 
580
- void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
626
+ static void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *data)
581
627
  {
582
628
  unsigned char lengthbyte = STBIW_UCHAR(length);
583
629
  STBIW_ASSERT(length <= 128); // inconsistent with spec but consistent with official code
@@ -585,7 +631,7 @@ void stbiw__write_dump_data(stbi__write_context *s, int length, unsigned char *d
585
631
  s->func(s->context, data, length);
586
632
  }
587
633
 
588
- void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
634
+ static void stbiw__write_hdr_scanline(stbi__write_context *s, int width, int ncomp, unsigned char *scratch, float *scanline)
589
635
  {
590
636
  unsigned char scanlineheader[4] = { 2, 2, 0, 0 };
591
637
  unsigned char rgbe[4];
@@ -686,15 +732,15 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
686
732
  char header[] = "#?RADIANCE\n# Written by stb_image_write.h\nFORMAT=32-bit_rle_rgbe\n";
687
733
  s->func(s->context, header, sizeof(header)-1);
688
734
 
689
- #ifdef STBI_MSC_SECURE_CRT
690
- len = sprintf_s(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
735
+ #ifdef __STDC_WANT_SECURE_LIB__
736
+ len = sprintf_s(buffer, sizeof(buffer), "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
691
737
  #else
692
738
  len = sprintf(buffer, "EXPOSURE= 1.0000000000000\n\n-Y %d +X %d\n", y, x);
693
739
  #endif
694
740
  s->func(s->context, buffer, len);
695
741
 
696
742
  for(i=0; i < y; i++)
697
- stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i)*x);
743
+ stbiw__write_hdr_scanline(s, x, comp, scratch, data + comp*x*(stbi__flip_vertically_on_write ? y-1-i : i));
698
744
  STBIW_FREE(scratch);
699
745
  return 1;
700
746
  }
@@ -809,7 +855,7 @@ static unsigned int stbiw__zhash(unsigned char *data)
809
855
 
810
856
  #endif // STBIW_ZLIB_COMPRESS
811
857
 
812
- unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
858
+ STBIWDEF unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_len, int quality)
813
859
  {
814
860
  #ifdef STBIW_ZLIB_COMPRESS
815
861
  // user provided a zlib compress implementation, use that
@@ -822,7 +868,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
822
868
  unsigned int bitbuf=0;
823
869
  int i,j, bitcount=0;
824
870
  unsigned char *out = NULL;
825
- unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(char**));
871
+ unsigned char ***hash_table = (unsigned char***) STBIW_MALLOC(stbiw__ZHASH * sizeof(unsigned char**));
826
872
  if (hash_table == NULL)
827
873
  return NULL;
828
874
  if (quality < 5) quality = 5;
@@ -845,7 +891,7 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
845
891
  for (j=0; j < n; ++j) {
846
892
  if (hlist[j]-data > i-32768) { // if entry lies within window
847
893
  int d = stbiw__zlib_countm(hlist[j], data+i, data_len-i);
848
- if (d >= best) best=d,bestloc=hlist[j];
894
+ if (d >= best) { best=d; bestloc=hlist[j]; }
849
895
  }
850
896
  }
851
897
  // when hash table entry is too long, delete half the entries
@@ -904,8 +950,8 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
904
950
  int blocklen = (int) (data_len % 5552);
905
951
  j=0;
906
952
  while (j < data_len) {
907
- for (i=0; i < blocklen; ++i) s1 += data[j+i], s2 += s1;
908
- s1 %= 65521, s2 %= 65521;
953
+ for (i=0; i < blocklen; ++i) { s1 += data[j+i]; s2 += s1; }
954
+ s1 %= 65521; s2 %= 65521;
909
955
  j += blocklen;
910
956
  blocklen = 5552;
911
957
  }
@@ -923,6 +969,9 @@ unsigned char * stbi_zlib_compress(unsigned char *data, int data_len, int *out_l
923
969
 
924
970
  static unsigned int stbiw__crc32(unsigned char *buffer, int len)
925
971
  {
972
+ #ifdef STBIW_CRC32
973
+ return STBIW_CRC32(buffer, len);
974
+ #else
926
975
  static unsigned int crc_table[256] =
927
976
  {
928
977
  0x00000000, 0x77073096, 0xEE0E612C, 0x990951BA, 0x076DC419, 0x706AF48F, 0xE963A535, 0x9E6495A3,
@@ -964,6 +1013,7 @@ static unsigned int stbiw__crc32(unsigned char *buffer, int len)
964
1013
  for (i=0; i < len; ++i)
965
1014
  crc = (crc >> 8) ^ crc_table[buffer[i] ^ (crc & 0xff)];
966
1015
  return ~crc;
1016
+ #endif
967
1017
  }
968
1018
 
969
1019
  #define stbiw__wpng4(o,a,b,c,d) ((o)[0]=STBIW_UCHAR(a),(o)[1]=STBIW_UCHAR(b),(o)[2]=STBIW_UCHAR(c),(o)[3]=STBIW_UCHAR(d),(o)+=4)
@@ -994,9 +1044,15 @@ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int
994
1044
  int type = mymap[filter_type];
995
1045
  unsigned char *z = pixels + stride_bytes * (stbi__flip_vertically_on_write ? height-1-y : y);
996
1046
  int signed_stride = stbi__flip_vertically_on_write ? -stride_bytes : stride_bytes;
1047
+
1048
+ if (type==0) {
1049
+ memcpy(line_buffer, z, width*n);
1050
+ return;
1051
+ }
1052
+
1053
+ // first loop isn't optimized since it's just one pixel
997
1054
  for (i = 0; i < n; ++i) {
998
1055
  switch (type) {
999
- case 0: line_buffer[i] = z[i]; break;
1000
1056
  case 1: line_buffer[i] = z[i]; break;
1001
1057
  case 2: line_buffer[i] = z[i] - z[i-signed_stride]; break;
1002
1058
  case 3: line_buffer[i] = z[i] - (z[i-signed_stride]>>1); break;
@@ -1005,20 +1061,17 @@ static void stbiw__encode_png_line(unsigned char *pixels, int stride_bytes, int
1005
1061
  case 6: line_buffer[i] = z[i]; break;
1006
1062
  }
1007
1063
  }
1008
- for (i=n; i < width*n; ++i) {
1009
- switch (type) {
1010
- case 0: line_buffer[i] = z[i]; break;
1011
- case 1: line_buffer[i] = z[i] - z[i-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;
1015
- case 5: line_buffer[i] = z[i] - (z[i-n]>>1); break;
1016
- case 6: line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
1017
- }
1064
+ switch (type) {
1065
+ case 1: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-n]; break;
1066
+ case 2: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - z[i-signed_stride]; break;
1067
+ case 3: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - ((z[i-n] + z[i-signed_stride])>>1); break;
1068
+ case 4: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], z[i-signed_stride], z[i-signed_stride-n]); break;
1069
+ case 5: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - (z[i-n]>>1); break;
1070
+ case 6: for (i=n; i < width*n; ++i) line_buffer[i] = z[i] - stbiw__paeth(z[i-n], 0,0); break;
1018
1071
  }
1019
1072
  }
1020
1073
 
1021
- unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
1074
+ STBIWDEF unsigned char *stbi_write_png_to_mem(const unsigned char *pixels, int stride_bytes, int x, int y, int n, int *out_len)
1022
1075
  {
1023
1076
  int force_filter = stbi_write_force_png_filter;
1024
1077
  int ctype[5] = { -1, 0, 4, 2, 6 };
@@ -1040,11 +1093,11 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
1040
1093
  int filter_type;
1041
1094
  if (force_filter > -1) {
1042
1095
  filter_type = force_filter;
1043
- stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, force_filter, line_buffer);
1096
+ stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, force_filter, line_buffer);
1044
1097
  } else { // Estimate the best filter by running through all of them:
1045
1098
  int best_filter = 0, best_filter_val = 0x7fffffff, est, i;
1046
1099
  for (filter_type = 0; filter_type < 5; filter_type++) {
1047
- stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, filter_type, line_buffer);
1100
+ stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, filter_type, line_buffer);
1048
1101
 
1049
1102
  // Estimate the entropy of the line using this filter; the less, the better.
1050
1103
  est = 0;
@@ -1057,7 +1110,7 @@ unsigned char *stbi_write_png_to_mem(unsigned char *pixels, int stride_bytes, in
1057
1110
  }
1058
1111
  }
1059
1112
  if (filter_type != best_filter) { // If the last iteration already got us the best filter, don't redo it
1060
- stbiw__encode_png_line(pixels, stride_bytes, x, y, j, n, best_filter, line_buffer);
1113
+ stbiw__encode_png_line((unsigned char*)(pixels), stride_bytes, x, y, j, n, best_filter, line_buffer);
1061
1114
  filter_type = best_filter;
1062
1115
  }
1063
1116
  }
@@ -1109,14 +1162,10 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const
1109
1162
  {
1110
1163
  FILE *f;
1111
1164
  int len;
1112
- unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
1165
+ unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
1113
1166
  if (png == NULL) return 0;
1114
- #ifdef STBI_MSC_SECURE_CRT
1115
- if (fopen_s(&f, filename, "wb"))
1116
- f = NULL;
1117
- #else
1118
- f = fopen(filename, "wb");
1119
- #endif
1167
+
1168
+ f = stbiw__fopen(filename, "wb");
1120
1169
  if (!f) { STBIW_FREE(png); return 0; }
1121
1170
  fwrite(png, 1, len, f);
1122
1171
  fclose(f);
@@ -1128,7 +1177,7 @@ STBIWDEF int stbi_write_png(char const *filename, int x, int y, int comp, const
1128
1177
  STBIWDEF int stbi_write_png_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int stride_bytes)
1129
1178
  {
1130
1179
  int len;
1131
- unsigned char *png = stbi_write_png_to_mem((unsigned char *) data, stride_bytes, x, y, comp, &len);
1180
+ unsigned char *png = stbi_write_png_to_mem((const unsigned char *) data, stride_bytes, x, y, comp, &len);
1132
1181
  if (png == NULL) return 0;
1133
1182
  func(context, png, len);
1134
1183
  STBIW_FREE(png);
@@ -1423,15 +1472,13 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
1423
1472
  for(x = 0; x < width; x += 8) {
1424
1473
  float YDU[64], UDU[64], VDU[64];
1425
1474
  for(row = y, pos = 0; row < y+8; ++row) {
1475
+ // row >= height => use last input row
1476
+ int clamped_row = (row < height) ? row : height - 1;
1477
+ int base_p = (stbi__flip_vertically_on_write ? (height-1-clamped_row) : clamped_row)*width*comp;
1426
1478
  for(col = x; col < x+8; ++col, ++pos) {
1427
- int p = (stbi__flip_vertically_on_write ? height-1-row : row)*width*comp + col*comp;
1428
1479
  float r, g, b;
1429
- if(row >= height) {
1430
- p -= width*comp*(row+1 - height);
1431
- }
1432
- if(col >= width) {
1433
- p -= comp*(col+1 - width);
1434
- }
1480
+ // if col >= width => use pixel from last input column
1481
+ int p = base_p + ((col < width) ? col : (width-1))*comp;
1435
1482
 
1436
1483
  r = imageData[p+0];
1437
1484
  g = imageData[p+ofsG];
@@ -1483,6 +1530,10 @@ STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const
1483
1530
  #endif // STB_IMAGE_WRITE_IMPLEMENTATION
1484
1531
 
1485
1532
  /* Revision history
1533
+ 1.11 (2019-08-11)
1534
+
1535
+ 1.10 (2019-02-07)
1536
+ support utf8 filenames in Windows; fix warnings and platform ifdefs
1486
1537
  1.09 (2018-02-11)
1487
1538
  fix typo in zlib quality API, improve STB_I_W_STATIC in C++
1488
1539
  1.08 (2018-01-29)
data/src/stb_truetype.h CHANGED
@@ -1,5 +1,5 @@
1
- // stb_truetype.h - v1.19 - public domain
2
- // authored from 2009-2016 by Sean Barrett / RAD Game Tools
1
+ // stb_truetype.h - v1.22 - public domain
2
+ // authored from 2009-2019 by Sean Barrett / RAD Game Tools
3
3
  //
4
4
  // This library processes TrueType files:
5
5
  // parse files
@@ -46,9 +46,13 @@
46
46
  // Rob Loach Cort Stratton
47
47
  // Kenney Phillis Jr. github:oyvindjam
48
48
  // Brian Costabile github:vassvik
49
+ // Ken Voskuil (kaesve) Ryan Griege
49
50
  //
50
51
  // VERSION HISTORY
51
52
  //
53
+ // 1.22 (2019-08-11) minimize missing-glyph duplication; fix kerning if both 'GPOS' and 'kern' are defined
54
+ // 1.21 (2019-02-25) fix warning
55
+ // 1.20 (2019-02-07) PackFontRange skips missing codepoints; GetScaleFontVMetrics()
52
56
  // 1.19 (2018-02-11) GPOS kerning, STBTT_fmod
53
57
  // 1.18 (2018-01-29) add missing function
54
58
  // 1.17 (2017-07-23) make more arguments const; doc fix
@@ -75,7 +79,7 @@
75
79
  //
76
80
  // USAGE
77
81
  //
78
- // Include this file in whatever places neeed to refer to it. In ONE C/C++
82
+ // Include this file in whatever places need to refer to it. In ONE C/C++
79
83
  // file, write:
80
84
  // #define STB_TRUETYPE_IMPLEMENTATION
81
85
  // before the #include of this file. This expands out the actual
@@ -242,19 +246,6 @@
242
246
  // recommend it.
243
247
  //
244
248
  //
245
- // SOURCE STATISTICS (based on v0.6c, 2050 LOC)
246
- //
247
- // Documentation & header file 520 LOC \___ 660 LOC documentation
248
- // Sample code 140 LOC /
249
- // Truetype parsing 620 LOC ---- 620 LOC TrueType
250
- // Software rasterization 240 LOC \ .
251
- // Curve tesselation 120 LOC \__ 550 LOC Bitmap creation
252
- // Bitmap management 100 LOC /
253
- // Baked bitmap interface 70 LOC /
254
- // Font name matching & access 150 LOC ---- 150
255
- // C runtime library abstraction 60 LOC ---- 60
256
- //
257
- //
258
249
  // PERFORMANCE MEASUREMENTS FOR 1.06:
259
250
  //
260
251
  // 32-bit 64-bit
@@ -556,6 +547,8 @@ STBTT_DEF void stbtt_GetBakedQuad(const stbtt_bakedchar *chardata, int pw, int p
556
547
  //
557
548
  // It's inefficient; you might want to c&p it and optimize it.
558
549
 
550
+ STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap);
551
+ // Query the font vertical metrics without having to create a font first.
559
552
 
560
553
 
561
554
  //////////////////////////////////////////////////////////////////////////////
@@ -641,6 +634,12 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
641
634
  // To use with PackFontRangesGather etc., you must set it before calls
642
635
  // call to PackFontRangesGatherRects.
643
636
 
637
+ STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip);
638
+ // If skip != 0, this tells stb_truetype to skip any codepoints for which
639
+ // there is no corresponding glyph. If skip=0, which is the default, then
640
+ // codepoints without a glyph recived the font's "missing character" glyph,
641
+ // typically an empty box by convention.
642
+
644
643
  STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, // same data as above
645
644
  int char_index, // character to display
646
645
  float *xpos, float *ypos, // pointers to current position in screen pixel space
@@ -669,6 +668,7 @@ struct stbtt_pack_context {
669
668
  int height;
670
669
  int stride_in_bytes;
671
670
  int padding;
671
+ int skip_missing;
672
672
  unsigned int h_oversample, v_oversample;
673
673
  unsigned char *pixels;
674
674
  void *nodes;
@@ -694,7 +694,7 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
694
694
  // file will only define one font and it always be at offset 0, so it will
695
695
  // return '0' for index 0, and -1 for all other indices.
696
696
 
697
- // The following structure is defined publically so you can declare one on
697
+ // The following structure is defined publicly so you can declare one on
698
698
  // the stack or as a global or etc, but you should treat it as opaque.
699
699
  struct stbtt_fontinfo
700
700
  {
@@ -733,6 +733,7 @@ STBTT_DEF int stbtt_FindGlyphIndex(const stbtt_fontinfo *info, int unicode_codep
733
733
  // and you want a speed-up, call this function with the character you're
734
734
  // going to process, then use glyph-based functions instead of the
735
735
  // codepoint-based functions.
736
+ // Returns 0 if the character codepoint is not defined in the font.
736
737
 
737
738
 
738
739
  //////////////////////////////////////////////////////////////////////////////
@@ -820,7 +821,7 @@ STBTT_DEF int stbtt_GetGlyphShape(const stbtt_fontinfo *info, int glyph_index, s
820
821
  // returns # of vertices and fills *vertices with the pointer to them
821
822
  // these are expressed in "unscaled" coordinates
822
823
  //
823
- // The shape is a series of countours. Each one starts with
824
+ // The shape is a series of contours. Each one starts with
824
825
  // a STBTT_moveto, then consists of a series of mixed
825
826
  // STBTT_lineto and STBTT_curveto segments. A lineto
826
827
  // draws a line from previous endpoint to its x,y; a curveto
@@ -916,7 +917,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
916
917
  STBTT_DEF unsigned char * stbtt_GetCodepointSDF(const stbtt_fontinfo *info, float scale, int codepoint, int padding, unsigned char onedge_value, float pixel_dist_scale, int *width, int *height, int *xoff, int *yoff);
917
918
  // These functions compute a discretized SDF field for a single character, suitable for storing
918
919
  // in a single-channel texture, sampling with bilinear filtering, and testing against
919
- // larger than some threshhold to produce scalable fonts.
920
+ // larger than some threshold to produce scalable fonts.
920
921
  // info -- the font
921
922
  // scale -- controls the size of the resulting SDF bitmap, same as it would be creating a regular bitmap
922
923
  // glyph/codepoint -- the character to generate the SDF for
@@ -2463,6 +2464,7 @@ static stbtt_int32 stbtt__GetGlyphGPOSInfoAdvance(const stbtt_fontinfo *info, i
2463
2464
  if (valueFormat2 != 0) return 0;
2464
2465
 
2465
2466
  STBTT_assert(coverageIndex < pairSetCount);
2467
+ STBTT__NOTUSED(pairSetCount);
2466
2468
 
2467
2469
  needle=glyph2;
2468
2470
  r=pairValueCount-1;
@@ -2540,8 +2542,7 @@ STBTT_DEF int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *info, int g1, int
2540
2542
 
2541
2543
  if (info->gpos)
2542
2544
  xAdvance += stbtt__GetGlyphGPOSInfoAdvance(info, g1, g2);
2543
-
2544
- if (info->kern)
2545
+ else if (info->kern)
2545
2546
  xAdvance += stbtt__GetGlyphKernInfoAdvance(info, g1, g2);
2546
2547
 
2547
2548
  return xAdvance;
@@ -3160,7 +3161,13 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
3160
3161
  if (e->y0 != e->y1) {
3161
3162
  stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
3162
3163
  if (z != NULL) {
3163
- STBTT_assert(z->ey >= scan_y_top);
3164
+ if (j == 0 && off_y != 0) {
3165
+ if (z->ey < scan_y_top) {
3166
+ // this can happen due to subpixel positioning and some kind of fp rounding error i think
3167
+ z->ey = scan_y_top;
3168
+ }
3169
+ }
3170
+ STBTT_assert(z->ey >= scan_y_top); // if we get really unlucky a tiny bit of an edge can be out of bounds
3164
3171
  // insert at front
3165
3172
  z->next = active;
3166
3173
  active = z;
@@ -3229,7 +3236,7 @@ static void stbtt__sort_edges_ins_sort(stbtt__edge *p, int n)
3229
3236
 
3230
3237
  static void stbtt__sort_edges_quicksort(stbtt__edge *p, int n)
3231
3238
  {
3232
- /* threshhold for transitioning to insertion sort */
3239
+ /* threshold for transitioning to insertion sort */
3233
3240
  while (n > 12) {
3234
3241
  stbtt__edge t;
3235
3242
  int c01,c12,c,m,i,j;
@@ -3364,7 +3371,7 @@ static void stbtt__add_point(stbtt__point *points, int n, float x, float y)
3364
3371
  points[n].y = y;
3365
3372
  }
3366
3373
 
3367
- // tesselate until threshhold p is happy... @TODO warped to compensate for non-linear stretching
3374
+ // tessellate until threshold p is happy... @TODO warped to compensate for non-linear stretching
3368
3375
  static int stbtt__tesselate_curve(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float objspace_flatness_squared, int n)
3369
3376
  {
3370
3377
  // midpoint
@@ -3789,6 +3796,7 @@ STBTT_DEF int stbtt_PackBegin(stbtt_pack_context *spc, unsigned char *pixels, in
3789
3796
  spc->stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw;
3790
3797
  spc->h_oversample = 1;
3791
3798
  spc->v_oversample = 1;
3799
+ spc->skip_missing = 0;
3792
3800
 
3793
3801
  stbrp_init_target(context, pw-padding, ph-padding, nodes, num_nodes);
3794
3802
 
@@ -3814,6 +3822,11 @@ STBTT_DEF void stbtt_PackSetOversampling(stbtt_pack_context *spc, unsigned int h
3814
3822
  spc->v_oversample = v_oversample;
3815
3823
  }
3816
3824
 
3825
+ STBTT_DEF void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *spc, int skip)
3826
+ {
3827
+ spc->skip_missing = skip;
3828
+ }
3829
+
3817
3830
  #define STBTT__OVER_MASK (STBTT_MAX_OVERSAMPLE-1)
3818
3831
 
3819
3832
  static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_in_bytes, unsigned int kernel_width)
@@ -3956,6 +3969,7 @@ static float stbtt__oversample_shift(int oversample)
3956
3969
  STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
3957
3970
  {
3958
3971
  int i,j,k;
3972
+ int missing_glyph_added = 0;
3959
3973
 
3960
3974
  k=0;
3961
3975
  for (i=0; i < num_ranges; ++i) {
@@ -3967,13 +3981,19 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, const stb
3967
3981
  int x0,y0,x1,y1;
3968
3982
  int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
3969
3983
  int glyph = stbtt_FindGlyphIndex(info, codepoint);
3970
- stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
3971
- scale * spc->h_oversample,
3972
- scale * spc->v_oversample,
3973
- 0,0,
3974
- &x0,&y0,&x1,&y1);
3975
- rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
3976
- rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
3984
+ if (glyph == 0 && (spc->skip_missing || missing_glyph_added)) {
3985
+ rects[k].w = rects[k].h = 0;
3986
+ } else {
3987
+ stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
3988
+ scale * spc->h_oversample,
3989
+ scale * spc->v_oversample,
3990
+ 0,0,
3991
+ &x0,&y0,&x1,&y1);
3992
+ rects[k].w = (stbrp_coord) (x1-x0 + spc->padding + spc->h_oversample-1);
3993
+ rects[k].h = (stbrp_coord) (y1-y0 + spc->padding + spc->v_oversample-1);
3994
+ if (glyph == 0)
3995
+ missing_glyph_added = 1;
3996
+ }
3977
3997
  ++k;
3978
3998
  }
3979
3999
  }
@@ -4007,7 +4027,7 @@ STBTT_DEF void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *info
4007
4027
  // rects array must be big enough to accommodate all characters in the given ranges
4008
4028
  STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const stbtt_fontinfo *info, stbtt_pack_range *ranges, int num_ranges, stbrp_rect *rects)
4009
4029
  {
4010
- int i,j,k, return_value = 1;
4030
+ int i,j,k, missing_glyph = -1, return_value = 1;
4011
4031
 
4012
4032
  // save current values
4013
4033
  int old_h_over = spc->h_oversample;
@@ -4026,7 +4046,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const
4026
4046
  sub_y = stbtt__oversample_shift(spc->v_oversample);
4027
4047
  for (j=0; j < ranges[i].num_chars; ++j) {
4028
4048
  stbrp_rect *r = &rects[k];
4029
- if (r->was_packed) {
4049
+ if (r->was_packed && r->w != 0 && r->h != 0) {
4030
4050
  stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
4031
4051
  int advance, lsb, x0,y0,x1,y1;
4032
4052
  int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
@@ -4072,6 +4092,13 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, const
4072
4092
  bc->yoff = (float) y0 * recip_v + sub_y;
4073
4093
  bc->xoff2 = (x0 + r->w) * recip_h + sub_x;
4074
4094
  bc->yoff2 = (y0 + r->h) * recip_v + sub_y;
4095
+
4096
+ if (glyph == 0)
4097
+ missing_glyph = j;
4098
+ } else if (spc->skip_missing) {
4099
+ return_value = 0;
4100
+ } else if (r->was_packed && r->w == 0 && r->h == 0 && missing_glyph >= 0) {
4101
+ ranges[i].chardata_for_range[j] = ranges[i].chardata_for_range[missing_glyph];
4075
4102
  } else {
4076
4103
  return_value = 0; // if any fail, report failure
4077
4104
  }
@@ -4140,6 +4167,19 @@ STBTT_DEF int stbtt_PackFontRange(stbtt_pack_context *spc, const unsigned char *
4140
4167
  return stbtt_PackFontRanges(spc, fontdata, font_index, &range, 1);
4141
4168
  }
4142
4169
 
4170
+ STBTT_DEF void stbtt_GetScaledFontVMetrics(const unsigned char *fontdata, int index, float size, float *ascent, float *descent, float *lineGap)
4171
+ {
4172
+ int i_ascent, i_descent, i_lineGap;
4173
+ float scale;
4174
+ stbtt_fontinfo info;
4175
+ stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, index));
4176
+ scale = size > 0 ? stbtt_ScaleForPixelHeight(&info, size) : stbtt_ScaleForMappingEmToPixels(&info, -size);
4177
+ stbtt_GetFontVMetrics(&info, &i_ascent, &i_descent, &i_lineGap);
4178
+ *ascent = (float) i_ascent * scale;
4179
+ *descent = (float) i_descent * scale;
4180
+ *lineGap = (float) i_lineGap * scale;
4181
+ }
4182
+
4143
4183
  STBTT_DEF void stbtt_GetPackedQuad(const stbtt_packedchar *chardata, int pw, int ph, int char_index, float *xpos, float *ypos, stbtt_aligned_quad *q, int align_to_integer)
4144
4184
  {
4145
4185
  float ipw = 1.0f / pw, iph = 1.0f / ph;
@@ -4360,12 +4400,7 @@ STBTT_DEF unsigned char * stbtt_GetGlyphSDF(const stbtt_fontinfo *info, float sc
4360
4400
  int w,h;
4361
4401
  unsigned char *data;
4362
4402
 
4363
- // if one scale is 0, use same scale for both
4364
- if (scale_x == 0) scale_x = scale_y;
4365
- if (scale_y == 0) {
4366
- if (scale_x == 0) return NULL; // if both scales are 0, return NULL
4367
- scale_y = scale_x;
4368
- }
4403
+ if (scale == 0) return NULL;
4369
4404
 
4370
4405
  stbtt_GetGlyphBitmapBoxSubpixel(info, glyph, scale, scale, 0.0f,0.0f, &ix0,&iy0,&ix1,&iy1);
4371
4406