diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java index d8de95bcc..273c8ec9b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/SWF.java @@ -271,8 +271,7 @@ public final class SWF implements TreeItem, Timelined { public Map characters = new HashMap<>(); public List abcList; public JPEGTablesTag jtt; - public Map sourceFontFamiliesMap = new HashMap<>(); - public Map sourceFontFacesMap = new HashMap<>(); + public Map sourceFontNamesMap = new HashMap<>(); public static final double unitDivisor = 20; private static final Logger logger = Logger.getLogger(SWF.class.getName()); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java index d5d02f8f3..ab2edc50b 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/configuration/Configuration.java @@ -452,7 +452,7 @@ public class Configuration { recentFiles.set(Helper.joinStrings(recentFilesArray, "::")); } - public static Map getFontIdToFamilyMap() { + public static Map getFontToNameMap() { String fonts = fontPairing.get(); if (fonts == null) { return new HashMap<>(); @@ -467,39 +467,20 @@ public class Configuration { } return result; } - - public static Map getFontIdToFaceMap() { - String fonts = fontPairing.get(); - if (fonts == null) { - return new HashMap<>(); - } - - Map result = new HashMap<>(); - for (String pair : fonts.split("::")) { - if (!pair.isEmpty()) { - String[] splittedPair = pair.split("="); - result.put(splittedPair[0], splittedPair.length < 3 ? "" : splittedPair[2]); - } - } - return result; - } - - public static void addFontPair(String fileName, int fontId, String fontName, String installedFontFamily, String installedFontFace) { + + public static void addFontPair(String fileName, int fontId, String fontName, String installedName) { String key = fileName + "_" + fontId + "_" + fontName; - Map fontPairs = getFontIdToFamilyMap(); - fontPairs.put(key, installedFontFamily); - fontPairs.put(fontName, installedFontFamily); + Map fontPairs = getFontToNameMap(); + fontPairs.put(key, installedName); + fontPairs.put(fontName, installedName); - Map facePairs = getFontIdToFaceMap(); - facePairs.put(key, installedFontFace); - facePairs.put(fontName, installedFontFace); StringBuilder sb = new StringBuilder(); int i = 0; for (Entry pair : fontPairs.entrySet()) { if (i != 0) { sb.append("::"); } - sb.append(pair.getKey()).append("=").append(pair.getValue()).append("=").append(facePairs.containsKey(pair.getKey()) ? facePairs.get(pair.getKey()) : ""); + sb.append(pair.getKey()).append("=").append(pair.getValue()); i++; } fontPairing.set(sb.toString()); 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 8b3c6ffe4..0a28339b5 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 @@ -120,7 +120,7 @@ public class FontExporter { ttfFile = File.createTempFile("ffdec_export", ".ttf"); } - Fontastic f = new Fontastic(t.getFontName(), ttfFile); + Fontastic f = new Fontastic(t.getFontNameIntag(), ttfFile); String cop = t.getCopyright(); f.getEngine().setCopyrightYear(cop == null ? "" : cop); diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/FontHelper.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/FontHelper.java index fdd8717e5..899d7df9a 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/FontHelper.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/helpers/FontHelper.java @@ -17,12 +17,26 @@ package com.jpexs.decompiler.flash.helpers; import java.awt.Font; +import java.awt.FontFormatException; import java.awt.GraphicsEnvironment; +import java.awt.font.FontRenderContext; +import java.awt.font.GlyphVector; +import java.awt.font.TextAttribute; +import java.io.EOFException; +import java.io.File; +import java.io.FileInputStream; +import java.io.IOException; +import java.io.InputStream; import java.lang.reflect.Field; +import java.lang.reflect.InvocationTargetException; +import java.text.AttributedCharacterIterator; +import java.util.ArrayList; import java.util.Arrays; import java.util.HashMap; +import java.util.List; import java.util.Locale; import java.util.Map; +import javax.swing.JPanel; /** * @@ -30,6 +44,11 @@ import java.util.Map; */ public class FontHelper { + private static Object getFontManager() throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Class clFmFactory = Class.forName("sun.font.FontManagerFactory"); + return clFmFactory.getDeclaredMethod("getInstance").invoke(null); + } + /** * Gets all available fonts in the system * @@ -40,24 +59,27 @@ public class FontHelper { Font fonts[] = null; try { - Class clFmFactory = Class.forName("sun.font.FontManagerFactory"); - Object fm = clFmFactory.getDeclaredMethod("getInstance").invoke(null); + + Object fm = getFontManager(); Class clFm = Class.forName("sun.font.SunFontManager"); //Delete cached installed names Field inField = clFm.getDeclaredField("installedNames"); inField.setAccessible(true); inField.set(null, null); + inField.setAccessible(false); //Delete cached family names Field allFamField = clFm.getDeclaredField("allFamilies"); allFamField.setAccessible(true); allFamField.set(fm, null); + allFamField.setAccessible(false); //Delete cached fonts Field allFonField = clFm.getDeclaredField("allFonts"); allFonField.setAccessible(true); allFonField.set(fm, null); + allFonField.setAccessible(false); fonts = (Font[]) clFm.getDeclaredMethod("getAllInstalledFonts").invoke(fm); } catch (Throwable ex) { @@ -67,7 +89,7 @@ public class FontHelper { fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts(); } for (Font f : fonts) { - String fam = f.getFamily(Locale.getDefault()); + String fam = f.getFamily(Locale.ENGLISH); //Do not want Java logical fonts if (Arrays.asList("Dialog", "DialogInput", "Monospaced", "Serif", "SansSerif").contains(fam)) { continue; @@ -75,21 +97,327 @@ public class FontHelper { if (!ret.containsKey(fam)) { ret.put(fam, new HashMap()); } - String face = getFontFace(f); - ret.get(f.getFamily()).put(face, f); + + ret.get(fam).put(f.getFontName(Locale.ENGLISH), f); } return ret; } - public static String getFontFace(Font f) { - String fam = f.getFamily(Locale.getDefault()); - String face = f.getFontName(Locale.getDefault()); - if (face.startsWith(fam)) { - face = face.substring(fam.length()).trim(); + /** + * Gets kerning offset for two characters of the font + * + * @param font Font + * @param char1 First character + * @param char2 Second character + * @return offset + */ + public static int getFontCharsKerning(Font font, char char1, char char2) { + char[] chars = new char[]{char1, char2}; + Map withKerningAttrs = new HashMap<>(); + + withKerningAttrs.put(TextAttribute.FONT, font); + withKerningAttrs.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); + Font withKerningFont = Font.getFont(withKerningAttrs); + GlyphVector withKerningVector = withKerningFont.layoutGlyphVector((new JPanel()).getFontMetrics(withKerningFont).getFontRenderContext(), chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); + int withKerningX = withKerningVector.getGlyphLogicalBounds(1).getBounds().x; + + Map noKerningAttrs = new HashMap<>(); + noKerningAttrs.put(TextAttribute.FONT, font); + noKerningAttrs.put(TextAttribute.KERNING, 0); + Font noKerningFont = Font.getFont(noKerningAttrs); + GlyphVector noKerningVector = noKerningFont.layoutGlyphVector((new JPanel()).getFontMetrics(noKerningFont).getFontRenderContext(), chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); + int noKerningX = noKerningVector.getGlyphLogicalBounds(1).getBounds().x; + return withKerningX - noKerningX; + } + + /** + * Gets all kerning pairs of a Font. It is very slow. + * + * @param font + * @param size + * @return + */ + public static List getFontKerningPairs(Font font, int size) { + File fontFile = getFontFile(font); + if (fontFile != null && fontFile.getName().toLowerCase().endsWith(".ttf")) { + KerningLoader k = new KerningLoader(); + try { + return k.loadFromTTF(fontFile, size); + } catch (IOException | FontFormatException ex) { + //ignore + } } - if (face.startsWith(".")) { - face = face.substring(1); + List ret = new ArrayList<>(); + + List availableChars = new ArrayList<>(); + for (char c1 = 0; c1 < Character.MAX_VALUE; c1++) { + if (font.canDisplay((int) c1)) { + availableChars.add(c1); + } + } + for (char c1 : availableChars) { + ret.addAll(getFontKerningPairsOneChar(availableChars, font, c1)); + + } + return ret; + } + + private static List getFontKerningPairsOneChar(List availableChars, Font font, char firstChar) { + List ret = new ArrayList<>(); + + char[] chars = new char[availableChars.size() * 2]; + + for (int i = 0; i < availableChars.size(); i++) { + chars[i * 2] = firstChar; + chars[i * 2 + 1] = availableChars.get(i); + } + + Map withKerningAttrs = new HashMap<>(); + + withKerningAttrs.put(TextAttribute.FONT, font); + withKerningAttrs.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); + Font withKerningFont = Font.getFont(withKerningAttrs); + GlyphVector withKerningVector = withKerningFont.layoutGlyphVector((new JPanel()).getFontMetrics(withKerningFont).getFontRenderContext(), chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); + int withKerningX[] = new int[availableChars.size()]; + for (int i = 0; i < availableChars.size(); i++) { + withKerningX[i] = withKerningVector.getGlyphLogicalBounds(i * 2 + 1).getBounds().x; + } + + Map noKerningAttrs = new HashMap<>(); + noKerningAttrs.put(TextAttribute.FONT, font); + noKerningAttrs.put(TextAttribute.KERNING, 0); + Font noKerningFont = Font.getFont(noKerningAttrs); + GlyphVector noKerningVector = noKerningFont.layoutGlyphVector((new JPanel()).getFontMetrics(noKerningFont).getFontRenderContext(), chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); + for (int i = 0; i < availableChars.size(); i++) { + int noKerningX = noKerningVector.getGlyphLogicalBounds(i * 2 + 1).getBounds().x; + int kerning = withKerningX[i] - noKerningX; + if (kerning > 0) { + ret.add(new KerningPair(firstChar, availableChars.get(i), kerning)); + } + } + return ret; + } + + public static class KerningPair { + + public char char1; + public char char2; + public int kerning; + + public KerningPair(char char1, char char2, int kerning) { + this.char1 = char1; + this.char2 = char2; + this.kerning = kerning; + } + + @Override + public int hashCode() { + int hash = 3; + hash = 67 * hash + this.char1; + hash = 67 * hash + this.char2; + hash = 67 * hash + this.kerning; + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final KerningPair other = (KerningPair) obj; + if (this.char1 != other.char1) { + return false; + } + if (this.char2 != other.char2) { + return false; + } + if (this.kerning != other.kerning) { + return false; + } + return true; + } + + @Override + public String toString() { + return "'" + char1 + "','" + char2 + "' => " + kerning; + } + + } + + private static Object getFont2d(Font f) throws ClassNotFoundException, NoSuchMethodException, IllegalAccessException, IllegalArgumentException, InvocationTargetException { + Object fm = getFontManager(); + return Class.forName("sun.font.FontManager").getDeclaredMethod("findFont2D", String.class, int.class, int.class).invoke(fm, f.getFontName(), f.getStyle(), 2/*LOGICAL_FALLBACK*/); + } + + public static File getFontFile(Font f) { + try { + Class pfClass = Class.forName("sun.font.PhysicalFont"); + Field platName = pfClass.getDeclaredField("platName"); + platName.setAccessible(true); + String fontPath = (String) platName.get(getFont2d(f)); + platName.setAccessible(false); + return new File(fontPath); + } catch (Throwable e) { + return null; + } + } + + private static Map getFontGlyphToCharMap(Font f) { + Map ret = new HashMap<>(); + FontRenderContext frc = new FontRenderContext(null, true, false); + for (char i = 0; i < Character.MAX_VALUE; i++) { + if (f.canDisplay(i)) { + GlyphVector gv = f.createGlyphVector(frc, new char[]{i}); + ret.put(gv.getGlyphCode(0), i); + } + } + return ret; + } + + private static class KerningLoader { + + private int size = -1; + private float scale; + private long bytePosition; + private long headOffset = -1; + private long kernOffset = -1; + private Font font; + private Map charmap; + + public List loadFromTTF(File file, int size) throws IOException, FontFormatException { + font = Font.createFont(Font.TRUETYPE_FONT, file); + charmap = getFontGlyphToCharMap(font); + InputStream input = new FileInputStream(file); + List ret = new ArrayList<>(); + this.size = size; + if (input == null) { + throw new IllegalArgumentException("input cannot be null."); + } + readTableDirectory(input); + if (headOffset == -1) { + throw new IOException("HEAD table not found."); + } + if (kernOffset == -1) { + return ret; + } + if (headOffset < kernOffset) { + readHEAD(input); + readKERN(input, ret); + } else { + readKERN(input, ret); + readHEAD(input); + } + input.close(); + for (KerningPair kp : ret) { + kp.kerning *= scale; + } + return ret; + } + + private void readTableDirectory(InputStream input) throws IOException { + skip(input, 4); + int tableCount = readUnsignedShort(input); + skip(input, 6); + + byte[] tagBytes = new byte[4]; + for (int i = 0; i < tableCount; i++) { + tagBytes[0] = readByte(input); + tagBytes[1] = readByte(input); + tagBytes[2] = readByte(input); + tagBytes[3] = readByte(input); + skip(input, 4); + long offset = readUnsignedLong(input); + skip(input, 4); + + String tag = new String(tagBytes, "ISO-8859-1"); + if (tag.equals("head")) { + headOffset = offset; + if (kernOffset != -1) { + break; + } + } else if (tag.equals("kern")) { + kernOffset = offset; + if (headOffset != -1) { + break; + } + } + } + } + + private void readHEAD(InputStream input) throws IOException { + seek(input, headOffset + 2 * 4 + 2 * 4 + 2); + int unitsPerEm = readUnsignedShort(input); + scale = (float) size / unitsPerEm; + } + + private void readKERN(InputStream input, List ret) throws IOException { + seek(input, kernOffset + 2); + for (int subTableCount = readUnsignedShort(input); subTableCount > 0; subTableCount--) { + skip(input, 2 * 2); + int tupleIndex = readUnsignedShort(input); + if (!((tupleIndex & 1) != 0) || (tupleIndex & 2) != 0 || (tupleIndex & 4) != 0) { + return; + } + if (tupleIndex >> 8 != 0) { + continue; + } + + int kerningCount = readUnsignedShort(input); + skip(input, 3 * 2); + while (kerningCount-- > 0) { + int firstGlyphCode = readUnsignedShort(input); + int secondGlyphCode = readUnsignedShort(input); + int offset = readShort(input); + ret.add(new KerningPair(charmap.get(firstGlyphCode), charmap.get(secondGlyphCode), offset)); + } + } + } + + private int readUnsignedByte(InputStream input) throws IOException { + bytePosition++; + int b = input.read(); + if (b == -1) { + throw new EOFException("Unexpected end of file."); + } + return b; + } + + private byte readByte(InputStream input) throws IOException { + return (byte) readUnsignedByte(input); + } + + private int readUnsignedShort(InputStream input) throws IOException { + return (readUnsignedByte(input) << 8) + readUnsignedByte(input); + } + + private short readShort(InputStream input) throws IOException { + return (short) readUnsignedShort(input); + } + + private long readUnsignedLong(InputStream input) throws IOException { + long value = readUnsignedByte(input); + value = (value << 8) + readUnsignedByte(input); + value = (value << 8) + readUnsignedByte(input); + value = (value << 8) + readUnsignedByte(input); + return value; + } + + private void skip(InputStream input, long skip) throws IOException { + while (skip > 0) { + long skipped = input.skip(skip); + if (skipped <= 0) { + break; + } + bytePosition += skipped; + skip -= skipped; + } + } + + private void seek(InputStream input, long position) throws IOException { + skip(input, position - bytePosition); } - return face; } } 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 7be666191..675cfc99f 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 @@ -296,7 +296,7 @@ public class DefineFont2Tag extends FontTag { } @Override - public String getFontName() { + public String getFontNameIntag() { String ret = fontName; if (ret.contains("" + (char) 0)) { ret = ret.substring(0, ret.indexOf(0)); 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 ee6b8c1c9..5f1ba4f71 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 @@ -284,7 +284,7 @@ public class DefineFont3Tag extends FontTag { } @Override - public String getFontName() { + public String getFontNameIntag() { String ret = fontName; if (ret.contains("" + (char) 0)) { ret = ret.substring(0, ret.indexOf(0)); 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 ac2deff67..941b0dca6 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 @@ -173,7 +173,7 @@ public class DefineFontTag extends FontTag { } @Override - public String getFontName() { + public String getFontNameIntag() { ensureFontInfo(); if (fontInfo2Tag != null) { return fontInfo2Tag.fontName; 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 a21ef7230..b8a895610 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 @@ -43,6 +43,7 @@ import java.awt.font.FontRenderContext; import java.awt.font.GlyphMetrics; import java.awt.font.GlyphVector; import java.awt.geom.Area; +import java.util.HashMap; import java.util.HashSet; import java.util.List; import java.util.Map; @@ -76,7 +77,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable public abstract int getGlyphWidth(int glyphIndex); - public abstract String getFontName(); + public abstract String getFontNameIntag(); public abstract boolean isSmall(); @@ -103,8 +104,25 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable public abstract int getDescent(); public abstract int getLeading(); + + public String getFontName(){ + DefineFontNameTag fontNameTag = getFontNameTag(); + if(fontNameTag == null){ + return getFontNameIntag(); + } + return fontNameTag.fontName; + } + + public String getFontCopyright(){ + DefineFontNameTag fontNameTag = getFontNameTag(); + if(fontNameTag == null){ + return ""; + } + return fontNameTag.fontCopyright; + } - public static Map> installedFonts; + public static Map> installedFontsByFamily; + public static Map installedFontsByName; public static String defaultFontName; @@ -142,7 +160,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable if (className != null) { nameAppend = ": " + className; } - String fontName = getFontName(); + String fontName = getFontNameIntag(); if (fontName != null) { nameAppend = ": " + fontName; } @@ -150,12 +168,12 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable } public String getSystemFontName() { - Map fontPairs = Configuration.getFontIdToFamilyMap(); - String key = swf.getShortFileName() + "_" + getFontId() + "_" + getFontName(); + Map fontPairs = Configuration.getFontToNameMap(); + String key = swf.getShortFileName() + "_" + getFontId() + "_" + getFontNameIntag(); if (fontPairs.containsKey(key)) { return fontPairs.get(key); } - key = getFontName(); + key = getFontNameIntag(); if (fontPairs.containsKey(key)) { return fontPairs.get(key); } @@ -206,52 +224,59 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable } public static void reload() { - installedFonts = FontHelper.getInstalledFonts(); - - if (installedFonts.containsKey("Times New Roman")) { + installedFontsByFamily = FontHelper.getInstalledFonts(); + installedFontsByName = new HashMap<>(); + + for(String fam:installedFontsByFamily.keySet()){ + for(String nam:installedFontsByFamily.get(fam).keySet()){ + installedFontsByName.put(nam, installedFontsByFamily.get(fam).get(nam)); + } + } + + if (installedFontsByFamily.containsKey("Times New Roman")) { defaultFontName = "Times New Roman"; - } else if (installedFonts.containsKey("Arial")) { + } else if (installedFontsByFamily.containsKey("Arial")) { defaultFontName = "Arial"; } else { - defaultFontName = installedFonts.keySet().iterator().next(); + defaultFontName = installedFontsByFamily.keySet().iterator().next(); } } public static String getFontNameWithFallback(String fontName) { - if (installedFonts.containsKey(fontName)) { + if (installedFontsByFamily.containsKey(fontName)) { return fontName; } - if (installedFonts.containsKey("Times New Roman")) { + if (installedFontsByFamily.containsKey("Times New Roman")) { return "Times New Roman"; } - if (installedFonts.containsKey("Arial")) { + if (installedFontsByFamily.containsKey("Arial")) { return "Arial"; } //First font - return installedFonts.keySet().iterator().next(); + return installedFontsByFamily.keySet().iterator().next(); } public static String isFontFamilyInstalled(String fontFamily) { - if (installedFonts.containsKey(fontFamily)) { + if (installedFontsByFamily.containsKey(fontFamily)) { return fontFamily; } if (fontFamily.contains("_")) { String beforeUnderscore = fontFamily.substring(0, fontFamily.indexOf('_')); - if (installedFonts.containsKey(beforeUnderscore)) { + if (installedFontsByFamily.containsKey(beforeUnderscore)) { return beforeUnderscore; } } return null; } - public static String findInstalledFontFamily(String fontFamily) { - if (installedFonts.containsKey(fontFamily)) { - return fontFamily; + public static String findInstalledFontName(String fontName) { + if (installedFontsByName.containsKey(fontName)) { + return fontName; } - if (fontFamily.contains("_")) { - String beforeUnderscore = fontFamily.substring(0, fontFamily.indexOf('_')); - if (installedFonts.containsKey(beforeUnderscore)) { + if (fontName.contains("_")) { + String beforeUnderscore = fontName.substring(0, fontName.indexOf('_')); + if (installedFontsByName.containsKey(beforeUnderscore)) { return beforeUnderscore; } } @@ -294,7 +319,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable @Override public String getCharacterExportFileName() { - return super.getCharacterExportFileName() + "_" + getFontName(); + return super.getCharacterExportFileName() + "_" + getFontNameIntag(); } public DefineFontNameTag getFontNameTag() { 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 2853eb8f0..c33676fbf 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 @@ -26,11 +26,11 @@ import java.util.Map; public class MissingCharacterHandler { public boolean handle(FontTag font, char character) { - String fontName = font.getFontName(); - if (!FontTag.installedFonts.containsKey(fontName)) { + String fontName = font.getFontNameIntag(); + if (!FontTag.installedFontsByFamily.containsKey(fontName)) { return false; } - Map faces = FontTag.installedFonts.get(fontName); + Map faces = FontTag.installedFontsByFamily.get(fontName); Font f = null; for (String face : faces.keySet()) { 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 2e5c71d4c..48d4e38fc 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 @@ -143,7 +143,7 @@ public abstract class TextTag extends CharacterTag implements DrawableTag { glyphs = font.getGlyphShapeTable(); if (!font.hasLayout()) { - String fontName = FontTag.getFontNameWithFallback(font.getFontName()); + String fontName = FontTag.getFontNameWithFallback(font.getFontNameIntag()); aFont = new Font(fontName, font.getFontStyle(), (int) (textHeight / SWF.unitDivisor)); fontMetrics = graphics.getFontMetrics(aFont); LineMetrics lm = fontMetrics.getLineMetrics("A", graphics); @@ -417,7 +417,7 @@ public abstract class TextTag extends CharacterTag implements DrawableTag { Element textElement = exporter.createElement("text"); textElement.setAttribute("font-size", Double.toString(rat * 1024)); - textElement.setAttribute("font-family", font.getFontName()); + textElement.setAttribute("font-family", font.getFontNameIntag()); textElement.setAttribute("textLength", Double.toString(totalAdvance / SWF.unitDivisor)); textElement.setAttribute("lengthAdjust", "spacing"); textElement.setTextContent(text.toString()); @@ -432,7 +432,7 @@ public abstract class TextTag extends CharacterTag implements DrawableTag { exporter.addToGroup(textElement); FontExportMode fontExportMode = FontExportMode.WOFF; - exporter.addStyle(font.getFontName(), new FontExporter().exportFont(font, fontExportMode), fontExportMode); + exporter.addStyle(font.getFontNameIntag(), new FontExporter().exportFont(font, fontExportMode), fontExportMode); if (hasOffset) { exporter.endGroup(); @@ -458,7 +458,7 @@ public abstract class TextTag extends CharacterTag implements DrawableTag { } if (charId == null) { - charId = exporter.getUniqueId(Helper.getValidHtmlId("font_" + font.getFontName() + "_" + ch)); + charId = exporter.getUniqueId(Helper.getValidHtmlId("font_" + font.getFontNameIntag() + "_" + ch)); exporter.createDefGroup(null, charId); SVGShapeExporter shapeExporter = new SVGShapeExporter(swf, shape, exporter, null, colorTransform, zoom); shapeExporter.export(); 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 4c1a44417..fb573d9af 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 @@ -117,7 +117,7 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { } @Override - public String getFontName() { + public String getFontNameIntag() { String ret = ""; for (int i = 0; i < fonts.size(); i++) { if (i > 0) { @@ -380,7 +380,7 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag { ret.glyphShapeTable.add(shpX); ret.fontBoundsTable.add(getGlyphBounds(g)); } - ret.fontName = getFontName(); + ret.fontName = getFontNameIntag(); ret.languageCode = new LANGCODE(1); ret.fontKerningTable = new KERNINGRECORD[0];/*new KERNINGRECORD[ft.kerning.size()]; for(int i=0;i withKerningAttrs = new HashMap<>(); - - withKerningAttrs.put(TextAttribute.FAMILY, fontName); - if ((fontStyle & Font.BOLD) == Font.BOLD) { - withKerningAttrs.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); - } - if ((fontStyle & Font.ITALIC) == Font.ITALIC) { - withKerningAttrs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE); - } - withKerningAttrs.put(TextAttribute.SIZE, (float) fontSize); - withKerningAttrs.put(TextAttribute.KERNING, TextAttribute.KERNING_ON); - Font withKerningFont = Font.getFont(withKerningAttrs); - GlyphVector withKerningVector = withKerningFont.layoutGlyphVector((new JPanel()).getFontMetrics(withKerningFont).getFontRenderContext(), chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); - int withKerningX = withKerningVector.getGlyphLogicalBounds(1).getBounds().x; - - Map noKerningAttrs = new HashMap<>(); - noKerningAttrs.put(TextAttribute.FAMILY, fontName); - if ((fontStyle & Font.BOLD) == Font.BOLD) { - noKerningAttrs.put(TextAttribute.WEIGHT, TextAttribute.WEIGHT_BOLD); - } - if ((fontStyle & Font.ITALIC) == Font.ITALIC) { - noKerningAttrs.put(TextAttribute.POSTURE, TextAttribute.POSTURE_OBLIQUE); - } - noKerningAttrs.put(TextAttribute.SIZE, (float) fontSize); - Font noKerningFont = Font.getFont(noKerningAttrs); - GlyphVector noKerningVector = noKerningFont.layoutGlyphVector((new JPanel()).getFontMetrics(noKerningFont).getFontRenderContext(), chars, 0, chars.length, Font.LAYOUT_LEFT_TO_RIGHT); - int noKerningX = noKerningVector.getGlyphLogicalBounds(1).getBounds().x; - return withKerningX - noKerningX; - } + } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java index ac00684ae..a35e4fb66 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/xfl/XFLConverter.java @@ -1950,7 +1950,7 @@ public class XFLConverter { } } if (fontName == null) { - fontName = font.getFontName(); + fontName = font.getFontNameIntag(); } int fontStyle = font.getFontStyle(); String installedFont; @@ -2451,7 +2451,7 @@ public class XFLConverter { } } if ((fontName == null) && (font != null)) { - fontName = font.getFontName(); + fontName = font.getFontNameIntag(); } int fontStyle = 0; if (font != null) { @@ -2609,7 +2609,7 @@ public class XFLConverter { } if (ft != null) { if (fontName == null) { - fontName = ft.getFontName(); + fontName = ft.getFontNameIntag(); } italic = ft.isItalic(); bold = ft.isBold(); @@ -3261,7 +3261,7 @@ public class XFLConverter { } if (ft != null) { if (fontName == null) { - fontName = ft.getFontName(); + fontName = ft.getFontNameIntag(); } italic = ft.isItalic(); bold = ft.isBold(); @@ -3343,7 +3343,7 @@ public class XFLConverter { if (tag instanceof FontTag) { FontTag ft = (FontTag) tag; String fontName = null; - if (f.equals(ft.getFontName())) { + if (f.equals(ft.getFontNameIntag())) { for (Tag u : tags) { if (u instanceof DefineFontNameTag) { if (((DefineFontNameTag) u).fontId == ft.getFontId()) { @@ -3352,7 +3352,7 @@ public class XFLConverter { } } if (fontName == null) { - fontName = ft.getFontName(); + fontName = ft.getFontNameIntag(); } String installedFont; if ((installedFont = FontTag.isFontFamilyInstalled(fontName)) != null) { diff --git a/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java b/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java index efc7d5717..9f64487a2 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java +++ b/src/com/jpexs/decompiler/flash/gui/FontEmbedDialog.java @@ -17,7 +17,6 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.tags.font.CharacterRanges; import com.jpexs.helpers.Helper; import java.awt.BorderLayout; @@ -37,11 +36,9 @@ import java.io.IOException; import java.util.HashSet; import java.util.Set; import java.util.TreeSet; -import java.util.Vector; import javax.swing.Box; import javax.swing.BoxLayout; import javax.swing.ButtonGroup; -import javax.swing.DefaultComboBoxModel; import javax.swing.JButton; import javax.swing.JCheckBox; import javax.swing.JComboBox; @@ -67,8 +64,8 @@ public class FontEmbedDialog extends AppDialog implements ActionListener { private static final int SAMPLE_MAX_LENGTH = 50; - private final JComboBox familyNamesSelection; - private final JComboBox faceSelection; + private final JComboBox familyNamesSelection; + private final JComboBox faceSelection; private final JCheckBox[] rangeCheckboxes; private final String rangeNames[]; private final JLabel[] rangeSamples; @@ -83,7 +80,7 @@ public class FontEmbedDialog extends AppDialog implements ActionListener { if (ttfFileRadio.isSelected() && customFont != null) { return customFont; } - return FontTag.installedFonts.get(familyNamesSelection.getSelectedItem().toString()).get(faceSelection.getSelectedItem().toString()); + return ((FontFace)faceSelection.getSelectedItem()).font; } public boolean hasUpdateTexts() { @@ -126,11 +123,11 @@ public class FontEmbedDialog extends AppDialog implements ActionListener { private JRadioButton ttfFileRadio; private JRadioButton installedRadio; - private void updateFaceSelection() { - faceSelection.setModel(new DefaultComboBoxModel<>(new Vector(FontTag.installedFonts.get(familyNamesSelection.getSelectedItem().toString()).keySet()))); + private void updateFaceSelection() { + faceSelection.setModel(FontPanel.getFaceModel((FontFamily)familyNamesSelection.getSelectedItem())); } - public FontEmbedDialog(String selectedFamily, String selectedFace, String selectedChars) { + public FontEmbedDialog(FontFace selectedFace, String selectedChars) { setSize(900, 600); setDefaultCloseOperation(HIDE_ON_CLOSE); setTitle(translate("dialog.title")); @@ -150,8 +147,8 @@ public class FontEmbedDialog extends AppDialog implements ActionListener { installedRadio.setSelected(true); individialSample = new JLabel(); - familyNamesSelection = new JComboBox<>(new Vector(new TreeSet(FontTag.installedFonts.keySet()))); - familyNamesSelection.setSelectedItem(selectedFamily); + familyNamesSelection = new JComboBox<>(FontPanel.getFamilyModel()); + familyNamesSelection.setSelectedItem(new FontFamily(selectedFace.font)); faceSelection = new JComboBox<>(); updateFaceSelection(); faceSelection.setSelectedItem(selectedFace); diff --git a/src/com/jpexs/decompiler/flash/gui/FontFace.java b/src/com/jpexs/decompiler/flash/gui/FontFace.java new file mode 100644 index 000000000..82f162cef --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/FontFace.java @@ -0,0 +1,73 @@ +/* + * Copyright (C) 2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.jpexs.decompiler.flash.gui; + +import java.awt.Font; +import java.util.Objects; + +/** + * + * @author JPEXS + */ +public class FontFace implements Comparable{ + public Font font; + public FontFace(Font font) { + this.font = font; + } + + @Override + public String toString() { + String face = font.getFontName(); + String fam = font.getFamily(); + if(face.startsWith(fam)){ + face = face.substring(fam.length()).trim(); + } + if(face.startsWith(".")){ + face=face.substring(1); + } + return face; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 79 * hash + Objects.hashCode(this.font); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final FontFace other = (FontFace) obj; + if (!Objects.equals(this.font, other.font)) { + return false; + } + return true; + } + + @Override + public int compareTo(FontFace o) { + return font.getFontName().compareTo(o.font.getFontName()); + } + +} diff --git a/src/com/jpexs/decompiler/flash/gui/FontFamily.java b/src/com/jpexs/decompiler/flash/gui/FontFamily.java new file mode 100644 index 000000000..1418559fe --- /dev/null +++ b/src/com/jpexs/decompiler/flash/gui/FontFamily.java @@ -0,0 +1,72 @@ +/* + * Copyright (C) 2014 JPEXS + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program 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 General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +package com.jpexs.decompiler.flash.gui; + +import java.awt.Font; +import java.util.Locale; +import java.util.Objects; + +/** + * + * @author JPEXS + */ +public class FontFamily implements Comparable{ + public String familyEn; + public String family; + + public FontFamily(Font font){ + this(font.getFamily(Locale.ENGLISH),font.getFamily()); + } + + public FontFamily(String familyEn, String family) { + this.familyEn = familyEn; + this.family = family; + } + + @Override + public String toString() { + return family; + } + + @Override + public int hashCode() { + int hash = 7; + hash = 89 * hash + Objects.hashCode(this.familyEn); + return hash; + } + + @Override + public boolean equals(Object obj) { + if (obj == null) { + return false; + } + if (getClass() != obj.getClass()) { + return false; + } + final FontFamily other = (FontFamily) obj; + if (!Objects.equals(this.familyEn, other.familyEn)) { + return false; + } + return true; + } + + @Override + public int compareTo(FontFamily o) { + return family.compareTo(o.family); + } +} diff --git a/src/com/jpexs/decompiler/flash/gui/FontPanel.java b/src/com/jpexs/decompiler/flash/gui/FontPanel.java index 3c50fac6a..272fdc703 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/FontPanel.java @@ -18,8 +18,6 @@ package com.jpexs.decompiler.flash.gui; import com.jpexs.decompiler.flash.SWF; import com.jpexs.decompiler.flash.configuration.Configuration; -import com.jpexs.decompiler.flash.helpers.FontHelper; -import com.jpexs.decompiler.flash.tags.DefineFontNameTag; import com.jpexs.decompiler.flash.tags.Tag; import com.jpexs.decompiler.flash.tags.base.FontTag; import com.jpexs.decompiler.flash.tags.base.TextTag; @@ -34,6 +32,7 @@ import java.awt.event.ItemListener; import java.io.File; import java.io.IOException; import java.util.HashSet; +import java.util.Locale; import java.util.Set; import java.util.TreeSet; import java.util.Vector; @@ -77,12 +76,22 @@ public class FontPanel extends javax.swing.JPanel { fontTag = null; } - private ComboBoxModel getFamilyModel() { - return new DefaultComboBoxModel<>(new Vector(new TreeSet(FontTag.installedFonts.keySet()))); + public static ComboBoxModel getFamilyModel() { + Set famSet=new TreeSet<>(); + for(Font f:FontTag.installedFontsByName.values()){ + famSet.add(new FontFamily(f)); + } + return new DefaultComboBoxModel<>(new Vector(famSet)); } - private ComboBoxModel getNameModel(String family) { - return new DefaultComboBoxModel<>(new Vector(FontTag.installedFonts.get(family).keySet())); + public static ComboBoxModel getFaceModel(FontFamily family) { + + Set faceSet=new TreeSet<>(); + for(Font f:FontTag.installedFontsByFamily.get(family.familyEn).values()){ + faceSet.add(new FontFace(f)); + } + + return new DefaultComboBoxModel<>(new Vector(faceSet)); } private void setEditable(boolean editable) { @@ -174,22 +183,10 @@ public class FontPanel extends javax.swing.JPanel { public void showFontTag(FontTag ft) { SWF swf = ft.getSwf(); - fontTag = ft; - DefineFontNameTag fontNameTag = null; - for (Tag tag : swf.tags) { - if (tag instanceof DefineFontNameTag) { - DefineFontNameTag dfnt = (DefineFontNameTag) tag; - if (dfnt.fontId == ft.getFontId()) { - fontNameTag = dfnt; - } - } - } - - fontNameLabel.setText(ft.getFontName()); - if (fontNameTag != null) { - fontDisplayNameTextArea.setText(fontNameTag.fontName); - fontCopyrightTextArea.setText(fontNameTag.fontCopyright); - } + fontTag = ft; + fontNameIntagLabel.setText(ft.getFontNameIntag()); + fontNameTextArea.setText(ft.getFontName()); + fontCopyrightTextArea.setText(ft.getFontCopyright()); fontIsBoldCheckBox.setSelected(ft.isBold()); fontIsItalicCheckBox.setSelected(ft.isItalic()); @@ -200,37 +197,29 @@ public class FontPanel extends javax.swing.JPanel { fontCharactersTextArea.setText(chars); setAllowSave(false); String key = swf.getShortFileName() + "_" + ft.getFontId() + "_" + ft.getFontName(); - if (swf.sourceFontFamiliesMap.containsKey(ft.getFontId())) { - fontFamilyNameSelection.setSelectedItem(swf.sourceFontFamiliesMap.get(ft.getFontId())); - } else if (Configuration.getFontIdToFamilyMap().containsKey(key)) { - fontFamilyNameSelection.setSelectedItem(Configuration.getFontIdToFamilyMap().get(key)); - } else if (Configuration.getFontIdToFamilyMap().containsKey(ft.getFontName())) { - fontFamilyNameSelection.setSelectedItem(Configuration.getFontIdToFamilyMap().get(ft.getFontName())); + + String selectedFont = ""; + + if (swf.sourceFontNamesMap.containsKey(ft.getFontId())) { + selectedFont = swf.sourceFontNamesMap.get(ft.getFontId()); + } else if (Configuration.getFontToNameMap().containsKey(key)) { + selectedFont = Configuration.getFontToNameMap().get(key); + } else if (Configuration.getFontToNameMap().containsKey(ft.getFontName())) { + selectedFont = Configuration.getFontToNameMap().get(ft.getFontName()); } else { - fontFamilyNameSelection.setSelectedItem(FontTag.findInstalledFontFamily(ft.getFontName())); + selectedFont = FontTag.findInstalledFontName(ft.getFontName()); } - - if (swf.sourceFontFacesMap.containsKey(ft.getFontId())) { - fontFaceSelection.setSelectedItem(swf.sourceFontFacesMap.get(ft.getFontId())); - } else if (Configuration.getFontIdToFaceMap().containsKey(key)) { - fontFaceSelection.setSelectedItem(Configuration.getFontIdToFaceMap().get(key)); - } else if (Configuration.getFontIdToFaceMap().containsKey(ft.getFontName())) { - fontFaceSelection.setSelectedItem(Configuration.getFontIdToFaceMap().get(ft.getFontName())); - } else { - java.util.Map faces = FontTag.installedFonts.get(fontFamilyNameSelection.getSelectedItem().toString()); - boolean found = false; - for (String face : faces.keySet()) { - Font f = faces.get(face); - if (f.isBold() == ft.isBold() && f.isItalic() == ft.isItalic()) { - found = true; - fontFaceSelection.setSelectedItem(face); - break; - } - } - if (!found) { - fontFaceSelection.setSelectedItem(""); - } + + Font selFont = FontTag.installedFontsByName.get(selectedFont); + if(selFont == null){ + selectedFont = FontTag.findInstalledFontName(ft.getFontName()); + selFont = FontTag.installedFontsByName.get(selectedFont); } + + fontFamilyNameSelection.setSelectedItem(new FontFamily(selFont)); + fontFaceSelection.setSelectedItem(new FontFace(selFont)); + + setAllowSave(true); setEditable(false); } @@ -250,9 +239,9 @@ public class FontPanel extends javax.swing.JPanel { addCharsPanel = new javax.swing.JPanel(); fontParamsPanel = new javax.swing.JPanel(); - fontNameLabel = new javax.swing.JLabel(); + fontNameIntagLabel = new javax.swing.JLabel(); javax.swing.JScrollPane fontDisplayNameScrollPane = new javax.swing.JScrollPane(); - fontDisplayNameTextArea = new javax.swing.JTextArea(); + fontNameTextArea = new javax.swing.JTextArea(); javax.swing.JLabel jLabel3 = new javax.swing.JLabel(); javax.swing.JScrollPane fontCopyrightScrollPane = new javax.swing.JScrollPane(); fontCopyrightTextArea = new javax.swing.JTextArea(); @@ -294,33 +283,33 @@ public class FontPanel extends javax.swing.JPanel { {TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED, TableLayout.PREFERRED,} })); - JLabel fontNameLabLabel = new JLabel(); - fontNameLabLabel.setText(AppStrings.translate("font.name")); // NOI18N - fontParamsPanel.add(fontNameLabLabel, "0,0,R"); + JLabel fontNameIntagLabLabel = new JLabel(); + fontNameIntagLabLabel.setText(AppStrings.translate("font.name.intag")); // NOI18N + fontParamsPanel.add(fontNameIntagLabLabel, "0,0,R"); - fontNameLabel.setText(AppStrings.translate("value.unknown")); // NOI18N - fontNameLabel.setMaximumSize(new java.awt.Dimension(250, 14)); - fontNameLabel.setMinimumSize(new java.awt.Dimension(250, 14)); - fontNameLabel.setPreferredSize(new java.awt.Dimension(250, 14)); - fontParamsPanel.add(fontNameLabel, "1,0"); + fontNameIntagLabel.setText(AppStrings.translate("value.unknown")); // NOI18N + fontNameIntagLabel.setMaximumSize(new java.awt.Dimension(250, 14)); + fontNameIntagLabel.setMinimumSize(new java.awt.Dimension(250, 14)); + fontNameIntagLabel.setPreferredSize(new java.awt.Dimension(250, 14)); + fontParamsPanel.add(fontNameIntagLabel, "1,0"); JLabel fontNameNameLabLabel = new JLabel(); - fontNameNameLabLabel.setText(AppStrings.translate("fontName.name")); // NOI18N + fontNameNameLabLabel.setText(AppStrings.translate("font.name")); // NOI18N fontParamsPanel.add(fontNameNameLabLabel, "0,1,R"); fontDisplayNameScrollPane.setBorder(null); fontDisplayNameScrollPane.setHorizontalScrollBarPolicy(javax.swing.ScrollPaneConstants.HORIZONTAL_SCROLLBAR_NEVER); fontDisplayNameScrollPane.setHorizontalScrollBar(null); - fontDisplayNameTextArea.setEditable(false); - fontDisplayNameTextArea.setColumns(20); - fontDisplayNameTextArea.setFont(new JLabel().getFont()); - fontDisplayNameTextArea.setLineWrap(true); - fontDisplayNameTextArea.setText(AppStrings.translate("value.unknown")); // NOI18N - fontDisplayNameTextArea.setWrapStyleWord(true); - fontDisplayNameTextArea.setMinimumSize(new java.awt.Dimension(250, 16)); - fontDisplayNameTextArea.setOpaque(false); - fontDisplayNameScrollPane.setViewportView(fontDisplayNameTextArea); + fontNameTextArea.setEditable(false); + fontNameTextArea.setColumns(20); + fontNameTextArea.setFont(new JLabel().getFont()); + fontNameTextArea.setLineWrap(true); + fontNameTextArea.setText(AppStrings.translate("value.unknown")); // NOI18N + fontNameTextArea.setWrapStyleWord(true); + fontNameTextArea.setMinimumSize(new java.awt.Dimension(250, 16)); + fontNameTextArea.setOpaque(false); + fontDisplayNameScrollPane.setViewportView(fontNameTextArea); fontParamsPanel.add(fontDisplayNameScrollPane, "1,1"); @@ -407,7 +396,7 @@ public class FontPanel extends javax.swing.JPanel { fontFamilyNameSelection.setModel(getFamilyModel()); fontFamilyNameSelection.setSelectedItem(FontTag.defaultFontName); - fontFaceSelection.setModel(getNameModel((String) fontFamilyNameSelection.getSelectedItem())); + fontFaceSelection.setModel(getFaceModel((FontFamily)fontFamilyNameSelection.getSelectedItem())); fontFamilyNameSelection.addItemListener(new java.awt.event.ItemListener() { @Override public void itemStateChanged(java.awt.event.ItemEvent evt) { @@ -520,7 +509,7 @@ public class FontPanel extends javax.swing.JPanel { for (int c = 0; c < newchars.length(); c++) { selChars.add(newchars.codePointAt(c)); } - fontAddChars((FontTag) item, selChars, FontTag.installedFonts.get(fontFamilyNameSelection.getSelectedItem().toString()).get(fontFaceSelection.getSelectedItem().toString())); + fontAddChars((FontTag) item, selChars, ((FontFace)fontFaceSelection.getSelectedItem()).font); fontAddCharactersField.setText(""); mainPanel.reload(true); } @@ -530,14 +519,14 @@ public class FontPanel extends javax.swing.JPanel { TreeItem item = mainPanel.tagTree.getCurrentTreeItem(); if (item instanceof FontTag) { FontTag ft = (FontTag) item; - FontEmbedDialog fed = new FontEmbedDialog(fontFamilyNameSelection.getSelectedItem().toString(), fontFaceSelection.getSelectedItem().toString(), fontAddCharactersField.getText()); + FontEmbedDialog fed = new FontEmbedDialog((FontFace)fontFaceSelection.getSelectedItem(), fontAddCharactersField.getText()); if (fed.display()) { Set selChars = fed.getSelectedChars(); if (!selChars.isEmpty()) { Font selFont = fed.getSelectedFont(); updateTextsCheckBox.setSelected(fed.hasUpdateTexts()); - fontFamilyNameSelection.setSelectedItem(selFont.getName()); - fontFaceSelection.setSelectedItem(FontHelper.getFontFace(selFont)); + fontFamilyNameSelection.setSelectedItem(new FontFamily(selFont)); + fontFaceSelection.setSelectedItem(new FontFace(selFont)); fontAddChars(ft, selChars, selFont); fontAddCharactersField.setText(""); mainPanel.reload(true); @@ -559,19 +548,17 @@ public class FontPanel extends javax.swing.JPanel { TreeItem item = mainPanel.tagTree.getCurrentTreeItem(); if (item instanceof FontTag) { FontTag f = (FontTag) item; - SWF swf = f.getSwf(); - String selectedFamily = (String) fontFamilyNameSelection.getSelectedItem(); - String selectedFace = (String) fontFaceSelection.getSelectedItem(); - swf.sourceFontFamiliesMap.put(f.getFontId(), selectedFamily); - swf.sourceFontFacesMap.put(f.getFontId(), selectedFace); - Configuration.addFontPair(swf.getShortFileName(), f.getFontId(), f.getFontName(), selectedFamily, selectedFace); + SWF swf = f.getSwf(); + String selectedName = ((FontFace)fontFaceSelection.getSelectedItem()).font.getFontName(Locale.ENGLISH); + swf.sourceFontNamesMap.put(f.getFontId(), selectedName); + Configuration.addFontPair(swf.getShortFileName(), f.getFontId(), f.getFontName(), selectedName); } } private void fontFamilySelectionItemStateChanged() { savePair(); - fontFaceSelection.setModel(getNameModel((String) fontFamilyNameSelection.getSelectedItem())); + fontFaceSelection.setModel(getFaceModel((FontFamily)fontFamilyNameSelection.getSelectedItem())); } private void fontFaceSelectionItemStateChanged() { @@ -597,10 +584,8 @@ public class FontPanel extends javax.swing.JPanel { setEditable(false); } - private void buttonPreviewFontActionPerformed(java.awt.event.ActionEvent evt) { - String familyName = (String) fontFamilyNameSelection.getSelectedItem(); - String face = (String) fontFaceSelection.getSelectedItem(); - new FontPreviewDialog(null, true, FontTag.installedFonts.get(familyName).get(face)).setVisible(true); + private void buttonPreviewFontActionPerformed(java.awt.event.ActionEvent evt) { + new FontPreviewDialog(null, true, ((FontFace)fontFaceSelection.getSelectedItem()).font).setVisible(true); } private void formComponentResized(java.awt.event.ComponentEvent evt) { @@ -671,17 +656,18 @@ public class FontPanel extends javax.swing.JPanel { private javax.swing.JTextArea fontCharactersTextArea; private javax.swing.JTextArea fontCopyrightTextArea; private javax.swing.JLabel fontDescentLabel; - private javax.swing.JTextArea fontDisplayNameTextArea; + private javax.swing.JTextArea fontNameTextArea; private javax.swing.JButton fontEmbedButton; private javax.swing.JCheckBox fontIsBoldCheckBox; private javax.swing.JCheckBox fontIsItalicCheckBox; private javax.swing.JLabel fontLeadingLabel; - private javax.swing.JLabel fontNameLabel; - private javax.swing.JComboBox fontFamilyNameSelection; - private javax.swing.JComboBox fontFaceSelection; + private javax.swing.JLabel fontNameIntagLabel; + private javax.swing.JComboBox fontFamilyNameSelection; + private javax.swing.JComboBox fontFaceSelection; private javax.swing.JLabel fontSourceLabel; private javax.swing.JPanel fontParamsPanel; private javax.swing.JPanel addCharsPanel; private javax.swing.JScrollPane jScrollPane1; private javax.swing.JCheckBox updateTextsCheckBox; + } diff --git a/src/com/jpexs/decompiler/flash/gui/FontPreviewDialog.form b/src/com/jpexs/decompiler/flash/gui/FontPreviewDialog.form index 1cc69016b..377bd9f46 100644 --- a/src/com/jpexs/decompiler/flash/gui/FontPreviewDialog.form +++ b/src/com/jpexs/decompiler/flash/gui/FontPreviewDialog.form @@ -6,9 +6,6 @@ - - - diff --git a/src/com/jpexs/decompiler/flash/gui/Main.java b/src/com/jpexs/decompiler/flash/gui/Main.java index 01a8cab83..6788d89d2 100644 --- a/src/com/jpexs/decompiler/flash/gui/Main.java +++ b/src/com/jpexs/decompiler/flash/gui/Main.java @@ -878,7 +878,7 @@ public class Main { * @throws IOException */ public static void main(String[] args) throws IOException { - + String pluginPath = Configuration.pluginPath.get(); if (pluginPath != null && !pluginPath.isEmpty()) { try { diff --git a/src/com/jpexs/decompiler/flash/gui/MainPanel.java b/src/com/jpexs/decompiler/flash/gui/MainPanel.java index f47c59393..069fb6993 100644 --- a/src/com/jpexs/decompiler/flash/gui/MainPanel.java +++ b/src/com/jpexs/decompiler/flash/gui/MainPanel.java @@ -1906,13 +1906,12 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec if (textTag.setFormattedText(new MissingCharacterHandler() { @Override public boolean handle(FontTag font, char character) { - String fontName = font.getSwf().sourceFontFamiliesMap.get(font.getFontId()); + String fontName = font.getSwf().sourceFontNamesMap.get(font.getFontId()); if (fontName == null) { fontName = font.getFontName(); - } - fontName = FontTag.findInstalledFontFamily(fontName); - Font f = new Font(fontName, font.getFontStyle(), 18); - if (!f.canDisplay(character)) { + } + Font f = FontTag.installedFontsByName.get(fontName); + if (f == null || !f.canDisplay(character)) { View.showMessageDialog(null, translate("error.font.nocharacter").replace("%char%", "" + character), translate("error"), JOptionPane.ERROR_MESSAGE); return false; } diff --git a/src/com/jpexs/decompiler/flash/gui/locales/FontEmbedDialog_cs.properties b/src/com/jpexs/decompiler/flash/gui/locales/FontEmbedDialog_cs.properties index e37dd1612..872adde20 100644 --- a/src/com/jpexs/decompiler/flash/gui/locales/FontEmbedDialog_cs.properties +++ b/src/com/jpexs/decompiler/flash/gui/locales/FontEmbedDialog_cs.properties @@ -21,6 +21,6 @@ filter.ttf = Soubory p\u00edsma True Type (*.ttf) error.invalidfontfile = Neplatn\u00fd soubor p\u00edsma error.cannotreadfontfile = Nelze na\u010d\u00edst soubor p\u00edsma installed = Nainstalov\u00e1no: -ttffile.noselection = TTF soubor: