using System; using System.Collections.Generic; using System.Drawing; using System.Drawing.Drawing2D; using System.Drawing.Imaging; using System.Linq; namespace GMAssetCompiler { internal class TexturePage { public List Entries { get; private set; } public IEnumerable Textures { get { IEnumerable enumerable = null; foreach (KeyValuePair> textureGroup in TextureGroups) { enumerable = ((enumerable != null) ? enumerable.Concat(textureGroup.Value) : textureGroup.Value); } return enumerable; } } public Dictionary> TextureGroups { get; private set; } private string GroupName { get; set; } public int MarginX { get; private set; } public int MarginY { get; private set; } public int GapX { get; private set; } public int GapY { get; private set; } public int TextureSizeWidth { get; private set; } public int TextureSizeHeight { get; private set; } public void Reset() { Entries.Clear(); TextureGroups.Clear(); } public TexturePage(int _gapX, int _gapY, int _marginX, int _marginY, int _width, int _height) { GapX = _gapX; GapY = _gapY; MarginX = _marginX; MarginY = _marginY; TextureSizeWidth = _width; TextureSizeHeight = _height; GroupName = string.Empty; Entries = new List(); TextureGroups = new Dictionary>(); } public void BeginGroup(string _resourceName) { string groupName = string.Empty; foreach (KeyValuePair> textureGroup in Program.TextureGroups) { if (textureGroup.Value.Contains(_resourceName)) { groupName = textureGroup.Key; break; } } GroupName = groupName; } public void EndGroup() { GroupName = string.Empty; } public static Bitmap Scale(Bitmap Bitmap, int scaleWidth, int scaleHeight) { Bitmap image = new Bitmap(Bitmap.Width * 3, Bitmap.Height * 3); using (Graphics graphics = Graphics.FromImage(image)) { graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.DrawImage(Bitmap, 0, 0); graphics.DrawImage(Bitmap, Bitmap.Width, 0); graphics.DrawImage(Bitmap, Bitmap.Width * 2, 0); graphics.DrawImage(Bitmap, 0, Bitmap.Height); graphics.DrawImage(Bitmap, Bitmap.Width, Bitmap.Height); graphics.DrawImage(Bitmap, Bitmap.Width * 2, Bitmap.Height); graphics.DrawImage(Bitmap, 0, Bitmap.Height * 2); graphics.DrawImage(Bitmap, Bitmap.Width, Bitmap.Height * 2); graphics.DrawImage(Bitmap, Bitmap.Width * 2, Bitmap.Height * 2); } Bitmap bitmap = new Bitmap(scaleWidth, scaleHeight); using (Graphics graphics2 = Graphics.FromImage(bitmap)) { graphics2.SmoothingMode = SmoothingMode.HighQuality; graphics2.PixelOffsetMode = PixelOffsetMode.HighQuality; graphics2.CompositingQuality = CompositingQuality.HighQuality; graphics2.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics2.DrawImage(image, new Rectangle(0, 0, scaleWidth, scaleHeight), new Rectangle(Bitmap.Width, Bitmap.Height, Bitmap.Width, Bitmap.Height), GraphicsUnit.Pixel); return bitmap; } } private unsafe Bitmap RemoveSpace(Bitmap _image, out int _XOffset, out int _YOffset, out int _CropWidth, out int _CropHeight) { int width = _image.Width; int height = _image.Height; _XOffset = 0; _YOffset = 0; _CropWidth = width; _CropHeight = height; BitmapData bitmapData = _image.LockBits(new Rectangle(0, 0, width, height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb); uint* ptr = (uint*)bitmapData.Scan0.ToPointer(); int num = width; int num2 = height; int num3 = 0; int num4 = 0; for (int i = 0; i < height; i++) { uint* ptr2 = (uint*)((long)ptr + i * bitmapData.Stride); for (int j = 0; j < width; j++) { if (((int)(*ptr2) & -16777216) != 0) { if (j < num) { num = j; } if (i < num2) { num2 = i; } if (j > num3) { num3 = j; } if (i > num4) { num4 = i; } } ptr2++; } } _image.UnlockBits(bitmapData); if (num == width && num2 == height) { _XOffset = 0; _YOffset = 0; _CropWidth = width; _CropHeight = height; return _image; } if (num != 0 || num2 != 0 || num3 != width - 1 || num4 != height - 1) { _XOffset = num; _YOffset = num2; _CropWidth = num3 - _XOffset + 1; _CropHeight = num4 - _YOffset + 1; int width2 = num3 - num + 1; int height2 = num4 - num2 + 1; Bitmap bitmap = new Bitmap(width2, height2); using (Graphics graphics = Graphics.FromImage(bitmap)) { graphics.SmoothingMode = SmoothingMode.HighQuality; graphics.PixelOffsetMode = PixelOffsetMode.HighQuality; graphics.CompositingQuality = CompositingQuality.HighQuality; graphics.InterpolationMode = InterpolationMode.HighQualityBicubic; graphics.DrawImage(_image, -num, -num2); _image = bitmap; return _image; } } return _image; } public TexturePageEntry AddImage(Bitmap _image, bool _pack, bool _ignoreTextureScale) { int width = _image.Width; int height = _image.Height; int _XOffset = 0; int _YOffset = 0; int _CropWidth = width; int _CropHeight = height; if (_pack) { _image = RemoveSpace(_image, out _XOffset, out _YOffset, out _CropWidth, out _CropHeight); } if (!_ignoreTextureScale && Program.TextureScale > 1) { _image = Scale(_image, Math.Max(1, _image.Width / Program.TextureScale), Math.Max(1, _image.Height / Program.TextureScale)); } if (_image.Width > TextureSizeWidth || _image.Height > TextureSizeHeight) { int num = _image.Width; int num2 = _image.Height; while (num > TextureSizeWidth || num2 > TextureSizeHeight) { num >>= 1; num2 >>= 1; } _image = Scale(_image, num, num2); } TexturePageEntry texturePageEntry = null; uint num3 = Loader.HashBitmap(_image); foreach (TexturePageEntry entry in Entries) { if (entry.W == _image.Width && entry.H == _image.Height && entry.Hash == num3 && entry.Name == GroupName && entry.XOffset == _XOffset && entry.YOffset == _YOffset) { texturePageEntry = entry; break; } } if (texturePageEntry == null) { texturePageEntry = ((!string.IsNullOrEmpty(GroupName)) ? new TexturePageEntry(_image, GroupName, num3) : new TexturePageEntry(_image, num3)); texturePageEntry.XOffset = _XOffset; texturePageEntry.YOffset = _YOffset; texturePageEntry.CropWidth = _CropWidth; texturePageEntry.CropHeight = _CropHeight; texturePageEntry.OW = width; texturePageEntry.OH = height; texturePageEntry.DebugTag = false; Entries.Add(texturePageEntry); } return texturePageEntry; } public void Compile() { IOrderedEnumerable orderedEnumerable = from e in Entries orderby e.Name, e.HasAlpha, e.W * e.H descending select e; Entries = orderedEnumerable.ToList(); int num = -1; foreach (TexturePageEntry item in orderedEnumerable) { num++; if (Program.DisplaySortedTextures) { Console.WriteLine("entry :: w={0} h={1} hasAlpha={2}", item.W, item.H, item.HasAlpha); } List list = null; int num2 = 0; foreach (KeyValuePair> textureGroup in TextureGroups) { if (item.Name == textureGroup.Key) { list = textureGroup.Value; break; } num2++; } if (list == null) { list = new List(); TextureGroups.Add(item.Name, list); num2++; } int _X = 0; int _Y = 0; bool flag = false; Texture texture = null; foreach (Texture item2 in list) { flag = item2.Alloc(item, out _X, out _Y); if (flag) { texture = item2; break; } } if (!flag) { Texture texture2 = new Texture(TextureSizeWidth, TextureSizeHeight, GapX, GapY, MarginX, MarginY); texture2.Group = 0; list.Add(texture2); texture2.Alloc(item, out _X, out _Y); texture = texture2; } item.X = _X; item.Y = _Y; item.TP = texture; texture.Entries.Add(item); if (item.DebugTag) { item.DebugTag = true; } } foreach (Texture texture3 in Textures) { int num3 = texture3.Bitmap.Width; int num4 = texture3.Bitmap.Height; int _X2 = 0; int _Y2 = 0; bool flag2 = true; while (flag2) { int num5 = (num3 == num4) ? num3 : (num3 / 2); int num6 = (num3 == num4) ? (num4 / 2) : num4; texture3.Resize(num5, num6); foreach (TexturePageEntry entry in texture3.Entries) { if (!texture3.Alloc(entry, out _X2, out _Y2)) { flag2 = false; break; } entry.X = _X2; entry.Y = _Y2; } if (flag2) { num3 = num5; num4 = num6; } } num = -1; texture3.Resize(num3, num4); foreach (TexturePageEntry entry2 in texture3.Entries) { num++; if (texture3.Alloc(entry2, out _X2, out _Y2)) { entry2.X = _X2; entry2.Y = _Y2; } else { Console.WriteLine("This should not happen #2"); } } } int num7 = 0; foreach (Texture texture4 in Textures) { texture4.TP = num7; texture4.CopyEntries(); num7++; } } } }