diff options
Diffstat (limited to 'src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp')
-rw-r--r-- | src/runtimerender/Qt3DSDistanceFieldGlyphCache.cpp | 48 |
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) { |