summaryrefslogtreecommitdiffstats
path: root/src/runtimerender/Qt3DSDistanceFieldRenderer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/runtimerender/Qt3DSDistanceFieldRenderer.cpp')
-rw-r--r--src/runtimerender/Qt3DSDistanceFieldRenderer.cpp127
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: