Esempio n. 1
0
        /// <summary>
        /// add or replace
        /// </summary>
        /// <param name="glyphIndex"></param>
        /// <param name="img"></param>
        public void AddGlyph(ushort glyphIndex, GlyphImage img)
        {
            var glyphCache = new CacheGlyph();

            glyphCache.glyphIndex = glyphIndex;
            glyphCache.img        = img;
            _glyphs[glyphIndex]   = glyphCache;
        }
        public void AddGlyph(int codePoint, GlyphImage img)
        {
            var glyphCache = new CacheGlyph();

            glyphCache.codePoint = codePoint;
            glyphCache.img       = img;

            glyphs[codePoint] = glyphCache;
        }
        public GlyphImage BuildSingleImage()
        {
            //1. add to list
            var glyphList = new List <CacheGlyph>(glyphs.Count);

            foreach (CacheGlyph glyphImg in glyphs.Values)
            {
                //sort data
                glyphList.Add(glyphImg);
            }


            int totalMaxLim  = MaxAtlasWidth;
            int maxRowHeight = 0;
            int currentY     = 0;
            int currentX     = 0;


            if (CompactGlyphSpace)
            {
                //2. sort by glyph width
                glyphList.Sort((a, b) =>
                {
                    return(a.img.Width.CompareTo(b.img.Width));
                });
                //3. layout
                for (int i = glyphList.Count - 1; i >= 0; --i)
                {
                    CacheGlyph g = glyphList[i];
                    if (g.img.Height > maxRowHeight)
                    {
                        maxRowHeight = g.img.Height;
                    }
                    if (currentX + g.img.Width > totalMaxLim)
                    {
                        //start new row
                        currentY += maxRowHeight;
                        currentX  = 0;
                    }
                    //-------------------
                    g.area    = new Rectangle(currentX, currentY, g.img.Width, g.img.Height);
                    currentX += g.img.Width;
                }
            }
            else
            {    //3. layout
                int glyphCount = glyphList.Count;
                for (int i = 0; i < glyphCount; ++i)
                {
                    CacheGlyph g = glyphList[i];
                    if (g.img.Height > maxRowHeight)
                    {
                        maxRowHeight = g.img.Height;
                    }
                    if (currentX + g.img.Width > totalMaxLim)
                    {
                        //start new row
                        currentY += maxRowHeight;
                        currentX  = 0;
                    }
                    //-------------------
                    g.area    = new Rectangle(currentX, currentY, g.img.Width, g.img.Height);
                    currentX += g.img.Width;
                }
            }

            currentY += maxRowHeight;
            int imgH = currentY;
            // -------------------------------
            //compact image location
            // TODO: review performance here again***

            int totalImgWidth = totalMaxLim;

            if (CompactGlyphSpace)
            {
                totalImgWidth = 0;//reset
                BinPacker binPacker = new BinPacker(totalMaxLim, currentY);
                for (int i = glyphList.Count - 1; i >= 0; --i)
                {
                    CacheGlyph  g       = glyphList[i];
                    BinPackRect newRect = binPacker.Insert(g.img.Width, g.img.Height);
                    g.area = new Rectangle(newRect.X, newRect.Y,
                                           g.img.Width, g.img.Height);


                    //recalculate proper max midth again, after arrange and compact space
                    if (newRect.Right > totalImgWidth)
                    {
                        totalImgWidth = newRect.Right;
                    }
                }
            }


            // -------------------------------
            //4. create array that can hold data
            int[] totalBuffer = new int[totalImgWidth * imgH];
            if (CompactGlyphSpace)
            {
                for (int i = glyphList.Count - 1; i >= 0; --i)
                {
                    CacheGlyph g = glyphList[i];
                    //copy data to totalBuffer
                    GlyphImage img = g.img;
                    CopyToDest(img.GetImageBuffer(), img.Width, img.Height, totalBuffer, g.area.Left, g.area.Top, totalImgWidth);
                }
            }
            else
            {
                int glyphCount = glyphList.Count;
                for (int i = 0; i < glyphCount; ++i)
                {
                    CacheGlyph g = glyphList[i];
                    //copy data to totalBuffer
                    GlyphImage img = g.img;
                    CopyToDest(img.GetImageBuffer(), img.Width, img.Height, totalBuffer, g.area.Left, g.area.Top, totalImgWidth);
                }
            }

            GlyphImage glyphImage = new GlyphImage(totalImgWidth, imgH);

            glyphImage.SetImageBuffer(totalBuffer, true);
            latestGenGlyphImage = glyphImage;
            return(glyphImage);
        }
        public GlyphImage BuildSingleImage()
        {
            //1. add to list
            var glyphList = new List <CacheGlyph>(glyphs.Count);

            foreach (CacheGlyph glyphImg in glyphs.Values)
            {
                //sort data
                glyphList.Add(glyphImg);
            }
            //2. sort
            glyphList.Sort((a, b) =>
            {
                return(a.img.Width.CompareTo(b.img.Width));
            });
            //3. layout

            int totalMaxLim  = 800;
            int maxRowHeight = 0;
            int currentY     = 0;
            int currentX     = 0;

            for (int i = glyphList.Count - 1; i >= 0; --i)
            {
                CacheGlyph g = glyphList[i];
                if (g.img.Height > maxRowHeight)
                {
                    maxRowHeight = g.img.Height;
                }
                if (currentX + g.img.Width > totalMaxLim)
                {
                    //start new row
                    currentY += maxRowHeight;
                    currentX  = 0;
                }
                //-------------------
                g.area    = new Rectangle(currentX, currentY, g.img.Width, g.img.Height);
                currentX += g.img.Width;
            }
            currentY += maxRowHeight;
            int imgH = currentY;
            //-------------------------------
            //compact image location
            //TODO: review performance here again***
            BinPacker binPacker = new BinPacker(totalMaxLim, currentY);

            for (int i = glyphList.Count - 1; i >= 0; --i)
            {
                CacheGlyph  g       = glyphList[i];
                BinPackRect newRect = binPacker.Insert(g.img.Width, g.img.Height);
                g.area = new Rectangle(newRect.X, newRect.Y,
                                       g.img.Width, g.img.Height);
            }
            //-------------------------------

            //4. create array that can hold data
            int[] totalBuffer = new int[totalMaxLim * imgH];
            for (int i = glyphList.Count - 1; i >= 0; --i)
            {
                CacheGlyph g = glyphList[i];
                //copy data to totalBuffer
                GlyphImage img = g.img;
                CopyToDest(img.GetImageBuffer(), img.Width, img.Height, totalBuffer, g.area.Left, g.area.Top, totalMaxLim);
            }
            //------------------

            GlyphImage glyphImage = new GlyphImage(totalMaxLim, imgH);

            glyphImage.SetImageBuffer(totalBuffer, true);
            latestGenGlyphImage = glyphImage;
            return(glyphImage);
        }
Esempio n. 5
0
        public GlyphImage BuildSingleImage()
        {
            //1. add to list
            var glyphList = new List <CacheGlyph>(_glyphs.Count);

            foreach (CacheGlyph glyphImg in _glyphs.Values)
            {
                //sort data
                glyphList.Add(glyphImg);
            }

            int totalMaxLim  = MaxAtlasWidth;
            int maxRowHeight = 0;
            int currentY     = 0;
            int currentX     = 0;

            switch (this.SpaceCompactOption)
            {
            default:
                throw new System.NotSupportedException();

            case CompactOption.BinPack:
            {
                //2. sort by glyph width
                glyphList.Sort((a, b) =>
                    {
                        return(a.img.Width.CompareTo(b.img.Width));
                    });
                //3. layout
                for (int i = glyphList.Count - 1; i >= 0; --i)
                {
                    CacheGlyph g = glyphList[i];
                    if (g.img.Height > maxRowHeight)
                    {
                        maxRowHeight = g.img.Height;
                    }
                    if (currentX + g.img.Width > totalMaxLim)
                    {
                        //start new row
                        currentY += maxRowHeight;
                        currentX  = 0;
                    }
                    //-------------------
                    g.area    = new Rectangle(currentX, currentY, g.img.Width, g.img.Height);
                    currentX += g.img.Width;
                }
            }
            break;

            case CompactOption.ArrangeByHeight:
            {
                //2. sort by height
                glyphList.Sort((a, b) =>
                    {
                        return(a.img.Height.CompareTo(b.img.Height));
                    });
                //3. layout
                int glyphCount = glyphList.Count;
                for (int i = 0; i < glyphCount; ++i)
                {
                    CacheGlyph g = glyphList[i];
                    if (g.img.Height > maxRowHeight)
                    {
                        maxRowHeight = g.img.Height;
                    }
                    if (currentX + g.img.Width > totalMaxLim)
                    {
                        //start new row
                        currentY    += maxRowHeight;
                        currentX     = 0;
                        maxRowHeight = g.img.Height;        //reset, after start new row
                    }
                    //-------------------
                    g.area    = new Rectangle(currentX, currentY, g.img.Width, g.img.Height);
                    currentX += g.img.Width;
                }
            }
            break;

            case CompactOption.None:
            {
                //3. layout
                int glyphCount = glyphList.Count;
                for (int i = 0; i < glyphCount; ++i)
                {
                    CacheGlyph g = glyphList[i];
                    if (g.img.Height > maxRowHeight)
                    {
                        maxRowHeight = g.img.Height;
                    }
                    if (currentX + g.img.Width > totalMaxLim)
                    {
                        //start new row
                        currentY    += maxRowHeight;
                        currentX     = 0;
                        maxRowHeight = g.img.Height;        //reset, after start new row
                    }
                    //-------------------
                    g.area    = new Rectangle(currentX, currentY, g.img.Width, g.img.Height);
                    currentX += g.img.Width;
                }
            }
            break;
            }

            currentY += maxRowHeight;
            int imgH = currentY;
            // -------------------------------
            //compact image location
            // TODO: review performance here again***

            int totalImgWidth = totalMaxLim;

            if (SpaceCompactOption == CompactOption.BinPack) //again here?
            {
                totalImgWidth = 0;                           //reset
                //use bin packer
                BinPacker binPacker = new BinPacker(totalMaxLim, currentY);
                for (int i = glyphList.Count - 1; i >= 0; --i)
                {
                    CacheGlyph  g       = glyphList[i];
                    BinPackRect newRect = binPacker.Insert(g.img.Width, g.img.Height);
                    g.area = new Rectangle(newRect.X, newRect.Y,
                                           g.img.Width, g.img.Height);


                    //recalculate proper max midth again, after arrange and compact space
                    if (newRect.Right > totalImgWidth)
                    {
                        totalImgWidth = newRect.Right;
                    }
                }
            }
            // -------------------------------
            //4. create array that can hold data
            int[] totalBuffer = new int[totalImgWidth * imgH];
            if (SpaceCompactOption == CompactOption.BinPack) //again here?
            {
                for (int i = glyphList.Count - 1; i >= 0; --i)
                {
                    CacheGlyph g = glyphList[i];
                    //copy data to totalBuffer
                    GlyphImage img = g.img;
                    CopyToDest(img.GetImageBuffer(), img.Width, img.Height, totalBuffer, g.area.Left, g.area.Top, totalImgWidth);
                }
            }
            else
            {
                int glyphCount = glyphList.Count;
                for (int i = 0; i < glyphCount; ++i)
                {
                    CacheGlyph g = glyphList[i];
                    //copy data to totalBuffer
                    GlyphImage img = g.img;
                    CopyToDest(img.GetImageBuffer(), img.Width, img.Height, totalBuffer, g.area.Left, g.area.Top, totalImgWidth);
                }
            }

            //new total glyph img
            GlyphImage glyphImage = new GlyphImage(totalImgWidth, imgH);

            //flip vertical Y
            {
                int[] totalBufferFlipY = new int[totalBuffer.Length];
                int   srcRowIndex      = imgH - 1;
                int   strideInBytes    = totalImgWidth * 4;
                for (int i = 0; i < imgH; ++i)
                {
                    //copy each row from src to dst
                    System.Buffer.BlockCopy(totalBuffer, strideInBytes * srcRowIndex, totalBufferFlipY, strideInBytes * i, strideInBytes);
                    srcRowIndex--;
                }
                totalBuffer = totalBufferFlipY;
            }
            glyphImage.SetImageBuffer(totalBuffer, true);
            _latestGenGlyphImage = glyphImage;
            return(glyphImage);
        }
 /// <summary>
 /// add or replace
 /// </summary>
 /// <param name="glyphIndex"></param>
 /// <param name="img"></param>
 public void AddGlyph(ushort glyphIndex, GlyphImage img)
 {
     _glyphs[glyphIndex] = new CacheGlyph(glyphIndex, img);
 }