Issue #389 Selecting font face while characters import

Issue #701 Importing from TTF file
Improved Font panel / Font embed dialog
Reloading installed fonts for other than windows systems
Removed xito Table Layout, using Oracle Table Layout instead
This commit is contained in:
Jindra Petřík
2014-10-25 20:58:32 +02:00
parent 1985ccb594
commit 8fd683d019
25 changed files with 665 additions and 4835 deletions

View File

@@ -271,7 +271,8 @@ public final class SWF implements TreeItem, Timelined {
public Map<Integer, CharacterTag> characters = new HashMap<>();
public List<ABCContainerTag> abcList;
public JPEGTablesTag jtt;
public Map<Integer, String> sourceFontsMap = new HashMap<>();
public Map<Integer, String> sourceFontFamiliesMap = new HashMap<>();
public Map<Integer, String> sourceFontFacesMap = new HashMap<>();
public static final double unitDivisor = 20;
private static final Logger logger = Logger.getLogger(SWF.class.getName());

View File

@@ -452,7 +452,7 @@ public class Configuration {
recentFiles.set(Helper.joinStrings(recentFilesArray, "::"));
}
public static Map<String, String> getFontPairs() {
public static Map<String, String> getFontIdToFamilyMap() {
String fonts = fontPairing.get();
if (fonts == null) {
return new HashMap<>();
@@ -467,19 +467,39 @@ public class Configuration {
}
return result;
}
public static Map<String, String> getFontIdToFaceMap() {
String fonts = fontPairing.get();
if (fonts == null) {
return new HashMap<>();
}
public static void addFontPair(String fileName, int fontId, String fontName, String systemFontName) {
Map<String, String> 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) {
String key = fileName + "_" + fontId + "_" + fontName;
Map<String, String> fontPairs = getFontPairs();
fontPairs.put(key, systemFontName);
fontPairs.put(fontName, systemFontName);
Map<String, String> fontPairs = getFontIdToFamilyMap();
fontPairs.put(key, installedFontFamily);
fontPairs.put(fontName, installedFontFamily);
Map<String,String> facePairs = getFontIdToFaceMap();
facePairs.put(key, installedFontFace);
facePairs.put(fontName, installedFontFace);
StringBuilder sb = new StringBuilder();
int i = 0;
for (Entry<String, String> pair : fontPairs.entrySet()) {
if (i != 0) {
sb.append("::");
}
sb.append(pair.getKey()).append("=").append(pair.getValue());
sb.append(pair.getKey()).append("=").append(pair.getValue()).append("=").append(facePairs.containsKey(pair.getKey())?facePairs.get(pair.getKey()):"");
i++;
}
fontPairing.set(sb.toString());

View File

@@ -12,34 +12,84 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
* License along with this library.
*/
package com.jpexs.decompiler.flash.helpers;
import com.jpexs.decompiler.flash.AppResources;
import java.awt.Font;
import java.awt.GraphicsEnvironment;
import java.lang.reflect.Field;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Locale;
import java.util.Locale;
import java.util.logging.Level;
import java.util.Map;
/**
*
* @author JPEXS
*/
public class FontHelper {
/**
* Gets all available fonts in the system
* @return Map<FamilyName,Map<FontNAme,Font>>
*/
public static Map<String,Map<String,Font>> getInstalledFonts(){
Map<String,Map<String,Font>> ret = new HashMap<>();
Font fonts[] = null;
try {
Class<?> clFmFactory = Class.forName("sun.font.FontManagerFactory");
Object fm = clFmFactory.getDeclaredMethod("getInstance").invoke(null);
Class<?> clFm = Class.forName("sun.font.SunFontManager");
public static String[] getInstalledFontFamilyNames() {
// todo: cannot load newly installed fonts, so this feature is disabled until i find a solution for font loading problem
if (Platform.isWindows()) {
try {
Class<?> clW32Fm = Class.forName("sun.awt.Win32FontManager");
Class<?> clSunFm = Class.forName("sun.font.SunFontManager");
Object fm = clW32Fm.newInstance();
return (String[]) clSunFm.getDeclaredMethod("getInstalledFontFamilyNames", Locale.class).invoke(fm, Locale.getDefault());
} catch (Throwable ex) {
// catch everything to avoid class not found problems, because Win32FontManager is an internal proprietary API
Logger.getLogger(FontHelper.class.getName()).log(Level.SEVERE, null, ex);
//Delete cached installed names
Field inField = clFm.getDeclaredField("installedNames");
inField.setAccessible(true);
inField.set(null, null);
//Delete cached family names
Field allFamField = clFm.getDeclaredField("allFamilies");
allFamField.setAccessible(true);
allFamField.set(fm,null);
//Delete cached fonts
Field allFonField = clFm.getDeclaredField("allFonts");
allFonField.setAccessible(true);
allFonField.set(fm, null);
fonts = (Font[]) clFm.getDeclaredMethod("getAllInstalledFonts").invoke(fm);
} catch (Throwable ex) {
//ignore
}
}
if(fonts == null){
fonts = GraphicsEnvironment.getLocalGraphicsEnvironment().getAllFonts();
}
for(Font f:fonts){
String fam = f.getFamily(Locale.getDefault());
//Do not want Java logical fonts
if(Arrays.asList("Dialog","DialogInput","Monospaced","Serif","SansSerif").contains(fam)){
continue;
}
if(!ret.containsKey(fam)){
ret.put(fam, new HashMap<String, Font>());
}
String face = getFontFace(f);
ret.get(f.getFamily()).put(face, 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();
}
if(face.startsWith(".")){
face = face.substring(1);
}
return face;
}
}

View File

@@ -120,9 +120,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
public abstract int getLeading();
public static String[] fontNamesArray;
public static List<String> fontNames;
public static Map<String,Map<String,Font>> installedFonts;
public static String defaultFontName;
@@ -168,7 +166,7 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
}
public String getSystemFontName() {
Map<String, String> fontPairs = Configuration.getFontPairs();
Map<String, String> fontPairs = Configuration.getFontIdToFamilyMap();
String key = swf.getShortFileName() + "_" + getFontId() + "_" + getFontName();
if (fontPairs.containsKey(key)) {
return fontPairs.get(key);
@@ -224,51 +222,52 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
}
public static void reload() {
fontNamesArray = FontHelper.getInstalledFontFamilyNames();
fontNames = Arrays.asList(fontNamesArray);
if (fontNames.contains("Times New Roman")) {
installedFonts = FontHelper.getInstalledFonts();
if (installedFonts.containsKey("Times New Roman")) {
defaultFontName = "Times New Roman";
} else if (fontNames.contains("Arial")) {
} else if (installedFonts.containsKey("Arial")) {
defaultFontName = "Arial";
} else {
defaultFontName = fontNames.get(0);
defaultFontName = installedFonts.keySet().iterator().next();
}
}
public static String getFontNameWithFallback(String fontName) {
if (fontNames.contains(fontName)) {
if (installedFonts.containsKey(fontName)) {
return fontName;
}
if (fontNames.contains("Times New Roman")) {
if (installedFonts.containsKey("Times New Roman")) {
return "Times New Roman";
}
if (fontNames.contains("Arial")) {
if (installedFonts.containsKey("Arial")) {
return "Arial";
}
//Fallback to DIALOG
return "Dialog";
//First font
return installedFonts.keySet().iterator().next();
}
public static String isFontInstalled(String fontName) {
if (fontNames.contains(fontName)) {
return fontName;
public static String isFontFamilyInstalled(String fontFamily) {
if (installedFonts.containsKey(fontFamily)) {
return fontFamily;
}
if (fontName.contains("_")) {
String beforeUnderscore = fontName.substring(0, fontName.indexOf('_'));
if (fontNames.contains(beforeUnderscore)) {
if (fontFamily.contains("_")) {
String beforeUnderscore = fontFamily.substring(0, fontFamily.indexOf('_'));
if (installedFonts.containsKey(beforeUnderscore)) {
return beforeUnderscore;
}
}
return null;
}
public static String findInstalledFontName(String fontName) {
if (fontNames.contains(fontName)) {
return fontName;
public static String findInstalledFontFamily(String fontFamily) {
if (installedFonts.containsKey(fontFamily)) {
return fontFamily;
}
if (fontName.contains("_")) {
String beforeUnderscore = fontName.substring(0, fontName.indexOf('_'));
if (fontNames.contains(beforeUnderscore)) {
if (fontFamily.contains("_")) {
String beforeUnderscore = fontFamily.substring(0, fontFamily.indexOf('_'));
if (installedFonts.containsKey(beforeUnderscore)) {
return beforeUnderscore;
}
}

View File

@@ -17,6 +17,7 @@
package com.jpexs.decompiler.flash.tags.base;
import java.awt.Font;
import java.util.Map;
/**
*
@@ -26,10 +27,22 @@ public class MissingCharacterHandler {
public boolean handle(FontTag font, char character) {
String fontName = font.getFontName();
if (!FontTag.fontNames.contains(fontName)) {
if (!FontTag.installedFonts.containsKey(fontName)) {
return false;
}
Font f = new Font(fontName, font.getFontStyle(), 18);
Map<String, Font> faces = FontTag.installedFonts.get(fontName);
Font f = null;
for (String face : faces.keySet()) {
Font ff = faces.get(face);
if (ff.isBold() == font.isBold() && ff.isItalic() == font.isItalic()) {
f = ff;
break;
}
}
if (f == null) {
f = faces.get(faces.keySet().iterator().next());
}
if (!f.canDisplay(character)) {
return false;
}

View File

@@ -1954,7 +1954,7 @@ public class XFLConverter {
}
int fontStyle = font.getFontStyle();
String installedFont;
if ((installedFont = FontTag.isFontInstalled(fontName)) != null) {
if ((installedFont = FontTag.isFontFamilyInstalled(fontName)) != null) {
fontName = new Font(installedFont, fontStyle, 10).getPSName();
}
String embedRanges = "";
@@ -2458,7 +2458,7 @@ public class XFLConverter {
fontStyle = font.getFontStyle();
}
String installedFont;
if ((installedFont = FontTag.isFontInstalled(fontName)) != null) {
if ((installedFont = FontTag.isFontFamilyInstalled(fontName)) != null) {
psFontName = new Font(installedFont, fontStyle, 10).getPSName();
} else {
psFontName = fontName;
@@ -2616,7 +2616,7 @@ public class XFLConverter {
size = det.fontHeight;
fontFace = fontName;
String installedFont = null;
if ((installedFont = FontTag.isFontInstalled(fontName)) != null) {
if ((installedFont = FontTag.isFontFamilyInstalled(fontName)) != null) {
fontName = installedFont;
fontFace = new Font(installedFont, (italic ? Font.ITALIC : 0) | (bold ? Font.BOLD : 0) | (!italic && !bold ? Font.PLAIN : 0), size < 0 ? 10 : size).getPSName();
}
@@ -3355,7 +3355,7 @@ public class XFLConverter {
fontName = ft.getFontName();
}
String installedFont;
if ((installedFont = FontTag.isFontInstalled(fontName)) != null) {
if ((installedFont = FontTag.isFontFamilyInstalled(fontName)) != null) {
fontFace = new Font(installedFont, (italic ? Font.ITALIC : 0) | (bold ? Font.BOLD : 0) | (!italic && !bold ? Font.PLAIN : 0), size < 0 ? 10 : size).getPSName();
} else {
fontFace = fontName;