Пример #1
0
        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);
        }
Пример #2
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));
        }
Пример #3
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)
        {
            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);
            }
        }
Пример #4
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, 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;
            }
        }
Пример #5
0
        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);
        }
Пример #6
0
        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);
        }