227 /* A gamma adjustment to the colour used in lcd text blitting */ 228 public int lcdTextContrast; 229 private static int lcdTextContrastDefaultValue = 140; 230 231 private int interpolationHint; // raw value of rendering Hint 232 public int strokeHint; 233 234 public int interpolationType; // algorithm choice based on 235 // interpolation and render Hints 236 237 public RenderingHints hints; 238 239 public Region constrainClip; // lightweight bounds in pixels 240 public int constrainX; 241 public int constrainY; 242 243 public Region clipRegion; 244 public Shape usrClip; 245 protected Region devClip; // Actual physical drawable in pixels 246 247 private final int devScale; // Actual physical scale factor 248 private int resolutionVariantHint; 249 250 // cached state for text rendering 251 private boolean validFontInfo; 252 private FontInfo fontInfo; 253 private FontInfo glyphVectorFontInfo; 254 private FontRenderContext glyphVectorFRC; 255 256 private final static int slowTextTransformMask = 257 AffineTransform.TYPE_GENERAL_TRANSFORM 258 | AffineTransform.TYPE_MASK_ROTATION 259 | AffineTransform.TYPE_FLIP; 260 261 static { 262 if (PerformanceLogger.loggingEnabled()) { 263 PerformanceLogger.setTime("SunGraphics2D static initialization"); 264 } 265 } 266 267 public SunGraphics2D(SurfaceData sd, Color fg, Color bg, Font f) { 268 surfaceData = sd; 269 foregroundColor = fg; 270 backgroundColor = bg; 271 272 transform = new AffineTransform(); 273 stroke = defaultStroke; 274 composite = defaultComposite; 275 paint = foregroundColor; 276 277 imageComp = CompositeType.SrcOverNoEa; 278 279 renderHint = SunHints.INTVAL_RENDER_DEFAULT; 280 antialiasHint = SunHints.INTVAL_ANTIALIAS_OFF; 281 textAntialiasHint = SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT; 282 fractionalMetricsHint = SunHints.INTVAL_FRACTIONALMETRICS_OFF; 283 lcdTextContrast = lcdTextContrastDefaultValue; 284 interpolationHint = -1; 285 strokeHint = SunHints.INTVAL_STROKE_DEFAULT; 286 resolutionVariantHint = SunHints.INTVAL_RESOLUTION_VARIANT_DEFAULT; 287 288 interpolationType = AffineTransformOp.TYPE_NEAREST_NEIGHBOR; 289 290 validateColor(); 291 292 devScale = sd.getDefaultScale(); 293 if (devScale != 1) { 294 transform.setToScale(devScale, devScale); 295 invalidateTransform(); 296 } 297 298 font = f; 299 if (font == null) { 300 font = defaultFont; 301 } 302 303 setDevClip(sd.getBounds()); 304 invalidatePipe(); 305 } 306 307 protected Object clone() { 308 try { 309 SunGraphics2D g = (SunGraphics2D) super.clone(); 310 g.transform = new AffineTransform(this.transform); 311 if (hints != null) { 312 g.hints = (RenderingHints) this.hints.clone(); 313 } 314 /* FontInfos are re-used, so must be cloned too, if they 315 * are valid, and be nulled out if invalid. 316 * The implied trade-off is that there is more to be gained 317 * from re-using these objects than is lost by having to 318 * clone them when the SG2D is cloned. 319 */ 320 if (this.fontInfo != null) { 321 if (this.validFontInfo) { 322 g.fontInfo = (FontInfo)this.fontInfo.clone(); 323 } else { 324 g.fontInfo = null; 325 } 326 } 1593 transform.translate(x, y); 1594 if (transformState <= TRANSFORM_INT_TRANSLATE) { 1595 transX += x; 1596 transY += y; 1597 transformState = (((transX | transY) == 0) ? 1598 TRANSFORM_ISIDENT : TRANSFORM_INT_TRANSLATE); 1599 } else { 1600 invalidateTransform(); 1601 } 1602 } 1603 1604 /** 1605 * Sets the Transform in the current graphics state. 1606 * @param Tx The Transform object to be used in the rendering process. 1607 * @see #transform 1608 * @see TransformChain 1609 * @see AffineTransform 1610 */ 1611 @Override 1612 public void setTransform(AffineTransform Tx) { 1613 if ((constrainX | constrainY) == 0 && devScale == 1) { 1614 transform.setTransform(Tx); 1615 } else { 1616 transform.setTransform(devScale, 0, 0, devScale, constrainX, 1617 constrainY); 1618 transform.concatenate(Tx); 1619 } 1620 invalidateTransform(); 1621 } 1622 1623 protected void invalidateTransform() { 1624 int type = transform.getType(); 1625 int origTransformState = transformState; 1626 if (type == AffineTransform.TYPE_IDENTITY) { 1627 transformState = TRANSFORM_ISIDENT; 1628 transX = transY = 0; 1629 } else if (type == AffineTransform.TYPE_TRANSLATION) { 1630 double dtx = transform.getTranslateX(); 1631 double dty = transform.getTranslateY(); 1632 transX = (int) Math.floor(dtx + 0.5); 1633 transY = (int) Math.floor(dty + 0.5); 1634 if (dtx == transX && dty == transY) { 1635 transformState = TRANSFORM_INT_TRANSLATE; 1636 } else { 1637 transformState = TRANSFORM_ANY_TRANSLATE; 1657 this.validFontInfo = false; 1658 this.fontMetrics = null; 1659 this.glyphVectorFontInfo = null; 1660 1661 if (transformState != origTransformState) { 1662 invalidatePipe(); 1663 } 1664 } 1665 if (strokeState != STROKE_CUSTOM) { 1666 validateBasicStroke((BasicStroke) stroke); 1667 } 1668 } 1669 1670 /** 1671 * Returns the current Transform in the Graphics2D state. 1672 * @see #transform 1673 * @see #setTransform 1674 */ 1675 @Override 1676 public AffineTransform getTransform() { 1677 if ((constrainX | constrainY) == 0 && devScale == 1) { 1678 return new AffineTransform(transform); 1679 } 1680 final double invScale = 1.0 / devScale; 1681 AffineTransform tx = new AffineTransform(invScale, 0, 0, invScale, 1682 -constrainX * invScale, 1683 -constrainY * invScale); 1684 tx.concatenate(transform); 1685 return tx; 1686 } 1687 1688 /** 1689 * Returns the current Transform ignoring the "constrain" 1690 * rectangle. 1691 */ 1692 public AffineTransform cloneTransform() { 1693 return new AffineTransform(transform); 1694 } 1695 1696 /** 1697 * Returns the current Paint in the Graphics2D state. 1698 * @see #setPaint 1699 * @see java.awt.Graphics#setColor 1700 */ 1701 public Paint getPaint() { 1702 return paint; 1703 } | 227 /* A gamma adjustment to the colour used in lcd text blitting */ 228 public int lcdTextContrast; 229 private static int lcdTextContrastDefaultValue = 140; 230 231 private int interpolationHint; // raw value of rendering Hint 232 public int strokeHint; 233 234 public int interpolationType; // algorithm choice based on 235 // interpolation and render Hints 236 237 public RenderingHints hints; 238 239 public Region constrainClip; // lightweight bounds in pixels 240 public int constrainX; 241 public int constrainY; 242 243 public Region clipRegion; 244 public Shape usrClip; 245 protected Region devClip; // Actual physical drawable in pixels 246 247 private int resolutionVariantHint; 248 249 // cached state for text rendering 250 private boolean validFontInfo; 251 private FontInfo fontInfo; 252 private FontInfo glyphVectorFontInfo; 253 private FontRenderContext glyphVectorFRC; 254 255 private final static int slowTextTransformMask = 256 AffineTransform.TYPE_GENERAL_TRANSFORM 257 | AffineTransform.TYPE_MASK_ROTATION 258 | AffineTransform.TYPE_FLIP; 259 260 static { 261 if (PerformanceLogger.loggingEnabled()) { 262 PerformanceLogger.setTime("SunGraphics2D static initialization"); 263 } 264 } 265 266 public SunGraphics2D(SurfaceData sd, Color fg, Color bg, Font f) { 267 surfaceData = sd; 268 foregroundColor = fg; 269 backgroundColor = bg; 270 stroke = defaultStroke; 271 composite = defaultComposite; 272 paint = foregroundColor; 273 274 imageComp = CompositeType.SrcOverNoEa; 275 276 renderHint = SunHints.INTVAL_RENDER_DEFAULT; 277 antialiasHint = SunHints.INTVAL_ANTIALIAS_OFF; 278 textAntialiasHint = SunHints.INTVAL_TEXT_ANTIALIAS_DEFAULT; 279 fractionalMetricsHint = SunHints.INTVAL_FRACTIONALMETRICS_OFF; 280 lcdTextContrast = lcdTextContrastDefaultValue; 281 interpolationHint = -1; 282 strokeHint = SunHints.INTVAL_STROKE_DEFAULT; 283 resolutionVariantHint = SunHints.INTVAL_RESOLUTION_VARIANT_DEFAULT; 284 285 interpolationType = AffineTransformOp.TYPE_NEAREST_NEIGHBOR; 286 287 transform = getDefaultTransform(); 288 if (!transform.isIdentity()) { 289 invalidateTransform(); 290 } 291 292 validateColor(); 293 294 font = f; 295 if (font == null) { 296 font = defaultFont; 297 } 298 299 setDevClip(sd.getBounds()); 300 invalidatePipe(); 301 } 302 303 private AffineTransform getDefaultTransform() { 304 GraphicsConfiguration gc = getDeviceConfiguration(); 305 return (gc == null) ? new AffineTransform() : gc.getDefaultTransform(); 306 } 307 308 protected Object clone() { 309 try { 310 SunGraphics2D g = (SunGraphics2D) super.clone(); 311 g.transform = new AffineTransform(this.transform); 312 if (hints != null) { 313 g.hints = (RenderingHints) this.hints.clone(); 314 } 315 /* FontInfos are re-used, so must be cloned too, if they 316 * are valid, and be nulled out if invalid. 317 * The implied trade-off is that there is more to be gained 318 * from re-using these objects than is lost by having to 319 * clone them when the SG2D is cloned. 320 */ 321 if (this.fontInfo != null) { 322 if (this.validFontInfo) { 323 g.fontInfo = (FontInfo)this.fontInfo.clone(); 324 } else { 325 g.fontInfo = null; 326 } 327 } 1594 transform.translate(x, y); 1595 if (transformState <= TRANSFORM_INT_TRANSLATE) { 1596 transX += x; 1597 transY += y; 1598 transformState = (((transX | transY) == 0) ? 1599 TRANSFORM_ISIDENT : TRANSFORM_INT_TRANSLATE); 1600 } else { 1601 invalidateTransform(); 1602 } 1603 } 1604 1605 /** 1606 * Sets the Transform in the current graphics state. 1607 * @param Tx The Transform object to be used in the rendering process. 1608 * @see #transform 1609 * @see TransformChain 1610 * @see AffineTransform 1611 */ 1612 @Override 1613 public void setTransform(AffineTransform Tx) { 1614 if ((constrainX | constrainY) == 0) { 1615 transform.setTransform(Tx); 1616 } else { 1617 transform.setToTranslation(constrainX, constrainY); 1618 transform.concatenate(Tx); 1619 } 1620 invalidateTransform(); 1621 } 1622 1623 protected void invalidateTransform() { 1624 int type = transform.getType(); 1625 int origTransformState = transformState; 1626 if (type == AffineTransform.TYPE_IDENTITY) { 1627 transformState = TRANSFORM_ISIDENT; 1628 transX = transY = 0; 1629 } else if (type == AffineTransform.TYPE_TRANSLATION) { 1630 double dtx = transform.getTranslateX(); 1631 double dty = transform.getTranslateY(); 1632 transX = (int) Math.floor(dtx + 0.5); 1633 transY = (int) Math.floor(dty + 0.5); 1634 if (dtx == transX && dty == transY) { 1635 transformState = TRANSFORM_INT_TRANSLATE; 1636 } else { 1637 transformState = TRANSFORM_ANY_TRANSLATE; 1657 this.validFontInfo = false; 1658 this.fontMetrics = null; 1659 this.glyphVectorFontInfo = null; 1660 1661 if (transformState != origTransformState) { 1662 invalidatePipe(); 1663 } 1664 } 1665 if (strokeState != STROKE_CUSTOM) { 1666 validateBasicStroke((BasicStroke) stroke); 1667 } 1668 } 1669 1670 /** 1671 * Returns the current Transform in the Graphics2D state. 1672 * @see #transform 1673 * @see #setTransform 1674 */ 1675 @Override 1676 public AffineTransform getTransform() { 1677 if ((constrainX | constrainY) == 0) { 1678 return new AffineTransform(transform); 1679 } 1680 AffineTransform tx 1681 = AffineTransform.getTranslateInstance(-constrainX, -constrainY); 1682 tx.concatenate(transform); 1683 return tx; 1684 } 1685 1686 /** 1687 * Returns the current Transform ignoring the "constrain" 1688 * rectangle. 1689 */ 1690 public AffineTransform cloneTransform() { 1691 return new AffineTransform(transform); 1692 } 1693 1694 /** 1695 * Returns the current Paint in the Graphics2D state. 1696 * @see #setPaint 1697 * @see java.awt.Graphics#setColor 1698 */ 1699 public Paint getPaint() { 1700 return paint; 1701 } |