diff options
Diffstat (limited to 'src/solaris/classes/sun/java2d/jules/JulesPathBuf.java')
-rw-r--r-- | src/solaris/classes/sun/java2d/jules/JulesPathBuf.java | 271 |
1 files changed, 271 insertions, 0 deletions
diff --git a/src/solaris/classes/sun/java2d/jules/JulesPathBuf.java b/src/solaris/classes/sun/java2d/jules/JulesPathBuf.java new file mode 100644 index 000000000..00c9407e7 --- /dev/null +++ b/src/solaris/classes/sun/java2d/jules/JulesPathBuf.java @@ -0,0 +1,271 @@ +/* + * Copyright 2010 Sun Microsystems, Inc. All Rights Reserved. + * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. + * + * This code is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License version 2 only, as + * published by the Free Software Foundation. Sun designates this + * particular file as subject to the "Classpath" exception as provided + * by Sun in the LICENSE file that accompanied this code. + * + * This code is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License + * version 2 for more details (a copy is included in the LICENSE file that + * accompanied this code). + * + * You should have received a copy of the GNU General Public License version + * 2 along with this work; if not, write to the Free Software Foundation, + * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. + * + * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara, + * CA 95054 USA or visit www.sun.com if you need additional information or + * have any questions. + */ + +package sun.java2d.jules; + +import java.awt.*; +import java.awt.geom.*; +import sun.awt.X11GraphicsEnvironment; +import sun.java2d.pipe.*; +import sun.java2d.xr.*; + +public class JulesPathBuf { + static final double[] emptyDash = new double[0]; + + private static final byte CAIRO_PATH_OP_MOVE_TO = 0; + private static final byte CAIRO_PATH_OP_LINE_TO = 1; + private static final byte CAIRO_PATH_OP_CURVE_TO = 2; + private static final byte CAIRO_PATH_OP_CLOSE_PATH = 3; + + private static final int CAIRO_FILL_RULE_WINDING = 0; + private static final int CAIRO_FILL_RULE_EVEN_ODD = 1; + + GrowablePointArray points = new GrowablePointArray(128); + GrowableByteArray ops = new GrowableByteArray(1, 128); + int[] xTrapArray = new int[512]; + + private static final boolean isCairoAvailable; + + static { + isCairoAvailable = + java.security.AccessController.doPrivileged( + new java.security.PrivilegedAction<Boolean>() { + public Boolean run() { + boolean loadSuccess = false; + if (X11GraphicsEnvironment.isXRenderAvailable()) { + try { + System.loadLibrary("jules"); + loadSuccess = true; + if (X11GraphicsEnvironment.isXRenderVerbose()) { + System.out.println( + "Xrender: INFO: Jules library loaded"); + } + } catch (UnsatisfiedLinkError ex) { + loadSuccess = false; + if (X11GraphicsEnvironment.isXRenderVerbose()) { + System.out.println( + "Xrender: INFO: Jules library not installed."); + } + } + } + return Boolean.valueOf(loadSuccess); + } + }); + } + + public static boolean isCairoAvailable() { + return isCairoAvailable; + } + + public TrapezoidList tesselateFill(Shape s, AffineTransform at, Region clip) { + int windingRule = convertPathData(s, at); + xTrapArray[0] = 0; + + xTrapArray = tesselateFillNative(points.getArray(), ops.getArray(), + points.getSize(), ops.getSize(), + xTrapArray, xTrapArray.length, + getCairoWindingRule(windingRule), + clip.getLoX(), clip.getLoY(), + clip.getHiX(), clip.getHiY()); + + return new TrapezoidList(xTrapArray); + } + + public TrapezoidList tesselateStroke(Shape s, BasicStroke bs, boolean thin, + boolean adjust, boolean antialias, + AffineTransform at, Region clip) { + + float lw; + if (thin) { + if (antialias) { + lw = 0.5f; + } else { + lw = 1.0f; + } + } else { + lw = bs.getLineWidth(); + } + + convertPathData(s, at); + + double[] dashArray = floatToDoubleArray(bs.getDashArray()); + xTrapArray[0] = 0; + + xTrapArray = + tesselateStrokeNative(points.getArray(), ops.getArray(), + points.getSize(), ops.getSize(), + xTrapArray, xTrapArray.length, lw, + bs.getEndCap(), bs.getLineJoin(), + bs.getMiterLimit(), dashArray, + dashArray.length, bs.getDashPhase(), + 1, 0, 0, 0, 1, 0, + clip.getLoX(), clip.getLoY(), + clip.getHiX(), clip.getHiY()); + + return new TrapezoidList(xTrapArray); + } + + protected double[] floatToDoubleArray(float[] dashArrayFloat) { + double[] dashArrayDouble = emptyDash; + if (dashArrayFloat != null) { + dashArrayDouble = new double[dashArrayFloat.length]; + + for (int i = 0; i < dashArrayFloat.length; i++) { + dashArrayDouble[i] = dashArrayFloat[i]; + } + } + + return dashArrayDouble; + } + + protected int convertPathData(Shape s, AffineTransform at) { + PathIterator pi = s.getPathIterator(at); + + double[] coords = new double[6]; + double currX = 0; + double currY = 0; + + while (!pi.isDone()) { + int curOp = pi.currentSegment(coords); + + int pointIndex; + switch (curOp) { + + case PathIterator.SEG_MOVETO: + ops.addByte(CAIRO_PATH_OP_MOVE_TO); + pointIndex = points.getNextIndex(); + points.setX(pointIndex, DoubleToCairoFixed(coords[0])); + points.setY(pointIndex, DoubleToCairoFixed(coords[1])); + currX = coords[0]; + currY = coords[1]; + break; + + case PathIterator.SEG_LINETO: + ops.addByte(CAIRO_PATH_OP_LINE_TO); + pointIndex = points.getNextIndex(); + points.setX(pointIndex, DoubleToCairoFixed(coords[0])); + points.setY(pointIndex, DoubleToCairoFixed(coords[1])); + currX = coords[0]; + currY = coords[1]; + break; + + /** + * q0 = p0 + * q1 = (p0+2*p1)/3 + * q2 = (p2+2*p1)/3 + * q3 = p2 + */ + case PathIterator.SEG_QUADTO: + double x1 = coords[0]; + double y1 = coords[1]; + double x2, y2; + double x3 = coords[2]; + double y3 = coords[3]; + + x2 = x1 + (x3 - x1) / 3; + y2 = y1 + (y3 - y1) / 3; + x1 = currX + 2 * (x1 - currX) / 3; + y1 =currY + 2 * (y1 - currY) / 3; + + ops.addByte(CAIRO_PATH_OP_CURVE_TO); + pointIndex = points.getNextIndex(); + points.setX(pointIndex, DoubleToCairoFixed(x1)); + points.setY(pointIndex, DoubleToCairoFixed(y1)); + pointIndex = points.getNextIndex(); + points.setX(pointIndex, DoubleToCairoFixed(x2)); + points.setY(pointIndex, DoubleToCairoFixed(y2)); + pointIndex = points.getNextIndex(); + points.setX(pointIndex, DoubleToCairoFixed(x3)); + points.setY(pointIndex, DoubleToCairoFixed(y3)); + currX = x3; + currY = y3; + break; + + case PathIterator.SEG_CUBICTO: + ops.addByte(CAIRO_PATH_OP_CURVE_TO); + pointIndex = points.getNextIndex(); + points.setX(pointIndex, DoubleToCairoFixed(coords[0])); + points.setY(pointIndex, DoubleToCairoFixed(coords[1])); + pointIndex = points.getNextIndex(); + points.setX(pointIndex, DoubleToCairoFixed(coords[2])); + points.setY(pointIndex, DoubleToCairoFixed(coords[3])); + pointIndex = points.getNextIndex(); + points.setX(pointIndex, DoubleToCairoFixed(coords[4])); + points.setY(pointIndex, DoubleToCairoFixed(coords[5])); + currX = coords[4]; + currY = coords[5]; + break; + + case PathIterator.SEG_CLOSE: + ops.addByte(CAIRO_PATH_OP_CLOSE_PATH); + break; + } + + pi.next(); + } + + return pi.getWindingRule(); + } + + private static native int[] + tesselateStrokeNative(int[] pointArray, byte[] ops, + int pointCnt, int opCnt, + int[] xTrapArray, int xTrapArrayLength, + double lineWidth, int lineCap, int lineJoin, + double miterLimit, double[] dashArray, + int dashCnt, double offset, + double m00, double m01, double m02, + double m10, double m11, double m12, + int clipLowX, int clipLowY, + int clipWidth, int clipHeight); + + private static native int[] + tesselateFillNative(int[] pointArray, byte[] ops, int pointCnt, + int opCnt, int[] xTrapArray, int xTrapArrayLength, + int windingRule, int clipLowX, int clipLowY, int clipWidth, int clipHeight); + + public void clear() { + points.clear(); + ops.clear(); + xTrapArray[0] = 0; + } + + private static int DoubleToCairoFixed(double dbl) { + return (int) (dbl * 256); + } + + private static int getCairoWindingRule(int j2dWindingRule) { + switch(j2dWindingRule) { + case PathIterator.WIND_EVEN_ODD: + return CAIRO_FILL_RULE_EVEN_ODD; + + case PathIterator.WIND_NON_ZERO: + return CAIRO_FILL_RULE_WINDING; + + default: + throw new IllegalArgumentException("Illegal Java2D winding rule specified"); + } + } +} |