protected override void Start()
    {
        _DKumaGenerator = GameObject.Find("DKUMAGenerator").GetComponent <DKUMAGenerator>();
        //	umaGenerator.umaData.cleanTextures();

        materialDefinitionList = new List <DKUMAData.MaterialDefinition>();

        //Update atlas area can be handled here
        DKUMAData.MaterialDefinition tempMaterialDefinition = new DKUMAData.MaterialDefinition();

        DKSlotData[] slots = umaGenerator.umaData.umaRecipe.slotDataList;
        if (slots == null)
        {
            Debug.LogError(umaGenerator.umaData.gameObject.name + " can not be generated : the Slot list is umpty. Verify your Elements configuration.");
        }
        else
        if (slots.Length > 0)
        {
            for (int i = 0; i < slots.Length; i++)
            {
                if (slots[i] != null && slots[i].overlayList.Count != 0)
                {
                    tempMaterialDefinition                        = new DKUMAData.MaterialDefinition();
                    tempMaterialDefinition.baseTexture            = slots[i].overlayList[0].textureList;
                    tempMaterialDefinition.baseColor              = slots[i].overlayList[0].color;
                    tempMaterialDefinition.materialSample         = slots[i].materialSample;
                    tempMaterialDefinition.overlays               = new DKUMAData.textureData[slots[i].overlayList.Count - 1];
                    tempMaterialDefinition.overlayColors          = new Color32[tempMaterialDefinition.overlays.Length];
                    tempMaterialDefinition.rects                  = new Rect[tempMaterialDefinition.overlays.Length];
                    tempMaterialDefinition.channelMask            = new Color32[tempMaterialDefinition.overlays.Length + 1][];
                    tempMaterialDefinition.channelAdditiveMask    = new Color32[tempMaterialDefinition.overlays.Length + 1][];
                    tempMaterialDefinition.channelMask[0]         = slots[i].overlayList[0].channelMask;
                    tempMaterialDefinition.channelAdditiveMask[0] = slots[i].overlayList[0].channelAdditiveMask;
                    tempMaterialDefinition.slotData               = slots[i];

                    for (int overlayID = 0; overlayID < slots[i].overlayList.Count - 1; overlayID++)
                    {
                        tempMaterialDefinition.overlays[overlayID]                = new DKUMAData.textureData();
                        tempMaterialDefinition.rects[overlayID]                   = slots[i].overlayList[overlayID + 1].rect;
                        tempMaterialDefinition.overlays[overlayID].textureList    = slots[i].overlayList[overlayID + 1].textureList;
                        tempMaterialDefinition.overlayColors[overlayID]           = slots[i].overlayList[overlayID + 1].color;
                        tempMaterialDefinition.channelMask[overlayID + 1]         = slots[i].overlayList[overlayID + 1].channelMask;
                        tempMaterialDefinition.channelAdditiveMask[overlayID + 1] = slots[i].overlayList[overlayID + 1].channelAdditiveMask;
                    }
                    materialDefinitionList.Add(tempMaterialDefinition);
                }
            }
        }

        if (_DKumaGenerator.usePRO && UnityEditorInternal.InternalEditorUtility.HasPro())
        {
            textureProcessPROCoroutine = new DK_RPG_TextureProcessPROCoroutine();
        }
        else
        {
            textureProcessIndieCoroutine = new DK_RPG_TextureProcessIndieCoroutine();
        }

        packTexture = new MaxRectsBinPack(_DKumaGenerator.atlasResolution, _DKumaGenerator.atlasResolution, false);
    }
Пример #2
0
        public void Execute(object parameter)
        {
            mpm.FB_UI_Atlas.Sprites.Clear();
            mpm.Rectangles.Clear();
            mpm.FB_UI_Atlas.Fonts.Clear();

            FontSettings fontSettings = new FontSettings();

            MaxRectsBinPack binPack = new MaxRectsBinPack((int)mpm.TextureWidth, (int)mpm.TextureHeight, false);

            //fontsize 20
            mpm.FontSystem.GenerateFont(mpm.Rectangles,
                                        mpm.FB_UI_Atlas.Fonts,
                                        binPack,
                                        fontSettings);

            //fontsize 40
            fontSettings = new FontSettings()
            {
                FontSize = 40
            };

            mpm.FontSystem.GenerateFont(mpm.Rectangles,
                                        mpm.FB_UI_Atlas.Fonts,
                                        binPack,
                                        fontSettings);


            AtlasHelper.GenAtlas(binPack, mpm.Rectangles, mpm.FB_UI_Atlas.Sprites, mpm.ImageFolder, mpm.ImageExtensions, mpm.TextureWidth, mpm.TextureHeight);
        }
Пример #3
0
    public DynamicAtlas(int width, int height, string name, HeuristicMethod method = HeuristicMethod.RectBestShortSideFit)
    {
        Texture      = new Texture2D(width, height, TextureFormat.RGBA32, false);
        Texture.name = name;
        this.method  = method;

        rectsPack = new MaxRectsBinPack(width, height, false);
        names     = new List <string>();
    }
Пример #4
0
    private void SubLayoutCells(ref float maxHeight, List <PUTableCell> cellsToAdd, MaxRectsBinPack.FreeRectChoiceHeuristic heuristic)
    {
        RectTransform contentRectTransform = contentObject.transform as RectTransform;

        float blockHeight = 2048.0f;
        float baseY       = maxHeight;

        if (cellsToAdd [0].IsHeader())
        {
            PUTableCell cell = cellsToAdd [0];
            cellsToAdd.RemoveAt(0);

            cell.puGameObject.rectTransform.anchoredPosition = new Vector2(0, -baseY);

            baseY += cell.puGameObject.rectTransform.sizeDelta.y;
        }

        // The MaxRects packer works by being given a canvas (width/height) to fit all rectangles in
        // For us to use this and allow arbitrary height, we give it a rect the size of the visible
        // scroll area, fill it up, and then repeat until we run out of cells.
        int bail = 500;

        while (cellsToAdd.Count > 0 && bail > 0)
        {
            MaxRectsBinPack packer = new MaxRectsBinPack((int)contentRectTransform.rect.width, (int)blockHeight, false);

            for (int i = cellsToAdd.Count - 1; i >= 0; i--)
            {
                PUTableCell cell = cellsToAdd [i];
                LORect      packedRect;

                if (packer.Insert((int)cell.puGameObject.rectTransform.sizeDelta.x, (int)cell.puGameObject.rectTransform.sizeDelta.y, heuristic, cell.puGameObject.rectTransform, out packedRect))
                {
                    packedRect.y += baseY;
                    cell.puGameObject.rectTransform.anchoredPosition = new Vector2(packedRect.x, -packedRect.y);
                    if ((packedRect.y + packedRect.height) > maxHeight)
                    {
                        maxHeight = (packedRect.y + packedRect.height);
                    }
                    cellsToAdd.RemoveAt(i);
                }
            }

            if (expandToFill)
            {
                packer.ExpandRectsToFill((int)contentRectTransform.rect.width, (maxHeight - baseY));
            }

            baseY = maxHeight;
            bail--;
        }

        if (bail == 0)
        {
            Debug.Log("Warning: PUGridTable layout failed to place all cells");
        }
    }
Пример #5
0
 public TextureAtlas(int size, string name = null)
 {
     texture = new Texture2D(size, size);
     if (name != null)
         texture.name = name;
     else
         texture.name = Guid.NewGuid().ToString();
     pack = new MaxRectsBinPack(size, size, false);
     rects = new Dictionary<int, Rect>();
 }
Пример #6
0
 public TextureAtlas(int size, string name = null)
 {
     texture = new Texture2D(size, size);
     if (name != null)
     {
         texture.name = name;
     }
     else
     {
         texture.name = Guid.NewGuid().ToString();
     }
     pack  = new MaxRectsBinPack(size, size, false);
     rects = new Dictionary <int, Rect>();
 }
Пример #7
0
    void CopyOri(List <rectData> _ori, string atlasName)
    {
        if (_ori == null || _ori.Count == 0)
        {
            //Debug.Log("完成");
            return;
        }
        List <Rect> rc = new List <Rect>();

        foreach (var item in _ori)
        {
            rc.Add(item.rect);
        }
        List <rectData> _surplus = new List <rectData>();
        List <rectData> mItemp   = new List <rectData>();

        // 图集组合优化: 一个图集,固定size,源图片中选择最佳组合,最大化利用图集size
        MaxRectsBinPack temp = new MaxRectsBinPack(1024, 1024, false);

        temp.insert2(rc, new List <Rect>(), inputReactDic[InputKey]);

        for (int i = 0; i < _ori.Count; i++)
        {
            Rect     rect = temp.usedRectangles[i];
            rectData data = new rectData();
            data = _ori[i];
            if (rect == new Rect())
            {
                _surplus.Add(data);
            }
            else
            {
                data.rect = rect;
                mItemp.Add(data);
            }
        }
        if (mItemp.Count != 0)
        {
            histDic.Add((atlasName + "_" + (++key)).ToString(), mItemp);
            CopyOri(_surplus, atlasName);
        }
        else
        {
            foreach (var item in _surplus)
            {
                Debug.LogError("图片大于1024相素 : " + item.key);
                //NGUIDebug.Log("图片大于1024相素 : " + item.key);
            }
        }
    }
Пример #8
0
        //合并小的图集为一张大图
        private IEnumerator FinallyPackage(CombineTextureData combineTextureData, Dictionary <RenderTexture, TextureClass[]> dic, Action <PackagedTextureResult> finishCallBack)
        {
            PackagedTextureResult result          = new PackagedTextureResult();
            TextureSize           size            = GetAtlasSize(combineTextureData.smallAtlasNumber);
            MaxRectsBinPack       maxRectsBinPack = new MaxRectsBinPack(size.x, size.y, false);
            Material            material          = InitMaterial();
            RenderTexture       render            = RenderTexture.GetTemporary(size.x, size.y, 0, RenderTextureFormat.ARGB4444);
            List <TextureClass> tc = new List <TextureClass> ();

            Graphics.Blit(null, null, material, 0);
            foreach (KeyValuePair <RenderTexture, TextureClass[]> keys in dic)
            {
                RenderTexture tempTexture = keys.Key;
                Rect          rect        = maxRectsBinPack.Insert(tempTexture.width, tempTexture.height, MaxRectsBinPack.FreeRectChoiceHeuristic.RectBestAreaFit);
                //重新计算位置
                for (int i = 0; i < keys.Value.Length; i++)
                {
                    keys.Value[i].rect = new Rect(rect.x + keys.Value[i].rect.x, rect.y + keys.Value[i].rect.y, keys.Value[i].rect.width, keys.Value[i].rect.height);
                    tc.Add(keys.Value[i]);
                }
                Rect scaleRect = GetScaleRect(rect, size.x, size.y);
                material.SetTexture("_MainTex", tempTexture);
                material.SetFloat("_ScaleX", scaleRect.width);
                material.SetFloat("_ScaleY", scaleRect.height);
                material.SetFloat("_OffsetX", scaleRect.x);
                material.SetFloat("_OffsetY", scaleRect.y);
                Graphics.Blit(null, render, material, 1);
                //归还小图集RenderTexture
                RenderTexture.ReleaseTemporary(tempTexture);
                tempTexture.Release();
                tempTexture = null;
                yield return(null);
            }
            Graphics.Blit(null, null, material, 0);
            for (int i = 0; i < tc.Count; i++)
            {
                tc[i].rect = GetUVRect(GetScaleRect(tc[i].rect, size.x, size.y), tc[i].textureSize, size.x, size.y);
            }
            result.renderTexture = render;
            result.textureInfo   = tc.ToArray();
            if (null != finishCallBack)
            {
                finishCallBack.Invoke(result);
            }
        }
Пример #9
0
        public void GenerateFont(ObservableCollection <System.Windows.UIElement> list,
                                 ObservableCollection <FontModel> fontList,
                                 MaxRectsBinPack maxRectsBinPack,
                                 FontSettings fontSettings)
        {
            _FontSettings    = fontSettings;
            _MaxRectsBinPack = maxRectsBinPack;
            _fontList        = fontList;
            _uiElemetList    = list;
            string message = "";
            bool   result  = checkBeforeRender(ref message);

            if (!result)
            {
                MessageBox.Show(message);
                return;
            }
            AsynDisplayImage();
        }
        protected override void OnInitialize()
        {
            base.OnInitialize();

            var scale     = 100d;
            var rectCount = 500;

            rectSizes = Enumerable.Range(0, rectCount)
                        .Select(p => new vec2((float)(rand.NextDouble() * scale), (float)(rand.NextDouble() * scale)))
                        .Where(p => 0 != (int)p.x && 0 != (int)p.y)
                        .ToArray();

            rects = new Rect[rectCount];

            var totalWidth = 1024;
            var extraWidth = 128;

            maxRectsBinPack = new MaxRectsBinPack(totalWidth, totalWidth, true);
            for (var i = 0; i < rectSizes.Length; i++)
            {
                var rect = rectSizes[i];
                rects[i] = maxRectsBinPack.Insert((int)rect.x, (int)rect.y, MaxRectsBinPack.FreeRectChoiceHeuristic.RectBestLongSideFit);
                while (rects[i].width == 0)
                {
                    maxRectsBinPack.freeRectangles.Add(new Rect {
                        x = totalWidth, y = 0, width = extraWidth, height = totalWidth + extraWidth
                    });
                    maxRectsBinPack.freeRectangles.Add(new Rect {
                        x = 0, y = totalWidth, width = totalWidth, height = extraWidth
                    });

                    totalWidth += extraWidth;
                    rects[i]    = maxRectsBinPack.Insert((int)rect.x, (int)rect.y, MaxRectsBinPack.FreeRectChoiceHeuristic.RectBestLongSideFit);
                }
            }
        }
Пример #11
0
        public Bitmap test_draw(ObservableCollection <System.Windows.UIElement> list,
                                ObservableCollection <FontModel> fontList,
                                MaxRectsBinPack binPack,
                                string alphabet,
                                FontSettings fontSettings)
        {
            alphabet = alphabet.Replace("\n", "");
            alphabet = alphabet.Replace("\r", "");
            Library library = new Library();
            Face    face    = library.NewFace(fontSettings.FontName, 0);

            // Find the largest glyph bounding rectangle
            //  Rect glyphRect = getGlyphRect(face, alphabet);
            //int glyphWidth = (int)Math.Ceiling(glyphRect.Width) + 4 * fontSettings.OutlineWidth;
            //int glyphHeight = (int)Math.Ceiling(glyphRect.Height) + 4 * fontSettings.OutlineWidth;
            int glyphWidth  = 18 + 4 * fontSettings.OutlineWidth;
            int glyphHeight = 18 + 4 * fontSettings.OutlineWidth;

            //add new font

            FontModel newFont = new FontModel()
            {
                Id            = (ushort)fontSettings.FontSize,
                size          = fontSettings.FontSize,
                lineheight    = glyphHeight,              // 22,
                spacelength   = (int)(glyphWidth * 0.6f), //todo ?
                baseline      = 0,
                kerning       = -0.5f,
                monowidth     = fontSettings.FontSize + 1,
                letterspacing = 0,
                rangeFrom     = alphabet[0],
                rangeTo       = alphabet[alphabet.Length - 1]
            };

            fontList.Add(newFont);


            Bitmap   bmp = new Bitmap((int)Math.Ceiling((double)fontSettings.ImageWidth), (int)Math.Ceiling((double)fontSettings.ImageHeight));
            Graphics g   = Graphics.FromImage(bmp);

            g.Clear(fontSettings.BgColor);
            //g.Clear(Color.Black);q
            int x = 0, y = 0;

            for (int i = 0; i < alphabet.ToCharArray().Length; i++)
            {
                string currentChar0 = alphabet.ToCharArray()[i].ToString();
                uint   glyphIndex   = face.GetCharIndex(uchar2code(currentChar0));


                if (fontSettings.FontSize <= 14)
                {
                    face.SetPixelSizes((uint)0, (uint)fontSettings.FontSize);
                    face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
                    face.Glyph.RenderGlyph(RenderMode.Normal);
                }
                else
                {
                    face.SetCharSize(0, fontSettings.FontSize, 0, 72);
                    face.LoadGlyph(glyphIndex, LoadFlags.ForceAutohint, LoadTarget.Lcd);
                    face.Glyph.RenderGlyph(RenderMode.Lcd);
                }

                //Get character alignment
                float left   = (float)face.Glyph.Metrics.HorizontalBearingX;
                float right  = (float)face.Glyph.Metrics.HorizontalBearingX + (float)face.Glyph.Metrics.Width;
                float top    = (float)face.Glyph.Metrics.HorizontalBearingY;
                float bottom = (float)face.Glyph.Metrics.HorizontalBearingY + (float)face.Glyph.Metrics.Height;
                float FHT    = fontSettings.FontSize;
                int   FHD    = (int)Math.Ceiling(FHT);
                int   kx     = x + face.Glyph.BitmapLeft;
                int   ky     = (int)Math.Round((float)y + (FHD - face.Glyph.BitmapTop));


                ////Select render mode (1 times or 2 times)
                //if (this.grender_mode == "freetype_nearestneighbor")
                //{
                //    face.SetCharSize(0, this.fontHeight * 2, 0, 72);
                //    face.LoadGlyph(glyphIndex, LoadFlags.ForceAutohint, LoadTarget.Lcd);
                //    face.Glyph.RenderGlyph(RenderMode.Lcd);
                //    FTBitmap ftbmp = face.Glyph.Bitmap;
                //    if (ftbmp.Width == 0)
                //    {
                //        x += this.tile_width;
                //        if (x + this.tile_width > this.image_width)
                //        {
                //            x = 0;
                //            y += this.tile_height;
                //        }
                //        continue;
                //    }

                //    Bitmap tmpBmp = ftbmp.ToGdipBitmap(this.penColor);

                //    tmpBmp = kPasteImage(tmpBmp, tile_width * 2, tile_height * 2, (int)face.Glyph.BitmapLeft,
                //                        (int)Math.Round(((float)this.fontHeight * 2 - face.Glyph.BitmapTop)));

                //    Bitmap cBmp = kResizeImage(tmpBmp, tmpBmp.Width / 2, tmpBmp.Height / 2, System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor);
                //    Bitmap nBmp = gray2alpha(cBmp);
                //    cBmp.Dispose();

                //    g.DrawImageUnscaled(nBmp, x + FontSettings.relativePositionX, y + FontSettings.relativePositionY);
                //    nBmp.Dispose();
                //}
                //else if (this.grender_mode == "freetype_HighQualityBicubic")
                //{
                //    face.SetCharSize(0, this.fontHeight * 2, 0, 72);
                //    face.LoadGlyph(glyphIndex, LoadFlags.ForceAutohint, LoadTarget.Lcd);
                //    face.Glyph.RenderGlyph(RenderMode.Lcd);
                //    FTBitmap ftbmp = face.Glyph.Bitmap;
                //    if (ftbmp.Width == 0)
                //    {
                //        x += this.tile_width;
                //        if (x + this.tile_width > this.image_width)
                //        {
                //            x = 0;
                //            y += this.tile_height;
                //        }
                //        continue;
                //    }

                //    Bitmap tmpBmp = ftbmp.ToGdipBitmap(this.penColor);

                //    tmpBmp = kPasteImage(tmpBmp, tile_width * 2, tile_height * 2, (int)face.Glyph.BitmapLeft,
                //        (int)Math.Round(((float)this.fontHeight * 2 - face.Glyph.BitmapTop)));

                //    Bitmap cBmp = kResizeImage(tmpBmp, tmpBmp.Width / 2, tmpBmp.Height / 2, System.Drawing.Drawing2D.InterpolationMode.HighQualityBicubic);
                //    Bitmap nBmp = gray2alpha(cBmp);
                //    cBmp.Dispose();

                //    g.DrawImageUnscaled(nBmp, x + FontSettings.relativePositionX, y + FontSettings.relativePositionY);
                //    nBmp.Dispose();

                //}
                //else if (this.grender_mode == "freetype_drawtwice")
                //{
                //    face.LoadGlyph(glyphIndex, LoadFlags.Default, LoadTarget.Normal);
                //    face.Glyph.RenderGlyph(RenderMode.Normal);
                //    FTBitmap ftbmp = face.Glyph.Bitmap;
                //    if (ftbmp.Width == 0)
                //    {
                //        x += this.tile_width;
                //        if (x + this.tile_width > this.image_width)
                //        {
                //            x = 0;
                //            y += this.tile_height;
                //        }
                //        continue;
                //    }
                //    Bitmap cBmp = ftbmp.ToGdipBitmap(this.penColor);
                //    Bitmap sBmp = ftbmp.ToGdipBitmap(this.shadowColor);

                //    Bitmap nBmp = gray2alpha(cBmp);
                //    cBmp.Dispose();

                //    g.DrawImageUnscaled(sBmp, kx + FontSettings.relativePositionX + 1, ky + FontSettings.relativePositionY + 1);//draw twice
                //    g.DrawImageUnscaled(nBmp, kx + FontSettings.relativePositionX, ky + FontSettings.relativePositionY);
                //    cBmp.Dispose();
                //    nBmp.Dispose();

                //}
                //else if (this.grender_mode == "freeyype_nosmoothing")
                //{
                //    face.SetPixelSizes((uint)0, (uint)this.fontHeight);
                //    face.LoadGlyph(glyphIndex, LoadFlags.Monochrome, LoadTarget.Mono);
                //    face.Glyph.RenderGlyph(RenderMode.Mono);
                //    FTBitmap ftbmp = face.Glyph.Bitmap;
                //    if (ftbmp.Width == 0)
                //    {
                //        x += this.tile_width;
                //        if (x + this.tile_width > this.image_width)
                //        {
                //            x = 0;
                //            y += this.tile_height;
                //        }
                //        continue;
                //    }
                //    Bitmap cBmp = ftbmp.ToGdipBitmap(this.penColor);
                //    g.DrawImageUnscaled(cBmp, kx + FontSettings.relativePositionX, ky + FontSettings.relativePositionY);
                //    cBmp.Dispose();
                //}

                //    int tile_width = 24;
                //int tile_height = FontSettings.iFontHeight;//24;
                ////else
                ////{
                FTBitmap ftbmp = face.Glyph.Bitmap;

                //    if (ftbmp.Width == 0)
                //    {
                //        x += tile_width;
                //        if (x + tile_width > this.image_width)
                //        {
                //            x = 0;
                //            y += tile_height;
                //        }
                //        continue;
                //    }


                Bitmap cBmp = ftbmp.ToGdipBitmap(fontSettings.PenColor);
                Bitmap nBmp = gray2alpha(cBmp);

                Rect newPos = binPack.Insert(cBmp.Width, cBmp.Height, MaxRectsBinPack.FreeRectChoiceHeuristic.RectBottomLeftRule);

                //DebugRectangle
                System.Windows.Shapes.Rectangle testRect = new System.Windows.Shapes.Rectangle
                {
                    Stroke          = System.Windows.Media.Brushes.LightGreen,
                    StrokeThickness = 0
                };

                ImageBrush ib = new ImageBrush();
                //    cBmp.MakeTransparent();
                cBmp.Dispose();
                var source = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(nBmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty,
                                                                                          System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
                nBmp.Dispose();
                ib.ImageSource  = source;
                testRect.Fill   = ib;
                testRect.Width  = newPos.Width;
                testRect.Height = newPos.Height;
                Canvas.SetLeft(testRect, newPos.Left);
                Canvas.SetTop(testRect, newPos.Top);
                list.Add(testRect);

                Glyph newGlyph = new Glyph()
                {
                    X      = (int)Math.Ceiling(newPos.Left),
                    Y      = (int)Math.Ceiling(newPos.Top),
                    width  = (int)Math.Ceiling(newPos.Width),
                    height = (int)Math.Ceiling(newPos.Height)
                };
                newFont.SetGlyph(currentChar0, newGlyph);

                //if(glyphIndex == 33)
                //{

                //}
                // Construct KerningData
                for (int j = 0; j < alphabet.ToCharArray().Length; j++)
                {
                    string left_Char0      = alphabet.ToCharArray()[j].ToString();
                    uint   left_glyphIndex = face.GetCharIndex(uchar2code(left_Char0));

                    //if (left_glyphIndex == 45)
                    //{

                    //}
                    //char c1 = mAlphabet[i];
                    //FT_UInt c1Index = FT_Get_Char_Index(face, c1);
                    var delta = face.GetKerning(left_glyphIndex, glyphIndex, KerningMode.Default);

                    // KerningData kd = new KerningData(kern_currentChar0, currentChar0, delta.X.ToInt32() >> 6, 0, delta.Y.ToInt32() >> 6, 0);
                    if (left_glyphIndex == 0 || delta.X == 0) //no kerning
                    {
                        continue;
                    }

                    Kerning newKerning = new Kerning();
                    newKerning.RightGlyphID = left_glyphIndex;
                    newKerning.KerningValue = delta.X.ToInt32() >> 6;
                    newFont.SetKerning(left_Char0, newKerning);
                }

                newFont.SetVerticalOffset(currentChar0, ky);

                //cBmp.Dispose();
                //g.DrawImageUnscaled(nBmp, (int)Math.Ceiling(newPos.X) + fontSettings.relativePositionX, (int)Math.Ceiling(newPos.Y) + fontSettings.relativePositionY);
                //// g.DrawImageUnscaled(nBmp, kx + FontSettings.relativePositionX, ky + FontSettings.relativePositionY);
                //nBmp.Dispose();
            }
            g.Dispose();
            library.Dispose();
            return(bmp);
        }
Пример #12
0
        private void button_Click(object sender, RoutedEventArgs e)
        {
            try
            {
                var mpm = ((AtlasModel)this.DataContext);

                mpm.Sprites.Clear();
                mpm.Rectangles.Clear();
                //    mpm.Fonts.Clear();

                //     FontSettings fontSettings = new FontSettings();

                MaxRectsBinPack binPack = new MaxRectsBinPack((int)mpm.TextureWidth, (int)mpm.TextureHeight, false);

                System.Drawing.Image image = System.Drawing.Image.FromFile(@"F:\Projekte\coop\XGame\_devFolder\Work\UI\Button_test-export.png");//mpm.AngelcodeFontFile);
                Rect newPos = binPack.Insert(image.Width, image.Height, MaxRectsBinPack.FreeRectChoiceHeuristic.RectBestLongSideFit);
                foreach (var fontModel in mpm.Fonts)
                {
                    foreach (FontData character  in fontModel.Items)
                    {
                        character.Glyph.X += (int)newPos.X;
                        character.Glyph.Y += (int)newPos.Y;
                    }
                }

                Rectangle testRect = new Rectangle
                {
                    Stroke          = Brushes.LightBlue,
                    StrokeThickness = 0
                };
                ImageBrush  ib  = new ImageBrush();
                BitmapImage bmi = new BitmapImage(new Uri(@"F:\Projekte\coop\XGame\_devFolder\Work\UI\Button_test-export.png", UriKind.Absolute));
                ib.ImageSource = bmi;
                testRect.Fill  = ib;


                testRect.Width  = newPos.Width;
                testRect.Height = newPos.Height;

                Canvas.SetLeft(testRect, newPos.Left);
                Canvas.SetTop(testRect, newPos.Top);

                mpm.Rectangles.Add(testRect);
                //mpm.FontSystem.GenerateFont(mpm.Rectangles,
                //                           mpm.Fonts,
                //                            binPack,
                //                          fontSettings);

                //fontSettings = new FontSettings()
                //{
                //    FontSize = 40
                //};

                //mpm.FontSystem.GenerateFont(mpm.Rectangles,
                //                          mpm.FB_UI_Atlas.Fonts,
                //                          binPack,
                //                          fontSettings);


                AtlasHelper.GenAtlas(binPack, mpm.Rectangles, mpm.Sprites, mpm.ImageFolder, mpm.ImageExtensions, mpm.TextureWidth, mpm.TextureHeight);


                RenderTargetBitmap renderBitmap = new RenderTargetBitmap(
                    (int)canvas.Width, (int)canvas.Height,
                    96d, 96d, PixelFormats.Pbgra32);
                // needed otherwise the image output is black
                canvas.Measure(new Size((int)canvas.Width, (int)canvas.Height));
                canvas.Arrange(new Rect(new Size((int)canvas.Width, (int)canvas.Height)));

                renderBitmap.Render(canvas);

                //JpegBitmapEncoder encoder = new JpegBitmapEncoder();
                PngBitmapEncoder encoder = new PngBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(renderBitmap));

                using (FileStream file = File.Create(((AtlasModel)this.DataContext).FB_UI_Atlas.TextureName))
                {
                    encoder.Save(file);
                }

                var fbData = mpm.FB_UI_Atlas.CreateFBData();

                //@"F:\Projekte\coop\XGame\data\dbData\UI\TestAtlas.fbbin"
                using (FileStream fileStream = new FileStream(mpm.TargetFbbinFile, FileMode.Create))
                {
                    // Write the data to the file, byte by byte.
                    for (int i = 0; i < fbData._fbData.Length; i++)
                    {
                        fileStream.WriteByte(fbData._fbData[i]);
                    }

                    // Set the stream position to the beginning of the file.
                    fileStream.Seek(0, SeekOrigin.Begin);

                    // Read and verify the data.
                    for (int i = 0; i < fileStream.Length; i++)
                    {
                        if (fbData._fbData[i] != fileStream.ReadByte())
                        {
                            Console.WriteLine("Error writing data.");
                            return;
                        }
                    }
                    Console.WriteLine("The data was written to {0} " +
                                      "and verified.", fileStream.Name);
                }
            }
            catch (Exception ex)
            {
            }
        }
Пример #13
0
    private static Rect[] PackTextures(Texture2D texture, Texture2D[] sprites, int padding, int width, int height, int maxSize, bool forceSquare)
    {
        if ((width > maxSize && height < maxSize) || (height > maxSize && width < maxSize))
        {
            width = height = maxSize;
        }

        if (width > maxSize || height > maxSize)
        {
            throw new InvalidOperationException("Packed sprites exceed maximum atlas size");
        }

        if (forceSquare)
        {
            var max = Mathf.Max(width, height);
            width  = max;
            height = max;
        }
        else if (height > width)
        {
            int temp = width;
            width  = height;
            height = temp;
        }

        MaxRectsBinPack bp = new MaxRectsBinPack(width, height, false);

        Rect[] rects = new Rect[sprites.Length];

        for (int i = 0; i < sprites.Length; i++)
        {
            Texture2D sprite       = sprites[i];
            var       spriteWidth  = sprite.width + padding;
            var       spriteHeight = sprite.height + padding;

            var  packingMethodConfig = (dfTexturePacker.dfTexturePackingMethod)EditorPrefs.GetInt("DaikonForge.AtlasPackingMethod", (int)dfTexturePacker.dfTexturePackingMethod.RectBestAreaFit);
            Rect rect = bp.Insert(
                spriteWidth,
                spriteHeight,
                packingMethodConfig
                );

            // If the rect could not be packed into the current dimensions,
            // increase the texture size.
            if (rect.width == 0 || rect.height == 0)
            {
                return(PackTextures(texture, sprites, padding, (width <= height ? width << 1 : width), (height < width ? height << 1 : height), maxSize, forceSquare));
            }

            rects[i] = rect;
        }

        // Check for max size
        if (width > maxSize || height > maxSize)
        {
            throw new InvalidOperationException("Packed sprites exceed maximum atlas size");
        }

        texture.Resize(width, height);
        texture.SetPixels(new Color[width * height]);

        var extrudeEdges = EditorPrefs.GetBool("DaikonForge.AtlasExtrudeSprites", false) && padding > 0;

        for (int i = 0; i < sprites.Length; i++)
        {
            Texture2D sprite = sprites[i];
            Rect      rect   = rects[i];
            Color[]   colors = sprite.GetPixels();

            #region Edge extrusion coded provided by Mistale - http:            //www.daikonforge.com/dfgui/forums/topic/dilate-texture-atlas/

            // Dilate border if padding is set
            if (extrudeEdges)
            {
                int w      = (int)sprite.width;
                int h      = (int)sprite.height;
                int xStart = (int)rect.x;
                int yStart = (int)rect.y;
                int xStop  = xStart + w - 1;
                int yStop  = yStart + h - 1;

                Color[] wColors;

                int halfPadding = (int)(padding / 2f);

                // Top border
                wColors = sprite.GetPixels(0, 0, sprite.width, 1);
                for (int p = 0; p < halfPadding && yStart - p >= 1; p++)
                {
                    texture.SetPixels(xStart, yStart - p - 1, sprite.width, 1, wColors);
                }

                // Bottom border
                wColors = sprite.GetPixels(0, sprite.height - 1, sprite.width, 1);
                for (int p = 0; p < halfPadding && yStop + p < texture.height - 1; p++)
                {
                    texture.SetPixels(xStart, yStop + p + 1, sprite.width, 1, wColors);
                }

                // Left border
                wColors = sprite.GetPixels(0, 0, 1, sprite.height);
                for (int p = 0; p < halfPadding && xStart - p >= 1; p++)
                {
                    texture.SetPixels(xStart - p - 1, yStart, 1, sprite.height, wColors);
                }

                // Right border
                wColors = sprite.GetPixels(sprite.width - 1, 0, 1, sprite.height);
                for (int p = 0; p < halfPadding && xStop + p < texture.width - 1; p++)
                {
                    texture.SetPixels(xStop + p + 1, yStart, 1, sprite.height, wColors);
                }
            }

            #endregion

            texture.SetPixels(
                (int)rect.x,
                (int)rect.y,
                (int)sprite.width,
                (int)sprite.height,
                colors
                );

            rects[i] = new Rect(
                rect.x / width,
                rect.y / height,
                (rect.width - padding) / width,
                (rect.height - padding) / height
                );
        }

        return(rects);
    }
Пример #14
0
        internal static void GenAtlas(List <string> paths)
        {
            List <Image> textures = new List <Image>();
            double       size     = 0;

            foreach (var path in paths)
            {
                Image a = Image.Load(path);
                size += a.Width * a.Height;
                textures.Add(a);
            }


            size = Math.Sqrt(size) * 1.5;

            Rectangle[]     rects = new Rectangle[textures.Count];
            MaxRectsBinPack bp    = new MaxRectsBinPack((int)size, (int)size, false);

            for (int i = 0; i < textures.Count; i++)
            {
                Rectangle rect = bp.Insert(textures[i].Width, textures[i].Height, MaxRectsBinPack.FreeRectChoiceHeuristic.RectBestAreaFit);

                if (rect.Width == 0 || rect.Height == 0)
                {
                    Logger.LogError("The mystery error we thought impossible...");
                    return;
                }

                rects[i] = rect;
            }


            Vector2i MaxSize = new Vector2i();

            foreach (var rect in rects)
            {
                if (rect.X + rect.Width > MaxSize.X)
                {
                    MaxSize.X = rect.X + rect.Width;
                }

                if (rect.Y + rect.Height > MaxSize.Y)
                {
                    MaxSize.Y = rect.Y + rect.Height;
                }
            }


            Atlas = new Image <Rgba32>(MaxSize.X, MaxSize.Y);

            for (int i = 0; i < rects.Length; i++)
            {
                Vector4 coord = new Vector4(
                    (float)rects[i].X / Atlas.Width,
                    1.0f - (float)rects[i].Y / Atlas.Height,
                    (float)(rects[i].X + rects[i].Width) / Atlas.Width,
                    1.0f - ((float)(rects[i].Y + rects[i].Height) / Atlas.Height)
                    );

                AtlasCoords.TryAdd(paths[i], coord);

                Atlas.Mutate(o => o.DrawImage(textures[i], new SixLabors.ImageSharp.Point(rects[i].X, rects[i].Y), 1f));
            }

            Atlas.Mutate(o => o.Flip(FlipMode.Vertical));

            Atlas.SaveAsPng("pain_and_suffering_sequel.png");
        }
Пример #15
0
        static void Main(string[] args)
        {
            int binWidth = 128, binHeight = 128;

            // 128 128 30 20 50 20 10 80 90 20 90 20
            RectSize[] rectSizes =
            {
                new RectSize(30, 20),
                new RectSize(50, 20),
                new RectSize(10, 80),
                new RectSize(90, 20),
                new RectSize(90, 20)
            };

            Console.WriteLine("### MaxRectsBinPack ###");
            MaxRectsBinPack maxRectsBinPack = new MaxRectsBinPack();

            maxRectsBinPack.Init(binWidth, binHeight);
            foreach (var rectSize in rectSizes)
            {
                Rect rect = maxRectsBinPack.Insert(rectSize, new MaxRectsBinPack.Option()
                {
                    Method = MaxRectsBinPack.FreeRectChoiceHeuristic.RectBestAreaFit
                });
                if (0 != rect.Height)
                {
                    Console.WriteLine($"Rect -> {rect}, Free space left={maxRectsBinPack.FreeSpaceLeft}");
                }
                else
                {
                    Console.WriteLine($"Failed!-> {rectSize}");
                }
            }

            Console.WriteLine("### GuillotineBinPack ###");
            GuillotineBinPack binGuillotine = new GuillotineBinPack();

            binGuillotine.Init(binWidth, binHeight);
            foreach (var rectSize in rectSizes)
            {
                Rect rect = binGuillotine.Insert(rectSize, new GuillotineBinPack.Option()
                {
                    Merge           = true,
                    FreeRectChoice  = GuillotineBinPack.FreeRectChoiceHeuristic.RectBestAreaFit,
                    GuillotineSplit = GuillotineBinPack.GuillotineSplitHeuristic.SplitLongerAxis
                });
                if (0 != rect.Height)
                {
                    Console.WriteLine($"Rect -> {rect}, Free space left={binGuillotine.FreeSpaceLeft}");
                }
                else
                {
                    Console.WriteLine($"Failed!-> {rectSize}");
                }
            }

            Console.WriteLine("### ShelfBinPack ###");
            ShelfBinPack shelfBinPack = new ShelfBinPack
            {
                UseWasteMap = true
            };

            shelfBinPack.Init(binWidth, binHeight);
            foreach (var rectSize in rectSizes)
            {
                Rect rect = shelfBinPack.Insert(rectSize, new ShelfBinPack.Option()
                {
                    Method = ShelfBinPack.ShelfChoiceHeuristic.ShelfBestAreaFit
                });
                if (0 != rect.Height)
                {
                    Console.WriteLine($"Rect -> {rect}, Free space left= {shelfBinPack.FreeSpaceLeft}");
                }
                else
                {
                    Console.WriteLine($"Failed!-> {rectSize}");
                }
            }

            Console.WriteLine("### ShelfNextFitBinPack ###");
            ShelfNextFitBinPack shelfNextFitBinPack = new ShelfNextFitBinPack();

            shelfNextFitBinPack.Init(binWidth, binHeight);
            foreach (var rectSize in rectSizes)
            {
                Rect rect = shelfNextFitBinPack.Insert(rectSize, new OptionNone());
                if (0 != rect.Width)
                {
                    Console.WriteLine($"Rect -> {rect}, Free space left={shelfNextFitBinPack.FreeSpaceLeft}");
                }
                else
                {
                    Console.WriteLine($"Failed!-> {rectSize}");
                }
            }
            Console.WriteLine("### SkylineBinPack ###");
            SkylineBinPack skylineBinPack = new SkylineBinPack();

            skylineBinPack.Init(binWidth, binHeight);
            foreach (var rectSize in rectSizes)
            {
                Rect rect = skylineBinPack.Insert(rectSize, new SkylineBinPack.Option()
                {
                    Method = SkylineBinPack.LevelChoiceHeuristic.LevelBottomLeft
                });

                if (0 != rect.Height)
                {
                    Console.WriteLine($"Rect -> {rect}, Free space left= {skylineBinPack.FreeSpaceLeft}");
                }
                else
                {
                    Console.WriteLine($"Failed! -> {rectSize}");
                }
            }
        }
Пример #16
0
        public IEnumerator GetRenderTextureByTexturesOptimize(CombineTextureData combineTextureData, List <Spine.AtlasRegion> regions, int renderTextureSize, Action <PackagedTextureResult> finishCallBack)
        {
            ResetValue(combineTextureData);
            currentAtlasSize = renderTextureSize;
            List <TextureClass> textureList = new List <TextureClass>();
            //GetTextureClassList (textures);
            List <TextureClass> currentTextureList         = new List <TextureClass> ();
            Material            material                   = InitMaterial();
            MaxRectsBinPack     maxRectsBinPack            = new MaxRectsBinPack(currentAtlasSize, currentAtlasSize, false);
            RenderTexture       render                     = RenderTexture.GetTemporary(currentAtlasSize, currentAtlasSize, 0, RenderTextureFormat.ARGB4444);
            Dictionary <RenderTexture, TextureClass[]> dic = new Dictionary <RenderTexture, TextureClass[]> ();

            Graphics.Blit(null, null, material, 0);
            for (int i = 0; i < regions.Count; i++)
            {
                UnityEngine.Profiling.Profiler.BeginSample("SpineChange_ToTexture");
                RenderTexture regionTex = Spine.Unity.Modules.AttachmentTools.AtlasUtilities.ToTexture(regions[i]);
                UnityEngine.Profiling.Profiler.EndSample();
                textureList.Add(new TextureClass {
                    index = i, texture = regionTex, textureSize = new TextureSize {
                        x = regionTex.width, y = regionTex.height
                    }
                });
                if (!IsSuitableTexture(textureList[i].texture))
                {
                    throw new System.NotSupportedException("[--散图 " + textureList[i].texture.name + " 的大小超出单位图集的大小,请修改散图或单位图集的大小(SpineConstValue.smallAtlasSize)--]");
                }
                Rect posRect = maxRectsBinPack.Insert(textureList[i].texture.width, textureList[i].texture.height, MaxRectsBinPack.FreeRectChoiceHeuristic.RectBestAreaFit);
                if (posRect.height <= 0)
                {
                    //保存本次的图集和散图的位置信息
                    TextureClass[] array1 = new TextureClass[currentTextureList.Count];
                    currentTextureList.CopyTo(array1);
                    dic.Add(render, array1);
                    currentTextureList.Clear();
                    Graphics.Blit(null, null, material, 0);
                    //初始化参数进行下一次的合图
                    material        = InitMaterial();
                    maxRectsBinPack = new MaxRectsBinPack(currentAtlasSize, currentAtlasSize, false);
                    render          = RenderTexture.GetTemporary(currentAtlasSize, currentAtlasSize, 0, RenderTextureFormat.ARGB4444);
                    Graphics.Blit(null, null, material, 0);
                    textureList.RemoveAt(i);
                    --i;
                    combineTextureData.smallAtlasNumber++;
                    continue;
                }
                Rect scaleRect = GetScaleRect(posRect, renderTextureSize, renderTextureSize);
                material.SetTexture("_MainTex", textureList[i].texture);
                material.SetFloat("_ScaleX", scaleRect.width);
                material.SetFloat("_ScaleY", scaleRect.height);
                material.SetFloat("_OffsetX", scaleRect.x);
                material.SetFloat("_OffsetY", scaleRect.y);
                Graphics.Blit(null, render, material, 1);
                textureList[i].rect = posRect;
                currentTextureList.Add(textureList[i]);
                //卸载散图资源
                // textureList[i].texture = null;
                // UnityEngine.Resources.UnloadUnusedAssets();
                RenderTexture.ReleaseTemporary(textureList[i].texture);
                textureList[i].texture.Release();
                textureList[i].texture = null;
                yield return(null);
            }
            Graphics.Blit(null, null, material, 0);
            TextureClass[] array2 = new TextureClass[currentTextureList.Count];
            currentTextureList.CopyTo(array2);
            dic.Add(render, array2);
            if (null != combineTextureData.combineCoroutineBig)
            {
                GameManager.Instance.StopCoroutine(combineTextureData.combineCoroutineBig);
            }
            combineTextureData.combineCoroutineBig = GameManager.Instance.StartCoroutine(FinallyPackage(combineTextureData, dic, finishCallBack));
        }
Пример #17
0
	private static Rect[] PackTextures( Texture2D texture, Texture2D[] sprites, int padding, int width, int height, int maxSize, bool forceSquare )
	{

		if( ( width > maxSize && height < maxSize ) || ( height > maxSize && width < maxSize ) )
		{
			width = height = maxSize;
		}
		
		if( width > maxSize || height > maxSize )
			throw new InvalidOperationException( "Packed sprites exceed maximum atlas size" );

		if( forceSquare )
		{
			var max = Mathf.Max( width, height );
			width = max;
			height = max;
		}
		else if( height > width ) 
		{ 
			int temp = width; 
			width = height; 
			height = temp; 
		}

		MaxRectsBinPack bp = new MaxRectsBinPack( width, height, false );
		Rect[] rects = new Rect[ sprites.Length ];

		for( int i = 0; i < sprites.Length; i++ )
		{

			Texture2D sprite = sprites[ i ];
			var spriteWidth = sprite.width + padding;
			var spriteHeight = sprite.height + padding;

			var packingMethodConfig = (dfTexturePacker.dfTexturePackingMethod)EditorPrefs.GetInt( "DaikonForge.AtlasPackingMethod", (int)dfTexturePacker.dfTexturePackingMethod.RectBestAreaFit );
			Rect rect = bp.Insert( 
				spriteWidth, 
				spriteHeight,
				packingMethodConfig
			);

			// If the rect could not be packed into the current dimensions, 
			// increase the texture size.
			if( rect.width == 0 || rect.height == 0 )
			{
				return PackTextures( texture, sprites, padding, ( width <= height ? width << 1 : width ), ( height < width ? height << 1 : height ), maxSize, forceSquare );
			}

			rects[ i ] = rect;

		}

		// Check for max size
		if( width > maxSize || height > maxSize )
			throw new InvalidOperationException( "Packed sprites exceed maximum atlas size" );

		texture.Resize( width, height );
		texture.SetPixels( new Color[ width * height ] );

		var extrudeEdges = EditorPrefs.GetBool( "DaikonForge.AtlasExtrudeSprites", false ) && padding > 0;
		for( int i = 0; i < sprites.Length; i++ )
		{

			Texture2D sprite = sprites[ i ];
			Rect rect = rects[ i ];
			Color[] colors = sprite.GetPixels();

			#region Edge extrusion coded provided by Mistale - http://www.daikonforge.com/dfgui/forums/topic/dilate-texture-atlas/

			// Dilate border if padding is set
			if( extrudeEdges )
			{

				int w = (int)sprite.width;
				int h = (int)sprite.height;
				int xStart = (int)rect.x;
				int yStart = (int)rect.y;
				int xStop = xStart + w - 1;
				int yStop = yStart + h - 1;

				Color[] wColors;

				int halfPadding = (int)( padding / 2f );

				// Top border
				wColors = sprite.GetPixels( 0, 0, sprite.width, 1 );
				for( int p = 0; p < halfPadding && yStart - p >= 1; p++ ) 
					texture.SetPixels( xStart, yStart - p - 1, sprite.width, 1, wColors );

				// Bottom border
				wColors = sprite.GetPixels( 0, sprite.height - 1, sprite.width, 1 );
				for( int p = 0; p < halfPadding && yStop + p < texture.height - 1; p++ ) 
					texture.SetPixels( xStart, yStop + p + 1, sprite.width, 1, wColors );

				// Left border
				wColors = sprite.GetPixels( 0, 0, 1, sprite.height );
				for( int p = 0; p < halfPadding && xStart - p >= 1; p++ ) 
					texture.SetPixels( xStart - p - 1, yStart, 1, sprite.height, wColors );

				// Right border
				wColors = sprite.GetPixels( sprite.width - 1, 0, 1, sprite.height );
				for( int p = 0; p < halfPadding && xStop + p < texture.width - 1; p++ ) 
					texture.SetPixels( xStop + p + 1, yStart, 1, sprite.height, wColors );

			}

			#endregion

			texture.SetPixels(
				(int)rect.x,
				(int)rect.y,
				(int)sprite.width,
				(int)sprite.height,
				colors
			);

			rects[ i ] = new Rect(
				rect.x / width,
				rect.y / height,
				( rect.width - padding ) / width,
				( rect.height - padding ) / height
			);

		}

		return rects;

	}
Пример #18
0
    private static Rect[] PackTextures( Texture2D texture, Texture2D[] sprites, int padding, int width, int height, int maxSize )
    {
        if( ( width > maxSize && height < maxSize ) || ( height > maxSize && width < maxSize ) )
        {
            width = height = maxSize;
        }

        if( width > maxSize || height > maxSize )
            throw new InvalidOperationException( "Packed sprites exceed maximum atlas size" );

        if( height > width )
        {
            int temp = width;
            width = height;
            height = temp;
        }

        MaxRectsBinPack bp = new MaxRectsBinPack( width, height, false );
        Rect[] rects = new Rect[ sprites.Length ];

        for( int i = 0; i < sprites.Length; i++ )
        {

            Texture2D sprite = sprites[ i ];
            var spriteWidth = sprite.width + padding;
            var spriteHeight = sprite.height + padding;

            Rect rect = bp.Insert(
                spriteWidth,
                spriteHeight,
                MaxRectsBinPack.FreeRectChoiceHeuristic.RectBestAreaFit
            );

            // If the rect could not be packed into the current dimensions,
            // increase the texture size.
            if( rect.width == 0 || rect.height == 0 )
            {
                return PackTextures( texture, sprites, padding, ( width <= height ? width << 1 : width ), ( height < width ? height << 1 : height ), maxSize );
            }

            rects[ i ] = rect;

        }

        // Check for max size
        if( width > maxSize || height > maxSize )
            throw new InvalidOperationException( "Packed sprites exceed maximum atlas size" );

        texture.Resize( width, height );
        texture.SetPixels( new Color[ width * height ] );

        for( int i = 0; i < sprites.Length; i++ )
        {

            Texture2D sprite = sprites[ i ];
            Rect rect = rects[ i ];
            Color[] colors = sprite.GetPixels();

            texture.SetPixels(
                (int)rect.x,
                (int)rect.y,
                (int)sprite.width,
                (int)sprite.height,
                colors
            );

            rects[ i ] = new Rect(
                rect.x / width,
                rect.y / height,
                ( rect.width - padding ) / width,
                ( rect.height - padding ) / height
            );

        }

        return rects;
    }