From 9c2372a2e3bd6157ad645ac42603076a4b0499b1 Mon Sep 17 00:00:00 2001 From: Honfika Date: Sun, 23 Feb 2014 18:13:51 +0100 Subject: [PATCH] render DefineEditText tag (only basic texts, formatting is not supported yet) --- trunk/src/com/jpexs/decompiler/flash/SWF.java | 20 ++-- .../flash/tags/DefineEditTextTag.java | 94 ++++++++++++++++++- .../flash/tags/base/BoundedTag.java | 1 - 3 files changed, 96 insertions(+), 19 deletions(-) diff --git a/trunk/src/com/jpexs/decompiler/flash/SWF.java b/trunk/src/com/jpexs/decompiler/flash/SWF.java index d601615ee..249ceb6fd 100644 --- a/trunk/src/com/jpexs/decompiler/flash/SWF.java +++ b/trunk/src/com/jpexs/decompiler/flash/SWF.java @@ -2316,6 +2316,7 @@ public final class SWF implements TreeItem { Matrix mat = new Matrix(layer.matrix); mat = mat.preConcatenate(transformation); + boolean showPlaceholder = false; if (character instanceof DrawableTag) { DrawableTag drawable = (DrawableTag) character; SerializableImage img; @@ -2332,12 +2333,9 @@ public final class SWF implements TreeItem { drawMatrix.translate(rect.xMin, rect.yMin); drawable.toImage(layer.ratio < 0 ? 0 : layer.ratio/*layer.duration*/, allTags, characters, visited, img, m); } else { + // only DefineFont tags img = drawable.toImage(layer.ratio < 0 ? 0 : layer.ratio/*layer.duration*/, allTags, characters, visited, transformation); } - /*if (character instanceof BoundedTag) { - BoundedTag bounded = (BoundedTag) character; - RECT rect = bounded.getRect(characters, visited); - }*/ if (layer.filters != null) { for (FILTER filter : layer.filters) { img = filter.apply(img); @@ -2404,6 +2402,10 @@ public final class SWF implements TreeItem { g.setTransform(drawMatrix.toTransform()); g.drawImage(img.getBufferedImage(), 0, 0, null); } else if (character instanceof BoundedTag) { + showPlaceholder = true; + } + + if (showPlaceholder) { mat.translateX /= unzoom; mat.translateY /= unzoom; AffineTransform trans = mat.toTransform(); @@ -2418,17 +2420,9 @@ public final class SWF implements TreeItem { g.drawLine(r.Xmin / div, r.Ymin / div, r.Xmax / div, r.Ymax / div); g.drawLine(r.Xmax / div, r.Ymin / div, r.Xmin / div, r.Ymax / div); g.setComposite(AlphaComposite.Dst); - } + } } g.setTransform(AffineTransform.getScaleInstance(1, 1)); - /*g.setPaint(Color.yellow); - g.draw(new ExportRectangle(ret.getWidth()-1,ret.getHeight()-1));*/ - - /*try { - ImageIO.write(ret, "png", new File("tst_id_" + containerId + "_time_" + System.currentTimeMillis() + ".png")); - } catch (IOException ex) { - Logger.getLogger(SWF.class.getName()).log(Level.SEVERE, null, ex); - }*/ } public static void frameToImage(int containerId, int frame, List allTags, List controlTags, RECT displayRect, int totalFrameCount, Stack visited, SerializableImage image, Matrix transformation) { diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java index f38d425d6..48aed6bbc 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java @@ -19,19 +19,25 @@ package com.jpexs.decompiler.flash.tags; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.SWFInputStream; import com.jpexs.decompiler.flash.SWFOutputStream; +import com.jpexs.decompiler.flash.exporters.Matrix; +import com.jpexs.decompiler.flash.exporters.Point; import com.jpexs.decompiler.flash.tags.base.CharacterTag; +import com.jpexs.decompiler.flash.tags.base.DrawableTag; +import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.tags.text.ParseException; import com.jpexs.decompiler.flash.tags.text.ParsedSymbol; import com.jpexs.decompiler.flash.tags.text.TextLexer; import com.jpexs.decompiler.flash.types.BasicType; +import com.jpexs.decompiler.flash.types.GLYPHENTRY; import com.jpexs.decompiler.flash.types.MATRIX; import com.jpexs.decompiler.flash.types.RECT; import com.jpexs.decompiler.flash.types.RGBA; +import com.jpexs.decompiler.flash.types.TEXTRECORD; import com.jpexs.decompiler.flash.types.annotations.Conditional; import com.jpexs.decompiler.flash.types.annotations.SWFType; -import java.awt.geom.GeneralPath; +import com.jpexs.helpers.SerializableImage; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; @@ -53,7 +59,7 @@ import java.util.regex.Pattern; * * @author JPEXS */ -public class DefineEditTextTag extends TextTag { +public class DefineEditTextTag extends TextTag implements DrawableTag { @SWFType(BasicType.UI16) public int characterID; @@ -609,8 +615,86 @@ public class DefineEditTextTag extends TextTag { return needed; } - //@Override - public List getPaths(List tags) { - return null; //FIXME + @Override + public SerializableImage toImage(int frame, List tags, Map characters, Stack visited, Matrix transformation) { + throw new Error("this overload of toImage call is not supported on BoundedTag"); + } + + @Override + public void toImage(int frame, List tags, Map characters, Stack visited, SerializableImage image, Matrix transformation) { + FontTag font = null; + for (Tag tag : tags) { + if (tag instanceof FontTag) { + if (((FontTag) tag).getFontId() == fontId) { + font = (FontTag) tag; + } + } + } + if (hasText) { + List textRecords = new ArrayList<>(); + TEXTRECORD tr = new TEXTRECORD(); + tr.styleFlagsHasFont = true; + tr.fontId = fontId; + tr.textHeight = fontHeight; + tr.styleFlagsHasYOffset = true; + tr.yOffset = fontHeight; + String txt; + if (html) { + txt = getInnerText(initialText); + } else { + txt = initialText; + } + tr.glyphEntries = new GLYPHENTRY[txt.length()]; + for (int i = 0; i < txt.length(); i++) { + char c = txt.charAt(i); + Character nextChar = null; + if (i + 1 < txt.length()) { + nextChar = txt.charAt(i + 1); + } + int advance; + tr.glyphEntries[i] = new GLYPHENTRY(); + tr.glyphEntries[i].glyphIndex = font.charToGlyph(tags, c); + if (font.hasLayout()) { + int kerningAdjustment = 0; + if (nextChar != null) { + kerningAdjustment = font.getGlyphKerningAdjustment(tags, tr.glyphEntries[i].glyphIndex, font.charToGlyph(tags, nextChar)); + kerningAdjustment /= font.getDivider(); + } + advance = (int) Math.round(font.getDivider() * Math.round((double) fontHeight * (font.getGlyphAdvance(tr.glyphEntries[i].glyphIndex) + kerningAdjustment) / (font.getDivider() * 1024.0))); + } else { + String fontName = FontTag.defaultFontName; + advance = (int) Math.round(SWF.unitDivisor * FontTag.getSystemFontAdvance(fontName, font.getFontStyle(), (int) (fontHeight / SWF.unitDivisor), c, nextChar)); + } + tr.glyphEntries[i].glyphAdvance = advance; + } + textRecords.add(tr); + staticTextToImage(swf, characters, textRecords, bounds, 1, image, transformation); + } + } + + private String getInnerText(String html) { + String result = ""; + boolean inTag = false; + for (int i = 0; i < html.length(); i++) { + char c = html.charAt(i); + if (c == '<') { + inTag = true; + } else if (inTag && c == '>') { + inTag = false; + } else if (!inTag) { + result += c; + } + } + return result; + } + + @Override + public Point getImagePos(int frame, Map characters, Stack visited) { + return new Point(bounds.Xmin / SWF.unitDivisor, bounds.Ymin / SWF.unitDivisor); + } + + @Override + public int getNumFrames() { + return 1; } } diff --git a/trunk/src/com/jpexs/decompiler/flash/tags/base/BoundedTag.java b/trunk/src/com/jpexs/decompiler/flash/tags/base/BoundedTag.java index 81597d6bc..f93990700 100644 --- a/trunk/src/com/jpexs/decompiler/flash/tags/base/BoundedTag.java +++ b/trunk/src/com/jpexs/decompiler/flash/tags/base/BoundedTag.java @@ -27,5 +27,4 @@ import java.util.Stack; public interface BoundedTag { public RECT getRect(Map characters, Stack visited); - //public List getPaths(List tags); }