📄 renderobject.cpp
字号:
// We have gone from not affecting the inline status of the parent flow to suddenly // having an impact. See if there is a mismatch between the parent flow's // childrenInline() state and our state. setInline(style()->isDisplayInlineType()); if (isInline() != parent()->childrenInline()) { if (!isInline()) toRenderBoxModelObject(parent())->childBecameNonInline(this); else { // An anonymous block must be made to wrap this inline. RenderBlock* block = toRenderBlock(parent())->createAnonymousBlock(); RenderObjectChildList* childlist = parent()->virtualChildren(); childlist->insertChildNode(parent(), block, this); block->children()->appendChildNode(block, childlist->removeChildNode(parent(), this)); } }}void RenderObject::setAnimatableStyle(PassRefPtr<RenderStyle> style){ if (!isText() && style) setStyle(animation()->updateAnimations(this, style.get())); else setStyle(style);}StyleDifference RenderObject::adjustStyleDifference(StyleDifference diff, unsigned contextSensitiveProperties) const{#if USE(ACCELERATED_COMPOSITING) // If transform changed, and we are not composited, need to do a layout. if (contextSensitiveProperties & ContextSensitivePropertyTransform) // Text nodes share style with their parents but transforms don't apply to them, // hence the !isText() check. // FIXME: when transforms are taken into account for overflow, we will need to do a layout. if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited())) diff = StyleDifferenceLayout; else if (diff < StyleDifferenceRecompositeLayer) diff = StyleDifferenceRecompositeLayer; // If opacity changed, and we are not composited, need to repaint (also // ignoring text nodes) if (contextSensitiveProperties & ContextSensitivePropertyOpacity) if (!isText() && (!hasLayer() || !toRenderBoxModelObject(this)->layer()->isComposited())) diff = StyleDifferenceRepaintLayer; else if (diff < StyleDifferenceRecompositeLayer) diff = StyleDifferenceRecompositeLayer;#else UNUSED_PARAM(contextSensitiveProperties);#endif // If we have no layer(), just treat a RepaintLayer hint as a normal Repaint. if (diff == StyleDifferenceRepaintLayer && !hasLayer()) diff = StyleDifferenceRepaint; return diff;}void RenderObject::setStyle(PassRefPtr<RenderStyle> style){ if (m_style == style) return; StyleDifference diff = StyleDifferenceEqual; unsigned contextSensitiveProperties = ContextSensitivePropertyNone; if (m_style) diff = m_style->diff(style.get(), contextSensitiveProperties); diff = adjustStyleDifference(diff, contextSensitiveProperties); styleWillChange(diff, style.get()); RefPtr<RenderStyle> oldStyle = m_style.release(); m_style = style; updateFillImages(oldStyle ? oldStyle->backgroundLayers() : 0, m_style ? m_style->backgroundLayers() : 0); updateFillImages(oldStyle ? oldStyle->maskLayers() : 0, m_style ? m_style->maskLayers() : 0); updateImage(oldStyle ? oldStyle->borderImage().image() : 0, m_style ? m_style->borderImage().image() : 0); updateImage(oldStyle ? oldStyle->maskBoxImage().image() : 0, m_style ? m_style->maskBoxImage().image() : 0); // We need to ensure that view->maximalOutlineSize() is valid for any repaints that happen // during styleDidChange (it's used by clippedOverflowRectForRepaint()). if (m_style->outlineWidth() > 0 && m_style->outlineSize() > maximalOutlineSize(PaintPhaseOutline)) toRenderView(document()->renderer())->setMaximalOutlineSize(m_style->outlineSize()); styleDidChange(diff, oldStyle.get()); if (!m_parent || isText()) return; // Now that the layer (if any) has been updated, we need to adjust the diff again, // check whether we should layout now, and decide if we need to repaint. StyleDifference updatedDiff = adjustStyleDifference(diff, contextSensitiveProperties); if (diff <= StyleDifferenceLayoutPositionedMovementOnly) { if (updatedDiff == StyleDifferenceLayout) setNeedsLayoutAndPrefWidthsRecalc(); else if (updatedDiff == StyleDifferenceLayoutPositionedMovementOnly) setNeedsPositionedMovementLayout(); } if (updatedDiff == StyleDifferenceRepaintLayer || updatedDiff == StyleDifferenceRepaint) { // Do a repaint with the new style now, e.g., for example if we go from // not having an outline to having an outline. repaint(); }}void RenderObject::setStyleInternal(PassRefPtr<RenderStyle> style){ m_style = style;}void RenderObject::styleWillChange(StyleDifference diff, const RenderStyle* newStyle){ if (m_style) { // If our z-index changes value or our visibility changes, // we need to dirty our stacking context's z-order list. if (newStyle) {#if ENABLE(DASHBOARD_SUPPORT) if (m_style->visibility() != newStyle->visibility() || m_style->zIndex() != newStyle->zIndex() || m_style->hasAutoZIndex() != newStyle->hasAutoZIndex()) document()->setDashboardRegionsDirty(true);#endif // Keep layer hierarchy visibility bits up to date if visibility changes. if (m_style->visibility() != newStyle->visibility()) { if (RenderLayer* l = enclosingLayer()) { if (newStyle->visibility() == VISIBLE) l->setHasVisibleContent(true); else if (l->hasVisibleContent() && (this == l->renderer() || l->renderer()->style()->visibility() != VISIBLE)) { l->dirtyVisibleContentStatus(); if (diff > StyleDifferenceRepaintLayer) repaint(); } } } } if (m_parent && (diff == StyleDifferenceRepaint || newStyle->outlineSize() < m_style->outlineSize())) repaint(); if (isFloating() && (m_style->floating() != newStyle->floating())) // For changes in float styles, we need to conceivably remove ourselves // from the floating objects list. toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists(); else if (isPositioned() && (newStyle->position() != AbsolutePosition && newStyle->position() != FixedPosition)) // For changes in positioning styles, we need to conceivably remove ourselves // from the positioned objects list. toRenderBox(this)->removeFloatingOrPositionedChildFromBlockLists(); s_affectsParentBlock = isFloatingOrPositioned() && (!newStyle->isFloating() && newStyle->position() != AbsolutePosition && newStyle->position() != FixedPosition) && parent() && (parent()->isBlockFlow() || parent()->isRenderInline()); // reset style flags if (diff == StyleDifferenceLayout || diff == StyleDifferenceLayoutPositionedMovementOnly) { m_floating = false; m_positioned = false; m_relPositioned = false; } m_paintBackground = false; m_hasOverflowClip = false; m_hasTransform = false; m_hasReflection = false; } else s_affectsParentBlock = false; if (view()->frameView()) { // FIXME: A better solution would be to only invalidate the fixed regions when scrolling. It's overkill to // prevent the entire view from blitting on a scroll. bool newStyleSlowScroll = newStyle && (newStyle->position() == FixedPosition || newStyle->hasFixedBackgroundImage()); bool oldStyleSlowScroll = m_style && (m_style->position() == FixedPosition || m_style->hasFixedBackgroundImage()); if (oldStyleSlowScroll != newStyleSlowScroll) { if (oldStyleSlowScroll) view()->frameView()->removeSlowRepaintObject(); if (newStyleSlowScroll) view()->frameView()->addSlowRepaintObject(); } }}void RenderObject::styleDidChange(StyleDifference diff, const RenderStyle*){ if (s_affectsParentBlock) handleDynamicFloatPositionChange(); if (!m_parent) return; if (diff == StyleDifferenceLayout) setNeedsLayoutAndPrefWidthsRecalc(); else if (diff == StyleDifferenceLayoutPositionedMovementOnly) setNeedsPositionedMovementLayout(); // Don't check for repaint here; we need to wait until the layer has been // updated by subclasses before we know if we have to repaint (in setStyle()).}void RenderObject::updateFillImages(const FillLayer* oldLayers, const FillLayer* newLayers){ // FIXME: This will be slow when a large number of images is used. Fix by using a dict. for (const FillLayer* currOld = oldLayers; currOld; currOld = currOld->next()) { if (currOld->image() && (!newLayers || !newLayers->containsImage(currOld->image()))) currOld->image()->removeClient(this); } for (const FillLayer* currNew = newLayers; currNew; currNew = currNew->next()) { if (currNew->image() && (!oldLayers || !oldLayers->containsImage(currNew->image()))) currNew->image()->addClient(this); }}void RenderObject::updateImage(StyleImage* oldImage, StyleImage* newImage){ if (oldImage != newImage) { if (oldImage) oldImage->removeClient(this); if (newImage) newImage->addClient(this); }}IntRect RenderObject::viewRect() const{ return view()->viewRect();}FloatPoint RenderObject::localToAbsolute(FloatPoint localPoint, bool fixed, bool useTransforms) const{ TransformState transformState(TransformState::ApplyTransformDirection, localPoint); mapLocalToContainer(0, fixed, useTransforms, transformState); transformState.flatten(); return transformState.lastPlanarPoint();}FloatPoint RenderObject::absoluteToLocal(FloatPoint containerPoint, bool fixed, bool useTransforms) const{ TransformState transformState(TransformState::UnapplyInverseTransformDirection, containerPoint); mapAbsoluteToLocalPoint(fixed, useTransforms, transformState); transformState.flatten(); return transformState.lastPlanarPoint();}void RenderObject::mapLocalToContainer(RenderBoxModelObject* repaintContainer, bool fixed, bool useTransforms, TransformState& transformState) const{ if (repaintContainer == this) return; RenderObject* o = parent(); if (!o) return; if (o->hasOverflowClip()) transformState.move(-toRenderBox(o)->layer()->scrolledContentOffset()); o->mapLocalToContainer(repaintContainer, fixed, useTransforms, transformState);}void RenderObject::mapAbsoluteToLocalPoint(bool fixed, bool useTransforms, TransformState& transformState) const{ RenderObject* o = parent(); if (o) { o->mapAbsoluteToLocalPoint(fixed, useTransforms, transformState); if (o->hasOverflowClip()) transformState.move(toRenderBox(o)->layer()->scrolledContentOffset()); }}TransformationMatrix RenderObject::transformFromContainer(const RenderObject* containerObject, const IntSize& offsetInContainer) const{ TransformationMatrix containerTransform; containerTransform.translate(offsetInContainer.width(), offsetInContainer.height()); RenderLayer* layer; if (hasLayer() && (layer = toRenderBox(this)->layer()) && layer->transform()) containerTransform.multLeft(layer->currentTransform()); if (containerObject && containerObject->style()->hasPerspective()) { // Perpsective on the container affects us, so we have to factor it in here. ASSERT(containerObject->hasLayer()); FloatPoint perspectiveOrigin = toRenderBox(containerObject)->layer()->perspectiveOrigin(); TransformationMatrix perspectiveMatrix; perspectiveMatrix.applyPerspective(containerObject->style()->perspective()); containerTransform.translateRight3d(-perspectiveOrigin.x(), -perspectiveOrigin.y(), 0); containerTransform.multiply(perspectiveMatrix); containerTransform.translateRight3d(perspectiveOrigin.x(), perspectiveOrigin.y(), 0); } return containerTransform;}FloatQuad RenderObject::localToContainerQuad(const FloatQuad& localQuad, RenderBoxModelObject* repaintContainer, bool fixed) const{ TransformState transformState(TransformState::ApplyTransformDirection, FloatPoint(), &localQuad); mapLocalToContainer(repaintContainer, fixed, true, transformState); transformState.flatten(); return transformState.lastPlanarQuad();}IntSize RenderObject::offsetFromContainer(RenderObject* o) const{ ASSERT(o == container()); IntSize offset; if (o->hasOverflowClip()) offset -= toRenderBox(o)->layer()->scrolledContentOffset(); return offset;}IntRect RenderObject::localCaretRect(InlineBox*, int, int* extraWidthToEndOfLine){ if (extraWidthToEndOfLine) *extraWidthToEndOfLine = 0; return IntRect();}RenderView* RenderObject::view() const{ return toRenderView(document()->renderer());}bool RenderObject::isRooted(RenderView** view){ RenderObject* o = this; while (o->parent()) o = o->parent(); if (!o->isRenderView()) return false; if (view) *view = toRenderView(o); return true;}bool RenderObject::hasOutlineAnnotation() const{ return node() && node()->isLink() && document()->printing();}RenderObject* RenderObject::container() const{ // This method is extremely similar to containingBlock(), but with a few notable // exceptions. // (1) It can be used on orphaned subtrees, i.e., it can be called safely even when // the object is not part of the primary document subtree yet. // (2) For normal flow e
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -