< prev index next >

src/java.desktop/share/classes/sun/java2d/marlin/DHelpers.java

Print this page




  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.java2d.marlin;
  27 
  28 import static java.lang.Math.PI;
  29 import static java.lang.Math.cos;
  30 import static java.lang.Math.sqrt;
  31 import static java.lang.Math.cbrt;
  32 import static java.lang.Math.acos;




  33 
  34 final class DHelpers implements MarlinConst {
  35 
  36     private DHelpers() {
  37         throw new Error("This is a non instantiable class");
  38     }
  39 
  40     static boolean within(final double x, final double y, final double err) {
  41         final double d = y - x;
  42         return (d <= err && d >= -err);
  43     }
  44 
  45     static int quadraticRoots(final double a, final double b,
  46                               final double c, double[] zeroes, final int off)
  47     {
  48         int ret = off;
  49         double t;
  50         if (a != 0.0d) {
  51             final double dis = b*b - 4*a*c;
  52             if (dis > 0.0d) {


 154 
 155     static double evalQuad(final double a, final double b,
 156                           final double c, final double t)
 157     {
 158         return t * (t * a + b) + c;
 159     }
 160 
 161     // returns the index 1 past the last valid element remaining after filtering
 162     static int filterOutNotInAB(double[] nums, final int off, final int len,
 163                                 final double a, final double b)
 164     {
 165         int ret = off;
 166         for (int i = off, end = off + len; i < end; i++) {
 167             if (nums[i] >= a && nums[i] < b) {
 168                 nums[ret++] = nums[i];
 169             }
 170         }
 171         return ret;
 172     }
 173 
 174     static double polyLineLength(double[] poly, final int off, final int nCoords) {
 175         assert nCoords % 2 == 0 && poly.length >= off + nCoords : "";
 176         double acc = 0.0d;
 177         for (int i = off + 2; i < off + nCoords; i += 2) {
 178             acc += linelen(poly[i], poly[i+1], poly[i-2], poly[i-1]);
 179         }
 180         return acc;
 181     }
 182 
 183     static double linelen(double x1, double y1, double x2, double y2) {
 184         final double dx = x2 - x1;
 185         final double dy = y2 - y1;
 186         return Math.sqrt(dx*dx + dy*dy);
 187     }
 188 
 189     static void subdivide(double[] src, int srcoff, double[] left, int leftoff,
 190                           double[] right, int rightoff, int type)
 191     {
 192         switch(type) {
 193         case 6:
 194             DHelpers.subdivideQuad(src, srcoff, left, leftoff, right, rightoff);
 195             return;
 196         case 8:
 197             DHelpers.subdivideCubic(src, srcoff, left, leftoff, right, rightoff);
 198             return;
 199         default:
 200             throw new InternalError("Unsupported curve type");
 201         }
 202     }


 414         }
 415         if (right != null) {
 416             right[rightoff + 0] = ctrlx;
 417             right[rightoff + 1] = ctrly;
 418             right[rightoff + 2] = x2;
 419             right[rightoff + 3] = y2;
 420         }
 421     }
 422 
 423     static void subdivideAt(double t, double[] src, int srcoff,
 424                             double[] left, int leftoff,
 425                             double[] right, int rightoff, int size)
 426     {
 427         switch(size) {
 428         case 8:
 429             subdivideCubicAt(t, src, srcoff, left, leftoff, right, rightoff);
 430             return;
 431         case 6:
 432             subdivideQuadAt(t, src, srcoff, left, leftoff, right, rightoff);
 433             return;























































































































































































































































































 434         }
 435     }
 436 }


  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package sun.java2d.marlin;
  27 
  28 import static java.lang.Math.PI;
  29 import static java.lang.Math.cos;
  30 import static java.lang.Math.sqrt;
  31 import static java.lang.Math.cbrt;
  32 import static java.lang.Math.acos;
  33 import java.util.Arrays;
  34 import static sun.java2d.marlin.MarlinConst.INITIAL_EDGES_COUNT;
  35 import sun.java2d.marlin.stats.Histogram;
  36 import sun.java2d.marlin.stats.StatLong;
  37 
  38 final class DHelpers implements MarlinConst {
  39 
  40     private DHelpers() {
  41         throw new Error("This is a non instantiable class");
  42     }
  43 
  44     static boolean within(final double x, final double y, final double err) {
  45         final double d = y - x;
  46         return (d <= err && d >= -err);
  47     }
  48 
  49     static int quadraticRoots(final double a, final double b,
  50                               final double c, double[] zeroes, final int off)
  51     {
  52         int ret = off;
  53         double t;
  54         if (a != 0.0d) {
  55             final double dis = b*b - 4*a*c;
  56             if (dis > 0.0d) {


 158 
 159     static double evalQuad(final double a, final double b,
 160                           final double c, final double t)
 161     {
 162         return t * (t * a + b) + c;
 163     }
 164 
 165     // returns the index 1 past the last valid element remaining after filtering
 166     static int filterOutNotInAB(double[] nums, final int off, final int len,
 167                                 final double a, final double b)
 168     {
 169         int ret = off;
 170         for (int i = off, end = off + len; i < end; i++) {
 171             if (nums[i] >= a && nums[i] < b) {
 172                 nums[ret++] = nums[i];
 173             }
 174         }
 175         return ret;
 176     }
 177 









 178     static double linelen(double x1, double y1, double x2, double y2) {
 179         final double dx = x2 - x1;
 180         final double dy = y2 - y1;
 181         return Math.sqrt(dx*dx + dy*dy);
 182     }
 183 
 184     static void subdivide(double[] src, int srcoff, double[] left, int leftoff,
 185                           double[] right, int rightoff, int type)
 186     {
 187         switch(type) {
 188         case 6:
 189             DHelpers.subdivideQuad(src, srcoff, left, leftoff, right, rightoff);
 190             return;
 191         case 8:
 192             DHelpers.subdivideCubic(src, srcoff, left, leftoff, right, rightoff);
 193             return;
 194         default:
 195             throw new InternalError("Unsupported curve type");
 196         }
 197     }


 409         }
 410         if (right != null) {
 411             right[rightoff + 0] = ctrlx;
 412             right[rightoff + 1] = ctrly;
 413             right[rightoff + 2] = x2;
 414             right[rightoff + 3] = y2;
 415         }
 416     }
 417 
 418     static void subdivideAt(double t, double[] src, int srcoff,
 419                             double[] left, int leftoff,
 420                             double[] right, int rightoff, int size)
 421     {
 422         switch(size) {
 423         case 8:
 424             subdivideCubicAt(t, src, srcoff, left, leftoff, right, rightoff);
 425             return;
 426         case 6:
 427             subdivideQuadAt(t, src, srcoff, left, leftoff, right, rightoff);
 428             return;
 429         }
 430     }
 431 
 432     // From sun.java2d.loops.GeneralRenderer:
 433 
 434     static final int OUTCODE_TOP     = 1;
 435     static final int OUTCODE_BOTTOM  = 2;
 436     static final int OUTCODE_LEFT    = 4;
 437     static final int OUTCODE_RIGHT   = 8;
 438 
 439     static int outcode(final double x, final double y,
 440                        final double[] clipRect)
 441     {
 442         int code;
 443         if (y < clipRect[0]) {
 444             code = OUTCODE_TOP;
 445         } else if (y >= clipRect[1]) {
 446             code = OUTCODE_BOTTOM;
 447         } else {
 448             code = 0;
 449         }
 450         if (x < clipRect[2]) {
 451             code |= OUTCODE_LEFT;
 452         } else if (x >= clipRect[3]) {
 453             code |= OUTCODE_RIGHT;
 454         }
 455         return code;
 456     }
 457 
 458     // a stack of polynomial curves where each curve shares endpoints with
 459     // adjacent ones.
 460     static final class PolyStack {
 461         private static final byte TYPE_LINETO  = (byte) 0;
 462         private static final byte TYPE_QUADTO  = (byte) 1;
 463         private static final byte TYPE_CUBICTO = (byte) 2;
 464 
 465         // curves capacity = edges count (8192) = edges x 2 (coords)
 466         private static final int INITIAL_CURVES_COUNT = INITIAL_EDGES_COUNT << 1;
 467 
 468         // types capacity = edges count (4096)
 469         private static final int INITIAL_TYPES_COUNT = INITIAL_EDGES_COUNT;
 470 
 471         double[] curves;
 472         int end;
 473         byte[] curveTypes;
 474         int numCurves;
 475 
 476         // curves ref (dirty)
 477         final DoubleArrayCache.Reference curves_ref;
 478         // curveTypes ref (dirty)
 479         final ByteArrayCache.Reference curveTypes_ref;
 480 
 481         // used marks (stats only)
 482         int curveTypesUseMark;
 483         int curvesUseMark;
 484 
 485         private final StatLong stat_polystack_types;
 486         private final StatLong stat_polystack_curves;
 487         private final Histogram hist_polystack_curves;
 488         private final StatLong stat_array_polystack_curves;
 489         private final StatLong stat_array_polystack_curveTypes;
 490 
 491        PolyStack(final DRendererContext rdrCtx) {
 492            this(rdrCtx, null, null, null, null, null);
 493        }
 494 
 495        PolyStack(final DRendererContext rdrCtx,
 496                  final StatLong stat_polystack_types,
 497                  final StatLong stat_polystack_curves,
 498                  final Histogram hist_polystack_curves,
 499                  final StatLong stat_array_polystack_curves,
 500                  final StatLong stat_array_polystack_curveTypes)
 501        {
 502             curves_ref = rdrCtx.newDirtyDoubleArrayRef(INITIAL_CURVES_COUNT); // 32K
 503             curves     = curves_ref.initial;
 504 
 505             curveTypes_ref = rdrCtx.newDirtyByteArrayRef(INITIAL_TYPES_COUNT); // 4K
 506             curveTypes     = curveTypes_ref.initial;
 507             numCurves = 0;
 508             end = 0;
 509 
 510             if (DO_STATS) {
 511                 curveTypesUseMark = 0;
 512                 curvesUseMark = 0;
 513             }
 514             this.stat_polystack_types = stat_polystack_types;
 515             this.stat_polystack_curves = stat_polystack_curves;
 516             this.hist_polystack_curves = hist_polystack_curves;
 517             this.stat_array_polystack_curves = stat_array_polystack_curves;
 518             this.stat_array_polystack_curveTypes = stat_array_polystack_curveTypes;
 519         }
 520 
 521         /**
 522          * Disposes this PolyStack:
 523          * clean up before reusing this instance
 524          */
 525         void dispose() {
 526             end = 0;
 527             numCurves = 0;
 528 
 529             if (DO_STATS) {
 530                 stat_polystack_types.add(curveTypesUseMark);
 531                 stat_polystack_curves.add(curvesUseMark);
 532                 hist_polystack_curves.add(curvesUseMark);
 533 
 534                 // reset marks
 535                 curveTypesUseMark = 0;
 536                 curvesUseMark = 0;
 537             }
 538 
 539             // Return arrays:
 540             // curves and curveTypes are kept dirty
 541             curves     = curves_ref.putArray(curves);
 542             curveTypes = curveTypes_ref.putArray(curveTypes);
 543         }
 544 
 545         private void ensureSpace(final int n) {
 546             // use substraction to avoid integer overflow:
 547             if (curves.length - end < n) {
 548                 if (DO_STATS) {
 549                     stat_array_polystack_curves.add(end + n);
 550                 }
 551                 curves = curves_ref.widenArray(curves, end, end + n);
 552             }
 553             if (curveTypes.length <= numCurves) {
 554                 if (DO_STATS) {
 555                     stat_array_polystack_curveTypes.add(numCurves + 1);
 556                 }
 557                 curveTypes = curveTypes_ref.widenArray(curveTypes,
 558                                                        numCurves,
 559                                                        numCurves + 1);
 560             }
 561         }
 562 
 563         void pushCubic(double x0, double y0,
 564                        double x1, double y1,
 565                        double x2, double y2)
 566         {
 567             ensureSpace(6);
 568             curveTypes[numCurves++] = TYPE_CUBICTO;
 569             // we reverse the coordinate order to make popping easier
 570             final double[] _curves = curves;
 571             int e = end;
 572             _curves[e++] = x2;    _curves[e++] = y2;
 573             _curves[e++] = x1;    _curves[e++] = y1;
 574             _curves[e++] = x0;    _curves[e++] = y0;
 575             end = e;
 576         }
 577 
 578         void pushQuad(double x0, double y0,
 579                       double x1, double y1)
 580         {
 581             ensureSpace(4);
 582             curveTypes[numCurves++] = TYPE_QUADTO;
 583             final double[] _curves = curves;
 584             int e = end;
 585             _curves[e++] = x1;    _curves[e++] = y1;
 586             _curves[e++] = x0;    _curves[e++] = y0;
 587             end = e;
 588         }
 589 
 590         void pushLine(double x, double y) {
 591             ensureSpace(2);
 592             curveTypes[numCurves++] = TYPE_LINETO;
 593             curves[end++] = x;    curves[end++] = y;
 594         }
 595 
 596         void pullAll(final DPathConsumer2D io) {
 597             final int nc = numCurves;
 598             if (nc == 0) {
 599                 return;
 600             }
 601             if (DO_STATS) {
 602                 // update used marks:
 603                 if (numCurves > curveTypesUseMark) {
 604                     curveTypesUseMark = numCurves;
 605                 }
 606                 if (end > curvesUseMark) {
 607                     curvesUseMark = end;
 608                 }
 609             }
 610             final byte[]  _curveTypes = curveTypes;
 611             final double[] _curves = curves;
 612             int e = 0;
 613 
 614             for (int i = 0; i < nc; i++) {
 615                 switch(_curveTypes[i]) {
 616                 case TYPE_LINETO:
 617                     io.lineTo(_curves[e], _curves[e+1]);
 618                     e += 2;
 619                     continue;
 620                 case TYPE_QUADTO:
 621                     io.quadTo(_curves[e+0], _curves[e+1],
 622                               _curves[e+2], _curves[e+3]);
 623                     e += 4;
 624                     continue;
 625                 case TYPE_CUBICTO:
 626                     io.curveTo(_curves[e+0], _curves[e+1],
 627                                _curves[e+2], _curves[e+3],
 628                                _curves[e+4], _curves[e+5]);
 629                     e += 6;
 630                     continue;
 631                 default:
 632                 }
 633             }
 634             numCurves = 0;
 635             end = 0;
 636         }
 637 
 638         void popAll(final DPathConsumer2D io) {
 639             int nc = numCurves;
 640             if (nc == 0) {
 641                 return;
 642             }
 643             if (DO_STATS) {
 644                 // update used marks:
 645                 if (numCurves > curveTypesUseMark) {
 646                     curveTypesUseMark = numCurves;
 647                 }
 648                 if (end > curvesUseMark) {
 649                     curvesUseMark = end;
 650                 }
 651             }
 652             final byte[]  _curveTypes = curveTypes;
 653             final double[] _curves = curves;
 654             int e  = end;
 655 
 656             while (nc != 0) {
 657                 switch(_curveTypes[--nc]) {
 658                 case TYPE_LINETO:
 659                     e -= 2;
 660                     io.lineTo(_curves[e], _curves[e+1]);
 661                     continue;
 662                 case TYPE_QUADTO:
 663                     e -= 4;
 664                     io.quadTo(_curves[e+0], _curves[e+1],
 665                               _curves[e+2], _curves[e+3]);
 666                     continue;
 667                 case TYPE_CUBICTO:
 668                     e -= 6;
 669                     io.curveTo(_curves[e+0], _curves[e+1],
 670                                _curves[e+2], _curves[e+3],
 671                                _curves[e+4], _curves[e+5]);
 672                     continue;
 673                 default:
 674                 }
 675             }
 676             numCurves = 0;
 677             end = 0;
 678         }
 679 
 680         @Override
 681         public String toString() {
 682             String ret = "";
 683             int nc = numCurves;
 684             int last = end;
 685             int len;
 686             while (nc != 0) {
 687                 switch(curveTypes[--nc]) {
 688                 case TYPE_LINETO:
 689                     len = 2;
 690                     ret += "line: ";
 691                     break;
 692                 case TYPE_QUADTO:
 693                     len = 4;
 694                     ret += "quad: ";
 695                     break;
 696                 case TYPE_CUBICTO:
 697                     len = 6;
 698                     ret += "cubic: ";
 699                     break;
 700                 default:
 701                     len = 0;
 702                 }
 703                 last -= len;
 704                 ret += Arrays.toString(Arrays.copyOfRange(curves, last, last+len))
 705                                        + "\n";
 706             }
 707             return ret;
 708         }
 709     }
 710 }
< prev index next >