faster bitmap export

This commit is contained in:
honfika@gmail.com
2015-05-13 16:20:54 +02:00
parent a63ff9a95e
commit a79d7d6956
4 changed files with 186 additions and 194 deletions

View File

@@ -491,7 +491,7 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
int idx;
IMorphEdge prevEdge = null;
List<IMorphEdge> tmpPath = new ArrayList<>();
Map<String, List<IMorphEdge>> coordMap = createCoordMap(subPath);
Map<PointInt, List<IMorphEdge>> coordMap = createCoordMap(subPath);
while (subPath.size() > 0) {
idx = 0;
while (idx < subPath.size()) {
@@ -516,16 +516,15 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
}
}
protected Map<String, List<IMorphEdge>> createCoordMap(List<IMorphEdge> path) {
Map<String, List<IMorphEdge>> coordMap = new HashMap<>();
protected Map<PointInt, List<IMorphEdge>> createCoordMap(List<IMorphEdge> path) {
Map<PointInt, List<IMorphEdge>> coordMap = new HashMap<>();
for (int i = 0; i < path.size(); i++) {
PointInt from = path.get(i).getFrom();
String key = from.getX() + "_" + from.getY();
List<IMorphEdge> coordMapArray = coordMap.get(key);
List<IMorphEdge> coordMapArray = coordMap.get(from);
if (coordMapArray == null) {
List<IMorphEdge> list = new ArrayList<>();
list.add(path.get(i));
coordMap.put(key, list);
coordMap.put(from, list);
} else {
coordMapArray.add(path.get(i));
}
@@ -533,12 +532,12 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
return coordMap;
}
protected void removeEdgeFromCoordMap(Map<String, List<IMorphEdge>> coordMap, IMorphEdge edge) {
String key = edge.getFrom().getX() + "_" + edge.getFrom().getY();
List<IMorphEdge> coordMapArray = coordMap.get(key);
protected void removeEdgeFromCoordMap(Map<PointInt, List<IMorphEdge>> coordMap, IMorphEdge edge) {
PointInt from = edge.getFrom();
List<IMorphEdge> coordMapArray = coordMap.get(from);
if (coordMapArray != null) {
if (coordMapArray.size() == 1) {
coordMap.remove(key);
coordMap.remove(from);
} else {
int i = coordMapArray.indexOf(edge);
if (i > -1) {
@@ -548,9 +547,8 @@ public abstract class MorphShapeExporterBase implements IMorphShapeExporter {
}
}
protected IMorphEdge findNextEdgeInCoordMap(Map<String, List<IMorphEdge>> coordMap, IMorphEdge edge) {
String key = edge.getTo().getX() + "_" + edge.getTo().getY();
List<IMorphEdge> coordMapArray = coordMap.get(key);
protected IMorphEdge findNextEdgeInCoordMap(Map<PointInt, List<IMorphEdge>> coordMap, IMorphEdge edge) {
List<IMorphEdge> coordMapArray = coordMap.get(edge.getTo());
if (coordMapArray != null && coordMapArray.size() > 0) {
return coordMapArray.get(0);
}

View File

@@ -68,7 +68,7 @@ public class BitmapExporter extends ShapeExporterBase {
private final SWF swf;
private GeneralPath path;
private GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD); //For correct intersections display;
private Paint fillPathPaint;
@@ -508,174 +508,173 @@ public class BitmapExporter extends ShapeExporterBase {
}
protected void finalizePath() {
if (path != null) {
if (fillPaint != null) {
graphics.setComposite(AlphaComposite.SrcOver);
if (fillPaint instanceof MultipleGradientPaint) {
AffineTransform oldAf = graphics.getTransform();
if (fillPathPaint != null) {
graphics.setPaint(fillPathPaint);
}
graphics.fill(path);
graphics.setClip(path);
Matrix inverse = null;
try {
double scx = fillTransform.getScaleX();
double scy = fillTransform.getScaleY();
double shx = fillTransform.getShearX();
double shy = fillTransform.getShearY();
double det = scx * scy - shx * shy;
if (Math.abs(det) <= Double.MIN_VALUE) {
// use only the translate values
// todo: make it better
fillTransform.setToTranslation(fillTransform.getTranslateX(), fillTransform.getTranslateY());
}
inverse = new Matrix(new AffineTransform(fillTransform).createInverse());
} catch (NoninvertibleTransformException ex) {
// it should never happen as we already checked the determinant of the matrix
}
fillTransform.preConcatenate(oldAf);
graphics.setTransform(fillTransform);
graphics.setPaint(fillPaint);
if (inverse != null) {
ExportRectangle rect = inverse.transform(new ExportRectangle(path.getBounds2D()));
double minX = rect.xMin;
double minY = rect.yMin;
graphics.fill(new java.awt.Rectangle((int) minX, (int) minY, (int) (rect.xMax - minX), (int) (rect.yMax - minY)));
}
graphics.setTransform(oldAf);
graphics.setClip(null);
} else if (fillPaint instanceof TexturePaint) {
AffineTransform oldAf = graphics.getTransform();
graphics.setClip(path);
Matrix inverse = null;
try {
double scx = fillTransform.getScaleX();
double scy = fillTransform.getScaleY();
double shx = fillTransform.getShearX();
double shy = fillTransform.getShearY();
double det = scx * scy - shx * shy;
if (Math.abs(det) <= Double.MIN_VALUE) {
// use only the translate values
// todo: make it better
fillTransform.setToTranslation(fillTransform.getTranslateX(), fillTransform.getTranslateY());
}
inverse = new Matrix(new AffineTransform(fillTransform).createInverse());
} catch (NoninvertibleTransformException ex) {
// it should never happen as we already checked the determinant of the matrix
}
fillTransform.preConcatenate(oldAf);
graphics.setTransform(fillTransform);
graphics.setPaint(fillPaint);
if (inverse != null) {
ExportRectangle rect = inverse.transform(new ExportRectangle(path.getBounds2D()));
double minX = rect.xMin;
double minY = rect.yMin;
graphics.fill(new Rectangle((int) minX, (int) minY, (int) (rect.xMax - minX), (int) (rect.yMax - minY)));
}
graphics.setTransform(oldAf);
graphics.setClip(null);
} else {
graphics.setPaint(fillPaint);
graphics.fill(path);
if (fillPaint != null) {
graphics.setComposite(AlphaComposite.SrcOver);
if (fillPaint instanceof MultipleGradientPaint) {
AffineTransform oldAf = graphics.getTransform();
if (fillPathPaint != null) {
graphics.setPaint(fillPathPaint);
}
}
if (linePaint != null && lineStroke != null) {
Shape strokedShape = lineStroke.createStrokedShape(path);
graphics.setComposite(AlphaComposite.SrcOver);
if (linePaint instanceof MultipleGradientPaint) {
AffineTransform oldAf = graphics.getTransform();
if (linePathPaint != null) {
graphics.setPaint(linePathPaint);
}
graphics.fill(strokedShape);
graphics.setClip(strokedShape);
Matrix inverse = null;
try {
double scx = lineTransform.getScaleX();
double scy = lineTransform.getScaleY();
double shx = lineTransform.getShearX();
double shy = lineTransform.getShearY();
double det = scx * scy - shx * shy;
if (Math.abs(det) <= Double.MIN_VALUE) {
// use only the translate values
// todo: make it better
lineTransform.setToTranslation(lineTransform.getTranslateX(), lineTransform.getTranslateY());
}
inverse = new Matrix(new AffineTransform(lineTransform).createInverse());
} catch (NoninvertibleTransformException ex) {
// it should never happen as we already checked the determinant of the matrix
graphics.fill(path);
graphics.setClip(path);
Matrix inverse = null;
try {
double scx = fillTransform.getScaleX();
double scy = fillTransform.getScaleY();
double shx = fillTransform.getShearX();
double shy = fillTransform.getShearY();
double det = scx * scy - shx * shy;
if (Math.abs(det) <= Double.MIN_VALUE) {
// use only the translate values
// todo: make it better
fillTransform.setToTranslation(fillTransform.getTranslateX(), fillTransform.getTranslateY());
}
lineTransform.preConcatenate(oldAf);
graphics.setTransform(lineTransform);
graphics.setPaint(linePaint);
inverse = new Matrix(new AffineTransform(fillTransform).createInverse());
if (inverse != null) {
ExportRectangle rect = inverse.transform(new ExportRectangle(strokedShape.getBounds2D()));
double minX = rect.xMin;
double minY = rect.yMin;
graphics.fill(new java.awt.Rectangle((int) minX, (int) minY, (int) (rect.xMax - minX), (int) (rect.yMax - minY)));
}
graphics.setTransform(oldAf);
graphics.setClip(null);
} else if (linePaint instanceof TexturePaint) {
AffineTransform oldAf = graphics.getTransform();
graphics.setClip(strokedShape);
Matrix inverse = null;
try {
double scx = lineTransform.getScaleX();
double scy = lineTransform.getScaleY();
double shx = lineTransform.getShearX();
double shy = lineTransform.getShearY();
double det = scx * scy - shx * shy;
if (Math.abs(det) <= Double.MIN_VALUE) {
// use only the translate values
// todo: make it better
lineTransform.setToTranslation(lineTransform.getTranslateX(), lineTransform.getTranslateY());
}
inverse = new Matrix(new AffineTransform(lineTransform).createInverse());
} catch (NoninvertibleTransformException ex) {
// it should never happen as we already checked the determinant of the matrix
}
lineTransform.preConcatenate(oldAf);
graphics.setTransform(lineTransform);
graphics.setPaint(linePaint);
if (inverse != null) {
ExportRectangle rect = inverse.transform(new ExportRectangle(path.getBounds2D()));
double minX = rect.xMin;
double minY = rect.yMin;
graphics.fill(new Rectangle((int) minX, (int) minY, (int) (rect.xMax - minX), (int) (rect.yMax - minY)));
}
graphics.setTransform(oldAf);
graphics.setClip(null);
} else {
graphics.setPaint(linePaint);
graphics.fill(strokedShape);
} catch (NoninvertibleTransformException ex) {
// it should never happen as we already checked the determinant of the matrix
}
} else if (lineColor != null) {
graphics.setColor(lineColor);
graphics.setStroke(lineStroke == null ? defaultStroke : lineStroke);
graphics.draw(path);
fillTransform.preConcatenate(oldAf);
graphics.setTransform(fillTransform);
graphics.setPaint(fillPaint);
if (inverse != null) {
ExportRectangle rect = inverse.transform(new ExportRectangle(path.getBounds2D()));
double minX = rect.xMin;
double minY = rect.yMin;
graphics.fill(new java.awt.Rectangle((int) minX, (int) minY, (int) (rect.xMax - minX), (int) (rect.yMax - minY)));
}
graphics.setTransform(oldAf);
graphics.setClip(null);
} else if (fillPaint instanceof TexturePaint) {
AffineTransform oldAf = graphics.getTransform();
graphics.setClip(path);
Matrix inverse = null;
try {
double scx = fillTransform.getScaleX();
double scy = fillTransform.getScaleY();
double shx = fillTransform.getShearX();
double shy = fillTransform.getShearY();
double det = scx * scy - shx * shy;
if (Math.abs(det) <= Double.MIN_VALUE) {
// use only the translate values
// todo: make it better
fillTransform.setToTranslation(fillTransform.getTranslateX(), fillTransform.getTranslateY());
}
inverse = new Matrix(new AffineTransform(fillTransform).createInverse());
} catch (NoninvertibleTransformException ex) {
// it should never happen as we already checked the determinant of the matrix
}
fillTransform.preConcatenate(oldAf);
graphics.setTransform(fillTransform);
graphics.setPaint(fillPaint);
if (inverse != null) {
ExportRectangle rect = inverse.transform(new ExportRectangle(path.getBounds2D()));
double minX = rect.xMin;
double minY = rect.yMin;
graphics.fill(new Rectangle((int) minX, (int) minY, (int) (rect.xMax - minX), (int) (rect.yMax - minY)));
}
graphics.setTransform(oldAf);
graphics.setClip(null);
} else {
graphics.setPaint(fillPaint);
graphics.fill(path);
}
}
path = new GeneralPath(GeneralPath.WIND_EVEN_ODD); //For correct intersections display
if (linePaint != null && lineStroke != null) {
Shape strokedShape = lineStroke.createStrokedShape(path);
graphics.setComposite(AlphaComposite.SrcOver);
if (linePaint instanceof MultipleGradientPaint) {
AffineTransform oldAf = graphics.getTransform();
if (linePathPaint != null) {
graphics.setPaint(linePathPaint);
}
graphics.fill(strokedShape);
graphics.setClip(strokedShape);
Matrix inverse = null;
try {
double scx = lineTransform.getScaleX();
double scy = lineTransform.getScaleY();
double shx = lineTransform.getShearX();
double shy = lineTransform.getShearY();
double det = scx * scy - shx * shy;
if (Math.abs(det) <= Double.MIN_VALUE) {
// use only the translate values
// todo: make it better
lineTransform.setToTranslation(lineTransform.getTranslateX(), lineTransform.getTranslateY());
}
inverse = new Matrix(new AffineTransform(lineTransform).createInverse());
} catch (NoninvertibleTransformException ex) {
// it should never happen as we already checked the determinant of the matrix
}
lineTransform.preConcatenate(oldAf);
graphics.setTransform(lineTransform);
graphics.setPaint(linePaint);
if (inverse != null) {
ExportRectangle rect = inverse.transform(new ExportRectangle(strokedShape.getBounds2D()));
double minX = rect.xMin;
double minY = rect.yMin;
graphics.fill(new java.awt.Rectangle((int) minX, (int) minY, (int) (rect.xMax - minX), (int) (rect.yMax - minY)));
}
graphics.setTransform(oldAf);
graphics.setClip(null);
} else if (linePaint instanceof TexturePaint) {
AffineTransform oldAf = graphics.getTransform();
graphics.setClip(strokedShape);
Matrix inverse = null;
try {
double scx = lineTransform.getScaleX();
double scy = lineTransform.getScaleY();
double shx = lineTransform.getShearX();
double shy = lineTransform.getShearY();
double det = scx * scy - shx * shy;
if (Math.abs(det) <= Double.MIN_VALUE) {
// use only the translate values
// todo: make it better
lineTransform.setToTranslation(lineTransform.getTranslateX(), lineTransform.getTranslateY());
}
inverse = new Matrix(new AffineTransform(lineTransform).createInverse());
} catch (NoninvertibleTransformException ex) {
// it should never happen as we already checked the determinant of the matrix
}
lineTransform.preConcatenate(oldAf);
graphics.setTransform(lineTransform);
graphics.setPaint(linePaint);
if (inverse != null) {
ExportRectangle rect = inverse.transform(new ExportRectangle(path.getBounds2D()));
double minX = rect.xMin;
double minY = rect.yMin;
graphics.fill(new Rectangle((int) minX, (int) minY, (int) (rect.xMax - minX), (int) (rect.yMax - minY)));
}
graphics.setTransform(oldAf);
graphics.setClip(null);
} else {
graphics.setPaint(linePaint);
graphics.fill(strokedShape);
}
} else if (lineColor != null) {
graphics.setColor(lineColor);
graphics.setStroke(lineStroke == null ? defaultStroke : lineStroke);
graphics.draw(path);
}
path.reset();
lineStroke = null;
lineColor = null;
fillPaint = null;

View File

@@ -35,8 +35,6 @@ public class PathExporter extends ShapeExporterBase {
private GeneralPath path = new GeneralPath(GeneralPath.WIND_EVEN_ODD);
private final double unitDivisor = 1;
public static List<GeneralPath> export(SHAPE shape) {
PathExporter exporter = new PathExporter(shape, new ColorTransform());
exporter.export();
@@ -114,18 +112,17 @@ public class PathExporter extends ShapeExporterBase {
@Override
public void moveTo(double x, double y) {
path.moveTo(x / unitDivisor, y / unitDivisor);
path.moveTo(x, y);
}
@Override
public void lineTo(double x, double y) {
path.lineTo(x / unitDivisor, y / unitDivisor);
path.lineTo(x, y);
}
@Override
public void curveTo(double controlX, double controlY, double anchorX, double anchorY) {
path.quadTo(controlX / unitDivisor, controlY / unitDivisor,
anchorX / unitDivisor, anchorY / unitDivisor);
path.quadTo(controlX, controlY, anchorX, anchorY);
}
protected void finalizePath() {

View File

@@ -428,7 +428,7 @@ public abstract class ShapeExporterBase implements IShapeExporter {
int idx;
IEdge prevEdge = null;
List<IEdge> tmpPath = new ArrayList<>();
Map<String, List<IEdge>> coordMap = createCoordMap(subPath);
Map<PointInt, List<IEdge>> coordMap = createCoordMap(subPath);
while (subPath.size() > 0) {
idx = 0;
while (idx < subPath.size()) {
@@ -453,16 +453,15 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
}
private Map<String, List<IEdge>> createCoordMap(List<IEdge> path) {
Map<String, List<IEdge>> coordMap = new HashMap<>();
private Map<PointInt, List<IEdge>> createCoordMap(List<IEdge> path) {
Map<PointInt, List<IEdge>> coordMap = new HashMap<>();
for (int i = 0; i < path.size(); i++) {
PointInt from = path.get(i).getFrom();
String key = from.getX() + "_" + from.getY();
List<IEdge> coordMapArray = coordMap.get(key);
List<IEdge> coordMapArray = coordMap.get(from);
if (coordMapArray == null) {
List<IEdge> list = new ArrayList<>();
list.add(path.get(i));
coordMap.put(key, list);
coordMap.put(from, list);
} else {
coordMapArray.add(path.get(i));
}
@@ -470,12 +469,12 @@ public abstract class ShapeExporterBase implements IShapeExporter {
return coordMap;
}
private void removeEdgeFromCoordMap(Map<String, List<IEdge>> coordMap, IEdge edge) {
String key = edge.getFrom().getX() + "_" + edge.getFrom().getY();
List<IEdge> coordMapArray = coordMap.get(key);
private void removeEdgeFromCoordMap(Map<PointInt, List<IEdge>> coordMap, IEdge edge) {
PointInt from = edge.getFrom();
List<IEdge> coordMapArray = coordMap.get(from);
if (coordMapArray != null) {
if (coordMapArray.size() == 1) {
coordMap.remove(key);
coordMap.remove(from);
} else {
int i = coordMapArray.indexOf(edge);
if (i > -1) {
@@ -485,9 +484,8 @@ public abstract class ShapeExporterBase implements IShapeExporter {
}
}
private IEdge findNextEdgeInCoordMap(Map<String, List<IEdge>> coordMap, IEdge edge) {
String key = edge.getTo().getX() + "_" + edge.getTo().getY();
List<IEdge> coordMapArray = coordMap.get(key);
private IEdge findNextEdgeInCoordMap(Map<PointInt, List<IEdge>> coordMap, IEdge edge) {
List<IEdge> coordMapArray = coordMap.get(edge.getTo());
if (coordMapArray != null && coordMapArray.size() > 0) {
return coordMapArray.get(0);
}