diff options
author | vng <viktor.govako@gmail.com> | 2010-12-29 02:28:10 +0300 |
---|---|---|
committer | Alex Zolotarev <alex@maps.me> | 2015-09-23 01:08:51 +0300 |
commit | e82bdfd361c80bcee7997681b5bce7b100b82ab7 (patch) | |
tree | 240c364f25130f613193664a9181d857bb4fe51c | |
parent | 01e8135397f30bf9107228bd4006c8e0ec10d76b (diff) |
Filter texts by rect.
-rw-r--r-- | geometry/geometry_tests/tree_test.cpp | 11 | ||||
-rw-r--r-- | geometry/tree4d.hpp | 14 | ||||
-rw-r--r-- | yg/geometry_batcher.cpp | 38 | ||||
-rw-r--r-- | yg/geometry_batcher.hpp | 6 | ||||
-rw-r--r-- | yg/text_renderer.cpp | 59 | ||||
-rw-r--r-- | yg/text_renderer.hpp | 39 | ||||
-rw-r--r-- | yg/yg.pro | 3 |
7 files changed, 134 insertions, 36 deletions
diff --git a/geometry/geometry_tests/tree_test.cpp b/geometry/geometry_tests/tree_test.cpp index 69a67cf3e0..bcc0721419 100644 --- a/geometry/geometry_tests/tree_test.cpp +++ b/geometry/geometry_tests/tree_test.cpp @@ -6,12 +6,7 @@ namespace { - struct simple_traits - { - static m2::RectD GetLimitRect(m2::RectD const & r) { return r; } - }; - - typedef m4::Tree<m2::RectD, simple_traits> tree_t; + typedef m4::Tree<m2::RectD> tree_t; bool compare_true(m2::RectD const &, m2::RectD const &) { return true; } } @@ -27,14 +22,14 @@ UNIT_TEST(Tree4D_Smoke) }; for (size_t i = 0; i < ARRAY_SIZE(arr); ++i) - theTree.ReplaceIf(arr[i], &compare_true); + theTree.ReplaceIf(arr[i], arr[i], &compare_true); vector<m2::RectD> test; theTree.ForEach(MakeBackInsertFunctor(test)); TEST_EQUAL(3, test.size(), ()); m2::RectD const replaceR(0.5, 0.5, 2.5, 2.5); - theTree.ReplaceIf(replaceR, &compare_true); + theTree.ReplaceIf(replaceR, replaceR, &compare_true); test.clear(); theTree.ForEach(MakeBackInsertFunctor(test)); diff --git a/geometry/tree4d.hpp b/geometry/tree4d.hpp index 7e22ed290f..c03dbb61ad 100644 --- a/geometry/tree4d.hpp +++ b/geometry/tree4d.hpp @@ -10,7 +10,7 @@ namespace m4 { - template <class T, class TTraits> + template <class T> class Tree { struct value_t @@ -44,10 +44,8 @@ namespace m4 public: template <class TCompare> - void ReplaceIf(T const & obj, TCompare comp) + void ReplaceIf(T const & obj, m2::RectD const & rect, TCompare comp) { - m2::RectD const rect = TTraits::GetLimitRect(obj); - region_t rgn; for (size_t i = 0; i < 4; ++i) { @@ -96,11 +94,19 @@ namespace m4 m_tree.insert(value_t(obj, rect)); } + template <class TCompare> + void ReplaceIf(T const & obj, TCompare comp) + { + ReplaceIf(obj, obj.GetLimitRect(), comp); + } + template <class ToDo> void ForEach(ToDo toDo) const { for (tree_t::const_iterator i = m_tree.begin(); i != m_tree.end(); ++i) toDo((*i).m_val); } + + void Clear() { m_tree.clear(); } }; } diff --git a/yg/geometry_batcher.cpp b/yg/geometry_batcher.cpp index ee26436362..b273aba4e3 100644 --- a/yg/geometry_batcher.cpp +++ b/yg/geometry_batcher.cpp @@ -537,34 +537,28 @@ namespace yg p->m_pageID); } - void GeometryBatcher::drawText(m2::PointD const & pt, float angle, uint8_t fontSize, string const & utf8Text, double depth) + template <class ToDo> + void GeometryBatcher::ForEachGlyph(uint8_t fontSize, wstring const & text, bool isMask, ToDo toDo) { - wstring text = FromUtf8(utf8Text); - m2::PointD currPt(0, 0); for (size_t i = 0; i < text.size(); ++i) { - uint32_t glyphID = m_skin->mapGlyph(GlyphKey(text[i], fontSize, true)); - CharStyle const * p = static_cast<CharStyle const *>(m_skin->fromID(glyphID)); - if (p) - { - drawGlyph(pt, currPt, angle, 0, p, depth); - currPt = currPt.Move(p->m_xAdvance, 0); - } - } + uint32_t glyphID = m_skin->mapGlyph(GlyphKey(text[i], fontSize, isMask)); + CharStyle const * p = static_cast<CharStyle const *>(m_skin->fromID(glyphID)); + if (p) + { + toDo(currPt, p); + currPt += m2::PointD(p->m_xAdvance, 0); + } + } + } - currPt = m2::PointD(0, 0); + void GeometryBatcher::drawText(m2::PointD const & pt, float angle, uint8_t fontSize, string const & utf8Text, double depth) + { + wstring text = FromUtf8(utf8Text); - for (size_t i = 0; i < text.size(); ++i) - { - uint32_t glyphID = m_skin->mapGlyph(GlyphKey(text[i], fontSize, false)); - CharStyle const * p = static_cast<CharStyle const *>(m_skin->fromID(glyphID)); - if (p) - { - drawGlyph(pt, currPt, angle, 0, p, depth); - currPt = currPt.Move(p->m_xAdvance, 0); - } - } + ForEachGlyph(fontSize, text, true, bind(&GeometryBatcher::drawGlyph, this, cref(pt), _1, angle, 0, _2, depth)); + ForEachGlyph(fontSize, text, false, bind(&GeometryBatcher::drawGlyph, this, cref(pt), _1, angle, 0, _2, depth)); } /// Incapsulate array of points in readable getting direction. diff --git a/yg/geometry_batcher.hpp b/yg/geometry_batcher.hpp index e6161b210a..4d10531418 100644 --- a/yg/geometry_batcher.hpp +++ b/yg/geometry_batcher.hpp @@ -103,6 +103,7 @@ namespace yg void setSkin(shared_ptr<Skin> skin); shared_ptr<Skin> skin() const; + shared_ptr<ResourceManager> resManager() const { return m_resourceManager; } void beginFrame(); void endFrame(); @@ -120,6 +121,11 @@ namespace yg uint32_t styleID, double depth); + private: + template <class ToDo> + void ForEachGlyph(uint8_t fontSize, wstring const & text, bool isMask, ToDo toDo); + + public: /// Drawing text from point rotated by the angle. void drawText(m2::PointD const & pt, float angle, diff --git a/yg/text_renderer.cpp b/yg/text_renderer.cpp new file mode 100644 index 0000000000..1277c1eccd --- /dev/null +++ b/yg/text_renderer.cpp @@ -0,0 +1,59 @@ +#include "../base/SRC_FIRST.hpp" + +#include "text_renderer.hpp" +#include "resource_manager.hpp" +#include "skin.hpp" + +#include "../coding/strutil.hpp" + +#include "../std/bind.hpp" + +#include "../base/start_mem_debug.hpp" + + +namespace yg { namespace gl { + +void TextRenderer::TextObj::Draw(GeometryBatcher * pBatcher) const +{ + pBatcher->drawText(m_pt, 0.0, m_size, m_utf8Text, m_depth); +} + +m2::RectD TextRenderer::TextObj::GetLimitRect(GeometryBatcher * pBatcher) const +{ + shared_ptr<ResourceManager> pRM = pBatcher->resManager(); + m2::RectD rect; + m2::PointD pt(0, 0); + + wstring const text = FromUtf8(m_utf8Text); + for (size_t i = 0; i < text.size(); ++i) + { + GlyphMetrics const m = pRM->getGlyphMetrics(GlyphKey(text[i], m_size, true)); + + rect.Add(m_pt + pt); + rect.Add(m_pt + pt + m2::PointD(m.m_xOffset + m.m_width, - m.m_yOffset - m.m_height)); + pt += m2::PointD(m.m_xAdvance, 0); + } + + rect.Inflate(2, 2); + return rect; +} + +void TextRenderer::drawText(m2::PointD const & pt, + float angle, + uint8_t fontSize, + string const & utf8Text, + double depth) +{ + TextObj obj(pt, utf8Text, fontSize, depth); + m_tree.ReplaceIf(obj, obj.GetLimitRect(this), TextObj::better_depth()); +} + +void TextRenderer::endFrame() +{ + m_tree.ForEach(bind(&TextObj::Draw, _1, this)); + m_tree.Clear(); + + GeometryBatcher::endFrame(); +} + +}} diff --git a/yg/text_renderer.hpp b/yg/text_renderer.hpp index c3d36b48b0..75c6b04b7b 100644 --- a/yg/text_renderer.hpp +++ b/yg/text_renderer.hpp @@ -1,6 +1,9 @@ #pragma once #include "geometry_batcher.hpp" + +#include "../geometry/tree4d.hpp" + #include "../std/shared_ptr.hpp" namespace yg @@ -10,13 +13,47 @@ namespace yg { class TextRenderer : public GeometryBatcher { - private: + class TextObj + { + m2::PointD m_pt; + uint8_t m_size; + string m_utf8Text; + double m_depth; + + public: + TextObj(m2::PointD const & pt, string const & txt, uint8_t sz, double d) + : m_pt(pt), m_utf8Text(txt), m_size(sz), m_depth(d) + { + } + + void Draw(GeometryBatcher * pBatcher) const; + m2::RectD GetLimitRect(GeometryBatcher * pBatcher) const; + + struct better_depth + { + bool operator() (TextObj const & r1, TextObj const & r2) const + { + return r1.m_depth > r2.m_depth; + } + }; + }; + + m4::Tree<TextObj> m_tree; + public: typedef GeometryBatcher::Params Params; TextRenderer(Params const & params) : GeometryBatcher(params) {} + + void drawText(m2::PointD const & pt, + float angle, + uint8_t fontSize, + string const & utf8Text, + double depth); + + void endFrame(); }; } } @@ -56,7 +56,8 @@ SOURCES += \ glyph_cache.cpp \ glyph_cache_impl.cpp \ ft2_debug.cpp \ - geometry_batcher.cpp + geometry_batcher.cpp \ + text_renderer.cpp \ HEADERS += \ internal/opengl.hpp \ |