summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJere Tuliniemi <jere.tuliniemi@qt.io>2019-04-12 14:24:32 +0300
committerFrederik Gladhorn <frederik.gladhorn@qt.io>2019-04-29 14:44:37 +0000
commite97f897eca6d48fa16d2402f17f3aea5f0816ece (patch)
tree7ca16f305e8396be43462a9fec78b56801d0f29b
parent1040c4cc4bee2cdca543ced6e4cd2a0504de8767 (diff)
Add clipping to distance field fonts
Removes fallback to the old text renderer and adds the clipping feature to the distance field font renderer. Task-number: QT3DS-3329 Change-Id: Ie41b93c9a9ed791297349007c7e2b3bf10c982b1 Reviewed-by: Mahmoud Badri <mahmoud.badri@qt.io> Reviewed-by: Tomi Korpipää <tomi.korpipaa@qt.io>
-rw-r--r--src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.cpp59
-rw-r--r--src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp67
2 files changed, 88 insertions, 38 deletions
diff --git a/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.cpp b/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.cpp
index 64e5a737..2562ea79 100644
--- a/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.cpp
+++ b/src/Runtime/Source/runtimerender/Qt3DSDistanceFieldRenderer.cpp
@@ -115,6 +115,9 @@ Q3DSDistanceFieldRenderer::buildGlyphsPerTexture(const SText &textInfo)
return QHash<Q3DSDistanceFieldGlyphCache::TextureInfo *, GlyphInfo>();
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;
+ bool hasValidBoundingBox = boundingBox.x() > 0 || boundingBox.y() > 0;
QRawFont font = m_fontDatabase.findFont(textInfo.m_Font.c_str());
font.setPixelSize(qreal(textInfo.m_FontSize));
@@ -391,6 +394,43 @@ Q3DSDistanceFieldRenderer::buildGlyphsPerTexture(const SText &textInfo)
cy2 += float(shadowOffsetY * fontScale);
}
+ float x1Clip = 1.0f;
+ float x2Clip = 1.0f;
+ float y1Clip = 1.0f;
+ float y2Clip = 1.0f;
+
+ if (hasValidBoundingBox) {
+ if ((cx1 < -halfWidth && cx2 < -halfWidth)
+ || (cx1 > halfWidth && cx2 > halfWidth)
+ || (cy1 < -halfHeight && cy2 < -halfHeight)
+ || (cy1 > halfHeight && cy2 > halfHeight)) {
+ continue;
+ }
+
+ float xDiff = qAbs(cx1 - cx2);
+ float yDiff = qAbs(cy1 - cy2);
+
+ if (cx1 < -halfWidth) {
+ x1Clip = 1.0f - qAbs(cx1 - (-halfWidth)) / xDiff;
+ cx1 = -halfWidth;
+ }
+
+ if (cx2 > halfWidth) {
+ x2Clip = 1.0f - qAbs(cx2 - halfWidth) / xDiff;
+ cx2 = halfWidth;
+ }
+
+ if (cy1 < -halfHeight) {
+ y1Clip = 1.0f - qAbs(cy1 - (-halfHeight)) / yDiff;
+ cy1 = -halfHeight;
+ }
+
+ if (cy2 > halfHeight) {
+ y2Clip = 1.0f - qAbs(cy2 - halfHeight) / yDiff;
+ cy2 = halfHeight;
+ }
+ }
+
cy1 = -cy1;
cy2 = -cy2;
@@ -414,9 +454,7 @@ Q3DSDistanceFieldRenderer::buildGlyphsPerTexture(const SText &textInfo)
else if (cy2 > maximum.y)
maximum.y = cy2;
- if (boundingBox.x() > 0 || boundingBox.y() > 0) {
- const float halfWidth = boundingBox.x() / 2.0f;
- const float halfHeight = boundingBox.y() / 2.0f;
+ if (hasValidBoundingBox) {
if (maximum.x < halfWidth)
maximum.x = halfWidth;
if (minimum.x > -halfWidth)
@@ -450,6 +488,21 @@ Q3DSDistanceFieldRenderer::buildGlyphsPerTexture(const SText &textInfo)
ty2 += float(c.height * shadowOffsetY * fontScale) / float(metrics.height);
}
+ if (hasValidBoundingBox) {
+ float tx1Orig = tx1;
+ float tx2Orig = tx2;
+ float ty1Orig = ty1;
+ float ty2Orig = ty2;
+
+ float xDiff = qAbs(tx1 - tx2);
+ tx1 = tx2Orig - xDiff * x1Clip;
+ tx2 = tx1Orig + xDiff * x2Clip;
+
+ float yDiff = qAbs(ty1 - ty2);
+ ty1 = ty2Orig - yDiff * y1Clip;
+ ty2 = ty1Orig + yDiff * y2Clip;
+ }
+
const QSGDistanceFieldGlyphCache::Texture *texture
= cache->glyphTexture(glyphIndex);
if (texture->textureId == 0) {
diff --git a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
index 2940f088..e1086304 100644
--- a/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
+++ b/src/Runtime/Source/runtimerender/rendererimpl/Qt3DSRendererImplLayerRenderPreparationData.cpp
@@ -383,44 +383,41 @@ namespace render {
inText.CalculateMVPAndNormalMatrix(inViewProjection, theMVP, theNormalMatrix);
SRenderableObject *theRenderable = nullptr;
+
#if QT_VERSION >= QT_VERSION_CHECK(5,12,2)
- // TODO: Implement clipping for the distance field renderer
- if (inText.m_WordWrap != TextWordWrap::Clip || (inText.m_BoundingBox.x == 0.0f
- && inText.m_BoundingBox.y == 0.0f)) {
- QT3DSMat44 modelView = (inProjection.getInverse() * inViewProjection)
- * inText.m_GlobalTransform;
- Q3DSDistanceFieldRenderer *distanceFieldText
- = static_cast<Q3DSDistanceFieldRenderer *>(
- m_Renderer.GetQt3DSContext().getDistanceFieldRenderer());
- theRenderable = RENDER_FRAME_NEW(SDistanceFieldRenderable)(
- theFlags, inText.GetGlobalPos(), inText, inText.m_Bounds, theMVP,
- modelView, *distanceFieldText);
- } else
+ QT3DSMat44 modelView = (inProjection.getInverse() * inViewProjection)
+ * inText.m_GlobalTransform;
+ Q3DSDistanceFieldRenderer *distanceFieldText
+ = static_cast<Q3DSDistanceFieldRenderer *>(
+ m_Renderer.GetQt3DSContext().getDistanceFieldRenderer());
+ theRenderable = RENDER_FRAME_NEW(SDistanceFieldRenderable)(
+ theFlags, inText.GetGlobalPos(), inText, inText.m_Bounds, theMVP,
+ modelView, *distanceFieldText);
+#else
+ TTPathObjectAndTexture theResult
+ = theTextRenderer->RenderText(inText, inTextScaleFactor);
+ inText.m_TextTexture = theResult.second.second.mPtr;
+ inText.m_TextTextureDetails = theResult.second.first;
+ inText.m_PathFontItem = theResult.first.second;
+ inText.m_PathFontDetails = theResult.first.first;
+ STextScaleAndOffset theScaleAndOffset(*inText.m_TextTexture,
+ inText.m_TextTextureDetails, inText);
+ QT3DSVec2 theTextScale(theScaleAndOffset.m_TextScale);
+ QT3DSVec2 theTextOffset(theScaleAndOffset.m_TextOffset);
+ QT3DSVec3 minimum(theTextOffset[0] - theTextScale[0],
+ theTextOffset[1] - theTextScale[1], 0);
+ QT3DSVec3 maximum(theTextOffset[0] + theTextScale[0],
+ theTextOffset[1] + theTextScale[1], 0);
+ inText.m_Bounds = NVBounds3(minimum, maximum);
+
+ if (inText.m_PathFontDetails)
+ ioFlags.SetRequiresStencilBuffer(true);
+
+ theRenderable = RENDER_FRAME_NEW(STextRenderable)(
+ theFlags, inText.GetGlobalPos(), m_Renderer, inText, inText.m_Bounds, theMVP,
+ inViewProjection, *inText.m_TextTexture, theTextOffset, theTextScale);
#endif
- {
- TTPathObjectAndTexture theResult
- = theTextRenderer->RenderText(inText, inTextScaleFactor);
- inText.m_TextTexture = theResult.second.second.mPtr;
- inText.m_TextTextureDetails = theResult.second.first;
- inText.m_PathFontItem = theResult.first.second;
- inText.m_PathFontDetails = theResult.first.first;
- STextScaleAndOffset theScaleAndOffset(*inText.m_TextTexture,
- inText.m_TextTextureDetails, inText);
- QT3DSVec2 theTextScale(theScaleAndOffset.m_TextScale);
- QT3DSVec2 theTextOffset(theScaleAndOffset.m_TextOffset);
- QT3DSVec3 minimum(theTextOffset[0] - theTextScale[0],
- theTextOffset[1] - theTextScale[1], 0);
- QT3DSVec3 maximum(theTextOffset[0] + theTextScale[0],
- theTextOffset[1] + theTextScale[1], 0);
- inText.m_Bounds = NVBounds3(minimum, maximum);
-
- if (inText.m_PathFontDetails)
- ioFlags.SetRequiresStencilBuffer(true);
- theRenderable = RENDER_FRAME_NEW(STextRenderable)(
- theFlags, inText.GetGlobalPos(), m_Renderer, inText, inText.m_Bounds, theMVP,
- inViewProjection, *inText.m_TextTexture, theTextOffset, theTextScale);
- }
m_TransparentObjects.push_back(theRenderable);
}
return retval;