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 1dcc9577f..bf27450f1 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 @@ -35,6 +35,7 @@ import com.jpexs.decompiler.flash.tags.dynamictext.SameStyleTextRecord; import com.jpexs.decompiler.flash.tags.dynamictext.TextStyle; import com.jpexs.decompiler.flash.tags.dynamictext.Word; import com.jpexs.decompiler.flash.tags.text.ParsedSymbol; +import com.jpexs.decompiler.flash.tags.text.TextAlign; import com.jpexs.decompiler.flash.tags.text.TextLexer; import com.jpexs.decompiler.flash.tags.text.TextParseException; import com.jpexs.decompiler.flash.types.BasicType; @@ -663,6 +664,11 @@ public class DefineEditTextTag extends TextTag { return true; } + @Override + public boolean alignText(TextAlign textAlign) { + return true; + } + @Override public RECT getRect(Set added) { return bounds; 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 6a6bbf740..a8b24068b 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 @@ -30,6 +30,7 @@ import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler; import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.tags.text.ParsedSymbol; +import com.jpexs.decompiler.flash.tags.text.TextAlign; import com.jpexs.decompiler.flash.tags.text.TextLexer; import com.jpexs.decompiler.flash.tags.text.TextParseException; import com.jpexs.decompiler.flash.types.BasicType; @@ -444,6 +445,41 @@ public class DefineText2Tag extends TextTag { return true; } + @Override + public boolean alignText(TextAlign textAlign) { + int maxWidth = 0; + for (TEXTRECORD tr : textRecords) { + int width = tr.getTotalAdvance(); + + if (width > maxWidth) { + maxWidth = width; + } + } + + for (TEXTRECORD tr : textRecords) { + int width = tr.getTotalAdvance(); + switch (textAlign) { + case LEFT: + tr.xOffset = 0; + tr.styleFlagsHasXOffset = true; + break; + case CENTER: + tr.xOffset = (maxWidth - width) / 2; + tr.styleFlagsHasXOffset = true; + break; + case RIGHT: + tr.xOffset = maxWidth - width; + tr.styleFlagsHasXOffset = true; + break; + case JUSTIFY: + tr.xOffset = 0; + tr.styleFlagsHasXOffset = true; + break; + } + } + return true; + } + @Override public RECT getRect(Set added) { return textBounds; 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 43991ccac..83462acc2 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 @@ -31,6 +31,7 @@ import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler; import com.jpexs.decompiler.flash.tags.base.RenderContext; import com.jpexs.decompiler.flash.tags.base.TextTag; import com.jpexs.decompiler.flash.tags.text.ParsedSymbol; +import com.jpexs.decompiler.flash.tags.text.TextAlign; import com.jpexs.decompiler.flash.tags.text.TextLexer; import com.jpexs.decompiler.flash.tags.text.TextParseException; import com.jpexs.decompiler.flash.types.BasicType; @@ -425,7 +426,6 @@ public class DefineTextTag extends TextTag { tr.glyphEntries[i].glyphAdvance = advance; currentX += advance; - } if (currentX > maxX) { @@ -453,6 +453,41 @@ public class DefineTextTag extends TextTag { return true; } + @Override + public boolean alignText(TextAlign textAlign) { + int maxWidth = 0; + for (TEXTRECORD tr : textRecords) { + int width = tr.getTotalAdvance(); + + if (width > maxWidth) { + maxWidth = width; + } + } + + for (TEXTRECORD tr : textRecords) { + int width = tr.getTotalAdvance(); + switch (textAlign) { + case LEFT: + tr.xOffset = 0; + tr.styleFlagsHasXOffset = true; + break; + case CENTER: + tr.xOffset = (maxWidth - width) / 2; + tr.styleFlagsHasXOffset = true; + break; + case RIGHT: + tr.xOffset = maxWidth - width; + tr.styleFlagsHasXOffset = true; + break; + case JUSTIFY: + tr.xOffset = 0; + tr.styleFlagsHasXOffset = true; + break; + } + } + return true; + } + @Override public int getCharacterId() { return characterID; diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/TextTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/TextTag.java index 4c33dd9ef..81af44a33 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/TextTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/TextTag.java @@ -28,6 +28,7 @@ import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter; import com.jpexs.decompiler.flash.exporters.shape.SVGShapeExporter; import com.jpexs.decompiler.flash.importers.TextImportResizeTextBoundsMode; import com.jpexs.decompiler.flash.tags.Tag; +import com.jpexs.decompiler.flash.tags.text.TextAlign; import com.jpexs.decompiler.flash.tags.text.TextParseException; import com.jpexs.decompiler.flash.types.ColorTransform; import com.jpexs.decompiler.flash.types.FILLSTYLE; @@ -85,6 +86,8 @@ public abstract class TextTag extends CharacterTag implements DrawableTag { // use the texts from the "texts" argument when it is not null public abstract boolean setFormattedText(MissingCharacterHandler missingCharHandler, String formattedText, String[] texts) throws TextParseException; + public abstract boolean alignText(TextAlign textAlign); + @Override public abstract int getCharacterId(); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/TextAlign.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/TextAlign.java new file mode 100644 index 000000000..eae4877e9 --- /dev/null +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/TextAlign.java @@ -0,0 +1,26 @@ +/* + * Copyright (C) 2010-2015 JPEXS, All rights reserved. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 3.0 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. + */ +package com.jpexs.decompiler.flash.tags.text; + +/** + * + * @author JPEXS + */ +public enum TextAlign { + + LEFT, RIGHT, CENTER, JUSTIFY +} diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/TEXTRECORD.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/TEXTRECORD.java index 887f29d6d..412045b7e 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/TEXTRECORD.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/types/TEXTRECORD.java @@ -70,4 +70,12 @@ public class TEXTRECORD implements Serializable { } return ret.toString(); } + + public int getTotalAdvance() { + int width = 0; + for (GLYPHENTRY ge : glyphEntries) { + width += ge.glyphAdvance; + } + return width; + } } diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index 47b93d6c3..e21732b23 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -100,6 +100,7 @@ import com.jpexs.decompiler.flash.tags.base.SoundStreamHeadTypeTag; import com.jpexs.decompiler.flash.tags.base.SoundTag; import com.jpexs.decompiler.flash.tags.base.TextImportErrorHandler; import com.jpexs.decompiler.flash.tags.base.TextTag; +import com.jpexs.decompiler.flash.tags.text.TextAlign; import com.jpexs.decompiler.flash.tags.text.TextParseException; import com.jpexs.decompiler.flash.timeline.DepthState; import com.jpexs.decompiler.flash.timeline.Frame; @@ -1990,6 +1991,14 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec return false; } + public boolean alignText(TextTag textTag, TextAlign textAlign) { + if (textTag.alignText(textAlign)) { + return true; + } + + return false; + } + @Override public void actionPerformed(ActionEvent e) { switch (e.getActionCommand()) { diff --git a/src/com/jpexs/decompiler/flash/gui/TextPanel.java b/src/com/jpexs/decompiler/flash/gui/TextPanel.java index f36f2aae1..b4ae4b6ad 100644 --- a/src/com/jpexs/decompiler/flash/gui/TextPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/TextPanel.java @@ -18,9 +18,11 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.gui.abc.LineMarkedEditorPane; +import com.jpexs.decompiler.flash.tags.DefineEditTextTag; 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.TextAlign; import com.jpexs.decompiler.flash.tags.text.TextParseException; import com.jpexs.decompiler.flash.treeitems.TreeItem; import java.awt.BorderLayout; @@ -49,6 +51,14 @@ public class TextPanel extends JPanel implements ActionListener { private static final String ACTION_SAVE_TEXT = "SAVETEXT"; + private static final String ACTION_TEXT_ALIGN_LEFT = "TEXTALIGNLEFT"; + + private static final String ACTION_TEXT_ALIGN_CENTER = "TEXTALIGNCENTER"; + + private static final String ACTION_TEXT_ALIGN_RIGHT = "TEXTALIGNRIGHT"; + + private static final String ACTION_TEXT_ALIGN_JUSTIFY = "TEXTALIGNJUSTIFY"; + private final MainPanel mainPanel; private final SearchPanel textSearchPanel; @@ -61,6 +71,14 @@ public class TextPanel extends JPanel implements ActionListener { private final JButton textCancelButton; + private final JButton textAlignLeftButton; + + private final JButton textAlignCenterButton; + + private final JButton textAlignRightButton; + + private final JButton textAlignJustifyButton; + public TextPanel(final MainPanel mainPanel) { super(new BorderLayout()); @@ -109,9 +127,33 @@ public class TextPanel extends JPanel implements ActionListener { textCancelButton.setActionCommand(ACTION_CANCEL_TEXT); textCancelButton.addActionListener(this); + textAlignLeftButton = new JButton("", View.getIcon("textalignleft16")); + textAlignLeftButton.setMargin(new Insets(3, 3, 3, 10)); + textAlignLeftButton.setActionCommand(ACTION_TEXT_ALIGN_LEFT); + textAlignLeftButton.addActionListener(this); + + textAlignCenterButton = new JButton("", View.getIcon("textaligncenter16")); + textAlignCenterButton.setMargin(new Insets(3, 3, 3, 10)); + textAlignCenterButton.setActionCommand(ACTION_TEXT_ALIGN_CENTER); + textAlignCenterButton.addActionListener(this); + + textAlignRightButton = new JButton("", View.getIcon("textalignright16")); + textAlignRightButton.setMargin(new Insets(3, 3, 3, 10)); + textAlignRightButton.setActionCommand(ACTION_TEXT_ALIGN_RIGHT); + textAlignRightButton.addActionListener(this); + + textAlignJustifyButton = new JButton("", View.getIcon("textalignjustify16")); + textAlignJustifyButton.setMargin(new Insets(3, 3, 3, 10)); + textAlignJustifyButton.setActionCommand(ACTION_TEXT_ALIGN_JUSTIFY); + textAlignJustifyButton.addActionListener(this); + textButtonsPanel.add(textEditButton); textButtonsPanel.add(textSaveButton); textButtonsPanel.add(textCancelButton); + textButtonsPanel.add(textAlignLeftButton); + textButtonsPanel.add(textAlignCenterButton); + textButtonsPanel.add(textAlignRightButton); + textButtonsPanel.add(textAlignJustifyButton); textSaveButton.setVisible(false); textCancelButton.setVisible(false); @@ -133,6 +175,17 @@ public class TextPanel extends JPanel implements ActionListener { textSaveButton.setVisible(edit); textEditButton.setVisible(!edit); textCancelButton.setVisible(edit); + + TreeItem item = mainPanel.tagTree.getCurrentTreeItem(); + boolean alignable = false; + if (item instanceof TextTag && !(item instanceof DefineEditTextTag)) { + alignable = !edit; + } + + textAlignLeftButton.setVisible(alignable); + textAlignCenterButton.setVisible(alignable); + textAlignRightButton.setVisible(alignable); + textAlignJustifyButton.setVisible(false); // todo } public void updateSearchPos() { @@ -157,7 +210,7 @@ public class TextPanel extends JPanel implements ActionListener { setEditText(false); mainPanel.reload(true); break; - case ACTION_SAVE_TEXT: + case ACTION_SAVE_TEXT: { TreeItem item = mainPanel.tagTree.getCurrentTreeItem(); if (item instanceof TextTag) { TextTag textTag = (TextTag) item; @@ -168,6 +221,38 @@ public class TextPanel extends JPanel implements ActionListener { } } break; + } + case ACTION_TEXT_ALIGN_LEFT: + case ACTION_TEXT_ALIGN_CENTER: + case ACTION_TEXT_ALIGN_RIGHT: + case ACTION_TEXT_ALIGN_JUSTIFY: { + TreeItem item = mainPanel.tagTree.getCurrentTreeItem(); + if (item instanceof TextTag) { + TextTag textTag = (TextTag) item; + TextAlign ta = null; + switch (e.getActionCommand()) { + case ACTION_TEXT_ALIGN_LEFT: + ta = TextAlign.LEFT; + break; + case ACTION_TEXT_ALIGN_CENTER: + ta = TextAlign.CENTER; + break; + case ACTION_TEXT_ALIGN_RIGHT: + ta = TextAlign.RIGHT; + break; + case ACTION_TEXT_ALIGN_JUSTIFY: + ta = TextAlign.JUSTIFY; + break; + } + + if (mainPanel.alignText(textTag, ta)) { + setEditText(false); + item.getSwf().clearImageCache(); + mainPanel.refreshTree(); + } + } + break; + } } } diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/shape_align_center.png b/src/com/jpexs/decompiler/flash/gui/graphics/shape_align_center.png new file mode 100644 index 000000000..efe9a98e5 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/shape_align_center.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/textaligncenter16.png b/src/com/jpexs/decompiler/flash/gui/graphics/textaligncenter16.png new file mode 100644 index 000000000..57beb3813 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/textaligncenter16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/textalignjustify16.png b/src/com/jpexs/decompiler/flash/gui/graphics/textalignjustify16.png new file mode 100644 index 000000000..2fbdd6920 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/textalignjustify16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/textalignleft16.png b/src/com/jpexs/decompiler/flash/gui/graphics/textalignleft16.png new file mode 100644 index 000000000..6c8fcc116 Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/textalignleft16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/graphics/textalignright16.png b/src/com/jpexs/decompiler/flash/gui/graphics/textalignright16.png new file mode 100644 index 000000000..a1502571c Binary files /dev/null and b/src/com/jpexs/decompiler/flash/gui/graphics/textalignright16.png differ diff --git a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTree.java b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTree.java index 91d8234e7..44129cdba 100644 --- a/src/com/jpexs/decompiler/flash/gui/tagtree/TagTree.java +++ b/src/com/jpexs/decompiler/flash/gui/tagtree/TagTree.java @@ -536,7 +536,7 @@ public class TagTree extends JTree { public TreeItem getCurrentTreeItem() { if (!mainPanel.folderPreviewPanel.selectedItems.isEmpty()) { - return mainPanel.folderPreviewPanel.selectedItems.get(0); + return mainPanel.folderPreviewPanel.selectedItems.entrySet().iterator().next().getValue(); } TreeItem item = (TreeItem) getLastSelectedPathComponent(); return item;