package org.geogebra.desktop.awt;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.GradientPaint;
import java.awt.Graphics2D;
import java.awt.Paint;
import java.awt.RenderingHints;
import java.awt.RenderingHints.Key;
import java.awt.geom.AffineTransform;
import org.geogebra.common.awt.GAffineTransform;
import org.geogebra.common.awt.GBasicStroke;
import org.geogebra.common.awt.GBufferedImage;
import org.geogebra.common.awt.GColor;
import org.geogebra.common.awt.GComposite;
import org.geogebra.common.awt.GFont;
import org.geogebra.common.awt.GFontRenderContext;
import org.geogebra.common.awt.GGraphics2D;
import org.geogebra.common.awt.GLine2D;
import org.geogebra.common.awt.GPaint;
import org.geogebra.common.awt.GShape;
import org.geogebra.common.awt.MyImage;
import org.geogebra.common.factories.AwtFactory;
import org.geogebra.common.util.debug.Log;
import org.geogebra.desktop.factories.AwtFactoryD;
import org.geogebra.desktop.gui.MyImageD;
import com.kitfox.svg.SVGException;
/**
* Desktop implementation of Graphics2D; wraps the java.awt.Graphics2D class
*
* @author Zbynek
*
*/
public class GGraphics2DD implements GGraphics2D {
private Graphics2D impl;
/**
*
* @param g2Dtemp
* wrapped graphics
*/
public GGraphics2DD(Graphics2D g2Dtemp) {
impl = g2Dtemp;
}
@Override
public void drawString(String str, int x, int y) {
impl.drawString(str, x, y);
}
@Override
public void drawString(String str, double x, double y) {
impl.drawString(str, (float) x, (float) y);
}
@Override
public void setComposite(GComposite comp) {
impl.setComposite(GCompositeD.getAwtComposite(comp));
}
@Override
public void setPaint(GPaint paint) {
if (paint instanceof GColor) {
impl.setPaint(GColorD.getAwtColor((GColor) paint));
} else if (paint instanceof GGradientPaintD) {
impl.setPaint(((GGradientPaintD) paint).getPaint());
return;
} else if (paint instanceof GTexturePaintD) {
impl.setPaint(((GTexturePaintD) paint).getPaint());
return;
} else {
Log.error("unknown paint type");
}
}
private static Key getAwtHintKey(int key) {
switch (key) {
case com.himamis.retex.renderer.share.platform.graphics.RenderingHints.KEY_ANTIALIASING:
return RenderingHints.KEY_ANTIALIASING;
case com.himamis.retex.renderer.share.platform.graphics.RenderingHints.KEY_RENDERING:
return RenderingHints.KEY_RENDERING;
case com.himamis.retex.renderer.share.platform.graphics.RenderingHints.KEY_TEXT_ANTIALIASING:
return RenderingHints.KEY_TEXT_ANTIALIASING;
case com.himamis.retex.renderer.share.platform.graphics.RenderingHints.KEY_INTERPOLATION:
return RenderingHints.KEY_INTERPOLATION;
}
return null;
}
private static Object getAwtHintValue(int value) {
switch (value) {
case com.himamis.retex.renderer.share.platform.graphics.RenderingHints.VALUE_ANTIALIAS_ON:
return RenderingHints.VALUE_ANTIALIAS_ON;
case com.himamis.retex.renderer.share.platform.graphics.RenderingHints.VALUE_RENDER_QUALITY:
return RenderingHints.VALUE_RENDER_QUALITY;
case com.himamis.retex.renderer.share.platform.graphics.RenderingHints.VALUE_TEXT_ANTIALIAS_ON:
return RenderingHints.VALUE_TEXT_ANTIALIAS_ON;
case com.himamis.retex.renderer.share.platform.graphics.RenderingHints.VALUE_INTERPOLATION_BILINEAR:
return RenderingHints.VALUE_INTERPOLATION_BILINEAR;
case com.himamis.retex.renderer.share.platform.graphics.RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR:
return RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
case com.himamis.retex.renderer.share.platform.graphics.RenderingHints.VALUE_INTERPOLATION_BICUBIC:
return RenderingHints.VALUE_INTERPOLATION_BICUBIC;
}
return null;
}
@Override
public void setRenderingHint(int key, int value) {
impl.setRenderingHint(getAwtHintKey(key), getAwtHintValue(value));
}
@Override
public void translate(double tx, double ty) {
impl.translate(tx, ty);
}
@Override
public void scale(double sx, double sy) {
impl.scale(sx, sy);
}
@Override
public void transform(GAffineTransform Tx) {
impl.transform(GAffineTransformD.getAwtAffineTransform(Tx));
}
/**
*
* @return currently used paint
*/
public GPaint getPaint() {
Paint paint = impl.getPaint();
if (paint instanceof Color) {
return GColorD.newColor((Color) paint);
} else if (paint instanceof GradientPaint) {
return new GGradientPaintD((GradientPaint) paint);
}
// other types of paint are currently not used in setPaint
return null;
}
@Override
public GComposite getComposite() {
return new GCompositeD(impl.getComposite());
}
@Override
public GColor getBackground() {
return GColorD.newColor(impl.getBackground());
}
@Override
public GFontRenderContext getFontRenderContext() {
return new GFontRenderContextD(impl.getFontRenderContext());
}
@Override
public GColor getColor() {
return GColorD.newColor(impl.getColor());
}
@Override
public GFont getFont() {
return new GFontD(impl.getFont());
}
/**
* @param g2
* graphics object
* @return wrapped implementation
*/
public static Graphics2D getAwtGraphics(GGraphics2D g2) {
return ((GGraphics2DD) g2).impl;
}
@Override
public void setFont(GFont font) {
impl.setFont(GFontD.getAwtFont(font));
}
@Override
public void setStroke(GBasicStroke s) {
impl.setStroke(
((AwtFactoryD) AwtFactory.getPrototype()).getAwtStroke(s));
}
@Override
public void setColor(GColor selColor) {
impl.setColor(GColorD.getAwtColor(selColor));
}
@Override
public GBasicStroke getStroke() {
return (GBasicStrokeD) impl.getStroke();
}
@Override
public void drawImage(GBufferedImage img, int x, int y) {
impl.drawImage(GBufferedImageD.getAwtBufferedImage(img), x, y, null);
}
@Override
public void drawImage(MyImage img, int x, int y) {
MyImageD imgD = (MyImageD) img;
if (imgD.isSVG()) {
try {
// TODO: x, y
imgD.getDiagram().render(impl);
} catch (SVGException e) {
e.printStackTrace();
}
} else {
impl.drawImage(imgD.getImage(), x, y, null);
}
}
@Override
public void fillRect(int x, int y, int width, int height) {
impl.fillRect(x, y, width, height);
}
@Override
public void clearRect(int x, int y, int width, int height) {
impl.clearRect(x, y, width, height);
}
@Override
public void drawLine(int x1, int y1, int x2, int y2) {
impl.drawLine(x1, y1, x2, y2);
}
@Override
public void setClip(GShape shape) {
if (shape == null) {
impl.setClip(null);
} else if (shape instanceof GShapeD) {
impl.setClip(GGenericShapeD.getAwtShape(shape));
}
}
@Override
public void resetClip() {
impl.setClip(null);
}
@Override
public void drawRect(int x, int y, int width, int height) {
impl.drawRect(x, y, width, height);
}
@Override
public void setClip(int x, int y, int width, int height) {
impl.setClip(x, y, width, height);
}
/**
* Replace wrapped graphics
*
* @param g
* implementation
*/
public void setImpl(Graphics2D g) {
impl = g;
}
@Override
public void drawRoundRect(int x, int y, int width, int height, int arcWidth,
int arcHeight) {
impl.drawRoundRect(x, y, width, height, arcWidth, arcHeight);
}
@Override
public void fillRoundRect(int x, int y, int width, int height, int arcWidth,
int arcHeight) {
impl.fillRoundRect(x, y, width, height, arcWidth, arcHeight);
}
@Override
public void setAntialiasing() {
setAntialiasing(impl);
}
/**
* @param g2
* initialise g2 for best quality rendering
*/
public static void setAntialiasing(Graphics2D g2) {
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING,
RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g2.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
g2.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
}
@Override
public void setTransparent() {
impl.setComposite(AlphaComposite.Src);
}
@Override
public void draw(GShape shape) {
impl.draw(GGenericShapeD.getAwtShape(shape));
}
@Override
public void fill(GShape shape) {
impl.fill(GGenericShapeD.getAwtShape(shape));
}
@Override
public Object setInterpolationHint(
boolean needsInterpolationRenderingHint) {
Graphics2D g2 = impl;
Object oldInterpolationHint = g2
.getRenderingHint(RenderingHints.KEY_INTERPOLATION);
if (oldInterpolationHint == null) {
oldInterpolationHint = RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR;
}
if (needsInterpolationRenderingHint) {
// improve rendering quality for transformed images
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
} else {
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_NEAREST_NEIGHBOR);
}
return oldInterpolationHint;
}
@Override
public void resetInterpolationHint(Object hint) {
impl.setRenderingHint(RenderingHints.KEY_INTERPOLATION, hint);
}
@Override
public void updateCanvasColor() {
// TODO Auto-generated method stub
}
private GLine2D line = AwtFactory.getPrototype().newLine2D();
@Override
public void drawStraightLine(double x1, double y1, double x2, double y2) {
line.setLine(x1, y1, x2, y2);
// turn off "pure" to avoid blurry axes
impl.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_DEFAULT);
impl.draw(GGenericShapeD.getAwtShape(line));
impl.setRenderingHint(RenderingHints.KEY_STROKE_CONTROL,
RenderingHints.VALUE_STROKE_PURE);
}
/**
* Dispose wrapped implementation
*/
public void dispose() {
impl.dispose();
}
/**
* @param img
* image
* @param x
* left
* @param y
* top
* @param width
* width
* @param height
* height
*/
public void drawImage(MyImageD img, int x, int y, int width, int height) {
if (img.isSVG()) {
try {
// TODO: scaling
img.getDiagram().render(impl);
} catch (SVGException e) {
e.printStackTrace();
}
} else {
impl.drawImage(img.getImage(), x, y, width, height, null);
}
}
private AffineTransform affineTransform;
@Override
public void saveTransform() {
affineTransform = impl.getTransform();
}
@Override
public void restoreTransform() {
if (affineTransform == null) {
throw new RuntimeException("Save transform was not called!");
}
impl.setTransform(affineTransform);
affineTransform = null;
}
}