4 using System.Collections.Generic;
6 using SiliconStudio.Core.Mathematics;
8 namespace SiliconStudio.
Paradox.Effects.Modules.Processors
14 internal class GuillotinePacker
16 private readonly List<Rectangle> freeRectangles =
new List<Rectangle>();
17 private readonly List<Rectangle> tempFreeRectangles =
new List<Rectangle>();
19 public int Width {
get;
private set; }
20 public int Height {
get;
private set; }
22 public void Clear(
int width,
int height)
24 freeRectangles.Clear();
25 freeRectangles.Add(
new Rectangle {
X = 0,
Y = 0, Width = width, Height = height });
38 freeRectangles.Add(oldRectangle);
43 return Insert(width, height, freeRectangles, ref bestRectangle);
46 public bool TryInsert(
int width,
int height,
int count)
49 tempFreeRectangles.Clear();
50 tempFreeRectangles.AddRange(freeRectangles);
52 for (var i = 0; i <
count; ++i)
54 if (!
Insert(width, height, tempFreeRectangles, ref bestRectangle))
56 tempFreeRectangles.Clear();
62 freeRectangles.Clear();
63 freeRectangles.AddRange(tempFreeRectangles);
64 tempFreeRectangles.Clear();
69 private static bool Insert(
int width,
int height, List<Rectangle> freeRectanglesList , ref
Rectangle bestRectangle)
72 int bestScore = int.MaxValue;
73 int freeRectangleIndex = -1;
76 for (
int i = 0; i < freeRectanglesList.Count; ++i)
78 var currentFreeRectangle = freeRectanglesList[i];
79 if (width == currentFreeRectangle.Width && height == currentFreeRectangle.Height)
82 bestRectangle.X = currentFreeRectangle.X;
83 bestRectangle.Y = currentFreeRectangle.Y;
84 bestRectangle.Width = width;
85 bestRectangle.Height = height;
86 freeRectangleIndex = i;
89 if (width <= currentFreeRectangle.Width && height <= currentFreeRectangle.Height)
93 var score = currentFreeRectangle.Width * currentFreeRectangle.Height - width * height;
94 if (score < bestScore)
96 bestRectangle.X = currentFreeRectangle.X;
97 bestRectangle.Y = currentFreeRectangle.Y;
98 bestRectangle.Width = width;
99 bestRectangle.Height = height;
101 freeRectangleIndex = i;
107 if (freeRectangleIndex == -1)
110 var freeRectangle = freeRectanglesList[freeRectangleIndex];
113 int w = freeRectangle.Width - bestRectangle.Width;
114 int h = freeRectangle.Height - bestRectangle.Height;
115 var splitHorizontal = (bestRectangle.Width * h > w * bestRectangle.Height);
118 var bottom =
new Rectangle {
X = freeRectangle.X,
Y = freeRectangle.Y + bestRectangle.Height, Width = splitHorizontal ? freeRectangle.Width : bestRectangle.Width, Height = h };
119 var right =
new Rectangle {
X = freeRectangle.X + bestRectangle.Width,
Y = freeRectangle.Y, Width = w, Height = splitHorizontal ? bestRectangle.Height : freeRectangle.Height };
121 if (bottom.Width > 0 && bottom.Height > 0)
122 freeRectanglesList.Add(bottom);
123 if (right.Width > 0 && right.Height > 0)
124 freeRectanglesList.Add(right);
127 if (freeRectangleIndex != freeRectanglesList.Count - 1)
128 freeRectanglesList[freeRectangleIndex] = freeRectanglesList[freeRectanglesList.Count - 1];
129 freeRectanglesList.RemoveAt(freeRectanglesList.Count - 1);
System.Windows.Shapes.Rectangle Rectangle
Structure using the same layout than System.Drawing.Rectangle