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);
        }
Esempio n. 3
0
        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);
        }
Esempio n. 8
0
        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);
            }
        }
Esempio n. 10
0
        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);
        }
Esempio n. 11
0
 public static void stbtt_PackEnd(stbtt_pack_context spc)
 {
     CRuntime.free(spc.nodes);
     CRuntime.free(spc.pack_info);
 }
Esempio n. 12
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));
        }
Esempio n. 13
0
        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));
                }
            }
        }
Esempio n. 14
0
        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);
 }
Esempio n. 17
0
        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);
            }
        }