public static int stbtt_PackFontRanges(stbtt_pack_context spc, byte *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges) { var info = new stbtt_fontinfo(); var i = 0; var j = 0; var n = 0; var return_value = 1; stbrp_rect *rects; for (i = 0; i < num_ranges; ++i) { for (j = 0; j < ranges[i].num_chars; ++j) { ranges[i].chardata_for_range[j].x0 = ranges[i].chardata_for_range[j].y0 = ranges[i].chardata_for_range[j].x1 = ranges[i].chardata_for_range[j].y1 = 0; } } n = 0; for (i = 0; i < num_ranges; ++i) { n += ranges[i].num_chars; } rects = (stbrp_rect *)CRuntime.malloc((ulong)(sizeof(stbrp_rect) * n)); if (rects == null) { return(0); } info.userdata = spc.user_allocator_context; stbtt_InitFont(info, fontdata, stbtt_GetFontOffsetForIndex(fontdata, font_index)); n = stbtt_PackFontRangesGatherRects(spc, info, ranges, num_ranges, rects); stbtt_PackFontRangesPackRects(spc, rects, n); return_value = stbtt_PackFontRangesRenderIntoRects(spc, info, ranges, num_ranges, rects); CRuntime.free(rects); return(return_value); }
public static int stbtt_PackBegin(stbtt_pack_context spc, byte *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) { var context = (stbrp_context *)CRuntime.malloc((ulong)sizeof(stbrp_context)); var num_nodes = pw - padding; var nodes = (stbrp_node *)CRuntime.malloc((ulong)(sizeof(stbrp_node) * num_nodes)); if (context == null || nodes == null) { if (context != null) { CRuntime.free(context); } if (nodes != null) { CRuntime.free(nodes); } return(0); } spc.user_allocator_context = alloc_context; spc.width = pw; spc.height = ph; spc.pixels = pixels; spc.pack_info = context; spc.nodes = nodes; spc.padding = padding; spc.stride_in_bytes = stride_in_bytes != 0 ? stride_in_bytes : pw; spc.h_oversample = 1; spc.v_oversample = 1; spc.skip_missing = 0; stbrp_init_target(context, pw - padding, ph - padding, nodes, num_nodes); if (pixels != null) { CRuntime.memset(pixels, 0, (ulong)(pw * ph)); } return(1); }
public static int stbtt_PackBegin(stbtt_pack_context spc, byte *pixels, int pw, int ph, int stride_in_bytes, int padding, void *alloc_context) { stbrp_context *context = (stbrp_context *)(CRuntime.malloc((ulong)(sizeof(stbrp_context)))); int num_nodes = (int)(pw - padding); stbrp_node * nodes = (stbrp_node *)(CRuntime.malloc((ulong)(sizeof(stbrp_node) * num_nodes))); if (((context) == (null)) || ((nodes) == (null))) { if (context != (null)) { CRuntime.free(context); } if (nodes != (null)) { CRuntime.free(nodes); } return((int)(0)); } spc.user_allocator_context = alloc_context; spc.width = (int)(pw); spc.height = (int)(ph); spc.pixels = pixels; spc.pack_info = context; spc.nodes = nodes; spc.padding = (int)(padding); spc.stride_in_bytes = (int)(stride_in_bytes != 0 ? stride_in_bytes : pw); spc.h_oversample = (uint)(1); spc.v_oversample = (uint)(1); spc.skip_missing = (int)(0); stbrp_init_target(context, (int)(pw - padding), (int)(ph - padding), nodes, (int)(num_nodes)); if ((pixels) != null) { CRuntime.memset(pixels, (int)(0), (ulong)(pw * ph)); } return((int)(1)); }
public static int stbtt_BakeFontBitmap_internal(byte *data, int offset, float pixel_height, byte *pixels, int pw, int ph, int first_char, int num_chars, stbtt_bakedchar *chardata) { float scale = 0; var x = 0; var y = 0; var bottom_y = 0; var i = 0; var f = new stbtt_fontinfo(); f.userdata = null; if (stbtt_InitFont(f, data, offset) == 0) { return(-1); } CRuntime.memset(pixels, 0, (ulong)(pw * ph)); x = y = 1; bottom_y = 1; scale = stbtt_ScaleForPixelHeight(f, pixel_height); for (i = 0; i < num_chars; ++i) { var advance = 0; var lsb = 0; var x0 = 0; var y0 = 0; var x1 = 0; var y1 = 0; var gw = 0; var gh = 0; var g = stbtt_FindGlyphIndex(f, first_char + i); stbtt_GetGlyphHMetrics(f, g, &advance, &lsb); stbtt_GetGlyphBitmapBox(f, g, scale, scale, &x0, &y0, &x1, &y1); gw = x1 - x0; gh = y1 - y0; if (x + gw + 1 >= pw) { y = bottom_y; x = 1; } if (y + gh + 1 >= ph) { return(-i); } stbtt_MakeGlyphBitmap(f, pixels + x + y * pw, gw, gh, pw, scale, scale, g); chardata[i].x0 = (ushort)(short)x; chardata[i].y0 = (ushort)(short)y; chardata[i].x1 = (ushort)(short)(x + gw); chardata[i].y1 = (ushort)(short)(y + gh); chardata[i].xadvance = scale * advance; chardata[i].xoff = x0; chardata[i].yoff = y0; x = x + gw + 1; if (y + gh + 1 > bottom_y) { bottom_y = y + gh + 1; } } return(bottom_y); }
public static void stbtt__v_prefilter(byte *pixels, int w, int h, int stride_in_bytes, uint kernel_width) { var buffer = stackalloc byte[8]; var safe_h = (int)(h - kernel_width); var j = 0; CRuntime.memset(buffer, 0, (ulong)8); for (j = 0; j < w; ++j) { var i = 0; uint total = 0; CRuntime.memset(buffer, 0, (ulong)kernel_width); total = 0; switch (kernel_width) { case 2: for (i = 0; i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = pixels[i * stride_in_bytes]; pixels[i * stride_in_bytes] = (byte)(total / 2); } break; case 3: for (i = 0; i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = pixels[i * stride_in_bytes]; pixels[i * stride_in_bytes] = (byte)(total / 3); } break; case 4: for (i = 0; i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = pixels[i * stride_in_bytes]; pixels[i * stride_in_bytes] = (byte)(total / 4); } break; case 5: for (i = 0; i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = pixels[i * stride_in_bytes]; pixels[i * stride_in_bytes] = (byte)(total / 5); } break; default: for (i = 0; i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = pixels[i * stride_in_bytes]; pixels[i * stride_in_bytes] = (byte)(total / kernel_width); } break; } for (; i < h; ++i) { total -= buffer[i & (8 - 1)]; pixels[i * stride_in_bytes] = (byte)(total / kernel_width); } pixels += 1; } }
public static int stbtt__ray_intersect_bezier(float *orig, float *ray, float *q0, float *q1, float *q2, float **hits) { var q0perp = q0[1] * ray[0] - q0[0] * ray[1]; var q1perp = q1[1] * ray[0] - q1[0] * ray[1]; var q2perp = q2[1] * ray[0] - q2[0] * ray[1]; var roperp = orig[1] * ray[0] - orig[0] * ray[1]; var a = q0perp - 2 * q1perp + q2perp; var b = q1perp - q0perp; var c = q0perp - roperp; float s0 = 0; float s1 = 0; var num_s = 0; if (a != 0.0) { var discr = b * b - a * c; if (discr > 0.0) { var rcpna = -1 / a; var d = (float)CRuntime.sqrt(discr); s0 = (b + d) * rcpna; s1 = (b - d) * rcpna; if (s0 >= 0.0 && s0 <= 1.0) { num_s = 1; } if (d > 0.0 && s1 >= 0.0 && s1 <= 1.0) { if (num_s == 0) { s0 = s1; } ++num_s; } } } else { s0 = c / (-2 * b); if (s0 >= 0.0 && s0 <= 1.0) { num_s = 1; } } if (num_s == 0) { return(0); } var rcp_len2 = 1 / (ray[0] * ray[0] + ray[1] * ray[1]); var rayn_x = ray[0] * rcp_len2; var rayn_y = ray[1] * rcp_len2; var q0d = q0[0] * rayn_x + q0[1] * rayn_y; var q1d = q1[0] * rayn_x + q1[1] * rayn_y; var q2d = q2[0] * rayn_x + q2[1] * rayn_y; var rod = orig[0] * rayn_x + orig[1] * rayn_y; var q10d = q1d - q0d; var q20d = q2d - q0d; var q0rd = q0d - rod; hits[0][0] = q0rd + s0 * (2.0f - 2.0f * s0) * q10d + s0 * s0 * q20d; hits[0][1] = a * s0 + b; if (num_s > 1) { hits[1][0] = q0rd + s1 * (2.0f - 2.0f * s1) * q10d + s1 * s1 * q20d; hits[1][1] = a * s1 + b; return(2); } return(1); }
public static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts) { var i = 0; var orig = stackalloc float[2]; var ray = stackalloc float[] { 1, 0 }; float y_frac = 0; var winding = 0; y_frac = (float)CRuntime.fmod(y, 1.0f); if (y_frac < 0.01f) { y += 0.01f; } else if (y_frac > 0.99f) { y -= 0.01f; } orig[0] = x; orig[1] = y; for (i = 0; i < nverts; ++i) { if (verts[i].type == STBTT_vline) { int x0 = verts[i - 1].x; int y0 = verts[i - 1].y; int x1 = verts[i].x; int y1 = verts[i].y; if (y > (y0 < y1 ? y0 : y1) && y < (y0 < y1 ? y1 : y0) && x > (x0 < x1 ? x0 : x1)) { var x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0; if (x_inter < x) { winding += y0 < y1 ? 1 : -1; } } } if (verts[i].type == STBTT_vcurve) { int x0 = verts[i - 1].x; int y0 = verts[i - 1].y; int x1 = verts[i].cx; int y1 = verts[i].cy; int x2 = verts[i].x; int y2 = verts[i].y; var ax = x0 < (x1 < x2 ? x1 : x2) ? x0 : x1 < x2 ? x1 : x2; var ay = y0 < (y1 < y2 ? y1 : y2) ? y0 : y1 < y2 ? y1 : y2; var by = y0 < (y1 < y2 ? y2 : y1) ? y1 < y2 ? y2 : y1 : y0; if (y > ay && y < by && x > ax) { var q0 = stackalloc float[2]; var q1 = stackalloc float[2]; var q2 = stackalloc float[2]; var hitsArray = new UnsafeArray2D <float>(2, 2); var hits = (float **)hitsArray; q0[0] = x0; q0[1] = y0; q1[0] = x1; q1[1] = y1; q2[0] = x2; q2[1] = y2; if (equal(q0, q1) != 0 || equal(q1, q2) != 0) { x0 = verts[i - 1].x; y0 = verts[i - 1].y; x1 = verts[i].x; y1 = verts[i].y; if (y > (y0 < y1 ? y0 : y1) && y < (y0 < y1 ? y1 : y0) && x > (x0 < x1 ? x0 : x1)) { var x_inter = (y - y0) / (y1 - y0) * (x1 - x0) + x0; if (x_inter < x) { winding += y0 < y1 ? 1 : -1; } } } else { var num_hits = stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits); if (num_hits >= 1) { if (hits[0][0] < 0) { winding += hits[0][1] < 0 ? -1 : 1; } } if (num_hits >= 2) { if (hits[1][0] < 0) { winding += hits[1][1] < 0 ? -1 : 1; } } } } } } return(winding); }
public static void stbtt__rasterize_sorted_edges(stbtt__bitmap *result, stbtt__edge *e, int n, int vsubsample, int off_x, int off_y, void *userdata) { var hh = new stbtt__hheap(); stbtt__active_edge *active = null; var y = 0; var j = 0; var i = 0; var scanline_data = stackalloc float[129]; float *scanline; float *scanline2; if (result->w > 64) { scanline = (float *)CRuntime.malloc((ulong)((result->w * 2 + 1) * sizeof(float))); } else { scanline = scanline_data; } scanline2 = scanline + result->w; y = off_y; e[n].y0 = (float)(off_y + result->h) + 1; while (j < result->h) { var scan_y_top = y + 0.0f; var scan_y_bottom = y + 1.0f; var step = &active; CRuntime.memset(scanline, 0, (ulong)(result->w * sizeof(float))); CRuntime.memset(scanline2, 0, (ulong)((result->w + 1) * sizeof(float))); while (*step != null) { var z = *step; if (z->ey <= scan_y_top) { *step = z->next; z->direction = 0; stbtt__hheap_free(&hh, z); } else { step = &(*step)->next; } } while (e->y0 <= scan_y_bottom) { if (e->y0 != e->y1) { var z = stbtt__new_active(&hh, e, off_x, scan_y_top, userdata); if (z != null) { if (j == 0 && off_y != 0) { if (z->ey < scan_y_top) { z->ey = scan_y_top; } } z->next = active; active = z; } } ++e; } if (active != null) { stbtt__fill_active_edges_new(scanline, scanline2 + 1, result->w, active, scan_y_top); } { float sum = 0; for (i = 0; i < result->w; ++i) { float k = 0; var m = 0; sum += scanline2[i]; k = scanline[i] + sum; k = CRuntime.fabs(k) * 255 + 0.5f; m = (int)k; if (m > 255) { m = 255; } result->pixels[j * result->stride + i] = (byte)m; } } step = &active; while (*step != null) { var z = *step; z->fx += z->fdx; step = &(*step)->next; } ++y; ++j; } stbtt__hheap_cleanup(&hh, userdata); if (scanline != scanline_data) { CRuntime.free(scanline); } }
public 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 = new stbtt__hheap(); stbtt__active_edge *active = (null); int y = 0; int j = (int)(0); int i = 0; float *scanline_data = stackalloc float[129]; float *scanline; float *scanline2; if ((result->w) > (64)) { scanline = (float *)(CRuntime.malloc((ulong)((result->w * 2 + 1) * sizeof(float)))); } else { scanline = scanline_data; } scanline2 = scanline + result->w; y = (int)(off_y); e[n].y0 = (float)((float)(off_y + result->h) + 1); while ((j) < (result->h)) { float scan_y_top = (float)(y + 0.0f); float scan_y_bottom = (float)(y + 1.0f); stbtt__active_edge **step = &active; CRuntime.memset(scanline, (int)(0), (ulong)(result->w * sizeof(float))); CRuntime.memset(scanline2, (int)(0), (ulong)((result->w + 1) * sizeof(float))); while ((*step) != null) { stbtt__active_edge *z = *step; if (z->ey <= scan_y_top) { *step = z->next; z->direction = (float)(0); stbtt__hheap_free(&hh, z); } else { step = &((*step)->next); } } while (e->y0 <= scan_y_bottom) { if (e->y0 != e->y1) { stbtt__active_edge *z = stbtt__new_active(&hh, e, (int)(off_x), (float)(scan_y_top), userdata); if (z != (null)) { if (((j) == (0)) && (off_y != 0)) { if ((z->ey) < (scan_y_top)) { z->ey = (float)(scan_y_top); } } z->next = active; active = z; } } ++e; } if ((active) != null) { stbtt__fill_active_edges_new(scanline, scanline2 + 1, (int)(result->w), active, (float)(scan_y_top)); } { float sum = (float)(0); for (i = (int)(0); (i) < (result->w); ++i) { float k = 0; int m = 0; sum += (float)(scanline2[i]); k = (float)(scanline[i] + sum); k = (float)((float)(CRuntime.fabs((double)(k))) * 255 + 0.5f); m = ((int)(k)); if ((m) > (255)) { m = (int)(255); } result->pixels[j * result->stride + i] = ((byte)(m)); } } step = &active; while ((*step) != null) { stbtt__active_edge *z = *step; z->fx += (float)(z->fdx); step = &((*step)->next); } ++y; ++j; } stbtt__hheap_cleanup(&hh, userdata); if (scanline != scanline_data) { CRuntime.free(scanline); } }
public static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) { stbtt__point *points = null; int num_points = (int)(0); float objspace_flatness_squared = (float)(objspace_flatness * objspace_flatness); int i = 0; int n = (int)(0); int start = (int)(0); int pass = 0; for (i = (int)(0); (i) < (num_verts); ++i) { if ((vertices[i].type) == (STBTT_vmove)) { ++n; } } *num_contours = (int)(n); if ((n) == (0)) { return(null); } *contour_lengths = (int *)(CRuntime.malloc((ulong)(sizeof(int) * n))); if ((*contour_lengths) == (null)) { *num_contours = (int)(0); return(null); } for (pass = (int)(0); (pass) < (2); ++pass) { float x = (float)(0); float y = (float)(0); if ((pass) == (1)) { points = (stbtt__point *)(CRuntime.malloc((ulong)(num_points * sizeof(stbtt__point)))); if ((points) == (null)) { goto error; } } num_points = (int)(0); n = (int)(-1); for (i = (int)(0); (i) < (num_verts); ++i) { switch (vertices[i].type) { case STBTT_vmove: if ((n) >= (0)) { (*contour_lengths)[n] = (int)(num_points - start); } ++n; start = (int)(num_points); x = (float)(vertices[i].x); y = (float)(vertices[i].y); stbtt__add_point(points, (int)(num_points++), (float)(x), (float)(y)); break; case STBTT_vline: x = (float)(vertices[i].x); y = (float)(vertices[i].y); stbtt__add_point(points, (int)(num_points++), (float)(x), (float)(y)); break; case STBTT_vcurve: stbtt__tesselate_curve(points, &num_points, (float)(x), (float)(y), (float)(vertices[i].cx), (float)(vertices[i].cy), (float)(vertices[i].x), (float)(vertices[i].y), (float)(objspace_flatness_squared), (int)(0)); x = (float)(vertices[i].x); y = (float)(vertices[i].y); break; case STBTT_vcubic: stbtt__tesselate_cubic(points, &num_points, (float)(x), (float)(y), (float)(vertices[i].cx), (float)(vertices[i].cy), (float)(vertices[i].cx1), (float)(vertices[i].cy1), (float)(vertices[i].x), (float)(vertices[i].y), (float)(objspace_flatness_squared), (int)(0)); x = (float)(vertices[i].x); y = (float)(vertices[i].y); break; } } (*contour_lengths)[n] = (int)(num_points - start); } return(points); error: ; CRuntime.free(points); CRuntime.free(*contour_lengths); *contour_lengths = null; *num_contours = (int)(0); return(null); }
public static void stbtt_PackEnd(stbtt_pack_context spc) { CRuntime.free(spc.nodes); CRuntime.free(spc.pack_info); }
public static int stbtt__compute_crossings_x(float x, float y, int nverts, stbtt_vertex *verts) { int i = 0; float *orig = stackalloc float[2]; float *ray = stackalloc float[2]; ray[0] = (float)(1); ray[1] = (float)(0); float y_frac = 0; int winding = (int)(0); orig[0] = (float)(x); orig[1] = (float)(y); y_frac = ((float)(CRuntime.fmod((double)(y), (double)(1.0f)))); if ((y_frac) < (0.01f)) { y += (float)(0.01f); } else if ((y_frac) > (0.99f)) { y -= (float)(0.01f); } orig[1] = (float)(y); for (i = (int)(0); (i) < (nverts); ++i) { if ((verts[i].type) == (STBTT_vline)) { int x0 = (int)(verts[i - 1].x); int y0 = (int)(verts[i - 1].y); int x1 = (int)(verts[i].x); int y1 = (int)(verts[i].y); if ((((y) > ((y0) < (y1) ? (y0) : (y1))) && ((y) < ((y0) < (y1) ? (y1) : (y0)))) && ((x) > ((x0) < (x1) ? (x0) : (x1)))) { float x_inter = (float)((y - y0) / (y1 - y0) * (x1 - x0) + x0); if ((x_inter) < (x)) { winding += (int)(((y0) < (y1)) ? 1 : -1); } } } if ((verts[i].type) == (STBTT_vcurve)) { int x0 = (int)(verts[i - 1].x); int y0 = (int)(verts[i - 1].y); int x1 = (int)(verts[i].cx); int y1 = (int)(verts[i].cy); int x2 = (int)(verts[i].x); int y2 = (int)(verts[i].y); int ax = (int)((x0) < ((x1) < (x2) ? (x1) : (x2)) ? (x0) : ((x1) < (x2) ? (x1) : (x2))); int ay = (int)((y0) < ((y1) < (y2) ? (y1) : (y2)) ? (y0) : ((y1) < (y2) ? (y1) : (y2))); int by = (int)((y0) < ((y1) < (y2) ? (y2) : (y1)) ? ((y1) < (y2) ? (y2) : (y1)) : (y0)); if ((((y) > (ay)) && ((y) < (by))) && ((x) > (ax))) { float *q0 = stackalloc float[2]; float *q1 = stackalloc float[2]; float *q2 = stackalloc float[2]; float *hits = stackalloc float[4]; q0[0] = ((float)(x0)); q0[1] = ((float)(y0)); q1[0] = ((float)(x1)); q1[1] = ((float)(y1)); q2[0] = ((float)(x2)); q2[1] = ((float)(y2)); if (((equal(q0, q1)) != 0) || ((equal(q1, q2)) != 0)) { x0 = ((int)(verts[i - 1].x)); y0 = ((int)(verts[i - 1].y)); x1 = ((int)(verts[i].x)); y1 = ((int)(verts[i].y)); if ((((y) > ((y0) < (y1) ? (y0) : (y1))) && ((y) < ((y0) < (y1) ? (y1) : (y0)))) && ((x) > ((x0) < (x1) ? (x0) : (x1)))) { float x_inter = (float)((y - y0) / (y1 - y0) * (x1 - x0) + x0); if ((x_inter) < (x)) { winding += (int)(((y0) < (y1)) ? 1 : -1); } } } else { int num_hits = (int)(stbtt__ray_intersect_bezier(orig, ray, q0, q1, q2, hits)); if ((num_hits) >= (1)) { if ((hits[0]) < (0)) { winding += (int)((hits[1]) < (0) ? -1 : 1); } } if ((num_hits) >= (2)) { if ((hits[2]) < (0)) { winding += (int)((hits[3]) < (0) ? -1 : 1); } } } } } } return((int)(winding)); }
public static int stbtt__ray_intersect_bezier(float *orig, float *ray, float *q0, float *q1, float *q2, float *hits) { float q0perp = (float)(q0[1] * ray[0] - q0[0] * ray[1]); float q1perp = (float)(q1[1] * ray[0] - q1[0] * ray[1]); float q2perp = (float)(q2[1] * ray[0] - q2[0] * ray[1]); float roperp = (float)(orig[1] * ray[0] - orig[0] * ray[1]); float a = (float)(q0perp - 2 * q1perp + q2perp); float b = (float)(q1perp - q0perp); float c = (float)(q0perp - roperp); float s0 = (float)(0); float s1 = (float)(0); int num_s = (int)(0); if (a != 0.0) { float discr = (float)(b * b - a * c); if ((discr) > (0.0)) { float rcpna = (float)(-1 / a); float d = (float)(CRuntime.sqrt((double)(discr))); s0 = (float)((b + d) * rcpna); s1 = (float)((b - d) * rcpna); if (((s0) >= (0.0)) && (s0 <= 1.0)) { num_s = (int)(1); } if ((((d) > (0.0)) && ((s1) >= (0.0))) && (s1 <= 1.0)) { if ((num_s) == (0)) { s0 = (float)(s1); } ++num_s; } } } else { s0 = (float)(c / (-2 * b)); if (((s0) >= (0.0)) && (s0 <= 1.0)) { num_s = (int)(1); } } if ((num_s) == (0)) { return((int)(0)); } else { float rcp_len2 = (float)(1 / (ray[0] * ray[0] + ray[1] * ray[1])); float rayn_x = (float)(ray[0] * rcp_len2); float rayn_y = (float)(ray[1] * rcp_len2); float q0d = (float)(q0[0] * rayn_x + q0[1] * rayn_y); float q1d = (float)(q1[0] * rayn_x + q1[1] * rayn_y); float q2d = (float)(q2[0] * rayn_x + q2[1] * rayn_y); float rod = (float)(orig[0] * rayn_x + orig[1] * rayn_y); float q10d = (float)(q1d - q0d); float q20d = (float)(q2d - q0d); float q0rd = (float)(q0d - rod); hits[0] = (float)(q0rd + s0 * (2.0f - 2.0f * s0) * q10d + s0 * s0 * q20d); hits[1] = (float)(a * s0 + b); if ((num_s) > (1)) { hits[2] = (float)(q0rd + s1 * (2.0f - 2.0f * s1) * q10d + s1 * s1 * q20d); hits[3] = (float)(a * s1 + b); return((int)(2)); } else { return((int)(1)); } } }
public static void stbtt__v_prefilter(byte *pixels, int w, int h, int stride_in_bytes, uint kernel_width) { byte *buffer = stackalloc byte[8]; int safe_h = (int)(h - kernel_width); int j = 0; CRuntime.memset(buffer, (int)(0), (ulong)(8)); for (j = (int)(0); (j) < (w); ++j) { int i = 0; uint total = 0; CRuntime.memset(buffer, (int)(0), (ulong)(kernel_width)); total = (uint)(0); switch (kernel_width) { case 2: for (i = (int)(0); i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = (byte)(pixels[i * stride_in_bytes]); pixels[i * stride_in_bytes] = ((byte)(total / 2)); } break; case 3: for (i = (int)(0); i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = (byte)(pixels[i * stride_in_bytes]); pixels[i * stride_in_bytes] = ((byte)(total / 3)); } break; case 4: for (i = (int)(0); i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = (byte)(pixels[i * stride_in_bytes]); pixels[i * stride_in_bytes] = ((byte)(total / 4)); } break; case 5: for (i = (int)(0); i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = (byte)(pixels[i * stride_in_bytes]); pixels[i * stride_in_bytes] = ((byte)(total / 5)); } break; default: for (i = (int)(0); i <= safe_h; ++i) { total += (uint)(pixels[i * stride_in_bytes] - buffer[i & (8 - 1)]); buffer[(i + kernel_width) & (8 - 1)] = (byte)(pixels[i * stride_in_bytes]); pixels[i * stride_in_bytes] = ((byte)(total / kernel_width)); } break; } for (; (i) < (h); ++i) { total -= (uint)(buffer[i & (8 - 1)]); pixels[i * stride_in_bytes] = ((byte)(total / kernel_width)); } pixels += 1; } }
public static stbtt__point *stbtt_FlattenCurves(stbtt_vertex *vertices, int num_verts, float objspace_flatness, int **contour_lengths, int *num_contours, void *userdata) { stbtt__point *points = null; var num_points = 0; var objspace_flatness_squared = objspace_flatness * objspace_flatness; var i = 0; var n = 0; var start = 0; var pass = 0; for (i = 0; i < num_verts; ++i) { if (vertices[i].type == STBTT_vmove) { ++n; } } *num_contours = n; if (n == 0) { return(null); } *contour_lengths = (int *)CRuntime.malloc((ulong)(sizeof(int) * n)); if (*contour_lengths == null) { *num_contours = 0; return(null); } for (pass = 0; pass < 2; ++pass) { float x = 0; float y = 0; if (pass == 1) { points = (stbtt__point *)CRuntime.malloc((ulong)(num_points * sizeof(stbtt__point))); if (points == null) { goto error; } } num_points = 0; n = -1; for (i = 0; i < num_verts; ++i) { switch (vertices[i].type) { case STBTT_vmove: if (n >= 0) { (*contour_lengths)[n] = num_points - start; } ++n; start = num_points; x = vertices[i].x; y = vertices[i].y; stbtt__add_point(points, num_points++, x, y); break; case STBTT_vline: x = vertices[i].x; y = vertices[i].y; stbtt__add_point(points, num_points++, x, y); break; case STBTT_vcurve: stbtt__tesselate_curve(points, &num_points, x, y, vertices[i].cx, vertices[i].cy, vertices[i].x, vertices[i].y, objspace_flatness_squared, 0); x = vertices[i].x; y = vertices[i].y; break; case STBTT_vcubic: stbtt__tesselate_cubic(points, &num_points, x, y, vertices[i].cx, vertices[i].cy, vertices[i].cx1, vertices[i].cy1, vertices[i].x, vertices[i].y, objspace_flatness_squared, 0); x = vertices[i].x; y = vertices[i].y; break; } } (*contour_lengths)[n] = num_points - start; } return(points); error :; CRuntime.free(points); CRuntime.free(*contour_lengths); *contour_lengths = null; *num_contours = 0; return(null); }
public static void stbtt_FreeSDF(byte *bitmap, void *userdata) { CRuntime.free(bitmap); }
public static void stbtt__tesselate_cubic(stbtt__point *points, int *num_points, float x0, float y0, float x1, float y1, float x2, float y2, float x3, float y3, float objspace_flatness_squared, int n) { float dx0 = (float)(x1 - x0); float dy0 = (float)(y1 - y0); float dx1 = (float)(x2 - x1); float dy1 = (float)(y2 - y1); float dx2 = (float)(x3 - x2); float dy2 = (float)(y3 - y2); float dx = (float)(x3 - x0); float dy = (float)(y3 - y0); float longlen = (float)(CRuntime.sqrt((double)(dx0 * dx0 + dy0 * dy0)) + CRuntime.sqrt((double)(dx1 * dx1 + dy1 * dy1)) + CRuntime.sqrt((double)(dx2 * dx2 + dy2 * dy2))); float shortlen = (float)(CRuntime.sqrt((double)(dx * dx + dy * dy))); float flatness_squared = (float)(longlen * longlen - shortlen * shortlen); if ((n) > (16)) { return; } if ((flatness_squared) > (objspace_flatness_squared)) { float x01 = (float)((x0 + x1) / 2); float y01 = (float)((y0 + y1) / 2); float x12 = (float)((x1 + x2) / 2); float y12 = (float)((y1 + y2) / 2); float x23 = (float)((x2 + x3) / 2); float y23 = (float)((y2 + y3) / 2); float xa = (float)((x01 + x12) / 2); float ya = (float)((y01 + y12) / 2); float xb = (float)((x12 + x23) / 2); float yb = (float)((y12 + y23) / 2); float mx = (float)((xa + xb) / 2); float my = (float)((ya + yb) / 2); stbtt__tesselate_cubic(points, num_points, (float)(x0), (float)(y0), (float)(x01), (float)(y01), (float)(xa), (float)(ya), (float)(mx), (float)(my), (float)(objspace_flatness_squared), (int)(n + 1)); stbtt__tesselate_cubic(points, num_points, (float)(mx), (float)(my), (float)(xb), (float)(yb), (float)(x23), (float)(y23), (float)(x3), (float)(y3), (float)(objspace_flatness_squared), (int)(n + 1)); } else { stbtt__add_point(points, (int)(*num_points), (float)(x3), (float)(y3)); *num_points = (int)(*num_points + 1); } }