mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-09 07:48:16 +00:00
Fixed Not updating Morphshape end bounds
Fixed SVG import - linear gradients Adding morhpshape with/without updating bounds Fixed nullpointer on gradient linestyle morphshape import
This commit is contained in:
@@ -30,6 +30,8 @@ All notable changes to this project will be documented in this file.
|
||||
- Generic tag editor - morphshape fill - show bitmapId for repeating bitmap fill, gradient matrix for focal gradient
|
||||
- Morphshape SVG export - focalPoint animation
|
||||
- Do not display lines with zero width
|
||||
- Not updating Morphshape end bounds
|
||||
- SVG import - linear gradients
|
||||
|
||||
### Changed
|
||||
- Basic tag info panel always visible even when nothing to display (to avoid flickering)
|
||||
|
||||
@@ -309,7 +309,7 @@ public class ShapeForMorphExporter extends ShapeExporterBase {
|
||||
currentLineStyle = lineStyles.size();
|
||||
LINESTYLE2 lineStyle = new LINESTYLE2();
|
||||
lineStyle.width = (int) thickness;
|
||||
lineStyle.color = new RGBA(color);
|
||||
lineStyle.color = color == null ? null : new RGBA(color);
|
||||
lineStyle.pixelHintingFlag = pixelHinting;
|
||||
switch (scaleMode) {
|
||||
case "NONE":
|
||||
|
||||
@@ -1700,6 +1700,15 @@ public class SvgImporter {
|
||||
//svgTest("types-basicDOM-01-b");
|
||||
}
|
||||
|
||||
private double angle(double x1, double y1, double x2, double y2) {
|
||||
double dx = x2 - x1;
|
||||
double dy = y2 - y1;
|
||||
if (dx == 0 && dy == 0) {
|
||||
return 0;
|
||||
}
|
||||
return Math.atan2(dy, dx);
|
||||
}
|
||||
|
||||
private void applyFillGradients(SvgFill fill, FILLSTYLE fillStyle, RECT bounds, StyleChangeRecord scr, Matrix transform, int shapeNum, SvgStyle style) {
|
||||
if (fill == null || fillStyle == null) {
|
||||
return;
|
||||
@@ -1718,14 +1727,16 @@ public class SvgImporter {
|
||||
double x2 = parseCoordinate(lgfill.x2, 1);
|
||||
double y2 = parseCoordinate(lgfill.y2, 1);
|
||||
|
||||
Matrix xyMatrix = new Matrix();
|
||||
xyMatrix.scaleX = (x2 - x1) * SWF.unitDivisor;
|
||||
xyMatrix.rotateSkew0 = (y2 - y1) * SWF.unitDivisor;
|
||||
xyMatrix.rotateSkew1 = -xyMatrix.rotateSkew0;
|
||||
xyMatrix.scaleY = xyMatrix.scaleX;
|
||||
|
||||
Matrix gmatrix = new Matrix();
|
||||
Matrix tMatrix = new Matrix();
|
||||
if (lgfill.gradientUnits == SvgGradientUnits.OBJECT_BOUNDING_BOX) {
|
||||
Matrix xyMatrix = new Matrix();
|
||||
xyMatrix.scaleX = (x2 - x1) * SWF.unitDivisor;
|
||||
xyMatrix.rotateSkew0 = (y2 - y1) * SWF.unitDivisor;
|
||||
xyMatrix.rotateSkew1 = -xyMatrix.rotateSkew0;
|
||||
xyMatrix.scaleY = xyMatrix.scaleX;
|
||||
|
||||
Matrix gmatrix = new Matrix();
|
||||
|
||||
gmatrix.scaleX = (bounds.Xmax - bounds.Xmin) / SWF.unitDivisor;
|
||||
gmatrix.rotateSkew0 = 0;
|
||||
gmatrix.rotateSkew1 = 0;
|
||||
@@ -1734,23 +1745,53 @@ public class SvgImporter {
|
||||
gmatrix.translateY = bounds.Ymin;
|
||||
x1 *= bounds.getWidth();
|
||||
y1 *= bounds.getHeight();
|
||||
} else {
|
||||
gmatrix = new Matrix(fillStyle.gradientMatrix);
|
||||
x1 *= SWF.unitDivisor;
|
||||
y1 *= SWF.unitDivisor;
|
||||
}
|
||||
|
||||
Matrix zeroStartMatrix = Matrix.getTranslateInstance(0.5, 0);
|
||||
Matrix scaleMatrix = Matrix.getScaleInstance(1 / 16384.0 / 2);
|
||||
Matrix transMatrix = Matrix.getTranslateInstance(x1, y1);
|
||||
|
||||
Matrix zeroStartMatrix = Matrix.getTranslateInstance(0.5, 0);
|
||||
Matrix scaleMatrix = Matrix.getScaleInstance(1 / 16384.0 / 2);
|
||||
Matrix transMatrix = Matrix.getTranslateInstance(x1, y1);
|
||||
|
||||
Matrix tMatrix = new Matrix();
|
||||
tMatrix = tMatrix
|
||||
.concatenate(transMatrix)
|
||||
|
||||
tMatrix = tMatrix.concatenate(transMatrix)
|
||||
.concatenate(gmatrix)
|
||||
.concatenate(xyMatrix)
|
||||
.concatenate(zeroStartMatrix)
|
||||
.concatenate(scaleMatrix);
|
||||
.concatenate(scaleMatrix);
|
||||
} else {
|
||||
Matrix gmatrix = new Matrix(fillStyle.gradientMatrix);
|
||||
x1 *= SWF.unitDivisor;
|
||||
y1 *= SWF.unitDivisor;
|
||||
x2 *= SWF.unitDivisor;
|
||||
y2 *= SWF.unitDivisor;
|
||||
|
||||
Point a = new Point(-16384.0, 0.0);
|
||||
Point b = new Point(16384.0, 0.0);
|
||||
Point c = new Point(x1, y1);
|
||||
Point d = new Point(x2, y2);
|
||||
|
||||
if (!(a.equals(c) && b.equals(d))) {
|
||||
double AdeltaX = b.x - a.x;
|
||||
double AdeltaY = b.y - a.y;
|
||||
|
||||
double BdeltaX = d.x - c.x;
|
||||
double BdeltaY = d.y - c.y;
|
||||
|
||||
double lenAB = Math.sqrt(AdeltaX * AdeltaX + AdeltaY * AdeltaY);
|
||||
double lenCD = Math.sqrt(BdeltaX * BdeltaX + BdeltaY * BdeltaY);
|
||||
|
||||
double rotation = angle(c.x, c.y, d.x, d.y) - angle(a.x, a.y, b.x, b.y);
|
||||
|
||||
double scale = lenCD / lenAB;
|
||||
|
||||
tMatrix = tMatrix
|
||||
.concatenate(Matrix.getTranslateInstance(c.x, c.y))
|
||||
.concatenate(Matrix.getRotateInstance(rotation * 180 / Math.PI))
|
||||
.concatenate(Matrix.getScaleInstance(scale))
|
||||
.concatenate(Matrix.getTranslateInstance(-a.x, -a.y))
|
||||
;
|
||||
}
|
||||
|
||||
tMatrix = tMatrix.concatenate(gmatrix);
|
||||
}
|
||||
fillStyle.gradientMatrix = tMatrix.toMATRIX();
|
||||
} else if (fill instanceof SvgRadialGradient) {
|
||||
SvgRadialGradient rgfill = (SvgRadialGradient) fill;
|
||||
|
||||
@@ -371,7 +371,7 @@ public abstract class MorphShapeTag extends DrawableTag {
|
||||
}
|
||||
|
||||
public void updateEndBounds() {
|
||||
startBounds = SHAPERECORD.getBounds(endEdges.shapeRecords, morphLineStyles.getEndLineStyles(getShapeNum()), getShapeNum() == 2 ? 4 : 3, false);
|
||||
endBounds = SHAPERECORD.getBounds(endEdges.shapeRecords, morphLineStyles.getEndLineStyles(getShapeNum()), getShapeNum() == 2 ? 4 : 3, false);
|
||||
}
|
||||
|
||||
public void updateBounds() {
|
||||
|
||||
@@ -4430,19 +4430,26 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
replace(items, false);
|
||||
}
|
||||
|
||||
public boolean replaceMorphShape(MorphShapeTag morphShape, boolean create) {
|
||||
public boolean replaceMorphShape(MorphShapeTag morphShape, boolean create, boolean fill) {
|
||||
File fileStart = showImportFileChooser("filter.images|*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.svg", true, AppStrings.translate("dialog.morphshape.startShape"));
|
||||
if (fileStart == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
DefineShape4Tag shapeStart = new DefineShape4Tag(morphShape.getSwf());
|
||||
SWF.addTagBefore(shapeStart, morphShape);
|
||||
|
||||
DefineShape4Tag shapeEnd = new DefineShape4Tag(morphShape.getSwf());
|
||||
SWF.addTagBefore(shapeEnd, morphShape);
|
||||
|
||||
shapeStart.shapeBounds = Helper.deepCopy(morphShape.startBounds);
|
||||
shapeEnd.shapeBounds = Helper.deepCopy(morphShape.endBounds);
|
||||
|
||||
if (morphShape instanceof DefineMorphShape2Tag) {
|
||||
DefineMorphShape2Tag ms2 = (DefineMorphShape2Tag) morphShape;
|
||||
shapeStart.edgeBounds = Helper.deepCopy(ms2.startEdgeBounds);
|
||||
shapeEnd.edgeBounds = Helper.deepCopy(ms2.endEdgeBounds);
|
||||
}
|
||||
|
||||
File selfileStart = Helper.fixDialogFile(fileStart);
|
||||
byte[] dataStart = null;
|
||||
@@ -4460,9 +4467,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
try {
|
||||
Tag newStartTag;
|
||||
if (svgTextStart != null) {
|
||||
newStartTag = new SvgImporter().importSvg(shapeStart, shapeEnd, svgTextStart, false);
|
||||
newStartTag = new SvgImporter().importSvg(shapeStart, shapeEnd, svgTextStart, fill);
|
||||
} else {
|
||||
newStartTag = new ShapeImporter().importImage(shapeStart, dataStart, 0, false);
|
||||
newStartTag = new ShapeImporter().importImage(shapeStart, dataStart, 0, fill);
|
||||
}
|
||||
newStartTag.getTimelined().removeTag(newStartTag);
|
||||
|
||||
@@ -4487,9 +4494,9 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
|
||||
Tag newEndTag;
|
||||
if (svgTextEnd != null) {
|
||||
newEndTag = new SvgImporter().importSvg(shapeEnd, svgTextEnd, false);
|
||||
newEndTag = new SvgImporter().importSvg(shapeEnd, svgTextEnd, fill);
|
||||
} else {
|
||||
newEndTag = new ShapeImporter().importImage(shapeEnd, dataEnd, 0, false);
|
||||
newEndTag = new ShapeImporter().importImage(shapeEnd, dataEnd, 0, fill);
|
||||
}
|
||||
newEndTag.getTimelined().removeTag(newEndTag);
|
||||
}
|
||||
@@ -4544,7 +4551,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
file = showImportFileChooser("filter.images|*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.svg", true);
|
||||
}
|
||||
if (ti0 instanceof MorphShapeTag) {
|
||||
return replaceMorphShape((MorphShapeTag) ti0, create);
|
||||
return replaceMorphShape((MorphShapeTag) ti0, create, true);
|
||||
}
|
||||
if (ti0 instanceof DefineVideoStreamTag) {
|
||||
file = showImportFileChooser("filter.movies|*.flv", false);
|
||||
@@ -4741,8 +4748,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
return false;
|
||||
}
|
||||
|
||||
if ((item instanceof ShapeTag) || (item instanceof MorphShapeTag)) {
|
||||
Tag st = (Tag) item;
|
||||
if (item instanceof MorphShapeTag) {
|
||||
return replaceMorphShape((MorphShapeTag) item, false, false);
|
||||
}
|
||||
if (item instanceof ShapeTag) {
|
||||
ShapeTag st = (ShapeTag) item;
|
||||
String filter = "filter.images|*.jpg;*.jpeg;*.gif;*.png;*.bmp;*.svg";
|
||||
File selectedFile = showImportFileChooser(filter, true);
|
||||
if (selectedFile != null) {
|
||||
@@ -4757,20 +4767,11 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
}
|
||||
try {
|
||||
Tag newTag = null;
|
||||
if (st instanceof ShapeTag) {
|
||||
if (svgText != null) {
|
||||
newTag = new SvgImporter().importSvg((ShapeTag) st, svgText, false);
|
||||
} else {
|
||||
newTag = new ShapeImporter().importImage((ShapeTag) st, data, 0, false);
|
||||
}
|
||||
}
|
||||
if (st instanceof MorphShapeTag) {
|
||||
if (svgText != null) {
|
||||
newTag = new SvgImporter().importSvg((MorphShapeTag) st, svgText, false);
|
||||
} else {
|
||||
newTag = new ShapeImporter().importImage((MorphShapeTag) st, data, 0, false);
|
||||
}
|
||||
}
|
||||
if (svgText != null) {
|
||||
newTag = new SvgImporter().importSvg(st, svgText, false);
|
||||
} else {
|
||||
newTag = new ShapeImporter().importImage(st, data, 0, false);
|
||||
}
|
||||
SWF swf = st.getSwf();
|
||||
if (newTag != null) {
|
||||
refreshTree(swf);
|
||||
|
||||
@@ -192,6 +192,8 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
private JButton replaceShapeButton;
|
||||
|
||||
private JButton replaceMorphShapeButton;
|
||||
|
||||
private JButton replaceMorphShapeUpdateBoundsButton;
|
||||
|
||||
private JButton replaceShapeUpdateBoundsButton;
|
||||
|
||||
@@ -1310,10 +1312,20 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
replaceMorphShapeButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
mainPanel.replaceMorphShape((MorphShapeTag) mainPanel.getCurrentTree().getCurrentTreeItem(), false);
|
||||
mainPanel.replaceMorphShape((MorphShapeTag) mainPanel.getCurrentTree().getCurrentTreeItem(), false, true);
|
||||
}
|
||||
});
|
||||
replaceMorphShapeButton.setVisible(false);
|
||||
|
||||
replaceMorphShapeUpdateBoundsButton = new JButton(mainPanel.translate("button.replaceNoFill"), View.getIcon("importmorphshape16"));
|
||||
replaceMorphShapeUpdateBoundsButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
replaceMorphShapeUpdateBoundsButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
mainPanel.replaceMorphShape((MorphShapeTag) mainPanel.getCurrentTree().getCurrentTreeItem(), false, false);
|
||||
}
|
||||
});
|
||||
replaceMorphShapeUpdateBoundsButton.setVisible(false);
|
||||
|
||||
replaceShapeUpdateBoundsButton = new JButton(mainPanel.translate("button.replaceNoFill"), View.getIcon("importshape16"));
|
||||
replaceShapeUpdateBoundsButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
@@ -1375,8 +1387,9 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
displayEditButtonsPanel.add(displayEditEditPointsButton);
|
||||
//displayEditButtonsPanel.add(fixPathsButton);
|
||||
displayEditButtonsPanel.add(replaceShapeButton);
|
||||
displayEditButtonsPanel.add(replaceMorphShapeButton);
|
||||
displayEditButtonsPanel.add(replaceShapeUpdateBoundsButton);
|
||||
displayEditButtonsPanel.add(replaceMorphShapeButton);
|
||||
displayEditButtonsPanel.add(replaceMorphShapeUpdateBoundsButton);
|
||||
displayEditButtonsPanel.add(morphShowPanel);
|
||||
return displayEditButtonsPanel;
|
||||
}
|
||||
@@ -1737,10 +1750,11 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
replaceImageAlphaButton.setVisible(showAlpha);
|
||||
replaceSpriteButton.setVisible(showSprite);
|
||||
replaceShapeButton.setVisible(showShape);
|
||||
replaceMorphShapeButton.setVisible(showMorphShape);
|
||||
replaceMorphShapeButton.setVisible(showMorphShape);
|
||||
morphShowPanel.setVisible(showMorphShape);
|
||||
displayEditEditPointsButton.setVisible(showShape || showMorphShape);
|
||||
replaceShapeUpdateBoundsButton.setVisible(showShape);
|
||||
replaceMorphShapeUpdateBoundsButton.setVisible(showMorphShape);
|
||||
replaceSoundButton.setVisible(showSound);
|
||||
replaceMovieButton.setVisible(showMovie);
|
||||
prevFontsButton.setVisible(false);
|
||||
@@ -2333,6 +2347,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
|
||||
if (displayEditTag instanceof MorphShapeTag) {
|
||||
replaceMorphShapeButton.setVisible(true);
|
||||
replaceMorphShapeUpdateBoundsButton.setVisible(true);
|
||||
displayEditEditPointsButton.setVisible(true);
|
||||
}
|
||||
|
||||
@@ -2384,8 +2399,9 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
displayEditSaveButton.setVisible(true);
|
||||
displayEditCancelButton.setVisible(true);
|
||||
replaceShapeButton.setVisible(false);
|
||||
replaceMorphShapeButton.setVisible(false);
|
||||
replaceMorphShapeButton.setVisible(false);
|
||||
replaceShapeUpdateBoundsButton.setVisible(false);
|
||||
replaceMorphShapeUpdateBoundsButton.setVisible(false);
|
||||
displayEditEditPointsButton.setVisible(false);
|
||||
mainPanel.setEditingStatus();
|
||||
}
|
||||
@@ -2418,6 +2434,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
replaceShapeButton.setVisible(false);
|
||||
replaceMorphShapeButton.setVisible(false);
|
||||
replaceShapeUpdateBoundsButton.setVisible(false);
|
||||
replaceMorphShapeUpdateBoundsButton.setVisible(false);
|
||||
displayEditEditPointsButton.setVisible(false);
|
||||
|
||||
if ((displayEditTag instanceof MorphShapeTag) && (morphDisplayMode == MORPH_ANIMATE)) {
|
||||
@@ -2519,6 +2536,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
replaceShapeButton.setVisible(false);
|
||||
replaceMorphShapeButton.setVisible(false);
|
||||
replaceShapeUpdateBoundsButton.setVisible(false);
|
||||
replaceMorphShapeUpdateBoundsButton.setVisible(false);
|
||||
displayEditEditPointsButton.setVisible(false);
|
||||
|
||||
morphShowPanel.setVisible(false);
|
||||
@@ -2815,6 +2833,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
if (displayEditTag instanceof MorphShapeTag) {
|
||||
morphShowPanel.setVisible(true);
|
||||
replaceMorphShapeButton.setVisible(true);
|
||||
replaceMorphShapeUpdateBoundsButton.setVisible(true);
|
||||
displayEditEditPointsButton.setVisible(true);
|
||||
}
|
||||
|
||||
|
||||
@@ -353,7 +353,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
replaceNoFillMenuItem = new JMenuItem(mainPanel.translate("button.replaceNoFill"));
|
||||
replaceNoFillMenuItem.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
public void actionPerformed(ActionEvent e) {
|
||||
mainPanel.replaceNoFillButtonActionPerformed(getCurrentItem());
|
||||
}
|
||||
});
|
||||
@@ -1046,6 +1046,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
|
||||
if (canReplace.test(it -> it instanceof MorphShapeTag)) {
|
||||
replaceMenuItem.setVisible(true);
|
||||
replaceNoFillMenuItem.setVisible(true);
|
||||
}
|
||||
|
||||
if (canReplace.test(it -> it instanceof DefineBinaryDataTag)) {
|
||||
@@ -3830,7 +3831,7 @@ public class TagTreeContextMenu extends JPopupMenu {
|
||||
remove = !mainPanel.replaceNoFill(tag);
|
||||
break;
|
||||
case MORPH_SHAPE:
|
||||
remove = !mainPanel.replaceMorphShape((MorphShapeTag) tag, true);
|
||||
remove = !mainPanel.replaceMorphShape((MorphShapeTag) tag, true, false);
|
||||
break;
|
||||
case FONT:
|
||||
remove = !mainPanel.fontEmbed(tag, true);
|
||||
|
||||
Reference in New Issue
Block a user