From 4de75eb0cc129bbfd7fa29cbc7381476305523d9 Mon Sep 17 00:00:00 2001 From: Sean Barrett Date: Sun, 13 Sep 2015 13:35:51 -0700 Subject: [PATCH] stb_textedit: better support for baseline at bottom stb_textedit: end-of-line handling places cursor before newline stb_truetype: avoid compiler warning due to local vars hiding local vars readme: add list of one-file libs --- stb_textedit.h | 25 ++++++++++++++++++------- stb_truetype.h | 24 ++++++++++++------------ tools/README.footer.md | 35 ++++++++++++++++++++++++++++++++++- 3 files changed, 64 insertions(+), 20 deletions(-) diff --git a/stb_textedit.h b/stb_textedit.h index b8309ff..6740b91 100644 --- a/stb_textedit.h +++ b/stb_textedit.h @@ -1,4 +1,4 @@ -// stb_textedit.h - v1.6 - public domain - Sean Barrett +// stb_textedit.h - v1.7 - 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 @@ -31,6 +31,7 @@ // // VERSION HISTORY // +// 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 @@ -45,10 +46,14 @@ // 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 // // This file behaves differently depending on what symbols you define @@ -380,9 +385,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; @@ -393,6 +395,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; @@ -986,8 +991,11 @@ retry: 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; } @@ -1012,8 +1020,11 @@ retry: 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; } diff --git a/stb_truetype.h b/stb_truetype.h index a868596..00d22eb 100644 --- a/stb_truetype.h +++ b/stb_truetype.h @@ -1919,7 +1919,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); @@ -1928,17 +1928,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) { @@ -1948,7 +1948,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 @@ -1959,9 +1959,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; @@ -1975,7 +1975,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); @@ -1988,9 +1988,9 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill, STBTT_assert(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 diff --git a/tools/README.footer.md b/tools/README.footer.md index aa07eeb..23c3336 100644 --- a/tools/README.footer.md +++ b/tools/README.footer.md @@ -70,7 +70,40 @@ too rare or if the size of implementation vs. apparent benefit is too low. #### Are there other single-file public-domain libraries out there? -Yes. I'll put a list here when people remind me what they are. +Yes. Here are some: + +- [jo_gif.cpp](http://www.jonolick.com/home/gif-writer): tiny GIF writer (public domain) +- [gif.h](https://github.com/ginsweater/gif-h): animated GIF writer (public domain) +- [tiny_jpeg.h](https://github.com/serge-rgb/TinyJPEG/blob/master/tiny_jpeg.h): JPEG encoder (public domain) +- [lodepng](http://lodev.org/lodepng/): PNG encoder/decoder (zlib license) + +- [nanoSVG](https://github.com/memononen/nanosvg): 1-file SVG parser; 1-file SVG rasterizer (zlib license) +- [tinyobjloader](https://github.com/syoyo/tinyobjloader): wavefront OBJ file loader (BSD license) + +- [sdf.h](https://github.com/memononen/SDF): compute signed-distance field from antialiased image (MIT license) +- [nv_voronoi.h](http://www.icculus.org/~mordred/nvlib/): find voronoi regions on lattice w/ integer inputs (public domain) +- [nanoflann](https://github.com/jlblancoc/nanoflann): build KD trees for point clouds (BSD license) + +- [DG_misc.h](https://github.com/DanielGibson/Snippets/): Daniel Gibson's stb.h-esque cross-platform helpers: path/file, strings (public domain) +- [MakeID.h](http://www.humus.name/3D/MakeID.h): allocate/deallocate small integer IDs efficiently (public domain) +- [utest](https://github.com/evolutional/utest): unit testing (MIT license) + +There are some that have a source file and require a separate header file (which they may +not even supply). That's twice as many files, and we at nothings/stb cannot condone +this! But you might like them anyway: + +- [picopng.cpp](http://lodev.org/lodepng/picopng.cpp): tiny PNG loader (zlib license) +- [jpeg-compressor](https://github.com/richgel999/jpeg-compressor): 2-file jpeg compress, 2-file jpeg decompress (public domain) +- [tinyexr](https://github.com/syoyo/tinyexr): EXR image read/write, uses miniz internally (BSD license) +- [miniz.c](https://github.com/richgel999/miniz): zlib compression,decompression, zip file, png writing (public domain) +- [Remotery](https://github.com/Celtoys/Remotery): CPU/GPU profiler Win/Mac/Linux, using web browser for viewer (Apache 2.0 license) +- [Clipper](http://www.angusj.com/delphi/clipper.php): line & polygon clipping & offsetting (Boost license) +- [json.h](https://github.com/sheredom/json.h): JSON parser (public domain) +- [Zange](https://github.com/vurtun/zange/blob/master/json.c): another JSON parser (MIT license) + +There is also this XML library, but if you're using XML, shame on you: + +- [tinyxml2](https://github.com/leethomason/tinyxml2): XML (zlib license) #### Do you have any advice on how to create my own single-file library?