3 #pragma warning disable 162 // Unreachable code detected (due to useCacheFonts)
4 using System.Collections.Generic;
7 using System.Threading.Tasks;
9 using SharpDX.DirectWrite;
11 using SiliconStudio.Assets;
12 using SiliconStudio.Assets.Compiler;
13 using SiliconStudio.BuildEngine;
14 using SiliconStudio.Core.IO;
15 using SiliconStudio.Core.Serialization;
16 using SiliconStudio.Core.Serialization.Assets;
17 using SiliconStudio.Paradox.Assets.SpriteFont.Compiler;
18 using SiliconStudio.Paradox.Graphics;
35 var assetDirectory = assetAbsolutePath.GetParent();
36 fontPathOnDisk = UPath.Combine(assetDirectory, asset.Source);
37 if (!
File.Exists(fontPathOnDisk))
39 result.Error(
"The font source '{0}' does not exist on the PC.", asset.FontName);
43 asset.FontName = fontPathOnDisk.GetFileName();
47 fontPathOnDisk = GetFontPath(asset, result);
48 if (fontPathOnDisk == null)
50 result.Error(
"The font named '{0}' could not be located on the PC.", asset.FontName);
54 var fontImportLocation = FontHelper.GetFontPath(asset.FontName, asset.Style);
59 new DynamicFontCommand(urlInStorage, asset)
66 var assetDirectory = assetAbsolutePath.GetParent();
67 assetClone.Source = asset.Source != null? UPath.Combine(assetDirectory, asset.Source): null;
68 assetClone.CharacterSet = asset.CharacterSet != null ? UPath.Combine(assetDirectory, asset.CharacterSet): null;
70 result.BuildSteps =
new ListBuildStep {
new StaticFontCommand(urlInStorage, assetAbsolutePath, assetClone) };
74 internal class StaticFontCommand :
AssetCommand<SpriteFontAsset>
76 private readonly
UFile assetAbsolutePath;
79 : base(url, description)
81 this.assetAbsolutePath = assetAbsolutePath;
86 foreach (var inputFile
in base.GetInputFiles())
88 yield
return inputFile;
91 if(
File.Exists(asset.CharacterSet))
97 const bool useCacheFonts =
false;
100 var cachedImagePath = assetAbsolutePath.GetFileName() +
".CachedImage";
101 var cachedFontGlyphs = assetAbsolutePath.GetFileName() +
".CachedGlyphs";
107 data = FontCompiler.Compile(asset);
109 catch (FontNotFoundException ex)
113 commandContext.Logger.Error(
"Font [{0}] was not found on this machine.", ex.FontName);
114 return Task.FromResult(ResultStatus.Failed);
119 commandContext.Logger.Warning(
"Font [{0}] was not found on this machine. Trying to use cached glyphs/image", ex.FontName);
120 if (!
File.Exists(cachedFontGlyphs))
122 commandContext.Logger.Error(
"Expecting cached glyphs [{0}]", cachedFontGlyphs);
123 return Task.FromResult(ResultStatus.Failed);
126 if (!
File.Exists(cachedImagePath))
128 commandContext.Logger.Error(
"Expecting cached image [{0}]", cachedImagePath);
129 return Task.FromResult(ResultStatus.Failed);
133 using (var glyphStream = File.OpenRead(cachedFontGlyphs))
138 using (var imageStream = File.OpenRead(cachedImagePath))
139 data.Bitmaps[0].Value = Image.Load(imageStream);
144 if (data == null || data.Bitmaps.Length == 0)
145 return Task.FromResult(ResultStatus.Failed);
148 var imageUrl =
Url +
"__image";
149 data.Bitmaps[0].Location = imageUrl;
151 assetManager.Save(
Url, data);
153 var image = data.Bitmaps[0].Value;
161 using (var imageStream = File.OpenWrite(cachedImagePath))
162 image.Save(imageStream, ImageFileType.Paradox);
166 using (var glyphStream = File.OpenWrite(cachedFontGlyphs))
167 BinarySerialization.Write(glyphStream, data);
169 catch (IOException ex)
171 commandContext.Logger.Warning(
"Cannot save cached glyphs [{0}] or image [{1}]", ex, cachedFontGlyphs, cachedImagePath);
178 return Task.FromResult(ResultStatus.Successful);
184 using (var factory =
new Factory())
188 using (var fontCollection = factory.GetSystemFontCollection(
false))
191 if (!fontCollection.FindFamilyName(asset.FontName, out index))
193 result.Error(
"Can't find font '{0}'.", asset.FontName);
197 using (var fontFamily = fontCollection.GetFontFamily(index))
199 var weight = FontWeight.Regular;
200 var style = SharpDX.DirectWrite.FontStyle.Normal;
204 weight = FontWeight.Bold;
206 case FontStyle.Italic:
207 weight = FontWeight.Regular;
208 style = SharpDX.DirectWrite.FontStyle.Italic;
210 case FontStyle.Regular:
211 weight = FontWeight.Regular;
215 font = fontFamily.GetFirstMatchingFont(weight, FontStretch.Normal, style);
218 result.Error(
"Cannot find style '{0}' for font family {1}.", asset.Style, asset.FontName);
224 var fontFace =
new FontFace(font);
227 var file = fontFace.GetFiles().
First();
228 var referenceKey = file.GetReferenceKey();
229 var originalLoader = (FontFileLoaderNative)file.Loader;
230 var loader = originalLoader.QueryInterface<LocalFontFileLoader>();
231 return loader.GetFilePath(referenceKey);
235 internal class DynamicFontCommand :
AssetCommand<SpriteFontAsset>
237 public DynamicFontCommand(
string url, SpriteFontAsset description)
238 : base(url, description)
246 Size = FontHelper.PointsToPixels(asset.Size),
248 FontName = asset.FontName,
249 ExtraLineSpacing = asset.LineSpacing,
250 DefaultSize = asset.Size,
251 ExtraSpacing = asset.Spacing,
253 UseKerning = asset.UseKerning,
254 AntiAlias = asset.AntiAlias,
258 assetManager.Save(Url, dynamicFont);
260 return Task.FromResult(ResultStatus.Successful);
Result of a compilation of assets when using IAssetCompiler.Compile
bool IsDynamic
Determine if the characters are pre-generated off-line or at run-time.
SharpDX.DirectWrite.Factory Factory
char DefaultCharacter
The default character fall-back.
Data for a dynamic SpriteFont object.
override void Compile(AssetCompilerContext context, string urlInStorage, UFile assetAbsolutePath, SpriteFontAsset asset, AssetCompilerResult result)
A command processing an Asset.
The context used when compiling an asset in a Package.
SharpDX.DirectWrite.Font Font
SpriteFont to use with SpriteBatch. See SpriteFont to learn how to use it.
object Clone()
Clones the current value of this cloner with the specified new shadow registry (optional) ...
UFile Source
Gets or sets the source file containing the font data if required.
Data for a static SpriteFont object that supports kerning.
SiliconStudio.Paradox.Graphics.Font.FontStyle FontStyle
Allows to clone an asset or values stored in an asset.
Defines a normalized file path. See UPath for details. This class cannot be inherited.