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 + -
显示快捷键?