public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { var output = new SpriteFontContent(); // extract the glyphs from the texture and map them to a list of characters. // we need to call GtCharacterForIndex for each glyph in the Texture to // get the char for that glyph, by default we start at ' ' then '!' and then ASCII // after that. if (input._bitmap == null) { throw new ArgumentNullException("Texture Bitmap cannot be null"); } int linespacing = 0; var glyphs = ExtractGlyphs(input._bitmap, out linespacing); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); } var outputBitmap = GlyphPacker.ArrangeGlyphs(glyphs.ToArray(), true, true); //outputBitmap.Save ("fontglyphs.png"); foreach (Glyph glyph in glyphs) { glyph.XAdvance += linespacing; if (!output.CharacterMap.Contains(glyph.Character)) { output.CharacterMap.Add(glyph.Character); } output.Glyphs.Add(new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height)); output.Cropping.Add(new Rectangle(0, 0, glyph.Subrect.Width, glyph.Subrect.Height)); ABCFloat abc = glyph.CharacterWidths; output.Kerning.Add(new Vector3(abc.A, abc.B, abc.C)); } output.Texture._bitmap = outputBitmap; var bitmapContent = new PixelBitmapContent <Color> (outputBitmap.Width, outputBitmap.Height); bitmapContent.SetPixelData(outputBitmap.GetData()); output.Texture.Faces.Add(new MipmapChain(bitmapContent)); GraphicsUtil.CompressTexture(output.Texture, context, false, false); return(output); }
public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { var output = new SpriteFontContent(); // extract the glyphs from the texture and map them to a list of characters. // we need to call GtCharacterForIndex for each glyph in the Texture to // get the char for that glyph, by default we start at ' ' then '!' and then ASCII // after that. var systemBitmap = input.Faces[0][0].ToSystemBitmap(); int linespacing = 0; var glyphs = ExtractGlyphs(systemBitmap, out linespacing); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); } systemBitmap.Dispose(); systemBitmap = GlyphPacker.ArrangeGlyphs(glyphs.ToArray(), true, true); foreach (Glyph glyph in glyphs) { glyph.XAdvance += linespacing; if (!output.CharacterMap.Contains(glyph.Character)) { output.CharacterMap.Add(glyph.Character); } output.Glyphs.Add(new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height)); output.Cropping.Add(new Rectangle(0, 0, glyph.Subrect.Width, glyph.Subrect.Height)); ABCFloat abc = glyph.CharacterWidths; output.Kerning.Add(new Vector3(abc.A, abc.B, abc.C)); } output.Texture.Faces.Add(new MipmapChain(systemBitmap.ToXnaBitmap(true))); systemBitmap.Dispose(); GraphicsUtil.CompressTexture(context.TargetProfile, output.Texture, context, false, false, false); return(output); }
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context) { var output = new SpriteFontContent(input); var fontName = input.FontName; #if WINDOWS var windowsfolder = Environment.GetFolderPath(Environment.SpecialFolder.Windows); var fontDirectory = Path.Combine(windowsfolder, "Fonts"); fontName = FindFontFileFromFontName(fontName, fontDirectory); if (string.IsNullOrWhiteSpace(fontName)) { fontName = input.FontName; #endif var directory = Path.GetDirectoryName(input.Identity.SourceFilename); var directories = new string[] { directory, "/Library/Fonts", #if WINDOWS fontDirectory, #endif } ; foreach (var dir in directories) { if (File.Exists(Path.Combine(dir, fontName + ".ttf"))) { fontName += ".ttf"; directory = dir; break; } if (File.Exists(Path.Combine(dir, fontName + ".ttc"))) { fontName += ".ttc"; directory = dir; break; } if (File.Exists(Path.Combine(dir, fontName + ".otf"))) { fontName += ".otf"; directory = dir; break; } } fontName = Path.Combine(directory, fontName); #if WINDOWS } #endif context.Logger.LogMessage("Building Font {0}", fontName); try { if (!File.Exists(fontName)) { throw new Exception(string.Format("Could not load {0}", fontName)); } var lineSpacing = 0f; var glyphs = ImportFont(input, out lineSpacing, context, fontName); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); } Bitmap outputBitmap = GlyphPacker.ArrangeGlyphs(glyphs, true, true); //outputBitmap.Save ("/Users/Jimmy/Desktop/Cocos2D-XNAImages/fontglyphs.png"); // Adjust line and character spacing. lineSpacing += input.Spacing; foreach (Glyph glyph in glyphs) { glyph.XAdvance += input.Spacing; if (!output.CharacterMap.Contains(glyph.Character)) { output.CharacterMap.Add(glyph.Character); } output.Glyphs.Add(new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height)); output.Cropping.Add(new Rectangle(0, (int)(glyph.YOffset + glyphs.Select(x => x.YOffset).Max()), glyph.Subrect.Width, glyph.Subrect.Height)); ABCFloat abc = glyph.CharacterWidths; output.Kerning.Add(new Vector3(abc.A, abc.B, abc.C)); } // outputBitmap.Save("/Users/Jimmy/Desktop/Cocos2D-XNAImages/test.png"); output.Texture._bitmap = outputBitmap; var bitmapContent = new PixelBitmapContent <Color>(outputBitmap.Width, outputBitmap.Height); bitmapContent.SetPixelData(outputBitmap.GetData()); output.Texture.Faces.Add(new MipmapChain(bitmapContent)); GraphicsUtil.CompressTexture(output.Texture, context, false, false); } catch (Exception ex) { context.Logger.LogImportantMessage("{0}", ex.ToString()); } return(output); }
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context) { var output = new SpriteFontContent(input); var fontName = input.FontName; #if WINDOWS || LINUX #if WINDOWS var windowsfolder = Environment.GetFolderPath(Environment.SpecialFolder.Windows); var fontDirectory = Path.Combine(windowsfolder, "Fonts"); fontName = FindFontFileFromFontName(fontName, fontDirectory); #elif LINUX fontName = FindFontFileFromFontName(fontName, input.Style.ToString()); #endif if (string.IsNullOrWhiteSpace(fontName)) { fontName = input.FontName; #endif var directory = Path.GetDirectoryName(input.Identity.SourceFilename); List <string> directories = new List <string>(); directories.Add(directory); directories.Add("/Library/Fonts"); #if WINDOWS directories.Add(fontDirectory); #endif foreach (var dir in directories) { if (File.Exists(Path.Combine(dir, fontName + ".ttf"))) { fontName += ".ttf"; directory = dir; break; } if (File.Exists(Path.Combine(dir, fontName + ".ttc"))) { fontName += ".ttc"; directory = dir; break; } if (File.Exists(Path.Combine(dir, fontName + ".otf"))) { fontName += ".otf"; directory = dir; break; } } fontName = Path.Combine(directory, fontName); #if WINDOWS || LINUX } #endif context.Logger.LogMessage("Building Font {0}", fontName); try { if (!File.Exists(fontName)) { throw new Exception(string.Format("Could not load {0}", fontName)); } var lineSpacing = 0f; int yOffsetMin = 0; var glyphs = ImportFont(input, out lineSpacing, out yOffsetMin, context, fontName); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); } var compressed = TextureFormat == TextureProcessorOutputFormat.DxtCompressed || TextureFormat == TextureProcessorOutputFormat.Compressed; var systemBitmap = GlyphPacker.ArrangeGlyphs(glyphs, compressed, compressed); //systemBitmap.Save ("fontglyphs.png"); // Adjust line and character spacing. lineSpacing += input.Spacing; output.VerticalLineSpacing = (int)lineSpacing; foreach (var glyph in glyphs) { output.CharacterMap.Add(glyph.Character); var texRect = new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height); output.Glyphs.Add(texRect); var cropping = new Rectangle(0, (int)(glyph.YOffset - yOffsetMin), (int)glyph.XAdvance, output.VerticalLineSpacing); output.Cropping.Add(cropping); // Set the optional character kerning. if (input.UseKerning) { output.Kerning.Add(new Vector3(glyph.CharacterWidths.A, glyph.CharacterWidths.B, glyph.CharacterWidths.C)); } else { output.Kerning.Add(new Vector3(0, texRect.Width, 0)); } } output.Texture.Faces[0].Add(systemBitmap.ToXnaBitmap(true)); systemBitmap.Dispose(); if (compressed) { GraphicsUtil.CompressTexture(context.TargetProfile, output.Texture, context, false, true, true); } } catch (Exception ex) { context.Logger.LogImportantMessage("{0}", ex.ToString()); } return(output); }
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context) { var output = new SpriteFontContent(input); var fontName = input.FontName; #if WINDOWS || LINUX #if WINDOWS var windowsfolder = Environment.GetFolderPath(Environment.SpecialFolder.Windows); var fontDirectory = Path.Combine(windowsfolder, "Fonts"); fontName = FindFontFileFromFontName(fontName, fontDirectory); #elif LINUX fontName = FindFontFileFromFontName(fontName, input.Style.ToString()); #endif if (string.IsNullOrWhiteSpace(fontName)) { fontName = input.FontName; #endif var directory = Path.GetDirectoryName(input.Identity.SourceFilename); List <string> directories = new List <string>(); directories.Add(directory); directories.Add("/Library/Fonts"); #if WINDOWS directories.Add(fontDirectory); #endif foreach (var dir in directories) { if (File.Exists(Path.Combine(dir, fontName + ".ttf"))) { fontName += ".ttf"; directory = dir; break; } if (File.Exists(Path.Combine(dir, fontName + ".ttc"))) { fontName += ".ttc"; directory = dir; break; } if (File.Exists(Path.Combine(dir, fontName + ".otf"))) { fontName += ".otf"; directory = dir; break; } } fontName = Path.Combine(directory, fontName); #if WINDOWS || LINUX } #endif context.Logger.LogMessage("Building Font {0}", fontName); // Get the platform specific texture profile. var texProfile = TextureProfile.ForPlatform(context.TargetPlatform); try { if (!File.Exists(fontName)) { throw new Exception(string.Format("Could not load {0}", fontName)); } var lineSpacing = 0f; int yOffsetMin = 0; var glyphs = ImportFont(input, out lineSpacing, out yOffsetMin, context, fontName); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); } // We need to know how to pack the glyphs. bool requiresPot, requiresSquare; texProfile.Requirements(context, TextureFormat, out requiresPot, out requiresSquare); var face = GlyphPacker.ArrangeGlyphs(glyphs, requiresPot, requiresSquare); // Adjust line and character spacing. lineSpacing += input.Spacing; output.VerticalLineSpacing = (int)lineSpacing; foreach (var glyph in glyphs) { output.CharacterMap.Add(glyph.Character); var texRect = new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height); output.Glyphs.Add(texRect); var cropping = new Rectangle(0, (int)(glyph.YOffset - yOffsetMin), (int)glyph.XAdvance, output.VerticalLineSpacing); output.Cropping.Add(cropping); // Set the optional character kerning. if (input.UseKerning) { output.Kerning.Add(new Vector3(glyph.CharacterWidths.A, glyph.CharacterWidths.B, glyph.CharacterWidths.C)); } else { output.Kerning.Add(new Vector3(0, texRect.Width, 0)); } } output.Texture.Faces[0].Add(face); } catch (Exception ex) { context.Logger.LogImportantMessage("{0}", ex.ToString()); } // Perform the final texture conversion. texProfile.ConvertTexture(context, output.Texture, TextureFormat, false, true); return(output); }
public override SpriteFontContent Process(FontDescription input, ContentProcessorContext context) { var output = new SpriteFontContent(input); var fontFile = FindFont(input.FontName, input.Style.ToString()); if (string.IsNullOrWhiteSpace(fontFile)) { var directories = new List <string> { Path.GetDirectoryName(input.Identity.SourceFilename) }; var extensions = new string[] { "", ".ttf", ".ttc", ".otf" }; // Add special per platform directories if (CurrentPlatform.OS == OS.Windows) { directories.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Fonts")); } else if (CurrentPlatform.OS == OS.MacOSX) { directories.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Library", "Fonts")); directories.Add("/Library/Fonts"); } foreach (var dir in directories) { foreach (var ext in extensions) { fontFile = Path.Combine(dir, input.FontName + ext); if (File.Exists(fontFile)) { break; } } if (File.Exists(fontFile)) { break; } } } if (!File.Exists(fontFile)) { throw new FileNotFoundException("Could not find \"" + input.FontName + "\" font file."); } context.Logger.LogMessage("Building Font {0}", fontFile); // Get the platform specific texture profile. var texProfile = TextureProfile.ForPlatform(context.TargetPlatform); { if (!File.Exists(fontFile)) { throw new Exception(string.Format("Could not load {0}", fontFile)); } var lineSpacing = 0f; int yOffsetMin = 0; var glyphs = ImportFont(input, out lineSpacing, out yOffsetMin, context, fontFile); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); } // We need to know how to pack the glyphs. bool requiresPot, requiresSquare; texProfile.Requirements(context, TextureFormat, out requiresPot, out requiresSquare); var face = GlyphPacker.ArrangeGlyphs(glyphs, requiresPot, requiresSquare); // Adjust line and character spacing. lineSpacing += input.Spacing; output.VerticalLineSpacing = (int)lineSpacing; foreach (var glyph in glyphs) { output.CharacterMap.Add(glyph.Character); var texRect = new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height); output.Glyphs.Add(texRect); var cropping = new Rectangle(0, (int)(glyph.YOffset - yOffsetMin), (int)glyph.XAdvance, output.VerticalLineSpacing); output.Cropping.Add(cropping); // Set the optional character kerning. if (input.UseKerning) { output.Kerning.Add(new Vector3(glyph.CharacterWidths.A, glyph.CharacterWidths.B, glyph.CharacterWidths.C)); } else { output.Kerning.Add(new Vector3(0, texRect.Width, 0)); } } output.Texture.Faces[0].Add(face); } if (PremultiplyAlpha) { var bmp = output.Texture.Faces[0][0]; var data = bmp.GetPixelData(); var idx = 0; for (; idx < data.Length;) { var r = data[idx]; // Special case of simply copying the R component into the A, since R is the value of white alpha we want data[idx + 0] = r; data[idx + 1] = r; data[idx + 2] = r; data[idx + 3] = r; idx += 4; } bmp.SetPixelData(data); } else { var bmp = output.Texture.Faces[0][0]; var data = bmp.GetPixelData(); var idx = 0; for (; idx < data.Length;) { var r = data[idx]; // Special case of simply moving the R component into the A and setting RGB to solid white, since R is the value of white alpha we want data[idx + 0] = 255; data[idx + 1] = 255; data[idx + 2] = 255; data[idx + 3] = r; idx += 4; } bmp.SetPixelData(data); } // Perform the final texture conversion. texProfile.ConvertTexture(context, output.Texture, TextureFormat, true); return(output); }
public override SpriteFontContent Process( FontDescription input, ContentProcessorContext context) { string fontFile = FindFont(input.FontName, input.Style.ToString()); if (string.IsNullOrWhiteSpace(fontFile)) { var directories = new List <string> { Path.GetDirectoryName(input.Identity.SourceFilename) }; // Add special per platform directories if (PlatformInfo.CurrentOS == PlatformInfo.OS.Windows) { directories.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Windows), "Fonts")); } else if (PlatformInfo.CurrentOS == PlatformInfo.OS.MacOSX) { directories.Add(Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.Personal), "Library", "Fonts")); directories.Add("/Library/Fonts"); directories.Add("/System/Library/Fonts/Supplemental"); } foreach (var dir in directories) { foreach (var ext in _fontExtensions) { fontFile = Path.Combine(dir, input.FontName + ext); if (File.Exists(fontFile)) { break; } } if (File.Exists(fontFile)) { break; } } } if (!File.Exists(fontFile)) { throw new FileNotFoundException("Could not find \"" + input.FontName + "\" font file."); } context.Logger.LogMessage("Building Font {0}", fontFile); // Get the platform specific texture profile. var texProfile = TextureProfile.ForPlatform(context.TargetPlatform); if (!File.Exists(fontFile)) { throw new Exception(string.Format("Could not load {0}", fontFile)); } var glyphs = ImportFont(input, out float lineSpacing, out int yOffsetMin, context, fontFile); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); } texProfile.Requirements(context, TextureFormat, out bool requiresPot, out bool requiresSquare); var output = new SpriteFontContent(input); var face = GlyphPacker.ArrangeGlyphs(glyphs, requiresPot, requiresSquare); output.Texture.Faces[0].Add(face); // Adjust line and character spacing. lineSpacing += input.Spacing; output.VerticalLineSpacing = (int)lineSpacing; foreach (var glyph in glyphs) { output.CharacterMap.Add(glyph.Character); var texRegion = new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height); output.Regions.Add(texRegion); output.Croppings.Add( new Rectangle(0, (int)(glyph.YOffset - yOffsetMin), (int)glyph.XAdvance, output.VerticalLineSpacing)); // Set the optional character kerning. output.Kerning.Add(input.UseKerning ? new Vector3(glyph.CharacterWidths.A, glyph.CharacterWidths.B, glyph.CharacterWidths.C) : new Vector3(0, texRegion.Width, 0)); } var facePixels = face.GetPixelSpan(); if (PremultiplyAlpha) { for (int i = 0; i < facePixels.Length; i++) { ref Color pixel = ref facePixels[i]; // A is the value of white alpha we want pixel.R = pixel.A; pixel.G = pixel.A; pixel.B = pixel.A; } }
public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { var output = new SpriteFontContent(); // extract the glyphs from the texture and map them to a list of characters. // we need to call GtCharacterForIndex for each glyph in the Texture to // get the char for that glyph, by default we start at ' ' then '!' and then ASCII // after that. BitmapContent face = input.Faces[0][0]; SurfaceFormat faceFormat; face.TryGetFormat(out faceFormat); if (faceFormat != SurfaceFormat.Color) { var colorFace = new PixelBitmapContent <Color>(face.Width, face.Height); BitmapContent.Copy(face, colorFace); face = colorFace; } var glyphs = ExtractGlyphs((PixelBitmapContent <Color>)face); // Optimize. foreach (var glyph in glyphs) { GlyphCropper.Crop(glyph); output.VerticalLineSpacing = Math.Max(output.VerticalLineSpacing, glyph.Subrect.Height); } var format = GraphicsUtil.GetTextureFormatForPlatform(TextureFormat, context.TargetPlatform); var requiresPOT = GraphicsUtil.RequiresPowerOfTwo(format, context.TargetPlatform, context.TargetProfile); var requiresSquare = GraphicsUtil.RequiresSquare(format, context.TargetPlatform); face = GlyphPacker.ArrangeGlyphs(glyphs.ToArray(), requiresPOT, requiresSquare); foreach (var glyph in glyphs) { output.CharacterMap.Add(glyph.Character); output.Glyphs.Add(new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height)); output.Cropping.Add(new Rectangle((int)glyph.XOffset, (int)glyph.YOffset, glyph.Width, glyph.Height)); var abc = glyph.CharacterWidths; output.Kerning.Add(new Vector3(abc.A, abc.B, abc.C)); } output.Texture.Faces[0].Add(face); var bmp = output.Texture.Faces[0][0]; if (PremultiplyAlpha) { var data = bmp.GetPixelData(); var idx = 0; for (; idx < data.Length;) { var r = data[idx + 0]; var g = data[idx + 1]; var b = data[idx + 2]; var a = data[idx + 3]; var col = Color.FromNonPremultiplied(r, g, b, a); data[idx + 0] = col.R; data[idx + 1] = col.G; data[idx + 2] = col.B; data[idx + 3] = col.A; idx += 4; } bmp.SetPixelData(data); } if (GraphicsUtil.IsCompressedTextureFormat(format)) { try { GraphicsUtil.CompressTexture(context.TargetProfile, output.Texture, format, context, false, true); } catch (Exception ex) { context.Logger.LogImportantMessage("{0}", ex.ToString()); } } return(output); }
public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { var output = new SpriteFontContent(); // extract the glyphs from the texture and map them to a list of characters. // we need to call GtCharacterForIndex for each glyph in the Texture to // get the char for that glyph, by default we start at ' ' then '!' and then ASCII // after that. var systemBitmap = input.Faces[0][0].ToSystemBitmap(); var glyphs = ExtractGlyphs(systemBitmap); // Optimize. foreach (Glyph glyph in glyphs) { GlyphCropper.Crop(glyph); output.VerticalLineSpacing = Math.Max(output.VerticalLineSpacing, glyph.Subrect.Height); } systemBitmap.Dispose(); var compressed = TextureFormat == TextureProcessorOutputFormat.DxtCompressed || TextureFormat == TextureProcessorOutputFormat.Compressed; systemBitmap = GlyphPacker.ArrangeGlyphs(glyphs.ToArray(), compressed, compressed); foreach (Glyph glyph in glyphs) { output.CharacterMap.Add(glyph.Character); output.Glyphs.Add(new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height)); output.Cropping.Add(new Rectangle((int)glyph.XOffset, (int)glyph.YOffset, glyph.Subrect.Width, glyph.Subrect.Height)); ABCFloat abc = glyph.CharacterWidths; output.Kerning.Add(new Vector3(abc.A, abc.B, abc.C)); } output.Texture.Faces[0].Add(systemBitmap.ToXnaBitmap(false)); systemBitmap.Dispose(); var bmp = output.Texture.Faces[0][0]; if (PremultiplyAlpha) { var data = bmp.GetPixelData(); var idx = 0; for (; idx < data.Length;) { var r = data[idx + 0]; var g = data[idx + 1]; var b = data[idx + 2]; var a = data[idx + 3]; var col = Color.FromNonPremultiplied(r, g, b, a); data[idx + 0] = col.R; data[idx + 1] = col.G; data[idx + 2] = col.B; data[idx + 3] = col.A; idx += 4; } bmp.SetPixelData(data); } if (compressed) { GraphicsUtil.CompressTexture(context.TargetProfile, output.Texture, context, false, PremultiplyAlpha, true); } return(output); }
public override SpriteFontContent Process(Texture2DContent input, ContentProcessorContext context) { // extract the glyphs from the texture and map them to a list of characters. // we need to call GtCharacterForIndex for each glyph in the Texture to // get the char for that glyph, by default we start at ' ' then '!' and then ASCII // after that. BitmapContent face = input.Faces[0][0]; face.TryGetFormat(out SurfaceFormat faceFormat); if (faceFormat != SurfaceFormat.Rgba32) { var colorFace = new PixelBitmapContent <Color>(face.Width, face.Height); BitmapContent.Copy(face, colorFace); face = colorFace; } var output = new SpriteFontContent(); var glyphs = ExtractGlyphs((PixelBitmapContent <Color>)face); // Optimize. foreach (var glyph in glyphs) { GlyphCropper.Crop(glyph); output.VerticalLineSpacing = Math.Max(output.VerticalLineSpacing, glyph.Subrect.Height); } // Get the platform specific texture profile. var texProfile = TextureProfile.ForPlatform(context.TargetPlatform); texProfile.Requirements(context, TextureFormat, out bool requiresPot, out bool requiresSquare); face = GlyphPacker.ArrangeGlyphs(glyphs, requiresPot, requiresSquare); foreach (var glyph in glyphs) { output.CharacterMap.Add(glyph.Character); output.Regions.Add( new Rectangle(glyph.Subrect.X, glyph.Subrect.Y, glyph.Subrect.Width, glyph.Subrect.Height)); output.Croppings.Add( new Rectangle((int)glyph.XOffset, (int)glyph.YOffset, glyph.Width, glyph.Height)); var abc = glyph.CharacterWidths; output.Kerning.Add(new Vector3(abc.A, abc.B, abc.C)); } output.Texture.Faces[0].Add(face); var bmp = output.Texture.Faces[0][0]; if (PremultiplyAlpha) { var data = bmp.GetPixelData(); var idx = 0; for (; idx < data.Length;) { var r = data[idx + 0]; var g = data[idx + 1]; var b = data[idx + 2]; var a = data[idx + 3]; var col = Color.FromNonPremultiplied(r, g, b, a); data[idx + 0] = col.R; data[idx + 1] = col.G; data[idx + 2] = col.B; data[idx + 3] = col.A; idx += 4; } bmp.SetPixelData(data); } // Perform the final texture conversion. texProfile.ConvertTexture(context, output.Texture, TextureFormat, true); return(output); }