1 |
/* |
/* |
2 |
TextNodeView.java |
TextNodeView.java |
3 |
* |
* |
4 |
* Copyright (c) 2003, Benja Fallenstein |
* Copyright (c) 2003, Benja Fallenstein, Asko Soukka |
5 |
* |
* |
6 |
* This file is part of Fenfire. |
* This file is part of Fenfire. |
7 |
* |
* |
23 |
* |
* |
24 |
*/ |
*/ |
25 |
/* |
/* |
26 |
* Written by Benja Fallenstein |
* Written by Benja Fallenstein, Asko Soukka |
27 |
*/ |
*/ |
28 |
package org.fenfire.view; |
package org.fenfire.view; |
29 |
import org.fenfire.swamp.*; |
import org.fenfire.swamp.*; |
32 |
import org.nongnu.libvob.linebreaking.*; |
import org.nongnu.libvob.linebreaking.*; |
33 |
import org.nongnu.libvob.vobs.*; |
import org.nongnu.libvob.vobs.*; |
34 |
|
|
35 |
|
import java.awt.Color; |
36 |
import java.lang.Math; |
import java.lang.Math; |
37 |
|
|
38 |
/** A node function returning a vob that shows |
/** |
39 |
* the given node as text. |
* A node function returning a vob that shows the given node as text. |
40 |
* <em>Should</em> take a width and do linebreaking; |
* The maximum size of a single line is determined by <pre>width</pre>. |
|
* currently, places text as a single very long line. |
|
41 |
*/ |
*/ |
42 |
public class TextNodeView extends org.fenfire.view.lava.TextHandler |
public class TextNodeView implements NodeFunction { |
43 |
implements NodeFunction { |
public static final String rcsid = "$Id$"; |
44 |
public static final String rcsid = "$Id$"; |
|
45 |
public static boolean dbg = false; |
public static boolean dbg = false; |
46 |
private static void pa(String s) { System.out.println("TextNodeView::"+s); } |
private static void pa(String s) { System.out.println("TextNodeView::"+s); } |
47 |
|
|
48 |
final SimpleLinebreaker breaker = new SimpleLinebreaker(); |
public final static float DEFAULT_SCALE = 1f; |
49 |
|
public final static float DEFAULT_WIDTH = 300f; |
50 |
final NodeFunction nodeContent; |
public final static Color DEFAULT_TEXT_COLOR = Color.black; |
51 |
|
|
52 |
final float width = 300; |
private final SimpleLinebreaker breaker = new SimpleLinebreaker(); |
53 |
|
private final NodeFunction nodeContent; |
54 |
|
private final TextStyle style; |
55 |
|
private final Color textColor; |
56 |
|
private final float scale; |
57 |
|
private final float width; |
58 |
|
|
59 |
public TextNodeView(NodeFunction nodeContent, |
public TextNodeView(NodeFunction nodeContent, |
60 |
TextStyle style, |
TextStyle style, |
61 |
|
Color textColor, |
62 |
|
float width, |
63 |
float scale) { |
float scale) { |
64 |
this.nodeContent = nodeContent; |
this.nodeContent = nodeContent; |
65 |
super.setStyle(style); |
this.style = style; |
66 |
super.setScale(scale); |
this.textColor = textColor; |
67 |
|
this.width = width; |
68 |
|
this.scale = scale; |
69 |
|
} |
70 |
|
public TextNodeView(NodeFunction nodeContent, TextStyle style, |
71 |
|
Color textColor, float width) { |
72 |
|
this(nodeContent, style, textColor, width, DEFAULT_SCALE); |
73 |
|
} |
74 |
|
public TextNodeView(NodeFunction nodeContent, TextStyle style, |
75 |
|
Color textColor) { |
76 |
|
this(nodeContent, style, textColor, DEFAULT_WIDTH, DEFAULT_SCALE); |
77 |
|
} |
78 |
|
public TextNodeView(NodeFunction nodeContent, TextStyle style, |
79 |
|
float scale) { |
80 |
|
this(nodeContent, style, DEFAULT_TEXT_COLOR, scale, DEFAULT_SCALE); |
81 |
|
} |
82 |
|
public TextNodeView(NodeFunction nodeContent, TextStyle style) { |
83 |
|
this(nodeContent, style, DEFAULT_TEXT_COLOR, DEFAULT_WIDTH, DEFAULT_WIDTH); |
84 |
} |
} |
85 |
|
|
86 |
private boolean hasContext = true; |
public Object f(ConstGraph g, Object node) { |
87 |
public void setHasNoContext() { hasContext = false; } |
final Enfilade1D enf = (Enfilade1D)nodeContent.f(g, node); |
88 |
|
final Object objNode = node; |
89 |
|
final String s = enf.makeString(); |
90 |
|
if (s.length() == 0) |
91 |
|
return new org.nongnu.libvob.lava.placeable.Placeable() { |
92 |
|
public void place(VobScene vs, int into) { |
93 |
|
} |
94 |
|
public float getWidth() { return 10; } |
95 |
|
public float getHeight() { return 10; } |
96 |
|
}; |
97 |
|
|
98 |
private org.fenfire.view.lava.TextHandler.Context context = null; |
final HChain ch = getChain(s); |
99 |
public void setContext(org.fenfire.view.lava.TextHandler.Context context) |
final HBroken br = breaker.breakLines(ch, width, scale); |
100 |
{ this.context = context; } |
final float height = br.getHeight(); |
101 |
|
|
102 |
/** Get position of the first character placed |
final float width; |
103 |
* after given coordinates. |
if(br.getLineCount() > 1) { // Let's get the longest line |
104 |
|
float maxWidth = br.getLineWidth(0); |
105 |
|
for (int i=1; i<br.getLineCount(); i++) |
106 |
|
if (br.getLineWidth(i) > maxWidth) |
107 |
|
maxWidth = br.getLineWidth(i); |
108 |
|
width = maxWidth; |
109 |
|
} else width = br.getLineWidth(0); |
110 |
|
|
111 |
|
//// Code of the old single line TextNodeView |
112 |
|
//final TextVob vob = new TextVob(style, s, false); |
113 |
|
//final float width = style.getWidth(s, scale); |
114 |
|
//final float height = style.getHeight(scale); |
115 |
|
|
116 |
|
if(dbg) { |
117 |
|
pa(" "+s+"' "+width+" "+height+" "+scale+" "+br); |
118 |
|
} |
119 |
|
|
120 |
|
return new org.nongnu.libvob.lava.placeable.Placeable() { |
121 |
|
public void place(VobScene vs, int into) { |
122 |
|
br.put(vs, into); |
123 |
|
} |
124 |
|
|
125 |
|
public float getWidth() { return width; } |
126 |
|
public float getHeight() { return height; } |
127 |
|
}; |
128 |
|
} |
129 |
|
|
130 |
|
/** |
131 |
|
* Get the position of the first character placed after given coordinates. |
132 |
*/ |
*/ |
133 |
public int getPos(ConstGraph g, Object node, float x, float y) { |
public void getPos(ConstGraph g, Object node, float x, float y) { |
134 |
Enfilade1D enf = (Enfilade1D)nodeContent.f(g, node); |
Enfilade1D enf = (Enfilade1D)nodeContent.f(g, node); |
135 |
final Object objNode = node; |
Object objNode = node; |
136 |
String s = enf.makeString(); |
getPos(enf.makeString(), x, y); |
137 |
|
} |
138 |
|
public int getPos(String s, float x, float y) { |
139 |
if (s.length() == 0) return 0; |
if (s.length() == 0) return 0; |
140 |
|
|
141 |
HChain ch = getChain(s); |
HChain ch = getChain(s); |
142 |
final HBroken br = breaker.breakLines(ch, width*scale, scale); |
HBroken br = breaker.breakLines(ch, width, scale); |
143 |
|
|
144 |
int pos = 0; |
int pos = 0; |
145 |
int line = 0; |
int line = 0; |
182 |
return pos; |
return pos; |
183 |
} |
} |
184 |
|
|
185 |
/** Get coordinates before the given character position. |
/** |
186 |
* The Y coordinate is located below the line. |
* Get the coordinates before the given character position. |
187 |
|
* The Y coordinate will be located just below the the line. |
188 |
*/ |
*/ |
189 |
public void getXY(ConstGraph g, Object node, int pos, float[] xy) { |
public void getXY(ConstGraph g, Object node, int pos, float[] xy) { |
190 |
Enfilade1D enf = (Enfilade1D)nodeContent.f(g, node); |
Enfilade1D enf = (Enfilade1D)nodeContent.f(g, node); |
191 |
final Object objNode = node; |
Object objNode = node; |
192 |
String s = enf.makeString(); |
getXY(enf.makeString(), pos, xy); |
193 |
|
} |
194 |
|
public void getXY(String s, int pos, float[] xy) { |
195 |
if (s.length() == 0) { |
if (s.length() == 0) { |
196 |
if (xy != null && xy.length >= 2) { |
if (xy != null && xy.length >= 2) { |
197 |
xy[0] = 0; |
xy[0] = 0; |
201 |
} |
} |
202 |
|
|
203 |
HChain ch = getChain(s); |
HChain ch = getChain(s); |
204 |
final HBroken br = breaker.breakLines(ch, width*scale, scale); |
HBroken br = breaker.breakLines(ch, width, scale); |
205 |
|
|
206 |
float xoffs[] = new float[1]; |
float xoffs[] = new float[1]; |
207 |
int line = br.getLine(pos, xoffs); |
int line = br.getLine(pos, xoffs); |
208 |
|
|
209 |
if (xy != null && xy.length >= 2) { |
if (xy != null && xy.length >= 2) { |
210 |
// XXX the x offs doesn't seem to be exact, when there is a lot of spaces |
// XXX the x offs doesn't seem to be exact, |
211 |
|
// when there is a lot of spaces. An old bug. |
212 |
xy[0] = xoffs[0]; |
xy[0] = xoffs[0]; |
213 |
xy[1] = br.getLineOffset(line); |
xy[1] = br.getLineOffset(line); |
214 |
} |
} |
215 |
} |
} |
216 |
|
|
217 |
public Object f(ConstGraph g, Object node) { |
protected HChain getChain(String s) { |
|
if (hasContext) { |
|
|
if (context == null) throw new Error("No context set"); |
|
|
context.toBePlaced(node, this); |
|
|
} |
|
|
|
|
|
Enfilade1D enf = (Enfilade1D)nodeContent.f(g, node); |
|
|
|
|
|
final Object objNode = node; |
|
|
String s = enf.makeString(); |
|
|
if (s.length() == 0) |
|
|
return new org.nongnu.libvob.lava.placeable.Placeable() { |
|
|
public void place(VobScene vs, int into) { |
|
|
} |
|
|
public float getWidth() { return 10; } |
|
|
public float getHeight() { return 10; } |
|
|
}; |
|
|
|
|
|
HChain ch = getChain(s); |
|
|
final HBroken br = breaker.breakLines(ch, width*scale, scale); |
|
|
final float height = br.getHeight(); |
|
|
|
|
|
final float width; |
|
|
if(br.getLineCount() > 1) { // Let's get the longest line |
|
|
float maxWidth = br.getLineWidth(0); |
|
|
for (int i=1; i<br.getLineCount(); i++) |
|
|
if (br.getLineWidth(i) > maxWidth) |
|
|
maxWidth = br.getLineWidth(i); |
|
|
width = maxWidth; |
|
|
} else width = br.getLineWidth(0); |
|
|
|
|
|
//final TextVob vob = new TextVob(style, s, false); |
|
|
//final float width = style.getWidth(s, scale); |
|
|
//final float height = style.getHeight(scale); |
|
|
|
|
|
if(dbg) { |
|
|
pa(" "+s+"' "+width+" "+height+" "+scale+" "+br); |
|
|
} |
|
|
|
|
|
return new org.nongnu.libvob.lava.placeable.Placeable() { |
|
|
public void place(VobScene vs, int into) { |
|
|
br.put(vs, into); |
|
|
} |
|
|
|
|
|
public float getWidth() { return width; } |
|
|
public float getHeight() { return height; } |
|
|
}; |
|
|
} |
|
|
|
|
|
|
|
|
protected HChain getChain(String s) { |
|
218 |
HChain ch = new LinebreakableChain(); |
HChain ch = new LinebreakableChain(); |
219 |
|
|
220 |
int pos = 0; |
int pos = 0; |
248 |
|
|
249 |
if(dbg) pa("addVobs: "+start+" "+end+" '"+s+"'"); |
if(dbg) pa("addVobs: "+start+" "+end+" '"+s+"'"); |
250 |
|
|
251 |
TextVob vob = new TextVob(style, s, false, key, color); |
TextVob vob = new TextVob(style, s, false, key, textColor); |
252 |
ch.addBox(vob); |
ch.addBox(vob); |
253 |
} |
} |
254 |
} |
} |