package org.geogebra.desktop.export.epsgraphics;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.awt.image.PixelGrabber;
import org.geogebra.common.awt.GAffineTransform;
import org.geogebra.common.awt.GBufferedImage;
import org.geogebra.common.awt.GColor;
import org.geogebra.common.awt.GFont;
import org.geogebra.common.awt.GGraphics2D;
import org.geogebra.common.awt.GPoint2D;
import org.geogebra.common.awt.GShape;
import org.geogebra.common.awt.MyImage;
import org.geogebra.common.awt.font.GTextLayout;
import org.geogebra.common.factories.AwtFactory;
import org.geogebra.desktop.awt.GBufferedImageD;
import org.geogebra.desktop.awt.GFontRenderContextD;
import org.geogebra.desktop.awt.GGenericShapeD;
import org.geogebra.desktop.awt.GTextLayoutD;
import org.geogebra.desktop.gui.MyImageD;
public class EpsGraphicsD extends EpsGraphics {
@Override
final protected GFontRenderContextD getNewFontRenderContext() {
return new GFontRenderContextD(
new FontRenderContext(null, false, true));
}
public EpsGraphicsD(String string, StringBuilder epsOutput, int i, int j,
int pixelWidth, int pixelHeight, ColorMode colorRgb,
GColor bgColor) {
super(string, epsOutput, i, j, pixelWidth, pixelHeight, colorRgb,
bgColor);
}
public EpsGraphicsD(EpsGraphicsD eps) {
super(eps);
}
@Override
public GGraphics2D create() {
return new EpsGraphicsD(this);
}
@Override
public void drawString(String s, double x, double y, GFont font) {
if (getAccurateTextMode()) {
GTextLayout layout = AwtFactory.getPrototype().newTextLayout(s,
font, getFontRenderContext());
// methodNotSupported();
// GShape shape = layout
// .getOutline(AwtFactory.getTranslateInstance(x, y));
GTextLayoutD layoutD = (GTextLayoutD) layout;
TextLayout layoutNative = layoutD.getImpl();
Shape shapeNative = layoutNative
.getOutline(AffineTransform.getTranslateInstance(x, y));
GShape shape = new GGenericShapeD(shapeNative);
draw(shape, "fill", false);
} else {
append("newpath");
GPoint2D location = transform(x, y);
append(location.getX() + " " + location.getY() + " moveto");
StringBuilder buffer = new StringBuilder();
// for (char ch = iterator.first(); ch != CharacterIterator.DONE; ch
// = iterator
// .next()) {
for (int i = 0; i < s.length(); i++) {
char ch = s.charAt(i);
if (ch == '(' || ch == ')') {
buffer.append('\\');
}
buffer.append(ch);
}
append("(" + buffer.toString() + ") show");
}
}
@Override
public void drawImage(GBufferedImage img, int dx1, int dy1, int dx2,
int dy2, int sx1, int sy1, int sx2, int sy2, GColor bgcolor) {
if (dx1 >= dx2) {
throw new IllegalArgumentException("dx1 >= dx2");
}
if (sx1 >= sx2) {
throw new IllegalArgumentException("sx1 >= sx2");
}
if (dy1 >= dy2) {
throw new IllegalArgumentException("dy1 >= dy2");
}
if (sy1 >= sy2) {
throw new IllegalArgumentException("sy1 >= sy2");
}
append("gsave");
int width = sx2 - sx1;
int height = sy2 - sy1;
int destWidth = dx2 - dx1;
int destHeight = dy2 - dy1;
int[] pixels = new int[width * height];
PixelGrabber pg = new PixelGrabber(
GBufferedImageD.getAwtBufferedImage(img), sx1, sy1, sx2 - sx1,
sy2 - sy1, pixels, 0, width);
try {
pg.grabPixels();
} catch (InterruptedException e) {
return;
}
GAffineTransform matrix = AwtFactory.getPrototype()
.newAffineTransform();
matrix.setTransform(_transform);
matrix.translate(dx1, dy1);
matrix.scale(destWidth / (double) width, destHeight / (double) height);
double[] m = new double[6];
try {
matrix = matrix.createInverse();
} catch (Exception e) {
throw new RuntimeException(
"Unable to get inverse of matrix: " + matrix);
}
matrix.scale(1, -1);
matrix.getMatrix(m);
String bitsPerSample = "8";
// TODO Not using proper imagemask function yet
// if (getColorDepth() == BLACK_AND_WHITE) {
// bitsPerSample = "true";
// }
append(width + " " + height + " " + bitsPerSample + " [" + m[0] + " "
+ m[1] + " " + m[2] + " " + m[3] + " " + m[4] + " " + m[5]
+ "]");
// Fill the background to update the bounding box.
GColor oldColor = getColor();
setColor(getBackground());
fillRect(dx1, dy1, destWidth, destHeight);
setColor(oldColor);
if (this.colorMode.equals(ColorMode.BLACK_AND_WHITE)
|| this.colorMode.equals(ColorMode.GRAYSCALE)) {
// TODO Should really use imagemask.
append("{currentfile " + width + " string readhexstring pop} bind");
append("image");
} else {// TODO: no difference between RGB and CMYK
append("{currentfile 3 " + width
+ " mul string readhexstring pop} bind");
append("false 3 colorimage");
}
StringBuffer line = new StringBuffer();
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
GColor color = GColor.newColorRGB(pixels[x + width * y]);
if (this.colorMode.equals(ColorMode.BLACK_AND_WHITE)) {
if (color.getRed() + color.getGreen()
+ color.getBlue() > 255 * 1.5 - 1) {
line.append("ff");
} else {
line.append("00");
}
} else if (this.colorMode.equals(ColorMode.GRAYSCALE)) {
line.append(toHexString((color.getRed() + color.getGreen()
+ color.getBlue()) / 3));
} else {// TODO: no difference between RGB and CMYK
line.append(toHexString(color.getRed())
+ toHexString(color.getGreen())
+ toHexString(color.getBlue()));
}
if (line.length() > 64) {
append(line.toString());
line = new StringBuffer();
}
}
}
if (line.length() > 0) {
append(line.toString());
}
append("grestore");
}
@Override
public void drawImage(MyImage img, int x, int y) {
MyImageD imgd = (MyImageD) img;
BufferedImage bi = (BufferedImage) imgd.getImage();
drawImage(new GBufferedImageD(bi), x, y);
}
@Override
public void setRenderingHint(int hintKey, int hintValue) {
// nothing to do
}
@Override
public void resetClip() {
this.setClip(null);
}
}