public static PFrame.Tiny.Font Convert(UnityEngine.Font ufont)
        {
            var font = new PFrame.Tiny.Font();

            font.Ascent     = ufont.ascent;
            font.LineHeight = ufont.lineHeight;
            font.FontSize   = ufont.fontSize;

            var ucharInfos       = ufont.characterInfo;
            var num              = ucharInfos.Length;
            var characterInfoMap = new NativeHashMap <int, PFrame.Tiny.CharacterInfo>(num, Allocator.Temp);

            for (int i = 0; i < num; i++)
            {
                var ucharInfo = ucharInfos[i];
                var charInfo  = TinyAuthoringUtil.Convert(ucharInfo);
                characterInfoMap.Add(charInfo.index, charInfo);
            }
            font.CharacterInfoMap = characterInfoMap;

            return(font);
        }
        public static void CreateTextMesh(
            TextMesh textMesh,
            PFrame.Tiny.Font font,
            Mesh mesh
            )
        {
            var Idx    = 0;
            var TriIdx = 0;

            var textLayoutData = TextMeshUtil.GetTextLayoutData(textMesh, font);
            var charNum        = textLayoutData.CharNum;
            //var text = textMesh.Text;
            //var charNum = text.LengthInBytes;
            int triCount  = 2 * 3 * charNum;
            int vertCount = 4 * charNum;

            var Tris   = new NativeArray <int>(triCount, Allocator.TempJob);
            var Verts  = new NativeArray <float3>(vertCount, Allocator.TempJob);
            var UVs    = new NativeArray <float2>(vertCount, Allocator.TempJob);
            var Colors = new NativeArray <Unity.Tiny.Color>(vertCount, Allocator.TempJob);

            TextMeshUtil.CreateTextMesh(textMesh, font, textLayoutData, (charInfo, pos, scale) =>
            {
                var posX = pos.x;
                var posY = pos.y;
                var posZ = pos.z;

                float minx = posX + charInfo.minX * scale;
                float maxx = posX + charInfo.maxX * scale;
                float miny = posY + charInfo.minY * scale;
                float maxy = posY + charInfo.maxY * scale;

                Verts[Idx + 0] = new float3(minx, miny, posZ);
                Verts[Idx + 1] = new float3(minx, maxy, posZ);
                Verts[Idx + 2] = new float3(maxx, maxy, posZ);
                Verts[Idx + 3] = new float3(maxx, miny, posZ);
                //float x = posX + charInfo.bearing * scale;
                //float y = posY + charInfo.minY * scale;
                //var width = charInfo.glyphWidth * scale;
                //var height = charInfo.glyphHeight * scale;

                //Verts[Idx + 0] = new float3(x, y, posZ);
                //Verts[Idx + 1] = new float3(x, y + height, posZ);
                //Verts[Idx + 2] = new float3(x + width, y + height, posZ);
                //Verts[Idx + 3] = new float3(x + width, y, posZ);

                UVs[Idx + 0] = charInfo.uvBottomLeft;
                UVs[Idx + 1] = charInfo.uvTopLeft;
                UVs[Idx + 2] = charInfo.uvTopRight;
                UVs[Idx + 3] = charInfo.uvBottomRight;

                Tris[TriIdx + 0] = Idx + 0;
                Tris[TriIdx + 1] = Idx + 1;
                Tris[TriIdx + 2] = Idx + 2;
                Tris[TriIdx + 3] = Idx + 0;
                Tris[TriIdx + 4] = Idx + 2;
                Tris[TriIdx + 5] = Idx + 3;

                Idx    += 4;
                TriIdx += 6;
            });

            mesh.SetVertices(Verts);
            mesh.SetUVs(0, UVs);
            mesh.SetIndices(Tris, 0, Tris.Length, MeshTopology.Triangles, 0, true, 0);
            mesh.SetColors(Colors);

            Verts.Dispose();
            Tris.Dispose();
            UVs.Dispose();
            Colors.Dispose();

            textLayoutData.Dispose();
        }