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 *stbi__bmp_load(stbi__context s, int *x, int *y, int *comp, int req_comp, stbi__result_info *ri) { byte *_out_; uint mr = 0; uint mg = 0; uint mb = 0; uint ma = 0; uint all_a = 0; var palArray = new UnsafeArray2D <byte>(256, 4); var pal = (byte **)palArray; var psize = 0; var i = 0; var j = 0; var width = 0; var flip_vertically = 0; var pad = 0; var target = 0; var info = new stbi__bmp_data(); info.all_a = 255; if (stbi__bmp_parse_header(s, &info) == null) { return(null); } flip_vertically = (int)s.img_y > 0 ? 1 : 0; s.img_y = (uint)CRuntime.abs((int)s.img_y); if (s.img_y > 1 << 24) { return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } if (s.img_x > 1 << 24) { return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } mr = info.mr; mg = info.mg; mb = info.mb; ma = info.ma; all_a = info.all_a; if (info.hsz == 12) { if (info.bpp < 24) { psize = (info.offset - info.extra_read - 24) / 3; } } else { if (info.bpp < 16) { psize = (info.offset - info.extra_read - info.hsz) >> 2; } } if (info.bpp == 24 && ma == 0xff000000) { s.img_n = 3; } else { s.img_n = ma != 0 ? 4 : 3; } if (req_comp != 0 && req_comp >= 3) { target = req_comp; } else { target = s.img_n; } if (stbi__mad3sizes_valid(target, (int)s.img_x, (int)s.img_y, 0) == 0) { return((byte *)(ulong)(stbi__err("too large") != 0 ? 0 : 0)); } _out_ = (byte *)stbi__malloc_mad3(target, (int)s.img_x, (int)s.img_y, 0); if (_out_ == null) { return((byte *)(ulong)(stbi__err("outofmem") != 0 ? 0 : 0)); } if (info.bpp < 16) { var z = 0; if (psize == 0 || psize > 256) { CRuntime.free(_out_); return((byte *)(ulong)(stbi__err("invalid") != 0 ? 0 : 0)); } for (i = 0; i < psize; ++i) { pal[i][2] = stbi__get8(s); pal[i][1] = stbi__get8(s); pal[i][0] = stbi__get8(s); if (info.hsz != 12) { stbi__get8(s); } pal[i][3] = 255; } stbi__skip(s, info.offset - info.extra_read - info.hsz - psize * (info.hsz == 12 ? 3 : 4)); if (info.bpp == 1) { width = (int)((s.img_x + 7) >> 3); } else if (info.bpp == 4) { width = (int)((s.img_x + 1) >> 1); } else if (info.bpp == 8) { width = (int)s.img_x; } else { CRuntime.free(_out_); return((byte *)(ulong)(stbi__err("bad bpp") != 0 ? 0 : 0)); } pad = -width & 3; if (info.bpp == 1) { for (j = 0; j < (int)s.img_y; ++j) { var bit_offset = 7; int v = stbi__get8(s); for (i = 0; i < (int)s.img_x; ++i) { var color = (v >> bit_offset) & 0x1; _out_[z++] = pal[color][0]; _out_[z++] = pal[color][1]; _out_[z++] = pal[color][2]; if (target == 4) { _out_[z++] = 255; } if (i + 1 == (int)s.img_x) { break; } if (--bit_offset < 0) { bit_offset = 7; v = stbi__get8(s); } } stbi__skip(s, pad); } } else { for (j = 0; j < (int)s.img_y; ++j) { for (i = 0; i < (int)s.img_x; i += 2) { int v = stbi__get8(s); var v2 = 0; if (info.bpp == 4) { v2 = v & 15; v >>= 4; } _out_[z++] = pal[v][0]; _out_[z++] = pal[v][1]; _out_[z++] = pal[v][2]; if (target == 4) { _out_[z++] = 255; } if (i + 1 == (int)s.img_x) { break; } v = info.bpp == 8 ? stbi__get8(s) : v2; _out_[z++] = pal[v][0]; _out_[z++] = pal[v][1]; _out_[z++] = pal[v][2]; if (target == 4) { _out_[z++] = 255; } } stbi__skip(s, pad); } } } else { var rshift = 0; var gshift = 0; var bshift = 0; var ashift = 0; var rcount = 0; var gcount = 0; var bcount = 0; var acount = 0; var z = 0; var easy = 0; stbi__skip(s, info.offset - info.extra_read - info.hsz); if (info.bpp == 24) { width = (int)(3 * s.img_x); } else if (info.bpp == 16) { width = (int)(2 * s.img_x); } else { width = 0; } pad = -width & 3; if (info.bpp == 24) { easy = 1; } else if (info.bpp == 32) { if (mb == 0xff && mg == 0xff00 && mr == 0x00ff0000 && ma == 0xff000000) { easy = 2; } } if (easy == 0) { if (mr == 0 || mg == 0 || mb == 0) { CRuntime.free(_out_); return((byte *)(ulong)(stbi__err("bad masks") != 0 ? 0 : 0)); } rshift = stbi__high_bit(mr) - 7; rcount = stbi__bitcount(mr); gshift = stbi__high_bit(mg) - 7; gcount = stbi__bitcount(mg); bshift = stbi__high_bit(mb) - 7; bcount = stbi__bitcount(mb); ashift = stbi__high_bit(ma) - 7; acount = stbi__bitcount(ma); if (rcount > 8 || gcount > 8 || bcount > 8 || acount > 8) { CRuntime.free(_out_); return((byte *)(ulong)(stbi__err("bad masks") != 0 ? 0 : 0)); } } for (j = 0; j < (int)s.img_y; ++j) { if (easy != 0) { for (i = 0; i < (int)s.img_x; ++i) { byte a = 0; _out_[z + 2] = stbi__get8(s); _out_[z + 1] = stbi__get8(s); _out_[z + 0] = stbi__get8(s); z += 3; a = (byte)(easy == 2 ? stbi__get8(s) : 255); all_a |= a; if (target == 4) { _out_[z++] = a; } } } else { var bpp = info.bpp; for (i = 0; i < (int)s.img_x; ++i) { var v = bpp == 16 ? (uint)stbi__get16le(s) : stbi__get32le(s); uint a = 0; _out_[z++] = (byte)(stbi__shiftsigned(v & mr, rshift, rcount) & 255); _out_[z++] = (byte)(stbi__shiftsigned(v & mg, gshift, gcount) & 255); _out_[z++] = (byte)(stbi__shiftsigned(v & mb, bshift, bcount) & 255); a = (uint)(ma != 0 ? stbi__shiftsigned(v & ma, ashift, acount) : 255); all_a |= a; if (target == 4) { _out_[z++] = (byte)(a & 255); } } } stbi__skip(s, pad); } } if (target == 4 && all_a == 0) { for (i = (int)(4 * s.img_x * s.img_y - 1); i >= 0; i -= 4) { _out_[i] = 255; } } if (flip_vertically != 0) { byte t = 0; for (j = 0; j < (int)s.img_y >> 1; ++j) { var p1 = _out_ + j * s.img_x * target; var p2 = _out_ + (s.img_y - 1 - j) * s.img_x * target; for (i = 0; i < (int)s.img_x * target; ++i) { t = p1[i]; p1[i] = p2[i]; p2[i] = t; } } } if (req_comp != 0 && req_comp != target) { _out_ = stbi__convert_format(_out_, target, req_comp, s.img_x, s.img_y); if (_out_ == null) { return(_out_); } } *x = (int)s.img_x; *y = (int)s.img_y; if (comp != null) { *comp = s.img_n; } return(_out_); }