void InlineBlockBox::handleLayout(LayoutEngine& eng, const Dimensions& containing) { eng.setCursor(cursor_); layoutChildren(eng); layoutHeight(containing); if(isReplaceable()) { NodePtr node = getNode(); node->setDimensions(rect(0, 0, getWidth() / LayoutEngine::getFixedPointScale(), getHeight() / LayoutEngine::getFixedPointScale())); } // try and fit the box at cursor, failing that we move the cursor and try again. FixedPoint width_at_cursor = eng.getWidthAtPosition(eng.getCursor().y, eng.getCursor().y + getHeight() + getMBPHeight(), containing.content_.width) - eng.getCursor().x + eng.getXAtPosition(eng.getCursor().y, eng.getCursor().y + getHeight() + getMBPHeight()); if(getWidth() + getMBPWidth() > width_at_cursor) { point p = eng.getCursor(); p.y += getLineHeight(); while(eng.hasFloatsAtPosition(p.y, p.y + getHeight() + getMBPHeight()) && getWidth() + getMBPWidth() > width_at_cursor) { width_at_cursor = eng.getWidthAtPosition(p.y, p.y + getHeight() + getMBPHeight(), containing.content_.width); } p.x = eng.getXAtPosition(p.y, p.y + getHeight() + getMBPHeight()); setContentX(p.x); setContentY(p.y); p.y += getHeight() + getMBPHeight(); p.x = eng.getXAtPosition(p.y, p.y + getLineHeight()); eng.setCursor(p); } else { setContentX(eng.getCursor().x); // XXX if height is greater than other objects on line we need to increase lineheight. setContentY(eng.getCursor().y); eng.setCursor(point(getLeft() + getWidth() + getMBPRight(), eng.getCursor().y)); } }
void TextBox::handleLayout(LayoutEngine& eng, const Dimensions& containing) { // TextBox's have no children to deal with, by definition. // XXX fix the point() to be the actual last point, say from LayoutEngine point cursor = reflowText(eng, containing, eng.getCursor()); eng.setCursor(cursor); calculateHorzMPB(containing.content_.width); calculateVertMPB(containing.content_.height); }
void InlineBlockBox::handlePreChildLayout2(LayoutEngine& eng, const Dimensions& containing) { cursor_ = eng.getCursor(); eng.setCursor(point(0, 0)); if(!getChildren().empty() || !isReplaceable()) { setContentHeight(0); } else if(isReplaceable()) { NodePtr node = getNode(); const rect& r = node->getDimensions(); setContentWidth(r.w() * LayoutEngine::getFixedPointScale()); setContentHeight(r.h() * LayoutEngine::getFixedPointScale()); } }
void Box::layout(LayoutEngine& eng, const Dimensions& ocontaining) { auto containing = ocontaining; auto styles = getStyleNode(); std::unique_ptr<LayoutEngine::FloatContextManager> fcm; if(getParent() && getParent()->isFloat()) { fcm.reset(new LayoutEngine::FloatContextManager(eng, FloatList())); } point cursor; // If we have a clear flag set, then move the cursor in the layout engine to clear appropriate floats. if(node_ != nullptr) { eng.moveCursorToClearFloats(node_->getClear(), cursor); } NodePtr node = getNode(); std::unique_ptr<RenderContext::Manager> ctx_manager; if(node != nullptr) { ctx_manager.reset(new RenderContext::Manager(node->getProperties())); } if(styles != nullptr) { auto ovf = styles->getOverflow(); // this is kind of a hack, since we really want to avoid re-running layout //if(ovf == Overflow::SCROLL || ovf == Overflow::AUTO) { containing.content_.width -= scrollbar_default_width * LayoutEngine::getFixedPointScale(); //} } handlePreChildLayout(eng, containing); if(node_ != nullptr) { const std::vector<StyleNodePtr>& node_children = node_->getChildren(); if(!node_children.empty()) { boxes_ = eng.layoutChildren(node_children, shared_from_this()); } } for(auto& child : boxes_) { if(child->isFloat()) { handlePreChildLayout3(eng, containing); child->layout(eng, dimensions_); handlePostFloatChildLayout(eng, child); eng.addFloat(child); } } offset_ = (getParent() != nullptr ? getParent()->getOffset() : point()) + point(dimensions_.content_.x, dimensions_.content_.y); if(isBlockBox()) { const FixedPoint y1 = offset_.y; point p(eng.getXAtPosition(y1, y1 + getLineHeight()), 0); eng.setCursor(p); } handlePreChildLayout2(eng, containing); for(auto& child : boxes_) { if(!child->isFloat()) { handlePreChildLayout3(eng, containing); child->layout(eng, dimensions_); handlePostChildLayout(eng, child); } } handleLayout(eng, containing); //layoutAbsolute(eng, containing); for(auto& child : boxes_) { child->postParentLayout(eng, dimensions_); } // need to call this after doing layout, since we need to now what the computed padding/border values are. border_info_.init(dimensions_); background_info_.init(dimensions_); if(isBlockBox() && !isFloat()) { point p; p.y = getTop() + getHeight() + getMBPBottom(); p.x = eng.getXAtPosition(p.y, p.y + getLineHeight()); eng.setCursor(p); } precss_content_height_ = dimensions_.content_.height; if(isBlockBox() && styles != nullptr) { auto css_h = styles->getHeight(); if(!css_h->isAuto()) { setContentHeight(css_h->getLength().compute(containing.content_.height)); } } eng.closeLineBox(); }