forked from jasder/antlr
add font metrics to gen PS properly
[git-p4: depot-paths = "//depot/code/antlr4/main/": change = 9152]
This commit is contained in:
parent
89d4b31ef6
commit
72906f5910
|
@ -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();
|
||||
}
|
||||
|
||||
|
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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; }
|
||||
}
|
|
@ -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
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue