浏览代码

Updated stb_truetype 1.07 -> 1.08

ocornut 9 年之前
父节点
当前提交
730e8119fe
共有 1 个文件被更改,包括 39 次插入24 次删除
  1. 39 24
      stb_truetype.h

+ 39 - 24
stb_truetype.h

@@ -1,4 +1,4 @@
-// stb_truetype.h - v1.07 - public domain
+// stb_truetype.h - v1.08 - public domain
 // authored from 2009-2015 by Sean Barrett / RAD Game Tools
 // authored from 2009-2015 by Sean Barrett / RAD Game Tools
 //
 //
 //   This library processes TrueType files:
 //   This library processes TrueType files:
@@ -39,13 +39,16 @@
 //       Omar Cornut
 //       Omar Cornut
 //       github:aloucks
 //       github:aloucks
 //       Peter LaValle
 //       Peter LaValle
+//       Sergey Popov
 //       Giumo X. Clanjor
 //       Giumo X. Clanjor
+//       Higor Euripedes
 //
 //
 //   Misc other:
 //   Misc other:
 //       Ryan Gordon
 //       Ryan Gordon
 //
 //
 // VERSION HISTORY
 // VERSION HISTORY
 //
 //
+//   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;
 //   1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
 //                     variant PackFontRanges to pack and render in separate phases;
 //                     variant PackFontRanges to pack and render in separate phases;
 //                     fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
 //                     fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
@@ -802,7 +805,16 @@ typedef struct
    unsigned char *pixels;
    unsigned char *pixels;
 } stbtt__bitmap;
 } 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
 
 
 //////////////////////////////////////////////////////////////////////////////
 //////////////////////////////////////////////////////////////////////////////
 //
 //
@@ -1684,7 +1696,7 @@ static stbtt__active_edge *stbtt__new_active(stbtt__hheap *hh, stbtt__edge *e, i
    //STBTT_assert(e->y0 <= start_point);
    //STBTT_assert(e->y0 <= start_point);
    if (!z) return z;
    if (!z) return z;
    z->fdx = dxdy;
    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 = e->x0 + dxdy * (start_point - e->y0);
    z->fx -= off_x;
    z->fx -= off_x;
    z->direction = e->invert ? 1.0f : -1.0f;
    z->direction = e->invert ? 1.0f : -1.0f;
@@ -1745,7 +1757,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)
 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;
    stbtt__active_edge *active = NULL;
    int y,j=0;
    int y,j=0;
    int max_weight = (255 / vsubsample);  // weight per vertical scanline
    int max_weight = (255 / vsubsample);  // weight per vertical scanline
@@ -1907,7 +1919,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
          float dx = e->fdx;
          float dx = e->fdx;
          float xb = x0 + dx;
          float xb = x0 + dx;
          float x_top, x_bottom;
          float x_top, x_bottom;
-         float y0,y1;
+         float sy0,sy1;
          float dy = e->fdy;
          float dy = e->fdy;
          STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
          STBTT_assert(e->sy <= y_bottom && e->ey >= y_top);
 
 
@@ -1916,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.
          // line with y_top, but that may be off the line segment.
          if (e->sy > y_top) {
          if (e->sy > y_top) {
             x_top = x0 + dx * (e->sy - y_top);
             x_top = x0 + dx * (e->sy - y_top);
-            y0 = e->sy;
+            sy0 = e->sy;
          } else {
          } else {
             x_top = x0;
             x_top = x0;
-            y0 = y_top;
+            sy0 = y_top;
          }
          }
          if (e->ey < y_bottom) {
          if (e->ey < y_bottom) {
             x_bottom = x0 + dx * (e->ey - y_top);
             x_bottom = x0 + dx * (e->ey - y_top);
-            y1 = e->ey;
+            sy1 = e->ey;
          } else {
          } else {
             x_bottom = xb;
             x_bottom = xb;
-            y1 = y_bottom;
+            sy1 = y_bottom;
          }
          }
 
 
          if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
          if (x_top >= 0 && x_bottom >= 0 && x_top < len && x_bottom < len) {
@@ -1936,7 +1948,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
                float height;
                float height;
                // simple case, only spans one pixel
                // simple case, only spans one pixel
                int x = (int) x_top;
                int x = (int) x_top;
-               height = y1 - y0;
+               height = sy1 - sy0;
                STBTT_assert(x >= 0 && x < len);
                STBTT_assert(x >= 0 && x < len);
                scanline[x] += e->direction * (1-((x_top - x) + (x_bottom-x))/2)  * height;
                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
                scanline_fill[x] += e->direction * height; // everything right of this pixel is filled
@@ -1947,9 +1959,9 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
                if (x_top > x_bottom) {
                if (x_top > x_bottom) {
                   // flip scanline vertically; signed area is the same
                   // flip scanline vertically; signed area is the same
                   float t;
                   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;
                   t = x_bottom, x_bottom = x_top, x_top = t;
                   dx = -dx;
                   dx = -dx;
                   dy = -dy;
                   dy = -dy;
@@ -1963,7 +1975,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
 
 
                sign = e->direction;
                sign = e->direction;
                // area of the rectangle covered from y0..y_crossing
                // 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)
                // 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);
                scanline[x1] += area * (1-((x_top - x1)+(x1+1-x1))/2);
 
 
@@ -1976,9 +1988,9 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
 
 
                STBTT_assert(fabs(area) <= 1.01f);
                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 {
          } else {
             // if edge goes outside of box we're drawing, we require
             // if edge goes outside of box we're drawing, we require
@@ -2048,7 +2060,7 @@ static void stbtt__fill_active_edges_new(float *scanline, float *scanline_fill,
 static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata)
 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;
    (void)vsubsample;
-   stbtt__hheap hh = { 0 };
+   stbtt__hheap hh = { 0, 0, 0 };
    stbtt__active_edge *active = NULL;
    stbtt__active_edge *active = NULL;
    int y,j=0, i;
    int y,j=0, i;
    float scanline_data[129], *scanline, *scanline2;
    float scanline_data[129], *scanline, *scanline2;
@@ -2088,11 +2100,13 @@ static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e,
 
 
       // insert all edges that start before the bottom of this scanline
       // insert all edges that start before the bottom of this scanline
       while (e->y0 <= scan_y_bottom) {
       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);
+            STBTT_assert(z->ey >= scan_y_top);
+            // insert at front
+            z->next = active;
+            active = z;
+         }
          ++e;
          ++e;
       }
       }
 
 
@@ -2835,7 +2849,7 @@ STBTT_DEF int stbtt_PackFontRangesGatherRects(stbtt_pack_context *spc, stbtt_fon
       ranges[i].v_oversample = (unsigned char) spc->v_oversample;
       ranges[i].v_oversample = (unsigned char) spc->v_oversample;
       for (j=0; j < ranges[i].num_chars; ++j) {
       for (j=0; j < ranges[i].num_chars; ++j) {
          int x0,y0,x1,y1;
          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);
          int glyph = stbtt_FindGlyphIndex(info, codepoint);
          stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
          stbtt_GetGlyphBitmapBoxSubpixel(info,glyph,
                                          scale * spc->h_oversample,
                                          scale * spc->h_oversample,
@@ -2876,7 +2890,7 @@ STBTT_DEF int stbtt_PackFontRangesRenderIntoRects(stbtt_pack_context *spc, stbtt
          if (r->was_packed) {
          if (r->was_packed) {
             stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
             stbtt_packedchar *bc = &ranges[i].chardata_for_range[j];
             int advance, lsb, x0,y0,x1,y1;
             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);
             int glyph = stbtt_FindGlyphIndex(info, codepoint);
             stbrp_coord pad = (stbrp_coord) spc->padding;
             stbrp_coord pad = (stbrp_coord) spc->padding;
 
 
@@ -3179,6 +3193,7 @@ STBTT_DEF int stbtt_FindMatchingFont(const unsigned char *font_collection, const
 
 
 // FULL VERSION HISTORY
 // FULL VERSION HISTORY
 //
 //
+//   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;
 //   1.07 (2015-08-01) allow PackFontRanges to accept arrays of sparse codepoints;
 //                     allow PackFontRanges to pack and render in separate phases;
 //                     allow PackFontRanges to pack and render in separate phases;
 //                     fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);
 //                     fix stbtt_GetFontOFfsetForIndex (never worked for non-0 input?);