From 136c3a2cce423a0dd7b90b5255da531a084626b2 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 9 Dec 2014 18:32:53 -0800 Subject: [PATCH 1/3] Replace 2D and 3D text overlay textWidth() method with textSize() --- interface/src/ui/overlays/Overlays.cpp | 8 ++++---- interface/src/ui/overlays/Overlays.h | 4 ++-- interface/src/ui/overlays/Text3DOverlay.cpp | 20 ++++++++++++++++---- interface/src/ui/overlays/Text3DOverlay.h | 2 +- interface/src/ui/overlays/TextOverlay.cpp | 16 ++++++++++++++-- interface/src/ui/overlays/TextOverlay.h | 2 +- libraries/shared/src/RegisteredMetaTypes.cpp | 12 ++++++++++++ libraries/shared/src/RegisteredMetaTypes.h | 4 ++++ 8 files changed, 54 insertions(+), 14 deletions(-) diff --git a/interface/src/ui/overlays/Overlays.cpp b/interface/src/ui/overlays/Overlays.cpp index 25e667e56c..ace4ecf353 100644 --- a/interface/src/ui/overlays/Overlays.cpp +++ b/interface/src/ui/overlays/Overlays.cpp @@ -432,19 +432,19 @@ bool Overlays::isLoaded(unsigned int id) { return thisOverlay->isLoaded(); } -float Overlays::textWidth(unsigned int id, const QString& text) const { +QSizeF Overlays::textSize(unsigned int id, const QString& text) const { Overlay* thisOverlay = _overlays2D[id]; if (thisOverlay) { if (typeid(*thisOverlay) == typeid(TextOverlay)) { - return static_cast(thisOverlay)->textWidth(text); + return static_cast(thisOverlay)->textSize(text); } } else { thisOverlay = _overlays3D[id]; if (thisOverlay) { if (typeid(*thisOverlay) == typeid(Text3DOverlay)) { - return static_cast(thisOverlay)->textWidth(text); + return static_cast(thisOverlay)->textSize(text); } } } - return 0.0f; + return QSizeF(0.0f, 0.0f); } diff --git a/interface/src/ui/overlays/Overlays.h b/interface/src/ui/overlays/Overlays.h index 7acc2c7878..fb2c936a64 100644 --- a/interface/src/ui/overlays/Overlays.h +++ b/interface/src/ui/overlays/Overlays.h @@ -85,9 +85,9 @@ public slots: /// returns whether the overlay's assets are loaded or not bool isLoaded(unsigned int id); - /// returns the width of the given text in the specified overlay if it is a text overlay: in pixels if it is a 2D text + /// returns the size of the given text in the specified overlay if it is a text overlay: in pixels if it is a 2D text /// overlay; in meters if it is a 3D text overlay - float textWidth(unsigned int id, const QString& text) const; + QSizeF textSize(unsigned int id, const QString& text) const; private: QMap _overlays2D; diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 2e80fae8a0..7db73dda8c 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -236,11 +236,23 @@ Text3DOverlay* Text3DOverlay::createClone() const { return new Text3DOverlay(this);; } -float Text3DOverlay::textWidth(const QString& text) const { +QSizeF Text3DOverlay::textSize(const QString& text) const { + QFont font(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); // Same font properties as render() QFontMetrics fontMetrics(font); - float scaleFactor = _lineHeight * LINE_SCALE_RATIO / (float)FIXED_FONT_POINT_SIZE; - return scaleFactor * (float)fontMetrics.width(qPrintable(text)); + const float TEXT_SCALE_ADJUST = 1.02f; // Experimentally detemined for the specified font + const int TEXT_HEIGHT_ADJUST = -6; + float scaleFactor = _lineHeight * TEXT_SCALE_ADJUST * LINE_SCALE_RATIO / (float)FIXED_FONT_POINT_SIZE; + + QStringList lines = text.split(QRegExp("\r\n|\r|\n")); + + float width = 0.0f; + for (int i = 0; i < lines.count(); i += 1) { + width = std::max(width, scaleFactor * (float)fontMetrics.width(qPrintable(lines[i]))); + } + + float height = lines.count() * scaleFactor * (float)(fontMetrics.height() + TEXT_HEIGHT_ADJUST); + + return QSizeF(width, height); } - diff --git a/interface/src/ui/overlays/Text3DOverlay.h b/interface/src/ui/overlays/Text3DOverlay.h index d74131391a..aefda852db 100644 --- a/interface/src/ui/overlays/Text3DOverlay.h +++ b/interface/src/ui/overlays/Text3DOverlay.h @@ -51,7 +51,7 @@ public: virtual void setProperties(const QScriptValue& properties); virtual QScriptValue getProperty(const QString& property); - float textWidth(const QString& text) const; // Meters + QSizeF textSize(const QString& test) const; // Meters virtual Text3DOverlay* createClone() const; diff --git a/interface/src/ui/overlays/TextOverlay.cpp b/interface/src/ui/overlays/TextOverlay.cpp index 272c9bc916..b603e1f3bf 100644 --- a/interface/src/ui/overlays/TextOverlay.cpp +++ b/interface/src/ui/overlays/TextOverlay.cpp @@ -169,8 +169,20 @@ QScriptValue TextOverlay::getProperty(const QString& property) { return Overlay2D::getProperty(property); } -float TextOverlay::textWidth(const QString& text) const { +QSizeF TextOverlay::textSize(const QString& text) const { + QFont font(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT); // Same font properties as render() QFontMetrics fontMetrics(font); - return fontMetrics.width(qPrintable(text)); + const int TEXT_HEIGHT_ADJUST = -2; // Experimentally determined for the specified font + + QStringList lines = text.split(QRegExp("\r\n|\r|\n")); + + int width = 0; + for (int i = 0; i < lines.count(); i += 1) { + width = std::max(width, fontMetrics.width(qPrintable(lines[i]))); + } + + int height = lines.count() * (fontMetrics.height() + TEXT_HEIGHT_ADJUST); + + return QSizeF(width, height); } diff --git a/interface/src/ui/overlays/TextOverlay.h b/interface/src/ui/overlays/TextOverlay.h index 754faea2bc..793d705d3c 100644 --- a/interface/src/ui/overlays/TextOverlay.h +++ b/interface/src/ui/overlays/TextOverlay.h @@ -59,7 +59,7 @@ public: virtual TextOverlay* createClone() const; virtual QScriptValue getProperty(const QString& property); - float textWidth(const QString& text) const; // Pixels + QSizeF textSize(const QString& test) const; // Pixels private: QString _text; diff --git a/libraries/shared/src/RegisteredMetaTypes.cpp b/libraries/shared/src/RegisteredMetaTypes.cpp index cc8db8783f..4099384aea 100644 --- a/libraries/shared/src/RegisteredMetaTypes.cpp +++ b/libraries/shared/src/RegisteredMetaTypes.cpp @@ -39,6 +39,7 @@ void registerMetaTypes(QScriptEngine* engine) { qScriptRegisterMetaType(engine, pickRayToScriptValue, pickRayFromScriptValue); qScriptRegisterMetaType(engine, collisionToScriptValue, collisionFromScriptValue); qScriptRegisterMetaType(engine, quuidToScriptValue, quuidFromScriptValue); + qScriptRegisterMetaType(engine, qSizeFToScriptValue, qSizeFFromScriptValue); } QScriptValue vec4toScriptValue(QScriptEngine* engine, const glm::vec4& vec4) { @@ -206,3 +207,14 @@ void quuidFromScriptValue(const QScriptValue& object, QUuid& uuid) { uuid = fromString; } +QScriptValue qSizeFToScriptValue(QScriptEngine* engine, const QSizeF& qSizeF) { + QScriptValue obj = engine->newObject(); + obj.setProperty("width", qSizeF.width()); + obj.setProperty("height", qSizeF.height()); + return obj; +} + +void qSizeFFromScriptValue(const QScriptValue& object, QSizeF& qSizeF) { + qSizeF.setWidth(object.property("width").toVariant().toFloat()); + qSizeF.setHeight(object.property("height").toVariant().toFloat()); +} diff --git a/libraries/shared/src/RegisteredMetaTypes.h b/libraries/shared/src/RegisteredMetaTypes.h index b9278c9f2d..ca4898b65c 100644 --- a/libraries/shared/src/RegisteredMetaTypes.h +++ b/libraries/shared/src/RegisteredMetaTypes.h @@ -81,4 +81,8 @@ void collisionFromScriptValue(const QScriptValue &object, Collision& collision); QScriptValue quuidToScriptValue(QScriptEngine* engine, const QUuid& uuid); void quuidFromScriptValue(const QScriptValue& object, QUuid& uuid); +//Q_DECLARE_METATYPE(QSizeF) // Don't need to to this becase it's arleady a meta type +QScriptValue qSizeFToScriptValue(QScriptEngine* engine, const QSizeF& qSizeF); +void qSizeFFromScriptValue(const QScriptValue& object, QSizeF& qSizeF); + #endif // hifi_RegisteredMetaTypes_h From 3ea3a497c64396bef3444a00fa2bca447797e964 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 9 Dec 2014 18:33:29 -0800 Subject: [PATCH 2/3] Update scripts to use new textSize() method --- examples/editModels.js | 4 ++-- examples/lobby.js | 2 +- examples/newEditEntities.js | 4 ++-- examples/virtualKeyboard.js | 10 +++++----- 4 files changed, 10 insertions(+), 10 deletions(-) diff --git a/examples/editModels.js b/examples/editModels.js index c961d55bed..e0ade3b6a3 100644 --- a/examples/editModels.js +++ b/examples/editModels.js @@ -1191,8 +1191,8 @@ var toolBar = (function () { visible: false }); - menuItemWidth = Math.max(Overlays.textWidth(loadURLMenuItem, "Model URL"), - Overlays.textWidth(loadFileMenuItem, "Model File")) + 20; + menuItemWidth = Math.max(Overlays.textSize(loadURLMenuItem, "Model URL").width, + Overlays.textSize(loadFileMenuItem, "Model File").width) + 20; Overlays.editOverlay(loadURLMenuItem, { width: menuItemWidth }); Overlays.editOverlay(loadFileMenuItem, { width: menuItemWidth }); diff --git a/examples/lobby.js b/examples/lobby.js index dd011d08a4..a1f161d8a5 100644 --- a/examples/lobby.js +++ b/examples/lobby.js @@ -331,7 +331,7 @@ function handleLookAt(pickRay) { } else { currentTestLine = allWords[currentTestWord]; } - var lineLength = Overlays.textWidth(descriptionText, currentTestLine); + var lineLength = Overlays.textSize(descriptionText, currentTestLine).width; if (lineLength < textWidth || wordsOnLine == 0) { wordsFormated++; currentTestWord++; diff --git a/examples/newEditEntities.js b/examples/newEditEntities.js index 43e304a76d..e9f42bf74c 100644 --- a/examples/newEditEntities.js +++ b/examples/newEditEntities.js @@ -159,8 +159,8 @@ var toolBar = (function () { visible: false }); - menuItemWidth = Math.max(Overlays.textWidth(loadURLMenuItem, "Model URL"), - Overlays.textWidth(loadFileMenuItem, "Model File")) + 20; + menuItemWidth = Math.max(Overlays.textSize(loadURLMenuItem, "Model URL").width, + Overlays.textSize(loadFileMenuItem, "Model File").width) + 20; Overlays.editOverlay(loadURLMenuItem, { width: menuItemWidth }); Overlays.editOverlay(loadFileMenuItem, { width: menuItemWidth }); diff --git a/examples/virtualKeyboard.js b/examples/virtualKeyboard.js index c89dc6fb04..ce793c6ea0 100644 --- a/examples/virtualKeyboard.js +++ b/examples/virtualKeyboard.js @@ -80,7 +80,7 @@ function updateTextOverlay() { var textLines = textText.split("\n"); var maxLineWidth = 0; for (textLine in textLines) { - var lineWidth = Overlays.textWidth(text, textLines[textLine]); + var lineWidth = Overlays.textSize(text, textLines[textLine]).width; if (lineWidth > maxLineWidth) { maxLineWidth = lineWidth; } @@ -92,7 +92,7 @@ function updateTextOverlay() { Overlays.editOverlay(text, {text: textText, font: {size: textFontSize}, topMargin: topMargin}); var maxLineWidth = 0; for (textLine in textLines) { - var lineWidth = Overlays.textWidth(text, textLines[textLine]); + var lineWidth = Overlays.textSize(text, textLines[textLine]).width; if (lineWidth > maxLineWidth) { maxLineWidth = lineWidth; } @@ -122,18 +122,18 @@ keyboard.onKeyRelease = function(event) { var textLines = textText.split("\n"); var maxLineWidth = 0; for (textLine in textLines) { - var lineWidth = Overlays.textWidth(textSizeMeasureOverlay, textLines[textLine]); + var lineWidth = Overlays.textSize(textSizeMeasureOverlay, textLines[textLine]).width; if (lineWidth > maxLineWidth) { maxLineWidth = lineWidth; } } var usernameLine = "--" + GlobalServices.myUsername; - var usernameWidth = Overlays.textWidth(textSizeMeasureOverlay, usernameLine); + var usernameWidth = Overlays.textSize(textSizeMeasureOverlay, usernameLine).width; if (maxLineWidth < usernameWidth) { maxLineWidth = usernameWidth; } else { var spaceableWidth = maxLineWidth - usernameWidth; - var spaceWidth = Overlays.textWidth(textSizeMeasureOverlay, " "); + var spaceWidth = Overlays.textSize(textSizeMeasureOverlay, " ").width; var numberOfSpaces = Math.floor(spaceableWidth / spaceWidth); for (var i = 0; i < numberOfSpaces; i++) { usernameLine = " " + usernameLine; From 8cf50b71eaa086e50c28a9606ddb2914c67b6694 Mon Sep 17 00:00:00 2001 From: David Rowe Date: Tue, 9 Dec 2014 19:18:37 -0800 Subject: [PATCH 3/3] Update some comments to reflect changes --- interface/src/entities/RenderableTextEntityItem.cpp | 2 +- interface/src/ui/overlays/Text3DOverlay.cpp | 2 +- interface/src/ui/overlays/TextOverlay.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/interface/src/entities/RenderableTextEntityItem.cpp b/interface/src/entities/RenderableTextEntityItem.cpp index f790f6fa35..4059ee5751 100644 --- a/interface/src/entities/RenderableTextEntityItem.cpp +++ b/interface/src/entities/RenderableTextEntityItem.cpp @@ -63,7 +63,7 @@ void RenderableTextEntityItem::render(RenderArgs* args) { const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 40.0f; // this is a ratio determined through experimentation - // Same font properties as textWidth() + // Same font properties as textSize() TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); float maxHeight = (float)textRenderer->calculateHeight("Xy") * LINE_SCALE_RATIO; diff --git a/interface/src/ui/overlays/Text3DOverlay.cpp b/interface/src/ui/overlays/Text3DOverlay.cpp index 7db73dda8c..41e36cb396 100644 --- a/interface/src/ui/overlays/Text3DOverlay.cpp +++ b/interface/src/ui/overlays/Text3DOverlay.cpp @@ -108,7 +108,7 @@ void Text3DOverlay::render(RenderArgs* args) { const int FIXED_FONT_SCALING_RATIO = FIXED_FONT_POINT_SIZE * 40.0f; // this is a ratio determined through experimentation - // Same font properties as textWidth() + // Same font properties as textSize() TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, FIXED_FONT_POINT_SIZE); float maxHeight = (float)textRenderer->calculateHeight("Xy") * LINE_SCALE_RATIO; diff --git a/interface/src/ui/overlays/TextOverlay.cpp b/interface/src/ui/overlays/TextOverlay.cpp index b603e1f3bf..ae8a7cbcfe 100644 --- a/interface/src/ui/overlays/TextOverlay.cpp +++ b/interface/src/ui/overlays/TextOverlay.cpp @@ -77,7 +77,7 @@ void TextOverlay::render(RenderArgs* args) { glVertex2f(_bounds.left(), _bounds.bottom()); glEnd(); - // Same font properties as textWidth() + // Same font properties as textSize() TextRenderer* textRenderer = TextRenderer::getInstance(SANS_FONT_FAMILY, _fontSize, DEFAULT_FONT_WEIGHT); const int leftAdjust = -1; // required to make text render relative to left edge of bounds