< prev index next >

modules/javafx.graphics/src/main/java/com/sun/marlin/DRendererNoAA.java

Print this page




  46     public static final long OFF_CURX_OR  = 0;
  47     public static final long OFF_ERROR    = OFF_CURX_OR  + SIZE_INT;
  48     public static final long OFF_BUMP_X   = OFF_ERROR    + SIZE_INT;
  49     public static final long OFF_BUMP_ERR = OFF_BUMP_X   + SIZE_INT;
  50     public static final long OFF_NEXT     = OFF_BUMP_ERR + SIZE_INT;
  51     public static final long OFF_YMAX     = OFF_NEXT     + SIZE_INT;
  52 
  53     // size of one edge in bytes
  54     public static final int SIZEOF_EDGE_BYTES = (int)(OFF_YMAX + SIZE_INT);
  55 
  56     // curve break into lines
  57     // cubic error in subpixels to decrement step
  58     private static final double CUB_DEC_ERR_SUBPIX
  59         = MarlinProperties.getCubicDecD2() * (1.0d / 8.0d); // 1 pixel
  60     // cubic error in subpixels to increment step
  61     private static final double CUB_INC_ERR_SUBPIX
  62         = MarlinProperties.getCubicIncD1() * (1.0d / 8.0d); // 0.4 pixel
  63 
  64     // TestNonAARasterization (JDK-8170879): cubics
  65     // bad paths (59294/100000 == 59,29%, 94335 bad pixels (avg = 1,59), 3966 warnings (avg = 0,07)


  66 
  67     // cubic bind length to decrement step
  68     public static final double CUB_DEC_BND
  69         = 8.0d * CUB_DEC_ERR_SUBPIX;
  70     // cubic bind length to increment step
  71     public static final double CUB_INC_BND
  72         = 8.0d * CUB_INC_ERR_SUBPIX;
  73 
  74     // cubic countlg
  75     public static final int CUB_COUNT_LG = 2;
  76     // cubic count = 2^countlg
  77     private static final int CUB_COUNT = 1 << CUB_COUNT_LG;
  78     // cubic count^2 = 4^countlg
  79     private static final int CUB_COUNT_2 = 1 << (2 * CUB_COUNT_LG);
  80     // cubic count^3 = 8^countlg
  81     private static final int CUB_COUNT_3 = 1 << (3 * CUB_COUNT_LG);
  82     // cubic dt = 1 / count
  83     private static final double CUB_INV_COUNT = 1.0d / CUB_COUNT;
  84     // cubic dt^2 = 1 / count^2 = 1 / 4^countlg
  85     private static final double CUB_INV_COUNT_2 = 1.0d / CUB_COUNT_2;
  86     // cubic dt^3 = 1 / count^3 = 1 / 8^countlg
  87     private static final double CUB_INV_COUNT_3 = 1.0d / CUB_COUNT_3;
  88 
  89     // quad break into lines
  90     // quadratic error in subpixels
  91     private static final double QUAD_DEC_ERR_SUBPIX
  92         = MarlinProperties.getQuadDecD2() * (1.0d / 8.0d); // 0.5 pixel
  93 
  94     // TestNonAARasterization (JDK-8170879): quads
  95     // bad paths (62916/100000 == 62,92%, 103818 bad pixels (avg = 1,65), 6514 warnings (avg = 0,10)


  96 
  97     // quadratic bind length to decrement step
  98     public static final double QUAD_DEC_BND
  99         = 8.0d * QUAD_DEC_ERR_SUBPIX;
 100 
 101 //////////////////////////////////////////////////////////////////////////////
 102 //  SCAN LINE
 103 //////////////////////////////////////////////////////////////////////////////
 104     // crossings ie subpixel edge x coordinates
 105     private int[] crossings;
 106     // auxiliary storage for crossings (merge sort)
 107     private int[] aux_crossings;
 108 
 109     // indices into the segment pointer lists. They indicate the "active"
 110     // sublist in the segment lists (the portion of the list that contains
 111     // all the segments that cross the next scan line).
 112     private int edgeCount;
 113     private int[] edgePtrs;
 114     // auxiliary storage for edge pointers (merge sort)
 115     private int[] aux_edgePtrs;


 158                                           final DCurve c,
 159                                           final double x2, final double y2)
 160     {
 161         int count = 1; // dt = 1 / count
 162 
 163         // maximum(ddX|Y) = norm(dbx, dby) * dt^2 (= 1)
 164         double maxDD = Math.abs(c.dbx) + Math.abs(c.dby);
 165 
 166         final double _DEC_BND = QUAD_DEC_BND;
 167 
 168         while (maxDD >= _DEC_BND) {
 169             // divide step by half:
 170             maxDD /= 4.0d; // error divided by 2^2 = 4
 171 
 172             count <<= 1;
 173             if (DO_STATS) {
 174                 rdrCtx.stats.stat_rdr_quadBreak_dec.add(count);
 175             }
 176         }
 177 
 178         int nL = 0; // line count

 179         if (count > 1) {
 180             final double icount = 1.0d / count; // dt
 181             final double icount2 = icount * icount; // dt^2
 182 
 183             final double ddx = c.dbx * icount2;
 184             final double ddy = c.dby * icount2;
 185             double dx = c.bx * icount2 + c.cx * icount;
 186             double dy = c.by * icount2 + c.cy * icount;
 187 
 188             double x1, y1;
 189 
 190             while (--count > 0) {
 191                 x1 = x0 + dx;
 192                 dx += ddx;
 193                 y1 = y0 + dy;
 194                 dy += ddy;
 195 
 196                 addLine(x0, y0, x1, y1);
 197 
 198                 if (DO_STATS) { nL++; }
 199                 x0 = x1;
 200                 y0 = y1;
 201             }
 202         }
 203         addLine(x0, y0, x2, y2);
 204 
 205         if (DO_STATS) {
 206             rdrCtx.stats.stat_rdr_quadBreak.add(nL + 1);
 207         }
 208     }
 209 
 210     // x0, y0 and x3,y3 are the endpoints of the curve. We could compute these
 211     // using c.xat(0),c.yat(0) and c.xat(1),c.yat(1), but this might introduce
 212     // numerical errors, and our callers already have the exact values.
 213     // Another alternative would be to pass all the control points, and call
 214     // c.set here, but then too many numbers are passed around.
 215     private void curveBreakIntoLinesAndAdd(double x0, double y0,
 216                                            final DCurve c,
 217                                            final double x3, final double y3)
 218     {
 219         int count           = CUB_COUNT;
 220         final double icount  = CUB_INV_COUNT;   // dt
 221         final double icount2 = CUB_INV_COUNT_2; // dt^2
 222         final double icount3 = CUB_INV_COUNT_3; // dt^3
 223 
 224         // the dx and dy refer to forward differencing variables, not the last
 225         // coefficients of the "points" polynomial
 226         double dddx, dddy, ddx, ddy, dx, dy;
 227         dddx = 2.0d * c.dax * icount3;
 228         dddy = 2.0d * c.day * icount3;
 229         ddx = dddx + c.dbx * icount2;
 230         ddy = dddy + c.dby * icount2;
 231         dx = c.ax * icount3 + c.bx * icount2 + c.cx * icount;
 232         dy = c.ay * icount3 + c.by * icount2 + c.cy * icount;
 233 
 234         // we use x0, y0 to walk the line
 235         double x1 = x0, y1 = y0;
 236         int nL = 0; // line count
 237 
 238         final double _DEC_BND = CUB_DEC_BND;
 239         final double _INC_BND = CUB_INC_BND;
 240 
 241         while (count > 0) {
 242             // divide step by half:
 243             while (Math.abs(ddx) + Math.abs(ddy) >= _DEC_BND) {
 244                 dddx /= 8.0d;
 245                 dddy /= 8.0d;
 246                 ddx = ddx / 4.0d - dddx;
 247                 ddy = ddy / 4.0d - dddy;
 248                 dx = (dx - ddx) / 2.0d;
 249                 dy = (dy - ddy) / 2.0d;
 250 
 251                 count <<= 1;
 252                 if (DO_STATS) {
 253                     rdrCtx.stats.stat_rdr_curveBreak_dec.add(count);
 254                 }
 255             }
 256 
 257             // double step:
 258             // can only do this on even "count" values, because we must divide count by 2
 259             while (count % 2 == 0
 260                    && Math.abs(dx) + Math.abs(dy) <= _INC_BND)
 261             {
 262                 dx = 2.0d * dx + ddx;
 263                 dy = 2.0d * dy + ddy;
 264                 ddx = 4.0d * (ddx + dddx);
 265                 ddy = 4.0d * (ddy + dddy);
 266                 dddx *= 8.0d;
 267                 dddy *= 8.0d;
 268 
 269                 count >>= 1;
 270                 if (DO_STATS) {
 271                     rdrCtx.stats.stat_rdr_curveBreak_inc.add(count);
 272                 }
 273             }
 274             if (--count > 0) {
 275                 x1 += dx;
 276                 dx += ddx;
 277                 ddx += dddx;
 278                 y1 += dy;
 279                 dy += ddy;
 280                 ddy += dddy;
 281             } else {
 282                 x1 = x3;
 283                 y1 = y3;







 284             }
 285 
 286             addLine(x0, y0, x1, y1);





 287 
 288             if (DO_STATS) { nL++; }
 289             x0 = x1;
 290             y0 = y1;
 291         }


 292         if (DO_STATS) {
 293             rdrCtx.stats.stat_rdr_curveBreak.add(nL);
 294         }
 295     }
 296 
 297     private void addLine(double x1, double y1, double x2, double y2) {
 298         if (DO_MONITORS) {
 299             rdrCtx.stats.mon_rdr_addLine.start();
 300         }
 301         if (DO_STATS) {
 302             rdrCtx.stats.stat_rdr_addLine.add(1);
 303         }
 304         int or = 1; // orientation of the line. 1 if y increases, 0 otherwise.
 305         if (y2 < y1) {
 306             or = 0;
 307             double tmp = y2;
 308             y2 = y1;
 309             y1 = tmp;
 310             tmp = x2;
 311             x2 = x1;
 312             x1 = tmp;
 313         }


 652         this.x0 = sx;
 653         this.y0 = sy;
 654     }
 655 
 656     @Override
 657     public void lineTo(final double pix_x1, final double pix_y1) {
 658         final double x1 = tosubpixx(pix_x1);
 659         final double y1 = tosubpixy(pix_y1);
 660         addLine(x0, y0, x1, y1);
 661         x0 = x1;
 662         y0 = y1;
 663     }
 664 
 665     @Override
 666     public void curveTo(final double pix_x1, final double pix_y1,
 667                         final double pix_x2, final double pix_y2,
 668                         final double pix_x3, final double pix_y3)
 669     {
 670         final double xe = tosubpixx(pix_x3);
 671         final double ye = tosubpixy(pix_y3);
 672         curve.set(x0, y0, tosubpixx(pix_x1), tosubpixy(pix_y1),
 673                   tosubpixx(pix_x2), tosubpixy(pix_y2), xe, ye);


 674         curveBreakIntoLinesAndAdd(x0, y0, curve, xe, ye);
 675         x0 = xe;
 676         y0 = ye;
 677     }
 678 
 679     @Override
 680     public void quadTo(final double pix_x1, final double pix_y1,
 681                        final double pix_x2, final double pix_y2)
 682     {
 683         final double xe = tosubpixx(pix_x2);
 684         final double ye = tosubpixy(pix_y2);
 685         curve.set(x0, y0, tosubpixx(pix_x1), tosubpixy(pix_y1), xe, ye);


 686         quadBreakIntoLinesAndAdd(x0, y0, curve, xe, ye);
 687         x0 = xe;
 688         y0 = ye;
 689     }
 690 
 691     @Override
 692     public void closePath() {
 693         if (x0 != sx0 || y0 != sy0) {
 694             addLine(x0, y0, sx0, sy0);
 695             x0 = sx0;
 696             y0 = sy0;
 697         }
 698     }
 699 
 700     @Override
 701     public void pathDone() {
 702         closePath();
 703 
 704         // call endRendering() to determine the boundaries:
 705         endRendering();




  46     public static final long OFF_CURX_OR  = 0;
  47     public static final long OFF_ERROR    = OFF_CURX_OR  + SIZE_INT;
  48     public static final long OFF_BUMP_X   = OFF_ERROR    + SIZE_INT;
  49     public static final long OFF_BUMP_ERR = OFF_BUMP_X   + SIZE_INT;
  50     public static final long OFF_NEXT     = OFF_BUMP_ERR + SIZE_INT;
  51     public static final long OFF_YMAX     = OFF_NEXT     + SIZE_INT;
  52 
  53     // size of one edge in bytes
  54     public static final int SIZEOF_EDGE_BYTES = (int)(OFF_YMAX + SIZE_INT);
  55 
  56     // curve break into lines
  57     // cubic error in subpixels to decrement step
  58     private static final double CUB_DEC_ERR_SUBPIX
  59         = MarlinProperties.getCubicDecD2() * (1.0d / 8.0d); // 1 pixel
  60     // cubic error in subpixels to increment step
  61     private static final double CUB_INC_ERR_SUBPIX
  62         = MarlinProperties.getCubicIncD1() * (1.0d / 8.0d); // 0.4 pixel
  63 
  64     // TestNonAARasterization (JDK-8170879): cubics
  65     // bad paths (59294/100000 == 59,29%, 94335 bad pixels (avg = 1,59), 3966 warnings (avg = 0,07)
  66 // 2018
  67     // 1.0 / 0.2: bad paths (67194/100000 == 67,19%, 117394 bad pixels (avg = 1,75 - max =  9), 4042 warnings (avg = 0,06)
  68 
  69     // cubic bind length to decrement step
  70     public static final double CUB_DEC_BND
  71         = 8.0d * CUB_DEC_ERR_SUBPIX;
  72     // cubic bind length to increment step
  73     public static final double CUB_INC_BND
  74         = 8.0d * CUB_INC_ERR_SUBPIX;
  75 
  76     // cubic countlg
  77     public static final int CUB_COUNT_LG = 2;
  78     // cubic count = 2^countlg
  79     private static final int CUB_COUNT = 1 << CUB_COUNT_LG;
  80     // cubic count^2 = 4^countlg
  81     private static final int CUB_COUNT_2 = 1 << (2 * CUB_COUNT_LG);
  82     // cubic count^3 = 8^countlg
  83     private static final int CUB_COUNT_3 = 1 << (3 * CUB_COUNT_LG);
  84     // cubic dt = 1 / count
  85     private static final double CUB_INV_COUNT = 1.0d / CUB_COUNT;
  86     // cubic dt^2 = 1 / count^2 = 1 / 4^countlg
  87     private static final double CUB_INV_COUNT_2 = 1.0d / CUB_COUNT_2;
  88     // cubic dt^3 = 1 / count^3 = 1 / 8^countlg
  89     private static final double CUB_INV_COUNT_3 = 1.0d / CUB_COUNT_3;
  90 
  91     // quad break into lines
  92     // quadratic error in subpixels
  93     private static final double QUAD_DEC_ERR_SUBPIX
  94         = MarlinProperties.getQuadDecD2() * (1.0d / 8.0d); // 0.5 pixel
  95 
  96     // TestNonAARasterization (JDK-8170879): quads
  97     // bad paths (62916/100000 == 62,92%, 103818 bad pixels (avg = 1,65), 6514 warnings (avg = 0,10)
  98 // 2018
  99     // 0.50px  = bad paths (62915/100000 == 62,92%, 103810 bad pixels (avg = 1,65), 6512 warnings (avg = 0,10)
 100 
 101     // quadratic bind length to decrement step
 102     public static final double QUAD_DEC_BND
 103         = 8.0d * QUAD_DEC_ERR_SUBPIX;
 104 
 105 //////////////////////////////////////////////////////////////////////////////
 106 //  SCAN LINE
 107 //////////////////////////////////////////////////////////////////////////////
 108     // crossings ie subpixel edge x coordinates
 109     private int[] crossings;
 110     // auxiliary storage for crossings (merge sort)
 111     private int[] aux_crossings;
 112 
 113     // indices into the segment pointer lists. They indicate the "active"
 114     // sublist in the segment lists (the portion of the list that contains
 115     // all the segments that cross the next scan line).
 116     private int edgeCount;
 117     private int[] edgePtrs;
 118     // auxiliary storage for edge pointers (merge sort)
 119     private int[] aux_edgePtrs;


 162                                           final DCurve c,
 163                                           final double x2, final double y2)
 164     {
 165         int count = 1; // dt = 1 / count
 166 
 167         // maximum(ddX|Y) = norm(dbx, dby) * dt^2 (= 1)
 168         double maxDD = Math.abs(c.dbx) + Math.abs(c.dby);
 169 
 170         final double _DEC_BND = QUAD_DEC_BND;
 171 
 172         while (maxDD >= _DEC_BND) {
 173             // divide step by half:
 174             maxDD /= 4.0d; // error divided by 2^2 = 4
 175 
 176             count <<= 1;
 177             if (DO_STATS) {
 178                 rdrCtx.stats.stat_rdr_quadBreak_dec.add(count);
 179             }
 180         }
 181 
 182         final int nL = count; // line count
 183 
 184         if (count > 1) {
 185             final double icount = 1.0d / count; // dt
 186             final double icount2 = icount * icount; // dt^2
 187 
 188             final double ddx = c.dbx * icount2;
 189             final double ddy = c.dby * icount2;
 190             double dx = c.bx * icount2 + c.cx * icount;
 191             double dy = c.by * icount2 + c.cy * icount;
 192 
 193             // we use x0, y0 to walk the line
 194             for (double x1 = x0, y1 = y0; --count > 0; dx += ddx, dy += ddy) {
 195                 x1 += dx;
 196                 y1 += dy;



 197 
 198                 addLine(x0, y0, x1, y1);


 199                 x0 = x1;
 200                 y0 = y1;
 201             }
 202         }
 203         addLine(x0, y0, x2, y2);
 204 
 205         if (DO_STATS) {
 206             rdrCtx.stats.stat_rdr_quadBreak.add(nL);
 207         }
 208     }
 209 
 210     // x0, y0 and x3,y3 are the endpoints of the curve. We could compute these
 211     // using c.xat(0),c.yat(0) and c.xat(1),c.yat(1), but this might introduce
 212     // numerical errors, and our callers already have the exact values.
 213     // Another alternative would be to pass all the control points, and call
 214     // c.set here, but then too many numbers are passed around.
 215     private void curveBreakIntoLinesAndAdd(double x0, double y0,
 216                                            final DCurve c,
 217                                            final double x3, final double y3)
 218     {
 219         int count            = CUB_COUNT;
 220         final double icount  = CUB_INV_COUNT;   // dt
 221         final double icount2 = CUB_INV_COUNT_2; // dt^2
 222         final double icount3 = CUB_INV_COUNT_3; // dt^3
 223 
 224         // the dx and dy refer to forward differencing variables, not the last
 225         // coefficients of the "points" polynomial
 226         double dddx, dddy, ddx, ddy, dx, dy;
 227         dddx = 2.0d * c.dax * icount3;
 228         dddy = 2.0d * c.day * icount3;
 229         ddx = dddx + c.dbx * icount2;
 230         ddy = dddy + c.dby * icount2;
 231         dx = c.ax * icount3 + c.bx * icount2 + c.cx * icount;
 232         dy = c.ay * icount3 + c.by * icount2 + c.cy * icount;
 233 


 234         int nL = 0; // line count
 235 
 236         final double _DEC_BND = CUB_DEC_BND;
 237         final double _INC_BND = CUB_INC_BND;
 238 
 239         // we use x0, y0 to walk the line
 240         for (double x1 = x0, y1 = y0; count > 0; ) {
 241             // inc / dec => ratio ~ 5 to minimize upscale / downscale but minimize edges












 242 
 243             // double step:
 244             // can only do this on even "count" values, because we must divide count by 2
 245             while ((count % 2 == 0)
 246                     && ((Math.abs(ddx) + Math.abs(ddy)) <= _INC_BND)) {

 247                 dx = 2.0d * dx + ddx;
 248                 dy = 2.0d * dy + ddy;
 249                 ddx = 4.0d * (ddx + dddx);
 250                 ddy = 4.0d * (ddy + dddy);
 251                 dddx *= 8.0d;
 252                 dddy *= 8.0d;
 253 
 254                 count >>= 1;
 255                 if (DO_STATS) {
 256                     rdrCtx.stats.stat_rdr_curveBreak_inc.add(count);
 257                 }
 258             }
 259 
 260             // divide step by half:
 261             while ((Math.abs(ddx) + Math.abs(ddy)) >= _DEC_BND) {
 262                 dddx /= 8.0d;
 263                 dddy /= 8.0d;
 264                 ddx = ddx / 4.0d - dddx;
 265                 ddy = ddy / 4.0d - dddy;
 266                 dx = (dx - ddx) / 2.0d;
 267                 dy = (dy - ddy) / 2.0d;
 268 
 269                 count <<= 1;
 270                 if (DO_STATS) {
 271                     rdrCtx.stats.stat_rdr_curveBreak_dec.add(count);
 272                 }
 273             }
 274             if (--count == 0) {
 275                 break;
 276             }
 277 
 278             x1 += dx;
 279             y1 += dy;
 280             dx += ddx;
 281             dy += ddy;
 282             ddx += dddx;
 283             ddy += dddy;
 284 
 285             addLine(x0, y0, x1, y1);
 286             x0 = x1;
 287             y0 = y1;
 288         }
 289         addLine(x0, y0, x3, y3);
 290 
 291         if (DO_STATS) {
 292             rdrCtx.stats.stat_rdr_curveBreak.add(nL + 1);
 293         }
 294     }
 295 
 296     private void addLine(double x1, double y1, double x2, double y2) {
 297         if (DO_MONITORS) {
 298             rdrCtx.stats.mon_rdr_addLine.start();
 299         }
 300         if (DO_STATS) {
 301             rdrCtx.stats.stat_rdr_addLine.add(1);
 302         }
 303         int or = 1; // orientation of the line. 1 if y increases, 0 otherwise.
 304         if (y2 < y1) {
 305             or = 0;
 306             double tmp = y2;
 307             y2 = y1;
 308             y1 = tmp;
 309             tmp = x2;
 310             x2 = x1;
 311             x1 = tmp;
 312         }


 651         this.x0 = sx;
 652         this.y0 = sy;
 653     }
 654 
 655     @Override
 656     public void lineTo(final double pix_x1, final double pix_y1) {
 657         final double x1 = tosubpixx(pix_x1);
 658         final double y1 = tosubpixy(pix_y1);
 659         addLine(x0, y0, x1, y1);
 660         x0 = x1;
 661         y0 = y1;
 662     }
 663 
 664     @Override
 665     public void curveTo(final double pix_x1, final double pix_y1,
 666                         final double pix_x2, final double pix_y2,
 667                         final double pix_x3, final double pix_y3)
 668     {
 669         final double xe = tosubpixx(pix_x3);
 670         final double ye = tosubpixy(pix_y3);
 671         curve.set(x0, y0,
 672                 tosubpixx(pix_x1), tosubpixy(pix_y1),
 673                 tosubpixx(pix_x2), tosubpixy(pix_y2),
 674                 xe, ye);
 675         curveBreakIntoLinesAndAdd(x0, y0, curve, xe, ye);
 676         x0 = xe;
 677         y0 = ye;
 678     }
 679 
 680     @Override
 681     public void quadTo(final double pix_x1, final double pix_y1,
 682                        final double pix_x2, final double pix_y2)
 683     {
 684         final double xe = tosubpixx(pix_x2);
 685         final double ye = tosubpixy(pix_y2);
 686         curve.set(x0, y0,
 687                 tosubpixx(pix_x1), tosubpixy(pix_y1),
 688                 xe, ye);
 689         quadBreakIntoLinesAndAdd(x0, y0, curve, xe, ye);
 690         x0 = xe;
 691         y0 = ye;
 692     }
 693 
 694     @Override
 695     public void closePath() {
 696         if (x0 != sx0 || y0 != sy0) {
 697             addLine(x0, y0, sx0, sy0);
 698             x0 = sx0;
 699             y0 = sy0;
 700         }
 701     }
 702 
 703     @Override
 704     public void pathDone() {
 705         closePath();
 706 
 707         // call endRendering() to determine the boundaries:
 708         endRendering();


< prev index next >