/*
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.types.gfx;
import com.jpexs.decompiler.flash.types.shaperecords.CurvedEdgeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
import com.jpexs.decompiler.flash.types.shaperecords.StraightEdgeRecord;
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
import java.io.IOException;
import java.io.Serializable;
import java.util.ArrayList;
import java.util.List;
/**
*
* @author JPEXS
*/
public class ContourType implements Serializable {
public int moveToX;
public int moveToY;
public EdgeType[] edges;
public boolean isReference;
public long reference;
public ContourType(List<SHAPERECORD> records) {
int i = 0;
int divider = 1;
for (; i < records.size(); i++) {
SHAPERECORD rec = records.get(i);
if (rec instanceof StyleChangeRecord) {
StyleChangeRecord scr = (StyleChangeRecord) rec;
if (scr.stateMoveTo) {
moveToX = scr.moveDeltaX / divider;
moveToY = scr.moveDeltaY / divider;
break;
}
}
}
List<EdgeType> edgesList = new ArrayList<>();
for (; i < records.size(); i++) {
SHAPERECORD rec = records.get(i);
if (rec instanceof StraightEdgeRecord) {
StraightEdgeRecord ser = (StraightEdgeRecord) rec;
if (ser.generalLineFlag) {
edgesList.add(new EdgeType(ser.deltaX / divider, ser.deltaY / divider));
} else if (ser.vertLineFlag) {
edgesList.add(new EdgeType(true, ser.deltaY / divider));
} else {
edgesList.add(new EdgeType(false, ser.deltaX / divider));
}
} else if (rec instanceof CurvedEdgeRecord) {
CurvedEdgeRecord cer = (CurvedEdgeRecord) rec;
edgesList.add(new EdgeType(cer.controlDeltaX / divider, cer.controlDeltaY / divider, cer.anchorDeltaX / divider, cer.anchorDeltaY / divider));
}
}
edges = edgesList.toArray(new EdgeType[edgesList.size()]);
}
public ContourType(GFxInputStream sis, long fontOffset) throws IOException {
moveToX = sis.readSI15("moveToX");
moveToY = sis.readSI15("moveToY");
long numEdgesRef = sis.readUI30("numEdgesRef");
isReference = (numEdgesRef & 1) == 1;
numEdgesRef >>= 1;
long oldPos = sis.getPos();
int numEdges;
if (isReference) {
long referencePos = numEdgesRef;
sis.setPos(fontOffset + referencePos);
numEdges = (int) (sis.readUI30("numEdges") >> 1);
} else {
numEdges = (int) numEdgesRef;
}
edges = new EdgeType[(int) numEdges];
for (int i = 0; i < edges.length; i++) {
sis.newDumpLevel("edgeType", "EdgeType");
edges[i] = new EdgeType(sis);
sis.endDumpLevel();
}
if (isReference) {
sis.setPos(oldPos);
}
}
public List<SHAPERECORD> toSHAPERECORDS() {
int multiplier = 1;
List<SHAPERECORD> recs = new ArrayList<>();
StyleChangeRecord src = new StyleChangeRecord();
src.stateMoveTo = true;
src.moveDeltaX = moveToX * multiplier;
src.moveDeltaY = moveToY * multiplier;
src.calculateBits();
recs.add(src);
for (EdgeType e : edges) {
recs.add(e.toSHAPERECORD());
}
int x = src.moveDeltaX;
int y = src.moveDeltaY;
for (SHAPERECORD rec : recs) {
x = rec.changeX(x);
y = rec.changeY(y);
}
StraightEdgeRecord closeSer = new StraightEdgeRecord();
closeSer.generalLineFlag = true;
closeSer.deltaX = (src.moveDeltaX - x);
closeSer.deltaY = (src.moveDeltaY - y);
closeSer.calculateBits();
recs.add(closeSer);
return recs;
}
public void write(GFxOutputStream sos) throws IOException {
sos.writeSI15(moveToX);
sos.writeSI15(moveToY);
sos.writeUI30(edges.length << 1);
for (int i = 0; i < edges.length; i++) {
edges[i].write(sos);
}
}
}