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);
        }
Esempio n. 2
0
        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));
        }