// Attempt to allocate a slot, returns false if it could not allocate, which is very bad private bool allocateSlot(StitchHolder holder) { // Try to insert it into all current slots with both rotations foreach (StitchSlot slot in _slotList) { if (slot.AddSlot(holder)) return true; holder.Rotate(); if (slot.AddSlot(holder)) return true; holder.Rotate(); } // Make it bigger, and try inserting it in the new space return expandAndAllocateSlot(holder); }
// Attempts to place the holder into the final image, returns false if it failed public bool AddSlot(StitchHolder holder) { if (Holder != null) return false; else { int i = holder.GetWidth(); int j = holder.GetHeight(); if (i <= Width && j <= Height) { if (i == Width && j == Height) { Holder = holder; return true; } else { if (_subSlots == null) { // Subdivide remaining space for the subslots _subSlots = new List<StitchSlot>(); _subSlots.Add(new StitchSlot(OriginX, OriginY, i, j)); int k = Width - i; int l = Height - j; if (k > 0 && l > 0) { int i1 = Math.Max(Height, k); int j1 = Math.Max(Width, l); if (i1 >= j1) { _subSlots.Add(new StitchSlot(OriginX, OriginY + j, i, l)); _subSlots.Add(new StitchSlot(OriginX + i, OriginY, k, Height)); } else { _subSlots.Add(new StitchSlot(OriginX + i, OriginY, k, j)); _subSlots.Add(new StitchSlot(OriginX, OriginY + j, Width, l)); } } else if (k == 0) _subSlots.Add(new StitchSlot(OriginX, OriginY + j, i, l)); else if (l == 0) _subSlots.Add(new StitchSlot(OriginX + i, OriginY, k, j)); } foreach (StitchSlot slot in _subSlots) { if (slot.AddSlot(holder)) return true; } return false; } } else return false; } }
// Try to make the resulting image bigger, and add the slot, returns false if it could not allocate private bool expandAndAllocateSlot(StitchHolder holder) { int i = Math.Min(holder.GetWidth(), holder.GetHeight()); bool flag = (CurrentWidth == 0 && CurrentHeight == 0); bool mw = CurrentWidth + i <= MAX_DIMENSIONS; bool mh = CurrentHeight + i <= MAX_DIMENSIONS; // If we are out of space if (!mw && !mh) return false; bool flag1 = mw && (flag || (CurrentWidth <= CurrentHeight)); int j = Math.Max(holder.GetWidth(), holder.GetHeight()); // Expanding it would run out of space if (MathUtil.NextPowerOf2((flag1 ? CurrentWidth : CurrentHeight) + j) > MAX_DIMENSIONS) return false; else { StitchSlot slot; if (flag1) { if (holder.GetWidth() > holder.GetHeight()) holder.Rotate(); if (CurrentHeight == 0) CurrentHeight = holder.GetHeight(); slot = new StitchSlot(CurrentWidth, 0, holder.GetWidth(), CurrentHeight); CurrentWidth += holder.GetWidth(); } else { slot = new StitchSlot(0, CurrentHeight, CurrentWidth, holder.GetHeight()); CurrentHeight += holder.GetHeight(); } if (!slot.AddSlot(holder)) return false; _slotList.Add(slot); return true; } }