void RenderMathMLFraction::paint(PaintInfo& info, const LayoutPoint& paintOffset) { RenderMathMLBlock::paint(info, paintOffset); if (info.context->paintingDisabled() || info.phase != PaintPhaseForeground) return; RenderBox* denominatorWrapper = lastChildBox(); if (!denominatorWrapper || !m_lineThickness) return; IntPoint adjustedPaintOffset = roundedIntPoint(paintOffset + location() + denominatorWrapper->location() + LayoutPoint(0, m_lineThickness / 2)); GraphicsContextStateSaver stateSaver(*info.context); info.context->setStrokeThickness(m_lineThickness); info.context->setStrokeStyle(SolidStroke); info.context->setStrokeColor(style()->visitedDependentColor(CSSPropertyColor), ColorSpaceSRGB); info.context->drawLine(adjustedPaintOffset, IntPoint(adjustedPaintOffset.x() + denominatorWrapper->pixelSnappedOffsetWidth(), adjustedPaintOffset.y())); }
void RenderSliderContainer::layout() { HTMLInputElement* input = element()->shadowHost()->toInputElement(); bool isVertical = hasVerticalAppearance(input); style().setFlexDirection(isVertical ? FlowColumn : FlowRow); TextDirection oldTextDirection = style().direction(); if (isVertical) { // FIXME: Work around rounding issues in RTL vertical sliders. We want them to // render identically to LTR vertical sliders. We can remove this work around when // subpixel rendering is enabled on all ports. style().setDirection(LTR); } RenderBox* thumb = input->sliderThumbElement() ? input->sliderThumbElement()->renderBox() : 0; RenderBox* track = input->sliderTrackElement() ? input->sliderTrackElement()->renderBox() : 0; // Force a layout to reset the position of the thumb so the code below doesn't move the thumb to the wrong place. // FIXME: Make a custom Render class for the track and move the thumb positioning code there. if (track) track->setChildNeedsLayout(MarkOnlyThis); RenderFlexibleBox::layout(); style().setDirection(oldTextDirection); // These should always exist, unless someone mutates the shadow DOM (e.g., in the inspector). if (!thumb || !track) return; double percentageOffset = sliderPosition(input).toDouble(); LayoutUnit availableExtent = isVertical ? track->contentHeight() : track->contentWidth(); availableExtent -= isVertical ? thumb->height() : thumb->width(); LayoutUnit offset = percentageOffset * availableExtent; LayoutPoint thumbLocation = thumb->location(); if (isVertical) thumbLocation.setY(thumbLocation.y() + track->contentHeight() - thumb->height() - offset); else if (style().isLeftToRightDirection()) thumbLocation.setX(thumbLocation.x() + offset); else thumbLocation.setX(thumbLocation.x() - offset); thumb->setLocation(thumbLocation); thumb->repaint(); }
void RenderTextControlSingleLine::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; // FIXME: We should remove the height-related hacks in layout() and // styleDidChange(). We need them because // - Center the inner elements vertically if the input height is taller than // the intrinsic height of the inner elements. // - Shrink the inner elment heights if the input height is samller than the // intrinsic heights of the inner elements. // We don't honor paddings and borders for textfields without decorations // and type=search if the text height is taller than the contentHeight() // because of compability. RenderTextControlInnerBlock* innerTextRenderer = innerTextElement()->renderer(); RenderBox* innerBlockRenderer = innerBlockElement() ? innerBlockElement()->renderBox() : 0; // To ensure consistency between layouts, we need to reset any conditionally overriden height. if (innerTextRenderer && !innerTextRenderer->style().logicalHeight().isAuto()) { innerTextRenderer->style().setLogicalHeight(Length(Auto)); setNeedsLayoutOnAncestors(innerTextRenderer, this); } if (innerBlockRenderer && !innerBlockRenderer->style().logicalHeight().isAuto()) { innerBlockRenderer->style().setLogicalHeight(Length(Auto)); setNeedsLayoutOnAncestors(innerBlockRenderer, this); } RenderBlockFlow::layoutBlock(false); HTMLElement* container = containerElement(); RenderBox* containerRenderer = container ? container->renderBox() : 0; // Set the text block height LayoutUnit desiredLogicalHeight = textBlockLogicalHeight(); LayoutUnit logicalHeightLimit = computeLogicalHeightLimit(); if (innerTextRenderer && innerTextRenderer->logicalHeight() > logicalHeightLimit) { if (desiredLogicalHeight != innerTextRenderer->logicalHeight()) setNeedsLayout(MarkOnlyThis); m_desiredInnerTextLogicalHeight = desiredLogicalHeight; innerTextRenderer->style().setLogicalHeight(Length(desiredLogicalHeight, Fixed)); innerTextRenderer->setNeedsLayout(MarkOnlyThis); if (innerBlockRenderer) { innerBlockRenderer->style().setLogicalHeight(Length(desiredLogicalHeight, Fixed)); innerBlockRenderer->setNeedsLayout(MarkOnlyThis); } } // The container might be taller because of decoration elements. if (containerRenderer) { containerRenderer->layoutIfNeeded(); LayoutUnit containerLogicalHeight = containerRenderer->logicalHeight(); if (containerLogicalHeight > logicalHeightLimit) { containerRenderer->style().setLogicalHeight(Length(logicalHeightLimit, Fixed)); setNeedsLayout(MarkOnlyThis); } else if (containerRenderer->logicalHeight() < contentLogicalHeight()) { containerRenderer->style().setLogicalHeight(Length(contentLogicalHeight(), Fixed)); setNeedsLayout(MarkOnlyThis); } else containerRenderer->style().setLogicalHeight(Length(containerLogicalHeight, Fixed)); } // If we need another layout pass, we have changed one of children's height so we need to relayout them. if (needsLayout()) RenderBlockFlow::layoutBlock(true); // Center the child block in the block progression direction (vertical centering for horizontal text fields). if (!container && innerTextRenderer && innerTextRenderer->height() != contentLogicalHeight()) centerRenderer(*innerTextRenderer); else centerContainerIfNeeded(containerRenderer); // Ignores the paddings for the inner spin button. if (RenderBox* innerSpinBox = innerSpinButtonElement() ? innerSpinButtonElement()->renderBox() : 0) { RenderBox* parentBox = innerSpinBox->parentBox(); if (containerRenderer && !containerRenderer->style().isLeftToRightDirection()) innerSpinBox->setLogicalLocation(LayoutPoint(-paddingLogicalLeft(), -paddingBefore())); else innerSpinBox->setLogicalLocation(LayoutPoint(parentBox->logicalWidth() - innerSpinBox->logicalWidth() + paddingLogicalRight(), -paddingBefore())); innerSpinBox->setLogicalHeight(logicalHeight() - borderBefore() - borderAfter()); } HTMLElement* placeholderElement = inputElement().placeholderElement(); if (RenderBox* placeholderBox = placeholderElement ? placeholderElement->renderBox() : 0) { LayoutSize innerTextSize; if (innerTextRenderer) innerTextSize = innerTextRenderer->size(); placeholderBox->style().setWidth(Length(innerTextSize.width() - placeholderBox->horizontalBorderAndPaddingExtent(), Fixed)); placeholderBox->style().setHeight(Length(innerTextSize.height() - placeholderBox->verticalBorderAndPaddingExtent(), Fixed)); bool neededLayout = placeholderBox->needsLayout(); bool placeholderBoxHadLayout = placeholderBox->everHadLayout(); placeholderBox->layoutIfNeeded(); LayoutPoint textOffset; if (innerTextRenderer) textOffset = innerTextRenderer->location(); if (innerBlockElement() && innerBlockElement()->renderBox()) textOffset += toLayoutSize(innerBlockElement()->renderBox()->location()); if (containerRenderer) textOffset += toLayoutSize(containerRenderer->location()); placeholderBox->setLocation(textOffset); if (!placeholderBoxHadLayout && placeholderBox->checkForRepaintDuringLayout()) { // This assumes a shadow tree without floats. If floats are added, the // logic should be shared with RenderBlock::layoutBlockChild. placeholderBox->repaint(); } // The placeholder gets layout last, after the parent text control and its other children, // so in order to get the correct overflow from the placeholder we need to recompute it now. if (neededLayout) computeOverflow(clientLogicalBottom()); } #if PLATFORM(IOS) // FIXME: We should not be adjusting styles during layout. <rdar://problem/7675493> if (inputElement().isSearchField()) RenderThemeIOS::adjustRoundBorderRadius(style(), *this); #endif }
void RenderListItem::positionListMarker() { if (m_marker && m_marker->parent()->isBox() && !m_marker->isInside() && m_marker->inlineBoxWrapper()) { LayoutUnit markerOldLogicalLeft = m_marker->logicalLeft(); LayoutUnit blockOffset = 0; LayoutUnit lineOffset = 0; for (RenderBox* o = m_marker->parentBox(); o != this; o = o->parentBox()) { blockOffset += o->logicalTop(); lineOffset += o->logicalLeft(); } bool adjustOverflow = false; LayoutUnit markerLogicalLeft; RootInlineBox& root = m_marker->inlineBoxWrapper()->root(); bool hitSelfPaintingLayer = false; LayoutUnit lineTop = root.lineTop(); LayoutUnit lineBottom = root.lineBottom(); // FIXME: Need to account for relative positioning in the layout overflow. if (style()->isLeftToRightDirection()) { LayoutUnit leftLineOffset = logicalLeftOffsetForLine(blockOffset, logicalLeftOffsetForLine(blockOffset, false), false); markerLogicalLeft = leftLineOffset - lineOffset - paddingStart() - borderStart() + m_marker->marginStart(); m_marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogicalLeft - markerOldLogicalLeft).toFloat()); for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) { LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOverflowRect(lineTop, lineBottom); LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOverflowRect(lineTop, lineBottom); if (markerLogicalLeft < newLogicalVisualOverflowRect.x() && !hitSelfPaintingLayer) { newLogicalVisualOverflowRect.setWidth(newLogicalVisualOverflowRect.maxX() - markerLogicalLeft); newLogicalVisualOverflowRect.setX(markerLogicalLeft); if (box == root) adjustOverflow = true; } if (markerLogicalLeft < newLogicalLayoutOverflowRect.x()) { newLogicalLayoutOverflowRect.setWidth(newLogicalLayoutOverflowRect.maxX() - markerLogicalLeft); newLogicalLayoutOverflowRect.setX(markerLogicalLeft); if (box == root) adjustOverflow = true; } box->setOverflowFromLogicalRects(newLogicalLayoutOverflowRect, newLogicalVisualOverflowRect, lineTop, lineBottom); if (box->boxModelObject()->hasSelfPaintingLayer()) hitSelfPaintingLayer = true; } } else { LayoutUnit rightLineOffset = logicalRightOffsetForLine(blockOffset, logicalRightOffsetForLine(blockOffset, false), false); markerLogicalLeft = rightLineOffset - lineOffset + paddingStart() + borderStart() + m_marker->marginEnd(); m_marker->inlineBoxWrapper()->adjustLineDirectionPosition((markerLogicalLeft - markerOldLogicalLeft).toFloat()); for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) { LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOverflowRect(lineTop, lineBottom); LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOverflowRect(lineTop, lineBottom); if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalVisualOverflowRect.maxX() && !hitSelfPaintingLayer) { newLogicalVisualOverflowRect.setWidth(markerLogicalLeft + m_marker->logicalWidth() - newLogicalVisualOverflowRect.x()); if (box == root) adjustOverflow = true; } if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalLayoutOverflowRect.maxX()) { newLogicalLayoutOverflowRect.setWidth(markerLogicalLeft + m_marker->logicalWidth() - newLogicalLayoutOverflowRect.x()); if (box == root) adjustOverflow = true; } box->setOverflowFromLogicalRects(newLogicalLayoutOverflowRect, newLogicalVisualOverflowRect, lineTop, lineBottom); if (box->boxModelObject()->hasSelfPaintingLayer()) hitSelfPaintingLayer = true; } } if (adjustOverflow) { LayoutRect markerRect(LayoutPoint(markerLogicalLeft + lineOffset, blockOffset), m_marker->size()); if (!style()->isHorizontalWritingMode()) markerRect = markerRect.transposedRect(); RenderBox* o = m_marker; bool propagateVisualOverflow = true; bool propagateLayoutOverflow = true; do { o = o->parentBox(); if (o->isRenderBlock()) { if (propagateVisualOverflow) toRenderBlock(o)->addContentsVisualOverflow(markerRect); if (propagateLayoutOverflow) toRenderBlock(o)->addLayoutOverflow(markerRect); } if (o->hasOverflowClip()) { propagateLayoutOverflow = false; propagateVisualOverflow = false; } if (o->hasSelfPaintingLayer()) propagateVisualOverflow = false; markerRect.moveBy(-o->location()); } while (o != this && propagateVisualOverflow && propagateLayoutOverflow); } } }
void RenderTextControlSingleLine::layout() { // FIXME: We should remove the height-related hacks in layout() and // styleDidChange(). We need them because // - Center the inner elements vertically if the input height is taller than // the intrinsic height of the inner elements. // - Shrink the inner elment heights if the input height is samller than the // intrinsic heights of the inner elements. // We don't honor paddings and borders for textfields without decorations // and type=search if the text height is taller than the contentHeight() // because of compability. LayoutUnit oldHeight = height(); computeLogicalHeight(); LayoutUnit oldWidth = width(); computeLogicalWidth(); bool relayoutChildren = oldHeight != height() || oldWidth != width(); RenderBox* innerTextRenderer = innerTextElement()->renderBox(); ASSERT(innerTextRenderer); RenderBox* innerBlockRenderer = innerBlockElement() ? innerBlockElement()->renderBox() : 0; HTMLElement* container = containerElement(); RenderBox* containerRenderer = container ? container->renderBox() : 0; // Set the text block height LayoutUnit desiredHeight = textBlockHeight(); LayoutUnit currentHeight = innerTextRenderer->height(); LayoutUnit heightLimit = (inputElement()->isSearchField() || !container) ? height() : contentHeight(); if (currentHeight > heightLimit) { if (desiredHeight != currentHeight) relayoutChildren = true; innerTextRenderer->style()->setHeight(Length(desiredHeight, Fixed)); m_desiredInnerTextHeight = desiredHeight; if (innerBlockRenderer) innerBlockRenderer->style()->setHeight(Length(desiredHeight, Fixed)); } // The container might be taller because of decoration elements. if (containerRenderer) { containerRenderer->layoutIfNeeded(); LayoutUnit containerHeight = containerRenderer->height(); if (containerHeight > heightLimit) { containerRenderer->style()->setHeight(Length(heightLimit, Fixed)); relayoutChildren = true; } else if (containerRenderer->height() < contentHeight()) { containerRenderer->style()->setHeight(Length(contentHeight(), Fixed)); relayoutChildren = true; } else containerRenderer->style()->setHeight(Length(containerHeight, Fixed)); } RenderBlock::layoutBlock(relayoutChildren); // Center the child block vertically currentHeight = innerTextRenderer->height(); if (!container && currentHeight != contentHeight()) { LayoutUnit heightDiff = currentHeight - contentHeight(); innerTextRenderer->setY(innerTextRenderer->y() - (heightDiff / 2 + layoutMod(heightDiff, 2))); } else if (inputElement()->isSearchField() && containerRenderer && containerRenderer->height() > contentHeight()) { // A quirk for find-in-page box on Safari Windows. // http://webkit.org/b/63157 LayoutUnit heightDiff = containerRenderer->height() - contentHeight(); containerRenderer->setY(containerRenderer->y() - (heightDiff / 2 + layoutMod(heightDiff, 2))); } // Ignores the paddings for the inner spin button. if (RenderBox* innerSpinBox = innerSpinButtonElement() ? innerSpinButtonElement()->renderBox() : 0) { RenderBox* parentBox = innerSpinBox->parentBox(); if (containerRenderer && !containerRenderer->style()->isLeftToRightDirection()) innerSpinBox->setLocation(LayoutPoint(-paddingLeft(), -paddingTop())); else innerSpinBox->setLocation(LayoutPoint(parentBox->width() - innerSpinBox->width() + paddingRight(), -paddingTop())); innerSpinBox->setHeight(height() - borderTop() - borderBottom()); } HTMLElement* placeholderElement = inputElement()->placeholderElement(); if (RenderBox* placeholderBox = placeholderElement ? placeholderElement->renderBox() : 0) { placeholderBox->style()->setWidth(Length(innerTextRenderer->width() - placeholderBox->borderAndPaddingWidth(), Fixed)); placeholderBox->style()->setHeight(Length(innerTextRenderer->height() - placeholderBox->borderAndPaddingHeight(), Fixed)); placeholderBox->layoutIfNeeded(); LayoutPoint textOffset = innerTextRenderer->location(); if (innerBlockElement() && innerBlockElement()->renderBox()) textOffset += toLayoutSize(innerBlockElement()->renderBox()->location()); if (containerRenderer) textOffset += toLayoutSize(containerRenderer->location()); placeholderBox->setLocation(textOffset); } }
void RenderTextControlSingleLine::layout() { SubtreeLayoutScope layoutScope(this); // FIXME: We should remove the height-related hacks in layout() and // styleDidChange(). We need them because // - Center the inner elements vertically if the input height is taller than // the intrinsic height of the inner elements. // - Shrink the inner elment heights if the input height is samller than the // intrinsic heights of the inner elements. // We don't honor paddings and borders for textfields without decorations // and type=search if the text height is taller than the contentHeight() // because of compability. RenderBox* innerTextRenderer = innerTextElement()->renderBox(); RenderBox* viewPortRenderer = editingViewPortElement() ? editingViewPortElement()->renderBox() : 0; // To ensure consistency between layouts, we need to reset any conditionally overriden height. if (innerTextRenderer && !innerTextRenderer->style()->logicalHeight().isAuto()) { innerTextRenderer->style()->setLogicalHeight(Length(Auto)); layoutScope.setNeedsLayout(innerTextRenderer); } if (viewPortRenderer && !viewPortRenderer->style()->logicalHeight().isAuto()) { viewPortRenderer->style()->setLogicalHeight(Length(Auto)); layoutScope.setNeedsLayout(viewPortRenderer); } RenderBlockFlow::layoutBlock(false); Element* container = containerElement(); RenderBox* containerRenderer = container ? container->renderBox() : 0; // Set the text block height LayoutUnit desiredLogicalHeight = textBlockLogicalHeight(); LayoutUnit logicalHeightLimit = computeLogicalHeightLimit(); if (innerTextRenderer && innerTextRenderer->logicalHeight() > logicalHeightLimit) { if (desiredLogicalHeight != innerTextRenderer->logicalHeight()) layoutScope.setNeedsLayout(this); m_desiredInnerTextLogicalHeight = desiredLogicalHeight; innerTextRenderer->style()->setLogicalHeight(Length(desiredLogicalHeight, Fixed)); layoutScope.setNeedsLayout(innerTextRenderer); if (viewPortRenderer) { viewPortRenderer->style()->setLogicalHeight(Length(desiredLogicalHeight, Fixed)); layoutScope.setNeedsLayout(viewPortRenderer); } } // The container might be taller because of decoration elements. if (containerRenderer) { containerRenderer->layoutIfNeeded(); LayoutUnit containerLogicalHeight = containerRenderer->logicalHeight(); if (containerLogicalHeight > logicalHeightLimit) { containerRenderer->style()->setLogicalHeight(Length(logicalHeightLimit, Fixed)); layoutScope.setNeedsLayout(this); } else if (containerRenderer->logicalHeight() < contentLogicalHeight()) { containerRenderer->style()->setLogicalHeight(Length(contentLogicalHeight(), Fixed)); layoutScope.setNeedsLayout(this); } else containerRenderer->style()->setLogicalHeight(Length(containerLogicalHeight, Fixed)); } // If we need another layout pass, we have changed one of children's height so we need to relayout them. if (needsLayout()) RenderBlockFlow::layoutBlock(true); // Center the child block in the block progression direction (vertical centering for horizontal text fields). if (!container && innerTextRenderer && innerTextRenderer->height() != contentLogicalHeight()) { LayoutUnit logicalHeightDiff = innerTextRenderer->logicalHeight() - contentLogicalHeight(); innerTextRenderer->setLogicalTop(innerTextRenderer->logicalTop() - (logicalHeightDiff / 2 + layoutMod(logicalHeightDiff, 2))); } else centerContainerIfNeeded(containerRenderer); HTMLElement* placeholderElement = inputElement()->placeholderElement(); if (RenderBox* placeholderBox = placeholderElement ? placeholderElement->renderBox() : 0) { LayoutSize innerTextSize; if (innerTextRenderer) innerTextSize = innerTextRenderer->size(); placeholderBox->style()->setWidth(Length(innerTextSize.width() - placeholderBox->borderAndPaddingWidth(), Fixed)); placeholderBox->style()->setHeight(Length(innerTextSize.height() - placeholderBox->borderAndPaddingHeight(), Fixed)); bool neededLayout = placeholderBox->needsLayout(); bool placeholderBoxHadLayout = placeholderBox->everHadLayout(); placeholderBox->layoutIfNeeded(); LayoutPoint textOffset; if (innerTextRenderer) textOffset = innerTextRenderer->location(); if (editingViewPortElement() && editingViewPortElement()->renderBox()) textOffset += toLayoutSize(editingViewPortElement()->renderBox()->location()); if (containerRenderer) textOffset += toLayoutSize(containerRenderer->location()); placeholderBox->setLocation(textOffset); if (!placeholderBoxHadLayout && placeholderBox->checkForRepaintDuringLayout()) { // This assumes a shadow tree without floats. If floats are added, the // logic should be shared with RenderBlockFlow::layoutBlockChild. placeholderBox->repaint(); } // The placeholder gets layout last, after the parent text control and its other children, // so in order to get the correct overflow from the placeholder we need to recompute it now. if (neededLayout) computeOverflow(clientLogicalBottom()); } }
void RenderTextControlSingleLine::layout() { StackStats::LayoutCheckPoint layoutCheckPoint; // FIXME: We should remove the height-related hacks in layout() and // styleDidChange(). We need them because // - Center the inner elements vertically if the input height is taller than // the intrinsic height of the inner elements. // - Shrink the inner elment heights if the input height is samller than the // intrinsic heights of the inner elements. // We don't honor paddings and borders for textfields without decorations // and type=search if the text height is taller than the contentHeight() // because of compability. RenderBox* innerTextRenderer = innerTextElement()->renderBox(); ASSERT(innerTextRenderer); RenderBox* innerBlockRenderer = innerBlockElement() ? innerBlockElement()->renderBox() : 0; // To ensure consistency between layouts, we need to reset any conditionally overriden height. innerTextRenderer->style()->setHeight(Length(Auto)); if (innerBlockRenderer) innerBlockRenderer->style()->setHeight(Length(Auto)); RenderBlock::layoutBlock(false); HTMLElement* container = containerElement(); RenderBox* containerRenderer = container ? container->renderBox() : 0; // Set the text block height LayoutUnit desiredHeight = textBlockHeight(); LayoutUnit currentHeight = innerTextRenderer->height(); LayoutUnit heightLimit = computeHeightLimit(); if (currentHeight > heightLimit) { if (desiredHeight != currentHeight) setNeedsLayout(true, MarkOnlyThis); innerTextRenderer->style()->setHeight(Length(desiredHeight, Fixed)); m_desiredInnerTextHeight = desiredHeight; if (innerBlockRenderer) innerBlockRenderer->style()->setHeight(Length(desiredHeight, Fixed)); } // The container might be taller because of decoration elements. if (containerRenderer) { containerRenderer->layoutIfNeeded(); LayoutUnit containerHeight = containerRenderer->height(); if (containerHeight > heightLimit) { containerRenderer->style()->setHeight(Length(heightLimit, Fixed)); setNeedsLayout(true, MarkOnlyThis); } else if (containerRenderer->height() < contentHeight()) { containerRenderer->style()->setHeight(Length(contentHeight(), Fixed)); setNeedsLayout(true, MarkOnlyThis); } else containerRenderer->style()->setHeight(Length(containerHeight, Fixed)); } // If we need another layout pass, we have changed one of children's height so we need to relayout them. if (needsLayout()) RenderBlock::layoutBlock(true); // Center the child block vertically currentHeight = innerTextRenderer->height(); if (!container && currentHeight != contentHeight()) { LayoutUnit heightDiff = currentHeight - contentHeight(); innerTextRenderer->setY(innerTextRenderer->y() - (heightDiff / 2 + layoutMod(heightDiff, 2))); } else centerContainerIfNeeded(containerRenderer); // Ignores the paddings for the inner spin button. if (RenderBox* innerSpinBox = innerSpinButtonElement() ? innerSpinButtonElement()->renderBox() : 0) { RenderBox* parentBox = innerSpinBox->parentBox(); if (containerRenderer && !containerRenderer->style()->isLeftToRightDirection()) innerSpinBox->setLocation(LayoutPoint(-paddingLeft(), -paddingTop())); else innerSpinBox->setLocation(LayoutPoint(parentBox->width() - innerSpinBox->width() + paddingRight(), -paddingTop())); innerSpinBox->setHeight(height() - borderTop() - borderBottom()); } HTMLElement* placeholderElement = inputElement()->placeholderElement(); if (RenderBox* placeholderBox = placeholderElement ? placeholderElement->renderBox() : 0) { placeholderBox->style()->setWidth(Length(innerTextRenderer->width() - placeholderBox->borderAndPaddingWidth(), Fixed)); placeholderBox->style()->setHeight(Length(innerTextRenderer->height() - placeholderBox->borderAndPaddingHeight(), Fixed)); bool neededLayout = placeholderBox->needsLayout(); bool placeholderBoxHadLayout = placeholderBox->everHadLayout(); placeholderBox->layoutIfNeeded(); LayoutPoint textOffset = innerTextRenderer->location(); if (innerBlockElement() && innerBlockElement()->renderBox()) textOffset += toLayoutSize(innerBlockElement()->renderBox()->location()); if (containerRenderer) textOffset += toLayoutSize(containerRenderer->location()); placeholderBox->setLocation(textOffset); if (!placeholderBoxHadLayout && placeholderBox->checkForRepaintDuringLayout()) { // This assumes a shadow tree without floats. If floats are added, the // logic should be shared with RenderBlock::layoutBlockChild. placeholderBox->repaint(); } // The placeholder gets layout last, after the parent text control and its other children, // so in order to get the correct overflow from the placeholder we need to recompute it now. if (neededLayout) computeOverflow(clientLogicalBottom()); } }
void RenderMathMLRow::layoutRowItems(LayoutUnit& ascent, LayoutUnit& descent) { // We first stretch the vertical operators. // For inline formulas, we can then calculate the logical width. LayoutUnit width = borderAndPaddingStart(); for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { if (child->isOutOfFlowPositioned()) continue; if (is<RenderMathMLBlock>(child)) { auto renderOperator = downcast<RenderMathMLBlock>(child)->unembellishedOperator(); if (renderOperator && renderOperator->hasOperatorFlag(MathMLOperatorDictionary::Stretchy) && renderOperator->isVertical()) renderOperator->stretchTo(ascent, descent); } child->layoutIfNeeded(); width += child->marginStart() + child->logicalWidth() + child->marginEnd(); } width += borderEnd() + paddingEnd(); // FIXME: RenderMathMLRoot classes should also recalculate the exact logical width instead of using the preferred width. // See http://webkit.org/b/153987 if ((!isRenderMathMLMath() || style().display() == INLINE) && !isRenderMathMLRoot()) setLogicalWidth(width); LayoutUnit verticalOffset = borderTop() + paddingTop(); LayoutUnit maxAscent = 0, maxDescent = 0; // Used baseline alignment. LayoutUnit horizontalOffset = borderAndPaddingStart(); bool shouldFlipHorizontal = !style().isLeftToRightDirection(); for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { if (child->isOutOfFlowPositioned()) { child->containingBlock()->insertPositionedObject(*child); continue; } LayoutUnit childHorizontalExtent = child->logicalWidth(); LayoutUnit ascent = ascentForChild(*child); LayoutUnit descent = child->verticalMarginExtent() + child->logicalHeight() - ascent; maxAscent = std::max(maxAscent, ascent); maxDescent = std::max(maxDescent, descent); LayoutUnit childVerticalMarginBoxExtent = maxAscent + maxDescent; horizontalOffset += child->marginStart(); setLogicalHeight(std::max(logicalHeight(), verticalOffset + borderBottom() + paddingBottom() + childVerticalMarginBoxExtent + horizontalScrollbarHeight())); LayoutPoint childLocation(shouldFlipHorizontal ? logicalWidth() - horizontalOffset - childHorizontalExtent : horizontalOffset, verticalOffset + child->marginTop()); child->setLocation(childLocation); horizontalOffset += childHorizontalExtent + child->marginEnd(); } LayoutUnit centerBlockOffset = 0; // FIXME: Remove the FLEX when it is not required by the css. if (style().display() == BLOCK || style().display() == FLEX) centerBlockOffset = std::max<LayoutUnit>(0, (logicalWidth() - (horizontalOffset + borderEnd() + paddingEnd())) / 2); if (shouldFlipHorizontal && centerBlockOffset > 0) centerBlockOffset = -centerBlockOffset; for (RenderBox* child = firstChildBox(); child; child = child->nextSiblingBox()) { LayoutUnit ascent = ascentForChild(*child); LayoutUnit startOffset = maxAscent - ascent; child->setLocation(child->location() + LayoutPoint(centerBlockOffset, startOffset)); } ascent = maxAscent; descent = maxDescent; }
bool ContainerNode::getUpperLeftCorner(FloatPoint& point) const { if (!renderer()) return false; // What is this code really trying to do? RenderObject* o = renderer(); RenderObject* p = o; if (!o->isInline() || o->isReplaced()) { point = o->localToAbsolute(FloatPoint(), UseTransforms); return true; } // find the next text/image child, to get a position while (o) { p = o; if (o->firstChild()) o = o->firstChild(); else if (o->nextSibling()) o = o->nextSibling(); else { RenderObject* next = 0; while (!next && o->parent()) { o = o->parent(); next = o->nextSibling(); } o = next; if (!o) break; } ASSERT(o); if (!o->isInline() || o->isReplaced()) { point = o->localToAbsolute(FloatPoint(), UseTransforms); return true; } if (p->node() && p->node() == this && o->isText() && !o->isBR() && !toRenderText(o)->firstTextBox()) { // do nothing - skip unrendered whitespace that is a child or next sibling of the anchor } else if ((o->isText() && !o->isBR()) || o->isReplaced()) { point = FloatPoint(); if (o->isText() && toRenderText(o)->firstTextBox()) { point.move(toRenderText(o)->linesBoundingBox().x(), toRenderText(o)->firstTextBox()->root()->lineTop()); } else if (o->isBox()) { RenderBox* box = toRenderBox(o); point.moveBy(box->location()); } point = o->container()->localToAbsolute(point, UseTransforms); return true; } } // If the target doesn't have any children or siblings that could be used to calculate the scroll position, we must be // at the end of the document. Scroll to the bottom. FIXME: who said anything about scrolling? if (!o && document().view()) { point = FloatPoint(0, document().view()->contentsHeight()); return true; } return false; }
bool RenderTextControlSingleLine::nodeAtPoint(const HitTestRequest& request, HitTestResult& result, const IntPoint& pointInContainer, const IntPoint& accumulatedOffset, HitTestAction hitTestAction) { // If we're within the text control, we want to act as if we've hit the inner text block element, in case the point // was on the control but not on the inner element (see Radar 4617841). // In a search field, we want to act as if we've hit the results block if we're to the left of the inner text block, // and act as if we've hit the close block if we're to the right of the inner text block. if (!RenderTextControl::nodeAtPoint(request, result, pointInContainer, accumulatedOffset, hitTestAction)) return false; // If we hit a node inside the inner text element, say that we hit that element, // and if we hit our node (e.g. we're over the border or padding), also say that we hit the // inner text element so that it gains focus. if (result.innerNode()->isDescendantOf(innerTextElement()) || result.innerNode() == node()) hitInnerTextElement(result, pointInContainer, accumulatedOffset); // If we found a spin button, we're done. HTMLElement* innerSpinButton = innerSpinButtonElement(); if (innerSpinButton && result.innerNode() == innerSpinButton) return true; #if ENABLE(INPUT_SPEECH) HTMLElement* speechButton = speechButtonElement(); if (speechButton && result.innerNode() == speechButton) return true; #endif // If we're not a search field, or we already found the speech, results or cancel buttons, we're done. HTMLElement* innerBlock = innerBlockElement(); HTMLElement* resultsButton = resultsButtonElement(); HTMLElement* cancelButton = cancelButtonElement(); if (!innerBlock || result.innerNode() == resultsButton || result.innerNode() == cancelButton) return true; Node* innerNode = 0; RenderBox* innerBlockRenderer = innerBlock->renderBox(); RenderBox* innerTextRenderer = innerTextElement()->renderBox(); IntPoint localPoint = result.localPoint(); localPoint.move(-innerBlockRenderer->location()); int textLeft = accumulatedOffset.x() + x() + innerBlockRenderer->x() + innerTextRenderer->x(); if (resultsButton && resultsButton->renderer() && pointInContainer.x() < textLeft) innerNode = resultsButton; #if ENABLE(INPUT_SPEECH) if (!innerNode && speechButtonElement() && speechButtonElement()->renderer()) { int buttonLeft = accumulatedOffset.x() + x() + innerBlockRenderer->x() + innerBlockRenderer->width() - speechButtonElement()->renderBox()->width(); if (pointInContainer.x() >= buttonLeft) innerNode = speechButtonElement(); } #endif if (!innerNode) { int textRight = textLeft + innerTextRenderer->width(); if (cancelButton && cancelButton->renderer() && pointInContainer.x() > textRight) innerNode = cancelButton; } if (innerNode) { result.setInnerNode(innerNode); localPoint.move(-innerNode->renderBox()->location()); } result.setLocalPoint(localPoint); return true; }
void RenderListItem::positionListMarker() { if (!m_marker || !m_marker->parent() || !m_marker->parent()->isBox()) return; if (m_marker->isInside() || !m_marker->inlineBoxWrapper()) return; LayoutUnit markerOldLogicalLeft = m_marker->logicalLeft(); LayoutUnit blockOffset = 0; LayoutUnit lineOffset = 0; for (RenderBox* o = m_marker->parentBox(); o != this; o = o->parentBox()) { blockOffset += o->logicalTop(); lineOffset += o->logicalLeft(); } bool adjustOverflow = false; LayoutUnit markerLogicalLeft; bool hitSelfPaintingLayer = false; const RootInlineBox& rootBox = m_marker->inlineBoxWrapper()->root(); LayoutUnit lineTop = rootBox.lineTop(); LayoutUnit lineBottom = rootBox.lineBottom(); // FIXME: Need to account for relative positioning in the layout overflow. if (style().isLeftToRightDirection()) { markerLogicalLeft = m_marker->lineOffsetForListItem() - lineOffset - paddingStart() - borderStart() + m_marker->marginStart(); m_marker->inlineBoxWrapper()->adjustLineDirectionPosition(markerLogicalLeft - markerOldLogicalLeft); for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) { LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOverflowRect(lineTop, lineBottom); LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOverflowRect(lineTop, lineBottom); if (markerLogicalLeft < newLogicalVisualOverflowRect.x() && !hitSelfPaintingLayer) { newLogicalVisualOverflowRect.setWidth(newLogicalVisualOverflowRect.maxX() - markerLogicalLeft); newLogicalVisualOverflowRect.setX(markerLogicalLeft); if (box == &rootBox) adjustOverflow = true; } if (markerLogicalLeft < newLogicalLayoutOverflowRect.x()) { newLogicalLayoutOverflowRect.setWidth(newLogicalLayoutOverflowRect.maxX() - markerLogicalLeft); newLogicalLayoutOverflowRect.setX(markerLogicalLeft); if (box == &rootBox) adjustOverflow = true; } box->setOverflowFromLogicalRects(newLogicalLayoutOverflowRect, newLogicalVisualOverflowRect, lineTop, lineBottom); if (box->renderer().hasSelfPaintingLayer()) hitSelfPaintingLayer = true; } } else { markerLogicalLeft = m_marker->lineOffsetForListItem() - lineOffset + paddingStart() + borderStart() + m_marker->marginEnd(); m_marker->inlineBoxWrapper()->adjustLineDirectionPosition(markerLogicalLeft - markerOldLogicalLeft); for (InlineFlowBox* box = m_marker->inlineBoxWrapper()->parent(); box; box = box->parent()) { LayoutRect newLogicalVisualOverflowRect = box->logicalVisualOverflowRect(lineTop, lineBottom); LayoutRect newLogicalLayoutOverflowRect = box->logicalLayoutOverflowRect(lineTop, lineBottom); if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalVisualOverflowRect.maxX() && !hitSelfPaintingLayer) { newLogicalVisualOverflowRect.setWidth(markerLogicalLeft + m_marker->logicalWidth() - newLogicalVisualOverflowRect.x()); if (box == &rootBox) adjustOverflow = true; } if (markerLogicalLeft + m_marker->logicalWidth() > newLogicalLayoutOverflowRect.maxX()) { newLogicalLayoutOverflowRect.setWidth(markerLogicalLeft + m_marker->logicalWidth() - newLogicalLayoutOverflowRect.x()); if (box == &rootBox) adjustOverflow = true; } box->setOverflowFromLogicalRects(newLogicalLayoutOverflowRect, newLogicalVisualOverflowRect, lineTop, lineBottom); if (box->renderer().hasSelfPaintingLayer()) hitSelfPaintingLayer = true; } } if (adjustOverflow) { LayoutRect markerRect(markerLogicalLeft + lineOffset, blockOffset, m_marker->width(), m_marker->height()); if (!style().isHorizontalWritingMode()) markerRect = markerRect.transposedRect(); RenderBox* o = m_marker; bool propagateVisualOverflow = true; bool propagateLayoutOverflow = true; do { o = o->parentBox(); if (o->hasOverflowClip()) propagateVisualOverflow = false; if (is<RenderBlock>(*o)) { if (propagateVisualOverflow) downcast<RenderBlock>(*o).addVisualOverflow(markerRect); if (propagateLayoutOverflow) downcast<RenderBlock>(*o).addLayoutOverflow(markerRect); } if (o->hasOverflowClip()) propagateLayoutOverflow = false; if (o->hasSelfPaintingLayer()) propagateVisualOverflow = false; markerRect.moveBy(-o->location()); } while (o != this && propagateVisualOverflow && propagateLayoutOverflow); } }