public bool Insert(AtlasImage image, out Rect rect)
        {
            int width  = image.Width + Spacing.Left + Spacing.Right;
            int height = image.Height + Spacing.Top + Spacing.Bottom;

            if (Packer.Insert(width, height, Heuristic, out rect))
            {
                // we don't want to change the size of the image,
                // so we remove the offsets after packing
                rect.X += Spacing.Left;
                rect.Y += Spacing.Top;
                rect.W -= Spacing.Left + Spacing.Right;
                rect.H -= Spacing.Top + Spacing.Bottom;

                return(true);
            }
            return(false);
        }
Ejemplo n.º 2
0
        public unsafe AtlasData Serialize(
            AtlasPacker packer, DirectoryInfo output,
            TextureDelegate onTexture, ProgressDelegate onProgress)
        {
            int stateCount  = packer._states.Count;
            int singleCount = packer._singles.Count;
            var textures    = new string[stateCount + singleCount];

            int totalItemCount = packer.TotalItemCount;
            var items          = new List <AtlasData.Item>(totalItemCount);

            if (!output.Exists)
            {
                output.Create();
            }

            void AddItem(AtlasData.Item item)
            {
                items.Add(item);
                onProgress.Invoke(items.Count / (float)totalItemCount);
            }

            for (int textureIndex = 0; textureIndex < stateCount; textureIndex++)
            {
                AtlasPackerState state = packer._states[textureIndex];
                int width  = state.Width;
                int height = state.Height;

                using (var result = new Image <Rgba32>(width, height))
                {
                    Span <Rgba32> resultSpan = result.GetPixelSpan();
                    foreach (AtlasPackerState.Item item in state.Items)
                    {
                        using (var img = Image.Load <Rgba32>(item.AtlasImage.File.OpenRead()))
                        {
                            var srcRect = new Rect(0, 0, img.Width, img.Height);
                            var input32 = img.GetPixelSpan();

                            Copy(input32, inputStride: srcRect.W, srcRect,
                                 resultSpan, outputStride: width, item.Rect);

                            AddItem(new AtlasData.Item(item.AtlasImage.RelativePath, textureIndex, item.Rect));
                        }
                    }

                    using (var fs = GetFileStream(textures, textureIndex, output))
                        result.Save(fs, SaveFormat);

                    onTexture?.Invoke(resultSpan, new Size(width, height), textureIndex);
                }
            }

            for (int singleIndex = 0; singleIndex < singleCount; singleIndex++)
            {
                AtlasImage item = packer._singles[singleIndex];
                using (var img = Image.Load <Rgba32>(item.File.OpenRead()))
                {
                    int index = singleIndex + stateCount; // add amount of states as offset
                    using (var fs = GetFileStream(textures, index, output))
                        img.Save(fs, SaveFormat);

                    AddItem(new AtlasData.Item(item.RelativePath, index, 0, 0, item.Width, item.Height));
                    onTexture?.Invoke(img.GetPixelSpan(), new Size(item.Width, item.Height), index);
                }
            }

            return(new AtlasData(textures, items));
        }
 public Item(Rect rect, AtlasImage image)
 {
     Rect       = rect;
     AtlasImage = image;
 }