< prev index next >

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

Print this page




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

  78     public static final float CUB_DEC_BND
  79         = 8f * CUB_DEC_ERR_SUBPIX;
  80     // cubic bind length to increment step = 8 * error in subpixels
  81     public static final float CUB_INC_BND
  82         = 8f * CUB_INC_ERR_SUBPIX;
  83 
  84     // cubic countlg
  85     public static final int CUB_COUNT_LG = 2;
  86     // cubic count = 2^countlg
  87     private static final int CUB_COUNT = 1 << CUB_COUNT_LG;
  88     // cubic count^2 = 4^countlg
  89     private static final int CUB_COUNT_2 = 1 << (2 * CUB_COUNT_LG);
  90     // cubic count^3 = 8^countlg
  91     private static final int CUB_COUNT_3 = 1 << (3 * CUB_COUNT_LG);
  92     // cubic dt = 1 / count
  93     private static final float CUB_INV_COUNT = 1f / CUB_COUNT;
  94     // cubic dt^2 = 1 / count^2 = 1 / 4^countlg
  95     private static final float CUB_INV_COUNT_2 = 1f / CUB_COUNT_2;
  96     // cubic dt^3 = 1 / count^3 = 1 / 8^countlg
  97     private static final float CUB_INV_COUNT_3 = 1f / CUB_COUNT_3;
  98 
  99     // quad break into lines
 100     // quadratic error in subpixels
 101     private static final float QUAD_DEC_ERR_SUBPIX
 102         = 1f * (NORM_SUBPIXELS / 8f); // 1 subpixel for typical 8x8 subpixels


 103 
 104     // quadratic bind length to decrement step = 8 * error in subpixels
 105     public static final float QUAD_DEC_BND
 106         = 8f * QUAD_DEC_ERR_SUBPIX;
 107 
 108 //////////////////////////////////////////////////////////////////////////////
 109 //  SCAN LINE
 110 //////////////////////////////////////////////////////////////////////////////
 111     // crossings ie subpixel edge x coordinates
 112     private int[] crossings;
 113     // auxiliary storage for crossings (merge sort)
 114     private int[] aux_crossings;
 115 
 116     // indices into the segment pointer lists. They indicate the "active"
 117     // sublist in the segment lists (the portion of the list that contains
 118     // all the segments that cross the next scan line).
 119     private int edgeCount;
 120     private int[] edgePtrs;
 121     // auxiliary storage for edge pointers (merge sort)
 122     private int[] aux_edgePtrs;


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


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




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


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


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


< prev index next >