Paradox Game Engine  v1.0.0 beta06
 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Events Macros Pages
FontCompiler.cs
Go to the documentation of this file.
1 // Copyright (c) 2014 Silicon Studio Corp. (http://siliconstudio.co.jp)
2 // This file is distributed under GPL v3. See LICENSE.md for details.
3 //
4 // Copyright (c) 2010-2013 SharpDX - Alexandre Mutel
5 //
6 // Permission is hereby granted, free of charge, to any person obtaining a copy
7 // of this software and associated documentation files (the "Software"), to deal
8 // in the Software without restriction, including without limitation the rights
9 // to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10 // copies of the Software, and to permit persons to whom the Software is
11 // furnished to do so, subject to the following conditions:
12 //
13 // The above copyright notice and this permission notice shall be included in
14 // all copies or substantial portions of the Software.
15 //
16 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17 // IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18 // FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19 // AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20 // LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21 // OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22 // THE SOFTWARE.
23 // -----------------------------------------------------------------------------
24 // The following code is a port of MakeSpriteFont from DirectXTk
25 // http://go.microsoft.com/fwlink/?LinkId=248929
26 // -----------------------------------------------------------------------------
27 // Microsoft Public License (Ms-PL)
28 //
29 // This license governs use of the accompanying software. If you use the
30 // software, you accept this license. If you do not accept the license, do not
31 // use the software.
32 //
33 // 1. Definitions
34 // The terms "reproduce," "reproduction," "derivative works," and
35 // "distribution" have the same meaning here as under U.S. copyright law.
36 // A "contribution" is the original software, or any additions or changes to
37 // the software.
38 // A "contributor" is any person that distributes its contribution under this
39 // license.
40 // "Licensed patents" are a contributor's patent claims that read directly on
41 // its contribution.
42 //
43 // 2. Grant of Rights
44 // (A) Copyright Grant- Subject to the terms of this license, including the
45 // license conditions and limitations in section 3, each contributor grants
46 // you a non-exclusive, worldwide, royalty-free copyright license to reproduce
47 // its contribution, prepare derivative works of its contribution, and
48 // distribute its contribution or any derivative works that you create.
49 // (B) Patent Grant- Subject to the terms of this license, including the license
50 // conditions and limitations in section 3, each contributor grants you a
51 // non-exclusive, worldwide, royalty-free license under its licensed patents to
52 // make, have made, use, sell, offer for sale, import, and/or otherwise dispose
53 // of its contribution in the software or derivative works of the contribution
54 // in the software.
55 //
56 // 3. Conditions and Limitations
57 // (A) No Trademark License- This license does not grant you rights to use any
58 // contributors' name, logo, or trademarks.
59 // (B) If you bring a patent claim against any contributor over patents that
60 // you claim are infringed by the software, your patent license from such
61 // contributor to the software ends automatically.
62 // (C) If you distribute any portion of the software, you must retain all
63 // copyright, patent, trademark, and attribution notices that are present in the
64 // software.
65 // (D) If you distribute any portion of the software in source code form, you
66 // may do so only under this license by including a complete copy of this
67 // license with your distribution. If you distribute any portion of the software
68 // in compiled or object code form, you may only do so under a license that
69 // complies with this license.
70 // (E) The software is licensed "as-is." You bear the risk of using it. The
71 // contributors give no express warranties, guarantees or conditions. You may
72 // have additional consumer rights under your local laws which this license
73 // cannot change. To the extent permitted under your local laws, the
74 // contributors exclude the implied warranties of merchantability, fitness for a
75 // particular purpose and non-infringement.
76 //--------------------------------------------------------------------
77 
78 using System;
79 using System.Collections.Generic;
80 using System.Drawing;
81 using System.IO;
82 using System.Text;
83 
84 using SiliconStudio.Paradox.Graphics;
86 
87 using System.Linq;
88 
89 namespace SiliconStudio.Paradox.Assets.SpriteFont.Compiler
90 {
91  /// <summary>
92  /// Main class used to compile a Font file XML file.
93  /// </summary>
94  public class FontCompiler
95  {
96  /// <summary>
97  /// Compiles the specified font description into a <see cref="SpriteFontData" /> object.
98  /// </summary>
99  /// <param name="fontAsset">The font description.</param>
100  /// <returns>A SpriteFontData object.</returns>
102  {
103  float lineSpacing;
104  float baseLine;
105 
106  Glyph[] glyphs = ImportFont(fontAsset, out lineSpacing, out baseLine);
107 
108  // Optimize.
109  foreach (Glyph glyph in glyphs)
110  GlyphCropper.Crop(glyph);
111 
112  Bitmap bitmap = GlyphPacker.ArrangeGlyphs(glyphs);
113 
114  // Automatically detect whether this is a monochromatic or color font?
115  //if (fontAsset.Format == FontTextureFormat.Auto)
116  //{
117  // bool isMono = BitmapUtils.IsRgbEntirely(Color.White, bitmap);
118  //
119  // fontAsset.Format = isMono ? FontTextureFormat.CompressedMono :
120  // FontTextureFormat.Rgba32;
121  //}
122 
123  // Convert to premultiplied alpha format.
124  if (!fontAsset.NoPremultiply)
125  {
126  if (fontAsset.AntiAlias == FontAntiAliasMode.ClearType)
127  {
128  BitmapUtils.PremultiplyAlphaClearType(bitmap);
129  }
130  else
131  {
132  BitmapUtils.PremultiplyAlpha(bitmap);
133  }
134  }
135 
136  return SpriteFontWriter.CreateSpriteFontData(fontAsset, glyphs, lineSpacing, baseLine, bitmap);
137  }
138 
139  static Glyph[] ImportFont(SpriteFontAsset options, out float lineSpacing, out float baseLine)
140  {
141  // Which importer knows how to read this source font?
142  IFontImporter importer;
143 
144  var sourceExtension = (Path.GetExtension(options.Source) ?? "").ToLowerInvariant();
145  var bitmapFileExtensions = new List<string> { ".bmp", ".png", ".gif" };
146  var importFromBitmap = bitmapFileExtensions.Contains(sourceExtension);
147 
148  importer = importFromBitmap ? (IFontImporter) new BitmapImporter() : new TrueTypeImporter();
149 
150  // create the list of character to import
151  var characters = GetCharactersToImport(options);
152 
153  // Import the source font data.
154  importer.Import(options, characters);
155 
156  lineSpacing = importer.LineSpacing;
157  baseLine = importer.BaseLine;
158 
159  // Get all glyphs
160  var glyphs = new List<Glyph>(importer.Glyphs);
161 
162  // Validate.
163  if (glyphs.Count == 0)
164  {
165  throw new Exception("Font does not contain any glyphs.");
166  }
167  if (!importFromBitmap && options.AntiAlias != FontAntiAliasMode.ClearType)
168  {
169  foreach (var glyph in importer.Glyphs)
170  BitmapUtils.ConvertGreyToAlpha(glyph.Bitmap, glyph.Subrect);
171  }
172 
173  // Sort the glyphs
174  glyphs.Sort((left, right) => left.Character.CompareTo(right.Character));
175 
176 
177  // Check that the default character is part of the glyphs
178  if (options.DefaultCharacter != 0)
179  {
180  bool defaultCharacterFound = false;
181  foreach (var glyph in glyphs)
182  {
183  if (glyph.Character == options.DefaultCharacter)
184  {
185  defaultCharacterFound = true;
186  break;
187  }
188  }
189  if (!defaultCharacterFound)
190  {
191  throw new InvalidOperationException("The specified DefaultCharacter is not part of this font.");
192  }
193  }
194 
195  return glyphs.ToArray();
196  }
197 
199  {
200  var characters = new List<char>();
201 
202  // extract the list from the provided file if it exits
203  if (File.Exists(asset.CharacterSet))
204  {
205  string text;
206  using (var streamReader = new StreamReader(asset.CharacterSet, Encoding.UTF8))
207  text = streamReader.ReadToEnd();
208  characters.AddRange(text);
209  }
210 
211  // add character coming from character ranges
212  characters.AddRange(CharacterRegion.Flatten(asset.CharacterRegions));
213 
214  // remove duplicated characters
215  characters = characters.Distinct().ToList();
216 
217  return characters;
218  }
219  }
220 }
static List< char > GetCharactersToImport(SpriteFontAsset asset)
System.Text.Encoding Encoding
SharpDX.DirectWrite.Font Font
System.IO.File File
SpriteFont to use with SpriteBatch. See SpriteFont to learn how to use it.
Definition: SpriteFont.cs:26
FontAntiAliasMode
Available antialias mode.
Main class used to compile a Font file XML file.
Definition: FontCompiler.cs:94
Data for a static SpriteFont object that supports kerning.
static StaticSpriteFontData Compile(SpriteFontAsset fontAsset)
Compiles the specified font description into a SpriteFontData object.
UFile CharacterSet
A text file referencing which characters to include when generating the static fonts (eg...