< prev index next >
modules/javafx.graphics/src/main/java/com/sun/marlin/RendererNoAA.java
Print this page
*** 88,103 ****
private static final float CUB_INV_COUNT_3 = 1f / CUB_COUNT_3;
// quad break into lines
// quadratic error in subpixels
private static final float QUAD_DEC_ERR_SUBPIX
! = 1f * (1f / 8f); // 1 pixel for typical 1x1 subpixels
// quadratic bind length to decrement step = 8 * error in subpixels
public static final float QUAD_DEC_BND
= 8f * QUAD_DEC_ERR_SUBPIX;
//////////////////////////////////////////////////////////////////////////////
// SCAN LINE
//////////////////////////////////////////////////////////////////////////////
// crossings ie subpixel edge x coordinates
private int[] crossings;
--- 88,110 ----
private static final float CUB_INV_COUNT_3 = 1f / CUB_COUNT_3;
// quad break into lines
// quadratic error in subpixels
private static final float QUAD_DEC_ERR_SUBPIX
! = 0.5f * (1f / 8f); // 1 pixel for typical 1x1 subpixels
// quadratic bind length to decrement step = 8 * error in subpixels
public static final float QUAD_DEC_BND
= 8f * QUAD_DEC_ERR_SUBPIX;
+ public static final boolean USE_SUBDIVIDE_QUAD = false;
+ public static final int SUBDIVIDE_MAX = 30;
+
+ public static final float QUAD_ERR_SUBPIX = 1f / 16f;
+ public static final float MAX_FLAT_SQ
+ = 4f * QUAD_ERR_SUBPIX * QUAD_ERR_SUBPIX; // x4
+
//////////////////////////////////////////////////////////////////////////////
// SCAN LINE
//////////////////////////////////////////////////////////////////////////////
// crossings ie subpixel edge x coordinates
private int[] crossings;
*** 681,699 ****
x0 = xe;
y0 = ye;
}
@Override
! public void quadTo(float x1, float y1, float x2, float y2) {
! final float xe = tosubpixx(x2);
! final float ye = tosubpixy(y2);
! curve.set(x0, y0, tosubpixx(x1), tosubpixy(y1), xe, ye);
! quadBreakIntoLinesAndAdd(x0, y0, curve, xe, ye);
x0 = xe;
y0 = ye;
}
@Override
public void closePath() {
addLine(x0, y0, sx0, sy0);
x0 = sx0;
y0 = sy0;
--- 688,811 ----
x0 = xe;
y0 = ye;
}
@Override
! public void quadTo(float pix_x1, float pix_y1,
! float pix_x2, float pix_y2)
! {
! final float cx1 = tosubpixx(pix_x1);
! final float cy1 = tosubpixy(pix_y1);
!
! final float xe = tosubpixx(pix_x2);
! final float ye = tosubpixy(pix_y2);
!
! if (USE_SUBDIVIDE_QUAD) {
! subdivideQuad(0, x0, y0, cx1, cy1, xe, ye);
! } else {
! curve.set(x0, y0, cx1, cy1, xe, ye);
! quadBreakIntoLinesAndAdd(x0, y0, curve, xe, ye);
! }
x0 = xe;
y0 = ye;
}
+ void subdivideQuad(final int level,
+ final float x0, final float y0,
+ final float x1, final float y1,
+ final float x2, final float y2)
+ {
+ if (level < SUBDIVIDE_MAX) {
+
+ /* Test if the curve is flat enough for insertion. */
+
+ // use Roger Willcocks bezier flatness criterion
+ // var tolerance:Number = 4*tol*tol;
+
+ final float ux = 2f * x1 - x0 - x2;
+
+ final float uy = 2f * y1 - y0 - y2;
+
+ if (ux * ux + uy * uy > MAX_FLAT_SQ) {
+ /*
+ AGG
+ float dx = x2 - x0;
+ float dy = y2 - y0;
+ final float dist = Math.abs( (x1 - x2) * dy - (y1 - y2) * dx);
+ // TODO: check collinearity ?
+ */
+
+ // if (level == 0 || dist * dist > MAX_FLAT_SQ * (dx * dx + dy * dy)) {
+ // if (ptSegDistSq(x0, y0, x2, y2, x1, y1) > MAX_FLAT_SQ) {
+ final float cx01 = (x0 + x1) / 2.0f;
+ final float cx12 = (x1 + x2) / 2.0f;
+ final float cx012 = (cx01 + cx12) / 2.0f;
+
+ final float cy01 = (y0 + y1) / 2.0f;
+ final float cy12 = (y1 + y2) / 2.0f;
+ final float cy012 = (cy01 + cy12) / 2.0f;
+
+ subdivideQuad(level + 1, x0, y0, cx01, cy01, cx012, cy012);
+ subdivideQuad(level + 1, cx012, cy012, cx12, cy12, x2, y2);
+ return;
+ }
+ }
+
+ addLine(x0, y0, x2, y2);
+ }
+
+ public static float ptSegDistSq(float x1, float y1,
+ float x2, float y2,
+ float px, float py)
+ {
+ // Adjust vectors relative to x1,y1
+ // x2,y2 becomes relative vector from x1,y1 to end of segment
+ x2 -= x1;
+ y2 -= y1;
+ // px,py becomes relative vector from x1,y1 to test point
+ px -= x1;
+ py -= y1;
+ float dotprod = px * x2 + py * y2;
+ float projlenSq;
+ if (dotprod <= 0f) {
+ // px,py is on the side of x1,y1 away from x2,y2
+ // distance to segment is length of px,py vector
+ // "length of its (clipped) projection" is now 0.0
+ projlenSq = 0f;
+ } else {
+ // switch to backwards vectors relative to x2,y2
+ // x2,y2 are already the negative of x1,y1=>x2,y2
+ // to get px,py to be the negative of px,py=>x2,y2
+ // the dot product of two negated vectors is the same
+ // as the dot product of the two normal vectors
+ px = x2 - px;
+ py = y2 - py;
+ dotprod = px * x2 + py * y2;
+ if (dotprod <= 0f) {
+ // px,py is on the side of x2,y2 away from x1,y1
+ // distance to segment is length of (backwards) px,py vector
+ // "length of its (clipped) projection" is now 0.0
+ projlenSq = 0f;
+ } else {
+ // px,py is between x1,y1 and x2,y2
+ // dotprod is the length of the px,py vector
+ // projected on the x2,y2=>x1,y1 vector times the
+ // length of the x2,y2=>x1,y1 vector
+ projlenSq = dotprod * dotprod / (x2 * x2 + y2 * y2);
+ }
+ }
+ // Distance to line is now the length of the relative point
+ // vector minus the length of its projection onto the line
+ // (which is zero if the projection falls outside the range
+ // of the line segment).
+ float lenSq = px * px + py * py - projlenSq;
+ if (lenSq < 0f) {
+ lenSq = 0f;
+ }
+ return lenSq;
+ }
+
@Override
public void closePath() {
addLine(x0, y0, sx0, sy0);
x0 = sx0;
y0 = sy0;
< prev index next >