Font export (TTF)

jar path updated in libsrc projects
This commit is contained in:
Jindra Pet��k
2014-03-18 19:56:59 +01:00
parent 0d642a6614
commit 5d76a98324
136 changed files with 46107 additions and 148 deletions
@@ -54,7 +54,10 @@ import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.ecma.Null;
import com.jpexs.decompiler.flash.exporters.ExportRectangle;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.PathExporter;
import com.jpexs.decompiler.flash.exporters.ShapeExporterBase;
import com.jpexs.decompiler.flash.exporters.modes.BinaryDataExportMode;
import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
import com.jpexs.decompiler.flash.exporters.modes.FramesExportMode;
import com.jpexs.decompiler.flash.exporters.modes.ImageExportMode;
import com.jpexs.decompiler.flash.exporters.modes.MorphshapeExportMode;
@@ -94,6 +97,7 @@ import com.jpexs.decompiler.flash.tags.base.CharacterTag;
import com.jpexs.decompiler.flash.tags.base.Container;
import com.jpexs.decompiler.flash.tags.base.ContainerItem;
import com.jpexs.decompiler.flash.tags.base.DrawableTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.base.PlaceObjectTypeTag;
import com.jpexs.decompiler.flash.tags.base.RemoveTag;
@@ -117,8 +121,11 @@ import com.jpexs.decompiler.flash.treenodes.TagNode;
import com.jpexs.decompiler.flash.treenodes.TreeNode;
import com.jpexs.decompiler.flash.types.CXFORMWITHALPHA;
import com.jpexs.decompiler.flash.types.ColorTransform;
import com.jpexs.decompiler.flash.types.GRADRECORD;
import com.jpexs.decompiler.flash.types.MATRIX;
import com.jpexs.decompiler.flash.types.RECT;
import com.jpexs.decompiler.flash.types.RGB;
import com.jpexs.decompiler.flash.types.SHAPE;
import com.jpexs.decompiler.flash.types.filters.BlendComposite;
import com.jpexs.decompiler.flash.types.filters.FILTER;
import com.jpexs.decompiler.flash.types.sound.SoundFormat;
@@ -135,6 +142,10 @@ import com.jpexs.helpers.Helper;
import com.jpexs.helpers.ProgressListener;
import com.jpexs.helpers.SerializableImage;
import com.jpexs.helpers.utf8.Utf8Helper;
import fontastic.FGlyph;
import fontastic.FPoint;
import fontastic.Fontastic;
import fontastic.PVector;
import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Graphics2D;
@@ -1259,6 +1270,137 @@ public final class SWF implements TreeItem, Timelined {
exportSound(baos, t, mode);
return baos.toByteArray();
}
public void exportFonts(AbortRetryIgnoreHandler handler, String outdir, FontExportMode mode) throws IOException {
exportFonts(handler, outdir, tags, mode);
}
public List<File> exportFonts(AbortRetryIgnoreHandler handler, String outdir, List<Tag> tags, final FontExportMode mode) throws IOException {
List<File> ret = new ArrayList<>();
if (tags.isEmpty()) {
return ret;
}
File foutdir = new File(outdir);
if (!foutdir.exists()) {
if (!foutdir.mkdirs()) {
if (!foutdir.exists()) {
throw new IOException("Cannot create directory " + outdir);
}
}
}
for (Tag t : tags) {
File newfile = null;
if (t instanceof FontTag) {
final FontTag st = (FontTag) t;
final File file = new File(outdir + File.separator + st.getCharacterExportFileName() + ".ttf");
newfile = file;
new RetryTask(new RunnableIOEx() {
@Override
public void run() throws IOException {
exportFont(st, mode, file);
}
}, handler).run();
ret.add(newfile);
}
}
return ret;
}
public void exportFont(final FontTag t, FontExportMode mode, File file) throws IOException {
List<SHAPE> shapes=t.getGlyphShapeTable();
Fontastic f = new Fontastic(t.getFontName(),file);
String cop=t.getCopyright();
f.getEngine().setCopyrightYear(cop==null?"":cop);
f.setAuthor(ApplicationInfo.shortApplicationVerName);
f.setVersion("1.0");
f.setAscender(t.getAscent()/t.getDivider());
f.setDescender(t.getDescent()/t.getDivider());
//f.set
for(int i=0;i<shapes.size();i++){
SHAPE s=shapes.get(i);
final List<FPoint[]> contours=new ArrayList<>();
PathExporter seb=new PathExporter(s,new ColorTransform()){
private double transformX(double x){
return Math.ceil((double)(x/t.getDivider()));
}
private double transformY(double y){
return -Math.ceil((double)(y/t.getDivider()));
}
List<FPoint> path=new ArrayList<>();
private double lastX=0;
private double lastY=0;
@Override
protected void finalizePath() {
FPoint[] points=path.toArray(new FPoint[path.size()]);
if(points.length>0){
contours.add(points);
}
path.clear();
}
@Override
public void moveTo(double x, double y) {
finalizePath();
lastX = x;
lastY = y;
path.add(new FPoint(new PVector(transformX(x),transformY(y))));
}
@Override
public void lineTo(double x, double y) {
lastX = x;
lastY = y;
path.add(new FPoint(new PVector(transformX(x),transformY(y))));
}
@Override
public void curveTo(double controlX, double controlY, double anchorX, double anchorY) {
lastX = anchorX;
lastY = anchorY;
path.add(new FPoint(
new PVector(transformX(anchorX),transformY(anchorY)),
new PVector(transformX(controlX),transformY(controlY))
));
}
};
seb.export();
char c=t.glyphToChar(i);
if(contours.isEmpty()){
continue;
}
if(c=='.'){
continue;
}
final FGlyph g=f.addGlyph(c);
double adv=t.getGlyphAdvance(i);
if(adv!=-1){
g.setAdvanceWidth((int)adv);
}else{
g.setAdvanceWidth(t.getGlyphWidth(i)/t.getDivider()+100);
}
for(FPoint[] cnt:contours){
if(cnt.length==0){
continue;
}
g.addContour(cnt);
}
}
f.buildFont();
}
public void exportSound(OutputStream fos, SoundTag t, SoundExportMode mode) throws IOException {
if (t instanceof SoundTag) {
@@ -27,6 +27,7 @@ import com.jpexs.decompiler.flash.abc.RenameType;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.configuration.ConfigurationItem;
import com.jpexs.decompiler.flash.exporters.modes.BinaryDataExportMode;
import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
import com.jpexs.decompiler.flash.exporters.modes.FramesExportMode;
import com.jpexs.decompiler.flash.exporters.modes.ImageExportMode;
import com.jpexs.decompiler.flash.exporters.modes.MovieExportMode;
@@ -541,7 +542,8 @@ public class CommandLineArgumentParser {
"all",
"frame",
"fla",
"xfl"
"xfl",
"font"
};
String[] deprecatedExportFormats = new String[]{
@@ -665,6 +667,10 @@ public class CommandLineArgumentParser {
System.out.println("Exporting movies...");
exfile.exportMovies(handler, outDir.getAbsolutePath() + (exportFormats.length > 1 ? File.separator + "movies" : ""), enumFromStr(formats.get("movie"), MovieExportMode.class));
break;
case "font":
System.out.println("Exporting fonts...");
exfile.exportFonts(handler, outDir.getAbsolutePath() + (exportFormats.length > 1 ? File.separator + "fonts" : ""), enumFromStr(formats.get("font"), FontExportMode.class));
break;
case "frame":
System.out.println("Exporting frames...");
exfile.exportFrames(handler, outDir.getAbsolutePath() + (exportFormats.length > 1 ? File.separator + "frames" : ""), 0, null, enumFromStr(formats.get("frame"), FramesExportMode.class));
@@ -935,6 +941,9 @@ public class CommandLineArgumentParser {
private static <E extends Enum> E enumFromStr(String str, Class<E> cls) {
E[] vals = cls.getEnumConstants();
if(str == null){
return vals[0];
}
for (E e : vals) {
if (e.toString().toLowerCase().equals(str.toLowerCase())) {
return e;
@@ -41,7 +41,7 @@ public class PathExporter extends ShapeExporterBase {
return exporter.paths;
}
private PathExporter(SHAPE shape, ColorTransform colorTransform) {
protected PathExporter(SHAPE shape, ColorTransform colorTransform) {
super(shape, colorTransform);
}
@@ -0,0 +1,26 @@
/*
* 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.exporters.modes;
/**
*
* @author JPEXS
*/
public enum FontExportMode {
TTF
}
@@ -19,6 +19,7 @@ package com.jpexs.decompiler.flash.gui;
import com.jpexs.decompiler.flash.abc.ScriptPack;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.BinaryDataExportMode;
import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
import com.jpexs.decompiler.flash.exporters.modes.FramesExportMode;
import com.jpexs.decompiler.flash.exporters.modes.ImageExportMode;
import com.jpexs.decompiler.flash.exporters.modes.MovieExportMode;
@@ -28,6 +29,7 @@ import com.jpexs.decompiler.flash.exporters.modes.SoundExportMode;
import com.jpexs.decompiler.flash.exporters.modes.TextExportMode;
import com.jpexs.decompiler.flash.tags.DefineBinaryDataTag;
import com.jpexs.decompiler.flash.tags.DefineVideoStreamTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.tags.base.ImageTag;
import com.jpexs.decompiler.flash.tags.base.ShapeTag;
import com.jpexs.decompiler.flash.tags.base.SoundTag;
@@ -65,7 +67,8 @@ public class ExportDialog extends AppDialog {
"sounds",
"scripts",
"binaryData",
"frames"
"frames",
"fonts"
//,"morphshapes"
};
@@ -78,7 +81,8 @@ public class ExportDialog extends AppDialog {
{SoundTag.class},
{TreeNode.class, ScriptPack.class},
{DefineBinaryDataTag.class},
{FrameNodeItem.class}
{FrameNodeItem.class},
{FontTag.class}
//,{MorphShapeTag.class}
};
@@ -91,7 +95,8 @@ public class ExportDialog extends AppDialog {
SoundExportMode.class,
ScriptExportMode.class,
BinaryDataExportMode.class,
FramesExportMode.class
FramesExportMode.class,
FontExportMode.class
//MorphshapeExportMode.class
};
@@ -121,7 +121,7 @@ public class FontPanel extends javax.swing.JPanel {
continue;
}
}
f.addCharacter(swf.tags, c, fontSelection.getSelectedItem().toString());
f.addCharacter(c, fontSelection.getSelectedItem().toString());
oldchars += c;
}
@@ -30,6 +30,7 @@ import com.jpexs.decompiler.flash.action.Action;
import com.jpexs.decompiler.flash.action.parser.pcode.ASMParser;
import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.modes.BinaryDataExportMode;
import com.jpexs.decompiler.flash.exporters.modes.FontExportMode;
import com.jpexs.decompiler.flash.exporters.modes.FramesExportMode;
import com.jpexs.decompiler.flash.exporters.modes.ImageExportMode;
import com.jpexs.decompiler.flash.exporters.modes.MovieExportMode;
@@ -1467,6 +1468,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
if (nodeType == TreeNodeType.TEXT) {
ret.add((Tag) n.getItem());
}
if (nodeType == TreeNodeType.FONT) {
ret.add((Tag) n.getItem());
}
}
if (d instanceof FrameNode) {
FrameNode fn = (FrameNode) d;
@@ -1500,6 +1504,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
List<TreeNode> as12scripts = new ArrayList<>();
List<Tag> binaryData = new ArrayList<>();
Map<Integer, List<Integer>> frames = new HashMap<>();
List<Tag> fonts = new ArrayList<>();
for (TreeNode d : sel) {
if (d.getItem().getSwf() != swf) {
@@ -1529,6 +1534,9 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
if (nodeType == TreeNodeType.TEXT) {
texts.add((Tag) n.getItem());
}
if (nodeType == TreeNodeType.FONT) {
fonts.add((Tag) n.getItem());
}
}
if (d instanceof FrameNode) {
FrameNode fn = (FrameNode) d;
@@ -1569,6 +1577,8 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
ret.addAll(swf.exportMovies(handler, selFile + File.separator + "movies", movies, export.getValue(MovieExportMode.class)));
ret.addAll(swf.exportSounds(handler, selFile + File.separator + "sounds", sounds, export.getValue(SoundExportMode.class)));
ret.addAll(SWF.exportBinaryData(handler, selFile + File.separator + "binaryData", binaryData, export.getValue(BinaryDataExportMode.class)));
ret.addAll(swf.exportFonts(handler, selFile + File.separator + "fonts", fonts, export.getValue(FontExportMode.class)));
for (Entry<Integer, List<Integer>> entry : frames.entrySet()) {
ret.addAll(swf.exportFrames(handler, selFile + File.separator + "frames", entry.getKey(), entry.getValue(), export.getValue(FramesExportMode.class)));
}
@@ -1976,6 +1986,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
swf.exportMovies(errorHandler, selFile + File.separator + "movies", export.getValue(MovieExportMode.class));
swf.exportSounds(errorHandler, selFile + File.separator + "sounds", export.getValue(SoundExportMode.class));
swf.exportBinaryData(errorHandler, selFile + File.separator + "binaryData", export.getValue(BinaryDataExportMode.class));
swf.exportFonts(errorHandler, selFile + File.separator + "fonts", export.getValue(FontExportMode.class));
swf.exportFrames(errorHandler, selFile + File.separator + "frames", 0, null, export.getValue(FramesExportMode.class));
for (CharacterTag c : swf.characters.values()) {
if (c instanceof DefineSpriteTag) {
@@ -2193,7 +2204,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
try {
if (textTag.setFormattedText(new MissingCharacterHandler() {
@Override
public boolean handle(FontTag font, List<Tag> tags, char character) {
public boolean handle(FontTag font, char character) {
String fontName = font.getSwf().sourceFontsMap.get(font.getFontId());
if (fontName == null) {
fontName = font.getFontName();
@@ -2204,7 +2215,7 @@ public final class MainPanel extends JPanel implements ActionListener, TreeSelec
View.showMessageDialog(null, translate("error.font.nocharacter").replace("%char%", "" + character), translate("error"), JOptionPane.ERROR_MESSAGE);
return false;
}
font.addCharacter(tags, character, fontName);
font.addCharacter(character, fontName);
return true;
}
@@ -55,3 +55,6 @@ frames = Frames
frames.png = PNG
frames.gif = GIF
frames.avi = AVI
fonts = Fonts
fonts.ttf = TTF
@@ -793,11 +793,11 @@ public class DefineEditTextTag extends TextTag {
int advance;
FontTag font = lastStyle.font;
GLYPHENTRY ge = new GLYPHENTRY();
ge.glyphIndex = font.charToGlyph(swf.tags, c);
ge.glyphIndex = font.charToGlyph(c);
if (font.hasLayout()) {
int kerningAdjustment = 0;
if (nextChar != null) {
kerningAdjustment = font.getGlyphKerningAdjustment(swf.tags, ge.glyphIndex, font.charToGlyph(swf.tags, nextChar));
kerningAdjustment = font.getGlyphKerningAdjustment(ge.glyphIndex, font.charToGlyph(nextChar));
kerningAdjustment /= font.getDivider();
}
advance = (int) Math.round(font.getDivider() * Math.round((double) lastStyle.fontHeight * (font.getGlyphAdvance(ge.glyphIndex) + kerningAdjustment) / (font.getDivider() * 1024.0)));
@@ -282,12 +282,12 @@ public class DefineFont2Tag extends FontTag {
}
@Override
public char glyphToChar(List<Tag> tags, int glyphIndex) {
public char glyphToChar(int glyphIndex) {
return (char) (int) codeTable.get(glyphIndex);
}
@Override
public int charToGlyph(List<Tag> tags, char c) {
public int charToGlyph(char c) {
return codeTable.indexOf((Integer) (int) c);
}
@@ -370,7 +370,7 @@ public class DefineFont2Tag extends FontTag {
}
@Override
public void addCharacter(List<Tag> tags, char character, String fontName) {
public void addCharacter(char character, String fontName) {
int fontStyle = getFontStyle();
SHAPE shp = SHAPERECORD.systemFontCharacterToSHAPE(fontName, fontStyle, getDivider() * 1024, character);
@@ -392,7 +392,7 @@ public class DefineFont2Tag extends FontTag {
}
if (!exists) {
FontTag.shiftGlyphIndices(fontId, pos, tags);
shiftGlyphIndices(fontId, pos);
glyphShapeTable.add(pos, shp);
codeTable.add(pos, (int) character);
} else {
@@ -429,9 +429,9 @@ public class DefineFont2Tag extends FontTag {
}
@Override
public int getGlyphKerningAdjustment(List<Tag> tags, int glyphIndex, int nextGlyphIndex) {
char c1 = glyphToChar(tags, glyphIndex);
char c2 = glyphToChar(tags, nextGlyphIndex);
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
char c1 = glyphToChar(glyphIndex);
char c2 = glyphToChar(nextGlyphIndex);
int kerningAdjustment = 0;
for (KERNINGRECORD ker : fontKerningTable) {
if (ker.fontKerningCode1 == c1 && ker.fontKerningCode2 == c2) {
@@ -101,12 +101,12 @@ public class DefineFont3Tag extends FontTag {
}
@Override
public char glyphToChar(List<Tag> tags, int glyphIndex) {
public char glyphToChar(int glyphIndex) {
return (char) (int) codeTable.get(glyphIndex);
}
@Override
public int charToGlyph(List<Tag> tags, char c) {
public int charToGlyph(char c) {
return codeTable.indexOf((Integer) (int) c);
}
@@ -353,15 +353,15 @@ public class DefineFont3Tag extends FontTag {
}
@Override
public void addCharacter(List<Tag> tags, char character, String fontName) {
public void addCharacter(char character, String fontName) {
//Font Align Zones will be removed as adding new character zones is not supported:-(
for (int i = 0; i < tags.size(); i++) {
Tag t = tags.get(i);
for (int i = 0; i < swf.tags.size(); i++) {
Tag t = swf.tags.get(i);
if (t instanceof DefineFontAlignZonesTag) {
DefineFontAlignZonesTag fa = (DefineFontAlignZonesTag) t;
if (fa.fontID == fontId) {
tags.remove(i);
swf.tags.remove(i);
i--;
}
}
@@ -385,7 +385,7 @@ public class DefineFont3Tag extends FontTag {
}
if (!exists) {
FontTag.shiftGlyphIndices(fontId, pos, tags);
shiftGlyphIndices(fontId, pos);
glyphShapeTable.add(pos, shp);
codeTable.add(pos, (int) character);
} else {
@@ -422,12 +422,12 @@ public class DefineFont3Tag extends FontTag {
}
@Override
public int getGlyphKerningAdjustment(List<Tag> tags, int glyphIndex, int nextGlyphIndex) {
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
if (glyphIndex == -1 || nextGlyphIndex == -1) {
return 0;
}
char c1 = glyphToChar(tags, glyphIndex);
char c2 = glyphToChar(tags, nextGlyphIndex);
char c1 = glyphToChar(glyphIndex);
char c2 = glyphToChar(nextGlyphIndex);
int kerningAdjustment = 0;
for (KERNINGRECORD ker : fontKerningTable) {
if (ker.fontKerningCode1 == c1 && ker.fontKerningCode2 == c2) {
@@ -63,9 +63,9 @@ public class DefineFontTag extends FontTag {
return glyphShapeTable.get(glyphIndex).getBounds().getWidth();
}
private void ensureFontInfo(List<Tag> tags) {
private void ensureFontInfo() {
if (fontInfoTag == null) {
for (Tag t : tags) {
for (Tag t : swf.tags) {
if (t instanceof DefineFontInfoTag) {
if (((DefineFontInfoTag) t).fontId == fontId) {
fontInfoTag = (DefineFontInfoTag) t;
@@ -83,8 +83,8 @@ public class DefineFontTag extends FontTag {
}
@Override
public char glyphToChar(List<Tag> tags, int glyphIndex) {
ensureFontInfo(tags);
public char glyphToChar(int glyphIndex) {
ensureFontInfo();
if (fontInfo2Tag != null) {
return (char) (int) fontInfo2Tag.codeTable.get(glyphIndex);
} else if (fontInfoTag != null) {
@@ -95,8 +95,8 @@ public class DefineFontTag extends FontTag {
}
@Override
public int charToGlyph(List<Tag> tags, char c) {
ensureFontInfo(tags);
public int charToGlyph(char c) {
ensureFontInfo();
if (fontInfo2Tag != null) {
return fontInfo2Tag.codeTable.indexOf(c);
} else if (fontInfoTag != null) {
@@ -175,7 +175,7 @@ public class DefineFontTag extends FontTag {
@Override
public String getFontName() {
ensureFontInfo(swf.tags);
ensureFontInfo();
if (fontInfo2Tag != null) {
return fontInfo2Tag.fontName;
}
@@ -267,10 +267,10 @@ public class DefineFontTag extends FontTag {
}
@Override
public void addCharacter(List<Tag> tags, char character, String fontName) {
public void addCharacter(char character, String fontName) {
SHAPE shp = SHAPERECORD.systemFontCharacterToSHAPE(fontName, getFontStyle(), getDivider() * 1024, character);
List<Integer> codeTable = new ArrayList<>();
ensureFontInfo(tags);
ensureFontInfo();
if (fontInfoTag != null) {
codeTable = fontInfoTag.codeTable;
}
@@ -293,7 +293,7 @@ public class DefineFontTag extends FontTag {
pos = codeTable.size();
}
if (!exists) {
FontTag.shiftGlyphIndices(fontId, pos, tags);
shiftGlyphIndices(fontId, pos);
glyphShapeTable.add(pos, shp);
codeTable.add(pos, (int) character);
} else {
@@ -305,7 +305,7 @@ public class DefineFontTag extends FontTag {
@Override
public String getCharacters(List<Tag> tags) {
String ret = "";
ensureFontInfo(tags);
ensureFontInfo();
if (fontInfoTag != null) {
for (int i : fontInfoTag.codeTable) {
ret += (char) i;
@@ -320,7 +320,7 @@ public class DefineFontTag extends FontTag {
}
@Override
public int getGlyphKerningAdjustment(List<Tag> tags, int glyphIndex, int nextGlyphIndex) {
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
return 0;
}
}
@@ -99,7 +99,7 @@ public class DefineText2Tag extends TextTag {
ret += "\r\n";
}
}
ret += rec.getText(swf.tags, fnt);
ret += rec.getText(fnt);
}
return ret;
}
@@ -160,7 +160,7 @@ public class DefineText2Tag extends TextTag {
if (params.length() > 0) {
ret += "[" + params + "\r\n]";
}
ret += Helper.escapeString(rec.getText(swf.tags, fnt)).replace("[", "\\[").replace("]", "\\]");
ret += Helper.escapeString(rec.getText(fnt)).replace("[", "\\[").replace("]", "\\]");
}
return ret;
}
@@ -349,7 +349,6 @@ public class DefineText2Tag extends TextTag {
}
String txt = (String) s.values[0];
tr.glyphEntries = new GLYPHENTRY[txt.length()];
List<Tag> tags = swf.tags;
for (int i = 0; i < txt.length(); i++) {
char c = txt.charAt(i);
Character nextChar = null;
@@ -357,24 +356,24 @@ public class DefineText2Tag extends TextTag {
nextChar = txt.charAt(i + 1);
}
if (!font.containsChar(tags, c)) {
if (!missingCharHandler.handle(font, tags, c)) {
if (!font.containsChar(c)) {
if (!missingCharHandler.handle(font, c)) {
return false;
}
}
if (nextChar != null && !font.containsChar(tags, nextChar)) {
if (!missingCharHandler.handle(font, tags, nextChar)) {
if (nextChar != null && !font.containsChar(nextChar)) {
if (!missingCharHandler.handle(font, nextChar)) {
return false;
}
}
tr.glyphEntries[i] = new GLYPHENTRY();
tr.glyphEntries[i].glyphIndex = font.charToGlyph(tags, c);
tr.glyphEntries[i].glyphIndex = font.charToGlyph(c);
int advance;
if (font.hasLayout()) {
int kerningAdjustment = 0;
if (nextChar != null) {
kerningAdjustment = font.getGlyphKerningAdjustment(tags, tr.glyphEntries[i].glyphIndex, font.charToGlyph(tags, nextChar));
kerningAdjustment = font.getGlyphKerningAdjustment(tr.glyphEntries[i].glyphIndex, font.charToGlyph(nextChar));
}
advance = (int) Math.round(font.getDivider() * Math.round(((double) textHeight * font.getGlyphAdvance(tr.glyphEntries[i].glyphIndex) + kerningAdjustment) / (font.getDivider() * 1024.0)));
} else {
@@ -100,7 +100,7 @@ public class DefineTextTag extends TextTag {
ret += "\r\n";
}
}
ret += rec.getText(swf.tags, fnt);
ret += rec.getText(fnt);
}
return ret;
}
@@ -165,7 +165,7 @@ public class DefineTextTag extends TextTag {
if (fnt == null) {
ret += AppStrings.translate("fontNotFound").replace("%fontId%", Integer.toString(rec.fontId));
} else {
ret += Helper.escapeString(rec.getText(swf.tags, fnt)).replace("[", "\\[").replace("]", "\\]");
ret += Helper.escapeString(rec.getText(fnt)).replace("[", "\\[").replace("]", "\\]");
}
}
return ret;
@@ -355,7 +355,6 @@ public class DefineTextTag extends TextTag {
}
String txt = (String) s.values[0];
tr.glyphEntries = new GLYPHENTRY[txt.length()];
List<Tag> tags = swf.tags;
for (int i = 0; i < txt.length(); i++) {
char c = txt.charAt(i);
Character nextChar = null;
@@ -363,24 +362,24 @@ public class DefineTextTag extends TextTag {
nextChar = txt.charAt(i + 1);
}
if (!font.containsChar(tags, c)) {
if (!missingCharHandler.handle(font, tags, c)) {
if (!font.containsChar(c)) {
if (!missingCharHandler.handle(font, c)) {
return false;
}
}
if (nextChar != null && !font.containsChar(tags, nextChar)) {
if (!missingCharHandler.handle(font, tags, nextChar)) {
if (nextChar != null && !font.containsChar(nextChar)) {
if (!missingCharHandler.handle(font, nextChar)) {
return false;
}
}
tr.glyphEntries[i] = new GLYPHENTRY();
tr.glyphEntries[i].glyphIndex = font.charToGlyph(tags, c);
tr.glyphEntries[i].glyphIndex = font.charToGlyph(c);
int advance;
if (font.hasLayout()) {
int kerningAdjustment = 0;
if (nextChar != null) {
kerningAdjustment = font.getGlyphKerningAdjustment(tags, tr.glyphEntries[i].glyphIndex, font.charToGlyph(tags, nextChar));
kerningAdjustment = font.getGlyphKerningAdjustment(tr.glyphEntries[i].glyphIndex, font.charToGlyph(nextChar));
}
advance = (int) Math.round(font.getDivider() * Math.round(((double) textHeight * font.getGlyphAdvance(tr.glyphEntries[i].glyphIndex) + kerningAdjustment) / (font.getDivider() * 1024.0)));
} else {
@@ -21,6 +21,7 @@ import com.jpexs.decompiler.flash.configuration.Configuration;
import com.jpexs.decompiler.flash.exporters.Matrix;
import com.jpexs.decompiler.flash.exporters.Point;
import com.jpexs.decompiler.flash.helpers.FontHelper;
import com.jpexs.decompiler.flash.tags.DefineFontNameTag;
import com.jpexs.decompiler.flash.tags.DefineText2Tag;
import com.jpexs.decompiler.flash.tags.DefineTextTag;
import com.jpexs.decompiler.flash.tags.Tag;
@@ -61,15 +62,15 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
public abstract List<SHAPE> getGlyphShapeTable();
public abstract void addCharacter(List<Tag> tags, char character, String fontName);
public abstract void addCharacter(char character, String fontName);
public abstract char glyphToChar(List<Tag> tags, int glyphIndex);
public abstract char glyphToChar(int glyphIndex);
public abstract int charToGlyph(List<Tag> tags, char c);
public abstract int charToGlyph(char c);
public abstract double getGlyphAdvance(int glyphIndex);
public abstract int getGlyphKerningAdjustment(List<Tag> tags, int glyphIndex, int nextGlyphIndex);
public abstract int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex);
public abstract int getGlyphWidth(int glyphIndex);
@@ -115,8 +116,8 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
return false;
}
public boolean containsChar(List<Tag> tags, char character) {
return charToGlyph(tags, character) > -1;
public boolean containsChar(char character) {
return charToGlyph(character) > -1;
}
public int getFontStyle() {
@@ -161,9 +162,9 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
return defaultFontName;
}
public static void shiftGlyphIndices(int fontId, int startIndex, List<Tag> tags) {
public void shiftGlyphIndices(int fontId, int startIndex) {
List<TEXTRECORD> textRecords = new ArrayList<>();
for (Tag t : tags) {
for (Tag t : swf.tags) {
if (t instanceof DefineTextTag) {
textRecords.addAll(((DefineTextTag) t).textRecords);
}
@@ -283,4 +284,28 @@ public abstract class FontTag extends CharacterTag implements AloneTag, Drawable
return new RECT(0, (int) (previewSize * SWF.unitDivisor), 0, (int) (previewSize * SWF.unitDivisor));
}
@Override
public String getCharacterExportFileName() {
return super.getCharacterExportFileName()+"_"+getFontName();
}
public DefineFontNameTag getFontNameTag(){
for(Tag t:swf.tags){
if(t instanceof DefineFontNameTag){
DefineFontNameTag dfn=(DefineFontNameTag)t;
if(dfn.fontId==getFontId()){
return dfn;
}
}
}
return null;
}
public String getCopyright(){
DefineFontNameTag dfn=getFontNameTag();
if(dfn==null){
return null;
}
return dfn.fontCopyright;
}
}
@@ -26,7 +26,7 @@ import java.util.List;
*/
public class MissingCharacterHandler {
public boolean handle(FontTag font, List<Tag> tags, char character) {
public boolean handle(FontTag font, char character) {
String fontName = font.getFontName();
if (!FontTag.fontNames.contains(fontName)) {
return false;
@@ -35,7 +35,7 @@ public class MissingCharacterHandler {
if (!f.canDisplay(character)) {
return false;
}
font.addCharacter(tags, character, fontName);
font.addCharacter(character, fontName);
return true;
}
}
@@ -187,11 +187,11 @@ public abstract class TextTag extends CharacterTag implements BoundedTag, Drawab
if (font.hasLayout()) {
int kerningAdjustment = 0;
if (nextEntry != null) {
kerningAdjustment = font.getGlyphKerningAdjustment(tags, entry.glyphIndex, nextEntry.glyphIndex);
kerningAdjustment = font.getGlyphKerningAdjustment(entry.glyphIndex, nextEntry.glyphIndex);
}
defaultAdvance = (int) Math.round(SWF.unitDivisor * textHeight * (font.getGlyphAdvance(entry.glyphIndex) + kerningAdjustment) / (font.getDivider() * 1024.0));
} else {
defaultAdvance = (int) Math.round(SWF.unitDivisor * FontTag.getSystemFontAdvance(aFont, font.glyphToChar(tags, entry.glyphIndex), nextEntry == null ? null : font.glyphToChar(tags, nextEntry.glyphIndex)));
defaultAdvance = (int) Math.round(SWF.unitDivisor * FontTag.getSystemFontAdvance(aFont, font.glyphToChar(entry.glyphIndex), nextEntry == null ? null : font.glyphToChar(nextEntry.glyphIndex)));
}
letterSpacing = adv - defaultAdvance;
x += adv;
@@ -145,7 +145,7 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag {
}
@Override
public void addCharacter(List<Tag> tags, char character, String fontName) {
public void addCharacter(char character, String fontName) {
int fontStyle = getFontStyle();
FontType font = fonts.get(0);
SHAPE shp = SHAPERECORD.systemFontCharacterToSHAPE(fontName, fontStyle, (int) (SWF.unitDivisor * font.nominalSize), character);
@@ -167,7 +167,7 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag {
}
if (!exists) {
FontTag.shiftGlyphIndices(fontId, pos, tags);
shiftGlyphIndices(fontId, pos);
}
Font fnt = new Font(fontName, fontStyle, font.nominalSize);
@@ -185,12 +185,12 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag {
}
@Override
public char glyphToChar(List<Tag> tags, int glyphIndex) {
public char glyphToChar(int glyphIndex) {
return (char) fonts.get(0).glyphInfo.get(glyphIndex).glyphCode;
}
@Override
public int charToGlyph(List<Tag> tags, char c) {
public int charToGlyph(char c) {
FontType ft = fonts.get(0);
for (int i = 0; i < ft.glyphInfo.size(); i++) {
if (ft.glyphInfo.get(i).glyphCode == c) {
@@ -206,9 +206,9 @@ public final class DefineCompactedFont extends FontTag implements DrawableTag {
}
@Override
public int getGlyphKerningAdjustment(List<Tag> tags, int glyphIndex, int nextGlyphIndex) {
int char1 = glyphToChar(tags, glyphIndex);
int char2 = glyphToChar(tags, nextGlyphIndex);
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
int char1 = glyphToChar(glyphIndex);
int char2 = glyphToChar(nextGlyphIndex);
for (KerningPairType kp : fonts.get(0).kerning) {
if (kp.char1 == char1 && kp.char2 == char2) {
return kp.advance;
@@ -62,10 +62,10 @@ public class TEXTRECORD implements Serializable {
@SWFArray(countField = "glyphCount")
public GLYPHENTRY[] glyphEntries;
public String getText(List<Tag> tags, FontTag font) {
public String getText(FontTag font) {
String ret = "";
for (GLYPHENTRY ge : glyphEntries) {
ret += font.glyphToChar(tags, ge.glyphIndex);
ret += font.glyphToChar(ge.glyphIndex);
}
return ret;
}
@@ -345,7 +345,7 @@ public abstract class SHAPERECORD implements Cloneable, NeedsCharacters, Seriali
}
// Taken from org.apache.fop.afp.util
private static double[][] approximateCubic(double[] cubicControlPointCoords) {
public static double[][] approximateCubic(double[] cubicControlPointCoords) {
if (cubicControlPointCoords.length < 8) {
throw new IllegalArgumentException("Must have at least 8 coordinates");
}
@@ -2442,7 +2442,7 @@ public class XFLConverter {
firstRun = false;
if (font != null) {
ret += "<DOMTextRun>";
ret += "<characters>" + xmlString((newline ? "\r" : "") + rec.getText(tags, font)) + "</characters>";
ret += "<characters>" + xmlString((newline ? "\r" : "") + rec.getText(font)) + "</characters>";
ret += "<textAttrs>";
ret += "<DOMTextAttrs aliasText=\"false\" rotation=\"true\" size=\"" + twipToPixel(textHeight) + "\" bitmapSize=\"" + textHeight + "\"";