Пример #1
0
        public BitmapFontData(string fontFile, bool flip)
            : this()
        {
            FontFile  = fontFile;
            IsFlipped = flip;

            using (TextReader reader = new StreamReader(FontFile)) {
                reader.ReadLine(); // Info

                string line = reader.ReadLine();
                if (line == null)
                {
                    throw new IOException("Invalid font file: " + fontFile);
                }

                string[] common = line.Split(SpaceToken, 4);
                if (common.Length < 4)
                {
                    throw new IOException("Invalid font file: " + fontFile);
                }

                if (!common[1].StartsWith("lineHeight="))
                {
                    throw new IOException("Invalid font file: " + fontFile);
                }
                LineHeight = int.Parse(common[1].Substring(11));

                if (!common[2].StartsWith("base="))
                {
                    throw new IOException("Invalid font file: " + fontFile);
                }
                int baseLine = int.Parse(common[2].Substring(5));

                line = reader.ReadLine();
                if (line == null)
                {
                    throw new IOException("Invalid font file: " + fontFile);
                }

                string[] pageLine = line.Split(SpaceToken, 4);
                if (pageLine.Length < 3)
                {
                    throw new IOException("Invalid font file: " + fontFile);
                }

                if (!pageLine[2].StartsWith("file="))
                {
                    throw new IOException("Invalid font file: " + fontFile);
                }
                string imageFilename = null;
                if (pageLine[2].EndsWith("\""))
                {
                    imageFilename = pageLine[2].Substring(6, pageLine[2].Length - 6 - 1);
                }
                else
                {
                    imageFilename = pageLine[2].Substring(5, pageLine[2].Length - 5);
                }

                ImagePath = Path.Combine(Path.GetDirectoryName(fontFile), imageFilename);
                Descent   = 0;

                while (true)
                {
                    line = reader.ReadLine();
                    if (line == null)
                    {
                        break;
                    }
                    if (line.StartsWith("kernings "))
                    {
                        break;
                    }
                    if (!line.StartsWith("char "))
                    {
                        continue;
                    }

                    Glyph glyph = new Glyph();

                    string[] tokens = line.Split(SpaceEqToken, StringSplitOptions.RemoveEmptyEntries);
                    int      ch     = int.Parse(tokens[2]);
                    if (ch <= char.MaxValue)
                    {
                        this[(char)ch] = glyph;
                    }
                    else
                    {
                        continue;
                    }

                    glyph.SrcX     = int.Parse(tokens[4]);
                    glyph.SrcY     = int.Parse(tokens[6]);
                    glyph.Width    = int.Parse(tokens[8]);
                    glyph.Height   = int.Parse(tokens[10]);
                    glyph.XOffset  = int.Parse(tokens[12]);
                    glyph.YOffset  = flip ? int.Parse(tokens[14]) : -(glyph.Height + int.Parse(tokens[14]));
                    glyph.XAdvance = int.Parse(tokens[16]);

                    if (glyph.Width > 0 && glyph.Height > 0)
                    {
                        Descent = Math.Min(baseLine + glyph.YOffset, Descent);
                    }
                }

                while (true)
                {
                    line = reader.ReadLine();
                    if (line == null)
                    {
                        break;
                    }
                    if (!line.StartsWith("kerning "))
                    {
                        break;
                    }

                    string[] tokens = line.Split(SpaceEqToken, StringSplitOptions.RemoveEmptyEntries);

                    int first  = int.Parse(tokens[2]);
                    int second = int.Parse(tokens[4]);

                    if (first < 0 || first > char.MaxValue || second < 0 || second > char.MaxValue)
                    {
                        continue;
                    }
                    Glyph g = this[(char)first];

                    int amount = int.Parse(tokens[6]);
                    g.SetKerning((char)second, amount);
                }

                Glyph spaceGlyph = this[' '];
                if (spaceGlyph == null)
                {
                    Glyph xAdvanceGlyph = this['l'];
                    if (xAdvanceGlyph == null)
                    {
                        xAdvanceGlyph = FirstGlyph;
                    }

                    this[' '] = spaceGlyph = new Glyph()
                    {
                        XAdvance = xAdvanceGlyph.XAdvance,
                    };
                }
                SpaceWidth = (spaceGlyph != null) ? spaceGlyph.XAdvance + spaceGlyph.Width : 1;

                Glyph xGlyph = null;
                for (int i = 0; i < BitmapFont.XChars.Length; i++)
                {
                    xGlyph = this[BitmapFont.XChars[i]];
                    if (xGlyph != null)
                    {
                        break;
                    }
                }
                if (xGlyph == null)
                {
                    xGlyph = FirstGlyph;
                }
                XHeight = xGlyph.Height;

                Glyph capGlyph = null;
                for (int i = 0; i < BitmapFont.CapChars.Length; i++)
                {
                    capGlyph = this[BitmapFont.CapChars[i]];
                    if (capGlyph != null)
                    {
                        break;
                    }
                }

                if (capGlyph == null)
                {
                    foreach (Glyph[] page in Glyphs)
                    {
                        if (page == null)
                        {
                            continue;
                        }

                        foreach (Glyph glyph in page)
                        {
                            if (glyph == null || glyph.Height == 0 || glyph.Width == 0)
                            {
                                continue;
                            }
                            CapHeight = Math.Min(CapHeight, glyph.Height);
                        }
                    }
                }
                else
                {
                    CapHeight = capGlyph.Height;
                }

                Ascent = baseLine - CapHeight;
                Down   = -LineHeight;

                if (flip)
                {
                    Ascent = -Ascent;
                    Down   = -Down;
                }
            }
        }
Пример #2
0
        public void ComputeGlyphAdvancesAndPositions(CharSequence str, IList <float> glyphAdvances, IList <float> glyphPositions)
        {
            glyphAdvances.Clear();
            glyphPositions.Clear();

            int            index     = 0;
            int            end       = str.Length;
            float          width     = 0;
            Glyph          lastGlyph = null;
            BitmapFontData data      = Data;

            if (data.ScaleX == 1)
            {
                for (; index < end; index++)
                {
                    char  ch = str[index];
                    Glyph g  = data[ch];

                    if (g != null)
                    {
                        if (lastGlyph != null)
                        {
                            width += lastGlyph.GetKerning(ch);
                        }

                        lastGlyph = g;
                        glyphAdvances.Add(g.XAdvance);
                        glyphPositions.Add(width);
                        width += g.XAdvance;
                    }
                }

                glyphAdvances.Add(0);
                glyphPositions.Add(width);
            }
            else
            {
                float scaleX = data.ScaleX;
                for (; index < end; index++)
                {
                    char  ch = str[index];
                    Glyph g  = data[ch];

                    if (g != null)
                    {
                        if (lastGlyph != null)
                        {
                            width += lastGlyph.GetKerning(ch) * scaleX;
                        }

                        lastGlyph = g;
                        float xAdvance = g.XAdvance * scaleX;
                        glyphAdvances.Add(xAdvance);
                        glyphPositions.Add(width);
                        width += xAdvance;
                    }
                }

                glyphAdvances.Add(0);
                glyphPositions.Add(width);
            }
        }