#1561 Font editing - import kerning when adding characters

This commit is contained in:
Jindra Petřík
2021-02-28 20:34:02 +01:00
parent b9e60534cf
commit 9fffe11861
7 changed files with 143 additions and 33 deletions

View File

@@ -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) {

View File

@@ -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);

View File

@@ -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);

View File

@@ -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()) {