Пример #1
0
            static bool minimizeArea(IntRectangle a, IntRectangle b, IntSize item)
            {
                var x0 = a.Width - item.Width;
                var y0 = a.Height - item.Height;
                var x1 = b.Width - item.Width;
                var y1 = b.Height - item.Height;

                return((x0 + y0) <= (x1 + y1));
            }
Пример #2
0
        internal unsafe Glyph(Font font, int index)
        {
            // Get glyph index (search)
            Index = index;
            Font  = font;

            // Get horizontal metrics (at raw scale)
            int advWidth, bearing;

            stbtt_GetGlyphHMetrics(Font.Info, Index, &advWidth, &bearing);
            _advanceWidth = advWidth;
            _bearing      = bearing;

            // Get glyph box info
            int x0, x1, y0, y1;

            stbtt_GetGlyphBitmapBox(Font.Info, Index, 1F, 1F, &x0, &y0, &x1, &y1);
            Box = new IntRectangle(x0, y0, x1 - x0, y1 - y0);
        }
Пример #3
0
        private void Partition(IntRectangle itemRect)
        {
            var _rems = new List <IntRectangle>(128);
            var _adds = new List <IntRectangle>(128);

            // For all known free rects
            foreach (var freeRect in _freeRects)
            {
                // If the free rect overlaps the item rect
                if (freeRect.Overlaps(itemRect))
                {
                    // Generate the new partitions
                    _adds.AddRange(GeneratePartitions(freeRect, itemRect));

                    // Remove the free rect
                    _rems.Add(freeRect);
                }

                // Remove other free rects that fully contained
                foreach (var other in _freeRects)
                {
                    if (freeRect == other)
                    {
                        continue;
                    }
                    if (freeRect.Contains(other))
                    {
                        _rems.Add(other);
                    }
                }
            }

            // Perform mutations to rectangle set
            foreach (var rect in _rems)
            {
                _freeRects.Remove(rect);
            }
            foreach (var rect in _adds)
            {
                _freeRects.Add(rect);
            }
        }
Пример #4
0
        protected override bool Insert(IntSize itemSize, out IntRectangle itemRect)
        {
            // Try to find suitable rectangle for item
            if (TryGetSuitableFreeRect(itemSize, out var freeRect))
            {
                // Store the element and associate rectangle
                itemRect = new IntRectangle(freeRect.Position, itemSize);

                // Partition and merge the free rects
                Partition(itemRect);

                return(true);
            }
            else
            {
                // Unable to fit item into any rectangle
                itemRect = default;
                return(false);
            }
        }
Пример #5
0
        private bool TryGetSuitableFreeRect(IntSize itemSize, out IntRectangle freeRectangle)
        {
            freeRectangle = IntRectangle.Infinite;

            var found = false;

            //
            foreach (var freeRect in _freeRects.OrderBy(r => r.Min.X + r.Min.Y))
            {
                // If the item can fit in here...
                if (freeRect.Width >= itemSize.Width && freeRect.Height >= itemSize.Height)
                {
                    // Select the free rect that causes minimal wasted area
                    if (minimizeArea(freeRectangle, freeRect, itemSize))
                    {
                        freeRectangle = freeRect;
                        found         = true;
                    }
                }
            }

            // Return if we found a suitable rectangle
            return(found);
Пример #6
0
 /// <summary>
 /// Constructs a new nine slice.
 /// </summary>
 public NineSlice(Image frame, IntRectangle center)
 {
     Image  = frame ?? throw new ArgumentNullException(nameof(frame));
     Center = center;
 }
Пример #7
0
 internal GlyphMetrics(float advanceWidth, float bearing, IntRectangle box)
 {
     AdvanceWidth = advanceWidth;
     Bearing      = bearing;
     _box         = box;
 }
Пример #8
0
        private static IEnumerable <IntRectangle> GeneratePartitions(IntRectangle freeRect, IntRectangle itemRect)
        {
            var ht = itemRect.Top - freeRect.Top;

            if (ht > 0)
            {
                yield return(new IntRectangle(freeRect.X, freeRect.Y, freeRect.Width, ht));
            }

            var hb = freeRect.Bottom - itemRect.Bottom;

            if (hb > 0)
            {
                yield return(new IntRectangle(freeRect.X, itemRect.Bottom, freeRect.Width, hb));
            }

            var wr = freeRect.Right - itemRect.Right;

            if (wr > 0)
            {
                yield return(new IntRectangle(itemRect.Right, freeRect.Top, wr, freeRect.Height));
            }

            var wl = itemRect.Left - freeRect.Left;

            if (wl > 0)
            {
                yield return(new IntRectangle(freeRect.Left, freeRect.Top, wl, freeRect.Height));
            }
        }
Пример #9
0
 /// <summary>
 /// Rasterize a rectangular region.
 /// </summary>
 public static IEnumerable <IntVector> Rectangle(IntRectangle rect)
 {
     return(Rectangle(rect.X, rect.Y, rect.Width, rect.Height));
 }
Пример #10
0
 protected abstract bool Insert(IntSize size, out IntRectangle rectangle);
Пример #11
0
 public bool TryGetRectangle(TElement element, out IntRectangle rectangle)
 {
     return(_elements.TryGetValue(element, out rectangle));
 }
Пример #12
0
 /// <inheritdoc/>
 public bool TryGetRectangle(T element, out IntRectangle rectangle)
 {
     return(((IRectanglePacker <T>)_impl).TryGetRectangle(element, out rectangle));
 }