void BlockBox::handleLayout(LayoutEngine& eng, const Dimensions& containing) { if(isReplaceable()) { layoutChildren(eng); } else { layoutChildren(eng); layoutHeight(containing); } if(isFloat()) { FixedPoint top = 0; const FixedPoint lh = getStyleNode()->getHeight()->isAuto() ? getLineHeight() : getStyleNode()->getHeight()->getLength().compute(containing.content_.height); const FixedPoint box_w = getDimensions().content_.width; FixedPoint y = 0; FixedPoint x = 0; FixedPoint y1 = y + getOffset().y; FixedPoint left = getStyleNode()->getFloat() == Float::LEFT ? eng.getXAtPosition(y1, y1 + lh) + x : eng.getX2AtPosition(y1, y1 + lh); FixedPoint w = eng.getWidthAtPosition(y1, y1 + lh, containing.content_.width); bool placed = false; while(!placed) { if(w >= box_w) { left = left - (getStyleNode()->getFloat() == Float::LEFT ? x : box_w) + getMBPLeft(); top = y + getMBPTop() + containing.content_.height; placed = true; } else { y += lh; y1 = y + getOffset().y; left = getStyleNode()->getFloat() == Float::LEFT ? eng.getXAtPosition(y1, y1 + lh) + x : eng.getX2AtPosition(y1, y1 + lh); w = eng.getWidthAtPosition(y1, y1 + lh, containing.content_.width); } } setContentX(left); setContentY(top); } else { for(auto& child : getChildren()) { setContentHeight(child->getTop() + child->getHeight() + child->getMBPBottom()); } } }
void ListItemBox::handleLayout(LayoutEngine& eng, const Dimensions& containing) { auto lst = getStyleNode()->getListStyleType(); switch(lst) { case ListStyleType::DISC: /* is the default */ break; case ListStyleType::CIRCLE: marker_ = utils::codepoint_to_utf8(marker_circle); break; case ListStyleType::SQUARE: marker_ = utils::codepoint_to_utf8(marker_square); break; case ListStyleType::DECIMAL: { std::ostringstream ss; ss << std::dec << count_ << "."; marker_ = ss.str(); break; } case ListStyleType::DECIMAL_LEADING_ZERO: { std::ostringstream ss; ss << std::dec << std::setfill('0') << std::setw(2) << count_ << "."; marker_ = ss.str(); break; } case ListStyleType::LOWER_ROMAN: if(count_ < 4000) { marker_ = to_roman(count_, true) + "."; } break; case ListStyleType::UPPER_ROMAN: if(count_ < 4000) { marker_ = to_roman(count_, false) + "."; } break; case ListStyleType::LOWER_GREEK: if(count_ <= (marker_lower_greek_end - marker_lower_greek + 1)) { marker_ = utils::codepoint_to_utf8(marker_lower_greek + count_) + "."; } break; case ListStyleType::LOWER_ALPHA: case ListStyleType::LOWER_LATIN: if(count_ <= (marker_lower_latin_end - marker_lower_latin + 1)) { marker_ = utils::codepoint_to_utf8(marker_lower_latin + count_) + "."; } break; case ListStyleType::UPPER_ALPHA: case ListStyleType::UPPER_LATIN: if(count_ <= (marker_upper_latin_end - marker_upper_latin + 1)) { marker_ = utils::codepoint_to_utf8(marker_upper_latin + count_) + "."; } break; case ListStyleType::ARMENIAN: if(count_ <= (marker_armenian_end - marker_armenian + 1)) { marker_ = utils::codepoint_to_utf8(marker_armenian + count_) + "."; } break; case ListStyleType::GEORGIAN: if(count_ <= (marker_georgian_end - marker_georgian + 1)) { marker_ = utils::codepoint_to_utf8(marker_georgian + count_) + "."; } break; case ListStyleType::NONE: default: marker_.clear(); break; } FixedPoint top = getMBPTop() + containing.content_.height; FixedPoint left = getMBPLeft(); if(isFloat()) { // XXX fixme to use a more intelligent approach than iterating every pixel! const FixedPoint lh = 65536;//getDimensions().content_.height; const FixedPoint box_w = getDimensions().content_.width; FixedPoint y = getMBPTop(); FixedPoint x = getMBPLeft(); FixedPoint y1 = y + getOffset().y; left = getStyleNode()->getFloat() == Float::LEFT ? eng.getXAtPosition(y1, y1 + lh) + x : eng.getX2AtPosition(y1, y1 + lh); FixedPoint w = eng.getWidthAtPosition(y1, y1 + lh, containing.content_.width); bool placed = false; while(!placed) { if(w >= box_w) { left = left - (getStyleNode()->getFloat() == Float::LEFT ? x : box_w); top = y; placed = true; } else { y += lh; y1 = y + getOffset().y; left = getStyleNode()->getFloat() == Float::LEFT ? eng.getXAtPosition(y1, y1 + lh) + x : eng.getX2AtPosition(y1, y1 + lh); w = eng.getWidthAtPosition(y1, y1 + lh, containing.content_.width); } } } setContentX(left); setContentY(top); auto& css_height = getStyleNode()->getHeight(); if(!css_height->isAuto()) { FixedPoint h = css_height->getLength().compute(containing.content_.height); //if(h > child_height_) { // /* apply overflow properties */ //} setContentHeight(h); } }