mirror of
https://git.huckle.dev/Huckles-Minecraft-Archive/jpexs-decompiler.git
synced 2026-09-27 05:40:46 +00:00
Font export (TTF)
jar path updated in libsrc projects
This commit is contained in:
@@ -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 + "\"";
|
||||
|
||||
Reference in New Issue
Block a user