📄 qpaintengine_raster.cpp
字号:
&& qFuzzyCompare(matrix.m22(), qreal(-1)) ) || (qFuzzyCompare(matrix.m11(), qreal(0.0)) && qFuzzyCompare(matrix.m12(), qreal(-1)) && qFuzzyCompare(matrix.m21(), qreal(1)) && qFuzzyCompare(matrix.m22(), qreal(0)) ) ; }#endif}/*! \reimp*/void QRasterPaintEngine::updateState(const QPaintEngineState &state){ Q_D(QRasterPaintEngine); QPaintEngine::DirtyFlags flags = state.state(); bool update_fast_pen = false; bool update_fast_text = false; if (flags & DirtyTransform) { update_fast_pen = true; updateMatrix(state.transform()); // the cliprect set on the dash stroker needs to be updated when the // transform changes, if we have a pen that needs stroking Qt::PenStyle pen_style = d->pen.style(); if (d->dashStroker && pen_style != Qt::SolidLine && pen_style != Qt::NoPen && d->pen.widthF() != 0.0f) { QRectF clipRect = d->matrix.inverted().mapRect(QRectF(d->deviceRect)); d->dashStroker->setClipRect(clipRect); } } if (flags & DirtyOpacity) { int newOpacity = qRound(state.opacity() * 256.0); if (d->opacity != newOpacity) { update_fast_pen = true; update_fast_text = true; d->opacity = newOpacity; if (d->opacity > 256) d->opacity = 256; if (d->opacity < 0) d->opacity = 0; // Force update pen/brush as to get proper alpha colors propagated flags |= DirtyPen; flags |= DirtyBrush; } } if (flags & DirtyPen && d->pen != state.pen()) { update_fast_pen = true; update_fast_text = true; d->pen = state.pen(); if (d->pen.style() == Qt::CustomDashLine && d->pen.dashPattern().size() == 0) d->pen.setStyle(Qt::SolidLine); d->basicStroker.setJoinStyle(d->pen.joinStyle()); d->basicStroker.setCapStyle(d->pen.capStyle()); d->basicStroker.setMiterLimit(d->pen.miterLimit()); qreal penWidth = d->pen.widthF(); if (penWidth == 0) d->basicStroker.setStrokeWidth(1); else d->basicStroker.setStrokeWidth(penWidth); Qt::PenStyle pen_style = d->pen.style(); if(pen_style == Qt::SolidLine) { d->stroker = &d->basicStroker; } else if (pen_style != Qt::NoPen) { if (!d->dashStroker) d->dashStroker = new QDashStroker(&d->basicStroker); if (penWidth == 0) { d->dashStroker->setClipRect(d->deviceRect); } else { QRectF clipRect = d->matrix.inverted().mapRect(QRectF(d->deviceRect)); d->dashStroker->setClipRect(clipRect); } d->dashStroker->setDashPattern(d->pen.dashPattern()); d->dashStroker->setDashOffset(d->pen.dashOffset()); d->stroker = d->dashStroker; } else { d->stroker = 0; } d->penData.setup(pen_style == Qt::NoPen ? QBrush() : d->pen.brush(), d->opacity); d->updateMatrixData(&d->penData, d->pen.brush(), d->matrix); } if (flags & (DirtyBrush|DirtyBrushOrigin)) { QBrush brush = state.brush(); d->brush = brush; d->brushOffset = state.brushOrigin(); d->brushData.setup(d->brush, d->opacity); d->updateMatrixData(&d->brushData, d->brush, d->brushMatrix()); } if (!d->paint_unclipped && (flags & (DirtyClipPath | DirtyClipRegion))) { d->user_clip_enabled = true; // If we're setting a clip, we kill the old clip if (d->rasterBuffer->disabled_clip) { delete d->rasterBuffer->disabled_clip; d->rasterBuffer->disabled_clip = 0; } } if (d->paint_unclipped) { } else if (flags & DirtyClipPath) { if (state.clipOperation() == Qt::NoClip) updateClipRegion(QRegion(), Qt::NoClip); else updateClipPath(state.clipPath(), state.clipOperation()); } else if (flags & DirtyClipRegion) { updateClipRegion(state.clipRegion(), state.clipOperation()); } else if (flags & DirtyClipEnabled) { if (state.isClipEnabled() != d->user_clip_enabled) { d->user_clip_enabled = state.isClipEnabled(); // The tricky case... When we disable clipping we still do // system clip so we need to rasterize the system clip and // replace the current clip with it. Since people might // choose to set clipping to true later on we have to save the // current one (in disabled_clip). if (!state.isClipEnabled()) { // save current clip for later Q_ASSERT(!d->rasterBuffer->disabled_clip); d->rasterBuffer->disabled_clip = d->rasterBuffer->clip; d->rasterBuffer->disabledClipRegion = d->rasterBuffer->clipRegion; d->rasterBuffer->disabledClipRect = d->rasterBuffer->clipRect; d->rasterBuffer->clip = 0; d->rasterBuffer->clipRegion = QRegion(); d->rasterBuffer->clipRect = QRect(); d->disabledClipRegion = d->clipRegion; updateClipRegion(QRegion(), Qt::NoClip); } else { // re-enable old clip d->rasterBuffer->resetClip(); d->rasterBuffer->clip = d->rasterBuffer->disabled_clip; d->rasterBuffer->clipRegion = d->rasterBuffer->disabledClipRegion; d->rasterBuffer->clipRect = d->rasterBuffer->disabledClipRect; d->rasterBuffer->disabled_clip = 0; d->rasterBuffer->disabledClipRegion = QRegion(); d->rasterBuffer->disabledClipRect = QRect(); d->clipRegion = d->disabledClipRegion; d->disabledClipRegion = QRegion(); } d->penData.adjustSpanMethods(); d->brushData.adjustSpanMethods(); } } if (!d->mono_surface) { if (flags & DirtyHints) { update_fast_pen = true; d->antialiased = bool(state.renderHints() & QPainter::Antialiasing); d->bilinear = bool(state.renderHints() & QPainter::SmoothPixmapTransform); // propegate state to data's d->brushData.bilinear = d->penData.bilinear = d->bilinear; d->penData.adjustSpanMethods(); d->brushData.adjustSpanMethods(); } if (flags & DirtyCompositionMode) { update_fast_text = true; d->rasterBuffer->compositionMode = state.compositionMode(); } } if (update_fast_pen) { d->fast_pen = !d->antialiased && (d->pen.widthF() == 0 || (d->pen.widthF() <= 1 && (d->txop <= QTransform::TxTranslate || d->pen.isCosmetic()))); } if (update_fast_text) { const QPainter::CompositionMode mode = d->rasterBuffer->compositionMode; d->fast_text = d->rasterBuffer->buffer() && (d->penData.type == QSpanData::Solid) && (mode == QPainter::CompositionMode_Source || (mode == QPainter::CompositionMode_SourceOver && qAlpha(d->penData.solid.color) == 255)); }}void QRasterPaintEnginePrivate::updateMatrixData(QSpanData *spanData, const QBrush &b, const QTransform &m){ if (b.d->style == Qt::NoBrush || b.d->style == Qt::SolidPattern) return; if (b.d->hasTransform) { spanData->setupMatrix(b.transform() * m, bilinear); } else { if (txop <= QTransform::TxTranslate) { // specialize setupMatrix for translation matrices // to avoid needless matrix inversion spanData->m11 = 1; spanData->m12 = 0; spanData->m13 = 0; spanData->m21 = 0; spanData->m22 = 1; spanData->m23 = 0; spanData->dx = -m.dx(); spanData->dy = -m.dy(); spanData->txop = txop; spanData->bilinear = bilinear; spanData->adjustSpanMethods(); } else { spanData->setupMatrix(m, bilinear); } }}/*! \internal*/void QRasterPaintEngine::updateClipRegion(const QRegion &r, Qt::ClipOperation op){#ifdef QT_DEBUG_DRAW qDebug() << " - QRasterPaintEngine::updateClipRegion() op=" << op << r;#endif Q_D(QRasterPaintEngine); if (d->paint_unclipped) return; if (d->txop <= QTransform::TxScale && (!d->rasterBuffer->clip || op == Qt::NoClip || op == Qt::ReplaceClip)) { switch (op) { case Qt::NoClip: d->clipRegion = d->deviceRect; break; case Qt::IntersectClip: d->clipRegion &= d->matrix.map(r); break; case Qt::ReplaceClip: d->clipRegion = d->matrix.map(r) & d->deviceRect; break; case Qt::UniteClip: d->clipRegion |= d->matrix.map(r); break; default: break; } const QRegion sysClip = systemClip(); if (!sysClip.isEmpty()) d->clipRegion &= sysClip; if (!d->clipRegion.isEmpty()) { if (d->clipRegion.rects().count() == 1) d->setClipRect(d->clipRegion.boundingRect()); else d->setClipRegion(d->clipRegion); return; } } QPainterPath p; p.addRegion(r); updateClipPath(p, op);}void QRasterPaintEnginePrivate::setClipRect(const QRect &rect){ rasterBuffer->resetClip(); rasterBuffer->clipRect = rect; rasterBuffer->clipRegion = QRegion(); rasterBuffer->clipEnabled = true; penData.adjustSpanMethods(); brushData.adjustSpanMethods();}void QRasterPaintEnginePrivate::setClipRegion(const QRegion ®ion){ rasterBuffer->resetClip(); rasterBuffer->clipRect = QRect(); rasterBuffer->clipRegion = region; rasterBuffer->clipEnabled = true; penData.adjustSpanMethods(); brushData.adjustSpanMethods();}/*! \internal*/void QRasterPaintEngine::updateClipPath(const QPainterPath &path, Qt::ClipOperation op){ Q_D(QRasterPaintEngine);#ifdef QT_DEBUG_DRAW qDebug() << " - QRasterPaintEngine::updateClipPath(), op=" << op << path.boundingRect();#endif if (d->paint_unclipped) return; // Convert old clip if necessary if (d->rasterBuffer->clip) { // nothing } else if (!d->rasterBuffer->clipRect.isEmpty()) { if (op == Qt::UniteClip || op == Qt::IntersectClip) { d->rasterBuffer->clip = new QClipData(d->rasterBuffer->height()); d->rasterBuffer->clip->setClipRect(d->rasterBuffer->clipRect); } d->rasterBuffer->clipRect = QRect(); } else if (!d->rasterBuffer->clipRegion.isEmpty()) { if (op == Qt::UniteClip || op == Qt::IntersectClip) { d->rasterBuffer->clip = new QClipData(d->rasterBuffer->height()); d->rasterBuffer->clip->setClipRegion(d->rasterBuffer->clipRegion); } d->rasterBuffer->clipRegion = QRegion(); } d->updateClip_helper(path, op); // Reset the baseClip if the operation requires it. if (!d->baseClip.isEmpty()) { switch (op) { case Qt::UniteClip: case Qt::ReplaceClip: case Qt::NoClip: d->outlineMapper->setMatrix(QTransform(), QTransform::TxNone); d->updateClip_helper(d->baseClip, Qt::IntersectClip); d->outlineMapper->setMatrix(d->matrix, d->txop); break; default: break; } }}/*! \internal*/void QRasterPaintEngine::fillPath(const QPainterPath &path, QSpanData *fillData){#ifdef QT_DEBUG_DRAW qDebug() << " --- fillPath, bounds=" << path.boundingRect();#endif if (!fillData->blend) return; Q_D(QRasterPaintEngine); const QRectF controlPointRect = path.controlPointRect(); resolveGradientBoundsConditional(controlPointRect, fillData); ProcessSpans blend = d->getBrushFunc(d->matrix.mapRect(controlPointRect), fillData); d->rasterize(d->outlineMapper->convertPath(path), blend, fillData, d->rasterBuffer);}static void fillRect(const QRect &r, QSpanData *data, QRasterPaintEnginePrivate *pe){ QRect rect = r.normalized(); int x1 = qMax(rect.x(), 0); int x2 = qMin(rect.width() + rect.x(), data->rasterBuffer->width()); int y1 = qMax(rect.y(), 0); int y2 = qMin(rect.height() + rect.y(), data->rasterBuffer->height()); QClipData *clip = data->rasterBuffer->clipEnabled ? data->rasterBuffer->clip : 0; if (clip) { x1 = qMax(x1, clip->xmin); x2 = qMin(x2, clip->xmax); y1 = qMax(y1, clip->ymin); y2 = qMin(y2, clip->ymax); } const int width = x2 - x1; const int height = y2 - y1; rect = QRect(x1, y1, width, height); if (rect.isEmpty()) return; if (pe && data->fillRect && pe->isUnclipped_normalized(rect)) { const QPainter::CompositionMode mode = pe->rasterBuffer->compositionMode; if (mode == QPainter::CompositionMode_Source || (mode == QPainter::CompositionMode_SourceOver
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -