mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-18 00:38:10 +00:00
Issue #250 Export FLA: Static text spacing and marigins
Better text viewer code formatting
This commit is contained in:
@@ -50,7 +50,6 @@ import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictEqAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.avm2.model.operations.StrictNeqAVM2Item;
|
||||
import com.jpexs.decompiler.flash.abc.types.ABCException;
|
||||
import com.jpexs.decompiler.flash.abc.types.MethodBody;
|
||||
import com.jpexs.decompiler.flash.helpers.Helper;
|
||||
import com.jpexs.decompiler.graph.Graph;
|
||||
import com.jpexs.decompiler.graph.GraphPart;
|
||||
import com.jpexs.decompiler.graph.GraphPartMulti;
|
||||
|
||||
@@ -59,33 +59,33 @@ public class ExportDialog extends AppDialog {
|
||||
|
||||
Container cnt = getContentPane();
|
||||
cnt.setLayout(new BorderLayout());
|
||||
JPanel comboPanel=new JPanel(null);
|
||||
JPanel comboPanel = new JPanel(null);
|
||||
combos = new JComboBox[optionNames.length];
|
||||
JLabel labels[]=new JLabel[optionNames.length];
|
||||
int labWidth=0;
|
||||
JLabel labels[] = new JLabel[optionNames.length];
|
||||
int labWidth = 0;
|
||||
for (int i = 0; i < optionNames.length; i++) {
|
||||
labels[i] = new JLabel(optionNames[i]);
|
||||
if(labels[i].getPreferredSize().width>labWidth){
|
||||
if (labels[i].getPreferredSize().width > labWidth) {
|
||||
labWidth = labels[i].getPreferredSize().width;
|
||||
}
|
||||
}
|
||||
int comboWidth=200;
|
||||
int comboWidth = 200;
|
||||
int top = 10;
|
||||
for (int i = 0; i < optionNames.length; i++) {
|
||||
JLabel lab = new JLabel(optionNames[i]);
|
||||
lab.setBounds(10, top, lab.getPreferredSize().width, lab.getPreferredSize().height);
|
||||
comboPanel.add(lab);
|
||||
combos[i] = new JComboBox<>(options[i]);
|
||||
combos[i].setBounds(10+labWidth+10, top, comboWidth, combos[i].getPreferredSize().height);
|
||||
combos[i].setBounds(10 + labWidth + 10, top, comboWidth, combos[i].getPreferredSize().height);
|
||||
comboPanel.add(combos[i]);
|
||||
top += combos[i].getHeight();
|
||||
}
|
||||
Dimension dim=new Dimension(10+labWidth+10+comboWidth+10,top+10);
|
||||
Dimension dim = new Dimension(10 + labWidth + 10 + comboWidth + 10, top + 10);
|
||||
comboPanel.setMinimumSize(dim);
|
||||
comboPanel.setPreferredSize(dim);
|
||||
cnt.add(comboPanel,BorderLayout.CENTER);
|
||||
cnt.add(comboPanel, BorderLayout.CENTER);
|
||||
|
||||
JPanel buttonsPanel=new JPanel(new FlowLayout());
|
||||
JPanel buttonsPanel = new JPanel(new FlowLayout());
|
||||
JButton okButton = new JButton(translate("button.ok"));
|
||||
okButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@@ -93,7 +93,7 @@ public class ExportDialog extends AppDialog {
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
JButton cancelButton = new JButton(translate("button.cancel"));
|
||||
cancelButton.addActionListener(new ActionListener() {
|
||||
@Override
|
||||
@@ -102,11 +102,11 @@ public class ExportDialog extends AppDialog {
|
||||
setVisible(false);
|
||||
}
|
||||
});
|
||||
|
||||
|
||||
buttonsPanel.add(okButton);
|
||||
buttonsPanel.add(cancelButton);
|
||||
|
||||
cnt.add(buttonsPanel,BorderLayout.SOUTH);
|
||||
cnt.add(buttonsPanel, BorderLayout.SOUTH);
|
||||
pack();
|
||||
//setSize(245, top + getInsets().top);
|
||||
View.centerScreen(this);
|
||||
|
||||
@@ -36,36 +36,22 @@ import com.jpexs.decompiler.flash.gui.player.FlashPlayerPanel;
|
||||
import com.jpexs.decompiler.flash.gui.proxy.ProxyFrame;
|
||||
import com.jpexs.decompiler.flash.helpers.Cache;
|
||||
import com.jpexs.decompiler.flash.helpers.Helper;
|
||||
import com.jpexs.decompiler.flash.types.ZONERECORD;
|
||||
import com.sun.jna.Platform;
|
||||
import com.sun.jna.WString;
|
||||
import java.awt.*;
|
||||
import java.awt.event.ActionEvent;
|
||||
import java.awt.event.ActionListener;
|
||||
import java.awt.event.KeyAdapter;
|
||||
import java.awt.event.KeyEvent;
|
||||
import java.awt.event.MouseAdapter;
|
||||
import java.awt.event.MouseEvent;
|
||||
import java.awt.event.WindowAdapter;
|
||||
import java.awt.event.WindowEvent;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.font.LineMetrics;
|
||||
import java.awt.font.TextAttribute;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.QuadCurve2D;
|
||||
import java.io.*;
|
||||
import java.net.Socket;
|
||||
import java.net.URLDecoder;
|
||||
import java.security.AccessController;
|
||||
import java.security.PrivilegedAction;
|
||||
import java.text.AttributedCharacterIterator.Attribute;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Calendar;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Properties;
|
||||
import java.util.Scanner;
|
||||
import java.util.logging.ConsoleHandler;
|
||||
@@ -77,12 +63,9 @@ import java.util.regex.Matcher;
|
||||
import java.util.regex.Pattern;
|
||||
import javax.swing.JFileChooser;
|
||||
import javax.swing.JFrame;
|
||||
import static javax.swing.JFrame.EXIT_ON_CLOSE;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.JPanel;
|
||||
import javax.swing.SwingWorker;
|
||||
import javax.swing.UIManager;
|
||||
import static javax.swing.WindowConstants.HIDE_ON_CLOSE;
|
||||
import javax.swing.filechooser.FileFilter;
|
||||
|
||||
/**
|
||||
@@ -523,7 +506,7 @@ public class Main {
|
||||
}
|
||||
|
||||
public static void initLang() {
|
||||
if (Configuration.containsConfig("locale")) {
|
||||
if (Configuration.containsConfig("locale")) {
|
||||
Locale.setDefault(Locale.forLanguageTag((String) Configuration.getConfig("locale", "en")));
|
||||
}
|
||||
UIManager.put("OptionPane.okButtonText", AppStrings.translate("button.ok"));
|
||||
@@ -630,7 +613,7 @@ public class Main {
|
||||
initLang();
|
||||
|
||||
View.setLookAndFeel();
|
||||
|
||||
|
||||
if ((Boolean) Configuration.getConfig("cacheOnDisk", Boolean.TRUE)) {
|
||||
Cache.setStorageType(Cache.STORAGE_FILES);
|
||||
} else {
|
||||
|
||||
@@ -1162,8 +1162,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel
|
||||
fontParams1.add(fontAddCharsPanel);
|
||||
JPanel fontSelectionPanel = new JPanel(new FlowLayout());
|
||||
fontSelectionPanel.add(new JLabel(translate("font.source")));
|
||||
String fontNames[] = GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames();
|
||||
fontSelection = new JComboBox<>(fontNames);
|
||||
fontSelection = new JComboBox<>(FontTag.fontNames.toArray(new String[FontTag.fontNames.size()]));
|
||||
fontSelection.setSelectedIndex(0);
|
||||
fontSelection.setSelectedItem("Times New Roman");
|
||||
fontSelection.setSelectedItem("Arial");
|
||||
@@ -2382,16 +2381,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel
|
||||
if (fontName == null) {
|
||||
fontName = font.getFontName(tags);
|
||||
}
|
||||
//
|
||||
if (!fontNames.contains(fontName)) {
|
||||
fontName = "Times New Roman";
|
||||
}
|
||||
if (!fontNames.contains(fontName)) {
|
||||
fontName = "Arial";
|
||||
}
|
||||
if (!fontNames.contains(fontName)) {
|
||||
fontName = fontSelection.getItemAt(0);
|
||||
}
|
||||
fontName = FontTag.findInstalledFontName(fontName);
|
||||
Font f = new Font(fontName, font.getFontStyle(), 18);
|
||||
if (!f.canDisplay(character)) {
|
||||
View.showMessageDialog(null, translate("error.font.nocharacter").replace("%char%", "" + character), translate("error"), JOptionPane.ERROR_MESSAGE);
|
||||
@@ -3105,10 +3095,7 @@ public class MainFrame extends AppRibbonFrame implements ActionListener, TreeSel
|
||||
if (sourceFontsMap.containsKey(ft.getFontId())) {
|
||||
fontSelection.setSelectedItem(sourceFontsMap.get(ft.getFontId()));
|
||||
} else {
|
||||
fontSelection.setSelectedIndex(0);
|
||||
fontSelection.setSelectedItem("Times New Roman");
|
||||
fontSelection.setSelectedItem("Arial");
|
||||
fontSelection.setSelectedItem(ft.getFontName(swf.tags));
|
||||
fontSelection.setSelectedItem(FontTag.findInstalledFontName(ft.getFontName(swf.tags)));
|
||||
}
|
||||
fontChangeList.componentResized(null);
|
||||
showDetailWithPreview(CARDFONTPANEL);
|
||||
|
||||
@@ -33,7 +33,6 @@ import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Stack;
|
||||
import javax.swing.JOptionPane;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
|
||||
|
||||
@@ -27,16 +27,12 @@ import com.jpexs.decompiler.flash.abc.types.traits.TraitSlotConst;
|
||||
import static com.jpexs.decompiler.flash.gui.AppStrings.translate;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.helpers.Cache;
|
||||
import com.jpexs.decompiler.flash.helpers.Helper;
|
||||
import com.jpexs.decompiler.flash.helpers.Highlighting;
|
||||
import com.jpexs.decompiler.flash.tags.ABCContainerTag;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.Timer;
|
||||
import java.util.TimerTask;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.event.CaretEvent;
|
||||
import javax.swing.event.CaretListener;
|
||||
|
||||
|
||||
@@ -25,7 +25,6 @@ import static com.jpexs.decompiler.flash.gui.AppStrings.translate;
|
||||
import com.jpexs.decompiler.flash.gui.View;
|
||||
import com.jpexs.decompiler.flash.helpers.Helper;
|
||||
import java.awt.BorderLayout;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.util.ArrayList;
|
||||
import javax.swing.*;
|
||||
|
||||
@@ -24,11 +24,7 @@ import com.jpexs.decompiler.flash.tags.base.ImageTag;
|
||||
import com.jpexs.decompiler.flash.types.ALPHABITMAPDATA;
|
||||
import com.jpexs.decompiler.flash.types.ALPHACOLORMAPDATA;
|
||||
import com.jpexs.decompiler.flash.types.ARGB;
|
||||
import com.jpexs.decompiler.flash.types.RGBA;
|
||||
import java.awt.AlphaComposite;
|
||||
import java.awt.Color;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
|
||||
@@ -19,7 +19,6 @@ 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.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.MissingCharacterHandler;
|
||||
import com.jpexs.decompiler.flash.tags.base.TextTag;
|
||||
@@ -50,7 +49,7 @@ import java.util.regex.Pattern;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineEditTextTag extends CharacterTag implements BoundedTag, TextTag {
|
||||
public class DefineEditTextTag extends TextTag {
|
||||
|
||||
public int characterID;
|
||||
public RECT bounds;
|
||||
|
||||
@@ -26,7 +26,6 @@ import com.jpexs.decompiler.flash.types.RECT;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import java.awt.Font;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
@@ -78,7 +77,7 @@ public class DefineFont2Tag extends FontTag {
|
||||
if (fontFlagsHasLayout) {
|
||||
return fontAdvanceTable.get(glyphIndex);
|
||||
} else {
|
||||
return getGlyphWidth(glyphIndex) + 20;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -348,4 +347,9 @@ public class DefineFont2Tag extends FontTag {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLayout() {
|
||||
return fontFlagsHasLayout;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -32,11 +32,8 @@ import java.io.ByteArrayInputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
public class DefineFont3Tag extends FontTag {
|
||||
@@ -71,7 +68,7 @@ public class DefineFont3Tag extends FontTag {
|
||||
|
||||
@Override
|
||||
public int getGlyphWidth(int glyphIndex) {
|
||||
return glyphShapeTable.get(glyphIndex).getBounds().getWidth() / 20;
|
||||
return glyphShapeTable.get(glyphIndex).getBounds().getWidth();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -79,7 +76,7 @@ public class DefineFont3Tag extends FontTag {
|
||||
if (fontFlagsHasLayout) {
|
||||
return fontAdvanceTable.get(glyphIndex) / 20;
|
||||
} else {
|
||||
return getGlyphWidth(glyphIndex) + 20;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -349,4 +346,9 @@ public class DefineFont3Tag extends FontTag {
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean hasLayout() {
|
||||
return fontFlagsHasLayout;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -49,7 +49,7 @@ public class DefineFontTag extends FontTag {
|
||||
|
||||
@Override
|
||||
public int getGlyphAdvance(int glyphIndex) {
|
||||
return getGlyphWidth(glyphIndex);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.helpers.Helper;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
@@ -64,7 +63,7 @@ import java.util.regex.Pattern;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag, DrawableTag {
|
||||
public class DefineText2Tag extends TextTag implements DrawableTag {
|
||||
|
||||
public int characterID;
|
||||
public RECT textBounds;
|
||||
@@ -343,17 +342,15 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag,
|
||||
}
|
||||
tr.glyphEntries[i].glyphIndex = font.charToGlyph(tags, c);
|
||||
|
||||
/*if (tr.glyphEntries[i].glyphIndex == -1) {
|
||||
throw new ParseException("Font does not contain glyph for character '" + c + "'", lexer.yyline());
|
||||
}*/
|
||||
tr.glyphEntries[i].glyphAdvance = textHeight * font.getGlyphAdvance(tr.glyphEntries[i].glyphIndex) / 1024;
|
||||
|
||||
int gw = textHeight * font.getGlyphWidth(tr.glyphEntries[i].glyphIndex) / 1024;
|
||||
if (i == 0) {
|
||||
currentX += gw;
|
||||
int advance;
|
||||
if (font.hasLayout()) {
|
||||
advance = (int) Math.round((double) textHeight * font.getGlyphAdvance(tr.glyphEntries[i].glyphIndex) / (font.getDivider() * 1024.0));
|
||||
} else {
|
||||
currentX += tr.glyphEntries[i].glyphAdvance;
|
||||
advance = 20 * FontTag.getSystemFontAdvance(fontName, font.getFontStyle(), textHeight / 20, c);
|
||||
}
|
||||
tr.glyphEntries[i].glyphAdvance = advance;
|
||||
|
||||
currentX += advance;
|
||||
if (SWFOutputStream.getNeededBitsU(tr.glyphEntries[i].glyphIndex) > glyphBits) {
|
||||
glyphBits = SWFOutputStream.getNeededBitsU(tr.glyphEntries[i].glyphIndex);
|
||||
}
|
||||
@@ -461,6 +458,8 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag,
|
||||
@Override
|
||||
public BufferedImage toImage(int frame, List<Tag> tags, RECT displayRect, HashMap<Integer, CharacterTag> characters, Stack<Integer> visited) {
|
||||
RECT bound = getBounds();
|
||||
int fixX = -bound.Xmin;
|
||||
int fixY = -bound.Ymin;
|
||||
BufferedImage ret = new BufferedImage(bound.Xmax / 20, bound.Ymax / 20, BufferedImage.TYPE_INT_ARGB);
|
||||
Color textColor = new Color(0, 0, 0);
|
||||
FontTag font = null;
|
||||
@@ -482,10 +481,10 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag,
|
||||
textHeight = rec.textHeight;
|
||||
}
|
||||
if (rec.styleFlagsHasXOffset) {
|
||||
x = rec.xOffset * 1024 / textHeight;
|
||||
x = rec.xOffset;
|
||||
}
|
||||
if (rec.styleFlagsHasYOffset) {
|
||||
y = rec.yOffset * 1024 / textHeight;
|
||||
y = rec.yOffset;
|
||||
}
|
||||
|
||||
for (GLYPHENTRY entry : rec.glyphEntries) {
|
||||
@@ -494,14 +493,15 @@ public class DefineText2Tag extends CharacterTag implements BoundedTag, TextTag,
|
||||
rect.Xmin /= font.getDivider();
|
||||
rect.Ymax /= font.getDivider();
|
||||
rect.Ymin /= font.getDivider();
|
||||
BufferedImage img = SHAPERECORD.shapeToImage(tags, 4, null, null, glyphs.get(entry.glyphIndex).shapeRecords, textColor);
|
||||
BufferedImage img = SHAPERECORD.shapeToImage(tags, 1, null, null, glyphs.get(entry.glyphIndex).shapeRecords, textColor);
|
||||
AffineTransform tr = new AffineTransform();
|
||||
tr.setToIdentity();
|
||||
float rat = textHeight / 1024f;
|
||||
tr.translate(rat * x / 20, rat * (y + rect.Ymin) / 20);
|
||||
tr.scale(rat / font.getDivider(), rat / font.getDivider());
|
||||
tr.scale(1 / 20f, 1 / 20f);
|
||||
tr.translate(x + fixX, y + rat * rect.Ymin + fixY);
|
||||
tr.scale(rat, rat);
|
||||
g.drawImage(img, tr, null);
|
||||
x += entry.glyphAdvance * 1024 / textHeight;
|
||||
x += entry.glyphAdvance;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -20,7 +20,6 @@ import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.SWFInputStream;
|
||||
import com.jpexs.decompiler.flash.SWFOutputStream;
|
||||
import com.jpexs.decompiler.flash.helpers.Helper;
|
||||
import com.jpexs.decompiler.flash.tags.base.BoundedTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.CharacterTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
|
||||
import com.jpexs.decompiler.flash.tags.base.FontTag;
|
||||
@@ -64,7 +63,7 @@ import java.util.regex.Pattern;
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag, DrawableTag {
|
||||
public class DefineTextTag extends TextTag implements DrawableTag {
|
||||
|
||||
public int characterID;
|
||||
public RECT textBounds;
|
||||
@@ -342,19 +341,15 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag,
|
||||
}
|
||||
tr.glyphEntries[i].glyphIndex = font.charToGlyph(tags, c);
|
||||
|
||||
|
||||
|
||||
/*if (tr.glyphEntries[i].glyphIndex == -1) {
|
||||
throw new ParseException("Font does not contain glyph for character '" + c + "'", lexer.yyline());
|
||||
}*/
|
||||
tr.glyphEntries[i].glyphAdvance = textHeight * font.getGlyphAdvance(tr.glyphEntries[i].glyphIndex) / 1024;
|
||||
|
||||
int gw = textHeight * font.getGlyphWidth(tr.glyphEntries[i].glyphIndex) / 1024;
|
||||
if (i == 0) {
|
||||
currentX += gw;
|
||||
int advance;
|
||||
if (font.hasLayout()) {
|
||||
advance = (int) Math.round((double) textHeight * font.getGlyphAdvance(tr.glyphEntries[i].glyphIndex) / (font.getDivider() * 1024.0));
|
||||
} else {
|
||||
currentX += tr.glyphEntries[i].glyphAdvance;
|
||||
advance = 20 * FontTag.getSystemFontAdvance(fontName, font.getFontStyle(), textHeight / 20, c);
|
||||
}
|
||||
tr.glyphEntries[i].glyphAdvance = advance;
|
||||
|
||||
currentX += advance;
|
||||
if (SWFOutputStream.getNeededBitsU(tr.glyphEntries[i].glyphIndex) > glyphBits) {
|
||||
glyphBits = SWFOutputStream.getNeededBitsU(tr.glyphEntries[i].glyphIndex);
|
||||
}
|
||||
@@ -497,10 +492,10 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag,
|
||||
textHeight = rec.textHeight;
|
||||
}
|
||||
if (rec.styleFlagsHasXOffset) {
|
||||
x = rec.xOffset * 1024 / textHeight;
|
||||
x = rec.xOffset;
|
||||
}
|
||||
if (rec.styleFlagsHasYOffset) {
|
||||
y = rec.yOffset * 1024 / textHeight;
|
||||
y = rec.yOffset;
|
||||
}
|
||||
|
||||
for (GLYPHENTRY entry : rec.glyphEntries) {
|
||||
@@ -513,11 +508,11 @@ public class DefineTextTag extends CharacterTag implements BoundedTag, TextTag,
|
||||
AffineTransform tr = new AffineTransform();
|
||||
tr.setToIdentity();
|
||||
float rat = textHeight / 1024f;
|
||||
tr.translate(rat * x / 20, rat * (y + rect.Ymin) / 20);
|
||||
tr.scale(rat / font.getDivider(), rat / font.getDivider());
|
||||
tr.translate(fixX, fixY);
|
||||
tr.scale(1 / 20f, 1 / 20f);
|
||||
tr.translate(x + fixX, y + rat * rect.Ymin + fixY);
|
||||
tr.scale(rat, rat);
|
||||
g.drawImage(img, tr, null);
|
||||
x += entry.glyphAdvance * 1024 / textHeight;
|
||||
x += entry.glyphAdvance;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
|
||||
@@ -24,7 +24,12 @@ import com.jpexs.decompiler.flash.types.GLYPHENTRY;
|
||||
import com.jpexs.decompiler.flash.types.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.TEXTRECORD;
|
||||
import java.awt.Font;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphMetrics;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
|
||||
/**
|
||||
@@ -67,6 +72,10 @@ public abstract class FontTag extends CharacterTag implements AloneTag {
|
||||
|
||||
public abstract int getLeading();
|
||||
|
||||
public boolean hasLayout() {
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean containsChar(List<Tag> tags, char character) {
|
||||
return charToGlyph(tags, character) > -1;
|
||||
}
|
||||
@@ -125,4 +134,36 @@ public abstract class FontTag extends CharacterTag implements AloneTag {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public static int getSystemFontAdvance(String fontName, int fontStyle, int fontSize, char character) {
|
||||
return getSystemFontAdvance(new Font(fontName, fontStyle, fontSize), character);
|
||||
}
|
||||
|
||||
public static int getSystemFontAdvance(Font aFont, char character) {
|
||||
GlyphVector gv = aFont.createGlyphVector(new FontRenderContext(aFont.getTransform(), true, true), "" + character);
|
||||
GlyphMetrics gm = gv.getGlyphMetrics(0);
|
||||
return Math.round(gm.getAdvanceX());
|
||||
}
|
||||
public static List<String> fontNames = Arrays.asList(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
|
||||
|
||||
public static String findInstalledFontName(String fontName) {
|
||||
if (fontNames.contains(fontName)) {
|
||||
return fontName;
|
||||
}
|
||||
if (fontName.contains("_")) {
|
||||
String beforeUnderscore = fontName.substring(0, fontName.indexOf("_"));
|
||||
if (fontNames.contains(beforeUnderscore)) {
|
||||
return beforeUnderscore;
|
||||
}
|
||||
}
|
||||
fontName = "Times New Roman";
|
||||
if (fontNames.contains(fontName)) {
|
||||
return fontName;
|
||||
}
|
||||
fontName = "Arial";
|
||||
if (fontNames.contains(fontName)) {
|
||||
return fontName;
|
||||
}
|
||||
return fontNames.get(0);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -60,23 +60,24 @@ public abstract class ImageTag extends CharacterTag {
|
||||
|
||||
return "unk";
|
||||
}
|
||||
|
||||
protected static int max255(float val){
|
||||
if(val>255){
|
||||
|
||||
protected static int max255(float val) {
|
||||
if (val > 255) {
|
||||
return 255;
|
||||
}
|
||||
return (int)val;
|
||||
return (int) val;
|
||||
}
|
||||
|
||||
protected static Color intToColor(int val){
|
||||
return new Color(val&0xff,(val>>8)&0xff,(val>>16)&0xff,(val>>24)&0xff);
|
||||
|
||||
protected static Color intToColor(int val) {
|
||||
return new Color(val & 0xff, (val >> 8) & 0xff, (val >> 16) & 0xff, (val >> 24) & 0xff);
|
||||
}
|
||||
protected static int colorToInt(Color c){
|
||||
return (c.getAlpha()<<24)|(c.getBlue()<<16)|(c.getGreen()<<8)|c.getRed();
|
||||
|
||||
protected static int colorToInt(Color c) {
|
||||
return (c.getAlpha() << 24) | (c.getBlue() << 16) | (c.getGreen() << 8) | c.getRed();
|
||||
}
|
||||
|
||||
protected static Color multiplyAlpha(Color c){
|
||||
float multiplier = c.getAlpha()==0?0:255.0f/c.getAlpha();
|
||||
return new Color(max255(c.getRed()*multiplier), max255(c.getGreen()*multiplier), max255(c.getBlue()*multiplier), c.getAlpha());
|
||||
|
||||
protected static Color multiplyAlpha(Color c) {
|
||||
float multiplier = c.getAlpha() == 0 ? 0 : 255.0f / c.getAlpha();
|
||||
return new Color(max255(c.getRed() * multiplier), max255(c.getGreen() * multiplier), max255(c.getBlue() * multiplier), c.getAlpha());
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,29 +16,177 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.tags.base;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.text.ParseException;
|
||||
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.SHAPE;
|
||||
import com.jpexs.decompiler.flash.types.TEXTRECORD;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import java.awt.Font;
|
||||
import java.awt.FontMetrics;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.Point;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphMetrics;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.font.LineMetrics;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public interface TextTag {
|
||||
public abstract class TextTag extends CharacterTag implements BoundedTag {
|
||||
|
||||
public MATRIX getTextMatrix();
|
||||
public TextTag(SWF swf, int id, String name, byte[] data, long pos) {
|
||||
super(swf, id, name, data, pos);
|
||||
}
|
||||
|
||||
public String getText(List<Tag> tags);
|
||||
public abstract MATRIX getTextMatrix();
|
||||
|
||||
public String getFormattedText(List<Tag> tags);
|
||||
public abstract String getText(List<Tag> tags);
|
||||
|
||||
public boolean setFormattedText(MissingCharacterHandler missingCharHandler, List<Tag> tags, String text, String fontName) throws ParseException;
|
||||
public abstract String getFormattedText(List<Tag> tags);
|
||||
|
||||
public int getCharacterId();
|
||||
public abstract boolean setFormattedText(MissingCharacterHandler missingCharHandler, List<Tag> tags, String text, String fontName) throws ParseException;
|
||||
|
||||
public RECT getBounds();
|
||||
@Override
|
||||
public abstract int getCharacterId();
|
||||
|
||||
public void setBounds(RECT r);
|
||||
public abstract RECT getBounds();
|
||||
|
||||
public abstract void setBounds(RECT r);
|
||||
|
||||
private static void updateRect(RECT ret, int x, int y) {
|
||||
if (x < ret.Xmin) {
|
||||
ret.Xmin = x;
|
||||
}
|
||||
if (x > ret.Xmax) {
|
||||
ret.Xmax = x;
|
||||
}
|
||||
if (y < ret.Ymin) {
|
||||
ret.Ymin = y;
|
||||
}
|
||||
if (y > ret.Ymax) {
|
||||
ret.Ymax = y;
|
||||
}
|
||||
}
|
||||
|
||||
public static Map<String, Object> getTextRecordsAttributes(List<TEXTRECORD> list, List<Tag> tags) {
|
||||
Map<String, Object> att = new HashMap<>();
|
||||
RECT textBounds = new RECT(Integer.MAX_VALUE, Integer.MIN_VALUE, Integer.MAX_VALUE, Integer.MIN_VALUE);
|
||||
FontTag font = null;
|
||||
int x = 0;
|
||||
int y = 0;
|
||||
int textHeight = 12;
|
||||
int lineSpacing = 0;
|
||||
double leading = 0;
|
||||
double ascent = 0;
|
||||
double descent = 0;
|
||||
double lineDistance = 0;
|
||||
|
||||
List<String> availableFonts = Arrays.asList(GraphicsEnvironment.getLocalGraphicsEnvironment().getAvailableFontFamilyNames());
|
||||
|
||||
List<SHAPE> glyphs = new ArrayList<>();
|
||||
boolean firstLine = true;
|
||||
double top = 0;
|
||||
List<Integer> allLeftMargins = new ArrayList<>();
|
||||
List<Integer> allLetterSpacings = new ArrayList<>();
|
||||
FontMetrics fontMetrics = null;
|
||||
BufferedImage bi = new BufferedImage(5, 5, BufferedImage.TYPE_INT_RGB);
|
||||
Font aFont = null;
|
||||
int currentLeftMargin = 0;
|
||||
for (int r = 0; r < list.size(); r++) {
|
||||
TEXTRECORD rec = list.get(r);
|
||||
if (rec.styleFlagsHasFont) {
|
||||
for (Tag t : tags) {
|
||||
if (t instanceof FontTag) {
|
||||
FontTag ft = (FontTag) t;
|
||||
if (ft.getFontId() == rec.fontId) {
|
||||
font = ft;
|
||||
}
|
||||
}
|
||||
}
|
||||
textHeight = rec.textHeight;
|
||||
glyphs = font.getGlyphShapeTable();
|
||||
|
||||
if (font.getLeading() == -1) {
|
||||
String fontName = font.getFontName(tags);
|
||||
if (!availableFonts.contains(fontName)) {
|
||||
fontName = "Times New Roman";
|
||||
}
|
||||
if (!availableFonts.contains(fontName)) {
|
||||
fontName = "Arial";
|
||||
}
|
||||
aFont = new Font(fontName, font.getFontStyle(), textHeight / 20);
|
||||
fontMetrics = bi.getGraphics().getFontMetrics(aFont);
|
||||
LineMetrics lm = fontMetrics.getLineMetrics("A", bi.getGraphics());
|
||||
ascent = lm.getAscent();
|
||||
descent = lm.getDescent();
|
||||
leading = lm.getLeading();
|
||||
lineDistance = ascent + descent;
|
||||
} else {
|
||||
leading = ((double) font.getLeading() * textHeight / 1024.0 / font.getDivider() / 20.0);
|
||||
ascent = ((double) font.getAscent() * textHeight / 1024.0 / font.getDivider() / 20.0);
|
||||
descent = ((double) font.getDescent() * textHeight / 1024.0 / font.getDivider() / 20.0);
|
||||
lineDistance = ascent + descent;
|
||||
}
|
||||
|
||||
}
|
||||
currentLeftMargin = 0;
|
||||
if (rec.styleFlagsHasXOffset) {
|
||||
x = rec.xOffset;
|
||||
currentLeftMargin = x;
|
||||
}
|
||||
if (rec.styleFlagsHasYOffset) {
|
||||
if (!firstLine) {
|
||||
top += lineDistance;
|
||||
int topint = 20 * (int) Math.round(top);
|
||||
lineSpacing = rec.yOffset - topint;
|
||||
top += ((double) lineSpacing) / 20;
|
||||
} else {
|
||||
top = ascent - 2.0; //I don't know why, but there are always 2 pixels
|
||||
}
|
||||
y = rec.yOffset;
|
||||
}
|
||||
firstLine = false;
|
||||
String lineStr = "";
|
||||
allLeftMargins.add(currentLeftMargin);
|
||||
int letterSpacing = 0;
|
||||
for (int e = 0; e < rec.glyphEntries.length; e++) {
|
||||
GLYPHENTRY entry = rec.glyphEntries[e];
|
||||
GLYPHENTRY nextEntry = null;
|
||||
if (e < rec.glyphEntries.length - 1) {
|
||||
nextEntry = rec.glyphEntries[e + 1];
|
||||
}
|
||||
RECT rect = SHAPERECORD.getBounds(glyphs.get(entry.glyphIndex).shapeRecords);
|
||||
rect.Xmax = (int) Math.round(((double) rect.Xmax * textHeight) / (font.getDivider() * 1024));
|
||||
rect.Xmin = (int) Math.round(((double) rect.Xmin * textHeight) / (font.getDivider() * 1024));
|
||||
rect.Ymax = (int) Math.round(((double) rect.Ymax * textHeight) / (font.getDivider() * 1024));
|
||||
rect.Ymin = (int) Math.round(((double) rect.Ymin * textHeight) / (font.getDivider() * 1024));
|
||||
updateRect(textBounds, x + rect.Xmin, y + rect.Ymin);
|
||||
updateRect(textBounds, x + rect.Xmax, y + rect.Ymax);
|
||||
int adv = entry.glyphAdvance;
|
||||
int defaultAdvance = 20 * FontTag.getSystemFontAdvance(aFont, font.glyphToChar(tags, entry.glyphIndex));
|
||||
letterSpacing = adv - defaultAdvance;
|
||||
x += adv;
|
||||
}
|
||||
allLetterSpacings.add(letterSpacing);
|
||||
}
|
||||
att.put("indent", 0); //?
|
||||
att.put("rightMargin", 0); //?
|
||||
att.put("lineSpacing", lineSpacing);
|
||||
att.put("textBounds", textBounds);
|
||||
att.put("allLeftMargins", allLeftMargins);
|
||||
att.put("allLetterSpacings", allLetterSpacings);
|
||||
return att;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,8 @@ package com.jpexs.decompiler.flash.types;
|
||||
import com.jpexs.decompiler.flash.tags.Tag;
|
||||
import com.jpexs.decompiler.flash.tags.base.NeedsCharacters;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.SHAPERECORD;
|
||||
import com.jpexs.decompiler.flash.types.shaperecords.StyleChangeRecord;
|
||||
import java.awt.Point;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
|
||||
@@ -16,14 +16,6 @@
|
||||
*/
|
||||
package com.jpexs.decompiler.flash.types;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.awt.font.FontRenderContext;
|
||||
import java.awt.font.GlyphMetrics;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.font.LineBreakMeasurer;
|
||||
import java.awt.font.LineMetrics;
|
||||
import javax.swing.JFrame;
|
||||
|
||||
/**
|
||||
* Represents 32-bit alpha, red, green and blue value
|
||||
*
|
||||
|
||||
@@ -35,7 +35,6 @@ import java.awt.AlphaComposite;
|
||||
import java.awt.BasicStroke;
|
||||
import java.awt.Color;
|
||||
import java.awt.Font;
|
||||
import java.awt.Graphics;
|
||||
import java.awt.Graphics2D;
|
||||
import java.awt.GraphicsEnvironment;
|
||||
import java.awt.LinearGradientPaint;
|
||||
@@ -49,10 +48,8 @@ import java.awt.TexturePaint;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.geom.AffineTransform;
|
||||
import java.awt.geom.GeneralPath;
|
||||
import java.awt.geom.Path2D;
|
||||
import java.awt.geom.PathIterator;
|
||||
import java.awt.geom.Point2D;
|
||||
import java.awt.geom.QuadCurve2D;
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
@@ -63,7 +60,6 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.logging.Level;
|
||||
import java.util.logging.Logger;
|
||||
import javax.swing.JFrame;
|
||||
import javax.swing.JPanel;
|
||||
|
||||
/**
|
||||
|
||||
@@ -2277,6 +2277,8 @@ public class XFLConverter {
|
||||
ret += " instanceName=\"" + xmlString(instanceName) + "\"";
|
||||
}
|
||||
ret += antiAlias;
|
||||
Map<String, Object> attrs = TextTag.getTextRecordsAttributes(textRecords, tags);
|
||||
|
||||
ret += " width=\"" + tag.getBounds().getWidth() / 2 + "\" height=\"" + tag.getBounds().getHeight() + "\" autoExpand=\"true\" isSelectable=\"false\">";
|
||||
ret += matStr;
|
||||
|
||||
@@ -2289,7 +2291,14 @@ public class XFLConverter {
|
||||
int textHeight = -1;
|
||||
RGB textColor = null;
|
||||
RGBA textColorA = null;
|
||||
for (TEXTRECORD rec : textRecords) {
|
||||
boolean newline = false;
|
||||
boolean firstRun = true;
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Integer> leftMargins = (List<Integer>) attrs.get("allLeftMargins");
|
||||
@SuppressWarnings("unchecked")
|
||||
List<Integer> letterSpacings = (List<Integer>) attrs.get("allLetterSpacings");
|
||||
for (int r = 0; r < textRecords.size(); r++) {
|
||||
TEXTRECORD rec = textRecords.get(r);
|
||||
if (rec.styleFlagsHasColor) {
|
||||
if (tag instanceof DefineTextTag) {
|
||||
textColor = rec.textColor;
|
||||
@@ -2327,13 +2336,23 @@ public class XFLConverter {
|
||||
}
|
||||
}
|
||||
}
|
||||
newline = false;
|
||||
if (!firstRun && rec.styleFlagsHasYOffset) {
|
||||
newline = true;
|
||||
}
|
||||
firstRun = false;
|
||||
if (font != null) {
|
||||
ret += "<DOMTextRun>";
|
||||
ret += "<characters>" + xmlString(rec.getText(tags, font)) + "</characters>";
|
||||
ret += "<characters>" + xmlString((newline ? "\r" : "") + rec.getText(tags, font)) + "</characters>";
|
||||
ret += "<textAttrs>";
|
||||
|
||||
ret += "<DOMTextAttrs aliasText=\"false\" rotation=\"true\" size=\"" + twipToPixel(textHeight) + "\" bitmapSize=\"" + textHeight + "\"";
|
||||
//indent=\"5\" leftMargin=\"2\" letterSpacing=\"1\" lineSpacing=\"6\" rightMargin=\"3\"
|
||||
ret += " letterSpacing=\"" + doubleToString(twipToPixel(letterSpacings.get(r))) + "\"";
|
||||
ret += " indent=\"" + doubleToString(twipToPixel((int) attrs.get("indent"))) + "\"";
|
||||
ret += " leftMargin=\"" + doubleToString(twipToPixel(leftMargins.get(r))) + "\"";
|
||||
ret += " lineSpacing=\"" + doubleToString(twipToPixel((int) attrs.get("lineSpacing"))) + "\"";
|
||||
ret += " rightMargin=\"" + doubleToString(twipToPixel((int) attrs.get("rightMargin"))) + "\"";
|
||||
|
||||
if (textColor != null) {
|
||||
ret += " fillColor=\"" + textColor.toHexRGB() + "\"";
|
||||
} else if (textColorA != null) {
|
||||
|
||||
Reference in New Issue
Block a user