示例#1
0
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();
    }

}
示例#2
0
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();
    }

}
示例#3
0
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());
        }
    }
}
示例#4
0
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;
}