Revision control
Copy as Markdown
// Copyright (C) 2025 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
// Qt-Security score:significant reason:default
#ifndef QCPAINTERENGINE_P_H
#define QCPAINTERENGINE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists purely as an
// implementation detail. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include <QtGui/qcolor.h>
#include <QtGui/qtransform.h>
#include <QtGui/qpainterpath.h>
#include <QtGui/qmatrix4x4.h>
#include <QtCore/qrect.h>
#include <QtCore/qlist.h>
#include "qcanvaspainter.h"
#include "qcanvaspath.h"
#include "qcpainterengineutils_p.h"
QT_BEGIN_NAMESPACE
class QCPainterRhiRenderer;
class QCPainterEngine
{
public:
enum QCPointFlags : quint8 {
PointCorner = 1 << 0,
PointLeft = 1 << 1,
PointBevel = 1 << 2,
PointInnerBevel = 1 << 3,
};
QCPainterEngine();
// State
void beginPaint(float logicalWidth, float logicalHeight, float dpr = 1.0f);
void setCustomMatrix(const QMatrix4x4 &matrix);
void endPaint();
void save();
void restore();
void reset();
// Painting styles
void setStrokeColor(QColor color);
void setStrokePaint(const QCPaint &paint);
void setFillColor(QColor color);
void setFillPaint(const QCPaint &paint);
void setLineWidth(float width);
void setLineCap(QCanvasPainter::LineCap lineCap);
void setLineJoin(QCanvasPainter::LineJoin lineJoin);
void setGlobalAlpha(float alpha);
void setGlobalBrightness(float value);
void setGlobalContrast(float value);
void setGlobalSaturation(float value);
void setFillRule(QCanvasPainter::FillRule fillRule);
QCanvasPainter::FillRule fillRule() const;
// Custom paints
void setCustomStrokeBrush(const QCanvasBrush &brush);
void setCustomFillBrush(const QCanvasBrush &brush);
// Transform
QTransform currentTransform() const;
void transform(const QTransform &transform);
void setTransform(const QTransform &transform);
void resetTransform();
void translate(float x, float y);
void scale(float x, float y);
void rotate(float angle);
void skew(float angleX, float angleY = 0.0f);
void setBrushTransform(const QTransform &transform);
// Images
int createImage(int width, int height,
QCanvasPainter::ImageFlags flags,
const uchar* data);
bool deleteImage(int imageId);
void drawImageId(int imageId, float x, float y, float width, float height,
QColor tintColor);
void drawImageIdAt(int imageId, float x, float y, float width, float height,
float dX, float dY, float dWidth, float dHeight,
QColor tintColor);
QCPaint createImagePattern(float x, float y, float width, float height,
int imageId, float angle, QColor tintColor);
// Paths
void beginPath();
void closePath();
void moveTo(float x, float y);
void lineTo(float x, float y);
void bezierTo(float cp1X, float cp1Y, float cp2X, float cp2Y, float x, float y);
void quadTo(float cpX, float cpY, float x, float y);
void arcTo(float x1, float y1, float x2, float y2, float radius);
void addArc(float x, float y, float radius,
float a0, float a1, QCanvasPainter::PathWinding direction,
bool isConnected);
void addRect(float x, float y, float width, float height);
void addRoundRect(float x, float y, float width, float height, float radius);
void addRoundRect(float x, float y, float width, float height,
float radiusTopLeft, float radiusTopRight,
float radiusBottomRight, float radiusBottomLeft);
// TODO: Have also startAngle, endAngle and direction (winding)?
void addEllipse(float x, float y, float radiusX, float radiusY);
void addCircle(float x, float y, float radius);
void addPath(const QPainterPath &path);
void addPath(const QCanvasPath &path, const QTransform &transform = QTransform());
void addPath(const QCanvasPath &path, qsizetype start, qsizetype count, const QTransform &transform = QTransform());
void setPathWinding(QCanvasPainter::PathWinding winding);
void fill(QCanvasPainter::FillRule fillRule, QCanvasPath *maybePath = nullptr, int pathGroup = -1, bool cachedPathUpdateRequired = false);
void fillForClear();
void stroke(QCanvasPath *maybePath = nullptr, int pathGroup = -1, bool cachedPathUpdateRequired = false);
void fill(const QCanvasPath &path, QCanvasPainter::FillRule fillRule, int pathGroup);
void stroke(const QCanvasPath &path, int pathGroup);
void setStencilClip(const QList<QRectF> &rects);
void setStencilClip(const QVectorPath &clipPath);
// Blending
void setGlobalCompositeOperation(QCanvasPainter::CompositeOperation op);
// Clipping
void resetClipRect();
void setClipRect(const QRectF &rect);
// Text
void setTextWrapMode(QCanvasPainter::WrapMode wrapMode);
void setTextLineHeight(float height);
void setTextAntialias(float antialias);
void setTextAlignment(QCanvasPainter::TextAlign align);
void setTextBaseline(QCanvasPainter::TextBaseline baseline);
void setTextDirection(QCanvasPainter::TextDirection direction);
void fillText(const QString &text, const QRectF &rect);
void fillShapedText(QFontEngine *fontEngine, const quint32 *glyphIndexes,
const QFixedPoint *glyphPositions, int glyphCount);
QRectF textBoundingBox(const QString &text, const QRectF &rect);
// Other
void resetDebugCounters();
void syncDebugCounters();
QCDebugCounters debugCounters() const;
void setAntialias(float antialias);
void setMiterLimit(float limit);
void removePathGroup(int pathGroup);
void setWindingEnforceEnabled(bool enabled);
void setHighQualityStrokingEnabled(bool enabled);
void setAntialiasingEnabled(bool enabled);
// Internal
QCContext* initialize(QCPainterRhiRenderer *renderer);
void cleanup();
void releaseUnusedResources();
#ifdef QCPAINTER_PERF_DEBUG
QCPerfLogging *perfLogger() { return &perf; }
#endif
private:
friend class QCanvasPainterPrivate;
friend class QCPainterRhiRenderer;
void setDevicePixelRatio(float ratio);
void appendCommand(QCCommand command);
void appendCommands(const QCCommand commands[], int cCount);
void appendCommandsData(const float commandsData[], int dCount, bool ignoreTransform = false);
void handleSetPathWinding(QCanvasPainter::PathWinding winding);
void handleClosePath();
void handleMoveTo();
void handleAddPoint(float x, float y, QCPointFlags flags);
void commandsToPaths();
void tesselateBezier(float x1, float y1, float x2, float y2,
float x3, float y3, float x4, float y4,
int level, QCPointFlags flags);
void enforceWinding(int pointsOffset, int pointsCount, QCanvasPainter::PathWinding winding);
void expandFill();
void expandStroke(float w, QCanvasPainter::LineCap cap, QCanvasPainter::LineJoin join, float miterLimit);
void calculateJoins(float w, QCanvasPainter::LineJoin join, float miterLimit);
void addBevelJoin(const QCPoint &p0, const QCPoint &p1,
float lw, float rw, float lu, float ru);
void addRoundJoin(const QCPoint &p0, const QCPoint &p1,
float lw, float rw, float lu, float ru, int capDivs);
void addButtCapStart(const QCPoint &p,
float dx, float dy, float w, float d,
float aa, float u0, float u1);
void addRoundCapStart(const QCPoint &p,
float dx, float dy, float w, int capDivs,
float u0, float u1);
void addButtCapEnd(const QCPoint &p,
float dx, float dy, float w, float d,
float aa, float u0, float u1);
void addRoundCapEnd(const QCPoint &p,
float dx, float dy, float w, int capDivs,
float u0, float u1);
inline void addVert(float x, float y, float u, float v) noexcept;
void ensureVertices(int count);
void preparePainterPath(const QCanvasPath &path, bool ignoreTransform = false);
void appendPainterPath(const QCanvasPath &path,
const QTransform &transform = QTransform());
void appendPainterPath(const QCanvasPath &path,
qsizetype start,
qsizetype count,
const QTransform &transform = QTransform());
bool fillCachedPathUpdateRequired(QCanvasPath *path, int pathGroup);
bool strokeCachedPathUpdateRequired(QCanvasPath *path, int pathGroup);
QCanvasPainter::TextAlign effectiveTextAlign(QStringView text) const;
void fillPlainRect(const QCPaint &paint, float x, float y, float width, float height);
QCPaint getFillPaint(bool ignoreTransform = false);
QCPaint getStrokePaint(float *strokeWidth, bool ignoreTransform = false);
#ifndef QCPAINTER_DISABLE_TEXT_SUPPORT
void updateStateFontVars();
void renderFilledText(int fontTex);
#endif
QCContext ctx;
QCState state;
QCPainterRhiRenderer *m_renderer = nullptr;
#ifdef QCPAINTER_PERF_DEBUG
QCPerfLogging perf;
#endif
#ifndef QCPAINTER_DISABLE_TEXT_SUPPORT
QCRhiDistanceFieldGlyphCache::VertexList textVertices;
QCRhiDistanceFieldGlyphCache::IndexList textIndices;
QCRhiDistanceFieldGlyphCache::VertexList colorTextVertices;
QCRhiDistanceFieldGlyphCache::IndexList colorTextIndices;
#endif
};
QT_END_NAMESPACE
#endif // QCPAINTERENGINE_P_H