示例#1
0
        /// <summary>
        /// initializes a TextureAtlas with a previously initialized Texture2D object, and
        /// with an initial capacity for Quads.
        /// The TextureAtlas capacity can be increased in runtime.
        /// WARNING: Do not reinitialize the TextureAtlas because it will leak memory (issue #706)
        /// </summary>
        public bool InitWithTexture(CCTexture2D texture, int capacity)
        {
            //Debug.Assert(texture != null);

            // retained in property
            m_pTexture = texture;

            // Re-initialization is not allowed
            Debug.Assert(m_pQuads == null);

            if (capacity < 4)
            {
                capacity = 4;
            }

            m_pVertexBuffer = new CCQuadVertexBuffer(capacity, BufferUsage.WriteOnly);
            m_pQuads        = m_pVertexBuffer.Data;

            Dirty = true;

            return(true);
        }
示例#2
0
        protected virtual bool InitWithTexture(CCTexture2D tex, int capacity)
        {
            m_blendFunc = CCBlendFunc.AlphaBlend;

            m_pobTextureAtlas = new CCTextureAtlas();

            if (capacity == 0)
            {
                capacity = kDefaultSpriteBatchCapacity;
            }

            ContentSize = tex.ContentSize; // @@ TotallyEvil - contentSize should return the size of the sprite sheet
            m_pobTextureAtlas.InitWithTexture(tex, capacity);

            UpdateBlendFunc();

            // no lazy alloc in this node
            m_pChildren      = new CCRawList <CCNode>(capacity);
            m_pobDescendants = new CCRawList <CCSprite>(capacity);

            return(true);
        }
示例#3
0
        public virtual void AddChild(CCNode child, int zOrder, int tag)
        {
            Debug.Assert(child != null, "Argument must be non-null");
            Debug.Assert(child.m_pParent == null, "child already added. It can't be added again");
            Debug.Assert(child != this, "Can not add myself to myself.");

            if (m_pChildren == null)
            {
                m_pChildren = new CCRawList <CCNode>();
            }

            InsertChild(child, zOrder);

            child.m_nTag            = tag;
            child.Parent            = this;
            child.m_uOrderOfArrival = s_globalOrderOfArrival++;

            if (m_bRunning)
            {
                child.OnEnter();
                child.OnEnterTransitionDidFinish();
            }
        }
示例#4
0
        /// <summary>
        /// initializes a TextureAtlas with a previously initialized Texture2D object, and
        /// with an initial capacity for Quads.
        /// The TextureAtlas capacity can be increased in runtime.
        /// WARNING: Do not reinitialize the TextureAtlas because it will leak memory (issue #706)
        /// </summary>
        public bool InitWithTexture(CCTexture2D texture, int capacity)
        {
            //Debug.Assert(texture != null);

            // retained in property
            m_pTexture = texture;

            // Re-initialization is not allowed
            Debug.Assert(m_pQuads == null);

            if (capacity == 0)
            {
                capacity = 4;
            }

            m_pQuads = new CCRawList <CCV3F_C4B_T2F_Quad>(capacity);

            Dirty = true;

            MapBuffers();

            return(true);
        }
示例#5
0
        public int RebuildIndexInOrder(CCSprite pobParent, int uIndex)
        {
            CCRawList <CCNode> pChildren = pobParent.Children;

            if (pChildren != null && pChildren.count > 0)
            {
                CCNode[] elements = pChildren.Elements;
                for (int i = 0, count = pChildren.count; i < count; i++)
                {
                    if (elements[i].ZOrder < 0)
                    {
                        uIndex = RebuildIndexInOrder((CCSprite)pChildren[i], uIndex);
                    }
                }
            }

            // ignore self (batch node)
            if (!pobParent.Equals(this))
            {
                pobParent.AtlasIndex = uIndex;
                uIndex++;
            }

            if (pChildren != null && pChildren.count > 0)
            {
                CCNode[] elements = pChildren.Elements;
                for (int i = 0, count = pChildren.count; i < count; i++)
                {
                    if (elements[i].ZOrder >= 0)
                    {
                        uIndex = RebuildIndexInOrder((CCSprite)elements[i], uIndex);
                    }
                }
            }

            return(uIndex);
        }
示例#6
0
        public void RemoveSpriteFromAtlas(CCSprite pobSprite)
        {
            // remove from TextureAtlas
            m_pobTextureAtlas.RemoveQuadAtIndex(pobSprite.AtlasIndex);

            // Cleanup sprite. It might be reused (issue #569)
            pobSprite.BatchNode = null;

            int uIndex = m_pobDescendants.IndexOf(pobSprite);

            if (uIndex >= 0)
            {
                m_pobDescendants.RemoveAt(uIndex);

                // update all sprites beyond this one
                int        count    = m_pobDescendants.count;
                CCSprite[] elements = m_pobDescendants.Elements;

                for (; uIndex < count; ++uIndex)
                {
                    elements[uIndex].AtlasIndex--;
                }
            }

            // remove children recursively
            CCRawList <CCNode> pChildren = pobSprite.Children;

            if (pChildren != null && pChildren.count > 0)
            {
                CCNode[] elements = pChildren.Elements;
                for (int i = 0, count = pChildren.count; i < count; i++)
                {
                    RemoveSpriteFromAtlas((CCSprite)elements[i]);
                }
            }
        }
示例#7
0
        public void InsertChild(CCSprite pobSprite, int uIndex)
        {
            pobSprite.BatchNode  = this;
            pobSprite.AtlasIndex = uIndex;
            pobSprite.Dirty      = true;

            if (m_pobTextureAtlas.TotalQuads == m_pobTextureAtlas.Capacity)
            {
                IncreaseAtlasCapacity();
            }

            m_pobTextureAtlas.InsertQuad(ref pobSprite.m_sQuad, uIndex);

            m_pobDescendants.Insert(uIndex, pobSprite);

            // update indices
            CCSprite[] delements = m_pobDescendants.Elements;
            for (int i = uIndex + 1, count = m_pobDescendants.count; i < count; i++)
            {
                delements[i].AtlasIndex++;
            }

            // add children recursively
            CCRawList <CCNode> pChildren = pobSprite.Children;

            if (pChildren != null && pChildren.count > 0)
            {
                CCNode[] elements = pChildren.Elements;
                for (int j = 0, count = pChildren.count; j < count; j++)
                {
                    var pChild = (CCSprite)elements[j];
                    uIndex = AtlasIndexForChild(pChild, pChild.ZOrder);
                    InsertChild(pChild, uIndex);
                }
            }
        }
示例#8
0
 ///<summary>
 /// Constructs a new enumerator.
 ///</summary>
 ///<param name="list"></param>
 public Enumerator(CCRawList <T> list)
 {
     _index = -1;
     _list  = list;
 }
示例#9
0
        private void UpdateAtlasIndex(CCSprite sprite, ref int curIndex)
        {
            int count = 0;
            CCRawList <CCNode> pArray = sprite.Children;

            if (pArray != null)
            {
                count = pArray.Count;
            }

            int oldIndex = 0;

            if (count == 0)
            {
                oldIndex                 = sprite.AtlasIndex;
                sprite.AtlasIndex        = curIndex;
                sprite.m_uOrderOfArrival = 0;
                if (oldIndex != curIndex)
                {
                    Swap(oldIndex, curIndex);
                }
                curIndex++;
            }
            else
            {
                bool needNewIndex = true;

                if (pArray.Elements[0].m_nZOrder >= 0)
                {
                    //all children are in front of the parent
                    oldIndex                 = sprite.AtlasIndex;
                    sprite.AtlasIndex        = curIndex;
                    sprite.m_uOrderOfArrival = 0;
                    if (oldIndex != curIndex)
                    {
                        Swap(oldIndex, curIndex);
                    }
                    curIndex++;

                    needNewIndex = false;
                }

                for (int i = 0; i < count; i++)
                {
                    var child = (CCSprite)pArray.Elements[i];
                    if (needNewIndex && child.m_nZOrder >= 0)
                    {
                        oldIndex                 = sprite.AtlasIndex;
                        sprite.AtlasIndex        = curIndex;
                        sprite.m_uOrderOfArrival = 0;
                        if (oldIndex != curIndex)
                        {
                            Swap(oldIndex, curIndex);
                        }
                        curIndex++;
                        needNewIndex = false;
                    }

                    UpdateAtlasIndex(child, ref curIndex);
                }

                if (needNewIndex)
                {
                    //all children have a zOrder < 0)
                    oldIndex                 = sprite.AtlasIndex;
                    sprite.AtlasIndex        = curIndex;
                    sprite.m_uOrderOfArrival = 0;
                    if (oldIndex != curIndex)
                    {
                        Swap(oldIndex, curIndex);
                    }
                    curIndex++;
                }
            }
        }
示例#10
0
        private CCBMFontConfiguration InitializeFont(string fontName, float fontSize, string charset)
        {
            if (m_pData == null)
            {
                InitializeTTFAtlas(1024, 1024);
            }

            if (String.IsNullOrEmpty(charset))
            {
                charset = " ";
            }

            var chars = new CCRawList <char>();

            var fontKey = GetFontKey(fontName, fontSize);

            CCBMFontConfiguration fontConfig;

            if (!s_pConfigurations.TryGetValue(fontKey, out fontConfig))
            {
                fontConfig = new CCBMFontConfiguration();
                s_pConfigurations.Add(fontKey, fontConfig);
            }

            for (int i = 0; i < charset.Length; i++)
            {
                var ch = charset[i];
                if (!fontConfig.m_pFontDefDictionary.ContainsKey(ch) && chars.IndexOf(ch) == -1)
                {
                    chars.Add(ch);
                }
            }

            if (chars.Count == 0)
            {
                return(fontConfig);
            }

            CreateFont(fontName, fontSize * CCMacros.CCContentScaleFactor(), chars);

            fontConfig.m_nCommonHeight = (int)Math.Ceiling(GetFontHeight());

            int[] data = null;

            for (int i = 0; i < chars.Count; i++)
            {
                var s = chars[i].ToString();

                var charSize = GetMeasureString(s);

                int w = (int)Math.Ceiling(charSize.Width + 2);
                int h = (int)Math.Ceiling(charSize.Height + 2);

                if (data == null || data.Length < (w * h))
                {
                    data = new int[w * h];
                }

                unsafe
                {
                    int   stride;
                    byte *pBase = GetBitmapData(s, out stride);

                    int minX = w;
                    int maxX = 0;
                    int minY = h;
                    int maxY = 0;

                    for (int y = 0; y < h; y++)
                    {
                        var row = (int *)(pBase + y * stride);

                        for (int x = 0; x < w; x++)
                        {
                            if (row[x] != 0)
                            {
                                minX = Math.Min(minX, x);
                                maxX = Math.Max(maxX, x);
                                minY = Math.Min(minY, y);
                                maxY = Math.Max(maxY, y);
                            }
                        }
                    }

                    w = Math.Max(maxX - minX + 1, 1);
                    h = Math.Max(maxY - minY + 1, 1);

                    //maxX = minX + w;
                    //maxY = minY + h;

                    int index = 0;
                    for (int y = minY; y <= maxY; y++)
                    {
                        var row = (int *)(pBase + y * stride);
                        for (int x = minX; x <= maxX; x++)
                        {
                            data[index] = row[x];
                            index++;
                        }
                    }

                    var region = AllocateRegion(w, h);

                    if (region.x >= 0)
                    {
                        SetRegionData(region, data, w);

                        var info = GetKerningInfo(chars[i]);

                        var fontDef = new CCBMFontConfiguration.CCBMFontDef()
                        {
                            charID   = chars[i],
                            rect     = new CCRect(region.x, region.y, region.width, region.height),
                            xOffset  = minX, // + (int)Math.Ceiling(info.A),
                            yOffset  = minY,
                            xAdvance = (int)Math.Ceiling(info.A + info.B + info.C)
                        };

                        fontConfig.CharacterSet.Add(chars[i]);
                        fontConfig.m_pFontDefDictionary.Add(chars[i], fontDef);
                    }
                    else
                    {
                        CCLog.Log("Texture atlas is full");
                    }
                }
            }

            m_bTextureDirty = true;

            return(fontConfig);
        }
示例#11
0
        protected void UpdateLabel()
        {
            SetString(m_sInitialString, true);

            if (m_fWidth > 0)
            {
                // Step 1: Make multiline
                string str_whole        = m_sString;
                int    stringLength     = m_sString.Length;
                var    multiline_string = new StringBuilder(stringLength);
                var    last_word        = new StringBuilder(stringLength);

                int   line = 1, i = 0;
                bool  start_line = false, start_word = false;
                float startOfLine = -1, startOfWord = -1;
                int   skip = 0;

                CCRawList <CCNode> children = m_pChildren;
                for (int j = 0; j < children.count; j++)
                {
                    CCSprite characterSprite;

                    while ((characterSprite = (CCSprite)GetChildByTag(j + skip)) == null)
                    {
                        skip++;
                    }

                    if (!characterSprite.Visible)
                    {
                        continue;
                    }

                    if (i >= stringLength)
                    {
                        break;
                    }

                    char character = str_whole[i];

                    if (!start_word)
                    {
                        startOfWord = GetLetterPosXLeft(characterSprite);
                        start_word  = true;
                    }
                    if (!start_line)
                    {
                        startOfLine = startOfWord;
                        start_line  = true;
                    }

                    // Newline.
                    if (character == '\n')
                    {
                        int len = last_word.Length;
                        while (len > 0 && Char.IsWhiteSpace(last_word[len - 1]))
                        {
                            len--;
                            last_word.Remove(len, 1);
                        }

                        multiline_string.Append(last_word);
                        multiline_string.Append('\n');

#if XBOX || XBOX360
                        last_word.Length = 0;
#else
                        last_word.Clear();
#endif

                        start_word  = false;
                        start_line  = false;
                        startOfWord = -1;
                        startOfLine = -1;
                        i++;
                        line++;

                        if (i >= stringLength)
                        {
                            break;
                        }

                        character = str_whole[i];

                        if (startOfWord == 0)
                        {
                            startOfWord = GetLetterPosXLeft(characterSprite);
                            start_word  = true;
                        }
                        if (startOfLine == 0)
                        {
                            startOfLine = startOfWord;
                            start_line  = true;
                        }
                    }

                    // Whitespace.
                    if (Char.IsWhiteSpace(character))
                    {
                        last_word.Append(character);
                        multiline_string.Append(last_word);
#if XBOX || XBOX360
                        last_word.Length = 0;
#else
                        last_word.Clear();
#endif
                        start_word  = false;
                        startOfWord = -1;
                        i++;
                        continue;
                    }

                    // Out of bounds.
                    if (GetLetterPosXRight(characterSprite) - startOfLine > m_fWidth)
                    {
                        if (!m_bLineBreakWithoutSpaces)
                        {
                            last_word.Append(character);

                            int len = multiline_string.Length;
                            while (len > 0 && Char.IsWhiteSpace(multiline_string[len - 1]))
                            {
                                len--;
                                multiline_string.Remove(len, 1);
                            }

                            if (multiline_string.Length > 0)
                            {
                                multiline_string.Append('\n');
                            }

                            line++;
                            start_line  = false;
                            startOfLine = -1;
                            i++;
                        }
                        else
                        {
                            int len = last_word.Length;
                            while (len > 0 && Char.IsWhiteSpace(last_word[len - 1]))
                            {
                                len--;
                                last_word.Remove(len, 1);
                            }

                            multiline_string.Append(last_word);
                            multiline_string.Append('\n');

#if XBOX || XBOX360
                            last_word.Length = 0;
#else
                            last_word.Clear();
#endif

                            start_word  = false;
                            start_line  = false;
                            startOfWord = -1;
                            startOfLine = -1;
                            line++;

                            if (i >= stringLength)
                            {
                                break;
                            }

                            if (startOfWord == 0)
                            {
                                startOfWord = GetLetterPosXLeft(characterSprite);
                                start_word  = true;
                            }
                            if (startOfLine == 0)
                            {
                                startOfLine = startOfWord;
                                start_line  = true;
                            }

                            j--;
                        }

                        continue;
                    }
                    else
                    {
                        // Character is normal.
                        last_word.Append(character);
                        i++;
                        continue;
                    }
                }

                multiline_string.Append(last_word);

                m_sString = multiline_string.ToString();

                UpdateString(true);
            }

            // Step 2: Make alignment
            if (m_pAlignment != CCTextAlignment.CCTextAlignmentLeft)
            {
                int i = 0;

                int lineNumber = 0;
                int str_len    = m_sString.Length;
                var last_line  = new CCRawList <char>();
                for (int ctr = 0; ctr <= str_len; ++ctr)
                {
                    if (ctr == str_len || m_sString[ctr] == '\n')
                    {
                        float lineWidth   = 0.0f;
                        int   line_length = last_line.Count;
                        // if last line is empty we must just increase lineNumber and work with next line
                        if (line_length == 0)
                        {
                            lineNumber++;
                            continue;
                        }
                        int index = i + line_length - 1 + lineNumber;
                        if (index < 0)
                        {
                            continue;
                        }

                        var lastChar = (CCSprite)GetChildByTag(index);
                        if (lastChar == null)
                        {
                            continue;
                        }

                        lineWidth = lastChar.Position.X + lastChar.ContentSize.Width / 2.0f;

                        float shift = 0;
                        switch (m_pAlignment)
                        {
                        case CCTextAlignment.CCTextAlignmentCenter:
                            shift = ContentSize.Width / 2.0f - lineWidth / 2.0f;
                            break;

                        case CCTextAlignment.CCTextAlignmentRight:
                            shift = ContentSize.Width - lineWidth;
                            break;

                        default:
                            break;
                        }

                        if (shift != 0)
                        {
                            for (int j = 0; j < line_length; j++)
                            {
                                index = i + j + lineNumber;
                                if (index < 0)
                                {
                                    continue;
                                }

                                var characterSprite = (CCSprite)GetChildByTag(index);
                                characterSprite.Position = characterSprite.Position + new CCPoint(shift, 0.0f);
                            }
                        }

                        i += line_length;
                        lineNumber++;

                        last_line.Clear();
                        continue;
                    }

                    last_line.Add(m_sString[ctr]);
                }
            }
        }
示例#12
0
        private static void GetKerningInfo(CCRawList <char> charset)
        {
            _abcValues.Clear();

            var fontFace = new FontFace(_currentFont);

            var value = new ABCFloat[1];

            var glyphRun = new GlyphRun();

            glyphRun.FontFace = fontFace;
            glyphRun.FontSize = _currentDIP;

            var BrushColor = SharpDX.Color.White;

            SharpDX.DirectWrite.Matrix mtrx = new SharpDX.DirectWrite.Matrix();
            mtrx.M11 = 1F;
            mtrx.M12 = 0;
            mtrx.M21 = 0;
            mtrx.M22 = 1F;
            mtrx.Dx  = 0;
            mtrx.Dy  = 0;

            //GlyphMetrics[] metrics = fontFace.GetGdiCompatibleGlyphMetrics(23, 1, mtrx, false, glyphIndices, false);

            //FontMetrics metr = fontFace.GetGdiCompatibleMetrics(23, 1, new SharpDX.DirectWrite.Matrix());
            //_pRenderTarget.DrawGlyphRun(new SharpDX.DrawingPointF(left, top), glyphRun, new SharpDX.Direct2D1.SolidColorBrush(_pRenderTarget, BrushColor), MeasuringMode.GdiClassic);
            int[] codePoints = new int[1];
            var   unitsPerEm = fontFace.Metrics.DesignUnitsPerEm;
            var   familyName = _currentFont.ToString();


            for (int i = 0; i < charset.Count; i++)
            {
                var ch = charset[i];
                if (!_abcValues.ContainsKey(ch))
                {
                    var textLayout = new TextLayout(FactoryDWrite, ch.ToString(), textFormat, unitsPerEm, unitsPerEm);

                    var tlMetrics = textLayout.Metrics;
                    var tlmWidth  = tlMetrics.Width;
                    var tllWidth  = tlMetrics.LayoutWidth;

                    codePoints[0] = (int)ch;
                    short[] glyphIndices = fontFace.GetGlyphIndices(codePoints);
                    glyphRun.Indices = glyphIndices;

                    var metrics = fontFace.GetDesignGlyphMetrics(glyphIndices, false);

                    //var width = metrics[0].AdvanceWidth + metrics[0].LeftSideBearing + metrics[0].RightSideBearing;
                    //var glyphWidth = _currentFontSizeEm * (float)metrics[0].AdvanceWidth / unitsPerEm;
                    //var abcWidth = _currentDIP * (float)width / unitsPerEm;

                    //value[0].abcfA = _currentFontSizeEm * (float)metrics[0].LeftSideBearing / unitsPerEm;
                    //value[0].abcfB = _currentFontSizeEm * (float)metrics[0].AdvanceWidth / unitsPerEm;
                    //value[0].abcfC = _currentFontSizeEm * (float)metrics[0].RightSideBearing / unitsPerEm;

                    // The A and C values are throwing the spacing off
                    //value[0].abcfA = _currentDIP * (float)metrics[0].LeftSideBearing / unitsPerEm;
                    value[0].abcfB = _currentDIP * (float)metrics[0].AdvanceWidth / unitsPerEm;
                    //value[0].abcfC = _currentDIP * (float)metrics[0].RightSideBearing / unitsPerEm;

                    _abcValues.Add(
                        ch,
                        new KerningInfo()
                    {
                        A = value[0].abcfA,
                        B = value[0].abcfB,
                        C = value[0].abcfC
                    });
                }
            }
        }
示例#13
0
        private string CreateFont(string fontName, float fontSize, CCRawList <char> charset)
        {
            if (Factory2D == null)
            {
                Factory2D      = new SharpDX.Direct2D1.Factory();
                FactoryDWrite  = new SharpDX.DirectWrite.Factory();
                FactoryImaging = new SharpDX.WIC.ImagingFactory();

                dpi      = Factory2D.DesktopDpi;
                dpiScale = dpi.Height / 72f;
            }

            if (_defaultFont == null)
            {
                _defaultFont = GenericSanSerif();
                //_defaultDIP = ConvertPointSizeToDIP(_defaultFontSizeEm);
            }

            FontFamily fontFamily = GetFontFamily(fontName);


            if (!_fontFamilyCache.TryGetValue(fontName, out fontFamily))
            {
                var ext = Path.GetExtension(fontName);

                _currentFont = _defaultFont;

                if (!String.IsNullOrEmpty(ext) && ext.ToLower() == ".ttf")
                {
                    //var appPath = AppDomain.CurrentDomain.BaseDirectory;
                    //var contentPath = Path.Combine(appPath, CCApplication.SharedApplication.Content.RootDirectory);
                    //var fontPath = Path.Combine(contentPath, fontName);

                    //if (File.Exists(fontPath))
                    //{
                    // try
                    //{
                    //var fontFileReference = new FontCollection(
                    //_loadedFonts.AddFontFile(fontPath);

                    //        //fontFamily = _loadedFonts.Families[_loadedFonts.Families.Length - 1];

                    //        //_currentFont = new Font(fontFamily, fontSize);
                    //    }
                    //    catch
                    //    {
                    //        _currentFont = _defaultFont;
                    //    }
                    //}
                    //else
                    //{
                    _currentFont       = _defaultFont;
                    _currentFontSizeEm = fontSize;
                    _currentDIP        = ConvertPointSizeToDIP(fontSize);
                    //}
                }
                else
                {
                    _currentFont       = GetFont(fontName, fontSize);
                    _currentFontSizeEm = fontSize;
                    _currentDIP        = ConvertPointSizeToDIP(fontSize);
                }

                _fontFamilyCache.Add(fontName, _currentFont.FontFamily);
            }
            else
            {
                _currentFont       = fontFamily.GetFirstMatchingFont(FontWeight.Regular, FontStretch.Normal, FontStyle.Normal);
                _currentFontSizeEm = fontSize;
                _currentDIP        = ConvertPointSizeToDIP(fontSize);
            }
            fontName   = _currentFont.FontFamily.FamilyNames.GetString(0);
            textFormat = new TextFormat(FactoryDWrite, fontName, _currentDIP);

            GetKerningInfo(charset);

            return(_currentFont.ToString());
        }
示例#14
0
 private void CreateFont(string fontName, float fontSize, CCRawList <char> charset)
 {
     throw(new NotImplementedException("PSM support for CCLabel is not implemented yet."));
 }