mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-07-17 18:09:33 +00:00
#1075 Lenght of DefineText is more larger than original when DefineText is saved: detect letter spacing
This commit is contained in:
@@ -18,6 +18,7 @@ package com.jpexs.decompiler.flash.tags.base;
|
||||
|
||||
import com.jpexs.decompiler.flash.SWF;
|
||||
import com.jpexs.decompiler.flash.configuration.Configuration;
|
||||
import com.jpexs.decompiler.flash.configuration.SwfSpecificConfiguration;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.Matrix;
|
||||
import com.jpexs.decompiler.flash.exporters.commonshape.SVGExporter;
|
||||
import com.jpexs.decompiler.flash.exporters.shape.CanvasShapeExporter;
|
||||
@@ -181,16 +182,30 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
|
||||
}
|
||||
|
||||
public String getSystemFontName() {
|
||||
Map<String, String> fontPairs = Configuration.getFontToNameMap();
|
||||
String key = swf.getShortFileName() + "_" + getFontId() + "_" + getFontNameIntag();
|
||||
if (fontPairs.containsKey(key)) {
|
||||
return fontPairs.get(key);
|
||||
int fontId = getFontId();
|
||||
String selectedFont = swf.sourceFontNamesMap.get(fontId);
|
||||
if (selectedFont == null) {
|
||||
SwfSpecificConfiguration swfConf = Configuration.getSwfSpecificConfiguration(swf.getShortFileName());
|
||||
String key = fontId + "_" + getFontNameIntag();
|
||||
if (swfConf != null) {
|
||||
selectedFont = swfConf.fontPairingMap.get(key);
|
||||
}
|
||||
}
|
||||
key = getFontNameIntag();
|
||||
if (fontPairs.containsKey(key)) {
|
||||
return fontPairs.get(key);
|
||||
|
||||
if (selectedFont == null) {
|
||||
selectedFont = Configuration.getFontToNameMap().get(getFontNameIntag());
|
||||
}
|
||||
return defaultFontName;
|
||||
|
||||
if (selectedFont != null && FontTag.installedFontsByName.containsKey(selectedFont)) {
|
||||
return selectedFont;
|
||||
}
|
||||
|
||||
// findInstalledFontName always returns an available font name
|
||||
return FontTag.findInstalledFontName(getFontName());
|
||||
}
|
||||
|
||||
public Font getSystemFont() {
|
||||
return FontTag.installedFontsByName.get(getSystemFontName());
|
||||
}
|
||||
|
||||
protected void shiftGlyphIndices(int fontId, int startIndex) {
|
||||
|
||||
@@ -261,6 +261,12 @@ public abstract class StaticTextTag extends TextTag {
|
||||
writer.append("font ").append(rec.fontId).newLine();
|
||||
writer.append("height ").append(rec.textHeight).newLine();
|
||||
}
|
||||
if (fnt != null) {
|
||||
int letterSpacing = detectLetterSpacing(rec, fnt, rec.textHeight);
|
||||
if (letterSpacing != 0) {
|
||||
writer.append("letterspacing ").append(letterSpacing).newLine();
|
||||
}
|
||||
}
|
||||
if (rec.styleFlagsHasColor) {
|
||||
if (getTextNum() == 1) {
|
||||
writer.append("color ").append(rec.textColor.toHexRGB()).newLine();
|
||||
@@ -296,8 +302,8 @@ public abstract class StaticTextTag extends TextTag {
|
||||
RGBA colorA = null;
|
||||
int fontId = -1;
|
||||
int textHeight = -1;
|
||||
int letterSpacing = 0;
|
||||
FontTag font = null;
|
||||
String fontName = null;
|
||||
Integer x = null;
|
||||
Integer y = null;
|
||||
int currentX = 0;
|
||||
@@ -342,7 +348,6 @@ public abstract class StaticTextTag extends TextTag {
|
||||
}
|
||||
|
||||
font = (FontTag) ft;
|
||||
fontName = font.getSystemFontName();
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new TextParseException("Invalid font id - number expected. Found: " + paramValue, lexer.yyline());
|
||||
}
|
||||
@@ -354,6 +359,13 @@ public abstract class StaticTextTag extends TextTag {
|
||||
throw new TextParseException("Invalid font height - number expected. Found: " + paramValue, lexer.yyline());
|
||||
}
|
||||
break;
|
||||
case "letterspacing":
|
||||
try {
|
||||
letterSpacing = Integer.parseInt(paramValue);
|
||||
} catch (NumberFormatException nfe) {
|
||||
throw new TextParseException("Invalid font letter spacing - number expected. Found: " + paramValue, lexer.yyline());
|
||||
}
|
||||
break;
|
||||
case "x":
|
||||
try {
|
||||
x = Integer.parseInt(paramValue);
|
||||
@@ -527,17 +539,7 @@ public abstract class StaticTextTag extends TextTag {
|
||||
GLYPHENTRY ge = new GLYPHENTRY();
|
||||
ge.glyphIndex = font.charToGlyph(c);
|
||||
|
||||
int advance;
|
||||
if (font.hasLayout()) {
|
||||
int kerningAdjustment = 0;
|
||||
if (nextChar != null) {
|
||||
kerningAdjustment = font.getCharKerningAdjustment(c, nextChar);
|
||||
}
|
||||
advance = (int) Math.round(((double) textHeight * (font.getGlyphAdvance(ge.glyphIndex) + kerningAdjustment)) / (font.getDivider() * 1024.0));
|
||||
} else {
|
||||
advance = (int) Math.round(SWF.unitDivisor * FontTag.getSystemFontAdvance(fontName, font.getFontStyle(), (int) (textHeight / SWF.unitDivisor), c, nextChar));
|
||||
}
|
||||
|
||||
int advance = getAdvance(font, ge.glyphIndex, textHeight, c, nextChar) + letterSpacing;
|
||||
ge.glyphAdvance = advance;
|
||||
tr.glyphEntries.add(ge);
|
||||
|
||||
@@ -568,6 +570,42 @@ public abstract class StaticTextTag extends TextTag {
|
||||
return true;
|
||||
}
|
||||
|
||||
private int getAdvance(FontTag font, int glyphIndex, int textHeight, char c, Character nextChar) {
|
||||
int advance;
|
||||
if (font.hasLayout()) {
|
||||
int kerningAdjustment = 0;
|
||||
if (nextChar != null) {
|
||||
kerningAdjustment = font.getCharKerningAdjustment(c, nextChar);
|
||||
}
|
||||
advance = (int) Math.round(((double) textHeight * (font.getGlyphAdvance(glyphIndex) + kerningAdjustment)) / (font.getDivider() * 1024.0));
|
||||
} else {
|
||||
String fontName = font.getSystemFontName();
|
||||
advance = (int) Math.round(SWF.unitDivisor * FontTag.getSystemFontAdvance(fontName, font.getFontStyle(), (int) (textHeight / SWF.unitDivisor), c, nextChar));
|
||||
}
|
||||
|
||||
return advance;
|
||||
}
|
||||
|
||||
private int detectLetterSpacing(TEXTRECORD textRecord, FontTag font, int textHeight) {
|
||||
int totalLetterSpacing = 0;
|
||||
List<GLYPHENTRY> glyphEntries = textRecord.glyphEntries;
|
||||
for (int i = 0; i < glyphEntries.size(); i++) {
|
||||
GLYPHENTRY glyph = glyphEntries.get(i);
|
||||
GLYPHENTRY nextGlyph = null;
|
||||
if (i + 1 < glyphEntries.size()) {
|
||||
nextGlyph = glyphEntries.get(i + 1);
|
||||
}
|
||||
|
||||
char c = font.glyphToChar(glyph.glyphIndex);
|
||||
Character nextChar = nextGlyph == null ? null : font.glyphToChar(nextGlyph.glyphIndex);
|
||||
int advance = getAdvance(font, glyph.glyphIndex, textHeight, c, nextChar);
|
||||
int letterSpacing = glyph.glyphAdvance - advance;
|
||||
totalLetterSpacing += letterSpacing;
|
||||
}
|
||||
|
||||
return (int) Math.round(totalLetterSpacing / glyphEntries.size());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void getNeededCharacters(Set<Integer> needed) {
|
||||
for (TEXTRECORD tr : textRecords) {
|
||||
|
||||
Reference in New Issue
Block a user