Path: blob/master/src/java.desktop/share/classes/sun/java2d/loops/MaskFill.java
41159 views
/*1* Copyright (c) 1999, 2021, 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.loops;2627import java.awt.Composite;28import java.awt.image.BufferedImage;2930import sun.awt.image.BufImgSurfaceData;31import sun.java2d.SunGraphics2D;32import sun.java2d.SurfaceData;33import sun.java2d.pipe.Region;3435/**36* MaskFill37* 1) fills rectangles of pixels on a surface38* 2) performs compositing of colors based upon a Composite39* parameter40* 3) blends result of composite with destination using an41* alpha coverage mask42* 4) the mask may be null in which case it should be treated43* as if it were an array of all opaque values (0xff)44*/45public class MaskFill extends GraphicsPrimitive46{47public static final String methodSignature = "MaskFill(...)".toString();48public static final String fillPgramSignature =49"FillAAPgram(...)".toString();50public static final String drawPgramSignature =51"DrawAAPgram(...)".toString();5253public static final int primTypeID = makePrimTypeID();5455private static RenderCache fillcache = new RenderCache(10);5657public static MaskFill locate(SurfaceType srctype,58CompositeType comptype,59SurfaceType dsttype)60{61return (MaskFill)62GraphicsPrimitiveMgr.locate(primTypeID,63srctype, comptype, dsttype);64}6566public static MaskFill locatePrim(SurfaceType srctype,67CompositeType comptype,68SurfaceType dsttype)69{70return (MaskFill)71GraphicsPrimitiveMgr.locatePrim(primTypeID,72srctype, comptype, dsttype);73}7475/*76* Note that this uses locatePrim, not locate, so it can return77* null if there is no specific loop to handle this op...78*/79public static MaskFill getFromCache(SurfaceType src,80CompositeType comp,81SurfaceType dst)82{83Object o = fillcache.get(src, comp, dst);84if (o != null) {85return (MaskFill) o;86}87MaskFill fill = locatePrim(src, comp, dst);88if (fill != null) {89fillcache.put(src, comp, dst, fill);90}91return fill;92}9394protected MaskFill(String alternateSignature,95SurfaceType srctype,96CompositeType comptype,97SurfaceType dsttype)98{99super(alternateSignature, primTypeID, srctype, comptype, dsttype);100}101102protected MaskFill(SurfaceType srctype,103CompositeType comptype,104SurfaceType dsttype)105{106super(methodSignature, primTypeID, srctype, comptype, dsttype);107}108109public MaskFill(long pNativePrim,110SurfaceType srctype,111CompositeType comptype,112SurfaceType dsttype)113{114super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);115}116117/**118* All MaskFill implementors must have this invoker method119*/120public native void MaskFill(SunGraphics2D sg2d, SurfaceData sData,121Composite comp,122int x, int y, int w, int h,123byte[] mask, int maskoff, int maskscan);124125public native void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData,126Composite comp,127double x, double y,128double dx1, double dy1,129double dx2, double dy2);130131public native void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData,132Composite comp,133double x, double y,134double dx1, double dy1,135double dx2, double dy2,136double lw1, double lw2);137138public boolean canDoParallelograms() {139return (getNativePrim() != 0);140}141142static {143GraphicsPrimitiveMgr.registerGeneral(new MaskFill(null, null, null));144}145146protected GraphicsPrimitive makePrimitive(SurfaceType srctype,147CompositeType comptype,148SurfaceType dsttype)149{150if (SurfaceType.OpaqueColor.equals(srctype) ||151SurfaceType.AnyColor.equals(srctype))152{153if (CompositeType.Xor.equals(comptype)) {154throw new InternalError("Cannot construct MaskFill for " +155"XOR mode");156} else {157return new General(srctype, comptype, dsttype);158}159} else {160throw new InternalError("MaskFill can only fill with colors");161}162}163164private static class General extends MaskFill {165FillRect fillop;166MaskBlit maskop;167168public General(SurfaceType srctype,169CompositeType comptype,170SurfaceType dsttype)171{172super(srctype, comptype, dsttype);173fillop = FillRect.locate(srctype,174CompositeType.SrcNoEa,175SurfaceType.IntArgb);176maskop = MaskBlit.locate(SurfaceType.IntArgb, comptype, dsttype);177}178179public void MaskFill(SunGraphics2D sg2d,180SurfaceData sData,181Composite comp,182int x, int y, int w, int h,183byte[] mask, int offset, int scan)184{185BufferedImage dstBI =186new BufferedImage(w, h, BufferedImage.TYPE_INT_ARGB);187SurfaceData tmpData = BufImgSurfaceData.createData(dstBI);188189// REMIND: This is not pretty. It would be nicer if we190// passed a "FillData" object to the Pixel loops, instead191// of a SunGraphics2D parameter...192Region clip = sg2d.clipRegion;193sg2d.clipRegion = null;194int pixel = sg2d.pixel;195sg2d.pixel = tmpData.pixelFor(sg2d.getColor());196fillop.FillRect(sg2d, tmpData, 0, 0, w, h);197sg2d.pixel = pixel;198sg2d.clipRegion = clip;199200maskop.MaskBlit(tmpData, sData, comp, null,2010, 0, x, y, w, h,202mask, offset, scan);203}204}205206public GraphicsPrimitive traceWrap() {207return new TraceMaskFill(this);208}209210private static class TraceMaskFill extends MaskFill {211MaskFill target;212MaskFill fillPgramTarget;213MaskFill drawPgramTarget;214215public TraceMaskFill(MaskFill target) {216super(target.getSourceType(),217target.getCompositeType(),218target.getDestType());219this.target = target;220this.fillPgramTarget = new MaskFill(fillPgramSignature,221target.getSourceType(),222target.getCompositeType(),223target.getDestType());224this.drawPgramTarget = new MaskFill(drawPgramSignature,225target.getSourceType(),226target.getCompositeType(),227target.getDestType());228}229230public GraphicsPrimitive traceWrap() {231return this;232}233234public void MaskFill(SunGraphics2D sg2d, SurfaceData sData,235Composite comp,236int x, int y, int w, int h,237byte[] mask, int maskoff, int maskscan)238{239tracePrimitive(target);240target.MaskFill(sg2d, sData, comp, x, y, w, h,241mask, maskoff, maskscan);242}243244public void FillAAPgram(SunGraphics2D sg2d, SurfaceData sData,245Composite comp,246double x, double y,247double dx1, double dy1,248double dx2, double dy2)249{250tracePrimitive(fillPgramTarget);251target.FillAAPgram(sg2d, sData, comp,252x, y, dx1, dy1, dx2, dy2);253}254255public void DrawAAPgram(SunGraphics2D sg2d, SurfaceData sData,256Composite comp,257double x, double y,258double dx1, double dy1,259double dx2, double dy2,260double lw1, double lw2)261{262tracePrimitive(drawPgramTarget);263target.DrawAAPgram(sg2d, sData, comp,264x, y, dx1, dy1, dx2, dy2, lw1, lw2);265}266267public boolean canDoParallelograms() {268return target.canDoParallelograms();269}270}271}272273274