< prev index next >
src/java.desktop/share/classes/sun/java2d/marlin/DMarlinRenderingEngine.java
Print this page
*** 82,91 ****
--- 82,98 ----
private static final float MIN_PEN_SIZE = 1.0f / NORM_SUBPIXELS;
static final double UPPER_BND = Float.MAX_VALUE / 2.0d;
static final double 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 DMarlinRenderingEngine() {
super();
*** 131,141 ****
caps,
join,
miterlimit,
dashes,
dashphase,
! rdrCtx.transformerPC2D.wrapPath2d(p2d)
);
// Use Path2D copy constructor (trim)
return new Path2D.Double(p2d);
--- 138,148 ----
caps,
join,
miterlimit,
dashes,
dashphase,
! rdrCtx.transformerPC2D.wrapPath2D(p2d)
);
// Use Path2D copy constructor (trim)
return new Path2D.Double(p2d);
*** 193,210 ****
// recycle the DRendererContext instance
returnRendererContext(rdrCtx);
}
}
! final void strokeTo(final DRendererContext rdrCtx,
! Shape src,
! AffineTransform at,
! BasicStroke bs,
! boolean thin,
! NormMode normalize,
! boolean antialias,
! DPathConsumer2D pc2d)
{
double lw;
if (thin) {
if (antialias) {
lw = userSpaceLineWidth(at, MIN_PEN_SIZE);
--- 200,217 ----
// recycle the DRendererContext instance
returnRendererContext(rdrCtx);
}
}
! void strokeTo(final DRendererContext rdrCtx,
! Shape src,
! AffineTransform at,
! BasicStroke bs,
! boolean thin,
! NormMode normalize,
! boolean antialias,
! DPathConsumer2D pc2d)
{
double lw;
if (thin) {
if (antialias) {
lw = userSpaceLineWidth(at, MIN_PEN_SIZE);
*** 225,235 ****
bs.getDashArray(),
bs.getDashPhase(),
pc2d);
}
! private final double userSpaceLineWidth(AffineTransform at, double lw) {
double widthScale;
if (at == null) {
widthScale = 1.0d;
--- 232,242 ----
bs.getDashArray(),
bs.getDashPhase(),
pc2d);
}
! private double userSpaceLineWidth(AffineTransform at, double lw) {
double widthScale;
if (at == null) {
widthScale = 1.0d;
*** 293,313 ****
}
return (lw / widthScale);
}
! final void strokeTo(final DRendererContext rdrCtx,
! Shape src,
! AffineTransform at,
! double width,
! NormMode norm,
! int caps,
! int join,
! float miterlimit,
! float[] dashes,
! float dashphase,
! DPathConsumer2D 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 DRendererContext rdrCtx,
! Shape src,
! AffineTransform at,
! double width,
! NormMode norm,
! int caps,
! int join,
! float miterlimit,
! float[] dashes,
! float dashphase,
! DPathConsumer2D 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;
+ double scale = 1.0d;
double[] dashesD = null;
// Ensure converting dashes to double precision:
if (dashes != null) {
recycleDashes = true;
*** 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))) {
! final double scale = Math.sqrt(a*a + c*c);
if (dashesD != null) {
for (int i = 0; i < dashLen; i++) {
dashesD[i] *= scale;
}
--- 370,380 ----
// 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 = Math.sqrt(a*a + c*c);
if (dashesD != null) {
for (int i = 0; i < dashLen; i++) {
dashesD[i] *= scale;
}
*** 397,423 ****
// 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 DTransformingPathConsumer2D transformerPC2D = rdrCtx.transformerPC2D;
pc2d = transformerPC2D.deltaTransformConsumer(pc2d, strokerat);
! pc2d = rdrCtx.stroker.init(pc2d, width, caps, join, miterlimit);
if (dashesD != null) {
pc2d = rdrCtx.dasher.init(pc2d, dashesD, dashLen, dashphase,
recycleDashes);
}
pc2d = transformerPC2D.inverseDeltaTransformConsumer(pc2d, strokerat);
final PathIterator pi = norm.getNormalizingPathIterator(rdrCtx,
src.getPathIterator(at));
pathTo(rdrCtx, pi, pc2d);
--- 405,452 ----
// either at is null or it's the identity. In either case
// we don't transform the path.
at = null;
}
+ final DTransformingPathConsumer2D 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 (dashesD != null) {
pc2d = rdrCtx.dasher.init(pc2d, dashesD, 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);
*** 779,788 ****
--- 808,830 ----
MarlinTileGenerator ptg = null;
DRenderer r = null;
final DRendererContext rdrCtx = getRendererContext();
try {
+ if (DO_CLIP || (DO_CLIP_RUNTIME_ENABLE && MarlinProperties.isDoClipAtRuntime())) {
+ // Define the initial clip bounds:
+ final double[] 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;
*** 790,811 ****
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();
--- 832,871 ----
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);
!
! DPathConsumer2D 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();
*** 824,839 ****
// 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);
--- 884,899 ----
// 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);
*** 860,871 ****
DRenderer r = null;
final DRendererContext rdrCtx = getRendererContext();
try {
r = rdrCtx.renderer.init(clip.getLoX(), clip.getLoY(),
! clip.getWidth(), clip.getHeight(),
! DRenderer.WIND_EVEN_ODD);
r.moveTo( x, y);
r.lineTo( (x+dx1), (y+dy1));
r.lineTo( (x+dx1+dx2), (y+dy1+dy2));
r.lineTo( (x+dx2), (y+dy2));
--- 920,931 ----
DRenderer r = null;
final DRendererContext rdrCtx = getRendererContext();
try {
r = rdrCtx.renderer.init(clip.getLoX(), clip.getLoY(),
! clip.getWidth(), clip.getHeight(),
! WIND_EVEN_ODD);
r.moveTo( x, y);
r.lineTo( (x+dx1), (y+dy1));
r.lineTo( (x+dx1+dx2), (y+dy1+dy2));
r.lineTo( (x+dx2), (y+dy2));
*** 913,930 ****
public float getMinimumAAPenSize() {
return MIN_PEN_SIZE;
}
static {
! if (PathIterator.WIND_NON_ZERO != DRenderer.WIND_NON_ZERO ||
! PathIterator.WIND_EVEN_ODD != DRenderer.WIND_EVEN_ODD ||
! BasicStroke.JOIN_MITER != DStroker.JOIN_MITER ||
! BasicStroke.JOIN_ROUND != DStroker.JOIN_ROUND ||
! BasicStroke.JOIN_BEVEL != DStroker.JOIN_BEVEL ||
! BasicStroke.CAP_BUTT != DStroker.CAP_BUTT ||
! BasicStroke.CAP_ROUND != DStroker.CAP_ROUND ||
! BasicStroke.CAP_SQUARE != DStroker.CAP_SQUARE)
{
throw new InternalError("mismatched renderer constants");
}
}
--- 973,990 ----
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");
}
}
*** 1042,1051 ****
--- 1102,1113 ----
+ 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 >