📄 qpaintengine_x11.cpp
字号:
Q_ASSERT(points); Q_ASSERT(pointCount); Q_D(QX11PaintEngine); if (!d->has_pen) return; if (d->cpen.widthF() > .0f || d->has_alpha_brush || d->has_alpha_pen || d->has_custom_pen || (d->render_hints & QPainter::Antialiasing)) { Qt::PenCapStyle capStyle = d->cpen.capStyle(); if (capStyle == Qt::FlatCap) d->cpen.setCapStyle(Qt::SquareCap); const QPoint *end = points + pointCount; while (points < end) { QPainterPath path; path.moveTo(*points); path.lineTo(points->x()+.005, points->y()); drawPath(path); ++points; } d->cpen.setCapStyle(capStyle); return; } static const int BUF_SIZE = 1024; XPoint xPoints[BUF_SIZE]; int i = 0, j = 0; while (i < pointCount) { while (i < pointCount && j < BUF_SIZE) { const QPoint &xformed = d->matrix.map(points[i]); int x = xformed.x(); int y = xformed.y(); if (x >= SHRT_MIN && y >= SHRT_MIN && x < SHRT_MAX && y < SHRT_MAX) { xPoints[j].x = x; xPoints[j].y = y; ++j; } ++i; } if (j) XDrawPoints(d->dpy, d->hd, d->gc, xPoints, j, CoordModeOrigin); j = 0; }}void QX11PaintEngine::drawPoints(const QPointF *points, int pointCount){ Q_ASSERT(points); Q_ASSERT(pointCount); Q_D(QX11PaintEngine); if (!d->has_pen) return; if (d->cpen.widthF() > .0f || d->has_alpha_brush || d->has_alpha_pen || d->has_custom_pen || (d->render_hints & QPainter::Antialiasing)) { Qt::PenCapStyle capStyle = d->cpen.capStyle(); if (capStyle == Qt::FlatCap) d->cpen.setCapStyle(Qt::SquareCap); const QPointF *end = points + pointCount; while (points < end) { QPainterPath path; path.moveTo(*points); path.lineTo(points->x() + 0.005, points->y()); drawPath(path); ++points; } d->cpen.setCapStyle(capStyle); return; } static const int BUF_SIZE = 1024; XPoint xPoints[BUF_SIZE]; int i = 0, j = 0; while (i < pointCount) { while (i < pointCount && j < BUF_SIZE) { const QPointF &xformed = d->matrix.map(points[i]); int x = qFloor(xformed.x()); int y = qFloor(xformed.y()); if (x >= SHRT_MIN && y >= SHRT_MIN && x < SHRT_MAX && y < SHRT_MAX) { xPoints[j].x = x; xPoints[j].y = y; ++j; } ++i; } if (j) XDrawPoints(d->dpy, d->hd, d->gc, xPoints, j, CoordModeOrigin); j = 0; }}QPainter::RenderHints QX11PaintEngine::supportedRenderHints() const{#if !defined(QT_NO_XRENDER) if (X11->use_xrender) return QPainter::Antialiasing;#endif return QFlag(0);}void QX11PaintEngine::updateState(const QPaintEngineState &state){ Q_D(QX11PaintEngine); QPaintEngine::DirtyFlags flags = state.state(); if (flags & DirtyOpacity) { d->opacity = state.opacity(); // Force update pen/brush as to get proper alpha colors propagated flags |= DirtyPen; flags |= DirtyBrush; } if (flags & DirtyTransform) updateMatrix(state.transform()); if (flags & DirtyPen) updatePen(state.pen()); if (flags & (DirtyBrush | DirtyBrushOrigin)) updateBrush(state.brush(), state.brushOrigin()); if (flags & DirtyFont) updateFont(state.font()); if (state.state() & DirtyClipEnabled) { if (state.isClipEnabled()) { QPolygonF clip_poly_dev(d->matrix.map(painter()->clipPath().toFillPolygon())); QPolygonF clipped_poly_dev; d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev); updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), Qt::ReplaceClip); } else { updateClipRegion_dev(QRegion(), Qt::NoClip); } } if (flags & DirtyClipPath) { QPolygonF clip_poly_dev(d->matrix.map(state.clipPath().toFillPolygon())); QPolygonF clipped_poly_dev; d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev); updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon(), state.clipPath().fillRule()), state.clipOperation()); } else if (flags & DirtyClipRegion) { QPainterPath clip_path; clip_path.addRegion(state.clipRegion()); QPolygonF clip_poly_dev(d->matrix.map(clip_path.toFillPolygon())); QPolygonF clipped_poly_dev; d->clipPolygon_dev(clip_poly_dev, &clipped_poly_dev); updateClipRegion_dev(QRegion(clipped_poly_dev.toPolygon()), state.clipOperation()); } if (flags & DirtyHints) updateRenderHints(state.renderHints());#if !defined(QT_NO_XRENDER) if (flags & DirtyCompositionMode) { d->composition_mode = qpainterOpToXrender(state.compositionMode()); }#endif d->decidePathFallback();}void QX11PaintEngine::updateRenderHints(QPainter::RenderHints hints){ Q_D(QX11PaintEngine); d->render_hints = hints; if ((d->txop > QTransform::TxTranslate) || (hints & QPainter::Antialiasing)) d->use_path_fallback = true; else d->use_path_fallback = false;#if !defined(QT_NO_XRENDER) if (X11->use_xrender && d->picture) { XRenderPictureAttributes attrs; attrs.poly_edge = (hints & QPainter::Antialiasing) ? PolyEdgeSmooth : PolyEdgeSharp; XRenderChangePicture(d->dpy, d->picture, CPPolyEdge, &attrs); }#endif}void QX11PaintEngine::updatePen(const QPen &pen){ Q_D(QX11PaintEngine); d->cpen = pen; int cp = CapButt; int jn = JoinMiter; int ps = pen.style(); if (d->opacity < 1.0) { QColor c = d->cpen.color(); c.setAlpha(qRound(c.alpha()*d->opacity)); d->cpen.setColor(c); } d->has_pen = (ps != Qt::NoPen); d->has_alpha_pen = (pen.color().alpha() != 255); switch (pen.capStyle()) { case Qt::SquareCap: cp = CapProjecting; break; case Qt::RoundCap: cp = CapRound; break; case Qt::FlatCap: default: cp = CapButt; break; } switch (pen.joinStyle()) { case Qt::BevelJoin: jn = JoinBevel; break; case Qt::RoundJoin: jn = JoinRound; break; case Qt::MiterJoin: default: jn = JoinMiter; break; } d->adapted_pen_origin = false; char dashes[10]; // custom pen dashes int dash_len = 0; // length of dash list int xStyle = LineSolid; /* We are emulating Windows here. Windows treats cpen.width() == 1 (or 0) as a very special case. The fudge variable unifies this case with the general case. */ qreal pen_width = pen.widthF(); int scale = qRound(pen_width < 1 ? 1 : pen_width); int space = (pen_width < 1 ? 1 : (2 * scale)); int dot = 1 * scale; int dash = 4 * scale; d->has_custom_pen = false; switch (ps) { case Qt::NoPen: case Qt::SolidLine: xStyle = LineSolid; break; case Qt::DashLine: dashes[0] = dash; dashes[1] = space; dash_len = 2; xStyle = LineOnOffDash; break; case Qt::DotLine: dashes[0] = dot; dashes[1] = space; dash_len = 2; xStyle = LineOnOffDash; break; case Qt::DashDotLine: dashes[0] = dash; dashes[1] = space; dashes[2] = dot; dashes[3] = space; dash_len = 4; xStyle = LineOnOffDash; break; case Qt::DashDotDotLine: dashes[0] = dash; dashes[1] = space; dashes[2] = dot; dashes[3] = space; dashes[4] = dot; dashes[5] = space; dash_len = 6; xStyle = LineOnOffDash; break; case Qt::CustomDashLine: d->has_custom_pen = true; break; } ulong mask = GCForeground | GCBackground | GCGraphicsExposures | GCLineWidth | GCCapStyle | GCJoinStyle | GCLineStyle; XGCValues vals; vals.graphics_exposures = false; if (d->pdev_depth == 1) { vals.foreground = qGray(pen.color().rgb()) > 127 ? 0 : 1; vals.background = qGray(QColor(Qt::transparent).rgb()) > 127 ? 0 : 1; } else if (d->pdev->devType() == QInternal::Pixmap && d->pdev_depth == 32 && X11->use_xrender) { vals.foreground = pen.color().rgba(); vals.background = QColor(Qt::transparent).rgba(); } else { QColormap cmap = QColormap::instance(d->scrn); vals.foreground = cmap.pixel(pen.color()); vals.background = cmap.pixel(QColor(Qt::transparent)); } vals.line_width = qRound(pen.widthF()); vals.cap_style = cp; vals.join_style = jn; vals.line_style = xStyle; XChangeGC(d->dpy, d->gc, mask, &vals); if (dash_len) { // make dash list XSetDashes(d->dpy, d->gc, 0, dashes, dash_len); } if (!d->has_clipping) { // if clipping is set the paintevent clip region is merged with the clip region QRegion sysClip = systemClip(); if (!sysClip.isEmpty()) x11SetClipRegion(d->dpy, d->gc, 0, d->picture, sysClip); else x11ClearClipRegion(d->dpy, d->gc, 0, d->picture); }}void QX11PaintEngine::updateBrush(const QBrush &brush, const QPointF &origin){ Q_D(QX11PaintEngine); d->cbrush = brush; d->bg_origin = origin; d->adapted_brush_origin = false;#if !defined(QT_NO_XRENDER) d->current_brush = 0;#endif if (d->opacity < 1.0) { QColor c = d->cbrush.color(); c.setAlpha(qRound(c.alpha()*d->opacity)); d->cbrush.setColor(c); } int s = FillSolid; int bs = d->cbrush.style(); d->has_brush = (bs != Qt::NoBrush); d->has_pattern = bs >= Qt::Dense1Pattern && bs <= Qt::DiagCrossPattern; d->has_texture = bs == Qt::TexturePattern; d->has_alpha_brush = brush.color().alpha() != 255; ulong mask = GCForeground | GCBackground | GCGraphicsExposures | GCLineStyle | GCCapStyle | GCJoinStyle | GCFillStyle; XGCValues vals; vals.graphics_exposures = false; if (d->pdev_depth == 1) { vals.foreground = qGray(d->cbrush.color().rgb()) > 127 ? 0 : 1; vals.background = qGray(QColor(Qt::transparent).rgb()) > 127 ? 0 : 1; } else if (X11->use_xrender && d->pdev->devType() == QInternal::Pixmap && d->pdev_depth == 32) { vals.foreground = d->cbrush.color().rgba(); vals.background = QColor(Qt::transparent).rgba(); } else { QColormap cmap = QColormap::instance(d->scrn); vals.foreground = cmap.pixel(d->cbrush.color()); vals.background = cmap.pixel(QColor(Qt::transparent)); if (!X11->use_xrender && d->has_brush && !d->has_pattern && !brush.isOpaque()) { QPixmap pattern = qt_patternForAlpha(brush.color().alpha(), d->scrn); mask |= GCStipple; vals.stipple = pattern.handle(); s = FillStippled; d->adapted_brush_origin = true; } } vals.cap_style = CapButt; vals.join_style = JoinMiter; vals.line_style = LineSolid;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -