// System.out.println("DrawImage G: " + g2d);
AffineTransform at = null;
while (true) {
if (cr instanceof AffineRed) {
AffineRed ar = (AffineRed)cr;
if (at == null)
at = ar.getTransform();
else
at.concatenate(ar.getTransform());
cr = ar.getSource();
continue;
} else if (cr instanceof TranslateRed) {
TranslateRed tr = (TranslateRed)cr;
// System.out.println("testing Translate");
int dx = tr.getDeltaX();
int dy = tr.getDeltaY();
if (at == null)
at = AffineTransform.getTranslateInstance(dx, dy);
else
at.translate(dx, dy);
cr = tr.getSource();
continue;
}
break;
}
AffineTransform g2dAt = g2d.getTransform();
if ((at == null) || (at.isIdentity()))
at = g2dAt;
else
at.preConcatenate(g2dAt);
ColorModel srcCM = cr.getColorModel();
ColorModel g2dCM = getDestinationColorModel(g2d);
ColorSpace g2dCS = null;
if (g2dCM != null)
g2dCS = g2dCM.getColorSpace();
if (g2dCS == null)
// Assume device is sRGB
g2dCS = ColorSpace.getInstance(ColorSpace.CS_sRGB);
ColorModel drawCM = g2dCM;
if ((g2dCM == null) || !g2dCM.hasAlpha()) {
// If we can't find out about our device or the device
// does not support alpha just use SRGB unpremultiplied
// (Just because this seems to work for us).
drawCM = sRGB_Unpre;
}
if (cr instanceof BufferedImageCachableRed) {
// There is a huge win if we can use the BI directly here.
// This results in something like a 10x performance gain
// for images, the best thing is this is the common case.
if (g2dCS.equals(srcCM.getColorSpace()) &&
drawCM.equals(srcCM)) {
// System.err.println("Fast Case");
g2d.setTransform(at);
BufferedImageCachableRed bicr;
bicr = (BufferedImageCachableRed)cr;
g2d.drawImage(bicr.getBufferedImage(),
bicr.getMinX(), bicr.getMinY(), null);
g2d.setTransform(g2dAt);
return;
}
}
// Scaling down so do it before color conversion.
double determinant = at.getDeterminant();
if (!at.isIdentity() && (determinant <= 1.0)) {
if (at.getType() != AffineTransform.TYPE_TRANSLATION)
cr = new AffineRed(cr, at, g2d.getRenderingHints());
else {
int xloc = cr.getMinX() + (int)at.getTranslateX();
int yloc = cr.getMinY() + (int)at.getTranslateY();
cr = new TranslateRed(cr, xloc, yloc);
}
}
if (g2dCS != srcCM.getColorSpace()) {
// System.out.println("srcCS: " + srcCM.getColorSpace());
// System.out.println("g2dCS: " + g2dCS);
// System.out.println("sRGB: " +
// ColorSpace.getInstance(ColorSpace.CS_sRGB));
// System.out.println("LsRGB: " +
// ColorSpace.getInstance
// (ColorSpace.CS_LINEAR_RGB));
if (g2dCS == ColorSpace.getInstance(ColorSpace.CS_sRGB))
cr = convertTosRGB(cr);
else if (g2dCS == ColorSpace.getInstance(ColorSpace.CS_LINEAR_RGB))
cr = convertToLsRGB(cr);
}
srcCM = cr.getColorModel();
if (!drawCM.equals(srcCM))
cr = FormatRed.construct(cr, drawCM);
// Scaling up so do it after color conversion.
if (!at.isIdentity() && (determinant > 1.0))
cr = new AffineRed(cr, at, g2d.getRenderingHints());
// Now CR is in device space, so clear the g2d transform.
g2d.setTransform(IDENTITY);
// Ugly Hack alert. This Makes it use our SrcOver implementation