Пример #1
0
        public override void RemoveAllChildren(bool cleanup)
        {
            // Invalidate atlas index. issue #569
            // useSelfRender should be performed on all descendants. issue #1216
            CCSprite[] elements = Descendants.Elements;
            for (int i = 0, count = Descendants.Count; i < count; i++)
            {
                elements[i].BatchNode = null;
            }

            base.RemoveAllChildren(cleanup);

            Descendants.Clear();
            TextureAtlas.RemoveAllQuads();
        }
Пример #2
0
        void LayoutLabel()
        {
            if (FontAtlas == null || string.IsNullOrEmpty(Text))
            {
                ContentSize = CCSize.Zero;
                return;
            }

            TextureAtlas.RemoveAllQuads();
            Descendants.Clear();
            lettersInfo.Clear();

            FontAtlas.PrepareLetterDefinitions(Text);

            var start      = 0;
            var typesetter = new CCTLTextLayout(this);

            var length      = Text.Length;
            var insetBounds = labelDimensions;

            var layoutAvailable = true;

            if (insetBounds == CCSize.Zero)
            {
                insetBounds     = new CCSize(8388608, 8388608);
                layoutAvailable = false;
            }

            var boundsWidth              = insetBounds.Width;
            var contentScaleFactorWidth  = CCLabel.DefaultTexelToContentSizeRatios.Width;
            var contentScaleFactorHeight = CCLabel.DefaultTexelToContentSizeRatios.Height;

            List <CCTLLine> lineList = new List <CCTLLine>();

            while (start < length)// && textPosition.Y < insetBounds.Bottom)
            {
                // Now we ask the typesetter to break off a line for us.
                // This also will take into account line feeds embedded in the text.
                //  Example: "This is text \n with a line feed embedded inside it"
                int count = typesetter.SuggestLineBreak(start, boundsWidth);
                var line  = typesetter.GetLine(start, start + count);
                lineList.Add(line);

                start += count;
            }


            // Calculate our vertical starting position
            var totalHeight       = lineList.Count * LineHeight;
            var nextFontPositionY = totalHeight;

            if (Dimensions.Height > 0)
            {
                var labelHeightPixel = Dimensions.Height * contentScaleFactorHeight;
                if (totalHeight > labelHeightPixel)
                {
                    int numLines = (int)(labelHeightPixel / LineHeight);
                    totalHeight = numLines * LineHeight;
                }
                switch (VerticalAlignment)
                {
                case CCVerticalTextAlignment.Top:
                    nextFontPositionY = labelHeightPixel;
                    break;

                case CCVerticalTextAlignment.Center:
                    nextFontPositionY = (labelHeightPixel + totalHeight) * 0.5f;
                    break;

                case CCVerticalTextAlignment.Bottom:
                    nextFontPositionY = totalHeight;
                    break;

                default:
                    break;
                }
            }


            var   lineGlyphIndex = 0;
            float longestLine    = (labelDimensions.Width > 0) ? labelDimensions.Width : 0;

            // Used for calculating overlapping on last line character
            var lastCharWidth   = 0.0f;
            int lastCharAdvance = 0;

            // Define our horizontal justification
            var flushFactor = (float)HorizontalAlignment / (float)CCTextAlignment.Right;

            // We now loop through all of our line's glyph runs
            foreach (var line in lineList)
            {
                var gliphRun  = line.GlyphRun;
                var lineWidth = line.Bounds.Width * contentScaleFactorWidth;
                var flush     = line.PenOffsetForFlush(flushFactor, boundsWidth);

                foreach (var glyph in gliphRun)
                {
                    var letterPosition = glyph.Position;
                    var letterDef      = glyph.Definition;
                    lastCharWidth     = letterDef.Width * contentScaleFactorWidth;
                    letterPosition.X += flush;
                    letterPosition.Y  = (nextFontPositionY - letterDef.YOffset) / contentScaleFactorHeight;

                    //recordLetterInfo(letterPosition, glyph.def, lineGlyphIndex++);

                    var tmpInfo = new LetterInfo();

                    tmpInfo.Definition         = letterDef;
                    tmpInfo.Position           = letterPosition;
                    tmpInfo.ContentSize.Width  = letterDef.Width;
                    tmpInfo.ContentSize.Height = letterDef.Height;

                    if (lineGlyphIndex >= lettersInfo.Count)
                    {
                        lettersInfo.Add(tmpInfo);
                    }
                    else
                    {
                        lettersInfo[lineGlyphIndex] = tmpInfo;
                    }

                    lineGlyphIndex++;

                    lastCharAdvance = (int)glyph.Definition.XAdvance;
                }

                // calculate our longest line which is used for calculating our ContentSize
                if (lineWidth > longestLine)
                {
                    longestLine = lineWidth;
                }

                nextFontPositionY -= LineHeight;
            }

            CCSize tmpSize;

            // If the last character processed has an xAdvance which is less that the width of the characters image, then we need
            // to adjust the width of the string to take this into account, or the character will overlap the end of the bounding
            // box
            if (lastCharAdvance < lastCharWidth)
            {
                tmpSize.Width = longestLine - lastCharAdvance + lastCharWidth;
            }
            else
            {
                tmpSize.Width = longestLine;
            }

            tmpSize.Height = totalHeight;

            if (Dimensions.Height > 0)
            {
                tmpSize.Height = Dimensions.Height * contentScaleFactorHeight;
            }

            ContentSize = tmpSize / CCLabel.DefaultTexelToContentSizeRatios;

            lineList.Clear();

            CCRect   uvRect;
            CCSprite letterSprite;

            for (int c = 0; c < Children.Count; c++)
            {
                letterSprite = (CCSprite)Children[c];
                int tag = letterSprite.Tag;
                if (tag >= length)
                {
                    RemoveChild(letterSprite, true);
                }
                else if (tag >= 0)
                {
                    if (letterSprite != null)
                    {
                        uvRect = lettersInfo[tag].Definition.Subrect;
                        letterSprite.TextureRectInPixels = uvRect;
                        letterSprite.ContentSize         = uvRect.Size;
                    }
                }
            }

            UpdateQuads();
            UpdateColor();
        }