< prev index next >

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

Print this page




  42 
  43     // crossing capacity = edges count / 4 ~ 1024
  44     static final int INITIAL_CROSSING_COUNT = INITIAL_EDGES_COUNT >> 2;
  45 
  46     // common to all types of input path segments.
  47     // OFFSET as bytes
  48     // only integer values:
  49     public static final long OFF_CURX_OR  = 0;
  50     public static final long OFF_ERROR    = OFF_CURX_OR  + SIZE_INT;
  51     public static final long OFF_BUMP_X   = OFF_ERROR    + SIZE_INT;
  52     public static final long OFF_BUMP_ERR = OFF_BUMP_X   + SIZE_INT;
  53     public static final long OFF_NEXT     = OFF_BUMP_ERR + SIZE_INT;
  54     public static final long OFF_YMAX     = OFF_NEXT     + SIZE_INT;
  55 
  56     // size of one edge in bytes
  57     public static final int SIZEOF_EDGE_BYTES = (int)(OFF_YMAX + SIZE_INT);
  58 
  59     // curve break into lines
  60     // cubic error in subpixels to decrement step
  61     private static final float CUB_DEC_ERR_SUBPIX
  62         = 1f * (1f / 8f); // 1 pixel for typical 1x1 subpixels
  63     // cubic error in subpixels to increment step
  64     private static final float CUB_INC_ERR_SUBPIX
  65         = 0.4f * (1f / 8f); // 0.4 pixel for typical 1x1 subpixels
  66 
  67     // cubic bind length to decrement step = 8 * error in subpixels
  68     // multiply by 8 = error scale factor:

  69     public static final float CUB_DEC_BND
  70         = 8f * CUB_DEC_ERR_SUBPIX;
  71     // cubic bind length to increment step = 8 * error in subpixels
  72     public static final float CUB_INC_BND
  73         = 8f * CUB_INC_ERR_SUBPIX;
  74 
  75     // cubic countlg
  76     public static final int CUB_COUNT_LG = 2;
  77     // cubic count = 2^countlg
  78     private static final int CUB_COUNT = 1 << CUB_COUNT_LG;
  79     // cubic count^2 = 4^countlg
  80     private static final int CUB_COUNT_2 = 1 << (2 * CUB_COUNT_LG);
  81     // cubic count^3 = 8^countlg
  82     private static final int CUB_COUNT_3 = 1 << (3 * CUB_COUNT_LG);
  83     // cubic dt = 1 / count
  84     private static final float CUB_INV_COUNT = 1f / CUB_COUNT;
  85     // cubic dt^2 = 1 / count^2 = 1 / 4^countlg
  86     private static final float CUB_INV_COUNT_2 = 1f / CUB_COUNT_2;
  87     // cubic dt^3 = 1 / count^3 = 1 / 8^countlg
  88     private static final float CUB_INV_COUNT_3 = 1f / CUB_COUNT_3;
  89 
  90     // quad break into lines
  91     // quadratic error in subpixels
  92     private static final float QUAD_DEC_ERR_SUBPIX
  93         = 1f * (1f / 8f); // 1 pixel for typical 1x1 subpixels


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


 142     private int buckets_minY;
 143     private int buckets_maxY;
 144 
 145     // edgeBuckets ref (clean)
 146     private final IntArrayCache.Reference edgeBuckets_ref;
 147     // edgeBucketCounts ref (clean)
 148     private final IntArrayCache.Reference edgeBucketCounts_ref;
 149 
 150     boolean useRLE = false;
 151 
 152     // Flattens using adaptive forward differencing. This only carries out
 153     // one iteration of the AFD loop. All it does is update AFD variables (i.e.
 154     // X0, Y0, D*[X|Y], COUNT; not variables used for computing scanline crossings).
 155     private void quadBreakIntoLinesAndAdd(float x0, float y0,
 156                                           final Curve c,
 157                                           final float x2, final float y2)
 158     {
 159         int count = 1; // dt = 1 / count
 160 
 161         // maximum(ddX|Y) = norm(dbx, dby) * dt^2 (= 1)
 162         float maxDD = FloatMath.max(Math.abs(c.dbx), Math.abs(c.dby));
 163 
 164         final float _DEC_BND = QUAD_DEC_BND;
 165 
 166         while (maxDD >= _DEC_BND) {
 167             // divide step by half:
 168             maxDD /= 4f; // error divided by 2^2 = 4
 169 
 170             count <<= 1;
 171             if (DO_STATS) {
 172                 rdrCtx.stats.stat_rdr_quadBreak_dec.add(count);
 173             }
 174         }
 175 
 176         int nL = 0; // line count
 177         if (count > 1) {
 178             final float icount = 1f / count; // dt
 179             final float icount2 = icount * icount; // dt^2
 180 
 181             final float ddx = c.dbx * icount2;
 182             final float ddy = c.dby * icount2;


 221 
 222         // the dx and dy refer to forward differencing variables, not the last
 223         // coefficients of the "points" polynomial
 224         float dddx, dddy, ddx, ddy, dx, dy;
 225         dddx = 2f * c.dax * icount3;
 226         dddy = 2f * c.day * icount3;
 227         ddx = dddx + c.dbx * icount2;
 228         ddy = dddy + c.dby * icount2;
 229         dx = c.ax * icount3 + c.bx * icount2 + c.cx * icount;
 230         dy = c.ay * icount3 + c.by * icount2 + c.cy * icount;
 231 
 232         // we use x0, y0 to walk the line
 233         float x1 = x0, y1 = y0;
 234         int nL = 0; // line count
 235 
 236         final float _DEC_BND = CUB_DEC_BND;
 237         final float _INC_BND = CUB_INC_BND;
 238 
 239         while (count > 0) {
 240             // divide step by half:
 241             while (Math.abs(ddx) >= _DEC_BND || Math.abs(ddy) >= _DEC_BND) {
 242                 dddx /= 8f;
 243                 dddy /= 8f;
 244                 ddx = ddx/4f - dddx;
 245                 ddy = ddy/4f - dddy;
 246                 dx = (dx - ddx) / 2f;
 247                 dy = (dy - ddy) / 2f;
 248 
 249                 count <<= 1;
 250                 if (DO_STATS) {
 251                     rdrCtx.stats.stat_rdr_curveBreak_dec.add(count);
 252                 }
 253             }
 254 
 255             // double step:
 256             // TODO: why use first derivative dX|Y instead of second ddX|Y ?
 257             // both scale changes should use speed or acceleration to have the same metric.
 258 
 259             // can only do this on even "count" values, because we must divide count by 2
 260             while (count % 2 == 0
 261                    && Math.abs(dx) <= _INC_BND && Math.abs(dy) <= _INC_BND)
 262             {
 263                 dx = 2f * dx + ddx;
 264                 dy = 2f * dy + ddy;
 265                 ddx = 4f * (ddx + dddx);
 266                 ddy = 4f * (ddy + dddy);
 267                 dddx *= 8f;
 268                 dddy *= 8f;
 269 
 270                 count >>= 1;
 271                 if (DO_STATS) {
 272                     rdrCtx.stats.stat_rdr_curveBreak_inc.add(count);
 273                 }
 274             }
 275             if (--count > 0) {
 276                 x1 += dx;
 277                 dx += ddx;
 278                 ddx += dddx;
 279                 y1 += dy;
 280                 dy += ddy;
 281                 ddy += dddy;




  42 
  43     // crossing capacity = edges count / 4 ~ 1024
  44     static final int INITIAL_CROSSING_COUNT = INITIAL_EDGES_COUNT >> 2;
  45 
  46     // common to all types of input path segments.
  47     // OFFSET as bytes
  48     // only integer values:
  49     public static final long OFF_CURX_OR  = 0;
  50     public static final long OFF_ERROR    = OFF_CURX_OR  + SIZE_INT;
  51     public static final long OFF_BUMP_X   = OFF_ERROR    + SIZE_INT;
  52     public static final long OFF_BUMP_ERR = OFF_BUMP_X   + SIZE_INT;
  53     public static final long OFF_NEXT     = OFF_BUMP_ERR + SIZE_INT;
  54     public static final long OFF_YMAX     = OFF_NEXT     + SIZE_INT;
  55 
  56     // size of one edge in bytes
  57     public static final int SIZEOF_EDGE_BYTES = (int)(OFF_YMAX + SIZE_INT);
  58 
  59     // curve break into lines
  60     // cubic error in subpixels to decrement step
  61     private static final float CUB_DEC_ERR_SUBPIX
  62         = 1f * (1f / 8f); // 1 pixel
  63     // cubic error in subpixels to increment step
  64     private static final float CUB_INC_ERR_SUBPIX
  65         = 0.4f * (1f / 8f); // 0.4 pixel
  66 
  67     // bad paths (59294/100000 == 59,29%, 94335 bad pixels (avg = 1,59), 3966 warnings (avg = 0,07)
  68 
  69     // cubic bind length to decrement step
  70     public static final float CUB_DEC_BND
  71         = 8f * CUB_DEC_ERR_SUBPIX;
  72     // cubic bind length to increment step
  73     public static final float CUB_INC_BND
  74         = 8f * 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 float CUB_INV_COUNT = 1f / CUB_COUNT;
  86     // cubic dt^2 = 1 / count^2 = 1 / 4^countlg
  87     private static final float CUB_INV_COUNT_2 = 1f / CUB_COUNT_2;
  88     // cubic dt^3 = 1 / count^3 = 1 / 8^countlg
  89     private static final float CUB_INV_COUNT_3 = 1f / CUB_COUNT_3;
  90 
  91     // quad break into lines
  92     // quadratic error in subpixels
  93     private static final float QUAD_DEC_ERR_SUBPIX
  94         = 0.5f * (1f / 8f); // 0.5 pixel
  95 
  96     // bad paths (62916/100000 == 62,92%, 103818 bad pixels (avg = 1,65), 6514 warnings (avg = 0,10)
  97 
  98     // quadratic bind length to decrement step
  99     public static final float QUAD_DEC_BND
 100         = 8f * QUAD_DEC_ERR_SUBPIX;
 101 
 102 //////////////////////////////////////////////////////////////////////////////
 103 //  SCAN LINE
 104 //////////////////////////////////////////////////////////////////////////////
 105     // crossings ie subpixel edge x coordinates
 106     private int[] crossings;
 107     // auxiliary storage for crossings (merge sort)
 108     private int[] aux_crossings;
 109 
 110     // indices into the segment pointer lists. They indicate the "active"
 111     // sublist in the segment lists (the portion of the list that contains
 112     // all the segments that cross the next scan line).
 113     private int edgeCount;
 114     private int[] edgePtrs;
 115     // auxiliary storage for edge pointers (merge sort)
 116     private int[] aux_edgePtrs;
 117 
 118     // max used for both edgePtrs and crossings (stats only)


 145     private int buckets_minY;
 146     private int buckets_maxY;
 147 
 148     // edgeBuckets ref (clean)
 149     private final IntArrayCache.Reference edgeBuckets_ref;
 150     // edgeBucketCounts ref (clean)
 151     private final IntArrayCache.Reference edgeBucketCounts_ref;
 152 
 153     boolean useRLE = false;
 154 
 155     // Flattens using adaptive forward differencing. This only carries out
 156     // one iteration of the AFD loop. All it does is update AFD variables (i.e.
 157     // X0, Y0, D*[X|Y], COUNT; not variables used for computing scanline crossings).
 158     private void quadBreakIntoLinesAndAdd(float x0, float y0,
 159                                           final Curve c,
 160                                           final float x2, final float y2)
 161     {
 162         int count = 1; // dt = 1 / count
 163 
 164         // maximum(ddX|Y) = norm(dbx, dby) * dt^2 (= 1)
 165         float maxDD = Math.abs(c.dbx) + Math.abs(c.dby);
 166 
 167         final float _DEC_BND = QUAD_DEC_BND;
 168 
 169         while (maxDD >= _DEC_BND) {
 170             // divide step by half:
 171             maxDD /= 4f; // error divided by 2^2 = 4
 172 
 173             count <<= 1;
 174             if (DO_STATS) {
 175                 rdrCtx.stats.stat_rdr_quadBreak_dec.add(count);
 176             }
 177         }
 178 
 179         int nL = 0; // line count
 180         if (count > 1) {
 181             final float icount = 1f / count; // dt
 182             final float icount2 = icount * icount; // dt^2
 183 
 184             final float ddx = c.dbx * icount2;
 185             final float ddy = c.dby * icount2;


 224 
 225         // the dx and dy refer to forward differencing variables, not the last
 226         // coefficients of the "points" polynomial
 227         float dddx, dddy, ddx, ddy, dx, dy;
 228         dddx = 2f * c.dax * icount3;
 229         dddy = 2f * c.day * icount3;
 230         ddx = dddx + c.dbx * icount2;
 231         ddy = dddy + c.dby * icount2;
 232         dx = c.ax * icount3 + c.bx * icount2 + c.cx * icount;
 233         dy = c.ay * icount3 + c.by * icount2 + c.cy * icount;
 234 
 235         // we use x0, y0 to walk the line
 236         float x1 = x0, y1 = y0;
 237         int nL = 0; // line count
 238 
 239         final float _DEC_BND = CUB_DEC_BND;
 240         final float _INC_BND = CUB_INC_BND;
 241 
 242         while (count > 0) {
 243             // divide step by half:
 244             while (Math.abs(ddx) + Math.abs(ddy) >= _DEC_BND) {
 245                 dddx /= 8f;
 246                 dddy /= 8f;
 247                 ddx = ddx/4f - dddx;
 248                 ddy = ddy/4f - dddy;
 249                 dx = (dx - ddx) / 2f;
 250                 dy = (dy - ddy) / 2f;
 251 
 252                 count <<= 1;
 253                 if (DO_STATS) {
 254                     rdrCtx.stats.stat_rdr_curveBreak_dec.add(count);
 255                 }
 256             }
 257 
 258             // double step:
 259             // TODO: why use first derivative dX|Y instead of second ddX|Y ?
 260             // both scale changes should use speed or acceleration to have the same metric.
 261 
 262             // can only do this on even "count" values, because we must divide count by 2
 263             while (count % 2 == 0
 264                    && Math.abs(dx) + Math.abs(dy) <= _INC_BND)
 265             {
 266                 dx = 2f * dx + ddx;
 267                 dy = 2f * dy + ddy;
 268                 ddx = 4f * (ddx + dddx);
 269                 ddy = 4f * (ddy + dddy);
 270                 dddx *= 8f;
 271                 dddy *= 8f;
 272 
 273                 count >>= 1;
 274                 if (DO_STATS) {
 275                     rdrCtx.stats.stat_rdr_curveBreak_inc.add(count);
 276                 }
 277             }
 278             if (--count > 0) {
 279                 x1 += dx;
 280                 dx += ddx;
 281                 ddx += dddx;
 282                 y1 += dy;
 283                 dy += ddy;
 284                 ddy += dddy;


< prev index next >