From 74fa1d12917de0270587c1f9ab9bbc6b7e9e4b7e Mon Sep 17 00:00:00 2001 From: HifiExperiments Date: Sun, 18 Aug 2024 20:35:57 -0700 Subject: [PATCH] text vertical alignment, use uint8_t for entity property enums, fix text recalculating too often --- cmake/macros/GenerateEntityProperties.cmake | 6 +- .../src/RenderableTextEntityItem.cpp | 3 +- .../src/RenderableTextEntityItem.h | 1 + .../entities/src/EntityItemProperties.cpp.in | 17 ++++++ .../entities/src/EntityItemProperties.h.in | 1 + .../entities/src/EntityItemProperties.txt | 1 + .../entities/src/EntityItemPropertiesDocs.cpp | 3 +- libraries/networking/src/udt/PacketHeaders.h | 1 + libraries/octree/src/OctreePacketData.h | 2 + libraries/render-utils/src/text/Font.cpp | 61 ++++++++++++++----- libraries/render-utils/src/text/Font.h | 16 +++-- .../shared/src/AmbientOcclusionTechnique.h | 2 +- libraries/shared/src/BillboardMode.h | 2 +- libraries/shared/src/EntityShape.h | 2 +- libraries/shared/src/GizmoType.h | 2 +- libraries/shared/src/MaterialMappingMode.h | 2 +- libraries/shared/src/MirrorMode.h | 2 +- libraries/shared/src/PrimitiveMode.h | 2 +- libraries/shared/src/PulseMode.h | 2 +- libraries/shared/src/RenderLayer.h | 2 +- libraries/shared/src/ShapeInfo.h | 2 +- libraries/shared/src/TextAlignment.h | 6 +- libraries/shared/src/TextEffect.h | 2 +- .../shared/src/TextVerticalAlignment.cpp | 25 ++++++++ libraries/shared/src/TextVerticalAlignment.h | 40 ++++++++++++ libraries/shared/src/TonemappingCurve.h | 2 +- libraries/shared/src/WebInputMode.h | 2 +- .../create/assets/data/createAppTooltips.json | 3 + .../html/js/entityProperties.js | 11 ++++ 29 files changed, 180 insertions(+), 43 deletions(-) create mode 100644 libraries/shared/src/TextVerticalAlignment.cpp create mode 100644 libraries/shared/src/TextVerticalAlignment.h diff --git a/cmake/macros/GenerateEntityProperties.cmake b/cmake/macros/GenerateEntityProperties.cmake index 11bc3ff0cb..b8980a9c25 100644 --- a/cmake/macros/GenerateEntityProperties.cmake +++ b/cmake/macros/GenerateEntityProperties.cmake @@ -277,7 +277,7 @@ macro(GENERATE_ENTITY_PROPERTIES) endif() if(NOT COMMON_PROPS) if(LINE MATCHES ".*enum( |,).*") - string(CONCAT ENTITY_ITEM_PROPERTY_APPEND "${ENTITY_ITEM_PROPERTY_APPEND}" "\t\t\tAPPEND_ENTITY_PROPERTY(${ENTITY_PROPERTY_ENUM}, (uint32_t)properties.get${ENTITY_PROPERTY_NAME_CAPS}());\n") + string(CONCAT ENTITY_ITEM_PROPERTY_APPEND "${ENTITY_ITEM_PROPERTY_APPEND}" "\t\t\tAPPEND_ENTITY_PROPERTY(${ENTITY_PROPERTY_ENUM}, (uint8_t)properties.get${ENTITY_PROPERTY_NAME_CAPS}());\n") elseif(ENTITY_PROPERTY_NETWORK_GETTER) string(CONCAT ENTITY_ITEM_PROPERTY_APPEND "${ENTITY_ITEM_PROPERTY_APPEND}" "\t\t\tAPPEND_ENTITY_PROPERTY(${ENTITY_PROPERTY_ENUM}, ${ENTITY_PROPERTY_NETWORK_GETTER});\n") else() @@ -286,7 +286,7 @@ macro(GENERATE_ENTITY_PROPERTIES) string(CONCAT ENTITY_ITEM_PROPERTY_READ "${ENTITY_ITEM_PROPERTY_READ}" "\tREAD_ENTITY_PROPERTY_TO_PROPERTIES(${ENTITY_PROPERTY_ENUM}, ${ENTITY_PROPERTY_READ_TYPE}, set${ENTITY_PROPERTY_NAME_CAPS});\n") string(CONCAT ${CURRENT_TYPE}_REQUESTED_PROPS "${${CURRENT_TYPE}_REQUESTED_PROPS}" "\trequestedProperties += ${ENTITY_PROPERTY_ENUM};\n") if(LINE MATCHES ".*enum( |,).*") - string(CONCAT ${CURRENT_TYPE}_ENTITY_APPEND "${${CURRENT_TYPE}_ENTITY_APPEND}" "\tAPPEND_ENTITY_PROPERTY(${ENTITY_PROPERTY_ENUM}, (uint32_t)get${ENTITY_PROPERTY_NAME_CAPS}());\n") + string(CONCAT ${CURRENT_TYPE}_ENTITY_APPEND "${${CURRENT_TYPE}_ENTITY_APPEND}" "\tAPPEND_ENTITY_PROPERTY(${ENTITY_PROPERTY_ENUM}, (uint8_t)get${ENTITY_PROPERTY_NAME_CAPS}());\n") elseif(ENTITY_VARIABLE_NETWORK_GETTER) string(CONCAT ${CURRENT_TYPE}_ENTITY_APPEND "${${CURRENT_TYPE}_ENTITY_APPEND}" "\tAPPEND_ENTITY_PROPERTY(${ENTITY_PROPERTY_ENUM}, ${ENTITY_VARIABLE_NETWORK_GETTER});\n") else() @@ -492,7 +492,7 @@ macro(GENERATE_ENTITY_PROPERTIES) string(CONCAT ${CURRENT_TYPE_CAPS}_GROUP_LIST_CHANGED "${${CURRENT_TYPE_CAPS}_GROUP_LIST_CHANGED}" "\tif (${GROUP_PROPERTY_NAME}Changed()) {\n\t\tout += \"${GROUP_PROPERTY_NAME}\";\n\t}\n") string(CONCAT ${CURRENT_TYPE_CAPS}_REQUESTED_PROPS "${${CURRENT_TYPE_CAPS}_REQUESTED_PROPS}" "\trequestedProperties += ${GROUP_PROPERTY_ENUM};\n") if(LINE MATCHES ".*enum( |,).*") - string(CONCAT ${CURRENT_TYPE_CAPS}_GROUP_APPEND "${${CURRENT_TYPE_CAPS}_GROUP_APPEND}" "\tAPPEND_ENTITY_PROPERTY(${GROUP_PROPERTY_ENUM}, (uint32_t)get${GROUP_PROPERTY_NAME_CAPS}());\n") + string(CONCAT ${CURRENT_TYPE_CAPS}_GROUP_APPEND "${${CURRENT_TYPE_CAPS}_GROUP_APPEND}" "\tAPPEND_ENTITY_PROPERTY(${GROUP_PROPERTY_ENUM}, (uint8_t)get${GROUP_PROPERTY_NAME_CAPS}());\n") elseif(GROUP_VARIABLE_NETWORK_GETTER) string(CONCAT ${CURRENT_TYPE_CAPS}_GROUP_APPEND "${${CURRENT_TYPE_CAPS}_GROUP_APPEND}" "\tAPPEND_ENTITY_PROPERTY(${GROUP_PROPERTY_ENUM}, ${GROUP_VARIABLE_NETWORK_GETTER});\n") else() diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp index 1cfab07986..e7167b8c78 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.cpp +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.cpp @@ -77,6 +77,7 @@ void TextEntityRenderer::doRenderUpdateAsynchronousTyped(const TypedEntityPointe _effectColor = toGlm(entity->getTextEffectColor()); _effectThickness = entity->getTextEffectThickness(); _alignment = entity->getAlignment(); + _verticalAlignment = entity->getVerticalAlignment(); bool materialChanged = false; glm::vec3 color = toGlm(entity->getBackgroundColor()); @@ -381,7 +382,7 @@ void entities::TextPayload::render(RenderArgs* args) { glm::vec2 bounds = glm::vec2(dimensions.x - (textRenderable->_leftMargin + textRenderable->_rightMargin), dimensions.y - (textRenderable->_topMargin + textRenderable->_bottomMargin)); textRenderer->draw(batch, textRenderable->_font, { textRenderable->_text, textColor, effectColor, { textRenderable->_leftMargin / scale, -textRenderable->_topMargin / scale }, - bounds / scale, scale, textRenderable->_effectThickness, textRenderable->_effect, textRenderable->_alignment, textRenderable->_unlit, forward, mirror }); + bounds / scale, scale, textRenderable->_effectThickness, textRenderable->_effect, textRenderable->_alignment, textRenderable->_verticalAlignment, textRenderable->_unlit, forward, mirror }); } namespace render { diff --git a/libraries/entities-renderer/src/RenderableTextEntityItem.h b/libraries/entities-renderer/src/RenderableTextEntityItem.h index f48bb8085f..782b4d4f34 100644 --- a/libraries/entities-renderer/src/RenderableTextEntityItem.h +++ b/libraries/entities-renderer/src/RenderableTextEntityItem.h @@ -74,6 +74,7 @@ private: QString _font { "" }; TextAlignment _alignment { TextAlignment::LEFT }; + TextVerticalAlignment _verticalAlignment { TextVerticalAlignment::TOP }; TextEffect _effect { TextEffect::NO_EFFECT }; glm::vec3 _effectColor { 0 }; float _effectThickness { 0.0f }; diff --git a/libraries/entities/src/EntityItemProperties.cpp.in b/libraries/entities/src/EntityItemProperties.cpp.in index bc8804c396..31272b954f 100644 --- a/libraries/entities/src/EntityItemProperties.cpp.in +++ b/libraries/entities/src/EntityItemProperties.cpp.in @@ -376,6 +376,23 @@ void EntityItemProperties::setAlignmentFromString(const QString& alignment) { } } +inline void addTextVerticalAlignment(QHash& lookup, TextVerticalAlignment verticalAlignment) { lookup[TextVerticalAlignmentHelpers::getNameForTextVerticalAlignment(verticalAlignment)] = verticalAlignment; } +const QHash stringToTextVerticalAlignmentLookup = [] { + QHash toReturn; + addTextVerticalAlignment(toReturn, TextVerticalAlignment::TOP); + addTextVerticalAlignment(toReturn, TextVerticalAlignment::BOTTOM); + addTextVerticalAlignment(toReturn, TextVerticalAlignment::CENTER); + return toReturn; +}(); +QString EntityItemProperties::getVerticalAlignmentAsString() const { return TextVerticalAlignmentHelpers::getNameForTextVerticalAlignment(_verticalAlignment); } +void EntityItemProperties::setVerticalAlignmentFromString(const QString& verticalAlignment) { + auto textVerticalAlignmentItr = stringToTextVerticalAlignmentLookup.find(verticalAlignment.toLower()); + if (textVerticalAlignmentItr != stringToTextVerticalAlignmentLookup.end()) { + _verticalAlignment = textVerticalAlignmentItr.value(); + _verticalAlignmentChanged = true; + } +} + QString getCollisionGroupAsString(uint16_t group) { switch (group) { case USER_COLLISION_GROUP_DYNAMIC: diff --git a/libraries/entities/src/EntityItemProperties.h.in b/libraries/entities/src/EntityItemProperties.h.in index 9c904837df..6565d650c9 100644 --- a/libraries/entities/src/EntityItemProperties.h.in +++ b/libraries/entities/src/EntityItemProperties.h.in @@ -55,6 +55,7 @@ #include "GizmoType.h" #include "TextEffect.h" #include "TextAlignment.h" +#include "TextVerticalAlignment.h" #include "MirrorMode.h" #include "EntityShape.h" diff --git a/libraries/entities/src/EntityItemProperties.txt b/libraries/entities/src/EntityItemProperties.txt index c4c9d5f0a3..e03142afdd 100644 --- a/libraries/entities/src/EntityItemProperties.txt +++ b/libraries/entities/src/EntityItemProperties.txt @@ -161,6 +161,7 @@ enum:TEXT_EFFECT prop:textEffect type:TextEffect default:TextEffect::NO_EFFECT e enum:TEXT_EFFECT_COLOR prop:textEffectColor type:u8vec3Color default:TextEntityItem::DEFAULT_TEXT_COLOR renderProp, enum:TEXT_EFFECT_THICKNESS prop:textEffectThickness type:float default:TextEntityItem::DEFAULT_TEXT_EFFECT_THICKNESS min:0.0f max:0.5f renderProp, enum:TEXT_ALIGNMENT prop:alignment type:TextAlignment default:TextAlignment::LEFT enum renderProp, +enum:TEXT_VERTICAL_ALIGNMENT prop:verticalAlignment type:TextVerticalAlignment default:TextVerticalAlignment::TOP enum renderProp, Zone enum:SHAPE_TYPE prop:shapeType type:ShapeType enum default:SHAPE_TYPE_NONE common noGetterSetterProp, enum:COMPOUND_SHAPE_URL prop:compoundShapeURL type:QString default:"" urlPermission common, diff --git a/libraries/entities/src/EntityItemPropertiesDocs.cpp b/libraries/entities/src/EntityItemPropertiesDocs.cpp index a321327aec..2e1c0013e3 100644 --- a/libraries/entities/src/EntityItemPropertiesDocs.cpp +++ b/libraries/entities/src/EntityItemPropertiesDocs.cpp @@ -779,7 +779,8 @@ * @property {Entities.TextEffect} textEffect="none" - The effect that is applied to the text. * @property {Color} textEffectColor=255,255,255 - The color of the effect. * @property {number} textEffectThickness=0.2 - The magnitude of the text effect, range 0.00.5. - * @property {Entities.TextAlignment} alignment="left" - How the text is aligned against its background. + * @property {Entities.TextAlignment} alignment="left" - How the text is horizontally aligned against its background. + * @property {Entities.TextVerticalAlignment} verticalAlignment="top" - How the text is vertically aligned against its background. * @property {boolean} faceCamera - true if billboardMode is "yaw", false * if it isn't. Setting this property to false sets the billboardMode to "none". *

Deprecated: This property is deprecated and will be removed.

diff --git a/libraries/networking/src/udt/PacketHeaders.h b/libraries/networking/src/udt/PacketHeaders.h index ff3bfaaa9b..923913e896 100644 --- a/libraries/networking/src/udt/PacketHeaders.h +++ b/libraries/networking/src/udt/PacketHeaders.h @@ -361,6 +361,7 @@ enum class EntityVersion : PacketVersion { TonemappingAndAmbientOcclusion, ModelLoadPriority, PropertyCleanup, + TextVerticalAlignment, // Add new versions above here NUM_PACKET_TYPE, diff --git a/libraries/octree/src/OctreePacketData.h b/libraries/octree/src/OctreePacketData.h index eaffc4bdb4..cf4d259a4c 100644 --- a/libraries/octree/src/OctreePacketData.h +++ b/libraries/octree/src/OctreePacketData.h @@ -43,6 +43,7 @@ #include "GizmoType.h" #include "TextEffect.h" #include "TextAlignment.h" +#include "TextVerticalAlignment.h" #include "MirrorMode.h" #include "TonemappingCurve.h" #include "AmbientOcclusionTechnique.h" @@ -288,6 +289,7 @@ public: static int unpackDataFromBytes(const unsigned char* dataBytes, GizmoType& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, TextEffect& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, TextAlignment& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } + static int unpackDataFromBytes(const unsigned char* dataBytes, TextVerticalAlignment& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, MirrorMode& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, TonemappingCurve& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } static int unpackDataFromBytes(const unsigned char* dataBytes, AmbientOcclusionTechnique& result) { memcpy(&result, dataBytes, sizeof(result)); return sizeof(result); } diff --git a/libraries/render-utils/src/text/Font.cpp b/libraries/render-utils/src/text/Font.cpp index 3019b8f1c3..d8b5deed96 100644 --- a/libraries/render-utils/src/text/Font.cpp +++ b/libraries/render-utils/src/text/Font.cpp @@ -373,17 +373,22 @@ void Font::setupGPU() { } inline QuadBuilder adjustedQuadBuilderForAlignmentMode(const Glyph& glyph, glm::vec2 advance, float scale, float enlargeForShadows, - TextAlignment alignment, float rightSpacing) { + TextAlignment alignment, float rightSpacing, TextVerticalAlignment verticalAlignment, float bottomSpacing) { if (alignment == TextAlignment::RIGHT) { advance.x += rightSpacing; } else if (alignment == TextAlignment::CENTER) { advance.x += 0.5f * rightSpacing; } + if (verticalAlignment == TextVerticalAlignment::BOTTOM) { + advance.y += bottomSpacing; + } else if (verticalAlignment == TextVerticalAlignment::CENTER) { + advance.y += 0.5f * bottomSpacing; + } return QuadBuilder(glyph, advance, scale, enlargeForShadows); } void Font::buildVertices(Font::DrawInfo& drawInfo, const QString& str, const glm::vec2& origin, const glm::vec2& bounds, float scale, bool enlargeForShadows, - TextAlignment alignment) { + TextAlignment alignment, TextVerticalAlignment verticalAlignment) { drawInfo.verticesBuffer = std::make_shared(); drawInfo.indicesBuffer = std::make_shared(); drawInfo.indexCount = 0; @@ -394,6 +399,7 @@ void Font::buildVertices(Font::DrawInfo& drawInfo, const QString& str, const glm drawInfo.origin = origin; float rightEdge = origin.x + bounds.x; + float bottomEdge = origin.y - bounds.y; // Top left of text bool firstTokenOfLine = true; @@ -403,7 +409,7 @@ void Font::buildVertices(Font::DrawInfo& drawInfo, const QString& str, const glm for (int i = 0; i < tokens.length(); i++) { const QString& token = tokens[i]; - if ((bounds.y != -1) && (advance.y < origin.y - bounds.y)) { + if ((bounds.y != -1) && (advance.y < bottomEdge)) { // We are out of the y bound, stop drawing break; } @@ -459,25 +465,47 @@ void Font::buildVertices(Font::DrawInfo& drawInfo, const QString& str, const glm std::vector quadBuilders; quadBuilders.reserve(glyphsAndCorners.size()); { + float bottomSpacing = -FLT_MAX; + bool foundBottomSpacing = false; + if (verticalAlignment != TextVerticalAlignment::TOP) { + int i = (int)glyphsAndCorners.size() - 1; + while (!foundBottomSpacing && i >= 0) { + auto* nextGlyphAndCorner = &glyphsAndCorners[i]; + bottomSpacing = std::max(bottomSpacing, bottomEdge - (nextGlyphAndCorner->second.y + (nextGlyphAndCorner->first.offset.y - nextGlyphAndCorner->first.size.y))); + i--; + while (i >= 0) { + 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 can stop + if (prevGlyphAndCorner.second.x >= nextGlyphAndCorner->second.x) { + foundBottomSpacing = true; + break; + } + nextGlyphAndCorner = &prevGlyphAndCorner; + bottomSpacing = std::max(bottomSpacing, bottomEdge - (nextGlyphAndCorner->second.y + (nextGlyphAndCorner->first.offset.y - nextGlyphAndCorner->first.size.y))); + i--; + } + } + } + int i = (int)glyphsAndCorners.size() - 1; while (i >= 0) { - auto nextGlyphAndCorner = glyphsAndCorners[i]; - float rightSpacing = rightEdge - (nextGlyphAndCorner.second.x + nextGlyphAndCorner.first.d); - quadBuilders.push_back(adjustedQuadBuilderForAlignmentMode(nextGlyphAndCorner.first, nextGlyphAndCorner.second, scale, enlargeForShadows, - alignment, rightSpacing)); + auto* nextGlyphAndCorner = &glyphsAndCorners[i]; + float rightSpacing = rightEdge - (nextGlyphAndCorner->second.x + nextGlyphAndCorner->first.d); + quadBuilders.push_back(adjustedQuadBuilderForAlignmentMode(nextGlyphAndCorner->first, nextGlyphAndCorner->second, scale, enlargeForShadows, + alignment, rightSpacing, verticalAlignment, bottomSpacing)); i--; while (i >= 0) { - const auto& prevGlyphAndCorner = glyphsAndCorners[i]; + 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) { + if (prevGlyphAndCorner.second.x >= nextGlyphAndCorner->second.x) { break; } quadBuilders.push_back(adjustedQuadBuilderForAlignmentMode(prevGlyphAndCorner.first, prevGlyphAndCorner.second, scale, enlargeForShadows, - alignment, rightSpacing)); + alignment, rightSpacing, verticalAlignment, bottomSpacing)); - nextGlyphAndCorner = prevGlyphAndCorner; + nextGlyphAndCorner = &prevGlyphAndCorner; i--; } } @@ -529,12 +557,13 @@ void Font::drawString(gpu::Batch& batch, Font::DrawInfo& drawInfo, const DrawPro const bool boundsChanged = props.bounds != drawInfo.bounds || props.origin != drawInfo.origin; // If we're switching to or from shadow effect mode, we need to rebuild the vertices - if (props.str != drawInfo.string || boundsChanged || props.alignment != _alignment || + if (props.str != drawInfo.string || boundsChanged || props.alignment != drawInfo.alignment || props.verticalAlignment != drawInfo.verticalAlignment || (drawInfo.params.effect != textEffect && (textEffect == SHADOW_EFFECT || drawInfo.params.effect == SHADOW_EFFECT)) || - (textEffect == SHADOW_EFFECT && props.scale != _scale)) { - _scale = props.scale; - _alignment = props.alignment; - buildVertices(drawInfo, props.str, props.origin, props.bounds, props.scale, textEffect == SHADOW_EFFECT, props.alignment); + (textEffect == SHADOW_EFFECT && props.scale != drawInfo.scale)) { + drawInfo.scale = props.scale; + drawInfo.alignment = props.alignment; + drawInfo.verticalAlignment = props.verticalAlignment; + buildVertices(drawInfo, props.str, props.origin, props.bounds, props.scale, textEffect == SHADOW_EFFECT, drawInfo.alignment, drawInfo.verticalAlignment); } setupGPU(); diff --git a/libraries/render-utils/src/text/Font.h b/libraries/render-utils/src/text/Font.h index c9d96bc6f6..d9e2570e7e 100644 --- a/libraries/render-utils/src/text/Font.h +++ b/libraries/render-utils/src/text/Font.h @@ -15,6 +15,7 @@ #include "Glyph.h" #include "TextEffect.h" #include "TextAlignment.h" +#include "TextVerticalAlignment.h" #include #include @@ -55,6 +56,10 @@ public: glm::vec2 origin; glm::vec2 bounds; DrawParams params; + + float scale { 0.0f }; + TextAlignment alignment { TextAlignment::LEFT }; + TextVerticalAlignment verticalAlignment { TextVerticalAlignment::TOP }; }; glm::vec2 computeExtent(const QString& str) const; @@ -62,9 +67,10 @@ public: struct DrawProps { DrawProps(const QString& str, const glm::vec4& color, const glm::vec3& effectColor, const glm::vec2& origin, const glm::vec2& bounds, - float scale, float effectThickness, TextEffect effect, TextAlignment alignment, bool unlit, bool forward, bool mirror) : + float scale, float effectThickness, TextEffect effect, TextAlignment alignment, TextVerticalAlignment verticalAlignment, bool unlit, + bool forward, bool mirror) : str(str), color(color), effectColor(effectColor), origin(origin), bounds(bounds), scale(scale), effectThickness(effectThickness), - effect(effect), alignment(alignment), unlit(unlit), forward(forward), mirror(mirror) {} + effect(effect), alignment(alignment), verticalAlignment(verticalAlignment), unlit(unlit), forward(forward), mirror(mirror) {} DrawProps(const QString& str, const glm::vec4& color, const glm::vec2& origin, const glm::vec2& bounds, bool forward) : str(str), color(color), origin(origin), bounds(bounds), forward(forward) {} @@ -77,6 +83,7 @@ public: float effectThickness { 0.0f }; TextEffect effect { TextEffect::NO_EFFECT }; TextAlignment alignment { TextAlignment::LEFT }; + TextVerticalAlignment verticalAlignment { TextVerticalAlignment::TOP }; bool unlit = true; bool forward; bool mirror = false; @@ -100,7 +107,7 @@ private: const Glyph& getGlyph(const QChar& c) const; void buildVertices(DrawInfo& drawInfo, const QString& str, const glm::vec2& origin, const glm::vec2& bounds, float scale, bool enlargeForShadows, - TextAlignment alignment); + TextAlignment alignment, TextVerticalAlignment verticalAlignment); void setupGPU(); @@ -118,9 +125,6 @@ private: float _leading { 0.0f }; float _spaceWidth { 0.0f }; - float _scale { 0.0f }; - TextAlignment _alignment { TextAlignment::LEFT }; - bool _loaded { false }; bool _needsParamsUpdate { false }; diff --git a/libraries/shared/src/AmbientOcclusionTechnique.h b/libraries/shared/src/AmbientOcclusionTechnique.h index 15ce034606..3295149e4d 100644 --- a/libraries/shared/src/AmbientOcclusionTechnique.h +++ b/libraries/shared/src/AmbientOcclusionTechnique.h @@ -25,7 +25,7 @@ * @typedef {string} AmbientOcclusionTechnique */ -enum class AmbientOcclusionTechnique { +enum class AmbientOcclusionTechnique : uint8_t { SSAO = 0, HBAO, }; diff --git a/libraries/shared/src/BillboardMode.h b/libraries/shared/src/BillboardMode.h index dd377cab31..7c7ab981fb 100644 --- a/libraries/shared/src/BillboardMode.h +++ b/libraries/shared/src/BillboardMode.h @@ -33,7 +33,7 @@ * @typedef {string} BillboardMode */ -enum class BillboardMode { +enum class BillboardMode : uint8_t { NONE = 0, YAW, FULL diff --git a/libraries/shared/src/EntityShape.h b/libraries/shared/src/EntityShape.h index 8c1500d4cb..baa3eb7738 100644 --- a/libraries/shared/src/EntityShape.h +++ b/libraries/shared/src/EntityShape.h @@ -37,7 +37,7 @@ * * @typedef {string} Entities.Shape */ -enum class EntityShape { +enum class EntityShape : uint8_t { Triangle, Quad, Hexagon, diff --git a/libraries/shared/src/GizmoType.h b/libraries/shared/src/GizmoType.h index ca091e63fe..edee96698a 100644 --- a/libraries/shared/src/GizmoType.h +++ b/libraries/shared/src/GizmoType.h @@ -24,7 +24,7 @@ * @typedef {string} Entities.GizmoType */ -enum GizmoType { +enum GizmoType : uint8_t { RING = 0, // put new gizmo-types before this line. UNSET_GIZMO_TYPE diff --git a/libraries/shared/src/MaterialMappingMode.h b/libraries/shared/src/MaterialMappingMode.h index d95fbb339e..d48739562a 100644 --- a/libraries/shared/src/MaterialMappingMode.h +++ b/libraries/shared/src/MaterialMappingMode.h @@ -11,7 +11,7 @@ #include "QString" -enum MaterialMappingMode { +enum MaterialMappingMode : uint8_t { UV = 0, PROJECTED, // put new mapping-modes before this line. diff --git a/libraries/shared/src/MirrorMode.h b/libraries/shared/src/MirrorMode.h index e48e564df0..cfcef790f2 100644 --- a/libraries/shared/src/MirrorMode.h +++ b/libraries/shared/src/MirrorMode.h @@ -30,7 +30,7 @@ * @typedef {string} MirrorMode */ -enum class MirrorMode { +enum class MirrorMode : uint8_t { NONE = 0, MIRROR, PORTAL diff --git a/libraries/shared/src/PrimitiveMode.h b/libraries/shared/src/PrimitiveMode.h index 6dd65ec0c7..f52d21ca59 100644 --- a/libraries/shared/src/PrimitiveMode.h +++ b/libraries/shared/src/PrimitiveMode.h @@ -25,7 +25,7 @@ * @typedef {string} Entities.PrimitiveMode */ -enum class PrimitiveMode { +enum class PrimitiveMode : uint8_t { SOLID = 0, LINES }; diff --git a/libraries/shared/src/PulseMode.h b/libraries/shared/src/PulseMode.h index 8d4c24b4be..fb6bfc434f 100644 --- a/libraries/shared/src/PulseMode.h +++ b/libraries/shared/src/PulseMode.h @@ -26,7 +26,7 @@ * @typedef {string} Entities.PulseMode */ -enum class PulseMode { +enum class PulseMode : uint8_t { NONE = 0, IN_PHASE, OUT_PHASE diff --git a/libraries/shared/src/RenderLayer.h b/libraries/shared/src/RenderLayer.h index e0c249a001..d3fb97a256 100644 --- a/libraries/shared/src/RenderLayer.h +++ b/libraries/shared/src/RenderLayer.h @@ -26,7 +26,7 @@ * @typedef {string} Entities.RenderLayer */ -enum class RenderLayer { +enum class RenderLayer : uint8_t { WORLD = 0, FRONT, HUD diff --git a/libraries/shared/src/ShapeInfo.h b/libraries/shared/src/ShapeInfo.h index 6b0f981b24..7af28e8684 100644 --- a/libraries/shared/src/ShapeInfo.h +++ b/libraries/shared/src/ShapeInfo.h @@ -28,7 +28,7 @@ const int MAX_HULL_POINTS = 42; const int32_t END_OF_MESH_PART = -1; // bogus vertex index at end of mesh part const int32_t END_OF_MESH = -2; // bogus vertex index at end of mesh -enum ShapeType { +enum ShapeType : uint8_t { SHAPE_TYPE_NONE, SHAPE_TYPE_BOX, SHAPE_TYPE_SPHERE, diff --git a/libraries/shared/src/TextAlignment.h b/libraries/shared/src/TextAlignment.h index b82d8e8c57..643b501b31 100644 --- a/libraries/shared/src/TextAlignment.h +++ b/libraries/shared/src/TextAlignment.h @@ -12,21 +12,21 @@ #include "QString" /*@jsdoc - *

A {@link Entities.EntityProperties-Text|Text} entity may use one of the following alignments:

+ *

A {@link Entities.EntityProperties-Text|Text} entity may use one of the following horizontal alignments:

* * * * * * - * + * * * *
ValueDescription
"left"Text is aligned to the left side.
"center"Text is centered.
"center"Text is centered horizontally.
"right"Text is aligned to the right side.
* @typedef {string} Entities.TextAlignment */ -enum class TextAlignment { +enum class TextAlignment : uint8_t { LEFT = 0, CENTER, RIGHT diff --git a/libraries/shared/src/TextEffect.h b/libraries/shared/src/TextEffect.h index 09affc1f4e..f0bbf22209 100644 --- a/libraries/shared/src/TextEffect.h +++ b/libraries/shared/src/TextEffect.h @@ -27,7 +27,7 @@ * @typedef {string} Entities.TextEffect */ -enum class TextEffect { +enum class TextEffect : uint8_t { NO_EFFECT = 0, OUTLINE_EFFECT, OUTLINE_WITH_FILL_EFFECT, diff --git a/libraries/shared/src/TextVerticalAlignment.cpp b/libraries/shared/src/TextVerticalAlignment.cpp new file mode 100644 index 0000000000..fa9381cba0 --- /dev/null +++ b/libraries/shared/src/TextVerticalAlignment.cpp @@ -0,0 +1,25 @@ +// +// Created by HifiExperiments on 2/9/21 +// Copyright 2021 Vircadia contributors. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#include "TextVerticalAlignment.h" + +const char* textVerticalAlignmentNames[] = { + "top", + "bottom", + "center" +}; + +static const size_t TEXT_VERTICAL_ALIGNMENT_NAMES = (sizeof(textVerticalAlignmentNames) / sizeof(textVerticalAlignmentNames[0])); + +QString TextVerticalAlignmentHelpers::getNameForTextVerticalAlignment(TextVerticalAlignment verticalAlignment) { + if (((int)verticalAlignment <= 0) || ((int)verticalAlignment >= (int)TEXT_VERTICAL_ALIGNMENT_NAMES)) { + verticalAlignment = (TextVerticalAlignment)0; + } + + return textVerticalAlignmentNames[(int)verticalAlignment]; +} \ No newline at end of file diff --git a/libraries/shared/src/TextVerticalAlignment.h b/libraries/shared/src/TextVerticalAlignment.h new file mode 100644 index 0000000000..67dc5162b4 --- /dev/null +++ b/libraries/shared/src/TextVerticalAlignment.h @@ -0,0 +1,40 @@ +// +// Created by HifiExperiments on 8/17/24 +// Copyright 2021 Vircadia contributors. +// +// Distributed under the Apache License, Version 2.0. +// See the accompanying file LICENSE or http://www.apache.org/licenses/LICENSE-2.0.html +// + +#ifndef hifi_TextVerticalAlignment_h +#define hifi_TextVerticalAlignment_h + +#include "QString" + +/*@jsdoc + *

A {@link Entities.EntityProperties-Text|Text} entity may use one of the following vertical alignments:

+ * + * + * + * + * + * + * + * + * + *
ValueDescription
"top"Text is aligned to the top.
"bottom"Text is aligned to the bottom.
"center"Text is centered vertically.
+ * @typedef {string} Entities.TextVerticalAlignment + */ + +enum class TextVerticalAlignment { + TOP = 0, + BOTTOM, + CENTER, +}; + +class TextVerticalAlignmentHelpers { +public: + static QString getNameForTextVerticalAlignment(TextVerticalAlignment alignment); +}; + +#endif // hifi_TextVerticalAlignment_h \ No newline at end of file diff --git a/libraries/shared/src/TonemappingCurve.h b/libraries/shared/src/TonemappingCurve.h index f13cb3d437..f5f4d3fbb5 100644 --- a/libraries/shared/src/TonemappingCurve.h +++ b/libraries/shared/src/TonemappingCurve.h @@ -27,7 +27,7 @@ * @typedef {string} TonemappingCurve */ -enum class TonemappingCurve { +enum class TonemappingCurve : uint8_t { RGB = 0, SRGB, REINHARD, diff --git a/libraries/shared/src/WebInputMode.h b/libraries/shared/src/WebInputMode.h index a65ae1341c..e1bd7b7984 100644 --- a/libraries/shared/src/WebInputMode.h +++ b/libraries/shared/src/WebInputMode.h @@ -25,7 +25,7 @@ * @typedef {string} WebInputMode */ -enum class WebInputMode { +enum class WebInputMode : uint8_t { TOUCH = 0, MOUSE, }; diff --git a/scripts/system/create/assets/data/createAppTooltips.json b/scripts/system/create/assets/data/createAppTooltips.json index a6feb44b99..fcbad7b320 100644 --- a/scripts/system/create/assets/data/createAppTooltips.json +++ b/scripts/system/create/assets/data/createAppTooltips.json @@ -45,6 +45,9 @@ "textAlignment": { "tooltip": "How the text is aligned within its left and right bounds." }, + "textVerticalAlignment": { + "tooltip": "How the text is aligned within its top and bottom bounds." + }, "topMargin": { "tooltip": "The top margin, in meters." }, diff --git a/scripts/system/create/entityProperties/html/js/entityProperties.js b/scripts/system/create/entityProperties/html/js/entityProperties.js index dd97620eea..20f34ba8b8 100644 --- a/scripts/system/create/entityProperties/html/js/entityProperties.js +++ b/scripts/system/create/entityProperties/html/js/entityProperties.js @@ -273,6 +273,17 @@ const GROUPS = [ propertyID: "textAlignment", propertyName: "alignment", // actual entity property name }, + { + label: "Vertical Alignment", + type: "dropdown", + options: { + top: "Top", + center: "Center", + bottom: "Bottom" + }, + propertyID: "textVerticalAlignment", + propertyName: "verticalAlignment", // actual entity property name + }, { label: "Top Margin", type: "number-draggable",