Path: blob/master/src/java.desktop/share/classes/sun/java2d/pipe/AlphaPaintPipe.java
41159 views
/*1* Copyright (c) 1997, 2002, Oracle and/or its affiliates. All rights reserved.2* DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.3*4* This code is free software; you can redistribute it and/or modify it5* under the terms of the GNU General Public License version 2 only, as6* published by the Free Software Foundation. Oracle designates this7* particular file as subject to the "Classpath" exception as provided8* by Oracle in the LICENSE file that accompanied this code.9*10* This code is distributed in the hope that it will be useful, but WITHOUT11* ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or12* FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License13* version 2 for more details (a copy is included in the LICENSE file that14* accompanied this code).15*16* You should have received a copy of the GNU General Public License version17* 2 along with this work; if not, write to the Free Software Foundation,18* Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.19*20* Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA21* or visit www.oracle.com if you need additional information or have any22* questions.23*/2425package sun.java2d.pipe;2627import java.lang.ref.WeakReference;28import java.awt.Rectangle;29import java.awt.Shape;30import java.awt.PaintContext;31import java.awt.Transparency;32import java.awt.image.ColorModel;33import java.awt.image.Raster;34import java.awt.image.WritableRaster;35import java.awt.image.BufferedImage;36import sun.awt.image.BufImgSurfaceData;37import sun.java2d.SunGraphics2D;38import sun.java2d.SurfaceData;39import sun.java2d.loops.Blit;40import sun.java2d.loops.MaskBlit;41import sun.java2d.loops.CompositeType;42import sun.java2d.loops.GraphicsPrimitiveMgr;4344/**45* This class implements a CompositePipe that renders path alpha tiles46* into a destination according to the Composite attribute of a47* SunGraphics2D.48*/49public class AlphaPaintPipe implements CompositePipe {50static WeakReference<Raster> cachedLastRaster;51static WeakReference<ColorModel> cachedLastColorModel;52static WeakReference<SurfaceData> cachedLastData;5354static class TileContext {55SunGraphics2D sunG2D;56PaintContext paintCtxt;57ColorModel paintModel;58WeakReference<Raster> lastRaster;59WeakReference<SurfaceData> lastData;60MaskBlit lastMask;61Blit lastBlit;62SurfaceData dstData;6364public TileContext(SunGraphics2D sg, PaintContext pc) {65sunG2D = sg;66paintCtxt = pc;67paintModel = pc.getColorModel();68dstData = sg.getSurfaceData();69synchronized (AlphaPaintPipe.class) {70if (cachedLastColorModel != null &&71cachedLastColorModel.get() == paintModel)72{73this.lastRaster = cachedLastRaster;74this.lastData = cachedLastData;75}76}77}78}7980public Object startSequence(SunGraphics2D sg, Shape s, Rectangle devR,81int[] abox) {82PaintContext paintContext =83sg.paint.createContext(sg.getDeviceColorModel(),84devR,85s.getBounds2D(),86sg.cloneTransform(),87sg.getRenderingHints());88return new TileContext(sg, paintContext);89}9091public boolean needTile(Object context, int x, int y, int w, int h) {92return true;93}9495private static final int TILE_SIZE = 32;9697public void renderPathTile(Object ctx,98byte[] atile, int offset, int tilesize,99int x, int y, int w, int h) {100TileContext context = (TileContext) ctx;101PaintContext paintCtxt = context.paintCtxt;102SunGraphics2D sg = context.sunG2D;103SurfaceData dstData = context.dstData;104SurfaceData srcData = null;105Raster lastRas = null;106if (context.lastData != null && context.lastRaster != null) {107srcData = context.lastData.get();108lastRas = context.lastRaster.get();109if (srcData == null || lastRas == null) {110srcData = null;111lastRas = null;112}113}114ColorModel paintModel = context.paintModel;115116for (int rely = 0; rely < h; rely += TILE_SIZE) {117int ty = y + rely;118int th = Math.min(h-rely, TILE_SIZE);119for (int relx = 0; relx < w; relx += TILE_SIZE) {120int tx = x + relx;121int tw = Math.min(w-relx, TILE_SIZE);122123Raster srcRaster = paintCtxt.getRaster(tx, ty, tw, th);124if ((srcRaster.getMinX() != 0) || (srcRaster.getMinY() != 0)) {125srcRaster = srcRaster.createTranslatedChild(0, 0);126}127if (lastRas != srcRaster) {128lastRas = srcRaster;129context.lastRaster = new WeakReference<>(lastRas);130// REMIND: This will fail for a non-Writable raster!131BufferedImage bImg =132new BufferedImage(paintModel,133(WritableRaster) srcRaster,134paintModel.isAlphaPremultiplied(),135null);136srcData = BufImgSurfaceData.createData(bImg);137context.lastData = new WeakReference<>(srcData);138context.lastMask = null;139context.lastBlit = null;140}141142if (atile == null) {143if (context.lastBlit == null) {144CompositeType comptype = sg.imageComp;145if (CompositeType.SrcOverNoEa.equals(comptype) &&146paintModel.getTransparency() == Transparency.OPAQUE)147{148comptype = CompositeType.SrcNoEa;149}150context.lastBlit =151Blit.getFromCache(srcData.getSurfaceType(),152comptype,153dstData.getSurfaceType());154}155context.lastBlit.Blit(srcData, dstData,156sg.composite, null,1570, 0, tx, ty, tw, th);158} else {159if (context.lastMask == null) {160CompositeType comptype = sg.imageComp;161if (CompositeType.SrcOverNoEa.equals(comptype) &&162paintModel.getTransparency() == Transparency.OPAQUE)163{164comptype = CompositeType.SrcNoEa;165}166context.lastMask =167MaskBlit.getFromCache(srcData.getSurfaceType(),168comptype,169dstData.getSurfaceType());170}171172int toff = offset + rely * tilesize + relx;173context.lastMask.MaskBlit(srcData, dstData,174sg.composite, null,1750, 0, tx, ty, tw, th,176atile, toff, tilesize);177}178}179}180}181182public void skipTile(Object context, int x, int y) {183return;184}185186public void endSequence(Object ctx) {187TileContext context = (TileContext) ctx;188if (context.paintCtxt != null) {189context.paintCtxt.dispose();190}191synchronized (AlphaPaintPipe.class) {192if (context.lastData != null) {193cachedLastRaster = context.lastRaster;194if (cachedLastColorModel == null ||195cachedLastColorModel.get() != context.paintModel)196{197// Avoid creating new WeakReference if possible198cachedLastColorModel =199new WeakReference<>(context.paintModel);200}201cachedLastData = context.lastData;202}203}204}205}206207208