Fixed: Flash viewer - strokes scaling, cropped strokes

This commit is contained in:
Jindra Petřík
2021-03-24 20:36:42 +01:00
parent a1c7b26b9d
commit f073a6615e
25 changed files with 360 additions and 37 deletions
@@ -2903,7 +2903,7 @@ public final class SWF implements SWFContainerItem, Timelined {
RenderContext renderContext = new RenderContext();
renderContext.cursorPosition = cursorPosition;
renderContext.mouseButton = mouseButton;
timeline.toImage(frame, time, renderContext, image, false, m, transformation, m, colorTransform);
timeline.toImage(frame, time, renderContext, image, false, m, new Matrix(), m, colorTransform);
return image;
}
@@ -3830,4 +3830,9 @@ public final class SWF implements SWFContainerItem, Timelined {
removeTag(index);
addTag(index, newTag);
}
@Override
public RECT getRectWithStrokes() {
return getRect();
}
}
@@ -391,6 +391,9 @@ public class BitmapExporter extends ShapeExporterBase {
case "NORMAL":
thickness *= Math.max(strokeTransformation.scaleX, strokeTransformation.scaleY);
break;
case "NONE":
thickness /= SWF.unitDivisor;
break;
}
if (thickness < 0) {
@@ -405,8 +408,7 @@ public class BitmapExporter extends ShapeExporterBase {
// Do not scale strokes automatically:
try {
AffineTransform t = (AffineTransform) graphics.getTransform().clone();
t.translate(-0.5, -0.5);
AffineTransform t = (AffineTransform) strokeTransformation.toTransform().clone();//(AffineTransform) graphics.getTransform().clone();
lineStroke = new TransformedStroke(lineStroke, t);
} catch (NoninvertibleTransformException net) {
// ignore
@@ -904,6 +904,11 @@ public class DefineEditTextTag extends TextTag {
return bounds;
}
@Override
public RECT getRectWithStrokes() {
return getRect();
}
@Override
public int getCharacterId() {
return characterID;
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.ReadOnlyTagList;
@@ -429,4 +430,9 @@ public class DefineSpriteTag extends DrawableTag implements Timelined {
removeTag(index);
addTag(index, newTag);
}
@Override
public RECT getRectWithStrokes() {
return getRect(); //?
}
}
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
@@ -79,4 +80,9 @@ public class DefineText2Tag extends StaticTextTag {
public int getTextNum() {
return 2;
}
@Override
public RECT getRectWithStrokes() {
return getRect();
}
}
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
@@ -79,4 +80,9 @@ public class DefineTextTag extends StaticTextTag {
public int getTextNum() {
return 1;
}
@Override
public RECT getRectWithStrokes() {
return getRect();
}
}
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
@@ -143,4 +144,9 @@ public class DefineVideoStreamTag extends CharacterTag implements BoundedTag {
public RECT getRect(Set<BoundedTag> added) {
return new RECT(0, (int) (SWF.unitDivisor * width), 0, (int) (SWF.unitDivisor * height));
}
@Override
public RECT getRectWithStrokes() {
return getRect();
}
}
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.types.RECT;
@@ -26,5 +27,7 @@ public interface BoundedTag {
public RECT getRect();
public RECT getRectWithStrokes();
public RECT getRect(Set<BoundedTag> added);
}
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.␍ */
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.ReadOnlyTagList;
@@ -80,6 +81,11 @@ public abstract class ButtonTag extends DrawableTag implements Timelined {
return getRect(new HashSet<>());
}
@Override
public RECT getRectWithStrokes() {
return getRect();
}
@Override
public int getUsedParameters() {
return PARAMETER_FRAME | PARAMETER_TIME | PARAMETER_RATIO; // inner tags can contain morphshapes, too
@@ -462,6 +462,11 @@ public abstract class FontTag extends DrawableTag implements AloneTag {
return getRect(null); // parameter not used
}
@Override
public RECT getRectWithStrokes() {
return getRect();
}
@Override
public RECT getRect(Set<BoundedTag> added) {
return new RECT(0, (int) (PREVIEWSIZE * SWF.unitDivisor), 0, (int) (PREVIEWSIZE * SWF.unitDivisor));
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. */
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.SWF;
@@ -277,4 +278,9 @@ public abstract class ImageTag extends DrawableTag {
public void setCharacterId(int characterId) {
this.characterID = characterId;
}
@Override
public RECT getRectWithStrokes() {
return getRect();
}
}
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. */
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.SWF;
@@ -27,6 +28,8 @@ import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.FILLSTYLEARRAY;
import com.jpexs.decompiler.flash.types.LINESTYLEARRAY;
import com.jpexs.decompiler.flash.types.MORPHFILLSTYLEARRAY;
import com.jpexs.decompiler.flash.types.MORPHLINESTYLE;
import com.jpexs.decompiler.flash.types.MORPHLINESTYLE2;
import com.jpexs.decompiler.flash.types.MORPHLINESTYLEARRAY;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPE;
@@ -79,6 +82,38 @@ public abstract class MorphShapeTag extends DrawableTag {
return getRect(new HashSet<>());
}
@Override
public RECT getRectWithStrokes() {
int shapeNum = getShapeNum();
int maxWidth = 0;
if (shapeNum == 1) {
for (MORPHLINESTYLE ls : morphLineStyles.lineStyles) {
if (ls.startWidth > maxWidth) {
maxWidth = ls.startWidth;
}
if (ls.endWidth > maxWidth) {
maxWidth = ls.endWidth;
}
}
}
if (shapeNum == 2) {
for (MORPHLINESTYLE2 ls : morphLineStyles.lineStyles2) {
if (ls.startWidth > maxWidth) {
maxWidth = ls.startWidth;
}
if (ls.endWidth > maxWidth) {
maxWidth = ls.endWidth;
}
}
}
RECT r = getRect();
r.Xmin -= maxWidth;
r.Ymin -= maxWidth;
r.Xmax += maxWidth;
r.Ymax += maxWidth;
return r;
}
@Override
public void getNeededCharacters(Set<Integer> needed) {
morphFillStyles.getNeededCharacters(needed);
@@ -12,7 +12,8 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. */
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.SWF;
@@ -27,9 +28,12 @@ import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter;
import com.jpexs.decompiler.flash.helpers.LazyObject;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.LINESTYLE;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.SHAPEWITHSTYLE;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
import com.jpexs.helpers.ByteArrayRange;
import com.jpexs.helpers.SerializableImage;
import java.awt.Color;
@@ -123,6 +127,39 @@ public abstract class ShapeTag extends DrawableTag implements LazyObject {
return getRect(null); // parameter not used
}
@Override
public RECT getRectWithStrokes() {
int maxWidth = 0;
for (LINESTYLE ls : getShapes().lineStyles.lineStyles) {
if (ls.width > maxWidth) {
maxWidth = ls.width;
}
}
for (SHAPERECORD sr : getShapes().shapeRecords) {
if (sr instanceof StyleChangeRecord) {
StyleChangeRecord scr = (StyleChangeRecord) sr;
if (scr.stateNewStyles) {
for (LINESTYLE ls : scr.lineStyles.lineStyles) {
if (ls.width > maxWidth) {
maxWidth = ls.width;
}
}
}
}
}
RECT r = getRect();
r.Xmin -= maxWidth;
r.Ymin -= maxWidth;
r.Xmax += maxWidth;
r.Ymax += maxWidth;
return r;
}
@Override
public int getUsedParameters() {
return 0;
@@ -529,4 +529,9 @@ public final class DefineCompactedFont extends FontTag {
public boolean isLeadingEditable() {
return true;
}
@Override
public RECT getRectWithStrokes() {
return getRect();
}
}
@@ -612,12 +612,14 @@ public class Timeline {
drawableFrameCount = 1;
}
RECT boundRect = drawable.getRect();
RECT boundRect = drawable.getRectWithStrokes();
ExportRectangle rect = new ExportRectangle(boundRect);
Matrix mat = transformation.concatenate(layerMatrix);
rect = mat.transform(rect);
strokeTransform = strokeTransform.concatenate(layerMatrix);
boolean cacheAsBitmap = layer.cacheAsBitmap() && layer.placeObjectTag != null && drawable.isSingleFrame();
/* // draw bounds
AffineTransform trans = mat.preConcatenate(Matrix.getScaleInstance(1 / SWF.unitDivisor)).toTransform();
@@ -682,6 +684,8 @@ public class Timeline {
}
Matrix m = mat.preConcatenate(Matrix.getTranslateInstance(-rect.xMin, -rect.yMin));
//strokeTransform = strokeTransform.preConcatenate(Matrix.getTranslateInstance(-rect.xMin, -rect.yMin));
//strokeTransform = strokeTransform.clone();
//strokeTransform.translate(-rect.xMin, -rect.yMin);