📄 render_layer.cpp
字号:
// Add in the offset of the view. We can obtain this by calling // absolutePosition() on the RenderCanvas. int xOff, yOff; m_object->absolutePosition(xOff, yOff, true); x += xOff; y += yOff; return; } RenderLayer* parentLayer; if (m_object->style()->position() == ABSOLUTE) parentLayer = enclosingPositionedAncestor(); else parentLayer = parent(); if (!parentLayer) return; parentLayer->convertToLayerCoords(ancestorLayer, x, y); x += xPos(); y += yPos();}void RenderLayer::scrollOffset(int& x, int& y){ x += scrollXOffset(); y += scrollYOffset();}void RenderLayer::subtractScrollOffset(int& x, int& y){ x -= scrollXOffset(); y -= scrollYOffset();}void RenderLayer::scrollToOffset(int x, int y, bool updateScrollbars, bool repaint){ if (renderer()->style()->overflow() != OMARQUEE) { if (x < 0) x = 0; if (y < 0) y = 0; // Call the scrollWidth/Height functions so that the dimensions will be computed if they need // to be (for overflow:hidden blocks). // ### merge the scrollWidth()/scrollHeight() methods int maxX = m_scrollWidth - m_object->clientWidth(); int maxY = m_scrollHeight - m_object->clientHeight(); if (x > maxX) x = maxX; if (y > maxY) y = maxY; } // FIXME: Eventually, we will want to perform a blit. For now never // blit, since the check for blitting is going to be very // complicated (since it will involve testing whether our layer // is either occluded by another layer or clipped by an enclosing // layer or contains fixed backgrounds, etc.). m_scrollX = x; m_scrollY = y; // Update the positions of our child layers. RenderLayer* rootLayer = root(); for (RenderLayer* child = firstChild(); child; child = child->nextSibling()) child->updateLayerPositions(rootLayer); // Fire the scroll DOM event. m_object->element()->dispatchHTMLEvent(EventImpl::SCROLL_EVENT, true, false); // Just schedule a full repaint of our object. if (repaint) m_object->repaint(true); if (updateScrollbars) { if (m_hBar) m_hBar->setValue(m_scrollX); if (m_vBar) m_vBar->setValue(m_scrollY); }}void RenderLayer::updateScrollPositionFromScrollbars(){ bool needUpdate = false; int newX = m_scrollX; int newY = m_scrollY; if (m_hBar) { newX = m_hBar->value(); if (newX != m_scrollX) needUpdate = true; } if (m_vBar) { newY = m_vBar->value(); if (newY != m_scrollY) needUpdate = true; } if (needUpdate) scrollToOffset(newX, newY, false);}voidRenderLayer::showScrollbar(Qt::Orientation o, bool show){ QScrollBar *sb = (o == Qt::Horizontal) ? m_hBar : m_vBar; if (show && !sb) { QScrollView* scrollView = m_object->element()->getDocument()->view(); sb = new QScrollBar(o, scrollView, "__khtml"); scrollView->addChild(sb, 0, -50000); sb->setBackgroundMode(QWidget::NoBackground); sb->show(); if (!m_scrollMediator) m_scrollMediator = new RenderScrollMediator(this); m_scrollMediator->connect(sb, SIGNAL(valueChanged(int)), SLOT(slotValueChanged())); } else if (!show && sb) { delete sb; sb = 0; } if (o == Qt::Horizontal) m_hBar = sb; else m_vBar = sb;}int RenderLayer::verticalScrollbarWidth(){ if (!m_vBar) return 0;#ifdef APPLE_CHANGES return m_vBar->width();#else return m_vBar->style().pixelMetric(QStyle::PM_ScrollBarExtent);#endif}int RenderLayer::horizontalScrollbarHeight(){ if (!m_hBar) return 0;#ifdef APPLE_CHANGES return m_hBar->height();#else return m_hBar->style().pixelMetric(QStyle::PM_ScrollBarExtent);#endif}void RenderLayer::moveScrollbarsAside(){ QScrollView* scrollView = m_object->element()->getDocument()->view(); if (m_hBar) scrollView->addChild(m_hBar, 0, -50000); if (m_vBar) scrollView->addChild(m_vBar, 0, -50000);}void RenderLayer::positionScrollbars(const QRect& absBounds){#ifdef APPLE_CHANGES if (m_vBar) { scrollView->addChild(m_vBar, absBounds.x()+absBounds.width()-m_object->borderRight()-m_vBar->width(), absBounds.y()+m_object->borderTop()); m_vBar->resize(m_vBar->width(), absBounds.height() - (m_object->borderTop()+m_object->borderBottom()) - (m_hBar ? m_hBar->height()-1 : 0)); } if (m_hBar) { scrollView->addChild(m_hBar, absBounds.x()+m_object->borderLeft(), absBounds.y()+absBounds.height()-m_object->borderBottom()-m_hBar->height()); m_hBar->resize(absBounds.width() - (m_object->borderLeft()+m_object->borderRight()) - (m_vBar ? m_vBar->width()-1 : 0), m_hBar->height()); }#else int tx = absBounds.x(); int ty = absBounds.y(); int bl = m_object->borderLeft(); int bt = m_object->borderTop(); int w = width() - bl - m_object->borderRight(); int h = height() - bt - m_object->borderBottom(); if (w <= 0 || h <= 0 || (!m_vBar && !m_hBar)) return; QScrollView* scrollView = m_object->element()->getDocument()->view(); tx += bl; ty += bt; QScrollBar *b = m_hBar; if (!m_hBar) b = m_vBar; int sw = b->style().pixelMetric(QStyle::PM_ScrollBarExtent); if (m_vBar) { QRect vBarRect = QRect(tx + w - sw + 1, ty, sw, h - (m_hBar ? sw : 0) + 1); m_vBar->resize(vBarRect.width(), vBarRect.height()); scrollView->addChild(m_vBar, vBarRect.x(), vBarRect.y()); } if (m_hBar) { QRect hBarRect = QRect(tx, ty + h - sw + 1, w - (m_vBar ? sw : 0) + 1, sw); m_hBar->resize(hBarRect.width(), hBarRect.height()); scrollView->addChild(m_hBar, hBarRect.x(), hBarRect.y()); }#endif}#define LINE_STEP 10#define PAGE_KEEP 40void RenderLayer::checkScrollbarsAfterLayout(){ int rightPos = m_object->overflowWidth(); int bottomPos = m_object->overflowHeight(); int clientWidth = m_object->clientWidth(); int clientHeight = m_object->clientHeight(); m_scrollWidth = clientWidth; m_scrollHeight = clientHeight; if (rightPos - m_object->borderLeft() > m_scrollWidth) m_scrollWidth = rightPos - m_object->borderLeft(); if (bottomPos - m_object->borderTop() > m_scrollHeight) m_scrollHeight = bottomPos - m_object->borderTop(); bool needHorizontalBar = rightPos > width(); bool needVerticalBar = bottomPos > height(); bool haveHorizontalBar = m_hBar; bool haveVerticalBar = m_vBar; // overflow:scroll should just enable/disable. if (m_object->style()->overflow() == OSCROLL) { m_hBar->setEnabled(needHorizontalBar); m_vBar->setEnabled(needVerticalBar); } // overflow:auto may need to lay out again if scrollbars got added/removed. bool scrollbarsChanged = (m_object->style()->overflow() == OAUTO) && (haveHorizontalBar != needHorizontalBar || haveVerticalBar != needVerticalBar); if (scrollbarsChanged) { showScrollbar(Qt::Horizontal, needHorizontalBar); showScrollbar(Qt::Vertical, needVerticalBar); m_object->setNeedsLayout(true); if (m_object->isRenderBlock()) static_cast<RenderBlock*>(m_object)->layoutBlock(true); else m_object->layout(); return; } // Set up the range (and page step/line step). if (m_hBar) { int pageStep = (clientWidth-PAGE_KEEP); if (pageStep < 0) pageStep = clientWidth; m_hBar->setSteps(LINE_STEP, pageStep);#ifdef APPLE_CHANGES m_hBar->setKnobProportion(clientWidth, m_scrollWidth);#else m_hBar->setRange(0, needHorizontalBar ? m_scrollWidth-clientWidth : 0);#endif } if (m_vBar) { int pageStep = (clientHeight-PAGE_KEEP); if (pageStep < 0) pageStep = clientHeight; m_vBar->setSteps(LINE_STEP, pageStep);#ifdef APPLE_CHANGES m_vBar->setKnobProportion(clientHeight, m_scrollHeight);#else m_vBar->setRange(0, needVerticalBar ? m_scrollHeight-clientHeight : 0);#endif }}void RenderLayer::paintScrollbars(RenderObject::PaintInfo& pI){#ifdef APPLE_CHANGES if (m_hBar) m_hBar->paint(p, damageRect); if (m_vBar) m_vBar->paint(p, damageRect);#else if (!m_object->element()) return; QScrollView* scrollView = m_object->element()->getDocument()->view(); if (m_hBar) { int x = m_hBar->x(); int y = m_hBar->y(); scrollView->viewportToContents(x, y, x, y); RenderWidget::paintWidget(pI, m_hBar, x, y); } if (m_vBar) { int x = m_vBar->x(); int y = m_vBar->y(); scrollView->viewportToContents(x, y, x, y); RenderWidget::paintWidget(pI, m_vBar, x, y); }#endif}void RenderLayer::paint(QPainter *p, const QRect& damageRect, bool selectionOnly){ paintLayer(this, p, damageRect, selectionOnly);}static void setClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect){ if (paintDirtyRect == clipRect) return; p->save();#ifdef APPLE_CHANGES p->addClip(clipRect);#else QRect clippedRect = p->xForm(clipRect); QRegion creg(clippedRect); QRegion old = p->clipRegion(); if (!old.isNull()) creg = old.intersect(creg); p->setClipRegion(creg);#endif}static void restoreClip(QPainter* p, const QRect& paintDirtyRect, const QRect& clipRect){ if (paintDirtyRect == clipRect) return; p->restore();}void RenderLayer::paintLayer(RenderLayer* rootLayer, QPainter *p, const QRect& paintDirtyRect, bool selectionOnly){ // Calculate the clip rects we should use. QRect layerBounds, damageRect, clipRectToApply; calculateRects(rootLayer, paintDirtyRect, layerBounds, damageRect, clipRectToApply); int x = layerBounds.x(); int y = layerBounds.y(); // Ensure our z-order lists are up-to-date. updateZOrderLists();#ifdef APPLE_CHANGES // Set our transparency if we need to. if (isTransparent()) p->beginTransparencyLayer(renderer()->style()->opacity());#endif // We want to paint our layer, but only if we intersect the damage rect. bool shouldPaint = intersectsDamageRect(layerBounds, damageRect); if (shouldPaint && !selectionOnly) { // Paint our background first, before painting any child layers. if (!damageRect.isEmpty()) { // Establish the clip used to paint our background. setClip(p, paintDirtyRect, damageRect); // Paint the background. RenderObject::PaintInfo paintInfo(p, damageRect, PaintActionElementBackground); renderer()->paint(paintInfo, x - renderer()->xPos(), y - renderer()->yPos()); // Position our scrollbars. positionScrollbars(layerBounds); // Our scrollbar widgets paint exactly when we tell them to, so that they work properly with // z-index. We paint after we painted the background/border, so that the scrollbars will // sit above the background/border. paintScrollbars(paintInfo); // Restore the clip. restoreClip(p, paintDirtyRect, damageRect); } } // Now walk the sorted list of children with negative z-indices. if (m_negZOrderList) { uint count = m_negZOrderList->count(); for (uint i = 0; i < count; i++) { RenderLayer* child = m_negZOrderList->at(i); child->paintLayer(rootLayer, p, paintDirtyRect, selectionOnly); } } // Now establish the appropriate clip and paint our child RenderObjects. if (shouldPaint && !clipRectToApply.isEmpty()) { // Set up the clip used when painting our children. setClip(p, paintDirtyRect, clipRectToApply); RenderObject::PaintInfo paintInfo(p, clipRectToApply, PaintActionSelection); if (selectionOnly) renderer()->paint(paintInfo, x - renderer()->xPos(), y - renderer()->yPos()); else { paintInfo.phase = PaintActionChildBackgrounds; renderer()->paint(paintInfo, x - renderer()->xPos(), y - renderer()->yPos()); paintInfo.phase = PaintActionFloat; renderer()->paint(paintInfo, x - renderer()->xPos(), y - renderer()->yPos()); paintInfo.phase = PaintActionForeground; renderer()->paint(paintInfo, x - renderer()->xPos(), y - renderer()->yPos()); paintInfo.phase = PaintActionOutline; renderer()->paint(paintInfo, x - renderer()->xPos(), y - renderer()->yPos()); RenderCanvas *rc = static_cast<RenderCanvas*>(renderer()->document()->renderer()); if (rc->selectionStart() && rc->selectionEnd()) { paintInfo.phase = PaintActionSelection; renderer()->paint(paintInfo, x - renderer()->xPos(), y - renderer()->yPos()); } }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -