예제 #1
0
        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);
        }
예제 #2
0
        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);
        }
예제 #3
0
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            var bmp = input.Faces[0][0];

            if (ColorKeyEnabled)
            {
                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 = new Color(r, g, b, a);
                    if (col.Equals(ColorKeyColor))
                    {
                        data[idx + 0] = 0;
                        data[idx + 1] = 0;
                        data[idx + 2] = 0;
                        data[idx + 3] = 0;
                    }

                    idx += 4;
                }

                bmp.SetPixelData(data);
            }


            if (ResizeToPowerOfTwo)
            {
                if (!GraphicsUtil.IsPowerOfTwo(bmp.Width) || !GraphicsUtil.IsPowerOfTwo(bmp.Height))
                {
                    input.Resize(GraphicsUtil.GetNextPowerOfTwo(bmp.Width), GraphicsUtil.GetNextPowerOfTwo(bmp.Height));
                    bmp = input.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 (TextureFormat == TextureProcessorOutputFormat.NoChange)
            {
                return(input);
            }
            try
            {
                if (TextureFormat == TextureProcessorOutputFormat.DxtCompressed ||
                    TextureFormat == TextureProcessorOutputFormat.Compressed)
                {
                    GraphicsUtil.CompressTexture(context.TargetProfile, input, context, GenerateMipmaps, PremultiplyAlpha, false);
                }
            }
            catch (EntryPointNotFoundException ex) {
                context.Logger.LogImportantMessage("Could not find the entry point to compress the texture", ex.ToString());
                TextureFormat = TextureProcessorOutputFormat.Color;
            }
            catch (DllNotFoundException ex) {
                context.Logger.LogImportantMessage("Could not compress texture. Required shared lib is missing. {0}", ex.ToString());
                TextureFormat = TextureProcessorOutputFormat.Color;
            }
            catch (Exception ex)
            {
                context.Logger.LogImportantMessage("Could not compress texture {0}", ex.ToString());
                TextureFormat = TextureProcessorOutputFormat.Color;
            }

            if (GenerateMipmaps)
            {
                context.Logger.LogMessage("Generating mipmaps.");
                input.GenerateMipmaps(false);
            }

            return(input);
        }
        public override SpriteFontContent Process(FontDescription input,
                                                  ContentProcessorContext context)
        {
            var output = new SpriteFontContent(input);

            var estimatedSurfaceArea = 0;
            var largestHeight        = 0;
            var widthsAndHeights     = new List <Point>();
            var fontName             = input.FontName;

            var directory = Path.GetDirectoryName(input.Identity.SourceFilename);

            if (File.Exists(Path.Combine(directory, fontName + ".ttf")))
            {
                fontName += ".ttf";
            }
            if (File.Exists(Path.Combine(directory, fontName + ".ttc")))
            {
                fontName += ".ttc";
            }
            if (File.Exists(Path.Combine(directory, fontName + ".otf")))
            {
                fontName += ".otf";
            }

            fontName = Path.Combine(directory, fontName);
            context.Logger.LogMessage("Building Font {0}", fontName);
            try {
                Library lib  = new Library();
                Face    face = lib.NewFace(fontName, 0);
                face.SetCharSize(0, (int)input.Size * 64, 0, 96);

                if (face.FamilyName == "Microsoft Sans Serif" && input.FontName != "Microsoft Sans Serif")
                {
                    throw new PipelineException(string.Format("Font {0} is not installed on this computer.", input.FontName));
                }

                foreach (var ch in input.Characters)
                {
                    uint glyphIndex = face.GetCharIndex(ch);
                    face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
                    var width = (int)face.Glyph.Advance.X >> 6;

                    var height = (int)face.Glyph.Metrics.Height >> 6;

                    estimatedSurfaceArea += width;
                    largestHeight         = Math.Max(largestHeight, height);

                    widthsAndHeights.Add(new Point(width, height));
                }

                estimatedSurfaceArea *= largestHeight;

                output.VerticalLineSpacing = largestHeight;

                // calculate the best height and width for our output texture.
                // TODO: GetMonoGamePlatform()
                var texBounds = calculateOutputTextureBounds(estimatedSurfaceArea, true);
                // Create our texture
                var outputBitmap = new Bitmap(texBounds.X, texBounds.Y);
                using (var g = System.Drawing.Graphics.FromImage(outputBitmap))
                {
                    g.FillRectangle(Brushes.Transparent, new System.Drawing.Rectangle(0, 0, outputBitmap.Width, outputBitmap.Height));
                }
                int x = 0;
                int y = 0;
                // Draw each glyph into the image.
                for (int i = 0; i < input.Characters.Count; i++)
                {
                    char c          = input.Characters[i];
                    uint glyphIndex = face.GetCharIndex(c);
                    face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
                    face.Glyph.RenderGlyph(RenderMode.Normal);

                    var A = face.Glyph.Metrics.HorizontalBearingX >> 6;
                    var B = face.Glyph.Metrics.Width >> 6;
                    var C = (face.Glyph.Metrics.HorizontalAdvance >> 6) - (A + B);

                    int charWidth = (int)(Math.Abs(A) + B + C);

                    if (!input.UseKerning)
                    {
                        charWidth = (int)B;
                    }

                    if (x + charWidth >= outputBitmap.Width)
                    {
                        x  = 0;
                        y += largestHeight;
                    }

                    var rect = new Microsoft.Xna.Framework.Rectangle(x, y, charWidth, widthsAndHeights[i].Y);
                    output.Glyphs.Add(rect);

                    // Characters with a negative a kerning value (like j) need to be adjusted,
                    // so (in the case of j) the bottom curve doesn't render outside our source
                    // rect.
                    var renderPoint = new PointF(x, y);
                    if (A < 0)
                    {
                        renderPoint.X += Math.Abs(A);
                    }

                    if (face.Glyph.Bitmap.Width > 0 && face.Glyph.Bitmap.Rows > 0)
                    {
                        BitmapData data        = outputBitmap.LockBits(new System.Drawing.Rectangle((int)renderPoint.X, (int)renderPoint.Y, face.Glyph.Bitmap.Width, face.Glyph.Bitmap.Rows), ImageLockMode.ReadWrite, PixelFormat.Format32bppArgb);
                        byte[]     pixelAlphas = new byte[face.Glyph.Bitmap.Width * face.Glyph.Bitmap.Rows];
                        Marshal.Copy(face.Glyph.Bitmap.Buffer, pixelAlphas, 0, pixelAlphas.Length);

                        for (int j = 0; j < pixelAlphas.Length; j++)
                        {
                            int pixelOffset = (j / data.Width) * data.Stride + (j % data.Width * 4);
                            Marshal.WriteByte(data.Scan0, pixelOffset + 3, pixelAlphas[j]);
                        }

                        outputBitmap.UnlockBits(data);
                    }
                    output.Cropping.Add(new Microsoft.Xna.Framework.Rectangle(0, (face.Glyph.Metrics.VerticalAdvance >> 6) - face.Glyph.BitmapTop, charWidth, widthsAndHeights[i].Y));

                    if (!input.UseKerning)
                    {
                        A = 0;
                        C = 0;
                    }
                    output.Kerning.Add(new Vector3(A, B, C));

                    // Add a 2 pixel spacing between characters
                    x += charWidth + 2;
                }

                // Drawing against a transparent black background blends
                // the 'alpha' pixels against black, leaving a black outline.
                // Interpolate between black and white
                // based on it's intensity to covert this 'outline' to
                // it's grayscale equivalent.
                var transBlack = Color.Transparent;
                for (var i = 0; i < outputBitmap.Width; i++)
                {
                    for (var j = 0; j < outputBitmap.Height; j++)
                    {
                        var px = outputBitmap.GetPixel(i, j);

                        if (px.ColorsEqual(transBlack))
                        {
                            continue;
                        }

                        var val = px.A / (255.0f);
                        var col = Color.Lerp(Color.Transparent, Color.White, val);
                        px = System.Drawing.Color.FromArgb(px.A, col.R, col.G, col.B);
                        outputBitmap.SetPixel(i, j, px);
                    }
                }
                outputBitmap.Save("test.png");
                output.Texture._bitmap = outputBitmap;

                var bitmapContent = new PixelBitmapContent <Color>(texBounds.X, texBounds.Y);
                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);
        }
예제 #5
0
        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);
        }
예제 #7
0
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            if (ColorKeyEnabled)
            {
                var replaceColor = System.Drawing.Color.FromArgb(0);
                for (var x = 0; x < input._bitmap.Width; x++)
                {
                    for (var y = 0; y < input._bitmap.Height; y++)
                    {
                        var col = input._bitmap.GetPixel(x, y);

                        if (col.ColorsEqual(ColorKeyColor))
                        {
                            input._bitmap.SetPixel(x, y, replaceColor);
                        }
                    }
                }
            }

            var face = input.Faces[0][0];

            if (ResizeToPowerOfTwo)
            {
                if (!GraphicsUtil.IsPowerOfTwo(face.Width) || !GraphicsUtil.IsPowerOfTwo(face.Height))
                {
                    input.Resize(GraphicsUtil.GetNextPowerOfTwo(face.Width), GraphicsUtil.GetNextPowerOfTwo(face.Height));
                }
            }

            if (PremultiplyAlpha)
            {
                for (var x = 0; x < input._bitmap.Width; x++)
                {
                    for (var y = 0; y < input._bitmap.Height; y++)
                    {
                        var oldCol             = input._bitmap.GetPixel(x, y);
                        var preMultipliedColor = Color.FromNonPremultiplied(oldCol.R, oldCol.G, oldCol.B, oldCol.A);
                        input._bitmap.SetPixel(x, y, System.Drawing.Color.FromArgb(preMultipliedColor.A,
                                                                                   preMultipliedColor.R,
                                                                                   preMultipliedColor.G,
                                                                                   preMultipliedColor.B));
                    }
                }
            }

            // Set the first layer
            input.Faces[0][0].SetPixelData(input._bitmap.GetData());

            if (TextureFormat == TextureProcessorOutputFormat.NoChange)
            {
                return(input);
            }
            try
            {
                if (TextureFormat == TextureProcessorOutputFormat.DXTCompressed ||
                    TextureFormat == TextureProcessorOutputFormat.Compressed)
                {
                    context.Logger.LogMessage("Compressing using {0}", TextureFormat);
                }
                GraphicsUtil.CompressTexture(input, context, GenerateMipmaps, PremultiplyAlpha);
                context.Logger.LogMessage("Compression {0} Suceeded", TextureFormat);
            }
            catch (EntryPointNotFoundException ex) {
                context.Logger.LogImportantMessage("Could not find the entry point to compress the texture", ex.ToString());
                TextureFormat = TextureProcessorOutputFormat.Color;
            }
            catch (DllNotFoundException ex) {
                context.Logger.LogImportantMessage("Could not compress texture. Required shared lib is missing. {0}", ex.ToString());
                TextureFormat = TextureProcessorOutputFormat.Color;
            }
            catch (Exception ex)
            {
                context.Logger.LogImportantMessage("Could not compress texture {0}", ex.ToString());
                TextureFormat = TextureProcessorOutputFormat.Color;
            }

            return(input);
        }
예제 #8
0
        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);
        }
예제 #9
0
        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);
        }
예제 #10
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);
                }
            }

            if (TextureFormat == TextureProcessorOutputFormat.NoChange)
            {
                return(input);
            }

            try
            {
                if (TextureFormat != TextureProcessorOutputFormat.Color)
                {
                    input.ConvertBitmapType(typeof(PixelBitmapContent <Vector4>));
                    GraphicsUtil.CompressTexture(context.TargetProfile, input, TextureFormat, context, GenerateMipmaps, false);
                }
                else
                {
                    input.ConvertBitmapType(typeof(PixelBitmapContent <Color>));
                    if (GenerateMipmaps)
                    {
                        input.GenerateMipmaps(false);
                    }
                }
            }
            catch (EntryPointNotFoundException ex)
            {
                context.Logger.LogImportantMessage("Could not find the entry point to compress the texture. " + ex.ToString());
                throw ex;
            }
            catch (DllNotFoundException ex)
            {
                context.Logger.LogImportantMessage("Could not compress texture. Required shared lib is missing. " + ex.ToString());
                throw ex;
            }
            catch (Exception ex)
            {
                context.Logger.LogImportantMessage("Could not convert texture. " + ex.ToString());
                throw ex;
            }

            return(input);
        }
예제 #11
0
        public override TextureContent Process(TextureContent input, ContentProcessorContext context)
        {
            if (ColorKeyEnabled)
            {
                var replaceColor = System.Drawing.Color.FromArgb(0);
                for (var x = 0; x < input._bitmap.Width; x++)
                {
                    for (var y = 0; y < input._bitmap.Height; y++)
                    {
                        var col = input._bitmap.GetPixel(x, y);

                        if (col.ColorsEqual(ColorKeyColor))
                        {
                            input._bitmap.SetPixel(x, y, replaceColor);
                        }
                    }
                }
            }

            var face = input.Faces[0][0];

            if (ResizeToPowerOfTwo)
            {
                if (!GraphicsUtil.IsPowerOfTwo(face.Width) || !GraphicsUtil.IsPowerOfTwo(face.Height))
                {
                    input.Resize(GraphicsUtil.GetNextPowerOfTwo(face.Width), GraphicsUtil.GetNextPowerOfTwo(face.Height));
                }
            }

            if (PremultiplyAlpha)
            {
                for (var x = 0; x < input._bitmap.Width; x++)
                {
                    for (var y = 0; y < input._bitmap.Height; y++)
                    {
                        var oldCol             = input._bitmap.GetPixel(x, y);
                        var preMultipliedColor = Color.FromNonPremultiplied(oldCol.R, oldCol.G, oldCol.B, oldCol.A);
                        input._bitmap.SetPixel(x, y, System.Drawing.Color.FromArgb(preMultipliedColor.A,
                                                                                   preMultipliedColor.R,
                                                                                   preMultipliedColor.G,
                                                                                   preMultipliedColor.B));
                    }
                }
            }

            if (GenerateMipmaps)
            {
                throw new NotImplementedException();
            }

            // TODO: Set all mip level data
            input.Faces[0][0].SetPixelData(input._bitmap.GetData());

            if (TextureFormat == TextureProcessorOutputFormat.NoChange)
            {
                return(input);
            }

            if (TextureFormat == TextureProcessorOutputFormat.DXTCompressed ||
                TextureFormat == TextureProcessorOutputFormat.Compressed)
            {
                GraphicsUtil.CompressTexture(input, context.TargetPlatform, PremultiplyAlpha);
            }

            return(input);
        }