update stb utfcpp yoga modules

This commit is contained in:
BlackMATov
2021-01-15 21:36:01 +07:00
parent a6e55546d7
commit 36ff7b0ff0
26 changed files with 594 additions and 275 deletions

View File

@@ -1,4 +1,4 @@
/* stb_image - v2.25 - public domain image loader - http://nothings.org/stb
/* stb_image - v2.26 - public domain image loader - http://nothings.org/stb
no warranty implied; use at your own risk
Do this:
@@ -48,6 +48,7 @@ LICENSE
RECENT REVISION HISTORY:
2.26 (2020-07-13) many minor fixes
2.25 (2020-02-02) fix warnings
2.24 (2020-02-02) fix warnings; thread-local failure_reason and flip_vertically
2.23 (2019-08-11) fix clang static analysis warning
@@ -93,22 +94,30 @@ RECENT REVISION HISTORY:
Carmelo J Fdez-Aguera
Bug & warning fixes
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
Christpher Lloyd Jerry Jansson Joseph Thomson Phil Jordan
Dave Moore Roy Eltham Hayaki Saito Nathan Reed
Won Chun Luke Graham Johan Duparc Nick Verigakis
the Horde3D community Thomas Ruf Ronny Chevalier github:rlyeh
Janez Zemva John Bartholomew Michal Cichon github:romigrou
Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
Laurent Gomila Cort Stratton Sergio Gonzalez github:snagar
Aruelien Pocheville Thibault Reuille Cass Everitt github:Zelex
Ryamond Barbiero Paul Du Bois Engin Manap github:grim210
Aldo Culquicondor Philipp Wiesemann Dale Weiler github:sammyhw
Oriol Ferrer Mesia Josh Tobin Matthew Gregan github:phprus
Julian Raschke Gregory Mullen Baldur Karlsson github:poppolopoppo
Christian Floisand Kevin Schmidt JR Smith github:darealshinji
Brad Weinberger Matvey Cherevko github:Michaelangel007
Blazej Dariusz Roszkowski Alexander Veselov
Marc LeBlanc David Woo Guillaume George Martins Mozeiko
Christpher Lloyd Jerry Jansson Joseph Thomson Blazej Dariusz Roszkowski
Phil Jordan Dave Moore Roy Eltham
Hayaki Saito Nathan Reed Won Chun
Luke Graham Johan Duparc Nick Verigakis the Horde3D community
Thomas Ruf Ronny Chevalier github:rlyeh
Janez Zemva John Bartholomew Michal Cichon github:romigrou
Jonathan Blow Ken Hamada Tero Hanninen github:svdijk
Laurent Gomila Cort Stratton github:snagar
Aruelien Pocheville Sergio Gonzalez Thibault Reuille github:Zelex
Cass Everitt Ryamond Barbiero github:grim210
Paul Du Bois Engin Manap Aldo Culquicondor github:sammyhw
Philipp Wiesemann Dale Weiler Oriol Ferrer Mesia github:phprus
Josh Tobin Matthew Gregan github:poppolopoppo
Julian Raschke Gregory Mullen Christian Floisand github:darealshinji
Baldur Karlsson Kevin Schmidt JR Smith github:Michaelangel007
Brad Weinberger Matvey Cherevko [reserved]
Luca Sas Alexander Veselov Zack Middleton [reserved]
Ryan C. Gordon [reserved] [reserved]
DO NOT ADD YOUR NAME HERE
To add your name to the credits, pick a random blank space in the middle and fill it.
80% of merge conflicts on stb PRs are due to people adding their name at the end
of the credits.
*/
#ifndef STBI_INCLUDE_STB_IMAGE_H
@@ -318,7 +327,14 @@ RECENT REVISION HISTORY:
// - If you use STBI_NO_PNG (or _ONLY_ without PNG), and you still
// want the zlib decoder to be available, #define STBI_SUPPORT_ZLIB
//
// - If you define STBI_MAX_DIMENSIONS, stb_image will reject images greater
// than that size (in either width or height) without further processing.
// This is to let programs in the wild set an upper bound to prevent
// denial-of-service attacks on untrusted data, as one could generate a
// valid image of gigantic dimensions and force stb_image to allocate a
// huge block of memory and spend disproportionate time decoding it. By
// default this is set to (1 << 24), which is 16777216, but that's still
// very big.
#ifndef STBI_NO_STDIO
#include <stdio.h>
@@ -574,13 +590,19 @@ STBIDEF int stbi_zlib_decode_noheader_buffer(char *obuffer, int olen, const ch
#ifndef STBI_NO_THREAD_LOCALS
#if defined(__cplusplus) && __cplusplus >= 201103L
#define STBI_THREAD_LOCAL thread_local
#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
#define STBI_THREAD_LOCAL _Thread_local
#elif defined(__GNUC__)
#elif defined(__GNUC__) && __GNUC__ < 5
#define STBI_THREAD_LOCAL __thread
#elif defined(_MSC_VER)
#define STBI_THREAD_LOCAL __declspec(thread)
#endif
#elif defined (__STDC_VERSION__) && __STDC_VERSION__ >= 201112L && !defined(__STDC_NO_THREADS__)
#define STBI_THREAD_LOCAL _Thread_local
#endif
#ifndef STBI_THREAD_LOCAL
#if defined(__GNUC__)
#define STBI_THREAD_LOCAL __thread
#endif
#endif
#endif
#ifdef _MSC_VER
@@ -734,6 +756,10 @@ static int stbi__sse2_available(void)
#define STBI_SIMD_ALIGN(type, name) type name
#endif
#ifndef STBI_MAX_DIMENSIONS
#define STBI_MAX_DIMENSIONS (1 << 24)
#endif
///////////////////////////////////////////////
//
// stbi__context struct and start_xxx functions
@@ -751,6 +777,7 @@ typedef struct
int read_from_callbacks;
int buflen;
stbi_uc buffer_start[128];
int callback_already_read;
stbi_uc *img_buffer, *img_buffer_end;
stbi_uc *img_buffer_original, *img_buffer_original_end;
@@ -764,6 +791,7 @@ static void stbi__start_mem(stbi__context *s, stbi_uc const *buffer, int len)
{
s->io.read = NULL;
s->read_from_callbacks = 0;
s->callback_already_read = 0;
s->img_buffer = s->img_buffer_original = (stbi_uc *) buffer;
s->img_buffer_end = s->img_buffer_original_end = (stbi_uc *) buffer+len;
}
@@ -775,7 +803,8 @@ static void stbi__start_callbacks(stbi__context *s, stbi_io_callbacks *c, void *
s->io_user_data = user;
s->buflen = sizeof(s->buffer_start);
s->read_from_callbacks = 1;
s->img_buffer_original = s->buffer_start;
s->callback_already_read = 0;
s->img_buffer = s->img_buffer_original = s->buffer_start;
stbi__refill_buffer(s);
s->img_buffer_original_end = s->img_buffer_end;
}
@@ -789,12 +818,17 @@ static int stbi__stdio_read(void *user, char *data, int size)
static void stbi__stdio_skip(void *user, int n)
{
int ch;
fseek((FILE*) user, n, SEEK_CUR);
ch = fgetc((FILE*) user); /* have to read a byte to reset feof()'s flag */
if (ch != EOF) {
ungetc(ch, (FILE *) user); /* push byte back onto stream if valid. */
}
}
static int stbi__stdio_eof(void *user)
{
return feof((FILE*) user);
return feof((FILE*) user) || ferror((FILE *) user);
}
static stbi_io_callbacks stbi__stdio_callbacks =
@@ -1171,8 +1205,10 @@ static unsigned char *stbi__load_and_postprocess_8bit(stbi__context *s, int *x,
if (result == NULL)
return NULL;
// it is the responsibility of the loaders to make sure we get either 8 or 16 bit.
STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
if (ri.bits_per_channel != 8) {
STBI_ASSERT(ri.bits_per_channel == 16);
result = stbi__convert_16_to_8((stbi__uint16 *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
ri.bits_per_channel = 8;
}
@@ -1195,8 +1231,10 @@ static stbi__uint16 *stbi__load_and_postprocess_16bit(stbi__context *s, int *x,
if (result == NULL)
return NULL;
// it is the responsibility of the loaders to make sure we get either 8 or 16 bit.
STBI_ASSERT(ri.bits_per_channel == 8 || ri.bits_per_channel == 16);
if (ri.bits_per_channel != 16) {
STBI_ASSERT(ri.bits_per_channel == 8);
result = stbi__convert_8_to_16((stbi_uc *) result, *x, *y, req_comp == 0 ? *comp : req_comp);
ri.bits_per_channel = 16;
}
@@ -1499,6 +1537,7 @@ enum
static void stbi__refill_buffer(stbi__context *s)
{
int n = (s->io.read)(s->io_user_data,(char*)s->buffer_start,s->buflen);
s->callback_already_read += (int) (s->img_buffer - s->img_buffer_original);
if (n == 0) {
// at end of file, treat same as if from memory, but need to handle case
// where s->img_buffer isn't pointing to safe memory, e.g. 0-byte file
@@ -1544,6 +1583,7 @@ stbi_inline static int stbi__at_eof(stbi__context *s)
#else
static void stbi__skip(stbi__context *s, int n)
{
if (n == 0) return; // already there!
if (n < 0) {
s->img_buffer = s->img_buffer_end;
return;
@@ -1686,7 +1726,7 @@ static unsigned char *stbi__convert_format(unsigned char *data, int img_n, int r
STBI__CASE(4,1) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); } break;
STBI__CASE(4,2) { dest[0]=stbi__compute_y(src[0],src[1],src[2]); dest[1] = src[3]; } break;
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
default: STBI_ASSERT(0);
default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return stbi__errpuc("unsupported", "Unsupported format conversion");
}
#undef STBI__CASE
}
@@ -1743,7 +1783,7 @@ static stbi__uint16 *stbi__convert_format16(stbi__uint16 *data, int img_n, int r
STBI__CASE(4,1) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); } break;
STBI__CASE(4,2) { dest[0]=stbi__compute_y_16(src[0],src[1],src[2]); dest[1] = src[3]; } break;
STBI__CASE(4,3) { dest[0]=src[0];dest[1]=src[1];dest[2]=src[2]; } break;
default: STBI_ASSERT(0);
default: STBI_ASSERT(0); STBI_FREE(data); STBI_FREE(good); return (stbi__uint16*) stbi__errpuc("unsupported", "Unsupported format conversion");
}
#undef STBI__CASE
}
@@ -2052,7 +2092,7 @@ stbi_inline static int stbi__extend_receive(stbi__jpeg *j, int n)
sgn = (stbi__int32)j->code_buffer >> 31; // sign bit is always in MSB
k = stbi_lrot(j->code_buffer, n);
STBI_ASSERT(n >= 0 && n < (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask)));
if (n < 0 || n >= (int) (sizeof(stbi__bmask)/sizeof(*stbi__bmask))) return 0;
j->code_buffer = k & ~stbi__bmask[n];
k &= stbi__bmask[n];
j->code_bits -= n;
@@ -2163,6 +2203,7 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64], stbi__
// first scan for DC coefficient, must be first
memset(data,0,64*sizeof(data[0])); // 0 all the ac values now
t = stbi__jpeg_huff_decode(j, hdc);
if (t == -1) return stbi__err("can't merge dc and ac", "Corrupt JPEG");
diff = t ? stbi__extend_receive(j, t) : 0;
dc = j->img_comp[b].dc_pred + diff;
@@ -3153,6 +3194,8 @@ static int stbi__process_frame_header(stbi__jpeg *z, int scan)
p = stbi__get8(s); if (p != 8) return stbi__err("only 8-bit","JPEG format not supported: 8-bit only"); // JPEG baseline
s->img_y = stbi__get16be(s); if (s->img_y == 0) return stbi__err("no header height", "JPEG format not supported: delayed height"); // Legal, but we don't handle it--but neither does IJG
s->img_x = stbi__get16be(s); if (s->img_x == 0) return stbi__err("0 width","Corrupt JPEG"); // JPEG requires
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
c = stbi__get8(s);
if (c != 3 && c != 1 && c != 4) return stbi__err("bad component count","Corrupt JPEG");
s->img_n = c;
@@ -4033,16 +4076,23 @@ typedef struct
stbi__zhuffman z_length, z_distance;
} stbi__zbuf;
stbi_inline static int stbi__zeof(stbi__zbuf *z)
{
return (z->zbuffer >= z->zbuffer_end);
}
stbi_inline static stbi_uc stbi__zget8(stbi__zbuf *z)
{
if (z->zbuffer >= z->zbuffer_end) return 0;
return *z->zbuffer++;
return stbi__zeof(z) ? 0 : *z->zbuffer++;
}
static void stbi__fill_bits(stbi__zbuf *z)
{
do {
STBI_ASSERT(z->code_buffer < (1U << z->num_bits));
if (z->code_buffer >= (1U << z->num_bits)) {
z->zbuffer = z->zbuffer_end; /* treat this as EOF so we fail. */
return;
}
z->code_buffer |= (unsigned int) stbi__zget8(z) << z->num_bits;
z->num_bits += 8;
} while (z->num_bits <= 24);
@@ -4067,10 +4117,11 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
for (s=STBI__ZFAST_BITS+1; ; ++s)
if (k < z->maxcode[s])
break;
if (s == 16) return -1; // invalid code!
if (s >= 16) return -1; // invalid code!
// code size is s, so:
b = (k >> (16-s)) - z->firstcode[s] + z->firstsymbol[s];
STBI_ASSERT(z->size[b] == s);
if (b >= sizeof (z->size)) return -1; // some data was corrupt somewhere!
if (z->size[b] != s) return -1; // was originally an assert, but report failure instead.
a->code_buffer >>= s;
a->num_bits -= s;
return z->value[b];
@@ -4079,7 +4130,12 @@ static int stbi__zhuffman_decode_slowpath(stbi__zbuf *a, stbi__zhuffman *z)
stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
{
int b,s;
if (a->num_bits < 16) stbi__fill_bits(a);
if (a->num_bits < 16) {
if (stbi__zeof(a)) {
return -1; /* report error for unexpected end of data. */
}
stbi__fill_bits(a);
}
b = z->fast[a->code_buffer & STBI__ZFAST_MASK];
if (b) {
s = b >> 9;
@@ -4093,13 +4149,16 @@ stbi_inline static int stbi__zhuffman_decode(stbi__zbuf *a, stbi__zhuffman *z)
static int stbi__zexpand(stbi__zbuf *z, char *zout, int n) // need to make room for n bytes
{
char *q;
int cur, limit, old_limit;
unsigned int cur, limit, old_limit;
z->zout = zout;
if (!z->z_expandable) return stbi__err("output buffer limit","Corrupt PNG");
cur = (int) (z->zout - z->zout_start);
limit = old_limit = (int) (z->zout_end - z->zout_start);
while (cur + n > limit)
cur = (unsigned int) (z->zout - z->zout_start);
limit = old_limit = (unsigned) (z->zout_end - z->zout_start);
if (UINT_MAX - cur < (unsigned) n) return stbi__err("outofmem", "Out of memory");
while (cur + n > limit) {
if(limit > UINT_MAX / 2) return stbi__err("outofmem", "Out of memory");
limit *= 2;
}
q = (char *) STBI_REALLOC_SIZED(z->zout_start, old_limit, limit);
STBI_NOTUSED(old_limit);
if (q == NULL) return stbi__err("outofmem", "Out of memory");
@@ -4197,11 +4256,12 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a)
c = stbi__zreceive(a,2)+3;
if (n == 0) return stbi__err("bad codelengths", "Corrupt PNG");
fill = lencodes[n-1];
} else if (c == 17)
} else if (c == 17) {
c = stbi__zreceive(a,3)+3;
else {
STBI_ASSERT(c == 18);
} else if (c == 18) {
c = stbi__zreceive(a,7)+11;
} else {
return stbi__err("bad codelengths", "Corrupt PNG");
}
if (ntot - n < c) return stbi__err("bad codelengths", "Corrupt PNG");
memset(lencodes+n, fill, c);
@@ -4227,7 +4287,7 @@ static int stbi__parse_uncompressed_block(stbi__zbuf *a)
a->code_buffer >>= 8;
a->num_bits -= 8;
}
STBI_ASSERT(a->num_bits == 0);
if (a->num_bits < 0) return stbi__err("zlib corrupt","Corrupt PNG");
// now fill header the normal way
while (k < 4)
header[k++] = stbi__zget8(a);
@@ -4249,6 +4309,7 @@ static int stbi__parse_zlib_header(stbi__zbuf *a)
int cm = cmf & 15;
/* int cinfo = cmf >> 4; */
int flg = stbi__zget8(a);
if (stbi__zeof(a)) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
if ((cmf*256+flg) % 31 != 0) return stbi__err("bad zlib header","Corrupt PNG"); // zlib spec
if (flg & 32) return stbi__err("no preset dict","Corrupt PNG"); // preset dictionary not allowed in png
if (cm != 8) return stbi__err("bad compression","Corrupt PNG"); // DEFLATE required for png
@@ -4510,7 +4571,7 @@ static int stbi__create_png_image_raw(stbi__png *a, stbi_uc *raw, stbi__uint32 r
return stbi__err("invalid filter","Corrupt PNG");
if (depth < 8) {
STBI_ASSERT(img_width_bytes <= x);
if (img_width_bytes > x) return stbi__err("invalid width","Corrupt PNG");
cur += x*out_n - img_width_bytes; // store output to the rightmost img_len bytes, so we can decode in place
filter_bytes = 1;
width = img_width_bytes;
@@ -4905,8 +4966,10 @@ static int stbi__parse_png_file(stbi__png *z, int scan, int req_comp)
if (!first) return stbi__err("multiple IHDR","Corrupt PNG");
first = 0;
if (c.length != 13) return stbi__err("bad IHDR len","Corrupt PNG");
s->img_x = stbi__get32be(s); if (s->img_x > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
s->img_y = stbi__get32be(s); if (s->img_y > (1 << 24)) return stbi__err("too large","Very large image (corrupt?)");
s->img_x = stbi__get32be(s);
s->img_y = stbi__get32be(s);
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
z->depth = stbi__get8(s); if (z->depth != 1 && z->depth != 2 && z->depth != 4 && z->depth != 8 && z->depth != 16) return stbi__err("1/2/4/8/16-bit only","PNG not supported: 1/2/4/8/16-bit only");
color = stbi__get8(s); if (color > 6) return stbi__err("bad ctype","Corrupt PNG");
if (color == 3 && z->depth == 16) return stbi__err("bad ctype","Corrupt PNG");
@@ -5055,10 +5118,12 @@ static void *stbi__do_png(stbi__png *p, int *x, int *y, int *n, int req_comp, st
void *result=NULL;
if (req_comp < 0 || req_comp > 4) return stbi__errpuc("bad req_comp", "Internal error");
if (stbi__parse_png_file(p, STBI__SCAN_load, req_comp)) {
if (p->depth < 8)
if (p->depth <= 8)
ri->bits_per_channel = 8;
else if (p->depth == 16)
ri->bits_per_channel = 16;
else
ri->bits_per_channel = p->depth;
return stbi__errpuc("bad bits_per_channel", "PNG not supported: unsupported color depth");
result = p->out;
p->out = NULL;
if (req_comp && req_comp != p->s->img_out_n) {
@@ -5219,6 +5284,8 @@ static void *stbi__bmp_parse_header(stbi__context *s, stbi__bmp_data *info)
info->mr = info->mg = info->mb = info->ma = 0;
info->extra_read = 14;
if (info->offset < 0) return stbi__errpuc("bad BMP", "bad BMP");
if (hsz != 12 && hsz != 40 && hsz != 56 && hsz != 108 && hsz != 124) return stbi__errpuc("unknown BMP", "BMP type not supported: unknown");
if (hsz == 12) {
s->img_x = stbi__get16le(s);
@@ -5310,6 +5377,9 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
flip_vertically = ((int) s->img_y) > 0;
s->img_y = abs((int) s->img_y);
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
mr = info.mr;
mg = info.mg;
mb = info.mb;
@@ -5324,7 +5394,10 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
psize = (info.offset - info.extra_read - info.hsz) >> 2;
}
if (psize == 0) {
STBI_ASSERT(info.offset == (s->img_buffer - s->buffer_start));
STBI_ASSERT(info.offset == s->callback_already_read + (int) (s->img_buffer - s->img_buffer_original));
if (info.offset != s->callback_already_read + (s->img_buffer - s->buffer_start)) {
return stbi__errpuc("bad offset", "Corrupt BMP");
}
}
if (info.bpp == 24 && ma == 0xff000000)
@@ -5419,6 +5492,7 @@ static void *stbi__bmp_load(stbi__context *s, int *x, int *y, int *comp, int req
gshift = stbi__high_bit(mg)-7; gcount = stbi__bitcount(mg);
bshift = stbi__high_bit(mb)-7; bcount = stbi__bitcount(mb);
ashift = stbi__high_bit(ma)-7; acount = stbi__bitcount(ma);
if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { STBI_FREE(out); return stbi__errpuc("bad masks", "Corrupt BMP"); }
}
for (j=0; j < (int) s->img_y; ++j) {
if (easy) {
@@ -5643,6 +5717,9 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
STBI_NOTUSED(tga_x_origin); // @TODO
STBI_NOTUSED(tga_y_origin); // @TODO
if (tga_height > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
if (tga_width > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
// do a tiny bit of precessing
if ( tga_image_type >= 8 )
{
@@ -5682,6 +5759,11 @@ static void *stbi__tga_load(stbi__context *s, int *x, int *y, int *comp, int req
// do I need to load a palette?
if ( tga_indexed)
{
if (tga_palette_len == 0) { /* you have to have at least one entry! */
STBI_FREE(tga_data);
return stbi__errpuc("bad palette", "Corrupt TGA");
}
// any data to skip? (offset usually = 0)
stbi__skip(s, tga_palette_start );
// load the palette
@@ -5890,6 +5972,9 @@ static void *stbi__psd_load(stbi__context *s, int *x, int *y, int *comp, int req
h = stbi__get32be(s);
w = stbi__get32be(s);
if (h > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
if (w > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
// Make sure the depth is 8 bits.
bitdepth = stbi__get16be(s);
if (bitdepth != 8 && bitdepth != 16)
@@ -6244,6 +6329,10 @@ static void *stbi__pic_load(stbi__context *s,int *px,int *py,int *comp,int req_c
x = stbi__get16be(s);
y = stbi__get16be(s);
if (y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
if (x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
if (stbi__at_eof(s)) return stbi__errpuc("bad file","file too short (pic header)");
if (!stbi__mad3sizes_valid(x, y, 4, 0)) return stbi__errpuc("too large", "PIC image too large to decode");
@@ -6352,6 +6441,9 @@ static int stbi__gif_header(stbi__context *s, stbi__gif *g, int *comp, int is_in
g->ratio = stbi__get8(s);
g->transparent = -1;
if (g->w > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
if (g->h > STBI_MAX_DIMENSIONS) return stbi__err("too large","Very large image (corrupt?)");
if (comp != 0) *comp = 4; // can't actually tell whether it's 3 or 4 until we parse the comments
if (is_info) return 1;
@@ -6529,7 +6621,7 @@ static stbi_uc *stbi__gif_load_next(stbi__context *s, stbi__gif *g, int *comp, i
memset(g->history, 0x00, pcount); // pixels that were affected previous frame
first_frame = 1;
} else {
// second frame - how do we dispoase of the previous one?
// second frame - how do we dispose of the previous one?
dispose = (g->eflags & 0x1C) >> 2;
pcount = g->w * g->h;
@@ -6683,6 +6775,8 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
stbi_uc *two_back = 0;
stbi__gif g;
int stride;
int out_size = 0;
int delays_size = 0;
memset(&g, 0, sizeof(g));
if (delays) {
*delays = 0;
@@ -6699,22 +6793,28 @@ static void *stbi__load_gif_main(stbi__context *s, int **delays, int *x, int *y,
stride = g.w * g.h * 4;
if (out) {
void *tmp = (stbi_uc*) STBI_REALLOC( out, layers * stride );
void *tmp = (stbi_uc*) STBI_REALLOC_SIZED( out, out_size, layers * stride );
if (NULL == tmp) {
STBI_FREE(g.out);
STBI_FREE(g.history);
STBI_FREE(g.background);
return stbi__errpuc("outofmem", "Out of memory");
}
else
out = (stbi_uc*) tmp;
else {
out = (stbi_uc*) tmp;
out_size = layers * stride;
}
if (delays) {
*delays = (int*) STBI_REALLOC( *delays, sizeof(int) * layers );
*delays = (int*) STBI_REALLOC_SIZED( *delays, delays_size, sizeof(int) * layers );
delays_size = layers * sizeof(int);
}
} else {
out = (stbi_uc*)stbi__malloc( layers * stride );
out_size = layers * stride;
if (delays) {
*delays = (int*) stbi__malloc( layers * sizeof(int) );
delays_size = layers * sizeof(int);
}
}
memcpy( out + ((layers - 1) * stride), u, stride );
@@ -6893,6 +6993,9 @@ static float *stbi__hdr_load(stbi__context *s, int *x, int *y, int *comp, int re
token += 3;
width = (int) strtol(token, NULL, 10);
if (height > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)");
if (width > STBI_MAX_DIMENSIONS) return stbi__errpf("too large","Very large image (corrupt?)");
*x = width;
*y = height;
@@ -7207,6 +7310,9 @@ static void *stbi__pnm_load(stbi__context *s, int *x, int *y, int *comp, int req
if (!stbi__pnm_info(s, (int *)&s->img_x, (int *)&s->img_y, (int *)&s->img_n))
return 0;
if (s->img_y > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
if (s->img_x > STBI_MAX_DIMENSIONS) return stbi__errpuc("too large","Very large image (corrupt?)");
*x = s->img_x;
*y = s->img_y;
if (comp) *comp = s->img_n;

View File

@@ -1,4 +1,4 @@
/* stb_image_write - v1.14 - public domain - http://nothings.org/stb
/* stb_image_write - v1.15 - public domain - http://nothings.org/stb
writes out PNG/BMP/TGA/JPEG/HDR images to C stdio - Sean Barrett 2010-2015
no warranty implied; use at your own risk
@@ -267,6 +267,8 @@ typedef struct
{
stbi_write_func *func;
void *context;
unsigned char buffer[64];
int buf_used;
} stbi__write_context;
// initialize a callback-based context
@@ -380,16 +382,36 @@ static void stbiw__writef(stbi__write_context *s, const char *fmt, ...)
va_end(v);
}
static void stbiw__write_flush(stbi__write_context *s)
{
if (s->buf_used) {
s->func(s->context, &s->buffer, s->buf_used);
s->buf_used = 0;
}
}
static void stbiw__putc(stbi__write_context *s, unsigned char c)
{
s->func(s->context, &c, 1);
}
static void stbiw__write1(stbi__write_context *s, unsigned char a)
{
if (s->buf_used + 1 > sizeof(s->buffer))
stbiw__write_flush(s);
s->buffer[s->buf_used++] = a;
}
static void stbiw__write3(stbi__write_context *s, unsigned char a, unsigned char b, unsigned char c)
{
unsigned char arr[3];
arr[0] = a; arr[1] = b; arr[2] = c;
s->func(s->context, arr, 3);
int n;
if (s->buf_used + 3 > sizeof(s->buffer))
stbiw__write_flush(s);
n = s->buf_used;
s->buf_used = n+3;
s->buffer[n+0] = a;
s->buffer[n+1] = b;
s->buffer[n+2] = c;
}
static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, int write_alpha, int expand_mono, unsigned char *d)
@@ -398,7 +420,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
int k;
if (write_alpha < 0)
s->func(s->context, &d[comp - 1], 1);
stbiw__write1(s, d[comp - 1]);
switch (comp) {
case 2: // 2 pixels = mono + alpha, alpha is written separately, so same as 1-channel case
@@ -406,7 +428,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
if (expand_mono)
stbiw__write3(s, d[0], d[0], d[0]); // monochrome bmp
else
s->func(s->context, d, 1); // monochrome TGA
stbiw__write1(s, d[0]); // monochrome TGA
break;
case 4:
if (!write_alpha) {
@@ -422,7 +444,7 @@ static void stbiw__write_pixel(stbi__write_context *s, int rgb_dir, int comp, in
break;
}
if (write_alpha > 0)
s->func(s->context, &d[comp - 1], 1);
stbiw__write1(s, d[comp - 1]);
}
static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, int x, int y, int comp, void *data, int write_alpha, int scanline_pad, int expand_mono)
@@ -447,6 +469,7 @@ static void stbiw__write_pixels(stbi__write_context *s, int rgb_dir, int vdir, i
unsigned char *d = (unsigned char *) data + (j*x+i)*comp;
stbiw__write_pixel(s, rgb_dir, comp, write_alpha, expand_mono, d);
}
stbiw__write_flush(s);
s->func(s->context, &zero, scanline_pad);
}
}
@@ -476,7 +499,7 @@ static int stbi_write_bmp_core(stbi__write_context *s, int x, int y, int comp, c
STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
{
stbi__write_context s;
stbi__write_context s = { 0 };
stbi__start_write_callbacks(&s, func, context);
return stbi_write_bmp_core(&s, x, y, comp, data);
}
@@ -484,7 +507,7 @@ STBIWDEF int stbi_write_bmp_to_func(stbi_write_func *func, void *context, int x,
#ifndef STBI_WRITE_NO_STDIO
STBIWDEF int stbi_write_bmp(char const *filename, int x, int y, int comp, const void *data)
{
stbi__write_context s;
stbi__write_context s = { 0 };
if (stbi__start_write_file(&s,filename)) {
int r = stbi_write_bmp_core(&s, x, y, comp, data);
stbi__end_write_file(&s);
@@ -557,24 +580,25 @@ static int stbi_write_tga_core(stbi__write_context *s, int x, int y, int comp, v
if (diff) {
unsigned char header = STBIW_UCHAR(len - 1);
s->func(s->context, &header, 1);
stbiw__write1(s, header);
for (k = 0; k < len; ++k) {
stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin + k * comp);
}
} else {
unsigned char header = STBIW_UCHAR(len - 129);
s->func(s->context, &header, 1);
stbiw__write1(s, header);
stbiw__write_pixel(s, -1, comp, has_alpha, 0, begin);
}
}
}
stbiw__write_flush(s);
}
return 1;
}
STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data)
{
stbi__write_context s;
stbi__write_context s = { 0 };
stbi__start_write_callbacks(&s, func, context);
return stbi_write_tga_core(&s, x, y, comp, (void *) data);
}
@@ -582,7 +606,7 @@ STBIWDEF int stbi_write_tga_to_func(stbi_write_func *func, void *context, int x,
#ifndef STBI_WRITE_NO_STDIO
STBIWDEF int stbi_write_tga(char const *filename, int x, int y, int comp, const void *data)
{
stbi__write_context s;
stbi__write_context s = { 0 };
if (stbi__start_write_file(&s,filename)) {
int r = stbi_write_tga_core(&s, x, y, comp, (void *) data);
stbi__end_write_file(&s);
@@ -748,7 +772,7 @@ static int stbi_write_hdr_core(stbi__write_context *s, int x, int y, int comp, f
STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const float *data)
{
stbi__write_context s;
stbi__write_context s = { 0 };
stbi__start_write_callbacks(&s, func, context);
return stbi_write_hdr_core(&s, x, y, comp, (float *) data);
}
@@ -756,7 +780,7 @@ STBIWDEF int stbi_write_hdr_to_func(stbi_write_func *func, void *context, int x,
#ifndef STBI_WRITE_NO_STDIO
STBIWDEF int stbi_write_hdr(char const *filename, int x, int y, int comp, const float *data)
{
stbi__write_context s;
stbi__write_context s = { 0 };
if (stbi__start_write_file(&s,filename)) {
int r = stbi_write_hdr_core(&s, x, y, comp, (float *) data);
stbi__end_write_file(&s);
@@ -1552,7 +1576,7 @@ static int stbi_write_jpg_core(stbi__write_context *s, int width, int height, in
STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x, int y, int comp, const void *data, int quality)
{
stbi__write_context s;
stbi__write_context s = { 0 };
stbi__start_write_callbacks(&s, func, context);
return stbi_write_jpg_core(&s, x, y, comp, (void *) data, quality);
}
@@ -1561,7 +1585,7 @@ STBIWDEF int stbi_write_jpg_to_func(stbi_write_func *func, void *context, int x,
#ifndef STBI_WRITE_NO_STDIO
STBIWDEF int stbi_write_jpg(char const *filename, int x, int y, int comp, const void *data, int quality)
{
stbi__write_context s;
stbi__write_context s = { 0 };
if (stbi__start_write_file(&s,filename)) {
int r = stbi_write_jpg_core(&s, x, y, comp, data, quality);
stbi__end_write_file(&s);

View File

@@ -1,4 +1,4 @@
// stb_sprintf - v1.08 - public domain snprintf() implementation
// stb_sprintf - v1.09 - public domain snprintf() implementation
// originally by Jeff Roberts / RAD Game Tools, 2015/10/20
// http://github.com/nothings/stb
//
@@ -1229,7 +1229,7 @@ STBSP__PUBLICDEF int STB_SPRINTF_DECORATE(vsprintfcb)(STBSP_SPRINTFCB *callback,
stbsp__cb_buf_clamp(i, n);
n -= i;
STBSP__UNALIGNED(while (i >= 4) {
*(stbsp__uint32 *)bf = *(stbsp__uint32 *)s;
*(stbsp__uint32 volatile *)bf = *(stbsp__uint32 volatile *)s;
bf += 4;
s += 4;
i -= 4;

View File

@@ -42,7 +42,7 @@ namespace utf8
uint32_t cp;
public:
invalid_code_point(uint32_t codepoint) : cp(codepoint) {}
virtual const char* what() const NOEXCEPT OVERRIDE { return "Invalid code point"; }
virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid code point"; }
uint32_t code_point() const {return cp;}
};
@@ -50,7 +50,7 @@ namespace utf8
uint8_t u8;
public:
invalid_utf8 (uint8_t u) : u8(u) {}
virtual const char* what() const NOEXCEPT OVERRIDE { return "Invalid UTF-8"; }
virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid UTF-8"; }
uint8_t utf8_octet() const {return u8;}
};
@@ -58,13 +58,13 @@ namespace utf8
uint16_t u16;
public:
invalid_utf16 (uint16_t u) : u16(u) {}
virtual const char* what() const NOEXCEPT OVERRIDE { return "Invalid UTF-16"; }
virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Invalid UTF-16"; }
uint16_t utf16_word() const {return u16;}
};
class not_enough_room : public exception {
public:
virtual const char* what() const NOEXCEPT OVERRIDE { return "Not enough space"; }
virtual const char* what() const UTF_CPP_NOEXCEPT UTF_CPP_OVERRIDE { return "Not enough space"; }
};
/// The library API - functions intended to be called by the users

View File

@@ -39,11 +39,11 @@ DEALINGS IN THE SOFTWARE.
#endif
#if UTF_CPP_CPLUSPLUS >= 201103L // C++ 11 or later
#define OVERRIDE override
#define NOEXCEPT noexcept
#define UTF_CPP_OVERRIDE override
#define UTF_CPP_NOEXCEPT noexcept
#else // C++ 98/03
#define OVERRIDE
#define NOEXCEPT throw()
#define UTF_CPP_OVERRIDE
#define UTF_CPP_NOEXCEPT throw()
#endif // C++ 11 or later

66
sources/3rdparty/yoga/BitUtils.h vendored Normal file
View File

@@ -0,0 +1,66 @@
/*
* Copyright (c) Facebook, Inc. and its affiliates.
*
* This source code is licensed under the MIT license found in the
* LICENSE file in the root directory of this source tree.
*/
#pragma once
#include <cstdio>
#include <cstdint>
#include "YGEnums.h"
namespace facebook {
namespace yoga {
namespace detail {
constexpr size_t log2ceilFn(size_t n) {
return n < 1 ? 0 : (1 + log2ceilFn(n / 2));
}
constexpr int mask(size_t bitWidth, size_t index) {
return ((1 << bitWidth) - 1) << index;
}
// The number of bits necessary to represent enums defined with YG_ENUM_SEQ_DECL
template <typename Enum>
constexpr size_t bitWidthFn() {
static_assert(
enums::count<Enum>() > 0, "Enums must have at least one entries");
return log2ceilFn(enums::count<Enum>() - 1);
}
template <typename Enum>
constexpr Enum getEnumData(int flags, size_t index) {
return static_cast<Enum>((flags & mask(bitWidthFn<Enum>(), index)) >> index);
}
template <typename Enum>
void setEnumData(uint32_t& flags, size_t index, int newValue) {
flags = (flags & ~mask(bitWidthFn<Enum>(), index)) |
((newValue << index) & (mask(bitWidthFn<Enum>(), index)));
}
template <typename Enum>
void setEnumData(uint8_t& flags, size_t index, int newValue) {
flags = (flags & ~mask(bitWidthFn<Enum>(), index)) |
((newValue << index) & (mask(bitWidthFn<Enum>(), index)));
}
constexpr bool getBooleanData(int flags, size_t index) {
return (flags >> index) & 1;
}
inline void setBooleanData(uint8_t& flags, size_t index, bool value) {
if (value) {
flags |= 1 << index;
} else {
flags &= ~(1 << index);
}
}
} // namespace detail
} // namespace yoga
} // namespace facebook

View File

@@ -125,8 +125,8 @@ public:
data.repr &= ~PERCENT_BIT;
data.repr += BIAS;
return YGValue{data.value,
payload_.repr & 0x40000000 ? YGUnitPercent : YGUnitPoint};
return YGValue{
data.value, payload_.repr & 0x40000000 ? YGUnitPercent : YGUnitPoint};
}
bool isUndefined() const noexcept {

View File

@@ -6,6 +6,7 @@
*/
#include "Utils.h"
#include <stdexcept>
using namespace facebook;
@@ -52,6 +53,13 @@ bool YGFloatsEqual(const float a, const float b) {
return yoga::isUndefined(a) && yoga::isUndefined(b);
}
bool YGDoubleEqual(const double a, const double b) {
if (!yoga::isUndefined(a) && !yoga::isUndefined(b)) {
return fabs(a - b) < 0.0001f;
}
return yoga::isUndefined(a) && yoga::isUndefined(b);
}
float YGFloatSanitize(const float val) {
return yoga::isUndefined(val) ? 0 : val;
}
@@ -65,3 +73,7 @@ YGFloatOptional YGFloatOptionalMax(YGFloatOptional op1, YGFloatOptional op2) {
}
return op1.isUndefined() ? op2 : op1;
}
void throwLogicalErrorWithMessage(const char* message) {
throw std::logic_error(message);
}

View File

@@ -64,6 +64,8 @@ inline bool YGValueEqual(
// difference between two floats is less than 0.0001f or both are undefined.
bool YGFloatsEqual(const float a, const float b);
bool YGDoubleEqual(const double a, const double b);
float YGFloatMax(const float a, const float b);
YGFloatOptional YGFloatOptionalMax(
@@ -141,3 +143,5 @@ inline YGFloatOptional YGResolveValueMargin(
const float ownerSize) {
return value.isAuto() ? YGFloatOptional{0} : YGResolveValue(value, ownerSize);
}
void throwLogicalErrorWithMessage(const char* message);

View File

@@ -179,6 +179,8 @@ const char* YGOverflowToString(const YGOverflow value) {
const char* YGPositionTypeToString(const YGPositionType value) {
switch (value) {
case YGPositionTypeStatic:
return "static";
case YGPositionTypeRelative:
return "relative";
case YGPositionTypeAbsolute:

View File

@@ -128,7 +128,11 @@ YG_ENUM_SEQ_DECL(
YGOverflowHidden,
YGOverflowScroll)
YG_ENUM_SEQ_DECL(YGPositionType, YGPositionTypeRelative, YGPositionTypeAbsolute)
YG_ENUM_SEQ_DECL(
YGPositionType,
YGPositionTypeStatic,
YGPositionTypeRelative,
YGPositionTypeAbsolute)
YG_ENUM_DECL(
YGPrintOptions,

View File

@@ -6,10 +6,12 @@
*/
#pragma once
#include "Bitfield.h"
#include "BitUtils.h"
#include "YGFloatOptional.h"
#include "Yoga-internal.h"
using namespace facebook::yoga;
struct YGLayout {
std::array<float, 4> position = {};
std::array<float, 2> dimensions = {{YGUndefined, YGUndefined}};
@@ -18,12 +20,14 @@ struct YGLayout {
std::array<float, 4> padding = {};
private:
static constexpr size_t directionIdx = 0;
static constexpr size_t didUseLegacyFlagIdx = 1;
static constexpr size_t doesLegacyStretchFlagAffectsLayoutIdx = 2;
static constexpr size_t hadOverflowIdx = 3;
facebook::yoga::Bitfield<uint8_t, YGDirection, bool, bool, bool> flags_ =
{YGDirectionInherit, false, false, false};
static constexpr size_t directionOffset = 0;
static constexpr size_t didUseLegacyFlagOffset =
directionOffset + facebook::yoga::detail::bitWidthFn<YGDirection>();
static constexpr size_t doesLegacyStretchFlagAffectsLayoutOffset =
didUseLegacyFlagOffset + 1;
static constexpr size_t hadOverflowOffset =
doesLegacyStretchFlagAffectsLayoutOffset + 1;
uint8_t flags = 0;
public:
uint32_t computedFlexBasisGeneration = 0;
@@ -32,7 +36,7 @@ public:
// Instead of recomputing the entire layout every single time, we cache some
// information to break early when nothing changed
uint32_t generationCount = 0;
YGDirection lastOwnerDirection = (YGDirection) -1;
YGDirection lastOwnerDirection = YGDirectionInherit;
uint32_t nextCachedMeasurementsIndex = 0;
std::array<YGCachedMeasurement, YG_MAX_CACHED_RESULT_COUNT>
@@ -41,27 +45,41 @@ public:
YGCachedMeasurement cachedLayout = YGCachedMeasurement();
YGDirection direction() const { return flags_.at<directionIdx>(); }
decltype(flags_)::Ref<directionIdx> direction() {
return flags_.at<directionIdx>();
YGDirection direction() const {
return facebook::yoga::detail::getEnumData<YGDirection>(
flags, directionOffset);
}
bool didUseLegacyFlag() const { return flags_.at<didUseLegacyFlagIdx>(); }
decltype(flags_)::Ref<didUseLegacyFlagIdx> didUseLegacyFlag() {
return flags_.at<didUseLegacyFlagIdx>();
void setDirection(YGDirection direction) {
facebook::yoga::detail::setEnumData<YGDirection>(
flags, directionOffset, direction);
}
bool didUseLegacyFlag() const {
return facebook::yoga::detail::getBooleanData(
flags, didUseLegacyFlagOffset);
}
void setDidUseLegacyFlag(bool val) {
facebook::yoga::detail::setBooleanData(flags, didUseLegacyFlagOffset, val);
}
bool doesLegacyStretchFlagAffectsLayout() const {
return flags_.at<doesLegacyStretchFlagAffectsLayoutIdx>();
}
decltype(flags_)::Ref<doesLegacyStretchFlagAffectsLayoutIdx>
doesLegacyStretchFlagAffectsLayout() {
return flags_.at<doesLegacyStretchFlagAffectsLayoutIdx>();
return facebook::yoga::detail::getBooleanData(
flags, doesLegacyStretchFlagAffectsLayoutOffset);
}
bool hadOverflow() const { return flags_.at<hadOverflowIdx>(); }
decltype(flags_)::Ref<hadOverflowIdx> hadOverflow() {
return flags_.at<hadOverflowIdx>();
void setDoesLegacyStretchFlagAffectsLayout(bool val) {
facebook::yoga::detail::setBooleanData(
flags, doesLegacyStretchFlagAffectsLayoutOffset, val);
}
bool hadOverflow() const {
return facebook::yoga::detail::getBooleanData(flags, hadOverflowOffset);
}
void setHadOverflow(bool hadOverflow) {
facebook::yoga::detail::setBooleanData(
flags, hadOverflowOffset, hadOverflow);
}
bool operator==(YGLayout layout) const;

View File

@@ -16,7 +16,7 @@ using facebook::yoga::detail::CompactValue;
YGNode::YGNode(YGNode&& node) {
context_ = node.context_;
flags_ = node.flags_;
flags = node.flags;
measure_ = node.measure_;
baseline_ = node.baseline_;
print_ = node.print_;
@@ -29,7 +29,7 @@ YGNode::YGNode(YGNode&& node) {
config_ = node.config_;
resolvedDimensions_ = node.resolvedDimensions_;
for (auto c : children_) {
c->setOwner(c);
c->setOwner(this);
}
}
@@ -42,7 +42,7 @@ YGNode::YGNode(const YGNode& node, YGConfigRef config) : YGNode{node} {
void YGNode::print(void* printContext) {
if (print_.noContext != nullptr) {
if (flags_.at<printUsesContext_>()) {
if (facebook::yoga::detail::getBooleanData(flags, printUsesContext_)) {
print_.withContext(this, printContext);
} else {
print_.noContext(this);
@@ -148,14 +148,14 @@ YGSize YGNode::measure(
YGMeasureMode heightMode,
void* layoutContext) {
return flags_.at<measureUsesContext_>()
return facebook::yoga::detail::getBooleanData(flags, measureUsesContext_)
? measure_.withContext(
this, width, widthMode, height, heightMode, layoutContext)
: measure_.noContext(this, width, widthMode, height, heightMode);
}
float YGNode::baseline(float width, float height, void* layoutContext) {
return flags_.at<baselineUsesContext_>()
return facebook::yoga::detail::getBooleanData(flags, baselineUsesContext_)
? baseline_.withContext(this, width, height, layoutContext)
: baseline_.noContext(this, width, height);
}
@@ -166,7 +166,7 @@ void YGNode::setMeasureFunc(decltype(YGNode::measure_) measureFunc) {
if (measureFunc.noContext == nullptr) {
// TODO: t18095186 Move nodeType to opt-in function and mark appropriate
// places in Litho
flags_.at<nodeType_>() = YGNodeTypeDefault;
setNodeType(YGNodeTypeDefault);
} else {
YGAssertWithNode(
this,
@@ -182,14 +182,14 @@ void YGNode::setMeasureFunc(decltype(YGNode::measure_) measureFunc) {
}
void YGNode::setMeasureFunc(YGMeasureFunc measureFunc) {
flags_.at<measureUsesContext_>() = false;
facebook::yoga::detail::setBooleanData(flags, measureUsesContext_, false);
decltype(YGNode::measure_) m;
m.noContext = measureFunc;
setMeasureFunc(m);
}
YOGA_EXPORT void YGNode::setMeasureFunc(MeasureWithContextFn measureFunc) {
flags_.at<measureUsesContext_>() = true;
facebook::yoga::detail::setBooleanData(flags, measureUsesContext_, true);
decltype(YGNode::measure_) m;
m.withContext = measureFunc;
setMeasureFunc(m);
@@ -208,10 +208,10 @@ void YGNode::insertChild(YGNodeRef child, uint32_t index) {
}
void YGNode::setDirty(bool isDirty) {
if (isDirty == flags_.at<isDirty_>()) {
if (isDirty == facebook::yoga::detail::getBooleanData(flags, isDirty_)) {
return;
}
flags_.at<isDirty_>() = isDirty;
facebook::yoga::detail::setBooleanData(flags, isDirty_, isDirty);
if (isDirty && dirtied_) {
dirtied_(this);
}
@@ -232,7 +232,7 @@ void YGNode::removeChild(uint32_t index) {
}
void YGNode::setLayoutDirection(YGDirection direction) {
layout_.direction() = direction;
layout_.setDirection(direction);
}
void YGNode::setLayoutMargin(float margin, int index) {
@@ -270,7 +270,7 @@ void YGNode::setLayoutMeasuredDimension(float measuredDimension, int index) {
}
void YGNode::setLayoutHadOverflow(bool hadOverflow) {
layout_.hadOverflow() = hadOverflow;
layout_.setHadOverflow(hadOverflow);
}
void YGNode::setLayoutDimension(float dimension, int index) {
@@ -307,6 +307,9 @@ void YGNode::setPosition(
const YGFlexDirection crossAxis =
YGFlexDirectionCross(mainAxis, directionRespectingRoot);
// Here we should check for `YGPositionTypeStatic` and in this case zero inset
// properties (left, right, top, bottom, begin, end).
// https://www.w3.org/TR/css-position-3/#valdef-position-static
const YGFloatOptional relativePositionMain =
relativePosition(mainAxis, mainSize);
const YGFloatOptional relativePositionCross =
@@ -351,7 +354,9 @@ YGValue YGNode::resolveFlexBasisPtr() const {
return flexBasis;
}
if (!style_.flex().isUndefined() && style_.flex().unwrap() > 0.0f) {
return flags_.at<useWebDefaults_>() ? YGValueAuto : YGValueZero;
return facebook::yoga::detail::getBooleanData(flags, useWebDefaults_)
? YGValueAuto
: YGValueZero;
}
return YGValueAuto;
}
@@ -390,7 +395,7 @@ void YGNode::cloneChildrenIfNeeded(void* cloneContext) {
}
void YGNode::markDirtyAndPropogate() {
if (!flags_.at<isDirty_>()) {
if (!facebook::yoga::detail::getBooleanData(flags, isDirty_)) {
setDirty(true);
setLayoutComputedFlexBasis(YGFloatOptional());
if (owner_) {
@@ -400,7 +405,7 @@ void YGNode::markDirtyAndPropogate() {
}
void YGNode::markDirtyAndPropogateDownwards() {
flags_.at<isDirty_>() = true;
facebook::yoga::detail::setBooleanData(flags, isDirty_, true);
for_each(children_.begin(), children_.end(), [](YGNodeRef childNode) {
childNode->markDirtyAndPropogateDownwards();
});
@@ -427,17 +432,18 @@ float YGNode::resolveFlexShrink() const {
if (!style_.flexShrink().isUndefined()) {
return style_.flexShrink().unwrap();
}
if (!flags_.at<useWebDefaults_>() && !style_.flex().isUndefined() &&
style_.flex().unwrap() < 0.0f) {
if (!facebook::yoga::detail::getBooleanData(flags, useWebDefaults_) &&
!style_.flex().isUndefined() && style_.flex().unwrap() < 0.0f) {
return -style_.flex().unwrap();
}
return flags_.at<useWebDefaults_>() ? kWebDefaultFlexShrink
: kDefaultFlexShrink;
return facebook::yoga::detail::getBooleanData(flags, useWebDefaults_)
? kWebDefaultFlexShrink
: kDefaultFlexShrink;
}
bool YGNode::isNodeFlexible() {
return (
(style_.positionType() == YGPositionTypeRelative) &&
(style_.positionType() != YGPositionTypeAbsolute) &&
(resolveFlexGrow() != 0 || resolveFlexShrink() != 0));
}
@@ -536,11 +542,11 @@ bool YGNode::didUseLegacyFlag() {
void YGNode::setLayoutDoesLegacyFlagAffectsLayout(
bool doesLegacyFlagAffectsLayout) {
layout_.doesLegacyStretchFlagAffectsLayout() = doesLegacyFlagAffectsLayout;
layout_.setDoesLegacyStretchFlagAffectsLayout(doesLegacyFlagAffectsLayout);
}
void YGNode::setLayoutDidUseLegacyFlag(bool didUseLegacyFlag) {
layout_.didUseLegacyFlag() = didUseLegacyFlag;
layout_.setDidUseLegacyFlag(didUseLegacyFlag);
}
bool YGNode::isLayoutTreeEqualToNode(const YGNode& node) const {
@@ -577,7 +583,8 @@ void YGNode::reset() {
clearChildren();
auto webDefaults = flags_.at<useWebDefaults_>();
auto webDefaults =
facebook::yoga::detail::getBooleanData(flags, useWebDefaults_);
*this = YGNode{getConfig()};
if (webDefaults) {
useWebDefaults();

View File

@@ -6,9 +6,12 @@
*/
#pragma once
#ifdef __cplusplus
#include <cstdint>
#include <stdio.h>
#include "Bitfield.h"
#include "BitUtils.h"
#include "CompactValue.h"
#include "YGConfig.h"
#include "YGLayout.h"
@@ -35,10 +38,7 @@ private:
static constexpr size_t useWebDefaults_ = 7;
void* context_ = nullptr;
using Flags = facebook::yoga::
Bitfield<uint8_t, bool, bool, bool, YGNodeType, bool, bool, bool, bool>;
Flags flags_ =
{true, false, false, YGNodeTypeDefault, false, false, false, false};
uint8_t flags = 1;
uint8_t reserved_ = 0;
union {
YGMeasureFunc noContext;
@@ -70,13 +70,13 @@ private:
void setBaselineFunc(decltype(baseline_));
void useWebDefaults() {
flags_.at<useWebDefaults_>() = true;
facebook::yoga::detail::setBooleanData(flags, useWebDefaults_, true);
style_.flexDirection() = YGFlexDirectionRow;
style_.alignContent() = YGAlignStretch;
}
// DANGER DANGER DANGER!
// If the the node assigned to has children, we'd either have to deallocate
// If the node assigned to has children, we'd either have to deallocate
// them (potentially incorrect) or ignore them (danger of leaks). Only ever
// use this after checking that there are no children.
// DO NOT CHANGE THE VISIBILITY OF THIS METHOD!
@@ -114,9 +114,13 @@ public:
void print(void*);
bool getHasNewLayout() const { return flags_.at<hasNewLayout_>(); }
bool getHasNewLayout() const {
return facebook::yoga::detail::getBooleanData(flags, hasNewLayout_);
}
YGNodeType getNodeType() const { return flags_.at<nodeType_>(); }
YGNodeType getNodeType() const {
return facebook::yoga::detail::getEnumData<YGNodeType>(flags, nodeType_);
}
bool hasMeasureFunc() const noexcept { return measure_.noContext != nullptr; }
@@ -142,7 +146,9 @@ public:
uint32_t getLineIndex() const { return lineIndex_; }
bool isReferenceBaseline() { return flags_.at<isReferenceBaseline_>(); }
bool isReferenceBaseline() {
return facebook::yoga::detail::getBooleanData(flags, isReferenceBaseline_);
}
// returns the YGNodeRef that owns this YGNode. An owner is used to identify
// the YogaTree that a YGNode belongs to. This method will return the parent
@@ -175,7 +181,9 @@ public:
YGConfigRef getConfig() const { return config_; }
bool isDirty() const { return flags_.at<isDirty_>(); }
bool isDirty() const {
return facebook::yoga::detail::getBooleanData(flags, isDirty_);
}
std::array<YGValue, 2> getResolvedDimensions() const {
return resolvedDimensions_;
@@ -223,19 +231,22 @@ public:
void setPrintFunc(YGPrintFunc printFunc) {
print_.noContext = printFunc;
flags_.at<printUsesContext_>() = false;
facebook::yoga::detail::setBooleanData(flags, printUsesContext_, false);
}
void setPrintFunc(PrintWithContextFn printFunc) {
print_.withContext = printFunc;
flags_.at<printUsesContext_>() = true;
facebook::yoga::detail::setBooleanData(flags, printUsesContext_, true);
}
void setPrintFunc(std::nullptr_t) { setPrintFunc(YGPrintFunc{nullptr}); }
void setHasNewLayout(bool hasNewLayout) {
flags_.at<hasNewLayout_>() = hasNewLayout;
facebook::yoga::detail::setBooleanData(flags, hasNewLayout_, hasNewLayout);
}
void setNodeType(YGNodeType nodeType) { flags_.at<nodeType_>() = nodeType; }
void setNodeType(YGNodeType nodeType) {
return facebook::yoga::detail::setEnumData<YGNodeType>(
flags, nodeType_, nodeType);
}
void setMeasureFunc(YGMeasureFunc measureFunc);
void setMeasureFunc(MeasureWithContextFn);
@@ -244,11 +255,11 @@ public:
}
void setBaselineFunc(YGBaselineFunc baseLineFunc) {
flags_.at<baselineUsesContext_>() = false;
facebook::yoga::detail::setBooleanData(flags, baselineUsesContext_, false);
baseline_.noContext = baseLineFunc;
}
void setBaselineFunc(BaselineWithContextFn baseLineFunc) {
flags_.at<baselineUsesContext_>() = true;
facebook::yoga::detail::setBooleanData(flags, baselineUsesContext_, true);
baseline_.withContext = baseLineFunc;
}
void setBaselineFunc(std::nullptr_t) {
@@ -264,7 +275,8 @@ public:
void setLineIndex(uint32_t lineIndex) { lineIndex_ = lineIndex; }
void setIsReferenceBaseline(bool isReferenceBaseline) {
flags_.at<isReferenceBaseline_>() = isReferenceBaseline;
facebook::yoga::detail::setBooleanData(
flags, isReferenceBaseline_, isReferenceBaseline);
}
void setOwner(YGNodeRef owner) { owner_ = owner; }
@@ -321,3 +333,5 @@ public:
bool isLayoutTreeEqualToNode(const YGNode& node) const;
void reset();
};
#endif

View File

@@ -6,16 +6,19 @@
*/
#pragma once
#ifdef __cplusplus
#include <algorithm>
#include <array>
#include <cstdint>
#include <type_traits>
#include "Bitfield.h"
#include "CompactValue.h"
#include "YGEnums.h"
#include "YGFloatOptional.h"
#include "Yoga-internal.h"
#include "Yoga.h"
#include "BitUtils.h"
class YOGA_EXPORT YGStyle {
template <typename Enum>
@@ -27,6 +30,19 @@ public:
using Dimensions = Values<YGDimension>;
using Edges = Values<YGEdge>;
template <typename T>
struct BitfieldRef {
YGStyle& style;
size_t offset;
operator T() const {
return facebook::yoga::detail::getEnumData<T>(style.flags, offset);
}
BitfieldRef<T>& operator=(T x) {
facebook::yoga::detail::setEnumData<T>(style.flags, offset, x);
return *this;
}
};
template <typename T, T YGStyle::*Prop>
struct Ref {
YGStyle& style;
@@ -60,43 +76,35 @@ public:
CompactValue operator[](Idx idx) const { return (style.*Prop)[idx]; }
};
YGStyle() = default;
YGStyle() {
alignContent() = YGAlignFlexStart;
alignItems() = YGAlignStretch;
}
~YGStyle() = default;
private:
static constexpr size_t directionIdx = 0;
static constexpr size_t flexDirectionIdx = 1;
static constexpr size_t justifyContentIdx = 2;
static constexpr size_t alignContentIdx = 3;
static constexpr size_t alignItemsIdx = 4;
static constexpr size_t alignSelfIdx = 5;
static constexpr size_t positionTypeIdx = 6;
static constexpr size_t flexWrapIdx = 7;
static constexpr size_t overflowIdx = 8;
static constexpr size_t displayIdx = 9;
using Flags = facebook::yoga::Bitfield<
uint32_t,
YGDirection,
YGFlexDirection,
YGJustify,
YGAlign,
YGAlign,
YGAlign,
YGPositionType,
YGWrap,
YGOverflow,
YGDisplay>;
static constexpr size_t directionOffset = 0;
static constexpr size_t flexdirectionOffset =
directionOffset + facebook::yoga::detail::bitWidthFn<YGDirection>();
static constexpr size_t justifyContentOffset = flexdirectionOffset +
facebook::yoga::detail::bitWidthFn<YGFlexDirection>();
static constexpr size_t alignContentOffset =
justifyContentOffset + facebook::yoga::detail::bitWidthFn<YGJustify>();
static constexpr size_t alignItemsOffset =
alignContentOffset + facebook::yoga::detail::bitWidthFn<YGAlign>();
static constexpr size_t alignSelfOffset =
alignItemsOffset + facebook::yoga::detail::bitWidthFn<YGAlign>();
static constexpr size_t positionTypeOffset =
alignSelfOffset + facebook::yoga::detail::bitWidthFn<YGAlign>();
static constexpr size_t flexWrapOffset =
positionTypeOffset + facebook::yoga::detail::bitWidthFn<YGPositionType>();
static constexpr size_t overflowOffset =
flexWrapOffset + facebook::yoga::detail::bitWidthFn<YGWrap>();
static constexpr size_t displayOffset =
overflowOffset + facebook::yoga::detail::bitWidthFn<YGOverflow>();
uint32_t flags = 0;
Flags flags_ = {YGDirectionInherit,
YGFlexDirectionColumn,
YGJustifyFlexStart,
YGAlignFlexStart,
YGAlignStretch,
YGAlignAuto,
YGPositionTypeRelative,
YGWrapNoWrap,
YGOverflowVisible,
YGDisplayFlex};
YGFloatOptional flex_ = {};
YGFloatOptional flexGrow_ = {};
YGFloatOptional flexShrink_ = {};
@@ -115,45 +123,68 @@ public:
// for library users needing a type
using ValueRepr = std::remove_reference<decltype(margin_[0])>::type;
YGDirection direction() const { return flags_.at<directionIdx>(); }
Flags::Ref<directionIdx> direction() { return flags_.at<directionIdx>(); }
YGDirection direction() const {
return facebook::yoga::detail::getEnumData<YGDirection>(
flags, directionOffset);
}
BitfieldRef<YGDirection> direction() { return {*this, directionOffset}; }
YGFlexDirection flexDirection() const {
return flags_.at<flexDirectionIdx>();
return facebook::yoga::detail::getEnumData<YGFlexDirection>(
flags, flexdirectionOffset);
}
Flags::Ref<flexDirectionIdx> flexDirection() {
return flags_.at<flexDirectionIdx>();
BitfieldRef<YGFlexDirection> flexDirection() {
return {*this, flexdirectionOffset};
}
YGJustify justifyContent() const { return flags_.at<justifyContentIdx>(); }
Flags::Ref<justifyContentIdx> justifyContent() {
return flags_.at<justifyContentIdx>();
YGJustify justifyContent() const {
return facebook::yoga::detail::getEnumData<YGJustify>(
flags, justifyContentOffset);
}
BitfieldRef<YGJustify> justifyContent() {
return {*this, justifyContentOffset};
}
YGAlign alignContent() const { return flags_.at<alignContentIdx>(); }
Flags::Ref<alignContentIdx> alignContent() {
return flags_.at<alignContentIdx>();
YGAlign alignContent() const {
return facebook::yoga::detail::getEnumData<YGAlign>(
flags, alignContentOffset);
}
BitfieldRef<YGAlign> alignContent() { return {*this, alignContentOffset}; }
YGAlign alignItems() const {
return facebook::yoga::detail::getEnumData<YGAlign>(
flags, alignItemsOffset);
}
BitfieldRef<YGAlign> alignItems() { return {*this, alignItemsOffset}; }
YGAlign alignSelf() const {
return facebook::yoga::detail::getEnumData<YGAlign>(flags, alignSelfOffset);
}
BitfieldRef<YGAlign> alignSelf() { return {*this, alignSelfOffset}; }
YGPositionType positionType() const {
return facebook::yoga::detail::getEnumData<YGPositionType>(
flags, positionTypeOffset);
}
BitfieldRef<YGPositionType> positionType() {
return {*this, positionTypeOffset};
}
YGAlign alignItems() const { return flags_.at<alignItemsIdx>(); }
Flags::Ref<alignItemsIdx> alignItems() { return flags_.at<alignItemsIdx>(); }
YGAlign alignSelf() const { return flags_.at<alignSelfIdx>(); }
Flags::Ref<alignSelfIdx> alignSelf() { return flags_.at<alignSelfIdx>(); }
YGPositionType positionType() const { return flags_.at<positionTypeIdx>(); }
Flags::Ref<positionTypeIdx> positionType() {
return flags_.at<positionTypeIdx>();
YGWrap flexWrap() const {
return facebook::yoga::detail::getEnumData<YGWrap>(flags, flexWrapOffset);
}
BitfieldRef<YGWrap> flexWrap() { return {*this, flexWrapOffset}; }
YGWrap flexWrap() const { return flags_.at<flexWrapIdx>(); }
Flags::Ref<flexWrapIdx> flexWrap() { return flags_.at<flexWrapIdx>(); }
YGOverflow overflow() const {
return facebook::yoga::detail::getEnumData<YGOverflow>(
flags, overflowOffset);
}
BitfieldRef<YGOverflow> overflow() { return {*this, overflowOffset}; }
YGOverflow overflow() const { return flags_.at<overflowIdx>(); }
Flags::Ref<overflowIdx> overflow() { return flags_.at<overflowIdx>(); }
YGDisplay display() const { return flags_.at<displayIdx>(); }
Flags::Ref<displayIdx> display() { return flags_.at<displayIdx>(); }
YGDisplay display() const {
return facebook::yoga::detail::getEnumData<YGDisplay>(flags, displayOffset);
}
BitfieldRef<YGDisplay> display() { return {*this, displayOffset}; }
YGFloatOptional flex() const { return flex_; }
Ref<YGFloatOptional, &YGStyle::flex_> flex() { return {*this}; }
@@ -201,3 +232,5 @@ YOGA_EXPORT bool operator==(const YGStyle& lhs, const YGStyle& rhs);
YOGA_EXPORT inline bool operator!=(const YGStyle& lhs, const YGStyle& rhs) {
return !(lhs == rhs);
}
#endif

View File

@@ -11,6 +11,13 @@
#include "YGEnums.h"
#include "YGMacros.h"
#if defined(_MSC_VER) && defined(__clang__)
#define COMPILING_WITH_CLANG_ON_WINDOWS
#endif
#if defined(COMPILING_WITH_CLANG_ON_WINDOWS)
#include <limits>
constexpr float YGUndefined = std::numeric_limits<float>::quiet_NaN();
#else
YG_EXTERN_C_BEGIN
// Not defined in MSVC++
@@ -20,6 +27,7 @@ static const uint32_t __nan = 0x7fc00000;
#endif
#define YGUndefined NAN
#endif
typedef struct YGValue {
float value;
@@ -30,7 +38,10 @@ YOGA_EXPORT extern const YGValue YGValueAuto;
YOGA_EXPORT extern const YGValue YGValueUndefined;
YOGA_EXPORT extern const YGValue YGValueZero;
#if !defined(COMPILING_WITH_CLANG_ON_WINDOWS)
YG_EXTERN_C_END
#endif
#undef COMPILING_WITH_CLANG_ON_WINDOWS
#ifdef __cplusplus

View File

@@ -54,10 +54,10 @@ struct YGCachedMeasurement {
float computedHeight;
YGCachedMeasurement()
: availableWidth(0),
availableHeight(0),
widthMeasureMode((YGMeasureMode) -1),
heightMeasureMode((YGMeasureMode) -1),
: availableWidth(-1),
availableHeight(-1),
widthMeasureMode(YGMeasureModeUndefined),
heightMeasureMode(YGMeasureModeUndefined),
computedWidth(-1),
computedHeight(-1) {}

View File

@@ -249,9 +249,6 @@ YOGA_EXPORT YGNodeRef YGNodeClone(YGNodeRef oldNode) {
static YGConfigRef YGConfigClone(const YGConfig& oldConfig) {
const YGConfigRef config = new YGConfig(oldConfig);
YGAssert(config != nullptr, "Could not allocate memory for config");
if (config == nullptr) {
abort();
}
gConfigInstanceCount++;
return config;
}
@@ -386,6 +383,14 @@ YOGA_EXPORT void YGNodeInsertChild(
owner->markDirtyAndPropogate();
}
YOGA_EXPORT void YGNodeSwapChild(
const YGNodeRef owner,
const YGNodeRef child,
const uint32_t index) {
owner->replaceChild(child, index);
child->setOwner(owner);
}
YOGA_EXPORT void YGNodeRemoveChild(
const YGNodeRef owner,
const YGNodeRef excludedChild) {
@@ -1126,7 +1131,7 @@ static bool YGIsBaselineLayout(const YGNodeRef node) {
const uint32_t childCount = YGNodeGetChildCount(node);
for (uint32_t i = 0; i < childCount; i++) {
const YGNodeRef child = YGNodeGetChild(node, i);
if (child->getStyle().positionType() == YGPositionTypeRelative &&
if (child->getStyle().positionType() != YGPositionTypeAbsolute &&
child->getStyle().alignSelf() == YGAlignBaseline) {
return true;
}
@@ -1655,8 +1660,8 @@ static void YGNodeAbsoluteLayoutChild(
static void YGNodeWithMeasureFuncSetMeasuredDimensions(
const YGNodeRef node,
const float availableWidth,
const float availableHeight,
float availableWidth,
float availableHeight,
const YGMeasureMode widthMeasureMode,
const YGMeasureMode heightMeasureMode,
const float ownerWidth,
@@ -1669,14 +1674,21 @@ static void YGNodeWithMeasureFuncSetMeasuredDimensions(
node->hasMeasureFunc(),
"Expected node to have custom measure function");
if (widthMeasureMode == YGMeasureModeUndefined) {
availableWidth = YGUndefined;
}
if (heightMeasureMode == YGMeasureModeUndefined) {
availableHeight = YGUndefined;
}
const float paddingAndBorderAxisRow =
YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, availableWidth);
const float paddingAndBorderAxisColumn = YGNodePaddingAndBorderForAxis(
node, YGFlexDirectionColumn, availableWidth);
YGNodePaddingAndBorderForAxis(node, YGFlexDirectionRow, ownerWidth);
const float paddingAndBorderAxisColumn =
YGNodePaddingAndBorderForAxis(node, YGFlexDirectionColumn, ownerWidth);
const float marginAxisRow =
node->getMarginForAxis(YGFlexDirectionRow, availableWidth).unwrap();
node->getMarginForAxis(YGFlexDirectionRow, ownerWidth).unwrap();
const float marginAxisColumn =
node->getMarginForAxis(YGFlexDirectionColumn, availableWidth).unwrap();
node->getMarginForAxis(YGFlexDirectionColumn, ownerWidth).unwrap();
// We want to make sure we don't call measure with negative size
const float innerWidth = YGFloatIsUndefined(availableWidth)
@@ -1868,15 +1880,17 @@ static float YGNodeCalculateAvailableInnerDim(
const YGNodeConstRef node,
YGFlexDirection axis,
float availableDim,
float ownerDim) {
float ownerDim,
float ownerDimForMarginPadding) {
YGFlexDirection direction =
YGFlexDirectionIsRow(axis) ? YGFlexDirectionRow : YGFlexDirectionColumn;
YGDimension dimension =
YGFlexDirectionIsRow(axis) ? YGDimensionWidth : YGDimensionHeight;
const float margin = node->getMarginForAxis(direction, ownerDim).unwrap();
const float margin =
node->getMarginForAxis(direction, ownerDimForMarginPadding).unwrap();
const float paddingAndBorder =
YGNodePaddingAndBorderForAxis(node, direction, ownerDim);
YGNodePaddingAndBorderForAxis(node, direction, ownerDimForMarginPadding);
float availableInnerDim = availableDim - margin - paddingAndBorder;
// Max dimension overrides predefined dimension value; Min dimension in turn
@@ -2328,7 +2342,8 @@ static void YGDistributeFreeSpaceFirstPass(
// first and second passes.
deltaFreeSpace += boundMainSize - childFlexBasis;
collectedFlexItemsValues.totalFlexShrinkScaledFactors -=
flexShrinkScaledFactor;
(-currentRelativeChild->resolveFlexShrink() *
currentRelativeChild->getLayout().computedFlexBasis.unwrap());
}
}
} else if (
@@ -2490,7 +2505,7 @@ static void YGJustifyMainAxis(
i < collectedFlexItemsValues.endOfLineIndex;
i++) {
const YGNodeRef child = node->getChild(i);
if (child->getStyle().positionType() == YGPositionTypeRelative) {
if (child->getStyle().positionType() != YGPositionTypeAbsolute) {
if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) {
numberOfAutoMarginsOnCurrentLine++;
}
@@ -2574,7 +2589,7 @@ static void YGJustifyMainAxis(
// Now that we placed the element, we need to update the variables.
// We need to do that only for relative elements. Absolute elements do not
// take part in that phase.
if (childStyle.positionType() == YGPositionTypeRelative) {
if (childStyle.positionType() != YGPositionTypeAbsolute) {
if (child->marginLeadingValue(mainAxis).unit == YGUnitAuto) {
collectedFlexItemsValues.mainDim +=
collectedFlexItemsValues.remainingFreeSpace /
@@ -2894,9 +2909,9 @@ static void YGNodelayoutImpl(
// STEP 2: DETERMINE AVAILABLE SIZE IN MAIN AND CROSS DIRECTIONS
float availableInnerWidth = YGNodeCalculateAvailableInnerDim(
node, YGFlexDirectionRow, availableWidth, ownerWidth);
node, YGFlexDirectionRow, availableWidth, ownerWidth, ownerWidth);
float availableInnerHeight = YGNodeCalculateAvailableInnerDim(
node, YGFlexDirectionColumn, availableHeight, ownerHeight);
node, YGFlexDirectionColumn, availableHeight, ownerHeight, ownerWidth);
float availableInnerMainDim =
isMainAxisRow ? availableInnerWidth : availableInnerHeight;
@@ -3296,7 +3311,7 @@ static void YGNodelayoutImpl(
if (child->getStyle().display() == YGDisplayNone) {
continue;
}
if (child->getStyle().positionType() == YGPositionTypeRelative) {
if (child->getStyle().positionType() != YGPositionTypeAbsolute) {
if (child->getLineIndex() != i) {
break;
}
@@ -3338,7 +3353,7 @@ static void YGNodelayoutImpl(
if (child->getStyle().display() == YGDisplayNone) {
continue;
}
if (child->getStyle().positionType() == YGPositionTypeRelative) {
if (child->getStyle().positionType() != YGPositionTypeAbsolute) {
switch (YGNodeAlignItem(node, child)) {
case YGAlignFlexStart: {
child->setLayoutPosition(
@@ -3516,8 +3531,8 @@ static void YGNodelayoutImpl(
YGNodeBoundAxisWithinMinAndMax(
node,
crossAxis,
YGFloatOptional{totalLineCrossDim +
paddingAndBorderAxisCross},
YGFloatOptional{
totalLineCrossDim + paddingAndBorderAxisCross},
crossAxisownerSize)
.unwrap()),
paddingAndBorderAxisCross),
@@ -3529,7 +3544,7 @@ static void YGNodelayoutImpl(
if (performLayout && node->getStyle().flexWrap() == YGWrapWrapReverse) {
for (uint32_t i = 0; i < childCount; i++) {
const YGNodeRef child = YGNodeGetChild(node, i);
if (child->getStyle().positionType() == YGPositionTypeRelative) {
if (child->getStyle().positionType() != YGPositionTypeAbsolute) {
child->setLayoutPosition(
node->getLayout().measuredDimensions[dim[crossAxis]] -
child->getLayout().position[pos[crossAxis]] -
@@ -3646,14 +3661,14 @@ static inline bool YGMeasureModeNewMeasureSizeIsStricterAndStillValid(
}
YOGA_EXPORT float YGRoundValueToPixelGrid(
const float value,
const float pointScaleFactor,
const double value,
const double pointScaleFactor,
const bool forceCeil,
const bool forceFloor) {
float scaledValue = value * pointScaleFactor;
double scaledValue = ((double) value) * pointScaleFactor;
// We want to calculate `fractial` such that `floor(scaledValue) = scaledValue
// - fractial`.
float fractial = fmodf(scaledValue, 1.0f);
double fractial = fmod(scaledValue, 1.0f);
if (fractial < 0) {
// This branch is for handling negative numbers for `value`.
//
@@ -3672,10 +3687,10 @@ YOGA_EXPORT float YGRoundValueToPixelGrid(
// - Finding the `floor`: -2.2 - fractial2 = -2.2 - 0.8 = -3
++fractial;
}
if (YGFloatsEqual(fractial, 0)) {
if (YGDoubleEqual(fractial, 0)) {
// First we check if the value is already rounded
scaledValue = scaledValue - fractial;
} else if (YGFloatsEqual(fractial, 1.0f)) {
} else if (YGDoubleEqual(fractial, 1.0f)) {
scaledValue = scaledValue - fractial + 1.0f;
} else if (forceCeil) {
// Next we check if we need to use forced rounding
@@ -3686,7 +3701,7 @@ YOGA_EXPORT float YGRoundValueToPixelGrid(
// Finally we just round the value
scaledValue = scaledValue - fractial +
(!YGFloatIsUndefined(fractial) &&
(fractial > 0.5f || YGFloatsEqual(fractial, 0.5f))
(fractial > 0.5f || YGDoubleEqual(fractial, 0.5f))
? 1.0f
: 0.0f);
}
@@ -3803,8 +3818,10 @@ bool YGLayoutNodeInternal(
if (needToVisitNode) {
// Invalidate the cached results.
layout->nextCachedMeasurementsIndex = 0;
layout->cachedLayout.widthMeasureMode = (YGMeasureMode) -1;
layout->cachedLayout.heightMeasureMode = (YGMeasureMode) -1;
layout->cachedLayout.availableWidth = -1;
layout->cachedLayout.availableHeight = -1;
layout->cachedLayout.widthMeasureMode = YGMeasureModeUndefined;
layout->cachedLayout.heightMeasureMode = YGMeasureModeUndefined;
layout->cachedLayout.computedWidth = -1;
layout->cachedLayout.computedHeight = -1;
}
@@ -4061,24 +4078,24 @@ YOGA_EXPORT void YGConfigSetPointScaleFactor(
static void YGRoundToPixelGrid(
const YGNodeRef node,
const float pointScaleFactor,
const float absoluteLeft,
const float absoluteTop) {
const double pointScaleFactor,
const double absoluteLeft,
const double absoluteTop) {
if (pointScaleFactor == 0.0f) {
return;
}
const float nodeLeft = node->getLayout().position[YGEdgeLeft];
const float nodeTop = node->getLayout().position[YGEdgeTop];
const double nodeLeft = node->getLayout().position[YGEdgeLeft];
const double nodeTop = node->getLayout().position[YGEdgeTop];
const float nodeWidth = node->getLayout().dimensions[YGDimensionWidth];
const float nodeHeight = node->getLayout().dimensions[YGDimensionHeight];
const double nodeWidth = node->getLayout().dimensions[YGDimensionWidth];
const double nodeHeight = node->getLayout().dimensions[YGDimensionHeight];
const float absoluteNodeLeft = absoluteLeft + nodeLeft;
const float absoluteNodeTop = absoluteTop + nodeTop;
const double absoluteNodeLeft = absoluteLeft + nodeLeft;
const double absoluteNodeTop = absoluteTop + nodeTop;
const float absoluteNodeRight = absoluteNodeLeft + nodeWidth;
const float absoluteNodeBottom = absoluteNodeTop + nodeHeight;
const double absoluteNodeRight = absoluteNodeLeft + nodeWidth;
const double absoluteNodeBottom = absoluteNodeTop + nodeHeight;
// If a node has a custom measure function we never want to round down its
// size as this could lead to unwanted text truncation.
@@ -4096,11 +4113,11 @@ static void YGRoundToPixelGrid(
// whole number, we don't have any fraction To verify if the result is close
// to whole number we want to check both floor and ceil numbers
const bool hasFractionalWidth =
!YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 0) &&
!YGFloatsEqual(fmodf(nodeWidth * pointScaleFactor, 1.0), 1.0);
!YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 0) &&
!YGDoubleEqual(fmod(nodeWidth * pointScaleFactor, 1.0), 1.0);
const bool hasFractionalHeight =
!YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 0) &&
!YGFloatsEqual(fmodf(nodeHeight * pointScaleFactor, 1.0), 1.0);
!YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 0) &&
!YGDoubleEqual(fmod(nodeHeight * pointScaleFactor, 1.0), 1.0);
node->setLayoutDimension(
YGRoundValueToPixelGrid(
@@ -4321,6 +4338,7 @@ YOGA_EXPORT void YGConfigSetShouldDiffLayoutWithoutLegacyStretchBehaviour(
void YGAssert(const bool condition, const char* message) {
if (!condition) {
Log::log(YGNodeRef{nullptr}, YGLogLevelFatal, nullptr, "%s\n", message);
throwLogicalErrorWithMessage(message);
}
}
@@ -4330,6 +4348,7 @@ void YGAssertWithNode(
const char* message) {
if (!condition) {
Log::log(node, YGLogLevelFatal, nullptr, "%s\n", message);
throwLogicalErrorWithMessage(message);
}
}
@@ -4339,6 +4358,7 @@ void YGAssertWithConfig(
const char* message) {
if (!condition) {
Log::log(config, YGLogLevelFatal, nullptr, "%s\n", message);
throwLogicalErrorWithMessage(message);
}
}

View File

@@ -69,6 +69,11 @@ WIN_EXPORT void YGNodeInsertChild(
YGNodeRef child,
uint32_t index);
WIN_EXPORT void YGNodeSwapChild(
YGNodeRef node,
YGNodeRef child,
uint32_t index);
WIN_EXPORT void YGNodeRemoveChild(YGNodeRef node, YGNodeRef child);
WIN_EXPORT void YGNodeRemoveAllChildren(YGNodeRef node);
WIN_EXPORT YGNodeRef YGNodeGetChild(YGNodeRef node, uint32_t index);
@@ -347,8 +352,8 @@ WIN_EXPORT void YGConfigSetContext(YGConfigRef config, void* context);
WIN_EXPORT void* YGConfigGetContext(YGConfigRef config);
WIN_EXPORT float YGRoundValueToPixelGrid(
float value,
float pointScaleFactor,
double value,
double pointScaleFactor,
bool forceCeil,
bool forceFloor);

View File

@@ -8,7 +8,6 @@
#include "event.h"
#include <atomic>
#include <memory>
#include <stdexcept>
namespace facebook {
namespace yoga {

View File

@@ -11,6 +11,7 @@
#include <vector>
#include <array>
#include <yoga/YGEnums.h>
#include <stdint.h>
struct YGConfig;
struct YGNode;
@@ -90,9 +91,6 @@ struct YOGA_EXPORT Event {
static void publish(const YGNode& node, const TypedData<E>& eventData = {}) {
#ifdef YG_ENABLE_EVENTS
publish(node, E, Data{eventData});
#else
(void)node;
(void)eventData;
#endif
}

View File

@@ -26,10 +26,6 @@ void vlog(
va_list args) {
YGConfig* logConfig = config != nullptr ? config : YGConfigGetDefault();
logConfig->log(logConfig, node, level, context, format, args);
if (level == YGLogLevelFatal) {
abort();
}
}
} // namespace