#1152 Font info tag modified tag was not set => saved swf was corrupt: fixed

This commit is contained in:
honfika@gmail.com
2016-02-13 08:31:33 +01:00
parent 4d886bc688
commit be5bbb607e
7 changed files with 187 additions and 104 deletions

View File

@@ -50,7 +50,7 @@ public class DefineFont2Tag extends FontTag {
public static final String NAME = "DefineFont2";
@SWFType(BasicType.UI16)
public int fontId;
public int fontID;
public boolean fontFlagsHasLayout;
@@ -106,7 +106,7 @@ public class DefineFont2Tag extends FontTag {
*/
public DefineFont2Tag(SWF swf) {
super(swf, ID, NAME, null);
fontId = swf.getNextCharacterId();
fontID = swf.getNextCharacterId();
languageCode = new LANGCODE();
fontName = "New font";
glyphShapeTable = new ArrayList<>();
@@ -127,7 +127,7 @@ public class DefineFont2Tag extends FontTag {
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
fontId = sis.readUI16("fontId");
fontID = sis.readUI16("fontId");
fontFlagsHasLayout = sis.readUB(1, "fontFlagsHasLayout") == 1;
fontFlagsShiftJIS = sis.readUB(1, "fontFlagsShiftJIS") == 1;
fontFlagsSmallText = sis.readUB(1, "fontFlagsSmallText") == 1;
@@ -246,7 +246,7 @@ public class DefineFont2Tag extends FontTag {
@Override
public void getData(SWFOutputStream sos) throws IOException {
checkWideParameters();
sos.writeUI16(fontId);
sos.writeUI16(fontID);
sos.writeUB(1, fontFlagsHasLayout ? 1 : 0);
sos.writeUB(1, fontFlagsShiftJIS ? 1 : 0);
sos.writeUB(1, fontFlagsSmallText ? 1 : 0);
@@ -348,12 +348,12 @@ public class DefineFont2Tag extends FontTag {
@Override
public int getCharacterId() {
return fontId;
return fontID;
}
@Override
public void setCharacterId(int characterId) {
this.fontId = characterId;
this.fontID = characterId;
}
@Override
@@ -467,7 +467,7 @@ public class DefineFont2Tag extends FontTag {
}
if (!exists) {
shiftGlyphIndices(fontId, pos);
shiftGlyphIndices(fontID, pos);
glyphShapeTable.add(pos, shp);
codeTable.add(pos, (int) character);
} else {

View File

@@ -50,7 +50,7 @@ public class DefineFont3Tag extends FontTag {
public static final String NAME = "DefineFont3";
@SWFType(BasicType.UI16)
public int fontId;
public int fontID;
public boolean fontFlagsHasLayout;
@@ -106,7 +106,7 @@ public class DefineFont3Tag extends FontTag {
*/
public DefineFont3Tag(SWF swf) {
super(swf, ID, NAME, null);
fontId = swf.getNextCharacterId();
fontID = swf.getNextCharacterId();
languageCode = new LANGCODE();
fontName = "New font";
glyphShapeTable = new ArrayList<>();
@@ -120,7 +120,7 @@ public class DefineFont3Tag extends FontTag {
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
fontId = sis.readUI16("fontId");
fontID = sis.readUI16("fontId");
fontFlagsHasLayout = sis.readUB(1, "fontFlagsHasLayout") == 1;
fontFlagsShiftJIS = sis.readUB(1, "fontFlagsShiftJIS") == 1;
fontFlagsSmallText = sis.readUB(1, "fontFlagsSmallText") == 1;
@@ -246,7 +246,7 @@ public class DefineFont3Tag extends FontTag {
}
byte[] baGlyphShapes = baosGlyphShapes.toByteArray();
sos.writeUI16(fontId);
sos.writeUI16(fontID);
sos.writeUB(1, fontFlagsHasLayout ? 1 : 0);
sos.writeUB(1, fontFlagsShiftJIS ? 1 : 0);
sos.writeUB(1, fontFlagsSmallText ? 1 : 0);
@@ -341,12 +341,12 @@ public class DefineFont3Tag extends FontTag {
@Override
public int getCharacterId() {
return fontId;
return fontID;
}
@Override
public void setCharacterId(int characterId) {
this.fontId = characterId;
this.fontID = characterId;
}
@Override
@@ -435,7 +435,7 @@ public class DefineFont3Tag extends FontTag {
Tag t = swf.getTags().get(i);
if (t instanceof DefineFontAlignZonesTag) {
DefineFontAlignZonesTag fa = (DefineFontAlignZonesTag) t;
if (fa.fontID == fontId) {
if (fa.fontID == fontID) {
swf.removeTag(t);
i--;
}
@@ -460,7 +460,7 @@ public class DefineFont3Tag extends FontTag {
}
if (!exists) {
shiftGlyphIndices(fontId, pos);
shiftGlyphIndices(fontID, pos);
glyphShapeTable.add(pos, shp);
codeTable.add(pos, (int) character);
} else {

View File

@@ -19,7 +19,7 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
import com.jpexs.decompiler.flash.tags.base.FontInfoTag;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.LANGCODE;
import com.jpexs.decompiler.flash.types.annotations.Reserved;
@@ -36,15 +36,12 @@ import java.util.List;
* @author JPEXS
*/
@SWFVersion(from = 6)
public class DefineFontInfo2Tag extends Tag implements CharacterIdTag {
public class DefineFontInfo2Tag extends FontInfoTag {
public static final int ID = 62;
public static final String NAME = "DefineFontInfo2";
@SWFType(BasicType.UI16)
public int fontID;
public String fontName;
@Reserved
@@ -143,12 +140,38 @@ public class DefineFontInfo2Tag extends Tag implements CharacterIdTag {
}
@Override
public int getCharacterId() {
return fontID;
public List<Integer> getCodeTable() {
return codeTable;
}
@Override
public void setCharacterId(int characterId) {
this.fontID = characterId;
public void addCharacter(int index, int character) {
codeTable.add(index, character);
setModified(true);
}
@Override
public String getFontName() {
return fontName;
}
@Override
public boolean getFontFlagsBold() {
return fontFlagsBold;
}
@Override
public void setFontFlagsBold(boolean value) {
fontFlagsBold = value;
}
@Override
public boolean getFontFlagsItalic() {
return fontFlagsItalic;
}
@Override
public void setFontFlagsItalic(boolean value) {
fontFlagsItalic = value;
}
}

View File

@@ -19,7 +19,7 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
import com.jpexs.decompiler.flash.tags.base.FontInfoTag;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.Reserved;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
@@ -35,15 +35,12 @@ import java.util.List;
* @author JPEXS
*/
@SWFVersion(from = 1)
public class DefineFontInfoTag extends Tag implements CharacterIdTag {
public class DefineFontInfoTag extends FontInfoTag {
public static final int ID = 13;
public static final String NAME = "DefineFontInfo";
@SWFType(BasicType.UI16)
public int fontId;
public String fontName;
@Reserved
@@ -90,7 +87,7 @@ public class DefineFontInfoTag extends Tag implements CharacterIdTag {
@Override
public final void readData(SWFInputStream sis, ByteArrayRange data, int level, boolean parallel, boolean skipUnusualTags, boolean lazy) throws IOException {
fontId = sis.readUI16("fontId");
fontID = sis.readUI16("fontId");
if (swf.version >= 6) {
fontName = sis.readNetString("fontName", Utf8Helper.charset);
} else {
@@ -121,7 +118,7 @@ public class DefineFontInfoTag extends Tag implements CharacterIdTag {
*/
@Override
public void getData(SWFOutputStream sos) throws IOException {
sos.writeUI16(fontId);
sos.writeUI16(fontID);
if (swf.version >= 6) {
sos.writeNetString(fontName, Utf8Helper.charset);
} else {
@@ -144,12 +141,38 @@ public class DefineFontInfoTag extends Tag implements CharacterIdTag {
}
@Override
public int getCharacterId() {
return fontId;
public List<Integer> getCodeTable() {
return codeTable;
}
@Override
public void setCharacterId(int characterId) {
this.fontId = characterId;
public void addCharacter(int index, int character) {
codeTable.add(index, character);
setModified(true);
}
@Override
public String getFontName() {
return fontName;
}
@Override
public boolean getFontFlagsBold() {
return fontFlagsBold;
}
@Override
public void setFontFlagsBold(boolean value) {
fontFlagsBold = value;
}
@Override
public boolean getFontFlagsItalic() {
return fontFlagsItalic;
}
@Override
public void setFontFlagsItalic(boolean value) {
fontFlagsItalic = value;
}
}

View File

@@ -19,6 +19,8 @@ package com.jpexs.decompiler.flash.tags;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.SWFInputStream;
import com.jpexs.decompiler.flash.SWFOutputStream;
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
import com.jpexs.decompiler.flash.tags.base.FontInfoTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.SHAPE;
@@ -50,10 +52,7 @@ public class DefineFontTag extends FontTag {
public List<SHAPE> glyphShapeTable;
@Internal
private DefineFontInfoTag fontInfoTag = null;
@Internal
private DefineFontInfo2Tag fontInfo2Tag = null;
private FontInfoTag fontInfoTag = null;
/**
* Constructor
@@ -139,17 +138,14 @@ public class DefineFontTag extends FontTag {
private void ensureFontInfo() {
if (fontInfoTag == null) {
for (Tag t : swf.getTags()) {
if (t instanceof DefineFontInfoTag) {
if (((DefineFontInfoTag) t).fontId == fontId) {
fontInfoTag = (DefineFontInfoTag) t;
break;
}
}
if (t instanceof DefineFontInfo2Tag) {
if (((DefineFontInfo2Tag) t).fontID == fontId) {
fontInfo2Tag = (DefineFontInfo2Tag) t;
break;
List<CharacterIdTag> characterIdTags = swf.getCharacterIdTags(fontId);
if (characterIdTags != null) {
for (CharacterIdTag t : characterIdTags) {
if (t instanceof FontInfoTag) {
if (((FontInfoTag) t).fontID == fontId) {
fontInfoTag = (FontInfoTag) t;
break;
}
}
}
}
@@ -159,10 +155,8 @@ public class DefineFontTag extends FontTag {
@Override
public char glyphToChar(int glyphIndex) {
ensureFontInfo();
if (fontInfo2Tag != null) {
return (char) (int) fontInfo2Tag.codeTable.get(glyphIndex);
} else if (fontInfoTag != null) {
return (char) (int) fontInfoTag.codeTable.get(glyphIndex);
if (fontInfoTag != null) {
return (char) (int) fontInfoTag.getCodeTable().get(glyphIndex);
} else {
return '?';
}
@@ -171,10 +165,8 @@ public class DefineFontTag extends FontTag {
@Override
public int charToGlyph(char c) {
ensureFontInfo();
if (fontInfo2Tag != null) {
return fontInfo2Tag.codeTable.indexOf((int) c);
} else if (fontInfoTag != null) {
return fontInfoTag.codeTable.indexOf((int) c);
if (fontInfoTag != null) {
return fontInfoTag.getCodeTable().indexOf((int) c);
}
return -1;
@@ -198,33 +190,24 @@ public class DefineFontTag extends FontTag {
@Override
public String getFontNameIntag() {
ensureFontInfo();
if (fontInfo2Tag != null) {
return fontInfo2Tag.fontName;
}
if (fontInfoTag != null) {
return fontInfoTag.fontName;
return fontInfoTag.getFontName();
}
return null;
}
@Override
public boolean isBold() {
if (fontInfo2Tag != null) {
return fontInfo2Tag.fontFlagsBold;
}
if (fontInfoTag != null) {
return fontInfoTag.fontFlagsBold;
return fontInfoTag.getFontFlagsBold();
}
return false;
}
@Override
public boolean isItalic() {
if (fontInfo2Tag != null) {
return fontInfo2Tag.fontFlagsItalic;
}
if (fontInfoTag != null) {
return fontInfoTag.fontFlagsItalic;
return fontInfoTag.getFontFlagsItalic();
}
return false;
}
@@ -236,12 +219,12 @@ public class DefineFontTag extends FontTag {
@Override
public boolean isBoldEditable() {
return fontInfo2Tag != null || fontInfoTag != null;
return fontInfoTag != null;
}
@Override
public boolean isItalicEditable() {
return fontInfo2Tag != null || fontInfoTag != null;
return fontInfoTag != null;
}
@Override
@@ -250,21 +233,15 @@ public class DefineFontTag extends FontTag {
@Override
public void setBold(boolean value) {
if (fontInfo2Tag != null) {
fontInfo2Tag.fontFlagsBold = value;
}
if (fontInfoTag != null) {
fontInfoTag.fontFlagsBold = value;
fontInfoTag.setFontFlagsBold(value);
}
}
@Override
public void setItalic(boolean value) {
if (fontInfo2Tag != null) {
fontInfo2Tag.fontFlagsItalic = value;
}
if (fontInfoTag != null) {
fontInfoTag.fontFlagsItalic = value;
fontInfoTag.setFontFlagsItalic(value);
}
}
@@ -291,33 +268,36 @@ public class DefineFontTag extends FontTag {
@Override
public void addCharacter(char character, Font font) {
SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(font, (int) Math.round(getDivider() * 1024), character);
List<Integer> codeTable = new ArrayList<>();
ensureFontInfo();
if (fontInfoTag != null) {
codeTable = fontInfoTag.codeTable;
}
if (fontInfo2Tag != null) {
codeTable = fontInfo2Tag.codeTable;
}
int code = (int) character;
int pos = -1;
boolean exists = false;
for (int i = 0; i < codeTable.size(); i++) {
if (codeTable.get(i) >= code) {
if (codeTable.get(i) == code) {
exists = true;
if (fontInfoTag != null) {
List<Integer> codeTable = fontInfoTag.getCodeTable();
for (int i = 0; i < codeTable.size(); i++) {
if (codeTable.get(i) >= code) {
if (codeTable.get(i) == code) {
exists = true;
}
pos = i;
break;
}
pos = i;
break;
}
if (pos == -1) {
pos = codeTable.size();
}
} else {
pos = 0;
}
if (pos == -1) {
pos = codeTable.size();
}
if (!exists) {
shiftGlyphIndices(fontId, pos);
glyphShapeTable.add(pos, shp);
codeTable.add(pos, (int) character);
if (fontInfoTag != null) {
fontInfoTag.addCharacter(pos, (int) character);
}
} else {
glyphShapeTable.set(pos, shp);
}
@@ -335,12 +315,7 @@ public class DefineFontTag extends FontTag {
StringBuilder ret = new StringBuilder();
ensureFontInfo();
if (fontInfoTag != null) {
for (int i : fontInfoTag.codeTable) {
ret.append((char) i);
}
}
if (fontInfo2Tag != null) {
for (int i : fontInfo2Tag.codeTable) {
for (int i : fontInfoTag.getCodeTable()) {
ret.append((char) i);
}
}

View File

@@ -0,0 +1,62 @@
/*
* Copyright (C) 2010-2016 JPEXS, All rights reserved.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3.0 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library.
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.SWF;
import com.jpexs.decompiler.flash.tags.Tag;
import com.jpexs.decompiler.flash.types.BasicType;
import com.jpexs.decompiler.flash.types.annotations.SWFType;
import com.jpexs.helpers.ByteArrayRange;
import java.util.List;
/**
*
* @author JPEXS
*/
public abstract class FontInfoTag extends Tag implements CharacterIdTag {
@SWFType(BasicType.UI16)
public int fontID;
public FontInfoTag(SWF swf, int id, String name, ByteArrayRange data) {
super(swf, id, name, data);
}
public abstract List<Integer> getCodeTable();
public abstract void addCharacter(int index, int character);
@Override
public int getCharacterId() {
return fontID;
}
@Override
public void setCharacterId(int characterId) {
this.fontID = characterId;
}
public abstract String getFontName();
public abstract boolean getFontFlagsBold();
public abstract void setFontFlagsBold(boolean value);
public abstract boolean getFontFlagsItalic();
public abstract void setFontFlagsItalic(boolean value);
}

View File

@@ -371,7 +371,7 @@ public final class DefineCompactedFont extends FontTag {
@Override
public FontTag toClassicFont() {
DefineFont2Tag ret = new DefineFont2Tag(swf);
ret.fontId = getFontId();
ret.fontID = getFontId();
ret.fontFlagsBold = isBold();
ret.fontFlagsItalic = isItalic();
ret.fontFlagsWideOffsets = true;