void RenderListItem::insertOrMoveMarkerRendererIfNeeded() { // Sanity check the location of our marker. if (!m_marker) return; RenderElement* currentParent = m_marker->parent(); RenderBlock* newParent = getParentOfFirstLineBox(this, m_marker); if (!newParent) { // If the marker is currently contained inside an anonymous box, // then we are the only item in that anonymous box (since no line box // parent was found). It's ok to just leave the marker where it is // in this case. if (currentParent && currentParent->isAnonymousBlock()) return; newParent = this; } if (newParent != currentParent) { // Removing and adding the marker can trigger repainting in // containers other than ourselves, so we need to disable LayoutState. LayoutStateDisabler layoutStateDisabler(&view()); m_marker->removeFromParent(); newParent->addChild(m_marker, firstNonMarkerChild(newParent)); m_marker->updateMarginsAndContent(); // If current parent is an anonymous block that has lost all its children, destroy it. if (currentParent && currentParent->isAnonymousBlock() && !currentParent->firstChild() && !toRenderBlock(currentParent)->continuation()) currentParent->destroy(); } }
void RenderListItem::insertOrMoveMarkerRendererIfNeeded() { // Sanity check the location of our marker. if (!m_marker) return; // FIXME: Do not even try to reposition the marker when we are not in layout // until after we fixed webkit.org/b/163789. if (!view().frameView().isInRenderTreeLayout()) return; RenderElement* currentParent = m_marker->parent(); RenderBlock* newParent = getParentOfFirstLineBox(*this, *m_marker); if (!newParent) { // If the marker is currently contained inside an anonymous box, // then we are the only item in that anonymous box (since no line box // parent was found). It's ok to just leave the marker where it is // in this case. if (currentParent && currentParent->isAnonymousBlock()) return; if (multiColumnFlowThread()) newParent = multiColumnFlowThread(); else newParent = this; } if (newParent != currentParent) { // Removing and adding the marker can trigger repainting in // containers other than ourselves, so we need to disable LayoutState. LayoutStateDisabler layoutStateDisabler(view()); // Mark the parent dirty so that when the marker gets inserted into the tree // and dirties ancestors, it stops at the parent. newParent->setChildNeedsLayout(MarkOnlyThis); m_marker->setNeedsLayout(MarkOnlyThis); m_marker->removeFromParent(); newParent->addChild(m_marker, firstNonMarkerChild(*newParent)); m_marker->updateMarginsAndContent(); // If current parent is an anonymous block that has lost all its children, destroy it. if (currentParent && currentParent->isAnonymousBlock() && !currentParent->firstChild() && !downcast<RenderBlock>(*currentParent).continuation()) currentParent->destroy(); } }
void TextAutoSizingValue::reset() { HashSet<RefPtr<Node> >::iterator end = m_autoSizedNodes.end(); for (HashSet<RefPtr<Node> >::iterator i = m_autoSizedNodes.begin(); i != end; ++i) { const RefPtr<Node>& autoSizingNode = *i; RenderText* text = static_cast<RenderText*>(autoSizingNode->renderer()); if (!text) continue; // Reset the font size back to the original specified size FontDescription fontDescription = text->style().fontDescription(); float originalSize = fontDescription.specifiedSize(); if (fontDescription.computedSize() != originalSize) { fontDescription.setComputedSize(originalSize); RefPtr<RenderStyle> style = cloneRenderStyleWithState(text->style()); style->setFontDescription(fontDescription); style->font().update(autoSizingNode->document().ensureStyleResolver().fontSelector()); text->parent()->setStyle(style.releaseNonNull()); } // Reset the line height of the parent. RenderElement* parentRenderer = text->parent(); if (!parentRenderer) continue; if (parentRenderer->isAnonymousBlock()) parentRenderer = parentRenderer->parent(); const RenderStyle& parentStyle = parentRenderer->style(); Length originalLineHeight = parentStyle.specifiedLineHeight(); if (originalLineHeight != parentStyle.lineHeight()) { RefPtr<RenderStyle> newParentStyle = cloneRenderStyleWithState(parentStyle); newParentStyle->setLineHeight(originalLineHeight); newParentStyle->setFontDescription(fontDescription); newParentStyle->font().update(autoSizingNode->document().ensureStyleResolver().fontSelector()); parentRenderer->setStyle(newParentStyle.releaseNonNull()); } } }
bool TextAutoSizingValue::adjustNodeSizes() { bool objectsRemoved = false; // Remove stale nodes. Nodes may have had their renderers detached. We'll // also need to remove the style from the documents m_textAutoSizedNodes // collection. Return true indicates we need to do that removal. Vector<RefPtr<Node> > nodesForRemoval; HashSet<RefPtr<Node> >::iterator end = m_autoSizedNodes.end(); for (HashSet<RefPtr<Node> >::iterator i = m_autoSizedNodes.begin(); i != end; ++i) { RefPtr<Node> autoSizingNode = *i; RenderText* text = static_cast<RenderText*>(autoSizingNode->renderer()); if (!text || !text->style().textSizeAdjust().isAuto() || !text->candidateComputedTextSize()) { // remove node. nodesForRemoval.append(autoSizingNode); objectsRemoved = true; } } unsigned count = nodesForRemoval.size(); for (unsigned i = 0; i < count; i++) m_autoSizedNodes.remove(nodesForRemoval[i]); // If we only have one piece of text with the style on the page don't // adjust it's size. if (m_autoSizedNodes.size() <= 1) return objectsRemoved; // Compute average size float cumulativeSize = 0; end = m_autoSizedNodes.end(); for (HashSet<RefPtr<Node> >::iterator i = m_autoSizedNodes.begin(); i != end; ++i) { RefPtr<Node> autoSizingNode = *i; RenderText* renderText = static_cast<RenderText*>(autoSizingNode->renderer()); cumulativeSize += renderText->candidateComputedTextSize(); } float averageSize = roundf(cumulativeSize / m_autoSizedNodes.size()); // Adjust sizes bool firstPass = true; end = m_autoSizedNodes.end(); for (HashSet<RefPtr<Node> >::iterator i = m_autoSizedNodes.begin(); i != end; ++i) { const RefPtr<Node>& autoSizingNode = *i; RenderText* text = static_cast<RenderText*>(autoSizingNode->renderer()); if (text && text->style().fontDescription().computedSize() != averageSize) { float specifiedSize = text->style().fontDescription().specifiedSize(); float scaleChange = averageSize / specifiedSize; if (scaleChange > MAX_SCALE_INCREASE && firstPass) { firstPass = false; averageSize = roundf(specifiedSize * MAX_SCALE_INCREASE); scaleChange = averageSize / specifiedSize; } RefPtr<RenderStyle> style = cloneRenderStyleWithState(text->style()); FontDescription fontDescription = style->fontDescription(); fontDescription.setComputedSize(averageSize); style->setFontDescription(fontDescription); style->font().update(autoSizingNode->document().ensureStyleResolver().fontSelector()); text->parent()->setStyle(style.releaseNonNull()); RenderElement* parentRenderer = text->parent(); if (parentRenderer->isAnonymousBlock()) parentRenderer = parentRenderer->parent(); // If we have a list we should resize ListMarkers separately. RenderObject* listMarkerRenderer = parentRenderer->firstChild(); if (listMarkerRenderer->isListMarker()) { RefPtr<RenderStyle> style = cloneRenderStyleWithState(listMarkerRenderer->style()); style->setFontDescription(fontDescription); style->font().update(autoSizingNode->document().ensureStyleResolver().fontSelector()); toRenderListMarker(*listMarkerRenderer).setStyle(style.releaseNonNull()); } // Resize the line height of the parent. const RenderStyle& parentStyle = parentRenderer->style(); Length lineHeightLength = parentStyle.specifiedLineHeight(); int specifiedLineHeight = 0; if (lineHeightLength.isPercent()) specifiedLineHeight = minimumValueForLength(lineHeightLength, fontDescription.specifiedSize()); else specifiedLineHeight = lineHeightLength.value(); int lineHeight = specifiedLineHeight * scaleChange; if (!lineHeightLength.isFixed() || lineHeightLength.value() != lineHeight) { RefPtr<RenderStyle> newParentStyle = cloneRenderStyleWithState(parentStyle); newParentStyle->setLineHeight(Length(lineHeight, Fixed)); newParentStyle->setSpecifiedLineHeight(lineHeightLength); newParentStyle->setFontDescription(fontDescription); newParentStyle->font().update(autoSizingNode->document().ensureStyleResolver().fontSelector()); parentRenderer->setStyle(newParentStyle.releaseNonNull()); } } } return objectsRemoved; }