1 package org.joshy.html; 2 3 import java.util.List ; 4 import java.awt.Point ; 5 import java.awt.Rectangle ; 6 import java.awt.font.LineMetrics ; 7 import java.awt.Color ; 8 import java.awt.Graphics ; 9 import java.awt.Graphics2D ; 10 import java.awt.Font ; 11 12 import org.w3c.dom.Element ; 13 import org.w3c.dom.Node ; 14 import org.joshy.u; 15 16 import org.joshy.html.box.InlineBox; 17 import org.joshy.html.box.LineBox; 18 import org.joshy.html.box.*; 19 import org.joshy.html.Context; 20 import org.joshy.html.util.GraphicsUtil; 21 import org.joshy.html.util.TextUtil; 22 import org.joshy.html.util.FontUtil; 23 import org.joshy.html.util.InlineUtil; 24 import org.joshy.html.util.LineBreaker; 25 import org.joshy.html.painter.*; 26 27 public class InlineLayout extends BoxLayout { 28 29 30 public Box layoutChildren(Context c, Box box) { 31 if(!box.isAnonymous()) { 35 if(isBlockLayout(box.getElement(),c)) { 36 return super.layoutChildren(c,box); 37 } 38 } 39 40 int debug_counter = 0; 41 int childcount = 0; 42 BlockBox block = (BlockBox)box; 43 44 Rectangle bounds = new Rectangle (); 46 bounds.width = c.getExtents().width; 47 bounds.width -= box.margin.left + box.border.left + box.padding.left + 48 box.padding.right + box.border.right + box.margin.right; 49 bounds.x = 0; 50 bounds.y = 0; 51 bounds.height = 0; 52 int remaining_width = bounds.width; 53 54 LineBox curr_line = new LineBox(); 56 curr_line.x = bounds.x; 57 curr_line.width = 0; 59 Element elem = block.getElement(); 60 remaining_width = InlineUtil.doTextIndent(c,elem,remaining_width,curr_line); 61 LineBox prev_line = new LineBox(); 62 prev_line.y = bounds.y; 63 prev_line.height = 0; 64 InlineBox prev_inline = null; 65 66 if(c.getLeftTab().y > 0) { 68 c.getLeftTab().y -= c.placement_point.y; 69 } 70 if(c.getRightTab().y > 0) { 71 c.getRightTab().y -= c.placement_point.y; 72 } 73 if(c.getRightTab().y < 0) { 74 c.getRightTab().y = 0; 75 } 76 if(c.getLeftTab().y < 0) { 77 c.getLeftTab().y = 0; 78 } 79 80 InlineBox prev_align_inline = null; 81 List inline_node_list = null; 82 if(box.isAnonymous()) { 83 inline_node_list = ((AnonymousBlockBox)box).node_list; 84 } else { 85 inline_node_list = InlineUtil.getInlineNodeList(elem,elem,c); 86 } 87 88 Node current_node = InlineUtil.nextTextNode(inline_node_list); 90 TextUtil.stripWhitespace(c,current_node,elem); 91 92 remaining_width = adjustForTab(c, prev_line, remaining_width); 94 95 while(current_node != null) { 96 while(true) { 98 if(prev_inline != null && prev_inline.node == current_node) { 101 if(isReplaced(current_node)) { 105 break; 107 } 108 if(isFloatedBlock(current_node,c)) { 109 break; 110 } 111 if(InlineUtil.isBreak(current_node)) { 112 break; 113 } 114 if(prev_inline.end_index >= current_node.getNodeValue().length()) { 116 break; 119 } 120 } 121 if(bounds.width < 100) { 122 } 124 debug_counter++; 125 if(debug_counter > 143) { 126 u.on(); 127 u.p("previous inline = " + prev_inline); 128 u.p("current line = " + curr_line); 129 u.p("lines = "); 130 u.p("current node = " + current_node + " text= " + current_node.getNodeValue()); 132 u.p("rem width = " + remaining_width + " width " + bounds.width); 133 } 134 if(debug_counter > 143) { 135 u.p("element = " + elem); 136 org.joshy.x.p(elem); 137 u.p("previous inline = " + prev_inline); 138 u.p("current inline = " + curr_line); 139 u.p("lines = "); 140 u.p("db 1 hit"); 142 System.exit(-1); 143 } 144 InlineBox new_inline = this.calculateInline(c,current_node,remaining_width,bounds.width, 148 curr_line, prev_inline, elem, prev_align_inline); 149 151 if(new_inline.break_before && !new_inline.floated) { 153 remaining_width = bounds.width; 155 saveLine(curr_line, prev_line, elem, bounds.width, bounds.x, c, block); 156 bounds.height += curr_line.height; 157 prev_line = curr_line; 158 curr_line = new LineBox(); 159 curr_line.x = bounds.x; 160 remaining_width = adjustForTab(c, prev_line, remaining_width); 164 curr_line.width = 0; 166 } 167 168 curr_line.addChild(new_inline); 170 171 if(!isFloated(new_inline,c)) { 175 if(!this.isFloatedBlock(new_inline.node,c)) { 176 if(new_inline.height + new_inline.y > curr_line.height) { 177 curr_line.height = new_inline.height + new_inline.y; 178 } 179 if(new_inline.baseline > curr_line.baseline) { 180 curr_line.baseline = new_inline.baseline; 181 } 182 } 183 } 184 185 InlineUtil.handleFloated(c, new_inline, curr_line, bounds.width, elem); 186 187 curr_line.width += new_inline.width; 189 remaining_width = remaining_width - new_inline.width; 191 if(new_inline.break_after) { 193 remaining_width = bounds.width; 195 saveLine(curr_line, prev_line,elem,bounds.width,bounds.x,c,block); 199 bounds.height += curr_line.height; 200 prev_line = curr_line; 202 curr_line = new LineBox(); 203 curr_line.x = bounds.x; 204 remaining_width = adjustForTab(c, prev_line, remaining_width); 208 curr_line.width = 0; 210 } 212 213 if(!isFloated(new_inline,c)) { 215 prev_align_inline = new_inline; 216 } else { 217 prev_align_inline = prev_inline; 218 } 219 prev_inline = new_inline; 220 } 221 current_node = InlineUtil.nextTextNode(inline_node_list); 222 TextUtil.stripWhitespace(c,current_node,elem); 223 } 224 225 saveLine(curr_line,prev_line,elem,bounds.width,bounds.x,c,block); 226 bounds.height += curr_line.height; 228 229 block.width = bounds.width; 230 block.height = bounds.height; 231 block.x = 0; 232 block.y = 0; 233 c.getLeftTab().y += c.placement_point.y; 237 c.getRightTab().y += c.placement_point.y; 238 return block; 242 } 243 244 245 private int adjustForTab(Context c, LineBox prev_line, int remaining_width) { 246 if(prev_line.y < c.getLeftTab().y) { 247 remaining_width -= c.getLeftTab().x; 248 } 250 if(prev_line.y + prev_line.height < c.getRightTab().y) { 251 remaining_width -= c.getRightTab().x; 252 } 254 return remaining_width; 255 } 256 257 258 259 private InlineBox calculateInline(Context c, Node node, int avail, int max_width, 261 LineBox line, InlineBox prev, Element containing_block, InlineBox prev_align) { 262 int start = 0; 265 if(prev != null && prev.node == node) { 266 start = prev.end_index; 267 } 268 269 String text = node.getNodeValue(); 271 274 text = TextUtil.transformText(c,node,text); 278 280 if(isReplaced(node)) { 281 return LineBreaker.generateReplacedInlineBox(c,node,avail,prev, text,prev_align); 282 } 283 if(isFloatedBlock(node,c)) { 284 return LineBreaker.generateFloatedBlockInlineBox(c,node,avail,prev, text,prev_align); 285 } 286 if(InlineUtil.isBreak(node)) { 287 return LineBreaker.generateBreakInlineBox(node); 288 } 289 if(LineBreaker.isWhitespace(c,containing_block)) { 290 return LineBreaker.generateWhitespaceInlineBox(c,node,start,prev,text,prev_align); 291 } 292 if(LineBreaker.isUnbreakableLine(c,node,start,text,avail)) { 294 return LineBreaker.generateUnbreakableInlineBox(c,node,start,text,prev,prev_align); 295 } 296 if(LineBreaker.canFitOnLine(c,node,start,text,avail)) { 298 return LineBreaker.generateRestOfTextNodeInlineBox(c,node,start,text,prev,prev_align); 299 } 300 return LineBreaker.generateMultilineBreak(c,node,start,text,prev,prev_align,avail); 302 } 303 304 305 306 307 private void saveLine(LineBox line_to_save, LineBox prev_line, Element containing_block, int width, int x, 308 Context c, BlockBox block) { 309 310 311 313 String text_align = c.css.getStringProperty(containing_block,"text-align"); 315 if(text_align != null) { 317 if(text_align.equals("right")) { 318 line_to_save.x = x + width - line_to_save.width; 321 } 324 if(text_align.equals("center")) { 325 line_to_save.x = x + (width - line_to_save.width)/2; 326 } 327 } 328 329 line_to_save.y = prev_line.y + prev_line.height; 331 332 if(line_to_save.y < c.getLeftTab().y) { 336 line_to_save.x+= c.getLeftTab().x; 337 } 341 345 if(c.getRightTab().y >0) { 346 } 351 355 FontUtil.setupVerticalAlign(c,containing_block,line_to_save); 356 block.addChild(line_to_save); 357 } 360 361 362 public void paintComponent(Context c, Box box) { 363 if(box.isAnonymous()) { 366 InlinePainter.paintInlineContext(c,box); 368 return; 369 } 370 if(this.isBlockLayout(box.getElement(),c)) { 371 super.paintComponent(c,box); 373 return; 374 } 375 InlinePainter.paintInlineContext(c,box); 377 } 378 379 380 public void paintChildren(Context c, Box box) { 381 if(box.isAnonymous()) { 383 return; 385 } 386 if(this.isBlockLayout(box.getElement(),c)) { 387 super.paintChildren(c,box); 389 } 390 } 391 392 } 393 394 | Popular Tags |