@Override
 protected void startNewPage() {
   super.startNewPage();
   pagebox = createBlock(body, curpage, false);
   pagebox.setStyle(createPageStyle());
   body.addSubBox(pagebox);
 }
 @Override
 protected void renderImage(
     float x, float y, float width, float height, String mimetype, byte[] data) {
   // DOM element
   Element el = createImageElement(x, y, width, height, mimetype, data);
   curpage.appendChild(el);
   // Image box
   BlockBox block = createBlock(pagebox, el, true);
   block.setStyle(createRectangleStyle(x, y, width, height, false, false));
   pagebox.addSubBox(block);
 }
 /**
  * Creates a text box with the given parent and text node assigned.
  *
  * @param contblock The parent node (and the containing block in the same time)
  * @param n The corresponding text node in the DOM tree.
  * @return The new text box.
  */
 protected TextBox createTextBox(BlockBox contblock, Text n) {
   TextBox text =
       new TextBox(
           n,
           (Graphics2D) contblock.getGraphics().create(),
           contblock.getVisualContext().create());
   text.setOrder(next_order++);
   text.setContainingBlock(contblock);
   text.setClipBlock(viewport);
   text.setViewport(viewport);
   text.setBase(baseurl);
   return text;
 }
 @Override
 protected void renderText(String data) {
   // DOM element
   Element el = createTextElement(data);
   curpage.appendChild(el);
   // Block box
   BlockBox block = createBlock(pagebox, el, false);
   block.setStyle(createTextStyle(curstyle));
   pagebox.addSubBox(block);
   // Text box
   TextBox text = createTextBox(block, (Text) el.getFirstChild());
   block.addSubBox(text);
 }
 @Override
 protected void createDocument() throws ParserConfigurationException {
   super.createDocument();
   // create viewport with the initial dimension
   Element vp = createAnonymousElement(getDocument(), "Xdiv", "block");
   Element root = getDocument().getDocumentElement();
   viewport = new Viewport(vp, g, ctx, null, root, dim.width, dim.height);
   viewport.setConfig(config);
   // create the root boxes
   html = createBlock(viewport, root, false);
   html.setStyle(createBlockStyle());
   viewport.addSubBox(html);
   body = createBlock(html, (Element) root.getElementsByTagName("body").item(0), false);
   body.setStyle(createBodyStyle());
   html.addSubBox(body);
 }
 @Override
 protected void renderPath(List<PathSegment> path, boolean stroke, boolean fill) {
   float[] rect = toRectangle(path);
   if (rect != null) {
     // DOM element
     Element el =
         createRectangleElement(
             rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1], stroke, fill);
     curpage.appendChild(el);
     // Block box
     BlockBox block = createBlock(pagebox, el, false);
     block.setStyle(
         createRectangleStyle(
             rect[0], rect[1], rect[2] - rect[0], rect[3] - rect[1], stroke, fill));
     pagebox.addSubBox(block);
   } else if (stroke) {
     for (PathSegment segm : path) {
       if (segm.getX1() == segm.getX2() || segm.getY1() == segm.getY2()) {
         // DOM element
         Element el = createLineElement(segm.getX1(), segm.getY1(), segm.getX2(), segm.getY2());
         curpage.appendChild(el);
         // Block box
         BlockBox block = createBlock(pagebox, el, false);
         block.setStyle(createLineStyle(segm.getX1(), segm.getY1(), segm.getX2(), segm.getY2()));
         pagebox.addSubBox(block);
       } else log.warn("Skipped non-orthogonal line segment");
     }
   }
 }
 /**
  * Creates a new block box from the given element with the given parent. No style is assigned to
  * the resulting box.
  *
  * @param parent The parent box in the tree of boxes.
  * @param n The element that this box belongs to.
  * @param replaced When set to <code>true</code>, a replaced block box will be created. Otherwise,
  *     a normal non-replaced block will be created.
  * @return The new block box.
  */
 protected BlockBox createBlock(BlockBox parent, Element n, boolean replaced) {
   BlockBox root;
   if (replaced) {
     BlockReplacedBox rbox =
         new BlockReplacedBox(
             (Element) n,
             (Graphics2D) parent.getGraphics().create(),
             parent.getVisualContext().create());
     rbox.setViewport(viewport);
     rbox.setContentObj(
         new ReplacedImage(rbox, rbox.getVisualContext(), baseurl, n.getAttribute("src")));
     root = rbox;
   } else {
     root =
         new BlockBox(
             (Element) n,
             (Graphics2D) parent.getGraphics().create(),
             parent.getVisualContext().create());
     root.setViewport(viewport);
   }
   root.setBase(baseurl);
   root.setParent(parent);
   root.setContainingBlock(parent);
   root.setClipBlock(viewport);
   root.setOrder(next_order++);
   return root;
 }