示例#1
0
        public BitmapPacker Insert(Bitmap texture)
        {
            //image = new Bitmap(filename);

            if (A != null && B != null)
            {
                BitmapPacker newNode = A.Insert(texture);
                if (newNode != null) return newNode;
                return B.Insert(texture);
            }
            else
            {
                if (image != null) return null;

                //if we're too small, return
                if (Rect.Width < texture.Width || Rect.Height < texture.Height) return null;

                //if we're just right, accept
                if (Rect.Width == texture.Width && Rect.Height == texture.Height)
                {
                    image = texture;
                    return this;
                }

                //otherwise, gotta split this node and create some kids
                A = new BitmapPacker();
                B = new BitmapPacker();

                //decide which way to split
                int dw = Rect.Width - texture.Width;
                int dh = Rect.Height - texture.Height;

                if (dw > dh)
                {
                    A.Rect = new System.Drawing.Rectangle(Rect.Left, Rect.Top, texture.Width, Rect.Bottom - Rect.Top);
                    B.Rect = new System.Drawing.Rectangle(Rect.Left + texture.Width, Rect.Top, Rect.Right - (Rect.Left + texture.Width), Rect.Bottom - Rect.Top);
                }
                else
                {
                    A.Rect = new System.Drawing.Rectangle(Rect.Left, Rect.Top, Rect.Right - Rect.Left, texture.Height);
                    B.Rect = new System.Drawing.Rectangle(Rect.Left, Rect.Top + texture.Height, Rect.Right - Rect.Left, Rect.Bottom - (Rect.Top + texture.Height));
                }

                //insert into first child we created
                return A.Insert(texture);
            }
        }
示例#2
0
        public Bitmap GetBitmap()
        {
            var bitmaps = new List<Bitmap>();
            foreach (var tex in _items)
            {
                if (File.Exists(tex.Filename))
                {
                    var bmp = new Bitmap(tex.Filename);
                    bmp.Tag = tex;
                    bitmaps.Add(bmp);
                    if (string.IsNullOrWhiteSpace(tex.Name)) tex.Name = Path.GetFileNameWithoutExtension(tex.Filename);
                }
            }
            bitmaps = bitmaps.OrderByDescending(b => b.Width * b.Height).ToList();

            Bitmap result = null;
            BitmapPacker packTest = null;
            if (bitmaps.Count > 0)
            {
                _width = 256;
                _height = 256;
                do
                {
                    var packer = new BitmapPacker { Rect = new Rectangle(0, 0, _width, _height) };
                    foreach (var bmp in bitmaps)
                    {
                        packTest = packer.Insert(bmp);
                        if (packTest == null) break;
                        (bmp.Tag as TextureAtlasItem).Width = packTest.Rect.Width;
                        (bmp.Tag as TextureAtlasItem).Height = packTest.Rect.Height;
                        (bmp.Tag as TextureAtlasItem).X = packTest.Rect.X;
                        (bmp.Tag as TextureAtlasItem).Y = packTest.Rect.Y;
                    }
                    if (packTest == null)
                    {
                        if (_width > _height) _height *= 2; else _width *= 2;
                    }
                    else
                    {
                        result = new Bitmap(_width, _height, PixelFormat.Format32bppArgb);
                        packer.Render(result);
                    }
                } while (packTest == null);
            }
            bitmaps.Clear();
            return result;
        }
示例#3
0
        public void Build(System.Drawing.Font font, TextRenderingHint hint, string filename)
        {
            //new Glyph(97, font, hint);

            //Create Glyphs
            _glyphs.Clear();
            for (int i = 33; i < 256; i++)
            {
                _glyphs.Add(new Glyph(i, font, hint));
            }

            //Create Texture
            bool allFit;
            int startWidth = 128;
            int startHeight = 128;
            BitmapPacker root;
            do
            {
                allFit = true;
                root = new BitmapPacker();
                root.Rect = new System.Drawing.Rectangle(0, 0, startWidth, startHeight);
                foreach (var glyph in _glyphs)
                {
                    if (glyph.Bitmap != null)
                    {
                        var bp = root.Insert(glyph.Bitmap);
                        if (bp == null)
                        {
                            if (startWidth > startHeight)
                            {
                                startHeight *= 2;
                            }
                            else
                            {
                                startWidth *= 2;
                            }
                            allFit = false;
                            break;
                        }
                        else
                        {
                            glyph.Info.X1 = (byte)bp.Rect.X;
                            glyph.Info.Y1 = (byte)bp.Rect.Y;
                            glyph.Info.X2 = (byte)bp.Rect.Right;
                            glyph.Info.Y2 = (byte)bp.Rect.Bottom;
                        }
                    }
                }
            } while (!allFit);

            Bitmap result = new Bitmap(root.Rect.Width, root.Rect.Height, System.Drawing.Imaging.PixelFormat.Format32bppArgb);
            root.Render(result);
            result.Save(filename + ".png");

            CalculateKernings();

            using (var fs = new FileStream(filename + ".info", FileMode.Create))
            {
                using (var bw = new BinaryWriter(fs))
                {
                    foreach (var g in _glyphs)
                    {
                        bw.Write(g.Info.X1);
                        bw.Write(g.Info.Y1);
                        bw.Write(g.Info.X2);
                        bw.Write(g.Info.Y2);
                        bw.Write(g.Info.YOffset);
                    }
                    bw.Write(_kerning);
                }
            }
        }