Fixed Proper error message when there is no room for new characters in the font (DefineFont1)

Fixed Synchronization problems when adding characters to the font vs its display
This commit is contained in:
Jindra Petřík
2023-09-24 09:45:15 +02:00
parent c7f4aaddfb
commit ef9e80cb21
12 changed files with 92 additions and 51 deletions

View File

@@ -244,7 +244,7 @@ public class DefineFont2Tag extends FontTag {
* @throws java.io.IOException
*/
@Override
public void getData(SWFOutputStream sos) throws IOException {
public synchronized void getData(SWFOutputStream sos) throws IOException {
checkWideParameters();
sos.writeUI16(fontID);
sos.writeUB(1, fontFlagsHasLayout ? 1 : 0);
@@ -319,12 +319,12 @@ public class DefineFont2Tag extends FontTag {
}
@Override
public int getGlyphWidth(int glyphIndex) {
public synchronized int getGlyphWidth(int glyphIndex) {
return glyphShapeTable.get(glyphIndex).getBounds(1).getWidth();
}
@Override
public RECT getGlyphBounds(int glyphIndex) {
public synchronized RECT getGlyphBounds(int glyphIndex) {
if (fontFlagsHasLayout) {
return fontBoundsTable.get(glyphIndex);
}
@@ -332,7 +332,7 @@ public class DefineFont2Tag extends FontTag {
}
@Override
public double getGlyphAdvance(int glyphIndex) {
public synchronized double getGlyphAdvance(int glyphIndex) {
if (fontFlagsHasLayout) {
return fontAdvanceTable.get(glyphIndex);
} else {
@@ -341,7 +341,7 @@ public class DefineFont2Tag extends FontTag {
}
@Override
public List<SHAPE> getGlyphShapeTable() {
public synchronized List<SHAPE> getGlyphShapeTable() {
return glyphShapeTable;
}
@@ -356,12 +356,12 @@ public class DefineFont2Tag extends FontTag {
}
@Override
public char glyphToChar(int glyphIndex) {
public synchronized char glyphToChar(int glyphIndex) {
return Utf8Helper.codePointToChar(codeTable.get(glyphIndex), getCodesCharset());
}
@Override
public int charToGlyph(char c) {
public synchronized int charToGlyph(char c) {
return codeTable.indexOf(Utf8Helper.charToCodePoint(c, getCodesCharset()));
}
@@ -444,7 +444,7 @@ public class DefineFont2Tag extends FontTag {
}
@Override
public void addCharacter(char character, Font font) {
public synchronized boolean addCharacter(char character, Font font) {
int fontStyle = getFontStyle();
SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(font, (int) Math.round(getDivider() * 1024), character);
@@ -519,10 +519,11 @@ public class DefineFont2Tag extends FontTag {
checkWideParameters();
setModified(true);
getSwf().clearImageCache();
return true;
}
@Override
public boolean removeCharacter(char character) {
public synchronized boolean removeCharacter(char character) {
int code = (int) character;
int pos = -1;
for (int i = 0; i < codeTable.size(); i++) {
@@ -565,7 +566,7 @@ public class DefineFont2Tag extends FontTag {
}
@Override
public void setAdvanceValues(Font font) {
public synchronized void setAdvanceValues(Font font) {
List<RECT> newFontBoundsTable = new ArrayList<>();
List<Integer> newFontAdvanceTable = new ArrayList<>();
for (int i = 0; i < codeTable.size(); i++) {
@@ -589,12 +590,12 @@ public class DefineFont2Tag extends FontTag {
}
@Override
public int getCharacterCount() {
public synchronized int getCharacterCount() {
return codeTable.size();
}
@Override
public String getCharacters() {
public synchronized String getCharacters() {
StringBuilder ret = new StringBuilder(codeTable.size());
for (int i : codeTable) {
Character c = Utf8Helper.codePointToChar(i, getCodesCharset());
@@ -609,14 +610,14 @@ public class DefineFont2Tag extends FontTag {
}
@Override
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
public synchronized int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
char c1 = glyphToChar(glyphIndex);
char c2 = glyphToChar(nextGlyphIndex);
return getCharKerningAdjustment(c1, c2);
}
@Override
public int getCharKerningAdjustment(char c1, char c2) {
public synchronized int getCharKerningAdjustment(char c1, char c2) {
int kerningAdjustment = 0;
int c1Code = Utf8Helper.charToCodePoint(c1, getCodesCharset());
int c2Code = Utf8Helper.charToCodePoint(c2, getCodesCharset());

View File

@@ -231,7 +231,7 @@ public class DefineFont3Tag extends FontTag {
* @throws java.io.IOException
*/
@Override
public void getData(SWFOutputStream sos) throws IOException {
public synchronized void getData(SWFOutputStream sos) throws IOException {
checkWideParameters();
List<Long> offsetTable = new ArrayList<>();
ByteArrayOutputStream baosGlyphShapes = new ByteArrayOutputStream();
@@ -307,12 +307,12 @@ public class DefineFont3Tag extends FontTag {
}
@Override
public int getGlyphWidth(int glyphIndex) {
public synchronized int getGlyphWidth(int glyphIndex) {
return glyphShapeTable.get(glyphIndex).getBounds(1).getWidth();
}
@Override
public double getGlyphAdvance(int glyphIndex) {
public synchronized double getGlyphAdvance(int glyphIndex) {
if (fontFlagsHasLayout && glyphIndex != -1) {
return fontAdvanceTable.get(glyphIndex);
} else {
@@ -321,17 +321,17 @@ public class DefineFont3Tag extends FontTag {
}
@Override
public char glyphToChar(int glyphIndex) {
public synchronized char glyphToChar(int glyphIndex) {
return Utf8Helper.codePointToChar(codeTable.get(glyphIndex), getCodesCharset());
}
@Override
public int charToGlyph(char c) {
public synchronized int charToGlyph(char c) {
return codeTable.indexOf(Utf8Helper.charToCodePoint(c, getCodesCharset()));
}
@Override
public List<SHAPE> getGlyphShapeTable() {
public synchronized List<SHAPE> getGlyphShapeTable() {
return glyphShapeTable;
}
@@ -424,7 +424,7 @@ public class DefineFont3Tag extends FontTag {
}
@Override
public void addCharacter(char character, Font font) {
public synchronized boolean addCharacter(char character, Font font) {
//Font Align Zones will be removed as adding new character zones is not supported:-(
for (int i = 0; i < swf.getTags().size(); i++) {
@@ -508,10 +508,11 @@ public class DefineFont3Tag extends FontTag {
checkWideParameters();
setModified(true);
getSwf().clearImageCache();
return true;
}
@Override
public boolean removeCharacter(char character) {
public synchronized boolean removeCharacter(char character) {
//Font Align Zones will be removed as removing character zones is not supported:-(
for (int i = 0; i < swf.getTags().size(); i++) {
@@ -566,7 +567,7 @@ public class DefineFont3Tag extends FontTag {
}
@Override
public void setAdvanceValues(Font font) {
public synchronized void setAdvanceValues(Font font) {
List<RECT> newFontBoundsTable = new ArrayList<>();
List<Integer> newFontAdvanceTable = new ArrayList<>();
for (int i = 0; i < codeTable.size(); i++) {
@@ -590,12 +591,12 @@ public class DefineFont3Tag extends FontTag {
}
@Override
public int getCharacterCount() {
public synchronized int getCharacterCount() {
return codeTable.size();
}
@Override
public String getCharacters() {
public synchronized String getCharacters() {
StringBuilder ret = new StringBuilder(codeTable.size());
for (int i : codeTable) {
Character c = Utf8Helper.codePointToChar(i, getCodesCharset());
@@ -610,7 +611,7 @@ public class DefineFont3Tag extends FontTag {
}
@Override
public RECT getGlyphBounds(int glyphIndex) {
public synchronized RECT getGlyphBounds(int glyphIndex) {
if (fontFlagsHasLayout) {
return fontBoundsTable.get(glyphIndex);
}
@@ -618,7 +619,7 @@ public class DefineFont3Tag extends FontTag {
}
@Override
public int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
public synchronized int getGlyphKerningAdjustment(int glyphIndex, int nextGlyphIndex) {
if (glyphIndex == -1 || nextGlyphIndex == -1) {
return 0;
}
@@ -628,7 +629,7 @@ public class DefineFont3Tag extends FontTag {
}
@Override
public int getCharKerningAdjustment(char c1, char c2) {
public synchronized int getCharKerningAdjustment(char c1, char c2) {
int c1Code = Utf8Helper.charToCodePoint(c1, getCodesCharset());
int c2Code = Utf8Helper.charToCodePoint(c2, getCodesCharset());

View File

@@ -19,6 +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.ValueTooLargeException;
import com.jpexs.decompiler.flash.tags.base.CharacterIdTag;
import com.jpexs.decompiler.flash.tags.base.FontInfoTag;
import com.jpexs.decompiler.flash.tags.base.FontTag;
@@ -35,6 +36,8 @@ import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.util.logging.Level;
import java.util.logging.Logger;
/**
*
@@ -107,7 +110,7 @@ public class DefineFontTag extends FontTag {
* @throws java.io.IOException
*/
@Override
public void getData(SWFOutputStream sos) throws IOException {
public synchronized void getData(SWFOutputStream sos) throws IOException {
sos.writeUI16(fontId);
ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
List<Integer> offsetTable = new ArrayList<>();
@@ -133,7 +136,7 @@ public class DefineFontTag extends FontTag {
}
@Override
public int getGlyphWidth(int glyphIndex) {
public synchronized int getGlyphWidth(int glyphIndex) {
return glyphShapeTable.get(glyphIndex).getBounds(1).getWidth();
}
@@ -154,7 +157,7 @@ public class DefineFontTag extends FontTag {
}
@Override
public char glyphToChar(int glyphIndex) {
public synchronized char glyphToChar(int glyphIndex) {
ensureFontInfo();
if (fontInfoTag != null) {
return Utf8Helper.codePointToChar(fontInfoTag.getCodeTable().get(glyphIndex), getCodesCharset());
@@ -174,7 +177,7 @@ public class DefineFontTag extends FontTag {
}
@Override
public List<SHAPE> getGlyphShapeTable() {
public synchronized List<SHAPE> getGlyphShapeTable() {
return glyphShapeTable;
}
@@ -275,9 +278,9 @@ public class DefineFontTag extends FontTag {
}
@Override
public void addCharacter(char character, Font font) {
public synchronized boolean addCharacter(char character, Font font) {
SHAPE shp = SHAPERECORD.fontCharacterToSHAPE(font, (int) Math.round(getDivider() * 1024), character);
ensureFontInfo();
int code = (int) Utf8Helper.charToCodePoint(character, getCodesCharset());
@@ -307,6 +310,31 @@ public class DefineFontTag extends FontTag {
pos = 0;
}
//Check whether offset is not too large
ByteArrayOutputStream baos = new ByteArrayOutputStream();
SWFOutputStream sos2 = new SWFOutputStream(baos, getVersion(), getCharset());
for (int s = 0; s <= glyphShapeTable.size(); s++) {
SHAPE shape;
if (s == glyphShapeTable.size() || pos == s) {
if (pos != s) {
break;
}
shape = shp;
} else {
shape = glyphShapeTable.get(s);
}
int offset = glyphShapeTable.size() * 2 + (int) sos2.getPos();
if (offset > 0xffff) {
return false;
}
try {
sos2.writeSHAPE(shape, 1);
} catch (IOException ex) {
//should not happen
}
}
if (!exists) {
shiftGlyphIndices(fontId, pos, true);
glyphShapeTable.add(pos, shp);
@@ -319,10 +347,11 @@ public class DefineFontTag extends FontTag {
setModified(true);
getSwf().clearImageCache();
return true;
}
@Override
public boolean removeCharacter(char character) {
public synchronized boolean removeCharacter(char character) {
ensureFontInfo();
if (fontInfoTag == null) {
return false;
@@ -362,7 +391,7 @@ public class DefineFontTag extends FontTag {
}
@Override
public int getCharacterCount() {
public synchronized int getCharacterCount() {
ensureFontInfo();
if (fontInfoTag != null) {
List<Integer> codeTable = fontInfoTag.getCodeTable();
@@ -372,7 +401,7 @@ public class DefineFontTag extends FontTag {
}
@Override
public String getCharacters() {
public synchronized String getCharacters() {
ensureFontInfo();
if (fontInfoTag != null) {
List<Integer> codeTable = fontInfoTag.getCodeTable();

View File

@@ -65,7 +65,7 @@ public abstract class FontTag extends DrawableTag implements AloneTag {
public abstract List<SHAPE> getGlyphShapeTable();
public abstract void addCharacter(char character, Font font);
public abstract boolean addCharacter(char character, Font font);
public abstract boolean removeCharacter(char character);
@@ -440,7 +440,7 @@ public abstract class FontTag extends DrawableTag implements AloneTag {
}
@Override
public void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) {
public synchronized void toImage(int frame, int time, int ratio, RenderContext renderContext, SerializableImage image, SerializableImage fullImage, boolean isClip, Matrix transformation, Matrix strokeTransformation, Matrix absoluteTransformation, Matrix fullTransformation, ColorTransform colorTransform, double unzoom, boolean sameImage, ExportRectangle viewRect, boolean scaleStrokes, int drawMode, int blendMode, boolean canUseSmoothing) {
SHAPERECORD.shapeListToImage(1, swf, getGlyphShapeTable(), image, frame, Color.black, colorTransform);
}

View File

@@ -16,6 +16,7 @@
*/
package com.jpexs.decompiler.flash.tags.base;
import com.jpexs.decompiler.flash.ValueTooLargeException;
import java.awt.Font;
import java.util.Map;
@@ -50,7 +51,6 @@ public class MissingCharacterHandler {
if (!f.canDisplay(character)) {
return false;
}
font.addCharacter(character, f);
return true;
return font.addCharacter(character, f);
}
}

View File

@@ -149,7 +149,7 @@ public final class DefineCompactedFont extends FontTag {
}
@Override
public void addCharacter(char character, Font cfont) {
public boolean addCharacter(char character, Font cfont) {
int fontStyle = getFontStyle();
FontType font = fonts.get(0);
@@ -217,6 +217,7 @@ public final class DefineCompactedFont extends FontTag {
setModified(true);
getSwf().clearImageCache();
return true;
}
@Override