Esempio n. 1
0
        public static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings,
                                            float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert,
                                            void *userdata)
        {
            var          y_scale_inv = invert != 0 ? -scale_y : scale_y;
            stbtt__edge *e;
            var          n          = 0;
            var          i          = 0;
            var          j          = 0;
            var          k          = 0;
            var          m          = 0;
            var          vsubsample = 1;

            n = 0;
            for (i = 0; i < windings; ++i)
            {
                n += wcount[i];
            }

            e = (stbtt__edge *)CRuntime.malloc((ulong)(sizeof(stbtt__edge) * (n + 1)));
            if (e == null)
            {
                return;
            }
            n = 0;
            m = 0;
            for (i = 0; i < windings; ++i)
            {
                var p = pts + m;
                m += wcount[i];
                j  = wcount[i] - 1;
                for (k = 0; k < wcount[i]; j = k++)
                {
                    var a = k;
                    var b = j;
                    if (p[j].y == p[k].y)
                    {
                        continue;
                    }
                    e[n].invert = 0;
                    if (invert != 0 && p[j].y > p[k].y ||
                        invert == 0 && p[j].y < p[k].y)
                    {
                        e[n].invert = 1;
                        a           = j;
                        b           = k;
                    }

                    e[n].x0 = p[a].x * scale_x + shift_x;
                    e[n].y0 = (p[a].y * y_scale_inv + shift_y) * vsubsample;
                    e[n].x1 = p[b].x * scale_x + shift_x;
                    e[n].y1 = (p[b].y * y_scale_inv + shift_y) * vsubsample;
                    ++n;
                }
            }

            stbtt__sort_edges(e, n);
            stbtt__rasterize_sorted_edges(result, e, n, vsubsample, off_x, off_y, userdata);
            CRuntime.free(e);
        }
 public static void *stbtt__hheap_alloc(stbtt__hheap *hh, ulong size, void *userdata)
 {
     if ((hh->first_free) != null)
     {
         void *p = hh->first_free;
         hh->first_free = *(void **)(p);
         return(p);
     }
     else
     {
         if ((hh->num_remaining_in_head_chunk) == (0))
         {
             int count             = (int)((size) < (32) ? 2000 : (size) < (128) ? 800 : 100);
             stbtt__hheap_chunk *c = (stbtt__hheap_chunk *)(CRuntime.malloc((ulong)((ulong)sizeof(stbtt__hheap_chunk) + size * (ulong)(count))));
             if ((c) == (null))
             {
                 return(null);
             }
             c->next  = hh->head;
             hh->head = c;
             hh->num_remaining_in_head_chunk = (int)(count);
         }
         --hh->num_remaining_in_head_chunk;
         return((sbyte *)(hh->head) + sizeof(stbtt__hheap_chunk) + size * (ulong)hh->num_remaining_in_head_chunk);
     }
 }
Esempio n. 3
0
        public static int stbtt_PackFontRanges(stbtt_pack_context spc, byte *fontdata, int font_index, stbtt_pack_range *ranges, int num_ranges)
        {
            stbtt_fontinfo info         = new stbtt_fontinfo();
            int            i            = 0;
            int            j            = 0;
            int            n            = 0;
            int            return_value = (int)(1);
            stbrp_rect *   rects;

            for (i = (int)(0); (i) < (num_ranges); ++i)
            {
                for (j = (int)(0); (j) < (ranges[i].num_chars); ++j)
                {
                    ranges[i].chardata_for_range[j].x0 = (ushort)(ranges[i].chardata_for_range[j].y0 = (ushort)(ranges[i].chardata_for_range[j].x1 = (ushort)(ranges[i].chardata_for_range[j].y1 = (ushort)(0))));
                }
            }
            n = (int)(0);
            for (i = (int)(0); (i) < (num_ranges); ++i)
            {
                n += (int)(ranges[i].num_chars);
            }
            rects = (stbrp_rect *)(CRuntime.malloc((ulong)(sizeof(stbrp_rect) * n)));
            if ((rects) == (null))
            {
                return((int)(0));
            }
            info.userdata = spc.user_allocator_context;
            stbtt_InitFont(info, fontdata, (int)(stbtt_GetFontOffsetForIndex(fontdata, (int)(font_index))));
            n = (int)(stbtt_PackFontRangesGatherRects(spc, info, ranges, (int)(num_ranges), rects));
            stbtt_PackFontRangesPackRects(spc, rects, (int)(n));
            return_value = (int)(stbtt_PackFontRangesRenderIntoRects(spc, info, ranges, (int)(num_ranges), rects));
            CRuntime.free(rects);
            return((int)(return_value));
        }
        public static void *stbtt__hheap_alloc(stbtt__hheap *hh, ulong size, void *userdata)
        {
            if (hh->first_free != null)
            {
                var p = hh->first_free;
                hh->first_free = *(void **)p;
                return(p);
            }

            if (hh->num_remaining_in_head_chunk == 0)
            {
                var count = size < 32 ? 2000 : size < 128 ? 800 : 100;
                var c     = (stbtt__hheap_chunk *)CRuntime.malloc((ulong)sizeof(stbtt__hheap_chunk) +
                                                                  size * (ulong)count);
                if (c == null)
                {
                    return(null);
                }
                c->next  = hh->head;
                hh->head = c;
                hh->num_remaining_in_head_chunk = count;
            }

            --hh->num_remaining_in_head_chunk;
            return((sbyte *)hh->head + sizeof(stbtt__hheap_chunk) + size * (ulong)hh->num_remaining_in_head_chunk);
        }
        public static void stbtt__rasterize(stbtt__bitmap *result, stbtt__point *pts, int *wcount, int windings, float scale_x, float scale_y, float shift_x, float shift_y, int off_x, int off_y, int invert, void *userdata)
        {
            float        y_scale_inv = (float)((invert) != 0 ? -scale_y : scale_y);
            stbtt__edge *e;
            int          n          = 0;
            int          i          = 0;
            int          j          = 0;
            int          k          = 0;
            int          m          = 0;
            int          vsubsample = (int)(1);

            n = (int)(0);
            for (i = (int)(0); (i) < (windings); ++i)
            {
                n += (int)(wcount[i]);
            }
            e = (stbtt__edge *)(CRuntime.malloc((ulong)(sizeof(stbtt__edge) * (n + 1))));
            if ((e) == (null))
            {
                return;
            }
            n = (int)(0);
            m = (int)(0);
            for (i = (int)(0); (i) < (windings); ++i)
            {
                stbtt__point *p = pts + m;
                m += (int)(wcount[i]);
                j  = (int)(wcount[i] - 1);
                for (k = (int)(0); (k) < (wcount[i]); j = (int)(k++))
                {
                    int a = (int)(k);
                    int b = (int)(j);
                    if ((p[j].y) == (p[k].y))
                    {
                        continue;
                    }
                    e[n].invert = (int)(0);
                    if ((((invert) != 0) && ((p[j].y) > (p[k].y))) || ((invert == 0) && ((p[j].y) < (p[k].y))))
                    {
                        e[n].invert = (int)(1);
                        a           = (int)(j);
                        b           = (int)(k);
                    }
                    e[n].x0 = (float)(p[a].x * scale_x + shift_x);
                    e[n].y0 = (float)((p[a].y * y_scale_inv + shift_y) * vsubsample);
                    e[n].x1 = (float)(p[b].x * scale_x + shift_x);
                    e[n].y1 = (float)((p[b].y * y_scale_inv + shift_y) * vsubsample);
                    ++n;
                }
            }
            stbtt__sort_edges(e, (int)(n));
            stbtt__rasterize_sorted_edges(result, e, (int)(n), (int)(vsubsample), (int)(off_x), (int)(off_y), userdata);
            CRuntime.free(e);
        }
Esempio n. 6
0
        /// <summary>
        ///     Creates and initializes a font from ttf/otf/ttc data
        /// </summary>
        /// <param name="data"></param>
        /// <param name="offset"></param>
        /// <returns>null if the data was invalid</returns>
        public static stbtt_fontinfo CreateFont(byte[] data, int offset)
        {
            var dataCopy = (byte *)CRuntime.malloc(data.Length);

            Marshal.Copy(data, 0, new IntPtr(dataCopy), data.Length);

            var info = new stbtt_fontinfo
            {
                isDataCopy = true
            };

            if (stbtt_InitFont_internal(info, dataCopy, offset) == 0)
            {
                info.Dispose();
                return(null);
            }

            return(info);
        }
        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_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);
        }
Esempio n. 9
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 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);
        }
Esempio n. 11
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. 13
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);
        }