diff --git a/libraries/render-utils/src/sdf_text3D.slf b/libraries/render-utils/src/sdf_text3D.slf index c5bed1ecab..ccc9091100 100644 --- a/libraries/render-utils/src/sdf_text3D.slf +++ b/libraries/render-utils/src/sdf_text3D.slf @@ -32,6 +32,7 @@ <@include sdf_text3D.slh@> <$declareEvalSDFSuperSampled()$> +layout(location=RENDER_UTILS_ATTR_POSITION_MS) in vec2 _positionMS; <@if HIFI_USE_TRANSLUCENT or HIFI_USE_FORWARD@> layout(location=RENDER_UTILS_ATTR_POSITION_ES) in vec4 _positionES; <@endif@> @@ -44,6 +45,11 @@ layout(location=RENDER_UTILS_ATTR_FADE1) flat in vec4 _glyphBounds; // we're reu void main() { vec4 color = evalSDFSuperSampled(_texCoord0, _glyphBounds); + vec2 absPos = abs(_positionMS); + if (max(absPos.x, absPos.y) >= 1.0 || _positionMS.x <= 0.0) { + color.a = 0.0; + } + <@if HIFI_USE_TRANSLUCENT or HIFI_USE_FORWARD@> color.a *= params.color.a; if (color.a <= 0.0) { diff --git a/libraries/render-utils/src/sdf_text3D.slv b/libraries/render-utils/src/sdf_text3D.slv index 9ac3b871f9..d88ee78f89 100644 --- a/libraries/render-utils/src/sdf_text3D.slv +++ b/libraries/render-utils/src/sdf_text3D.slv @@ -19,6 +19,7 @@ <@include sdf_text3D.slh@> +layout(location=RENDER_UTILS_ATTR_POSITION_MS) out vec2 _positionMS; <@if HIFI_USE_TRANSLUCENT or HIFI_USE_FORWARD@> layout(location=RENDER_UTILS_ATTR_POSITION_ES) out vec4 _positionES; <@endif@> @@ -47,6 +48,9 @@ void main() { <$transformModelToClipPos(cam, obj, position, gl_Position)$> <@endif@> + // Our position has scale baked in, but we need the normalized values in the fragment shader + _positionMS = inPosition.xy * vec2(length(obj._model[0]), length(obj._model[1])); + const vec3 normal = vec3(0, 0, 1); <$transformModelToWorldDir(cam, obj, normal, _normalWS)$> } \ No newline at end of file diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index 81cdaa51c9..2d24fa9a91 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -338,9 +338,18 @@ void Font::buildVertices(Font::DrawInfo& drawInfo, const QString& str, const glm float rightEdge = origin.x + enlargedBoundsX; // Top left of text + bool firstTokenOfLine = true; glm::vec2 advance = origin; std::vector> glyphsAndCorners; - foreach(const QString& token, tokenizeForWrapping(str)) { + const QStringList tokens = tokenizeForWrapping(str); + for (size_t i = 0; i < tokens.length(); i++) { + const QString& token = tokens[i]; + + if ((bounds.y != -1) && (advance.y < origin.y - bounds.y)) { + // We are out of the y bound, stop drawing + break; + } + bool isNewLine = (token == QString('\n')); bool forceNewLine = false; @@ -349,36 +358,43 @@ void Font::buildVertices(Font::DrawInfo& drawInfo, const QString& str, const glm // We are out of the x bound, force new line forceNewLine = true; } - if (isNewLine || forceNewLine) { + + if (isNewLine || (forceNewLine && !firstTokenOfLine)) { + if (forceNewLine && !firstTokenOfLine) { + // We want to try this token again on the new line + i--; + } + // Character return, move the advance to a new line advance = glm::vec2(origin.x, advance.y - _leading); - - if (isNewLine) { - // No need to draw anything, go directly to next token - continue; - } else if (computeExtent(token).x > enlargedBoundsX) { - // token will never fit, stop drawing - break; - } - } - if ((bounds.y != -1) && (advance.y - _fontSize < origin.y - bounds.y)) { - // We are out of the y bound, stop drawing - break; + firstTokenOfLine = true; + // No need to draw anything, go directly to next token + continue; } // Draw the token - if (!isNewLine) { - for (auto c : token) { - auto glyph = _glyphs[c]; - - glyphsAndCorners.emplace_back(glyph, advance - glm::vec2(0.0f, _ascent)); - - // Advance by glyph size - advance.x += glyph.d; + for (const QChar& c : token) { + if (advance.x > rightEdge) { + break; } + const Glyph& glyph = _glyphs[c]; + glyphsAndCorners.emplace_back(glyph, advance - glm::vec2(0.0f, _ascent)); + + // Advance by glyph size + advance.x += glyph.d; + } + + if (forceNewLine && firstTokenOfLine) { + // If the first word of a line didn't fit, we draw as many characters as we could, now go to the next line + // Character return, move the advance to a new line + advance = glm::vec2(origin.x, advance.y - _leading); + firstTokenOfLine = true; + } else { // Add space after all non return tokens advance.x += _spaceWidth; + // Our token fits in the x direction! Any subsequent tokens won't be the first for this line. + firstTokenOfLine = false; } } @@ -393,7 +409,7 @@ void Font::buildVertices(Font::DrawInfo& drawInfo, const QString& str, const glm alignment, rightSpacing)); i--; while (i >= 0) { - auto prevGlyphAndCorner = glyphsAndCorners[i]; + const auto& prevGlyphAndCorner = glyphsAndCorners[i]; // We're to the right of the last character we checked, which means we're on a previous line, so we need to // recalculate the spacing, so we exit this loop if (prevGlyphAndCorner.second.x >= nextGlyphAndCorner.second.x) {