From 3bce3e5f82aa5282c15b810f38e5e8e076e3aa5a Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Tue, 2 Jun 2020 15:34:49 -0700 Subject: working test case --- sys/libfont/font.c | 40 +++++++++++++++++++++++----------------- sys/libfont/test.c | 30 ++++++++++++++++-------------- 2 files changed, 39 insertions(+), 31 deletions(-) (limited to 'sys') diff --git a/sys/libfont/font.c b/sys/libfont/font.c index f7dfce7..ff54afd 100644 --- a/sys/libfont/font.c +++ b/sys/libfont/font.c @@ -2248,13 +2248,16 @@ sort_edges_quicksort(Edge *p, int n) /* handling of equality is crucial here */ /* for sentinels & efficiency with duplicates */ for (;;++i) { - if (!CMP_Y0(&p[i], &p[0])) break; + if (!CMP_Y0(&p[i], &p[0])) + break; } for (;;--j) { - if (!CMP_Y0(&p[0], &p[j])) break; + if (!CMP_Y0(&p[0], &p[j])) + break; } /* make sure we haven't crossed */ - if (i >= j) break; + if (i >= j) + break; t = p[i]; p[i] = p[j]; p[j] = t; @@ -2284,7 +2287,7 @@ sort_edges(Edge *p, int n) static void -rasterize(font·Bitmap *result, Point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata) +rasterize_points(font·Bitmap *result, Point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata) { float y_scale_inv = invert ? -scale_y : scale_y; Edge *e; @@ -2326,7 +2329,6 @@ rasterize(font·Bitmap *result, Point *pts, int *wcount, int windings, float sca } // now sort the edges by their highest point (should snap to integer, and then by x) - //STBTT_sort(e, n, sizeof(e[0]), edge_compare); sort_edges(e, n); // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule @@ -2339,7 +2341,9 @@ static void add_point(Point *points, int n, float x, float y) { - if (!points) return; // during first pass, it's unallocated + if (!points) + return; // during first pass, it's unallocated + points[n].x = x; points[n].y = y; } @@ -2428,7 +2432,8 @@ flatten(font·Vertex *vertices, int num_verts, float objspace_flatness, int **co ++n; *num_contours = n; - if (n == 0) return 0; + if (n == 0) + return 0; *contour_lengths = malloc(sizeof(**contour_lengths) * n); @@ -2482,25 +2487,26 @@ flatten(font·Vertex *vertices, int num_verts, float objspace_flatness, int **co } (*contour_lengths)[n] = num_points - start; } - return points; + error: free(points); free(*contour_lengths); - *contour_lengths = 0; - *num_contours = 0; + *contour_lengths = nil; + *num_contours = 0; return nil; } -void -font·rasterize(font·Bitmap *result, float flatness_in_pixels, font·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) +static +void +rasterize(font·Bitmap *result, float flatness_in_pixels, font·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) { - float scale = scale_x > scale_y ? scale_y : scale_x; + float scale = (scale_x > scale_y) ? scale_y : scale_x; int winding_count = 0; int *winding_lengths = nil; Point *windings = flatten(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, userdata); if (windings) { - rasterize(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); + rasterize_points(result, windings, winding_lengths, winding_count, scale_x, scale_y, shift_x, shift_y, x_off, y_off, invert, userdata); free(winding_lengths); free(windings); } @@ -2546,7 +2552,7 @@ font·glyph_makebitmap_subpixel(font·Info *info, float scale_x, float scale_y, if (gbm.pixels) { gbm.stride = gbm.w; - font·rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); + rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0, iy0, 1, info->userdata); } } free(vertices); @@ -2574,7 +2580,7 @@ font·glyph_fillbitmap_subpixel(font·Info *info, uchar *output, int out_w, int gbm.stride = out_stride; if (gbm.w && gbm.h) - font·rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata); + rasterize(&gbm, 0.35f, vertices, num_verts, scale_x, scale_y, shift_x, shift_y, ix0,iy0, 1, info->userdata); free(vertices); } @@ -2624,7 +2630,7 @@ h_prefilter(uchar *pixels, int w, int h, int stride_in_bytes, unsigned int kerne uchar buffer[SAMPLE]; int safe_w = w - kernel_width; int j; - memset(buffer, 0, SAMPLE); // suppress bogus warning from VS2013 -analyze + memset(buffer, 0, SAMPLE); for (j=0; j < h; ++j) { int i; unsigned int total; diff --git a/sys/libfont/test.c b/sys/libfont/test.c index b92a56f..569d7ad 100644 --- a/sys/libfont/test.c +++ b/sys/libfont/test.c @@ -15,11 +15,12 @@ int main() { int i, err; - float scale; + float x, dx, scale; uchar *bitmap; font·Info *info; mmap·Reader fontfile; - int x, y, as, ds, lg, ax, lsb, off, kern, r[2], c0[2], c1[2]; + int off, y, ascent, descent, baseln; + int adv, lsb, r0[2], r1[2]; err = 0; fontfile = mmap·open("/home/nolln/root/data/DejaVuSans.ttf"); @@ -34,22 +35,23 @@ main() bitmap = calloc(W*H, sizeof(*bitmap)); scale = font·scaleheightto(info, L); - font·vmetrics(info, &as, &ds, &lg); - as *= scale; - ds *= scale; + font·vmetrics(info, &ascent, &descent, &baseln); + ascent *= scale; - x = 0; + x = 0.; for (i = 0; i < strlen(phrase); i++) { - font·code_hmetrics(info, phrase[i], &ax, &lsb); - font·code_bitmapbox(info, phrase[i], scale, scale, c0, c0+1, c1, c1+1); + dx = x - (float)floor(x); + font·code_hmetrics(info, phrase[i], &adv, &lsb); + font·code_bitmapbox_subpixel(info, phrase[i], scale, scale, dx, 0, r0, r0+1, r1, r1+1); - y = as + c0[1]; - off = x + lsb * scale + y * W; - font·code_fillbitmap(info, bitmap+off, c1[0]-c0[0], c1[1]-c0[1], W, scale, scale, phrase[i]); + y = ascent + r0[1]; + off = (int)floor(x) + (lsb * scale) + y * W; - x += ax * scale; - kern = font·code_kernadvance(info, phrase[i], phrase[i+1]); - x += kern * scale; + font·code_fillbitmap_subpixel(info, bitmap+off, r1[0]-r0[0], r1[1]-r0[1], W, scale, scale, dx, 0, phrase[i]); + + x += scale * adv; + if (phrase[i+1]) + x += scale * font·code_kernadvance(info, phrase[i], phrase[i+1]); } stbi_write_png("out.png", W, H, 1, bitmap, W); -- cgit v1.2.1