aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-06-02 15:34:49 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-06-02 15:34:49 -0700
commit3bce3e5f82aa5282c15b810f38e5e8e076e3aa5a (patch)
treecbc06496811a52756eb13142dec845e5cac8e056 /sys
parent5f8b49fd56158b07f10333cb8873b1b80fc2f9ee (diff)
working test case
Diffstat (limited to 'sys')
-rw-r--r--sys/libfont/font.c40
-rw-r--r--sys/libfont/test.c30
2 files changed, 39 insertions, 31 deletions
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);