瀏覽代碼

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

Sean Barrett 10 年之前
父節點
當前提交
4de75eb0cc
共有 3 個文件被更改,包括 64 次插入20 次删除
  1. 18 7
      stb_textedit.h
  2. 12 12
      stb_truetype.h
  3. 34 1
      tools/README.footer.md

+ 18 - 7
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;
       }
 

+ 12 - 12
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

+ 34 - 1
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?