diff options
author | rachytski <siarhei.rachytski@gmail.com> | 2013-03-30 00:19:45 +0400 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:52:38 +0300 |
commit | c9b3cc7ef221508bc6b351bf6189d8ac637bce38 (patch) | |
tree | 3ad8b8d53b16e3c01ab58b33cf41bc6ba2979091 /gui | |
parent | 2807f21e5f2b8534b2dd99ac3bb3140184532365 (diff) |
added CachedTextView to render texts on GUI thread as a collection of display lists without re-uploading data to texture upon string modification.
Diffstat (limited to 'gui')
-rw-r--r-- | gui/cached_text_view.cpp | 146 | ||||
-rw-r--r-- | gui/cached_text_view.hpp | 57 | ||||
-rw-r--r-- | gui/gui.pro | 4 | ||||
-rw-r--r-- | gui/gui_tests/gui_tests.cpp | 29 |
4 files changed, 236 insertions, 0 deletions
diff --git a/gui/cached_text_view.cpp b/gui/cached_text_view.cpp new file mode 100644 index 0000000000..54dce2908c --- /dev/null +++ b/gui/cached_text_view.cpp @@ -0,0 +1,146 @@ +#include "cached_text_view.hpp" +#include "controller.hpp" + +#include "../geometry/transformations.hpp" + +#include "../graphics/glyph.hpp" +#include "../graphics/screen.hpp" + +namespace gui +{ + CachedTextView::CachedTextView(Params const & p) + : Element(p) + { + m_text = p.m_text; + m_uniText = strings::MakeUniString(p.m_text); + + setFont(EActive, graphics::FontDesc(12, graphics::Color(0, 0, 0, 255))); + setFont(EPressed, graphics::FontDesc(12, graphics::Color(0, 0, 0, 255))); + + setColor(EActive, graphics::Color(graphics::Color(192, 192, 192, 255))); + setColor(EPressed, graphics::Color(graphics::Color(64, 64, 64, 255))); + } + + void CachedTextView::setText(string const & text) + { + if (m_text != text) + { + m_text = text; + m_uniText = strings::MakeUniString(text); + setIsDirtyLayout(true); + } + } + + void CachedTextView::setFont(EState state, graphics::FontDesc const & desc) + { + setIsDirtyLayout(true); + Element::setFont(state, desc); + } + + string const & CachedTextView::text() const + { + return m_text; + } + + vector<m2::AnyRectD> const & CachedTextView::boundRects() const + { + if (isDirtyRect()) + { + const_cast<CachedTextView*>(this)->layout(); + + m_boundRects.clear(); + + copy(m_layout->boundRects().begin(), + m_layout->boundRects().end(), + back_inserter(m_boundRects)); + } + return m_boundRects; + } + + void CachedTextView::draw(graphics::OverlayRenderer *r, math::Matrix<double, 3, 3> const & m) const + { + if (isVisible()) + { + checkDirtyLayout(); + + math::Matrix<double, 3, 3> id = math::Identity<double, 3>(); + + if (m_maskedLayout) + for (unsigned i = 0; i < m_uniText.size(); ++i) + r->drawDisplayList(m_maskedDls[i].get(), + math::Shift(id, m_maskedLayout->entries()[i].m_pt + m_maskedLayout->pivot())); + + for (unsigned i = 0; i < m_uniText.size(); ++i) + r->drawDisplayList(m_dls[i].get(), + math::Shift(id, m_layout->entries()[i].m_pt + m_layout->pivot())); + } + } + + void CachedTextView::cache() + { + layout(); + + DisplayListCache * dlc = m_controller->GetDisplayListCache(); + graphics::FontDesc fontDesc = font(EActive); + + if (fontDesc.m_isMasked) + { + m_maskedDls.resize(m_uniText.size()); + for (unsigned i = 0; i < m_uniText.size(); ++i) + m_maskedDls[i] = dlc->FindGlyph(graphics::GlyphKey(m_uniText[i], + fontDesc.m_size, + fontDesc.m_isMasked, + fontDesc.m_isMasked ? fontDesc.m_maskColor : fontDesc.m_color)); + + fontDesc.m_isMasked = false; + } + + m_dls.resize(m_uniText.size()); + + for (unsigned i = 0; i < m_uniText.size(); ++i) + m_dls[i] = dlc->FindGlyph(graphics::GlyphKey(m_uniText[i], + fontDesc.m_size, + fontDesc.m_isMasked, + fontDesc.m_color)); + + + } + + void CachedTextView::purge() + { + m_dls.clear(); + } + + void CachedTextView::layout() + { + if (m_uniText.empty()) + return; + + graphics::FontDesc fontDesc = font(EActive); + + if (fontDesc.m_isMasked) + { + m_maskedLayout.reset(new graphics::GlyphLayout(m_controller->GetGlyphCache(), + fontDesc, + pivot(), + m_uniText, + position())); + fontDesc.m_isMasked = false; + } + + m_layout.reset(new graphics::GlyphLayout(m_controller->GetGlyphCache(), + fontDesc, + pivot(), + m_uniText, + position())); + } + + void CachedTextView::setPivot(m2::PointD const & pv) + { + Element::setPivot(pv); + if (m_maskedLayout) + m_maskedLayout->setPivot(pivot()); + if (m_layout) + m_layout->setPivot(pivot()); + } +} diff --git a/gui/cached_text_view.hpp b/gui/cached_text_view.hpp new file mode 100644 index 0000000000..5afdaf5be2 --- /dev/null +++ b/gui/cached_text_view.hpp @@ -0,0 +1,57 @@ +#pragma once + +#include "element.hpp" + +#include "../std/map.hpp" +#include "../std/vector.hpp" +#include "../std/shared_ptr.hpp" + +#include "../base/string_utils.hpp" +#include "../base/matrix.hpp" + +#include "../graphics/glyph_cache.hpp" +#include "../graphics/display_list.hpp" +#include "../graphics/glyph_layout.hpp" + +namespace gui +{ + class CachedTextView : public Element + { + private: + + string m_text; + + strings::UniString m_uniText; + + vector<shared_ptr<graphics::DisplayList> > m_dls; + vector<shared_ptr<graphics::DisplayList> > m_maskedDls; + + scoped_ptr<graphics::GlyphLayout> m_layout; + scoped_ptr<graphics::GlyphLayout> m_maskedLayout; + + mutable vector<m2::AnyRectD> m_boundRects; + + public: + + struct Params : public Element::Params + { + string m_text; + }; + + CachedTextView(Params const & p); + + void setText(string const & text); + string const & text() const; + + vector<m2::AnyRectD> const & boundRects() const; + void draw(graphics::OverlayRenderer * r, math::Matrix<double, 3, 3> const & m) const; + + void cache(); + void purge(); + void layout(); + + void setFont(EState state, graphics::FontDesc const & desc); + + void setPivot(m2::PointD const & pv); + }; +} diff --git a/gui/gui.pro b/gui/gui.pro index 48d84069db..9556a39b03 100644 --- a/gui/gui.pro +++ b/gui/gui.pro @@ -16,6 +16,8 @@ HEADERS += \ text_view.hpp \ balloon.hpp \ image_view.hpp \ + cached_text_view.hpp \ + display_list_cache.hpp SOURCES += \ controller.cpp \ @@ -24,3 +26,5 @@ SOURCES += \ text_view.cpp \ balloon.cpp \ image_view.cpp \ + cached_text_view.cpp \ + display_list_cache.cpp diff --git a/gui/gui_tests/gui_tests.cpp b/gui/gui_tests/gui_tests.cpp index c552e8a795..f4d348388f 100644 --- a/gui/gui_tests/gui_tests.cpp +++ b/gui/gui_tests/gui_tests.cpp @@ -4,6 +4,7 @@ #include "../button.hpp" #include "../text_view.hpp" #include "../image_view.hpp" +#include "../cached_text_view.hpp" struct BalloonTest { @@ -117,6 +118,33 @@ struct TextViewTest } }; +struct CachedTextViewTest +{ + shared_ptr<gui::CachedTextView> m_cachedTextView; + + void Init(gui::Controller * c) + { + gui::CachedTextView::Params ctp; + + ctp.m_pivot = m2::PointD(100, 100); + ctp.m_depth = graphics::maxDepth; + ctp.m_position = graphics::EPosAbove; + ctp.m_text = "(123.15, 783.123)"; + + m_cachedTextView.reset(new gui::CachedTextView(ctp)); + m_cachedTextView->setIsVisible(true); + + m_cachedTextView->setFont(gui::Element::EActive, + graphics::FontDesc(20, graphics::Color(0, 0, 0, 255), true)); + + c->AddElement(m_cachedTextView); + } + + void DoDraw(shared_ptr<graphics::Screen> const & p) + { + } +}; + struct ImageViewTest { shared_ptr<gui::ImageView> m_imageView; @@ -155,4 +183,5 @@ UNIT_TEST_GUI(BalloonTest); UNIT_TEST_GUI(ButtonTest); UNIT_TEST_GUI(TextViewTest); UNIT_TEST_GUI(ImageViewTest); +UNIT_TEST_GUI(CachedTextViewTest); |