void ShapeOutsideInfo::updateDeltasForContainingBlockLine(const RenderBlockFlow* containingBlock, const FloatingObject* floatingObject, LayoutUnit lineTop, LayoutUnit lineHeight) { LayoutUnit shapeTop = containingBlock->logicalTopForFloat(floatingObject) + std::max(LayoutUnit(), containingBlock->marginBeforeForChild(*m_renderer)); LayoutUnit lineTopInShapeCoordinates = lineTop - shapeTop + logicalTopOffset(); if (shapeSizeDirty() || m_lineTop != lineTopInShapeCoordinates || m_lineHeight != lineHeight) { m_lineTop = lineTopInShapeCoordinates; m_shapeLineTop = lineTopInShapeCoordinates - logicalTopOffset(); m_lineHeight = lineHeight; LayoutUnit floatMarginBoxWidth = containingBlock->logicalWidthForFloat(floatingObject); if (lineOverlapsShapeBounds()) { SegmentList segments = computeSegmentsForLine(lineTopInShapeCoordinates, lineHeight); if (segments.size()) { LayoutUnit rawLeftMarginBoxDelta = segments.first().logicalLeft + containingBlock->marginStartForChild(*m_renderer); m_leftMarginBoxDelta = clampTo<LayoutUnit>(rawLeftMarginBoxDelta, LayoutUnit(), floatMarginBoxWidth); LayoutUnit rawRightMarginBoxDelta = segments.last().logicalRight - containingBlock->logicalWidthForChild(*m_renderer) - containingBlock->marginEndForChild(*m_renderer); m_rightMarginBoxDelta = clampTo<LayoutUnit>(rawRightMarginBoxDelta, -floatMarginBoxWidth, LayoutUnit()); 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. // FIXME: The latest CSS Shapes spec says that in this case, the // content should interact with previously stacked floats on the line // as if this outermost float did not exist. Perhaps obviously, this // solution cannot do that, and will be revisted with bug 122576. m_leftMarginBoxDelta = floatMarginBoxWidth; m_rightMarginBoxDelta = -floatMarginBoxWidth; } }
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; }
void ShapeOutsideInfo::updateDeltasForContainingBlockLine(const RenderBlockFlow& containingBlock, const FloatingObject& floatingObject, LayoutUnit lineTop, LayoutUnit lineHeight) { 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 (lineOverlapsShapeBounds()) { SegmentList segments = computeSegmentsForLine(borderBoxLineTop, lineHeight); if (segments.size()) { LayoutUnit logicalLeftMargin = containingBlock.style()->isLeftToRightDirection() ? containingBlock.marginStartForChild(&m_renderer) : containingBlock.marginEndForChild(&m_renderer); LayoutUnit rawLeftMarginBoxDelta = segments.first().logicalLeft + logicalLeftMargin; m_leftMarginBoxDelta = clampToLayoutUnit(rawLeftMarginBoxDelta, LayoutUnit(), floatMarginBoxWidth); LayoutUnit logicalRightMargin = containingBlock.style()->isLeftToRightDirection() ? containingBlock.marginEndForChild(&m_renderer) : containingBlock.marginStartForChild(&m_renderer); LayoutUnit rawRightMarginBoxDelta = segments.last().logicalRight - containingBlock.logicalWidthForChild(&m_renderer) - logicalRightMargin; m_rightMarginBoxDelta = clampToLayoutUnit(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; } }
LayoutRect ShapeOutsideInfo::computedShapePhysicalBoundingBox() const { LayoutRect physicalBoundingBox = computedShape().shapeMarginLogicalBoundingBox(); physicalBoundingBox.setX(physicalBoundingBox.x() + logicalLeftOffset()); if (m_renderer.style()->isFlippedBlocksWritingMode()) physicalBoundingBox.setY(m_renderer.logicalHeight() - physicalBoundingBox.maxY()); else physicalBoundingBox.setY(physicalBoundingBox.y() + logicalTopOffset()); if (!m_renderer.style()->isHorizontalWritingMode()) physicalBoundingBox = physicalBoundingBox.transposedRect(); else physicalBoundingBox.setY(physicalBoundingBox.y() + logicalTopOffset()); return physicalBoundingBox; }
FloatPoint ShapeOutsideInfo::shapeToRendererPoint(FloatPoint point) const { FloatPoint result = FloatPoint(point.x() + logicalLeftOffset(), point.y() + logicalTopOffset()); if (m_renderer.style()->isFlippedBlocksWritingMode()) result.setY(m_renderer.logicalHeight() - result.y()); if (!m_renderer.style()->isHorizontalWritingMode()) result = result.transposedPoint(); return result; }
bool ShapeInsideInfo::updateSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight) { ASSERT(lineHeight >= 0); m_shapeLineTop = lineTop - logicalTopOffset(); m_lineHeight = lineHeight; m_segments.clear(); m_segmentRanges.clear(); if (lineOverlapsShapeBounds()) m_segments = computeSegmentsForLine(lineTop, lineHeight); return m_segments.size(); }
SegmentList ShapeOutsideInfo::computeSegmentsForLine(LayoutUnit lineTop, LayoutUnit lineHeight) const { ASSERT(lineHeight >= 0); SegmentList segments; computedShape().getExcludedIntervals((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 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; } }