#include "Node.h" #include "Font.h" #include "pugixml/pugixml.hpp" #include "utils/stringUtils.h" #include "RenderState.h" #include "AnimationFrame.h" #include "res/ResFont.h" namespace oxygine { namespace text { Node::Node(): _firstChild(0), _lastChild(0), _nextSibling(0) { } Node::~Node() { Node* child = _firstChild; while (child) { Node* next = child->_nextSibling; delete child; child = next; } } void Node::appendNode(Node* tn) { if (!_firstChild) _firstChild = tn; else _lastChild->_nextSibling = tn; _lastChild = tn; } void Node::resize(Aligner& rd) { _resize(rd); Node* child = _firstChild; while (child) { child->resize(rd); child = child->_nextSibling; } } void Node::finalPass(Aligner& rd) { _finalPass(rd); Node* child = _firstChild; while (child) { child->finalPass(rd); child = child->_nextSibling; } } void Node::drawChildren(DrawContext& dc) { Node* child = _firstChild; while (child) { child->draw(dc); child = child->_nextSibling; } } Symbol* Node::getSymbol(int& pos) { Node* node = _firstChild; while (node) { int num = 0; Symbol* res = node->getSymbol(pos); if (res) return res; node = node->_nextSibling; } return 0; } void Node::draw(DrawContext& dc) { drawChildren(dc); } /* bool test() { string utf = ws2utf8(L"A"); wstring ws = utf8tows(utf.c_str()); const char *bf = (char*)ws.c_str(); const char *utfstr = utf.c_str(); int code = 0; while (getNextSingleCode(code, utfstr)) { int q = 0; } return true; } bool b = test(); */ TextNode::TextNode(const char* v) { #ifdef OX_DEBUG _text = v; #endif const char* utfstr = v; int code = 0; utfstr = getNextCode(code, utfstr); while (code) { Symbol s; s.code = code; _data.push_back(s); utfstr = getNextCode(code, utfstr); } } Symbol* TextNode::getSymbol(int& pos) { if ((int)_data.size() > pos) return &_data[pos]; pos -= _data.size(); return Node::getSymbol(pos); } void TextNode::draw(DrawContext& dc) { for (size_t i = 0; i < _data.size(); ++i) { const Symbol& s = _data[i]; if (!s.gl.texture) continue; dc.renderer->drawElement(s.gl.texture, dc.color.rgba(), s.gl.src, s.destRect); } drawChildren(dc); } int _defMissing = '?'; void TextNode::setDefaultMissingSymbol(int v) { _defMissing = v; } void TextNode::_resize(Aligner& rd) { if (!_data.empty()) { int i = 0; const Font* font = rd.getStyle().font->getFont(0, rd.getStyle().fontSize); glyphOptions opt = rd.getStyle().options; while (i != (int)_data.size()) { Symbol& s = _data[i]; if (s.code == '\n') rd.nextLine(); else { const glyph* gl = font->getGlyph(s.code, opt); if (gl) { s.gl = *gl; i += rd.putSymbol(s); } else { gl = font->getGlyph(_defMissing, opt); if (gl)//even 'missing' symbol could be missing { s.gl = *gl; i += rd.putSymbol(s); } } } ++i; if (i < 0) i = 0; } } } float mlt(int x, float sf) { //return (x + 0.01f) / sf; return x / sf; } void TextNode::_finalPass(Aligner& rd) { float scaleFactor = rd.getScale(); int offsetY = rd.bounds.pos.y; for (size_t i = 0; i < _data.size(); ++i) { Symbol& s = _data[i]; s.y += offsetY; if (s.gl.texture) s.destRect = RectF(mlt(s.x, scaleFactor), mlt(s.y, scaleFactor), mlt(s.gl.sw, scaleFactor), mlt(s.gl.sh, scaleFactor)); else s.destRect = RectF(0, 0, 0, 0); //s.destRect.size = Vector2(4.26666666f, 7.46666666f); } } void DivNode::_resize(Aligner& rd) { } void DivNode::draw(DrawContext& dc) { /* Color prevColor = dc.renderer->getPrimaryColor(); Color blendedColor = color; blendedColor.a = (blendedColor.a * dc.rs->alpha) / 255; dc.renderer->setPrimaryColor(blendedColor); drawChildren(dc); dc.renderer->setPrimaryColor(prevColor); */ Color prev = dc.color; dc.color = color * dc.primary; drawChildren(dc); dc.color = prev; } DivNode::DivNode(const pugi::xml_node& node) { pugi::xml_attribute attr = node.first_attribute(); while (attr) { if (!strcmp(attr.name(), "c") || !strcmp(attr.name(), "color")) { color = hex2color(attr.value()); } attr = attr.next_attribute(); } } } }