📄 qpainter.cpp
字号:
/*! Restores the current painter state (pops a saved state off the stack). \sa save()*/void QPainter::restore(){#ifdef QT_DEBUG_DRAW if (qt_show_painter_debug_output) printf("QPainter::restore()\n");#endif Q_D(QPainter); if (d->states.size()<=1) { qWarning("QPainter::restore: Unbalanced save/restore"); return; } else if (!isActive()) { qWarning("QPainter::restore: Painter not active"); return; } QPainterState *tmp = d->state; d->states.pop_back(); d->state = d->states.back(); d->txinv = false; // trigger clip update if the clip path/region has changed since // last save if (!d->state->clipInfo.isEmpty() && (tmp->changeFlags & (QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyClipPath))) { // reuse the tmp state to avoid any extra allocs... tmp->dirtyFlags = QPaintEngine::DirtyClipPath; tmp->clipOperation = Qt::NoClip; tmp->clipPath = QPainterPath(); d->engine->updateState(*tmp); // replay the list of clip states, for (int i=0; i<d->state->clipInfo.size(); ++i) { const QPainterClipInfo &info = d->state->clipInfo.at(i); tmp->matrix.setMatrix(info.matrix.m11(), info.matrix.m12(), info.matrix.m13(), info.matrix.m21(), info.matrix.m22(), info.matrix.m23(), info.matrix.dx() - d->redirection_offset.x(), info.matrix.dy() - d->redirection_offset.y(), info.matrix.m33()); tmp->clipOperation = info.operation; if (info.clipType == QPainterClipInfo::RegionClip) { tmp->dirtyFlags = QPaintEngine::DirtyClipRegion | QPaintEngine::DirtyTransform; tmp->clipRegion = info.region; } else { // clipType == QPainterClipInfo::PathClip tmp->dirtyFlags = QPaintEngine::DirtyClipPath | QPaintEngine::DirtyTransform; tmp->clipPath = info.path; } d->engine->updateState(*tmp); } //Since we've updated the clip region anyway, pretend that the clip path hasn't changed: d->state->dirtyFlags &= ~(QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipRegion); tmp->changeFlags &= ~(QPaintEngine::DirtyClipPath | QPaintEngine::DirtyClipRegion); tmp->changeFlags |= QPaintEngine::DirtyTransform; } d->updateState(d->state); delete tmp;}/*! \fn bool QPainter::begin(QPaintDevice *device) Begins painting the paint \a device and returns true if successful; otherwise returns false. Notice that all painter settings (setPen(), setBrush() etc.) are reset to default values when begin() is called. The errors that can occur are serious problems, such as these: \code painter->begin(0); // impossible - paint device cannot be 0 QPixmap image(0, 0); painter->begin(&image); // impossible - image.isNull() == true; painter->begin(myWidget); painter2->begin(myWidget); // impossible - only one painter at a time \endcode Note that most of the time, you can use one of the constructors instead of begin(), and that end() is automatically done at destruction. \warning A paint device can only be painted by one painter at a time. \sa end(), QPainter()*/bool QPainter::begin(QPaintDevice *pd){ Q_ASSERT(pd); Q_D(QPainter); if (d->engine) { qWarning("QPainter::begin: Painter already active"); return false; } // Ensure fresh painter state if (d->emptyState && !d->state->dirtyFlags) d->emptyState = false; else d->state->init(d->state->painter); d->original_device = pd; QPaintDevice *rpd = redirected(pd, &d->redirection_offset); if (rpd) { pd = rpd; }#ifdef QT_DEBUG_DRAW if (qt_show_painter_debug_output) printf("QPainter::begin(), device=%p, type=%d\n", pd, pd->devType());#endif d->state->bgOrigin = QPointF(); d->device = pd; if (pd->devType() == QInternal::Pixmap) static_cast<QPixmap *>(pd)->detach(); else if (pd->devType() == QInternal::Image) static_cast<QImage *>(pd)->detach(); d->engine = pd->paintEngine(); if (!d->engine) { qWarning("QPainter::begin: Paint device returned engine == 0, type: %d", pd->devType()); return true; } switch (pd->devType()) { case QInternal::Widget: { const QWidget *widget = static_cast<const QWidget *>(pd); Q_ASSERT(widget); if(!d->engine->hasFeature(QPaintEngine::PaintOutsidePaintEvent) && !widget->testAttribute(Qt::WA_PaintOutsidePaintEvent) && !widget->testAttribute(Qt::WA_WState_InPaintEvent)) { qWarning("QPainter::begin: Widget painting can only begin as a " "result of a paintEvent"); return false; } break; } case QInternal::Pixmap: { const QPixmap *pm = static_cast<const QPixmap *>(pd); Q_ASSERT(pm); if (pm->isNull()) { qWarning("QPainter::begin: Cannot paint on a null pixmap"); return false; } if (pm->depth() == 1) { d->state->pen = QPen(Qt::color1); d->state->brush = QBrush(Qt::color0); } break; } case QInternal::Image: { const QImage *img = static_cast<const QImage *>(pd); Q_ASSERT(img); if (img->isNull()) { qWarning("QPainter::begin: Cannot paint on a null image"); return false; } if (img->depth() == 1) { d->state->pen = QPen(Qt::color1); d->state->brush = QBrush(Qt::color0); } break; } default: break; } if (d->state->ww == 0) // For compat with 3.x painter defaults d->state->ww = d->state->wh = d->state->vw = d->state->vh = 1024; // Slip a painter state into the engine before we do any other operations d->engine->state = d->state; d->engine->setPaintDevice(pd); bool begun = d->engine->begin(pd); if (!begun) { qWarning("QPainter::begin(): Returned false"); end(); return false; } else { d->engine->setActive(begun); } // Copy painter properties from original paint device, // required for QPixmap::grabWidget() if (d->original_device->devType() == QInternal::Widget) { QWidget *widget = static_cast<QWidget *>(d->original_device); initFrom(widget); } else { d->state->layoutDirection = QApplication::layoutDirection(); // make sure we have a font compatible with the paintdevice d->state->deviceFont = d->state->font = QFont(d->state->deviceFont, d->device); } QRect systemRect = d->engine->systemRect(); if (!systemRect.isEmpty()) { d->state->ww = d->state->vw = systemRect.width(); d->state->wh = d->state->vh = systemRect.height(); } else { d->state->ww = d->state->vw = pd->metric(QPaintDevice::PdmWidth); d->state->wh = d->state->vh = pd->metric(QPaintDevice::PdmHeight); } d->redirection_offset += d->engine->coordinateOffset(); Q_ASSERT(d->engine->isActive()); if (!d->redirection_offset.isNull()) d->updateMatrix(); Q_ASSERT(d->engine->isActive()); d->state->renderHints = QPainter::TextAntialiasing; ++d->device->painters; d->state->emulationSpecifier = 0; return true;}/*! Ends painting. Any resources used while painting are released. You don't normally need to call this since it is called by the destructor. Returns true if the painter is no longer active; otherwise returns false. \sa begin(), isActive()*/bool QPainter::end(){#ifdef QT_DEBUG_DRAW if (qt_show_painter_debug_output) printf("QPainter::end()\n");#endif if (!isActive()) { qWarning("QPainter::end: Painter not active, aborted"); return false; } Q_D(QPainter); if (d->states.size()>1) { qWarning("QPainter::end: Painter ended with %d saved states", d->states.size()); } bool ended = true; d->fillrect_func = 0; if (d->engine->isActive()) { ended = d->engine->end(); d->updateState(0); --d->device->painters; if (d->device->painters == 0) { d->engine->setPaintDevice(0); d->engine->setActive(false); } } if (d->engine->autoDestruct()) { delete d->engine; } d->engine = 0; d->device = 0; return ended;}/*! Returns the paint engine that the painter is currently operating on if the painter is active; otherwise 0. \sa isActive()*/QPaintEngine *QPainter::paintEngine() const{ Q_D(const QPainter); return d->engine;}/*! Returns the font metrics for the painter if the painter is active. Otherwise, the return value is undefined. \sa font(), isActive(), {QPainter#Settings}{Settings}*/QFontMetrics QPainter::fontMetrics() const{ Q_D(const QPainter); return QFontMetrics(d->state->font);}/*! Returns the font info for the painter if the painter is active. Otherwise, the return value is undefined. \sa font(), isActive(), {QPainter#Settings}{Settings}*/QFontInfo QPainter::fontInfo() const{ Q_D(const QPainter); return QFontInfo(d->state->font);}/*! \since 4.2 Returns the opacity of the painter. The default value is 1.*/qreal QPainter::opacity() const{ Q_D(const QPainter); return d->state->opacity;}/*! \since 4.2 Sets the opacity of the painter to \a opacity. The value should be in the range 0.0 to 1.0, where 0.0 is fully transparent and 1.0 is fully opaque. Opacity set on the painter will apply to all drawing operations individually.*/void QPainter::setOpacity(qreal opacity){ Q_D(QPainter); d->state->opacity = qMin(qreal(1), qMax(qreal(0), opacity)); d->state->dirtyFlags |= QPaintEngine::DirtyOpacity;}/*! Returns the currently set brush origin. \sa setBrushOrigin(), {QPainter#Settings}{Settings}*/QPoint QPainter::brushOrigin() const{ Q_D(const QPainter); return QPointF(d->state->bgOrigin).toPoint();}/*! \fn void QPainter::setBrushOrigin(const QPointF &position) Sets the brush origin to \a position. The brush origin specifies the (0, 0) coordinate of the painter's brush. This setting only applies to pattern brushes and pixmap brushes.
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -