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; int x = 0; int y = 0; int bottom_y = 0; int i = 0; stbtt_fontinfo 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) { int advance = 0; int lsb = 0; int x0 = 0; int y0 = 0; int x1 = 0; int y1 = 0; int gw = 0; int gh = 0; int 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 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 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 = 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 = off_y; e[n].y0 = (float)(off_y + result->h) + 1; while ((j) < (result->h)) { float scan_y_top = y + 0.0f; float scan_y_bottom = y + 1.0f; stbtt__active_edge **step = &active; CRuntime.Memset(scanline, 0, (ulong)(result->w * sizeof(float))); CRuntime.Memset(scanline2, 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 = 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, 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; int 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) { stbtt__active_edge *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__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, 0, (ulong)(8)); for (j = 0; (j) < (w); ++j) { int 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 stbi__zbuild_huffman(StbiZhuffman *z, byte *sizelist, int num) { var i = 0; var k = 0; var code = 0; var next_code = stackalloc int[16]; var sizes = stackalloc int[17]; CRuntime.Memset(sizes, 0, (ulong)sizeof(int)); CRuntime.Memset(z->fast, 0, (ulong)((1 << 9) * sizeof(ushort))); for (i = 0; i < num; ++i) { ++sizes[sizelist[i]]; } sizes[0] = 0; for (i = 1; i < 16; ++i) { if (sizes[i] > 1 << i) { return(stbi__err("bad sizes")); } } code = 0; for (i = 1; i < 16; ++i) { next_code[i] = code; z->firstcode[i] = (ushort)code; z->firstsymbol[i] = (ushort)k; code = code + sizes[i]; if (sizes[i] != 0) { if (code - 1 >= 1 << i) { return(stbi__err("bad codelengths")); } } z->maxcode[i] = code << (16 - i); code <<= 1; k += sizes[i]; } z->maxcode[16] = 0x10000; for (i = 0; i < num; ++i) { var s = (int)sizelist[i]; if (s != 0) { var c = next_code[s] - z->firstcode[s] + z->firstsymbol[s]; var fastv = (ushort)((s << 9) | i); z->size[c] = (byte)s; z->value[c] = (ushort)i; if (s <= 9) { var j = stbi__bit_reverse(next_code[s], s); while (j < 1 << 9) { z->fast[j] = fastv; j += 1 << s; } } ++next_code[s]; } } return(1); }
public static int stbi__compute_huffman_codes(StbiZbuf *a) { var z_codelength = new StbiZhuffman(); var lencodes = stackalloc byte[286 + 32 + 137]; var codelength_sizes = stackalloc byte[19]; var i = 0; var n = 0; var hlit = (int)(stbi__zreceive(a, 5) + 257); var hdist = (int)(stbi__zreceive(a, 5) + 1); var hclen = (int)(stbi__zreceive(a, 4) + 4); var ntot = hlit + hdist; CRuntime.Memset(codelength_sizes, 0, (ulong)(19 * sizeof(byte))); for (i = 0; i < hclen; ++i) { var s = (int)stbi__zreceive(a, 3); codelength_sizes[LengthDezigzag[i]] = (byte)s; } if (stbi__zbuild_huffman(&z_codelength, codelength_sizes, 19) == 0) { return(0); } n = 0; while (n < ntot) { var c = stbi__zhuffman_decode(a, &z_codelength); if (c < 0 || c >= 19) { return(stbi__err("bad codelengths")); } if (c < 16) { lencodes[n++] = (byte)c; } else { var fill = (byte)0; if (c == 16) { c = (int)(stbi__zreceive(a, 2) + 3); if (n == 0) { return(stbi__err("bad codelengths")); } fill = lencodes[n - 1]; } else if (c == 17) { c = (int)(stbi__zreceive(a, 3) + 3); } else { c = (int)(stbi__zreceive(a, 7) + 11); } if (ntot - n < c) { return(stbi__err("bad codelengths")); } CRuntime.Memset(lencodes + n, fill, (ulong)c); n += c; } } if (n != ntot) { return(stbi__err("bad codelengths")); } if (stbi__zbuild_huffman(&a->z_length, lencodes, hlit) == 0) { return(0); } if (stbi__zbuild_huffman(&a->z_distance, lencodes + hlit, hdist) == 0) { return(0); } return(1); }