diff --git a/lib/FlashPlayer.exe b/lib/FlashPlayer.exe deleted file mode 100644 index 51430c392..000000000 Binary files a/lib/FlashPlayer.exe and /dev/null differ diff --git a/lib/JavactiveX.jar b/lib/JavactiveX.jar new file mode 100644 index 000000000..1b69ece16 Binary files /dev/null and b/lib/JavactiveX.jar differ diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FontExporter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FontExporter.java index 05a7839de..5c904214a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FontExporter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/exporters/FontExporter.java @@ -24,6 +24,7 @@ import com.jpexs.decompiler.flash.AbortRetryIgnoreHandler; import com.jpexs.decompiler.flash.ApplicationInfo; import com.jpexs.decompiler.flash.RetryTask; import com.jpexs.decompiler.flash.RunnableIOEx; +import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.exporters.modes.FontExportMode; import com.jpexs.decompiler.flash.exporters.settings.FontExportSettings; import com.jpexs.decompiler.flash.exporters.shape.PathExporter; @@ -108,9 +109,12 @@ public class FontExporter { return new byte[0]; } - public void exportFont(final FontTag t, FontExportMode mode, File file) throws IOException { + public void exportFont(FontTag ft, FontExportMode mode, File file) throws IOException { + final FontTag t = ft.toClassicFont(); List shapes = t.getGlyphShapeTable(); + final double divider = t.getDivider(); + File ttfFile = file; if (mode == FontExportMode.WOFF) { @@ -122,9 +126,10 @@ public class FontExporter { f.getEngine().setCopyrightYear(cop == null ? "" : cop); f.setAuthor(ApplicationInfo.shortApplicationVerName); - f.setVersion("1.0"); - f.setAscender(t.getAscent() / t.getDivider()); - f.setDescender(t.getDescent() / t.getDivider()); + f.setVersion("1.0"); + + f.setAscender(Math.round(t.getAscent() / divider)); + f.setDescender(Math.round(t.getDescent() / divider)); for (int i = 0; i < shapes.size(); i++) { SHAPE s = shapes.get(i); @@ -132,11 +137,11 @@ public class FontExporter { PathExporter seb = new PathExporter(s, new ColorTransform()) { private double transformX(double x) { - return Math.ceil((double) (x / t.getDivider())); + return Math.ceil((double) (x / divider)); } private double transformY(double y) { - return -Math.ceil((double) (y / t.getDivider())); + return -Math.ceil((double) (y / divider)); } List path = new ArrayList<>(); @@ -178,9 +183,9 @@ public class FontExporter { final FGlyph g = f.addGlyph(c); double adv = t.getGlyphAdvance(i); if (adv != -1) { - g.setAdvanceWidth((int) adv); + g.setAdvanceWidth((int) Math.round(adv / divider)); } else { - g.setAdvanceWidth(t.getGlyphWidth(i) / t.getDivider() + 100); + g.setAdvanceWidth((int)Math.round(t.getGlyphWidth(i) / divider + 100)); } for (FPoint[] cnt : contours) { if (cnt.length == 0) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java index 6e6c9ad88..8670d97d2 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java @@ -260,7 +260,7 @@ public class DefineEditTextTag extends TextTag { char firstChar = size.charAt(0); if (firstChar != '+' && firstChar != '-') { int fontSize = Integer.parseInt(size); - style.fontHeight = fontSize * (style.font == null ? 1 : style.font.getDivider()); + style.fontHeight = (int)Math.round(fontSize * (style.font == null ? 1 : style.font.getDivider())); style.fontLeading = leading; } else { // todo: parse relative sizes @@ -824,7 +824,7 @@ public class DefineEditTextTag extends TextTag { kerningAdjustment = font.getGlyphKerningAdjustment(ge.glyphIndex, font.charToGlyph(nextChar)); kerningAdjustment /= font.getDivider(); } - advance = (int) Math.round(font.getDivider() * Math.round((double) lastStyle.fontHeight * (font.getGlyphAdvance(ge.glyphIndex) + kerningAdjustment) / (font.getDivider() * 1024.0))); + advance = (int) Math.round(Math.round((double) lastStyle.fontHeight * (font.getGlyphAdvance(ge.glyphIndex) + kerningAdjustment) / (font.getDivider() * 1024.0))); } else { String fontName = FontTag.defaultFontName; int fontStyle = font == null ? 0 : font.getFontStyle(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java index 7cffc99f1..96f4f89fa 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont2Tag.java @@ -97,6 +97,14 @@ public class DefineFont2Tag extends FontTag { return glyphShapeTable.get(glyphIndex).getBounds().getWidth(); } + @Override + public RECT getGlyphBounds(int glyphIndex) { + return fontBoundsTable.get(glyphIndex); + } + + + + @Override public double getGlyphAdvance(int glyphIndex) { if (fontFlagsHasLayout) { @@ -340,7 +348,7 @@ public class DefineFont2Tag extends FontTag { } @Override - public int getDivider() { + public double getDivider() { return 1; } @@ -369,10 +377,10 @@ public class DefineFont2Tag extends FontTag { } @Override - public void addCharacter(char character, String fontName) { + public void addCharacter(char character, Font font) { int fontStyle = getFontStyle(); - SHAPE shp = SHAPERECORD.systemFontCharacterToSHAPE(fontName, fontStyle, getDivider() * 1024, character); + SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(font, fontStyle, (int)Math.round(getDivider() * 1024), character); int code = (int) character; int pos = -1; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java index 2dea51ad5..cfef8825e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFont3Tag.java @@ -95,7 +95,7 @@ public class DefineFont3Tag extends FontTag { @Override public double getGlyphAdvance(int glyphIndex) { if (fontFlagsHasLayout && glyphIndex != -1) { - return fontAdvanceTable.get(glyphIndex) / SWF.unitDivisor; + return fontAdvanceTable.get(glyphIndex); } else { return -1; } @@ -334,7 +334,7 @@ public class DefineFont3Tag extends FontTag { } @Override - public int getDivider() { + public double getDivider() { return 20; } @@ -363,7 +363,7 @@ public class DefineFont3Tag extends FontTag { } @Override - public void addCharacter(char character, String fontName) { + public void addCharacter(char character, Font font) { //Font Align Zones will be removed as adding new character zones is not supported:-( for (int i = 0; i < swf.tags.size(); i++) { @@ -377,7 +377,7 @@ public class DefineFont3Tag extends FontTag { } } int fontStyle = getFontStyle(); - SHAPE shp = SHAPERECORD.systemFontCharacterToSHAPE(fontName, fontStyle, getDivider() * 1024, character); + SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(font, fontStyle, (int)Math.round(getDivider() * 1024), character); int code = (int) character; int pos = -1; boolean exists = false; @@ -433,6 +433,13 @@ public class DefineFont3Tag extends FontTag { return fontFlagsHasLayout; } + @Override + public RECT getGlyphBounds(int glyphIndex) { + return fontBoundsTable.get(glyphIndex); + } + + + @Override public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) { if (glyphIndex == -1 || nextGlyphIndex == -1) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java index e02ce4db2..91d5d0497 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineFontTag.java @@ -20,11 +20,13 @@ import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.types.BasicType; +import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.decompiler.flash.types.annotations.Internal; import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD; import com.jpexs.helpers.ByteArrayRange; +import java.awt.Font; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.OutputStream; @@ -260,13 +262,13 @@ public class DefineFontTag extends FontTag { } @Override - public int getDivider() { + public double getDivider() { return 1; } @Override - public void addCharacter(char character, String fontName) { - SHAPE shp = SHAPERECORD.systemFontCharacterToSHAPE(fontName, getFontStyle(), getDivider() * 1024, character); + public void addCharacter(char character, Font font) { + SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(font, getFontStyle(), (int)Math.round(getDivider() * 1024), character); List codeTable = new ArrayList<>(); ensureFontInfo(); if (fontInfoTag != null) { @@ -322,4 +324,5 @@ public class DefineFontTag extends FontTag { public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) { return 0; } + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java index 928f74219..1ca1777f3 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineText2Tag.java @@ -389,7 +389,7 @@ public class DefineText2Tag extends TextTag { if (nextChar != null) { kerningAdjustment = font.getGlyphKerningAdjustment(tr.glyphEntries[i].glyphIndex, font.charToGlyph(nextChar)); } - advance = (int) Math.round(font.getDivider() * ((double) textHeight * font.getGlyphAdvance(tr.glyphEntries[i].glyphIndex) + kerningAdjustment) / (font.getDivider() * 1024.0)); + advance = (int) Math.round(((double) textHeight * (font.getGlyphAdvance(tr.glyphEntries[i].glyphIndex) + kerningAdjustment)) / (font.getDivider() * 1024.0)); } else { advance = (int) Math.round(SWF.unitDivisor * FontTag.getSystemFontAdvance(fontName, font.getFontStyle(), (int) (textHeight / SWF.unitDivisor), c, nextChar)); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java index 040bfd23d..78a092336 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineTextTag.java @@ -395,7 +395,7 @@ public class DefineTextTag extends TextTag { if (nextChar != null) { kerningAdjustment = font.getGlyphKerningAdjustment(tr.glyphEntries[i].glyphIndex, font.charToGlyph(nextChar)); } - advance = (int) Math.round(font.getDivider() * ((double) textHeight * font.getGlyphAdvance(tr.glyphEntries[i].glyphIndex) + kerningAdjustment) / (font.getDivider() * 1024.0)); + advance = (int) Math.round(((double) textHeight * (font.getGlyphAdvance(tr.glyphEntries[i].glyphIndex + kerningAdjustment))) / (font.getDivider() * 1024.0)); } else { advance = (int) Math.round(SWF.unitDivisor * FontTag.getSystemFontAdvance(fontName, font.getFontStyle(), (int) (textHeight / SWF.unitDivisor), c, nextChar)); } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java index c8ede7cf6..866557b4c 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/FontTag.java @@ -22,18 +22,29 @@ import com.jpexs.decompiler.flash.exporters.commonshape.Matrix; import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter; import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter; import com.jpexs.decompiler.flash.helpers.FontHelper; +import com.jpexs.decompiler.flash.tags.DefineFont2Tag; import com.jpexs.decompiler.flash.tags.DefineFontNameTag; import com.jpexs.decompiler.flash.tags.DefineText2Tag; import com.jpexs.decompiler.flash.tags.DefineTextTag; import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.gfx.DefineCompactedFont; import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.GLYPHENTRY; +import com.jpexs.decompiler.flash.types.KERNINGRECORD; +import com.jpexs.decompiler.flash.types.LANGCODE; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.SHAPE; import com.jpexs.decompiler.flash.types.TEXTRECORD; +import com.jpexs.decompiler.flash.types.gfx.FontType; +import com.jpexs.decompiler.flash.types.gfx.GlyphInfoType; +import com.jpexs.decompiler.flash.types.gfx.GlyphType; +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.ByteArrayRange; +import com.jpexs.helpers.Helper; import com.jpexs.helpers.SerializableImage; import java.awt.Color; import java.awt.Font; @@ -43,11 +54,15 @@ import java.awt.font.FontRenderContext; import java.awt.font.GlyphMetrics; import java.awt.font.GlyphVector; import java.awt.geom.Area; +import java.io.IOException; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashSet; import java.util.List; import java.util.Map; import java.util.Set; +import java.util.logging.Level; +import java.util.logging.Logger; /** * @@ -65,7 +80,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable public abstract List getGlyphShapeTable(); - public abstract void addCharacter(char character, String fontName); + public abstract void addCharacter(char character, Font font); public abstract char glyphToChar(int glyphIndex); @@ -97,7 +112,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable public abstract void setItalic(boolean value); - public abstract int getDivider(); + public abstract double getDivider(); public abstract int getAscent(); @@ -338,4 +353,16 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable sb.append("\t}\r\n"); return sb.toString(); } + + + + + + public RECT getGlyphBounds(int glyphIndex) { + return getGlyphShapeTable().get(glyphIndex).getBounds(); + } + + public FontTag toClassicFont() { + return this; + } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/MissingCharacterHandler.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/MissingCharacterHandler.java index b2cf935dc..c21fe14aa 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/MissingCharacterHandler.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/MissingCharacterHandler.java @@ -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 java.awt.Font; @@ -32,7 +33,7 @@ public class MissingCharacterHandler { if (!f.canDisplay(character)) { return false; } - font.addCharacter(character, fontName); + font.addCharacter(character, f); return true; } } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java index c335a7b20..ec65ac569 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/gfx/DefineCompactedFont.java @@ -144,10 +144,12 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { } @Override - public void addCharacter(char character, String fontName) { + public void addCharacter(char character, Font cfont) { int fontStyle = getFontStyle(); FontType font = fonts.get(0); - SHAPE shp = SHAPERECORD.systemFontCharacterToSHAPE(fontName, fontStyle, (int) (SWF.unitDivisor * font.nominalSize), character); + + double d = 1; //1024/font.nominalSize; + SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(cfont, fontStyle, (int) (SWF.unitDivisor * font.nominalSize * d), character); int code = (int) character; int pos = -1; @@ -169,7 +171,7 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { shiftGlyphIndices(fontId, pos); } - Font fnt = new Font(fontName, fontStyle, font.nominalSize); + Font fnt = cfont.deriveFont(fontStyle, Math.round(font.nominalSize * d)); int advance = (int) Math.round(fnt.createGlyphVector((new JPanel()).getFontMetrics(fnt).getFontRenderContext(), "" + character).getGlyphMetrics(0).getAdvanceX()); if (!exists) { font.glyphInfo.add(pos, new GlyphInfoType(code, advance, 0)); @@ -278,7 +280,7 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { } @Override - public int getDivider() { + public double getDivider() { return 1; } @@ -307,17 +309,13 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { return ret; } - private int resizemultiplier() { - FontType ft = fonts.get(0); - return (int) Math.round(1024.0 / ft.nominalSize); + @Override + public RECT getGlyphBounds(int glyphIndex) { + GlyphType gt = fonts.get(0).glyphs.get(glyphIndex); + return new RECT(resize(gt.boundingBox[0]), resize(gt.boundingBox[1]), resize(gt.boundingBox[2]), resize(gt.boundingBox[3])); } - private int resize(int val) { - int ret = val * resizemultiplier(); - return ret; - } - - private SHAPE resize(SHAPE shp) { + public SHAPE resizeShape(SHAPE shp) { SHAPE ret = new SHAPE(); ret.numFillBits = 1; ret.numLineBits = 0; @@ -350,36 +348,39 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { return ret; } + protected int resize(double val) { + FontType ft = fonts.get(0); + return (int) Math.round(val * 1024.0 / ft.nominalSize); + } + + @Override public FontTag toClassicFont() { try { DefineFont2Tag ret = new DefineFont2Tag(swf); - ret.fontId = fontId; + ret.fontId = getFontId(); ret.fontFlagsBold = isBold(); ret.fontFlagsItalic = isItalic(); ret.fontFlagsWideOffsets = true; ret.fontFlagsWideCodes = true; ret.fontFlagsHasLayout = true; - FontType ft = fonts.get(0); - ret.fontAscent = resize(ft.ascent); - ret.fontDescent = resize(ft.descent); - ret.fontLeading = resize(ft.leading); + ret.fontAscent = (getAscent()); + ret.fontDescent = (getDescent()); + ret.fontLeading = (getLeading()); ret.fontAdvanceTable = new ArrayList<>(); ret.fontBoundsTable = new ArrayList<>(); ret.codeTable = new ArrayList<>(); ret.glyphShapeTable = new ArrayList<>(); - ret.numGlyphs = ft.glyphInfo.size(); - SHAPE shpA = SHAPERECORD.systemFontCharacterToSHAPE("Times New Roman", 0, getDivider() * 1024, 'A'); - for (GlyphInfoType gi : ft.glyphInfo) { - ret.fontAdvanceTable.add(resize(gi.advanceX)); - ret.codeTable.add(gi.glyphCode); - } + List shp = getGlyphShapeTable(); + ret.numGlyphs = shp.size(); + for (int g = 0; g < shp.size(); g++) { + ret.fontAdvanceTable.add(resize(getGlyphAdvance(g))); + ret.codeTable.add((int) glyphToChar(g)); - for (GlyphType gt : ft.glyphs) { - SHAPE shpX = resize(gt.toSHAPE()); - ret.glyphShapeTable.add(shpX); // - ret.fontBoundsTable.add(new RECT(resize(gt.boundingBox[0]), resize(gt.boundingBox[1]), resize(gt.boundingBox[2]), resize(gt.boundingBox[3]))); + SHAPE shpX = resizeShape(shp.get(g)); + ret.glyphShapeTable.add(shpX); + ret.fontBoundsTable.add(getGlyphBounds(g)); } - ret.fontName = ft.fontName; + ret.fontName = getFontName(); ret.languageCode = new LANGCODE(1); ret.fontKerningTable = new KERNINGRECORD[0];/*new KERNINGRECORD[ft.kerning.size()]; for(int i=0;i 1024) { multiplier = fontSize / 1024; fontSize = 1024; } List retList = new ArrayList<>(); - Font f = new Font(FontTag.getFontNameWithFallback(fontName), fontStyle, fontSize); + Font f = font.deriveFont(fontStyle, fontSize); GlyphVector v = f.createGlyphVector((new JPanel()).getFontMetrics(f).getFontRenderContext(), "" + character); Shape shp = v.getOutline(); double[] points = new double[6]; diff --git a/nbproject/project.xml b/nbproject/project.xml index 211ec2d7a..ccf7640f3 100644 --- a/nbproject/project.xml +++ b/nbproject/project.xml @@ -187,7 +187,7 @@ src - lib/LZMA.jar;lib/jna-3.5.1.jar;lib/jpproxy.jar;lib/jsyntaxpane-0.9.5.jar;lib/trident-6.2.jar;lib/substance-flamingo-6.2.jar;lib/flamingo-6.2.jar;lib/substance-6.2.jar;lib/jl1.0.1.jar;lib/nellymoser.jar;lib/gif.jar;lib/avi.jar;lib/ttf.jar;lib/jpacker.jar;lib/sfntly.jar;lib/gnujpdf.jar;libsrc/ffdec_lib/src + lib/LZMA.jar;lib/jna-3.5.1.jar;lib/jpproxy.jar;lib/jsyntaxpane-0.9.5.jar;lib/trident-6.2.jar;lib/substance-flamingo-6.2.jar;lib/flamingo-6.2.jar;lib/substance-6.2.jar;lib/jl1.0.1.jar;lib/nellymoser.jar;lib/gif.jar;lib/avi.jar;lib/ttf.jar;lib/jpacker.jar;lib/sfntly.jar;lib/gnujpdf.jar;libsrc/ffdec_lib/src;lib/JavactiveX.jar build javadoc reports diff --git a/src/com/jpexs/decompiler/flash/gui/FontPanel.form b/src/com/jpexs/decompiler/flash/gui/FontPanel.form index 0d4dba3ef..8240f65b8 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontPanel.form +++ b/src/com/jpexs/decompiler/flash/gui/FontPanel.form @@ -41,7 +41,11 @@ - + + + + + @@ -91,7 +95,11 @@ - + + + + + @@ -583,6 +591,14 @@ + + + + + + + + diff --git a/src/com/jpexs/decompiler/flash/gui/FontPanel.java b/src/com/jpexs/decompiler/flash/gui/FontPanel.java index 5f772e548..2007e730f 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FontPanel.java @@ -23,13 +23,25 @@ import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.treeitems.TreeItem; +import com.jpexs.helpers.Helper; import java.awt.Font; +import java.awt.FontFormatException; +import java.awt.font.FontRenderContext; +import java.io.File; +import java.io.IOException; +import java.util.Arrays; +import java.util.HashSet; import java.util.Set; import java.util.TreeSet; +import java.util.logging.Level; +import java.util.logging.Logger; import javax.swing.ComboBoxModel; import javax.swing.DefaultComboBoxModel; +import javax.swing.JFileChooser; +import javax.swing.JFrame; import javax.swing.JLabel; import javax.swing.JOptionPane; +import javax.swing.filechooser.FileFilter; /** * @@ -86,14 +98,14 @@ public class FontPanel extends javax.swing.JPanel { return mainPanel.translate(key); } - private void fontAddChars(FontTag ft, Set selChars, String selFont) { + private void fontAddChars(FontTag ft, Set selChars, Font font) { FontTag f = (FontTag) mainPanel.tagTree.getCurrentTreeItem(); SWF swf = ft.getSwf(); String oldchars = f.getCharacters(swf.tags); for (int ic : selChars) { char c = (char) ic; if (oldchars.indexOf((int) c) == -1) { - Font font = new Font(selFont, f.getFontStyle(), 1024); + font = font.deriveFont(f.getFontStyle(), 1024); if (!font.canDisplay(c)) { View.showMessageDialog(null, translate("error.font.nocharacter").replace("%char%", "" + c), translate("error"), JOptionPane.ERROR_MESSAGE); return; @@ -129,7 +141,7 @@ public class FontPanel extends javax.swing.JPanel { continue; } } - f.addCharacter(c, fontSelection.getSelectedItem().toString()); + f.addCharacter(c, font); oldchars += c; } @@ -233,6 +245,7 @@ public class FontPanel extends javax.swing.JPanel { buttonSave = new javax.swing.JButton(); buttonCancel = new javax.swing.JButton(); buttonPreviewFont = new javax.swing.JButton(); + importTTFButton = new javax.swing.JButton(); addComponentListener(new java.awt.event.ComponentAdapter() { public void componentResized(java.awt.event.ComponentEvent evt) { @@ -494,11 +507,21 @@ public class FontPanel extends javax.swing.JPanel { } }); + importTTFButton.setText("Import TTF"); + importTTFButton.addActionListener(new java.awt.event.ActionListener() { + public void actionPerformed(java.awt.event.ActionEvent evt) { + importTTFButtonActionPerformed(evt); + } + }); + javax.swing.GroupLayout jPanel2Layout = new javax.swing.GroupLayout(jPanel2); jPanel2.setLayout(jPanel2Layout); jPanel2Layout.setHorizontalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 463, Short.MAX_VALUE) + .addGroup(jPanel2Layout.createSequentialGroup() + .addContainerGap() + .addComponent(importTTFButton) + .addContainerGap(387, Short.MAX_VALUE)) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() @@ -536,7 +559,10 @@ public class FontPanel extends javax.swing.JPanel { ); jPanel2Layout.setVerticalGroup( jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) - .addGap(0, 415, Short.MAX_VALUE) + .addGroup(javax.swing.GroupLayout.Alignment.TRAILING, jPanel2Layout.createSequentialGroup() + .addContainerGap(341, Short.MAX_VALUE) + .addComponent(importTTFButton) + .addGap(85, 85, 85)) .addGroup(jPanel2Layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING) .addGroup(jPanel2Layout.createSequentialGroup() .addContainerGap() @@ -588,25 +614,26 @@ public class FontPanel extends javax.swing.JPanel { for (int c = 0; c < newchars.length(); c++) { selChars.add(newchars.codePointAt(c)); } - fontAddChars((FontTag) item, selChars, fontSelection.getSelectedItem().toString()); + fontAddChars((FontTag) item, selChars, new Font(fontSelection.getSelectedItem().toString(),Font.PLAIN,12)); fontAddCharactersField.setText(""); mainPanel.reload(true); } }//GEN-LAST:event_fontAddCharsButtonActionPerformed - + + private void fontEmbedButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_fontEmbedButtonActionPerformed TreeItem item = mainPanel.tagTree.getCurrentTreeItem(); if (item instanceof FontTag) { - FontTag fontTag = (FontTag) item; - FontEmbedDialog fed = new FontEmbedDialog(fontSelection.getSelectedItem().toString(), fontAddCharactersField.getText(), fontTag.getFontStyle()); - if (fed.display()) { + FontTag ft = (FontTag) item; + FontEmbedDialog fed = new FontEmbedDialog(fontSelection.getSelectedItem().toString(), fontAddCharactersField.getText(), ft.getFontStyle()); + if (fed.display()) { Set selChars = fed.getSelectedChars(); if (!selChars.isEmpty()) { - String selFont = fed.getSelectedFont(); - fontSelection.setSelectedItem(selFont); - fontAddChars(fontTag, selChars, selFont); - fontAddCharactersField.setText(""); - mainPanel.reload(true); + String selFont = fed.getSelectedFont(); + fontSelection.setSelectedItem(selFont); + fontAddChars(ft, selChars, new Font(selFont,Font.PLAIN,10)); + fontAddCharactersField.setText(""); + mainPanel.reload(true); } } } @@ -651,6 +678,59 @@ public class FontPanel extends javax.swing.JPanel { jPanel1.updateUI(); }//GEN-LAST:event_formComponentResized + private void importTTFButtonActionPerformed(java.awt.event.ActionEvent evt) {//GEN-FIRST:event_importTTFButtonActionPerformed + TreeItem item = mainPanel.tagTree.getCurrentTreeItem(); + if (item instanceof FontTag) { + FontTag ft = (FontTag) item; + + + JFileChooser fc = new JFileChooser(); + fc.setCurrentDirectory(new File(Configuration.lastOpenDir.get())); + FileFilter ttfFilter = new FileFilter() { + @Override + public boolean accept(File f) { + return (f.getName().toLowerCase().endsWith(".ttf")) || (f.isDirectory()); + } + + @Override + public String getDescription() { + return "TTF files"; + } + }; + fc.setFileFilter(ttfFilter); + + fc.setAcceptAllFileFilterUsed(false); + JFrame fr = new JFrame(); + View.setWindowIcon(fr); + int returnVal = fc.showOpenDialog(fr); + if (returnVal == JFileChooser.APPROVE_OPTION) { + Configuration.lastOpenDir.set(Helper.fixDialogFile(fc.getSelectedFile()).getParentFile().getAbsolutePath()); + File selfile = Helper.fixDialogFile(fc.getSelectedFile()); + Set selChars = new HashSet<>(); + try { + Font f = Font.createFont(Font.TRUETYPE_FONT, selfile); + int required[] = new int[]{0x0001, 0x0000, 0x000D, 0x0020}; + loopi:for(char i=0;i 0) { - res = new byte[4]; - readFromPipe(res); - ret.x = ((res[0] & 0xff) << 8) + (res[1] & 0xff); - ret.y = ((res[2] & 0xff) << 8) + (res[3] & 0xff); - } - return button; - } - return 0; - } - private double zoom = 1.0; @Override public synchronized void zoom(double zoom) { - if (pipe != null) { - try { - long zoomint = Math.round(100 / (zoom / this.zoom)); - if (zoom == 1.0) { - zoomint = 0; - } - this.zoom = zoom; - writeToPipe(new byte[]{CMD_ZOOM}); - writeToPipe(new byte[]{(byte) ((zoomint >> 8) & 0xff), (byte) (zoomint & 0xff)}); - } catch (IOException ex) { - //ignore - } + int zoomint = (int) Math.round(100 / (zoom / this.zoom)); + if (zoom == 1.0) { + zoomint = 0; } + flash.Zoom(zoomint); + } public synchronized String getVariable(String name) throws IOException { - if (pipe != null) { - writeToPipe(new byte[]{CMD_GETVARIABLE}); - int nameLen = name.getBytes().length; - writeToPipe(new byte[]{(byte) ((nameLen >> 8) & 0xff), (byte) (nameLen & 0xff)}); - writeToPipe(name.getBytes()); - byte res[] = new byte[2]; - readFromPipe(res); - int retLen = ((res[0] & 0xff) << 8) + (res[1] & 0xff); - res = new byte[retLen]; - readFromPipe(res); - String ret = new String(res, 0, retLen); - return ret; - } - return null; + return flash.GetVariable(name); } public synchronized void setVariable(String name, String value) throws IOException { - if (pipe != null) { - writeToPipe(new byte[]{CMD_SETVARIABLE}); - int nameLen = name.getBytes().length; - writeToPipe(new byte[]{(byte) ((nameLen >> 8) & 0xff), (byte) (nameLen & 0xff)}); - writeToPipe(name.getBytes()); - - int valLen = value.getBytes().length; - writeToPipe(new byte[]{(byte) ((valLen >> 8) & 0xff), (byte) (valLen & 0xff)}); - writeToPipe(value.getBytes()); - } + flash.SetVariable(name, value); } public synchronized String call(String callString) throws IOException { - if (pipe != null) { - writeToPipe(new byte[]{CMD_CALL}); - int callLen = callString.getBytes().length; - writeToPipe(new byte[]{(byte) ((callLen >> 8) & 0xff), (byte) (callLen & 0xff)}); - writeToPipe(callString.getBytes()); - byte res[] = new byte[2]; - readFromPipe(res); - int retLen = ((res[0] & 0xff) << 8) + (res[1] & 0xff); - res = new byte[retLen]; - readFromPipe(res); - String ret = new String(res, 0, retLen); - return ret; - } - return null; - } - - private synchronized void resize() throws IOException { - if (pipe != null) { - writeToPipe(new byte[]{CMD_RESIZE}); - writeToPipe(new byte[]{ - (byte) (getWidth() / 256), (byte) (getWidth() % 256), - (byte) (getHeight() / 256), (byte) (getHeight() % 256),}); - } - } - - private int __getCurrentFrame() throws IOException { - byte[] res = new byte[2]; - writeToPipe(new byte[]{CMD_CURRENT_FRAME}); - readFromPipe(res); - return ((res[0] & 0xff) << 8) + (res[1] & 0xff); + return flash.CallFunction(callString); } @Override public synchronized int getCurrentFrame() { - try { - if (specialPlayback) { - if (!specialPlaying) { - return specialPosition; - } - String posStr = getVariable("_root.my_sound.position"); - if (posStr != null) { - return Integer.parseInt(posStr); - } - } - return __getCurrentFrame(); - } catch (IOException ex) { - return 0; - } + return flash.getFrameNum(); } @Override public synchronized int getTotalFrames() { - try { - if (specialPlayback) { - String durStr = getVariable("_root.my_sound.duration"); - if (durStr != null) { - return Integer.parseInt(durStr); - } - } - byte[] res = new byte[2]; - writeToPipe(new byte[]{CMD_TOTAL_FRAMES}); - readFromPipe(res); - return ((res[0] & 0xff) << 8) + (res[1] & 0xff); - } catch (IOException ex) { - return 0; - } + return flash.getTotalFrames(); } @Override public synchronized void setBackground(Color color) { - try { - writeToPipe(new byte[]{CMD_BGCOLOR}); - writeToPipe(new byte[]{(byte) color.getRed(), (byte) color.getGreen(), (byte) color.getBlue()}); - } catch (IOException ex) { - } - - } - - public void setRightClickMenu(JPopupMenu menu) { - rightClickMenu = menu; + flash.setBackgroundColor((color.getRed() << 16) + (color.getGreen() << 8) + color.getBlue()); } public FlashPlayerPanel(Component frame) { if (!Platform.isWindows()) { throw new FlashUnsupportedException(); } - this.frame = frame; - //this.add(rightClickMenu); - addComponentListener(new ComponentListener() { - @Override - public void componentResized(ComponentEvent e) { - try { - resize(); - } catch (IOException ex) { - } - } - - @Override - public void componentMoved(ComponentEvent e) { - } - - @Override - public void componentShown(ComponentEvent e) { - componentResized(e); - } - - @Override - public void componentHidden(ComponentEvent e) { - } - }); - } - - private synchronized void execute() { - if (!executed) { - hwnd = new WinDef.HWND(); - hwnd.setPointer(Native.getComponentPointer(this)); - - hwndFrame = new WinDef.HWND(); - hwndFrame.setPointer(Native.getComponentPointer(frame)); - - startFlashPlayer(); - - executed = true; - } - } - - private void restartFlashPlayer() { - Kernel32.INSTANCE.TerminateProcess(process, 0); - Kernel32.INSTANCE.CloseHandle(pipe); - startFlashPlayer(); - } - - private void startFlashPlayer() { - String path = Utf8Helper.urlDecode(FlashPlayerPanel.class.getProtectionDomain().getCodeSource().getLocation().getPath()); - String appDir = new File(path).getParentFile().getAbsolutePath(); - if (!appDir.endsWith("\\")) { - appDir += "\\"; - } - String exePath = appDir + "lib\\FlashPlayer.exe"; - File f = new File(exePath); - if (!f.exists()) { - Logger.getLogger(FlashPlayerPanel.class.getName()).log(Level.SEVERE, "FlashPlayer.exe not found: " + f.getPath()); - return; - } - - String pipeName = "\\\\.\\pipe\\ffdec_flashplayer_" + hwnd.getPointer().hashCode(); - pipe = Kernel32.INSTANCE.CreateNamedPipe(pipeName, Kernel32.PIPE_ACCESS_DUPLEX, Kernel32.PIPE_TYPE_BYTE, 1, 4096, 4096, 0, null); - - SHELLEXECUTEINFO sei = new SHELLEXECUTEINFO(); - sei.fMask = 0x00000040; - sei.lpFile = new WString(exePath); - sei.lpParameters = new WString(hwnd.getPointer().hashCode() + " " + hwndFrame.getPointer().hashCode()); - sei.nShow = WinUser.SW_NORMAL; - Shell32.INSTANCE.ShellExecuteEx(sei); - process = sei.hProcess; - - Kernel32.INSTANCE.ConnectNamedPipe(pipe, null); + flash = ActiveX.createObject(ShockwaveFlash.class, this); } public synchronized void stopSWF() { - if (rightClickTimer != null) { - rightClickTimer.cancel(); - rightClickTimer = null; - } displaySWF("-", null, 1); stopped = true; } @@ -363,183 +128,51 @@ public class FlashPlayerPanel extends Panel implements Closeable, MediaDisplay { } } - public synchronized void displaySWF(String flash, Color bgColor, int frameRate) { - try { - zoom = 1.0; - this.flash = flash; - repaint(); - this.frameRate = frameRate; - execute(); - if (bgColor != null) { - setBackground(bgColor); - } - resize(); - if (pipe != null) { - writeToPipe(new byte[]{CMD_PLAY}); - writeToPipe(new byte[]{(byte) flash.getBytes().length}); - writeToPipe(flash.getBytes()); - } - stopped = false; - specialPlaying = false; - specialPosition = 0; - if (specialPlayback) { - play(); - } - if (rightClickTimer != null) { - rightClickTimer.cancel(); - } - rightClickTimer = new Timer(); - rightClickTimer.schedule(new TimerTask() { + public synchronized void displaySWF(String flashName, Color bgColor, int frameRate) { - @Override - public void run() { - try { - final Point pt = new Point(); - final int button = checkClick(pt); - View.execInEventDispatch(new Runnable() { - - @Override - public void run() { - if (rightClickMenu != null) { - if (button == 2) { - ShadowPopupFactory.uninstall(); - rightClickMenu.show(FlashPlayerPanel.this, pt.x, pt.y); - ShadowPopupFactory.install(); - } - if (button == 1) { - rightClickMenu.setVisible(false); - } - } - } - }); - } catch (IOException ex) { - //ignore - } - } - }, 100, 100); - } catch (IOException ex) { + zoom = 1.0; + //this.frameRate = frameRate; + if (bgColor != null) { + setBackground(bgColor); } + flash.setMovie(flashName); + //play + stopped = false; + } @Override public void close() throws IOException { - if (rightClickTimer != null) { - rightClickTimer.cancel(); - rightClickTimer = null; - } - Kernel32.INSTANCE.CloseHandle(pipe); - Kernel32.INSTANCE.TerminateProcess(process, 0); - } - @Override - public void paint(Graphics g) { - if (flash != null) { - execute(); - } - super.paint(g); - } - private int specialPosition = 0; - - private synchronized void __pause() throws IOException { - writeToPipe(new byte[]{CMD_PAUSE}); } @Override public void pause() { - try { - if (specialPlayback) { - specialPosition = getCurrentFrame(); - __gotoFrame(3); - __play(); - specialPlaying = false; - return; - } - __pause(); - } catch (IOException ex) { - } + flash.Stop(); } @Override public void rewind() { - try { - if (specialPlayback) { - boolean plays = specialPlaying; - pause(); - specialPosition = 0; - if (plays) { - play(); - } - - return; - } - writeToPipe(new byte[]{CMD_REWIND}); - } catch (IOException ex) { - } - } - - private synchronized void __play() throws IOException { - writeToPipe(new byte[]{CMD_RESUME}); + flash.Rewind(); } @Override public void play() { - try { - if (specialPlayback) { - double p = (((double) specialPosition) / 1000.0); - setVariable("_root.execParam", "" + p); - __gotoFrame(1); - __play(); - specialPlaying = true; - return; - } - __play(); - } catch (IOException ex) { - } + flash.Play(); } @Override public boolean isPlaying() { - try { - if (specialPlayback) { - return specialPlaying; - } - writeToPipe(new byte[]{CMD_PLAYING}); - byte[] res = new byte[1]; - readFromPipe(res); - return res[0] == 1; - } catch (IOException ex) { - return false; - } - } - - private synchronized void __gotoFrame(int frame) throws IOException { - writeToPipe(new byte[]{CMD_GOTO}); - writeToPipe(new byte[]{(byte) ((frame >> 8) & 0xff), (byte) (frame & 0xff)}); + return flash.IsPlaying(); } @Override public void gotoFrame(int frame) { - try { - if (specialPlayback) { - if (specialPlaying) { - pause(); - specialPosition = frame; - play(); - } else { - specialPosition = frame; - } - return; - } - __gotoFrame(frame); - } catch (IOException ex) { - } + flash.GotoFrame(frame); } @Override public int getFrameRate() { - if (specialPlayback) { - return 1000; - } return frameRate; } @@ -548,69 +181,4 @@ public class FlashPlayerPanel extends Panel implements Closeable, MediaDisplay { return !isStopped(); } - private synchronized boolean writeToPipe(final byte[] data) throws IOException { - final IntByReference ibr = new IntByReference(); - int result = -1; - try { - result = CancellableWorker.call(new Callable() { - @Override - public Integer call() throws Exception { - boolean result = Kernel32.INSTANCE.WriteFile(pipe, data, data.length, ibr, null); - if (!result) { - return Kernel32.INSTANCE.GetLastError(); - } - if (ibr.getValue() != data.length) { - return -1; - } - return 0; - } - }, PIPE_TIMEOUT_MS, TimeUnit.MILLISECONDS); - } catch (InterruptedException | ExecutionException | TimeoutException ex) { - // ignore - } - if (result != 0) { - if (result == Kernel32.ERROR_NO_DATA || result == -1) { - restartFlashPlayer(); - throw new IOException("Pipe write error."); - } else { - // System.out.println("pipe write failed. datalength: " + data.length + " error:" + result); - } - } - return result == 0; - } - - private synchronized boolean readFromPipe(final byte[] res) throws IOException { - final IntByReference ibr = new IntByReference(); - int result = -1; - try { - result = CancellableWorker.call(new Callable() { - @Override - public Integer call() throws Exception { - int read = 0; - while (read < res.length) { - byte[] data = new byte[res.length - read]; - boolean result = Kernel32.INSTANCE.ReadFile(pipe, data, data.length, ibr, null); - if (!result) { - return Kernel32.INSTANCE.GetLastError(); - } - int readNow = ibr.getValue(); - System.arraycopy(data, 0, res, read, readNow); - read += readNow; - } - return 0; - } - }, PIPE_TIMEOUT_MS, TimeUnit.MILLISECONDS); - } catch (InterruptedException | ExecutionException | TimeoutException ex) { - // ignore - } - if (result != 0) { - if (result == Kernel32.ERROR_BROKEN_PIPE || result == -1) { - restartFlashPlayer(); - throw new IOException("Pipe read error."); - } else { - // System.out.println("pipe read failed. result: " + result + " datalength: " + res.length + " received: " + ibr.getValue() + " error: " + result); - } - } - return result == 0; - } }