SquirrelJME/SquirrelJME

View on GitHub
modules/midp-lcdui/src/main/java/cc/squirreljme/runtime/lcdui/gfx/EnforcedDrawingAreaGraphics.java

Summary

Maintainability
A
0 mins
Test Coverage
// -*- Mode: Java; indent-tabs-mode: t; tab-width: 4 -*-
// ---------------------------------------------------------------------------
// SquirrelJME
//     Copyright (C) Stephanie Gawroriski <xer@multiphasicapps.net>
// ---------------------------------------------------------------------------
// SquirrelJME is under the Mozilla Public License Version 2.0.
// See license.mkd for licensing and copyright information.
// ---------------------------------------------------------------------------

package cc.squirreljme.runtime.lcdui.gfx;

import javax.microedition.lcdui.Font;
import javax.microedition.lcdui.Graphics;
import javax.microedition.lcdui.Image;
import javax.microedition.lcdui.Text;

/**
 * This is a graphics which enforces a translation and maximum drawing bounds
 * to a target graphics object.
 *
 * @since 2018/12/02
 */
public final class EnforcedDrawingAreaGraphics
    extends Graphics
{
    /** The graphics to draw into. */
    protected final Graphics graphics;
    
    /** The X translation. */
    protected final int x;
    
    /** The Y translation. */
    protected final int y;
    
    /** The width. */
    protected final int width;
    
    /** The height. */
    protected final int height;
    
    /** Draw X actual. */
    private int _dx;
    
    /** Draw Y actual. */
    private int _dy;
    
    /** Current X translation. */
    private int _transx;
    
    /** Current Y translation. */
    private int _transy;
    
    /** Clip X. */
    private int _clipx;
    
    /** Clip Y. */
    private int _clipy;
    
    /** Clip Width. */
    private int _clipw;
    
    /** Clip Height. */
    private int _cliph;
    
    /** Has this been initialized? */
    private boolean _beeninit;
    
    /**
     * Initializes the enforced drawing area.
     *
     * @param __g The graphics to draw to.
     * @param __x The X translation.
     * @param __y The Y translation.
     * @param __w The width.
     * @param __h The height.
     * @throws NullPointerException On null arguments.
     * @since 2018/12/02
     */
    public EnforcedDrawingAreaGraphics(Graphics __g, int __x, int __y,
        int __w, int __h)
        throws NullPointerException
    {
        if (__g == null)
            throw new NullPointerException("NARG");
        
        // Clip in
        if (__x < 0)
            __x = 0;
        if (__y < 0)
            __y = 0;
        
        this.graphics = __g;
        this.x = __x;
        this.y = __y;
        this.width = __w;
        this.height = __h;
        
        // Initialize our translation with our offsets
        this._transx = 0;
        this._transy = 0;
        this._dx = __x;
        this._dy = __y;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void clipRect(int __x, int __y, int __w, int __h)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        // Translate
        __x += this._transx;
        __y += this._transy;
        
        // Our viewing area
        int vw = this.width,
            vh = this.height;
        
        // Calculate logical viewing area coordinates
        int lsx = __x,
            lsy = __y,
            lex = lsx + __w,
            ley = lsy + __h;
        
        // Get the original clipping bounds
        int csx = this._clipx,
            csy = this._clipy,
            cex = csx + this._clipw,
            cey = csy + this._cliph;
        
        // Clip coordinates via the old bounds
        if (lsx < csx)
            lsx = csx;
        if (lsy < csy)
            lsy = csy;
        if (lex > cex)
            lex = cex;
        if (ley > cey)
            ley = cey;
        
        // Determine logical clipping coordinates
        int clipx = lsx,
            clipy = lsy,
            clipw = lex - lsx,
            cliph = ley - lsy;
        
        // Store these for later clipRect() calls
        this._clipx = clipx;
        this._clipy = clipy;
        this._clipw = clipw;
        this._cliph = cliph;
        
        // Determine physical start coordinates
        int px = this.x + clipx,
            py = this.y + clipy;
        
        // Set the clipping area
        Graphics graphics = this.graphics;
        graphics.setClip(
            px - graphics.getTranslateX(), py - graphics.getTranslateY(),
            clipw, cliph);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void copyArea(int __sx, int __sy, int __w, int __h,
        int __dx, int __dy, int __anchor)
        throws IllegalArgumentException, IllegalStateException
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.copyArea(this._dx + __sx, this._dy + __sy,
            __w, __h, this._dx + __dx, this._dy + __dy, __anchor);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawArc(int __x, int __y, int __w, int __h, int __startAngle,
        int __arcAngle)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawArc(this._dx + __x, this._dy + __y,
            __w, __h, __startAngle, __arcAngle);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawARGB16(short[] __data, int __off, int __scanlen,
        int __x, int __y, int __w, int __h)
        throws NullPointerException
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawARGB16(__data, __off, __scanlen,
            this._dx + __x, this._dy + __y, __w, __h);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawChar(char __s, int __x, int __y, int __anchor)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawChar(__s, this._dx + __x, this._dy + __y,
            __anchor);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawChars(char[] __s, int __o, int __l, int __x,
        int __y, int __anchor)
        throws NullPointerException
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawChars(__s, __o, __l,
            this._dx + __x, this._dy + __y,
            __anchor);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawImage(Image __i, int __x, int __y, int __anchor)
        throws IllegalArgumentException, NullPointerException
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawImage(__i, this._dx + __x, this._dy + __y,
            __anchor);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawLine(int __x1, int __y1, int __x2, int __y2)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawLine(this._dx + __x1, this._dy + __y1,
            this._dx + __x2, this._dy + __y2);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawRGB(int[] __data, int __off, int __scanlen,
        int __x, int __y, int __w, int __h, boolean __alpha)
        throws NullPointerException
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawRGB(__data, __off, __scanlen,
            this._dx + __x, this._dy + __y, __w, __h, __alpha);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawRGB16(short[] __data, int __off, int __scanlen,
        int __x, int __y, int __w, int __h)
        throws NullPointerException
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawRGB16(__data, __off, __scanlen,
            this._dx + __x, this._dy + __y, __w, __h);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawRect(int __x, int __y, int __w, int __h)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawRect(this._dx + __x, this._dy + __y,
            __w, __h);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawRegion(Image __src, int __xsrc, int __ysrc,
        int __wsrc, int __hsrc, int __trans, int __xdest, int __ydest,
        int __anch)
        throws IllegalArgumentException, NullPointerException
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawRegion(__src, __xsrc, __ysrc, __wsrc, __hsrc,
            __trans, this._dx + __xdest, this._dy + __ydest, __anch);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawRegion(Image __src, int __xsrc, int __ysrc,
        int __wsrc, int __hsrc, int __trans, int __xdest, int __ydest,
        int __anch, int __wdest, int __hdest)
        throws IllegalArgumentException, NullPointerException
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawRegion(__src, __xsrc, __ysrc, __wsrc, __hsrc,
            __trans, this._dx + __xdest, this._dy + __ydest, __anch,
            __wdest, __hdest);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawRoundRect(int __x, int __y, int __w, int __h,
        int __aw, int __ah)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawRoundRect(this._dx + __x, this._dy + __y,
            __w, __h, __aw, __ah);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawString(String __s, int __x, int __y,
        int __anchor)
        throws NullPointerException
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawString(__s, this._dx + __x, this._dy + __y,
            __anchor);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawSubstring(String __s, int __o, int __l, int __x,
        int __y, int __anchor)
        throws NullPointerException, StringIndexOutOfBoundsException
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawSubstring(__s, __o, __l,
            this._dx + __x, this._dy + __y, __anchor);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void drawText(Text __t, int __x, int __y)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.drawText(__t, this._dx + __x, this._dy + __y);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void fillArc(int __x, int __y, int __w, int __h, int __startAngle,
        int __arcAngle)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.fillArc(this._dx + __x, this._dy + __y,
            __w, __h, __startAngle, __arcAngle);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void fillRect(int __x, int __y, int __w, int __h)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.fillRect(this._dx + __x, this._dy + __y,
            __w, __h);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void fillRoundRect(int __x, int __y, int __w, int __h,
        int __aw, int __ah)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        this.graphics.fillRoundRect(this._dx + __x, this._dy + __y,
            __w, __h, __aw, __ah);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void fillTriangle(int __x1, int __y1, int __x2, int __y2,
        int __x3, int __y3)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        int x = this._transx, y = this._transy;
        this.graphics.fillTriangle(
            x + __x1, y + __y1,
            x + __x2, y + __y2,
            x + __x3, y + __y3);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getAlpha()
    {
        return this.graphics.getAlpha();
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getAlphaColor()
    {
        return this.graphics.getAlphaColor();
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getBlendingMode()
    {
        return this.graphics.getBlendingMode();
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getBlueComponent()
    {
        return this.graphics.getBlueComponent();
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getClipHeight()
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        return this._cliph;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getClipWidth()
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        return this._clipw;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getClipX()
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        return this._clipx;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getClipY()
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        return this._clipy;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getColor()
    {
        return this.graphics.getColor();
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getDisplayColor(int __rgb)
    {
        return this.graphics.getDisplayColor(__rgb);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final Font getFont()
    {
        return this.graphics.getFont();
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getGrayScale()
    {
        return this.graphics.getGrayScale();
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getGreenComponent()
    {
        return this.graphics.getGreenComponent();
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getRedComponent()
    {
        return this.graphics.getRedComponent();
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getStrokeStyle()
    {
        return this.graphics.getStrokeStyle();
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getTranslateX()
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        return this._transx;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final int getTranslateY()
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        return this._transy;
    }
    
    /**
     * Reclips the clipping area and sets up translation.
     *
     * @since 2018/12/02
     */
    public final void initialize()
    {
        // Only initialize once
        if (this._beeninit)
            return;
        
        Graphics g = this.graphics;
        
        // Our viewing area
        int x = this.x,
            y = this.y,
            width = this.width,
            height = this.height;
        
        // Set new clipping area
        g.setClip(x, y, width, height);
        this._clipx = 0;
        this._clipy = 0;
        this._clipw = width;
        this._cliph = height;
        
        // Reset translation and draw position
        this._dx = x;
        this._dy = y;
        this._transx = 0;
        this._transy = 0;
        
        // Set as initialized
        this._beeninit = true;
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void setAlpha(int __a)
        throws IllegalArgumentException
    {
        this.graphics.setAlpha(__a);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void setAlphaColor(int __argb)
    {
        this.graphics.setAlphaColor(__argb);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void setAlphaColor(int __a, int __r, int __g, int __b)
        throws IllegalArgumentException
    {
        this.graphics.setAlphaColor(__a, __r, __g, __b);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void setBlendingMode(int __m)
        throws IllegalArgumentException
    {
        this.graphics.setBlendingMode(__m);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void setClip(int __x, int __y, int __w, int __h)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        // Translate
        __x += this._transx;
        __y += this._transy;
        
        // Our viewing area
        int vw = this.width,
            vh = this.height;
        
        // Calculate logical viewing area coordinates
        int lsx = __x,
            lsy = __y,
            lex = lsx + __w,
            ley = lsy + __h;
        
        // Clip these coordinates into the logical viewing space
        if (lsx < 0)
            lsx = 0;
        if (lsy < 0)
            lsy = 0;
        if (lex > vw)
            lex = vw;
        if (ley > vh)
            ley = vh;
        
        // Determine logical clipping coordinates
        int clipx = lsx,
            clipy = lsy,
            clipw = lex - lsx,
            cliph = ley - lsy;
        
        // Store these for later clipRect() calls
        this._clipx = clipx;
        this._clipy = clipy;
        this._clipw = clipw;
        this._cliph = cliph;
        
        // Determine physical start coordinates
        int px = this.x + clipx,
            py = this.y + clipy;
        
        // Set the clipping area
        Graphics graphics = this.graphics;
        graphics.setClip(
            px - graphics.getTranslateX(), py - graphics.getTranslateY(),
            clipw, cliph);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void setColor(int __rgb)
    {
        this.graphics.setColor(__rgb);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void setColor(int __r, int __g, int __b)
        throws IllegalArgumentException
    {
        this.graphics.setColor(__r, __g, __b);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void setFont(Font __font)
    {
        this.graphics.setFont(__font);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void setGrayScale(int __v)
    {
        this.graphics.setGrayScale(__v);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     * @param __s
     */
    @Override
    public final void setStrokeStyle(int __s)
        throws IllegalArgumentException
    {
        this.graphics.setStrokeStyle(__s);
    }
    
    /**
     * {@inheritDoc}
     * @since 2018/12/02
     */
    @Override
    public final void translate(int __x, int __y)
    {
        // Initialize?
        if (!this._beeninit)
            this.initialize();
        
        // Add our translation, we manage it ourselves
        int transx = this._transx + __x,
            transy = this._transy + __y;
        
        // Set our own translation but not to the target
        this._transx = transx;
        this._transy = transy;
        
        // Our draw offset is our offset and our own translation
        this._dx = this.x + transx;
        this._dy = this.y + transy;
    }
}