diff --git a/CHANGELOG.md b/CHANGELOG.md index 72111a88a..55120fde8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,9 @@ All notable changes to this project will be documented in this file. - Chinese translation update - [#2305] Saving recent colors in the color selection dialog - [#2328] Searching/replacing in texts now supports selection / all files scope +- Texts spacing is now separated where possible - does not use `[space xx]`, + but new `spacing "x" NN` and `spacingpair "x" "y" NN` prefix so now + texts are more readable and searchable ### Fixed - [#2319] AS3 Compound assignments problems in some cases diff --git a/lib/jsyntaxpane-0.9.5.jar b/lib/jsyntaxpane-0.9.5.jar index 143874001..b61ea7ccd 100644 Binary files a/lib/jsyntaxpane-0.9.5.jar and b/lib/jsyntaxpane-0.9.5.jar differ diff --git a/libsrc/ffdec_lib/lexers/text.flex b/libsrc/ffdec_lib/lexers/text.flex index d7468e0d1..f3ebcbd6a 100644 --- a/libsrc/ffdec_lib/lexers/text.flex +++ b/libsrc/ffdec_lib/lexers/text.flex @@ -31,11 +31,11 @@ package com.jpexs.decompiler.flash.tags.text; %{ - StringBuilder string = null; boolean finish = false; boolean parameter = false; - String parameterName = null; + StringBuilder string = null; + /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader @@ -54,12 +54,14 @@ package com.jpexs.decompiler.flash.tags.text; %} -Parameter = [a-z0-9_]+ -Value = [^ \r\n\]]+ +Parameter = [a-z_][a-z0-9_]* +Value = [^ \r\n\]\"]+ Divider = [ \r\n]+ HexDigit = [0-9a-fA-F] +StringCharacter = [^\r\n\"\\] -%state PARAMETER,VALUE + +%state PARAMETER,VALUE,STRING %% @@ -96,8 +98,8 @@ HexDigit = [0-9a-fA-F] { {Divider} {} {Parameter} { - parameterName = yytext(); yybegin(VALUE); + return new ParsedSymbol(SymbolType.PARAMETER_IDENTIFIER, yytext()); } "]" { yybegin(YYINITIAL); @@ -107,9 +109,17 @@ HexDigit = [0-9a-fA-F] { {Divider} {} - {Value} { - yybegin(PARAMETER); - return new ParsedSymbol(SymbolType.PARAMETER, new Object[] {parameterName, yytext()}); + + \" { + string = new StringBuilder(); + yybegin(STRING); + } + + {Parameter} { + return new ParsedSymbol(SymbolType.PARAMETER_IDENTIFIER, yytext()); + } + {Value} { + return new ParsedSymbol(SymbolType.PARAMETER_VALUE, yytext()); } "]" { yybegin(YYINITIAL); @@ -117,6 +127,36 @@ HexDigit = [0-9a-fA-F] } } + { + \" { + yybegin(VALUE); + // length also includes the trailing quote + String tos = string.toString(); + string = null; + return new ParsedSymbol(SymbolType.PARAMETER_VALUE, tos); + } + + {StringCharacter}+ { string.append(yytext()); } + + /* escape sequences */ + "\\b" { string.append('\b'); } + "\\t" { string.append('\t'); } + "\\n" { string.append('\n'); } + "\\f" { string.append('\f'); } + "\\r" { string.append('\r'); } + "\\\"" { string.append('\"'); } + "\\'" { string.append('\''); } + "\\\\" { string.append('\\'); } + \\x{HexDigit}{2} { char val = (char) Integer.parseInt(yytext().substring(2), 16); + string.append(val); } + \\u{HexDigit}{4} { char val = (char) Integer.parseInt(yytext().substring(2), 16); + string.append(val); } + + /* escape sequences */ + + \\. { /* ignore illegal character escape */ } +} + /* error fallback */ [^] { if (!parameter) { if (string == null) string = new StringBuilder(); string.append(yytext()); } } <> { return null; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java index 0f98418aa..b1e9548ad 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/DefineEditTextTag.java @@ -42,6 +42,7 @@ import com.jpexs.decompiler.flash.tags.dynamictext.TextStyle; import com.jpexs.decompiler.flash.tags.dynamictext.Word; import com.jpexs.decompiler.flash.tags.enums.TextRenderMode; import com.jpexs.decompiler.flash.tags.text.ParsedSymbol; +import com.jpexs.decompiler.flash.tags.text.SymbolType; import com.jpexs.decompiler.flash.tags.text.TextAlign; import com.jpexs.decompiler.flash.tags.text.TextLexer; import com.jpexs.decompiler.flash.tags.text.TextParseException; @@ -680,9 +681,10 @@ public class DefineEditTextTag extends TextTag { int textIdx = 0; while ((s = lexer.yylex()) != null) { switch (s.type) { - case PARAMETER: - String paramName = (String) s.values[0]; - String paramValue = (String) s.values[1]; + case PARAMETER_IDENTIFIER: + String paramName = (String) s.value; + s = lexer.yylex(); + String paramValue = (String) s.value; switch (paramName) { case "xmin": try { @@ -855,7 +857,7 @@ public class DefineEditTextTag extends TextTag { } break; case TEXT: - String s2 = (String) s.values[0]; + String s2 = (String) s.value; if (s2 == null) { s2 = ""; } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/StaticTextTag.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/StaticTextTag.java index 32965cf8f..5c0d164ca 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/StaticTextTag.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/base/StaticTextTag.java @@ -41,11 +41,15 @@ import com.jpexs.decompiler.flash.types.RGBA; import com.jpexs.decompiler.flash.types.TEXTRECORD; import com.jpexs.decompiler.flash.types.annotations.SWFType; import com.jpexs.helpers.ByteArrayRange; +import com.jpexs.helpers.Helper; import com.jpexs.helpers.SerializableImage; import java.io.IOException; import java.io.StringReader; import java.util.ArrayList; +import java.util.LinkedHashMap; +import java.util.LinkedHashSet; import java.util.List; +import java.util.Map; import java.util.Set; import java.util.regex.Matcher; import java.util.regex.Pattern; @@ -89,8 +93,7 @@ public abstract class StaticTextTag extends TextTag { public List textRecords; /** - * Gets text number. - * DefineText = 1, DefineText2 = 2 + * Gets text number. DefineText = 1, DefineText2 = 2 * * @return Text num */ @@ -98,6 +101,7 @@ public abstract class StaticTextTag extends TextTag { /** * Constructor. + * * @param swf SWF * @param id ID * @param name Name @@ -282,6 +286,7 @@ public abstract class StaticTextTag extends TextTag { } writer.append("]"); int textHeight = 12; + int prevLetterSpacing = 0; for (TEXTRECORD rec : textRecords) { int letterSpacing = 0; if (rec.styleFlagsHasFont || rec.styleFlagsHasColor || rec.styleFlagsHasXOffset || rec.styleFlagsHasYOffset) { @@ -297,9 +302,10 @@ public abstract class StaticTextTag extends TextTag { } if (fnt != null && !ignoreLetterSpacing) { letterSpacing = detectLetterSpacing(rec, fnt, textHeight); - if (letterSpacing != 0) { + if (letterSpacing != prevLetterSpacing) { writer.append("letterspacing ").append(letterSpacing).newLine(); } + prevLetterSpacing = letterSpacing; } if (rec.styleFlagsHasColor) { if (getTextNum() == 1) { @@ -314,12 +320,114 @@ public abstract class StaticTextTag extends TextTag { if (rec.styleFlagsHasYOffset) { writer.append("y ").append(rec.yOffset).newLine(); } - writer.append("]"); } if (fnt == null) { writer.append(AppResources.translate("fontNotFound").replace("%fontId%", Integer.toString(rec.fontId))); } else { + + boolean first = true; + Map spacing = new LinkedHashMap<>(); + Map spacingCount = new LinkedHashMap<>(); + Set ignoredSpacings = new LinkedHashSet<>(); + Map> charToSpacing = new LinkedHashMap<>(); + Set noSpacing = new LinkedHashSet<>(); + Map charCount = new LinkedHashMap<>(); + if (rec.glyphEntries.size() > 1) { + for (int i = 0; i < rec.glyphEntries.size(); i++) { + GLYPHENTRY ge = rec.glyphEntries.get(i); + char c = fnt.glyphToChar(ge.glyphIndex); + Character nextChar = null; + if (i + 1 < rec.glyphEntries.size()) { + GLYPHENTRY nge = rec.glyphEntries.get(i + 1); + nextChar = fnt.glyphToChar(nge.glyphIndex); + } + int advance = getAdvance(fnt, ge.glyphIndex, textHeight, c, nextChar); + int delta = ge.glyphAdvance - advance; + String spacingKey = "" + c + (nextChar == null ? "" : nextChar); + int spacingVal = delta - letterSpacing; + + if (!charToSpacing.containsKey(c)) { + charToSpacing.put(c, new LinkedHashSet<>()); + } + charToSpacing.get(c).add(spacingVal); + + if (!charCount.containsKey(c)) { + charCount.put(c, 0); + } + charCount.put(c, charCount.get(c) + 1); + + + if (delta != letterSpacing && !ignoreLetterSpacing) { + if (ignoredSpacings.contains(spacingKey)) { + continue; + } + if (spacing.containsKey(spacingKey) && spacing.get(spacingKey) != spacingVal) { + spacing.remove(spacingKey); + spacingCount.remove(spacingKey); + ignoredSpacings.add(spacingKey); + continue; + } + spacing.put(spacingKey, spacingVal); + if (!spacingCount.containsKey(spacingKey)) { + spacingCount.put(spacingKey, 0); + } + spacingCount.put(spacingKey, spacingCount.get(spacingKey) + 1); + } else { + noSpacing.add(c); + } + } + } + List spacingKeys = new ArrayList<>(spacing.keySet()); + Map simpleSpacing = new LinkedHashMap<>(); + for (String spacingKey : spacingKeys) { + Character c = spacingKey.charAt(0); + if (charToSpacing.get(c).size() == 1 && charCount.get(c) > 1) { + spacing.remove(spacingKey); + simpleSpacing.put(c, charToSpacing.get(c).iterator().next()); + } + } + + if (!(rec.styleFlagsHasFont || rec.styleFlagsHasColor || rec.styleFlagsHasXOffset || rec.styleFlagsHasYOffset) + && (!simpleSpacing.isEmpty() || !spacing.isEmpty())) { + writer.append("[").newLine().append("resetspacing").newLine(); + } + + if (!simpleSpacing.isEmpty()) { + //writer.append("[").newLine(); + for (Character c : simpleSpacing.keySet()) { + writer.append("spacing \"").append(Helper.escapeString("" + c)).append("\""); + writer.append(" "); + writer.append(simpleSpacing.get(c)); + writer.newLine(); + } + //writer.append("]"); + } + + if (!spacing.isEmpty()) { + //writer.append("[").newLine(); + + for (String spacingKey : spacing.keySet()) { + writer.append("spacingpair \"").append(Helper.escapeString("" + spacingKey.charAt(0))).append("\""); + writer.append(" "); + if (spacingKey.length() > 1) { + writer.append("\"").append(spacingKey.charAt(1)).append("\""); + } else { + writer.append("\"\""); + } + writer.append(" "); + writer.append(spacing.get(spacingKey)); + writer.newLine(); + } + + //writer.append("]"); + } + + if (rec.styleFlagsHasFont || rec.styleFlagsHasColor || rec.styleFlagsHasXOffset || rec.styleFlagsHasYOffset + || !simpleSpacing.isEmpty() || !spacing.isEmpty()) { + writer.append("]"); + } + for (int i = 0; i < rec.glyphEntries.size(); i++) { GLYPHENTRY ge = rec.glyphEntries.get(i); char c = fnt.glyphToChar(ge.glyphIndex); @@ -329,12 +437,17 @@ public abstract class StaticTextTag extends TextTag { if (!ignoreLetterSpacing) { Character nextChar = null; if (i + 1 < rec.glyphEntries.size()) { - nextChar = fnt.glyphToChar(ge.glyphIndex); + GLYPHENTRY nge = rec.glyphEntries.get(i + 1); + nextChar = fnt.glyphToChar(nge.glyphIndex); } - int advance = getAdvance(fnt, ge.glyphIndex, textHeight, c, nextChar); - int delta = ge.glyphAdvance - advance; - if (delta != letterSpacing && !ignoreLetterSpacing) { - writer.append("[space " + (delta - letterSpacing) + "]"); + + String spacingKey = "" + c + (nextChar == null ? "" : nextChar); + if (!spacing.containsKey(spacingKey) && !simpleSpacing.containsKey(c)) { + int advance = getAdvance(fnt, ge.glyphIndex, textHeight, c, nextChar); + int delta = ge.glyphAdvance - advance; + if (delta != letterSpacing && !ignoreLetterSpacing) { + writer.append("[space " + (delta - letterSpacing) + "]"); + } } } } @@ -367,13 +480,37 @@ public abstract class StaticTextTag extends TextTag { textMatrix.hasScale = false; RECT textBounds = new RECT(); int textIdx = 0; + Map simpleSpacing = new LinkedHashMap<>(); + Map pairSpacing = new LinkedHashMap<>(); + boolean append = false; while ((s = lexer.yylex()) != null) { switch (s.type) { - case PARAMETER: - String paramName = (String) s.values[0]; - String paramValue = (String) s.values[1]; + case PARAMETER_IDENTIFIER: + String paramName = (String) s.value; + switch (paramName) { + case "font": + case "height": + case "letterspacing": case "color": + case "x": + case "y": + case "resetspacing": + simpleSpacing.clear(); + pairSpacing.clear(); + } + + if (!paramName.equals("space")) { + append = false; + } + + String paramValue; + switch (paramName) { + case "resetspacing": + break; + case "color": + s = lexer.yylex(); + paramValue = (String) s.value; if (getTextNum() == 1) { Matcher m = Pattern.compile("#([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])").matcher(paramValue); if (m.matches()) { @@ -391,6 +528,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "font": + s = lexer.yylex(); + paramValue = (String) s.value; try { fontId = Integer.parseInt(paramValue); @@ -405,6 +544,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "height": + s = lexer.yylex(); + paramValue = (String) s.value; try { textHeight = Integer.parseInt(paramValue); } catch (NumberFormatException nfe) { @@ -412,6 +553,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "letterspacing": + s = lexer.yylex(); + paramValue = (String) s.value; try { letterSpacing = Integer.parseInt(paramValue); } catch (NumberFormatException nfe) { @@ -419,6 +562,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "x": + s = lexer.yylex(); + paramValue = (String) s.value; try { x = Integer.parseInt(paramValue); currentX = x; @@ -427,6 +572,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "y": + s = lexer.yylex(); + paramValue = (String) s.value; try { y = Integer.parseInt(paramValue); currentY = y; @@ -435,6 +582,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "xmin": + s = lexer.yylex(); + paramValue = (String) s.value; try { textBounds.Xmin = Integer.parseInt(paramValue); } catch (NumberFormatException nfe) { @@ -442,6 +591,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "xmax": + s = lexer.yylex(); + paramValue = (String) s.value; try { textBounds.Xmax = Integer.parseInt(paramValue); } catch (NumberFormatException nfe) { @@ -449,6 +600,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "ymin": + s = lexer.yylex(); + paramValue = (String) s.value; try { textBounds.Ymin = Integer.parseInt(paramValue); } catch (NumberFormatException nfe) { @@ -456,6 +609,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "ymax": + s = lexer.yylex(); + paramValue = (String) s.value; try { textBounds.Ymax = Integer.parseInt(paramValue); } catch (NumberFormatException nfe) { @@ -463,6 +618,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "scalex": + s = lexer.yylex(); + paramValue = (String) s.value; try { textMatrix.scaleX = MATRIX.toFloat(Integer.parseInt(paramValue)); textMatrix.hasScale = true; @@ -471,6 +628,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "scaley": + s = lexer.yylex(); + paramValue = (String) s.value; try { textMatrix.scaleY = MATRIX.toFloat(Integer.parseInt(paramValue)); textMatrix.hasScale = true; @@ -480,6 +639,8 @@ public abstract class StaticTextTag extends TextTag { break; case "scalexf": + s = lexer.yylex(); + paramValue = (String) s.value; try { textMatrix.scaleX = Float.parseFloat(paramValue); textMatrix.hasScale = true; @@ -488,6 +649,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "scaleyf": + s = lexer.yylex(); + paramValue = (String) s.value; try { textMatrix.scaleY = Float.parseFloat(paramValue); textMatrix.hasScale = true; @@ -497,6 +660,8 @@ public abstract class StaticTextTag extends TextTag { break; case "rotateskew0": + s = lexer.yylex(); + paramValue = (String) s.value; try { textMatrix.rotateSkew0 = MATRIX.toFloat(Integer.parseInt(paramValue)); textMatrix.hasRotate = true; @@ -505,6 +670,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "rotateskew1": + s = lexer.yylex(); + paramValue = (String) s.value; try { textMatrix.rotateSkew1 = MATRIX.toFloat(Integer.parseInt(paramValue)); textMatrix.hasRotate = true; @@ -513,6 +680,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "rotateskew0f": + s = lexer.yylex(); + paramValue = (String) s.value; try { textMatrix.rotateSkew0 = Float.parseFloat(paramValue); textMatrix.hasRotate = true; @@ -521,6 +690,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "rotateskew1f": + s = lexer.yylex(); + paramValue = (String) s.value; try { textMatrix.rotateSkew1 = Float.parseFloat(paramValue); textMatrix.hasRotate = true; @@ -529,6 +700,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "translatex": + s = lexer.yylex(); + paramValue = (String) s.value; try { textMatrix.translateX = Integer.parseInt(paramValue); } catch (NumberFormatException nfe) { @@ -536,6 +709,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "translatey": + s = lexer.yylex(); + paramValue = (String) s.value; try { textMatrix.translateY = Integer.parseInt(paramValue); } catch (NumberFormatException nfe) { @@ -543,6 +718,8 @@ public abstract class StaticTextTag extends TextTag { } break; case "space": + s = lexer.yylex(); + paramValue = (String) s.value; try { int space = Integer.parseInt(paramValue); if (textRecords.isEmpty()) { @@ -556,12 +733,45 @@ public abstract class StaticTextTag extends TextTag { throw new TextParseException("Invalid space value - number expected. Found: " + paramValue, lexer.yyline()); } break; + case "spacing": + s = lexer.yylex(); + String spacingChar = (String) s.value; + if (spacingChar.length() != 1) { + throw new TextParseException("Invalid spacing character - single character expected. Found: " + (String) s.value, lexer.yyline()); + } + s = lexer.yylex(); + try { + int space = Integer.parseInt((String) s.value); + simpleSpacing.put(spacingChar.charAt(0), space); + } catch (NumberFormatException nfe) { + throw new TextParseException("Invalid spacing value - number expected. Found: " + (String) s.value, lexer.yyline()); + } + break; + case "spacingpair": + s = lexer.yylex(); + String spacingChar1 = (String) s.value; + if (spacingChar1.length() != 1) { + throw new TextParseException("Invalid spacing character1 - single character expected. Found: " + (String) s.value, lexer.yyline()); + } + s = lexer.yylex(); + String spacingChar2 = (String) s.value; + if (spacingChar2.length() > 1) { + throw new TextParseException("Invalid spacing character2 - single character expected. Found: " + (String) s.value, lexer.yyline()); + } + s = lexer.yylex(); + try { + int space = Integer.parseInt((String) s.value); + pairSpacing.put(spacingChar1 + spacingChar2, space); + } catch (NumberFormatException nfe) { + throw new TextParseException("Invalid spacing value - number expected. Found: " + (String) s.value, lexer.yyline()); + } + break; default: throw new TextParseException("Unrecognized parameter name: " + paramName, lexer.yyline()); } break; case TEXT: - String txt = (texts == null || textIdx >= texts.length) ? (String) s.values[0] : texts[textIdx++]; + String txt = (texts == null || textIdx >= texts.length) ? (String) s.value : texts[textIdx++]; if (txt == null || (font == null && txt.isEmpty())) { continue; } @@ -597,36 +807,42 @@ public abstract class StaticTextTag extends TextTag { txt = txtSb.toString(); - TEXTRECORD tr = new TEXTRECORD(); - textRecords.add(tr); - if (fontId > -1) { - tr.fontId = fontId; - tr.textHeight = textHeight; - fontId = -1; - tr.styleFlagsHasFont = true; - } - if (getTextNum() == 1) { - if (color != null) { - tr.textColor = color; - tr.styleFlagsHasColor = true; - color = null; + TEXTRECORD tr; + + if (append) { + tr = textRecords.get(textRecords.size() - 1); + } else { + tr = new TEXTRECORD(); + textRecords.add(tr); + if (fontId > -1) { + tr.fontId = fontId; + tr.textHeight = textHeight; + fontId = -1; + tr.styleFlagsHasFont = true; } - } else if (colorA != null) { - tr.textColorA = colorA; - tr.styleFlagsHasColor = true; - colorA = null; + if (getTextNum() == 1) { + if (color != null) { + tr.textColor = color; + tr.styleFlagsHasColor = true; + color = null; + } + } else if (colorA != null) { + tr.textColorA = colorA; + tr.styleFlagsHasColor = true; + colorA = null; + } + if (x != null) { + tr.xOffset = x; + tr.styleFlagsHasXOffset = true; + x = null; + } + if (y != null) { + tr.yOffset = y; + tr.styleFlagsHasYOffset = true; + y = null; + } + tr.glyphEntries = new ArrayList<>(txt.length()); } - if (x != null) { - tr.xOffset = x; - tr.styleFlagsHasXOffset = true; - x = null; - } - if (y != null) { - tr.yOffset = y; - tr.styleFlagsHasYOffset = true; - y = null; - } - tr.glyphEntries = new ArrayList<>(txt.length()); for (int i = 0; i < txt.length(); i++) { char c = txt.charAt(i); Character nextChar = null; @@ -637,7 +853,16 @@ public abstract class StaticTextTag extends TextTag { GLYPHENTRY ge = new GLYPHENTRY(); ge.glyphIndex = font.charToGlyph(c); - int advance = getAdvance(font, ge.glyphIndex, textHeight, c, nextChar) + letterSpacing; + int advance = getAdvance(font, ge.glyphIndex, textHeight, c, nextChar); + + advance += letterSpacing; + if (simpleSpacing.containsKey(c)) { + advance += simpleSpacing.get(c) - letterSpacing; + } + String pairKey = "" + c + (nextChar == null ? "" : nextChar); + if (pairSpacing.containsKey(pairKey)) { + advance += pairSpacing.get(pairKey) - letterSpacing; + } ge.glyphAdvance = advance; tr.glyphEntries.add(ge); @@ -650,6 +875,7 @@ public abstract class StaticTextTag extends TextTag { if (currentX < minX) { minX = currentX; } + append = true; break; } } @@ -670,6 +896,7 @@ public abstract class StaticTextTag extends TextTag { /** * Gets advance. + * * @param font Font * @param glyphIndex Glyph index * @param textHeight Text height @@ -695,6 +922,7 @@ public abstract class StaticTextTag extends TextTag { /** * Detects letter spacing. + * * @param textRecord Text record * @param font Font * @param textHeight Text height diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/ParsedSymbol.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/ParsedSymbol.java index 9a69754d9..5d554c175 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/ParsedSymbol.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/ParsedSymbol.java @@ -23,32 +23,23 @@ package com.jpexs.decompiler.flash.tags.text; */ public class ParsedSymbol { - public Object[] values; + public Object value; public SymbolType type; public ParsedSymbol(SymbolType type) { this.type = type; - this.values = new Object[0]; + this.value = ""; } - public ParsedSymbol(SymbolType type, Object... values) { + public ParsedSymbol(SymbolType type, Object value) { this.type = type; - this.values = values; + this.value = value; } @Override public String toString() { - String v = ""; - boolean first = true; - for (Object o : values) { - if (!first) { - v += ", "; - } - first = false; - v += o.toString(); - } - return type.toString() + " " + v; + return type.toString() + " " + value.toString(); } public boolean isType(SymbolType... types) { diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/SymbolType.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/SymbolType.java index b0bad6f22..d366ccc34 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/SymbolType.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/SymbolType.java @@ -24,5 +24,6 @@ package com.jpexs.decompiler.flash.tags.text; public enum SymbolType { TEXT, - PARAMETER + PARAMETER_IDENTIFIER, + PARAMETER_VALUE } diff --git a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/TextLexer.java b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/TextLexer.java index 4a2d8602d..b425601fe 100644 --- a/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/TextLexer.java +++ b/libsrc/ffdec_lib/src/com/jpexs/decompiler/flash/tags/text/TextLexer.java @@ -1,320 +1,282 @@ +/* The following code was generated by JFlex 1.6.0 */ + /* - * Copyright (C) 2010-2024 JPEXS, All rights reserved. - * + * 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.text; + + /** - * This class is a scanner generated by - * JFlex 1.6.0 from the specification file - * C:/Dropbox/Programovani/JavaSE/FFDec/libsrc/ffdec_lib/lexers/text.flex + * This class is a scanner generated by + * JFlex 1.6.0 + * from the specification file C:/Dropbox/Programovani/JavaSE/FFDec/libsrc/ffdec_lib/lexers/text.flex */ public final class TextLexer { - /** - * This character denotes the end of file - */ - public static final int YYEOF = -1; + /** This character denotes the end of file */ + public static final int YYEOF = -1; - /** - * initial size of the lookahead buffer - */ - private static final int ZZ_BUFFERSIZE = 16384; + /** initial size of the lookahead buffer */ + private static final int ZZ_BUFFERSIZE = 16384; - /** - * lexical states - */ - public static final int YYINITIAL = 0; + /** lexical states */ + public static final int YYINITIAL = 0; + public static final int PARAMETER = 2; + public static final int VALUE = 4; + public static final int STRING = 6; - public static final int PARAMETER = 2; + /** + * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l + * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l + * at the beginning of a line + * l is of the form l = 2*k, k a non negative integer + */ + private static final int ZZ_LEXSTATE[] = { + 0, 0, 1, 1, 2, 2, 3, 3 + }; - public static final int VALUE = 4; + /** + * Translates characters to character classes + */ + private static final String ZZ_CMAP_PACKED = + "\12\0\1\11\1\22\1\22\1\11\22\0\1\4\1\0\1\10\4\0"+ + "\1\20\10\0\12\2\7\0\6\5\24\0\1\12\1\7\1\3\1\0"+ + "\1\1\1\0\1\6\1\13\3\6\1\16\7\1\1\15\3\1\1\17"+ + "\1\1\1\14\1\23\2\1\1\21\2\1\12\0\1\22\u1fa2\0\1\22"+ + "\1\22\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\udfe6\0"; - /** - * ZZ_LEXSTATE[l] is the state in the DFA for the lexical state l - * ZZ_LEXSTATE[l+1] is the state in the DFA for the lexical state l at the - * beginning of a line l is of the form l = 2*k, k a non negative integer - */ - private static final int ZZ_LEXSTATE[] = { - 0, 0, 1, 1, 2, 2 - }; + /** + * Translates characters to character classes + */ + private static final char [] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); - /** - * Translates characters to character classes - */ - private static final String ZZ_CMAP_PACKED - = "\12\0\1\20\1\21\1\21\1\20\22\0\1\3\1\0\1\15\4\0" - + "\1\16\10\0\12\5\7\0\6\4\24\0\1\6\1\7\1\2\1\0" - + "\1\1\1\0\1\5\1\10\3\5\1\13\7\1\1\12\3\1\1\14" - + "\1\1\1\11\3\1\1\17\2\1\12\0\1\21\u1fa2\0\1\21\1\21" - + "\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\uffff\0\udfe6\0"; + /** + * Translates DFA states to action switch labels. + */ + private static final int [] ZZ_ACTION = zzUnpackAction(); - /** - * Translates characters to character classes - */ - private static final char[] ZZ_CMAP = zzUnpackCMap(ZZ_CMAP_PACKED); + private static final String ZZ_ACTION_PACKED_0 = + "\4\0\2\1\1\2\1\3\1\4\1\5\1\6\1\7"+ + "\1\10\1\11\1\12\1\2\1\13\1\14\1\15\1\16"+ + "\1\17\1\20\1\21\1\22\1\23\1\24\1\25\1\26"+ + "\1\14\1\27\1\30\1\31\1\32\1\33\1\34\1\35"+ + "\1\36\1\37\2\27\2\0\1\40\1\0"; - /** - * Translates DFA states to action switch labels. - */ - private static final int[] ZZ_ACTION = zzUnpackAction(); + private static int [] zzUnpackAction() { + int [] result = new int[44]; + int offset = 0; + offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); + return result; + } - private static final String ZZ_ACTION_PACKED_0 - = "\3\0\1\1\1\2\1\1\1\3\1\4\1\5\1\6" - + "\1\7\1\10\1\11\1\12\1\13\1\14\1\15\1\16" - + "\1\17\1\20\1\21\1\22\1\10\1\0\1\23"; - - private static int[] zzUnpackAction() { - int[] result = new int[25]; - int offset = 0; - offset = zzUnpackAction(ZZ_ACTION_PACKED_0, offset, result); - return result; + private static int zzUnpackAction(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); } + return j; + } - private static int zzUnpackAction(String packed, int offset, int[] result) { - int i = 0; - /* index in packed string */ - int j = offset; - /* index in unpacked array */ + /** + * Translates a state to a row index in the transition table + */ + private static final int [] ZZ_ROWMAP = zzUnpackRowMap(); - int l = packed.length(); - while (i < l) { - int count = packed.charAt(i++); - int value = packed.charAt(i++); - do { - result[j++] = value; - } while (--count > 0); - } - return j; + private static final String ZZ_ROWMAP_PACKED_0 = + "\0\0\0\24\0\50\0\74\0\120\0\144\0\120\0\120"+ + "\0\170\0\120\0\214\0\240\0\264\0\120\0\310\0\334"+ + "\0\120\0\120\0\120\0\120\0\120\0\120\0\120\0\120"+ + "\0\120\0\120\0\120\0\120\0\360\0\120\0\120\0\120"+ + "\0\120\0\120\0\120\0\120\0\120\0\120\0\360\0\u0104"+ + "\0\u0118\0\u012c\0\120\0\360"; + + private static int [] zzUnpackRowMap() { + int [] result = new int[44]; + int offset = 0; + offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackRowMap(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int high = packed.charAt(i++) << 16; + result[j++] = high | packed.charAt(i++); } + return j; + } - /** - * Translates a state to a row index in the transition table - */ - private static final int[] ZZ_ROWMAP = zzUnpackRowMap(); + /** + * The transition table of the DFA + */ + private static final int [] ZZ_TRANS = zzUnpackTrans(); - private static final String ZZ_ROWMAP_PACKED_0 - = "\0\0\0\22\0\44\0\66\0\66\0\110\0\66\0\132" - + "\0\66\0\154\0\176\0\66\0\66\0\66\0\66\0\66" - + "\0\66\0\66\0\66\0\66\0\66\0\66\0\220\0\242" - + "\0\66"; + private static final String ZZ_TRANS_PACKED_0 = + "\7\5\1\6\1\5\1\7\1\10\7\5\1\7\1\5"+ + "\1\7\1\11\1\7\1\12\1\13\1\7\1\11\2\7"+ + "\1\13\1\7\5\11\1\7\1\11\1\7\1\11\1\14"+ + "\1\15\1\14\1\12\1\13\1\14\1\15\1\14\1\16"+ + "\1\13\1\14\5\15\1\14\1\15\1\14\1\15\7\17"+ + "\1\20\1\21\1\7\12\17\24\0\3\22\1\23\3\22"+ + "\1\24\1\25\1\0\1\26\1\27\1\30\1\31\1\32"+ + "\1\33\1\34\1\35\1\0\1\22\1\0\2\11\3\0"+ + "\1\11\4\0\5\11\1\0\1\11\1\0\1\11\4\0"+ + "\1\13\4\0\1\13\12\0\3\14\2\0\3\14\2\0"+ + "\13\14\2\15\2\0\1\14\1\15\1\14\2\0\1\14"+ + "\5\15\1\14\1\15\1\14\1\15\7\17\3\0\12\17"+ + "\7\36\1\37\1\40\1\0\1\36\1\41\1\42\1\43"+ + "\1\44\1\45\1\46\1\47\1\0\1\50\2\0\1\51"+ + "\2\0\2\51\4\0\1\51\2\0\1\51\7\0\1\52"+ + "\2\0\2\52\4\0\1\52\2\0\1\52\7\0\1\53"+ + "\2\0\2\53\4\0\1\53\2\0\1\53\7\0\1\54"+ + "\2\0\2\54\4\0\1\54\2\0\1\54\5\0"; - private static int[] zzUnpackRowMap() { - int[] result = new int[25]; - int offset = 0; - offset = zzUnpackRowMap(ZZ_ROWMAP_PACKED_0, offset, result); - return result; + private static int [] zzUnpackTrans() { + int [] result = new int[320]; + int offset = 0; + offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackTrans(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + value--; + do result[j++] = value; while (--count > 0); } + return j; + } - private static int zzUnpackRowMap(String packed, int offset, int[] result) { - int i = 0; - /* index in packed string */ - int j = offset; - /* index in unpacked array */ + /* error codes */ + private static final int ZZ_UNKNOWN_ERROR = 0; + private static final int ZZ_NO_MATCH = 1; + private static final int ZZ_PUSHBACK_2BIG = 2; - int l = packed.length(); - while (i < l) { - int high = packed.charAt(i++) << 16; - result[j++] = high | packed.charAt(i++); - } - return j; + /* error messages for the codes above */ + private static final String ZZ_ERROR_MSG[] = { + "Unkown internal scanner error", + "Error: could not match input", + "Error: pushback value was too large" + }; + + /** + * ZZ_ATTRIBUTE[aState] contains the attributes of state aState + */ + private static final int [] ZZ_ATTRIBUTE = zzUnpackAttribute(); + + private static final String ZZ_ATTRIBUTE_PACKED_0 = + "\4\0\1\11\1\1\2\11\1\1\1\11\3\1\1\11"+ + "\2\1\14\11\1\1\11\11\2\1\2\0\1\11\1\0"; + + private static int [] zzUnpackAttribute() { + int [] result = new int[44]; + int offset = 0; + offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); + return result; + } + + private static int zzUnpackAttribute(String packed, int offset, int [] result) { + int i = 0; /* index in packed string */ + int j = offset; /* index in unpacked array */ + int l = packed.length(); + while (i < l) { + int count = packed.charAt(i++); + int value = packed.charAt(i++); + do result[j++] = value; while (--count > 0); } + return j; + } - /** - * The transition table of the DFA - */ - private static final int[] ZZ_TRANS = zzUnpackTrans(); + /** the input device */ + private java.io.Reader zzReader; - private static final String ZZ_TRANS_PACKED_0 - = "\6\4\1\5\1\6\10\4\3\7\1\10\1\11\1\12" - + "\1\7\1\10\2\7\5\10\2\7\1\10\1\12\1\7" - + "\2\13\1\11\1\12\14\13\1\12\1\13\22\0\2\14" - + "\1\15\3\14\1\16\1\17\1\20\1\21\1\22\1\23" - + "\1\24\1\25\1\26\1\27\3\0\1\10\3\0\1\10" - + "\2\0\5\10\2\0\1\10\5\0\1\12\14\0\1\12" - + "\1\0\2\13\2\0\14\13\1\0\1\13\4\0\2\30" - + "\2\0\1\30\2\0\1\30\12\0\2\31\2\0\1\31" - + "\2\0\1\31\6\0"; + /** the current state of the DFA */ + private int zzState; - private static int[] zzUnpackTrans() { - int[] result = new int[180]; - int offset = 0; - offset = zzUnpackTrans(ZZ_TRANS_PACKED_0, offset, result); - return result; - } + /** the current lexical state */ + private int zzLexicalState = YYINITIAL; - private static int zzUnpackTrans(String packed, int offset, int[] result) { - int i = 0; - /* index in packed string */ + /** this buffer contains the current text to be matched and is + the source of the yytext() string */ + private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; - int j = offset; - /* index in unpacked array */ + /** the textposition at the last accepting state */ + private int zzMarkedPos; - int l = packed.length(); - while (i < l) { - int count = packed.charAt(i++); - int value = packed.charAt(i++); - value--; - do { - result[j++] = value; - } while (--count > 0); - } - return j; - } + /** the current text position in the buffer */ + private int zzCurrentPos; + /** startRead marks the beginning of the yytext() string in the buffer */ + private int zzStartRead; - /* error codes */ - private static final int ZZ_UNKNOWN_ERROR = 0; + /** endRead marks the last character in the buffer, that has been read + from input */ + private int zzEndRead; - private static final int ZZ_NO_MATCH = 1; + /** number of newlines encountered up to the start of the matched text */ + private int yyline; - private static final int ZZ_PUSHBACK_2BIG = 2; + /** the number of characters up to the start of the matched text */ + private int yychar; - /* error messages for the codes above */ - private static final String ZZ_ERROR_MSG[] = { - "Unkown internal scanner error", - "Error: could not match input", - "Error: pushback value was too large" - }; + /** + * the number of characters from the last newline up to the start of the + * matched text + */ + private int yycolumn; - /** - * ZZ_ATTRIBUTE[aState] contains the attributes of state aState - */ - private static final int[] ZZ_ATTRIBUTE = zzUnpackAttribute(); + /** + * zzAtBOL == true <=> the scanner is currently at the beginning of a line + */ + private boolean zzAtBOL = true; - private static final String ZZ_ATTRIBUTE_PACKED_0 - = "\3\0\2\11\1\1\1\11\1\1\1\11\2\1\13\11" - + "\1\1\1\0\1\11"; + /** zzAtEOF == true <=> the scanner is at the EOF */ + private boolean zzAtEOF; - private static int[] zzUnpackAttribute() { - int[] result = new int[25]; - int offset = 0; - offset = zzUnpackAttribute(ZZ_ATTRIBUTE_PACKED_0, offset, result); - return result; - } + /** denotes if the user-EOF-code has already been executed */ + private boolean zzEOFDone; + + /** + * The number of occupied positions in zzBuffer beyond zzEndRead. + * When a lead/high surrogate has been read from the input stream + * into the final zzBuffer position, this will have a value of 1; + * otherwise, it will have a value of 0. + */ + private int zzFinalHighSurrogate = 0; - private static int zzUnpackAttribute(String packed, int offset, int[] result) { - int i = 0; - /* index in packed string */ - - int j = offset; - /* index in unpacked array */ - - int l = packed.length(); - while (i < l) { - int count = packed.charAt(i++); - int value = packed.charAt(i++); - do { - result[j++] = value; - } while (--count > 0); - } - return j; - } - - /** - * the input device - */ - private java.io.Reader zzReader; - - /** - * the current state of the DFA - */ - private int zzState; - - /** - * the current lexical state - */ - private int zzLexicalState = YYINITIAL; - - /** - * this buffer contains the current text to be matched and is the source of - * the yytext() string - */ - private char zzBuffer[] = new char[ZZ_BUFFERSIZE]; - - /** - * the textposition at the last accepting state - */ - private int zzMarkedPos; - - /** - * the current text position in the buffer - */ - private int zzCurrentPos; - - /** - * startRead marks the beginning of the yytext() string in the buffer - */ - private int zzStartRead; - - /** - * endRead marks the last character in the buffer, that has been read from - * input - */ - private int zzEndRead; - - /** - * number of newlines encountered up to the start of the matched text - */ - private int yyline; - - /** - * the number of characters up to the start of the matched text - */ - private int yychar; - - /** - * the number of characters from the last newline up to the start of the - * matched text - */ - private int yycolumn; - - /** - * zzAtBOL == true <=> the scanner is currently at the beginning of a line - */ - private boolean zzAtBOL = true; - - /** - * zzAtEOF == true <=> the scanner is at the EOF - */ - private boolean zzAtEOF; - - /** - * denotes if the user-EOF-code has already been executed - */ - private boolean zzEOFDone; - - /** - * The number of occupied positions in zzBuffer beyond zzEndRead. When a - * lead/high surrogate has been read from the input stream into the final - * zzBuffer position, this will have a value of 1; otherwise, it will have a - * value of 0. - */ - private int zzFinalHighSurrogate = 0; - - /* user code: */ - StringBuilder string = null; + /* user code: */ boolean finish = false; - boolean parameter = false; - String parameterName = null; - + StringBuilder string = null; + /** * Create an empty lexer, yyrset will be called later to reset and assign * the reader @@ -331,538 +293,536 @@ public final class TextLexer { return yyline + 1; } - /** - * Creates a new scanner - * - * @param in the java.io.Reader to read input from. - */ - public TextLexer(java.io.Reader in) { - this.zzReader = in; + + + /** + * Creates a new scanner + * + * @param in the java.io.Reader to read input from. + */ + public TextLexer(java.io.Reader in) { + this.zzReader = in; + } + + + /** + * Unpacks the compressed character translation table. + * + * @param packed the packed character translation table + * @return the unpacked character translation table + */ + private static char [] zzUnpackCMap(String packed) { + char [] map = new char[0x110000]; + int i = 0; /* index in packed string */ + int j = 0; /* index in unpacked array */ + while (i < 116) { + int count = packed.charAt(i++); + char value = packed.charAt(i++); + do map[j++] = value; while (--count > 0); + } + return map; + } + + + /** + * Refills the input buffer. + * + * @return false, iff there was new input. + * + * @exception java.io.IOException if any I/O-Error occurs + */ + private boolean zzRefill() throws java.io.IOException { + + /* first: make room (if you can) */ + if (zzStartRead > 0) { + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + System.arraycopy(zzBuffer, zzStartRead, + zzBuffer, 0, + zzEndRead-zzStartRead); + + /* translate stored positions */ + zzEndRead-= zzStartRead; + zzCurrentPos-= zzStartRead; + zzMarkedPos-= zzStartRead; + zzStartRead = 0; } - /** - * Unpacks the compressed character translation table. - * - * @param packed the packed character translation table - * @return the unpacked character translation table - */ - private static char[] zzUnpackCMap(String packed) { - char[] map = new char[0x110000]; - int i = 0; - /* index in packed string */ + /* is the buffer big enough? */ + if (zzCurrentPos >= zzBuffer.length - zzFinalHighSurrogate) { + /* if not: blow it up */ + char newBuffer[] = new char[zzBuffer.length*2]; + System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); + zzBuffer = newBuffer; + zzEndRead += zzFinalHighSurrogate; + zzFinalHighSurrogate = 0; + } - int j = 0; - /* index in unpacked array */ + /* fill the buffer with new input */ + int requested = zzBuffer.length - zzEndRead; + int totalRead = 0; + while (totalRead < requested) { + int numRead = zzReader.read(zzBuffer, zzEndRead + totalRead, requested - totalRead); + if (numRead == -1) { + break; + } + totalRead += numRead; + } - while (i < 114) { - int count = packed.charAt(i++); - char value = packed.charAt(i++); - do { - map[j++] = value; - } while (--count > 0); + if (totalRead > 0) { + zzEndRead += totalRead; + if (totalRead == requested) { /* possibly more input available */ + if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) { + --zzEndRead; + zzFinalHighSurrogate = 1; } - return map; + } + return false; } - /** - * Refills the input buffer. - * - * @return false, iff there was new input. - * @throws java.io.IOException if any I/O-Error occurs - */ - private boolean zzRefill() throws java.io.IOException { + // totalRead = 0: End of stream + return true; + } - /* first: make room (if you can) */ - if (zzStartRead > 0) { - zzEndRead += zzFinalHighSurrogate; - zzFinalHighSurrogate = 0; - System.arraycopy(zzBuffer, zzStartRead, - zzBuffer, 0, - zzEndRead - zzStartRead); + + /** + * Closes the input stream. + */ + public final void yyclose() throws java.io.IOException { + zzAtEOF = true; /* indicate end of file */ + zzEndRead = zzStartRead; /* invalidate buffer */ - /* translate stored positions */ - zzEndRead -= zzStartRead; - zzCurrentPos -= zzStartRead; - zzMarkedPos -= zzStartRead; - zzStartRead = 0; + if (zzReader != null) + zzReader.close(); + } + + + /** + * Resets the scanner to read from a new input stream. + * Does not close the old reader. + * + * All internal variables are reset, the old input stream + * cannot be reused (internal buffer is discarded and lost). + * Lexical state is set to ZZ_INITIAL. + * + * Internal scan buffer is resized down to its initial length, if it has grown. + * + * @param reader the new input stream + */ + public final void yyreset(java.io.Reader reader) { + zzReader = reader; + zzAtBOL = true; + zzAtEOF = false; + zzEOFDone = false; + zzEndRead = zzStartRead = 0; + zzCurrentPos = zzMarkedPos = 0; + zzFinalHighSurrogate = 0; + yyline = yychar = yycolumn = 0; + zzLexicalState = YYINITIAL; + if (zzBuffer.length > ZZ_BUFFERSIZE) + zzBuffer = new char[ZZ_BUFFERSIZE]; + } + + + /** + * Returns the current lexical state. + */ + public final int yystate() { + return zzLexicalState; + } + + + /** + * Enters a new lexical state + * + * @param newState the new lexical state + */ + public final void yybegin(int newState) { + zzLexicalState = newState; + } + + + /** + * Returns the text matched by the current regular expression. + */ + public final String yytext() { + return new String( zzBuffer, zzStartRead, zzMarkedPos-zzStartRead ); + } + + + /** + * Returns the character at position pos from the + * matched text. + * + * It is equivalent to yytext().charAt(pos), but faster + * + * @param pos the position of the character to fetch. + * A value from 0 to yylength()-1. + * + * @return the character at position pos + */ + public final char yycharat(int pos) { + return zzBuffer[zzStartRead+pos]; + } + + + /** + * Returns the length of the matched text region. + */ + public final int yylength() { + return zzMarkedPos-zzStartRead; + } + + + /** + * Reports an error that occured while scanning. + * + * In a wellformed scanner (no or only correct usage of + * yypushback(int) and a match-all fallback rule) this method + * will only be called with things that "Can't Possibly Happen". + * If this method is called, something is seriously wrong + * (e.g. a JFlex bug producing a faulty scanner etc.). + * + * Usual syntax/scanner level error handling should be done + * in error fallback rules. + * + * @param errorCode the code of the errormessage to display + */ + private void zzScanError(int errorCode) { + String message; + try { + message = ZZ_ERROR_MSG[errorCode]; + } + catch (ArrayIndexOutOfBoundsException e) { + message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; + } + + throw new Error(message); + } + + + /** + * Pushes the specified amount of characters back into the input stream. + * + * They will be read again by then next call of the scanning method + * + * @param number the number of characters to be read again. + * This number must not be greater than yylength()! + */ + public void yypushback(int number) { + if ( number > yylength() ) + zzScanError(ZZ_PUSHBACK_2BIG); + + zzMarkedPos -= number; + } + + + /** + * Resumes scanning until the next regular expression is matched, + * the end of input is encountered or an I/O-Error occurs. + * + * @return the next token + * @exception java.io.IOException if any I/O-Error occurs + */ + public ParsedSymbol yylex() throws java.io.IOException, TextParseException { + int zzInput; + int zzAction; + + // cached fields: + int zzCurrentPosL; + int zzMarkedPosL; + int zzEndReadL = zzEndRead; + char [] zzBufferL = zzBuffer; + char [] zzCMapL = ZZ_CMAP; + + int [] zzTransL = ZZ_TRANS; + int [] zzRowMapL = ZZ_ROWMAP; + int [] zzAttrL = ZZ_ATTRIBUTE; + + while (true) { + zzMarkedPosL = zzMarkedPos; + + yychar+= zzMarkedPosL-zzStartRead; + + boolean zzR = false; + int zzCh; + int zzCharCount; + for (zzCurrentPosL = zzStartRead ; + zzCurrentPosL < zzMarkedPosL ; + zzCurrentPosL += zzCharCount ) { + zzCh = Character.codePointAt(zzBufferL, zzCurrentPosL, zzMarkedPosL); + zzCharCount = Character.charCount(zzCh); + switch (zzCh) { + case '\u000B': + case '\u000C': + case '\u0085': + case '\u2028': + case '\u2029': + yyline++; + yycolumn = 0; + zzR = false; + break; + case '\r': + yyline++; + yycolumn = 0; + zzR = true; + break; + case '\n': + if (zzR) + zzR = false; + else { + yyline++; + yycolumn = 0; + } + break; + default: + zzR = false; + yycolumn += zzCharCount; } + } - /* is the buffer big enough? */ - if (zzCurrentPos >= zzBuffer.length - zzFinalHighSurrogate) { - /* if not: blow it up */ - char newBuffer[] = new char[zzBuffer.length * 2]; - System.arraycopy(zzBuffer, 0, newBuffer, 0, zzBuffer.length); - zzBuffer = newBuffer; - zzEndRead += zzFinalHighSurrogate; - zzFinalHighSurrogate = 0; + if (zzR) { + // peek one character ahead if it is \n (if we have counted one line too much) + boolean zzPeek; + if (zzMarkedPosL < zzEndReadL) + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; + else if (zzAtEOF) + zzPeek = false; + else { + boolean eof = zzRefill(); + zzEndReadL = zzEndRead; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + if (eof) + zzPeek = false; + else + zzPeek = zzBufferL[zzMarkedPosL] == '\n'; } + if (zzPeek) yyline--; + } + zzAction = -1; - /* fill the buffer with new input */ - int requested = zzBuffer.length - zzEndRead; - int totalRead = 0; - while (totalRead < requested) { - int numRead = zzReader.read(zzBuffer, zzEndRead + totalRead, requested - totalRead); - if (numRead == -1) { - break; - } - totalRead += numRead; - } + zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + + zzState = ZZ_LEXSTATE[zzLexicalState]; - if (totalRead > 0) { - zzEndRead += totalRead; - if (totalRead == requested) { - /* possibly more input available */ + // set up zzAction for empty match case: + int zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + } - if (Character.isHighSurrogate(zzBuffer[zzEndRead - 1])) { - --zzEndRead; - zzFinalHighSurrogate = 1; - } - } - return false; - } - - // totalRead = 0: End of stream - return true; - } - - /** - * Closes the input stream. - */ - public final void yyclose() throws java.io.IOException { - zzAtEOF = true; - /* indicate end of file */ - - zzEndRead = zzStartRead; - /* invalidate buffer */ - - if (zzReader != null) { - zzReader.close(); - } - } - - /** - * Resets the scanner to read from a new input stream. Does not close the - * old reader. - *

- * All internal variables are reset, the old input stream - * cannot be reused (internal buffer is discarded and lost). Lexical - * state is set to ZZ_INITIAL. - *

- * Internal scan buffer is resized down to its initial length, if it has - * grown. - * - * @param reader the new input stream - */ - public final void yyreset(java.io.Reader reader) { - zzReader = reader; - zzAtBOL = true; - zzAtEOF = false; - zzEOFDone = false; - zzEndRead = zzStartRead = 0; - zzCurrentPos = zzMarkedPos = 0; - zzFinalHighSurrogate = 0; - yyline = yychar = yycolumn = 0; - zzLexicalState = YYINITIAL; - if (zzBuffer.length > ZZ_BUFFERSIZE) { - zzBuffer = new char[ZZ_BUFFERSIZE]; - } - } - - /** - * Returns the current lexical state. - */ - public final int yystate() { - return zzLexicalState; - } - - /** - * Enters a new lexical state - * - * @param newState the new lexical state - */ - public final void yybegin(int newState) { - zzLexicalState = newState; - } - - /** - * Returns the text matched by the current regular expression. - */ - public final String yytext() { - return new String(zzBuffer, zzStartRead, zzMarkedPos - zzStartRead); - } - - /** - * Returns the character at position pos from the matched text. - *

- * It is equivalent to yytext().charAt(pos), but faster - * - * @param pos the position of the character to fetch. A value from 0 to - * yylength()-1. - * @return the character at position pos - */ - public final char yycharat(int pos) { - return zzBuffer[zzStartRead + pos]; - } - - /** - * Returns the length of the matched text region. - */ - public final int yylength() { - return zzMarkedPos - zzStartRead; - } - - /** - * Reports an error that occured while scanning. - *

- * In a wellformed scanner (no or only correct usage of yypushback(int) and - * a match-all fallback rule) this method will only be called with things - * that "Can't Possibly Happen". If this method is called, something is - * seriously wrong (e.g. a JFlex bug producing a faulty scanner etc.). - *

- * Usual syntax/scanner level error handling should be done in error - * fallback rules. - * - * @param errorCode the code of the errormessage to display - */ - private void zzScanError(int errorCode) { - String message; - try { - message = ZZ_ERROR_MSG[errorCode]; - } catch (ArrayIndexOutOfBoundsException e) { - message = ZZ_ERROR_MSG[ZZ_UNKNOWN_ERROR]; - } - - throw new Error(message); - } - - /** - * Pushes the specified amount of characters back into the input stream. - *

- * They will be read again by then next call of the scanning method - * - * @param number the number of characters to be read again. This number must - * not be greater than yylength()! - */ - public void yypushback(int number) { - if (number > yylength()) { - zzScanError(ZZ_PUSHBACK_2BIG); - } - - zzMarkedPos -= number; - } - - /** - * Resumes scanning until the next regular expression is matched, the end of - * input is encountered or an I/O-Error occurs. - * - * @return the next token - * @throws java.io.IOException if any I/O-Error occurs - */ - public ParsedSymbol yylex() throws java.io.IOException, TextParseException { - int zzInput; - int zzAction; - - // cached fields: - int zzCurrentPosL; - int zzMarkedPosL; - int zzEndReadL = zzEndRead; - char[] zzBufferL = zzBuffer; - char[] zzCMapL = ZZ_CMAP; - - int[] zzTransL = ZZ_TRANS; - int[] zzRowMapL = ZZ_ROWMAP; - int[] zzAttrL = ZZ_ATTRIBUTE; + zzForAction: { while (true) { - zzMarkedPosL = zzMarkedPos; - - yychar += zzMarkedPosL - zzStartRead; - - boolean zzR = false; - int zzCh; - int zzCharCount; - for (zzCurrentPosL = zzStartRead; - zzCurrentPosL < zzMarkedPosL; - zzCurrentPosL += zzCharCount) { - zzCh = Character.codePointAt(zzBufferL, zzCurrentPosL, zzMarkedPosL); - zzCharCount = Character.charCount(zzCh); - switch (zzCh) { - case '\u000B': - case '\u000C': - case '\u0085': - case '\u2028': - case '\u2029': - yyline++; - yycolumn = 0; - zzR = false; - break; - case '\r': - yyline++; - yycolumn = 0; - zzR = true; - break; - case '\n': - if (zzR) { - zzR = false; - } else { - yyline++; - yycolumn = 0; - } - break; - default: - zzR = false; - yycolumn += zzCharCount; - } + + if (zzCurrentPosL < zzEndReadL) { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); + } + else if (zzAtEOF) { + zzInput = YYEOF; + break zzForAction; + } + else { + // store back cached positions + zzCurrentPos = zzCurrentPosL; + zzMarkedPos = zzMarkedPosL; + boolean eof = zzRefill(); + // get translated positions and possibly new buffer + zzCurrentPosL = zzCurrentPos; + zzMarkedPosL = zzMarkedPos; + zzBufferL = zzBuffer; + zzEndReadL = zzEndRead; + if (eof) { + zzInput = YYEOF; + break zzForAction; } - - if (zzR) { - // peek one character ahead if it is \n (if we have counted one line too much) - boolean zzPeek; - if (zzMarkedPosL < zzEndReadL) { - zzPeek = zzBufferL[zzMarkedPosL] == '\n'; - } else if (zzAtEOF) { - zzPeek = false; - } else { - boolean eof = zzRefill(); - zzEndReadL = zzEndRead; - zzMarkedPosL = zzMarkedPos; - zzBufferL = zzBuffer; - if (eof) { - zzPeek = false; - } else { - zzPeek = zzBufferL[zzMarkedPosL] == '\n'; - } - } - if (zzPeek) { - yyline--; - } + else { + zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); + zzCurrentPosL += Character.charCount(zzInput); } - zzAction = -1; + } + int zzNext = zzTransL[ zzRowMapL[zzState] + zzCMapL[zzInput] ]; + if (zzNext == -1) break zzForAction; + zzState = zzNext; - zzCurrentPosL = zzCurrentPos = zzStartRead = zzMarkedPosL; + zzAttributes = zzAttrL[zzState]; + if ( (zzAttributes & 1) == 1 ) { + zzAction = zzState; + zzMarkedPosL = zzCurrentPosL; + if ( (zzAttributes & 8) == 8 ) break zzForAction; + } - zzState = ZZ_LEXSTATE[zzLexicalState]; - - // set up zzAction for empty match case: - int zzAttributes = zzAttrL[zzState]; - if ((zzAttributes & 1) == 1) { - zzAction = zzState; - } - - zzForAction: - { - while (true) { - - if (zzCurrentPosL < zzEndReadL) { - zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); - zzCurrentPosL += Character.charCount(zzInput); - } else if (zzAtEOF) { - zzInput = YYEOF; - break zzForAction; - } else { - // store back cached positions - zzCurrentPos = zzCurrentPosL; - zzMarkedPos = zzMarkedPosL; - boolean eof = zzRefill(); - // get translated positions and possibly new buffer - zzCurrentPosL = zzCurrentPos; - zzMarkedPosL = zzMarkedPos; - zzBufferL = zzBuffer; - zzEndReadL = zzEndRead; - if (eof) { - zzInput = YYEOF; - break zzForAction; - } else { - zzInput = Character.codePointAt(zzBufferL, zzCurrentPosL, zzEndReadL); - zzCurrentPosL += Character.charCount(zzInput); - } - } - int zzNext = zzTransL[zzRowMapL[zzState] + zzCMapL[zzInput]]; - if (zzNext == -1) { - break zzForAction; - } - zzState = zzNext; - - zzAttributes = zzAttrL[zzState]; - if ((zzAttributes & 1) == 1) { - zzAction = zzState; - zzMarkedPosL = zzCurrentPosL; - if ((zzAttributes & 8) == 8) { - break zzForAction; - } - } - - } - } - - // store back cached position - zzMarkedPos = zzMarkedPosL; - - switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { - case 1: { - if (string == null) { - string = new StringBuilder(); - } - string.append(yytext()); - } - case 20: - break; - case 2: { - parameter = true; - yybegin(PARAMETER); - if (string != null) { - String ret = string.toString(); - string = null; - return new ParsedSymbol(SymbolType.TEXT, ret); - } - } - case 21: - break; - case 3: { - if (!parameter) { - if (string == null) { - string = new StringBuilder(); - } - string.append(yytext()); - } - } - case 22: - break; - case 4: { - parameterName = yytext(); - yybegin(VALUE); - } - case 23: - break; - case 5: { - yybegin(YYINITIAL); - parameter = false; - } - case 24: - break; - case 6: { - } - case 25: - break; - case 7: { - yybegin(PARAMETER); - return new ParsedSymbol(SymbolType.PARAMETER, new Object[]{parameterName, yytext()}); - } - case 26: - break; - case 8: { - throw new TextParseException("Illegal escape sequence \"" + yytext() + "\"", yyline + 1); - } - case 27: - break; - case 9: { - if (string == null) { - string = new StringBuilder(); - } - string.append(']'); - } - case 28: - break; - case 10: { - if (string == null) { - string = new StringBuilder(); - } - string.append('['); - } - case 29: - break; - case 11: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\\'); - } - case 30: - break; - case 12: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\b'); - } - case 31: - break; - case 13: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\t'); - } - case 32: - break; - case 14: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\n'); - } - case 33: - break; - case 15: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\f'); - } - case 34: - break; - case 16: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\r'); - } - case 35: - break; - case 17: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\"'); - } - case 36: - break; - case 18: { - if (string == null) { - string = new StringBuilder(); - } - string.append('\''); - } - case 37: - break; - case 19: { - char val = (char) Integer.parseInt(yytext().substring(2), 16); - string.append(val); - } - case 38: - break; - default: - if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { - zzAtEOF = true; - switch (zzLexicalState) { - case YYINITIAL: { - if (finish) { - return null; - } else { - finish = true; - return new ParsedSymbol(SymbolType.TEXT, string == null ? null : string.toString()); - } - } - case 26: - break; - default: { - return null; - } - } - } else { - zzScanError(ZZ_NO_MATCH); - } - } } + } + + // store back cached position + zzMarkedPos = zzMarkedPosL; + + switch (zzAction < 0 ? zzAction : ZZ_ACTION[zzAction]) { + case 1: + { if (string == null) string = new StringBuilder(); string.append(yytext()); + } + case 33: break; + case 2: + { if (!parameter) { if (string == null) string = new StringBuilder(); string.append(yytext()); } + } + case 34: break; + case 3: + { parameter = true; + yybegin(PARAMETER); + if (string != null){ + String ret = string.toString(); + string = null; + return new ParsedSymbol(SymbolType.TEXT, ret); + } + } + case 35: break; + case 4: + { yybegin(VALUE); + return new ParsedSymbol(SymbolType.PARAMETER_IDENTIFIER, yytext()); + } + case 36: break; + case 5: + { yybegin(YYINITIAL); + parameter = false; + } + case 37: break; + case 6: + { + } + case 38: break; + case 7: + { return new ParsedSymbol(SymbolType.PARAMETER_VALUE, yytext()); + } + case 39: break; + case 8: + { return new ParsedSymbol(SymbolType.PARAMETER_IDENTIFIER, yytext()); + } + case 40: break; + case 9: + { string = new StringBuilder(); + yybegin(STRING); + } + case 41: break; + case 10: + { string.append(yytext()); + } + case 42: break; + case 11: + { yybegin(VALUE); + // length also includes the trailing quote + String tos = string.toString(); + string = null; + return new ParsedSymbol(SymbolType.PARAMETER_VALUE, tos); + } + case 43: break; + case 12: + { throw new TextParseException("Illegal escape sequence \"" + yytext() + "\"", yyline + 1); + } + case 44: break; + case 13: + { if (string == null) string = new StringBuilder(); string.append(']'); + } + case 45: break; + case 14: + { if (string == null) string = new StringBuilder(); string.append('\\'); + } + case 46: break; + case 15: + { if (string == null) string = new StringBuilder(); string.append('\"'); + } + case 47: break; + case 16: + { if (string == null) string = new StringBuilder(); string.append('['); + } + case 48: break; + case 17: + { if (string == null) string = new StringBuilder(); string.append('\b'); + } + case 49: break; + case 18: + { if (string == null) string = new StringBuilder(); string.append('\t'); + } + case 50: break; + case 19: + { if (string == null) string = new StringBuilder(); string.append('\n'); + } + case 51: break; + case 20: + { if (string == null) string = new StringBuilder(); string.append('\f'); + } + case 52: break; + case 21: + { if (string == null) string = new StringBuilder(); string.append('\r'); + } + case 53: break; + case 22: + { if (string == null) string = new StringBuilder(); string.append('\''); + } + case 54: break; + case 23: + { /* ignore illegal character escape */ + } + case 55: break; + case 24: + { string.append('\\'); + } + case 56: break; + case 25: + { string.append('\"'); + } + case 57: break; + case 26: + { string.append('\b'); + } + case 58: break; + case 27: + { string.append('\t'); + } + case 59: break; + case 28: + { string.append('\n'); + } + case 60: break; + case 29: + { string.append('\f'); + } + case 61: break; + case 30: + { string.append('\r'); + } + case 62: break; + case 31: + { string.append('\''); + } + case 63: break; + case 32: + { char val = (char) Integer.parseInt(yytext().substring(2), 16); + string.append(val); + } + case 64: break; + default: + if (zzInput == YYEOF && zzStartRead == zzCurrentPos) { + zzAtEOF = true; + switch (zzLexicalState) { + case YYINITIAL: { + if (finish) {return null;} else {finish=true; return new ParsedSymbol(SymbolType.TEXT, string == null ? null : string.toString());} + } + case 45: break; + default: + { + return null; + } + } + } + else { + zzScanError(ZZ_NO_MATCH); + } + } } + } + + } diff --git a/libsrc/jsyntaxpane/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/swftext.flex b/libsrc/jsyntaxpane/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/swftext.flex index 354d7fec1..d4cba3067 100644 --- a/libsrc/jsyntaxpane/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/swftext.flex +++ b/libsrc/jsyntaxpane/jsyntaxpane/src/main/jflex/jsyntaxpane/lexers/swftext.flex @@ -37,7 +37,7 @@ import jsyntaxpane.TokenType; %} -Parameter = [a-z0-9_]+ +Parameter = [a-z_][a-z0-9_]* Value = [^ \r\n\]]+ Divider = [ \r\n]+ @@ -76,9 +76,11 @@ Divider = [ \r\n]+ } { - {Divider} {} - {Value} { - yybegin(PARAMETER); + {Divider} {} + {Parameter} { + return token(TokenType.KEYWORD); + } + {Value} { return token(TokenType.NUMBER); } "]" {