📄 renderobject.cpp
字号:
RenderObject* o; if (!(o = nextSibling())) { o = parent(); while (o && !o->nextSibling()) { if (o == stayWithin) return 0; o = o->parent(); } if (o) o = o->nextSibling(); } return o;}RenderObject* RenderObject::previousInPreOrder() const{ if (RenderObject* o = previousSibling()) { while (o->lastChild()) o = o->lastChild(); return o; } return parent();}RenderObject* RenderObject::childAt(unsigned index) const{ RenderObject* child = firstChild(); for (unsigned i = 0; child && i < index; i++) child = child->nextSibling(); return child;}RenderObject* RenderObject::firstLeafChild() const{ RenderObject* r = firstChild(); while (r) { RenderObject* n = 0; n = r->firstChild(); if (!n) break; r = n; } return r;}RenderObject* RenderObject::lastLeafChild() const{ RenderObject* r = lastChild(); while (r) { RenderObject* n = 0; n = r->lastChild(); if (!n) break; r = n; } return r;}static void addLayers(RenderObject* obj, RenderLayer* parentLayer, RenderObject*& newObject, RenderLayer*& beforeChild){ if (obj->hasLayer()) { if (!beforeChild && newObject) { // We need to figure out the layer that follows newObject. We only do // this the first time we find a child layer, and then we update the // pointer values for newObject and beforeChild used by everyone else. beforeChild = newObject->parent()->findNextLayer(parentLayer, newObject); newObject = 0; } parentLayer->addChild(toRenderBoxModelObject(obj)->layer(), beforeChild); return; } for (RenderObject* curr = obj->firstChild(); curr; curr = curr->nextSibling()) addLayers(curr, parentLayer, newObject, beforeChild);}void RenderObject::addLayers(RenderLayer* parentLayer, RenderObject* newObject){ if (!parentLayer) return; RenderObject* object = newObject; RenderLayer* beforeChild = 0; WebCore::addLayers(this, parentLayer, object, beforeChild);}void RenderObject::removeLayers(RenderLayer* parentLayer){ if (!parentLayer) return; if (hasLayer()) { parentLayer->removeChild(toRenderBoxModelObject(this)->layer()); return; } for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) curr->removeLayers(parentLayer);}void RenderObject::moveLayers(RenderLayer* oldParent, RenderLayer* newParent){ if (!newParent) return; if (hasLayer()) { RenderLayer* layer = toRenderBoxModelObject(this)->layer(); if (oldParent) oldParent->removeChild(layer); newParent->addChild(layer); return; } for (RenderObject* curr = firstChild(); curr; curr = curr->nextSibling()) curr->moveLayers(oldParent, newParent);}RenderLayer* RenderObject::findNextLayer(RenderLayer* parentLayer, RenderObject* startPoint, bool checkParent){ // Error check the parent layer passed in. If it's null, we can't find anything. if (!parentLayer) return 0; // Step 1: If our layer is a child of the desired parent, then return our layer. RenderLayer* ourLayer = hasLayer() ? toRenderBoxModelObject(this)->layer() : 0; if (ourLayer && ourLayer->parent() == parentLayer) return ourLayer; // Step 2: If we don't have a layer, or our layer is the desired parent, then descend // into our siblings trying to find the next layer whose parent is the desired parent. if (!ourLayer || ourLayer == parentLayer) { for (RenderObject* curr = startPoint ? startPoint->nextSibling() : firstChild(); curr; curr = curr->nextSibling()) { RenderLayer* nextLayer = curr->findNextLayer(parentLayer, 0, false); if (nextLayer) return nextLayer; } } // Step 3: If our layer is the desired parent layer, then we're finished. We didn't // find anything. if (parentLayer == ourLayer) return 0; // Step 4: If |checkParent| is set, climb up to our parent and check its siblings that // follow us to see if we can locate a layer. if (checkParent && parent()) return parent()->findNextLayer(parentLayer, this, true); return 0;}RenderLayer* RenderObject::enclosingLayer() const{ const RenderObject* curr = this; while (curr) { RenderLayer* layer = curr->hasLayer() ? toRenderBoxModelObject(curr)->layer() : 0; if (layer) return layer; curr = curr->parent(); } return 0;}RenderBox* RenderObject::enclosingBox() const{ RenderObject* curr = const_cast<RenderObject*>(this); while (curr) { if (curr->isBox()) return toRenderBox(curr); curr = curr->parent(); } ASSERT_NOT_REACHED(); return 0;}RenderBlock* RenderObject::firstLineBlock() const{ return 0;}void RenderObject::setPrefWidthsDirty(bool b, bool markParents){ bool alreadyDirty = m_prefWidthsDirty; m_prefWidthsDirty = b; if (b && !alreadyDirty && markParents && (isText() || (style()->position() != FixedPosition && style()->position() != AbsolutePosition))) invalidateContainerPrefWidths();}void RenderObject::invalidateContainerPrefWidths(){ // In order to avoid pathological behavior when inlines are deeply nested, we do include them // in the chain that we mark dirty (even though they're kind of irrelevant). RenderObject* o = isTableCell() ? containingBlock() : container(); while (o && !o->m_prefWidthsDirty) { o->m_prefWidthsDirty = true; if (o->style()->position() == FixedPosition || o->style()->position() == AbsolutePosition) // A positioned object has no effect on the min/max width of its containing block ever. // We can optimize this case and not go up any further. break; o = o->isTableCell() ? o->containingBlock() : o->container(); }}void RenderObject::setLayerNeedsFullRepaint(){ ASSERT(hasLayer()); toRenderBoxModelObject(this)->layer()->setNeedsFullRepaint(true);}RenderBlock* RenderObject::containingBlock() const{ if (isTableCell()) { const RenderTableCell* cell = static_cast<const RenderTableCell*>(this); if (parent() && cell->section()) return cell->table(); return 0; } if (isRenderView()) return const_cast<RenderView*>(toRenderView(this)); RenderObject* o = parent(); if (!isText() && m_style->position() == FixedPosition) { while (o && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) o = o->parent(); } else if (!isText() && m_style->position() == AbsolutePosition) { while (o && (o->style()->position() == StaticPosition || (o->isInline() && !o->isReplaced())) && !o->isRenderView() && !(o->hasTransform() && o->isRenderBlock())) { // For relpositioned inlines, we return the nearest enclosing block. We don't try // to return the inline itself. This allows us to avoid having a positioned objects // list in all RenderInlines and lets us return a strongly-typed RenderBlock* result // from this method. The container() method can actually be used to obtain the // inline directly. if (o->style()->position() == RelativePosition && o->isInline() && !o->isReplaced()) return o->containingBlock(); o = o->parent(); } } else { while (o && ((o->isInline() && !o->isReplaced()) || o->isTableRow() || o->isTableSection() || o->isTableCol() || o->isFrameSet() || o->isMedia()#if ENABLE(SVG) || o->isSVGContainer() || o->isSVGRoot()#endif )) o = o->parent(); } if (!o || !o->isRenderBlock()) return 0; // Probably doesn't happen any more, but leave just in case. -dwh return toRenderBlock(o);}static bool mustRepaintFillLayers(const RenderObject* renderer, const FillLayer* layer){ // Nobody will use multiple layers without wanting fancy positioning. if (layer->next()) return true; // Make sure we have a valid image. StyleImage* img = layer->image(); bool shouldPaintBackgroundImage = img && img->canRender(renderer->style()->effectiveZoom()); // These are always percents or auto. if (shouldPaintBackgroundImage && (!layer->xPosition().isZero() || !layer->yPosition().isZero() || layer->size().width().isPercent() || layer->size().height().isPercent())) // The image will shift unpredictably if the size changes. return true; return false;}bool RenderObject::mustRepaintBackgroundOrBorder() const{ if (hasMask() && mustRepaintFillLayers(this, style()->maskLayers())) return true; // If we don't have a background/border/mask, then nothing to do. if (!hasBoxDecorations()) return false; if (mustRepaintFillLayers(this, style()->backgroundLayers())) return true; // Our fill layers are ok. Let's check border. if (style()->hasBorder()) { // Border images are not ok. StyleImage* borderImage = style()->borderImage().image(); bool shouldPaintBorderImage = borderImage && borderImage->canRender(style()->effectiveZoom()); // If the image hasn't loaded, we're still using the normal border style. if (shouldPaintBorderImage && borderImage->isLoaded()) return true; } return false;}void RenderObject::drawLineForBoxSide(GraphicsContext* graphicsContext, int x1, int y1, int x2, int y2, BoxSide s, Color c, const Color& textcolor, EBorderStyle style, int adjbw1, int adjbw2){ int width = (s == BSTop || s == BSBottom ? y2 - y1 : x2 - x1); if (style == DOUBLE && width < 3) style = SOLID; if (!c.isValid()) { if (style == INSET || style == OUTSET || style == RIDGE || style == GROOVE) c.setRGB(238, 238, 238); else c = textcolor; } switch (style) { case BNONE: case BHIDDEN: return; case DOTTED: case DASHED: graphicsContext->setStrokeColor(c); graphicsContext->setStrokeThickness(width); graphicsContext->setStrokeStyle(style == DASHED ? DashedStroke : DottedStroke); if (width > 0) switch (s) { case BSBottom: case BSTop: graphicsContext->drawLine(IntPoint(x1, (y1 + y2) / 2), IntPoint(x2, (y1 + y2) / 2)); break; case BSRight: case BSLeft: graphicsContext->drawLine(IntPoint((x1 + x2) / 2, y1), IntPoint((x1 + x2) / 2, y2)); break; } break; case DOUBLE: { int third = (width + 1) / 3; if (adjbw1 == 0 && adjbw2 == 0) { graphicsContext->setStrokeStyle(NoStroke); graphicsContext->setFillColor(c); switch (s) { case BSTop: case BSBottom: graphicsContext->drawRect(IntRect(x1, y1, x2 - x1, third)); graphicsContext->drawRect(IntRect(x1, y2 - third, x2 - x1, third));
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -