Example #1
0
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            SurfaceFormat format;

            if (input.Faces[0][0].TryGetFormat(out format))
            {
                // If it is already a compressed format, we cannot do anything else so just return it
                if (format.IsCompressedFormat())
                {
                    return(input);
                }
            }

            if (ColorKeyEnabled || ResizeToPowerOfTwo || MakeSquare || PremultiplyAlpha)
            {
                // Convert to floating point format for modifications. Keep the original format for conversion back later on if required.
                var originalType = input.Faces[0][0].GetType();
                try
                {
                    input.ConvertBitmapType(typeof(PixelBitmapContent <Vector4>));
                }
                catch (Exception ex)
                {
                    context.Logger.LogImportantMessage("Could not convert input texture for processing. " + ex.ToString());
                    throw ex;
                }

                for (int f = 0; f < input.Faces.Count; ++f)
                {
                    var face = input.Faces[f];
                    for (int m = 0; m < face.Count; ++m)
                    {
                        var bmp = (PixelBitmapContent <Vector4>)face[m];

                        if (ColorKeyEnabled)
                        {
                            bmp.ReplaceColor(ColorKeyColor.ToVector4(), Vector4.Zero);
                        }

                        if (ResizeToPowerOfTwo)
                        {
                            if (!GraphicsUtil.IsPowerOfTwo(bmp.Width) || !GraphicsUtil.IsPowerOfTwo(bmp.Height) || (MakeSquare && bmp.Height != bmp.Width))
                            {
                                var newWidth  = GraphicsUtil.GetNextPowerOfTwo(bmp.Width);
                                var newHeight = GraphicsUtil.GetNextPowerOfTwo(bmp.Height);
                                if (MakeSquare)
                                {
                                    newWidth = newHeight = Math.Max(newWidth, newHeight);
                                }
                                var resized = new PixelBitmapContent <Vector4>(newWidth, newHeight);
                                BitmapContent.Copy(bmp, resized);
                                bmp = resized;
                            }
                        }
                        else if (MakeSquare && bmp.Height != bmp.Width)
                        {
                            var newSize = Math.Max(bmp.Width, bmp.Height);
                            var resized = new PixelBitmapContent <Vector4>(newSize, newSize);
                            BitmapContent.Copy(bmp, resized);
                        }

                        if (PremultiplyAlpha)
                        {
                            for (int y = 0; y < bmp.Height; ++y)
                            {
                                var row = bmp.GetRow(y);
                                for (int x = 0; x < bmp.Width; ++x)
                                {
                                    row[x] = Color.FromNonPremultiplied(row[x]).ToVector4();
                                }
                            }
                        }

                        face[m] = bmp;
                    }
                }

                // If no change to the surface format was desired, change it back now before it early outs
                if (TextureFormat == TextureProcessorOutputFormat.NoChange)
                {
                    input.ConvertBitmapType(originalType);
                }
            }

            // Get the texture profile for the platform and let it convert the texture.
            var texProfile = TextureProfile.ForPlatform(context.TargetPlatform);

            texProfile.ConvertTexture(context, input, TextureFormat, GenerateMipmaps, false);

            return(input);
        }
Example #2
0
        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)
        {
            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(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);
        }
Example #5
0
        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);
        }