KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > joshy > html > util > LineBreaker


1 package org.joshy.html.util;
2
3 import org.w3c.dom.*;
4 import org.joshy.html.box.*;
5 import org.joshy.u;
6 import org.joshy.html.*;
7 import java.awt.Rectangle JavaDoc;
8
9
10
11 public class LineBreaker {
12 public static InlineBox generateMultilineBreak(Context c, Node node, int start, String JavaDoc text,
13     InlineBox prev, InlineBox prev_align, int avail) {
14     //u.p("normal breaking");
15
// calc end index to most words that will fit
16
int end = start;
17     int dbcount = 0;
18     while(true) {
19         dbcount++;
20         //u.off();
21
u.on();
22         if(dbcount > 50) {
23             u.on();
24         }
25         if(dbcount>100) {
26             u.on();
27             u.p("db 2 hit");
28             u.p("text = " + text);
29             u.p("end = " + end);
30             System.exit(-1);
31         }
32
33         //u.p("end = " + end);
34
int next_space = text.indexOf(" ",end);
35         if(next_space == -1) { next_space = text.length(); }
36         //u.p("next space = " + next_space);
37
try {
38             //u.p("end = " + end + " next space = " + next_space + " text = " + text.substring(end,next_space));
39
} catch (Exception JavaDoc ex) {
40             u.p(ex);
41             System.exit(-1);
42         }
43         int len2 = FontUtil.len(c,node,text.substring(start,next_space));
44         //u.p("len2 = " + len2 + " avail = " + avail);
45
// if this won't fit, then break and use the previous span
46
if(len2 > avail) {
47             InlineBox box = newBox(c, node, start, end, prev, text, prev_align);
48             //u.p("normal break returning span: " + box);
49
return box;
50         }
51         // if this will fit but we are at the end then break and use current span
52
if(next_space == text.length()) {
53             InlineBox box = newBox(c, node, start, next_space, prev, text, prev_align);
54             //u.p("normal break returning curr span: " + box);
55
return box;
56         }
57         // skip over the space
58
end = next_space + 1;
59     }
60 }
61
62 public static boolean canFitOnLine(Context c, Node node, int start, String JavaDoc text, int avail) {
63     // if the rest of text can fit on the current line
64
// if length of remaining text < available width
65
//u.p("avail = " + avail + " len = " + FontUtil.len(c,node,text.substring(start)));
66
if(FontUtil.len(c,node,text.substring(start)) < avail) {
67         return true;
68     } else {
69         return false;
70     }
71 }
72 public static InlineBox generateRestOfTextNodeInlineBox(Context c, Node node, int start, String JavaDoc text,
73     InlineBox prev, InlineBox prev_align) {
74         InlineBox box = newBox(c,node,start,text.length(),prev,text, prev_align);
75         // turn off breaking since more might fit on this line
76
box.break_after = false;
77         //u.p("fits on line returning : " + box);
78
return box;
79 }
80
81 public static boolean isUnbreakableLine(Context c, Node node, int start, String JavaDoc text, int avail) {
82     int first_word_index = text.indexOf(" ",start);
83     if(first_word_index == -1) {
84         first_word_index = text.length();
85     }
86     String JavaDoc first_word = text.substring(start,first_word_index);
87     first_word = first_word.trim();
88     if(avail < FontUtil.len(c, node, first_word)) {
89         return true;
90     } else {
91         return false;
92     }
93 }
94
95
96 public static InlineBox generateUnbreakableInlineBox(Context c, Node node, int start, String JavaDoc text, InlineBox prev, InlineBox prev_align) {
97     int first_word_index = text.indexOf(" ",start);
98     if(first_word_index == -1) {
99         first_word_index = text.length();
100     }
101     String JavaDoc first_word = text.substring(start,first_word_index);
102     first_word = first_word.trim();
103     InlineBox box = newBox(c, node, start, first_word_index, prev, text, prev_align);
104     // move back to the left margin since this is on it's own line
105
box.x = 0;
106     box.break_before = true;
107     //u.p("unbreakable long word returning: " + box);
108
box.break_after = true;
109     return box;
110 }
111
112 public static boolean isWhitespace(Context c, Element containing_block) {
113     String JavaDoc white_space = c.css.getStringProperty(containing_block,"white-space");
114     // if doing preformatted whitespace
115
if(white_space!=null && white_space.equals("pre")) {
116         return true;
117     } else {
118         return false;
119     }
120 }
121
122 public static InlineBox generateWhitespaceInlineBox(Context c, Node node, int start,
123     InlineBox prev, String JavaDoc text, InlineBox prev_align) {
124         //u.p("preformatted text");
125
int cr_index = text.indexOf("\n",start+1);
126         //u.p("cr_index = " + cr_index);
127
if(cr_index == -1) {
128             cr_index = text.length();
129         }
130         InlineBox box = newBox(c,node,start,cr_index,prev,text, prev_align);
131         return box;
132 }
133
134 public static InlineBox generateBreakInlineBox(Node node) {
135     InlineBox box = new InlineBox();
136     box.node = node;
137     box.width = 0;
138     box.height = 0;
139     box.break_after = true;
140     box.x = 0;
141     box.y = 0;
142     box.is_break = true;
143     return box;
144 }
145
146 // change this to use the existing block instead of a new one
147
public static InlineBox generateFloatedBlockInlineBox(Context c, Node node, int avail, InlineBox prev, String JavaDoc text, InlineBox prev_align) {
148     Layout layout = LayoutFactory.getLayout(node);
149     Rectangle JavaDoc oe = c.getExtents();
150     c.setExtents(new Rectangle JavaDoc(oe));
151     BlockBox block = (BlockBox) layout.layout(c,(Element)node);
152     Rectangle JavaDoc bounds = new Rectangle JavaDoc(block.x,block.y,block.width,block.height);
153     c.setExtents(oe);
154     InlineBox box = newBox(c,node,0,0,prev,text,bounds,prev_align);
155     box.sub_block = block;
156     box.width = bounds.width;
157     box.height = bounds.height;
158     box.break_after = false;
159     if(box.width > avail) {
160         box.break_before = true;
161         box.x = 0;
162     }
163     return box;
164 }
165
166     // change this to use the existing block instead of a new one
167
public static InlineBox generateReplacedInlineBox(Context c, Node node, int avail, InlineBox prev, String JavaDoc text, InlineBox prev_align) {
168     //u.p("generating replaced Inline Box");
169

170     // get the layout for the replaced element
171
Layout layout = LayoutFactory.getLayout(node);
172     BlockBox block = (BlockBox)layout.layout(c,(Element)node);
173     //u.p("got a block box from the sub layout: " + block);
174
Rectangle JavaDoc bounds = new Rectangle JavaDoc(block.x,block.y,block.width,block.height);
175     //u.p("bounds = " + bounds);
176
/* joshy: change this to just modify the existing block instead of creating
177     a new one*/

178     
179     // create new inline
180
InlineBox box = newBox(c,node,0,0,prev,text, bounds, prev_align);
181     //joshy: activate this: box.block = block
182
//u.p("created a new inline box");
183
box.replaced = true;
184     box.sub_block = block;
185     block.setParent(box);
186     
187     // set up the extents
188
box.width = bounds.width;
189     box.height = bounds.height;
190     box.break_after = false;
191     
192     // if it won't fit on this line, then put it on the next one
193
if(box.width > avail) {
194         box.break_before = true;
195         box.x = 0;
196     }
197     
198     // return
199
//u.p("last replaced = " + box);
200
return box;
201 }
202
203 private static InlineBox newBox(Context c, Node node,int start, int end, InlineBox prev, String JavaDoc text, InlineBox prev_align) {
204     return newBox(c,node,start,end,prev,text,null, prev_align);
205 }
206
207 // this function by itself takes up fully 29% of the complete program's
208
// rendering time.
209
private static InlineBox newBox(Context c, Node node,int start, int end, InlineBox prev, String JavaDoc text, Rectangle JavaDoc bounds, InlineBox prev_align) {
210     //u.p("newBox node = " + node.getNodeName() + " start = " + start + " end = " + end +
211
//" prev = " + prev + " text = " + text + " bounds = " + bounds + " prev_align = " + prev_align);
212
//u.p("Making box for: " + node);
213
//u.p("prev = " + prev);
214
if(prev_align != prev) {
215          //u.p("prev = " + prev);
216
//u.p("prev align inline = " + prev_align);
217
}
218     InlineBox box = new InlineBox();
219     box.node = node;
220     box.start_index = start;
221     box.end_index = end;
222     /*
223     if(prev!= null && !prev.break_after) {
224         box.x = prev.x + prev.width;
225     } else {
226         box.x = 0;
227     }
228     */

229
230     // use the prev_align to calculate the x
231
if(prev_align!= null && !prev_align.break_after) {
232         //u.p("moving over w/ prev = " + prev);
233
//u.p("moving over w/ prev align = " + prev_align);
234
box.x = prev_align.x + prev_align.width;
235     } else {
236         //u.p("setting x to 0");
237
box.x = 0;
238     }
239
240     box.y = 0; // it's relative to the line
241
try {
242         if(!InlineLayout.isReplaced(node)) {
243             if(!InlineLayout.isFloatedBlock(node,c)) {
244                 box.width = FontUtil.len(c,node,text.substring(start,end));
245             } else {
246                 box.width = bounds.width;
247             }
248         } else {
249             box.width = bounds.width;
250         }
251     } catch (StringIndexOutOfBoundsException JavaDoc ex) {
252         u.p("ex");
253         u.p("start = " + start);
254         u.p("end = " + end);
255         u.p("text = " + node.getNodeValue());
256         throw ex;
257     }
258     //u.p("box.x = " + box.x);
259
if(InlineLayout.isReplaced(node)) {
260         box.height = bounds.height;
261     } else if(InlineLayout.isFloatedBlock(node,c)) {
262         box.height = bounds.height;
263     } else {
264         box.height = FontUtil.lineHeight(c,node);
265     }
266     //u.p("box.x = " + box.x);
267
//box.baseline = box.height;
268
box.break_after = true;
269
270     box.text = text;
271     if(!InlineLayout.isReplaced(node)) {
272         if(!InlineLayout.isFloatedBlock(node,c)) {
273             FontUtil.setupTextDecoration(c,node,box);
274             if(box.text == null) {
275                 return box;
276             }
277         }
278     }
279     //u.p("box.x = " + box.x);
280

281     // do vertical alignment
282
//u.p("setting up vertical align on: " + node);
283
FontUtil.setupVerticalAlign(c,node,box);
284     box.setFont(FontUtil.getFont(c,node));
285     if(node.getNodeType()== node.TEXT_NODE) {
286         box.color = c.css.getColor((Element)node.getParentNode(),true);
287     } else {
288         box.color = c.css.getColor((Element)node,true);
289     }
290     InlineLayout.setupRelative(c,box);
291
292     //u.p("box.x = " + box.x);
293
//u.p("returning box: " + box);
294
//u.p("colo r= " + box.color);
295
return box;
296 }
297
298 }
299
Popular Tags