< prev index next >

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

Print this page




 525     @Override
 526     public void lineTo(final float x1, final float y1) {
 527         lineTo(x1, y1, false);
 528     }
 529 
 530     private void lineTo(final float x1, final float y1,
 531                         final boolean force)
 532     {
 533         final int outcode0 = this.cOutCode;
 534 
 535         if (!force && clipRect != null) {
 536             final int outcode1 = Helpers.outcode(x1, y1, clipRect);
 537 
 538             // Should clip
 539             final int orCode = (outcode0 | outcode1);
 540             if (orCode != 0) {
 541                 final int sideCode = outcode0 & outcode1;
 542 
 543                 // basic rejection criteria:
 544                 if (sideCode == 0) {
 545                     // ovelap clip:
 546                     if (subdivide) {
 547                         // avoid reentrance
 548                         subdivide = false;
 549                         // subdivide curve => callback with subdivided parts:
 550                         boolean ret = curveSplitter.splitLine(cx0, cy0, x1, y1,
 551                                                               orCode, this);
 552                         // reentrance is done:
 553                         subdivide = true;
 554                         if (ret) {
 555                             return;
 556                         }
 557                     }
 558                     // already subdivided so render it
 559                 } else {
 560                     this.cOutCode = outcode1;
 561                     _moveTo(x1, y1, outcode0);
 562                     opened = true;
 563                     return;
 564                 }
 565             }


 619         // basic acceptance criteria
 620         if ((sOutCode & cOutCode) == 0) {
 621             if (cx0 != sx0 || cy0 != sy0) {
 622                 lineTo(sx0, sy0, true);
 623             }
 624 
 625             drawJoin(cdx, cdy, cx0, cy0, sdx, sdy, cmx, cmy, smx, smy, sOutCode);
 626 
 627             emitLineTo(sx0 + smx, sy0 + smy);
 628 
 629             if (opened) {
 630                 emitLineTo(sx0 - smx, sy0 - smy);
 631             } else {
 632                 emitMoveTo(sx0 - smx, sy0 - smy);
 633             }
 634         }
 635         // Ignore caps like finish(false)
 636         emitReverse();
 637 
 638         this.prev = CLOSE;



 639 
 640         if (opened) {
 641             // do not emit close
 642             opened = false;
 643         } else {
 644             emitClose();
 645         }
 646     }
 647 
 648     private void emitReverse() {
 649         reverse.popAll(out);
 650     }
 651 
 652     @Override
 653     public void pathDone() {
 654         if (prev == DRAWING_OP_TO) {
 655             finish(cOutCode);
 656         }
 657 
 658         out.pathDone();
 659 
 660         // this shouldn't matter since this object won't be used
 661         // after the call to this method.
 662         this.prev = CLOSE;
 663 
 664         // Dispose this instance:
 665         dispose();
 666     }
 667 
 668     private void finish(final int outcode) {
 669         // Problem: impossible to guess if the path will be closed in advance
 670         //          i.e. if caps must be drawn or not ?
 671         // Solution: use the ClosedPathDetector before Stroker to determine
 672         // if the path is a closed path or not
 673         if (!rdrCtx.closedPath) {


 674             if (outcode == 0) {
 675                 // current point = end's cap:
 676                 if (capStyle == CAP_ROUND) {
 677                     drawRoundCap(cx0, cy0, cmx, cmy);
 678                 } else if (capStyle == CAP_SQUARE) {
 679                     emitLineTo(cx0 - cmy + cmx, cy0 + cmx + cmy);
 680                     emitLineTo(cx0 - cmy - cmx, cy0 + cmx - cmy);
 681                 }
 682             }
 683             emitReverse();
 684 
 685             if (!capStart) {
 686                 capStart = true;
 687 
 688                 if (sOutCode == 0) {
 689                     // starting point = initial cap:
 690                     if (capStyle == CAP_ROUND) {
 691                         drawRoundCap(sx0, sy0, -smx, -smy);
 692                     } else if (capStyle == CAP_SQUARE) {
 693                         emitLineTo(sx0 + smy - smx, sy0 - smx - smy);
 694                         emitLineTo(sx0 + smy + smx, sy0 - smx + smy);
 695                     }
 696                 }
 697             }
 698         } else {
 699             emitReverse();
 700         }
 701         emitClose();
 702     }
 703 
 704     private void emitMoveTo(final float x0, final float y0) {
 705         out.moveTo(x0, y0);
 706     }
 707 
 708     private void emitLineTo(final float x1, final float y1) {
 709         out.lineTo(x1, y1);
 710     }
 711 
 712     private void emitLineToRev(final float x1, final float y1) {
 713         reverse.pushLine(x1, y1);
 714     }
 715 
 716     private void emitLineTo(final float x1, final float y1,
 717                             final boolean rev)
 718     {
 719         if (rev) {


1043 
1044     @Override
1045     public void curveTo(final float x1, final float y1,
1046                         final float x2, final float y2,
1047                         final float x3, final float y3)
1048     {
1049         final int outcode0 = this.cOutCode;
1050 
1051         if (clipRect != null) {
1052             final int outcode1 = Helpers.outcode(x1, y1, clipRect);
1053             final int outcode2 = Helpers.outcode(x2, y2, clipRect);
1054             final int outcode3 = Helpers.outcode(x3, y3, clipRect);
1055 
1056             // Should clip
1057             final int orCode = (outcode0 | outcode1 | outcode2 | outcode3);
1058             if (orCode != 0) {
1059                 final int sideCode = outcode0 & outcode1 & outcode2 & outcode3;
1060 
1061                 // basic rejection criteria:
1062                 if (sideCode == 0) {
1063                     // ovelap clip:
1064                     if (subdivide) {
1065                         // avoid reentrance
1066                         subdivide = false;
1067                         // subdivide curve => callback with subdivided parts:
1068                         boolean ret = curveSplitter.splitCurve(cx0, cy0, x1, y1,
1069                                                                x2, y2, x3, y3,
1070                                                                orCode, this);
1071                         // reentrance is done:
1072                         subdivide = true;
1073                         if (ret) {
1074                             return;
1075                         }
1076                     }
1077                     // already subdivided so render it
1078                 } else {
1079                     this.cOutCode = outcode3;
1080                     _moveTo(x3, y3, outcode0);
1081                     opened = true;
1082                     return;
1083                 }


1191         this.cmy = (l[kind - 1] - r[kind - 1]) / 2.0f;
1192     }
1193 
1194     @Override
1195     public void quadTo(final float x1, final float y1,
1196                        final float x2, final float y2)
1197     {
1198         final int outcode0 = this.cOutCode;
1199 
1200         if (clipRect != null) {
1201             final int outcode1 = Helpers.outcode(x1, y1, clipRect);
1202             final int outcode2 = Helpers.outcode(x2, y2, clipRect);
1203 
1204             // Should clip
1205             final int orCode = (outcode0 | outcode1 | outcode2);
1206             if (orCode != 0) {
1207                 final int sideCode = outcode0 & outcode1 & outcode2;
1208 
1209                 // basic rejection criteria:
1210                 if (sideCode == 0) {
1211                     // ovelap clip:
1212                     if (subdivide) {
1213                         // avoid reentrance
1214                         subdivide = false;
1215                         // subdivide curve => call lineTo() with subdivided curves:
1216                         boolean ret = curveSplitter.splitQuad(cx0, cy0, x1, y1,
1217                                                               x2, y2, orCode, this);
1218                         // reentrance is done:
1219                         subdivide = true;
1220                         if (ret) {
1221                             return;
1222                         }
1223                     }
1224                     // already subdivided so render it
1225                 } else {
1226                     this.cOutCode = outcode2;
1227                     _moveTo(x2, y2, outcode0);
1228                     opened = true;
1229                     return;
1230                 }
1231             }




 525     @Override
 526     public void lineTo(final float x1, final float y1) {
 527         lineTo(x1, y1, false);
 528     }
 529 
 530     private void lineTo(final float x1, final float y1,
 531                         final boolean force)
 532     {
 533         final int outcode0 = this.cOutCode;
 534 
 535         if (!force && clipRect != null) {
 536             final int outcode1 = Helpers.outcode(x1, y1, clipRect);
 537 
 538             // Should clip
 539             final int orCode = (outcode0 | outcode1);
 540             if (orCode != 0) {
 541                 final int sideCode = outcode0 & outcode1;
 542 
 543                 // basic rejection criteria:
 544                 if (sideCode == 0) {
 545                     // overlap clip:
 546                     if (subdivide) {
 547                         // avoid reentrance
 548                         subdivide = false;
 549                         // subdivide curve => callback with subdivided parts:
 550                         boolean ret = curveSplitter.splitLine(cx0, cy0, x1, y1,
 551                                                               orCode, this);
 552                         // reentrance is done:
 553                         subdivide = true;
 554                         if (ret) {
 555                             return;
 556                         }
 557                     }
 558                     // already subdivided so render it
 559                 } else {
 560                     this.cOutCode = outcode1;
 561                     _moveTo(x1, y1, outcode0);
 562                     opened = true;
 563                     return;
 564                 }
 565             }


 619         // basic acceptance criteria
 620         if ((sOutCode & cOutCode) == 0) {
 621             if (cx0 != sx0 || cy0 != sy0) {
 622                 lineTo(sx0, sy0, true);
 623             }
 624 
 625             drawJoin(cdx, cdy, cx0, cy0, sdx, sdy, cmx, cmy, smx, smy, sOutCode);
 626 
 627             emitLineTo(sx0 + smx, sy0 + smy);
 628 
 629             if (opened) {
 630                 emitLineTo(sx0 - smx, sy0 - smy);
 631             } else {
 632                 emitMoveTo(sx0 - smx, sy0 - smy);
 633             }
 634         }
 635         // Ignore caps like finish(false)
 636         emitReverse();
 637 
 638         this.prev = CLOSE;
 639         this.cx0 = sx0;
 640         this.cy0 = sy0;
 641         this.cOutCode = sOutCode;
 642 
 643         if (opened) {
 644             // do not emit close
 645             opened = false;
 646         } else {
 647             emitClose();
 648         }
 649     }
 650 
 651     private void emitReverse() {
 652         reverse.popAll(out);
 653     }
 654 
 655     @Override
 656     public void pathDone() {
 657         if (prev == DRAWING_OP_TO) {
 658             finish(cOutCode);
 659         }
 660 
 661         out.pathDone();
 662 
 663         // this shouldn't matter since this object won't be used
 664         // after the call to this method.
 665         this.prev = CLOSE;
 666 
 667         // Dispose this instance:
 668         dispose();
 669     }
 670 
 671     private void finish(final int outcode) {
 672         // Problem: impossible to guess if the path will be closed in advance
 673         //          i.e. if caps must be drawn or not ?
 674         // Solution: use the ClosedPathDetector before Stroker to determine
 675         // if the path is a closed path or not
 676         if (rdrCtx.closedPath) {
 677             emitReverse();
 678         } else {
 679             if (outcode == 0) {
 680                 // current point = end's cap:
 681                 if (capStyle == CAP_ROUND) {
 682                     drawRoundCap(cx0, cy0, cmx, cmy);
 683                 } else if (capStyle == CAP_SQUARE) {
 684                     emitLineTo(cx0 - cmy + cmx, cy0 + cmx + cmy);
 685                     emitLineTo(cx0 - cmy - cmx, cy0 + cmx - cmy);
 686                 }
 687             }
 688             emitReverse();
 689 
 690             if (!capStart) {
 691                 capStart = true;
 692 
 693                 if (sOutCode == 0) {
 694                     // starting point = initial cap:
 695                     if (capStyle == CAP_ROUND) {
 696                         drawRoundCap(sx0, sy0, -smx, -smy);
 697                     } else if (capStyle == CAP_SQUARE) {
 698                         emitLineTo(sx0 + smy - smx, sy0 - smx - smy);
 699                         emitLineTo(sx0 + smy + smx, sy0 - smx + smy);
 700                     }
 701                 }
 702             }


 703         }
 704         emitClose();
 705     }
 706 
 707     private void emitMoveTo(final float x0, final float y0) {
 708         out.moveTo(x0, y0);
 709     }
 710 
 711     private void emitLineTo(final float x1, final float y1) {
 712         out.lineTo(x1, y1);
 713     }
 714 
 715     private void emitLineToRev(final float x1, final float y1) {
 716         reverse.pushLine(x1, y1);
 717     }
 718 
 719     private void emitLineTo(final float x1, final float y1,
 720                             final boolean rev)
 721     {
 722         if (rev) {


1046 
1047     @Override
1048     public void curveTo(final float x1, final float y1,
1049                         final float x2, final float y2,
1050                         final float x3, final float y3)
1051     {
1052         final int outcode0 = this.cOutCode;
1053 
1054         if (clipRect != null) {
1055             final int outcode1 = Helpers.outcode(x1, y1, clipRect);
1056             final int outcode2 = Helpers.outcode(x2, y2, clipRect);
1057             final int outcode3 = Helpers.outcode(x3, y3, clipRect);
1058 
1059             // Should clip
1060             final int orCode = (outcode0 | outcode1 | outcode2 | outcode3);
1061             if (orCode != 0) {
1062                 final int sideCode = outcode0 & outcode1 & outcode2 & outcode3;
1063 
1064                 // basic rejection criteria:
1065                 if (sideCode == 0) {
1066                     // overlap clip:
1067                     if (subdivide) {
1068                         // avoid reentrance
1069                         subdivide = false;
1070                         // subdivide curve => callback with subdivided parts:
1071                         boolean ret = curveSplitter.splitCurve(cx0, cy0, x1, y1,
1072                                                                x2, y2, x3, y3,
1073                                                                orCode, this);
1074                         // reentrance is done:
1075                         subdivide = true;
1076                         if (ret) {
1077                             return;
1078                         }
1079                     }
1080                     // already subdivided so render it
1081                 } else {
1082                     this.cOutCode = outcode3;
1083                     _moveTo(x3, y3, outcode0);
1084                     opened = true;
1085                     return;
1086                 }


1194         this.cmy = (l[kind - 1] - r[kind - 1]) / 2.0f;
1195     }
1196 
1197     @Override
1198     public void quadTo(final float x1, final float y1,
1199                        final float x2, final float y2)
1200     {
1201         final int outcode0 = this.cOutCode;
1202 
1203         if (clipRect != null) {
1204             final int outcode1 = Helpers.outcode(x1, y1, clipRect);
1205             final int outcode2 = Helpers.outcode(x2, y2, clipRect);
1206 
1207             // Should clip
1208             final int orCode = (outcode0 | outcode1 | outcode2);
1209             if (orCode != 0) {
1210                 final int sideCode = outcode0 & outcode1 & outcode2;
1211 
1212                 // basic rejection criteria:
1213                 if (sideCode == 0) {
1214                     // overlap clip:
1215                     if (subdivide) {
1216                         // avoid reentrance
1217                         subdivide = false;
1218                         // subdivide curve => call lineTo() with subdivided curves:
1219                         boolean ret = curveSplitter.splitQuad(cx0, cy0, x1, y1,
1220                                                               x2, y2, orCode, this);
1221                         // reentrance is done:
1222                         subdivide = true;
1223                         if (ret) {
1224                             return;
1225                         }
1226                     }
1227                     // already subdivided so render it
1228                 } else {
1229                     this.cOutCode = outcode2;
1230                     _moveTo(x2, y2, outcode0);
1231                     opened = true;
1232                     return;
1233                 }
1234             }


< prev index next >