Revision control
Copy as Markdown
// Copyright (C) 2026 The Qt Company Ltd.
// SPDX-License-Identifier: LicenseRef-Qt-Commercial OR GPL-3.0-only
// Qt-Security score:significant reason:default
#ifndef QCRHICOLORGLYPHCACHE_P_H
#define QCRHICOLORGLYPHCACHE_P_H
//
// W A R N I N G
// -------------
//
// This file is not part of the Qt API. It exists for the convenience
// of other Qt classes. This header file may change from version to
// version without notice, or even be removed.
//
// We mean it.
//
#include "qcrhidistancefieldglyphcache_p.h"
#include <QtGui/QImage>
#include <QtGui/QRawFont>
#include <QtGui/QGlyphRun>
#include <QtCore/QSet>
#include <QtGui/private/qfontengine_p.h>
#include <rhi/qrhi.h>
#include "qcareaallocator_p.h"
QT_BEGIN_NAMESPACE
class QCRhiColorGlyphCache
{
public:
QCRhiColorGlyphCache(QRhi *rhi);
~QCRhiColorGlyphCache();
void addGlyphRun(QPointF glyphPos,
const QGlyphRun &run,
QColor color,
const QTransform &transform,
float devicePixelRatio,
QCRhiDistanceFieldGlyphCache::VertexList *verts,
QCRhiDistanceFieldGlyphCache::IndexList *indices);
void commitResourceUpdate(QRhiResourceUpdateBatch *batch);
void optimizeAfterRendering();
QRhiTexture *texture() const { return m_atlas; }
bool isEmpty() const { return m_atlas == nullptr; }
private:
struct GlyphKey
{
QFontEngine::FaceId faceId;
quint32 glyph;
int pixelSize;
float scale; // rasterization scale (device pixel ratio)
QRgb color; // text color, used by COLR "foreground" layers
bool operator==(const GlyphKey &o) const
{
return glyph == o.glyph && pixelSize == o.pixelSize && scale == o.scale
&& color == o.color && faceId == o.faceId;
}
};
friend size_t qHash(const GlyphKey &k, size_t seed)
{
return qHashMulti(seed, k.faceId, k.glyph, k.pixelSize, k.scale, k.color);
}
struct GlyphData
{
QRect atlasRect;
QPointF bearing;
bool valid = false;
quint32 ref = 0;
};
void ensureAtlas();
void growAtlas(int requiredSize);
const GlyphData &ensureGlyph(const GlyphKey &key, QFontEngine *fe,
QColor color, const QTransform &rasterTransform);
bool useTextureResizeWorkaround() const;
void referenceGlyph(const GlyphKey &key, GlyphData &gd);
QRect evictUntilAllocated(const QSize &allocSize);
void releaseGlyphs(const QSet<GlyphKey> &glyphs);
QRhi *m_rhi = nullptr;
QRhiTexture *m_atlas = nullptr;
QRhiResourceUpdateBatch *m_batch = nullptr;
QCAreaAllocator *m_allocator = nullptr;
QHash<GlyphKey, GlyphData> m_glyphs;
QSet<GlyphKey> m_referencedThisFrame;
QSet<GlyphKey> m_referencedPrevFrame;
QSet<GlyphKey> m_unusedGlyphs;
const GlyphData m_invalidGlyph;
int m_atlasSize = 0; // current physical atlas texture size (square, px)
int m_maxAtlasSize = 0; // allocator coordinate space and growth ceiling (px)
QImage m_atlasImage; // CPU shadow of the atlas (resize workaround only)
};
QT_END_NAMESPACE
#endif // QCRHICOLORGLYPHCACHE_P_H