summaryrefslogtreecommitdiffstats
path: root/src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp')
-rw-r--r--src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp48
1 files changed, 29 insertions, 19 deletions
diff --git a/src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp b/src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp
index d19c9f6..658c402 100644
--- a/src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp
+++ b/src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp
@@ -59,9 +59,11 @@ Q3DSDistanceFieldGlyphCache::Q3DSDistanceFieldGlyphCache(
: QSGDistanceFieldGlyphCache(font)
, m_context(context)
{
- m_maxTextureSize = Q3DSDISTANCEFIELDGLYPHCACHE_MAXIMUM_TEXURE_SIZE;
+ m_maxTextureWidth = Q3DSDISTANCEFIELDGLYPHCACHE_MAXIMUM_TEXURE_SIZE;
loadPregeneratedCache(font);
+ if (m_textures.size() < m_maxTextureCount)
+ m_textures.resize(m_maxTextureCount);
}
Q3DSDistanceFieldGlyphCache::~Q3DSDistanceFieldGlyphCache()
@@ -71,16 +73,14 @@ Q3DSDistanceFieldGlyphCache::~Q3DSDistanceFieldGlyphCache()
delete m_areaAllocator;
}
-int Q3DSDistanceFieldGlyphCache::maxTextureSize() const
-{
- return m_maxTextureSize;
-}
-
Q3DSDistanceFieldGlyphCache::TextureInfo *Q3DSDistanceFieldGlyphCache::textureInfo(int index) const
{
- while (index >= m_textures.size())
- m_textures.append(TextureInfo());
- return &m_textures[index];
+ Q_ASSERT(index < m_textures.size());
+
+ if (index < m_textures.size())
+ return &m_textures[index];
+ else
+ return nullptr;
}
void Q3DSDistanceFieldGlyphCache::referenceGlyphs(const QSet<glyph_t> &glyphs)
@@ -145,7 +145,7 @@ void Q3DSDistanceFieldGlyphCache::storeGlyphs(const QList<QDistanceField> &glyph
TexCoord c = glyphTexCoord(glyphIndex);
TextureInfo *texInfo = m_glyphsTexture.value(glyphIndex);
- resizeTexture(texInfo, maxTextureSize(), texInfo->allocatedArea.height());
+ resizeTexture(texInfo, m_maxTextureWidth, texInfo->allocatedArea.height());
Q_ASSERT(!glyphTextures[texInfo].contains(glyphIndex));
glyphTextures[texInfo].append(glyphIndex);
@@ -187,15 +187,22 @@ void Q3DSDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs)
QList<GlyphPosition> glyphPositions;
QVector<glyph_t> glyphsToRender;
+ const int padding = Q3DSDISTANCEFIELDGLYPHCACHE_PADDING;
+ if (m_maxTextureHeight == 0) {
+ const qreal scaleFactor = qreal(1) / QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution);
+ // We need to add a buffer to avoid glyphs that overlap the border between two
+ // textures causing the height of the textures to extend beyond the limit.
+ m_maxTextureHeight = m_maxTextureWidth - (qCeil(m_referenceFont.pixelSize() * scaleFactor) + distanceFieldRadius() * 2 + padding * 2);
+ }
+
if (m_areaAllocator == nullptr) {
- m_areaAllocator = new QSGAreaAllocator(QSize(maxTextureSize(),
- m_maxTextureCount * maxTextureSize()));
+ m_areaAllocator = new QSGAreaAllocator(QSize(m_maxTextureWidth,
+ m_maxTextureCount * m_maxTextureHeight));
}
for (QSet<glyph_t>::const_iterator it = glyphs.constBegin(); it != glyphs.constEnd() ; ++it) {
glyph_t glyphIndex = *it;
- int padding = Q3DSDISTANCEFIELDGLYPHCACHE_PADDING;
QRectF boundingRect = glyphData(glyphIndex).boundingRect;
int glyphWidth = qCeil(boundingRect.width()) + distanceFieldRadius() * 2;
int glyphHeight = qCeil(boundingRect.height()) + distanceFieldRadius() * 2;
@@ -230,8 +237,8 @@ void Q3DSDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs)
continue;
}
- TextureInfo *tex = textureInfo(alloc.y() / maxTextureSize());
- alloc = QRect(alloc.x(), alloc.y() % maxTextureSize(), alloc.width(), alloc.height());
+ TextureInfo *tex = textureInfo(alloc.y() / m_maxTextureHeight);
+ alloc = QRect(alloc.x(), alloc.y() % m_maxTextureHeight, alloc.width(), alloc.height());
tex->allocatedArea |= alloc;
Q_ASSERT(tex->padding == padding || tex->padding < 0);
@@ -243,6 +250,7 @@ void Q3DSDistanceFieldGlyphCache::requestGlyphs(const QSet<glyph_t> &glyphs)
glyphPositions.append(p);
glyphsToRender.append(glyphIndex);
+
m_glyphsTexture.insert(glyphIndex, tex);
}
@@ -361,7 +369,7 @@ bool Q3DSDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
}
qreal pixelSize = qreal(Qtdf::fetch<quint16>(qtdfTableStart, Qtdf::pixelSize));
- m_maxTextureSize = int(Qtdf::fetch<quint32>(qtdfTableStart, Qtdf::textureSize));
+ m_maxTextureWidth = m_maxTextureHeight = int(Qtdf::fetch<quint32>(qtdfTableStart, Qtdf::textureSize));
m_doubleGlyphResolution = Qtdf::fetch<quint8>(qtdfTableStart, Qtdf::flags) == 1;
padding = Qtdf::fetch<quint8>(qtdfTableStart, Qtdf::headerPadding);
@@ -370,7 +378,7 @@ bool Q3DSDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
return false;
}
- if (m_maxTextureSize <= 0) {
+ if (m_maxTextureWidth <= 0) {
qWarning("Invalid texture size in '%s'", qPrintable(font.familyName()));
return false;
}
@@ -396,13 +404,15 @@ bool Q3DSDistanceFieldGlyphCache::loadPregeneratedCache(const QRawFont &font)
return false;
}
- if (m_areaAllocator->size().height() % m_maxTextureSize != 0) {
+ if (m_areaAllocator->size().height() % m_maxTextureHeight != 0) {
qWarning("Area allocator size mismatch in '%s'", qPrintable(font.familyName()));
return false;
}
- textureCount = m_areaAllocator->size().height() / m_maxTextureSize;
+ textureCount = m_areaAllocator->size().height() / m_maxTextureHeight;
m_maxTextureCount = qMax(m_maxTextureCount, textureCount);
+ if (m_textures.size() < m_maxTextureCount)
+ m_textures.resize(m_maxTextureCount);
const char *textureRecord = allocatorData;
for (int i = 0; i < textureCount; ++i, textureRecord += Qtdf::TextureRecordSize) {