Пример #1
0
        public void RenderCharacter(byte *ptr, char c, FontPack font, FontColor foreground, FontColor background)
        {
            //Make sure we have this
            if (!font.font.ContainsKey(c))
            {
                return;
            }

            //Get lines
            float[] data = font.font[c];

            //Copy
            for (int y = 0; y < font.height; y++)
            {
                //Get pointer and offset
                byte *line   = ptr + (y * format.BytesPerPixel * imageWidth);
                int   offset = font.width * y;

                //Mix
                for (int x = 0; x < font.width; x++)
                {
                    SetMixColor(line, data[offset + x], foreground, background);
                    line += format.BytesPerPixel;
                }
            }
        }
Пример #2
0
        public static FontPack FromStream(Stream s)
        {
            //Load header
            byte[] header = new byte[Math.Max(HEADER_SIZE, CHAR_HEADER_SIZE)];
            s.Read(header, 0, HEADER_SIZE);

            //Check magic
            if (header[0] != 'S' || header[1] != 'D' || header[2] != 'R' || header[3] != 'F')
            {
                throw new Exception("Invalid font file");
            }

            //Read header parts
            byte version = header[4];
            byte count   = header[5];
            byte width   = header[6];
            byte height  = header[7];

            //Create
            FontPack pack = new FontPack(width, height);

            //Load all fonts
            for (int i = 0; i < count; i++)
            {
                //Load font header
                s.Read(header, 0, CHAR_HEADER_SIZE);
                byte charCode  = header[0];
                byte charFlags = header[1];

                //Read font data
                byte[] buffer = new byte[width * height];
                s.Read(buffer, 0, buffer.Length);

                //Convert font data
                float[] converted = new float[width * height];
                for (int p = 0; p < width * height; p++)
                {
                    converted[p] = (float)buffer[p] / byte.MaxValue;
                }
                pack.font.Add((char)charCode, converted);
            }

            return(pack);
        }
Пример #3
0
        public FontPack MakeScaledPack(float hScale, float vScale)
        {
            //Make pack
            FontPack pack = new FontPack((byte)(width * hScale), (byte)(height * vScale));

            //Convert characters
            foreach (var c in font)
            {
                float[] data = new float[pack.height * pack.width];
                for (int y = 0; y < pack.height; y++)
                {
                    for (int x = 0; x < pack.width; x++)
                    {
                        //First, get data points to use on both axis
                        float yRatio       = GetInterpScale(y, vScale, out int srcYa, out int srcYb);
                        float xRatio       = GetInterpScale(x, hScale, out int srcXa, out int srcXb);
                        float yRatioInvert = 1 - yRatio;
                        float xRatioInvert = 1 - xRatio;

                        //Constrain
                        if (srcYa >= height)
                        {
                            srcYa = height - 1;
                        }
                        if (srcYb >= height)
                        {
                            srcYb = height - 1;
                        }

                        //Apply on the X axis
                        float p1 = (c.Value[srcXa + (srcYa * width)] * xRatioInvert) + (c.Value[srcXb + (srcYa * width)] * xRatio);
                        float p2 = (c.Value[srcXa + (srcYb * width)] * xRatioInvert) + (c.Value[srcXb + (srcYb * width)] * xRatio);

                        //Now, apply on the X axis between those two points
                        data[x + (y * pack.width)] = (p1 * yRatioInvert) + (p2 * yRatio);
                    }
                }
                pack.font.Add(c.Key, data);
            }

            return(pack);
        }
Пример #4
0
        public bool RenderRawBox(byte *ptr, char[][] lines, FontPack font, FontAlignHorizontal horizTextAlign, FontAlignVertical vertTextAlign, int boundsWidth, int boundsHeight, FontColor foreground, FontColor background)
        {
            //Fill box with background
            for (int y = 0; y < boundsHeight; y++)
            {
                byte *fillLine = ptr + (format.BytesPerPixel * y * imageWidth);
                for (int x = 0; x < boundsWidth; x++)
                {
                    format.WritePixel(fillLine, background.r, background.g, background.b);
                    fillLine += format.BytesPerPixel;
                }
            }

            //Determine Y offset
            int offsetY;

            switch (vertTextAlign)
            {
            case FontAlignVertical.Top: offsetY = 0; break;

            case FontAlignVertical.Bottom: offsetY = boundsHeight - (lines.Length * font.height); break;

            case FontAlignVertical.Center: offsetY = (boundsHeight - (lines.Length * font.height)) / 2; break;

            default: throw new Exception("Unknown alignment.");
            }

            //Draw
            bool  fitAll = true;
            byte *line   = ptr + (format.BytesPerPixel * offsetY * imageWidth);

            for (int ln = 0; ln < lines.Length; ln++)
            {
                //Calculate X offset
                int offsetX;
                switch (horizTextAlign)
                {
                case FontAlignHorizontal.Left: offsetX = 0; break;

                case FontAlignHorizontal.Right: offsetX = boundsWidth - (lines[ln].Length * font.width); break;

                case FontAlignHorizontal.Center: offsetX = (boundsWidth - (lines[ln].Length * font.width)) / 2; break;

                default: throw new Exception("Unknown alignment.");
                }

                //Write
                byte *lineDraw = line + (offsetX * format.BytesPerPixel);
                byte *maxDraw  = line + ((boundsWidth - font.width) * format.BytesPerPixel);
                for (int i = 0; i < lines[ln].Length && lineDraw <= maxDraw; i++)
                {
                    RenderCharacter(lineDraw, lines[ln][i], font, foreground, background);
                    lineDraw += format.BytesPerPixel * font.width;
                }

                //Update flag if we have too much
                fitAll = fitAll && (lineDraw <= maxDraw);

                //Offset
                line += format.BytesPerPixel * imageWidth * font.height;
            }

            return(fitAll);
        }