< 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 >