src/solaris/classes/sun/java2d/x11/X11Renderer.java

Print this page




  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.x11;
  27 
  28 import java.awt.Polygon;
  29 import java.awt.Shape;
  30 import java.awt.geom.AffineTransform;
  31 import java.awt.geom.PathIterator;
  32 import java.awt.geom.Path2D;
  33 import java.awt.geom.IllegalPathStateException;
  34 import sun.awt.SunToolkit;
  35 import sun.java2d.SunGraphics2D;
  36 import sun.java2d.SurfaceData;
  37 import sun.java2d.loops.GraphicsPrimitive;
  38 import sun.java2d.pipe.Region;
  39 import sun.java2d.pipe.PixelDrawPipe;
  40 import sun.java2d.pipe.PixelFillPipe;

  41 import sun.java2d.pipe.ShapeDrawPipe;
  42 import sun.java2d.pipe.SpanIterator;
  43 import sun.java2d.pipe.ShapeSpanIterator;
  44 import sun.java2d.pipe.LoopPipe;
  45 
  46 public class X11Renderer implements
  47     PixelDrawPipe,
  48     PixelFillPipe,
  49     ShapeDrawPipe
  50 {
  51     public static X11Renderer getInstance() {
  52         return (GraphicsPrimitive.tracingEnabled()
  53                 ? new X11TracingRenderer()
  54                 : new X11Renderer());
  55     }
  56 
  57     private final long validate(SunGraphics2D sg2d) {
  58         // NOTE: getCompClip() will revalidateAll() if the
  59         // surfaceData is invalid.  This should ensure that
  60         // the clip and pixel that we are validating against
  61         // are the most current.
  62         //
  63         // The assumption is that the pipeline after that
  64         // revalidation will either be another X11 pipe


 282         try {
 283             long xgc = validate(sg2d);
 284             XFillPoly(sg2d.surfaceData.getNativeOps(), xgc,
 285                       sg2d.transX, sg2d.transY, xpoints, ypoints, npoints);
 286         } finally {
 287             SunToolkit.awtUnlock();
 288         }
 289     }
 290 
 291     native void XFillSpans(long pXSData, long xgc,
 292                            SpanIterator si, long iterator,
 293                            int transx, int transy);
 294 
 295     native void XDoPath(SunGraphics2D sg2d, long pXSData, long xgc,
 296                         int transX, int transY, Path2D.Float p2df,
 297                         boolean isFill);
 298 
 299     private void doPath(SunGraphics2D sg2d, Shape s, boolean isFill) {
 300         Path2D.Float p2df;
 301         int transx, transy;
 302         if (sg2d.transformState <= sg2d.TRANSFORM_INT_TRANSLATE) {
 303             if (s instanceof Path2D.Float) {
 304                 p2df = (Path2D.Float)s;
 305             } else {
 306                 p2df = new Path2D.Float(s);
 307             }
 308             transx = sg2d.transX;
 309             transy = sg2d.transY;
 310         } else {
 311             p2df = new Path2D.Float(s, sg2d.transform);
 312             transx = 0;
 313             transy = 0;
 314         }
 315         SunToolkit.awtLock();
 316         try {
 317             long xgc = validate(sg2d);
 318             XDoPath(sg2d, sg2d.surfaceData.getNativeOps(), xgc,
 319                     transx, transy, p2df, isFill);
 320         } finally {
 321             SunToolkit.awtUnlock();
 322         }
 323     }
 324 
 325     public void draw(SunGraphics2D sg2d, Shape s) {
 326         if (sg2d.strokeState == sg2d.STROKE_THIN) {
 327             // Delegate to drawPolygon() if possible...
 328             if (s instanceof Polygon &&
 329                 sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE)
 330             {
 331                 Polygon p = (Polygon) s;
 332                 drawPolygon(sg2d, p.xpoints, p.ypoints, p.npoints);
 333                 return;
 334             }
 335 
 336             // Otherwise we will use drawPath() for
 337             // high-quality thin paths.
 338             doPath(sg2d, s, false);
 339         } else if (sg2d.strokeState < sg2d.STROKE_CUSTOM) {
 340             // REMIND: X11 can handle uniform scaled wide lines
 341             // and dashed lines itself if we set the appropriate
 342             // XGC attributes (TBD).
 343             ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
 344             try {
 345                 SunToolkit.awtLock();
 346                 try {
 347                     long xgc = validate(sg2d);
 348                     XFillSpans(sg2d.surfaceData.getNativeOps(), xgc,
 349                                si, si.getNativeIterator(),
 350                                0, 0);
 351                 } finally {
 352                     SunToolkit.awtUnlock();
 353                 }
 354             } finally {
 355                 si.dispose();
 356             }
 357         } else {
 358             fill(sg2d, sg2d.stroke.createStrokedShape(s));
 359         }
 360     }
 361 
 362     public void fill(SunGraphics2D sg2d, Shape s) {
 363         if (sg2d.strokeState == sg2d.STROKE_THIN) {
 364             // Delegate to fillPolygon() if possible...
 365             if (s instanceof Polygon &&
 366                 sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE)
 367             {
 368                 Polygon p = (Polygon) s;
 369                 fillPolygon(sg2d, p.xpoints, p.ypoints, p.npoints);
 370                 return;
 371             }
 372 
 373             // Otherwise we will use fillPath() for
 374             // high-quality fills.
 375             doPath(sg2d, s, true);
 376             return;
 377         }
 378 
 379         AffineTransform at;
 380         int transx, transy;
 381         if (sg2d.transformState < sg2d.TRANSFORM_TRANSLATESCALE) {
 382             // Transform (translation) will be done by XFillSpans
 383             at = null;
 384             transx = sg2d.transX;
 385             transy = sg2d.transY;
 386         } else {
 387             // Transform will be done by the PathIterator
 388             at = sg2d.transform;
 389             transx = transy = 0;
 390         }
 391 
 392         ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
 393         try {
 394             // Subtract transx/y from the SSI clip to match the
 395             // (potentially untranslated) geometry fed to it
 396             Region clip = sg2d.getCompClip();
 397             ssi.setOutputAreaXYXY(clip.getLoX() - transx,
 398                                   clip.getLoY() - transy,
 399                                   clip.getHiX() - transx,
 400                                   clip.getHiY() - transy);
 401             ssi.appendPath(s.getPathIterator(at));




  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.x11;
  27 
  28 import java.awt.Polygon;
  29 import java.awt.Shape;
  30 import java.awt.geom.AffineTransform;

  31 import java.awt.geom.Path2D;
  32 
  33 import sun.awt.SunToolkit;
  34 import sun.java2d.SunGraphics2D;

  35 import sun.java2d.loops.GraphicsPrimitive;
  36 import sun.java2d.pipe.LoopPipe;
  37 import sun.java2d.pipe.PixelDrawPipe;
  38 import sun.java2d.pipe.PixelFillPipe;
  39 import sun.java2d.pipe.Region;
  40 import sun.java2d.pipe.ShapeDrawPipe;

  41 import sun.java2d.pipe.ShapeSpanIterator;
  42 import sun.java2d.pipe.SpanIterator;
  43 
  44 public class X11Renderer implements
  45     PixelDrawPipe,
  46     PixelFillPipe,
  47     ShapeDrawPipe
  48 {
  49     public static X11Renderer getInstance() {
  50         return (GraphicsPrimitive.tracingEnabled()
  51                 ? new X11TracingRenderer()
  52                 : new X11Renderer());
  53     }
  54 
  55     private final long validate(SunGraphics2D sg2d) {
  56         // NOTE: getCompClip() will revalidateAll() if the
  57         // surfaceData is invalid.  This should ensure that
  58         // the clip and pixel that we are validating against
  59         // are the most current.
  60         //
  61         // The assumption is that the pipeline after that
  62         // revalidation will either be another X11 pipe


 280         try {
 281             long xgc = validate(sg2d);
 282             XFillPoly(sg2d.surfaceData.getNativeOps(), xgc,
 283                       sg2d.transX, sg2d.transY, xpoints, ypoints, npoints);
 284         } finally {
 285             SunToolkit.awtUnlock();
 286         }
 287     }
 288 
 289     native void XFillSpans(long pXSData, long xgc,
 290                            SpanIterator si, long iterator,
 291                            int transx, int transy);
 292 
 293     native void XDoPath(SunGraphics2D sg2d, long pXSData, long xgc,
 294                         int transX, int transY, Path2D.Float p2df,
 295                         boolean isFill);
 296 
 297     private void doPath(SunGraphics2D sg2d, Shape s, boolean isFill) {
 298         Path2D.Float p2df;
 299         int transx, transy;
 300         if (sg2d.transformState <= SunGraphics2D.TRANSFORM_INT_TRANSLATE) {
 301             if (s instanceof Path2D.Float) {
 302                 p2df = (Path2D.Float)s;
 303             } else {
 304                 p2df = new Path2D.Float(s);
 305             }
 306             transx = sg2d.transX;
 307             transy = sg2d.transY;
 308         } else {
 309             p2df = new Path2D.Float(s, sg2d.transform);
 310             transx = 0;
 311             transy = 0;
 312         }
 313         SunToolkit.awtLock();
 314         try {
 315             long xgc = validate(sg2d);
 316             XDoPath(sg2d, sg2d.surfaceData.getNativeOps(), xgc,
 317                     transx, transy, p2df, isFill);
 318         } finally {
 319             SunToolkit.awtUnlock();
 320         }
 321     }
 322 
 323     public void draw(SunGraphics2D sg2d, Shape s) {
 324         if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
 325             // Delegate to drawPolygon() if possible...
 326             if (s instanceof Polygon &&
 327                 sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE)
 328             {
 329                 Polygon p = (Polygon) s;
 330                 drawPolygon(sg2d, p.xpoints, p.ypoints, p.npoints);
 331                 return;
 332             }
 333 
 334             // Otherwise we will use drawPath() for
 335             // high-quality thin paths.
 336             doPath(sg2d, s, false);
 337         } else if (sg2d.strokeState < SunGraphics2D.STROKE_CUSTOM) {
 338             // REMIND: X11 can handle uniform scaled wide lines
 339             // and dashed lines itself if we set the appropriate
 340             // XGC attributes (TBD).
 341             ShapeSpanIterator si = LoopPipe.getStrokeSpans(sg2d, s);
 342             try {
 343                 SunToolkit.awtLock();
 344                 try {
 345                     long xgc = validate(sg2d);
 346                     XFillSpans(sg2d.surfaceData.getNativeOps(), xgc,
 347                                si, si.getNativeIterator(),
 348                                0, 0);
 349                 } finally {
 350                     SunToolkit.awtUnlock();
 351                 }
 352             } finally {
 353                 si.dispose();
 354             }
 355         } else {
 356             fill(sg2d, sg2d.stroke.createStrokedShape(s));
 357         }
 358     }
 359 
 360     public void fill(SunGraphics2D sg2d, Shape s) {
 361         if (sg2d.strokeState == SunGraphics2D.STROKE_THIN) {
 362             // Delegate to fillPolygon() if possible...
 363             if (s instanceof Polygon &&
 364                 sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE)
 365             {
 366                 Polygon p = (Polygon) s;
 367                 fillPolygon(sg2d, p.xpoints, p.ypoints, p.npoints);
 368                 return;
 369             }
 370 
 371             // Otherwise we will use fillPath() for
 372             // high-quality fills.
 373             doPath(sg2d, s, true);
 374             return;
 375         }
 376 
 377         AffineTransform at;
 378         int transx, transy;
 379         if (sg2d.transformState < SunGraphics2D.TRANSFORM_TRANSLATESCALE) {
 380             // Transform (translation) will be done by XFillSpans
 381             at = null;
 382             transx = sg2d.transX;
 383             transy = sg2d.transY;
 384         } else {
 385             // Transform will be done by the PathIterator
 386             at = sg2d.transform;
 387             transx = transy = 0;
 388         }
 389 
 390         ShapeSpanIterator ssi = LoopPipe.getFillSSI(sg2d);
 391         try {
 392             // Subtract transx/y from the SSI clip to match the
 393             // (potentially untranslated) geometry fed to it
 394             Region clip = sg2d.getCompClip();
 395             ssi.setOutputAreaXYXY(clip.getLoX() - transx,
 396                                   clip.getLoY() - transy,
 397                                   clip.getHiX() - transx,
 398                                   clip.getHiY() - transy);
 399             ssi.appendPath(s.getPathIterator(at));