Пример #1
0
        private static void Main(string[] args)
        {
            if (args.Length < 2)
            {
                Program.DisplayUsage();
                return;
            }

            string input = args[0];
            string output = args[1];
            bool detailed = args.Length > 2 && args[2].Equals("--detailed");

            if(output.EndsWith(".mfnt") == false)
            {
                output = output + ".mfnt";
            }

            FontBaker baker = new FontBaker();
            if (baker.Bake(input, output))
            {
                Console.WriteLine("Success!");
            }
            else
            {
                Console.WriteLine("Error: " + baker.ErrorMessage);
                if(detailed)
                {
                    Console.WriteLine("Details: " + baker.DetailedError);
                }
            }
        }
Пример #2
0
        private void LoadFont()
        {
            var buffer  = File.ReadAllBytes("Fonts/DroidSans.ttf");
            var buffer2 = File.ReadAllBytes("Fonts/DroidSansJapanese.ttf");

            var tempBitmap = new byte[FontBitmapWidth * FontBitmapHeight];

            var fontBaker = new FontBaker();

            fontBaker.Begin(tempBitmap, FontBitmapWidth, FontBitmapHeight);
            fontBaker.Add(buffer, 32, new []
            {
                FontBakerCharacterRange.BasicLatin,
                FontBakerCharacterRange.Latin1Supplement,
                FontBakerCharacterRange.LatinExtendedA,
                FontBakerCharacterRange.Cyrillic,
            });

            fontBaker.Add(buffer2, 32, new []
            {
                FontBakerCharacterRange.Hiragana,
                FontBakerCharacterRange.Katakana
            });

            var _charData = fontBaker.End();

            // Offset by minimal offset
            float minimumOffsetY = 10000;

            foreach (var pair in _charData)
            {
                if (pair.Value.yoff < minimumOffsetY)
                {
                    minimumOffsetY = pair.Value.yoff;
                }
            }

            var keys = _charData.Keys.ToArray();

            foreach (var key in keys)
            {
                var pc = _charData[key];
                pc.yoff       -= minimumOffsetY;
                _charData[key] = pc;
            }

            var rgb = new Color[FontBitmapWidth * FontBitmapHeight];

            for (var i = 0; i < tempBitmap.Length; ++i)
            {
                var b = tempBitmap[i];
                rgb[i].R = b;
                rgb[i].G = b;
                rgb[i].B = b;

                rgb[i].A = b;
            }

            _fontTexture = new Texture2D(GraphicsDevice, FontBitmapWidth, FontBitmapHeight);
            _fontTexture.SetData(rgb);

            var glyphBounds = new List <Rectangle>();
            var cropping    = new List <Rectangle>();
            var chars       = new List <char>();
            var kerning     = new List <Vector3>();

            var orderedKeys = _charData.Keys.OrderBy(a => a);

            foreach (var key in orderedKeys)
            {
                var character = _charData[key];

                var bounds = new Rectangle(character.x0, character.y0,
                                           character.x1 - character.x0,
                                           character.y1 - character.y0);

                glyphBounds.Add(bounds);
                cropping.Add(new Rectangle((int)character.xoff, (int)character.yoff, bounds.Width, bounds.Height));

                chars.Add(key);

                kerning.Add(new Vector3(0, bounds.Width, character.xadvance - bounds.Width));
            }

            var constructorInfo = typeof(SpriteFont).GetTypeInfo().DeclaredConstructors.First();

            _font = (SpriteFont)constructorInfo.Invoke(new object[]
            {
                _fontTexture, glyphBounds, cropping,
                chars, 20, 0, kerning, ' '
            });
        }
Пример #3
0
        // Copied / Adapted from:
        // https://github.com/StbSharp/StbTrueTypeSharp/tree/master/samples/StbTrueTypeSharp.MonoGame.Test
        public static SpriteFont LoadFont(string path, float fontHeight, FontRange fontRange = FontRange.Latin)
        {
            var fontBaker = new FontBaker();

            fontBaker.Begin(FontBitmapWidth, FontBitmapHeight);
            if (fontRange == FontRange.Latin)
            {
                fontBaker.Add(File.ReadAllBytes(path), fontHeight, new[]
                {
                    CharacterRange.BasicLatin,
                    CharacterRange.Latin1Supplement,
                    CharacterRange.LatinExtendedA,
                    CharacterRange.LatinExtendedB,
                    CharacterRange.Greek,
                    LatinSymbols
                });
            }
            else if (fontRange == FontRange.Japanese)
            {
                fontBaker.Add(File.ReadAllBytes(path), fontHeight, new[]
                {
                    CharacterRange.BasicLatin,
                    CharacterRange.Latin1Supplement,
                    CharacterRange.LatinExtendedA,
                    CharacterRange.LatinExtendedB,
                    CharacterRange.Greek,
                    LatinSymbols,
                    ExtendedSymbols,
                    CharacterRange.Hiragana,
                    CharacterRange.Katakana,
                    CharacterRange.CjkSymbolsAndPunctuation,
                    CharacterRange.CjkUnifiedIdeographs
                });
            }

            var _charData = fontBaker.End();

            // Offset by minimal offset
            int minimumOffsetY = 10000;

            foreach (var pair in _charData.Glyphs)
            {
                if (pair.Value.YOffset < minimumOffsetY)
                {
                    minimumOffsetY = pair.Value.YOffset;
                }
            }

            var keys = _charData.Glyphs.Keys.ToArray();

            foreach (var key in keys)
            {
                var pc = _charData.Glyphs[key];
                pc.YOffset           -= minimumOffsetY;
                _charData.Glyphs[key] = pc;
            }

            var rgb = new Color[FontBitmapWidth * FontBitmapHeight];

            for (var i = 0; i < _charData.Bitmap.Length; ++i)
            {
                var b = _charData.Bitmap[i];
                rgb[i].R = b;
                rgb[i].G = b;
                rgb[i].B = b;

                rgb[i].A = b;
            }

            var fontTexture = new Texture2D(Globals.GraphicsManager.GraphicsDevice, FontBitmapWidth, FontBitmapHeight);

            fontTexture.SetData(rgb);

            var glyphBounds = new List <Rectangle>();
            var cropping    = new List <Rectangle>();
            var chars       = new List <char>();
            var kerning     = new List <Vector3>();

            var orderedKeys = _charData.Glyphs.Keys.OrderBy(a => a);

            foreach (var key in orderedKeys)
            {
                var character = _charData.Glyphs[key];

                var bounds = new Rectangle(character.X, character.Y,
                                           character.Width,
                                           character.Height);

                glyphBounds.Add(bounds);
                cropping.Add(new Rectangle(character.XOffset, character.YOffset, bounds.Width, bounds.Height));

                chars.Add((char)key);

                kerning.Add(new Vector3(0, bounds.Width, character.XAdvance - bounds.Width));
            }

            var constructorInfo = typeof(SpriteFont).GetTypeInfo().DeclaredConstructors.First();
            var spacing         = cropping.Max(x => x.Height);

            return((SpriteFont)constructorInfo.Invoke(new object[]
            {
                fontTexture, glyphBounds, cropping,
                chars, spacing, 0, kerning, ' '
            }));
        }
Пример #4
0
        /// <summary>
        /// LoadContent will be called once per game and is the place to load
        /// all of your content.
        /// </summary>
        protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            _spriteBatch = new SpriteBatch(GraphicsDevice);

            // TODO: use this.Content to load your game content here
            // Create white texture
            _white = new Texture2D(GraphicsDevice, 1, 1);
            _white.SetData(new[] { Color.White });

            // Load image data into memory
            var path = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);

            path = Path.Combine(path, "image.jpg");
            var buffer = File.ReadAllBytes(path);

            var image = StbImage.LoadFromMemory(buffer, StbImage.STBI_rgb_alpha);

            _image = new Texture2D(GraphicsDevice, image.Width, image.Height, false, SurfaceFormat.Color);
            _image.SetData(image.Data);

            // Load ttf
            buffer = File.ReadAllBytes("Fonts/DroidSans.ttf");
            var buffer2 = File.ReadAllBytes("Fonts/DroidSansJapanese.ttf");

            var tempBitmap = new byte[FontBitmapWidth * FontBitmapHeight];

            var fontBaker = new FontBaker();

            fontBaker.Begin(tempBitmap, FontBitmapWidth, FontBitmapHeight);
            fontBaker.Add(buffer, 32, new []
            {
                FontBakerCharacterRange.BasicLatin,
                FontBakerCharacterRange.Latin1Supplement,
                FontBakerCharacterRange.LatinExtendedA,
                FontBakerCharacterRange.Cyrillic,
            });

            fontBaker.Add(buffer2, 32, new []
            {
                FontBakerCharacterRange.Hiragana,
                FontBakerCharacterRange.Katakana
            });

            _charData = fontBaker.End();

            // Offset by minimal offset
            float minimumOffsetY = 10000;

            foreach (var pair in _charData)
            {
                if (pair.Value.yoff < minimumOffsetY)
                {
                    minimumOffsetY = pair.Value.yoff;
                }
            }

            var keys = _charData.Keys.ToArray();

            foreach (var key in keys)
            {
                var pc = _charData[key];
                pc.yoff       -= minimumOffsetY;
                _charData[key] = pc;
            }


            var rgb = new Color[FontBitmapWidth * FontBitmapHeight];

            for (var i = 0; i < tempBitmap.Length; ++i)
            {
                var b = tempBitmap[i];
                rgb[i].R = b;
                rgb[i].G = b;
                rgb[i].B = b;

                rgb[i].A = b;
            }

            _fontTexture = new Texture2D(GraphicsDevice, FontBitmapWidth, FontBitmapHeight);
            _fontTexture.SetData(rgb);

            // Load ogg
            path   = Path.GetDirectoryName(System.Reflection.Assembly.GetEntryAssembly().Location);
            path   = Path.Combine(path, "Adeste_Fideles.ogg");
            buffer = File.ReadAllBytes(path);

            int chan, sampleRate;
            var audioShort = StbVorbis.decode_vorbis_from_memory(buffer, out sampleRate, out chan);

            byte[] audioData = new byte[audioShort.Length / 2 * 4];
            for (var i = 0; i < audioShort.Length; ++i)
            {
                if (i * 2 >= audioData.Length)
                {
                    break;
                }

                var b1 = (byte)(audioShort[i] >> 8);
                var b2 = (byte)(audioShort[i] & 256);

                audioData[i * 2 + 0] = b2;
                audioData[i * 2 + 1] = b1;
            }

            _effect = new DynamicSoundEffectInstance(sampleRate, AudioChannels.Stereo)
            {
                Volume = 0.5f
            };


            _effect.SubmitBuffer(audioData);

            GC.Collect();
        }
Пример #5
0
        public void ApplyFontFile([NotNull] string fileName)
        {
            _fontTexture?.Dispose();

            var fontData   = File.ReadAllBytes(fileName);
            var tempBitmap = new byte[FontBitmapWidth * FontBitmapHeight];

            var fontBaker = new FontBaker();

            fontBaker.Begin(tempBitmap, FontBitmapWidth, FontBitmapHeight);

            var fontSizeInPx = PointToPixel(FontSize);

            fontBaker.Add(fontData, fontSizeInPx, new[] {
                FontBakerCharacterRange.BasicLatin,
                FontBakerCharacterRange.Latin1Supplement,
                FontBakerCharacterRange.LatinExtendedA,
                FontBakerCharacterRange.LatinExtendedB,
//                FontBakerCharacterRange.Cyrillic
            });

            var charData = fontBaker.End();

            var minOffsetY = float.MaxValue;

            foreach (var kv in charData)
            {
                if (kv.Value.yoff < minOffsetY)
                {
                    minOffsetY = kv.Value.yoff;
                }
            }

            var keys = charData.Keys.ToArray();

            foreach (var key in keys)
            {
                var pc = charData[key];

                pc.yoff -= minOffsetY;

                charData[key] = pc;
            }

            var rgba = new Color[FontBitmapWidth * FontBitmapHeight];

            for (var i = 0; i < tempBitmap.Length; ++i)
            {
                var b = tempBitmap[i];

                rgba[i].R = b;
                rgba[i].G = b;
                rgba[i].B = b;
                rgba[i].A = b;
            }

            var fontTexture = new Texture2D(_graphicsDevice, FontBitmapWidth, FontBitmapHeight, false, SurfaceFormat.Color);

            fontTexture.SetData(rgba);

            var glyphBounds = new List <Rectangle>();
            var cropping    = new List <Rectangle>();
            var chars       = new List <char>();
            var kerning     = new List <Vector3>();

            var orderedKeys = charData.Keys.OrderBy(a => a);

            foreach (var key in orderedKeys)
            {
                var character = charData[key];

                var bounds = new Rectangle(
                    character.x0,
                    character.y0,
                    character.x1 - character.x0,
                    character.y1 - character.y0);

                glyphBounds.Add(bounds);
                cropping.Add(new Rectangle((int)character.xoff, (int)character.yoff, bounds.Width, bounds.Height));

                chars.Add(key);

                kerning.Add(new Vector3(0, bounds.Width, character.xadvance - bounds.Width));
            }

            // The constructor is made public from 3.7.
            // But since we are using 3.6, we have to use reflection to access it.
            var constructor = typeof(SpriteFont).GetConstructor(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance, null, SpriteFontConstructorTypes, null);

            if (constructor == null)
            {
                throw new MissingMethodException("Cannot access constructor of " + nameof(_spriteFont));
            }

            var spriteFont = (SpriteFont)constructor.Invoke(new object[] {
                fontTexture, glyphBounds, cropping,
                chars, LineSpacing, Spacing, kerning, DefaultCharacter
            });

            _charData    = charData;
            _fontTexture = fontTexture;
            _spriteFont  = spriteFont;
        }