Path: blob/aarch64-shenandoah-jdk8u272-b10/jdk/src/solaris/classes/sun/java2d/jules/JulesPathBuf.java
32288 views
/*1* Copyright (c) 2010, 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.jules;2627import java.awt.*;28import java.awt.geom.*;29import sun.awt.X11GraphicsEnvironment;30import sun.java2d.pipe.*;31import sun.java2d.xr.*;3233public class JulesPathBuf {34static final double[] emptyDash = new double[0];3536private static final byte CAIRO_PATH_OP_MOVE_TO = 0;37private static final byte CAIRO_PATH_OP_LINE_TO = 1;38private static final byte CAIRO_PATH_OP_CURVE_TO = 2;39private static final byte CAIRO_PATH_OP_CLOSE_PATH = 3;4041private static final int CAIRO_FILL_RULE_WINDING = 0;42private static final int CAIRO_FILL_RULE_EVEN_ODD = 1;4344GrowablePointArray points = new GrowablePointArray(128);45GrowableByteArray ops = new GrowableByteArray(1, 128);46int[] xTrapArray = new int[512];4748private static final boolean isCairoAvailable;4950static {51isCairoAvailable =52java.security.AccessController.doPrivileged(53new java.security.PrivilegedAction<Boolean>() {54public Boolean run() {55boolean loadSuccess = false;56if (X11GraphicsEnvironment.isXRenderAvailable()) {57try {58System.loadLibrary("jules");59loadSuccess = true;60if (X11GraphicsEnvironment.isXRenderVerbose()) {61System.out.println(62"Xrender: INFO: Jules library loaded");63}64} catch (UnsatisfiedLinkError ex) {65loadSuccess = false;66if (X11GraphicsEnvironment.isXRenderVerbose()) {67System.out.println(68"Xrender: INFO: Jules library not installed.");69}70}71}72return Boolean.valueOf(loadSuccess);73}74});75}7677public static boolean isCairoAvailable() {78return isCairoAvailable;79}8081public TrapezoidList tesselateFill(Shape s, AffineTransform at, Region clip) {82int windingRule = convertPathData(s, at);83xTrapArray[0] = 0;8485xTrapArray = tesselateFillNative(points.getArray(), ops.getArray(),86points.getSize(), ops.getSize(),87xTrapArray, xTrapArray.length,88getCairoWindingRule(windingRule),89clip.getLoX(), clip.getLoY(),90clip.getHiX(), clip.getHiY());9192return new TrapezoidList(xTrapArray);93}9495public TrapezoidList tesselateStroke(Shape s, BasicStroke bs, boolean thin,96boolean adjust, boolean antialias,97AffineTransform at, Region clip) {9899float lw;100if (thin) {101if (antialias) {102lw = 0.5f;103} else {104lw = 1.0f;105}106} else {107lw = bs.getLineWidth();108}109110convertPathData(s, at);111112double[] dashArray = floatToDoubleArray(bs.getDashArray());113xTrapArray[0] = 0;114115xTrapArray =116tesselateStrokeNative(points.getArray(), ops.getArray(),117points.getSize(), ops.getSize(),118xTrapArray, xTrapArray.length, lw,119bs.getEndCap(), bs.getLineJoin(),120bs.getMiterLimit(), dashArray,121dashArray.length, bs.getDashPhase(),1221, 0, 0, 0, 1, 0,123clip.getLoX(), clip.getLoY(),124clip.getHiX(), clip.getHiY());125126return new TrapezoidList(xTrapArray);127}128129protected double[] floatToDoubleArray(float[] dashArrayFloat) {130double[] dashArrayDouble = emptyDash;131if (dashArrayFloat != null) {132dashArrayDouble = new double[dashArrayFloat.length];133134for (int i = 0; i < dashArrayFloat.length; i++) {135dashArrayDouble[i] = dashArrayFloat[i];136}137}138139return dashArrayDouble;140}141142protected int convertPathData(Shape s, AffineTransform at) {143PathIterator pi = s.getPathIterator(at);144145double[] coords = new double[6];146double currX = 0;147double currY = 0;148149while (!pi.isDone()) {150int curOp = pi.currentSegment(coords);151152int pointIndex;153switch (curOp) {154155case PathIterator.SEG_MOVETO:156ops.addByte(CAIRO_PATH_OP_MOVE_TO);157pointIndex = points.getNextIndex();158points.setX(pointIndex, DoubleToCairoFixed(coords[0]));159points.setY(pointIndex, DoubleToCairoFixed(coords[1]));160currX = coords[0];161currY = coords[1];162break;163164case PathIterator.SEG_LINETO:165ops.addByte(CAIRO_PATH_OP_LINE_TO);166pointIndex = points.getNextIndex();167points.setX(pointIndex, DoubleToCairoFixed(coords[0]));168points.setY(pointIndex, DoubleToCairoFixed(coords[1]));169currX = coords[0];170currY = coords[1];171break;172173/**174* q0 = p0175* q1 = (p0+2*p1)/3176* q2 = (p2+2*p1)/3177* q3 = p2178*/179case PathIterator.SEG_QUADTO:180double x1 = coords[0];181double y1 = coords[1];182double x2, y2;183double x3 = coords[2];184double y3 = coords[3];185186x2 = x1 + (x3 - x1) / 3;187y2 = y1 + (y3 - y1) / 3;188x1 = currX + 2 * (x1 - currX) / 3;189y1 =currY + 2 * (y1 - currY) / 3;190191ops.addByte(CAIRO_PATH_OP_CURVE_TO);192pointIndex = points.getNextIndex();193points.setX(pointIndex, DoubleToCairoFixed(x1));194points.setY(pointIndex, DoubleToCairoFixed(y1));195pointIndex = points.getNextIndex();196points.setX(pointIndex, DoubleToCairoFixed(x2));197points.setY(pointIndex, DoubleToCairoFixed(y2));198pointIndex = points.getNextIndex();199points.setX(pointIndex, DoubleToCairoFixed(x3));200points.setY(pointIndex, DoubleToCairoFixed(y3));201currX = x3;202currY = y3;203break;204205case PathIterator.SEG_CUBICTO:206ops.addByte(CAIRO_PATH_OP_CURVE_TO);207pointIndex = points.getNextIndex();208points.setX(pointIndex, DoubleToCairoFixed(coords[0]));209points.setY(pointIndex, DoubleToCairoFixed(coords[1]));210pointIndex = points.getNextIndex();211points.setX(pointIndex, DoubleToCairoFixed(coords[2]));212points.setY(pointIndex, DoubleToCairoFixed(coords[3]));213pointIndex = points.getNextIndex();214points.setX(pointIndex, DoubleToCairoFixed(coords[4]));215points.setY(pointIndex, DoubleToCairoFixed(coords[5]));216currX = coords[4];217currY = coords[5];218break;219220case PathIterator.SEG_CLOSE:221ops.addByte(CAIRO_PATH_OP_CLOSE_PATH);222break;223}224225pi.next();226}227228return pi.getWindingRule();229}230231private static native int[]232tesselateStrokeNative(int[] pointArray, byte[] ops,233int pointCnt, int opCnt,234int[] xTrapArray, int xTrapArrayLength,235double lineWidth, int lineCap, int lineJoin,236double miterLimit, double[] dashArray,237int dashCnt, double offset,238double m00, double m01, double m02,239double m10, double m11, double m12,240int clipLowX, int clipLowY,241int clipWidth, int clipHeight);242243private static native int[]244tesselateFillNative(int[] pointArray, byte[] ops, int pointCnt,245int opCnt, int[] xTrapArray, int xTrapArrayLength,246int windingRule, int clipLowX, int clipLowY, int clipWidth, int clipHeight);247248public void clear() {249points.clear();250ops.clear();251xTrapArray[0] = 0;252}253254private static int DoubleToCairoFixed(double dbl) {255return (int) (dbl * 256);256}257258private static int getCairoWindingRule(int j2dWindingRule) {259switch(j2dWindingRule) {260case PathIterator.WIND_EVEN_ODD:261return CAIRO_FILL_RULE_EVEN_ODD;262263case PathIterator.WIND_NON_ZERO:264return CAIRO_FILL_RULE_WINDING;265266default:267throw new IllegalArgumentException("Illegal Java2D winding rule specified");268}269}270}271272273