📄 qpaintengine_x11.cpp
字号:
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) { updateClipRegion_dev(d->matrix.map(state.clipRegion()), 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 > QPainterPrivate::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(); 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(d->bg_col.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 = d->bg_col.rgba(); } else { QColormap cmap = QColormap::instance(d->scrn); vals.foreground = cmap.pixel(pen.color()); vals.background = cmap.pixel(d->bg_col); } 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 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(d->bg_col.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 = d->bg_col.rgba(); } else { QColormap cmap = QColormap::instance(d->scrn); vals.foreground = cmap.pixel(d->cbrush.color()); vals.background = cmap.pixel(d->bg_col); if (!d->has_pattern && !brush.isOpaque()) { QPixmap pattern = qt_patternForAlpha(brush.color().alpha()); 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; if (d->has_pattern || d->has_texture) { QPixmap pm; if (bs == Qt::TexturePattern) { pm = d->cbrush.texture();#if !defined(QT_NO_XRENDER) if (X11->use_xrender) { XRenderPictureAttributes attrs; attrs.repeat = true; XRenderChangePicture(d->dpy, d->cbrush.texture().x11PictureHandle(), CPRepeat, &attrs); }#endif } else { pm = qt_pixmapForBrush(bs, true); } pm.x11SetScreen(d->scrn); if (pm.depth() == 1) { mask |= GCStipple; vals.stipple = pm.handle(); s = d->bg_mode == Qt::TransparentMode ? FillStippled : FillOpaqueStippled;#if !defined(QT_NO_XRENDER) if (X11->use_xrender) { d->bitmap_texture = QPixmap(pm.size()); if (d->bg_mode == Qt::OpaqueMode) d->bitmap_texture.fill(d->bg_brush.color()); else d->bitmap_texture.fill(Qt::transparent); ::Picture src = X11->getSolidFill(d->scrn, d->cbrush.color()); XRenderComposite(d->dpy, PictOpSrc, src, pm.x11PictureHandle(), d->bitmap_texture.x11PictureHandle(), 0, 0, pm.width(), pm.height(), 0, 0, pm.width(), pm.height()); XRenderPictureAttributes attrs; attrs.repeat = true; XRenderChangePicture(d->dpy, d->bitmap_texture.x11PictureHandle(), CPRepeat, &attrs); d->current_brush = d->bitmap_texture.x11PictureHandle(); }#endif } else { mask |= GCTile;#ifndef QT_NO_XRENDER if (d->pdev_depth == 32 && pm.depth() != 32) pm.data->convertToARGB32();#endif vals.tile = (pm.depth() == d->pdev_depth ? pm.handle() : pm.data->x11ConvertToDefaultDepth()); s = FillTiled;#if !defined(QT_NO_XRENDER) d->current_brush = d->cbrush.texture().x11PictureHandle();#endif } mask |= GCTileStipXOrigin | GCTileStipYOrigin; vals.ts_x_origin = qRound(origin.x()); vals.ts_y_origin = qRound(origin.y()); }#if !defined(QT_NO_XRENDER) else if (d->has_alpha_brush) { d->current_brush = X11->getSolidFill(d->scrn, d->cbrush.color()); }#endif vals.fill_style = s; XChangeGC(d->dpy, d->gc_brush, mask, &vals); if (!d->has_clipping) { QRegion sysClip = systemClip(); if (!sysClip.isEmpty()) x11SetClipRegion(d->dpy, d->gc_brush, 0, d->picture, sysClip); else x11ClearClipRegion(d->dpy, d->gc_brush, 0, d->picture); }}void QX11PaintEngine::drawEllipse(const QRect &rect){ Q_D(QX11PaintEngine); QRect devclip(SHRT_MIN, SHRT_MIN, SHRT_MAX*2 - 1, SHRT_MAX*2 - 1); QRect r(rect); if (d->txop == QPainterPrivate::TxTranslate) r.translate(qRound(d->matrix.dx()), qRound(d->matrix.dy())); if (d->use_path_fallback || devclip.intersect(r) != r) { QPainterPath path; path.addEllipse(rect); drawPath(path); return; } int x = r.x(); int y = r.y(); int w = r.width(); int h = r.height(); if (w < 1 || h < 1) return; if (w == 1 && h == 1) { XDrawPoint(d->dpy, d->hd, d->has_pen ? d->gc : d->gc_brush, x, y); return; } d->setupAdaptedOrigin(rect.topLeft()); if (d->has_brush) { // draw filled ellipse if (!d->has_pen) { XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64); XDrawArc(d->dpy, d->hd, d->gc_brush, x, y, w-1, h-1, 0, 360*64); return; } else{ XFillArc(d->dpy, d->hd, d->gc_brush, x, y, w, h, 0, 360*64); } } if (d->has_pen) // draw outline XDrawArc(d->dpy, d->hd, d->gc, x, y, w, h, 0, 360*64); d->resetAdaptedOrigin();}void QX11PaintEnginePrivate::fillPolygon_translated(const QPointF *polygonPoints, int pointCount, QX11PaintEnginePrivate::GCMode gcMode, QPaintEngine::PolygonDrawMode mode){ QVarLengthArray<QPointF> translated_points(pointCount); QPointF offset(matrix.dx(), matrix.dy()); for (int i = 0; i < pointCount; ++i) translated_points[i] = polygonPoints[i] + offset; fillPolygon_dev(translated_points.data(), pointCount, gcMode, mode);}#ifndef QT_NO_XRENDERstatic void qt_XRenderCompositeTrapezoids(Display *dpy, int op, Picture src, Picture dst, _Xconst XRenderPictFormat *maskFormat, int xSrc, int ySrc, const QVector<XTrapezoid> &traps){ const int MAX_TRAPS = 50000; int traps_left = traps.size(); while (traps_left) { int to_draw = traps_left; if (to_draw > MAX_TRAPS) to_draw = MAX_TRAPS; XRenderCompositeTrapezoids(dpy, op, src, dst, maskFormat, xSrc, ySrc, traps.constData()+traps.size()-traps_left, to_draw); traps_left -= to_draw; }}#endifvoid QX11PaintEnginePrivate::fillPolygon_dev(const QPointF *polygonPoints, int pointCount, QX11PaintEnginePrivate::GCMode gcMode,
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -