1 /*
   2  * Copyright (c) 1999, 2008, Oracle and/or its affiliates. All rights reserved.
   3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
   4  *
   5  * This code is free software; you can redistribute it and/or modify it
   6  * under the terms of the GNU General Public License version 2 only, as
   7  * published by the Free Software Foundation.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.java2d.loops;
  27 
  28 import java.awt.Font;
  29 import java.awt.Color;
  30 import java.awt.Composite;
  31 import java.awt.AlphaComposite;
  32 import java.awt.Transparency;
  33 import java.awt.image.ColorModel;
  34 import java.awt.image.WritableRaster;
  35 import java.awt.image.BufferedImage;
  36 import sun.awt.image.BufImgSurfaceData;
  37 import sun.java2d.loops.GraphicsPrimitive;
  38 import sun.java2d.SurfaceData;
  39 import sun.java2d.SunGraphics2D;
  40 import sun.java2d.pipe.Region;
  41 
  42 /**
  43  * BlitBg
  44  * 1) copies rectangle of pixels from one surface to another
  45  * 2) performs compositing of colors based upon a Composite
  46  *    parameter
  47  * 3) assumes that non-opaque pixels are to be blended with
  48  *    the indicated Bg color before compositing with the
  49  *    destination
  50  *
  51  * precise behavior is undefined if the source surface
  52  * and the destination surface are the same surface
  53  * with overlapping regions of pixels
  54  */
  55 public class BlitBg extends GraphicsPrimitive
  56 {
  57     public static final String methodSignature = "BlitBg(...)".toString();
  58 
  59     public static final int primTypeID = makePrimTypeID();
  60 
  61     private static RenderCache blitcache = new RenderCache(20);
  62 
  63     public static BlitBg locate(SurfaceType srctype,
  64                                 CompositeType comptype,
  65                                 SurfaceType dsttype)
  66     {
  67         return (BlitBg)
  68             GraphicsPrimitiveMgr.locate(primTypeID,
  69                                         srctype, comptype, dsttype);
  70     }
  71 
  72     public static BlitBg getFromCache(SurfaceType src,
  73                                       CompositeType comp,
  74                                       SurfaceType dst)
  75     {
  76         Object o = blitcache.get(src, comp, dst);
  77         if (o != null) {
  78             return (BlitBg) o;
  79         }
  80         BlitBg blit = locate(src, comp, dst);
  81         if (blit == null) {
  82             System.out.println("blitbg loop not found for:");
  83             System.out.println("src:  "+src);
  84             System.out.println("comp: "+comp);
  85             System.out.println("dst:  "+dst);
  86         } else {
  87             blitcache.put(src, comp, dst, blit);
  88         }
  89         return blit;
  90     }
  91 
  92     protected BlitBg(SurfaceType srctype,
  93                      CompositeType comptype,
  94                      SurfaceType dsttype)
  95     {
  96         super(methodSignature, primTypeID, srctype, comptype, dsttype);
  97     }
  98 
  99     public BlitBg(long pNativePrim,
 100                   SurfaceType srctype,
 101                   CompositeType comptype,
 102                   SurfaceType dsttype)
 103     {
 104         super(pNativePrim, methodSignature, primTypeID, srctype, comptype, dsttype);
 105     }
 106 
 107     /**
 108      * All BlitBg implementors must have this invoker method
 109      */
 110     public native void BlitBg(SurfaceData src, SurfaceData dst,
 111                               Composite comp, Region clip,
 112                               int bgColor,
 113                               int srcx, int srcy,
 114                               int dstx, int dsty,
 115                               int width, int height);
 116 
 117     static {
 118         GraphicsPrimitiveMgr.registerGeneral(new BlitBg(null, null, null));
 119     }
 120 
 121     public GraphicsPrimitive makePrimitive(SurfaceType srctype,
 122                                            CompositeType comptype,
 123                                            SurfaceType dsttype)
 124     {
 125         /*
 126         System.out.println("Constructing general blitbg for:");
 127         System.out.println("src:  "+srctype);
 128         System.out.println("comp: "+comptype);
 129         System.out.println("dst:  "+dsttype);
 130         */
 131         return new General(srctype, comptype, dsttype);
 132     }
 133 
 134     private static class General extends BlitBg {
 135         CompositeType compositeType;
 136 
 137         public General(SurfaceType srctype,
 138                        CompositeType comptype,
 139                        SurfaceType dsttype)
 140         {
 141             super(srctype, comptype, dsttype);
 142             compositeType = comptype;
 143         }
 144 
 145         @Override
 146         public void BlitBg(SurfaceData srcData,
 147                            SurfaceData dstData,
 148                            Composite comp,
 149                            Region clip,
 150                            int bgArgb,
 151                            int srcx, int srcy,
 152                            int dstx, int dsty,
 153                            int width, int height)
 154         {
 155             ColorModel dstModel = dstData.getColorModel();
 156             boolean bgHasAlpha = (bgArgb >>> 24) != 0xff;
 157             if (!dstModel.hasAlpha() && bgHasAlpha) {
 158                 dstModel = ColorModel.getRGBdefault();
 159             }
 160             WritableRaster wr =
 161                 dstModel.createCompatibleWritableRaster(width, height);
 162             boolean isPremult = dstModel.isAlphaPremultiplied();
 163             BufferedImage bimg =
 164                 new BufferedImage(dstModel, wr, isPremult, null);
 165             SurfaceData tmpData = BufImgSurfaceData.createData(bimg);
 166             Color bgColor = new Color(bgArgb, bgHasAlpha);
 167             SunGraphics2D sg2d = new SunGraphics2D(tmpData, bgColor, bgColor,
 168                                                    defaultFont);
 169             FillRect fillop = FillRect.locate(SurfaceType.AnyColor,
 170                                               CompositeType.SrcNoEa,
 171                                               tmpData.getSurfaceType());
 172             Blit combineop = Blit.getFromCache(srcData.getSurfaceType(),
 173                                                CompositeType.SrcOverNoEa,
 174                                                tmpData.getSurfaceType());
 175             Blit blitop = Blit.getFromCache(tmpData.getSurfaceType(), compositeType,
 176                                             dstData.getSurfaceType());
 177             fillop.FillRect(sg2d, tmpData, 0, 0, width, height);
 178             combineop.Blit(srcData, tmpData, AlphaComposite.SrcOver, null,
 179                            srcx, srcy, 0, 0, width, height);
 180             blitop.Blit(tmpData, dstData, comp, clip,
 181                         0, 0, dstx, dsty, width, height);
 182         }
 183 
 184         private static Font defaultFont = new Font("Dialog", Font.PLAIN, 12);
 185     }
 186 
 187     public GraphicsPrimitive traceWrap() {
 188         return new TraceBlitBg(this);
 189     }
 190 
 191     private static class TraceBlitBg extends BlitBg {
 192         BlitBg target;
 193 
 194         public TraceBlitBg(BlitBg target) {
 195             super(target.getSourceType(),
 196                   target.getCompositeType(),
 197                   target.getDestType());
 198             this.target = target;
 199         }
 200 
 201         public GraphicsPrimitive traceWrap() {
 202             return this;
 203         }
 204 
 205         @Override
 206         public void BlitBg(SurfaceData src, SurfaceData dst,
 207                            Composite comp, Region clip,
 208                            int bgColor,
 209                            int srcx, int srcy, int dstx, int dsty,
 210                            int width, int height)
 211         {
 212             tracePrimitive(target);
 213             target.BlitBg(src, dst, comp, clip, bgColor,
 214                           srcx, srcy, dstx, dsty, width, height);
 215         }
 216     }
 217 }