Updated stb headers.

This commit is contained in:
Branimir Karadžić
2016-04-03 22:06:44 -07:00
parent b656ee74e3
commit 5d0f84394f
4 changed files with 848 additions and 404 deletions

File diff suppressed because it is too large Load Diff

View File

@@ -1,4 +1,10 @@
// stb_rect_pack.h - v0.05 - public domain - rectangle packing
#if defined(__GNUC__) || defined(__clang__)
# pragma GCC diagnostic ignored "-Wtype-limits"
# pragma GCC diagnostic ignored "-Wunused-function"
# pragma GCC diagnostic ignored "-Wunused-parameter"
#endif
// stb_rect_pack.h - v0.08 - public domain - rectangle packing
// Sean Barrett 2014
//
// Useful for e.g. packing rectangular textures into an atlas.
@@ -13,6 +19,7 @@
// 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.
//
@@ -20,11 +27,29 @@
// implement them to the same API, but with a different init
// function.
//
// Credits
//
// Library
// Sean Barrett
// Minor features
// Martins Mozeiko
// Bugfixes / warning fixes
// Jeremy Jaussaud
//
// Version history:
//
// 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
//
// LICENSE
//
// This software is dual-licensed to the public domain and under the following
// license: you are granted a perpetual, irrevocable license to copy, modify,
// publish, and distribute this file as you see fit.
//////////////////////////////////////////////////////////////////////////////
//
@@ -129,7 +154,7 @@ enum
{
STBRP_HEURISTIC_Skyline_default=0,
STBRP_HEURISTIC_Skyline_BL_sortHeight = STBRP_HEURISTIC_Skyline_default,
STBRP_HEURISTIC_Skyline_BF_sortHeight
STBRP_HEURISTIC_Skyline_BF_sortHeight,
};
@@ -169,7 +194,10 @@ struct stbrp_context
//
#ifdef STB_RECT_PACK_IMPLEMENTATION
#ifndef STBRP_SORT
#include <stdlib.h>
#define STBRP_SORT qsort
#endif
#ifndef STBRP_ASSERT
#include <assert.h>
@@ -178,7 +206,7 @@ struct stbrp_context
enum
{
STBRP__INIT_skyline = 1
STBRP__INIT_skyline = 1,
};
STBRP_DEF void stbrp_setup_heuristic(stbrp_context *context, int heuristic)
@@ -248,7 +276,6 @@ STBRP_DEF void stbrp_init_target(stbrp_context *context, int width, int height,
// 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)
{
(void)c;
stbrp_node *node = first;
int x1 = x0 + width;
int min_y, visited_width, waste_area;
@@ -525,20 +552,24 @@ STBRP_DEF void stbrp_pack_rects(stbrp_context *context, stbrp_rect *rects, int n
}
// sort according to heuristic
qsort(rects, num_rects, sizeof(rects[0]), rect_height_compare);
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_height_compare);
for (i=0; i < num_rects; ++i) {
stbrp__findresult 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;
if (rects[i].w == 0 || rects[i].h == 0) {
rects[i].x = rects[i].y = 0; // empty rect needs no space
} else {
rects[i].x = rects[i].y = STBRP__MAXVAL;
stbrp__findresult 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);
STBRP_SORT(rects, num_rects, sizeof(rects[0]), rect_original_order);
// set was_packed flags
for (i=0; i < num_rects; ++i)

View File

@@ -1,4 +1,4 @@
// stb_textedit.h - v1.4 - public domain - Sean Barrett
// stb_textedit.h - v1.8 - public domain - Sean Barrett
// Development of this library was sponsored by RAD Game Tools
//
// This C header file implements the guts of a multi-line text-editing
@@ -17,19 +17,24 @@
//
// LICENSE
//
// This software has been placed in the public domain by its author.
// Where that dedication is not recognized, you are granted a perpetual,
// irrevocable license to copy and modify this file as you see fit.
// This software is dual-licensed to the public domain and under the following
// license: you are granted a perpetual, irrevocable license to copy, modify,
// publish, and distribute this file as you see fit.
//
//
// DEPENDENCIES
//
// Uses the C runtime function 'memmove'. Uses no other functions.
// Performs no runtime allocations.
// Uses the C runtime function 'memmove', which you can override
// by defining STB_TEXTEDIT_memmove before the implementation.
// Uses no other functions. Performs no runtime allocations.
//
//
// VERSION HISTORY
//
// 1.8 (2016-04-02) better keyboard handling when mouse button is down
// 1.7 (2015-09-13) change y range handling in case baseline is non-0
// 1.6 (2015-04-15) allow STB_TEXTEDIT_memmove
// 1.5 (2014-09-10) add support for secondary keys for OS X
// 1.4 (2014-08-17) fix signed/unsigned warnings
// 1.3 (2014-06-19) fix mouse clicking to round to nearest char boundary
// 1.2 (2014-05-27) fix some RAD types that had crept into the new code
@@ -42,7 +47,13 @@
// ADDITIONAL CONTRIBUTORS
//
// Ulf Winklemann: move-by-word in 1.1
// Scott Graham: mouse selection bugfix in 1.3
// Fabian Giesen: secondary key inputs in 1.5
// Martins Mozeiko: STB_TEXTEDIT_memmove
//
// Bugfixes:
// Scott Graham
// Daniel Keller
// Omar Cornut
//
// USAGE
//
@@ -142,6 +153,10 @@
// required for WORDLEFT/WORDRIGHT
// STB_TEXTEDIT_K_WORDLEFT keyboard input to move cursor left one word // e.g. ctrl-LEFT
// STB_TEXTEDIT_K_WORDRIGHT keyboard input to move cursor right one word // e.g. ctrl-RIGHT
// STB_TEXTEDIT_K_LINESTART2 secondary keyboard input to move cursor to start of line
// STB_TEXTEDIT_K_LINEEND2 secondary keyboard input to move cursor to end of line
// STB_TEXTEDIT_K_TEXTSTART2 secondary keyboard input to move cursor to start of text
// STB_TEXTEDIT_K_TEXTEND2 secondary keyboard input to move cursor to end of text
//
// Todo:
// STB_TEXTEDIT_K_PGUP keyboard input to move cursor up a page
@@ -352,7 +367,10 @@ typedef struct
// included just the "header" portion
#ifdef STB_TEXTEDIT_IMPLEMENTATION
#include <string.h> // memmove
#ifndef STB_TEXTEDIT_memmove
#include <string.h>
#define STB_TEXTEDIT_memmove memmove
#endif
/////////////////////////////////////////////////////////////////////////////
@@ -368,9 +386,6 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
float base_y = 0, prev_x;
int i=0, k;
if (y < 0)
return 0;
r.x0 = r.x1 = 0;
r.ymin = r.ymax = 0;
r.num_chars = 0;
@@ -381,6 +396,9 @@ static int stb_text_locate_coord(STB_TEXTEDIT_STRING *str, float x, float y)
if (r.num_chars <= 0)
return n;
if (i==0 && y < base_y + r.ymin)
return 0;
if (y < base_y + r.ymax)
break;
@@ -434,6 +452,8 @@ static void stb_textedit_click(STB_TEXTEDIT_STRING *str, STB_TexteditState *stat
static void stb_textedit_drag(STB_TEXTEDIT_STRING *str, STB_TexteditState *state, float x, float y)
{
int p = stb_text_locate_coord(str, x, y);
if (state->select_start == state->select_end)
state->select_start = state->cursor;
state->cursor = state->select_end = p;
}
@@ -917,23 +937,35 @@ retry:
state->has_preferred_x = 0;
break;
#ifdef STB_TEXTEDIT_K_TEXTSTART2
case STB_TEXTEDIT_K_TEXTSTART2:
#endif
case STB_TEXTEDIT_K_TEXTSTART:
state->cursor = state->select_start = state->select_end = 0;
state->has_preferred_x = 0;
break;
#ifdef STB_TEXTEDIT_K_TEXTEND2
case STB_TEXTEDIT_K_TEXTEND2:
#endif
case STB_TEXTEDIT_K_TEXTEND:
state->cursor = STB_TEXTEDIT_STRINGLEN(str);
state->select_start = state->select_end = 0;
state->has_preferred_x = 0;
break;
#ifdef STB_TEXTEDIT_K_TEXTSTART2
case STB_TEXTEDIT_K_TEXTSTART2 | STB_TEXTEDIT_K_SHIFT:
#endif
case STB_TEXTEDIT_K_TEXTSTART | STB_TEXTEDIT_K_SHIFT:
stb_textedit_prep_selection_at_cursor(state);
state->cursor = state->select_end = 0;
state->has_preferred_x = 0;
break;
#ifdef STB_TEXTEDIT_K_TEXTEND2
case STB_TEXTEDIT_K_TEXTEND2 | STB_TEXTEDIT_K_SHIFT:
#endif
case STB_TEXTEDIT_K_TEXTEND | STB_TEXTEDIT_K_SHIFT:
stb_textedit_prep_selection_at_cursor(state);
state->cursor = state->select_end = STB_TEXTEDIT_STRINGLEN(str);
@@ -941,6 +973,9 @@ retry:
break;
#ifdef STB_TEXTEDIT_K_LINESTART2
case STB_TEXTEDIT_K_LINESTART2:
#endif
case STB_TEXTEDIT_K_LINESTART: {
StbFindState find;
stb_textedit_clamp(str, state);
@@ -951,16 +986,25 @@ retry:
break;
}
#ifdef STB_TEXTEDIT_K_LINEEND2
case STB_TEXTEDIT_K_LINEEND2:
#endif
case STB_TEXTEDIT_K_LINEEND: {
StbFindState find;
stb_textedit_clamp(str, state);
stb_textedit_move_to_first(state);
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
state->cursor = find.first_char + find.length;
state->has_preferred_x = 0;
state->cursor = find.first_char + find.length;
if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
--state->cursor;
break;
}
#ifdef STB_TEXTEDIT_K_LINESTART2
case STB_TEXTEDIT_K_LINESTART2 | STB_TEXTEDIT_K_SHIFT:
#endif
case STB_TEXTEDIT_K_LINESTART | STB_TEXTEDIT_K_SHIFT: {
StbFindState find;
stb_textedit_clamp(str, state);
@@ -971,13 +1015,19 @@ retry:
break;
}
#ifdef STB_TEXTEDIT_K_LINEEND2
case STB_TEXTEDIT_K_LINEEND2 | STB_TEXTEDIT_K_SHIFT:
#endif
case STB_TEXTEDIT_K_LINEEND | STB_TEXTEDIT_K_SHIFT: {
StbFindState find;
stb_textedit_clamp(str, state);
stb_textedit_prep_selection_at_cursor(state);
stb_textedit_find_charpos(&find, str, state->cursor, state->single_line);
state->cursor = state->select_end = find.first_char + find.length;
state->has_preferred_x = 0;
state->cursor = find.first_char + find.length;
if (find.length > 0 && STB_TEXTEDIT_GETCHAR(str, state->cursor-1) == STB_TEXTEDIT_NEWLINE)
--state->cursor;
state->select_end = state->cursor;
break;
}
@@ -1008,13 +1058,13 @@ static void stb_textedit_discard_undo(StbUndoState *state)
int n = state->undo_rec[0].insert_length, i;
// delete n characters from all other records
state->undo_char_point = state->undo_char_point - (short) n; // vsnet05
memmove(state->undo_char, state->undo_char + n, (size_t) ((size_t)state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
STB_TEXTEDIT_memmove(state->undo_char, state->undo_char + n, (size_t) (state->undo_char_point*sizeof(STB_TEXTEDIT_CHARTYPE)));
for (i=0; i < state->undo_point; ++i)
if (state->undo_rec[i].char_storage >= 0)
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage - (short) n; // vsnet05 // @OPTIMIZE: get rid of char_storage and infer it
}
--state->undo_point;
memmove(state->undo_rec, state->undo_rec+1, (size_t) ((size_t)state->undo_point*sizeof(state->undo_rec[0])));
STB_TEXTEDIT_memmove(state->undo_rec, state->undo_rec+1, (size_t) (state->undo_point*sizeof(state->undo_rec[0])));
}
}
@@ -1032,13 +1082,13 @@ static void stb_textedit_discard_redo(StbUndoState *state)
int n = state->undo_rec[k].insert_length, i;
// delete n characters from all other records
state->redo_char_point = state->redo_char_point + (short) n; // vsnet05
memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
STB_TEXTEDIT_memmove(state->undo_char + state->redo_char_point, state->undo_char + state->redo_char_point-n, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_char_point)*sizeof(STB_TEXTEDIT_CHARTYPE)));
for (i=state->redo_point; i < k; ++i)
if (state->undo_rec[i].char_storage >= 0)
state->undo_rec[i].char_storage = state->undo_rec[i].char_storage + (short) n; // vsnet05
}
++state->redo_point;
memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((size_t)(STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
STB_TEXTEDIT_memmove(state->undo_rec + state->redo_point-1, state->undo_rec + state->redo_point, (size_t) ((STB_TEXTEDIT_UNDOSTATECOUNT - state->redo_point)*sizeof(state->undo_rec[0])));
}
}

View File

@@ -27,6 +27,10 @@
// Mikko Mononen: compound shape support, more cmap formats
// Tor Andersson: kerning, subpixel rendering
//
// Misc other:
// Ryan Gordon
// Simon Glass
//
// Bug/warning reports/fixes:
// "Zer" on mollyrocket (with fix)
// Cass Everitt
@@ -45,13 +49,18 @@
// Omar Cornut
// github:aloucks
// Peter LaValle
// Sergey Popov
// Giumo X. Clanjor
//
// Misc other:
// Ryan Gordon
// Higor Euripedes
// Thomas Fields
// Derek Vinyard
//
// VERSION HISTORY
//
// 1.11 (2016-04-02) fix unused-variable warning
// 1.10 (2016-04-02) user-defined fabs(); rare memory leak; remove duplicate typedef
// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use allocation userdata properly
// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
// variant PackFontRanges to pack and render in separate phases;
// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
@@ -68,9 +77,9 @@
//
// LICENSE
//
// This software is in the public domain. Where that dedication is not
// recognized, you are granted a perpetual, irrevocable license to copy,
// distribute, and modify this file as you see fit.
// This software is dual-licensed to the public domain and under the following
// license: you are granted a perpetual, irrevocable license to copy, modify,
// publish, and distribute this file as you see fit.
//
// USAGE
//
@@ -406,6 +415,11 @@ int main(int arg, char **argv)
#define STBTT_sqrt(x) sqrt(x)
#endif
#ifndef STBTT_fabs
#include <math.h>
#define STBTT_fabs(x) fabs(x)
#endif
// #define your own functions "STBTT_malloc" / "STBTT_free" to avoid malloc.h
#ifndef STBTT_malloc
#include <stdlib.h>
@@ -629,7 +643,7 @@ STBTT_DEF int stbtt_GetFontOffsetForIndex(const unsigned char *data, int index);
// The following structure is defined publically so you can declare one on
// the stack or as a global or etc, but you should treat it as opaque.
typedef struct stbtt_fontinfo
struct stbtt_fontinfo
{
void * userdata;
unsigned char * data; // pointer to .ttf file
@@ -640,7 +654,7 @@ typedef struct stbtt_fontinfo
int loca,head,glyf,hhea,hmtx,kern; // table locations as offset from start of .ttf
int index_map; // a cmap mapping for our chosen character encoding
int indexToLocFormat; // format needed to map from glyph index to glyph
} stbtt_fontinfo;
};
STBTT_DEF int stbtt_InitFont(stbtt_fontinfo *info, const unsigned char *data, int offset);
// Given an offset into the file that defines a font, this function builds
@@ -808,7 +822,16 @@ typedef struct
unsigned char *pixels;
} stbtt__bitmap;
STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, float flatness_in_pixels, stbtt_vertex *vertices, int num_verts, float scale_x, float scale_y, float shift_x, float shift_y, int x_off, int y_off, int invert, void *userdata);
// rasterize a shape with quadratic beziers into a bitmap
STBTT_DEF void stbtt_Rasterize(stbtt__bitmap *result, // 1-channel bitmap to draw into
float flatness_in_pixels, // allowable error of curve in pixels
stbtt_vertex *vertices, // array of vertices defining shape
int num_verts, // number of vertices in above array
float scale_x, float scale_y, // scale applied to input vertices
float shift_x, float shift_y, // translation applied to input vertices
int x_off, int y_off, // another translation applied to input
int invert, // if non-zero, vertically flip shape
void *userdata); // context for to STBTT_MALLOC
//////////////////////////////////////////////////////////////////////////////
//
@@ -933,6 +956,12 @@ typedef int stbtt__test_oversample_pow2[(STBTT_MAX_OVERSAMPLE & (STBTT_MAX_OVERS
#define STBTT_RASTERIZER_VERSION 2
#endif
#ifdef _MSC_VER
#define STBTT__NOTUSED(v) (void)(v)
#else
#define STBTT__NOTUSED(v) (void)sizeof(v)
#endif
//////////////////////////////////////////////////////////////////////////
//
// accessors to parse data from file
@@ -1550,7 +1579,7 @@ STBTT_DEF void stbtt_FreeShape(const stbtt_fontinfo *info, stbtt_vertex *v)
STBTT_DEF void stbtt_GetGlyphBitmapBoxSubpixel(const stbtt_fontinfo *font, int glyph, float scale_x, float scale_y,float shift_x, float shift_y, int *ix0, int *iy0, int *ix1, int *iy1)
{
int x0,y0,x1,y1;
int x0=0,y0=0,x1,y1; // =0 suppresses compiler warning
if (!stbtt_GetGlyphBox(font, glyph, &x0,&y0,&x1,&y1)) {
// e.g. space character
if (ix0) *ix0 = 0;
@@ -1666,6 +1695,7 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
{
stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
STBTT_assert(z != NULL);
if (!z) return z;
// round dx down to avoid overshooting
@@ -1687,10 +1717,11 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
{
stbtt__active_edge *z = (stbtt__active_edge *) stbtt__hheap_alloc(hh, sizeof(*z), userdata);
float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0);
STBTT_assert(z != NULL);
//STBTT_assert(e->y0 <= start_point);
if (!z) return z;
z->fdx = dxdy;
z->fdy = (1/dxdy);
z->fdy = dxdy != 0.0f ? (1.0f/dxdy) : 0.0f;
z->fx = e->x0 + dxdy * (start_point - e->y0);
z->fx -= off_x;
z->direction = e->invert ? 1.0f : -1.0f;
@@ -1751,7 +1782,7 @@ static void stbtt__fill_active_edges(unsigned char *scanline, int len, stbtt__ac
static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
{
stbtt__hheap hh = { 0 };
stbtt__hheap hh = { 0, 0, 0 };
stbtt__active_edge *active = NULL;
int y,j=0;
int max_weight = (255 / vsubsample); // weight per vertical scanline
@@ -1811,21 +1842,23 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
while (e->y0 <= scan_y) {
if (e->y1 > scan_y) {
stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y, userdata);
// find insertion point
if (active == NULL)
active = z;
else if (z->x < active->x) {
// insert at front
z->next = active;
active = z;
} else {
// find thing to insert AFTER
stbtt__active_edge *p = active;
while (p->next && p->next->x < z->x)
p = p->next;
// at this point, p->next->x is NOT < z->x
z->next = p->next;
p->next = z;
if (z != NULL) {
// find insertion point
if (active == NULL)
active = z;
else if (z->x < active->x) {
// insert at front
z->next = active;
active = z;
} else {
// find thing to insert AFTER
stbtt__active_edge *p = active;
while (p->next && p->next->x < z->x)
p = p->next;
// at this point, p->next->x is NOT < z->x
z->next = p->next;
p->next = z;
}
}
}
++e;
@@ -1913,7 +1946,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
float dx = e->fdx;
float xb = x0 + dx;
float x_top, x_bottom;
float y0,y1;
float sy0,sy1;
float dy = e->fdy;
STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
@@ -1922,17 +1955,17 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
// line with y_top, but that may be off the line segment.
if (e->sy > y_top) {
x_top = x0 + dx * (e->sy - y_top);
y0 = e->sy;
sy0 = e->sy;
} else {
x_top = x0;
y0 = y_top;
sy0 = y_top;
}
if (e->ey < y_bottom) {
x_bottom = x0 + dx * (e->ey - y_top);
y1 = e->ey;
sy1 = e->ey;
} else {
x_bottom = xb;
y1 = y_bottom;
sy1 = y_bottom;
}
if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
@@ -1942,7 +1975,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
float height;
// simple case, only spans one pixel
int x = (int) x_top;
height = y1 - y0;
height = sy1 - sy0;
STBTT_assert(x >= 0 && x < len);
scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2) * height;
scanline_fill[x] += e->direction * height; // everything right of this pixel is filled
@@ -1953,9 +1986,9 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
if (x_top > x_bottom) {
// flip scanline vertically; signed area is the same
float t;
y0 = y_bottom - (y0 - y_top);
y1 = y_bottom - (y1 - y_top);
t = y0, y0 = y1, y1 = t;
sy0 = y_bottom - (sy0 - y_top);
sy1 = y_bottom - (sy1 - y_top);
t = sy0, sy0 = sy1, sy1 = t;
t = x_bottom, x_bottom = x_top, x_top = t;
dx = -dx;
dy = -dy;
@@ -1969,7 +2002,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
sign = e->direction;
// area of the rectangle covered from y0..y_crossing
area = sign * (y_crossing-y0);
area = sign * (y_crossing-sy0);
// area of the triangle (x_top,y0), (x+1,y0), (x+1,y_crossing)
scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2);
@@ -1980,11 +2013,11 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
}
y_crossing += dy * (x2 - (x1+1));
STBTT_assert(fabs(area) <= 1.01f);
STBTT_assert(STBTT_fabs(area) <= 1.01f);
scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (y1-y_crossing);
scanline[x2] += area + sign * (1-((x2-x2)+(x_bottom-x2))/2) * (sy1-y_crossing);
scanline_fill[x2] += sign * (y1-y0);
scanline_fill[x2] += sign * (sy1-sy0);
}
} else {
// if edge goes outside of box we're drawing, we require
@@ -2053,13 +2086,13 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
// directly AA rasterize edges w/o supersampling
static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
{
(void)vsubsample;
stbtt__hheap hh;
memset(&hh, 0, sizeof(hh));
stbtt__hheap hh = { 0, 0, 0 };
stbtt__active_edge *active = NULL;
int y,j=0, i;
float scanline_data[129], *scanline, *scanline2;
STBTT__NOTUSED(vsubsample);
if (result->w > 64)
scanline = (float *) STBTT_malloc((result->w*2+1) * sizeof(float), userdata);
else
@@ -2095,11 +2128,15 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
// insert all edges that start before the bottom of this scanline
while (e->y0 <= scan_y_bottom) {
stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
STBTT_assert(z->ey >= scan_y_top);
// insert at front
z->next = active;
active = z;
if (e->y0 != e->y1) {
stbtt__active_edge *z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata);
if (z != NULL) {
STBTT_assert(z->ey >= scan_y_top);
// insert at front
z->next = active;
active = z;
}
}
++e;
}
@@ -2114,7 +2151,7 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
int m;
sum += scanline2[i];
k = scanline[i] + sum;
k = (float) fabs(k)*255 + 0.5f;
k = (float) STBTT_fabs(k)*255 + 0.5f;
m = (int) k;
if (m > 255) m = 255;
result->pixels[j*result->stride + i] = (unsigned char) m;
@@ -2415,7 +2452,10 @@ STBTT_DEF unsigned char *stbtt_GetGlyphBitmapSubpixel(const stbtt_fontinfo *info
if (scale_x == 0) scale_x = scale_y;
if (scale_y == 0) {
if (scale_x == 0) return NULL;
if (scale_x == 0) {
STBTT_free(vertices, info->userdata);
return NULL;
}
scale_y = scale_x;
}
@@ -2507,6 +2547,7 @@ STBTT_DEF int stbtt_BakeFontBitmap(const unsigned char *data, int offset, // fo
float scale;
int x,y,bottom_y, i;
stbtt_fontinfo f;
f.userdata = NULL;
if (!stbtt_InitFont(&f, data, offset))
return -1;
STBTT_memset(pixels, 0, pw*ph); // background of 0 around pixels
@@ -2570,11 +2611,6 @@ STBTT_DEF void stbtt_GetBakedQuad(stbtt_bakedchar *chardata, int pw, int ph, int
//
#ifndef STB_RECT_PACK_VERSION
#ifdef _MSC_VER
#define STBTT__NOTUSED(v) (void)(v)
#else
#define STBTT__NOTUSED(v) (void)sizeof(v)
#endif
typedef int stbrp_coord;
@@ -2700,6 +2736,7 @@ static void stbtt__h_prefilter(unsigned char *pixels, int w, int h, int stride_i
unsigned char buffer[STBTT_MAX_OVERSAMPLE];
int safe_w = w - kernel_width;
int j;
STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
for (j=0; j < h; ++j) {
int i;
unsigned int total;
@@ -2761,6 +2798,7 @@ static void stbtt__v_prefilter(unsigned char *pixels, int w, int h, int stride_i
unsigned char buffer[STBTT_MAX_OVERSAMPLE];
int safe_h = h - kernel_width;
int j;
STBTT_memset(buffer, 0, STBTT_MAX_OVERSAMPLE); // suppress bogus warning from VS2013 -analyze
for (j=0; j < w; ++j) {
int i;
unsigned int total;
@@ -2842,7 +2880,7 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fon
ranges[i].v_oversample = (unsigned char) spc->v_oversample;
for (j=0; j < ranges[i].num_chars; ++j) {
int x0,y0,x1,y1;
int codepoint = ranges[i].first_unicode_codepoint_in_range ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
int glyph = stbtt_FindGlyphIndex(info, codepoint);
stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
scale * spc->h_oversample,
@@ -2883,7 +2921,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt
if (r->was_packed) {
stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
int advance, lsb, x0,y0,x1,y1;
int codepoint = ranges[i].first_unicode_codepoint_in_range ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
int codepoint = ranges[i].array_of_unicode_codepoints == NULL ? ranges[i].first_unicode_codepoint_in_range + j : ranges[i].array_of_unicode_codepoints[j];
int glyph = stbtt_FindGlyphIndex(info, codepoint);
stbrp_coord pad = (stbrp_coord) spc->padding;
@@ -2969,6 +3007,7 @@ STBTT_DEF int stbtt_PackFontRanges(stbtt_pack_context *spc, unsigned char *fontd
if (rects == NULL)
return 0;
info.userdata = spc->user_allocator_context;
stbtt_InitFont(&info, fontdata, stbtt_GetFontOffsetForIndex(fontdata,font_index));
n = stbtt_PackFontRangesGatherRects(spc, &info, ranges, num_ranges, rects);
@@ -3186,6 +3225,12 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const
// FULL VERSION HISTORY
//
// 1.11 (2016-04-02) fix unused-variable warning
// 1.10 (2016-04-02) allow user-defined fabs() replacement
// fix memory leak if fontsize=0.0
// fix warning from duplicate typedef
// 1.09 (2016-01-16) warning fix; avoid crash on outofmem; use alloc userdata for PackFontRanges
// 1.08 (2015-09-13) document stbtt_Rasterize(); fixes for vertical & horizontal edges
// 1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
// allow PackFontRanges to pack and render in separate phases;
// fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);