📄 renderobject.cpp
字号:
size_t n = rects.size(); if (!n) return IntRect(); IntRect result = rects[0]; for (size_t i = 1; i < n; ++i) result.unite(rects[i]); return result;}void RenderObject::addAbsoluteRectForLayer(IntRect& result){ if (hasLayer()) result.unite(absoluteBoundingBoxRect()); for (RenderObject* current = firstChild(); current; current = current->nextSibling()) current->addAbsoluteRectForLayer(result);}IntRect RenderObject::paintingRootRect(IntRect& topLevelRect){ IntRect result = absoluteBoundingBoxRect(); topLevelRect = result; for (RenderObject* current = firstChild(); current; current = current->nextSibling()) current->addAbsoluteRectForLayer(result); return result;}void RenderObject::paint(PaintInfo& /*paintInfo*/, int /*tx*/, int /*ty*/){}RenderBoxModelObject* RenderObject::containerForRepaint() const{#if USE(ACCELERATED_COMPOSITING) if (RenderView* v = view()) { if (v->usesCompositing()) { RenderLayer* compLayer = enclosingLayer()->enclosingCompositingLayer(); return compLayer ? compLayer->renderer() : 0; } }#endif // Do root-relative repaint. return 0;}void RenderObject::repaintUsingContainer(RenderBoxModelObject* repaintContainer, const IntRect& r, bool immediate){ if (!repaintContainer || repaintContainer->isRenderView()) { RenderView* v = repaintContainer ? toRenderView(repaintContainer) : view(); v->repaintViewRectangle(r, immediate); } else {#if USE(ACCELERATED_COMPOSITING) RenderView* v = view(); if (v->usesCompositing()) { ASSERT(repaintContainer->hasLayer() && repaintContainer->layer()->isComposited()); repaintContainer->layer()->setBackingNeedsRepaintInRect(r); }#else ASSERT_NOT_REACHED();#endif }}void RenderObject::repaint(bool immediate){ // Don't repaint if we're unrooted (note that view() still returns the view when unrooted) RenderView* view; if (!isRooted(&view)) return; if (view->printing()) return; // Don't repaint if we're printing. RenderBoxModelObject* repaintContainer = containerForRepaint(); repaintUsingContainer(repaintContainer ? repaintContainer : view, clippedOverflowRectForRepaint(repaintContainer), immediate);}void RenderObject::repaintRectangle(const IntRect& r, bool immediate){ // Don't repaint if we're unrooted (note that view() still returns the view when unrooted) RenderView* view; if (!isRooted(&view)) return; if (view->printing()) return; // Don't repaint if we're printing. IntRect dirtyRect(r); // FIXME: layoutDelta needs to be applied in parts before/after transforms and // repaint containers. https://bugs.webkit.org/show_bug.cgi?id=23308 dirtyRect.move(view->layoutDelta()); RenderBoxModelObject* repaintContainer = containerForRepaint(); computeRectForRepaint(repaintContainer, dirtyRect); repaintUsingContainer(repaintContainer ? repaintContainer : view, dirtyRect, immediate);}bool RenderObject::repaintAfterLayoutIfNeeded(RenderBoxModelObject* repaintContainer, const IntRect& oldBounds, const IntRect& oldOutlineBox){ RenderView* v = view(); if (v->printing()) return false; // Don't repaint if we're printing. IntRect newBounds = clippedOverflowRectForRepaint(repaintContainer); IntRect newOutlineBox; bool fullRepaint = selfNeedsLayout(); // Presumably a background or a border exists if border-fit:lines was specified. if (!fullRepaint && style()->borderFit() == BorderFitLines) fullRepaint = true; if (!fullRepaint) { newOutlineBox = outlineBoundsForRepaint(repaintContainer); if (newOutlineBox.location() != oldOutlineBox.location() || (mustRepaintBackgroundOrBorder() && (newBounds != oldBounds || newOutlineBox != oldOutlineBox))) fullRepaint = true; } if (!repaintContainer) repaintContainer = v; if (fullRepaint) { repaintUsingContainer(repaintContainer, oldBounds); if (newBounds != oldBounds) repaintUsingContainer(repaintContainer, newBounds); return true; } if (newBounds == oldBounds && newOutlineBox == oldOutlineBox) return false; int deltaLeft = newBounds.x() - oldBounds.x(); if (deltaLeft > 0) repaintUsingContainer(repaintContainer, IntRect(oldBounds.x(), oldBounds.y(), deltaLeft, oldBounds.height())); else if (deltaLeft < 0) repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), newBounds.y(), -deltaLeft, newBounds.height())); int deltaRight = newBounds.right() - oldBounds.right(); if (deltaRight > 0) repaintUsingContainer(repaintContainer, IntRect(oldBounds.right(), newBounds.y(), deltaRight, newBounds.height())); else if (deltaRight < 0) repaintUsingContainer(repaintContainer, IntRect(newBounds.right(), oldBounds.y(), -deltaRight, oldBounds.height())); int deltaTop = newBounds.y() - oldBounds.y(); if (deltaTop > 0) repaintUsingContainer(repaintContainer, IntRect(oldBounds.x(), oldBounds.y(), oldBounds.width(), deltaTop)); else if (deltaTop < 0) repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), newBounds.y(), newBounds.width(), -deltaTop)); int deltaBottom = newBounds.bottom() - oldBounds.bottom(); if (deltaBottom > 0) repaintUsingContainer(repaintContainer, IntRect(newBounds.x(), oldBounds.bottom(), newBounds.width(), deltaBottom)); else if (deltaBottom < 0) repaintUsingContainer(repaintContainer, IntRect(oldBounds.x(), newBounds.bottom(), oldBounds.width(), -deltaBottom)); if (newOutlineBox == oldOutlineBox) return false; // We didn't move, but we did change size. Invalidate the delta, which will consist of possibly // two rectangles (but typically only one). RenderStyle* outlineStyle = outlineStyleForRepaint(); int ow = outlineStyle->outlineSize(); ShadowData* boxShadow = style()->boxShadow(); int width = abs(newOutlineBox.width() - oldOutlineBox.width()); if (width) { int shadowRight = 0; for (ShadowData* shadow = boxShadow; shadow; shadow = shadow->next) shadowRight = max(shadow->x + shadow->blur, shadowRight); int borderRight = isBox() ? toRenderBox(this)->borderRight() : 0; int borderWidth = max(-outlineStyle->outlineOffset(), max(borderRight, max(style()->borderTopRightRadius().width(), style()->borderBottomRightRadius().width()))) + max(ow, shadowRight); IntRect rightRect(newOutlineBox.x() + min(newOutlineBox.width(), oldOutlineBox.width()) - borderWidth, newOutlineBox.y(), width + borderWidth, max(newOutlineBox.height(), oldOutlineBox.height())); int right = min(newBounds.right(), oldBounds.right()); if (rightRect.x() < right) { rightRect.setWidth(min(rightRect.width(), right - rightRect.x())); repaintUsingContainer(repaintContainer, rightRect); } } int height = abs(newOutlineBox.height() - oldOutlineBox.height()); if (height) { int shadowBottom = 0; for (ShadowData* shadow = boxShadow; shadow; shadow = shadow->next) shadowBottom = max(shadow->y + shadow->blur, shadowBottom); int borderBottom = isBox() ? toRenderBox(this)->borderBottom() : 0; int borderHeight = max(-outlineStyle->outlineOffset(), max(borderBottom, max(style()->borderBottomLeftRadius().height(), style()->borderBottomRightRadius().height()))) + max(ow, shadowBottom); IntRect bottomRect(newOutlineBox.x(), min(newOutlineBox.bottom(), oldOutlineBox.bottom()) - borderHeight, max(newOutlineBox.width(), oldOutlineBox.width()), height + borderHeight); int bottom = min(newBounds.bottom(), oldBounds.bottom()); if (bottomRect.y() < bottom) { bottomRect.setHeight(min(bottomRect.height(), bottom - bottomRect.y())); repaintUsingContainer(repaintContainer, bottomRect); } } return false;}void RenderObject::repaintDuringLayoutIfMoved(const IntRect&){}void RenderObject::repaintOverhangingFloats(bool){}bool RenderObject::checkForRepaintDuringLayout() const{ // FIXME: <https://bugs.webkit.org/show_bug.cgi?id=20885> It is probably safe to also require // m_everHadLayout. Currently, only RenderBlock::layoutBlock() adds this condition. See also // <https://bugs.webkit.org/show_bug.cgi?id=15129>. return !document()->view()->needsFullRepaint() && !hasLayer();}IntRect RenderObject::rectWithOutlineForRepaint(RenderBoxModelObject* repaintContainer, int outlineWidth){ IntRect r(clippedOverflowRectForRepaint(repaintContainer)); r.inflate(outlineWidth); return r;}IntRect RenderObject::clippedOverflowRectForRepaint(RenderBoxModelObject*){ ASSERT_NOT_REACHED(); return IntRect();}void RenderObject::computeRectForRepaint(RenderBoxModelObject* repaintContainer, IntRect& rect, bool fixed){ if (repaintContainer == this) return; if (RenderObject* o = parent()) { if (o->isBlockFlow()) { RenderBlock* cb = toRenderBlock(o); if (cb->hasColumns()) cb->adjustRectForColumns(rect); } if (o->hasOverflowClip()) { // o->height() is inaccurate if we're in the middle of a layout of |o|, so use the // layer's size instead. Even if the layer's size is wrong, the layer itself will repaint // anyway if its size does change. RenderBox* boxParent = toRenderBox(o); IntRect boxRect(0, 0, boxParent->layer()->width(), boxParent->layer()->height()); int x = rect.x(); int y = rect.y(); boxParent->layer()->subtractScrolledContentOffset(x, y); // For overflow:auto/scroll/hidden. IntRect repaintRect(x, y, rect.width(), rect.height()); rect = intersection(repaintRect, boxRect); if (rect.isEmpty()) return; } o->computeRectForRepaint(repaintContainer, rect, fixed); }}void RenderObject::dirtyLinesFromChangedChild(RenderObject*){}#ifndef NDEBUGvoid RenderObject::showTreeForThis() const{ if (node()) node()->showTreeForThis();}#endif // NDEBUGColor RenderObject::selectionBackgroundColor() const{ Color color; if (style()->userSelect() != SELECT_NONE) { RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION); if (pseudoStyle && pseudoStyle->backgroundColor().isValid()) color = pseudoStyle->backgroundColor().blendWithWhite(); else color = document()->frame()->selection()->isFocusedAndActive() ? theme()->activeSelectionBackgroundColor() : theme()->inactiveSelectionBackgroundColor(); } return color;}Color RenderObject::selectionForegroundColor() const{ Color color; if (style()->userSelect() == SELECT_NONE) return color; if (RefPtr<RenderStyle> pseudoStyle = getUncachedPseudoStyle(SELECTION)) { color = pseudoStyle->textFillColor(); if (!color.isValid()) color = pseudoStyle->color(); } else color = document()->frame()->selection()->isFocusedAndActive() ? theme()->activeSelectionForegroundColor() : theme()->inactiveSelectionForegroundColor(); return color;}Node* RenderObject::draggableNode(bool dhtmlOK, bool uaOK, int x, int y, bool& dhtmlWillDrag) const{ if (!dhtmlOK && !uaOK) return 0; for (const RenderObject* curr = this; curr; curr = curr->parent()) { Node* elt = curr->node(); if (elt && elt->nodeType() == Node::TEXT_NODE) { // Since there's no way for the author to address the -webkit-user-drag style for a text node, // we use our own judgement. if (uaOK && view()->frameView()->frame()->eventHandler()->shouldDragAutoNode(curr->node(), IntPoint(x, y))) { dhtmlWillDrag = false; return curr->node(); } if (elt->canStartSelection()) // In this case we have a click in the unselected portion of text. If this text is // selectable, we want to start the selection process instead of looking for a parent // to try to drag. return 0; } else { EUserDrag dragMode = curr->style()->userDrag(); if (dhtmlOK && dragMode == DRAG_ELEMENT) { dhtmlWillDrag = true; return curr->node(); } if (uaOK && dragMode == DRAG_AUTO && view()->frameView()->frame()->eventHandler()->shouldDragAutoNode(curr->node(), IntPoint(x, y))) { dhtmlWillDrag = false; return curr->node(); } } } return 0;}void RenderObject::selectionStartEnd(int& spos, int& epos) const{ view()->selectionStartEnd(spos, epos);}void RenderObject::handleDynamicFloatPositionChange(){
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -