Beispiel #1
0
    /// <summary>
    /// Add a dark shadowy outline around the sprite, giving it some visual depth.
    /// </summary>

    void AddOutline(UISpriteData sprite)
    {
        var sprites = new List <UIAtlasMaker.SpriteEntry>();

        UIAtlasMaker.ExtractSprites(mAtlas, sprites);
        UIAtlasMaker.SpriteEntry se = null;

        for (int i = 0; i < sprites.Count; ++i)
        {
            if (sprites[i].name == sprite.name)
            {
                se = sprites[i];
                break;
            }
        }

        if (se != null)
        {
            int w1 = se.tex.width;
            int h1 = se.tex.height;

            int w2 = w1 + 2;
            int h2 = h1 + 2;

            var c2 = NGUIEditorTools.AddBorder(se.tex.GetPixels32(), w1, h1);
            NGUIEditorTools.AddDepth(c2, w2, h2, NGUISettings.backgroundColor);

            if (se.temporaryTexture)
            {
                DestroyImmediate(se.tex);
            }

            if ((se.borderLeft | se.borderRight | se.borderBottom | se.borderTop) != 0)
            {
                ++se.borderLeft;
                ++se.borderRight;
                ++se.borderTop;
                ++se.borderBottom;
            }

            se.tex      = new Texture2D(w2, h2);
            se.tex.name = sprite.name;
            se.tex.SetPixels32(c2);
            se.tex.Apply();
            se.temporaryTexture = true;

            var before = NGUISettings.atlasTrimming;
            NGUISettings.atlasTrimming = false;
            UIAtlasMaker.UpdateAtlas(mAtlas, sprites);
            NGUISettings.atlasTrimming = before;

            DestroyImmediate(se.tex);
            se.tex = null;
        }
    }
Beispiel #2
0
    /// <summary>
    /// Apply an effect to the font.
    /// </summary>

    void ApplyEffect(Effect effect, Color foreground, Color background)
    {
        BMFont bf      = mFont.bmFont;
        int    offsetX = 0;
        int    offsetY = 0;

        if (mFont.atlas != null)
        {
            UISpriteData sd = mFont.atlas.GetSprite(bf.spriteName);
            if (sd == null)
            {
                return;
            }
            offsetX = sd.x;
            offsetY = sd.y + mFont.texHeight - sd.paddingTop;
        }

        string    path  = AssetDatabase.GetAssetPath(mFont.texture);
        Texture2D bfTex = NGUIEditorTools.ImportTexture(path, true, true, false);

        Color32[] atlas = bfTex.GetPixels32();

        // First we need to extract textures for all the glyphs, making them bigger in the process
        List <BMGlyph>   glyphs        = bf.glyphs;
        List <Texture2D> glyphTextures = new List <Texture2D>(glyphs.Count);

        for (int i = 0, imax = glyphs.Count; i < imax; ++i)
        {
            BMGlyph glyph = glyphs[i];
            if (glyph.width < 1 || glyph.height < 1)
            {
                continue;
            }

            int width  = glyph.width;
            int height = glyph.height;

            if (effect == Effect.Outline || effect == Effect.Shadow || effect == Effect.Border)
            {
                width  += 2;
                height += 2;
                --glyph.offsetX;
                --glyph.offsetY;
            }
            else if (effect == Effect.Crop && width > 2 && height > 2)
            {
                width  -= 2;
                height -= 2;
                ++glyph.offsetX;
                ++glyph.offsetY;
            }

            int       size   = width * height;
            Color32[] colors = new Color32[size];
            Color32   clear  = background;
            clear.a = 0;
            for (int b = 0; b < size; ++b)
            {
                colors[b] = clear;
            }

            if (effect == Effect.Crop)
            {
                for (int y = 0; y < height; ++y)
                {
                    for (int x = 0; x < width; ++x)
                    {
                        int fx = x + glyph.x + offsetX + 1;
                        int fy = y + (mFont.texHeight - glyph.y - glyph.height) + 1;
                        if (mFont.atlas != null)
                        {
                            fy += bfTex.height - offsetY;
                        }
                        colors[x + y * width] = atlas[fx + fy * bfTex.width];
                    }
                }
            }
            else
            {
                for (int y = 0; y < glyph.height; ++y)
                {
                    for (int x = 0; x < glyph.width; ++x)
                    {
                        int fx = x + glyph.x + offsetX;
                        int fy = y + (mFont.texHeight - glyph.y - glyph.height);
                        if (mFont.atlas != null)
                        {
                            fy += bfTex.height - offsetY;
                        }

                        Color c = atlas[fx + fy * bfTex.width];

                        if (effect == Effect.Border)
                        {
                            colors[x + 1 + (y + 1) * width] = c;
                        }
                        else
                        {
                            if (effect == Effect.AlphaCurve)
                            {
                                c.a = Mathf.Clamp01(mCurve.Evaluate(c.a));
                            }

                            Color bg = background;
                            bg.a = (effect == Effect.BackgroundCurve) ? Mathf.Clamp01(mCurve.Evaluate(c.a)) : c.a;

                            Color fg = foreground;
                            fg.a = (effect == Effect.ForegroundCurve) ? Mathf.Clamp01(mCurve.Evaluate(c.a)) : c.a;

                            if (effect == Effect.Outline || effect == Effect.Shadow)
                            {
                                colors[x + 1 + (y + 1) * width] = Color.Lerp(bg, c, c.a);
                            }
                            else
                            {
                                colors[x + y * width] = Color.Lerp(bg, fg, c.a);
                            }
                        }
                    }
                }

                // Apply the appropriate affect
                if (effect == Effect.Shadow)
                {
                    NGUIEditorTools.AddShadow(colors, width, height, NGUISettings.backgroundColor);
                }
                else if (effect == Effect.Outline)
                {
                    NGUIEditorTools.AddDepth(colors, width, height, NGUISettings.backgroundColor);
                }
            }

            Texture2D tex = new Texture2D(width, height, TextureFormat.ARGB32, false);
            tex.SetPixels32(colors);
            tex.Apply();
            glyphTextures.Add(tex);
        }

        // Pack all glyphs into a new texture
        Texture2D final = new Texture2D(bfTex.width, bfTex.height, TextureFormat.ARGB32, false);

        Rect[] rects = final.PackTextures(glyphTextures.ToArray(), 1);
        final.Apply();

        // Make RGB channel use the background color (Unity makes it black by default)
        Color32[] fcs = final.GetPixels32();
        Color32   bc  = background;

        for (int i = 0, imax = fcs.Length; i < imax; ++i)
        {
            if (fcs[i].a == 0)
            {
                fcs[i].r = bc.r;
                fcs[i].g = bc.g;
                fcs[i].b = bc.b;
            }
        }

        final.SetPixels32(fcs);
        final.Apply();

        // Update the glyph rectangles
        int index = 0;
        int tw    = final.width;
        int th    = final.height;

        for (int i = 0, imax = glyphs.Count; i < imax; ++i)
        {
            BMGlyph glyph = glyphs[i];
            if (glyph.width < 1 || glyph.height < 1)
            {
                continue;
            }

            Rect rect = rects[index++];
            glyph.x      = Mathf.RoundToInt(rect.x * tw);
            glyph.y      = Mathf.RoundToInt(rect.y * th);
            glyph.width  = Mathf.RoundToInt(rect.width * tw);
            glyph.height = Mathf.RoundToInt(rect.height * th);
            glyph.y      = th - glyph.y - glyph.height;
        }

        // Update the font's texture dimensions
        mFont.texWidth  = final.width;
        mFont.texHeight = final.height;

        if (mFont.atlas == null)
        {
            // Save the final texture
            byte[] bytes = final.EncodeToPNG();
            NGUITools.DestroyImmediate(final);
            System.IO.File.WriteAllBytes(path, bytes);
            AssetDatabase.Refresh(ImportAssetOptions.ForceSynchronousImport);
        }
        else
        {
            // Update the atlas
            final.name = mFont.spriteName;
            bool val = NGUISettings.atlasTrimming;
            NGUISettings.atlasTrimming = false;
            UIAtlasMaker.AddOrUpdate(mFont.atlas, final);
            NGUISettings.atlasTrimming = val;
            NGUITools.DestroyImmediate(final);
        }

        // Cleanup
        for (int i = 0; i < glyphTextures.Count; ++i)
        {
            NGUITools.DestroyImmediate(glyphTextures[i]);
        }

        // Refresh all labels
        mFont.MarkAsChanged();
    }