📄 render_object.cpp
字号:
void RenderObject::getAbsoluteRepaintRectIncludingFloats(QRect& bounds, QRect& fullBounds){ bounds = fullBounds = getAbsoluteRepaintRect();}void RenderObject::computeAbsoluteRepaintRect(QRect& r, bool f){ if (parent()) return parent()->computeAbsoluteRepaintRect(r, f);}void RenderObject::dirtyLinesFromChangedChild(RenderObject* child){}#ifndef NDEBUGQString RenderObject::information() const{ QString str; QTextStream ts( &str, IO_WriteOnly ); ts << renderName() << "(" << (style() ? style()->refCount() : 0) << ")" << ": " << (void*)this << " "; if (isInline()) ts << "il "; if (childrenInline()) ts << "ci "; if (isFloating()) ts << "fl "; if (isAnonymous()) ts << "an "; if (isRelPositioned()) ts << "rp "; if (isPositioned()) ts << "ps "; if (needsLayout()) ts << "nl "; if (m_recalcMinMax) ts << "rmm "; if (mouseInside()) ts << "mi "; if (style() && style()->zIndex()) ts << "zI: " << style()->zIndex(); if (element() && element()->active()) ts << "act "; if (element() && element()->hasAnchor()) ts << "anchor "; if (element() && element()->focused()) ts << "focus "; if (element()) ts << " <" << getTagName(element()->id()).string() << ">"; ts << " (" << xPos() << "," << yPos() << "," << width() << "," << height() << ")" << (isTableCell() ? ( QString::fromLatin1(" [r=") + QString::number( static_cast<const RenderTableCell *>(this)->row() ) + QString::fromLatin1(" c=") + QString::number( static_cast<const RenderTableCell *>(this)->col() ) + QString::fromLatin1(" rs=") + QString::number( static_cast<const RenderTableCell *>(this)->rowSpan() ) + QString::fromLatin1(" cs=") + QString::number( static_cast<const RenderTableCell *>(this)->colSpan() ) + QString::fromLatin1("]") ) : QString::null ); return str;}void RenderObject::printTree(int indent) const{ QString ind; ind.fill(' ', indent); kdDebug() << ind << information() << endl; RenderObject *child = firstChild(); while( child != 0 ) { child->printTree(indent+2); child = child->nextSibling(); }}void RenderObject::dump(QTextStream *stream, QString ind) const{ if (isAnonymous()) { *stream << " anonymous"; } if (isFloating()) { *stream << " floating"; } if (isPositioned()) { *stream << " positioned"; } if (isRelPositioned()) { *stream << " relPositioned"; } if (isText()) { *stream << " text"; } if (isInline()) { *stream << " inline"; } if (isReplaced()) { *stream << " replaced"; } if (shouldPaintBackgroundOrBorder()) { *stream << " paintBackground"; } if (needsLayout()) { *stream << " needsLayout"; } if (minMaxKnown()) { *stream << " minMaxKnown"; } *stream << endl; RenderObject *child = firstChild(); while( child != 0 ) { *stream << ind << child->renderName() << ": "; child->dump(stream,ind+" "); child = child->nextSibling(); }}#endifbool RenderObject::shouldSelect() const{ const RenderObject* curr = this; DOM::NodeImpl *node = 0; bool forcedOn = false; while (curr) { if (curr->style()->userSelect() == SELECT_TEXT) forcedOn = true; if (!forcedOn && curr->style()->userSelect() == SELECT_NONE) return false; if (!node) node = curr->element(); curr = curr->parent(); } // somewhere up the render tree there must be an element! assert(node); return node->dispatchHTMLEvent(DOM::EventImpl::SELECTSTART_EVENT, true, true);}DOM::NodeImpl* RenderObject::draggableNode(bool dhtmlOK, bool uaOK, bool& dhtmlWillDrag) const{ if (!dhtmlOK && !uaOK) return 0; const RenderObject* curr = this; while (curr) { DOM::NodeImpl *elt = curr->element(); if (elt && elt->nodeType() == Node::TEXT_NODE) { // Since there's no way for the author to address the -khtml-user-drag style for a text node, // we use our own judgement. if (uaOK && canvas()->view()->part()->shouldDragAutoNode(curr->node())) { dhtmlWillDrag = false; return curr->node(); } else if (curr->shouldSelect()) { // 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(); } else if (uaOK && dragMode == DRAG_AUTO && canvas()->view()->part()->shouldDragAutoNode(curr->node())) { dhtmlWillDrag = false; return curr->node(); } } curr = curr->parent(); } return 0;}void RenderObject::selectionStartEnd(int& spos, int& epos){ if (parent()) parent()->selectionStartEnd(spos, epos);}RenderBlock* RenderObject::createAnonymousBlock(){ RenderStyle *newStyle = new (renderArena()) RenderStyle(); newStyle->inheritFrom(m_style); newStyle->setDisplay(BLOCK); RenderBlock *newBox = new (renderArena()) RenderBlock(document() /* anonymous box */); newBox->setStyle(newStyle); return newBox;}void RenderObject::handleDynamicFloatPositionChange(){ // 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()) { if (parent()->isRenderInline()) { // We have to split the parent flow. RenderInline* parentInline = static_cast<RenderInline*>(parent()); RenderBlock* newBox = parentInline->createAnonymousBlock(); RenderFlow* oldContinuation = parent()->continuation(); parentInline->setContinuation(newBox); RenderObject* beforeChild = nextSibling(); parent()->removeChildNode(this); parentInline->splitFlow(beforeChild, newBox, this, oldContinuation); } else if (parent()->isRenderBlock()) static_cast<RenderBlock*>(parent())->makeChildrenNonInline(); } else { // An anonymous block must be made to wrap this inline. RenderBlock* box = createAnonymousBlock(); parent()->insertChildNode(box, this); box->appendChildNode(parent()->removeChildNode(this)); } }}void RenderObject::setStyle(RenderStyle *style){ if (m_style == style) return; bool affectsParentBlock = false; RenderStyle::Diff d = RenderStyle::Equal; 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 (style) { if ((m_style->hasAutoZIndex() != style->hasAutoZIndex() || m_style->zIndex() != style->zIndex() || m_style->visibility() != style->visibility()) && layer()) { layer()->stackingContext()->dirtyZOrderLists(); if (m_style->hasAutoZIndex() != style->hasAutoZIndex() || m_style->visibility() != style->visibility()) layer()->dirtyZOrderLists(); } } d = m_style->diff(style); // The background of the root element or the body element could propagate up to // the canvas. Just dirty the entire canvas when our style changes substantially. if (d >= RenderStyle::Visible && element() && (element()->id() == ID_HTML || element()->id() == ID_BODY)) canvas()->repaint(); else if (m_parent && d == RenderStyle::Visible && !isText()) // Do a repaint with the old style first, e.g., for example if we go from // having an outline to not having an outline. repaint(); if (m_style->position() != style->position() && layer()) layer()->repaintIncludingDescendants(); if (isFloating() && (m_style->floating() != style->floating())) // For changes in float styles, we need to conceivably remove ourselves // from the floating objects list. removeFromObjectLists(); else if (isPositioned() && (style->position() != ABSOLUTE && style->position() != FIXED)) // For changes in positioning styles, we need to conceivably remove ourselves // from the positioned objects list. removeFromObjectLists(); // reset style flags m_floating = false; m_positioned = false; m_relPositioned = false; m_paintBackground = false; m_hasOverflowClip = false; affectsParentBlock = m_style && isFloatingOrPositioned() && (!style->isFloating() && style->position() != ABSOLUTE && style->position() != FIXED) && parent() && (parent()->isBlockFlow() || parent()->isInlineFlow()); } RenderStyle *oldStyle = m_style; m_style = style; CachedImage* ob = 0; CachedImage* nb = 0; if (m_style) { m_style->ref(); nb = m_style->backgroundImage(); } if (oldStyle) { ob = oldStyle->backgroundImage(); oldStyle->deref(renderArena()); } if (ob != nb) { if (ob) ob->deref(this); if (nb) nb->ref(this); } setShouldPaintBackgroundOrBorder((m_style->backgroundColor().isValid() && qAlpha(m_style->backgroundColor().rgb()) > 0) || m_style->hasBorder() || nb ); if (affectsParentBlock) handleDynamicFloatPositionChange(); // No need to ever schedule repaints from a style change of a text run, since // we already did this for the parent of the text run. if (d >= RenderStyle::Position && m_parent) setNeedsLayoutAndMinMaxRecalc(); else if (d == RenderStyle::Visible && !isText() && m_parent) repaint();}QRect RenderObject::viewRect() const{ return containingBlock()->viewRect();}bool RenderObject::absolutePosition(int &xPos, int &yPos, bool f){ RenderObject* o = parent(); if (o) { o->absolutePosition(xPos, yPos, f); if (o->hasOverflowClip()) o->layer()->subtractScrollOffset(xPos, yPos); return true; } else { xPos = yPos = 0; return false; }}void RenderObject::caretPos(int /*offset*/, bool /*override*/, int &_x, int &_y, int &width, int &height){ _x = _y = height = -1; width = 1; // the caret has a default width of one pixel. If you want // to check for validity, only test the x-coordinate for >= 0.}int RenderObject::paddingTop() const{ int w = 0; Length padding = m_style->paddingTop(); if (padding.isPercent()) w = containingBlock()->contentWidth(); w = padding.minWidth(w); if ( isTableCell() && padding.isVariable() ) w = static_cast<const RenderTableCell *>(this)->table()->cellPadding(); return w;}int RenderObject::paddingBottom() const{ int w = 0; Length padding = style()->paddingBottom(); if (padding.isPercent()) w = containingBlock()->contentWidth(); w = padding.minWidth(w); if ( isTableCell() && padding.isVariable() ) w = static_cast<const RenderTableCell *>(this)->table()->cellPadding(); return w;}int RenderObject::paddingLeft() const{ int w = 0; Length padding = style()->paddingLeft(); if (padding.isPercent()) w = containingBlock()->contentWidth(); w = padding.minWidth(w); if ( isTableCell() && padding.isVariable() ) w = static_cast<const RenderTableCell *>(this)->table()->cellPadding(); return w;}int RenderObject::paddingRight() const{ int w = 0; Length padding = style()->paddingRight(); if (padding.isPercent()) w = containingBlock()->contentWidth(); w = padding.minWidth(w); if ( isTableCell() && padding.isVariable() ) w = static_cast<const RenderTableCell *>(this)->table()->cellPadding(); return w;}RenderCanvas* RenderObject::canvas() const{ return static_cast<RenderCanvas*>(document()->renderer());}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 elements, it just returns the parent. // (3) For absolute positioned elements, it will return a relative positioned inline. // containingBlock() simply skips relpositioned inlines and lets an enclosing block handle // the layout of the positioned object. This does mean that calcAbsoluteHorizontal and // calcAbsoluteVertical have to use container(). EPosition pos = m_style->position(); RenderObject *o = 0; if (!isText() && pos == FIXED) { // container() can be called on an object that is not in the // tree yet. We don't call canvas() since it will assert if it // can't get back to the canvas. Instead we just walk as high up // as we can. If we're in the tree, we'll get the root. If we // aren't we'll get the root of our little subtree (most likely // we'll just return 0). o = parent(); while (o && o->parent()) o = o->parent(); } else if (!isText() && pos == ABSOLUTE) { // Same goes here. We technically just want our containing block, but // we may not have one if we're part of an uninstalled subtree. We'll // climb as high as we can though. o = parent(); while (o && o->style()->position() == STATIC && !o->isRoot() && !o->isCanvas()) o = o->parent(); } else o = parent(); return o;}#if 0static void checkFloats(RenderObject* o, RenderObject* f){ if (o->isRenderBlock()) { RenderBlock* b = static_cast<RenderBlock*>(o); if (b->containsFloat(f)) assert(false); } for (RenderObject* c = o->firstChild(); c; c = c->nextSibling()) checkFloats(c, f);}#endifvoid RenderObject::removeFromObjectLists(){ if (isFloating()) { RenderBlock* outermostBlock = containingBlock(); for (RenderBlock* p = outermostBlock; p && !p->isCanvas(); p = p->containingBlock()) {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -