├── images ├── sample.png └── FolderStructure.png ├── samples ├── SpriteFontPlus.Samples.BMFont │ ├── Icon.ico │ ├── Fonts │ │ ├── test_0.png │ │ ├── test.bmfc │ │ └── test.fnt │ ├── Program.cs │ ├── SpriteFontPlus.Samples.BMFont.csproj │ └── Game1.cs └── SpriteFontPlus.Samples.TtfBaking │ ├── Icon.ico │ ├── Fonts │ ├── DroidSans.ttf │ ├── DroidSansJapanese.ttf │ └── LICENSE.txt │ ├── Program.cs │ ├── SpriteFontPlus.Samples.TtfBaking.FNA.csproj │ ├── SpriteFontPlus.Samples.TtfBaking.FNA.Core.csproj │ ├── SpriteFontPlus.Samples.TtfBaking.MonoGame.csproj │ └── Game1.cs ├── src ├── GlyphInfo.cs ├── Utility.cs ├── SpriteFontPlus.FNA.csproj ├── SpriteFontPlus.FNA.Core.csproj ├── SpriteFontPlus.MonoGame.csproj ├── CharacterRange.cs ├── TtfFontBakerResult.cs ├── TtfFontBaker.cs └── BMFontLoader.cs ├── Directory.Build.props ├── .github └── workflows │ └── build-and-publish.yml ├── .vscode ├── tasks.json └── launch.json ├── LICENSE ├── .gitattributes ├── README.md └── .gitignore /images/sample.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rds1983/SpriteFontPlus/HEAD/images/sample.png -------------------------------------------------------------------------------- /images/FolderStructure.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rds1983/SpriteFontPlus/HEAD/images/FolderStructure.png -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.BMFont/Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rds1983/SpriteFontPlus/HEAD/samples/SpriteFontPlus.Samples.BMFont/Icon.ico -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.TtfBaking/Icon.ico: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rds1983/SpriteFontPlus/HEAD/samples/SpriteFontPlus.Samples.TtfBaking/Icon.ico -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.BMFont/Fonts/test_0.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rds1983/SpriteFontPlus/HEAD/samples/SpriteFontPlus.Samples.BMFont/Fonts/test_0.png -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.TtfBaking/Fonts/DroidSans.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rds1983/SpriteFontPlus/HEAD/samples/SpriteFontPlus.Samples.TtfBaking/Fonts/DroidSans.ttf -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.TtfBaking/Fonts/DroidSansJapanese.ttf: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/rds1983/SpriteFontPlus/HEAD/samples/SpriteFontPlus.Samples.TtfBaking/Fonts/DroidSansJapanese.ttf -------------------------------------------------------------------------------- /src/GlyphInfo.cs: -------------------------------------------------------------------------------- 1 | namespace SpriteFontPlus 2 | { 3 | public struct GlyphInfo 4 | { 5 | public int X, Y, Width, Height; 6 | public int XOffset, YOffset; 7 | public int XAdvance; 8 | } 9 | } -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.BMFont/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpriteFontPlus.Samples.BMFont 4 | { 5 | /// 6 | /// The main class. 7 | /// 8 | public static class Program 9 | { 10 | /// 11 | /// The main entry point for the application. 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | using (var game = new Game1()) 17 | game.Run(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.TtfBaking/Program.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | 3 | namespace SpriteFontPlus.Samples.TtfBaking 4 | { 5 | /// 6 | /// The main class. 7 | /// 8 | public static class Program 9 | { 10 | /// 11 | /// The main entry point for the application. 12 | /// 13 | [STAThread] 14 | static void Main() 15 | { 16 | using (var game = new Game1()) 17 | game.Run(); 18 | } 19 | } 20 | } 21 | -------------------------------------------------------------------------------- /src/Utility.cs: -------------------------------------------------------------------------------- 1 | using System.IO; 2 | 3 | namespace SpriteFontPlus 4 | { 5 | internal static class Utility 6 | { 7 | public static byte[] ToByteArray(this Stream stream) 8 | { 9 | byte[] bytes; 10 | 11 | // Rewind stream if it is at end 12 | if (stream.CanSeek && stream.Length == stream.Position) 13 | { 14 | stream.Seek(0, SeekOrigin.Begin); 15 | } 16 | 17 | // Copy it's data to memory 18 | using (var ms = new MemoryStream()) 19 | { 20 | stream.CopyTo(ms); 21 | bytes = ms.ToArray(); 22 | } 23 | 24 | return bytes; 25 | } 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /Directory.Build.props: -------------------------------------------------------------------------------- 1 | 2 | 3 | SpriteFontPlusTeam 4 | SpriteFontPlus 5 | Library extending functionality of the SpriteFont. 6 | MIT 7 | https://github.com/rds1983/SpriteFontPlus 8 | SpriteFontPlus 9 | 0.9.2 10 | 1.24.7 11 | 2.22.4 12 | 2.0.1 13 | 14 | -------------------------------------------------------------------------------- /.github/workflows/build-and-publish.yml: -------------------------------------------------------------------------------- 1 | name: Build & Publish 2 | 3 | on: 4 | workflow_dispatch: 5 | 6 | jobs: 7 | BuildAndPublish: 8 | runs-on: windows-latest 9 | 10 | steps: 11 | - uses: actions/checkout@v2 12 | with: 13 | submodules: recursive 14 | - name: Setup .NET Core 15 | uses: actions/setup-dotnet@v1 16 | with: 17 | dotnet-version: '3.1.x' 18 | - name: Build SpriteFontPlus.MonoGame 19 | run: dotnet build src\SpriteFontPlus.MonoGame.csproj --configuration Release 20 | - name: Install NuGet 21 | uses: NuGet/setup-nuget@v1 22 | - name: Publish SpriteFontPlus.MonoGame to NuGet 23 | run: nuget.exe push src\bin\MonoGame\Release\SpriteFontPlus.*.nupkg ${{secrets.NUGET_APIKEY}} -Source https://api.nuget.org/v3/index.json 24 | -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.TtfBaking/SpriteFontPlus.Samples.TtfBaking.FNA.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | WinExe 4 | 5 | 6 | net45 7 | bin\FNA\$(Configuration) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | PreserveNewest 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.TtfBaking/SpriteFontPlus.Samples.TtfBaking.FNA.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | WinExe 4 | 5 | 6 | netcoreapp3.1 7 | bin\FNA.Core\$(Configuration) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | PreserveNewest 17 | 18 | 19 | PreserveNewest 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /src/SpriteFontPlus.FNA.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net45 4 | SpriteFontPlus.FNA 5 | SpriteFontPlus.FNA 6 | $(DefineConstants);FNA 7 | bin\FNA\$(Configuration) 8 | true 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /.vscode/tasks.json: -------------------------------------------------------------------------------- 1 | { 2 | // See https://go.microsoft.com/fwlink/?LinkId=733558 3 | // for the documentation about the tasks.json format 4 | "version": "2.0.0", 5 | "tasks": [ 6 | { 7 | "label": "FNA Debug", 8 | "command": "dotnet build", 9 | "type": "shell", 10 | "group": "build", 11 | "args": [ 12 | "build/FNA/SpriteFontPlus.sln", 13 | "/t:build", 14 | "/p:Configuration=Debug" 15 | ], 16 | "presentation": { 17 | "reveal": "silent" 18 | }, 19 | "problemMatcher": "$msCompile" 20 | }, 21 | { 22 | "label": "FNA Release", 23 | "command": "dotnet build", 24 | "type": "shell", 25 | "group": "build", 26 | "args": [ 27 | "build/FNA/SpriteFontPlus.sln", 28 | "/t:build", 29 | "/p:Configuration=Release" 30 | ], 31 | "presentation": { 32 | "reveal": "silent" 33 | }, 34 | "problemMatcher": "$msCompile" 35 | } 36 | ] 37 | } -------------------------------------------------------------------------------- /src/SpriteFontPlus.FNA.Core.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | net8.0 4 | SpriteFontPlus.FNA 5 | SpriteFontPlus.FNA 6 | $(DefineConstants);FNA 7 | bin\FNA\$(Configuration) 8 | true 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.BMFont/SpriteFontPlus.Samples.BMFont.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | WinExe 4 | 5 | 6 | net6.0 7 | bin\MonoGame\$(Configuration) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | PreserveNewest 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.TtfBaking/SpriteFontPlus.Samples.TtfBaking.MonoGame.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | WinExe 4 | 5 | 6 | net6.0 7 | bin\MonoGame\$(Configuration) 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | PreserveNewest 21 | 22 | 23 | PreserveNewest 24 | 25 | 26 | 27 | -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.BMFont/Fonts/test.bmfc: -------------------------------------------------------------------------------- 1 | # AngelCode Bitmap Font Generator configuration file 2 | fileVersion=1 3 | 4 | # font settings 5 | fontName=Arial 6 | fontFile= 7 | charSet=0 8 | fontSize=32 9 | aa=1 10 | scaleH=100 11 | useSmoothing=1 12 | isBold=0 13 | isItalic=0 14 | useUnicode=1 15 | disableBoxChars=1 16 | outputInvalidCharGlyph=0 17 | dontIncludeKerningPairs=0 18 | useHinting=1 19 | renderFromOutline=0 20 | useClearType=1 21 | 22 | # character alignment 23 | paddingDown=0 24 | paddingUp=0 25 | paddingRight=0 26 | paddingLeft=0 27 | spacingHoriz=1 28 | spacingVert=1 29 | useFixedHeight=0 30 | forceZero=0 31 | 32 | # output file 33 | outWidth=256 34 | outHeight=256 35 | outBitDepth=32 36 | fontDescFormat=1 37 | fourChnlPacked=0 38 | textureFormat=png 39 | textureCompression=0 40 | alphaChnl=1 41 | redChnl=0 42 | greenChnl=0 43 | blueChnl=0 44 | invA=0 45 | invR=0 46 | invG=0 47 | invB=0 48 | 49 | # outline 50 | outlineThickness=0 51 | 52 | # selected chars 53 | chars=32-126,160-255 54 | 55 | # imported icon images 56 | -------------------------------------------------------------------------------- /src/SpriteFontPlus.MonoGame.csproj: -------------------------------------------------------------------------------- 1 | 2 | 3 | netstandard2.0 4 | SpriteFontPlus 5 | SpriteFontPlus 6 | $(DefineConstants);MONOGAME 7 | bin\MonoGame\$(Configuration) 8 | true 9 | 10 | 11 | 12 | true 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2019 Roman Shapiro 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /src/CharacterRange.cs: -------------------------------------------------------------------------------- 1 | namespace SpriteFontPlus 2 | { 3 | public struct CharacterRange 4 | { 5 | public static readonly CharacterRange BasicLatin = new CharacterRange((char)0x0020, (char)0x007F); 6 | 7 | public static readonly CharacterRange Latin1Supplement = 8 | new CharacterRange((char)0x00A0, (char)0x00FF); 9 | 10 | public static readonly CharacterRange LatinExtendedA = 11 | new CharacterRange((char)0x0100, (char)0x017F); 12 | 13 | public static readonly CharacterRange LatinExtendedB = 14 | new CharacterRange((char)0x0180, (char)0x024F); 15 | 16 | public static readonly CharacterRange Cyrillic = new CharacterRange((char)0x0400, (char)0x04FF); 17 | 18 | public static readonly CharacterRange CyrillicSupplement = 19 | new CharacterRange((char)0x0500, (char)0x052F); 20 | 21 | public static readonly CharacterRange Hiragana = 22 | new CharacterRange((char)0x3040, (char)0x309F); 23 | 24 | public static readonly CharacterRange Katakana = 25 | new CharacterRange((char)0x30A0, (char)0x30FF); 26 | 27 | public char Start { get; private set; } 28 | public char End { get; private set; } 29 | 30 | public CharacterRange(char start, char end) 31 | { 32 | Start = start; 33 | End = end; 34 | } 35 | 36 | public CharacterRange(char single) : this(single, single) 37 | { 38 | } 39 | } 40 | } -------------------------------------------------------------------------------- /.vscode/launch.json: -------------------------------------------------------------------------------- 1 | { 2 | // Use IntelliSense to learn about possible attributes. 3 | // Hover to view descriptions of existing attributes. 4 | // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 5 | "version": "0.2.0", 6 | "configurations": [ 7 | { 8 | "name": "DynamicSpriteFont", 9 | "type": "coreclr", 10 | "request": "launch", 11 | "preLaunchTask": "FNA Debug", 12 | "program": "${workspaceFolder}/samples/SpriteFontPlus.Samples.DynamicSpriteFont/bin/FNA/Debug/netcoreapp2.1/SpriteFontPlus.Samples.DynamicSpriteFont.dll", 13 | "args": [], 14 | "cwd": "${workspaceFolder}/samples/SpriteFontPlus.Samples.DynamicSpriteFont/bin/FNA/Debug/netcoreapp2.1/", 15 | "console": "internalConsole", 16 | "stopAtEntry": false, 17 | "internalConsoleOptions": "openOnSessionStart" 18 | }, 19 | { 20 | "name": "TtfBaking", 21 | "type": "coreclr", 22 | "request": "launch", 23 | "preLaunchTask": "FNA Debug", 24 | "program": "${workspaceFolder}/samples/SpriteFontPlus.Samples.TtfBaking/bin/FNA/Debug/netcoreapp2.1/SpriteFontPlus.Samples.TtfBaking.dll", 25 | "args": [], 26 | "cwd": "${workspaceFolder}/samples/SpriteFontPlus.Samples.TtfBaking/bin/FNA/Debug/netcoreapp2.1/", 27 | "console": "internalConsole", 28 | "stopAtEntry": false, 29 | "internalConsoleOptions": "openOnSessionStart" 30 | } 31 | ] 32 | } -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.BMFont/Game1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Microsoft.Xna.Framework; 4 | using Microsoft.Xna.Framework.Graphics; 5 | 6 | namespace SpriteFontPlus.Samples.BMFont 7 | { 8 | /// 9 | /// This is the main type for your game. 10 | /// 11 | public class Game1 : Game 12 | { 13 | GraphicsDeviceManager _graphics; 14 | SpriteBatch _spriteBatch; 15 | 16 | private SpriteFont _font; 17 | 18 | public Game1() 19 | { 20 | _graphics = new GraphicsDeviceManager(this) 21 | { 22 | PreferredBackBufferWidth = 1024, 23 | PreferredBackBufferHeight = 768 24 | }; 25 | 26 | Content.RootDirectory = "Content"; 27 | IsMouseVisible = true; 28 | Window.AllowUserResizing = true; 29 | } 30 | 31 | /// 32 | /// LoadContent will be called once per game and is the place to load 33 | /// all of your content. 34 | /// 35 | protected override void LoadContent() 36 | { 37 | // Create a new SpriteBatch, which can be used to draw textures. 38 | _spriteBatch = new SpriteBatch(GraphicsDevice); 39 | 40 | string fontData; 41 | using (var stream = TitleContainer.OpenStream("Fonts/test.fnt")) 42 | { 43 | using (var reader = new StreamReader(stream)) 44 | { 45 | fontData = reader.ReadToEnd(); 46 | } 47 | } 48 | 49 | _font = BMFontLoader.Load(fontData, name => TitleContainer.OpenStream("Fonts/" + name), GraphicsDevice); 50 | 51 | GC.Collect(); 52 | } 53 | 54 | /// 55 | /// UnloadContent will be called once per game and is the place to unload 56 | /// game-specific content. 57 | /// 58 | protected override void UnloadContent() 59 | { 60 | // TODO: Unload any non ContentManager content here 61 | } 62 | 63 | /// 64 | /// This is called when the game should draw itself. 65 | /// 66 | /// Provides a snapshot of timing values. 67 | protected override void Draw(GameTime gameTime) 68 | { 69 | GraphicsDevice.Clear(Color.CornflowerBlue); 70 | 71 | // TODO: Add your drawing code here 72 | _spriteBatch.Begin(); 73 | 74 | // Render some text 75 | _spriteBatch.DrawString(_font, "The quick brown fox jumps over the lazy dog", 76 | new Vector2(0, 0), Color.White); 77 | 78 | _spriteBatch.End(); 79 | 80 | base.Draw(gameTime); 81 | } 82 | } 83 | } -------------------------------------------------------------------------------- /.gitattributes: -------------------------------------------------------------------------------- 1 | ############################################################################### 2 | # Set default behavior to automatically normalize line endings. 3 | ############################################################################### 4 | * text=auto 5 | 6 | ############################################################################### 7 | # Set default behavior for command prompt diff. 8 | # 9 | # This is need for earlier builds of msysgit that does not have it on by 10 | # default for csharp files. 11 | # Note: This is only used by command line 12 | ############################################################################### 13 | #*.cs diff=csharp 14 | 15 | ############################################################################### 16 | # Set the merge driver for project and solution files 17 | # 18 | # Merging from the command prompt will add diff markers to the files if there 19 | # are conflicts (Merging from VS is not affected by the settings below, in VS 20 | # the diff markers are never inserted). Diff markers may cause the following 21 | # file extensions to fail to load in VS. An alternative would be to treat 22 | # these files as binary and thus will always conflict and require user 23 | # intervention with every merge. To do so, just uncomment the entries below 24 | ############################################################################### 25 | #*.sln merge=binary 26 | #*.csproj merge=binary 27 | #*.vbproj merge=binary 28 | #*.vcxproj merge=binary 29 | #*.vcproj merge=binary 30 | #*.dbproj merge=binary 31 | #*.fsproj merge=binary 32 | #*.lsproj merge=binary 33 | #*.wixproj merge=binary 34 | #*.modelproj merge=binary 35 | #*.sqlproj merge=binary 36 | #*.wwaproj merge=binary 37 | 38 | ############################################################################### 39 | # behavior for image files 40 | # 41 | # image files are treated as binary by default. 42 | ############################################################################### 43 | #*.jpg binary 44 | #*.png binary 45 | #*.gif binary 46 | 47 | ############################################################################### 48 | # diff behavior for common document formats 49 | # 50 | # Convert binary document formats to text before diffing them. This feature 51 | # is only available from the command line. Turn it on by uncommenting the 52 | # entries below. 53 | ############################################################################### 54 | #*.doc diff=astextplain 55 | #*.DOC diff=astextplain 56 | #*.docx diff=astextplain 57 | #*.DOCX diff=astextplain 58 | #*.dot diff=astextplain 59 | #*.DOT diff=astextplain 60 | #*.pdf diff=astextplain 61 | #*.PDF diff=astextplain 62 | #*.rtf diff=astextplain 63 | #*.RTF diff=astextplain 64 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | **BREAKING CHANGE:** DynamicSpriteFont had been moved to the project: https://github.com/rds1983/FontStashSharp 2 | 3 | # SpriteFontPlus 4 | [![NuGet](https://img.shields.io/nuget/v/SpriteFontPlus.svg)](https://www.nuget.org/packages/SpriteFontPlus/) 5 | ![Build & Publish](https://github.com/rds1983/SpriteFontPlus/workflows/Build%20&%20Publish/badge.svg) 6 | [![Chat](https://img.shields.io/discord/628186029488340992.svg)](https://discord.gg/ZeHxhCY) 7 | 8 | Library that extends functionality of the SpriteFont. 9 | 10 | # Features 11 | * Creation of SpriteFont in the run-time from ttf. 12 | * Creation of SpriteFont in the run-time from AngelCode BMFont(only XML with single texture works for now). 13 | 14 | # Adding Reference 15 | There are two ways of referencing SpriteFontPlus in the project: 16 | 1. Through nuget(works only for MonoGame): https://www.nuget.org/packages/SpriteFontPlus/ 17 | 2. As source code(works for both MonoGame and FNA): 18 | 19 | a. Clone this repo. 20 | 21 | b. Execute `git submodule update --init --recursive` within the folder the repo was cloned to. 22 | 23 | c. Add src/SpriteFontPlus.MonoGame.csproj or src/SpriteFontPlus.FNA.csproj to the solution. 24 | 25 | * If FNA is used, then the folder structure is expected to be following: ![Folder Structure](/images/FolderStructure.png) 26 | 27 | # Loading SpriteFont from a ttf 28 | Following code creates a SpriteFont from a ttf: 29 | ```c# 30 | var fontBakeResult = TtfFontBaker.Bake(File.ReadAllBytes(@"C:\\Windows\\Fonts\arial.ttf"), 31 | 25, 32 | 1024, 33 | 1024, 34 | new[] 35 | { 36 | CharacterRange.BasicLatin, 37 | CharacterRange.Latin1Supplement, 38 | CharacterRange.LatinExtendedA, 39 | CharacterRange.Cyrillic 40 | } 41 | ); 42 | 43 | SpriteFont font = fontBakeResult.CreateSpriteFont(GraphicsDevice); 44 | ``` 45 | Full sample is here: 46 | [samples/SpriteFontPlus.Samples.TtfBaking](samples/SpriteFontPlus.Samples.TtfBaking) 47 | 48 | 49 | # Loading SpriteFont from AngelCode BMFont 50 | ```c# 51 | string fontData; 52 | using (var stream = TitleContainer.OpenStream("Fonts/test.fnt")) 53 | { 54 | using (var reader = new StreamReader(stream)) 55 | { 56 | fontData = reader.ReadToEnd(); 57 | } 58 | } 59 | 60 | SpriteFont font = BMFontLoader.Load(fontData, name => TitleContainer.OpenStream("Fonts/" + name), GraphicsDevice); 61 | ``` 62 | 63 | Full sample is here: 64 | [samples/SpriteFontPlus.Samples.BMFont](samples/SpriteFontPlus.Samples.BMFont) 65 | 66 | ## Building From Source Code 67 | 1. Clone this repo. 68 | 2. `git submodule update --init --recursive` 69 | 3. Open a solution from the "build" folder. 70 | 71 | ## Credits 72 | * [MonoGame](http://www.monogame.net/) 73 | * [FNA](https://github.com/FNA-XNA/FNA) 74 | * [BMFont](https://www.angelcode.com/products/bmfont/) 75 | * [Cyotek.Drawing.BitmapFont](https://github.com/cyotek/Cyotek.Drawing.BitmapFont) 76 | * [stb](https://github.com/nothings/stb) 77 | -------------------------------------------------------------------------------- /src/TtfFontBakerResult.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using System.Linq; 4 | using System.Reflection; 5 | using Microsoft.Xna.Framework; 6 | using Microsoft.Xna.Framework.Graphics; 7 | 8 | namespace SpriteFontPlus 9 | { 10 | public class TtfFontBakerResult 11 | { 12 | public Dictionary Glyphs 13 | { 14 | get; private set; 15 | } 16 | public float FontFontPixelHeight 17 | { 18 | get; private set; 19 | } 20 | public byte[] Pixels 21 | { 22 | get; private set; 23 | } 24 | public int Width 25 | { 26 | get; private set; 27 | } 28 | public int Height 29 | { 30 | get; private set; 31 | } 32 | 33 | public TtfFontBakerResult(Dictionary glyphs, 34 | float fontPixelHeight, 35 | byte[] pixels, 36 | int width, 37 | int height) 38 | { 39 | if (glyphs == null) 40 | { 41 | throw new ArgumentNullException(nameof(glyphs)); 42 | } 43 | 44 | if (fontPixelHeight <= 0) 45 | { 46 | throw new ArgumentOutOfRangeException(nameof(fontPixelHeight)); 47 | } 48 | 49 | if (pixels == null) 50 | { 51 | throw new ArgumentNullException(nameof(pixels)); 52 | } 53 | 54 | if (width <= 0) 55 | { 56 | throw new ArgumentOutOfRangeException(nameof(width)); 57 | } 58 | 59 | if (height <= 0) 60 | { 61 | throw new ArgumentOutOfRangeException(nameof(height)); 62 | } 63 | 64 | if (pixels.Length < width * height) 65 | { 66 | throw new ArgumentException("pixels.Length should be higher than width * height"); 67 | } 68 | 69 | Glyphs = glyphs; 70 | FontFontPixelHeight = fontPixelHeight; 71 | Pixels = pixels; 72 | Width = width; 73 | Height = height; 74 | } 75 | 76 | public SpriteFont CreateSpriteFont(GraphicsDevice graphicsDevice) 77 | { 78 | var rgb = new Color[Width * Height]; 79 | for (var i = 0; i < Pixels.Length; ++i) 80 | { 81 | var b = Pixels[i]; 82 | rgb[i].R = b; 83 | rgb[i].G = b; 84 | rgb[i].B = b; 85 | 86 | rgb[i].A = b; 87 | } 88 | 89 | var texture = new Texture2D(graphicsDevice, Width, Height); 90 | texture.SetData(rgb); 91 | 92 | var glyphBounds = new List(); 93 | var cropping = new List(); 94 | var chars = new List(); 95 | var kerning = new List(); 96 | 97 | var orderedKeys = Glyphs.Keys.OrderBy(a => a); 98 | foreach (var key in orderedKeys) 99 | { 100 | var character = Glyphs[key]; 101 | 102 | var bounds = new Rectangle(character.X, character.Y, 103 | character.Width, 104 | character.Height); 105 | 106 | glyphBounds.Add(bounds); 107 | cropping.Add(new Rectangle((int)character.XOffset, 108 | character.YOffset, 109 | bounds.Width, bounds.Height)); 110 | 111 | chars.Add((char)key); 112 | 113 | kerning.Add(new Vector3(0, bounds.Width, character.XAdvance - bounds.Width)); 114 | } 115 | 116 | var constructorInfo = typeof(SpriteFont).GetTypeInfo().DeclaredConstructors.First(); 117 | var font = (SpriteFont)constructorInfo.Invoke(new object[] 118 | { 119 | texture, glyphBounds, cropping, 120 | chars, (int)FontFontPixelHeight, 0, kerning, ' ' 121 | }); 122 | 123 | return font; 124 | } 125 | } 126 | } -------------------------------------------------------------------------------- /src/TtfFontBaker.cs: -------------------------------------------------------------------------------- 1 | using StbTrueTypeSharp; 2 | using System; 3 | using System.Collections.Generic; 4 | using System.IO; 5 | using System.Linq; 6 | 7 | namespace SpriteFontPlus 8 | { 9 | public static class TtfFontBaker 10 | { 11 | public static TtfFontBakerResult Bake(Stream ttfStream, float fontPixelHeight, 12 | int bitmapWidth, int bitmapHeight, 13 | IEnumerable characterRanges) 14 | { 15 | return Bake(ttfStream.ToByteArray(), fontPixelHeight, bitmapWidth, bitmapHeight, characterRanges); 16 | } 17 | 18 | public unsafe static TtfFontBakerResult Bake(byte[] ttf, float fontPixelHeight, 19 | int bitmapWidth, int bitmapHeight, 20 | IEnumerable characterRanges) 21 | { 22 | if (ttf == null || ttf.Length == 0) 23 | { 24 | throw new ArgumentNullException(nameof(ttf)); 25 | } 26 | 27 | if (fontPixelHeight <= 0) 28 | { 29 | throw new ArgumentOutOfRangeException(nameof(fontPixelHeight)); 30 | } 31 | 32 | if (bitmapWidth <= 0) 33 | { 34 | throw new ArgumentOutOfRangeException(nameof(bitmapWidth)); 35 | } 36 | 37 | if (bitmapHeight <= 0) 38 | { 39 | throw new ArgumentOutOfRangeException(nameof(bitmapHeight)); 40 | } 41 | 42 | if (characterRanges == null) 43 | { 44 | throw new ArgumentNullException(nameof(characterRanges)); 45 | } 46 | 47 | if (!characterRanges.Any()) 48 | { 49 | throw new ArgumentException("characterRanges must have a least one value."); 50 | } 51 | 52 | byte[] pixels; 53 | var glyphs = new Dictionary(); 54 | StbTrueType.stbtt_fontinfo fontInfo = new StbTrueType.stbtt_fontinfo(); 55 | fixed (byte* ttfPtr = ttf) 56 | { 57 | if (StbTrueType.stbtt_InitFont(fontInfo, ttfPtr, 0) == 0) 58 | { 59 | throw new Exception("Failed to init font."); 60 | } 61 | } 62 | 63 | float scaleFactor = StbTrueType.stbtt_ScaleForPixelHeight(fontInfo, fontPixelHeight); 64 | 65 | int ascent, descent, lineGap; 66 | StbTrueType.stbtt_GetFontVMetrics(fontInfo, &ascent, &descent, &lineGap); 67 | 68 | pixels = new byte[bitmapWidth * bitmapHeight]; 69 | StbTrueType.stbtt_pack_context pc = new StbTrueType.stbtt_pack_context(); 70 | 71 | fixed (byte* ttfPtr = ttf) 72 | fixed (byte* pixelsPtr = pixels) 73 | { 74 | StbTrueType.stbtt_PackBegin(pc, pixelsPtr, bitmapWidth, 75 | bitmapHeight, bitmapWidth, 1, null); 76 | 77 | foreach (var range in characterRanges) 78 | { 79 | if (range.Start > range.End) 80 | { 81 | continue; 82 | } 83 | 84 | var cd = new StbTrueType.stbtt_packedchar[range.End - range.Start + 1]; 85 | for (var i = 0; i < cd.Length; ++i) 86 | { 87 | cd[i] = new StbTrueType.stbtt_packedchar(); 88 | } 89 | 90 | fixed (StbTrueType.stbtt_packedchar* cdPtr = cd) 91 | { 92 | StbTrueType.stbtt_PackFontRange(pc, ttfPtr, 0, fontPixelHeight, 93 | range.Start, 94 | range.End - range.Start + 1, 95 | cdPtr); 96 | } 97 | 98 | for (var i = 0; i < cd.Length; ++i) 99 | { 100 | var yOff = cd[i].yoff; 101 | yOff += ascent * scaleFactor; 102 | 103 | var glyphInfo = new GlyphInfo 104 | { 105 | X = cd[i].x0, 106 | Y = cd[i].y0, 107 | Width = cd[i].x1 - cd[i].x0, 108 | Height = cd[i].y1 - cd[i].y0, 109 | XOffset = (int)cd[i].xoff, 110 | YOffset = (int)Math.Round(yOff), 111 | XAdvance = (int)Math.Round(cd[i].xadvance) 112 | }; 113 | 114 | glyphs[(char)(i + range.Start)] = glyphInfo; 115 | } 116 | } 117 | } 118 | 119 | 120 | return new TtfFontBakerResult(glyphs, fontPixelHeight, pixels, bitmapWidth, bitmapHeight); 121 | } 122 | } 123 | } -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.TtfBaking/Game1.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.IO; 3 | using Microsoft.Xna.Framework; 4 | using Microsoft.Xna.Framework.Graphics; 5 | 6 | namespace SpriteFontPlus.Samples.TtfBaking 7 | { 8 | /// 9 | /// This is the main type for your game. 10 | /// 11 | public class Game1 : Game 12 | { 13 | private const int FontBitmapWidth = 1024; 14 | private const int FontBitmapHeight = 1024; 15 | 16 | GraphicsDeviceManager _graphics; 17 | SpriteBatch _spriteBatch; 18 | 19 | private SpriteFont _font, _fontJapanese; 20 | 21 | public Game1() 22 | { 23 | _graphics = new GraphicsDeviceManager(this) 24 | { 25 | }; 26 | 27 | Content.RootDirectory = "Content"; 28 | IsMouseVisible = true; 29 | Window.AllowUserResizing = true; 30 | } 31 | 32 | /// 33 | /// LoadContent will be called once per game and is the place to load 34 | /// all of your content. 35 | /// 36 | protected override void LoadContent() 37 | { 38 | // Create a new SpriteBatch, which can be used to draw textures. 39 | _spriteBatch = new SpriteBatch(GraphicsDevice); 40 | 41 | TtfFontBakerResult fontBakeResult; 42 | using (var stream = File.OpenRead("Fonts/DroidSans.ttf")) 43 | { 44 | // TODO: use this.Content to load your game content here 45 | fontBakeResult = TtfFontBaker.Bake(stream, 46 | 25, 47 | FontBitmapWidth, 48 | FontBitmapHeight, 49 | new[] 50 | { 51 | CharacterRange.BasicLatin, 52 | CharacterRange.Latin1Supplement, 53 | CharacterRange.LatinExtendedA, 54 | CharacterRange.Cyrillic 55 | } 56 | ); 57 | 58 | _font = fontBakeResult.CreateSpriteFont(GraphicsDevice); 59 | } 60 | 61 | fontBakeResult = TtfFontBaker.Bake(File.ReadAllBytes("Fonts/DroidSansJapanese.ttf"), 62 | 25, 63 | FontBitmapWidth, 64 | FontBitmapHeight, 65 | new[] 66 | { 67 | new CharacterRange(' '), 68 | CharacterRange.Hiragana, 69 | CharacterRange.Katakana 70 | } 71 | ); 72 | 73 | _fontJapanese = fontBakeResult.CreateSpriteFont(GraphicsDevice); 74 | 75 | GC.Collect(); 76 | } 77 | 78 | /// 79 | /// UnloadContent will be called once per game and is the place to unload 80 | /// game-specific content. 81 | /// 82 | protected override void UnloadContent() 83 | { 84 | // TODO: Unload any non ContentManager content here 85 | } 86 | 87 | /// 88 | /// This is called when the game should draw itself. 89 | /// 90 | /// Provides a snapshot of timing values. 91 | protected override void Draw(GameTime gameTime) 92 | { 93 | GraphicsDevice.Clear(Color.CornflowerBlue); 94 | 95 | // TODO: Add your drawing code here 96 | _spriteBatch.Begin(); 97 | 98 | // Render some text 99 | _spriteBatch.DrawString(_font, "The quick brown fox jumps over the lazy dog", 100 | new Vector2(0, 0), Color.White); 101 | _spriteBatch.DrawString(_font, "Üben quält finſteren Jagdſchloß höfliche Bäcker größeren, N: Blåbærsyltetøy", 102 | new Vector2(0, 30), Color.White); 103 | _spriteBatch.DrawString(_font, "Høj bly gom vandt fræk sexquiz på wc, S: bäckasiner söka", 104 | new Vector2(0, 60), Color.White); 105 | _spriteBatch.DrawString(_font, "Sævör grét áðan því úlpan var ónýt, P: Pchnąć w tę łódź jeża lub osiem skrzyń fig", 106 | new Vector2(0, 90), Color.White); 107 | _spriteBatch.DrawString(_font, "Příliš žluťoučký kůň úpěl ďábelské kódy, R: В чащах юга жил-был цитрус? Да, но фальшивый экземпляр! ёъ.", 108 | new Vector2(0, 120), Color.White); 109 | _spriteBatch.DrawString(_font, "kilómetros y frío, añoraba, P: vôo à noite, F: Les naïfs ægithales hâtifs pondant à Noël où", 110 | new Vector2(0, 150), Color.White); 111 | _spriteBatch.DrawString(_fontJapanese, "いろはにほへど", 112 | new Vector2(0, 180), Color.White); 113 | 114 | _spriteBatch.End(); 115 | 116 | base.Draw(gameTime); 117 | } 118 | } 119 | } -------------------------------------------------------------------------------- /src/BMFontLoader.cs: -------------------------------------------------------------------------------- 1 | using System; 2 | using System.Collections.Generic; 3 | using Cyotek.Drawing.BitmapFont; 4 | using System.Linq; 5 | using System.Reflection; 6 | 7 | using Microsoft.Xna.Framework; 8 | using Microsoft.Xna.Framework.Graphics; 9 | using System.IO; 10 | using StbImageSharp; 11 | 12 | namespace SpriteFontPlus 13 | { 14 | public class TextureWithOffset 15 | { 16 | public Texture2D Texture { get; set; } 17 | public Point Offset { get; set; } 18 | 19 | public TextureWithOffset(Texture2D texture) 20 | { 21 | if (texture == null) 22 | { 23 | throw new ArgumentNullException("texture"); 24 | } 25 | 26 | Texture = texture; 27 | } 28 | 29 | public TextureWithOffset(Texture2D texture, Point offset): this(texture) 30 | { 31 | Offset = offset; 32 | } 33 | } 34 | 35 | public static class BMFontLoader 36 | { 37 | private static SpriteFont Load(BitmapFont data, Func textureGetter) 38 | { 39 | if (data.Pages.Length > 1) 40 | { 41 | throw new NotSupportedException("For now only BMFonts with single texture are supported"); 42 | } 43 | 44 | var texture = textureGetter(data.Pages[0].FileName); 45 | 46 | var glyphBounds = new List(); 47 | var cropping = new List(); 48 | var chars = new List(); 49 | var kerning = new List(); 50 | 51 | var characters = data.Characters.Values.OrderBy(c => c.Char); 52 | foreach (var character in characters) 53 | { 54 | var bounds = new Rectangle(character.X, character.Y, character.Width, character.Height); 55 | 56 | bounds.Offset(texture.Offset); 57 | glyphBounds.Add(bounds); 58 | cropping.Add(new Rectangle(character.XOffset, character.YOffset, bounds.Width, bounds.Height)); 59 | 60 | chars.Add(character.Char); 61 | 62 | kerning.Add(new Vector3(0, character.Width, character.XAdvance - character.Width)); 63 | } 64 | 65 | var constructorInfo = typeof(SpriteFont).GetTypeInfo().DeclaredConstructors.First(); 66 | var result = (SpriteFont)constructorInfo.Invoke(new object[] 67 | { 68 | texture.Texture, glyphBounds, cropping, 69 | chars, data.LineHeight, 0, kerning, ' ' 70 | }); 71 | 72 | return result; 73 | } 74 | 75 | private static BitmapFont LoadBMFont(string data) 76 | { 77 | var bmFont = new BitmapFont(); 78 | if (data.StartsWith("<")) 79 | { 80 | // xml 81 | bmFont.LoadXml(data); 82 | } 83 | else 84 | { 85 | bmFont.LoadText(data); 86 | } 87 | 88 | return bmFont; 89 | } 90 | 91 | public static SpriteFont Load(string data, Func textureGetter) 92 | { 93 | var bmFont = LoadBMFont(data); 94 | 95 | return Load(bmFont, textureGetter); 96 | } 97 | 98 | public unsafe static SpriteFont Load(string data, Func imageStreamOpener, GraphicsDevice device) 99 | { 100 | var bmFont = LoadBMFont(data); 101 | 102 | var textures = new Dictionary(); 103 | for (var i = 0; i < bmFont.Pages.Length; ++i) 104 | { 105 | var fileName = bmFont.Pages[i].FileName; 106 | Stream stream = null; 107 | try 108 | { 109 | stream = imageStreamOpener(fileName); 110 | if (!stream.CanSeek) 111 | { 112 | // If stream isn't seekable, use MemoryStream instead 113 | var ms = new MemoryStream(); 114 | stream.CopyTo(ms); 115 | ms.Seek(0, SeekOrigin.Begin); 116 | stream.Dispose(); 117 | stream = ms; 118 | } 119 | 120 | var image = ImageResult.FromStream(stream, ColorComponents.RedGreenBlueAlpha); 121 | if (image.SourceComp == ColorComponents.Grey) 122 | { 123 | // If input image is single byte per pixel, then StbImageSharp will set alpha to 255 in the resulting 32-bit image 124 | // Such behavior isn't acceptable for us 125 | // So reset alpha to color value 126 | for (var j = 0; j < image.Data.Length / 4; ++j) 127 | { 128 | image.Data[j * 4 + 3] = image.Data[j * 4]; 129 | } 130 | } 131 | 132 | var texture = new Texture2D(device, image.Width, image.Height); 133 | var bounds = new Rectangle(0, 0, image.Width, image.Height); 134 | texture.SetData(0, bounds, image.Data, 0, bounds.Width * bounds.Height * 4); 135 | 136 | textures[fileName] = texture; 137 | } 138 | finally 139 | { 140 | stream.Dispose(); 141 | } 142 | } 143 | 144 | return Load(bmFont, fileName => new TextureWithOffset(textures[fileName])); 145 | } 146 | } 147 | } -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ## Ignore Visual Studio temporary files, build results, and 2 | ## files generated by popular Visual Studio add-ons. 3 | 4 | # User-specific files 5 | *.suo 6 | *.user 7 | *.userosscache 8 | *.sln.docstates 9 | 10 | # User-specific files (MonoDevelop/Xamarin Studio) 11 | *.userprefs 12 | 13 | # Build results 14 | [Dd]ebug/ 15 | [Dd]ebugPublic/ 16 | [Rr]elease/ 17 | [Rr]eleases/ 18 | x64/ 19 | x86/ 20 | bld/ 21 | [Bb]in/ 22 | [Oo]bj/ 23 | [Ll]og/ 24 | 25 | # Visual Studio 2015 cache/options directory 26 | .vs/ 27 | # Uncomment if you have tasks that create the project's static files in wwwroot 28 | #wwwroot/ 29 | 30 | # MSTest test Results 31 | [Tt]est[Rr]esult*/ 32 | [Bb]uild[Ll]og.* 33 | 34 | # NUNIT 35 | *.VisualState.xml 36 | TestResult.xml 37 | 38 | # Build Results of an ATL Project 39 | [Dd]ebugPS/ 40 | [Rr]eleasePS/ 41 | dlldata.c 42 | 43 | # DNX 44 | project.lock.json 45 | project.fragment.lock.json 46 | artifacts/ 47 | 48 | *_i.c 49 | *_p.c 50 | *_i.h 51 | *.ilk 52 | *.meta 53 | *.obj 54 | *.pch 55 | *.pdb 56 | *.pgc 57 | *.pgd 58 | *.rsp 59 | *.sbr 60 | *.tlb 61 | *.tli 62 | *.tlh 63 | *.tmp 64 | *.tmp_proj 65 | *.log 66 | *.vspscc 67 | *.vssscc 68 | .builds 69 | *.pidb 70 | *.svclog 71 | *.scc 72 | 73 | # Chutzpah Test files 74 | _Chutzpah* 75 | 76 | # Visual C++ cache files 77 | ipch/ 78 | *.aps 79 | *.ncb 80 | *.opendb 81 | *.opensdf 82 | *.sdf 83 | *.cachefile 84 | *.VC.db 85 | *.VC.VC.opendb 86 | 87 | # Visual Studio profiler 88 | *.psess 89 | *.vsp 90 | *.vspx 91 | *.sap 92 | 93 | # TFS 2012 Local Workspace 94 | $tf/ 95 | 96 | # Guidance Automation Toolkit 97 | *.gpState 98 | 99 | # ReSharper is a .NET coding add-in 100 | _ReSharper*/ 101 | *.[Rr]e[Ss]harper 102 | *.DotSettings.user 103 | 104 | # JustCode is a .NET coding add-in 105 | .JustCode 106 | 107 | # TeamCity is a build add-in 108 | _TeamCity* 109 | 110 | # DotCover is a Code Coverage Tool 111 | *.dotCover 112 | 113 | # NCrunch 114 | _NCrunch_* 115 | .*crunch*.local.xml 116 | nCrunchTemp_* 117 | 118 | # MightyMoose 119 | *.mm.* 120 | AutoTest.Net/ 121 | 122 | # Web workbench (sass) 123 | .sass-cache/ 124 | 125 | # Installshield output folder 126 | [Ee]xpress/ 127 | 128 | # DocProject is a documentation generator add-in 129 | DocProject/buildhelp/ 130 | DocProject/Help/*.HxT 131 | DocProject/Help/*.HxC 132 | DocProject/Help/*.hhc 133 | DocProject/Help/*.hhk 134 | DocProject/Help/*.hhp 135 | DocProject/Help/Html2 136 | DocProject/Help/html 137 | 138 | # Click-Once directory 139 | publish/ 140 | 141 | # Publish Web Output 142 | *.[Pp]ublish.xml 143 | *.azurePubxml 144 | # TODO: Comment the next line if you want to checkin your web deploy settings 145 | # but database connection strings (with potential passwords) will be unencrypted 146 | #*.pubxml 147 | *.publishproj 148 | 149 | # Microsoft Azure Web App publish settings. Comment the next line if you want to 150 | # checkin your Azure Web App publish settings, but sensitive information contained 151 | # in these scripts will be unencrypted 152 | PublishScripts/ 153 | 154 | # NuGet Packages 155 | *.nupkg 156 | # The packages folder can be ignored because of Package Restore 157 | **/packages/* 158 | # except build/, which is used as an MSBuild target. 159 | !**/packages/build/ 160 | # Uncomment if necessary however generally it will be regenerated when needed 161 | #!**/packages/repositories.config 162 | # NuGet v3's project.json files produces more ignoreable files 163 | *.nuget.props 164 | *.nuget.targets 165 | 166 | # Microsoft Azure Build Output 167 | csx/ 168 | *.build.csdef 169 | 170 | # Microsoft Azure Emulator 171 | ecf/ 172 | rcf/ 173 | 174 | # Windows Store app package directories and files 175 | AppPackages/ 176 | BundleArtifacts/ 177 | Package.StoreAssociation.xml 178 | _pkginfo.txt 179 | 180 | # Visual Studio cache files 181 | # files ending in .cache can be ignored 182 | *.[Cc]ache 183 | # but keep track of directories ending in .cache 184 | !*.[Cc]ache/ 185 | 186 | # Others 187 | ClientBin/ 188 | ~$* 189 | *~ 190 | *.dbmdl 191 | *.dbproj.schemaview 192 | *.jfm 193 | *.pfx 194 | *.publishsettings 195 | node_modules/ 196 | orleans.codegen.cs 197 | 198 | # Since there are multiple workflows, uncomment next line to ignore bower_components 199 | # (https://github.com/github/gitignore/pull/1529#issuecomment-104372622) 200 | #bower_components/ 201 | 202 | # RIA/Silverlight projects 203 | Generated_Code/ 204 | 205 | # Backup & report files from converting an old project file 206 | # to a newer Visual Studio version. Backup files are not needed, 207 | # because we have git ;-) 208 | _UpgradeReport_Files/ 209 | Backup*/ 210 | UpgradeLog*.XML 211 | UpgradeLog*.htm 212 | 213 | # SQL Server files 214 | *.mdf 215 | *.ldf 216 | 217 | # Business Intelligence projects 218 | *.rdl.data 219 | *.bim.layout 220 | *.bim_*.settings 221 | 222 | # Microsoft Fakes 223 | FakesAssemblies/ 224 | 225 | # GhostDoc plugin setting file 226 | *.GhostDoc.xml 227 | 228 | # Node.js Tools for Visual Studio 229 | .ntvs_analysis.dat 230 | 231 | # Visual Studio 6 build log 232 | *.plg 233 | 234 | # Visual Studio 6 workspace options file 235 | *.opt 236 | 237 | # Visual Studio LightSwitch build output 238 | **/*.HTMLClient/GeneratedArtifacts 239 | **/*.DesktopClient/GeneratedArtifacts 240 | **/*.DesktopClient/ModelManifest.xml 241 | **/*.Server/GeneratedArtifacts 242 | **/*.Server/ModelManifest.xml 243 | _Pvt_Extensions 244 | 245 | # Paket dependency manager 246 | .paket/paket.exe 247 | paket-files/ 248 | 249 | # FAKE - F# Make 250 | .fake/ 251 | 252 | # JetBrains Rider 253 | .idea/ 254 | *.sln.iml 255 | 256 | # CodeRush 257 | .cr/ 258 | 259 | # Python Tools for Visual Studio (PTVS) 260 | __pycache__/ 261 | *.pyc -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.TtfBaking/Fonts/LICENSE.txt: -------------------------------------------------------------------------------- 1 | 2 | Apache License 3 | Version 2.0, January 2004 4 | http://www.apache.org/licenses/ 5 | 6 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION 7 | 8 | 1. Definitions. 9 | 10 | "License" shall mean the terms and conditions for use, reproduction, 11 | and distribution as defined by Sections 1 through 9 of this document. 12 | 13 | "Licensor" shall mean the copyright owner or entity authorized by 14 | the copyright owner that is granting the License. 15 | 16 | "Legal Entity" shall mean the union of the acting entity and all 17 | other entities that control, are controlled by, or are under common 18 | control with that entity. For the purposes of this definition, 19 | "control" means (i) the power, direct or indirect, to cause the 20 | direction or management of such entity, whether by contract or 21 | otherwise, or (ii) ownership of fifty percent (50%) or more of the 22 | outstanding shares, or (iii) beneficial ownership of such entity. 23 | 24 | "You" (or "Your") shall mean an individual or Legal Entity 25 | exercising permissions granted by this License. 26 | 27 | "Source" form shall mean the preferred form for making modifications, 28 | including but not limited to software source code, documentation 29 | source, and configuration files. 30 | 31 | "Object" form shall mean any form resulting from mechanical 32 | transformation or translation of a Source form, including but 33 | not limited to compiled object code, generated documentation, 34 | and conversions to other media types. 35 | 36 | "Work" shall mean the work of authorship, whether in Source or 37 | Object form, made available under the License, as indicated by a 38 | copyright notice that is included in or attached to the work 39 | (an example is provided in the Appendix below). 40 | 41 | "Derivative Works" shall mean any work, whether in Source or Object 42 | form, that is based on (or derived from) the Work and for which the 43 | editorial revisions, annotations, elaborations, or other modifications 44 | represent, as a whole, an original work of authorship. For the purposes 45 | of this License, Derivative Works shall not include works that remain 46 | separable from, or merely link (or bind by name) to the interfaces of, 47 | the Work and Derivative Works thereof. 48 | 49 | "Contribution" shall mean any work of authorship, including 50 | the original version of the Work and any modifications or additions 51 | to that Work or Derivative Works thereof, that is intentionally 52 | submitted to Licensor for inclusion in the Work by the copyright owner 53 | or by an individual or Legal Entity authorized to submit on behalf of 54 | the copyright owner. For the purposes of this definition, "submitted" 55 | means any form of electronic, verbal, or written communication sent 56 | to the Licensor or its representatives, including but not limited to 57 | communication on electronic mailing lists, source code control systems, 58 | and issue tracking systems that are managed by, or on behalf of, the 59 | Licensor for the purpose of discussing and improving the Work, but 60 | excluding communication that is conspicuously marked or otherwise 61 | designated in writing by the copyright owner as "Not a Contribution." 62 | 63 | "Contributor" shall mean Licensor and any individual or Legal Entity 64 | on behalf of whom a Contribution has been received by Licensor and 65 | subsequently incorporated within the Work. 66 | 67 | 2. Grant of Copyright License. Subject to the terms and conditions of 68 | this License, each Contributor hereby grants to You a perpetual, 69 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 70 | copyright license to reproduce, prepare Derivative Works of, 71 | publicly display, publicly perform, sublicense, and distribute the 72 | Work and such Derivative Works in Source or Object form. 73 | 74 | 3. Grant of Patent License. Subject to the terms and conditions of 75 | this License, each Contributor hereby grants to You a perpetual, 76 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable 77 | (except as stated in this section) patent license to make, have made, 78 | use, offer to sell, sell, import, and otherwise transfer the Work, 79 | where such license applies only to those patent claims licensable 80 | by such Contributor that are necessarily infringed by their 81 | Contribution(s) alone or by combination of their Contribution(s) 82 | with the Work to which such Contribution(s) was submitted. If You 83 | institute patent litigation against any entity (including a 84 | cross-claim or counterclaim in a lawsuit) alleging that the Work 85 | or a Contribution incorporated within the Work constitutes direct 86 | or contributory patent infringement, then any patent licenses 87 | granted to You under this License for that Work shall terminate 88 | as of the date such litigation is filed. 89 | 90 | 4. Redistribution. You may reproduce and distribute copies of the 91 | Work or Derivative Works thereof in any medium, with or without 92 | modifications, and in Source or Object form, provided that You 93 | meet the following conditions: 94 | 95 | (a) You must give any other recipients of the Work or 96 | Derivative Works a copy of this License; and 97 | 98 | (b) You must cause any modified files to carry prominent notices 99 | stating that You changed the files; and 100 | 101 | (c) You must retain, in the Source form of any Derivative Works 102 | that You distribute, all copyright, patent, trademark, and 103 | attribution notices from the Source form of the Work, 104 | excluding those notices that do not pertain to any part of 105 | the Derivative Works; and 106 | 107 | (d) If the Work includes a "NOTICE" text file as part of its 108 | distribution, then any Derivative Works that You distribute must 109 | include a readable copy of the attribution notices contained 110 | within such NOTICE file, excluding those notices that do not 111 | pertain to any part of the Derivative Works, in at least one 112 | of the following places: within a NOTICE text file distributed 113 | as part of the Derivative Works; within the Source form or 114 | documentation, if provided along with the Derivative Works; or, 115 | within a display generated by the Derivative Works, if and 116 | wherever such third-party notices normally appear. The contents 117 | of the NOTICE file are for informational purposes only and 118 | do not modify the License. You may add Your own attribution 119 | notices within Derivative Works that You distribute, alongside 120 | or as an addendum to the NOTICE text from the Work, provided 121 | that such additional attribution notices cannot be construed 122 | as modifying the License. 123 | 124 | You may add Your own copyright statement to Your modifications and 125 | may provide additional or different license terms and conditions 126 | for use, reproduction, or distribution of Your modifications, or 127 | for any such Derivative Works as a whole, provided Your use, 128 | reproduction, and distribution of the Work otherwise complies with 129 | the conditions stated in this License. 130 | 131 | 5. Submission of Contributions. Unless You explicitly state otherwise, 132 | any Contribution intentionally submitted for inclusion in the Work 133 | by You to the Licensor shall be under the terms and conditions of 134 | this License, without any additional terms or conditions. 135 | Notwithstanding the above, nothing herein shall supersede or modify 136 | the terms of any separate license agreement you may have executed 137 | with Licensor regarding such Contributions. 138 | 139 | 6. Trademarks. This License does not grant permission to use the trade 140 | names, trademarks, service marks, or product names of the Licensor, 141 | except as required for reasonable and customary use in describing the 142 | origin of the Work and reproducing the content of the NOTICE file. 143 | 144 | 7. Disclaimer of Warranty. Unless required by applicable law or 145 | agreed to in writing, Licensor provides the Work (and each 146 | Contributor provides its Contributions) on an "AS IS" BASIS, 147 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or 148 | implied, including, without limitation, any warranties or conditions 149 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A 150 | PARTICULAR PURPOSE. You are solely responsible for determining the 151 | appropriateness of using or redistributing the Work and assume any 152 | risks associated with Your exercise of permissions under this License. 153 | 154 | 8. Limitation of Liability. In no event and under no legal theory, 155 | whether in tort (including negligence), contract, or otherwise, 156 | unless required by applicable law (such as deliberate and grossly 157 | negligent acts) or agreed to in writing, shall any Contributor be 158 | liable to You for damages, including any direct, indirect, special, 159 | incidental, or consequential damages of any character arising as a 160 | result of this License or out of the use or inability to use the 161 | Work (including but not limited to damages for loss of goodwill, 162 | work stoppage, computer failure or malfunction, or any and all 163 | other commercial damages or losses), even if such Contributor 164 | has been advised of the possibility of such damages. 165 | 166 | 9. Accepting Warranty or Additional Liability. While redistributing 167 | the Work or Derivative Works thereof, You may choose to offer, 168 | and charge a fee for, acceptance of support, warranty, indemnity, 169 | or other liability obligations and/or rights consistent with this 170 | License. However, in accepting such obligations, You may act only 171 | on Your own behalf and on Your sole responsibility, not on behalf 172 | of any other Contributor, and only if You agree to indemnify, 173 | defend, and hold each Contributor harmless for any liability 174 | incurred by, or claims asserted against, such Contributor by reason 175 | of your accepting any such warranty or additional liability. 176 | 177 | END OF TERMS AND CONDITIONS 178 | 179 | APPENDIX: How to apply the Apache License to your work. 180 | 181 | To apply the Apache License to your work, attach the following 182 | boilerplate notice, with the fields enclosed by brackets "[]" 183 | replaced with your own identifying information. (Don't include 184 | the brackets!) The text should be enclosed in the appropriate 185 | comment syntax for the file format. We also recommend that a 186 | file or class name and description of purpose be included on the 187 | same "printed page" as the copyright notice for easier 188 | identification within third-party archives. 189 | 190 | Copyright [yyyy] [name of copyright owner] 191 | 192 | Licensed under the Apache License, Version 2.0 (the "License"); 193 | you may not use this file except in compliance with the License. 194 | You may obtain a copy of the License at 195 | 196 | http://www.apache.org/licenses/LICENSE-2.0 197 | 198 | Unless required by applicable law or agreed to in writing, software 199 | distributed under the License is distributed on an "AS IS" BASIS, 200 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 201 | See the License for the specific language governing permissions and 202 | limitations under the License. 203 | -------------------------------------------------------------------------------- /samples/SpriteFontPlus.Samples.BMFont/Fonts/test.fnt: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | 22 | 23 | 24 | 25 | 26 | 27 | 28 | 29 | 30 | 31 | 32 | 33 | 34 | 35 | 36 | 37 | 38 | 39 | 40 | 41 | 42 | 43 | 44 | 45 | 46 | 47 | 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | 67 | 68 | 69 | 70 | 71 | 72 | 73 | 74 | 75 | 76 | 77 | 78 | 79 | 80 | 81 | 82 | 83 | 84 | 85 | 86 | 87 | 88 | 89 | 90 | 91 | 92 | 93 | 94 | 95 | 96 | 97 | 98 | 99 | 100 | 101 | 102 | 103 | 104 | 105 | 106 | 107 | 108 | 109 | 110 | 111 | 112 | 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | 121 | 122 | 123 | 124 | 125 | 126 | 127 | 128 | 129 | 130 | 131 | 132 | 133 | 134 | 135 | 136 | 137 | 138 | 139 | 140 | 141 | 142 | 143 | 144 | 145 | 146 | 147 | 148 | 149 | 150 | 151 | 152 | 153 | 154 | 155 | 156 | 157 | 158 | 159 | 160 | 161 | 162 | 163 | 164 | 165 | 166 | 167 | 168 | 169 | 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | 178 | 179 | 180 | 181 | 182 | 183 | 184 | 185 | 186 | 187 | 188 | 189 | 190 | 191 | 192 | 193 | 194 | 195 | 196 | 197 | 198 | 199 | 200 | 201 | 202 | 203 | 204 | 205 | 206 | 207 | 208 | 209 | 210 | 211 | 212 | 213 | 214 | 215 | 216 | 217 | 218 | 219 | 220 | 221 | 222 | 223 | 224 | 225 | 226 | 227 | 228 | 229 | 230 | 231 | 232 | 233 | 234 | 235 | 236 | 237 | 238 | 239 | 240 | 241 | 242 | 243 | 244 | 245 | 246 | 247 | 248 | 249 | 250 | 251 | 252 | 253 | 254 | 255 | 256 | 257 | 258 | 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | 269 | 270 | 271 | 272 | 273 | 274 | 275 | 276 | 277 | 278 | 279 | 280 | 281 | 282 | 283 | 284 | 285 | 286 | 287 | 288 | 289 | 290 | 291 | 292 | 293 | 294 | 295 | --------------------------------------------------------------------------------