diff options
Diffstat (limited to 'src/runtimerender/Qt3DSDistanceFieldRenderer.cpp')
-rw-r--r-- | src/runtimerender/Qt3DSDistanceFieldRenderer.cpp | 127 |
1 files changed, 80 insertions, 47 deletions
diff --git a/src/runtimerender/Qt3DSDistanceFieldRenderer.cpp b/src/runtimerender/Qt3DSDistanceFieldRenderer.cpp index cf80617..6378660 100644 --- a/src/runtimerender/Qt3DSDistanceFieldRenderer.cpp +++ b/src/runtimerender/Qt3DSDistanceFieldRenderer.cpp @@ -97,27 +97,27 @@ void Q3DSDistanceFieldRenderer::EndFrame() // Remove meshes for glyphs that weren't rendered last frame NVAllocatorCallback &alloc = m_context->GetAllocator(); - QHash<size_t, QHash<Q3DSDistanceFieldGlyphCache::TextureInfo *, GlyphInfo>>::const_iterator - glyphIt = m_glyphCache.constBegin(); - while (glyphIt != m_glyphCache.constEnd()) { + QHash<size_t, QHash<Q3DSDistanceFieldGlyphCache::TextureInfo *, GlyphInfo>>::iterator + glyphIt = m_glyphCache.begin(); + while (glyphIt != m_glyphCache.end()) { const size_t textHash = glyphIt.key(); if (!m_renderedTexts.contains(textHash)) - m_glyphCache.erase(glyphIt++); + glyphIt = m_glyphCache.erase(glyphIt); else - glyphIt++; + ++glyphIt; } - QHash<size_t, Q3DSDistanceFieldMesh>::const_iterator meshIt = m_meshCache.constBegin(); - while (meshIt != m_meshCache.constEnd()) { + QHash<size_t, Q3DSDistanceFieldMesh>::iterator meshIt = m_meshCache.begin(); + while (meshIt != m_meshCache.end()) { const size_t glyphHash = meshIt.key(); const Q3DSDistanceFieldMesh &mesh = meshIt.value(); if (!m_renderedGlyphs.contains(glyphHash)) { NVDelete(alloc, mesh.vertexBuffer); NVDelete(alloc, mesh.indexBuffer); NVDelete(alloc, mesh.inputAssembler); - m_meshCache.erase(meshIt++); + meshIt = m_meshCache.erase(meshIt); } else { - meshIt++; + ++meshIt; } } @@ -134,22 +134,27 @@ Q3DSDistanceFieldRenderer::buildGlyphsPerTexture(const SText &textInfo) QVector2D boundingBox = QVector2D(textInfo.m_BoundingBox.x, textInfo.m_BoundingBox.y); const float halfWidth = boundingBox.x() / 2.0f; const float halfHeight = boundingBox.y() / 2.0f; + + QVector2D center; + if (textInfo.m_VerticalAlignment == TextVerticalAlignment::Top) + center.setY(halfHeight); + else if (textInfo.m_VerticalAlignment == TextVerticalAlignment::Bottom) + center.setY(-halfHeight); + + if (textInfo.m_HorizontalAlignment == TextHorizontalAlignment::Left) + center.setX(halfWidth); + else if (textInfo.m_HorizontalAlignment == TextHorizontalAlignment::Right) + center.setX(-halfWidth); + bool hasValidBoundingBox = boundingBox.x() > 0 || boundingBox.y() > 0; QRawFont font = m_fontDatabase.findFont(textInfo.m_Font.c_str()); qreal scaleFactor = font.pixelSize() / qreal(textInfo.m_FontSize); - const float boundingWidth = (textInfo.m_HorizontalAlignment == TextHorizontalAlignment::Left - || textInfo.m_HorizontalAlignment == TextHorizontalAlignment::Right) - ? halfWidth : boundingBox.x(); - const float boundingHeight = (textInfo.m_VerticalAlignment == TextVerticalAlignment::Top - || textInfo.m_VerticalAlignment == TextVerticalAlignment::Bottom) - ? halfHeight : boundingBox.y(); - const qreal maximumWidth = boundingBox.isNull() ? qreal(0x01000000) - : qreal(boundingWidth) * scaleFactor; + : qreal(boundingBox.x()) * scaleFactor; const qreal maximumHeight = boundingBox.isNull() ? qreal(0x01000000) - : qreal(boundingHeight) * scaleFactor; + : qreal(boundingBox.y()) * scaleFactor; QTextLayout layout; QTextOption option = layout.textOption(); @@ -177,6 +182,7 @@ Q3DSDistanceFieldRenderer::buildGlyphsPerTexture(const SText &textInfo) QString text = textInfo.m_Text.c_str(); text.replace(QLatin1Char('\n'), QChar::LineSeparator); + text.replace(QLatin1String("<br>"), QString(QChar::LineSeparator)); qreal width; qreal height; @@ -218,6 +224,13 @@ Q3DSDistanceFieldRenderer::buildGlyphsPerTexture(const SText &textInfo) width = qMin(maximumWidth, qMax(width, textWidth)); height += layout.engine()->lines[line.lineNumber()].height().toReal(); + // Windows seems to have leading taken into account already in descent, which is used + // to calculate height. Linux and Integrity do not, so we'll need to handle the + // negative leading here. On Windows the leading is not negative, as it has already + // been accounted for in the descent. + const QFixed leading = layout.engine()->lines[line.lineNumber()].leading; + if (leading < 0) + height += leading.toInt(); // Fast path for right elide if (textInfo.m_Elide == TextElide::ElideRight @@ -430,40 +443,47 @@ Q3DSDistanceFieldRenderer::buildGlyphsPerTexture(const SText &textInfo) float y1Clip = 1.0f; float y2Clip = 1.0f; + float leftPos = -halfWidth + center.x(); + float rightPos = halfWidth + center.x(); + float topPos = -halfHeight + center.y(); + float bottomPos = halfHeight + center.y(); + if (hasValidBoundingBox) { - if ((cx1 < -halfWidth && cx2 < -halfWidth) - || (cx1 > halfWidth && cx2 > halfWidth) - || (cy1 < -halfHeight && cy2 < -halfHeight) - || (cy1 > halfHeight && cy2 > halfHeight)) { + if ((cx1 < leftPos && cx2 < leftPos) + || (cx1 > rightPos && cx2 > rightPos) + || (cy1 < topPos && cy2 < topPos) + || (cy1 > bottomPos && cy2 > bottomPos)) { continue; } float xDiff = qAbs(cx1 - cx2); float yDiff = qAbs(cy1 - cy2); - if (cx1 < -halfWidth) { - x1Clip = 1.0f - qAbs(cx1 - (-halfWidth)) / xDiff; - cx1 = -halfWidth; + if (cx1 < leftPos) { + x1Clip = 1.0f - qAbs(cx1 - leftPos) / xDiff; + cx1 = leftPos; } - if (cx2 > halfWidth) { - x2Clip = 1.0f - qAbs(cx2 - halfWidth) / xDiff; - cx2 = halfWidth; + if (cx2 > rightPos) { + x2Clip = 1.0f - qAbs(cx2 - rightPos) / xDiff; + cx2 = rightPos; } - if (cy1 < -halfHeight) { - y1Clip = 1.0f - qAbs(cy1 - (-halfHeight)) / yDiff; - cy1 = -halfHeight; + if (cy1 < topPos) { + y1Clip = 1.0f - qAbs(cy1 - topPos) / yDiff; + cy1 = topPos; } - if (cy2 > halfHeight) { - y2Clip = 1.0f - qAbs(cy2 - halfHeight) / yDiff; - cy2 = halfHeight; + if (cy2 > bottomPos) { + y2Clip = 1.0f - qAbs(cy2 - bottomPos) / yDiff; + cy2 = bottomPos; } } cy1 = -cy1; cy2 = -cy2; + topPos = -topPos; + bottomPos = -bottomPos; if (cx1 < minimum.x) minimum.x = cx1; @@ -488,14 +508,14 @@ Q3DSDistanceFieldRenderer::buildGlyphsPerTexture(const SText &textInfo) maximum.y = cy1; if (hasValidBoundingBox) { - if (maximum.x < halfWidth) - maximum.x = halfWidth; - if (minimum.x > -halfWidth) - minimum.x = -halfWidth; - if (maximum.y < halfHeight) - maximum.y = halfHeight; - if (minimum.y > -halfHeight) - minimum.y = -halfHeight; + if (maximum.x < rightPos) + maximum.x = rightPos; + if (minimum.x > leftPos) + minimum.x = leftPos; + if (maximum.y < topPos) + maximum.y = topPos; + if (minimum.y > bottomPos) + minimum.y = bottomPos; } float tx1 = float(c.x + c.xMargin); @@ -974,10 +994,12 @@ void Q3DSDistanceFieldRenderer::renderText(SText &text, const QT3DSMat44 &mvp) glyphInfo.fontScale * float(m_pixelRatio), textColor); } - m_renderedGlyphs += glyphHashValue; + if (!m_renderedGlyphs.contains(glyphHashValue)) + m_renderedGlyphs += glyphHashValue; } - m_renderedTexts += textHashValue; + if (!m_renderedTexts.contains(textHashValue)) + m_renderedTexts += textHashValue; text.m_Bounds = NVBounds3(minimum, maximum); } @@ -1001,9 +1023,20 @@ ITextRendererCore &ITextRendererCore::createDistanceFieldRenderer(NVFoundationBa void Q3DSDistanceFieldRenderer::checkAndAddRenderedTexts(SText &text) { - auto hashVal = getTextHashValue(text); - if (m_glyphCache.contains(hashVal)) - m_renderedTexts += hashVal; + auto textHashVal = getTextHashValue(text); + if (m_glyphCache.contains(textHashVal)) { + m_renderedTexts += textHashVal; + + QHash<Q3DSDistanceFieldGlyphCache::TextureInfo *, GlyphInfo> &glyphsPerTexture + = m_glyphCache[textHashVal]; + QHash<Q3DSDistanceFieldGlyphCache::TextureInfo *, GlyphInfo>::const_iterator it; + for (it = glyphsPerTexture.constBegin(); it != glyphsPerTexture.constEnd(); ++it) { + const GlyphInfo &glyphInfo = it.value(); + size_t glyphHashValue = getGlyphHashValue(glyphInfo); + if (m_meshCache.contains(glyphHashValue)) + m_renderedGlyphs += glyphHashValue; + } + } } // Unused methods: |