X-Git-Url: https://git.mxchange.org/?a=blobdiff_plain;f=simgear%2Fcanvas%2Felements%2FCanvasText.cxx;h=a00cc1fa703f6b362a687034b6255dd273025c2d;hb=1f431323635de0dd86d60a0fc58efa9557983ef8;hp=3e5d78531cf71c3bfff0124c032894cd8b3b756c;hpb=77946585b1c9b54c4848b604eb1549e2ec55df12;p=simgear.git diff --git a/simgear/canvas/elements/CanvasText.cxx b/simgear/canvas/elements/CanvasText.cxx index 3e5d7853..a00cc1fa 100644 --- a/simgear/canvas/elements/CanvasText.cxx +++ b/simgear/canvas/elements/CanvasText.cxx @@ -37,13 +37,15 @@ namespace canvas void setFill(const std::string& fill); void setBackgroundColor(const std::string& fill); - osg::Vec2 handleHit(float x, float y); + osg::Vec2 handleHit(const osg::Vec2f& pos); virtual osg::BoundingBox computeBound() const; protected: canvas::Text *_text_element; + + virtual void computePositions(unsigned int contextID) const; }; //---------------------------------------------------------------------------- @@ -79,13 +81,13 @@ namespace canvas } //---------------------------------------------------------------------------- - osg::Vec2 Text::TextOSG::handleHit(float x, float y) + osg::Vec2 Text::TextOSG::handleHit(const osg::Vec2f& pos) { float line_height = _characterHeight + _lineSpacing; // TODO check with align other than TOP float first_line_y = -0.5 * _lineSpacing;//_offset.y() - _characterHeight; - size_t line = std::max(0, (y - first_line_y) / line_height); + size_t line = std::max(0, (pos.y() - first_line_y) / line_height); if( _textureGlyphQuadMap.empty() ) return osg::Vec2(-1, -1); @@ -102,7 +104,7 @@ namespace canvas const float character_width = getCharacterHeight() * getCharacterAspectRatio(); - y = (line + 0.5) * line_height; + float y = (line + 0.5) * line_height; bool line_found = false; for(size_t i = 0; i < line_numbers.size(); ++i) @@ -132,20 +134,21 @@ namespace canvas + HIT_FRACTION * glyphs[i]->getHorizontalAdvance() * character_width; - if( x <= threshold ) + if( pos.x() <= threshold ) { + osg::Vec2 hit(0, y); if( i == 0 || line_numbers[i - 1] != line ) // first character of line - x = coords[i * 4].x(); + hit.x() = coords[i * 4].x(); else if( coords[(i - 1) * 4].x() == coords[(i - 1) * 4 + 2].x() ) // If previous character width is zero set to begin of next character // (Happens eg. with spaces) - x = coords[i * 4].x(); + hit.x() = coords[i * 4].x(); else // position at center between characters - x = 0.5 * (coords[(i - 1) * 4 + 2].x() + coords[i * 4].x()); + hit.x() = 0.5 * (coords[(i - 1) * 4 + 2].x() + coords[i * 4].x()); - return osg::Vec2(x, y); + return hit; } } @@ -174,6 +177,70 @@ namespace canvas return bb; } + //---------------------------------------------------------------------------- + void Text::TextOSG::computePositions(unsigned int contextID) const + { + if( _textureGlyphQuadMap.empty() || _layout == VERTICAL ) + return osgText::Text::computePositions(contextID); + + // TODO check when it can be larger + assert( _textureGlyphQuadMap.size() == 1 ); + + const GlyphQuads& quads = _textureGlyphQuadMap.begin()->second; + const GlyphQuads::Glyphs& glyphs = quads._glyphs; + const GlyphQuads::Coords2& coords = quads._coords; + const GlyphQuads::LineNumbers& line_numbers = quads._lineNumbers; + + float wr = _characterHeight / getCharacterAspectRatio(); + + size_t cur_line = static_cast(-1); + for(size_t i = 0; i < glyphs.size(); ++i) + { + // Check horizontal offsets + + bool first_char = cur_line != line_numbers[i]; + cur_line = line_numbers[i]; + + bool last_char = (i + 1 == glyphs.size()) + || (cur_line != line_numbers[i + 1]); + + if( first_char || last_char ) + { + // From osg/src/osgText/Text.cpp: + // + // osg::Vec2 upLeft = local+osg::Vec2(0.0f-fHorizQuadMargin, ...); + // osg::Vec2 lowLeft = local+osg::Vec2(0.0f-fHorizQuadMargin, ...); + // osg::Vec2 lowRight = local+osg::Vec2(width+fHorizQuadMargin, ...); + // osg::Vec2 upRight = local+osg::Vec2(width+fHorizQuadMargin, ...); + + float left = coords[i * 4].x(), + right = coords[i * 4 + 2].x(), + width = glyphs[i]->getWidth() * wr; + + // (local + width + fHoriz) - (local - fHoriz) = width + 2*fHoriz | -width + float margin = 0.5f * (right - left - width), + cursor_x = left + margin + - glyphs[i]->getHorizontalBearing().x() * wr; + + if( first_char ) + { + if( cur_line == 0 || cursor_x < _textBB._min.x() ) + _textBB._min.x() = cursor_x; + } + + if( last_char ) + { + float cursor_w = cursor_x + glyphs[i]->getHorizontalAdvance() * wr; + + if( cur_line == 0 || cursor_w > _textBB._max.x() ) + _textBB._max.x() = cursor_w; + } + } + } + + return osgText::Text::computePositions(contextID); + } + //---------------------------------------------------------------------------- Text::Text( const CanvasWeakPtr& canvas, const SGPropertyNode_ptr& node, @@ -187,22 +254,32 @@ namespace canvas _text->setAxisAlignment(osgText::Text::USER_DEFINED_ROTATION); _text->setRotation(osg::Quat(osg::PI, osg::X_AXIS)); - addStyle("fill", &TextOSG::setFill, _text); - addStyle("background", &TextOSG::setBackgroundColor, _text); - addStyle("character-size", - static_cast(&TextOSG::setCharacterSize), - _text); - addStyle("character-aspect-ratio", &TextOSG::setCharacterAspect, _text); - addStyle("padding", &TextOSG::setBoundingBoxMargin, _text); - // TEXT = 1 default - // BOUNDINGBOX = 2 - // FILLEDBOUNDINGBOX = 4 - // ALIGNMENT = 8 - addStyle("draw-mode", &TextOSG::setDrawMode, _text); - addStyle("max-width", &TextOSG::setMaximumWidth, _text); - addStyle("font", &Text::setFont, this); - addStyle("alignment", &Text::setAlignment, this); - addStyle("text", &Text::setText, this); + if( !isInit() ) + { + osg::ref_ptr Text::*text = &Text::_text; + + addStyle("fill", "color", &TextOSG::setFill, text); + addStyle("background", "color", &TextOSG::setBackgroundColor, text); + addStyle("character-size", + "numeric", + static_cast< + void (TextOSG::*)(float) + > (&TextOSG::setCharacterSize), + text); + addStyle("character-aspect-ratio", + "numeric", + &TextOSG::setCharacterAspect, text); + addStyle("padding", "numeric", &TextOSG::setBoundingBoxMargin, text); + // TEXT = 1 default + // BOUNDINGBOX = 2 + // FILLEDBOUNDINGBOX = 4 + // ALIGNMENT = 8 + addStyle("draw-mode", "", &TextOSG::setDrawMode, text); + addStyle("max-width", "numeric", &TextOSG::setMaximumWidth, text); + addStyle("font", "", &Text::setFont); + addStyle("alignment", "", &Text::setAlignment); + addStyle("text", "", &Text::setText); + } setupStyle(); } @@ -266,26 +343,9 @@ namespace canvas #endif //---------------------------------------------------------------------------- - void Text::childChanged(SGPropertyNode* child) - { - if( child->getParent() != _node ) - return; - - const std::string& name = child->getNameString(); - if( name == "hit-y" ) - handleHit - ( - _node->getFloatValue("hit-x"), - _node->getFloatValue("hit-y") - ); - } - - //---------------------------------------------------------------------------- - void Text::handleHit(float x, float y) + osg::Vec2 Text::getNearestCursor(const osg::Vec2& pos) const { - const osg::Vec2& pos = _text->handleHit(x, y); - _node->setFloatValue("cursor-x", pos.x()); - _node->setFloatValue("cursor-y", pos.y()); + return _text->handleHit(pos); } } // namespace canvas