Exemple #1
0
        /*
           * get unicode font ranges
           */
        public static List<FontRange> GetFontUnicodeRanges(Font font)
        {
            Graphics g = Graphics.FromHwnd(IntPtr.Zero);
              IntPtr hdc = g.GetHdc();
              IntPtr hFont = font.ToHfont();
              IntPtr old = SelectObject(hdc, hFont);
              uint size = GetFontUnicodeRanges(hdc, IntPtr.Zero);
              IntPtr glyphSet = Marshal.AllocHGlobal((int)size);
              GetFontUnicodeRanges(hdc, glyphSet);
              List<FontRange> fontRanges = new List<FontRange>();
              int count = Marshal.ReadInt32(glyphSet, 12);

              for (int i = 0; i < count; i++)
              {
            FontRange range = new FontRange();
            range.Low = (UInt16)Marshal.ReadInt16(glyphSet, 16 + i * 4);
            range.High = (UInt16)(range.Low + Marshal.ReadInt16(glyphSet, 18 + i * 4) - 1);
            fontRanges.Add(range);
              }

              SelectObject(hdc, old);
              Marshal.FreeHGlobal(glyphSet);
              g.ReleaseHdc(hdc);
              g.Dispose();
              return fontRanges;
        }
Exemple #2
0
        /// <summary>
        /// Gets the unicode ranges for font.
        /// </summary>
        /// <param name="font">The font.</param>
        /// <returns></returns>
        public List <FontRange> GetUnicodeRangesForFont(Font font)
        {
            Graphics g        = Graphics.FromHwnd(IntPtr.Zero);
            IntPtr   hdc      = g.GetHdc();
            IntPtr   hFont    = font.ToHfont();
            IntPtr   old      = SelectObject(hdc, hFont);
            uint     size     = GetFontUnicodeRanges(hdc, IntPtr.Zero);
            IntPtr   glyphSet = Marshal.AllocHGlobal((int)size);

            GetFontUnicodeRanges(hdc, glyphSet);
            List <FontRange> fontRanges = new List <FontRange>();
            int count = Marshal.ReadInt32(glyphSet, 12);

            for (int i = 0; i < count; i++)
            {
                FontRange range = new FontRange();
                range.Low  = (UInt16)Marshal.ReadInt16(glyphSet, 16 + i * 4);
                range.High = (UInt16)(range.Low + Marshal.ReadInt16(glyphSet, 18 + i * 4) - 1);
                fontRanges.Add(range);
            }
            SelectObject(hdc, old);
            Marshal.FreeHGlobal(glyphSet);
            g.ReleaseHdc(hdc);
            g.Dispose();
            return(fontRanges);
        }
        // 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, ' '
            }));
        }