Exemplo n.º 1
0
    public void LoadFromDisk()
    {
        string json = PlayerPrefs.GetString(KeyPlayerPrefs);

        if (string.IsNullOrEmpty(json))
        {
            Debug.Log("FileInfo is not exists in PlayerPrefs!");
            return;
        }

        DynamicAtlas.FileInfo info = JsonUtility.FromJson <DynamicAtlas.FileInfo>(json);

        DynamicAtlas loadAtlas = DynamicAtlas.Load(info);

        if (loadAtlas == null)
        {
            Debug.Log(string.Format("Load atlas {0} is not exists!", info.Name));
            return;
        }

        atlas = loadAtlas;
        Show();

        Debug.Log(string.Format("Load atlas name: {0}, method: {1}", atlas.Name, atlas.Method));
    }
Exemplo n.º 2
0
    public void DeleteFromDisk()
    {
        string json = PlayerPrefs.GetString(KeyPlayerPrefs);

        if (string.IsNullOrEmpty(json))
        {
            Debug.Log("FileInfo is not exists in PlayerPrefs!");
            return;
        }

        DynamicAtlas.FileInfo info = JsonUtility.FromJson <DynamicAtlas.FileInfo>(json);

        bool isDelete = DynamicAtlas.Delete(info);

        if (isDelete == false)
        {
            Debug.Log(string.Format("Atlas {0} is not exists!", info.Name));
            return;
        }

        PlayerPrefs.DeleteKey(KeyPlayerPrefs);
        PlayerPrefs.Save();

        Debug.Log(string.Format("Delete atlas: {0}", atlas.Name));
    }
Exemplo n.º 3
0
    /// <summary>
    /// Save to disk the DynamicAtlas.
    /// </summary>
    /// <param name="atlas">DynamicAtlas.</param>
    /// <param name="info">Custom FileInfo.</param>
    /// <returns>Return FileInfo (Path and Name of saved atlas).</returns>
    public static FileInfo Save(DynamicAtlas atlas, FileInfo info = null)
    {
        if (info == null)
        {
            info = new FileInfo(atlas.Texture.name);
        }

        if (Directory.Exists(info.Path) == false)
        {
            Directory.CreateDirectory(info.Path);
        }

        if (atlas.IsApplied == false)
        {
            atlas.Apply();
        }

        byte[] bytes = atlas.Texture.EncodeToPNG();
        string json  = JsonUtility.ToJson(atlas);

        File.WriteAllBytes(info.PathTexture, bytes);
        File.WriteAllText(info.PathData, json);

        return(info);
    }
    void ClearFreeAreas()
    {
        DynamicAtlas dynamicAtlas = DynamicAtlasManager.Instance.GetDynamicAtlas(_mGroup);

        if (AtlasConfig.kUsingCopyTexture)
        {
            List <List <IntegerRectangle> > freeLists = dynamicAtlas.GetFreeAreas();
            int freeListsCount         = freeLists.Count;
            List <Texture2D> tex2DList = dynamicAtlas.tex2DList;
            for (int i = 0; i < freeListsCount; i++)
            {
                var       freeList      = freeLists[i];
                int       freeListCount = freeList.Count;
                Texture2D dstTex        = tex2DList[i];
                for (int j = 0; j < freeListCount; j++)
                {
                    IntegerRectangle item   = freeList[j];
                    Color32[]        colors = new Color32[item.width * item.height];
                    for (int k = 0; k < colors.Length; ++k)
                    {
                        colors[k] = Color.clear;
                    }
                    dstTex.SetPixels32((int)item.x, (int)item.y, item.width, item.height, colors);
                    dstTex.Apply();
                }
            }
        }
        else
        {
            dynamicAtlas.ClearTextureWithBlit();
        }
    }
Exemplo n.º 5
0
 void UpdateUV()
 {
     if (AtlasType == FXAtlasType.Static)
     {
         if (m_Atlas != null)
         {
             Texture texture = m_Atlas.spriteMaterial.mainTexture;
             if (texture != null)
             {
                 m_SpriteUV.Set(m_Sprite.x, m_Sprite.y, m_Sprite.width, m_Sprite.height);
                 m_SpriteUV = NGUIMath.ConvertToTexCoords(m_SpriteUV, texture.width, texture.height);
             }
         }
     }
     else if (AtlasType == FXAtlasType.Dynamic)
     {
         DynamicAtlasManager dynamic_atlas_manager = DynamicAtlasManager.GetInstance();
         if (dynamic_atlas_manager != null)
         {
             DynamicAtlas the_atlas = dynamic_atlas_manager.GetDynamicAtlas(m_DynamicAtlasType);
             if (the_atlas != null)
             {
                 Texture texture = the_atlas.m_Material.mainTexture;
                 if (texture != null && m_Sprite != null)
                 {
                     m_SpriteUV.Set(m_Sprite.x, m_Sprite.y, m_Sprite.width, m_Sprite.height);
                     m_SpriteUV = NGUIMath.ConvertToTexCoords(m_SpriteUV, texture.width, texture.height);
                 }
             }
         }
     }
 }
Exemplo n.º 6
0
 public void SetGroup(DynamicAtlasGroup group)
 {
     if (m_Atlas != null)
     {
         return;
     }
     m_Group = group;
     m_Atlas = DynamicAtlasManager.Instance.GetDynamicAtlas(group);
 }
    void DrawFreeArea(int index, DynamicAtlas dynamicAtlas)
    {
        Texture2D tex2D = null;

        if (texList.Count < index + 1)
        {
            tex2D = new Texture2D((int)_mGroup, (int)_mGroup, TextureFormat.ARGB32, false, true);
            texList.Add(tex2D);
            if (mFillColor == null)
            {
                mFillColor = tex2D.GetPixels32();
                for (int i = 0; i < mFillColor.Length; ++i)
                {
                    mFillColor[i] = Color.clear;
                }
            }
        }
        else
        {
            tex2D = texList[index];
        }
        tex2D.SetPixels32(mFillColor);
        if (isRefreshFreeAreas)
        {
            Color32[] tmpColor;
            List <IntegerRectangle> freeList = dynamicAtlas.GetFreeAreas()[index];
            foreach (IntegerRectangle item in freeList)
            {
                int size = item.width * item.height;
                tmpColor = new Color32[size];
                for (int k = 0; k < size; ++k)
                {
                    tmpColor[k] = Color.green;//画边
                }
                tex2D.SetPixels32(item.x, item.y, item.width, item.height, tmpColor);
                int outLineSize = 2;
                if (item.width < outLineSize * 2 || item.height < outLineSize * 2)
                {
                    outLineSize = 0;
                }

                size    -= outLineSize * 4;
                tmpColor = new Color32[size];
                for (int k = 0; k < size; ++k)
                {
                    tmpColor[k] = Color.yellow;
                }
                tex2D.SetPixels32(item.x + outLineSize, item.y + outLineSize, item.width - outLineSize * 2, item.height - outLineSize * 2, tmpColor);
                tex2D.Apply();
            }
        }

        float poxX = (index + 1) * 10 + index * dynamicAtlas.atlasWidth * scale;

        GUI.DrawTexture(new Rect(poxX, formPosY, dynamicAtlas.atlasWidth * scale, dynamicAtlas.atlasHeight * scale), tex2D);
    }
Exemplo n.º 8
0
    protected bool IsDynamicAtlasAvailable(eDynamicAtlasType type)
    {
        DynamicAtlas atlas = GetDynamicAtlas(type);

        if (atlas != null)
        {
            return(atlas.IsInitialized());
        }

        return(false);
    }
Exemplo n.º 9
0
    public void Create()
    {
        atlas = new DynamicAtlas(sizeAtlas, sizeAtlas, nameAtlas, method);
        // or
        // atlas = new DynamicAtlas(sizeAtlas, sizeAtlas, nameAtlas);
        // or
        // atlas = new DynamicAtlas(sizeAtlas, nameAtlas);

        Debug.Log(string.Format("Create atlas: {0}, method: {1}", atlas.Name, atlas.Method));

        Show();
    }
Exemplo n.º 10
0
    public void UnloadDynamicSprite(string spriteName, eDynamicAtlasType type)
    {
        DynamicAtlas atlas = GetDynamicAtlas(type);

        if (atlas != null)
        {
            atlas.RemoveSpriteReference(spriteName);
        }
        else
        {
            EB.Debug.LogError("DynamicAtlasManager[UnloadDynamicSprite]: Dynamic atlas does not exist!");
        }
    }
Exemplo n.º 11
0
    /// <summary>
    /// Loads the dynamic sprite.
    /// </summary>
    /// <param name="spriteName">Sprite name.</param>
    /// <param name="type">dynamic atlas type.</param>
    /// <param name="is_runtime">Set this to true if loading dynamic sprite at runtime(like uispirt & FX), set to false if trying to pre load dynamic sprite during loading process.</param>
    public void LoadDynamicSprite(string spriteName, eDynamicAtlasType type, bool is_runtime = true)
    {
        DynamicAtlas atlas = GetDynamicAtlas(type);

        if (atlas != null)
        {
            atlas.LoadDynamicSprite(spriteName, is_runtime);
        }
        else
        {
            EB.Debug.LogError("DynamicAtlasManager[LoadDynamicSprite]: Dynamic atlas does not exist!");
        }
    }
Exemplo n.º 12
0
    public void RemoveSpriteUVUpdateCallback(eDynamicAtlasType type, EventDelegate.Callback onSpriteUVUpdate)
    {
        DynamicAtlas atlas = GetDynamicAtlas(type);

        if (atlas != null)
        {
            EventDelegate.Remove(atlas.onSpriteUVsUpdate, onSpriteUVUpdate);
        }
        else
        {
            EB.Debug.LogError("DynamicAtlasManager[RemoveSpriteUVUpdateCallback]: Dynamic atlas does not exist!");
        }
    }
Exemplo n.º 13
0
    public void RemoveTextureAsyncCallback(eDynamicAtlasType type, EventDelegate.Callback onTextureAsyncSucceeded, EventDelegate.Callback onTextureAsyncFailed)
    {
        DynamicAtlas atlas = GetDynamicAtlas(type);

        if (atlas != null)
        {
            EventDelegate.Remove(atlas.onTextureAsyncSucceeded, onTextureAsyncSucceeded);
            EventDelegate.Remove(atlas.onTextureAsyncFailed, onTextureAsyncFailed);
        }
        else
        {
            EB.Debug.LogError("DynamicAtlasManager[RemoveTextureAsyncCallback]: Dynamic atlas does not exist!");
        }
    }
    public DynamicAtlas GetDynamicAtlas(DynamicAtlasGroup group, bool topFirst = true)
    {
        DynamicAtlas data;

        if (m_DynamicAtlas.ContainsKey(group))
        {
            data = m_DynamicAtlas[group];
        }
        else
        {
            data = new DynamicAtlas(group, topFirst);
            m_DynamicAtlas[group] = data;
        }
        return(data);
    }
Exemplo n.º 15
0
    public UISpriteData GetAtlasSprite(string spriteName, eDynamicAtlasType type)
    {
        DynamicAtlas atlas = GetDynamicAtlas(type);

        if (atlas != null)
        {
            return(atlas.GetSpriteData(spriteName));
        }
        else
        {
            EB.Debug.LogError("DynamicAtlasManager[GetAtlasSprite]: Dynamic atlas does not exist!");
        }

        return(null);
    }
Exemplo n.º 16
0
    public void SaveOnDisk()
    {
        if (AtlasIsNull())
        {
            return;
        }

        DynamicAtlas.FileInfo info = DynamicAtlas.Save(atlas);

        string json = JsonUtility.ToJson(info);

        Debug.Log("Save complite, infoFile: " + json);

        PlayerPrefs.SetString(KeyPlayerPrefs, json);
        PlayerPrefs.Save();
    }
Exemplo n.º 17
0
    /// <summary>
    /// Load from disk the DynamicAtlas.
    /// </summary>
    /// <param name="info">FileInfo.</param>
    /// <returns>Return DynamicAtlas.</returns>
    public static DynamicAtlas Load(FileInfo info)
    {
        if (File.Exists(info.PathTexture) == false || File.Exists(info.PathData) == false)
        {
            return(null);
        }

        byte[] bytes = File.ReadAllBytes(info.PathTexture);
        string json  = File.ReadAllText(info.PathData);

        DynamicAtlas atlas = JsonUtility.FromJson <DynamicAtlas>(json);

        atlas.Texture = new Texture2D(0, 0, TextureFormat.RGBA32, false);
        atlas.Texture.LoadImage(bytes);
        atlas.Texture.name = info.Name;

        return(atlas);
    }
Exemplo n.º 18
0
            private unsafe DynamicAtlas <Color> .Reservation Upload(FTBitmap bitmap)
            {
                bool foundRoom = false;

                DynamicAtlas <Color> .Reservation result = default(DynamicAtlas <Color> .Reservation);

                int width = bitmap.Width, rows = bitmap.Rows, pitch = bitmap.Pitch;

                var widthW  = width + (Font.GlyphMargin * 2);
                var heightW = rows + (Font.GlyphMargin * 2);

                foreach (var atlas in Atlases)
                {
                    if (atlas.TryReserve(widthW, heightW, out result))
                    {
                        foundRoom = true;
                        break;
                    }
                }

                if (!foundRoom)
                {
                    var newAtlas = new DynamicAtlas <Color>(
                        Font.RenderCoordinator, AtlasWidth, AtlasHeight,
                        SurfaceFormat.Color, 4, Font.MipMapping ? PickMipGenerator(Font) : null
                        );
                    Atlases.Add(newAtlas);
                    if (!newAtlas.TryReserve(widthW, heightW, out result))
                    {
                        throw new InvalidOperationException("Character too large for atlas");
                    }
                }

                var pSrc = (byte *)bitmap.Buffer;

                fixed(Color *pPixels = result.Atlas.Pixels)
                {
                    var pDest = (byte *)pPixels;

                    switch (bitmap.PixelMode)
                    {
                    case PixelMode.Gray:
                        var table = Font.GammaTable;

                        for (var y = 0; y < rows; y++)
                        {
                            var rowOffset = result.Atlas.Width * (y + result.Y + Font.GlyphMargin) + (result.X + Font.GlyphMargin);
                            var pDestRow  = pDest + (rowOffset * 4);
                            int yPitch    = y * pitch;

                            for (var x = 0; x < width; x++)
                            {
                                var g = table[pSrc[x + yPitch]];
                                pDestRow[3] = pDestRow[2] = pDestRow[1] = pDestRow[0] = g;
                                pDestRow   += 4;
                            }
                        }
                        break;

                    case PixelMode.Mono:
                        for (var y = 0; y < rows; y++)
                        {
                            var rowOffset = result.Atlas.Width * (y + result.Y + Font.GlyphMargin) + (result.X + Font.GlyphMargin);
                            var pDestRow  = pDest + (rowOffset * 4);
                            int yPitch    = y * pitch;

                            for (int x = 0; x < pitch; x++, pDestRow += (8 * 4))
                            {
                                var bits = pSrc[x + yPitch];

                                for (int i = 0; i < 8; i++)
                                {
                                    int  iy   = 7 - i;
                                    byte g    = ((bits & (1 << iy)) != 0) ? (byte)255 : (byte)0;
                                    var  pElt = pDestRow + (i * 4);
                                    pElt[3] = pElt[2] = pElt[1] = pElt[0] = g;
                                }
                            }
                        }
                        break;

                    default:
                        throw new NotImplementedException("Unsupported pixel mode: " + bitmap.PixelMode);
                    }
                }

                return(result);
            }
Exemplo n.º 19
0
    void UpdateGeometry()
    {
#if UNITY_EDITOR
        if (mUpdateFrame != Time.frameCount || !Application.isPlaying)
#else
        if (mUpdateFrame != Time.frameCount)
#endif
        {
            mUpdateFrame = Time.frameCount;

            if (GetComponent <ParticleSystem>() != null)
            {
                //
                int max_particles = GetComponent <ParticleSystem>().maxParticles;
                m_Particles.Adjust(max_particles);
                bool isBufferChanged = m_Meshes.Adjust(max_particles, true);

                ParticleSystem.Particle[] particles = m_Particles.GetBuffer();
                GetComponent <ParticleSystem>().GetParticles(particles);

                //
                ParticleMesh[] meshes         = m_Meshes.GetBuffer();
                int            mesh_count     = meshes.Length;
                int            particle_count = GetComponent <ParticleSystem>().particleCount;

                if (isBufferChanged)
                {
                    UnityEngine.Profiling.Profiler.BeginSample("FXBillboardParticle 001");
                    for (int i = particle_count; i < mesh_count; i++)
                    {
                        if (meshes[i].m_Renderer != null)
                        {
                            meshes[i].m_Renderer.enabled = false;
                        }
                    }
                    UnityEngine.Profiling.Profiler.EndSample();
                }

                UnityEngine.Profiling.Profiler.BeginSample("FXBillboardParticle 002");
                for (int i = 0; i < particle_count; i++)
                {
                    ParticleSystem.Particle particle = particles[i];

                    float     factor           = (particle.startLifetime - particle.remainingLifetime) / particle.startLifetime;
                    float     size             = particle.GetCurrentSize(GetComponent <ParticleSystem>()) * Mathf.Lerp(FromSize, ToSize, factor);
                    Matrix4x4 transform_matrix = Matrix4x4.TRS(particle.position,
                                                               Quaternion.AngleAxis(particle.rotation, -Camera.main.transform.forward),
                                                               new Vector3(size, size, size));

                    meshes[i].PreUpdate(transform);

                    if (AtlasType == FXAtlasType.Static)
                    {
                        if (meshes[i].m_Renderer != null && m_Atlas != null)
                        {
                            meshes[i].m_Renderer.sharedMaterial = m_Atlas.spriteMaterial;
                            meshes[i].m_Renderer.enabled        = true;
                        }
                    }
                    else if (AtlasType == FXAtlasType.Dynamic)
                    {
                        DynamicAtlasManager dynamic_atlas_manager = DynamicAtlasManager.GetInstance();
                        if (meshes[i].m_Renderer != null && dynamic_atlas_manager != null)
                        {
                            DynamicAtlas dynamic_atlas = dynamic_atlas_manager.GetDynamicAtlas(m_DynamicAtlasType);
                            if (dynamic_atlas != null)
                            {
                                meshes[i].m_Renderer.sharedMaterial = dynamic_atlas.m_Material;
                                meshes[i].m_Renderer.enabled        = true;
                            }
                        }
                    }

                    if (GetComponent <ParticleSystem>().simulationSpace == ParticleSystemSimulationSpace.Local)
                    {
                        meshes[i].m_Vertices[0].Set(-0.5f, -0.5f, 0);
                        meshes[i].m_Vertices[0] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[0]);

                        meshes[i].m_Vertices[1].Set(-0.5f, 0.5f, 0);
                        meshes[i].m_Vertices[1] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[1]);

                        meshes[i].m_Vertices[2].Set(0.5f, 0.5f, 0);
                        meshes[i].m_Vertices[2] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[2]);

                        meshes[i].m_Vertices[3].Set(0.5f, -0.5f, 0);
                        meshes[i].m_Vertices[3] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[3]);
                    }
                    else
                    {
                        Matrix4x4 world2local_matrix = transform.worldToLocalMatrix;

                        meshes[i].m_Vertices[0].Set(-0.5f, -0.5f, 0);
                        meshes[i].m_Vertices[0] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[0]);
                        meshes[i].m_Vertices[0] = world2local_matrix.MultiplyPoint(meshes[i].m_Vertices[0]);

                        meshes[i].m_Vertices[1].Set(-0.5f, 0.5f, 0);
                        meshes[i].m_Vertices[1] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[1]);
                        meshes[i].m_Vertices[1] = world2local_matrix.MultiplyPoint(meshes[i].m_Vertices[1]);

                        meshes[i].m_Vertices[2].Set(0.5f, 0.5f, 0);
                        meshes[i].m_Vertices[2] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[2]);
                        meshes[i].m_Vertices[2] = world2local_matrix.MultiplyPoint(meshes[i].m_Vertices[2]);

                        meshes[i].m_Vertices[3].Set(0.5f, -0.5f, 0);
                        meshes[i].m_Vertices[3] = transform_matrix.MultiplyPoint(meshes[i].m_Vertices[3]);
                        meshes[i].m_Vertices[3] = world2local_matrix.MultiplyPoint(meshes[i].m_Vertices[3]);
                    }

                    //
                    Rect  uv          = m_SpriteUV;
                    float frame       = TileX * TileY * factor;
                    int   frame_index = (int)frame;
                    int   frameX      = frame_index % TileX;
                    int   frameY      = TileY - frame_index / TileY - 1;
                    float stepX       = m_SpriteUV.width / (float)TileX;
                    float stepY       = m_SpriteUV.height / (float)TileY;
                    uv.Set(stepX * frameX + m_SpriteUV.x, stepY * frameY + m_SpriteUV.y, stepX, stepY);

                    meshes[i].m_UVs[0].Set(uv.xMin, uv.yMin);
                    meshes[i].m_UVs[1].Set(uv.xMin, uv.yMax);
                    meshes[i].m_UVs[2].Set(uv.xMax, uv.yMax);
                    meshes[i].m_UVs[3].Set(uv.xMax, uv.yMin);

                    //
                    Color color = particle.GetCurrentColor(GetComponent <ParticleSystem>()) * Color.Lerp(FromColor, ToColor, factor);
                    meshes[i].m_Colors[0] = color;
                    meshes[i].m_Colors[1] = color;
                    meshes[i].m_Colors[2] = color;
                    meshes[i].m_Colors[3] = color;

                    meshes[i].m_Indices[0] = 0;
                    meshes[i].m_Indices[1] = 1;
                    meshes[i].m_Indices[2] = 2;
                    meshes[i].m_Indices[3] = 0;
                    meshes[i].m_Indices[4] = 2;
                    meshes[i].m_Indices[5] = 3;

                    meshes[i].Update();
                }
                UnityEngine.Profiling.Profiler.EndSample();
            }
        }
    }
Exemplo n.º 20
0
    public void OnGUI()
    {
        if (EditorApplication.isPlaying == false)
        {
            _DynamicAtlasWindow.Close();
            return;
        }
        EditorGUILayout.BeginHorizontal();
        EditorGUILayout.BeginVertical();
        EditorGUILayout.LabelField("--------------------------------------------------------------------------------");

        DynamicAtlas dynamicAtlas = DynamicAtlasManager.Instance.GetDynamicAtlas(_mGroup);

        EditorGUILayout.LabelField("图集尺寸:" + dynamicAtlas.atlasWidth + " x " + dynamicAtlas.atlasHeight);
        EditorGUILayout.LabelField("--------------------------------------------------------------------------------");
        EditorGUILayout.EndVertical();
        GUILayout.Space(10);
        EditorGUILayout.BeginVertical();
        isShowFreeAreas = GUILayout.Toggle(isShowFreeAreas, "Show Free Areas", GUILayout.Width(200), GUILayout.Height(20));

        EditorGUILayout.BeginHorizontal();
        if (isShowFreeAreas)
        {
            if (GUILayout.Button("Refresh and Clear Free Area", GUILayout.Width(200), GUILayout.Height(20)))
            {
                isRefreshFreeAreas = true;
                ClearFreeAreas();
            }
        }
        EditorGUILayout.EndHorizontal();
        EditorGUILayout.EndVertical();
        scale = EditorGUILayout.Slider(scale, 0.2f, 1);
        EditorGUILayout.EndHorizontal();


        if (AtlasConfig.kUsingCopyTexture)
        {
            List <Texture2D> tex2DList = dynamicAtlas.tex2DList;
            int count = tex2DList.Count;
            for (int i = 0; i < count; i++)
            {
                Texture2D tex2D = tex2DList[i];
                float     poxX  = (i + 1) * 10 + i * dynamicAtlas.atlasWidth * scale;
                if (isShowFreeAreas)
                {
                    DrawFreeArea(i, dynamicAtlas);
                }
                GUI.DrawTexture(new Rect(poxX, formPosY, dynamicAtlas.atlasWidth * scale, dynamicAtlas.atlasHeight * scale), tex2D);
            }
        }
        else
        {
            List <RenderTexture> renderTexList = dynamicAtlas.renderTexList;
            int count = renderTexList.Count;
            for (int i = 0; i < count; i++)
            {
                float poxX = (i + 1) * 10 + i * dynamicAtlas.atlasWidth * scale;
                if (isShowFreeAreas)
                {
                    DrawFreeArea(i, dynamicAtlas);
                }
                GUI.DrawTexture(new Rect(poxX, formPosY, dynamicAtlas.atlasWidth * scale, dynamicAtlas.atlasHeight * scale), renderTexList[i]);
            }
        }

        if (isShowFreeAreas)
        {
            isRefreshFreeAreas = false;
        }
    }
Exemplo n.º 21
0
            public bool GetGlyph(char ch, out Glyph glyph)
            {
                if (IsDisposed)
                {
                    glyph = default(Glyph);
                    return(false);
                }

                if (Cache.TryGetValue(ch, out glyph))
                {
                    return(true);
                }

                if ((ch == '\r') || (ch == '\n') || (ch == '\0'))
                {
                    return(false);
                }

                Font.Face.SetCharSize(
                    0, _SizePoints,
                    (uint)(BaseDPI * Font.DPIPercent / 100), (uint)(BaseDPI * Font.DPIPercent / 100)
                    );

                uint index;

                if (ch == '\t')
                {
                    index = Font.Face.GetCharIndex(' ');
                }
                else
                {
                    index = Font.Face.GetCharIndex(ch);
                }

                if (index <= 0)
                {
                    return(false);
                }

                var flags = LoadFlags.Color | LoadFlags.Render;

                if (!Font.EnableBitmaps)
                {
                    flags |= LoadFlags.NoBitmap;
                }
                if (!Font.Hinting)
                {
                    flags |= LoadFlags.NoHinting;
                }

                Font.Face.LoadGlyph(
                    index, flags, LoadTarget.Normal
                    );

                var ftgs   = Font.Face.Glyph;
                var scaleX = Font.Face.Size.Metrics.ScaleX;
                var scaleY = Font.Face.Size.Metrics.ScaleY;
                var bitmap = ftgs.Bitmap;

                DynamicAtlas <Color> .Reservation texRegion = default(DynamicAtlas <Color> .Reservation);
                if ((bitmap.Width > 0) && (bitmap.Rows > 0))
                {
                    texRegion = Upload(bitmap);
                }

                var ascender = Font.Face.Size.Metrics.Ascender.ToSingle();
                var metrics  = ftgs.Metrics;
                var advance  = metrics.HorizontalAdvance.ToSingle();

                if (ch == '\t')
                {
                    advance *= Font.TabSize;
                }

                var scaleFactor = 100f / Font.DPIPercent;

                var widthMetric    = metrics.Width.ToSingle();
                var bearingXMetric = metrics.HorizontalBearingX.ToSingle();

                glyph = new SrGlyph {
                    Character        = ch,
                    Width            = widthMetric,
                    LeftSideBearing  = bearingXMetric,
                    RightSideBearing = (
                        advance -
                        widthMetric -
                        metrics.HorizontalBearingX.ToSingle()
                        ),
                    XOffset         = ftgs.BitmapLeft - bearingXMetric - Font.GlyphMargin,
                    YOffset         = -ftgs.BitmapTop + ascender - Font.GlyphMargin,
                    Texture         = texRegion.Texture,
                    BoundsInTexture = texRegion.Rectangle,
                    LineSpacing     = Font.Face.Size.Metrics.Height.ToSingle()
                };

                // Some fonts have weirdly-sized space characters
                if (Char.IsWhiteSpace(ch))
                {
                    glyph.RightSideBearing = (float)Math.Round(glyph.RightSideBearing);
                }

                Cache[ch] = glyph;
                return(true);
            }
Exemplo n.º 22
0
            private unsafe DynamicAtlas <Color> .Reservation Upload(FTBitmap bitmap)
            {
                bool foundRoom = false;

                DynamicAtlas <Color> .Reservation result = default(DynamicAtlas <Color> .Reservation);

                int width = bitmap.Width, rows = bitmap.Rows, pitch = bitmap.Pitch;

                var widthW  = width + (Font.GlyphMargin * 2);
                var heightW = rows + (Font.GlyphMargin * 2);

                foreach (var atlas in Atlases)
                {
                    if (atlas.TryReserve(widthW, heightW, out result))
                    {
                        foundRoom = true;
                        break;
                    }
                }

                var surfaceFormat = Font.sRGB ? Evil.TextureUtils.ColorSrgbEXT : SurfaceFormat.Color;

                if (!foundRoom)
                {
                    var isFirstAtlas = (Atlases.Count == 0) && (_SizePoints < SmallFirstAtlasThreshold);
                    var newAtlas     = new DynamicAtlas <Color>(
                        Font.RenderCoordinator, isFirstAtlas ? FirstAtlasWidth : AtlasWidth, isFirstAtlas ? FirstAtlasHeight : AtlasHeight,
                        surfaceFormat, 4, Font.MipMapping ? PickMipGenerator(Font) : null, tag: $"{Font.Face.FamilyName} {SizePoints}pt"
                        );
                    Atlases.Add(newAtlas);
                    if (!newAtlas.TryReserve(widthW, heightW, out result))
                    {
                        throw new InvalidOperationException("Character too large for atlas");
                    }
                }

                var pSrc = (byte *)bitmap.Buffer;

                fixed(Color *pPixels = result.Atlas.Pixels)
                {
                    var pDest = (byte *)pPixels;

                    switch (bitmap.PixelMode)
                    {
                    case PixelMode.Gray:
                        var table = Font.GammaRamp?.GammaTable;
                        var srgb  = (surfaceFormat != SurfaceFormat.Color);

                        for (var y = 0; y < rows; y++)
                        {
                            var rowOffset = result.Atlas.Width * (y + result.Y + Font.GlyphMargin) + (result.X + Font.GlyphMargin);
                            var pDestRow  = pDest + (rowOffset * 4);
                            int yPitch    = y * pitch;

                            if (table == null)
                            {
                                for (var x = 0; x < width; x++)
                                {
                                    var a = pSrc[x + yPitch];
                                    var g = srgb ? ColorSpace.LinearByteTosRGBByteTable[a] : a;

                                    pDestRow[3] = a;
                                    pDestRow[2] = pDestRow[1] = pDestRow[0] = g;
                                    pDestRow   += 4;
                                }
                            }
                            else
                            {
                                for (var x = 0; x < width; x++)
                                {
                                    var a = table[pSrc[x + yPitch]];
                                    var g = srgb ? ColorSpace.LinearByteTosRGBByteTable[a] : a;

                                    pDestRow[3] = a;
                                    pDestRow[2] = pDestRow[1] = pDestRow[0] = g;
                                    pDestRow   += 4;
                                }
                            }
                        }
                        break;

                    case PixelMode.Mono:
                        for (var y = 0; y < rows; y++)
                        {
                            var rowOffset = result.Atlas.Width * (y + result.Y + Font.GlyphMargin) + (result.X + Font.GlyphMargin);
                            var pDestRow  = pDest + (rowOffset * 4);
                            int yPitch    = y * pitch;

                            for (int x = 0; x < pitch; x++, pDestRow += (8 * 4))
                            {
                                var bits = pSrc[x + yPitch];

                                for (int i = 0; i < 8; i++)
                                {
                                    int  iy   = 7 - i;
                                    byte g    = ((bits & (1 << iy)) != 0) ? (byte)255 : (byte)0;
                                    var  pElt = pDestRow + (i * 4);
                                    pElt[3] = pElt[2] = pElt[1] = pElt[0] = g;
                                }
                            }
                        }
                        break;

                    default:
                        throw new NotImplementedException("Unsupported pixel mode: " + bitmap.PixelMode);
                    }
                }

                result.Invalidate();
                return(result);
            }
Exemplo n.º 23
0
            private bool PopulateGlyphCache(uint ch, out Glyph glyph, Color?defaultColor)
            {
                var resolution = (uint)(BaseDPI * Font.DPIPercent / 100);
                var size       = Font.GetFTSize(_SizePoints, resolution);

                uint index;

                if (ch == '\t')
                {
                    index = Font.Face.GetCharIndex(' ');
                }
                else
                {
                    index = Font.Face.GetCharIndex(ch);
                }

                if (index <= 0)
                {
                    glyph = default(Glyph);
                    return(false);
                }

                var flags = LoadFlags.Render;

                if (!Font.EnableBitmaps)
                {
                    flags |= LoadFlags.NoBitmap;
                }
                if (!Font.Hinting)
                {
                    flags |= LoadFlags.NoHinting;
                }
                if (Font.Monochrome)
                {
                    flags |= LoadFlags.Monochrome;
                }
                else
                {
                    flags |= LoadFlags.Color;
                }

                Font.Face.LoadGlyph(
                    index, flags, Font.Monochrome ? LoadTarget.Mono : LoadTarget.Normal
                    );

                var sizeMetrics = size.Metrics;

                var ftgs   = Font.Face.Glyph;
                var scaleX = sizeMetrics.ScaleX;
                var scaleY = sizeMetrics.ScaleY;
                var bitmap = ftgs.Bitmap;

                DynamicAtlas <Color> .Reservation texRegion = default(DynamicAtlas <Color> .Reservation);
                if ((bitmap.Width > 0) && (bitmap.Rows > 0))
                {
                    texRegion = Upload(bitmap);
                }

                var ascender     = sizeMetrics.Ascender.ToSingle();
                var glyphMetrics = ftgs.Metrics;
                var advance      = glyphMetrics.HorizontalAdvance.ToSingle();

                if (ch == '\t')
                {
                    advance *= Font.TabSize;
                }

                var scaleFactor = 100f / Font.DPIPercent;

                var widthMetric    = glyphMetrics.Width.ToSingle();
                var bearingXMetric = glyphMetrics.HorizontalBearingX.ToSingle();

                var rect = texRegion.Rectangle;

                glyph = new SrGlyph {
                    Character        = ch,
                    Width            = widthMetric,
                    LeftSideBearing  = bearingXMetric,
                    RightSideBearing = (
                        advance -
                        widthMetric -
                        glyphMetrics.HorizontalBearingX.ToSingle()
                        ),
                    XOffset       = ftgs.BitmapLeft - bearingXMetric - Font.GlyphMargin,
                    YOffset       = -ftgs.BitmapTop + ascender - Font.GlyphMargin + Font.VerticalOffset + VerticalOffset,
                    RectInTexture = rect,
                    // FIXME: This will become invalid if the extra spacing changes
                    // FIXME: Scale the spacing appropriately based on ratios
                    LineSpacing  = sizeMetrics.Height.ToSingle() + ExtraLineSpacing,
                    DefaultColor = defaultColor,
                    Baseline     = sizeMetrics.Ascender.ToSingle()
                };

                if (texRegion.Atlas != null)
                {
                    glyph.Texture         = texRegion.Atlas;
                    glyph.BoundsInTexture = texRegion.Atlas.BoundsFromRectangle(in rect);
                }

                // HACK
                if (ch <= 0xCFFF)
                {
                    // Some fonts have weirdly-sized space characters
                    if (char.IsWhiteSpace((char)ch))
                    {
                        glyph.RightSideBearing = (float)Math.Round(glyph.RightSideBearing);
                    }
                }

                if (ch < LowCacheSize)
                {
                    LowCache[ch] = glyph;
                }
                Cache[ch] = glyph;

                return(true);
            }