Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mapsme/omim.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorvng <viktor.govako@gmail.com>2010-12-29 02:28:10 +0300
committerAlex Zolotarev <alex@maps.me>2015-09-23 01:08:51 +0300
commite82bdfd361c80bcee7997681b5bce7b100b82ab7 (patch)
tree240c364f25130f613193664a9181d857bb4fe51c
parent01e8135397f30bf9107228bd4006c8e0ec10d76b (diff)
Filter texts by rect.
-rw-r--r--geometry/geometry_tests/tree_test.cpp11
-rw-r--r--geometry/tree4d.hpp14
-rw-r--r--yg/geometry_batcher.cpp38
-rw-r--r--yg/geometry_batcher.hpp6
-rw-r--r--yg/text_renderer.cpp59
-rw-r--r--yg/text_renderer.hpp39
-rw-r--r--yg/yg.pro3
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();
};
}
}
diff --git a/yg/yg.pro b/yg/yg.pro
index ced2138000..97388314bf 100644
--- a/yg/yg.pro
+++ b/yg/yg.pro
@@ -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 \