mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-11 14:08:56 +00:00
#1561 Font editing - import kerning when adding characters
This commit is contained in:
@@ -163,37 +163,14 @@ public class FontHelper {
|
||||
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) {
|
||||
//NOT AVAILABLE IN java9+
|
||||
/*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
|
||||
}
|
||||
}
|
||||
List<KerningPair> ret = new ArrayList<>();
|
||||
public static List<KerningPair> getFontKerningPairs(File fontFile, int size) {
|
||||
|
||||
List<Character> availableChars = new ArrayList<>();
|
||||
for (char c1 = 0; c1 < Character.MAX_VALUE; c1++) {
|
||||
if (font.canDisplay((int) c1)) {
|
||||
availableChars.add(c1);
|
||||
}
|
||||
KerningLoader k = new KerningLoader();
|
||||
try {
|
||||
return k.loadFromTTF(fontFile, size);
|
||||
} catch (IOException | FontFormatException ex) {
|
||||
// ignore
|
||||
}
|
||||
for (char c1 : availableChars) {
|
||||
ret.addAll(getFontKerningPairsOneChar(availableChars, font, c1));
|
||||
|
||||
}
|
||||
return ret;*/
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
@@ -343,7 +320,7 @@ public class FontHelper {
|
||||
Object[] paths = Files.find(d.toPath(), Integer.MAX_VALUE, new BiPredicate<Path, BasicFileAttributes>() {
|
||||
@Override
|
||||
public boolean test(Path t, BasicFileAttributes u) {
|
||||
return u.isRegularFile() && (t.endsWith(".ttf") || t.endsWith(".TTF"));
|
||||
return u.isRegularFile() && (t.toString().endsWith(".ttf") || t.toString().endsWith(".TTF"));
|
||||
}
|
||||
}).toArray();
|
||||
for (Object o : paths) {
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* 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.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -482,6 +483,33 @@ public class DefineFont2Tag extends FontTag {
|
||||
fontBoundsTable.set(pos, shp.getBounds());
|
||||
fontAdvanceTable.set(pos, (int) getDivider() * Math.round(FontHelper.getFontAdvance(advanceFont, character)));
|
||||
}
|
||||
|
||||
for (int k = 0; k < fontKerningTable.size(); k++) {
|
||||
if (fontKerningTable.get(k).fontKerningCode1 == character
|
||||
|| fontKerningTable.get(k).fontKerningCode2 == character) {
|
||||
fontKerningTable.remove(k);
|
||||
k--;
|
||||
}
|
||||
}
|
||||
List<FontHelper.KerningPair> kerning = getFontKerningPairs(font, (int) (getDivider() * 1024));
|
||||
for (FontHelper.KerningPair pair : kerning) {
|
||||
if (pair.char1 != character && pair.char2 != character) {
|
||||
continue;
|
||||
}
|
||||
int glyph1 = charToGlyph(pair.char1);
|
||||
if (pair.char1 == character) {
|
||||
|
||||
} else if (glyph1 == -1) {
|
||||
continue;
|
||||
}
|
||||
int glyph2 = charToGlyph(pair.char2);
|
||||
if (pair.char2 == character) {
|
||||
|
||||
} else if (glyph2 == -1) {
|
||||
continue;
|
||||
}
|
||||
fontKerningTable.add(new KERNINGRECORD(pair.char1, pair.char2, pair.kerning));
|
||||
}
|
||||
}
|
||||
|
||||
checkWideParameters();
|
||||
@@ -514,6 +542,14 @@ public class DefineFont2Tag extends FontTag {
|
||||
if (fontFlagsHasLayout) {
|
||||
fontBoundsTable.remove(pos);
|
||||
fontAdvanceTable.remove(pos);
|
||||
|
||||
for (int i = 0; i < fontKerningTable.size(); i++) {
|
||||
if (fontKerningTable.get(i).fontKerningCode1 == character
|
||||
|| fontKerningTable.get(i).fontKerningCode2 == character) {
|
||||
fontKerningTable.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shiftGlyphIndices(fontID, pos + 1, false);
|
||||
|
||||
@@ -12,7 +12,8 @@
|
||||
* 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.tags;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
@@ -475,6 +476,33 @@ public class DefineFont3Tag extends FontTag {
|
||||
fontBoundsTable.set(pos, shp.getBounds());
|
||||
fontAdvanceTable.set(pos, (int) getDivider() * Math.round(FontHelper.getFontAdvance(advanceFont, character)));
|
||||
}
|
||||
|
||||
for (int k = 0; k < fontKerningTable.size(); k++) {
|
||||
if (fontKerningTable.get(k).fontKerningCode1 == character
|
||||
|| fontKerningTable.get(k).fontKerningCode2 == character) {
|
||||
fontKerningTable.remove(k);
|
||||
k--;
|
||||
}
|
||||
}
|
||||
List<FontHelper.KerningPair> kerning = getFontKerningPairs(font, (int) (getDivider() * 1024));
|
||||
for (FontHelper.KerningPair pair : kerning) {
|
||||
if (pair.char1 != character && pair.char2 != character) {
|
||||
continue;
|
||||
}
|
||||
int glyph1 = charToGlyph(pair.char1);
|
||||
if (pair.char1 == character) {
|
||||
|
||||
} else if (glyph1 == -1) {
|
||||
continue;
|
||||
}
|
||||
int glyph2 = charToGlyph(pair.char2);
|
||||
if (pair.char2 == character) {
|
||||
|
||||
} else if (glyph2 == -1) {
|
||||
continue;
|
||||
}
|
||||
fontKerningTable.add(new KERNINGRECORD(pair.char1, pair.char2, pair.kerning));
|
||||
}
|
||||
}
|
||||
|
||||
checkWideParameters();
|
||||
@@ -519,6 +547,14 @@ public class DefineFont3Tag extends FontTag {
|
||||
if (fontFlagsHasLayout) {
|
||||
fontBoundsTable.remove(pos);
|
||||
fontAdvanceTable.remove(pos);
|
||||
|
||||
for (int i = 0; i < fontKerningTable.size(); i++) {
|
||||
if (fontKerningTable.get(i).fontKerningCode1 == character
|
||||
|| fontKerningTable.get(i).fontKerningCode2 == character) {
|
||||
fontKerningTable.remove(i);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
shiftGlyphIndices(fontID, pos + 1, false);
|
||||
|
||||
@@ -42,8 +42,10 @@ import java.awt.font.GlyphMetrics;
|
||||
import java.awt.font.GlyphVector;
|
||||
import java.awt.geom.Area;
|
||||
import java.io.File;
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.List;
|
||||
import java.util.Locale;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
@@ -124,14 +126,22 @@ public abstract class FontTag extends DrawableTag implements AloneTag {
|
||||
}
|
||||
|
||||
private static Map<String, Map<String, Font>> installedFontsByFamily;
|
||||
|
||||
private static Map<String, Map<String, File>> installedFontFilesByFamily;
|
||||
|
||||
private static Map<String, Font> installedFontsByName;
|
||||
|
||||
private static Map<Font, File> customFontToFile;
|
||||
|
||||
private static String defaultFontName;
|
||||
|
||||
private static boolean firstLoaded = false;
|
||||
|
||||
private static Map<String, Map<String, Map<Integer, List<FontHelper.KerningPair>>>> installedFontKerningPairsByFamily;
|
||||
|
||||
private static Map<Font, Map<Integer, List<FontHelper.KerningPair>>> customFontKerningPairs;
|
||||
|
||||
|
||||
private static void ensureLoaded() {
|
||||
if (!firstLoaded) {
|
||||
reload();
|
||||
@@ -272,10 +282,52 @@ public abstract class FontTag extends DrawableTag implements AloneTag {
|
||||
return defaultFontName;
|
||||
}
|
||||
|
||||
protected static List<FontHelper.KerningPair> getFontKerningPairs(Font font, int size) {
|
||||
if (customFontToFile.containsKey(font)) {
|
||||
if (!customFontKerningPairs.containsKey(font) || !customFontKerningPairs.get(font).containsKey(size)) {
|
||||
if (!customFontKerningPairs.containsKey(font)) {
|
||||
customFontKerningPairs.put(font, new HashMap<>());
|
||||
}
|
||||
customFontKerningPairs.get(font).put(size, FontHelper.getFontKerningPairs(customFontToFile.get(font), size));
|
||||
}
|
||||
return customFontKerningPairs.get(font).get(size);
|
||||
}
|
||||
if (installedFontKerningPairsByFamily.containsKey(font.getFamily(Locale.ENGLISH))
|
||||
&& installedFontKerningPairsByFamily.get(font.getFamily()).containsKey(font.getFontName(Locale.ENGLISH))
|
||||
&& installedFontKerningPairsByFamily.get(font.getFamily()).get(font.getFontName(Locale.ENGLISH)).containsKey(size)) {
|
||||
return installedFontKerningPairsByFamily.get(font.getFamily()).get(font.getFontName(Locale.ENGLISH)).get(size);
|
||||
}
|
||||
|
||||
if (installedFontFilesByFamily.containsKey(font.getFamily(Locale.ENGLISH)) && installedFontFilesByFamily.get(font.getFamily()).containsKey(font.getFontName(Locale.ENGLISH))) {
|
||||
File file = installedFontFilesByFamily.get(font.getFamily(Locale.ENGLISH)).get(font.getFontName(Locale.ENGLISH));
|
||||
if (!installedFontKerningPairsByFamily.containsKey(font.getFamily(Locale.ENGLISH))) {
|
||||
installedFontKerningPairsByFamily.put(font.getFamily(Locale.ENGLISH), new HashMap<>());
|
||||
}
|
||||
if (!installedFontKerningPairsByFamily.get(font.getFamily(Locale.ENGLISH)).containsKey(font.getFontName(Locale.ENGLISH))) {
|
||||
installedFontKerningPairsByFamily.get(font.getFamily(Locale.ENGLISH)).put(font.getFontName(Locale.ENGLISH), new HashMap<>());
|
||||
}
|
||||
|
||||
installedFontKerningPairsByFamily.get(font.getFamily(Locale.ENGLISH)).get(font.getFontName(Locale.ENGLISH)).put(size, FontHelper.getFontKerningPairs(file, size));
|
||||
}
|
||||
if (installedFontKerningPairsByFamily.containsKey(font.getFamily(Locale.ENGLISH))
|
||||
&& installedFontKerningPairsByFamily.get(font.getFamily()).containsKey(font.getFontName(Locale.ENGLISH))
|
||||
&& installedFontKerningPairsByFamily.get(font.getFamily()).get(font.getFontName(Locale.ENGLISH)).containsKey(size)) {
|
||||
return installedFontKerningPairsByFamily.get(font.getFamily()).get(font.getFontName(Locale.ENGLISH)).get(size);
|
||||
}
|
||||
return new ArrayList<>();
|
||||
}
|
||||
|
||||
public static void addCustomFont(Font font, File file) {
|
||||
customFontToFile.put(font, file);
|
||||
}
|
||||
|
||||
public static void reload() {
|
||||
installedFontKerningPairsByFamily = new HashMap<>();
|
||||
installedFontsByFamily = FontHelper.getInstalledFonts();
|
||||
installedFontFilesByFamily = FontHelper.getInstalledFontFiles();
|
||||
installedFontsByName = new HashMap<>();
|
||||
customFontToFile = new HashMap<>();
|
||||
customFontKerningPairs = new HashMap<>();
|
||||
|
||||
for (String fam : installedFontsByFamily.keySet()) {
|
||||
for (String nam : installedFontsByFamily.get(fam).keySet()) {
|
||||
|
||||
Reference in New Issue
Block a user