mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-19 13:18:24 +00:00
better font name handling
kerning moved to FontHelper
This commit is contained in:
@@ -271,8 +271,7 @@ 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> sourceFontFamiliesMap = new HashMap<>();
|
||||
public Map<Integer, String> sourceFontFacesMap = new HashMap<>();
|
||||
public Map<Integer, String> sourceFontNamesMap = new HashMap<>();
|
||||
public static final double unitDivisor = 20;
|
||||
private static final Logger logger = Logger.getLogger(SWF.class.getName());
|
||||
|
||||
|
||||
@@ -452,7 +452,7 @@ public class Configuration {
|
||||
recentFiles.set(Helper.joinStrings(recentFilesArray, "::"));
|
||||
}
|
||||
|
||||
public static Map<String, String> getFontIdToFamilyMap() {
|
||||
public static Map<String, String> getFontToNameMap() {
|
||||
String fonts = fontPairing.get();
|
||||
if (fonts == null) {
|
||||
return new HashMap<>();
|
||||
@@ -467,39 +467,20 @@ public class Configuration {
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
public static Map<String, String> getFontIdToFaceMap() {
|
||||
String fonts = fontPairing.get();
|
||||
if (fonts == null) {
|
||||
return new HashMap<>();
|
||||
}
|
||||
|
||||
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) {
|
||||
|
||||
public static void addFontPair(String fileName, int fontId, String fontName, String installedName) {
|
||||
String key = fileName + "_" + fontId + "_" + fontName;
|
||||
Map<String, String> fontPairs = getFontIdToFamilyMap();
|
||||
fontPairs.put(key, installedFontFamily);
|
||||
fontPairs.put(fontName, installedFontFamily);
|
||||
Map<String, String> fontPairs = getFontToNameMap();
|
||||
fontPairs.put(key, installedName);
|
||||
fontPairs.put(fontName, installedName);
|
||||
|
||||
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()).append("=").append(facePairs.containsKey(pair.getKey()) ? facePairs.get(pair.getKey()) : "");
|
||||
sb.append(pair.getKey()).append("=").append(pair.getValue());
|
||||
i++;
|
||||
}
|
||||
fontPairing.set(sb.toString());
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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, Font>());
|
||||
}
|
||||
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<AttributedCharacterIterator.Attribute, Object> 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<AttributedCharacterIterator.Attribute, Object> 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<KerningPair> 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<KerningPair> ret = new ArrayList<>();
|
||||
|
||||
List<Character> 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<KerningPair> getFontKerningPairsOneChar(List<Character> availableChars, Font font, char firstChar) {
|
||||
List<KerningPair> 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<AttributedCharacterIterator.Attribute, Object> 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<AttributedCharacterIterator.Attribute, Object> 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<Integer, Character> getFontGlyphToCharMap(Font f) {
|
||||
Map<Integer, Character> 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<Integer, Character> charmap;
|
||||
|
||||
public List<KerningPair> loadFromTTF(File file, int size) throws IOException, FontFormatException {
|
||||
font = Font.createFont(Font.TRUETYPE_FONT, file);
|
||||
charmap = getFontGlyphToCharMap(font);
|
||||
InputStream input = new FileInputStream(file);
|
||||
List<KerningPair> 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<KerningPair> 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;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -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));
|
||||
|
||||
@@ -173,7 +173,7 @@ public class DefineFontTag extends FontTag {
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getFontName() {
|
||||
public String getFontNameIntag() {
|
||||
ensureFontInfo();
|
||||
if (fontInfo2Tag != null) {
|
||||
return fontInfo2Tag.fontName;
|
||||
|
||||
@@ -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<String, Map<String, Font>> installedFonts;
|
||||
public static Map<String, Map<String, Font>> installedFontsByFamily;
|
||||
public static Map<String,Font> 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<String, String> fontPairs = Configuration.getFontIdToFamilyMap();
|
||||
String key = swf.getShortFileName() + "_" + getFontId() + "_" + getFontName();
|
||||
Map<String, String> 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() {
|
||||
|
||||
@@ -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<String, Font> faces = FontTag.installedFonts.get(fontName);
|
||||
Map<String, Font> faces = FontTag.installedFontsByFamily.get(fontName);
|
||||
|
||||
Font f = null;
|
||||
for (String face : faces.keySet()) {
|
||||
|
||||
@@ -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();
|
||||
|
||||
@@ -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<ft.kerning.size();i++){
|
||||
|
||||
@@ -12,18 +12,14 @@
|
||||
* 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.types;
|
||||
|
||||
import com.jpexs.decompiler.flash.helpers.FontHelper;
|
||||
import com.jpexs.decompiler.flash.types.annotations.SWFType;
|
||||
import java.awt.Font;
|
||||
import java.awt.Font;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.io.Serializable;
|
||||
import java.io.Serializable;
|
||||
import java.text.AttributedCharacterIterator;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
/**
|
||||
* Represents 24-bit red, green, blue value
|
||||
@@ -58,48 +54,10 @@ public class KERNINGRECORD implements Serializable {
|
||||
public KERNINGRECORD(Font font, char char1, char char2) {
|
||||
fontKerningCode1 = char1;
|
||||
fontKerningCode2 = char2;
|
||||
fontKerningCode2 = char2;
|
||||
fontKerningAdjustment = FontHelper.getFontCharsKerning(font, char1, char2);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
public KERNINGRECORD(String fontName, int fontStyle, int fontSize, char char1, char char2) {
|
||||
fontKerningCode1 = char1;
|
||||
fontKerningCode2 = char2;
|
||||
fontKerningAdjustment = KERNINGRECORD.getSystemFontKerning(fontName, fontSize, fontStyle, char1, char2);
|
||||
}
|
||||
|
||||
public static int getSystemFontKerning(Font font, char char1, char char2) {
|
||||
return getSystemFontKerning(font.getFamily(), font.getSize(), font.getStyle(), char1, char2);
|
||||
}
|
||||
|
||||
public static int getSystemFontKerning(String fontName, int fontSize, int fontStyle, char char1, char char2) {
|
||||
char[] chars = new char[]{char1, char2};
|
||||
Map<AttributedCharacterIterator.Attribute, Object> 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<AttributedCharacterIterator.Attribute, Object> 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;
|
||||
|
||||
}
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -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<String> familyNamesSelection;
|
||||
private final JComboBox<String> faceSelection;
|
||||
private final JComboBox<FontFamily> familyNamesSelection;
|
||||
private final JComboBox<FontFace> 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<String>(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<String>(new TreeSet<String>(FontTag.installedFonts.keySet())));
|
||||
familyNamesSelection.setSelectedItem(selectedFamily);
|
||||
familyNamesSelection = new JComboBox<>(FontPanel.getFamilyModel());
|
||||
familyNamesSelection.setSelectedItem(new FontFamily(selectedFace.font));
|
||||
faceSelection = new JComboBox<>();
|
||||
updateFaceSelection();
|
||||
faceSelection.setSelectedItem(selectedFace);
|
||||
|
||||
73
src/com/jpexs/decompiler/flash/gui/FontFace.java
Normal file
73
src/com/jpexs/decompiler/flash/gui/FontFace.java
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
package com.jpexs.decompiler.flash.gui;
|
||||
|
||||
import java.awt.Font;
|
||||
import java.util.Objects;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author JPEXS
|
||||
*/
|
||||
public class FontFace implements Comparable<FontFace>{
|
||||
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());
|
||||
}
|
||||
|
||||
}
|
||||
72
src/com/jpexs/decompiler/flash/gui/FontFamily.java
Normal file
72
src/com/jpexs/decompiler/flash/gui/FontFamily.java
Normal file
@@ -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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
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<FontFamily>{
|
||||
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);
|
||||
}
|
||||
}
|
||||
@@ -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<String> getFamilyModel() {
|
||||
return new DefaultComboBoxModel<>(new Vector<String>(new TreeSet<String>(FontTag.installedFonts.keySet())));
|
||||
public static ComboBoxModel<FontFamily> getFamilyModel() {
|
||||
Set<FontFamily> famSet=new TreeSet<>();
|
||||
for(Font f:FontTag.installedFontsByName.values()){
|
||||
famSet.add(new FontFamily(f));
|
||||
}
|
||||
return new DefaultComboBoxModel<>(new Vector<FontFamily>(famSet));
|
||||
}
|
||||
|
||||
private ComboBoxModel<String> getNameModel(String family) {
|
||||
return new DefaultComboBoxModel<>(new Vector<String>(FontTag.installedFonts.get(family).keySet()));
|
||||
public static ComboBoxModel<FontFace> getFaceModel(FontFamily family) {
|
||||
|
||||
Set<FontFace> faceSet=new TreeSet<>();
|
||||
for(Font f:FontTag.installedFontsByFamily.get(family.familyEn).values()){
|
||||
faceSet.add(new FontFace(f));
|
||||
}
|
||||
|
||||
return new DefaultComboBoxModel<>(new Vector<FontFace>(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<String, Font> 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<Integer> 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<String> fontFamilyNameSelection;
|
||||
private javax.swing.JComboBox<String> fontFaceSelection;
|
||||
private javax.swing.JLabel fontNameIntagLabel;
|
||||
private javax.swing.JComboBox<FontFamily> fontFamilyNameSelection;
|
||||
private javax.swing.JComboBox<FontFace> 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;
|
||||
|
||||
}
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
<Property name="title" type="java.lang.String" editor="org.netbeans.modules.i18n.form.FormI18nStringEditor">
|
||||
<ResourceString bundle="com/jpexs/decompiler/flash/gui/locales/FontPreviewDialog.properties" key="fontPreview.dialog.title" replaceFormat="java.util.ResourceBundle.getBundle("{bundleNameSlashes}").getString("{key}")"/>
|
||||
</Property>
|
||||
<Property name="iconImage" type="java.awt.Image" editor="org.netbeans.modules.form.ComponentChooserEditor">
|
||||
<ComponentRef name="default"/>
|
||||
</Property>
|
||||
<Property name="preferredSize" type="java.awt.Dimension" editor="org.netbeans.beaninfo.editors.DimensionEditor">
|
||||
<Dimension value="[1024, 512]"/>
|
||||
</Property>
|
||||
|
||||
@@ -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 {
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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: <select>
|
||||
ttffile.noselection = TTF soubor: <vyberte>
|
||||
ttffile.selection = TTF soubor: %fontname% (%filename%)
|
||||
allcharacters = V\u0161echny znaky (%available% znak\u016f)
|
||||
@@ -16,3 +16,12 @@
|
||||
range.description = %name% (%available% z %total% znak\u00f3w)
|
||||
dialog.title = Osadzanie czcionki
|
||||
label.individual = Indywidualne znaki:
|
||||
|
||||
button.loadfont = Wczytaj czcionk\u0119 z dysku...
|
||||
filter.ttf = Pliki True Type Font (*.ttf)
|
||||
error.invalidfontfile = Nieprawid\u0142owy plik czcionki
|
||||
error.cannotreadfontfile = Nie mo\u017cna odczyta\u0107 pliku czcionki
|
||||
installed = Zainstalowane:
|
||||
ttffile.noselection = Plik TTF: <wybierz>
|
||||
ttffile.selection = Plik TTF: %fontname% (%filename%)
|
||||
allcharacters = Wszystkie znaki (%available% znak\u00f3w)
|
||||
|
||||
@@ -513,3 +513,5 @@ button.zoomnone.hint = Zoom to 1:1
|
||||
button.snapshot.hint = Take snapshot into clipboard
|
||||
|
||||
editorTruncateWarning = Text truncated at position %chars% in debug mode.
|
||||
|
||||
font.name.intag = Font name in tag:
|
||||
@@ -501,4 +501,16 @@ menu.file.deobfuscation.old = Star\u00fd zp\u016fsob
|
||||
menu.file.deobfuscation.new = Nov\u00fd zp\u016fsob
|
||||
|
||||
contextmenu.openswfinside = Otev\u0159\u00edt SWF uvnit\u0159
|
||||
binarydata.swfInside = Vypad\u00e1 to, \u017ee uvnit\u0159 v tomto BinaryData tagu se nach\u00e1z\u00ed SWF soubor. Klikn\u011bte zde pro jeho na\u010dten\u00ed jako podstrom.
|
||||
binarydata.swfInside = Vypad\u00e1 to, \u017ee uvnit\u0159 v tomto BinaryData tagu se nach\u00e1z\u00ed SWF soubor. Klikn\u011bte zde pro jeho na\u010dten\u00ed jako podstrom.
|
||||
|
||||
|
||||
#after version 3.0.0
|
||||
button.zoomin.hint = P\u0159ibl\u00ed\u017eit
|
||||
button.zoomout.hint = Odd\u00e1lit
|
||||
button.zoomfit.hint = Rozt\u00e1hnout
|
||||
button.zoomnone.hint = M\u011b\u0159\u00edtko 1:1
|
||||
button.snapshot.hint = Sn\u00edmek do schr\u00e1nky
|
||||
|
||||
editorTruncateWarning = Text je o\u0159\u00edznut na pozici %chars% v lad\u00edc\u00edm m\u00f3du.
|
||||
|
||||
font.name.intag = N\u00e1zev p\u00edsma v tagu:
|
||||
Reference in New Issue
Block a user