src/java.desktop/share/classes/sun/java2d/pipe/SpanShapeRenderer.java
changeset 47216 71c04702a3d5
parent 32865 f9cb6e427f9e
child 52248 2e330da7cbf4
equal deleted inserted replaced
47215:4ebc2e2fb97c 47216:71c04702a3d5
       
     1 /*
       
     2  * Copyright (c) 1998, 2007, 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.pipe;
       
    27 
       
    28 import sun.java2d.SunGraphics2D;
       
    29 import sun.java2d.SurfaceData;
       
    30 import java.awt.Rectangle;
       
    31 import java.awt.Shape;
       
    32 import java.awt.BasicStroke;
       
    33 import java.awt.geom.PathIterator;
       
    34 import java.awt.geom.AffineTransform;
       
    35 import java.awt.geom.Rectangle2D;
       
    36 import sun.awt.SunHints;
       
    37 
       
    38 /**
       
    39  * This class is used to convert raw geometry into a span iterator
       
    40  * object using a simple flattening polygon scan converter.
       
    41  * The iterator can be passed on to special SpanFiller loops to
       
    42  * perform the actual rendering.
       
    43  */
       
    44 public abstract class SpanShapeRenderer implements ShapeDrawPipe {
       
    45     static final RenderingEngine RenderEngine = RenderingEngine.getInstance();
       
    46 
       
    47     public static class Composite extends SpanShapeRenderer {
       
    48         CompositePipe comppipe;
       
    49 
       
    50         public Composite(CompositePipe pipe) {
       
    51             comppipe = pipe;
       
    52         }
       
    53 
       
    54         public Object startSequence(SunGraphics2D sg, Shape s,
       
    55                                     Rectangle devR, int[] bbox) {
       
    56             return comppipe.startSequence(sg, s, devR, bbox);
       
    57         }
       
    58 
       
    59         public void renderBox(Object ctx, int x, int y, int w, int h) {
       
    60             comppipe.renderPathTile(ctx, null, 0, w, x, y, w, h);
       
    61         }
       
    62 
       
    63         public void endSequence(Object ctx) {
       
    64             comppipe.endSequence(ctx);
       
    65         }
       
    66     }
       
    67 
       
    68     public static class Simple extends SpanShapeRenderer
       
    69         implements  LoopBasedPipe
       
    70     {
       
    71         public Object startSequence(SunGraphics2D sg, Shape s,
       
    72                                     Rectangle devR, int[] bbox) {
       
    73             return sg;
       
    74         }
       
    75 
       
    76         public void renderBox(Object ctx, int x, int y, int w, int h) {
       
    77             SunGraphics2D sg2d = (SunGraphics2D) ctx;
       
    78             SurfaceData sd = sg2d.getSurfaceData();
       
    79             sg2d.loops.fillRectLoop.FillRect(sg2d, sd, x, y, w, h);
       
    80         }
       
    81 
       
    82         public void endSequence(Object ctx) {
       
    83         }
       
    84     }
       
    85 
       
    86     public void draw(SunGraphics2D sg, Shape s) {
       
    87         if (sg.stroke instanceof BasicStroke) {
       
    88             ShapeSpanIterator sr = LoopPipe.getStrokeSpans(sg, s);
       
    89             try {
       
    90                 renderSpans(sg, sg.getCompClip(), s, sr);
       
    91             } finally {
       
    92                 sr.dispose();
       
    93             }
       
    94         } else {
       
    95             fill(sg, sg.stroke.createStrokedShape(s));
       
    96         }
       
    97     }
       
    98 
       
    99     public static final int NON_RECTILINEAR_TRANSFORM_MASK =
       
   100         (AffineTransform.TYPE_GENERAL_TRANSFORM |
       
   101          AffineTransform.TYPE_GENERAL_ROTATION);
       
   102 
       
   103     public void fill(SunGraphics2D sg, Shape s) {
       
   104         if (s instanceof Rectangle2D &&
       
   105             (sg.transform.getType() & NON_RECTILINEAR_TRANSFORM_MASK) == 0)
       
   106         {
       
   107             renderRect(sg, (Rectangle2D) s);
       
   108             return;
       
   109         }
       
   110 
       
   111         Region clipRegion = sg.getCompClip();
       
   112         ShapeSpanIterator sr = LoopPipe.getFillSSI(sg);
       
   113         try {
       
   114             sr.setOutputArea(clipRegion);
       
   115             sr.appendPath(s.getPathIterator(sg.transform));
       
   116             renderSpans(sg, clipRegion, s, sr);
       
   117         } finally {
       
   118             sr.dispose();
       
   119         }
       
   120     }
       
   121 
       
   122     public abstract Object startSequence(SunGraphics2D sg, Shape s,
       
   123                                          Rectangle devR, int[] bbox);
       
   124 
       
   125     public abstract void renderBox(Object ctx, int x, int y, int w, int h);
       
   126 
       
   127     public abstract void endSequence(Object ctx);
       
   128 
       
   129     public void renderRect(SunGraphics2D sg, Rectangle2D r) {
       
   130         double corners[] = {
       
   131             r.getX(), r.getY(), r.getWidth(), r.getHeight(),
       
   132         };
       
   133         corners[2] += corners[0];
       
   134         corners[3] += corners[1];
       
   135         if (corners[2] <= corners[0] || corners[3] <= corners[1]) {
       
   136             return;
       
   137         }
       
   138         sg.transform.transform(corners, 0, corners, 0, 2);
       
   139         if (corners[2] < corners[0]) {
       
   140             double t = corners[2];
       
   141             corners[2] = corners[0];
       
   142             corners[0] = t;
       
   143         }
       
   144         if (corners[3] < corners[1]) {
       
   145             double t = corners[3];
       
   146             corners[3] = corners[1];
       
   147             corners[1] = t;
       
   148         }
       
   149         int abox[] = {
       
   150             (int) corners[0],
       
   151             (int) corners[1],
       
   152             (int) corners[2],
       
   153             (int) corners[3],
       
   154         };
       
   155         Rectangle devR = new Rectangle(abox[0], abox[1],
       
   156                                        abox[2] - abox[0],
       
   157                                        abox[3] - abox[1]);
       
   158         Region clipRegion = sg.getCompClip();
       
   159         clipRegion.clipBoxToBounds(abox);
       
   160         if (abox[0] >= abox[2] || abox[1] >= abox[3]) {
       
   161             return;
       
   162         }
       
   163         Object context = startSequence(sg, r, devR, abox);
       
   164         if (clipRegion.isRectangular()) {
       
   165             renderBox(context, abox[0], abox[1],
       
   166                       abox[2] - abox[0],
       
   167                       abox[3] - abox[1]);
       
   168         } else {
       
   169             SpanIterator sr = clipRegion.getSpanIterator(abox);
       
   170             while (sr.nextSpan(abox)) {
       
   171                 renderBox(context, abox[0], abox[1],
       
   172                               abox[2] - abox[0],
       
   173                               abox[3] - abox[1]);
       
   174             }
       
   175         }
       
   176         endSequence(context);
       
   177     }
       
   178 
       
   179     public void renderSpans(SunGraphics2D sg, Region clipRegion, Shape s,
       
   180                             ShapeSpanIterator sr)
       
   181     {
       
   182         Object context = null;
       
   183         int abox[] = new int[4];
       
   184         try {
       
   185             sr.getPathBox(abox);
       
   186             Rectangle devR = new Rectangle(abox[0], abox[1],
       
   187                                            abox[2] - abox[0],
       
   188                                            abox[3] - abox[1]);
       
   189             clipRegion.clipBoxToBounds(abox);
       
   190             if (abox[0] >= abox[2] || abox[1] >= abox[3]) {
       
   191                 return;
       
   192             }
       
   193             sr.intersectClipBox(abox[0], abox[1], abox[2], abox[3]);
       
   194             context = startSequence(sg, s, devR, abox);
       
   195 
       
   196             spanClipLoop(context, sr, clipRegion, abox);
       
   197 
       
   198         } finally {
       
   199             if (context != null) {
       
   200                 endSequence(context);
       
   201             }
       
   202         }
       
   203     }
       
   204 
       
   205     public void spanClipLoop(Object ctx, SpanIterator sr,
       
   206                              Region r, int[] abox) {
       
   207         if (!r.isRectangular()) {
       
   208             sr = r.filter(sr);
       
   209         }
       
   210         while (sr.nextSpan(abox)) {
       
   211             int x = abox[0];
       
   212             int y = abox[1];
       
   213             renderBox(ctx, x, y, abox[2] - x, abox[3] - y);
       
   214         }
       
   215     }
       
   216 }