/// <summary>
        /// Processes the definition for a single font face.
        /// </summary>
        private static SpriteFontFace ProcessFace(Dictionary <String, PlatformNativeSurface> textures, ContentManager manager,
                                                  IContentProcessorMetadata metadata, SpriteFontFaceDescription description, String style, IEnumerable <CharacterRegion> characterRegions)
        {
            if (description == null)
            {
                return(null);
            }

            var textureName   = ResolveDependencyAssetPath(metadata, description.Texture);
            var textureRegion = description.TextureRegion;

            if (String.IsNullOrEmpty(textureName))
            {
                throw new ContentLoadException(OpenGLStrings.InvalidSpriteFontTexture);
            }

            var faceSurface = textures[textureName];
            var faceGlyphs  = OpenGLSpriteFontHelper.IdentifyGlyphs(faceSurface, textureRegion);

            var kerningDefaultAdjustment = description.Kernings?["default"] ?? 0;
            var kerningPairs             = description.Kernings?.Where(x => !String.Equals(x.Key, "default", StringComparison.InvariantCulture))
                                           .ToDictionary(x => CreateKerningPair(x.Key), x => x.Value);

            var kerning = new SpriteFontKerning()
            {
                DefaultAdjustment = kerningDefaultAdjustment
            };

            foreach (var kvp in kerningPairs)
            {
                kerning.Set(kvp.Key, kvp.Value);
            }

            var ascender  = description.Ascender;
            var descender = description.Descender;

            var faceTexture = manager.Load <Texture2D>(textureName, metadata.AssetDensity);
            var face        = new SpriteFontFace(manager.Ultraviolet,
                                                 faceTexture, characterRegions, faceGlyphs, kerning, ascender, descender, description.Glyphs?.Substitution ?? '?');

            return(face);
        }
        /// <summary>
        /// Imports a font face from the specified preprocessed asset stream.
        /// </summary>
        private static SpriteFontFace ImportPreprocessedFace(ContentManager manager,
                                                             IContentProcessorMetadata metadata, BinaryReader reader, IEnumerable <CharacterRegion> characterRegions, Int32 fileVersion)
        {
            var faceExists = reader.ReadBoolean();

            if (!faceExists)
            {
                return(null);
            }

            var texturePath            = reader.ReadString();
            var texture                = manager.Load <Texture2D>(texturePath, metadata.AssetDensity);
            var textureRegionSpecified = reader.ReadBoolean();

            if (textureRegionSpecified)
            {
                reader.ReadInt32();
                reader.ReadInt32();
                reader.ReadInt32();
                reader.ReadInt32();
            }

            var substitution = reader.ReadChar();

            var glyphPositions = new List <Rectangle>();
            var glyphCount     = reader.ReadInt32();

            for (int j = 0; j < glyphCount; j++)
            {
                var glyphX      = reader.ReadInt32();
                var glyphY      = reader.ReadInt32();
                var glyphWidth  = reader.ReadInt32();
                var glyphHeight = reader.ReadInt32();

                glyphPositions.Add(new Rectangle(glyphX, glyphY, glyphWidth, glyphHeight));
            }

            var kerningPairs             = new Dictionary <SpriteFontKerningPair, Int32>();
            var kerningDefaultAdjustment = reader.ReadInt32();
            var kerningCount             = reader.ReadInt32();

            for (int j = 0; j < kerningCount; j++)
            {
                var pairFirstChar  = reader.ReadChar();
                var pairSecondChar = reader.ReadChar();
                var offset         = reader.ReadInt32();

                kerningPairs[new SpriteFontKerningPair(pairFirstChar, pairSecondChar)] = offset;
            }

            var kerning = new SpriteFontKerning()
            {
                DefaultAdjustment = kerningDefaultAdjustment
            };

            foreach (var kvp in kerningPairs)
            {
                kerning.Set(kvp.Key, kvp.Value);
            }

            var ascender  = (fileVersion > 0) ? reader.ReadInt32() : 0;
            var descender = (fileVersion > 0) ? reader.ReadInt32() : 0;

            return(new SpriteFontFace(manager.Ultraviolet,
                                      texture, characterRegions, glyphPositions, kerning, ascender, descender, substitution));
        }