package com.kreative.paint.io;
import java.awt.*;
import java.awt.geom.AffineTransform;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.Collection;
import java.util.zip.*;
import com.kreative.paint.*;
import com.kreative.paint.Canvas;
import com.kreative.paint.document.draw.DrawObject;
import com.kreative.paint.document.draw.PaintSettings;
import com.kreative.paint.document.draw.TextAlignment;
import com.kreative.paint.document.tile.Tile;
import com.kreative.paint.document.tile.TileSurface;
public class CKPaintSerializer extends Serializer {
private static final int TYPE_CANVAS = fcc("Canv");
private static final int TYPE_LAYER = fcc("Layr");
private static final int TYPE_PAINT_SETTINGS = fcc("PtSt");
private static final int TYPE_TILE = fcc("Tile");
private static final int TYPE_TILE_SURFACE = fcc("TSrf");
private static final int BI_TYPE_INT_ARGB = fcc("argb");
protected void loadRecognizedTypesAndClasses() {
addTypeAndClass(TYPE_CANVAS, 1, Canvas.class);
addTypeAndClass(TYPE_LAYER, 1, Layer.class);
addTypeAndClass(TYPE_PAINT_SETTINGS, 3, PaintSettings.class);
addTypeAndClass(TYPE_TILE, 2, Tile.class);
addTypeAndClass(TYPE_TILE_SURFACE, 1, TileSurface.class);
}
public void serializeObject(Object o, DataOutputStream stream) throws IOException {
if (o instanceof Canvas) {
Canvas v = (Canvas)o;
stream.writeInt(v.getWidth());
stream.writeInt(v.getHeight());
stream.writeInt(v.getDPIX());
stream.writeInt(v.getDPIY());
stream.writeInt(-1);
stream.writeInt(v.getHotspotX());
stream.writeInt(v.getHotspotY());
SerializationManager.writeObject(v.getPaintSelection(), stream);
stream.writeInt(v.size());
for (Layer l : v) {
SerializationManager.writeObject(l, stream);
}
} else if (o instanceof Layer) {
Layer v = (Layer)o;
stream.writeUTF(v.getName());
stream.writeBoolean(v.isVisible());
stream.writeBoolean(v.isLocked());
stream.writeBoolean(v.isSelected());
stream.writeBoolean(true);
stream.writeInt(v.getX());
stream.writeInt(v.getY());
stream.writeInt(v.getMatte());
stream.writeInt(BI_TYPE_INT_ARGB);
stream.writeInt(v.getTileSize());
Collection<Tile> tiles = v.getTiles();
stream.writeInt(tiles.size());
for (Tile tile : tiles) {
SerializationManager.writeObject(tile, stream);
}
stream.writeInt(v.size());
for (DrawObject d : v) {
SerializationManager.writeObject(d, stream);
}
SerializationManager.writeObject(v.getClip(), stream);
SerializationManager.writeObject(v.getPoppedImage(), stream);
SerializationManager.writeObject(v.getPoppedImageTransform(), stream);
} else if (o instanceof PaintSettings) {
PaintSettings v = (PaintSettings)o;
SerializationManager.writeObject(v.fillPaint, stream);
SerializationManager.writeObject(v.fillComposite, stream);
SerializationManager.writeObject(v.fillAntiAliased, stream);
SerializationManager.writeObject(v.drawPaint, stream);
SerializationManager.writeObject(v.drawComposite, stream);
SerializationManager.writeObject(v.drawStroke, stream);
SerializationManager.writeObject(v.drawAntiAliased, stream);
SerializationManager.writeObject(v.textFont, stream);
SerializationManager.writeObject(v.textAlignment.awtValue, stream);
SerializationManager.writeObject(v.textAntiAliased, stream);
} else if (o instanceof Tile) {
Tile v = (Tile)o;
int x = v.getX();
int y = v.getY();
int width = v.getWidth();
int height = v.getHeight();
int matte = v.getMatte();
stream.writeInt(x);
stream.writeInt(y);
stream.writeInt(width);
stream.writeInt(height);
stream.writeInt(matte);
int[] rgb = new int[width * height];
v.getRGB(x, y, width, height, rgb, 0, width);
ByteArrayOutputStream bos = new ByteArrayOutputStream();
DeflaterOutputStream dos = new DeflaterOutputStream(bos);
for (int p : rgb) dos.write((p >> 24) & 0xFF);
for (int p : rgb) dos.write((p >> 16) & 0xFF);
for (int p : rgb) dos.write((p >> 8) & 0xFF);
for (int p : rgb) dos.write(p & 0xFF);
dos.finish();
dos.close();
bos.close();
byte crgb[] = bos.toByteArray();
stream.writeInt(crgb.length);
stream.write(crgb);
} else if (o instanceof TileSurface) {
TileSurface v = (TileSurface)o;
stream.writeInt(v.getX());
stream.writeInt(v.getY());
stream.writeInt(v.getTileWidth());
stream.writeInt(v.getTileHeight());
stream.writeInt(v.getMatte());
Collection<Tile> tiles = v.getTiles();
stream.writeInt(tiles.size());
for (Tile t : tiles) SerializationManager.writeObject(t, stream);
}
}
public Object deserializeObject(int type, int version, DataInputStream stream) throws IOException {
if (type == TYPE_CANVAS) {
if (version != 1) throw new IOException("Invalid version number.");
int w = stream.readInt();
int h = stream.readInt();
int dx = stream.readInt();
int dy = stream.readInt();
Canvas o = new Canvas(w,h,dx,dy);
o.clear();
int n = stream.readInt();
if (n == -1) {
int hsx = stream.readInt();
int hsy = stream.readInt();
Shape s = (Shape)SerializationManager.readObject(stream);
o.setHotspot(hsx, hsy);
o.setPaintSelection(s);
n = stream.readInt();
} else {
o.setHotspot(0, 0);
o.setPaintSelection(null);
}
for (int i = 0; i < n; i++) {
Layer l = (Layer)SerializationManager.readObject(stream);
o.add(l);
}
return o;
} else if (type == TYPE_LAYER) {
if (version != 1) throw new IOException("Invalid version number.");
String name = stream.readUTF();
boolean vis = stream.readBoolean();
boolean lock = stream.readBoolean();
boolean sel = stream.readBoolean();
boolean v2 = stream.readBoolean();
int x = stream.readInt();
int y = stream.readInt();
int matte = stream.readInt();
stream.readInt();
int tsize = stream.readInt();
Layer l = new Layer(tsize, matte);
l.setName(name);
l.setVisible(vis);
l.setLocked(lock);
l.setSelected(sel);
l.setX(x);
l.setY(y);
int ntiles = stream.readInt();
for (int i = 0; i < ntiles; i++) {
Tile tile = (Tile)SerializationManager.readObject(stream);
l.addTile(tile);
}
int nobjs = stream.readInt();
for (int i = 0; i < nobjs; i++) {
DrawObject obj = (DrawObject)SerializationManager.readObject(stream);
l.add(obj);
}
if (v2) {
Shape clip = (Shape)SerializationManager.readObject(stream);
BufferedImage pimg = (BufferedImage)SerializationManager.readObject(stream);
AffineTransform ptx = (AffineTransform)SerializationManager.readObject(stream);
l.setClip(clip);
l.setPoppedImage(pimg, ptx);
} else {
l.setClip(null);
l.setPoppedImage(null, null);
}
return l;
} else if (type == TYPE_PAINT_SETTINGS) {
if (version < 1 || version > 3) throw new IOException("Invalid version number.");
if (version < 3) {
Composite dc = (Composite)SerializationManager.readObject(stream);
Paint dp = (Paint)SerializationManager.readObject(stream);
Composite fc = (Composite)SerializationManager.readObject(stream);
Paint fp = (Paint)SerializationManager.readObject(stream);
Stroke st = (Stroke)SerializationManager.readObject(stream);
Font fn = (Font)SerializationManager.readObject(stream);
TextAlignment ta = TextAlignment.forAWTValue((Integer)SerializationManager.readObject(stream));
boolean aa = (version > 1) ? (Boolean)SerializationManager.readObject(stream) : false;
return new PaintSettings(fp, fc, aa, dp, dc, st, aa, fn, ta, aa);
} else {
Paint fp = (Paint)SerializationManager.readObject(stream);
Composite fc = (Composite)SerializationManager.readObject(stream);
boolean fa = (Boolean)SerializationManager.readObject(stream);
Paint dp = (Paint)SerializationManager.readObject(stream);
Composite dc = (Composite)SerializationManager.readObject(stream);
Stroke ds = (Stroke)SerializationManager.readObject(stream);
boolean da = (Boolean)SerializationManager.readObject(stream);
Font tf = (Font)SerializationManager.readObject(stream);
TextAlignment ta = TextAlignment.forAWTValue((Integer)SerializationManager.readObject(stream));
boolean taa = (Boolean)SerializationManager.readObject(stream);
return new PaintSettings(fp, fc, fa, dp, dc, ds, da, tf, ta, taa);
}
} else if (type == TYPE_TILE) {
if (version < 1 || version > 2) throw new IOException("Invalid version number.");
int x = stream.readInt();
int y = stream.readInt();
int width = stream.readInt();
int height = stream.readInt();
int matte = stream.readInt();
int clen = stream.readInt();
byte[] crgb = new byte[clen];
stream.read(crgb);
int[] rgb = new int[width * height];
ByteArrayInputStream bis = new ByteArrayInputStream(crgb);
InflaterInputStream iis = new InflaterInputStream(bis);
for (int i = 0; i < rgb.length; i++) rgb[i] |= ((iis.read() << 24) & 0xFF000000);
for (int i = 0; i < rgb.length; i++) rgb[i] |= ((iis.read() << 16) & 0x00FF0000);
for (int i = 0; i < rgb.length; i++) rgb[i] |= ((iis.read() << 8) & 0xFF00);
for (int i = 0; i < rgb.length; i++) rgb[i] |= (iis.read() & 0xFF);
iis.close();
bis.close();
Tile t = new Tile(x, y, width, height, (version < 2) ? 0x00FFFFFF : matte);
t.setRGB(x, y, width, height, rgb, 0, width);
return t;
} else if (type == TYPE_TILE_SURFACE) {
if (version != 1) throw new IOException("Invalid version number.");
int x = stream.readInt();
int y = stream.readInt();
int width = stream.readInt();
int height = stream.readInt();
int matte = stream.readInt();
int tiles = stream.readInt();
TileSurface ts = new TileSurface(x, y, width, height, matte);
for (int i = 0; i < tiles; i++) {
Tile t = (Tile)SerializationManager.readObject(stream);
ts.addTile(t);
}
return ts;
} else {
return null;
}
}
}