gosu 0.15.0 → 0.15.1
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/Gosu/Version.hpp +1 -1
- data/src/RubyGosu.cxx +58 -43
- data/src/RubyGosu.h +1 -1
- data/src/stb_image.h +153 -56
- data/src/stb_image_write.h +111 -60
- data/src/stb_truetype.h +74 -39
- data/src/stb_vorbis.c +55 -15
- data/src/utf8proc.c +47 -29
- data/src/utf8proc.h +46 -24
- data/src/utf8proc_data.h +10043 -9609
- metadata +2 -2
data/src/stb_image_write.h
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
/* stb_image_write - v1.
|
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
|
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
|
-
|
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
|
-
#
|
282
|
-
|
283
|
-
|
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,
|
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
|
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
|
396
|
-
else
|
397
|
-
j_end = y
|
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
|
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)
|
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
|
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]
|
908
|
-
s1 %= 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
|
-
|
1009
|
-
|
1010
|
-
|
1011
|
-
|
1012
|
-
|
1013
|
-
|
1014
|
-
|
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
|
-
|
1115
|
-
|
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
|
1430
|
-
|
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.
|
2
|
-
// authored from 2009-
|
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
|
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
|
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
|
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
|
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
|
-
|
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
|
-
/*
|
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
|
-
//
|
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
|
-
|
3971
|
-
|
3972
|
-
|
3973
|
-
|
3974
|
-
|
3975
|
-
|
3976
|
-
|
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
|
-
|
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
|
|