📄 render_object.cpp
字号:
if (p->containsFloat(this)) outermostBlock = p; } if (outermostBlock) outermostBlock->markAllDescendantsWithFloatsForLayout(this);#if 0 // Debugging code for float checking. checkFloats(canvas(), this);#endif } if (isPositioned()) { RenderObject *p; for (p = parent(); p; p = p->parent()) { if (p->isRenderBlock()) static_cast<RenderBlock*>(p)->removePositionedObject(this); } }}RenderArena* RenderObject::renderArena() const{ DOM::DocumentImpl* doc = document(); return doc ? doc->renderArena() : 0;}void RenderObject::remove(){#if APPLE_CHANGES // Delete our accessibility object if we have one. KWQAccObjectCache* cache = document()->getExistingAccObjectCache(); if (cache) cache->detach(this);#endif removeFromObjectLists(); if (parent()) //have parent, take care of the tree integrity parent()->removeChild(this);}void RenderObject::detach(){ remove(); // by default no refcounting arenaDelete(document()->renderArena(), this);}#if KWIQvoid RenderObject::arenaDelete(RenderArena *arena, void *base){ if (m_style->backgroundImage()) m_style->backgroundImage()->deref(this); if (m_style) m_style->deref(arena); void *savedBase = baseOfRenderObjectBeingDeleted; delete this; base = baseOfRenderObjectBeingDeleted; // Recover the size left there for us by operator delete and free the memory. arena->free(*(size_t *)base, base); baseOfRenderObjectBeingDeleted = savedBase;}#elsevoid RenderObject::arenaDelete(RenderArena *arena, void *base) if (m_style->backgroundImage()) m_style->backgroundImage()->deref(this); if (m_style) m_style->deref(arena); #ifndef NDEBUG void *savedBase = baseOfRenderObjectBeingDeleted; baseOfRenderObjectBeingDeleted = base;#endif delete this;#ifndef NDEBUG baseOfRenderObjectBeingDeleted = savedBase;#endif // Recover the size left there for us by operator delete and free the memory. arena->free(*(size_t *)base, base);}#endifvoid RenderObject::arenaDelete(RenderArena *arena){#if KWIQ //KWIQ: removed dynamic cast arenaDelete(arena, static_cast<void *>(this));#else arenaDelete(arena, dynamic_cast<void *>(this));#endif }Position RenderObject::positionForCoordinates(int x, int y){ return Position(element(), caretMinOffset());}bool RenderObject::mouseInside() const{ if (!m_mouseInside && continuation()) return continuation()->mouseInside(); return m_mouseInside; }bool RenderObject::isDragging() const{ return m_isDragging; }void RenderObject::updateDragState(bool dragOn){ bool valueChanged = (dragOn != m_isDragging); m_isDragging = dragOn; if (valueChanged && style()->affectedByDragRules()) element()->setChanged(); for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) curr->updateDragState(dragOn); if (continuation()) continuation()->updateDragState(dragOn);}bool RenderObject::nodeAtPoint(NodeInfo& info, int _x, int _y, int _tx, int _ty, HitTestAction hitTestAction, bool inside){ int tx = _tx + xPos(); int ty = _ty + yPos(); QRect boundsRect(tx, ty, width(), height()); inside |= (style()->visibility() != HIDDEN && boundsRect.contains(_x, _y)) || isBody() || isRoot(); bool inOverflowRect = inside; if (!inOverflowRect) { QRect overflowRect(tx, ty, overflowWidth(false), overflowHeight(false)); inOverflowRect = overflowRect.contains(_x, _y); } // ### table should have its own, more performant method if (hitTestAction != HitTestSelfOnly && ((!isRenderBlock() || !static_cast<RenderBlock*>(this)->isPointInScrollbar(_x, _y, _tx, _ty)) && (inOverflowRect || isInline() || isCanvas() || isTableRow() || isTableSection() || inside || mouseInside() || (childrenInline() && firstChild() && firstChild()->isCompact())))) { if (hitTestAction == HitTestChildrenOnly) inside = false; int stx = _tx + xPos(); int sty = _ty + yPos(); if (hasOverflowClip()) layer()->subtractScrollOffset(stx, sty); for (RenderObject* child = lastChild(); child; child = child->previousSibling()) if (!child->layer() && !child->isFloating() && child->nodeAtPoint(info, _x, _y, stx, sty)) inside = true; } if (inside) { if (!info.innerNode() && !isInline() && continuation()) { // We are in the margins of block elements that are part of a continuation. In // this case we're actually still inside the enclosing inline element that was // split. Go ahead and set our inner node accordingly. info.setInnerNode(continuation()->element()); if (!info.innerNonSharedNode()) info.setInnerNonSharedNode(continuation()->element()); } if (info.innerNode() && info.innerNode()->renderer() && !info.innerNode()->renderer()->isInline() && element() && isInline()) { // Within the same layer, inlines are ALWAYS fully above blocks. Change inner node. info.setInnerNode(element()); // Clear everything else. info.setInnerNonSharedNode(0); info.setURLElement(0); } if (!info.innerNode() && element()) info.setInnerNode(element()); if(!info.innerNonSharedNode() && element()) info.setInnerNonSharedNode(element()); } return inside;}short RenderObject::verticalPositionHint( bool firstLine ) const{ short vpos = m_verticalPosition; if ( m_verticalPosition == PositionUndefined || firstLine ) { vpos = getVerticalPosition( firstLine ); if ( !firstLine ) m_verticalPosition = vpos; } return vpos;}short RenderObject::getVerticalPosition( bool firstLine ) const{ if (!isInline()) return 0; // This method determines the vertical position for inline elements. int vpos = 0; EVerticalAlign va = style()->verticalAlign(); if ( va == TOP ) { vpos = PositionTop; } else if ( va == BOTTOM ) { vpos = PositionBottom; } else if ( va == LENGTH ) { vpos = -style()->verticalAlignLength().width( lineHeight( firstLine ) ); } else { bool checkParent = parent()->isInline() && !parent()->isInlineBlockOrInlineTable(); vpos = checkParent ? parent()->verticalPositionHint( firstLine ) : 0; // don't allow elements nested inside text-top to have a different valignment. if ( va == BASELINE ) return vpos; // if ( vpos == PositionTop )// vpos = 0; const QFont &f = parent()->font( firstLine ); int fontsize = f.pixelSize(); if ( va == SUB ) vpos += fontsize/5 + 1; else if ( va == SUPER ) vpos -= fontsize/3 + 1; else if ( va == TEXT_TOP ) {// qDebug( "got TEXT_TOP vertical pos hint" );// qDebug( "parent:" );// qDebug( "CSSLH: %d, CSS_FS: %d, basepos: %d", fontheight, fontsize, parent()->baselinePosition( firstLine ) );// qDebug( "this:" );// qDebug( "CSSLH: %d, CSS_FS: %d, basepos: %d", lineHeight( firstLine ), style()->font().pixelSize(), baselinePosition( firstLine ) ); vpos += ( baselinePosition( firstLine ) - parent()->baselinePosition( firstLine, !checkParent ) ); } else if ( va == MIDDLE ) {#if APPLE_CHANGES vpos += - (int)(QFontMetrics(f).xHeight()/2) - lineHeight( firstLine )/2 + baselinePosition( firstLine );#else QRect b = QFontMetrics(f).boundingRect('x'); vpos += -b.height()/2 - lineHeight( firstLine )/2 + baselinePosition( firstLine );#endif } else if ( va == TEXT_BOTTOM ) { vpos += QFontMetrics(f).descent(); if ( !isReplaced() ) vpos -= fontMetrics(firstLine).descent(); } else if ( va == BASELINE_MIDDLE ) vpos += - lineHeight( firstLine )/2 + baselinePosition( firstLine ); } return vpos;}short RenderObject::lineHeight( bool firstLine, bool ) const{ RenderStyle* s = style(firstLine); Length lh = s->lineHeight(); // its "unset", choose nice default if (lh.value < 0) return s->fontMetrics().lineSpacing(); if (lh.isPercent()) return lh.minWidth(s->font().pixelSize()); // its fixed return lh.value;}short RenderObject::baselinePosition( bool firstLine, bool isRootLineBox ) const{ const QFontMetrics &fm = fontMetrics( firstLine ); return fm.ascent() + ( lineHeight( firstLine, isRootLineBox ) - fm.height() ) / 2;}void RenderObject::invalidateVerticalPositions(){ m_verticalPosition = PositionUndefined; RenderObject *child = firstChild(); while( child ) { child->invalidateVerticalPositions(); child = child->nextSibling(); }}void RenderObject::recalcMinMaxWidths(){ KHTMLAssert( m_recalcMinMax );#ifdef DEBUG_LAYOUT kdDebug( 6040 ) << renderName() << " recalcMinMaxWidths() this=" << this <<endl;#endif if (m_recalcMinMax) updateFirstLetter(); RenderObject *child = firstChild(); while( child ) { // gcc sucks. if anybody knows a trick to get rid of the // warning without adding an extra (unneeded) initialisation, // go ahead int cmin = 0; int cmax = 0; bool test = false; if ( ( m_minMaxKnown && child->m_recalcMinMax ) || !child->m_minMaxKnown ) { cmin = child->minWidth(); cmax = child->maxWidth(); test = true; } if ( child->m_recalcMinMax ) child->recalcMinMaxWidths(); if ( !child->m_minMaxKnown ) child->calcMinMaxWidth(); if ( m_minMaxKnown && test && (cmin != child->minWidth() || cmax != child->maxWidth()) ) m_minMaxKnown = false; child = child->nextSibling(); } // we need to recalculate, if the contains inline children, as the change could have // happened somewhere deep inside the child tree. Also do this for blocks or tables that // are inline (i.e., inline-block and inline-table). if ((!isInline() || isInlineBlockOrInlineTable()) && childrenInline()) m_minMaxKnown = false; if ( !m_minMaxKnown ) calcMinMaxWidth(); m_recalcMinMax = false;}void RenderObject::scheduleRelayout(){ if (!isCanvas()) return; KHTMLView *view = static_cast<RenderCanvas *>(this)->view(); if (view) view->scheduleRelayout();}void RenderObject::removeLeftoverAnonymousBoxes(){}InlineBox* RenderObject::createInlineBox(bool, bool isRootLineBox, bool){ KHTMLAssert(!isRootLineBox); return new (renderArena()) InlineBox(this);}void RenderObject::dirtyLineBoxes(bool, bool){}InlineBox* RenderObject::inlineBoxWrapper() const{ return 0;}void RenderObject::setInlineBoxWrapper(InlineBox* b){}void RenderObject::deleteLineBoxWrapper(){}RenderStyle* RenderObject::style(bool firstLine) const { RenderStyle *s = m_style; if (firstLine) { const RenderObject* obj = isText() ? parent() : this; if (obj->isBlockFlow()) { RenderBlock* firstLineBlock = obj->firstLineBlock(); if (firstLineBlock) s = firstLineBlock->getPseudoStyle(RenderStyle::FIRST_LINE, style()); } else if (!obj->isAnonymous() && obj->isInlineFlow()) { RenderStyle* parentStyle = obj->parent()->style(true); if (parentStyle != obj->parent()->style()) { // A first-line style is in effect. We need to cache a first-line style // for ourselves. style()->setHasPseudoStyle(RenderStyle::FIRST_LINE_INHERITED); s = obj->getPseudoStyle(RenderStyle::FIRST_LINE_INHERITED, parentStyle); } } } return s;}RenderStyle* RenderObject::getPseudoStyle(RenderStyle::PseudoId pseudo, RenderStyle* parentStyle) const{ if (!style()->hasPseudoStyle(pseudo)) return 0; if (!parentStyle) parentStyle = style(); RenderStyle* result = style()->getPseudoStyle(pseudo); if (result) return result; DOM::NodeImpl* node = element(); if (isText()) node = element()->parentNode(); if (!node) return 0; if (pseudo == RenderStyle::FIRST_LINE_INHERITED) result = document()->styleSelector()->styleForElement(static_cast<DOM::ElementImpl*>(node), parentStyle); else result = document()->styleSelector()->pseudoStyleForElement(pseudo, static_cast<DOM::ElementImpl*>(node), parentStyle); if (result) style()->addPseudoStyle(result); return result;}void RenderObject::getTextDecorationColors(int decorations, QColor& underline, QColor& overline, QColor& linethrough, bool quirksMode){ RenderObject* curr = this; do {
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -