ShapeOutsideDeltas ShapeOutsideInfo::computeDeltasForContainingBlockLine( const LineLayoutBlockFlow& containingBlock, const FloatingObject& floatingObject, LayoutUnit lineTop, LayoutUnit lineHeight) { ASSERT(lineHeight >= 0); LayoutUnit borderBoxTop = containingBlock.logicalTopForFloat(floatingObject) + containingBlock.marginBeforeForChild(m_layoutBox); LayoutUnit borderBoxLineTop = lineTop - borderBoxTop; if (isShapeDirty() || !m_shapeOutsideDeltas.isForLine(borderBoxLineTop, lineHeight)) { LayoutUnit referenceBoxLineTop = borderBoxLineTop - logicalTopOffset(); LayoutUnit floatMarginBoxWidth = std::max( containingBlock.logicalWidthForFloat(floatingObject), LayoutUnit()); if (computedShape().lineOverlapsShapeMarginBounds(referenceBoxLineTop, lineHeight)) { LineSegment segment = computedShape().getExcludedInterval( (borderBoxLineTop - logicalTopOffset()), std::min(lineHeight, shapeLogicalBottom() - borderBoxLineTop)); if (segment.isValid) { LayoutUnit logicalLeftMargin = containingBlock.style()->isLeftToRightDirection() ? containingBlock.marginStartForChild(m_layoutBox) : containingBlock.marginEndForChild(m_layoutBox); LayoutUnit rawLeftMarginBoxDelta( segment.logicalLeft + logicalLeftOffset() + logicalLeftMargin); LayoutUnit leftMarginBoxDelta = clampTo<LayoutUnit>( rawLeftMarginBoxDelta, LayoutUnit(), floatMarginBoxWidth); LayoutUnit logicalRightMargin = containingBlock.style()->isLeftToRightDirection() ? containingBlock.marginEndForChild(m_layoutBox) : containingBlock.marginStartForChild(m_layoutBox); LayoutUnit rawRightMarginBoxDelta( segment.logicalRight + logicalLeftOffset() - containingBlock.logicalWidthForChild(m_layoutBox) - logicalRightMargin); LayoutUnit rightMarginBoxDelta = clampTo<LayoutUnit>( rawRightMarginBoxDelta, -floatMarginBoxWidth, LayoutUnit()); m_shapeOutsideDeltas = ShapeOutsideDeltas(leftMarginBoxDelta, rightMarginBoxDelta, true, borderBoxLineTop, lineHeight); return m_shapeOutsideDeltas; } } // Lines that do not overlap the shape should act as if the float // wasn't there for layout purposes. So we set the deltas to remove the // entire width of the float. m_shapeOutsideDeltas = ShapeOutsideDeltas(floatMarginBoxWidth, -floatMarginBoxWidth, false, borderBoxLineTop, lineHeight); } return m_shapeOutsideDeltas; }
LayoutUnit ShapeInsideInfo::computeFirstFitPositionForFloat(const FloatSize& floatSize) const { if (!computedShape() || !floatSize.width() || shapeLogicalBottom() < logicalLineTop()) return 0; LayoutUnit firstFitPosition = 0; if (computedShape()->firstIncludedIntervalLogicalTop(m_shapeLineTop, floatSize, firstFitPosition) && (m_shapeLineTop <= firstFitPosition)) return firstFitPosition; return 0; }
bool ExclusionShapeInsideInfo::computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight) { ASSERT(lineHeight >= 0); m_lineTop = lineTop; m_lineHeight = lineHeight; m_segments.clear(); m_segmentRanges.clear(); if (lineOverlapsShapeBounds()) { ASSERT(m_shape); m_shape->getIncludedIntervals(lineTop, std::min(lineHeight, shapeLogicalBottom() - lineTop), m_segments); } return m_segments.size(); }
SegmentList ShapeInfo<RenderType>::computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight) const { ASSERT(lineHeight >= 0); SegmentList segments; getIntervals((lineTop - logicalTopOffset()), std::min(lineHeight, shapeLogicalBottom() - lineTop), segments); for (size_t i = 0; i < segments.size(); i++) { segments[i].logicalLeft += logicalLeftOffset(); segments[i].logicalRight += logicalLeftOffset(); } return segments; }
bool ExclusionShapeInsideInfo::adjustLogicalLineTop(float minSegmentWidth) { if (!m_shape || m_lineHeight <= 0 || m_lineTop > shapeLogicalBottom()) return false; float floatNewLineTop; if (m_shape->firstIncludedIntervalLogicalTop(m_lineTop, FloatSize(minSegmentWidth, m_lineHeight), floatNewLineTop)) { LayoutUnit newLineTop = floatLogicalTopToLayoutUnit(floatNewLineTop); if (newLineTop > m_lineTop) { m_lineTop = newLineTop; return true; } } return false; }
bool ExclusionShapeInsideInfo::adjustLogicalLineTop(float minSegmentWidth) { const ExclusionShape* shape = computedShape(); if (!shape || m_lineHeight <= 0 || logicalLineTop() > shapeLogicalBottom()) return false; LayoutUnit newLineTop; if (shape->firstIncludedIntervalLogicalTop(m_shapeLineTop, LayoutSize(minSegmentWidth, m_lineHeight), newLineTop)) { if (newLineTop > m_shapeLineTop) { m_shapeLineTop = newLineTop; return true; } } return false; }
bool ShapeInfo<RenderType, shapeGetter, intervalGetter>::computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight) { ASSERT(lineHeight >= 0); m_shapeLineTop = lineTop - logicalTopOffset(); m_lineHeight = lineHeight; m_segments.clear(); if (lineOverlapsShapeBounds()) (computedShape()->*intervalGetter)(m_shapeLineTop, std::min(m_lineHeight, shapeLogicalBottom() - lineTop), m_segments); LayoutUnit logicalLeftOffset = this->logicalLeftOffset(); for (size_t i = 0; i < m_segments.size(); i++) { m_segments[i].logicalLeft += logicalLeftOffset; m_segments[i].logicalRight += logicalLeftOffset; } return m_segments.size(); }
void ShapeOutsideInfo::updateDeltasForContainingBlockLine(const RenderBlockFlow& containingBlock, const FloatingObject& floatingObject, LayoutUnit lineTop, LayoutUnit lineHeight) { ASSERT(lineHeight >= 0); LayoutUnit borderBoxTop = containingBlock.logicalTopForFloat(&floatingObject) + containingBlock.marginBeforeForChild(m_renderer); LayoutUnit borderBoxLineTop = lineTop - borderBoxTop; if (isShapeDirty() || m_borderBoxLineTop != borderBoxLineTop || m_lineHeight != lineHeight) { m_borderBoxLineTop = borderBoxLineTop; m_referenceBoxLineTop = borderBoxLineTop - logicalTopOffset(); m_lineHeight = lineHeight; LayoutUnit floatMarginBoxWidth = containingBlock.logicalWidthForFloat(&floatingObject); if (computedShape().lineOverlapsShapeMarginBounds(m_referenceBoxLineTop, m_lineHeight)) { LineSegment segment = computedShape().getExcludedInterval((borderBoxLineTop - logicalTopOffset()), std::min(lineHeight, shapeLogicalBottom() - borderBoxLineTop)); if (segment.isValid) { LayoutUnit logicalLeftMargin = containingBlock.style().isLeftToRightDirection() ? containingBlock.marginStartForChild(m_renderer) : containingBlock.marginEndForChild(m_renderer); LayoutUnit rawLeftMarginBoxDelta = segment.logicalLeft + logicalLeftOffset() + logicalLeftMargin; m_leftMarginBoxDelta = clampTo<LayoutUnit>(rawLeftMarginBoxDelta, LayoutUnit(), floatMarginBoxWidth); LayoutUnit logicalRightMargin = containingBlock.style().isLeftToRightDirection() ? containingBlock.marginEndForChild(m_renderer) : containingBlock.marginStartForChild(m_renderer); LayoutUnit rawRightMarginBoxDelta = segment.logicalRight + logicalLeftOffset() - containingBlock.logicalWidthForChild(m_renderer) - logicalRightMargin; m_rightMarginBoxDelta = clampTo<LayoutUnit>(rawRightMarginBoxDelta, -floatMarginBoxWidth, LayoutUnit()); m_lineOverlapsShape = true; return; } } // Lines that do not overlap the shape should act as if the float // wasn't there for layout purposes. So we set the deltas to remove the // entire width of the float m_leftMarginBoxDelta = floatMarginBoxWidth; m_rightMarginBoxDelta = -floatMarginBoxWidth; m_lineOverlapsShape = false; } }