aboutsummaryrefslogtreecommitdiff
path: root/sys
diff options
context:
space:
mode:
authorNicholas Noll <nbnoll@eml.cc>2020-06-02 15:49:46 -0700
committerNicholas Noll <nbnoll@eml.cc>2020-06-02 15:49:46 -0700
commite8415cc286e76ed760eb1737e097532b6eb0cf54 (patch)
tree23d299be3ed51d2756b1ef18be5202c04ff8503c /sys
parent3bce3e5f82aa5282c15b810f38e5e8e076e3aa5a (diff)
feat: extracted out allocation into interface
Diffstat (limited to 'sys')
-rw-r--r--sys/libfont/font.c127
1 files changed, 72 insertions, 55 deletions
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) {