1 /* 2 * Copyright (c) 1997, 2007, 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.pipe; 27 28 import java.awt.BasicStroke; 29 import java.awt.Rectangle; 30 import java.awt.Shape; 31 import java.awt.geom.Rectangle2D; 32 import java.awt.geom.PathIterator; 33 import sun.awt.SunHints; 34 import sun.java2d.SunGraphics2D; 35 36 /** 37 * This class is used to convert raw geometry into 8-bit alpha tiles 38 * using an AATileGenerator for application by the next stage of 39 * the pipeline. 40 * This class sets up the Generator and computes the alpha tiles 41 * and then passes them on to a CompositePipe object for painting. 42 */ 43 public class AAShapePipe 44 implements ShapeDrawPipe, ParallelogramPipe 45 { 46 static RenderingEngine renderengine = RenderingEngine.getInstance(); 47 48 CompositePipe outpipe; 49 50 public AAShapePipe(CompositePipe pipe) { 51 outpipe = pipe; 52 } 53 54 public void draw(SunGraphics2D sg, Shape s) { 55 BasicStroke bs; 56 57 if (sg.stroke instanceof BasicStroke) { 58 bs = (BasicStroke) sg.stroke; 59 } else { 60 s = sg.stroke.createStrokedShape(s); 61 bs = null; 62 } 63 64 renderPath(sg, s, bs); 65 } 66 67 public void fill(SunGraphics2D sg, Shape s) { 68 renderPath(sg, s, null); 69 } 70 71 private static Rectangle2D computeBBox(double x, double y, 72 double dx1, double dy1, 73 double dx2, double dy2) 74 { 75 double lox, loy, hix, hiy; 76 lox = hix = x; 77 loy = hiy = y; 78 if (dx1 < 0) { lox += dx1; } else { hix += dx1; } 79 if (dy1 < 0) { loy += dy1; } else { hiy += dy1; } 80 if (dx2 < 0) { lox += dx2; } else { hix += dx2; } 81 if (dy2 < 0) { loy += dy2; } else { hiy += dy2; } 82 return new Rectangle2D.Double(lox, loy, hix-lox, hiy-loy); 83 } 84 85 public void fillParallelogram(SunGraphics2D sg, 86 double x, double y, 87 double dx1, double dy1, 88 double dx2, double dy2) 89 { 90 Region clip = sg.getCompClip(); 91 int abox[] = new int[4]; 92 AATileGenerator aatg = 93 renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, 0, 0, 94 clip, abox); 95 if (aatg == null) { 96 // Nothing to render 97 return; 98 } 99 100 renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox); 101 } 102 103 public void drawParallelogram(SunGraphics2D sg, 104 double x, double y, 105 double dx1, double dy1, 106 double dx2, double dy2, 107 double lw1, double lw2) 108 { 109 Region clip = sg.getCompClip(); 110 int abox[] = new int[4]; 111 AATileGenerator aatg = 112 renderengine.getAATileGenerator(x, y, dx1, dy1, dx2, dy2, lw1, lw2, 113 clip, abox); 114 if (aatg == null) { 115 // Nothing to render 116 return; 117 } 118 119 // Note that bbox is of the original shape, not the wide path. 120 // This is appropriate for handing to Paint methods... 121 renderTiles(sg, computeBBox(x, y, dx1, dy1, dx2, dy2), aatg, abox); 122 } 123 124 private static byte[] theTile; 125 126 public synchronized static byte[] getAlphaTile(int len) { 127 byte[] t = theTile; 128 if (t == null || t.length < len) { 129 t = new byte[len]; 130 } else { 131 theTile = null; 132 } 133 return t; 134 } 135 136 public synchronized static void dropAlphaTile(byte[] t) { 137 theTile = t; 138 } 139 140 public void renderPath(SunGraphics2D sg, Shape s, BasicStroke bs) { 141 boolean adjust = (bs != null && 142 sg.strokeHint != SunHints.INTVAL_STROKE_PURE); 143 boolean thin = (sg.strokeState <= sg.STROKE_THINDASHED); 144 145 Region clip = sg.getCompClip(); 146 int abox[] = new int[4]; 147 AATileGenerator aatg = 148 renderengine.getAATileGenerator(s, sg.transform, clip, 149 bs, thin, adjust, abox); 150 if (aatg == null) { 151 // Nothing to render 152 return; 153 } 154 155 renderTiles(sg, s, aatg, abox); 156 } 157 158 public void renderTiles(SunGraphics2D sg, Shape s, 159 AATileGenerator aatg, int abox[]) 160 { 161 Object context = null; 162 byte alpha[] = null; 163 try { 164 context = outpipe.startSequence(sg, s, 165 new Rectangle(abox[0], abox[1], 166 abox[2] - abox[0], 167 abox[3] - abox[1]), 168 abox); 169 170 int tw = aatg.getTileWidth(); 171 int th = aatg.getTileHeight(); 172 alpha = getAlphaTile(tw * th); 173 174 byte[] atile; 175 176 for (int y = abox[1]; y < abox[3]; y += th) { 177 for (int x = abox[0]; x < abox[2]; x += tw) { 178 int w = Math.min(tw, abox[2] - x); 179 int h = Math.min(th, abox[3] - y); 180 181 int a = aatg.getTypicalAlpha(); 182 if (a == 0x00 || 183 outpipe.needTile(context, x, y, w, h) == false) 184 { 185 aatg.nextTile(); 186 outpipe.skipTile(context, x, y); 187 continue; 188 } 189 if (a == 0xff) { 190 atile = null; 191 aatg.nextTile(); 192 } else { 193 atile = alpha; 194 aatg.getAlpha(alpha, 0, tw); 195 } 196 197 outpipe.renderPathTile(context, atile, 0, tw, 198 x, y, w, h); 199 } 200 } 201 } finally { 202 aatg.dispose(); 203 if (context != null) { 204 outpipe.endSequence(context); 205 } 206 if (alpha != null) { 207 dropAlphaTile(alpha); 208 } 209 } 210 } 211 }