Package tripleplay.util

Source Code of tripleplay.util.EffectRenderer$Gradient

//
// Triple Play - utilities for use in PlayN-based games
// Copyright (c) 2011-2014, Three Rings Design, Inc. - All rights reserved.
// http://github.com/threerings/tripleplay/blob/master/LICENSE

package tripleplay.util;

import pythagoras.f.IRectangle;

import playn.core.Canvas;
import playn.core.PlayN;
import playn.core.TextLayout;

import tripleplay.ui.Style;

/**
* Handles the rendering of text with a particular effect (shadow, outline, etc.).
*/
public abstract class EffectRenderer
{
    /** An "effect" that just renders the text normally. */
    public static final EffectRenderer NONE = new EffectRenderer() {
        @Override public void render (Canvas canvas, TextLayout layout, int textColor,
            boolean underlined, float x, float y) {
            canvas.save();
            canvas.setFillColor(textColor);
            if (underlined) {
                IRectangle bounds = layout.bounds();
                float sx = x + bounds.x(), sy = y + bounds.y() + bounds.height() + 1;
                canvas.fillRect(sx, sy, bounds.width(), 1);
            }
            canvas.fillText(layout, x, y);
            canvas.restore();
        }
    };

    public float adjustWidth (float width) { return width; }
    public float adjustHeight (float height) { return height; }
    public float offsetX () { return 0; }
    public float offsetY () { return 0; }

    public abstract void render (Canvas canvas, TextLayout layout, int textColor,
        boolean underlined, float x, float y);

    public static class PixelOutline extends EffectRenderer {
        public final int outlineColor;

        public PixelOutline (int outlineColor) {
            this.outlineColor = outlineColor;
        }

        @Override public float adjustWidth (float width) { return width + 2; }
        @Override public float adjustHeight (float height) { return height + 2; }

        @Override public void render (Canvas canvas, TextLayout text, int textColor,
            boolean underlined, float x, float y) {
            canvas.save();
            if (underlined) {
                IRectangle bounds = text.bounds();
                float sx = x + bounds.x() + 1, sy = y + bounds.y() + bounds.height() + 2;
                canvas.setFillColor(outlineColor).fillRect(sx-1, sy-1, bounds.width()+3, 3);
                canvas.setFillColor(textColor).fillRect(sx, sy, bounds.width(), 1);
            }
            canvas.setFillColor(outlineColor);
            canvas.fillText(text, x+0, y+0);
            canvas.fillText(text, x+0, y+1);
            canvas.fillText(text, x+0, y+2);
            canvas.fillText(text, x+1, y+0);
            canvas.fillText(text, x+1, y+2);
            canvas.fillText(text, x+2, y+0);
            canvas.fillText(text, x+2, y+1);
            canvas.fillText(text, x+2, y+2);
            canvas.setFillColor(textColor);
            canvas.fillText(text, x+1, y+1);
            canvas.restore();
        }

        @Override public boolean equals (Object obj) {
            if (!(obj instanceof PixelOutline)) return false;
            return outlineColor == ((PixelOutline)obj).outlineColor;
        }

        @Override public int hashCode () {
            return outlineColor;
        }
    }

    public static class VectorOutline extends EffectRenderer {
        public final int outlineColor;
        public final float outlineWidth;
        public final Canvas.LineCap outlineCap;
        public final Canvas.LineJoin outlineJoin;

        public VectorOutline (int outlineColor, float outlineWidth) {
            this(outlineColor, outlineWidth, Canvas.LineCap.ROUND, Canvas.LineJoin.ROUND);
        }

        public VectorOutline (int outlineColor, float outlineWidth,
                              Canvas.LineCap cap, Canvas.LineJoin join) {
            this.outlineColor = outlineColor;
            this.outlineWidth = outlineWidth;
            this.outlineCap = cap;
            this.outlineJoin = join;
        }

        @Override public float adjustWidth (float width) { return width + 2*outlineWidth; }
        @Override public float adjustHeight (float height) { return height + 2*outlineWidth; }

        @Override public void render (Canvas canvas, TextLayout text, int textColor,
            boolean underlined, float x, float y) {
            canvas.save();
            canvas.setStrokeColor(outlineColor);
            canvas.setStrokeWidth(outlineWidth*2);
            canvas.setLineCap(outlineCap);
            canvas.setLineJoin(outlineJoin);
            canvas.strokeText(text, x+outlineWidth, y+outlineWidth);
            canvas.setFillColor(textColor);
            canvas.fillText(text, x+outlineWidth, y+outlineWidth);
            if (underlined) {
                IRectangle bounds = text.bounds();
                float sx = x + bounds.x() + outlineWidth;
                float sy = y + bounds.y() + bounds.height() + outlineWidth + 1;
                canvas.fillRect(sx, sy, bounds.width(), 1);
            }
            canvas.restore();
        }

        @Override public boolean equals (Object obj) {
            if (!(obj instanceof VectorOutline)) return false;
            VectorOutline that = (VectorOutline)obj;
            return outlineColor == that.outlineColor && outlineWidth == that.outlineWidth &&
                    outlineCap == that.outlineCap && outlineJoin == that.outlineJoin;
        }

        @Override public int hashCode () {
            return outlineColor ^ (int)outlineWidth ^ outlineCap.hashCode() ^
                    outlineJoin.hashCode();
        }
    }

    public static class Shadow extends EffectRenderer {
        public final int shadowColor;
        public final float shadowX, shadowY;

        public Shadow (int shadowColor, float shadowX, float shadowY) {
            this.shadowColor = shadowColor;
            this.shadowX = shadowX;
            this.shadowY = shadowY;
        }

        @Override public float adjustWidth (float width) { return width + Math.abs(shadowX); }
        @Override public float adjustHeight (float height) { return height + Math.abs(shadowY); }

        @Override public void render (Canvas canvas, TextLayout text, int textColor,
            boolean underlined, float x, float y) {
            float tx = (shadowX < 0) ? -shadowX : 0, ty = (shadowY < 0) ? -shadowY : 0;
            float sx = (shadowX < 0) ? 0 : shadowX, sy = (shadowY < 0) ? 0 : shadowY;
            canvas.save();
            if (underlined) {
                IRectangle bounds = text.bounds();
                canvas.setFillColor(shadowColor).fillRect(
                    sx+bounds.x()+x, sy+bounds.y()+bounds.height()+1, bounds.width()+1, 1);
                canvas.setFillColor(textColor).fillRect(
                    tx+bounds.x()+x, ty+bounds.y()+bounds.height()+1, bounds.width()+1, 1);
            }
            canvas.setFillColor(shadowColor);
            canvas.fillText(text, x+sx, y+sy);
            canvas.setFillColor(textColor);
            canvas.fillText(text, x+tx, y+ty);
            canvas.restore();
        }

        @Override public boolean equals (Object obj) {
            if (!(obj instanceof Shadow)) return false;
            Shadow that = (Shadow)obj;
            return shadowColor == that.shadowColor &&
                    shadowX == that.shadowX && shadowY == that.shadowY;
        }

        @Override public int hashCode () {
            return shadowColor ^ (int)shadowX ^ (int)shadowY;
        }
    }

    public static class Gradient extends EffectRenderer {
        public final int gradientColor;
        public final Style.GradientType gradientType;

        public Gradient (int gradientColor, Style.GradientType gradientType) {
            this.gradientColor = gradientColor;
            this.gradientType = gradientType;
        }

        @Override public void render (Canvas canvas, TextLayout text, int textColor,
            boolean underlined, float x, float y) {

            int colors[] = null;
            float positions[] = null;

            switch (gradientType) {
            case BOTTOM:
                colors = new int[] {textColor, gradientColor};
                positions = new float[] {0, 1};
                break;
            case TOP:
                colors = new int[] {gradientColor, textColor};
                positions = new float[] {0, 1};
                break;
            case CENTER:
                colors = new int[] {textColor, gradientColor, textColor};
                positions = new float[] {0, 0.5f, 1};
                break;
            }

            // The compiler should've warned if new values showed up in the enum, but sanity check
            assert colors != null : "Unhandled gradient type: " + gradientType;

            canvas.save();

            canvas.setFillGradient(
                PlayN.graphics().createLinearGradient(0, 0, 0, text.height(), colors, positions));
            canvas.fillText(text, x, y);

            if (underlined) {
                IRectangle bounds = text.bounds();
                float sx = x + bounds.x(), sy = y + bounds.y() + bounds.height() + 1;
                canvas.fillRect(sx, sy, bounds.width(), 1);
            }

            canvas.restore();
        }

        @Override public boolean equals (Object obj) {
            if (!(obj instanceof Gradient)) return false;
            Gradient that = (Gradient)obj;
            return gradientColor == that.gradientColor && gradientType == that.gradientType;
        }

        @Override public int hashCode () {
            return (83 * gradientColor) ^ (113 * gradientType.ordinal());
        }
    }
}
TOP

Related Classes of tripleplay.util.EffectRenderer$Gradient

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.