Make numerous improvements

- Python static hello world now 1.8mb
- Python static fully loaded now 10mb
- Python HTTPS client now uses MbedTLS
- Python REPL now completes import stmts
- Increase stack size for Python for now
- Begin synthesizing posixpath and ntpath
- Restore Python \N{UNICODE NAME} support
- Restore Python NFKD symbol normalization
- Add optimized code path for Intel SHA-NI
- Get more Python unit tests passing faster
- Get Python help() pagination working on NT
- Python hashlib now supports MbedTLS PBKDF2
- Make memcpy/memmove/memcmp/bcmp/etc. faster
- Add Mersenne Twister and Vigna to LIBC_RAND
- Provide privileged __printf() for error code
- Fix zipos opendir() so that it reports ENOTDIR
- Add basic chmod() implementation for Windows NT
- Add Cosmo's best functions to Python cosmo module
- Pin function trace indent depth to that of caller
- Show memory diagram on invalid access in MODE=dbg
- Differentiate stack overflow on crash in MODE=dbg
- Add stb_truetype and tools for analyzing font files
- Upgrade to UNICODE 13 and reduce its binary footprint
- COMPILE.COM now logs resource usage of build commands
- Start implementing basic poll() support on bare metal
- Set getauxval(AT_EXECFN) to GetModuleFileName() on NT
- Add descriptions to strerror() in non-TINY build modes
- Add COUNTBRANCH() macro to help with micro-optimizations
- Make error / backtrace / asan / memory code more unbreakable
- Add fast perfect C implementation of μ-Law and a-Law audio codecs
- Make strtol() functions consistent with other libc implementations
- Improve Linenoise implementation (see also github.com/jart/bestline)
- COMPILE.COM now suppresses stdout/stderr of successful build commands
This commit is contained in:
Justine Tunney 2021-09-27 22:58:51 -07:00
parent fa7b4f5bd1
commit 39bf41f4eb
806 changed files with 77494 additions and 63859 deletions

View file

@ -66,6 +66,10 @@ $(THIRD_PARTY_STB_A_OBJS): \
OVERRIDE_CPPFLAGS += \
-DSTACK_FRAME_UNLIMITED
o/$(MODE)/third_party/stb/stb_truetype.o: \
OVERRIDE_CFLAGS += \
-Os
THIRD_PARTY_STB_LIBS = $(foreach x,$(THIRD_PARTY_STB_ARTIFACTS),$($(x)))
THIRD_PARTY_STB_SRCS = $(foreach x,$(THIRD_PARTY_STB_ARTIFACTS),$($(x)_SRCS))
THIRD_PARTY_STB_CHECKS = $(foreach x,$(THIRD_PARTY_STB_ARTIFACTS),$($(x)_CHECKS))

View file

@ -233,7 +233,7 @@ void stbi_set_flip_vertically_on_load(int flag_true_if_should_flip) {
static void *stbi__load_main(stbi__context *s, int *x, int *y, int *comp,
int req_comp, stbi__result_info *ri, int bpc) {
memset(ri, 0, sizeof(*ri));
bzero(ri, sizeof(*ri));
ri->bits_per_channel = 8;
ri->num_channels = 0;
#ifndef STBI_NO_JPEG
@ -1028,7 +1028,7 @@ static optimizespeed int stbi__jpeg_decode_block(stbi__jpeg *j, short data[64],
t = stbi__jpeg_huff_decode(j, hdc);
if (t < 0) return stbi__err("bad huffman code", "Corrupt JPEG");
// 0 all the ac values now so we can do it 32-bits at a time
memset(data, 0, 64 * sizeof(data[0]));
bzero(data, 64 * sizeof(data[0]));
diff = t ? stbi__extend_receive(j, t) : 0;
dc = j->img_comp[b].dc_pred + diff;
j->img_comp[b].dc_pred = dc;
@ -1077,7 +1077,7 @@ static int stbi__jpeg_decode_block_prog_dc(stbi__jpeg *j, short data[64],
if (j->code_bits < 16) stbi__grow_buffer_unsafe(j);
if (j->succ_high == 0) {
// first scan for DC coefficient, must be first
memset(data, 0, 64 * sizeof(data[0])); // 0 all the ac values now
bzero(data, 64 * sizeof(data[0])); // 0 all the ac values now
t = stbi__jpeg_huff_decode(j, hdc);
diff = t ? stbi__extend_receive(j, t) : 0;
dc = j->img_comp[b].dc_pred + diff;
@ -1969,7 +1969,7 @@ static unsigned char *load_jpeg_image(stbi__jpeg *z, int *out_x, int *out_y,
unsigned char *output;
unsigned char *coutput[4];
stbi__resample res_comp[4];
memset(coutput, 0, sizeof(coutput));
bzero(coutput, sizeof(coutput));
for (k = 0; k < decode_n; ++k) {
stbi__resample *r = &res_comp[k];
@ -2198,8 +2198,8 @@ static int stbi__zbuild_huffman(stbi__zhuffman *z,
int i, k = 0;
int code, next_code[16], sizes[17];
// DEFLATE spec for generating codes
memset(sizes, 0, sizeof(sizes));
memset(z->fast, 0, sizeof(z->fast));
bzero(sizes, sizeof(sizes));
bzero(z->fast, sizeof(z->fast));
for (i = 0; i < num; ++i) ++sizes[sizelist[i]];
sizes[0] = 0;
for (i = 1; i < 16; ++i)
@ -2378,14 +2378,12 @@ static int stbi__parse_huffman_block(stbi__zbuf *a) {
if (dist == 1) { // run of one byte; common in images.
unsigned char v = *p;
if (len) {
do
*zout++ = v;
do *zout++ = v;
while (--len);
}
} else {
if (len) {
do
*zout++ = *p++;
do *zout++ = *p++;
while (--len);
}
}
@ -2404,7 +2402,7 @@ static int stbi__compute_huffman_codes(stbi__zbuf *a) {
int hdist = stbi__zreceive(a, 5) + 1;
int hclen = stbi__zreceive(a, 4) + 4;
int ntot = hlit + hdist;
memset(codelength_sizes, 0, sizeof(codelength_sizes));
bzero(codelength_sizes, sizeof(codelength_sizes));
for (i = 0; i < hclen; ++i) {
int s = stbi__zreceive(a, 3);
codelength_sizes[length_dezigzag[i]] = (unsigned char)s;
@ -3700,11 +3698,11 @@ static unsigned char *stbi__gif_load_next(stbi__context *s, stbi__gif *g,
// the current background; background colour is only used for pixels that
// are not rendered first frame, after that "background" color refers to
// the color that was there the previous frame.
memset(g->out, 0x00, 4 * pcount);
memset(g->background, 0x00,
4 * pcount); // state of the background (starts transparent)
memset(g->history, 0x00,
pcount); // pixels that were affected previous frame
bzero(g->out, 4 * pcount);
bzero(g->background,
4 * pcount); // state of the background (starts transparent)
bzero(g->history,
pcount); // pixels that were affected previous frame
first_frame = 1;
} else {
// second frame - how do we dispoase of the previous one?
@ -3741,8 +3739,8 @@ static unsigned char *stbi__gif_load_next(stbi__context *s, stbi__gif *g,
}
// clear my history;
memset(g->history, 0x00,
g->w * g->h); // pixels that were affected previous frame
bzero(g->history,
g->w * g->h); // pixels that were affected previous frame
for (;;) {
int tag = stbi__get8(s);

View file

@ -394,9 +394,7 @@ static float stbir__support_trapezoid(float scale) {
static float stbir__filter_triangle(float x, float s) {
STBIR__UNUSED_PARAM(s);
x = (float)fabs(x);
if (x <= 1.0f)
return 1 - x;
else
@ -405,40 +403,31 @@ static float stbir__filter_triangle(float x, float s) {
static float stbir__filter_cubic(float x, float s) {
STBIR__UNUSED_PARAM(s);
x = (float)fabs(x);
if (x < 1.0f)
return (4 + x * x * (3 * x - 6)) / 6;
else if (x < 2.0f)
return (8 + x * (-12 + x * (6 - x))) / 6;
return (0.0f);
}
static float stbir__filter_catmullrom(float x, float s) {
STBIR__UNUSED_PARAM(s);
x = (float)fabs(x);
if (x < 1.0f)
return 1 - x * x * (2.5f - 1.5f * x);
else if (x < 2.0f)
return 2 - x * (4 + x * (0.5f * x - 2.5f));
return (0.0f);
}
static float stbir__filter_mitchell(float x, float s) {
STBIR__UNUSED_PARAM(s);
x = (float)fabs(x);
if (x < 1.0f)
return (16 + x * x * (21 * x - 36)) / 18;
else if (x < 2.0f)
return (32 + x * (-60 + x * (36 - 7 * x))) / 18;
return (0.0f);
}
@ -1080,7 +1069,7 @@ static float* stbir__add_empty_ring_buffer_entry(stbir__info* stbir_info,
ring_buffer = stbir__get_ring_buffer_entry(
stbir_info->ring_buffer, ring_buffer_index,
stbir_info->ring_buffer_length_bytes / sizeof(float));
memset(ring_buffer, 0, stbir_info->ring_buffer_length_bytes);
bzero(ring_buffer, stbir_info->ring_buffer_length_bytes);
return ring_buffer;
}
@ -1340,8 +1329,8 @@ static void stbir__decode_and_resample_downsample(stbir__info* stbir_info,
// Decode the nth scanline from the source image into the decode buffer.
stbir__decode_scanline(stbir_info, n);
memset(stbir_info->horizontal_buffer, 0,
stbir_info->output_w * stbir_info->channels * sizeof(float));
bzero(stbir_info->horizontal_buffer,
stbir_info->output_w * stbir_info->channels * sizeof(float));
// Now resample it into the horizontal buffer.
if (stbir__use_width_upsampling(stbir_info))
@ -1584,7 +1573,7 @@ static void stbir__resample_vertical_upsample(stbir__info* stbir_info, int n) {
STBIR_ASSERT(stbir__use_height_upsampling(stbir_info));
memset(encode_buffer, 0, output_w * sizeof(float) * channels);
bzero(encode_buffer, output_w * sizeof(float) * channels);
// I tried reblocking this for better cache usage of encode_buffer
// (using x_outer, k, x_inner), but it lost speed. -- stb
@ -2104,7 +2093,7 @@ static int stbir__resize_allocated(
if (tempmem_size_in_bytes < memory_required) return 0;
memset(tempmem, 0, tempmem_size_in_bytes);
bzero(tempmem, tempmem_size_in_bytes);
info->input_data = input_data;
info->input_stride_bytes = width_stride_input;

460
third_party/stb/stb_rect_pack.c vendored Normal file
View file

@ -0,0 +1,460 @@
/*-*- mode:c;indent-tabs-mode:nil;c-basic-offset:3;tab-width:8;coding:utf-8 -*-│
vi: set net ft=c ts=3 sts=3 sw=3 fenc=utf-8 :vi
stb_truetype
Copyright 2017 Sean Barrett
Permission is hereby granted, free of charge, to any person obtaining
a copy of this software and associated documentation files (the
"Software"), to deal in the Software without restriction, including
without limitation the rights to use, copy, modify, merge, publish,
distribute, sublicense, and/or sell copies of the Software, and to
permit persons to whom the Software is furnished to do so, subject to
the following conditions:
The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*/
#include "libc/alg/alg.h"
#include "libc/assert.h"
#include "libc/dce.h"
#include "third_party/stb/stb_rect_pack.h"
asm(".ident\t\"\\n\\n\
stb_rect_pack (MIT License)\\n\
Copyright 2017 Sean Barrett\"");
asm(".include \"libc/disclaimer.inc\"");
/* clang-format off */
// stb_rect_pack.h - v1.01 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
// Does not do rotation.
//
// in the file that you want to have the implementation.
//
// Not necessarily the awesomest packing method, but better than
// the totally naive one in stb_truetype (which is primarily what
// this is meant to replace).
//
// Has only had a few tests run, may have issues.
//
// More docs to come.
//
// No memory allocations; uses qsort() and assert() from stdlib.
// Can override those by defining STBRP_SORT and STBRP_ASSERT.
//
// This library currently uses the Skyline Bottom-Left algorithm.
//
// Please note: better rectangle packers are welcome! Please
// implement them to the same API, but with a different init
// function.
//
// Credits
//
// Library
// Sean Barrett
// Minor features
// Martins Mozeiko
// github:IntellectualKitty
//
// Bugfixes / warning fixes
// Jeremy Jaussaud
// Fabian Giesen
//
// Version history:
//
// 1.01 (2021-07-11) always use large rect mode, expose STBRP__MAXVAL in public section
// 1.00 (2019-02-25) avoid small space waste; gracefully fail too-wide rectangles
// 0.99 (2019-02-07) warning fixes
// 0.11 (2017-03-03) return packing success/fail result
// 0.10 (2016-10-25) remove cast-away-const to avoid warnings
// 0.09 (2016-08-27) fix compiler warnings
// 0.08 (2015-09-13) really fix bug with empty rects (w=0 or h=0)
// 0.07 (2015-09-13) fix bug with empty rects (w=0 or h=0)
// 0.06 (2015-04-15) added STBRP_SORT to allow replacing qsort
// 0.05: added STBRP_ASSERT to allow replacing assert
// 0.04: fixed minor bug in STBRP_LARGE_RECTS support
// 0.01: initial release
#define STBRP__INIT_skyline 1
typedef struct
{
int x,y;
stbrp_node **prev_link;
} stbrp__findresult;
// Optionally select which packing heuristic the library should use. Different
// heuristics will produce better/worse results for different data sets.
// If you call init again, this will be reset to the default.
void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
{
switch (context->init_mode) {
case STBRP__INIT_skyline:
assert(heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight ||
heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight);
context->heuristic = heuristic;
break;
default:
unreachable;
}
}
// Optionally call this function after init but before doing any packing to
// change the handling of the out-of-temp-memory scenario, described above.
// If you call init again, this will be reset to the default (false).
void stbrp_setup_allow_out_of_mem(stbrp_context *context, int allow_out_of_mem)
{
if (allow_out_of_mem) {
// if it's ok to run out of memory, then don't bother aligning them;
// this gives better packing, but may fail due to OOM (even though
// the rectangles easily fit). @TODO a smarter approach would be to only
// quantize once we've hit OOM, then we could get rid of this parameter.
context->align = 1;
} else {
// if it's not ok to run out of memory, then quantize the widths
// so that num_nodes is always enough nodes.
//
// I.e. num_nodes * align >= width
// align >= width / num_nodes
// align = ceil(width/num_nodes)
context->align = (context->width + context->num_nodes-1) / context->num_nodes;
}
}
// Initialize a rectangle packer to:
// pack a rectangle that is 'width' by 'height' in dimensions
// using temporary storage provided by the array 'nodes', which is 'num_nodes' long
//
// You must call this function every time you start packing into a new target.
//
// There is no "shutdown" function. The 'nodes' memory must stay valid for
// the following stbrp_pack_rects() call (or calls), but can be freed after
// the call (or calls) finish.
//
// Note: to guarantee best results, either:
// 1. make sure 'num_nodes' >= 'width'
// or 2. call stbrp_allow_out_of_mem() defined below with 'allow_out_of_mem = 1'
//
// If you don't do either of the above things, widths will be quantized to multiples
// of small integers to guarantee the algorithm doesn't run out of temporary storage.
//
// If you do #2, then the non-quantized algorithm will be used, but the algorithm
// may run out of temporary storage and be unable to pack some rectangles.
void stbrp_init_target(stbrp_context *context, int width, int height, stbrp_node *nodes, int num_nodes)
{
int i;
for (i=0; i < num_nodes-1; ++i)
nodes[i].next = &nodes[i+1];
nodes[i].next = NULL;
context->init_mode = STBRP__INIT_skyline;
context->heuristic = STBRP_HEURISTIC_Skyline_default;
context->free_head = &nodes[0];
context->active_head = &context->extra[0];
context->width = width;
context->height = height;
context->num_nodes = num_nodes;
stbrp_setup_allow_out_of_mem(context, 0);
// node 0 is the full width, node 1 is the sentinel (lets us not store width explicitly)
context->extra[0].x = 0;
context->extra[0].y = 0;
context->extra[0].next = &context->extra[1];
context->extra[1].x = (stbrp_coord) width;
context->extra[1].y = (1<<30);
context->extra[1].next = NULL;
}
// find minimum y position if it starts at x1
static int stbrp__skyline_find_min_y(stbrp_context *c, stbrp_node *first, int x0, int width, int *pwaste)
{
stbrp_node *node = first;
int x1 = x0 + width;
int min_y, visited_width, waste_area;
assert(first->x <= x0);
#if 0
// skip in case we're past the node
while (node->next->x <= x0)
++node;
#else
assert(node->next->x > x0); // we ended up handling this in the caller for efficiency
#endif
assert(node->x <= x0);
min_y = 0;
waste_area = 0;
visited_width = 0;
while (node->x < x1) {
if (node->y > min_y) {
// raise min_y higher.
// we've accounted for all waste up to min_y,
// but we'll now add more waste for everything we've visted
waste_area += visited_width * (node->y - min_y);
min_y = node->y;
// the first time through, visited_width might be reduced
if (node->x < x0)
visited_width += node->next->x - x0;
else
visited_width += node->next->x - node->x;
} else {
// add waste area
int under_width = node->next->x - node->x;
if (under_width + visited_width > width)
under_width = width - visited_width;
waste_area += under_width * (min_y - node->y);
visited_width += under_width;
}
node = node->next;
}
*pwaste = waste_area;
return min_y;
}
static stbrp__findresult stbrp__skyline_find_best_pos(stbrp_context *c, int width, int height)
{
int best_waste = (1<<30), best_x, best_y = (1 << 30);
stbrp__findresult fr;
stbrp_node **prev, *node, *tail, **best = NULL;
// align to multiple of c->align
width = (width + c->align - 1);
width -= width % c->align;
assert(width % c->align == 0);
// if it can't possibly fit, bail immediately
if (width > c->width || height > c->height) {
fr.prev_link = NULL;
fr.x = fr.y = 0;
return fr;
}
node = c->active_head;
prev = &c->active_head;
while (node->x + width <= c->width) {
int y,waste;
y = stbrp__skyline_find_min_y(c, node, node->x, width, &waste);
if (c->heuristic == STBRP_HEURISTIC_Skyline_BL_sortHeight) { // actually just want to test BL
// bottom left
if (y < best_y) {
best_y = y;
best = prev;
}
} else {
// best-fit
if (y + height <= c->height) {
// can only use it if it first vertically
if (y < best_y || (y == best_y && waste < best_waste)) {
best_y = y;
best_waste = waste;
best = prev;
}
}
}
prev = &node->next;
node = node->next;
}
best_x = (best == NULL) ? 0 : (*best)->x;
// if doing best-fit (BF), we also have to try aligning right edge to each node position
//
// e.g, if fitting
//
// ____________________
// |____________________|
//
// into
//
// | |
// | ____________|
// |____________|
//
// then right-aligned reduces waste, but bottom-left BL is always chooses left-aligned
//
// This makes BF take about 2x the time
if (c->heuristic == STBRP_HEURISTIC_Skyline_BF_sortHeight) {
tail = c->active_head;
node = c->active_head;
prev = &c->active_head;
// find first node that's admissible
while (tail->x < width)
tail = tail->next;
while (tail) {
int xpos = tail->x - width;
int y,waste;
assert(xpos >= 0);
// find the left position that matches this
while (node->next->x <= xpos) {
prev = &node->next;
node = node->next;
}
assert(node->next->x > xpos && node->x <= xpos);
y = stbrp__skyline_find_min_y(c, node, xpos, width, &waste);
if (y + height <= c->height) {
if (y <= best_y) {
if (y < best_y || waste < best_waste || (waste==best_waste && xpos < best_x)) {
best_x = xpos;
assert(y <= best_y);
best_y = y;
best_waste = waste;
best = prev;
}
}
}
tail = tail->next;
}
}
fr.prev_link = best;
fr.x = best_x;
fr.y = best_y;
return fr;
}
static stbrp__findresult stbrp__skyline_pack_rectangle(stbrp_context *context, int width, int height)
{
// find best position according to heuristic
stbrp__findresult res = stbrp__skyline_find_best_pos(context, width, height);
stbrp_node *node, *cur;
// bail if:
// 1. it failed
// 2. the best node doesn't fit (we don't always check this)
// 3. we're out of memory
if (res.prev_link == NULL || res.y + height > context->height || context->free_head == NULL) {
res.prev_link = NULL;
return res;
}
// on success, create new node
node = context->free_head;
node->x = (stbrp_coord) res.x;
node->y = (stbrp_coord) (res.y + height);
context->free_head = node->next;
// insert the new node into the right starting point, and
// let 'cur' point to the remaining nodes needing to be
// stiched back in
cur = *res.prev_link;
if (cur->x < res.x) {
// preserve the existing one, so start testing with the next one
stbrp_node *next = cur->next;
cur->next = node;
cur = next;
} else {
*res.prev_link = node;
}
// from here, traverse cur and free the nodes, until we get to one
// that shouldn't be freed
while (cur->next && cur->next->x <= res.x + width) {
stbrp_node *next = cur->next;
// move the current node to the free list
cur->next = context->free_head;
context->free_head = cur;
cur = next;
}
// stitch the list back in
node->next = cur;
if (cur->x < res.x + width)
cur->x = (stbrp_coord) (res.x + width);
#ifndef NDEBUG
cur = context->active_head;
while (cur->x < context->width) {
assert(cur->x < cur->next->x);
cur = cur->next;
}
assert(cur->next == NULL);
{
int count=0;
cur = context->active_head;
while (cur) {
cur = cur->next;
++count;
}
cur = context->free_head;
while (cur) {
cur = cur->next;
++count;
}
assert(count == context->num_nodes+2);
}
#endif
return res;
}
static int rect_height_compare(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
if (p->h > q->h)
return -1;
if (p->h < q->h)
return 1;
return (p->w > q->w) ? -1 : (p->w < q->w);
}
static int rect_original_order(const void *a, const void *b)
{
const stbrp_rect *p = (const stbrp_rect *) a;
const stbrp_rect *q = (const stbrp_rect *) b;
return (p->was_packed < q->was_packed) ? -1 : (p->was_packed > q->was_packed);
}
// Assign packed locations to rectangles. The rectangles are of type
// 'stbrp_rect' defined below, stored in the array 'rects', and there
// are 'num_rects' many of them.
//
// Rectangles which are successfully packed have the 'was_packed' flag
// set to a non-zero value and 'x' and 'y' store the minimum location
// on each axis (i.e. bottom-left in cartesian coordinates, top-left
// if you imagine y increasing downwards). Rectangles which do not fit
// have the 'was_packed' flag set to 0.
//
// You should not try to access the 'rects' array from another thread
// while this function is running, as the function temporarily reorders
// the array while it executes.
//
// To pack into another rectangle, you need to call stbrp_init_target
// again. To continue packing into the same rectangle, you can call
// this function again. Calling this multiple times with multiple rect
// arrays will probably produce worse packing results than calling it
// a single time with the full rectangle array, but the option is
// available.
//
// The function returns 1 if all of the rectangles were successfully
// packed and 0 otherwise.
int stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int num_rects)
{
stbrp__findresult fr;
int i, all_rects_packed = 1;
// we use the 'was_packed' field internally to allow sorting/unsorting
for (i=0; i < num_rects; ++i) {
rects[i].was_packed = i;
}
// sort according to heuristic
qsort(rects, num_rects, sizeof(rects[0]), rect_height_compare);
for (i=0; i < num_rects; ++i) {
if (rects[i].w == 0 || rects[i].h == 0) {
rects[i].x = rects[i].y = 0; // empty rect needs no space
} else {
fr = stbrp__skyline_pack_rectangle(context, rects[i].w, rects[i].h);
if (fr.prev_link) {
rects[i].x = (stbrp_coord) fr.x;
rects[i].y = (stbrp_coord) fr.y;
} else {
rects[i].x = rects[i].y = STBRP__MAXVAL;
}
}
}
// unsort
qsort(rects, num_rects, sizeof(rects[0]), rect_original_order);
// set was_packed flags and all_rects_packed status
for (i=0; i < num_rects; ++i) {
rects[i].was_packed = !(rects[i].x == STBRP__MAXVAL && rects[i].y == STBRP__MAXVAL);
if (!rects[i].was_packed)
all_rects_packed = 0;
}
// return the all_rects_packed status
return all_rects_packed;
}

50
third_party/stb/stb_rect_pack.h vendored Normal file
View file

@ -0,0 +1,50 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_STB_STB_RECT_PACK_H_
#define COSMOPOLITAN_THIRD_PARTY_STB_STB_RECT_PACK_H_
#define STBRP__MAXVAL 0x7fffffff
#define STB_RECT_PACK_VERSION 1
#define STBRP_HEURISTIC_Skyline_default 0
#define STBRP_HEURISTIC_Skyline_BL_sortHeight 0
#define STBRP_HEURISTIC_Skyline_BF_sortHeight 1
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
typedef struct stbrp_context stbrp_context;
typedef struct stbrp_node stbrp_node;
typedef struct stbrp_rect stbrp_rect;
typedef int stbrp_coord;
struct stbrp_node {
stbrp_coord x, y;
stbrp_node *next;
};
struct stbrp_context {
int width;
int height;
int align;
int init_mode;
int heuristic;
int num_nodes;
stbrp_node *active_head;
stbrp_node *free_head;
stbrp_node extra[2]; // so optimal user-node-count is 'width' not 'width+2'
};
struct stbrp_rect {
int id; // reserved for your use:
stbrp_coord w, h; // input
stbrp_coord x, y; // output
int was_packed; // non-zero if valid packing
}; // 16 bytes, nominally
void stbrp_init_target(stbrp_context *, int, int, stbrp_node *, int);
void stbrp_setup_allow_out_of_mem(stbrp_context *, int);
void stbrp_setup_heuristic(stbrp_context *, int);
int stbrp_pack_rects(stbrp_context *, stbrp_rect *, int);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_STB_STB_RECT_PACK_H_ */

4283
third_party/stb/stb_truetype.c vendored Normal file

File diff suppressed because it is too large Load diff

262
third_party/stb/stb_truetype.h vendored Normal file
View file

@ -0,0 +1,262 @@
#ifndef COSMOPOLITAN_THIRD_PARTY_STB_STB_TRUETYPE_H_
#define COSMOPOLITAN_THIRD_PARTY_STB_STB_TRUETYPE_H_
#include "libc/runtime/runtime.h"
#include "third_party/stb/stb_rect_pack.h"
#define STBTT_vmove 1
#define STBTT_vline 2
#define STBTT_vcurve 3
#define STBTT_vcubic 4
#define STBTT_MACSTYLE_DONTCARE 0
#define STBTT_MACSTYLE_BOLD 1
#define STBTT_MACSTYLE_ITALIC 2
#define STBTT_MACSTYLE_UNDERSCORE 4
#define STBTT_MACSTYLE_NONE 8
#define STBTT_PLATFORM_ID_UNICODE 0
#define STBTT_PLATFORM_ID_MAC 1
#define STBTT_PLATFORM_ID_ISO 2
#define STBTT_PLATFORM_ID_MICROSOFT 3
#define STBTT_UNICODE_EID_UNICODE_1_0 0
#define STBTT_UNICODE_EID_UNICODE_1_1 1
#define STBTT_UNICODE_EID_ISO_10646 2
#define STBTT_UNICODE_EID_UNICODE_2_0_BMP 3
#define STBTT_UNICODE_EID_UNICODE_2_0_FULL 4
#define STBTT_MS_EID_SYMBOL 0
#define STBTT_MS_EID_UNICODE_BMP 1
#define STBTT_MS_EID_SHIFTJIS 2
#define STBTT_MS_EID_UNICODE_FULL 10
#define STBTT_MAC_EID_ROMAN 0
#define STBTT_MAC_EID_ARABIC 4
#define STBTT_MAC_EID_JAPANESE 1
#define STBTT_MAC_EID_HEBREW 5
#define STBTT_MAC_EID_CHINESE_TRAD 2
#define STBTT_MAC_EID_GREEK 6
#define STBTT_MAC_EID_KOREAN 3
#define STBTT_MAC_EID_RUSSIAN 7
#define STBTT_MS_LANG_ENGLISH 0x0409
#define STBTT_MS_LANG_ITALIAN 0x0410
#define STBTT_MS_LANG_CHINESE 0x0804
#define STBTT_MS_LANG_JAPANESE 0x0411
#define STBTT_MS_LANG_DUTCH 0x0413
#define STBTT_MS_LANG_KOREAN 0x0412
#define STBTT_MS_LANG_FRENCH 0x040c
#define STBTT_MS_LANG_RUSSIAN 0x0419
#define STBTT_MS_LANG_GERMAN 0x0407
#define STBTT_MS_LANG_SPANISH 0x0409
#define STBTT_MS_LANG_HEBREW 0x040d
#define STBTT_MS_LANG_SWEDISH 0x041D
#define STBTT_MAC_LANG_ENGLISH 0
#define STBTT_MAC_LANG_JAPANESE 11
#define STBTT_MAC_LANG_ARABIC 12
#define STBTT_MAC_LANG_KOREAN 23
#define STBTT_MAC_LANG_DUTCH 4
#define STBTT_MAC_LANG_RUSSIAN 32
#define STBTT_MAC_LANG_FRENCH 1
#define STBTT_MAC_LANG_SPANISH 6
#define STBTT_MAC_LANG_GERMAN 2
#define STBTT_MAC_LANG_SWEDISH 5
#define STBTT_MAC_LANG_HEBREW 10
#define STBTT_MAC_LANG_CHINESE_SIMPLIFIED 33
#define STBTT_MAC_LANG_ITALIAN 3
#define STBTT_MAC_LANG_CHINESE_TRAD 19
#define STBTT_POINT_SIZE(x) (-(x))
#if !(__ASSEMBLER__ + __LINKER__ + 0)
COSMOPOLITAN_C_START_
typedef int16_t stbtt_vertex_type;
typedef struct stbtt_fontinfo stbtt_fontinfo;
typedef struct stbtt_pack_context stbtt_pack_context;
typedef struct {
unsigned char *data;
int cursor;
int size;
} stbtt__buf;
typedef struct {
unsigned short x0, y0, x1, y1;
float xoff, yoff, xadvance;
} stbtt_bakedchar;
typedef struct {
float x0, y0, s0, t0;
float x1, y1, s1, t1;
} stbtt_aligned_quad;
typedef struct {
unsigned short x0, y0, x1, y1;
float xoff, yoff, xadvance;
float xoff2, yoff2;
} stbtt_packedchar;
typedef struct {
int w, h, stride;
unsigned char *pixels;
} stbtt__bitmap;
typedef struct {
float font_size;
int first_unicode_codepoint_in_range;
int *array_of_unicode_codepoints;
int num_chars;
stbtt_packedchar *chardata_for_range;
unsigned char h_oversample, v_oversample;
} stbtt_pack_range;
struct stbtt_pack_context {
void *user_allocator_context;
void *pack_info;
int width;
int height;
int stride_in_bytes;
int padding;
int skip_missing;
unsigned int h_oversample, v_oversample;
unsigned char *pixels;
void *nodes;
};
struct stbtt_fontinfo {
void *userdata;
int hmtx, kern, gpos, svg;
int loca, head, glyf, hhea;
unsigned char *data; // pointer to .ttf file
int fontstart; // offset of start of font
int numGlyphs; // needed for range checking
int index_map; // cmap mapping for chosen char encoding
int indexToLocFormat; // format mapping glyph index to glyph
stbtt__buf cff; // cff font data
stbtt__buf charstrings; // charstring index
stbtt__buf gsubrs; // global charstring subroutines index
stbtt__buf subrs; // private charstring subroutines index
stbtt__buf fontdicts; // array of font dicts
stbtt__buf fdselect; // map from glyph to fontdict
};
typedef struct stbtt_kerningentry {
int glyph1; // use stbtt_FindGlyphIndex
int glyph2;
int advance;
} stbtt_kerningentry;
typedef struct {
stbtt_vertex_type x, y, cx, cy, cx1, cy1;
unsigned char type, padding;
} stbtt_vertex;
extern jmp_buf stbtt_jmpbuf;
int stbtt_BakeFontBitmap(const unsigned char *, int, float, unsigned char *,
int, int, int, int, stbtt_bakedchar *);
void stbtt_GetBakedQuad(const stbtt_bakedchar *, int, int, int, float *,
float *, stbtt_aligned_quad *, int);
void stbtt_GetScaledFontVMetrics(const unsigned char *, int, float, float *,
float *, float *);
int stbtt_PackBegin(stbtt_pack_context *, unsigned char *, int, int, int, int,
void *);
void stbtt_PackEnd(stbtt_pack_context *);
int stbtt_PackFontRange(stbtt_pack_context *, const unsigned char *, int, float,
int, int, stbtt_packedchar *);
int stbtt_PackFontRanges(stbtt_pack_context *, const unsigned char *, int,
stbtt_pack_range *, int);
void stbtt_PackSetOversampling(stbtt_pack_context *, unsigned int,
unsigned int);
void stbtt_PackSetSkipMissingCodepoints(stbtt_pack_context *, int);
void stbtt_GetPackedQuad(const stbtt_packedchar *, int, int, int, float *,
float *, stbtt_aligned_quad *, int);
int stbtt_PackFontRangesGatherRects(stbtt_pack_context *,
const stbtt_fontinfo *, stbtt_pack_range *,
int, stbrp_rect *);
void stbtt_PackFontRangesPackRects(stbtt_pack_context *, stbrp_rect *, int);
int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *,
const stbtt_fontinfo *,
stbtt_pack_range *, int, stbrp_rect *);
int stbtt_GetNumberOfFonts(const unsigned char *);
int stbtt_GetFontOffsetForIndex(const unsigned char *, int);
int stbtt_InitFont(stbtt_fontinfo *, const unsigned char *, int);
int stbtt_FindGlyphIndex(const stbtt_fontinfo *, int);
float stbtt_ScaleForPixelHeight(const stbtt_fontinfo *, float);
float stbtt_ScaleForMappingEmToPixels(const stbtt_fontinfo *, float);
void stbtt_GetFontVMetrics(const stbtt_fontinfo *, int *, int *, int *);
int stbtt_GetFontVMetricsOS2(const stbtt_fontinfo *, int *, int *, int *);
void stbtt_GetFontBoundingBox(const stbtt_fontinfo *, int *, int *, int *,
int *);
void stbtt_GetCodepointHMetrics(const stbtt_fontinfo *, int, int *, int *);
int stbtt_GetCodepointKernAdvance(const stbtt_fontinfo *, int, int);
int stbtt_GetCodepointBox(const stbtt_fontinfo *, int, int *, int *, int *,
int *);
void stbtt_GetGlyphHMetrics(const stbtt_fontinfo *, int, int *, int *);
int stbtt_GetGlyphKernAdvance(const stbtt_fontinfo *, int, int);
int stbtt_GetGlyphBox(const stbtt_fontinfo *, int, int *, int *, int *, int *);
int stbtt_GetKerningTableLength(const stbtt_fontinfo *);
int stbtt_GetKerningTable(const stbtt_fontinfo *, stbtt_kerningentry *, int);
int stbtt_IsGlyphEmpty(const stbtt_fontinfo *, int);
int stbtt_GetCodepointShape(const stbtt_fontinfo *, int, stbtt_vertex **);
int stbtt_GetGlyphShape(const stbtt_fontinfo *, int, stbtt_vertex **);
void stbtt_FreeShape(const stbtt_fontinfo *, stbtt_vertex *);
unsigned char *stbtt_FindSVGDoc(const stbtt_fontinfo *, int);
int stbtt_GetCodepointSVG(const stbtt_fontinfo *, int, const char **);
int stbtt_GetGlyphSVG(const stbtt_fontinfo *, int, const char **);
void stbtt_FreeBitmap(unsigned char *, void *);
void *stbtt_GetCodepointBitmap(const stbtt_fontinfo *, float, float, int, int *,
int *, int *, int *);
void *stbtt_GetCodepointBitmapSubpixel(const stbtt_fontinfo *, float, float,
float, float, int, int *, int *, int *,
int *);
void stbtt_MakeCodepointBitmap(const stbtt_fontinfo *, unsigned char *, int,
int, int, float, float, int);
void stbtt_MakeCodepointBitmapSubpixel(const stbtt_fontinfo *, unsigned char *,
int, int, int, float, float, float,
float, int);
void stbtt_MakeCodepointBitmapSubpixelPrefilter(const stbtt_fontinfo *,
unsigned char *, int, int, int,
float, float, float, float, int,
int, float *, float *, int);
void stbtt_GetCodepointBitmapBox(const stbtt_fontinfo *, int, float, float,
int *, int *, int *, int *);
void stbtt_GetCodepointBitmapBoxSubpixel(const stbtt_fontinfo *, int, float,
float, float, float, int *, int *,
int *, int *);
unsigned char *stbtt_GetGlyphBitmap(const stbtt_fontinfo *, float, float, int,
int *, int *, int *, int *);
unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *, float,
float, float, float, int, int *,
int *, int *, int *);
void stbtt_MakeGlyphBitmap(const stbtt_fontinfo *, unsigned char *, int, int,
int, float, float, int);
void stbtt_MakeGlyphBitmapSubpixel(const stbtt_fontinfo *, unsigned char *, int,
int, int, float, float, float, float, int);
void stbtt_MakeGlyphBitmapSubpixelPrefilter(const stbtt_fontinfo *,
unsigned char *, int, int, int,
float, float, float, float, int,
int, float *, float *, int);
void stbtt_GetGlyphBitmapBox(const stbtt_fontinfo *, int, float, float, int *,
int *, int *, int *);
void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *, int, float, float,
float, float, int *, int *, int *, int *);
void stbtt_Rasterize(stbtt__bitmap *, float, stbtt_vertex *, int, float, float,
float, float, int, int, int, void *);
void stbtt_FreeSDF(unsigned char *, void *);
unsigned char *stbtt_GetGlyphSDF(const stbtt_fontinfo *, float, int, int,
unsigned char, float, int *, int *, int *,
int *);
unsigned char *stbtt_GetCodepointSDF(const stbtt_fontinfo *, float, int, int,
unsigned char, float, int *, int *, int *,
int *);
int stbtt_FindMatchingFont(const unsigned char *, const char *, int);
int stbtt_CompareUTF8toUTF16_bigendian(const char *, int, const char *, int);
const char *stbtt_GetFontNameString(const stbtt_fontinfo *, int *, int, int,
int, int);
COSMOPOLITAN_C_END_
#endif /* !(__ASSEMBLER__ + __LINKER__ + 0) */
#endif /* COSMOPOLITAN_THIRD_PARTY_STB_STB_TRUETYPE_H_ */

View file

@ -616,7 +616,7 @@ static void add_entry(Codebook *c, uint32 huff_code, int symbol, int count,
static int compute_codewords(Codebook *c, uint8 *len, int n, uint32 *values) {
int i, k, m = 0;
uint32 available[32];
memset(available, 0, sizeof(available));
bzero(available, sizeof(available));
// find the first entry
for (k = 0; k < n; ++k)
if (len[k] < NO_CODE) break;
@ -1642,8 +1642,11 @@ static void decode_residue(vorb *f, float *residue_buffers[], int ch, int n,
CHECK(f);
for (i = 0; i < ch; ++i)
if (!do_not_decode[i]) memset(residue_buffers[i], 0, sizeof(float) * n);
for (i = 0; i < ch; ++i) {
if (!do_not_decode[i]) {
bzero(residue_buffers[i], sizeof(float) * n);
}
}
if (rtype == 2 && ch != 1) {
for (j = 0; j < ch; ++j)
@ -2913,7 +2916,7 @@ static int vorbis_decode_packet_rest(vorb *f, int *len, Mode *m, int left_start,
#ifndef STB_VORBIS_NO_DEFER_FLOOR
for (i = 0; i < f->channels; ++i) {
if (really_zero_channel[i]) {
memset(f->channel_buffers[i], 0, sizeof(*f->channel_buffers[i]) * n2);
bzero(f->channel_buffers[i], sizeof(*f->channel_buffers[i]) * n2);
} else {
do_floor(f, map, i, n, f->channel_buffers[i], f->finalY[i], NULL);
}