< prev index next >

src/java.desktop/share/classes/sun/java2d/marlin/MarlinRenderingEngine.java

Print this page

        

*** 83,92 **** --- 83,99 ---- private static final float MIN_PEN_SIZE = 1.0f / NORM_SUBPIXELS; static final float UPPER_BND = Float.MAX_VALUE / 2.0f; static final float LOWER_BND = -UPPER_BND; + static final boolean DO_CLIP = MarlinProperties.isDoClip(); + static final boolean DO_CLIP_FILL = true; + + static final boolean DO_TRACE_PATH = false; + + static final boolean DO_CLIP_RUNTIME_ENABLE = MarlinProperties.isDoClipRuntimeFlag(); + /** * Public constructor */ public MarlinRenderingEngine() { super();
*** 132,142 **** caps, join, miterlimit, dashes, dashphase, ! rdrCtx.transformerPC2D.wrapPath2d(p2d) ); // Use Path2D copy constructor (trim) return new Path2D.Float(p2d); --- 139,149 ---- caps, join, miterlimit, dashes, dashphase, ! rdrCtx.transformerPC2D.wrapPath2D(p2d) ); // Use Path2D copy constructor (trim) return new Path2D.Float(p2d);
*** 193,210 **** // recycle the RendererContext instance returnRendererContext(rdrCtx); } } ! final void strokeTo(final RendererContext rdrCtx, ! Shape src, ! AffineTransform at, ! BasicStroke bs, ! boolean thin, ! NormMode normalize, ! boolean antialias, ! PathConsumer2D pc2d) { float lw; if (thin) { if (antialias) { lw = userSpaceLineWidth(at, MIN_PEN_SIZE); --- 200,217 ---- // recycle the RendererContext instance returnRendererContext(rdrCtx); } } ! void strokeTo(final RendererContext rdrCtx, ! Shape src, ! AffineTransform at, ! BasicStroke bs, ! boolean thin, ! NormMode normalize, ! boolean antialias, ! PathConsumer2D pc2d) { float lw; if (thin) { if (antialias) { lw = userSpaceLineWidth(at, MIN_PEN_SIZE);
*** 225,235 **** bs.getDashArray(), bs.getDashPhase(), pc2d); } ! private final float userSpaceLineWidth(AffineTransform at, float lw) { float widthScale; if (at == null) { widthScale = 1.0f; --- 232,242 ---- bs.getDashArray(), bs.getDashPhase(), pc2d); } ! private float userSpaceLineWidth(AffineTransform at, float lw) { float widthScale; if (at == null) { widthScale = 1.0f;
*** 293,313 **** } return (lw / widthScale); } ! final void strokeTo(final RendererContext rdrCtx, ! Shape src, ! AffineTransform at, ! float width, ! NormMode norm, ! int caps, ! int join, ! float miterlimit, ! float[] dashes, ! float dashphase, ! PathConsumer2D pc2d) { // We use strokerat so that in Stroker and Dasher we can work only // with the pre-transformation coordinates. This will repeat a lot of // computations done in the path iterator, but the alternative is to // work with transformed paths and compute untransformed coordinates --- 300,320 ---- } return (lw / widthScale); } ! void strokeTo(final RendererContext rdrCtx, ! Shape src, ! AffineTransform at, ! float width, ! NormMode norm, ! int caps, ! int join, ! float miterlimit, ! float[] dashes, ! float dashphase, ! PathConsumer2D pc2d) { // We use strokerat so that in Stroker and Dasher we can work only // with the pre-transformation coordinates. This will repeat a lot of // computations done in the path iterator, but the alternative is to // work with transformed paths and compute untransformed coordinates
*** 322,331 **** --- 329,339 ---- // transformation before the path processing. AffineTransform strokerat = null; int dashLen = -1; boolean recycleDashes = false; + float scale = 1.0f; if (at != null && !at.isIdentity()) { final double a = at.getScaleX(); final double b = at.getShearX(); final double c = at.getShearY();
*** 354,364 **** // need to transform input paths to stroker and tell stroker // the scaled width. This condition is satisfied if // a*b == -c*d && a*a+c*c == b*b+d*d. In the actual check below, we // leave a bit of room for error. if (nearZero(a*b + c*d) && nearZero(a*a + c*c - (b*b + d*d))) { ! final float scale = (float) Math.sqrt(a*a + c*c); if (dashes != null) { recycleDashes = true; dashLen = dashes.length; dashes = rdrCtx.dasher.copyDashArray(dashes); --- 362,372 ---- // need to transform input paths to stroker and tell stroker // the scaled width. This condition is satisfied if // a*b == -c*d && a*a+c*c == b*b+d*d. In the actual check below, we // leave a bit of room for error. if (nearZero(a*b + c*d) && nearZero(a*a + c*c - (b*b + d*d))) { ! scale = (float) Math.sqrt(a*a + c*c); if (dashes != null) { recycleDashes = true; dashLen = dashes.length; dashes = rdrCtx.dasher.copyDashArray(dashes);
*** 392,421 **** // either at is null or it's the identity. In either case // we don't transform the path. at = null; } if (USE_SIMPLIFIER) { // Use simplifier after stroker before Renderer // to remove collinear segments (notably due to cap square) pc2d = rdrCtx.simplifier.init(pc2d); } ! final TransformingPathConsumer2D transformerPC2D = rdrCtx.transformerPC2D; pc2d = transformerPC2D.deltaTransformConsumer(pc2d, strokerat); ! pc2d = rdrCtx.stroker.init(pc2d, width, caps, join, miterlimit); if (dashes != null) { if (!recycleDashes) { dashLen = dashes.length; } pc2d = rdrCtx.dasher.init(pc2d, dashes, dashLen, dashphase, recycleDashes); } pc2d = transformerPC2D.inverseDeltaTransformConsumer(pc2d, strokerat); final PathIterator pi = norm.getNormalizingPathIterator(rdrCtx, src.getPathIterator(at)); pathTo(rdrCtx, pi, pc2d); --- 400,450 ---- // either at is null or it's the identity. In either case // we don't transform the path. at = null; } + final TransformingPathConsumer2D transformerPC2D = rdrCtx.transformerPC2D; + + if (DO_TRACE_PATH) { + // trace Stroker: + pc2d = transformerPC2D.traceStroker(pc2d); + } + if (USE_SIMPLIFIER) { // Use simplifier after stroker before Renderer // to remove collinear segments (notably due to cap square) pc2d = rdrCtx.simplifier.init(pc2d); } ! // deltaTransformConsumer may adjust the clip rectangle: pc2d = transformerPC2D.deltaTransformConsumer(pc2d, strokerat); ! // stroker will adjust the clip rectangle (width / miter limit): ! pc2d = rdrCtx.stroker.init(pc2d, width, caps, join, miterlimit, scale); if (dashes != null) { if (!recycleDashes) { dashLen = dashes.length; } pc2d = rdrCtx.dasher.init(pc2d, dashes, dashLen, dashphase, recycleDashes); + } else if (rdrCtx.doClip && (caps != Stroker.CAP_BUTT)) { + if (DO_TRACE_PATH) { + pc2d = transformerPC2D.traceClosedPathDetector(pc2d); + } + + // If no dash and clip is enabled: + // detect closedPaths (polygons) for caps + pc2d = transformerPC2D.detectClosedPath(pc2d); } pc2d = transformerPC2D.inverseDeltaTransformConsumer(pc2d, strokerat); + if (DO_TRACE_PATH) { + // trace Input: + pc2d = transformerPC2D.traceInput(pc2d); + } + final PathIterator pi = norm.getNormalizingPathIterator(rdrCtx, src.getPathIterator(at)); pathTo(rdrCtx, pi, pc2d);
*** 777,786 **** --- 806,828 ---- MarlinTileGenerator ptg = null; Renderer r = null; final RendererContext rdrCtx = getRendererContext(); try { + if (DO_CLIP || (DO_CLIP_RUNTIME_ENABLE && MarlinProperties.isDoClipAtRuntime())) { + // Define the initial clip bounds: + final float[] clipRect = rdrCtx.clipRect; + + clipRect[0] = clip.getLoY(); + clipRect[1] = clip.getLoY() + clip.getHeight(); + clipRect[2] = clip.getLoX(); + clipRect[3] = clip.getLoX() + clip.getWidth(); + + // Enable clipping: + rdrCtx.doClip = true; + } + // Test if at is identity: final AffineTransform _at = (at != null && !at.isIdentity()) ? at : null; final NormMode norm = (normalize) ? NormMode.ON_WITH_AA : NormMode.OFF;
*** 788,809 **** if (bs == null) { // fill shape: final PathIterator pi = norm.getNormalizingPathIterator(rdrCtx, s.getPathIterator(_at)); // note: Winding rule may be EvenOdd ONLY for fill operations ! r = rdrCtx.renderer.init(clip.getLoX(), clip.getLoY(), clip.getWidth(), clip.getHeight(), ! pi.getWindingRule()); // TODO: subdivide quad/cubic curves into monotonic curves ? ! pathTo(rdrCtx, pi, r); } else { // draw shape with given stroke: r = rdrCtx.renderer.init(clip.getLoX(), clip.getLoY(), clip.getWidth(), clip.getHeight(), ! PathIterator.WIND_NON_ZERO); strokeTo(rdrCtx, s, _at, bs, thin, norm, true, r); } if (r.endRendering()) { ptg = rdrCtx.ptg.init(); --- 830,869 ---- if (bs == null) { // fill shape: final PathIterator pi = norm.getNormalizingPathIterator(rdrCtx, s.getPathIterator(_at)); + final int windingRule = pi.getWindingRule(); + // note: Winding rule may be EvenOdd ONLY for fill operations ! r = rdrCtx.renderer.init(clip.getLoX(), clip.getLoY(), clip.getWidth(), clip.getHeight(), ! windingRule); ! ! PathConsumer2D pc2d = r; ! ! if (DO_CLIP_FILL && rdrCtx.doClip) { ! if (DO_TRACE_PATH) { ! // trace Filler: ! pc2d = rdrCtx.transformerPC2D.traceFiller(pc2d); ! } ! pc2d = rdrCtx.transformerPC2D.pathClipper(pc2d); ! } ! ! if (DO_TRACE_PATH) { ! // trace Input: ! pc2d = rdrCtx.transformerPC2D.traceInput(pc2d); ! } // TODO: subdivide quad/cubic curves into monotonic curves ? ! pathTo(rdrCtx, pi, pc2d); ! } else { // draw shape with given stroke: r = rdrCtx.renderer.init(clip.getLoX(), clip.getLoY(), clip.getWidth(), clip.getHeight(), ! WIND_NON_ZERO); strokeTo(rdrCtx, s, _at, bs, thin, norm, true, r); } if (r.endRendering()) { ptg = rdrCtx.ptg.init();
*** 822,837 **** // Return null to cancel AA tile generation (nothing to render) return ptg; } @Override ! public final AATileGenerator getAATileGenerator(double x, double y, ! double dx1, double dy1, ! double dx2, double dy2, ! double lw1, double lw2, ! Region clip, ! int[] bbox) { // REMIND: Deal with large coordinates! double ldx1, ldy1, ldx2, ldy2; boolean innerpgram = (lw1 > 0.0d && lw2 > 0.0d); --- 882,897 ---- // Return null to cancel AA tile generation (nothing to render) return ptg; } @Override ! public AATileGenerator getAATileGenerator(double x, double y, ! double dx1, double dy1, ! double dx2, double dy2, ! double lw1, double lw2, ! Region clip, ! int[] bbox) { // REMIND: Deal with large coordinates! double ldx1, ldy1, ldx2, ldy2; boolean innerpgram = (lw1 > 0.0d && lw2 > 0.0d);
*** 858,869 **** Renderer r = null; final RendererContext rdrCtx = getRendererContext(); try { r = rdrCtx.renderer.init(clip.getLoX(), clip.getLoY(), ! clip.getWidth(), clip.getHeight(), ! Renderer.WIND_EVEN_ODD); r.moveTo((float) x, (float) y); r.lineTo((float) (x+dx1), (float) (y+dy1)); r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2)); r.lineTo((float) (x+dx2), (float) (y+dy2)); --- 918,929 ---- Renderer r = null; final RendererContext rdrCtx = getRendererContext(); try { r = rdrCtx.renderer.init(clip.getLoX(), clip.getLoY(), ! clip.getWidth(), clip.getHeight(), ! WIND_EVEN_ODD); r.moveTo((float) x, (float) y); r.lineTo((float) (x+dx1), (float) (y+dy1)); r.lineTo((float) (x+dx1+dx2), (float) (y+dy1+dy2)); r.lineTo((float) (x+dx2), (float) (y+dy2));
*** 911,928 **** public float getMinimumAAPenSize() { return MIN_PEN_SIZE; } static { ! if (PathIterator.WIND_NON_ZERO != Renderer.WIND_NON_ZERO || ! PathIterator.WIND_EVEN_ODD != Renderer.WIND_EVEN_ODD || ! BasicStroke.JOIN_MITER != Stroker.JOIN_MITER || ! BasicStroke.JOIN_ROUND != Stroker.JOIN_ROUND || ! BasicStroke.JOIN_BEVEL != Stroker.JOIN_BEVEL || ! BasicStroke.CAP_BUTT != Stroker.CAP_BUTT || ! BasicStroke.CAP_ROUND != Stroker.CAP_ROUND || ! BasicStroke.CAP_SQUARE != Stroker.CAP_SQUARE) { throw new InternalError("mismatched renderer constants"); } } --- 971,988 ---- public float getMinimumAAPenSize() { return MIN_PEN_SIZE; } static { ! if (PathIterator.WIND_NON_ZERO != WIND_NON_ZERO || ! PathIterator.WIND_EVEN_ODD != WIND_EVEN_ODD || ! BasicStroke.JOIN_MITER != JOIN_MITER || ! BasicStroke.JOIN_ROUND != JOIN_ROUND || ! BasicStroke.JOIN_BEVEL != JOIN_BEVEL || ! BasicStroke.CAP_BUTT != CAP_BUTT || ! BasicStroke.CAP_ROUND != CAP_ROUND || ! BasicStroke.CAP_SQUARE != CAP_SQUARE) { throw new InternalError("mismatched renderer constants"); } }
*** 1043,1052 **** --- 1103,1114 ---- + MarlinCache.RLE_MIN_WIDTH); // optimisation parameters logInfo("sun.java2d.renderer.useSimplifier = " + MarlinConst.USE_SIMPLIFIER); + logInfo("sun.java2d.renderer.clip = " + + MarlinProperties.isDoClip()); // debugging parameters logInfo("sun.java2d.renderer.doStats = " + MarlinConst.DO_STATS); logInfo("sun.java2d.renderer.doMonitors = "
< prev index next >