From e8415cc286e76ed760eb1737e097532b6eb0cf54 Mon Sep 17 00:00:00 2001 From: Nicholas Noll Date: Tue, 2 Jun 2020 15:49:46 -0700 Subject: feat: extracted out allocation into interface --- sys/libfont/font.c | 127 ++++++++++++++++++++++++++++++----------------------- 1 file changed, 72 insertions(+), 55 deletions(-) (limited to 'sys') diff --git a/sys/libfont/font.c b/sys/libfont/font.c index ff54afd..3c615fd 100644 --- a/sys/libfont/font.c +++ b/sys/libfont/font.c @@ -18,8 +18,8 @@ typedef struct Point Point; struct Buffer { uchar *data; - int cursor; - int size; + int cursor; + int size; }; struct Edge { @@ -46,22 +46,29 @@ struct Point struct font·Info { - void *userdata; - uchar *data; // pointer to .ttf file - int fontstart; // offset of start of font - - int numglyphs; // number of glyphs, needed for range checking - - int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf - int index_map; // a cmap mapping for our chosen character encoding - int indexToLocFormat; // format needed to map from glyph index to glyph - - Buffer cff; // cff font data - Buffer charstrings; // the charstring index - Buffer gsubrs; // global charstring subroutines index - Buffer subrs; // private charstring subroutines index - Buffer fontdicts; // array of font dicts - Buffer fdselect; // map from glyph to fontdict + struct { + void *heap; + union { + mem·Allocator; + mem·Allocator mal; + }; + }; + + uchar *data; // pointer to .ttf file + int fontstart; // offset of start of font + + int numglyphs; // number of glyphs, needed for range checking + + int loca,head,glyf,hhea,hmtx,kern,gpos,svg; // table locations as offset from start of .ttf + int index_map; // a cmap mapping for our chosen character encoding + int indexToLocFormat; // format needed to map from glyph index to glyph + + Buffer cff; // cff font data + Buffer charstrings; // the charstring index + Buffer gsubrs; // global charstring subroutines index + Buffer subrs; // private charstring subroutines index + Buffer fontdicts; // array of font dicts + Buffer fdselect; // map from glyph to fontdict }; struct font·Bitmap @@ -482,15 +489,18 @@ init(font·Info *info, uchar *data, int fontstart) } font·Info * -font·make(uchar *data, int fontstart) +font·make(uchar *file, int offset, mem·Allocator mem, void *heap) { int err; font·Info *info; - info = calloc(1, sizeof(*info)); - err = init(info, data, fontstart); + info = mem.alloc(heap, 1, sizeof(*info)); + info->mal = mem; + info->heap = heap; + + err = init(info, file, offset); if (err) { - free(info); + mem.free(heap, info); info = nil; } @@ -500,7 +510,13 @@ font·make(uchar *data, int fontstart) void font·free(font·Info *info) { - free(info); + void *heap; + mem·Allocator mem; + + heap = info->heap; + mem = info->mal; + + mem.free(heap, info); } int @@ -721,7 +737,7 @@ glyph_shape_tt(font·Info *info, int glyph_index, font·Vertex **pvertices) n = 1+ttUSHORT(endPtsOfContours + numberOfContours*2-2); m = n + 2*numberOfContours; // a loose bound on how many vertices we might need - vertices = malloc(m * sizeof(vertices[0])); + vertices = info->alloc(info->heap, m, sizeof(vertices[0])); if (vertices == 0) return 0; @@ -893,7 +909,7 @@ glyph_shape_tt(font·Info *info, int glyph_index, font·Vertex **pvertices) v->cy = (short)(n * (mtx[1]*x + mtx[3]*y + mtx[5])); } // Append vertices. - tmp = malloc((num_vertices+comp_num_verts)*sizeof(font·Vertex)); + tmp = info->alloc(info->heap, num_vertices+comp_num_verts, sizeof(font·Vertex)); if (!tmp) { if (vertices) free(vertices); if (comp_verts) free(comp_verts); @@ -1302,7 +1318,7 @@ static int glyph_shape_t2(font·Info *info, int glyph_index, font·Vertex **pver csctx count_ctx = CSCTX_INIT(1); csctx output_ctx = CSCTX_INIT(0); if (run_charstring(info, glyph_index, &count_ctx)) { - *pvertices = malloc(count_ctx.num_vertices*sizeof(font·Vertex)); + *pvertices = info->alloc(info->heap, count_ctx.num_vertices, sizeof(font·Vertex)); output_ctx.pvertices = *pvertices; if (run_charstring(info, glyph_index, &output_ctx)) { assert(output_ctx.num_vertices == count_ctx.num_vertices); @@ -1825,7 +1841,7 @@ typedef struct hheap static void * -hheap_alloc(hheap *hh, size_t size, void *userdata) +hheap_alloc(hheap *hh, size_t size, mem·Allocator mem, void *heap) { if (hh->first_free) { void *p = hh->first_free; @@ -1834,7 +1850,7 @@ hheap_alloc(hheap *hh, size_t size, void *userdata) } else { if (hh->num_remaining_in_head_chunk == 0) { int count = (size < 32 ? 2000 : size < 128 ? 800 : 100); - hheap_chunk *c = malloc(sizeof(hheap_chunk) + size * count); + hheap_chunk *c = mem.alloc(heap, 1, sizeof(hheap_chunk) + size * count); if (c == nil) return nil; c->next = hh->head; @@ -1856,21 +1872,21 @@ hheap_free(hheap *hh, void *p) static void -hheap_cleanup(hheap *hh, void *userdata) +hheap_cleanup(hheap *hh, mem·Allocator mem, void *heap) { hheap_chunk *c = hh->head; while (c) { hheap_chunk *n = c->next; - free(c); + mem.free(heap, c); c = n; } } static ActiveEdge * -new_active(hheap *hh, Edge *e, int off_x, float start_point, void *userdata) +new_active(hheap *hh, Edge *e, int off_x, float start_point, mem·Allocator mem, void *heap) { - ActiveEdge *z = (ActiveEdge *) hheap_alloc(hh, sizeof(*z), userdata); + ActiveEdge *z = (ActiveEdge *) hheap_alloc(hh, sizeof(*z), mem, heap); float dxdy = (e->x1 - e->x0) / (e->y1 - e->y0); assert(z != nil); //assert(e->y0 <= start_point); @@ -2093,7 +2109,7 @@ fill_active_edges_new(float *scanline, float *scanline_fill, int len, ActiveEdge // directly AA rasterize edges w/o supersampling static void -rasterize_sorted_edges(font·Bitmap *result, Edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) +rasterize_sorted_edges(font·Bitmap *result, Edge *e, int n, int vsubsample, int off_x, int off_y, mem·Allocator mem, void *heap) { hheap hh = { 0, 0, 0 }; ActiveEdge *active = nil; @@ -2101,7 +2117,7 @@ rasterize_sorted_edges(font·Bitmap *result, Edge *e, int n, int vsubsample, int float scanline_data[129], *scanline, *scanline2; if (result->w > 64) - scanline = malloc((result->w*2+1) * sizeof(float)); + scanline = mem.alloc(heap, (result->w*2+1), sizeof(float)); else scanline = scanline_data; @@ -2136,7 +2152,7 @@ rasterize_sorted_edges(font·Bitmap *result, Edge *e, int n, int vsubsample, int // insert all edges that start before the bottom of this scanline while (e->y0 <= scan_y_bottom) { if (e->y0 != e->y1) { - ActiveEdge *z = new_active(&hh, e, off_x, scan_y_top, userdata); + ActiveEdge *z = new_active(&hh, e, off_x, scan_y_top, mem, heap); if (z != nil) { if (j == 0 && off_y != 0) { if (z->ey < scan_y_top) { @@ -2182,10 +2198,10 @@ rasterize_sorted_edges(font·Bitmap *result, Edge *e, int n, int vsubsample, int ++j; } - hheap_cleanup(&hh, userdata); + hheap_cleanup(&hh, mem, heap); if (scanline != scanline_data) - free(scanline); + mem.free(heap, scanline); } #define CMP_Y0(a,b) ((a)->y0 < (b)->y0) @@ -2287,7 +2303,7 @@ sort_edges(Edge *p, int n) static void -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) +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, mem·Allocator mem, void *heap) { float y_scale_inv = invert ? -scale_y : scale_y; Edge *e; @@ -2300,8 +2316,9 @@ rasterize_points(font·Bitmap *result, Point *pts, int *wcount, int windings, fl for (i=0; i < windings; ++i) n += wcount[i]; - e = malloc(sizeof(*e) * (n+1)); // add an extra one as a sentinel - if (e == 0) return; + e = mem.alloc(heap, n+1, sizeof(*e)); // add an extra one as a sentinel + if (e == 0) + return; n = 0; m=0; @@ -2332,9 +2349,9 @@ rasterize_points(font·Bitmap *result, Point *pts, int *wcount, int windings, fl sort_edges(e, n); // now, traverse the scanlines and find the intersections on each scanline, use xor winding rule - rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata); + rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, mem, heap); - free(e); + mem.free(heap, e); } static @@ -2418,7 +2435,7 @@ tesselate_cubic(Point *points, int *num_points, float x0, float y0, float x1, fl // returns number of contours static Point * -flatten(font·Vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) +flatten(font·Vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, mem·Allocator mem, void *heap) { Point *points=0; int num_points=0; @@ -2435,7 +2452,7 @@ flatten(font·Vertex *vertices, int num_verts, float objspace_flatness, int **co if (n == 0) return 0; - *contour_lengths = malloc(sizeof(**contour_lengths) * n); + *contour_lengths = mem.alloc(heap, n, sizeof(**contour_lengths)); if (*contour_lengths == 0) { *num_contours = 0; @@ -2446,7 +2463,7 @@ flatten(font·Vertex *vertices, int num_verts, float objspace_flatness, int **co for (pass=0; pass < 2; ++pass) { float x=0,y=0; if (pass == 1) { - points = malloc(num_points * sizeof(points[0])); + points = mem.alloc(heap, num_points, sizeof(points[0])); if (!points) goto error; } @@ -2490,8 +2507,8 @@ flatten(font·Vertex *vertices, int num_verts, float objspace_flatness, int **co return points; error: - free(points); - free(*contour_lengths); + mem.free(heap, points); + mem.free(heap, *contour_lengths); *contour_lengths = nil; *num_contours = 0; return nil; @@ -2499,14 +2516,14 @@ error: 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) +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, mem·Allocator mal, void *heap) { 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); + Point *windings = flatten(vertices, num_verts, flatness_in_pixels / scale, &winding_lengths, &winding_count, mal, heap); if (windings) { - rasterize_points(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, mal, heap); free(winding_lengths); free(windings); } @@ -2548,11 +2565,11 @@ font·glyph_makebitmap_subpixel(font·Info *info, float scale_x, float scale_y, if (yoff ) *yoff = iy0; if (gbm.w && gbm.h) { - gbm.pixels = malloc(gbm.w * gbm.h); + gbm.pixels = info->alloc(info->heap, 1, gbm.h*gbm.w); if (gbm.pixels) { gbm.stride = gbm.w; - 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->mal, info->heap); } } free(vertices); @@ -2580,7 +2597,7 @@ font·glyph_fillbitmap_subpixel(font·Info *info, uchar *output, int out_w, int gbm.stride = out_stride; if (gbm.w && gbm.h) - 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->mal, info->heap); free(vertices); } @@ -3029,8 +3046,8 @@ font·glyph_sdf(font·Info *info, float scale, int glyph, int padding, uchar one float *precompute; font·Vertex *verts; int num_verts = font·glyph_shape(info, glyph, &verts); - data = malloc(w * h); - precompute = malloc(num_verts * sizeof(float)); + data = info->alloc(info->heap, 1, w * h); + precompute = info->alloc(info->heap, num_verts, sizeof(float)); for (i=0,j=num_verts-1; i < num_verts; j=i++) { if (verts[i].type == font·Vline) { -- cgit v1.2.1