--- old/modules/javafx.graphics/src/main/java/com/sun/marlin/DRenderer.java 2017-04-19 21:26:33.914147386 +0200 +++ new/modules/javafx.graphics/src/main/java/com/sun/marlin/DRenderer.java 2017-04-19 21:26:33.782147371 +0200 @@ -38,10 +38,8 @@ private static final double POWER_2_TO_32 = 0x1.0p32; // use double to make tosubpix methods faster (no int to double conversion) - static final double F_SUBPIXEL_POSITIONS_X - = SUBPIXEL_POSITIONS_X; - static final double F_SUBPIXEL_POSITIONS_Y - = SUBPIXEL_POSITIONS_Y; + static final double SUBPIXEL_SCALE_X = SUBPIXEL_POSITIONS_X; + static final double SUBPIXEL_SCALE_Y = SUBPIXEL_POSITIONS_Y; static final int SUBPIXEL_MASK_X = SUBPIXEL_POSITIONS_X - 1; static final int SUBPIXEL_MASK_Y = SUBPIXEL_POSITIONS_Y - 1; @@ -68,19 +66,19 @@ // curve break into lines // cubic error in subpixels to decrement step private static final double CUB_DEC_ERR_SUBPIX - = 1d * (NORM_SUBPIXELS / 8d); // 1 pixel + = 1.0d * (NORM_SUBPIXELS / 8.0d); // 1 pixel // cubic error in subpixels to increment step private static final double CUB_INC_ERR_SUBPIX - = 0.4d * (NORM_SUBPIXELS / 8d); // 0.4 pixel + = 0.4d * (NORM_SUBPIXELS / 8.0d); // 0.4 pixel // bad paths (59294/100000 == 59,29%, 94335 bad pixels (avg = 1,59), 3966 warnings (avg = 0,07) // cubic bind length to decrement step public static final double CUB_DEC_BND - = 8d * CUB_DEC_ERR_SUBPIX; + = 8.0d * CUB_DEC_ERR_SUBPIX; // cubic bind length to increment step public static final double CUB_INC_BND - = 8d * CUB_INC_ERR_SUBPIX; + = 8.0d * CUB_INC_ERR_SUBPIX; // cubic countlg public static final int CUB_COUNT_LG = 2; @@ -91,22 +89,22 @@ // cubic count^3 = 8^countlg private static final int CUB_COUNT_3 = 1 << (3 * CUB_COUNT_LG); // cubic dt = 1 / count - private static final double CUB_INV_COUNT = 1d / CUB_COUNT; + private static final double CUB_INV_COUNT = 1.0d / CUB_COUNT; // cubic dt^2 = 1 / count^2 = 1 / 4^countlg - private static final double CUB_INV_COUNT_2 = 1d / CUB_COUNT_2; + private static final double CUB_INV_COUNT_2 = 1.0d / CUB_COUNT_2; // cubic dt^3 = 1 / count^3 = 1 / 8^countlg - private static final double CUB_INV_COUNT_3 = 1d / CUB_COUNT_3; + private static final double CUB_INV_COUNT_3 = 1.0d / CUB_COUNT_3; // quad break into lines // quadratic error in subpixels private static final double QUAD_DEC_ERR_SUBPIX - = 0.5d * (NORM_SUBPIXELS / 8d); // 0.5 pixel + = 0.5d * (NORM_SUBPIXELS / 8.0d); // 0.5 pixel // bad paths (62916/100000 == 62,92%, 103818 bad pixels (avg = 1,65), 6514 warnings (avg = 0,10) // quadratic bind length to decrement step public static final double QUAD_DEC_BND - = 8d * QUAD_DEC_ERR_SUBPIX; + = 8.0d * QUAD_DEC_ERR_SUBPIX; ////////////////////////////////////////////////////////////////////////////// // SCAN LINE @@ -177,7 +175,7 @@ while (maxDD >= _DEC_BND) { // divide step by half: - maxDD /= 4d; // error divided by 2^2 = 4 + maxDD /= 4.0d; // error divided by 2^2 = 4 count <<= 1; if (DO_STATS) { @@ -187,7 +185,7 @@ int nL = 0; // line count if (count > 1) { - final double icount = 1d / count; // dt + final double icount = 1.0d / count; // dt final double icount2 = icount * icount; // dt^2 final double ddx = c.dbx * icount2; @@ -234,8 +232,8 @@ // the dx and dy refer to forward differencing variables, not the last // coefficients of the "points" polynomial double dddx, dddy, ddx, ddy, dx, dy; - dddx = 2d * c.dax * icount3; - dddy = 2d * c.day * icount3; + dddx = 2.0d * c.dax * icount3; + dddy = 2.0d * c.day * icount3; ddx = dddx + c.dbx * icount2; ddy = dddy + c.dby * icount2; dx = c.ax * icount3 + c.bx * icount2 + c.cx * icount; @@ -251,12 +249,12 @@ while (count > 0) { // divide step by half: while (Math.abs(ddx) + Math.abs(ddy) >= _DEC_BND) { - dddx /= 8d; - dddy /= 8d; - ddx = ddx/4d - dddx; - ddy = ddy/4d - dddy; - dx = (dx - ddx) / 2d; - dy = (dy - ddy) / 2d; + dddx /= 8.0d; + dddy /= 8.0d; + ddx = ddx / 4.0d - dddx; + ddy = ddy / 4.0d - dddy; + dx = (dx - ddx) / 2.0d; + dy = (dy - ddy) / 2.0d; count <<= 1; if (DO_STATS) { @@ -265,19 +263,16 @@ } // double step: - // TODO: why use first derivative dX|Y instead of second ddX|Y ? - // both scale changes should use speed or acceleration to have the same metric. - // can only do this on even "count" values, because we must divide count by 2 while (count % 2 == 0 && Math.abs(dx) + Math.abs(dy) <= _INC_BND) { - dx = 2d * dx + ddx; - dy = 2d * dy + ddy; - ddx = 4d * (ddx + dddx); - ddy = 4d * (ddy + dddy); - dddx *= 8d; - dddy *= 8d; + dx = 2.0d * dx + ddx; + dy = 2.0d * dy + ddy; + ddx = 4.0d * (ddx + dddx); + ddy = 4.0d * (ddy + dddy); + dddx *= 8.0d; + dddy *= 8.0d; count >>= 1; if (DO_STATS) { @@ -349,7 +344,7 @@ return; } - // edge min/max X/Y are in subpixel space (inclusive) within bounds: + // edge min/max X/Y are in subpixel space (half-open interval): // note: Use integer crossings to ensure consistent range within // edgeBuckets / edgeBucketCounts arrays in case of NaN values (int = 0) if (firstCrossing < edgeMinY) { @@ -359,12 +354,9 @@ edgeMaxY = lastCrossing; } - // Use double-precision for improved accuracy: - final double x1d = x1; - final double y1d = y1; - final double slope = (x1d - x2) / (y1d - y2); + final double slope = (x1 - x2) / (y1 - y2); - if (slope >= 0.0) { // <==> x1 < x2 + if (slope >= 0.0d) { // <==> x1 < x2 if (x1 < edgeMinX) { edgeMinX = x1; } @@ -429,7 +421,7 @@ // = fixed_floor(x1_fixed + 2^31 - 1) // = fixed_floor(x1_fixed + 0x7FFFFFFF) // and error = fixed_fract(x1_fixed + 0x7FFFFFFF) - final double x1_intercept = x1d + (firstCrossing - y1d) * slope; + final double x1_intercept = x1 + (firstCrossing - y1) * slope; // inlined scalb(x1_intercept, 32): final long x1_fixed_biased = ((long) (POWER_2_TO_32 * x1_intercept)) @@ -462,7 +454,7 @@ // pointer from bucket _unsafe.putInt(addr, _edgeBuckets[bucketIdx]); addr += SIZE_INT; - // y max (inclusive) + // y max (exclusive) _unsafe.putInt(addr, lastCrossing); // Update buckets: @@ -654,12 +646,12 @@ } private static double tosubpixx(final double pix_x) { - return F_SUBPIXEL_POSITIONS_X * pix_x; + return SUBPIXEL_SCALE_X * pix_x; } private static double tosubpixy(final double pix_y) { // shift y by -0.5 for fast ceil(y - 0.5): - return F_SUBPIXEL_POSITIONS_Y * pix_y - 0.5d; + return SUBPIXEL_SCALE_Y * pix_y - 0.5d; } @Override @@ -1181,8 +1173,8 @@ if (useBlkFlags) { // flag used blocks: - _blkFlags[ pix_x >> _BLK_SIZE_LG] = 1; - _blkFlags[(pix_x + 1) >> _BLK_SIZE_LG] = 1; + // note: block processing handles extra pixel: + _blkFlags[pix_x >> _BLK_SIZE_LG] = 1; } } else { tmp = (x0 & _SUBPIXEL_MASK_X); @@ -1201,10 +1193,9 @@ if (useBlkFlags) { // flag used blocks: - _blkFlags[ pix_x >> _BLK_SIZE_LG] = 1; - _blkFlags[(pix_x + 1) >> _BLK_SIZE_LG] = 1; - _blkFlags[ pix_xmax >> _BLK_SIZE_LG] = 1; - _blkFlags[(pix_xmax + 1) >> _BLK_SIZE_LG] = 1; + // note: block processing handles extra pixel: + _blkFlags[pix_x >> _BLK_SIZE_LG] = 1; + _blkFlags[pix_xmax >> _BLK_SIZE_LG] = 1; } } } @@ -1252,8 +1243,8 @@ if (useBlkFlags) { // flag used blocks: - _blkFlags[ pix_x >> _BLK_SIZE_LG] = 1; - _blkFlags[(pix_x + 1) >> _BLK_SIZE_LG] = 1; + // note: block processing handles extra pixel: + _blkFlags[pix_x >> _BLK_SIZE_LG] = 1; } } else { tmp = (x0 & _SUBPIXEL_MASK_X); @@ -1272,10 +1263,9 @@ if (useBlkFlags) { // flag used blocks: - _blkFlags[ pix_x >> _BLK_SIZE_LG] = 1; - _blkFlags[(pix_x + 1) >> _BLK_SIZE_LG] = 1; - _blkFlags[ pix_xmax >> _BLK_SIZE_LG] = 1; - _blkFlags[(pix_xmax + 1) >> _BLK_SIZE_LG] = 1; + // note: block processing handles extra pixel: + _blkFlags[pix_x >> _BLK_SIZE_LG] = 1; + _blkFlags[pix_xmax >> _BLK_SIZE_LG] = 1; } } }