This repository has been archived on 2024-04-07. You can view files and clone it, but cannot push or open issues or pull requests.
chovy-gm/GMAssetCompiler/yyRect.cs

297 lines
5.6 KiB
C#

using System.Collections.Generic;
using System.Drawing;
namespace GMAssetCompiler
{
public class yyRect
{
public ulong CRC;
public bool packflag;
public bool full;
public ushort x;
public ushort y;
public ushort width;
public ushort height;
public int arealeft;
public List<yyRect> Children;
public int top
{
get
{
return y;
}
}
public int left
{
get
{
return x;
}
}
public int bottom
{
get
{
return y + height;
}
}
public int right
{
get
{
return x + width;
}
}
public int area
{
get
{
return width * height;
}
}
public override string ToString()
{
return string.Format("{0},{1}, {2},{3}, {4}", x, y, width, height, area);
}
public static yyRect Create(int _width, int _height)
{
yyRect yyRect = new yyRect(0, 0, _width, _height);
yyRect.Children = new List<yyRect>();
yyRect.Children.Add(yyRect);
return yyRect;
}
public yyRect(int _x, int _y, int _width, int _height)
{
Children = null;
x = (ushort)_x;
y = (ushort)_y;
width = (ushort)_width;
height = (ushort)_height;
arealeft = area;
CRC = (x | ((ulong)y << 16) | ((ulong)width << 32) | ((ulong)height << 48));
}
private List<yyRect> Clip(int _x, int _y, int _w, int _h, out bool _full)
{
_full = false;
if (_x >= right || _x + _w <= left || _y >= bottom || _y + _h <= top)
{
return null;
}
if (right > _x && left < _x + _w && top > _y && bottom < _y + height)
{
_full = true;
return null;
}
if (_x == x && _y == y && _w == width && _h == height)
{
_full = true;
return null;
}
List<yyRect> list = new List<yyRect>();
if (_x > left)
{
int num = _x - left;
list.Add(new yyRect(left, y, num, height));
}
int num2 = _x + _w;
if (num2 < right)
{
list.Add(new yyRect(num2, y, right - num2, height));
}
if (_y > top)
{
int num3 = _y - top;
list.Add(new yyRect(x, y, width, num3));
}
int num4 = _y + _h;
if (num4 < bottom)
{
list.Add(new yyRect(x, num4, width, bottom - num4));
}
return list;
}
public yyRect Test(int _width, int _height)
{
arealeft = 0;
if (Children.Count == 0)
{
return null;
}
yyRect result = null;
foreach (yyRect child in Children)
{
foreach (yyRect child2 in Children)
{
bool _full = false;
if (child2.width >= _width && child2.height >= _height)
{
List<yyRect> list = child.Clip(child2.x, child2.y, _width, _height, out _full);
if (list == null && _full)
{
arealeft = child.arealeft;
result = child2;
}
else if (list != null && list.Count != 0)
{
foreach (yyRect item in list)
{
if (item != null && arealeft < item.arealeft)
{
arealeft = item.arealeft;
result = child2;
}
}
}
else if (arealeft < child.arealeft)
{
arealeft = child.arealeft;
result = child2;
}
}
}
}
return result;
}
private List<yyRect> AddImageEx(int _width, int _height, out bool _full)
{
_full = false;
List<yyRect> list = Clip(x, y, _width, _height, out _full);
if (list == null || list.Count == 0)
{
return null;
}
return list;
}
private void AddRange(List<yyRect> _rects)
{
foreach (yyRect _rect in _rects)
{
bool flag = false;
int count = Children.Count;
for (int i = 0; i < count; i++)
{
if (Children[i].CRC == _rect.CRC)
{
flag = true;
break;
}
}
if (!flag)
{
Children.Add(_rect);
}
}
}
public void CompactList()
{
foreach (yyRect child in Children)
{
child.packflag = false;
}
List<yyRect> list = new List<yyRect>(128);
foreach (yyRect child2 in Children)
{
if (!child2.packflag)
{
foreach (yyRect child3 in Children)
{
if (child2 != child3 && !child3.packflag && child3.x >= child2.x && child3.y >= child2.y && child3.right <= child2.right && child3.bottom <= child2.bottom)
{
list.Add(child3);
child3.packflag = true;
}
}
}
}
foreach (yyRect item in list)
{
Children.Remove(item);
}
}
public Point AddImage(yyRect _rect, int _width, int _height)
{
if (_rect == null)
{
return new Point(-1, -1);
}
bool _full = false;
List<yyRect> list = _rect.AddImageEx(_width, _height, out _full);
int num = _rect.x;
int num2 = _rect.y;
if (_full || (list != null && list.Count != 0))
{
if (_rect != this)
{
Children.Remove(_rect);
}
if (list != null && list.Count != 0)
{
if (Children == null)
{
Children = new List<yyRect>(64);
}
AddRange(list);
}
}
List<yyRect> list2 = new List<yyRect>(64);
List<yyRect> list3 = new List<yyRect>(64);
foreach (yyRect child in Children)
{
_full = false;
list = child.Clip(num, num2, _width, _height, out _full);
if (_full || (list != null && list.Count != 0))
{
list2.Add(child);
if (list != null && list.Count != 0)
{
list3.AddRange(list);
}
}
}
foreach (yyRect item in list2)
{
Children.Remove(item);
}
if (list3.Count != 0)
{
AddRange(list3);
}
CompactList();
return new Point(num, num2);
}
public void Draw(Graphics _gr, int _ox, int _oy)
{
if (Children != null && Children.Count != 0)
{
foreach (yyRect child in Children)
{
_gr.DrawRectangle(rect: new Rectangle(child.x + _ox, child.y + _oy, child.width - 1, child.height - 1), pen: Pens.Yellow);
}
}
}
}
}