jdk/src/java.desktop/share/classes/sun/java2d/marlin/TransformingPathConsumer2D.java
changeset 34419 14108cfd0823
parent 34417 57a3863abbb4
child 36902 bb30d89aa00e
equal deleted inserted replaced
34418:a947f6b4e0b3 34419:14108cfd0823
       
     1 /*
       
     2  * Copyright (c) 2007, 2015, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * under the terms of the GNU General Public License version 2 only, as
       
     7  * published by the Free Software Foundation.  Oracle designates this
       
     8  * particular file as subject to the "Classpath" exception as provided
       
     9  * by Oracle in the LICENSE file that accompanied this code.
       
    10  *
       
    11  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    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 sun.awt.geom.PathConsumer2D;
       
    29 import java.awt.geom.AffineTransform;
       
    30 import java.awt.geom.Path2D;
       
    31 
       
    32 final class TransformingPathConsumer2D {
       
    33 
       
    34     TransformingPathConsumer2D() {
       
    35         // used by RendererContext
       
    36     }
       
    37 
       
    38     // recycled PathConsumer2D instance from transformConsumer()
       
    39     private final Path2DWrapper        wp_Path2DWrapper        = new Path2DWrapper();
       
    40 
       
    41     PathConsumer2D wrapPath2d(Path2D.Float p2d)
       
    42     {
       
    43         return wp_Path2DWrapper.init(p2d);
       
    44     }
       
    45 
       
    46     // recycled PathConsumer2D instances from transformConsumer()
       
    47     private final TranslateFilter      tx_TranslateFilter      = new TranslateFilter();
       
    48     private final DeltaScaleFilter     tx_DeltaScaleFilter     = new DeltaScaleFilter();
       
    49     private final ScaleFilter          tx_ScaleFilter          = new ScaleFilter();
       
    50     private final DeltaTransformFilter tx_DeltaTransformFilter = new DeltaTransformFilter();
       
    51     private final TransformFilter      tx_TransformFilter      = new TransformFilter();
       
    52 
       
    53     PathConsumer2D transformConsumer(PathConsumer2D out,
       
    54                                      AffineTransform at)
       
    55     {
       
    56         if (at == null) {
       
    57             return out;
       
    58         }
       
    59         float mxx = (float) at.getScaleX();
       
    60         float mxy = (float) at.getShearX();
       
    61         float mxt = (float) at.getTranslateX();
       
    62         float myx = (float) at.getShearY();
       
    63         float myy = (float) at.getScaleY();
       
    64         float myt = (float) at.getTranslateY();
       
    65         if (mxy == 0f && myx == 0f) {
       
    66             if (mxx == 1f && myy == 1f) {
       
    67                 if (mxt == 0f && myt == 0f) {
       
    68                     return out;
       
    69                 } else {
       
    70                     return tx_TranslateFilter.init(out, mxt, myt);
       
    71                 }
       
    72             } else {
       
    73                 if (mxt == 0f && myt == 0f) {
       
    74                     return tx_DeltaScaleFilter.init(out, mxx, myy);
       
    75                 } else {
       
    76                     return tx_ScaleFilter.init(out, mxx, myy, mxt, myt);
       
    77                 }
       
    78             }
       
    79         } else if (mxt == 0f && myt == 0f) {
       
    80             return tx_DeltaTransformFilter.init(out, mxx, mxy, myx, myy);
       
    81         } else {
       
    82             return tx_TransformFilter.init(out, mxx, mxy, mxt, myx, myy, myt);
       
    83         }
       
    84     }
       
    85 
       
    86     // recycled PathConsumer2D instances from deltaTransformConsumer()
       
    87     private final DeltaScaleFilter     dt_DeltaScaleFilter     = new DeltaScaleFilter();
       
    88     private final DeltaTransformFilter dt_DeltaTransformFilter = new DeltaTransformFilter();
       
    89 
       
    90     PathConsumer2D deltaTransformConsumer(PathConsumer2D out,
       
    91                                           AffineTransform at)
       
    92     {
       
    93         if (at == null) {
       
    94             return out;
       
    95         }
       
    96         float mxx = (float) at.getScaleX();
       
    97         float mxy = (float) at.getShearX();
       
    98         float myx = (float) at.getShearY();
       
    99         float myy = (float) at.getScaleY();
       
   100         if (mxy == 0f && myx == 0f) {
       
   101             if (mxx == 1f && myy == 1f) {
       
   102                 return out;
       
   103             } else {
       
   104                 return dt_DeltaScaleFilter.init(out, mxx, myy);
       
   105             }
       
   106         } else {
       
   107             return dt_DeltaTransformFilter.init(out, mxx, mxy, myx, myy);
       
   108         }
       
   109     }
       
   110 
       
   111     // recycled PathConsumer2D instances from inverseDeltaTransformConsumer()
       
   112     private final DeltaScaleFilter     iv_DeltaScaleFilter     = new DeltaScaleFilter();
       
   113     private final DeltaTransformFilter iv_DeltaTransformFilter = new DeltaTransformFilter();
       
   114 
       
   115     PathConsumer2D inverseDeltaTransformConsumer(PathConsumer2D out,
       
   116                                                  AffineTransform at)
       
   117     {
       
   118         if (at == null) {
       
   119             return out;
       
   120         }
       
   121         float mxx = (float) at.getScaleX();
       
   122         float mxy = (float) at.getShearX();
       
   123         float myx = (float) at.getShearY();
       
   124         float myy = (float) at.getScaleY();
       
   125         if (mxy == 0f && myx == 0f) {
       
   126             if (mxx == 1f && myy == 1f) {
       
   127                 return out;
       
   128             } else {
       
   129                 return iv_DeltaScaleFilter.init(out, 1.0f/mxx, 1.0f/myy);
       
   130             }
       
   131         } else {
       
   132             float det = mxx * myy - mxy * myx;
       
   133             return iv_DeltaTransformFilter.init(out,
       
   134                                                 myy / det,
       
   135                                                -mxy / det,
       
   136                                                -myx / det,
       
   137                                                 mxx / det);
       
   138         }
       
   139     }
       
   140 
       
   141     static final class TranslateFilter implements PathConsumer2D {
       
   142         private PathConsumer2D out;
       
   143         private float tx, ty;
       
   144 
       
   145         TranslateFilter() {}
       
   146 
       
   147         TranslateFilter init(PathConsumer2D out,
       
   148                              float tx, float ty)
       
   149         {
       
   150             this.out = out;
       
   151             this.tx = tx;
       
   152             this.ty = ty;
       
   153             return this; // fluent API
       
   154         }
       
   155 
       
   156         @Override
       
   157         public void moveTo(float x0, float y0) {
       
   158             out.moveTo(x0 + tx, y0 + ty);
       
   159         }
       
   160 
       
   161         @Override
       
   162         public void lineTo(float x1, float y1) {
       
   163             out.lineTo(x1 + tx, y1 + ty);
       
   164         }
       
   165 
       
   166         @Override
       
   167         public void quadTo(float x1, float y1,
       
   168                            float x2, float y2)
       
   169         {
       
   170             out.quadTo(x1 + tx, y1 + ty,
       
   171                        x2 + tx, y2 + ty);
       
   172         }
       
   173 
       
   174         @Override
       
   175         public void curveTo(float x1, float y1,
       
   176                             float x2, float y2,
       
   177                             float x3, float y3)
       
   178         {
       
   179             out.curveTo(x1 + tx, y1 + ty,
       
   180                         x2 + tx, y2 + ty,
       
   181                         x3 + tx, y3 + ty);
       
   182         }
       
   183 
       
   184         @Override
       
   185         public void closePath() {
       
   186             out.closePath();
       
   187         }
       
   188 
       
   189         @Override
       
   190         public void pathDone() {
       
   191             out.pathDone();
       
   192         }
       
   193 
       
   194         @Override
       
   195         public long getNativeConsumer() {
       
   196             return 0;
       
   197         }
       
   198     }
       
   199 
       
   200     static final class ScaleFilter implements PathConsumer2D {
       
   201         private PathConsumer2D out;
       
   202         private float sx, sy, tx, ty;
       
   203 
       
   204         ScaleFilter() {}
       
   205 
       
   206         ScaleFilter init(PathConsumer2D out,
       
   207                          float sx, float sy,
       
   208                          float tx, float ty)
       
   209         {
       
   210             this.out = out;
       
   211             this.sx = sx;
       
   212             this.sy = sy;
       
   213             this.tx = tx;
       
   214             this.ty = ty;
       
   215             return this; // fluent API
       
   216         }
       
   217 
       
   218         @Override
       
   219         public void moveTo(float x0, float y0) {
       
   220             out.moveTo(x0 * sx + tx, y0 * sy + ty);
       
   221         }
       
   222 
       
   223         @Override
       
   224         public void lineTo(float x1, float y1) {
       
   225             out.lineTo(x1 * sx + tx, y1 * sy + ty);
       
   226         }
       
   227 
       
   228         @Override
       
   229         public void quadTo(float x1, float y1,
       
   230                            float x2, float y2)
       
   231         {
       
   232             out.quadTo(x1 * sx + tx, y1 * sy + ty,
       
   233                        x2 * sx + tx, y2 * sy + ty);
       
   234         }
       
   235 
       
   236         @Override
       
   237         public void curveTo(float x1, float y1,
       
   238                             float x2, float y2,
       
   239                             float x3, float y3)
       
   240         {
       
   241             out.curveTo(x1 * sx + tx, y1 * sy + ty,
       
   242                         x2 * sx + tx, y2 * sy + ty,
       
   243                         x3 * sx + tx, y3 * sy + ty);
       
   244         }
       
   245 
       
   246         @Override
       
   247         public void closePath() {
       
   248             out.closePath();
       
   249         }
       
   250 
       
   251         @Override
       
   252         public void pathDone() {
       
   253             out.pathDone();
       
   254         }
       
   255 
       
   256         @Override
       
   257         public long getNativeConsumer() {
       
   258             return 0;
       
   259         }
       
   260     }
       
   261 
       
   262     static final class TransformFilter implements PathConsumer2D {
       
   263         private PathConsumer2D out;
       
   264         private float mxx, mxy, mxt, myx, myy, myt;
       
   265 
       
   266         TransformFilter() {}
       
   267 
       
   268         TransformFilter init(PathConsumer2D out,
       
   269                              float mxx, float mxy, float mxt,
       
   270                              float myx, float myy, float myt)
       
   271         {
       
   272             this.out = out;
       
   273             this.mxx = mxx;
       
   274             this.mxy = mxy;
       
   275             this.mxt = mxt;
       
   276             this.myx = myx;
       
   277             this.myy = myy;
       
   278             this.myt = myt;
       
   279             return this; // fluent API
       
   280         }
       
   281 
       
   282         @Override
       
   283         public void moveTo(float x0, float y0) {
       
   284             out.moveTo(x0 * mxx + y0 * mxy + mxt,
       
   285                        x0 * myx + y0 * myy + myt);
       
   286         }
       
   287 
       
   288         @Override
       
   289         public void lineTo(float x1, float y1) {
       
   290             out.lineTo(x1 * mxx + y1 * mxy + mxt,
       
   291                        x1 * myx + y1 * myy + myt);
       
   292         }
       
   293 
       
   294         @Override
       
   295         public void quadTo(float x1, float y1,
       
   296                            float x2, float y2)
       
   297         {
       
   298             out.quadTo(x1 * mxx + y1 * mxy + mxt,
       
   299                        x1 * myx + y1 * myy + myt,
       
   300                        x2 * mxx + y2 * mxy + mxt,
       
   301                        x2 * myx + y2 * myy + myt);
       
   302         }
       
   303 
       
   304         @Override
       
   305         public void curveTo(float x1, float y1,
       
   306                             float x2, float y2,
       
   307                             float x3, float y3)
       
   308         {
       
   309             out.curveTo(x1 * mxx + y1 * mxy + mxt,
       
   310                         x1 * myx + y1 * myy + myt,
       
   311                         x2 * mxx + y2 * mxy + mxt,
       
   312                         x2 * myx + y2 * myy + myt,
       
   313                         x3 * mxx + y3 * mxy + mxt,
       
   314                         x3 * myx + y3 * myy + myt);
       
   315         }
       
   316 
       
   317         @Override
       
   318         public void closePath() {
       
   319             out.closePath();
       
   320         }
       
   321 
       
   322         @Override
       
   323         public void pathDone() {
       
   324             out.pathDone();
       
   325         }
       
   326 
       
   327         @Override
       
   328         public long getNativeConsumer() {
       
   329             return 0;
       
   330         }
       
   331     }
       
   332 
       
   333     static final class DeltaScaleFilter implements PathConsumer2D {
       
   334         private PathConsumer2D out;
       
   335         private float sx, sy;
       
   336 
       
   337         DeltaScaleFilter() {}
       
   338 
       
   339         DeltaScaleFilter init(PathConsumer2D out,
       
   340                               float mxx, float myy)
       
   341         {
       
   342             this.out = out;
       
   343             sx = mxx;
       
   344             sy = myy;
       
   345             return this; // fluent API
       
   346         }
       
   347 
       
   348         @Override
       
   349         public void moveTo(float x0, float y0) {
       
   350             out.moveTo(x0 * sx, y0 * sy);
       
   351         }
       
   352 
       
   353         @Override
       
   354         public void lineTo(float x1, float y1) {
       
   355             out.lineTo(x1 * sx, y1 * sy);
       
   356         }
       
   357 
       
   358         @Override
       
   359         public void quadTo(float x1, float y1,
       
   360                            float x2, float y2)
       
   361         {
       
   362             out.quadTo(x1 * sx, y1 * sy,
       
   363                        x2 * sx, y2 * sy);
       
   364         }
       
   365 
       
   366         @Override
       
   367         public void curveTo(float x1, float y1,
       
   368                             float x2, float y2,
       
   369                             float x3, float y3)
       
   370         {
       
   371             out.curveTo(x1 * sx, y1 * sy,
       
   372                         x2 * sx, y2 * sy,
       
   373                         x3 * sx, y3 * sy);
       
   374         }
       
   375 
       
   376         @Override
       
   377         public void closePath() {
       
   378             out.closePath();
       
   379         }
       
   380 
       
   381         @Override
       
   382         public void pathDone() {
       
   383             out.pathDone();
       
   384         }
       
   385 
       
   386         @Override
       
   387         public long getNativeConsumer() {
       
   388             return 0;
       
   389         }
       
   390     }
       
   391 
       
   392     static final class DeltaTransformFilter implements PathConsumer2D {
       
   393         private PathConsumer2D out;
       
   394         private float mxx, mxy, myx, myy;
       
   395 
       
   396         DeltaTransformFilter() {}
       
   397 
       
   398         DeltaTransformFilter init(PathConsumer2D out,
       
   399                                   float mxx, float mxy,
       
   400                                   float myx, float myy)
       
   401         {
       
   402             this.out = out;
       
   403             this.mxx = mxx;
       
   404             this.mxy = mxy;
       
   405             this.myx = myx;
       
   406             this.myy = myy;
       
   407             return this; // fluent API
       
   408         }
       
   409 
       
   410         @Override
       
   411         public void moveTo(float x0, float y0) {
       
   412             out.moveTo(x0 * mxx + y0 * mxy,
       
   413                        x0 * myx + y0 * myy);
       
   414         }
       
   415 
       
   416         @Override
       
   417         public void lineTo(float x1, float y1) {
       
   418             out.lineTo(x1 * mxx + y1 * mxy,
       
   419                        x1 * myx + y1 * myy);
       
   420         }
       
   421 
       
   422         @Override
       
   423         public void quadTo(float x1, float y1,
       
   424                            float x2, float y2)
       
   425         {
       
   426             out.quadTo(x1 * mxx + y1 * mxy,
       
   427                        x1 * myx + y1 * myy,
       
   428                        x2 * mxx + y2 * mxy,
       
   429                        x2 * myx + y2 * myy);
       
   430         }
       
   431 
       
   432         @Override
       
   433         public void curveTo(float x1, float y1,
       
   434                             float x2, float y2,
       
   435                             float x3, float y3)
       
   436         {
       
   437             out.curveTo(x1 * mxx + y1 * mxy,
       
   438                         x1 * myx + y1 * myy,
       
   439                         x2 * mxx + y2 * mxy,
       
   440                         x2 * myx + y2 * myy,
       
   441                         x3 * mxx + y3 * mxy,
       
   442                         x3 * myx + y3 * myy);
       
   443         }
       
   444 
       
   445         @Override
       
   446         public void closePath() {
       
   447             out.closePath();
       
   448         }
       
   449 
       
   450         @Override
       
   451         public void pathDone() {
       
   452             out.pathDone();
       
   453         }
       
   454 
       
   455         @Override
       
   456         public long getNativeConsumer() {
       
   457             return 0;
       
   458         }
       
   459     }
       
   460 
       
   461     static final class Path2DWrapper implements PathConsumer2D {
       
   462         private Path2D.Float p2d;
       
   463 
       
   464         Path2DWrapper() {}
       
   465 
       
   466         Path2DWrapper init(Path2D.Float p2d) {
       
   467             this.p2d = p2d;
       
   468             return this;
       
   469         }
       
   470 
       
   471         @Override
       
   472         public void moveTo(float x0, float y0) {
       
   473             p2d.moveTo(x0, y0);
       
   474         }
       
   475 
       
   476         @Override
       
   477         public void lineTo(float x1, float y1) {
       
   478             p2d.lineTo(x1, y1);
       
   479         }
       
   480 
       
   481         @Override
       
   482         public void closePath() {
       
   483             p2d.closePath();
       
   484         }
       
   485 
       
   486         @Override
       
   487         public void pathDone() {}
       
   488 
       
   489         @Override
       
   490         public void curveTo(float x1, float y1,
       
   491                             float x2, float y2,
       
   492                             float x3, float y3)
       
   493         {
       
   494             p2d.curveTo(x1, y1, x2, y2, x3, y3);
       
   495         }
       
   496 
       
   497         @Override
       
   498         public void quadTo(float x1, float y1, float x2, float y2) {
       
   499             p2d.quadTo(x1, y1, x2, y2);
       
   500         }
       
   501 
       
   502         @Override
       
   503         public long getNativeConsumer() {
       
   504             throw new InternalError("Not using a native peer");
       
   505         }
       
   506     }
       
   507 }