Ejemplo n.º 1
0
        /// <summary>
        /// Function to read the textures for the font.
        /// </summary>
        /// <param name="filePath">The path to the font file.</param>
        /// <param name="fontInfo">The information about the font.</param>
        /// <returns>A list of textures.</returns>
        private IReadOnlyList <GorgonTexture2D> ReadTextures(string filePath, BmFontInfo fontInfo)
        {
            var textures  = new GorgonTexture2D[fontInfo.FontTextures.Length];
            var directory = new DirectoryInfo(Path.GetDirectoryName(filePath).FormatDirectory(Path.DirectorySeparatorChar));

            Debug.Assert(directory.Exists, "Font directory should exist, but does not.");

            for (int i = 0; i < fontInfo.FontTextures.Length; ++i)
            {
                var fileInfo = new FileInfo(directory.FullName.FormatDirectory(Path.DirectorySeparatorChar) + fontInfo.FontTextures[i].FormatFileName());

                if (!fileInfo.Exists)
                {
                    throw new FileNotFoundException(string.Format(Resources.GORGFX_ERR_FONT_TEXTURE_FILE_NOT_FOUND, fileInfo.FullName));
                }

                IGorgonImageCodec codec = GetImageCodec(fileInfo.Extension);

                using (IGorgonImage image = codec.LoadFromFile(fileInfo.FullName))
                {
                    image.ToTexture2D(Factory.Graphics,
                                      new GorgonTexture2DLoadOptions
                    {
                        Name = $"BmFont_Texture_{Guid.NewGuid():N}"
                    });
                }
            }

            return(textures);
        }
Ejemplo n.º 2
0
        /// <summary>
        /// Function to read the texture information from the font.
        /// </summary>
        /// <param name="fontInfo">The font information to update.</param>
        /// <param name="reader">The reader that is reading the file data.</param>
        private static void ParseTextures(BmFontInfo fontInfo, StreamReader reader)
        {
            for (int i = 0; i < fontInfo.FontTextures.Length; ++i)
            {
                string line = reader.ReadLine();

                if (string.IsNullOrWhiteSpace(line))
                {
                    throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
                }

                string[] lineItems = line.Split(new[]
                {
                    ' '
                },
                                                StringSplitOptions.RemoveEmptyEntries);
                Dictionary <string, string> keyValues = GetLineKeyValuePairs(lineItems);

                if (!keyValues.ContainsKey(PageLine))
                {
                    throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
                }

                int    id       = Convert.ToInt32(keyValues[PageIdTag]);
                string fileName = keyValues[PageFileTag].Trim('\"');

                fontInfo.FontTextures[id] = fileName;
            }
        }
Ejemplo n.º 3
0
        /// <summary>
        /// Function to parse the common info line in the font file.
        /// </summary>
        /// <param name="fontInfo">The font information structure to populate.</param>
        /// <param name="line">The line containing the common info.</param>
        private static void ParseCommonLine(BmFontInfo fontInfo, string line)
        {
            if (string.IsNullOrWhiteSpace(line))
            {
                throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
            }

            string[] infoItems = line.Split(new[]
            {
                ' '
            },
                                            StringSplitOptions.RemoveEmptyEntries);

            Dictionary <string, string> keyValues = GetLineKeyValuePairs(infoItems);

            // Check for the "info" tag.
            if (!keyValues.ContainsKey(CommonLine))
            {
                throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
            }

            // Get supported tags.
            string lineHeight    = keyValues[LineHeightTag];
            string textureWidth  = keyValues[ScaleWTag];
            string textureHeight = keyValues[ScaleHTag];
            string textureCount  = keyValues[PagesTag];

            fontInfo.LineHeight    = Convert.ToSingle(lineHeight);
            fontInfo.TextureHeight = Convert.ToInt32(textureHeight);
            fontInfo.TextureWidth  = Convert.ToInt32(textureWidth);
            fontInfo.FontTextures  = new string[Convert.ToInt32(textureCount)];
        }
Ejemplo n.º 4
0
        /// <summary>
        /// Function to parse the info line in the file.
        /// </summary>
        /// <param name="line">The line containing the font info.</param>
        /// <returns>A new <seealso cref="BmFontInfo"/> containing some of the font information.</returns>
        private static BmFontInfo ParseInfoLine(string line)
        {
            if (string.IsNullOrWhiteSpace(line))
            {
                throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
            }

            string[] infoItems = line.Split(new []
            {
                ' '
            },
                                            StringSplitOptions.RemoveEmptyEntries);

            Dictionary <string, string> keyValues = GetLineKeyValuePairs(infoItems);

            // Check for the "info" tag.
            if (!keyValues.ContainsKey(InfoLine))
            {
                throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
            }

            // Get supported tags.
            string    face    = keyValues[FaceTag];
            string    size    = keyValues[SizeTag];
            string    bold    = keyValues[BoldTag];
            string    italic  = keyValues[ItalicTag];
            string    aa      = keyValues[AaTag];
            string    spacing = keyValues[SpacingTag];
            FontStyle style   = FontStyle.Normal;

            if ((string.Equals(bold, "1", StringComparison.OrdinalIgnoreCase)) &&
                (string.Equals(italic, "1", StringComparison.OrdinalIgnoreCase)))
            {
                style = FontStyle.BoldItalics;
            }
            else if (string.Equals(italic, "1", StringComparison.OrdinalIgnoreCase))
            {
                style = FontStyle.Italics;
            }
            else if (string.Equals(bold, "1", StringComparison.OrdinalIgnoreCase))
            {
                style = FontStyle.Bold;
            }

            // Create with required settings.
            var result = new BmFontInfo(face, Convert.ToSingle(size))
            {
                PackingSpacing   = spacing.Length > 0 ? Convert.ToInt32(spacing[0]) : 1,
                FontStyle        = style,
                AntiAliasingMode =
                    (aa.Length > 0 && string.Equals(aa, "1", StringComparison.OrdinalIgnoreCase)) ? FontAntiAliasMode.AntiAlias : FontAntiAliasMode.None,
                DefaultCharacter = ' '
            };

            return(result);
        }
Ejemplo n.º 5
0
        /// <summary>
        /// Function to read the meta data for font data within a stream.
        /// </summary>
        /// <param name="stream">The stream containing the metadata to read.</param>
        /// <returns>
        /// The font meta data as a <see cref="IGorgonFontInfo"/> value.
        /// </returns>
        protected override IGorgonFontInfo OnGetMetaData(Stream stream)
        {
            using (var reader = new StreamReader(stream, Encoding.ASCII, true, 80000, true))
            {
                BmFontInfo result = ParseInfoLine(reader.ReadLine());
                ParseCommonLine(result, reader.ReadLine());
                ParseTextures(result, reader);
                ParseCharacters(result, reader);
                ParseKerning(result, reader);

                return(result);
            }
        }
Ejemplo n.º 6
0
        /// <summary>
        /// Function to build builds from the font information.
        /// </summary>
        /// <param name="textures">The list of textures loaded.</param>
        /// <param name="fontInfo">The font information to retrieve glyph data from.</param>
        /// <returns>A new list of glyphs.</returns>
        private IReadOnlyList <GorgonGlyph> GetGlyphs(IReadOnlyList <GorgonTexture2D> textures, BmFontInfo fontInfo)
        {
            var glyphs = new List <GorgonGlyph>();

            foreach (char character in fontInfo.Characters)
            {
                int advance = fontInfo.CharacterAdvances[character];

                // Build a glyph that is not linked to a texture if it's whitespace.
                if (char.IsWhiteSpace(character))
                {
                    glyphs.Add(CreateGlyph(character, advance));
                    continue;
                }

                int             textureIndex = fontInfo.GlyphTextureIndices[character];
                GorgonTexture2D texture      = textures[textureIndex];

                DX.Rectangle glyphRectangle = fontInfo.GlyphRects[character];
                DX.Point     offset         = fontInfo.GlyphOffsets[character];

                GorgonGlyph glyph = CreateGlyph(character, advance);
                glyph.Offset = offset;
                glyph.UpdateTexture(texture, glyphRectangle, DX.Rectangle.Empty, 0);

                glyphs.Add(glyph);
            }

            return(glyphs);
        }
Ejemplo n.º 7
0
        /// <summary>
        /// Function to read in the kerning information.
        /// </summary>
        /// <param name="fontInfo">The font information to update.</param>
        /// <param name="reader">The reader that is reading the file data.</param>
        private static void ParseKerning(BmFontInfo fontInfo, StreamReader reader)
        {
            if (reader.EndOfStream)
            {
                fontInfo.UseKerningPairs = false;
                return;
            }

            string countLine = reader.ReadLine();

            if (string.IsNullOrWhiteSpace(countLine))
            {
                fontInfo.UseKerningPairs = false;
                return;
            }

            string[] lineItems = countLine.Split(new[]
            {
                ' '
            },
                                                 StringSplitOptions.RemoveEmptyEntries);

            Dictionary <string, string> keyValues = GetLineKeyValuePairs(lineItems);

            if (!keyValues.ContainsKey(KerningCountLine))
            {
                throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
            }

            int count = Convert.ToInt32(keyValues[CountTag]);

            if (count < 1)
            {
                fontInfo.UseKerningPairs = false;
                return;
            }

            fontInfo.UseKerningPairs = true;

            // Iterate through the characters so we have enough info to build out glyph data.
            for (int i = 0; i < count; ++i)
            {
                string line = reader.ReadLine();

                if (string.IsNullOrWhiteSpace(line))
                {
                    throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
                }

                lineItems = line.Split(new[]
                {
                    ' '
                },
                                       StringSplitOptions.RemoveEmptyEntries);

                keyValues = GetLineKeyValuePairs(lineItems);

                if (!keyValues.ContainsKey(KerningLine))
                {
                    throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
                }

                var pair = new GorgonKerningPair(Convert.ToChar(Convert.ToInt32(keyValues[KernFirstTag])), Convert.ToChar(Convert.ToInt32(keyValues[KernSecondTag])));
                fontInfo.KerningPairs[pair] = Convert.ToInt32(keyValues[KernAmountTag]);
            }
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Function to read in the character information.
        /// </summary>
        /// <param name="fontInfo">The font information to update.</param>
        /// <param name="reader">The reader that is reading the file data.</param>
        private static void ParseCharacters(BmFontInfo fontInfo, StreamReader reader)
        {
            string countLine     = reader.ReadLine();
            var    characterList = new StringBuilder();

            if (string.IsNullOrWhiteSpace(countLine))
            {
                throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
            }

            string[] lineItems = countLine.Split(new[]
            {
                ' '
            },
                                                 StringSplitOptions.RemoveEmptyEntries);

            Dictionary <string, string> keyValues = GetLineKeyValuePairs(lineItems);

            if (!keyValues.ContainsKey(CharCountLine))
            {
                throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
            }

            int count = Convert.ToInt32(keyValues[CountTag]);

            // Iterate through the characters so we have enough info to build out glyph data.
            for (int i = 0; i < count; ++i)
            {
                string line = reader.ReadLine();

                if (string.IsNullOrWhiteSpace(line))
                {
                    throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
                }

                lineItems = line.Split(new[]
                {
                    ' '
                },
                                       StringSplitOptions.RemoveEmptyEntries);

                keyValues = GetLineKeyValuePairs(lineItems);

                if (!keyValues.ContainsKey(CharLine))
                {
                    throw new GorgonException(GorgonResult.CannotRead, Resources.GORGFX_ERR_FONT_FILE_FORMAT_INVALID);
                }

                char character = Convert.ToChar(Convert.ToInt32(keyValues[CharIdTag]));
                characterList.Append(character);

                fontInfo.GlyphRects[character] = new DX.Rectangle(Convert.ToInt32(keyValues[CharXTag]),
                                                                  Convert.ToInt32(keyValues[CharYTag]),
                                                                  Convert.ToInt32(keyValues[CharWidthTag]),
                                                                  Convert.ToInt32(keyValues[CharHeightTag]));
                fontInfo.GlyphOffsets[character]        = new DX.Point(Convert.ToInt32(keyValues[CharXOffsetTag]), Convert.ToInt32(keyValues[CharYOffsetTag]));
                fontInfo.CharacterAdvances[character]   = Convert.ToInt32(keyValues[CharAdvanceTag]);
                fontInfo.GlyphTextureIndices[character] = Convert.ToInt32(keyValues[CharPageTag]);
            }

            fontInfo.Characters = characterList.ToString();
        }