/// <summary>
        /// start from (0, 0) to the right.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="server"></param>
        /// <param name="totalWidth"></param>
        /// <param name="totalHeight"></param>
        unsafe private void PositionPass(string text, GlyphServer server,
                                         out float totalWidth, out float totalHeight)
        {
            int          textureWidth  = server.TextureWidth;
            int          textureHeight = server.TextureHeight;
            VertexBuffer buffer        = this.positionBuffer;
            var          positionArray = (QuadPositionStruct *)buffer.MapBuffer(MapBufferAccess.ReadWrite);
            const float  height        = 2; // 2 is the height value in clip space.

            totalWidth  = 0;
            totalHeight = height;
            int index = 0;

            foreach (var c in text)
            {
                if (index >= this.textModel.Capacity)
                {
                    break;
                }

                GlyphInfo glyphInfo;
                float     wByH = 0;
                if (server.GetGlyphInfo(c, out glyphInfo))
                {
                    float w = (glyphInfo.quad.rightBottom.x - glyphInfo.quad.leftBottom.x) * textureWidth;
                    float h = (glyphInfo.quad.rightBottom.y - glyphInfo.quad.rightTop.y) * textureHeight;
                    wByH = height * w / h;
                }
                else
                {
                    // put an empty glyph(square) here.
                    wByH = height * 1.0f / 1.0f;
                }

                var leftTop     = new vec2(totalWidth, height);
                var leftBottom  = new vec2(totalWidth, 0);
                var rightBottom = new vec2(totalWidth + wByH, 0);
                var rightTop    = new vec2(totalWidth + wByH, height);
                positionArray[index++] = new QuadPositionStruct(leftTop, leftBottom, rightBottom, rightTop);

                totalWidth += wByH;
            }

            buffer.UnmapBuffer();
        }
        /// <summary>
        /// start from (0, 0) to the right.
        /// </summary>
        /// <param name="text"></param>
        /// <param name="server"></param>
        /// <param name="totalWidth"></param>
        /// <param name="totalHeight"></param>
        unsafe private void PositionPass(string text, GlyphServer server,
                                         out float totalWidth, out float totalHeight)
        {
            int          textureWidth  = server.TextureWidth;
            int          textureHeight = server.TextureHeight;
            VertexBuffer buffer        = this.positionBuffer;
            var          positionArray = (QuadPositionStruct *)buffer.MapBuffer(MapBufferAccess.ReadWrite);
            const float  height        = 2.0f; // let's say height is 2.0f.

            totalWidth  = 0;
            totalHeight = height;
            int index = 0;

            foreach (var c in text)
            {
                if (index >= this.labelModel.Capacity)
                {
                    break;
                }

                GlyphInfo glyphInfo;
                float     wByH = 0;
                if (server.GetGlyphInfo(c, out glyphInfo))
                {
                    float w = (glyphInfo.quad.rightBottom.x - glyphInfo.quad.leftBottom.x) * textureWidth;
                    float h = (glyphInfo.quad.rightBottom.y - glyphInfo.quad.rightTop.y) * textureHeight;
                    wByH = height * w / h;
                }
                else
                {
                    // put an empty glyph(square) here.
                    wByH = height * 1.0f / 1.0f;
                }

                var leftTop     = new vec2(totalWidth, height / 2);
                var leftBottom  = new vec2(totalWidth, -height / 2);
                var rightBottom = new vec2(totalWidth + wByH, -height / 2);
                var rightTop    = new vec2(totalWidth + wByH, height / 2);
                positionArray[index++] = new QuadPositionStruct(leftTop, leftBottom, rightBottom, rightTop);
                totalWidth            += wByH;
            }

            // move to center.
            const float scale = 1f;

            for (int i = 0; i < text.Length; i++)
            {
                if (i >= this.labelModel.Capacity)
                {
                    break;
                }

                QuadPositionStruct quad = positionArray[i];
                var newPos = new QuadPositionStruct(
                    // y is already in [-1, 1], so just shrink x to [-1, 1]
                    new vec2(quad.leftTop.x / totalWidth * 2.0f - 1f, quad.leftTop.y) * scale,
                    new vec2(quad.leftBottom.x / totalWidth * 2.0f - 1f, quad.leftBottom.y) * scale,
                    new vec2(quad.rightBottom.x / totalWidth * 2.0f - 1f, quad.rightBottom.y) * scale,
                    new vec2(quad.rightTop.x / totalWidth * 2.0f - 1f, quad.rightTop.y) * scale
                    );

                positionArray[i] = newPos;
            }

            buffer.UnmapBuffer();
        }