abstractregionpainter.java

来自「Mobile 应用程序使用 Java Micro Edition (Java M」· Java 代码 · 共 718 行 · 第 1/3 页

JAVA
718
字号
         * @param insets The stretching insets. May be null. If null, then assumed to be 0, 0, 0, 0.         * @param canvasSize The size of the canvas used when encoding the various x/y values. May be null.         *                   If null, then it is assumed that there are no encoded values, and any calls         *                   to one of the "decode" methods will return the passed in value.         * @param inverted Whether to "invert" the meaning of the 9-square grid and stretching insets         */        public PaintContext(Insets insets, Dimension canvasSize, boolean inverted) {            this(insets, canvasSize, inverted, null, 1, 1);        }        /**         * Creates a new PaintContext.         *         * @param insets The stretching insets. May be null. If null, then assumed to be 0, 0, 0, 0.         * @param canvasSize The size of the canvas used when encoding the various x/y values. May be null.         *                   If null, then it is assumed that there are no encoded values, and any calls         *                   to one of the "decode" methods will return the passed in value.         * @param inverted Whether to "invert" the meaning of the 9-square grid and stretching insets         * @param cacheMode A hint as to which caching mode to use. If null, then set to no caching.         * @param maxH The maximium scale in the horizontal direction to use before punting and redrawing from scratch.         *             For example, if maxH is 2, then we will attempt to scale any cached images up to 2x the canvas         *             width before redrawing from scratch. Reasonable maxH values may improve painting performance.         *             If set too high, then you may get poor looking graphics at higher zoom levels. Must be >= 1.         * @param maxV The maximium scale in the vertical direction to use before punting and redrawing from scratch.         *             For example, if maxV is 2, then we will attempt to scale any cached images up to 2x the canvas         *             height before redrawing from scratch. Reasonable maxV values may improve painting performance.         *             If set too high, then you may get poor looking graphics at higher zoom levels. Must be >= 1.         */        public PaintContext(Insets insets, Dimension canvasSize, boolean inverted,                            CacheMode cacheMode, double maxH, double maxV) {            if (maxH < 1 || maxH < 1) {                throw new IllegalArgumentException("Both maxH and maxV must be >= 1");            }            this.stretchingInsets = insets == null ? EMPTY_INSETS : insets;            this.canvasSize = canvasSize;            this.inverted = inverted;            this.cacheMode = cacheMode == null ? CacheMode.NO_CACHING : cacheMode;            this.maxHorizontalScaleFactor = maxH;            this.maxVerticalScaleFactor = maxV;            if (canvasSize != null) {                a = insets.left;                b = canvasSize.width - insets.right;                c = insets.top;                d = canvasSize.height - insets.bottom;                this.canvasSize = canvasSize;                this.inverted = inverted;                if (inverted) {                    float available = canvasSize.width - (b - a);                    aPercent = available > 0f ? a / available : 0f;                    bPercent = available > 0f ? b / available : 0f;                    available = canvasSize.height - (d - c);                    cPercent = available > 0f ? c / available : 0f;                    dPercent = available > 0f ? d / available : 0f;                }            }        }    }    //---------------------- private methods    //initializes the class to prepare it for being able to decode points    private void prepare(float w, float h) {        //if no PaintContext has been specified, reset the values and bail        //also bail if the canvasSize was not set (since decoding will not work)        if (ctx == null || ctx.canvasSize == null) {            f = 1f;            leftWidth = centerWidth = rightWidth = 0f;            topHeight = centerHeight = bottomHeight = 0f;            leftScale = centerHScale = rightScale = 0f;            topScale = centerVScale = bottomScale = 0f;            return;        }        //calculate the scaling factor, and the sizes for the various 9-square sections        Number scale = (Number)UIManager.get("scale");        f = scale == null ? 1f : scale.floatValue();        if (ctx.inverted) {            centerWidth = (ctx.b - ctx.a) * f;            float availableSpace = w - centerWidth;            leftWidth = availableSpace * ctx.aPercent;            rightWidth = availableSpace * ctx.bPercent;            centerHeight = (ctx.d - ctx.c) * f;            availableSpace = h - centerHeight;            topHeight = availableSpace * ctx.cPercent;            bottomHeight = availableSpace * ctx.dPercent;        } else {            leftWidth = ctx.a * f;            rightWidth = (float)(ctx.canvasSize.getWidth() - ctx.b) * f;            centerWidth = w - leftWidth - rightWidth;            topHeight = ctx.c * f;            bottomHeight = (float)(ctx.canvasSize.getHeight() - ctx.d) * f;            centerHeight = h - topHeight - bottomHeight;        }        leftScale = ctx.a == 0f ? 0f : leftWidth / ctx.a;        centerHScale = (ctx.b - ctx.a) == 0f ? 0f : centerWidth / (ctx.b - ctx.a);        rightScale = (ctx.canvasSize.width - ctx.b) == 0f ? 0f : rightWidth / (ctx.canvasSize.width - ctx.b);        topScale = ctx.c == 0f ? 0f : topHeight / ctx.c;        centerVScale = (ctx.d - ctx.c) == 0f ? 0f : centerHeight / (ctx.d - ctx.c);        bottomScale = (ctx.canvasSize.height - ctx.d) == 0f ? 0f : bottomHeight / (ctx.canvasSize.height - ctx.d);    }    private void paintWith9SquareCaching(Graphics2D g, PaintContext ctx,                                         JComponent c, int w, int h,                                         Object[] extendedCacheKeys) {        // check if we can scale to the requested size        Dimension canvas = ctx.canvasSize;        Insets insets = ctx.stretchingInsets;        if (w <= (canvas.width * ctx.maxHorizontalScaleFactor) && h <= (canvas.height * ctx.maxVerticalScaleFactor)) {            // get image at canvas size            VolatileImage img = getImage(g.getDeviceConfiguration(), c, canvas.width, canvas.height, extendedCacheKeys);            if (img != null) {                // calculate dst inserts                // todo: destination inserts need to take into acount scale factor for high dpi. Note: You can use f for this, I think                Insets dstInsets;                if (ctx.inverted){                    int leftRight = (w-(canvas.width-(insets.left+insets.right)))/2;                    int topBottom = (h-(canvas.height-(insets.top+insets.bottom)))/2;                    dstInsets = new Insets(topBottom,leftRight,topBottom,leftRight);                } else {                    dstInsets = insets;                }                // paint 9 square scaled                Object oldScaleingHints = g.getRenderingHint(RenderingHints.KEY_INTERPOLATION);                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);                ImageScalingHelper.paint(g, 0, 0, w, h, img, insets, dstInsets,                        ImageScalingHelper.PaintType.PAINT9_STRETCH, ImageScalingHelper.PAINT_ALL);                g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,                    oldScaleingHints!=null?oldScaleingHints:RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);            } else {                // render directly                paint0(g, c, w, h, extendedCacheKeys);            }        } else {            // paint directly            paint0(g, c, w, h, extendedCacheKeys);        }    }    private void paintWithFixedSizeCaching(Graphics2D g, JComponent c, int w,                                           int h, Object[] extendedCacheKeys) {        VolatileImage img = getImage(g.getDeviceConfiguration(), c, w, h, extendedCacheKeys);        if (img != null) {            //render cached image            g.drawImage(img, 0, 0, null);        } else {            // render directly            paint0(g, c, w, h, extendedCacheKeys);        }    }    /** Gets the rendered image for this painter at the requested size, either from cache or create a new one */    private VolatileImage getImage(GraphicsConfiguration config, JComponent c,                                   int w, int h, Object[] extendedCacheKeys) {        ImageCache imageCache = ImageCache.getInstance();        //get the buffer for this component        VolatileImage buffer = (VolatileImage) imageCache.getImage(config, w, h, this, extendedCacheKeys);        int renderCounter = 0; //to avoid any potential, though unlikely, infinite loop        do {            //validate the buffer so we can check for surface loss            int bufferStatus = VolatileImage.IMAGE_INCOMPATIBLE;            if (buffer != null) {                bufferStatus = buffer.validate(config);            }            //If the buffer status is incompatible or restored, then we need to re-render to the volatile image            if (bufferStatus == VolatileImage.IMAGE_INCOMPATIBLE || bufferStatus == VolatileImage.IMAGE_RESTORED) {                //if the buffer is null (hasn't been created), or isn't the right size, or has lost its contents,                //then recreate the buffer                if (buffer == null || buffer.getWidth() != w || buffer.getHeight() != h ||                        bufferStatus == VolatileImage.IMAGE_INCOMPATIBLE) {                    //clear any resources related to the old back buffer                    if (buffer != null) {                        buffer.flush();                        buffer = null;                    }                    //recreate the buffer                    buffer = config.createCompatibleVolatileImage(w, h,                            Transparency.TRANSLUCENT);                    // put in cache for future                    imageCache.setImage(buffer, config, w, h, this, extendedCacheKeys);                }                //create the graphics context with which to paint to the buffer                Graphics2D bg = buffer.createGraphics();                //clear the background before configuring the graphics                bg.setComposite(AlphaComposite.Clear);                bg.fillRect(0, 0, w, h);                bg.setComposite(AlphaComposite.SrcOver);                configureGraphics(bg);                // paint the painter into buffer                paint0(bg, c, w, h, extendedCacheKeys);                //close buffer graphics                bg.dispose();            }        } while (buffer.contentsLost() && renderCounter++ < 3);        // check if we failed        if (renderCounter == 3) return null;        // return image        return buffer;    }    //convenience method which creates a temporary graphics object by creating a    //clone of the passed in one, configuring it, drawing with it, disposing it.    //These steps have to be taken to ensure that any hints set on the graphics    //are removed subsequent to painting.    private void paint0(Graphics2D g, JComponent c, int width, int height,                        Object[] extendedCacheKeys) {        prepare(width, height);        g = (Graphics2D)g.create();        configureGraphics(g);        doPaint(g, c, width, height, extendedCacheKeys);        g.dispose();    }    private float clamp(float value) {        if (value < 0) {            value = 0;        } else if (value > 1) {            value = 1;        }        return value;    }    private int clamp(int value) {        if (value < 0) {            value = 0;        } else if (value > 255) {            value = 255;        }        return value;    }}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?