protected override bool Insert(IntSize size, out IntRectangle rect) { // Find first acceptable insertion for (var i = 0; i < Strips.Count; i++) { // Try to fit compact if (CheckFit(i, in size)) { // Anchor image to rect = new IntRectangle(Strips[i].Position, size); InsertStrip(new Strip(rect.X, rect.Y + size.Height, size.Width)); return(true); } } // No acceptable insertion, try to place on "shelf" if (CheckFitShelf(size, out var shelf)) { rect = new IntRectangle((0, shelf), size); InsertStrip(new Strip(0, shelf + size.Height, size.Width)); return(true); } // Unable to find a place to insert rect = default; return(false); }
internal Surface(IntSize size, MultisampleQuality multisample, SurfaceType surfaceType, bool isScreenBound) { if (size.Width <= 0 || size.Height <= 0) { throw new ArgumentException("Surface dimensions must be greater than zero."); } Size = size; IsScreenBound = isScreenBound; SurfaceType = surfaceType; // Keep highest supported MSAA level. Multisample = Calc.Min(multisample, GraphicsAdapter.SurfaceFactory.MaxSupportedMultisampleQuality); if (Multisample != multisample) { Log.Warning($"Requested MSAA level '{multisample}' was not supported on this device."); } if (!IsScreenBound) { // Surface is an offscreen render target Native = GraphicsAdapter.SurfaceFactory.Create(this); Multisample = multisample; } else { if (SurfaceType != SurfaceType.UnsignedByte) { throw new ArgumentException($"Screen bound surfaces must be have type '{nameof(SurfaceType.UnsignedByte)}'."); } } }
/// <summary> /// Constructs a new blank image of the specified size. /// </summary> /// <param name="width">The width of the image in pixels.</param> /// <param name="height">The height of the image in pixels.</param> /// <exception cref="ArgumentException">Thrown when any dimension is negative or exceeds <see cref="MaxImageDimension"/>.</exception> public Image(int width, int height) { ValidateImageSize(in width, in height); // Allocate pixels Pixels = new ColorBytes[width * height]; _size = new IntSize(width, height); }
public SkylinePacker(IntSize size) : base(size) { Strips = new List <Strip>(); // Start clean Clear(); }
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)); }
private static Queue <Surface> GetPool(IntSize size, MultisampleQuality multisample) { var key = (multisample, size); if (_pools.TryGetValue(key, out var pool)) { // Return already known pool return(pool); } else { // Construct pool _pools[key] = new Queue <Surface>(); return(_pools[key]); } }
public bool TryAdd(TElement element, IntSize itemSize) { if (Contains(element)) { // Already packed. return(false); } else if (Insert(itemSize, out var rectangle)) { // Rectangle was inserted, store element. _elements[element] = rectangle; return(true); } else { // Failed to insert return(false); } }
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); } }
/// <summary> /// Loads an image directly from a block of bytes. /// </summary> /// <exception cref="InvalidOperationException">Thrown if an error was encountered when loading the image.</exception> public unsafe Image(byte[] file) { // Decode from file to raw RGBA bytes var result = ImageResult.FromMemory(file, ColorComponents.RedGreenBlueAlpha); var width = result.Width; var height = result.Height; // Ensure image size is acceptable and no error while loading occurred ValidateImageSize(in width, in height); // Allocate pixels Pixels = new ColorBytes[width * height]; _size = new IntSize(width, height); // Copy grabbed pixels to image fixed(byte *ptr = result.Data) { Copy((ColorBytes *)ptr, width, (0, 0, width, height), this, IntVector.Zero); } }
/// <summary> /// Requests a temporary surface. /// </summary> /// <param name="size">The size of the surface.</param> /// <param name="multisample">The multisample quality of the surface.</param> /// <returns>A surface owned by this pool.</returns> public static Surface Request(IntSize size, MultisampleQuality multisample = MultisampleQuality.None) { // Get the associated pool the specified multisample level var pool = GetPool(size, multisample); lock (pool) { if (pool.Count > 0) { // Return an existing surface return(pool.Dequeue()); } } // The pool did not return a surface... lock (_owned) { // Construct a new surface and return it. var surface = new Surface(size, multisample); _owned.Add(surface); return(surface); } }
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);
/// <summary> /// Constructs a new instance of <see cref="IntRectangle"/>. /// </summary> /// <param name="position">The position of the rectangle.</param> /// <param name="size">The size of the rectangle.</param> public IntRectangle(IntVector position, IntSize size) : this(position.X, position.Y, size.Width, size.Height) { }
/// <inheritdoc/> public bool TryAdd(T element, IntSize itemSize) { return(((IRectanglePacker <T>)_impl).TryAdd(element, itemSize)); }
protected RectanglePackerImpl(IntSize size) { _elements = new Dictionary <TElement, IntRectangle>(); Size = size; }
public MaxrectsPacker(IntSize size) : base(size) { // Start clean Clear(); }
protected abstract bool Insert(IntSize size, out IntRectangle rectangle);
/// <summary> /// Creates a new surface. /// </summary> /// <param name="size">Size of the surface in pixels.</param> /// <param name="multisample">MSAA to use on the surface</param> /// <param name="surfaceType">The storage format of the surface.</param> public Surface(IntSize size, MultisampleQuality multisample = MultisampleQuality.None, SurfaceType surfaceType = SurfaceType.UnsignedByte) : this(size, multisample, surfaceType, false) { }
/// <summary> /// Constructs a new blank image of the specified size. /// </summary> /// <param name="size">The size of the image in pixels.</param> /// <exception cref="ArgumentException">Thrown when any dimension is negative or exceeds <see cref="MaxImageDimension"/>.</exception> public Image(IntSize size) : this(size.Width, size.Height) { }
internal void SetSize(IntSize size) { Size = size; }
private bool CheckFitShelf(IntSize size, out int shelf) { shelf = Strips.Where(s => s.X < size.Width).Max(s => s.Y); return(Size.Height - shelf >= size.Height); }
/// <summary> /// Rasterize a rectangular region. /// </summary> public static IEnumerable <IntVector> Rectangle(IntVector position, IntSize size) { return(Rectangle(position.X, position.Y, size.Width, size.Height)); }
/// <summary> /// Constructs a new instance of <see cref="RectanglePacker{T}"/>. /// </summary> /// <param name="size">The size of the container rectangle.</param> /// <param name="quality">The packing algorithm to use.</param> public RectanglePacker(IntSize size, PackingAlgorithm quality = PackingAlgorithm.Maxrects) : this(size.Width, size.Height, quality) { }
/// <summary> /// Rasterize a rectangular region. /// </summary> public static IEnumerable <IntVector> Rectangle(IntSize size) { return(Rectangle(0, 0, size.Width, size.Height)); }