From f0b64e79fc32ee8f69e90b581e4cfadf76633688 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jindra=20Pet=C5=99=C3=ADk?= Date: Mon, 1 Mar 2021 10:05:22 +0100 Subject: [PATCH] Font editing - font name, ascent, descent, leading DefineCompactedFont (GFX) kerning import --- CHANGELOG.md | 1 + .../decompiler/flash/tags/DefineFont2Tag.java | 26 ++++ .../decompiler/flash/tags/DefineFont3Tag.java | 25 ++++ .../decompiler/flash/tags/DefineFontTag.java | 26 ++++ .../decompiler/flash/tags/base/FontTag.java | 10 ++ .../flash/tags/gfx/DefineCompactedFont.java | 70 +++++++++-- .../jpexs/decompiler/flash/gui/FontPanel.java | 114 +++++++++++++++++- 7 files changed, 259 insertions(+), 13 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1ea283481..3a8ccc899 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ All notable changes to this project will be documented in this file. ## [Unreleased] ### Added - #1561 Font editing - import ascent, descent, leading, kerning +- Font editing - font name, ascent, descent, leading ### Fixed - #1623 Right side marker (gray line) in P-code 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 7bc543f4e..21a5d334c 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 @@ -658,4 +658,30 @@ public class DefineFont2Tag extends FontTag { } } } + + @Override + public void setFontNameIntag(String name) { + fontName = name; + } + + @Override + public boolean isFontNameInTagEditable() { + return true; + } + + @Override + public boolean isAscentEditable() { + return hasLayout(); + } + + @Override + public boolean isDescentEditable() { + return hasLayout(); + } + + @Override + public boolean isLeadingEditable() { + return hasLayout(); + } + } 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 1d86419c2..ebfdfe6ff 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 @@ -675,4 +675,29 @@ public class DefineFont3Tag extends FontTag { } } } + + @Override + public void setFontNameIntag(String name) { + fontName = name; + } + + @Override + public boolean isFontNameInTagEditable() { + return true; + } + + @Override + public boolean isAscentEditable() { + return hasLayout(); + } + + @Override + public boolean isDescentEditable() { + return hasLayout(); + } + + @Override + public boolean isLeadingEditable() { + return hasLayout(); + } } 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 441dc9325..9df4bec39 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 @@ -395,4 +395,30 @@ public class DefineFontTag extends FontTag { public void setHasLayout(boolean hasLayout) { } + + @Override + public void setFontNameIntag(String name) { + + } + + @Override + public boolean isFontNameInTagEditable() { + return false; + } + + @Override + public boolean isAscentEditable() { + return false; + } + + @Override + public boolean isDescentEditable() { + return false; + } + + @Override + public boolean isLeadingEditable() { + return false; + } + } 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 05dcf30c9..9ee99aa47 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 @@ -85,6 +85,8 @@ public abstract class FontTag extends DrawableTag implements AloneTag { public abstract String getFontNameIntag(); + public abstract void setFontNameIntag(String name); + public abstract boolean isSmall(); public abstract boolean isBold(); @@ -97,6 +99,14 @@ public abstract class FontTag extends DrawableTag implements AloneTag { public abstract boolean isItalicEditable(); + public abstract boolean isFontNameInTagEditable(); + + public abstract boolean isAscentEditable(); + + public abstract boolean isDescentEditable(); + + public abstract boolean isLeadingEditable(); + public abstract void setSmall(boolean value); public abstract void setBold(boolean value); 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 10d948bf9..d9b6b4daf 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 @@ -129,14 +129,7 @@ public final class DefineCompactedFont extends FontTag { @Override public String getFontNameIntag() { - StringBuilder ret = new StringBuilder(); - for (int i = 0; i < fonts.size(); i++) { - if (i > 0) { - ret.append(", "); - } - ret.append(fonts.get(i).fontName); - } - return ret.toString(); + return fonts.get(0).fontName; } @Override @@ -194,6 +187,33 @@ public final class DefineCompactedFont extends FontTag { shapeCache.set(pos, font.glyphs.get(pos).toSHAPE()); } + for (int k = 0; k < font.kerning.size(); k++) { + if (font.kerning.get(k).char1 == character + || font.kerning.get(k).char2 == character) { + font.kerning.remove(k); + k--; + } + } + List kerning = getFontKerningPairs(cfont, (int) (getDivider() * 1024)); + for (FontHelper.KerningPair pair : kerning) { + if (pair.char1 != character && pair.char2 != character) { + continue; + } + int glyph1 = charToGlyph(pair.char1); + if (pair.char1 == character) { + + } else if (glyph1 == -1) { + continue; + } + int glyph2 = charToGlyph(pair.char2); + if (pair.char2 == character) { + + } else if (glyph2 == -1) { + continue; + } + font.kerning.add(new KerningPairType(pair.char1, pair.char2, pair.kerning)); + } + setModified(true); getSwf().clearImageCache(); } @@ -222,6 +242,15 @@ public final class DefineCompactedFont extends FontTag { font.glyphInfo.remove(pos); font.glyphs.remove(pos); shapeCache.remove(pos); + + for (int k = 0; k < font.kerning.size(); k++) { + if (font.kerning.get(k).char1 == character + || font.kerning.get(k).char2 == character) { + font.kerning.remove(k); + k--; + } + } + shiftGlyphIndices(fontId, pos + 1, false); setModified(true); @@ -475,4 +504,29 @@ public final class DefineCompactedFont extends FontTag { @Override public void setHasLayout(boolean hasLayout) { } + + @Override + public void setFontNameIntag(String name) { + fonts.get(0).fontName = name; + } + + @Override + public boolean isFontNameInTagEditable() { + return true; + } + + @Override + public boolean isAscentEditable() { + return true; + } + + @Override + public boolean isDescentEditable() { + return true; + } + + @Override + public boolean isLeadingEditable() { + return true; + } } diff --git a/src/com/jpexs/decompiler/flash/gui/FontPanel.java b/src/com/jpexs/decompiler/flash/gui/FontPanel.java index 6ca9bffc8..bedd71df3 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FontPanel.java @@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.configuration.Configuration; import com.jpexs.decompiler.flash.gui.helpers.TableLayoutHelper; +import com.jpexs.decompiler.flash.tags.DefineFontTag; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.tags.base.TextTag; @@ -121,12 +122,37 @@ public class FontPanel extends JPanel { if (fontTag.isItalicEditable()) { fontIsItalicCheckBox.setEnabled(true); } + if (fontTag.isFontNameInTagEditable()) { + fontNameIntagTextField.setVisible(true); + fontNameIntagLabel.setVisible(false); + } + + boolean layoutEditable = (fontTag.hasLayout() || fontTag.getCharacterCount() == 0) && (!(fontTag instanceof DefineFontTag)); + + if (layoutEditable) { + fontAscentTextField.setVisible(true); + fontAscentLabel.setVisible(false); + + fontDescentTextField.setVisible(true); + fontDescentLabel.setVisible(false); + + fontLeadingTextField.setVisible(true); + fontLeadingLabel.setVisible(false); + } } else { buttonEdit.setVisible(true); buttonSave.setVisible(false); buttonCancel.setVisible(false); fontIsBoldCheckBox.setEnabled(false); fontIsItalicCheckBox.setEnabled(false); + fontNameIntagTextField.setVisible(false); + fontNameIntagLabel.setVisible(true); + fontAscentTextField.setVisible(false); + fontAscentLabel.setVisible(true); + fontDescentTextField.setVisible(false); + fontDescentLabel.setVisible(true); + fontLeadingTextField.setVisible(false); + fontLeadingLabel.setVisible(true); } } @@ -217,14 +243,18 @@ public class FontPanel extends JPanel { SWF swf = ft.getSwf(); fontTag = ft; fontNameIntagLabel.setText(ft.getFontNameIntag()); + fontNameIntagTextField.setText(ft.getFontNameIntag()); fontNameTextArea.setText(ft.getFontName()); fontCopyrightTextArea.setText(ft.getFontCopyright()); fontIsBoldCheckBox.setSelected(ft.isBold()); fontIsItalicCheckBox.setSelected(ft.isItalic()); - fontDescentLabel.setText(ft.getDescent() == -1 ? translate("value.unknown") : Integer.toString(ft.getDescent())); fontAscentLabel.setText(ft.getAscent() == -1 ? translate("value.unknown") : Integer.toString(ft.getAscent())); + fontAscentTextField.setText(ft.getAscent() == -1 ? "0" : "" + ft.getAscent()); + fontDescentLabel.setText(ft.getDescent() == -1 ? translate("value.unknown") : Integer.toString(ft.getDescent())); + fontDescentTextField.setText(ft.getDescent() == -1 ? "0" : "" + ft.getDescent()); fontLeadingLabel.setText(ft.getLeading() == -1 ? translate("value.unknown") : Integer.toString(ft.getLeading())); + fontLeadingTextField.setText(ft.getLeading() == -1 ? "0" : "" + ft.getLeading()); String chars = ft.getCharacters(); fontCharactersTextArea.setText(chars); try { @@ -252,6 +282,7 @@ public class FontPanel extends JPanel { contentScrollPane = new FasterScrollPane(); addCharsPanel = new JPanel(); fontParamsPanel = new JPanel(); + fontNameIntagTextField = new JTextField(30); fontNameIntagLabel = new JLabel(); JScrollPane fontDisplayNameScrollPane = new FasterScrollPane(); fontNameTextArea = new JTextArea(); @@ -264,10 +295,13 @@ public class FontPanel extends JPanel { fontIsItalicCheckBox = new JCheckBox(); JLabel jLabel6 = new JLabel(); fontAscentLabel = new JLabel(); + fontAscentTextField = new JTextField(30); JLabel jLabel7 = new JLabel(); fontDescentLabel = new JLabel(); + fontDescentTextField = new JTextField(30); JLabel jLabel8 = new JLabel(); fontLeadingLabel = new JLabel(); + fontLeadingTextField = new JTextField(30); JLabel jLabel9 = new JLabel(); fontCharactersScrollPane = new FasterScrollPane(); fontCharactersTextArea = new JTextArea(); @@ -305,10 +339,19 @@ public class FontPanel extends JPanel { fontNameIntagLabLabel.setText(AppStrings.translate("font.name.intag")); fontParamsPanel.add(fontNameIntagLabLabel, "0,0,R"); + fontNameIntagTextField.setText(AppStrings.translate("value.unknown")); + //fontNameIntagTextField.setMinimumSize(new Dimension(100, fontNameIntagTextField.getMinimumSize().height)); + //fontNameIntagTextField.setPreferredSize(new Dimension(250, fontNameIntagTextField.getPreferredSize().height)); + fontNameIntagLabel.setText(AppStrings.translate("value.unknown")); fontNameIntagLabel.setMinimumSize(new Dimension(100, fontNameIntagLabel.getMinimumSize().height)); fontNameIntagLabel.setPreferredSize(new Dimension(250, fontNameIntagLabel.getPreferredSize().height)); - fontParamsPanel.add(fontNameIntagLabel, "1,0"); + + JPanel fontNamePanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + fontNamePanel.add(fontNameIntagTextField); + fontNamePanel.add(fontNameIntagLabel); + fontNameIntagTextField.setVisible(false); + fontParamsPanel.add(fontNamePanel, "1,0"); JLabel fontNameNameLabLabel = new JLabel(); fontNameNameLabLabel.setText(AppStrings.translate("font.name")); @@ -367,19 +410,37 @@ public class FontPanel extends JPanel { fontParamsPanel.add(jLabel6, "0,5,R"); fontAscentLabel.setText(AppStrings.translate("value.unknown")); - fontParamsPanel.add(fontAscentLabel, "1,5"); + + JPanel fontAscentPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + fontAscentPanel.add(fontAscentLabel); + fontAscentPanel.add(fontAscentTextField); + fontAscentTextField.setVisible(false); + + fontParamsPanel.add(fontAscentPanel, "1,5"); jLabel7.setText(AppStrings.translate("font.descent")); fontParamsPanel.add(jLabel7, "0,6,R"); fontDescentLabel.setText(AppStrings.translate("value.unknown")); - fontParamsPanel.add(fontDescentLabel, "1,6"); + + JPanel fontDescentPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + fontDescentPanel.add(fontDescentLabel); + fontDescentPanel.add(fontDescentTextField); + fontDescentTextField.setVisible(false); + + fontParamsPanel.add(fontDescentPanel, "1,6"); jLabel8.setText(AppStrings.translate("font.leading")); fontParamsPanel.add(jLabel8, "0,7,R"); fontLeadingLabel.setText(AppStrings.translate("value.unknown")); - fontParamsPanel.add(fontLeadingLabel, "1,7"); + + JPanel fontLeadingPanel = new JPanel(new FlowLayout(FlowLayout.LEFT, 0, 0)); + fontLeadingPanel.add(fontLeadingLabel); + fontLeadingPanel.add(fontLeadingTextField); + fontLeadingTextField.setVisible(false); + + fontParamsPanel.add(fontLeadingPanel, "1,7"); jLabel9.setText(AppStrings.translate("font.characters")); fontParamsPanel.add(jLabel9, "0,8,R,T"); @@ -608,12 +669,47 @@ public class FontPanel extends JPanel { } private void buttonSaveActionPerformed(ActionEvent evt) { + + if (!(fontTag instanceof DefineFontTag)) { + if (fontTag.getCharacterCount() == 0 && !fontTag.hasLayout()) { + fontTag.setHasLayout(true); + } + if (fontTag.hasLayout()) { + + try { + int ascent = Integer.parseInt(fontAscentTextField.getText()); + int descent = Integer.parseInt(fontLeadingTextField.getText()); + int leading = Integer.parseInt(fontLeadingTextField.getText()); + if (ascent < 0 || descent < 0 || leading < 0) { + return; + } + fontTag.setAscent(ascent); + fontTag.setDescent(descent); + fontTag.setLeading(leading); + + fontAscentLabel.setText("" + ascent); + fontDescentLabel.setText("" + descent); + fontLeadingLabel.setText("" + leading); + } catch (NumberFormatException nfe) { + return; + } + } + } + if (fontTag.isBoldEditable()) { fontTag.setBold(fontIsBoldCheckBox.isSelected()); } if (fontTag.isItalicEditable()) { fontTag.setItalic(fontIsItalicCheckBox.isSelected()); } + if (fontTag.isFontNameInTagEditable()) { + fontTag.setFontNameIntag(fontNameIntagTextField.getText()); + fontNameIntagLabel.setText(fontNameIntagTextField.getText()); + + } + + mainPanel.tagTree.repaint(); + fontTag.setModified(true); setEditable(false); } @@ -705,6 +801,8 @@ public class FontPanel extends JPanel { private JButton fontRemoveCharsButton; + private JTextField fontAscentTextField; + private JLabel fontAscentLabel; private JScrollPane fontCharactersScrollPane; @@ -715,6 +813,8 @@ public class FontPanel extends JPanel { private JLabel fontDescentLabel; + private JTextField fontDescentTextField; + private JTextArea fontNameTextArea; private JButton fontEmbedButton; @@ -725,6 +825,10 @@ public class FontPanel extends JPanel { private JLabel fontLeadingLabel; + private JTextField fontLeadingTextField; + + private JTextField fontNameIntagTextField; + private JLabel fontNameIntagLabel; private JComboBox fontFamilyNameSelection;