add font metrics to gen PS properly

[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9152]
This commit is contained in:
parrt 2011-10-22 11:22:22 -08:00
parent 89d4b31ef6
commit 72906f5910
9 changed files with 854 additions and 6 deletions

View File

@ -68,6 +68,10 @@ public class Trees {
return tok.getText();
}
}
Object payload = t.getPayload();
if ( payload instanceof Token ) {
return ((Token)payload).getText();
}
return t.getPayload().toString();
}

View File

@ -0,0 +1,131 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.runtime.tree.gui;
public class Arial extends FontMetrics {
{
maxCharHeight = 781;
widths[32] = 277; // space
widths[33] = 277; // exclam
widths[34] = 354; // quotedbl
widths[35] = 556; // numbersign
widths[36] = 556; // dollar
widths[37] = 889; // percent
widths[38] = 666; // ampersand
widths[39] = 190; // quotesingle
widths[40] = 333; // parenleft
widths[41] = 333; // parenright
widths[42] = 389; // asterisk
widths[43] = 583; // plus
widths[44] = 277; // comma
widths[45] = 333; // hyphen
widths[46] = 277; // period
widths[47] = 277; // slash
widths[48] = 556; // zero
widths[49] = 556; // one
widths[50] = 556; // two
widths[51] = 556; // three
widths[52] = 556; // four
widths[53] = 556; // five
widths[54] = 556; // six
widths[55] = 556; // seven
widths[56] = 556; // eight
widths[57] = 556; // nine
widths[58] = 277; // colon
widths[59] = 277; // semicolon
widths[60] = 583; // less
widths[61] = 583; // equal
widths[62] = 583; // greater
widths[63] = 556; // question
widths[64] = 1015; // at
widths[65] = 666; // A
widths[66] = 666; // B
widths[67] = 722; // C
widths[68] = 722; // D
widths[69] = 666; // E
widths[70] = 610; // F
widths[71] = 777; // G
widths[72] = 722; // H
widths[73] = 277; // I
widths[74] = 500; // J
widths[75] = 666; // K
widths[76] = 556; // L
widths[77] = 833; // M
widths[78] = 722; // N
widths[79] = 777; // O
widths[80] = 666; // P
widths[81] = 777; // Q
widths[82] = 722; // R
widths[83] = 666; // S
widths[84] = 610; // T
widths[85] = 722; // U
widths[86] = 666; // V
widths[87] = 943; // W
widths[88] = 666; // X
widths[89] = 666; // Y
widths[90] = 610; // Z
widths[91] = 277; // bracketleft
widths[92] = 277; // backslash
widths[93] = 277; // bracketright
widths[94] = 469; // asciicircum
widths[95] = 556; // underscore
widths[96] = 333; // grave
widths[97] = 556; // a
widths[98] = 556; // b
widths[99] = 500; // c
widths[100] = 556; // d
widths[101] = 556; // e
widths[102] = 277; // f
widths[103] = 556; // g
widths[104] = 556; // h
widths[105] = 222; // i
widths[106] = 222; // j
widths[107] = 500; // k
widths[108] = 222; // l
widths[109] = 833; // m
widths[110] = 556; // n
widths[111] = 556; // o
widths[112] = 556; // p
widths[113] = 556; // q
widths[114] = 333; // r
widths[115] = 500; // s
widths[116] = 277; // t
widths[117] = 556; // u
widths[118] = 500; // v
widths[119] = 722; // w
widths[120] = 500; // x
widths[121] = 500; // y
widths[122] = 500; // z
widths[123] = 333; // braceleft
widths[124] = 259; // bar
widths[125] = 333; // braceright
widths[126] = 583; // asciitilde
}
}

View File

@ -0,0 +1,131 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.runtime.tree.gui;
public class ArialBlack extends FontMetrics {
{
maxCharHeight = 770;
widths[32] = 333; // space
widths[33] = 333; // exclam
widths[34] = 500; // quotedbl
widths[35] = 660; // numbersign
widths[36] = 666; // dollar
widths[37] = 1000; // percent
widths[38] = 889; // ampersand
widths[39] = 277; // quotesingle
widths[40] = 389; // parenleft
widths[41] = 389; // parenright
widths[42] = 556; // asterisk
widths[43] = 660; // plus
widths[44] = 333; // comma
widths[45] = 333; // hyphen
widths[46] = 333; // period
widths[47] = 277; // slash
widths[48] = 666; // zero
widths[49] = 666; // one
widths[50] = 666; // two
widths[51] = 666; // three
widths[52] = 666; // four
widths[53] = 666; // five
widths[54] = 666; // six
widths[55] = 666; // seven
widths[56] = 666; // eight
widths[57] = 666; // nine
widths[58] = 333; // colon
widths[59] = 333; // semicolon
widths[60] = 660; // less
widths[61] = 660; // equal
widths[62] = 660; // greater
widths[63] = 610; // question
widths[64] = 740; // at
widths[65] = 777; // A
widths[66] = 777; // B
widths[67] = 777; // C
widths[68] = 777; // D
widths[69] = 722; // E
widths[70] = 666; // F
widths[71] = 833; // G
widths[72] = 833; // H
widths[73] = 389; // I
widths[74] = 666; // J
widths[75] = 833; // K
widths[76] = 666; // L
widths[77] = 943; // M
widths[78] = 833; // N
widths[79] = 833; // O
widths[80] = 722; // P
widths[81] = 833; // Q
widths[82] = 777; // R
widths[83] = 722; // S
widths[84] = 722; // T
widths[85] = 833; // U
widths[86] = 777; // V
widths[87] = 1000; // W
widths[88] = 777; // X
widths[89] = 777; // Y
widths[90] = 722; // Z
widths[91] = 389; // bracketleft
widths[92] = 277; // backslash
widths[93] = 389; // bracketright
widths[94] = 660; // asciicircum
widths[95] = 500; // underscore
widths[96] = 333; // grave
widths[97] = 666; // a
widths[98] = 666; // b
widths[99] = 666; // c
widths[100] = 666; // d
widths[101] = 666; // e
widths[102] = 389; // f
widths[103] = 666; // g
widths[104] = 666; // h
widths[105] = 333; // i
widths[106] = 333; // j
widths[107] = 666; // k
widths[108] = 333; // l
widths[109] = 1000; // m
widths[110] = 666; // n
widths[111] = 666; // o
widths[112] = 666; // p
widths[113] = 666; // q
widths[114] = 443; // r
widths[115] = 610; // s
widths[116] = 443; // t
widths[117] = 666; // u
widths[118] = 610; // v
widths[119] = 943; // w
widths[120] = 666; // x
widths[121] = 610; // y
widths[122] = 556; // z
widths[123] = 389; // braceleft
widths[124] = 277; // bar
widths[125] = 389; // braceright
widths[126] = 660; // asciitilde
}
}

View File

@ -0,0 +1,37 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.runtime.tree.gui;
public class CourierNew extends FontMetrics {
{
maxCharHeight = 678;
for (int i=0; i<128; i++) widths[i] = 600;
}
}

View File

@ -0,0 +1,89 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.runtime.tree.gui;
/** Font metrics. The only way to generate accurate images
* in any format that contain text is to know the font metrics.
* Specifically, we need to know the width of every character and the
* maximum height (since we want all characters to fit within same line height).
* I used ttf2tfm to dump the font metrics from Mac TrueType fonts and
* then converted that to a Java class for use in a PostScript generator
* for trees. Commands:
*
* $ ttf2tfm /Library/Fonts/Arial\ Black.ttf > metrics
*
* Then run metrics into python code after stripping header/footer:
*
#
# Process lines from ttf2tfm that look like this:
# Glyph Code Glyph Name Width llx lly urx ury
# ------------------------------------------------------------------------
# 3 00020 space 333 0, 0 -- 0, 0
#
lines = open("metrics").read().split('\n')
print "public class FontName {"
print " public static int[] widths = new int[128];"
print " static {"
maxh = 0;
for line in lines:
all = line.split(' ')
words = [x for x in all if len(x)>0]
ascii = int(words[1], 16)
height = int(words[8])
if height>maxh: maxh = height
if ascii>=128: break
print " widths[%d] = %s; // %s" % (ascii, words[3], words[2])
print " }"
print " public static int MAX_CHAR_HEIGHT = "+str(maxh)+";"
print "}"
Units are 1000th of an 'em'.
*/
public abstract class FontMetrics {
protected int maxCharHeight;
protected int[] widths = new int[128];
public double getWidth(String s, int fontSize) {
double w = 0;
for (char c : s.toCharArray()) {
w += getWidth(c, fontSize);
}
return w;
}
public double getWidth(char c, int fontSize) {
return widths[c]/1000.0 * fontSize;
}
public double getLineHeight(int fontSize) {
return maxCharHeight / 1000.0 * fontSize;
}
}

View File

@ -0,0 +1,159 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.runtime.tree.gui;
public class PostScriptDocument {
protected int boundingBoxWidth;
protected int boundingBoxHeight;
protected FontMetrics fontMetrics;
protected String fontName;
protected int fontSize = 12;
protected double lineWidth = 0.3;
protected StringBuilder ps = new StringBuilder();
protected boolean closed = false;
public PostScriptDocument() {
this("CourierNew", 12);
}
public PostScriptDocument(String fontName, int fontSize) {
header();
setFont(fontName, fontSize);
}
public String getPS() { close(); return ps.toString(); }
public void boundingBox(int w, int h) {
boundingBoxWidth = w;
boundingBoxHeight = h;
ps.append(String.format("%%%%BoundingBox: %d %d %d %d\n", 0,0,
boundingBoxWidth,boundingBoxHeight));
}
public void close() {
if ( closed ) return;
ps.append("showpage\n");
ps.append("%%Trailer\n");
closed = true;
}
protected void header() {
ps.append("%!PS-Adobe-3.0 EPSF-3.0\n");
ps.append("%%BoundingBox: (atend)\n");
lineWidth(0.3);
ps.append("%\n");
ps.append("% x y rarrow\n");
ps.append("%\n");
ps.append("/rarrow {\n");
ps.append(" moveto\n");
ps.append(" -3 +2 rlineto\n");
ps.append(" 0 -4 rlineto\n");
ps.append(" 3 +2 rlineto\n");
ps.append(" fill\n");
ps.append("} def\n");
ps.append("%\n");
ps.append("% x y darrow\n");
ps.append("%\n");
ps.append("/darrow {\n");
ps.append(" moveto\n");
ps.append(" -2 +3 rlineto\n");
ps.append(" 4 0 rlineto\n");
ps.append(" -2 -3 rlineto\n");
ps.append(" fill\n");
ps.append("} def\n");
}
// Courier, Helvetica, Times, ... should be available
public void setFont(String fontName, int fontSize) {
this.fontName = fontName;
this.fontSize = fontSize;
try {
Class c = Class.forName("org.antlr.v4.runtime.tree.gui." + fontName);
this.fontMetrics = (FontMetrics)c.newInstance();
}
catch (Exception e) {
throw new UnsupportedOperationException("No font metrics for "+fontName);
}
ps.append(String.format("/%s findfont\n%d scalefont setfont\n", fontName, fontSize));
}
public void lineWidth(double w) {
lineWidth = w;
ps.append(w+" setlinewidth\n");
}
public void move(double x, double y) {
ps.append(String.format("%1.3f %1.3f moveto\n", x, y));
}
public void lineto(double x, double y) {
ps.append(String.format("%1.3f %1.3f lineto\n", x, y));
}
public void line(double x1, double y1, double x2, double y2) {
move(x1, y1);
lineto(x2, y2);
}
public void rect(double x, double y, double width, double height) {
line(x, y, x, y + height);
line(x, y + height, x + width, y + height);
line(x + width, y + height, x + width, y);
line(x + width, y, x, y);
}
public void stroke() {
ps.append("stroke\n");
}
public void rarrow(double x, double y) {
ps.append(String.format("%1.3f %1.3f rarrow\n", x,y));
}
public void darrow(double x, double y) {
ps.append(String.format("%1.3f %1.3f darrow\n", x,y));
}
public void text(String s, double x, double y) {
move(x,y);
ps.append(String.format("(%s) show\n", s));
stroke();
}
// courier new: wid/hei 7.611979 10.0625
/** All chars are 600 thousands of an 'em' wide if courier */
public double getWidth(char c) { return fontMetrics.getWidth(c, fontSize); }
public double getWidth(String s) { return fontMetrics.getWidth(s, fontSize); }
public double getLineHeight() { return fontMetrics.getLineHeight(fontSize); }
public int getFontSize() { return fontSize; }
}

View File

@ -0,0 +1,131 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.runtime.tree.gui;
public class TimesNewRoman extends FontMetrics {
{
maxCharHeight = 717;
widths[32] = 250; // space
widths[33] = 333; // exclam
widths[34] = 408; // quotedbl
widths[35] = 500; // numbersign
widths[36] = 500; // dollar
widths[37] = 833; // percent
widths[38] = 777; // ampersand
widths[39] = 180; // quotesingle
widths[40] = 333; // parenleft
widths[41] = 333; // parenright
widths[42] = 500; // asterisk
widths[43] = 563; // plus
widths[44] = 250; // comma
widths[45] = 333; // hyphen
widths[46] = 250; // period
widths[47] = 277; // slash
widths[48] = 500; // zero
widths[49] = 500; // one
widths[50] = 500; // two
widths[51] = 500; // three
widths[52] = 500; // four
widths[53] = 500; // five
widths[54] = 500; // six
widths[55] = 500; // seven
widths[56] = 500; // eight
widths[57] = 500; // nine
widths[58] = 277; // colon
widths[59] = 277; // semicolon
widths[60] = 563; // less
widths[61] = 563; // equal
widths[62] = 563; // greater
widths[63] = 443; // question
widths[64] = 920; // at
widths[65] = 722; // A
widths[66] = 666; // B
widths[67] = 666; // C
widths[68] = 722; // D
widths[69] = 610; // E
widths[70] = 556; // F
widths[71] = 722; // G
widths[72] = 722; // H
widths[73] = 333; // I
widths[74] = 389; // J
widths[75] = 722; // K
widths[76] = 610; // L
widths[77] = 889; // M
widths[78] = 722; // N
widths[79] = 722; // O
widths[80] = 556; // P
widths[81] = 722; // Q
widths[82] = 666; // R
widths[83] = 556; // S
widths[84] = 610; // T
widths[85] = 722; // U
widths[86] = 722; // V
widths[87] = 943; // W
widths[88] = 722; // X
widths[89] = 722; // Y
widths[90] = 610; // Z
widths[91] = 333; // bracketleft
widths[92] = 277; // backslash
widths[93] = 333; // bracketright
widths[94] = 469; // asciicircum
widths[95] = 500; // underscore
widths[96] = 333; // grave
widths[97] = 443; // a
widths[98] = 500; // b
widths[99] = 443; // c
widths[100] = 500; // d
widths[101] = 443; // e
widths[102] = 333; // f
widths[103] = 500; // g
widths[104] = 500; // h
widths[105] = 277; // i
widths[106] = 277; // j
widths[107] = 500; // k
widths[108] = 277; // l
widths[109] = 777; // m
widths[110] = 500; // n
widths[111] = 500; // o
widths[112] = 500; // p
widths[113] = 500; // q
widths[114] = 333; // r
widths[115] = 389; // s
widths[116] = 277; // t
widths[117] = 500; // u
widths[118] = 500; // v
widths[119] = 722; // w
widths[120] = 500; // x
widths[121] = 500; // y
widths[122] = 443; // z
widths[123] = 479; // braceleft
widths[124] = 200; // bar
widths[125] = 479; // braceright
widths[126] = 541; // asciitilde
}
}

View File

@ -0,0 +1,169 @@
/*
[The "BSD license"]
Copyright (c) 2011 Terence Parr
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
3. The name of the author may not be used to endorse or promote products
derived from this software without specific prior written permission.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
package org.antlr.v4.runtime.tree.gui;
import org.abego.treelayout.*;
import org.abego.treelayout.util.DefaultConfiguration;
import org.antlr.v4.runtime.*;
import org.antlr.v4.runtime.tree.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
public class TreePostScriptGenerator {
public class VariableExtentProvide implements NodeExtentProvider<Tree> {
@Override
public double getWidth(Tree tree) {
String s = getText(tree);
return doc.getWidth(s) + nodeWidthPadding*2;
}
@Override
public double getHeight(Tree tree) {
String s = getText(tree);
double h = doc.getLineHeight() + nodeHeightPadding*2;
String[] lines = s.split("\n");
return h * lines.length;
}
}
protected double gapBetweenLevels = 30;
protected double gapBetweenNodes = 10;
protected int nodeWidthPadding = 1; // added to left/right
protected int nodeHeightPadding = 1; // added above/below
protected Tree root;
protected TreeTextProvider treeTextProvider;
protected TreeLayout<Tree> treeLayout;
protected PostScriptDocument doc;
public TreePostScriptGenerator(BaseRecognizer parser, Tree root) {
this(parser, root, "CourierNew", 11);
}
public TreePostScriptGenerator(BaseRecognizer parser, Tree root,
String fontName, int fontSize)
{
this.root = root;
setTreeTextProvider(new TreeViewer.DefaultTreeTextProvider(parser));
doc = new PostScriptDocument(fontName, fontSize);
this.treeLayout =
new TreeLayout<Tree>(new TreeLayoutAdaptor(root),
new VariableExtentProvide(),
new DefaultConfiguration<Tree>(gapBetweenLevels,
gapBetweenNodes,
Configuration.Location.Bottom));
}
public String getPS() {
// generate the edges and boxes (with text)
generateEdges(getTree().getRoot());
for (Tree textInBox : treeLayout.getNodeBounds().keySet()) {
generateNode(textInBox);
}
Dimension size = treeLayout.getBounds().getBounds().getSize();
doc.boundingBox(size.width, size.height);
doc.close();
return doc.getPS();
}
protected void generateEdges(Tree parent) {
if (!getTree().isLeaf(parent)) {
Rectangle2D.Double parentBounds = getBoundsOfNode(parent);
System.out.println("%% parent("+getText(parent)+")="+parentBounds);
double x1 = parentBounds.getCenterX();
double y1 = parentBounds.y;
for (Tree child : getChildren(parent)) {
Rectangle2D.Double childBounds = getBoundsOfNode(child);
System.out.println("%% child("+getText(child)+")="+childBounds);
double x2 = childBounds.getCenterX();
double y2 = childBounds.getMaxY();
doc.line(x1, y1, x2, y2);
generateEdges(child);
}
}
}
protected void generateNode(Tree t) {
// draw the text on top of the box (possibly multiple lines)
String[] lines = getText(t).split("\n");
Rectangle2D.Double box = getBoundsOfNode(t);
// for debugging, turn this on to see boundingbox of nodes
// doc.rect(box.x, box.y, box.width, box.height);
double x = box.x+nodeWidthPadding;
double y = box.y+nodeHeightPadding;
for (int i = 0; i < lines.length; i++) {
doc.text(lines[i], x, y);
y += doc.getFontSize();
}
}
protected TreeForTreeLayout<Tree> getTree() {
return treeLayout.getTree();
}
protected Iterable<Tree> getChildren(Tree parent) {
return getTree().getChildren(parent);
}
protected Rectangle2D.Double getBoundsOfNode(Tree node) {
return treeLayout.getNodeBounds().get(node);
}
protected String getText(Tree tree) {
return treeTextProvider.getText(tree);
}
public TreeTextProvider getTreeTextProvider() {
return treeTextProvider;
}
public void setTreeTextProvider(TreeTextProvider treeTextProvider) {
this.treeTextProvider = treeTextProvider;
}
public static void main(String[] args) {
CommonAST t = new CommonAST(new CommonToken(1, "+"));
CommonAST a = new CommonAST(new CommonToken(1, "expression"));
CommonAST f = new CommonAST(new CommonToken(1, "3000"));
CommonAST b = new CommonAST(new CommonToken(1, "*"));
CommonAST c = new CommonAST(new CommonToken(1, "42"));
CommonAST d = new CommonAST(new CommonToken(1, "105"));
t.addChild(a);
a.addChild(f);
t.addChild(b);
b.addChild(c);
b.addChild(d);
TreePostScriptGenerator psgen = new TreePostScriptGenerator(null, t, "TimesNewRoman", 11);
System.out.println(psgen.getPS());
}
}

View File

@ -29,20 +29,17 @@
package org.antlr.v4.runtime.tree.gui;
import org.abego.treelayout.NodeExtentProvider;
import org.abego.treelayout.TreeForTreeLayout;
import org.abego.treelayout.TreeLayout;
import org.abego.treelayout.*;
import org.abego.treelayout.util.DefaultConfiguration;
import org.antlr.v4.runtime.BaseRecognizer;
import org.antlr.v4.runtime.tree.Tree;
import org.antlr.v4.runtime.tree.Trees;
import org.antlr.v4.runtime.tree.*;
import javax.swing.*;
import java.awt.*;
import java.awt.geom.Rectangle2D;
public class TreeViewer extends JComponent {
public class DefaultTreeTextProvider implements TreeTextProvider {
public static class DefaultTreeTextProvider implements TreeTextProvider {
BaseRecognizer parser;
public DefaultTreeTextProvider(BaseRecognizer parser) {
this.parser = parser;