📄 qbackingstore.cpp
字号:
move whole rect by dx,dy rect must be valid doesn't generate any updates*/void QWidgetBackingStore::bltRect(const QRect &rect, int dx, int dy, QWidget *widget){#if defined(Q_WS_X11) || defined(Q_WS_QWS) if (buffer.isNull()) return;#endif QPoint pos(widget->mapTo(tlw, rect.topLeft()));#if defined(Q_WS_WIN) QRasterPaintEngine *engine = (QRasterPaintEngine*) buffer.paintEngine(); HDC engine_dc = engine->getDC(); if (!engine_dc) return; BitBlt(engine_dc, pos.x()+dx, pos.y()+dy, rect.width(), rect.height(), engine_dc, pos.x(), pos.y(), SRCCOPY); engine->releaseDC(engine_dc);#elif defined(Q_WS_X11)// qDebug("XCreateGC"); GC gc = XCreateGC(tlw->d_func()->xinfo.display(), buffer.handle(), 0, 0);// qDebug() << "XCopyArea" << pos << rect << "dx" << dy << "dy" << dy; XCopyArea(X11->display, buffer.handle(), buffer.handle(), gc, pos.x(), pos.y(), rect.width(), rect.height(), pos.x()+dx, pos.y()+dy);// qDebug("XFreeGC"); XFreeGC(tlw->d_func()->xinfo.display(), gc);// qDebug("done");#elif defined(Q_WS_QWS) pos += topLevelOffset(); QRect bsrect(pos, rect.size()); QRect boundingRect = bsrect.unite(bsrect.translated(dx,dy)); if (!QRect(QPoint(0,0), buffer.size()).contains(boundingRect)) { return; } buffer.blit(bsrect, pos + QPoint(dx,dy));#endif}//parent's coordinates; move whole rect; update parent and widget//assume the screen blt has already been done, so we don't need to refresh that partvoid QWidgetPrivate::moveRect(const QRect &rect, int dx, int dy){ Q_Q(QWidget); if (!q->isVisible()) return; QWidget *tlw = q->window(); QTLWExtra* x = tlw->d_func()->topData(); static int accelEnv = -1; if (accelEnv == -1) { accelEnv = qgetenv("QT_NO_FAST_MOVE").toInt() == 0; } QWidget *pw = q->parentWidget(); QWidgetPrivate *pd = pw->d_func(); QRect clipR = pd->clipRect(); QRect newRect = rect.translated(dx,dy); QRect destRect = rect.intersect(clipR); if (destRect.isValid()) destRect = destRect.translated(dx,dy).intersect(clipR); QRect sourceRect = destRect.translated(-dx, -dy); bool accelerateMove = accelEnv && isOpaque() && !isOverlapped(sourceRect) && !isOverlapped(destRect); if (!accelerateMove) { QRegion parentR(rect & clipR); if (q->mask().isEmpty()) { parentR -= newRect; } else { // invalidateBuffer() excludes anything outside the mask parentR += newRect & clipR; } pd->invalidateBuffer(parentR); invalidateBuffer((newRect & clipR).translated(-data.crect.topLeft())); } else { QWidgetBackingStore *wbs = x->backingStore; if (sourceRect.isValid()) wbs->bltRect(sourceRect, dx, dy, pw); QRegion childExpose = newRect & clipR; childExpose -= destRect; QPoint toplevelOffset = pw->mapTo(tlw, QPoint()); QRect newDirty = (wbs->dirty & sourceRect.translated(toplevelOffset)).boundingRect().translated(QPoint(dx,dy) - toplevelOffset); childExpose += newDirty; childExpose.translate(-data.crect.topLeft()); invalidateBuffer(childExpose); QRegion parentExpose = rect & clipR; parentExpose -= newRect; if (!q->mask().isEmpty()) { parentExpose += QRegion(newRect) - q->mask().translated(data.crect.topLeft()); } pd->invalidateBuffer(parentExpose);#ifdef Q_WS_QWS //QWS does not have native child widgets: copy everything to screen, just like scrollRect() pd->dirtyWidget_sys(QRegion(sourceRect)+destRect);#endif }}//widget's coordinates; scroll within rect; only update widgetvoid QWidgetPrivate::scrollRect(const QRect &rect, int dx, int dy){ Q_Q(QWidget); QWidget *tlw = q->window(); QTLWExtra* x = tlw->d_func()->topData(); static int accelEnv = -1; if (accelEnv == -1) { accelEnv = qgetenv("QT_NO_FAST_SCROLL").toInt() == 0; } bool accelerateScroll = accelEnv && isOpaque() && !isOverlapped(data.crect); if (!accelerateScroll) { invalidateBuffer(rect); } else { QRect scrollRect = rect & clipRect(); QRect destRect = scrollRect.isValid() ? scrollRect.translated(dx,dy).intersect(scrollRect) : QRect(); QRect sourceRect = destRect.translated(-dx, -dy); QWidgetBackingStore *wbs = x->backingStore; QPoint toplevelOffset = q->mapTo(tlw, QPoint()); if (sourceRect.isValid()) wbs->bltRect(sourceRect, dx, dy, q); QRegion childExpose = scrollRect; childExpose -= destRect;// childExpose += (wbs->dirty & sourceRect.translated(toplevelOffset)).boundingRect().translated(QPoint(dx,dy) - toplevelOffset); QRect newDirty = (wbs->dirty & sourceRect.translated(toplevelOffset)).boundingRect().translated(QPoint(dx,dy) - toplevelOffset);// qDebug() << "scrollRect" << q << rect << dx << dy << "dirty" << wbs->dirty << "newDirty" << newDirty; childExpose += newDirty; invalidateBuffer(childExpose); // Instead of using native scroll-on-screen, we copy from // backingstore, giving only one screen update for each // scroll, and a solid appearance dirtyWidget_sys(rect); }}void QWidgetBackingStore::dirtyRegion(const QRegion &rgn, QWidget *widget){ QRegion wrgn(rgn); Q_ASSERT(widget->window() == tlw); if(!widget->isVisible() || !widget->updatesEnabled()) return; wrgn &= widget->d_func()->clipRect(); if (!widget->mask().isEmpty()) wrgn &= widget->mask();#ifndef Q_WS_QWS widget->d_func()->dirtyWidget_sys(wrgn);#endif if(!QWidgetBackingStore::paintOnScreen(widget)) { wrgn.translate(widget->mapTo(tlw, QPoint(0, 0))); dirty += wrgn;#ifdef Q_WS_QWS tlw->d_func()->dirtyWidget_sys(wrgn); //optimization: don't translate twice#endif }}void QWidgetBackingStore::copyToScreen(QWidget *widget, const QRegion &rgn){ QWidget *tlw = widget->window(); QTLWExtra *topextra = tlw->d_func()->extra->topextra; QPoint offset = widget->mapTo(tlw, QPoint()); topextra->backingStore->copyToScreen(rgn, widget, offset, false);}/** * Copies the contents of the backingstore into the screen area of \a widget. * \a offset is the position of \a widget relative to the top level widget. * \a rgn is the region to be updated in \a widget coordinates. * \a recursive indicates that the widget should recursivly call copyToScreen * for all child widgets. */void QWidgetBackingStore::copyToScreen(const QRegion &rgn, QWidget *widget, const QPoint &offset, bool recursive){ if (rgn.isEmpty()) return;#ifdef Q_WS_QWS Q_UNUSED(offset); Q_UNUSED(recursive); QWidget *win = widget->window(); QBrush bgBrush = win->palette().brush(win->backgroundRole()); bool opaque = bgBrush.style() == Qt::NoBrush || bgBrush.isOpaque(); QRegion globalrgn = rgn; globalrgn.translate(win->geometry().topLeft()); win->qwsDisplay()->repaintRegion(win->data->winid, opaque, globalrgn); widget->d_func()->cleanWidget_sys(rgn); qt_flushUpdate(0, globalrgn);#else if (!QWidgetBackingStore::paintOnScreen(widget)) { widget->d_func()->cleanWidget_sys(rgn); qt_flushUpdate(widget, rgn); QPoint wOffset = widget->data->wrect.topLeft();#if defined(Q_WS_WIN)#if 1 QRasterPaintEngine *engine = (QRasterPaintEngine*) buffer.paintEngine(); HDC engine_dc = engine->getDC(); HDC widget_dc = (HDC) widget->d_func()->hd; bool tmp_widget_dc = false; if (!widget_dc) { widget_dc = GetDC(widget->winId()); tmp_widget_dc = true; } QRect br = rgn.boundingRect(); QRect wbr = br.translated(-wOffset); BitBlt(widget_dc, wbr.x(), wbr.y(), wbr.width(), wbr.height(), engine_dc, br.x() + offset.x(), br.y() + offset.y(), SRCCOPY); if (tmp_widget_dc) ReleaseDC(widget->winId(), widget_dc);#else recursive = false; // Fetch source device context. QRasterPaintEngine *engine = (QRasterPaintEngine*) buffer.paintEngine(); HDC engine_dc = engine->getDC(); // Fetch target device context. QWidget *window = widget->window(); HDC window_dc = GetWindowDC(widget->window()->winId()); int frame_x = window->geometry().x() - window->x(); int frame_y = window->geometry().y() - window->y(); // The rect in the backingstore to update. QRect br = rgn.boundingRect().translated(offset); // Copy backingstore to screen, offsetting for the widget's frame. BitBlt(window_dc, br.x() + frame_x, br.y() + frame_y, br.width(), br.height(), engine_dc, br.x(), br.y(), SRCCOPY); // Clean up ReleaseDC(widget->window()->winId(), window_dc); engine->releaseDC(engine_dc);#endif#elif defined(Q_WS_X11) extern void *qt_getClipRects(const QRegion &r, int &num); // in qpaintengine_x11.cpp GC gc = XCreateGC(X11->display, buffer.handle(), 0, 0); QRegion wrgn(rgn); QRect br = rgn.boundingRect(); if (!wOffset.isNull()) wrgn.translate(-wOffset); QRect wbr = wrgn.boundingRect(); if (br.right() + offset.x() >= buffer.size().width() || br.bottom() + offset.y() >= buffer.size().height()) {// QRegion dirty = rgn - QRect(-offset, buffer.size());// qDebug() << dirty; widget->d_func()->dirtyWidget_sys(rgn - QRect(-offset, buffer.size())); } int num; XRectangle *rects = (XRectangle *)qt_getClipRects(wrgn, num);// qDebug() << "XSetClipRectangles";// for (int i = 0; i < num; ++i)// qDebug() << " " << i << rects[i].x << rects[i].x << rects[i].y << rects[i].width << rects[i].height; XSetClipRectangles(X11->display, gc, 0, 0, rects, num, YXBanded ); XSetGraphicsExposures(X11->display, gc, False);// XFillRectangle(X11->display, widget->handle(), gc, 0, 0, widget->width(), widget->height()); XCopyArea(X11->display, buffer.handle(), widget->handle(), gc, br.x() + offset.x(), br.y() + offset.y(), br.width(), br.height(), wbr.x(), wbr.y()); XFreeGC(X11->display, gc);#endif } if(recursive) { const QObjectList children = widget->children(); for(int i = 0; i < children.size(); ++i) { if(QWidget *child = qobject_cast<QWidget*>(children.at(i))) { if(!child->isWindow() && child->isVisible()) { if (qRectIntersects(rgn.boundingRect().translated(-child->pos()), child->rect())) { QRegion childRegion(rgn); childRegion.translate(-child->pos()); childRegion &= child->d_func()->clipRect(); if(!childRegion.isEmpty()) copyToScreen(childRegion, child, offset+child->pos(), recursive); } } } } }#endif}void QWidgetBackingStore::cleanRegion(const QRegion &rgn, QWidget *widget, bool recursiveCopyToScreen){ if (!widget->isVisible() || !widget->updatesEnabled() || !tlw->testAttribute(Qt::WA_Mapped) || rgn.isEmpty()) return;#if defined(Q_WS_QWS) && !defined(QT_NO_QWS_MANAGER) QTLWExtra *topextra = tlw->d_func()->extra->topextra;#endif if(!QWidgetBackingStore::paintOnScreen(widget)) { QRegion toClean;#ifdef Q_WS_QWS bool created = buffer.createIfNecessary(tlw); if (created) {#ifndef QT_NO_QWS_MANAGER if (topextra->qwsManager) topextra->qwsManager->d_func()->dirtyRegion(QDecoration::All,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -