/* * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.java2d; import java.awt.Graphics;import java.awt.Graphics2D;import java.awt.RenderingHints;import java.awt.RenderingHints.Key;import java.awt.geom.Area;import java.awt.geom.AffineTransform;import java.awt.geom.NoninvertibleTransformException;import java.awt.AlphaComposite;import java.awt.BasicStroke;import java.awt.image.BufferedImage;import java.awt.image.BufferedImageOp;import java.awt.image.RenderedImage;import java.awt.image.renderable.RenderableImage;import java.awt.image.renderable.RenderContext;import java.awt.image.AffineTransformOp;import java.awt.image.Raster;import java.awt.image.WritableRaster;import java.awt.Image;import java.awt.Composite;import java.awt.Color;import java.awt.image.ColorModel;import java.awt.GraphicsConfiguration;import java.awt.Paint;import java.awt.GradientPaint;import java.awt.LinearGradientPaint;import java.awt.RadialGradientPaint;import java.awt.TexturePaint;import java.awt.geom.Rectangle2D;import java.awt.geom.PathIterator;import java.awt.geom.GeneralPath;import java.awt.Shape;import java.awt.Stroke;import java.awt.FontMetrics;import java.awt.Rectangle;import java.text.AttributedCharacterIterator;import java.awt.Font;import java.awt.image.ImageObserver;import java.awt.Transparency;import java.awt.font.GlyphVector;import java.awt.font.TextLayout;import sun.font.FontDesignMetrics;import sun.font.FontUtilities;import sun.java2d.pipe.PixelDrawPipe;import sun.java2d.pipe.PixelFillPipe;import sun.java2d.pipe.ShapeDrawPipe;import sun.java2d.pipe.ValidatePipe;import sun.java2d.pipe.ShapeSpanIterator;import sun.java2d.pipe.Region;import sun.java2d.pipe.TextPipe;import sun.java2d.pipe.DrawImagePipe;import sun.java2d.pipe.LoopPipe;import sun.java2d.loops.FontInfo;import sun.java2d.loops.RenderLoops;import sun.java2d.loops.CompositeType;import sun.java2d.loops.SurfaceType;import sun.java2d.loops.Blit;import sun.java2d.loops.MaskFill;import sun.font.FontManager;import java.awt.font.FontRenderContext;import sun.java2d.loops.XORComposite;import sun.awt.ConstrainableGraphics;import sun.awt.SunHints;import java.util.Map;import java.util.Iterator;import sun.java2d.DestSurfaceProvider;import sun.misc.PerformanceLogger; /** * This is a the master Graphics2D superclass for all of the Sun * Graphics implementations. This class relies on subclasses to * manage the various device information, but provides an overall * general framework for performing all of the requests in the * Graphics and Graphics2D APIs. * * @author Jim Graham */public final class SunGraphics2D extends Graphics2D implements ConstrainableGraphics, Cloneable, DestSurfaceProvider{ /* * Attribute States */ /* Paint */ public static final int PAINT_CUSTOM = 6; /* Any other Paint object */ public static final int PAINT_TEXTURE = 5; /* Tiled Image */ public static final int PAINT_RAD_GRADIENT = 4; /* Color RadialGradient */ public static final int PAINT_LIN_GRADIENT = 3; /* Color LinearGradient */ public static final int PAINT_GRADIENT = 2; /* Color Gradient */ public static final int PAINT_ALPHACOLOR = 1; /* Non-opaque Color */ public static final int PAINT_OPAQUECOLOR = 0; /* Opaque Color */ /* Composite*/ public static final int COMP_CUSTOM = 3;/* Custom Composite */ public static final int COMP_XOR = 2;/* XOR Mode Composite */ public static final int COMP_ALPHA = 1;/* AlphaComposite */ public static final int COMP_ISCOPY = 0;/* simple stores into destination, * i.e. Src, SrcOverNoEa, and other * alpha modes which replace * the destination. */ /* Stroke */ public static final int STROKE_CUSTOM = 3; /* custom Stroke */ public static final int STROKE_WIDE = 2; /* BasicStroke */ public static final int STROKE_THINDASHED = 1; /* BasicStroke */ public static final int STROKE_THIN = 0; /* BasicStroke */ /* Transform */ public static final int TRANSFORM_GENERIC = 4; /* any 3x2 */ public static final int TRANSFORM_TRANSLATESCALE = 3; /* scale XY */ public static final int TRANSFORM_ANY_TRANSLATE = 2; /* non-int translate */ public static final int TRANSFORM_INT_TRANSLATE = 1; /* int translate */ public static final int TRANSFORM_ISIDENT = 0; /* Identity */ /* Clipping */ public static final int CLIP_SHAPE = 2; /* arbitrary clip */ public static final int CLIP_RECTANGULAR = 1; /* rectangular clip */ public static final int CLIP_DEVICE = 0; /* no clipping set */ /* The following fields are used when the current Paint is a Color. */ public int eargb; // ARGB value with ExtraAlpha baked in public int pixel; // pixel value for eargb public SurfaceData surfaceData; public PixelDrawPipe drawpipe; public PixelFillPipe fillpipe; public DrawImagePipe imagepipe; public ShapeDrawPipe shapepipe; public TextPipe textpipe; public MaskFill alphafill; public RenderLoops loops; public CompositeType imageComp; /* Image Transparency checked on fly */ public int paintState; public int compositeState; public int strokeState; public int transformState; public int clipState; public Color foregroundColor; public Color backgroundColor; public AffineTransform transform; public int transX; public int transY; protected static final Stroke defaultStroke = new BasicStroke(); protected static final Composite defaultComposite = AlphaComposite.SrcOver; private static final Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); public Paint paint; public Stroke stroke; public Composite composite; protected Font font; protected FontMetrics fontMetrics; public int renderHint; public int antialiasHint; public int textAntialiasHint; private int fractionalMetricsHint; /* A gamma adjustment to the colour used in lcd text blitting */ public int lcdTextContrast; private static int lcdTextContrastDefaultValue = 140; private int interpolationHint; // raw value of rendering Hint public int strokeHint; public int interpolationType; // algorithm choice based on // interpolation and render Hints public RenderingHints hints; public Region constrainClip; // lightweight bounds public int constrainX; public int constrainY; public Region clipRegion; public Shape usrClip; protected Region devClip; // Actual physical drawable // cached state for text rendering private boolean validFontInfo; private FontInfo fontInfo; private FontInfo glyphVectorFontInfo; private FontRenderContext glyphVectorFRC; private final static int slowTextTransformMask = AffineTransform.TYPE_GENERAL_TRANSFORM | AffineTransform.TYPE_MASK_ROTATION | AffineTransform.TYPE_FLIP; static { if (PerformanceLogger.loggingEnabled()) { PerformanceLogger.setTime("SunGraphics2D static initialization"); } } public SunGraphics2D(SurfaceData sd, Color fg, Color bg, Font f) { surfaceData = sd; foregroundColor = fg; backgroundColor = bg; transform = new AffineTransform(); stroke = defaultStroke; composite = defaultComposite; paint = foregroundColor; imageComp = CompositeType.SrcOverNoEa; renderHint = SunHints.INTVAL_RENDER_DEFAULT; antialiasHint = SunHints.INTVAL_ANTIALIAS_OFF; textAntialiasHint = SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT; fractionalMetricsHint = SunHints.INTVAL_FRACTIONALMETRICS_OFF; lcdTextContrast = lcdTextContrastDefaultValue; interpolationHint = -1; strokeHint = SunHints.INTVAL_STROKE_DEFAULT; interpolationType = AffineTransformOp.TYPE_NEAREST_NEIGHBOR; validateColor(); font = f; if (font == null) { font = defaultFont; } setDevClip(sd.getBounds()); invalidatePipe(); } protected Object clone() { try { SunGraphics2D g = (SunGraphics2D) super.clone(); g.transform = new AffineTransform(this.transform); if (hints != null) { g.hints = (RenderingHints) this.hints.clone(); } /* FontInfos are re-used, so must be cloned too, if they * are valid, and be nulled out if invalid. * The implied trade-off is that there is more to be gained * from re-using these objects than is lost by having to * clone them when the SG2D is cloned. */ if (this.fontInfo != null) { if (this.validFontInfo) { g.fontInfo = (FontInfo)this.fontInfo.clone(); } else { g.fontInfo = null; } } if (this.glyphVectorFontInfo != null) { g.glyphVectorFontInfo = (FontInfo)this.glyphVectorFontInfo.clone(); g.glyphVectorFRC = this.glyphVectorFRC; } //g.invalidatePipe(); return g; } catch (CloneNotSupportedException e) { } return null; } /** * Create a new SunGraphics2D based on this one. */ public Graphics create() { return (Graphics) clone(); } public void setDevClip(int x, int y, int w, int h) { Region c = constrainClip; if (c == null) { devClip = Region.getInstanceXYWH(x, y, w, h); } else { devClip = c.getIntersectionXYWH(x, y, w, h); } validateCompClip(); } public void setDevClip(Rectangle r) { setDevClip(r.x, r.y, r.width, r.height); } /** * Constrain rendering for lightweight objects. * * REMIND: This method will back off to the "workaround" * of using translate and clipRect if the Graphics * to be constrained has a complex transform. The * drawback of the workaround is that the resulting * clip and device origin cannot be "enforced". * * @exception IllegalStateException If the Graphics * to be constrained has a complex transform. */ public void constrain(int x, int y, int w, int h) { if ((x|y) != 0) { translate(x, y); } if (transformState >= TRANSFORM_TRANSLATESCALE) { clipRect(0, 0, w, h); return; } x = constrainX = transX; y = constrainY = transY; w = Region.dimAdd(x, w); h = Region.dimAdd(y, h); Region c = constrainClip; if (c == null) { c = Region.getInstanceXYXY(x, y, w, h); } else { c = c.getIntersectionXYXY(x, y, w, h); if (c == constrainClip) { // Common case to ignore return; } } constrainClip = c; if (!devClip.isInsideQuickCheck(c)) { devClip = devClip.getIntersection(c); validateCompClip(); } } protected static ValidatePipe invalidpipe = new ValidatePipe(); /* * Invalidate the pipeline */ protected void invalidatePipe() { drawpipe = invalidpipe; fillpipe = invalidpipe; shapepipe = invalidpipe; textpipe = invalidpipe; imagepipe = invalidpipe; loops = null; } public void validatePipe() { surfaceData.validatePipe(this); } /* * Intersect two Shapes by the simplest method, attempting to produce * a simplified result. * The boolean arguments keep1 and keep2 specify whether or not * the first or second shapes can be modified during the operation * or whether that shape must be "kept" unmodified. */ Shape intersectShapes(Shape s1, Shape s2, boolean keep1, boolean keep2) { if (s1 instanceof Rectangle && s2 instanceof Rectangle) { return ((Rectangle) s1).intersection((Rectangle) s2); } if (s1 instanceof Rectangle2D) { return intersectRectShape((Rectangle2D) s1, s2, keep1, keep2); } else if (s2 instanceof Rectangle2D) { return intersectRectShape((Rectangle2D) s2, s1, keep2, keep1); } return intersectByArea(s1, s2, keep1, keep2); } /* * Intersect a Rectangle with a Shape by the simplest method, * attempting to produce a simplified result. * The boolean arguments keep1 and keep2 specify whether or not * the first or second shapes can be modified during the operation * or whether that shape must be "kept" unmodified. */ Shape intersectRectShape(Rectangle2D r, Shape s, boolean keep1, boolean keep2) { if (s instanceof Rectangle2D) { Rectangle2D r2 = (Rectangle2D) s; Rectangle2D outrect; if (!keep1) { outrect = r; } else if (!keep2) { outrect = r2; } else { outrect = new Rectangle2D.Float(); } double x1 = Math.max(r.getX(), r2.getX()); double x2 = Math.min(r.getX() + r.getWidth(), r2.getX() + r2.getWidth()); double y1 = Math.max(r.getY(), r2.getY()); double y2 = Math.min(r.getY() + r.getHeight(), r2.getY() + r2.getHeight()); if (((x2 - x1) < 0) || ((y2 - y1) < 0)) // Width or height is negative. No intersection. outrect.setFrameFromDiagonal(0, 0, 0, 0); else outrect.setFrameFromDiagonal(x1, y1, x2, y2); return outrect; } if (r.contains(s.getBounds2D())) { if (keep2) { s = cloneShape(s); } return s; } return intersectByArea(r, s, keep1, keep2); } protected static Shape cloneShape(Shape s) { return new GeneralPath(s); } /* * Intersect two Shapes using the Area class. Presumably other * attempts at simpler intersection methods proved fruitless. * The boolean arguments keep1 and keep2 specify whether or not * the first or second shapes can be modified during the operation * or whether that shape must be "kept" unmodified. * @see #intersectShapes * @see #intersectRectShape */ Shape intersectByArea(Shape s1, Shape s2, boolean keep1, boolean keep2) { Area a1, a2; // First see if we can find an overwriteable source shape // to use as our destination area to avoid duplication. if (!keep1 && (s1 instanceof Area)) { a1 = (Area) s1; } else if (!keep2 && (s2 instanceof Area)) { a1 = (Area) s2; s2 = s1; } else { a1 = new Area(s1); } if (s2 instanceof Area) { a2 = (Area) s2; } else { a2 = new Area(s2); } a1.intersect(a2); if (a1.isRectangular()) { return a1.getBounds(); } return a1; } /* * Intersect usrClip bounds and device bounds to determine the composite * rendering boundaries. */ public Region getCompClip() { if (!surfaceData.isValid()) { // revalidateAll() implicitly recalculcates the composite clip revalidateAll(); } return clipRegion; } public Font getFont() { if (font == null) { font = defaultFont; } return font; } private static final double[] IDENT_MATRIX = {1, 0, 0, 1}; private static final AffineTransform IDENT_ATX = new AffineTransform();Lines 1–500 of 3310. Load more
/* * Copyright (c) 1996, 2008, Oracle and/or its affiliates. All rights reserved. * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. * * This code is free software; you can redistribute it and/or modify it * under the terms of the GNU General Public License version 2 only, as * published by the Free Software Foundation. Oracle designates this * particular file as subject to the "Classpath" exception as provided * by Oracle in the LICENSE file that accompanied this code. * * This code is distributed in the hope that it will be useful, but WITHOUT * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License * version 2 for more details (a copy is included in the LICENSE file that * accompanied this code). * * You should have received a copy of the GNU General Public License version * 2 along with this work; if not, write to the Free Software Foundation, * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. * * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA * or visit www.oracle.com if you need additional information or have any * questions. */ package sun.java2d; import java.awt.Graphics; import java.awt.Graphics2D; import java.awt.RenderingHints; import java.awt.RenderingHints.Key; import java.awt.geom.Area; import java.awt.geom.AffineTransform; import java.awt.geom.NoninvertibleTransformException; import java.awt.AlphaComposite; import java.awt.BasicStroke; import java.awt.image.BufferedImage; import java.awt.image.BufferedImageOp; import java.awt.image.RenderedImage; import java.awt.image.renderable.RenderableImage; import java.awt.image.renderable.RenderContext; import java.awt.image.AffineTransformOp; import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.awt.Image; import java.awt.Composite; import java.awt.Color; import java.awt.image.ColorModel; import java.awt.GraphicsConfiguration; import java.awt.Paint; import java.awt.GradientPaint; import java.awt.LinearGradientPaint; import java.awt.RadialGradientPaint; import java.awt.TexturePaint; import java.awt.geom.Rectangle2D; import java.awt.geom.PathIterator; import java.awt.geom.GeneralPath; import java.awt.Shape; import java.awt.Stroke; import java.awt.FontMetrics; import java.awt.Rectangle; import java.text.AttributedCharacterIterator; import java.awt.Font; import java.awt.image.ImageObserver; import java.awt.Transparency; import java.awt.font.GlyphVector; import java.awt.font.TextLayout; import sun.font.FontDesignMetrics; import sun.font.FontUtilities; import sun.java2d.pipe.PixelDrawPipe; import sun.java2d.pipe.PixelFillPipe; import sun.java2d.pipe.ShapeDrawPipe; import sun.java2d.pipe.ValidatePipe; import sun.java2d.pipe.ShapeSpanIterator; import sun.java2d.pipe.Region; import sun.java2d.pipe.TextPipe; import sun.java2d.pipe.DrawImagePipe; import sun.java2d.pipe.LoopPipe; import sun.java2d.loops.FontInfo; import sun.java2d.loops.RenderLoops; import sun.java2d.loops.CompositeType; import sun.java2d.loops.SurfaceType; import sun.java2d.loops.Blit; import sun.java2d.loops.MaskFill; import sun.font.FontManager; import java.awt.font.FontRenderContext; import sun.java2d.loops.XORComposite; import sun.awt.ConstrainableGraphics; import sun.awt.SunHints; import java.util.Map; import java.util.Iterator; import sun.java2d.DestSurfaceProvider; import sun.misc.PerformanceLogger; /** * This is a the master Graphics2D superclass for all of the Sun * Graphics implementations. This class relies on subclasses to * manage the various device information, but provides an overall * general framework for performing all of the requests in the * Graphics and Graphics2D APIs. * * @author Jim Graham */ public final class SunGraphics2D extends Graphics2D implements ConstrainableGraphics, Cloneable, DestSurfaceProvider { /* * Attribute States */ /* Paint */ public static final int PAINT_CUSTOM = 6; /* Any other Paint object */ public static final int PAINT_TEXTURE = 5; /* Tiled Image */ public static final int PAINT_RAD_GRADIENT = 4; /* Color RadialGradient */ public static final int PAINT_LIN_GRADIENT = 3; /* Color LinearGradient */ public static final int PAINT_GRADIENT = 2; /* Color Gradient */ public static final int PAINT_ALPHACOLOR = 1; /* Non-opaque Color */ public static final int PAINT_OPAQUECOLOR = 0; /* Opaque Color */ /* Composite*/ public static final int COMP_CUSTOM = 3;/* Custom Composite */ public static final int COMP_XOR = 2;/* XOR Mode Composite */ public static final int COMP_ALPHA = 1;/* AlphaComposite */ public static final int COMP_ISCOPY = 0;/* simple stores into destination, * i.e. Src, SrcOverNoEa, and other * alpha modes which replace * the destination. */ /* Stroke */ public static final int STROKE_CUSTOM = 3; /* custom Stroke */ public static final int STROKE_WIDE = 2; /* BasicStroke */ public static final int STROKE_THINDASHED = 1; /* BasicStroke */ public static final int STROKE_THIN = 0; /* BasicStroke */ /* Transform */ public static final int TRANSFORM_GENERIC = 4; /* any 3x2 */ public static final int TRANSFORM_TRANSLATESCALE = 3; /* scale XY */ public static final int TRANSFORM_ANY_TRANSLATE = 2; /* non-int translate */ public static final int TRANSFORM_INT_TRANSLATE = 1; /* int translate */ public static final int TRANSFORM_ISIDENT = 0; /* Identity */ /* Clipping */ public static final int CLIP_SHAPE = 2; /* arbitrary clip */ public static final int CLIP_RECTANGULAR = 1; /* rectangular clip */ public static final int CLIP_DEVICE = 0; /* no clipping set */ /* The following fields are used when the current Paint is a Color. */ public int eargb; // ARGB value with ExtraAlpha baked in public int pixel; // pixel value for eargb public SurfaceData surfaceData; public PixelDrawPipe drawpipe; public PixelFillPipe fillpipe; public DrawImagePipe imagepipe; public ShapeDrawPipe shapepipe; public TextPipe textpipe; public MaskFill alphafill; public RenderLoops loops; public CompositeType imageComp; /* Image Transparency checked on fly */ public int paintState; public int compositeState; public int strokeState; public int transformState; public int clipState; public Color foregroundColor; public Color backgroundColor; public AffineTransform transform; public int transX; public int transY; protected static final Stroke defaultStroke = new BasicStroke(); protected static final Composite defaultComposite = AlphaComposite.SrcOver; private static final Font defaultFont = new Font(Font.DIALOG, Font.PLAIN, 12); public Paint paint; public Stroke stroke; public Composite composite; protected Font font; protected FontMetrics fontMetrics; public int renderHint; public int antialiasHint; public int textAntialiasHint; private int fractionalMetricsHint; /* A gamma adjustment to the colour used in lcd text blitting */ public int lcdTextContrast; private static int lcdTextContrastDefaultValue = 140; private int interpolationHint; // raw value of rendering Hint public int strokeHint; public int interpolationType; // algorithm choice based on // interpolation and render Hints public RenderingHints hints; public Region constrainClip; // lightweight bounds public int constrainX; public int constrainY; public Region clipRegion; public Shape usrClip; protected Region devClip; // Actual physical drawable // cached state for text rendering private boolean validFontInfo; private FontInfo fontInfo; private FontInfo glyphVectorFontInfo; private FontRenderContext glyphVectorFRC; private final static int slowTextTransformMask = AffineTransform.TYPE_GENERAL_TRANSFORM | AffineTransform.TYPE_MASK_ROTATION | AffineTransform.TYPE_FLIP; static { if (PerformanceLogger.loggingEnabled()) { PerformanceLogger.setTime("SunGraphics2D static initialization"); } } public SunGraphics2D(SurfaceData sd, Color fg, Color bg, Font f) { surfaceData = sd; foregroundColor = fg; backgroundColor = bg; transform = new AffineTransform(); stroke = defaultStroke; composite = defaultComposite; paint = foregroundColor; imageComp = CompositeType.SrcOverNoEa; renderHint = SunHints.INTVAL_RENDER_DEFAULT; antialiasHint = SunHints.INTVAL_ANTIALIAS_OFF; textAntialiasHint = SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT; fractionalMetricsHint = SunHints.INTVAL_FRACTIONALMETRICS_OFF; lcdTextContrast = lcdTextContrastDefaultValue; interpolationHint = -1; strokeHint = SunHints.INTVAL_STROKE_DEFAULT; interpolationType = AffineTransformOp.TYPE_NEAREST_NEIGHBOR; validateColor(); font = f; if (font == null) { font = defaultFont; } setDevClip(sd.getBounds()); invalidatePipe(); } protected Object clone() { try { SunGraphics2D g = (SunGraphics2D) super.clone(); g.transform = new AffineTransform(this.transform); if (hints != null) { g.hints = (RenderingHints) this.hints.clone(); } /* FontInfos are re-used, so must be cloned too, if they * are valid, and be nulled out if invalid. * The implied trade-off is that there is more to be gained * from re-using these objects than is lost by having to * clone them when the SG2D is cloned. */ if (this.fontInfo != null) { if (this.validFontInfo) { g.fontInfo = (FontInfo)this.fontInfo.clone(); } else { g.fontInfo = null; } } if (this.glyphVectorFontInfo != null) { g.glyphVectorFontInfo = (FontInfo)this.glyphVectorFontInfo.clone(); g.glyphVectorFRC = this.glyphVectorFRC; } //g.invalidatePipe(); return g; } catch (CloneNotSupportedException e) { } return null; } /** * Create a new SunGraphics2D based on this one. */ public Graphics create() { return (Graphics) clone(); } public void setDevClip(int x, int y, int w, int h) { Region c = constrainClip; if (c == null) { devClip = Region.getInstanceXYWH(x, y, w, h); } else { devClip = c.getIntersectionXYWH(x, y, w, h); } validateCompClip(); } public void setDevClip(Rectangle r) { setDevClip(r.x, r.y, r.width, r.height); } /** * Constrain rendering for lightweight objects. * * REMIND: This method will back off to the "workaround" * of using translate and clipRect if the Graphics * to be constrained has a complex transform. The * drawback of the workaround is that the resulting * clip and device origin cannot be "enforced". * * @exception IllegalStateException If the Graphics * to be constrained has a complex transform. */ public void constrain(int x, int y, int w, int h) { if ((x|y) != 0) { translate(x, y); } if (transformState >= TRANSFORM_TRANSLATESCALE) { clipRect(0, 0, w, h); return; } x = constrainX = transX; y = constrainY = transY; w = Region.dimAdd(x, w); h = Region.dimAdd(y, h); Region c = constrainClip; if (c == null) { c = Region.getInstanceXYXY(x, y, w, h); } else { c = c.getIntersectionXYXY(x, y, w, h); if (c == constrainClip) { // Common case to ignore return; } } constrainClip = c; if (!devClip.isInsideQuickCheck(c)) { devClip = devClip.getIntersection(c); validateCompClip(); } } protected static ValidatePipe invalidpipe = new ValidatePipe(); /* * Invalidate the pipeline */ protected void invalidatePipe() { drawpipe = invalidpipe; fillpipe = invalidpipe; shapepipe = invalidpipe; textpipe = invalidpipe; imagepipe = invalidpipe; loops = null; } public void validatePipe() { surfaceData.validatePipe(this); } /* * Intersect two Shapes by the simplest method, attempting to produce * a simplified result. * The boolean arguments keep1 and keep2 specify whether or not * the first or second shapes can be modified during the operation * or whether that shape must be "kept" unmodified. */ Shape intersectShapes(Shape s1, Shape s2, boolean keep1, boolean keep2) { if (s1 instanceof Rectangle && s2 instanceof Rectangle) { return ((Rectangle) s1).intersection((Rectangle) s2); } if (s1 instanceof Rectangle2D) { return intersectRectShape((Rectangle2D) s1, s2, keep1, keep2); } else if (s2 instanceof Rectangle2D) { return intersectRectShape((Rectangle2D) s2, s1, keep2, keep1); } return intersectByArea(s1, s2, keep1, keep2); } /* * Intersect a Rectangle with a Shape by the simplest method, * attempting to produce a simplified result. * The boolean arguments keep1 and keep2 specify whether or not * the first or second shapes can be modified during the operation * or whether that shape must be "kept" unmodified. */ Shape intersectRectShape(Rectangle2D r, Shape s, boolean keep1, boolean keep2) { if (s instanceof Rectangle2D) { Rectangle2D r2 = (Rectangle2D) s; Rectangle2D outrect; if (!keep1) { outrect = r; } else if (!keep2) { outrect = r2; } else { outrect = new Rectangle2D.Float(); } double x1 = Math.max(r.getX(), r2.getX()); double x2 = Math.min(r.getX() + r.getWidth(), r2.getX() + r2.getWidth()); double y1 = Math.max(r.getY(), r2.getY()); double y2 = Math.min(r.getY() + r.getHeight(), r2.getY() + r2.getHeight()); if (((x2 - x1) < 0) || ((y2 - y1) < 0)) // Width or height is negative. No intersection. outrect.setFrameFromDiagonal(0, 0, 0, 0); else outrect.setFrameFromDiagonal(x1, y1, x2, y2); return outrect; } if (r.contains(s.getBounds2D())) { if (keep2) { s = cloneShape(s); } return s; } return intersectByArea(r, s, keep1, keep2); } protected static Shape cloneShape(Shape s) { return new GeneralPath(s); } /* * Intersect two Shapes using the Area class. Presumably other * attempts at simpler intersection methods proved fruitless. * The boolean arguments keep1 and keep2 specify whether or not * the first or second shapes can be modified during the operation * or whether that shape must be "kept" unmodified. * @see #intersectShapes * @see #intersectRectShape */ Shape intersectByArea(Shape s1, Shape s2, boolean keep1, boolean keep2) { Area a1, a2; // First see if we can find an overwriteable source shape // to use as our destination area to avoid duplication. if (!keep1 && (s1 instanceof Area)) { a1 = (Area) s1; } else if (!keep2 && (s2 instanceof Area)) { a1 = (Area) s2; s2 = s1; } else { a1 = new Area(s1); } if (s2 instanceof Area) { a2 = (Area) s2; } else { a2 = new Area(s2); } a1.intersect(a2); if (a1.isRectangular()) { return a1.getBounds(); } return a1; } /* * Intersect usrClip bounds and device bounds to determine the composite * rendering boundaries. */ public Region getCompClip() { if (!surfaceData.isValid()) { // revalidateAll() implicitly recalculcates the composite clip revalidateAll(); } return clipRegion; } public Font getFont() { if (font == null) { font = defaultFont; } return font; } private static final double[] IDENT_MATRIX = {1, 0, 0, 1}; private static final AffineTransform IDENT_ATX = new AffineTransform();