mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-06-26 11:55:46 +00:00
Added #1913 Shape transforming
This commit is contained in:
@@ -2,6 +2,9 @@
|
||||
All notable changes to this project will be documented in this file.
|
||||
|
||||
## [Unreleased]
|
||||
### Added
|
||||
- [#1913] Shape transforming
|
||||
|
||||
### Fixed
|
||||
- [#1915] SVG import - gradient when it has two final stops
|
||||
- Native sound export format for ADPCM compression is FLV
|
||||
|
||||
@@ -24,7 +24,6 @@ import com.jpexs.decompiler.flash.EventListener;
|
||||
import com.jpexs.decompiler.flash.OpenableSourceInfo;
|
||||
import com.jpexs.decompiler.flash.ReadOnlyTagList;
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.abc.ABC;
|
||||
import com.jpexs.decompiler.flash.abc.RenameType;
|
||||
import com.jpexs.decompiler.flash.abc.ScriptPack;
|
||||
@@ -4877,7 +4876,7 @@ public final class MainPanel extends JPanel implements TreeSelectionListener, Se
|
||||
if (treeItem instanceof DefineVideoStreamTag) {
|
||||
previewPanel.setImageReplaceButtonVisible(false, false, false, false, !((Tag) treeItem).isReadOnly());
|
||||
}
|
||||
previewPanel.showImagePanel(timelined, tag.getSwf(), -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), treeItem instanceof ShapeTag, !Configuration.playFrameSounds.get(), (treeItem instanceof DefineSpriteTag) || (treeItem instanceof ButtonTag), (treeItem instanceof DefineSpriteTag) || (treeItem instanceof ButtonTag));
|
||||
previewPanel.showImagePanel(timelined, tag.getSwf(), -1, true, Configuration.autoPlayPreviews.get(), !Configuration.animateSubsprites.get(), treeItem instanceof ShapeTag, !Configuration.playFrameSounds.get(), (treeItem instanceof DefineSpriteTag) || (treeItem instanceof ButtonTag), (treeItem instanceof DefineSpriteTag) || (treeItem instanceof ButtonTag) || (treeItem instanceof ShapeTag));
|
||||
} else if (treeItem instanceof Frame && internalViewer) {
|
||||
Frame fn = (Frame) treeItem;
|
||||
SWF swf = (SWF) fn.getOpenable();
|
||||
|
||||
@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.SWFHeader;
|
||||
import com.jpexs.decompiler.flash.action.parser.ActionParseException;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.exporters.PreviewExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.ExportRectangle;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.gui.controls.JPersistentSplitPane;
|
||||
import com.jpexs.decompiler.flash.gui.debugger.DebuggerTools;
|
||||
@@ -30,8 +31,10 @@ import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel;
|
||||
import com.jpexs.decompiler.flash.gui.player.MediaDisplay;
|
||||
import com.jpexs.decompiler.flash.gui.player.PlayerControls;
|
||||
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineShape4Tag;
|
||||
import com.jpexs.decompiler.flash.tags.DefineSpriteTag;
|
||||
import com.jpexs.decompiler.flash.tags.MetadataTag;
|
||||
import com.jpexs.decompiler.flash.tags.PlaceObject2Tag;
|
||||
import com.jpexs.decompiler.flash.tags.PlaceObject3Tag;
|
||||
import com.jpexs.decompiler.flash.tags.ProductInfoTag;
|
||||
import com.jpexs.decompiler.flash.tags.SetBackgroundColorTag;
|
||||
@@ -43,14 +46,24 @@ import com.jpexs.decompiler.flash.tags.base.ButtonTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
import com.jpexs.decompiler.flash.timeline.Frame;
|
||||
import com.jpexs.decompiler.flash.timeline.TagScript;
|
||||
import com.jpexs.decompiler.flash.timeline.Timelined;
|
||||
import com.jpexs.decompiler.flash.treeitems.TreeItem;
|
||||
import com.jpexs.decompiler.flash.types.BUTTONRECORD;
|
||||
import com.jpexs.decompiler.flash.types.FILLSTYLE;
|
||||
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.LINESTYLE;
|
||||
import com.jpexs.decompiler.flash.types.LINESTYLE2;
|
||||
import com.jpexs.decompiler.flash.types.LINESTYLEARRAY;
|
||||
import com.jpexs.decompiler.flash.types.MATRIX;
|
||||
import com.jpexs.decompiler.flash.types.RECT;
|
||||
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 com.jpexs.helpers.SerializableImage;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.CardLayout;
|
||||
@@ -61,6 +74,7 @@ import java.awt.FlowLayout;
|
||||
import java.awt.GridBagConstraints;
|
||||
import java.awt.GridBagLayout;
|
||||
import java.awt.Insets;
|
||||
import java.awt.Point;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.geom.Point2D;
|
||||
@@ -167,7 +181,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
private JButton replaceImageButton;
|
||||
|
||||
private JButton replaceImageAlphaButton;
|
||||
|
||||
|
||||
private JButton replaceMovieButton;
|
||||
|
||||
private JButton prevFontsButton;
|
||||
@@ -358,7 +372,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
replaceImageAlphaButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
replaceImageAlphaButton.addActionListener(mainPanel::replaceAlphaButtonActionPerformed);
|
||||
replaceImageAlphaButton.setVisible(false);
|
||||
|
||||
|
||||
replaceMovieButton = new JButton(mainPanel.translate("button.replace"), View.getIcon("replacemovie16"));
|
||||
replaceMovieButton.setMargin(new Insets(3, 3, 3, 10));
|
||||
replaceMovieButton.addActionListener(new ActionListener() {
|
||||
@@ -539,7 +553,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
mainPanel.setTagTreeSelectedNode(mainPanel.getCurrentTree(), placeObject);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
imagePanel.setLoop(Configuration.loopMedia.get());
|
||||
|
||||
@@ -702,7 +716,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
genericTagPanel = new GenericTagTreePanel(mainPanel);
|
||||
genericTagCard.add(genericTagPanel, BorderLayout.CENTER);
|
||||
genericTagCard.add(createGenericTagButtonsPanel(), BorderLayout.SOUTH);
|
||||
addGenericListener();
|
||||
addGenericListener();
|
||||
return genericTagCard;
|
||||
}
|
||||
|
||||
@@ -917,7 +931,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
|
||||
binaryPanel.setBinaryData(null);
|
||||
genericTagPanel.clear();
|
||||
fontPanel.clear();
|
||||
fontPanel.clear();
|
||||
}
|
||||
|
||||
public void closeTag() {
|
||||
@@ -1329,7 +1343,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
swf.updateCharacters();
|
||||
tag.getTimelined().resetTimeline();
|
||||
swf.assignClassesToSymbols();
|
||||
swf.assignExportNamesToSymbols();
|
||||
swf.assignExportNamesToSymbols();
|
||||
if (Configuration.editorMode.get()) {
|
||||
genericEditButton.setVisible(false);
|
||||
genericSaveButton.setVisible(true);
|
||||
@@ -1349,7 +1363,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
mainPanel.clearEditingStatus();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void saveGenericTagButtonActionPerformed(ActionEvent evt) {
|
||||
saveGenericTag(true);
|
||||
}
|
||||
@@ -1361,12 +1375,12 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
genericSaveButton.setVisible(true);
|
||||
genericSaveButton.setEnabled(false);
|
||||
genericCancelButton.setVisible(true);
|
||||
genericCancelButton.setEnabled(false);
|
||||
genericCancelButton.setEnabled(false);
|
||||
} else {
|
||||
genericTagPanel.setEditMode(false, null);
|
||||
genericEditButton.setVisible(true);
|
||||
genericSaveButton.setVisible(false);
|
||||
genericCancelButton.setVisible(false);
|
||||
genericCancelButton.setVisible(false);
|
||||
}
|
||||
mainPanel.clearEditingStatus();
|
||||
}
|
||||
@@ -1452,9 +1466,9 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
placeCancelButton.setVisible(true);
|
||||
|
||||
if (Configuration.editorMode.get()) {
|
||||
placeSaveButton.setEnabled(false);
|
||||
placeSaveButton.setEnabled(false);
|
||||
} else {
|
||||
placeSaveButton.setEnabled(true);
|
||||
placeSaveButton.setEnabled(true);
|
||||
}
|
||||
placeCancelButton.setEnabled(true);
|
||||
mainPanel.setEditingStatus();
|
||||
@@ -1475,6 +1489,36 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
}, 40); //add some delay before controls are hidden
|
||||
}
|
||||
|
||||
private void transformStyles(Matrix matrix, FILLSTYLEARRAY fillStyles, LINESTYLEARRAY lineStyles, int shapeNum) {
|
||||
List<FILLSTYLE> fillStyleToTransform = new ArrayList<>();
|
||||
for (FILLSTYLE fs:fillStyles.fillStyles) {
|
||||
fillStyleToTransform.add(fs);
|
||||
}
|
||||
if (shapeNum >= 4) {
|
||||
for(LINESTYLE2 ls:lineStyles.lineStyles2) {
|
||||
if (ls.hasFillFlag) {
|
||||
fillStyleToTransform.add(ls.fillType);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (FILLSTYLE fs:fillStyleToTransform) {
|
||||
switch(fs.fillStyleType) {
|
||||
case FILLSTYLE.CLIPPED_BITMAP:
|
||||
case FILLSTYLE.NON_SMOOTHED_CLIPPED_BITMAP:
|
||||
case FILLSTYLE.NON_SMOOTHED_REPEATING_BITMAP:
|
||||
case FILLSTYLE.REPEATING_BITMAP:
|
||||
fs.bitmapMatrix = new Matrix(fs.bitmapMatrix).preConcatenate(matrix).toMATRIX();
|
||||
break;
|
||||
case FILLSTYLE.LINEAR_GRADIENT:
|
||||
case FILLSTYLE.RADIAL_GRADIENT:
|
||||
case FILLSTYLE.FOCAL_RADIAL_GRADIENT:
|
||||
fs.gradientMatrix = new Matrix(fs.gradientMatrix).preConcatenate(matrix).toMATRIX();
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void saveImageTransform(boolean refreshTree) {
|
||||
Matrix matrix = imagePanel.getNewMatrix();
|
||||
|
||||
@@ -1512,14 +1556,88 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
}
|
||||
}
|
||||
sprite.resetTimeline();
|
||||
} else if (character instanceof ShapeTag) {
|
||||
ShapeTag shape = (ShapeTag) character;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
for (SHAPERECORD rec : shape.shapes.shapeRecords) {
|
||||
if (rec instanceof StyleChangeRecord) {
|
||||
StyleChangeRecord scr = (StyleChangeRecord) rec;
|
||||
if (scr.stateNewStyles) {
|
||||
transformStyles(matrix, scr.fillStyles, scr.lineStyles, shape.getShapeNum());
|
||||
}
|
||||
if (scr.stateMoveTo) {
|
||||
Point nextPoint = new Point(scr.moveDeltaX, scr.moveDeltaY);
|
||||
x = scr.changeX(x);
|
||||
y = scr.changeY(y);
|
||||
Point nextPoint2 = matrix.transform(nextPoint);
|
||||
scr.moveDeltaX = nextPoint2.x;
|
||||
scr.moveDeltaY = nextPoint2.y;
|
||||
}
|
||||
}
|
||||
if (rec instanceof StraightEdgeRecord) {
|
||||
StraightEdgeRecord ser = (StraightEdgeRecord) rec;
|
||||
ser.generalLineFlag = true;
|
||||
ser.vertLineFlag = false;
|
||||
Point currentPoint = new Point(x, y);
|
||||
Point nextPoint = new Point(x + ser.deltaX, y + ser.deltaY);
|
||||
x = ser.changeX(x);
|
||||
y = ser.changeY(y);
|
||||
Point currentPoint2 = matrix.transform(currentPoint);
|
||||
Point nextPoint2 = matrix.transform(nextPoint);
|
||||
ser.deltaX = nextPoint2.x - currentPoint2.x;
|
||||
ser.deltaY = nextPoint2.y - currentPoint2.y;
|
||||
ser.simplify();
|
||||
}
|
||||
if (rec instanceof CurvedEdgeRecord) {
|
||||
CurvedEdgeRecord cer = (CurvedEdgeRecord) rec;
|
||||
Point currentPoint = new Point(x, y);
|
||||
Point controlPoint = new Point(x + cer.controlDeltaX, y + cer.controlDeltaY);
|
||||
Point anchorPoint = new Point(x + cer.controlDeltaX + cer.anchorDeltaX, y + cer.controlDeltaY + cer.anchorDeltaY);
|
||||
x = cer.changeX(x);
|
||||
y = cer.changeY(y);
|
||||
|
||||
Point currentPoint2 = matrix.transform(currentPoint);
|
||||
Point controlPoint2 = matrix.transform(controlPoint);
|
||||
Point anchorPoint2 = matrix.transform(anchorPoint);
|
||||
|
||||
cer.controlDeltaX = controlPoint2.x - currentPoint2.x;
|
||||
cer.controlDeltaY = controlPoint2.y - currentPoint2.y;
|
||||
cer.anchorDeltaX = anchorPoint2.x - controlPoint2.x;
|
||||
cer.anchorDeltaY = anchorPoint2.y - controlPoint2.y;
|
||||
}
|
||||
}
|
||||
|
||||
transformStyles(matrix, shape.shapes.fillStyles, shape.shapes.lineStyles, shape.getShapeNum());
|
||||
|
||||
ExportRectangle shapeRect = matrix.transform(new ExportRectangle(shape.shapeBounds));
|
||||
shape.shapeBounds = new RECT(
|
||||
(int) Math.round(shapeRect.xMin),
|
||||
(int) Math.round(shapeRect.xMax),
|
||||
(int) Math.round(shapeRect.yMin),
|
||||
(int) Math.round(shapeRect.yMax)
|
||||
);
|
||||
if (shape instanceof DefineShape4Tag) {
|
||||
DefineShape4Tag shape4 = (DefineShape4Tag) shape;
|
||||
ExportRectangle edgeRect = matrix.transform(new ExportRectangle(shape4.edgeBounds));
|
||||
shape4.edgeBounds = new RECT(
|
||||
(int) Math.round(edgeRect.xMin),
|
||||
(int) Math.round(edgeRect.xMax),
|
||||
(int) Math.round(edgeRect.yMin),
|
||||
(int) Math.round(edgeRect.yMax)
|
||||
);
|
||||
}
|
||||
shape.getSwf().clearShapeCache();
|
||||
shape.setModified(true);
|
||||
}
|
||||
|
||||
mainPanel.clearEditingStatus();
|
||||
if (refreshTree) {
|
||||
mainPanel.refreshTree(item.getOpenable());
|
||||
mainPanel.reload(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private void saveImageTransformButtonActionPerformed(ActionEvent evt) {
|
||||
saveImageTransform(true);
|
||||
}
|
||||
@@ -1552,7 +1670,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
fSwf.displayRect = displayedCharacter.getSwf().getRect();//sprite.getRect();
|
||||
CharacterTag character = displayedCharacter;
|
||||
Set<Integer> needed = new LinkedHashSet<>();
|
||||
DefineSpriteTag sprite = null;
|
||||
CharacterTag placedCharacter = displayedCharacter;
|
||||
if (displayedCharacter instanceof ButtonTag) {
|
||||
ButtonTag buttonTag = (ButtonTag) displayedCharacter;
|
||||
List<BUTTONRECORD> records = buttonTag.getRecords();
|
||||
@@ -1563,10 +1681,9 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
}
|
||||
}
|
||||
} else {
|
||||
sprite = (DefineSpriteTag) character;
|
||||
sprite.getNeededCharactersDeep(needed);
|
||||
needed.remove(sprite.getCharacterId());
|
||||
needed.add(sprite.getCharacterId());
|
||||
displayedCharacter.getNeededCharactersDeep(needed);
|
||||
needed.remove(displayedCharacter.getCharacterId());
|
||||
needed.add(displayedCharacter.getCharacterId());
|
||||
}
|
||||
|
||||
for (int n : needed) {
|
||||
@@ -1583,7 +1700,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
}
|
||||
|
||||
if (displayedCharacter instanceof ButtonTag) {
|
||||
sprite = new DefineSpriteTag(fSwf);
|
||||
DefineSpriteTag sprite = new DefineSpriteTag(fSwf);
|
||||
sprite.frameCount = 1;
|
||||
ButtonTag buttonTag = (ButtonTag) displayedCharacter;
|
||||
List<BUTTONRECORD> records = buttonTag.getRecords();
|
||||
@@ -1600,13 +1717,15 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
showFrameTag.setTimelined(sprite);
|
||||
fSwf.addTag(sprite);
|
||||
sprite.setTimelined(fSwf);
|
||||
|
||||
placedCharacter = sprite;
|
||||
}
|
||||
|
||||
DefineSpriteTag sprite2 = new DefineSpriteTag(fSwf);
|
||||
sprite2.frameCount = 1;
|
||||
PlaceObject3Tag placeTag = new PlaceObject3Tag(fSwf);
|
||||
placeTag.depth = 1;
|
||||
placeTag.characterId = sprite.getCharacterId();
|
||||
placeTag.characterId = placedCharacter.getCharacterId();
|
||||
placeTag.placeFlagHasCharacter = true;
|
||||
|
||||
placeTag.matrix = new MATRIX();
|
||||
@@ -1666,7 +1785,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
|
||||
if (Configuration.editorMode.get()) {
|
||||
if (placeEditMode == PLACE_EDIT_RAW) {
|
||||
placeGenericPanel.setEditMode(true, null);
|
||||
placeGenericPanel.setEditMode(true, null);
|
||||
}
|
||||
placeEditButton.setVisible(false);
|
||||
placeSaveButton.setVisible(true);
|
||||
@@ -1716,7 +1835,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
saveImageTransform(false);
|
||||
ok = ok && !(imageTransformSaveButton.isVisible() && imageTransformSaveButton.isEnabled());
|
||||
}
|
||||
|
||||
|
||||
if (placeSaveButton.isVisible() && placeSaveButton.isEnabled() && Configuration.autoSaveTagModifications.get()) {
|
||||
savePlaceTag(false);
|
||||
ok = ok && !(placeSaveButton.isVisible() && placeSaveButton.isEnabled());
|
||||
@@ -1779,7 +1898,7 @@ public class PreviewPanel extends JPersistentSplitPane implements TagEditorPanel
|
||||
public void startEditTextTag() {
|
||||
textPanel.startEdit();
|
||||
}
|
||||
|
||||
|
||||
public void pauseImage() {
|
||||
imagePanel.pause();
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user