Skip to content

Commit

Permalink
fixed PathClipFilter (missing corner) in closePath() and pathDone()
Browse files Browse the repository at this point in the history
  • Loading branch information
bourgesl committed Oct 16, 2017
1 parent ba72458 commit 979fb54
Show file tree
Hide file tree
Showing 10 changed files with 246 additions and 98 deletions.
2 changes: 1 addition & 1 deletion pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@
<groupId>org.marlin</groupId>
<artifactId>marlin</artifactId>
<packaging>jar</packaging>
<version>0.8.1.1-Unsafe</version>
<version>0.8.1.2-Unsafe</version>
<name>Marlin software rasterizer</name>

<url>https://github.com/bourgesl/marlin-renderer</url>
Expand Down
7 changes: 0 additions & 7 deletions src/main/java/org/marlin/pisces/DHelpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -431,13 +431,6 @@ static void subdivideAt(double t, double[] src, int srcoff,

// From sun.java2d.loops.GeneralRenderer:

static final int OUTCODE_TOP = 1;
static final int OUTCODE_BOTTOM = 2;
static final int OUTCODE_LEFT = 4;
static final int OUTCODE_RIGHT = 8;
static final int OUTCODE_MASK_T_B = OUTCODE_TOP | OUTCODE_BOTTOM;
static final int OUTCODE_MASK_L_R = OUTCODE_LEFT | OUTCODE_RIGHT;

static int outcode(final double x, final double y,
final double[] clipRect)
{
Expand Down
23 changes: 10 additions & 13 deletions src/main/java/org/marlin/pisces/DMarlinRenderingEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -92,8 +92,6 @@ abstract PathIterator getNormalizingPathIterator(DRendererContext rdrCtx,

static final boolean DO_CLIP_FILL = true;

static final boolean SKIP_WINDING_RULE_EVEN_ODD = false;

/**
* Public constructor
*/
Expand Down Expand Up @@ -858,20 +856,19 @@ public AATileGenerator getAATileGenerator(Shape s,
clip.getWidth(), clip.getHeight(),
windingRule);

if (!SKIP_WINDING_RULE_EVEN_ODD) {
DPathConsumer2D pc2d = r;
DPathConsumer2D pc2d = r;

if (DO_CLIP_FILL && (windingRule == WIND_NON_ZERO) && rdrCtx.doClip) {
if (DO_TRACE_PATH) {
// trace Input:
pc2d = rdrCtx.transformerPC2D.traceInput(pc2d);
}
pc2d = rdrCtx.transformerPC2D.pathClipper(pc2d);
if (DO_CLIP_FILL && (windingRule == WIND_NON_ZERO) && rdrCtx.doClip) {
if (DO_TRACE_PATH) {
// trace Input:
pc2d = rdrCtx.transformerPC2D.traceInput(pc2d);
}

// TODO: subdivide quad/cubic curves into monotonic curves ?
pathTo(rdrCtx, pi, pc2d);
pc2d = rdrCtx.transformerPC2D.pathClipper(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(),
Expand Down
78 changes: 50 additions & 28 deletions src/main/java/org/marlin/pisces/DTransformingPathConsumer2D.java
Original file line number Diff line number Diff line change
Expand Up @@ -495,6 +495,9 @@ static final class PathClipFilter implements DPathConsumer2D {
// the current outcode of the current sub path
private int cOutCode = 0;

// the cumulated (and) outcode of the complete path
private int gOutCode = MarlinConst.OUTCODE_MASK_T_B_L_R;

private boolean outside = false;
private double cx0, cy0;

Expand Down Expand Up @@ -524,7 +527,8 @@ PathClipFilter init(final DPathConsumer2D out) {
_clipRect[2] -= margin - rdrOffX;
_clipRect[3] += margin + rdrOffX;

init_corners = true;
this.init_corners = true;
this.gOutCode = MarlinConst.OUTCODE_MASK_T_B_L_R;

return this; // fluent API
}
Expand All @@ -539,6 +543,8 @@ void dispose() {

@Override
public void pathDone() {
finishPath();

out.pathDone();

// TODO: fix possible leak if exception happened
Expand All @@ -548,35 +554,45 @@ public void pathDone() {

@Override
public void closePath() {
if (outside) {
this.outside = false;
finishPath();

if (sOutCode == 0) {
out.closePath();
this.cOutCode = sOutCode;
}

private void finishPath() {
if (outside) {
// criteria: inside or totally outside ?
if (gOutCode == 0) {
finish();
} else {
this.outside = false;
stack.reset();
}
}
out.closePath();
this.cOutCode = sOutCode;
}

private void finish() {
this.outside = false;

if (!stack.isEmpty()) {
if (init_corners) {
init_corners = false;

final double[] _corners = corners;
final double[] _clipRect = clipRect;
// Top Left (0):
corners[0] = clipRect[2];
corners[1] = clipRect[0];
_corners[0] = _clipRect[2];
_corners[1] = _clipRect[0];
// Bottom Left (1):
corners[2] = clipRect[2];
corners[3] = clipRect[1];
_corners[2] = _clipRect[2];
_corners[3] = _clipRect[1];
// Top right (2):
corners[4] = clipRect[3];
corners[5] = clipRect[0];
_corners[4] = _clipRect[3];
_corners[5] = _clipRect[0];
// Bottom Right (3):
corners[6] = clipRect[3];
corners[7] = clipRect[1];
_corners[6] = _clipRect[3];
_corners[7] = _clipRect[1];
}
stack.pullAll(corners, out);
}
Expand All @@ -601,7 +617,10 @@ public void lineTo(final double xe, final double ye) {
final int sideCode = (outcode0 & outcode1);

// basic rejection criteria:
if (sideCode != 0) {
if (sideCode == 0) {
this.gOutCode = 0;
} else {
this.gOutCode &= sideCode;
// keep last point coordinate before entering the clip again:
this.outside = true;
this.cx0 = xe;
Expand All @@ -611,7 +630,6 @@ public void lineTo(final double xe, final double ye) {
return;
}
if (outside) {
this.outside = false;
finish();
}
// clipping disabled:
Expand All @@ -624,25 +642,25 @@ private void clip(final int sideCode,
{
// corner or cross-boundary on left or right side:
if ((outcode0 != outcode1)
&& ((sideCode & DHelpers.OUTCODE_MASK_T_B) != 0))
&& ((sideCode & MarlinConst.OUTCODE_MASK_T_B) != 0))
{
// combine outcodes:
final int mergeCode = (outcode0 | outcode1);
final int tbCode = mergeCode & DHelpers.OUTCODE_MASK_T_B;
final int lrCode = mergeCode & DHelpers.OUTCODE_MASK_L_R;
// add corners to outside stack:
final int off = (lrCode == DHelpers.OUTCODE_LEFT) ? 0 : 2;
final int tbCode = mergeCode & MarlinConst.OUTCODE_MASK_T_B;
final int lrCode = mergeCode & MarlinConst.OUTCODE_MASK_L_R;
final int off = (lrCode == MarlinConst.OUTCODE_LEFT) ? 0 : 2;

// add corners to outside stack:
switch (tbCode) {
case DHelpers.OUTCODE_TOP:
case MarlinConst.OUTCODE_TOP:
stack.push(off); // top
return;
case DHelpers.OUTCODE_BOTTOM:
case MarlinConst.OUTCODE_BOTTOM:
stack.push(off + 1); // bottom
return;
default:
// both TOP / BOTTOM:
if ((outcode0 & DHelpers.OUTCODE_TOP) != 0) {
if ((outcode0 & MarlinConst.OUTCODE_TOP) != 0) {
// top to bottom
stack.push(off); // top
stack.push(off + 1); // bottom
Expand All @@ -666,9 +684,12 @@ public void curveTo(final double x1, final double y1,

int sideCode = outcode0 & outcode3;

if (sideCode != 0) {
if (sideCode == 0) {
this.gOutCode = 0;
} else {
sideCode &= DHelpers.outcode(x1, y1, clipRect);
sideCode &= DHelpers.outcode(x2, y2, clipRect);
this.gOutCode &= sideCode;

// basic rejection criteria:
if (sideCode != 0) {
Expand All @@ -682,7 +703,6 @@ public void curveTo(final double x1, final double y1,
}
}
if (outside) {
this.outside = false;
finish();
}
// clipping disabled:
Expand All @@ -699,8 +719,11 @@ public void quadTo(final double x1, final double y1,

int sideCode = outcode0 & outcode2;

if (outcode2 != 0) {
if (sideCode == 0) {
this.gOutCode = 0;
} else {
sideCode &= DHelpers.outcode(x1, y1, clipRect);
this.gOutCode &= sideCode;

// basic rejection criteria:
if (sideCode != 0) {
Expand All @@ -714,7 +737,6 @@ public void quadTo(final double x1, final double y1,
}
}
if (outside) {
this.outside = false;
finish();
}
// clipping disabled:
Expand Down
7 changes: 0 additions & 7 deletions src/main/java/org/marlin/pisces/Helpers.java
Original file line number Diff line number Diff line change
Expand Up @@ -437,13 +437,6 @@ static void subdivideAt(float t, float[] src, int srcoff,

// From sun.java2d.loops.GeneralRenderer:

static final int OUTCODE_TOP = 1;
static final int OUTCODE_BOTTOM = 2;
static final int OUTCODE_LEFT = 4;
static final int OUTCODE_RIGHT = 8;
static final int OUTCODE_MASK_T_B = OUTCODE_TOP | OUTCODE_BOTTOM;
static final int OUTCODE_MASK_L_R = OUTCODE_LEFT | OUTCODE_RIGHT;

static int outcode(final float x, final float y,
final float[] clipRect)
{
Expand Down
8 changes: 8 additions & 0 deletions src/main/java/org/marlin/pisces/MarlinConst.java
Original file line number Diff line number Diff line change
Expand Up @@ -163,4 +163,12 @@ interface MarlinConst {
*/
public static final int CAP_SQUARE = 2;

// Out codes
static final int OUTCODE_TOP = 1;
static final int OUTCODE_BOTTOM = 2;
static final int OUTCODE_LEFT = 4;
static final int OUTCODE_RIGHT = 8;
static final int OUTCODE_MASK_T_B = OUTCODE_TOP | OUTCODE_BOTTOM;
static final int OUTCODE_MASK_L_R = OUTCODE_LEFT | OUTCODE_RIGHT;
static final int OUTCODE_MASK_T_B_L_R = OUTCODE_MASK_T_B | OUTCODE_MASK_L_R;
}
25 changes: 11 additions & 14 deletions src/main/java/org/marlin/pisces/MarlinRenderingEngine.java
Original file line number Diff line number Diff line change
Expand Up @@ -93,8 +93,6 @@ abstract PathIterator getNormalizingPathIterator(RendererContext rdrCtx,

static final boolean DO_CLIP_FILL = true;

static final boolean SKIP_WINDING_RULE_EVEN_ODD = false;

/**
* Public constructor
*/
Expand Down Expand Up @@ -856,21 +854,20 @@ public AATileGenerator getAATileGenerator(Shape s,
clip.getWidth(), clip.getHeight(),
windingRule);

if (!SKIP_WINDING_RULE_EVEN_ODD) {
PathConsumer2D pc2d = r;
PathConsumer2D pc2d = r;

if (DO_CLIP_FILL && (windingRule == WIND_NON_ZERO) && rdrCtx.doClip) {
if (DO_TRACE_PATH) {
// trace Input:
pc2d = rdrCtx.transformerPC2D.traceInput(pc2d);
}
pc2d = rdrCtx.transformerPC2D.pathClipper(pc2d);
if (DO_CLIP_FILL && (windingRule == WIND_NON_ZERO) && rdrCtx.doClip) {
if (DO_TRACE_PATH) {
// trace Input:
pc2d = rdrCtx.transformerPC2D.traceInput(pc2d);
}

// TODO: subdivide quad/cubic curves into monotonic curves ?
pathTo(rdrCtx, pi, pc2d);
pc2d = rdrCtx.transformerPC2D.pathClipper(pc2d);
}
} else {

// 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(),
Expand Down
6 changes: 6 additions & 0 deletions src/main/java/org/marlin/pisces/MarlinTileGenerator.java
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@

final class MarlinTileGenerator implements AATileGenerator, MarlinConst {

private static final boolean DISABLE_BLEND = false;

private static final int MAX_TILE_ALPHA_SUM = TILE_W * TILE_H * MAX_AA_ALPHA;

private static final int TH_AA_ALPHA_FILL_EMPTY = ((MAX_AA_ALPHA + 1) / 3); // 33%
Expand Down Expand Up @@ -142,6 +144,10 @@ public int getTileHeight() {
*/
@Override
public int getTypicalAlpha() {
if (DISABLE_BLEND) {
// always return empty tiles to disable blending operations
return 0x00;
}
int al = cache.alphaSumInTile(x);
// Note: if we have a filled rectangle that doesn't end on a tile
// border, we could still return 0xff, even though al!=maxTileAlphaSum
Expand Down
Loading

0 comments on commit 979fb54

Please sign in to comment.